|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T m
Length: 86841 (0x15339)
Types: TextFile
Names: »msxp98.asm«
└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit
└─⟦71044c191⟧ »EurOpenD3/misc/kermit.ms-2.32.tar.Z«
└─⟦31f2d420d⟧
└─⟦this⟧ »msxp98.asm«
name msxp98
; File MSXP98.ASM
; NEC PC-9801 MS DOS Kermit module.
;
; Last edit: 16 Jul 1988
; 16 Jul 1988 Keyboard kanji translation comes into chrout to work with
; SET KEY command.
; 14 Jul 1988 V2.31
; old global variable PCNET is now local variable
; local termination pointer NETDONE is renamed LCLEXIT
; GETMODEM is added as a dummy routine (from MSXGEN.ASM)
; Ungermann-Bass port name is UB-NETCI
; 25 Jun 1988 Ungermann-Bass PC-NIU N98 support in NETCI mode
; 15 Jun 1988 V1.00
; 06 Jun 1988 show modem is installed
; 23 May 1988 added KEYCLICK, AUTOTEK features
; 19 May 1988 become v2.27(A) level (TEK4014, VT100)
; 18 May 1988 Keyboard routine for VT100 is installed.
; 16 May 1988 Works with v2.27(A) VT100 output routine.
; 15 May 1988 Fixed bug in SERINI.
; 14 May 1988 Works with dumb terminal emulator !
; 12 May 1988 start coding based on MSXGEN.ASM by H.Fujii
public serini, serrst, clrbuf, outchr, coms, vts, vtstat, dodel
public ctlu, cmblnk, locate, lclini, prtchr, dobaud, clearl
public dodisk, getbaud, beep, trnprs, pcwait, termtb
public count, xofsnt, puthlp, putmod, clrmod, poscur
public sendbr, sendbl, term, machnam, setktab, setkhlp, showkey
public ihosts, ihostr, dtrlow, serhng, dumpscr, comptab
public chrout, cstatus, cquit, cquery, chang ; kbd action verbs
public snull, kdos, klogof, klogon
public shomodem, getmodem, mdmhand
public pf1, pf2, pf3, pf4
public kp0, kp1, kp2, kp3, kp4, kp5, kp6, kp7, kp8, kp9
public kpmins, kpcoma, kpentr, kpdot
public uparrw, dnarrw, lfarrw, rtarrw
public keyinchg
public s2jis, jis2s, is_kanji1
public curkey_mode, keypad_mode
public kanji_rmode, kanji_smode
public keyin_dos, vt100_flags
include mssdef.h
BIOS equ 18h
AUTOWRAP_BIT equ 1
AUTOTEK_BIT equ 2
KEYCLICK_BIT equ 4
CURSOR_BIT equ 8
BLINK_BIT equ 16
LOOPTEST_BIT equ 128
CHR_GS equ 1Dh
CHR_CAN equ 18h
false equ 0
true equ 1
instat equ 6
print_out equ 05h ; dos function to print to printer
prtscr equ 80h ; print screen pressed
;
; Ungermann-Bass PC-NIU N98 command interpreter interface
; CALL AH -- Function number
; AL -- Port number relative to 0
; CX -- may be a counter
; ES:BX -- may be a buffer address
NETCI_PORT equ 0 ; NETCI port number
NETCI_INT equ 06Bh ; Software interrupt vector# for NETCI
NETCI_OPEN equ 2 ; NETCI open function
NETCI_CLOSE equ 3 ; NETCI close function
NETCI_READ equ 1 ; NETCI read function
NETCI_WRITE equ 0 ; NETCI write function
NETCI_CNTL equ 6 ; NETCI control function
NETCI_STATUS equ 7 ; NETCI status function
NETCI_RBRK equ 8 ; NETCI read break function
; Buffer size for Network transfer
NETBUFLEN equ 256
; port assignments for 8251 serial controllers
;
;== PORT 1 ==
mndata equ 30h
mnst1a equ 32h
mncmda equ 32h
mnmska equ 35h ; mask set
mnrdsa equ 33h ; read signal
;== PORT 2 ==
mndatb equ 0B1h
mnst1b equ 0B3h
mncmdb equ 0B3h
mnmskb equ 0B0h
mnrdsb equ 0B0h ; read signal
;== PORT 3 ==
mndatc equ 0B9h
mnst1c equ 0BBh
mncmdc equ 0BBh
mnmskc equ 0B2h ; mask set
mnrdsc equ 0B2h ; read signal
; Status bits from austt
txrdy equ 01h
rxrdy equ 02h
; Command values for mncmd
ccmd equ 37H ; RTS & DTR high, RX & TX enabled, reset ERR
cbrk equ 08H ; break enabled
cmode equ 40H ; enable mode reset
mmode equ 4EH ; 16x rate, 8 data, no parity, 1 stop
; Mask values for mnmsk
txmsk equ 04H ; disables transmit ready interrupt
rxmsk equ 01H ; disables receive ready interrupt
tbemsk equ 02H ; disables transmit buffer empty interrupt
; port assignments for 8253 timers
; Standard interface
tmdata equ 75H ; data port
tmcmda equ 77H ; command port (Was 27H Ian 10/27/84)
; values for tmcmd which select timer channel and mode
tmsela equ 0B6H ; Channel 2, mode 3 (standard port)
; Timer information for current port selection
tmrinfo struc
tmdat dw 0 ; data port
tmcmd dw 0 ; command port
tmsel db 0 ; byte which selects channel and mode
tmrinfo ends
; Modem information for current port selection
; port assignments for 8259 interrupt controllers
; Standard interface
intcmda equ 00H ; Command port (master controller)
intmska equ 02H ; Mask port
ictmsk equ 01H ; Timer interrupt mask (to master)
icsmska equ 10H ; Standard serial interrupt mask (to master)
icsvcta equ 0CH ;Interrupt vector for standard interface
icEOI equ 20H ; generic end of interrupt for intcmd
kbfifosiz equ 64 ; size of fifo buffer in IO.SYS
; miscellaneous constants
ctrlP equ 10H ; ^P.
ctrl_q equ 11H ; ^Q
ctrl_s equ 13H ; ^S
printkey equ 00FFH ; Scan code of unshifted PRINT key.
brkstp equ 0096H ; Scan code of unshifted break/stop key.
mntrgh equ bufsiz*3/4 ; High XON/XOFF trigger = 3/4 of buffer full.
; external variables used:
; drives - # of disk drives on system
; flags - global flags as per flginfo structure defined in pcdefs
; trans - global transmission parameters, trinfo struct defined in pcdefs
; portval - pointer to current portinfo structure (currently either port1
; or port2)
; port1, port2 - portinfo structures for the corresponding ports
; global variables defined in this module:
; xofsnt, xofrcv - tell whether we saw or sent an xoff.
datas segment public 'datas'
extrn drives:byte, flags:byte, trans:byte, ttyact:byte
extrn filtst:byte ;* in mssker
extrn portval:word, port1:byte, port2:byte, port3:byte, port4:byte
extrn lclexit:word
extrn comand:byte, dmpname:byte ; [jrd]
extrn kbdflg:byte, rxtable:byte
;- common variables -----
curkey_mode db 0
keypad_mode db 0
kanji_smode db 0 ; Kanji 1st/2nd byte indicator
kanji_rmode db 0
kanji_scode db 0
kanji_rcode db 0
keyin_dos db 0
vt100_flags db 0
;------------------------
pcnet db 0 ; 2.30 global --> 2.31 local
kanjis1 db 0 ; storage for Kanji 1st byte
kanjir1 db 0
kanjio1 db 0 ; storage for DEC Kanji code
kanjio2 db 0
param_dst dw ?
mdstreg db ? ; modem status register
machnam db 'NEC PC-9801 (KEK v1.10)$'
erms20 db cr,lf,'?Warning: System has no disk drives$'
erms40 db cr,lf,'?Warning: Unrecognized baud rate$'
erms41 db cr,lf,'?Warning: Cannot open com port$'
erms50 db cr,lf,'Error reading from device$'
hnd1 db cr,lf,'Enter a file handle. Check your DOS manual if you are '
db cr,lf,'not certain what value to supply (generally 3).$'
hnd2 db cr,lf,'Handle: $'
hnderr db cr,lf,'Warning: Handle not known.'
deverr db cr,lf,'Any routine using the communications port will'
db cr,lf,'probably not work.$'
hndhlp db cr,lf,'A one to four digit file handle $'
dev1 db cr,lf,'Device: $'
devhlp db cr,lf,'Name for your systems auxiliary port $'
badbd db cr,lf,'Unimplemented baud rate$'
noimp db cr,lf,'Command not implemented.$'
hngmsg db cr,lf,' The phone should have hungup.',cr,lf,'$'
hnghlp db cr,lf,' The modem control lines DTR and RTS for the current'
db ' port are forced low (off)'
db cr,lf,' to hangup the phone. Normally, Kermit leaves them'
db ' high (on) when it exits.'
db cr,lf,'$'
msmsg1 db cr,lf,' Modem is not ready: DSR is off$'
msmsg2 db cr,lf,' Modem is ready: DSR is on$'
msmsg3 db cr,lf,' no Carrier Detect: CD is off$'
msmsg4 db cr,lf,' Carrier Detect: CD is on$'
msmsg5 db cr,lf,' no Clear To Send: CTS is off$'
msmsg6 db cr,lf,' Clear To Send: CTS is on$'
rdbuf db 80 dup (?) ; temp buf [jrd]
tmpbuf db 80 DUP (?)
test_hndl dw ?
test_fnam db 'KERMIT.TST',0
shkmsg db 'Not implemented.'
shklen equ $-shkmsg
setktab db 0
setkhlp db 0
crlf db cr,lf,'$'
delstr db BS,BS,' ',BS,BS,'$' ; Delete string
delscr db ESCAPE,'[2J$' ; Delete screen
scn_color dw 0507h
save_cur db ESCAPE,'[s$' ; save cursor
restore_cur db ESCAPE,'[u$' ; resoter cursor
home_cur db ESCAPE,'[H$' ; home cursor
; If delete code moves cursor then BS over code, BS over bad char, space
; over both to erase from screen, BS twice to restore cursor position.
clrlin db cr,'$' ; Clear line (just the cr part).
clreol db ESCAPE,'[K$' ; Clear to end of line.
telflg db 0 ; non-zero if we're a terminal.
argadr dw ? ; address of arg blk from msster.asm
parmsk db ? ; 8/7 bit parity mask, for reception
flowoff db ? ; flow-off char, Xoff or null (if no flow)
flowon db ? ; flow-on char, Xon or null
captrtn dw ? ; routine to call for captured output
xofsnt db 0 ; Say if we sent an XOFF.
xofrcv db 0 ; Say if we received an XOFF.
prthnd dw 0 ; Port handle.
temp dw 0
temp1 dw ? ; Temporary storage.
temp2 dw ? ; Temporary storage.
prtstr db 20 dup(?) ; Name of auxiliary device
; Entries for choosing communications port
comptab db 7 ; Number of options
mkeyw '1',1
mkeyw '2',2
mkeyw '3',3
mkeyw 'COM1',1
mkeyw 'COM2',2
mkeyw 'COM3',3
mkeyw 'UB-NETCI','N'
mkeyw ' ',0 ; port is not present, for Status
ourarg termarg <>
modem mdminfo <mndata,mnst1a,mncmda,0,0,0,0>
timer tmrinfo <tmdata,tmcmda,tmsela>
;++ The following structure must be initialized as in MSSKER
;
portn prtinfo <0FFFFh,0,defpar,1,0,defhand,floxon>
termtb db tttypes ; entries for Status, not Set
mkeyw 'Heath-19',ttheath
mkeyw 'none',ttgenrc
mkeyw 'Tek4014',tttek
mkeyw 'VT102',ttvt100
mkeyw 'VT52',ttvt52
vthlp db ' one of the following:',cr,lf
db ' terminal types of: None, VT102, or Tek4014',cr,lf
db ' Keyclick (on/off) '
db ' Keyinput (CON/direct) ',cr,lf
db ' Color (white,yellow...)'
db ' Highlight (cyan,green...)',cr,lf
db ' AutoTek (on/off) ',
db ' Kanji-code (DECcode,ShiftJIS,none)',cr,lf
db '$'
; <<< DO NOT forget to update the number of items at 'vttbl' when you add
; new item to the following list >>>
vttbl db 13
mkeyw 'AutoTek',AUTOTEK_BIT+200H
mkeyw 'Blink',BLINK_BIT+200H
mkeyw 'Color',300H
mkeyw 'Cursor',CURSOR_BIT+200H
mkeyw 'Highlight',301H
mkeyw 'Kanji-Code',400H
mkeyw 'Keyclick',KEYCLICK_BIT+200H
mkeyw 'Keyinput',500H
mkeyw 'LoopTest',LOOPTEST_BIT+200H
mkeyw 'None',ttgenrc+100H ; note 100H flag for decoding here
mkeyw 'Tek4014',tttek+100H
mkeyw 'VT102',ttvt100+100H
mkeyw 'Wrap',AUTOWRAP_BIT+200H
; <<< DO NOT forget to update the number of items at 'vttbl' when you add
; new item to the above list >>>
ontab db 2
mkeyw 'off',0
mkeyw 'on',1
colortab db 8
mkeyw 'black',0
mkeyw 'blue',1
mkeyw 'cyan',5
mkeyw 'green',4
mkeyw 'magenta',3
mkeyw 'red',2
mkeyw 'white',7
mkeyw 'yellow',6
kanjitab db 3
mkeyw 'DEC-code',2
mkeyw 'None',0
mkeyw 'Shift-JIS',4
keyintab db 2
mkeyw 'CON ',1
mkeyw 'direct',0
; this table is indexed by the baud rate definitions given in
; pcdefs. Unsupported baud rates should contain FF.
; Baudrate clock count table for 5/10 MHz CPU
even
bddat5 label word ; AHS 29-MAY-86
dw 00D30H ; 45.5 baud
dw 00C00H ; 50 baud
dw 00800H ; 75 baud
dw 00574H ; 110 baud
dw 00476H ; 134.5 baud
dw 00400H ; 150 baud
dw 00200H ; 300 baud
dw 00100H ; 600 baud
dw 00080H ; 1200 baud
dw 00055H ; 1800 baud
dw 0004DH ; 2000 baud
dw 00040H ; 2400 baud
dw 00020H ; 4800 baud
dw 00010H ; 9600 baud
dw 00008H ; 19200 baud
dw 00004H ; 38400 baud (not tested - may not work)
dw 0FFFFH
dw 0FFFFH
dw 0FFFFH
; Baud rate clock count table for 8 MHz CPU
bddat8 label word ; AHS 29-MAY-86
dw 0FFFFH ; 45.5 baud
dw 0FFFFH ; 50 baud
dw 00680H ; 75 baud
dw 0FFFFH ; 110 baud
dw 0FFFFH ; 134.5 baud
dw 00340H ; 150 baud
dw 001A0H ; 300 baud
dw 000D0H ; 600 baud
dw 00068H ; 1200 baud
dw 0004EH ; 1800 baud
dw 0FFFFH ; 2000 baud
dw 00034H ; 2400 baud
dw 0001AH ; 4800 baud
dw 0000DH ; 9600 baud
dw 0FFFFH ; 19200 baud
dw 0FFFFH ; 38400 baud (not tested - may not work)
dw 0FFFFH
dw 0FFFFH
dw 0FFFFH
baudlen equ ($-bddat8)/2 ; number of entries above
unkbaud db ' Unk ' ; must be 5 characters
baudname db ' 45.5'
db ' 50 '
db ' 75 '
db ' 110 '
db '134.5'
db ' 150 '
db ' 300 '
db ' 600 '
db ' 1200'
db ' 1800'
db ' 2000'
db ' 2400'
db ' 4800'
db ' 9600'
db '19200'
db '38400'
db '57.6K'
db '115 K'
BAUDNSIZ equ 18
parityname db 'even' ; must be 4 characters
db 'mark'
db 'none'
db 'odd '
db 'spc '
lclename db 'loc'
remename db 'rem'
axsave dw ?
portinia dw 0
dmphand dw ? ; file handle for dump file
oldsera_ofs dw ?
oldsera_sgm dw ?
oldmska db ?
oldmsdat db ?
; variables for serial interrupt handler
even
source db bufsiz DUP (?) ; Buffer for data from port.
db 2 DUP (?) ; guard for source.
srcpnt dw 0 ; Pointer in buffer (DI).
count dw 0 ; Number of chars in int buffer.
rcvpnt dw 0 ; Save SI register here.
mdmhand db 0 ; modem status register, current
; buffer for network
xmtbuf db NETBUFLEN DUP (0) ; Buffer for Network xfer.
db 2 DUP (0) ; guard
xmtpnt dw 0
xmtcnt dw 0
; Function key definition tables
ker_keydef db 0FEh,'f 01 ',0FFh,062h, 8 dup (0) ; f 1
db 0FEh,'f 02 ',0FFh,063h, 8 dup (0) ; f 2
db 0FEh,'f 03 ',0FFh,064h, 8 dup (0) ; f 3
db 0FEh,'f 04 ',0FFh,065h, 8 dup (0) ; f 4
db 0FEh,'f 05 ',0FFh,066h, 8 dup (0) ; f 5
db 0FEh,'f 06 ',0FFh,067h, 8 dup (0) ; f 6
db 0FEh,'f 07 ',0FFh,068h, 8 dup (0) ; f 7
db 0FEh,'f 08 ',0FFh,069h, 8 dup (0) ; f 8
db 0FEh,'f 09 ',0FFh,06Ah, 8 dup (0) ; f 9
db 0FEh,'f 10 ',0FFh,06Bh, 8 dup (0) ; f10
db 0FEh,'F 01 ',0FFh,082h, 8 dup (0) ; shift f 1
db 0FEh,'F 02 ',0FFh,083h, 8 dup (0) ; shift f 2
db 0FEh,'F 03 ',0FFh,084h, 8 dup (0) ; shift f 3
db 0FEh,'F 04 ',0FFh,085h, 8 dup (0) ; shift f 4
db 0FEh,'F 05 ',0FFh,086h, 8 dup (0) ; shift f 5
db 0FEh,'F 06 ',0FFh,087h, 8 dup (0) ; shift f 6
db 0FEh,'F 07 ',0FFh,088h, 8 dup (0) ; shift f 7
db 0FEh,'F 08 ',0FFh,089h, 8 dup (0) ; shift f 8
db 0FEh,'F 09 ',0FFh,08Ah, 8 dup (0) ; shift f 9
db 0FEh,'F 10 ',0FFh,08Bh, 8 dup (0) ; shift f10
db 0FFh,036h, 4 dup (0) ; ROLL UP
db 0FFh,037h, 4 dup (0) ; ROLL DOWN
db 0FFh,038h, 4 dup (0) ; INS
db 0FFh,039h, 4 dup (0) ; DEL
db 0FFh,03Ah, 4 dup (0) ; up arrow
db 0FFh,03Bh, 4 dup (0) ; left arrow
db 0FFh,03Ch, 4 dup (0) ; right arrow
db 0FFh,03Dh, 4 dup (0) ; down arrow
db 0FFh,03Eh, 4 dup (0) ; HOME CLR
db 0FFh,03Fh, 4 dup (0) ; HELP
db 0FFh,0AEh, 4 dup (0) ; shift HOME CLR
KEYDEF_SIZE = $ - ker_keydef + 2
DOS_keydef db KEYDEF_SIZE dup (?)
;
even
dw 80 DUP (?) ; local stack for interrupt processing
mnstk dw ?
mnsp dw ? ; remote stack info
mnsseg dw ?
baud_set db ?
scrn_page db 0
; mode line buffer
mode_len db 0
db 'Esc-chr: '
mode_esc db '^]'
db ' help: '
mode_hlp db '^]'
db '? port:'
mode_prt db '1'
db ' speed:'
mode_spd db ' '
db ' parity:'
mode_pty db 'none'
db ' echo:'
mode_ech db 'rem'
db ' '
mode_typ db 'VT102 '
db ' '
mode_prn db ' '
MODE_LINE_LENG = $ - mode_len - 1
onmsg db 'off'
db 'on '
colmsg db 'black '
db 'blue '
db 'red '
db 'magenta'
db 'green '
db 'cyan '
db 'yellow '
db 'white '
knjmsg db 'none '
db 'none '
db 'DEC-code '
db 'DEC-code '
db 'shift-JIS'
db 'shift-JIS'
keyinmsg db 'direct'
db 'CON '
vstmsg db '<Terminal status>',cr,lf
db ' Keyclick: '
vstmsg_key db ' '
db ' Keyinput: '
vstmsg_keyin db ' '
db ' Color: '
vstmsg_col db ' '
db ' Highlight: '
vstmsg_high db ' '
db cr,lf,' Kanji-send : '
vstmsg_sknj db ' '
db ' Kanji-receive : '
vstmsg_rknj db ' '
db cr,lf,' AutoTek: '
vstmsg_autot db ' '
db ' Wrap: '
vstmsg_autow db ' '
db '$'
datas ends
code segment public 'code'
extrn comnd:near, dopar:near, prserr:near, atoi:near, prompt:near
extrn isfile:near ;* in mssker
extrn sleep:near, msuinit:near, keybd:near
extrn vt100:near, vt100_ini:near
extrn vt100_save:near, vt100_restore:near, vt100_modlin:near
extrn vt100_dump:near, vt100_color:near
extrn tek4014:near, tek4014_ini:near
extrn tek4014_save:near, tek4014_restore:near, tek4014_modlin:near
assume cs:code,ds:datas
;-----------------
; Utility Package
;-----------------
NOUT PROC NEAR
; Copy numeric value from AX to ASCII buffer indicated by DI.
; DI is updated.
mov dx,0
mov bx,10
div bx
push dx ; save remainder digit
or ax,ax ; anything left?
jz nout1 ; no, start output phase
call nout
nout1: pop ax ; retrieve a digit
add al,'0' ; make it ASCII
stosb ; put it in buffer
ret
NOUT ENDP
;-------------------
is_kanji1 proc near
;
; Check if al is Kanji 1st byte (stc) or not (clc)
;
cmp al,81h
jb is_kanji1_no
cmp al,0FCh
ja is_kanji1_no
cmp al,9fh
jbe is_kanji1_yes
cmp al,0E0h
jae is_kanji1_yes
is_kanji1_no:
clc
ret
is_kanji1_yes:
stc
ret
is_kanji1 endp
;-------------------
jis2s proc near
;
; Convert JIS Kanji code in AX to shift-JIS Kanji code
; ah 2nd byte
; al 1st byte
;
test al,1
jz jis2s1
add ah,1Fh
jmp jis2s2
jis2s1:
add ah,7Dh
jis2s2:
cmp ah,7Fh
jb jis2s3
add ah,1
jis2s3:
sub al,21h
shr al,1
add al,81h
cmp al,9Fh
jbe jis2s4
add al,40h
jis2s4:
ret
jis2s endp
;-------------------
s2jis proc near
;
; Convert Shift JIS Kanji code in AX to JIS Kanji code
; ah 2nd byte
; al 1st byte
;
cmp al,9Fh
ja s2jis1
sub al,71h
jmp s2jis2
s2jis1:
sub al,0B1h
s2jis2:
shl al,1
inc al
cmp ah,7Fh
jbe s2jis3
dec ah
s2jis3:
cmp ah,9Eh
jb s2jis4
sub ah,7Dh
inc al
jmp s2jis5
s2jis4:
sub ah,1Fh
s2jis5:
ret
s2jis endp
set_keydef proc near
; Save MS-DOS key definition table and set new key definition table.
; This is done by calling NEC-PC98 extended bios.
push ax
push cx
push dx
mov dx,offset DOS_keydef
mov ax,0
mov cl,0Ch
int 0DCh
mov dx,offset ker_keydef
mov ax,0
mov cl,0Dh
int 0DCh
pop dx
pop cx
pop ax
ret
set_keydef endp
reset_keydef proc near
; Restore MS-DOS key definition table
push ax
push cx
push dx
mov dx,offset DOS_keydef
mov ax,0
mov cl,0Dh
int 0DCh
pop dx
pop cx
pop ax
ret
reset_keydef endp
SCRN_CHK PROC NEAR
; Check the display screen. If it is not DOS page, save the current page
; and return to DOS page.
cmp scrn_page,1 ; VT100 page ?
jne scrn_chk1 ; ne = no.
call vt100_save
jmp scrn_chkx
scrn_chk1:
cmp scrn_page,2 ; TEK page ?
jne scrn_chk2 ; ne = no.
call tek4014_save
jmp scrn_chkx
scrn_chk2:
jmp scrn_chk_ex
scrn_chkx:
push ax
push dx
mov ah,prstr
mov dx,offset restore_cur
int dos
pop dx
pop ax
scrn_chk_ex:
mov scrn_page,0 ; force to DOS page
ret
SCRN_CHK ENDP
SET_MODLIN PROC NEAR
; set the mode line buffer
;
push es
mov ax,ds
mov es,ax
;
mov al,' '
mov ah,trans.escchr
cmp ah,020h
jge set_modlin1
mov al,'^'
or ah,040h
set_modlin1:
mov word ptr mode_esc,ax
mov word ptr mode_hlp,ax
;
mov al,ourarg.baudb
mov si,offset unkbaud ; Assume unknown baud.
mov cx,5 ; length of baud space
cmp al,BAUDNSIZ ; too big?
jnb set_modlin2 ; yes, use default
mul cl
xor ah,ah
add ax,offset baudname
mov si,ax
set_modlin2:
mov di,offset mode_spd
rep movsb
;
mov al,ourarg.prt
cmp al,'N'
je set_modlin3
add al,'0' ; convert to character
set_modlin3:
mov mode_prt,al
;
mov al,ourarg.parity
xor ah,ah
mov cx,4
imul cl
add ax,offset parityname
mov si,ax
mov di,offset mode_pty
rep movsb
;
mov si,offset lclename
test ourarg.flgs,lclecho
jnz set_modlin4
mov si,offset remename
set_modlin4:
mov cx,3
mov di,offset mode_ech
rep movsb
;
pop es
ret
SET_MODLIN ENDP
ENT_VT PROC NEAR
cmp scrn_page,1 ; VT screen ?
je ent_vt1 ; e = yes. terminal screen. keep going
push ax
push dx
mov ah,prstr
mov dx,offset save_cur
int dos
mov ah,prstr
mov dx,offset home_cur
int dos
pop dx
pop ax
call vt100_restore
mov scrn_page,1
ent_vt1:
mov dx,offset mode_len
call vt100_modlin
ret
ENT_VT ENDP
ENT_TK PROC NEAR
cmp scrn_page,2 ; TEK screen ?
je ent_tk1
push ax
push dx
mov ah,prstr
mov dx,offset save_cur
int dos
mov ah,prstr
mov dx,offset home_cur
int dos
pop dx
pop ax
call tek4014_restore
mov scrn_page,2
ent_tk1:
mov dx,offset mode_len
call tek4014_modlin
ret
ENT_TK ENDP
;---------------------------------------------------------------------------
; this is called by Kermit initialization. It checks the
; number of disks on the system, sets the drives variable
; appropriately. Returns normally.
DODISK PROC NEAR
mov ah,gcurdsk ; Current disk value to AL.
int dos
mov dl,al ; Put current disk in DL.
mov ah,seldsk ; Select current disk.
int dos ; Get number of drives in AL.
mov drives,al
ret
DODISK ENDP
; Clear the input buffer. This throws away all the characters in the
; serial interrupt buffer. This is particularly important when
; talking to servers, since NAKs can accumulate in the buffer.
CLRBUF PROC NEAR
cli
mov srcpnt,offset source ; receive circular buffer
mov count,0
sti
call prtchr ; empty any intermediate buffers
nop ; got a char, clear again
nop
nop
cli
push ax
mov ax,offset source ; reset pointers
mov rcvpnt,ax
mov srcpnt,ax
mov count,0
pop ax
sti
ret
CLRBUF ENDP
; Clear to the end of the current line. Returns normally.
CLEARL PROC NEAR
push ax
push dx
call scrn_chk
mov ah,prstr
mov dx,offset clreol
int dos
pop dx
pop ax
ret
CLEARL ENDP
shomodem proc near
mov ah,cmcfm ; get a confirm
call comnd
jmp r ; no confirm
nop
call serini ; activate port to get status
call serrst ; turn off port again
;
mov dx,mnst1a ; read status
in al,dx
and al,80h ; set only DR bit
mov mdstreg,al
mov dx,mnrdsa ; read signal
in al,dx
and al,60h ; set CS and CD only
or mdstreg,al
;
mov ah,prstr
mov dx,offset msmsg1 ; modem ready msg
test mdstreg,80h ; is DSR asserted?
jz shomd1 ; z = no
mov dx,offset msmsg2 ; say not asserted
shomd1: int dos
mov dx,offset msmsg3 ; CD asserted msg
test mdstreg,20h ; CD asserted?
jz shomd2 ; z = no
mov dx,offset msmsg4 ; say not asserted
shomd2: int dos
mov dx,offset msmsg5 ; CTS asserted msg
test mdstreg,40h ; CTS asserted?
jz shomd3 ; z = no
mov dx,offset msmsg6 ; say not asserted
shomd3: int dos
jmp rskp
shomodem endp
getmodem proc near
mov al,0
ret
getmodem endp
; Put the char in AH to the serial port. This assumes the
; port has been initialized. Should honor xon/xoff. Skip returns on
; success, returns normally if the character cannot be written.
OUTCHR PROC NEAR
push cx ; save regs
cmp flowoff,0 ; Are we doing flow control.
je outch2
xor cx,cx
cmp ah,flowoff ; sending xoff?
jne outch1 ; ne = no
mov xofsnt,false ; supress xon from chkxon buffer routine
outch1: cmp xofrcv,true ; Are we being held?
jne outch2 ; No - it's OK to go on.
loop outch1 ; held, try for a while
mov xofrcv,false ; timed out, force it off and fall thru.
outch2: push dx ; Save register.
xor cx,cx
mov al,ah ; Parity routine works on AL.
call dopar ; Set parity appropriately.
; Begin revised output routine
mov ah,al
mov temp,ax ; put data there
cmp ourarg.prt,'N' ; Network port ?
jne outch6 ; ne = No.
pop dx
pop cx
jmp outchn
outch6:
mov dx,modem.mdstat
outch3: in al,dx
test al,txrdy
jnz outch4
loop outch3
jmp outch5
outch4: mov al,ah
mov dx,modem.mddat
out dx,al
outch5: pop dx
pop cx
jmp rskp
;
outchn:
push bx
mov bx,offset xmtbuf ; set xfer address
add bx,xmtcnt ; count of chars in buffer
mov [bx],ah ; put char in buffer
pop bx
inc xmtcnt ; count of items in this buffer
cmp xmtcnt,NETBUFLEN ; is buffer full now?
jae outchn1 ; ae = buffer is full, send it now.
cmp ah,trans.seol ; end of packet?
je outchn1 ; e = yes, send buffer.
cmp ah,flowon ; flow control?
je outchn1 ; e = yes, always expedite
cmp ah,flowoff ; ditto for flow off
je outchn1
cmp ttyact,0 ; are we in Connect mode?
je outchn2 ; e = no, wait for more before sending
outchn1:
call send ; network send routine
jc outchn3 ; c = error
outchn2:
jmp rskp ; good exit
outchn3:
ret ; bad exit
OUTCHR ENDP
SEND PROC NEAR
push ax
push bx
push cx
push es
;
push ds
pop es ; ES = DS
mov bx,offset xmtbuf ; xfer start address
mov ah,NETCI_WRITE ; set function
mov al,NETCI_PORT ; set port
;
send0:
mov cx,xmtcnt ; packet length
jcxz send1
int NETCI_INT ; send packet
cmp cx,xmtcnt ; all done ?
jae send1 ; e = yes.
pop ax
mov bx,offset xmtbuf
add bx,cx ; update xfer address
sub xmtcnt,cx
jmp send0
;
send1:
mov xmtcnt,0
pop es
pop cx
pop bx
pop ax
clc
ret
SEND ENDP
; This routine blanks the screen. Returns normally.
CMBLNK PROC NEAR
push ax ; save some registers
push dx
call scrn_chk
mov ah,prstr
mov dx,offset delscr ; delete screen.
int dos
pop dx
pop ax
ret
CMBLNK ENDP
; Homes the cursor. Returns normally.
LOCATE PROC NEAR
call scrn_chk
mov dx,0 ; Go to top left corner of screen.
jmp poscur
LOCATE ENDP
; Write a line at the bottom of the screen...
; the line is passed in dx, terminated by a $. Returns normally.
putmod proc near
call scrn_chk
push dx ; preserve message
mov dx,1800h ; now address line 24
call poscur
pop dx ; get message back
mov ah,prstr
int dos ; write it out
ret ; and return
putmod endp
; clear the mode line written by putmod. Returns normally.
clrmod proc near
call scrn_chk
mov dx,1800h
call poscur ; Go to bottom row.
call clearl ; Clear to end of line.
ret
clrmod endp
; Put a help message on the screen.
; Pass the message in ax, terminated by a null. Returns normally.
puthlp proc near
push dx ; save regs
push si
push ax ; preserve this
call scrn_chk
call cmblnk
call locate
mov ah,prstr
mov dx,offset crlf
int dos
pop si ; point to string again
cld
puthl3: lodsb ; get a byte
cmp al,0 ; end of string?
je puthl4 ; yes, stop
mov dl,al
mov ah,dconio
int dos ; else write to screen
jmp puthl3 ; and keep going
puthl4: mov ah,prstr
mov dx,offset crlf
int dos
pop si
pop dx
ret
puthlp endp
; Set the baud rate for the current port, based on the value
; in the portinfo structure. Returns normally.
DOBAUD PROC NEAR
push ax
push bx
push dx
;
mov axsave,ax
mov bx,portval
mov ax,[bx].baud
shl ax,1
;
; determine CPU clock
;
push ax
in al,042h
test al,0C0h
jz c5mhz
test al,020h
jz c5mhz
c8mhz:
mov bx,offset bddat8
jmp dobd0
c5mhz:
mov bx,offset bddat5
dobd0:
pop ax
add bx,ax
cmp word ptr [bx],0FFFFh
jne dobd1
mov ah,prstr
mov dx,offset badbd
int dos
jmp dobd_ex
dobd1:
mov dx,timer.tmcmd
mov al,timer.tmsel
out dx,al
mov ax,[bx]
mov dx,timer.tmdat
out dx,al
mov al,ah
out dx,al
dobd_ex:
pop dx
pop bx
pop ax
ret ; Must be set before starting Kermit.
DOBAUD ENDP
; Get the current baud rate from the serial card and set it
; in the portinfo structure for the current port. Returns normally.
; This is used during initialization.
GETBAUD PROC NEAR
cmp flags.comflg,'N' ; Network ?
je gbaud1 ; e = yes. do nothing here.
push bx
cmp baud_set,1 ; Did we already set baud rate?
je gbaud0 ; yes, so just leave
mov bx,portval
mov [bx].baud,B9600
mov baud_set,1
gbaud0:
pop bx
gbaud1:
ret
GETBAUD ENDP
; Set the mode for the current port. This is part of the serial
; initialization routine.
DOMODE PROC NEAR
push ax
push cx
push dx
;
mov dx,modem.mdcom ;send 3 zeros to command port to reset chip
mov al,0
out dx,al
mov al,0
out dx,al
mov al,0
out dx,al
mov al,cmode ;enable mode setting
out dx,al
mov cx,100 ;allow chip time to reset
mode1: loop mode1
mov al,mmode ;mode: 16x rate, 8 data, no parity, 1 stop
out dx,al
mov cx,100
mode2: loop mode2
mov al,ccmd ;RTS & DTR high, RX & TX enabled, reset errors
out dx,al
;
pop dx
pop cx
pop ax
ret
DOMODE ENDP
; Use for DOS 2.0 and above. Check the port status. If no data, skip
; return. Else, read in a char and return.
; Note added by [jrd]: The test for char-at-input-port is int 21h function
; 44h (ioctl) sub function 6 (get input status). On many systems an FFH will
; be reported (meaning Ready) even though no char is available; the Ready
; indication is misleading. In such cases the system will wait for a char
; and will appear to be hung. A preferrable method is to use the ROM Bios
; call int 14H function 3 (get port status) and if the lsb of the returned
; 8 bits in AH is 1 then a char is availble at the port; this assumes that
; the machine emulates this ROM Bios operation.
; Lastly, if the current code is used and the system hangs then reboot
; and say ECHO Hello >COM1 before running Kermit; this should make MSDOS
; truely aware of the port's actual status. Dark grey magic. Good luck! [jrd]
PRTCHR PROC NEAR
prtch0:
call chkxon
cmp ourarg.prt,'N'
jne prtch3
jmp prtchn
prtch3:
cmp count,0
jnz prtch2
jmp rskp ; No data -check console
prtch2:
pushf
cli ; disable interrupts while manipulating pointers
mov si,rcvpnt
lodsb ; get a byte
cmp si,offset source + bufsiz ; bigger than buffer?
jb prtch1 ; no, keep going
mov si,offset source ; yes wrap around
prtch1:
dec count
mov rcvpnt,si
mov dx,count
popf
ret
prtchn:
cmp count,0 ; Data in buffer?
je prtchn0 ; e = No. Get them from port.
jmp prtchn2
prtchn0:
push ax
push bx
push cx
push es
mov ax,offset source
mov rcvpnt,ax
mov srcpnt,ax
;
mov ah,NETCI_READ
mov al,NETCI_PORT
mov bx,offset source
mov cx,bufsiz
push ds
pop es
int NETCI_INT
mov count,cx
add srcpnt,cx
pop es
pop cx
pop bx
pop ax
cmp count,0
jnz prtchn2
jmp rskp
prtchn2:
pushf
cli ; disable interrupts while manipulating pointers
mov si,rcvpnt
lodsb ; get a byte
dec count
mov rcvpnt,si
;
; I'm not sure the floowings are necesary or not.
; The handshake should be done at network level.
;
; check the data
;
;@@ push bx
;@@ or al,al
;@@ jz prtchn5 ; Ignore nulls.
;@@ mov ah,al ; copy the character in AH
;@@ and ah,parmsk ; apply parity mask
;@@ mov bx,portval
;@@ cmp [bx].floflg,0 ; Doing flow control?
;@@ je prtchn4 ; Nope.
;@@ mov bx,[bx].flowc ; Flow control character (BH=XON, BL=XOFF).
;@@ cmp ah,bl ; Is it an XOFF?
;@@ jne prtchn3 ; Nope, go on.
;@@ mov xofrcv,true ; Set the flag.
;@@ jmp short prtchn5
prtchn3:
;@@ cmp ah,bh ; Get an XON?
;@@ jne prtchn4 ; No, go on.
;@@ mov xofrcv,false ; Clear our flag.
;@@ jmp short prtchn5
;
prtchn4:
;@@ pop bx
mov dx,count
popf
ret
prtchn5:
;@@ pop bx
;@@ popf
;@@ jmp prtchn
PRTCHR ENDP
; Local routine to see if we have to transmit an xon
chkxon proc near
push bx
mov bx,portval
cmp [bx].floflg,0 ; doing flow control?
je chkxo1 ; no, skip all this
cmp xofsnt,false ; have we sent an xoff?
je chkxo1 ; no, forget it
cmp count,mntrgh ; below trigger?
jae chkxo1 ; no, forget it
mov ax,[bx].flowc ; ah gets xon
call outchr ; send it
nop
nop
nop ; in case it skips
mov xofsnt,false ; remember we've sent the xon.
chkxo1: pop bx ; restore register
ret ; and return
chkxon endp
; IHOSTS - Initialize the host by sending XON, or equivalent, and enter the
; cycle of clear input buffer, wait 1 second, test if buffer empty then exit
; else repeat cycle. Requires that the port be initialized before hand.
; Ihosts is used by the local send-file routine just after initializing
; the serial port.
; 22 March 1986 [jrd]
IHOSTS PROC NEAR
push ax ; save the registers
push bx
push cx
push dx
mov bx,portval ; port indicator
mov ax,[bx].flowc ; put Go-ahead flow control char in ah
or ah,ah ; don't send null if flow = none
jz ihosts1 ; z = null
call outchr ; send it (release Host's output queue)
nop ; outchr can do skip return
nop
nop
ihosts1:call clrbuf ; clear out interrupt buffer
mov ax,1 ; sleep for 1 second
; NOTE: for systems with a time-of-day clock uncomment the line below
; (call sleep) to provide an interval for the host to respond.
;;; call sleep ; procedure sleep is in msscom.asm
call prtchr ; check for char at port
jmp ihosts1 ; have a char in al, repeat wait/read cycle
nop ; prtchr does skip return on empty buffer
pop dx ; empty buffer. we are done here.
pop cx
pop bx
pop ax
ret
IHOSTS ENDP
; IHOSTR - initialize the remote host for our reception of a file by
; sending the flow-on character (XON typically) to release any held
; data. Called by receive-file code just after initializing the serial
; port. 22 March 1986 [jrd]
IHOSTR PROC NEAR
push ax ; save regs
push bx
push cx
mov bx,portval ; port indicator
mov ax,[bx].flowc ; put Go-ahead flow control char in ah
or ah,ah ; don't send null if flow = null
jz ihostr1 ; z = null
call outchr ; send it (release Host's output queue)
nop ; outchr can do skip return
nop
nop
ihostr1:pop cx
pop bx
pop ax
ret
IHOSTR ENDP
DTRLOW PROC NEAR ; Global proc to Hangup the Phone by making
; DTR and RTS low.
mov ah,cmtxt ; allow text to be able to display help
mov bx,offset rdbuf ; dummy buffer
mov dx,offset hnghlp ; help message
call comnd ; get a confirm
jmp r
; not yet imp. call serhng ; drop DTR and RTS
mov ah,prstr ; give a nice message
; not yet imp. mov dx,offset hngmsg
mov dx,offset noimp ; for now
int dos
jmp rskp
DTRLOW ENDP
; Hang up the Phone. Similar to SERRST except it just forces DTR and RTS low
; to terminate the connection. 29 March 1986 [jrd]
; Calling this twice without intervening calls to serini should be harmless.
; Returns normally.
; SERHNG is Not Yet Implemented.
SERHNG PROC NEAR
ret
SERHNG ENDP
; Wait for the # of milliseconds in ax, for non-IBM compatibles.
; Based on 4.77 Mhz 8088 processor speeds.
; Thanks to Bernie Eiben for this one.
pcwait proc near
mov cx,240 ; inner loop counter for 1 millisecond
pcwai1: sub cx,1 ; inner loop takes 20 clock cycles
jnz pcwai1
dec ax ; outer loop counter
jnz pcwait ; wait another millisecond
ret
pcwait endp
; Send a break out the current serial port. Returns normally.
SENDBR PROC NEAR ; Normal Break
mov dx,modem.mdcom ; set command port
mov al,cbrk+ccmd ; add break to normal command
out dx,al
sub cx,cx ; counter 0 = 65536
sndbr1: loop sndbr1 ; wait a while
mov al,ccmd ; restore normal command
out dx,al
ret
SENDBR ENDP
SENDBL PROC NEAR ; Long Break
mov dx,modem.mdcom ; set command port
mov al,cbrk+ccmd ; add break to normal command
out dx,al
push dx ; save I/O address
call pcwait
mov al,ccmd
pop dx ; restore I/O address
out dx,al ; restore normal command
ret
SENDBL ENDP
; Position the cursor according to contents of DX:
; DH contains row, DL contains column. Returns normally.
POSCUR PROC NEAR
push di
mov di,offset tmpbuf
mov byte ptr [di],ESCAPE
mov byte ptr [di+1],'['
add di,2
mov al,dh
xor ah,ah
inc ax
push dx
call nout
mov byte ptr [di],';'
inc di
pop dx
mov al,dl
xor ah,ah
inc ax
call nout
mov byte ptr [di],'H'
mov byte ptr [di+1],'$'
mov dx,offset tmpbuf
mov ah,prstr
int dos
pop di
ret
POSCUR ENDP
; Delete a character from the terminal. This works by printing
; backspaces and spaces. Returns normally.
DODEL PROC NEAR
mov ah,prstr
mov dx,offset delstr ; Erase weird character.
int dos
ret
DODEL ENDP
; Move the cursor to the left margin, then clear to end of line.
; Returns normally.
CTLU PROC NEAR
mov ah,prstr
mov dx,offset clrlin
int dos
call clearl
ret
CTLU ENDP
; Called only when Kermit exits. Program pointer passed to mssker by
; proc chknet in word 'lclexit'.
; This is used as a local end routine.
NETCLOSE PROC NEAR
cmp pcnet,0 ; already closed ?
je netclo1 ; e = yes
push ax
mov ah,NETCI_CLOSE
mov al,NETCI_PORT
int NETCI_INT
mov pcnet,0
pop ax
netclo1:
call reset_keydef ; reset key definition table
ret
NETCLOSE ENDP
; Open NETCI port
chknet proc near
cmp pcnet,0 ; netport is closed ?
jne chknetx
push ax
push bx
push cx
push es
;
push cs
pop es
mov temp,0
mov bx,offset temp
mov cx,0
mov ah,NETCI_OPEN
mov al,NETCI_PORT
int NETCI_INT
mov lclexit,offset netclose
call clrbuf
mov xmtcnt,0
mov pcnet,2
;
pop es
pop cx
pop bx
pop ax
chknetx:
clc
ret
chknet endp
;
; Set the current port.
;
COMS PROC NEAR
mov dx,offset comptab ; the table to examine
mov bx,0 ; use keywords as help
mov ah,cmkey ; parse keyword from comptab
call comnd
jmp r ; no match
cmp bl,'N' ; Network ?
jne coms1 ; ne = no
jmp comsn ; Yes, setup for networks
coms1:
mov temp,bx
mov ah,cmcfm
call comnd ; Get a confirm.
jmp r ; Didn't get a confirm.
mov bx,temp ; get port number/letter
mov flags.comflg,bl ; remember port number
xor bh,bh ; clear high byte
mov bl,flags.comflg ; get COMx number (1-3)
push bx
pop bx
mov ax,offset port1
mov portval,ax
call inita
clc
ret
comsn:
mov temp,bx
mov ah,cmcfm
call comnd ; Get a confirm
jmp r ; Didn't get a confirm
nop
call serrst ; reset serial port
call chknet ; start network usage
cmp pcnet,0 ; is network alive (non-zero)?
jne comsn4 ; ne = yes
stc
ret ; return failure
comsn4:
mov portval,offset portn ; set netowrk port data
mov flags.comflg,'N' ; set the comm port flag.
clc ; return sucess
ret
COMS ENDP
; Set heath emulation on/off.
VTS PROC NEAR
mov ah,cmkey ; Parse another keyword.
mov bx,offset vthlp ; Use this help
mov dx,offset vttbl ; Use this table
call comnd
jmp r ; Vsetup always returns +1.
cmp bh,1h ; marker for terminal type?
jne vsetup_n1 ; ne = no
jmp vsetup_1
vsetup_n1:
cmp bh,2h ; marker for set term something on/off?
jne vsetup_n2 ; ne = no
jmp vsetup_2
vsetup_n2:
cmp bh,3h ; marker for color
jne vsetup_n3 ; ne = no
jmp vsetup_3
vsetup_n3:
cmp bh,4h ; marker for kanji
jne vsetup_n4 ; ne = no
jmp vsetup_4
vsetup_n4:
cmp bh,5
jne vsetup_n5
jmp vsetup_5
vsetup_n5:
jmp vsetup_ex
;
vsetup_1:
push bx
mov ah,cmcfm
call comnd
jmp vsetup_ex2
nop
pop bx
mov flags.vtflg,bl ; Set the terminal emulation type
ret
vsetup_2:
xor bh,bh
mov param_dst,bx
mov ah,cmkey
mov bx,0
mov dx,offset ontab
call comnd
jmp r ; bad keyword
push bx
mov ah,cmcfm ; get a confirm
call comnd
jmp vsetup_ex2 ; did not get a confirm
nop
mov ax,param_dst
pop bx
cmp bl,0
jne vsetup_2_1
not al
and vt100_flags,al
jmp vsetup_2_2
vsetup_2_1:
or vt100_flags,al
vsetup_2_2:
jmp rskp
vsetup_3:
mov dx,offset scn_color
xor bh,bh
add dx,bx
mov param_dst,dx
mov ah,cmkey
mov bx,0
mov dx,offset colortab
call comnd
jmp r ; bad keyword
push bx
mov ah,cmcfm ; get a confirm
call comnd
jmp vsetup_ex2 ; did not get a confirm
nop
pop dx ; get old bx value to dx
mov bx,param_dst
mov byte ptr [bx],dl
mov ax,scn_color
call vt100_color
jmp rskp
vsetup_4:
mov ah,cmkey
mov bx,0
mov dx,offset kanjitab
call comnd
jmp r ; bad keyword
push bx
mov ah,cmcfm ; get a confirm
call comnd
jmp vsetup_ex2 ; did not get a confirm
nop
pop bx ; get old bx value to dx
mov kanji_scode,bl
mov kanji_rcode,bl
jmp rskp
vsetup_5:
mov ah,cmkey
mov bx,0
mov dx,offset keyintab
call comnd
jmp r
push bx
mov ah,cmcfm
call comnd
jmp vsetup_ex2
nop
pop bx
mov keyin_dos,bl
jmp rskp
vsetup_ex:
jmp rskp
vsetup_ex2:
pop bx
ret
VTS ENDP
VTSTAT PROC NEAR ; For Status display [jrd]
push ax
push bx
push cx
push dx
push si
push di
push es
;
push ds
pop es
cld
mov si,offset onmsg
mov cx,3
test vt100_flags,KEYCLICK_BIT
jz vtstat1
add si,cx
vtstat1:
mov di,offset vstmsg_key
rep movsb
mov si,offset onmsg
mov cx,3
test vt100_flags,AUTOTEK_BIT
jz vtstat2
add si,cx
vtstat2:
mov di,offset vstmsg_autot
rep movsb
mov si,offset onmsg
mov cx,3
test vt100_flags,AUTOWRAP_BIT
jz vtstat3
add si,cx
vtstat3:
mov di,offset vstmsg_autow
rep movsb
mov si,offset colmsg
mov ax,scn_color
mov ah,0
mov cx,7
imul cl
add si,ax
mov di,offset vstmsg_col
rep movsb
mov si,offset colmsg
mov ax,scn_color
xchg ah,al
mov ah,0
mov cx,7
imul cl
add si,ax
mov di,offset vstmsg_high
rep movsb
mov si,offset knjmsg
mov ah,0
mov al,kanji_scode
mov cx,9
imul cl
add si,ax
mov di,offset vstmsg_sknj
rep movsb
mov si,offset knjmsg
mov ah,0
mov al,kanji_rcode
mov cx,9
imul cl
add si,ax
mov di,offset vstmsg_rknj
rep movsb
mov si,offset keyinmsg
mov cx,6
cmp keyin_dos,0
je vtstat9
add si,cx
vtstat9:
mov di,offset vstmsg_keyin
rep movsb
mov ah,prstr
mov dx,offset vstmsg
int dos
;
pop es
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret ; no emulator status to display
VTSTAT ENDP
; Save the screen to a buffer and then append buffer to a disk file. [jrd]
; Default filename is Kermit.scn; actual file can be a device too. Filename
; is determined by mssset and is passed as pointer dmpname.
DUMPSCR PROC NEAR ; Dumps screen contents to a file. Just Beeps here
push ax
push bx
push cx
push dx
mov dmphand,-1 ; preset illegal handle
mov dx,offset dmpname ; name of disk file, from mssset
mov ax,dx ; where isfile wants name ptr
call isfile ; what kind of file is this?
jc dmp5 ; c = no such file, create it
test byte ptr filtst.dta+21,1fh ; file attributes, ok to write?
jnz dmp0 ; nz = no.
mov al,1 ; writing
mov ah,open2 ; open existing file
int dos
jc dmp0 ; c = failure
mov dmphand,ax ; save file handle
mov bx,ax ; need handle here
mov cx,0ffffh ; setup file pointer
mov dx,-1 ; and offset
mov al,2 ; move to eof minus one byte
mov ah,lseek ; seek the end
int dos
jmp dmp1
dmp5: test filtst.fstat,80h ; access problem?
jnz dmp0 ; nz = yes
mov ah,creat2 ; file did not exist
mov cx,20h ; attributes, archive bit
int dos
mov dmphand,ax ; save file handle
jnc dmp1 ; nc = ok
dmp0: call beep
pop dx
pop cx
pop bx
pop ax
clc
ret
dmp1: mov ah,ioctl ; is destination ready for output?
mov al,7 ; test output status
mov bx,dmphand ; handle
int dos
jc dmp0 ; c = error
cmp al,0ffh ; ready?
jne dmp0 ; ne = not ready.
;
test flags.vtflg,ttvt100
jz dmp_v1
call ent_vt
dmp_v1:
mov bx,dmphand ; need file handle
call vt100_dump
;
mov bx,offset tmpbuf
mov byte ptr [bx],CTLZ ; put EOF mark
mov dx,bx
mov bx,dmphand
mov cx,1
mov ah,write2
int dos ; write EOF
;
mov ah,close2 ; close the file now
int dos
;
pop dx
pop cx
pop bx
pop ax
clc
ret
DUMPSCR ENDP
notimp: mov ah,prstr
mov dx,offset noimp
int dos
jmp prserr
; Initialize variables to values used by this routine.
lclini: mov prthnd,0 ; No handle yet
mov flags.comflg,1 ; Communication port 1
mov scrn_page,0 ; start page is DOS screen
mov curkey_mode,0 ; cursor key is ANSI normal
mov keypad_mode,0 ; keypad is normal
mov vt100_flags,AUTOTEK_BIT+CURSOR_BIT+BLINK_BIT ; set flags
mov kanji_scode,2 ; DEC kanji code
mov kanji_rcode,2
mov kanji_smode,0 ; 1st character must be Kanji 1st byte.
mov kanji_rmode,0
mov xmtcnt,0 ; clear counter for xfer
or flags.remflg,d8bit ; display 8-bit
call set_keydef
mov lclexit,offset netclose
call msuinit ; declare keyboard translator present
call vt100_ini
call tek4014_ini
ret
showkey:
mov ax,offset shkmsg
mov cx,shklen
ret
; serial port interrupt routine. This is not accessible outside this
; module, handles serial port receiver interrupts.
SERINT PROC NEAR
push ds ; save these on remote stack
push ax
mov ax,seg datas ; get our own data segment
mov ds,ax
mov mnsp,sp ; save remote stack information
mov mnsseg,ss
mov sp,offset mnstk ; switch to local stack
mov ss,ax
push es ; and save remaining registers
push bp
push di
push si
push dx
push cx
push bx
mov es,ax
call mnproc ; process the interrupt
mov al,icEOI
mov dx,intcmda
out dx,al
pop bx ; restore registers from stack
pop cx
pop dx
pop si
pop di
pop bp
pop es
mov ax,mnsseg ; switch back to remote stack
mov ss,ax
mov ax,mnsp
mov sp,ax
pop ax
pop ds
iret
; handler for serial input
mnproc: cld
mov di,srcpnt ; get buffer pointer
mov dx,modem.mdstat ; is data available?
in al,dx
test al,rxrdy
jz mnpro7
mov dx,modem.mddat ; read data
in al,dx
or al,al
jz mnpro7 ; Ignore nulls.
; do NOT ignore rubouts, because TEK LOY code use this.
; cmp al,7FH ; Ignore rubouts, too.
; jz mnpro7
mov ah,al
;
; originally the following was
;
; and ah,7fH ; only consider low-order 7 bits for flow ctl.
; do NOT mask 8-th bit for flow control when parity is none.
;
and ah,parmsk ; apply parity mask for flow ctl.
mov bp,portval
cmp ds:[bp].floflg,0 ; Doing flow control?
je mnpro4 ; Nope.
mov bx,ds:[bp].flowc ; Flow control char (BH = XON, BL = XOFF).
cmp ah,bl ; Is it an XOFF?
jne mnpro3 ; Nope, go on.
mov xofrcv,true ; Set the flag.
jmp short mnpro7
mnpro3: cmp ah,bh ; Get an XON?
jne mnpro4 ; No, go on.
mov xofrcv,false ; Clear our flag.
jmp mnpro7
mnpro4: stosb
cmp di,offset source + bufsiz
jb mnpro5 ; not past end...
mov di,offset source ; wrap buffer around
mnpro5: mov srcpnt,di ; update ptr
inc count
cmp ds:[bp].floflg,0 ; Doing flow control?
je mnpro7 ; No, just leave.
cmp xofsnt,true ; Have we sent an XOFF?
je mnpro7 ; Yes.
cmp count,mntrgh ; Past the high trigger point?
jbe mnpro7 ; No, we're within our limit.
mov ah,bl ; Get the XOFF.
call outchr ; Send it.
nop ; ignore failure.
nop
nop
mov xofsnt,true ; Remember we sent it.
mnpro7: ret
SERINT ENDP
; Initialization for using serial port. Returns normally.
SERINI PROC NEAR
cmp flags.comflg,'N' ;@@@@@
je serin1 ;@@@@@
call inita
serin0:;;;; call clrbuf ; Clear input buffer.
;; push bx
;; mov bx,portval ; get port
;; mov parmsk,0ffh ; parity mask, assume parity is None
;; cmp [bx].parflg,parnon ; is it None?
;; je serin1 ; e = yes
;; mov parmsk,07fh ; no, pass lower 7 bits as data
;;serin1: mov bx,[bx].flowc ; get flow control chars
;; mov flowoff,bl ; xoff or null
;; mov flowon,bh ; xon or null
;; pop bx
serin1:
ret ; We're done.
SERINI ENDP
; Reset the serial port. This is the opposite of serini. Calling
; this twice without intervening calls to serini should be harmless.
; Returns normally.
SERRST PROC NEAR
call scrn_chk
cmp portinia,0 ; Did we reset port already?
je rsta0 ; Yes, so just leave.
push es
cli ; Disable interrupts
xor ax,ax ; Address low memory
mov es,ax
mov ax,oldsera_ofs ; Restore interrupt vector
mov es:[4*icsvcta],ax
mov ax,oldsera_sgm
mov es:[4*icsvcta+2],ax
mov dx,intmska ; restore old master controller mask
mov al,oldmska
out dx,al
mov dx,mnmska ; disable serial interrupts at port
; mov al,txmsk+rxmsk+tbemsk
mov al,oldmsdat
out dx,al
mov portinia,0 ; Remember port has been reset
sti ; Allow interrupts
pop es
rsta0: ret
SERRST ENDP
; Local routine to initialize the standard serial port
INITA PROC NEAR
cmp portinia,1 ; Did we initialize port already ?
je inita0 ; Yes, so just leave.
;
cli ; Disable interrupts
push ax
push dx
push es
;
mov ax,offset port1
mov portval,ax
xor ax,ax
mov es,ax
mov ax,es:[4*icsvcta] ; save interrupt vector for port1
mov oldsera_ofs,ax
mov ax,es:[4*icsvcta+2]
mov oldsera_sgm,ax
mov ax,offset serint ; pointer to our routine
mov es:[4*icsvcta],ax ; set interrupt routine offset
mov es:[4*icsvcta+2],cs ; and segment
mov dx,intmska
in al,dx
mov oldmska,al ; save old master controller mask
;
and al,not icsmska ; enable serial interrupt at master
out dx,al
mov dx,mnmska
in al,dx
mov oldmsdat,al
and al,0f8h
or al,rxmsk
out dx,al
mov modem.mddat,mndata
mov modem.mdstat,mnst1a
mov modem.mdcom,mncmda
mov timer.tmdat,tmdata
mov timer.tmcmd,tmcmda
mov timer.tmsel,tmsela
call domode
call dobaud
mov portinia,1
call clrbuf
;
pop es
pop dx
pop ax
sti
inita0: ret
INITA ENDP
;
; Produce a short beep. The PC DOS bell is long enough to cause a loss
; of data at the port. Returns normally.
BEEP PROC NEAR
mov dl,bell
mov ah,dconio
int dos
ret
BEEP ENDP
;
; Dumb terminal emulator. Doesn't work too well above 1200 baud (and
; even at 1200 baud you sometimes lose the first one or two characters
; on a line). Does capture (logging), local echo, debug display, tests
; for printer/logging device not ready. Uses keyboard translator
; 20 March 1987 [jrd].
term proc near
mov kanji_smode,0 ; clear Kanji pending flag
mov kanji_rmode,0
mov argadr,ax ; save argument ptr
mov si,ax ; this is source
mov di,offset ourarg ; place to store arguments
mov ax,ds
mov es,ax ; address destination segment
mov cx,size termarg
cld
rep movsb ; copy into our arg blk
and ourarg.flgs,not (prtscr) ; no screen printing at startup
mov ax,ourarg.captr
mov captrtn,ax ; buffer capture routine
mov mode_len,0
mov ax,1001h
test vt100_flags,BLINK_BIT
jz term_01
mov ax,1000h
term_01:
int bios
test vt100_flags,CURSOR_BIT
jz term_02
mov ax,1100h
int bios
term_02:
test ourarg.flgs,modoff ; mode line off?
jnz term_1
call set_modlin ; setup mode line
mov mode_len,MODE_LINE_LENG
term_1:
mov parmsk,0ffh ; parity mask, assume parity = None
cmp ourarg.parity,parnon ; is parity None?
je term_2 ; e = yes, keep all 8 bits
mov parmsk,07fh ; else keep lower 7 bits
term_2:
cmp flags.vtflg,ttvt100 ; vt100 emulation ?
je term_vt ; e = yes.
cmp flags.vtflg,tttek ; Tek4014 emulation ?
je term_tk ; e = yes.
jmp term0 ; non supported terminal
;
; vt100 emulation
term_vt:
call ent_vt
jmp term0
;
; tek4014 emulation
term_tk:
call ent_tk
;
term0:
test vt100_flags,LOOPTEST_BIT
je term1
jmp term_tst1
term1: call portchr ; get char from port, apply parity mask
jnc short term2 ; nc = no char, go on
call outtty ; display and capture char
jmp term1 ; do quick loop back for more
term2: call keybd ; keyboard translator to read and send text
jnc term1 ; nc = do not exit Connect mode
ret
term_tst1:
mov ax,3D00h ; open file (read only)
mov dx,offset test_fnam
int dos
jc term_tstz ; if error, then normal operation
mov test_hndl,ax
term_tst2:
call portchr
jnc short term_tst3
call outtty
jmp term_tst2
term_tst3:
mov ah,3Fh ; read file/device
mov dx,offset tmpbuf
mov bx,test_hndl
mov cx,8
int dos
jc term_tstx
mov cx,ax
jcxz term_tstx
mov si,offset tmpbuf
term_tst4:
push cx
push si
mov ah,[si]
call outchr
nop
nop
nop
pop si
pop cx
inc si
loop term_tst4
jmp term_tst2
term_tstx:
mov ah,3Eh
mov bx,test_hndl
int dos
term_tstz:
and vt100_flags,NOT LOOPTEST_BIT
clc
jmp term1
term endp
;; keyboard translator action routines, system dependent, called from msugen.
; These are invoked by a jump instruction. Return carry clear for normal
; processing, return carry set exit Connect mode (kbdflg has transfer char).
; chrout is called from KEYBD after key definition translation.
; the character is in AL.
chrout:
cmp kanji_scode,0 ; if kanji is not used, no translation
je chroutx
test kanji_scode,4 ; if shift-JIS is used, no translation
jnz chroutx
cmp kanji_smode,0 ; 1st byte ?
je chrout_1 ; e = yes,
jmp chrout_knj2
chrout_1:
call is_kanji1 ; Kanji code 1st byte ?
jnc chroutx ; nc = no. ASCII character
mov kanjis1,al
mov kanji_smode,1
jmp chroutxx
chroutx:
call outprt ; put char in al to serial port
mov kanji_smode,0
chroutxx:
clc ; stay in Connect mode
ret
chrout_knj2:
mov ah,al
mov al,kanjis1
call s2jis
or ax,8080h ; convert to DEC code
mov kanjis1,ah
mov ah,0
call outprt
mov al,kanjis1
jmp chroutx
trnprs: push ax ; toggle Copy screen to printer
test ourarg.flgs,prtscr ; are we currently printing?
jnz trnpr2 ; nz = yes, its on and going off
mov ah,ioctl
mov al,7 ; get output status of printer
push bx
mov bx,4 ; file handle for system printer
int dos
pop bx
jc trnpr1 ; c = printer not ready
cmp al,0ffh ; Ready status?
je trnpr2 ; e = Ready
trnpr1: call beep ; Not Ready, complain
jmp trnpr3 ; and ignore request
trnpr2: xor ourarg.flgs,prtscr ; flip the flag
trnpr3: pop ax
clc
ret
klogon proc near ; resume logging (if any)
test flags.capflg,logses ; session logging enabled?
jz klogn ; z = no, forget it
or ourarg.flgs,capt ; turn on capture flag
klogn: clc
ret
klogon endp
klogof proc near ; suspend logging (if any)
and argadr.flgs,not capt ; stop capturing
klogo: clc
ret
klogof endp
uparrw: mov al,'A'
jmp short comarr
dnarrw: mov al,'B'
jmp short comarr
rtarrw: mov al,'C'
jmp short comarr
lfarrw: mov al,'D'
comarr: push ax
mov ah,ESCAPE
call outchr
nop
nop
nop
mov ah,'['
cmp curkey_mode,0
je comar1
mov ah,'O'
comar1: call outchr
nop
nop
nop
pop ax
mov ah,al
call outchr
nop
nop
nop
clc
ret
pf1: mov al,'P'
jmp short compf
pf2: mov al,'Q'
jmp short compf
pf3: mov al,'R'
jmp short compf
pf4: mov al,'S'
compf: push ax
mov ah,ESCAPE
call outchr
nop
nop
nop
mov ah,'O'
call outchr
nop
nop
nop
pop ax
mov ah,al
call outchr
nop
nop
nop
clc
ret
kp0: mov al,'p'
jmp short comkp
kp1: mov al,'q'
jmp short comkp
kp2: mov al,'r'
jmp short comkp
kp3: mov al,'s'
jmp short comkp
kp4: mov al,'t'
jmp short comkp
kp5: mov al,'u'
jmp short comkp
kp6: mov al,'v'
jmp short comkp
kp7: mov al,'w'
jmp short comkp
kp8: mov al,'x'
jmp short comkp
kp9: mov al,'y'
jmp short comkp
kpmins: mov al,'m'
jmp short comkp
kpcoma: mov al,'l'
jmp short comkp
kpentr: mov al,'M'
jmp short comkp
kpdot: mov al,'n'
jmp short comkp
comkp: cmp keypad_mode,0
je comkp1
push ax
mov ah,ESCAPE
call outchr
nop
nop
nop
mov ah,'O'
call outchr
nop
nop
nop
pop ax
jmp short comkp2
comkp1: sub al,40h
comkp2: mov ah,al
call outchr
nop
nop
nop
clc
ret
snull: mov ah,0 ; send a null
call outchr ; send without echo or logging
nop
nop
nop
clc
ret
keyinchg:
xor keyin_dos,1
clc
ret
kdos: mov al,'P' ; Push to DOS
jmp short cmdcom
cstatus:mov al,'S' ; these commands exit Connect mode
jmp short cmdcom
cquit: mov al,'C'
jmp short cmdcom
cquery: mov al,'?'
jmp short cmdcom
chang: mov al,'H' ; Hangup, drop DTR & RTS
;;; jmp short cmdcom
cmdcom: mov kbdflg,al ; pass char to msster.asm via kbdflg
stc ; say exit Connect mode
ret
;; end of action routines
; put the character in al to the screen, do capture and printing,
; does translation for Set Input command.
; Adapted from msyibm.asm [jrd]
outtty proc near
test flags.remflg,d8bit ; keep 8 bits for displays?
jnz outnp8 ; nz = yes, 8 bits if possible
and al,7fh ; remove high bit
outnp8: cmp rxtable+256,0 ; is translation off?
je outtty_knj0 ; e = yes, off
push bx ; Translate incoming char
mov bx,offset rxtable ; address of translate table
xlatb ; new char is in al
pop bx
;
; Kanji test
;
outtty_knj0:
cmp kanji_rcode,0 ; Kanji code used ?
je outnp7 ; e = no, no translation
test kanji_rcode,2 ; DEC code ?
jz outtty_knj1 ; z = no
jmp outtty_dknj0
outtty_knj1:
test kanji_rcode,4 ; Shift-JIS code ?
jz outtty_knj2
jmp outtty_sknj0
outtty_knj2:
;
outnp7:
push bx
mov bx,argadr ; args from msster directly
test [bx].flgs,capt ; capturing output? Can be shut off
pop bx ; if out dev becomes not ready.
jz outnoc ; no, forget this part
push ax ; save char
call captrtn ; give it captured character
cmp kanji_rmode,0
je outnp71
mov al,kanjir1
call captrtn
outnp71:
pop ax ; restore character and keep going
outnoc: test ourarg.flgs,prtscr ; should we be printing?
jz outnop ; no, keep going
push ax
mov ah,print_out ; write to system printer device
mov dl,al
int dos
cmp kanji_rmode,0
je outnoc1
mov dl,kanjir1
int dos
outnoc1:
pop ax
jnc outnop ; nc = successful print
push ax
call beep ; else make a noise and
call trnprs ; turn off printing
pop ax
outnop: cmp flags.vtflg,0 ; emulating vt100 terminal?
jnz outnop1 ; nz = yup, go do something smart
test ourarg.flgs,trnctl ; debug? if so use dos tty mode
jz outnp4 ; z = no
mov ah,conout
cmp al,7fh ; Ascii Del char or greater?
jb outnp1 ; b = no
je outnp0 ; e = Del char
push ax ; save the char
mov dl,7eh ; output a tilde for 8th bit
int dos
pop ax ; restore char
and al,7fh ; strip high bit
outnp0: cmp al,7fh ; is char now a DEL?
jne outnp1 ; ne = no
and al,3fH ; strip next highest bit (Del --> '?')
jmp outnp2 ; send, preceded by caret
outnp1: cmp al,' ' ; control char?
jae outnp3 ; ae = no
add al,'A'-1 ; make visible
outnp2: push ax ; save char
mov dl,5eh ; caret
int dos ; display it
pop ax ; recover the non-printable char
outnp3: mov dl,al
int dos
ret
outnp4: cmp al,bell ; bell (Control G)?
jne outnp5 ; ne = no
jmp beep ; use short beep, avoid char loss.
outnop1:
cmp flags.vtflg,ttvt100 ; vt100 emulation?
je outtty_vt
cmp flags.vtflg,tttek ; tek4014 emulation?
je outtty_tk
;
outnp5: test flags.remflg,d8bit ; keep 8 bits for displays?
jnz outnp9 ; nz = yes, 8 bits if possible
and al,7fh ; remove high bit
outnp9: mov ah,conout ; dostty screen mode
mov dl,al ; write without intervention.
int dos ; else let dos display char
cmp kanji_rmode,0
je outnpx
test flags.remflg,d8bit
jnz outnp91
and al,7fh
outnp91:
mov ah,conout
mov dl,kanjir1
int dos
mov kanji_rmode,0
outnpx:
ret ; and return
;
outtty_vt:
cmp al,CHR_GS
jne outtty_vt1
test vt100_flags,AUTOTEK_BIT
jz outtty_vt1
push ax
call vt100_save
call ent_tk
mov flags.vtflg,tttek
pop ax
jmp outtty_tk1
outtty_vt1:
cmp kanji_rmode,0
je outtty_vt2
mov al,kanjio1
call vt100
mov al,kanjio2
outtty_vt2:
call vt100
jmp outtty_snd
outtty_tk:
cmp al,CHR_CAN
jne outtty_tk1
test vt100_flags,AUTOTEK_BIT
jz outtty_tk1
push ax
call tek4014_save
call ent_vt
mov flags.vtflg,ttvt100
pop ax
jmp outtty_vt1
outtty_tk1:
call tek4014
outtty_snd:
mov kanji_rmode,0
jcxz outtty_snd_ex ; If there is no answer-back, return
outtty_snd1:
mov ah,[si]
call outchr ; send character without echo
nop
nop
nop
inc si
loop outtty_snd1
outtty_snd_ex:
ret
outtty_dknj0:
cmp kanji_rmode,0 ; 1st byte ?
jne outtty_dknj2
cmp al,0A0h ; Is kanji ?
ja outtty_dknj1 ; a = Yes.
jmp outnp7
outtty_dknj1:
mov kanji_rmode,1
mov kanjir1,al
mov kanjio1,al
ret
outtty_dknj2:
test al,0A0h
jbe outtty_dknj3
mov kanjio2,al
mov ah,al
mov al,kanjir1
and ax,7F7Fh
call jis2s
mov kanjir1,ah
outtty_dknj3:
jmp outnp7
;
outtty_sknj0:
cmp kanji_rmode,0 ; 1st byte ?
jne outtty_sknj2
call is_kanji1
jc outtty_sknj1 ; c = Yes.
jmp outnp7
outtty_sknj1:
mov kanji_rmode,1
mov kanjir1,al
mov kanjio1,al
ret
outtty_sknj2:
mov kanjio2,al
mov ah,al
mov al,kanjio1
call s2jis
or ax,8080h
xchg kanjio1,al
xchg kanjio2,ah
mov kanjir1,ah
jmp outnp7
;
outtty endp
; send the character in al out to the serial port; handle echoing.
; Can send an 8 bit char while displaying only 7 bits locally.
outprt proc near
test ourarg.flgs,lclecho ; echoing?
jz outpr1 ; z = no, forget it
push ax ; save char
call outtty ; print it
pop ax ; restore
outpr1: mov ah,al ; this is where outchr expects it
call outchr ; output to the port
nop
nop
nop ; skip returns...
ret
outprt endp
; Get a char from the serial port manager
; returns with carry on if a character is available
portchr proc near
call prtchr ; character at port?
jmp short portc1 ; yes
nop
portc0: clc ; no carry -> no character
ret ; and return...
portc1: and al,parmsk ; apply 8/7 bit parity mask
or al,al ; catch nulls
jz portc0 ; z = null, ignore it
;;--------------------------------------------------------
;; DO NOT IGNORE DELs. TEK4014 uses DEL code for LOY byte.
;; (H.Fujii 19-May-1988)
;;
;; cmp al,del ; catch dels
;; je portc0 ; e = del, ignore it
;;--------------------------------------------------------
portc2: stc ; have a character
ret ; and return
portchr endp
; Jumping to this location is like retskp. It assumes the instruction
; after the call is a jmp addr.
RSKP PROC NEAR
pop bp
add bp,3
push bp
ret
RSKP ENDP
; Jumping here is the same as a ret.
R PROC NEAR
ret
R ENDP
code ends
end
;
;+ End of MSXP98.ASM