home *** CD-ROM | disk | FTP | other *** search
- ; XEROX REQUIRES 4MHZ ZPU OPERATION
- EXTRN BINH2
- XEROX:
- ld hl,(6)
- ld sp,hl
- LD A,(5CH); CDOS FCB-1
- LD (TO),A
- LD A,(6CH); CDOS FCB-2
- LD (FROM),A
- LD A,(TO)
- OR A
- JR NZ,NXT
- LD C,C.DISK
- CALL CDOS
- INC A
- LD (TO),A
- NXT:
- LD A,(FROM)
- OR A
- JR NZ,NXT2
- LD C,C.DISK
- CALL CDOS
- INC A
- LD (FROM),A
- NXT2:
- LD HL,TO
- CP (HL)
- JR NZ,NXT2A
- LD DE,NOTSAME
- LD C,W.LINE
- CALL CDOS
- JP 0
- NOTSAME:DB LF,CR,BEL,BEL,BEL,'CANNOT COPY TO SAME FLOPPY',LF,CR,'$'
- NXT2A:
- LD A,(TO)
- ADD 40H
- LD (DR),A
- LD DE,QUEST
- LD C,W.LINE
- CALL CDOS
- LD C,R.CHAR
- CALL CDOS
- CP 'Y'
- JR Z,OK
- CP 'y'
- JR Z,OK
- JP 0
- QUEST: DB LF,CR,BEL,BEL,BEL,'OK TO DESTROY CURRENT CONTENTS OF FLOPPY ON DRIVE '
- DR: DB ' ? $'
- CRLF: DB LF,CR,'$'
- FROM: DB 0
- TO: DB 0
- CURR: DB 0
- SAMEDR: DB 0
- DENSITY: DB 0
- RETRY: DB 0
- HLSAVE: DW 0
- TRKSINMEM: DB 0
- TRKIN: DB 0
- TRKOUT: DB 0
- TRKCNT: DB 0
- ENTRY $MEMRY
- $MEMRY: DW 0
- OK:
- LD DE,CRLF
- LD C,W.LINE
- CALL CDOS
- LD A,0; TEST IF FLOPPIES ON SAME DUAL DRIVE
- LD (SAMEDR),A
- LD A,(FROM)
- LD B,A
- LD A,(TO)
- SUB B
- JP P,POSA
- NEG
- POSA: CP 1
- JR NZ,NOTONE; NO
- LD A,(TO); IF DIFFERENCE IS ONE IT MUST BE A 1,2 OR 3,4
- CP B; COMBINATION
- JP P,AGR
- LD A,B
- AGR: RRA; I.E. THE LARGEST MUST BE EVEN
- JR C,NOTONE; NOT ON SAME DUAL DRIVE
- LD (SAMEDR),A
- NOTONE:
- LD A,(FROM)
- LD B,A
- XOR A
- SCF
- NXT3: RLA
- DJNZ NXT3
- OR MOTORON+MAXI+DBLDEN
- LD (FROM),A
- LD A,(TO)
- LD B,A
- XOR A
- SCF
- NXT4: RLA
- DJNZ NXT4
- OR MOTORON+MAXI+DBLDEN
- LD (TO),A
- MSKINTRP: EQU 03H
- AUXDSK: EQU 04H; INPUT/OUTPUT PORT FOR FAST SEEK
- FASTSEEK: EQU 0EFH
- SEEKCOMP: EQU 40H
- RESETFST: EQU 0FFH
- ;
- DSKSTAT:EQU 30H; INPUT PORT FOR DISK STATUS
- NOTREADY: EQU 80H
- PROTECT:EQU 40H
- HEADDOWN: EQU 20H
- WRFAULT:EQU 20H
- NOTFND: EQU 10H
- CRCERR: EQU 08H
- LOSTDATA: EQU 04H
- DRQ: EQU 02H
- BUSY: EQU 01H
- ;
- DSKCMD: EQU 30H; OUTPUT PORT FOR DISK COMMANDS
- RESTORE:EQU 0CH
- SEEK: EQU 18H
- READ: EQU 88H
- ENBLHOLD: EQU 04H
- WRITE: EQU 0A8H
- RESET: EQU 0D0H
- ;
- TRKREG: EQU 31H; I/O PORT FOR TRACK REGISTER
- ;
- SECREG: EQU 32H; I/O PORT FOR SECTOR REGISTER
- ;
- DATAREG:EQU 33H; I/O PORT FOR DATA
- ;
- DSKCNTRL:EQU 34H; OUTPUT PORT FOR DISK CONTROL
- MOTORON:EQU 20H
- MAXI: EQU 10H
- DBLDEN: EQU 40H
- AUTOWAIT: EQU 80H
- ;
- DSKFLGS:EQU 34H; INPUT PORT FOR DISK FLAGS
- HEADLOAD: EQU 20H
- EOJ: EQU 01H
- ;
- CDOS: EQU 5; CDOS CALL ADDRESS
- ; CDOS CALL CODES
- C.DISK: EQU 25
- R.CHAR: EQU 1
- W.LINE: EQU 9
- DIVIDE: EQU 138
- RES.CDOS: EQU 13
- SEL.DISK: EQU 14
- ; TTY CONTROL CODES
- CR: EQU 0DH
- LF: EQU 0AH
- BEL: EQU 07H
- ; DISK CONSTANTS
- MAXRETRY: EQU 10 ; NUMBER OF RETRIES IF R/W ERROR
- NRTRKS: EQU 77
- NRSECS: EQU 26 ; SINGLE DEN
- NRSECS2: EQU 16 ; DOUBLE DEN
- TRKSIZE:EQU NRSECS2*512; SIZE OF A TRACK
- TRKSIZ1:EQU NRSECS*128
- XOR A
- LD (TRKIN),A
- LD (TRKOUT),A
- LD HL,($MEMRY); GET START OF BUFFER
- EX DE,HL; SAVE IN DE
- LD HL,(6); GET HIGHEST MEMORY ADDRESS
- SCF
- SBC HL,DE; CALCULATE AVAILABLE MEMORY
- LD DE,TRKSIZE; SIZE OF A TRACK
- LD C,DIVIDE
- CALL CDOS
- LD A,L
- LD (TRKSINMEM),A; SET MAX. NR OF TRACKS READABLE
- LD A,(FROM)
- AND NOT DBLDEN ; DISABLE DOUBLE DENSITY FOR HOME
- LD (CURR),A
- OUT DSKCNTRL,A; SELECT INPUT DISK
- LD D,NOTREADY+NOTFND+CRCERR+BUSY
- LD A,RESTORE; RESTORE DISK TO TRACK ZERO
- CALL EXECUTE
- LD A,(TO)
- AND NOT DBLDEN
- LD (CURR),A
- OUT DSKCNTRL,A
- LD D,NOTREADY+PROTECT+NOTFND+CRCERR+BUSY
- LD A,RESTORE
- CALL EXECUTE
- ; READ IN FIRST SECTOR TO SEE IF DOUBLE OR SINGLE DENSITY
- LD HL,($MEMRY)
- LD A,(FROM)
- AND NOT DBLDEN
- LD (CURR),A
- CALL SETUP
- ADD READ
- LD D,NOTREADY+NOTFND+CRCERR+LOSTDATA
- LD C,SECREG
- LD E,1
- OUT (C),E
- LD C,DATAREG
- OUT DSKCMD,A; START READING
- LOOP2:
- IN A,DSKFLGS; WAIT FOR DRQ OR EOJ
- RRA
- JR C,DENSREADY; EOJ FOUND?
- INI; PLACE NEXT BYTE AT (HL) AND UPDATE
- JR LOOP2; GET NEXT BYTE FROM SECTOR
- DENSREADY:
- IN A,DSKSTAT; GET STATUS AFTER SECTOR
- LD B,A
- AND D
- JP NZ,ERROR
- LD IX,($MEMRY)
- LD A,'L'
- CP (IX+78H)
- JR NZ,SINGLE
- LD A,'G'
- CP (IX+79H)
- JR NZ,SINGLE
- LD A,'S'
- CP (IX+7AH)
- JR NZ,SINGLE
- CP (IX+7BH)
- JR NZ,SINGLE
- LD A,'D'
- CP (IX+7CH)
- JR NZ,SINGLE
- CP (IX+7DH)
- JR NZ,SINGLE
- LD A,0FFH
- LD (DENSITY),A
- LD DE,DOUBLEDEN
- JR DENMESS
- SINGLE:
- XOR A
- LD (DENSITY),A
- LD DE,SINGLEDEN
- DENMESS:
- LD C,W.LINE
- CALL CDOS
- JR RESTART
- DOUBLEDEN: DB 'Double density transfer.',CR,LF,'$'
- SINGLEDEN: DB 'Single density transfer.',CR,LF,'$'
- RESTART:
- LD HL,($MEMRY)
- LD A,0
- LD (TRKCNT),A
- LD A,(DENSITY)
- OR A
- JR Z,SNGSKP1
- IN A,TRKREG
- OR A ; CHECK FOR TRACK 2 OR GREATER
- SNGSKP1: LD A,(FROM)
- JR NZ,DBLSKP1
- AND NOT DBLDEN
- DBLSKP1:
- LD (CURR),A
- CALL SETUP; PREPARE DISK FOR COMING OPERATION
- ADD READ; CONSTRUCT READ COMMAND
- RDTRACK:
- LD E,1; SECTOR COUNTER
- LD D,NOTREADY+NOTFND+CRCERR+LOSTDATA
- PUSH HL
- LD HL,RETRY
- LD (HL),0
- POP HL
- AGAIN:
- LD (HLSAVE),HL ;SAVE FOR RETRIES
- LD C,SECREG
- OUT (C),E
- LD C,DATAREG
- OUT DSKCMD,A; START READING
- AGAIN2:
- IN A,DSKFLGS; WAIT FOR DRQ OR EOJ
- RRA
- JR C,READREADY; EOJ FOUND?
- INI; PLACE NEXT BYTE AT (HL) AND UPDATE
- JR AGAIN2; GET NEXT BYTE FROM SECTOR
- READREADY:
- IN A,DSKSTAT; GET STATUS AFTER SECTOR
- LD B,A
- AND D
- JP NZ,RERROR
- LD A,E
- CP NRSECS
- JP Z,LSTSEC; LAST SECTOR OF TRACK INPUT
- LD A,(DENSITY)
- OR A
- JR Z,DBLSKP4
- IN A,TRKREG ; CHECK FOR DBLDEN
- OR A
- JR Z,DBLSKP4
- LD A,E
- CP NRSECS2
- JP Z,LSTSEC
- DBLSKP4: INC E
- RRETRY:
- LD A,(DENSITY)
- OR A
- JR Z,SNGSKP8
- IN A,TRKREG
- OR A ; CHECK FOR TRACK 2 OR GREATER
- SNGSKP8:
- LD A,(FROM)
- JR NZ,DBLSKP8
- AND NOT DBLDEN
- DBLSKP8:
- OR AUTOWAIT
- OUT DSKCNTRL,A
- LD A,READ
- JR AGAIN
- RERROR:
- LD A,(RETRY)
- CP MAXRETRY
- JP Z,ERROR
- INC A
- LD (RETRY),A
- PUSH DE
- PUSH BC
- LD A,B
- LD HL,RSTAT; SET ERROR OR STATUS BITS
- CALL BINH2
- IN A,TRKREG; GET TRACK-NUMBER
- LD HL,RTRK
- CALL BINH2
- IN A,SECREG; GET SECTOR-NUMBER
- LD HL,RSEC
- CALL BINH2
- LD DE,MESRETRY
- LD C,W.LINE
- CALL CDOS
- POP BC
- POP DE
- LD HL,(HLSAVE)
- JR RRETRY
- MESRETRY: DB 'Retry, Status = '
- RSTAT: DB ' , Track = '
- RTRK: DB ' , Sector = '
- RSEC: DB ' .',CR,LF,'$'
- LSTSEC:
- LD A,(TRKIN); DO IT FOR 77 TRACKS
- CP NRTRKS-1
- JP Z,WRTHEM
- INC A
- LD (TRKIN),A
- LD B,A
- DEC A
- CALL SEEKTRK; GO TO NEXT TRACK
- LD A,(TRKSINMEM)
- LD B,A
- LD A,(TRKCNT)
- INC A
- CP B
- JP Z,WRTHEM
- LD (TRKCNT),A
- LD A,(DENSITY)
- OR A
- JR Z,SNGSKPA
- IN A,TRKREG
- OR A ; CHECK FOR TRACK 2 OR GREATER
- SNGSKPA:
- LD A,(FROM)
- JR NZ,DBLSKPA
- AND NOT DBLDEN
- DBLSKPA:
- OR AUTOWAIT
- OUT DSKCNTRL,A
- LD A,READ
- JP RDTRACK
- WRTHEM:
- LD HL,($MEMRY)
- LD A,0
- LD (TRKCNT),A
- LD A,(SAMEDR); TEST IF ON SAME DUAL DRIVE IS INPUT
- OR A
- JR Z,DIFDR; NO
- LD A,(TRKOUT)
- LD B,A
- LD A,(TRKIN)
- CALL SEEKTRK; SEEK BACK TO WRITING POSITION
- DIFDR:
- LD A,(TRKOUT)
- OUT TRKREG,A
- LD A,(DENSITY)
- OR A
- JR Z,SNGSKP2
- IN A,TRKREG
- OR A ; CHECK FOR TRACK 2 OR GREATER
- SNGSKP2:
- LD A,(TO)
- JR NZ,DBLSKP2
- AND NOT DBLDEN
- DBLSKP2:
- LD (CURR),A
- CALL SETUP; PREPARE DISK FOR COMING OPERATION
- ADD WRITE; CONTRUCT WRITE COMMAND
- WRTRACK:
- LD E,1; SECTOR COUNTER
- LD D,NOTREADY+PROTECT+WRFAULT+NOTFND+CRCERR+LOSTDATA
- BACK:
- LD C,SECREG
- OUT (C),E
- LD C,DATAREG
- OUT DSKCMD,A; START WRITING
- BACK2:
- IN A,DSKFLGS; WAIT FOR DRQ OR EOJ
- RRA
- JR C,WRREADY; EOJ FOUND?
- OUTI; GET NEXT BYTE FROM (HL) AND UPDATE
- JR BACK2; WRITE NEXT BYTE TO SECTOR
- WRREADY:
- IN A,DSKSTAT; GET STATUS AFTER SECTOR
- LD B,A
- AND D
- JP NZ,ERROR
- LD A,E;
- CP NRSECS
- JR Z,VERIFY; LAST SECTOR OF TRACK WRITTEN
- LD A,(DENSITY)
- OR A
- JR Z,DBLSKP5
- IN A,TRKREG ; CHECK FOR DBLDEN
- OR A
- JR Z,DBLSKP5
- LD A,E
- CP NRSECS2
- JR Z,VERIFY
- DBLSKP5: INC E
- LD A,(DENSITY)
- OR A
- JR Z,SNGSKP9
- IN A,TRKREG
- OR A ; CHECK FOR TRACK 2 OR GREATER
- SNGSKP9:
- LD A,(TO)
- JR NZ,DBLSKP9
- AND NOT DBLDEN
- DBLSKP9:
- OR AUTOWAIT
- OUT DSKCNTRL,A
- LD A,WRITE
- JR BACK
- VERIFY:
- LD E,1; RESTART AT FIRST SECTOR
- LD D,NOTREADY+NOTFND+CRCERR+LOSTDATA
- BACK3:
- LD A,(DENSITY)
- OR A
- JR Z,SNGSKP3
- LD A,(TRKOUT)
- OR A ; CHECK FOR TRACK 2 OR GREATER
- SNGSKP3:
- LD A,(TO)
- JR NZ,DBLSKP3
- AND NOT DBLDEN
- DBLSKP3:
- OR AUTOWAIT
- OUT DSKCNTRL,A
- LD B,0FFH; SET ERROR CODE TO "VERIFY ERROR"
- LD C,SECREG
- OUT (C),E
- LD A,READ
- OUT DSKCMD,A; START READING
- BACK4:
- IN A,DSKFLGS; WAIT FOR DRQ OR EOJ
- RRA
- JR C,SECREAD; IF EOJ, SECTOR IS READ
- IN A,DATAREG; GET BYTE
- JR BACK4
- SECREAD:
- IN A,DSKSTAT; STATUS AFTER SECTOR READ
- LD B,A
- AND D
- JP NZ,ERROR
- LD A,E; LAST SECTOR OF TRACK?
- CP NRSECS
- JR Z,ENDVERIFY
- LD A,(DENSITY)
- OR A
- JR Z,DBLSKP6
- IN A,TRKREG ; CHECK FOR DBLDEN
- OR A
- JR Z,DBLSKP6
- LD A,E
- CP NRSECS2
- JR Z,ENDVERIFY
- DBLSKP6: INC E
- JR BACK3
- ENDVERIFY:
- LD A,(TRKOUT); DO IT FOR 77 TRACKS
- CP NRTRKS-1
- JP Z,TERM
- INC A
- LD (TRKOUT),A
- LD B,A
- DEC A
- CALL SEEKTRK; GO TO NEXT TRACK
- LD A,(TRKSINMEM); CHECK IF END OF MEMORY
- LD B,A
- LD A,(TRKCNT)
- INC A
- CP B
- JP Z,RESTART
- LD (TRKCNT),A
- LD A,(DENSITY)
- OR A
- JR Z,SNGSKPB
- IN A,TRKREG
- OR A
- SNGSKPB:
- LD A,(TO)
- JR NZ,DBLSKPB
- AND NOT DBLDEN
- DBLSKPB:
- OR AUTOWAIT
- OUT DSKCNTRL,A
- LD A,WRITE
- JP WRTRACK
- ;
- ;THIS SUBROUTINE IS USED AFTER SWITCH TO NEW DRIVE TO PREPARE IT
- ;FOR A NEW SEQUENCE OF READS OR WRITES
- ;
- SETUP:
- OUT DSKCNTRL,A
- LD B,A; READ/WRITE FROM FIRST SECTOR ONWARDS
- LD A,1;
- OUT SECREG,A
- IN A,DSKFLGS
- AND HEADLOAD; HEAD LOADED?
- LD C,A
- LD A,B
- OR A,AUTOWAIT; FOR NEXT COMMANDS USE AUTO WAIT MODE
- OUT DSKCNTRL,A
- LD A,C
- OR A; WAS HEAD LOADED?
- LD A,4
- RET Z; NO
- XOR A
- RET
- ;
- ;THIS SUBROUTINE EXECUTES "RESTORES" AND "SEEKS" (ERROR MASK IN REG.D)
- ;
- EXECUTE:
- OUT DSKCMD,A
- WAIT:
- IN A,DSKFLGS; CHECK IF READY
- RRA
- JR NC,WAIT
- IN A,DSKSTAT
- LD B,A
- AND D; COMPARE TO ERROR MASK
- JR NZ,ERROR
- RET
- ;
- ;THIS ROUTINE EXECUTES A FAST SEEK FROM (A) TO (B)
- ;
- SEEKTRK:
- OUT TRKREG,A; SET TO CURRENT TRACK
- LD A,B; GET REQUIRED TRACK-NR
- OUT DATAREG,A; GIVE DESIRED TRACK TO 4FDC
- LD A,FASTSEEK; SET TO FAST SEEK
- OUT AUXDSK,A
- LD A,SEEK;
- LD D,NOTREADY
- CALL EXECUTE
- REDO2: IN A,AUXDSK; SEEK COMPLETED?
- AND SEEKCOMP
- JR NZ,REDO2
- LD A,RESETFST; RESET FAST SEEK MODE
- OUT AUXDSK,A
- RET
- ;
- ;THIS HANDLES ANY ERROR AND TERMINATES THE PROGRAM WITH AN APPROPRIATE
- ;ERROR MESSAGE
- ;
- ERROR:
- PUSH BC; SAVE ERROR STATUS
- LD A,B
- LD HL,ERSTAT; SET ERROR OR STATUS BITS
- CALL BINH2
- IN A,TRKREG; GET TRACK-NUMBER
- LD HL,TRK
- CALL BINH2
- IN A,SECREG; GET SECTOR-NUMBER
- LD HL,SEC
- CALL BINH2
- LD A,RESET; RESET ANY CURRENT COMMAND
- OUT DSKCMD,A
- LD A,(CURR)
- AND 0FH
- LD B,1
- RRA: RRA ; FIND OUT DEVICE NAME
- JR C,DEVFND
- INC B
- JR RRA
- DEVFND: LD A,B
- ADD 40H
- LD (DEV),A
- LD DE,ERMSG
- LD C,W.LINE
- CALL CDOS
- POP BC; RESTORE ERROR FLAG
- LD A,B
- LD DE,VERFERR
- CP 0FFH
- JR Z,ERTERM; ERROR FOUND IN VERIFICATION
- LD DE,IOERR
- AND NOTFND+CRCERR
- JR NZ,ERTERM; REAL READ OR WRITE ERROR
- LD A,B
- LD DE,READYERR
- AND NOTREADY
- JR NZ,ERTERM; DRIVE IS NOT READY
- LD A,B
- LD DE,PROTERR
- AND PROTECT
- JR NZ,ERTERM; FLOPPY IS WRITE PROTECTED
- LD A,B
- LD DE,WRERR
- AND WRFAULT
- JR NZ,ERTERM; I/O ERROR ON WRITING
- LD DE,UNKNERR; STRANGE ERROR
- ERTERM:
- LD C,W.LINE; PREPARE FOR WRITE MESSAGE
- CALL CDOS
- LD DE,ERMSG2
- CALL CDOS
- JP TERM2
- VERFERR:DB '(DATA READ BACK UNEQUAL TO DATA WRITTEN)$'
- IOERR: DB '(DATA ERROR WHEN READING OR WRITING)$'
- READYERR: DB '(DRIVE NOT READY: MAKE READY AND RETRY)$'
- PROTERR:DB '(FLOPPY IS WRITE PROTECTED)$'
- WRERR: DB '(DATA ERROR WHEN WRITING: RE-INITIALIZE FLOPPY)$'
- UNKNERR:DB '(UNIDENTIFIABLE PROBLEM)$'
- ERMSG: DB BEL,BEL,BEL,'ERROR ',BEL,BEL,'ON DRIVE ',BEL,BEL,BEL
- DEV: DB ' , AT TRACK '
- TRK: DB ' , SECTOR '
- SEC: DB ' ,',LF,CR,'STATUS='
- ERSTAT: DB ' $'
- ERMSG2: DB '.',LF,CR,'PROGRAM PREMATURELY TERMINATED.$'
- TRMMSG: DB 'FAST COPY OPERATION SUCCEEDED. FLOPPY WRITTEN AND VERIFIED.$'
- ;
- ;THIS TERMINATES THE PROGRAM AFTER RESTORING THE "CURRENT DISK" SELECTION
- ;
- TERM:
- LD C,W.LINE
- LD DE,TRMMSG
- CALL CDOS
- TERM2:
- LD C,C.DISK; GET CURRENT DRIVE
- CALL CDOS
- LD E,A
- LD C,RES.CDOS; RESET CDOS AND LOG OFF ALL DISKS
- CALL CDOS
- LD C,SEL.DISK; RESTORE CURRENT DISK SELECTION
- CALL CDOS
- JP 100H
- END XEROX
-