Subversion Repositories Kolibri OS

Rev

Rev 2288 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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