        name msxapr
; File MSXAPR.ASM          ** current version, needs work **
; Kermit system dependent module for ACT Apricot
; 
; Last edit: 25 April 1988 [rwtc]
; Version 2.30
; This version runs ok on the FP portable and hopefully on the xi/pc
; I have removed all the microscreen stuff to reduce the size of the filew
; for editing convenience, it could be replaced if anyone feels the need
; of it. Other mods that were necessary were to the SENDBR command this
; now seems to work ok, also the log session command had got scrambled
; somewhere along the line this now works. 
; MSUAPR.ASM this works as a basic keyboard translator only, 
; work is still needed to provide comlete terminal emulation facilities.
;
; [rwtc] = Dick Carlton Department of Earth Sciences, The Open University
; Walton Hall, Milton Keynes MK7 6AA
;
; 27 May 1987 Add keyboard translator and input translation table rxtable,
; remove references to register bp, minor cleanups here and there. [jrd]
; ASSUMPTION: This module can use something like the Generic keyboard
;  translator MSUGEN.asm. Work needed to make MSUAPR.asm!
;
; 28 Sept 1986 Revise procedure Term to permit capturing, printer ready
;  testing, debug display. Revised other port procedures too. [jrd]
; 4 Sept 1986 Add Bob Goeke's change to move comms port table to a system
;  dependent module (typ msx---) to allow 3+ ports and localized idents. [jrd]
 
; Added global entry point vtstat for use by Status in mssset.
; Added register save/restore in getbaud procedure.
; Also trimmed off trailing commas in publics. Joe R. Doupnik 12 March 1986
; Add global procedures ihosts and ihostr to handle host initialization
; when packets are to be sent or received by us,resp. 24 March 1986
; Add global procedure dtrlow (without worker serhng) to force DTR and RTS low
; in support of Kermit command Hangup. Says Not Yet Implemented. [jrd]
; Add global procedure Dumpscr, called by Ter in file msster, to dump screen
;  to a file. Just does a beep for now. 13 April 1986 [jrd]
; Move Hangup message out from middle of Show Key area (my goof).
;  23 April 1986 [jrd]
        public  serini, serrst, clrbuf, outchr, coms, vts, vtstat, dodel
        public  ctlu, cmblnk, locate, lclini, prtchr, dobaud, clearl
        public  dodisk, getbaud, beep, trnprs, pcwait, termtb ;[rwtc]
        public  count, xofsnt, puthlp, putmod, clrmod, poscur, shomodem
        public  sendbr, sendbl, term, machnam, setktab, setkhlp, showkey
        public  ihosts, ihostr, dtrlow, serhng, dumpscr, comptab ; [jrd]
        public  chrout, cstatus, cquit, cquery, chang          ; kbd action verbs
        public  snull, kdos, klogof, klogon, modlin, cpyktab, lng_br
 
        include a:\mssdef.h

if1
	%out [Beginning pass 1]
else
	%out [Beginning pass 2]
endif
 
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
rddev   equ     3FH
open    equ     3DH
control equ     0FCH                    ; System Control Device
 
; external variables used:
; drives - # of disk drives on system
; flags - global flags as per flginfo structure defined in pcdefs
; trans - global transmission parameters, trinfo struct defined in pcdefs
; portval - pointer to current portinfo structure (currently either port1
;           or port2)
; port1, port2 - portinfo structures for the corresponding ports
 
; global variables defined in this module:
; xofsnt, xofrcv - tell whether we saw or sent an xoff.
 
modfrm  struc                           ; Format of mode line
        db      'Esc chr: '
m_echr  db      2 dup (?)
        db      ', Speed: '
m_baud  db      4 dup (?)
        db      ', Parity: '
m_par   db      4 dup (?)
        db      ', Echo: '
m_echo  db      3 dup (?)
        db      ', Log: '
m_log   db      3 dup (?)
        db      ', Type '
m_hlp   db      2 dup (?)
        db      '? for Help$'
