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

⟦bc8dddb3e⟧ TextFile

    Length: 86841 (0x15339)
    Types: TextFile
    Names: »msxp98.asm«

Derivation

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

TextFile

         name    msxp98
; File MSXP98.ASM
; NEC PC-9801 MS DOS Kermit module.
;
; Last edit: 16 Jul 1988
; 16 Jul 1988 Keyboard kanji translation comes into chrout to work with
;             SET KEY command.
; 14 Jul 1988 V2.31
;             old global variable PCNET is now local variable
;             local termination pointer NETDONE is renamed LCLEXIT
;             GETMODEM is added as a dummy routine (from MSXGEN.ASM)
;             Ungermann-Bass port name is UB-NETCI
; 25 Jun 1988 Ungermann-Bass PC-NIU N98 support in NETCI mode
; 15 Jun 1988 V1.00
; 06 Jun 1988 show modem is installed
; 23 May 1988 added KEYCLICK, AUTOTEK features
; 19 May 1988 become v2.27(A) level (TEK4014, VT100)
; 18 May 1988 Keyboard routine for VT100 is installed.
; 16 May 1988 Works with v2.27(A) VT100 output routine.
; 15 May 1988 Fixed bug in SERINI.
; 14 May 1988 Works with dumb terminal emulator !
; 12 May 1988 start coding based on MSXGEN.ASM by H.Fujii

        public  serini, serrst, clrbuf, outchr, coms, vts, vtstat, dodel
        public  ctlu, cmblnk, locate, lclini, prtchr, dobaud, clearl
        public  dodisk, getbaud, beep, trnprs, pcwait, termtb
        public  count, xofsnt, puthlp, putmod, clrmod, poscur
        public  sendbr, sendbl, term, machnam, setktab, setkhlp, showkey
        public  ihosts, ihostr, dtrlow, serhng, dumpscr, comptab
        public  chrout, cstatus, cquit, cquery, chang   ; kbd action verbs
        public  snull, kdos, klogof, klogon
        public  shomodem, getmodem, mdmhand
        public  pf1, pf2, pf3, pf4
        public  kp0, kp1, kp2, kp3, kp4, kp5, kp6, kp7, kp8, kp9
        public  kpmins, kpcoma, kpentr, kpdot
        public  uparrw, dnarrw, lfarrw, rtarrw
        public  keyinchg

        public  s2jis, jis2s, is_kanji1
        public  curkey_mode, keypad_mode
        public  kanji_rmode, kanji_smode
        public  keyin_dos, vt100_flags

        include mssdef.h

BIOS            equ     18h

AUTOWRAP_BIT    equ     1
AUTOTEK_BIT     equ     2
KEYCLICK_BIT    equ     4
CURSOR_BIT      equ     8
BLINK_BIT       equ     16
LOOPTEST_BIT    equ     128

CHR_GS  equ     1Dh
CHR_CAN equ     18h

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

;
; Ungermann-Bass PC-NIU N98 command interpreter interface
; CALL    AH -- Function number
;         AL -- Port number relative to 0
;         CX -- may be a counter
;      ES:BX -- may be a buffer address

NETCI_PORT      equ     0               ; NETCI port number

NETCI_INT       equ     06Bh            ; Software interrupt vector# for NETCI
NETCI_OPEN      equ     2               ; NETCI open function
NETCI_CLOSE     equ     3               ; NETCI close function
NETCI_READ      equ     1               ; NETCI read function
NETCI_WRITE     equ     0               ; NETCI write function
NETCI_CNTL      equ     6               ; NETCI control function
NETCI_STATUS    equ     7               ; NETCI status function
NETCI_RBRK      equ     8               ; NETCI read break function

; Buffer size for Network transfer

NETBUFLEN       equ     256

; port assignments for 8251 serial controllers
;
;== PORT 1 ==

mndata  equ     30h
mnst1a  equ     32h
mncmda  equ     32h

mnmska  equ     35h     ; mask set
mnrdsa  equ     33h     ; read signal

;== PORT 2 ==

mndatb  equ     0B1h
mnst1b  equ     0B3h
mncmdb  equ     0B3h

mnmskb  equ     0B0h
mnrdsb  equ     0B0h    ; read signal

;== PORT 3 ==

mndatc  equ     0B9h
mnst1c  equ     0BBh
mncmdc  equ     0BBh

mnmskc  equ     0B2h    ; mask set
mnrdsc  equ     0B2h    ; read signal

; Status bits from austt

txrdy   equ     01h
rxrdy   equ     02h

; Command values for mncmd

ccmd    equ     37H             ; RTS & DTR high, RX & TX enabled, reset ERR
cbrk    equ     08H             ; break enabled
cmode   equ     40H             ; enable mode reset
mmode   equ     4EH             ; 16x rate, 8 data, no parity, 1 stop

; Mask values for mnmsk


txmsk   equ     04H             ; disables transmit ready interrupt
rxmsk   equ     01H             ; disables receive ready interrupt
tbemsk  equ     02H             ; disables transmit buffer empty interrupt


; port assignments for 8253 timers

;               Standard interface

tmdata  equ     75H             ; data port
tmcmda  equ     77H             ; command port  (Was 27H Ian 10/27/84)


; values for tmcmd which select timer channel and mode

tmsela  equ     0B6H            ; Channel 2, mode 3 (standard port)

; Timer information for current port selection

tmrinfo struc
tmdat   dw      0               ; data port
tmcmd   dw      0               ; command port
tmsel   db      0               ; byte which selects channel and mode
tmrinfo ends

; Modem information for current port selection

; port assignments for 8259 interrupt controllers

;               Standard interface

intcmda equ     00H             ; Command port (master controller)
intmska equ     02H             ; Mask port
ictmsk  equ     01H             ; Timer interrupt mask (to master)
icsmska equ     10H     ; Standard serial interrupt mask (to master)
icsvcta equ     0CH     ;Interrupt vector for standard interface

icEOI   equ     20H             ; generic end of interrupt for intcmd
kbfifosiz equ   64              ; size of fifo buffer in IO.SYS


; miscellaneous constants

ctrlP   equ     10H             ; ^P.
ctrl_q  equ     11H             ; ^Q
ctrl_s  equ     13H             ; ^S
printkey equ    00FFH           ; Scan code of unshifted PRINT key.
brkstp  equ     0096H           ; Scan code of unshifted break/stop key.
mntrgh  equ     bufsiz*3/4      ; High XON/XOFF trigger = 3/4 of buffer full.

; 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.

datas   segment public 'datas'
        extrn   drives:byte, flags:byte, trans:byte, ttyact:byte
        extrn   filtst:byte     ;* in mssker
        extrn   portval:word, port1:byte, port2:byte, port3:byte, port4:byte
        extrn   lclexit:word
        extrn   comand:byte, dmpname:byte                       ; [jrd]
        extrn   kbdflg:byte, rxtable:byte

;- common variables -----
curkey_mode     db      0
keypad_mode     db      0
kanji_smode     db      0       ; Kanji 1st/2nd byte indicator
kanji_rmode     db      0
kanji_scode     db      0
kanji_rcode     db      0
keyin_dos       db      0
vt100_flags     db      0
;------------------------

pcnet           db      0       ; 2.30 global --> 2.31 local

kanjis1         db      0       ; storage for Kanji 1st byte
kanjir1         db      0
kanjio1         db      0       ; storage for DEC Kanji code
kanjio2         db      0

param_dst       dw      ?
mdstreg db      ?               ; modem status register

machnam db      'NEC PC-9801 (KEK v1.10)$'
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$'
hnd1    db      cr,lf,'Enter a file handle.  Check your DOS manual if you are '
        db      cr,lf,'not certain what value to supply (generally 3).$'
hnd2    db      cr,lf,'Handle: $'
hnderr  db      cr,lf,'Warning: Handle not known.'
deverr  db      cr,lf,'Any routine using the communications port will'
        db      cr,lf,'probably not work.$'
hndhlp  db      cr,lf,'A one to four digit file handle $'
dev1    db      cr,lf,'Device: $'
devhlp  db      cr,lf,'Name for your systems auxiliary port $'
badbd   db      cr,lf,'Unimplemented baud rate$'
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,' 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$'

rdbuf   db      80 dup (?)      ; temp buf [jrd]

tmpbuf          db      80 DUP (?)

test_hndl       dw      ?
test_fnam       db      'KERMIT.TST',0

shkmsg  db      'Not implemented.'
shklen  equ     $-shkmsg
setktab db      0
setkhlp db      0
crlf    db      cr,lf,'$'
delstr  db      BS,BS,'  ',BS,BS,'$'    ; Delete string
delscr  db      ESCAPE,'[2J$'           ; Delete screen

scn_color       dw      0507h

save_cur        db      ESCAPE,'[s$'    ; save cursor
restore_cur     db      ESCAPE,'[u$'    ; resoter cursor
home_cur        db      ESCAPE,'[H$'    ; home cursor

