         name    msxp98
; File MSXP98.ASM
; NEC PC-9801 MS DOS Kermit module.
;
; Last edit: 17 Apr 1991
; 17 Apr 1991 Joe Doupnik's modifications are added. -> KEK v1.22
; 05 Apr 1991 KEK v1.21 for MS-Kermit v3.10
;             correct flow control mismatch.
;             added pcwtst for correct pcwait.
; 25 Jul 1990 KEK v1.20 for MS-Kermit v3.02
; 24 Sep 1989 KEK v1.16 (added VT52 mode).
; 04 Aug 1989 Fixed wrong ESC M (Reverse index) behavior (in MSYP98.ASM).
; 30 May 1989 ESC [ 0 m resets to color to default (color in command mode).
; 25 Apr 1989 KEK v1.15 .
; 24 Apr 1989 Fixed bug of cooked log for dumb terminal emulator.
; 21 Apr 1989 Raw mode logging is moved to outside the terminal emulator.
; 16 Apr 1989 Cooked log in VT100 mode is installed.
; 01 Mar 1989 Bug on JIS-7 input when local echo is on.
; 24 Feb 1989 start test of the device port. v1.15 alpha
; 13 Feb 1989 domode is called when really necessary.
;             graphic display on when exit.
; 08 Feb 1989 Call getbaud in lclini.
; 04 Feb 1989 Bug report from Yoro@Kyoto.Univ. SHOW MODEM becomes mad
;             when modem is not ready.  This was bug in getmodem.
; 28 Jan 1989 KEK v1.14, + MS-Kermit 2.23/A
; 17 Dec 1988 AUTOTEK feature is completely removed. Use eneble/disable Tek.
; 08 Sep 1988 JIS-7 code for 'Kanji-send' is installed.
;             The original idea and its code is due to Ogawa, NTT software-lab.
;             Thanx for cooperation !
; 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, vtstat
        public  ctlu, cmblnk, locate, lclini, prtchr, clearl
        public  baudst, getbaud, beep, trnprs, termtb
        public	setchtab
        public  count, xofsnt, puthlp, putmod, clrmod, poscur
        public  sendbr, sendbl, term, machnam, setktab, setkhlp, showkey
        public  ihosts, ihostr, dtrlow, serhng, dumpscr
        public	bdtab, comptab, portval
        public  chrout, cstatus, cquit, cquery, chang   ; kbd action verbs
        public  snull, kdos, klogof, klogon
	public	trnmod
        public	shomodem, getmodem, mdmhand
	public	pf1, pf2, pf3, pf4
	public	kp0, kp1, kp2, kp3, kp4, kp5, kp6, kp7, kp8, kp9
	public	decf6, decf7, decf8, decf9, decf10, decf11, decf12, decf13
	public	decf14, dechelp, decdo, decf17, decf18, decf19, decf20
	public	decfind, decinsert, decremove, decselect
	public	decprev, decnext
	public	kpmins, kpcoma, kpentr, kpdot
	public	uparrw, dnarrw, lfarrw, rtarrw
        public	keyinchg
	public	vtchg, vtreset, vtrmac, vtsmac
        public	upone, dnone, upscn, dnscn
        public	gupone, gdnone
        public	prtscn
        public	outcapt
        public	set_cur_color
 
	public	cpu_clock, vtgrph_flg, vttest_flg
	public	curkey_mode, keypad_mode, display_mode
	public	kanji_rmode, kanji_smode
	public	kanji_rcode, kanji_scode
	public	keyin_dos, vt100_cursr
	public  vt100_flags, vt100_pflag, vt100_lflag, vt100_gflag
	public	vt_ourarg
	public	scn_color, def_color
	public	extmacro, vtmacname, vtmaclen
        include mssdef.h
        include	msxp98.h
 
CHR_GS	equ	1Dh
CHR_CAN	equ	18h
 
false   equ     0
true    equ     1
instat  equ     6
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, CL is used as a subfunction for control
;      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
 
NETCI_BRK	equ	2		; NETCI control function, BREAK
NETCI_DIS	equ	4		; NETCI control function, DISCONNECT
NETCI_HLD	equ	6		; NETCI control function, HOLD
 
; 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
chng	equ	10H		; RTS & DTR low, RX & TX disabled, reset ERR
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)
 
; Baudrate
 
B9600	equ	13
 
; Modem information
 
mdminfo struc
mddat   dw      0
mdstat  dw      0
mdcom   dw      0
mden    db      0
mddis   db      0
mdmeoi  db      0
mdintv  dw      0
mdminfo ends
 
; 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
 
; miscellaneous constants
 
mntrgh	equ	bufsiz*3/4	; High XON/XOFF trigger = 3/4 of buffer full.
 
; external variables used:
; 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.
 
data    segment public 'data'
	extrn	denyflg:word, rdbuf:byte
        extrn   flags:byte, trans:byte, ttyact:byte
        extrn	repflg:byte, diskio:byte, filtst:byte
        extrn	lclexit:word, taklev:byte, takadr:word
        extrn   comand:byte, dmpname:byte, prnhand:word
        extrn   kbdflg:byte, rxtable:byte, mcctab:byte
 
;------------------------
cpu_clock	db	0
curkey_mode	db	0
keypad_mode	db	0
display_mode	db	0
kanji_7smode	db	0
kanji_7rmode	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_cursr	db	0	; cursor attributes
vt100_flags	db	0
vt100_lflag     db      0
vt100_pflag	db	0	; printer control
vt100_gflag	db	0
;------------------------
vtgrph_flg	db	0
vttest_flg	db	0
replay_hold	db	0
		db	0	; adjustment for word boundary
;------------------------
;
portval		dw	1
;
; previous baud rate for serial port 1
pbaud_1		dw	0FFFFh	; set unknown baud rate
;
; color for Foreground, Background, Highlight and Modeline
;
def_color	db	07h, 00h, 06h, 07h
scn_color	db	07h, 00h, 06h, 07h
;------------------------
 
fairness	dw	0
 
KI_len		dw	0
KI_ofs		dw	0
 
KO_len		dw	0
KO_ofs		dw	0
 
pcnet		db	0	; 2.30 global --> 2.31 local
 
kanjis1		db	0	; storage for Kanji 1st byte (Keyboard)
kanjis2		db	0
kanjir1		db	0	; storage for Shift-JIS kanji code
kanjir2		db	0
kanjio1		db	0	; storage for DEC Kanji code
kanjio2		db	0
 
mdstreg	db	?		; modem status register
 
machnam db      'NEC PC-9801 (KEK v1.22  17-APR-1991)$'
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.$'
pntmsg	db	'Printer not ready, printing request skipped$'
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$'
vtrname	db	'TERMINALR'		; a macro name, must be Upper Case
vtrlen	equ	$-vtrname
vtsname	db	'TERMINALS'		; a macro name, must be Upper Case
vtslen	equ	$-vtsname
prodname db	'PRODUCT'
vtplen	equ	$-prodname
vtmacname dw	vtrname			; pointer to selected macro name
vtmaclen db	vtrlen
oldsp	dw	0 
 
tmpbuf		db	80 DUP (?)
 
;playback_hndl	dw	?
;playback_fnam	db	80 dup (?)
;playback_defnam	db	'KERMIT.LOG',0
;playback_hlp	db	cr,lf,'Filename to playback$'
 
prthnd  dw      0               ; Port handle.
prtnam  db      80 dup (0)	; Name of auxiliary device
prtdef	db	'AUX',0		; default device name
prtdev	db	?		; device flag (device=1,file=0)
prthld	db	?		; hold port
prthlp	db	cr,lf,'specify device/file name (default AUX)$'
 
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
fulscr	db	ESCAPE,'[>1h$'
nrmscr	db	ESCAPE,'[>1l$'
delscr	db	ESCAPE,'[2J$'		; Delete screen
retscr	db	ESCAPE,'[>1h'
	db	ESCAPE,'[25;1H',ESCAPE,'[0J'
	db	cr,'$'
 
; 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.
 
temp    dw      0
temp1   dw      ?               ; Temporary storage.
temp2   dw      ?               ; Temporary storage.
 
; Entries for choosing communications port
comptab db      9               ; Number of options
        mkeyw   '1',1
        mkeyw   '2',2
	mkeyw	'3',3
        mkeyw   'COM1',1
        mkeyw   'COM2',2
        mkeyw	'COM3',3
	mkeyw	'Device','D'
	mkeyw	'File','D'
        mkeyw   'UB-NETCI','N'
        mkeyw	'   ',0		; port is not present, for Status
 
