Subversion Repositories Kolibri OS

Rev

Rev 1065 | Go to most recent revision | Details | Compare with Previous | 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
1132 Lrz 28
        org     0x7C00
29
        jmp     start
30
        nop
1065 Lrz 31
; FAT parameters, BPB
32
; they must be changed at install, replaced with real values
1132 Lrz 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       ;
1065 Lrz 59
 
1132 Lrz 60
curseg  dw      0x8000
1065 Lrz 61
 
62
start:
1132 Lrz 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
1065 Lrz 71
if use_lba
1132 Lrz 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_
1065 Lrz 81
else
1132 Lrz 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
1065 Lrz 90
@@:
91
end if
92
; get FAT parameters
1132 Lrz 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
1065 Lrz 107
noloader:
1132 Lrz 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     $
1065 Lrz 117
kordldr_ok:
1132 Lrz 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
1065 Lrz 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
1132 Lrz 129
        sub     eax, 2
130
        movzx   ecx, [bp+BPB_SecsPerClus-0x7C00]
131
        mul     ecx
1065 Lrz 132
 
133
read_sectors2:
134
; same as read_sectors32, but eax is relative to start of data
1132 Lrz 135
        add     eax, [bp-10]
1065 Lrz 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!
1132 Lrz 142
        pusha
143
        add     eax, [bp+BPB_HiddSec-0x7C00]
1065 Lrz 144
if use_lba
1132 Lrz 145
        push    ds
1065 Lrz 146
do_read_sectors:
1132 Lrz 147
        push    ax
148
        push    cx
149
        cmp     cx, 0x7F
150
        jbe     @f
151
        mov     cx, 0x7F
1065 Lrz 152
@@:
153
; create disk address packet on the stack
154
; dq starting LBA
1132 Lrz 155
        push    0
156
        push    0
157
        push    eax
1065 Lrz 158
; dd buffer
1132 Lrz 159
        push    es
160
        push    bx
1065 Lrz 161
; dw number of blocks to transfer (no more than 0x7F)
1132 Lrz 162
        push    cx
1065 Lrz 163
; dw packet size in bytes
1132 Lrz 164
        push    10h
1065 Lrz 165
; issue BIOS call
1132 Lrz 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_
1065 Lrz 174
; restore stack
1132 Lrz 175
        add     sp, 10h
1065 Lrz 176
; increase current sector & buffer; decrease number of sectors
1132 Lrz 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
1065 Lrz 190
else
191
do_read_sectors:
1132 Lrz 192
        pusha
193
        pop     edi     ; loword(edi) = di, hiword(edi) = si
194
        push    bx
1065 Lrz 195
 
196
; eax / (SectorsPerTrack) -> eax, remainder bx
1132 Lrz 197
        movzx   esi, [bp+BPB_SecPerTrk-0x7C00]
198
        xor     edx, edx
199
        div     esi
200
        mov     bx, dx          ; bx=sector-1
1065 Lrz 201
 
202
; eax -> dx:ax
1132 Lrz 203
        push    eax
204
        pop     ax
205
        pop     dx
1065 Lrz 206
; (dword in dx:ax) / (NumHeads) -> (word in ax), remainder dx
1132 Lrz 207
        div     [bp+BPB_NumHeads-0x7C00]
1065 Lrz 208
 
209
; number of sectors: read no more than to end of track
1132 Lrz 210
        sub     si, bx
211
        cmp     cx, si
212
        jbe     @f
213
        mov     cx, si
1065 Lrz 214
@@:
215
 
1132 Lrz 216
        inc     bx
1065 Lrz 217
; now ax=track, dl=head, dh=0, cl=number of sectors, ch=0, bl=sector; convert to int13 format
1132 Lrz 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
1065 Lrz 229
@@:
1132 Lrz 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_
1065 Lrz 240
@@:
1132 Lrz 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
1065 Lrz 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
1132 Lrz 262
;       push    0x8000
263
;       pop     es
1065 Lrz 264
; read current cluster: first cluster goes to 8000:0000, others - to 8200:0000
1132 Lrz 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
1065 Lrz 273
@@:
1132 Lrz 274
        mov     [bp-7C00h + curseg], ax
275
        pop     eax
276
        pop     es
1065 Lrz 277
; scan for filename
1132 Lrz 278
        shl     cx, 4
279
        xor     di, di
1065 Lrz 280
sloop:
1132 Lrz 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
1065 Lrz 290
scont:
1132 Lrz 291
        add     di, 0x20
292
        loop    sloop
1065 Lrz 293
; next cluster
1132 Lrz 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
1065 Lrz 304
@@:
1132 Lrz 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
1065 Lrz 313
snotfound:
1132 Lrz 314
        stc
1065 Lrz 315
sdone:
1132 Lrz 316
        ret
1065 Lrz 317
 
318
out_string:
319
; in: ds:si -> ASCIIZ string
1132 Lrz 320
        lodsb
321
        test    al, al
322
        jz      sdone
323
        mov     ah, 0Eh
324
        mov     bx, 7
325
        int     10h
326
        jmp     out_string
1065 Lrz 327
 
1132 Lrz 328
aReadError      db      'Read error',0
1065 Lrz 329
if use_lba
1132 Lrz 330
aNoLBA          db      'The drive does not support LBA!',0
1065 Lrz 331
end if
1132 Lrz 332
aLoaderNotFound db      'Loader not found',0
333
aPressAnyKey    db      13,10,'Press any key...',13,10,0
334
main_loader     db      'KORDLDR F32'
1065 Lrz 335
 
1132 Lrz 336
        db      56h
1065 Lrz 337
; just to make file 512 bytes long :)
1132 Lrz 338
        db      'd' xor 'i' xor 'a' xor 'm' xor 'o' xor 'n' xor 'd'
1065 Lrz 339
 
340
; bootsector signature
1132 Lrz 341
        dw      0xAA55
1065 Lrz 342
 
343
; display offsets of all procedures used by kordldr.f12.asm
344
macro show [procedure]
345
{
1132 Lrz 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
1065 Lrz 356
}
357
 
1132 Lrz 358
show read_sectors32, read_sectors2, err_, noloader