; QTO-HP1C.ASM - QTERM Overlay for Hewlett-Packard HP-125 Computer
;
; Author: Mike Freeman 17-Apr-89
; 301 N.E. 107th Street; Vancouver, Wa 98685; (206)574-8221
;
; See QTERM.PAT for documentation of QTERM's patch area
;
; I claim no copyright on this overlay; as a road-sign in Oklahoma
; once said:  "No Speed Limit -- Do Your Damnedest"
;
; The program QTERM is Copyright 1989 by DPG (David Goodenough)
;
; Revised 04/19-89 to save/restore all Z80 registers (including IX and IY)
; during BDOS calls; Ymodem Batch transfers now work -- Mike Freeman
; Revised 04/25/89 to home cursor/clear screen upon QTERM entry/exit
; Also made Z80-specific code more obvious by commenting in Zilog instructions
; -- Mike Freeman --
; Revised 04/26/89 to map/unmap RDR/PUN last to avoid escape sequences
; showing up/not being interpreted properly after QTERM exits if the HP-125
; has been placed in Remote Mode -- Mike Freeman
; Revised 04/28/89 to trim screen-clearing code at startup/exit -- Mike Freeman
;
;This overlay adapts QTERM.COM from QTERMxxx.LBR to run on the Hewlett-Packard
;HP-125 Series 100 Business Computer running a HP-modified CP/M Version 2.2
;operating system.  This overlay is a full QTERM implementation except that:
;(1) Break is not implemented (a Break can be sent from the Keyboard only);
;(2) The DTR-manipulation/modem hangup routines are not implemented; (3) The
;routine to change Baud-rate is not implemented (this is changed from the
;Keyboard's Configuration Menu); (4) Stop-bit manipulation is not implemented
;(HP gives the user no way to do this) and (5) changing of parity is not
;implemented (this is also changed from the Configuration Menu).  The Hp-125
;consists of 2 Z80 processors: one is the CPU and the other handles terminal
;I/O.  HP does not allow the user to access the Z80 I/O ports directly.
;However, HP does provide the CP/M Reader and Punch BDOS calls along with
;a "subfunction" call (passed in BC) to get Reader status.  When properly
;mapped, the Reader takes input from Datacomm Port 1 and the Punch sends output
;to Datacomm Port 1.  All data is in the form 8N1 and special provisions must
;be made to insure that all 8 bits of data are sent/received by DAtacomm 1.
;(Datacomm 2, the Printer Port, can only accommodate 7-bit data).  Device
;mapping of Reader/Punch to Datacomm Port 1 is accomplished by sending a series
;of escape sequences to the HP-125's Console (rather than using the IO byte).
;
;To assemble QTO-HP1C.ASM using ASM:
;A>ASM QTO-HP1C

;To produce the modified QTERM.COM ready for use with the HP-125 using MLOAD:
;A>MLOAD QTO-HP1=QTERM.COM,QTO-HP1C.HEX
;
;
; Parameters
;
HAYES   EQU     000H            ;Nonzero means HAYES-style hang-up string
;
;BDOS equates
;
BOOT    EQU     0               ;CP/M Warm-start
RDR     EQU     3               ; Reader input
PUN     EQU     4               ; Punch output
BDOS    EQU     5               ; BDOS entry
DCONIO  EQU     6               ;Direct Console I/O
PRT     EQU     9               ; Print "$"-terminated string to Console
;
;Special HP subfunctions
;
RDRSTS  EQU     70FFH           ; Get Reader status (A nonzero if char ready)
BITS8   EQU     73FFH           ; Set Datacomm 1 to pass 8-bit data
BITS7   EQU     74FFH           ; Set Datacomm 1 to allow only 7-bit data
JVT     EQU     7EFFH           ; Jump-vector (BIOS routine address) transfer
;
;Ascii equates
;
ESC     EQU     1BH             ; <ESC>
;
;Routine addresses
;
CONOUT  EQU     0109H           ; Character in C to Console
DECOUT  EQU     010CH           ; Number in HL to Console in decimal
;
       ORG     0110H           ; Overlay starts here
;
;Get modem (Reader) status
;
       PUSH    B               ;Protect BC
       LXI     B,RDRSTS        ; Set subfunction call to
       CALL    ENTRY           ; Get Reader status
       POP     B               ;Restore registers
       RET                     ; And return
       DS      120H-$ AND 0FFH
;
;Get modem character into A
;
       PUSH    B               ;Save BC
       MVI     C,RDR           ; Set function call to
       CALL    ENTRY           ;Get character
       POP     B               ;Restore BC
       RET                     ;and return
       DS      130H-$ AND 0FFH
;
;Get Punch status (always true)
;
       XRA     A               ;Set Z
       INR     A               ;Clear Z
       RET                     ; And return
       DS      140H-$ AND 0FFH
;
;Send character in A to Punch
;
       PUSH    PSW             ;Save registers
       PUSH    B               ;...
       PUSH    D               ;...
       MOV     E,A             ; Put character in E
       MVI     C,PUN           ; Set function call to
       CALL    ENTRY           ;Send character
       POP     D               ;Restore registers
       POP     B               ;...
       POP     PSW             ;...
       RET                     ;and return
       DS      150H-$ AND 0FFH
;
;Set Break (not implemented)
;
       RET                     ; ...
       DS      160H-$ AND 0FFH
;
;Clear break (not implemented)
;
       RET                     ; ...
       DS      170H-$ AND 0FFH
;
;Kill DTR routines/modem hang-up string (not implemented)
IF HAYES
;
       RET                     ;Modem hangup string follows
       DB      10,0FEH,'+++',0FEH,'ATH0',0DH
;
ENDIF ; HAYES
;
IF NOT HAYES
;
;
       DB      0,0C9H          ; ...
;
ENDIF ;NOT HAYES
;
       DS      180H-$ AND 0FFH
;
;Restore DTR (not implemented)
;
       RET                     ; ...
       DS      190H-$ AND 0FFH
;
;Baud-rate setting routine (not implemented
;
       RET                     ; ...
       DS      1B0H-$ AND 0FFH
;
;Set Parity/Stop-bits (not implemented)
;
       RET                     ; ...
       DS      1CCH-$ AND 0FFH
;
       DS      1               ;Reserved for future use
;
       DS      1               ; Transfer size
;
       DB      4               ; Processor speed in mHz
;
       DB      '\'-40H         ; Escape character
;
       DB      'HP-125 Series 100',0 ; Sign-on id
       DS      1F0H-$ AND 0FFH
;
HOMCLR: DB      ESC,'H',ESC,'J',0 ; Home cursor/clear screen
       DS      200H-$ AND 0FFH
;
;MOVETO - Place cursor in row/column H/L
;
MOVETO: PUSH    H               ; Save row/column
       MVI     C,ESC           ; Send cursor leadin
       CALL    CONOUT          ; ...
       MVI     C,'&'           ; ...
       CALL    CONOUT          ; ...
       MVI     C,'A'+20H       ; ...
       CALL    CONOUT          ; ...
       POP     H               ; Get row/column
       PUSH    H               ; Save again
       MOV     L,H             ; Get row
       MVI     H,0             ; Make 16-bit integer
       CALL    DECOUT          ; Type in decimal to Console
       MVI     C,'R'+20H       ; Say it was a row
       CALL    CONOUT          ; ...
       POP     H               ; Get row/column
       MVI     H,0             ; Isolate column as 16-bit integer
       CALL    DECOUT          ; Type in decimal
       MVI     C,'C'           ; Terminate sequence - column
       JMP     CONOUT          ; And return
       DS      22FH-$ AND 0FFH
;
       DB      0FFH            ; Terminal capabilities (all)
;
       DB      ESC,'&@',0,0,0,0,0 ; Enhancement off
       DB      ESC,'&F',0,0,0,0,0 ; Enhancement on
       DB      ESC,'M',0,0,0,0,0,0 ; Delete line
       DB      ESC,'L',0,0,0,0,0,0 ; Insert line
       DB      ESC,'P',0,0,0,0,0,0 ; Delete character
       DB      ESC,'R',20H,ESC,'Q',08H,0,0 ; Insert character
       DB      ESC,'K',0,0,0,0,0,0 ; Clear to end-of-line
       DB      ESC,'J',0,0,0,0,0,0 ; Clear to end-of-screen
;
;
       JMP     INIT            ; Initialization
       JMP     FINISH          ; Termination
;
;Initialization code
;
INIT:   LXI     D,JBUF          ; Point to dispatch vector address arg block
       LXI     B,JVT           ; Set subfunction call to
       CALL    BDOS            ; Get Reader input routine address
       LHLD    JBUF+3          ; Remember this address
       SHLD    READ8+1         ; For 8-bit Reader routine
       LXI     H,READ8         ; Put this address in BIOS dispatch table
       LXI     B,BITS8         ; Set up to set 8-bit passthru
                               ; And fall into common code
;
COMCOD: PUSH    B               ; Save passthru function code
       SHLD    JBUF+3          ; Put BIOS dispatch address in arg block
       MVI     A,1             ; Say we want to write into dispatch table
       STA     JBUF+1          ; ...
       LXI     D,JBUF          ; Point to jump vector argument block
       LXI     B,JVT           ; Set subfunction call to
       CALL    BDOS            ; Write routine address into dispatch table
       LXI     H,HOMCLR        ;Start/end with a clean screen
       MVI     B,4             ;4 characters in the escape sequence
COMCO0: MOV     E,M             ;Get character from escape sequence
       INX     H               ;Increment pointer
       MVI     C,DCONIO        ;Send character directly to the Console
       CALL    ENTRY           ;...
;       DJNZ    COMCO0          ;Get all characters
       DB      10H,COMCO0-$-1 AND 0FFH;...
       POP     B               ; Get passthru code
       CALL    BDOS            ;Set Passthru
       LXI     D,MAPSEQ        ; Send mapping escape sequences
       MVI     C,PRT           ; To the Console
       JMP     BDOS            ; To do/undo Reader/Datacomm Port 1 mappings
                               ;and return
;
;Final (exit) code
;
FINISH: LHLD    READ8+1         ; Point to real Reader input address
       LXI     B,BITS7         ; Set for 7-bit terminal passthru
       MVI     A,'9'           ; Set to turn off Datacomm mappings
       STA     MAPSEQ+8        ; ...
       STA     MAPSEQ+19       ; ...
;       JR      COMCOD          ; And branch to common code
       DB      18H,COMCOD-$-1 AND 0FFH;...
;
;Routine to read 8-bit data from Datacomm Port 1
;
READ8:  CALL    $-$             ; Read data
       MOV     A,B             ; Get 8-bit data
       RET                     ; And return
;
;Put BIOS routine address vector block here
;
JBUF:   DB      7,0,0C3H,0,0    ; ...
;
;Escape sequence string to map Reader/Punch to Datacomm Port 1
;
MAPSEQ: DB      ESC,'&i0s25d2M' ; Map Datacomm 1 to Reader
       DB      ESC,'&i10s16d2M$' ; And Punch to Datacomm 1
;
;ENTRY - Save/restore registers BC-IY and call BDOS
;
ENTRY:  PUSH    B               ;Save registers
       PUSH    D               ;...
       PUSH    H               ;...
       DB      0DDH,0E5H       ;PUSH IX
       DB      0FDH,0E5H       ;PUSH IY
       CALL    BDOS            ;Do BDOS call
       DB      0FDH,0E1H       ;Restore registers - POP IY
       DB      0DDH,0E1H       ;POP IX
       POP     H               ;...
       POP     D               ;...
       POP     B               ;...
       RET                     ;and return
;
       END                     ; End of overlay