home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 25
/
CD_ASCQ_25_1095.iso
/
dos
/
prg
/
cpe50
/
fdc.asm
< prev
next >
Wrap
Assembly Source File
|
1995-08-29
|
16KB
|
842 lines
; ********************************************* FDC emulation
IDEAL
INCLUDE "cpe2\macros.inc"
EXTRN UnpackArea:PROC,PackArea:PROC
EXTRN srF:WORD
EXTRN dradir:BYTE,draname:BYTE,mvadir:BYTE,mvaname:BYTE
PUBLIC outFA,outFB,inpFB,OpenDriveA,CloseDisk,DiskChange,dcstat,fha
PUBLIC DiskBuf,thistrack
P386
GROUP DGROUP _stack,_data
SEGMENT _text PAGE PUBLIC 'CODE'
ASSUME CS:_text
ASSUME DS:DGROUP
CloseDisk:
PUSHAD
MOV BX,[fha]
CMP BX,0ffffh
JE CLDS_NoDiskFile
MOV AH,3Eh
INT 21h
CLDS_NoDiskFile:
POPAD
RET
OpenDriveA:
PUSH ES
PUSHAD
CALL CloseDisk
MOV [diskchange],0
MOV DX,OFFSET dradir
MOV AX,3d02h
INT 21h
JC ODRA_CheckMV
MOV [fha],AX
MOV BX,AX
MOV AX,3f00h
MOV CX,9
MOV DX,OFFSET DiskType
INT 21h
CMP [DWORD PTR DiskType+4],'KSID' ; recognized: NORMDISK and CRUXDISK
JNE ODRA_Fault
CMP [DWORD PTR DiskType],'MRON'
JE ODRA_AllOK
CMP [DWORD PTR DiskType],'XURC'
JNE ODRA_Fault
ODRA_AllOK:
MOV [dcstat],0
MOV [dcbytecnt],0
MOV [dccommand],0
CALL DCSeekCurr
JMP ODRA_End
ODRA_CheckMV:
MOV EAX,[DWORD PTR draname]
MOV [DWORD PTR mvaname],EAX
MOV EAX,[DWORD PTR draname+4]
MOV [DWORD PTR mvaname+4],EAX
MOV EAX,[DWORD PTR draname+8]
MOV [DWORD PTR mvaname+8],EAX
XOR EDI,EDI
MOV DI,OFFSET mvaname
PUSH DS
POP ES
MOV CX,12
MOV AL,'.'
REPNE SCASB
MOV [DWORD PTR EDI-1],'KSD.'
MOV DX,OFFSET mvadir
MOV AX,3d02h
INT 21h
JC ODRA_Fault
MOV [fha],AX
MOV BX,AX
MOV AX,3f00h
MOV CX,4
MOV DX,OFFSET DiskType
INT 21h
CMP [DWORD PTR DiskType],'- VM' ; recognize MV - CPCEMU Disk-File
JNE ODRA_Fault
MOV AX,3f00h
MOV CX,252
MOV DX,OFFSET DiskBuf+4
INT 21h
MOV AX,[WORD PTR DiskBuf+032h]
MOV [tracklen],AX
MOV AL,[BYTE PTR DiskBuf+030h]
MOV [BYTE PTR DiskType+8],AL
JMP ODRA_AllOK
ODRA_Fault:
MOV [fha],0ffffh
ODRA_End:
POPAD
POP ES
RET
CorrectParms:
AND [BYTE PTR dccmdparms],1
PUSH AX
MOV AL,[BYTE PTR dccmdparms]
MOV [dccurrdrive],AL
POP AX
RET
DCSetStatusRegs:
PUSH AX
MOV AL,[dccurrdrive]
AND AL,3
MOV [DCsReg0],AL
MOV [DCsReg1],0
MOV [DCsReg2],0
MOV [DCsReg3],AL
OR [DCsReg3],20h
CMP [dccurrdrive],0
JNE DCSSR_NotDriveA
TEST [dcfaxx],1
JZ DCSSR_NotDriveA
CMP [fha],0ffffh
JNE DCSSR_DiskInDrive
DCSSR_NotDriveA:
OR [DCsReg0],0c8h
XOR [DCsReg3],20h
DCSSR_DiskInDrive:
CMP [CurrTrack],0
JNE DCSSR_NotTrack0
OR [DCsReg3],10h
DCSSR_NotTrack0:
CMP [tracktoohi],0
JE DCSSR_TrackOK
OR [DCsReg0],0c0h
DCSSR_TrackOK:
POP AX
RET
DCRecalibrate:
RET
DCGetInfo:
CALL CorrectParms
CMP [BYTE PTR dccmdparms],0
JNE DC_WrongDrive
PUSH AX
MOV [dcdata],0
MOV AL,[DCsReg3]
MOV [BYTE PTR dcdata],AL
DCGI_End:
POP AX
RET
DCGetTrack:
CALL CorrectParms
CMP [lastfdcmd],8
JE DCGT_Return80
CMP [BYTE PTR dccmdparms],0
JNE DC_WrongDrive
PUSH AX
MOV AH,[CurrTrack]
MOV [BYTE PTR dcdata+1],AH
MOV AH,[DCsReg0]
MOV [BYTE PTR dcdata],AH
MOV [DCsReg0],80h
POP AX
RET
DCGT_Return80:
MOV [dcdata],80h
MOV [dcbytecnt],1
RET
DCSeek0:
CALL CorrectParms
CMP [BYTE PTR dccmdparms],0
MOV [DCsReg0],20h
JNE DC_WrongDrive
PUSHAD
MOV AH,[BYTE PTR dccmdparms]
MOV [dccurrdrive],AH
CALL DCSetStatusRegs
OR [DCsReg0],20h
CMP [dccurrdrive],0
JNE DCS0_End
MOV [CurrTrack],0
CALL DCSeekCurr
DCS0_End:
POPAD
RET
DCWrite:
CALL CorrectParms
CMP [BYTE PTR dccmdparms],0
JNE DC_WrongDrive
MOV [dccommand],OFFSET Writecmd
MOV [dccppt],OFFSET DiskBuf
MOV [dcbytecnt],512
MOV [dcstat],1
MOV [wrinprogr],1
RET
DCWritectd:
PUSHAD
MOV [wrinprogr],0
MOV [dcextdata],0
MOV [dcdpt],OFFSET dcdata
MOV AH,[BYTE PTR dccmdparms]
MOV [dccurrdrive],AH
CALL DCSetStatusRegs
MOV AH,[DCsReg0]
MOV [BYTE PTR dcdata],AH
MOV AH,[DCsReg1]
MOV [BYTE PTR dcdata+1],AH
MOV AH,[DCsReg2]
MOV [BYTE PTR dcdata+2],AH
MOV AH,[CurrTrack]
MOV [BYTE PTR dcdata+3],AH
MOV [BYTE PTR dcdata+4],0
MOV AH,[BYTE PTR dccmdparms+3]
CMP [DWORD PTR DiskType],'XURC'
JE DCWR_Writeprotected
CMP [DWORD PTR DiskType],'- VM'
JE DCWR_Writeprotected
TEST [DCsReg0],0c0h
JNZ DCWR_Erreur
CMP [fha],0ffffh
JE DCWR_Erreur
MOV BP,0
DCWR_WriteLoop:
MOV [BYTE PTR dcdata+5],AH
PUSH AX
MOV CX,[trackoffshi]
MOV DX,[trackoffslo]
MOV BX,[fha]
MOV AX,4200h
INT 21h ; seek track start
MOV SI,OFFSET idfield
XOR BX,BX
POP AX
DCWR_Loop1:
CMP [BYTE PTR SI],255
JE DCWR_Erreur
CMP [SI],AH
JE DCWR_found
ADD BX,512
INC SI
JMP DCWR_Loop1
DCWR_found:
PUSH SI
MOV CX,512
PUSH ES
PUSH DS
POP ES
MOV DI,BX
ADD DI,OFFSET thistrack
MOV SI,OFFSET DiskBuf
ADD SI,BP
REP MOVSB
POP ES
POP SI
CMP AH,[BYTE PTR dccmdparms+5]
JE DCWR_AllWritten
INC AH
ADD BP,512
JMP DCWR_WriteLoop
DCWR_AllWritten:
MOV BX,[fha]
MOV DX,OFFSET thistrack
MOV AX,4000h
MOV CX,5120
INT 21h
DCWR_DontWrite:
POPAD
RET
DCWR_Erreur:
OR [BYTE PTR dcdata+1],4
JMP DCWR_DontWrite
DCWR_Writeprotected:
OR [dcdata],0C0h
OR [dcdata+1],2
JMP DCWR_DontWrite
DCReadSec:
CALL CorrectParms
CMP [BYTE PTR dccmdparms],0
JNE DC_WrongDrive
PUSHAD
MOV AH,[BYTE PTR dccmdparms]
MOV [dccurrdrive],AH
CALL DCSetStatusRegs
MOV AH,[DCsReg0]
MOV [BYTE PTR dcdata],AH
MOV AH,[DCsReg1]
MOV [BYTE PTR dcdata+1],AH
MOV AH,[DCsReg2]
MOV [BYTE PTR dcdata+2],AH
MOV BP,0
MOV AH,[BYTE PTR dccmdparms+3]
TEST [DCsReg0],0c0h
JNZ DCRS_AllRead
CMP [fha],0ffffh
JE DCRS_AllRead
DCRS_ReadLoop:
MOV [BYTE PTR dcdata+5],AH
PUSH AX
MOV BX,OFFSET thistrack
MOV SI,OFFSET idfield
POP AX
DCRS_Loop1:
CMP [BYTE PTR SI],255
JE DCRS_Erreur
CMP [SI],AH
JE DCRS_found
ADD BX,512
INC SI
JMP DCRS_Loop1
DCRS_found:
INC SI
PUSH SI
PUSH AX
MOV CX,512
MOV SI,BX
MOV DI,OFFSET DiskBuf
ADD DI,BP
PUSH ES
PUSH DS
POP ES
REP MOVSB
POP ES
POP AX
POP SI
MOV CX,0
MOV DX,0
ADD BP,512
CMP [BYTE PTR dccmdparms+5],AH
JE DCRS_AllRead
INC AH
JMP DCRS_ReadLoop
DCRS_AllRead:
MOV [dcextdata],BP
MOV BP,OFFSET DiskBuf
MOV [dcedp],BP
DCRS_Ret:
POPAD
RET
DCRS_Erreur:
OR [BYTE PTR dcdata+1],4
JMP DCRS_AllRead
DCSeek:
CALL CorrectParms
CMP [BYTE PTR dccmdparms],0
MOV [DCsReg0],32
JNE DC_WrongDrive
PUSHAD
MOV AH,[BYTE PTR dccmdparms]
MOV [dccurrdrive],AH
CMP [dccurrdrive],0
JNE DCSeekEnd
MOV AH,[BYTE PTR dccmdparms+1]
MOV [CurrTrack],AH
CALL DCSetStatusRegs
OR [DCsReg0],32 ; seek completed
CALL DCSeekCurr
DCSeekEnd:
POPAD
RET
DCGetID:
CALL CorrectParms
CMP [BYTE PTR dccmdparms],0
JNE DC_WrongDrive
PUSHAD
MOV AH,[BYTE PTR dccmdparms]
MOV [dccurrdrive],AH
CALL DCSetStatusRegs
TEST [DCsReg0],0c0h
JNZ DCGI_OK
MOV BP,OFFSET dcdata
MOV EAX,0
MOV [BP],EAX
MOV AL,[CurrTrack]
MOV [BP+3],AL
ADD BP,4
MOV sFree,[IDTPtr]
MOV AH,[sFree]
MOV BL,[sFree+66]
INC sFree
CMP AH,0FFh
JNE DCGI_Wback
MOV sFree,OFFSET idfield
MOV AH,[sFree]
MOV BL,[sFree+66]
INC sFree
DCGI_Wback:
MOV [IDTPtr],sFree
XOR AL,AL
MOV [BP],AX
MOV [BP+2],BL
; CMP [fha],0ffffh
; JNE DCGI_OK
; MOV [BYTE PTR dcdata],32
DCGI_OK:
MOV AH,[DCsReg0]
MOV [BYTE PTR dcdata],AH
MOV AH,[DCsReg1]
MOV [BYTE PTR dcdata+1],AH
MOV AH,[DCsReg2]
MOV [BYTE PTR dcdata+2],AH
POPAD
RET
DCSeekCurr:
MOV [IDTPtr],OFFSET idfield
CMP [DWORD PTR DiskType],'XURC'
JE DCSC_Packed
CMP [DWORD PTR DiskType],'- VM'
JE DCSC_MV
PUSHAD
MOV EAX,0
MOV AL,[CurrTrack]
CMP AL,[DiskType+8]
JC DCSC_TrackOK
MOV [tracktoohi],1
JMP DCSC_End
DCSC_TrackOK:
MOV [tracktoohi],0
MOV EBX,5252
MUL EBX
ADD EAX,9
PUSH EAX
ROL EAX,16
MOV CX,AX
ROL EAX,16
MOV DX,AX
MOV EAX,4200h
MOV BX,[fha]
CMP BX,0ffffh
JE DCSC_End
INT 21h
MOV BX,[fha]
MOV AX,3f00h
MOV DX,OFFSET idfield
MOV CX,132
INT 21h
MOV AX,3f00h
MOV DX,OFFSET thistrack
MOV CX,5120
INT 21h
POP EAX
ADD EAX,132
ROL EAX,16
MOV CX,AX
ROL EAX,16
MOV DX,AX
MOV [trackoffslo],DX
MOV [trackoffshi],CX
DCSC_End:
POPAD
RET
DCSC_MV:
PUSHAD
MOV EAX,0
MOV AL,[CurrTrack]
CMP AL,[DiskType+8]
JC DCSC_MV_TrackOK
MOV [tracktoohi],1
JMP DCSC_MV_End
DCSC_MV_TrackOK:
MOV [tracktoohi],0
XOR EBX,EBX
MOV BX,[tracklen]
MUL EBX
ADD EAX,256
PUSH EAX
ROL EAX,16
MOV CX,AX
ROL EAX,16
MOV DX,AX
MOV EAX,4200h
MOV BX,[fha]
CMP BX,0ffffh
JE DCSC_MV_End
INT 21h
MOV BX,[fha]
MOV AX,3f00h
MOV DX,OFFSET DiskBuf
MOV CX,256
INT 21h
MOVZX CX,[BYTE PTR DiskBuf+015h]
MOV [BYTE PTR ECX+idfield],0ffh
XOR EAX,EAX
DCSC_MV_BuildIDfield:
MOV AX,CX
DEC AX
SHL AX,3
ADD AX,018h
MOV BL,[BYTE PTR EAX+DiskBuf+2]
MOV [BYTE PTR ECX+idfield-1],BL
MOV BL,[BYTE PTR EAX+DiskBuf+3]
MOV [BYTE PTR ECX+idfield+65],BL
LOOP DCSC_MV_BuildIDField
MOV BX,[fha]
MOV AX,3f00h
MOV DX,OFFSET thistrack
MOV CX,5120
INT 21h
POP EAX
ADD EAX,132
ROL EAX,16
MOV CX,AX
ROL EAX,16
MOV DX,AX
MOV [trackoffslo],DX
MOV [trackoffshi],CX
DCSC_MV_End:
POPAD
RET
DCSC_Packed:
PUSHAD
XOR AX,AX
MOV AL,[CurrTrack]
CMP AL,[DiskType+8]
JC DCSC_PCKD_TrackOK
MOV [tracktoohi],1
JMP DCSC_PCKD_End
DCSC_PCKD_TrackOK:
MOV [tracktoohi],0
ADD AL,AL
ADD AL,AL
ADD AL,9
MOV DX,AX
XOR CX,CX
MOV AX,4200h
MOV BX,[fha]
CMP BX,0ffffh
JE DCSC_PCKD_End
INT 21h
MOV DX,OFFSET DiskBuf
MOV CX,4
MOV AX,3f00h
INT 21h
MOV EAX,[DWORD PTR DiskBuf]
MOV DX,AX
ROL EAX,16
MOV CL,AL
XOR CH,CH
PUSH AX
MOV AX,4200h
INT 21h
POP AX
CMP AH,0
JE DCSC_PCKD_ButNotThis
MOV DX,OFFSET DiskBuf+8
MOV CX,5252
MOV AX,3f00h
INT 21h
PUSH ES
PUSH DS
POP ES
MOV SI,OFFSET DiskBuf
MOV [DWORD PTR SI],'XURC'
MOV [DWORD PTR SI+4],'KCAP'
MOV DI,OFFSET thistrack
MOV CX,5252
PUSHAD
CALL FAR UnpackArea
POPAD
MOV SI,DI
MOV CX,132
MOV DI,OFFSET idfield
REP MOVSB
MOV DI,OFFSET thistrack
MOV CX,5120
REP MOVSB
POP ES
JMP DCSC_PCKD_End
DCSC_PCKD_ButNotThis:
MOV DX,OFFSET idfield
MOV CX,132
MOV AX,3f00h
INT 21h
MOV DX,OFFSET thistrack
MOV CX,5120
MOV AX,3f00h
INT 21h
DCSC_PCKD_End:
POPAD
RET
DC_WrongDrive:
PUSH AX
MOV AL,[DCsReg0]
AND AX,020h
OR AL,0C8h
MOV [dcdata],AX
POP AX
MOV [dcbytecnt],1
MOV [dcextdata],0
RET
outFA: MOV [BYTE PTR dcFAxx],AL
AND AL,3
MOV [dccurrdrive],AL
MOV [dcstat],0
MOV [dcbytecnt],0
RET
outFB: CMP sC,7Eh
JE outFB7E
CMP sC,7Fh
JE outFB7F
outFBend:
RET
outFB7E:
RET
outFB7F:
CMP [dcstat],0
JE oFB7F_newcmd
CMP [dcstat],1
JE oFB7F_parms
DEC [dcbytecnt]
JS outFB7F_cmdfinish
MOV BP,[dcdpt]
MOV [BP],AL
INC BP
MOV [dcdpt],BP
outFB7F_end:
RET
outFB7F_cmdfinish:
MOV [dcstat],0
RET
oFB7F_parms:
MOV BP,[dccppt]
MOV [BP],AL
INC BP
MOV [dccppt],BP
DEC [dcbytecnt]
JNE outFB7F_end
oFB7F_stage2:
MOV BP,[dccommand]
PUSH AX
MOVZX AX,[BP+2]
MOV [dcbytecnt],AX
POP AX
MOV BP,[BP+4]
MOV [dcstat],2
CMP [dcbytecnt],0
JNE oFB7F_2ok
MOV [dcstat],0
oFB7F_2ok:
MOV [dcextdata],0
JMP BP
oFB7F_newcmd:
XCHG [thisfdcmd],AL
MOV [lastfdcmd],AL
MOV AL,[thisfdcmd]
CMP [diskchange],0
JE oFB7F_NoDiskChange
CALL OpenDriveA
oFB7F_NoDiskChange:
MOV BP,OFFSET dccommands
oFB7Fnc_loop:
CMP [DWORD PTR BP],0
JE oFB7F_invalid
CMP AL,[BYTE PTR BP]
JE oFB7Fnc_found
ADD BP,6
JMP oFB7Fnc_loop
oFB7F_invalid:
MOV [dcdata],80h
MOV [dcbytecnt],1
MOV [dcstat],2
MOV [dcdpt],OFFSET dcdata
MOV [dcextdata],0
JMP outFB7F_end
oFB7Fnc_found:
MOV [dccommand],BP
PUSH AX
MOVZX AX,[BP+1]
MOV [dcbytecnt],AX
POP AX
MOV [dccppt],OFFSET dccmdparms
MOV [dcdpt],OFFSET dcdata
MOV [dcstat],1
CMP [dcbytecnt],0
JE oFB7F_stage2
RET
inpFB: CMP sC,7fh ; *?*
JE inpFB7F
CMP sC,7eh
JE inpFB7E
inpFBxx: CMP sC,0edh
JE inpFBED
RET
inpFBED:
MOV AL,[BYTE PTR sRF]
RET
inpFB7E: ; on PC: Main Status Register 3F4
MOV AX,80h
CMP [wrinprogr],0
JNE inpFB7E_Write
CMP [dcstat],2
JNE inpFB7Estatnot2
OR AL,40h
CMP [dcextdata],0
JE inpFB7Enoext
OR AL,20h
JMP inpFB7Eend
inpFB7Enoext:
OR AL,10h
JMP inpFB7Eend
inpFB7Estatnot2:
CMP [fha],0ffffh
JNE inpFB7Eend
inpFB7Eend:
RET
inpFB7E_Write:
OR AL,60h
RET
inpFB7F:
CMP [dcstat],1
JE oFB7F_parms
CMP [dcstat],2
JNE inpFB7Fend
CMP [dcextdata],0
JE inpFB7F_normdata
DEC [dcextdata]
MOV BP,[dcedp]
MOV AL,[BP]
INC BP
MOV [dcedp],BP
JMP inpFB7Fend
inpFB7F_normdata:
DEC [dcbytecnt]
MOV BP,[dcdpt]
MOV AL,[BP]
INC BP
MOV [dcdpt],BP
CMP [dcbytecnt],0
JNE inpFB7Fend
MOV [dcstat],0
inpFB7Fend:
RET
inpFB7Ffinish:
MOV [dcstat],0
RET
ENDS
SEGMENT _data PAGE PUBLIC 'DATA'
fha dw 0
MACRO FCMD c1,c2,c3,c4
db c1,c2,c3,0
dw c4
ENDM
LABEL dccommands WORD
FCMD 8,0,2,DCGetTrack
FCMD 7,1,0,DCSeek0
FCMD 3,2,0,DCRecalibrate
FCMD 4,1,1,DCGetInfo
FCMD 15,2,0,DCSeek
FCMD 04Ah,1,7,DCGetID
FCMD 045h,8,0,DCWrite
FCMD 046h,8,7,DCReadSec
FCMD 066h,8,7,DCReadSec
dd 0
LABEL Writecmd WORD
FCMD 0ffh,0,7,DCWritectd
EVEN
dcFAxx db 0,0
dccommand dw ?
dcstat db 0,0
dcbytecnt dw 0
dccmdparms dw 10 DUP (?)
dcdata dw 20 DUP (?)
dcextdata dw ?
dcedp dw ?
dcdpt dw ?
dccppt dw ?
dccurrdrive db 0
CurrTrack db 0
idfield dw 66 DUP (?)
trackoffslo dw ?
trackoffshi dw ?
IDTPtr dw ?
diskchange dw 0
DCsReg0 db 0
DCsReg1 db 0
DCsReg2 db 0
DCsReg3 db 0
tracktoohi db 0,0
thisfdcmd db 0
lastfdcmd db 0
DiskType db 10 DUP (0)
tracklen dw 0
wrinprogr dw 0
ENDS
SEGMENT _stack PARA STACK 'STACK'
DiskBuf db 5300 DUP (?)
thistrack db 5300 DUP (?)
ENDS
END