Subversion Repositories Kolibri OS

Rev

Rev 1132 | Go to most recent revision | Details | Last modification | View Log | RSS feed

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