?? floppy.txt
字號(hào):
Hi, Find enclosed dma.asi, floppy.p, floppy.asm, floppy.asi. Note thatthese functions do NOT automatically retry on an error; in particular ifyou get error #6 the main code should try again.Two parameter tables are supplied; the first does 1024 byte sectorsand the second does 256 byte sectors. If you need 512 bytes fill in theparameters appropriately... most of them are similar to the BIOS parametersor 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 = 40hDMAXFER_VERIFY = 0DMAXFER_WRITE = 4DMAXFER_READ = 8MACRO DMA_CLEARBYTEFF out 0ch,alENDM DMA_CLEARBYTEFFMACRO DMA_WRITEBASE low,high,channel mov al,low out 00+2*channel,al jmp $+2 mov al,high out 00+2*channel,al jmp $+2ENDM DMA_WRITEBASEMACRO DMA_WRITECOUNT low, high, channel mov al,low out 01+2*channel,al jmp $+2 mov al,high out 01+2*channel,al jmp $+2ENDM DMA_WRITECOUNTMACRO DMA_MASKOFF channel mov al,channel out 0ah,alENDM DMA_MASKOFFMACRO DMA_MASKON channel mov al,channel OR 2 out 0ah,alENDM DMA_MASKONMACRO DMA_GETMODE mode,transfer,channel mov al,mode OR transfer OR channelENDM DMA_GETMODEMACRO DMA_SETMODE out 0bh,alENDM DMA_SETMODEMACRO 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 $+2ENDM DMA_SETPAGE--------------------------floppy.p (prototype file)----------------------/* MKLibHead 1.00 Wednesday October 25, 1995 22:13:16 */#ifdef __cplusplusextern "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 = 3f2hDISKSTATUS = 3f4hDISKDATA = 3f5hINPUTSTATUS = 3F6HRATECONFIG = 3F7HDK_WRITE = 2DK_READ = 1SPEC_NODMA = 1FLOPPY_DMA = 2HEADSEL_BIT = 2CMD_SPECIFY = 3CMD_RECALIBRATE = 7CMD_SENSE = 8CMD_SEEK = 0FHCMD_READID = 4ahCMD_FORMAT = 04DHCMD_WRITE = 045HCMD_READ = 066HCSR_READY = 80hCSR_READ = 40hCSR_IOINPROG = 20hMTR_NOSELECT = 0fchMTR_DMA = 8MTR_NORESET = 4MTR_MASKOFF = 0fhDTIME_MUL = 182DTIME_DIV = 100CHANGEABLE = 80hMULTIHEAD = 1struc stdparamscmd db ?drivehead db ?cylinder db ?head db ?sector db ?size db ?eot db ?gaplen db ?cusize db ?ends stdparamsSR0_UNUSED = 7SR0_ABTERM = 6SR0_SEEK = 5SR0_RECALFAIL = 4SR1_SECTOOBIG = 7SR1_CRC = 5SR1_OVERRUN = 4SR1_NODATA = 2SR1_WRITEPROT = 1SR1_NOADDRESS = 0SR2_BADSEC = 6SR2_CRC = 5SR2_WRONGCYL = 4SR2_BADCYL = 1SR2_MISSADDRESS = 0struc stdresponsesr0 db ?sr1 db ?sr2 db ?cylinder db ?head db ?sector db ?size db ?ends stdresponseDERR_NONE = 0DERR_INVFUNC = 1DERR_NOADDRESS = 2DERR_WRITEPROT = 3DERR_NOSECT = 4DERR_CHANGED = 6DERR_DMAOVER = 8DERR_DMABOUND = 9DERR_BADMEDIA = 0CHDERR_BADCRC = 10HDERR_CTRLFAIL = 20HDERR_SEEKFAIL = 40HDERR_TIMEOUT = 80HSTRUC diskparmsteploadul 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,Disk1024include "floppy.asi"include "dma.asi" STACK DATASEGdone dw 0 ; Set true when an interrupt completessectorsize dw 256 ; Size of a sectortransfercount dw 0 ; size to transferturnofftime dw 0 ; Ticks till disk turnoffcountime dw 0 ; Ticks while delayingmotors db 0 ; Motor on specifierresponsebuf db 7 DUP (?) ; Controller response buffercalibrated db 0 ; Calibration control flagserror db 0 ; Error foundtracks 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,10sop = $ - parmtable2;; Tenths to ticks conversion; CODESEGbufpos dd ?multiplier dw DTIME_MULdivisor dw DTIME_DIVoldint8 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 tasknotcount: mov al,20h out 20h,al pop ds pop ax iretENDP 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 iretENDP FloppyInt;; Stop the timer;PROC StopTimer mov [countime],0 ; Kill count time and [done],0 ; Reset done flag retENDP 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 retENDP StartTimer;; Wait till done flag goes true;PROC WaitDone mov ax,[done] or ax,ax jz WaitDone retENDP 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 retwcr_ok: call StopTimer ; Stop timer clc ; Everything ok retENDP 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 okrcd_fail: retENDP ReadControllerData;; Read the standard response from the controller;PROC ReadSevenResponse mov cl,7 ; 7 bytes to read mov di,offset responsebuf ; Get bufferReadRespLoop: 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 finersr_fail: retENDP ReadSevenResponse;; Write data to controller;PROC WriteControllerDataC jc short wcd_fail ; Skip out if previous errorWriteControllerData: 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 errorswcd_fail2: retwcd_fail: call ReadSevenResponse ; Wrong dir, empty controller output buf mov al,DERR_CTRLFAIL ; Signal a fail mov [error],al ; stc ; retENDP 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 timeoutalreadyon: clc ; Never an error with select retENDP 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 diskmissing: stc ; We have an error mov [error],al ; ret ;notchanging: clc ; Life is fine retENDP 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 retENDP 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 bytesis_fail: retENDP SenseInterruptStatus;; Home the drive head;PROC Home push ax push cx mov cx,ax mov ax,1 shl ax,cl pop cx
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -