home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
kermit.columbia.edu
/
kermit.columbia.edu.tar
/
kermit.columbia.edu
/
extra
/
nyenhuis2.arc
/
MSXHPX.ASM
< prev
Wrap
Assembly Source File
|
1988-07-01
|
31KB
|
1,163 lines
name msxhpx
; File MSXHPX.ASM
; Edit history:
; Last edit: 4 June 1988
; 1 July 1988 Version 2.31
; 1 Jan 1988 version 2.30
; 25 May 1987 Add keyboard translator, input translation, cleanups. [jrd]
; 1 Oct 86 Version 2.29a
; 30 Sept 1986 Reject DEL char at serial port reception level to avoid
; problems when DEL is used as a filler char (by Emacs). [jrd]
; 28 Sept 1986 Revise procedure Term to permit capturing, printer ready
; testing, debug display. Revised other port procedures slightly too;
; especially to set port into binary mode via ioctl. [jrd]
; 22 Sept 1986 Add modifications from Mike Mellinger: outchr, serhng.
; Introduce COM3 as additional choice. Startup 8 bits, no parity. [jrd]
; 4 Sept 1986 Add Bob Goeke's change to move comms port table to a system
; dependent module (typ msx---) to allow 3+ ports and localized idents. [jrd]
; Date: 15 Oct 85
; HP Portable Kermit
; for HP110 and HP Portable Plus
; Port 1: Serial, Port 2: internal modem
; Defaults: even parity, 9600 baud: serial, 1200 internal modem
; Internal modem code only works on HP Portable Plus
; 15 Nov 85:
; Added code to shut off serial port and modem when quitting Kermit
; 11 Jan 86;
; change msdefs.h to mssdef.h for kermit 2.28 jrd
;
; Add global entry point vtstat for use by Status in mssset.
; Also trimmed off trailing commas in publics. Joe R. Doupnik 12 March 1986
; Add global procedures ihosts and ihostr to handle host initialization
; when packets are to be sent or received by us,resp. 24 March 1986
; Add global procedure dtrlow (without worker serhng) to force DTR & RTS low
; in support of Kermit command Hangup. Says Not Yet Implemented. [jrd]
; Add global procedure Dumpscr, called by Ter in file msster, to dump screen
; to a file. Just does a beep for now. 13 April 1986 [jrd]
; In proc Outchr add override of xon from chkxon sending routine.
; This makes a hand typed Xoff supress the xon flow control character sent
; automatically as the receiver buffer empties. 20 April 1986 [jrd]
; Fix port selector table, comptab, (from original version) to properly
; hold port name AUX. 23 April 1986 [jrd]
;
; Fixed error in resetting the serial port, 25 April 1986
;
page 80,132
PLUS equ 0
public serini, serrst, clrbuf, outchr, coms, vts, vtstat, dodel
public ctlu, cmblnk, locate, lclini, prtchr, dobaud, clearl
public dodisk, getbaud, beep, pcwait, termtb, shomodem, getmodem
public xofsnt, puthlp, putmod, clrmod, poscur
public sendbr, sendbl, term, machnam, setktab, setkhlp, showkey
public ihosts, ihostr, dtrlow, serhng, dumpscr, comptab
public chrout, cstatus, cquit
public cquery, trnprs, snull, klogon, klogof, kdos
include mssdef.h
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
; 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
extrn portval:word, port1:byte, port2:byte, dmpname:byte
extrn port3:byte, kbdflg:byte, rxtable:byte
ifdef PLUS
machnam db 'HP-PLUS$'
else
machnam db 'HP-110$'
endif
erms20 db cr,lf,'?Warning: System has no disk drives$'
erms40 db cr,lf,'?Warning: Unrecognized baud rate$'
erms41 db cr,lf,'?Warning: Cannot open com port$'
erms50 db cr,lf,'Error reading from device$'
badbd db cr,lf,'Unimplemented baud rate$'
badpar db cr,lf,'Unimplemented parity$'
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,' Communications port is not ready.$'
msmsg2 db cr,lf,' Communications port is ready.$'
rdbuf db 80 dup (?) ; temp buf
shkmsg db 'Not implemented.'
shklen equ $-shkmsg
baudstr db 'SB' ; string used in setting baud rate
baudx db 0,';'
par_str db 'P' ; string used to set parity
par_x db 4,';' ; 4=no parity (use 0 for even parity)
brk_on db 'B1;' ; start sending breaks
brk_off db 'B0;' ; stop sending breaks
chk_msg db 0BFH,';' ; check serial buffer
$m0 db 'M0;'
$m1 db 'M1;'
$off_m db 'M3;M5;'
off_len equ $-$off_m
;
ini_msg db 'C2;' ; XON/XOFF
db 'LI1;' ; DTR on
db 'SS0;' ; 1 Stop Bit
Db 'SW0;' ; 8 bits ( use SW1 for 7 Bit Length)
setktab db 0
setkhlp db 0
crlf db cr,lf,'$'
delstr db BS,BS,' ',BS,'$'
clrlin db cr,ESCAPE,'K$'
clreol db ESCAPE,'K$'
telflg db 0 ; non-zero if we're a terminal
xofsnt db 0 ; Say if we sent an XOFF
xofrcv db 0 ; Say if we received an XOFF
invseq db ESCAPE,'&dB$' ; Reverse video
nrmseq db ESCAPE,'&d@$' ; Normal video
ivlseq db 80 dup (' '),cr,'$' ; make line inverse video
prthnd dw 0 ; Port handle
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
tempbuf dw 10 dup(?)
prttab dw com1,com2,com3
com1 db 'COM1',0
com2 db 'AUX',0
com3 db 'COM3',0
blank db ESCAPE,'H',ESCAPE,'J$'
movcur db ESCAPE,'&a'
colno db 20 dup(?)
ten db 10
tmp db ?,'$'
temp dw 0
temp1 dw ? ; Temporary storage
temp2 dw ? ; Temporary storage
; Entries for choosing communications port. [19b]
comptab db 7 ; 7 entries. Rewritten by [jrd]
mkeyw '1',1
mkeyw '2',2
mkeyw '3',2
mkeyw 'AUX',2 ; alias for com2
mkeyw 'COM1',1
mkeyw 'COM2',2
mkeyw 'COM3',3
termtb db tttypes ; entries for Status, not Set
mkeyw 'Heath-19',ttheath
mkeyw 'none',ttgenrc
mkeyw 'Tek4014',tttek
mkeyw 'VT102',ttvt100
mkeyw 'VT52',ttvt52
; variables for serial interupt handler
source db bufsiz DUP(?) ; buffer for data from port
bufout dw 0 ; buffer removal pointer
count dw 0 ; number of chars in int buffer
bufin dw 0 ; buffer insertion pointer
ourarg termarg <>
datas ends
code segment public 'code'
extrn comnd:near, dopar:near, prserr:near, atoi:near, prompt:near
extrn sleep:near
extrn msuinit:near, keybd:near ; in msuhpx
assume cs:code,ds:datas
; 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.
; Returns normally.
CLRBUF PROC NEAR
cli
mov bufin,offset source
mov bufout,offset source
mov count,0
sti
ret
CLRBUF ENDP
; Clear to the end of the current line. Returns normally.
CLEARL PROC NEAR
push ax ; save regs
push dx
mov ah,prstr
mov dx,offset clreol
int dos
pop dx
pop ax
ret
CLEARL 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: push cx ; save regs
or ah,ah ; sending a null?
jz outch2 ; z = yes
xor cx,cx ; clear counter
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
mov al,ah ; Parity routine works on AL
call dopar ; Set parity appropriately
; Begin revised output routine
mov byte ptr temp,al ; put data there
cmp prthnd,0 ; Got a handle yet?
jne outch3 ; Yup just go on
call opnprt ; Else 'open' the port
outch3: 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
pop dx
pop cx
jmp rskp
; This routine blanks the screen. Returns normally.
CMBLNK PROC NEAR
push ax ; save regs
push dx
mov ah,prstr
mov dx,offset blank
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
ifdef PLUS
mov dx,1800H ; now address line 24
else
mov dx,0F00H ; now address line 15
endif
call poscur
mov dx,offset invseq ; put into inverse video
mov ah,prstr
int dos
pop dx ; get message back
int dos ; print it
mov dx,offset nrmseq ; normal video
int dos
ret
putmod endp
; clear the mode line written by putmod. Returns normally.
clrmod proc near
ifdef PLUS
mov dx,1800H
else
mov dx,0F00H
endif
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
mov ah,prstr
mov dx,offset crlf
int dos
pop si ; point to string again
puth0: mov ah,prstr
mov dx,offset invseq ; put into reverse video
int dos
mov ah,prstr
mov dx,offset ivlseq ; make line inverse video
int dos
cld
puth1: lodsb ; get a byte
cmp al,0 ; end of string?
je puth2
mov dl,al
mov ah,conout
int dos ; else write to screen
cmp al,lf ; line feed?
je puth0 ; yes, clear the next line
jmp puth1
puth2: mov ah,prstr
mov dx,offset crlf
int dos
mov dx,offset nrmseq ; normal video
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 ; save regs
push bx
push dx
mov bx,portval
mov dx,[bx].baud ; get baud rate from table
cmp dx,0
jb bd_bd
cmp dx,10
je bd_bd
cmp dx,15
ja bd_bd
;
cmp dx,10
jb baud_4
cmp dx,11
jne baud_1
mov dl,'A'
jmp baud_5
baud_1: cmp dx,12
jne baud_2
mov dx,'C'
jmp baud_5
baud_2: cmp dx,13
jne baud_3
mov dx,'E'
jmp baud_5
baud_3: cmp dx,14
jne bd_bd
mov dx,'F'
jmp baud_5
baud_4: add dl,'0' ; make # printable
baud_5: mov baudx,dl ; put into baud rate message
mov cx,4
mov dx,offset baudstr ; point to message
cmp prthnd,0 ; is port open
je Baud_R ; No, skip hardware set
call w_ioctl ; write to ioctl of serial port
pop dx ; [jrd]
pop bx
pop ax
Baud_R: ret ; ...and return
;
bd_bd: mov ah,prstr
mov dx,offset badbd ; Say it's not implemented
int dos
mov bx,portval
mov [bx].baud,0FFFFH ; So it's not a recognized value
pop dx
pop bx
pop ax
ret ; Must be set before starting Kermit
DOBAUD ENDP
; Use hardware parity of None so software routines can do the work. [jrd]
DOPARITY PROC NEAR
push ax ; save regs
push bx
push cx
push dx
;; mov bx,portval
;; mov dl,[bx].parflg ; get parity flag
;; cmp dl,0
;; jne par_1
;; mov dx,'0' ; even parity
;; jmp par_3
;;par_1: cmp dl,2
;; jne par_2
mov dx,'4' ; no parity
;; jmp par_3
;;par_2: cmp dl,3
;; jne bd_par
;; mov dx,'1' ; odd parity
par_3: mov par_x,dl ; set up string
mov dx,offset par_str ; point to string
mov cx,3 ; 3 lettters in string
cmp prthnd,0 ; is port open
je Par_R ; No, skip hardware set
call w_ioctl ; write to ioctl of serial port
pop dx ; [jrd]
pop cx
pop bx
pop ax
Par_R: ret ; ...and return
bd_par: mov bx,portval
mov [bx].parflg,0
mov ah,prstr
mov dx,offset badpar
int dos
pop dx
pop cx
pop bx
pop ax
ret
DOPARITY 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
ret ; Can't do this
GETBAUD ENDP
; SHOW MODEM - displays status of modem lines DSR, CD, CTS, in this case
; it just says whether or not the port is ready for i/o.
shomodem proc near
mov ah,cmcfm ; get a confirm
call comnd
jmp r ; no confirm
nop
cmp prthnd,0 ; Got a handle yet?
jne shmod0 ; Yup just go on
call opnprt ; Else 'open' the port
shmod0: mov dx,offset msmsg1 ; say port is not ready
mov bx,prthnd
mov al,7 ; output status command
mov ah,ioctl ; ask DOS to look for us
int dos
jc shmod1 ; c = call failed, device not ready
or al,al
jz shmod1 ; not ready
mov dx,offset msmsg2 ; say port is ready
shmod1: mov ah,prstr
int dos
jmp rskp
shomodem endp
getmodem proc near
mov al,0 ; no modem status
ret
getmodem endp
;
; write cx bytes to ioctl of serial port
;
W_IOCTL PROC NEAR
push ax ; save regs
push bx
mov ah,ioctl
mov al,3
mov bx,prthnd
int dos
pop bx
pop ax
ret
W_IOCTL ENDP
;
; read cx bytes from ioctl of serial port to tempbuf
;
R_IOCTL PROC NEAR
push ax ; save regs
push bx
mov ah,ioctl
mov al,2
mov bx,prthnd
mov dx,offset tempbuf
int dos
pop bx
pop ax
ret
R_IOCTL ENDP
;
; check serial port for characters and return number in al
;
CHK_BUFF PROC NEAR
push cx
push dx
mov dx,offset chk_msg
mov cx,2
call w_ioctl
mov cx,1
call r_ioctl
mov ax,tempbuf
pop dx
pop cx
ret
CHK_BUFF ENDP
; Use for DOS 2.0 and above. Check the port status. If no data, skip
; return. Else, read in a char and return.
PRTCHR PROC NEAR
push bx
push cx
push si
cmp prthnd,0 ; got a handle
jne prtch1 ; ne = yes
call opnprt ; open port if not
prtch1: cmp count,0 ; any chars in buffer?
jne prtch2 ; ...yes, get one
call chk_buff ; any chars at port?
or al,al
jz prtch4 ; no, go to skip return
mov ah,0
mov cx,1 ; read one char
mov count,cx
mov bx,prthnd
mov ah,readf2 ; DOS read from file/device
mov dx,offset source
int dos
jc prt3x ; c = failure
mov bufout,offset source
prtch2: dec count
mov si,bufout
cld
lodsb
mov bufout,si
prtch3: pop si
pop cx
pop bx
ret ; return success
prt3x: mov ah,prstr
mov dx,offset erms50
int dos
prtch4: pop si
pop cx
pop bx
jmp rskp ; no chars
PRTCHR ENDP
; Send a break out the current serial port. Returns normally.
SENDBR PROC NEAR
push cx
push dx
mov dx,offset brk_on
mov cx,3
call w_ioctl
mov dx,offset brk_off
mov cx,3
call w_ioctl
pop dx
pop cx
clc ; clear carry to stay in Connect mode
ret
SENDBR ENDP
SENDBL PROC NEAR ; Send a Long Break
jmp sendbr ; same as regular here
SENDBL 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
pop dx ; empty buffer. we are done here
pop cx
pop bx
pop ax
ret
IHOSTS ENDP
; IHOSTR - initialize the remote host for our reception of a file by
; sending the flow-on character (XON typically) to release any held
; data. Called by receive-file code just after initializing the serial
; port. 22 March 1986 [jrd]
IHOSTR PROC NEAR
push ax ; save regs
push bx
push cx
mov bx,portval ; port indicator
mov ax,[bx].flowc ; put Go-ahead flow control char in ah
or ah,ah ; don't send null if flow = none
jz ihostr1 ; z = null
call outchr ; send it (release Host's output queue)
nop ; outchr can do skip return
nop
nop
ihostr1:pop cx
pop bx
pop ax
ret
IHOSTR ENDP
DTRLOW PROC NEAR ; Global proc to Hangup the Phone by making
; DTR and RTS low.
mov ah,cmtxt ; allow text to be able to display help
mov bx,offset rdbuf ; dummy buffer
mov dx,offset hnghlp ; help message
call comnd ; get a confirm
jmp r
call serhng ; drop DTR and RTS
mov ah,prstr ; give a nice message
mov dx,offset hngmsg
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.
; Adapted from recommendation by Mike Mellinger. [jrd]
SERHNG PROC NEAR
push ax
push bx
push cx
push dx
mov dx,offset com2
mov ah,open2 ; open device AUX
mov al,1 ; for writing
int dos
jc serhn1 ; c = error
mov bx,ax ; file handle
mov ah,write2
mov dx,offset $off_m ; magic words to turn off DTR
mov cx,off_len ; their length
int dos ; write them
mov ah,close2 ; close the device
int dos
serhn1: pop dx
pop cx
pop bx
pop ax
ret
SERHNG ENDP
; Wait for the # of milliseconds in ax, for non-IBM compatibles.
; 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
; Position the cursor according to contents of DX:
; DH contains row, DL contains column. Returns normally.
POSCUR PROC NEAR
push ax ; save regs
push dx
push di
mov ax,ds
mov es,ax ; address data segment!!
cld
mov di,offset colno
mov al,dl ; column
call nout
mov al,'x'
stosb
mov al,dh ; row
call nout
mov al,'Y'
stosb
mov al,'$'
stosb
mov dx,offset movcur
mov ah,prstr
int dos ; print the sequence
pop di
pop dx
pop ax
ret
POSCUR ENDP
NOUT PROC NEAR
cbw ; extend the word
div byte ptr ten ; divide by ten
or al,al ; any quotient?
jz nout1 ; no, forget this
push ax ; save current result
call nout ; output high order
pop ax ; restore
nout1: mov al,ah ; get digit
add al,'0' ; make printable
stosb ; put in buffer
ret ; and return
NOUT ENDP
; Delete a character from the terminal. This works by printing
; backspaces and spaces. Returns normally.
DODEL PROC NEAR
push ax ; save regs
push dx
mov ah,prstr
mov dx,offset delstr ; Erase weird character
int dos
pop dx
pop ax
ret
DODEL ENDP
; Move the cursor to the left margin, then clear to end of line.
; Returns normally.
CTLU PROC NEAR
push ax ; save regs
push dx
mov ah,prstr
mov dx,offset clrlin
int dos
call clearl
pop dx
pop ax
ret
CTLU ENDP
; Set the current port.
COMS PROC NEAR
call serr_x ; force close on serial port
mov dx,offset comptab ; table of comms ports
mov bx,0 ; use keywords as help
mov ah,cmkey ; parse a keyword
call comnd
jmp r ; failure
nop
push bx
mov ah,cmcfm
call comnd ; Get a confirm
jmp comx ; Didn't get a confirm
nop
pop bx
mov flags.comflg,bl ; Set the comm port flag
cmp flags.comflg,1 ; Using Com 1?
jne coms2 ; ne = no
mov portval,offset port1
ret
coms2: cmp bl,2 ; using com2?
jne coms3 ; ne = no
mov portval,offset port2
ret
coms3: mov portval,offset port3
ret
comx: pop bx
ret
COMS ENDP
; Set heath emulation on/off.
VTS PROC NEAR
jmp notimp
VTS ENDP
VTSTAT PROC NEAR ; For Status display [jrd]
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
call beep
ret
DUMPSCR ENDP
notimp: mov ah,prstr
mov dx,offset noimp
int dos
jmp prserr
; Initialize variables to values used by the generic MS DOS version.
lclini: call msuinit ; init keyboard translator
mov flags.vtflg,0 ; Don't do terminal emulation
mov prthnd,0 ; no port handle yet. [jrd]
;;; call opnprt ; Get file handle for comm port
push bx
mov bx,offset port1
mov [bx].baud,B9600 ; port1 -> 9600 baud
mov [bx].parflg,2 ; no parity
mov bx,offset port2
mov [bx].baud,B1200 ; port2 -> 1200 baud
mov [bx].parflg,2 ; no parity
pop bx
ret
; 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", "COM2", "COM3","AUX".
opnprt: mov al,flags.comflg
dec al ; flags.comflg = 1 for com1, 2 com2, 3 com3
mov ah,0
mov si,ax
shl si,1 ; double index
mov dx,prttab[si]
mov ah,open2
mov al,2
int dos
jnc opnpr1
mov ah,prstr ; It didn't like the string
mov dx,offset erms41
int dos
mov prthnd,0 ; clear port file handle
stc ; carry set for failure
ret
opnpr1: mov prthnd,ax ; Call succeeded
mov ah,ioctl
mov al,00h ; get device info
xor dx,dx
mov bx,prthnd ; port's handle
int dos
or dl,20h ; set binary mode in device info
mov dh,0
mov ah,ioctl
mov al,01h ; set device info
int dos
ret ; carry clear for success
showkey:
mov ax,offset shkmsg
mov cx,shklen
ret
; Initialization for using serial port. Returns normally.
SERINI PROC NEAR
cld ; Do increments in string operations
cmp prthnd,0 ; Got Handle already?
jne ser_x ; ne = yes, skip open
call opnprt ; open handle
jc serin2 ; carry set = failure
mov cx,3
mov ax,portval
cmp ax,offset port1
jnz seri
mov dx,offset $m1
jmp serx
seri: mov dx,offset $m0
serx: call w_ioctl
ser_x: mov dx,offset ini_msg
mov cx,15
call w_ioctl
call dobaud ; set baud rate
call doparity ; set parity
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
clc ; carry clear for success
serin2: ret
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 flags.extflg,0
jne serr_x
ret
serr_x: push bx ; save reg
cmp prthnd,0 ; handle there?
je serr_1 ; no, don't try to close
mov cx,off_len
mov dx,offset $off_m
call w_ioctl
mov bx,prthnd
mov ah,close2
int dos ; close handle
mov prthnd,0
serr_1: pop bx
ret
SERRST 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. 27 Sept 86 [jrd].
term proc near
mov argadr,ax ; save argument ptr
mov si,ax ; this is source
mov di,offset ourarg ; place to store arguments
push es ; save register
push ds
pop es ; set es to datas segment
mov cx,size termarg
cld
rep movsb ; copy into our arg blk
pop es ; restore reg
and ourarg.flgs,not (prtscr) ; no screen printing at startup
mov ax,ourarg.captr
mov captrtn,ax ; buffer capture routine
mov parmsk,0ffh ; parity mask, assume parity = None
cmp ourarg.parity,parnon ; is parity None?
je term1 ; e = yes, keep all 8 bits
mov parmsk,07fh ; else keep lower 7 bits
term1: call portchr ; get char from port, apply parity mask
jnc short term2 ; nc = no char, go on
call outtty ; display and capture char
term2: call keybd ; call keyboard translator in msu
jnc term1 ; nc = no char or have processed it
; carry set = quit Connect mode
term4: ret
term endp
; put the character in al to the screen, do capture and printing,
; does translation for Set Input command.
; Adapted from msyibm.asm [jrd]
outtty proc near
test flags.remflg,d8bit ; keep 8 bits for displays?
jnz outnp8 ; nz = yes, 8 bits if possible
and al,7fh ; remove high bit
outnp8: cmp rxtable+256,0 ; is translation off?
je outnp7 ; e = yes, off
push bx ; Translate incoming char
mov bx,offset rxtable ; address of translate table
xlatb ; new char is in al
pop bx
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
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
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 a 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:
outnp5: mov ah,conout ; dostty screen mode
mov dl,al ; write without intervention
int dos ; else let dos display char
ret ; and return
outtty endp
; send the character in al out to the serial port; handle echoing.
; Can send an 8 bit char while displaying only 7 bits locally.
outprt proc near
test ourarg.flgs,lclecho ; echoing?
jz outpr1 ; z = no, forget it
push ax ; save char
call outtty ; print it
pop ax ; restore
outpr1: mov ah,al ; this is where outchr expects it
call outchr ; output to the port
nop
nop
nop ; skip returns
ret
outprt endp
; Get a char from the serial port manager
; returns with carry on if a character is available
portchr proc near
call prtchr ; character at port?
jmp short portc1 ; yes, go handle
nop ; skip return is stupid
portc0: clc ; no carry -> no character
ret ; and return
portc1: and al,parmsk ; apply 8/7 bit parity mask
or al,al ; catch nulls
jz portc0 ; z = null, ignore it
cmp al,del ; catch dels
je portc0 ; e = del, ignore it
stc ; have a character
ret ; and return
portchr endp
;; keyboard translator action routines, system dependent, called from msugen.
; These are invoked by a jump instruction. Return carry clear for normal
; processing, return carry set to exit Connect mode (kbdflg has transfer char)
chrout: call outprt ; put char in al to serial port
clc ; stay in Connect mode
ret
trnprs: push ax ; toggle Copy screen to printer
test ourarg.flgs,prtscr ; are we currently printing?
jnz trnpr2 ; nz = yes, its on and going off
mov ah,ioctl
mov al,7 ; get output status of printer
push bx
mov bx,4 ; file handle for system printer
int dos
pop bx
jc trnpr1 ; c = printer not ready
cmp al,0ffh ; Ready status?
je trnpr2 ; e = Ready
trnpr1: call beep ; Not Ready, complain
jmp trnpr3 ; and ignore request
trnpr2: xor ourarg.flgs,prtscr ; flip the flag
trnpr3: pop ax
clc
ret
klogon proc near ; resume logging (if any)
test flags.capflg,logses ; session logging enabled?
jz klogn ; z = no, forget it
or ourarg.flgs,capt ; turn on capture flag
klogn: clc
ret
klogon endp
klogof proc near ; suspend logging (if any)
and argadr.flgs,not capt ; stop capturing
klogo: clc
ret
klogof endp
snull: mov ah,0 ; send a null
call outchr ; send without echo or logging
nop
nop
nop
clc
ret
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
cmdcom: mov kbdflg,al ; pass char to msster.asm via kbdflg
stc ; say exit Connect mode
ret
; 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