terug.gif
(***************************************************************************)
(*                                                                         *)
(* Floppy Disk Controller 8271 for the Acorn Atom Emulator v1.31 (c) W.Ras *)
(* ----------------------------------------------------------------------- *)
(*                                                                         *)
(* This source code may be distributed freely within the following         *)
(* restrictions                                                            *)
(* 1. You may not charge for this program or for any part of it.           *)
(* 2. This copyright message may not be removed from it.                   *)
(* 3. You may use sections of code from this program in your applications, *)
(* but you must acknowledge its use. I'd appreciate it if you'd let me     *)
(* know, i.e. send me a copy of your work.                                 *)
(*                                                                         *)
(* Please report any problems, questions, comments to me at this address:  *)
(* avio@casema.net                                                         *)
(*                                                                         *)
(* The latest version of the emulator can be downloaded from my Atom-page: *)
(* http://www.casema.net/~avio/atom.htm                                    *)
(*                                                                         *)
(***************************************************************************)
{$g+,f+,i-,r-,s-}
UNIT FDC8271;
INTERFACE
VAR DUMMY:BYTE; {!!!must not be separated from WRITEPROTECT!!!}
WRITEPROTECT:ARRAY[0..1] OF BYTE; {write protect drive 0/2 and 1/3; xF/Fx=protected}
DISKETTENAMES:ARRAY[0..3] OF STRING[13];
PROCEDURE CLRDRIVETXT;
PROCEDURE READ_FDC;
PROCEDURE WRITE_FDC;
PROCEDURE FDC_NMI_HANDLER;
PROCEDURE OPEN_DISK_IMAGE (DRIVENR:BYTE; NOWRITE:BOOLEAN);
PROCEDURE CLOSE_DISK_IMAGE (DRIVENR:BYTE);
IMPLEMENTATION
CONST NMI = $BFF6; {---same address as IRQ in main program---}
VAR IMAGENAAM:ARRAY[0..12] OF CHAR;
{$f-}
PROCEDURE CMDDEST; ASSEMBLER;
ASM;
DW $0000
END;
PROCEDURE DRVCTRLOUTP; ASSEMBLER;
ASM;
DB $00
END;
PROCEDURE SETDRIVETXT; ASSEMBLER;
ASM;
PUSH DI
PUSH BX
PUSH CX
MOV DI,$DCA0
MOV CH,+8
@SETDR2: MOV CL,+6
@SETDR1: MOV WORD PTR [ES:DI],$FFFF
MOV WORD PTR [ES:DI+$02],$FF00
MOV WORD PTR [ES:DI+32],$FFFF
MOV WORD PTR [ES:DI+32+$02],$FF00
ADD DI,+$04
DEC CL
JNZ @SETDR1
ADD DI,$0120-6*$04
DEC CH
CMP CH,+4
JNZ @SETDR5
ADD DI,$0120
@SETDR5: OR CH,CH
JNZ @SETDR2
MOV DI,$E120
MOV CH,+2
@SETDR4: MOV WORD PTR [ES:DI],$F0FF
MOV WORD PTR [ES:DI+$02],$FF0F
ADD DI,+$04
MOV CL,+4
@SETDR3: MOV WORD PTR [ES:DI],$00FF
MOV WORD PTR [ES:DI+$02],$FFFF
ADD DI,+$04
DEC CL
JNZ @SETDR3
MOV WORD PTR [ES:DI],$0FFF
MOV WORD PTR [ES:DI+$02],$FFF0
ADD DI,+$0C
DEC CH
JNZ @SETDR4
{SUB CX,CX}
MOV WORD PTR @LIGHTCOLOR[$00],CX
MOV WORD PTR @LIGHTCOLOR[$02],CX
MOV BL,BYTE PTR [CS:CMDDEST+$01]
AND BL,$01
TEST BYTE PTR [CS:DRVCTRLOUTP],00100000b
JZ @SETDR6
OR BL,$02
@SETDR6: MOV BH,$00
MOV BYTE PTR @LIGHTCOLOR[BX],$01
MOV BX,+3
@SETDR9: SHL BX,1
MOV DI,WORD PTR @LIGHTPOS[BX]
SHR BX,1
CMP BYTE PTR @LIGHTCOLOR[BX],$00
JNZ @SETDR7
MOV WORD PTR [ES:DI],$F0FF
MOV WORD PTR [ES:DI+$02],$FF0F
MOV WORD PTR [ES:DI+$04],$0FFF
MOV WORD PTR [ES:DI+$06],$FFF0
JMP @SETDR8
@SETDR7: MOV WORD PTR [ES:DI],$F0FF
MOV WORD PTR [ES:DI+$02],$FF00
MOV WORD PTR [ES:DI+$04],$0FFF
MOV WORD PTR [ES:DI+$06],$FF00
@SETDR8: DEC BX
JNS @SETDR9
POP CX
POP BX
POP DI
RET
@LIGHTCOLOR: DB $00,$00,$00,$00
@LIGHTPOS: DW $DEE8,$DF08,$E368,$E388
END;
{---[clrdrivetxt]-----------------------------------------------------------}
PROCEDURE CLRDRIVETXT; ASSEMBLER;
ASM;
PUSH DI
PUSH CX
MOV DI,$DCA0
MOV CH,+9
@CLRDR2: MOV CL,+6
@CLRDR1: MOV WORD PTR [ES:DI],$FFFF
MOV WORD PTR [ES:DI+$02],$00FF
MOV WORD PTR [ES:DI+32],$FFFF
MOV WORD PTR [ES:DI+32+$02],$00FF
ADD DI,+$04
DEC CL
JNZ @CLRDR1
ADD DI,$0120-6*$04
DEC CH
JNZ @CLRDR2
POP CX
POP DI
END;
PROCEDURE FILEHANDLES; ASSEMBLER;
ASM;
DW $0000
DW $0000
DW $0000
DW $0000
END;
PROCEDURE CALL_FDC; ASSEMBLER;
ASM;
AND DI,$00FF
SHL DI,1
CMP AH,$01
JA @CALL_FDC2
JZ @CALL_FDC1
{---read reg---}
CMP DI,+4*2
JA @CALL_FDC3
JMP WORD PTR @READTABLE[DI]
@CALL_FDC1: {---write reg---}
CMP DI,+4*2
JA @CALL_FDC4
JMP WORD PTR @WRITETABLE[DI]
@CALL_FDC2: {---nmi handler---}
JMP WORD PTR @NMIHNDLR
@CALL_FDC3: MOV AL,$00
@CALL_FDC4: RETN
@READTABLE: DW OFFSET @READFDC00
DW OFFSET @READFDC01
DW OFFSET @READFDC02
DW OFFSET @READFDC03
DW OFFSET @READFDC04
@WRITETABLE: DW OFFSET @WRITEFDC00
DW OFFSET @WRITEFDC01
DW OFFSET @WRITEFDC02
DW OFFSET @WRITEFDC03
DW OFFSET @WRITEFDC04
@COMMANDTABLE: DB $00,$3F,$03; DW OFFSET @COMMAND00
DB $04,$3F,$03; DW OFFSET @COMMAND04
DB $0A,$3F,$02; DW OFFSET @COMMAND0A
DB $0B,$3F,$03; DW OFFSET @COMMAND0B
DB $0E,$3F,$02; DW OFFSET @COMMAND0E
DB $0F,$3F,$03; DW OFFSET @COMMAND0F
DB $12,$3F,$02; DW OFFSET @COMMAND12
DB $13,$3F,$03; DW OFFSET @COMMAND13
DB $16,$3F,$02; DW OFFSET @COMMAND16
DB $17,$3F,$03; DW OFFSET @COMMAND17
DB $1B,$3F,$03; DW OFFSET @COMMAND1B
DB $1E,$3F,$02; DW OFFSET @COMMAND1E
DB $1F,$3F,$03; DW OFFSET @COMMAND1F
DB $23,$3F,$05; DW OFFSET @COMMAND23
DB $29,$3F,$01; DW OFFSET @COMMAND29
DB $2C,$3F,$00; DW OFFSET @COMMAND2C
DB $35,$FF,$04; DW OFFSET @COMMAND35
DB $3A,$3F,$02; DW OFFSET @COMMAND3A
DB $3D,$3F,$01; DW OFFSET @COMMAND3D
DB $00,$00,$00; DW OFFSET @NOCOMMAND
@STATUSREG: DB $00
@RESULTREG: DB $00
@COMMANDREG: DB $00
@PARAMREG: DB $00
@RESETREG: DB $00
@DATAREG: DB $00
@ERRORNR: DB $00
@MODEREG: DB $00 {!!!do not separate @modereg and @headpos!!!}
@HEADPOS: DW $0000 {head position for drive 0/2 and 1/3}
@FDCREG06: DB $00
@FDCREG10: DB $00
@FDCREG11: DB $00
@FDCREG13: DB $00
@FDCREG18: DB $00
@FDCREG19: DB $00
@FDCREG22: DB $00
@AANTALPARAM: DB $00
@COMMANDHNDLR: DW $0000
@PARAMTELLER: DB $00
@PARAMETERS: DD $00000000,$00000000
@NMIHNDLR: DW OFFSET @NONMI
@TRACK: DB $00
@SECTOR: DB $00
@AANTALSECT: DB $00
@BYTESPERSECT: DW $0000
@BUFPTR: DW $0000
@BUFFER: DD 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
DD 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
DD 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
DD 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
{---[saveerrornr]-----------------------------------------------------------}
@SAVEERRORNR: MOV BYTE PTR @ERRORNR,AL
MOV BYTE PTR @STATUSREG,10000000b
OR BYTE PTR [NMI],$80
RETN
{---[setcmddest]------------------------------------------------------------}
@SETCMDDEST: PUSH AX
SUB AX,AX
TEST BYTE PTR @COMMANDREG,01000000b
JZ @SETCMDDEST1
DEC AL
@SETCMDDEST1: TEST BYTE PTR @COMMANDREG,10000000b
JZ @SETCMDDEST2
DEC AH
@SETCMDDEST2: MOV WORD PTR [CS:CMDDEST],AX
POP AX
RETN
{---[getDIfordrive]---------------------------------------------------------}
@GETDIFORDRIVE:MOV DI,-1 {--> points to @modereg}
CMP WORD PTR [CS:CMDDEST],$0000
JZ @GETDI1
INC DI {--> points to @headpos 0/2}
CMP BYTE PTR [CS:CMDDEST+$01],$00
JZ @GETDI1
INC DI {--> points to @headpos 1/3}
@GETDI1: RETN
{---[chkdriveready (carry clear if successful)]-----------------------------}
@CHKDRIVEREADY:CMP WORD PTR [CS:CMDDEST],$0000
CLC
JNZ @CHKDRVREADY1
@DRVNOTREADY: MOV AL,$10
CALL @SAVEERRORNR
STC
@CHKDRVREADY1: RETN
{---[chkwriteprot (carry clear if no writeprotect)]-------------------------}
@CHKWRITEPROT: PUSH DS
PUSH AX
MOV AX,SEG WRITEPROTECT
MOV DS,AX
MOV AL,BYTE PTR WRITEPROTECT[DI]
TEST BYTE PTR [CS:DRVCTRLOUTP],00100000b
JZ @CHKWRITEPROT2
SHR AL,4
@CHKWRITEPROT2:AND AL,$01
POP AX
POP DS
CLC
JZ @CHKWRITEPROT1
MOV AL,$12
CALL @SAVEERRORNR
STC
@CHKWRITEPROT1:RETN
{---[chklegalpos (carry clear if successful)]-------------------------------}
@CHKLEGALPOS: CMP BYTE PTR @TRACK,+40
JAE @CHKLEGAL1
CMP BYTE PTR @SECTOR,+10
JAE @CHKLEGAL1
CMP WORD PTR @BYTESPERSECT,$0100
JNZ @CHKLEGAL1
CLC
RETN
@CHKLEGAL1: MOV AL,$1E
CALL @SAVEERRORNR
STC
RETN
{---[checkerror (carry set on error)]---------------------------------------}
@CHECKERROR: OR BYTE PTR @STATUSREG,00001000b
CMP BYTE PTR @ERRORNR,$00
JZ @CHKERR1
MOV AL,$00
XCHG AL,BYTE PTR @ERRORNR
MOV BYTE PTR @RESULTREG,AL
MOV BYTE PTR @STATUSREG,00011000b
MOV WORD PTR @NMIHNDLR,OFFSET @NONMI
CALL CLRDRIVETXT
STC
RETN
@CHKERR1: CLC
RETN
{---[seekfilepos]-----------------------------------------------------------}
@SEEKFILEPOS: MOV AL,BYTE PTR @TRACK
MOV CL,+10
MUL CL
MOV CH,BYTE PTR @SECTOR
CMP CH,CL
JAE @SEEKF1
ADD AL,CH
ADC AH,$00
@SEEKF1: SUB CX,CX
XCHG AL,AH
XCHG CL,AL
MOV DX,AX {---CX:DX=filepos---}
MOV AX,$4200
CALL @GETFILEHANDLE
JZ @DRVNOTREADY
INT $21
JC @DRVNOTREADY
{CLC}
RETN
{---[getfilehandle]---------------------------------------------------------}
@GETFILEHANDLE:MOV BL,BYTE PTR [CS:CMDDEST+$01]
AND BX,+$02
TEST BYTE PTR [CS:DRVCTRLOUTP],00100000b
JZ @GETFHNDL1
OR BL,$04
@GETFHNDL1: MOV BX,WORD PTR FILEHANDLES[CS:BX]
OR BX,BX
RETN
{---[readfdc00: read status]------------------------------------------------}
@READFDC00: MOV AL,BYTE PTR @STATUSREG
MOV BYTE PTR [$BA00],AL {for debug purposes only}
RETN
{---[readfdc01: read result]------------------------------------------------}
@READFDC01: AND BYTE PTR @STATUSREG,11100111b
MOV AL,$00
XCHG AL,BYTE PTR @RESULTREG
MOV BYTE PTR [$BA01],AL {for debug purposes only}
RETN
{---[readfdc02/03]----------------------------------------------------------}
@READFDC02:
@READFDC03: MOV AL,$00
RETN
{---[readfdc04: read data]--------------------------------------------------}
@READFDC04: AND BYTE PTR @STATUSREG,11110011b
MOV AL,BYTE PTR @DATAREG
MOV BYTE PTR [$BA04],AL {for debug purposes only}
RETN
{---[writefdc00: write command]---------------------------------------------}
@WRITEFDC00: PUSH BX
MOV BX,-5
@WRFDC00_1: ADD BX,+5
MOV AH,AL
AND AH,BYTE PTR @COMMANDTABLE[BX+$01]
CMP AH,BYTE PTR @COMMANDTABLE[BX]
JNZ @WRFDC00_1
MOV BYTE PTR @COMMANDREG,AL
MOV AL,BYTE PTR @COMMANDTABLE[BX+$02]
MOV BYTE PTR @AANTALPARAM,AL
MOV AX,WORD PTR @COMMANDTABLE[BX+$03]
MOV WORD PTR @COMMANDHNDLR,AX
POP BX
MOV BYTE PTR @PARAMTELLER,$00
OR BYTE PTR @STATUSREG,10010000b
CMP BYTE PTR @AANTALPARAM,$00
JNZ @WRFDC00_2
AND BYTE PTR @STATUSREG,01111110b
PUSHA
CALL WORD PTR @COMMANDHNDLR
POPA
@WRFDC00_2: RETN
{---[writefdc01: write parameter]-------------------------------------------}
@WRITEFDC01: PUSH BX
MOV BL,BYTE PTR @PARAMTELLER
AND BX,$0007
CMP BL,BYTE PTR @AANTALPARAM
JAE @WRFDC01_2
MOV BYTE PTR @PARAMETERS[BX],AL
INC BL
MOV BYTE PTR @PARAMTELLER,BL
AND BYTE PTR @STATUSREG,11111110b
CMP BL,BYTE PTR @AANTALPARAM
JNZ @WRFDC01_2
AND BYTE PTR @STATUSREG,01111110b
PUSHA
CALL WORD PTR @COMMANDHNDLR
POPA
@WRFDC01_2: POP BX
RETN
{---[writefdc02: reset fdc]-------------------------------------------------}
@WRITEFDC02: MOV AL,$00
MOV BYTE PTR @STATUSREG,AL
MOV BYTE PTR @RESULTREG,AL
MOV BYTE PTR @FDCREG06,AL
MOV BYTE PTR @HEADPOS[$00],AL
MOV BYTE PTR @FDCREG13,AL
MOV BYTE PTR @HEADPOS[$01],AL
MOV BYTE PTR @FDCREG22,AL
MOV BYTE PTR [CS:DRVCTRLOUTP],AL
MOV BYTE PTR @AANTALPARAM,AL
MOV BYTE PTR @ERRORNR,AL
DEC AL
MOV BYTE PTR @COMMANDREG,AL
MOV BYTE PTR @FDCREG10,AL
MOV BYTE PTR @FDCREG11,AL
MOV BYTE PTR @FDCREG18,AL
MOV BYTE PTR @FDCREG19,AL
@WRITEFDC03: RETN
{---[writefdc04: write data]------------------------------------------------}
@WRITEFDC04: AND BYTE PTR @STATUSREG,11110011b
MOV BYTE PTR @DATAREG,AL
MOV BYTE PTR [$BA04],AL {for debug purposes only}
RETN
{---[fdc commands]----------------------------------------------------------}
@COMMAND00:
@COMMAND04:
@COMMAND0A:
@COMMAND0E:
@COMMAND0F:
@COMMAND12:
@COMMAND16:
@COMMAND17:
@COMMAND1E:
CALL @SETCMDDEST
@COMMAND35:
@NOCOMMAND: RETN
{---[command0B: write data variable length/multi-record format]-------------}
@COMMAND0B: MOV WORD PTR @NMIHNDLR,OFFSET @WRITEDAT
CALL @SETCMDDEST
CALL @CHKDRIVEREADY
JC @CMD0B_1
CALL @GETDIFORDRIVE
CALL @CHKWRITEPROT
JC @CMD0B_1
MOV AL,BYTE PTR @PARAMETERS[$00]
MOV BYTE PTR @HEADPOS[DI],AL
MOV BYTE PTR @TRACK,AL
MOV AL,BYTE PTR @PARAMETERS[$01]
MOV BYTE PTR @SECTOR,AL
MOV AL,BYTE PTR @PARAMETERS[$02]
MOV CL,AL
AND AL,00011111b
MOV BYTE PTR @AANTALSECT,AL
SHR CL,5
ADD CL,$07
MOV AX,$0001
SHL AX,CL
MOV WORD PTR @BYTESPERSECT,AX
CALL @CHKLEGALPOS
JC @CMD0B_1
CALL @SEEKFILEPOS
JC @CMD0B_1
MOV WORD PTR @BUFPTR,-1
OR BYTE PTR [NMI],$80
MOV BYTE PTR @STATUSREG,10001100b
CALL SETDRIVETXT
@CMD0B_1: RETN
@WRITEDAT: CALL @CHECKERROR
JC @WRITED6
CMP BYTE PTR @AANTALSECT,$00
JZ @WRITED1
MOV SI,WORD PTR @BUFPTR
CMP SI,$0100
JAE @WRITED2
MOV AL,BYTE PTR @DATAREG
MOV BYTE PTR @BUFFER[SI],AL
@WRITED2: INC SI
MOV WORD PTR @BUFPTR,SI
MOV BYTE PTR @RESULTREG,$00
CMP SI,WORD PTR @BYTESPERSECT
JL @WRITED3
MOV WORD PTR @BUFPTR,$0000
MOV AH,$40
CALL @GETFILEHANDLE
JZ @WRITED4
MOV CX,$0100
MOV DX,OFFSET @BUFFER
PUSH DS
PUSH CS
POP DS
INT $21 {---write data to disk image---}
POP DS
JC @WRITED4
DEC BYTE PTR @AANTALSECT
JZ @WRITED5
INC BYTE PTR @SECTOR
CALL @CHKLEGALPOS
JNC @WRITED3
@WRITED6: RETN
@WRITED5: MOV BYTE PTR @STATUSREG,00011000b
CALL CLRDRIVETXT
RETN
@WRITED3: MOV BYTE PTR @STATUSREG,10001100b
OR BYTE PTR [NMI],$80
RETN
@WRITED1: MOV BYTE PTR @STATUSREG,00011000b
MOV WORD PTR @NMIHNDLR,OFFSET @NONMI
CALL CLRDRIVETXT
@NONMI: RETN
@WRITED4: MOV AL,$16 {write error}
CALL @SAVEERRORNR
RETN
{---[command13: read data variable length/multi-record format]--------------}
@COMMAND13: MOV WORD PTR @NMIHNDLR,OFFSET @READDAT
CALL @SETCMDDEST
CALL @CHKDRIVEREADY
JC @CMD13_1
CALL @GETDIFORDRIVE
MOV AL,BYTE PTR @PARAMETERS[$00]
MOV BYTE PTR @HEADPOS[DI],AL
MOV BYTE PTR @TRACK,AL
MOV AL,BYTE PTR @PARAMETERS[$01]
MOV BYTE PTR @SECTOR,AL
MOV AL,BYTE PTR @PARAMETERS[$02]
MOV CL,AL
AND AL,00011111b
MOV BYTE PTR @AANTALSECT,AL
SHR CL,5
ADD CL,$07
MOV AX,$0001
SHL AX,CL
MOV WORD PTR @BYTESPERSECT,AX
CALL @CHKLEGALPOS
JC @CMD13_1
CALL @SEEKFILEPOS
JC @CMD13_1
MOV WORD PTR @BUFPTR,0
OR BYTE PTR [NMI],$80
MOV BYTE PTR @STATUSREG,10001100b
CALL SETDRIVETXT
@CMD13_1: RETN
@READDAT: CALL @CHECKERROR
JC @READD6
CMP BYTE PTR @AANTALSECT,$00
JZ @READD1
MOV SI,WORD PTR @BUFPTR
OR SI,SI
JNZ @READD2
MOV AH,$3F
CALL @GETFILEHANDLE
JZ @READD3
MOV CX,$0100
MOV DX,OFFSET @BUFFER
PUSH DS
PUSH CS
POP DS
INT $21 {---read data from disk image---}
POP DS
JC @READD3
CMP AX,$0100
JNZ @READD3
MOV SI,WORD PTR @BUFPTR
@READD2: MOV AL,BYTE PTR @BUFFER[SI]
MOV BYTE PTR @DATAREG,AL
INC SI
MOV WORD PTR @BUFPTR,SI
MOV BYTE PTR @RESULTREG,$00
CMP SI,WORD PTR @BYTESPERSECT
JL @READD4
MOV WORD PTR @BUFPTR,$0000
DEC BYTE PTR @AANTALSECT
JZ @READD5
INC BYTE PTR @SECTOR
CALL @CHKLEGALPOS
JNC @READD4
@READD6: RETN
@READD5: MOV BYTE PTR @STATUSREG,10011100b
OR BYTE PTR [NMI],$80
RETN
@READD4: MOV BYTE PTR @STATUSREG,10001100b
OR BYTE PTR [NMI],$80
RETN
@READD1: MOV BYTE PTR @STATUSREG,00011000b
MOV WORD PTR @NMIHNDLR,OFFSET @NONMI
CALL CLRDRIVETXT
RETN
@READD3: MOV AL,$1E {illegal track or sector / read error}
CALL @SAVEERRORNR
RETN
{---[command1B: read ID command]--------------------------------------------}
@COMMAND1B: MOV WORD PTR @NMIHNDLR,OFFSET @READID
CALL @SETCMDDEST
CALL @CHKDRIVEREADY
JC @CMD1B_1
CALL @GETDIFORDRIVE
MOV AL,BYTE PTR @PARAMETERS[$00]
MOV BYTE PTR @HEADPOS[DI],AL
MOV BYTE PTR @TRACK,AL
MOV BYTE PTR @SECTOR,$00
MOV AL,BYTE PTR @PARAMETERS[$02]
MOV BYTE PTR @AANTALSECT,AL
CALL @CHKLEGALPOS
JC @CMD1B_1
MOV WORD PTR @BUFPTR,0
OR BYTE PTR [NMI],$80
MOV BYTE PTR @STATUSREG,10000000b
CALL SETDRIVETXT
@CMD1B_1: RETN
@READID: CALL @CHECKERROR
JC @READID8
CMP BYTE PTR @AANTALSECT,$00
JZ @READID1
MOV SI,WORD PTR @BUFPTR
OR SI,SI
JNZ @READID2
MOV AL,BYTE PTR @TRACK
@READID2: CMP SI,+$01
JNZ @READID3
MOV AL,$00
@READID3: CMP SI,+$02
JNZ @READID4
MOV AL,BYTE PTR @SECTOR
@READID4: CMP SI,+$03
JNZ @READID5
MOV AL,$01
@READID5: MOV BYTE PTR @DATAREG,AL
INC SI
MOV WORD PTR @BUFPTR,SI
CMP SI,+$04
JB @READID6
MOV WORD PTR @BUFPTR,$0000
DEC BYTE PTR @AANTALSECT
JZ @READID7
INC BYTE PTR @SECTOR
CALL @CHKLEGALPOS
JNC @READID6
@READID8: RETN
@READID7: MOV BYTE PTR @STATUSREG,10011100b
OR BYTE PTR [NMI],$80
RETN
@READID6: MOV BYTE PTR @STATUSREG,10001100b
OR BYTE PTR [NMI],$80
RETN
@READID1: MOV BYTE PTR @STATUSREG,00011000b
MOV WORD PTR @NMIHNDLR,OFFSET @NONMI
CALL CLRDRIVETXT
RETN
{---[command1F: verify data and deleted data]-------------------------------}
@COMMAND1F: MOV WORD PTR @NMIHNDLR,OFFSET @VERIFYDAT
CALL @SETCMDDEST
CALL @CHKDRIVEREADY
JC @CMD1F_1
CALL @GETDIFORDRIVE
MOV AL,BYTE PTR @PARAMETERS[$00]
MOV BYTE PTR @HEADPOS[DI],AL
MOV BYTE PTR @STATUSREG,10000000b
OR BYTE PTR [NMI],$80
CALL SETDRIVETXT
@CMD1F_1: RETN
@VERIFYDAT: CALL @CHECKERROR
JC @VERIFY1
MOV BYTE PTR @STATUSREG,00011000b
MOV BYTE PTR @RESULTREG,$00
MOV WORD PTR @NMIHNDLR,OFFSET @NONMI
CALL CLRDRIVETXT
@VERIFY1: RETN
{---[command23: formattrack]------------------------------------------------}
@COMMAND23: MOV WORD PTR @NMIHNDLR,OFFSET @FORMATTRACK
CALL @SETCMDDEST
CALL @CHKDRIVEREADY
JC @CMD23_1
CALL @GETDIFORDRIVE
CALL @CHKWRITEPROT
JC @CMD23_1
MOV AL,BYTE PTR @PARAMETERS[$00]
MOV BYTE PTR @HEADPOS[DI],AL
MOV BYTE PTR @TRACK,AL
MOV BYTE PTR @SECTOR,$00
MOV AL,BYTE PTR @PARAMETERS[$02]
MOV CL,AL
AND AL,00011111b
MOV BYTE PTR @AANTALSECT,AL
SHR CL,5
ADD CL,$07
MOV AX,$0001
SHL AX,CL
MOV WORD PTR @BYTESPERSECT,AX
CALL @CHKLEGALPOS
JC @CMD23_1
CALL @SEEKFILEPOS
JC @CMD23_1
MOV WORD PTR @BUFPTR,0
OR BYTE PTR [NMI],$80
MOV BYTE PTR @STATUSREG,10001100b
CALL SETDRIVETXT
@CMD23_1: RETN
@FORMATTRACK: CALL @CHECKERROR
JC @FORMAT6
CMP BYTE PTR @AANTALSECT,$00
JZ @FORMAT1
MOV SI,WORD PTR @BUFPTR
INC SI
MOV WORD PTR @BUFPTR,SI
MOV BYTE PTR @RESULTREG,$00
CMP SI,+$04
JB @FORMAT2
MOV SI,$00FE
@FORMAT3: MOV WORD PTR @BUFFER[SI],$E5E5
SUB SI,+$02
JNS @FORMAT3
MOV AH,$40
CALL @GETFILEHANDLE
JZ @FORMAT4
MOV CX,$0100
MOV DX,OFFSET @BUFFER
PUSH DS
PUSH CS
POP DS
INT $21 {---write data to disk image---}
POP DS
JC @FORMAT4
MOV WORD PTR @BUFPTR,$0000
DEC BYTE PTR @AANTALSECT
JZ @FORMAT5
INC BYTE PTR @SECTOR
CALL @CHKLEGALPOS
JNC @FORMAT2
@FORMAT6: RETN
@FORMAT5: MOV BYTE PTR @STATUSREG,00010000b
OR BYTE PTR [NMI],$80
RETN
@FORMAT2: MOV BYTE PTR @STATUSREG,10001100b
OR BYTE PTR [NMI],$80
RETN
@FORMAT1: MOV BYTE PTR @STATUSREG,00011000b
MOV WORD PTR @NMIHNDLR,OFFSET @NONMI
CALL CLRDRIVETXT
RETN
@FORMAT4: MOV AL,$16
CALL @SAVEERRORNR
RETN
{---[command29: seektrack]--------------------------------------------------}
@COMMAND29: MOV WORD PTR @NMIHNDLR,OFFSET @SEEKTRACK
CALL @SETCMDDEST
CALL @CHKDRIVEREADY
JC @CMD29_1
CALL @GETDIFORDRIVE
MOV AL,BYTE PTR @PARAMETERS[$00]
MOV BYTE PTR @HEADPOS[DI],AL
MOV BYTE PTR @STATUSREG,10000000b
OR BYTE PTR [NMI],$80
CALL SETDRIVETXT
@CMD29_1: RETN
@SEEKTRACK: CALL @CHECKERROR
JC @SEEKTR1
MOV BYTE PTR @STATUSREG,00011000b
MOV BYTE PTR @RESULTREG,$00
CALL CLRDRIVETXT
@SEEKTR1: RETN
{---[command2C: read drive status]------------------------------------------}
@COMMAND2C: CALL @GETDIFORDRIVE
MOV AL,10000000b
CMP BYTE PTR [CS:CMDDEST+$01],$00
JZ @CMD2C_1
OR AL,01000000b {drive 1 ready}
@CMD2C_1: CMP BYTE PTR [CS:CMDDEST+$00],$00
JZ @CMD2C_2
OR AL,00000100b {drive 0 ready}
@CMD2C_2: CMP BYTE PTR @HEADPOS[DI],$00
JNZ @CMD2C_3
OR AL,00000010b {head on track 0}
@CMD2C_3: PUSH DS
PUSH AX
MOV AX,SEG WRITEPROTECT
MOV DS,AX
MOV AL,BYTE PTR WRITEPROTECT[DI]
TEST BYTE PTR [CS:DRVCTRLOUTP],00100000b
JZ @CMD2C_5
SHR AL,4
@CMD2C_5: AND AL,$01
POP AX
POP DS
JZ @CMD2C_4
OR AL,00001000b {disk write protected}
@CMD2C_4: MOV BYTE PTR @RESULTREG,AL
OR BYTE PTR @STATUSREG,00010000b
RETN
{---[command3A: write register]---------------------------------------------}
@COMMAND3A: CALL @SETCMDDEST
MOV AX,WORD PTR @PARAMETERS[$00]
CMP AL,$06
JNZ @CMD3A_1
MOV BYTE PTR @FDCREG06,AH
RETN
@CMD3A_1: CMP AL,$10
JNZ @CMD3A_2
MOV BYTE PTR @FDCREG10,AH
RETN
@CMD3A_2: CMP AL,$11
JNZ @CMD3A_3
MOV BYTE PTR @FDCREG11,AH
RETN
@CMD3A_3: CMP AL,$12
JNZ @CMD3A_4
MOV BYTE PTR @HEADPOS[$00],AH
RETN
@CMD3A_4: CMP AL,$13
JNZ @CMD3A_5
MOV BYTE PTR @FDCREG13,AH
RETN
@CMD3A_5: CMP AL,$14
JNZ @CMD3A_6
@CMD3A_7: MOV BYTE PTR @MODEREG,AH
RETN
@CMD3A_6: CMP AL,$17
JZ @CMD3A_7
CMP AL,$18
JNZ @CMD3A_8
MOV BYTE PTR @FDCREG18,AH
RETN
@CMD3A_8: CMP AL,$19
JNZ @CMD3A_9
MOV BYTE PTR @FDCREG19,AH
RETN
@CMD3A_9: CMP AL,$22
JNZ @CMD3A_10
MOV BYTE PTR @FDCREG22,AH
RETN
@CMD3A_10: CMP AL,$23
JNZ @CMD3A_11
MOV BYTE PTR [CS:DRVCTRLOUTP],AH
MOV WORD PTR [CS:CMDDEST],$0000
TEST AH,$40
JZ @CMD3A_12
DEC BYTE PTR [CS:CMDDEST+$00]
@CMD3A_12: TEST AH,$80
JZ @CMD3A_11
DEC BYTE PTR [CS:CMDDEST+$01]
@CMD3A_11: RETN
{---[command3D: read register]----------------------------------------------}
@COMMAND3D: CALL @SETCMDDEST
MOV AL,BYTE PTR @PARAMETERS[$00]
MOV AH,BYTE PTR @FDCREG06
CMP AL,$06
JZ @CMD3D_1
MOV AH,BYTE PTR @FDCREG10
CMP AL,$10
JZ @CMD3D_1
MOV AH,BYTE PTR @FDCREG11
CMP AL,$11
JZ @CMD3D_1
MOV AH,BYTE PTR @HEADPOS[$00]
CMP AL,$12
JZ @CMD3D_1
MOV AH,BYTE PTR @FDCREG13
CMP AL,$13
JZ @CMD3D_1
MOV AH,BYTE PTR @MODEREG
CMP AL,$14
JZ @CMD3D_1
CMP AL,$17
JZ @CMD3D_1
MOV AH,BYTE PTR @FDCREG18
CMP AL,$18
JZ @CMD3D_1
MOV AH,BYTE PTR @FDCREG19
CMP AL,$19
JZ @CMD3D_1
MOV AH,BYTE PTR @HEADPOS[$01]
CMP AL,$1A
JZ @CMD3D_1
MOV AH,BYTE PTR @FDCREG22
CMP AL,$22
JZ @CMD3D_1
MOV AH,BYTE PTR [CS:DRVCTRLOUTP]
CMP AL,$23
JNZ @CMD3D_2
@CMD3D_1: MOV BYTE PTR @RESULTREG,AH
OR BYTE PTR @STATUSREG,00010000b
@CMD3D_2: RETN
END;
{$f+}
PROCEDURE READ_FDC; ASSEMBLER;
ASM
MOV AH,$00
CALL CALL_FDC
END;
PROCEDURE WRITE_FDC; ASSEMBLER;
ASM;
MOV AH,$01
CALL CALL_FDC
END;
PROCEDURE FDC_NMI_HANDLER; ASSEMBLER;
ASM;
PUSHA
MOV AH,$02
CALL CALL_FDC
POPA
END;
PROCEDURE OPEN_DISK_IMAGE (DRIVENR:BYTE; NOWRITE:BOOLEAN); ASSEMBLER;
ASM;
MOV AL,BYTE PTR DRIVENR
MOV CL,+14
MUL CL
MOV SI,AX
MOV BL,BYTE PTR DISKETTENAMES[SI]
MOV BH,$00
INC SI
MOV WORD PTR DISKETTENAMES[SI+BX],'D.'
MOV WORD PTR DISKETTENAMES[SI+BX+$02],'KS'
MOV BYTE PTR DISKETTENAMES[SI+BX+$04],$00
MOV AH,$3D
MOV AL,$A0 {read only; no write access by others}
TEST BYTE PTR NOWRITE,$FF
JNZ @ODI2
MOV AL,$A2 {allow read and write; no write access by others}
@ODI2: MOV CL,$FF
MOV DX,SI
ADD DX,OFFSET DISKETTENAMES
PUSH SI
INT $21
POP SI
JNC @ODI1
SUB AX,AX
MOV BYTE PTR DISKETTENAMES[SI-$01],$00
@ODI1: MOV BL,BYTE PTR DRIVENR
MOV BH,$00
SHL BX,1
MOV WORD PTR FILEHANDLES[CS:BX],AX
END;
PROCEDURE CLOSE_DISK_IMAGE (DRIVENR:BYTE); ASSEMBLER;
ASM;
MOV BL,BYTE PTR DRIVENR
MOV BH,$00
SHL BX,1
MOV BX,WORD PTR FILEHANDLES[CS:BX]
MOV AH,$3E
INT $21
MOV BL,BYTE PTR DRIVENR
MOV BH,$00
SHL BX,1
MOV WORD PTR FILEHANDLES[CS:BX],$0000
MOV WORD PTR [CS:CMDDEST],$0000
END;
{INITIALISATION}
VAR I:BYTE;
BEGIN
DUMMY := $00;
FOR I := 0 TO 1 DO WRITEPROTECT[I] := $00;
FOR I := 0 TO 3 DO DISKETTENAMES[I] := '';
END.
terug.gif