home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
kermit.columbia.edu
/
kermit.columbia.edu.tar
/
kermit.columbia.edu
/
extra
/
nyenhuis3.arc
/
MSSSHO.ASM
< prev
next >
Wrap
Assembly Source File
|
1990-01-14
|
71KB
|
2,413 lines
name msssho
; File MSSSHO.ASM
include mssdef.h
; Show & Status commands
; edit history:
; Last edit 14 Jan 1990
public shorx, shomac, shcom, shfile, shlog, shpro, shscpt, shserv
public shterm, status, statc, stat0, srchkw, srchkb, shmem
public partab, destab, seoftab, blktab, dmpname, lsesnam, lpktnam
public ltranam, incstb, inactb, rxoffmsg, rxonmsg, lnout, lnouts
public shosta, begtim, endtim, fsta, ssta ; statistics procedures
public rtmsg, rppos, stpos, rprpos, sppos, perpos, cxerr, frpos
public fmtdsp, ermsg, msgmsg, init, cxmsg, intmsg, kbpr, perpr
public winpr, windflag, pktsize, clrfln, oldkbt, oldper
public wrpmsg
mcclen equ macmax*10
; equates for screen positioning
scrser equ 0209H ; place for server state display line
scrfln equ 0316H ; place for file name
scrkb equ 0416H ; Place for percent transferred
scrper equ 0516H ; Place for Kbytes transferred
scrst equ 0616H ; Place for status
scrnp equ 0816H ; Place for number of packets
scrsz equ 0916h ; packet size
scrnrt equ 0A16H ; Place for number of retries
screrr equ 0B16H ; Place for error msgs
scrmsg equ 0C16H ; Last message position
scrsp equ 0E00H ; Place for send packet
scrrp equ 1300H ; Place for receive packet
scrrpr equ 1700H ; Prompt when Kermit ends (does cr/lf)
data segment
extrn termtb:byte, comptab:byte, portval:word,dtrans:byte,rdbuf:byte
extrn trans:byte, curdsk:byte, flags:byte, maxtry:byte, comand:byte
extrn spause:byte, taklev:byte, takadr:word, alrhms:byte, bdtab:byte
extrn denyflg:word, rxtable:byte, mcctab:byte, script:byte
extrn errlev:byte, luser:byte, srvtmo:byte, mccptr:word, thsep:byte
extrn scpbuflen:word, setchtab:byte, xfchtab:byte, xftyptab:byte
extrn tfilsz:word, diskio:byte, tloghnd:word, dosnum:word
extrn templp:byte, windused:byte, numpkt:word, verident:byte
extrn decbuf:byte
crlf db cr,lf,'$'
eqs db ' = $'
spaces db ' $'
outlin1 db 10 dup (' '),'$'
;;; version appears here
outlin2 db cr,lf,lf
db cr,lf,' File name:'
db cr,lf,' KBytes transferred:'
db cr,lf
db cr,lf
db cr,lf
db cr,lf,' Number of packets:'
db cr,lf,' Packet length:'
db cr,lf,' Number of retries: 0'
db cr,lf,' Last error:'
db cr,lf,' Last message:'
db cr,lf,'$'
permsg db cr,' Percent transferred:$'
cxzhlp db 'X: cancel file, Z: cancel group, E: exit nicely,'
db ' C: exit abruptly, Enter: retry$'
erword db cr,lf,'Error: $'
msword db cr,lf,'Message: $'
rtword db cr,lf,'Retry $'
cxzser db cr,lf,'Type X to cancel file, Z to cancel group,'
db cr,lf,' E to exit nicely, C to quit abruptly,'
db cr,lf,' or Enter to retry',cr,lf,'$'
windmsg db ' Window slots in use:$'
windflag db 0 ; flag to init windows msg, 0=none
oldwind db -1 ; last windows in use value
oldper dw 0 ; old percentage
oldkbt dw 0 ; old KB transferred
wrpmsg db 0 ; non-zero if we wrote percent message
fmtdsp db 0 ; non-zero if formatted display in use
prepksz dw 0 ; previous packet size
onehun dw 100
denom dw 0
temp dw 0
temp1 dw 0
shmcnt dw 0
sixteen dw 16
infms1 db 'Server mode: type Control-C to exit',cr,lf,'$'
infms7 db 'File interrupt',cr,lf,'$'
infms8 db 'File group interrupt',cr,lf,'$'
infms9 db 'User ',5eh,' interrupt',cr,lf,'$'
partab db 5
mkeyw 'none (8-bit data) ',PARNON
mkeyw 'even (7-bit data) ',PAREVN
mkeyw 'odd (7-bit data) ',PARODD
mkeyw 'mark (7-bit data) ',PARMRK
mkeyw 'space (7-bit data) ',PARSPC
destab db 3
mkeyw 'Disk',1
mkeyw 'Printer',0
mkeyw 'Screen',2
seoftab db 2
mkeyw 'Ctrl-Z',1
mkeyw 'NoCtrl-Z',0
warntab db 3 ; File Warning table
mkeyw 'overwrite',1
mkeyw 'rename',0
mkeyw 'no-supersede',4
; What type of block check to use
blktab db 3
mkeyw '1-char-checksum',1
mkeyw '2-char-checksum',2
mkeyw '3-char-CRC-CCITT',3
modtab db 3 ; Mode line status
mkeyw 'off',0
mkeyw 'on',1
mkeyw 'on (owned by host)',2
ontab db 2
mkeyw 'off',0
mkeyw 'on',1
unkctab db 2 ; unknown character-set disposition
mkeyw 'keep',0
mkeyw 'cancel',1
logsta db 8 ; Log Status table
mkeyw 'off',logoff ; suspended or no logging
mkeyw 'Packet',logpkt
mkeyw 'Session',logses
mkeyw 'Packet+Session',logpkt+logses
mkeyw 'Transaction',logtrn
mkeyw 'Packet+Transaction',logpkt+logtrn
mkeyw 'Session+Transaction',logses+logtrn
mkeyw 'Packet+Session+Transaction',logpkt+logses+logtrn
dissta db 6 ; Status of Display mode [jrd]
mkeyw 'Quiet, 7-bit',dquiet
mkeyw 'Regular, 7-bit',dregular
mkeyw 'Serial, 7-bit',dserial
mkeyw 'Quiet, 8-bit',dquiet+d8bit
mkeyw 'Regular, 8-bit',dregular+d8bit
mkeyw 'Serial, 8-bit',dserial+d8bit
endistab db 2 ; Server ENABLE/DISABLE status
mkeyw 'enabled',0
mkeyw 'disabled',1
inactb db 2 ; Set Input Timeout Action
mkeyw 'Proceed',0 ;[jrs]
mkeyw 'Quit',1 ;[jrs]
incstb db 2 ;[jrs] Set Input Case
mkeyw 'Ignore',0dfh ;[jrs]
mkeyw 'Observe',0ffh ;[jrs]
; Statistics data storage area
fsta statinfo <> ; for last operation values
ssta statinfo <> ; for session values
sflag dw 0 ; flag for send (1) or receive (0)
; 80h = begtim started
statmsg db cr,lf,lf,' Last Transfer '
db ' Entire Session'
db cr,lf,' Item Sent Rec''d '
db ' Sent Rec''d',cr,lf,'$'
fchmsg db cr,lf,' File characters: $'
spmsg db cr,lf,' Comms port chars: $'
pktmsg db cr,lf,' Packets: $'
nakmsg db cr,lf,' NAKs: $'
retmsg db cr,lf,' Packet retries: $'
timemsg db cr,lf,lf,' Protocol time, secs:$'
chpsmsg db cr,lf,' File characters/sec:$'
spedmsg db cr,lf,' Comms port bits/sec:$'
sndmsg db 'Sent ',0
rcvmsg db 'Recv ',0
date db '00:00:00 00 Jan 1980',0
datelen equ $-date-1
atmsg db cr,lf,' at '
atlen equ $-atmsg
fasmsg db ' as '
faslen equ $-fasmsg
fsucmsg db ', completed, bytes: ',0
fbadmsg db ', failed, bytes: ',0
fintmsg db ', interrupted, bytes: ',0
months db 'JAN','FEB','MAR','APR','MAY','JUN','JUL','AUG','SEP'
db 'OCT','NOV','DEC'
even
tens dd 1,10,100,1000,10000,100000,1000000,10000000,100000000
dd 1000000000
tenslen equ ($-tens) / 4 ; number of double words in array tens
lnoutsep db 0 ; non-zero to separate thousands in lnout
; end statistics data area
sixty dw 60
ten dw 10
logmsg db 'Kind Default filename Status$'
nologmsg db '(not active)$'
lsesmsg db 'Session (Session.log)$'
lpktmsg db 'Packets (Packet.log)$'
ltramsg db 'Transactions (Transact.log)$'
dmpmsg db 'Screen Dump, in Connect mode$'
dmpmsg2 db 'Dump screen: $' ; for general STATUS display
modst db 'Mode line: $'
locst db 'Local echo: $'
duphlf db 'Duplex: half$'
dupful db 'Duplex: full$'
belon db 'Ring bell after transfer$'
beloff db 'No bell after transfer$'
vtemst db 'Terminal emulation: $' ; terminal emulator
portst db 'Communications port: $'
capmsg db 'Logging: $'
eofmsg db 'EOF mode: $'
flost db 'No flow control used$'
floxmsg db 'Flow control: xon/xoff $'
handst db 'Handshake used: $'
destst db 'Destination: $'
xtypmsg db 'File Type: $'
xchmsg db 'Transfer char-set: $'
chmsg db 'File char set: $'
unkmsg db 'Unknown-char-set: $'
diskst db 'Path: $'
blokst db 'Block check used: $'
sqcst db 'Send control char prefix: $'
rqcst db 'Receive control char prefix: $'
debon db 'Debug: $'
flwon db 'Warning (file names): $'
parmsg db 'Parity: $'
abfdst db 'Incomplete file: discard$'
abfkst db 'Incomplete file: keep$'
sndmsg1 db 'Send Delay: $'
sndmsg2 db ' sec, Pause: $'
sndmsg3 db ' ms$'
msohst db 'Start-of-Packet char S: ',5eh,'$'
meolst db 'End-of-Packet char S: ',5eh,'$'
msrec db ' R: ',5eh,'$'
msrecv db ' R: $'
tmost db 'Timeout (seconds) S: $'
stimst db 'Send timeout (seconds): $'
rtimst db 'Receive timeout (seconds): $'
spakst db 'Send packet size (maximum): $'
rpakst db 'Receive packet size (maximum): $'
spakst1 db 'Send packet size (current): $'
rpakst1 db 'Receive packet size (current): $'
snpdst db 'Number of padding chars S: $'
spadst db 'Padding char S: ',5eh,'$'
retrymsg db 'Retry send/receive packet limit: $'
swinst db 'Sliding window slots (max): $'
dispst db 'Display: $'
timmsg db 'Timer: $'
srvmsg db 'Timeout (sec) waiting for a transaction: $'
escmes db 'Escape character: $'
scpmsg db 'Script commands Echo, If, Input, Output, Pause, Reinput,'
db ' Transmit, Wait$'
sechmsg db 'Input echoing: $'
scasmsg db 'Case sensitivity: $'
stmo1msg db 'Timeout (seconds): $'
stmo2msg db 'Timeout-action: $'
sxfilmsg db 'Transmit fill-empty-line: $'
sxlfmsg db 'Transmit line-feeds-sent: $'
sxpmtmsg db 'Transmit prompt character: $'
stbufmsg db 'INPUT-buffer-length: $'
takon db 'Take-echo: $'
atton db 'Attributes packets: $'
sachmsg db ' Character-set: $'
sadtmsg db ' Date-Time: $'
salnmsg db ' Length: $'
satymsg db ' Type: $'
baudrt db 'Speed: $'
unrec db 'unknown$'
kbdmsg db 'Keyboard translation: $'
stcntmsg db 'Take/Macro COUNT: $'
stargmsg db 'Take/Macro ARGC: $'
nonemsg db 'not active$'
sterlmsg db 'Errorlevel: $'
stalrmsg db 'Alarm time: $'
lusrmsg db 'Login Username: $'
servmsg db 'Server commands available to remote user: $'
scwdmsg db 'CD/CWD: $'
sdelmsg db 'DELETE: $'
sdirmsg db 'DIR: $'
sfinmsg db 'FINISH: $'
sgetmsg db 'GET: $'
shstmsg db 'HOST: $'
skermsg db 'KERMIT: $'
slogmsg db 'LOGIN: $'
ssndmsg db 'MESSAGE:$'
sspcmsg db 'SPACE: $'
stypmsg db 'TYPE: $'
stekmsg db 'Tek4010: $'
nonmsg db 'none$'
onmsg db 'on'
offmsg db 'off'
moremsg db cr,lf,'-- More --$'
rxoffmsg db cr,lf,' Input Translation is off$'
rxonmsg db cr,lf,' Input Translation is on$'
shormsg db cr,lf,' Translation table of received byte codes while'
db ' in CONNECT mode -'
db cr,lf,' Format: [received byte (decimal) -> local byte'
db ' (decimal)]',cr,lf,'$'
shopm1 db ' [\$' ; Show Translation material
shopm2 db ' -> \$'
shopm3 db '] $'
shmmsg db ' name of macro, or press ENTER to see all$'
shom9m1 db cr,lf,' Free space (bytes) for names: $'
shom9m3 db cr,lf,' No macro(s)$'
shom9m4 db '<cr>$'
memmsg1 db cr,lf,' DOS free memory (bytes):$'
memmsg2 db cr,lf,' Total free bytes: $'
prterr db '?Unrecognized value$'
lpktnam db 'Packet.log',54 dup (0) ; default packet log filename
lsesnam db 'Session.log',54 dup (0); default capture/session filename
ltranam db 'Transact.log',52 dup (0); default transaction log filename
dmpname db 'Kermit.scn',54 dup (0) ; file name for screen dumps [jrd]
even
stent struc ; structure for status information table sttab
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
sttab stent <baudprt> ; STATUS
stent <srchkw,vtemst,termtb,flags.vtflg> ; terminal emulator
stent <srchkw,portst,comptab,flags.comflg>
stent <srchkw,modst,modtab,flags.modflg>
stent <srchkw,parmsg,partab,parflg,portval>
stent <stlnum,spakst,,dtrans.slong>
stent <onoff,locst,,ecoflg,portval>
stent <stlnum,rpakst,,dtrans.rlong>
stent <msg2,flost,floxmsg,floflg,portval>
stent <prsar,msohst,msrec,trans.ssoh,trans.rsoh>
stent <prhnd>
stent <prsar,meolst,msrec,trans.seol,trans.reol>
stent <drnum,diskst,,curdsk>
stent <prsarv,tmost,msrecv,dtrans.stime,trans.rtime>
stent <srchkw,flwon,warntab,flags.flwflg>
stent <prsnd, sndmsg1>
stent <srchkw,destst,destab,flags.destflg>
stent <stnum,retrymsg,,maxtry>
stent <msg2,abfkst,abfdst,flags.abfflg>
stent <srchkw,blokst,blktab,dtrans.chklen>
stent <srchkw,eofmsg,seoftab,flags.eofcz>
stent <srchkw,capmsg,logsta,flags.capflg>
stent <msg2,beloff,belon,flags.belflg>
stent <srchkw,debon,logsta,flags.debug>
stent <onechr,escmes,,trans.escchr>
stent <onoff,timmsg,,flags.timflg>
stent <srchkw,dispst,dissta,flags.remflg>
stent <pasz,dmpmsg2,offset dmpname>
stent <msg2,dupful,duphlf,duplex,portval>
stent <srchkw,kbdmsg,ontab,flags.xltkbd>
stent <vtstat>
dw 0 ; end of table
stcom stent <srchkw,portst,comptab,flags.comflg> ; SHOW COMMS
stent <baudprt>
stent <onoff,locst,,ecoflg,portval>
stent <srchkw,parmsg,partab,parflg,portval>
stent <prhnd>
stent <msg2,flost,floxmsg,floflg,portval>
stent <msg2,dupful,duphlf,duplex,portval>
stent <srchkw,dispst,dissta,flags.remflg>
stent <srchkw,debon,logsta,flags.debug>
dw 0
stfile stent <drnum,diskst,,curdsk> ; SHOW FILE
stent <msg2,abfkst,abfdst,flags.abfflg>
stent <srchkw,destst,destab,flags.destflg>
stent <srchkw,flwon,warntab,flags.flwflg>
stent <srchkw,eofmsg,seoftab,flags.eofcz>
stent <srchkww,chmsg,setchtab,flags.chrset>
stent <srchkw,xtypmsg,xftyptab,dtrans.xtype>
stent <srchkw,xchmsg,xfchtab,dtrans.xchset>
stent <stmsg,atton>
stent <srchkw,unkmsg,unkctab,flags.unkchs>
stent <srchkb,sachmsg,ontab,attchr,flags.attflg>
stent <stmsg,spaces>
stent <srchkb,sadtmsg,ontab,attdate,flags.attflg>
stent <stmsg,spaces>
stent <srchkb,salnmsg,ontab,attlen,flags.attflg>
stent <stmsg,spaces>
stent <srchkb,satymsg,ontab,atttype,flags.attflg>
dw 0
stlog stent <stmsg,logmsg> ; SHOW LOG
stent <stmsg,lpktmsg>
stent <msg2b,nologmsg,lpktnam,logpkt,flags.capflg>
stent <stmsg,lsesmsg>
stent <msg2b,nologmsg,lsesnam,logses,flags.capflg>
stent <stmsg,ltramsg>
stent <msg2b,nologmsg,ltranam,logtrn,flags.capflg>
stent <stmsg,dmpmsg>
stent <stmsg,dmpname>
dw 0
stpro stent <stlnum,spakst,,dtrans.slong> ; SHOW PROTOCOL
stent <stlnum,rpakst,,dtrans.rlong>
stent <stlnum,spakst1,,trans.slong>
stent <stlnum,rpakst1,,trans.rlong>
stent <stnum,stimst,,dtrans.stime>
stent <stnum,rtimst,,trans.rtime>
stent <onechr,sqcst,,dtrans.squote>
stent <onechr,rqcst,,trans.rquote>
stent <prsar,msohst,msrec,trans.ssoh,trans.rsoh>
stent <prsarv,snpdst,msrecv,dtrans.spad,trans.rpad>
stent <prsar,meolst,msrec,trans.seol,trans.reol>
stent <prsar,spadst,msrec,dtrans.spadch,trans.rpadch>
stent <prsnd,sndmsg1>
stent <srchkw,blokst,blktab,dtrans.chklen>
stent <stnum,retrymsg,,maxtry>
stent <stnum,swinst,,dtrans.windo>
stent <onoff,timmsg,,flags.timflg>
stent <prhnd>
stent <srchkw,debon,logsta,flags.debug>
stent <srchkw,capmsg,logsta,flags.capflg>
stent <srchkw,xtypmsg,xftyptab,dtrans.xtype>
stent <srchkww,chmsg,setchtab,flags.chrset>
stent <stmsg,atton>
stent <srchkw,xchmsg,xfchtab,dtrans.xchset>
stent <srchkb,sachmsg,ontab,attchr,flags.attflg>
stent <stmsg,spaces>
stent <srchkb,sadtmsg,ontab,attdate,flags.attflg>
stent <stmsg,spaces>
stent <srchkb,salnmsg,ontab,attlen,flags.attflg>
stent <stmsg,spaces>
stent <srchkb,satymsg,ontab,atttype,flags.attflg>
dw 0
dw 0
stscpt stent <stmsg,scpmsg> ; SHOW SCRIPT
stent <onoff,sechmsg,,script.inecho>
stent <srchkw,scasmsg,incstb,script.incasv>
stent <stlnum,stmo1msg,,script.indfto>
stent <srchkw,stmo2msg,inactb,script.inactv>
stent <stalr,stalrmsg>
stent <stlnum,stbufmsg,,scpbuflen>
stent <stnum,sterlmsg,,errlev>
stent <prfil>
stent <onoff,sxlfmsg,,script.xmitlf>
stent <onechr,sxpmtmsg,,script.xmitpmt>
stent <stcnt,stcntmsg>
stent <srchkw,takon,ontab,flags.takflg>
stent <starg,stargmsg>
dw 0
stserv stent <pasz,lusrmsg,offset luser> ; SHOW SERVER
stent <stmsg,servmsg>
stent <srchkb,scwdmsg,endistab,cwdflg,denyflg>
stent <srchkb,skermsg,endistab,kerflg,denyflg>
stent <srchkb,sdelmsg,endistab,delflg,denyflg>
stent <srchkb,slogmsg,endistab,pasflg,denyflg>
stent <srchkb,sdirmsg,endistab,dirflg,denyflg>
stent <srchkb,ssndmsg,endistab,sndflg,denyflg>
stent <srchkb,sfinmsg,endistab,finflg,denyflg>
stent <srchkb,sspcmsg,endistab,spcflg,denyflg>
stent <srchkb,sgetmsg,endistab,getsflg,denyflg>
stent <srchkb,stypmsg,endistab,typflg,denyflg>
stent <srchkb,shstmsg,endistab,hostflg,denyflg>
dw 0
stserv2 stent <stnum,srvmsg,,srvtmo>
dw 0
stterm stent <srchkw,vtemst,termtb,flags.vtflg> ; SHOW TERMINAL
stent <srchkw,dispst,dissta,flags.remflg>
stent <srchkb,stekmsg,endistab,tekxflg,denyflg>
stent <onechr,escmes,,trans.escchr>
stent <srchkw,modst,modtab,flags.modflg>
stent <srchkw,kbdmsg,ontab,flags.xltkbd>
stent <vtstat>
dw 0
data ends
code segment
extrn comnd:near, decout:near, locate:near, prtscr:near, strlen:near
extrn getbaud:near, vtstat:near, shomodem:near
extrn cmblnk:near, prtasz:near, putmod:near, clrmod:near
extrn poscur:near, clearl:near, nout:near, dodec:near
assume cs:code, ds:data, es:nothing
; Display asciiz message pointed to by DS:DX on Last error line
ERMSG PROC NEAR
test flags.remflg,dquiet ; quiet screen?
jnz ermsgx ; nz = yes
push si ; position cursor to Last Error line
push dx ; save preexisting message pointer
test flags.remflg,dserial ; serial mode display?
jnz erpo1 ; nz = yes
cmp fmtdsp,0 ; formatted display?
jne erpo2 ; ne = yes
erpo1: mov ah,prstr
mov dx,offset erword ; put out word Error:
int dos
jmp short erpo3
erpo2: mov dx,screrr
call poscur
call clearl ; clear the line
erpo3: pop dx ; restore old pointer
mov si,dx ; string pointer
mov cx,10 ; try ten items
cld
ermsg1: lodsb
cmp al,' ' ; strip these leading spaces
loope ermsg1
dec si ; backup to non-space
push dx ; preserve caller's dx
mov dx,si
call prtasz ; display asciiz message
pop dx
pop si
ermsgx: ret
ERMSG ENDP
; Decode and display Message packet pointed to by SI.
MSGMSG PROC NEAR
test flags.remflg,dquiet ; quiet screen?
jnz msgmsgx ; nz = yes
cmp [si].datlen,0 ; anything present?
je msgmsgx ; e = no
test flags.remflg,dserial ; serial mode display?
jnz msgms1 ; nz = yes
cmp fmtdsp,0 ; formatted display?
jne msgms2 ; ne = yes
cmp flags.xflg,0 ; packet header seen?
je msgms2 ; e = no
msgms1: mov ah,prstr
mov dx,offset msword ; put out word Message:
int dos
jmp short msgms3 ; display the message
msgms2: push si
mov dx,scrmsg ; Last message line
call poscur
call clearl ; clear the line
pop si
msgms3: call dodec ; decode to decbuf, SI is pktinfo ptr
mov dx,offset decbuf ; final error message string, asciiz
call prtasz ; display asciiz message
msgmsgx:ret
MSGMSG ENDP
; Show number of retries message
RTMSG PROC NEAR
test flags.remflg,dquiet ; quiet display mode?
jnz rtmsx ; nz = yes
test flags.remflg,dserver ; in server mode?
jnz rtms0 ; nz = yes
cmp flags.xflg,0 ; receiving to screen?
jne rtmsx ; ne = yes
cmp fmtdsp,0 ; formatted display?
je rtms1 ; e = no, do as normal
rtms0: test flags.remflg,dserial ; serial mode display?
jnz rtms1 ; nz = yes
push ax
push dx
push si
mov dx,scrnrt
call poscur
call clearl
pop si
jmp short rtms3
rtms1: push ax
push dx
mov dx,offset rtword ; display word Retry
mov ah,prstr
int dos
rtms3: mov ax,fsta.pretry ; number of retries
call decout ; write the number of group retries
pop dx
pop ax
rtmsx: ret
RTMSG ENDP
; Reassure user that we acknowledge his ^X/^Z
INTMSG PROC NEAR
cmp flags.cxzflg,0 ; anything there?
je int1 ; e = no
test flags.remflg,dserver ; server mode?
jnz int4 ; nz = yes
cmp flags.xflg,0 ; writing to screen?
jne int1 ; ne = yes, nothing to do
int4: test flags.remflg,dquiet ; quiet screen?
jnz int1 ; yes, suppress msg
test flags.remflg,dserial ; serial mode display?
jz int2 ; z = no
cmp fmtdsp,0 ; formatted screen?
jne int2 ; ne = yes
mov dx,offset crlf ; output initial cr/lf
mov ah,prstr
int dos
jmp short int3 ; display the message
int2: mov dx,scrmsg ; last message position
call poscur
call clearl
int3: mov dx,offset infms7 ; File interrupted
cmp flags.cxzflg,'X' ; File interrupt?
je int0 ; e = yes
mov dx,offset infms8 ; File group interrupted
cmp flags.cxzflg,'Z' ; correct?
je int0 ; e = yes
mov dl,flags.cxzflg ; say Control ^letter interrupt
mov infms9+6,dl ; store interrupt code letter
mov dx,offset infms9
int0: mov ah,prstr
int dos
int1: ret
INTMSG ENDP
; Clear Last error and Last message lines
cxerr: mov temp,0 ; say last error line
jmp short cxcomm ; do common code
CXMSG PROC NEAR
mov temp,1 ; say last message line
cxcomm: test flags.remflg,dserver ; server mode?
jnz cxm1 ; nz = yes
cmp flags.xflg,0 ; Writing to screen?
jne cxm0 ; ne = yes
cxm1: cmp fmtdsp,0 ; formatted display?
je cxm0 ; e = no
push dx
push si
mov dx,screrr ; Last Error postion
cmp temp,0 ; do last error line?
je cxm2 ; e = yes
mov dx,scrmsg ; Last Message position
cxm2: call poscur
call clearl
pop si
pop dx
cxm0: ret
CXMSG ENDP
; Clear out the old filename on the screen.
CLRFLN PROC NEAR
test flags.remflg,dquiet ; quiet display?
jnz clrflnx ; nz = yes
test flags.remflg,dserial ; serial display mode?
jnz clrfln1 ; nz = yes, use just cr/lf
cmp fmtdsp,0 ; formatted display?
je clrfln1 ; e = no
mov dx,scrfln
call poscur
call clearl ; clear to end of line
ret
clrfln1:push ax ; for serial display, does cr/lf
mov ah,prstr
mov dx,offset crlf
int dos
pop ax
clrflnx:ret
CLRFLN ENDP
; display packet quantity and size, SI has pkt ptr
PKTSIZE PROC NEAR
push ax
push dx
push si
cmp fmtdsp,0 ; formatted display?
je pktsiz2 ; e = no, no display
mov ax,[si].datlen ; packet size (data part)
add al,trans.chklen ; plus checksum
adc ah,0
cmp ax,prepksz ; same as previous packet?
je pktsiz2 ; e = yes, skip display of size
push ax
mov dx,scrsz ; position cursor
call poscur
call clearl ; clear to end of line
pop ax
mov prepksz,ax ; remember new value
add ax,3 ; plus LEN, SEQ, TYPE
cmp ax,94 ; larger than Regular?
jbe pktsiz1 ; be = no
add ax,3 ; add Long Packet len and chksum
pktsiz1:call decout ; show packet length
; number of packets part
pktsiz2:test flags.remflg,dquiet ; quiet screen?
jnz pktsiz3 ; nz = yes
call nppos ; number of packets sent
mov ax,numpkt ; number of packets
call nout ; write the packet number
pktsiz3:pop si
pop dx
pop ax
ret
PKTSIZE ENDP
; some random screen positioning functions
kbpos: mov dx,scrkb ; KBytes transferred
cmp fmtdsp,0 ; formatted display?
jne setup2 ; ne = yes
ret ; else ignore postioning request
perpos: mov dx,scrper ; Percent transferred
cmp fmtdsp,0 ; formatted display?
jne setup2 ; ne = yes
ret ; else ignore postioning request
frpos: mov dx,scrmsg ; say renamed file
jmp short setup2
stpos: mov dx,scrst ; status of file transfer
jmp short setup2
nppos: mov dx,scrnp ; Number of packets sent
cmp fmtdsp,0 ; formatted display?
jne setup2 ; ne = yes
ret
rprpos: test flags.remflg,dserial+dquiet ; reprompt position
jnz rprpos1 ; nz = no mode line for these
cmp fmtdsp,0 ; formatted display?
je rprpos1 ; e = no, so no mode line
call clrmod ; clear mode line
rprpos1:mov dx,scrrpr ; Reprompt position
call setup2 ; position cursor
mov fmtdsp,0 ; turn off formatted display flag
ret
sppos: mov dx,scrsp ; Debug Send packet location
jmp short setup1
rppos: mov dx,scrrp ; Debug Receive packet location
jmp short setup1
; common service routines for positioning
setup1: test flags.remflg,dquiet+dserial; quiet or serial display mode?
jnz setupa ; nz = yes
cmp fmtdsp,0 ; non-formatted display?
je setupa ; e = yes
jmp poscur
setup2: test flags.remflg,dquiet+dserial; quiet or serial display mode?
jnz setupa ; nz = yes
cmp fmtdsp,0 ; non-formatted display?
je setupa ; e = yes
call poscur ; no
jmp clearl
setupa: test flags.remflg,dquiet ; quiet mode?
jnz setupx ; nz = yes, do nothing
push ax ; display cr/lf and return
push dx
mov dx,offset crlf
mov ah,prstr
int dos
pop dx
pop ax
setupx: ret
; Initialize formatted screen
INIT PROC NEAR
mov windflag,0 ; init windows in use display flag
test flags.remflg,dquiet ; quiet display mode?
jnz init4 ; nz = yes
test flags.remflg,dserver ; server mode?
jnz init1 ; nz = yes
cmp flags.xflg,0 ; destination is screen
jne init4 ; ne = yes
init1: test flags.remflg,dserial ; serial mode display?
jnz init3 ; nz = yes
call cmblnk ; clear the screen
mov dx,offset cxzhlp
call putmod ; write mode line
mov fmtdsp,1 ; say doing formatted display
test flags.remflg,dserver ; server mode?
jz init2 ; z = no
mov dx,scrser ; move cursor to top of screen
call poscur
mov ah,prstr
mov dx,offset infms1 ; say now in server mode
int dos
init2: call locate
mov ah,prstr ; put statistics headers on the screen
mov dx,offset outlin1
int dos
mov dx,offset verident
int dos
mov dx,offset outlin2
int dos
mov wrpmsg,0 ; haven't printed the messsage yet
mov prepksz,0 ; set previous packet size to zero
ret
init3: mov ah,prstr
mov dx,offset cxzser ; status line as a text string
int dos
init4: mov wrpmsg,1 ; suppress display of percentage msg
mov fmtdsp,0 ; say doing unformatted display
ret
INIT ENDP
; show number of Kilobytes transferred
; modifies ax
kbpr proc near
test flags.remflg,dquiet ; quiet display mode?
jnz kbpr1 ; nz = yes, no printing
push bx
mov ax,tfilsz ; low order word
mov bx,tfilsz+2 ; high order word
add ax,512 ; round up, add half the denominator
adc bx,0
rcr bx,1 ; divide double word by 1024,
rcr ax,1 ; by dword shift right 10
rcr bx,1
rcr ax,1
mov al,ah
mov ah,bl ; ax has the result
pop bx
cmp ax,oldkbt ; is it the same?
je kbpr1 ; yes, skip printing
mov oldkbt,ax ; save new # of kb
push ax
call kbpos ; postion the cursor
pop ax
call decout ; print number of KBytes transferred
kbpr1: ret
kbpr endp
; show percent transferred
; modifies ax
perpr proc near
test flags.remflg,dquiet ; quiet display mode?
jz perpr1 ; z = no. allow printing
ret ; skip printing in remote mode
perpr1: cmp diskio.sizehi,0 ; high word of original file size > 0 ?
jne perpr3 ; ne = yes, use big file code
cmp diskio.sizelo,0 ; anything here at all?
jne perpr2 ; ne = yes, use small file code
ret ; otherwise, quit now
perpr2: push cx ; case for files < 64 Kb
push dx
mov ax,diskio.sizelo ; original size (low word)
mov denom,ax
mov dx,tfilsz+2 ;transferred size times 256 in [dx,ax]
mov ax,tfilsz
mov dh,dl ; whole value multiplied by 256
mov dl,ah
mov ah,al
xor al,al
mov cx,denom ; round up, add half the denominator
shr cx,1
add ax,cx
adc dx,0
div denom ; (256*xfer)/orig. ax = quo, dx = rem
mul onehun ; multiply quotient above by 100
mov al,ah ; divide result (ax) by 256
xor ah,ah ; percentage is in ax
jmp perpr4 ; finish in common code
perpr3: push cx ; case for file size > 64 KB
push dx
mov ax,diskio.sizelo ; original file size low order word
shr ax,1 ; divide by 2
mov al,ah ; divide again by 256 for total of 512
xor ah,ah ; clear ah
mov dx,diskio.sizehi ; high order word
xchg dh,dl ; do shl dx,cl=7
ror dx,1 ; old low bit of dh to high bit of dh
and dl,80h ; clear lower bits. divided by two
or ax,dx ; paste together the two parts into ax
mov denom,ax ; denom = original size divided by 512
mov dx,tfilsz+2 ; high order word of transferred size
mov ax,tfilsz ; low order word
mov cx,denom ; round up, add half the denominator
shr cx,1
add ax,cx
adc dx,0
div denom ; xfer/(orig/512). ax=quot, dx=rem
mul onehun ; times 100 for 512*percentage, in ax
mov al,ah ; divide ax by 512
xor ah,ah
shr al,1 ; final percentage, in ax
perpr4: cmp ax,oldper ; same as it was before?
je perpr7 ; yes, don't bother printing
mov oldper,ax ; remember this for next time
cmp wrpmsg,0 ; did we write the percentage message?
jne perpr5 ; ne = yes, skip this part
push ax
call perpos ; position cursor
mov dx,offset permsg
mov ah,prstr
int dos ; write out message
pop ax
mov wrpmsg,1 ; init flag so we don't do it again
perpr5: push ax
call perpos ; position the cursor
pop ax
cmp ax,onehun ; > 100% ?
jle perpr6 ; no, accept it
mov ax,onehun ; else just use 100
perpr6: call decout
mov dl,25h ; load a percent sign
mov ah,conout ; display the character
int dos
perpr7: pop dx
pop cx
ret
perpr endp
winpr proc near ; print number of active window slots
cmp trans.windo,1 ; windowing in use?
jbe winprx ; be = no, no message
test flags.remflg,dregular ; regular display?
jz winprx ; z = no, no display
cmp fmtdsp,0 ; formatted display?
je winprx ; e = no, no display here
test flags.remflg,dserver ; server mode?
jnz winpr4 ; nz = yes, writing to their screen
cmp flags.xflg,0 ; receiving to screen?
je winpr4 ; e = no
winprx: ret
winpr4: push ax
push bx
push cx
push dx
push si
cmp windflag,0 ; have we written an initial value?
jne winpr1 ; ne = yes
mov dx,scrnp ; position cursor
dec dh
xor dl,dl ; 0 = left most column for text
call poscur
call clearl ; clear the line
mov ah,prstr
mov dx,offset windmsg ; the text
int dos
xor al,al ; display an initial 0
mov oldwind,-1
mov windflag,1 ; say have done the work
jmp short winpr2
winpr1: mov al,windused ; window slots in use
cmp al,oldwind ; same as before?
je winpr3 ; e = yes, ignore
winpr2: push ax
mov dx,scrnp ; position cursor
dec dh
call poscur
call clearl
pop ax
mov oldwind,al ; remember last value
xor ah,ah
call decout ; display value
winpr3: pop si
pop dx
pop cx
pop bx
pop ax
ret
winpr endp
; SHOW TRANSLATE-RECEIVE
; Display characters being changed for Connect mode serial receive translator
SHORX PROC NEAR ; show translate table of incoming
; chars, only those changed
mov ah,cmeol ; get a confirm
call comnd
jnc shorx0a ; nc = success
ret ; failure
shorx0a:mov ah,prstr
mov dx,offset rxoffmsg ; assume translation is off
cmp rxtable+256,0 ; is translation off?
je shorx0 ; e = yes
mov dx,offset rxonmsg ; say translation is on
shorx0: int dos
mov dx,offset shormsg ; give title line
int dos
xor cx,cx ; formatted line counter
xor bx,bx ; entry subscript
shorx1: cmp rxtable[bx],bl ; entry same as normal?
je shorx2 ; e = yes, skip it
call shorprt ; display the entry
shorx2: inc bx ; next entry
cmp bx,255 ; done all entries yet?
jbe shorx1 ; be = not yet
mov ah,prstr
mov dx,offset crlf ; end with cr/lf
int dos
clc ; success
ret
; worker routine
shorprt:cmp cx,4 ; done five entries for this line?
jb shorpr1 ; b = no
mov ah,prstr
mov dx,offset crlf ; break line now
int dos
xor cx,cx
shorpr1:mov ah,prstr
mov dx,offset shopm1 ; start of display
int dos
xor ah,ah
mov al,bl ; original byte code
call decout ; display its value
mov ah,prstr
mov dx,offset shopm2 ; intermediate part of display
int dos
xor ah,ah
mov al,rxtable[bx] ; new byte code
call decout ; display its value
mov ah,prstr
mov dx,offset shopm3 ; last part of display
int dos
inc cx ; count item displayed
ret
SHORX ENDP
; SHOW MACRO [macro name]
SHOMAC PROC NEAR
mov ah,cmword
mov dx,offset rdbuf
mov bx,offset shmmsg
mov comand.cmper,1 ; don't react to \%x variables
call comnd
jnc shoma1a ; nc = success
ret ; failure
shoma1a:mov al,ah
xor ah,ah
mov shmcnt,ax ; save length of user spec
mov ah,cmeol
call comnd
jnc shoma1b ; nc = success
ret ; failure
shoma1b:mov si,offset mcctab ; table of macro names
cld
lodsb
mov cl,al ; number of macro entries
xor ch,ch
jcxz shom6 ; z = none
mov temp,0 ; count of macros displayed
mov temp1,0 ; lines displayed, for more message
shom2: push cx ; save loop counter
lodsb ; length of macro name
xor ah,ah
mov cx,shmcnt ; length of user's string
jcxz shom4 ; show all names
cmp al,cl ; mac name shorter that user spec?
jb shom5 ; b = yes, no match
push ax
push si ; save these around match test
mov di,offset rdbuf ; user's string
shom3: mov ah,[di]
inc di
lodsb ; al = mac name char, ah = user char
and ax,not 2020h ; clear bits (uppercase chars)
cmp ah,al ; same?
loope shom3 ; while equal, do more
pop si ; restore regs
pop ax
jne shom5 ; ne = no match
shom4: call shom9 ; show this name
shom5: add si,ax ; point to next name, add name length
add si,3 ; and '$', and string pointer
pop cx ; recover loop counter
cmp flags.cxzflg,0 ; does user wish to stop now?
jne shom5a ; ne = yes
loop shom2 ; one less macro to examine
shom5a: mov flags.cxzflg,0 ; clear flag before exiting
cmp temp,0 ; did we show any macros?
jne shom7 ; ne = yes
shom6: mov ah,prstr
mov dx,offset shom9m3 ; no entries found
int dos
shom7: mov ah,prstr ; Summary line
mov dx,offset shom9m1 ; free space: name entries
int dos
mov ax,offset mcctab+mcclen
sub ax,mccptr ; compute # of free name bytes
call decout
mov ah,prstr
mov dx,offset crlf
int dos
clc ; success
ret
; worker, show mac name and def
shom9: push ax ; call with si pointing at macro
push si ; name, byte ptr [si-1] = length
push es
cmp byte ptr[si],0 ; name starts with null char?
jne shom9g ; ne = no
jmp shom9e ; yes, TAKE file, ignore
shom9g: call shom20 ; do newline, check for more/exit
jnc shom9h ; nc = continue
jmp shom9e ; exit
shom9h: mov ah,conout
mov dl,' ' ; add a space
int dos
inc temp ; count displayed macros
mov dx,si ; display macro name
mov ah,prstr
int dos
mov dx,offset eqs ; display equals sign
int dos
mov al,[si-1] ; length of macro name
xor ah,ah
add si,ax ; skip over name
inc si ; skip '$' field
mov es,[si] ; segment of string structure
xor si,si ; es:si = address of count + string
mov cl,es:[si] ; length of string
xor ch,ch
inc si ; si = offset of string text proper
shom9a: mov al,es:[si] ; get a byte into al
inc si
cmp al,' ' ; control char?
jae shom9c ; ae = no
cmp al,cr ; carriage return?
jne shom9b ; ne = no
mov ah,prstr
mov dx,offset shom9m4 ; show <cr>
int dos
cmp cx,1 ; more to show?
je shom9d ; e = no
call shom20 ; new line, check for continue or exit
jc shom9e ; c = exit
mov ah,conout ; show two spaces
mov dl,' ' ; the spaces
int dos
int dos
cmp byte ptr es:[si],lf ; cr followed by linefeed?
jne short shom9d ; ne = no
inc si ; skip the leading lf
dec cx
jmp short shom9d
shom9b: push ax
mov ah,conout
mov dl,5eh ; caret
int dos
pop ax
add al,'A'-1 ; add offset to make printable letter
shom9c: mov ah,conout
mov dl,al ; display it
int dos
shom9d: loop shom9a ; do whole string
shom9e: pop es
pop si
pop ax
ret
shom20: inc temp1 ; count lines displayed
cmp temp1,24 ; done a normal screens' worth?
jb shom22 ; b = no
mov ah,prstr
mov dx,offset moremsg ; say more
int dos
mov temp1,0
mov flags.cxzflg,0 ; clear flag so we can see Control-C
mov ah,0ch ; clear keyboard buffer
mov al,coninq ; quiet input
int dos
cmp al,3 ; Control-C?
je shom21 ; e = yes
or al,al ; scan code?
jne shom22 ; ne = no
mov ah,coninq ; read the second byte
int dos
or al,al ; null for Control-Break?
jne shom22 ; ne = no
shom21: mov flags.cxzflg,'C' ; say want to exit now
shom22: mov ah,prstr
mov dx,offset crlf
int dos
cmp flags.cxzflg,0 ; want to exit?
jne shom23 ; ne = yes
clc
ret
shom23: stc ; say exit now
ret
SHOMAC ENDP
SHCOM PROC NEAR ; Show Modem
mov ah,cmeol
call comnd ; get a confirm
jc shcom1 ; c = failure
mov dx,offset crlf
mov ah,prstr
int dos ; print a crlf
mov bx,offset stcom ; table of items to be shown
call statc ; finish in common code
call shomodem
clc
shcom1: ret
SHCOM ENDP
SHFILE PROC NEAR ; Show File
mov ah,cmeol
call comnd ; get a confirm
jnc shfile1 ; nc = success
ret ; failure
shfile1:mov dx,offset crlf
mov ah,prstr
int dos ; print a crlf
mov bx,offset stfile ; table of items to be shown
jmp statc ; finish in common code
SHFILE ENDP
SHLOG PROC NEAR ; Show Log
mov ah,cmeol
call comnd ; get a confirm
jnc shlog1 ; nc = success
ret ; failure
shlog1: mov dx,offset crlf
mov ah,prstr
int dos ; print a crlf
mov bx,offset stlog ; table of items to be shown
jmp statc ; finish in common code
SHLOG ENDP
SHMEM PROC NEAR ; Show (free) Memory. Recursive!
mov ah,cmeol
call comnd ; get a confirm
jnc shmem1 ; nc = success
ret ; failure
shmem1: mov ah,prstr
mov dx,offset memmsg1 ; header message
int dos
mov word ptr rdbuf,' ' ; two spaces
mov rdbuf+2,0 ; safety null terminator
mov di,offset rdbuf+1 ; look at first space
mov temp,0 ; total free memory
mov temp1,0 ; and high word thereof
push es ; save es
call shmem4 ; allocate memory, recursively
mov dx,offset rdbuf ; output buffer
call prtasz ; show pieces
mov dx,offset memmsg2 ; trailer
mov ah,prstr
int dos
mov di,offset rdbuf ; setup buffer for lnout
mov rdbuf,0
mov ax,temp ; total free space
mov dx,temp1
call lnouts ; 32 bit to decimal ascii in di
mov dx,offset rdbuf ; with thousands separator
call prtasz
pop es
ret
; worker routine
shmem4: mov bx,0ffffh ; allocate all memory (must fail)
mov ah,alloc ; DOS memory allocator
int dos ; returns available paragraphs in bx
jnc shmem6 ; nc = got it all (not very likely)
or bx,bx ; bx = # paragraphs alloc'd. Anything?
jz shmem5 ; z = no
mov ah,alloc ; consume qty now given in bx
int dos
jnc shmem6 ; nc = got the fragment
shmem5: ret
shmem6: push ax ; save allocation segment
mov ax,bx ; convert paragraphs
mul sixteen ; to bytes in dx:ax
add temp,ax ; running total
adc temp1,dx ; 32 bits
cmp byte ptr [di],0 ; starting on a null?
jne shmem7 ; ne = no, skip punctuation
mov byte ptr [di],'+' ; plus punctuation
inc di
shmem7: call lnouts ; long number to decimal in buffer di
call shmem4 ; recurse
pop es ; recover allocation segment
mov ah,freemem ; free the allocation
int dos
ret
SHMEM ENDP
SHPRO PROC NEAR ; Show Protocol
mov ah,cmeol
call comnd ; get a confirm
jnc shpro1 ; nc = success
ret ; failure
shpro1: mov dx,offset crlf
mov ah,prstr
int dos ; print a crlf
mov bx,offset stpro ; table of items to be shown
jmp statc ; finish in common code
SHPRO ENDP
SHSCPT PROC NEAR ; Show Script
mov ah,cmeol
call comnd ; get a confirm
jnc shscpt1 ; nc = success
ret ; failure
shscpt1:mov dx,offset crlf
mov ah,prstr
int dos ; print a crlf
mov bx,offset stscpt ; table of items to be shown
jmp statc ; finish in common code
SHSCPT ENDP
SHSERV PROC NEAR ; Show Server
mov ah,cmeol
call comnd ; get a confirm
jnc shserv1 ; nc = success
ret ; failure
shserv1:mov dx,offset crlf
mov ah,prstr
int dos ; print a crlf
mov bx,offset stserv2 ; do timeout item
call statc
mov dx,offset crlf
mov ah,prstr
int dos
mov bx,offset stserv ; table of items to be shown
jmp statc ; finish in common code
SHSERV ENDP
SHTERM PROC NEAR ; Show Terminal
mov ah,cmeol
call comnd ; get a confirm
jnc shterm1 ; nc = success
ret ; failure
shterm1:mov dx,offset crlf
mov ah,prstr
int dos ; print a crlf
mov bx,offset stterm ; table of items to be shown
jmp statc ; use common code
SHTERM ENDP
; Start recording of statistics for this operation.
begtim proc near
test sflag,80h ; is this a duplicate call?
jz begtim1 ; z = no
ret ; else just return
begtim1:push ax
push cx
push dx
xor ax,ax ; clear statistics counters for this file
mov fsta.prbyte,ax ; bytes received from serial port
mov fsta.prbyte+2,ax
mov fsta.psbyte,ax ; bytes sent out serial port
mov fsta.psbyte+2,ax
mov fsta.frbyte,ax ; bytes received for this file
mov fsta.frbyte+2,ax
mov fsta.fsbyte,ax ; bytes sent for this file
mov fsta.fsbyte+2,ax
mov fsta.prpkt,ax ; packets received for this file
mov fsta.prpkt+2,ax
mov fsta.pspkt,ax ; packets sent for this file
mov fsta.pspkt+2,ax
mov fsta.nakrcnt,ax ; NAKs received for this file
mov fsta.nakscnt,ax ; NAKs sent for this file
mov fsta.xstatus,al ; clear status byte
mov ah,getdate ; get current date, convert to ascii
int dos
mov date+9,'0' ; init day of month
begtim2:cmp dl,10 ; day of month. Ten or more days?
jl begtim3 ; l = no
sub dl,10
inc date+9 ; add up tens of days
jmp short begtim2 ; repeat for higher order
begtim3:add dl,'0' ; ascii bias
mov date+10,dl ; day units
mov dl,dh ; months (1-12)
dec dl ; start at zero to index table
xor dh,dh
mov di,dx ; months
shl di,1
add di,dx ; times three chars/month
mov al,months[di] ; get text string for month
mov date+12,al
mov ax,word ptr months[di+1]
mov word ptr date+13,ax
mov ax,cx ; year since 1980
mov dx,0
mov di,offset date+16 ; destination
call lnout ; convert number to asciiz in buffer
; start time
mov ah,gettim ; DOS time of day, convert to ascii
int dos
mov fsta.btime,dx ; store ss.s low word of seconds
mov fsta.btime+2,cx ; store hhmm high word of seconds
mov date,'0' ; init begin hours field
begtim4:cmp ch,10 ; ten or more hours?
jl begtim5 ; l = no
sub ch,10
inc date ; add up tens of hours
jmp short begtim4 ; repeat for twenties
begtim5:add ch,'0' ; ascii bias
mov date+1,ch ; store units of hours
mov date+3,'0' ; minutes field
begtim6:cmp cl,10 ; ten or more minutes?
jl begtim7 ; l = no
sub cl,10
inc date+3 ; add up tens of minutes
jmp short begtim6 ; repeat for higher orders
begtim7:add cl,'0' ; ascii bias
mov date+4,cl ; store units of minutes
mov date+6,'0' ; seconds field
begtim8:cmp dh,10 ; ten or more seconds?
jl begtim9 ; l = no
sub dh,10
inc date+6 ; add up tens of seconds
jmp short begtim8 ; repeat for higher orders
begtim9:add dh,'0' ; ascii bias
mov date+7,dh
mov sflag,80h ; say begtim has been run
pop dx
pop cx
pop ax
ret
begtim endp
; Take snapshot of statistics counters at end of an operation
; Enter with ax = 0 for a receive operation, ax = 1 for a send. [jrd]
endtim proc near
test sflag,80h ; called more than once without calling begtim?
jnz endtim1 ; ne = no, so do statistics snapshot
ret ; yes, do nothing
endtim1:and sflag,not (1) ; assume receive operation
or ax,ax ; send (ax > 0), receive (ax = 0) flag
jz endtim2 ; z = receive opeation
or sflag,1 ; say send operation
endtim2:push ax
push cx
push dx
mov ah,gettim ; get DOS time of day
int dos
mov fsta.etime,dx ; store ss. s
mov fsta.etime+2,cx ; hhmm
cmp cx,fsta.btime+2 ; end time less than start time?
ja endtim2a ; a = above (no need to test low order word)
cmp dx,fsta.btime ; be. How about low order word
jae endtim2a ; ae = no wrap around of time
add ch,24 ; add one day to hours field
endtim2a:sub dl,byte ptr fsta.btime ; 0.01 sec difference
jns endtim2b
dec dh ; borrow a second
add dl,100 ; make difference positive
endtim2b:sub dh,byte ptr fsta.btime+1; seconds difference
jns endtim2c
dec cl ; borrow a minute
add dh,60 ; make difference positive
endtim2c:xor bh,bh
mov bl,dh ; bx has seconds difference
sub cl,byte ptr fsta.btime+2 ; minutes
jns endtim2d
dec ch ; borrow an hour
add cl,60
endtim2d:mov al,cl
xor ah,ah
mul sixty ; minutes to seconds
add bx,ax ; seconds to bx
sub ch,byte ptr fsta.btime+3 ; hours difference
jns endtim2e
add ch,24
endtim2e:mov al,ch
xor ah,ah
mul sixty ; hours to minutes in ax
mul sixty ; minutes to seconds in dx,ax
add ax,bx ; ax = seconds
adc dx,0 ; dx = high word of seconds
mov fsta.etime,ax ; store elapsed time, seconds, low wd
mov fsta.etime+2,dx ; high word
add ssta.etime,ax ; add to session time, low word
adc ssta.etime+2,dx ; add to session time, high word
mov ax,fsta.pretry ; retries for last transfer
add ssta.pretry,ax ; retries for this session
test sflag,1 ; completing a receive operation?
jnz endtim3 ; nz = no, a send operation
mov ax,tfilsz ; file bytes received, low word
mov fsta.frbyte,ax
add ssta.frbyte,ax ; session received file bytes, low word
mov ax,tfilsz+2 ; high word
mov fsta.frbyte+2,ax
adc ssta.frbyte+2,ax
jmp short endtim4
endtim3:mov ax,tfilsz ; file bytes sent, low word
mov fsta.fsbyte,ax ; file bytes sent
add ssta.fsbyte,ax ; session sent file bytes, low word
mov ax,tfilsz+2 ; high word
mov fsta.fsbyte+2,ax
adc ssta.fsbyte+2,ax
endtim4:mov ax,fsta.nakrcnt ; NAKs received for this file
add ssta.nakrcnt,ax ; session received NAKs
mov ax,fsta.nakscnt ; NAKs sent for this file
add ssta.nakscnt,ax ; session sent NAKs
; do transaction logging
cmp tloghnd,0 ; logging transaction? -1 = not opened
jg endtim5 ; g = logging
jmp endtim12 ; skip logging
endtim5:push di ; kind of transaction
push bx ; save these registers
mov bx,tloghnd ; handle for transaction log
mov dx,offset rcvmsg ; assume receive message
test sflag,1 ; 1 for send, 0 for receive
jz endtim6 ; z = receive
mov dx,offset sndmsg ; send message
endtim6:call strlen ; length of message to cx
mov ah,write2
int dos ; write kind of transfer
; File names
cmp diskio.string,0 ; local filename
je endtim9 ; e = no filename
test sflag,1 ; a send operation?
jnz endtim8 ; nz = yes
; Receive
mov dx,offset fsta.xname ; remote name
call strlen ; length to cx
jcxz endtim7 ; no name
mov ah,write2
int dos
mov dx,offset diskio.string ; local name
call strlen ; length to cx
mov si,offset fsta.xname ; compare these two names
mov di,dx
push ds
pop es
repe cmpsb ; compare
je endtim9 ; e = same, so no 'as' msg
mov dx,offset fasmsg ; give 'as' message
mov cx,faslen ; length
mov ah,write2
int dos
endtim7:mov dx,offset diskio.string ; local name
call strlen ; get length
mov ah,write2 ; write local name
int dos
jmp short endtim9
endtim8:mov dx,offset templp ; Send. local name
call strlen
mov ah,write2
int dos
cmp fsta.xname,0 ; using an alias?
je endtim9 ; e = no
mov dx,offset fasmsg ; give 'as' message
mov cx,faslen
mov ah,write2
int dos
mov dx,offset fsta.xname ; get alias
call strlen
mov ah,write2
int dos
; status of transfer
endtim9:mov dx,offset atmsg ; say At
mov cx,atlen ; length
mov bx,tloghnd ; handle
mov ah,write2
int dos
mov dx,offset date ; write time and date field
mov cx,datelen ; length
mov ah,write2
int dos
mov dx,offset fsucmsg ; assume success message
cmp fsta.xstatus,0 ; 0 = completed?
je endtim10 ; e = completed
mov dx,offset fbadmsg ; failed message
test fsta.xstatus,80h ; interrupted?
jz endtim10 ; z = no
mov dx,offset fintmsg ; interrupted message
endtim10:call strlen ; get length to cx
mov ah,write2
int dos
; file bytes transferred
mov ax,tfilsz ; file bytes, low word
mov dx,tfilsz+2 ; high word
mov di,offset rdbuf ; work buffer
call lnouts ; transform to ascii
mov [di],0a0dh ; append cr/lf
add di,2 ; count them
mov dx,offset rdbuf ; start of work buffer
mov cx,di ; next free byte
sub cx,dx ; compute length
mov ah,write2
int dos
cmp dosnum,300h+30 ; DOS 3.30 or higher?
jb endtim11 ; b = no
mov ah,68h ; Commit the file now
int dos
endtim11:pop bx
pop di
endtim12:mov tfilsz,0 ; clear file size area
mov tfilsz+2,0
mov sflag,0 ; say have done ending once already
mov fsta.xname,0 ; clear statistics "as" name
pop dx
pop cx
pop ax
ret
endtim endp
; SHOW STATISTICS command. Displays last operation and session statistics
; 9 March 1987 [jrd]
shosta proc near ; show file transfer statistics
mov ah,cmeol ; confirm with carriage return
call comnd
jnc shosta1
ret ; failure
shosta1:xor ax,ax
call endtim ; update statistics, just in case
push bx
push cx
push dx
mov dx,offset statmsg ; header
mov ah,prstr
int dos
mov dx,offset fchmsg ; File characters msg
mov ah,prstr
int dos
mov bx,offset fsta ; last file structure
mov ax,fsta.fsbyte ; last transfer file bytes sent
mov dx,fsta.fsbyte+2
mov cx,12 ; field width
call shoprt ; show result
mov ax,fsta.frbyte ; last transfer file bytes received
mov dx,fsta.frbyte+2
call shoprt ; show result
mov ax,ssta.fsbyte ; session file bytes sent
mov dx,ssta.fsbyte+2
call shoprt ; show result
mov ax,ssta.frbyte ; session file bytes received
mov dx,ssta.frbyte+2
call shoprt ; show result
mov ah,prstr
mov dx,offset spmsg ; serial port material
int dos
mov ax,fsta.psbyte ; last transfer port bytes sent
mov dx,fsta.psbyte+2
call shoprt ; show result
mov ax,fsta.prbyte ; last transfer port bytes received
mov dx,fsta.prbyte+2
call shoprt ; show result
mov ax,ssta.psbyte ; session port bytes sent
mov dx,ssta.psbyte+2
call shoprt ; show result
mov ax,ssta.prbyte ; session port bytes received
mov dx,ssta.prbyte+2
call shoprt ; show result
mov dx,offset pktmsg ; packets material
mov ah,prstr
int dos
mov ax,fsta.pspkt ; last transfer packets sent
mov dx,fsta.pspkt+2
call shoprt ; show result
mov ax,fsta.prpkt ; last transfer packets received
mov dx,fsta.prpkt+2
call shoprt ; show result
mov ax,ssta.pspkt ; session packets sent
mov dx,ssta.pspkt+2
call shoprt ; show result
mov ax,ssta.prpkt ; session packets received
mov dx,ssta.prpkt+2
call shoprt ; show result
mov dx,offset nakmsg ; NAKs material
mov ah,prstr
int dos
mov ax,fsta.nakscnt ; last transfer NAKs sent
xor dx,dx
call shoprt
mov ax,fsta.nakrcnt ; last transfer NAKs received
xor dx,dx
call shoprt
mov ax,ssta.nakscnt ; session NAKs sent
xor dx,dx
call shoprt
mov ax,ssta.nakrcnt ; session NAKs received
xor dx,dx
call shoprt
mov dx,offset retmsg ; retries
mov ah,prstr
int dos
mov ax,fsta.pretry ; last transfer retry count
xor dx,dx
mov cx,18
call shoprt
mov ax,ssta.pretry ; session retries
xor dx,dx
mov cx,24
call shoprt
mov dx,offset timemsg ; elapsed time material
mov ah,prstr
int dos
mov ax,fsta.etime ; elapsed time of last transfer
mov dx,fsta.etime+2
mov cx,18
call shoprt ; show result
mov ax,ssta.etime ; elapsed time of session
mov dx,ssta.etime+2
mov cx,24
call shoprt ; show result
mov dx,offset chpsmsg ; File chars per second
mov ah,prstr
int dos
mov ax,fsta.frbyte ; file bytes received, low
mov dx,fsta.frbyte+2 ; file bytes received, high
add ax,fsta.fsbyte ; file bytes sent, low
adc dx,fsta.fsbyte+2 ; high. [dx,ax] = total file bytes
mov bx,offset fsta
call showrk ; do worker
xor dx,dx ; discard the fractional cps
mov cx,18
call shoprt ; show result
mov ax,ssta.frbyte ; file bytes received, low
mov dx,ssta.frbyte+2 ; file bytes received, high
add ax,ssta.fsbyte ; file bytes sent, low
adc dx,ssta.fsbyte+2 ; high. [dx,ax] = total file bytes
mov bx,offset ssta
call showrk ; do worker
xor dx,dx ; discard the fractional cps
mov cx,24
call shoprt ; show result
mov dx,offset spedmsg ; speed material
mov ah,prstr
int dos
; compute baud rate as 10 * total port bytes / elapsed time
mov ax,fsta.prbyte ; port bytes received, low
mov dx,fsta.prbyte+2 ; port bytes received, high
add ax,fsta.psbyte ; port bytes sent, low
adc dx,fsta.psbyte+2 ; high. [dx,ax] = total port bytes
mov bx,offset fsta
call showrk ; do worker for bytes/sec and fraction
mov cx,dx ; save remainder of bytes/second
mul ten ; bytes/sec times ten to dx,ax
push dx ; save high order part
push ax ; save partial baud rate
mov ax,cx ; remainder to ax
xor dx,dx ; clear extension
mul ten ; remainder times ten too (keep only overflow)
mov cx,dx ; overflow part
pop ax ; recover main partial result
pop dx ; high order part
add ax,cx ; add two partial results
adc dx,0 ; add to extension
mov cx,18
call shoprt ; show result
mov ax,ssta.prbyte ; port bytes received, low
mov dx,ssta.prbyte+2 ; port bytes received, high
add ax,ssta.psbyte ; port bytes sent, low
adc dx,ssta.psbyte+2 ; high. [dx,ax] = total port bytes
mov bx,offset ssta
call showrk ; do worker for bytes/sec and fraction
mov cx,dx ; save remainder of bytes/second
mul ten ; bytes/sec times ten to dx,ax
push dx ; save high order part
push ax ; save partial baud rate
mov ax,cx ; remainder to ax
xor dx,dx ; clear extension
mul ten ; remainder times ten too (keep only overflow)
mov cx,dx ; overflow part
pop ax ; recover main partial result
pop dx ; high order part
add ax,cx ; add two partial results
adc dx,0 ; add to extension
mov cx,24
call shoprt ; show result
mov ah,prstr
mov dx,offset crlf
int dos
pop dx
pop cx
pop bx
clc
ret
shosta endp
; baud rate and char/sec worker for above
; Enter with dx,ax holding the byte count, returns (dx,ax / seconds in
; ax (whole number) and dx (fraction).
showrk proc near
mov cx,[bx].etime ; low word of sec in cx
cmp [bx].etime+2,0 ; is high word of sec zero (e.t. < 65536 sec)?
jz showrk1 ; z = yes, ready for arithmetic
push ax ; else scale values, save byte count
push dx
mov ax,[bx].etime ; elapsed time for file, low word
mov dx,[bx].etime+2 ; high word
shr ax,1 ; divide seconds by two, low word
ror dx,1 ; get low bit of high word
and dx,8000 ; pick out just that bit
or ax,dx ; mask in that bit, new time in ax (dx = 0)
mov cx,ax ; save elapsed time (double-seconds)
pop dx ; get byte count again
pop ax
shr ax,1 ; divide byte count by two also
push dx
ror dx,1 ; rotate low bit to high position
and dx,8000h ; get low bit of high word
or ax,dx ; byte count divided by two, low word
pop dx
shr dx,1 ; and high word
showrk1:or cx,cx ; is elapsed time (in cx) zero seconds?
jnz showrk2 ; nz = no
inc cx ; set time to one second (no div by 0)
showrk2:div cx ; bytes div seconds, ax = quo, dx = rem
ret
showrk endp
; Display SHOW STATISTICS line. Enter with dx,ax with long value, cx = width
shoprt proc near
push di
mov di,offset rdbuf ; work space for output
call lnouts ; show long integer, with separator
pop di
mov dx,offset rdbuf
push bx
push cx
push dx
mov bx,cx ; field width
call strlen ; length of string in dx
sub bx,cx ; number of spaces necessary
xchg bx,cx
jle shoprt2 ; le = no spaces
mov dl,' '
mov ah,conout
shoprt1:int dos ; display the leading spaces
loop shoprt1
shoprt2:pop dx
pop cx
pop bx
jmp prtasz ; display asciiz string
shoprt endp
; STATUS command
STATUS PROC NEAR
mov ah,cmeol
call comnd ; get a confirm
jnc stat0a ; nc = success
ret ; failure
stat0a: mov dx,offset crlf
mov ah,prstr
int dos ; print a crlf
; STAT0 is an external ref (in mster)
STAT0: call cmblnk ; clear the screen
call locate ; home the cursor
mov bx,offset sttab ; table to control printing
xor cx,cx ; column counter
; STATC is external ref in msx
STATC: cmp word ptr [bx],0 ; end of table?
je statx ; e = yes
cld ; string direction is forward
push ds
pop es
mov di,offset rdbuf ; point to destination buffer
mov byte ptr[di],spc ; start with two spaces
inc di
mov byte ptr[di],spc
inc di
push cx ; save column number
push bx
call [bx].sttyp ; call appropriate routine
pop bx
pop cx
sub di,offset rdbuf ; number of bytes used
add cx,di ; new line col count
push cx ; save col number around print
mov cx,di ; how much to print now
mov di,offset rdbuf ; source text
cmp cx,2 ; nothing besides our two spaces?
jbe stat5 ; e = yes, forget it
call prtscr ; print counted string
stat5: pop cx
add bx,size stent ; look at next entry
cmp word ptr [bx],0 ; at end of table?
je statx ; e = yes
cmp cx,38 ; place for second display?
jbe stat2 ; be = 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 statc
stat2: mov ax,cx
mov cx,38 ; where we want to be next time
sub cx,ax ; compute number of filler spaces
or cx,cx
jle stat4 ; nothing to do
mov ah,conout
mov dl,' '
stat3: int dos ; fill with spaces
loop stat3 ; do cx times
stat4: mov cx,38 ; current column number
jmp statc ; and do it
statx: clc
ret
STATUS ENDP
; handler routines for status
; all are called with di/ destination buffer, bx/ stat ptr. They can change
; any register except es:, must update di to the end of the buffer.
; copy the message into the buffer
stmsg proc near
push ds
pop es ; ensure es points to data segment
mov si,[bx].msg ; get message address
stms1: lodsb ; get a byte
stosb ; drop it off
or al,al ; ending on null?
jz stms2 ; z = yes
cmp al,'$' ; end of message?
jne stms1 ; no, keep going
stms2: dec di ; else back up ptr
ret
stmsg endp
; get address of test value in stent. Returns address in si
stval proc near
mov si,[bx].basval ; get base value
or si,si ; any there?
jz stva1 ; z = 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
; print a single character
onechr proc near
call stmsg ; copy message part first
call stval ; pick up test value address
mov al,[si] ; this is char to print
cmp al,' ' ; printable?
jae onech1 ; yes, keep going
add al,64 ; make printable
mov byte ptr [di],5eh ; caret
inc di ; note ctrl char
onech1: stosb ; drop char off
ret
onechr endp
; numeric field
stnum proc near ; for 8 bit numbers
call stmsg ; copy message
call stval ; pick up value address
mov al,[si] ; get value
xor ah,ah ; high order is 0
jmp outnum ; put number into buffer
stnum endp
stlnum proc near ; for 16 bit numbers [jrd]
call stmsg ; copy message
call stval ; pick up value address
mov ax,[si] ; get value
jmp outnum ; put number into buffer
stlnum endp
; translate the number in ax
outnum proc near
xor dx,dx
mov bx,10
div bx ; divide to get digit
push dx ; save remainder digit
or ax,ax ; test quotient
jz outnu1 ; zero, no more of number
call outnum ; else call for rest of number
outnu1: pop ax ; get digit back
add al,'0' ; make printable
stosb ; drop it off
ret
outnum endp
; on/off field
onoff proc near
call stmsg ; copy message
call stval ; get value cell
mov al,[si]
mov si,offset onmsg
mov cx,2 ; assume 2-byte 'ON' message
or al,al ; test value
jnz onof1 ; on, have right msg
mov si,offset offmsg
mov cx,3
onof1: cld
push ds
pop es
rep movsb ; copy right message in
ret
onoff endp
; print first message if false, second if true
msg2 proc near
call stval ; get value cell
mov al,[si]
mov si,[bx].msg ; assume off
or al,al ; is it?
jz msg21 ; yes, continue
mov si,[bx].val2 ; else use alternate message
msg21: jmp stms1 ; handle copy and return
msg2 endp
; print first message if false, second if true, uses bit in byte for value
msg2b proc near
call stbval ; get bit value cell
mov si,[bx].msg ; assume off
or al,al ; is it?
jz msg2b1 ; yes, continue
mov si,[bx].val2 ; else use alternate message
msg2b1: jmp stms1 ; handle copy and return
msg2b endp
; search a keyword table for a word value, print that value
srchkww proc near
call stmsg ; first print message
call stval
mov ax,[si] ; get value to hunt for
mov bx,[bx].val2 ; this is table address
jmp prttab ; and look in table
srchkww endp
; search a keyword table for a byte value, print that value
srchkw proc near
call stmsg ; first print message
call stval
mov al,[si] ; get value to hunt for
xor ah,ah ; high order is 0
mov bx,[bx].val2 ; this is table address
jmp prttab ; and look in table
srchkw endp
; search a keyword table for a bit value, print that value
srchkb proc near
call stmsg ; first print message
call stbval ; get bit set or reset
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
or si,si ; any there?
jz stbva1 ; z = no, quit with no match
mov ax,[si] ; get value
test ax,[bx].tstcel ; bit test value against data word
jz stbva1 ; z = they don't match
mov ax,1 ; match
ret
stbva1: xor ax,ax ; no match
ret ; and return it
stbval endp
; Print the drive name
drnum proc near
call stmsg ; copy message part first
call stval ; pick up test value address
mov ah,gcurdsk ; Get current disk
int dos
inc al ; We want 1 == A (not zero)
mov curdsk,al
add al,'@' ; Make it printable
cld
push ds
pop es
stosb
mov word ptr [di],'\:'
add di,2 ; end with a colon and backslash
mov byte ptr [di],0 ; terminate in case drive is not ready
xor dl,dl ; get current drive
mov ah,gcd ; get current directory
mov si,di ; current working buffer position
int dos
push cx
push dx
mov dx,di ; directory string
call strlen ; length of path part to cx
cmp cx,26 ; too long to show the whole thing?
jbe drnum3 ; be = is ok, show the whole path
push di ; scan backward for last backslash
mov al,'\' ; thing to search for
std ; backward
mov di,si ; start of buffer
add di,cx ; length of string
repne scasb ; scan backward for a backslash
jcxz drnum2 ; should not happen, but then again
repne scasb ; do again for second to last path part
drnum2: cld ; reset direction flag
dec di ; move di two places preceding backslash
mov [di],'--' ; insert a missing path indicator
dec di
mov byte ptr [di],'-'
mov si,di ; we will show just this part
pop di ; recover main status pointer
drnum3: pop dx
pop cx
drnum4: lodsb ; copy until null terminator
stosb
or al,al ; end of string?
jnz drnum4 ; nz = no
dec di ; offset inc of stosb
ret
drnum endp
; Print the screen-dump filename [jrd]
pasz proc near
call stmsg ; copy message part
mov si,[bx].val2 ; address of asciiz string
push ds
pop es
cld
pasz1: lodsb ; get a byte
or al,al ; at end yet?
jz pasz2 ; z = yes
stosb ; store in buffer
jmp short pasz1 ; keep storing non-null chars
pasz2: ret
pasz endp
; Display Send and Receive chars
prsar proc near
call stmsg ; display leadin part of message
push ds
pop es
cld
mov si,[bx].tstcel ; get address of first item
mov al,[si]
cmp al,7fh ; DEL code?
jne prsar1 ; ne = no
mov ax,'1\' ; say \127
cmp byte ptr [di-1],5eh ; caret present in msg?
jne prsar5 ; ne = no
dec di ; remove "^"
prsar5: stosw
mov ax,'72'
stosw
jmp short prsar2
prsar1: add al,40H ; make it printable
stosb
prsar2: mov si,[bx].val2 ; get address of second msg
call stms1 ; add that
mov si,[bx].basval ; second value's address
mov al,[si] ; second value
cmp al,7fh ; DEL code?
jne prsar3 ; ne = no
mov ax,'1\' ; say \127
cmp byte ptr [di-1],5eh ; caret present in msg?
jne prsar6 ; ne = no
dec di ; remove "^"
prsar6: stosw
mov ax,'72'
stosw
ret
prsar3: add al,40H ; make it printable
stosb
ret
prsar endp
; Display Send and Receive char value
prsarv proc near
call stmsg ; display leadin part of message
mov si,[bx].tstcel ; get address of first item
mov al,[si]
xor ah,ah
push bx
call outnum
pop bx
mov si,[bx].val2 ; get address of second msg
call stms1 ; add that
mov si,[bx].basval ; second value's address
mov al,[si] ; second value
xor ah,ah
jmp outnum
prsarv endp
; print Send Delay and Pause
prsnd proc near
call stmsg ; display leadin part of msg
mov al,trans.sdelay ; Send Delay (sec)
xor ah,ah
call outnum
mov si,offset sndmsg2 ; second part of msg
call stms1 ; add that
mov al,spause ; Send Pause (millisec)
call outnum
mov si,offset sndmsg3 ; last part of msg
call stms1 ; add it too
ret
prsnd endp
; Print the handshake
prhnd: mov si,offset handst ; copy in initial message
call stms1
mov si,offset nonmsg ; assume no handshake
mov bx,portval
cmp [bx].hndflg,0 ; Is handshaking in effect?
jne prh0 ; Yes, print what we're using
jmp stms1 ; no, say so and return
prh0: mov al,5eh ; Doing handshaking with control char
push ds
pop es
cld
stosb
mov al,[bx].hands
add al,40H ; Make printable
stosb ; put in buffer
ret ; and return
; Print the Transmit Fill char
prfil: mov si,offset sxfilmsg ; copy in initial message
call stms1
mov si,offset nonmsg ; assume no handshake
mov al,script.xmitfill ; filling char
or al,al ; is filling in effect?
jnz prfil1 ; nz = yes, print what we're using
jmp stms1 ; no, say so and return
prfil1: push ds
pop es
cld
cmp al,20h ; printable already?
ja prfil2 ; a = yes
push ax
mov al,5eh ; control char
stosb
pop ax
add al,40H ; make printable
stosb ; put in buffer
ret ; and return
prfil2: cmp al,126 ; in ordinary printable range?
ja prfil3 ; a = no
stosb ; store in buffer
ret
prfil3: mov byte ptr [di],'\' ; show as \number
inc di
xor ah,ah
jmp outnum ; do rest of number
; 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
xor dh,dh
inc dx ; account for "$" in table
mov si,dx ; put to index register
cmp ax,[bx+si] ; this one?
je prtt1 ; e = yes
add bx,dx ; go to end of keyword
add bx,2 ; point to next keyword
dec cl ; more keywords to check?
jnz prtt0 ; nz = yes, go to it
mov bx,offset prterr
prtt1: mov si,bx
pop cx ; recover column count
jmp stms1 ; copy in message
; Print the baud rate
BAUDPRT PROC NEAR
mov si,offset baudrt ; "Speed: "
call stms1 ; display that part
push di
push cx
call getbaud ; read baud rate first
pop cx
pop di
mov bx,portval
mov ax,[bx].baud
cmp al,byte ptr bdtab ; number of table entries
jb bdprt5 ; b = in table
mov si,offset unrec ; say unrecognized value
jmp stms1 ; display text and return
bdprt5: mov bx,offset bdtab ; show ascii rate from table
jmp prttab
BAUDPRT ENDP
; display Take/Macro COUNT
stcnt proc near
call stmsg ; display leadin part of msg
cmp taklev,0 ; in a Take file or macro?
jne stcnt1 ; ne = yes
mov si,offset nonemsg ; say none
call stms1
ret
stcnt1: push bx
mov bx,takadr ; current Take structure
mov ax,[bx].takctr ; get COUNT
pop bx
jmp outnum
stcnt endp
; display Take/Macro ARGC
starg proc near
call stmsg ; display leadin part of msg
cmp taklev,0 ; in a Take file or macro?
jne starg1 ; ne = yes
mov si,offset nonemsg ; say none
call stms1
ret
starg1: push bx
mov bx,takadr ; current Take structure
mov ax,[bx].takargc ; get ARGC
pop bx
jmp outnum
starg endp
; ALARM time
stalr proc near
call stmsg ; display leading part of msg
push bx ; preserve register
xor bx,bx ; position index
push ds
pop es
cld
stalr1: push bx ; save around calls
cmp alrhms[bx],10 ; two digits?
jae stalr2 ; ae = yes
mov al,'0'
stosb ; show leading zero
stalr2: mov al,alrhms[bx] ; show time component
xor ah,ah
call outnum
pop bx ; recover index
inc bx
cmp bx,3 ; done all fields?
jae stalr3 ; ae = yes
mov al,':'
stosb
jmp short stalr1 ; do next field
stalr3: pop bx
ret
stalr endp
; LNOUT - Table driven unsigned long integer (32 bit) display
; Register dx holds high order word and ax holds low order word of unsigned
; long integer to be stored in decimal. Storage area is given by DS:[DI]
; DI is incremented for each storage, null terminated.
; Table TENS holds set of double word values of ten raised to powers 0 to 9
; TENSLEN holds the number of these double words
; All registers preserved. 8 March 1987 [jrd]
lnouts proc near ; do lnout with thousands separator
push ax
mov al,thsep ; get thousands separator
mov lnoutsep,al ; tell lnout to use it
pop ax
call lnout ; compute value to di
mov lnoutsep,0 ; clear for future callers
ret
lnouts endp
lnout proc near
push ax
push bx
push cx
push dx
push si
xor si,si ; flag to say start printing (no leading 0's)
mov cx,tenslen ; number of table entries
lnout1: push cx ; save loop counter
mov bx,cx ; index into tens double word table
dec bx ; index starts at zero
add bx,bx
add bx,bx ; bx times four (double words to bytes)
xor cx,cx ; cx is now a counter of subtractions
lnout2: cmp dx,word ptr tens[bx+2] ; pattern 10**(bx/4), high order part
jb lnout4 ; b = present number is less than pattern
ja lnout3 ; a = present number is larger than pattern
cmp ax,word ptr tens[bx] ; high words match, how about lows
jb lnout4 ; b = present number is smaller than pattern
lnout3: sub ax,word ptr tens[bx] ; subtract low order words
sbb dx,word ptr tens[bx+2] ; subtract high order words, w/borrow
inc cl ; count number of subtractions
inc si ; flag to indicate printing needed
jmp lnout2 ; try again to deduct present test pattern
lnout4: or bx,bx ; doing least significant digit?
jz lnout5 ; z = yes, always print this one
or si,si ; should we print?
jz lnout6 ; z = no, not yet
lnout5: add cl,'0' ; get number of subtractions
mov [di],cx ; store it (ch is still zero), asciiz
inc di
cmp bx,9*4 ; places for thousands separator?
je lnout5a ; e = yes
cmp bx,6*4
je lnout5a
cmp bx,3*4
jne lnout6 ; ne = no
lnout5a:mov cl,lnoutsep ; get thousands separator
jcxz lnout6 ; z = none
mov word ptr [di],cx
inc di
lnout6: pop cx ; recover loop counter
loop lnout1
pop si
pop dx
pop cx
pop bx
pop ax
ret
lnout endp
code ends
end