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

  1. ;Install - Data Technology Corporation CP/M 2.2 Install.
  2. ;
  3. ;    +-----------------------+
  4. ;    |            |
  5. ;    |     I N S T A L L     |
  6. ;    |            |
  7. ;    +-----------------------+
  8. ;
  9. ;
  10. ;    Version number:    2.2B
  11. ;    Version date:    December 3, 1980
  12. ;
  13. ;    Update date:    March 31, 1981
  14. ;        Source modified for assembly with ASM.
  15. ;
  16. ;    Update date:    April 27, 1981
  17. ;        Source modified for controller timeout.
  18.  
  19. ;    Update date:    June 16, 1981
  20. ;        Source modified for new CONFIG parameters.
  21. ;
  22. ;    The following code is supplied to customers who
  23. ;    purchase a hard/floppy disk system from DTC.
  24. ;    The following code reads the user created CPMxx.com
  25. ;    file and writes out onto the Hard disk boot sectors.
  26. ;
  27. ;    The format of the Hard Disk Boot sectors are as follows:
  28. ;
  29. ;    Logical        Routine
  30. ;    Sector        Name
  31. ;
  32. ;      0        Boot program
  33. ;
  34. ;    1 thru 8    CCP
  35. ;
  36. ;    9 thru 22    BDOS
  37. ;
  38. ;    23 thru 32    DTC CBIOS
  39. ;
  40. ;    The format of the CPMxx.com file is as follows:
  41. ;
  42. ;    CP/M        Routine
  43. ;    Sector        Name
  44. ;
  45. ;    0 thru 14    Do not care.
  46. ;
  47. ;      15,16        Boot program
  48. ;
  49. ;    17 thru 32    CCP
  50. ;
  51. ;    33 thru 60    BDOS
  52. ;
  53. ;    61 thru 88    DTC CBIOS
  54.     
  55.  
  56.  
  57.  
  58.  
  59. VERS:    EQU    22
  60.  
  61. CR:    EQU    0Dh        ;ASCII carrriage return
  62. LF:    EQU    0Ah        ;ASCII line feed
  63. TAB:    EQU    9        ;ASCII HORIZONTAL TAB
  64. EOS:    EQU    '$'        ;BDOS End of string
  65. ERRCD:    EQU    0FFh        ;BDOS error code
  66.  
  67.  
  68.  
  69. ;    BDOS function equates.
  70.  
  71. PRTSTR:    EQU    09    ;Print String    DE = buffer address.
  72. RDCB:    EQU    10    ;Read console buffer   DE = buffer address.
  73. OPEN:    EQU    15    ;Open file   DE = FCB address.
  74. READS:    EQU    20    ;Read sequential file    DE = FCB.
  75. SETDMA:    EQU    26    ;Set DMA address    DE = DMA address.
  76.  
  77. ;    Page zero locations.
  78.  
  79. BDOSV:    EQU    5    ;BDOS jump address.
  80. DFCB:    EQU    005Ch    ;Default FCB address.
  81. DBUF:    EQU    0080h    ;Default DMA buffer.
  82.  
  83.  
  84.  
  85.     
  86.  
  87.  
  88.  
  89.  
  90.     ORG    100h
  91.  
  92. INSTAL:
  93.     PUSH    PSW
  94.     PUSH    B
  95.     PUSH    D
  96.     PUSH    H
  97.     LXI    H,0
  98.     DAD    SP
  99.     SHLD    SYSTK        ;save system stack
  100.  
  101.  
  102.     LXI    SP,STACK
  103.     CALL    GFILEN        ;Get file name
  104.     CALL    SKIPF        ;Skip do not care sectors
  105.     CALL    RBOOT        ;Read Boot
  106.     CALL    RCPM        ;Read CP/M
  107.     CALL    RBIOS        ;Read BIOS
  108.     CALL    WOUT        ;Write out onto hard disk
  109.  
  110.     LXI    D,ENDMSG
  111.     MVI    C,PRTSTR
  112.     CALL    BDOSV        ;Output successful message
  113.  
  114. ;    Return to system gracefully.
  115.  
  116. SYSRET:    LHLD    SYSTK
  117.     SPHL
  118.     POP    H
  119.     POP    D
  120.     POP    B
  121.     POP    PSW
  122.     RET            ;return to system
  123.  
  124. ENDMSG:    DB    CR,LF,'Disk Boot Successfully Updated.'
  125.     DB    CR,LF,EOS
  126.  
  127.  
  128.  
  129.  
  130. ;    GFILEN - Get file name and opent the file.
  131. ;
  132. ;    ENTRY    loaction 5C = filename.
  133.  
  134. GFILEN:
  135.     LXI    H,5Ch
  136.     LXI    D,FCB
  137.     LXI    B,12
  138.     CALL    MOVDTA        ;Move file name to FCB
  139.  
  140.     LXI    D,FCB
  141.     MVI    C,OPEN
  142.     CALL    BDOSV        ;Open the file
  143.     CPI    ERRCD
  144.     RNZ            ;If no error
  145.  
  146.     LXI    D,OPNERR
  147.     MVI    C,PRTSTR
  148.     CALL    BDOSV
  149.     JMP    SYSRET
  150.  
  151. OPNERR:    DB    CR,LF,'Error on file open.',CR,LF,EOS
  152.  
  153.  
  154.  
  155. ;    SKIPF - Skip meaningless sectors on file.
  156.  
  157. SKIPF:
  158.     LXI    D,DBUF
  159.     MVI    C,SETDMA
  160.     CALL    BDOSV        ;Set DMA address to default buffer
  161.  
  162.     MVI    A,15        ;Skip 15 sectors
  163. SKPF1:    PUSH    PSW
  164.     LXI    D,FCB
  165.     MVI    C,READS
  166.     CALL    BDOSV        ;Read a sector
  167.     CPI    ERRCD
  168.     JZ    SKPF2        ;If error on read
  169.     POP    PSW
  170.     DCR    A
  171.     JNZ    SKPF1        ;If 16 sectors not read
  172.     RET
  173.  
  174. SKPF2:    LXI    D,SKERR
  175.     MVI    C,PRTSTR
  176.     CALL    BDOSV        ;Output error message
  177.     JMP    SYSRET
  178.  
  179. SKERR:    DB    CR,LF,'File read error sectors 0 thru 15.'
  180.     DB    CR,LF,EOS
  181.  
  182.  
  183. ;    RBOOT - Read the boot sector.
  184.  
  185. RBOOT:
  186.     LXI    H,BUFFER
  187.     LXI    D,BUFFER+1
  188.     LXI    B,255
  189.     XRA    A
  190.     MOV    M,A
  191.     CALL    MOVDTA        ;Clear 256 bytes of buffer
  192.  
  193.     LXI    D,BUFFER
  194.     MVI    A,2
  195. RBOOT1:
  196.     PUSH    PSW
  197.     PUSH    D
  198.     MVI    C,SETDMA
  199.     CALL    BDOSV        ;Set DMA address
  200.  
  201.     LXI    D,FCB
  202.     MVI    C,READS
  203.     CALL    BDOSV        ;Read the boot sector
  204.     CPI    ERRCD
  205.     JZ    RBOOT2
  206.     POP    D
  207.     LXI    H,128
  208.     DAD    D
  209.     XCHG
  210.     POP    PSW
  211.     DCR    A
  212.     JNZ    RBOOT1
  213.     RET
  214.  
  215. RBOOT2:
  216.     LXI    D,BTERR
  217.     MVI    C,PRTSTR
  218.     CALL    BDOSV        ;Output error message
  219.     JMP    SYSRET
  220.  
  221. BTERR:    DB    CR,LF,'File read error on boot sector.'
  222.     DB    CR,LF,EOS
  223.  
  224.  
  225.  
  226.  
  227. ;    RCPM - Read CPM sectors.
  228.  
  229. RCPM:
  230.     MVI    A,22*2
  231.     LXI    D,BUFFER+256
  232. RCPM1:    PUSH    PSW
  233.     PUSH    D        ;Save buffer address
  234.     MVI    C,SETDMA
  235.     CALL    BDOSV        ;Set DMA address to default buffer
  236.  
  237.     LXI    D,FCB
  238.     MVI    C,READS
  239.     CALL    BDOSV        ;Read a sector
  240.     CPI    ERRCD
  241.     JZ    RCPM2        ;If error on read
  242.     POP    D
  243.     LXI    H,128
  244.     DAD    D
  245.     XCHG
  246.     POP    PSW
  247.     DCR    A
  248.     JNZ    RCPM1        ;If 22*2 sectors not read
  249.     RET
  250.  
  251. RCPM2:    LXI    D,RCERR
  252.     MVI    C,PRTSTR
  253.     CALL    BDOSV        ;Output error message
  254.     JMP    SYSRET
  255.  
  256. RCERR:    DB    CR,LF,'File read error in CPM sectors (17 thru 60).'
  257.     DB    CR,LF,EOS
  258.     RET
  259.  
  260.  
  261.  
  262.  
  263. ;    RBIOS - Read BIOS sectors.
  264.  
  265. RBIOS:
  266.     LXI    H,BUFFER+22*256+256
  267.     LXI    D,BUFFER+22*256+256+1
  268.     LXI    B,255
  269.     XRA    A
  270.     MOV    M,A
  271.     CALL    MOVDTA        ;Clear the rest of the buffer
  272.  
  273.     LXI    D,BUFFER+22*256+256
  274. RBIOS1:    PUSH    D        ;Save buffer address
  275.     MVI    C,SETDMA
  276.     CALL    BDOSV        ;Set DMA address to default buffer
  277.  
  278.     LXI    D,FCB
  279.     MVI    C,READS
  280.     CALL    BDOSV        ;Read a sector
  281.     POP    D
  282.     LXI    H,128
  283.     DAD    D
  284.     XCHG
  285.     ORA    A
  286.     JZ    RBIOS1        ;If no errors
  287.  
  288.     RET
  289.  
  290.  
  291.  
  292.  
  293. ;    WOUT - Write out boot sectors onto hard disk.
  294.  
  295. WOUT:
  296.     LXI    D,DMESSG    ;Output disk selection message
  297.     CALL    INFCRT
  298.     SUI    'A'
  299.     JM    WOUT        ;If invalid entry
  300.     MOV    B,A        ;Save CP/M drive #
  301.     XRA    A        ;Determine LUN
  302.     LXI    H,CONTBL
  303.     LXI    D,CONELN
  304.     MVI    C,CONLEN
  305. WOUT1:
  306.     CMP    B
  307.     JP    WOUT2
  308.     ADD    M
  309.     DAD    D
  310.     DCR    C
  311.     JP    WOUT1
  312.     LXI    D,INVMSG    ;Invalid drive select
  313.     MVI    C,PRTSTR
  314.     CALL    BDOSV
  315.     JMP    WOUT
  316. WOUT2:
  317.     JZ    WOUT3        ;This table?
  318.     LXI    D,-CONELN    ;No. Went too far.
  319.     DAD    D        ;HL = table entry address
  320.     SUB    M
  321. WOUT3:
  322.     MOV    C,A        ;Compute relative logical disk
  323.     INX    H        ;Get LUNiTYPE
  324.     MOV    A,M
  325.     STA    TYPE
  326.     MOV    D,A
  327.     ANI    TYPEDRV        ;Floppy?
  328.     JZ    WOUT4
  329.     MOV    A,D
  330.     ANI    TYPEN48+TYPEN96
  331.     MVI    A,0
  332.     JNZ    WOUT4
  333.     MOV    A,B
  334.     SUB    C
  335. WOUT4:
  336.     MOV    C,A
  337.     INX    H        ;Set drive type
  338.     MOV    A,M
  339.     STA    CIOADT+4
  340.     INX    H        ;Set track format code
  341.     MOV    A,M
  342.     STA    CIOFS+5
  343.     INX    H        ;Set LUN
  344.     MOV    A,M
  345.     STA    CIOESC+1
  346.     STA    CIOPB+1
  347.     STA    CIOADT+1
  348.     STA    CIOFS+1
  349.     INX    H        ;Set # sectors
  350.     MOV    A,M
  351.     STA    LOGNSEC
  352.     INX    H        ;Compute logical address
  353.     MOV    E,M
  354.     INX    H
  355.     MOV    D,M
  356.     CALL    MUL
  357.     XCHG
  358.     LXI    H,CIOPB+1
  359.     MOV    A,M
  360.     ADD    B
  361.     MOV    M,A
  362.     INX    H
  363.     MOV    M,D
  364.     INX    H
  365.     MOV    M,E
  366.     LDA    CIOADT+4    ;Does controller have Class 6,
  367.     CPI    0FFh        ;  op code?
  368.     JZ    WOUTA
  369.     LXI    H,CIOADT
  370.     CALL    EXEC
  371.     CZ    WAITF
  372.     MOV    A,C
  373.     ANI    FERR
  374.     JZ    WOUT5
  375.     LXI    D,ADTMSG
  376.     MVI    C,PRTSTR
  377.     CALL    BDOSV
  378.     JMP    SYSRET
  379. WOUT5:
  380.     LDA    CIOFS+5        ;Floppy?
  381.     CPI    0FFh
  382.     JZ    WOUTA
  383.     LXI    H,CIOFS
  384.     CALL    EXEC        ; diskettes
  385.     CZ    WAITF
  386.     MOV    A,C
  387.     ANI    FERR
  388.     JZ    WOUTA
  389.     LXI    H,CIOFS
  390.     CALL    ERROR
  391.     JMP    SYSRET
  392. WOUTA:
  393.  
  394.     LXI    H,CIOPB        ;Set Command buffer address
  395.     LXI    D,BUFFER    ;Set data buffer address
  396.     CALL    WDISK        ;Write the data
  397.     MOV    A,C
  398.     ANI    FERR
  399.     RZ
  400.     LXI    H,CIOPB        ;Report errors
  401.     CALL    ERROR
  402.     JMP    WOUT
  403.  
  404. TYPE:    DS    1
  405. CIOESC:    DB    ESCMD,0,0,0,0,0
  406. CIOADT:    DB    ADCMD,0,0,0,0,0
  407. CIOFS:    DB    FSCMD,0,0,0,0,0
  408. CIOPB:    DB    WTCMD
  409.     DB    0
  410. LOGSEC:    DB    0,0            ;Write logical sector 0
  411. LOGNSEC:
  412.     DB    0        ;Write two or three tracks
  413.     DB    0            ;Perform no retries
  414.  
  415. DMESSG:    DB    CR,LF
  416.     DB    'Select Drive : ',EOS
  417. INVMSG:    DB    CR,LF,'Invalid drive selection.',EOS
  418. ADTMSG:    DB    CR,LF,'Drive Assignment error.',EOS
  419.  
  420. ;    Configuration table
  421. ;
  422. CONTBL:
  423.     IF    LUN0
  424.     DB    LUN0NLD
  425.     DB    LUN0TYPE+TYPEN48*N48M0+TYPEN96*N96M0
  426.     DB    LUN0DAT,B0
  427.     DB    0 SHL 5
  428.     DB    2*26*(NH0+NF0)+3*16*(N48M0+N96M0)
  429.     DW    LUN0SEC
  430.     ENDIF
  431.     IF    LUN1
  432.     DB    LUN1NLD
  433.     DB    LUN1TYPE+TYPEN48*N48M1+TYPEN96+N96M1
  434.     DB    LUN1DAT,B1
  435.     DB    1 SHL 5
  436.     DB    2*26*(NH1+NF1)+3*16*(N48M1+N96M1)
  437.     DW    LUN1SEC
  438.     ENDIF
  439.     IF    LUN2
  440.     DB    LUN2NLD
  441.     DB    LUN2TYPE+TYPEN48*N48M2+TYPEN96*N96M2
  442.     DB    LUN2DAT,B2
  443.     DB    2 SHL 5
  444.     DB    2*26*(NH2+NF2)+3*16*(N48M2+N96M2)
  445.     DW    LUN2SEC
  446.     ENDIF
  447.     IF    LUN3
  448.     DB    LUN3NLD
  449.     DB    LUN3TYPE+TYPEN48*N48M3+TYPEN96*N96M3
  450.     DB    LUN3DAT,B3
  451.     DB    3 SHL 5
  452.     DB    2*26*(NH3+NF3)+3*16*(N48M3+N96M3)
  453.     DW    LUN3SEC
  454.     ENDIF
  455. CONELN:    EQU    8        ;Entry length
  456. CONLEN:    EQU    ($-CONTBL)/CONELN
  457.  
  458.  
  459.  
  460. ;    INFCRT - Output message and input from console.
  461. ;
  462. ;    ENTRY    DE = message address.
  463. ;
  464. ;    EXIT    A = First character entered (upper case).
  465.  
  466. INFCRT:
  467.     MVI    C,PRTSTR
  468.     CALL    BDOSV        ;Output message
  469.     LXI    D,INBUFX
  470.     MVI    C,RDCB
  471.     CALL    BDOSV
  472.     LDA    INBUFX+1
  473.     ANA    A
  474.     MVI    A,CR
  475.     RZ
  476.     LDA    INBUF
  477.     CPI    'A'+20h
  478.     RC            ;If upper case
  479.     CPI    'Z'+20h+1
  480.     RNC            ;If upper case
  481.     SUI    20h        ;Fold to uppercase
  482.     RET
  483.  
  484. INBUFX    DB    10,0
  485. INBUF    DB    0,0,0,0,0,0,0,0,0,0
  486.  
  487.  
  488.  
  489.  
  490.  
  491.  
  492. ;    MOVDTA - Move data utility program.
  493. ;
  494. ;    ENTRY    HL = Source field.
  495. ;        DE = Destination field.
  496. ;        BC = number of bytes.
  497.  
  498. MOVDTA:
  499.     MOV    A,M
  500.     STAX    D
  501.     INX    H
  502.     INX    D
  503.     DCX    B
  504.     MOV    A,B
  505.     ANA    C
  506.     CPI    0FFh        ;-1
  507.     JNZ    MOVDTA
  508.     RET
  509.  
  510. ;    Multiply single X double
  511. ;
  512. ;    Entry:    DE = Multiplicand
  513. ;         C = Multiplier
  514. ;    Exit:    HL = Product (least significant)
  515. ;         B = Product (most significant)
  516. ;
  517. MUL:
  518.     LXI    H,0
  519.     MVI    B,0
  520.     MOV    A,C
  521.     ORA    A
  522.     RZ
  523. MUL1:
  524.     DAD    D
  525.     JNC    MUL2
  526.     INR    B
  527. MUL2:
  528.     DCR    A
  529.     JNZ    MUL1
  530.     RET
  531.  
  532.  
  533.  
  534.  
  535. SYSTK:    DW    0        ;Hold stack
  536.  
  537. FCB:    DS    12        ;file name
  538.     DB    0,0,0,0,0
  539.     DB    0,0,0,0,0
  540.     DB    0,0,0,0,0
  541.     DB    0,0,0,0,0
  542.     DB    0,0,0,0
  543.  
  544.  
  545.  
  546.     DS    50
  547. STACK:    DS    1
  548.  
  549.  
  550.  
  551.  
  552. ;    Disk I/O Routines
  553. ;
  554. ;
  555.     IF    I696
  556. ;    E X E C
  557.  
  558. EXEC:    MVI    B,BUSY        ;Wait for not busy.
  559.     MVI    C,BUSY and (not BUSY)
  560.     CALL    WAITM
  561.     RNZ
  562.     
  563.  
  564.     MVI    A,SLCT        ;Alert controller
  565.     OUT    DIO+1
  566. EXEC1:
  567.     MOV    C,B        ;Wait for controller busy
  568.     CALL    WAITM
  569.     RNZ
  570.  
  571.     MVI    A,DODTA        ;Enable data in
  572.     OUT    DIO+1
  573.  
  574. EXEC2:    IN    DIO+2        ;Get status
  575.     XRI    0FFh
  576.     JM    EXEC2        ;If not requesting next byte
  577.     ANI    CMND+DIROUT
  578.     JNZ    EXEC3        ;If CMND or DIROUT false
  579.     MOV    A,M
  580.     INX    H
  581.     OUT    DIO        ;Send byte from command buffer
  582.     JMP    EXEC2
  583.  
  584. EXEC3:    CMP    A        ;Z:=1
  585.     RET
  586. ;
  587. ;
  588. ;
  589. ;
  590. ;    WDISK - Output from memory buffer.
  591. ;    ENTRY:    HL = COMMAND BUFFER ADDRESS
  592. ;        DE = DATA BUFFER ADDRESS
  593. ;
  594.  
  595. WDISK:    CALL    EXEC        ;Output command
  596.     RNZ            ;Return if timeout
  597. WDISK1:    IN    DIO+2        ;Read status
  598.     ORA    A
  599.     JP    WDISK1        ;If request is present
  600.     ANI    CMND
  601.     JNZ    GCMPS        ;If done with transfer
  602.     LDAX    D        ;Get the data byte
  603.     OUT    DIO
  604.     INX    D        ;Advance buffer address
  605.     JMP    WDISK1
  606. ;
  607. ;
  608. ;
  609. ;
  610. ;    RDISK - Input to memory buffer.
  611. ;
  612. ;    Entry:    HL = command buffer address
  613. ;        DE = data buffer address
  614.  
  615. RDISK:    CALL    EXEC
  616.     RNZ            ;Return if timeout
  617. RDISK1:    IN    DIO+2        ;Read status
  618.     ORA    A
  619.     JP    RDISK1        ;If request is present
  620.     ANI    CMND
  621.     JNZ    GCMPS
  622.     IN    DIO
  623.     STAX    D
  624.     INX    D
  625.     JMP    RDISK1
  626. ;
  627. ;
  628. ;
  629. ;
  630. ;    WAITF - Wait for function to complete.
  631.  
  632. WAITF:    MVI    B,REQ+CMND    ;Wait for both REQ and CMND
  633.     MOV    C,B
  634.     CALL    WAITM
  635.     RNZ
  636. ;
  637. ;    Get completion status.
  638.  
  639. GCMPS:    IN    DIO        ;Get completion status
  640.     MOV    C,A
  641.  
  642. GCMP1:    IN    DIO+2
  643.     ORA    A
  644.     JP    GCMP1        ;If REQ not set
  645.  
  646.     MOV    B,A
  647.     IN    DIO        ;Get message byte
  648.     RET
  649.     ENDIF
  650. ;
  651.  
  652. ;
  653. ;
  654. ;
  655.     IF    I796
  656. ;    EXEC - Output the command
  657. ;
  658. ;    Enter:    HL is the command buffer address
  659. ;        DE - data transfer address.
  660.  
  661. EXEC:
  662.     MOV    A,E        ;Output DMA address
  663.     OUT    DIO+2
  664.     MOV    A,D
  665.     OUT    DIO+3
  666.     MOV    A,L
  667.     OUT    DIO+4
  668.     MOV    A,H
  669.     OUT    DIO+5
  670.     MVI    A,0
  671.     OUT    DIO+6
  672.     OUT    DIO+7
  673.     OUT    DIO
  674.     CMP    A        ;Z:=1
  675.     RET
  676.  
  677.  
  678. ;    Disk read/write
  679. ;
  680. ;    Entry:    same as EXEC
  681. ;
  682. RDISK:
  683. WDISK:    CALL    EXEC
  684.     RNZ            ;Return if timeout
  685.  
  686. ;    WAITF - Wait until transfer done
  687. ;
  688. ;    Enter:    none
  689. ;    Exit:    when transfer completed
  690.  
  691. WAITF:    MVI    B,CMDDON    ;Wait for CMDDON
  692.     MOV    C,B
  693.     CALL    WAITM
  694.     RNZ            ;Return if timeout
  695. ;
  696.  
  697. ;    GCMPS - Get completion status
  698. ;
  699. ;    Enter:    none
  700. ;    Exit:    Status in C
  701. GCMPS:    IN    DIO+1
  702.     MOV    C,A
  703.     RET
  704.     ENDIF
  705.  
  706. ;    WAITM - Wait for controller with timeout
  707. ;
  708. ;    Entry:    B=Status mask
  709. ;        C=Status value
  710. ;    Exit:    Z=1 if OK, else timeout with A=C=TERR
  711. ;
  712. WAITM:
  713.     PUSH    D        ;Save D
  714.     PUSH    H
  715.     LXI    H,138        ;Two minute timeout
  716.     LXI    D,0        ;Max wait @4MHZ is 868 ms
  717. WAITML:
  718.     IF    I696
  719.     IN    DIO+2
  720.     ENDIF
  721.     IF    I796
  722.     IN    DIO
  723.     ENDIF
  724.     ANA    B        ;Mask wait bits
  725.     CMP    C        ;Check value
  726.     JZ    WAITM1
  727.     DCX    D        ;Not ready.  Decrement time
  728.     MOV    A,D
  729.     ORA    E
  730.     JNZ    WAITML
  731.     DCX    H
  732.     MOV    A,H
  733.     ORA    L
  734.     JNZ    WAITML
  735.     MVI    B,0        ;Timeout
  736.     MVI    A,TERR
  737.     ORA    A
  738. WAITM1:
  739.     POP    H
  740.     POP    D        ;Restore D
  741.     MOV    C,A        ;Return status in C
  742.     RET
  743. ;    DTC Error Print Routine
  744. ;
  745. ;Called at completion of disk command when error status is returned.
  746. ;
  747. ;    Entry:    HL = Address of Command Descriptor Block
  748. ;        C = Status byte
  749. ;
  750. ERROR:
  751.     PUSH    B        ;Save status
  752.     PUSH    H        ;SAVE ADDRESS OF CDB
  753.     MOV    A,M        ;GET CLASS CODE
  754.     ANI    0E0H
  755.     RAL            ;MAKE CDB LENGTH INDEX
  756.     RAL
  757.     RAL
  758.     MOV    E,A        ;GET CDB LENGTH
  759.     MVI    D,0
  760.     LXI    H,CDBLEN
  761.     DAD    D
  762.     MOV    C,M
  763.     POP    H        ;RESTORE CDB ADDRESS
  764.     PUSH    H
  765.     LXI    D,ERRCDB
  766.     CALL    PUTHEX        ;BUILD CDB FOR PRINT
  767.     LXI    D,EHEAD        ;Print header
  768.     MVI    C,PRTSTR
  769.     CALL    BDOSV
  770.     POP    H        ;Get status
  771.     POP    B
  772.     PUSH    H
  773.     MOV    A,C        ;Timeout?
  774.     ANI    TERR
  775.     LXI    D,TOMSG
  776.     JNZ    ERROR1
  777.     LXI    H,CIOESC    ;No. READ ERROR SENSE
  778.     LXI    D,SENSE
  779.     CALL    RDISK
  780.     LXI    D,ESENSE
  781.     MVI    C,PRTSTR
  782.     CALL    BDOSV
  783.     LXI    D,ESENS1
  784.     LXI    H,SENSE
  785.     MOV    A,M
  786.     MVI    C,PRTSTR
  787.     ORA    A
  788.     CM    BDOSV
  789.     LXI    D,ETYPE
  790.     LXI    H,SENSE        ;BUILD ERROR SENSE MESSAGE
  791.     MOV    A,M
  792.     RAR
  793.     RAR
  794.     RAR
  795.     RAR
  796.     ANI    3
  797.     CALL    HEXASC
  798.     LXI    D,ECODE
  799.     MOV    A,M
  800.     CALL    HEXASC
  801.     LXI    D,ELUN
  802.     INX    H
  803.     MOV    A,M
  804.     RLC
  805.     RLC
  806.     RLC
  807.     ANI    7
  808.     CALL    HEXASC
  809.     MOV    A,M
  810.     ANI    01FH
  811.     MOV    M,A
  812.     LXI    D,ELAD
  813.     MVI    C,3
  814.     CALL    PUTHEX
  815.     LXI    D,ESENS2    ;PRINT MESSAGE
  816. ERROR1:
  817.     MVI    C,PRTSTR
  818.     CALL    BDOSV
  819.     POP    H        ;RESTORE CDB ADDRESS
  820.     RET
  821. ;
  822. ;
  823.  
  824. ;    PUT HEXADECIMAL STRING
  825. ;
  826. ;    ENTRY:    HL = ADDRESS OF HEX NUMBER STRING
  827. ;        DE = ADDRESS OF HEX ASCII STRING
  828. ;         C = NUMBER OF BYTES TO CONVERT
  829. ;
  830. PUTHEX:    CALL    HEXBYT
  831.     MVI    A,' '
  832.     STAX    D
  833.     INX    D
  834.     DCR    C
  835.     JNZ    PUTHEX
  836.     MVI    A,EOS
  837.     STAX    D
  838.     RET
  839. ;
  840. ;
  841. HEXBYT:    MOV    A,M
  842.     RAR
  843.     RAR
  844.     RAR
  845.     RAR
  846.     CALL    HEXASC
  847.     MOV    A,M
  848.     INX    H
  849. HEXASC:    ANI    0FH
  850.     ADI    090H
  851.     DAA
  852.     ACI    040H
  853.     DAA
  854.     STAX    D
  855.     INX    D
  856.     RET
  857. ;
  858. ;
  859. ;    CDB length table (indexed by class)
  860. CDBLEN:    DB    6,10,0,0,0,0,6,6
  861. ;
  862. EHEAD:    DB    CR,LF,LF,'Disk error:'
  863.     DB    CR,LF,'Command Descriptor:',TAB,TAB
  864. ERRCDB:    DS    31
  865. ;
  866. TOMSG:    DB    CR,LF,TAB,TAB,TAB,TAB,'Timeout',EOS
  867. ESENSE:    DB    CR,LF,'Error Sense:',EOS
  868. ESENS1:    DB    CR,LF,TAB,TAB,TAB,TAB,'Block address valid.',EOS
  869. ESENS2:    DB    CR,LF,TAB,'Error type:',TAB,TAB
  870. ETYPE:    DS    1
  871.     DB    CR,LF,TAB,'Error code:',TAB,TAB
  872. ECODE:    DS    1
  873.     DB    CR,LF,TAB,'Logical unit:',TAB,TAB
  874. ELUN:    DS    1
  875.     DB    CR,LF,TAB,'Logical address:',TAB
  876. ELAD:    DS    4
  877. SENSE:    DS    4
  878. ;
  879. BUFFER:    DS    9*1024+256
  880. ;
  881.     END
  882.