vt_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
;
port1	prtinfo	<0FFFFh,0,defpar,1,0,defhand,floxon>
port2	prtinfo	<0FFFFh,0,defpar,1,0,defhand,floxon>
portd	prtinfo	<0FFFFh,0,defpar,1,0,defhand,floxon>
portf	prtinfo	<0FFFFh,0,defpar,1,0,defhand,floxon>
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
 
setchtab	db	3
	mkeyw	'EUC',1
	mkeyw	'JIS7',2
	mkeyw	'MS-Kanji',0
 
; this table is indexed by the baud rate definitions given in
; pcdefs.  Unsupported baud rates should contain FF.
 
bdtab	db	17
	mkeyw	'45.5',0
	mkeyw	'50',1
	mkeyw	'75',2
	mkeyw	'110',3
	mkeyw	'134.5',4
	mkeyw	'150',5
	mkeyw	'300',6
	mkeyw	'600',7
	mkeyw	'1200',8
	mkeyw	'1800',9
	mkeyw	'2000',10
	mkeyw	'2400',11
	mkeyw	'4800',12
	mkeyw	'9600',13
	mkeyw	'19200',14
	mkeyw	'38400',15
	mkeyw	'Unknown',-1

; 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
 
 
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
;
	even
	dw	80 DUP (?)	; local stack for interrupt processing
mnstk	dw	?
mnsp	dw	?		; remote stack info
mnsseg	dw	?
 
baud_set	db	0
 
onmsg		db	'off'
		db	'on '
applmsg		db	'normal     '
		db	'application'
colmsg		db	'black  '
		db	'blue   '
		db	'red    '
		db	'magenta'
		db	'green  '
		db	'cyan   '
		db	'yellow '
		db	'white  '
knjmsg		db	'none     '
		db	'DEC-code '
		db	'Shift-JIS'
		db	'JIS-7    '
keyinmsg	db	'BIOS  '
		db	'CON   '
		db	'DOS   '
insrepmsg	db	'Replace'
		db	'Insert '
originmsg	db	'Absolute'
		db	'Relative'
lfnlmsg		db	'Line-feed'
		db	'New-line '
clkmsg		db	'5/10 MHz'
		db	'8 MHz   '
dspmsg		db	'Digital '
		db	'Analogue'
 
vstmsg		db	'<Terminal status>  clock '
vstmsg_clk	db	'        '
		db	'  Diaplay: '
vstmsg_dsp	db	'        '
		db	cr,lf,'  Keyclick: '
vstmsg_key	db	'    '
		db	'  Keyinput: '
vstmsg_keyin	db	'      '
		db	'  Cursorkey: '
vstmsg_curmod	db	'           '
		db	'  Keypad: '
vstmsg_kpdmod	db	'           '
		db	cr,lf,'  Color:  Fore:'
vstmsg_colf	db	'        '
                db      '  Back:'
vstmsg_colb     db      '        '
		db	'  Highlight:'
vstmsg_colh	db	'        '
                db      '  Modeline:'
vstmsg_colm     db      '        '
		db	cr,lf,'  Kanji-send: '
vstmsg_sknj	db	'          '
		db	'  Kanji-receive: '
vstmsg_rknj	db	'          '
		db	cr,lf,'  Ins/Rep: '
vstmsg_insrep	db	'       '
		db	'  LF/NL: '
vstmsg_lfnl	db	'         '
		db	'  Orgin: '
vstmsg_origin	db	'        '
		db	'  Wrap: '
vstmsg_autow	db	'    '
		db	cr,lf,'  Cooked-log: '
vstmsg_logcook	db	'    '
		db	'$'
 
data    ends
 
code    segment public 'code'
        extrn   comnd:near, dopar:near, atoi:near, prompt:near
        extrn	isfile:near, strlen:near, strcpy:near
        extrn   sleep:near, msuinit:near, keybd:near
        extrn	kbdlini:near, kbdlend:near
        extrn	ans_keystr:near
	extrn	pntchr:near, pntflsh:near
 
	extrn	vt100:near, vt100_ini:near, vt100_reset:near
	extrn	vt100_save:near, vt100_restore:near, vt100_modlin:near
	extrn	vt100_dump:near, vt100_color:near
	extrn	vt100_rupn:near, vt100_rdnn:near
	extrn	vt100_prnl:near, vt100_prns:near
 
	extrn	tekstat:near
 
 	extrn	prn_chk:near		; in MSYP98.ASM
 	extrn	set_modlin:near		; in MSYP98.ASM
 	extrn	gdisp_on:near		; in MSGP98.ASM
 	extrn	set_gcolor:near		; in MSGP98.ASM
 
 	extrn	text_scrn:near		; in MSZP98.ASM
 	extrn	pc98_bell:near		; in MSZP98.ASM
 	extrn	pcwait:near		; in MSZP98.ASM
 	extrn	pcwtst:near		; in MSZP98.ASM
 
	extrn	tek4014:near, tek4014_ini:near, tek4014_reset:near
	extrn	tek4014_save:near, tek4014_restore:near, tek4014_modlin:near
	extrn	tek4014_color:near
	extrn	sixel_rollup:near, sixel_rolldown:near
 
	extrn	sense_sftkey:near
	extrn	set_keydef:near, reset_keydef:near
	extrn	is_kanji1:near, s2jis:near, jis2s:near
 
        assume  cs:code,ds:data,es:nothing
 
;-----------------
; 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
 
ENT_VT	PROC	NEAR
;@@	call	vt100_restore
	and	vt100_gflag,7Fh		; mask text screen control
	call	set_gcolor
	call	set_modlin
	call	vt100_modlin
	mov	kanji_rmode,0		; clear all kanji pending flags
	mov	kanji_smode,0
	ret
ENT_VT	ENDP
 
ENT_TK	PROC	NEAR
;@@	call	cmblnk
;@@	call	tek4014_restore
	and	vt100_gflag,7Fh
	cmp	vt100_gflag,4		; TeK screen ?
	jge	ent_tk_1		; ge = yes
	mov	vt100_gflag,4
ent_tk_1:
	or	vt100_gflag,80h		; set text screen cotrol bit
	call	set_gcolor
	call	set_modlin
	call	tek4014_modlin
	mov	kanji_rmode,0
	mov	kanji_smode,0
	ret
ENT_TK	ENDP
 
SET_CUR_COLOR	PROC	NEAR
;
; Set the current color.  The color table is given in [si] - [si+3]
;
	push	ax
	push	di
	mov	di,offset scn_color	; copy color to current buffer
	mov	ax,[si]			; fore & back
	mov	[di],ax
	mov	ax,[si+2]		; highlight & modeline
	mov	[di+2],ax
	pop	di
	pop	ax
	ret
SET_CUR_COLOR	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
	cmp	repflg,0		; in replay mode ?
	jne	clrbf2			; ne=yes. do not read any character.
clrbf1:
	call	prtchr			; empty any intermediate buffers
	jnc	clrbf1			; got a char, clear again
clrbf2:
	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
        mov ah,prstr
        mov dx,offset clreol
        int dos
        pop dx
        pop ax
        ret
CLEARL  ENDP
 
shomodem	proc	near
	mov     ah,cmeol        	; get a confirm
        call    comnd
        jnc	shomd0
        ret		               	; no confirm
shomd0:
;
	call	serini			; activate port to get status
	call	serrst			; turn off port again
;
	call	getmodem	; get modem status in al
	mov	mdstreg,al
;
	mov	ah,prstr
	mov	dx,offset msmsg1	; modem not ready msg
	test	mdstreg,moddsr		; is DSR asserted?
	jz	shomd1			; z = no
	mov	dx,offset msmsg2	; say asserted
shomd1:	int	dos
	mov	dx,offset msmsg3	; CD not asserted msg
	test	mdstreg,modcd		; CD asserted?
	jz	shomd2			; z = no
	mov	dx,offset msmsg4	; say asserted
shomd2:	int	dos
	mov	dx,offset msmsg5	; CTS asserted msg
	test	mdstreg,modcts		; CTS asserted?
	jz	shomd3			; z = no
	mov	dx,offset msmsg6	; say asserted
shomd3:	int	dos
	clc
	ret
