Subversion Repositories Kolibri OS

Rev

Rev 1962 | Go to most recent revision | 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
; they must be changed at install, replaced with real values
33
                rb      8       ; BS_OEMName, ignored
34
                dw      200h    ; BPB_BytsPerSec
35
BPB_SecsPerClus db      ?
36
BPB_RsvdSecCnt  dw      ?
37
BPB_NumFATs     db      ?
38
BPB_RootEntCnt  dw      ?
39
                dw      ?       ; BPB_TotSec16
40
                db      ?       ; BPB_Media
41
                dw      ?       ; BPB_FATSz16 = 0 for FAT32
42
BPB_SecPerTrk   dw      ?
43
BPB_NumHeads    dw      ?
44
BPB_HiddSec     dd      ?
45
                dd      ?       ; BPB_TotSec32
46
BPB_FATSz32     dd      ?
47
BPB_ExtFlags    dw      ?
48
                dw      ?       ; BPB_FSVer
49
BPB_RootClus    dd      ?
50
                dw      ?       ; BPB_FSInfo
51
BPB_BkBootSec   dw      ?
52
                rb      12      ; BPB_Reserved
53
BS_DrvNum       db      ?
54
                db      ?       ; BS_Reserved1
55
                db      ?       ; BS_BootSig
56
                dd      ?       ; BS_VolID
57
                rb      11      ; BS_VolLab
58
                rb      8       ;
59
 
60
curseg  dw      0x8000
61
 
62
start:
63
        xor     ax, ax
64
        mov     ss, ax
65
        mov     sp, 0x7C00
66
        mov     ds, ax
67
        mov     bp, sp
68
        cld
69
        sti
70
        push    dx      ; byte [bp-2] = boot drive
71
if use_lba
72
        mov     ah, 41h
73
        mov     bx, 55AAh
74
        int     13h
75
        mov     si, aNoLBA
76
        jc      err_
77
        cmp     bx, 0AA55h
78
        jnz     err_
79
        test    cl, 1
80
        jz      err_
81
else
82
        mov     ah, 8
83
        int     13h
84
        jc      @f
85
        movzx   ax, dh
86
        inc     ax
87
        mov     [bp+BPB_NumHeads-0x7C00], ax
88
        and     cx, 3Fh
89
        mov     [bp+BPB_SecPerTrk-0x7C00], cx
90
@@:
91
end if
92
; get FAT parameters
93
        xor     bx, bx
94
        movzx   eax, [bp+BPB_NumFATs-0x7C00]
95
        mul     [bp+BPB_FATSz32-0x7C00]
96
        movzx   ecx, [bp+BPB_RsvdSecCnt-0x7C00]
97
        push    ecx     ; FAT start = dword [bp-6]
98
        add     eax, ecx
99
        push    eax     ; data start = dword [bp-10]
100
        ;push   dword -1        ; dword [bp-14] = current sector for FAT cache
101
        db      66h
102
        push    -1      ; dword [bp-14] = current sector for FAT cache
103
        mov     eax, [bp+BPB_RootClus-0x7C00]
104
        mov     si, main_loader
105
        call    lookup_in_dir
106
        jnc     kordldr_ok
107
noloader:
108
        mov     si, aLoaderNotFound
109
err_:
110
        call    out_string
111
        mov     si, aPressAnyKey
112
        call    out_string
113
        xor     ax, ax
114
        int     16h
115
        int     18h
116
        jmp     $
117
kordldr_ok:
118
        mov     eax, [es:di+20-2]       ; hiword(eax) = hiword(cluster)
119
        mov     ax, [es:di+26]          ; loword(eax) = loword(cluster)
120
        mov     es, bx          ; es = 0
121
        mov     bx, 0x7E00
122
        push    bx      ; save return address: bx = 7E00
123
; fall through - 'ret' in read_cluster will return to 7E00
124
 
125
read_cluster:
126
; ss:bp = 0:7C00
127
; es:bx = pointer to data
128
; eax = cluster
129
        sub     eax, 2
130
        movzx   ecx, [bp+BPB_SecsPerClus-0x7C00]
131
        mul     ecx
132
 
133
read_sectors2:
134
; same as read_sectors32, but eax is relative to start of data
135
        add     eax, [bp-10]
136
read_sectors32:
137
; ss:bp = 0:7C00
138
; es:bx = pointer to data
139
; eax = first sector
140
; cx = number of sectors
141
; some high words of 32-bit registers are destroyed!
142
        pusha
143
        add     eax, [bp+BPB_HiddSec-0x7C00]
144
if use_lba
145
        push    ds
146
do_read_sectors:
147
        push    ax
148
        push    cx
149
        cmp     cx, 0x7F
150
        jbe     @f
151
        mov     cx, 0x7F
152
@@:
153
; create disk address packet on the stack
154
; dq starting LBA
155
        push    0
156
        push    0
157
        push    eax
158
; dd buffer
159
        push    es
160
        push    bx
161
; dw number of blocks to transfer (no more than 0x7F)
162
        push    cx
163
; dw packet size in bytes
164
        push    10h
165
; issue BIOS call
166
        push    ss
167
        pop     ds
168
        mov     si, sp
169
        mov     dl, [bp-2]
170
        mov     ah, 42h
171
        int     13h
172
        mov     si, aReadError
173
        jc      err_
174
; restore stack
175
        add     sp, 10h
176
; increase current sector & buffer; decrease number of sectors
177
        movzx   esi, cx
178
        mov     ax, es
