Another attempt at implementing a block layer
This commit is contained in:
parent
6f7fc05171
commit
e86b1ba004
168
kernel/disk.asm
Normal file
168
kernel/disk.asm
Normal 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
|
@ -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
|
|
@ -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
|
||||||
|
@ -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
|
|
||||||
|
@ -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"
|
||||||
|
Loading…
Reference in New Issue
Block a user