shomodem	endp
 
;
; returns modem status in AL. Needs more work.  Current version
; returns only valid for PORT 1.
;
getmodem	proc	near
	push	bx
	push	dx
	mov	dx,mnst1a	; read status of port 1A
	in	al,dx
	and	al,80h		; set only DR bit
	mov	bl,al		; save it
	mov	dx,mnrdsa	; read signal
	in	al,dx
	and	al,60h		; set CS and CD only
	or	bl,al
;
	mov	al,0
	test	bl,80h		; is DSR asserted?
	jz	getmd1		; z = no
	or	al,moddsr	; set DSR bit
getmd1:
	test	bl,20h		; CD asserted?
	jnz	getmd2		; nz = no
	or	al,modcd	; set CD bit
getmd2:
	test	bl,40h		; CTS asserted?
;@@	jnz	shomd3
	jnz	getmd3		; @@ [04-Feb-89]
	or	al,modcts	; set CTS bit
getmd3:
	pop	dx
	pop	bx
	ret
getmodem	endp
 
; Put the char in AH to the serial port, assumimg the port is active.
; Returns carry clear if success, else carry set.
 
OUTCHR  PROC    NEAR
	cmp	repflg,0		; in REPLAY mode?
	je	outch0			; e=no
	cmp	ah,03h			; CTRL-C ?
	je	outch0_1		; e=yes
	xor	replay_hold,1		; toggle replay_hold flag
	clc
	jmp	outch0_2
outch0_1:
	stc
outch0_2:
	ret
outch0:
	push	cx			; save regs
	cmp	flowoff,0		; Are we doing flow control.
	je	outch2
	mov	cx,1500h	; about 15 sec in 4 millisec interval
        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.
        push	ax
        mov	ax,4		; 4 millisec wait loop
        call	pcwait
        pop	ax
        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	vt_ourarg.prt,'N'		; Network port ?
	jne	outch6			; ne = No.
	pop	dx
	pop	cx
	jmp	outchn
outch6:
	cmp	vt_ourarg.prt,'D'	; DOS device ?
	jne	outch7		; ne = no
	jmp	outchd
outch7:
	mov	dx,modem.mdstat
outch3:	in	al,dx
	test	al,txrdy
	jnz	outch4
	loop	outch3
	stc			; fail to send
	jmp	outch5
outch4:	mov	al,ah
	mov	dx,modem.mddat
	out	dx,al
	clc			; we have sent it.
outch5:	pop     dx
        pop     cx
	clc
	ret
;
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:
	clc				; good exit
outchn3:
	ret				; bad  exit
 
outchd:
        cmp     prthnd,0        ; Got a handle yet?
        jne     outchd3         ; Yup just go on
        call    opnprt          ; Else 'open' the port
outchd3:
	cmp	prtdev,1	; device ?
	je	outchd5		; e = yes.
	xor	prthld,1	; flip-flop
	jmp	outch5
outchd5:
        push    bx
        mov     bx,prthnd       ; port handle
        mov     cx,1            ; one byte to write
        mov     dx,offset temp  ; place where data will be found
        mov     ah,write2       ; dos 2 write to file/device
        int     dos
        pop     bx              ; end of revised routine
        jmp	outch5
 
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
        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
        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
        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
        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	cmblnk
;@@	call	locate
	mov	ah,prstr		;@@
	mov	dx,offset retscr	;@@
	int	dos			;@@
        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.
 
BAUDST	PROC	NEAR
	mov	dx,offset bdtab		; baud rate table, ascii
	xor	bx,bx			; help is the table itself
	mov	ah,cmkey		; get keyword
	call	comnd
	jc	baudst1			; c = failure
	push	bx			; save result
	mov	ah,cmeol		; get confirmation
	call	comnd
	pop	bx
	jc	baudst1			; c = failure
	mov	si,portval
	mov	ax,[si].baud		; remember original value
	mov	[si].baud,bx		; set the baud rate
	call	dobaud			; use common code
	clc
baudst1:ret
BAUDST	ENDP
;
DOBAUD  PROC    NEAR
	push	ax
	push	bx
	push	dx
;
	mov	axsave,ax
	mov	bx,portval
	mov	ax,[bx].baud
	shl	ax,1
;
	cmp	cpu_clock,CPU_5M_CLOCK
	je	c5mhz
c8mhz:
	mov	bx,offset bddat8
	jmp	dobd0
c5mhz:
	mov	bx,offset bddat5
dobd0:
	add	bx,ax
	cmp	word ptr [bx],0FFFFh
	jne	dobd1
	mov	ah,prstr
	mov	dx,offset badbd
	int	dos
	jmp	dobd_ex
dobd1:
	mov	ax,[bx]
	cmp	pbaud_1,ax		; same as previous baud rate ?
	jne	dobd2
	jmp	dobd_ex
dobd2:
	call	domode			; reset RS-232C chip
	mov	dx,timer.tmcmd
	mov	al,timer.tmsel
	out	dx,al
	mov	ax,[bx]
	mov	pbaud_1,ax		; store baud rate
	mov	dx,timer.tmdat
	out	dx,al
	mov	al,ah
	out	dx,al
	mov	baud_set,1
dobd_ex:
	pop	dx
        pop	bx
	pop	ax
	clc
        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,'A'	; controlable ?
	jae	gbaud1			; ae = No. 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
 
; Get Char from	serial port buffer.
; returns carry set if no character available at port, otherwise
; returns carry clear with char in al, # of chars in buffer in dx.
 
PRTCHR  PROC    NEAR
	cmp	repflg,0		; in replay mode ?
	je	prtch0			; e=no.
	jmp	prtchf
prtch0:
	cmp	vt_ourarg.prt,'D'
	jne	prtch4
	jmp	prtchd
prtch4:
	call    chkxon
	cmp	vt_ourarg.prt,'N'
	jne	prtch3
	jmp	prtchn
prtch3:
	cmp	count,0
	jnz	prtch2
	xor	dx,dx		; No data in buffer
	xor	al,al
	stc			; No data in AL.
	ret
prtch2:
	pushf
	cli			; disable interrupts while manipulating pointers
	push	si		; save SI (uses in rpack)
	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
	pop	si		; restore SI
	popf
	clc			; we have data in AL
	ret
;
;  Read from replay file
;
prtchf:
	cmp	repflg,1	; nomral state ?
	jne	prtchf0		; ne=no
	cmp	replay_hold,0	; holding?
	je	prtchf1		; e=no
prtchf0:
	xor	dx,dx		; no char at all.
	xor	al,al		; with NUL
	stc			; no char is available
	ret
prtchf1:
	push	bx
	push	cx
	mov	ah,readf2
	mov	bx,diskio.handle	; file handle
	mov	cx,1			; read one char
	mov	dx,offset rdbuf		; to this buffer
	int	dos
	jc	prtchf2			; c=read failure
	cmp	ax,cx			; read the byte?
	jne	prtchf2			; ne=no
	mov	al,rdbuf
	mov	dx,1
	clc
	jmp	prtchf3
prtchf2:
	call	pc98_bell		; notify that we cannot read.
	mov	repflg,2
	xor	dx,dx
	xor	al,al
	stc
prtchf3:
	pop	cx
	pop	bx
	ret
;
;  Read from file/device
;
prtchd:
	cmp	prthld,0	; hold ?
	je	prtchd2		; e = no
	stc
	ret
prtchd2:
        push    bx
        push    cx
        cmp     prthnd,0        ; Got a handle yet?
        jne     prtchd0         ; Yup just go on
        call    opnprt          ; Else 'open' the port
prtchd0:
        call    chkxon
        mov     bx,prthnd
        mov     al,instat       ; input status command
        mov     ah,ioctl        ; see note above
        int     dos
        jc      prtchd4         ; c = call failed, device not ready
        or      al,al
        jz      prtchd4         ; not ready
        mov     bx,prthnd       ; the file handle
        mov     ah,readf2       ; read file/device
        mov     cx,1            ; want just one character
        mov     dx,offset rdbuf ; where to store it
        int     dos
        jnc     prtchd1         ; nc = no error
        cmp     al,5            ; Error condition
        je      prt3dx
        cmp     al,6            ; Error condition
        je      prt3dx
        jmp     prtchd4         ; else report no char present
prtchd1:;;;mov   count,0         ; update count (always 0 for one char reads)
        mov     dx,0		; needed to obey rules
        or      ax,ax           ; reading from end of file?
        jz      prtchd4         ; z = yes
        mov     al,rdbuf        ; recover char
