Subversion Repositories Kolibri OS

Rev

Rev 1065 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1065 Rev 1132
Line 23... Line 23...
23
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
;*****************************************************************************
25
;*****************************************************************************
Line 26... Line 26...
26
 
26
 
27
use_lba = 0
27
use_lba = 0
28
	org	0x7C00
28
        org     0x7C00
29
	jmp	start
29
        jmp     start
30
	nop
30
        nop
31
; FAT parameters, BPB
31
; FAT parameters, BPB
32
; note: they can be changed at install, replaced with real values
32
; note: they can be changed at install, replaced with real values
33
; these settings are for most typical 1.44M floppies
33
; these settings are for most typical 1.44M floppies
34
		db	'KOLIBRI '	; BS_OEMName, ignored
34
                db      'KOLIBRI '      ; BS_OEMName, ignored
35
		dw	200h		; BPB_BytsPerSec
35
                dw      200h            ; BPB_BytsPerSec
36
BPB_SecsPerClus	db	1
36
BPB_SecsPerClus db      1
37
BPB_RsvdSecCnt	dw	1
37
BPB_RsvdSecCnt  dw      1
38
BPB_NumFATs	db	2
38
BPB_NumFATs     db      2
39
BPB_RootEntCnt	dw	0xE0
39
BPB_RootEntCnt  dw      0xE0
40
		dw	2880		; BPB_TotSec16
40
                dw      2880            ; BPB_TotSec16
41
		db	0xF0		; BPB_Media
41
                db      0xF0            ; BPB_Media
42
BPB_FATSz16	dw	9
42
BPB_FATSz16     dw      9
43
BPB_SecPerTrk	dw	18
43
BPB_SecPerTrk   dw      18
44
BPB_NumHeads	dw	2
44
BPB_NumHeads    dw      2
45
BPB_HiddSec	dd	0
45
BPB_HiddSec     dd      0
46
		dd	0		; BPB_TotSec32
46
                dd      0               ; BPB_TotSec32
47
BS_DrvNum	db	0
47
BS_DrvNum       db      0
48
		db	0		; BS_Reserved1
48
                db      0               ; BS_Reserved1
49
		db	')'		; BS_BootSig
49
                db      ')'             ; BS_BootSig
50
		dd	12344321h	; BS_VolID
50
                dd      12344321h       ; BS_VolID
51
filename:
51
filename:
52
		db	'KORD.OS    '	; BS_VolLab
52
                db      'KORD.OS    '   ; BS_VolLab
53
		db	'FAT12   '	; BS_FilSysType
53
                db      'FAT12   '      ; BS_FilSysType
54
; Used memory map:
54
; Used memory map:
55
;	8000:0000 - current directory
55
;       8000:0000 - current directory
56
;	9000:0000 - root directory data [cached]
56
;       9000:0000 - root directory data [cached]
57
start:
57
start:
58
	xor	ax, ax
58
        xor     ax, ax
59
	mov	ss, ax
59
        mov     ss, ax
60
	mov	sp, 0x7C00
60
        mov     sp, 0x7C00
61
	mov	ds, ax
61
        mov     ds, ax
62
	mov	bp, sp
62
        mov     bp, sp
63
	cld
63
        cld
64
	sti
64
        sti
65
	mov	[bp+BS_DrvNum-0x7C00], dl
65
        mov     [bp+BS_DrvNum-0x7C00], dl
66
if use_lba
66
if use_lba
67
	mov	ah, 41h
67
        mov     ah, 41h
68
	mov	bx, 55AAh
68
        mov     bx, 55AAh
69
	int	13h
69
        int     13h
70
	mov	si, aNoLBA
70
        mov     si, aNoLBA
71
	jc	err
71
        jc      err_
72
	cmp	bx, 0AA55h
72
        cmp     bx, 0AA55h
73
	jnz	err
73
        jnz     err_
74
	test	cx, 1
74
        test    cx, 1
75
	jz	err
75
        jz      err_
76
else
76
else
77
	mov	ah, 8
77
        mov     ah, 8
