home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / sigm / vols000 / vol050 / format < prev    next >
Encoding:
Text File  |  1984-04-29  |  16.0 KB  |  1,047 lines

  1. ;Format - Data Technology Corporation CP/M 2.2 Format.
  2. ;
  3. ;    +-----------------------+
  4. ;    |            |
  5. ;    |      F O R M A T     |
  6. ;    |            |
  7. ;    +-----------------------+
  8. ;
  9. ;
  10. ;    Version number:    2.2B
  11. ;    Version date:    October 24, 1980
  12. ;
  13. ;    UPDATE    JANUARY 6,1981
  14. ;    ADD MRX101D DISK SIZE CONDITIONALS
  15. ;
  16. ;    Update March 31, 1981
  17. ;        Modified for assembly with ASM.
  18. ;        Parameterized for hard disk.
  19. ;
  20. ;    Update April 27, 1981
  21. ;        Modified for controller timeout.
  22. ;
  23. ;    Update date:    June 15, 1981
  24. ;        Modified for new configuration parameters.
  25. ;        Formats full hard disk only.
  26.  
  27. ;    The following code is supplied to customers who
  28. ;    purchase a hard/floppy disk system from DTC.
  29. ;    The following code formats floppy disks and the
  30. ;    hard disk contained within the DTC hard disk unit.
  31.  
  32.  
  33.  
  34.  
  35.  
  36. VERS:    EQU    22
  37.  
  38. CR:    EQU    0Dh        ;ASCII carrriage return
  39. LF:    EQU    0Ah        ;ASCII line feed
  40. EOS:    EQU    '$'        ;BDOS End of string
  41. TAB:    EQU    9        ;ASCII horizontal tab
  42. ERRCD:    EQU    0FFh        ;BDOS error code
  43.  
  44.  
  45.  
  46.  
  47.  
  48. ;    BDOS function equates.
  49.  
  50. PRTSTR:    EQU    09    ;Print String    DE = buffer address.
  51. RDCB:    EQU    10    ;Read console buffer   DE = buffer address.
  52. OPEN:    EQU    15    ;Open file   DE = FCB address.
  53. READS:    EQU    20    ;Read sequential file    DE = FCB.
  54. SETDMA:    EQU    26    ;Set DMA address    DE = DMA address.
  55.  
  56. ;    Page zero locations.
  57.  
  58. BDOSV:    EQU    5    ;BDOS JUMP ADDRESS.
  59. DFCB:    EQU    005Ch    ;Default FCB address.
  60. DBUF:    EQU    0080h    ;Default DMA buffer.
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67.  
  68.     ORG    100h
  69.  
  70.  
  71. FORMAT:
  72.     PUSH    PSW
  73.     PUSH    B
  74.     PUSH    D
  75.     PUSH    H
  76.     LXI    H,0
  77.     DAD    SP
  78.     SHLD    SYSTK        ;save system stack
  79.  
  80.  
  81.     LXI    SP,STACK
  82.     LXI    D,SMESSG    ;Output sign-on message
  83.     MVI    C,PRTSTR
  84.     CALL    BDOSV
  85.  
  86.     CALL    INITBF        ;intialize data buffer
  87. FORM1:    CALL    INITL        ;Intialize for formatting
  88.     LDA    DTYPE
  89.     MOV    B,A
  90.     ANI    TYPEDRV
  91.     JZ    FORM2        ;If floppy disk
  92.     MOV    A,B
  93.     ANI    TYPEN48+TYPEN96
  94.     JNZ    FORM2
  95.     CALL    FORMH        ;Format hard disk
  96.     JNZ    FORM1        ;If new disk requested
  97.     JMP    SYSRET
  98.  
  99. FORM2:    CALL    FORMF        ;Format floppy disk
  100.     JNZ    FORM1        ;If new disk requested
  101.     JMP    SYSRET
  102.  
  103.  
  104. ;    Return to system gracefully.
  105.  
  106. SYSRET:    LHLD    SYSTK
  107.     SPHL
  108.     POP    H
  109.     POP    D
  110.     POP    B
  111.     POP    PSW
  112.     RET            ;return to system
  113.  
  114. SMESSG:    DB    CR,LF,LF,LF
  115.     DB    'Data Technology Disk Format Program'
  116.     DB    ' Version ',VERS/10+'0','.',VERS mod 10 + '0'
  117.     DB    CR,LF,EOS
  118.  
  119.  
  120.  
  121.  
  122. ;    INITBF - Intialize data buffer with constant pettern.
  123.  
  124. INITBF:
  125.     MVI    C,0E5h
  126.     LHLD    BDOSV+1        ;Get buffer end address
  127.     XCHG
  128.     LXI    H,BUFFER
  129. IBF1:    MOV    M,C        ;Set a byte
  130.     INX    H
  131.     MOV    A,D
  132.     CMP    H
  133.     JNZ    IBF1
  134.     MOV    A,E
  135.     CMP    L
  136.     JNZ    IBF1        ;If entire buffer not set
  137.  
  138.     RET
  139.  
  140.  
  141.  
  142. ;    INITL - Get parameters from operator.
  143.  
  144. INITL:
  145.     XRA    A        ;Reset E5FLAG
  146.     STA    E5FLAG
  147. INIL1:    LXI    D,DMESSG    ;Output disk selection message
  148.     CALL    INFCRT
  149.     STA    LETTER
  150.     SUI    '0'
  151.     JM    INIL1        ;If invalid entry
  152.     CPI    4
  153.     JP    INIL1        ;If invalid entry
  154.     RRC
  155.     RRC
  156.     RRC
  157.     STA    DRVNO
  158.  
  159.     CALL    DDTYPE        ;Determine Disk type
  160.     JNZ    INIL4
  161.     LDA    DTYPE
  162.     MOV    B,A
  163.     ANI    TYPEDRV
  164.     JZ    INILf        ;If floppy disk unit
  165.     MOV    A,B        ; or mini floppy
  166.     ANI    18h
  167.     JNZ    INILf
  168.  
  169.     XRA    A
  170. INIL2:    LXI    D,HDMESG
  171.     CALL    INFCRT        ;Get hard disk response
  172.     CPI    'Y'
  173.     RNZ
  174.  
  175. INIL3:    LXI    D,INTMSG    ;Get interleave code
  176.     CALL    INFCRT
  177.     SUI    '1'
  178.     JM    INIL3        ;If invalid interleave code
  179.     CPI    16
  180.     JP    INIL3        ;If invlaid interleave code
  181.     INR    A
  182.     STA    HDILC        ;Save interleave code
  183.  
  184.     RET
  185.  
  186. INIL4:
  187.     LXI    D,ADTMSG
  188.     MVI    C,PRTSTR
  189.     CALL    BDOSV
  190.     JMP    INITL
  191.  
  192.  
  193. INILf:    LXI    D,DENMSG    ;Output density seclection
  194.     CALL    INFCRT
  195.     SUI    '1'
  196.     JM    INILf        ;If invalid density
  197.     CPI    2
  198.     JP    INILf        ;If invalid density
  199.     STA    FPDEN
  200.  
  201. INILg:    LXI    D,SIDMSG    ;Get number of sides
  202.     CALL    INFCRT
  203.     SUI    '1'
  204.     JM    INILg        ;If invalid number of sides
  205.     CPI    2
  206.     JP    INILg        ;If invalid number of sides
  207.     MOV    C,A
  208.     LDA    FPDEN
  209.     ADD    A
  210.     ADD    C
  211.     STA    FPSLV        ;Save format selection value
  212.     RET
  213.  
  214. DMESSG:    DB    CR,LF
  215.     DB    'Select Drive (0, 1, 2, 3): ',EOS
  216.  
  217. DENMSG:    DB    CR,LF
  218.     DB    'Select a sector size:'
  219.     DB    CR,LF
  220.     DB    '     1) 128 Byte Single density.'
  221.     DB    CR,LF
  222.     DB    '     2) 256 Byte Double density.'
  223.     DB    CR,LF
  224.     DB    'Sector Size: ',EOS
  225.  
  226. HDMESG:    DB    CR,LF
  227.     DB    'This program will format the entire hard disk.',CR,LF
  228.     DB    'Do you wish to continue (Y or N)? ',EOS
  229.  
  230. ADTMSG:    DB    CR,LF,'Assign Drive Type error.',EOS
  231.  
  232. INTMSG:    DB    CR,LF
  233.     DB    'Enter interleave value (1--16): '
  234.     DB    EOS
  235.  
  236. SIDMSG:    DB    CR,LF
  237.     DB    'Enter number of sides (1 or 2): '
  238.     DB    EOS
  239.  
  240.  
  241.  
  242.  
  243.  
  244. ;    FORMH - Format a hard disk unit.
  245.  
  246. FORMH:
  247.     CALL    SCMND        ;Set command buffers
  248.     LDA    HDILC        ;Set interleave code
  249.     STA    CIOFDC+4
  250.     LXI    H,CIOSTC
  251.     CALL    EXEC        ;Output command buffer
  252.     CZ    WAITF        ;Wait completion
  253.     MOV    A,C
  254.     ANI    FERR
  255.     JZ    FRMH1        ;If unit is ready
  256.     LXI    D,UNDMSG    ;Unit not available
  257.     MVI    C,PRTSTR
  258.     CALL    BDOSV
  259.     ORI    0FFh
  260.     RET
  261.  
  262. FRMH1:
  263.  
  264.     LXI    D,BFDMSG        ;Output message
  265.     MVI    C,PRTSTR
  266.     CALL    BDOSV
  267.  
  268.     LXI    H,CIOFDC
  269.     CALL    EXEC        ;Output Command
  270.     CZ    WAITF        ;Wait for completion
  271.     MOV    A,C
  272.     ANI    FERR
  273.     JZ    FRMH2        ;If no errors
  274.     LXI    H,CIOFDC
  275.     CALL    ERROR        ;Print error message
  276.     JMP    FORMH
  277.  
  278. FRMH2:
  279.     CALL    FRME5        ;Fill disk with E5s
  280.     JC    FORMH        ;Error
  281.     RET
  282.  
  283.  
  284. FRME5:
  285.     LDA    E5FLAG        ;Is data E5?
  286.     CPI    0E5h
  287.     JZ    FRMH7
  288.     ORA    A        ;No.  Has data been checked?
  289.     JNZ    FRMH12
  290.     LXI    H,0
  291.     SHLD    CIORED+2
  292.     LXI    H,CIORED    ;No.  Read a sector.
  293.     LXI    D,BUFFER
  294.     CALL    RDISK
  295.     MOV    A,C
  296.     ANI    FERR
  297.     JZ    FRMH3
  298.     LXI    H,CIORED
  299.     CALL    ERROR
  300.     STC
  301.     RET
  302. FRMH3:
  303.     LDA    BUFFER        ;Set E5FLAG
  304.     ORA    A
  305.     JNZ    FRMH4
  306.     INR    A
  307. FRMH4:
  308.     STA    E5FLAG
  309.     CPI    0E5h        ;Is data E5?
  310.     JZ    FRMH12
  311.     CALL    INITBF        ;No.  Set buffer to E5s
  312.     LHLD    BDOSV+1        ;Compute # sectors in buffer
  313.     LXI    D,-BUFFER
  314.     DAD    D
  315.     LDA    DTYPE
  316.     ANI    TYPESEC
  317.     RRC
  318.     MOV    B,A
  319.     MVI    D,3
  320.     CALL    DBLSHR
  321. FRMH5:
  322.     DCR    B
  323.     JM    FRMH6
  324.     MVI    D,1
  325.     CALL    DBLSHR
  326.     JMP    FRMH5
  327. FRMH6:
  328.     MOV    A,L
  329.     STA    CIOWRT+4    ;# SECTORS
  330.     XCHG
  331.     LXI    H,0
  332.     SHLD    CIOWRT+2
  333. FRMH7:
  334.     PUSH    D
  335.     LXI    H,CIOWRT
  336.     LXI    D,BUFFER
  337.     CALL    WDISK        ;Output  buffer
  338.     POP    D
  339.     MOV    A,C
  340.     ANI    FERR
  341.     JZ    FRMH8        ;If no errors
  342.     LXI    H,CIOWRT
  343.     CALL    ERROR
  344.     STC
  345.     RET
  346.  
  347. FRMH8:
  348.     PUSH    D        ;Increment logical address
  349.     LXI    H,CIOWRT+2
  350.     MOV    D,M        ;It's in reverse order
  351.     INX    H
  352.     MOV    E,M
  353.     POP    H
  354.     XCHG
  355.     DAD    D
  356.     PUSH    D
  357.     XCHG
  358.     LXI    H,CIOWRT+1
  359.     JNC    FRMH9
  360.     INR    M
  361. FRMH9:
  362.     INX    H
  363.     MOV    M,D
  364.     INX    H
  365.     MOV    M,E
  366.     LXI    D,ESECTOR    ;Done?
  367.     LXI    H,CIOWRT+1
  368.     MOV    A,M
  369.     ANI    1Fh
  370.     XCHG
  371. FRMH10:
  372.     CMP    M
  373.     JZ    FRMH11
  374.     POP    D
  375.     JMP    FRMH8
  376. FRMH11:
  377.     INX    D
  378.     INX    H
  379.     DCR    B
  380.     LDAX    D
  381.     JNZ    FRMH10
  382.  
  383. FRMH12:
  384.     LXI    D,FCMSG
  385.     CALL    INFCRT
  386.     CPI    CR
  387.     RET
  388.  
  389. UNDMSG:    DB    CR,LF,'Unit is not present.',CR,LF,EOS
  390.  
  391. BFDMSG:    DB    CR,LF,'Begin formatting hard disk.'
  392.     DB    CR,LF,EOS
  393.  
  394. FNAMSG:    DB    CR,LF,'Function is not presently available.'
  395.     DB    CR,LF,EOS
  396.  
  397.  
  398.  
  399.  
  400. ;    FORMF - Format a floppy disk unit.
  401.  
  402. FORMF:
  403.     CALL    SCMND        ;Set command buffers
  404.     MVI    A,1        ;Set interleave code
  405.     STA    CIOFDC+4
  406.     LXI    H,CIOSTC
  407.     CALL    EXEC        ;Output command buffer
  408.     CZ    WAITF        ;Wait completion
  409.     MOV    A,C
  410.     ANI    FERR
  411.     JZ    FRMF1        ;If unit is ready
  412.     LXI    D,NRYMSG    ;Output not ready message
  413.     CALL    INFCRT
  414.     JMP    FORMF        ;retry on any character
  415.  
  416. FRMF1:
  417.     LDA    FPSLV        ;Get selection value
  418.     MOV    E,A
  419.     MVI    D,0
  420.     LXI    H,FPYTFC
  421.     LDA    DTYPE
  422.     MOV    B,A
  423.     ANI    TYPEDRV
  424.     JZ    FRMF2
  425.     LXI    H,M48TFC
  426.     MOV    A,B
  427.     ANI    TYPEN48
  428.     JNZ    FRMF2
  429.     LXI    H,M96TFC
  430. FRMF2:
  431.     DAD    D
  432.     MOV    A,M
  433.     STA    CIOFSC+5
  434.     LXI    H,CIOFSC
  435.     CALL    EXEC        ;Output Command
  436.     CZ    WAITF        ;Wait function complete
  437.  
  438.     LXI    D,FDKMSG
  439.     MVI    C,PRTSTR
  440.     CALL    BDOSV        ;Output format disk
  441.     LXI    H,CIOFDC
  442.     CALL    EXEC        ;Output Command
  443.     CZ    WAITF        ;Wait for completion
  444.     MOV    A,C
  445.     ANI    FERR
  446.     JZ    FRMF3        ;If no errors
  447.     LXI    H,CIOFDC
  448.     CALL    ERROR        ;PRINT ERROR MESSAGE
  449.     JMP    FORMF
  450.  
  451. FRMF3:
  452.     LHLD    ESECTOR        ;Fill 1/4th of disk with E5s
  453.     MVI    D,2
  454.     CALL    DBLSHR
  455.     SHLD    ESECTOR
  456.     CALL    FRME5
  457.     JC    FORMF
  458.     RZ            ;If request to return to CP/M
  459.     CPI    'F'
  460.     JZ    FORMF        ;If request for another
  461.     RET
  462. ;    Track format code tables (indexed by density*2+# sides)
  463. ;
  464. FPYTFC:    DB    0,1,6,7
  465. M48TFC:    DB    0,1,4,5
  466. M96TFC:    DB    2,3,6,7
  467. ;
  468.  
  469. FCMSG:
  470.     DB    CR,LF,'Function Complete.'
  471.     DB    CR,LF,LF
  472.     DB    'Type RETURN to return to CP/M, '
  473.     DB    'or F to Format another: '
  474.     DB    EOS
  475.  
  476. NRYMSG:    DB    CR,LF
  477.     DB    'Disk unit is not ready. ',CR,LF
  478.     DB    'Please ready unit and hit RETURN. '
  479.     DB    EOS
  480.  
  481. FDKMSG:    DB    CR,LF,'Formatting the entire disk.'
  482.     DB    CR,LF,EOS
  483.  
  484.  
  485.  
  486.  
  487. ;    INFCRT - Output message and input from console.
  488. ;
  489. ;    ENTRY    DE = message address.
  490. ;
  491. ;    EXIT    A = First character entered (upper case).
  492.  
  493. INFCRT:
  494.     MVI    C,PRTSTR
  495.     CALL    BDOSV        ;Output message
  496.     LXI    D,INBUFX
  497.     MVI    C,RDCB
  498.     CALL    BDOSV
  499.     LDA    INBUFX+1
  500.     ANA    A
  501.     MVI    A,CR
  502.     RZ
  503.     LDA    INBUF
  504.     CPI    'A'+20h
  505.     RC            ;If upper case
  506.     CPI    'Z'+20h+1
  507.     RNC            ;If upper case
  508.     SUI    20h        ;Fold to uppercase
  509.     RET
  510.  
  511. INBUFX    DB    10,0
  512. INBUF    DB    0,0,0,0,0,0,0,0,0,0
  513.  
  514.  
  515.  
  516.  
  517. ;    DDTYPE - determine disk type (hard or floppy).
  518.  
  519. DDTYPE:
  520.     XRA    A
  521.     STA    CIOFSC+5
  522.     LDA    DRVNO
  523.     STA    CIOFSC+1
  524.     STA    CIOADT+1
  525.     LXI    H,DT
  526.     LXI    D,6
  527.     MVI    B,NLUN
  528. DDTYP1:
  529.     CMP    M
  530.     JZ    DDTYP2
  531.     DAD    D
  532.     DCR    B
  533.     JNZ    DDTYP1
  534.     ORI    0FFH        ;Configuration error.
  535.     RET
  536. DDTYP2:
  537.     INX    H
  538.     MOV    A,M
  539.     STA    DTYPE
  540.     INX    H
  541.     MOV    A,M
  542.     STA    CIOADT+4    ;ASSIGN DRIVE TYPE
  543.     INX    H        ;Compute end sector
  544.     MOV    C,M
  545.     INX    H
  546.     MOV    E,M
  547.     INX    H
  548.     MOV    D,M
  549.     CALL    MUL
  550.     XCHG
  551.     LXI    H,ESECTOR
  552.     MOV    M,B
  553.     INX    H
  554.     MOV    M,D
  555.     INX    H
  556.     MOV    M,E
  557.     LDA    CIOADT+4    ;Does controller have Class 6,
  558.     CPI    0FFh        ;  op code 1?
  559.     RZ
  560.     LXI    H,CIOADT
  561.     CALL    EXEC        ;Output Command
  562.     CZ    WAITF        ;Wait function complete
  563.     MOV    A,C
  564.     ANI    FERR        ;Mask for errors
  565.     RET
  566. ;
  567. ;    Drive Type table (indexed by LUN)
  568. ;
  569. DT:
  570.     IF    LUN0
  571.     DB    0 SHL 5
  572.     DB    LUN0TYPE+TYPEN48*N48M0+TYPEN96*N96M0
  573.     DB    LUN0DAT,LUN0NLD
  574.     DW    LUN0SEC
  575.     ENDIF
  576.     IF    LUN1
  577.     DB    1 SHL 5
  578.     DB    LUN1TYPE+TYPEN48*N48M1+TYPEN96*N96M1
  579.     DB    LUN1DAT,LUN1NLD
  580.     DW    LUN1SEC
  581.     ENDIF
  582.     IF    LUN2
  583.     DB    2 SHL 5
  584.     DB    LUN2TYPE+TYPEN48*N48M2+TYPEN96*N96M2 
  585.     DB    LUN2DAT,LUN2NLD
  586.     DW    LUN2SEC
  587.     ENDIF
  588.     IF    LUN3
  589.     DB    3 SHL 5
  590.     DB    LUN3TYPE+TYPEN48*N48M3+TYPEN96*N96M3
  591.     DB    LUN3DAT,LUN3NLD
  592.     DW    LUN3SEC
  593.     ENDIF
  594. ;
  595.  
  596.  
  597.  
  598.  
  599. ;    SCMND - Set drive into command buffers.
  600.  
  601. SCMND:
  602.     LDA    DRVNO
  603.     LXI    H,CIOFSC+1
  604.     LXI    D,6
  605.     MVI    B,CIONUM
  606. SCMD1:    MOV    M,A
  607.     DAD    D
  608.     DCR    B
  609.     JNZ    SCMD1        ;If not all buffer set
  610.     RET
  611.  
  612.  
  613.  
  614.  
  615.  
  616. ;    MOVDTA - Move data utility program.
  617. ;
  618. ;    ENTRY    H = Source field.
  619. ;        DE = Destination field.
  620. ;        BC = number of bytes.
  621.  
  622. MOVDTA:
  623.     MOV    A,M
  624.     STAX    D
  625.     INX    H
  626.     INX    D
  627.     DCX    B
  628.     MOV    A,B
  629.     ANA    C
  630.     CPI    0FFh        ;-1
  631.     JNZ    MOVDTA
  632.     RET
  633.  
  634.  
  635.  
  636. ;MULTIPLY SINGLE X DOUBLE
  637. ;
  638. ;    ENTRY:    DE = MULTIPLICAND
  639. ;         C = MULTIPLIER
  640. ;    EXIT:    HL = PRODUCT (LEAST SIGNIFICANT)
  641. ;         B = PRODUCT (MOST SIGNIFICANT)
  642. ;
  643. MUL:    LXI    H,0
  644.     MOV    A,C
  645.     ORA    A
  646.     RZ
  647.     MVI    B,0
  648. MUL1:    DAD    D
  649.     JNC    MUL2
  650.     INR    B
  651. MUL2:
  652.     DCR    A
  653.     JNZ    MUL1
  654.     RET
  655. ;
  656. ;
  657. ;Shift HL right by (D)
  658. ;
  659. DBLSHR:
  660.     XRA    A
  661.     MOV    A,H
  662.     RAR
  663.     MOV    H,A
  664.     MOV    A,L
  665.     RAR
  666.     MOV    L,A
  667.     DCR    D
  668.     JNZ    DBLSHR
  669.     RET
  670. ;
  671. ;
  672. ;
  673. CIOBGN:
  674. CIOFSC:    DB    FSCMD,0,0,0,0,0
  675. CIOWRT:    DB    WTCMD,0,0,0,1,0C0h
  676. CIORED:    DB    RDCMD,0,0,0,1,0
  677. CIOESC:    DB    ESCMD,0,0,0,0,0
  678. CIOSTC:    DB    STCMD,0,0,0,0,0
  679. CIOFDC:    DB    FDCMD,0,0,0,0,0
  680. CIOADT:    DB    ADCMD,0,0,0,0,0
  681. CIONUM:    EQU    ($-CIOBGN)/6    ;Number of entries above
  682.  
  683.  
  684.  
  685.  
  686. SYSTK:    DW    0        ;Hold stack
  687.  
  688.  
  689.  
  690.     DS    50
  691. STACK:    DS    1
  692.  
  693.  
  694.  
  695.  
  696.  
  697. LETTER:    DB    0,EOS
  698.  
  699. STRACK:    DW    0        ;Starting track number
  700. CTRACK:    DW    0        ;Current track number
  701. ETRACK:    DW    0        ;Ending track number
  702. ESECTOR: DS    3        ;Ending sector
  703.  
  704.  
  705.  
  706. DRVNO:    DB    0
  707. DTYPE:    DB    0
  708. HDFTP:    DB    0        ;Hard disk format type
  709. HDILC:    DB    0        ;Hard disk interleave code
  710. FPDEN:    DB    0        ;floppy Density selection
  711. FPSLV:    DB    0        ;floppy format selection value
  712.  
  713. E5FLAG:    DB    0        ;Format data value
  714.  
  715.  
  716.  
  717. ;    Disk I/O Routines
  718. ;
  719. ;
  720.     IF    I696
  721. ;    E X E C
  722.  
  723. EXEC:    MVI    B,BUSY        ;Wait for not busy.
  724.     MVI    C,BUSY and (not BUSY)
  725.     CALL    WAITM
  726.     RNZ
  727.     
  728.  
  729.     MVI    A,SLCT        ;Alert controller
  730.     OUT    DIO+1
  731. EXEC1:
  732.     MOV    C,B        ;Wait for controller busy
  733.     CALL    WAITM
  734.     RNZ
  735.  
  736.     MVI    A,DODTA        ;Enable data in
  737.     OUT    DIO+1
  738.  
  739. EXEC2:    IN    DIO+2        ;Get status
  740.     XRI    0FFh
  741.     JM    EXEC2        ;If not requesting next byte
  742.     ANI    CMND+DIROUT
  743.     JNZ    EXEC3        ;If CMND or DIROUT false
  744.     MOV    A,M
  745.     INX    H
  746.     OUT    DIO        ;Send byte from command buffer
  747.     JMP    EXEC2
  748.  
  749. EXEC3:    CMP    A        ;Z:=1
  750.     RET
  751. ;
  752. ;
  753. ;
  754. ;
  755. ;    WDISK - Output from memory buffer.
  756. ;    ENTRY:    HL = COMMAND BUFFER ADDRESS
  757. ;        DE = DATA BUFFER ADDRESS
  758. ;
  759.  
  760. WDISK:    CALL    EXEC        ;Output command
  761.     RNZ            ;Return if timeout
  762. WDISK1:    IN    DIO+2        ;Read status
  763.     ORA    A
  764.     JP    WDISK1        ;If request is present
  765.     ANI    CMND
  766.     JNZ    GCMPS        ;If done with transfer
  767.     LDAX    D        ;Get the data byte
  768.     OUT    DIO
  769.     INX    D        ;Advance buffer address
  770.     JMP    WDISK1
  771. ;
  772. ;
  773. ;
  774. ;
  775. ;    RDISK - Input to memory buffer.
  776. ;
  777. ;    Entry:    HL = command buffer address
  778. ;        DE = data buffer address
  779.  
  780. RDISK:    CALL    EXEC
  781.     RNZ            ;Return if timeout
  782. RDISK1:    IN    DIO+2        ;Read status
  783.     ORA    A
  784.     JP    RDISK1        ;If request is present
  785.     ANI    CMND
  786.     JNZ    GCMPS
  787.     IN    DIO
  788.     STAX    D
  789.     INX    D
  790.     JMP    RDISK1
  791. ;
  792. ;
  793. ;
  794. ;
  795. ;    WAITF - Wait for function to complete.
  796.  
  797. WAITF:    MVI    B,REQ+CMND    ;Wait for both REQ and CMND
  798.     MOV    C,B
  799.     CALL    WAITM
  800.     RNZ
  801. ;
  802. ;    Get completion status.
  803.  
  804. GCMPS:    IN    DIO        ;Get completion status
  805.     MOV    C,A
  806.  
  807. GCMP1:    IN    DIO+2
  808.     ORA    A
  809.     JP    GCMP1        ;If REQ not set
  810.  
  811.     MOV    B,A
  812.     IN    DIO        ;Get message byte
  813.     RET
  814.     ENDIF
  815. ;
  816.  
  817. ;
  818. ;
  819. ;
  820.     IF    I796
  821. ;    EXEC - Output the command
  822. ;
  823. ;    Enter:    HL is the command buffer address
  824. ;        DE - data transfer address.
  825.  
  826. EXEC:
  827.     MOV    A,E        ;Output DMA address
  828.     OUT    DIO+2
  829.     MOV    A,D
  830.     OUT    DIO+3
  831.     MOV    A,L
  832.     OUT    DIO+4
  833.     MOV    A,H
  834.     OUT    DIO+5
  835.     MVI    A,0
  836.     OUT    DIO+6
  837.     OUT    DIO+7
  838.     OUT    DIO
  839.     CMP    A        ;Z:=1
  840.     RET
  841.  
  842.  
  843. ;    Disk read/write
  844. ;
  845. ;    Entry:    same as EXEC
  846. ;
  847. RDISK:
  848. WDISK:    CALL    EXEC
  849.     RNZ            ;Return if timeout
  850.  
  851. ;    WAITF - Wait until transfer done
  852. ;
  853. ;    Enter:    none
  854. ;    Exit:    when transfer completed
  855.  
  856. WAITF:    MVI    B,CMDDON    ;Wait for CMDDON
  857.     MOV    C,B
  858.     CALL    WAITM
  859.     RNZ            ;Return if timeout
  860. ;
  861.  
  862. ;    GCMPS - Get completion status
  863. ;
  864. ;    Enter:    none
  865. ;    Exit:    Status in C
  866. GCMPS:    IN    DIO+1
  867.     MOV    C,A
  868.     RET
  869.     ENDIF
  870.  
  871. ;    WAITM - Wait for controller with timeout
  872. ;
  873. ;    Entry:    B=Status mask
  874. ;        C=Status value
  875. ;    Exit:    Z=1 if OK, else timeout with A=C=TERR
  876. ;
  877. WAITM:
  878.     PUSH    D        ;Save D
  879.     PUSH    H
  880.     LXI    H,138        ;Two minute timeout
  881.     LXI    D,0        ;Max wait @4MHZ is 868 ms
  882. WAITML:
  883.     IF    I696
  884.     IN    DIO+2
  885.     ENDIF
  886.     IF    I796
  887.     IN    DIO
  888.     ENDIF
  889.     ANA    B        ;Mask wait bits
  890.     CMP    C        ;Check value
  891.     JZ    WAITM1
  892.     DCX    D        ;Not ready.  Decrement time
  893.     MOV    A,D
  894.     ORA    E
  895.     JNZ    WAITML
  896.     DCX    H
  897.     MOV    A,H
  898.     ORA    L
  899.     JNZ    WAITML
  900.     MVI    B,0        ;Timeout
  901.     MVI    A,TERR
  902.     ORA    A
  903. WAITM1:
  904.     POP    H
  905.     POP    D        ;Restore D
  906.     MOV    C,A        ;Return status in C
  907.     RET
  908. ;    DTC Error Print Routine
  909. ;
  910. ;Called at completion of disk command when error status is returned.
  911. ;
  912. ;    Entry:    HL = Address of Command Descriptor Block
  913. ;        C = Status byte
  914. ;
  915. ERROR:
  916.     PUSH    B        ;Save status
  917.     PUSH    H        ;SAVE ADDRESS OF CDB
  918.     MOV    A,M        ;GET CLASS CODE
  919.     ANI    0E0H
  920.     RAL            ;MAKE CDB LENGTH INDEX
  921.     RAL
  922.     RAL
  923.     MOV    E,A        ;GET CDB LENGTH
  924.     MVI    D,0
  925.     LXI    H,CDBLEN
  926.     DAD    D
  927.     MOV    C,M
  928.     POP    H        ;RESTORE CDB ADDRESS
  929.     PUSH    H
  930.     LXI    D,ERRCDB
  931.     CALL    PUTHEX        ;BUILD CDB FOR PRINT
  932.     LXI    D,EHEAD        ;Print header
  933.     MVI    C,PRTSTR
  934.     CALL    BDOSV
  935.     POP    H        ;Get status
  936.     POP    B
  937.     PUSH    H
  938.     MOV    A,C        ;Timeout?
  939.     ANI    TERR
  940.     LXI    D,TOMSG
  941.     JNZ    ERROR1
  942.     LXI    H,CIOESC    ;No. READ ERROR SENSE
  943.     LXI    D,SENSE
  944.     CALL    RDISK
  945.     LXI    D,ESENSE
  946.     MVI    C,PRTSTR
  947.     CALL    BDOSV
  948.     LXI    D,ESENS1
  949.     LXI    H,SENSE
  950.     MOV    A,M
  951.     MVI    C,PRTSTR
  952.     ORA    A
  953.     CM    BDOSV
  954.     LXI    D,ETYPE
  955.     LXI    H,SENSE        ;BUILD ERROR SENSE MESSAGE
  956.     MOV    A,M
  957.     RAR
  958.     RAR
  959.     RAR
  960.     RAR
  961.     ANI    3
  962.     CALL    HEXASC
  963.     LXI    D,ECODE
  964.     MOV    A,M
  965.     CALL    HEXASC
  966.     LXI    D,ELUN
  967.     INX    H
  968.     MOV    A,M
  969.     RLC
  970.     RLC
  971.     RLC
  972.     ANI    7
  973.     CALL    HEXASC
  974.     MOV    A,M
  975.     ANI    01FH
  976.     MOV    M,A
  977.     LXI    D,ELAD
  978.     MVI    C,3
  979.     CALL    PUTHEX
  980.     LXI    D,ESENS2    ;PRINT MESSAGE
  981. ERROR1:
  982.     MVI    C,PRTSTR
  983.     CALL    BDOSV
  984.     POP    H        ;RESTORE CDB ADDRESS
  985.     RET
  986. ;
  987. ;
  988.  
  989. ;    PUT HEXADECIMAL STRING
  990. ;
  991. ;    ENTRY:    HL = ADDRESS OF HEX NUMBER STRING
  992. ;        DE = ADDRESS OF HEX ASCII STRING
  993. ;         C = NUMBER OF BYTES TO CONVERT
  994. ;
  995. PUTHEX:    CALL    HEXBYT
  996.     MVI    A,' '
  997.     STAX    D
  998.     INX    D
  999.     DCR    C
  1000.     JNZ    PUTHEX
  1001.     MVI    A,EOS
  1002.     STAX    D
  1003.     RET
  1004. ;
  1005. ;
  1006. HEXBYT:    MOV    A,M
  1007.     RAR
  1008.     RAR
  1009.     RAR
  1010.     RAR
  1011.     CALL    HEXASC
  1012.     MOV    A,M
  1013.     INX    H
  1014. HEXASC:    ANI    0FH
  1015.     ADI    090H
  1016.     DAA
  1017.     ACI    040H
  1018.     DAA
  1019.     STAX    D
  1020.     INX    D
  1021.     RET
  1022. ;
  1023. ;
  1024. ;    CDB length table (indexed by class)
  1025. CDBLEN:    DB    6,10,0,0,0,0,6,6
  1026. ;
  1027. EHEAD:    DB    CR,LF,LF,'Disk error:'
  1028.     DB    CR,LF,'Command Descriptor:',TAB,TAB
  1029. ERRCDB:    DS    31
  1030. ;
  1031. TOMSG:    DB    CR,LF,TAB,TAB,TAB,TAB,'Timeout',EOS
  1032. ESENSE:    DB    CR,LF,'Error Sense:',EOS
  1033. ESENS1:    DB    CR,LF,TAB,TAB,TAB,TAB,'Block address valid.',EOS
  1034. ESENS2:    DB    CR,LF,TAB,'Error type:',TAB,TAB
  1035. ETYPE:    DS    1
  1036.     DB    CR,LF,TAB,'Error code:',TAB,TAB
  1037. ECODE:    DS    1
  1038.     DB    CR,LF,TAB,'Logical unit:',TAB,TAB
  1039. ELUN:    DS    1
  1040.     DB    CR,LF,TAB,'Logical address:',TAB
  1041. ELAD:    DS    4
  1042. SENSE:    DS    4
  1043. ;
  1044. BUFFER:    EQU    $
  1045. ;
  1046.     END
  1047.