modfrm  ends
 
datas   segment public  'datas'
        extrn   drives:byte,  flags:byte, trans:byte
        extrn   portval:word, port1:byte, port2:byte
        extrn   comand:byte, dmpname:byte                       ; [jrd]
        extrn   kbdflg:byte, rxtable:byte
 
 
;
machnam db      'ACT Apricot$'
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$'
erms50  db      cr,lf,'Error reading from device$'
badbd   db      cr,lf,'Unimplemented baud rate$'
noimp   db      cr,lf,'Command not implemented.$'
shkmsg  db      'Not implemented.'
shkmln  equ     $-shkmsg
setktab db      0
setkhlp db      0
hngmsg  db      cr,lf,' The phone should have hungup.',cr,lf,'$' ; [jrd]
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,'$'                                       ; [jrd]
rdbuf   db      80 dup (?)      ; temp buf [jrd]
crlf    db      cr,lf,'$'
delstr  db      BS,BS,' ',BS,'$'        ; Delete string.
clrlin  db      cr,escape,'K$'             ; Clear line.
clreol  db      escape,'K$'                ; Clear line.
clrscr  db      escape,'H',escape,'J$'        ; Home and clear screen.
; Set High/Low intensity and/or Inverse video/Normal video
; rwtc 26.06.87.
invseq  db      escape,'p$'                ; Inverse video mode.
nrmseq  db      escape,'q$'                ; Normal video mode.
hinton  db      escape,'($'                ; High intensity mode.
hintof  db      escape,')$'                ; Low intensity mode.
on25    db      escape,'j',escape,';$'        ; Save cursor posn, move to line 25
off25   db      escape,'k$'                ; Restore cursor to saved position
offmscr db      escape,'/',0,escape,'s$'      ; Turn off lights, clear, clock on
onmscr  db      escape,'U',escape,'W'         ; Direct output to microscreen
        db      escape,'c',escape,'B'         ; Disable scrolling, cursor down
        db      'Break Close  Status  '
        db      'Push   Help   Log'
        db      escape,'V'                 ; Revert to normal screen
        db      escape,'/',3FH             ; Turn on all keypad lights
        db      '$'
xofsnt  db      0                       ; Say if we sent an XOFF.
count   dw      0                       ; Number of chars in int buffer.
portin  db      0                       ; Port initialization flag

inited  db      0                       ; Terminal handler init flag
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
tmp     db      ?,'$'
temp    dw      0
temp1   dw      ?                       ; Temporary storage.
temp2   dw      ?                       ; Temporary storage.

; Added from msxibm.asm [rwtc] 22.03.88 this is here just to make the
; status display look nicer (at the moment) [rwtc]
                                        ; begin Terminal emulator data set

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

; shomodem messages from msxibm.asm [rwtc] 18.03.88 (just for show at present)

mdstreg db	0
msmsg1  db      cr,lf,' Modem is not ready: DSR is off$'
msmsg2  db      cr,lf,' Modem is ready:     DSR is on$'
msmsg3  db      cr,lf,' no Carrier Detect:  CD  is off$'
msmsg4  db      cr,lf,' Carrier Detect:     CD  is on$'
msmsg5  db      cr,lf,' no Clear To Send:   CTS is off$'
msmsg6  db      cr,lf,' Clear To Send:      CTS is on$'

 
; This character string is used to program various keys to return
; the correct ASCII characters.
 
kbdesc  db      escape,'43',44,'['-100O    ; Program CTRL-[ key
        db      escape,'43',45,']'-100O    ; Program CTRL-] key
        db      '$'
 
