home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / sigm / vols000 / vol041 / xerox.z80 < prev   
Text File  |  1984-04-29  |  12KB  |  659 lines

  1. ;    XEROX REQUIRES 4MHZ ZPU OPERATION
  2.     EXTRN    BINH2
  3. XEROX:    
  4.     ld    hl,(6)
  5.     ld    sp,hl
  6.     LD    A,(5CH);    CDOS FCB-1
  7.     LD    (TO),A
  8.     LD    A,(6CH);    CDOS FCB-2
  9.     LD    (FROM),A
  10.     LD    A,(TO)
  11.     OR    A
  12.     JR    NZ,NXT
  13.     LD    C,C.DISK
  14.     CALL    CDOS
  15.     INC    A
  16.     LD    (TO),A
  17. NXT:
  18.     LD    A,(FROM)
  19.     OR    A
  20.     JR    NZ,NXT2
  21.     LD    C,C.DISK
  22.     CALL    CDOS
  23.     INC    A
  24.     LD    (FROM),A
  25. NXT2:
  26.     LD    HL,TO
  27.     CP    (HL)
  28.     JR    NZ,NXT2A
  29.     LD    DE,NOTSAME
  30.     LD    C,W.LINE
  31.     CALL    CDOS
  32.     JP    0
  33. NOTSAME:DB    LF,CR,BEL,BEL,BEL,'CANNOT COPY TO SAME FLOPPY',LF,CR,'$'
  34. NXT2A:    
  35.     LD    A,(TO)
  36.     ADD    40H
  37.     LD    (DR),A
  38.     LD    DE,QUEST
  39.     LD    C,W.LINE
  40.     CALL    CDOS
  41.     LD    C,R.CHAR
  42.     CALL    CDOS
  43.     CP    'Y'
  44.     JR    Z,OK
  45.     CP    'y'
  46.     JR    Z,OK
  47.     JP    0
  48. QUEST:    DB    LF,CR,BEL,BEL,BEL,'OK TO DESTROY CURRENT CONTENTS OF FLOPPY ON DRIVE '
  49. DR:    DB    ' ? $'
  50. CRLF:    DB    LF,CR,'$'
  51. FROM:    DB    0
  52. TO:    DB    0
  53. CURR:    DB    0
  54. SAMEDR:    DB    0
  55. DENSITY: DB    0
  56. RETRY:    DB    0
  57. HLSAVE:    DW    0
  58. TRKSINMEM: DB    0
  59. TRKIN:    DB    0
  60. TRKOUT:    DB    0
  61. TRKCNT:    DB    0
  62.     ENTRY    $MEMRY
  63. $MEMRY:    DW    0
  64. OK:
  65.     LD    DE,CRLF
  66.     LD    C,W.LINE
  67.     CALL    CDOS
  68.     LD    A,0;    TEST IF FLOPPIES ON SAME DUAL DRIVE
  69.     LD    (SAMEDR),A
  70.     LD    A,(FROM)
  71.     LD    B,A
  72.     LD    A,(TO)
  73.     SUB    B
  74.     JP    P,POSA
  75.     NEG
  76. POSA:    CP    1
  77.     JR    NZ,NOTONE;    NO
  78.     LD    A,(TO);        IF DIFFERENCE IS ONE IT MUST BE A 1,2 OR 3,4
  79.     CP    B;                        COMBINATION
  80.     JP    P,AGR
  81.     LD    A,B
  82. AGR:    RRA;            I.E. THE LARGEST MUST BE EVEN
  83.     JR    C,NOTONE;        NOT ON SAME DUAL DRIVE
  84.     LD    (SAMEDR),A
  85. NOTONE:    
  86.     LD    A,(FROM)
  87.     LD    B,A
  88.     XOR    A
  89.     SCF
  90. NXT3:    RLA
  91.     DJNZ    NXT3
  92.     OR    MOTORON+MAXI+DBLDEN
  93.     LD    (FROM),A
  94.     LD    A,(TO)
  95.     LD    B,A
  96.     XOR    A
  97.     SCF
  98. NXT4:    RLA
  99.     DJNZ    NXT4
  100.     OR    MOTORON+MAXI+DBLDEN
  101.     LD    (TO),A
  102. MSKINTRP: EQU    03H
  103. AUXDSK: EQU    04H;        INPUT/OUTPUT PORT FOR FAST SEEK
  104.     FASTSEEK: EQU    0EFH
  105.     SEEKCOMP: EQU    40H
  106.     RESETFST: EQU    0FFH
  107. ;
  108. DSKSTAT:EQU    30H;        INPUT PORT FOR DISK STATUS
  109.     NOTREADY: EQU    80H
  110.     PROTECT:EQU    40H
  111.     HEADDOWN: EQU    20H
  112.     WRFAULT:EQU    20H
  113.     NOTFND: EQU    10H
  114.     CRCERR: EQU    08H
  115.     LOSTDATA: EQU    04H
  116.     DRQ:    EQU    02H
  117.     BUSY:    EQU    01H
  118. ;
  119. DSKCMD:    EQU    30H;        OUTPUT PORT FOR DISK COMMANDS
  120.     RESTORE:EQU    0CH
  121.     SEEK:    EQU    18H
  122.     READ:    EQU    88H
  123.     ENBLHOLD: EQU    04H
  124.     WRITE:    EQU    0A8H
  125.     RESET:    EQU    0D0H
  126. ;
  127. TRKREG:    EQU    31H;        I/O PORT FOR TRACK REGISTER
  128. ;
  129. SECREG:    EQU    32H;        I/O PORT FOR SECTOR REGISTER
  130. ;
  131. DATAREG:EQU    33H;        I/O PORT FOR DATA
  132. ;
  133. DSKCNTRL:EQU    34H;        OUTPUT PORT FOR DISK CONTROL
  134.     MOTORON:EQU    20H
  135.     MAXI:    EQU    10H
  136.     DBLDEN:    EQU    40H
  137.     AUTOWAIT: EQU    80H
  138. ;
  139. DSKFLGS:EQU    34H;        INPUT PORT FOR DISK FLAGS
  140.     HEADLOAD: EQU    20H
  141.     EOJ:    EQU    01H
  142. ;
  143. CDOS:    EQU    5;        CDOS CALL ADDRESS
  144. ;    CDOS CALL CODES
  145.     C.DISK: EQU    25
  146.     R.CHAR: EQU    1
  147.     W.LINE: EQU    9
  148.     DIVIDE: EQU    138
  149.     RES.CDOS: EQU    13
  150.     SEL.DISK: EQU    14
  151. ;    TTY CONTROL CODES
  152. CR:    EQU    0DH
  153. LF:    EQU    0AH
  154. BEL:    EQU    07H
  155. ;    DISK CONSTANTS
  156. MAXRETRY: EQU    10    ; NUMBER OF RETRIES IF R/W ERROR
  157. NRTRKS:    EQU    77
  158. NRSECS:    EQU    26    ; SINGLE DEN
  159. NRSECS2: EQU    16    ; DOUBLE DEN
  160. TRKSIZE:EQU    NRSECS2*512;    SIZE OF A TRACK
  161. TRKSIZ1:EQU    NRSECS*128
  162.     XOR    A
  163.     LD    (TRKIN),A
  164.     LD    (TRKOUT),A
  165.     LD    HL,($MEMRY);    GET START OF BUFFER
  166.     EX    DE,HL;        SAVE IN DE
  167.     LD    HL,(6);        GET HIGHEST MEMORY ADDRESS
  168.     SCF    
  169.     SBC    HL,DE;        CALCULATE AVAILABLE MEMORY
  170.     LD    DE,TRKSIZE;    SIZE OF A TRACK
  171.     LD    C,DIVIDE
  172.     CALL    CDOS
  173.     LD    A,L
  174.     LD    (TRKSINMEM),A;    SET MAX. NR OF TRACKS READABLE
  175.     LD    A,(FROM)
  176.     AND    NOT DBLDEN    ; DISABLE DOUBLE DENSITY FOR HOME
  177.     LD    (CURR),A
  178.     OUT    DSKCNTRL,A;    SELECT INPUT DISK
  179.     LD    D,NOTREADY+NOTFND+CRCERR+BUSY
  180.     LD    A,RESTORE;    RESTORE DISK TO TRACK ZERO
  181.     CALL    EXECUTE
  182.     LD    A,(TO)
  183.     AND    NOT DBLDEN
  184.     LD    (CURR),A
  185.     OUT    DSKCNTRL,A
  186.     LD    D,NOTREADY+PROTECT+NOTFND+CRCERR+BUSY
  187.     LD    A,RESTORE
  188.     CALL    EXECUTE
  189. ; READ IN FIRST SECTOR TO SEE IF DOUBLE OR SINGLE DENSITY
  190.     LD    HL,($MEMRY)
  191.     LD    A,(FROM)
  192.     AND    NOT DBLDEN
  193.     LD    (CURR),A
  194.     CALL    SETUP
  195.     ADD    READ
  196.     LD    D,NOTREADY+NOTFND+CRCERR+LOSTDATA
  197.     LD    C,SECREG
  198.     LD    E,1
  199.     OUT    (C),E
  200.     LD    C,DATAREG
  201.     OUT    DSKCMD,A;    START READING
  202. LOOP2:    
  203.     IN    A,DSKFLGS;    WAIT FOR DRQ OR EOJ
  204.     RRA
  205.     JR    C,DENSREADY;    EOJ FOUND?
  206.     INI;            PLACE NEXT BYTE AT (HL) AND UPDATE
  207.     JR    LOOP2;        GET NEXT BYTE FROM SECTOR
  208. DENSREADY:
  209.     IN    A,DSKSTAT;    GET STATUS AFTER SECTOR
  210.     LD    B,A
  211.     AND    D
  212.     JP    NZ,ERROR
  213.     LD    IX,($MEMRY)
  214.     LD    A,'L'
  215.     CP    (IX+78H)
  216.     JR    NZ,SINGLE
  217.     LD    A,'G'
  218.     CP    (IX+79H)
  219.     JR    NZ,SINGLE
  220.     LD    A,'S'
  221.     CP    (IX+7AH)
  222.     JR    NZ,SINGLE
  223.     CP    (IX+7BH)
  224.     JR    NZ,SINGLE
  225.     LD    A,'D'
  226.     CP    (IX+7CH)
  227.     JR    NZ,SINGLE
  228.     CP    (IX+7DH)
  229.     JR    NZ,SINGLE
  230.     LD    A,0FFH
  231.     LD    (DENSITY),A
  232.     LD    DE,DOUBLEDEN
  233.     JR    DENMESS
  234. SINGLE:
  235.     XOR    A
  236.     LD    (DENSITY),A
  237.     LD    DE,SINGLEDEN
  238. DENMESS:
  239.     LD    C,W.LINE
  240.     CALL    CDOS
  241.     JR    RESTART
  242. DOUBLEDEN: DB    'Double density transfer.',CR,LF,'$'
  243. SINGLEDEN: DB    'Single density transfer.',CR,LF,'$'
  244. RESTART:
  245.     LD    HL,($MEMRY)
  246.     LD    A,0
  247.     LD    (TRKCNT),A
  248.     LD    A,(DENSITY)
  249.     OR    A
  250.     JR    Z,SNGSKP1
  251.     IN    A,TRKREG
  252.     OR    A    ; CHECK FOR TRACK 2 OR GREATER
  253. SNGSKP1: LD    A,(FROM)
  254.     JR    NZ,DBLSKP1
  255.     AND    NOT DBLDEN
  256. DBLSKP1:
  257.     LD    (CURR),A
  258.     CALL    SETUP;        PREPARE DISK FOR COMING OPERATION
  259.     ADD    READ;        CONSTRUCT READ COMMAND
  260. RDTRACK:
  261.     LD    E,1;        SECTOR    COUNTER
  262.     LD    D,NOTREADY+NOTFND+CRCERR+LOSTDATA
  263.     PUSH    HL
  264.     LD    HL,RETRY
  265.     LD    (HL),0
  266.     POP    HL
  267. AGAIN:
  268.     LD    (HLSAVE),HL    ;SAVE FOR RETRIES
  269.     LD    C,SECREG
  270.     OUT    (C),E
  271.     LD    C,DATAREG
  272.     OUT    DSKCMD,A;    START READING
  273. AGAIN2:    
  274.     IN    A,DSKFLGS;    WAIT FOR DRQ OR EOJ
  275.     RRA
  276.     JR    C,READREADY;    EOJ FOUND?
  277.     INI;            PLACE NEXT BYTE AT (HL) AND UPDATE
  278.     JR    AGAIN2;        GET NEXT BYTE FROM SECTOR
  279. READREADY:
  280.     IN    A,DSKSTAT;    GET STATUS AFTER SECTOR
  281.     LD    B,A
  282.     AND    D
  283.     JP    NZ,RERROR
  284.     LD    A,E
  285.     CP    NRSECS
  286.     JP    Z,LSTSEC;    LAST SECTOR OF TRACK INPUT
  287.     LD    A,(DENSITY)
  288.     OR    A
  289.     JR    Z,DBLSKP4
  290.     IN    A,TRKREG    ; CHECK FOR DBLDEN
  291.     OR    A
  292.     JR    Z,DBLSKP4
  293.     LD    A,E
  294.     CP    NRSECS2
  295.     JP    Z,LSTSEC
  296. DBLSKP4: INC    E
  297. RRETRY:
  298.     LD    A,(DENSITY)
  299.     OR    A
  300.     JR    Z,SNGSKP8
  301.     IN    A,TRKREG
  302.     OR    A    ; CHECK FOR TRACK 2 OR GREATER
  303. SNGSKP8:
  304.     LD    A,(FROM)
  305.     JR    NZ,DBLSKP8
  306.     AND    NOT DBLDEN
  307. DBLSKP8:
  308.     OR    AUTOWAIT
  309.     OUT    DSKCNTRL,A
  310.     LD    A,READ
  311.     JR    AGAIN
  312. RERROR:
  313.     LD    A,(RETRY)
  314.     CP    MAXRETRY
  315.     JP    Z,ERROR
  316.     INC    A
  317.     LD    (RETRY),A
  318.     PUSH    DE
  319.     PUSH    BC
  320.     LD    A,B
  321.     LD    HL,RSTAT;    SET ERROR OR STATUS BITS
  322.     CALL    BINH2
  323.     IN    A,TRKREG;    GET TRACK-NUMBER
  324.     LD    HL,RTRK
  325.     CALL    BINH2
  326.     IN    A,SECREG;    GET SECTOR-NUMBER
  327.     LD    HL,RSEC
  328.     CALL    BINH2
  329.     LD    DE,MESRETRY
  330.     LD    C,W.LINE
  331.     CALL    CDOS
  332.     POP    BC
  333.     POP    DE
  334.     LD    HL,(HLSAVE)
  335.     JR    RRETRY
  336. MESRETRY: DB    'Retry, Status = '
  337. RSTAT:    DB    '  , Track = '
  338. RTRK:    DB    '  , Sector = '
  339. RSEC:    DB    '  .',CR,LF,'$'
  340. LSTSEC:
  341.     LD    A,(TRKIN);    DO IT FOR 77 TRACKS
  342.     CP    NRTRKS-1
  343.     JP    Z,WRTHEM
  344.     INC    A
  345.     LD    (TRKIN),A
  346.     LD    B,A
  347.     DEC    A
  348.     CALL    SEEKTRK;    GO TO NEXT TRACK
  349.     LD    A,(TRKSINMEM)
  350.     LD    B,A
  351.     LD    A,(TRKCNT)
  352.     INC    A
  353.     CP    B
  354.     JP    Z,WRTHEM
  355.     LD    (TRKCNT),A
  356.     LD    A,(DENSITY)
  357.     OR    A
  358.     JR    Z,SNGSKPA
  359.     IN    A,TRKREG
  360.     OR    A    ; CHECK FOR TRACK 2 OR GREATER
  361. SNGSKPA:
  362.     LD    A,(FROM)
  363.     JR    NZ,DBLSKPA
  364.     AND    NOT DBLDEN
  365. DBLSKPA:
  366.     OR    AUTOWAIT
  367.     OUT    DSKCNTRL,A
  368.     LD    A,READ
  369.     JP    RDTRACK
  370. WRTHEM:
  371.     LD    HL,($MEMRY)
  372.     LD    A,0
  373.     LD    (TRKCNT),A
  374.     LD    A,(SAMEDR);    TEST IF ON SAME DUAL DRIVE IS INPUT
  375.     OR    A
  376.     JR    Z,DIFDR;    NO
  377.     LD    A,(TRKOUT)
  378.     LD    B,A
  379.     LD    A,(TRKIN)
  380.     CALL    SEEKTRK;    SEEK BACK TO WRITING POSITION
  381. DIFDR:
  382.     LD    A,(TRKOUT)
  383.     OUT    TRKREG,A
  384.     LD    A,(DENSITY)
  385.     OR    A
  386.     JR    Z,SNGSKP2
  387.     IN    A,TRKREG
  388.     OR    A    ; CHECK FOR TRACK 2 OR GREATER
  389. SNGSKP2:
  390.     LD    A,(TO)
  391.     JR    NZ,DBLSKP2
  392.     AND    NOT DBLDEN
  393. DBLSKP2:
  394.     LD    (CURR),A
  395.     CALL    SETUP;        PREPARE DISK FOR COMING OPERATION
  396.     ADD    WRITE;        CONTRUCT WRITE COMMAND
  397. WRTRACK:
  398.     LD    E,1;        SECTOR COUNTER
  399.     LD    D,NOTREADY+PROTECT+WRFAULT+NOTFND+CRCERR+LOSTDATA
  400. BACK:
  401.     LD    C,SECREG
  402.     OUT    (C),E
  403.     LD    C,DATAREG
  404.     OUT    DSKCMD,A;    START WRITING
  405. BACK2:
  406.     IN    A,DSKFLGS;    WAIT FOR DRQ OR EOJ
  407.     RRA
  408.     JR    C,WRREADY;    EOJ FOUND?
  409.     OUTI;            GET NEXT BYTE FROM (HL) AND UPDATE
  410.     JR    BACK2;        WRITE NEXT BYTE TO SECTOR
  411. WRREADY:
  412.     IN    A,DSKSTAT;    GET STATUS AFTER SECTOR
  413.     LD    B,A
  414.     AND    D
  415.     JP    NZ,ERROR
  416.     LD    A,E;
  417.     CP    NRSECS
  418.     JR    Z,VERIFY;    LAST SECTOR OF TRACK WRITTEN
  419.     LD    A,(DENSITY)
  420.     OR    A
  421.     JR    Z,DBLSKP5
  422.     IN    A,TRKREG    ; CHECK FOR DBLDEN
  423.     OR    A
  424.     JR    Z,DBLSKP5
  425.     LD    A,E
  426.     CP    NRSECS2
  427.     JR    Z,VERIFY
  428. DBLSKP5: INC    E
  429.     LD    A,(DENSITY)
  430.     OR    A
  431.     JR    Z,SNGSKP9
  432.     IN    A,TRKREG
  433.     OR    A    ; CHECK FOR TRACK 2 OR GREATER
  434. SNGSKP9:
  435.     LD    A,(TO)
  436.     JR    NZ,DBLSKP9
  437.     AND    NOT DBLDEN
  438. DBLSKP9:
  439.     OR    AUTOWAIT
  440.     OUT    DSKCNTRL,A
  441.     LD    A,WRITE
  442.     JR    BACK
  443. VERIFY:
  444.     LD    E,1;        RESTART AT FIRST SECTOR
  445.     LD    D,NOTREADY+NOTFND+CRCERR+LOSTDATA
  446. BACK3:
  447.     LD    A,(DENSITY)
  448.     OR    A
  449.     JR    Z,SNGSKP3
  450.     LD    A,(TRKOUT)
  451.     OR    A    ; CHECK FOR TRACK 2 OR GREATER
  452. SNGSKP3:
  453.     LD    A,(TO)
  454.     JR    NZ,DBLSKP3
  455.     AND    NOT DBLDEN
  456. DBLSKP3:
  457.     OR    AUTOWAIT
  458.     OUT    DSKCNTRL,A
  459.     LD    B,0FFH;        SET ERROR CODE TO "VERIFY ERROR"
  460.     LD    C,SECREG
  461.     OUT    (C),E
  462.     LD    A,READ
  463.     OUT    DSKCMD,A;    START READING
  464. BACK4:
  465.     IN    A,DSKFLGS;    WAIT FOR DRQ OR EOJ
  466.     RRA
  467.     JR    C,SECREAD;    IF EOJ, SECTOR IS READ
  468.     IN    A,DATAREG;    GET BYTE
  469.     JR    BACK4
  470. SECREAD:
  471.     IN    A,DSKSTAT;    STATUS AFTER SECTOR READ
  472.     LD    B,A
  473.     AND    D
  474.     JP    NZ,ERROR
  475.     LD    A,E;        LAST SECTOR OF TRACK?
  476.     CP    NRSECS
  477.     JR    Z,ENDVERIFY
  478.     LD    A,(DENSITY)
  479.     OR    A
  480.     JR    Z,DBLSKP6
  481.     IN    A,TRKREG    ; CHECK FOR DBLDEN
  482.     OR    A
  483.     JR    Z,DBLSKP6
  484.     LD    A,E
  485.     CP    NRSECS2
  486.     JR    Z,ENDVERIFY
  487. DBLSKP6: INC    E
  488.     JR    BACK3
  489. ENDVERIFY:
  490.     LD    A,(TRKOUT);    DO IT FOR 77 TRACKS
  491.     CP    NRTRKS-1
  492.     JP    Z,TERM
  493.     INC    A
  494.     LD    (TRKOUT),A
  495.     LD    B,A
  496.     DEC    A
  497.     CALL    SEEKTRK;    GO TO NEXT TRACK
  498.     LD    A,(TRKSINMEM);    CHECK IF END OF MEMORY
  499.     LD    B,A
  500.     LD    A,(TRKCNT)
  501.     INC    A
  502.     CP    B
  503.     JP    Z,RESTART
  504.     LD    (TRKCNT),A
  505.     LD    A,(DENSITY)
  506.     OR    A
  507.     JR    Z,SNGSKPB
  508.     IN    A,TRKREG
  509.     OR    A
  510. SNGSKPB:
  511.     LD    A,(TO)
  512.     JR    NZ,DBLSKPB
  513.     AND    NOT DBLDEN
  514. DBLSKPB:
  515.     OR    AUTOWAIT
  516.     OUT    DSKCNTRL,A
  517.     LD    A,WRITE
  518.     JP    WRTRACK
  519. ;
  520. ;THIS SUBROUTINE IS USED AFTER SWITCH TO NEW DRIVE TO PREPARE IT
  521. ;FOR A NEW SEQUENCE OF READS OR WRITES
  522. ;
  523. SETUP:
  524.     OUT    DSKCNTRL,A
  525.     LD    B,A;        READ/WRITE FROM FIRST SECTOR ONWARDS
  526.     LD    A,1;
  527.     OUT    SECREG,A
  528.     IN    A,DSKFLGS
  529.     AND    HEADLOAD;    HEAD LOADED?
  530.     LD    C,A
  531.     LD    A,B
  532.     OR    A,AUTOWAIT;    FOR NEXT COMMANDS USE AUTO WAIT MODE
  533.     OUT    DSKCNTRL,A
  534.     LD    A,C
  535.     OR    A;        WAS HEAD LOADED?
  536.     LD    A,4
  537.     RET    Z;        NO
  538.     XOR    A
  539.     RET
  540. ;
  541. ;THIS SUBROUTINE EXECUTES "RESTORES" AND "SEEKS" (ERROR MASK IN REG.D)
  542. ;
  543. EXECUTE:
  544.     OUT    DSKCMD,A
  545. WAIT:
  546.     IN    A,DSKFLGS;    CHECK IF READY
  547.     RRA
  548.     JR    NC,WAIT
  549.     IN    A,DSKSTAT
  550.     LD    B,A
  551.     AND    D;        COMPARE TO ERROR MASK
  552.     JR    NZ,ERROR
  553.     RET
  554. ;
  555. ;THIS ROUTINE EXECUTES A FAST SEEK FROM (A) TO (B)
  556. ;
  557. SEEKTRK:
  558.     OUT    TRKREG,A;    SET TO CURRENT TRACK
  559.     LD    A,B;        GET REQUIRED TRACK-NR
  560.     OUT    DATAREG,A;    GIVE DESIRED TRACK TO 4FDC
  561.     LD    A,FASTSEEK;    SET TO FAST SEEK
  562.     OUT    AUXDSK,A
  563.     LD    A,SEEK;
  564.     LD    D,NOTREADY
  565.     CALL    EXECUTE
  566. REDO2:    IN    A,AUXDSK;    SEEK COMPLETED?
  567.     AND    SEEKCOMP
  568.     JR    NZ,REDO2
  569.     LD    A,RESETFST;    RESET FAST SEEK MODE
  570.     OUT    AUXDSK,A
  571.     RET
  572. ;
  573. ;THIS HANDLES ANY ERROR AND TERMINATES THE PROGRAM WITH AN APPROPRIATE
  574. ;ERROR MESSAGE
  575. ;
  576. ERROR:
  577.     PUSH    BC;    SAVE ERROR STATUS
  578.     LD    A,B
  579.     LD    HL,ERSTAT;    SET ERROR OR STATUS BITS
  580.     CALL    BINH2
  581.     IN    A,TRKREG;    GET TRACK-NUMBER
  582.     LD    HL,TRK
  583.     CALL    BINH2
  584.     IN    A,SECREG;    GET SECTOR-NUMBER
  585.     LD    HL,SEC
  586.     CALL    BINH2
  587.     LD    A,RESET;    RESET ANY CURRENT COMMAND
  588.     OUT    DSKCMD,A
  589.     LD    A,(CURR)
  590.     AND    0FH
  591.     LD    B,1
  592. RRA:    RRA    ;        FIND OUT DEVICE NAME
  593.     JR    C,DEVFND
  594.     INC    B
  595.     JR    RRA
  596. DEVFND: LD    A,B
  597.     ADD    40H
  598.     LD    (DEV),A
  599.     LD    DE,ERMSG
  600.     LD    C,W.LINE
  601.     CALL    CDOS
  602.     POP    BC;        RESTORE ERROR FLAG
  603.     LD    A,B
  604.     LD    DE,VERFERR
  605.     CP    0FFH
  606.     JR    Z,ERTERM;    ERROR FOUND IN VERIFICATION
  607.     LD    DE,IOERR
  608.     AND    NOTFND+CRCERR
  609.     JR    NZ,ERTERM;    REAL READ OR WRITE ERROR
  610.     LD    A,B
  611.     LD    DE,READYERR
  612.     AND    NOTREADY
  613.     JR    NZ,ERTERM;    DRIVE IS NOT READY
  614.     LD    A,B
  615.     LD    DE,PROTERR
  616.     AND     PROTECT
  617.     JR    NZ,ERTERM;    FLOPPY IS WRITE PROTECTED
  618.     LD    A,B
  619.     LD    DE,WRERR
  620.     AND    WRFAULT
  621.     JR    NZ,ERTERM;    I/O ERROR ON WRITING
  622.     LD    DE,UNKNERR;    STRANGE ERROR
  623. ERTERM:
  624.     LD    C,W.LINE;    PREPARE FOR WRITE MESSAGE
  625.     CALL    CDOS
  626.     LD    DE,ERMSG2
  627.     CALL    CDOS
  628.     JP    TERM2
  629. VERFERR:DB    '(DATA READ BACK UNEQUAL TO DATA WRITTEN)$'
  630. IOERR:    DB    '(DATA ERROR WHEN READING OR WRITING)$'
  631. READYERR: DB    '(DRIVE NOT READY: MAKE READY AND RETRY)$'
  632. PROTERR:DB    '(FLOPPY IS WRITE PROTECTED)$'
  633. WRERR:    DB    '(DATA ERROR WHEN WRITING: RE-INITIALIZE FLOPPY)$'
  634. UNKNERR:DB    '(UNIDENTIFIABLE PROBLEM)$'
  635. ERMSG:    DB    BEL,BEL,BEL,'ERROR ',BEL,BEL,'ON DRIVE ',BEL,BEL,BEL
  636. DEV:    DB    ' , AT TRACK '
  637. TRK:    DB    '  , SECTOR '
  638. SEC:    DB    '  ,',LF,CR,'STATUS='
  639. ERSTAT: DB    '   $'
  640. ERMSG2: DB    '.',LF,CR,'PROGRAM PREMATURELY TERMINATED.$'
  641. TRMMSG:    DB    'FAST COPY OPERATION SUCCEEDED. FLOPPY WRITTEN AND VERIFIED.$'
  642. ;
  643. ;THIS TERMINATES THE PROGRAM AFTER RESTORING THE "CURRENT DISK" SELECTION
  644. ;
  645. TERM:
  646.     LD    C,W.LINE
  647.     LD    DE,TRMMSG
  648.     CALL    CDOS
  649. TERM2:
  650.     LD    C,C.DISK;    GET CURRENT DRIVE
  651.     CALL    CDOS
  652.     LD    E,A
  653.     LD    C,RES.CDOS;    RESET CDOS AND LOG OFF ALL DISKS
  654.     CALL    CDOS
  655.     LD    C,SEL.DISK;    RESTORE CURRENT DISK SELECTION
  656.     CALL    CDOS
  657.     JP    100H
  658.     END    XEROX
  659.