; If delete code moves cursor then BS over code, BS over bad char, space
; over both to erase from screen, BS twice to restore cursor position.
clrlin  db      cr,'$'                  ; Clear line (just the cr part).
clreol  db      ESCAPE,'[K$'    ; Clear to end of line.
telflg  db      0               ; non-zero if we're a terminal.
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
xofsnt  db      0               ; Say if we sent an XOFF.
xofrcv  db      0               ; Say if we received an XOFF.

prthnd  dw      0               ; Port handle.
temp    dw      0
temp1   dw      ?               ; Temporary storage.
temp2   dw      ?               ; Temporary storage.
prtstr  db      20 dup(?)       ; Name of auxiliary device

; Entries for choosing communications port
comptab db      7               ; Number of options
        mkeyw   '1',1
        mkeyw   '2',2
        mkeyw   '3',3
        mkeyw   'COM1',1
        mkeyw   'COM2',2
        mkeyw   'COM3',3
        mkeyw   'UB-NETCI','N'
        mkeyw   '   ',0         ; port is not present, for Status

ourarg  termarg <>
modem   mdminfo <mndata,mnst1a,mncmda,0,0,0,0>
timer   tmrinfo <tmdata,tmcmda,tmsela>

;++ The following structure must be initialized as in MSSKER
;
portn   prtinfo <0FFFFh,0,defpar,1,0,defhand,floxon>

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

vthlp   db      ' one of the following:',cr,lf
        db      '  terminal types of: None, VT102, or Tek4014',cr,lf
        db      '  Keyclick (on/off)      '
        db      '  Keyinput (CON/direct)  ',cr,lf
        db      '  Color (white,yellow...)'
        db      '  Highlight (cyan,green...)',cr,lf
        db      '  AutoTek (on/off)       ',
        db      '  Kanji-code (DECcode,ShiftJIS,none)',cr,lf
        db      '$'

; <<< DO NOT forget to update the number of items at 'vttbl' when you add
;     new item to the following list >>>
vttbl   db      13
        mkeyw   'AutoTek',AUTOTEK_BIT+200H
        mkeyw   'Blink',BLINK_BIT+200H
        mkeyw   'Color',300H
        mkeyw   'Cursor',CURSOR_BIT+200H
        mkeyw   'Highlight',301H
        mkeyw   'Kanji-Code',400H
        mkeyw   'Keyclick',KEYCLICK_BIT+200H
        mkeyw   'Keyinput',500H
        mkeyw   'LoopTest',LOOPTEST_BIT+200H
        mkeyw   'None',ttgenrc+100H     ; note 100H flag for decoding here
        mkeyw   'Tek4014',tttek+100H
        mkeyw   'VT102',ttvt100+100H
        mkeyw   'Wrap',AUTOWRAP_BIT+200H
; <<< DO NOT forget to update the number of items at 'vttbl' when you add
;     new item to the above list >>>

ontab   db      2
        mkeyw   'off',0
        mkeyw   'on',1

colortab        db      8
        mkeyw   'black',0
        mkeyw   'blue',1
        mkeyw   'cyan',5
        mkeyw   'green',4
        mkeyw   'magenta',3
        mkeyw   'red',2
        mkeyw   'white',7
        mkeyw   'yellow',6

kanjitab        db      3
        mkeyw   'DEC-code',2
        mkeyw   'None',0
        mkeyw   'Shift-JIS',4

keyintab        db      2
        mkeyw   'CON   ',1
        mkeyw   'direct',0

; this table is indexed by the baud rate definitions given in
; pcdefs.  Unsupported baud rates should contain FF.

; Baudrate clock count table for 5/10 MHz CPU
        even
bddat5  label   word                    ; AHS 29-MAY-86
        dw      00D30H          ; 45.5 baud
        dw      00C00H          ; 50 baud
        dw      00800H          ; 75 baud
        dw      00574H          ; 110 baud
        dw      00476H          ; 134.5 baud
        dw      00400H          ; 150 baud
        dw      00200H          ; 300 baud
        dw      00100H          ; 600 baud
        dw      00080H          ; 1200 baud
        dw      00055H          ; 1800 baud
        dw      0004DH          ; 2000 baud
        dw      00040H          ; 2400 baud
        dw      00020H          ; 4800 baud
        dw      00010H          ; 9600 baud
        dw      00008H          ; 19200 baud
        dw      00004H          ; 38400 baud (not tested - may not work)
        dw      0FFFFH
        dw      0FFFFH
        dw      0FFFFH

; Baud rate clock count table for 8 MHz CPU

bddat8  label   word                    ; AHS 29-MAY-86
        dw      0FFFFH          ; 45.5 baud
        dw      0FFFFH          ; 50 baud
        dw      00680H          ; 75 baud
        dw      0FFFFH          ; 110 baud
        dw      0FFFFH          ; 134.5 baud
        dw      00340H          ; 150 baud
        dw      001A0H          ; 300 baud
        dw      000D0H          ; 600 baud
        dw      00068H          ; 1200 baud
        dw      0004EH          ; 1800 baud
        dw      0FFFFH          ; 2000 baud
        dw      00034H          ; 2400 baud
        dw      0001AH          ; 4800 baud
        dw      0000DH          ; 9600 baud
        dw      0FFFFH          ; 19200 baud
        dw      0FFFFH          ; 38400 baud (not tested - may not work)
        dw      0FFFFH
        dw      0FFFFH
        dw      0FFFFH

baudlen equ     ($-bddat8)/2     ; number of entries above

unkbaud         db      ' Unk ' ; must be 5 characters
baudname        db      ' 45.5'
                db      '  50 '
                db      '  75 '
                db      ' 110 '
                db      '134.5'
                db      ' 150 '
                db      ' 300 '
                db      ' 600 '
                db      ' 1200'
                db      ' 1800'
                db      ' 2000'
                db      ' 2400'
                db      ' 4800'
                db      ' 9600'
                db      '19200'
                db      '38400'
                db      '57.6K'
                db      '115 K'
BAUDNSIZ        equ     18

parityname      db      'even'          ; must be 4 characters
                db      'mark'
                db      'none'
                db      'odd '
                db      'spc '

lclename        db      'loc'
remename        db      'rem'

axsave          dw      ?
portinia        dw      0

dmphand         dw      ?               ; file handle for dump file

oldsera_ofs     dw      ?
oldsera_sgm     dw      ?
oldmska         db      ?
oldmsdat        db      ?

; variables for serial interrupt handler
        even
source  db      bufsiz DUP (?)  ; Buffer for data from port.
        db      2 DUP (?)       ; guard for source.
srcpnt  dw      0               ; Pointer in buffer (DI).
count   dw      0               ; Number of chars in int buffer.
rcvpnt  dw      0               ; Save SI register here.
mdmhand db      0               ; modem status register, current

; buffer for network

xmtbuf  db      NETBUFLEN DUP (0)       ; Buffer for Network xfer.
        db      2 DUP (0)               ; guard
xmtpnt  dw      0
xmtcnt  dw      0

; Function key definition tables

ker_keydef      db      0FEh,'f 01 ',0FFh,062h, 8 dup (0)       ; f 1
                db      0FEh,'f 02 ',0FFh,063h, 8 dup (0)       ; f 2
                db      0FEh,'f 03 ',0FFh,064h, 8 dup (0)       ; f 3
                db      0FEh,'f 04 ',0FFh,065h, 8 dup (0)       ; f 4
                db      0FEh,'f 05 ',0FFh,066h, 8 dup (0)       ; f 5
                db      0FEh,'f 06 ',0FFh,067h, 8 dup (0)       ; f 6
                db      0FEh,'f 07 ',0FFh,068h, 8 dup (0)       ; f 7
                db      0FEh,'f 08 ',0FFh,069h, 8 dup (0)       ; f 8
                db      0FEh,'f 09 ',0FFh,06Ah, 8 dup (0)       ; f 9
                db      0FEh,'f 10 ',0FFh,06Bh, 8 dup (0)       ; f10
                db      0FEh,'F 01 ',0FFh,082h, 8 dup (0)       ; shift f 1
                db      0FEh,'F 02 ',0FFh,083h, 8 dup (0)       ; shift f 2
                db      0FEh,'F 03 ',0FFh,084h, 8 dup (0)       ; shift f 3
                db      0FEh,'F 04 ',0FFh,085h, 8 dup (0)       ; shift f 4
                db      0FEh,'F 05 ',0FFh,086h, 8 dup (0)       ; shift f 5
                db      0FEh,'F 06 ',0FFh,087h, 8 dup (0)       ; shift f 6
                db      0FEh,'F 07 ',0FFh,088h, 8 dup (0)       ; shift f 7
                db      0FEh,'F 08 ',0FFh,089h, 8 dup (0)       ; shift f 8
                db      0FEh,'F 09 ',0FFh,08Ah, 8 dup (0)       ; shift f 9
                db      0FEh,'F 10 ',0FFh,08Bh, 8 dup (0)       ; shift f10
                db      0FFh,036h, 4 dup (0)    ; ROLL UP
                db      0FFh,037h, 4 dup (0)    ; ROLL DOWN
                db      0FFh,038h, 4 dup (0)    ; INS
                db      0FFh,039h, 4 dup (0)    ; DEL
                db      0FFh,03Ah, 4 dup (0)    ; up arrow
                db      0FFh,03Bh, 4 dup (0)    ; left arrow
                db      0FFh,03Ch, 4 dup (0)    ; right arrow
                db      0FFh,03Dh, 4 dup (0)    ; down arrow
                db      0FFh,03Eh, 4 dup (0)    ; HOME CLR
                db      0FFh,03Fh, 4 dup (0)    ; HELP
                db      0FFh,0AEh, 4 dup (0)    ; shift HOME CLR