;  This table is indexed by the baud rate definitions given in msdefs.h.
;  Unsupported baud rates should contain FF.
bddat   label   word
        dw      0FFH                    ;    45.5  Unsupported
        dw      1                       ;    50
        dw      2                       ;    75
        dw      3                       ;   110
        dw      4                       ;   134.5
        dw      5                       ;   150
        dw      6                       ;   300
        dw      7                       ;   600
        dw      8                       ;  1200
        dw      9                       ;  1800
        dw      0FFH                    ;  2000    Unsupported
        dw      10                      ;  2400
        dw      12                      ;  4800    (Have to skip 3600)
        dw      14                      ;  9600    (Have to skip 7200)
        dw      15                      ; 19200
        dw      0FFH                    ; 38400    Unsupported
 
comptab db      2                       ; communciations port options [jrd]
        mkeyw   '1',1
        mkeyw   'COM1',1                ; no choice here
 
ourarg  termarg <>
modbuf  modfrm  <>                      ; Mode line buffer
 
; Some static data for the mode line.
unkbaud db      'Unk '
baudn   db      '45.5'
        db      '  50'
        db      '  75'
        db      ' 110'
        db      ' 135'
        db      ' 150'
        db      ' 300'
        db      ' 600'
        db      '1200'
        db      '1800'
        db      '2000'
        db      '2400'
        db      '4800'
        db      '9600'
        db      ' 19K'
        db      ' 38K'
 
parnams db      'Even'
        db      'Mark'
        db      'None'
        db      'Odd '
        db      'Spc '
offmsg  db      'Off'
onmsg   db      'On '
lclmsg  db      'Lcl'
remmsg  db      'Rem'
keyoff  dw      0
keyseg  dw      0

datas   ends
 
code    segment public 'code'
        extrn   comnd:near, dopar:near, prserr:near, atoi:near, prompt:near
        extrn   sleep:near, msuinit:near, keybd:near            ; [jrd]
        assume  cs:code,ds:datas
 
; Produce a short beep.  The PC DOS bell is long enough to cause a loss
; of data at the port.  Returns normally.
 
BEEP    PROC    NEAR
        mov     dl,bell
        mov     ah,dconio
        int     dos
        ret
BEEP    ENDP
 
; Clear to the end of the current line.  Returns normally.
 
CLEARL  PROC    NEAR
        mov     dx,offset clreol
        jmp     tmsg                    ; Send terminal message
CLEARL  ENDP
 
; Clear the input buffer. This throws away all the characters in the
; serial interrupt buffer.  This is particularly important when
; talking to servers, since NAKs can accumulate in the buffer.
; Returns normally.
 
CLRBUF  PROC    NEAR
        push    bx                      ; save regs. [jrd]
        push    cx
        mov     bx,34H                  ; Serial Device Driver
        mov     cx,2                    ; Read serial port
clrbf1: int     control                 ; Call System Control Device
        cmp     ax,-1                   ; Read anything ?
        jne     clrbf1                  ; Yes, try again
        pop     cx                      ; [jrd]
        pop     bx
        ret
CLRBUF  ENDP
 
; clear the mode line written by putmod.  Returns normally.
 
CLRMOD  PROC    NEAR
        mov     dx,offset on25          ; Move to line 25
        call    tmsg
        call    clearl                  ; Clear to end of line.
        mov     dx,offset off25         ; Restore cursor position
        call    tmsg
        ret
CLRMOD  ENDP
 
; This routine blanks the screen.  Returns normally.
 
CMBLNK  PROC    NEAR
        mov     dx,offset clrscr
        jmp     tmsg                    ; Send terminal message.
CMBLNK  ENDP
 
; Set the current port.
 
COMS    PROC    NEAR
        jmp     notimp
COMS    ENDP
 
; Make a copy of the keyboard table so that we can redefine some keys
; when we go into CONNECT state.

 
CPYKTAB PROC    NEAR
        push    ds
        mov     ax,0
        mov     es,ax                   ; ES -> lowest page in memory
        mov     ax,es:[0712H]
        mov     keyoff,ax               ; Save offset to keytable
        mov     si,ax                   ; For the copy
        mov     ax,es:[0714H]
        mov     keyseg,ax               ; Save segment of keytable
