Style corrected for new rules, no semantic changes
git-svn-id: svn://kolibrios.org@2288 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,392 +1,392 @@
|
||||
; Copyright (c) 2008-2009, diamond
|
||||
; All rights reserved.
|
||||
;
|
||||
; Redistribution and use in source and binary forms, with or without
|
||||
; modification, are permitted provided that the following conditions are met:
|
||||
; * Redistributions of source code must retain the above copyright
|
||||
; notice, this list of conditions and the following disclaimer.
|
||||
; * Redistributions in binary form must reproduce the above copyright
|
||||
; notice, this list of conditions and the following disclaimer in the
|
||||
; documentation and/or other materials provided with the distribution.
|
||||
; * Neither the name of the <organization> nor the
|
||||
; names of its contributors may be used to endorse or promote products
|
||||
; derived from this software without specific prior written permission.
|
||||
;
|
||||
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
|
||||
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
||||
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
;*****************************************************************************
|
||||
|
||||
use_lba = 0
|
||||
org 0x7C00
|
||||
jmp start
|
||||
nop
|
||||
; FAT parameters, BPB
|
||||
; note: they can be changed at install, replaced with real values
|
||||
; these settings are for most typical 1.44M floppies
|
||||
db 'KOLIBRI ' ; BS_OEMName, ignored
|
||||
dw 200h ; BPB_BytsPerSec
|
||||
BPB_SecsPerClus db 1
|
||||
BPB_RsvdSecCnt dw 1
|
||||
BPB_NumFATs db 2
|
||||
BPB_RootEntCnt dw 0xE0
|
||||
dw 2880 ; BPB_TotSec16
|
||||
db 0xF0 ; BPB_Media
|
||||
BPB_FATSz16 dw 9
|
||||
BPB_SecPerTrk dw 18
|
||||
BPB_NumHeads dw 2
|
||||
BPB_HiddSec dd 0
|
||||
dd 0 ; BPB_TotSec32
|
||||
BS_DrvNum db 0
|
||||
db 0 ; BS_Reserved1
|
||||
db ')' ; BS_BootSig
|
||||
dd 12344321h ; BS_VolID
|
||||
filename:
|
||||
db 'KORD.OS ' ; BS_VolLab
|
||||
db 'FAT12 ' ; BS_FilSysType
|
||||
; Used memory map:
|
||||
; 8000:0000 - current directory
|
||||
; 9000:0000 - root directory data [cached]
|
||||
start:
|
||||
xor ax, ax
|
||||
mov ss, ax
|
||||
mov sp, 0x7C00
|
||||
mov ds, ax
|
||||
mov bp, sp
|
||||
cld
|
||||
sti
|
||||
mov [bp+BS_DrvNum-0x7C00], dl
|
||||
if use_lba
|
||||
mov ah, 41h
|
||||
mov bx, 55AAh
|
||||
int 13h
|
||||
mov si, aNoLBA
|
||||
jc err_
|
||||
cmp bx, 0AA55h
|
||||
jnz err_
|
||||
test cx, 1
|
||||
jz err_
|
||||
else
|
||||
mov ah, 8
|
||||
int 13h
|
||||
jc @f ; on error, assume that BPB geometry is valid
|
||||
mov al, dh
|
||||
mov ah, 0
|
||||
inc ax
|
||||
mov [bp+BPB_NumHeads-0x7C00], ax
|
||||
and cx, 3Fh
|
||||
mov [bp+BPB_SecPerTrk-0x7C00], cx
|
||||
@@:
|
||||
end if
|
||||
; get FAT parameters
|
||||
xor bx, bx
|
||||
mov al, [bp+BPB_NumFATs-0x7C00]
|
||||
mov ah, 0
|
||||
mul [bp+BPB_FATSz16-0x7C00]
|
||||
add ax, [bp+BPB_RsvdSecCnt-0x7C00]
|
||||
adc dx, bx
|
||||
push dx
|
||||
push ax ; root directory start = dword [bp-4]
|
||||
mov cx, [bp+BPB_RootEntCnt-0x7C00]
|
||||
add cx, 0xF
|
||||
rcr cx, 1
|
||||
shr cx, 3 ; cx = size of root directory in sectors
|
||||
add ax, cx
|
||||
adc dx, bx
|
||||
push dx
|
||||
push ax ; data start = dword [bp-8]
|
||||
; load start of root directory (no more than 0x2000 bytes = 0x10 sectors)
|
||||
cmp cx, 0x10
|
||||
jb @f
|
||||
mov cx, 0x10
|
||||
@@:
|
||||
mov ax, [bp-4]
|
||||
mov dx, [bp-2]
|
||||
push 0x9000
|
||||
pop es
|
||||
call read_sectors
|
||||
add word [bp-4], cx ; dword [bp-4] = start of non-cached root data
|
||||
adc word [bp-2], bx
|
||||
; load kordldr.f12
|
||||
mov si, main_loader
|
||||
call lookup_in_root_dir
|
||||
jc noloader
|
||||
test byte [es:di+11], 10h ; directory?
|
||||
jz kordldr_ok
|
||||
noloader:
|
||||
mov si, aLoaderNotFound
|
||||
err_:
|
||||
call out_string
|
||||
mov si, aPressAnyKey
|
||||
call out_string
|
||||
xor ax, ax
|
||||
int 16h
|
||||
int 18h
|
||||
jmp $
|
||||
kordldr_ok:
|
||||
mov ax, [es:di+26] ; get file cluster
|
||||
mov bx, 0x7E00
|
||||
xor cx, cx
|
||||
mov es, cx
|
||||
sub ax, 2
|
||||
jc noloader
|
||||
push bx ; save return address: bx = 7E00
|
||||
mov cl, [bp+BPB_SecsPerClus-0x7C00]
|
||||
mul cx
|
||||
; fall through - 'ret' in read_sectors will return to 7E00
|
||||
|
||||
read_sectors2:
|
||||
; same as read_sectors, but dx:ax is relative to start of data
|
||||
add ax, [bp-8]
|
||||
adc dx, [bp-6]
|
||||
read_sectors:
|
||||
; ss:bp = 0:7C00
|
||||
; es:bx = pointer to data
|
||||
; dx:ax = first sector
|
||||
; cx = number of sectors
|
||||
pusha
|
||||
add ax, word [bp+BPB_HiddSec-0x7C00]
|
||||
adc dx, word [bp+BPB_HiddSec+2-0x7C00]
|
||||
if use_lba
|
||||
push ds
|
||||
do_read_sectors:
|
||||
push ax
|
||||
push cx
|
||||
push dx
|
||||
cmp cx, 0x7F
|
||||
jbe @f
|
||||
mov cx, 0x7F
|
||||
@@:
|
||||
; create disk address packet on the stack
|
||||
; dq starting LBA
|
||||
push 0
|
||||
push 0
|
||||
push dx
|
||||
push ax
|
||||
; dd buffer
|
||||
push es
|
||||
push bx
|
||||
; dw number of blocks to transfer (no more than 0x7F)
|
||||
push cx
|
||||
; dw packet size in bytes
|
||||
push 10h
|
||||
; issue BIOS call
|
||||
push ss
|
||||
pop ds
|
||||
mov si, sp
|
||||
mov dl, [bp+BS_DrvNum-0x7C00]
|
||||
mov ah, 42h
|
||||
int 13h
|
||||
mov si, aReadError
|
||||
jc err_
|
||||
; restore stack
|
||||
add sp, 10h
|
||||
; increase current sector & buffer; decrease number of sectors
|
||||
mov si, cx
|
||||
mov ax, es
|
||||
shl cx, 5
|
||||
add ax, cx
|
||||
mov es, ax
|
||||
pop dx
|
||||
pop cx
|
||||
pop ax
|
||||
add ax, si
|
||||
adc dx, 0
|
||||
sub cx, si
|
||||
jnz do_read_sectors
|
||||
pop ds
|
||||
popa
|
||||
ret
|
||||
else
|
||||
do_read_sectors:
|
||||
pusha
|
||||
pop di
|
||||
push bx
|
||||
|
||||
; (dword in dx:ax) / (SectorsPerTrack) -> (dword in dx:ax), remainder bx
|
||||
mov si, ax
|
||||
xchg ax, dx
|
||||
xor dx, dx
|
||||
div [bp+BPB_SecPerTrk-0x7C00]
|
||||
push ax
|
||||
mov ax, si
|
||||
div [bp+BPB_SecPerTrk-0x7C00]
|
||||
mov bx, dx ; bx=sector-1
|
||||
pop dx
|
||||
|
||||
; (dword in dx:ax) / (NumHeads) -> (word in ax), remainder dx
|
||||
div [bp+BPB_NumHeads-0x7C00]
|
||||
|
||||
; number of sectors: read no more than to end of track
|
||||
push bx
|
||||
sub bx, [bp+BPB_SecPerTrk-0x7C00]
|
||||
neg bx
|
||||
cmp cx, bx
|
||||
jbe @f
|
||||
mov cx, bx
|
||||
@@:
|
||||
pop bx
|
||||
|
||||
inc bx
|
||||
; now ax=track, dl=head, dh=0, cl=number of sectors, ch=0, bl=sector; convert to int13 format
|
||||
mov di, cx
|
||||
mov dh, dl
|
||||
mov dl, [bp+BS_DrvNum-0x7C00]
|
||||
shl ah, 6
|
||||
mov ch, al
|
||||
mov al, cl
|
||||
mov cl, bl
|
||||
or cl, ah
|
||||
pop bx
|
||||
mov si, 3
|
||||
mov ah, 2
|
||||
@@:
|
||||
push ax
|
||||
int 13h
|
||||
jnc @f
|
||||
xor ax, ax
|
||||
int 13h ; reset drive
|
||||
pop ax
|
||||
dec si
|
||||
jnz @b
|
||||
mov si, aReadError
|
||||
jmp err_
|
||||
@@:
|
||||
pop ax
|
||||
mov ax, es
|
||||
mov cx, di
|
||||
shl cx, 5
|
||||
add ax, cx
|
||||
mov es, ax
|
||||
push di
|
||||
popa
|
||||
add ax, di
|
||||
adc dx, 0
|
||||
sub cx, di
|
||||
jnz do_read_sectors
|
||||
popa
|
||||
ret
|
||||
end if
|
||||
|
||||
scan_for_filename:
|
||||
; in: ds:si -> 11-bytes FAT name
|
||||
; in: es:0 -> part of directory data
|
||||
; in: cx = number of entries
|
||||
; out: if found: CF=0, ZF=1, es:di -> directory entry
|
||||
; out: if not found, but continue required: CF=1 and ZF=0
|
||||
; out: if not found and zero item reached: CF=1 and ZF=1
|
||||
xor di, di
|
||||
push cx
|
||||
sloop:
|
||||
cmp byte [es:di], 0
|
||||
jz snotfound
|
||||
test byte [es:di+11], 8 ; volume label?
|
||||
jnz scont ; ignore volume labels
|
||||
pusha
|
||||
mov cx, 11
|
||||
repz cmpsb
|
||||
popa
|
||||
jz sdone
|
||||
scont:
|
||||
add di, 0x20
|
||||
loop sloop
|
||||
inc cx ; clear ZF flag
|
||||
snotfound:
|
||||
stc
|
||||
sdone:
|
||||
pop cx
|
||||
lrdret:
|
||||
ret
|
||||
|
||||
lookup_in_root_dir:
|
||||
; ss:bp = 0:7C00
|
||||
; in: ds:si -> 11-bytes FAT name
|
||||
; out: if found: CF=0, es:di -> directory entry
|
||||
; out: if not found: CF=1
|
||||
mov cx, [bp+BPB_RootEntCnt-0x7C00]
|
||||
push cx
|
||||
; first, look in root directory cache
|
||||
push 0x9000
|
||||
pop es
|
||||
test ch, ch
|
||||
jz @f
|
||||
mov cx, 0x100
|
||||
@@:
|
||||
mov ax, [bp-4]
|
||||
mov dx, [bp-2] ; dx:ax = starting sector of not cached data of root directory
|
||||
lrdloop:
|
||||
call scan_for_filename
|
||||
pop bx
|
||||
jz lrdret
|
||||
sub bx, cx
|
||||
mov cx, bx
|
||||
stc
|
||||
jz lrdret
|
||||
; read no more than 0x10000 bytes, or 0x10000/0x20 = 0x800 entries
|
||||
push cx
|
||||
cmp ch, 0x8
|
||||
jb @f
|
||||
mov cx, 0x800
|
||||
@@:
|
||||
push 0x8000
|
||||
pop es
|
||||
push cx
|
||||
push es
|
||||
xor bx, bx
|
||||
add cx, 0xF
|
||||
shr cx, 4
|
||||
call read_sectors
|
||||
pop es
|
||||
add ax, cx
|
||||
adc dx, bx
|
||||
pop cx
|
||||
jmp lrdloop
|
||||
|
||||
out_string:
|
||||
; in: ds:si -> ASCIIZ string
|
||||
lodsb
|
||||
test al, al
|
||||
jz lrdret
|
||||
mov ah, 0Eh
|
||||
mov bx, 7
|
||||
int 10h
|
||||
jmp out_string
|
||||
|
||||
aReadError db 'Read error',0
|
||||
if use_lba
|
||||
aNoLBA db 'The drive does not support LBA!',0
|
||||
end if
|
||||
aLoaderNotFound db 'Loader not found',0
|
||||
aPressAnyKey db 13,10,'Press any key...',13,10,0
|
||||
main_loader db 'KORDLDR F1X'
|
||||
|
||||
if use_lba
|
||||
db 0 ; make bootsector 512 bytes in length
|
||||
end if
|
||||
|
||||
; bootsector signature
|
||||
dw 0xAA55
|
||||
|
||||
; display offsets of all procedures used by kordldr.f12.asm
|
||||
macro show [procedure]
|
||||
{
|
||||
bits = 16
|
||||
display `procedure,' = '
|
||||
repeat bits/4
|
||||
d = '0' + procedure shr (bits - %*4) and 0Fh
|
||||
if d > '9'
|
||||
d = d + 'A'-'9'-1
|
||||
end if
|
||||
display d
|
||||
end repeat
|
||||
display 13,10
|
||||
}
|
||||
|
||||
show read_sectors, read_sectors2, lookup_in_root_dir, scan_for_filename, err_, noloader
|
||||
; Copyright (c) 2008-2009, diamond
|
||||
; All rights reserved.
|
||||
;
|
||||
; Redistribution and use in source and binary forms, with or without
|
||||
; modification, are permitted provided that the following conditions are met:
|
||||
; * Redistributions of source code must retain the above copyright
|
||||
; notice, this list of conditions and the following disclaimer.
|
||||
; * Redistributions in binary form must reproduce the above copyright
|
||||
; notice, this list of conditions and the following disclaimer in the
|
||||
; documentation and/or other materials provided with the distribution.
|
||||
; * Neither the name of the <organization> nor the
|
||||
; names of its contributors may be used to endorse or promote products
|
||||
; derived from this software without specific prior written permission.
|
||||
;
|
||||
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
|
||||
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
||||
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
;*****************************************************************************
|
||||
|
||||
use_lba = 0
|
||||
org 0x7C00
|
||||
jmp start
|
||||
nop
|
||||
; FAT parameters, BPB
|
||||
; note: they can be changed at install, replaced with real values
|
||||
; these settings are for most typical 1.44M floppies
|
||||
db 'KOLIBRI ' ; BS_OEMName, ignored
|
||||
dw 200h ; BPB_BytsPerSec
|
||||
BPB_SecsPerClus db 1
|
||||
BPB_RsvdSecCnt dw 1
|
||||
BPB_NumFATs db 2
|
||||
BPB_RootEntCnt dw 0xE0
|
||||
dw 2880 ; BPB_TotSec16
|
||||
db 0xF0 ; BPB_Media
|
||||
BPB_FATSz16 dw 9
|
||||
BPB_SecPerTrk dw 18
|
||||
BPB_NumHeads dw 2
|
||||
BPB_HiddSec dd 0
|
||||
dd 0 ; BPB_TotSec32
|
||||
BS_DrvNum db 0
|
||||
db 0 ; BS_Reserved1
|
||||
db ')' ; BS_BootSig
|
||||
dd 12344321h ; BS_VolID
|
||||
filename:
|
||||
db 'KORD.OS ' ; BS_VolLab
|
||||
db 'FAT12 ' ; BS_FilSysType
|
||||
; Used memory map:
|
||||
; 8000:0000 - current directory
|
||||
; 9000:0000 - root directory data [cached]
|
||||
start:
|
||||
xor ax, ax
|
||||
mov ss, ax
|
||||
mov sp, 0x7C00
|
||||
mov ds, ax
|
||||
mov bp, sp
|
||||
cld
|
||||
sti
|
||||
mov [bp+BS_DrvNum-0x7C00], dl
|
||||
if use_lba
|
||||
mov ah, 41h
|
||||
mov bx, 55AAh
|
||||
int 13h
|
||||
mov si, aNoLBA
|
||||
jc err_
|
||||
cmp bx, 0AA55h
|
||||
jnz err_
|
||||
test cx, 1
|
||||
jz err_
|
||||
else
|
||||
mov ah, 8
|
||||
int 13h
|
||||
jc @f ; on error, assume that BPB geometry is valid
|
||||
mov al, dh
|
||||
mov ah, 0
|
||||
inc ax
|
||||
mov [bp+BPB_NumHeads-0x7C00], ax
|
||||
and cx, 3Fh
|
||||
mov [bp+BPB_SecPerTrk-0x7C00], cx
|
||||
@@:
|
||||
end if
|
||||
; get FAT parameters
|
||||
xor bx, bx
|
||||
mov al, [bp+BPB_NumFATs-0x7C00]
|
||||
mov ah, 0
|
||||
mul [bp+BPB_FATSz16-0x7C00]
|
||||
add ax, [bp+BPB_RsvdSecCnt-0x7C00]
|
||||
adc dx, bx
|
||||
push dx
|
||||
push ax ; root directory start = dword [bp-4]
|
||||
mov cx, [bp+BPB_RootEntCnt-0x7C00]
|
||||
add cx, 0xF
|
||||
rcr cx, 1
|
||||
shr cx, 3 ; cx = size of root directory in sectors
|
||||
add ax, cx
|
||||
adc dx, bx
|
||||
push dx
|
||||
push ax ; data start = dword [bp-8]
|
||||
; load start of root directory (no more than 0x2000 bytes = 0x10 sectors)
|
||||
cmp cx, 0x10
|
||||
jb @f
|
||||
mov cx, 0x10
|
||||
@@:
|
||||
mov ax, [bp-4]
|
||||
mov dx, [bp-2]
|
||||
push 0x9000
|
||||
pop es
|
||||
call read_sectors
|
||||
add word [bp-4], cx ; dword [bp-4] = start of non-cached root data
|
||||
adc word [bp-2], bx
|
||||
; load kordldr.f12
|
||||
mov si, main_loader
|
||||
call lookup_in_root_dir
|
||||
jc noloader
|
||||
test byte [es:di+11], 10h ; directory?
|
||||
jz kordldr_ok
|
||||
noloader:
|
||||
mov si, aLoaderNotFound
|
||||
err_:
|
||||
call out_string
|
||||
mov si, aPressAnyKey
|
||||
call out_string
|
||||
xor ax, ax
|
||||
int 16h
|
||||
int 18h
|
||||
jmp $
|
||||
kordldr_ok:
|
||||
mov ax, [es:di+26] ; get file cluster
|
||||
mov bx, 0x7E00
|
||||
xor cx, cx
|
||||
mov es, cx
|
||||
sub ax, 2
|
||||
jc noloader
|
||||
push bx ; save return address: bx = 7E00
|
||||
mov cl, [bp+BPB_SecsPerClus-0x7C00]
|
||||
mul cx
|
||||
; fall through - 'ret' in read_sectors will return to 7E00
|
||||
|
||||
read_sectors2:
|
||||
; same as read_sectors, but dx:ax is relative to start of data
|
||||
add ax, [bp-8]
|
||||
adc dx, [bp-6]
|
||||
read_sectors:
|
||||
; ss:bp = 0:7C00
|
||||
; es:bx = pointer to data
|
||||
; dx:ax = first sector
|
||||
; cx = number of sectors
|
||||
pusha
|
||||
add ax, word [bp+BPB_HiddSec-0x7C00]
|
||||
adc dx, word [bp+BPB_HiddSec+2-0x7C00]
|
||||
if use_lba
|
||||
push ds
|
||||
do_read_sectors:
|
||||
push ax
|
||||
push cx
|
||||
push dx
|
||||
cmp cx, 0x7F
|
||||
jbe @f
|
||||
mov cx, 0x7F
|
||||
@@:
|
||||
; create disk address packet on the stack
|
||||
; dq starting LBA
|
||||
push 0
|
||||
push 0
|
||||
push dx
|
||||
push ax
|
||||
; dd buffer
|
||||
push es
|
||||
push bx
|
||||
; dw number of blocks to transfer (no more than 0x7F)
|
||||
push cx
|
||||
; dw packet size in bytes
|
||||
push 10h
|
||||
; issue BIOS call
|
||||
push ss
|
||||
pop ds
|
||||
mov si, sp
|
||||
mov dl, [bp+BS_DrvNum-0x7C00]
|
||||
mov ah, 42h
|
||||
int 13h
|
||||
mov si, aReadError
|
||||
jc err_
|
||||
; restore stack
|
||||
add sp, 10h
|
||||
; increase current sector & buffer; decrease number of sectors
|
||||
mov si, cx
|
||||
mov ax, es
|
||||
shl cx, 5
|
||||
add ax, cx
|
||||
mov es, ax
|
||||
pop dx
|
||||
pop cx
|
||||
pop ax
|
||||
add ax, si
|
||||
adc dx, 0
|
||||
sub cx, si
|
||||
jnz do_read_sectors
|
||||
pop ds
|
||||
popa
|
||||
ret
|
||||
else
|
||||
do_read_sectors:
|
||||
pusha
|
||||
pop di
|
||||
push bx
|
||||
|
||||
; (dword in dx:ax) / (SectorsPerTrack) -> (dword in dx:ax), remainder bx
|
||||
mov si, ax
|
||||
xchg ax, dx
|
||||
xor dx, dx
|
||||
div [bp+BPB_SecPerTrk-0x7C00]
|
||||
push ax
|
||||
mov ax, si
|
||||
div [bp+BPB_SecPerTrk-0x7C00]
|
||||
mov bx, dx ; bx=sector-1
|
||||
pop dx
|
||||
|
||||
; (dword in dx:ax) / (NumHeads) -> (word in ax), remainder dx
|
||||
div [bp+BPB_NumHeads-0x7C00]
|
||||
|
||||
; number of sectors: read no more than to end of track
|
||||
push bx
|
||||
sub bx, [bp+BPB_SecPerTrk-0x7C00]
|
||||
neg bx
|
||||
cmp cx, bx
|
||||
jbe @f
|
||||
mov cx, bx
|
||||
@@:
|
||||
pop bx
|
||||
|
||||
inc bx
|
||||
; now ax=track, dl=head, dh=0, cl=number of sectors, ch=0, bl=sector; convert to int13 format
|
||||
mov di, cx
|
||||
mov dh, dl
|
||||
mov dl, [bp+BS_DrvNum-0x7C00]
|
||||
shl ah, 6
|
||||
mov ch, al
|
||||
mov al, cl
|
||||
mov cl, bl
|
||||
or cl, ah
|
||||
pop bx
|
||||
mov si, 3
|
||||
mov ah, 2
|
||||
@@:
|
||||
push ax
|
||||
int 13h
|
||||
jnc @f
|
||||
xor ax, ax
|
||||
int 13h ; reset drive
|
||||
pop ax
|
||||
dec si
|
||||
jnz @b
|
||||
mov si, aReadError
|
||||
jmp err_
|
||||
@@:
|
||||
pop ax
|
||||
mov ax, es
|
||||
mov cx, di
|
||||
shl cx, 5
|
||||
add ax, cx
|
||||
mov es, ax
|
||||
push di
|
||||
popa
|
||||
add ax, di
|
||||
adc dx, 0
|
||||
sub cx, di
|
||||
jnz do_read_sectors
|
||||
popa
|
||||
ret
|
||||
end if
|
||||
|
||||
scan_for_filename:
|
||||
; in: ds:si -> 11-bytes FAT name
|
||||
; in: es:0 -> part of directory data
|
||||
; in: cx = number of entries
|
||||
; out: if found: CF=0, ZF=1, es:di -> directory entry
|
||||
; out: if not found, but continue required: CF=1 and ZF=0
|
||||
; out: if not found and zero item reached: CF=1 and ZF=1
|
||||
xor di, di
|
||||
push cx
|
||||
sloop:
|
||||
cmp byte [es:di], 0
|
||||
jz snotfound
|
||||
test byte [es:di+11], 8 ; volume label?
|
||||
jnz scont ; ignore volume labels
|
||||
pusha
|
||||
mov cx, 11
|
||||
repz cmpsb
|
||||
popa
|
||||
jz sdone
|
||||
scont:
|
||||
add di, 0x20
|
||||
loop sloop
|
||||
inc cx ; clear ZF flag
|
||||
snotfound:
|
||||
stc
|
||||
sdone:
|
||||
pop cx
|
||||
lrdret:
|
||||
ret
|
||||
|
||||
lookup_in_root_dir:
|
||||
; ss:bp = 0:7C00
|
||||
; in: ds:si -> 11-bytes FAT name
|
||||
; out: if found: CF=0, es:di -> directory entry
|
||||
; out: if not found: CF=1
|
||||
mov cx, [bp+BPB_RootEntCnt-0x7C00]
|
||||
push cx
|
||||
; first, look in root directory cache
|
||||
push 0x9000
|
||||
pop es
|
||||
test ch, ch
|
||||
jz @f
|
||||
mov cx, 0x100
|
||||
@@:
|
||||
mov ax, [bp-4]
|
||||
mov dx, [bp-2] ; dx:ax = starting sector of not cached data of root directory
|
||||
lrdloop:
|
||||
call scan_for_filename
|
||||
pop bx
|
||||
jz lrdret
|
||||
sub bx, cx
|
||||
mov cx, bx
|
||||
stc
|
||||
jz lrdret
|
||||
; read no more than 0x10000 bytes, or 0x10000/0x20 = 0x800 entries
|
||||
push cx
|
||||
cmp ch, 0x8
|
||||
jb @f
|
||||
mov cx, 0x800
|
||||
@@:
|
||||
push 0x8000
|
||||
pop es
|
||||
push cx
|
||||
push es
|
||||
xor bx, bx
|
||||
add cx, 0xF
|
||||
shr cx, 4
|
||||
call read_sectors
|
||||
pop es
|
||||
add ax, cx
|
||||
adc dx, bx
|
||||
pop cx
|
||||
jmp lrdloop
|
||||
|
||||
out_string:
|
||||
; in: ds:si -> ASCIIZ string
|
||||
lodsb
|
||||
test al, al
|
||||
jz lrdret
|
||||
mov ah, 0Eh
|
||||
mov bx, 7
|
||||
int 10h
|
||||
jmp out_string
|
||||
|
||||
aReadError db 'Read error',0
|
||||
if use_lba
|
||||
aNoLBA db 'The drive does not support LBA!',0
|
||||
end if
|
||||
aLoaderNotFound db 'Loader not found',0
|
||||
aPressAnyKey db 13,10,'Press any key...',13,10,0
|
||||
main_loader db 'KORDLDR F1X'
|
||||
|
||||
if use_lba
|
||||
db 0 ; make bootsector 512 bytes in length
|
||||
end if
|
||||
|
||||
; bootsector signature
|
||||
dw 0xAA55
|
||||
|
||||
; display offsets of all procedures used by kordldr.f12.asm
|
||||
macro show [procedure]
|
||||
{
|
||||
bits = 16
|
||||
display `procedure,' = '
|
||||
repeat bits/4
|
||||
d = '0' + procedure shr (bits - %*4) and 0Fh
|
||||
if d > '9'
|
||||
d = d + 'A'-'9'-1
|
||||
end if
|
||||
display d
|
||||
end repeat
|
||||
display 13,10
|
||||
}
|
||||
|
||||
show read_sectors, read_sectors2, lookup_in_root_dir, scan_for_filename, err_, noloader
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,358 +1,358 @@
|
||||
; Copyright (c) 2008-2009, diamond
|
||||
; All rights reserved.
|
||||
;
|
||||
; Redistribution and use in source and binary forms, with or without
|
||||
; modification, are permitted provided that the following conditions are met:
|
||||
; * Redistributions of source code must retain the above copyright
|
||||
; notice, this list of conditions and the following disclaimer.
|
||||
; * Redistributions in binary form must reproduce the above copyright
|
||||
; notice, this list of conditions and the following disclaimer in the
|
||||
; documentation and/or other materials provided with the distribution.
|
||||
; * Neither the name of the <organization> nor the
|
||||
; names of its contributors may be used to endorse or promote products
|
||||
; derived from this software without specific prior written permission.
|
||||
;
|
||||
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
|
||||
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
||||
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
;*****************************************************************************
|
||||
|
||||
use_lba = 0
|
||||
org 0x7C00
|
||||
jmp start
|
||||
nop
|
||||
; FAT parameters, BPB
|
||||
; they must be changed at install, replaced with real values
|
||||
rb 8 ; BS_OEMName, ignored
|
||||
dw 200h ; BPB_BytsPerSec
|
||||
BPB_SecsPerClus db ?
|
||||
BPB_RsvdSecCnt dw ?
|
||||
BPB_NumFATs db ?
|
||||
BPB_RootEntCnt dw ?
|
||||
dw ? ; BPB_TotSec16
|
||||
db ? ; BPB_Media
|
||||
dw ? ; BPB_FATSz16 = 0 for FAT32
|
||||
BPB_SecPerTrk dw ?
|
||||
BPB_NumHeads dw ?
|
||||
BPB_HiddSec dd ?
|
||||
dd ? ; BPB_TotSec32
|
||||
BPB_FATSz32 dd ?
|
||||
BPB_ExtFlags dw ?
|
||||
dw ? ; BPB_FSVer
|
||||
BPB_RootClus dd ?
|
||||
dw ? ; BPB_FSInfo
|
||||
BPB_BkBootSec dw ?
|
||||
rb 12 ; BPB_Reserved
|
||||
BS_DrvNum db ?
|
||||
db ? ; BS_Reserved1
|
||||
db ? ; BS_BootSig
|
||||
dd ? ; BS_VolID
|
||||
rb 11 ; BS_VolLab
|
||||
rb 8 ;
|
||||
|
||||
curseg dw 0x8000
|
||||
|
||||
start:
|
||||
xor ax, ax
|
||||
mov ss, ax
|
||||
mov sp, 0x7C00
|
||||
mov ds, ax
|
||||
mov bp, sp
|
||||
cld
|
||||
sti
|
||||
push dx ; byte [bp-2] = boot drive
|
||||
if use_lba
|
||||
mov ah, 41h
|
||||
mov bx, 55AAh
|
||||
int 13h
|
||||
mov si, aNoLBA
|
||||
jc err_
|
||||
cmp bx, 0AA55h
|
||||
jnz err_
|
||||
test cl, 1
|
||||
jz err_
|
||||
else
|
||||
mov ah, 8
|
||||
int 13h
|
||||
jc @f
|
||||
movzx ax, dh
|
||||
inc ax
|
||||
mov [bp+BPB_NumHeads-0x7C00], ax
|
||||
and cx, 3Fh
|
||||
mov [bp+BPB_SecPerTrk-0x7C00], cx
|
||||
@@:
|
||||
end if
|
||||
; get FAT parameters
|
||||
xor bx, bx
|
||||
movzx eax, [bp+BPB_NumFATs-0x7C00]
|
||||
mul [bp+BPB_FATSz32-0x7C00]
|
||||
movzx ecx, [bp+BPB_RsvdSecCnt-0x7C00]
|
||||
push ecx ; FAT start = dword [bp-6]
|
||||
add eax, ecx
|
||||
push eax ; data start = dword [bp-10]
|
||||
;push dword -1 ; dword [bp-14] = current sector for FAT cache
|
||||
db 66h
|
||||
push -1 ; dword [bp-14] = current sector for FAT cache
|
||||
mov eax, [bp+BPB_RootClus-0x7C00]
|
||||
mov si, main_loader
|
||||
call lookup_in_dir
|
||||
jnc kordldr_ok
|
||||
noloader:
|
||||
mov si, aLoaderNotFound
|
||||
err_:
|
||||
call out_string
|
||||
mov si, aPressAnyKey
|
||||
call out_string
|
||||
xor ax, ax
|
||||
int 16h
|
||||
int 18h
|
||||
jmp $
|
||||
kordldr_ok:
|
||||
mov eax, [es:di+20-2] ; hiword(eax) = hiword(cluster)
|
||||
mov ax, [es:di+26] ; loword(eax) = loword(cluster)
|
||||
mov es, bx ; es = 0
|
||||
mov bx, 0x7E00
|
||||
push bx ; save return address: bx = 7E00
|
||||
; fall through - 'ret' in read_cluster will return to 7E00
|
||||
|
||||
read_cluster:
|
||||
; ss:bp = 0:7C00
|
||||
; es:bx = pointer to data
|
||||
; eax = cluster
|
||||
sub eax, 2
|
||||
movzx ecx, [bp+BPB_SecsPerClus-0x7C00]
|
||||
mul ecx
|
||||
|
||||
read_sectors2:
|
||||
; same as read_sectors32, but eax is relative to start of data
|
||||
add eax, [bp-10]
|
||||
read_sectors32:
|
||||
; ss:bp = 0:7C00
|
||||
; es:bx = pointer to data
|
||||
; eax = first sector
|
||||
; cx = number of sectors
|
||||
; some high words of 32-bit registers are destroyed!
|
||||
pusha
|
||||
add eax, [bp+BPB_HiddSec-0x7C00]
|
||||
if use_lba
|
||||
push ds
|
||||
do_read_sectors:
|
||||
push ax
|
||||
push cx
|
||||
cmp cx, 0x7F
|
||||
jbe @f
|
||||
mov cx, 0x7F
|
||||
@@:
|
||||
; create disk address packet on the stack
|
||||
; dq starting LBA
|
||||
push 0
|
||||
push 0
|
||||
push eax
|
||||
; dd buffer
|
||||
push es
|
||||
push bx
|
||||
; dw number of blocks to transfer (no more than 0x7F)
|
||||
push cx
|
||||
; dw packet size in bytes
|
||||
push 10h
|
||||
; issue BIOS call
|
||||
push ss
|
||||
pop ds
|
||||
mov si, sp
|
||||
mov dl, [bp-2]
|
||||
mov ah, 42h
|
||||
int 13h
|
||||
mov si, aReadError
|
||||
jc err_
|
||||
; restore stack
|
||||
add sp, 10h
|
||||
; increase current sector & buffer; decrease number of sectors
|
||||
movzx esi, cx
|
||||
mov ax, es
|
||||
shl cx, 5
|
||||
add ax, cx
|
||||
mov es, ax
|
||||
pop cx
|
||||
pop ax
|
||||
add eax, esi
|
||||
sub cx, si
|
||||
jnz do_read_sectors
|
||||
pop ds
|
||||
popa
|
||||
ret
|
||||
else
|
||||
do_read_sectors:
|
||||
pusha
|
||||
pop edi ; loword(edi) = di, hiword(edi) = si
|
||||
push bx
|
||||
|
||||
; eax / (SectorsPerTrack) -> eax, remainder bx
|
||||
movzx esi, [bp+BPB_SecPerTrk-0x7C00]
|
||||
xor edx, edx
|
||||
div esi
|
||||
mov bx, dx ; bx=sector-1
|
||||
|
||||
; eax -> dx:ax
|
||||
push eax
|
||||
pop ax
|
||||
pop dx
|
||||
; (dword in dx:ax) / (NumHeads) -> (word in ax), remainder dx
|
||||
div [bp+BPB_NumHeads-0x7C00]
|
||||
|
||||
; number of sectors: read no more than to end of track
|
||||
sub si, bx
|
||||
cmp cx, si
|
||||
jbe @f
|
||||
mov cx, si
|
||||
@@:
|
||||
|
||||
inc bx
|
||||
; now ax=track, dl=head, dh=0, cl=number of sectors, ch=0, bl=sector; convert to int13 format
|
||||
movzx edi, cx
|
||||
mov dh, dl
|
||||
mov dl, [bp-2]
|
||||
shl ah, 6
|
||||
mov ch, al
|
||||
mov al, cl
|
||||
mov cl, bl
|
||||
or cl, ah
|
||||
pop bx
|
||||
mov si, 3
|
||||
mov ah, 2
|
||||
@@:
|
||||
push ax
|
||||
int 13h
|
||||
jnc @f
|
||||
xor ax, ax
|
||||
int 13h ; reset drive
|
||||
pop ax
|
||||
dec si
|
||||
jnz @b
|
||||
mov si, aReadError
|
||||
jmp err_
|
||||
@@:
|
||||
pop ax
|
||||
mov ax, es
|
||||
mov cx, di
|
||||
shl cx, 5
|
||||
add ax, cx
|
||||
mov es, ax
|
||||
push edi
|
||||
popa
|
||||
add eax, edi
|
||||
sub cx, di
|
||||
jnz do_read_sectors
|
||||
popa
|
||||
ret
|
||||
end if
|
||||
|
||||
lookup_in_dir:
|
||||
; in: ds:si -> 11-bytes FAT name
|
||||
; in: eax = cluster
|
||||
; in: bx = 0
|
||||
; out: if found: CF=0, es:di -> directory entry
|
||||
; out: if not found: CF=1
|
||||
; push 0x8000
|
||||
; pop es
|
||||
; read current cluster: first cluster goes to 8000:0000, others - to 8200:0000
|
||||
mov es, [bp-7C00h + curseg]
|
||||
push es
|
||||
push eax
|
||||
call read_cluster
|
||||
mov ax, es
|
||||
cmp ah, 82h
|
||||
jb @f
|
||||
mov ax, 8200h
|
||||
@@:
|
||||
mov [bp-7C00h + curseg], ax
|
||||
pop eax
|
||||
pop es
|
||||
; scan for filename
|
||||
shl cx, 4
|
||||
xor di, di
|
||||
sloop:
|
||||
cmp byte [es:di], bl
|
||||
jz snotfound
|
||||
test byte [es:di+11], 8 ; volume label?
|
||||
jnz scont ; ignore volume labels
|
||||
pusha
|
||||
mov cx, 11
|
||||
repz cmpsb
|
||||
popa
|
||||
jz sdone
|
||||
scont:
|
||||
add di, 0x20
|
||||
loop sloop
|
||||
; next cluster
|
||||
push 0x6000
|
||||
pop es
|
||||
push es ax
|
||||
shr eax, 7
|
||||
cmp eax, [bp-14]
|
||||
mov [bp-14], eax
|
||||
jz @f
|
||||
add eax, [bp-6]
|
||||
mov cx, 1
|
||||
call read_sectors32
|
||||
@@:
|
||||
pop di es
|
||||
and di, 0x7F
|
||||
shl di, 2
|
||||
and byte [es:di+3], 0x0F
|
||||
mov eax, [es:di]
|
||||
;and eax, 0x0FFFFFFF
|
||||
cmp eax, 0x0FFFFFF7
|
||||
jb lookup_in_dir
|
||||
snotfound:
|
||||
stc
|
||||
sdone:
|
||||
ret
|
||||
|
||||
out_string:
|
||||
; in: ds:si -> ASCIIZ string
|
||||
lodsb
|
||||
test al, al
|
||||
jz sdone
|
||||
mov ah, 0Eh
|
||||
mov bx, 7
|
||||
int 10h
|
||||
jmp out_string
|
||||
|
||||
aReadError db 'Read error',0
|
||||
if use_lba
|
||||
aNoLBA db 'The drive does not support LBA!',0
|
||||
end if
|
||||
aLoaderNotFound db 'Loader not found',0
|
||||
aPressAnyKey db 13,10,'Press any key...',13,10,0
|
||||
main_loader db 'KORDLDR F32'
|
||||
|
||||
db 56h
|
||||
; just to make file 512 bytes long :)
|
||||
db 'd' xor 'i' xor 'a' xor 'm' xor 'o' xor 'n' xor 'd'
|
||||
|
||||
; bootsector signature
|
||||
dw 0xAA55
|
||||
|
||||
; display offsets of all procedures used by kordldr.f12.asm
|
||||
macro show [procedure]
|
||||
{
|
||||
bits = 16
|
||||
display `procedure,' = '
|
||||
repeat bits/4
|
||||
d = '0' + procedure shr (bits - %*4) and 0Fh
|
||||
if d > '9'
|
||||
d = d + 'A'-'9'-1
|
||||
end if
|
||||
display d
|
||||
end repeat
|
||||
display 13,10
|
||||
}
|
||||
|
||||
show read_sectors32, read_sectors2, err_, noloader
|
||||
; Copyright (c) 2008-2009, diamond
|
||||
; All rights reserved.
|
||||
;
|
||||
; Redistribution and use in source and binary forms, with or without
|
||||
; modification, are permitted provided that the following conditions are met:
|
||||
; * Redistributions of source code must retain the above copyright
|
||||
; notice, this list of conditions and the following disclaimer.
|
||||
; * Redistributions in binary form must reproduce the above copyright
|
||||
; notice, this list of conditions and the following disclaimer in the
|
||||
; documentation and/or other materials provided with the distribution.
|
||||
; * Neither the name of the <organization> nor the
|
||||
; names of its contributors may be used to endorse or promote products
|
||||
; derived from this software without specific prior written permission.
|
||||
;
|
||||
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
|
||||
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
||||
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
;*****************************************************************************
|
||||
|
||||
use_lba = 0
|
||||
org 0x7C00
|
||||
jmp start
|
||||
nop
|
||||
; FAT parameters, BPB
|
||||
; they must be changed at install, replaced with real values
|
||||
rb 8 ; BS_OEMName, ignored
|
||||
dw 200h ; BPB_BytsPerSec
|
||||
BPB_SecsPerClus db ?
|
||||
BPB_RsvdSecCnt dw ?
|
||||
BPB_NumFATs db ?
|
||||
BPB_RootEntCnt dw ?
|
||||
dw ? ; BPB_TotSec16
|
||||
db ? ; BPB_Media
|
||||
dw ? ; BPB_FATSz16 = 0 for FAT32
|
||||
BPB_SecPerTrk dw ?
|
||||
BPB_NumHeads dw ?
|
||||
BPB_HiddSec dd ?
|
||||
dd ? ; BPB_TotSec32
|
||||
BPB_FATSz32 dd ?
|
||||
BPB_ExtFlags dw ?
|
||||
dw ? ; BPB_FSVer
|
||||
BPB_RootClus dd ?
|
||||
dw ? ; BPB_FSInfo
|
||||
BPB_BkBootSec dw ?
|
||||
rb 12 ; BPB_Reserved
|
||||
BS_DrvNum db ?
|
||||
db ? ; BS_Reserved1
|
||||
db ? ; BS_BootSig
|
||||
dd ? ; BS_VolID
|
||||
rb 11 ; BS_VolLab
|
||||
rb 8 ;
|
||||
|
||||
curseg dw 0x8000
|
||||
|
||||
start:
|
||||
xor ax, ax
|
||||
mov ss, ax
|
||||
mov sp, 0x7C00
|
||||
mov ds, ax
|
||||
mov bp, sp
|
||||
cld
|
||||
sti
|
||||
push dx ; byte [bp-2] = boot drive
|
||||
if use_lba
|
||||
mov ah, 41h
|
||||
mov bx, 55AAh
|
||||
int 13h
|
||||
mov si, aNoLBA
|
||||
jc err_
|
||||
cmp bx, 0AA55h
|
||||
jnz err_
|
||||
test cl, 1
|
||||
jz err_
|
||||
else
|
||||
mov ah, 8
|
||||
int 13h
|
||||
jc @f
|
||||
movzx ax, dh
|
||||
inc ax
|
||||
mov [bp+BPB_NumHeads-0x7C00], ax
|
||||
and cx, 3Fh
|
||||
mov [bp+BPB_SecPerTrk-0x7C00], cx
|
||||
@@:
|
||||
end if
|
||||
; get FAT parameters
|
||||
xor bx, bx
|
||||
movzx eax, [bp+BPB_NumFATs-0x7C00]
|
||||
mul [bp+BPB_FATSz32-0x7C00]
|
||||
movzx ecx, [bp+BPB_RsvdSecCnt-0x7C00]
|
||||
push ecx ; FAT start = dword [bp-6]
|
||||
add eax, ecx
|
||||
push eax ; data start = dword [bp-10]
|
||||
;push dword -1 ; dword [bp-14] = current sector for FAT cache
|
||||
db 66h
|
||||
push -1 ; dword [bp-14] = current sector for FAT cache
|
||||
mov eax, [bp+BPB_RootClus-0x7C00]
|
||||
mov si, main_loader
|
||||
call lookup_in_dir
|
||||
jnc kordldr_ok
|
||||
noloader:
|
||||
mov si, aLoaderNotFound
|
||||
err_:
|
||||
call out_string
|
||||
mov si, aPressAnyKey
|
||||
call out_string
|
||||
xor ax, ax
|
||||
int 16h
|
||||
int 18h
|
||||
jmp $
|
||||
kordldr_ok:
|
||||
mov eax, [es:di+20-2] ; hiword(eax) = hiword(cluster)
|
||||
mov ax, [es:di+26] ; loword(eax) = loword(cluster)
|
||||
mov es, bx ; es = 0
|
||||
mov bx, 0x7E00
|
||||
push bx ; save return address: bx = 7E00
|
||||
; fall through - 'ret' in read_cluster will return to 7E00
|
||||
|
||||
read_cluster:
|
||||
; ss:bp = 0:7C00
|
||||
; es:bx = pointer to data
|
||||
; eax = cluster
|
||||
sub eax, 2
|
||||
movzx ecx, [bp+BPB_SecsPerClus-0x7C00]
|
||||
mul ecx
|
||||
|
||||
read_sectors2:
|
||||
; same as read_sectors32, but eax is relative to start of data
|
||||
add eax, [bp-10]
|
||||
read_sectors32:
|
||||
; ss:bp = 0:7C00
|
||||
; es:bx = pointer to data
|
||||
; eax = first sector
|
||||
; cx = number of sectors
|
||||
; some high words of 32-bit registers are destroyed!
|
||||
pusha
|
||||
add eax, [bp+BPB_HiddSec-0x7C00]
|
||||
if use_lba
|
||||
push ds
|
||||
do_read_sectors:
|
||||
push ax
|
||||
push cx
|
||||
cmp cx, 0x7F
|
||||
jbe @f
|
||||
mov cx, 0x7F
|
||||
@@:
|
||||
; create disk address packet on the stack
|
||||
; dq starting LBA
|
||||
push 0
|
||||
push 0
|
||||
push eax
|
||||
; dd buffer
|
||||
push es
|
||||
push bx
|
||||
; dw number of blocks to transfer (no more than 0x7F)
|
||||
push cx
|
||||
; dw packet size in bytes
|
||||
push 10h
|
||||
; issue BIOS call
|
||||
push ss
|
||||
pop ds
|
||||
mov si, sp
|
||||
mov dl, [bp-2]
|
||||
mov ah, 42h
|
||||
int 13h
|
||||
mov si, aReadError
|
||||
jc err_
|
||||
; restore stack
|
||||
add sp, 10h
|
||||
; increase current sector & buffer; decrease number of sectors
|
||||
movzx esi, cx
|
||||
mov ax, es
|
||||
shl cx, 5
|
||||
add ax, cx
|
||||
mov es, ax
|
||||
pop cx
|
||||
pop ax
|
||||
add eax, esi
|
||||
sub cx, si
|
||||
jnz do_read_sectors
|
||||
pop ds
|
||||
popa
|
||||
ret
|
||||
else
|
||||
do_read_sectors:
|
||||
pusha
|
||||
pop edi ; loword(edi) = di, hiword(edi) = si
|
||||
push bx
|
||||
|
||||
; eax / (SectorsPerTrack) -> eax, remainder bx
|
||||
movzx esi, [bp+BPB_SecPerTrk-0x7C00]
|
||||
xor edx, edx
|
||||
div esi
|
||||
mov bx, dx ; bx=sector-1
|
||||
|
||||
; eax -> dx:ax
|
||||
push eax
|
||||
pop ax
|
||||
pop dx
|
||||
; (dword in dx:ax) / (NumHeads) -> (word in ax), remainder dx
|
||||
div [bp+BPB_NumHeads-0x7C00]
|
||||
|
||||
; number of sectors: read no more than to end of track
|
||||
sub si, bx
|
||||
cmp cx, si
|
||||
jbe @f
|
||||
mov cx, si
|
||||
@@:
|
||||
|
||||
inc bx
|
||||
; now ax=track, dl=head, dh=0, cl=number of sectors, ch=0, bl=sector; convert to int13 format
|
||||
movzx edi, cx
|
||||
mov dh, dl
|
||||
mov dl, [bp-2]
|
||||
shl ah, 6
|
||||
mov ch, al
|
||||
mov al, cl
|
||||
mov cl, bl
|
||||
or cl, ah
|
||||
pop bx
|
||||
mov si, 3
|
||||
mov ah, 2
|
||||
@@:
|
||||
push ax
|
||||
int 13h
|
||||
jnc @f
|
||||
xor ax, ax
|
||||
int 13h ; reset drive
|
||||
pop ax
|
||||
dec si
|
||||
jnz @b
|
||||
mov si, aReadError
|
||||
jmp err_
|
||||
@@:
|
||||
pop ax
|
||||
mov ax, es
|
||||
mov cx, di
|
||||
shl cx, 5
|
||||
add ax, cx
|
||||
mov es, ax
|
||||
push edi
|
||||
popa
|
||||
add eax, edi
|
||||
sub cx, di
|
||||
jnz do_read_sectors
|
||||
popa
|
||||
ret
|
||||
end if
|
||||
|
||||
lookup_in_dir:
|
||||
; in: ds:si -> 11-bytes FAT name
|
||||
; in: eax = cluster
|
||||
; in: bx = 0
|
||||
; out: if found: CF=0, es:di -> directory entry
|
||||
; out: if not found: CF=1
|
||||
; push 0x8000
|
||||
; pop es
|
||||
; read current cluster: first cluster goes to 8000:0000, others - to 8200:0000
|
||||
mov es, [bp-7C00h + curseg]
|
||||
push es
|
||||
push eax
|
||||
call read_cluster
|
||||
mov ax, es
|
||||
cmp ah, 82h
|
||||
jb @f
|
||||
mov ax, 8200h
|
||||
@@:
|
||||
mov [bp-7C00h + curseg], ax
|
||||
pop eax
|
||||
pop es
|
||||
; scan for filename
|
||||
shl cx, 4
|
||||
xor di, di
|
||||
sloop:
|
||||
cmp byte [es:di], bl
|
||||
jz snotfound
|
||||
test byte [es:di+11], 8 ; volume label?
|
||||
jnz scont ; ignore volume labels
|
||||
pusha
|
||||
mov cx, 11
|
||||
repz cmpsb
|
||||
popa
|
||||
jz sdone
|
||||
scont:
|
||||
add di, 0x20
|
||||
loop sloop
|
||||
; next cluster
|
||||
push 0x6000
|
||||
pop es
|
||||
push es ax
|
||||
shr eax, 7
|
||||
cmp eax, [bp-14]
|
||||
mov [bp-14], eax
|
||||
jz @f
|
||||
add eax, [bp-6]
|
||||
mov cx, 1
|
||||
call read_sectors32
|
||||
@@:
|
||||
pop di es
|
||||
and di, 0x7F
|
||||
shl di, 2
|
||||
and byte [es:di+3], 0x0F
|
||||
mov eax, [es:di]
|
||||
;and eax, 0x0FFFFFFF
|
||||
cmp eax, 0x0FFFFFF7
|
||||
jb lookup_in_dir
|
||||
snotfound:
|
||||
stc
|
||||
sdone:
|
||||
ret
|
||||
|
||||
out_string:
|
||||
; in: ds:si -> ASCIIZ string
|
||||
lodsb
|
||||
test al, al
|
||||
jz sdone
|
||||
mov ah, 0Eh
|
||||
mov bx, 7
|
||||
int 10h
|
||||
jmp out_string
|
||||
|
||||
aReadError db 'Read error',0
|
||||
if use_lba
|
||||
aNoLBA db 'The drive does not support LBA!',0
|
||||
end if
|
||||
aLoaderNotFound db 'Loader not found',0
|
||||
aPressAnyKey db 13,10,'Press any key...',13,10,0
|
||||
main_loader db 'KORDLDR F32'
|
||||
|
||||
db 56h
|
||||
; just to make file 512 bytes long :)
|
||||
db 'd' xor 'i' xor 'a' xor 'm' xor 'o' xor 'n' xor 'd'
|
||||
|
||||
; bootsector signature
|
||||
dw 0xAA55
|
||||
|
||||
; display offsets of all procedures used by kordldr.f12.asm
|
||||
macro show [procedure]
|
||||
{
|
||||
bits = 16
|
||||
display `procedure,' = '
|
||||
repeat bits/4
|
||||
d = '0' + procedure shr (bits - %*4) and 0Fh
|
||||
if d > '9'
|
||||
d = d + 'A'-'9'-1
|
||||
end if
|
||||
display d
|
||||
end repeat
|
||||
display 13,10
|
||||
}
|
||||
|
||||
show read_sectors32, read_sectors2, err_, noloader
|
||||
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user