KEYDEF_SIZE = $ - ker_keydef + 2

DOS_keydef      db      KEYDEF_SIZE dup (?)

;
        even
        dw      80 DUP (?)      ; local stack for interrupt processing
mnstk   dw      ?
mnsp    dw      ?               ; remote stack info
mnsseg  dw      ?

baud_set        db      ?

scrn_page       db      0

; mode line buffer
mode_len        db      0
                db      'Esc-chr: '
mode_esc        db      '^]'
                db      '  help: '
mode_hlp        db      '^]'
                db      '?  port:'
mode_prt        db      '1'
                db      ' speed:'
mode_spd        db      '     '
                db      ' parity:'
mode_pty        db      'none'
                db      ' echo:'
mode_ech        db      'rem'
                db      ' '
mode_typ        db      'VT102       '
                db      ' '
mode_prn        db      '   '
MODE_LINE_LENG  = $ - mode_len - 1

onmsg           db      'off'
                db      'on '
colmsg          db      'black  '
                db      'blue   '
                db      'red    '
                db      'magenta'
                db      'green  '
                db      'cyan   '
                db      'yellow '
                db      'white  '
knjmsg          db      'none     '
                db      'none     '
                db      'DEC-code '
                db      'DEC-code '
                db      'shift-JIS'
                db      'shift-JIS'
keyinmsg        db      'direct'
                db      'CON   '

vstmsg          db      '<Terminal status>',cr,lf
                db      '  Keyclick: '
vstmsg_key      db      '    '
                db      '  Keyinput: '
vstmsg_keyin    db      '      '
                db      '  Color: '
vstmsg_col      db      '        '
                db      '  Highlight: '
vstmsg_high     db      '        '
                db      cr,lf,'  Kanji-send : '
vstmsg_sknj     db      '          '
                db      '  Kanji-receive : '
vstmsg_rknj     db      '          '
                db      cr,lf,'  AutoTek: '
vstmsg_autot    db      '    '
                db      '  Wrap: '
vstmsg_autow    db      '    '
                db      '$'

datas   ends

code    segment public 'code'
        extrn   comnd:near, dopar:near, prserr:near, atoi:near, prompt:near
        extrn   isfile:near     ;* in mssker
        extrn   sleep:near, msuinit:near, keybd:near

        extrn   vt100:near, vt100_ini:near
        extrn   vt100_save:near, vt100_restore:near, vt100_modlin:near
        extrn   vt100_dump:near, vt100_color:near

        extrn   tek4014:near, tek4014_ini:near
        extrn   tek4014_save:near, tek4014_restore:near, tek4014_modlin:near

        assume  cs:code,ds:datas

;-----------------
; Utility Package
;-----------------

NOUT    PROC    NEAR
; Copy numeric value from AX to ASCII buffer indicated by DI.
; DI is updated.

        mov     dx,0
        mov     bx,10
        div     bx
        push    dx              ; save remainder digit
        or      ax,ax           ; anything left?
        jz      nout1           ; no, start output phase
        call    nout
nout1:  pop     ax              ; retrieve a digit
        add     al,'0'          ; make it ASCII
        stosb                   ; put it in buffer
        ret
NOUT    ENDP

;-------------------
is_kanji1       proc    near
;
; Check if al is Kanji 1st byte (stc) or not (clc)
;
        cmp     al,81h
        jb      is_kanji1_no
        cmp     al,0FCh
        ja      is_kanji1_no
        cmp     al,9fh
        jbe     is_kanji1_yes
        cmp     al,0E0h
        jae     is_kanji1_yes
is_kanji1_no:
        clc
        ret
is_kanji1_yes:
        stc
        ret
is_kanji1       endp

;-------------------
jis2s   proc    near
;
; Convert JIS Kanji code in AX to shift-JIS Kanji code
;       ah      2nd byte
;       al      1st byte
;
        test    al,1
        jz      jis2s1
        add     ah,1Fh
        jmp     jis2s2
jis2s1:
        add     ah,7Dh
jis2s2:
        cmp     ah,7Fh
        jb      jis2s3
        add     ah,1
jis2s3:
        sub     al,21h
        shr     al,1
        add     al,81h
        cmp     al,9Fh
        jbe     jis2s4
        add     al,40h
jis2s4:
        ret
jis2s   endp

;-------------------
s2jis   proc    near
;
; Convert Shift JIS Kanji code in AX to JIS Kanji code
;       ah      2nd byte
;       al      1st byte
;
        cmp     al,9Fh
        ja      s2jis1
        sub     al,71h
        jmp     s2jis2
s2jis1:
        sub     al,0B1h
s2jis2:
        shl     al,1
        inc     al
        cmp     ah,7Fh
        jbe     s2jis3
        dec     ah
s2jis3:
        cmp     ah,9Eh
        jb      s2jis4
        sub     ah,7Dh
        inc     al
        jmp     s2jis5
s2jis4:
        sub     ah,1Fh
s2jis5:
        ret
s2jis   endp

set_keydef      proc    near
; Save MS-DOS key definition table and set new key definition table.
; This is done by calling NEC-PC98 extended bios.

        push    ax
        push    cx
        push    dx

        mov     dx,offset DOS_keydef
        mov     ax,0
        mov     cl,0Ch
        int     0DCh
        mov     dx,offset ker_keydef
        mov     ax,0
        mov     cl,0Dh
        int     0DCh

        pop     dx
        pop     cx
        pop     ax
        ret
set_keydef      endp

reset_keydef    proc    near
; Restore MS-DOS key definition table

        push    ax
        push    cx
        push    dx

        mov     dx,offset DOS_keydef
        mov     ax,0
        mov     cl,0Dh
        int     0DCh

        pop     dx
        pop     cx
        pop     ax
        ret
reset_keydef    endp


SCRN_CHK        PROC    NEAR
; Check the display screen. If it is not DOS page, save the current page
; and return to DOS page.

        cmp     scrn_page,1     ; VT100 page ?
        jne     scrn_chk1       ; ne = no.
        call    vt100_save
        jmp     scrn_chkx
scrn_chk1:
        cmp     scrn_page,2     ; TEK page ?
        jne     scrn_chk2       ; ne = no.
        call    tek4014_save
        jmp     scrn_chkx
scrn_chk2:
        jmp     scrn_chk_ex
scrn_chkx:
        push    ax
        push    dx
        mov     ah,prstr
        mov     dx,offset restore_cur
        int     dos
        pop     dx
        pop     ax
scrn_chk_ex:
        mov     scrn_page,0     ; force to DOS page
        ret
SCRN_CHK        ENDP

SET_MODLIN      PROC    NEAR
; set the mode line buffer
;
        push    es
        mov     ax,ds
        mov     es,ax
;
        mov     al,' '
        mov     ah,trans.escchr
        cmp     ah,020h
        jge     set_modlin1
        mov     al,'^'
        or      ah,040h
set_modlin1:
        mov     word ptr mode_esc,ax
        mov     word ptr mode_hlp,ax
;
        mov     al,ourarg.baudb
        mov     si,offset unkbaud       ; Assume unknown baud.
        mov     cx,5                    ; length of baud space
        cmp     al,BAUDNSIZ             ; too big?
        jnb     set_modlin2             ; yes, use default
        mul     cl
        xor     ah,ah
        add     ax,offset baudname
        mov     si,ax
set_modlin2:
        mov     di,offset mode_spd
        rep     movsb
;
        mov     al,ourarg.prt
        cmp     al,'N'
        je      set_modlin3
        add     al,'0'                  ; convert to character
set_modlin3:
        mov     mode_prt,al
;
        mov     al,ourarg.parity
        xor     ah,ah
        mov     cx,4
        imul    cl
        add     ax,offset parityname
        mov     si,ax
        mov     di,offset mode_pty
        rep     movsb
;
        mov     si,offset lclename
        test    ourarg.flgs,lclecho
        jnz     set_modlin4
        mov     si,offset remename
set_modlin4:
        mov     cx,3
        mov     di,offset mode_ech
        rep     movsb
;
        pop     es
        ret
SET_MODLIN      ENDP

