DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T m

⟦8b4444c57⟧ TextFile

    Length: 31592 (0x7b68)
    Types: TextFile
    Names: »msxhp1.asm«

Derivation

└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit
    └─⟦71044c191⟧ »EurOpenD3/misc/kermit.ms-2.32.tar.Z« 
        └─⟦31f2d420d⟧ 
            └─⟦this⟧ »msxhp1.asm« 

TextFile

        name msxhp1
; File MSXHP1.ASM
; System dependent module for HP150.
; Use with file MSUHP1.ASM (keyboard translator)
; Last edit: 12 June 1988
; 1 July 1988 Version 2.31
; 11 Jan 1988 update to 2.30 consistency level.
; 1 Jan 1988 version 2.30

        public  serini, serrst, clrbuf, outchr, coms, vts, vtstat, dodel, ctlu
        public  cmblnk, locate, prtchr, dobaud, clearl, lclini
        public  dodisk, getbaud, beep, setkhlp, setktab
        public  machnam, xofsnt, term, poscur, termtb, shomodem, getmodem
        public  clrmod, putmod, puthlp, sendbr, sendbl, showkey, pcwait
        public  ihosts, ihostr, dtrlow, serhng, dumpscr, comptab
        public  chrout, cstatus, cquit
        public  cquery, trnprs, snull, klogon, klogof, kdos

        include mssdef.h

false   equ     0
true    equ     1
instat  equ     6
print_out equ   05h                     ; dos function to print to printer
prtscr  equ     80h                     ; print screen pressed

wrdev   equ     40H
rddev   equ     3fH
open    equ     3dH
close   equ     3eH
rdchan  equ     2
e_send_break equ 6
e_ioctl equ     44h             ; DOS i/o control function
passall equ     0803h           ; Port transparency mode [WHM]

datas   segment public 'datas'
        extrn   drives:byte, flags:byte, trans:byte
        extrn   portval:word, port1:byte, port2:byte, dmpname:byte
        extrn   kbdflg:byte, rxtable:byte

machnam db      'HP-150$'
erms20  db      cr,lf,'?Warning: System has no disk drives$'
erms40  db      cr,lf,'?Warning: Unrecognized baud rate$'
erms41  db      cr,lf,'?Warning: Cannot open com port$'
noimp   db      cr,lf,'Command not implemented.$'
hngmsg  db      cr,lf,' The phone should have hungup.',cr,lf,'$'
hnghlp  db      cr,lf,' The modem control lines DTR and RTS for the current'
        db      ' port are forced low (off)'
        db      cr,lf,' to hangup the phone. Normally, Kermit leaves them'
        db      ' high (on) when it exits.'
        db      cr,lf,'$'
msmsg1  db      cr,lf,' Communications port is not ready.$'
msmsg2  db      cr,lf,' Communications port is ready.$'
rdbuf   db      80 dup (?)      ; temp buf
setktab db      0
setkhlp db      0
shkmsg  db      '?Not implemented.'
shklen  equ     $-shkmsg
crlf    db      cr,lf,'$'
delstr  db      BS,BS,'  ',BS,BS,'$'    ; Delete string
clrlin  db      cr,ESCAPE,'K$'
xofsnt  db      0               ; Say if we sent an XOFF
xofrcv  db      0               ; Say if we received an XOFF
invseq  db      ESCAPE,'&dB$'   ; Reverse video
nrmseq  db      ESCAPE,'&d@$'   ; Normal mode
ivlseq  db      80 dup (' '),ESCAPE,'A','$' ; [ak] Make a line inverse video
tmp     db      ?,'$'
temp    dw      0
temp1   dw      ?               ; Temporary storage
temp2   dw      ?               ; Temporary storage

; Entries for choosing communications port

comptab db      4                       ; four entries
        mkeyw   '1',1
        mkeyw   '2',2
        mkeyw   'COM1',1
        mkeyw   'COM2',2

termtb  db      tttypes                 ; entries for Status, not Set
        mkeyw   'Heath-19',ttheath
        mkeyw   'none',ttgenrc
        mkeyw   'Tek4014',tttek
        mkeyw   'VT102',ttvt100
        mkeyw   'VT52',ttvt52

; variables for serial interrupt handler

