home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / sigm / vols000 / vol041 / fdcbios.z80 < prev    next >
Text File  |  1984-04-29  |  15KB  |  747 lines

  1.     LIST    NOCOND,NOGEN
  2. ;
  3. ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  4. ;
  5. ;    modifications by Mike Goetz and Hank Kee - 9/2/81
  6. ;
  7. ;    corrected PIP A:=B:filename.ext on Persci 277/299
  8. ;        Persci's must be configured as A: and B:
  9. ;        and/or C: and D: since they have but one
  10. ;        arm to access two drives
  11. ;    modified sign-on message to properly generate size
  12. ;        from MEMSIZE definition during assembly
  13. ;    corrected current drive assignment on warm boot
  14. ;    inclusion of LIST serial driver for CCS 8250 (30 CPS)
  15. ;        option to support LA34/LA36
  16. ;
  17. ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  18. ;
  19. PERSCISW:    EQU    1        ;ONE IF PERSCI DRIVE
  20. LARGESW:    EQU    1 OR PERSCISW    ;ONE IF MAXI DRIVE
  21. NUMDRIVES:    EQU    2        ;ONE TO FOUR (MUST BE SAME TYPE)
  22. BIGIOSW:    EQU    1        ;ZERO IF NO LIST, NO PUNCH
  23. ;
  24. MEMSIZE:    EQU    64
  25. SERIAL:        EQU    1        ;SERIAL PRINTER OPTION W/8250
  26. MEMSTAT:    EQU    MEMSIZE-9    ;2400 HEX OFFSET
  27. BEGINADR:    EQU    MEMSTAT*1024    ;THIS IS THE START OF CPM
  28. MEMUNITS:    EQU    MEMSIZE-(MEMSIZE/10*10)
  29. MEMTENTH:    EQU    MEMSIZE/10
  30. ;
  31.     ORG    1600H+BEGINADR 
  32. ;
  33. ;    CROMEMCO 4FDC I/O ASSIGNMENTS
  34. ;
  35. CSTATPORT:    EQU    00H        ;3P + S, 4FDC, TU-UART, OR SCC
  36. CDATAPORT:    EQU    01H
  37. IMODEPORT:    EQU    02H        ;(3P + S DOESNT HAVE THESE)
  38. IMASKPORT:    EQU    03H
  39. PARLPORT:    EQU    04H        ;NOT USED
  40. ;
  41. STATPORT:    EQU    30H        ;4FDC OR CCS 2422 BOARD
  42. TRAKPORT:    EQU    31H
  43. SECTPORT:    EQU    32H
  44. DATAPORT:    EQU    33H
  45. FLAGPORT:    EQU    34H
  46. ;
  47. BANKPORT:    EQU    40H        ;MEMORY BANKING PORT
  48. ;
  49. ;    1771/179X EQUATES
  50. ;
  51. HEADLOAD:    EQU    08H
  52. VERIFY:        EQU    04H
  53. ;
  54.         IF    BIGIOSW = 1
  55. ;
  56. ;    OTHER DEFINITIONS (OPTIONAL)
  57. ;
  58. BAUDRATE:    EQU    01H        ;110 BAUD FOR READER ?
  59. RSTATPORT:    EQU    10H
  60. RBAUDPORT:    EQU    RSTATPORT    ;TU-UART BOARD FOR PAPER TAPE
  61. RDATAPORT:    EQU    RSTATPORT+1
  62. PSTATPORT:    EQU    10H
  63. PBAUDPORT:    EQU    PSTATPORT    ;PAPER TAPE PUNCH ALSO
  64. PDATAPORT:    EQU    PSTATPORT+1
  65. LSTATPORT:    EQU    54H        ;PARALLEL PRINTER POARD
  66. LDATAPORT:    EQU    LSTATPORT
  67.         ENDIF
  68.  
  69. TRUE:    EQU    -1
  70. FALSE:    EQU    0
  71. NULLS:    EQU    6        ; NUMBER OF NULLS AFTER LF
  72. LF:    EQU    0AH        ; LINE FEED
  73.  
  74. SDATA:    EQU    20H        ; DATA PORT
  75. SINTEN:    EQU    21H        ; INTERRUPT REGISTER
  76. SIDENT:    EQU    22H        ; INTERRUPT IDENTIFICATION
  77. SLCTRL:    EQU    23H        ; LINE CONTROL REGISTER
  78. SMDMCT:    EQU    24H        ; MODEM CONTROL REGISTER
  79. SLSTAT:    EQU    25H        ; LINE STATUS REGISTER
  80. SMDMST:    EQU    26H        ; MODEM STATUS REGISTER
  81. SSTATP:    EQU    25H        ; SERIAL PRINTER STATUS PORT (INPUT)
  82. STBE:    EQU    20H        ; SERIAL PRINTER TBE BIT
  83.  
  84.  
  85. ;
  86. ;    CPM ENTRY POINTS
  87. CPMB:        EQU    00H+BEGINADR
  88. BDOS:        EQU    806H+BEGINADR
  89. ;
  90. ;    JUMP VECTOR
  91.     JP    CBOOT
  92. EBOOT:
  93.     JP    WBOOT
  94.     JP    CONSTAT
  95.     JP    CONIN
  96.     JP    CONOUT
  97.     JP    LIST
  98.     JP    PUNCH
  99.     JP    READER
  100.     JP    HOME    
  101.     JP    SELDSK        
  102.     JP    SETTRK
  103.     JP    SETSEC
  104.     JP    SETDMA
  105.     JP    READ
  106.     JP    WRITE
  107.     JP    LISTAT
  108.     JP    SECTRAN
  109. ;
  110. ;    CP/M 2.2 DISK CONTROL BLOCKS
  111. ;
  112. DPBASE:
  113.     DW    XLT0,0000
  114.     DW    0000,0000
  115.     DW    DIRBUF,DPB0
  116.     DW    CSV0,ALV0
  117. ;
  118.     IF    NUMDRIVES > 1
  119.     DW    XLT0,0000
  120.     DW    0000,0000
  121.     DW    DIRBUF,DPB0
  122.     DW    CSV1,ALV1
  123.     ENDIF
  124. ;
  125.     IF    NUMDRIVES > 2
  126.     DW    XLT0,0000
  127.     DW    0000,0000
  128.     DW    DIRBUF,DPB0
  129.     DW    CSV2,ALV2
  130.     ENDIF
  131. ;
  132.     IF    NUMDRIVES > 3
  133.     DW    XLT0,0000
  134.     DW    0000,0000
  135.     DW    DIRBUF,DPB0
  136.     DW    CSV3,ALV3
  137.     ENDIF
  138. ;
  139. DPB0:
  140. ;
  141. ;    disk parameter block, common to all disks
  142. ;    this implements a "standard" CP/M directory
  143. ;    with 64 entries, and 1K blocks.
  144. ;
  145.     DW    18+LARGESW*8    ;sectors per track
  146.     DB    3        ;block shift factor
  147.     DB    7        ;block mask
  148.     DB    0        ;null mask
  149.     DW    81+LARGESW*161    ;disk size-1
  150.     DW    63        ;directory max
  151.     DB    192        ;alloc 0
  152.     DB    0        ;alloc 1
  153.     DW    16        ;check size
  154.     DW    3-LARGESW    ;track offset
  155. ;
  156. XLT0:
  157. ;
  158. ;    sector translate vector
  159. ;
  160.     IF    LARGESW EQ 0
  161.     DB    1,6,11,16    ;sectors 1,2,3,4
  162.     DB    3,8,13,18    ;sectors 5,6,7,8
  163.     DB    5,10,15,2    ;sectors 9,10,11,12
  164.     DB    7,12,17,4    ;sectors 13,14,15,16
  165.     DB    9,14        ;sectors 17,18
  166.     ENDIF
  167. ;
  168. ;
  169.     IF    LARGESW    EQ 1
  170.     DB    1,7,13,19    ;sectors 1,2,3,4
  171.     DB    25,5,11,17    ;sectors 5,6,7,8
  172.     DB    23,3,9,15    ;sectors 9,10,11,12
  173.     DB    21,2,8,14    ;sectors 13,14,15,16
  174.     DB    20,26,6,12    ;sectors 17,18,19,20
  175.     DB    18,24,4,10    ;sectors 21,22,23,24
  176.     DB    16,22        ;sectors 25,26
  177.     ENDIF
  178. ;
  179. ;
  180. SIGNON:
  181.     DEFB    26,13,10,10
  182.     DEFB    MEMTENTH+30H
  183.     DEFB    MEMUNITS+30H
  184.     DEFB    'k CP/M version 2.2'
  185.     DEFB    13,10,0
  186. ;
  187. SELDSK:    ;
  188.     LD    HL,0
  189.     LD    A,C        ;C CONTAINS REQUESTED DRIVE NO.
  190.     CP    NUMDRIVES
  191.     RET    NC        ;IGNORE IF TOO HIGH
  192.     LD    (DKNUMB),A
  193.     LD    L,C    ;L=disk number 0,1,2,3
  194.     ADD    HL,HL    ;*2
  195.     ADD    HL,HL    ;*4
  196.     ADD    HL,HL    ;*8
  197.     ADD    HL,HL    ;*16 (size of each header)
  198.     LD    DE,DPBASE
  199.     ADD    HL,DE    ;HL=.dpbase(diskno*16)
  200.     RET    
  201. ;
  202. SECTRAN:    ;TRANSLATE SECTOR IN C USING TABLE AT DE
  203.     LD    B,0
  204.     EX    DE,HL        ;TABLE ADDR TO HL
  205.     ADD    HL,BC        ;GET ADDRESS
  206.     LD    L,(HL)        ;GET BYTE
  207.     LD    H,0        ;ANSWER IN HL
  208.     RET
  209. ;
  210. SETSEC:
  211.     LD    A,C        ;JUST SAVE SECTOR NUMBER
  212.     LD    (DKSECT),A
  213.     RET
  214. ;
  215. SETDMA:
  216.     LD    (DKDMA),BC    ;JUST SAVE I/O ADDRESS
  217.     RET
  218. ;
  219. ;
  220. ;    ERROR CHECKING READ AND WRITE RTNS FOR
  221. ;    CROMEMCO CBIOS
  222. ;
  223. READ:
  224.     CALL    CLEAR
  225. RETRYREAD:
  226.     CALL    READ4FDC    ;READ SECTOR
  227.     RET    Z        ;SUCCESSFUL READ. RETURN
  228.     CALL    ERROR        ;INCREMENT RETRYCOUNT
  229.     JR    NZ,RETRYREAD    ;RETRY 20 TIMES
  230.     OR    01H        ;CP/M CONVENTION FOR PERMANENT ERROR
  231.     RET    
  232. ;
  233. CLEAR:
  234.     XOR    A
  235.     LD    (TRKERCNT),A    ;ZERO OUT TRACK ERROR COUNTER
  236.     LD    (RETRYCOUNT),A    ;ZERO OUT CRC ERROR COUNTER
  237.     RET    
  238. ;
  239. WRITE:
  240.     CALL    CLEAR
  241. RETRYWRITE:
  242.     CALL    WRIT4FDC    ;WRITE SECTOR
  243.     RET    Z        ;SUCCESSFUL WRITE. RETURN
  244.     CALL    ERROR        ;INCREMENT RETRYCOUNT
  245.     JR    NZ,RETRYWRITE    ;RETRY 20 TIMES
  246.     OR    01H        ;CP/M CONVENTION FOR PERMANENT ERROR
  247.     RET    
  248. ;
  249. ERROR:
  250.     PUSH    HL
  251.     AND    10H        ;CHECK FOR NRF
  252.     JR    NZ,TRACKERROR    
  253.     LD    HL,RETRYCOUNT
  254.     INC    (HL)        ;INCREMENT RETRYCOUNT
  255.     LD    A,(HL)
  256.     POP    HL
  257.     SUB    20        ;20 TRIES?
  258.     RET    
  259. ;
  260. TRACKERROR:
  261.     LD    HL,TRKERCNT
  262.     INC    (HL)        ;INCREMENT NO OF TRACK ERRORS
  263.     LD    A,(HL)
  264.     SUB    10D        ;ALLOW ONLY 10 TRACK ERRORS
  265.     POP    HL
  266.     RET    Z        ;IF >10, RETURN A FAILURE
  267.     PUSH    BC
  268.     CALL    HOME        ;HOME THE HEAD
  269.     LD    A,(DKTRACK)
  270.     LD    C,A        ;GET TRACK IN C
  271.     CALL    SETTRK        ;RESEEK TO CORRECT TRACK
  272.     POP    BC
  273.     OR    0FFH        ;RETRY
  274.     RET    
  275. ;
  276. ;    RESTORE THE DISK TO TRACK ZERO
  277. ;
  278. HOME:
  279.     SUB    A,A        ;ZERO OUT TRACK COUNTER
  280.     LD    (DKTRACK),A
  281.     CALL    DISKSELECT    ;NOW SELECT THE DISK
  282.     OUT    FLAGPORT,A
  283.     LD    A,02H+HEADLOAD+VERIFY    ;USE SLOW STEPPING SPEED FOR ALL DISKS
  284.     OUT    STATPORT,A
  285. RSTI:
  286.     IN    A,FLAGPORT    ;NOW CHECK STATUS
  287.     RRA
  288.     JR    NC,RSTI        ;LOOP BACK UNTIL DONE
  289.     JP    SEEKTEST
  290. ;
  291. ;    HERE, ACTUALLY DO THE READ OPERATION
  292. ;
  293. READ4FDC:
  294.     PUSH    BC
  295.     PUSH    HL        ;FIRST, SAVE REGS
  296.     PUSH    DE
  297.     LD    E,88H        ;READ COMMAND (VALID FOR 1771, 179X)
  298.     CALL    INIT4FDC
  299. RDI1:
  300.     IN    A,FLAGPORT    ;NOW CHECK FLAGS
  301.     RRA
  302.     JR    C,RDI3        ;IF PREMATURELY DONE, STOP
  303.     INI
  304.     JR    NZ,RDI1        ;READ ANOTHER BYTE INTO CORE UNTIL DONE
  305. RDI2:
  306.     IN    A,FLAGPORT    ;CHECK FLAGS
  307.     RRA
  308.     JR    NC,RDI2        ;LOOP UNTIL READY
  309. RDI3:
  310.     IN    A,STATPORT    ;NOW CHECK STATUS
  311.     AND    A,9CH
  312. RDWREND:
  313.     EI
  314.     POP    DE        ;RESTORE REGS
  315.     POP    HL
  316.     POP    BC
  317.     RET
  318. ;
  319. ;    ACTUALLY DO WRITE OPERATION
  320. ;
  321. WRIT4FDC:
  322.     PUSH    BC
  323.     PUSH    HL        ;SAVE REGS
  324.     PUSH    DE
  325.     LD    E,0A8H        ;WRITE COMMAND (VALID FOR 1771, 179X)
  326.     CALL    INIT4FDC
  327. WRI1:
  328.     IN    A,FLAGPORT    ;CHECK FLAGS
  329.     RRA
  330.     JR    C,WRI3        ;IF PREMATURELY DONE, STOP
  331.     OUTI
  332.     JR    NZ,WRI1        ;WRITE DATA FROM MEMORY TIL DONE
  333. WRI2:
  334.     IN    A,FLAGPORT    ;CHECK FLAGS
  335.     RRA
  336.     JR    NC,WRI2        ;LOOP TIL DONE WITH WHOLE OPERATION
  337. WRI3:
  338.     IN    A,STATPORT    ;NOW CHECK ERROR STATUS
  339.     AND    A,0FCH
  340.     JR    RDWREND
  341. ;
  342. ;    SET THE TRACK, AND MOVE DISK ARM THERE
  343. ;
  344. SETTRK:
  345.     LD    A,C
  346.     LD    (DKTRACK),A    ;STORE THE TRACK NUMBER
  347.     SUB    A,A
  348.     CALL    DISKSELECT    ;NOW SELECT THE DISK
  349.     OUT    FLAGPORT,A
  350.     LD    A,C
  351.     OUT    DATAPORT,A    ;TELL 1771 ABOUT TRACK WANTED
  352.     LD    A,(DKSECT)
  353.     OUT    SECTPORT,A    ;TELL IT ABOUT SECTOR WANTED
  354.     PUSH    HL
  355.     PUSH    DE
  356.     LD    HL,LOGINTAB    ;NOW, SEE WHERE DISK ARM IS NOW
  357.     LD    A,(DKNUMB)
  358.     LD    E,A        ;LOOK UP IN TABLE
  359.     LD    D,0
  360.     ADD    HL,DE        ;GET BYTE
  361.     LD    A,(HL)
  362.     OUT    TRAKPORT,A    ;TELL 1771 WHERE ARM IS NOW
  363.     LD    A,(HL)
  364.     SUB    A,C
  365.     POP    DE        ;NOW CAN RESTORE THE REGS
  366.     POP    HL
  367.     RET    Z        ;IF ALREADY AT THAT TRACK, QUIT
  368.     LD    A,12H-LARGESW*2+HEADLOAD+VERIFY
  369.     OUT    STATPORT,A    ;PERFORM THE SEEK THAT IS NEEDED
  370. SKI:
  371.     IN    A,FLAGPORT    ;CHECK FLAGS
  372.     RRA
  373.     JR    NC,SKI        ;LOOP UNITL OPERATION DONE
  374. SEEKTEST:
  375.     IN    A,STATPORT    ;NOW CHECK ERROR STATUS
  376.     AND    A,98H
  377.     RET    NZ        ;ZERO IS ALL OK
  378.     PUSH    DE
  379.     LD    D,0        ;UPDATE TRACK TABLE
  380.     LD    A,(DKNUMB)
  381.     LD    E,A        ;WITH NEW POSITION
  382. ;
  383.     IF    PERSCISW = 1
  384.     CALL    ADDSHIFT    ;PERSCI DRIVES HAVE ONLY ONE ARM
  385.     LD    A,E
  386.     XOR    1
  387.     LD    E,A
  388.     CALL    ADDSHIFT
  389.     POP    DE
  390.     RET
  391.     ENDIF
  392. ;
  393. ADDSHIFT:            ;IF NOT PERSCI, FALL THRU HERE
  394.     PUSH    HL
  395.     LD    HL,LOGINTAB    ;GET CORRECT ADDRESS OF DISK
  396.     ADD    HL,DE
  397.     LD    A,(DKTRACK)    ;AND GET CURRENT TRACK NUMBER
  398.     LD    (HL),A
  399.     SUB    A,A        ;PUT IT IN
  400.     POP    HL
  401.     IF    PERSCISW = 0
  402.     POP    DE        ;AND MISC CLEANUP
  403.     ENDIF
  404.     RET
  405. ;
  406. ;    INITIALIZE THE 4FDC, BY SELECTING THE DISK AND
  407. ;    TURNING ON THE DISK MOTORS, AND INITIALIZE THE
  408. ;    REGISTERS FOR THE I/O OPERATION
  409. ;
  410. INIT4FDC:
  411.     LD    A,80H        ;FIRST, SELECT THE DISK
  412.     CALL    DISKSELECT
  413.     LD    HL,(DKDMA)    ;INITIALIZE HL AND BC REGS FOR I/O
  414.     LD    BC,8000H+DATAPORT    ;80H IS 128 BYTE SECTORS
  415.     LD    D,A        ;SAVE THE A REG
  416.     DI            ;DISABLE INTERRUPTS
  417.     LD    A,(DKSECT)
  418.     OUT    SECTPORT,A    ;SET THE SECTOR WANTED
  419.     IN    A,FLAGPORT
  420.     CPL            ;SEE IF HEAD IS LOADED
  421.     AND    A,20H
  422.     JR    Z,IN0
  423.     LD    A,04        ;THIS IS THE HEAD LOAD BIT
  424. IN0:
  425.     ADD    A,E        ;ADD HEAD LOAD BIT TO COMMAND
  426.     LD    E,A
  427.     LD    A,D        ;RESTORE THE A REG
  428.     OUT    FLAGPORT,A
  429.     LD    A,E
  430.     OUT    STATPORT,A    ;OUTPUT THE COMMAND
  431.     RET
  432. ;
  433. ;    FIGURE OUT WHICH DISK TO SELECT AND PUT BIT THERE
  434. ;
  435. DISKSELECT:
  436.     PUSH    BC        ;FIRST, SAVE THIS, ITS NEEDED
  437.     LD    C,A
  438.     LD    A,(DKNUMB)    ;GET DISK NUMBER 0-3
  439.     LD    B,A
  440.     INC    B        ;ADD ONE
  441.     SUB    A,A
  442.     SCF            ;SET A BIT IN TO BE SHIFTED
  443. SHIFTBIT:
  444.     RLA            ;NOW, ROTATE BITS OVER
  445.     DJNZ    SHIFTBIT
  446.     LD    B,A        ;SAVE THE NEW VALUE
  447.     XOR    A
  448.     OR    A,20H+LARGESW*10H ;CONDITION 4FDC FOR MOTOR ON AND MAXI
  449.     OR    A,B
  450.     OR    A,C        ;OR IN DRIVE SELECT AND COMMAND WANTED
  451.     POP    BC
  452.     RET
  453. ;
  454. ;    GETS CONTROL ON A WARM START
  455. ;
  456. WBOOT:
  457.     LD    A,01H        ;FIRST, RESTORE DEFAULT BANKING
  458.     OUT    BANKPORT,A
  459. ;
  460.     LD    SP,80H
  461.     LD    A,(DKNUMB)
  462.     LD    (CURRDRIVE),A    ;STORE SELECTED DRIVE
  463. ;
  464. STARTBOOT:
  465.     LD    C,0
  466.     CALL    SELDSK        ;SELECT DRIVE A TO REBOOT
  467.     CALL    HOME
  468.     LD    HL,CPMB-128    ;WILL INCREMENT BY 128 LATER
  469.     LD    (DKDMA),HL
  470.     LD    BC,44*256+1    ;SECTOR COUNT, FIRST SECTOR-1
  471. RDSEC:
  472.     LD    A,C        ;C IS SECTOR NUMBER
  473.     CP    18+LARGESW*8
  474.     JR    Z,NXTTRK
  475.     LD    DE,128        ;INCREMENT DMA ADDRESS
  476.     LD    HL,(DKDMA)
  477.     ADD    HL,DE
  478.     LD    (DKDMA),HL    ;STORE DMA ADDRESS
  479.     INC    C        ;INCREMENT SECTOR NUMBER
  480.     CALL    SETSEC
  481.     CALL    READ        ;READ THE DATA
  482.     JR    NZ,WBOOT    ;ON READ FAILURE TRY AGAIN
  483.     DJNZ    RDSEC
  484.     JR    BOOT        ;READ CCP AND BDOS;
  485. NXTTRK:
  486.     LD    A,(DKTRACK)
  487.     CP    2-LARGESW
  488.     JR    Z,BOOT        ;STOP AT TRACK 2
  489.     LD    C,A
  490.     INC    C        ;SEEK NEXT TRACK IF NOT
  491.     CALL    SETTRK
  492.     LD    C,0
  493.     JR    RDSEC
  494. ;
  495. ;
  496. CBOOT:    ;AFTER COLD BOOT
  497.     LD    SP,80H        ;INITIALIZE STACK FOR ROUTINE
  498.     LD    HL,SIGNON
  499.     CALL    PRMSG        ;PRINT MESSAGE
  500. BOOT:    ;GETS CONTROL AFTER COLD OR WARM BOOT
  501.     DI    
  502.     LD    A,0C3H        ;SET UP PARAMETERS ON PAGE 0
  503.     LD    (0),A
  504.     LD    HL,EBOOT
  505.     LD    (1),HL
  506.     LD    (7*8+1),HL
  507.     LD    (5),A
  508.     LD    HL,BDOS
  509.     LD    (6),HL
  510. ;
  511. ;        CROMEMCO INITIALIZATION HERE (READER, LIST NOT NEEDED)
  512. ;        NOTE .. THE CONSOLE TUART IS INITIALIZED BY RDOS
  513. ;
  514.     IF    BIGIOSW = 1
  515.     LD    A,BAUDRATE
  516.     OUT    PBAUDPORT,A
  517.     ENDIF
  518. ;
  519.     IF    SERIAL = 1
  520.     CALL    L2INIT
  521.     ENDIF
  522. ;
  523.     LD    BC,80H        ;SET DEFAULT DMA ADDR
  524.     CALL    SETDMA
  525. ;
  526.     LD    A,(CURRDRIVE)    ;RESELECT THE DRIVE THAT WAS ACTIVE
  527.     LD    C,A        ;  BEFORE THE WARM START
  528.     EI    
  529.     JP    CPMB
  530. ;
  531. ;
  532. ERRMSG:
  533.     DEFB    13,10,'?? ERROR ??',13,10,0
  534. ;
  535. PRMSG:    ;PRINT MESSAGE AT H,L UNTIL 0
  536.     LD    A,(HL)
  537.     OR    A        ;ZERO?
  538.     RET    Z
  539.     LD    C,A        ;GO PRINT CHAR
  540.     CALL    CONOUT
  541.     INC    HL        ;GET NEXT CHAR
  542.     JR    PRMSG
  543. ;
  544. ;
  545. ;HARDWARE UART CONSOLE ROUTINES
  546. ;
  547. CONSTAT:
  548.     IN    A,CSTATPORT    ;CHECK CONSOLE STATUS
  549.     AND    40H
  550.     RET    Z        ;ZERO MEANS NO INPUT BYTE READY
  551.     LD    A,0FFH
  552.     RET            ;FF MEANS INPUT
  553. ;
  554. CONIN:
  555.     CALL    CONSTAT        ;CHECK STATUS TIL GOT A BYTE
  556.     JR    Z,CONIN
  557.     IN    A,CDATAPORT    ;READ THE BYTE AND KILL OFF 80H
  558.     AND    7FH
  559. ;
  560. ;    THE FOLLOWING CODE REPLACES THE DEL KEY WITH A CTRL-U,
  561. ;    SO THAT DEL MEANS LINE DELETE. USE BACKSPACE TO DELETE
  562. ;    A SINGLE CHARACTER.
  563. ;
  564. ;    CP    127    ; DEL
  565. ;    RET    NZ
  566. ;    SUB    127-21    ; CTRL-U
  567.     RET    
  568. ;
  569. ;    CONSOLE OUTPUT ROUTINE
  570. ;
  571. CONOUT:
  572.     IN    A,CSTATPORT    ;FIRST, LOOP UNITL TRANSMITTER BUFFER
  573.     AND    80H        ;IS EMPTY
  574.     JR    Z,CONOUT
  575.     LD    A,C        ;NOW, OUTPUT CHARACTER TO CONSOLE
  576.     OUT    CDATAPORT,A
  577.     RET    
  578. ;
  579. ;    LIST STATUS CHECK FOR CP/M 2.2
  580. ;
  581. LISTAT:
  582.     IF    BIGIOSW = 1
  583.     IN    A,LSTATPORT    ;IF LIST TRANSMITTER IS BUSY,
  584.     CPL            ;THEN RETURN WITH ZERO
  585.     AND    20H
  586.     RET    Z
  587.     OR    A,0FFH        ;LIST TRANSMITTER BUFFER IS EMPTY
  588.     RET
  589.     ENDIF
  590. ;
  591. LIST:
  592.     IF BIGIOSW = 1 AND SERIAL = 0
  593.     CALL    LISTAT        ;CHECK IF PRINTER BUSY
  594.     JR    Z,LIST
  595.     LD    A,C        ;NOW OUTPUT CHARACTER
  596.     SET    7,A
  597.     OUT    LDATAPORT,A    ;WITH HIGH STROBE
  598.     RES    7,A
  599.     OUT    LDATAPORT,A    ;NOW LOW STROBE
  600.     SET    7,A
  601.     OUT    LDATAPORT,A    ;NOW HIGH STROBE AGAIN
  602.     RET
  603.     ENDIF
  604. ;
  605.     IF    SERIAL = 1
  606.     LD    A,C
  607.     JP    L2OUT
  608.     ENDIF
  609. ;
  610. PUNCH:
  611.     IF    BIGIOSW = 1
  612.     IN    A,PSTATPORT    ;CHECK IF PUNCH BUFFER EMPTY
  613.     AND    80H
  614.     JR    Z,PUNCH        ;LOOP UNTIL READY
  615.     LD    A,C
  616.     OUT    PDATAPORT,A    ;OUTPUT CHARACTER
  617.     RET
  618.     ENDIF
  619. ;
  620. READER:
  621.     IF    BIGIOSW = 1
  622.     IN    A,RSTATPORT    ;SEE IF READER BUFFER FULL
  623.     AND    40H
  624.     JR    Z,READER    ;LOOP UNTIL FULL
  625.     IN    A,RDATAPORT    ;AND READ IT
  626.     RET    
  627.     ENDIF
  628. ;
  629.     IF    BIGIOSW NE 1
  630.     XOR    A,A        ;DUMMY ROUTINE FOR LIST,PUNCH,READER
  631.     RET
  632.     ENDIF
  633.  
  634.  
  635. ;  Serial Printer Initialization Routine
  636.  
  637. L2INIT:    LD    A,0FH        ; SETUP THE 8250
  638.     OUT    SMDMCT,A    
  639.     LD    A,83H        ; SET DIVISOR REGISTER ACCESS
  640.     OUT    SLCTRL,A    
  641.     LD    A,80H        ; SET THE DIVISOR TO 384=300 BAUD
  642.     OUT    SDATA,A
  643.     LD    A,01H        ;
  644.     OUT    SINTEN,A    
  645.     LD    A,03H        ; SET DATA REGISTER ACCESS
  646.     OUT    SLCTRL,A    
  647.     LD    A,0H        ; DISABLE INTERRUPT
  648.     OUT    SINTEN,A    
  649.     OUT    SLSTAT,A    ; RESET ERROR FLAGS
  650.     RET
  651.  
  652.  
  653. ;  Get Serial Printer Output Status
  654. ;  Upon Exit:    A = -1 (FFH) and Z-flag is reset if ready for char.
  655. ;        A = 0 and Z-flag is set if not ready for character
  656.  
  657. L2RDY:    IN    A,SSTATP    ; GET LIST-OUT STATUS
  658.     AND    STBE        ; CHECK PRINTER TBE FLAG
  659.     RET    Z        ; PRINTER NOT READY FOR CHARACTER
  660.     LD    A,-1        ; PRINTER READY FOR CHARACTER
  661.     RET
  662.  
  663.  
  664. ;  Serial Printer Output Routine
  665. ;  Upon Entry:    A contains the character to be output
  666.  
  667. L2OUT:    PUSH    AF        ; SAVE CHARACTER FOR A MOMENT
  668. L2OT30:    CALL    L2RDY        ; GET LIST-OUT STATUS
  669.     JR    Z,L2OT30    ; ZERO MEANS PRINTER BUSY
  670.     POP    AF        ; RESTORE CHARACTER
  671.     OUT    SDATA,A        ; OUTPUT THE CHARACTER
  672.     CP    LF        ; CHECK FOR END OF LINE
  673.     RET    NZ        ; RETURN IF NOT LINE FEED CHARACTER
  674.     LD    A,NULLS+1    ; IF LF, GET NUMBER OF NULLS
  675. L2RTN:    DEC    A        ; CHECK FOR 0 NULLS AT TOP OF LOOP
  676.     RET    Z        ; RETURN IF ALL NULLS OUTPUT
  677.     PUSH    AF        ; SAVE NULLS COUNTER
  678.     SUB    A        ; PRINT A SINGLE NULL
  679.     CALL    L2OUT        ;    CHARACTER (RECURSIVE)
  680.     POP    AF        ; RESTORE NULLS COUNTER
  681.     JR    L2RTN        ; LOOP TO PRINT NEXT NULL
  682. ;
  683. DKNUMB:    EQU    4        ;THIS IS WHERE THE DISK NUMBER IS
  684. ;                ;KEPT IN NORMAL CP/M
  685. CURRDRIVE:
  686.     DB    0        ;THE SAVE AREA FOR THE DEFAULT DRIVE
  687. LOGINTAB:
  688.     DB    2-LARGESW,0,0,0        ;FOUR DRIVES MAX
  689. DKSECT:
  690.     DB    0        ;SECTOR NUMBER
  691. DKTRACK:
  692.     DB    0        ;TRACK NUMBER
  693. DKDMA:
  694.     DW    0        ;DMA ADDRESS
  695. TRKERCNT:
  696.     DB    0        ;NUMBER OF TRACK ERRORS
  697. RETRYCOUNT:
  698.     DB    0        ;NUMBER OF READ ERRORS
  699. ;
  700. ;    FROM HERE ON, THE AREAS ARE INITIALIZED BY CP/M AS NEEDED
  701. ;
  702. DIRBUF:
  703.     DS    128        ;SAVE AREA FOR DISK DIRECTORY OPERATIONS
  704. ;
  705. ;
  706. ALV0:
  707.     DS    32
  708. ;
  709.     IF    NUMDRIVES > 1
  710. ALV1:
  711.     DS    32
  712.     ENDIF
  713. ;
  714.     IF    NUMDRIVES > 2
  715. ALV2:
  716.     DS    32
  717.     ENDIF
  718. ;
  719.     IF    NUMDRIVES > 3
  720. ALV3:
  721.     DS    32
  722.     ENDIF
  723. ;
  724. CSV0:
  725.     DS    16
  726. ;
  727.     IF    NUMDRIVES > 1
  728. CSV1:
  729.     DS    16
  730.     ENDIF
  731. ;
  732.     IF    NUMDRIVES > 2
  733. CSV2:
  734.     DS    16
  735.     ENDIF
  736. ;
  737.     IF    NUMDRIVES > 3
  738. CSV3:
  739.     DS    16
  740.     ENDIF
  741. ;
  742.  
  743. ;  Note:  The last assembled byte of this module MUST NOT be a Define
  744. ;  Storage (DS or DEFS) pseudo-op to assure proper operation with CDOSGEN
  745.  
  746.     END
  747.