prtchd3:
        pop     cx
        pop     bx
        ret                     ; return success (char is in al)
prt3dx: mov     ah,prstr
        mov     dx,offset erms50
        int     dos
prtchd4:
        pop     cx
        pop     bx
	xor	dx,dx
	xor	al,al
	stc
	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
	xor	dx,dx			; no data in buffer
	xor	al,al
	stc				; no data in AL.
	ret
prtchn2:
	pushf
	cli			; disable interrupts while manipulating pointers
	push	si		; save SI
	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	; number of characters in buffer
	pop	si		; restore SI
	popf
	clc			; we have data in AL.
	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
	cmp	repflg,0	; in replay mode ?
	jne	ihosts2		; ne=yes.
        call    prtchr          ; check for char at port
        jnc	ihosts1		; have a char in al, repeat wait/read cycle
ihosts2:
        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
;@@	call	pc98_bell
        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)
ihostr1:pop     cx
        pop     bx
        pop     ax
        clc
        ret
IHOSTR  ENDP
 
DTRLOW  PROC    NEAR            ; Global proc to Hangup the Phone by making
                                ; DTR and RTS low.
        mov ah,cmline           ; 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
        jnc dtrlow1
        ret
dtrlow1:
	call serhng             ; drop DTR and RTS
        mov ah,prstr            ; give a nice message
	mov dx,offset hngmsg
        int dos
	ret
DTRLOW  ENDP
 
; Test version for NEC PC-9801 (03-Sep-1988)
; 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  PROC NEAR
	mov	dx,modem.mdcom	; set command port
	mov	al,chng		; hangup command
	out	dx,al
	xor	cx,cx		; counts for waiting loop
serhng1:
	loop	serhng1
	mov	pbaud_1,0FFFFh	; reset previous baud rate
        ret
SERHNG  ENDP
 
; Send a break out the current serial port.  Returns normally.
SENDBR  PROC    NEAR            ; Normal Break
	cmp	flags.comflg,'N'
	je	ub_sendbr
	mov	dx,modem.mdcom	; set command port
	mov	al,cbrk+ccmd	; add break to normal command
	out	dx,al
	mov	ax,275		; wait for 275 milliseconds
	call	pcwait
	mov	al,ccmd		; restore normal command
	out	dx,al
        ret
ub_sendbr:
        push    ax
        push    cx
        mov	ah,NETCI_CNTL	; control function
        mov	al,NETCI_PORT
        mov     cl,NETCI_BRK	; request break                          [ohl]
        int     NETCI_INT       ; Net/One command interface int. (6Bh)   [ohl]
        pop     cx
        pop     ax
        ret                     ;  [ohl] ---

SENDBR  ENDP
 
SENDBL  PROC    NEAR            ; Long Break
	cmp	flags.comflg,'N'
	je	ub_sendbl
	mov	dx,modem.mdcom	; set command port
	mov	al,cbrk+ccmd	; add break to normal command
	out	dx,al
	mov	ax,1800		; 1.8 second long break
	call	pcwait
	mov	al,ccmd
	out	dx,al		; restore normal command
        ret
ub_sendbl:
        push    ax
        push    cx
        mov	ah,NETCI_CNTL	; control function
        mov	al,NETCI_PORT
        mov     cl,NETCI_HLD	; request hold
        int     NETCI_INT       ; Net/One command interface int. (6Bh)   [ohl]
        pop     cx
        pop     ax
        ret                     ;  [ohl] ---
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
 
; 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
; in word 'lclexit'.
; This is used as a local end routine.
 
LCLCLOSE	PROC	NEAR
	push	ax
	call	clsprt			; close device if opened.
	cmp	pcnet,0			; network closed ?
	je	lclclo1			; e = yes
	mov	ah,NETCI_CLOSE		; UB-NETCI close command
	mov	al,NETCI_PORT
	int	NETCI_INT
	mov	pcnet,0
lclclo1:
	test	vtgrph_flg,EXITG_BIT
	jz	lclclo2
	call	gdisp_on		; graphic display on
lclclo2:
	call	reset_keydef		; reset key definition table
	call	kbdlend			; local reset keyboard routine
	mov	ah,prstr		;@@
	mov	dx,offset nrmscr	;@@
	int	dos			;@@
	pop	ax
	ret
LCLCLOSE	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 lclclose
	call	clrbuf
	mov	xmtcnt,0
	mov	pcnet,2
;
	pop	es
	pop	cx
	pop	bx
	pop	ax
chknetx:
	clc
	ret
chknet	endp
 
; Get a file handle for the communications port.  Use DOS call to get the
; next available handle.  If it fails, ask user what value to use (there
; should be a predefined handle for the port, generally 3).  The open
; will fail if the system uses names other than "COM1" or "COM2".
 
opnprt	proc	near
        mov     dx,offset prtnam        ; port name
        mov     ah,open2                ; open file/device
        mov     al,2                    ; for reading/writing
        int     dos
        jnc     opnpr2                  ; nc = no error so far
        stc                             ; set carry for failure
        ret
opnpr2: mov     prthnd,ax               ; Call succeeded
	mov	prtdev,1		; device is assumed
        mov     ah,ioctl
        mov     al,00h                  ; get device info
        xor     dx,dx
        mov     bx,prthnd               ; port's handle
        int     dos
        test	dl,80h			; is device ?
        jnz	opnpr3			; nz = yes.
	mov	prtdev,0		; say this is a file
        ret
opnpr3:
        or      dl,20h                  ; set raw mode in device info
        mov     dh,0
        mov     ah,ioctl
        mov     al,01h                  ; set device info
        int     dos
        ret                             ; carry clear for success
opnprt	endp
 
clsprt	proc	near
	cmp	prthnd,0		; already closed ?
	je	clsprt1			; e = yes. Do nothing.
	push	ax
	push	bx
	mov	ah,close2
	mov	bx,prthnd
	int	dos
	mov	prthnd,0
	pop	bx
	pop	ax
clsprt1:
	ret
clsprt	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
        jnc  coms0
        ret			; no match
coms0:
	cmp	bl,'N'		; Network ?
	jne	coms1		; ne = no
	jmp	comsn		; Yes, setup for networks
coms1:
	cmp	bl,'D'		; Device ?
	jne	coms2
	jmp	comsd		; Yes, setup for device
coms2:
	mov	temp,bx
        mov	ah,cmeol
        call	comnd			; Get a confirm.
        jnc	coms2_1
        ret				;  Didn't get a confirm.
coms2_1:
	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,cmeol
	call	comnd			; Get a confirm
	jnc	comsn0
	ret				;  Didn't get a confirm
comsn0:
	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
;
comsd:
 
; Set device name. Taken from 'setdmp' in MSSSET.ASM
; Puts device name in global string prtnam.
 
        mov     dx,offset rdbuf         ; work area
        mov     rdbuf,0                 ; clear it
        mov     bx,offset prthlp	; help message
        mov     ah,cmword               ; allow paths
        call    comnd
        jnc	comsd0
        ret
comsd0:
        mov     ah,cmeol
        call    comnd
        jnc	comsd1
        ret
comsd1:
        mov     dx,offset rdbuf         ; assume we will use this text
        call    strlen                  ; filename given?
	push	si
	push	di
        mov     si,dx                   ; for strcpy
        cmp     cx,0                    ; length of user's filename
        jg      comsd2			; g = filename is given
        mov     si,offset prtdef	; no name, use default instead
comsd2:
        mov     di,offset prtnam	; copy to globally available loc
        call    strcpy
	pop	di
	pop	si
 
	call	serrst			; reset serial port
	call	clsprt			; close previous device if exists.
	call	opnprt			; open device
	jnc	comsd3
	stc
	ret
comsd3:
	mov	portval,offset portd	; set device port data
	mov	flags.comflg,'D'
	clc
	ret
;
COMS    ENDP
 
; Set heath emulation on/off.
 
 
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
;  CPU clock
	mov	si,offset clkmsg
	mov	cx,8
	cmp	cpu_clock,CPU_5M_CLOCK
	je	vtstat0
	add	si,cx
vtstat0:
	mov	di,offset vstmsg_clk
	rep	movsb
;  Display
	mov	si,offset dspmsg
	mov	cx,8
	cmp	display_mode,0
	je	vtstat0_1
	add	si,cx
