Below is my code:
Code: Select all
File.ReadSectors.Params.DestinationSegment: equ 10 ; 2 bytes
File.ReadSectors.Params.ReadSector: equ 8 ; 2 bytes
File.ReadSectors.Params.SectorCount: equ 6 ; 2 bytes
File.ReadSectors.Params.MemoryOffset: equ 4 ; 2 bytes
File.ReadSectors.ParamsSize: equ 8
File.ReadSectors.LocalsSize: equ 0
File.ReadSectors:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; name: File.ReadSectors.read_sectors
; action: reads one or more disk sectors into memory
; in: ES:0=address of memory where sectors should be read
; DX:AX=first sector to read
; CX=number of sectors to read
; out (disk error): CY=1
; out (success): CY=0
; modifies: DX, CX, AX
; minimum CPU: 8088
; notes:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Prologue
enter File.ReadSectors.LocalsSize, 0
pushad
call Memory.ClearGeneralRegisters
mov word ax, word [ebp + File.ReadSectors.Params.DestinationSegment]
mov word es, word ax
mov word cx, word [ebp + File.ReadSectors.Params.SectorCount]
mov word ax, word [ebp + File.ReadSectors.Params.ReadSector]
xor word dx, word dx
File.ReadSectors.read_sectors:
push es
push bx
;xor bx,bx
mov bx, word [ebp + File.ReadSectors.Params.MemoryOffset]
; add partition start
;xchg bx, bx
add ax, word [File.FatInfo.HiddenSectors + 0] ; [bp - (over - hidden_sectors) + 0]
adc dx, word [File.FatInfo.HiddenSectors + 2]
File.ReadSectors.read_sectors_1:
push dx
push cx
push ax
; DX:AX=LBA sector number
push ax
mov ax,dx
xor dx,dx
; divide LBA by sectors_per_track (spt).
; Use a two-step 32-bit/16-bit divide to avoid overflow.
; See "9.3.5 Extended Precision Division" in Randall Hyde's "Art of Assembly"
div word [File.FatInfo.SectorsPerTrack] ; [bp- (over - sectors_per_track)]
; DX=high LBA % spt, AX=high LBA / spt
mov cx,ax
pop ax
; DX=high LBA % spt, CX=high LBA / spt, AX=low LBA
; New 32-bit dividend is DX:AX
div word [File.FatInfo.SectorsPerTrack] ; [bp- (over - sectors_per_track)]
; CX:AX=LBA / spt, DX=LBA % spt
xchg cx,dx
inc cx ; CL=sector
; DX:AX=LBA / spt, do normal one-step divide by heads value
div word [File.FatInfo.NumberOfHeads] ; [bp - (over - heads)]
mov dh,dl ; DH=head
mov ch,al ; CH=cylinder 7:0
mov dl, byte [File.FatInfo.DriveLetter] ; [bp - (over - boot_drive)]
shl cl,1
shl cl,1 ; trying to use only...
shr ah,1 ; ...8088 asm here
rcr cl,1
shr ah,1
rcr cl,1 ; CL7:6=cyl 9:8, CL5:0=sector
; now: read one sector
mov ax,0201h
int 13h
jnc File.ReadSectors.read_sectors_3
; disk error; recalibrate/reset drive
mov ah,0
int 13h
jc File.ReadSectors.read_sectors_2
; try the read again. If it fails a second time, give up.
mov ax,0201h
int 13h
jnc File.ReadSectors.read_sectors_3
File.ReadSectors.read_sectors_2:
pop ax
pop cx
pop dx
jmp short File.ReadSectors.read_sectors_5
; advance memory pointer
File.ReadSectors.read_sectors_3:
mov ax,es
add ax, 32 ; [File.FatInfo.ParagrahsPerSector] ; [bp - (over - para_per_sector)]
mov es,ax
pop ax
pop cx
pop dx
; increment DX:AX to advance to next sector
inc ax
jne File.ReadSectors.read_sectors_4
inc dx
File.ReadSectors.read_sectors_4:
loop File.ReadSectors.read_sectors_1
; clear CY bit to signal success
clc
File.ReadSectors.read_sectors_5:
pop bx
pop es
;ret
File.ReadSectors.End:
; Epilogue
popad
leave
ret File.ReadSectors.ParamsSize



