vbr: now able to load first cluster

This commit is contained in:
Nero 2019-03-31 20:53:14 +00:00
parent dad80532ab
commit 9a6ecabfd7

View File

@ -1,4 +1,4 @@
org 0x0600 org 0x0000
fdc: ; FDC Descriptor as per ECMA-107 fdc: ; FDC Descriptor as per ECMA-107
jmp _startup jmp _startup
@ -9,19 +9,19 @@ fdc: ; FDC Descriptor as per ECMA-107
.ss: .ss:
dw 0x200 ; sector size dw 0x200 ; sector size
.sc: .sc:
db 0 ; sectors per cluster db 2 ; sectors per cluster
.rsc: .rsc:
dw 2 ; reserved sector count dw 1 ; reserved sector count
.fn: .fn:
db 0 ; number of file allocation tables db 2 ; number of file allocation tables
.rde: .rde:
dw 0 ; number of root directory entries dw 0x70 ; number of root directory entries
.ts: .ts:
dw 720 ; total number of sectors dw 720 ; total number of sectors
.mi: ; medium identifier .mi: ; medium identifier
db 0xFD ; 5.25-inch Double sided, 40 tracks per side, 9 sectors per track (360 KB) db 0xFD ; 5.25-inch Double sided, 40 tracks per side, 9 sectors per track (360 KB)
.sf: ; sectors per fat .sf: ; sectors per fat
dw 0 dw 2
.spt: .spt:
dw 9 ; sectors per track dw 9 ; sectors per track
.nos: .nos:
@ -44,33 +44,65 @@ fdc: ; FDC Descriptor as per ECMA-107
times (62 - ($-$$)) db " " times (62 - ($-$$)) db " "
_startup: _startup:
xor ax, ax mov ax, 0x1050
mov ds, ax ; setup relocated stack area
mov es, ax
mov ss, ax mov ss, ax
xor sp, sp xor sp, sp
; relocate ; backup important values
push bx
push cx
push dx
; setup relocated code area
mov es, ax
mov di, 0x0000
; setup start code area
xor ax, ax
mov ds, ax
mov si, 0x7C00 mov si, 0x7C00
mov di, 0x0600 ; relocate 256 words
mov cx, 0x0100 mov cx, 0x0100
rep movsw rep movsw
; adjust CS ; adjust CS
jmp 0x0000:main jmp 0x1050:main
; non-fdc variables
rootdir:
.start:
dw 0
.length:
dw 0
main: main:
mov [fdc.drv], dl ; backup drive number ; setup buffer area directly after the BDA
mov ax, 0x0050
mov ds, ax
mov es, ax
mov [cs:fdc.drv], dl ; backup drive number
call fix_chs call fix_chs
call find_first_sector call calc_sectors
call find_first_cluster
xor bx, bx
call load_cluster
call error ; restore important variables
db "END OF IMPLEMENTATION", 0 xor ax, ax
mov bp, ax
mov si, ax
mov di, ax
pop dx
pop cx
pop bx
jmp 0x0050:0000
; Write AX, a string and bail out ; Write AX, a string and bail out
; Return pointer is the string start ; Return pointer is the string start
; String must be 0 suffixed ; String must be 0 suffixed
error: error:
call print16 call print16
push cs
pop ds
pop si pop si
mov bx, 0x0000 mov bx, 0x0000
mov al, 0x20 mov al, 0x20
@ -90,41 +122,49 @@ fix_chs:
int 0x13 int 0x13
jc .end ; skip if function does not exist jc .end ; skip if function does not exist
inc dh inc dh
mov [fdc.nos], dh mov [cs:fdc.nos], dh
mov ax, cx mov ax, cx
and ax, 0x003F and ax, 0x003F
mov [fdc.spt], ax ; no adjustment because sectors are 1-indexed mov [cs:fdc.spt], ax ; no adjustment because sectors are 1-indexed
mov ax, cx mov ax, cx
xchg al, ah xchg al, ah
mov cl,6 mov cl,6
shr ah,cl shr ah,cl
inc ax ; convert from maximum number (0-based) to total number (1-based) of cylinders inc ax ; convert from maximum number (0-based) to total number (1-based) of cylinders
mul word [fdc.nos] ; number of tracks = number of cylinders * heads mul word [cs:fdc.nos] ; number of tracks = number of cylinders * heads
mul word [fdc.spt] ; number of sectors = number of tracks * sectors per track mul word [cs:fdc.spt] ; number of sectors = number of tracks * sectors per track
mov [fdc.ts], ax mov [cs:fdc.ts], ax
.end: .end:
ret ret
; Load the root directory [buffer] calc_sectors:
find_first_sector: mov bx, [cs:fdc.ss] ; bytes per sector
mov bx, [fdc.ss] ; bytes per sector
mov cl, 5 mov cl, 5
shr bx, cl ; div by 2^5, 32 bytes per directory entity shr bx, cl ; div by 2^5, 32 bytes per entry
mov ax, [fdc.rde] ; number of root directory entities mov ax, [cs:fdc.rde] ; number of entries
xor dx, dx xor dx, dx
div bx div bx
mov cx, ax ; cx = number of rootdir sectors mov [cs:rootdir.length], ax
mov ax, [fdc.sf] ; sectors per fat mov ax, [cs:fdc.sf] ; sectors per fat
mul byte [fdc.fn] ; number of fats mul byte [cs:fdc.fn] ; number of fats
add ax, [fdc.rsc] ; ax = starting sector of rootdir add ax, [cs:fdc.rsc] ; reserved sectors
mov bx, buffer mov [cs:rootdir.start], ax
ret
; Load the root directory
find_first_cluster:
mov ax, [cs:rootdir.start]
mov cx, [cs:rootdir.length]
xor bx, bx
.blkloop: .blkloop:
call loadblk call loadblk
add bx, buffer add bx, [cs:fdc.ss]
add ax, 1 add ax, 1
loop .blkloop loop .blkloop
mov cx, [fdc.rde] push cs
mov bx, buffer pop es
mov cx, [cs:fdc.rde]
xor bx, bx
.dirloop: .dirloop:
push cx push cx
mov cx, 0x000B mov cx, 0x000B
@ -138,38 +178,49 @@ find_first_sector:
call error call error
db "NOT FOUND", 0 db "NOT FOUND", 0
.found: .found:
push ds
pop es
add bx, 26 add bx, 26
mov ax, [bx] mov ax, [bx]
ret ret
; Load a single FAT cluster into memory ; Load a single FAT cluster into memory
; in ax cluster number ; in ax cluster number
; bx buffer ; es:bx buffer
; ;
loadsec: load_cluster:
call print16 xor ch, ch
mov ax, bx mov cl, [cs:fdc.sc] ; sectors per cluster
call print16 xor dx, dx
dec ax ; somehow 2 is first cluster
div word cx
add ax, [cs:rootdir.start]
add ax, [cs:rootdir.length]
.loop:
call loadblk
inc ax
add bx, [cs:fdc.ss]
loop .loop
ret ret
; Load a single block into memory ; Load a single block into memory
; Does not return on error ; Does not return on error
; in ax sector number ; in ax sector number
; bx buffer ; es:bx buffer
loadblk: loadblk:
push ax push ax
push cx push cx
push dx push dx
xor dx, dx xor dx, dx
div word [fdc.spt] ; ax:temp = (lba / spt) div word [cs:fdc.spt] ; ax:temp = (lba / spt)
inc dx ; dx:sector = (lba % spt) + 1 inc dx ; dx:sector = (lba % spt) + 1
mov cl, dl ; sector number mov cl, dl ; sector number
xor dx, dx xor dx, dx
div word [fdc.nos] ; ax:cylinder = (tmp / heads) div word [cs:fdc.nos] ; ax:cylinder = (tmp / heads)
; dx:head = (tmp % heads) ; dx:head = (tmp % heads)
mov ch, al ; cylinder number mov ch, al ; cylinder number
mov dh, dl ; head number mov dh, dl ; head number
mov dl, [fdc.drv] ; driver number mov dl, [cs:fdc.drv] ; driver number
mov ax, 0x0201 ; ah=0x02 al=0x01 mov ax, 0x0201 ; ah=0x02 al=0x01
int 0x13 int 0x13
jc .error jc .error
@ -194,5 +245,3 @@ bootfilename:
times (0x1FE - ($-$$)) db 0 times (0x1FE - ($-$$)) db 0
dw 0xAA55 dw 0xAA55
buffer: