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 / CPMUG025.ARK / CBIOS24.ASM < prev    next >
Assembly Source File  |  1984-04-29  |  27KB  |  1,070 lines

  1. ; BASIC INPUT/OUTPUT OPERATING SYSTEM
  2. ; TARBELL ELECTRONICS
  3. ; 4-DRIVE VERSION OF 2-15-78
  4. ; (NOTE THAT CP/M VERSION 1.3 ONLY SUPPORTS 2 DRIVES,
  5. ; WHILE CP/M VERSION 1.4 WILL SUPPORT 4 DRIVES.)
  6. ;
  7. ; THIS MODULE CONTAINS ALL THE INPUT/OUTPUT
  8. ; ROUTINES FOR THE CP/M SYSTEM, INCLUDING
  9. ; THE DISK ROUTINES.
  10. ;
  11. MSIZE    EQU  24        ;MEMORY SIZE.
  12.  
  13. ; THIS SECTION DEFINES THE I/O PORTS AND
  14. ; STATUS BITS.  BY SETTING THE PROPER VALUES
  15. ; FOR THE EQU STATEMENTS, THE I/O MAY BE
  16. ; AUTOMATICALLY RECONFIGURED TO FIT MOST
  17. ; SITUATIONS.  THE TRUE AND FALSE ONES
  18. ; CONTROL CONDITIONAL ASSEMBLIES OF DIFFERENT
  19. ; SECTIONS OF I/O ROUTINES TO FIT DIFFERENT
  20. ; INTERFACE REQUIREMENTS.
  21.  
  22. TRUE    EQU  0FFFFH    ;DEFINE VALUE OF TRUE.
  23. FALSE    EQU  NOT TRUE    ;DEFINE VALUE OF FALSE.
  24.  
  25. INTRP    EQU  FALSE    ;TRUE IF INTERRUPTS ALLOWED.
  26.  
  27. STD    EQU  TRUE    ;TRUE IF STANDARD I/O.
  28. MSIO2    EQU  FALSE    ;TRUE IF MITS 2SIO.
  29. ISIO2    EQU  FALSE    ;TRUE IF IMSAI SIO-2.
  30. TUART    EQU  FALSE    ;TRUE IF CROMEMCO TUART.
  31. VDM    EQU  FALSE    ;TRUE IF PROC TECH VDM.
  32. SIO2    EQU  MSIO2 OR ISIO2 OR TUART
  33. OTHER    EQU  FALSE    ;TRUE IF SOMETHING ELSE.
  34.  
  35. CSTAT    EQU  0        ;CONSOLE STATUS PORT.
  36. CCOM    EQU  0        ;CONSOLE COMMAND PORT.
  37. CDATA    EQU  1        ;CONSOLE DATA PORT.
  38.  
  39.     IF   STD    ;IF STANDARD I/O,
  40. CKBR    EQU  00000001B    ;KEYBOARD READY BIT.
  41. CPTR    EQU  10000000B    ;CONS OUTPUT RDY BIT.
  42.     ENDIF
  43.  
  44.     IF   MSIO2    ;IF MITS 2SIO,
  45. CKBR    EQU  00000001B    ;KEYBOARD READY BIT.
  46. CPTR    EQU  00000010B    ;PRINT READY BIT.
  47.     ENDIF
  48.  
  49.     IF   ISIO2    ;IF IMSAI SIO-2,
  50. CKBR    EQU  00000010B    ;KEYBOARD READY BIT.
  51. CPTR    EQU  00000001B    ;PRINT READY BIT.
  52.     ENDIF
  53.  
  54.     IF   TUART    ;IF CROMEMCO TUART,
  55. CKBR    EQU  01000000B    ;KEYBOARD READY BIT.
  56. CPTR    EQU  10000000B    ;PRINT READY BIT.
  57.     ENDIF
  58.  
  59.     IF OTHER    ;IF SOMETHING ELSE,
  60. CKBR    EQU  00000010B    ;KEYBOARD READY BIT.
  61. CPTR    EQU  10000000B    ;PRINTER READY BIT.
  62.     ENDIF
  63.  
  64. CNULL    EQU  1        ;CONSOLE NULL COUNT.
  65.  
  66. LSTAT    EQU  2        ;LIST STATUS PORT.
  67. LCOM    EQU  2        ;LIST COMMAND PORT.
  68. LDATA    EQU  3        ;LIST DATA PORT.
  69. LRBIT    EQU  CPTR    ;LIST READY BIT.
  70. LNULL    EQU  2        ;LIST NULL COUNT.
  71.  
  72. DUAL    EQU  FALSE    ;TRUE IF DUAL DRIVE.
  73. FAST    EQU  FALSE    ;TRUE IF FAST SEEK.
  74.  
  75. DISK    EQU  0F8H    ;DISK BASE ADDRESS.
  76. DCOM    EQU  DISK    ;DISK COMMAND PORT.
  77. DSTAT    EQU  DISK    ;DISK STATUS PORT.
  78. TRACK    EQU  DISK+1    ;DISK TRACK PORT.
  79. SECTP    EQU  DISK+2    ;DISK SECTOR PORT.
  80. DDATA    EQU  DISK+3    ;DISK DATA PORT.
  81. WAIT    EQU  DISK+4    ;DISK WAIT PORT.
  82. DCONT    EQU  DISK+4    ;DISK CONTROL PORT.
  83.  
  84. RTCNT    EQU  10        ;RETRY COUNT.
  85.  
  86.     ORG  MSIZE*1024-1536    ;FIRST ADDRESS.
  87.  
  88. CBASE    EQU  (MSIZE-17)*1024  ;BIAS FOR LARGER THAN 17K.
  89. CPMB    EQU  CBASE+2900H    ;START OF CPM.
  90. BDOS    EQU  CBASE+3106H    ;START OF BDOS.
  91. CPML    EQU  $-CPMB    ;LENGTH OF CPM SYSTEM-BIOS.
  92. NSECTS    EQU  CPML/128    ;NUMBER OF SECTORS IN IT.
  93. ;
  94. ; I/O JUMP VECTOR
  95. ; THIS IS WHERE CPM CALLS WHENEVER IT NEEDS
  96. ; TO DO ANY INPUT/OUTPUT OPERATION.
  97. ; USER PROGRAMS MAY USE THESE ENTRY POINTS
  98. ; ALSO, BUT NOTE THAT THE LOCATION OF THIS
  99. ; VECTOR CHANGES WITH THE MEMORY SIZE.
  100. ;
  101.     JMP  BOOT    ;FROM COLD START LOADER.
  102. WBOOTE:    JMP  WBOOT    ;FROM WARM BOOT.
  103.     JMP  CONST    ;CHECK CONSOLE KB STATUS.
  104.     JMP  CONIN    ;READ CONSOLE CHARACTER.
  105.     JMP  CONOT    ;WRITE CONSOLE CHARACTER.
  106.     JMP  LIST    ;WRITE LISTING CHAR.
  107.     JMP  PUNCH    ;WRITE PUNCH CHAR.
  108.     JMP  READER    ;READ READER CHAR.
  109.     JMP  HOME    ;MOVE DISK TO TRACK ZERO.
  110.     JMP  SELDSK    ;SELECT DISK DRIVE.
  111.     JMP  SETTRK    ;SEEK TO TRACK IN REG A.
  112.     JMP  SETSEC    ;SET SECTOR NUMBER.
  113.     JMP  SETDMA    ;SET DISK STARTING ADR.
  114. READN:    JMP  READ    ;READ SELECTED SECTOR.
  115. WRITEN:    JMP  WRITE    ;WRITE SELECTED SECTOR.
  116. ; THESE ENTRY POINTS ADDED BY TARBELL ELECTRONICS.
  117.     JMP  READN    ;READ WITH NO HEAD LOAD.
  118.     JMP  WRITEN    ;WRITE WITH NO HEAD LOAD.
  119. ;
  120. ; BOOT
  121. ; THIS SECTION IS EXECUTED WHENEVER RESET AND RUN
  122. ; IS PUSHED, AFTER THE COLDSTART LOADER READS IN
  123. ; THE CPM SYSTEM.
  124. ;
  125. BOOT:    LXI  SP,80H    ;SET STACK POINTER.
  126.  
  127.     IF  INTRP    ;IF INTERRUPTS ALLOWED,
  128.     EI        ;ENABLE THEM HERE.
  129.     ENDIF
  130.  
  131.     IF   VDM    ;IF PROC TECH VDM,
  132.     CALL CLR    ;CLEAR VDM SCREEN.
  133.     ENDIF
  134.  
  135.     IF   STD    ;IF STANDARD I/O,
  136.     NOP!NOP!NOP!NOP    ;LEAVE SPACE FOR INIT.
  137.     NOP!NOP!NOP!NOP
  138.     NOP!NOP!NOP!NOP
  139.     NOP!NOP!NOP!NOP
  140.     ENDIF
  141.  
  142.     IF   MSIO2    ;IF MITS 2SIO,
  143.     MVI  A,3    ;INITIALIZE 2SIO.
  144.     OUT  CCOM
  145.     OUT  LCOM
  146.     MVI  A,11H
  147.     OUT  CCOM
  148.     OUT  LCOM
  149.     ENDIF
  150.  
  151.     IF   ISIO2    ;IF IMSAI SIO2,
  152.     MVI  A,0AAH    ;INITIALIZE SIO 2-2.
  153.     OUT  CCOM
  154.     MVI  A,40H
  155.     OUT  CCOM
  156.     MVI  A,0CEH
  157.     OUT  CCOM
  158.     MVI  A,37H
  159.     OUT  CCOM
  160.     ENDIF
  161.  
  162.     IF   TUART    ;IF CROMEMCO TUART,
  163.     MVI  A,1    ;SET A = 1.
  164.     OUT  54H    ;SELECT DEVICE A.
  165.     OUT  52H    ;RESET DEVICE B.
  166.     LXI  H,BAUDRS    ;GET ADR OF BAUD RATE TABLE.
  167.     MVI  A,11H    ;OCTUPLE THE CLOCK.
  168. IT1:    OUT  02H    ;& RESET CURRENT DEV.
  169.     MOV  A,M    ;GET BAUD RATE FROM TABLE.
  170.     OUT  0        ;SET BAUD RATE.
  171.     CALL CONIN    ;READ KEYBOARD.
  172.     CALL CONIN    ;READ KEYBOARD AGAIN.
  173.     CPI  0DH    ;IF NOT CARRIAGE-RETURN,
  174.     MVI  A,1    ;SLOW THE CLOCK.
  175.     JNZ  IT1    ;UNTIL A CARRIAGE-RETURN.
  176.     ENDIF
  177.  
  178.     LXI  H,SMSG    ;PRINT OPENING MESSAGE.
  179.     CALL PMSG
  180.     CALL CONIN    ;READ # OF DISKS.
  181.     MOV  C,A    ;ECHO THE CHAR.
  182.     CALL CONOT
  183.     ANI  7        ;LOOK AT 3 LSB'S.
  184.     STA  NODSKS    ;SAVE IT.
  185.     XRA  A        ;SET DISK NUMBER = 0.
  186.     STA  DISKNO
  187. GOCPM:    MVI  A,0C3H    ;PUT JMP TO WBOOT
  188.     STA  0        ;ADR AT ZERO.
  189.     LXI  H,WBOOTE
  190.     SHLD 1
  191.     STA  5
  192.     LXI  H,BDOS    ;PUT JUMP TO BDOS
  193.     SHLD 6        ;AT ADR 5,6,7.
  194.     LXI  H,80H    ;SET DEFAULT DMA ADR.
  195.     SHLD DMAADD
  196.     LDA  DISKNO    ;GET DISK NUMBER TO
  197.     MOV  C,A    ;PASS TO CCP IN C.
  198.     JMP  CPMB    ;JUMP TO CCP.
  199.  
  200.     IF   TUART    ;IF CROMEMCO TUART,
  201. BAUDRS:    DB   94H,0CEH,0A2H,92H,88H,84H,82H,1
  202.     ENDIF
  203.  
  204. ;
  205. ; WARM-BOOT:  READ ALL OF CPM BACK IN
  206. ; EXCEPT BIOS, THEN JUMP TO CCP.
  207. ;
  208. WBOOT:   LXI SP,80H    ;SET STACK POINTER.
  209.  
  210.     IF  INTRP    ;IF INTERRUPTS ALLOWED,
  211.     EI        ;ALLOW THEM HERE.
  212.     ENDIF
  213.  
  214.     LDA  DISKNO    ;SAVE DISK NUMBER.
  215.     STA  TEMP
  216.     MVI  C,0    ;SELECT DISK ZERO.
  217.     CALL SELDSK
  218.     CALL HOME    ;MOVE TO TRACK ZERO.
  219.          JNZ  RDERR    ;IF ERROR, PRINT MESSAGE.
  220.          MVI  D,NSECTS    ;GET # SECTORS FOR CPM READ.
  221.          LXI  B,2    ;TRACK (B)=0, SECTOR (C)=2.
  222.          LXI  H,CPMB    ;GET STARTING ADDRESS.
  223.  
  224.     IF  INTRP    ;IF INTERRUPTS ALLOWED,
  225.     DI        ;DISABLE THEM HERE.
  226.     ENDIF
  227.  
  228. RDBLK:   MOV  A,B    ;GO TO TRACK IN B.
  229.          CALL SEEK
  230.          JNZ  RDERR    ;IF ERROR, PRINT MESSAGE.
  231.          MOV  A,C    ;READ STARTING AT SECTOR IN C.
  232.          CALL  READ1
  233. RBLK1    JNZ  RDERR    ;IF ERROR, PRINT MESSAGE.
  234.          DCR  D        ;DECREMENT SECTOR COUNT.
  235.     JZ   ALDON    ;ALL DONE WHEN ZERO.
  236.          INR  C        ;INCREMENT SECTOR NUMBER.
  237.      MOV  A,C    ;IF SECTOR NUMBER
  238.          CPI  27    ;IS NOT 27,
  239.          JC   RBLK2    ;HOP OUT OF LOOP.
  240.          MVI  C,1    ;OTHERWISE, RESET SECTOR=1
  241.          INR  B        ;INCREMENT TRACK NUMBER,
  242.          JMP  RDBLK    ;AND READ NEXT TRACK.
  243. ALDON:    LDA  TEMP    ;RESTORE DISK NUMBER.
  244.  
  245.     IF  INTRP    ;IF INTERRUPTS ALLOWED,
  246.     EI        ;ALLOW THEM AGAIN HERE.
  247.     ENDIF
  248.  
  249.     STA  DISKNO
  250.     JMP  GOCPM    ;GO BACK TO CPM.
  251. ;
  252. RBLK2:   CALL READ2    ;READ ANOTHER TRACK.
  253.          JMP  RBLK1
  254. ;
  255. RDERR:   LXI  H,BTMSG    ;GET ADDRESS OF "BOOT ERROR".
  256.          CALL PMSG    ;PRINT IT.
  257.          CALL CONIN    ;READ A CHAR FROM CONSOLE.
  258.          JMP  WBOOT    ;DO A WARM BOOT.
  259. ;
  260. ; CHECK CONSOLE INPUT STATUS.
  261. ;
  262.  
  263. CONST:    IN   CSTAT    ;READ CONSOLE STATUS.
  264.     ANI  CKBR    ;LOOK AT KB READY BIT.
  265.     MVI  A,0    ;SET A=0 FOR RETURN.
  266.  
  267.     IF   STD    ;IF STANDARD I/O,
  268.     RNZ        ;NOT READY WHEN NOT 0.
  269.     ENDIF
  270.  
  271.     IF SIO2        ;IF MITS OR IMSAI,
  272.     RZ        ;NOT READY WHEN ZERO.
  273.     ENDIF
  274.  
  275.     IF OTHER    ;IF SOMETHING ELSE,
  276.     RNZ        ;IT MIGHT BE THIS.
  277.     ENDIF
  278.  
  279.     CMA        ;IF READY A=FF.
  280.     RET        ;RETURN FROM CONST.
  281.  
  282. ;
  283. ; READ A CHARACTER FROM CONSOLE.
  284. ;
  285. CONIN:   IN   CSTAT        ;READ CONSOLE STATUS.
  286.          ANI  CKBR    ;IF NOT READY,
  287.  
  288.     IF   STD    ;IF STANDARD I/O,
  289.     JNZ  CONIN    ;READY WHEN LOW.
  290.     ENDIF
  291.  
  292.     IF SIO2        ;IF MITS OR IMSAI,
  293.     JZ   CONIN    ;READY WHEN HIGH.
  294.     ENDIF
  295.  
  296.     IF OTHER    ;IF SOMETHING ELSE,
  297.     JNZ  CONIN    ;IT MIGHT BE THIS.
  298.     ENDIF
  299.  
  300.          IN   CDATA    ;READ A CHARACTER.
  301.          ANI  7FH    ;MAKE MOST SIG. BIT = 0.
  302.          RET
  303. ;
  304. ; WRITE A CHARACTER TO THE CONSOLE DEVICE.
  305. ;
  306.  
  307.     IF NOT VDM    ;IF NOT PROC TECH VDM,
  308. CONOT:    MVI  A,0DH    ;IF IT'S A CR,
  309.     CMP  C        ;THEN HOP OUT
  310.     JZ   CONUL    ;TO NULL ROUTINE.
  311. CONOT1:    IN   CSTAT    ;READ CONSOLE STATUS.
  312.     ANI  CPTR    ;IF NOT READY,
  313.     ENDIF
  314.  
  315.     IF STD AND NOT VDM  ;IF STANDARD I/O,
  316.     JNZ  CONOT1    ;READY WHEN LOW.
  317.     ENDIF
  318.  
  319.     IF SIO2        ;IF MITS OR IMSAI,
  320.     JZ   CONOT1    ;READY WHEN HIGH.
  321.     ENDIF
  322.  
  323.     IF NOT VDM    ;IF NOT PROC TECH VDM,
  324.     MOV  A,C    ;GET CHARACTER.
  325.     OUT  CDATA    ;PRINT IT.
  326.     RET        ;RETURN.
  327. CONUL:    PUSH B        ;SAVE B&C.
  328.     MVI  B,CNULL    ;GET NULL COUNT.
  329. CONUL1:    CALL CONOT1    ;PRINT CR.
  330.     MVI  C,0    ;GET NULL CHAR.
  331.     DCR  B        ;DECREMENT COUNTER.
  332.     JNZ  CONUL1    ;DO NEXT NULL.
  333.     POP  B        ;RESTORE B&C.
  334.     MOV  A,C    ;RESTORE A.
  335.     RET        ;RETURN.
  336.     ENDIF
  337.  
  338.     IF   VDM    ;IF PROC TECH VDM,
  339. ; VDM DRIVER FOR CBIOS.
  340. ; 9-24-77 VERSION
  341. ;
  342. VDMB   EQU  0CC00H
  343. VDMP   EQU  0CCH
  344. VDMD   EQU  0C8H
  345. CONOT: MOV  A,C        ;PUT CHAR IN A.
  346.        SHLD HLSAV    ;SAVE H&L.
  347.        LXI  H,0        ;CLEAR H&L.
  348.        DAD  SP        ;HL=SP.
  349.        LXI  SP,VSTACK    ;SET STACK PTR.
  350.        PUSH H        ;SAVE OLD SP.
  351.        PUSH D        ;SAVE D&E.
  352.        PUSH B        ;SAVE B&C.
  353.        PUSH PSW        ;SAVE A&PSW.
  354.        CALL SCREEN    ;WRITE ON SCREEN.
  355.        POP  PSW        ;RESTORE A&PSW.
  356.        POP  B        ;RESTORE B&C.
  357.        POP  D        ;RESTORE D&E.
  358.        POP  H        ;RESTORE H&L.
  359.        SPHL        ;RESTORE SP.
  360.        LHLD HLSAV    ;RESTORE H&L.
  361.        RET        ;RETURN FROM CONOT.
  362. ;
  363. ;
  364. SCREEN: MOV  B,A    ;GET CHARACTER.
  365.        MOV  A,B
  366.        ANI  7FH        ;NOT DELETE.
  367.        CPI  0DH        ;IF IT'S CR,
  368.        JZ   CHOT2    ;TAKE CARE OF IT.
  369.        CPI  20H        ;CTL CHAR?
  370.        RC        ;DON'T DISPLAY.
  371.     JMP  CHOUT    ;GO TO CHOUT.
  372. ;
  373. ; CLEAR SCREEN & INIT CURSOR.
  374. ;
  375. CLR:   LXI  H,VDMB    ;GET VDM MEM ADR.
  376.        MOV  A,H        ;FIGURE VDM MEM TOP.
  377.        ADI  4
  378. CLR2:  MVI  M,' '    ;PUT SPACE IN MEMORY.
  379.        INX  H        ;INCREMENT POINTER.
  380.        CMP  H        ;AT TOP YET?
  381.        JNZ  CLR2    ;KEEP GOING IF NOT.
  382.        XRA  A        ;SET A = 0.
  383.        STA  BOSL    ;BEG SCRN LINE = 0.
  384.        STA  BOTL    ;BEG TEXT LINE = 0.
  385.        STA  CCP        ;CURSOR PTR = 0.
  386.     CMA        ;SET A = FF.
  387.     STA CURF    ;SET CURSOR ON.
  388.        MVI  A,15    ;SET CURSOR AT BOTTOM.
  389.        STA  CLN
  390.        CALL VDMOT    ;SET VDM UP.
  391.        RET        ;RETURN FROM CLR.
  392. ;
  393. ; OUTPUT BOSL & BOTL TO VDM.
  394. ;
  395. VDMOT: LDA  BOSL    ;INITIALIZE VDM.
  396.        RLC        ;SHIFT LEFT 4.
  397.        RLC
  398.        RLC
  399.        RLC
  400.        LXI  H,BOTL
  401.        ORA  M
  402.        OUT  VDMD    ;OUT TO VDM PORT.
  403.        RET        ;RETURN FROM VDMOT.
  404. ;
  405. ; STORE CHAR IN VDM MEMORY.
  406. ;
  407. CHOUT: MOV  C,A        ;SAVE CHARACTER.
  408.        LDA  CCP        ;GET CURSOR PTR.
  409.        MOV  B,A        ;PUT IN B.
  410.        LDA  CLN        ;GET LINE NUMBER.
  411.        CALL CLNA    ;CONVERT TO ADR.
  412.        MOV  M,C        ;PUT CHAR ON SCREEN.
  413.        LDA  CCP        ;ADVANCE CURSOR.
  414.        INR  A
  415.        CPI  64        ;WRAP AROUND?
  416.        JNZ  CHOT1
  417. CHOT2: LDA  CCP        ;GET CURSOR POS.
  418.        MOV  B,A
  419.        LDA  CLN        ;GET LINE NUMBER.
  420.        CALL CCUR    ;CLEAR CURSOR.
  421.        CALL SCRL    ;SCROLL UP.
  422.        SUB  A        ;CURSOR TO LEFT MARGIN.
  423. CHOT1: STA  CCP
  424.        MOV  B,A
  425.        LDA  CLN
  426.        JMP  SCUR    ;SET CURSOR ON/OFF.
  427. ;
  428. ;
  429. SCRL:  LXI  H,BOTL    ;SAVE BEG. TEXT LINE.
  430.        PUSH H
  431.        MOV  A,M
  432.        INR  M
  433.        SUB  M
  434.        LXI  B,0
  435.        CALL CLNA    ;CONVERT LINE NO.
  436.        LXI  B,2040H
  437. SCRL2: MOV  M,B        ;CLEAR BOTTOM LINE.
  438.        INR  L
  439.        DCR  C
  440.        JNZ  SCRL2
  441.        POP  H
  442.        MOV  A,M
  443.        ANI  0FH
  444.        MOV  M,A
  445.        JMP  VDMOT
  446. ;
  447. ; CONVERT LINE NUMBER IN REG A AND CHR
  448. ; POSITION IN REG B TO ADDRESS IN H&L.
  449. ;
  450. CLNA:  MOV  L,A
  451.        LDA  BOTL
  452.        ADD  L
  453.        RRC
  454.        RRC
  455.        MOV  L,A
  456.        ANI  3
  457.        ADI  VDMP
  458.        MOV  H,A
  459.        MOV  A,L
  460.        ANI  0C0H
  461.        ADD  B
  462.        MOV  L,A
  463.        RET
  464. ;
  465. ;
  466. SCUR:  ANI  0FH
  467.        STA  CLN
  468.        CALL CLNA
  469.        MOV  A,B
  470.        STA  CCP
  471.        LDA  CURF
  472.        ORA  A
  473.        MOV  A,M
  474.        JZ   CCUR2
  475.        ORI  80H
  476.        MOV  M,A
  477.        RET
  478. CCUR2: ANI  7FH
  479.        MOV  M,A
  480.        RET
  481. ;
  482. ;
  483. CCUR:  CALL CLNA
  484.        MOV  A,M
  485.        ANI  7FH
  486.        MOV  M,A
  487.        RET
  488. ;
  489. ;
  490. CLN:   DS   1
  491. CCP:   DS   1
  492. CURF:  DS   1
  493. BOSL:  DS   1
  494. BOTL:  DS   1
  495. HLSAV: DS   32
  496. VSTACK: DS   1
  497.     ENDIF        ;END OF VDM DRIVER.
  498.  
  499. ;
  500. ; MOVE DISK TO TRACK ZERO.
  501. ;
  502. HOME:    MVI  A,RTCNT    ;GET RETRY COUNT.
  503. HRETRY:    STA  ERCNT    ;STORE IN ERROR CTR.
  504.     MVI  A,0D0H    ;CLEAR ANY PENDING COMMAND.
  505.     OUT  DCOM
  506.     LDA  DISKNO    ;GET DISK NUMBER.
  507.     MOV  E,A    ;PUT IN D&E.
  508.     XRA  A    
  509.     MOV  D,A
  510.     LXI  H,TRTAB    ;GET ADR OF TRK TABLE.
  511.  
  512.     IF  NOT DUAL    ;IF NOT A DUAL DRIVE.
  513.     DAD  D        ;ADD DISK NUMBER.
  514.     ENDIF
  515.  
  516.     MOV  M,A    ;PUT ZERO INTO TABLE.
  517. HOME1:    IN   DSTAT    ;READ DISK STATUS.
  518.     RRC        ;LOOK AT LSB.
  519.     JC   HOME1    ;WAIT FOR NOT BUSY.
  520.  
  521.     IF   FAST    ;IF FAST SEEK,
  522.     LDA  NODSKS    ;GET NUMBER OF DISKS.
  523.     DCR  A        ;IF ONLY ONE DISK,
  524.     JZ   HOME2    ;SKIP OVER NEXT PART.
  525.     LDA  DISKNO    ;GET DISK NUMBER.
  526.     RLC!RLC!RLC!RLC    ;SHIFT LEFT 4 BITS.
  527.     ANI  10H    ;LOOK AT BIT 4.
  528. HOME2:    CMA        ;INVERT.
  529.     MOV  E,A    ;SAVE IT.
  530.     ANI  0B2H    ;SET PERSCI
  531.     OUT  DCONT    ;RESTORE LINE.
  532. HLOOP:    IN   DSTAT    ;LOOK AT STATUS
  533.     ANI  4        ;BIT 2 (TRACK 0)
  534.     JZ   HLOOP    ;AND WAIT TILL 1.
  535.     MOV  A,E    ;RESTORE OLD BITS
  536.     ANI  0F2H    ;IN LATCH AND CLEAR
  537.     OUT  DCONT    ;RESTORE LINE.
  538.     ENDIF
  539.  
  540.     MVI  A,2    ;10 MS STEP RATE.
  541.     OUT  DCOM    ;ISSUE HOME COMMAND.
  542.     IN   WAIT    ;WAIT FOR INTRQ.
  543.     ORA  A        ;SET FLAGS.
  544.     JM   HERR    ;ERROR IF DRQ.
  545.     IN   DSTAT    ;READ DISK STATUS.
  546.     MOV  D,A    ;SAVE IN REGISTER D.
  547.     ANI  4        ;LOOK AT BIT 2.
  548.     JZ   HERR    ;ERROR IF NOT TRK 0.
  549.     MOV  A,D    ;GET STATUS BACK.
  550.     ANI  91H    ;MASK NON-ERROR BITS.
  551.     RZ        ;RETURN IF NO ERROR.
  552. HERR:    LDA  HECNT    ;GET TOTAL ERROR COUNT.
  553.     INR  A        ;ADD ONE.
  554.     STA  HECNT    ;SAVE IT BACK.
  555.     LDA  ERCNT    ;GET THIS ERROR COUNT.
  556.     DCR   A        ;DECREMENT COUNT.
  557.     JNZ  HRETRY    ;TRY TO HOME AGAIN.
  558.     LXI  H,HEMSG    ;PRINT "HOME ".
  559.     MOV  A,D    ;MASK NON-ERROR BITS.
  560.     ANI  91H
  561.     MOV  D,A
  562.     JMP  ERMSG    ;DO COMMON ERROR MSGS.
  563. ;
  564. ; SELECT DISK NUMBER ACCORDING TO REGISTER C.
  565. ;
  566. SELDSK:    MOV  A,C    ;GET NEW DISK NUMBER.
  567.     ANI  3        ;ONLY LOOK AT 2 LSB'S.
  568.     LXI  H,DISKNO    ;GET ADR OF OLD DISK NO.
  569.     CMP  M        ;NEW = OLD?
  570.     RZ        ;IF SO, RETURN.
  571.     PUSH A        ;SAVE DISK NUMBER.
  572.     LDA  NODSKS    ;GET NUMBER OF DISKS.
  573.     DCR  A        ;IF MORE THAN ONE DISK,
  574.     JNZ  SELMOR    ;TAKE CARE OF IT.
  575.     LXI  H,MNTMSG    ;GET ADR OF MOUNT MESSAGE.
  576.     CALL PMSG    ;PRINT "MOUNT ".
  577.     POP  A        ;GET DISK NUMBER.
  578.     STA  DISKNO    ;UPDATE OLD WITH NEW.
  579.     ADI  'A'    ;ADD ASCII FOR 'A'.
  580.     MOV  C,A    ;PUT INTO C.
  581.     CALL CONOT    ;PRINT IT.
  582.     CALL CONIN    ;READ A CARRIAGE RETURN.
  583.     XRA  A        ;SET A=0 FOR NO ERRO IND.
  584.     RET        ;RETURN FROM SELDSK.
  585. SELMOR:    POP  A        ;MAKE STACK RIGHT.
  586.     MOV  A,M    ;GET OLD DISK NUMBER.
  587.  
  588.     IF   DUAL    ;IF DUAL DRIVE,
  589.     ANI  0FEH    ;CLEAR OUT BIT 0.
  590.     ENDIF
  591.  
  592.     MOV  E,A    ;PUT OLD DISK NO. IN D&E.
  593.     MVI  D,0
  594.     LXI  H,TRTAB    ;GET ADDRESS OF TRACK TABLE.
  595.     DAD  D        ;ADD DISK NO. TO ADDRESS.
  596.     IN   TRACK    ;READ 1771 TRACK REGISTER.
  597.     MOV  M,A    ;PUT INTO TABLE.
  598.     MOV  A,C    ;GET NEW DISK NUMBER.
  599.  
  600.     IF   DUAL    ;IF A DUAL DRIVE,
  601.     ANI  0FEH    ;CLEAR BIT 0.
  602.     ENDIF
  603.  
  604.     MOV  E,A    ;PUT NEW DISK NO. IN D&E.
  605.     LXI  H,TRTAB    ;GET ADDRESS OF TRACK TABLE.
  606.     DAD  D        ;ADD DISK NO. TO ADDRESS.
  607.     MOV  A,M    ;GET NEW TRACK NUMBER.
  608.     OUT  TRACK    ;PUT INTO 1771 TRACK REG.
  609.     MOV  A,C    ;UPDATE OLD DISK NUMBER.
  610.     STA  DISKNO
  611.     CMA        ;BITS INVERTED INTO LATCH.
  612.     ADD  A        ;PUT BITS 1&2 AT 4&5.
  613.     ADD  A
  614.     ADD  A
  615.     ADD  A
  616.     ORI  2        ;MAKE LATCH COMMAND.
  617. DSK1:    OUT  DCONT    ;SET THE LATCH WITH CODE.
  618.          XRA  A        ;SET A = 0.
  619.          RET        ;RETURN FROM SELDSK.
  620. ;
  621. ; SET TRACK NUMBER TO WHATEVER IS IN REGISTER C.
  622. ; ALSO PERFORM MOVE TO THE CORRECT TRACK (SEEK).
  623. ;
  624. SETTRK:    MOV  A,C    ;GET NEW TRACK NUMBER.
  625.     STA  TRK    ;UPDATE OLD WITH NEW.
  626.     CALL SEEK    ;MOVE TO NEW TRACK.
  627.     RET        ;RETURN FROM SETTRK ROUTINE.
  628. ;
  629. ; SET DISK SECTOR NUMBER.
  630. ;
  631. SETSEC:  MOV  A,C    ;GET SECTOR NUMBER.
  632.          STA  SECT    ;PUT AT SECT # ADDRESS.
  633.          RET        ;RETURN FROM SETSEC.
  634. ;
  635. ; SET DISK DMA ADDRESS.
  636. ;
  637. SETDMA:  MOV  H,B    ;MOVE B&C TO H&L.
  638.          MOV  L,C
  639.          SHLD DMAADD    ;PUT AT DMA ADR ADDRESS.
  640.          RET        ;RETURN FROM SETDMA.
  641. ;
  642. ; READ A SECTOR WITHOUT LOADING HEAD FIRST.
  643. ;
  644. READ2:    OUT  SECTP    ;SET SECTOR NUMBER INTO 1771.
  645.     MVI  A,88H    ;GET CODE FOR READ W/O HLD.
  646.     JMP  READE    ;READ A SECTOR.
  647. ;
  648. ; READ THE SECTOR AT SECT, FROM THE PRESENT TRACK.
  649. ; USE STARTING ADDRESS AT DMAADD.
  650. ;
  651. READ:    MVI  A,RTCNT    ;GET RETRY COUNT.
  652. RRETRY:    STA  ERCNT    ;STORE IN ERROR CTR.
  653.     LHLD DMAADD    ;GET STARTING ADR.
  654.     MVI  A,0D0H    ;CAUSE INTERRUPT.
  655.     OUT  DCOM
  656.     XTHL        ;SOME DELAY.
  657.     XTHL
  658.  
  659.     IF  INTRP    ;IF INTERRUPTS ALLOWED,
  660.     DI        ;DISABLE THEM HERE.
  661.     ENDIF
  662.  
  663.     IN   DSTAT    ;READ STATUS.
  664.     ANI  20H    ;LOOK AT HLD BIT.
  665.     LDA  SECT    ;GET SECTOR NUMBER.
  666. READ1:    OUT  SECTP    ;SET SECTOR INTO 1771.
  667.     MVI  A,8CH    ;READ WITH HEAD LOAD
  668.     JZ   READE    ;HEAD NOT LOADED.
  669.     MVI  A,88H    ;CODE FOR READ W/O HD LD.
  670. READE:    OUT  DCOM    ;SEND COMMAND TO 1771.
  671. RLOOP:    IN   WAIT    ;WAIT FOR DRQ OR INTRQ.
  672.     ORA  A        ;SET FLAGS.
  673.     JP   RDDONE    ;DONE IF INTRQ.
  674.     IN   DDATA    ;READ A DATA BYTE FROM DISK.
  675.     MOV  M,A    ;PUT BYTE INTO MEMORY.
  676.     INX  H        ;INCREMENT MEMORY POINTER.
  677.     JMP  RLOOP    ;KEEP READING.
  678. RDDONE:    IN   DSTAT    ;READ DISK STATUS.
  679.  
  680.     IF  INTRP    ;IF INTERRUPTS ALLOWED,
  681.     EI        ;ALLOW AGAIN HERE.
  682.     ENDIF
  683.  
  684.     ANI  9DH    ;LOOK AT ERROR BITS.
  685.     RZ        ;RETURN IF NONE.
  686. CHECK:    CALL ERCHK    ;CHECK FOR SEEK ERROR.
  687.     LXI  H,RECNT    ;GET RD ERR COUNT ADDR.
  688.     INR  M        ;ONE MORE ERROR.
  689.     LDA  ERCNT    ;GET ERROR COUNT.
  690.     DCR  A        ;DECREMENT COUNT.
  691.     JNZ  RRETRY    ;TRY TO READ AGAIN.
  692.     LXI  H,RDMSG    ;PRINT "READ ".
  693. ERMSG:    CALL PMSG    ;PRINT ORIGIN MESSAGE.
  694. ERMSG1:
  695.  
  696.     IF NOT VDM    ;IF NOT PROC TECH VDM,
  697.     MOV  A,D    ;GET ERROR BITS.
  698.     ANI  80H    ;IF BIT 7 HIGH,
  699.     LXI  H,NRMSG    ;"NOT READY".
  700.     CNZ PMSG
  701.     MOV  A,D    ;GET ERROR BITS.
  702.     ANI  10H    ;IF BIT 4 IS HIGH,
  703.     LXI  H,RNMSG    ;PRINT "RECORD NOT FOUND"
  704.     CNZ PMSG
  705.     MOV  A,D    ;GET ERROR BITS.
  706.     ANI  8H        ;IF BIT 3 IS HIGH,
  707.     LXI  H,CRCMSG    ;PRINT "CRC ERROR".
  708.     CNZ PMSG
  709.     MOV  A,D    ;GET ERROR BITS.
  710.     ANI  4H        ;IF BIT 2 IS HIGH,
  711.     LXI  H,LDMSG    ;PRINT "LOST DATA".
  712.     CNZ PMSG
  713.     MOV  A,D    ;GET ERROR BITS.
  714.     ANI  1        ;IF BIT 1 IS HIGH,
  715.     LXI  H,BSYMSG    ;PRINT "BUSY".
  716.     CNZ  PMSG
  717.     ENDIF
  718.  
  719. PERMSG:    LXI  H,ERRMSG    ;PRINT "ERROR."
  720.     CALL PMSG
  721.     MVI  A,1    ;SET FOR PERM ERR MSG.
  722.     ORA  A        ;SET FLAGS.
  723.     RET
  724. ;
  725. ; ERCHK - CHECK FOR RECORD NOT FOUND ERROR.
  726. ;
  727. ERCHK:    MOV  D,A    ;SAVE ERROR BITS IN D.
  728.     ANI  10H    ;IF RECORD NOT FOUND,
  729.     JNZ  CHKSK    ;DO A CHECK ON SEEK.
  730.     MOV  A,D    ;OTHERWISE RESTORE BITS
  731.     ORA  A        ;SET FLAGS,
  732.     RET        ;AND RETURN.
  733. ;CHECK FOR SEEK TO CORRECT TRACK,
  734. ;AND CHANGE IF NECESSARY.
  735. CHKSK:    MVI  A,0C4H    ;SEND COMMAND TO 1771
  736.     OUT  DCOM    ;TO READ ADDRESS.
  737.     IN   WAIT    ;WAIT FOR DRQ OR INTRQ.
  738.     IN   DDATA    ;READ THE TRACK ADDRESS.
  739.     MOV  B,A    ;SAVE IN REGISTER B.
  740. CHKS2:    IN   WAIT    ;WAIT FOR INTRQ.
  741.     ORA  A        ;SET FLAGS.
  742.     JP   CHKS3    ;DONE WITH READ ADR OP.
  743.     IN   DDATA    ;READ ANOTHER BYTE.
  744.     JMP  CHKS2    ;DO IT AGAIN.
  745. CHKS3:    IN  DSTAT    ;READ DISK STATUS.
  746.     ORA  A        ;SET FLAGS.
  747.     JZ   CHKS4    ;READ ADR OK IF 0.
  748.     CALL HOME    ;OTHERWISE, HOME FIRST.
  749.     JMP  CHKS5
  750. CHKS4:    MOV  A,B    ;UPDATE TRACK REGISTER.
  751.     OUT  TRACK
  752. CHKS5:    LDA  TRK    ;GET REQUIRED TRACK NO.
  753.     CALL SEEK    ;MOVE THE HEAD TO IT.
  754.     MOV  A,D    ;GET ERROR BITS.
  755.     ORA  A        ;SET FLAGS.
  756.     RET        ;RETURN FROM ERCHK.
  757. ;
  758. ; WRITE THE SECTOR AT SECT, ON THE PRESENT TRACK.
  759. ; USE STARTING ADDRESS AT DMAADD.
  760. ;
  761. WRITE:    MVI  A,RTCNT    ;GET RETRY COUNT.
  762. WRETRY:    STA  ERCNT    ;STORE IN ERROR COUNTER.
  763.     LHLD DMAADD    ;GET STARTING ADR.
  764.     MVI  A,0D0H    ;STATUS INTERUPT FOR 1771.
  765.     OUT  DCOM    ;COMMAND 1771.
  766.     XTHL        ;WAIT FOR STATUS.
  767.     XTHL        ;CHANGE IT BACK.
  768.  
  769.     IF  INTRP    ;IF INTERRPUTS ALLOWED,
  770.     DI        ;DISABLE THEM HERE.
  771.     ENDIF
  772.  
  773.     IN   DSTAT    ;GET 1771 STATUS.
  774.     ANI  20H    ;CHECK FOR HEAD LOAD.
  775.     LDA  SECT    ;GET SECTOR NUMBER.
  776. WRITE1:    OUT  SECTP    ;SET THE SECTOR INTO 1771.
  777.     MVI  A,0ACH    ;SET UP 1771 FOR WRITE.
  778.     JZ   WRITE2    ;HEAD IS NOT LOADED.
  779.     MVI  A,0A8H    ;CODE FOR WRITE W/O HD LD.
  780. WRITE2:    OUT  DCOM
  781. WLOOP:    IN   WAIT    ;WAIT FOR READY.
  782.     ORA  A        ;SET FLAGS.
  783.     JP   WDONE    ;HOP OUT WHEN DONE.
  784.     MOV  A,M    ;GET BYTE FROM MEM.
  785.     OUT  DDATA    ;WRITE ONTO DISK.
  786.     INX  H        ;INCREMENT MEM PTR.
  787.     JMP  WLOOP    ;KEEP WRITING.
  788. WDONE:    IN   DSTAT    ;READ DISK STATUS.
  789.  
  790.     IF  INTRP    ;IF INTERRUPTS ALLOWED,
  791.     EI        ;ENABLE AGAIN HERE.
  792.     ENDIF
  793.  
  794.     ANI  0FDH    ;LOOK AT THESE BITS.
  795. PROCER:    RZ        ;RETURN IF NO ERR.
  796.     CALL ERCHK    ;CHECK/CORRECT SEEK ERR.
  797.     LXI  H,WECNT    ;GET ADR OF WRITE ERR CTR.
  798.     INR  M        ;ONE MORE WRITE ERROR.
  799.     LDA  ERCNT    ;GET ERROR COUNT.
  800.     DCR  A        ;DECREMENT COUNT.
  801.     JNZ  WRETRY    ;TRY TO WRITE AGAIN.
  802. WERR0:    LXI  H,WTMSG    ;PRINT "WRITE ".
  803.  
  804.     IF NOT VDM    ;IF NOT PROC TECH VDM,
  805.     CALL PMSG
  806.     MOV  A,D    ;GET ERROR BITS.
  807.     ANI  40H    ;LOOK AT BIT 6.
  808.     LXI  H,WPMSG    ;PRINT "PROTECT ".
  809.     CNZ  PMSG
  810.     MOV  A,D    ;GET ERROR BITS.
  811.     ANI  20H    ;LOOK AT BIT 5.
  812.     LXI  H,WFMSG    ;PRINT "FAULT ".
  813.     CNZ  PMSG
  814.     JMP  ERMSG1    ;DO COMMON MESSAGES.
  815.     ENDIF
  816.  
  817.     IF   VDM    ;IF PROC TECH VDM,
  818.     JMP  ERMSG
  819.     ENDIF
  820.  
  821. ;
  822. ; MOVE THE HEAD TO THE TRACK IN REGISTER A.
  823. ;
  824. SEEK:    PUSH B        ;SAVE B&C.
  825.     MOV  B,A    ;SAVE DESTINATION TRACK.
  826.     MVI  A,RTCNT    ;GET RETRY COUNT.
  827. SRETRY:    STA  SERCNT    ;STORE IN ERROR COUNTER.
  828.     IN   TRACK    ;READ PRESENT TRACK NO.
  829.     MOV  C,A    ;SAVE IN C.
  830.     MOV  A,C    ;DELAY.
  831.     CMP  B        ;SAME AS NEW TRACK NO.?
  832.     MOV  A,B    ;RESTORE A FROM B.
  833.     JNZ  NOTHR    ;JUMP IF NOT THERE.
  834. THERE:    POP  B        ;RESTORE B&C.
  835.     RET        ;RETURN FROM SEEK.
  836. NOTHR:
  837.  
  838.     IF NOT FAST    ;IF NOT FAST SEEK,
  839.     OUT  DDATA    ;TRACK TO DATA REGISTER.
  840. BUSY:    IN   DSTAT    ;READ DISK STATUS.
  841.     RRC        ;LOOK AT BIT 0.
  842.     JC   BUSY    ;WAIT TILL NOT BUSY.
  843.     MVI  A,12H    ;SET FOR 10 MS STEP.
  844.     ORI  4        ;VERIFY ON LAST TRACK.
  845.     OUT  DCOM    ;ISSUE SEEK COMMAND.
  846.     IN   WAIT    ;WAIT FOR INTRQ.
  847.     IN   DSTAT    ;READ STATUS.
  848.     ANI  91H    ;LOOK AT BITS.
  849.     JZ  THERE    ;OK IF ZERO.
  850.     ENDIF
  851.  
  852.     IF  FAST    ;IF FAST SEEK,
  853.     MVI  A,40H    ;IF CARRY = 1,
  854.     JC  SDIR    ;STEP IN.
  855.     MVI  A,60H    ;OTHERWISE, OUT.
  856. SDIR:    OUT  DCOM    ;ISSUE STEP DIRECTION.
  857.     MVI  A,20    ;DELAY LOOP COUNT.
  858. DLOOP:    DCR  A        ;DECREMENT COUNTER.
  859.     JNZ  DLOOP
  860.     MOV  A,C    ;GET PRESENT TRACK.
  861.     SUB  B        ;FIGURE TRACKS TO STEP.
  862.     JP   STEP    ;IF NEGATIVE,
  863.     CMA        ;FIGURE THE
  864.     INR  A        ;TWO'S COMPLEMENT.
  865. STEP:    MOV  C,A    ;GET DIFFERENCE.
  866.     MVI  A,1    ;PERSCI STEP COMMAND.
  867. STEP1:    OUT  DCONT    ;STEP PERSCI (E-14).
  868.     DCR  C        ;COUNT THE STEP.
  869.     JNZ  STEP1    ;STEP UNTIL C = 0.
  870.     IN   WAIT    ;CLEAR 1771.
  871.     IN   DSTAT
  872.     MOV  A,B    ;GET DEST. TRACK.
  873.     OUT  TRACK    ;UPDATE TRACK REG.
  874.     LDA  DISKNO    ;GET DISK NUMBER.
  875.     RLC!RLC!RLC!RLC    ;SHIFT LEFT 4 BITS.
  876.     ANI  10H    ;LOOK A BIT 4.
  877.     CMA        ;INVERT.
  878.     MOV  B,A    ;SAVE IN B.
  879.     ANI  72H    ;MAKE COMMAND TO
  880.     OUT  DCONT    ;SWITCH WAIT FOR
  881.     IN   WAIT    ;SEEK COMPLETE.
  882.     MOV  A,B    ;RESTORE ORIG. BITS.
  883.     ANI  0F2H    ;SWITCH WAIT BACK.
  884.     OUT  DCONT
  885.     XRA  A        ;MAKE GOOD RETURN.
  886.     POP  B        ;RESTOREE  B&C.
  887.     RET
  888.     ENDIF
  889.  
  890.     IF NOT FAST    ;IF NOT FAST SEEK,
  891.     PUSH H        ;SAVE H&L.
  892.     LXI  H,SECNT    ;GET ADR OF SEEK ERR CTR.
  893.     INR  M        ;ONE MORE SEEK ERROR.
  894.     POP  H        ;RESTORE H&L.
  895.     LDA  ERCNT    ;GET ERROR COUNT.
  896.     DCR  A        ;DECREMENT COUNT.
  897.     JNZ  SRETRY    ;RETRY SEK.
  898.     POP  B        ;RESTORE B&C.
  899.     LXI  H,SKMSG    ;PRINT "SEEK ".
  900.     IN   DSTAT    ;READ DISK STATUS.
  901.     ANI  91H    ;LOOK AT ERROR BITS.
  902.     MOV  D,A    ;PUT IN REG D.
  903.     JMP  ERMSG    ;DO COMMON ERR MESSAGES.
  904.     ENDIF
  905.  
  906. ;
  907. ; PRINT THE MESSAGE AT H&L UNTIL A ZERO.
  908. ;
  909. PMSG:    MOV  A,M    ;GET A CHARACTER.
  910.          ORA  A        ;IF IT'S ZERO,
  911.          RZ        ;RETURN.
  912.          MOV  C,A    ;OTHERWISE,
  913.          CALL CONOT    ;PRINT IT.
  914.          INX  H        ;INCREMENT H&L,
  915.          JMP  PMSG    ;AND GET ANOTHER.
  916. ;
  917. ; CBIOS MESSAGES
  918. ;
  919.  
  920.     IF NOT VDM    ;IF NOT PROC TECH VDM,
  921. NRMSG:    DB   'NOT READY ',0
  922. RNMSG:    DB   'RECORD NOT FOUND ',0
  923. CRCMSG:    DB   'CRC ',0
  924. LDMSG:    DB   'LOST DATA ',0
  925. BSYMSG:    DB   'BUSY ',0
  926. WPMSG:    DB   'PROTECT ',0
  927. WFMSG:    DB   'FAULT ',0
  928.     ENDIF
  929.  
  930. ERRMSG:    DB   'ERROR.',0
  931. RDMSG:    DB   0DH,0AH,'READ ',0
  932. WTMSG:    DB   0DH,0AH,'WRITE ',0
  933. BTMSG:    DB   'BOOT ERROR',0
  934. SKMSG:    DB   0DH,0AH,'SEEK ',0
  935. HEMSG:    DB   0DH,0AH,'HOME ',0
  936. MNTMSG:    DB   0DH,0AH,'MOUNT ',0
  937. SMSG:    DB   0DH,0AH,'TARBELL '
  938.     DB   MSIZE/10+'0',MSIZE MOD 10 + '0'
  939.     DB   'K CPM V1.4 OF 2-15-78'
  940.     DB   0DH,0AH
  941.  
  942.     IF  STD        ;IF STANDARD I/O,
  943.     DB   'STANDARD '
  944.     ENDIF
  945.  
  946.     IF  MSIO2    ;IF MITS 2SIO,
  947.     DB   '2SIO '
  948.     ENDIF
  949.  
  950.     IF  ISIO2    ;IF IMSAI SIO-2,
  951.     DB  'SIO-2 '
  952.     ENDIF
  953.  
  954.     IF  TUART    ;IF TUART,
  955.     DB  'TUART '
  956.     ENDIF
  957.  
  958.     IF   VDM    ;IF PROC TECH VDM,
  959.     DB   'VDM '
  960.     ENDIF
  961.  
  962.     IF  FAST    ;IF FAST SEEK,
  963.     DB  'FAST SEEK '
  964.     ENDIF
  965.  
  966.     IF  DUAL    ;IF DUAL DRIVE,
  967.     DB  'DUAL '
  968.     ENDIF
  969.  
  970.     DB  'VERSION.'
  971.     DB   0DH,0AH,'HOW MANY DISKS? ',0
  972. ;
  973. ; WRITE A CHARACTER ON LISTING DEVICE.
  974. ;
  975. LIST:
  976.     IF NOT VDM    ;IF NOT PROC TECH VDM,
  977.     MVI  A,0DH    ;IF IT'S A CR,
  978.     CMP  C        ;THEN HOP OUT TO
  979.     JZ   LINUL    ;NULL ROUTINE.
  980.     ENDIF
  981.  
  982. LIST1:    IN   LSTAT    ;READ LISTER STATUS.
  983.     ANI  LRBIT    ;LOOK AT READY BIT.
  984.  
  985.     IF   STD    ;IF STANDARD I/O,
  986.     JNZ  LIST1    ;READY WHEN LOW.
  987.     ENDIF
  988.  
  989.     IF   SIO2    ;IF MITS, IMSAI, CROM.,
  990.     JZ   LIST1    ;READY WHEN HIGH.
  991.     ENDIF
  992.  
  993.     IF  OTHER    ;IF ANYTHING ELSE,
  994.     JZ  LIST1    ;READY WHEN HIGH.
  995.     ENDIF
  996.  
  997.     MOV  A,C    ;GET DATA BYTE.
  998.     OUT  LDATA    ;PRINT IT.
  999.     RET        ;RETURN FROM LIST.
  1000.  
  1001.     IF NOT VDM    ;IF NOT PROC TECH VDM,
  1002. LINUL:    PUSH B        ;SAVE B&C.
  1003.     MVI  B,LNULL    ;GET NULL COUNT.
  1004. LINUL1:    CALL LIST1    ;PRINT (CR FIRST).
  1005.     MVI  C,0    ;GET NULL CHAR.
  1006.     DCR  B        ;DECREMENT COUNTER.
  1007.     JNZ  LINUL1    ;DO NEXT NULL.
  1008.     POP  B        ;RESTORE B&C.
  1009.     MOV  A,C    ;RESTORE A.
  1010.     RET        ;RETURN FROM LIST.
  1011.     ENDIF
  1012.  
  1013. ;
  1014. ; NORMALLY USED TO PUNCH PAPER TAPE, BUT IS
  1015. ; NICE FOR AN INFINITE BIT BUCKET TO CHECK FILES.
  1016. ;
  1017. PUNCH:
  1018.     IF NOT VDM    ;IF NOT PROC TECH VDM,
  1019.     NOP        ;SPACE FOR YOUR ROUTINE.
  1020.     NOP!NOP!NOP!NOP
  1021.     NOP!NOP!NOP!NOP
  1022.     NOP
  1023.     ENDIF
  1024.  
  1025.     RET        ;RETURN FROM PUNCH.
  1026. ;
  1027. ;  NORMALLY USED TO READ PAPER TAPE.
  1028. ; SET UP TO READ FROM CONSOLE IN STANDARD SYSTEM.
  1029. ;
  1030. READER:
  1031.     IF NOT VDM    ;IF NOT PROC TECH VDM,
  1032.     CALL CONIN    ;READ FROM CONSOLE.
  1033.     NOP!NOP!NOP!NOP    ;MORE SPACE FOR YOUR ROUTINE.
  1034.     NOP!NOP!NOP!NOP
  1035.     ENDIF
  1036.  
  1037.     RET        ;RETURN FROM READER.
  1038.  
  1039. ;NOTE:  AS THERE ARE ONLY NINE SECTORS
  1040. ;AVAILABLE FOR CBIOS ON THE SECOND SYSTEM TRACK (1),
  1041. ;THE LAST ADDRESS BEFORE THIS POINT SHOULD BE NO
  1042. ;GREATER THAN THE CBIOS STARTING ADDRESS + 047F (HEX).
  1043. ;THIS WILL NORMALLY BE XE7F (HEX).
  1044.  
  1045. ;
  1046. ; ERROR COUNTS.  THESE LOCATIONS KEEP TRACK OF THE
  1047. ; NUMBER OF ERRRS THAT OCCUR DURING READ, WRITE,
  1048. ; OR SEEK OPERATIONS.  THEY ARE INITIALIZED ONLY
  1049. ; WHEN A COLD-START IS PERFORMED BY THE BOOOTSTRAP.
  1050. ;
  1051. HECNT:    DB   0        ;HOME ERROR COUNT.
  1052. RECNT:    DB   0        ;READ ERROR COUNT.
  1053. WECNT:    DB   0        ;WRITE ERROR COUNT.
  1054. SECNT:    DB   0        ;SEEK ERROR COUNT.
  1055. ;
  1056. ; TRTAB - DISK TRACK TABLE - PRESENT POSITION OF
  1057. ;    HEADS FOR UP TO 4 DRIVES.
  1058. ;
  1059. TRTAB:    DS   4
  1060. ;
  1061. NODSKS:    DS   1        ;NUMBER OF DISKS.
  1062. ERCNT:    DS   1        ;ERROR COUNT FOR RETRIES.
  1063. SERCNT:    DS   1        ;SEEK RETRY COUNTER.
  1064. TEMP:    DS   1        ;TEMPORARY STORAGE.
  1065. TRK:    DS   1        ;CURRENTLY SELECTED TRACK.
  1066. SECT:    DS   1        ;CURRENTLY SELECTED SECTOR.
  1067. DMAADD:    DS   2        ;CURRENT READ/WRITE ADDRESS.
  1068. DISKNO:    DS   1        ;CURRENT DISK NUMBER.
  1069.          END
  1070.