ENT_VT  PROC    NEAR
        cmp     scrn_page,1             ; VT screen ?
        je      ent_vt1                 ; e = yes. terminal screen. keep going

        push    ax
        push    dx
        mov     ah,prstr
        mov     dx,offset save_cur
        int     dos
        mov     ah,prstr
        mov     dx,offset home_cur
        int     dos
        pop     dx
        pop     ax

        call    vt100_restore
        mov     scrn_page,1
ent_vt1:
        mov     dx,offset mode_len
        call    vt100_modlin
        ret
ENT_VT  ENDP

ENT_TK  PROC    NEAR
        cmp     scrn_page,2             ; TEK screen ?
        je      ent_tk1

        push    ax
        push    dx
        mov     ah,prstr
        mov     dx,offset save_cur
        int     dos
        mov     ah,prstr
        mov     dx,offset home_cur
        int     dos
        pop     dx
        pop     ax

        call    tek4014_restore
        mov     scrn_page,2
ent_tk1:
        mov     dx,offset mode_len
        call    tek4014_modlin
        ret
ENT_TK  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

; 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.

CLRBUF  PROC    NEAR
        cli
        mov     srcpnt,offset source    ; receive circular buffer
        mov     count,0
        sti
        call    prtchr                  ; empty any intermediate buffers
          nop                           ; got a char, clear again
          nop
          nop
        cli
        push    ax
        mov     ax,offset source        ; reset pointers
        mov     rcvpnt,ax
        mov     srcpnt,ax
        mov     count,0
        pop     ax
        sti
        ret
CLRBUF  ENDP

; Clear to the end of the current line.  Returns normally.

CLEARL  PROC    NEAR
        push ax
        push dx
        call    scrn_chk
        mov ah,prstr
        mov dx,offset clreol
        int dos
        pop dx
        pop ax
        ret
CLEARL  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     dx,mnst1a       ; read status
        in      al,dx
        and     al,80h          ; set only DR bit
        mov     mdstreg,al
        mov     dx,mnrdsa       ; read signal
        in      al,dx
        and     al,60h          ; set CS and CD only
        or      mdstreg,al
;
        mov     ah,prstr
        mov     dx,offset msmsg1        ; modem ready msg
        test    mdstreg,80h             ; 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,20h             ; 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,40h             ; CTS asserted?
        jz      shomd3                  ; z = no
        mov     dx,offset msmsg6        ; say not asserted
shomd3: 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  PROC    NEAR
        push    cx                      ; save regs
        cmp     flowoff,0               ; Are we doing flow control.
        je      outch2
        xor     cx,cx
        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.
        xor     cx,cx
        mov     al,ah           ; Parity routine works on AL.
        call    dopar           ; Set parity appropriately.
                                ; Begin revised output routine
        mov     ah,al
        mov     temp,ax         ; put data there
        cmp     ourarg.prt,'N'          ; Network port ?
        jne     outch6                  ; ne = No.
        pop     dx
        pop     cx
        jmp     outchn
outch6:
        mov     dx,modem.mdstat
outch3: in      al,dx
        test    al,txrdy
        jnz     outch4
        loop    outch3
        jmp     outch5
outch4: mov     al,ah
        mov     dx,modem.mddat
        out     dx,al
outch5: pop     dx
        pop     cx
        jmp     rskp
;
outchn:
        push    bx
        mov     bx,offset xmtbuf        ; set xfer address
        add     bx,xmtcnt               ; count of chars in buffer
        mov     [bx],ah                 ; put char in buffer
        pop     bx
        inc     xmtcnt                  ; count of items in this buffer
        cmp     xmtcnt,NETBUFLEN        ; is buffer full now?
        jae     outchn1                 ; ae = buffer is full, send it now.
        cmp     ah,trans.seol           ; end of packet?
        je      outchn1                 ; e = yes, send buffer.
        cmp     ah,flowon               ; flow control?
        je      outchn1                 ; e = yes, always expedite
        cmp     ah,flowoff              ; ditto for flow off
        je      outchn1
        cmp     ttyact,0                ; are we in Connect mode?
        je      outchn2                 ; e = no, wait for more before sending
outchn1:
        call    send                    ; network send routine
        jc      outchn3                 ; c = error
outchn2:
        jmp     rskp                    ; good exit
outchn3:
        ret                             ; bad  exit

OUTCHR  ENDP

SEND    PROC    NEAR
        push    ax
        push    bx
        push    cx
        push    es
;
        push    ds
        pop     es                      ; ES = DS
        mov     bx,offset xmtbuf        ; xfer start address
        mov     ah,NETCI_WRITE          ; set function
        mov     al,NETCI_PORT           ; set port
;
send0:
        mov     cx,xmtcnt               ; packet length
        jcxz    send1
        int     NETCI_INT               ; send packet
        cmp     cx,xmtcnt               ; all done ?
        jae     send1                   ; e = yes.
        pop     ax
        mov     bx,offset xmtbuf
        add     bx,cx                   ; update xfer address
        sub     xmtcnt,cx
        jmp     send0
;
send1:
        mov     xmtcnt,0
        pop     es
        pop     cx
        pop     bx
        pop     ax
        clc
        ret

SEND    ENDP
; This routine blanks the screen.  Returns normally.

CMBLNK  PROC    NEAR
        push ax                 ; save some registers
        push dx
        call    scrn_chk
        mov ah,prstr
        mov dx,offset delscr    ; delete screen.
        int     dos
        pop dx
        pop ax
        ret
CMBLNK  ENDP

; Homes the cursor.  Returns normally.

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

; Write a line at the bottom of the screen...
; the line is passed in dx, terminated by a $.  Returns normally.
putmod  proc    near
        call    scrn_chk
        push    dx              ; preserve message
        mov     dx,1800h        ; now address line 24
        call    poscur
        pop     dx              ; get message back
        mov     ah,prstr
        int     dos             ; write it out
        ret                     ; and return
putmod  endp

; clear the mode line written by putmod.  Returns normally.
clrmod  proc    near
        call    scrn_chk
        mov     dx,1800h
        call    poscur          ; Go to bottom row.
        call    clearl          ; Clear to end of line.
        ret
clrmod  endp

; Put a help message on the screen.
; Pass the message in ax, terminated by a null.  Returns normally.
puthlp  proc    near
        push    dx              ; save regs
        push    si
        push    ax              ; preserve this
        call    scrn_chk
        call    cmblnk
        call    locate
        mov     ah,prstr
        mov     dx,offset crlf
        int     dos
        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     ah,prstr
        mov     dx,offset crlf
        int     dos
        pop     si
        pop     dx
        ret
puthlp  endp

; Set the baud rate for the current port, based on the value
; in the portinfo structure.  Returns normally.

DOBAUD  PROC    NEAR
        push    ax
        push    bx
        push    dx
;
        mov     axsave,ax
        mov     bx,portval
        mov     ax,[bx].baud
        shl     ax,1
;
;  determine CPU clock
;
        push    ax
        in      al,042h
        test    al,0C0h
        jz      c5mhz
        test    al,020h
        jz      c5mhz
c8mhz:
        mov     bx,offset bddat8
        jmp     dobd0
c5mhz:
        mov     bx,offset bddat5
dobd0:
        pop     ax
        add     bx,ax
        cmp     word ptr [bx],0FFFFh
        jne     dobd1
        mov     ah,prstr
        mov     dx,offset badbd
        int     dos
        jmp     dobd_ex
dobd1:
        mov     dx,timer.tmcmd
        mov     al,timer.tmsel
        out     dx,al
        mov     ax,[bx]
        mov     dx,timer.tmdat
        out     dx,al
        mov     al,ah
        out     dx,al
dobd_ex:
        pop     dx
        pop     bx
        pop     ax
        ret                     ; Must be set before starting Kermit.
DOBAUD  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
        cmp     flags.comflg,'N'        ; Network ?
        je      gbaud1                  ; e = yes. do nothing here.
        push    bx
        cmp     baud_set,1      ; Did we already set baud rate?
        je      gbaud0          ; yes, so just leave
        mov     bx,portval
        mov     [bx].baud,B9600
        mov     baud_set,1
gbaud0:
        pop     bx
gbaud1:
        ret
GETBAUD ENDP

; Set the mode for the current port.  This is part of the serial
; initialization routine.

DOMODE  PROC    NEAR
        push    ax
        push    cx
        push    dx
;
        mov dx,modem.mdcom      ;send 3 zeros to command port to reset chip
        mov al,0
        out dx,al
        mov al,0
        out dx,al
        mov al,0
        out dx,al
        mov al,cmode            ;enable mode setting
        out dx,al
        mov cx,100              ;allow chip time to reset
mode1:  loop mode1
        mov al,mmode            ;mode: 16x rate, 8 data, no parity, 1 stop
        out dx,al
        mov cx,100
mode2:  loop mode2
        mov al,ccmd             ;RTS & DTR high, RX & TX enabled, reset errors
        out dx,al
;
        pop     dx
        pop     cx
        pop     ax
        ret
DOMODE  ENDP