;
        mov     ds,ax                   ; DS:SI -> system keyboard table
	call	keybd
        mov     es,ax
        mov     di,0                    ; ES:DI -> our keyboard table
;
        mov     cx,0400H                ; Length of table
        cld
        rep     movsb                   ; Copy table
;
	call	keybd
	jmp	notimp
        mov     ds,ax                   ; Point to our keyboard segment
;
        mov     cx,12
        cld
        rep     movsb                   ; copy pointers
        pop     ds                      ; restore DS
        ret
CPYKTAB ENDP

 
; Move the cursor to the left margin, then clear to end of line.
; Returns normally.
 
CTLU    PROC    NEAR
        mov     dx,offset clrlin
        jmp     tmsg
CTLU    ENDP
 
; Set the baud rate for the current port, based on the value
; in the portinfo structure.  Returns normally.
 
DOBAUD  PROC    NEAR
        push    ax                      ; save regs. [jrd]
        push    bx
        push    cx
        mov     bx,portval
        mov     temp1,ax                ; Save new rate, don't zap old rate yet
        mov     ax,[bx].baud            ; Check if new rate is valid.
        mov     tmp,2
        mul     tmp                     ; Get index into baud table.
        mov     bx,offset bddat         ; Start of table.
        add     bx,ax
        mov     ax,[bx]                 ; The data to output to the port
        cmp     ax,0FFH                 ; Unimplemented baud rate.
        jne     dobd0
        mov     ax,temp1                ; Get back original value.
        mov     bx,portval
        mov     [bx].baud,ax            ; Leave rate as is.
        mov     dx,offset badbd         ; Give an error message.
        call    tmsg
        pop     cx
        pop     bx
        pop     ax
        ret
;
dobd0:  mov     dx,ax
        mov     bx,34H                  ; Serial Device Driver
        mov     cx,4                    ; Set transmit baud rate
        int     control
        mov     cx,5                    ; Set receive baud rate
        int     control
        mov     dx,1                    ; Turn on XON/XOFF just in case...
        mov     cx,10                   ; Transmit XON/XOFF
        int     control
        mov     cx,11                   ; Receive XON/XOFF
        int     control
        mov     cx,3                    ; Install changes, zap line, etc...
        int     control
        mov     inited,0                ; Need to re-init on CONNECT
        pop     cx
        pop     bx
        pop     ax
        ret
DOBAUD  ENDP
 
; Delete a character from the terminal.  This works by printing
; backspaces and spaces.  Returns normally.
 
DODEL   PROC    NEAR
        mov     dx,offset delstr        ; Erase weird character.
        jmp     tmsg
DODEL   ENDP
 
; This is called by Kermit initialization.  It checks the
; number of disks on the system, sets the drives variable
; appropriately.  Returns normally.
 
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
 
; Get the current baud rate from the serial card and set it
; in the portinfo structure for the current port.  Returns normally.
; This is used during initialization.
 
GETBAUD PROC    NEAR
        push    ax                      ; save some regs [jrd]
        push    bx
        push    cx                      ; [jrd]
        push    dx                      ; [jrd]
        mov     bx,34H                  ; Serial Device Driver
        mov     cx,4                    ; Transmit baud rate
        mov     dx,-1                   ; Fetch data
        int     control                 ; Go speak to Control Device Driver
        mov     bx,offset bddat         ; -> baud rate table
        mov     cl,0                    ; Keep track of index
getb0:  cmp     ax,[bx]
        je      getb1
        inc     cl
        cmp     cl,baudsiz              ; At the end of the list
        jge     getb2
        add     bx,2
        jmp     getb0
getb1:  mov     ch,0
        mov     bx,portval
        mov     [bx].baud,cx            ; Save rate index in port structure
        jmp     getb3                   ; [jrd]
getb2:  mov     dx,offset erms40
        call    tmsg
getb3:  pop     dx                      ; restore regs [jrd]
        pop     cx                      ; [jrd]
        pop     bx                      ; [jrd]
        pop     ax                      ; [jrd]
        ret