source  db      bufsiz DUP(?)   ; Buffer for data from port
bufout  dw      0               ; buffer removal ptr
count   dw      0               ; Number of chars in int buffer
bufin   dw      0               ; buffer insertion ptr
telflg  db      0               ; Are we acting as a terminal
clreol  db      ESCAPE,'K$'
prttab  dw      com1,com2       ; rationalized by [jrd]
com1    db      'COM1',0
com2    db      'COM2',0
blank   db      ESCAPE,'H',ESCAPE,'J$'
movcur  db      ESCAPE,'&a'
colno   db      20 dup (?)
ten     db      10
prthnd  dw      0
argadr  dw      ?               ; address of arg blk from msster.asm
parmsk  db      ?               ; 8/7 bit parity mask, for reception
flowoff db      ?               ; flow-off char, Xoff or null (if no flow)
flowon  db      ?               ; flow-on char, Xon or null
captrtn dw      ?               ; routine to call for captured output
tempbuf dw      10 dup(?)
ourarg  termarg <>
datas   ends

code    segment public 'code'
        extrn   comnd:near, dopar:near, prserr:near, atoi:near, prompt:near
        extrn   sleep:near
        extrn   msuinit:near, keybd:near                ; in msuhp1.asm
        assume  cs:code, ds:datas, es:nothing

; See how many disk drives we have
DODISK  PROC    NEAR
        mov ah,gcurdsk                  ; Current disk value to AL
        int dos
        mov dl,al                       ; Put current disk in DL
        mov ah,seldsk                   ; Select current disk
        int dos                         ; Get number of drives in AL
        mov drives,al
        ret
DODISK  ENDP

; Clear the input buffer before sending a packet

CLRBUF  PROC    NEAR
        cli
        mov ax,offset source
        mov bufin,ax
        mov bufout,ax
        mov count,0
        sti
        cmp prthnd,0            ; have a port handle yet?
        jne clrb1               ; ne = yes, read chars
        ret                     ; else just return
clrb1:  call prtchr             ; get a character
         jmp clrb1              ; until there aren't any more
         nop
        ret
CLRBUF  ENDP

; Common routine to clear to end-of-line

CLEARL  PROC    NEAR
        push    ax              ; save regs
        push    dx
        mov     dx,offset clreol
        mov     ah,prstr
        int     dos
        pop     dx              ; restore regs
        pop     ax
        ret
CLEARL  ENDP

dobaud  proc    near            ; updated by [jrd] to set baud
        mov ah,prstr
        mov dx,offset noimp     ; Say it's not implemented
        int dos
        push bx                 ; save reg
        mov bx,portval
        mov [bx].baud,0FFFFH    ; So it's not a recognized value
        pop bx
        ret                     ; Must be set before starting Kermit
dobaud  endp

; Send the break signal out data comm
sendbl:                                 ; long break (same as regular here)
sendbr: mov     al,e_send_break         ; regular break
        call    dc_ioctl
        clc                             ; clear carry bit (stay in Connect)
        ret

; Set some data comm ioctl option.  AL has function code
dc_ioctl proc   near
        push    ax                      ; save regs
        push    bx
        push    cx
        push    dx
        mov     ah,8h
        mov     tempbuf,ax
        mov     dx,offset tempbuf
        mov     ah,e_ioctl
        mov     al,3
        mov     bx,prthnd
        mov     cx,2
        int     dos
        pop     dx                      ; restore regs
        pop     cx
        pop     bx
        pop     ax
        ret
dc_ioctl endp

shomodem proc   near
        mov     ah,cmcfm        ; get a confirm
        call    comnd
         jmp    r               ; no confirm
         nop
        cmp     prthnd,0        ; Got a handle yet?
        jne     shmod0          ; Yup just go on
        call    opnprt          ; Else 'open' the port
shmod0: mov     dx,offset msmsg1 ; say port is not ready
        mov     bx,prthnd
        mov     al,7            ; output status command
        mov     ah,ioctl        ; ask DOS to look for us
        int     dos
        jc      shmod1          ; c = call failed, device not ready
        or      al,al
        jz      shmod1          ; not ready
        mov     dx,offset msmsg2 ; say port is ready
shmod1: mov     ah,prstr
        int     dos
        jmp     rskp
shomodem endp

getmodem proc near
        mov     al,0
        ret
getmodem endp