; Use for DOS 2.0 and above.  Check the port status.  If no data, skip
; return.  Else, read in a char and return.
; Note added by [jrd]: The test for char-at-input-port is int 21h function
; 44h (ioctl) sub function 6 (get input status). On many systems an FFH will
; be reported (meaning Ready) even though no char is available; the Ready
; indication is misleading. In such cases the system will wait for a char
; and will appear to be hung. A preferrable method is to use the ROM Bios
; call int 14H function 3 (get port status) and if the lsb of the returned
; 8 bits in AH is 1 then a char is availble at the port; this assumes that
; the machine emulates this ROM Bios operation.
; Lastly, if the current code is used and the system hangs then reboot
; and say  ECHO Hello >COM1  before running Kermit; this should make MSDOS
; truely aware of the port's actual status. Dark grey magic. Good luck! [jrd]
PRTCHR  PROC    NEAR
prtch0:
        call    chkxon
        cmp     ourarg.prt,'N'
        jne     prtch3
        jmp     prtchn
prtch3:
        cmp     count,0
        jnz     prtch2
        jmp     rskp            ; No data -check console
prtch2:
        pushf
        cli                     ; disable interrupts while manipulating pointers
        mov     si,rcvpnt
        lodsb                   ; get a byte
        cmp     si,offset source + bufsiz       ; bigger than buffer?
        jb      prtch1          ; no, keep going
        mov     si,offset source        ; yes wrap around
prtch1:
        dec     count
        mov     rcvpnt,si
        mov     dx,count
        popf
        ret

prtchn:
        cmp     count,0                 ; Data in buffer?
        je      prtchn0                 ; e = No. Get them from port.
        jmp     prtchn2
prtchn0:
        push    ax
        push    bx
        push    cx
        push    es
        mov     ax,offset source
        mov     rcvpnt,ax
        mov     srcpnt,ax
 ;
        mov     ah,NETCI_READ
        mov     al,NETCI_PORT
        mov     bx,offset source
        mov     cx,bufsiz
        push    ds
        pop     es
        int     NETCI_INT
        mov     count,cx
        add     srcpnt,cx
        pop     es
        pop     cx
        pop     bx
        pop     ax
        cmp     count,0
        jnz     prtchn2
        jmp     rskp
prtchn2:
        pushf
        cli                     ; disable interrupts while manipulating pointers
        mov     si,rcvpnt
        lodsb                   ; get a byte
        dec     count
        mov     rcvpnt,si
;
;       I'm not sure the floowings are necesary or not.
;       The handshake should be done at network level.
;
;       check the data
;
;@@     push    bx
;@@     or      al,al
;@@     jz      prtchn5         ; Ignore nulls.
;@@     mov     ah,al           ; copy the character in AH
;@@     and     ah,parmsk       ; apply parity mask
;@@     mov     bx,portval
;@@     cmp     [bx].floflg,0   ; Doing flow control?
;@@     je      prtchn4         ; Nope.
;@@     mov     bx,[bx].flowc   ; Flow control character (BH=XON, BL=XOFF).
;@@     cmp     ah,bl           ; Is it an XOFF?
;@@     jne     prtchn3         ; Nope, go on.
;@@     mov     xofrcv,true     ; Set the flag.
;@@     jmp     short prtchn5
prtchn3:
;@@     cmp     ah,bh           ; Get an XON?
;@@     jne     prtchn4         ; No, go on.
;@@     mov     xofrcv,false    ; Clear our flag.
;@@     jmp     short prtchn5
;
prtchn4:
;@@     pop     bx
        mov     dx,count
        popf
        ret

prtchn5:
;@@     pop     bx
;@@     popf
;@@     jmp     prtchn

PRTCHR  ENDP

; Local routine to see if we have to transmit an xon
chkxon  proc    near
        push    bx
        mov     bx,portval
        cmp     [bx].floflg,0   ; doing flow control?
        je      chkxo1          ; no, skip all this
        cmp     xofsnt,false    ; have we sent an xoff?
        je      chkxo1          ; no, forget it
        cmp     count,mntrgh    ; below trigger?
        jae     chkxo1          ; no, forget it
        mov     ax,[bx].flowc   ; ah gets xon
        call    outchr          ; send it
          nop
          nop
          nop                     ; in case it skips
        mov     xofsnt,false    ; remember we've sent the xon.
chkxo1: pop     bx              ; restore register
        ret                     ; and return
chkxon  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
; NOTE: for systems with a time-of-day clock uncomment the line below
; (call sleep) to provide an interval for the host to respond.

;;;     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 = null
        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


; Send a break out the current serial port.  Returns normally.
SENDBR  PROC    NEAR            ; Normal Break
        mov     dx,modem.mdcom  ; set command port
        mov     al,cbrk+ccmd    ; add break to normal command
        out     dx,al
        sub     cx,cx           ; counter 0 = 65536
sndbr1: loop    sndbr1          ; wait a while
        mov     al,ccmd         ; restore normal command
        out     dx,al
        ret
SENDBR  ENDP
SENDBL  PROC    NEAR            ; Long Break
        mov     dx,modem.mdcom  ; set command port
        mov     al,cbrk+ccmd    ; add break to normal command
        out     dx,al
        push    dx              ; save I/O address
        call    pcwait
        mov     al,ccmd
        pop     dx              ; restore I/O address
        out     dx,al           ; restore normal command
        ret
SENDBL  ENDP

; Position the cursor according to contents of DX:
; DH contains row, DL contains column.  Returns normally.
POSCUR  PROC    NEAR
        push    di
        mov     di,offset tmpbuf
        mov     byte ptr [di],ESCAPE
        mov     byte ptr [di+1],'['
        add     di,2
        mov     al,dh
        xor     ah,ah
        inc     ax
        push    dx
        call    nout
        mov     byte ptr [di],';'
        inc     di
        pop     dx
        mov     al,dl
        xor     ah,ah
        inc     ax
        call    nout
        mov     byte ptr [di],'H'
        mov     byte ptr [di+1],'$'
        mov     dx,offset tmpbuf
        mov     ah,prstr
        int     dos
        pop     di
        ret
POSCUR  ENDP

; Delete a character from the terminal.  This works by printing
; backspaces and spaces.  Returns normally.

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

; Move the cursor to the left margin, then clear to end of line.
; Returns normally.

CTLU    PROC    NEAR
        mov ah,prstr
        mov dx,offset clrlin
        int dos
        call clearl
        ret
CTLU    ENDP

; Called only when Kermit exits. Program pointer passed to mssker by
; proc chknet in word 'lclexit'.
; This is used as a local end routine.

NETCLOSE        PROC    NEAR
        cmp     pcnet,0                 ; already closed ?
        je      netclo1                 ; e = yes
        push    ax
        mov     ah,NETCI_CLOSE
        mov     al,NETCI_PORT
        int     NETCI_INT
        mov     pcnet,0
        pop     ax
netclo1:
        call    reset_keydef            ; reset key definition table
        ret
NETCLOSE        ENDP

; Open NETCI port

chknet  proc    near
        cmp     pcnet,0                 ; netport is closed ?
        jne     chknetx
        push    ax
        push    bx
        push    cx
        push    es
;
        push    cs
        pop     es
        mov     temp,0
        mov     bx,offset temp
        mov     cx,0
        mov     ah,NETCI_OPEN
        mov     al,NETCI_PORT
        int     NETCI_INT
        mov     lclexit,offset netclose
        call    clrbuf
        mov     xmtcnt,0
        mov     pcnet,2
;
        pop     es
        pop     cx
        pop     bx
        pop     ax
chknetx:
        clc
        ret
chknet  endp

;
; Set the current port.
;
COMS    PROC    NEAR
        mov dx,offset comptab   ; the table to examine
        mov bx,0                ; use keywords as help
        mov ah,cmkey            ; parse keyword from comptab
        call comnd
         jmp r                  ; no match
        cmp     bl,'N'          ; Network ?
        jne     coms1           ; ne = no
        jmp     comsn           ; Yes, setup for networks
coms1:
        mov     temp,bx
        mov     ah,cmcfm
        call    comnd                   ; Get a confirm.
         jmp    r                       ;  Didn't get a confirm.
        mov     bx,temp                 ; get port number/letter
        mov     flags.comflg,bl         ; remember port number
        xor     bh,bh                   ; clear high byte
        mov     bl,flags.comflg         ; get COMx number (1-3)
        push    bx
        pop bx
        mov     ax,offset port1
        mov     portval,ax
        call    inita
        clc
        ret
comsn:
        mov     temp,bx
        mov     ah,cmcfm
        call    comnd                   ; Get a confirm
         jmp    r                       ;  Didn't get a confirm
         nop
        call    serrst                  ; reset serial port
        call    chknet                  ; start network usage
        cmp     pcnet,0                 ; is network alive (non-zero)?
        jne     comsn4                  ; ne = yes
        stc
        ret                             ; return failure
comsn4:
        mov     portval,offset portn    ; set netowrk port data
        mov     flags.comflg,'N'        ; set the comm port flag.
        clc                             ; return sucess
        ret
