home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
kermit.columbia.edu
/
kermit.columbia.edu.tar
/
kermit.columbia.edu
/
mskermit
/
msxp98.asm
< prev
next >
Wrap
Assembly Source File
|
2018-01-01
|
83KB
|
3,408 lines
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