GETBAUD ENDP
 
; Initialize local variables and communications port.
 
LCLINI  PROC    NEAR
        mov     flags.vtflg,0           ; Don't do terminal emulation.
        mov     bx,34H                  ; Control Device Driver
        mov     cx,0                    ; Initialise driver
        mov     dx,0
        int     control
        mov     cx,6                    ; Set transmit bits per character
        mov     dx,8                    ; to 8-bit bytes
        int     control
        mov     cx,8                    ; Set receive bits per character
        mov     dx,7                    ; to 8-bit bytes
        int     control
        mov     cx,8                    ; Set number of stop bits
        mov     dx,1                    ; to 1 stop bit
        int     control
        mov     cx,9                    ; Set parity type
        mov     dx,0                    ; Parity handled by DOPAR.
        int     control
        mov     cx,10                   ; Transmit XON/XOFF
        mov     dx,1                    ; Enabled
        int     control
        mov     cx,11                   ; Receive XON/XOFF
        mov     dx,1                    ; Enabled
        int     control
        mov     cx,3                    ; Install changes
        int     control
        mov     dx,offset kbdesc
        call    tmsg                    ; Re-program keyboard
        call    msuinit                 ; init keyboard translator
        ret
LCLINI  ENDP
 
; Homes the cursor.  Returns normally.
 
LOCATE  PROC    NEAR
        mov     dx,0000H                ; Go to top left corner of screen.
        jmp     poscur
LOCATE  ENDP
 
; Display mode line.
 
MODLIN  PROC    NEAR
        mov     al,ourarg.escc
        mov     modbuf.m_echr,' '
        mov     modbuf.m_hlp,' '
        cmp     al,32                   ; ESC char printable ?
        jnb     modl1                   ; Yes, keep going
        add     al,40H                  ; Convert to printable
        mov     modbuf.m_echr,'~'       ; Note control char
        mov     modbuf.m_hlp,'~'
modl1:  mov     modbuf.m_echr+1,al      ; Fill in character
        mov     modbuf.m_hlp+1,al
;
        mov     al,ourarg.baudb         ; Get baud rate
        mov     si,offset unkbaud       ; Just in case it falls out of range
        cmp     al,baudsiz              ; Too big ?
        jnb     modl2                   ; Yes, use default
        mov     cl,2                    ; Each entry is 4 bytes
        shl     al,cl
        mov     ah,0
        add     ax,offset baudn         ; ax -> baud rate string
        mov     si,ax
modl2:  mov     cx,size m_baud          ; length of baud space
        mov     di,offset modbuf.m_baud
        push    es                      ; save es
        push    ds
        pop     es                      ; set es to datas segment
        cld
        rep     movsb                   ; Copy over baud rate
;
        mov     al,ourarg.parity        ; Get parity code
        mov     cl,2                    ; Each entry is 4 bytes long
        shl     al,cl
        mov     ah,0
        add     ax,offset parnams       ; ax -> parity setting
        mov     si,ax
        mov     cx,4
        mov     di,offset modbuf.m_par
        rep     movsb                   ; Copy over parity setting string
;
        mov     si,offset remmsg        ; Assume remote echoing
        test    ourarg.flgs,lclecho
        jz      modl3
        mov     si,offset lclmsg        ; Doing local echo
modl3:  mov     cx,3
        mov     di,offset modbuf.m_echo
        rep     movsb
;
        mov     si,offset offmsg        ; Assume not logging
        test    ourarg.flgs,capt
        jz      modl4
        mov     si,offset onmsg         ; Logging input
modl4:  mov     cx,3
        mov     di,offset modbuf.m_log
        rep     movsb
        pop     es                      ; restore es
;
        mov     dx,offset modbuf
        call    putmod                  ; Print mode line
        ret
MODLIN  ENDP
 
; Clear microscreen, redisplay time and revert to system keyboard table.
 