78
	int	13h
78
        int     13h
79
	jc	@f		; on error, assume that BPB geometry is valid
79
        jc      @f              ; on error, assume that BPB geometry is valid
80
	mov	al, dh
80
        mov     al, dh
81
	mov	ah, 0
81
        mov     ah, 0
82
	inc	ax
82
        inc     ax
83
	mov	[bp+BPB_NumHeads-0x7C00], ax
83
        mov     [bp+BPB_NumHeads-0x7C00], ax
84
	and	cx, 3Fh
84
        and     cx, 3Fh
85
	mov	[bp+BPB_SecPerTrk-0x7C00], cx
85
        mov     [bp+BPB_SecPerTrk-0x7C00], cx
86
@@:
86
@@:
87
end if
87
end if
88
; get FAT parameters
88
; get FAT parameters
89
	xor	bx, bx
89
        xor     bx, bx
90
	mov	al, [bp+BPB_NumFATs-0x7C00]
90
        mov     al, [bp+BPB_NumFATs-0x7C00]
91
	mov	ah, 0
91
        mov     ah, 0
92
	mul	[bp+BPB_FATSz16-0x7C00]
92
        mul     [bp+BPB_FATSz16-0x7C00]
93
	add	ax, [bp+BPB_RsvdSecCnt-0x7C00]
93
        add     ax, [bp+BPB_RsvdSecCnt-0x7C00]
94
	adc	dx, bx
94
        adc     dx, bx
95
	push	dx
95
        push    dx
96
	push	ax	; root directory start = dword [bp-4]
96
        push    ax      ; root directory start = dword [bp-4]
97
	mov	cx, [bp+BPB_RootEntCnt-0x7C00]
97
        mov     cx, [bp+BPB_RootEntCnt-0x7C00]
98
	add	cx, 0xF
98
        add     cx, 0xF
99
	rcr	cx, 1
99
        rcr     cx, 1
100
	shr	cx, 3	; cx = size of root directory in sectors
100
        shr     cx, 3   ; cx = size of root directory in sectors
101
	add	ax, cx
101
        add     ax, cx
102
	adc	dx, bx
102
        adc     dx, bx
103
	push	dx
103
        push    dx
104
	push	ax	; data start = dword [bp-8]
104
        push    ax      ; data start = dword [bp-8]
105
; load start of root directory (no more than 0x2000 bytes = 0x10 sectors)
105
; load start of root directory (no more than 0x2000 bytes = 0x10 sectors)
106
	cmp	cx, 0x10
106
        cmp     cx, 0x10
107
	jb	@f
107
        jb      @f
108
	mov	cx, 0x10
108
        mov     cx, 0x10
109
@@:
109
@@:
110
	mov	ax, [bp-4]
110
        mov     ax, [bp-4]
111
	mov	dx, [bp-2]
111
        mov     dx, [bp-2]
112
	push	0x9000
112
        push    0x9000
113
	pop	es
113
        pop     es
114
	call	read_sectors
114
        call    read_sectors
115
	add	word [bp-4], cx		; dword [bp-4] = start of non-cached root data
115
        add     word [bp-4], cx         ; dword [bp-4] = start of non-cached root data
116
	adc	word [bp-2], bx
116
        adc     word [bp-2], bx
117
; load kordldr.f12
117
; load kordldr.f12
118
	mov	si, main_loader
118
        mov     si, main_loader
119
	call	lookup_in_root_dir
119
        call    lookup_in_root_dir
120
	jc	noloader
120
        jc      noloader
121
	test	byte [es:di+11], 10h	; directory?
121
        test    byte [es:di+11], 10h    ; directory?
122
	jz	kordldr_ok
122
        jz      kordldr_ok
123
noloader:
123
noloader:
124
	mov	si, aLoaderNotFound
124
        mov     si, aLoaderNotFound
125
err:
125
err_:
126
	call	out_string
126
        call    out_string
127
	mov	si, aPressAnyKey
127
        mov     si, aPressAnyKey
128
	call	out_string
128
        call    out_string