vtstat0_1:
	mov	di,offset vstmsg_dsp
	rep	movsb
;  Keyclick
	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
;  Log-cooked
	mov	si,offset onmsg
	mov	cx,3
	test	vt100_lflag,LOGCOOK_BIT
	jz	vtstat2
	add	si,cx
vtstat2:
	mov	di,offset vstmsg_logcook
	rep	movsb
;  Autowrap
	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
;  Cursor key mode
	mov	si,offset applmsg
	mov	cx,11
	mov	di,offset vstmsg_curmod
	cmp	curkey_mode,0
	je	vtstat5
	add	si,cx
vtstat5:
	rep	movsb
;  Keypad mode
	mov	si,offset applmsg
	mov	cx,11
	mov	di,offset vstmsg_kpdmod
	cmp	keypad_mode,0
	je	vtstat7
	add	si,cx
vtstat7:
	rep	movsb
;  Foreground
	mov	si,offset colmsg
	mov	di,offset def_color
	mov	al,[di]
	mov	ah,0
	mov	cx,7
	imul	cl
	add	si,ax
	mov	di,offset vstmsg_colf
	rep	movsb
;  Background
	mov	si,offset colmsg
	mov	di,offset def_color
	mov	al,[di+1]
	mov	ah,0
	mov	cx,7
	imul	cl
	add	si,ax
	mov	di,offset vstmsg_colb
	rep	movsb
;  Highlight
	mov	si,offset colmsg
	mov	di,offset def_color
	mov	al,[di+2]
	mov	ah,0
	mov	cx,7
	imul	cl
	add	si,ax
	mov	di,offset vstmsg_colh
	rep	movsb
;  Modeline
	mov	si,offset colmsg
	mov	di,offset def_color
	mov	al,[di+3]
	mov	ah,0
	mov	cx,7
	imul	cl
	add	si,ax
	mov	di,offset vstmsg_colm
	rep	movsb
;  Kanji-code send
	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
;  Kanji-code receive
	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
;  Keyinput
	mov	si,offset keyinmsg
	mov	ah,0
	mov	al,keyin_dos
	mov	cx,6
	imul	cl
	add	si,ax
	mov	di,offset vstmsg_keyin
	rep	movsb
;  Insert/Replace
	mov	si,offset insrepmsg
	mov	cx,7			; message length
	test	vt100_flags,INSERT_BIT
	jz	vtstat10
	add	si,cx
vtstat10:
	mov	di,offset vstmsg_insrep
	rep	movsb
;  Origin-mode
	mov	si,offset originmsg
	mov	cx,8
	test	vt100_flags,ORIGIN_BIT
	jz	vtstat11
	add	si,cx
vtstat11:
	mov	di,offset vstmsg_origin
	rep	movsb
;  Line-feed/New-line
	mov	si,offset lfnlmsg
	mov	cx,9
	test	vt100_flags,NEWLINE_BIT
	jz	vtstat12
	add	si,cx
vtstat12:
	mov	di,offset vstmsg_lfnl
	rep	movsb
;
	mov	ah,prstr
	mov	dx,offset vstmsg
	int	dos
;
	call	tekstat
	mov	dx,si
	mov	ah,prstr
	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.
;
	cmp	flags.vtflg,ttvt100
	je	dmp_v1
	cmp	flags.vtflg,ttvt52
	je	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
 
; Initialize variables to values used by this routine.
 
lclini:
	call	detclck		; determine CPU clock
	call	pcwtst		; adjust wait counter
	mov	prthnd,0	; No handle yet
	mov	portval,offset port1	; default portval
	mov	pbaud_1,0FFFFh	; previous baud rate is unknown
	mov	flags.comflg,1	; Communication port 1
	mov	flags.vtflg,ttvt100	; override default terminal type
	call	getbaud		; Put the baud rate in portval [08-Feb-89]
	mov	curkey_mode,0	; cursor key is ANSI normal
	mov	keypad_mode,0	; keypad is normal
	mov	vt100_flags,AUTOTEK_BIT	; set flags
	mov	vt100_lflag,LOGCOOK_BIT ; log mode is cooked
	mov	vt100_gflag,0
	mov	kanji_scode,KNJCODE_DEC	; DEC kanji code
	mov	kanji_rcode,KNJCODE_DEC
	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 lclclose	; set local close routine
        call	msuinit		; declare keyboard translator present
        call	kbdlini		; keyboard local initialize
	call	vt100_ini	; initialize VT100 terminal emulator
	call	tek4014_ini	; initialize TEK4014 terminal emulator
        push	si
        mov	si,offset def_color
        call	set_cur_color
        call	vt100_color	; setup color index table
        call	tek4014_color	; same for Tek4014
	pop	si
	mov	ah,prstr		;@@
	mov	dx,offset fulscr	;@@
	int	dos			;@@
	clc
        ret
 
showkey:
        mov ax,offset shkmsg
        mov cx,shklen
        ret
 
detclck	proc	near
;
;  determine CPU clock
;
	mov	cpu_clock,CPU_5M_CLOCK
	push	ax
	in	al,042h
	test	al,0C0h
	jz	detclck1
	test	al,020h
	jz	detclck1
	mov	cpu_clock,CPU_8M_CLOCK
detclck1:
	pop	ax
	ret
detclck	endp
 
; 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 data		; 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,'A'	;@@@@@
	jae	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:
	clc			; always success ! true ?!
        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 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:
	clc
	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	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
;
 
 
; Terminal emulator.
;
term    proc    near
	mov	oldsp,sp		; remember stack for i/o failure,
	mov	prthld,0		; clear port hold flag at the beginning
	mov	replay_hold,0
	mov	bx,portval
	mov	bx,[bx].flowc		; get flow control character
	mov	flowoff,bl
	mov	flowon,bh
	or	vt100_flags,AUTOTEK_BIT
	test	denyflg,tekxflg
	jz	term_01
	and	vt100_flags,(not AUTOTEK_BIT)
term_01:
	and	vt100_lflag,(not LOGENAB_BIT)
	test	flags.capflg,logses	; session logging enabled?
	jz	term_02			; z = no.
	or	vt100_lflag,LOGENAB_BIT
term_02:
	call	vt100_restore
	call	tek4014_restore
	mov	fairness,0
	mov	kanji_smode,0		; clear Kanji pending flag
	mov	kanji_rmode,0
	mov	kanji_7smode,0
	mov	kanji_7rmode,0
        mov     argadr,ax               ; save argument ptr
        mov     si,ax                   ; this is source
        mov     di,offset vt_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	vt_ourarg.flgs,not (prtscr) ; no screen printing at startup
;@@	mov	vt100_pflag,0
        mov     ax,vt_ourarg.captr
        mov     captrtn,ax              ; buffer capture routine
	test	vt_ourarg.flgs,modoff	; mode line off?
	jnz	term_1
	call	set_modlin		; setup mode line
term_1:
        mov     parmsk,0ffh             ; parity mask, assume parity = None
        cmp     vt_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:
	mov	ax,KI_code
	call	ans_keystr
	mov	KI_len,cx
	mov	KI_ofs,bx
	mov	ax,KO_code
	call	ans_keystr
	mov	KO_len,cx
	mov	KO_ofs,bx
;
	cmp	flags.vtflg,ttvt100	; vt100 emulation ?
	je	term_vt			; e = yes.
	cmp	flags.vtflg,ttvt52	; vt52 emulation ?
	je	term_vt			; e = yes.
	cmp	flags.vtflg,tttek	; Tek4014 emulation ?
	je	term_tk			; e = yes.
	jmp	term0			; non supported terminal
;
;  vt100/vt52 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
        jc	short term2	; c = no char, go on
        call    outtty          ; display and capture char
	inc	fairness
	cmp	fairness,100
	jb	term1		; do quick loop back for more
term2:	mov	fairness,0
	call	pntflsh		; flush printer buffer
	jnc	term2a		; nc = success
	call	pntdead		; call bad printer notifier
term2a:	call    keybd           ; keyboard translator to read and send text
        jnc     term1           ; nc = do not exit Connect mode

quit:	call	pntflsh		; flush printer buffer
	cmp	flags.vtflg,ttgenrc	; no emulation ?
	je	term3
	call	vt100_save
	call	tek4014_save