; Put the char in AH to the serial port.  This assumes the
; port has been initialized.  Should honor xon/xoff.  Skip returns on
; success, returns normally if the character cannot be written

outchr: push    cx              ; save regs
        or      ah,ah           ; sending a null?
        jz      outch2          ; z = yes
        xor     cx,cx           ; clear counter
        cmp     ah,flowoff      ; sending xoff?
        jne     outch1          ; ne = no
        mov     xofsnt,false    ; supress xon from chkxon buffer routine
outch1: cmp     xofrcv,true     ; Are we being held?
        jne     outch2          ; No - it's OK to go on
        loop    outch1          ; held, try for a while
        mov     xofrcv,false    ; timed out, force it off and fall thru
outch2: push    dx              ; Save register
        mov     al,ah           ; Parity routine works on AL
        call    dopar           ; Set parity appropriately
                                ; Begin revised output routine
        mov     byte ptr temp,al ; put data there
        cmp     prthnd,0        ; Got a handle yet?
        jne     outch3          ; Yup just go on
        call    opnprt          ; Else 'open' the port
outch3: push    bx
        mov     bx,prthnd       ; port handle
        mov     cx,1            ; one byte to write
        mov     dx,offset temp  ; place where data will be found
        mov     ah,write2       ; dos 2 write to file/device
        int     dos
        pop     bx              ; end of revised routine
        pop     dx
        pop     cx
        jmp     rskp

; Get a file handle for the communications port.  Use DOS call to get the
; next available handle.  If it fails, ask user what value to use (there
; should be a predefined handle for the port, generally 3).  The open
; will fail if the system uses names other than "COM1" or "COM2".
opnprt: mov al,flags.comflg
        dec al                  ; flags.comflg is 1 for com1, 2 for com2
        mov ah,0
        push si
        mov si,ax
        shl si,1                ; double index
        mov dx,prttab[si]
        pop si
        mov ah,open2
        mov al,2
        int dos
        jnc opnpr2
        mov ah,prstr            ; It didn't like the string
        mov dx,offset erms41
        int dos
        ret
opnpr2: mov prthnd,ax           ; Call succeeded
        mov ah,ioctl
        mov al,00h              ; get device info
        xor dx,dx
        mov bx,prthnd           ; port's handle
        int dos
        or dl,20h               ; set binary mode in device info
        mov dh,0
        mov ah,ioctl
        mov al,01h              ; set device info
        int dos
        ret

; This routine blanks the screen.

CMBLNK  PROC    NEAR            ; This is stolen from the IBM example
        push ax
        push dx
        mov ah,prstr
        mov dx,offset blank
        int dos
        pop dx
        pop ax
        ret
CMBLNK  ENDP

LOCATE  PROC    NEAR
        mov dx,0                ; Go to top left corner of screen
        jmp poscur              ; callret
LOCATE  ENDP

GETBAUD PROC    NEAR
        ret
GETBAUD ENDP


; skip returns if no character available at port,
; otherwise returns with char in al, # of chars in buffer in dx.

PRTCHR  PROC    NEAR
        push bx
        push cx
        push si
        cmp prthnd,0            ; have a handle yet?
        jne prtch1              ; yes, keep going
        call opnprt
prtch1: cmp count,0             ; no characters?
        jne prtch2              ; no, go fill buffer
        mov bx,prthnd
        mov al,rdchan
        mov ah,ioctl
        mov dx,offset source    ; buffer to read into
        mov cx,bufsiz           ; length of buffer
        int dos
        jc prtch4               ; c = error
        mov count,ax            ; reset count
        mov dx,ax               ; needed to obey rules
        or ax,ax
        jz prtch4               ; still no chars
        mov bufout,offset source ; this is output ptr
prtch2: dec count
        mov dx,count            ; return count in dx
        mov si,bufout
        cld
        lodsb                   ; get character
        mov bufout,si           ; update ptr
prtch3: pop si
        pop cx
        pop bx
        ret                     ; exit success
prtch4: pop si
        pop cx
        pop bx
        jmp rskp                ; no chars
PRTCHR  ENDP

; IHOSTS - Initialize the host by sending XON, or equivalent, and enter the
; cycle of clear input buffer, wait 1 second, test if buffer empty then exit
; else repeat cycle. Requires that the port be initialized before hand.
; Ihosts is used by the local send-file routine just after initializing
; the serial port.
; 22 March 1986 [jrd]