129
	xor	ax, ax
129
        xor     ax, ax
130
	int	16h
130
        int     16h
131
	int	18h
131
        int     18h
132
	jmp	$
132
        jmp     $
133
kordldr_ok:
133
kordldr_ok:
134
	mov	ax, [es:di+26]		; get file cluster
134
        mov     ax, [es:di+26]          ; get file cluster
135
	mov	bx, 0x7E00
135
        mov     bx, 0x7E00
136
	xor	cx, cx
136
        xor     cx, cx
137
	mov	es, cx
137
        mov     es, cx
138
	sub	ax, 2
138
        sub     ax, 2
139
	jc	noloader
139
        jc      noloader
140
	push	bx	; save return address: bx = 7E00
140
        push    bx      ; save return address: bx = 7E00
141
	mov	cl, [bp+BPB_SecsPerClus-0x7C00]
141
        mov     cl, [bp+BPB_SecsPerClus-0x7C00]
142
	mul	cx
142
        mul     cx
Line 143... Line 143...
143
; fall through - 'ret' in read_sectors will return to 7E00
143
; fall through - 'ret' in read_sectors will return to 7E00
144
 
144
 
145
read_sectors2:
145
read_sectors2:
146
; same as read_sectors, but dx:ax is relative to start of data
146
; same as read_sectors, but dx:ax is relative to start of data
147
	add	ax, [bp-8]
147
        add     ax, [bp-8]
148
	adc	dx, [bp-6]
148
        adc     dx, [bp-6]
149
read_sectors:
149
read_sectors:
150
; ss:bp = 0:7C00
150
; ss:bp = 0:7C00
151
; es:bx = pointer to data
151
; es:bx = pointer to data
152
; dx:ax = first sector
152
; dx:ax = first sector
153
; cx = number of sectors
153
; cx = number of sectors
154
	pusha
154
        pusha
155
	add	ax, word [bp+BPB_HiddSec-0x7C00]
155
        add     ax, word [bp+BPB_HiddSec-0x7C00]
156
	adc	dx, word [bp+BPB_HiddSec+2-0x7C00]
156
        adc     dx, word [bp+BPB_HiddSec+2-0x7C00]
157
if use_lba
157
if use_lba
158
	push	ds
158
        push    ds
159
do_read_sectors:
159
do_read_sectors:
160
	push	ax
160
        push    ax
161
	push	cx
161
        push    cx
162
	push	dx
162
        push    dx
163
	cmp	cx, 0x7F
163
        cmp     cx, 0x7F
164
	jbe	@f
164
        jbe     @f
165
	mov	cx, 0x7F
165
        mov     cx, 0x7F
166
@@:
166
@@:
167
; create disk address packet on the stack
167
; create disk address packet on the stack
168
; dq starting LBA
168
; dq starting LBA
169
	push	0
169
        push    0
170
	push	0
170
        push    0
171
	push	dx
171
        push    dx
172
	push	ax
172
        push    ax
173
; dd buffer
173
; dd buffer
174
	push	es
174
        push    es
175
	push	bx
175
        push    bx
176
; dw number of blocks to transfer (no more than 0x7F)
176
; dw number of blocks to transfer (no more than 0x7F)
177
	push	cx
177
        push    cx
178
; dw packet size in bytes
178
; dw packet size in bytes
179
	push	10h
179
        push    10h
180
; issue BIOS call
180
; issue BIOS call
181
	push	ss
181
        push    ss
182
	pop	ds
182
        pop     ds
183
	mov	si, sp
183
        mov     si, sp
184
	mov	dl, [bp+BS_DrvNum-0x7C00]
184
        mov     dl, [bp+BS_DrvNum-0x7C00]
185
	mov	ah, 42h
185
        mov     ah, 42h
186
	int	13h
186
        int     13h
187
	mov	si, aReadError
187
        mov     si, aReadError
188
	jc	err
188
        jc      err_
189
; restore stack
189
; restore stack
190
	add	sp, 10h
190
        add     sp, 10h
