home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / SIMTEL / CPMUG / CPMUG038.ARK / DFOCO.ASM < prev    next >
Assembly Source File  |  1984-04-29  |  57KB  |  2,333 lines

  1. ;                -- DFOCO --
  2. ;
  3. ;                            BY S. J. SINGER
  4. ;                            10 NOV 1979
  5. ;
  6. TRUE:    EQU    0FFH
  7. FALSE:    EQU    00H
  8. ;
  9. PERSCI:    EQU    FALSE        ;CONDITIONAL ASSEMBLY SWITCH FOR FAST SEEK
  10. ;                ;PERSCI DRIVES   (SET TRUE 0FFH FOR PERSCI)
  11. DELTA:    EQU    FALSE        ;CONDITIONAL SWITCH FOR DELTA CONTROLLER
  12. TARBELL:EQU    FALSE        ;CONDITIONAL SWITCH FOR NEW TARBELL DOUBLE
  13. ;                ;DENSITY CONTROLLER
  14. ;
  15. ;    (SET BOTH DELTA AND TARBELL FALSE FOR OLD TARBELL CONTROLLER)
  16. ;
  17. DUAL:    EQU    FALSE        ;CONDITIONAL SWITCH FOR DUAL DRIVES
  18. STEP:    EQU    1        ;STEPPING RATE 1=6 MSEC, 2=10 MSEC, 3=20 MSEC
  19. ;                (0=3 MSEC, 1=6 MSEC, 2=10 MSEC, 3=15 MSEC 1791)
  20. ;                (USE STEP = 6 FOR PERSCI DRIVES)
  21. ;
  22.     MACLIB    MACRO        ;INCLUDE SYSTEM MACROS
  23.     ORG    100H
  24.     LXI    H,0
  25.     DAD    SP        ;GET STACK POINTER
  26.     SHLD    OLDSTK
  27.     LXI    SP,NEWSTK    ;SET UP NEW STACK
  28.     LXI    H,TRKTBL    ;POINT TO TRACK TABLE
  29.     MVI    B,4
  30. ST2:    MOV    M,A        ;STORE IN TABLE
  31.     INX    H
  32.     DCR    B
  33.     JNZ    ST2        ;SET 4 TRACK LOCATIONS
  34.     DISKIO    ?DRIVE        ;GET CURRENTLY LOGGED DRIVE NO
  35.     STA    DRIVE        ;SAVE IT
  36.     STA    DRVNO        ;SELECTED DRIVE
  37.     STA    NEWDRV        ;ALSO SAVE IN NEW DRIVE NO
  38.     IF    NOT DUAL
  39.     LXI    H,TRKTBL    ;POINT TO TRACK TABLE
  40.     MVI    D,0
  41.     MOV    E,A        ;DRIVE NO
  42.     DAD    D
  43.     IN    TRACK        ;GET TRACK FROM 1771
  44.     MOV    M,A        ;STORE IT IN TABLE
  45.     ENDIF
  46.     LDA    81H        ;CONSOLE INPUT ALREADY HERE ?
  47.     ORA    A
  48.     JZ    SIGNON        ;BUFFER EMPTY, INPUT FROM CONSOLE
  49.     LDA    80H        ;GET NO OF CHAR INPUT
  50.     ORI    80H        ;ADD 128
  51.     MOV    L,A
  52.     XRA    A
  53.     MOV    H,A        ;HL CONTAINS ADDR OF END OF BUFFER
  54. ZBFF:    INR    L
  55.     JZ    START        ;REMAINDER OF BUFFER ZEROED
  56.     MOV    M,A
  57.     JMP    ZBFF        ;LOOP
  58. SIGNON:    PRINT    <CR,LF,'         - DFOCO -',CR,LF>
  59.     PRINT    <'CP/M FAST FORMAT-COPY UTILITY',CR,LF>
  60.     PRINT    <'COPYRIGHT NOV 1979 BY S J SINGER',CR,LF>
  61. NEWIN:    PRINT    <CR,LF,'*'>
  62.     MVI    A,0FFH        ;SET SWITCH TO RETURN HERE AGAIN
  63.     STA    INFLAG
  64.     LXI    SP,NEWSTK    ;RESET STACK POINTER
  65.     FILL    80H,0FFH    ;ZERO INPUT BUFFER
  66.     INPUT    80H        ;READ FILE NAME
  67. ;
  68. ;    SEARCH INPUT BUFFER FOR INITIAL COMMAND STRING
  69. ;
  70. START:    MVI    A,10
  71.     STA    RETRYS        ;SET DEFAULT READ OR WRITE RETRYS TO 10
  72.     XRA    A
  73.     STA    VALFLG        ;SET OTHER DEFAULTS
  74.     STA    VERFLG
  75.     STA    NOFILL
  76.     STA    DDFLG        ;SINGLE DENSITY
  77.     STA    FORMSW        ;RESET PROGRAM SWITCHES TO FALSE
  78.     STA    OFFSET        ;SET OFFSET TO ZERO
  79.     STA    SECSIZ        ;DEFAULT TO IBM STANDARD FORMAT
  80.     STA    CODE        ;SPECIAL PASCAL FLAG CODE T 0 S 1 B 128
  81.     MVI    A,26
  82.     STA    NUMSEC        ;NUMBER OF SECTORS
  83.     INR    A
  84.     STA    GAP        ;FORMAT ADDR LEADER GAP
  85.     MVI    A,13
  86.     STA    DGAP        ;GAP FOR MFM
  87.     MVI    A,51
  88.     STA    DNUMSEC        ;NUMBER OF SECTORS (MFM)
  89.     LXI    H,183
  90.     SHLD    FILOFF        ;FILL OFFSET (FM)
  91.     LXI    H,195
  92.     SHLD    DFILOFF        ;FILL OFFSET (MFM)
  93.     LXI    H,128
  94.     SHLD    BYTES        ;128 BYTES PER SECTOR
  95.     LDA    'S'
  96.     CALL    DENSEL        ;DEFAULT IS SINGLE DENSITY
  97.     MVI    A,0DDH
  98.     STA    DENCODE        ;DEFAULT DOUBLE DENSITY CODE (SINGLE SIDE)
  99.     LXI    H,SECMAP0    ;STANDARD MAP TRACK 0
  100.     CALL    STDMAP
  101.     FILL    SECMAP,SECMAP+104
  102.     INSTR    82H,40H,'NOVAL'    ;CHECK FOR VALIDATION OFF
  103.     JNC    START0
  104.     MVI    A,0FFH
  105.     STA    VALFLG        ;SET SWITCH
  106. START0:    INSTR    82H,40H,'RETRY'    ;CHANGE DEFAULT?
  107.     JNC    START2
  108.     CALL    GETNUM        ;GET RETRYS
  109.     ORA    A
  110.     JNZ    START1
  111.     INR    A        ;NO ZERO RETRYS
  112. START1:    STA    RETRYS        ;SAVE IT
  113. START2:    INSTR    82H,40H,'SIZE'
  114.     CC    SIZE
  115.     INSTR    82H,40H,'4D'    ;"QUAD" DISK ?
  116.     JNC    START2A
  117.     MVI    A,4DH        ;QUAD CODE
  118.     STA    DENCODE
  119.     JMP    START2B
  120. START2A:INSTR    82H,40H,'DD'
  121.     JNC    STARTX
  122. START2B:MVI    A,0FFH
  123.     STA    DDFLG        ;SET DOUBLE DENSITY FLAG
  124. STARTX:    INSTR    82H,40H,'MAP'
  125.     JC    MAP
  126.     INSTR    82H,40H,'DCOPY'    ;COPY DOUBLE DENSITY?
  127.     JC    DCOPY
  128.     INSTR    82H,40H,'COPY'    ;COPY A DISK?
  129.     JC    COPY
  130.     INSTR    82H,40H,'DFORM'
  131.     JC    DFORMAT        ;DOUBLE DENSITY FORMAT
  132.     INSTR    82H,40H,'FORM'
  133.     JC    FORMAT        ;SEARCH FOR FORMAT
  134.     INSTR    82H,40H,'DVALID' ;VALIDATE DOUBLE DENSITY
  135.     JC    DVALID
  136.     INSTR    82H,40H,'VALID'    ;VALIDATE DISK?
  137.     JC    VALID
  138.     JMP    NEWIN
  139. ;
  140. ;    COPY WILL COPY A DISK FROM ONE DRIVE TO ANOTHER AS QUICKLY AS POSSIBLE
  141. ;    THE PROGRAM WILL READ THE FORMAT FROM TRACK 2 OF BOTH DISKS TO OPTIMIZE
  142. ;    THE COPY OPERATION. ALL OF THE AVAILABLE MEMORY BETWEEN THE END OF FOCO
  143. ;    AND THE BEGINNING OF CP/M WILL BE USED BY COPY.
  144. ;
  145. DCOPY:    MVI    A,0FFH
  146.     STA    DDFLG        ;SET DOUBLE DENSITY FLAG
  147. ;
  148. COPY:    LHLD    6        ;POINTS TO TOP OF MEMORY
  149.     LXI    D,TRKBUF    ;END OF PROGRAM
  150.     CALL    DBLSUB        ;SUBTRACT DE FROM HL
  151.     MVI    C,0        ;ZERO TRACK COUNT
  152.     XCHG
  153.     IF    DELTA OR TARBELL
  154.     MVI    A,6+STEP    ;SECTOR OFFSET
  155.     ELSE    
  156.     MVI    A,5+STEP
  157.     ENDIF
  158.     STA    CPYOFF        ;SAVE FOR LATER
  159.     LXI    H,128*26    ;MAX BYTES PER TRACK
  160.     LDA    SECSIZ        ;SECTOR SIZE CODE
  161.     ORA    A        ;IF 128 THEN SECSIZ=0
  162.     JZ    C1
  163.     LXI    H,512*8        ;MAX BYTES PER TRACK
  164. C1:    LDA    DDFLG        ;DENSITY FLAG
  165.     ORA    A
  166.     JZ    C1A
  167.     DAD    H        ;DOUBLE IT (512*16)
  168.     LDA    SECSIZ        ;SECTOR SIZE CODE
  169.     CPI    2
  170.     JZ    C1A
  171.     LXI    H,51*128    ;128 BYTE SECTORS?
  172.     ORA    A
  173.     JZ    C1A
  174.     LXI    H,26*256    ;MUST BE 256 BYTE SECTORS THEN
  175. C1A:    SHLD    TRKSIZE        ;SAVE IT
  176.     XCHG
  177. C2:    CALL    DBLSUB        ;SUBTRACT
  178.     JC    C4        ;EXIT ON CARRY
  179.     INR    C        ;INCR TRACK COUNT
  180.     JMP    C2        ;LOOP TILL HL GOES MINUS
  181. C4:    MOV    A,C        ;TRACK LIMIT
  182.     STA    TRKLIM        ;TRACKS THAT CAN BE READ ON ONE PASS
  183.     LDA    DDFLG        ;DENSITY SWITCH
  184.     ORA    A
  185.     JZ    C4A
  186.     MVI    A,'D'
  187.     CALL    DENSEL        ;SELECT DOUBLE DENSITY
  188.     LDA    CPYOFF        ;SECTOR OFFSET FOR COPY
  189.     ADD    A        ;DOUBLE IT FOR DOUBLE DENSITY
  190.     STA    CPYOFF
  191. C4A:    XRA    A
  192.     STA    SOURCE        ;DEFAULT SOURCE DISK 'A:'
  193.     STA    VERFLG        ;DEFAULT VERIFICATION ON
  194.     INR    A
  195.     STA    DEST        ;DEFAULT DEST DISK 'B:'
  196.     LXI    H,SECMAP
  197.     MVI    A,'W'        ;READ WRITE MAPPING FOR 51 SECTORS
  198.     CALL    STDMAP        ;DEFAULT STD SECTOR MAP FOR A:
  199.     LXI    H,SECMAP1
  200.     MVI    A,'W'        ;READ WRITE MAPPING FOR 51 SECTORS
  201.     CALL    STDMAP        ;DEFAULT STD SECTOR MAP FOR B:
  202.     INSTR    82H,40H,'NOFILL';NO FILL WITH E5 REQUEST
  203.     JNC    C5
  204.     MVI    A,0FFH
  205.     STA    NOFILL        ;SET SWITCH
  206. C5:    INSTR    82H,40H,'NOVER'    ;NO VERIFICATION REQUEST
  207.     JNC    C6
  208.     MVI    A,0FFH
  209.     STA    VERFLG        ;SET FLAG FOR NO VERIFICATION
  210. C6:    INSTR    82H,40H,'FORM'
  211.     JNC    C7
  212.     MVI    A,0FFH
  213.     STA    FORMSW        ;SET FORMAT SWITCH
  214. C7:    CALL    GETRK        ;GET TRACK SPECIFICATIONS IF ANY
  215.     INSTR    82H,40H,'COPY'    ;POSITION BUFFER POINTER AFTER 'COPY'
  216.     SCAN    ,40H        ;LOOK FOR START OF SOURCE IF ANY
  217.     JZ    C10
  218.     LXI    D,DSKNAME    ;DE POINTS TO TABLE OF NAMES
  219.     MVI    C,0        ;COUNT OF DRIVE NO
  220. CLX:    SAV
  221.     MVI    C,2        ;LENGTH OF NAME
  222.     MATCH            ;DOES IT MATCH
  223.     RES
  224.     JZ    C8
  225.     INR    C        ;INCR DRIVE NO
  226.     MOV    A,C        ;DRIVE NO TO A
  227.     CPI    4
  228.     JP    SCANERR
  229.     INX    D
  230.     INX    D        ;POINT TO NEXT NAME IN TABLE
  231.     JMP    CLX
  232. C8:    MOV    A,C        ;DRIVE NO TO A
  233.     STA    SOURCE        ;SAVE SOURCE
  234. C9:    INSTR    82H,40H,'TO'    ;DESTINATION MARKER
  235.     JNC    C10        ;NO TO USE DEFAULTS
  236.     CALL    GETDRV        ;LOOK FOR DESTINATION DRIVE
  237.     JNC    SCANERR        ;MISSING DEST IF NO CARRY
  238.     STA    DEST        ;SAVE DESTINATION
  239.     LXI    H,SOURCE    ;POINT TO SOURCE
  240.     CMP    M        ;CHECK IF SAME
  241.     JNZ    C10
  242.     PRINT    <CR,LF,'SOURCE AND DESTINATION DRIVE ARE THE SAME',CR,LF>
  243.     PRINT    <'IS THIS WHAT YOU WANT? (Y/N) '>
  244.     CALL    CHECKY
  245. C10:    CALL    CPYFORM
  246.     PRINT    <'DISK '>
  247.     LDA    SOURCE
  248.     CALL    PRNDRV
  249.     PRINT    <' TO DISK '>
  250.     LDA    DEST
  251.     CALL    PRNDRV
  252. UTX:    LDA    FORMSW        ;CHECK FORMAT SWITCH
  253.     ORA    A
  254.     JNZ    CFX        ;TO COPY FORMAT
  255.     INSTR    82H,40H,'USING'    ;GET FORMAT FROM DISK?
  256.     JNC    C10A
  257.     CALL    GETNUM        ;GET TRACK NUMBER
  258.     CALL    TRKTEST        ;MAKE SURE ITS OK
  259.     STA    TNUM        ;SAVE IT
  260.     LDA    DEST        ;DEST DRIVE
  261.     CALL    SELECT
  262.     CALL    HOME
  263.     LXI    H,SECMAP    ;POINT TO SECTOR MAP
  264.     LDA    TNUM        ;TRACK NUMBER
  265.     CALL    RDFORM        ;READ FORMAT
  266.     MOVE    SECMAP,SECMAP1,52    ;SAME MAP FOR BOTH
  267. C10A:    LDA    STRK
  268.     ORA    A
  269.     JNZ    C10B
  270.     LDA    ETRK
  271.     CPI    76
  272.     JZ    C10E
  273.     LXI    H,STRK
  274.     LDA    ETRK
  275.     CMP    M        ;IS THERE JUST ONE TRACK
  276.     JZ    C10B
  277.     PRINT    <'  TRACKS '>
  278.     JMP    C10C
  279. C10B:    PRINT    <'  TRACK '>
  280. C10C:    LHLD    STRK
  281.     DECOUT            ;PRINT STARTING TRACK
  282.     LDA    ETRK
  283.     LXI    H,STRK
  284.     CMP    M
  285.     JZ    C10E
  286.     PRINT    <' THRU '>
  287.     LHLD    ETRK
  288.     DECOUT            ;PRINT ENDING TRACK
  289. C10E:    PRINT    <CR,LF,'TYPE RETURN TO BEGIN COPY '>
  290.     CHARIN
  291.     CPI    3
  292.     JZ    ENDFIL        ;EXIT ON CONTROL C
  293.     LDA    SOURCE        ;HOME BOTH DRIVES
  294.     CALL    SELECT
  295.     CALL    HOME        ;HOME IT
  296.     LDA    DEST
  297.     CALL    SELECT
  298.     CALL    HOME        ;HOME IT
  299.     LDA    STRK        ;STARTING TRACK NO
  300.     STA    STRKR        ;SET STARTING TRACK FOR READ
  301.     STA    STRKW        ;SET STARTING TRACK FRO WRITE
  302. ;
  303. ;    START OF ACTUAL COPY LOOP
  304. ;
  305. C11:    LDA    SOURCE        ;SOURCE DRIVE
  306.     LXI    H,DEST
  307.     CMP    M        ;COMPARE
  308.     JNZ    C11A
  309.     PRINT    <CR,LF,'LOAD SOURCE DISK, TYPE RETURN '>
  310.     CHARIN
  311.     LDA    SOURCE
  312.     CALL    HOME
  313. C11A:    CALL    SELECT
  314.     LDA    DDFLG        ;DENSITY FLAG
  315.     STA    DENTEMP        ;TO TEMPORARY (FOR TRACK ZERO COPY)
  316.     LDA    STRKR        ;GET READ START
  317.     MOV    B,A        ;STARTING TRACK TO B
  318.     LDA    TRKLIM        ;TRACK LIMIT
  319.     MOV    C,A
  320.     LXI    D,TRKBUF    ;POINTS TO MEMORY BUFFER
  321. C12:    MOV    A,B        ;TRACK NO TO A
  322.     STA    TNUM        ;TRACK NUMBER FOR ERROR MESS
  323.     LXI    H,SECMAP    ;READ SECTOR MAP
  324.     ORA    A        ;TRACK ZERO
  325.     JNZ    C14
  326.     MVI    A,'S'
  327.     CALL    DENSEL        ;SELECT SINGLE DENSITY
  328.     LXI    H,SECMAP0    ;SECTOR MAP FOR TRACK 0
  329.     MOV    A,B        ;TRACK NO BACK TO A
  330. C14:    CALL    SEEK        ;GET PROPER TRACK
  331.     CALL    RDTRK        ;READ A TRACK INTO MEMORY
  332.     MOV    A,B        ;TRACK NO TO A
  333.     ORA    A        ;IS IT TRACK ZERO
  334.     JNZ    C15
  335.     LDA    DENTEMP        ;DENSITY TEMPORARY
  336.     ORA    A        ;GO ON IF SINGLE
  337.     JZ    C15
  338.     MVI    A,'D'
  339.     CALL    DENSEL        ;SELECT DOUBLE DENSITY
  340. C15:    LDA    ETRK        ;ENDING TRACK
  341.     LXI    H,SECMAP
  342.     CMP    B        ;COMPARE WITH START TRACK
  343.     JZ    C20        ;FINISHED READ
  344.     INR    B        ;INCREMENT TRACK
  345.     DCR    C        ;DECR TRACK LIMIT
  346.     JZ    C20        ;FINISHED READ
  347.     PUSH    H
  348.     LHLD    TRKSIZE
  349.     DAD    D        ;ADD OFFSET
  350.     XCHG
  351.     POP    H
  352.     LDA    CPYOFF        ;SECTOR OFFSET
  353. C16:    CALL    MAPSLEW        ;OFFSET SECTOR MAP FOR SPEED
  354.     JMP    C12        ;KEEP READING TRACKS
  355. C20:    MOV    A,B        ;LAST TRACK READ
  356.     STA    STRKR        ;SAVE FOR NEXT READ
  357.     LDA    DEST        ;DESTINATION DRIVE
  358.     LXI    H,SOURCE
  359.     CMP    M
  360.     JNZ    C21
  361.     PRINT    <CR,LF,'LOAD DESTINATION DISK, TYPE RETURN '>
  362.     CHARIN
  363.     LDA    DEST
  364.     CALL    HOME
  365. C21:    CALL    SELECT
  366.     LDA    STRKW        ;STARTING TRACK FOR WRITE
  367.     MOV    B,A
  368.     LDA    TRKLIM        ;MAX TRACKS THAT FIT IM MEMORY
  369.     MOV    C,A
  370.     LXI    D,TRKBUF    ;MEMORY BUFFER
  371. C22:    MOV    A,B        ;TRACK NO
  372.     STA    TNUM        ;SAVE FOR ERROR MESS
  373.     LXI    H,SECMAP1    ;WRITE SECTOR MAP
  374.     ORA    A
  375.     JNZ    C23        ;GO ON IF NOT TRACK ZERO
  376.     MVI    A,'S'
  377.     CALL    DENSEL        ;SELECT SINGLE DENSITY
  378.     MOV    A,B        ;TRACK NO BACK TO A
  379.     LXI    H,SECMAP0    ;TRACK ZERO SECTOR MAP
  380. C23:    CALL    SEEK
  381.     CALL    WRTRK        ;WRITE A TRACK
  382.     LXI    H,SECMAP1
  383.     MOV    A,B        ;TRACK NUMBER
  384.     ORA    A
  385.     JNZ    C23A        ;GO ON IF NOT TRACK ZERO
  386.     LDA    DENTEMP        ;DENSITY TEMPORARY
  387.     ORA    A
  388.     JZ    C23A
  389.     MVI    A,'D'
  390.     CALL    DENSEL        ;SELECT MFM
  391. C23A:    LDA    ETRK        ;ENDING TRACK NO
  392.     CMP    B
  393.     JZ    C40        ;ALL DONE WITH COPY
  394.     INR    B
  395.     DCR    C        ;DECR TRACK LIMIT
  396.     JZ    C30        ;FINISHED WRITE
  397.     PUSH    H
  398.     LHLD    TRKSIZE        ;FULL TRACK OFFSET
  399. C24:    DAD    D        ;ADD IT
  400.     XCHG
  401.     POP    H
  402.     LDA    CPYOFF        ;SECTOR OFFSET
  403. C26:    CALL    MAPSLEW
  404.     JMP    C22        ;KEEP WRITING TRACKS
  405. C30:    MOV    A,B        ;LAST TRACK WRITTEN
  406.     STA    STRKW        ;SAVE IT FOR NEXT TIME
  407.     JMP    C11        ;GO READ SOME MORE
  408. C40:    PRINT    <CR,LF,LF,'COPY COMPLETE'>
  409.     JMP    ENDFIL
  410. ;
  411. ;    THIS COPY FORMAT LOGIC JUMPS TO THE FORMAT ROUTINE
  412. ;
  413. CFX:    XRA    A        ;ZERO
  414.     STA    TNUM
  415.     INSTR    82H,40H,'USING'
  416.     JNC    CFX1
  417.     CALL    GETNUM        ;TRACK NUMBER
  418.     CALL    TRKTEST        ;CHECK IT
  419.     STA    TNUM
  420. CFX1:    LDA    SOURCE
  421.     CALL    SELECT        ;SOURCE DRIVE HAS FORMAT
  422.     CALL    HOME
  423.     LXI    H,SECMAP
  424.     LDA    TNUM
  425.     CALL    RDFORM        ;READ FORMAT INTO SECMAP
  426.     LDA    DEST
  427.     STA    NEWDRV        ;NEW DRIVE NUMBER
  428.     LXI    H,SECMAP    ;CHECK SECTORS READ FROM DISK
  429.     MVI    C,26        ;SECTOR COUNT
  430. CFX3:    MOV    A,M        ;GET A SECTOR
  431.     ORA    A
  432.     JM    CFX4        ;ERROR IF MINUS
  433.     JZ    CFX4        ;ERROR IF ZERO
  434.     CPI    27
  435.     JP    CFX4        ;ERROR IF > 26
  436.     INX    H
  437.     DCR    C        ;DECR SECTOR COUNT
  438.     JNZ    CFX3        ;LOOP FOR 26 SECTORS
  439.     PRINT    <CR,LF,LF,'     FORMAT READ FROM SOURCE DISK'>
  440.     CALL    RDISP        ;DISPLAY IT
  441.     PRINT    <CR,LF,LF>
  442.     JMP    FMNS        ;TO FORMAT ROUTINE
  443. CFX4:    PRINT    <'INCORRECT SECTOR NUMBER READ FROM SOURCE DISK',CR,LF>
  444.     CALL    RDISP
  445.     JMP    ENDFIL        ;BACK TO INPUT ROUTINES
  446. ;
  447. ;
  448. ;    CPYFORM LOGIC FOR COPYING FORMAT RATHER THAN DATA
  449. ;
  450. CPYFORM:PRINT<CR,LF,LF,'COPYING '>
  451.     LDA    FORMSW        ;SWITCH ON IF FORMAT
  452.     ORA    A
  453.     JZ    CP3
  454.     PRINT    <'FORMAT FROM '>
  455. CP3:    RET
  456. ;
  457. ;    DISPLAY DISK SECTOR MAPPING
  458. ;
  459. MAP:    XRA    A
  460.     STA    TNUM        ;SELECT TRACK ZERO
  461.     LXI    H,82H        ;POINT TO START OF INPUT BUFFER
  462.     CALL    GETDRV        ;CHECK IF NEW DRIVE REQUESTED
  463.     JNC    MAP3
  464.     STA    NEWDRV
  465. MAP3:    CALL    GETRK        ;READ TRACK SPECS IF ANY
  466.     STA    TNUM        ;SAVE TRACK NUMBER
  467. MAP4:    LDA    NEWDRV        ;SELECTED DRIVE
  468.     CALL    SELECT
  469.     LDA    TNUM        ;GET BACK TRACK NO
  470.     LXI    H,SECMAP    ;POINT TO SECTOR TABLE
  471.     CALL    RDFORM        ;READ TRACK FORMAT
  472.     CALL    CLEAR        ;CLEAR SCREEN
  473.     PRINT    <CR,LF,'      SECTOR FORMAT DRIVE '>
  474.     LDA    NEWDRV        ;GET DRIVE NO
  475.     CALL    PRNDRV        ;PRINT DRIVE NAME
  476. MAP5:    PRINT    <' TRACK '>
  477. MAP6:    LHLD    TNUM
  478.     DECOUT            ;CONVERT TO DECIMAL AND PRINT
  479.     PRINT    <CR,LF>
  480.     CALL    RDISP        ;DISPLAY SECTOR MAP
  481.     JMP    ENDFIL        ;BYE
  482. ;
  483. ;    DISK VALIDATION ROUTINES
  484. ;
  485. DVALID:    MVI    A,0FFH
  486.     STA    DDFLG        ;SET DOUBLE DENSITY
  487. ;
  488. VALID:    LXI    H,82H        ;POINT TO START OF INPUT BUFFER
  489.     CALL    GETDRV        ;CHECK NEW DRIVE NUMBER
  490.     JNC    VDD0
  491.     STA    NEWDRV        ;SAVE NEW DRIVE NO
  492. VDD0:    MVI    A,0FFH        ;SET SWITCH FOR STD FORMAT
  493.     STA    TNUM        ;SELECT TRACK 0
  494.     LDA    DDFLG        ;DENSITY SWITCH
  495.     ORA    A
  496.     JZ    VDX
  497.     MVI    A,'D'
  498.     CALL    DENSEL        ;SELECT DOUBLE DENSITY
  499. VDX:    INSTR    82H,40H,'USING'
  500.     JNC    VALID0
  501.     CALL    GETNUM
  502.     CALL    TRKTEST        ;CHECK FOR GOOD TRACK NUMBER
  503.     STA    TNUM        ;SET TRACK NUMBER
  504. VALID0:    LDA    NEWDRV
  505. REVAL:    CALL    SELECT
  506.     CALL    HOME
  507.     LDA    DDFLG        ;DENSITY FLAG
  508.     STA    DENTEMP        ;TO TEMPORARY FOR TRACK ZERO READ
  509.     LXI    H,SECMAP    ;POINT TO SECTOR TABLE
  510.     LDA    TNUM        ;CHECK TRACK NUMBER
  511.     ORA    A        ;0FFH IF DEFAULT TO STD FORMAT
  512.     JP    VD1        ;READ SECTOR FORMAT FROM DISK
  513.     XRA    A        ;READ ONLY MAPPING 51 SECTORS
  514.     CALL    STDMAP        ;OTHERWISE USE STANDARD FORMAT
  515.     JMP    VD2
  516. VD1:    CALL    RDFORM        ;GET SECTOR MAPPING FROM TRACK TNUM
  517. VD2:    XRA    A
  518.     STA    HARDERR        ;ZERO ERROR COUNTERS
  519.     STA    SOFTERR
  520.     STA    TNUM        ;START WITH TRACK ZERO
  521.     LXI    H,SECMAP0    ;SECTOR MAP FOR TRACK 0
  522.     MVI    A,'S'
  523.     CALL    DENSEL        ;SELECT SINGLE DENSITY
  524. VALID1:    LDA    TNUM        ;GET A TRACK NUMBER
  525.     LXI    D,TRKBUF    ;TRACK BUFFER
  526.     CALL    RDTRK        ;VALIDATE THE TRACK
  527.     LXI    H,SECMAP    ;STANDARD SECTOR MAP
  528.     LDA    TNUM        ;TRACK NUMBER
  529.     ORA    A        ;TRACK 0
  530.     JNZ    VALIDP        ;SKIP IF NOT TRACK ZERO
  531.     LDA    DENTEMP        ;DENSITY TEMPORARY
  532.     ORA    A
  533.     JZ    VALIDO
  534.     MVI    A,'D'
  535.     CALL    DENSEL        ;SELECT DOUBLE DENSITY
  536. VALIDO:    LDA    TNUM        ;LOAD TRACK NO
  537. VALIDP:    CPI    76        ;FINISHED 76 TRACKS?
  538.     JZ    VALID2
  539.     INR    A        ;INCREMENT TRACK COUNT
  540.     STA    TNUM        ;STORE IT BACK
  541.     CALL    SEEK        ;STEP TO NEXT TRACK
  542.     LDA    SECSIZ        ;SECTOR SIZE CODE
  543.     CPI    2        ;CHECK 512
  544.     JNZ    VALIDR
  545.     MVI    A,3
  546.     JMP    VALIDD
  547.     IF    DELTA OR TARBELL
  548. VALIDR:    MVI    A,6+STEP
  549.     ELSE
  550. VALIDR:    MVI    A,5+STEP
  551.     ENDIF
  552. VALIDD:    MOV    B,A        ;OFFSET TO B
  553.     LDA    DDFLG
  554.     ORA    A
  555.     MOV    A,B        ;MOVE OFFSET BACK
  556.     JZ    VALIDS
  557.     ADD    A        ;DOUBLE OFFSET
  558.     DCR    A        ;SUBTRACT 1
  559.     MOV    B,A
  560.     LDA    SECSIZ        ;SECTOR SIZE CODE
  561.     ORA    A
  562.     MOV    A,B        ;MOVE OFFSET BACK
  563.     JZ    VALIDS
  564.     DCR    A        ;SUBTRACT 1
  565. VALIDS:    LXI    H,SECMAP    ;POINT TO SECTOR MAP
  566.     CALL    MAPSLEW        ;PRECESS IT 5 + STEP SECTORS
  567.     LXI    H,SECMAP
  568.     CALL    CHECKC        ;ABORT ON CONTROL C
  569.     JMP    VALID1        ;LOOP FOR 76 TRACKS
  570. VALID2:    LDA    HARDERR        ;CHECK ERRORS
  571.     ORA    A
  572.     JNZ    VALID8        ;HARD ERRORS HERE
  573.     PRINT    <CR,LF,'SUCCESSFUL VALIDATION DRIVE '>
  574. VALID3:    LDA    NEWDRV        ;GET DRIVE NUMBER
  575.     CALL    PRNDRV        ;PRINT DRIVE NAME
  576. VALID6:    LDA    SOFTERR        ;SOFT ERRORS
  577.     ORA    A
  578.     JZ    ENDFIL
  579.     DCR    A        ;CHECK FOR SINGLE SOFT ERROR
  580.     JZ    VALID12
  581.     PRINT    <CR,LF,LF,'THERE WERE '>
  582.     LHLD    SOFTERR        ;PRINT SOFT ERRORS
  583.     DECOUT            ;PRINT ERRORS IN DECIMAL
  584.     PRINT    <' RETRYS'>
  585. VALIDX:    LDA    HARDERR
  586.     ORA    A        ;CHECK NO OF HARD ERRORS
  587.     JZ    ENDFIL        ;RET FOR MORE INPUT IF NONE
  588.     PRINT    <' AND '>
  589.     LHLD    HARDERR
  590.     DECOUT            ;PRINT HARD ERRORS IN DECIMAL
  591.     LDA    HARDERR
  592.     DCR    A
  593.     JZ    VALID9
  594. VALID7:    PRINT    <' HARD ERRORS'>
  595.     JMP    ENDFIL        ;BACK FOR MORE INPUT
  596. VALID8:    PRINT    <CR,LF,'VALIDATION ERROR DRIVE '>
  597.     JMP    VALID3
  598. VALID9:    PRINT    <' HARD ERROR'>
  599.     JMP    ENDFIL
  600. VALID12:PRINT    <CR,LF,'THERE WAS 1 RETRY'>
  601.     JMP    VALIDX
  602. ;
  603. ;
  604. ;
  605. ;    DISK FORMATTING ROUTINES
  606. ;
  607. DFORMAT:MVI    A,0FFH        ;SET FLAG
  608.     STA    DDFLG
  609.     JMP    FM00
  610. ;
  611. ;
  612. FORMAT:
  613.     LDA    DDFLG        ;DOUBLE DENSITY?
  614.     ORA    A
  615.     JZ    FM1        ;DEFAULT SINGLE DENSITY IF ZERO
  616. FM00:    MVI    A,'D'
  617.     CALL    DENSEL        ;SELECT DOUBLE DENSITY
  618. FM1:    CALL    GETRK        ;GET TRACK SPECS
  619.     LXI    H,82H        ;POINT TO START OF INPUT BUFFER
  620.     CALL    GETDRV        ;GET DRIVE NUMBER
  621.     JNC    FM3
  622.     STA    NEWDRV
  623. FM3:    INSTR    82H,40H,'SKEW'    ;FIXED SKEW FACTOR?
  624.     JC    SKEW        ;GO DO IT
  625.     INSTR    82H,40H,'SPEC'    ;SPECIAL FORMAT?
  626.     JC    SPF
  627.     LDA    DDFLG        ;DENSITY SWITCH
  628.     ORA    A
  629.     JNZ    FM3A
  630.     LDA    SECSIZ        ;CHECK IF STANDARD FORMAT
  631.     ORA    A
  632.     JZ    FM4        ;STD IF ZERO
  633. FM3A:    PRINT    <CR,LF,LF,'FORMAT WITH '>
  634.     DECOUT    BYTES        ;NUMBER OF BYTES PER SECTOR
  635.     PRINT    <' BYTES PER SECTOR',CR,LF>
  636.     LDA    DDFLG
  637.     ORA    A
  638.     JZ    FM3C
  639.     PRINT    <'DOUBLE DENSITY '>
  640.     DECOUT    DNUMSEC
  641.     JMP    FM3E
  642. FM3C:    PRINT    <'SINGLE DENSITY '>
  643.     LDA    NUMSEC
  644.     MOV    L,A
  645.     MVI    H,0
  646.     DECOUT
  647. FM3E:    PRINT    <' SECTORS PER TRACK',CR,LF,LF>
  648.     JMP    FM5
  649. FM4:    PRINT    <CR,LF,LF>
  650.     PRINT    <'STANDARD IBM 3740 FORMAT',CR,LF,LF>
  651. FM5:    LXI    H,SECMAP    ;POINT TO SECTOR MAP
  652.     CALL    STDMAP        ;SET UP STANDARD MAPPING
  653. FMNS:    INSTR    82H,40H,'OFFSET';TRACK OFFSET?
  654.     JNC    FM0
  655.     CALL    GETNUM        ;GET OFFSET
  656.     STA    OFFSET        ;SAVE IT
  657. FM0:    PRINT    <'INSERT DISK TO BE FORMATTED IN DRIVE '>
  658.     LDA    NEWDRV
  659.     CALL    PRNDRV        ;PRINT DRIVE LETTER
  660.     PRINT    <CR,LF,'TYPE CARRIAGE RETURN '>
  661. FM6:    CHARIN            ;WAIT FOR CHARACTER INPUT (ANY WILL DO)
  662.     CPI    3
  663.     JZ    ENDFIL        ;TRAP OUT ON CONTROL C
  664. FM7:    LDA    NEWDRV
  665.     CALL    SELECT
  666.     CALL    DOFORM
  667.     MVI    A,0FFH        ;SET SWITCH TO SUPRESS READ FORMAT
  668.     STA    TNUM        ;MOVE STARTING TRACK NUMBER
  669.     LDA    VALFLG        ;CHECK VALIDATION SWITCH
  670.     ORA    A
  671.     JNZ    ENDFIL        ;IF NOT ZERO NO VALIDATION
  672.     JMP    VALID0        ;NOW VALIDATE DISK JUST TO MAKE SURE
  673. ;
  674. SPF:    PRINT    <CR,LF,LF,'INPUT SPECIAL SECTOR FORMAT',CR,LF,LF>
  675.     PRINT    <'PHYSICAL   LOGICAL',CR,LF,' SECTOR    SECTOR',CR,LF>
  676.     FILL    SECMAP,SECMAP+27
  677.     LXI    H,SECMAP    ;POINTS TO SECTOR TABLE
  678.     MVI    C,1        ;SECTOR COUNT
  679.     MVI    B,26        ;SECTOR LIMIT
  680. SPF2:    MOV    A,C        ;PSEC TO A
  681.     STA    PSEC        ;READY FOR CONVERSION
  682.     SAV            ;PUSH REGS
  683.     PRINT    <CR,LF,'     '>
  684.     LDA    PSEC
  685.     CPI    10
  686.     JP    SPF3        ;LINE UP COLUMNS
  687.     PRINT    SPACE,$
  688. SPF3:    DECOUT    PSEC        ;CONVERT AND PRINT NUMBER
  689.     PRINT    <'      '>    ;SOME SPACES
  690.     FILL    80H,90H        ;ZERO BUFFER
  691.     INPUT    80H        ;INPUT THE LOGICAL SECTOR
  692.     LXI    H,82H        ;START OF BUFFER
  693.     CALL    GETNUM        ;GET SECTOR
  694.     CALL    SECERR        ;CHECK FOR ERRORS
  695.     RES
  696.     JC    SPF2        ;DO THAT ONE OVER
  697.     MOV    M,A        ;CONVERTED LSEC TO TABLE
  698.     INX    H
  699.     INR    C        ;INCR COUNTERS
  700.     DCR    B
  701.     JNZ    SPF2        ;LOOP FOR 26 SECTORS
  702.     CALL    CLEAR        ;CLEAR SCREEN
  703.     CALL    RDISP        ;REDISPLAY SECTOR MAP
  704. RD6:    PRINT    <CR,LF,LF,LF,'TYPE RETURN TO FORMAT, SECTOR NO TO CORRECT '>
  705.     FILL    80H,90H        ;ZERO BUFFER
  706.     INPUT    80H
  707.     LDA    81H        ;NO OF CHAR TYPED IN
  708.     ORA    A
  709.     JNZ    RD8        ;CORRECT INPUT
  710.     PRINT    <CR,LF,LF,'WRITING NON STANDARD FORMAT ON DISK',CR,LF,LF>
  711.     JMP    FMNS        ;TO FORMAT ROUTINE
  712. RD8:    LXI    H,82H        ;POINT TO START OF BUFFER
  713.     CALL    GETNUM        ;GET SECTOR
  714.     STA    PSEC        ;SAVE PHYSICAL SECTOR
  715.     PRINT    <CR,LF,LF>
  716.     PRINT    <'PHYSICAL  LOGICAL',CR,LF,' SECTOR   SECTOR',CR,LF,'   '>
  717.     DECOUT    PSEC
  718.     PRINT    <'      '>
  719.     FILL    80H,90H
  720.     INPUT    80H
  721.     LXI    H,82H
  722.     CALL    GETNUM        ;LSEC
  723.     ORA    A
  724.     JZ    RD9        ;ALLOW ZERO SECTOR HERE FOR ERROR CORRECTION
  725.     CALL    SECERR        ;CHECK FOR ERRORS
  726.     JC    RD6        ;BACK FOR MORE INPUT
  727. RD9:    LXI    H,SECMAP
  728.     MOV    B,A        ;SAVE LSEC IN B
  729.     LDA    PSEC        ;GET BACK PSEC
  730.     MOV    E,A        ;OFFSET TO E
  731.     MVI    D,0        ;ZERO D
  732.     DAD    D        ;ADD IN OFFSET
  733.     DCX    H        ;BACK UP ONE (TABLE STARTS AT ZERO)
  734.     MOV    M,B        ;LOGICAL SECTOR NO TO TABLE
  735.     CALL    CLEAR        ;CLEAR SCREEN
  736.     CALL    RDISP        ;REDISPLAY
  737.     JMP    RD6        ;CONTINUE
  738. ;
  739. ;    STDMAP SET UP SECTOR MAP POINTED TO BY HL WITH STANDARD FORMAT
  740. ;
  741. STDMAP:
  742.     SAVE
  743.     MOV    C,A        ;READ WRITE CODE TO C (W=WRITE)
  744.     LDA    NUMSEC        ;NUMBER OF SECTORS
  745.     MOV    B,A        ;TO B
  746.     LDA    DDFLG        ;DENSITY FLAG
  747.     ORA    A
  748.     JZ    STDMAP1
  749.     LDA    DNUMSEC        ;NUMBER SECTORS DD
  750.     MOV    B,A
  751.     CPI    51
  752.     JZ    STDMAP2        ;INTERLEAVE FOR 128 BYTE SECTORS
  753. STDMAP1:MVI    C,1        ;SECTOR COUNT
  754. STD1:    MOV    M,C        ;MOVE SECTOR NO TO TABLE
  755.     INX    H
  756.     INR    C        ;INCR SEC NO AND TABLE POINTER
  757.     DCR    B        ;SECTOR COUNT
  758.     JNZ    STD1        ;LOOP FOR NUMSEC SECTORS
  759.     JMP    STD6
  760. STDMAP2:LXI    D,DDMAP        ;POINT TO DOUBLE DENSITY MAP
  761.     MOV    A,C        ;GET BACK READ WRITE CODE
  762.     CPI    'W'        ;IS IT WRITE
  763.     JNZ    STD4
  764.     LXI    D,DDMAP1
  765. STD4:    LDAX    D
  766.     MOV    M,A        ;MOVE SECTOR NO
  767.     INX    D
  768.     INX    H        ;INCR POINTERS
  769.     DCR    B        ;DECR COUNT
  770.     JNZ    STD4
  771. STD6:    RES
  772.     RET
  773. ;
  774. ;    SKEW ROUTINE ASSIGNS A SPECIFIED CONSTANT (MORE OR LESS) INTERVAL
  775. ;    BETWEEN SECTORS
  776. ;
  777. SKEW    CALL    GETNUM        ;SKEW FACTOR
  778.     STA    SKF        ;SAVE IT
  779.     FILL    SECMAP,SECMAP+27    ;INITIALIZE MAP TO ZERO
  780.     MVI    B,1        ;CURRENT SECTOR NUMBER
  781.     LXI    H,SECMAP    ;POINTS TO SECTOR MAP
  782.     MVI    C,26        ;MAX SECTOR COUNT
  783.     LDA    SKF        ;GET BACK SKEW FACTOR
  784.     MOV    D,A        ;SAVE IT IN D
  785. SKEW1:    MOV    A,B        ;GET THE SECTOR NUMBER
  786.     CALL    SRTAB        ;IS IT ALREADY IN THE TABLE
  787.     JNC    SKEW4        ;OK TO USE IT IF NO CARRY
  788.     INR    A        ;INCR BY ONE
  789.     CALL    MOD26        ;MAKE SURE ITS NOT > 26
  790. SKEW4:    MOV    M,A        ;SAVE IT IN TABLE
  791.     INX    H        ;INCR TABLE POINTER
  792.     MOV    A,D        ;SKEW FACTOR
  793.     ADD    B        ;ADD PRESENT SECTOR NO
  794.     CALL    MOD26        ;COMPUTE VALUE MOD 26
  795.     MOV    B,A        ;PUT IT BACK IN B
  796.     DCR    C        ;DECR SECTOR COUNT
  797.     JNZ    SKEW1        ;LOOP FOR 26 SECTORS
  798.     CALL    RDISP        ;REDISPLAY MAP WHEN FINISHED
  799.     JMP    RD6        ;CONTINUE
  800. ;
  801. ;    MOD26 ROUTINE COMPUTES A SECTOR NUMBER MOD 26
  802. ;
  803. MOD26:    CPI    27        ;IS SECTOR NO > 26
  804.     RM            ;RETURN IF NOT
  805.     SBI    26        ;SUBTRACT 26
  806.     RET
  807. ;
  808. ;    REDISPLAY SECTOR MAPPING
  809. ;
  810. RDISP:    PRINT    <CR,LF,'             SECTOR MAPPING',CR,LF,LF>
  811.     PRINT    <'PHYSICAL  LOGICAL     PHYSICAL  LOGICAL',CR,LF>
  812.     PRINT    <' SECTOR   SECTOR       SECTOR   SECTOR',CR,LF>
  813.     LXI    H,SECMAP
  814.     MVI    B,13
  815.     MVI    C,1
  816. RD1:    SAV            ;SAVE REGISTERS
  817.     MOV    A,C        ;PHYSICAL SECTOR
  818.     STA    PSEC        ;READY FOR CONVERSION
  819.     ADI    13        ;INCR BY 13
  820.     STA    PSEC1        ;PHYSICAL SECTOR SECOND COL
  821.     MOV    A,M        ;GET LOGICAL SECTOR
  822.     STA    LSEC
  823.     LXI    D,13
  824.     DAD    D        ;
  825.     MOV    A,M        ;GET LOGICAL SECTOR FOR SECOND COL
  826.     STA    LSEC1        ;STORE FOR CONVERSION
  827.     PRINT    <CR,LF,'    '>
  828.     LDA    PSEC
  829.     CPI    10
  830.     JP    RD2
  831.     PRINT    SPACE,$        ;ADJUST COL SPACING
  832. RD2:    DECOUT    PSEC        ;PRINT PSEC
  833.     PRINT    <'     '>
  834.     LDA    LSEC
  835.     CPI    10
  836.     JP    RD3
  837.     PRINT    SPACE,$
  838. RD3:    LDA    LSEC
  839.     ORA    A
  840.     JNZ    RD13
  841.     PRINT    <'-'>
  842.     JMP    RD14
  843. RD13:    DECOUT    LSEC        ;PRINT LSEC
  844. RD14:    PRINT    <'             '>
  845.     LDA    PSEC1
  846.     CPI    10
  847.     JP    RD4
  848.     PRINT    SPACE,$
  849. RD4:    DECOUT    PSEC1        ;SECOND PHYSICAL SECTOR
  850.     PRINT    <'     '>
  851.     LDA    LSEC1
  852.     CPI    10
  853.     JP    RD5
  854.     PRINT    SPACE,$
  855. RD5:    LDA    LSEC1
  856.     ORA    A
  857.     JNZ    RD15
  858.     PRINT    <'-'>
  859.     JMP    RD16
  860. RD15:    DECOUT    LSEC1        ;SECOND LOGICAL SECTOR
  861. RD16:    RES
  862.     INX    H        ;TABLE POINTER
  863.     INR    C        ;PSEC NUMBER
  864.     DCR    B        ;LINE COUNT
  865.     JNZ    RD1        ;LOOP FOR 13 LINES
  866.     RET
  867. ;
  868. ;    DISK FORMATTING ROUTINES. THREE SECTOR SIZES ARE AVAILABLE BOTH
  869. ;    SINGLE AND DOUBLE DENSITY, 128, 256, AND 512 BYTES. THE NUMBER
  870. ;    OF SECTORS IS AS FOLLOWS:
  871. ;
  872. ;        SINGLE DENSITY (FM)    DOUBLE DENSITY (MFM)
  873. ;    128        26            51
  874. ;    256        16            26
  875. ;    512         8            16
  876. ;
  877. DOFORM:    LDA    DDFLG        ;DOUBLE DENSITY FLAG
  878.     ORA    A
  879.     JZ    DOFORM2
  880. ;
  881. ;    START OF DOUBLE DENSITY FORMAT ROUTINE
  882. ;
  883. DOFORM1:CALL    HOME
  884.     LDA    SECSIZ
  885.     CPI    2
  886.     JNZ    DD1
  887.     LDA    OFFSET        ;SECTOR OFFSET
  888.     ORA    A
  889.     JNZ    DD1
  890.     MVI    A,15        ;SET DEFAULT OFFSET TO 15
  891.     STA    OFFSET
  892. DD1:    LDA    STRK        ;STARTING TRACK
  893.     STA    TRK        ;TO TEMPORARY
  894.     ORA    A
  895.     CZ    TRKZERO        ;FORMAT TRACK ZERO SINGLE DENSITY
  896.     CALL    SEEK        ;SEEK TRACK IN A REGISTER
  897. NEXTT:    LXI    H,TRKBUF    ;POINT TO TRACK BUFFER
  898.     CALL    DINDX
  899.     LDA    DNUMSEC
  900.     STA    FSECT        ;NUMBER OF SECTORS
  901. DOF1D:    CALL    DADDR
  902.     CALL    DDAT
  903.     LDA    FSECT
  904.     DCR    A
  905.     STA    FSECT
  906.     JNZ    DOF1D
  907.     CALL    FILBUF
  908. DOF3D:    LHLD    DFILOFF        ;SECTOR OFFSET
  909.     SHLD    FOFF        ;TO TEMPORARY
  910. DOF4D:    LXI    H,TRKBUF    ;POINT TO FORMAT BUFFER
  911.     CALL    DFILADR        ;PLACE TRACK AND SECTOR NUMBERS IN BUFFER
  912. DOF5D:    LXI    D,TRKBUF    ;POINT TO TRACK BUFFER
  913.     LXI    H,WLOOP        ;LOOP JUMP ADDR
  914.     MVI    A,0F4H        ;TRACK WRITE COMMAND
  915.     OUT    DCOM        ;ISSUE IT
  916.     CALL    WLOOP        ;WRITE FORMAT
  917. DONEITD:XTHL
  918.     XTHL
  919.     IN    STATP        ;READ STATUS
  920.     ANI    0FFH        ;TEST IT
  921.     JNZ    ERRMSG        ;ERROR HERE
  922.     LDA    TRK        ;TRACK NO
  923.     INR    A        ;INCREMENT IT
  924.     STA    TRK
  925.     MOV    C,A        ;STORE TEMPORARILY IN C
  926.     LDA    ETRK        ;END TRK
  927.     CMP    C        ;COMPARE
  928.     RM            ;RETURN IF MINUS
  929. INCTRKD:MVI    A,59H        ;STEP COMMAND
  930.     OUT    DCOM        ;ISSUE IT
  931.     IN    WAIT
  932.     IF    PERSCI
  933.     LXI    H,0FFFH        ;DELAY CONST
  934.     MVI    A,1        ;PERSCI STEP COMMAND
  935.     OUT    WAIT
  936. LLLD:    DCX    H        ;DECR COUNT
  937.     MOV    A,H
  938.     ORA    L
  939.     JNZ    LLLD        ;LOOP
  940.     ENDIF
  941.     CALL    CHECKC        ;ABORT ON CONTROL C
  942.     LDA    OFFSET        ;OFFSET NEXT TRACK
  943.     ORA    A
  944.     JZ    DOF4D
  945.     LXI    H,SECMAP    ;SECTOR MAP
  946.     CALL    MAPSLEW
  947.     JMP    NEXTT
  948. ;
  949. ;    WLOOP  -  FAST OUTPUT LOOP FOR DOUBLE DENSITY FORMATTING
  950. ;      ASSUMES HL COTAINS JMP TO START OF LOOP AND TOP OF STACK
  951. ;      RETURN ADDR.  LOOP RUNS IN 58 T-STATES OR 14.5 USEC AT 4 MHZ
  952. ;
  953. WLOOP:    IN    WAIT        ;WAIT FOR INTRQ OR DRQ
  954.     ORA    A        ;SET FLAGS
  955.     RP            ;RETURN ON INTRQ (FAST TEST IF NO RET)
  956.     LDAX    D        ;GET A BYTE
  957.     OUT    DDATA        ;OUTPUT IT
  958.     INX    D        ;INCR POINTER
  959.     PCHL            ;FAST JUMP IF HL CONTAINS JUMP ADDR
  960. ;
  961. TRKZERO:LDA    ETRK        ;END TRACK
  962.     PUSH    PSW        ;SAVE IT ON STACK
  963.     XRA    A        ;ZERO
  964.     STA    ETRK        ;JUST DO ONE TRACK
  965.     LDA    DDFLG        ;DENSITY FLAG
  966.     STA    DENTEMP        ;TO TEMPORARY
  967.     LDA    SECSIZ        ;SECTOR SIZE CODE
  968.     STA    SIZTEMP        ;TO TEMPORARY
  969.     LDA    NUMSEC        ;NUMBER OF SECTORS PER TRACK
  970.     STA    SECTEMP
  971.     MVI    A,26
  972.     STA    NUMSEC        ;SET NUMBER OF SECTORS TO 26
  973.     LHLD    BYTES        ;NUMBER OF BYTES PER SECTOR
  974.     SHLD    BYTETEMP    ;SAVE IT
  975.     LXI    H,128
  976.     SHLD    BYTES        ;SET BYTES TO 128
  977.     LDA    GAP        ;INTER SECTOR GAP
  978.     STA    GAPTEMP
  979.     MVI    A,27
  980.     STA    GAP
  981.     LHLD    FILOFF        ;OFFSET
  982.     SHLD    OFFTEMP
  983.     LXI    H,183
  984.     SHLD    FILOFF
  985.     XRA    A
  986.     STA    SECSIZ        ;SECTOR SIZE 0
  987.     MVI    A,'S'
  988.     CALL    DENSEL        ;SELECT SINGLE DENSITY
  989.     LXI    H,SECMAP
  990.     CALL    STDMAP        ;SINGLE DENSITY STD MAP
  991.     LDA    DENTEMP        ;DENSITY FLAG
  992.     ORA    A
  993.     MVI    A,10H        ;DOUBLE DENSITY
  994.     JNZ    TZ2
  995.     MVI    A,20H
  996. TZ2:    MOV    B,A        ;SAVE IT IN B
  997.     LDA    SIZTEMP
  998.     ORA    B        ;OR WITH B
  999.     STA    CODE        ;SAVE IN CODE
  1000.     CPI    10H        ;128 BYTE DOUBLE DENSITY
  1001.     JNZ    TZ4
  1002.     LDA    DENCODE
  1003.     STA    CODE
  1004. TZ4:    CALL    NEXTONE        ;SINGLE DENSITY FORMAT
  1005.     LDA    SIZTEMP
  1006.     STA    SECSIZ        ;RESTORE SECTOR SIZE
  1007.     LDA    SECTEMP
  1008.     STA    NUMSEC        ;RESTORE NUMBER OF SECTORS
  1009.     LHLD    BYTETEMP
  1010.     SHLD    BYTES        ;RESTORE NUMBER OF BYTES
  1011.     LDA    GAPTEMP
  1012.     STA    GAP        ;RESTORE GAP
  1013.     LHLD    OFFTEMP
  1014.     SHLD    FILOFF        ;RESTORE OFFSET
  1015.     LDA    DENTEMP
  1016.     ORA    A
  1017.     JZ    TRKZ1
  1018.     MVI    A,'D'
  1019.     CALL    DENSEL        ;SELECT DOUBLE DENSITY
  1020. TRKZ1:    LXI    H,SECMAP
  1021.     CALL    STDMAP        ;DOUBLE DENSITY STD MAP
  1022.     MVI    A,59H        ;STEP COMMAND
  1023.     OUT    DCOM
  1024.     IN    WAIT
  1025.     POP    PSW        ;GET BACK OLD END TRACK
  1026.     STA    ETRK        ;RESTORE IT
  1027.     MVI    A,1        ;START DOUBLE DENSITY ON TRACK 1
  1028.     STA    TRK        ;SET TRACK TO ONE
  1029.     RET
  1030. ;
  1031. ;
  1032. ;
  1033. ;    START OF SINGLE DENSITY FORMAT ROUTINE
  1034. ;
  1035. ;
  1036. DOFORM2:CALL    HOME        ;HOME SELECTED DRIVE
  1037.     LDA    STRK        ;STARTING TRACK
  1038.     STA    TRK        ;TO TEMPORARY
  1039.     ORA    A
  1040.     CZ    TRKZERO        ;FORMAT TRACK ZERO STANDARD 3740 FORMAT
  1041.     CALL    SEEK        ;SEEK TRACK IN A
  1042. NEXTONE:LXI    H,TRKBUF    ;POINT TO TRACK BUFFER
  1043.     CALL    INDX
  1044.     LDA    NUMSEC
  1045.     STA    FSECT        ;STORE IT
  1046. DOF1:    CALL    ADDR
  1047.     CALL    DATA
  1048.     LDA    FSECT
  1049.     DCR    A        ;DECR SECTOR COUNT
  1050.     STA    FSECT
  1051.     JNZ    DOF1
  1052.     CALL    FILBUF        ;FILL END OF BUFFER WITH FF'S
  1053. DOF3:    LHLD    FILOFF        ;SECTOR OFFSET
  1054.     SHLD    FOFF        ;TO TEMPORARY
  1055. DOF4:    LXI    H,TRKBUF    ;POINT TO FORMAT BUFFER
  1056.     CALL    FILADR        ;PLACE TRACK AND SECTOR NUMBERS IN BUFFER
  1057.     LDA    TRK        ;CHECK FOR TRACK ZERO
  1058.     ORA    A
  1059.     JNZ    DOF5
  1060.     LDA    CODE        ;DENSITY AND SECTOR SIZE CODE
  1061.     STA    TRKBUF+229    ;FOR BOTH DELTA AND TARBELL
  1062.     STA    TRKBUF+230    ;TRACK ZERO SECTOR ONE ONLY
  1063. DOF5:    LXI    H,TRKBUF    ;POINT TO TRACK BUFFER
  1064.     MVI    A,0F4H        ;TRACK WRITE COMMAND
  1065.     OUT    DCOM        ;ISSUE IT
  1066. DOF7:    IN    WAIT        ;WAIT FOR INTERRUPT
  1067.     ORA    A        ;SET FLAGS
  1068.     JP    DONEIT        ;INTERRUPT
  1069.     MOV    A,M        ;GET A BYTE
  1070.     OUT    DDATA        ;SEND IT
  1071.     INX    H        ;INCR BUFFER POINTER
  1072.     JMP    DOF7        ;LOOP TILL INTRQ
  1073. DONEIT:    XTHL
  1074.     XTHL
  1075.     IN    STATP        ;READ STATUS
  1076.     ANI    0FFH        ;TEST IT
  1077.     JNZ    ERRMSG        ;ERROR HERE
  1078.     LDA    TRK        ;TRACK NO
  1079.     INR    A        ;INCREMENT IT
  1080.     STA    TRK
  1081.     MOV    C,A        ;STORE TEMPORARILY IN C
  1082.     LDA    ETRK        ;END TRK
  1083.     CMP    C        ;COMPARE
  1084.     RM            ;RETURN IF MINUS
  1085. INCTRK:    MVI    A,58H+STEP    ;STEP COMMAND
  1086.     OUT    DCOM        ;ISSUE IT
  1087.     IN    WAIT
  1088.     IF    PERSCI
  1089.     LXI    H,0FFFH        ;DELAY CONST
  1090.     MVI    A,1        ;PERSCI STEP COMMAND
  1091.     OUT    WAIT
  1092. LLL:    DCX    H        ;DECR COUNT
  1093.     MOV    A,H
  1094.     ORA    L
  1095.     JNZ    LLL        ;LOOP
  1096.     ENDIF
  1097.     CALL    CHECKC        ;ABORT ON CONTROL C
  1098.     LDA    OFFSET        ;OFFSET NEXT TRACK
  1099.     ORA    A
  1100.     JZ    DOF4
  1101.     LXI    H,SECMAP    ;SECTOR MAP
  1102.     CALL    MAPSLEW
  1103.     JMP    NEXTONE
  1104. ;
  1105. ;
  1106. ;    INDX  -  INDEX BLOCK FOR IBM FORMATS (NOT REQUIRED FOR 1771 OR 1791)
  1107. ;
  1108. INDX:    LXI    D,40        ;COUNT
  1109.     MVI    B,0FFH        ;BYTE
  1110.     CALL    MOVEIT        ;STORE THE BLOCK
  1111.     LXI    D,6        ;COUNT
  1112.     MVI    B,0        ;ZERO
  1113.     CALL    MOVEIT        ;STORE THE BLOCK
  1114.     MVI    M,0FCH        ;INDEX MARK
  1115.     INX    H        ;INCR POINTER
  1116.     LXI    D,26        ;NOW 26 MORE FF'S
  1117.     MVI    B,0FFH
  1118.     CALL    MOVEIT        ;STORE THE BLOCK
  1119.     RET
  1120. ;
  1121. ;    DINDX -  INDEX BLOCK DOUBLE DENSITY (MFM)
  1122. ;
  1123. DINDX:    LDA    SECSIZ        ;SECTOR SIZE CODE
  1124.     CPI    1        ;256 BYTES?
  1125.     JZ    DINDX1        ;YES, STD IBM (MFM) FORMAT
  1126.     MVI    B,4EH        ;FILL CHAR
  1127.     LXI    D,30        ;30
  1128.     CALL    MOVEIT
  1129.     RET
  1130. DINDX1:    MVI    B,4EH        ;FILL BYTE
  1131.     LXI    D,80        ;COUNT
  1132.     CALL    MOVEIT
  1133.     MVI    B,0        ;12 ZEROS
  1134.     LXI    D,12
  1135.     CALL    MOVEIT
  1136.     MVI    B,0F6H        ;3 F6'S
  1137.     LXI    D,3
  1138.     CALL    MOVEIT
  1139.     MVI    M,0FCH        ;INDEX MARK
  1140.     INX    H
  1141.     MVI    B,4EH        ;50 4E'S
  1142.     LXI    D,50
  1143.     CALL    MOVEIT
  1144.     RET
  1145. ;
  1146. ;    ADDR  -  ADDRESS BLOCK
  1147. ;
  1148. ADDR:    LXI    D,6        ;WRITE 6 ZEROS
  1149.     MVI    B,0
  1150.     CALL    MOVEIT
  1151.     MVI    M,0FEH        ;ID ADDRESS MARK
  1152.     INX    H
  1153.     LXI    D,4        ;TRACK AND SECTOR ZERO INITIALLY
  1154.     XRA    A
  1155.     CALL    MOVEIT
  1156.     MVI    M,0F7H        ;WRITE 2 CRC'S
  1157.     INX    H
  1158.     RET
  1159. ;
  1160. ;    DADDR  -  ADDRESS BLOCK (MFM)
  1161. ;
  1162. DADDR:    LDA    SECSIZ        ;SECTOR SIZE CODE
  1163.     ORA    A
  1164.     JNZ    DADDR1
  1165.     MVI    B,0        ;9 00'S
  1166.     LXI    D,9
  1167.     CALL    MOVEIT
  1168.     MVI    B,0F5H        ;3 F5'S
  1169.     LXI    D,3
  1170.     CALL    MOVEIT
  1171.     MVI    M,0FEH
  1172.     INX    H        ;ID ADDR MARK
  1173.     MVI    B,0
  1174.     LXI    D,4        ;4 ZEROS FOR TRACK AND SECTOR NO
  1175.     CALL    MOVEIT
  1176.     MVI    M,0F7H        ;WRITE CRC'S
  1177.     INX    H
  1178.     RET
  1179. DADDR1:    LXI    D,12        ;12 ZEROS
  1180.     MVI    B,0
  1181.     CALL    MOVEIT
  1182.     LXI    D,3        ;3 F5'S
  1183.     MVI    B,0F5H
  1184.     CALL    MOVEIT
  1185.     MVI    M,0FEH        ;ID ADDR MARK
  1186.     INX    H
  1187.     LXI    D,4        ;4 ZEROS
  1188.     MVI    B,0
  1189.     CALL    MOVEIT
  1190.     MVI    M,0F7H        ;WRITE CRC'S
  1191.     INX    H
  1192.     RET
  1193. ;
  1194. ;    DATA  -  WRITE DATA BLOCK FILLED WITH E5'S
  1195. ;
  1196. DATA:    MVI    B,0FFH        ;WRITE 11 FF'S
  1197.     LXI    D,11
  1198.     CALL    MOVEIT
  1199.     MVI    B,0        ;NOW 6 ZEROS
  1200.     LXI    D,6
  1201.     CALL    MOVEIT
  1202.     MVI    M,0FBH        ;DATA ADDRESS MARK
  1203.     INX    H
  1204.     XCHG            ;SWAP DE, HL
  1205.     LHLD    BYTES        ;NUMBER OF BYTES IN SECTOR
  1206.     XCHG            ;SWAP THEM BACK
  1207.     MVI    B,0E5H        ;DATA FILL CHARACTER
  1208.     CALL    MOVEIT
  1209.     MVI    M,0F7H        ;WRITE 2 CRC'S
  1210.     INX    H
  1211.     LDA    GAP        ;INTERRECORD GAP
  1212.     MOV    E,A        ;TO E
  1213.     MVI    D,0        ;SET D TO ZERO
  1214.     MVI    B,0FFH        ;GAP BYTE
  1215.     CALL    MOVEIT
  1216.     RET
  1217. ;
  1218. ;    DDAT  -  FILL DATA BLOCK WITH E5'S  (MFM)
  1219. ;
  1220. DDAT:    MVI    B,04EH        ;WRITE 22 4E'S
  1221.     LXI    D,22
  1222.     CALL    MOVEIT
  1223.     MVI    B,0        ;NOW 12 ZEROS
  1224.     LXI    D,12
  1225.     CALL    MOVEIT
  1226.     LXI    D,3        ;3 F5'S
  1227.     MVI    B,0F5H        ;
  1228.     CALL    MOVEIT
  1229.     MVI    M,0FBH        ;DATA ADDRESS MARK
  1230.     INX    H
  1231.     XCHG            ;SWAP DE, HL
  1232.     LHLD    BYTES        ;NUMBER OF BYTES IN SECTOR
  1233.     XCHG            ;SWAP THEM BACK
  1234.     MVI    B,0E5H        ;DATA FILL CHARACTER
  1235.     CALL    MOVEIT
  1236.     MVI    M,0F7H        ;WRITE 2 CRC'S
  1237.     INX    H
  1238.     LDA    DGAP        ;INTERRECORD GAP
  1239.     MOV    E,A        ;TO E
  1240.     MVI    D,0        ;SET D TO ZERO
  1241.     MVI    B,4EH        ;GAP BYTE
  1242.     CALL    MOVEIT
  1243.     RET
  1244. ;
  1245. ;
  1246. ;    MOVEIT ROUTINE HL POINTS TO MEMORY, DE = BYTE COUNT, B CONTAINS BYTE
  1247. ;
  1248. MOVEIT:    MOV    M,B        ;STORE BYTE
  1249.     INX    H
  1250.     DCX    D
  1251.     MOV    A,E
  1252.     ORA    D
  1253.     JNZ    MOVEIT
  1254.     RET
  1255. ;
  1256. ;    FILADR  -  FILL IN TRACK AND SECTOR NUMBERS
  1257. ;
  1258. FILADR:
  1259.     LXI    B,SECMAP    ;POINTER TO SECTOR MAP
  1260.     LDA    NUMSEC        ;NUMBER OF SECTORS
  1261.     STA    SEC        ;SECTOR COUNTER
  1262.     LHLD    FOFF        ;FILL ADDR OFFSET
  1263.     XCHG
  1264.     LXI    H,TRKBUF+80    ;LOCATION OF FIRST TRACK NUMBER
  1265. FIL01:    LDA    TRK        ;TRACK NO
  1266.     MOV    M,A        ;TO BUFFER
  1267.     INX    H
  1268.     INX    H        ;POINT TO SECTOR
  1269.     LDAX    B        ;SECTOR NUMBER
  1270.     MOV    M,A        ;TO BUFFER
  1271.     INX    H
  1272.     LDA    SECSIZ        ;SECTOR SIZE CODE
  1273.     MOV    M,A        ;TO MEMORY
  1274.     DAD    D        ;INCR BUFFER POINTER
  1275.     INX    B        ;INCR SECTOR MAP POINTER
  1276.     LDA    SEC
  1277.     DCR    A
  1278.     STA    SEC        ;DECR SECTOR COUNT
  1279.     JNZ    FIL01        ;LOOP FOR NUMSEC SECTORS
  1280.     RET
  1281. ;
  1282. ;    DFILADR  -  FILL IN TRACK AND SECTOR NUMBERS
  1283. ;
  1284. DFILADR:
  1285.     LXI    B,SECMAP    ;POINTER TO SECTOR MAP
  1286.     LDA    DNUMSEC        ;NUMBER OF SECTORS
  1287.     STA    SEC        ;SECTOR COUNTER
  1288.     LHLD    FOFF        ;FILL ADDR OFFSET
  1289.     XCHG
  1290.     LXI    H,TRKBUF+43    ;LOCATION OF FIRST TRACK NUMBER
  1291.     LDA    SECSIZ        ;SECTOR SIZE CODE
  1292.     ORA    A
  1293.     JZ    DFIL00
  1294.     LXI    H,TRKBUF+46
  1295. DFIL00:    DCR    A
  1296.     JNZ    DFIL01
  1297.     LXI    H,TRKBUF+162    ;LOCATION FIRST TRACK NO 256 BYTE SECTORS
  1298. DFIL01:    LDA    TRK        ;TRACK NO
  1299.     MOV    M,A        ;TO BUFFER
  1300.     INX    H
  1301.     INX    H        ;POINT TO SECTOR
  1302.     LDAX    B        ;SECTOR NUMBER
  1303.     MOV    M,A        ;TO BUFFER
  1304.     INX    H
  1305.     LDA    SECSIZ        ;SECTOR SIZE CODE
  1306.     MOV    M,A        ;TO MEMORY
  1307.     DAD    D        ;INCR BUFFER POINTER
  1308.     INX    B        ;INCR SECTOR MAP POINTER
  1309.     LDA    SEC
  1310.     DCR    A
  1311.     STA    SEC        ;DECR SECTOR COUNT
  1312.     JNZ    FIL01        ;LOOP FOR NUMSEC SECTORS
  1313.     RET
  1314. ;
  1315. ;
  1316. ;    FILBUF  -  FILL END OF TRACK WITH FF'S OR 4E'S
  1317. ;
  1318. FILBUF:    LXI    D,1024        ;END OF TRACK FILL
  1319.     MVI    B,0FFH        ;FILL CHAR
  1320.     LDA    DDFLG        ;CHECK DENSITY FLAG
  1321.     ORA    A
  1322.     JZ    ET1
  1323.     MVI    B,4EH        ;DD FILL BYTE
  1324. ET1:    MOV    M,B
  1325.     INX    H
  1326.     DCX    D        ;DECR COUNT
  1327.     MOV    A,D
  1328.     ORA    E
  1329.     JNZ    ET1
  1330.     RET
  1331. ;
  1332. ;    IDREAD  -  READ ID FIELD ON CURRENT TRACK AND PUT DATA IN IDTAB
  1333. ;
  1334. IDREAD:    LDA    RETRYS
  1335. IDRD01:    STA    IDECNT        ;ERROR COUNT
  1336.     MVI    A,0D0H        ;INTERRUPT
  1337.     OUT    DCOM
  1338.     LXI    H,IDTAB        ;POINT TO TABLE
  1339.     XTHL
  1340.     XTHL            ;SHORT DELAY
  1341.     MVI    A,0C4H        ;READ ADDR COMMAND
  1342.     OUT    DCOM        ;SEND IT
  1343. IDRD02:    IN    WAIT        ;WAIT FOR DRQ OR INTRQ
  1344.     ORA    A
  1345.     JP    IDRD03
  1346.     IN    DDATA        ;READ DATA BYTE
  1347.     MOV    M,A        ;STORE IT
  1348.     INX    H        ;INCR POINTER
  1349.     JMP    IDRD02        ;LOOP TILL INTRQ
  1350. IDRD03:    IN    STATP        ;READ STATUS
  1351.     ANI    08H
  1352.     RZ
  1353.     LDA    IDECNT        ;ERROR COUNT
  1354.     DCR    A        ;DECR IT
  1355.     JNZ    IDRD01        ;TRY AGAIN
  1356.     PRINT    <CR,LF,'ERROR IN READING ID FIELD'>
  1357.     JMP    ENDFIL
  1358. ;
  1359. ;
  1360. ;
  1361. ;    WAIT ROUTINE CAUSES TIME DELAY OF ABOUT 1/3 SEC AT 4 MHZ
  1362. ;
  1363. DELAY:    SAV
  1364.     LXI    H,09000H    ;LOAD DELAY CONSTANT
  1365.     LXI    D,1        ;ONE TO DE
  1366. DL1:    XTHL
  1367.     XTHL
  1368.     INX    B        ;DELAY
  1369.     DAD    D
  1370.     JNC    DL1        ;LOOP TILL CARRY SET
  1371.     RES
  1372.     RET
  1373. ;
  1374. ;
  1375. ;    EXIT ROUTINES
  1376. ;
  1377. ENDFIL:    PRINT    CRLF,$
  1378.     LDA    DRIVE
  1379.     CALL    SELECT
  1380.     LDA    INFLAG        ;SEE WHERE TO GO
  1381.     ORA    A
  1382.     JNZ    NEWIN        ;BACK FOR MORE INPUT
  1383. MONITOR:LHLD    OLDSTK
  1384.     SPHL            ;RESET ORIGINAL STACK
  1385.     RET            ;BACK TO CP/M
  1386. ;
  1387. ;  ERROR ROUTINES
  1388. ;
  1389. ERRMSG:    PRINT    <CR,LF,'FORMATTING ERROR DRIVE '>
  1390.     LDA    NEWDRV
  1391.     ORA    A        ;TEST DRIVE NUMBER
  1392.     JZ    ERM2
  1393.     PRINT    <'B',CR,LF>
  1394.     JMP    ENDFIL
  1395. ERM2:    PRINT    <'A',CR,LF>
  1396.     JMP    ENDFIL
  1397. ;
  1398. ;    CHECK FOR LEGITIMATE SECTOR NUMBERS (1-26). AND CHECK IF SECTOR NUMBER
  1399. ;    ALREADY ASSIGNED
  1400. ;
  1401. SECERR:    CPI    1
  1402.     JP    SE0
  1403.     PRINT    <CR,LF,' ERROR - SECTOR NUMBERS MUST BE GREATER THAN ZERO'>
  1404.     JMP    SE1
  1405. SE0:    CPI    27
  1406.     JM    SE2
  1407.     PRINT    <CR,LF,' ERROR - SECTOR GREATER THAN 26'>
  1408. SE1:    STC
  1409.     RET
  1410. SE2:    LXI    H,SECMAP
  1411.     MVI    B,26
  1412. SE3:    CMP    M        ;CHECK IF SECTOR ALREADY USED
  1413.     JNZ    SE4
  1414.     PRINT    <CR,LF,' SORRY YOU ALREADY USED THAT ONE'>
  1415.     JMP    SE1
  1416. SE4:    INX    H
  1417.     DCR    B
  1418.     JNZ    SE3
  1419. SE5:    ORA    A        ;CLEAR CARRY
  1420.     RET
  1421. ;
  1422. ;    SCANERR - NUMBER MISSING WHERE EXPECTED
  1423. ;
  1424. SCANERR:PRINT  <CR,LF,LF,'MISSING OPERAND, PLEASE START OVER',CR,LF>
  1425.     JMP    ENDFIL        ;EXIT
  1426. ;
  1427. ;    DECERR - NON NUMERIC CHARACTER IN NUMBER
  1428. ;
  1429. DECERR:    PRINT  <CR,LF,LF,'ERROR IN ENTERING DECIMAL NUMBER, PLEASE START OVER'>
  1430.     JMP    ENDFIL        ;EXIT
  1431. ;
  1432. ;    TRKTEST - TEST FOR TRACK BETWEEN 0 AND 76
  1433. ;
  1434. TRKTEST:CPI    77        ;CHECK SECTOR > 76
  1435.     RM
  1436.     PRINT    <CR,LF,LF,'TRACK NUMBER MUST BE BETWEEN 0-76',CR,LF>
  1437.     JMP    ENDFIL
  1438. ;
  1439. ;
  1440. ;    SEARCH SECTOR TABLE FOR PREVIOUS SECTOR NUMBER
  1441. ;    SET CARRY ON MATCH
  1442. ;
  1443. SRTAB:    SAV
  1444.     LXI    H,SECMAP    ;POINT TO TABLE
  1445.     MVI    B,26        ;TABLE LENGTH
  1446. SR1:    CMP    M        ;COMPARE TABLE ENTRY WITH A
  1447.     JNZ    SR5        ;GO ON IF NO MATCH
  1448.     STC            ;SET CARRY
  1449. SR3:    RES
  1450.     RET
  1451. SR5:    INX    H        ;INCR POINTER
  1452.     DCR    B        ;DECR SECTOR COUNT
  1453.     JNZ    SR1        ;LOOP FOR 26 SECTORS
  1454.     ORA    A        ;RESET CARRY
  1455.     JMP    SR3        ;EXIT
  1456. ;
  1457. ;
  1458. ;    CLEAR ROUTINE CLEARS SCREEN (NULLS FOR SOME TERMINALS)
  1459. ;
  1460. CLEAR:    SAVE
  1461.     PRINT    <1AH,0,0,0,0,0,0,0,0,0,0>
  1462.     RESTORE
  1463.     RET
  1464. ;
  1465. ;    SEEK ROUTINE MOVES TO TRACK IN A REG (ASSUMES PREVIOUS HOME)
  1466. ;
  1467. SEEK:    SAV            ;SAVE REGS
  1468.     MOV    E,A        ;SAVE TRACK NO IN E
  1469.     IN    TRACK        ;READ 1771 TRACK REG
  1470.     MOV    B,A        ;SAVE IN B
  1471.     CMP    E        ;COMPARE WITH REQUESTED TRACK
  1472.     JZ    SEEK3
  1473.     IF    PERSCI
  1474.     MVI    A,40H        ;STEP IN
  1475.     JC    PSK1
  1476.     MVI    A,60H        ;STEP OUT
  1477. PSK1:    OUT    DCOM        ;OUTPUT STEP DIRECTION
  1478.     MVI    A,30        ;DELAY CONST
  1479. PSK3:    DCR    A
  1480.     JNZ    PSK3        ;WAIT SHORT TIME
  1481.     MOV    A,B        ;PRESENT TRACK
  1482.     SUB    E        ;SUBTRACT REQUESTED TRACK
  1483.     JP    PSK5        ;OK IF +
  1484.     CMA
  1485.     INR    A        ;COMPLIMENT IF -
  1486. PSK5:    MOV    B,A        ;NO OF STEPS IN B
  1487.     MVI    A,1        ;PERSCI STEP COMMAND
  1488. PSK7:    OUT    WAIT        ;STEP PERSCI
  1489.     DCR    B
  1490.     JNZ    PSK7
  1491.     IN    WAIT        ;CLEAR 1771
  1492.     IN    STATP
  1493.     MOV    A,E        ;DESTINATION TRACK
  1494.     OUT    TRACK
  1495.     LDA    LATCH        ;LATCH CODE FOR SELECTED DRIVE
  1496.     ANI    72H
  1497.     OUT    WAIT        ;COMMAND WAITS FOR SEEK COMPLETE
  1498.     IN    WAIT        ;WAIT FOR SEEK COMPLETE
  1499.     LDA    LATCH
  1500.     OUT    WAIT        ;RESET LATCH
  1501.     ELSE
  1502.     MVI    D,0
  1503.     MVI    C,5        ;RETRYS
  1504. SEEK1:    MOV    A,E        ;TRACK NO
  1505.     OUT    DDATA        ;TRACK NO TO DATA REG
  1506. SEEKW:    IN    STATP        ;CHECK BUSY
  1507.     RRC
  1508.     JC    SEEKW        ;WAIT TILL NOT BUSY DOOR CLOSED ETC.
  1509.     MVI    A,1CH+STEP    ;SEEK COMMAND (6 MSEC) WITH VERIFY
  1510.     OUT    DCOM        ;DO IT
  1511.     IN    WAIT
  1512.     IN    STATP        ;READ DISK STATUS
  1513.     ANI    91H
  1514.     JZ    SEEK3        ;EXIT IF ZERO
  1515.     DCR    C        ;DECR ERROR COUNT
  1516.     JZ    SEEK2        ;SEEK ERROR AFTER 5 RETRYS
  1517.     CALL    HOME        ;HOME THE DRIVE
  1518.     JMP    SEEK1        ;TRY AGAIN
  1519. SEEK2:    PUSH    D        ;SAVE TRACK NO
  1520.     PRINT    <CR,LF,'SEEK ERROR TRACK '>
  1521.     POP    H        ;TRACK NO TO L
  1522.     DECOUT            ;PRINT TRACK NO
  1523.     PRINT    <' DRIVE '>
  1524.     LDA    DRVNO        ;GET SELECTED DRIVE
  1525.     CALL    PRNDRV        ;PRINT A THRU C
  1526.     JMP    ENDFIL        ;EXIT
  1527.     ENDIF
  1528. SEEK3:    RES            ;RESTORE REGS
  1529.     RET
  1530. ;
  1531. ;
  1532. ;    HOME SELECTED DRIVE
  1533. ;
  1534. HOME:    SAV
  1535.     PUSH    PSW
  1536.     IF    PERSCI
  1537.     XRA    A        ;TRACK ZERO
  1538.     CALL    SEEK        ;SEEK IT
  1539.     CALL    DELAY
  1540.     MVI    A,8
  1541.     OUT    DCOM
  1542.     IN    WAIT
  1543.     IN    STATP        ;CHECK STATUS
  1544.     ANI    4        ;TRACK ZERO BIT
  1545.     JZ    HOMERR        ;ERROR IF NOT ZERO
  1546.     ELSE
  1547. HOME1:    IN    STATP        ;CHECK IF BUSY
  1548.     RRC
  1549.     JC    HOME1
  1550.     MVI    A,STEP        ;HOME COMMAND
  1551.     OUT    DCOM        ;ISSUE COMMAND
  1552.     CALL    DELAY        ;WAIT TILL DRIVE HOME
  1553. HOME3:    IN    STATP        ;READ DISK STATUS
  1554.     ANI    4        ;CHECK TRACK ZERO FLAG
  1555.     JZ    HOMERR        ;ERROR IF NOT T 0
  1556.     ENDIF
  1557. HOME5:    LXI    H,TRKTBL    ;POINT TO TRACK TABLE
  1558.     MVI    D,0
  1559.     LDA    DRVNO        ;SELECTED DRIVE
  1560.     MOV    E,A
  1561.     DAD    D        ;ADDR OF TABLE ENTRY
  1562.     XRA    A        ;ZERO
  1563.     MOV    M,A        ;TRACK ZERO
  1564.     IF    NOT PERSCI
  1565.     CALL    DELAY        ;WAIT
  1566.     ENDIF
  1567.     POP    PSW
  1568.     RES
  1569.     RET
  1570. HOMERR:    PRINT    <CR,LF,'ERROR IN HOMING DRIVE '>
  1571.     LDA    DRVNO        ;SELECTED DRIVE
  1572.     CALL    PRNDRV        ;PRINT IT
  1573.     JMP    ENDFIL        ;EXIT
  1574. ;
  1575. ;    READ ROUTINE READ SECTOR FROM SELECTED TRACK AND KEEP TRACK OF 
  1576. ;    ERRORS. DE POINTS TO THE MEMORY BUFFER. THE SECTOR TO BE READ
  1577. ;    IS IN SNUM.
  1578. ;
  1579. READ0:    MVI    B,88H        ;READ WITHOUT HEAD LOAD COMMAND
  1580.     LDA    RETRYS        ;RETRY COUNT
  1581.     STA    ERRORS        ;ERROR COUNT
  1582.     JMP    READ2        ;TO READ ROUTINE
  1583. READ1:    MVI    B,8CH        ;READ WITH HEAD LOAD COMMAND
  1584.     LDA    RETRYS        ;RETRY COUNT
  1585.     STA    ERRORS        ;ERROR COUNT
  1586. READ2:    LDA    SNUM        ;GET SECTOR NUMBER
  1587.     OUT    SECTP        ;SET SECTOR NUMBER INTO 1771
  1588.     LDA    DDFLG        ;DENSITY FLAG
  1589.     ORA    A
  1590.     JZ    READ3
  1591.     MVI    A,1
  1592.     OUT    WAIT+1        ;SET DOUBLE DENSITY
  1593. READ3:    XCHG
  1594.     SHLD    BBLOCK        ;POINTER TO START OF CURRENT BLOCK
  1595.     MOV    A,B        ;GET READ COMMAND
  1596.     OUT    DCOM        ;SENT IT
  1597. READ5:    IN    WAIT        ;WAIT TILL COMMAND EXECUTED
  1598.     ORA    A        ;CHECK ERROR STATUS
  1599.     JP    READ6        ;DONE IF BIT 7 HI (INTRQ)
  1600.     IN    DDATA        ;READ DATA
  1601.     MOV    M,A        ;STORE IT IN BUFFER
  1602.     INX    H
  1603.     JMP    READ5        ;BACK FOR ANOTHER BYTE
  1604. READ6:    XCHG
  1605.     IN    STATP        ;DISK STATUS
  1606.     ANI    9DH        ;CHECK ERROR BITS
  1607.     RZ            ;RETURN IF NONE
  1608.     LDA    SOFTERR        ;SOFT ERRORS
  1609.     INR    A
  1610.     STA    SOFTERR        ;STORE IT BACK
  1611.     LDA    ERRORS        ;ERROR COUNT
  1612.     DCR    A
  1613.     STA    ERRORS        ;STORE IT BACK
  1614.     JZ    RFILL        ;RETRY TRYS IF ZERO
  1615.     XCHG
  1616.     LHLD    BBLOCK        ;RESET BUFFER POINTER
  1617.     XCHG
  1618.     JMP    READ2        ;TRY AGAIN FOR RETRY TIMES
  1619. RFILL:    LDA    NOFILL        ;ERROR FILL FLAG
  1620.     ORA    A        ;IF ZERO DON'T FILL WITH E5'S
  1621.     JNZ    READ8
  1622.     SAVE
  1623.     LHLD    BBLOCK        ;POINTS TO BEGINNING OF READ BLOCK
  1624.     MVI    C,128        ;COUNTER
  1625.     MVI    A,0E5H        ;FILL BYTE
  1626. READ7:    MOV    M,A        ;STORE E5
  1627.     INX    H        ;INCR POINTER
  1628.     DCR    C
  1629.     JNZ    READ7        ;LOOP FOR 128 BYTES
  1630.     JMP    READ9
  1631. READ8:    SAV            ;SAVE REGISTERS
  1632. READ9:    PRINT    <CR,LF,'PERMANENT READ ERROR TRACK '>
  1633. READ10:    LHLD    TNUM        ;TRACK NUMBER
  1634.     DECOUT            ;PRINT DECIMAL
  1635.     PRINT    <' SECTOR '>
  1636.     LHLD    SNUM        ;SECTOR NUMBER
  1637.     DECOUT
  1638.     PRINT    <' DRIVE '>
  1639.     LDA    DRVNO        ;GET SELECTED DRIVE NO
  1640.     CALL    PRNDRV        ;PRINT DRIVE NO A THRU C
  1641. READ12:    LXI    H,HARDERR    ;POINT TO HARD ERRORS
  1642.     INR    M        ;INCREMENT IT
  1643.     MVI    A,0FFH        ;SET ERROR FLAG
  1644.     RES            ;RESTORE REGISTERS
  1645.     CALL    CHECKC        ;ABORT ON CONTROL C
  1646.     RET
  1647. ;
  1648. ;    VERIFY ROUTINE READ SECTOR FROM SELECTED TRACK AND KEEP TRACK OF 
  1649. ;    ERRORS. DE POINTS TO MEMORY BUFFER. (SWAPPED INTERNALLY WITH HL
  1650. ;    FOR SPEED IN THIS ROUTINE)
  1651. ;    THE SECTOR NUMBER TO BE READ IS IN SNUM
  1652. ;
  1653. VER0:    MVI    B,88H        ;READ WITHOUT HEAD LOAD
  1654.     LDA    RETRYS        ;RETRY COUNT
  1655.     STA    ERRORS        ;ERROR COUNT
  1656.     JMP    VER2        ;TO READ ROUTINE
  1657. VER1:    MVI    B,8CH        ;READ WITH HEAD LOAD
  1658.     LDA    RETRYS        ;RETRY COUNT
  1659.     STA    ERRORS        ;ERROR COUNT
  1660. VER2:    LDA    SNUM        ;SECTOR NUMBER
  1661.     OUT    SECTP        ;SET SECTOR NUMBER INTO 1771
  1662.     XCHG            ;SWAP REGISTERS
  1663.     SHLD    BBLOCK        ;START CURRENT BLOCK
  1664.     MOV    A,B        ;GET READ COMMAND
  1665.     OUT    DCOM        ;SENT IT
  1666. VER5:    IN    WAIT        ;WAIT TILL COMMAND EXECUTED
  1667.     ORA    A        ;CHECK ERROR STATUS
  1668.     JP    VER8        ;DONE IF BIT 7 HI (INTRQ)
  1669.     IN    DDATA        ;READ DATA
  1670.     CMP    M        ;COMPARE WITH MEMORY
  1671.     INX    H
  1672.     JZ    VER5        ;BACK FOR ANOTHER BYTE
  1673. VER6:    XCHG
  1674.     LDA    SOFTERR        ;SOFT ERRORS
  1675.     INR    A        ;INCREMENT IT
  1676.     STA    SOFTERR        ;STORE IT BACK
  1677.     LDA    ERRORS        ;ERROR COUNT
  1678.     DCR    A        ;DECREMENT IT
  1679.     STA    ERRORS        ;STORE IT BACK
  1680.     XCHG
  1681.     LHLD    BBLOCK        ;RESET MEMORY POINTER
  1682.     XCHG
  1683.     JNZ    VER2        ;TRY AGAIN FOR RETRY TIMES
  1684.     PUSH    H
  1685.     LXI    H,128        ;SECTOR INCR
  1686.     DAD    D        ;ADD TO MEMORY POINTER
  1687.     XCHG
  1688.     POP    H
  1689.     SAVE            ;SAVE REGISTERS
  1690.     PRINT    <CR,LF,'PERMANENT VERIFY 0R READ CRC ERROR TRACK '>
  1691.     JMP    READ10        ;PRINT REST OF ERROR MESSAGE AND RET
  1692. VER8:    XCHG            ;SWITCH REGISTERS BACK
  1693.     IN    STATP        ;GET DISK STATUS
  1694.     ANI    9DH        ;CHECK ERROR BITS
  1695.     RZ            ;RETURN IF NONE
  1696.     XCHG
  1697.     JMP    VER6
  1698. ;
  1699. ;
  1700. ;
  1701. ;    WRITE ROUTINE WRITES A SECTOR ON SELECTED TRACK
  1702. ;    DE POINTS TO THE MEMORY BUFFER. THE SECTOR NUMBER TO BE WRITTEN
  1703. ;    IS IN SNUM.
  1704. ;
  1705. WRITE0:    LDA    RETRYS        ;RETRY COUNT
  1706. WRITE1:    STA    ERRORS        ;ERROR COUNT
  1707.     IN    STATP        ;READ STATUS
  1708.     ANI    20H        ;CHECK HEAD LOAD BIT
  1709. WRITE2:    LDA    SNUM        ;SECTOR NUMBER
  1710.     OUT    SECTP        ;SET SECTOR NUMBER INTO 1771
  1711.     MVI    A,0ACH        ;WRITE WITH HEAD LOAD
  1712.     JNZ    WRITE3
  1713.     MVI    A,0A8H        ;WRITE WITH HEAD LOAD
  1714. WRITE3:    OUT    DCOM        ;ISSUE WRITE COMMND
  1715. WRITE5:    IN    WAIT        ;WAIT TILL COMMAND EXECUTED
  1716.     ORA    A        ;CHECK ERROR STATUS
  1717.     JP    WRITE7        ;DONE IF BIT 7 HI (INTRQ)
  1718.     LDAX    D        ;GET A BYTE FROM MEMORY
  1719.     OUT    DDATA        ;WRITE TO DISK
  1720.     INX    D        ;INCR POINTER
  1721.     JMP    WRITE5        ;BACK FOR ANOTHER BYTE
  1722. WRITE7:    XTHL
  1723.     XTHL            ;SHORT DELAY
  1724.     IN    STATP        ;READ DISK STATUS
  1725.     ANI    0FDH        ;CHECK ERROR BITS
  1726.     RZ            ;RETURN IF NONE
  1727.     LDA    SOFTERR        ;SOFT ERRORS
  1728.     INR    A        ;INCREMENT IT
  1729.     STA    SOFTERR        ;STORE IT BACK
  1730.     LDA    ERRORS        ;ERROR COUNT
  1731.     DCR    A
  1732.     JNZ    WRITE1        ;TRY AGAIN FOR RETRY TIMES
  1733.     SAV
  1734.     PRINT    <CR,LF,'PERMANENT WRITE ERROR TRACK '>
  1735.     JMP    READ10        ;PRINT REST OF ERROR MESS
  1736. ;
  1737. ;    RDTRK READS A TRACK FOR VALIDATION OR COPY
  1738. ;    HL POINTS TO SECTOR MAP, DE POINTS TO MEMORY BUFFER
  1739. ;
  1740. RDTRK:    SAV            ;SAVE REGISTERS
  1741.     LDA    NUMSEC        ;COUNT OF SECTORS PER TRACK
  1742.     MOV    C,A        ;TO C
  1743.     LDA    DDFLG        ;DENSITY FLAG
  1744.     ORA    A
  1745.     JZ    RDT0
  1746.     LDA    DNUMSEC        ;SECTORS DOUBLE DENSITY
  1747.     MOV    C,A
  1748. RDT0:    MOV    A,M        ;GET A SECTOR NUMBER
  1749.     STA    SNUM        ;SAVE SECTOR NUMBER IN MEMORY
  1750.     CALL    READ1        ;READ WITH HEAD LOAD
  1751. RDT1:    INX    H        ;INCR SECTOR MAP POINTER
  1752.     DCR    C        ;DECR SECTOR COUNT
  1753.     JZ    RDT4        ;EXIT
  1754.     ORA    A        ;CHECK SECTOR READ RETURN CODE
  1755.     JNZ    RDT0        ;IF ERROR READ WITH HEAD LOAD
  1756.     MOV    A,M        ;GET A SECTOR NUMBER FROM MAP
  1757.     STA    SNUM        ;SAVE SECTOR NUMBER IN MEMORY
  1758.     CALL    READ0        ;READ DISK WITHOUT HEAD LOAD
  1759.     JMP    RDT1        ;LOOP FOR 26 SECTORS
  1760. RDT4:    RES            ;RESTORE REGISTERS
  1761.     CALL    CHECKC        ;ABORT ON CONTROL C
  1762.     RET
  1763. ;
  1764. ;
  1765. ;    WRTRK WRITES AND VERIFIES A TRACK
  1766. ;    HL POINTS TO SECTOR MAP, DE POINTS TO MEMORY BUFFER
  1767. ;
  1768. WRTRK:    SAV            ;SAVE REGISTERS
  1769.     LDA    NUMSEC        ;COUNT OF SECTORS PER TRACK
  1770.     MOV    C,A        ;TO C
  1771.     LDA    DDFLG        ;DENSITY SWITCH
  1772.     ORA    A
  1773.     JZ    WRT
  1774.     LDA    DNUMSEC        ;NUMBER OF SECTORS (MFM)
  1775.     MOV    C,A        ;TO C
  1776. WRT:    PUSH    H
  1777.     PUSH    D        ;SAVE POINTERS FOR VERIFICATION
  1778. WRT0:    MOV    A,M        ;GET A SECTOR NUMBER
  1779.     STA    SNUM        ;SAVE SECTOR NUMBER IN MEMORY
  1780.     CALL    WRITE0        ;CALL WRITE ROUTINE
  1781. WRT1:    INX    H        ;INCR SECTOR MAP POINTER
  1782.     DCR    C        ;DECR SECTOR COUNT
  1783.     JZ    WRT3        ;EXIT
  1784.     JMP    WRT0        ;LOOP TILL SECTOR COUNT IS ZERO
  1785. WRT3:    POP    D
  1786.     POP    H
  1787.     CALL    CHECKC        ;ABORT ON CONTROL C
  1788.     LDA    VERFLG        ;VERIFY FLAG
  1789.     ORA    A
  1790.     JNZ    WRT20        ;NO VERIFY IF NOT ZERO
  1791.     LDA    NUMSEC        ;SECTOR COUNT
  1792.     MOV    C,A        ;TO C
  1793.     LDA    DDFLG        ;DENSITY FLAG
  1794.     ORA    A
  1795.     JZ    WRT10
  1796.     LDA    DNUMSEC        ;NUMBER OF SECTORS (MFM)
  1797.     MOV    C,A        ;TO C
  1798. WRT10:    MOV    A,M        ;GET SECTOR NUMBER
  1799.     STA    SNUM        ;SAVE IT
  1800.     CALL    VER0        ;VERIFY WITHOUT HEAD LOAD
  1801. WRT11:    INX    H        ;INCR SECTOR MAP POINTER
  1802.     DCR    C        ;DECR SECTOR COUNT
  1803.     JZ    WRT20        ;EXIT
  1804.     ORA    A        ;CHECK READ ERROR RETURN CODE
  1805.     JZ    WRT10        ;BACK TO READ IF NO ERROR
  1806.     PRINT    <CR,LF,LF,'VALIDATING DESTINATION DISK',CR,LF>
  1807.     LDA    DEST        ;DEST DISK NO
  1808.     JMP    REVAL
  1809. WRT20:    RES            ;RESTORE REGISTERS
  1810.     RET
  1811. ;
  1812. ;    RDFORM ROUTINE READS A TRACK IN A AND STORES THE SECTOR FORMAT IN A
  1813. ;    TABLE POINTED TO BY HL. A MUST CONTAIN THE DESIRED TRACK NUMBER
  1814. ;
  1815. RDFORM:    SAV            ;PUSH REGISTERS
  1816.     XCHG            ;DE POINTS TO SECTOR TABLE
  1817.     STA    TNUM        ;SAVE TRACK NUMBER
  1818.     LDA    DDFLG        ;DENSITY FLAD
  1819.     ORA    A
  1820.     JNZ    RDT7        ;EXIT IF DOUBLE DENSITY
  1821.     CALL    TRKRD        ;READ TRACK IN A
  1822.     LXI    H,TRKBUF+4AH
  1823.     LXI    B,183
  1824.     MVI    A,-1        ;SET FLAG FOR FIRST ITERATION
  1825.     STA    CNT        ;SET SECTOR COUNT TO NUMSEC
  1826. RDF4:    MOV    A,M        ;GET A BYTE FROM THE TRACK FORMAT
  1827.     CPI    0FEH        ;IS IT AN ADDRESS MARK/
  1828.     JZ    RDF5
  1829.     INX    H        ;BUMP POINTER
  1830.     JMP    RDF4        ;LOOP TILL ADDR MARK FOUND
  1831. RDF5:    INX    H        ;HL NOW POINTS TO TRACK NO
  1832.     LDA    TNUM        ;TRACK NUMBER
  1833.     CMP    M        ;COMPARE AGAINST MEMORY
  1834.     JNZ    RDF4        ;LOOK SOME MORE IF NOT SAME
  1835.     LDA    CNT        ;TEST FOR FIRST ITERATION
  1836.     ORA    A
  1837.     JP    RDFX
  1838.     MOV    A,M        ;PICK UP TRACK NO
  1839.     STA    TNUM        ;SAVE IT
  1840. RDFX:    INX    H
  1841.     INX    H        ;HL NOW POINTS TO FIRST SECTOR NUMBER
  1842. RDF6:    MOV    A,M        ;GET SECTOR NUMBER
  1843.     STAX    D        ;STORE IT IN TABLE
  1844.     LDA    CNT        ;COUNT
  1845.     ORA    A        ;IS IT THE FIRST SECTOR
  1846.     JP    RDFY
  1847.     LDA    NUMSEC
  1848.     STA    CNT        ;SET COUNT FOR 128 BYTE SECTORS
  1849.     INX    H        ;POINT TO SECTOR SIZE BYTE
  1850.     MOV    A,M
  1851.     STA    SECSIZ        ;SAVE IT
  1852.     PUSH    H
  1853.     CPI    1        ;256 BYTE SECTORS
  1854.     JNZ    RDFS
  1855.     MVI    A,16
  1856.     STA    NUMSEC
  1857.     STA    CNT        ;SET COUNT
  1858.     LXI    H,256
  1859.     SHLD    BYTES
  1860. RDFS:    CPI    2        ;512 BYTE SECTORS
  1861.     JNZ    RDFU
  1862.     MVI    A,8        ;8 SECTORS PER TRACK
  1863.     STA    NUMSEC
  1864.     STA    CNT        ;SET COUNT
  1865.     LXI    H,512        ;512 BYTES PER SECTOR
  1866.     SHLD    BYTES
  1867. RDFU:    POP    H
  1868.     DCX    H        ;BACK UP POINTER
  1869.     LDA    CNT        ;RELOAD COUNT
  1870. RDFY:    DCR    A        ;DECREMENT IT
  1871.     JZ    RDT7        ;FINISHED
  1872.     STA    CNT        ;STORE BACK COUNT
  1873.     INX    D        ;INCR TABLE POINTER
  1874.     DAD    B        ;INCR TRACK DATA POINTER BY 182
  1875.     JMP    RDF4        ;LOOP FOR 26 SECTORS
  1876. RDT7:    RESTORE
  1877.     RET
  1878. ;
  1879. ;    TRACK READ ROUTINE. TRACK NO IS IN A, HL POINTS TO BUFFER
  1880. ;
  1881. TRKRD:    SAVE
  1882.     LXI    H,TRKBUF    ;SET POINTER TO TRACK INPUT BUFFER
  1883.     CALL    SEEK        ;FIND THE TRACK
  1884.     MVI    A,0E4H        ;READ TRACK COMMAND
  1885.     OUT    DCOM        ;ISSUE IT
  1886. RTF1:    IN    WAIT        ;WAIT AND READ DISK STATUS
  1887.     ORA    A
  1888.     JP    RTF3        ;EXIT
  1889.     IN    DDATA        ;READ DATA
  1890.     MOV    M,A        ;SAVE BYTE IN MEMORY
  1891.     INX    H        ;INCR POINTER
  1892.     JMP    RTF1        ;LOOP TILL INTRQ
  1893. RTF3:    RESTORE
  1894.     RET
  1895. ;
  1896. ;    THIS ROUTINE OFFSETS THE SECTOR MAP BY A CONSTANT (OFFSET) PER TRACK
  1897. ;    CALLED WITH OFFSET IN A AND HL POINTING TO SECTOR MAP.
  1898. ;
  1899. MAPSLEW:SAVE            ;SAVE REGS
  1900.     PUSH    H        ;SAVE POINTER TO SECTOR MAP ON STACK
  1901.     MOV    B,A        ;SAVE OFFSET IN B
  1902.     XCHG            ;SECTOR MAP POINTER TO DE
  1903.     LXI    H,NUMSEC    ;POINT TO NUMBER OF SECTORS (FM)
  1904.     LDA    DDFLG        ;DENSITY FLAG
  1905.     ORA    A
  1906.     JZ    MS0
  1907.     LXI    H,DNUMSEC    ;NUMBER OF SECTORS (MFM)
  1908. MS0:    MOV    C,M        ;SECTOR COUNT TO C
  1909.     MOV    L,C        ;SECTOR COUNT TO L
  1910.     MVI    H,0
  1911.     MOV    A,B        ;OFFSET BACK TO A
  1912.     ADD    L        ;ADD SECTOR COUNT TO OFFSET
  1913.     MOV    B,A        ;OFFSET+SECTOR COUNT TO B
  1914.     DAD    D        ;16 BIT ADD DE TO HL
  1915. MS1:    LDAX    D        ;GET A SECTOR NO  (DE POINTS TO SOURCE)
  1916.     MOV    M,A        ;STORE IT  (HL POINTS TO DESTINATION)
  1917.     DCR    B        ;DECR COUNT OF BYTES TO BE MOVED
  1918.     JZ    MS5        ;EXIT
  1919.     MOV    A,C        ;GET NUMBER OF SECTORS
  1920.     CMP    B        ;DOES B=26
  1921.     JNZ    MS3        ;JUMP IF NOT
  1922.     POP    H        ;RESET DESTINATION
  1923.     DCX    H        ;PRE DECREMENT IT
  1924. MS3:    INX    H
  1925.     INX    D        ;INDEX POINTERS
  1926.     JMP    MS1        ;LOOP FOR OFFSET+26 ITERATIONS
  1927. MS5:    RESTORE            ;RESTORE REGS
  1928.     RET
  1929. ;
  1930. ;    SELECT THE DRIVE IN A
  1931. ;
  1932. SELECT:    SAV
  1933.     MOV    C,A
  1934.     LXI    H,DRVNO        ;POINT TO DRIVE NO
  1935.     CMP    M        ;COMPARE WITH A
  1936.     JZ    SEL5
  1937.     MOV    A,M        ;OLD DRIVE NUMBER
  1938.     MOV    E,A        ;OLD DRIVE NO TO E
  1939.     MVI    D,0
  1940.     LXI    H,TRKTBL    ;POINT TO TRACK TABLE
  1941.     IN    TRACK        ;READ 1771 TRACK REG
  1942.     IF    DUAL
  1943.     MVI    B,4        ;SET ALL TRACKS THE SAME
  1944. SEL1:    MOV    M,A        ;STORE TRACK
  1945.     INX    H        ;INCR TRACK TABLE POINTER
  1946.     DCR    B
  1947.     JNZ    SEL1        ;LOOP FOR 4 DRIVES
  1948.     ELSE
  1949.     DAD    D        ;COMPUTE ADDR
  1950.     MOV    M,A        ;TRACK NO TO TABLE
  1951.     ENDIF
  1952.     MOV    A,C        ;GET NEW DRIVE NO
  1953.     MOV    E,A        ;NEW DRIVE TO E
  1954.     LXI    H,TRKTBL    ;POINT TO TRACK TABLE
  1955.     DAD    D        ;COMPUTE ADDR
  1956.     MOV    A,M        ;NEW TRACK NO
  1957.     ORA    A        ;SET FLAGS
  1958.     JP    SEL3        ;PREV SELECTED IF NOT MINUS
  1959.     MOV    A,C        ;NEW DRIVE NO
  1960.     IF    DELTA
  1961.     CALL    SELDELT
  1962.     ELSE
  1963.     CALL    DOSEL
  1964.     ENDIF
  1965.     CALL    HOME
  1966.     XRA    A        ;TRACK ZERO
  1967. SEL3:    OUT    TRACK        ;SET 1771 TRACK REG
  1968. SEL5:    MOV    A,C
  1969.     STA    DRVNO        ;RESET DRIVE NO
  1970.     MOV    A,C        ;RESTORE DRIVE NO TO A
  1971.     IF    DELTA
  1972.     CALL    SELDELT
  1973.     ENDIF
  1974.     IF    TARBELL
  1975.     CALL    SELTARB
  1976.     ENDIF
  1977.     IF    NOT DELTA OR TARBELL
  1978.     CALL    DOSEL
  1979.     ENDIF
  1980.     RES
  1981.     RET
  1982. ;
  1983. ;
  1984. ;    DOSEL  ACTUAL DRIVE SELECT  (OLD TARBELL SINGLE DENSITY)
  1985. ;
  1986. DOSEL:    CMA            ;COMPLIMENT A
  1987.     ADD    A
  1988.     ADD    A
  1989.     ADD    A
  1990.     ADD    A        ;SHIFT LEFT 4 BITS
  1991.     ORI    2        ;LATCH COMMAND
  1992.     STA    LATCH        ;SAVE IT
  1993.     OUT    WAIT        ;SELECT DRIVE
  1994.     RET
  1995. ;
  1996. ;
  1997. ;  SELTARB SELECT DRIVE (NEW TARBELL CONTROLLER)
  1998. ;
  1999. SELTARB:ADD    A
  2000.     ADD    A
  2001.     ADD    A
  2002.     ADD    A        ;SHIFT LEFT 4 BITS
  2003.     ORI    2
  2004.     STA    LATCH
  2005.     OUT    WAIT
  2006.     RET
  2007. ;
  2008. ;
  2009. ;  SELDELT SELECT DRIVE  (DELTA CONTROLLER)
  2010. ;
  2011. SELDELT:CMA            ;COMPLIMENT
  2012.     STA    LATCH        ;SAVE IT
  2013.     OUT    WAIT        ;SELECT DRIVE
  2014.     RET
  2015. ;
  2016. ;
  2017. ;    GETNUM  GET A NUMBER FROM INPUT BUFFER AND TEST
  2018. ;
  2019. GETNUM:    SAV
  2020.     SCAN    ,40H
  2021.     JZ    SCANERR        ;ERROR IF NO NUMBER
  2022.     DECIN            ;CONVERT TO DECIMAL
  2023.     JC    DECERR        ;INPUT ERROR IF CARRY
  2024.     SHLD    DECFULL        ;SAVE FULL 16 BIT VALUE
  2025.     RES
  2026.     RET
  2027. ;
  2028. ;
  2029. ;
  2030. ;    GETRK GETS AND TESTS STARTING AND ENDING TRACK NUMBERS FROM THE INPUT
  2031. ;    BUFFER. TRACKS STORED IN STRK AND ETRK. ROUTINE RETURNS WITH STRK IN A
  2032. ;
  2033. GETRK:    SAV
  2034.     XRA    A        ;ZERO
  2035.     STA    STRK        ;DEFAULT TO 0
  2036.     MVI    A,76
  2037.     STA    ETRK        ;DEFAULT TO 76
  2038.     INSTR    82H,40H,'TRACK'    ;TRACK SPECIFICATIONS?
  2039.     JNC    GT5
  2040.     CALL    GETNUM        ;GET TRACK NUMBER
  2041.     CALL    TRKTEST        ;CHECK IT
  2042.     STA    STRK        ;STARTING TRACK
  2043.     STA    ETRK        ;SET ENDING TRACK TOO IF NO OTHER SPECIFIED
  2044.     INSTR    82H,40H,'-'    ;TRACK SEPARATOR
  2045.     JNC    GT5
  2046.     CALL    GETNUM        ;GET ENDING TRACK
  2047.     CALL    TRKTEST        ;CHECK IT
  2048.     STA    ETRK        ;ENDING TRACK
  2049. GT5:    LDA    STRK        ;STARTING TRACK TO A
  2050.     RES
  2051.     RET
  2052. ;
  2053. ;    DBLSUB  16 BIT SUBTRACT DE FROM HL TO HL
  2054. ;
  2055. DBLSUB:    XRA    A        ;CLEAR CARRY
  2056.     MOV    A,L
  2057.     SBB    E        ;SUBTRACT LOW BYTES
  2058.     MOV    L,A        ;BACK TO L
  2059.     MOV    A,H
  2060.     SBB    D        ;SUBTRACT HIGH BYTES
  2061.     MOV    H,A        ;DIFFERENCE IN HL
  2062.     RET
  2063. ;
  2064. ;    POLL CONSOLE INPUT FOR CONTROL C
  2065. ;
  2066. CHECKC:    SAV            ;SAVE REGS
  2067.     PUSH    PSW
  2068.     MVI    C,11        ;CP/M STATUS POLL CODE
  2069.     CALL    5        ;CALL    CP/M
  2070.     ANI    1        ;1 IF CHARACTER WAITING
  2071.     JZ    CKC3        ;EXIT
  2072.     CHARIN            ;READ THE CONSOLE
  2073.     CPI    3        ;WAS IT A CONTROL C
  2074.     JZ    ENDFIL        ;BACK TO INPUT LOOP
  2075. CKC3:    POP    PSW
  2076.     RES            ;RESTORE REGS
  2077.     RET
  2078. ;
  2079. ;    READ CONSOLE FOR YES
  2080. ;
  2081. CHECKY: SAV
  2082.     CHARIN            ;READ CONSOLE
  2083.     RES
  2084.     CPI    'Y'        ;YES
  2085.     RZ
  2086.     JMP    ENDFIL        ;BACK TO INPUT IF NOT YES
  2087. ;
  2088. ;
  2089. ;    SIZE ROUTINE SETS SECTOR SIZES 128, 256, OR 512 BYTES
  2090. ;
  2091. SIZE:    CALL    GETNUM        ;GET SECTOR SIZE
  2092.     CPI    128        ;128 BYTE SECTOR
  2093.     RZ            ;STANDARD FORMAT RETURN ZERO SET
  2094.     LHLD    DECFULL        ;CONVERTED DECIMAL NUMBER
  2095.     LXI    D,-256        ;COMPARE HL WITH 256
  2096.     DAD    D
  2097.     MOV    A,H
  2098.     ORA    L        ;TEST ZERO
  2099.     JNZ    SIZE1
  2100.     MVI    A,1
  2101.     STA    SECSIZ        ;256 BYTE SECTORS
  2102.     MVI    A,16
  2103.     STA    NUMSEC        ;NUMBER OF SECTORS
  2104.     MVI    A,26
  2105.     STA    DNUMSEC
  2106.     LXI    H,256
  2107.     SHLD    BYTES        ;BYTES PER SECTOR
  2108.     MVI    A,32        ;ADDR LEADER GAP
  2109.     STA    GAP
  2110.     MVI    A,46
  2111.     STA    DGAP        ;ADDR LEADER GAP (MFM)
  2112.     LXI    H,316        ;SECTOR OFFSET (FM)
  2113.     SHLD    FILOFF
  2114.     LXI    H,359        ;SECTOR OFFSET (MFM)
  2115.     SHLD    DFILOFF
  2116.     RET
  2117. SIZE1:    LHLD    DECFULL        ;CONVERTED DECIMAL NUMBER
  2118.     LXI    D,-512        ;COMPARE HL WITH 512
  2119.     DAD    D        ;ADD TO HL
  2120.     MOV    A,H
  2121.     ORA    L
  2122.     JNZ    SIZE3        ;ERROR NOT 512 OR 128
  2123.     MVI    A,2        ;SET SIZE TO 512
  2124.     STA    SECSIZ
  2125.     LXI    H,512        ;BYTES PER SECTOR
  2126.     SHLD    BYTES
  2127.     MVI    A,8        ;SECTORS PER TRACK
  2128.     STA    NUMSEC
  2129.     MVI    A,16
  2130.     STA    DNUMSEC        ;SECTORS PER TRACK (MFM)
  2131.     MVI    A,50        ;ADDR LEADER GAP
  2132.     STA    GAP
  2133.     MVI    A,64
  2134.     STA    DGAP
  2135.     LXI    H,590        ;OFFSET FOR 512 BYTES (FM)
  2136.     SHLD    FILOFF
  2137.     LXI    H,633
  2138.     SHLD    DFILOFF        ;OFFSET FOR 512 BYTES (MFM)
  2139.     RET
  2140. SIZE3:    PRINT    <CR,LF,LF,'ERROR IN FORMAT SECTOR SIZE',CR,LF,BEL>
  2141.     JMP    ENDFIL
  2142. ;
  2143. ;    DENSEL -  SELECT DENSITY
  2144. ;    FOR DELTA DOUBLE DENSITY CONTROLLER
  2145. ;
  2146.     IF    DELTA
  2147. DENSEL:    CPI    'D'        ;DOUBLE DENSITY ?
  2148.     JZ    DENSEL1
  2149.     MVI    A,2
  2150.     OUT    WAIT+1        ;SELECT SINGLE DENSITY
  2151.     XRA    A
  2152.     STA    DDFLG
  2153.     RET
  2154. DENSEL1:MVI    A,1        ;SELECT DOUBLE DENSITY
  2155.     OUT    WAIT+1
  2156.     MVI    A,0FFH
  2157.     STA    DDFLG
  2158.     RET
  2159.     ENDIF
  2160. ;
  2161. ;    FOR NEW TARBELL DOUBLE DENSITY CONTROLLER
  2162. ;
  2163.     IF    TARBELL
  2164. DENSEL:    CPI    'D'        ;DOUBLE DENSITY
  2165.     JZ    DENSEL1
  2166.     XRA    A
  2167.     STA    DDFLG        ;SET DENSITY FLAG
  2168.     LDA    LATCH
  2169.     ANI    0F7H
  2170.     STA    LATCH
  2171.     OUT    WAIT        ;SELECT SINGLE DENSITY
  2172.     RET
  2173. DENSEL1:MVI    A,0FFH
  2174.     STA    DDFLG
  2175.     LDA    LATCH
  2176.     ORI    08H
  2177.     STA    LATCH
  2178.     OUT    WAIT        ;SELECT DOUBLE DENSITY
  2179.     RET
  2180.     ENDIF
  2181. ;
  2182. ;
  2183. ;    FOR OLD TARBELL 1771 BASED CONTROLLER
  2184. ;
  2185.     IF     NOT TARBELL AND NOT DELTA
  2186. DENSEL:    CPI    'D'
  2187.     RNZ            ;JUST RETURN IF NOT DD
  2188.     PRINT    <CR,LF,'DOUBLE DENSITY NOT AVAILABLE FOR 1771',CR,LF>
  2189.     JMP    ENDFIL
  2190.     ENDIF
  2191. ;
  2192. ;    GETDRV  SEARCH COMMAND STRING FOR DRIVE NAME AND RETURN CODE
  2193. ;    A:=0 B:=1 C:=2 D:=3   CARRY SET IF DRIVE PRESENT
  2194. ;    GETDRV IS CALLED WITH HL POINTING TO STARTING POSITION FOR SEARCH
  2195. ;
  2196. GETDRV:    SAV            ;SAVE REGS
  2197.     LXI    D,DSKNAME    ;POINT TO NAME TABLE
  2198.     MVI    C,0        ;DRIVE NUMBER
  2199. GD1:    SAV
  2200.     MVI    B,40H        ;STRING LENGTH
  2201.     MVI    C,2        ;SUBSTRING LENGTH
  2202.     INSTR    
  2203.     RES
  2204.     JC    GD3        ;FOUND NAME ON CARRY
  2205.     MOV    A,C        ;DRIVE NO TO A
  2206.     CPI    3        ;CHECK LIMIT
  2207.     JZ    GD3
  2208.     INR    C        ;INCR DRIVE NO
  2209.     INX    D
  2210.     INX    D        ;POINT TO NEXT NAME
  2211.     JMP    GD1        ;LOOP FOR 4 DRIVES
  2212. GD3:    MOV    A,C        ;DRIVE NO TO A
  2213.     RES
  2214.     RET
  2215. ;
  2216. DSKNAME:DB    'A:'        ;TABLE OF DISK NAMES
  2217.     DB    'B:'
  2218.     DB    'C:'
  2219.     DB    'D:'
  2220. ;
  2221. ;    PRNDRV  PRINT DRIVE NAME CORRESPONDING TO CODE IN A REG
  2222. ;    0=A 1=B 2=C 3=D  >3 ERROR
  2223. ;
  2224. PRNDRV:    SAV
  2225.     CPI    4        ;CHECK RANGE
  2226.     JP    PRDR3        ;ERROR IF > 3
  2227.     ADI    'A'        ;CALC LETTER TO PRINT
  2228.     CHAROUT            ;PRINT IT
  2229. PRDR1:    RES
  2230.     RET
  2231. PRDR3:    PRINT    <CR,LF,'ERROR - DRIVE NUMBER GREATER THAN 3',CR,LF>
  2232.     JMP    PRDR1
  2233. ;
  2234. ;
  2235. ;
  2236. ;
  2237. ;    EQUATES AND DATA ALLOCATIONS
  2238. ;
  2239. DISK    EQU    0F8H        ;DISK BASE ADDR
  2240. DCOM    EQU    DISK            ;DISK COMMAND PORT
  2241. STATP    EQU    DISK        ;DISK STATUS PORT
  2242. TRACK    EQU    DISK+1            ;DISK TRACK COMMAND
  2243. SECTP    EQU    DISK+2            ;DISK SECTOR PORT
  2244. DDATA    EQU    DISK+3            ;DISK DATA PORT
  2245. WAIT    EQU    DISK+4            ;DISK WAIT CONTROL PORT
  2246. SPACE:    DB    ' $'        ;ASCII SPACE
  2247. CRLF:    DB    0DH,0AH,24H    ;ASCII CR LF
  2248. CNT:    DB    0        ;TEMP COUNTER
  2249. TNUM:    DW    0        ;TRACK NUMBER
  2250. SNUM:    DW    0        ;SECTOR NUMBER
  2251. HARDERR:DW    0        ;HARD DISK ERRORS
  2252. SOFTERR:DW    0        ;SOFT DISK ERRORS
  2253. ERRORS:    DB    0        ;RETRY COUNTER DURING READ OR VERIFY
  2254. VERERR:    DB    0        ;VERIFY ERROR FLAG, SET TO FF ON COPY ERROR
  2255. VERFLG:    DB    0        ;FLAG WHEN FF NO VERIFICATION DURING COPY
  2256. NOFILL    DB    0        ;FLAG, WHEN TRUE (FF) NO FILL WITH E5 ON ERROR
  2257. FORMSW:    DB    0        ;COPY FORMAT SWITCH FORMAT IF TRUE (FF)
  2258. RETRYS:    DB    0        ;MAXIMUM NUMBER OF RETRYS
  2259. INFLAG:    DB    0        ;FLAG, IF TRUE RETURN FOR MORE CONSOLE INPUT
  2260. VALFLG:    DB    0        ;VALIDATION FLAG, VALIDATE AFTER FORMAT IF 0
  2261. DDFLG:    DB    0        ;DOUBLE DENSITY FLAG
  2262. SKF:    DB    0        ;SKEW FACTOR
  2263. TRKLIM:    DB    0        ;THE NUMBER OF TRACKS THAT FIT IN MEMORY
  2264. OFFSET:    DB    0        ;TRACK SECTOR OFFSET
  2265. DRIVE:    DB    0        ;STORAGE FOR ORIGINALLY LOGGED DRIVE NO
  2266. DRVNO    DB    0        ;SELECTED DRIVE
  2267. NEWDRV:    DB    0        ;NEW DRIVE NO
  2268. LATCH    DB    0        ;LATCH COMMAND
  2269. TRKTBL:    DB    0        ;TRACK POS A:
  2270.     DB    0        ;TRACK POS B:
  2271.     DB    0        ;TRACK POS C:
  2272.     DB    0        ;TRACK POS D:
  2273. SOURCE:    DB    0        ;SOURCE DRIVE FOR COPY OPERATION
  2274. DEST:    DB    0        ;DESTINATION DRIVE FOR COPY
  2275. OLDSTK:    DW    0        ;OLD STACK POINTER
  2276. ENDSTK:    DS    48        ;NEW STACK
  2277. NEWSTK:    DW    0        ;TOP OF NEW STACK
  2278. SECSIZ:    DB    0        ;SECTOR SIZE CODE FOR FORMAT (0,1 OR 2)
  2279. NUMSEC:    DB    0        ;NUMBER OF SECTORS PER TRACK
  2280. DNUMSEC:DB    0        ;NUMBER OF BYTES PER SECTOR (MFM)
  2281. FSECT:    DB    0        ;SECTOR COUNT USED IN FORMATTING
  2282. BYTES:    DW    0        ;NUMBER OF BYTES PER SECTOR
  2283. GAP:    DB    0        ;FORMAT ADDR LEADER GAP
  2284. DGAP:    DB    0        ;FORMAT ADDR LEADER GAP (MFM)
  2285. FILOFF:    DW    0        ;SECTOR OFFSET IN TRACK BUFFER (FM)
  2286. DFILOFF:DW    0        ;SECTOR OFFSET IN TRACK BUFFER (MFM)
  2287. FOFF:    DW    0        ;TEMP STORAGE FOR SECTOR OFFSET
  2288. CPYOFF:    DB    0        ;OFFSET USED FOR COPY ROUTINES
  2289. TRK:    DB    0        ;TRACK NUMBER USED IN FORMATTING DISK
  2290. SEC:    DB    0        ;SECTOR COUNT USED IN FORMATTING
  2291. STRK:    DW    0        ;STARTING TRACK FOR FORMAT OR COPY
  2292. ETRK:    DW    0        ;ENDING TRACK FOR FORMAT OR COPY
  2293. STRKR:    DB    0        ;STARTING TRACK FOR READ
  2294. STRKW:    DB    0        ;STARTING TRACK FOR WRITE
  2295. PSEC:    DW    0        ;PHYSICAL SECTOR
  2296. PSEC1:    DW    0        ;ANOTHER
  2297. LSEC:    DW    0        ;LOGICAL SECTOR
  2298. LSEC1:    DW    0        ;ANOTHER
  2299. BBLOCK:    DW    0        ;POINTER TO START OF CURRENT READ BLOCK
  2300. SECMAP:    DS    104        ;PHYSICAL TO LOGICAL SECTOR MAP FOR READ
  2301. SECMAP1:DS    104        ;SECTOR MAP FOR WRITE
  2302. SECMAP0:DS    53        ;SECTOR MAP TRACK ZERO - ALWAYS SINGLE DENSITY
  2303. TRKSIZE:DW    0        ;NO OF BYTES PER TRACK FOR COPY ROUTINES
  2304. DENCODE:DB    0        ;DOUBLE DENSITY CODE (LAST BYTE SECTOR 1 T 0)
  2305. CODE:    DB    0        ;SPECIAL CODE FOR DISK ID FOR PASCAL
  2306. DENTEMP:DB    0        ;TEMP STORAGE FOR DDFLG
  2307. SIZTEMP:DB    0        ;TEMP STORAGE FOR SECSIZ
  2308. SECTEMP:DB    0        ;TEMP STORAGE FOR NUMSEC
  2309. BYTETEMP:DW    0        ;TEMP STORAGE FOR BYTES
  2310. GAPTEMP:DB    0        ;TEMP STORAGE FOR GAP
  2311. OFFTEMP:DW    0        ;TEMP STORAGE FOR OFFSET
  2312. DDMAP:    DB    1,18,35,10,27,44,2,19,36,11,28,45,3
  2313.     DB    20,37,12,29,46,4,21,38,13,30,47,5
  2314.     DB    22,39,14,31,48,6,23,40,15,32,49,7
  2315.     DB    24,41,16,33,50,8,25,42,17,34,51,9,26,43
  2316. ;
  2317. DDMAP1:    DB    1,35,27,2,36,28,3,37,29,4,38,30,5,39,31
  2318.     DB    6,40,32,7,41,33,8,42,34,9,43,18,10,44,19,11,45
  2319.     DB    20,12,46,21,13,47,22,14,48,23,15,49,24,16,50
  2320.     DB    25,17,51,26
  2321. DECFULL:DW    0        ;FULL 16 BIT VALUE OF DECIMAL INPUT
  2322. IDECNT:    DB    0        ;ERROR COUNT FOR ID READ
  2323. IDTAB:    DB    0        ;ADDR FIELD FOR ID READ
  2324. IDTAB1:    DB    0        ;ZERO
  2325. IDTAB2:    DB    0        ;SECTOR ADDR
  2326. IDTAB3:    DB    0        ;ZERO
  2327. IDTAB4:    DB    0        ;CRC
  2328. IDTAB5:    DB    0        ;CRC
  2329. TRKBUF:    DB    0        ;BUFFER STORAGE
  2330.     END
  2331. ;
  2332. ;
  2333.