home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Columbia Kermit
/
kermit.zip
/
archives
/
msr313src.tar.gz
/
msr313src.tar
/
msxrmx.a86
< prev
next >
Wrap
Text File
|
1988-08-16
|
37KB
|
1,082 lines
NAME MSXRMX
; RMX System dependent module derived from Generic MS DOS Kermit module
$INCLUDE(mssdef.h86)
public serini, serrst, clrbuf, outchr, coms, vts, dodel, termtb, bddat
public ctlu, cmblnk, locate, lclini, prtchr, dobaud, clearl, pcwait
public dodisk, getbaud, beep, srcptr, sendbl, dtrtime, shomodem
public xofsnt, puthlp, putmod, clrmod, poscur, savsi, portatt, sintok
public sendbr, term, setktab, setkhlp, showkey, dtrlow, serhng
public vtstat, ihosts, ihostr, dumpscr, comptab, costrt, coptr, spkout
public chrout, chang, klogof, klogon, snull, cquit, cstatus, cquery
false equ 0
true equ 1
; 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
; 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
PURGE prstr, dconio
extrn drives:byte, flags:byte, trans:byte, citok:word, cotok:word
extrn portval:word, prtbase:byte, oneport:byte, trmstr:byte
extrn mbox:word, tmbox:word, sigpair:word, sematok:word, spkcnt:word
extrn data:byte, pack:byte, combx:word, cimbx:word, termatt:word
extrn trok:byte, rxtable:byte, kbdflg:byte, subpksz:word, source:byte
extrn bufill:word, temp:word
erms40 db cr,lf,'?Warning: Unrecognized baud rate',cr,lf,'$'
erms60 db cr,lf,'Port doesn''t exist, use RUN ATTACH . . .'
db cr,lf,'& try again$'
wrn1prt db
& bell,cr,lf,'Warning: No ports found, port 0 being used',cr,lf,bell,'$'
badbd db cr,lf,'Unimplemented baud rate$'
noimp db cr,lf,'Command not implemented.$'
setktab db 0
setkhlp db 0
crlf db cr,lf,'$'
delstr db BS,BS,' ',BS,'$' ; Delete string.
clrlin db cr ; Clear line (just the cr part).
clreol db ESCAPE,'[0K' ; Clear line.
clscr db ESCAPE,'[2J' ; clear screen
cursor db ESCAPE,'[' ; position cursor
row dw ? ; part
db ';' ; of
col dw ? ; above
db 'H' ; last of above
mode db ESCAPE,'[24;1H',ESCAPE,'[0K' ; put cursor on mode line & clea
model db 80 dup(?) ; mode line contents
huosc db ESCAPE,']M:H',ESCAPE,'\' ; hangup OSC
xofsnt db 0 ; Say if we sent an XOFF.
xofrcv db 0 ; Say if we received an XOFF.
parmsk db ? ; 8/7 bit parity mask, for reception
savrflg db ? ; save previous remflg
comstr db 6,':COM_:'
tstr db 4,':T_:'
devname db 14 dup(?) ; :TERM:'s physical device name
; Entries for choosing communications port. [19b]
comptab db 10
%mkeyw (%('0 (TERM)'),0)
%mkeyw (%('1 (COM1 or T1)'),1)
%mkeyw (%('2 (COM2 or T2)'),2)
%mkeyw (%('3 (COM3 or T3)'),3)
%mkeyw (%('4 (COM4 or T4)'),4)
%mkeyw (%('5 (COM5 or T5)'),5)
%mkeyw (%('6 (COM6 or T6)'),6)
%mkeyw (%('7 (COM7 or T7)'),7)
%mkeyw (%('8 (COM8 or T8)'),8)
%mkeyw (%('9 (COM9 or T9)'),9)
ourarg termarg <>
termtb db 1
%mkeyw (%('none'),ttgenrc)
even
ten dw 10
dtrtime dw 500
status dw ?
sostrt dw ?
soend dw ?
sofin dw ?
savsi dw source ; points to next char in buffer
srcptr dw source ; points to next quadrant of buffer
sintok dw 0
soutok dw 0
portptr dw ?
costrt dw ?
coptr dw ?
argadr dw ?
portatt dw 4,4,0ffh,119h ; serial I/O port attributes for rqaspecial
inbaud dw 0,1 ; part of above
getptat dw 3,3,2 dup(?) ; structure to read baud rate
getinbd dw ? ; part of above
dest db 2 dup (?) ; outchr's buffer
; This table is indexed by portinfo.baud. Unsupported baud rates contain 0.
bddat label word
dw 0 ; 45.5 baud N/A
dw 50 ; 50 baud
dw 75 ; 75 baud
dw 110 ; 110 baud
dw 0 ; 134.5 baud N/A
dw 150 ; 150 baud
dw 300 ; 300 baud
dw 600 ; 600 baud
dw 1200 ; 1200 baud
dw 1800 ; 1800 baud
dw 2000 ; 2000 baud
dw 2400 ; 2400 baud
dw 4800 ; 4800 baud
dw 9600 ; 9600 baud
dw 19200 ; 19200 baud
dw 38400 ; 38400 baud
dw 56800 ; 56800 baud
dw 0 ; 113600 baud N/A
datas ends
code segment
extrn comnd:near, dopar:near, prserr:near, keybd:near, msuinit:near
extrn delcon:near, crfile:near, opfile:near, writer:near
extrn aspcl:near, prstr:near, awrite:near, rqsleep:near, flushci:near
extrn waitio:near, sendms:near, aopen:near, aclose:near, special:near
extrn rcvmsg:near, delseg:near, dconio:near, gfilsta:near
; This is the HANGUP command. It drops DTR momentarily, if the serial board
; and its driver support modem control.
dtrlow PROC
serhng: call serrst ; reset & reinitialize port
call serini
mov ax,soutok ; enable OSC's on output
mov bx,offset portatt
and word ptr[bx+4],0bfh
mov cx,5
call aspcl
mov ax,soutok ; send hangup OSC
mov bx,offset huosc
mov byte ptr[bx+4],'H'
mov cx,size huosc
mov dx,tmbox
call awrite
mov ax,soutok ; wait for it
mov bx,tmbox
call waitio
mov ax,dtrtime ; kill time
call pcwait
mov ax,soutok
mov bx,offset huosc
mov byte ptr[bx+4],'A'
mov cx,size huosc ; send answer OSC
mov dx,tmbox
call awrite
mov ax,soutok ; wait for it
mov bx,tmbox
call waitio
mov ax,soutok ; disable OSC's on output
mov bx,offset portatt
or word ptr[bx+4],40h
mov cx,5
call aspcl
call serrst ; reset port
jmp RSKP
dtrlow ENDP
pcwait PROC ; sleep for ax milliseconds (rounded up to nearest 10)
push ax ; too lazy to find out how much of this is necessary
push bx
push cx
push dx
push si
push di
push es
sub dx,dx
add ax,9
div ten
push ax
push ds
mov ax,offset status
push ax
call rqsleep
pop es
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
pcwait ENDP
; IHOSTS - Initialize the host by sending XON, or equivalent, and enter the
; cycle of clear input buffer, 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
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
test ah,ah ; don't send null if flow=null
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
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
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
test 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
; this is called by Kermit initialization. It checks the
; number of disks on the system, sets the drives variable
; appropriately. Returns normally.
DODISK PROC
mov drives,1 ; 1 "disk". It's $, which can be reattachfiled
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
push es
mov ax,ds
mov es,ax
cld
cli
mov di,savsi ; scan from current ptr
mov cx,offset source+bufsiz
sub cx,di ; to end of buffer for fill char
mov al,byte ptr bufill
repne scasb
je CLRB1 ; jump if found
mov di,offset source ; scan from the beginning, if not
mov cx,bufsiz
repne scasb
CLRB1: dec di
mov savsi,di ; current ptr points to fill char
sti
pop es
ret
CLRBUF 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
push bx
push cx
push dx
push es
mov al,ah
call dopar ; set parity, as req'd
mov dest,al
mov ax,soutok
mov bx,offset dest ; write it
mov cx,1
sub dx,dx
call awrite
pop es
pop dx
pop cx
pop bx
cmp status,0
jne OUTCH1
jmp RSKP ; OK return
OUTCH1: ret ; NG return
outchr ENDP
; Set the baud rate for the current port, based on the value in the portinfo
; structure. Returns normally. Entered w/current baud rate in ax.
DOBAUD PROC
push bx
mov bx,portval ; see if new baud rate is OK
mov si,[bx].baud
shl si,1
mov cx,bddat[si]
jcxz DOBD1 ; nope
call serrst ; yeah, force serini to set it
pop bx
ret
DOBD1: mov [bx].baud,ax ; restore previous baud rate
mov dx,offset badbd ; send bad baud msg
call prstr
pop bx
ret
DOBAUD ENDP
; Get the current baud rate from the serial card and set it
; in the potinfo structure for the current port. Returns normally.
; This is used during initialization.
GETBAUD PROC
ret ; It's all taken care of, so what's to do?
GETBAUD ENDP
; Use for DOS 2.0 and above. Check the port status. If no data, skip return.
; Else, read in a char and return. DX returns # chars (0 or 1 for us).
PRTCHR PROC
push si
cmp xofsnt,true ; if XOF has been sent,
je PRTCH4 ; see if there's room in buffer for XON
PRTCH1: sub dx,dx ; # of chars
mov si,savsi ; current serial input buffer ptr
cld
lodsb
cmp al,byte ptr bufill ; got one?
jne PRTCH2
pop si ; nope
jmp RSKP
PRTCH2: cmp si,offset source+bufsiz ; edge of the universe?
jb PRTCH3 ; no
mov si,offset source ; yeah, point to beginning
PRTCH3: mov savsi,si ; update current ptr
inc dx ; # chars=1
pop si
ret ; got one return
PRTCH4: mov ax,srcptr ; if next quadrant & current ptr are
sub ax,savsi ; 2 quadrants apart
jns PRTCH5 ; there's room to XON
add ax,bufsiz
PRTCH5: cmp ax,bufsiz/2
jg PRTCH1 ; they aren't
push bx ; send XON
mov bx,portval
mov ax,[bx].flowc
call outchr
nop
nop
nop
mov xofsnt,false ; reset
pop bx
jmp PRTCH1
PRTCHR ENDP
; Send a break out the current serial port. Returns normally.
SENDBR PROC
sendbl: mov dx,offset noimp ; send intel's appologies
call prstr ; for not having OS support
ret ; for their hardware's capabilities
SENDBR ENDP
; Show modem command. Not implemented.
SHOMODEM PROC
mov ah,cmcfm ; get a confirm
call comnd
ret ; no confirm
nop
nop
call SENDBR ; send not imp. msg
jmp RSKP
SHOMODEM ENDP
; Clear to the end of the current line. Returns normally.
CLEARL PROC
push bx
mov bx,offset clreol ; send ESC[0K
SCRO1: mov cx,4 ; to clear to end of line
SCRO2: push ax
SCRO3: mov ax,cotok
push es
push dx
push si
call writer
pop si
pop dx
pop es
pop ax
pop bx
ret
CLEARL ENDP
; This routine blanks the screen. Returns normally.
CMBLNK PROC
push bx
mov bx,offset clscr ; send ESC[2J for clear screen
jmp SCRO1
CMBLNK ENDP
; Position the cursor according to contents of DX:
; DH contains row, DL contains column. Returns normally.
POSCUR PROC
push bx
push ax
add dx,101h ; KERMIT starts w/0, RMX w/1
mov al,dh ; convert row to decimal
sub ah,ah
mov cl,10
div cl
add ax,'00' ; covert to ASCII
mov row,ax ; stash in row portion of escape sequence
mov al,dl ; convert column to decimal
sub ah,ah
div cl
add ax,'00' ; convert to ASCII
mov col,ax ; to column portion of escape sequence
mov bx,offset cursor
mov cx,8 ; send ESC[row;colH to position cursor
jmp SCRO3
POSCUR ENDP
; Move the cursor to the left margin, then clear to end of line.
; Returns normally.
CTLU PROC
push bx
mov bx,offset clrlin ; send CR,ESC[0K to clear entire line
mov cx,5
jmp SCRO2
CTLU ENDP
; Homes the cursor. Returns normally.
LOCATE PROC
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
push bx
push ax
mov bx,es ; save es
mov ax,ds
mov es,ax
mov di,dx
mov cx,0ffffh ; compute # bytes in line
mov al,'$'
repne scasb
neg cx
add cx,0fffeh
mov si,dx
mov di,offset model
mov dx,cx ; save # bytes
rep movsb ; move line after mode line escape sequence
mov cx,size mode ; mode line escape sequence length
add cx,dx ; plus line length
mov es,bx ; restore es
mov bx,offset mode ; write line prefixed w/escape sequence
jmp SCRO3
putmod ENDP
; clear the mode line written by putmod. Returns normally.
clrmod PROC
push bx
mov bx,offset mode ; mode line escape sequence
mov cx,size mode ; ESC[24;1HESC[0K
jmp SCRO2 ; clears mode line
clrmod ENDP
; Put a help message on the screen.
; Pass the message in ax, terminated by a null. Returns normally.
puthlp PROC
push dx
push si
push ax ; preserve this
mov dx,offset crlf
call prstr
pop si ; point to string again
puthl3: cld
lodsb ; get a byte
cmp al,0 ; end of string?
je puthl4 ; yes, stop
mov dl,al
call dconio ; else write to screen
jmp puthl3 ; and keep going
puthl4: mov dx,offset crlf
call prstr
pop si
pop dx
ret
puthlp ENDP
; Delete a character from the terminal. This works by printing
; backspaces and spaces. Returns normally.
DODEL PROC
mov dx,offset delstr
call prstr ; Erase weird character.
ret
DODEL ENDP
; Set the current port.
COMS PROC
call serrst ; reset the old port
mov dx,offset comptab
sub bx,bx
mov ah,cmkey
call comnd ; parse for the new one
ret
nop
nop
push bx ; save port #
mov ah,cmcfm
call comnd ; Get a confirm.
jmp short COMX ; Didn't get a confirm.
nop
pop cx ; get port #
mov ax,size prtinfo ; compute address of prtinfo structure
mul cl
add ax,offset prtbase
mov temp,ax ; save it
jcxz COMS1 ; jmp if port 0 (:TERM:)
call COMSR ; crfile :COMn: or :Tn:
jz COMS2 ; jmp if successful
mov dx,offset erms60
call prstr ; no luck, bitch
ret
COMX: pop bx
ret
COMS1: mov di,offset trmstr
mov temp+2,di ; port name string pointer
call crfile
COMS2: mov bx,temp
mov portval,bx ; set prtinfo ptr
COMS3: mov flags.comflg,cl ; remember port #
mov sintok,ax ; open port
mov bx,1
call aopen
call rdbaud ; read it's baud rate
mov bx,portval
mov [bx].baud,cx ; memorize it
call serrst ; reset port
mov di,temp+2 ; port name string pointer
mov portptr,di
call gfilsta ; puts physical device name @temp+10
mov ax,ds
mov es,ax
mov si,offset devname
mov di,offset temp+10
mov cx,size devname
repe cmpsb ; is it the same as :TERM:?
je COMS5 ; eq = yes
cmp oneport,true ; was it oneport?
jne COMS4 ; ne = no, exit
mov al,savrflg ; yes, restore remflg to what it was before
mov flags.remflg,al
mov oneport,cl ; clear oneport
COMS4: ret
COMS5: mov al,dquiet ; get current remflg & set to quiet mode
xchg al,flags.remflg
cmp oneport,true ; if not previously one port
je COMS4 ; save previous remflg & set oneport
mov savrflg,al
mov oneport,true ; set oneport
ret
COMSR proc
push cx ; save port #
add cl,'0' ; charify
mov di,offset comstr
mov temp+2,di ; temp+2 is port name string pointer
mov [di+5],cl ; setup :COMn: & :Tn: strings
mov tstr+3,cl
call crfile ; try COMn
jcxz CSR1 ; OK
mov di,offset tstr ; try Tn
mov temp+2,di
call crfile
CSR1: test cx,cx ; return zero flag, if successful
pop cx ; restore port #
ret
COMSR endp
COMS ENDP
; Reads serial port's baud rate. Returns baud rate index in cx if recognizable
; by KERMIT, if not, cx=0ffffh.
rdbaud PROC
push es
mov ax,sintok ; use aspecial function 4 to read baud rate
mov bx,offset getptat
mov cx,4
call aspcl
mov ax,ds
mov es,ax
mov ax,getinbd ; search bddat table for it
mov cx,baudsiz
mov di,offset bddat+2*(baudsiz-1)
std
repne scasw
cld
je RDB1 ; found it, cx=index
mov dx,offset erms40
call prstr ; not found, say so
mov cx,0ffffh ; return unrecognizable
RDB1: pop es
ret
rdbaud ENDP
; Set heath emulation on/off.
VTS PROC
mov dx,offset noimp
call prstr
jmp prserr
VTS ENDP
; Initialize variables & find port
lclini: mov flags.vtflg,0 ; Don't do terminal emulation.
call msuinit
mov di,offset trmstr ; get :TERM:'s physical devive name
call gfilsta
mov ax,ds
mov es,ax
mov si,offset temp+10 ; move it to devname
mov di,offset devname
mov cx,size devname
rep movsb
mov ax,offset prtbase ; base value of prtinfo struc ptr
mov ax,portval
mov temp,ax ; save in case it ends up port 0
LCL1: add portval,size prtinfo ; loop thru looking for 1st of 1 to max
inc cx ; 0 1st time thru
call COMSR ; try crfile COMn or Tn
jz LCL2 ; z = success
cmp cl,portmax-1 ; done?
jl LCL1 ; l = no
call COMS1 ; yes, go use :TERM:
mov dx,offset wrn1prt ; and give one port warning
call prstr
ret
LCL2: jmp COMS3 ; join common code
ret
showkey:ret ; obsolete, for ext def only
; Initialization for using serial port. Returns normally.
SERINI PROC
cmp sintok,0 ; is this trip necessary?
jne SIN3 ; no
push bx
push es
cmp oneport,true ; is it oneport?
jne SIN1 ; ne = no
mov ax,citok ; yes, shut down citsk
sub cx,cx
call aclose
mov ax,citok ; reopen
mov bx,3
call aopen
call flushci ; necessary for 386
SIN1: mov di,portptr ; get port ptr
push di ; save for 2nd crfile
call crfile ; create it
mov sintok,ax ; set serial input token
mov bx,1 ; open for reading
call aopen
pop di ; port ptr
call crfile ; create it
mov soutok,ax ; set serial output token
mov bx,2 ; open for writing
call aopen
mov bx,portval ; prtinfo struc ptr
mov parmsk,0ffh ; set parmsk according to this port
cmp [bx].parflg,parnon
je SIN2
mov parmsk,7fh
SIN2: mov bx,[bx].baud ; set baud rate according to this prot
shl bx,1
mov ax,bddat[bx]
mov inbaud,ax
mov ax,soutok ; set baud rate & attributes
mov bx,offset portatt
mov cx,5
call aspcl
mov ax,mbox ; when the message sent to mbox
mov bx,ax ; is the mbox token itself
call sendms ; it tells the serial input task
pop es ; to initialize & start input
pop bx
SIN3: 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
push bx
mov bx,sintok ; serial input token
test bx,bx
jz SERST1 ; unecessary
mov sintok,0 ; MUST be done 1st, cuz siotsk is gonna get ints
call delcon ; before we get back from delete connection
SERST1: mov ax,soutok ; serial output token
test ax,ax
jz SERST2 ; don't bother
push ax ; save for delcon
mov cx,tmbox
push cx ; save for rcvmsg
call aclose ; let I/O complete before delcon
pop ax
mov bx,0ffffh
call rcvmsg
call delseg
pop bx ; soutok
mov soutok,0 ; see above
call delcon ; ditto
cmp oneport,true
jne SERST2
call flushci ; necessary for 386
mov ax,citok
mov bx,offset termatt
mov cx,5
call aspcl
mov ax,cimbx ; restart citsk
mov bx,ax
call sendms
SERST2: pop bx
ret
SERRST ENDP
; Bell ringer
BEEP PROC
mov dl,bell
call dconio
ret
BEEP ENDP
VTSTAT PROC ; 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 ; Dumps screen contents to a file. Just Beeps here
jmp beep ; [jrd]
DUMPSCR ENDP
; Dumb terminal emulator.
TERM PROC
cmp oneport,true ; if oneport
jne TERM1
mov kbdflg,'C' ; force exit connect mode
jmp BEEP
TERM1: 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
mov parmsk,0ffh
cmp ourarg.parity,parnon
je TERM2
mov parmsk,7fh
TERM2: mov ax,citok ; shut down citsk & reopen citok
call aclose
mov ax,citok
mov bx,3
call aopen
sub ax,ax ; turn off control C trap
mov sigpair,ax
mov ax,citok
mov bx,offset sigpair
mov cx,6
call aspcl
push termatt+6 ; save
cmp trok,true
je TERM3
and termatt+6,0fdffh ; turn off translation
TERM3: push termatt+4 ; save
or termatt+4,0e0h ; disable OSC's & output ctrl chars
mov ax,cotok ; make it transparent as all get out
mov bx,offset termatt ; during terminal emulation
mov cx,5
call special
mov ax,citok
mov bx,offset termatt
mov cx,5
call aspcl
mov ax,cimbx ; start citsk & cotsk
mov bx,ax
call sendms
mov ax,combx
mov bx,ax
call sendms
mov ax,ds
mov es,ax
TERM4: call PORTCHR ; get char from port
call OUTTTY ; if char, output it
call KEYBD ; check keyboard
jnc TERM4 ; carry=exit Connect mode
pop termatt+4 ; restore
pop termatt+6 ; restore
mov ax,combx ; shut down cotsk
mov bx,ax
call sendms
mov ax,citok ; shut down citsk & reopen citok
call aclose
mov ax,citok
mov bx,3
call aopen
mov ax,sematok ; restore control C trap
mov sigpair,ax
mov ax,citok
mov bx,offset sigpair
mov cx,6
call aspcl
mov ax,cotok ; reopen cotok
mov bx,3
mov cx,bx
call opfile
mov ax,citok ; restore terminal attributes
mov bx,offset termatt
mov cx,5
call aspcl
mov ax,cotok
mov bx,offset termatt
mov cx,5
call special
mov ax,cimbx ; restart citsk
mov bx,ax
call sendms
ret
TERM ENDP
;; keyboard translator action routines, system dependent, called from msurmx.
; These are invoked by a jump instruction. Return carry clear for normal
; processing, return carry set exit Connect mode (kbdflg has transfer char).
klogon proc ; resume logging (if any)
test flags.capflg,logses ; session logging enabled?
jz klogn ; z = no, forget it
or argadr.flgs,capt ; turn on capture flag
or ourarg.flgs,capt ; turn on local capture flag as well
klogn: clc
ret
klogon endp
klogof proc ; suspend logging (if any)
and argadr.flgs,not capt ; stop capturing
and ourarg.flgs,not capt ; rest local as well
clc
ret
klogof endp
snull: mov ah,0 ; send a null
call outchr ; send without echo or logging
nop
nop
nop
clc
ret
cmdcom: mov kbdflg,al ; pass char to msster.asm via kbdflg
stc ; say exit Connect mode
ret
cstatus:mov al,'S' ; these commands exit Connect mode
jmp cmdcom
cquit: mov al,'C'
jmp cmdcom
cquery: mov al,'?'
jmp cmdcom
chang: mov al,'H'
jmp cmdcom
;; end of action routines
OUTTTY PROC
cmp rxtable+256,0 ; translation turned off?
je OTY1 ; e = yes, no translation
push bx
mov bx,offset rxtable ; address of translate table [jrd]
xlatb ; new char is in al
pop bx
OTY1: test ourarg.flgs,capt ; capturing output?
jz OTY2 ; no, forget it
push ax
call ourarg.captr ; else call the routine
pop ax
OTY2: test ourarg.flgs,trnctl ; debugging? nz=yes
jnz OTY3 ; bypass translation & do debug display
test flags.remflg,d8bit ; keep 8 bits for displays?
jnz OUTONE ; nz = yes, 8 bits if possible
and al,7fh ; remove high bit
OUTONE PROC
mov di,coptr ; CO buffer pointer
sub di,costrt ; is buffer full?
cmp di,cobufl
je OUTONE ; eq=yes, wait for room
cli ; disable ints during
mov di,coptr ; these 3
stosb ; critical
mov coptr,di ; instructions
sti
ret
OUTONE ENDP
OTY3: test al,al ; is high bit on?
jns OTY4 ; ns=no
mov ah,al ; save it
mov al,'~' ; output tilde
call OUTONE
mov al,ah ; restore it & turn off high bit
and al,7fh
OTY4: cmp al,7fh ; is it rubout?
jne OTY5 ; ne=no
and al,3fh ; convert to ?
jmp short OTY6 ; to display ^? for rubout
OTY5: cmp al,' ' ; is it a control character?
jae OUTONE ; ae=no, just output it
add al,'@' ; make printable
OTY6: mov ah,al ; save
mov al,'^' ; output ^
call OUTONE
mov al,ah ; restore & output
jmp OUTONE
OUTTTY ENDP
CHROUT PROC
test ourarg.flgs,lclecho ; echoing?
jz CHRO1 ; no, don't bother
push ax
call OUTTTY
pop ax
CHRO1: mov ah,al
call outchr ; output the character
nop
nop
nop
ret
CHROUT ENDP
SPKOUT PROC
inc spkcnt ; bump ctr
cmp ah,trans.ssoh
je SPK4 ; eq = start of packet
cmp bx,soend
je SPK1 ; eq = enough to write
clc
ret
SPK1: push cx
push bx
push ax
push dx
mov cx,bx ; bx is last byte+1
xchg bx,sostrt ; bx = current 1st byte, sostrt = next 1st byte
sub cx,bx ; cx = # bytes
mov ax,soutok ; call rqawrite(soutok,ds:bx,cx,0,@status)
sub dx,dx
call awrite
pop dx
pop ax
mov bx,sostrt
mov cx,sofin
SPK2: add bx,subpksz ; next time to write (soend) =
cmp bx,cx ; min{sofin,(sostrt + subpksz)}
jb SPK3
mov bx,cx
SPK3: mov soend,bx
pop bx
pop cx
clc
ret
SPK4: push cx
push bx ; start of packet
dec bx ; point to soh
mov sostrt,bx ; set sub-packet start ptr
sub cx,cx
mov cl,trans.chklen
add cx,offset data
add cx,pack.argbk1
inc cx
mov sofin,cx ; sofin = end of packet ptr
jmp SPK2
SPKOUT ENDP
PORTCHR PROC
call prtchr ; get char from port
jmp short PORCH1 ; got one
nop
jmp short RSKP ; don't got
PORCH1: and al,parmsk ; apply 8/7 bit parity mask
jz RSKP ; filter nulls
cmp al,del ; filter rubouts
je RSKP
ret
PORTCHR ENDP
; Jumping to this location is like retskp. It assumes the instruction
; after the call is a jmp addr.
RSKP PROC
pop bp
add bp,3
jmp bp
RSKP ENDP
code ends
end