COMS    ENDP

; Set heath emulation on/off.

VTS     PROC    NEAR
        mov     ah,cmkey                ; Parse another keyword.
        mov     bx,offset vthlp         ; Use this help
        mov     dx,offset vttbl         ; Use this table
        call    comnd
         jmp    r                       ; Vsetup always returns +1.
        cmp     bh,1h                   ; marker for terminal type?
        jne     vsetup_n1               ; ne = no
        jmp     vsetup_1
vsetup_n1:
        cmp     bh,2h                   ; marker for set term something on/off?
        jne     vsetup_n2               ; ne = no
        jmp     vsetup_2
vsetup_n2:
        cmp     bh,3h                   ; marker for color
        jne     vsetup_n3               ; ne = no
        jmp     vsetup_3
vsetup_n3:
        cmp     bh,4h                   ; marker for kanji
        jne     vsetup_n4               ; ne = no
        jmp     vsetup_4
vsetup_n4:
        cmp     bh,5
        jne     vsetup_n5
        jmp     vsetup_5
vsetup_n5:
        jmp     vsetup_ex
;
vsetup_1:
        push    bx
        mov     ah,cmcfm
        call    comnd
         jmp    vsetup_ex2
         nop
        pop     bx
        mov     flags.vtflg,bl          ; Set the terminal emulation type
        ret

vsetup_2:
        xor     bh,bh
        mov     param_dst,bx
        mov     ah,cmkey
        mov     bx,0
        mov     dx,offset ontab
        call    comnd
         jmp    r                       ; bad keyword
        push    bx
        mov     ah,cmcfm                ; get a confirm
        call    comnd
         jmp    vsetup_ex2              ; did not get a confirm
         nop
        mov     ax,param_dst
        pop     bx
        cmp     bl,0
        jne     vsetup_2_1
        not     al
        and     vt100_flags,al
        jmp     vsetup_2_2
vsetup_2_1:
        or      vt100_flags,al
vsetup_2_2:
        jmp     rskp

vsetup_3:
        mov     dx,offset scn_color
        xor     bh,bh
        add     dx,bx
        mov     param_dst,dx

        mov     ah,cmkey
        mov     bx,0
        mov     dx,offset colortab
        call    comnd
         jmp    r                       ; bad keyword
        push    bx
        mov     ah,cmcfm                ; get a confirm
        call    comnd
         jmp    vsetup_ex2              ; did not get a confirm
         nop
        pop     dx                      ; get old bx value to dx
        mov     bx,param_dst
        mov     byte ptr [bx],dl
        mov     ax,scn_color
        call    vt100_color
        jmp     rskp

vsetup_4:
        mov     ah,cmkey
        mov     bx,0
        mov     dx,offset kanjitab
        call    comnd
         jmp    r                       ; bad keyword
        push    bx
        mov     ah,cmcfm                ; get a confirm
        call    comnd
         jmp    vsetup_ex2              ; did not get a confirm
         nop
        pop     bx                      ; get old bx value to dx
        mov     kanji_scode,bl
        mov     kanji_rcode,bl
        jmp     rskp

vsetup_5:
        mov     ah,cmkey
        mov     bx,0
        mov     dx,offset keyintab
        call    comnd
         jmp    r
        push    bx
        mov     ah,cmcfm
        call    comnd
         jmp    vsetup_ex2
         nop
        pop     bx
        mov     keyin_dos,bl
        jmp     rskp

vsetup_ex:
        jmp     rskp
vsetup_ex2:
        pop     bx
        ret

VTS     ENDP


VTSTAT  PROC    NEAR    ; For Status display [jrd]
        push    ax
        push    bx
        push    cx
        push    dx
        push    si
        push    di
        push    es
;
        push    ds
        pop     es
        cld
        mov     si,offset onmsg
        mov     cx,3
        test    vt100_flags,KEYCLICK_BIT
        jz      vtstat1
        add     si,cx
vtstat1:
        mov     di,offset vstmsg_key
        rep     movsb

        mov     si,offset onmsg
        mov     cx,3
        test    vt100_flags,AUTOTEK_BIT
        jz      vtstat2
        add     si,cx
vtstat2:
        mov     di,offset vstmsg_autot
        rep     movsb

        mov     si,offset onmsg
        mov     cx,3
        test    vt100_flags,AUTOWRAP_BIT
        jz      vtstat3
        add     si,cx
vtstat3:
        mov     di,offset vstmsg_autow
        rep     movsb

        mov     si,offset colmsg
        mov     ax,scn_color
        mov     ah,0
        mov     cx,7
        imul    cl
        add     si,ax
        mov     di,offset vstmsg_col
        rep     movsb

        mov     si,offset colmsg
        mov     ax,scn_color
        xchg    ah,al
        mov     ah,0
        mov     cx,7
        imul    cl
        add     si,ax
        mov     di,offset vstmsg_high
        rep     movsb

        mov     si,offset knjmsg
        mov     ah,0
        mov     al,kanji_scode
        mov     cx,9
        imul    cl
        add     si,ax
        mov     di,offset vstmsg_sknj
        rep     movsb


        mov     si,offset knjmsg
        mov     ah,0
        mov     al,kanji_rcode
        mov     cx,9
        imul    cl
        add     si,ax
        mov     di,offset vstmsg_rknj
        rep     movsb

        mov     si,offset keyinmsg
        mov     cx,6
        cmp     keyin_dos,0
        je      vtstat9
        add     si,cx
vtstat9:
        mov     di,offset vstmsg_keyin
        rep     movsb

        mov     ah,prstr
        mov     dx,offset vstmsg
        int     dos
;
        pop     es
        pop     di
        pop     si
        pop     dx
        pop     cx
        pop     bx
        pop     ax
        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

        push    ax
        push    bx
        push    cx
        push    dx

        mov     dmphand,-1              ; preset illegal handle
        mov     dx,offset dmpname       ; name of disk file, from mssset
        mov     ax,dx                   ; where isfile wants name ptr
        call    isfile                  ; what kind of file is this?
        jc      dmp5                    ; c = no such file, create it
        test    byte ptr filtst.dta+21,1fh ; file attributes, ok to write?
        jnz     dmp0                    ; nz = no.
        mov     al,1                    ; writing
        mov     ah,open2                ; open existing file
        int     dos
        jc      dmp0                    ; c = failure
        mov     dmphand,ax              ; save file handle
        mov     bx,ax                   ; need handle here
        mov     cx,0ffffh               ; setup file pointer
        mov     dx,-1                   ; and offset
        mov     al,2                    ; move to eof minus one byte
        mov     ah,lseek                ; seek the end
        int     dos
        jmp     dmp1

dmp5:   test    filtst.fstat,80h        ; access problem?
        jnz     dmp0                    ; nz = yes
        mov     ah,creat2               ; file did not exist
        mov     cx,20h                  ; attributes, archive bit
        int     dos
        mov     dmphand,ax              ; save file handle
        jnc     dmp1                    ; nc = ok

dmp0:   call    beep
        pop     dx
        pop     cx
        pop     bx
        pop     ax
        clc
        ret

dmp1:   mov     ah,ioctl                ; is destination ready for output?
        mov     al,7                    ; test output status
        mov     bx,dmphand              ; handle
        int     dos
        jc      dmp0                    ; c = error
        cmp     al,0ffh                 ; ready?
        jne     dmp0                    ; ne = not ready.
;
        test    flags.vtflg,ttvt100
        jz      dmp_v1
        call    ent_vt
dmp_v1:
        mov     bx,dmphand              ; need file handle
        call    vt100_dump
;
        mov     bx,offset tmpbuf
        mov     byte ptr [bx],CTLZ      ; put EOF mark
        mov     dx,bx
        mov     bx,dmphand
        mov     cx,1
        mov     ah,write2
        int     dos                     ; write EOF
;
        mov     ah,close2               ; close the file now
        int     dos
;
        pop     dx
        pop     cx
        pop     bx
        pop     ax
        clc
        ret

DUMPSCR ENDP

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

; Initialize variables to values used by this routine.

lclini: mov     prthnd,0        ; No handle yet
        mov     flags.comflg,1  ; Communication port 1
        mov     scrn_page,0     ; start page is DOS screen
        mov     curkey_mode,0   ; cursor key is ANSI normal
        mov     keypad_mode,0   ; keypad is normal
        mov     vt100_flags,AUTOTEK_BIT+CURSOR_BIT+BLINK_BIT    ; set flags
        mov     kanji_scode,2   ; DEC kanji code
        mov     kanji_rcode,2
        mov     kanji_smode,0   ; 1st character must be Kanji 1st byte.
        mov     kanji_rmode,0
        mov     xmtcnt,0                ; clear counter for xfer
        or      flags.remflg,d8bit      ; display 8-bit
        call    set_keydef
        mov     lclexit,offset netclose
        call    msuinit         ; declare keyboard translator present
        call    vt100_ini
        call    tek4014_ini
        ret

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

