Files
2024-02-19 00:25:23 -05:00

1079 lines
22 KiB
Plaintext

Hi,
Find enclosed dma.asi, floppy.p, floppy.asm, floppy.asi. Note that
these functions do NOT automatically retry on an error; in particular if
you get error #6 the main code should try again.
Two parameter tables are supplied; the first does 1024 byte sectors
and the second does 256 byte sectors. If you need 512 bytes fill in the
parameters appropriately... most of them are similar to the BIOS parameters
or you can read the existing tables and guess what to change.
Have fun,
David
-----------------------------DMA.ASI (header)--------------------------------
; These macros only work for channels 0 - 3
;
DMAMODE_SINGLE = 40h
DMAXFER_VERIFY = 0
DMAXFER_WRITE = 4
DMAXFER_READ = 8
MACRO DMA_CLEARBYTEFF
out 0ch,al
ENDM DMA_CLEARBYTEFF
MACRO DMA_WRITEBASE low,high,channel
mov al,low
out 00+2*channel,al
jmp $+2
mov al,high
out 00+2*channel,al
jmp $+2
ENDM DMA_WRITEBASE
MACRO DMA_WRITECOUNT low, high, channel
mov al,low
out 01+2*channel,al
jmp $+2
mov al,high
out 01+2*channel,al
jmp $+2
ENDM DMA_WRITECOUNT
MACRO DMA_MASKOFF channel
mov al,channel
out 0ah,al
ENDM DMA_MASKOFF
MACRO DMA_MASKON channel
mov al,channel OR 2
out 0ah,al
ENDM DMA_MASKON
MACRO DMA_GETMODE mode,transfer,channel
mov al,mode OR transfer OR channel
ENDM DMA_GETMODE
MACRO DMA_SETMODE
out 0bh,al
ENDM DMA_SETMODE
MACRO DMA_SETPAGE data,channel
mov al,data
if channel eq 0
out 87h,al
else
if channel eq 1
out 83h,al
else
if channel eq 2
out 81h,al
else
if channel eq 3
out 82h,al
endif
endif
endif
endif
jmp $+2
ENDM DMA_SETPAGE
--------------------------floppy.p (prototype file)----------------------
/* MKLibHead 1.00 Wednesday October 25, 1995 22:13:16 */
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
/* Floppy.asm */
DiskSetInts(void);
DiskResetInts(void);
int FormatTrack(BYTE *buffer, int drive, int track, int head);
int DiskIO(BYTE *buffer, int drive, int track, int sector, int head, int towrite);
void Disk1024(void);
#ifdef __cplusplus
}
#endif // __cplusplus
--------------------------floppy.asi (header)------------------------------
MOTORSELECT = 3f2h
DISKSTATUS = 3f4h
DISKDATA = 3f5h
INPUTSTATUS = 3F6H
RATECONFIG = 3F7H
DK_WRITE = 2
DK_READ = 1
SPEC_NODMA = 1
FLOPPY_DMA = 2
HEADSEL_BIT = 2
CMD_SPECIFY = 3
CMD_RECALIBRATE = 7
CMD_SENSE = 8
CMD_SEEK = 0FH
CMD_READID = 4ah
CMD_FORMAT = 04DH
CMD_WRITE = 045H
CMD_READ = 066H
CSR_READY = 80h
CSR_READ = 40h
CSR_IOINPROG = 20h
MTR_NOSELECT = 0fch
MTR_DMA = 8
MTR_NORESET = 4
MTR_MASKOFF = 0fh
DTIME_MUL = 182
DTIME_DIV = 100
CHANGEABLE = 80h
MULTIHEAD = 1
struc stdparams
cmd db ?
drivehead db ?
cylinder db ?
head db ?
sector db ?
size db ?
eot db ?
gaplen db ?
cusize db ?
ends stdparams
SR0_UNUSED = 7
SR0_ABTERM = 6
SR0_SEEK = 5
SR0_RECALFAIL = 4
SR1_SECTOOBIG = 7
SR1_CRC = 5
SR1_OVERRUN = 4
SR1_NODATA = 2
SR1_WRITEPROT = 1
SR1_NOADDRESS = 0
SR2_BADSEC = 6
SR2_CRC = 5
SR2_WRONGCYL = 4
SR2_BADCYL = 1
SR2_MISSADDRESS = 0
struc stdresponse
sr0 db ?
sr1 db ?
sr2 db ?
cylinder db ?
head db ?
sector db ?
size db ?
ends stdresponse
DERR_NONE = 0
DERR_INVFUNC = 1
DERR_NOADDRESS = 2
DERR_WRITEPROT = 3
DERR_NOSECT = 4
DERR_CHANGED = 6
DERR_DMAOVER = 8
DERR_DMABOUND = 9
DERR_BADMEDIA = 0CH
DERR_BADCRC = 10H
DERR_CTRLFAIL = 20H
DERR_SEEKFAIL = 40H
DERR_TIMEOUT = 80H
STRUC diskparm
steploadul dw 4 DUP (?)
media db 4 DUP (?)
turnoff db 4 DUP (?)
hptchange db 4 DUP (?)
tpd db 4 DUP (?)
bpsspt dw 4 DUP (?)
fglfill dw 4 DUP (?)
settle db 4 DUP (?)
pup db 4 DUP (?)
ENDS diskparm
--------------------------------floppy.asm-------------------------------
;
; floppy.asm (DMA version)
;
; Function: 1.44MB floppy driver ( 4 drives)
; Handles floppy interrupt
; Handles managing floppy controller and DMA system
; Handles read/write format
; Handles OS floppy calls
;
IDEAL
model large,C
P386
public DiskSetInts,DiskResetInts,DiskIO,FormatTrack,Disk1024
include "floppy.asi"
include "dma.asi"
STACK
DATASEG
done dw 0 ; Set true when an interrupt completes
sectorsize dw 256 ; Size of a sector
transfercount dw 0 ; size to transfer
turnofftime dw 0 ; Ticks till disk turnoff
countime dw 0 ; Ticks while delaying
motors db 0 ; Motor on specifier
responsebuf db 7 DUP (?) ; Controller response buffer
calibrated db 0 ; Calibration control flags
error db 0 ; Error found
tracks db 4 DUP (?) ; Register current diskette tracks
;
; 256 byte sectors (default)
parmtable dw 2a1h,2a1h,2a1h,2a1h ; Diskette params, see DISKPARAM struc
db 0,0,0,0
db 20,20,20,20
db 81h,81h,81h,81h
db 80,80,80,80
dw 2201h,2201h,2201h,2201h
dw 00028h,00028h,00028h,00028h
db 0fh,0fh,0fh,0fh
db 10,10,10,10
;
; 1024 byte sectors
;
parmtable2 dw 2a1h,2a1h,2a1h,2a1h ; Diskette params, see DISKPARAM struc
db 0,0,0,0
db 20,20,20,20
db 81h,81h,81h,81h
db 80,80,80,80
dw 0a03h,0a03h,0a03h,0a03h
dw 0c48ch,0c48ch,0c48ch,0c48ch
db 0fh,0fh,0fh,0fh
db 10,10,10,10
sop = $ - parmtable2
;
; Tenths to ticks conversion
;
CODESEG
bufpos dd ?
multiplier dw DTIME_MUL
divisor dw DTIME_DIV
oldint8 dd ?
oldinte dd ?
cmd db DK_READ
;
; Timer interrupt
;
PROC FloppyTimerInt
push ax
push ds
push dgroup
pop ds
test [turnofftime],-1 ; See if turnofftime active
jz short noturnoff ; No
dec [turnofftime] ; Yes, decrement
jnz short noturnoff ; Not done
push dx ; Else save dx
and [motors],MTR_MASKOFF ; Kill all motors
mov al,[motors] ; Inform controller
mov dx,MOTORSELECT ;
out dx,al ;
pop dx ;
noturnoff:
test [countime],-1 ; See if delaying
jz short notcount ;
dec [countime] ; Yes, decrement
jnz short notcount ; Not done
or [done],3 ; Else inform task
notcount:
mov al,20h
out 20h,al
pop ds
pop ax
iret
ENDP FloppyTimerInt
;
; Floppy controller interrupt, interrupts after certain commands
;
PROC FloppyInt
push ax
push ds
push DGROUP ;
pop ds ;
or [done],1 ; Mark controller came
mov al,20h
out 20h,al
pop ds
pop ax ; and ax
iret
ENDP FloppyInt
;
; Stop the timer
;
PROC StopTimer
mov [countime],0 ; Kill count time
and [done],0 ; Reset done flag
ret
ENDP StopTimer
;
; Start the timer
;
PROC StartTimer
push dx ; Convert to ticks
mul [multiplier] ;
div [divisor] ;
pop dx ;
SimpleStartTimer:
inc ax ; Make sure at least 1
mov [countime],ax ; Set timer
and [done],0 ; Reset done flag
ret
ENDP StartTimer
;
; Wait till done flag goes true
;
PROC WaitDone
mov ax,[done]
or ax,ax
jz WaitDone
ret
ENDP WaitDone
;
; Wait for controller to be ready
;
PROC WaitControllerReady
mov ax,2 ; Give it two clock ticks
call far SimpleStartTimer ;
wcr_lp:
mov dx,DISKSTATUS ; Poll status reg
in al,dx ;
test al,CSR_READY ; See if ready bit set
jnz short wcr_ok ; Get out if so
test [done],1
jz wcr_lp ; Loop if not
call StopTimer ; Timed out
mov al,DERR_CTRLFAIL ; Mark controller fail
mov [error],al ;
stc
ret
wcr_ok:
call StopTimer ; Stop timer
clc ; Everything ok
ret
ENDP WaitControllerReady
;
; Read a byte from controller
;
PROC ReadControllerData
call WaitControllerReady ; Wait for ready
jc short rcd_fail ; In case fail
mov dx,DISKDATA ; Get data reg
in al,dx ; Get data
clc ; Life is ok
rcd_fail:
ret
ENDP ReadControllerData
;
; Read the standard response from the controller
;
PROC ReadSevenResponse
mov cl,7 ; 7 bytes to read
mov di,offset responsebuf ; Get buffer
ReadRespLoop:
call ReadControllerData ; Read a byte
jc short rsr_fail ; if it is raining
mov [di],al ; otherwise Save char in buf
inc di ;
dec cl ; Next byte
jnz short ReadRespLoop ;
clc ; Everything fine
rsr_fail:
ret
ENDP ReadSevenResponse
;
; Write data to controller
;
PROC WriteControllerDataC
jc short wcd_fail ; Skip out if previous error
WriteControllerData:
mov bl,al ; bl gets the char
call WaitControllerReady ; Wait for ready
jc short wcd_fail2 ; bail out if fail
test al,CSR_READ ; Make sure direction = toward controller
mov al,bl ; Get the char
jnz short wcd_fail ; Bail out if wrong dir
mov dx,DISKDATA ; Get data register
out dx,al ; Output a byte
clc ; no errors
wcd_fail2:
ret
wcd_fail:
call ReadSevenResponse ; Wrong dir, empty controller output buf
mov al,DERR_CTRLFAIL ; Signal a fail
mov [error],al ;
stc ;
ret
ENDP WriteControllerDataC
;
; Turn on motor
;
PROC MotorOn
mov [turnofftime],0 ; NEver turn off
and [motors],MTR_NOSELECT ; Kill select
or [motors],al ; Set new select
or [motors],MTR_DMA OR MTR_NORESET ; ints and dma enabled
add al,4 ; Get motor bit to turn on
push ax
push cx
mov cl,al
mov ax,1
shl ax,cl
pop cx
test [word ptr motors],ax
pushf
or [word ptr motors],ax
mov al,[motors] ; Which motors
mov dx,MOTORSELECT ; Motor reg
out dx,al ;
popf
pop ax ;
jnz short alreadyon ; No waiting if already on
sub al,4 ; Else get drive pup value
and eax,0ffffh
lea edi,[eax + DISkPARM.PUP]
add di,offset parmtable ; In parm table
movzx ax,[byte ptr di] ;
call StartTimer ; Start the timer
call WaitDone ; Wait for timeout
alreadyon:
clc ; Never an error with select
ret
ENDP MotorOn
;
; Check if disk change
;
PROC Changed
and eax,0ffffh
lea edi,[eax+DISKPARM.HPTCHANGE]
add di,offset parmtable ;
test [byte ptr di],CHANGEABLE;
jz short notchanging ; No, just exit
push ax ; Else read the digital input reg
mov dx,RATECONFIG ;
in al,dx ;
or al,al ;
pop ax ;
jns short notchanging ; Bit 7 is change line, 0=not changed
push ax ; It changed, we have to have a head
push cx ; move to reset the flipflop
mov ch,7 ;
call far seek ;
pop cx ;
pop ax ;
push ax ;
call far home ; Now bring us back home
pop ax ;
mov ax,4 ; Delay just a bit
call far SimpleStartTimer ;
call WaitDone ;
mov dx,RATECONFIG ; Read change line again
in al,dx ;
or al,al ;
mov al,DERR_CHANGED ; Assume a disk present
jns short missing ; yes, get out
mov al,DERR_TIMEOUT ; Else no disk
missing:
stc ; We have an error
mov [error],al ;
ret ;
notchanging:
clc ; Life is fine
ret
ENDP Changed
;
; Send the disk specify command
;
PROC Specify
and eax,0ffffh
lea esi,[eax*2 + DISKPARM.STEPLOADUl]
add si,offset parmtable ;
mov al,CMD_SPECIFY ; Specify command
call far WriteControllerData ;
lodsb ; Step and load time
call WriteControllerDataC ;
lodsb ; Unload time
; or al,SPEC_NODMA
call WriteControllerDataC ;
; No interrupt for this command
ret
ENDP Specify
;
; Find out if seek succeeded
;
PROC SenseInterruptStatus
mov al,CMD_SENSE ; Sense command
call far WriteControllerData
; No interrupt this command
jc short sis_fail
call ReadControllerData ; First response byte
jc short sis_fail
mov ah,al
call ReadControllerData ; Second response byte
sis_fail:
ret
ENDP SenseInterruptStatus
;
; Home the drive head
;
PROC Home
push ax
push cx
mov cx,ax
mov ax,1
shl ax,cl
pop cx
not ax
and [word ptr calibrated],ax
pop ax
push ax
mov ah,al ; save drive number
and [done],0
mov al,CMD_RECALIBRATE ; Send recal command
call far WriteControllerData ;
mov al,ah ; Write drive number
call WriteControllerDataC ;
jc short hfail ;
call WaitDone ; Wait for interrupt
call SenseInterruptStatus ; Now see what happened
mov al,DERR_SEEKFAIL ; Assume so
jc short hfail
test ah,(1 shl SR0_ABTERM ) ; See if aborted
jnz short hfail ; Branch if so
test ah,(1 SHL SR0_SEEK) ; Check if seek ok
jnz short hfail ; Branch if fail
pop ax ;
push bx
mov bx,offset tracks
add bx,ax
mov [byte ptr bx],0
pop bx
push ax
push cx
mov cx,ax
mov ax,1
shl ax,cl
pop cx
or [word ptr calibrated],ax
pop ax
clc ; Life is dandy, just like candy
ret
hfail:
mov [error],al ; Mark error
pop ax ; Failure
stc
ret
ENDP Home
;
; Reset command
;
PROC Reset
mov [calibrated],0 ; Mark everything uncalibrated
and [motors],MTR_MASKOFF ; Turn off motors
mov al,[motors] ;
mov dx,MOTORSELECT ;
out dx,al ;
mov [turnofftime],0 ; Don't need to turn off
ret
ENDP Reset
;
; Seek a track
;
PROC Seek
push ax
push cx
mov cx,ax
mov ax,1
shl ax,cl
pop cx
test [word ptr calibrated],ax
pop ax
jnz short nohome ; Yes, don't home
push ax ; Else go home
call home ;
pop ax ;
nohome:
mov di,ax
add di,offset tracks
cmp [byte ptr di],ch ;
jz short sthere ; Yes, get out
push ax
and [done],0
mov al,CMD_SEEK ; Send seek command
call far WriteControllerData ;
mov al,ah ; Send drive
call WriteControllerDataC ;
mov al,ch ; Send track
call WriteControllerDataC ;
jc short sdone2 ; Out if error
call WaitDone ; Wait for interrupt
call SenseInterruptStatus ; Check seek status
mov al,DERR_SEEKFAIL ;
jc short sdone
test ah,(1 SHL SR0_ABTERM) ; Error if aborted
jnz short sdone ;
test ah,(1 SHL SR0_SEEK) ; Error if can't seek
jnz short sdone ;
pop ax
push bx
mov bx,ax
add bx,offset tracks
mov [bx],ch ; Update track number
pop bx
sthere:
clc
ret
sdone:
mov [error],al ; Mark error
sdone2:
stc
pop ax
sdone3:
ret
ENDP Seek
;
; Set the KPS for Media
;
PROC SetMediaRate
and eax,0ffffh
lea edi,[eax + DISKPARM.MEDIA]
add di, offset parmtable ;
mov al,[di] ;
mov dx,RATECONFIG ; Goes in rateconfig table
out dx,al ;
ret
ENDP SetMediaRate
;
; XLATE a controller error to a bios error number
;
PROC xlateerr
push ax ; Save ax
mov si,offset responsebuf ; Get response
mov ax,[si] ;
test al,(1 SHL SR0_ABTERM) + (1 SHL SR0_UNUSED); Any errors
jz noerr ; No, get out
test al,(1 SHL SR0_ABTERM) ; If we don't have abterm ctrlfail
mov al,DERR_CTRLFAIL ;
jz goterr
test ah,(1 SHL SR1_NOADDRESS); No address mark
mov al,DERR_NOADDRESS
jnz goterr
test ah,(1 SHL SR1_WRITEPROT); Write protect
mov al,DERR_WRITEPROT
jnz goterr
test ah,(1 SHL SR1_NODATA) ; Can't find sector
mov al,DERR_NOSECT
jnz goterr
test ah,(1 SHL SR1_OVERRUN) ; DMA too slow
mov al,DERR_DMAOVER
jnz goterr
test ah,(1 SHL SR1_CRC) ; CRC error
mov al,DERR_BADCRC
jnz goterr
test ah,( 1 SHL SR1_SECTOOBIG); Sector too big, so can't find it
mov al,DERR_NOSECT
jnz noerr
mov al,DERR_CTRLFAIL ; Otherwise controller failed
goterr:
stc ; Mark error
mov [error],al ;
pop ax
ret
noerr:
pop ax
clc
ret
ENDP xlateerr
;
; Initialize DMA subsystem
;
PROC SetDMA
push ax
push ecx
push dx
mov ah,[cmd] ; Get command
DMA_CLEARBYTEFF ; Put us at low byte
cmp ah,DK_WRITE ; See if write
DMA_GETMODE DMAMODE_SINGLE,DMAXFER_READ,FLOPPY_DMA ; Assume read from mem
jz short wtmode ; Write, go fill in params
cmp ah,DK_READ ; See if read
DMA_GETMODE DMAMODE_SINGLE,DMAXFER_WRITE,FLOPPY_DMA ; Assume write to mem
jz short wtmode ; Branch if so
DMA_GETMODE DMAMODE_SINGLE,DMAXFER_VERIFY,FLOPPY_DMA ; Else must be verify
wtmode:
DMA_SETMODE ; Set the mode
mov dx,[transfercount] ; Get buffer count
dec dx ; Count is last byte xferd
DMA_WRITECOUNT dl,dh,FLOPPY_DMA ; WRite the count
inc dx ; Get original
movzx ecx,[word ptr bufpos+2] ; Get transfer buffer
movzx eax,[word ptr bufpos]
shl ecx,4
add ecx,eax
DMA_WRITEBASE cl,ch,FLOPPY_DMA; Write base address
push ecx ;
shr ecx,16 ; Get page
mov ah,ch ; Get high byte of page
DMA_SETPAGE cl,FLOPPY_DMA ; Write page
pop ecx ;
add cx,dx ; See if overflow a page
mov al,DERR_DMABOUND ; Bound err if so
jc short dma_err ; Yes, mark it
or ah,ah ; See if within lower 16 MB
stc ;
jnz short dma_err ; No, bounds error
DMA_MASKOFF FLOPPY_DMA ; Enable transfer
clc ;
sub al,al ; No error
dma_err:
mov [error],al ; Mark error
pop dx
pop ecx
pop ax
ret
ENDP SetDMA
;
; Read, write or verify a sector
;
PROC rwv
call SetDMA
jc rwv_fail
push ax
push cx
and eax,0ffffh
lea edi,[eax + DISKPARM.BPSSPT]
add di,offset parmtable ;
mov cl,[byte ptr di] ;
mov dx,1
shl dx,cl ;
shl dx,7 ;
pop cx
mov ah,[cmd] ; Check the command
cmp ah,DK_WRITE ; Is it write?
mov al,CMD_WRITE ; Assume so
jz short rwv_cmd ; Go do write
mov al,CMD_READ ; Otherwise it is read or verify
rwv_cmd:
push bx ; Save head
call far WriteControllerData ; Write command
pop bx ;
pop ax
pushf ; Save status
and [done],0
test bx,1
jz short rwv_head0 ;
bts ax,HEADSEL_BIT ; Yes, set headsel bit of drive
rwv_head0:
popf ; Restore status
push ax ; Write drive and head
push bx ;
call WriteControllerDataC ;
pop bx
mov al,ch ; Now write track
push bx ;
call WriteControllerDataC ;
pop bx ;
mov al,bl ; Write head
call WriteControllerDataC ;
mov al,cl ; Write sector
call WriteControllerDataC ;
pop ax ;
pushf ; Reset head sel bit
and ax,NOT (1 SHL HEADSEL_BIT)
popf
and eax,0ffffh
lea esi,[eax*2 + DISKPARM.BPSSPT]
add si,offset parmtable ;
push ax ;
lodsb ; Write bytes per sector
call WriteControllerDataC ;
mov al,cl ; This is last sector for xfer
call WriteControllerDataC ;
pop ax
mov si,ax
and eax,0ffffh
lea esi,[eax*2 + DISKPARM.FGLFILL]
add si,offset parmtable ;
lodsb ;
shr al,2
call WriteControllerDataC ; Write gap len/4
mov al,255 ; User specified data len = 255
call WriteControllerDataC ; Write it
jc short rwv_fail
call WaitDone
rwv_done:
call ReadSevenResponse ; Read the response
rwv_fail:
ret
ENDP rwv
PROC fmt
mov [cmd],DK_WRITE
call SetDMA
jc fmt_fail
push ax
mov al,CMD_FORMAT ; Format command
push bx ; Save head
call far WriteControllerData ; Write command
pop bx ;
pop ax
push ax ; Write drive and head
pushf ; Save status
and [done],0
test bx,1
jz short fmt_head0 ;
bts ax,HEADSEL_BIT ; Yes, set headsel bit of drive
fmt_head0:
popf ; Restore status
call WriteControllerDataC ;
pop ax
push ax
pushf
and eax,0ffffh
lea edi,[eax + DISKPARM.BPSSPT]
add di,offset parmtable ;
popf
mov al,[di] ; Write sector size code
call WriteControllerDataC ;
mov al,[di+1] ; Write SPT
call WriteControllerDataC
pop ax
pushf
lea edi,[eax + DISKPARM.FGLFILL]
add di,offset parmtable
mov dx,[di]
popf
mov al,[di] ; Write gap len
call WriteControllerDataC ;
mov al,[di+1] ; Write Fill
call WriteControllerDataC ;
jc short fmt_fail
call WaitDone
call ReadSevenResponse ; Read the response
fmt_fail:
ret
endp fmt
;
; Read, Write and verify a sector
;
PROC ReadWriteVerify
push cx
push bx
push ax ;
call motoron ;
pop ax ;
push ax ;
call changed ; See if changed or missing
pop ax ;
jc short rw_done ; Err if so
push ax ; Set the Media rate
call SetMediaRate ;
pop ax ; Send the disk specify bytes
push ax ;
call Specify ;
pop ax ;
jc short rw_done ; Err if failed
pop bx
pop cx
push cx
push bx
push ax ; Seek the track
push bx ;
push cx ;
call seek ;
pop cx ;
pop bx ;
pop ax ;
jc short rw_done ; Err if failed
call rwv ; Read Write or Verify the sector
jc short rw_done ; Err if failed
call xlateErr ; Translate the response
rw_done:
pop cx
pop bx
ret ;
ENDP ReadWriteVerify
;
;* DiskSetInts(void);
;
proc DiskSetInts
mov ax,3508h
int 21h
mov [word ptr oldint8],bx
mov [word ptr oldint8+2],es
mov ax,350eh
int 21h
mov [word ptr oldinte],bx
mov [word ptr oldinte+2],es
push ds
push cs
pop ds
mov dx,offset floppytimerint
mov ax,2508h
int 21h
mov dx,offset FloppyInt
mov ax,250eh
int 21h
pop ds
ret
endp DiskSetInts
;
;* DiskResetInts(void);
;
proc DiskResetInts
push ds
lds dx,[oldint8]
mov ax,2508h
int 21h
lds dx,[oldinte]
mov ax,250eh
int 21h
pop ds
ret
endp DiskResetInts
;
;* int FormatTrack(BYTE *buffer, int drive, int track, int head);
;
proc FormatTrack
arg buffer:dword, drive:word, track : word, head: word
uses si,di
mov [error],0
les di,[buffer]
mov [word ptr bufpos],di
mov [word ptr bufpos+2],es
movzx eax,[word ptr drive]
lea edi,[eax*2+diskparm.bpsspt]
add di,offset parmtable;
mov bx,[di]
mov al,bl
shl eax,8
mov al,1
test [head],-1
jz short firsthead
add al,bh
firsthead:
shl eax,8
mov al,[byte ptr head]
shl eax,8
mov al,[byte ptr track]
mov cl,bh
sub ch,ch
les di,[buffer]
tbuf:
stosd
add eax,10000h
loop tbuf
mov cl,bh
shl cx,2
mov [transfercount],cx
mov ch,[byte ptr track]
mov cl,1
mov bx,[head]
mov ax,[drive]
push cx
push bx
push ax ;
call motoron ;
pop ax ;
push ax ;
call changed ; See if changed or missing
pop ax ;
jc short fmt_done ; Err if so
push ax ; Set the Media rate
call SetMediaRate ;
pop ax ; Send the disk specify bytes
push ax ;
call Specify ;
pop ax ;
jc short fmt_done ; Err if failed
pop bx
pop cx
push cx
push bx
push ax ; Seek the track
push bx ;
push cx ;
call seek ;
pop cx ;
pop bx ;
pop ax ;
jc short fmt_done ; Err if failed
call fmt
jc short fmt_done ; Err if failed
call xlateErr ; Translate the response
fmt_done:
pop cx
pop bx
mov al,[error]
sub ah,ah
ret ;
endp FormatTrack
;
;* int DiskIO(BYTE *buffer, int drive, int track, int sector, int head, int towrite);
;
proc DiskIO
arg buffer:dword, drive:word, track : word, sector:word, head:word, towrite: word
USES si,di
mov [cmd],DK_READ
test [towrite],-1
jz short nowrite
mov [cmd],DK_WRITE
nowrite:
mov [error],0
mov ax,[sectorsize]
mov [transfercount],ax
les di,[buffer]
mov [word ptr bufpos],di
mov [word ptr bufpos+2],es
mov ax,[drive]
mov bl,[byte ptr head]
mov ch,[byte ptr track]
mov cl,[byte ptr sector]
call ReadWriteVerify
sub ebx,ebx
lea ebx,[ebx+DISKPARM.TURNOFF]; Else get the off timer byte
add bx,offset parmtable ;
movzx ax,[byte ptr bx] ;
mul [multiplier] ; Make it ticks
div [divisor] ;
mov [turnofftime],ax ; Set turnofftime
mov al,[error]
cbw
ret
endp DiskIO
;
;* void Disk1024(void);
;
proc Disk1024
USES si,di
push ds
pop es
cld
mov si,offset parmtable2
mov di,offset parmtable
mov cx,sop/4
rep movsd
mov [sectorsize],1024
ret
endp Disk1024
end