; QTERM Version 4.x Patch Area
; 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 Kaypro-II and -4 ('83 version without graphics).  Kaypro
;  (and Xerox BB-I) 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.
;  15-Feb-89, D. Presberg, BCS/BOSKUG.

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

; Modified for Xerox 820-II, 16/8. Clears screen at start, at end, and re-
;  sets alternate video at end; all terminal capabilities supported.
;  By Tim Carney 17-Apr-89.

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

yes     equ     0ffh            ; true value
no      equ     0               ; false value

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

       org     120h
modin:  in      a,(siod)        ;read modem input character (Kaypro data port)
       ret

       org     130h
modost: in      a,(sioc)        ;get modem output status  (Kaypro status port)
       and     04h             ; (result to Z:  bit-2 ... see above)
       ret

       org     140h
modout: out     (siod),a        ;write modem output char. (Kaypro data port)
       ret

       org     150h
sbreak: ld      a,(setf)        ;start "break"
       or      a               ;do we have valid data in r3,r4,r5
       ret     z               ;no - don't do it
       jp      exmlp           ; start break takes a bit extra, see below

       org     160h
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

       org     170h
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     180h
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     190h
setbd:  out     (00h),a         ;set baud rate (value in A) (Kaypro 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.

; Kaypro-II/4 has advertised values for rates up to 19200.  Not all available
;   low speeds are used by QTERM, however.

       org     1a0h
baudtb:

b38400: defb    0,no            ;  38400 baud
b19200: defb    0fh,yes         ;  19200
b9600:  defb    0eh,yes         ;   9600
b4800:  defb    0ch,yes         ;   4800
b2400:  defb    0ah,yes         ;   2400
b1200:  defb    07h,yes         ;   1200
b600:   defb    06h,yes         ;    600
b300:   defb    05h,yes         ;    300 baud
; (Kaypro goes down to 150, 134.5, 110, 75, and 50 baud, but QTERM doesn't.)

       org     1b0h
setmod: ld      (setf),a        ; flag we've done a set
       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     80h             ; mask off the rest
       or      (hl)            ; or in the remainder
       jp      finmod          ; have to finish 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     1c0h
modetb:

n17:    defb    10000000b       ;080h, 7n1
n18:    defb    11000000b       ;0c0h, 8n1
n27:    defb    10001000b       ;088h, 7n2
n28:    defb    11001000b       ;0c8h, 8n2
e17:    defb    10000011b       ;083h, 7e1
e18:    defb    11000011b       ;0c3h, 8e1
e27:    defb    10001011b       ;08bh, 7e2
e28:    defb    11001011b       ;0cbh, 8e2
o17:    defb    10000001b       ;081h, 7o1
o18:    defb    11000001b       ;0c8h, 8o1
o27:    defb    10001001b       ;089h, 7o2
o28:    defb    11001001b       ;0c9h, 8o2

       org     1cch
smlbuf: defb    no      ; set this 'yes' if you run out of ram - this feature
                       ; is not yet implemented, but in time (i.e. V4.1)
                       ; it will be. QTERM is a real memory hog - it needs
                       ; well in excess of 48K TPA. If you have a full blown
                       ; Z-system with oodles of RSX additions, you may
                       ; run out of space. By setting this true, you can get
                       ; QTERM to shrink some buffers and fit itself into
                       ; about 42K, the price paid is somewhat more
                       ; frequent disk access when reading and writing files.

       org     1cdh
xfersz: defb    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     1ceh
speed:  defb    4       ;cpu speed (Mhz; use 3 for 2.5, 4 for Xerox).
                       ; (5Mhz Assumes Advent speedup kit in Kaypro.)

       org     1cfh
escape: defb    1bh     ;escape character (1ch=^\  Control-Backslash)
                       ;use 1bh (^[=ESC) for Xerox.
       org     1d0h
signon:                 ;signon message
       defb    '(Xerox 16/8 1984) '
       defb    0

       org     1f0h
clrs:   defb    1ah     ;clear screen string (Control-Z)
       defb    0

scrout  equ     109h    ;(a routine to print to CON: the
                       ;   character in C)
decout  equ     10ch    ;(a routine to print to CON: a decimal value
                       ;   in HL.  Is available for VT100 and the like.)

       org     200h
moveto: push    hl      ;move cursor to position in HL (Row,Col)
       ld      c,1bh   ; 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.

b_brit  equ     00000001b       ; 0: bright (1.)        -- NOT mandatory
b_dim   equ     00000010b       ; 1: dim    (2.)        -- NOT mandatory
b_dlln  equ     00000100b       ; 2: delete line (4.)   -- important
b_inln  equ     00001000b       ; 3: insert line (8.)   -- important
b_dlch  equ     00010000b       ; 4: delete character (16.)-- unused by QTERM
b_inch  equ     00100000b       ; 5: insert character (32.)-- NOT mandatory
b_clel  equ     01000000b       ; 6: clear to end-of-line(64.) -- important
b_cles  equ     10000000b       ; 7: clear to end-of-screen(128.)-- important

       org     22fh
tcbits: defb    0ffh            ; capability bits- all functions supported
                               ; by Xerox.

; (Kaypro-II/4, non-graphics version, cannot do in-place insertion or deletion
;   of single characters:  it can only overwrite characters at the current
;   cursor position and move the cursor non-destructively, etc..  It can
;   do in-place insertion and deletion of lines, and its clear-to-end-of-
;   -screen and -line leaves the cursor as-is.  It also has clear-screen-and-
;   -home-the-cursor: see clrs, above.  It, of course, has no graphical screen
;   attributes, such as bright and dim.)

       org     230h
brites: defb    27              ;bright string (none for '83 Kaypro)
       defb    40              ;Xerox ESC-(, alternate video disable
       defb    0               ;code.

       org     238h
dims:   defb    27              ;dim string    (none for '83 Kaypro)
       defb    41              ;Xerox ESC-) ESC-8 (enable alternate
       defb    27              ;video,set to dim characters).
       defb    56
       defb    0



       org     240h
dlstr:  defb    1bh     ;delete line
       defb    'R'
       defb    0

       org     248h
ilstr:  defb    1bh     ;insert line
       defb    'E'
       defb    0

       org     250h
dcstr:  defb    27      ;delete character (none for '83 Kaypro)
       defb    'W'     ;Xerox ESC-W del character string.
       defb    0

       org     258h
icstr:  defb    27      ;insert character (none for '83 Kaypro)
       defb    'Q'     ;Xerox ESC-Q ins character string.
       defb    0


       org     260h
ceol:   defb    18h     ;clear to end of line (Control-X)
       defb    0

       org     268h
ceos:   defb    17      ;clear to end-of-screen (Control-W)
       defb    0       ;Xerox uses CTRL-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     270h
entry:  jp      do_ent          ; entry hook (270h .. 272h)



       org     273h            ; exit hook  (273h .. 275h)
exit:   jp      do_exit         ; Exit routine-Xerox 820-II, 16/8.

; Extra patch area if needed.  276h .. 2ffh

       org     276h
patcha:

do_ent: ld      c,26            ;Send clear screen and home cursor
       call    scrout          ;to console...
       jp      start

start:  ld      a,(b1200)       ; entry hook (from 270h)
       call    setbd           ;   Kaypro-II/4 setup for 1200 baud
       ld      a,(n18)         ; and 8n1 communications mode.
       call    setmod
       ret

exmlp:  ld      a,1             ; wait till transmitter is really finished
       out     (siod),a
       in      a,(siod)
       rra
       jr      nc,exmlp        ; loop till buffer empty
       ld      hl,r5
       set     4,(hl)          ; now go set the break bit.

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

finmod: ld      (hl),a          ; and save it back
       inc     hl
       inc     hl              ; point hl at r4
       ld      a,(hl)
       and     0f4h            ; mask out bits we don't want
       ld      b,a             ; save in b
       ld      a,c             ; get set byte back
       and     0bh             ; 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     40h             ; 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
       jp      sioout          ; go send the values

siodat: defb    3
r3:     defb    11000001b       ; value for wr3 (0c1h)
       defb    4
r4:     defb    01000100b       ; value for wr4 (044h)
       defb    5
r5:     defb    11101010b       ; value for wr5 (0e5h)

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

       org     02c5h
do_exit:
       ld      c,26            ; Xerox specific.Clear screen, home cursor
       call    scrout
       ld      c,27            ; Change alternate video mode to inverse.
       call    scrout          ; (52 or 54=blink, 53=graphics, 55=inverse
       ld      c,55            ; 56=dim).
       call    scrout
       ret

       end