term3:	mov	al,1
	call	text_scrn	; ON the text screen
	xor	al,al
	mov	ah,prstr
        mov	dx,offset retscr
        int	dos
	ret
 
;term_tst1:
;	mov	ax,3D00h	; open file (read only)
;	mov	dx,offset playback_fnam
;	int	dos
;	jc	term_tstz	; if error, then normal operation
;	mov	playback_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,playback_hndl
;@@	mov	cx,8
;	mov	cx,72		;@@
;	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
;	mov	al,[si]		;@@
;	call	outtty		;@@
;	pop	si
;	pop	cx
;	inc	si
;
;  check the keyboard by using direct console i/o
;  Any key can be used for toggle of screen output.
;
;	push	dx
;	mov	ah,dconio	; direct console i/o
;	mov	dl,0ffh		; read
;	int	dos
;	jz	term_tst5
;term_tst6:
;	mov	ah,dconio
;	mov	dl,0ffh
;	int	dos
;	jz	term_tst6
;	cmp	al,CR
;	jne	term_tst5
;	pop	dx
;	jmp	term_tstx
;term_tst5:
;	pop	dx
;
;	loop	term_tst4
;	jmp	term_tst2
;term_tstx:
;	mov	ah,3Eh
;	mov	bx,playback_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).
 
; kanji_shiftin sends designation codes for G0 to JIS-C6226.
; kanji_shiftout sends designation codes for G0 to JIS-roman.
; These routines are called in chrout when JIS-7 is specified.
 
kanji_shiftin	proc	near
	push	ax		; save ax
	push	cx
	push	si
	mov	cx,KI_len
	jcxz	kanji_shiftin2
	mov	si,KI_ofs
kanji_shiftin1:
	mov	al,[si]
	push	si		; save si and cx.
	push	cx		;   these are broken when local echo is on
	call	outprt
	pop	cx
	pop	si
	inc	si
	loop	kanji_shiftin1
kanji_shiftin2:
	mov	kanji_7smode,1
	pop	si
	pop	cx
	pop	ax
	ret
kanji_shiftin	endp
 
kanji_shiftout	proc	near
	push	ax		; save ax
	push	cx
	push	si
	mov	cx,KO_len
	jcxz	kanji_shiftout2
	mov	si,KO_ofs
kanji_shiftout1:
	mov	al,[si]
	push	si		; save si and cx.
	push	cx		;   these are broken when local echo is on
	call	outprt
	pop	cx
	pop	si
	inc	si
	loop	kanji_shiftout1
kanji_shiftout2:
	mov	kanji_7smode,0
	pop	si
	pop	cx
	pop	ax
	ret
kanji_shiftout	endp
 
; chrout is called from KEYBD after key definition translation.
; the character is in AL.
 
chrout:
	cmp	kanji_scode,KNJCODE_NONE	; if kanji is not used,
	je	chroutx2			;   no translation
	cmp	kanji_scode,KNJCODE_SJIS	; if shift-JIS is used,
	je	chroutx2			;   no translation
	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:
	cmp	kanji_scode,KNJCODE_JIS7	; JIS-7 used ?
	jne	chroutx2		; ne = no
	cmp	kanji_7smode,0		; roman-mode ?
	je	chroutx2		; e = yes.
	cmp	al,DEL			; BS and DEL can be used in Kanji mode
	je	chroutx2
	cmp	al,BS
	je	chroutx2
	call	kanji_shiftout
chroutx2:
	test	vt100_flags,NEWLINE_BIT	; newline mode ?
	jz	chroutx1		; z = no
	cmp	al,0Dh			; CR ?
	jne	chroutx1		; ne = no
	call	outprt			; send it
	mov	al,0Ah			; send LF
chroutx1:
	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
	cmp	kanji_scode,KNJCODE_JIS7	; JIS-7 used ?
	je	chrout_knj21			; e = yes.
	or	ax,8080h		; convert to DEC code
	jmp	chrout_knj22
chrout_knj21:
	cmp	kanji_7smode,0		; roman-mode ?
	jne	chrout_knj22		; ne = no.
	call	kanji_shiftin
chrout_knj22:
	mov	kanjis1,ah
	mov	ah,0
	call	outprt
	mov	al,kanjis1
	jmp	chroutx1
 
trnprs:	push	ax			; toggle Copy screen to printer
	test	vt100_pflag,(AUTOPRINT_BIT+PRINTCTRL_BIT)
					; are we currently printing?
	jz	trnpr0			; z = no, check the printer status
	and	vt100_pflag,(not (AUTOPRINT_BIT+PRINTCTRL_BIT))
					; clear printer flag
	jmp	trnpr1			; and going off
trnpr0:
	push	bx
	mov	bx,prnhand		; file handle for system printer
	mov	ah,ioctl
	mov	al,7			; get output status of printer
	int	dos
	pop	bx
	jc	trnpr1			; c = printer not ready
	cmp	al,0ffh			; Ready status
	jne	trnpr3			; ne = not-Ready	
	or	vt100_pflag,AUTOPRINT_BIT	; set the autoprint flag
trnpr1:	call	set_modlin
	call	vt100_modlin
