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 / BEEHIVE / ZCAT / SYSIOP21.LBR / SYSIOP.ZZ0 / SYSIOP.Z80
Text File  |  2000-06-30  |  44KB  |  1,231 lines

  1. VERSION    EQU    211
  2. ;**************************************************************************
  3. ;**************************************************************************
  4. ;**                                    ***
  5. ;**    System IO: A set of redirectable I/O drivers for ZCPR3        ***
  6. ;**                                    ***
  7. ;**************************************************************************
  8. ;**************************************************************************
  9. ;
  10. ; File Name        : SYSIOP.Z80
  11. ; Author        : Edmund Cramp
  12. ; Creation Date        : 10-Jun-1986
  13. ;
  14. ; Proccessor Type    : HD64180
  15. ; Assembler Name    : Z80ASM (S.L.R Systems)
  16. ;
  17. ; Ammendment Record
  18. ; *****************
  19. ; Name        Date        Details of Ammendment
  20. ; ----        ----        ---------------------
  21. ; Edmund Cramp    10-Jun-1986    Creation from Richard Conns distribution copy.
  22. ; Edmund Cramp    28-Jun-1986    Release 2.00
  23. ; Edmund Cramp    27-Aug-1986    Determine interrupt table location from 64180
  24. ;                registers. RDR and PUN modified. Console ISR
  25. ;                checks for chars stacked in ASCI. System size
  26. ;                determined from WB addrs.
  27. ; Edmund Cramp    31-Aug-1986    Rearranged the list ISR logic.
  28. ; Edmund Cramp    03-Sep-1986    Release 2.11 - shorter LST: driver code. Buffer
  29. ;                sizes adjusted and VT100 keypad mode bug fixed.
  30. ;                
  31. ; Module Function
  32. ; ***************
  33. ;    This device driver package is to be assembled and the resulting .COM
  34. ; file is to be renamed to SYS.IOP for use by the ZCPR3 system loader.  This
  35. ; version is not banked and resides in the normal ZCPR IOP area only.
  36. ;    As some of the devices are XON/XOFF devices I have implemented a key
  37. ; translation table for ANSI (VT-100) terminals and Zenith (VT-52) arrow keys.
  38. ; These keys generate an escape (ESC) sequence that is translated via a simple
  39. ; lookup table in the data area to the ZCPR standard of ^E,^X,^S,^D. This is
  40. ; nessesary as the ^S key is XOFF and all XOFFs are gobbled in the interrupt
  41. ; service routine.  For precise details on the XON/XOFF protocol see the DEC
  42. ; VT100 user manual.
  43. ;    For installation details see the "-READ.ME" file.
  44. ;**************************************************************************
  45.  
  46. ;    ==============
  47. ;    External Files
  48. ;    ==============
  49.  
  50.     MACLIB    HD64180.MLB    ; HD64180 macro library.
  51.     MACLIB    PORTS.LIB    ; SB-180 Hardware configuration file.
  52.     MACLIB    Z3BASE.LIB    ; ZCPR3 definition file.
  53.  
  54. ;    =============
  55. ;    Local Equates
  56. ;    =============
  57.  
  58.         ; Arrow key time-out value
  59. DELAY_VALUE    EQU    800        ; Adjust if arrow keys don't work.
  60.  
  61. BDOS        EQU    0005H        ; O/S entry vector.
  62.  
  63.         ; Console input character mask (select 7 or 8 bit input).
  64. IOMASK        EQU    01111111B    ; Select 7 bit console input.
  65.  
  66.         ; ASCII control characters.
  67. XON        EQU    11H        ; ^Q
  68. XOFF        EQU    13H        ; ^S
  69. ESC        EQU    1BH        ; Escape.
  70.  
  71.         ; Arrow key translation support for VT52 or VT100
  72. VT100        EQU    100        ; DEC VT1xx and ANSI terminals.
  73. VT52        EQU    52        ; DEC VT52 and Heath terminals.
  74. FOREIGN        EQU    0        ; Unknown terminal type - no translation
  75.  
  76.         ; IOP device driver offsets
  77. DEVCON        EQU    0        ; Console.
  78. DEVRDR        EQU    DEVCON+1    ; Reader.
  79. DEVPUN        EQU    DEVRDR+1    ; Punch.
  80. DEVLST        EQU    DEVPUN+1    ; List.
  81.  
  82.         ; Printer control codes
  83. NORMAL        EQU    18        ; EPSON switches to 80 column print.
  84. COMPRS        EQU    15        ; EPSON switches to 132 column print.
  85.  
  86.         ; HD64180 ASCI equates.
  87. RDRF        EQU    10000000B    ; Receive register full.
  88. OVRN        EQU    01000000B    ; Receiver buffer overrun.
  89. PE        EQU    00100000B    ; Parity error.
  90. FE        EQU    00010000B    ; Framing error.
  91. DCD0        EQU    00000100B    ; Carrier detect.
  92. TDRE        EQU    00000010B    ; Transmit register empty.
  93.  
  94. EFR        EQU    00001000B    ; Error flag reset.
  95.  
  96. ;    ============
  97. ;    Local Macros
  98. ;    ============
  99.  
  100. PRINTE    MACRO    MSG,N        ;; Macro to display free byte count
  101.     IF2
  102.     .PRINTX * MSG N bytes *
  103.     ENDIF
  104.     ENDM
  105.  
  106. MVERSN    MACRO            ;; Expand version number.
  107.     DEFB    VERSION/100+'0'
  108.     DEFB    '.'
  109.     DEFB    (VERSION MOD 100/10)+'0'
  110.     DEFB    (VERSION MOD 10)+'0'
  111.     ENDM
  112.  
  113. ;***************************************************************************
  114. ;***    SYSIOP                                ****
  115. ;***************************************************************************
  116.  
  117.         .PHASE    IOP        ; Base Address of I/O Drivers (from Z3BASE).
  118.  
  119.         JP    STATUS        ; Internal Status Routine
  120.         JP    SELECT        ; Device Select Routine
  121.         JP    NAMER        ; Device Name Routine
  122.         JP    TINIT        ; Initialize I/O package.
  123.  
  124.         JP    CONST        ; Console Input Status
  125.         JP    CONIN        ; Console Input Char
  126.         JP    CONOUT        ; Console Output Char
  127.  
  128.         JP    LIST        ; List Output Char
  129.  
  130.         JP    PUNCH        ; Punch Output Char
  131.         JP    READER        ; Reader Input Char
  132.  
  133.         JP    LISTST        ; List Output Status
  134.  
  135.         JP    NEWIO        ; New I/O Driver Installation Routine
  136.  
  137.         JP    COPEN        ; Open CON: Disk file.
  138.         JP    CCLOSE        ; Close CON: Disk file.
  139.         JP    LOPEN        ; Open LST: Disk file.
  140.         JP    LCLOSE        ; Close LST: Disk file.
  141.  
  142. ;+
  143. ; I/O Package Identification
  144. ;-
  145.         DEFB    'Z3IOP'        ; Read by Z3LOADER
  146.         DEFZ    'SB180b'    ; Package name.
  147. ;+
  148. ; Return information on devices supported by this I/O Package. On exit, HL
  149. ; points to an eight byte logical device table.  If error or no I/O support,
  150. ; return with Zero Flag Set.  Also, if no error, A=Driver Module Number
  151. ; (Msb=0 if "OPEN" and "CLOSE" functions are not implemented).
  152. ;-
  153. STATUS:        LD    HL,CNTTBL    ; Point to table
  154.         LD    A,00000010B    ; Module 2 (SB180b) w/o Disk Output.
  155.         OR    A        ; Set Flags
  156.         RET            ; 
  157.  
  158. ;+
  159. ; Select devices indicated by B and C.  B is the number of the logical device,
  160. ; where CON:=0, RDR:=1, PUN:=2, LST:=3, and C is the desired device (range 0
  161. ; to dev-1). Return with Zero Flag Set if Error.
  162. ;-
  163. SELECT:        CALL    RANGER        ; Do a range check for device and driver
  164.         JR    NC,SELERR    ; ...branch if error.
  165.         ; 
  166.         INC    HL        ; Bump pointer to selected device...
  167.         LD    (HL),C        ; ...and select the device driver.
  168.         ; 
  169. SELOK:        OR    -1        ; Return no error...
  170.         RET            ; ...0FFh and NZ.
  171.  
  172. ;+
  173. ; Check that a requested device and driver are legal. On entry B is the logical
  174. ; device number (0-3) and C is the physical device number (0 to dev-1).
  175. ; Exit NC if either device or driver are out of range.  If device is legal then
  176. ; return with offset (0,2,4,6) in Reg DE and Reg HL pointing to the entry in
  177. ; CNTTBL and the CY flag set.
  178. ;-
  179. RANGER:        LD    A,B        ; Check that device is legal...
  180.         CP    DEVLST+1    ; ...ie DEVCON to DEVLST...
  181.         RET    NC        ; ...exit if illegal device requested.
  182.         ; 
  183.         ADD    A,B        ; Double B so offset is 0,2,4,6
  184.         LD    E,A        ; Build offset in Reg DE...
  185.         LD    D,0        ; ...
  186.         LD    HL,CNTTBL    ; Point to the IOP table and adjust...
  187.         ADD    HL,DE        ; ...to point to to device in CNTTBL.
  188.         ; 
  189.         LD    A,C        ; Read the maximum number of devices...
  190.         CP    (HL)        ; Check for illegal driver request.
  191.         ; 
  192.         RET            ; Exit CY set if OK, clear CY if not.
  193.  
  194. ;+
  195. ; Return text string of physical device. Logical device    number is in B and the
  196. ; physical selection is in C. HL is returned pointing to the first character of
  197. ; the string. The strings are structured to begin with a device name followed
  198. ; by a space and then a description string which is terminated by a binary 0.
  199. ; Return with Zero Flag Set if error.
  200. ;-
  201. NAMER:        CALL    RANGER        ; Check device and driver numbers...
  202.         JR    NC,NAMERROR    ; Exit if error in name request.
  203.         ; 
  204.         LD    HL,NAMPTB    ; Point to device name table pointers.
  205.         ADD    HL,DE        ; ...offset to driver name pointer.
  206.         LD    E,(HL)        ; Copy driver name pointer into...
  207.         INC    HL        ; ...
  208.         LD    D,(HL)        ; ...reg DE.
  209.         EX    DE,HL        ; HL now points to driver name table.
  210.         ; 
  211.         LD    A,C        ; Generate the driver offset...
  212.         ADD    A,C        ; ...(0,2,4,6)...
  213.         LD    E,A        ; ...load Reg DE...
  214.         LD    D,0        ; ...
  215.         ADD    HL,DE        ; HL now points to driver name address.
  216.         ; 
  217.         LD    E,(HL)        ; Get address of NAME string...
  218.         INC    HL        ; ...
  219.         LD    D,(HL)        ; ...into Reg DE.
  220.         EX    DE,HL        ; Swop pointer, HL -> driver name.
  221.         ; 
  222.         JR    SELOK        ; Exit after setting OK flags.
  223.  
  224. NAMERROR:    LD    HL,ERRMSG    ; Point to an error message...
  225.         ; 
  226. SELERR:        XOR    A        ; ...Exit, error.
  227.         RET
  228.  
  229. ;+
  230. ; Get the status for the currently assigned console.
  231. ;-
  232. CONST:        LD    HL,CSTBLE    ; Beginning of jump table
  233.         ; 
  234. CONMSK:        LD    E,DEVCON*2    ; Point to console device in config table
  235.         JR    SELDEV        ; Select correct jump
  236.  
  237. ;+
  238. ; Input a character from the currently assigned console.
  239. ;-
  240. CONIN:        LD    HL,CITBLE    ; Beginning of character input table
  241.         JR    CONMSK        ; Get Console Mask
  242.  
  243. ;+
  244. ; Output the character in C to the currently assigned console.
  245. ;-
  246. CONOUT:        LD    HL,COTBLE    ; Beginning of the character out table
  247.         JR    CONMSK        ; Get the Console Mask
  248.  
  249. ;+
  250. ; Input a character from the currently assigned reader.
  251. ;-
  252. READER:        LD    HL,RTBLE    ; Beginning of reader input table
  253.         LD    E,DEVRDR*2    ; Point to reader device in config table
  254.         ; Fall through into SELDEV....
  255.  
  256. ;+
  257. ; Entry at SELDEV will form an offset into the table pointed to by HL and
  258. ; then pick up the address and jump there. The configuration of the physical
  259. ; device assignments is pointed to by B.  Note that the Acc and flags are
  260. ; preserved as the SB180 bios has a non-standard RDR and PUN driver.
  261. ;-
  262. SELDEV:        PUSH    AF        ; Save CY state for SB180 RDR/PUN.
  263.         PUSH    HL        ; Save driver pointer
  264.         ; 
  265.         LD    HL,CNTTBL    ; Point to IOP control table...
  266.         ; Reg E contains 8-bit offset...
  267.         LD    D,0        ; Make Reg DE a 16-bit offset...
  268.         ADD    HL,DE        ; Add offset to HL...
  269.         INC    HL        ; ...and adjust HL to point to device #.
  270.         ; 
  271.         LD    E,(HL)        ; Read current physical device from table
  272.         SLA    E        ; Double device for word pointer (D=0).
  273.         POP    HL        ; Retrive driver pointer from stack...
  274.         ADD    HL,DE        ; ...and adjust HL to physical device.
  275.         ; 
  276.         LD    E,(HL)        ; Get physical driver address...
  277.         INC    HL        ; ...
  278.         LD    D,(HL)        ; ...
  279.         EX    DE,HL        ; ...into reg HL.
  280.         ; 
  281.         POP    AF        ; Restore CY state for RDR/PUN (SB-180).
  282.         JP    (HL)        ; Branch to physical device driver.
  283.  
  284. ;+
  285. ; Output char in C to the currently assigned punch device.
  286. ;-
  287. PUNCH:        LD    HL,PTBLE    ; Beginning of punch table
  288.         LD    E,DEVPUN*2    ; Offset to punch devices.
  289.         JR    SELDEV        ; Select Device and Go
  290.  
  291. ;+
  292. ; Output char in C to the currently assigned list device.
  293. ;-
  294. LIST:        LD    HL,LTBLE    ; Beginning of the list device routine
  295.         ; 
  296. LSTMSK:        LD    E,DEVLST*2    ; Select list devices...
  297.         JR    SELDEV        ; ...branch to select function.
  298.  
  299. ;+
  300. ; Get the output status of the currently assigned list device.
  301. ;-
  302. LISTST:        LD    HL,LSTBLE    ; Beginning of the list device status
  303.         JR    LSTMSK        ; Branch to point to list devices.
  304.  
  305. ;**************************************************************************
  306. ;**     I/O Driver Support Specification Tables                ***
  307. ;**************************************************************************
  308. ;+
  309. ; IOP control table
  310. ; The first byte is the number of device drivers supported; the second is
  311. ; the currently selected device.
  312. ;-
  313. CNTTBL:        DEFB    CONSIZE,00    ; CON:
  314.         DEFB    RDRSIZE,00    ; RDR:
  315.         DEFB    PUNSIZE,00    ; PUN:
  316.         DEFB    LSTSIZE,00    ; LST:
  317.  
  318. ;+
  319. ; Logical Device name text pointers.
  320. ;-
  321. NAMPTB:        DEFW    CONAME        ; CON: device
  322.         DEFW    RDNAME        ; RDR: device
  323.         DEFW    PUNAME        ; PUN: device
  324.         DEFW    LSNAME        ; LST: device
  325.  
  326.         ; Physical console pointers
  327. CONAME:        DEFW    NAMDEC        ; DEC Console (xon/xoff handshake).
  328.         DEFW    NAMCRT        ; ISR Console.
  329.         DEFW    NAMPOL        ; Polled Console.
  330.         DEFW    NAMREM        ; ASCI0 serial line.
  331.         DEFW    NAMCRP        ; DEC Console and Printer output.
  332.         DEFW    NAM100        ; DEC w/ ANSI arrow key translation.
  333.         DEFW    NAM52        ; DEC w/ VT52 arrow key translation.
  334.         DEFW    NAMPAT        ; Patchable console device.
  335. CONSIZE        EQU    ($-CONAME)/2
  336.  
  337.         ; Physical reader pointers.
  338. RDNAME:        DEFW    NAMNUL        ; Null device
  339.         DEFW    NAMMOD        ; Modem.
  340.         DEFW    NAMRDR        ; SB-180 reader (returns status).
  341.         DEFW    NAMPAT        ; Patch device
  342. RDRSIZE        EQU    ($-RDNAME)/2
  343.  
  344.         ; Physical punch pointers.
  345. PUNAME:        DEFW    NAMNUL        ; Null device
  346.         DEFW    NAMMOD        ; Modem.
  347.         DEFW    NAMPUN        ; SB-180 punch (retuns status).
  348.         DEFW    NAMPAT        ; Patch device
  349. PUNSIZE        EQU    ($-PUNAME)/2
  350.  
  351.         ; Physical list pointers
  352. LSNAME:        DEFW    NAMNUL        ; Null device.
  353.         DEFW    NAMDEC        ; DEC (xon/xoff) console.
  354.         DEFW    NAMSER        ; Serial printer on ASCI-0.
  355.         DEFW    NAMPRT        ; Centronics printer.
  356.         DEFW    NAM80        ; MX80 set for 80 Columns.
  357.         DEFW    NAM132        ; MX80 set for 132 Columns.
  358. LSTSIZE        EQU    ($-LSNAME)/2
  359.  
  360. ;+
  361. ; Device Name Strings.
  362. ;-
  363. NAMCRT:        DEFZ    'CRT console (ISR)'        ;  1
  364. NAMPOL:        DEFZ    'CRTP polled I/O'        ;  2
  365. NAMDEC:        DEFZ    'DEC (xon/xoff) console'    ;  3
  366. NAM100:        DEFZ    'VT100 DEC console'        ;  4
  367. NAM52:        DEFZ    'VT52 DEC console'        ;  5
  368. NAMCRP:        DEFZ    'COPY to LST: device'        ;  6
  369. NAMREM:        DEFZ    'REMOTE console on ASCI0'    ;  7
  370. NAMPAT:        DEFZ    'PATCH test harness'        ;  8
  371. NAM80:        DEFZ    'MX80 printer'            ;  9
  372. NAM132:        DEFZ    'MX132 printer'            ; 10
  373. NAMNUL:        DEFZ    'NULL device'            ; 11
  374. NAMMOD:        DEFZ    'MODEM on ASCI0'        ; 12
  375. NAMPUN:        DEFZ    'PUN ASCI0 w/status'        ; 13
  376. NAMRDR:        DEFZ    'RDR ASCI0 w/status'        ; 14
  377. NAMPRT:        DEFZ    'LIST Centronics printer'    ; 15
  378. NAMSER:        DEFZ    'SERIAL printer on ASCI0'    ; 16
  379.  
  380. ;+
  381. ; Console input table
  382. ;-
  383. CITBLE:        DEFW    CIDEC        ; 0 Input from DEC (xon/xoff) device.
  384.         DEFW    CICRT        ; 1 Input from CRT via ISR.
  385.         DEFW    CIPOL        ; 2 Input from CRT via polled I/O.
  386.         DEFW    CIRMT        ; 3 Input from ASCI-0 port.
  387.         DEFW    CIDEC        ; 4 Input from DEC: - Output to LST:
  388.         DEFW    CI100        ; 5 Input from DEC w/ ANSI arrow keys.
  389.         DEFW    CI52        ; 6 Input from DEC w/ VT52 arrow keys.
  390.         DEFW    CIPAT        ; 7 Input from patched device (8-bit).
  391.  
  392. ;+
  393. ; Console status table
  394. ;-
  395. CSTBLE:        DEFW    CSDEC        ; 0 Status from DEC device.
  396.         DEFW    CSCRT        ; 1 Status from CRT ISR.
  397.         DEFW    CSPOL        ; 2 Status from CRT via polled I/O.
  398.         DEFW    CSMOD        ; 3 Status from ASCI-0 port.
  399.         DEFW    CSDEC        ; 4 Status for CRT and Printer.
  400.         DEFW    CSDEC        ; 5 Status from ANSI device.
  401.         DEFW    CSDEC        ; 6 Status from VT52 device.
  402.         DEFW    CSPAT        ; 7 Status from patched device.
  403.  
  404. ;+
  405. ; Console output table
  406. ;-
  407. COTBLE:        DEFW    CODEC        ; 0 Output to DEC (xon/xoff) device.
  408.         DEFW    COCRT        ; 1 Output to CRT (ISR input).
  409.         DEFW    COCRT        ; 2 Output to CRT (Polled input).
  410.         DEFW    COMOD        ; 3 Output to ASCI-0 port.
  411.         DEFW    COCRTP        ; 4 Output to CRT and Printer.
  412.         DEFW    CODEC        ; 5 Output to ANSI (xon/xoff) device.
  413.         DEFW    CODEC        ; 6 Output to VT52 (xon/xoff) device.
  414.         DEFW    COPAT        ; 7 Output to patched device.
  415.  
  416. ;+
  417. ; Punch device table
  418. ;-
  419. PTBLE:        DEFW    CONULL        ; 0 Output to null device
  420.         DEFW    COMOD        ; 1 Modem port
  421.         DEFW    COPUN        ; 2 SB-180 status checking punch.
  422.         DEFW    COPAT        ; 3 Patch device
  423.  
  424. ;+
  425. ; Reader device table
  426. ;-
  427. RTBLE:        DEFW    CINULL        ; 0 Input from null device.
  428.         DEFW    CIMOD        ; 1 Modem port.
  429.         DEFW    CIRDR        ; 2 SB-180 status checking reader.
  430.         DEFW    CIPAT        ; 3 Patch device
  431.  
  432. ;+
  433. ; List device table
  434. ;-
  435. LTBLE:        DEFW    CONULL        ; 0 Output to null device.
  436.         DEFW    CODEC        ; 1 Output to DEC device.
  437.         DEFW    COMOD        ; 2 Output to ASCI-0 for serial printer.
  438.         DEFW    MXOUT        ; 3 Any Centronics printer.
  439.         DEFW    COM80        ; 4 Output to 80 column EPSON printer.
  440.         DEFW    COM132        ; 5 Output to 132 column EPSON printer.
  441.  
  442. ;+
  443. ; Status from List device
  444. ;-
  445. LSTBLE:        DEFW    CSNULL        ; 0 Status from null device.
  446.         DEFW    CSDEC        ; 1 Status from DEC (xon/xoff) device.
  447.         DEFW    COSMOD        ; 2 Status from serial line (ASCI-0).
  448.         DEFW    COSMX        ; 3 Status from Centronics printer.
  449.         DEFW    COSMX        ; 4 Status from EPSON 80 col printer.
  450.         DEFW    COSMX        ; 5 Status from EPSON 132 col printer.
  451.  
  452. ;**************************************************************************
  453. ;***    Initialise all I/O devices.                    ***
  454. ;**************************************************************************
  455. ;+
  456. ;    This routine is called when the IOP is loaded.  It is intended to
  457. ; initialise the I/O device registers for devices used by the package.  Since
  458. ; SB-180 is an interrupt driven machine we also need to reset the interrupt
  459. ; vector table as well.  The interrupt vector table location is now determined
  460. ; from the HD64180 registers and the BIOS entry point from the warm boot vector
  461. ; so that this initialisation should work for any system size.
  462. ;    This means that any other IOP packages loaded AFTER this IOP must also
  463. ; re-patch the interrupt vector table.  Once the IOP has been initialised this
  464. ; routine is redundant and it is overlayed by the console ISR buffer.
  465. ;    As polled I/O is supported (in addition to interrupt driven I/O) for
  466. ; the console device it is possible to disable ASCI-1 (Console) interrupts.
  467. ; If the ASCI-1 interrupts are disabled and this IOP is replaced by one that
  468. ; does not specifically ENABLE the ASCI-1 interrupts then console I/O will
  469. ; cease.
  470. ;            >>> YOU HAVE BEEN WARNED <<<
  471. ;-
  472. TYPBUF:        DEFB    00        ; Re-use initialisation area for buffer.
  473.         ; 
  474. TINIT:        DI            ; Turn interrupts OFF.
  475.         ; Load our interrupt service vectors into the HD64180 table.
  476.         LD    A,I        ; Get high byte...
  477.         LD    H,A        ; ...into Reg H.
  478.         IN0    A,(IL)        ; Read low byte from HD64180...
  479.         AND    11100000B    ; ...mask...
  480.         LD    L,A        ; ...Reg HL contains table address.
  481.         PUSH    HL        ; Load IX via stack.
  482.         POP    IX        ; Point IX to ASCI ISR entries.
  483.         ;
  484.         ; Centronics ISR...
  485.         LD    (IX),LOW INTLPT
  486.         LD    (IX+1),HIGH INTLPT
  487.         ; Channel 1 ISR...
  488.         LD    (IX+16),LOW INTASCI1
  489.         LD    (IX+17),HIGH INTASCI1
  490.         ;
  491.         LD    HL,SELERR    ; Reset the TINIT entry vector...
  492.         LD    (IOP+10),HL    ; ...to prevent accidents.
  493.         ; 
  494.         LD    HL,(0001)    ; Get bios warm boot page address.
  495.         LD    L,40H+5        ; Calculate ASCI-1 Int location.
  496.         LD    (ASCIINT),HL    ; Save it for later.
  497.         ;
  498.         LD    DE,SIGNON    ; Sign-on message in printer buffer...
  499.         LD    C,09H        ; ...will be displayed...
  500.         CALL    BDOS        ; ...via the BDOS.
  501.         ; 
  502. TINDONE:    IN0    A,(RDR0)    ; Gobble any waiting characters...
  503.         IN0    A,(RDR1)    ;...
  504.         ; Done.
  505.         EI            ; Restore interrupts.
  506.         RET            ; Exit
  507.  
  508. BUFLEN        EQU    $-(TYPBUF+1)    ; Type-ahead buffer length (2-255).
  509.  
  510. ;**************************************************************************
  511. ;***    Interrupt control.                        ***
  512. ;**************************************************************************
  513. ;+
  514. ; This IOP supports a polled I/O console device in addition to the interrupt
  515. ; driver.  INTOGGLE is called by ASCI-1 status check routines to ensure that
  516. ; the ASCI-1 interrupts are set correctly.
  517. ;-
  518. INTOGGLE:    DI            ; Disable all interrupts.
  519.         JR    Z,INTON        ; Turn ASCI-1 interrupts ON
  520.         ; Turn ASCI-1 interrupts OFF.
  521.         IN0    B,(STAT1)    ; Read current CTS1 status.
  522.         RES    3,B        ; Clear ASCI-1 interrupts, save CTS1.
  523.         XOR    A        ; Set acc to zero (no ints).
  524.         JR    INTSAVE        ; Branch to save interrupt status.
  525.  
  526.         ; Turn ASCI-1 interrupts ON.
  527. INTON:        IN0    B,(STAT1)    ; Read CTS1 status...
  528.         SET    3,B        ; Enable ASCI-1 interrupts...
  529.         DEC    A        ; Set acc to -1 (ints on).
  530.         ; 
  531. INTSAVE:    OUT0    (STAT1),B    ; Write interrupt status to ASCI-1.
  532.         LD    (TOGGLE),A    ; Save current ASCI1 interrupt status...
  533.         ; Update the BIOS configuration table...
  534.         LD    HL,(ASCIINT)    ; Point to ASCI-1 STAT1 entry...
  535.         LD    (HL),B        ; ...save new ASCI-1 status.
  536.         ; 
  537.         EI            ; Enable interrupts.
  538.         RET            ; Exit - done.
  539.         
  540. ;**************************************************************************
  541. ;*** Set PAT to the Device whose jump table is pointed to by HL.    ***
  542. ;**************************************************************************
  543. ;+
  544. ; This Jump Table is structured as follows:
  545. ;    JMP ISTAT    <-- Input Status (0=No Char, 0FFH=Char)
  546. ;    JMP INPUT    <-- Input Character
  547. ;    JMP OUTPUT    <-- Output Character in C
  548. ;
  549. ; The Base Address of this Jump Table (JBASE) is passed to NEWIO in the
  550. ; HL Register Pair.
  551. ;-
  552. NEWIO:        LD    (CSPTCH),HL    ; Load input status vector.
  553.         LD    DE,3        ; Prepare for offset to next jump
  554.         ADD    HL,DE        ; HL points to next jump
  555.         LD    (CIPTCH),HL    ; Load input character vector.
  556.         ADD    HL,DE        ; HL points to next jump
  557.         LD    (COPTCH),HL    ; Load output character vector.
  558.         RET
  559.  
  560. ;**************************************************************************
  561. ;**************************************************************************
  562. ;***  Input Status, Input Character, and Output Character Routines    ***
  563. ;**************************************************************************
  564. ;**************************************************************************
  565. ;+
  566. ; Input Status --
  567. ; These routines return 00 in the A Register if no input data is available,
  568. ; 0FFH if input data is available. The Z flag will reflect the contents of
  569. ; the accumulator.
  570. ;
  571. ; Input Character --
  572. ; These routines return the character (byte) in the A Register.  All console
  573. ; input (with the notable exception of the PATCH device) will be masked by
  574. ; the value IOMASK, thus console input may be either 8-bit or 7-bit depending
  575. ; on the value of IOMASK.  Reader input is always 8-bit.
  576. ;
  577. ; Output Character --
  578. ; These routines output the character (byte) in the C Register.
  579. ;-
  580.  
  581. ;**************************************************************************
  582. ;***    I/O device test via patchable external driver.            ***
  583. ;**************************************************************************
  584. ;+
  585. ; Note that this version of the external driver will automatically quit and
  586. ; pass control back to the CRT if passed a set of null jumps (JP 0000).
  587. ;-
  588. CIPAT:        LD    HL,(CIPTCH)    ; Read current vector...
  589.         LD    A,H        ; ...test for 0000
  590.         OR    L        ; ...
  591.         JR    Z,CICRT        ; Input from console if not initialised.
  592.         JP    (HL)        ; Branch to patch driver.
  593.  
  594. CSPAT:        LD    HL,(CSPTCH)    ; Read current vector...
  595.         LD    A,H        ; ...test for 0000
  596.         OR    L        ; ...
  597.         JR    Z,CSCRT        ; Get status from console if not initialised.
  598.         JP    (HL)        ; Branch to patch driver.
  599.  
  600. COPAT:        LD    HL,(COPTCH)    ; Read current vector...
  601.         LD    A,H        ; ...test for 0000
  602.         OR    L        ; ...
  603.         JR    Z,COCRT        ; Output to console if not initialised.
  604.         JP    (HL)        ; Branch to patch driver.
  605.                 
  606. ;**************************************************************************
  607. ;***    Polled I/O driver for ASCI-1 (Console).                ***
  608. ;**************************************************************************
  609.  
  610. CSPOL:        LD    A,(TOGGLE)    ; Get current ASCI1 interrupt status...
  611.         AND    A        ; ...
  612.         CALL    NZ,INTOGGLE    ; ...and turn OFF if they're ON.
  613.         ; 
  614.         IN0    A,(STAT1)    ; Read status...
  615.         AND    RDRF        ; ...test for character.
  616.         ; 
  617.         JR    CSCRET        ; Branch to return console status.
  618.  
  619. CIPOL:        CALL    CSPOL        ; Wait for character...
  620.         JR    Z,CIPOL        ; ...
  621.         ; 
  622.         IN0    A,(RDR1)    ; Read character
  623.         AND    IOMASK        ; Select 7/8 bit input...
  624.         RET            ; ...and exit.
  625.  
  626. ;**************************************************************************
  627. ;***    Interrupt driven console with buffer - no handshaking.        ***
  628. ;**************************************************************************
  629.  
  630.         ; ASCI1 Input
  631. CICRT:        CALL    CSCRT        ; Test input status
  632.         JR    Z,CICRT        ; Loop if not ready
  633.         ; Get char from type-ahead buffer...
  634. CINPUT:        DI            ; Disable interrupts while buffer is rotated.
  635.         LD    HL,TYPBUF+BUFLEN; Point to end of buffer.
  636.         LD    B,BUFLEN    ; Length of buffer
  637.         LD    C,0        ; Null (to erase old char).
  638.         ; Rotate buffer (6Mhz clock and we get carried away).
  639. CIROTATE:    LD    A,(HL)        ; Get a character...
  640.         LD    (HL),C        ; Write prior character.
  641.         LD    C,A        ; Rotate the buffer through Reg C.
  642.         DEC    HL        ; Adjust pointer...
  643.         DJNZ    CIROTATE    ; ..and loop through entire buffer.
  644.         ; Finished rotating the buffer contents...
  645.         DEC    (HL)        ; Adjust the character pointer.
  646.         EI            ; Done with buffer - interrupts OK.
  647.         ; Common console input return.
  648. CISELCT:    AND    IOMASK        ; Select 7/8 bit input.
  649.         RET            ; Exit w/ oldest char in Acc and Reg C.
  650.  
  651.         ; ASCI1 Input status
  652. CSCRT:        LD    A,-1        ; Set Acc=-1
  653.         LD    (XON_FLAG),A    ; ...signal no handshake check.
  654.         ; Common status check code.
  655. CSTATUS:    LD    A,(TOGGLE)    ; Get current ASCI1 interrupt status...
  656.         AND    A        ; ...
  657.         CALL    Z,INTOGGLE    ; ...and turn ON if they're OFF.
  658.         ; 
  659.         LD    A,(TYPBUF)    ; Read the "characters waiting" count.
  660.         AND    A        ; Set Z flags READY/NOT READY.
  661.         ; Common console status return.
  662. CSCRET:        RET    Z        ; Not ready...
  663.         OR    -1        ; Set Acc to -1...
  664.         RET            ; Ready.
  665.  
  666.         ; ASCI1 Output status
  667. COSCRT:        IN0    A,(STAT1)    ; Read the status byte
  668.         AND    TDRE        ; Mask out the buffer empty bit
  669.         ; 
  670.         JR    CSCRET        ; Branch to return console status.
  671.  
  672.         ; ASCI1 Output    
  673. COCRT:        CALL    COSCRT        ; Test the output status
  674.         JR    Z,COCRT        ; Loop if not ready
  675.         ; 
  676.         OUT0    (TDR1),C    ; Xmit the data
  677.         RET            ; Return
  678.  
  679.         ; CRT and Printer output
  680. COCRTP:        CALL    CODEC        ; Send char to DEC (xon/xoff) device.
  681.         JP    LIST        ; Send char to printer.
  682.  
  683. ;**************************************************************************
  684. ;***    Terminals requiring XON/XOFF support (ANSI, DEC VT1xx and VT52)    ***
  685. ;**************************************************************************
  686.  
  687.         ; Common DEC status (flag xon/xoff handshaking).
  688. CSDEC:        XOR    A        ; Get a zero...
  689.         LD    (XON_FLAG),A    ; ...select xon/xoff handshake check.
  690.         ; Check the input status
  691.         LD    A,(XOFF_OUT)    ; Have we tried to stop console input?
  692.         AND    A        ; ...
  693.         JR    NZ,CSTATUS    ; No, use standard status check.
  694.         ; Yes, input buffer has been filling up...check low water-mark...
  695.         LD    A,(TYPBUF)    ; Get current buffer count...
  696.         CP    BUFLEN*1/3    ; ...is it below the minimum count?
  697.         JR    NC,CSTATUS    ; No, use standard status check.
  698.         ; 
  699.         DI            ; Disable interrupts...
  700.         LD    A,-1        ; ...flag console on again...
  701.         LD    (XOFF_OUT),A    ; ...
  702.         EI            ; ...enable interrupts...
  703.         LD    C,XON        ; ...and send an xon...
  704.         CALL    CODEC        ; ...to enable console.
  705.         JR    CSTATUS        ; Finally return console status.
  706.  
  707.         ; DEC VT1xx input with "Esc [ A/B/C/D" translation.
  708. CI100:        LD    A,VT100        ; Flag VT1xx terminals...
  709.         LD    (TERMTYP),A    ; ...
  710.         JR    CIDIN        ; Branch to common input routine.
  711.  
  712.         ; DEC VT52 input with "Esc A/B/C/D" translation.
  713. CI52:        LD    A,VT52        ; Flag VT52 and Heath terminals...
  714.         LD    (TERMTYP),A    ; ...
  715.         JR    CIDIN        ; Branch to common input routine.
  716.  
  717. CIDEC:        LD    A,FOREIGN    ; Flag unknown terminals...
  718.         LD    (TERMTYP),A    ; ...(ie do NO key translation).
  719.         ; Common DEC input.
  720. CIDIN:        CALL    CSDEC        ; Get status...
  721.         JR    Z,CIDIN        ; ...branch until ready.
  722.         CALL    CINPUT        ; Get character into Reg C and Acc.
  723.         ; Now convert the arrow keys if nessesary, since the ZCPR
  724.         ; termcap does not support standard ANSI escape sequences!
  725.         LD    A,(TERMTYP)    ; Get terminal type...
  726.         CP    FOREIGN        ; ...test for unknown terminal...
  727.         LD    A,C        ; ...restore character...
  728.         RET    Z        ; Exit if Foreign terminal (Char in A).
  729.         ; Key translation is supported...
  730.         CP    ESC        ; All arrow sequences start with Esc...
  731.         JR    Z,CI_ESC0    ; ...branch if escape.
  732.         ; Not an ESC - so exit...
  733.         JR    CISELCT        ; ...branch to strip msb if required.
  734.  
  735. ;+
  736. ; Start of escape sequence, wait for a character for a short time.  This allows
  737. ; operator entered escape sequences to get through and not hang the system.
  738. ; Tweek DELAY_VALUE if your terminal is sending slow arrow keys sequences and
  739. ; they're not being recognised... the default (800) works fine at 600 baud or
  740. ; higher with a DEC VT100.
  741. ;-
  742. CI_ESC0:    LD    HL,DELAY_VALUE    ; Set a delay counter...
  743. CI_ASCLP:    PUSH    HL        ; ...save it.
  744.         CALL    CSDEC        ; Test for another character.
  745.         POP    HL        ; Restore counter
  746.         JR    NZ,CI_ESC1    ; Return NZ if READY.
  747.         ; Not ready... count down...
  748.         DEC    HL        ; Decrement counter
  749.         LD    A,H        ; Test for done...
  750.         OR    L        ; ...
  751.         JR    NZ,CI_ASCLP    ; Loop until counter times out.
  752.         ; Nothing else, return a single ESC to the system.
  753.         LD    A,C        ; ESC character was saved in Reg C...
  754.         RET            ; ...
  755.  
  756.         ; We have a sequence ESC <char>...
  757. CI_ESC1:    CALL    CINPUT        ; Get the next character (in Reg C).
  758.         LD    B,0        ; B=0 flags 1st char in sequence.
  759.         ; 
  760.         LD    A,(TERMTYP)    ; Test for VT100 arrow keys...
  761.         CP    VT100        ; ...
  762.         JR    Z,CI_100    ; ...branch if VT100.
  763.         CP    VT52        ; Test for VT52 (and Heath) arrow keys.
  764.         JR    Z,CI_52        ; ...branch if VT52.
  765.         ; Error exit.
  766.         ; Not an recognisable escape sequence...
  767. CI_ERROR:    DI            ; Disable ints while buffer active.
  768.         ; Reg C contains current char, B may contain "["...
  769.         ; ...we know that it's an ESC sequence...
  770.         PUSH    BC        ; Save current character.
  771.         LD    A,B        ; Copy possible 2nd character...
  772.         LD    C,A        ; ...
  773.         AND    A        ; Test for any 2nd character...
  774.         CALL    NZ,PUTONE    ; ...and buffer any 2nd character.
  775.         POP    BC        ; Retrive current character in reg C.
  776.         CALL    PUTONE        ; Put current character into buffer
  777.         EI            ; Turn interrupts back on...
  778.         LD    A,ESC        ; Return an ESC to the O/S...
  779.         RET            ; ...exit with chars back in buffer.
  780.  
  781.         ; ANSI VT100 terminal support.
  782. CI_100:        LD    A,C        ; Restore the character to acc.
  783.         CP    '['        ; We're looking for "ESC [ (A,B,C,D)"
  784.         JR    NZ,CI_ERROR    ; Branch, not an "Esc [" sequence.
  785.         ; We have sequence "ESC [", get next character.  The fact that
  786.         ; the first two arrived within the delay period means that we
  787.         ; should have a machine generated sequence going so no need to
  788.         ; time the next character.
  789. CI_ESC2:    CALL    CSDEC        ; Get status...
  790.         JR    Z,CI_ESC2    ; ...branch until ready.
  791.         CALL    CINPUT        ; Get next char.
  792.         LD    B,'['        ; B="[" flags 2nd char in esc sequence.
  793.         ; Check range - (we expect A,B,C or D).
  794.         ; This is the entry point for VT52 sequences.
  795. CI_52:        LD    A,C        ; Get ASCII character to test.
  796.         SUB    'A'        ; Set range 0-3...
  797.         JR    C,CI_ERROR    ; Branch, range error.
  798.         CP    3+1        ; Test upper limit...
  799.         JR    NC,CI_ERROR    ; Branch, out of range.
  800.         ; Index into key table for value...
  801.         LD    HL,KEY_TABLE    ; Point to table...
  802.         LD    E,A        ; Add offset...
  803.         LD    D,0        ; ...
  804.         ADD    HL,DE        ; Index into table...
  805.         LD    A,(HL)        ; ...extract entry...
  806.         RET            ; ...and done.
  807.         
  808.         ; DEC output (watch the XON/XOFF status).
  809. CODEC:        CALL    COSCRT        ; Wait for ASCI register to empty...
  810.         JR    Z,CODEC        ; ...
  811.         ; ASCI is ready, check the terminal...
  812.         LD    A,(XON_STATUS)    ; Get XON/XOFF status...
  813.         CP    XOFF        ; ...
  814.         JR    Z,CODEC        ; Branch if terminal is busy.
  815.         OUT0    (TDR1),C    ; Xmit the data
  816.         RET            ; Return
  817.  
  818. ;**************************************************************************
  819. ;***    Start of Printer I/O Area for EPSON using the Centronics port.    ***
  820. ;**************************************************************************
  821.  
  822. ;+
  823. ; Normal 80 column output.
  824. ;-
  825. COM80:        LD    A,NORMAL    ; 80 char/line
  826.         JR    MXSEL        ; Branch to common output routine.
  827.  
  828. ;+
  829. ; Compressed 132 Column output
  830. ;-
  831. COM132:        LD    A,COMPRS    ; 132 char/line
  832.         JR    MXSEL        ; Branch to common output routine
  833.  
  834. ;+
  835. ; Set-up the EPSON printer
  836. ;-
  837. SETMX:        PUSH    BC        ; Save the current character on stack
  838.         LD    (HL),A        ; Save the new column number
  839.         LD    C,A        ; Pass the set-up char in Reg C.
  840.         CALL    MXOUT        ; Set-up the Printer (send control char).
  841.         LD    A,C        ; Re-enter MXSEL and with correct selection.
  842.         POP    BC        ; Restore users character.
  843.         ; Fall through to send Reg C (character) out to printer.
  844. ;+
  845. ; Interrupt driven LIST output with small buffer (uses unused space in IOP).
  846. ;-
  847. MXSEL:        LD    HL,COLS        ; Point to current printer selection
  848.         CP    (HL)        ; Check selection is correct.
  849.         JR    NZ,SETMX    ; Branch if re-selection is required.
  850.         ; Printer is set correctly...
  851. MXOUT:        CALL    COSMX        ; Get status of list buffer.
  852.         JR    Z,MXOUT        ; Wait if buffer is full.
  853.         ; Buffer is not full...
  854.         DI            ; Disable ints while we access buffer.
  855.         CALL    STUFBUF        ; Put the character into the buffer.
  856.         LD    A,(WAITFOR)    ; Read the ISR active flag...
  857.         AND    A        ; ...and test it.
  858.         JP    NZ,INTLPT    ; Start Printer output if nessesary.
  859.         ; Buffer is active...ISR will get around to it...
  860.         EI            ; Finished with buffer - turn ints on.
  861.         RET            ; Exit - done.
  862.         
  863. ;+
  864. ; Write character to list device output buffer.
  865. ;-
  866. STUFBUF:    LD    DE,(LPUT)    ; Get "put" pointer...
  867.         LD    A,C        ; Get data...
  868.         LD    (DE),A        ; ...save the data.
  869.         INC    DE        ; Bump "put" pointer
  870.         ;
  871.         LD    HL,LPCNT    ; Point to "put counter"
  872.         DEC    (HL)        ; ...adjust counter...
  873.         CALL    Z,RESPTRS    ; Reset pointers if time to wrap.
  874.         LD    (LPUT),DE    ; Save "put" pointer...
  875.         RET            ; Exit, buffer updated.
  876.  
  877. ;+
  878. ; Wrap buffer pointers, Reg HL points to counter, Reg DE is address pointer.
  879. ;-
  880. RESPTRS:    LD    DE,LBUFER    ; Wrap pointer...
  881.         LD    (HL),LSTBLEN    ; ...reset counter
  882.         RET            ; Exit.
  883.  
  884. ;+
  885. ; Buffered LIST status routine... will another character cause pointers
  886. ; to collide?  If not then return READY (NZ), otherwise return NOT READY (Z).
  887. ;-
  888. COSMX:        DI            ; Don't let the ISR interfere...
  889.         LD    HL,(LPUT)    ; Get the "put" pointer...
  890.         LD    DE,(LGET)    ; ...and the "get" pointer...
  891.         LD    A,(LPCNT)    ; ...plus "put" counter.
  892.         EI            ; Done reading - enable interrupts.
  893.         ; 
  894.         INC    HL        ; Simulate another write to buffer...
  895.         DEC    A        ; ...adjust counter.
  896.         JR    NZ,COSMX1    ; Branch if "put" pointer did NOT wrap.
  897.         LD    HL,LBUFER    ; Simulate a wrapped pointer...
  898.         ; 
  899. COSMX1:        XOR    A        ; Clear the carry flag and acc.
  900.         SBC    HL,DE        ; Will pointers collide ? (ie =0000).
  901.         RET    Z        ; Exit ZERO if buffer is full...
  902.         DEC    A        ; ...otherwise return NZ...
  903.         RET            ; ...
  904.  
  905. ;**************************************************************************
  906. ;***    Start of modem system polled I/O using ASCI-0 port.        ***
  907. ;**************************************************************************
  908. ;+
  909. ;    Note that if DCD0 pin is high then the ASCI-0 will be totally
  910. ; disabled.  This will cause problems if your modem puts its carrier detect
  911. ; on the DCD pin.  When the modem disconnects any OUTPUT to ASCI-0 will cause
  912. ; the system to hang.  The quick fix is to hook RTS,CTS and DCD together.
  913. ;    To aid in testing the serial interface the status test for the SB-180
  914. ; special devices "RDR" and "PUN" will abort with an error message if DCD0 is
  915. ; high when ASCI-0 is accessed.
  916. ;-
  917.  
  918. ;+
  919. ; Modem input status.
  920. ;-
  921. CSMOD:        LD    D,0        ; Return not ready if DCD0 is HIGH.
  922.         ; 
  923. CSMOD1:        LD    E,RDRF        ; Test ASCI receive buffer status.
  924.         JR    CSMRET        ; Return status.    
  925.  
  926. ;+
  927. ; Modem output status
  928. ;-
  929. COSMOD:        LD    D,0        ; Return not ready if DCD0 is HIGH.
  930.         ; 
  931. COSMOD1:    LD    E,TDRE        ; Test transmit buffer status.
  932.         ; Common modem status return - Reg B contains status mask.
  933. CSMRET:        IN0    A,(STAT0)    ; Set DCD0* status...
  934.         IN0    A,(STAT0)    ; ...Read ASCI0 status.
  935.         TST    DCD0        ; Check for DCD0*
  936.         JR    NZ,DCDERR    ; Branch if DCD0* is high.
  937.         AND    E        ; DCD0* is low - test status.
  938.         RET    Z        ; Not ready
  939.         OR    -1        ; Set Acc to -1
  940.         RET            ; Ready.
  941.  
  942. DCDERR:        LD    A,D        ; Get DCD0 action request flag...
  943.         AND    A        ; ...test it...
  944.         RET    Z        ; Return NOT READY if selected.
  945.         ; Otherwise we abort to O/S...
  946.         LD    DE,DCDMSG    ; Display the message...
  947.         LD    C,09H        ; ...via BDOS...
  948.         CALL    BDOS        ; ...
  949.         RST    0        ; Re-boot.
  950.  
  951. ;+
  952. ; Special SB-180 Reader input (returns status or aborts if DCD0 is HIGH).
  953. ;-
  954. CIRDR:        LD    D,-1        ; Abort if DCD0 is HIGH.
  955.         JR    C,CSMOD1    ; Branch, special status check.
  956.         ; Not a special status check - fall through to get a character.
  957. ;+
  958. ; Modem input character
  959. ;-
  960. CIMOD:        CALL    CSMOD        ; Check status
  961.         JR    Z,CIMOD        ; Wait for it.
  962.         ; 
  963.         IN0    A,(RDR0)    ; Read a character
  964.         RET
  965.  
  966. ;+
  967. ; Remote ASCI-0 input (returns either 7 or 8 bit input)
  968. ;-
  969. CIRMT:        CALL    CIMOD        ; Get a character
  970.         AND    IOMASK        ; Select 7/8 bit input...
  971.         RET            ; ...and exit.
  972.  
  973. ;+
  974. ; Special SB-180 Punch status call (No output, returns status or aborts if
  975. ; DCD0 is HIGH thus disabling the ASCI).
  976. ;-
  977. COPUN:        LD    D,-1        ; Abort if DCD0 is HIGH.
  978.         JR    C,COSMOD1    ; Branch, special status check.
  979.         ; Not a special status check - fall through to get a character.
  980. ;+
  981. ; Modem output
  982. ;-
  983. COMOD:        CALL    COSMOD        ; Check status
  984.         JR    Z,COMOD        ; Wait for transmit buffer to empty.
  985.         ; 
  986.         OUT0    (TDR0),C    ; Send the character.
  987.         RET
  988.  
  989. ;**************************************************************************
  990. ;***    Null Devices.                            ***
  991. ;**************************************************************************
  992.  
  993. CSNULL:        OR    -1        ; NULL status returns always READY
  994.         RET            ; Ready
  995.  
  996. CINULL:        LD    A,1AH        ; NULL input returns CP/M EOF.
  997. CONULL:        RET            ; NULL output just returns.
  998.  
  999. ;+
  1000. ; Record Output Routines
  1001. ;
  1002. ; Console Record...
  1003. ;-
  1004. COPEN:        EQU    CSNULL        ; Not implemented...
  1005. CCLOSE:        EQU    CSNULL        ; ...
  1006.  
  1007. ;+
  1008. ; List Record.
  1009. ;-
  1010. LOPEN:        EQU    CSNULL        ; Not implemented...
  1011. LCLOSE:        EQU    CSNULL        ; ...
  1012.  
  1013. ;**************************************************************************
  1014. ;***    Console and Printer Interrupt Service routines.            ***
  1015. ;**************************************************************************
  1016. ;+
  1017. ; Note that neither of these ISRs preserve the state of the users stack
  1018. ; below the stack pointer.  I haven't seen any problems with this or the
  1019. ; amount of stack space that the ISRs use.  However if I wasn't so short
  1020. ; of space in this IOP I would use a seperate stack space for both these
  1021. ; routines as a matter of good coding practice.
  1022. ;-
  1023.  
  1024. ;+
  1025. ; 8-bit Port ISR (Printer).
  1026. ;-
  1027. INTLPT:        PUSH    HL        ; Save Registers...
  1028.         PUSH    AF        ; ...
  1029.         LD    HL,LGCNT    ; Point to "get" count.
  1030.         ; 
  1031.         LD    A,(LPCNT)    ; Read the current "put" count...
  1032.         SUB    (HL)        ; Test for equality w/ "get" count.
  1033.         JR    Z,LISTEMTY    ; Branch, buffer empty.
  1034.         ; Get a char from the buffer and print it.
  1035.         PUSH    BC        ; Save registers...
  1036.         PUSH    DE        ; ...
  1037.         LD    DE,(LGET)    ; Load pointer to get char.
  1038.         LD    A,(DE)        ; Read the char...
  1039.         ; 
  1040.         OUT    (CENTDC),A    ; Latch to the Printer
  1041.         OUT    (CENTDS),A    ; Set STB*
  1042.         OUT    (CENTDC),A    ; Clear STB
  1043.         ; 
  1044.         INC    DE        ; Bump the "get" pointer...
  1045.         DEC    (HL)        ; ...adjust the "get counter".
  1046.         CALL    Z,RESPTRS    ; Wrap pointers if nessesary.
  1047.         LD    (LGET),DE    ; Save "get" pointer
  1048.         POP    DE        ; Restore DE and BC registers...
  1049.         POP    BC        ; ...
  1050.         ; 
  1051.         XOR    A        ; Get a 00
  1052.         ; 
  1053. LISTEX:        LD    (WAITFOR),A    ; Flag ISR status.
  1054.         POP    AF        ; Restore registers...
  1055.         POP    HL        ; ...
  1056.         EI            ; Restore interrupts...
  1057.         RET            ; ...exit, done.
  1058.  
  1059. LISTEMTY:    LD    A,11111111B    ; Set all lines high...
  1060.         OUT    (CENTDC),A    ; ...and clear interrupt.
  1061.         ; Acc = -1 ie list buffer is empty.
  1062.         JR    LISTEX        ; Branch to restore and quit.
  1063.  
  1064. ;+
  1065. ; Console Interrupt Service Routine. Interrupts generated by:-
  1066. ;    1. Incoming character (RDRF).
  1067. ;    2. Receiver overrun (OVRN).
  1068. ;    3. Parity Error (PE).
  1069. ;    4. Framing error (FE).
  1070. ; BREAK generates both overrun and framing error (OVRN AND FE).
  1071. ;-
  1072. INTASCI1:    PUSH    HL        ; Save all the registers...
  1073.         PUSH    DE        ; ...
  1074.         PUSH    BC        ; ...
  1075.         PUSH    AF        ; ...
  1076.         ; Test for errors first.
  1077. INTASCI10:    IN0    A,(STAT1)    ; Get status, check for errors...
  1078.         AND    OVRN+PE+FE    ; ...overrun, parity, framing error.
  1079.         JR    NZ,BREAK    ; Branch if ovrn, pe or fe.
  1080.         ; Get the character that woke us up...
  1081.         IN0    A,(RDR1)    ; Read ASCI1.
  1082.         ; Update the XON/XOFF buffer in case anyone's using it.
  1083.         LD    C,A        ; Save the character in Reg C.
  1084.         CP    XOFF        ; Is it XOFF?
  1085.         CALL    Z,UPDATE_FLG    ; Update flag if XOFF
  1086.         CP    XON        ; Is it XON?
  1087.         CALL    Z,UPDATE_FLG    ; Update flag if XON
  1088.         ; Now save character (if we can)...
  1089.         CALL    PUTONE        ; Save character and do buffer checks.
  1090.         ; Check for characters buffered in ASCI1...
  1091. TYPEX:        IN0    A,(STAT1)    ; Get ASCI1 status...
  1092.         AND    RDRF        ; ...check for buffered chars...
  1093.         JR    NZ,INTASCI10    ; Branch if another char waiting.
  1094.         ; ASCI is empty - restore system state...
  1095.         POP    AF        ; Get all the registers back...
  1096.         POP    BC        ; ...
  1097.         POP    DE        ; ...
  1098.         POP    HL        ; ...
  1099.         EI            ; Turn the interrupts on...
  1100.         RET            ; ...go back to sleep.
  1101.  
  1102.         ; We detected an error flag SET, if ORVN and FE then it's
  1103.         ; a BREAK.  Ignore all errors.
  1104. BREAK:        IN0    A,(CNTLA1)    ; Get ASCI1 control register contents.
  1105.         AND    A,NOT EFR    ; Clear error flag...
  1106.         OUT0    (CNTLA1),A    ; ...
  1107.         IN0    A,(RDR1)    ; ...clear 1 character from buffer.
  1108.         JR    TYPEX        ; Ignore BREAK (I do anyway).
  1109.  
  1110.         ; Acc and Reg C contain an xon or xoff character.
  1111. UPDATE_FLG:    LD    A,(XON_FLAG)    ; Are we using xon/xoff?
  1112.         AND    A        ; ...
  1113.         RET    NZ        ; Quit if not.
  1114.         ; We're doing xon/xoff handshaking.
  1115.         LD    A,XOFF        ; Test the current character...
  1116.         CP    C        ; ...in Reg C for XOFF.
  1117.         JR    Z,SET_XOFF    ; Branch and always SET if xoffs.
  1118.         ; It must be an XON...
  1119.         LD    A,(XON_STATUS)    ; Determine if we are waiting...
  1120.         CP    C        ; ...for an XON (in Reg C).
  1121.         RET    Z        ; Exit, doesn't follow an XOFF.
  1122.         ; Status was XOFF, so we must clear it and flush this XON,
  1123.         ; thus we kill all XOFFs (^S), all XOFF/XON pairs, but allow
  1124.         ; single XONs to pass through (for WordStar).
  1125. SET_XOFF:    LD    A,C        ; Restore Acc contents...
  1126.         LD    (XON_STATUS),A    ; ...save the handshake status...
  1127.         POP    HL        ; Flush the return address from stack
  1128.         JR    TYPEX        ; Exit w/o updating the buffer.
  1129.         
  1130. ;+
  1131. ; Place character from Reg C into the interrupt buffer if there is room.  Check
  1132. ; to see if we're running out of room and if the terminal supports xon/xoff and
  1133. ; the buffer is getting close to overflowing send an xoff to the terminal to
  1134. ; try and stop it.  We send an xoff for each character that arrives after the
  1135. ; buffer high water mark has been reached.  We can't assume that the other end
  1136. ; will respond instantly so there is some headroom allowed in the buffer to
  1137. ; avoid dropping characters if the sender takes a while to respond.
  1138. ;-
  1139. PUTONE:        LD    HL,TYPBUF    ; Get character count...
  1140.         LD    A,(HL)        ; ...
  1141.         INC    A        ; ...and bump it up.
  1142.         CP    BUFLEN*2/3    ; Check for plenty of room...
  1143.         JR    C,PUTONE2    ; ...branch if lots of room.
  1144.         ; Buffer is getting a bit full...
  1145.         CP    BUFLEN        ; Test for no room at all...
  1146.         RET    NC        ; ...and quit buffer overrun.
  1147.         ; Still some room in the buffer...
  1148.         CALL    PUTONE2        ; Save the character if we can.
  1149.         ; See what we can do about current buffer status...
  1150.         LD    A,(XON_FLAG)    ; Does terminal support xon/xoff?...
  1151.         AND    A        ; ...
  1152.         RET    NZ        ; ...quit if no xon/xoff support.
  1153.         ; Terminal supports xon/xoff...
  1154.         LD    (XOFF_OUT),A    ; Flag that we've stopped input...
  1155.         LD    C,XOFF        ; ...and send an xoff to try and...
  1156.         JP    CODEC        ; ...stop the console (returns to caller).
  1157.  
  1158.         ; Buffer has space for next character.
  1159. PUTONE2:    LD    (HL),A        ; Save the new character total...
  1160.         LD    E,A        ; ...and put the count in...
  1161.         LD    D,0        ; ...reg DE as 16 bit value.
  1162.         ADD    HL,DE        ; Point to the next free position...
  1163.         LD    (HL),C        ; ...and stash current character.
  1164.         RET            ; ...exit, done.
  1165.  
  1166. ;**************************************************************************
  1167. ;***    Data Storage                            ***
  1168. ;**************************************************************************
  1169.  
  1170.         ; Key translation table.
  1171. KEY_TABLE:    DEFB    05H,18H,04H,13H    ; ^E ^X ^D ^S Arrow keys.
  1172.  
  1173.         ; Printer control flags.
  1174. WAITFOR        DEFB    -1        ; Printer ISR control.
  1175. COLS        DEFS    1        ; Printer line length control.
  1176.  
  1177.         ; PATCH device addresses.
  1178. CSPTCH:        DEFW    0000        ; Patchable status check pointer.
  1179. CIPTCH:        DEFW    0000        ; Patchable input device pointer.
  1180. COPTCH:        DEFW    0000        ; Patchable output device pointer.
  1181.  
  1182.         ; Console terminal control flags.
  1183. XON_FLAG    DEFS    1        ; -1 for no checks, 0 checks xon/xoff
  1184. XON_STATUS    DEFB    00        ; Input handshake status (^S/^Q).
  1185. XOFF_OUT    DEFB    -1        ; Output handshake status (^S/^Q).
  1186. TOGGLE        DEFB    00        ; Current ASCI-1 interrupt status.
  1187. TERMTYP        DEFS    1        ; Terminal type
  1188. ASCIINT        DEFS    2        ; Adrs of ASCI0 int byte in CONFIG block.
  1189.         
  1190.         ; Printer ISR pointers.
  1191. LPUT:        DEFW    LBUFER        ; Pointer to next free space in buffer.
  1192. LGET:        DEFW    LBUFER        ; Pointer to next character in buffer.
  1193. LPCNT:        DEFB    LSTBLEN        ; Chars left before write pointer wraps.
  1194. LGCNT:        DEFB    LSTBLEN        ; Chars left before read pointer wraps.
  1195.  
  1196.         ; Error message.
  1197. ERRMSG:        DEFZ    'Error '    ; Error message for name string error.
  1198. DCDMSG:        DEFB    'DCD0* abort$'    ; Error message if ASCI0 disabled.
  1199.  
  1200.         ; Use whatever's left for a printer buffer.
  1201. LBUFER        EQU    $        ; Start of List output buffer.
  1202. LSTBLEN        EQU  (IOPS*128)-($-IOP) ; Size of list output buffer (2-255).
  1203.  
  1204. ;**************************************************************************
  1205. ;***    One time notice buried in printer buffer.            ***
  1206. ;**************************************************************************
  1207.  
  1208. SIGNON:        DEFB    ' Version '
  1209.         MVERSN
  1210.         DEFB    ' 3-Sep-1986$'
  1211.         DEFB    "Written by Edmund Cramp "
  1212.         DEFB    "for Synergy Concepts Inc. "
  1213.         DEFB    "Tampa, FL"
  1214.         
  1215. ;**************************************************************************
  1216. ;***    Module size display and check                    ***
  1217. ;**************************************************************************
  1218.  
  1219.     PRINTE    < Space available for SYSIOP .........>,%(IOPS*128)
  1220.  
  1221.     IF    $-IOP GT IOPS*128
  1222.     .PRINTX    * SYSIOP module is too large *
  1223.     ENDIF
  1224.  
  1225.     PRINTE    < Console type-ahead buffer size .....  >,%(BUFLEN)
  1226.     PRINTE    < Printer output buffer size ......... >,%(LSTBLEN)
  1227.  
  1228.     .DEPHASE
  1229.  
  1230.     END
  1231.