Subversion Repositories Kolibri OS

Rev

Rev 1962 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2288 clevermous 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