IHOSTS  PROC    NEAR
        push    ax              ; save the registers
        push    bx
        push    cx
        push    dx
        mov     bx,portval      ; port indicator
        mov     ax,[bx].flowc   ; put Go-ahead flow control char in ah
        or      ah,ah           ; don't send null if flow = none
        jz      ihosts1         ; z = null
        call    outchr          ; send it (release Host's output queue)
         nop                    ; outchr can do skip return
         nop
         nop
ihosts1:call    clrbuf          ; clear out interrupt buffer
        pop     dx              ; empty buffer. we are done here
        pop     cx
        pop     bx
        pop     ax
        ret
IHOSTS  ENDP

; IHOSTR - initialize the remote host for our reception of a file by
; sending the flow-on character (XON typically) to release any held
; data. Called by receive-file code just after initializing the serial
; port.         22 March 1986 [jrd]
IHOSTR  PROC    NEAR
        push    ax              ; save regs
        push    bx
        push    cx
        mov     bx,portval      ; port indicator
        mov     ax,[bx].flowc   ; put Go-ahead flow control char in ah
        or      ah,ah           ; don't send null if flow = none
        jz      ihostr1         ; z = null
        call    outchr          ; send it (release Host's output queue)
         nop                    ; outchr can do skip return
         nop
         nop
ihostr1:pop     cx
        pop     bx
        pop     ax
        ret
IHOSTR  ENDP

DTRLOW  PROC    NEAR            ; Global proc to Hangup the Phone by making
                                ; DTR and RTS low.
        mov ah,cmtxt            ; allow text to be able to display help
        mov bx,offset rdbuf     ; dummy buffer
        mov dx,offset hnghlp    ; help message
        call comnd              ; get a confirm
         jmp r
; not yet imp.  call serhng             ; drop DTR and RTS
        mov ah,prstr            ; give a nice message
; not yet imp.  mov dx,offset hngmsg
        mov dx,offset noimp     ; for now
        int dos
        clc
        jmp rskp
DTRLOW  ENDP

; Hang up the Phone. Similar to SERRST except it just forces DTR and RTS low
; to terminate the connection. 29 March 1986 [jrd]
; Calling this twice without intervening calls to serini should be harmless.
; Returns normally.
; SERHNG is Not Yet Implemented.
SERHNG  PROC    NEAR
        ret
SERHNG  ENDP

; Position the cursor according to contents of DX

POSCUR  PROC    NEAR
        push    ax                      ; save regs
        push    dx
        push    di
        push    es
        mov     ax,ds
        mov     es,ax                   ; address data segment
        cld
        mov     di,offset colno
        mov     al,dl                   ; column
        call    nout
        mov     al,'c'
        stosb
        mov     al,dh                   ; row
        call    nout
        mov     al,'Y'
        stosb
        mov     al,'$'
        stosb
        mov     dx,offset movcur
        mov     ah,prstr
        int     dos                     ; print the sequence
        pop     es                      ; restore regs
        pop     di
        pop     dx
        pop     ax
        ret
POSCUR  ENDP

NOUT    PROC    NEAR
        cbw                     ; extend to word
        div     byte ptr ten    ; divide by 10
        or      al,al           ; any quotient?
        jz      nout1           ; no, forget this
        push    ax              ; save current result
        call    nout            ; output high order
        pop     ax              ; restore
nout1:  mov     al,ah           ; get digit
        add     al,'0'          ; make printable
        stosb
        ret                     ; put in buffer and return
NOUT    endp

; Write a line in inverse video at the bottom of the screen...
; the line is passed in dx, terminated by a $.  Returns normally.
putmod  proc    near
        push    dx              ; preserve message
        mov     dx,24 * 100H    ; line 24
        call    poscur
        mov     dx,offset invseq ; put into inverse video
        mov     ah,prstr
        int     dos
        pop     dx
        int     dos
        mov     dx,offset nrmseq ; normal videw
        int     dos
        ret                     ; and return
putmod  endp

; Clear the mode line written by putmod.  Returns normally.
clrmod  proc    near
        mov     dx,24 * 100H
        call    poscur
        call    clearl
        ret
clrmod  endp

; Put a help message one the screen in reverse video.  Pass
; the message in AX, terminated by a null.  Returns normally.
; The message is put wherever the cursor currently is located.
puthlp  proc    near
        push ax                 ; save some regs
        push si
        push dx
        push ax
        mov ah,prstr            ; Leave some room before the message
        mov dx,offset crlf
        int dos
        pop si                  ; Put message address here
puth0:  mov ah,prstr
        mov dx,offset invseq    ; Put into reverse video
        int dos
        mov ah,prstr
        mov dx,offset ivlseq    ; Make line inverse video
        int dos
        cld
puth1:  lodsb
        cmp al,0                ; Terminated with a null
        je puth2
        mov dl,al
        mov ah,conout
        int dos
        cmp al,lf               ; Line feed?
        je puth0                ; Yes, clear the next line
        jmp puth1               ; Else, just keep on writing
puth2:  mov dx,offset crlf
        mov ah,prstr
        int dos
        mov dx,offset nrmseq            ; Normal video
        int dos
        pop si                          ; restore regs
        pop dx
        pop ax
        ret
puthlp  endp

; Perform a delete.

DODEL   PROC    NEAR
        push ax
        push dx
        mov ah,prstr
        mov dx,offset delstr            ; Erase weird character
        int dos
        pop dx
        pop ax
        ret
DODEL   ENDP

; Perform a Control-U.

CTLU    PROC    NEAR
        push ax
        push dx
        mov ah,prstr
        mov dx,offset clrlin
        int dos
        pop dx
        pop ax
        ret
CTLU    ENDP

COMS    PROC    NEAR
        mov dx,offset comptab           ; comms port table
        mov bx,0                        ; use keywords as help
        mov ah,cmkey                    ; parse keyword
        call comnd
         jmp r                          ; failed
        push bx
        mov ah,cmcfm
        call comnd                      ; Get a confirm
         jmp comx                       ;  Didn't get a confirm
         nop
        pop bx
        mov flags.comflg,bl             ; Set the comm port flag
        cmp flags.comflg,1              ; Using Com 1?
        jne coms2                       ; Nope
        mov portval,offset port1
        ret
coms2:  mov portval,offset port2        ; use Com2
        ret
comx:   pop bx
        ret
COMS    ENDP

VTS     PROC    NEAR                    ; Set Term code
        jmp notimp
VTS     ENDP


VTSTAT  PROC    NEAR    ; For Status display [jrd]
        ret             ; no emulator status to display
VTSTAT  ENDP

; Save the screen to a buffer and then append buffer to a disk file. [jrd]
; Default filename is Kermit.scn; actual file can be a device too. Filename
; is determined by mssset and is passed as pointer dmpname.

DUMPSCR PROC    NEAR    ; Dumps screen contents to a file. Just Beeps here
        call    beep
        ret
DUMPSCR ENDP


notimp: mov     ah,prstr
        mov     dx,offset noimp
        int     dos
        jmp     prserr

lclini: mov     flags.vtflg,0           ; no terminal emulation. [jrd]
        mov     prthnd,0                ; no port handle yet. [jrd]
        call    msuinit                 ; initialize keyboard module msugen
        ret


showkey:
        mov     ax,offset shkmsg
        mov     cx,shklen
        ret

; Wait for the # of milliseconds in ax, for non-IBM compatibles.
; Thanks to Bernie Eiben for this one.
pcwait  proc    near
        mov     cx,240          ; inner loop counter for 1 millisecond
pcwai1: sub     cx,1            ; inner loop takes 20 clock cycles
        jnz     pcwai1
        dec     ax              ; outer loop counter
        jnz     pcwait          ; wait another millisecond
        ret
pcwait  endp

; Initialization for using serial port.  Returns normally.
; Attempts to put port device in binary mode. [jrd]
SERINI  PROC    NEAR
        cld                     ; Do increments in string operations
        cmp prthnd,0            ; Got a handle yet?
        jne serin0              ; ne = yes, just go on
        push bx
        call opnprt             ; Else 'open' the port
        mov ax,passall          ; set for transparency mode [WHM]
        call dc_ioctl           ; use DOS function [WHM]
        pop bx
serin0: push bx
        mov bx,portval          ; get port [jrd]
        mov parmsk,0ffh         ; parity mask, assume parity is None
        cmp [bx].parflg,parnon  ; is it None?
        je serin1               ; e = yes
        mov parmsk,07fh         ; no, pass lower 7 bits as data
serin1: mov bx,[bx].flowc       ; get flow control chars
        mov flowoff,bl          ; xoff or null
        mov flowon,bh           ; xon or null
        pop bx
        clc                     ; carry clear for success
        ret
SERINI  ENDP

SERRST  PROC    NEAR
        push bx                 ; save reg
        mov bx,prthnd
        cmp bx,0                ; none there?
        je serrs1               ; no, don't try to close
        mov ah,close
        int dos                 ; close handle
        mov prthnd,0
serrs1: pop bx
        ret                     ; All done
SERRST  ENDP

; Generate a short beep.

BEEP    PROC    NEAR
        mov dl,bell
        mov ah,conout
        int dos
        ret
BEEP    ENDP

; Dumb terminal emulator.  Doesn't work too well above 1200 baud (and
; even at 1200 baud you sometimes lose the first one or two characters
; on a line). Does capture (logging), local echo, debug display, tests
; for printer/logging device not ready. 27 Sept 86 [jrd].
term    proc    near
        mov argadr,ax           ; save argument ptr
        mov si,ax               ; this is source
        mov di,offset ourarg    ; place to store arguments
        push es                 ; save register
        push ds
        pop es                  ; make es point to datas segment
        mov cx,size termarg
        cld
        rep movsb               ; copy into our arg blk
        pop es                  ; recover reg
        and ourarg.flgs,not (prtscr) ; no screen printing at startup
        mov ax,ourarg.captr
        mov captrtn,ax          ; buffer capture routine

        mov parmsk,0ffh         ; parity mask, assume parity = None
        cmp ourarg.parity,parnon ; is parity None?
        je term1                ; e = yes, keep all 8 bits
        mov parmsk,07fh         ; else keep lower 7 bits
term1:  call portchr            ; get char from port, apply parity mask
        jnc short term2         ; nc = no char, go on
        call outtty             ; display and capture char
term2:  call    keybd           ; call keyboard translator in msu
        jnc     term1           ; nc = no char or have processed it
                                ; carry set = quit Connect mode
term4:  ret
term    endp


; put the character in al to the screen, do capture and printing,
; does translation for Set Input command.
; Adapted from msyibm.asm [jrd]
outtty  proc    near
        test    flags.remflg,d8bit      ; keep 8 bits for displays?
        jnz     outnp8                  ; nz = yes, 8 bits if possible
        and     al,7fh                  ; remove high bit
outnp8: cmp     rxtable+256,0           ; is translation off?
        je      outnp7                  ; e = yes, off
        push    bx                      ; Translate incoming char
        mov     bx,offset rxtable       ; address of translate table
        xlatb                           ; new char is in al
        pop     bx
outnp7:
        push    bx
        mov     bx,argadr               ; args from msster directly
        test    [bx].flgs,capt          ; capturing output? Can be shut off
        pop     bx                      ;  if out dev becomes not ready
        jz      outnoc                  ; no, forget this part
        push    ax                      ; save char
        call    captrtn                 ; give it captured character
        pop     ax                      ; restore character and keep going
outnoc: test    ourarg.flgs,prtscr      ; should we be printing?
        jz      outnop                  ; no, keep going
        push    ax
        mov     ah,print_out            ; write to system printer device
        mov     dl,al
        int     dos
        pop     ax
        jnc     outnop                  ; nc = successful print
        push    ax
        call    beep                    ; else make a noise and
        call    trnprs                  ;  turn off printing
        pop     ax
outnop: cmp     flags.vtflg,0           ; emulating a terminal?
        jnz     outnop1                 ; nz = yup, go do something smart
        test    ourarg.flgs,trnctl      ; debug? if so use dos tty mode
        jz      outnp4                  ; z = no
        mov     ah,conout
        cmp     al,7fh                  ; Ascii Del char or greater?
        jb      outnp1                  ; b = no
        je      outnp0                  ; e = Del char
        push    ax                      ; save the char
        mov     dl,7eh                  ; output a tilde for 8th bit
        int     dos
        pop     ax                      ; restore char
        and     al,7fh                  ; strip high bit
outnp0: cmp     al,7fh                  ; is char now a DEL?
        jne     outnp1                  ; ne = no
        and     al,3fH                  ; strip next highest bit (Del --> '?')
        jmp     outnp2                  ; send, preceded by caret
outnp1: cmp     al,' '                  ; control char?
        jae     outnp3                  ; ae = no
        add     al,'A'-1                ; make visible
outnp2: push    ax                      ; save char
        mov     dl,5eh                  ; caret
        int     dos                     ; display it
        pop     ax                      ; recover the non-printable char
outnp3: mov     dl,al
        int     dos
        ret
outnp4: cmp     al,bell                 ; bell (Control G)?
        jne     outnp5                  ; ne = no
        jmp     beep                    ; use short beep, avoid char loss
outnop1:
outnp5: mov     ah,conout               ; dostty screen mode
        mov     dl,al                   ; write without intervention
        int     dos                     ; else let dos display char
        ret                             ; and return
outtty  endp


; send the character in al out to the serial port; handle echoing.
; Can send an 8 bit char while displaying only 7 bits locally.
outprt  proc    near
        test    ourarg.flgs,lclecho     ; echoing?
        jz      outpr1                  ; z = no, forget it
        push    ax                      ; save char
        call    outtty                  ; print it
        pop     ax                      ; restore
outpr1: mov     ah,al                   ; this is where outchr expects it
        call    outchr                  ; output to the port
         nop
         nop
         nop                            ; skip returns
        ret
outprt  endp

; Get a char from the serial port manager
; returns with carry on if a character is available
portchr proc    near
        call    prtchr                  ; character at port?
         jmp    short portc1            ; yes, go handle
         nop                            ; skip return is stupid
portc0: clc                             ; no carry -> no character
        ret                             ; and return
portc1: and     al,parmsk               ; apply 8/7 bit parity mask
        or      al,al                   ; catch nulls
        jz      portc0                  ; z = null, ignore it
        cmp     al,del                  ; catch dels
        je      portc0                  ; e = del, ignore it
        stc                             ; have a character
        ret                             ; and return
portchr endp

;; keyboard translator action routines, system dependent, called from msugen.
; These are invoked by a jump instruction. Return carry clear for normal
; processing, return carry set to exit Connect mode (kbdflg has transfer char)

chrout: call    outprt                  ; put char in al to serial port
        clc                             ; stay in Connect mode
        ret

trnprs: push    ax                      ; toggle Copy screen to printer
        test    ourarg.flgs,prtscr      ; are we currently printing?
        jnz     trnpr2                  ; nz = yes, its on and going off
        mov     ah,ioctl
        mov     al,7                    ; get output status of printer
        push    bx
        mov     bx,4                    ; file handle for system printer
        int     dos
        pop     bx
        jc      trnpr1                  ; c = printer not ready
        cmp     al,0ffh                 ; Ready status?
        je      trnpr2                  ; e = Ready
trnpr1: call    beep                    ; Not Ready, complain
        jmp     trnpr3                  ; and ignore request
trnpr2: xor     ourarg.flgs,prtscr      ; flip the flag
trnpr3: pop     ax
        clc
        ret

klogon  proc    near                    ; resume logging (if any)
        test    flags.capflg,logses     ; session logging enabled?
        jz      klogn                   ; z = no, forget it
        or      ourarg.flgs,capt        ; turn on capture flag
klogn:  clc
        ret
klogon  endp

klogof  proc    near                    ; suspend logging (if any)
        and     argadr.flgs,not capt    ; stop capturing
klogo:  clc
        ret
klogof  endp

snull:  mov     ah,0                    ; send a null
        call    outchr                  ; send without echo or logging
         nop
         nop
         nop
        clc
        ret

kdos:   mov     al,'P'                  ; Push to DOS
        jmp     short cmdcom
cstatus:mov     al,'S'                  ; these commands exit Connect mode
        jmp     short cmdcom
cquit:  mov     al,'C'
        jmp     short cmdcom
cquery: mov     al,'?'
        jmp     short cmdcom
cmdcom: mov     kbdflg,al               ; pass char to msster.asm via kbdflg
        stc                             ; say exit Connect mode
        ret
                                        ;; end of action routines

; Jumping to this location is like retskp.  It assumes the instruction
;   after the call is a jmp addr.

RSKP    PROC    NEAR
        pop     bp
        add     bp,3
        push    bp
        ret
RSKP    ENDP

; Jumping here is the same as a ret.

R       PROC    NEAR
        ret
R       ENDP

code    ends
        end