; serial port interrupt routine.  This is not accessible outside this
; module, handles serial port receiver interrupts.

SERINT  PROC  NEAR
        push ds                 ; save these on remote stack
        push ax
        mov ax,seg datas        ; get our own data segment
        mov ds,ax
        mov mnsp,sp             ; save remote stack information
        mov mnsseg,ss
        mov sp,offset mnstk     ; switch to local stack
        mov ss,ax
        push es                 ; and save remaining registers
        push bp
        push di
        push si
        push dx
        push cx
        push bx
        mov es,ax
        call mnproc             ; process the interrupt
        mov al,icEOI
        mov dx,intcmda
        out dx,al
        pop bx                  ; restore registers from stack
        pop cx
        pop dx
        pop si
        pop di
        pop bp
        pop es
        mov ax,mnsseg           ; switch back to remote stack
        mov ss,ax
        mov ax,mnsp
        mov sp,ax
        pop ax
        pop ds
        iret

; handler for serial input

mnproc: cld
        mov di,srcpnt           ; get buffer pointer
        mov dx,modem.mdstat     ; is data available?
        in al,dx
        test al,rxrdy
        jz mnpro7
        mov dx,modem.mddat      ; read data
        in al,dx
        or al,al
        jz mnpro7               ; Ignore nulls.

; do NOT ignore rubouts, because TEK LOY code use this.
;       cmp al,7FH              ; Ignore rubouts, too.
;       jz mnpro7

        mov ah,al
;
; originally the following was
;
;       and ah,7fH              ; only consider low-order 7 bits for flow ctl.
; do NOT mask 8-th bit for flow control when parity is none.
;
        and ah,parmsk           ; apply parity mask for flow ctl.
        mov bp,portval
        cmp ds:[bp].floflg,0    ; Doing flow control?
        je mnpro4               ; Nope.
        mov bx,ds:[bp].flowc    ; Flow control char (BH = XON, BL = XOFF).
        cmp ah,bl               ; Is it an XOFF?
        jne mnpro3              ; Nope, go on.
        mov xofrcv,true         ; Set the flag.
        jmp short mnpro7
mnpro3: cmp ah,bh               ; Get an XON?
        jne mnpro4              ; No, go on.
        mov xofrcv,false        ; Clear our flag.
        jmp mnpro7
mnpro4: stosb
        cmp di,offset source + bufsiz
        jb mnpro5               ; not past end...
        mov di,offset source    ; wrap buffer around
mnpro5: mov srcpnt,di           ; update ptr
        inc count
        cmp ds:[bp].floflg,0    ; Doing flow control?
        je mnpro7               ; No, just leave.
        cmp xofsnt,true         ; Have we sent an XOFF?
        je mnpro7               ; Yes.
        cmp count,mntrgh        ; Past the high trigger point?
        jbe mnpro7              ; No, we're within our limit.
        mov ah,bl               ; Get the XOFF.
        call outchr             ; Send it.
         nop                    ;   ignore failure.
         nop
         nop
        mov xofsnt,true         ; Remember we sent it.
mnpro7: ret

SERINT  ENDP

; Initialization for using serial port.  Returns normally.

SERINI  PROC    NEAR
        cmp     flags.comflg,'N'        ;@@@@@
        je      serin1                  ;@@@@@
        call    inita

serin0:;;;;     call clrbuf     ; Clear input buffer.
;;        push    bx
;;        mov     bx,portval      ; get port
;;        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
serin1:
        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
        call    scrn_chk
        cmp portinia,0          ; Did we reset port already?
        je rsta0                ; Yes, so just leave.
        push es
        cli                     ; Disable interrupts
        xor ax,ax               ; Address low memory
        mov es,ax
        mov ax,oldsera_ofs      ; Restore interrupt vector
        mov es:[4*icsvcta],ax
        mov ax,oldsera_sgm
        mov es:[4*icsvcta+2],ax
        mov dx,intmska          ; restore old master controller mask
        mov al,oldmska
        out dx,al
        mov dx,mnmska           ; disable serial interrupts at port
;       mov al,txmsk+rxmsk+tbemsk
        mov al,oldmsdat
        out dx,al
        mov portinia,0          ; Remember port has been reset
        sti                     ; Allow interrupts
        pop es
rsta0:  ret

SERRST  ENDP

; Local routine to initialize the standard serial port

INITA   PROC    NEAR
        cmp     portinia,1      ; Did we initialize port already ?
        je      inita0          ; Yes, so just leave.
;
        cli                     ; Disable interrupts
        push    ax
        push    dx
        push    es
;
        mov     ax,offset port1
        mov     portval,ax
        xor     ax,ax
        mov     es,ax
        mov     ax,es:[4*icsvcta]       ; save interrupt vector for port1
        mov     oldsera_ofs,ax
        mov     ax,es:[4*icsvcta+2]
        mov     oldsera_sgm,ax
        mov     ax,offset serint        ; pointer to our routine
        mov     es:[4*icsvcta],ax       ; set interrupt routine offset
        mov     es:[4*icsvcta+2],cs     ;  and segment
        mov     dx,intmska
        in      al,dx
        mov     oldmska,al              ; save old master controller mask
;
        and     al,not icsmska          ; enable serial interrupt at master
        out     dx,al
        mov     dx,mnmska
        in      al,dx
        mov     oldmsdat,al
        and     al,0f8h
        or      al,rxmsk
        out     dx,al
        mov     modem.mddat,mndata
        mov     modem.mdstat,mnst1a
        mov     modem.mdcom,mncmda
        mov     timer.tmdat,tmdata
        mov     timer.tmcmd,tmcmda
        mov     timer.tmsel,tmsela
        call    domode
        call    dobaud
        mov     portinia,1
        call    clrbuf
;
        pop     es
        pop     dx
        pop     ax
        sti
inita0: ret
INITA   ENDP

;
; 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
;


; 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. Uses keyboard translator
; 20 March 1987 [jrd].
term    proc    near
        mov     kanji_smode,0           ; clear Kanji pending flag
        mov     kanji_rmode,0
        mov     argadr,ax               ; save argument ptr
        mov     si,ax                   ; this is source
        mov     di,offset ourarg        ; place to store arguments
        mov     ax,ds
        mov     es,ax                   ; address destination segment
        mov     cx,size termarg
        cld
        rep     movsb                   ; copy into our arg blk
        and     ourarg.flgs,not (prtscr) ; no screen printing at startup
        mov     ax,ourarg.captr
        mov     captrtn,ax              ; buffer capture routine
        mov     mode_len,0
        mov     ax,1001h
        test    vt100_flags,BLINK_BIT
        jz      term_01
        mov     ax,1000h
term_01:
        int     bios
        test    vt100_flags,CURSOR_BIT
        jz      term_02
        mov     ax,1100h
        int     bios
term_02:
        test    ourarg.flgs,modoff      ; mode line off?
        jnz     term_1
        call    set_modlin              ; setup mode line
        mov     mode_len,MODE_LINE_LENG
term_1:
        mov     parmsk,0ffh             ; parity mask, assume parity = None
        cmp     ourarg.parity,parnon    ; is parity None?
        je      term_2                  ; e = yes, keep all 8 bits
        mov     parmsk,07fh             ; else keep lower 7 bits
term_2:
        cmp     flags.vtflg,ttvt100     ; vt100 emulation ?
        je      term_vt                 ; e = yes.
        cmp     flags.vtflg,tttek       ; Tek4014 emulation ?
        je      term_tk                 ; e = yes.
        jmp     term0                   ; non supported terminal
;
;  vt100 emulation
term_vt:
        call    ent_vt
        jmp     term0
;
;  tek4014 emulation
term_tk:
        call    ent_tk
;
term0:
        test    vt100_flags,LOOPTEST_BIT
        je      term1
        jmp     term_tst1

term1:  call    portchr         ; get char from port, apply parity mask
        jnc     short term2     ; nc = no char, go on
        call    outtty          ; display and capture char
        jmp     term1           ; do quick loop back for more
term2:  call    keybd           ; keyboard translator to read and send text
        jnc     term1           ; nc = do not exit Connect mode
        ret

term_tst1:
        mov     ax,3D00h        ; open file (read only)
        mov     dx,offset test_fnam
        int     dos
        jc      term_tstz       ; if error, then normal operation
        mov     test_hndl,ax
term_tst2:
        call    portchr
        jnc     short term_tst3
        call    outtty
        jmp     term_tst2
term_tst3:
        mov     ah,3Fh          ; read file/device
        mov     dx,offset tmpbuf
        mov     bx,test_hndl
        mov     cx,8
        int     dos
        jc      term_tstx
        mov     cx,ax
        jcxz    term_tstx
        mov     si,offset tmpbuf
term_tst4:
        push    cx
        push    si
        mov     ah,[si]
        call    outchr
         nop
         nop
         nop
        pop     si
        pop     cx
        inc     si
        loop    term_tst4
        jmp     term_tst2