NOTIMP: mov     dx,offset noimp
        call    tmsg
        jmp     prserr
 
; Put the number in ax into the buffer pointed to by di.  di is updated.
 
NOUT    PROC    NEAR
        mov     dx,0
        mov     bx,10
        div     bx
        push    dx
        or      ax,ax
        jz      nout1
        call    nout
nout1:  pop     ax
        add     al,'0'
        stosb
        ret
NOUT    ENDP
 
; Put the char in AH to the serial port.  This assumes the
; port has been initialized.  XON/XOFF are handled by the port
; driver.  Skip returns on success, returns normally if the
; character cannot be written.
 
OUTCHR  PROC    NEAR
        push    bx
        push    cx
        push    dx                      ; Save register.
        sub     cx,cx
        mov     al,ah                   ; Parity routine works on AL.
        call    dopar                   ; Set parity appropriately.
        mov     dl,al
        mov     dh,0
        mov     cx,1                    ; Transmit char
        mov     bx,34H                  ; Serial Device Driver
        int     control                 ; System Control Device
        pop     dx
        pop     cx
        pop     bx
        jmp     rskp
OUTCHR  ENDP
 
;  Position the cursor according to contents of DX:
;  DH contains row, DL contains column.  Origin (top left) = 0, 0
;  Returns normally. Revised 28 Sept 1986 by [jrd]
 
POSCUR  PROC    NEAR
        push    ax                      ; [jrd]
        mov     ah,conout               ; display on console
        push    dx                      ; Save row & column position
        mov     dl,escape                  ; Start cursor positioning sequence
        int     dos                     ; [jrd]
        mov     dl,'Y'
        int     dos                     ; [jrd]
        pop     dx                      ; Retrieve row position
        push    dx                      ; save again [jrd]
        mov     dl,dh
        add     dl,' '                  ; add ascii bias [jrd]
        int     dos
        pop     dx
        push    dx
        add     dl,' '
        int     dos
        pop     dx
        pop     ax                      ; [jrd]
        ret
POSCUR  ENDP
 
; Use for DOS 2.0 and above.  Check the port status.  If no data, skip
; return.  Else, read in a char and return.
; Revised 28 Sept 1986 by [jrd]
PRTCHR  PROC    NEAR
        push    bx
        push    cx
        push    si
        mov     bx,34H
        mov     cx,2
        int     control                 ; Read serial port
        pop     si
        pop     cx
        pop     bx
        cmp     ax,-1                   ; Character there ?
        jne     prtch1                  ; Yes, process it...
        jmp     rskp                    ; No character, skip return.
prtch1: ret
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
        mov     ax,1            ; sleep for 1 second
        call    sleep           ; procedure sleep is in msscom.asm
        call    prtchr          ; check for char at port
         jmp    ihosts1         ; have a char in al, repeat wait/read cycle
         nop                    ; prtchr does skip return on empty 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
        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
 
; Wait for the # of milliseconds in ax, for non-IBM compatibles.
; Based on 4.77 Mhz 8088 processor speeds.
; 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
 
 
; Put a help message on the screen.
; Pass the message in ax, terminated by a null.  Returns normally.
 
PUTHLP  PROC    NEAR
        push    ax                      ; preserve this
        mov     dx,offset crlf
        call    tmsg
        mov     dx,offset hinton        ; Turn on high intensity
        call    tmsg
        pop     si                      ; point to string again
        cld
puthl3: lodsb                           ; get a byte
        cmp     al,0                    ; end of string?
        je      puthl4                  ; yes, stop
        mov     dl,al
        mov     ah,dconio
        int     dos                     ; else write to screen
        jmp     puthl3                  ; and keep going
puthl4: mov     dx,offset hintof        ; Back to normal
        call    tmsg
        mov     dx,offset crlf
        call    tmsg
        ret
PUTHLP  ENDP
 
; Write a line in high intensity on line 25.  The line is pointed to by
; ds:dx, terminated by a $.  Returns normally.
 