179
        shl     cx, 5
180
        add     ax, cx
181
        mov     es, ax
182
        pop     cx
183
        pop     ax
184
        add     eax, esi
185
        sub     cx, si
186
        jnz     do_read_sectors
187
        pop     ds
188
        popa
189
        ret
190
else
191
do_read_sectors:
192
        pusha
193
        pop     edi     ; loword(edi) = di, hiword(edi) = si
194
        push    bx
195
 
196
; eax / (SectorsPerTrack) -> eax, remainder bx
197
        movzx   esi, [bp+BPB_SecPerTrk-0x7C00]
198
        xor     edx, edx
199
        div     esi
200
        mov     bx, dx          ; bx=sector-1
201
 
202
; eax -> dx:ax
203
        push    eax
204
        pop     ax
205
        pop     dx
206
; (dword in dx:ax) / (NumHeads) -> (word in ax), remainder dx
207
        div     [bp+BPB_NumHeads-0x7C00]
208
 
209
; number of sectors: read no more than to end of track
210
        sub     si, bx
211
        cmp     cx, si
212
        jbe     @f
213
        mov     cx, si
214
@@:
215
 
216
        inc     bx
217
; now ax=track, dl=head, dh=0, cl=number of sectors, ch=0, bl=sector; convert to int13 format
218
        movzx   edi, cx
219
        mov     dh, dl
220
        mov     dl, [bp-2]
221
        shl     ah, 6
222
        mov     ch, al
223
        mov     al, cl
224
        mov     cl, bl
225
        or      cl, ah
226
        pop     bx
227
        mov     si, 3
228
        mov     ah, 2
229
@@:
230
        push    ax
231
        int     13h
232
        jnc     @f
233
        xor     ax, ax
234
        int     13h     ; reset drive
235
        pop     ax
236
        dec     si
237
        jnz     @b
238
        mov     si, aReadError
239
        jmp     err_
240
@@:
241
        pop     ax
242
        mov     ax, es
243
        mov     cx, di
244
        shl     cx, 5
245
        add     ax, cx
246
        mov     es, ax
247
        push    edi
248
        popa
249
        add     eax, edi
250
        sub     cx, di
251
        jnz     do_read_sectors
252
        popa
253
        ret
254
end if
255
 
256
lookup_in_dir:
257
; in: ds:si -> 11-bytes FAT name
258
; in: eax = cluster
259
; in: bx = 0
260
; out: if found: CF=0, es:di -> directory entry
261
; out: if not found: CF=1
262
;       push    0x8000
263
;       pop     es
264
; read current cluster: first cluster goes to 8000:0000, others - to 8200:0000
265
        mov     es, [bp-7C00h + curseg]
266
        push    es
267
        push    eax
268
        call    read_cluster
269
        mov     ax, es
270
        cmp     ah, 82h
271
        jb      @f
272
        mov     ax, 8200h
273
@@:
274
        mov     [bp-7C00h + curseg], ax
275
        pop     eax
276
        pop     es
277
; scan for filename
278
        shl     cx, 4
279
        xor     di, di
280
sloop:
281
        cmp     byte [es:di], bl
282
        jz      snotfound
283
        test    byte [es:di+11], 8      ; volume label?
284
        jnz     scont                   ; ignore volume labels
285
        pusha
286
        mov     cx, 11
287
        repz cmpsb
288
        popa
289
        jz      sdone
290
scont:
291
        add     di, 0x20
292
        loop    sloop
293
; next cluster
294
        push    0x6000
295
        pop     es
296
        push    es ax
297
        shr     eax, 7
298
        cmp     eax, [bp-14]
299
        mov     [bp-14], eax
300
        jz      @f
301
        add     eax, [bp-6]
302
        mov     cx, 1
303
        call    read_sectors32
304
@@:
305
        pop     di es
306
        and     di, 0x7F
307
        shl     di, 2
308
        and     byte [es:di+3], 0x0F
309
        mov     eax, [es:di]
310
        ;and    eax, 0x0FFFFFFF
311
        cmp     eax, 0x0FFFFFF7
312
        jb      lookup_in_dir
313
snotfound:
314
        stc
315
sdone:
316
        ret
317
 
318
out_string:
319
; in: ds:si -> ASCIIZ string
320
        lodsb
321
        test    al, al
322
        jz      sdone
323
        mov     ah, 0Eh
324
        mov     bx, 7
325
        int     10h
326
        jmp     out_string
327
 
328
aReadError      db      'Read error',0
329
if use_lba
330
aNoLBA          db      'The drive does not support LBA!',0
331
end if
332
aLoaderNotFound db      'Loader not found',0
333
aPressAnyKey    db      13,10,'Press any key...',13,10,0
334
main_loader     db      'KORDLDR F32'
335
 
336
        db      56h
337
; just to make file 512 bytes long :)
338
        db      'd' xor 'i' xor 'a' xor 'm' xor 'o' xor 'n' xor 'd'
339
 
340
; bootsector signature
341
        dw      0xAA55
342
 
343
; display offsets of all procedures used by kordldr.f12.asm
344
macro show [procedure]
345
{
346
        bits = 16
347
        display `procedure,' = '
348
        repeat bits/4
349
                d = '0' + procedure shr (bits - %*4) and 0Fh
350
                if d > '9'
351
                        d = d + 'A'-'9'-1
352
                end if
353
                display d
354
        end repeat
355
        display 13,10
356
}
357
 
358
show read_sectors32, read_sectors2, err_, noloader