518 lines
10 KiB
NASM
518 lines
10 KiB
NASM
|
|
DOSSEG
|
|
.MODEL LARGE
|
|
|
|
include disk.inc
|
|
|
|
.DATA?
|
|
public DiskList
|
|
DiskList dd ?
|
|
|
|
|
|
.CODE
|
|
ASSUME ds:NOTHING
|
|
|
|
extrn InitializeInt13DiskList:far
|
|
extrn OpenInt13Disk:far
|
|
extrn CloseInt13Disk:far
|
|
extrn Int13DiskIo:far
|
|
extrn GetInt13DiskInfo:far
|
|
|
|
.386
|
|
|
|
;++
|
|
;
|
|
; UINT
|
|
; _far
|
|
; InitializeDiskList(
|
|
; VOID
|
|
; );
|
|
;
|
|
; Routine Description:
|
|
;
|
|
; This routine initializes internal data structures necessary so that
|
|
; other disk-related routines in this module can be called.
|
|
;
|
|
; A data structure for each disk (currently int13 units only) is built
|
|
; and saved away. The structure contains various info such as
|
|
; drive geometry.
|
|
;
|
|
; This routine may be called multiple times. Subsequent calls after
|
|
; the first simply return the disk count.
|
|
;
|
|
; Arguments:
|
|
;
|
|
; None.
|
|
;
|
|
; Return Value:
|
|
;
|
|
; Total count of all hard drives that we can deal with.
|
|
; 0 if an error occurs.
|
|
;
|
|
;--
|
|
|
|
public _InitializeDiskList
|
|
_InitializeDiskList proc far
|
|
|
|
push ds
|
|
push si
|
|
|
|
;
|
|
; See if we're initialized yet by counting items in the DiskList
|
|
; linked list. If 0, then assume not initialized yet.
|
|
;
|
|
mov ax,DGROUP
|
|
mov ds,ax
|
|
mov si,OFFSET DGROUP:DiskList
|
|
|
|
mov ax,0
|
|
|
|
idl1:
|
|
.errnz DiskInfoNextl
|
|
|
|
mov cx,[si].DiskInfoNextl
|
|
or cx,[si].DiskInfoNexth
|
|
jz idl2
|
|
inc ax
|
|
lds si,[si].DiskInfoNext
|
|
jmp short idl1
|
|
idl2:
|
|
cmp ax,0
|
|
jne idl3
|
|
|
|
;
|
|
; Currently we deal with int13 disks only.
|
|
;
|
|
push ax ; disk ids start at 0
|
|
call InitializeInt13DiskList
|
|
add sp,2
|
|
|
|
idl3:
|
|
pop si
|
|
pop ds
|
|
retf
|
|
|
|
_InitializeDiskList endp
|
|
|
|
|
|
;++
|
|
;
|
|
; HDISK
|
|
; _far
|
|
; OpenDisk(
|
|
; IN UINT DiskId
|
|
; );
|
|
;
|
|
; Routine Description:
|
|
;
|
|
; This routine "opens" a disk so that i/o can be performed to it.
|
|
; Housekeeping such as locking, etc, is performed.
|
|
; A disk can be opened only once at a time.
|
|
;
|
|
; Arguments:
|
|
;
|
|
; DiskId - supplies an ordinal value for the disk to be opened.
|
|
; Range is 0 - n-1, where n is the value returned by
|
|
; InitializeDiskList().
|
|
;
|
|
; Return Value:
|
|
;
|
|
; Handle, or 0 if an error occurs.
|
|
;
|
|
;--
|
|
|
|
DiskId equ word ptr [bp+6]
|
|
|
|
public _OpenDisk
|
|
_OpenDisk proc far
|
|
|
|
push bp
|
|
mov bp,sp
|
|
|
|
push ds
|
|
push si
|
|
|
|
;
|
|
; Locate the disk record corresponding to this disk id.
|
|
;
|
|
mov ax,DiskId
|
|
call far ptr pLocateDiskRecord
|
|
mov cx,si
|
|
or cx,dx
|
|
mov ax,0
|
|
jz od_done ; dx:ax already 0 for error return
|
|
|
|
od_gotrec:
|
|
;
|
|
; Make sure disk is not already open
|
|
;
|
|
cmp [si].DiskInfoDiskOpen,al
|
|
jz @f
|
|
mov dx,ax ; dx:ax = 0
|
|
jnz od_done ; disk already open, error.
|
|
@@:
|
|
;
|
|
; Int13 disks only for now.
|
|
;
|
|
push ds
|
|
push si
|
|
call OpenInt13Disk
|
|
pop si
|
|
pop ds
|
|
|
|
cmp ax,0
|
|
jnz @f
|
|
mov dx,ax
|
|
jz od_done ; error, dx:ax set for return
|
|
|
|
@@: inc [si].DiskInfoDiskOpen
|
|
mov dx,ds
|
|
mov ax,si ; dx:ax = handle for return
|
|
|
|
od_done:
|
|
pop si
|
|
pop ds
|
|
|
|
leave
|
|
retf
|
|
|
|
_OpenDisk endp
|
|
|
|
|
|
;++
|
|
;
|
|
; VOID
|
|
; _far
|
|
; CloseDisk(
|
|
; IN HDISK DiskHandle
|
|
; );
|
|
;
|
|
; Routine Description:
|
|
;
|
|
; This routine "closes" a disk previously opened by OpenDisk().
|
|
; Housekeeping such as unlocking, etc, is performed.
|
|
;
|
|
; Arguments:
|
|
;
|
|
; DiskHandle - supplies the handle of the disk to be closed,
|
|
; as previously opened by OpenDisk().
|
|
;
|
|
; Return Value:
|
|
;
|
|
; None.
|
|
;
|
|
;--
|
|
|
|
DiskHandle equ dword ptr [bp+6]
|
|
|
|
public _CloseDisk
|
|
_CloseDisk proc far
|
|
|
|
push bp
|
|
mov bp,sp
|
|
|
|
push ds
|
|
push si
|
|
|
|
lds si,DiskHandle
|
|
|
|
cmp [si].DiskInfoDiskOpen,0
|
|
jz cd_done ; not open, nothing to do
|
|
|
|
;
|
|
; Int13 disks only for now
|
|
;
|
|
push ds
|
|
push si
|
|
call CloseInt13Disk
|
|
pop si
|
|
pop ds ; ds:si -> disk record
|
|
|
|
dec [si].DiskInfoDiskOpen
|
|
|
|
cd_done:
|
|
pop si
|
|
pop ds
|
|
leave
|
|
retf
|
|
|
|
_CloseDisk endp
|
|
|
|
|
|
;++
|
|
;
|
|
; BOOL
|
|
; _far
|
|
; GetDiskInfoByHandle(
|
|
; IN HDISK DiskHandle,
|
|
; OUT FPBYTE Int13UnitNumber,
|
|
; OUT FPBYTE SectorsPerTrack,
|
|
; OUT FPUSHORT Heads,
|
|
; OUT FPUSHORT Cylinders,
|
|
; OUT FPULONG ExtendedSectorCount,
|
|
; OUT FPUINT DiskId
|
|
; );
|
|
;
|
|
; BOOL
|
|
; _far
|
|
; GetDiskInfoById(
|
|
; IN UINT DiskId,
|
|
; IN UINT Reserved,
|
|
; OUT FPBYTE Int13UnitNumber,
|
|
; OUT FPBYTE SectorsPerTrack,
|
|
; OUT FPUSHORT Heads,
|
|
; OUT FPUSHORT Cylinders,
|
|
; OUT FPULONG ExtendedSectorCount
|
|
; );
|
|
;
|
|
; Routine Description:
|
|
;
|
|
; These routines fetch information about a disk.
|
|
;
|
|
; Arguments:
|
|
;
|
|
; Return Value:
|
|
;
|
|
; non-0 - success
|
|
; 0 - failure
|
|
;
|
|
;--
|
|
|
|
DiskHandle equ dword ptr [bp+6]
|
|
DiskId equ word ptr [bp+6]
|
|
Int13UnitNumber equ dword ptr [bp+10]
|
|
SectorsPerTrack equ dword ptr [bp+14]
|
|
Heads equ dword ptr [bp+18]
|
|
Cylinders equ dword ptr [bp+22]
|
|
ExtendedSecCnt equ dword ptr [bp+26]
|
|
pDiskId equ dword ptr [bp+30]
|
|
|
|
public _GetDiskInfoById
|
|
_GetDiskInfoById proc far
|
|
|
|
push bp
|
|
mov bp,sp
|
|
|
|
push ds
|
|
push si
|
|
|
|
;
|
|
; Locate the disk record.
|
|
;
|
|
mov ax,DiskId
|
|
call far ptr pLocateDiskRecord
|
|
cmp dx,0
|
|
jnz gdi_do_it
|
|
cmp si,0
|
|
jnz gdi_do_it
|
|
mov ax,dx
|
|
jz gdi_done
|
|
|
|
gdi_do_it:
|
|
;
|
|
; Int13 disks are the only ones supported now so we can
|
|
; just call the int13-specific disk info routine.
|
|
;
|
|
push ExtendedSecCnt
|
|
push Cylinders
|
|
push Heads
|
|
push SectorsPerTrack
|
|
push Int13UnitNumber
|
|
push ds
|
|
push si
|
|
call GetInt13DiskInfo
|
|
add sp,24
|
|
mov ax,1
|
|
|
|
gdi_done:
|
|
pop si
|
|
pop ds
|
|
leave
|
|
retf
|
|
|
|
_GetDiskInfoById endp
|
|
|
|
|
|
public _GetDiskInfoByHandle
|
|
_GetDiskInfoByHandle proc far
|
|
|
|
push bp
|
|
mov bp,sp
|
|
|
|
push ds
|
|
push si
|
|
|
|
;
|
|
; Make sure the disk is open.
|
|
;
|
|
lds si,DiskHandle
|
|
cmp [si].DiskInfoDiskOpen,0
|
|
jz @f
|
|
|
|
;
|
|
; Set disk id in caller's variable
|
|
;
|
|
mov ax,[si].DiskInfoDiskId
|
|
lds si,pDiskId
|
|
mov [si],ax
|
|
lds si,DiskHandle
|
|
jmp short gdi_do_it
|
|
|
|
@@: mov ax,0
|
|
jz gdi_done
|
|
|
|
_GetDiskInfoByHandle endp
|
|
|
|
|
|
;++
|
|
;
|
|
; BOOL
|
|
; _far
|
|
; ReadDisk(
|
|
; IN HDISK DiskHandle,
|
|
; IN ULONG StartSector,
|
|
; IN BYTE SectorCount,
|
|
; OUT PVOID Buffer
|
|
; );
|
|
;
|
|
; BOOL
|
|
; _far
|
|
; WriteDisk(
|
|
; IN HDISK DiskHandle,
|
|
; IN ULONG StartSector,
|
|
; IN BYTE SectorCount,
|
|
; IN PVOID Buffer
|
|
; );
|
|
;
|
|
; Routine Description:
|
|
;
|
|
; These routines perform i/o to a disk previously opened with
|
|
; OpenDisk().
|
|
;
|
|
; Arguments:
|
|
;
|
|
; DiskHandle - supplies the handle of the disk to be read/written,
|
|
; as previously opened by OpenDisk().
|
|
;
|
|
; StartSector - supplies the physical start sector where the read/write
|
|
; is to begin.
|
|
;
|
|
; SectorCount - supplies the number of sectors to be read/written.
|
|
;
|
|
; Buffer - supplies a buffer for the transfer.
|
|
;
|
|
; Return Value:
|
|
;
|
|
; non-0 - success
|
|
; 0 - failure
|
|
;
|
|
;--
|
|
|
|
DiskHandle equ dword ptr [bp+6]
|
|
StartSector equ dword ptr [bp+10]
|
|
SectorCount equ word ptr [bp+14]
|
|
Buffer equ dword ptr [bp+16]
|
|
|
|
public _WriteDisk
|
|
_WriteDisk label far
|
|
|
|
mov ax,1
|
|
jmp short DiskIo
|
|
|
|
public _ReadDisk
|
|
_ReadDisk label far
|
|
|
|
mov ax,0
|
|
|
|
DiskIo proc far
|
|
|
|
push bp
|
|
mov bp,sp
|
|
|
|
push ds
|
|
push si
|
|
|
|
lds si,DiskHandle
|
|
cmp [si].DiskInfoDiskOpen,0
|
|
jnz @f
|
|
mov ax,0 ; not open, error out
|
|
jz rd_done
|
|
|
|
;
|
|
; Int13 disks only for now
|
|
;
|
|
@@: push ax
|
|
push Buffer
|
|
push SectorCount
|
|
push StartSector ; only care about low byte
|
|
push ds
|
|
push si
|
|
call Int13DiskIo
|
|
add sp,16
|
|
|
|
rd_done:
|
|
pop si
|
|
pop ds
|
|
leave
|
|
retf
|
|
|
|
DiskIo endp
|
|
|
|
|
|
;++
|
|
;
|
|
; PVOID
|
|
; _far
|
|
; pLocateDiskRecord(
|
|
; IN UINT DiskId
|
|
; );
|
|
;
|
|
; Routine Description:
|
|
;
|
|
; Internal routine.
|
|
;
|
|
; This routine locates a disk record in the linked list
|
|
; of all disk records as prepared by InitializeDiskList().
|
|
;
|
|
; Arguments:
|
|
;
|
|
; DiskId - supplies an ordinal value identifying the disk.
|
|
; Valid range is 0 - n-1, where n is the number returned
|
|
; from InitializeDiskList().
|
|
;
|
|
; This parameter is passed in ax, not on the stack.
|
|
;
|
|
; Return Value:
|
|
;
|
|
; NULL if record not located.
|
|
; Otherwise fills ds:si and dx:si with a far pointer to the
|
|
; disk record.
|
|
;
|
|
;--
|
|
pLocateDiskRecord proc far
|
|
|
|
mov dx,DGROUP
|
|
mov ds,dx
|
|
mov si,offset DGROUP:[DiskList] ; ds:si = &DiskList
|
|
|
|
;
|
|
; Note that this code depends on the link field in the
|
|
; disk record structure being first!
|
|
;
|
|
.errnz DiskInfoNext
|
|
ldr_loop:
|
|
lds si,[si].DiskInfoNext
|
|
mov dx,ds
|
|
cmp dx,0
|
|
jz ldr_done ; end of list, we're done
|
|
cmp [si].DiskInfoDiskId,ax
|
|
jz ldr_done
|
|
jmp short ldr_loop
|
|
|
|
ldr_done:
|
|
retf
|
|
|
|
pLocateDiskRecord endp
|
|
|
|
end
|