Another attempt at implementing a block layer

This commit is contained in:
Nero 2019-10-20 09:56:27 +00:00
parent 6f7fc05171
commit e86b1ba004
5 changed files with 174 additions and 137 deletions

168
kernel/disk.asm Normal file
View File

@ -0,0 +1,168 @@
disk_num: equ 0x40 ; BYTE drive number (A=0)
disk_heads: equ 0x41 ; BYTE number of heads/sides
disk_parm: equ 0x42 ; 11 BYTES for int 0x1E
disk_spt: equ 0x46 ; - BYTE
disk_parm_init:
push ax
push si
push di
push ds
; invalidate existing data
mov byte [disk_num], 0xFF
xor ax, ax
mov ds, ax
; if int 0x1E is already pointing to us,
; we have nothing to copy
mov di, disk_parm
lds si, [0x1E*4]
cmp si, di
je .correctparm
; copy bios table into our location
mov cx, 11
rep movsb
; make the interrupt vector point to our address
xor ax, ax
mov ds, ax
mov [0x1E*4], di
mov ax, cs
mov [0x1E*4+2], ax
.correctparm:
pop ds
pop di
pop si
pop ax
ret
disk_load_bpb:
mov ax, 0x0201
mov cx, 0x0001
xor dh, dh
mov bx, diskbuf
stc
int 0x13
jnc .end
; try a second time
mov ax, 0x0201
int 0x13
jnc .end
; try a third time
mov ax, 0x0201
int 0x13
.end:
ret
disk_select:
push ax
push cx
push dx
push bx
cmp byte [disk_num], dl
je .end
mov byte [disk_num], dl
call disk_load_bpb
jc .end
; Validate and apply sector size
mov ax, [diskbuf+fdc_ss]
; test ax, 0xF87F
; jnz .nobpd
call log2
sub al, 7
mov [disk_parm+3], al
; fetch sectors per track
mov al, [diskbuf+fdc_spt]
mov [disk_parm+4], al
; fetch number of sides/heads
mov ax, [diskbuf+fdc_nos]
mov [disk_heads], al
xor ah, ah
int 0x13
.end:
pop bx
pop dx
pop cx
pop ax
ret
; Setup CX, DX and BX for int 13h transfer
; IN BX ptr to 32-bit number
; OUT CL Sector number
; CH Cylinder number
; DL Drive number
; DH Head number
; BX Sector buffer
disk_prepare_chs:
mov ax, word [bx]
mov dx, word [bx+2]
xor bh, bh
mov bl, byte [disk_spt]
div word bx ; ax:temp = (lba / spt)
inc dx ; dx:sector = (lba % spt) + 1
mov cl, dl ; sector number
xor bx, bx
mov bl, byte [disk_heads]
xor dx, dx
div word bx ; ax:cylinder = (temp / nos)
; dx:head = (temp % nos)
mov ch, al ; cylinder number
mov dh, dl ; head number
mov dl, byte [disk_num]
mov bx, diskbuf
ret
; Read a sector into diskbuf
; IN BX ptr to DWORD giving sector number
disk_read:
push ax
push cx
push dx
push bx
call disk_prepare_chs
mov ax, 0x0201
int 0x13
pop bx
pop dx
pop cx
pop ax
ret
; Write a sector from diskbuf
; IN BX ptr to DWORD giving sector number
disk_write:
push ax
push cx
push dx
push bx
call disk_prepare_chs
mov ax, 0x0301
int 0x13
pop bx
pop dx
pop cx
pop ax
ret

View File