term_tstx:
        mov     ah,3Eh
        mov     bx,test_hndl
        int     dos
term_tstz:
        and     vt100_flags,NOT LOOPTEST_BIT
        clc
        jmp     term1

term    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 exit Connect mode (kbdflg has transfer char).

; chrout is called from KEYBD after key definition translation.
; the character is in AL.

chrout:
        cmp     kanji_scode,0           ; if kanji is not used, no translation
        je      chroutx
        test    kanji_scode,4           ; if shift-JIS is used, no translation
        jnz     chroutx
        cmp     kanji_smode,0           ; 1st byte ?
        je      chrout_1                ; e = yes,
        jmp     chrout_knj2
chrout_1:
        call    is_kanji1               ; Kanji code 1st byte ?
        jnc     chroutx                 ; nc = no. ASCII character
        mov     kanjis1,al
        mov     kanji_smode,1
        jmp     chroutxx
chroutx:
        call    outprt                  ; put char in al to serial port
        mov     kanji_smode,0
chroutxx:
        clc                             ; stay in Connect mode
        ret

chrout_knj2:
        mov     ah,al
        mov     al,kanjis1
        call    s2jis
        or      ax,8080h                ; convert to DEC code
        mov     kanjis1,ah
        mov     ah,0
        call    outprt
        mov     al,kanjis1
        jmp     chroutx

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

uparrw: mov     al,'A'
        jmp     short comarr
dnarrw: mov     al,'B'
        jmp     short comarr
rtarrw: mov     al,'C'
        jmp     short comarr
lfarrw: mov     al,'D'
comarr: push    ax
        mov     ah,ESCAPE
        call    outchr
          nop
          nop
          nop
        mov     ah,'['
        cmp     curkey_mode,0
        je      comar1
        mov     ah,'O'
comar1: call    outchr
          nop
          nop
          nop
        pop     ax
        mov     ah,al
        call    outchr
          nop
          nop
          nop
        clc
        ret

pf1:    mov     al,'P'
        jmp     short compf
pf2:    mov     al,'Q'
        jmp     short compf
pf3:    mov     al,'R'
        jmp     short compf
pf4:    mov     al,'S'
compf:  push    ax
        mov     ah,ESCAPE
        call    outchr
          nop
          nop
          nop
        mov     ah,'O'
        call    outchr
          nop
          nop
          nop
        pop     ax
        mov     ah,al
        call    outchr
          nop
          nop
          nop
        clc
        ret

kp0:    mov     al,'p'
        jmp     short comkp
kp1:    mov     al,'q'
        jmp     short comkp
kp2:    mov     al,'r'
        jmp     short comkp
kp3:    mov     al,'s'
        jmp     short comkp
kp4:    mov     al,'t'
        jmp     short comkp
kp5:    mov     al,'u'
        jmp     short comkp
kp6:    mov     al,'v'
        jmp     short comkp
kp7:    mov     al,'w'
        jmp     short comkp
kp8:    mov     al,'x'
        jmp     short comkp
kp9:    mov     al,'y'
        jmp     short comkp
kpmins: mov     al,'m'
        jmp     short comkp
kpcoma: mov     al,'l'
        jmp     short comkp
kpentr: mov     al,'M'
        jmp     short comkp
kpdot:  mov     al,'n'
        jmp     short comkp
comkp:  cmp     keypad_mode,0
        je      comkp1
        push    ax
        mov     ah,ESCAPE
        call    outchr
          nop
          nop
          nop
        mov     ah,'O'
        call    outchr
          nop
          nop
          nop
        pop     ax
        jmp     short comkp2
comkp1: sub     al,40h
comkp2: mov     ah,al
        call    outchr
          nop
          nop
          nop
        clc
        ret

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

keyinchg:
        xor     keyin_dos,1
        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
chang:  mov     al,'H'                  ; Hangup, drop DTR & RTS
;;;     jmp     short cmdcom
cmdcom: mov     kbdflg,al               ; pass char to msster.asm via kbdflg
        stc                             ; say exit Connect mode
        ret
                                        ;; end of action routines

; 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      outtty_knj0             ; e = yes, off
        push    bx                      ; Translate incoming char
        mov     bx,offset rxtable       ; address of translate table
        xlatb                           ; new char is in al
        pop     bx
;
; Kanji test
;
outtty_knj0:
        cmp     kanji_rcode,0           ; Kanji code used ?
        je      outnp7                  ; e = no, no translation
        test    kanji_rcode,2           ; DEC code ?
        jz      outtty_knj1             ; z = no
        jmp     outtty_dknj0
outtty_knj1:
        test    kanji_rcode,4           ; Shift-JIS code ?
        jz      outtty_knj2
        jmp     outtty_sknj0
outtty_knj2:
;
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
        cmp     kanji_rmode,0
        je      outnp71
        mov     al,kanjir1
        call    captrtn
outnp71:
        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
        cmp     kanji_rmode,0
        je      outnoc1
        mov     dl,kanjir1
        int     dos
outnoc1:
        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 vt100 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:
        cmp     flags.vtflg,ttvt100     ; vt100 emulation?
        je      outtty_vt
        cmp     flags.vtflg,tttek       ; tek4014 emulation?
        je      outtty_tk
;
outnp5: test    flags.remflg,d8bit      ; keep 8 bits for displays?
        jnz     outnp9                  ; nz = yes, 8 bits if possible
        and     al,7fh                  ; remove high bit
outnp9: mov     ah,conout               ; dostty screen mode
        mov     dl,al                   ; write without intervention.
        int     dos                     ; else let dos display char
        cmp     kanji_rmode,0
        je      outnpx
        test    flags.remflg,d8bit
        jnz     outnp91
        and     al,7fh
outnp91:
        mov     ah,conout
        mov     dl,kanjir1
        int     dos
        mov     kanji_rmode,0
outnpx:
        ret                             ; and return
;
outtty_vt:
        cmp     al,CHR_GS
        jne     outtty_vt1
        test    vt100_flags,AUTOTEK_BIT
        jz      outtty_vt1
        push    ax
        call    vt100_save
        call    ent_tk
        mov     flags.vtflg,tttek
        pop     ax
        jmp     outtty_tk1
outtty_vt1:
        cmp     kanji_rmode,0
        je      outtty_vt2
        mov     al,kanjio1
        call    vt100
        mov     al,kanjio2
outtty_vt2:
        call    vt100
        jmp     outtty_snd

outtty_tk:
        cmp     al,CHR_CAN
        jne     outtty_tk1
        test    vt100_flags,AUTOTEK_BIT
        jz      outtty_tk1
        push    ax
        call    tek4014_save
        call    ent_vt
        mov     flags.vtflg,ttvt100
        pop     ax
        jmp     outtty_vt1
outtty_tk1:
        call    tek4014
outtty_snd:
        mov     kanji_rmode,0
        jcxz    outtty_snd_ex           ; If there is no answer-back, return
outtty_snd1:
        mov     ah,[si]
        call    outchr                  ; send character without echo
         nop
         nop
         nop
        inc     si
        loop    outtty_snd1
outtty_snd_ex:
        ret

outtty_dknj0:
        cmp     kanji_rmode,0           ; 1st byte ?
        jne     outtty_dknj2
        cmp     al,0A0h                 ; Is kanji ?
        ja      outtty_dknj1            ; a = Yes.
        jmp     outnp7
outtty_dknj1:
        mov     kanji_rmode,1
        mov     kanjir1,al
        mov     kanjio1,al
        ret
outtty_dknj2:
        test    al,0A0h
        jbe     outtty_dknj3
        mov     kanjio2,al
        mov     ah,al
        mov     al,kanjir1
        and     ax,7F7Fh
        call    jis2s
        mov     kanjir1,ah
outtty_dknj3:
        jmp     outnp7
;
outtty_sknj0:
        cmp     kanji_rmode,0           ; 1st byte ?
        jne     outtty_sknj2
        call    is_kanji1
        jc      outtty_sknj1            ; c = Yes.
        jmp     outnp7
outtty_sknj1:
        mov     kanji_rmode,1
        mov     kanjir1,al
        mov     kanjio1,al
        ret
outtty_sknj2:
        mov     kanjio2,al
        mov     ah,al
        mov     al,kanjio1
        call    s2jis
        or      ax,8080h
        xchg    kanjio1,al
        xchg    kanjio2,ah
        mov     kanjir1,ah
        jmp     outnp7
;

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
         nop
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
;;--------------------------------------------------------
;; DO NOT IGNORE DELs. TEK4014 uses DEL code for LOY byte.
;; (H.Fujii 19-May-1988)
;;
;;        cmp     al,del                  ; catch dels
;;        je      portc0                  ; e = del, ignore it
;;--------------------------------------------------------
portc2: stc                             ; have a character
        ret                             ; and return
portchr 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

; Jumping here is the same as a ret.

R       PROC    NEAR
        ret
R       ENDP

code    ends
        end
;
;+ End of MSXP98.ASM