📄 floppy.txt
字号:
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 rethfail: mov [error],al ; Mark error pop ax ; Failure stc retENDP 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 retENDP 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 bxsthere: clc retsdone: mov [error],al ; Mark errorsdone2: stc pop axsdone3: retENDP 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 ; retENDP 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 failedgoterr: stc ; Mark error mov [error],al ; pop ax retnoerr: 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 verifywtmode: 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 errordma_err: mov [error],al ; Mark error pop dx pop ecx pop ax retENDP 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 verifyrwv_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 driverwv_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 WaitDonerwv_done: call ReadSevenResponse ; Read the responserwv_fail: retENDP rwvPROC 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 drivefmt_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 responsefmt_fail: retendp 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 responserw_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 retendp 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 retendp 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,bhfirsthead: 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 responsefmt_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_WRITEnowrite: 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 retendp 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 retendp Disk1024 end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -