; QTERM Version 4.2 Patch Area.

; This is an example of the Xerox patch code. It is included because
; it uses a SIO for serial communications, and can be changed to work
; with any other SIO / DART system with very little work. All that is
; needed is to disable the baud rate code, modify the terminal depen-
; dancy stuff, and alter siod and sioc to match the port addresses of
; the SIO (data and control) as needed, and it should work.

; This should be assembled with ZSM (available on all fashionable BBS's)
; like this:
; A>ZSM QT-XEROX
; and installed with ZPATCH:
; A>ZPATCH QTERM QT-XEROX

;======================================================================

; This is a ZSM version of the more generic QTERMPAT.AZM generated by
; D. Presberg & D. Goodenough

; Code as adapted from QTERM.COM from QTERM33A.LBR posted by David Goodenough
;  to BOSKUG RCP/M circa 12/27/88, and QTERM Vers. 4.x patch listing 8-Feb-89.

; D. Presberg dissasembled this with Z8E, 21-Jan-89.  Code labels taken from
;  D. Goodenough "qterm.z" example circa 8-Feb-89.

; This edit is for Xerox 820-II and 16/8. These use an SIO chip, port A, with a
;separate baud rate generator:  status port at 04, data port at 06, baud rate
;port at 0.
;  19-Feb-90, T. Carney, BCS/BOSKUG.

; D. Goodenough added break, dtr and mode stuff  2-23-89

; D. Goodenough upgraded to V4.2 (larger patch area, and more functions)

var     sioc    6               ; sio control port
var     siod    4               ; sio data port

var     rxrdy   1               ; receiver ready
var     txrdy   4               ; transmitter ready

var     baud    0               ; baud rate port

var     yes     0xff            ; true value
var     no      0               ; false value


org     0x0110
modist: in      a,(sioc)        ;get modem input status  (Xerox status port)
       and     rxrdy           ; (result to Z:   no inp. character available
       ret                     ;   is 0 at bit-0 (low order) ===>   Z==1    )

org     0x0120
modin:  in      a,(siod)        ;read modem input character (Xerox data port)
       ret

org     0x0130
modost: in      a,(sioc)        ;get modem output status  (Xerox status port)
       and     txrdy           ; (result to Z:  bit-2 ... see above)
       ret

org     0x0140
modout: out     (siod),a        ;write modem output char. (Xerox data port)
       ret

org     0x0150
sbreak: ld      a,(setf)        ;start "break"
       or      a               ;do we have valid data in r3,r4,r5
       ret     z               ;no - don't do it
       ld      hl,r5
       set     4,(hl)          ; set the bit
       jp      sioout          ; and go do it

org     0x0160
ebreak: ld      a,(setf)        ;end "break"
       or      a
       ret     z               ; don't do it unless r3, r4, r5 are valid
       ld      hl,r5
       res     4,(hl)
       jp      sioout          ; go clear the bit

org     0x0170
dtroff: ld      a,(setf)        ;drop DTR
       or      a
       ret     z               ; don't do it unless r3, r4, r5 are valid
       ld      hl,r5
       res     7,(hl)
       jp      sioout

org     0x0180
dtron:  ld      a,(setf)        ;raise DTR
       or      a
       ret     z               ; don't do it unless r3, r4, r5 are valid
       ld      hl,r5
       set     7,(hl)
       jp      sioout

org     0x0190
setbd:  out     (baud),a        ;set baud rate (value in A) (Xerox baud
       ret                     ;rate port)

; The Baud Rate Table has entries from 38400 baud down to 300 baud.
;   There are 2 bytes per entry.  The second byte determines if the entry is
;   enabled or disabled (ffh=enabled; 00=disabled).  The first byte is passed
;   as the A value to the setbd subroutine.

; Xerox 820-II, 16/8 have advertised values for rates up to 19200.  Not all
; available low speeds are used by QTERM, however.

org     0x01a0

baudtb:
b38400: db      0,no            ;  38400 baud
b19200: db      0xf,yes         ;  19200
b9600:  db      0xe,yes         ;   9600
b4800:  db      0xc,yes         ;   4800
b2400:  db      0xa,yes         ;   2400
b1200:  db      7,yes           ;   1200
b600:   db      6,yes           ;    600
b300:   db      5,yes           ;    300 baud


org     0x01b0
setmod: ld      (setf),a        ; flag we've done a set
       jp      domod           ; have to do this elsewhere

; Communication Mode Table.  Single byte values for 12 combinations of
;    number-of-bits(7/8), parity(none/even/odd), number-of-stop-bits(1/2).

org     0x1c0

modetb:
n17:    db      0b10000000      ;0x80, 7n1
n18:    db      0b11000000      ;0xc0, 8n1
n27:    db      0b10001000      ;0x88, 7n2
n28:    db      0b11001000      ;0xc8, 8n2
e17:    db      0b10000011      ;0x83, 7e1
e18:    db      0b11000011      ;0xc3, 8e1
e27:    db      0b10001011      ;0x8b, 7e2
e28:    db      0b11001011      ;0xcb, 8e2
o17:    db      0b10000001      ;0x81, 7o1
o18:    db      0b11000001      ;0xc8, 8o1
o27:    db      0b10001001      ;0x89, 7o2
o28:    db      0b11001001      ;0xc9, 8o2

org     0x01cc
resrvd: db      0       ; reserved for future use

org     0x01cd
xfersz: db      8       ;number of K to read/write during file xfers
                       ;Must be 1 / 2 / 4 / 8.  Best left as 8 unless
                       ;  disk is verrrrry slow.  Drop to smaller value
                       ;  if too many timeouts occur during "protocol"
                       ;  file transfers (xmodem or kermit).

org     0x01ce
speed:  db      4       ;cpu speed (Mhz; use 4 for Xerox)

org     0x01cf
escape: db      '\e'            ;escape character (1bh=^[  Escape)

org     0x01d0
signon:                 ;signon message
       db      '\e(Xerox 16/8 1984\e)\0'       ;Puts message in normal video.

org     0x01f0
clrs:   db      'z' & 0x1f, 0   ;clear screen string (Control-Z)

var     scrout  0x0109  ;(a routine to print to CON: the
                       ;   character in C)
var     decout  0x010c  ;(a routine to print to CON: a decimal value
                       ;   in HL.  Is available for VT100 and the like.)

org     0x0200
moveto: push    hl      ;move cursor to position in HL (Row,Col)
       ld      c,'\e'  ; lead-in with Esc (the ASCII one; not QTERM's)
       call    scrout
       ld      c,'='   ; 2nd lead-in is '='
       call    scrout
       pop     hl
       push    hl
       ld      a,h     ; row value (top row is 0.)
       call    poff    ; add offset and send it to screen
       pop     hl
       ld      a,l     ; col value (leftmost col is 0.)
poff:   add     a,' '   ; (adds 20h)
       ld      c,a
       jp      scrout  ; (scrout returns from 'moveto's call)

; Terminal Capability Bits.  The eight bits stand for each of the following
;   strings.   They count from 01h=bright to 80h=clear-to-end-of-screen.

var     b_brit  0b00000001      ; 0: bright (1.)        -- NOT mandatory
var     b_dim   0b00000010      ; 1: dim    (2.)        -- NOT mandatory
var     b_dlln  0b00000100      ; 2: delete line (4.)   -- important
var     b_inln  0b00001000      ; 3: insert line (8.)   -- important
var     b_dlch  0b00010000      ; 4: delete character (16.)-- unused by QTERM
var     b_inch  0b00100000      ; 5: insert character (32.)-- NOT mandatory
var     b_clel  0b01000000      ; 6: clear to end-of-line(64.) -- important
var     b_cles  0b10000000      ; 7: clear to end-of-screen(128.)-- important

org     0x022f
tcbits: db      0xff            ; capability bits: full support

org     0x0230
brites: db      '\e(\0'         ;bright string (disable alternate video)

org     0x0238
dims:   db      '\e)\0'         ;dim string (enable alternate video)

org     0x0240
dlstr:  db      '\eR\0'         ;delete line (Esc-R)

org     0x0248
ilstr:  db      '\eE\0'         ;insert line (Esc-E)

org     0x0250
dcstr:  db      '\eW\0'         ;delete character (Esc-W))

org     0x0258
icstr:  db      '\eQ\0'         ;insert character (Esc-Q)

org     0x0260
ceol:   db      'x' & 0x1f, 0   ;clear to end of line (Control-X)

org     0x0268
ceos:   db      'q' & 0x1f, 0   ;clear to end-of-screen (Control-Q)

; Entry and Exit hooks.  These are provided to perform custom initialisation
; on startup and on exit from QTERM.  They are invoked before any use is made
; of the screen or the port hardware.

org     0x0270
entry:  jp      do_ent          ; entry hook (270h .. 272h)

org     0x0273                  ; exit hook  (273h .. 275h)
exit:   jp      do_exit

org     0x0276
user:   ret                     ; user subroutine (276h .. 278h)

org     0x0279                  ; keyboard map routine  (279h .. 27bh)
kbmap:  ret

var     ilprmt  0x027c          ; inline prompt routine lives at 27ch

; Extra patch area if needed.  280h .. 4ffh

org     0x0280
patcha:

do_ent: ld      c,'z' & 0x1f    ; Clear screen and home cursor.
       call    scrout
       ld      c,'\e'          ; Send 'Esc'...
       call    scrout
       ld      c,'8'           ; '8' to screen (set dim video mode)
       call    scrout          ; (blink=4 or 6, graphics=5, inverse=7,
                               ; dim=8.
       ld      a,(b1200)       ; entry hook (from 270h)
       call    setbd           ;   Xerox setup for 1200 baud
       ld      a,(n18)         ; and 8n1 communications mode.
       call    setmod
       ret

domod:  ld      c,a             ; save byte in c
       ld      hl,r3           ; look at byte for wr3
       res     7,(hl)          ; turn off ms bit (Rx # bits / char)
       add     a,a             ; move bit from 6 to 7 in a
       and     0x80            ; mask off the rest
       or      (hl)            ; or in the remainder
       ld      (hl),a          ; and save it back
       inc     hl
       inc     hl              ; point hl at r4
       ld      a,(hl)
       and     0xf4            ; mask out bits we don't want
       ld      b,a             ; save in b
       ld      a,c             ; get set byte back
       and     0x0b            ; get bits out of set byte that we want
       or      b               ; or in the other bits
       ld      (hl),a          ; and save it back
       inc     hl
       inc     hl              ; point hl at r5
       ld      a,c
       and     0x40            ; get the bit we want from c
       res     6,(hl)          ; clear the bit in r5
       or      (hl)
       ld      (hl),a          ; put new composite value back

sioout: ld      hl,siodat
       ld      bc,6 * 256 + sioc
       otir
       ret

siodat: db      3
r3:     db      0b11000001      ; value for wr3 (0xc1)
       db      4
r4:     db      0b01000100      ; value for wr4 (0x44)
       db      5
r5:     db      0b11101010      ; value for wr5 (0xe5)

setf:   db      0               ; flag if we've done a set mode command

do_exit:
       ld      c,'z' & 0x1f    ; Clear screen and home cursor...
       call    scrout
       ld      c,'f' & 0x1f    ; and restore original video mode
       call    scrout
       ret

; MUST end by 4ffh