diff --git a/boot/kernel.asm b/boot/kernel.asm index 86543df..e190edf 100644 --- a/boot/kernel.asm +++ b/boot/kernel.asm @@ -24,6 +24,10 @@ print_banner: mov si, banner cmp al, 0x0D jnz .loop + push dx + call dinit + pop dx + cmp dl, 0x80 jc .k sub dl, (0x80-2) diff --git a/kernel/drive.asm b/kernel/drive.asm index 4582af6..bfd0c32 100644 --- a/kernel/drive.asm +++ b/kernel/drive.asm @@ -28,6 +28,45 @@ bpb: resb BPBSIZ4 section .text + ; initial setup for disk i/o +dinit: ; copy previously set DPT to our data area + lds si, [4*0x1E] + mov di, dpt + mov cx, 11 + rep movsb + ; restore DS + xor ax, ax + mov ds, ax + ; set vector + mov word [4*0x1E], dpt + mov word [4*0x1E+2], ds + ret + + ; restore DPT to default values if possible + ; IN dl bios drive number +rstdpt: mov ah, 8 + int 0x13 + jc .ret + mov ax, es + or ax, di + test ax, ax + jz .ret + ; DS:SI = ES:DI + mov ax, es + mov ds, ax + mov si, di + ; ES:DI = dpt + xor ax, ax + mov es, ax + mov di, dpt + ; do the copy + mov cx, 11 + rep movsb +.ret: ; restore DS to 0 + xor ax, ax + mov ds, ax + ret + ; log in drive ; currently only supports 18 sectors 2 heads floppies ; IN dl drive number @@ -46,6 +85,8 @@ logdrv: ; dont do anything if drive already selected mov [dsknum], dl ; save info for bios mov [biosnum], dl + ; reset dpt to defaults + call rstdpt ; set default geometry (1.44 MB floppy) mov word [bpb+BPBNOS], 2 mov word [bpb+BPBSPT], 18 @@ -54,10 +95,14 @@ logdrv: ; dont do anything if drive already selected xor dx, dx call mapabs ; copy bios parameter block - lea si, [dskbuf+BPBOFF] + ; TODO: guess from first byte of FAT if BPB invalid + mov si, dskbuf+BPBOFF mov di, bpb mov cx, BPBSIZ4 rep movsb + ; copy SPT to DPT + mov al, [bpb+BPBSPT] + mov [dpt+4], al ; make sure partition offset is forced zero xor ax, ax mov [bpb+BPBHS], ax @@ -68,7 +113,7 @@ calchs: ; put sectors per cylinder into bx mov ax, [bpb+BPBSPT] mul word [bpb+BPBNOS] mov bx, ax - ; but linear sector num into dx:ax + ; put linear sector num into dx:ax mov ax, [dskseek] mov dx, [dskseek+2] ; dx:ax = linear count, bx = sectors / cylinder