191
; increase current sector & buffer; decrease number of sectors
191
; increase current sector & buffer; decrease number of sectors
192
	mov	si, cx
192
        mov     si, cx
193
	mov	ax, es
193
        mov     ax, es
194
	shl	cx, 5
194
        shl     cx, 5
195
	add	ax, cx
195
        add     ax, cx
196
	mov	es, ax
196
        mov     es, ax
197
	pop	dx
197
        pop     dx
198
	pop	cx
198
        pop     cx
199
	pop	ax
199
        pop     ax
200
	add	ax, si
200
        add     ax, si
201
	adc	dx, 0
201
        adc     dx, 0
202
	sub	cx, si
202
        sub     cx, si
203
	jnz	do_read_sectors
203
        jnz     do_read_sectors
204
	pop	ds
204
        pop     ds
205
	popa
205
        popa
206
	ret
206
        ret
207
else
207
else
208
do_read_sectors:
208
do_read_sectors:
209
	pusha
209
        pusha
Line 210... Line 210...
210
	pop	di
210
        pop     di
211
	push	bx
211
        push    bx
212
 
212
 
213
; (dword in dx:ax) / (SectorsPerTrack) -> (dword in dx:ax), remainder bx
213
; (dword in dx:ax) / (SectorsPerTrack) -> (dword in dx:ax), remainder bx
214
	mov	si, ax
214
        mov     si, ax
215
	xchg	ax, dx
215
        xchg    ax, dx
216
	xor	dx, dx
216
        xor     dx, dx
217
	div	[bp+BPB_SecPerTrk-0x7C00]
217
        div     [bp+BPB_SecPerTrk-0x7C00]
218
	push	ax
218
        push    ax
219
	mov	ax, si
219
        mov     ax, si
Line 220... Line 220...
220
	div	[bp+BPB_SecPerTrk-0x7C00]
220
        div     [bp+BPB_SecPerTrk-0x7C00]
221
	mov	bx, dx		; bx=sector-1
221
        mov     bx, dx          ; bx=sector-1
Line 222... Line 222...
222
	pop	dx
222
        pop     dx
223
 
223
 
224
; (dword in dx:ax) / (NumHeads) -> (word in ax), remainder dx
224
; (dword in dx:ax) / (NumHeads) -> (word in ax), remainder dx
225
	div	[bp+BPB_NumHeads-0x7C00]
225
        div     [bp+BPB_NumHeads-0x7C00]
226
 
226
 
227
; number of sectors: read no more than to end of track
227
; number of sectors: read no more than to end of track
228
	push	bx
228
        push    bx
229
	sub	bx, [bp+BPB_SecPerTrk-0x7C00]
229
        sub     bx, [bp+BPB_SecPerTrk-0x7C00]
230
	neg	bx
230
        neg     bx
Line 231... Line 231...
231
	cmp	cx, bx
231
        cmp     cx, bx
232
	jbe	@f
232
        jbe     @f
233
	mov	cx, bx
233
        mov     cx, bx
234
@@:
234
@@:
235
	pop	bx
235
        pop     bx
236
 
236
 
237
	inc	bx
237
        inc     bx
238
; now ax=track, dl=head, dh=0, cl=number of sectors, ch=0, bl=sector; convert to int13 format
238
; now ax=track, dl=head, dh=0, cl=number of sectors, ch=0, bl=sector; convert to int13 format
239
	mov	di, cx
239
        mov     di, cx
240
	mov	dh, dl
240
        mov     dh, dl
241
	mov	dl, [bp+BS_DrvNum-0x7C00]
241
        mov     dl, [bp+BS_DrvNum-0x7C00]
242
	shl	ah, 6
242
        shl     ah, 6
243
	mov	ch, al
243
        mov     ch, al
244
	mov	al, cl
244
        mov     al, cl
245
	mov	cl, bl
245
        mov     cl, bl
246
	or	cl, ah
246
        or      cl, ah
247
	pop	bx
247
        pop     bx
248
	mov	si, 3
248
        mov     si, 3
249
	mov	ah, 2
