Int 13h/AH=2 requires you to set AL to the number of sectors to read. Since you don't set it before calling disk read it is probably an invalid value (likely 0). You need to tell it how many sectors to read. You shouldn't hard code the. Copy DL to a temporary memory location (ie
boot_drive: db 0x00) and then copy the value the bIOS passes to the bootloader. So right
after you set up the segment registers do something like
mov [boot_drive], dl. Then in reset_disk and the LBAToCHS routines you can set DL with
mov [boot_drive], dl rather than hard coding zero.
As well your LBAToCHS routine is buggy. Based on the stackoverflow answer I pointed to you a few days ago this routine should replace what you currently have with a version that works:
Code: Select all
;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
; Function: LBAToCHS
; Description: Translate Logical block address to CHS (Cylinder, Head, Sector).
; Works for all valid FAT12 compatible disk geometries.
;
; Resources: http://www.ctyme.com/intr/rb-0607.htm
; https://en.wikipedia.org/wiki/Logical_block_addressing#CHS_conversion
; https://stackoverflow.com/q/45434899/3857942
; Sector = (LBA mod SPT) + 1
; Head = (LBA / SPT) mod HEADS
; Cylinder = (LBA / SPT) / HEADS
;
; Inputs: AX = LBA
; Outputs: DL = Boot Drive Number
; DH = Head
; CH = Cylinder (lower 8 bits of 10-bit cylinder)
; CL = Sector/Cylinder
; Upper 2 bits of 10-bit Cylinders in upper 2 bits of CL
; Sector in lower 6 bits of CL
; AX = Clobbered
;
; Notes: Output registers match expectation of Int 13h/AH=2 inputs
;
LBAToCHS:
xor dx, dx ; Upper 16-bit of 32-bit value set to 0 for DIV
div word [bpbSectorsPerTrack] ; 32-bit by 16-bit DIV : LBA / SPT
mov cl, dl ; CL = S = LBA mod SPT
inc cl ; CL = S = (LBA mod SPT) + 1
xor dx, dx ; Upper 16-bit of 32-bit value set to 0 for DIV
div word [bpbHeadsPerCylinder]
; 32-bit by 16-bit DIV : (LBA / SPT) / HEADS
mov dh, dl ; DH = H = (LBA / SPT) mod HEADS
mov dl, [boot_drive] ; boot drive
mov ch, al ; CH = C(lower 8 bits) = (LBA / SPT) / HEADS
shl ah, 6 ; Store upper 2 bits of 10-bit Cylinder into
or cl, ah ; upper 2 bits of Sector (CL)
ret
Now the big issue is that before you call disk_read you need to set AL to the number of sectors to read. For a simple test you should read 1 sector. I noticed you modified your code to hard code the number of FAT tables to 2. you can use the value in the BPB. Replace:
Code: Select all
mov ax, word [bpbSectorsPerFAT]
mov bx, 0x0002
mul bx
With:
Code: Select all
mov ax, word [bpbSectorsPerFAT]
xor bh, bh
mov bl, [bpbNumberOfFATs]
mul bx
Note: XOR'ing a register with itself is the same as zeroing that register. It is a preferred idiom for zeroing a register if you don't care about the flags being clobbered.
FAT12 uses 8.3 file naming convention. When stored in the FAT all file names are 11 bytes wide and the period is dropped.
KERNEL db 'TerSysVI BIN' should be
KERNEL db 'TerSysVIBIN' (Also be aware of issues with case as it related to FAT12)