home *** CD-ROM | disk | FTP | other *** search
- .PAGE 96
- .TITLE 'FFC - FAST DISK DUPLICATION PROGRAM'
- .SBTTL 'EQUATES'
- .PREL
- .PHEX
- ; W EARNEST MOD 4/03/82
- ; 5/14/82 ADD FORMAT CODE
- ; 9/1/82 CHANGE STEP AND SKEW FOR NEW DRIVES
- ; 1/16/83 FIX REFORM FLAG BUG
- ; 2/11/83 FIX STOP TEST BUG
- ; 7/29/83 MOD DRIVE RDY TEST
- ; FOR BIGBOARD SYSTEM DATA ONLY COPY
- VER = 1
- REV = 5
- .PROGID FFC,VER,REV
- ;
- ; BIOS ENTRY POINT OFFSETS
- ;
- CONSTA = 06H ;CONSOLE STATUS (A=0, NO DATA)
- CONIN = 09H ;CONSOLE INPUT (INTO A)
- CONOUT = 0CH ;CONSOLE OUTPUT (FROM C)
- SELDSK = 1BH ;SELECT DISK (FROM C, 0..1)
- SETTRK = 1EH ;SET TRACK (FROM C, 0..76)
- SETSEC = 21H ;SET SECTOR (FROM C, 1..26)
- SETDMA = 24H ;SET DMA ADDRESS (FROM BC)
- READ = 27H ;READ SECTOR INTO DMA BUFFER
- WRITE = 2AH ;WRITE SECTOR FROM DMA BUFFER
- ;
- DISK = 10H ;DISK BASE ADDR
- DCOM = DISK ;DISK COMMAND PORT
- STATP = DISK ;DISK STATUS PORT
- TRACK = DISK+1 ;DISK TRACK COMMAND
- SECTP = DISK+2 ;DISK SECTOR PORT
- DDATA = DISK+3 ;DISK DATA PORT
- ROMSEL = 0F01BH ;FERGUSON SELECT SUBR.
- NMIVEC = 066H ;NMI ADDRESS
- STEP = 1 ;STEPPING RATE 2=10 MSEC,1=6 MSEC
- LF = 0AH ;LINE FEED
- CR = 0DH ;CARRIAGE RETURN
- BELL = 07H ;BELL
- ;
- FCB = 5CH
- BOOT = 0000H
- BDOS = 5
- NBPT = 128*26
- SKEW = 7
- DRVI = 0 ;DRIVE A INPUT
- DRVO = 1 ;DRIVE B OUTPUT
- ;
- .SBTTL 'MAIN COPY ROUTINE'
- START: LXI SP,STACK+64
- XRA A
- STA RFORM
- ;
- ; PRINT HEADING
- ;
- NEXTC: LXI H,STR1
- CALL WASC
- CALL CRCK
- REDO: MVI A,2 ;START TRACK
- STA TRKI
- STA TRKO
- STA TRKV
- MVI A,77
- STA STPTRK ;DEFAULT FULL DISK
- MVI A,5 ;NR OF PASSES
- STA PASCNT
- ;
- ; BEGIN MAIN LOOP
- ;
- CALL CRLF
- MVI A,10 ;RETRYS ALLOWED
- STA ERCNT
- COPY1: MVI C,DRVI
- MVI E,SELDSK
- CALL BIOSC
- CALL DRDYTS
- JRNZ COPY1
- MVI A,'R'
- STA RWCHR
- CALL INIPAS
- COPY2: LHLD PTR ;READ NEXT N TRACKS
- LDA TRKI
- CALL WSTS
- CALL RDTRK
- CALL CKEMT
- JRNZ ..A ;THIS TRACK HAS DATA
- LDA TRKI
- STA STPTRK ;MARK IT AS TOO FAR
- JMPR COPY2A
- ..A: CALL INCSEC
- LDA TRKI
- INR A
- STA TRKI
- LDA TRKCNT
- DCR A
- STA TRKCNT
- JRNZ COPY2
- ;
- COPY2A: MVI C,DRVO
- MVI E,SELDSK
- CALL BIOSC
- CALL DRDYTS
- JRNZ COPY2A
- MVI A,'W'
- STA RWCHR
- CALL INIPAS
- COPY3: LHLD PTR ;WRITE NEXT N TRACKS
- LDA TRKO
- CALL WSTS
- CALL WRTRK
- CALL INCSEC
- LDA TRKO
- INR A
- STA TRKO
- MOV L,A ;HOLD NEXT TRACK
- LDA STPTRK
- SUB L ;THERE YET?
- JRZ COPY4 ;TIME TO STOP, FOUND EMPTY
- JM COPY4 ;IN CASE OVERSHOOT
- LDA TRKCNT
- DCR A
- STA TRKCNT
- JRNZ COPY3
- ;
- LDA PASCNT
- DCR A
- STA PASCNT
- JNZ COPY1 ;LOOP UNTIL ALL PASSES DONE
- ;
- COPY4: LXI H,STR5 ;PRINT 'COPY COMPLETE'
- CALL WASC
- JMP START ;RESTART IT, CLEAN FLAGS
- ;
- INIPAS: LXI H,TRKBUF
- SHLD PTR
- MVI A,15 ;TRKCNT = NUMBER OF TRACKS PER PASS
- STA TRKCNT
- MVI A,1
- STA STSECT
- RET
- ;
- INCSEC: LHLD PTR
- LXI D,NBPT
- DAD D
- SHLD PTR
- LDA STSECT
- ADI SKEW
- CPI 27
- JRC ..A
- SUI 26
- ..A: STA STSECT
- RET
- .SBTTL 'READ/WRITE ROUTINES'
- ;
- ; RDTRK - READ ABSOLUTE TRACK INTO MEMORY
- ;
- ; ENTRY CONDITIONS
- ; HL........FWA OF AREA TO READ TRACK INTO
- ; A.........TRACK NUMBER (0 TO 76)
- ;
- RDTRK: PUSH D
- PUSH H
- CALL INIRW
- RTRK0: MVI B,26 ;SECTOR COUNTER
- LDA STSECT ;INITIAL SECTOR #
- MOV C,A ;SECTOR NR IN C
- RDTRK1: PUSH B
- CALL INISEC
- MVI E,READ
- CALL BIOSC ;READ A SECTOR
- ORA A ;OK?
- JNZ RERR ;NO GOOD
- CALL INCPTR
- POP B
- CALL SECINC
- NOWRP3: DJNZ RDTRK1
- POP H
- POP D
- RET
- ;
- RERR: POP B ;CLEAN STACK
- LXI H,RERCT
- DCR M
- JZ HERR ;HARD ERROR
- LHLD HLDDMA
- SHLD DMAPTR ;RESET IT
- JMP RTRK0
- ;
- INIRW: SHLD DMAPTR
- SHLD HLDDMA
- MOV C,A
- MVI E,SETTRK
- CALL BIOSC
- MVI A,5
- STA RERCT
- RET
- ;
- INISEC: MVI E,SETSEC
- CALL BIOSC
- LBCD DMAPTR
- MVI E,SETDMA
- JMP BIOSC
- ;
- INCPTR: LHLD DMAPTR
- LXI D,80H
- DAD D
- SHLD DMAPTR ;UPDATE POINTER
- RET
- ;
- SECINC: INR C
- MOV A,C
- CPI 27
- RC
- SUI 26
- MOV C,A
- RET
- ;
- ; WRTRK - WRITE ABSOLUTE TRACK FROM MEMORY
- ;
- ; ENTRY CONDITIONS
- ; HL........FWA OF AREA TO WRITE TRACK FROM
- ; A.........TRACK NUMBER (0 TO 76)
- ;
- WRTRK: PUSH D
- PUSH H
- CALL INIRW
- RWRTRK: LDA STSECT ;INITIAL SECTOR #
- MOV C,A
- MVI B,26 ;SECTOR COUNT
- WRTRK1: PUSH B
- CALL INISEC
- MVI E,WRITE
- CALL BIOSC
- ORA A
- JNZ WERR
- CALL INCPTR
- POP B
- CALL SECINC
- NOWRP4: DJNZ WRTRK1
- ;
- LXI H,VBUF
- SHLD DMAPTR
- LDA STSECT
- MOV C,A
- MVI B,26
- VTRK1: PUSH B
- CALL INISEC
- MVI E,READ
- CALL BIOSC
- ORA A
- JNZ VERR
- CALL INCPTR
- POP B
- CALL SECINC
- NOWRP5: DJNZ VTRK1
- POP H
- POP D
- RET
- ;
- VERR: POP B ;CLEAN UP STACK
- LXI H,ERCNT
- DCR M
- LXI H,STR7 ;DEST ERR, SOFT?
- JZ XERR
- POP H ;RECOV BUFFER ADDR AT START
- PUSH H
- SHLD DMAPTR
- JMP RWRTRK
- ;
- WERR: POP B
- LXI H,RERCT
- DCR M
- LXI H,STR4
- JRZ XERR ;WRITE ERROR, MAYBE SOFT
- LHLD HLDDMA
- SHLD DMAPTR
- JMP RWRTRK ;TRY WRITE AGAIN
- ;
- HERR: LXI H,STR3 ;HARD SOURCE ERROR MESSAGE
- JMP ERRC
- ;
- XERR: CALL WASC ;REPORT DEST ERR
- LDA RFORM ;HISTORY
- ORA A
- JNZ ERR ;HARD ERROR
- POP B
- DCR A
- STA RFORM ;NARK FORMAT NOW
- LXI H,STR6
- CALL WASC
- CALL FORMT ;REFORMAT THE DEST
- JMP REDO
- ;
- ERR: LXI H,STR2 ;HARD DEST ERROR
- ERRC: CALL WASC
- JMP START
- ;
- ; WASC - WRITE ASCII STRING TO CONSOLE
- ;
- WASC: MOV A,M
- ORA A
- RZ
- CALL WACC
- INX H
- JMPR WASC
- ;
- ; CRLF - WRITE END OF LINE TO CONSOLE
- ;
- CRLF: MVI A,CR
- CALL WACC
- MVI A,LF
- ;
- ; WACC - WRITE ASCII CHARACTER TO CONSOLE
- ;
- WACC: PUSH H
- PUSH D
- PUSH B
- MOV C,A
- MVI E,CONOUT
- CALL BIOSC
- POP B
- POP D
- POP H
- RET
- ;
- ; RACC - READ ASCII CHARACTER FROM CONSOLE
- ;
- RACC: PUSH H
- PUSH D
- PUSH B
- KBLP: CALL CONSTT
- ORA A
- JRZ KBLP ;WAIT FOR SOMETHING
- MVI E,CONIN
- CALL BIOSC
- ANI 7FH
- POP B
- POP D
- POP H
- RET
- ;
- CONSTT: MVI A,30 ;HALF MIN
- STA 0FF6CH ;KEEP DISK MOTORS ON
- MVI E,CONSTA
- CALL BIOSC
- RET
- ;
- ; CRCK - TEST FOR CR INPUT
- ;
- CRCK: CALL RACC
- CPI 0DH
- RZ
- CPI 3
- JZ BOOT
- CPI 60H
- JRC ..A
- ANI 5FH
- ..A: CPI 'F'
- JRNZ CRCK
- CALL FORMT
- JMP START
- ;
- WSTS: PUSH PSW
- MVI A,0DH ;CR
- CALL WACC
- LDA RWCHR
- CALL WACC
- MVI A,' '
- CALL WACC
- POP PSW
- PUSH PSW
- CALL HXBYT
- POP PSW
- RET
- ;
- HXBYT: PUSH PSW
- RAR
- RAR
- RAR
- RAR
- CALL HOUT
- POP PSW
- HOUT: ANI 0FH
- ADI 90H
- DAA
- ACI 40H
- DAA
- JMP WACC
- ;
- BIOSC: MVI D,0 ;FORCE LOW
- LXI H,0EA00H ;BIOS START ADDR
- DAD D ;CALC ADDR
- PCHL ;DO CALL
- ;
- DRDYTS: IN DISK
- BIT 7,A
- RZ ;DRIVE IS READY
- DRDYLP: IN DISK
- CMA
- BIT 7,A
- RNZ ;DRIVE IS READY
- CALL CONSTT
- ORA A
- JRZ DRDYLP ;WAIT FOR SOMETHING
- MVI E,CONIN
- CALL BIOSC
- ANI 7FH
- CPI 'C'-40H
- JZ START ;ABORT IT
- JMP DRDYLP ;TEST AGAIN
- ;
- CKEMT: PUSH H
- PUSH B
- LHLD HLDDMA ;DATA START
- LXI B,26*128 ;AMOUNT OF DATA
- EMTLP: MOV A,M
- CPI 0E5H ;NULL PATTERN
- JRNZ ..A ;NOT EMPTY
- INX H
- DCX B
- MOV A,B
- ORA C
- JRNZ EMTLP
- ..A: POP B
- POP H
- RET
- ;
- FORMT: DI ;NO INTERRUPTS BUT NMI (NO CLOCK)
- LXI H,26
- SHLD FSECT ;DEFINE # SECTORS & FIRST TRK
- MVI C,1
- CALL ROMSEL
- CALL HOME
- CALL DOFORM
- ENDFIL: CALL HOME
- MVI C,0
- CALL ROMSEL
- EI ;INTERRUPTS OK NOW
- JMP CRLF ;BACK TO MENU
- ;
- ; DISK FORMATTING ROUTINES.
- ;
- DOFORM: LXI H,TRKBUF ;POINT TO TRACK BUFFER
- MVI A,'F'
- STA RWCHR
- XRA A
- CALL WSTS
- CALL INDX
- DOF1: CALL ADDR
- CALL DATA
- LDA FSECT
- DCR A ;DECR SECTOR COUNT
- STA FSECT
- JNZ DOF1
- CALL FILBUF ;FILL END OF BUFFER WITH FF'S
- LXI D,TRKBUF
- ORA A
- DSBC D ;CALC SIZE OF BUFFER BUILT
- INR H ;ADJUST FOR FIRST DCR
- SHLD CNTSAV ;NEED MORE THAN ONCE
- LXI H,NMWCOD
- LXI B,NMWEND-NMWCOD
- LXI D,NMIVEC
- LDIR
- ;
- DOF4: LXI H,TRKBUF ;POINT TO FORMAT BUFFER
- CALL FILADR ;PLACE TRACK AND SECTOR NRS IN BUFF
- LXI H,TRKBUF ;POINT TO TRACK BUFFER
- LXI B,DDATA ;DATA PORT FOR OUTI,CLEAR B
- LDED CNTSAV ;REALLY JUST D REG
- IN STATP ;CLEAR ANY LEFTOVER FLAGS
- MVI A,0F4H ;TRACK WRITE COMMAND
- CALL CMDOUT ;START & KILL SOME TIME
- ;
- DOF7: HLT ;WAIT FOR INTERRUPT
- JMP DOF7 ;LOOP TILL ALL DONE
- ;
- TRKDUN: CALL BUSY ;MAKE SURE SHUT DOWN
- ANI 0FFH ;TEST IT
- JNZ ERRMSG ;ERROR HERE, DIDNT WORK
- LDA TRK ;TRACK NO
- INR A ;INCREMENT IT
- STA TRK
- CPI 77 ;PAST LAST TRK?
- RZ ;IF DONE ALL TRACKS
- CALL WSTS
- MVI A,58H+STEP ;STEP COMMAND,NO VERIF
- CALL WTCMD ;ISSUE IT
- JMP DOF4
- ;
- WTCMD: CALL CMDOUT ;EXECUTE & FALL THRU
- ;
- BUSY: IN STATP ;TEST 1771 BUSY
- BIT 0,A
- JNZ BUSY ;LOOP TILL FINISHED
- RET
- ;
- CMDOUT: OUT DCOM ;ISSUE COMMAND
- PAUSE: XTHL
- XTHL
- RET
- ;
- ; INDX - INDEX BLOCK FOR IBM FORMATS (NOT REQUIRED FOR 1771)
- ; 73 IN MEM, 73 ON DSK
- ;
- INDX: LXI B,40<8+0FFH ;40 COUNT,ONES BYTE
- CALL MOVEIT ;STORE THE BLOCK
- LXI B,6<8+0 ;COUNT 6, ZERO DATA
- CALL MOVEIT ;STORE THE BLOCK
- MVI M,0FCH ;INDEX MARK
- INX H ;INCR POINTER
- LXI B,26<8+0FFH ;NOW 26 MORE FF'S
- JMP MOVEIT ;STORE THE BLOCK
- ;
- ; ADDR - ADDRESS BLOCK 12 IN MEM, 13 ON DSK
- ;
- ADDR: LXI B,6<8+0 ;WRITE 6 ZEROS
- CALL MOVEIT
- MVI M,0FEH ;ID ADDRESS MARK
- INX H
- MVI B,4 ;TRACK AND SECTOR ZERO INITIALLY
- CALL MOVEIT
- MVI M,0F7H ;WRITE 2 CRC'S
- INX H
- RET
- ;
- ; DATA - WRITE DATA BLOCK FILLED WITH E5'S
- ; 180 IN MEM, 181 ON DSK
- DATA: LXI B,11<8+0FFH ;WRITE 11 FF'S
- CALL MOVEIT
- LXI B,6<8+0 ;NOW 6 ZEROS
- CALL MOVEIT
- MVI M,0FBH ;DATA ADDRESS MARK
- INX H
- LXI B,128<8+0E5H ;DATA FILL CHARACTER
- CALL MOVEIT
- MVI M,0F7H ;WRITE 2 CRC'S
- INX H
- LXI B,33<8+0FFH ;INTERRECORD GAP, FALL THRU
- ;
- ; MOVEIT ROUTINE HL --> MEMORY, DE = COUNT, B CONTAINS BYTE
- ;
- MOVEIT: MOV M,C ;STORE BYTE
- INX H
- DJNZ MOVEIT
- RET
- ;
- ; FILADR - FILL IN TRACK AND SECTOR NUMBERS
- ;
- FILADR: LXI B,26*256+1
- LXI D,190 ;FILL ADDR OFFSET (180+12)-2
- LXI H,TRKBUF+80 ;LOCATION OF FIRST TRACK NUMBER
- FIL01: LDA TRK ;TRACK NO
- MOV M,A ;TO BUFFER
- INX H
- INX H ;POINT TO SECTOR
- MOV M,C ;SECTOR NUMBER TO BUFFER
- DAD D ;INCR BUFFER POINTER
- INR C ;INCR SECTOR MAP NUMBER
- DJNZ FIL01
- RET
- ;
- ; FILBUF - FILL END OF TRACK WITH FF'S
- ;
- FILBUF: LXI D,1024 ;END OF TRACK FILL
- MVI C,0FFH ;FILL CHAR
- ET1: MOV M,C
- INX H
- DCX D ;DECR COUNT
- MOV A,D
- ORA E
- JNZ ET1
- RET
- ;
- ; ERROR ROUTINE
- ;
- ERRMSG: JMP ENDFIL
- ;
- ; HOME SELECTED DRIVE
- ;
- HOME: IN STATP ;CHECK IF BUSY
- RRC
- JC HOME
- MVI A,0+STEP ;HOME COMMAND
- CALL WTCMD ;ISSUE COMMAND, WAIT TILL NOT BUSY
- IN STATP ;READ DISK STATUS
- ANI 4 ;CHECK TRACK ZERO FLAG
- RNZ
- ;
- HOMERR: JMP ENDFIL ;EXIT
- ;
- NMWCOD: OUTI
- RNZ
- DCR D
- RNZ
- POP D
- JMP TRKDUN
- NMWEND = .
- ;
- ; STRING DATA
- ;
- STR1: .ASCII 'Fast Disk Duplicator Utility'
- .ASCII ' V '[VER+'0']'.'[REV+'0']' '
- .DATE
- .BYTE CR,LF
- .ASCII 'Source in Drive 0(A), Blank in Drive 1(B)'[CR][LF]
- .ASCII 'Press RETURN to copy, "F" to format,'[CR][LF]
- .ASCIZ 'Ctrl-C to Exit.'[CR][LF]
- STR2: .ASCIZ ' error, Disk Unsalvagable, Aborting'[BELL][CR][LF]
- STR3: .ASCIZ [CR][LF][BELL]'HARD Error on Source disk, Aborting'[CR][LF]
- STR4: .ASCIZ [CR][LF]'Write'
- STR5: .ASCIZ [CR][LF]'COPY COMPLETE'[BELL][CR][LF][LF]
- STR6: .ASCIZ [BELL]' error, Attempting reformat'[CR][LF]
- STR7: .ASCII [CR][LF]'Verification'
- ;
- .LOC .DATA.
- ;
- TRKNO: .BLKB 1 ;TRACK NUMBER
- DMAPTR: .BLKW 1 ;DMA POINTER
- HLDDMA: .BLKW 1 ;DMA HOLD FOR RETRY
- CNTSAV: .BLKW 1 ;D REG SAVE OF BUFFER SIZE CNT
- FSECT: .BLKB 1 ;SECTOR COUNT USED IN FORMATTING
- TRK: .BLKB 1 ;TRACK NUMBER USED IN FORMATTING DISK
- ;
- PTR: .BLKW 1
- VPTR: .BLKW 1
- TRKI: .BLKB 1 ;INPUT TRACK NUMBER
- TRKO: .BLKB 1 ;OUTPUT TRACK NUMBER
- TRKV: .BLKB 1 ;VERIFY TRACK NUMBER
- STPTRK: .BLKB 1
- RFORM: .BLKB 1
- RWCHR: .BLKB 1 ;R OR W FOR STATUS
- ERCNT: .BLKB 1 ;ERROR COUNTER
- RERCT: .BLKB 1 ;RETRY COUNTER
- PASCNT: .BLKB 1 ;PASS COUNT
- TRKCNT: .BLKB 1 ;TRACK COUNT
- STSECT: .BLKB 1 ;STARTING SECTOR
- STACK: .BLKW 32
- VBUF: .BLKB 26*128
- TRKBUF = .
- ;
- .END START
-