rdos/kernel/cluster.asm

96 lines
1.5 KiB
NASM

; read/write data from FAT clusters
; requires defines from fcb.asm
section .rodata
; sector sizes for fast lookup
sstab dw 0x800,0x400,0x200,0x100,0x80
section .text
; Map part of cluster into dskbuf
; IN DX:AX sector number within cluster area
mapclus mov bx, [cs:bpb+BPBRDE]
mov cl, 4
shr bx, cl ; 32 bytes per entry
add ax, bx
adc dx, 0
; counting from beginning of dir
; add fat table sizes
maprde xor ch, ch
mov cl, byte [cs:bpb+BPBFN]
.loop add ax, [cs:bpb+BPBFS]
adc dx, 0
loop .loop
; counting from beginning of FAT
; add reserved sector count
mapfat add ax, [cs:bpb+BPBRSC]
adc dx, 0
jmp maprel
; split AX at a bit boundary
; basically a DIV 2^CX
; IN ax divident
; cx integer log2(divisor)
; OUT ax quotient
; dx remainder (lower CX bits)
split mov dx, 1
shl dx, cl
dec dx
and dx, ax
shr ax, cl
ret
filesec call fcbdrv
mov bx, dx
; find sector size scale factor
mov ax, cs
mov es, ax
mov ax, [cs:bpb+BPBSS]
mov di, sstab
mov cx, 5
repne scasw
; CX is now sector size div 128
; same format as in DPT
mov ah, 0
mov al, [ds:bx+FCBRN]
call split
; ax = sector within current cluster
; dx = record number
push dx
mov di, ax
mov ax, [ds:bx+FCBCLUS]
sub ax, 2
mov ch, 0
mov cl, [cs:bpb+BPBSC]
mul cx
add ax, di
call mapclus
pop bx
mov cl, 7
shl bx, cl
add bx, dskbuf
mov dx, bx
mov ax, cs
mov ds, ax
ret
read mov bp, sp
call filesec
call getdta
mov cx, 0x80
call stofar
ret
write mov bp, sp
call filesec
call getdta
mov cx, 0x80
call lodfar
call dirty
ret