PUTMOD  PROC    NEAR
        push    dx                      ; preserve message pointer.
        mov     dx,offset on25          ; Move down to line 25
        call    tmsg
        mov     dx,offset invseq        ; Turn on high intensity
        call    tmsg
        pop     dx                      ; get message back
        call    tmsg                    ; write it out
        mov     dx,offset nrmseq        ; Normal (low) intensity again
        call    tmsg
        mov     dx,offset off25         ; Restore cursor position
        call    tmsg
        ret                             ; and return
PUTMOD  ENDP
 
; Jumping here is the same as a ret.
 
R       PROC    NEAR
        ret
R       ENDP
 
; 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
 
; Send a break out to the serial port.  Returns normally.
; Need to handle port directly since ACT's Control Device doesn't
; have a 'send break' facility.
; altered the SIO port address from 62HEX to 1AHEX this works for FP
; I'm not sure about the XI/PC [rwtc] 25.04.88
 
SENDBR  PROC    NEAR
        push    ax
        push    bx
        mov     al,5
        out     1ah,al                  ; Select SIO write register 5
        mov     al,0FAH
        out     1ah,al                  ; Start break
        mov     al,2
sendb0: mov     bx,-1
sendb1: dec     bx                      ; Delay for a while...
        jnz     sendb1
        dec     al
        jnz     sendb0
        mov     al,5
        out     1ah,al                  ; Select SIO write register 5
        mov     al,0EAH
        out     1ah,al                  ; Finished sending break
        pop     bx
        pop     ax
        clc
        ret
SENDBR  ENDP
SENDBL  PROC    NEAR                    ; Send a long break
        call    sendbr                  ; simulate long
        call    sendbr
        call    sendbr
        call    sendbr
        clc
        ret
SENDBL  ENDP
 
; Initialization for using serial port.  XON/XOFF has already been set by
; the local initialization routine.  Returns normally.
; Revised 28 Sept 1986 by [jrd]
SERINI  PROC    NEAR
        cmp     portin,0                ; Initialized already ?
        jne     serin0                  ; Yes, forget it.
        cld                             ; Do increments in string operations
; Some day we may have an interrupt handler to install...
        call    clrbuf                  ; Clear input buffer.
        push bx
        mov bx,portval          ; get port [jrd]
        mov parmsk,0ffh         ; parity mask, assume parity is None. [jrd]
        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
        mov     portin,1                ; Say we've been through once
serin0: ret                             ; We're done.
SERINI  ENDP
 
; Reset the serial port.  This is the opposite of serini.  Calling
; this twice without intervening calls to serini should be harmless.
; Returns normally.
 
SERRST  PROC    NEAR
        cmp     portin,0                ; Reset already ?
        je      srst1                   ; Yes, forget it
; One day soon we may want to restore the interrupt handler, I hope...
        mov     portin,0
srst1:  ret                             ; All done.
SERRST  ENDP
 
SHOWKEY PROC    NEAR
        mov     ax,offset shkmsg
        mov     cx,shkmln
        ret
SHOWKEY ENDP
 
 
; Dumb terminal emulator.
; Revised 28 Sept 1986 by [jrd]
TERM    PROC    NEAR
        mov     si,ax                   ; this is source
        mov     di,offset ourarg        ; place to store arguments
        push    es                      ; save es
        push    ds
        pop     es                      ; address destination segment
        mov     cx,size termarg
        cld
        rep     movsb                   ; copy into our arg blk
        pop     es                      ; recover es
        and ourarg.flgs,not (prtscr)    ; no screen printing at startup [jrd]
        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 term0a                       ; e = yes, keep all 8 bits
        mov parmsk,07fh                 ; else keep lower 7 bits
term0a: test flags.remflg,d8bit         ; keep 8 bits for displays?
        jnz term0b                      ; nz = yes, 8 bits if possible
        mov parmsk,07fh                 ; else keep lower 7 bits
