diff --git a/kernel/cluster.asm b/kernel/cluster.asm index 2dd33b2..f66a74e 100644 --- a/kernel/cluster.asm +++ b/kernel/cluster.asm @@ -1,7 +1,95 @@ ; read/write data from FAT clusters ; requires defines from fcb.asm -read mov bp, sp - call fcbdrv +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