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 / CPM / ZCPR2 / DISKIO.AQM / DISKIO.ASM
Assembly Source File  |  2000-06-30  |  36KB  |  1,393 lines

  1. *****************************************************************
  2. *                                *
  3. *  SYSIO -- Standard Set of Redirectable I/O Drivers        *
  4. *    for ARIES-1 with ZCPR2 and CHBIOSZ            *
  5. *                                *
  6. *****************************************************************
  7. FALSE    EQU    0
  8. TRUE    EQU    NOT FALSE
  9. stksiz    equ    200    ;Limit of Caller's Stack
  10. cr    equ    0dh    ;<CR>
  11.  
  12.     MACLIB    CBIOSHDR
  13.  
  14. biosdma    equ    scratch    ;Location of DMA Address
  15.  
  16. *****************************************************************
  17. *                                *
  18. *  Disk Serial, MPU Serial, Quad I/O, and Modem Equates        *
  19. *                                *
  20. *****************************************************************
  21.  
  22. ;  Disk Serial -- Serial Channel on Disk Controller Board (DCE)
  23. ;    Baud Rate is set at 19,200 Baud in Hardware (DIP Switches)
  24. ustat    equ    0E3F9H    ;USART Status Address
  25. ostat    equ    8    ;Output Status Bit (TBE)
  26. istat    equ    4    ;Input Status Bit (RDA)
  27.  
  28. ;  MPU Serial -- Serial Channel on CCS Z80 MPU Board (DCE)
  29. mpubase    equ    20H    ;Base address of 8250 on CCS Z80 MPU Board
  30. mpudata    equ    mpubase        ;Data I/O Registers
  31. mpudll    equ    mpubase        ;Divisor Latch Low
  32. mpudlh    equ    mpubase+1    ;Divisor Latch High
  33. mpuier    equ    mpubase+1    ;Interrupt Enable Register
  34. mpulcr    equ    mpubase+3    ;Line Control Register
  35. mpupcr    equ    mpubase+4    ;Peripheral Control Register
  36. mpustat    equ    mpubase+5    ;Line Status Register
  37. mpupsr    equ    mpubase+6    ;Peripheral Status Register
  38.  
  39. ;  MPU Serial RDA and TBE
  40. mpurda    equ    1    ; Data Available Bit (RDA)
  41. mputbe    equ    40h    ; Transmit Buffer Empty Bit (TBE)
  42.  
  43. ;  MPU Serial Baud Rate Values
  44. bm00050    equ    2304    ;    50   Baud
  45. bm00075    equ    1536    ;    75   Baud
  46. bm00110    equ    1047    ;   110   Baud
  47. bm00134    equ    857    ;   134.5 Baud
  48. bm00150    equ    768    ;   150   Baud
  49. bm00300    equ    384    ;   300   Baud
  50. bm00600    equ    192    ;   600   Baud
  51. bm01200    equ    96    ;  1200   Baud
  52. bm01800    equ    64    ;  1800   Baud
  53. bm02000    equ    58    ;  2000   Baud
  54. bm02400    equ    48    ;  2400   Baud
  55. bm03600    equ    32    ;  3600   Baud
  56. bm04800    equ    24    ;  4800   Baud
  57. bm07200    equ    16    ;  7200   Baud
  58. bm09600    equ    12    ;  9600   Baud
  59. bm19200    equ    6    ; 19200   Baud
  60. bm38400    equ    3    ; 38400   Baud
  61. bm56000    equ    2    ; 56000   Baud
  62.  
  63. ;  MPU Serial Channel Baud Rate
  64. mpbrate    equ    bm19200    ; 19,200 Baud
  65.  
  66. ;  Quad I/O Ports
  67. qbase    equ    80h    ; Base address of Quad RS-232 I/O Board
  68. q0data    equ    qbase        ; USART 0 Data Port (DTE)
  69. q0stat    equ    qbase+1        ; USART 0 Status Port
  70. q1data    equ    qbase+2        ; USART 1 Data Port (DTE)
  71. q1stat    equ    qbase+3        ; USART 1 Status Port
  72. q2data    equ    qbase+4        ; USART 2 Data Port (DTE)
  73. q2stat    equ    qbase+5        ; USART 2 Status Port
  74. q3data    equ    qbase+6        ; USART 3 Data Port (DCE)
  75. q3stat    equ    qbase+7        ; USART 3 Status Port
  76. q0baud    equ    qbase+8        ; USART 0 Baud Rate Port
  77. q1baud    equ    qbase+9        ; USART 1 Baud Rate Port
  78. q2baud    equ    qbase+10    ; USART 2 Baud Rate Port
  79. q3baud    equ    qbase+11    ; USART 3 Baud Rate Port
  80.  
  81. ;  Quad I/O RDA and TBE
  82. qrda    equ    2    ; Read Data Available Bit (RDA)
  83. qtbe    equ    1    ; Transmit Buffer Empty Bit (TBE)
  84.  
  85. *************************************
  86. *  Equate Values for PMMI as Modem  *
  87. *************************************
  88. *  Modem Ports (Special -- 300 or 600 Baud for PMMI)
  89. *mods    equ    0E0H    ; Modem Status Byte
  90. *modd    equ    0E1H    ; Modem Data Byte
  91. *
  92. *  Modem RDA and TBE
  93. *mrda    equ    2    ; Read Data Available Bit (RDA)
  94. *mtbe    equ    1    ; Transmit Buffer Empty Bit (TBE)
  95. *************************************
  96.  
  97. ;  Modem Ports set to QUAD I/O Port 2
  98. mods    equ    q2stat    ; Modem Status Port
  99. modd    equ    q2data    ; Modem Data Port
  100.  
  101. ;  Modem RDA and TBE
  102. mrda    equ    qrda
  103. mtbe    equ    qtbe
  104.  
  105. ;  Baud Rate Values
  106. b00050    equ    0    ;    50   Baud
  107. b00075    equ    1    ;    75   Baud
  108. b00110    equ    2    ;   110   Baud
  109. b00134    equ    3    ;   134.5 Baud
  110. b00150    equ    4    ;   150   Baud
  111. b00300    equ    5    ;   300   Baud
  112. b00600    equ    6    ;   600   Baud
  113. b01200    equ    7    ;  1200   Baud
  114. b01800    equ    8    ;  1800   Baud
  115. b02000    equ    9    ;  2000   Baud
  116. b02400    equ    10    ;  2400   Baud
  117. b03600    equ    11    ;  3600   Baud
  118. b04800    equ    12    ;  4800   Baud
  119. b07200    equ    13    ;  7200   Baud
  120. b09600    equ    14    ;  9600   Baud
  121. b19200    equ    15    ; 19200   Baud
  122.  
  123.  
  124. *****************************************************************
  125. *                                *
  126. *  Baud Rates for Quad I/O Devices                *
  127. *                                *
  128. *****************************************************************
  129.  
  130. q0brate    equ    b09600    ;  9600 Baud for Intersystem
  131. q1brate    equ    b01200    ;  1200 Baud for Clock
  132. q2brate    equ    b00300    ;   300 Baud for Smartmodem
  133. q3brate    equ    b00300    ;   300 Baud for Printer
  134.  
  135.  
  136. *****************************************************************
  137. *                                *
  138. *  Miscellaneous Constants                    *
  139. *                                *
  140. *****************************************************************
  141. XON    equ    11h    ;X-ON
  142. XOFF    equ    13h    ;X-OFF
  143. djram    equ    0e400h    ;Base of DJ RAM
  144. djcin    equ    djram+3    ;DJ Console Input
  145. djcout    equ    djram+6    ;DJ Console Output
  146.  
  147. *****************************************************************
  148. *                                *
  149. * The following are the Z80 Macro Definitions which are used to    *
  150. * define the Z80 Mnemonics used to implement the Z80 instruction*
  151. * set extensions employed in CBIOSZ.                *
  152. *                                *
  153. *****************************************************************
  154. ;
  155. ; MACROS TO PROVIDE Z80 EXTENSIONS
  156. ;   MACROS INCLUDE:
  157. ;
  158. $-MACRO         ;FIRST TURN OFF THE EXPANSIONS
  159. ;
  160. ;    JR    - JUMP RELATIVE
  161. ;    JRC    - JUMP RELATIVE IF CARRY
  162. ;    JRNC    - JUMP RELATIVE IF NO CARRY
  163. ;    JRZ    - JUMP RELATIVE IF ZERO
  164. ;    JRNZ    - JUMP RELATIVE IF NO ZERO
  165. ;    DJNZ    - DECREMENT B AND JUMP RELATIVE IF NO ZERO
  166. ;    LDIR    - MOV @HL TO @DE FOR COUNT IN BC
  167. ;    LXXD    - LOAD DOUBLE REG DIRECT
  168. ;    SXXD    - STORE DOUBLE REG DIRECT
  169. ;
  170. ;
  171. ;
  172. ;    @GENDD MACRO USED FOR CHECKING AND GENERATING
  173. ;    8-BIT JUMP RELATIVE DISPLACEMENTS
  174. ;
  175. @GENDD    MACRO    ?DD    ;;USED FOR CHECKING RANGE OF 8-BIT DISPLACEMENTS
  176.     IF (?DD GT 7FH) AND (?DD LT 0FF80H)
  177.     DB    100H    ;Displacement Range Error on Jump Relative
  178.     ELSE
  179.     DB    ?DD
  180.     ENDIF
  181.     ENDM
  182. ;
  183. ; Z80 MACRO EXTENSIONS
  184. ;
  185. JR    MACRO    ?N
  186.     DB    18H
  187.     @GENDD    ?N-$-1
  188.     ENDM
  189. ;
  190. JRC    MACRO    ?N
  191.     DB    38H
  192.     @GENDD    ?N-$-1
  193.     ENDM
  194. ;
  195. JRNC    MACRO    ?N
  196.     DB    30H
  197.     @GENDD    ?N-$-1
  198.     ENDM
  199. ;
  200. JRZ    MACRO    ?N
  201.     DB    28H
  202.     @GENDD    ?N-$-1
  203.     ENDM
  204. ;
  205. JRNZ    MACRO    ?N
  206.     DB    20H
  207.     @GENDD    ?N-$-1
  208.     ENDM
  209. ;
  210. DJNZ    MACRO    ?N
  211.     DB    10H
  212.     @GENDD    ?N-$-1
  213.     ENDM
  214. ;
  215. LDIR    MACRO
  216.     DB    0EDH,0B0H
  217.     ENDM
  218. ;
  219. LDED    MACRO    ?N
  220.     DB    0EDH,05BH
  221.     DW    ?N
  222.     ENDM
  223. ;
  224. LBCD    MACRO    ?N
  225.     DB    0EDH,4BH
  226.     DW    ?N
  227.     ENDM
  228. ;
  229. SDED    MACRO    ?N
  230.     DB    0EDH,53H
  231.     DW    ?N
  232.     ENDM
  233. ;
  234. SBCD    MACRO    ?N
  235.     DB    0EDH,43H
  236.     DW    ?N
  237.     ENDM
  238. ;
  239. ; END OF Z80 MACRO EXTENSIONS
  240. ;
  241.  
  242.  
  243. *****************************************************************
  244. *                                *
  245. * Terminal driver routines. Iobyte is initialized by the cold    *
  246. * boot routine, to modify, change the "intioby" equate.    The    *
  247. * I/O routines that follow all work exactly the same way. Using    *
  248. * iobyte, they obtain the address to jump to in order to execute*
  249. * the desired function. There is a table with four entries for    *
  250. * each of the possible assignments for each device. To modify    *
  251. * the I/O routines for a different I/O configuration, just    *
  252. * change the entries in the tables.                *
  253. *                                *
  254. *****************************************************************
  255.  
  256.     org    iobase        ;Base Address of I/O Drivers
  257. offset    equ    100h-iobase    ;Offset for load via DDT or ZSID
  258.  
  259.     jmp    status        ;Internal Status Routine
  260.     jmp    select        ;Device Select Routine
  261.     jmp    namer        ;Device Name Routine
  262.  
  263.     jmp    tinit        ;Initialize Terminal
  264.  
  265.     jmp    const        ;Console Input Status
  266.     jmp    conin        ;Console Input Char
  267.     jmp    conout        ;Console Output Char
  268.  
  269.     jmp    list        ;List Output Char
  270.  
  271.     jmp    punch        ;Punch Output Char
  272.  
  273.     jmp    reader        ;Reader Input Char
  274.  
  275.     jmp    listst        ;List Output Status
  276.  
  277.     jmp    newio        ;New I/O Driver Installation Routine
  278.  
  279.     jmp    copen        ;Open CON: Disk File
  280.     jmp    cclose        ;Close CON: Disk File
  281.  
  282.     jmp    lopen        ;Open LST: Disk File
  283.     jmp    lclose        ;Close LST: Disk File
  284.  
  285.  
  286. *****************************************************************
  287. *                                *
  288. *  I/O Driver Support Specification Tables            *
  289. *                                *
  290. *****************************************************************
  291.  
  292. *
  293. * Device Counts
  294. *    First Byte is Number of Devices, 2nd Byte is Selected Device
  295. *
  296. cnttbl:
  297.     db    5,(intioby AND 7)        ;CON:
  298.     db    2,(intioby AND 08h) SHR 3    ;RDR:
  299.     db    2,(intioby AND 10h) SHR 4    ;PUN:
  300.     db    6,(intioby AND 0E0h) SHR 5    ;LST:
  301.  
  302. *
  303. * Configuration Table
  304. *    First Byte is Rotate Count, 2nd Byte is Mask
  305. *
  306. cfgtbl:
  307.     db    0,111$1$1$000b    ;No Rotate, Mask Out 3 LSB
  308.     db    3,111$1$0$111b    ;3 Rotates, Mask Out Bit 3
  309.     db    4,111$0$1$111b    ;4 Rotates, Mask Out Bit 4
  310.     db    5,000$1$1$111b    ;5 Rotates, Mask Out 3 MSB
  311.  
  312. *****************************************************************
  313. *                                *
  314. * status: return information on devices supported by this    *
  315. *    I/O Package.  On exit, HL points to a logical device    *
  316. *    table which is structured as follows:            *
  317. *        Device    Count Byte  Current Assignment Byte    *
  318. *        ------    ----------  -----------------------    *
  319. *         CON:         0            1        *
  320. *         RDR:         2            3        *
  321. *         PUN:         4            5        *
  322. *         LST:         6            7        *
  323. *                                *
  324. *    If error or no I/O support, return with Zero Flag Set.    *
  325. *    Also, if no error, A=Driver Module Number        *
  326. *                                *
  327. *****************************************************************
  328. status:
  329.     lxi    h,cnttbl    ;point to table
  330.     mvi    a,81H        ;Module 1 (SYSIO) with Disk Output
  331.     ora    a        ;Set Flags
  332.     ret
  333.  
  334.  
  335. *****************************************************************
  336. *                                *
  337. * select: select devices indicated by B and C.  B is the number    *
  338. *    of the logical device, where CON:=0, RDR:=1, PUN:=2,    *
  339. *    LST:=3, and C is the desired device (range 0 to dev-1).    *
  340. *    Return with Zero Flag Set if Error.            *
  341. *                                *
  342. *****************************************************************
  343. ranger:
  344.     lxi    h,cnttbl-2    ;check for error
  345.     inr    b    ;range of 1 to 4
  346.     mov    a,b    ;Value in A
  347.     cpi    5    ;B out of range?
  348.     jnc    rangerr
  349.     push    b    ;save params
  350. rang:
  351.     inx    h    ;pt to next
  352.     inx    h
  353.     djnz    rang
  354.     mov    b,m    ;get count in b
  355.     mov    a,c    ;get selected device number
  356.     cmp    b    ;compare (C must be less than B)
  357.     pop    b    ;get params
  358.     jrnc    rangerr    ;range error if C >= B
  359. rangok:
  360.     mvi    a,0ffh    ;OK
  361.     ora    a    ;set flags
  362.     ret
  363. rangerr:
  364.     xra    a    ;not OK
  365.     ret
  366. select:
  367.     call    ranger    ;check for range error
  368.     rz        ;abort if error
  369.     inx    h    ;pt to current entry number
  370.     mov    m,c    ;save selected number there
  371.     lxi    h,cfgtbl-2    ;pt to configuration table
  372. sel2:
  373.     inx    h    ;Pt to Entry in Configuration Table
  374.     inx    h
  375.     djnz    sel2
  376.     mov    b,m    ;Get Rotate Count
  377.     inx    h    ;Pt to Select Mask
  378.     mov    d,m    ;Get Select Mask
  379.     mov    a,b    ;Any Rotation to do?
  380.     ora    a
  381.     jz    sel4
  382.     mov    a,c    ;Get Selected Number
  383. sel3:
  384.     rlc        ;Rotate Left 1 Bit
  385.     djnz    sel3
  386.     mov    c,a    ;Place Bit Pattern Back in C
  387. sel4:
  388.     lda    iobyte    ;get I/O byte
  389.     ana    d    ;mask out old selection
  390.     ora    c    ;mask in new selection
  391.     sta    iobyte    ;put I/O byte
  392.     jr    rangok    ;range OK
  393.  
  394. *****************************************************************
  395. *                                *
  396. * namer: return text string of physical device.  Logical device    *
  397. *    number is in B and physical selection is in C.        *
  398. *    HL is returned pointing to the first character of the    *
  399. *    string.  The strings are structured to begin with a    *
  400. *    device name followed by a space and then a description    *
  401. *    string which is terminated by a binary 0.        *
  402. *                                *
  403. *    Return with Zero Flag Set if error.            *
  404. *                                *
  405. *****************************************************************
  406. namer:
  407.     call    ranger    ;check for range error
  408.     rz        ;return if so
  409.     lxi    h,namptbl-2    ;pt to name ptr table
  410.     call    namsel    ;select ptr table entry
  411.     mov    b,c    ;physical selection number in B now
  412.     inr    b    ;Add 1 for Initial Increment
  413.     call    namsel    ;point to string
  414.     jr    rangok    ;return with HL pointing and range OK
  415. ;
  416. ;  Select entry B in table pted to by HL; this entry is itself a pointer,
  417. ;  and return with it in HL
  418. ;
  419. namsel:
  420.     inx    h    ;pt to next entry
  421.     inx    h
  422.     djnz    namsel
  423.     mov    a,m    ;get low
  424.     inx    h
  425.     mov    h,m    ;get high
  426.     mov    l,a    ;HL now points to entry
  427.     ret
  428.  
  429. *****************************************************************
  430. *                                *
  431. * const: get the status for the currently assigned console.    *
  432. *     The I/O Byte is used to select the device.        *
  433. *                                *
  434. *****************************************************************
  435. const:
  436.     lxi    h,cstble    ;Beginning of jump table
  437. conmask:
  438.     lxi    d,cfgtbl    ;Pt to First Entry in Config Table
  439.     jr    seldev        ;Select correct jump
  440.  
  441. *****************************************************************
  442. *                                *
  443. * conin: input a character from the currently assigned console.    *
  444. *     The I/O Byte is used to select the device.        *
  445. *                                *
  446. *****************************************************************
  447. conin:
  448.     lxi    h,citble    ;Beginning of character input table
  449.     jr    conmask        ;Get Console Mask
  450.  
  451. *****************************************************************
  452. *                                *
  453. * conout: output the character in C to the currently assigned    *
  454. *      console.  The I/O Byte is used to select the device.    *
  455. *                                *
  456. *****************************************************************
  457. conout:
  458.     lxi    h,cotble    ;Beginning of the character out table
  459.     jr    conmask        ;Get Console Mask
  460.  
  461. *****************************************************************
  462. *                                *
  463. * csreader: get the status of the currently assigned reader.    *
  464. *        The I/O Byte is used to select the device.        *
  465. *                                *
  466. *****************************************************************
  467. csreadr:
  468.     lxi    h,csrtble    ;Beginning of reader status table
  469. rdrmask:
  470.     lxi    d,cfgtbl+2    ;Pt to 2nd Entry in Config Table
  471.     jr    seldev
  472.  
  473. *****************************************************************
  474. *                                *
  475. * reader: input a character from the currently assigned reader.    *
  476. *      The I/O Byte is used to select the device.        *
  477. *                                *
  478. *****************************************************************
  479. reader:
  480.     lxi    h,rtble        ;Beginning of reader input table
  481.     jr    rdrmask        ;Get the Mask and Go
  482.  
  483. *****************************************************************
  484. *                                *
  485. * Entry at seldev will form an offset into the table pointed    *
  486. * to by H&L and then pick up the address and jump there.    *
  487. * The configuration of the physical device assignments is    *
  488. * pointed to by D&E (cfgtbl entry).                *
  489. *                                *
  490. *****************************************************************
  491. seldev:
  492.     push    b        ;Save Possible Char in C
  493.     ldax    d        ;Get Rotate Count
  494.     mov    b,a        ;... in B
  495.     inx    d        ;Pt to Mask
  496.     ldax    d        ;Get Mask
  497.     cma            ;Flip Bits
  498.     mov    c,a        ;... in C
  499.     lda    iobyte        ;Get I/O Byte
  500.     ana    c        ;Mask Out Selection
  501.     inr    b        ;Increment Rotate Count
  502. seld1:
  503.     dcr    b        ;Count down
  504.     jrz    seld2
  505.     rrc            ;Rotate Right one Bit
  506.     jr    seld1
  507. seld2:
  508.     rlc            ;Double Number for Table Offset
  509.     mvi    d,0        ;Form offset
  510.     mov    e,a
  511.     dad    d        ;Add offset
  512.     mov    a,m        ;Pick up low byte
  513.     inx    h
  514.     mov    h,m        ;Pick up high byte
  515.     mov    l,a        ;Form address
  516.     pop    b        ;Get Possible Char in C
  517.     pchl            ;Go there !
  518.  
  519. *****************************************************************
  520. *                                *
  521. * punch: output char in C to the currently assigned punch    *
  522. *     device.  The I/O Byte is used to select the device.    *
  523. *                                *
  524. *****************************************************************
  525. punch:
  526.     lxi    h,ptble        ;Beginning of punch table
  527.     lxi    d,cfgtbl+4    ;Get Mask
  528.     jr    seldev        ;Select Device and Go
  529.  
  530. *****************************************************************
  531. *                                *
  532. * list: output char in C to the currently assigned list device.    *
  533. *    The I/O Byte is used to select the device.        *
  534. *                                *
  535. *****************************************************************
  536. list:
  537.     lxi    h,ltble        ;Beginning of the list device routines
  538. lstmask:
  539.     lxi    d,cfgtbl+6    ;Get Mask
  540.     jr    seldev        ;Select Device and Go
  541.  
  542. *****************************************************************
  543. *                                *
  544. * Listst: get the output status of the currently assigned list    *
  545. *      device.  The I/O Byte is used to select the device.    *
  546. *                                *
  547. *****************************************************************
  548. listst:
  549.     lxi    h,lstble    ;Beginning of the list device status
  550.     jr    lstmask        ;Mask and Go
  551.  
  552. *****************************************************************
  553. *                                *
  554. * If customizing I/O routines is being performed, the tables    *
  555. * below should be modified to reflect the changes. All I/O    *
  556. * devices are decoded out of iobyte and the jump is taken from    *
  557. * the following tables.                        *
  558. *                                *
  559. *****************************************************************
  560.  
  561. *
  562. * name text tables
  563. *
  564. namptbl:
  565.     dw    conname-2    ;CON:
  566.     dw    rdrname-2    ;RDR:
  567.     dw    punname-2    ;PUN:
  568.     dw    lstname-2    ;LST:
  569.  
  570. conname:
  571.     dw    namtty    ;TTY
  572.     dw    namcrt    ;CRT
  573.     dw    namusr    ;CRT and Modem in Parallel
  574.     dw    namusr1    ;CRT Input and CRT/Remote Computer Output
  575.     dw    namdsk1    ;CRT and Disk
  576.  
  577. lstname:
  578.     dw    namtty    ;TTY
  579.     dw    namcrt    ;CRT
  580.     dw    namrem    ;Remote Computer
  581.     dw    nammod    ;Modem
  582.     dw    namdsk2    ;TTY and Disk
  583.     dw    namdsk3    ;Disk
  584.  
  585. rdrname:
  586.     dw    nammod    ;Modem
  587.     dw    namclk    ;Clock
  588.  
  589. punname:
  590.     dw    nammod    ;Modem
  591.     dw    namclk    ;Clock
  592.  
  593. namdsk1:
  594.     db    'CRTDISK Televideo 950 CRT with Disk File Output',0
  595. namdsk2:
  596.     db    'TTYDISK Model 43 Printing Terminal with Disk File Output',0
  597. namdsk3:
  598.     db    'DISK Disk File Output Only',0
  599. namtty:
  600.     db    'TTY Model 43 Printing Terminal',0
  601. namcrt:
  602.     db    'CRT Televideo 950 CRT',0
  603. namusr:
  604.     db    'CRTMOD Televideo 950 CRT and Modem in Parallel',0
  605. namusr1:
  606.     db    'CRTREM Televideo 950 CRT Input and CRT/Remote Output',0
  607. namrem:
  608.     db    'REMOTE Remote Computer',0
  609. nammod:
  610.     db    'MODEM DC Hayes Smartmodem',0
  611. namclk:
  612.     db    'CLOCK DC Hayes Chronograph',0
  613.  
  614. *
  615. * console input table
  616. *
  617. citble:
  618.     dw    citty        ;Input from tty (000) 
  619.     dw    cicrt        ;Input from crt (001) 
  620.     dw    ciusr        ;Input from crt and modem (010) 
  621.     dw    cicrt        ;Input from crt (011)
  622.     dw    cicrt        ;Input from crt (100)
  623.  
  624. *
  625. * console output table
  626. *
  627. cotble:
  628.     dw    cotty        ;Output to tty (000) 
  629.     dw    cocrt        ;Output to crt (001)
  630.     dw    cousr        ;Output to crt and modem (010)
  631.     dw    cousr1        ;Output to crt and remote system (011) 
  632.     dw    codsk1        ;Output to crt and disk file (100)
  633.  
  634. *
  635. * list device table
  636. *
  637. ltble:
  638.     dw    cotty        ;Output to tty (000) 
  639.     dw    cocrt        ;Output to crt (001)
  640.     dw    corem        ;Output to remote system (010)
  641.     dw    comod        ;Output to modem (011)
  642.     dw    codsk2        ;Output to tty and disk file (100)
  643.     dw    codsk3        ;Output to disk file (101)
  644.  
  645. *
  646. * punch device table
  647. *
  648.  
  649. ptble:
  650.     dw    comod        ;Output to modem (0)
  651.     dw    coclk        ;Output to clock (1) 
  652.  
  653. *
  654. * reader device table
  655. *
  656. rtble:
  657.     dw    cimod        ;Input from modem (0)
  658.     dw    ciclk        ;Input from clock (1)
  659.  
  660. *
  661. * console status table
  662. *
  663. cstble:
  664.     dw    cstty        ;Status of tty (000)
  665.     dw    cscrt        ;Status from crt (001)
  666.     dw    csusr        ;Status from crt and modem (010)
  667.     dw    cscrt        ;Status from crt (011)
  668.     dw    cscrt        ;Status from crt (100)
  669.  
  670. *
  671. * status from reader device
  672. *
  673. csrtble:
  674.     dw    csmod        ;Status from modem (0)
  675.     dw    csclk        ;Status from clock (1)
  676.  
  677. *
  678. * Status from list device
  679. *
  680. lstble:
  681.     dw    costty        ;Status from tty (000)
  682.     dw    coscrt        ;Status from crt (001)
  683.     dw    cosrem        ;Status from remote system (010)
  684.     dw    cosmod        ;Status from modem (011)
  685.     dw    costty        ;Status from tty (100)
  686.     dw    ready        ;Status of disk file is always ready (101)
  687.  
  688.  
  689. *****************************************************************
  690. *                                *
  691. * Tinit can be modified for different I/O setups.        *
  692. *                                *
  693. *****************************************************************
  694. tinit:                ;Initialize the terminal routine
  695.  
  696. ;  Initialize I/O Byte
  697.     mvi    a,intioby    ;Initialize IOBYTE
  698.     sta    iobyte
  699.  
  700. ;  Initialize MPU Serial I/O Channel Characteristics and Baud Rate
  701.     mvi    a,10$00$00$11b    ;Access Divisor:
  702.                 ;  10 -- Set divisor latch, clear break
  703.                 ;  00 -- 0 parity bit, even parity (N/A)
  704.                 ;  00 -- disable parity, 1 stop bit
  705.                 ;  11 -- 8 Data Bits
  706.     out    mpulcr        ;To Line Control Register
  707.     lxi    h,mpbrate    ;HL = MPU Channel Baud Rate
  708.     mov    a,l        ;Set Low-Byte of Baud Rate
  709.     out    mpudll        ;To Divisor Latch Low
  710.     mov    a,h        ;Set High-Byte of Baud Rate
  711.     out    mpudlh        ;To Divisor Latch High
  712.     mvi    a,00$00$01$11b    ;Reset Divisor Access and Set Characteristics:
  713.                 ;  00 -- Clear divisor latch, clear break
  714.                 ;  00 -- 0 parity bit, even parity (N/A)
  715.                 ;  01 -- disable parity, 2 stop bits
  716.                 ;  11 -- 8 Data Bits
  717.     out    mpulcr        ;To Line Control Register
  718.     xra    a        ;A=0
  719.     out    mpuier        ;Disable All Interrupts in Interrupt Register
  720.     out    mpustat        ;Clear All Error Flags in Line Status Register
  721.     mvi    a,0000$1111b    ;3 Zeroes, No Loop, 1, Set RLSD, CTS, DSR
  722.     out    mpupcr        ;To Peripheral Control Register
  723.  
  724. ;  Initialize Quad I/O Channel Characteristics
  725.     mvi    a,10$11$01$11b    ;General-Purpose Reset:
  726.                 ;  10 -- 1 1/2 Stop Bits
  727.                 ;  11 -- Even Parity, Enable Parity
  728.                 ;  01 -- 6 Bits/Char
  729.                 ;  11 -- 64x Baud Rate
  730.     call    setquad        ;Set All 4 Quad I/O Ports
  731.     mvi    a,01$11$01$11b    ;General-Purpose Reset:
  732.                 ;  01 -- Disable Hunt, Internal Reset
  733.                 ;  11 -- RTS High, Error Reset
  734.                 ;  01 -- No Break, Enable RxRDY
  735.                 ;  11 -- NOT DTR High, Enable TxEN
  736.     call    setquad        ;Set All 4 Quad I/O Ports
  737.     mvi    a,11$00$11$10b    ;Characteristics Set for All:
  738.                 ;  11 -- 2 Stop Bits
  739.                 ;  00 -- No Parity
  740.                 ;  11 -- 8 Bits/Char
  741.                 ;  10 -- 16x Baud Rate
  742.     call    setquad        ;Set All 4 Quad I/O Ports
  743.     mvi    a,00$11$01$11b    ;Characteristics Set for All:
  744.                 ;  00 -- Disable Hunt, No Internal Reset
  745.                 ;  11 -- RTS High, Error Reset
  746.                 ;  01 -- No Break, Enable RxRDY
  747.                 ;  11 -- NOT DTR High, Enable TxEN
  748.     call    setquad        ;Set All 4 Quad I/O Ports
  749.  
  750. ;  Initialize Quad I/O Baud Rates
  751.     mvi    a,q0brate    ;Set USART 0 Baud Rate
  752.     out    q0baud
  753.     mvi    a,q1brate    ;Set USART 1 Baud Rate
  754.     out    q1baud
  755.     mvi    a,q2brate    ;Set USART 2 Baud Rate
  756.     out    q2baud
  757.     mvi    a,q3brate    ;Set USART 3 Baud Rate
  758.     out    q3baud
  759.  
  760. ;  Clear Garbage Char from CRT
  761.     call    cscrt        ;Gobble up unwanted char
  762.     ora    a        ;A=0 if none
  763.     cnz    cicrt        ;Grab character
  764.     ret
  765.  
  766. ;  Set All Quad I/O Control Ports
  767. setquad:
  768.     out    q0stat        ;USART 0
  769.     out    q1stat        ;USART 1
  770.     out    q2stat        ;USART 2
  771.     out    q3stat        ;USART 3
  772.     xthl            ;Long Delay
  773.     xthl
  774.     ret
  775.  
  776.  
  777. *****************************************************************
  778. *                                *
  779. *  NEWIO -- Set UC1: Device to the Device Drivers whose Jump    *
  780. *    Table is Pointed to by HL                *
  781. *                                *
  782. *  This Jump Table is structured as follows:            *
  783. *    JMP ISTAT    <-- Input Status (0=No Char, 0FFH=Char)    *
  784. *    JMP INPUT    <-- Input Character            *
  785. *    JMP OUTPUT    <-- Output Character in C        *
  786. *                                *
  787. *  The Base Address of this Jump Table (JBASE) is passed to    *
  788. *    NEWIO in the HL Register Pair.                *
  789. *                                *
  790. *****************************************************************
  791. newio:
  792.     shld    cstble+6    ;Set UC1: Input Status
  793.     lxi    d,3        ;Prepare for offset to next jump
  794.     dad    d        ;HL points to next jump
  795.     shld    citble+6    ;Set UC1: Input Character
  796.     dad    d        ;HL points to next jump
  797.     shld    cotble+6    ;Set UC1: Output Character
  798.     ret
  799.  
  800.  
  801. *****************************************************************
  802. *                                *
  803. *  Input Status, Input Character, and Output Character        *
  804. *    Subroutines for CP/M                    *
  805. *                                *
  806. *****************************************************************
  807. *                                *
  808. *  Input Status --                        *
  809. *    These routines return 0 in the A Register if no input    *
  810. * data is available, 0FFH if input data is available.        *
  811. *                                *
  812. *  Input Character --                        *
  813. *    These routines return the character (byte) in the A    *
  814. * Register.  MSB is masked off.                    *
  815. *                                *
  816. *  Output Character --                        *
  817. *    These routines output the character (byte) in the C    *
  818. * Register.                            *
  819. *                                *
  820. *****************************************************************
  821.  
  822. *****************************************************************
  823. *                                *
  824. *  CRT Input Status, Input Character, and Output Character    *
  825. *                                *
  826. *****************************************************************
  827.  
  828. cscrt    equ    $    ;CRT Input Status
  829.     lda    ustat    ;Get Status
  830.     cma        ;Inverted Logic
  831.     ani    istat    ;Mask for input status and fall thru to 'STAT'
  832.     jr    stat    ;Set Flags
  833.  
  834. coscrt    equ    $    ;CRT Output Status
  835.     lda    ustat    ;Get USART status
  836.     cma        ;Inverted Logic
  837.     ani    ostat    ;Mask for output status
  838.     jr    stat    ;Return
  839.  
  840. cicrt    equ    $    ;CRT Input
  841.     jmp    djcin    ;Get char
  842.  
  843. cocrt    equ    $    ;CRT Output
  844.     jmp    djcout    ;Put char
  845.  
  846. *****************************************************************
  847. *                                *
  848. *  Modem Input Status, Input Character, and Output Character    *
  849. *                                *
  850. *****************************************************************
  851.  
  852. csmod    equ    $    ;Modem Input Status
  853.     in    mods
  854.     ani    mrda    ;Data available?
  855.     jr    stat
  856.  
  857. cosmod    equ    $    ;Modem Output Status
  858.     in    mods    ;Get status
  859.     ani    mtbe    ;TBE?
  860.     jr    stat
  861.  
  862. cimod    equ    $    ;Modem Input Character
  863.     call    csmod    ;RDA? 
  864.     jrz    cimod
  865.     in    modd    ;Get data
  866.     ani    7fh    ;Mask
  867.     ret
  868.  
  869. comod    equ    $    ;Modem Output
  870.     call    cosmod    ;TBE?
  871.     jrz    comod
  872.     mov    a,c    ;Get char
  873.     out    modd    ;Put data
  874.     ret
  875.  
  876. *****************************************************************
  877. *                                *
  878. *  Clock Input Status, Input Character, and Output Character    *
  879. *                                *
  880. *****************************************************************
  881.  
  882. csclk    equ    $    ;TTY Input Status
  883.     in    q1stat    ;Get Status
  884.     ani    qrda    ;Data available?
  885.     jr    stat
  886.  
  887. cosclk    equ    $    ;TTY Output Status
  888.     in    q1stat    ;Get Status
  889.     ani    qtbe    ;TBE?
  890.     jr    stat
  891.  
  892. ciclk    equ    $    ;TTY Input Character
  893.     call    csclk    ;RDA?
  894.     jrz    ciclk
  895.     in    q1data    ;Get data
  896.     ani    7fh    ;Mask
  897.     ret
  898.  
  899. coclk    equ    $    ;TTY Output Character
  900.     call    cosclk    ;TBE?
  901.     jrz    coclk
  902.     mov    a,c    ;Get data
  903.     out    q1data    ;Put data
  904.     ret
  905.  
  906. *****************************************************************
  907. *                                *
  908. * This is a common return point to correctly set the return     *
  909. *    status flags; it is centrally located for the jump        *
  910. *    relative instructions                    *
  911. *                                *
  912. *****************************************************************
  913. stat:
  914.     rz        ;Nothing found
  915. ready:
  916.     mvi    a,0ffh    ;Set A for negative status
  917.     ret
  918.  
  919. *****************************************************************
  920. *                                *
  921. *  TTY Input Status, Input Character, and Output Character    *
  922. *                                *
  923. *****************************************************************
  924.  
  925. cstty    equ    $    ;TTY Input Status
  926.     in    q3stat    ;Get Status
  927.     ani    qrda    ;Data available?
  928.     jr    stat
  929.  
  930. costty    equ    $    ;TTY Output Status
  931.     in    q3stat    ;Get Status
  932.     ani    qtbe    ;TBE?
  933.     jr    stat
  934.  
  935. citty    equ    $    ;TTY Input Character
  936.     call    cstty    ;RDA?
  937.     jrz    citty
  938.     in    q3data    ;Get data
  939.     ani    7fh    ;Mask
  940.     ret
  941.  
  942. cotty    equ    $    ;TTY Output Character
  943.     call    costty    ;TBE?
  944.     jrz    cotty
  945.     mov    a,c    ;Get data
  946.     out    q3data    ;Put data
  947.     ret
  948.  
  949. *****************************************************************
  950. *                                *
  951. *  Remote System Input Status, Input Character, and Output    *
  952. *    Character                        *
  953. *                                *
  954. *****************************************************************
  955.  
  956. csrem    equ    $    ;TTY Input Status
  957.     in    q0stat    ;Get Status
  958.     ani    qrda    ;Data available?
  959.     jr    stat
  960.  
  961. cosrem    equ    $    ;TTY Output Status
  962.     in    q0stat    ;Get Status
  963.     ani    qtbe    ;TBE?
  964.     jr    stat
  965.  
  966. cirem    equ    $    ;TTY Input Character
  967.     call    csrem    ;RDA?
  968.     jrz    cirem
  969.     in    q0data    ;Get data
  970.     ani    7fh    ;Mask
  971.     ret
  972.  
  973. corem    equ    $    ;TTY Output Character
  974.     call    coxoff    ;Check for XOFF and process
  975.     call    cosrem    ;TBE?
  976.     jrz    corem
  977.     mov    a,c    ;Get data
  978.     out    q0data    ;Put data
  979.     ret
  980. coxoff    equ    $    ;Remote XOFF Check and Processing
  981.     call    csrem    ;Input Char from LST: Device?
  982.     rz        ;Zero if none
  983.     call    cirem    ;Get Char
  984.     cpi    XOFF    ;XOFF?
  985.     rnz        ;Return if not
  986.     call    cirem    ;Wait for Any Other Char
  987.     ret
  988.  
  989. *****************************************************************
  990. *                                *
  991. *  User-Defined (CRT and Modem) Input Status, Input Character,    *
  992. *    and Output Character                    *
  993. *                                *
  994. *****************************************************************
  995.  
  996. csusr    equ    $    ;User (CRT and Modem) Input Status
  997.     call    cscrt    ;Input from CRT?
  998.     rnz        ;Char found
  999.     call    csmod    ;Input from Modem?
  1000.     ret
  1001.  
  1002. cosusr    equ    cosmod    ;Output status same as modem since modem is slower
  1003.  
  1004. ciusr    equ    $    ;Modem/CRT Input Combination
  1005.     call    cscrt    ;Input from CRT?
  1006.     jnz    cicrt    ;Get char from CRT
  1007.     call    csmod    ;Input from Modem?
  1008.     jnz    cimod    ;Get char from Modem
  1009.     jr    ciusr    ;Continue
  1010.  
  1011. cousr    equ    $    ;Modem/CRT Output Combination
  1012.     call    comod    ;Output to Modem
  1013.     jmp    cocrt    ;Output to CRT
  1014.  
  1015. ciusr1    equ    $    ;Modem/CRT Input w/CRT Output Combination
  1016.     call    ciusr    ;Get char
  1017.     push    psw    ;Save char in A
  1018.     mov    c,a    ;Char in C
  1019.     call    cocrt    ;Output to CRT
  1020.     pop    psw    ;Restore char in A
  1021.     ret
  1022.  
  1023. cousr1    equ    $    ;Remote System/CRT Output Combination
  1024.     call    corem    ;Output to Remote System
  1025.     jmp    cocrt    ;Output to CRT
  1026.  
  1027.  
  1028. *****************************************************************
  1029. *                                *
  1030. *  Disk System Output Character                    *
  1031. *    CODSK1 - CRT and Disk                    *
  1032. *    CODSK2 - TTY and Disk                    *
  1033. *                                *
  1034. *****************************************************************
  1035.  
  1036. codsk1    equ    $    ;CRT and Disk Output Character
  1037.     call    cocrt    ;Send to CRT
  1038.     lxi    d,dsk1    ;Disk 1 Parameters
  1039.     lda    clast    ;Check last char for double <CR>
  1040.     cpi    cr
  1041.     jrz    codsk1a
  1042.     mov    a,c    ;Set new last char
  1043.     sta    clast
  1044.     jr    codsk    ;Output to Disk
  1045. codsk1a:
  1046.     mov    a,c    ;Is this a <CR> also?
  1047.     cpi    cr
  1048.     rz
  1049.     sta    clast    ;No, so set as new last and continue
  1050.     jr    codsk
  1051.  
  1052. codsk2    equ    $    ;TTY and Disk Output Character
  1053.     call    cotty    ;Send to TTY
  1054.     lxi    d,dsk2    ;Disk 2 Parameters
  1055.     lda    tlast    ;Check last char for double <CR>
  1056.     cpi    cr
  1057.     jrz    codsk2a
  1058.     mov    a,c    ;Set new last char
  1059.     sta    tlast
  1060.     jr    codsk    ;Output to Disk
  1061. codsk2a:
  1062.     mov    a,c    ;Is this a <CR> also?
  1063.     cpi    cr
  1064.     rz
  1065.     sta    tlast    ;No, so set as new last and continue
  1066.     jr    codsk
  1067.  
  1068. codsk3    equ    $    ;Disk Output as Printer
  1069.     lxi    d,dsk2    ;Disk 2 Parameters
  1070.  
  1071. codsk    equ    $    ;Disk Output Character
  1072.     ldax    d    ;Get Open Flag
  1073.     ora    a    ;File Open?
  1074.     rz        ;Done if Not
  1075.     lxi    h,0    ;Save User Stack
  1076.     dad    sp
  1077.     shld    stack
  1078.     lxi    sp,stack    ;Set Driver Stack
  1079.     push    b    ;Save char in C
  1080.     push    d    ;Save ptr to File Spec Block
  1081.     lxi    d,stksav    ;Save User's Stack in case I'm in the BDOS
  1082.     lxi    b,stksiz    ;Arbitrary
  1083.     ldir        ;Copy
  1084.     pop    h    ;Get HL as ptr to File Spec Block
  1085.     pop    b    ;Get char in C
  1086.     push    h    ;Save ptr to File Spec Block
  1087.     inx    h    ;Pt to Buffer Address
  1088.     mov    e,m    ;Get address
  1089.     inx    h
  1090.     mov    d,m
  1091.     xchg        ;HL pts to next location
  1092.     mov    m,c    ;Store Character
  1093.     inx    h    ;Pt to following location
  1094.     xchg        ;... in DE
  1095.     mov    m,d    ;Store New Address
  1096.     dcx    h
  1097.     mov    m,e
  1098.     inx    h    ;Pt to char count
  1099.     inx    h
  1100.     inr    m    ;Increment char count
  1101.     mvi    a,128    ;Buffer full?
  1102.     cmp    m    ;It is if 128 characters are stored in it
  1103.     pop    h    ;Get Ptr to File Spec Block
  1104.     jrnz    done    ;Done if less than 128
  1105.     call    initfsb    ;Init File Spec Block
  1106.     call    write    ;Write Block to Disk
  1107. done:
  1108.     lhld    stack    ;Restore User Stack
  1109.     sphl
  1110.     lxi    d,stksav    ;Pt to User's Original Stack
  1111.     xchg        ;HL is where user's stack once was
  1112.     lxi    b,stksiz    ;Size of my Stack Save Area
  1113.     ldir        ;Restore Original Stack
  1114.     ret
  1115. ;
  1116. ;  COPEN -- Open Console File for Output
  1117. ;  LOPEN -- Open Printer File for Output
  1118. ;
  1119. copen:
  1120.     lxi    d,fcb1    ;Define Console File
  1121.     lxi    b,12    ;12 bytes
  1122.     ldir        ;Copy
  1123.     lxi    h,dsk1    ;Pt to File Spec Block
  1124.     xra    a    ;Set No Last Char
  1125.     sta    clast
  1126.     jr    open
  1127. lopen:
  1128.     lxi    d,fcb2    ;Define Printer File
  1129.     lxi    b,12    ;12 bytes
  1130.     ldir        ;Copy
  1131.     lxi    h,dsk2    ;Pt to File Spec Block
  1132.     xra    a    ;Set No Last Char
  1133.     sta    tlast
  1134. ;
  1135. ;  Open Disk File for Output
  1136. ;
  1137. open:
  1138.     push    h    ;Save ptr to File Spec Block
  1139.     call    savud    ;Save Current User and Disk as Home
  1140.     lda    disk    ;Set Home Base User and Disk
  1141.     sta    hdisk
  1142.     lda    user
  1143.     sta    huser
  1144.     call    initfsb    ;Init File Spec Block pted to by HL
  1145.     call    savenv    ;Save Environment
  1146.     call    initfcb    ;Clear FCB
  1147.     mvi    c,19    ;Delete File
  1148.     push    d    ;Save DE
  1149.     call    entry
  1150.     pop    d    ;Get DE
  1151.     call    initfcb
  1152.     mvi    c,22    ;Create File
  1153.     call    entry
  1154.     mvi    c,'M'    ;Make error possible
  1155.     call    errchk    ;Perform Error Check
  1156.     call    getenv    ;Restore Environment
  1157.     pop    h    ;Get Ptr to File Spec Block
  1158.     ret
  1159. ;
  1160. ;  Init File Spec Block pted to by HL
  1161. ;    On input, HL pts to File Spec Block
  1162. ;    On output, File Spec Block is initialized and HL pts to DMA Address
  1163. ;
  1164. initfsb:
  1165.     mvi    m,0ffh    ;Set File Open
  1166.     inx    h    ;Skip Buffer Address
  1167.     mov    d,h    ;DE=ptr to buffer address
  1168.     mov    e,l
  1169.     inx    h
  1170.     inx    h    ;Pt to Byte Count
  1171.     mvi    m,0    ;Init it to Zero
  1172.     inx    h    ;Pt to DMA Address
  1173.     mov    a,m    ;Set Buffer Address
  1174.     stax    d
  1175.     inx    h
  1176.     inx    d
  1177.     mov    a,m
  1178.     stax    d
  1179.     dcx    h    ;Pt to DMA Address
  1180.     ret
  1181. ;
  1182. ;  Close Disk Files
  1183. ;    CCLOSE -- CON file (DSK1)
  1184. ;    LCLOSE -- LST file (DSK2)
  1185. ;
  1186. cclose:
  1187.     lxi    h,dsk1    ;Pt to File Spec Block
  1188.     jr    close
  1189. lclose:
  1190.     lxi    h,dsk2    ;Pt to File Spec Block
  1191. close:
  1192.     push    h    ;Save ptr
  1193.     inx    h    ;Pt to Buffer Address
  1194.     mov    e,m    ;Get it
  1195.     inx    h
  1196.     mov    d,m
  1197.     inx    h    ;Pt to Byte Count
  1198.     mov    b,m    ;Get it
  1199.     xchg        ;HL pts to Buffer
  1200. close1:
  1201.     mvi    m,1AH    ;EOF Char
  1202.     inx    h
  1203.     inr    b    ;Buffer full?
  1204.     mvi    a,128    ;Check
  1205.     cmp    b
  1206.     jrnz    close1
  1207.     pop    h    ;Get ptr
  1208.     mvi    m,0    ;Set Not Open
  1209.     inx    h    ;Pt to DMA Address
  1210.     inx    h
  1211.     inx    h
  1212.     inx    h
  1213.     push    h    ;Save ptr
  1214.     call    write    ;Write Last Block
  1215.     pop    h    ;Get ptr
  1216.     call    savenv    ;Save User Environment
  1217.     mvi    c,16    ;Close Disk File
  1218.     call    entry
  1219.     mvi    c,'C'    ;Close error possible
  1220.     call    errchk    ;Perform error check
  1221.     jmp    getenv    ;Restore User Environment
  1222.  
  1223. ;
  1224. ;  Init FCB Pted to by DE and do not affect DE
  1225. ;
  1226. initfcb:
  1227.     push    d    ;Save Ptr
  1228.     xchg        ;Ptr in HL
  1229.     mvi    m,0    ;Clear Disk
  1230.     lxi    d,12    ;Pt to EX Field
  1231.     dad    d
  1232.     mvi    b,24    ;24 more bytes
  1233. ifcb:
  1234.     mvi    m,0    ;Zero Fill
  1235.     inx    h    ;Pt to Next
  1236.     djnz    ifcb
  1237.     pop    d    ;Get Ptr
  1238.     ret
  1239.  
  1240. ;
  1241. ;  Write Block to File whose DMA Address is pointed to by HL
  1242. ;
  1243. write:
  1244.     call    savenv    ;Save Environment
  1245.     mvi    c,21    ;Write Block
  1246.     call    entry
  1247.     mvi    c,'W'    ;Write error possible
  1248.     call    errchk    ;Perform error check
  1249. ;
  1250. ;  Get User Environment
  1251. ;    This routine restores the User's User/Disk Flag and DMA Address
  1252. ;
  1253. getenv:
  1254.     call    getud    ;Reset User/Disk
  1255.     lhld    usrdma    ;Reset User's DMA Address
  1256.     xchg
  1257.     mvi    c,26    ;Set DMA
  1258.     call    entry
  1259.     ret
  1260. ;
  1261. ;  Save User Environment
  1262. ;    This routine saves his DMA Address and User/Disk Flag
  1263. ;    This routine sets the Disk I/O User/Disk Flag and DMA Address
  1264. ;       and returns with DE containing the address of the FCB
  1265. ;    On input, HL pts to DMA Address entry in File Spec Block
  1266. ;
  1267. savenv:
  1268.     call    savdma    ;Save User's DMA Address
  1269.     call    savud    ;Save Current User/Disk
  1270.     call    setfud    ;Set User/Disk for Output File
  1271.     mov    e,m
  1272.     inx    h
  1273.     mov    d,m
  1274.     inx    h    ;Pt to FCB
  1275.     push    h    ;Save ptr
  1276.     mvi    c,26    ;Set DMA
  1277.     call    entry
  1278.     pop    h    ;Get ptr
  1279.     mov    e,m    ;Get FCB Address in DE
  1280.     inx    h
  1281.     mov    d,m
  1282.     ret
  1283. ;
  1284. ;  Save Current User/Disk
  1285. ;
  1286. savud:
  1287.     push    h    ;Save Regs
  1288.     push    d
  1289.     push    b
  1290.     mvi    c,25    ;Get Disk
  1291.     call    entry
  1292.     sta    disk
  1293.     mvi    c,32    ;Get User
  1294.     mvi    e,0ffh
  1295.     call    entry
  1296.     sta    user
  1297. rexit:
  1298.     pop    b    ;Restore Regs
  1299.     pop    d
  1300.     pop    h
  1301.     ret
  1302. ;
  1303. ;  Restore Current User/Disk
  1304. ;
  1305. getud:
  1306.     push    h    ;Save Regs
  1307.     push    d
  1308.     push    b
  1309.     lda    disk    ;Select Disk
  1310.     mov    e,a
  1311.     mvi    c,14
  1312.     call    entry
  1313.     lda    user    ;Select User
  1314.     mov    e,a
  1315.     mvi    c,32
  1316.     call    entry
  1317.     jr    rexit    ;Exit and Restore Regs
  1318. ;
  1319. ;  Set User/Disk for File Output
  1320. ;
  1321. setfud:
  1322.     push    h    ;Save Regs
  1323.     push    d
  1324.     push    b
  1325.     lda    hdisk    ;Select Home Disk
  1326.     mov    e,a
  1327.     mvi    c,14
  1328.     call    entry
  1329.     lda    huser    ;Select Home User
  1330.     mov    e,a
  1331.     mvi    c,32
  1332.     call    entry
  1333.     jr    rexit    ;Exit and Restore Regs
  1334. ;
  1335. ;  Save Current DMA Address
  1336. ;
  1337. savdma:
  1338.     push    h
  1339.     lhld    biosdma    ;Get Current DMA
  1340.     shld    usrdma    ;Set User DMA
  1341.     pop    h
  1342.     ret
  1343. ;
  1344. ;  Check for A=0FFH and print error code in C if so
  1345. ;
  1346. errchk:
  1347.     cpi    0ffh    ;Error?
  1348.     rnz
  1349. err1:
  1350.     call    djcout    ;Output Error Code
  1351.     mvi    c,7    ;Ring Bell
  1352.     jmp    djcout
  1353. ;
  1354. ;  Buffers
  1355. ;
  1356. dsk1:    db    0    ;Not Open
  1357.     dw    dma1    ;Buffer Address Set by Software
  1358.     db    0    ;No Bytes Stored
  1359.     dw    dma1    ;DMA Address
  1360.     dw    fcb1    ;FCB Address
  1361.  
  1362. dsk2:    db    0    ;Not Open
  1363.     dw    dma2    ;Buffer Address Set by Software
  1364.     db    0    ;No Bytes Stored
  1365.     dw    dma2    ;DMA Address
  1366.     dw    fcb2    ;FCB Address
  1367.  
  1368.     db    'End of SYSIO',0
  1369.  
  1370.     org    bufbase    ;Scratch Area for Buffers
  1371.  
  1372. dma1:    ds    128    ;DMA for Console
  1373. dma2:    ds    128    ;DMA for Printer
  1374.  
  1375. disk:    ds    1    ;Current Disk
  1376. user:    ds    1    ;Current User
  1377. hdisk:    ds    1    ;Home Disk
  1378. huser:    ds    1    ;Home User
  1379. usrdma:    ds    2    ;User DMA Address
  1380. fsbptr:    ds    2    ;Ptr to File Spec Block
  1381. clast:    ds    1    ;Last Char to CRT
  1382. tlast:    ds    1    ;Last Char to PRT
  1383. fcb1:    ds    36    ;CRT Disk Output FCB
  1384. fcb2:    ds    36    ;TTY Disk Output FCB
  1385.  
  1386.     ds    100    ;50-Element Local Stack
  1387. stack:    ds    2    ;User Stack Ptr
  1388.  
  1389. stksav:    ds    stksiz    ;User's Original Stack
  1390.  
  1391.  
  1392.     end
  1393.