term0b:
        call    clrmod                  ; Clear mode line
        test    ourarg.flgs,modoff      ; Is mode line disabled ?
        jnz     term0                   ; Yes, skip this
        call    modlin
;
term0: 
        cmp     inited,0                ; inited yet ?
        jnz     term1                   ; yes, skip this bit...
        mov     bx,34H
        mov     dx,1
        mov     cx,12                   ; Turn on RTS
        int     control
        mov     cx,13                   ; Turn on DTR
        int     control
        mov     inited,1                ; Remember we've inited
 
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           ; read keyboard and send via translator
        jnc     term1           ; nc = stay in Connect mode
 
term4:  call    clrmod
        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     outnp9                  ; nz = yes, 8 bits if possible
        and     al,7fh                  ; remove high bit
outnp9: cmp     rxtable+256,0           ; translation turned off?
        je      outnp7                  ; e = yes, no translation
        push    bx
        mov     bx,offset rxtable       ; address of translate table [jrd]
        xlatb                           ; new char is in al
        pop     bx
outnp7: test    ourarg.flgs,prtscr      ; should we be printing?
        jz      outnop                  ; no, keep going
        push    ax
        mov     ah,lstout               ; 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: test    ourarg.flgs,capt        ; capturing output?
        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,trnctl      ; debug? if so use Bios tty mode
        jz      outnp4                  ; z = no
        mov     ah,print_out            ; Bios tty screen write
        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)? [jrd]
        jne     outnp5                  ; ne = no
        jmp     beep                    ; use short beep, avoid char loss.
outnp5: or      al,al                   ; catch nulls
        jz      outnp6                  ; z = null, ignore it
        cmp     al,del                  ; catch dels
        je      outnp6                  ; e = del, ignore it
        mov     dl,al                   ; write without intervention.
        mov     ah,conout
        int     dos                     ; else let dos display char
outnp6: 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 [jrd]
        push    bx                      ; Translate incoming char [jrd]
        mov     bx,offset rxtable       ; address of translate table [jrd]
        xlat                            ; new char is in al
        pop     bx
        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 for invoking Quit (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

lng_br	proc	near
	call	sendbl
lng_br	endp

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
chang:	mov	al,'H'			; Hangup drop DTR & RTS
        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
 
; Print a message to the screen.  Returns normally.
 
TMSG    PROC    NEAR
        push    ax
        push    bx
        push    cx
        push    dx              ; dx has offset of message.
        mov     ah,prstr
        int     dos
        pop     dx
        pop     cx
        pop     bx
        pop     ax
        ret
TMSG    ENDP
 
SHOMODEM PROC   NEAR
        mov     ah,cmcfm                ; get a confirm
        call    comnd
         jmp    r                       ; no confirm
         nop
        call    serini                  ; activate port to get status
        call    serrst                  ; turn off port again
        mov     ah,prstr
        mov     dx,offset msmsg1        ; modem ready msg
        test    mdstreg,20h             ; is DSR asserted?
        jz      shomd1                  ; z = no
        mov     dx,offset msmsg2        ; say not asserted
shomd1: int     dos
        mov     dx,offset msmsg3        ; CD asserted msg
        test    mdstreg,80h             ; CD asserted?
        jz      shomd2                  ; z = no
        mov     dx,offset msmsg4        ; say not asserted
shomd2: int     dos
        mov     dx,offset msmsg5        ; CTS asserted msg
        test    mdstreg,10h             ; CTS asserted?
        jz      shomd3                  ; z = no
        mov     dx,offset msmsg6        ; say not asserted
shomd3: int     dos
        jmp     rskp
SHOMODEM ENDP

; Set heath emulation on/off.
 
VTS     PROC    NEAR
        jmp     notimp
VTS     ENDP
 
VTSTAT  PROC    NEAR                    ; For use by Status in mssset [jrd]
        ret                             ; no emulator status to report
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       ; [jrd]
        ret
DUMPSCR ENDP
 
 
CODE    ENDS
        END