249
        mov     ah, 2
250
@@:
250
@@:
251
	push	ax
251
        push    ax
252
	int	13h
252
        int     13h
253
	jnc	@f
253
        jnc     @f
254
	xor	ax, ax
254
        xor     ax, ax
255
	int	13h	; reset drive
255
        int     13h     ; reset drive
256
	pop	ax
256
        pop     ax
257
	dec	si
257
        dec     si
258
	jnz	@b
258
        jnz     @b
259
	mov	si, aReadError
259
        mov     si, aReadError
260
	jmp	err
260
        jmp     err_
261
@@:
261
@@:
262
	pop	ax
262
        pop     ax
263
	mov	ax, es
263
        mov     ax, es
264
	mov	cx, di
264
        mov     cx, di
265
	shl	cx, 5
265
        shl     cx, 5
266
	add	ax, cx
266
        add     ax, cx
267
	mov	es, ax
267
        mov     es, ax
268
	push	di
268
        push    di
269
	popa
269
        popa
270
	add	ax, di
270
        add     ax, di
Line 271... Line 271...
271
	adc	dx, 0
271
        adc     dx, 0
272
	sub	cx, di
272
        sub     cx, di
273
	jnz	do_read_sectors
273
        jnz     do_read_sectors
274
	popa
274
        popa
275
	ret
275
        ret
276
end if
276
end if
277
 
277
 
278
scan_for_filename:
278
scan_for_filename:
279
; in: ds:si -> 11-bytes FAT name
279
; in: ds:si -> 11-bytes FAT name
280
; in: es:0 -> part of directory data
280
; in: es:0 -> part of directory data
281
; in: cx = number of entries
281
; in: cx = number of entries
282
; out: if found: CF=0, ZF=1, es:di -> directory entry
282
; out: if found: CF=0, ZF=1, es:di -> directory entry
283
; out: if not found, but continue required: CF=1 and ZF=0
283
; out: if not found, but continue required: CF=1 and ZF=0
284
; out: if not found and zero item reached: CF=1 and ZF=1
284
; out: if not found and zero item reached: CF=1 and ZF=1
285
	xor	di, di
285
        xor     di, di
286
	push	cx
286
        push    cx
287
sloop:
287
sloop:
288
	cmp	byte [es:di], 0
288
        cmp     byte [es:di], 0
289
	jz	snotfound
289
        jz      snotfound
290
	test	byte [es:di+11], 8	; volume label?
290
        test    byte [es:di+11], 8      ; volume label?
291
	jnz	scont			; ignore volume labels
291
        jnz     scont                   ; ignore volume labels
292
	pusha
292
        pusha
293
	mov	cx, 11
293
        mov     cx, 11
294
	repz	cmpsb
294
        repz    cmpsb
295
	popa
295
        popa
296
	jz	sdone
296
        jz      sdone
297
scont:
297
scont:
298
	add	di, 0x20
298
        add     di, 0x20
299
	loop	sloop
299
        loop    sloop
Line 300... Line 300...
300
	inc	cx	; clear ZF flag
300
        inc     cx      ; clear ZF flag
301
snotfound:
301
snotfound:
302
	stc
302
        stc
303
sdone:
303
sdone:
304
	pop	cx
304
        pop     cx
305
lrdret:
305
lrdret:
306
	ret
306
        ret
307
 
307
 
308
lookup_in_root_dir:
308
lookup_in_root_dir:
309
; ss:bp = 0:7C00
309
; ss:bp = 0:7C00
310
; in: ds:si -> 11-bytes FAT name
310
; in: ds:si -> 11-bytes FAT name
311
; out: if found: CF=0, es:di -> directory entry
311
; out: if found: CF=0, es:di -> directory entry
312
; out: if not found: CF=1
312
; out: if not found: CF=1
313
	mov	cx, [bp+BPB_RootEntCnt-0x7C00]
313
        mov     cx, [bp+BPB_RootEntCnt-0x7C00]
314
	push	cx
314
        push    cx