@ -1,70 +0,0 @@
; Load a sector from drive.
; IN DX:AX sector number (lba)
; BX ptr to FCB
; OUT CL Sector number
; CH Cylinder number
; DH Head number
drive_chs_calc:
push bx ; backup fcb ptr
mov bx, [bx+fcb_spt] ; nos is in BH now
push bx ; backup nos
xor bh, bh ; zero out nos so spt is left
div word bx ; ax:temp = (lba / spt)
inc dx ; dx:sector = (lba % spt) + 1
mov cl, dl ; sector number
pop bx ; restore nos
xchg bl, bh ; put nos into bl
xor bh, bh ; zero out spt
div word bx ; ax:cylinder = (temp / nos)
; dx:head = (temp % nos)
mov ch, al ; cylinder number
mov dh, dl ; head number
pop bx ; restore fcb ptr
ret
; Load a sector from drive.
; IN DX:AX sector number
; BX ptr to FCB
drive_read:
push ax
push cx
push dx
push bx
push si
mov cx, dx
or cx, ax
jz .fast
call drive_chs_calc
mov si, 5 ; retry count
.try:
mov dl, [bx+fcb_drv] ; drive number
and dl, 0x7F
dec dl
mov ax, 0x0201
mov bx, diskbuf
; try read
int 0x13
jnc .end
; reset disk
mov ah, 0x00
int 0x13
; loop with si
dec si
test si, si
jnz .try
stc
.end:
pop si
pop bx
pop dx
pop cx
pop ax
ret
.fast: ; fast lane for boot sector
inc cl
jmp .try

View File

@ -7,7 +7,6 @@ exec:
mov bx, sp mov bx, sp
call fcb_parse call fcb_parse
call fcb_open_rootdir
add sp, 0x20 add sp, 0x20
pop bx pop bx

View File

@ -5,67 +5,4 @@ fcb_drv: equ 0 ; 1 byte, 1=A: 2=B: 3=C:
fcb_fn: equ 1 ; 8 bytes fcb_fn: equ 1 ; 8 bytes
fcb_ext: equ 9 ; 3 bytes fcb_ext: equ 9 ; 3 bytes
; Drive & FS data (6 bytes) fcb_type: equ 12 ; BYTE type identifier
fcb_spt: equ 12 ; byte sectors per track
fcb_nos: equ 13 ; byte number of sides/heads
fcb_ss: equ 14 ; byte sector size: 0=128, 1=256, 2=512, ...
fcb_cs: equ 15 ; byte cluster size: 0=128, 1=256, 2=512, ...
fcb_co: equ 16 ; word start sector for theoretical cluster 0
; Read/Write pointer (6 bytes)
fcb_left: equ 18 ; word number of bytes left to read in current sector
fcb_off: equ 20 ; dword offset in disk (not in file)
; Link to directory item (4 bytes)
fcb_ds: equ 24 ; dword offset of directory item
fcb_end: equ 32
fcb_open_rootdir:
mov dl, 0x01
or dl, 0x80
mov [bx], dl
dec dl
; Setup default data
; Default 2 heads, 9 sectors
mov word [bx+fcb_spt], 0x0209
xor ax, ax
xor dx, dx
lea di, [bx+fcb_ss]
; Sector & Cluster size 128 bytes
mov cx, (fcb_end - fcb_ss)
rep stosb
; load first sector
call drive_read
; copy sector size
mov ax, [diskbuf + fdc_ss]
call log2
sub ax, 7
; ... save as sector size
mov byte [bx+fcb_ss], al
; copy cluster size
xor ah, ah
mov al, [diskbuf + 0x0D]
call log2
add al, [bx+fcb_ss]
mov byte [bx+fcb_cs], al
; copy sectors per track
mov al, [diskbuf + fdc_spt]
mov byte [bx+fcb_spt], al
; copy number of heads/sides
mov al, [diskbuf + 0x1A]
mov byte [bx+fcb_nos], al
xor dx, dx
mov ax, [diskbuf + fdc_sf]
mul byte [diskbuf + fdc_fn]
add ax, [diskbuf + fdc_rsc]
int3
ret

View File

@ -22,7 +22,10 @@ init:
mov dx, banner mov dx, banner
call print_string call print_string
call exec_chain call disk_parm_init
mov dl, 0x00
call disk_select
cli cli
.halt: .halt:
@ -52,6 +55,6 @@ cpm_syscall:
%include "fdc.asm" %include "fdc.asm"
%include "fcb.asm" %include "fcb.asm"
%include "fcbparse.asm" %include "fcbparse.asm"
%include "drive.asm" %include "disk.asm"
%include "log2.asm" %include "log2.asm"
%include "dump.asm" %include "dump.asm"