home *** CD-ROM | disk | FTP | other *** search
- ; -- DFOCO --
- ;
- ; BY S. J. SINGER
- ; 10 NOV 1979
- ;
- TRUE: EQU 0FFH
- FALSE: EQU 00H
- ;
- PERSCI: EQU FALSE ;CONDITIONAL ASSEMBLY SWITCH FOR FAST SEEK
- ; ;PERSCI DRIVES (SET TRUE 0FFH FOR PERSCI)
- DELTA: EQU FALSE ;CONDITIONAL SWITCH FOR DELTA CONTROLLER
- TARBELL:EQU FALSE ;CONDITIONAL SWITCH FOR NEW TARBELL DOUBLE
- ; ;DENSITY CONTROLLER
- ;
- ; (SET BOTH DELTA AND TARBELL FALSE FOR OLD TARBELL CONTROLLER)
- ;
- DUAL: EQU FALSE ;CONDITIONAL SWITCH FOR DUAL DRIVES
- STEP: EQU 1 ;STEPPING RATE 1=6 MSEC, 2=10 MSEC, 3=20 MSEC
- ; (0=3 MSEC, 1=6 MSEC, 2=10 MSEC, 3=15 MSEC 1791)
- ; (USE STEP = 6 FOR PERSCI DRIVES)
- ;
- MACLIB MACRO ;INCLUDE SYSTEM MACROS
- ORG 100H
- LXI H,0
- DAD SP ;GET STACK POINTER
- SHLD OLDSTK
- LXI SP,NEWSTK ;SET UP NEW STACK
- LXI H,TRKTBL ;POINT TO TRACK TABLE
- MVI B,4
- ST2: MOV M,A ;STORE IN TABLE
- INX H
- DCR B
- JNZ ST2 ;SET 4 TRACK LOCATIONS
- DISKIO ?DRIVE ;GET CURRENTLY LOGGED DRIVE NO
- STA DRIVE ;SAVE IT
- STA DRVNO ;SELECTED DRIVE
- STA NEWDRV ;ALSO SAVE IN NEW DRIVE NO
- IF NOT DUAL
- LXI H,TRKTBL ;POINT TO TRACK TABLE
- MVI D,0
- MOV E,A ;DRIVE NO
- DAD D
- IN TRACK ;GET TRACK FROM 1771
- MOV M,A ;STORE IT IN TABLE
- ENDIF
- LDA 81H ;CONSOLE INPUT ALREADY HERE ?
- ORA A
- JZ SIGNON ;BUFFER EMPTY, INPUT FROM CONSOLE
- LDA 80H ;GET NO OF CHAR INPUT
- ORI 80H ;ADD 128
- MOV L,A
- XRA A
- MOV H,A ;HL CONTAINS ADDR OF END OF BUFFER
- ZBFF: INR L
- JZ START ;REMAINDER OF BUFFER ZEROED
- MOV M,A
- JMP ZBFF ;LOOP
- SIGNON: PRINT <CR,LF,' - DFOCO -',CR,LF>
- PRINT <'CP/M FAST FORMAT-COPY UTILITY',CR,LF>
- PRINT <'COPYRIGHT NOV 1979 BY S J SINGER',CR,LF>
- NEWIN: PRINT <CR,LF,'*'>
- MVI A,0FFH ;SET SWITCH TO RETURN HERE AGAIN
- STA INFLAG
- LXI SP,NEWSTK ;RESET STACK POINTER
- FILL 80H,0FFH ;ZERO INPUT BUFFER
- INPUT 80H ;READ FILE NAME
- ;
- ; SEARCH INPUT BUFFER FOR INITIAL COMMAND STRING
- ;
- START: MVI A,10
- STA RETRYS ;SET DEFAULT READ OR WRITE RETRYS TO 10
- XRA A
- STA VALFLG ;SET OTHER DEFAULTS
- STA VERFLG
- STA NOFILL
- STA DDFLG ;SINGLE DENSITY
- STA FORMSW ;RESET PROGRAM SWITCHES TO FALSE
- STA OFFSET ;SET OFFSET TO ZERO
- STA SECSIZ ;DEFAULT TO IBM STANDARD FORMAT
- STA CODE ;SPECIAL PASCAL FLAG CODE T 0 S 1 B 128
- MVI A,26
- STA NUMSEC ;NUMBER OF SECTORS
- INR A
- STA GAP ;FORMAT ADDR LEADER GAP
- MVI A,13
- STA DGAP ;GAP FOR MFM
- MVI A,51
- STA DNUMSEC ;NUMBER OF SECTORS (MFM)
- LXI H,183
- SHLD FILOFF ;FILL OFFSET (FM)
- LXI H,195
- SHLD DFILOFF ;FILL OFFSET (MFM)
- LXI H,128
- SHLD BYTES ;128 BYTES PER SECTOR
- LDA 'S'
- CALL DENSEL ;DEFAULT IS SINGLE DENSITY
- MVI A,0DDH
- STA DENCODE ;DEFAULT DOUBLE DENSITY CODE (SINGLE SIDE)
- LXI H,SECMAP0 ;STANDARD MAP TRACK 0
- CALL STDMAP
- FILL SECMAP,SECMAP+104
- INSTR 82H,40H,'NOVAL' ;CHECK FOR VALIDATION OFF
- JNC START0
- MVI A,0FFH
- STA VALFLG ;SET SWITCH
- START0: INSTR 82H,40H,'RETRY' ;CHANGE DEFAULT?
- JNC START2
- CALL GETNUM ;GET RETRYS
- ORA A
- JNZ START1
- INR A ;NO ZERO RETRYS
- START1: STA RETRYS ;SAVE IT
- START2: INSTR 82H,40H,'SIZE'
- CC SIZE
- INSTR 82H,40H,'4D' ;"QUAD" DISK ?
- JNC START2A
- MVI A,4DH ;QUAD CODE
- STA DENCODE
- JMP START2B
- START2A:INSTR 82H,40H,'DD'
- JNC STARTX
- START2B:MVI A,0FFH
- STA DDFLG ;SET DOUBLE DENSITY FLAG
- STARTX: INSTR 82H,40H,'MAP'
- JC MAP
- INSTR 82H,40H,'DCOPY' ;COPY DOUBLE DENSITY?
- JC DCOPY
- INSTR 82H,40H,'COPY' ;COPY A DISK?
- JC COPY
- INSTR 82H,40H,'DFORM'
- JC DFORMAT ;DOUBLE DENSITY FORMAT
- INSTR 82H,40H,'FORM'
- JC FORMAT ;SEARCH FOR FORMAT
- INSTR 82H,40H,'DVALID' ;VALIDATE DOUBLE DENSITY
- JC DVALID
- INSTR 82H,40H,'VALID' ;VALIDATE DISK?
- JC VALID
- JMP NEWIN
- ;
- ; COPY WILL COPY A DISK FROM ONE DRIVE TO ANOTHER AS QUICKLY AS POSSIBLE
- ; THE PROGRAM WILL READ THE FORMAT FROM TRACK 2 OF BOTH DISKS TO OPTIMIZE
- ; THE COPY OPERATION. ALL OF THE AVAILABLE MEMORY BETWEEN THE END OF FOCO
- ; AND THE BEGINNING OF CP/M WILL BE USED BY COPY.
- ;
- DCOPY: MVI A,0FFH
- STA DDFLG ;SET DOUBLE DENSITY FLAG
- ;
- COPY: LHLD 6 ;POINTS TO TOP OF MEMORY
- LXI D,TRKBUF ;END OF PROGRAM
- CALL DBLSUB ;SUBTRACT DE FROM HL
- MVI C,0 ;ZERO TRACK COUNT
- XCHG
- IF DELTA OR TARBELL
- MVI A,6+STEP ;SECTOR OFFSET
- ELSE
- MVI A,5+STEP
- ENDIF
- STA CPYOFF ;SAVE FOR LATER
- LXI H,128*26 ;MAX BYTES PER TRACK
- LDA SECSIZ ;SECTOR SIZE CODE
- ORA A ;IF 128 THEN SECSIZ=0
- JZ C1
- LXI H,512*8 ;MAX BYTES PER TRACK
- C1: LDA DDFLG ;DENSITY FLAG
- ORA A
- JZ C1A
- DAD H ;DOUBLE IT (512*16)
- LDA SECSIZ ;SECTOR SIZE CODE
- CPI 2
- JZ C1A
- LXI H,51*128 ;128 BYTE SECTORS?
- ORA A
- JZ C1A
- LXI H,26*256 ;MUST BE 256 BYTE SECTORS THEN
- C1A: SHLD TRKSIZE ;SAVE IT
- XCHG
- C2: CALL DBLSUB ;SUBTRACT
- JC C4 ;EXIT ON CARRY
- INR C ;INCR TRACK COUNT
- JMP C2 ;LOOP TILL HL GOES MINUS
- C4: MOV A,C ;TRACK LIMIT
- STA TRKLIM ;TRACKS THAT CAN BE READ ON ONE PASS
- LDA DDFLG ;DENSITY SWITCH
- ORA A
- JZ C4A
- MVI A,'D'
- CALL DENSEL ;SELECT DOUBLE DENSITY
- LDA CPYOFF ;SECTOR OFFSET FOR COPY
- ADD A ;DOUBLE IT FOR DOUBLE DENSITY
- STA CPYOFF
- C4A: XRA A
- STA SOURCE ;DEFAULT SOURCE DISK 'A:'
- STA VERFLG ;DEFAULT VERIFICATION ON
- INR A
- STA DEST ;DEFAULT DEST DISK 'B:'
- LXI H,SECMAP
- MVI A,'W' ;READ WRITE MAPPING FOR 51 SECTORS
- CALL STDMAP ;DEFAULT STD SECTOR MAP FOR A:
- LXI H,SECMAP1
- MVI A,'W' ;READ WRITE MAPPING FOR 51 SECTORS
- CALL STDMAP ;DEFAULT STD SECTOR MAP FOR B:
- INSTR 82H,40H,'NOFILL';NO FILL WITH E5 REQUEST
- JNC C5
- MVI A,0FFH
- STA NOFILL ;SET SWITCH
- C5: INSTR 82H,40H,'NOVER' ;NO VERIFICATION REQUEST
- JNC C6
- MVI A,0FFH
- STA VERFLG ;SET FLAG FOR NO VERIFICATION
- C6: INSTR 82H,40H,'FORM'
- JNC C7
- MVI A,0FFH
- STA FORMSW ;SET FORMAT SWITCH
- C7: CALL GETRK ;GET TRACK SPECIFICATIONS IF ANY
- INSTR 82H,40H,'COPY' ;POSITION BUFFER POINTER AFTER 'COPY'
- SCAN ,40H ;LOOK FOR START OF SOURCE IF ANY
- JZ C10
- LXI D,DSKNAME ;DE POINTS TO TABLE OF NAMES
- MVI C,0 ;COUNT OF DRIVE NO
- CLX: SAV
- MVI C,2 ;LENGTH OF NAME
- MATCH ;DOES IT MATCH
- RES
- JZ C8
- INR C ;INCR DRIVE NO
- MOV A,C ;DRIVE NO TO A
- CPI 4
- JP SCANERR
- INX D
- INX D ;POINT TO NEXT NAME IN TABLE
- JMP CLX
- C8: MOV A,C ;DRIVE NO TO A
- STA SOURCE ;SAVE SOURCE
- C9: INSTR 82H,40H,'TO' ;DESTINATION MARKER
- JNC C10 ;NO TO USE DEFAULTS
- CALL GETDRV ;LOOK FOR DESTINATION DRIVE
- JNC SCANERR ;MISSING DEST IF NO CARRY
- STA DEST ;SAVE DESTINATION
- LXI H,SOURCE ;POINT TO SOURCE
- CMP M ;CHECK IF SAME
- JNZ C10
- PRINT <CR,LF,'SOURCE AND DESTINATION DRIVE ARE THE SAME',CR,LF>
- PRINT <'IS THIS WHAT YOU WANT? (Y/N) '>
- CALL CHECKY
- C10: CALL CPYFORM
- PRINT <'DISK '>
- LDA SOURCE
- CALL PRNDRV
- PRINT <' TO DISK '>
- LDA DEST
- CALL PRNDRV
- UTX: LDA FORMSW ;CHECK FORMAT SWITCH
- ORA A
- JNZ CFX ;TO COPY FORMAT
- INSTR 82H,40H,'USING' ;GET FORMAT FROM DISK?
- JNC C10A
- CALL GETNUM ;GET TRACK NUMBER
- CALL TRKTEST ;MAKE SURE ITS OK
- STA TNUM ;SAVE IT
- LDA DEST ;DEST DRIVE
- CALL SELECT
- CALL HOME
- LXI H,SECMAP ;POINT TO SECTOR MAP
- LDA TNUM ;TRACK NUMBER
- CALL RDFORM ;READ FORMAT
- MOVE SECMAP,SECMAP1,52 ;SAME MAP FOR BOTH
- C10A: LDA STRK
- ORA A
- JNZ C10B
- LDA ETRK
- CPI 76
- JZ C10E
- LXI H,STRK
- LDA ETRK
- CMP M ;IS THERE JUST ONE TRACK
- JZ C10B
- PRINT <' TRACKS '>
- JMP C10C
- C10B: PRINT <' TRACK '>
- C10C: LHLD STRK
- DECOUT ;PRINT STARTING TRACK
- LDA ETRK
- LXI H,STRK
- CMP M
- JZ C10E
- PRINT <' THRU '>
- LHLD ETRK
- DECOUT ;PRINT ENDING TRACK
- C10E: PRINT <CR,LF,'TYPE RETURN TO BEGIN COPY '>
- CHARIN
- CPI 3
- JZ ENDFIL ;EXIT ON CONTROL C
- LDA SOURCE ;HOME BOTH DRIVES
- CALL SELECT
- CALL HOME ;HOME IT
- LDA DEST
- CALL SELECT
- CALL HOME ;HOME IT
- LDA STRK ;STARTING TRACK NO
- STA STRKR ;SET STARTING TRACK FOR READ
- STA STRKW ;SET STARTING TRACK FRO WRITE
- ;
- ; START OF ACTUAL COPY LOOP
- ;
- C11: LDA SOURCE ;SOURCE DRIVE
- LXI H,DEST
- CMP M ;COMPARE
- JNZ C11A
- PRINT <CR,LF,'LOAD SOURCE DISK, TYPE RETURN '>
- CHARIN
- LDA SOURCE
- CALL HOME
- C11A: CALL SELECT
- LDA DDFLG ;DENSITY FLAG
- STA DENTEMP ;TO TEMPORARY (FOR TRACK ZERO COPY)
- LDA STRKR ;GET READ START
- MOV B,A ;STARTING TRACK TO B
- LDA TRKLIM ;TRACK LIMIT
- MOV C,A
- LXI D,TRKBUF ;POINTS TO MEMORY BUFFER
- C12: MOV A,B ;TRACK NO TO A
- STA TNUM ;TRACK NUMBER FOR ERROR MESS
- LXI H,SECMAP ;READ SECTOR MAP
- ORA A ;TRACK ZERO
- JNZ C14
- MVI A,'S'
- CALL DENSEL ;SELECT SINGLE DENSITY
- LXI H,SECMAP0 ;SECTOR MAP FOR TRACK 0
- MOV A,B ;TRACK NO BACK TO A
- C14: CALL SEEK ;GET PROPER TRACK
- CALL RDTRK ;READ A TRACK INTO MEMORY
- MOV A,B ;TRACK NO TO A
- ORA A ;IS IT TRACK ZERO
- JNZ C15
- LDA DENTEMP ;DENSITY TEMPORARY
- ORA A ;GO ON IF SINGLE
- JZ C15
- MVI A,'D'
- CALL DENSEL ;SELECT DOUBLE DENSITY
- C15: LDA ETRK ;ENDING TRACK
- LXI H,SECMAP
- CMP B ;COMPARE WITH START TRACK
- JZ C20 ;FINISHED READ
- INR B ;INCREMENT TRACK
- DCR C ;DECR TRACK LIMIT
- JZ C20 ;FINISHED READ
- PUSH H
- LHLD TRKSIZE
- DAD D ;ADD OFFSET
- XCHG
- POP H
- LDA CPYOFF ;SECTOR OFFSET
- C16: CALL MAPSLEW ;OFFSET SECTOR MAP FOR SPEED
- JMP C12 ;KEEP READING TRACKS
- C20: MOV A,B ;LAST TRACK READ
- STA STRKR ;SAVE FOR NEXT READ
- LDA DEST ;DESTINATION DRIVE
- LXI H,SOURCE
- CMP M
- JNZ C21
- PRINT <CR,LF,'LOAD DESTINATION DISK, TYPE RETURN '>
- CHARIN
- LDA DEST
- CALL HOME
- C21: CALL SELECT
- LDA STRKW ;STARTING TRACK FOR WRITE
- MOV B,A
- LDA TRKLIM ;MAX TRACKS THAT FIT IM MEMORY
- MOV C,A
- LXI D,TRKBUF ;MEMORY BUFFER
- C22: MOV A,B ;TRACK NO
- STA TNUM ;SAVE FOR ERROR MESS
- LXI H,SECMAP1 ;WRITE SECTOR MAP
- ORA A
- JNZ C23 ;GO ON IF NOT TRACK ZERO
- MVI A,'S'
- CALL DENSEL ;SELECT SINGLE DENSITY
- MOV A,B ;TRACK NO BACK TO A
- LXI H,SECMAP0 ;TRACK ZERO SECTOR MAP
- C23: CALL SEEK
- CALL WRTRK ;WRITE A TRACK
- LXI H,SECMAP1
- MOV A,B ;TRACK NUMBER
- ORA A
- JNZ C23A ;GO ON IF NOT TRACK ZERO
- LDA DENTEMP ;DENSITY TEMPORARY
- ORA A
- JZ C23A
- MVI A,'D'
- CALL DENSEL ;SELECT MFM
- C23A: LDA ETRK ;ENDING TRACK NO
- CMP B
- JZ C40 ;ALL DONE WITH COPY
- INR B
- DCR C ;DECR TRACK LIMIT
- JZ C30 ;FINISHED WRITE
- PUSH H
- LHLD TRKSIZE ;FULL TRACK OFFSET
- C24: DAD D ;ADD IT
- XCHG
- POP H
- LDA CPYOFF ;SECTOR OFFSET
- C26: CALL MAPSLEW
- JMP C22 ;KEEP WRITING TRACKS
- C30: MOV A,B ;LAST TRACK WRITTEN
- STA STRKW ;SAVE IT FOR NEXT TIME
- JMP C11 ;GO READ SOME MORE
- C40: PRINT <CR,LF,LF,'COPY COMPLETE'>
- JMP ENDFIL
- ;
- ; THIS COPY FORMAT LOGIC JUMPS TO THE FORMAT ROUTINE
- ;
- CFX: XRA A ;ZERO
- STA TNUM
- INSTR 82H,40H,'USING'
- JNC CFX1
- CALL GETNUM ;TRACK NUMBER
- CALL TRKTEST ;CHECK IT
- STA TNUM
- CFX1: LDA SOURCE
- CALL SELECT ;SOURCE DRIVE HAS FORMAT
- CALL HOME
- LXI H,SECMAP
- LDA TNUM
- CALL RDFORM ;READ FORMAT INTO SECMAP
- LDA DEST
- STA NEWDRV ;NEW DRIVE NUMBER
- LXI H,SECMAP ;CHECK SECTORS READ FROM DISK
- MVI C,26 ;SECTOR COUNT
- CFX3: MOV A,M ;GET A SECTOR
- ORA A
- JM CFX4 ;ERROR IF MINUS
- JZ CFX4 ;ERROR IF ZERO
- CPI 27
- JP CFX4 ;ERROR IF > 26
- INX H
- DCR C ;DECR SECTOR COUNT
- JNZ CFX3 ;LOOP FOR 26 SECTORS
- PRINT <CR,LF,LF,' FORMAT READ FROM SOURCE DISK'>
- CALL RDISP ;DISPLAY IT
- PRINT <CR,LF,LF>
- JMP FMNS ;TO FORMAT ROUTINE
- CFX4: PRINT <'INCORRECT SECTOR NUMBER READ FROM SOURCE DISK',CR,LF>
- CALL RDISP
- JMP ENDFIL ;BACK TO INPUT ROUTINES
- ;
- ;
- ; CPYFORM LOGIC FOR COPYING FORMAT RATHER THAN DATA
- ;
- CPYFORM:PRINT<CR,LF,LF,'COPYING '>
- LDA FORMSW ;SWITCH ON IF FORMAT
- ORA A
- JZ CP3
- PRINT <'FORMAT FROM '>
- CP3: RET
- ;
- ; DISPLAY DISK SECTOR MAPPING
- ;
- MAP: XRA A
- STA TNUM ;SELECT TRACK ZERO
- LXI H,82H ;POINT TO START OF INPUT BUFFER
- CALL GETDRV ;CHECK IF NEW DRIVE REQUESTED
- JNC MAP3
- STA NEWDRV
- MAP3: CALL GETRK ;READ TRACK SPECS IF ANY
- STA TNUM ;SAVE TRACK NUMBER
- MAP4: LDA NEWDRV ;SELECTED DRIVE
- CALL SELECT
- LDA TNUM ;GET BACK TRACK NO
- LXI H,SECMAP ;POINT TO SECTOR TABLE
- CALL RDFORM ;READ TRACK FORMAT
- CALL CLEAR ;CLEAR SCREEN
- PRINT <CR,LF,' SECTOR FORMAT DRIVE '>
- LDA NEWDRV ;GET DRIVE NO
- CALL PRNDRV ;PRINT DRIVE NAME
- MAP5: PRINT <' TRACK '>
- MAP6: LHLD TNUM
- DECOUT ;CONVERT TO DECIMAL AND PRINT
- PRINT <CR,LF>
- CALL RDISP ;DISPLAY SECTOR MAP
- JMP ENDFIL ;BYE
- ;
- ; DISK VALIDATION ROUTINES
- ;
- DVALID: MVI A,0FFH
- STA DDFLG ;SET DOUBLE DENSITY
- ;
- VALID: LXI H,82H ;POINT TO START OF INPUT BUFFER
- CALL GETDRV ;CHECK NEW DRIVE NUMBER
- JNC VDD0
- STA NEWDRV ;SAVE NEW DRIVE NO
- VDD0: MVI A,0FFH ;SET SWITCH FOR STD FORMAT
- STA TNUM ;SELECT TRACK 0
- LDA DDFLG ;DENSITY SWITCH
- ORA A
- JZ VDX
- MVI A,'D'
- CALL DENSEL ;SELECT DOUBLE DENSITY
- VDX: INSTR 82H,40H,'USING'
- JNC VALID0
- CALL GETNUM
- CALL TRKTEST ;CHECK FOR GOOD TRACK NUMBER
- STA TNUM ;SET TRACK NUMBER
- VALID0: LDA NEWDRV
- REVAL: CALL SELECT
- CALL HOME
- LDA DDFLG ;DENSITY FLAG
- STA DENTEMP ;TO TEMPORARY FOR TRACK ZERO READ
- LXI H,SECMAP ;POINT TO SECTOR TABLE
- LDA TNUM ;CHECK TRACK NUMBER
- ORA A ;0FFH IF DEFAULT TO STD FORMAT
- JP VD1 ;READ SECTOR FORMAT FROM DISK
- XRA A ;READ ONLY MAPPING 51 SECTORS
- CALL STDMAP ;OTHERWISE USE STANDARD FORMAT
- JMP VD2
- VD1: CALL RDFORM ;GET SECTOR MAPPING FROM TRACK TNUM
- VD2: XRA A
- STA HARDERR ;ZERO ERROR COUNTERS
- STA SOFTERR
- STA TNUM ;START WITH TRACK ZERO
- LXI H,SECMAP0 ;SECTOR MAP FOR TRACK 0
- MVI A,'S'
- CALL DENSEL ;SELECT SINGLE DENSITY
- VALID1: LDA TNUM ;GET A TRACK NUMBER
- LXI D,TRKBUF ;TRACK BUFFER
- CALL RDTRK ;VALIDATE THE TRACK
- LXI H,SECMAP ;STANDARD SECTOR MAP
- LDA TNUM ;TRACK NUMBER
- ORA A ;TRACK 0
- JNZ VALIDP ;SKIP IF NOT TRACK ZERO
- LDA DENTEMP ;DENSITY TEMPORARY
- ORA A
- JZ VALIDO
- MVI A,'D'
- CALL DENSEL ;SELECT DOUBLE DENSITY
- VALIDO: LDA TNUM ;LOAD TRACK NO
- VALIDP: CPI 76 ;FINISHED 76 TRACKS?
- JZ VALID2
- INR A ;INCREMENT TRACK COUNT
- STA TNUM ;STORE IT BACK
- CALL SEEK ;STEP TO NEXT TRACK
- LDA SECSIZ ;SECTOR SIZE CODE
- CPI 2 ;CHECK 512
- JNZ VALIDR
- MVI A,3
- JMP VALIDD
- IF DELTA OR TARBELL
- VALIDR: MVI A,6+STEP
- ELSE
- VALIDR: MVI A,5+STEP
- ENDIF
- VALIDD: MOV B,A ;OFFSET TO B
- LDA DDFLG
- ORA A
- MOV A,B ;MOVE OFFSET BACK
- JZ VALIDS
- ADD A ;DOUBLE OFFSET
- DCR A ;SUBTRACT 1
- MOV B,A
- LDA SECSIZ ;SECTOR SIZE CODE
- ORA A
- MOV A,B ;MOVE OFFSET BACK
- JZ VALIDS
- DCR A ;SUBTRACT 1
- VALIDS: LXI H,SECMAP ;POINT TO SECTOR MAP
- CALL MAPSLEW ;PRECESS IT 5 + STEP SECTORS
- LXI H,SECMAP
- CALL CHECKC ;ABORT ON CONTROL C
- JMP VALID1 ;LOOP FOR 76 TRACKS
- VALID2: LDA HARDERR ;CHECK ERRORS
- ORA A
- JNZ VALID8 ;HARD ERRORS HERE
- PRINT <CR,LF,'SUCCESSFUL VALIDATION DRIVE '>
- VALID3: LDA NEWDRV ;GET DRIVE NUMBER
- CALL PRNDRV ;PRINT DRIVE NAME
- VALID6: LDA SOFTERR ;SOFT ERRORS
- ORA A
- JZ ENDFIL
- DCR A ;CHECK FOR SINGLE SOFT ERROR
- JZ VALID12
- PRINT <CR,LF,LF,'THERE WERE '>
- LHLD SOFTERR ;PRINT SOFT ERRORS
- DECOUT ;PRINT ERRORS IN DECIMAL
- PRINT <' RETRYS'>
- VALIDX: LDA HARDERR
- ORA A ;CHECK NO OF HARD ERRORS
- JZ ENDFIL ;RET FOR MORE INPUT IF NONE
- PRINT <' AND '>
- LHLD HARDERR
- DECOUT ;PRINT HARD ERRORS IN DECIMAL
- LDA HARDERR
- DCR A
- JZ VALID9
- VALID7: PRINT <' HARD ERRORS'>
- JMP ENDFIL ;BACK FOR MORE INPUT
- VALID8: PRINT <CR,LF,'VALIDATION ERROR DRIVE '>
- JMP VALID3
- VALID9: PRINT <' HARD ERROR'>
- JMP ENDFIL
- VALID12:PRINT <CR,LF,'THERE WAS 1 RETRY'>
- JMP VALIDX
- ;
- ;
- ;
- ; DISK FORMATTING ROUTINES
- ;
- DFORMAT:MVI A,0FFH ;SET FLAG
- STA DDFLG
- JMP FM00
- ;
- ;
- FORMAT:
- LDA DDFLG ;DOUBLE DENSITY?
- ORA A
- JZ FM1 ;DEFAULT SINGLE DENSITY IF ZERO
- FM00: MVI A,'D'
- CALL DENSEL ;SELECT DOUBLE DENSITY
- FM1: CALL GETRK ;GET TRACK SPECS
- LXI H,82H ;POINT TO START OF INPUT BUFFER
- CALL GETDRV ;GET DRIVE NUMBER
- JNC FM3
- STA NEWDRV
- FM3: INSTR 82H,40H,'SKEW' ;FIXED SKEW FACTOR?
- JC SKEW ;GO DO IT
- INSTR 82H,40H,'SPEC' ;SPECIAL FORMAT?
- JC SPF
- LDA DDFLG ;DENSITY SWITCH
- ORA A
- JNZ FM3A
- LDA SECSIZ ;CHECK IF STANDARD FORMAT
- ORA A
- JZ FM4 ;STD IF ZERO
- FM3A: PRINT <CR,LF,LF,'FORMAT WITH '>
- DECOUT BYTES ;NUMBER OF BYTES PER SECTOR
- PRINT <' BYTES PER SECTOR',CR,LF>
- LDA DDFLG
- ORA A
- JZ FM3C
- PRINT <'DOUBLE DENSITY '>
- DECOUT DNUMSEC
- JMP FM3E
- FM3C: PRINT <'SINGLE DENSITY '>
- LDA NUMSEC
- MOV L,A
- MVI H,0
- DECOUT
- FM3E: PRINT <' SECTORS PER TRACK',CR,LF,LF>
- JMP FM5
- FM4: PRINT <CR,LF,LF>
- PRINT <'STANDARD IBM 3740 FORMAT',CR,LF,LF>
- FM5: LXI H,SECMAP ;POINT TO SECTOR MAP
- CALL STDMAP ;SET UP STANDARD MAPPING
- FMNS: INSTR 82H,40H,'OFFSET';TRACK OFFSET?
- JNC FM0
- CALL GETNUM ;GET OFFSET
- STA OFFSET ;SAVE IT
- FM0: PRINT <'INSERT DISK TO BE FORMATTED IN DRIVE '>
- LDA NEWDRV
- CALL PRNDRV ;PRINT DRIVE LETTER
- PRINT <CR,LF,'TYPE CARRIAGE RETURN '>
- FM6: CHARIN ;WAIT FOR CHARACTER INPUT (ANY WILL DO)
- CPI 3
- JZ ENDFIL ;TRAP OUT ON CONTROL C
- FM7: LDA NEWDRV
- CALL SELECT
- CALL DOFORM
- MVI A,0FFH ;SET SWITCH TO SUPRESS READ FORMAT
- STA TNUM ;MOVE STARTING TRACK NUMBER
- LDA VALFLG ;CHECK VALIDATION SWITCH
- ORA A
- JNZ ENDFIL ;IF NOT ZERO NO VALIDATION
- JMP VALID0 ;NOW VALIDATE DISK JUST TO MAKE SURE
- ;
- SPF: PRINT <CR,LF,LF,'INPUT SPECIAL SECTOR FORMAT',CR,LF,LF>
- PRINT <'PHYSICAL LOGICAL',CR,LF,' SECTOR SECTOR',CR,LF>
- FILL SECMAP,SECMAP+27
- LXI H,SECMAP ;POINTS TO SECTOR TABLE
- MVI C,1 ;SECTOR COUNT
- MVI B,26 ;SECTOR LIMIT
- SPF2: MOV A,C ;PSEC TO A
- STA PSEC ;READY FOR CONVERSION
- SAV ;PUSH REGS
- PRINT <CR,LF,' '>
- LDA PSEC
- CPI 10
- JP SPF3 ;LINE UP COLUMNS
- PRINT SPACE,$
- SPF3: DECOUT PSEC ;CONVERT AND PRINT NUMBER
- PRINT <' '> ;SOME SPACES
- FILL 80H,90H ;ZERO BUFFER
- INPUT 80H ;INPUT THE LOGICAL SECTOR
- LXI H,82H ;START OF BUFFER
- CALL GETNUM ;GET SECTOR
- CALL SECERR ;CHECK FOR ERRORS
- RES
- JC SPF2 ;DO THAT ONE OVER
- MOV M,A ;CONVERTED LSEC TO TABLE
- INX H
- INR C ;INCR COUNTERS
- DCR B
- JNZ SPF2 ;LOOP FOR 26 SECTORS
- CALL CLEAR ;CLEAR SCREEN
- CALL RDISP ;REDISPLAY SECTOR MAP
- RD6: PRINT <CR,LF,LF,LF,'TYPE RETURN TO FORMAT, SECTOR NO TO CORRECT '>
- FILL 80H,90H ;ZERO BUFFER
- INPUT 80H
- LDA 81H ;NO OF CHAR TYPED IN
- ORA A
- JNZ RD8 ;CORRECT INPUT
- PRINT <CR,LF,LF,'WRITING NON STANDARD FORMAT ON DISK',CR,LF,LF>
- JMP FMNS ;TO FORMAT ROUTINE
- RD8: LXI H,82H ;POINT TO START OF BUFFER
- CALL GETNUM ;GET SECTOR
- STA PSEC ;SAVE PHYSICAL SECTOR
- PRINT <CR,LF,LF>
- PRINT <'PHYSICAL LOGICAL',CR,LF,' SECTOR SECTOR',CR,LF,' '>
- DECOUT PSEC
- PRINT <' '>
- FILL 80H,90H
- INPUT 80H
- LXI H,82H
- CALL GETNUM ;LSEC
- ORA A
- JZ RD9 ;ALLOW ZERO SECTOR HERE FOR ERROR CORRECTION
- CALL SECERR ;CHECK FOR ERRORS
- JC RD6 ;BACK FOR MORE INPUT
- RD9: LXI H,SECMAP
- MOV B,A ;SAVE LSEC IN B
- LDA PSEC ;GET BACK PSEC
- MOV E,A ;OFFSET TO E
- MVI D,0 ;ZERO D
- DAD D ;ADD IN OFFSET
- DCX H ;BACK UP ONE (TABLE STARTS AT ZERO)
- MOV M,B ;LOGICAL SECTOR NO TO TABLE
- CALL CLEAR ;CLEAR SCREEN
- CALL RDISP ;REDISPLAY
- JMP RD6 ;CONTINUE
- ;
- ; STDMAP SET UP SECTOR MAP POINTED TO BY HL WITH STANDARD FORMAT
- ;
- STDMAP:
- SAVE
- MOV C,A ;READ WRITE CODE TO C (W=WRITE)
- LDA NUMSEC ;NUMBER OF SECTORS
- MOV B,A ;TO B
- LDA DDFLG ;DENSITY FLAG
- ORA A
- JZ STDMAP1
- LDA DNUMSEC ;NUMBER SECTORS DD
- MOV B,A
- CPI 51
- JZ STDMAP2 ;INTERLEAVE FOR 128 BYTE SECTORS
- STDMAP1:MVI C,1 ;SECTOR COUNT
- STD1: MOV M,C ;MOVE SECTOR NO TO TABLE
- INX H
- INR C ;INCR SEC NO AND TABLE POINTER
- DCR B ;SECTOR COUNT
- JNZ STD1 ;LOOP FOR NUMSEC SECTORS
- JMP STD6
- STDMAP2:LXI D,DDMAP ;POINT TO DOUBLE DENSITY MAP
- MOV A,C ;GET BACK READ WRITE CODE
- CPI 'W' ;IS IT WRITE
- JNZ STD4
- LXI D,DDMAP1
- STD4: LDAX D
- MOV M,A ;MOVE SECTOR NO
- INX D
- INX H ;INCR POINTERS
- DCR B ;DECR COUNT
- JNZ STD4
- STD6: RES
- RET
- ;
- ; SKEW ROUTINE ASSIGNS A SPECIFIED CONSTANT (MORE OR LESS) INTERVAL
- ; BETWEEN SECTORS
- ;
- SKEW CALL GETNUM ;SKEW FACTOR
- STA SKF ;SAVE IT
- FILL SECMAP,SECMAP+27 ;INITIALIZE MAP TO ZERO
- MVI B,1 ;CURRENT SECTOR NUMBER
- LXI H,SECMAP ;POINTS TO SECTOR MAP
- MVI C,26 ;MAX SECTOR COUNT
- LDA SKF ;GET BACK SKEW FACTOR
- MOV D,A ;SAVE IT IN D
- SKEW1: MOV A,B ;GET THE SECTOR NUMBER
- CALL SRTAB ;IS IT ALREADY IN THE TABLE
- JNC SKEW4 ;OK TO USE IT IF NO CARRY
- INR A ;INCR BY ONE
- CALL MOD26 ;MAKE SURE ITS NOT > 26
- SKEW4: MOV M,A ;SAVE IT IN TABLE
- INX H ;INCR TABLE POINTER
- MOV A,D ;SKEW FACTOR
- ADD B ;ADD PRESENT SECTOR NO
- CALL MOD26 ;COMPUTE VALUE MOD 26
- MOV B,A ;PUT IT BACK IN B
- DCR C ;DECR SECTOR COUNT
- JNZ SKEW1 ;LOOP FOR 26 SECTORS
- CALL RDISP ;REDISPLAY MAP WHEN FINISHED
- JMP RD6 ;CONTINUE
- ;
- ; MOD26 ROUTINE COMPUTES A SECTOR NUMBER MOD 26
- ;
- MOD26: CPI 27 ;IS SECTOR NO > 26
- RM ;RETURN IF NOT
- SBI 26 ;SUBTRACT 26
- RET
- ;
- ; REDISPLAY SECTOR MAPPING
- ;
- RDISP: PRINT <CR,LF,' SECTOR MAPPING',CR,LF,LF>
- PRINT <'PHYSICAL LOGICAL PHYSICAL LOGICAL',CR,LF>
- PRINT <' SECTOR SECTOR SECTOR SECTOR',CR,LF>
- LXI H,SECMAP
- MVI B,13
- MVI C,1
- RD1: SAV ;SAVE REGISTERS
- MOV A,C ;PHYSICAL SECTOR
- STA PSEC ;READY FOR CONVERSION
- ADI 13 ;INCR BY 13
- STA PSEC1 ;PHYSICAL SECTOR SECOND COL
- MOV A,M ;GET LOGICAL SECTOR
- STA LSEC
- LXI D,13
- DAD D ;
- MOV A,M ;GET LOGICAL SECTOR FOR SECOND COL
- STA LSEC1 ;STORE FOR CONVERSION
- PRINT <CR,LF,' '>
- LDA PSEC
- CPI 10
- JP RD2
- PRINT SPACE,$ ;ADJUST COL SPACING
- RD2: DECOUT PSEC ;PRINT PSEC
- PRINT <' '>
- LDA LSEC
- CPI 10
- JP RD3
- PRINT SPACE,$
- RD3: LDA LSEC
- ORA A
- JNZ RD13
- PRINT <'-'>
- JMP RD14
- RD13: DECOUT LSEC ;PRINT LSEC
- RD14: PRINT <' '>
- LDA PSEC1
- CPI 10
- JP RD4
- PRINT SPACE,$
- RD4: DECOUT PSEC1 ;SECOND PHYSICAL SECTOR
- PRINT <' '>
- LDA LSEC1
- CPI 10
- JP RD5
- PRINT SPACE,$
- RD5: LDA LSEC1
- ORA A
- JNZ RD15
- PRINT <'-'>
- JMP RD16
- RD15: DECOUT LSEC1 ;SECOND LOGICAL SECTOR
- RD16: RES
- INX H ;TABLE POINTER
- INR C ;PSEC NUMBER
- DCR B ;LINE COUNT
- JNZ RD1 ;LOOP FOR 13 LINES
- RET
- ;
- ; DISK FORMATTING ROUTINES. THREE SECTOR SIZES ARE AVAILABLE BOTH
- ; SINGLE AND DOUBLE DENSITY, 128, 256, AND 512 BYTES. THE NUMBER
- ; OF SECTORS IS AS FOLLOWS:
- ;
- ; SINGLE DENSITY (FM) DOUBLE DENSITY (MFM)
- ; 128 26 51
- ; 256 16 26
- ; 512 8 16
- ;
- DOFORM: LDA DDFLG ;DOUBLE DENSITY FLAG
- ORA A
- JZ DOFORM2
- ;
- ; START OF DOUBLE DENSITY FORMAT ROUTINE
- ;
- DOFORM1:CALL HOME
- LDA SECSIZ
- CPI 2
- JNZ DD1
- LDA OFFSET ;SECTOR OFFSET
- ORA A
- JNZ DD1
- MVI A,15 ;SET DEFAULT OFFSET TO 15
- STA OFFSET
- DD1: LDA STRK ;STARTING TRACK
- STA TRK ;TO TEMPORARY
- ORA A
- CZ TRKZERO ;FORMAT TRACK ZERO SINGLE DENSITY
- CALL SEEK ;SEEK TRACK IN A REGISTER
- NEXTT: LXI H,TRKBUF ;POINT TO TRACK BUFFER
- CALL DINDX
- LDA DNUMSEC
- STA FSECT ;NUMBER OF SECTORS
- DOF1D: CALL DADDR
- CALL DDAT
- LDA FSECT
- DCR A
- STA FSECT
- JNZ DOF1D
- CALL FILBUF
- DOF3D: LHLD DFILOFF ;SECTOR OFFSET
- SHLD FOFF ;TO TEMPORARY
- DOF4D: LXI H,TRKBUF ;POINT TO FORMAT BUFFER
- CALL DFILADR ;PLACE TRACK AND SECTOR NUMBERS IN BUFFER
- DOF5D: LXI D,TRKBUF ;POINT TO TRACK BUFFER
- LXI H,WLOOP ;LOOP JUMP ADDR
- MVI A,0F4H ;TRACK WRITE COMMAND
- OUT DCOM ;ISSUE IT
- CALL WLOOP ;WRITE FORMAT
- DONEITD:XTHL
- XTHL
- IN STATP ;READ STATUS
- ANI 0FFH ;TEST IT
- JNZ ERRMSG ;ERROR HERE
- LDA TRK ;TRACK NO
- INR A ;INCREMENT IT
- STA TRK
- MOV C,A ;STORE TEMPORARILY IN C
- LDA ETRK ;END TRK
- CMP C ;COMPARE
- RM ;RETURN IF MINUS
- INCTRKD:MVI A,59H ;STEP COMMAND
- OUT DCOM ;ISSUE IT
- IN WAIT
- IF PERSCI
- LXI H,0FFFH ;DELAY CONST
- MVI A,1 ;PERSCI STEP COMMAND
- OUT WAIT
- LLLD: DCX H ;DECR COUNT
- MOV A,H
- ORA L
- JNZ LLLD ;LOOP
- ENDIF
- CALL CHECKC ;ABORT ON CONTROL C
- LDA OFFSET ;OFFSET NEXT TRACK
- ORA A
- JZ DOF4D
- LXI H,SECMAP ;SECTOR MAP
- CALL MAPSLEW
- JMP NEXTT
- ;
- ; WLOOP - FAST OUTPUT LOOP FOR DOUBLE DENSITY FORMATTING
- ; ASSUMES HL COTAINS JMP TO START OF LOOP AND TOP OF STACK
- ; RETURN ADDR. LOOP RUNS IN 58 T-STATES OR 14.5 USEC AT 4 MHZ
- ;
- WLOOP: IN WAIT ;WAIT FOR INTRQ OR DRQ
- ORA A ;SET FLAGS
- RP ;RETURN ON INTRQ (FAST TEST IF NO RET)
- LDAX D ;GET A BYTE
- OUT DDATA ;OUTPUT IT
- INX D ;INCR POINTER
- PCHL ;FAST JUMP IF HL CONTAINS JUMP ADDR
- ;
- TRKZERO:LDA ETRK ;END TRACK
- PUSH PSW ;SAVE IT ON STACK
- XRA A ;ZERO
- STA ETRK ;JUST DO ONE TRACK
- LDA DDFLG ;DENSITY FLAG
- STA DENTEMP ;TO TEMPORARY
- LDA SECSIZ ;SECTOR SIZE CODE
- STA SIZTEMP ;TO TEMPORARY
- LDA NUMSEC ;NUMBER OF SECTORS PER TRACK
- STA SECTEMP
- MVI A,26
- STA NUMSEC ;SET NUMBER OF SECTORS TO 26
- LHLD BYTES ;NUMBER OF BYTES PER SECTOR
- SHLD BYTETEMP ;SAVE IT
- LXI H,128
- SHLD BYTES ;SET BYTES TO 128
- LDA GAP ;INTER SECTOR GAP
- STA GAPTEMP
- MVI A,27
- STA GAP
- LHLD FILOFF ;OFFSET
- SHLD OFFTEMP
- LXI H,183
- SHLD FILOFF
- XRA A
- STA SECSIZ ;SECTOR SIZE 0
- MVI A,'S'
- CALL DENSEL ;SELECT SINGLE DENSITY
- LXI H,SECMAP
- CALL STDMAP ;SINGLE DENSITY STD MAP
- LDA DENTEMP ;DENSITY FLAG
- ORA A
- MVI A,10H ;DOUBLE DENSITY
- JNZ TZ2
- MVI A,20H
- TZ2: MOV B,A ;SAVE IT IN B
- LDA SIZTEMP
- ORA B ;OR WITH B
- STA CODE ;SAVE IN CODE
- CPI 10H ;128 BYTE DOUBLE DENSITY
- JNZ TZ4
- LDA DENCODE
- STA CODE
- TZ4: CALL NEXTONE ;SINGLE DENSITY FORMAT
- LDA SIZTEMP
- STA SECSIZ ;RESTORE SECTOR SIZE
- LDA SECTEMP
- STA NUMSEC ;RESTORE NUMBER OF SECTORS
- LHLD BYTETEMP
- SHLD BYTES ;RESTORE NUMBER OF BYTES
- LDA GAPTEMP
- STA GAP ;RESTORE GAP
- LHLD OFFTEMP
- SHLD FILOFF ;RESTORE OFFSET
- LDA DENTEMP
- ORA A
- JZ TRKZ1
- MVI A,'D'
- CALL DENSEL ;SELECT DOUBLE DENSITY
- TRKZ1: LXI H,SECMAP
- CALL STDMAP ;DOUBLE DENSITY STD MAP
- MVI A,59H ;STEP COMMAND
- OUT DCOM
- IN WAIT
- POP PSW ;GET BACK OLD END TRACK
- STA ETRK ;RESTORE IT
- MVI A,1 ;START DOUBLE DENSITY ON TRACK 1
- STA TRK ;SET TRACK TO ONE
- RET
- ;
- ;
- ;
- ; START OF SINGLE DENSITY FORMAT ROUTINE
- ;
- ;
- DOFORM2:CALL HOME ;HOME SELECTED DRIVE
- LDA STRK ;STARTING TRACK
- STA TRK ;TO TEMPORARY
- ORA A
- CZ TRKZERO ;FORMAT TRACK ZERO STANDARD 3740 FORMAT
- CALL SEEK ;SEEK TRACK IN A
- NEXTONE:LXI H,TRKBUF ;POINT TO TRACK BUFFER
- CALL INDX
- LDA NUMSEC
- STA FSECT ;STORE IT
- 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
- DOF3: LHLD FILOFF ;SECTOR OFFSET
- SHLD FOFF ;TO TEMPORARY
- DOF4: LXI H,TRKBUF ;POINT TO FORMAT BUFFER
- CALL FILADR ;PLACE TRACK AND SECTOR NUMBERS IN BUFFER
- LDA TRK ;CHECK FOR TRACK ZERO
- ORA A
- JNZ DOF5
- LDA CODE ;DENSITY AND SECTOR SIZE CODE
- STA TRKBUF+229 ;FOR BOTH DELTA AND TARBELL
- STA TRKBUF+230 ;TRACK ZERO SECTOR ONE ONLY
- DOF5: LXI H,TRKBUF ;POINT TO TRACK BUFFER
- MVI A,0F4H ;TRACK WRITE COMMAND
- OUT DCOM ;ISSUE IT
- DOF7: IN WAIT ;WAIT FOR INTERRUPT
- ORA A ;SET FLAGS
- JP DONEIT ;INTERRUPT
- MOV A,M ;GET A BYTE
- OUT DDATA ;SEND IT
- INX H ;INCR BUFFER POINTER
- JMP DOF7 ;LOOP TILL INTRQ
- DONEIT: XTHL
- XTHL
- IN STATP ;READ STATUS
- ANI 0FFH ;TEST IT
- JNZ ERRMSG ;ERROR HERE
- LDA TRK ;TRACK NO
- INR A ;INCREMENT IT
- STA TRK
- MOV C,A ;STORE TEMPORARILY IN C
- LDA ETRK ;END TRK
- CMP C ;COMPARE
- RM ;RETURN IF MINUS
- INCTRK: MVI A,58H+STEP ;STEP COMMAND
- OUT DCOM ;ISSUE IT
- IN WAIT
- IF PERSCI
- LXI H,0FFFH ;DELAY CONST
- MVI A,1 ;PERSCI STEP COMMAND
- OUT WAIT
- LLL: DCX H ;DECR COUNT
- MOV A,H
- ORA L
- JNZ LLL ;LOOP
- ENDIF
- CALL CHECKC ;ABORT ON CONTROL C
- LDA OFFSET ;OFFSET NEXT TRACK
- ORA A
- JZ DOF4
- LXI H,SECMAP ;SECTOR MAP
- CALL MAPSLEW
- JMP NEXTONE
- ;
- ;
- ; INDX - INDEX BLOCK FOR IBM FORMATS (NOT REQUIRED FOR 1771 OR 1791)
- ;
- INDX: LXI D,40 ;COUNT
- MVI B,0FFH ;BYTE
- CALL MOVEIT ;STORE THE BLOCK
- LXI D,6 ;COUNT
- MVI B,0 ;ZERO
- CALL MOVEIT ;STORE THE BLOCK
- MVI M,0FCH ;INDEX MARK
- INX H ;INCR POINTER
- LXI D,26 ;NOW 26 MORE FF'S
- MVI B,0FFH
- CALL MOVEIT ;STORE THE BLOCK
- RET
- ;
- ; DINDX - INDEX BLOCK DOUBLE DENSITY (MFM)
- ;
- DINDX: LDA SECSIZ ;SECTOR SIZE CODE
- CPI 1 ;256 BYTES?
- JZ DINDX1 ;YES, STD IBM (MFM) FORMAT
- MVI B,4EH ;FILL CHAR
- LXI D,30 ;30
- CALL MOVEIT
- RET
- DINDX1: MVI B,4EH ;FILL BYTE
- LXI D,80 ;COUNT
- CALL MOVEIT
- MVI B,0 ;12 ZEROS
- LXI D,12
- CALL MOVEIT
- MVI B,0F6H ;3 F6'S
- LXI D,3
- CALL MOVEIT
- MVI M,0FCH ;INDEX MARK
- INX H
- MVI B,4EH ;50 4E'S
- LXI D,50
- CALL MOVEIT
- RET
- ;
- ; ADDR - ADDRESS BLOCK
- ;
- ADDR: LXI D,6 ;WRITE 6 ZEROS
- MVI B,0
- CALL MOVEIT
- MVI M,0FEH ;ID ADDRESS MARK
- INX H
- LXI D,4 ;TRACK AND SECTOR ZERO INITIALLY
- XRA A
- CALL MOVEIT
- MVI M,0F7H ;WRITE 2 CRC'S
- INX H
- RET
- ;
- ; DADDR - ADDRESS BLOCK (MFM)
- ;
- DADDR: LDA SECSIZ ;SECTOR SIZE CODE
- ORA A
- JNZ DADDR1
- MVI B,0 ;9 00'S
- LXI D,9
- CALL MOVEIT
- MVI B,0F5H ;3 F5'S
- LXI D,3
- CALL MOVEIT
- MVI M,0FEH
- INX H ;ID ADDR MARK
- MVI B,0
- LXI D,4 ;4 ZEROS FOR TRACK AND SECTOR NO
- CALL MOVEIT
- MVI M,0F7H ;WRITE CRC'S
- INX H
- RET
- DADDR1: LXI D,12 ;12 ZEROS
- MVI B,0
- CALL MOVEIT
- LXI D,3 ;3 F5'S
- MVI B,0F5H
- CALL MOVEIT
- MVI M,0FEH ;ID ADDR MARK
- INX H
- LXI D,4 ;4 ZEROS
- MVI B,0
- CALL MOVEIT
- MVI M,0F7H ;WRITE CRC'S
- INX H
- RET
- ;
- ; DATA - WRITE DATA BLOCK FILLED WITH E5'S
- ;
- DATA: MVI B,0FFH ;WRITE 11 FF'S
- LXI D,11
- CALL MOVEIT
- MVI B,0 ;NOW 6 ZEROS
- LXI D,6
- CALL MOVEIT
- MVI M,0FBH ;DATA ADDRESS MARK
- INX H
- XCHG ;SWAP DE, HL
- LHLD BYTES ;NUMBER OF BYTES IN SECTOR
- XCHG ;SWAP THEM BACK
- MVI B,0E5H ;DATA FILL CHARACTER
- CALL MOVEIT
- MVI M,0F7H ;WRITE 2 CRC'S
- INX H
- LDA GAP ;INTERRECORD GAP
- MOV E,A ;TO E
- MVI D,0 ;SET D TO ZERO
- MVI B,0FFH ;GAP BYTE
- CALL MOVEIT
- RET
- ;
- ; DDAT - FILL DATA BLOCK WITH E5'S (MFM)
- ;
- DDAT: MVI B,04EH ;WRITE 22 4E'S
- LXI D,22
- CALL MOVEIT
- MVI B,0 ;NOW 12 ZEROS
- LXI D,12
- CALL MOVEIT
- LXI D,3 ;3 F5'S
- MVI B,0F5H ;
- CALL MOVEIT
- MVI M,0FBH ;DATA ADDRESS MARK
- INX H
- XCHG ;SWAP DE, HL
- LHLD BYTES ;NUMBER OF BYTES IN SECTOR
- XCHG ;SWAP THEM BACK
- MVI B,0E5H ;DATA FILL CHARACTER
- CALL MOVEIT
- MVI M,0F7H ;WRITE 2 CRC'S
- INX H
- LDA DGAP ;INTERRECORD GAP
- MOV E,A ;TO E
- MVI D,0 ;SET D TO ZERO
- MVI B,4EH ;GAP BYTE
- CALL MOVEIT
- RET
- ;
- ;
- ; MOVEIT ROUTINE HL POINTS TO MEMORY, DE = BYTE COUNT, B CONTAINS BYTE
- ;
- MOVEIT: MOV M,B ;STORE BYTE
- INX H
- DCX D
- MOV A,E
- ORA D
- JNZ MOVEIT
- RET
- ;
- ; FILADR - FILL IN TRACK AND SECTOR NUMBERS
- ;
- FILADR:
- LXI B,SECMAP ;POINTER TO SECTOR MAP
- LDA NUMSEC ;NUMBER OF SECTORS
- STA SEC ;SECTOR COUNTER
- LHLD FOFF ;FILL ADDR OFFSET
- XCHG
- 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
- LDAX B ;SECTOR NUMBER
- MOV M,A ;TO BUFFER
- INX H
- LDA SECSIZ ;SECTOR SIZE CODE
- MOV M,A ;TO MEMORY
- DAD D ;INCR BUFFER POINTER
- INX B ;INCR SECTOR MAP POINTER
- LDA SEC
- DCR A
- STA SEC ;DECR SECTOR COUNT
- JNZ FIL01 ;LOOP FOR NUMSEC SECTORS
- RET
- ;
- ; DFILADR - FILL IN TRACK AND SECTOR NUMBERS
- ;
- DFILADR:
- LXI B,SECMAP ;POINTER TO SECTOR MAP
- LDA DNUMSEC ;NUMBER OF SECTORS
- STA SEC ;SECTOR COUNTER
- LHLD FOFF ;FILL ADDR OFFSET
- XCHG
- LXI H,TRKBUF+43 ;LOCATION OF FIRST TRACK NUMBER
- LDA SECSIZ ;SECTOR SIZE CODE
- ORA A
- JZ DFIL00
- LXI H,TRKBUF+46
- DFIL00: DCR A
- JNZ DFIL01
- LXI H,TRKBUF+162 ;LOCATION FIRST TRACK NO 256 BYTE SECTORS
- DFIL01: LDA TRK ;TRACK NO
- MOV M,A ;TO BUFFER
- INX H
- INX H ;POINT TO SECTOR
- LDAX B ;SECTOR NUMBER
- MOV M,A ;TO BUFFER
- INX H
- LDA SECSIZ ;SECTOR SIZE CODE
- MOV M,A ;TO MEMORY
- DAD D ;INCR BUFFER POINTER
- INX B ;INCR SECTOR MAP POINTER
- LDA SEC
- DCR A
- STA SEC ;DECR SECTOR COUNT
- JNZ FIL01 ;LOOP FOR NUMSEC SECTORS
- RET
- ;
- ;
- ; FILBUF - FILL END OF TRACK WITH FF'S OR 4E'S
- ;
- FILBUF: LXI D,1024 ;END OF TRACK FILL
- MVI B,0FFH ;FILL CHAR
- LDA DDFLG ;CHECK DENSITY FLAG
- ORA A
- JZ ET1
- MVI B,4EH ;DD FILL BYTE
- ET1: MOV M,B
- INX H
- DCX D ;DECR COUNT
- MOV A,D
- ORA E
- JNZ ET1
- RET
- ;
- ; IDREAD - READ ID FIELD ON CURRENT TRACK AND PUT DATA IN IDTAB
- ;
- IDREAD: LDA RETRYS
- IDRD01: STA IDECNT ;ERROR COUNT
- MVI A,0D0H ;INTERRUPT
- OUT DCOM
- LXI H,IDTAB ;POINT TO TABLE
- XTHL
- XTHL ;SHORT DELAY
- MVI A,0C4H ;READ ADDR COMMAND
- OUT DCOM ;SEND IT
- IDRD02: IN WAIT ;WAIT FOR DRQ OR INTRQ
- ORA A
- JP IDRD03
- IN DDATA ;READ DATA BYTE
- MOV M,A ;STORE IT
- INX H ;INCR POINTER
- JMP IDRD02 ;LOOP TILL INTRQ
- IDRD03: IN STATP ;READ STATUS
- ANI 08H
- RZ
- LDA IDECNT ;ERROR COUNT
- DCR A ;DECR IT
- JNZ IDRD01 ;TRY AGAIN
- PRINT <CR,LF,'ERROR IN READING ID FIELD'>
- JMP ENDFIL
- ;
- ;
- ;
- ; WAIT ROUTINE CAUSES TIME DELAY OF ABOUT 1/3 SEC AT 4 MHZ
- ;
- DELAY: SAV
- LXI H,09000H ;LOAD DELAY CONSTANT
- LXI D,1 ;ONE TO DE
- DL1: XTHL
- XTHL
- INX B ;DELAY
- DAD D
- JNC DL1 ;LOOP TILL CARRY SET
- RES
- RET
- ;
- ;
- ; EXIT ROUTINES
- ;
- ENDFIL: PRINT CRLF,$
- LDA DRIVE
- CALL SELECT
- LDA INFLAG ;SEE WHERE TO GO
- ORA A
- JNZ NEWIN ;BACK FOR MORE INPUT
- MONITOR:LHLD OLDSTK
- SPHL ;RESET ORIGINAL STACK
- RET ;BACK TO CP/M
- ;
- ; ERROR ROUTINES
- ;
- ERRMSG: PRINT <CR,LF,'FORMATTING ERROR DRIVE '>
- LDA NEWDRV
- ORA A ;TEST DRIVE NUMBER
- JZ ERM2
- PRINT <'B',CR,LF>
- JMP ENDFIL
- ERM2: PRINT <'A',CR,LF>
- JMP ENDFIL
- ;
- ; CHECK FOR LEGITIMATE SECTOR NUMBERS (1-26). AND CHECK IF SECTOR NUMBER
- ; ALREADY ASSIGNED
- ;
- SECERR: CPI 1
- JP SE0
- PRINT <CR,LF,' ERROR - SECTOR NUMBERS MUST BE GREATER THAN ZERO'>
- JMP SE1
- SE0: CPI 27
- JM SE2
- PRINT <CR,LF,' ERROR - SECTOR GREATER THAN 26'>
- SE1: STC
- RET
- SE2: LXI H,SECMAP
- MVI B,26
- SE3: CMP M ;CHECK IF SECTOR ALREADY USED
- JNZ SE4
- PRINT <CR,LF,' SORRY YOU ALREADY USED THAT ONE'>
- JMP SE1
- SE4: INX H
- DCR B
- JNZ SE3
- SE5: ORA A ;CLEAR CARRY
- RET
- ;
- ; SCANERR - NUMBER MISSING WHERE EXPECTED
- ;
- SCANERR:PRINT <CR,LF,LF,'MISSING OPERAND, PLEASE START OVER',CR,LF>
- JMP ENDFIL ;EXIT
- ;
- ; DECERR - NON NUMERIC CHARACTER IN NUMBER
- ;
- DECERR: PRINT <CR,LF,LF,'ERROR IN ENTERING DECIMAL NUMBER, PLEASE START OVER'>
- JMP ENDFIL ;EXIT
- ;
- ; TRKTEST - TEST FOR TRACK BETWEEN 0 AND 76
- ;
- TRKTEST:CPI 77 ;CHECK SECTOR > 76
- RM
- PRINT <CR,LF,LF,'TRACK NUMBER MUST BE BETWEEN 0-76',CR,LF>
- JMP ENDFIL
- ;
- ;
- ; SEARCH SECTOR TABLE FOR PREVIOUS SECTOR NUMBER
- ; SET CARRY ON MATCH
- ;
- SRTAB: SAV
- LXI H,SECMAP ;POINT TO TABLE
- MVI B,26 ;TABLE LENGTH
- SR1: CMP M ;COMPARE TABLE ENTRY WITH A
- JNZ SR5 ;GO ON IF NO MATCH
- STC ;SET CARRY
- SR3: RES
- RET
- SR5: INX H ;INCR POINTER
- DCR B ;DECR SECTOR COUNT
- JNZ SR1 ;LOOP FOR 26 SECTORS
- ORA A ;RESET CARRY
- JMP SR3 ;EXIT
- ;
- ;
- ; CLEAR ROUTINE CLEARS SCREEN (NULLS FOR SOME TERMINALS)
- ;
- CLEAR: SAVE
- PRINT <1AH,0,0,0,0,0,0,0,0,0,0>
- RESTORE
- RET
- ;
- ; SEEK ROUTINE MOVES TO TRACK IN A REG (ASSUMES PREVIOUS HOME)
- ;
- SEEK: SAV ;SAVE REGS
- MOV E,A ;SAVE TRACK NO IN E
- IN TRACK ;READ 1771 TRACK REG
- MOV B,A ;SAVE IN B
- CMP E ;COMPARE WITH REQUESTED TRACK
- JZ SEEK3
- IF PERSCI
- MVI A,40H ;STEP IN
- JC PSK1
- MVI A,60H ;STEP OUT
- PSK1: OUT DCOM ;OUTPUT STEP DIRECTION
- MVI A,30 ;DELAY CONST
- PSK3: DCR A
- JNZ PSK3 ;WAIT SHORT TIME
- MOV A,B ;PRESENT TRACK
- SUB E ;SUBTRACT REQUESTED TRACK
- JP PSK5 ;OK IF +
- CMA
- INR A ;COMPLIMENT IF -
- PSK5: MOV B,A ;NO OF STEPS IN B
- MVI A,1 ;PERSCI STEP COMMAND
- PSK7: OUT WAIT ;STEP PERSCI
- DCR B
- JNZ PSK7
- IN WAIT ;CLEAR 1771
- IN STATP
- MOV A,E ;DESTINATION TRACK
- OUT TRACK
- LDA LATCH ;LATCH CODE FOR SELECTED DRIVE
- ANI 72H
- OUT WAIT ;COMMAND WAITS FOR SEEK COMPLETE
- IN WAIT ;WAIT FOR SEEK COMPLETE
- LDA LATCH
- OUT WAIT ;RESET LATCH
- ELSE
- MVI D,0
- MVI C,5 ;RETRYS
- SEEK1: MOV A,E ;TRACK NO
- OUT DDATA ;TRACK NO TO DATA REG
- SEEKW: IN STATP ;CHECK BUSY
- RRC
- JC SEEKW ;WAIT TILL NOT BUSY DOOR CLOSED ETC.
- MVI A,1CH+STEP ;SEEK COMMAND (6 MSEC) WITH VERIFY
- OUT DCOM ;DO IT
- IN WAIT
- IN STATP ;READ DISK STATUS
- ANI 91H
- JZ SEEK3 ;EXIT IF ZERO
- DCR C ;DECR ERROR COUNT
- JZ SEEK2 ;SEEK ERROR AFTER 5 RETRYS
- CALL HOME ;HOME THE DRIVE
- JMP SEEK1 ;TRY AGAIN
- SEEK2: PUSH D ;SAVE TRACK NO
- PRINT <CR,LF,'SEEK ERROR TRACK '>
- POP H ;TRACK NO TO L
- DECOUT ;PRINT TRACK NO
- PRINT <' DRIVE '>
- LDA DRVNO ;GET SELECTED DRIVE
- CALL PRNDRV ;PRINT A THRU C
- JMP ENDFIL ;EXIT
- ENDIF
- SEEK3: RES ;RESTORE REGS
- RET
- ;
- ;
- ; HOME SELECTED DRIVE
- ;
- HOME: SAV
- PUSH PSW
- IF PERSCI
- XRA A ;TRACK ZERO
- CALL SEEK ;SEEK IT
- CALL DELAY
- MVI A,8
- OUT DCOM
- IN WAIT
- IN STATP ;CHECK STATUS
- ANI 4 ;TRACK ZERO BIT
- JZ HOMERR ;ERROR IF NOT ZERO
- ELSE
- HOME1: IN STATP ;CHECK IF BUSY
- RRC
- JC HOME1
- MVI A,STEP ;HOME COMMAND
- OUT DCOM ;ISSUE COMMAND
- CALL DELAY ;WAIT TILL DRIVE HOME
- HOME3: IN STATP ;READ DISK STATUS
- ANI 4 ;CHECK TRACK ZERO FLAG
- JZ HOMERR ;ERROR IF NOT T 0
- ENDIF
- HOME5: LXI H,TRKTBL ;POINT TO TRACK TABLE
- MVI D,0
- LDA DRVNO ;SELECTED DRIVE
- MOV E,A
- DAD D ;ADDR OF TABLE ENTRY
- XRA A ;ZERO
- MOV M,A ;TRACK ZERO
- IF NOT PERSCI
- CALL DELAY ;WAIT
- ENDIF
- POP PSW
- RES
- RET
- HOMERR: PRINT <CR,LF,'ERROR IN HOMING DRIVE '>
- LDA DRVNO ;SELECTED DRIVE
- CALL PRNDRV ;PRINT IT
- JMP ENDFIL ;EXIT
- ;
- ; READ ROUTINE READ SECTOR FROM SELECTED TRACK AND KEEP TRACK OF
- ; ERRORS. DE POINTS TO THE MEMORY BUFFER. THE SECTOR TO BE READ
- ; IS IN SNUM.
- ;
- READ0: MVI B,88H ;READ WITHOUT HEAD LOAD COMMAND
- LDA RETRYS ;RETRY COUNT
- STA ERRORS ;ERROR COUNT
- JMP READ2 ;TO READ ROUTINE
- READ1: MVI B,8CH ;READ WITH HEAD LOAD COMMAND
- LDA RETRYS ;RETRY COUNT
- STA ERRORS ;ERROR COUNT
- READ2: LDA SNUM ;GET SECTOR NUMBER
- OUT SECTP ;SET SECTOR NUMBER INTO 1771
- LDA DDFLG ;DENSITY FLAG
- ORA A
- JZ READ3
- MVI A,1
- OUT WAIT+1 ;SET DOUBLE DENSITY
- READ3: XCHG
- SHLD BBLOCK ;POINTER TO START OF CURRENT BLOCK
- MOV A,B ;GET READ COMMAND
- OUT DCOM ;SENT IT
- READ5: IN WAIT ;WAIT TILL COMMAND EXECUTED
- ORA A ;CHECK ERROR STATUS
- JP READ6 ;DONE IF BIT 7 HI (INTRQ)
- IN DDATA ;READ DATA
- MOV M,A ;STORE IT IN BUFFER
- INX H
- JMP READ5 ;BACK FOR ANOTHER BYTE
- READ6: XCHG
- IN STATP ;DISK STATUS
- ANI 9DH ;CHECK ERROR BITS
- RZ ;RETURN IF NONE
- LDA SOFTERR ;SOFT ERRORS
- INR A
- STA SOFTERR ;STORE IT BACK
- LDA ERRORS ;ERROR COUNT
- DCR A
- STA ERRORS ;STORE IT BACK
- JZ RFILL ;RETRY TRYS IF ZERO
- XCHG
- LHLD BBLOCK ;RESET BUFFER POINTER
- XCHG
- JMP READ2 ;TRY AGAIN FOR RETRY TIMES
- RFILL: LDA NOFILL ;ERROR FILL FLAG
- ORA A ;IF ZERO DON'T FILL WITH E5'S
- JNZ READ8
- SAVE
- LHLD BBLOCK ;POINTS TO BEGINNING OF READ BLOCK
- MVI C,128 ;COUNTER
- MVI A,0E5H ;FILL BYTE
- READ7: MOV M,A ;STORE E5
- INX H ;INCR POINTER
- DCR C
- JNZ READ7 ;LOOP FOR 128 BYTES
- JMP READ9
- READ8: SAV ;SAVE REGISTERS
- READ9: PRINT <CR,LF,'PERMANENT READ ERROR TRACK '>
- READ10: LHLD TNUM ;TRACK NUMBER
- DECOUT ;PRINT DECIMAL
- PRINT <' SECTOR '>
- LHLD SNUM ;SECTOR NUMBER
- DECOUT
- PRINT <' DRIVE '>
- LDA DRVNO ;GET SELECTED DRIVE NO
- CALL PRNDRV ;PRINT DRIVE NO A THRU C
- READ12: LXI H,HARDERR ;POINT TO HARD ERRORS
- INR M ;INCREMENT IT
- MVI A,0FFH ;SET ERROR FLAG
- RES ;RESTORE REGISTERS
- CALL CHECKC ;ABORT ON CONTROL C
- RET
- ;
- ; VERIFY ROUTINE READ SECTOR FROM SELECTED TRACK AND KEEP TRACK OF
- ; ERRORS. DE POINTS TO MEMORY BUFFER. (SWAPPED INTERNALLY WITH HL
- ; FOR SPEED IN THIS ROUTINE)
- ; THE SECTOR NUMBER TO BE READ IS IN SNUM
- ;
- VER0: MVI B,88H ;READ WITHOUT HEAD LOAD
- LDA RETRYS ;RETRY COUNT
- STA ERRORS ;ERROR COUNT
- JMP VER2 ;TO READ ROUTINE
- VER1: MVI B,8CH ;READ WITH HEAD LOAD
- LDA RETRYS ;RETRY COUNT
- STA ERRORS ;ERROR COUNT
- VER2: LDA SNUM ;SECTOR NUMBER
- OUT SECTP ;SET SECTOR NUMBER INTO 1771
- XCHG ;SWAP REGISTERS
- SHLD BBLOCK ;START CURRENT BLOCK
- MOV A,B ;GET READ COMMAND
- OUT DCOM ;SENT IT
- VER5: IN WAIT ;WAIT TILL COMMAND EXECUTED
- ORA A ;CHECK ERROR STATUS
- JP VER8 ;DONE IF BIT 7 HI (INTRQ)
- IN DDATA ;READ DATA
- CMP M ;COMPARE WITH MEMORY
- INX H
- JZ VER5 ;BACK FOR ANOTHER BYTE
- VER6: XCHG
- LDA SOFTERR ;SOFT ERRORS
- INR A ;INCREMENT IT
- STA SOFTERR ;STORE IT BACK
- LDA ERRORS ;ERROR COUNT
- DCR A ;DECREMENT IT
- STA ERRORS ;STORE IT BACK
- XCHG
- LHLD BBLOCK ;RESET MEMORY POINTER
- XCHG
- JNZ VER2 ;TRY AGAIN FOR RETRY TIMES
- PUSH H
- LXI H,128 ;SECTOR INCR
- DAD D ;ADD TO MEMORY POINTER
- XCHG
- POP H
- SAVE ;SAVE REGISTERS
- PRINT <CR,LF,'PERMANENT VERIFY 0R READ CRC ERROR TRACK '>
- JMP READ10 ;PRINT REST OF ERROR MESSAGE AND RET
- VER8: XCHG ;SWITCH REGISTERS BACK
- IN STATP ;GET DISK STATUS
- ANI 9DH ;CHECK ERROR BITS
- RZ ;RETURN IF NONE
- XCHG
- JMP VER6
- ;
- ;
- ;
- ; WRITE ROUTINE WRITES A SECTOR ON SELECTED TRACK
- ; DE POINTS TO THE MEMORY BUFFER. THE SECTOR NUMBER TO BE WRITTEN
- ; IS IN SNUM.
- ;
- WRITE0: LDA RETRYS ;RETRY COUNT
- WRITE1: STA ERRORS ;ERROR COUNT
- IN STATP ;READ STATUS
- ANI 20H ;CHECK HEAD LOAD BIT
- WRITE2: LDA SNUM ;SECTOR NUMBER
- OUT SECTP ;SET SECTOR NUMBER INTO 1771
- MVI A,0ACH ;WRITE WITH HEAD LOAD
- JNZ WRITE3
- MVI A,0A8H ;WRITE WITH HEAD LOAD
- WRITE3: OUT DCOM ;ISSUE WRITE COMMND
- WRITE5: IN WAIT ;WAIT TILL COMMAND EXECUTED
- ORA A ;CHECK ERROR STATUS
- JP WRITE7 ;DONE IF BIT 7 HI (INTRQ)
- LDAX D ;GET A BYTE FROM MEMORY
- OUT DDATA ;WRITE TO DISK
- INX D ;INCR POINTER
- JMP WRITE5 ;BACK FOR ANOTHER BYTE
- WRITE7: XTHL
- XTHL ;SHORT DELAY
- IN STATP ;READ DISK STATUS
- ANI 0FDH ;CHECK ERROR BITS
- RZ ;RETURN IF NONE
- LDA SOFTERR ;SOFT ERRORS
- INR A ;INCREMENT IT
- STA SOFTERR ;STORE IT BACK
- LDA ERRORS ;ERROR COUNT
- DCR A
- JNZ WRITE1 ;TRY AGAIN FOR RETRY TIMES
- SAV
- PRINT <CR,LF,'PERMANENT WRITE ERROR TRACK '>
- JMP READ10 ;PRINT REST OF ERROR MESS
- ;
- ; RDTRK READS A TRACK FOR VALIDATION OR COPY
- ; HL POINTS TO SECTOR MAP, DE POINTS TO MEMORY BUFFER
- ;
- RDTRK: SAV ;SAVE REGISTERS
- LDA NUMSEC ;COUNT OF SECTORS PER TRACK
- MOV C,A ;TO C
- LDA DDFLG ;DENSITY FLAG
- ORA A
- JZ RDT0
- LDA DNUMSEC ;SECTORS DOUBLE DENSITY
- MOV C,A
- RDT0: MOV A,M ;GET A SECTOR NUMBER
- STA SNUM ;SAVE SECTOR NUMBER IN MEMORY
- CALL READ1 ;READ WITH HEAD LOAD
- RDT1: INX H ;INCR SECTOR MAP POINTER
- DCR C ;DECR SECTOR COUNT
- JZ RDT4 ;EXIT
- ORA A ;CHECK SECTOR READ RETURN CODE
- JNZ RDT0 ;IF ERROR READ WITH HEAD LOAD
- MOV A,M ;GET A SECTOR NUMBER FROM MAP
- STA SNUM ;SAVE SECTOR NUMBER IN MEMORY
- CALL READ0 ;READ DISK WITHOUT HEAD LOAD
- JMP RDT1 ;LOOP FOR 26 SECTORS
- RDT4: RES ;RESTORE REGISTERS
- CALL CHECKC ;ABORT ON CONTROL C
- RET
- ;
- ;
- ; WRTRK WRITES AND VERIFIES A TRACK
- ; HL POINTS TO SECTOR MAP, DE POINTS TO MEMORY BUFFER
- ;
- WRTRK: SAV ;SAVE REGISTERS
- LDA NUMSEC ;COUNT OF SECTORS PER TRACK
- MOV C,A ;TO C
- LDA DDFLG ;DENSITY SWITCH
- ORA A
- JZ WRT
- LDA DNUMSEC ;NUMBER OF SECTORS (MFM)
- MOV C,A ;TO C
- WRT: PUSH H
- PUSH D ;SAVE POINTERS FOR VERIFICATION
- WRT0: MOV A,M ;GET A SECTOR NUMBER
- STA SNUM ;SAVE SECTOR NUMBER IN MEMORY
- CALL WRITE0 ;CALL WRITE ROUTINE
- WRT1: INX H ;INCR SECTOR MAP POINTER
- DCR C ;DECR SECTOR COUNT
- JZ WRT3 ;EXIT
- JMP WRT0 ;LOOP TILL SECTOR COUNT IS ZERO
- WRT3: POP D
- POP H
- CALL CHECKC ;ABORT ON CONTROL C
- LDA VERFLG ;VERIFY FLAG
- ORA A
- JNZ WRT20 ;NO VERIFY IF NOT ZERO
- LDA NUMSEC ;SECTOR COUNT
- MOV C,A ;TO C
- LDA DDFLG ;DENSITY FLAG
- ORA A
- JZ WRT10
- LDA DNUMSEC ;NUMBER OF SECTORS (MFM)
- MOV C,A ;TO C
- WRT10: MOV A,M ;GET SECTOR NUMBER
- STA SNUM ;SAVE IT
- CALL VER0 ;VERIFY WITHOUT HEAD LOAD
- WRT11: INX H ;INCR SECTOR MAP POINTER
- DCR C ;DECR SECTOR COUNT
- JZ WRT20 ;EXIT
- ORA A ;CHECK READ ERROR RETURN CODE
- JZ WRT10 ;BACK TO READ IF NO ERROR
- PRINT <CR,LF,LF,'VALIDATING DESTINATION DISK',CR,LF>
- LDA DEST ;DEST DISK NO
- JMP REVAL
- WRT20: RES ;RESTORE REGISTERS
- RET
- ;
- ; RDFORM ROUTINE READS A TRACK IN A AND STORES THE SECTOR FORMAT IN A
- ; TABLE POINTED TO BY HL. A MUST CONTAIN THE DESIRED TRACK NUMBER
- ;
- RDFORM: SAV ;PUSH REGISTERS
- XCHG ;DE POINTS TO SECTOR TABLE
- STA TNUM ;SAVE TRACK NUMBER
- LDA DDFLG ;DENSITY FLAD
- ORA A
- JNZ RDT7 ;EXIT IF DOUBLE DENSITY
- CALL TRKRD ;READ TRACK IN A
- LXI H,TRKBUF+4AH
- LXI B,183
- MVI A,-1 ;SET FLAG FOR FIRST ITERATION
- STA CNT ;SET SECTOR COUNT TO NUMSEC
- RDF4: MOV A,M ;GET A BYTE FROM THE TRACK FORMAT
- CPI 0FEH ;IS IT AN ADDRESS MARK/
- JZ RDF5
- INX H ;BUMP POINTER
- JMP RDF4 ;LOOP TILL ADDR MARK FOUND
- RDF5: INX H ;HL NOW POINTS TO TRACK NO
- LDA TNUM ;TRACK NUMBER
- CMP M ;COMPARE AGAINST MEMORY
- JNZ RDF4 ;LOOK SOME MORE IF NOT SAME
- LDA CNT ;TEST FOR FIRST ITERATION
- ORA A
- JP RDFX
- MOV A,M ;PICK UP TRACK NO
- STA TNUM ;SAVE IT
- RDFX: INX H
- INX H ;HL NOW POINTS TO FIRST SECTOR NUMBER
- RDF6: MOV A,M ;GET SECTOR NUMBER
- STAX D ;STORE IT IN TABLE
- LDA CNT ;COUNT
- ORA A ;IS IT THE FIRST SECTOR
- JP RDFY
- LDA NUMSEC
- STA CNT ;SET COUNT FOR 128 BYTE SECTORS
- INX H ;POINT TO SECTOR SIZE BYTE
- MOV A,M
- STA SECSIZ ;SAVE IT
- PUSH H
- CPI 1 ;256 BYTE SECTORS
- JNZ RDFS
- MVI A,16
- STA NUMSEC
- STA CNT ;SET COUNT
- LXI H,256
- SHLD BYTES
- RDFS: CPI 2 ;512 BYTE SECTORS
- JNZ RDFU
- MVI A,8 ;8 SECTORS PER TRACK
- STA NUMSEC
- STA CNT ;SET COUNT
- LXI H,512 ;512 BYTES PER SECTOR
- SHLD BYTES
- RDFU: POP H
- DCX H ;BACK UP POINTER
- LDA CNT ;RELOAD COUNT
- RDFY: DCR A ;DECREMENT IT
- JZ RDT7 ;FINISHED
- STA CNT ;STORE BACK COUNT
- INX D ;INCR TABLE POINTER
- DAD B ;INCR TRACK DATA POINTER BY 182
- JMP RDF4 ;LOOP FOR 26 SECTORS
- RDT7: RESTORE
- RET
- ;
- ; TRACK READ ROUTINE. TRACK NO IS IN A, HL POINTS TO BUFFER
- ;
- TRKRD: SAVE
- LXI H,TRKBUF ;SET POINTER TO TRACK INPUT BUFFER
- CALL SEEK ;FIND THE TRACK
- MVI A,0E4H ;READ TRACK COMMAND
- OUT DCOM ;ISSUE IT
- RTF1: IN WAIT ;WAIT AND READ DISK STATUS
- ORA A
- JP RTF3 ;EXIT
- IN DDATA ;READ DATA
- MOV M,A ;SAVE BYTE IN MEMORY
- INX H ;INCR POINTER
- JMP RTF1 ;LOOP TILL INTRQ
- RTF3: RESTORE
- RET
- ;
- ; THIS ROUTINE OFFSETS THE SECTOR MAP BY A CONSTANT (OFFSET) PER TRACK
- ; CALLED WITH OFFSET IN A AND HL POINTING TO SECTOR MAP.
- ;
- MAPSLEW:SAVE ;SAVE REGS
- PUSH H ;SAVE POINTER TO SECTOR MAP ON STACK
- MOV B,A ;SAVE OFFSET IN B
- XCHG ;SECTOR MAP POINTER TO DE
- LXI H,NUMSEC ;POINT TO NUMBER OF SECTORS (FM)
- LDA DDFLG ;DENSITY FLAG
- ORA A
- JZ MS0
- LXI H,DNUMSEC ;NUMBER OF SECTORS (MFM)
- MS0: MOV C,M ;SECTOR COUNT TO C
- MOV L,C ;SECTOR COUNT TO L
- MVI H,0
- MOV A,B ;OFFSET BACK TO A
- ADD L ;ADD SECTOR COUNT TO OFFSET
- MOV B,A ;OFFSET+SECTOR COUNT TO B
- DAD D ;16 BIT ADD DE TO HL
- MS1: LDAX D ;GET A SECTOR NO (DE POINTS TO SOURCE)
- MOV M,A ;STORE IT (HL POINTS TO DESTINATION)
- DCR B ;DECR COUNT OF BYTES TO BE MOVED
- JZ MS5 ;EXIT
- MOV A,C ;GET NUMBER OF SECTORS
- CMP B ;DOES B=26
- JNZ MS3 ;JUMP IF NOT
- POP H ;RESET DESTINATION
- DCX H ;PRE DECREMENT IT
- MS3: INX H
- INX D ;INDEX POINTERS
- JMP MS1 ;LOOP FOR OFFSET+26 ITERATIONS
- MS5: RESTORE ;RESTORE REGS
- RET
- ;
- ; SELECT THE DRIVE IN A
- ;
- SELECT: SAV
- MOV C,A
- LXI H,DRVNO ;POINT TO DRIVE NO
- CMP M ;COMPARE WITH A
- JZ SEL5
- MOV A,M ;OLD DRIVE NUMBER
- MOV E,A ;OLD DRIVE NO TO E
- MVI D,0
- LXI H,TRKTBL ;POINT TO TRACK TABLE
- IN TRACK ;READ 1771 TRACK REG
- IF DUAL
- MVI B,4 ;SET ALL TRACKS THE SAME
- SEL1: MOV M,A ;STORE TRACK
- INX H ;INCR TRACK TABLE POINTER
- DCR B
- JNZ SEL1 ;LOOP FOR 4 DRIVES
- ELSE
- DAD D ;COMPUTE ADDR
- MOV M,A ;TRACK NO TO TABLE
- ENDIF
- MOV A,C ;GET NEW DRIVE NO
- MOV E,A ;NEW DRIVE TO E
- LXI H,TRKTBL ;POINT TO TRACK TABLE
- DAD D ;COMPUTE ADDR
- MOV A,M ;NEW TRACK NO
- ORA A ;SET FLAGS
- JP SEL3 ;PREV SELECTED IF NOT MINUS
- MOV A,C ;NEW DRIVE NO
- IF DELTA
- CALL SELDELT
- ELSE
- CALL DOSEL
- ENDIF
- CALL HOME
- XRA A ;TRACK ZERO
- SEL3: OUT TRACK ;SET 1771 TRACK REG
- SEL5: MOV A,C
- STA DRVNO ;RESET DRIVE NO
- MOV A,C ;RESTORE DRIVE NO TO A
- IF DELTA
- CALL SELDELT
- ENDIF
- IF TARBELL
- CALL SELTARB
- ENDIF
- IF NOT DELTA OR TARBELL
- CALL DOSEL
- ENDIF
- RES
- RET
- ;
- ;
- ; DOSEL ACTUAL DRIVE SELECT (OLD TARBELL SINGLE DENSITY)
- ;
- DOSEL: CMA ;COMPLIMENT A
- ADD A
- ADD A
- ADD A
- ADD A ;SHIFT LEFT 4 BITS
- ORI 2 ;LATCH COMMAND
- STA LATCH ;SAVE IT
- OUT WAIT ;SELECT DRIVE
- RET
- ;
- ;
- ; SELTARB SELECT DRIVE (NEW TARBELL CONTROLLER)
- ;
- SELTARB:ADD A
- ADD A
- ADD A
- ADD A ;SHIFT LEFT 4 BITS
- ORI 2
- STA LATCH
- OUT WAIT
- RET
- ;
- ;
- ; SELDELT SELECT DRIVE (DELTA CONTROLLER)
- ;
- SELDELT:CMA ;COMPLIMENT
- STA LATCH ;SAVE IT
- OUT WAIT ;SELECT DRIVE
- RET
- ;
- ;
- ; GETNUM GET A NUMBER FROM INPUT BUFFER AND TEST
- ;
- GETNUM: SAV
- SCAN ,40H
- JZ SCANERR ;ERROR IF NO NUMBER
- DECIN ;CONVERT TO DECIMAL
- JC DECERR ;INPUT ERROR IF CARRY
- SHLD DECFULL ;SAVE FULL 16 BIT VALUE
- RES
- RET
- ;
- ;
- ;
- ; GETRK GETS AND TESTS STARTING AND ENDING TRACK NUMBERS FROM THE INPUT
- ; BUFFER. TRACKS STORED IN STRK AND ETRK. ROUTINE RETURNS WITH STRK IN A
- ;
- GETRK: SAV
- XRA A ;ZERO
- STA STRK ;DEFAULT TO 0
- MVI A,76
- STA ETRK ;DEFAULT TO 76
- INSTR 82H,40H,'TRACK' ;TRACK SPECIFICATIONS?
- JNC GT5
- CALL GETNUM ;GET TRACK NUMBER
- CALL TRKTEST ;CHECK IT
- STA STRK ;STARTING TRACK
- STA ETRK ;SET ENDING TRACK TOO IF NO OTHER SPECIFIED
- INSTR 82H,40H,'-' ;TRACK SEPARATOR
- JNC GT5
- CALL GETNUM ;GET ENDING TRACK
- CALL TRKTEST ;CHECK IT
- STA ETRK ;ENDING TRACK
- GT5: LDA STRK ;STARTING TRACK TO A
- RES
- RET
- ;
- ; DBLSUB 16 BIT SUBTRACT DE FROM HL TO HL
- ;
- DBLSUB: XRA A ;CLEAR CARRY
- MOV A,L
- SBB E ;SUBTRACT LOW BYTES
- MOV L,A ;BACK TO L
- MOV A,H
- SBB D ;SUBTRACT HIGH BYTES
- MOV H,A ;DIFFERENCE IN HL
- RET
- ;
- ; POLL CONSOLE INPUT FOR CONTROL C
- ;
- CHECKC: SAV ;SAVE REGS
- PUSH PSW
- MVI C,11 ;CP/M STATUS POLL CODE
- CALL 5 ;CALL CP/M
- ANI 1 ;1 IF CHARACTER WAITING
- JZ CKC3 ;EXIT
- CHARIN ;READ THE CONSOLE
- CPI 3 ;WAS IT A CONTROL C
- JZ ENDFIL ;BACK TO INPUT LOOP
- CKC3: POP PSW
- RES ;RESTORE REGS
- RET
- ;
- ; READ CONSOLE FOR YES
- ;
- CHECKY: SAV
- CHARIN ;READ CONSOLE
- RES
- CPI 'Y' ;YES
- RZ
- JMP ENDFIL ;BACK TO INPUT IF NOT YES
- ;
- ;
- ; SIZE ROUTINE SETS SECTOR SIZES 128, 256, OR 512 BYTES
- ;
- SIZE: CALL GETNUM ;GET SECTOR SIZE
- CPI 128 ;128 BYTE SECTOR
- RZ ;STANDARD FORMAT RETURN ZERO SET
- LHLD DECFULL ;CONVERTED DECIMAL NUMBER
- LXI D,-256 ;COMPARE HL WITH 256
- DAD D
- MOV A,H
- ORA L ;TEST ZERO
- JNZ SIZE1
- MVI A,1
- STA SECSIZ ;256 BYTE SECTORS
- MVI A,16
- STA NUMSEC ;NUMBER OF SECTORS
- MVI A,26
- STA DNUMSEC
- LXI H,256
- SHLD BYTES ;BYTES PER SECTOR
- MVI A,32 ;ADDR LEADER GAP
- STA GAP
- MVI A,46
- STA DGAP ;ADDR LEADER GAP (MFM)
- LXI H,316 ;SECTOR OFFSET (FM)
- SHLD FILOFF
- LXI H,359 ;SECTOR OFFSET (MFM)
- SHLD DFILOFF
- RET
- SIZE1: LHLD DECFULL ;CONVERTED DECIMAL NUMBER
- LXI D,-512 ;COMPARE HL WITH 512
- DAD D ;ADD TO HL
- MOV A,H
- ORA L
- JNZ SIZE3 ;ERROR NOT 512 OR 128
- MVI A,2 ;SET SIZE TO 512
- STA SECSIZ
- LXI H,512 ;BYTES PER SECTOR
- SHLD BYTES
- MVI A,8 ;SECTORS PER TRACK
- STA NUMSEC
- MVI A,16
- STA DNUMSEC ;SECTORS PER TRACK (MFM)
- MVI A,50 ;ADDR LEADER GAP
- STA GAP
- MVI A,64
- STA DGAP
- LXI H,590 ;OFFSET FOR 512 BYTES (FM)
- SHLD FILOFF
- LXI H,633
- SHLD DFILOFF ;OFFSET FOR 512 BYTES (MFM)
- RET
- SIZE3: PRINT <CR,LF,LF,'ERROR IN FORMAT SECTOR SIZE',CR,LF,BEL>
- JMP ENDFIL
- ;
- ; DENSEL - SELECT DENSITY
- ; FOR DELTA DOUBLE DENSITY CONTROLLER
- ;
- IF DELTA
- DENSEL: CPI 'D' ;DOUBLE DENSITY ?
- JZ DENSEL1
- MVI A,2
- OUT WAIT+1 ;SELECT SINGLE DENSITY
- XRA A
- STA DDFLG
- RET
- DENSEL1:MVI A,1 ;SELECT DOUBLE DENSITY
- OUT WAIT+1
- MVI A,0FFH
- STA DDFLG
- RET
- ENDIF
- ;
- ; FOR NEW TARBELL DOUBLE DENSITY CONTROLLER
- ;
- IF TARBELL
- DENSEL: CPI 'D' ;DOUBLE DENSITY
- JZ DENSEL1
- XRA A
- STA DDFLG ;SET DENSITY FLAG
- LDA LATCH
- ANI 0F7H
- STA LATCH
- OUT WAIT ;SELECT SINGLE DENSITY
- RET
- DENSEL1:MVI A,0FFH
- STA DDFLG
- LDA LATCH
- ORI 08H
- STA LATCH
- OUT WAIT ;SELECT DOUBLE DENSITY
- RET
- ENDIF
- ;
- ;
- ; FOR OLD TARBELL 1771 BASED CONTROLLER
- ;
- IF NOT TARBELL AND NOT DELTA
- DENSEL: CPI 'D'
- RNZ ;JUST RETURN IF NOT DD
- PRINT <CR,LF,'DOUBLE DENSITY NOT AVAILABLE FOR 1771',CR,LF>
- JMP ENDFIL
- ENDIF
- ;
- ; GETDRV SEARCH COMMAND STRING FOR DRIVE NAME AND RETURN CODE
- ; A:=0 B:=1 C:=2 D:=3 CARRY SET IF DRIVE PRESENT
- ; GETDRV IS CALLED WITH HL POINTING TO STARTING POSITION FOR SEARCH
- ;
- GETDRV: SAV ;SAVE REGS
- LXI D,DSKNAME ;POINT TO NAME TABLE
- MVI C,0 ;DRIVE NUMBER
- GD1: SAV
- MVI B,40H ;STRING LENGTH
- MVI C,2 ;SUBSTRING LENGTH
- INSTR
- RES
- JC GD3 ;FOUND NAME ON CARRY
- MOV A,C ;DRIVE NO TO A
- CPI 3 ;CHECK LIMIT
- JZ GD3
- INR C ;INCR DRIVE NO
- INX D
- INX D ;POINT TO NEXT NAME
- JMP GD1 ;LOOP FOR 4 DRIVES
- GD3: MOV A,C ;DRIVE NO TO A
- RES
- RET
- ;
- DSKNAME:DB 'A:' ;TABLE OF DISK NAMES
- DB 'B:'
- DB 'C:'
- DB 'D:'
- ;
- ; PRNDRV PRINT DRIVE NAME CORRESPONDING TO CODE IN A REG
- ; 0=A 1=B 2=C 3=D >3 ERROR
- ;
- PRNDRV: SAV
- CPI 4 ;CHECK RANGE
- JP PRDR3 ;ERROR IF > 3
- ADI 'A' ;CALC LETTER TO PRINT
- CHAROUT ;PRINT IT
- PRDR1: RES
- RET
- PRDR3: PRINT <CR,LF,'ERROR - DRIVE NUMBER GREATER THAN 3',CR,LF>
- JMP PRDR1
- ;
- ;
- ;
- ;
- ; EQUATES AND DATA ALLOCATIONS
- ;
- DISK EQU 0F8H ;DISK BASE ADDR
- DCOM EQU DISK ;DISK COMMAND PORT
- STATP EQU DISK ;DISK STATUS PORT
- TRACK EQU DISK+1 ;DISK TRACK COMMAND
- SECTP EQU DISK+2 ;DISK SECTOR PORT
- DDATA EQU DISK+3 ;DISK DATA PORT
- WAIT EQU DISK+4 ;DISK WAIT CONTROL PORT
- SPACE: DB ' $' ;ASCII SPACE
- CRLF: DB 0DH,0AH,24H ;ASCII CR LF
- CNT: DB 0 ;TEMP COUNTER
- TNUM: DW 0 ;TRACK NUMBER
- SNUM: DW 0 ;SECTOR NUMBER
- HARDERR:DW 0 ;HARD DISK ERRORS
- SOFTERR:DW 0 ;SOFT DISK ERRORS
- ERRORS: DB 0 ;RETRY COUNTER DURING READ OR VERIFY
- VERERR: DB 0 ;VERIFY ERROR FLAG, SET TO FF ON COPY ERROR
- VERFLG: DB 0 ;FLAG WHEN FF NO VERIFICATION DURING COPY
- NOFILL DB 0 ;FLAG, WHEN TRUE (FF) NO FILL WITH E5 ON ERROR
- FORMSW: DB 0 ;COPY FORMAT SWITCH FORMAT IF TRUE (FF)
- RETRYS: DB 0 ;MAXIMUM NUMBER OF RETRYS
- INFLAG: DB 0 ;FLAG, IF TRUE RETURN FOR MORE CONSOLE INPUT
- VALFLG: DB 0 ;VALIDATION FLAG, VALIDATE AFTER FORMAT IF 0
- DDFLG: DB 0 ;DOUBLE DENSITY FLAG
- SKF: DB 0 ;SKEW FACTOR
- TRKLIM: DB 0 ;THE NUMBER OF TRACKS THAT FIT IN MEMORY
- OFFSET: DB 0 ;TRACK SECTOR OFFSET
- DRIVE: DB 0 ;STORAGE FOR ORIGINALLY LOGGED DRIVE NO
- DRVNO DB 0 ;SELECTED DRIVE
- NEWDRV: DB 0 ;NEW DRIVE NO
- LATCH DB 0 ;LATCH COMMAND
- TRKTBL: DB 0 ;TRACK POS A:
- DB 0 ;TRACK POS B:
- DB 0 ;TRACK POS C:
- DB 0 ;TRACK POS D:
- SOURCE: DB 0 ;SOURCE DRIVE FOR COPY OPERATION
- DEST: DB 0 ;DESTINATION DRIVE FOR COPY
- OLDSTK: DW 0 ;OLD STACK POINTER
- ENDSTK: DS 48 ;NEW STACK
- NEWSTK: DW 0 ;TOP OF NEW STACK
- SECSIZ: DB 0 ;SECTOR SIZE CODE FOR FORMAT (0,1 OR 2)
- NUMSEC: DB 0 ;NUMBER OF SECTORS PER TRACK
- DNUMSEC:DB 0 ;NUMBER OF BYTES PER SECTOR (MFM)
- FSECT: DB 0 ;SECTOR COUNT USED IN FORMATTING
- BYTES: DW 0 ;NUMBER OF BYTES PER SECTOR
- GAP: DB 0 ;FORMAT ADDR LEADER GAP
- DGAP: DB 0 ;FORMAT ADDR LEADER GAP (MFM)
- FILOFF: DW 0 ;SECTOR OFFSET IN TRACK BUFFER (FM)
- DFILOFF:DW 0 ;SECTOR OFFSET IN TRACK BUFFER (MFM)
- FOFF: DW 0 ;TEMP STORAGE FOR SECTOR OFFSET
- CPYOFF: DB 0 ;OFFSET USED FOR COPY ROUTINES
- TRK: DB 0 ;TRACK NUMBER USED IN FORMATTING DISK
- SEC: DB 0 ;SECTOR COUNT USED IN FORMATTING
- STRK: DW 0 ;STARTING TRACK FOR FORMAT OR COPY
- ETRK: DW 0 ;ENDING TRACK FOR FORMAT OR COPY
- STRKR: DB 0 ;STARTING TRACK FOR READ
- STRKW: DB 0 ;STARTING TRACK FOR WRITE
- PSEC: DW 0 ;PHYSICAL SECTOR
- PSEC1: DW 0 ;ANOTHER
- LSEC: DW 0 ;LOGICAL SECTOR
- LSEC1: DW 0 ;ANOTHER
- BBLOCK: DW 0 ;POINTER TO START OF CURRENT READ BLOCK
- SECMAP: DS 104 ;PHYSICAL TO LOGICAL SECTOR MAP FOR READ
- SECMAP1:DS 104 ;SECTOR MAP FOR WRITE
- SECMAP0:DS 53 ;SECTOR MAP TRACK ZERO - ALWAYS SINGLE DENSITY
- TRKSIZE:DW 0 ;NO OF BYTES PER TRACK FOR COPY ROUTINES
- DENCODE:DB 0 ;DOUBLE DENSITY CODE (LAST BYTE SECTOR 1 T 0)
- CODE: DB 0 ;SPECIAL CODE FOR DISK ID FOR PASCAL
- DENTEMP:DB 0 ;TEMP STORAGE FOR DDFLG
- SIZTEMP:DB 0 ;TEMP STORAGE FOR SECSIZ
- SECTEMP:DB 0 ;TEMP STORAGE FOR NUMSEC
- BYTETEMP:DW 0 ;TEMP STORAGE FOR BYTES
- GAPTEMP:DB 0 ;TEMP STORAGE FOR GAP
- OFFTEMP:DW 0 ;TEMP STORAGE FOR OFFSET
- DDMAP: DB 1,18,35,10,27,44,2,19,36,11,28,45,3
- DB 20,37,12,29,46,4,21,38,13,30,47,5
- DB 22,39,14,31,48,6,23,40,15,32,49,7
- DB 24,41,16,33,50,8,25,42,17,34,51,9,26,43
- ;
- DDMAP1: DB 1,35,27,2,36,28,3,37,29,4,38,30,5,39,31
- DB 6,40,32,7,41,33,8,42,34,9,43,18,10,44,19,11,45
- DB 20,12,46,21,13,47,22,14,48,23,15,49,24,16,50
- DB 25,17,51,26
- DECFULL:DW 0 ;FULL 16 BIT VALUE OF DECIMAL INPUT
- IDECNT: DB 0 ;ERROR COUNT FOR ID READ
- IDTAB: DB 0 ;ADDR FIELD FOR ID READ
- IDTAB1: DB 0 ;ZERO
- IDTAB2: DB 0 ;SECTOR ADDR
- IDTAB3: DB 0 ;ZERO
- IDTAB4: DB 0 ;CRC
- IDTAB5: DB 0 ;CRC
- TRKBUF: DB 0 ;BUFFER STORAGE
- END
- ;
- ;
-