315
; first, look in root directory cache
315
; first, look in root directory cache
316
	push	0x9000
316
        push    0x9000
317
	pop	es
317
        pop     es
318
	test	ch, ch
318
        test    ch, ch
319
	jz	@f
319
        jz      @f
320
	mov	cx, 0x100
320
        mov     cx, 0x100
321
@@:
321
@@:
322
	mov	ax, [bp-4]
322
        mov     ax, [bp-4]
323
	mov	dx, [bp-2]	; dx:ax = starting sector of not cached data of root directory
323
        mov     dx, [bp-2]      ; dx:ax = starting sector of not cached data of root directory
324
lrdloop:
324
lrdloop:
325
	call	scan_for_filename
325
        call    scan_for_filename
326
	pop	bx
326
        pop     bx
327
	jz	lrdret
327
        jz      lrdret
328
	sub	bx, cx
328
        sub     bx, cx
329
	mov	cx, bx
329
        mov     cx, bx
330
	stc
330
        stc
331
	jz	lrdret
331
        jz      lrdret
332
; read no more than 0x10000 bytes, or 0x10000/0x20 = 0x800 entries
332
; read no more than 0x10000 bytes, or 0x10000/0x20 = 0x800 entries
333
	push	cx
333
        push    cx
334
	cmp	ch, 0x8
334
        cmp     ch, 0x8
335
	jb	@f
335
        jb      @f
336
	mov	cx, 0x800
336
        mov     cx, 0x800
337
@@:
337
@@:
338
	push	0x8000
338
        push    0x8000
339
	pop	es
339
        pop     es
340
	push	cx
340
        push    cx
341
	push	es
341
        push    es
342
	xor	bx, bx
342
        xor     bx, bx
Line 343... Line 343...
343
	add	cx, 0xF
343
        add     cx, 0xF
344
	shr	cx, 4
344
        shr     cx, 4
345
	call	read_sectors
345
        call    read_sectors
346
	pop	es
346
        pop     es
347
	add	ax, cx
347
        add     ax, cx
348
	adc	dx, bx
348
        adc     dx, bx
349
	pop	cx
349
        pop     cx
350
	jmp	lrdloop
350
        jmp     lrdloop
351
 
351
 
Line 352... Line 352...
352
out_string:
352
out_string:
353
; in: ds:si -> ASCIIZ string
353
; in: ds:si -> ASCIIZ string
354
	lodsb
354
        lodsb
355
	test	al, al
355
        test    al, al
356
	jz	lrdret
356
        jz      lrdret
357
	mov	ah, 0Eh
357
        mov     ah, 0Eh
358
	mov	bx, 7
358
        mov     bx, 7
Line 359... Line 359...
359
	int	10h
359
        int     10h
360
	jmp	out_string
360
        jmp     out_string
361
 
361
 
Line 362... Line 362...
362
aReadError	db	'Read error',0
362
aReadError      db      'Read error',0
363
if use_lba
363
if use_lba
Line 364... Line 364...
364
aNoLBA		db	'The drive does not support LBA!',0
364
aNoLBA          db      'The drive does not support LBA!',0
365
end if
365
end if
366
aLoaderNotFound	db	'Loader not found',0
366
aLoaderNotFound db      'Loader not found',0
367
aPressAnyKey	db	13,10,'Press any key...',13,10,0
367
aPressAnyKey    db      13,10,'Press any key...',13,10,0
368
main_loader	db	'KORDLDR F1X'
368
main_loader     db      'KORDLDR F1X'
369
 
369
 
370
if use_lba
370
if use_lba
371
	db	0	; make bootsector 512 bytes in length
371
        db      0       ; make bootsector 512 bytes in length
372
end if
372
end if
373
 
373
 
374
; bootsector signature
374
; bootsector signature
375
	dw	0xAA55
375
        dw      0xAA55
376
 
376
 
377
; display offsets of all procedures used by kordldr.f12.asm
377
; display offsets of all procedures used by kordldr.f12.asm
Line 378... Line 378...
378
macro show [procedure]
378
macro show [procedure]