trnpr3:	pop	ax
	clc				; return carry clear (don't quit)
	ret
 
prtscn:	call	vt100_prns
	clc
	ret
 
klogon	proc	near			; resume logging (if any)
	test	flags.capflg,logses	; session logging enabled?
	jz	klogn			; z = no, forget it
        or      vt_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	al,ESCAPE		; [06-July-1990]
	call	outprt			; [06-July-1990]
	cmp	flags.vtflg,ttvt52
	je	comar2
	mov	al,'['			; [06-July-1990]
	cmp	curkey_mode,0
	je	comar1
	mov	al,'O'			; [06-July-1990]
comar1:	call	outprt			; [06-July-1990]
comar2:
	pop	ax
	call	outprt			; [06-July-1990]
	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	al,ESCAPE		; [06-July-1990]
	call	outprt			; [06-July-1990]
	cmp	flags.vtflg,ttvt52
	je	compf1
	mov	al,'O'
	call	outprt			; [06-July-1990]
compf1:
	pop	ax
	call	outprt			; [06-July-1990]
	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	al,ESCAPE		; [06-July-1990]
	call	outprt			; [06-July-1990]
	mov	al,'O'			; [06-July-1990]
	cmp	flags.vtflg,ttvt52
	jne	comkp0
	mov	al,'?'			; [06-July-1990]
comkp0:
	call	outprt			; [06-July-1990]
	pop	ax
	jmp	short comkp2
comkp1:	sub	al,40h
comkp2:
	call	outprt			; [06-July-1990]
	clc
	ret
 
decf6:
decf7:
decf8:
decf9:
decf10:
decf11:
decf12:
decf13:
decf14:
dechelp:
decdo:
decf17:
decf18:
decf19:
decf20:
	jmp	comdec1
decfind:
	mov	ah,'1'
	jmp	comdec
decinsert:
	mov	ah,'2'
	jmp	comdec
decremove:
	mov	ah,'3'
	jmp	comdec
decselect:
	mov	ah,'4'
	jmp	comdec
decprev:
	mov	ah,'5'
	jmp	comdec
decnext:
	mov	ah,'6'
comdec:
	push	ax
	mov	ah,ESCAPE
	call	outchr
	mov	ah,'['
	call	outchr
	pop	ax
	call	outchr
	mov	ah,'~'
	call	outchr
comdec1:
	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
 
; change terminal emulator
;
vtchg:
	cmp	flags.vtflg,ttvt100	; vt100 emulation mode?
	jne	vtchg_nvt100
	call	vt100_save
	jmp	vtchg1
vtchg_nvt100:
	cmp	flags.vtflg,tttek	; tek emulation mode?
	jne	vtchg_ntek
	call	tek4014_save
	jmp	vtchg1
vtchg_ntek:
vtchg1:
	inc	flags.vtflg
	cmp	flags.vtflg,TTTYPES
	jb	vtchg2
	mov	flags.vtflg,ttgenrc
	jmp	vtchg3
vtchg2:
	cmp	flags.vtflg,ttgenrc
	jne	vtchg21
	jmp	vtchg3
vtchg21:
	cmp	flags.vtflg,ttvt100
	jne	vtchg22
	call	ent_vt
	jmp	vtchg3
vtchg22:
	cmp	flags.vtflg,tttek
	jne	vtchg23
	call	ent_tk
	jmp	vtchg3
vtchg23:
	call	set_modlin
	call	vt100_modlin
	jmp	vtchg1
vtchg3:
	clc			; stay in connect mode
	ret
;
; reset terminal
vtreset:
	cmp	flags.vtflg,ttvt100
	jne	vtreset1
	call	vt100_reset
	jmp	vtresetx
vtreset1:
	cmp	flags.vtflg,tttek
	jne	vtreset2
	call	tek4014_reset
	jmp	vtresetx
vtreset2:
vtresetx:
	clc
	ret
 
upone:
	push	ax
	push	cx
	call	sense_sftkey
	test	al,08h		; GRPH is pressed ?
	jz	upone_1		; z=no
	mov	cx,6
	call	sixel_rollup
	jmp	upone_2
upone_1:
	mov	cx,1
	call	vt100_rupn
upone_2:
	pop	cx
	pop	ax
	clc
	ret
 
dnone:
	push	ax
	push	cx
	call	sense_sftkey
	test	al,08h		; GRPH is pressed ?
	jz	dnone_1
	mov	cx,6
	call	sixel_rolldown
	jmp	dnone_2
dnone_1:
	mov	cx,1
	call	vt100_rdnn
dnone_2:
	pop	cx
	pop	ax
	clc
	ret
 
upscn:
	push	cx
	mov	cx,24
	call	vt100_rupn
	pop	cx
	clc
	ret
 
dnscn:
	push	cx
	mov	cx,24
	call	vt100_rdnn
	pop	cx
	clc
	ret
 
gupone:
	push	cx
	mov	cx,6
	call	sixel_rollup
	pop	cx
	clc
	ret
 
gdnone:
	push	cx
	mov	cx,6
	call	sixel_rolldown
	pop	cx
	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
trnmod:	mov	al,'M'
	jmp	short cmdcom
cmdcom: mov     kbdflg,al               ; pass char to msster.asm via kbdflg
        stc                             ; say exit Connect mode
        ret
                                        ;; end of action routines
;
; capture routine.
; If capture flag is ON, put the character in AL to the file.
;
outcapt	proc	near
        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      outcapt1		; no, forget this part
        push    ax                      ; save char
        call    captrtn                 ; give it captured character
        pop     ax                      ; restore character and keep going
outcapt1:
	ret
outcapt	endp

;
; Dumb terminal emulator. AL is the character to be displayed.
; Taken from MSXGEN.ASM .
;
dumbterm	proc	near
	cmp	vt100_lflag,(LOGCOOK_BIT+LOGENAB_BIT)	; is cooked logging ?
	jne	dumbterm1		; ne = no.
	call	outcapt
dumbterm1:
	test	vt100_pflag,AUTOPRINT_BIT	; should we be printing?
	jz	dumbterm2		; no, keep going
        push    ax
        mov     ah,LSTOUT		; write to system printer device
        mov     dl,al
        int     dos
        pop     ax
        jnc     dumbterm2		; nc = successful print
        push    ax
        call    beep                    ; else make a noise and
        call    trnprs                  ;  turn off printing
        pop     ax
dumbterm2:
	test    vt_ourarg.flgs,trnctl      ; debug? if so use dos tty mode
        jz      dumbterm8		; z = no
        mov     ah,conout
        cmp     al,7fh                  ; Ascii Del char or greater?
        jb	dumbterm4		; b = no
        je	dumbterm3		; 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
dumbterm3:
	cmp     al,7fh                  ; is char now a DEL?
        jne	dumbterm4		; ne = no
        and     al,3fH			; strip next highest bit (Del --> '?')
        jmp	dumbterm5		; send, preceded by caret
dumbterm4:
	cmp     al,' '                  ; control char?
        jae	dumbterm6		; ae = no
        add     al,'A'-1                ; make visible
dumbterm5:
	push    ax                      ; save char
        mov     dl,5eh                  ; caret
        int     dos                     ; display it
        pop     ax                      ; recover the non-printable char
dumbterm6:
	mov     dl,al
        int     dos
        ret
dumbterm7:
	test    flags.remflg,d8bit      ; keep 8 bits for displays?
        jnz     dumbterm8		; nz = yes, 8 bits if possible
        and     al,7fh                  ; remove high bit
dumbterm8:
	mov     ah,conout               ; dostty screen mode
        mov     dl,al                   ; write without intervention
        int     dos                     ; else let dos display char
        ret                             ; and return
dumbterm	endp


; put the character in al to the screen, do capture and printing,
; does translation for Set Input command.
; Adapted from msyibm.asm [jrd]

outtty  proc    near
        test    flags.remflg,d8bit      ; keep 8 bits for displays?
        jnz     outnp8                  ; nz = yes, 8 bits if possible
        and     al,7fh                  ; remove high bit
outnp8:
	cmp	vt100_lflag,LOGENAB_BIT	; raw mode logging ?
	jne	outtty_lg1		; ne = no.
	call	outcapt			; log it
outtty_lg1:
        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. If kanji is used for receiving characters,
; do translation for capture file, printer and display.
; The capture file and printer use shift-JIS. On the other hand,
; VT100 emulator ueses DEC (extended UNIX - JIS-8) code.
;
outtty_knj0:
	cmp	kanji_rcode,KNJCODE_NONE	; Kanji code used ?
	je	outtty_knj2		; e = no, no translation
	cmp	kanji_rcode,KNJCODE_DEC		; DEC (EUC) code ?
	jne	outtty_knj1		; ne = no
	jmp	outtty_dknj0		; jump to DEC kanji processor
outtty_knj1:
	cmp	kanji_rcode,KNJCODE_SJIS	; Shift-JIS code ?
	jne	outtty_knj2		; ne = no
	jmp	outtty_sknj0		; jump to Shift-JIS process
outtty_knj2:
	jmp	outtty_trm
;
outtty_dknj0:
	cmp	flags.vtflg,0		; dumb terminal ?
	je	outtty_dknj1		; e = Yes. Needs code conversion.
	jmp	outtty_trm1
outtty_dknj1:
        cmp	kanji_rmode,0		; 2-byte code in progress ?
	je	outtty_dknj2		; e = No, not in progress.
	mov	kanjir2,al		; put 2nd byte
	mov	ah,al			; prepare to conversion
	mov	al,kanjir1		; put 1st byte
	cmp	al,08Eh			; SS2 ?
	jne	outtty_dknj5		; ne = No.
	mov	al,kanjir2		; get 2nd byte
	jmp	outtty_dknj3
outtty_dknj5:
	and	ax,7f7fh		; mask 8-th bits
	call	jis2s			; convert to Shift-JIS
	xchg	kanjir1,al		; save the 2byte code
	xchg	kanjir2,ah
	mov	kanjio1,ah
	mov	al,kanjir1
	call	dumbterm
	mov	al,kanjir2
	jmp	outtty_dknj3
outtty_dknj2:
	cmp	al,08Eh			; SS2 ?
	je	outtty_dknj4		; e = Yes.
	cmp	al,0A0h			; is Kanji ?
	jbe	outtty_dknj3		; z = No.
outtty_dknj4:
	mov	kanji_rmode,1		; set multi-byte flag
	mov	kanjio1,al		; save 1st byte
	mov	kanjir1,al
	ret
outtty_dknj3:
	call	dumbterm
	mov	kanji_rmode,0
	ret
;
outtty_sknj0:
outtty_sknj2:
	cmp     flags.vtflg,0           ; emulating a terminal?
        jnz	outtty_sknj3		; nz = yup, go do something smart
	call	dumbterm		; dumb terminal emulation
	ret
outtty_sknj3:
	cmp	kanji_rmode,0		; is it 1st byte character?
	je	outtty_sknj4		; e = yes.
	mov	kanjio2,al		; put 2nd byte
	mov	ah,al			; prepare to conversion
	mov	al,kanjio1		; put 1st byte
	call	s2jis			; convert to JIS
	or	ax,8080h		; use GR set
	xchg	kanjio1,al		; save the 2byte code
	xchg	kanjio2,ah
	mov	kanjir1,ah
	jmp	outtty_trm1
outtty_sknj4:
	call	is_kanji1		; check if kanji
	jc	outtty_sknj6		; c = Yes.
	test	al,80h			; katakana ?
	jz	outtty_sknj5		; z = No.
	mov	kanji_rmode,1		; set multi-byte flag
	mov	kanjio1,08Eh		; SS2 code
	mov	kanjio2,al		; extended UNIX convention
outtty_sknj5:
	jmp	outtty_trm1
outtty_sknj6:
	mov	kanji_rmode,1
	mov	kanjir1,al
	mov	kanjio1,al
	ret
;
outtty_trm:
	cmp	flags.vtflg,0
	jne	outtty_trm1
	call	dumbterm
	ret
outtty_trm1:
	cmp	flags.vtflg,tttek
	je	outtty_tk
;
outtty_vt:
outtty_vt1:
	cmp	kanji_rmode,0
	je	outtty_vt3
outtty_vt2:
	mov	al,kanjio1
	call	vt100
	mov	al,kanjio2
outtty_vt3:
	call	vt100
;
	cmp	ah,0
	jne	outtty_vt4
	jmp	outtty_snd
outtty_vt4:
	push	ax
	push	dx
;;@@	call	vt100_save
	mov	flags.vtflg,tttek
	call	ent_tk
	pop	dx
	pop	ax
	cmp	ah,2
	je	outtty_tk3
	cmp	ah,3
	jne	outtty_vt5
	mov	kanjio1,dh
	mov	kanjio2,dl
	jmp	outtty_tk2
outtty_vt5:
	jmp	outtty_snd_ex
 
outtty_tk:
outtty_tk1:
	cmp	kanji_rmode,0
	je	outtty_tk3
outtty_tk2:
	mov	al,kanjio1
	call	tek4014
	jnc	outtty_tk2_2
	jcxz	outtty_tk2_2
outtty_tk2_1:
	lodsb
	push	cx
	push	si
	call	vt100
	pop	si
	pop	cx
	loop	outtty_tk2_1
outtty_tk2_2:
	mov	al,kanjio2
outtty_tk3:
	call	tek4014
	jnc	outtty_tk3_2
	jcxz	outtty_tk3_2
outtty_tk3_1:
	lodsb
	push	cx
	push	si
	call	vt100
	pop	si
	pop	cx
	loop	outtty_tk3_1
outtty_tk3_2:
;
	cmp	ah,0
	jne	outtty_tk4
	jmp	outtty_snd
outtty_tk4:
	push	ax
	push	dx
;;@@	call	tek4014_save
	mov	flags.vtflg,ttvt100
	call	ent_vt
	pop	dx
	pop	ax
	cmp	ah,2
	je	outtty_vt3
	cmp	ah,3
	jne	outtty_tk5
	mov	kanjio1,dh
	mov	kanjio2,dl
	jmp	outtty_vt2
outtty_tk5:
	jmp	outtty_snd_ex
;
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  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    vt_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
        ret
outprt  endp

pntdead	proc	near			; display printer is inoperative msg
	push	ax
	test	vt_ourarg.flgs,modoff	; mode line off?
	jnz	pntdea1			; nz = off, skip msg
	push	bx
	mov	dx,offset pntmsg	; say printer not ready
	call	putmod			; write on mode line
	pop	bx
pntdea1:pop	ax
	stc				; say printer not ready
	ret
pntdead	endp

 
; Get a char from the serial port manager
; returns with carry clear if a character is available
portchr proc    near
        call    prtchr                  ; character at port?
        jc	portc2			; no character
	and     al,parmsk               ; apply 8/7 bit parity mask
        or      al,al                   ; catch nulls
        jnz	portc2			; nz = non null
        stc				; ignore null
portc2: ret
portchr endp

; Jump here to exit Connect mode and execute macros 'TERMINALR' (vtrmac) or
; 'TERMINALS' (vtsmac). Does nothing if macro does not exist.
; Preserves registers except ax. Returns to TELNET caller with 'C' in kbdflg.
vtrmac	proc	near			; RESET macro
	mov	vtmacname,offset vtrname ; select macro name
	mov	vtmaclen,vtrlen		; and its length
	jmp	vtmacro
vtrmac	endp

vtsmac	proc	near			; SET macro
	mov	vtmacname,offset vtsname
	mov	vtmaclen,vtslen
	jmp	vtmacro
vtsmac	endp

; Invoked by keyboard translator when an unknown keyboard verb is used as
; a string definition, such as {\ktest}. Enter with vtmacname pointing to
; uppercased verb name, asciiz, and vtmaclen set to its length.
extmacro proc	near
	jmp	vtmacro
extmacro endp

;
; Reference	Macro structure for	db	number of entries (mac names)
;  is file	 table mcctab	   |->	db	length of macroname, excl '$'
;  mssset.asm		each entry |-> 	db	'macroname','$'
;  where these			   |->	dw	segment:0 of definition string
;  are stored.					  (offset part is always 0)	
;		Definition string in 	db	length of <string with null>
;		 buffer macbuf	  	db	'string with trailing null'
;
vtmacro	proc	far			; common code for macros vtsmac,vtrmac
	push	bx			; and Product
	push	cx
	push	si
	push	di
	push	es
	mov	ax,ds
	mov	es,ax
	mov	di,offset rdbuf+1	; macro def buffer starts here
	mov	si,vtmacname		; pointer to macro name
	mov	cl,vtmaclen		; length of macro name<sp/null>text
	xor	ch,ch
	mov	[di-1],cl		; counted string field
	cld
	rep	movsb			; copy to rdbuf
	mov	byte ptr [di],0		; null terminator
	mov	si,offset rdbuf+1	; look for name-text separator
	mov	cl,vtmaclen
	xor	ch,ch
vtmac1:	lodsb
	cmp	al,' '			; space separator?
	je	vtmac1a			; e = yes, stop here
	or	al,al			; null terminator?
	jz	vtmac1a			; e = yes, stop here
	loop	vtmac1
	inc	si			; to do null lenght correctly
vtmac1a:sub	si,offset rdbuf+1+1	; compute length of macro name
	mov	cx,si
	mov	vtmaclen,cl		; save a macro name length
					; check for existence of macro
	mov	bx,offset mcctab	; table of macro names
	mov	cl,[bx]			; number of names in table
	xor	ch,ch
	jcxz	vtmacx			; z = empty table, do nothing
	inc	bx			; point to length of first name
vtmac2:	mov	al,[bx]			; length of this name
	xor	ah,ah
	cmp	al,vtmaclen		; length same as desired keyword?
	jne	vtmac3			; ne = no, search again
	mov	si,bx
	inc	si			; point at first char of name
	push	cx			; save name counter
	push	di			; save reg
	mov	cl,vtmaclen		; length of name, excluding '$'
	xor	ch,ch
	mov	di,vtmacname		; point at desired macro name
	push	es			; save reg
	push	ds
	pop	es			; make es use data segment
	cld
	repe	cmpsb			; match strings
	pop	es			; need current si below
	pop	cx
	pop	di			; recover saved regs
	je	vtmac4			; e = matched
vtmac3:	add	bx,ax			; step to next name, add name length
	add	bx,4			; + count, dollar sign, def word ptr
	loop	vtmac2			; try next name
vtmacx:	pop	es
	pop	di
	pop	si			; no macro, return to Connect mode
	pop	cx
	pop	bx
	ret

vtmac4:	cmp	taklev,maxtak		; room in Take level?
	jge	vtmacx			; ge = no, exit with no action
	inc	taklev			; increment take level
	add	takadr,size takinfo	; make a new Take entry/macro
	mov	bx,takadr		; point to current macro structure
	mov	ax,ds			; segment of rdbuf
	mov	[bx].takbuf,ax		; segment of definition string struc
	mov	cl,rdbuf		; length of whole string
	xor	ch,ch
	mov	[bx].takcnt,cx		; number of chars in definition
	mov	[bx].takargc,0		; our argument count
	mov	[bx].takptr,offset rdbuf+1 ; where to read next command char
	mov	[bx].taktyp,0ffh	; flag as a macro
	pop	es
	pop	di
	pop	si
	pop	cx
	pop	bx
	jmp	endcon			; exit Connect mode
vtmacro	endp

; Error recovery routine used when outchr reports unable to send character
;  or when vtmacro requests exiting Connect mode.
; Exit Connect mode cleanly, despite layers of intermediate calls.
endcon	proc	near
	mov	kbdflg,'C'		; report 'C' to TERM's caller
	mov	sp,oldsp		; recover startup stack pointer
					; TERM caller's return address is now
					; on the top of stack. A longjmp.
	jmp	quit			; exit Connect mode cleanly
endcon	endp
code    ends
        end
