home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Columbia Kermit
/
kermit.zip
/
archives
/
msr313src.tar.gz
/
msr313src.tar
/
msxap3.asm
< prev
next >
Wrap
Assembly Source File
|
1988-08-16
|
73KB
|
1,726 lines
NAME msxap3
Page 60,132
; Last edit: 14 March 1988
; NEC APCIII Edit History
; RFGoeke, MIT Center for Space Research, 627-253-1910
; Goeke @ SPACE.MIT.EDU
; 14 March 1988 Rev. a for V2.30
; Minor patches to get compatible with released IBM V2.30
; Major shuffle to get text lined up with msxibm so diff will work
; Change "esc" to "escape"; add shomodem and termtb; add vtemu.vtflgop
; 6 October 1987 Rev. F
; Recreate SERRST to turn off all ports; called by mssker when exiting;
; keeps incoming characters on unwatched line from bombing system.
; NB this is also called by mssrcv, mssscp, ssssen, and msster !!!
; so one has to keep the modem status lines ON at all times.
; Also increased Hangup DTR drop to 2 seconds; recalibrated pcwait.
; 8 July 1987 Rev. E
; Minor fix ups to keep pace with v/2.29C development; recalibrated
; timer code in pcwait.
; 5 November 1986 Rev. D
; Major bug in serini fixed (characters in unaddressed ports were
; coming through and corrupting DOS
; 14 October 1986 Rev. B
; Modified to work with [2.29a] code.
; 21 August 1986 Rev. N
; Modified from the [2.29] code for msxibm
; with help from the RAL Version 2.0.
; General considerations:
; The presence of ANSI.SYS in the booted CONFIG.SYS file is assumed.
; If ports 2 or 3 are to be used, OPTRS232.SYS is required in CONFIG.SYS
; References to modems have also been deleted.
; Bugs found:
; The NEC BIOS call to the screen (19H) tends to wipe out the SI
; register; a lot of push/pops have been added for this reason.
; The RS232 BIOS call miscalculates the end of the circular receive
; buffer by 20 bytes (see comments in SERINI).
; (The following comments are from msxibm.asm; not all apply here!)
; 1 Jan 1988 version 2.30
; 24 Dec 1987 Revise selection of COM1 to use COM1 name but COM2 addresses
; if base address of 02f8 (COM2) is found in 40:00h and display notice.
; Restore state of IRQ interrupt line when finished with serial port. [jrd]
; 31 Oct 1987 Add terminal type Tek4010, with Tek submode Tekflg. [jrd]
; 24 Oct 1987 Enhance clrbuf to empty any intermediate (net) buffers. [jrd]
; 19 Oct 1987 Fix stray tab-set at column 32. [jrd]
; 2 Oct 1987 Add PCjr baud rate table, from Ted Medin. [jrd]
; 6 Sept 1987 Allow serial port serint to send xoff when buffer fills even
; though user may have sent xoff by hand. [jrd]
; 27 Aug 1987 Skip timeout test in OUTCHR if receive timeout is zero. [jrd]
; 23 August 1987 Add vtemu.vtflgop to hold runtime terminal settings so that
; a reset command restores them to the Setup values, vtemu.vtflgst. Show
; displays the vtemu.vtflgop operational values. [jrd]
; 17 August 1987 Make timing adjustments for Token Passing and single buffered
; network adapter boards. Byte netdbfr indicates presence of double buffering;
; it is set in chknet as a vendor option. To test your boards force dbl buf
; then look for missing 256 byte parts of long packets sent out; missing parts
; mean new material overwrote not-yet-sent old == single buffering. [jrd]
; 8 August 1987 Add interrupt chaining in serint. [jrd]
; 23 July 1987 Clear xofsnt and xofrcv xon/xoff flags in ihost(s/r). [jrd]
; 9 July 1987 Cure confusion about COM1/2 for IBM PCjr (address of regular
; COM2 in 40:0h slot for COM1) with info from John Neufeld. [jrd]
; 2 July 1987 Route NetBios cancels through separate scb for systems, such
; as Novell NetWare, which object to having active scbs touched. [jrd]
; 25 June 1987 Add trapping of Int 14H (Bios RS232 procedure) to allow
; CTTY command to function without too much inteference from DOS. [jrd]
; 17 June 1987 Enlarge tab setting to full 132 columns at all times. [jrd]
; 11 June 1987 Add Set Term Roll on/off to control auto roll back of screen
; when new characters are displayed; default is off (no unwinding). [jrd]
; 20 May 1987 Remove rejection of NULL and DEL chars, let callers do it. [jrd]
; 16 May 1987 Add distinction between user typed and receiver threshold
; controlled sending of XOFF. User level overrides buffer control.[jrd]
; Add COM3 and COM4 support: examine memory 40:00h->40:07h for selected
; port COM1..4, resp. If word is null then set flags.comflg to 0 to say
; undefined port. Otherwise, use that word in seg 40h as base of UART i/o
; ports. Assume IRQ4 for COM1 and COM3 (same except for port addresses)
; and IRQ4 for COM2 and COM4 (again, same except for port addresses).
; Serial port info sturcture (not values) assumed identical for all ports.
; 25 April 1987 Add Netbios compatible local area network support. [jrd]
; Set Port command expanded to syntax SET PORT NET nodename. Use nodename
; if acting as a client to named remote node, leave blank if running in
; Server mode. Byte 'ttyact' is controlled by msster.asm to indicate Connect
; mode is being used. Byte 'netdone' (stored in mssker.asm) holds offset of
; network hangup procedure 'netclose' to be done when leaving Kermit. Hangup
; command extended to to network hangup as well. Network uses IBM Netbios
; standard calls (Int 5Ch) and allows for extensions of AT&T STARLAN for
; longer node names via Int 2Bh (the later is tested before use). Virtual
; circuits are employed. The Redirector is not necessary. Kermit can operate
; as either a terminal (does a CALL at Connect mode startup), a file receiver
; (does a CALL at startup), or a Kermit server (does an anonomous LISTEN at
; startup, hence no nodename). Clients should Set Timer Off.
; 16 April 1987 Add measurement and correction of software timer pcwait. [jrd]
; 5 April 1987 Keep DTR & RTS low for 1/2 second in serhng, suggested by
; Jack Bryans. [jrd]
; 28 March 1987 Reference screen coord wrt low_rgt from msyibm, let number
; of tabs be full screen width. [jrd]
; 22 March 1987 Fix bug in pcwait code, from Stefan Vogel. [jrd]
; 6 March 1987 Make PCWAIT a global procedure, add SENDBL to send Long
; Break. [jrd]
; 21 Feb 1987 Merge operations for semi-clone machines (those identical to
; IBM PC's except the serial port must be accessed via the Bios rather than
; from the real UART hardware). Ports automatically checked for 8250. [jrd]
; 1 Oct 1986 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]
; 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]
; 26 August 1986 Use parity mask when testing for nulls & Xon/Xoff in serial
; port interrupt routine. [jrd]
; 16 August 1986 Use observed screen attributes for mode line. [jrd]
; 9 August 1986 Revise SERINT to insert control-G for overrun chars, give
; faster return of interrupts to system, remove use of BP in code. [jrd]
; 17 July 1986 Minor clean up of Terminal Status display routine. [jrd]
; 22 June 1986 Leave 8250 UART signal OUT1 low to avoid resetting Hayes
; 1200B modems (thanks to Neil Rickert). [jrd]
; Skip sending null byte in ihosts and ihostr (thanks to Skip Russell). [jrd]
; 22 May 1986 Rewrite serial port interrupt procedure and proc prtchr
; to avoid lockups with interrupts disabled, buffer corruption, and to
; minimize lost clock interrupts. Flow control not needed at 9600 baud,
; slow screen refresh, VT102 emulation, on a 4.77 MHz IBM PC clone.
; Added buffer low water mark to give more xon/xoff hysterisis. [jrd]
; [2.29] code frozen on 6 May 1986 [jrd]
; Note -
; When the Bios is used for serial port i/o the modem signals DSR and CTS
; must be asserted low before the Bios will access the hardware. Jumpers
; from pin 20 (DTR) to pin 6 (DSR) and from pin 4 (RTS) to pin 5 (CTS)
; will probably be necessary.
; From Glenn Everhart (who suggested using the Bios alternative)
;
public serini, serrst, clrbuf, outchr, coms, vts, vtstat
public dodel, ctlu, cmblnk, locate, prtchr, dobaud, clearl
public dodisk, getbaud, beep, termtb, shomodem
public count, xofsnt, puthlp, putmod, clrmod, poscur
public sendbr, sendbl, machnam, setktab, setkhlp, lclini, showkey
public ihosts, ihostr, dtrlow, serhng, comptab, pcwait
include mssdef.h
false equ 0
true equ 1
; the following sets the text attributes RFG
att_low_mask equ 1FH ; Various attribute-related equates
att_overline equ 01H ; this is all NEC version stuff RFG
att_blink equ 02H
att_rev_video equ 04H
att_underline equ 08H
att_intensity equ att_rev_video
nec_black equ 00H ; This table gives colors RFG
nec_blue equ 20H ; (only bits 8,7,6 count)
nec_red equ 40H
nec_magenta equ 60H
nec_green equ 80H
nec_cyan equ 0A0H
nec_yellow equ 0C0H
nec_white equ 0E0H
; constants used by serial port handler
KEYB EQU 18H ; RFG
BIOS EQU 19H ; RFG
; 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
; low_rgt - low byte = last column (typ 79), high byte = last text row
; (typ 23) in screen coordinates (start at 0), set by msyibm.
; global variables defined in this module:
; xofsnt, xofrcv - tell whether we saw or sent an xoff.
; setktab - keyword table for redefining keys (should contain a 0 if
; not implemented)
; setkhlp - help for setktab.
datas segment public 'datas'
extrn drives:byte, flags:byte, trans:byte, ttyact:byte
extrn portval:word, port1:byte, port2:byte, port3:byte, port4:byte
extrn netdone:word, pcnet:byte
extrn refresh:byte, scbattr:byte, low_rgt:word, vtemu:byte
extrn vtroll:byte, tekflg:byte
; structure for status information table sttab.
stent struc
sttyp dw ? ; type (actually routine to call)
msg dw ? ; message to print
val2 dw ? ; needed value: another message, or tbl addr
tstcel dw ? ; address of cell to test, in data segment
basval dw 0 ; base value, if non-zero
stent ends
setktab db 0 ; superceded by msuibm code, return 0 here
setkhlp db '$' ; and add empty help string
savsci dd ? ; old serial port interrupt vector.
sav232 dd ? ; Original Bios Int 14H address, in Code seg.
savirq db ? ; Original Interrupt mask for IRQ
; brkval db BRKBIT ; What to send for a break.
brkadr dw 0 ; Where to send it.
modem mdminfo <>
hngmsg db cr,lf,' The phone or network connection should have hungup.'
db cr,lf,'$'
nohngmsg db cr,lf,' Command ineffective on this port.',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.',cr,lf
db ' For networks, the active session is terminated.',cr,lf,'$'
erms40 db cr,lf,'?Warning: Unrecognized baud rate',cr,lf,'$'
badbd db cr,lf,'Unimplemented baud rate$'
prterr db '?Unrecognized value$'
badprt db cr,lf,' Serial port COM$'
badprt2 db ' is not available.$'
badprt3 db cr,lf,' Notice: Port COM1 uses hardware addresses of COM2'
db ' (safe).',cr,lf,'$'
biosmsg db cr,lf,'This port operates through the Bios',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$'
;;;;;;;;;;;;;;;;;;;;;;;;;;;;; NEC Specific data follows
machnam db 'NEC APC III (a)$'
First db true ; used in getbaud
source db 20 DUP(?) ; Buffer for data from port; see comments
db bufsiz DUP(?) ; in serini for why this must be bufsiz+20
uart db 01001110B ; set up various parameters....
; | | | |
; | | | +--- Clock 10 x16, 11 x64
; | | +----- Word Length 00 5, 01 6,10 7, 11 8
; | +------- Parity 00 None, 01 Odd, 11 Even
; +--------- Stop Bits 01 1, 10 1.5, 11 2
stnorm db 00100111B ; This will be CL for serini, normally RFG
stbrk db 00101111B ; This will send a break from serini RFG
stdtr db 00000101B ; This will drop the DTR and RTS line RFG
stoff db 00100010B ; This kills send and receive enable RFG
; ||||||+--- Send enable
; |||||+---- DTR on
; ||||+----- Receive enable
; |||+------ Force spacing on output (for break)
; ||+------- Error request
; |+-------- Request to send
; +--------- Interrrupt reset
saybr db escape,'[25;0H'
db escape,'[35mBreak sent. . .',escape,'[0m$'
initfail db cr,lf,escape,'[31mSerial port could not be initialized',escape,'[m$'
outfail db cr,lf,escape,'[31mTime out on send via serial port',escape,'[m$'
intfail db cr,lf,escape,'[31mTime out on receive via serial port',escape,'[m$'
inbfail db cr,lf,escape,'[31mSerial port receive buffer overflow',escape,'[m$'
mlcurat db ? ; used for the mode line cursor attributes
clreol db escape,'[0K$' ; Clear to end of line.......
blank db escape,'[H',escape,'[J$' ; Home cursor, then Clear screen....
;;;;;;;;;;;;;;;;;;;;;;;;;;;; End of NEC specific stuff
crlf db cr,lf,'$'
delstr db BS,BS,' ',BS,BS,'$' ; Delete string
clrlin db cr,'$' ; Clear line (just the cr part).
onmsg db 'on$'
offmsg db 'off$'
clone db 0 ; clone flag (0 = real, 'B' = system Bios,
; 'N' = NetBios/network)
portin db 0 ; Has comm port been initialized
xofsnt db 0 ; Say if we sent an XOFF.
xofrcv db 0 ; Say if we received an XOFF.
parmsk db ? ; parity mask, 0ffh for no parity, 07fh with.
flowoff db ? ; flow-off char, Xoff or null (if no flow)
flowon db ? ; flow-on char, Xon or null
overrun db ? ; holds status of receiver overrun
pcwcnt dw 240 ; number of loops for 1 millisec in pcwait
temp dw 0
tempsci dw 0 ; temp storage for serint
tempdum dw 0 ; temp storage for serdum
rdbuf db 80 dup (?) ; temporary storage
; begin Terminal emulator data set
termtb db tttypes ; entries for Status, not Set
mkeyw 'Heath-19',ttheath
mkeyw 'none',ttgenrc
mkeyw 'Tek4010',tttek
mkeyw 'VT102',ttvt100
mkeyw 'VT52',ttvt52
vttbl db 13 ; twelve entries.
mkeyw 'Character-set',chaval
mkeyw 'Color',200H ; screen fore/back colors; 200H=marker
mkeyw 'Cursor-style',curval
mkeyw 'Heath-19',ttheath+100H ; note 100H flag for decoding here
; mkeyw 'Keyclick',keyval ; NEC can't do internally
mkeyw 'Margin-bell',marval
mkeyw 'None',ttgenrc+100H
mkeyw 'Newline',newval
mkeyw 'Rollback',400h ; note 400H flag for decoding
; mkeyw 'Screen-background',scrval ; NEC keep black back
mkeyw 'Tabstops',tabval
mkeyw 'Tek4010',tttek+100H
mkeyw 'VT102',ttvt100+100H
mkeyw 'VT52',ttvt52+100H
mkeyw 'Wrap',wraval
scrtab db 02H ; screen attributes
mkeyw 'normal',00H
mkeyw 'reverse',01H
curtab db 02H ; cursor attributes
mkeyw 'block',00H
mkeyw 'underline',01H
chatab db 02H ; character set (pound sign choice)
mkeyw 'UK-ascii',01H
mkeyw 'US-ascii',00H ; US ASCII is default (0).
tabtab db 02H ; label says it all!
mkeyw 'at',0FFH ; For setting tab stops.
mkeyw 'Clear',00H ; For clearing tab stops.
alltab db 02H ; more tab command decoding
mkeyw 'all',00H
mkeyw 'at',01H
vtable dw ontab, curtab, chatab, ontab, ontab, ontab, scrtab, 0
vtsflg equ this byte ; define small digits xxxval
newval equ $-vtsflg ; and mask for bit in byte
db vsnewline
curval equ $-vtsflg
db vscursor
chaval equ $-vtsflg
db vsshift3
keyval equ $-vtsflg
db vskeyclick
wraval equ $-vtsflg
db vswrap
marval equ $-vtsflg
db vsmarginbell
scrval equ $-vtsflg
db vsscreen
numflgs equ $-vtsflg
tabval equ $-vtsflg
db 0
vtrtns dw numflgs dup (flgset), tabset ; dispatch table for vtsflg
clrset db ? ; Temp for SET Term Tabstops xxx
tmptabs db 132 dup (?) ; Temporary for unconfirmed tabs.
vthlp db ' one of the following:',cr,lf
db ' terminal types of: None, Heath-19, Tek4010,'
db ' VT52, or VT102',cr,lf
db ' Newline-mode Cursor-style Character-set (US UK)',cr,lf
db ' Tabstops Wrap (long lines) Color (of connect screen)'
db cr,lf,' Roll (undo screen roll back before writing new chars,'
db ' default=off)',cr,lf
db ' Margin-bell'
db '$'
clrhlp db ' one of the following:'
db cr,lf,' AT #s (to set tabs at column #s)'
db cr,lf,' Clear AT #s or Clear ALL (to clear tabstops)'
db cr,lf,' Ex: Set Term Tab at 10, 20, 34 sets tabs'
db cr,lf,' Ex: Set Term Tab Clear at 9, 17, 65 clears tabs$'
allhlp db ' one of the following:'
db cr,lf,' AT #s (to clear at specific columns)'
db cr,lf,' ALL (to clear all tabstops)$'
tbshlp db ' column number of tab stop to set, 1 to screen width-1$'
tbchlp db ' column number of tab stop to clear, 1 to screen width-1$'
tbserr db cr,lf,'?Column number is not in range 1 to screen width-1$'
;;;;;;;;;;;;;;;;;;;; modified for the realities of the APC III
colhlp db cr,lf,' Color of: '
db escape,'[34mblue '
db escape,'[31mred '
db escape,'[35mmagenta '
db escape,'[32mgreen '
db escape,'[36mcyan '
db escape,'[33myellow '
db escape,'[37mwhite'
db escape,'[0m$'
colltb db 7 ; 7 entries
mkeyw 'Blue',nec_blue
mkeyw 'Cyan',nec_cyan
mkeyw 'Green',nec_green
mkeyw 'Magenta',nec_magenta
mkeyw 'Red',nec_red
mkeyw 'White',nec_white
mkeyw 'Yellow',nec_yellow
;;;;;;;;;;;;;;;;;;;; end of NEC colors
vtwrap db ' Term wrap-lines: $'
vtbell db ' Term margin-bell: $'
vtnewln db ' Term newline: $'
vtcur db ' Term cursor-style: $'
vtcset db ' Term character-set: $'
; vtclik db ' Term key-click: $'
; vtscrn db ' Term screen-background: $'
colst1 db ' Term color foreground:3$'
; colst2 db ' background:4$'
; terminal emulator
vtstbl stent <srchkb,vtwrap,ontab,,vtsflg+wraval> ; VT100 line wrap
stent <srchkb,vtbell,ontab,,vtsflg+marval> ; VT100 margin bell
stent <srchkb,vtcur,curtab,,vtsflg+curval> ; VT100 cursor type
stent <srchkb,vtnewln,ontab,,vtsflg+newval> ; VT100 newline
; stent <srchkb,vtscrn,scrtab,,vtsflg+scrval> ; VT100 screen
stent <srchkb,vtcset,chatab,,vtsflg+chaval> ; VT100 character set
; stent <srchkb,vtclik,ontab,,vtsflg+keyval> ; VT100 keyclick
stent <colstat> ; VT100 colors
stent <tabstat> ; VT100 tab status - needs one whole line
dw 0 ; end of table
; end of Terminal data set
ontab db 2 ; Two entries.
mkeyw 'off',0 ; Should be alphabetized
mkeyw 'on',1
comptab db 6 ; six entries for NEC
mkeyw '1',1
mkeyw '2',2
mkeyw '3',3
mkeyw 'AUX',1
mkeyw 'AUX2',2
mkeyw 'AUX3',3
; this table is indexed by the baud rate definitions given in
; pcdefs. Unsupported baud rates should contain FF.
baudtab db 0FFH ; 45.5
db 0FFH ; 50
db 0 ; 75
db 0FFH ; 110
db 0FFH ; 134.5
db 1 ; 150
db 2 ; 300
db 3 ; 600
db 4 ; 1200
db 0FFH ; 1800
db 0FFH ; 2000
db 5 ; 2400
db 6 ; 4800
db 7 ; 9600
db 0FFH ; 19.2k
db 0FFh ; 38.4k
db 0FFh ; 57.6k
db 0FFh ; 115.2k
nbaud equ $-baudtab
; variables for serial interrupt handler
; BIOS handles the buffer; count not used RFG
count dw 0 ; Number of chars in int buffer.
mdstreg db 0 ; Modem status register, current.
datas ends
code segment public 'code'
extrn comnd:near, dopar:near, defkey:near, lclyini:near
extrn sleep:near, atsclr:near, scrseg:near,scrloc:near, scrsync:near
extrn atoi:near, strlen:near, prtscr:near, scroff:near, scron:near
extrn anstat:near ; RFG
assume cs:code,ds:datas
int_rs232 macro ; this is necessary since we need to
local rs1,rs2 ; to use the 1A interrupt if we have
cmp flags.comflg,1 ; only one port, and 1E if we have more
je rs1
push si ; a necessary save
push bx ; a short save
mov bh,0
mov bl,flags.comflg ; get the port number
sub bl,1 ; put it into NEC terms
mov si,bx ; then into the right place
pop bx ; and restore
int 1EH ; now the multi-choice interrupt
pop si ; and restore
jmp rs2
rs1: int 1AH
rs2: nop
endm
; local initialization
lclini proc near
mov flags.comflg,1 ; assume COM1 for communications port
; call coms2 ; setup serial port modem.info for COM1 RFG
; call model ; get model of IBM machine RFG
call lclyini ; let other modules initialize too...
ret
lclini endp
; this is called by Kermit initialization. It checks the
; number of disks on the system, sets the drives variable
; appropriately. Returns normally.
; From RAL Version 2.0 RFG
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.
dodsk0: mov drives,al ; Remember how many.
ret
DODISK ENDP
; Returns normally. Obsolete, name here for external reference only.
showkey proc near
ret ; return
showkey endp
; SHOW MODEM, displays current status of lines DSR, CD, and CTS.
; Uses byte mdstreg, the modem line status register. [jrd]
shomodem proc near
mov ah,cmcfm ; get a confirm
call comnd
jmp r ; no confirm
nop
mov ah,6 ; status request - NEC code follows
int_rs232 ; go get the answer
and ch,80h ; CH bit 7 Data set ready
xor cl,0FFh ; CL bit 6 Clear to Send = 0
and cl,60h ; 5 Carrier detect = 0
or ch,cl ; lump the answer together
mov mdstreg,ch ; and save it
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
; 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.
; On the NEC, where the buffer is (really) managed by the BIOS, we could
; clear it by calling serini or blindly reading everything out, RFG
CLRBUF PROC NEAR
clrb2: mov ah,2 ; Get data length in CX...Page SE-12
int_rs232 ; Call APC ROM BIOS
clrb4: or ch,cl ; check for zero in both halfs of CX
cmp ch,0 ; is CH 0?
je clrb1 ; If zero then buffer is clear else
mov ah,4 ; Receive Character...by way of NEC BIOS
int_rs232
jmp clrb2
clrb1:
ret
CLRBUF ENDP
; Clear to the end of the current line. Returns normally. RFG
CLEARL PROC NEAR
push ax
push dx
mov dx,offset clreol
mov ah,prstr
int dos
pop dx
pop ax
ret
CLEARL ENDP
; This routine blanks the screen. Returns normally.
CMBLNK PROC NEAR
mov ah,prstr
mov dx,offset blank
int dos
ret
CMBLNK ENDP
; Locate: homes the cursor. Returns normally.
LOCATE PROC NEAR
mov dx,0 ; Go to top left corner of screen.
jmp poscur
LOCATE ENDP
; Position the cursor according to contents of DX:
; DH contains row, DL contains column. Returns normally.
POSCUR PROC NEAR
push ax
push bx
push si ; NEC
mov ah,2 ; Position cursor.
mov bh,0 ; page 0
int bios
pop si ; NEC
pop bx
pop ax
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
ret
BEEP PROC NEAR ; NEC version
mov dl,bell
mov ah,conout
int dos
ret
BEEP ENDP
; write a line in inverse video at the bottom of the screen...
; the line is passed in dx, terminated by a $. Returns normally.
; This is only used for the send/receive mode lines. RFG
putmod proc near
push ax ; save regs
push bx
push cx
push dx ; preserve message
call anstat ; get the screen attributes RPG
mov bh,ah ; mlbattr returned in ah
mov mlcurat,ah ; and put it in mlcurat
mov cx,1800h ; from line 24, column 0
mov dx,184fh ; to line 24, column 79
mov ax,600h ; do a scroll up
int bios
mov dx,1800h ; now address line 24
call poscur
pop si ; get message back (from dx push)
mov cx,1 ; only one char at a time
xor bh,bh ; page 0
putmo1: lodsb ; get a byte
cmp al,'$' ; end of string?
je putmo2
push si ; save si
push ax ; and the char
call poscur
inc dl ; increment for next write
pop ax ; recover char
mov ah,9 ; try this
mov bl,mlcurat ; page 0, inverse video
mov bh,0
int bios
pop si ; recover pointer
jmp putmo1
putmo2: pop cx
pop bx
pop ax
ret
putmod endp
; clear the mode line written by putmod. Returns normally.
; separate out the text attributes RFG
clrmod proc near
push ax
push bx
push cx
push dx
call anstat ; get the screen attributes RPG
mov bh,al ; scbattr returned in al
mov cx,1800h ; from line 24, column 0
mov dx,184fh ; to line 24, column 79
mov ax,600h ; do a scroll up
int bios
pop dx
pop cx
pop bx
pop ax
ret
clrmod endp
; put a help message on the screen. This one uses reverse video...
; pass the message in ax, terminated by a null. Returns normally.
; separate out text attributes
puthlp proc near
push bx ; save regs. [jrd]
push cx
push dx
push si
push ax ; preserve this
cld
mov si,ax ; point to it
mov dh,1 ; init counter
puthl1: lodsb ; get a byte
cmp al,lf ; linefeed?
jne puthl2 ; no, keep going
inc dh ; count it
jmp puthl1 ; and keep looping
puthl2: cmp al,0 ; end of string?
jne puthl1 ; no, keep going;
call anstat ; get screen attributes RPG
mov bh,ah ; mlbattr returned in ah
mov mlcurat,ah ; and save it
mov ax,600h ; scroll to clear window
xor cx,cx ; from top left
mov dl,4fh ; to bottom right of needed piece
int bios
call locate ; home cursor
mov bh,0 ; Page 0
mov bl,mlcurat
mov cx,1 ; one char at a time
cld ; scan direction is forward [jrd]
pop si ; point to string again
puthl3: lodsb ; get a byte
cmp al,0 ; end of string?
je puthl4 ; yes, stop
push si ; save around bios call
cmp al,' ' ; printable?
jb puth21 ; b = no
mov ah,9 ; write char at current cursor position [jrd]
int bios ; do the Bios int 10h call
inc dl ; point to next column
jmp puth23 ; move cursor there
puth21: cmp al,cr ; carriage return?
jne puth22 ; ne = no
xor dl,dl ; set to column zero
jmp puth23
puth22: cmp al,lf ; line feed?
jne puth23
inc dh ; go to next line
puth23: mov ah,2 ; set cursor position to dx
int bios
pop si ; restore pointer [jrd]
jmp puthl3 ; and keep going
puthl4: mov dx,24 * 100H ; go to last line
call poscur ; position cursor
pop si ; [jrd]
pop dx
pop cx
pop bx
ret
puthlp endp
; begin Terminal set & status code
; SET Term parameters, especially for use with VT100 emulator. [jrd]
; Taken from work done originally by James Harvey IUPUI.
; VTS is called only by mssset to set terminal type and characteristics.
VTS proc near ; SET TERM whatever
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?
je vsetu0a ; e = yes
cmp bh,4H ; marker for roll back control?
je vsetu3 ; e = yes
cmp bh,2h ; marker for set term color?
je vsetu2 ; e = yes
jmp short vsetu1 ; else dispatch on bl
vsetu0a:push bx ; yes
mov ah,cmcfm
call comnd ; Get a confirm.
jmp vsetu0 ; Didn't get a confirm.
nop
pop bx
mov flags.vtflg,bl ; Set the terminal emulation type
mov tekflg,0 ; clear Tek sub mode
ret
vsetu0: pop bx
ret
vsetu3: mov ah,cmkey ; Set Term Roll On/Off, auto roll back
mov bx,0 ; Use on/off table as help
mov dx,offset ontab ; Use on/off table
call comnd
jmp r ; bad keyword
push bx
mov ah,cmcfm ; get a confirm
call comnd
jmp vsetu0 ; did not get a confirm
nop
pop bx
mov vtroll,bl ; set roll state (0=no auto rollback)
jmp rskp ; return successfully
vsetu1: sal bx,1 ; Make bx a word index.
call vtrtns[bx] ; Dispatch.
jmp r ; Vsetup always returns +1.
jmp r ; Vsetup always returns +1.
; Set Term Color foreground, background
vsetu2:
mov ah,cmkey ; COLOR - get value
mov bx,offset colhlp ; use this help text
mov dx,offset colltb ; parse by this table
call comnd
jmp r
push bx ; save it
cmp ah,0 ; any response
jne vsetu2a ; ne = yes
jmp vsetux ; else give not confirmed msg
vsetu2a:
pop ax ; get value
mov bx,vtemu.att_ptr ; address of attributes byte
mov byte ptr [bx],al ; put the color in (plain, otherwise)
jmp rskp
vsetux: pop bx ; throw away
jmp r ; and exit complaining
; SET Term flags. These are the (near) equivalent of VT100 Setup mode values.
flgset: push bx ; Save bx for a second.
mov ah,cmkey ; Another keyword.
mov dx,vtable[bx] ; The table to use.
mov bx,0 ; Use default help.
call comnd
jmp flgse3
push bx ; Save switch value.
mov ah,cmcfm ; Confirm it.
call comnd
jmp flgse2
pop dx ; Restore switch value.
pop bx ; And index.
sar bx,1 ; Make it a byte index.
mov al,vtsflg[bx] ; Get the flag.
cmp dx,0 ; Set or clear?
je flgse1 ; Go clear it.
or vtemu.vtflgst,al ; Set the flag.
or vtemu.vtflgop,al ; in runtime flags too
jmp rskp ; Give good return.
flgse1: not al ; Complement
and vtemu.vtflgst,al ; Clear the indicated setup flag.
and vtemu.vtflgop,al ; Clear the indicated runtime flag.
jmp rskp ; Give good return.
flgse2: pop bx ; error exits
flgse3: pop bx
ret
; SET Term Tabstops Clear ALL
; SET Term Tabstops Clear AT n1, n2, ..., nx
; SET Term Tabstops At n1, n2, ..., nx
tabset: cld ; Make sure this is clear.
mov di,offset tmptabs ; clear our temp work area here.
mov cx,132 ; 132 columns
mov al,0 ; set "not touched" indicator
rep stosb ; in all tmptabs slots
mov ah,cmkey ; Parse keyword.
mov bx,offset clrhlp ; Use this help text.
mov dx,offset tabtab ; This table.
call comnd
jmp r
mov clrset,2 ; code for set a tab
cmp bl,0 ; Was it set or clear?
jne tabse1 ; SET - go parse column number(s).
mov clrset,1 ; code for clear at/all tab(s)
mov ah,cmkey ; CLEAR - parse ALL or AT
mov bx,offset allhlp ; Use this help text.
mov dx,offset alltab ; Parse ALL or AT.
call comnd
jmp r
cmp bx,0 ; ALL?
jne tabse1 ; ne = AT, clear at specific places.
mov al,1 ; ALL, means clear all tab stops.
mov cx,132 ; use 132 columns
mov di,offset tmptabs
rep stosb
mov ah,cmcfm ; Confirm it.
call comnd
jmp r
jmp tabcpy ; update active & coldstart tabs
tabse1: mov dx,offset tbshlp ; Tell them we want a column number.
cmp clrset,1 ; Clearing?
jne tabse2 ; ne = Set. we guessed right on help.
mov dx,offset tbchlp ; Yes - use this help instead.
tabse2: mov ah,cmtxt ; get text w/o white space
mov bx,offset rdbuf ; temp buffer
call comnd
jmp r
cmp ah,0 ; anything given?
jne tabse4 ; ne = yes.
jmp r ; else give not confirmed msg
tabse4: mov ah,cmcfm ; Parse confirm
mov bx,0 ; Use default help.
call comnd
jmp r ; not confirmed, complain.
mov si,offset rdbuf ; si = place where atoi wants text
tabse5: mov dx,si
call strlen ; current length of text
mov ah,cl ; put length where Atoi wants it
jcxz tabcpy ; nothing left
call atoi ; convert text to numeric in ax
jmp tabcpy ; no number available
mov bx,ax ; for subscripting in code below
dec bx ; Put column in range 0-79
cmp bx,0 ; check range (1-80 --> 0-79)
jl tbsbad ; l = too small. complain
cmp bl,132-1 ; more than the right most column?
jna tabse3 ; na = no, is ok
tbsbad: mov ah,prstr ; Not in range - complain and exit.
mov dx,offset tbserr
int dos
jmp rskp
tabse3: mov al,clrset ; Get value for setting or clearing.
mov tmptabs[bx],al ; store in tabs temp work array
jmp short tabse5 ; look for more
tabcpy: mov cx,132 ; update all active tab stops
mov si,vtemu.vttbst ; in terminal emulator's active buffer
mov di,vtemu.vttbs ; and in the cold-start buffer.
mov bx,0 ; subscript
tabcpy1:mov al,byte ptr tmptabs [bx] ; get a table entry into al
or al,al ; what is the code?
jz tabcpy3 ; z = do not touch
cmp al,2 ; set a tab?
je tabcpy2 ; e = set the tab
mov byte ptr [bx+si],0 ; clear the tab
mov byte ptr [bx+di],0 ; clear the tab
jmp short tabcpy3
tabcpy2:mov byte ptr [bx+si],0ffh ; set the tab
mov byte ptr [bx+di],0ffh ; set the tab
tabcpy3:inc bx ; inc subscript
loop tabcpy1
jmp rskp ; Give good return.
VTS endp ; end of Set Term things.
; Terminal Status display, called within STAT0: in MSSSET.[jrd]
VTSTAT proc near ;enter with di within sttbuf, save bx, di
push bx
push di
mov bx,ds
mov es,bx
cld
mov bx,offset vtstbl ; table of things to show
xor cx,cx
vtsta1: cmp word ptr [bx],0 ; end of table?
je vtstax ; e = yes
push bx
call [bx].sttyp ; call appropriate routine
pop bx ; cx incremented by output count
cmp cx,38 ; place for second display
jbe vtsta2 ; le = only half full
mov dx,offset crlf ; over half full. send cr/lf
mov ah,prstr
int dos
xor cx,cx ; say line is empty now
jmp short vtsta4
vtsta2: mov ax,cx
mov cx,38 ; where we want to be next time
sub cx,ax ; compute number of filler spaces
jcxz vtsta4 ; nothing to do
mov ah,conout
mov dl,' '
vtsta3: int dos ; fill with spaces
loop vtsta3 ; do cx times
mov cx,38 ; current column number
vtsta4: add bx,size stent ; look at next entry
jmp vtsta1 ; and do it
vtstax: pop di
pop bx
ret ; return to STAT0: in MSSSET.
; foreground/background color status
colstat proc near
mov dx,offset colst1
mov ah,prstr
int dos ; print first part of msg
mov bx,vtemu.att_ptr ; pointer to attributes byte
mov al,byte ptr [bx]
and al,0E0H ; color bits only, please
mov ah,0
mov bx,offset colltb
call prttab
add cx,18 ; about the # columns we used
ret
colstat endp
; Tabs Status display
tabstat proc near ; display tabs ruler for Status
push dx
jcxz tabsta0 ; empty line, as it should be
xor cx,cx ; used line, empty it
mov dx,offset crlf ; cr, lf
mov ah,prstr
int dos
tabsta0:mov si,vtemu.vttbst ; active tabs address, not shadow
mov cl,byte ptr low_rgt ; loop screen width-1 times
xor ch,ch ; clear high byte
dec si ; dec for inc below
xor ax,ax ; tens counter
tabsta1:mov dl,0F9H ; default position symbol ( mid-dot )
inc si ; start with position 1
inc al
cmp al,10 ; time to roll over?
jb tabsta2 ; b = not yet
mov al,0 ; modulo 10
inc ah
mov dl,ah ; display a tens-digit
add dl,'0'
cmp dl,'9' ; larger than 90?
jbe tabsta2 ; be = no
sub dl,10 ; roll over to 0, 1, etc
tabsta2:cmp byte ptr [si],0 ; is tab set?
je tabsta3 ; e = no
mov dl,'T' ; yes, display a 'T'
tabsta3:push ax
mov ah,conout ; console output
int dos
pop ax
loop tabsta1 ; loop til done (cx has count)
pop dx
mov cx,38 ; say line is used
ret
tabstat endp
; handler routines for status. All are called with bx/ stat ptr.
onoff proc near
call stmsg ; print the message
mov si,[bx].basval ; get base value
cmp si,0 ; any there?
je onoff1 ; e = no
mov si,[si] ; yes, use as base address
onoff1: add si,[bx].tstcel ; add offset of test cell
mov al,[si]
mov dx,offset onmsg
add cx,2 ; assume two byte on message
or al,al ; test value
jnz onoff2 ; nz = on
mov dx,offset offmsg
inc cx ; three byte message
onoff2: mov ah,prstr ; display the message
int dos
ret
onoff endp
; search a keyword table for a bit value, print that value. [jrd]
srchkb proc near
call stmsg ; first print message
call stbval ; get bit set or reset
mov ah,0 ; al has 0/1, high order is 0
mov bx,[bx].val2 ; this is table address
jmp prttab ; and look in table.
srchkb endp
; get address of test value in stent. Returns address in si. [jrd]
stbval proc near
mov si,[bx].basval ; get address of test value
cmp si,0 ; any there?
je stbva1 ; no, quit with no match
mov al,byte ptr [si] ; get byte value
mov ah,0
test al,vtemu.vtflgop ; bit test value against emulator flags byte
jz stbva1 ; z = they don't match
mov al,1 ; match
ret
stbva1: mov al,0 ; no match
ret ; and return it
stbval endp
; get address of test value in stent. Returns address in si
stval proc near
mov si,[bx].basval ; get base value
cmp si,0 ; any there?
je stva1 ; no, keep going
mov si,[si] ; yes, use as base address
stva1: add si,[bx].tstcel ; add offset of test cell
ret ; and return it
stval endp
; copy the message to the screen
stmsg proc near
mov si,[bx].msg ; get message address
stms1: lodsb ; get a byte
cmp al,'$' ; end of message?
je stms2 ; e = yes
mov dl,al ; display the character
mov ah,conout
int dos
inc cx ; count output chars
jmp stms1
stms2: ret
stmsg endp
; Print value from table. BX/address of table, AL/value of variable.
prttab: push cx ; save column count
mov cl,[bx] ; Number of entries in our table.
inc bx ; Point to the data.
prtt0: mov dl,[bx] ; Length of keyword.
inc bx ; Point to keyword.
mov dh,0
inc dx ; Account for "$" in table.
mov si,dx ; Put to index register.
cmp ax,[bx+si] ; Is this the one?
je prtt1
add bx,dx ; Go to end of keyword.
add bx,2 ; Point to next keyword.
dec cl ; Any more keywords to check?
jnz prtt0 ; Yes, go to it.
mov bx,offset prterr
prtt1: mov si,bx
pop cx ; recover column count
jmp stms1 ; copy in message
ret ; and return
VTSTAT endp ; end of Terminal set & status code
; Wait for the # of milliseconds in ax
; Thanks to Bernie Eiben for this one.
; Recalibrated for 8 MHz clock on NEC -- RFG
pcwait proc near
mov cx,300 ; inner loop counter for 1 millisecond
; was 240 for IBM PC
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
; set the current port.
; modified to use all 3 ports RFG
COMS PROC NEAR
mov dx,offset comptab
mov bx,0
mov ah,cmkey
call comnd
jmp r
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 coms0 ; Nope.
mov ax,offset port1
mov portval,ax
ret
coms0:
cmp flags.comflg,2 ; Using Com 2?
jne coms1 ; Nope.
mov ax,offset port2
mov portval,ax
ret
coms1:
cmp flags.comflg,3 ; Using Com 3?
jne comx ; this can't be!
mov ax,offset port3
mov portval,ax
ret
comx: pop bx
ret
COMS ENDP
; Test presently selected serial port for having a real 8250 UART.
; Return carry clear and clone = 0 if 8250 present,
; else carry set and clone = 'B' for system Bios or
; carry set and clone = 'N' for network.
; Method is to check UART's Interrupt Identification Register for high
; five bits being zero; IBM does it this way. Assumes port structure
; has been initialized with addresses of UART. 21 Feb 1987 [jrd]
; 29 May 1987 Add double check by reading Line Status Register. [jrd]
chkport proc near
chkport endp
; Set the baud rate for the current port, based on the value
; in the portinfo structure. Returns normally.
; lifted from the RAL version 2.0 RFG
; This routine should set the baud rate for the current port but it
; is actually done in SERINI.
dobaud proc near
push si ; [jrd]
push bx
mov bx,portval
mov si,[bx].baud ; get baud rate index pointer..
pop bx
mov al,baudtab[si] ; load up baud rate.........
pop si ; [jrd]
cmp al,0FFH ; Is Baud Rate Possible??
je badbaud
call serini ; Simply re-init port with new baud rate
dbret: ret
BadBaud: mov ah,prstr ; MS-DOS Print String...
mov dx,offset badbd ; point at message
int DOS
jmp dbret
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.
; lifted from RAL version 2.0 RFG
;* RAL..This routine appears to be called every time a status is done.
;* I will set baud rate first time, and simply return from then on.
;*
;* Page SA-2 APC III Programmer Reference Manual
GETBAUD PROC NEAR
push ax ; addition to fix (bug) in msster RFG
push bx
mov al,First ; Check to see if this is the first time....
cmp al,false
je GBRET ; Quit if baud rate already known.....
mov First,False ; Flip Flag...
mov bx,portval
mov [bx].baud,0Dh ; Default to 9600 Baud.....
call serini ; Set up port........
GBRET:
pop bx
pop ax
ret
GETBAUD ENDP
; Get Char from serial port buffer.
; skip returns if no character available at port,
; otherwise returns with char in al, # of chars in buffer in dx.
; Revised 22 May 1986, and again slightly 2 August 1986 by [jrd]
; 21 Feb 1987 Add support for Bios calls (Clone) [jrd]
; 25 April 1987 Add Netbios support, remove test for NUL and DEL. [jrd]
; partially taken from RAL version 2.0
; use call for all 3 RS232 ports RFG
PRTCHR PROC NEAR
push cx
push bx
mov ah,2 ; Get data length in CX...Page SE-12
int_rs232 ; Call APC ROM BIOS
or ch,cl ; check for zero in both halfs of CX
cmp ch,0 ; is CH 0?
je prtcn ; give up if no characters........
mov ah,4 ; Receive Character...by way of NEC BIOS
int_rs232
cmp ah,0 ; check return status
je prtc1 ; 0 = everything normal
; 1 = port not initialized
; 2 = (receive) buffer overflow
; 3 = timed out
call beep ; say something
cmp ah,2
je prtc2
mov ah,prstr ; say timed out
mov dx,offset intfail
int dos
jmp prtcx
prtc2: mov ah,prstr ; say buffer overflow
mov dx,offset inbfail
int dos
jmp prtcx
prtc1:
mov al,ch ; Character is returned in CH....
prtcx: pop bx
pop cx
ret
prtcn: ; no characters in queue, check console
pop bx
pop cx
jmp rskp
PRTCHR ENDP
; Network Receive packet routine. Request a net packet with no-wait option.
; Return carry clear if success. If failure, reset serial port (Server mode
; reinits serial port) and return carry set. No entry setup needed.
RECEIVE PROC NEAR ; receive network session pkt
RECEIVE ENDP
; Network Receive post processing interrupt routine.
; Copy chars from rcvbuf to circular buffer source, act on xon/xoff,
; clear rposted interlock flag. At entry, CS is our code segment,
; es:bx points to scb, netbios stack, interrupts are off.
RPOST PROC FAR ; network receive post interrupt routine
RPOST 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.
; 21 Feb 1987 Add support for Bios calls (Clone) [jrd]
; 25 April 1987 Add Netbios support [jrd]
; 16 May 1987 Add entry point OUTCH2 for non-flow controlled sending to
; prevent confusion of flow control logic at top of outchr; used by receiver
; buffer high/low water mark flow control code. [jrd]
; XON/XOFF is handled by the BIOS an NEC RFG
OUTCHR PROC NEAR
push dx
push bx
mov al,ah ; parity works on AH
call dopar ; do parity work before sending
mov ah,3 ; NEC ROM BIOS send character in AL
int_rs232 ; Call ROM BIOS send character in AL
cmp ah,0 ; check return status
je outc1 ; 0 = everything normal
; 1 = port not initialized
; 2 = (receive) buffer overflow
; 3 = timed out
call beep ; say something
mov ah,prstr
mov dx,offset outfail
int dos
pop bx
pop dx
ret ; and return (abnormally?)
outc1:
pop bx
pop dx
jmp rskp
OUTCHR ENDP
; Network Send packet routine. Send xmt scb with no-wait option. Waits
; up to 6 seconds for current Send to complete before emitting new Send.
; Failure to Send resets serial port (Server mode allows reiniting of serial
; port). Returns carry clear for success, carry set for failure.
; Enter with xmtcnt holding length of data in xmtbuf to be sent.
SEND PROC NEAR ; Network. Send session packet
SEND ENDP
; Network Send packet completion interrupt routine. At entry CS is our
; code segment, es:bx points to scb, netbios stack, interrupts are off.
SPOST PROC NEAR ; post routine for Send packets
SPOST ENDP
; dispatch prebuilt network session scb, enter with bx pointing to scb.
; returns status in al (and ah too). Allows STARLAN Int 2ah for netint.
SESSION PROC NEAR
SESSION ENDP
; Make a virtual circuit Session, given preset scb's from proc chknet.
; For Server mode, does a Listen to '*', otherwise does a Call to indicated
; remote node. Updates vcid number in scb's. Shows success or fail msg.
; Updates network status byte pcnet to 2 if session is established.
; Does nothing if a session is active upon entry; otherwise, does a network
; hangup first to clear old session material from adapter board. This is
; the second procedure to call in initializing the network for usage.
SETNET PROC NEAR ; Network, make a connection
SETNET ENDP
; Called only when Kermit exits. Name passed to mssker by proc chknet
; in word netdone.
NETCLOSE PROC NEAR ; close entire network connection
NETCLOSE ENDP
; Start connection process to network. Obtains Network board local name
; and appends '.K' to form Kermit's local name (removed when Kermit exits).
; If no local name is present then use name 'mskermit.K'.
; Sets local name in scb's for xmt, rcv, lsn. (Does not need DOS 3.x)
; Sets NETDONE pointer to procedure netclose for Kermit exit.
; Verifies existance of interrupt 5ch support, verifies vendor specific
; support for BREAK and other features, sets network type bit in nettype,
; sets BREAK support in nsbrk, hangsup old session if new node name given,
; fills in local and remote node names and name number in scbs (including ISN
; names for STARLAN), and sets network status byte pcnet to 0 (no net) or
; to 1 (net ready). This is the first procedure called to init network usage.
; Byte count of new host name is in temp from COMS.
chknet proc near
chknet endp
; local routine to see if we have to transmit an xon
; its handled by the hardware on the NEC RFG
chkxon proc near
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]
; 22 June 1986 Don't send null char if not using flow control. [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 ; check for null char
jz ihostr1 ; z = null, don't send it
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
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 ; check for null char
jz ihostr1 ; z = null, don't send it
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
; Send a break out the current serial port. Returns normally.
; an APC specific version RFG
SENDBR PROC NEAR
push dx
push cx
push ax
mov ah,prstr ; tell the user on the status line
mov dx,offset saybr ; that we're sending it
int dos
mov ah,5 ; set the break bit
mov al,stbrk
int_rs232
mov ax,275 ; # of ms to wait
call pcwait ; hold break for desired interval
mov ah,5 ; and clear the break bit
mov al,stnorm
int_rs232
pop ax
pop cx
pop dx
ret
SENDBR ENDP
SENDBL PROC NEAR ; Send a long break
push dx
push cx
push ax
mov ah,prstr ; tell the user on the status line
mov dx,offset saybr ; that we're sending it
int dos
mov ah,5 ; set the break bit
mov al,stbrk
int_rs232
mov ax,1800 ; # of ms to wait
call pcwait ; hold break for desired interval
mov ah,5 ; and clear the break bit
mov al,stnorm
int_rs232
pop ax
pop cx
pop dx
ret
SENDBL ENDP
; Initialization for using serial port. This routine performs
; any initialization necessary for using the serial port, including
; setting up interrupt routines, setting buffer pointers, etc.
; Doing this twice in a row should be harmless (this version checks
; a flag and returns if initialization has already been done).
; SERRST below should restore any interrupt vectors that this changes.
;************* RAL *****************************************************
;* Page SE-10 MS-DOS Programmers Manual
;* Performs Serial Port Initialization.............
;***********************************************************************
; Various mods to allow 3 ports and setting timeout parameters so that we
; won't hang forever if the line dies. RFG
SERINI PROC NEAR
call serrst ; Turn off the unused ports to avoid
; characters coming in and causing a
; d.e.l.a.y.e.d CRASH
push es
push di
push si ; additional save RFG
mov AX,datas ; point at start of this segement?
mov ES,AX
mov DI,offset source ; Point at Serial Buffer....
mov bx,portval
mov parmsk,0ffh ; parity mask, assume parity is None. [jrd]
cmp [bx].parflg,parnon ; is it None?
je serin3 ; e = yes
mov parmsk,07fh ; no, pass lower 7 bits as data
serin3:
mov si,[bx].baud ; get baud rate index pointer..
mov ah,[bx].floflg
mov al,baudtab[si] ; load up baud rate.........
; AH = 1 XON/XOFF flow control
; AH = 0 No Flow control
; Page SE-10 NEC Programmer Ref manual
cmp AH,0 ; doing flow control?
je NoFlow ; 0 if not flow control
mov ah,1 ; Init with Xon/Xoff
NoFlow:
mov ch,uart ; set up various UART parameters
mov dx,bufsiz ; load with Buffer Size...bufsiz in mssdef.h
; (currently 2048 bytes)
; NB that since the BIOS uses 1 word per char,
; this means the buffer is really only
; bufsiz/2 long. (1 sec at 9600 baud)
; Due to a bug in the BIOS, the size is
; miscalculated by the 20 bytes used at
; the front by the BIOS for pointers, etc.;
; without the pad put into the 'source'
; definition, the handler would simply
; overwrite the following data area.
; This is a circular buffer managed entirely
; by the BIOS with XON set at 3/4 DX and
; XOFF set at 1/4 DX.
mov bh,2 ; time out on send is this number *500 ms
; 0 = infinity RFG
; this should /not/ affect waiting for XON
; from the host (handled in BIOS again)
mov bl,4 ; time out on receive is this number *500 ms
; 0 = infinity RFG
; since we're checking buffer before we read
; (see prtchr), shouldn't be necessary.
mov CL,stnorm ; see NEC Ref Guide, Page SE-11 RFG
mov CH,uart ; set up various parameters.... again
int_rs232 ; Call NEC Rom
cmp ah,0 ; Did everything go ok??
je serinx ; continue if so...
call beep ; otherwise, notify the authorities
mov ah,prstr
mov dx,offset initfail
int dos
serinx:
pop si ; additional restore RFG
pop di
pop es
ret ; We're done. [21c]
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.
; in NEC land, we simply turn everyone OFF. RFG
SERRST PROC NEAR
push es
push di
push si
mov AX,datas ; point at start of this segement?
mov ES,AX
mov DI,offset source ; Point at Serial Buffer....
mov ch,uart ; just as a formality
mov cl,stoff ; now we turn unused ports dead off 'cause
; if we don't, and come characters come in,
; we get a d.e.l.a.y.e.d crash!
mov ah,0 ; initialize port mode
mov al,0 ; baud probably irrelevant
mov dx,bufsiz ; just to give it a valid number
mov bh,0 ; zip to the high byte
mov bl,0 ; turn port 1 off
mov si,bx
int 1EH ; could have used 1AH here
mov ch,uart
mov cl,stoff
mov ah,0
mov al,0
mov dx,bufsiz
mov bh,0
mov bl,1 ; turn port 2 off
mov si,bx
int 1EH
mov ch,uart
mov cl,stoff
mov ah,0
mov al,0
mov dx,bufsiz
mov bh,0
mov bl,2 ; turn port 3 off
mov si,bx
int 1EH
pop si
pop di
pop es
ret ; All done.
SERRST ENDP
; Dummy Interrupt 14H to defeat DOS interference with serial port when CTTY
; and Kermit use the port simultaneously. If ports differ then chain DOS to
; original Int 14H Bios code. Else return dummy status=ok reports and
; Backspace for Read, ignore char for Write.
; Entered with AH = function request, AL = char to be sent, DX = com port num
; CS is our code segment, DS is DOS's, SS is ours or DOS's, interrupts off.
; 25 June 1987 [jrd]
SERDUM PROC FAR
SERDUM ENDP
; serial port interrupt routine. This is not accessible outside this
; module, handles serial port receiver interrupts.
; Revised on 22 May 1986, again 2 August 1986 to run at 38.4kb on PC's. [jrd]
; Srcpnt holds offset, within buffer Source, where next rcv'd char goes.
; Count is number of chars now in buffer, and oldest char is srcpnt-count
; done modulo size of Source. All pointer management is handled here.
; Control-G char substituted for char(s) lost in overrun condition. [jrd]
; Upgraded to read cause of interrupt from interrupt ident reg (accepts only
; data ready), chain to old interrupt if source is not our device. [jrd]
SERINT PROC FAR
SERINT ENDP
DTRLOW PROC NEAR ; Global proc to Hangup the Phone or Network
; by making DTR and RTS low (phone). [jrd]
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
; 5 April 1987 Add 500 millisec wait with lines low before returning. [jrd]
; Calling this twice without intervening calls to serini should be harmless.
; If network then call nethangup procedure to hangup the session without
; losing local name information.
; Returns normally.
serhng proc near ; clear modem's delta status bits and lower DTR & RTS
push ax
mov ah,5 ; direct to the UART
mov al,stdtr ; lower the boom
int_rs232 ; drop the DTR
mov ax,500 ; hold it low for a bit
call pcwait
pop ax
ret
serhng 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