NAME mssset ; File MSSSET.ASM ; Set command module ; edit history: ; Last edit: 4 Jan 1988 ; 1 Jan 1988 version 2.30 ; 4 Jan 1988 Check current disk on every Status display. [jrd] ; 3 Nov 1987 Fix parsing of Set Display with trailing spaces. [jrd] ; 19 Oct 1987 Cleanup, rewrite num0, allow \### in Set Escape-char. [jrd] ; 27 Aug 1987 Suppress Set Translate msgs if in quiet Take file. [jrd] ; 18 Aug 1987 Change ESC to escape for MASM 4.5+ [jrd] ; 31 July 1987 Increase Macro name space to 50 average names. [jrd] ; 7 July 1987 Change Show Macro to do cr/lf expansion internally. [jrd] ; 31 June 1987 Modify DEFINE Macro command to not parse backslash numbers ; to binary; instead convert only commas to binary cr and simply store ; everything else literally for the end user to parse. [jrd] ; 22 June 1987 Fix Set Remote On/Off display bits. [jrd] ; 13 June 1987 Rewrite Define/Do/Show Macro procedures to do automatic ; deletion of macro space. A macro can be removed by saying Def mac-name ; Permit backslash format binary numbers in defintions. Use base 10. ; Many numerical parsing routines removed to file msster.asm so this file ; will assemble under MASM 1.25. [jrd] ; 24 May 1987 Add SET DELAY seconds command. [jrd] ; 10 May 1987 Add keywords ON/OFF to Set Trans Input. Default is Off. ; On/off condition is byte rxtable[256] (0=off, else on). [jrd] ; 24 March 1987 Add path to default disk status display. ; Revise LOG Command to be LOG PACKETS | SESSION filespec [jrd] ; 21 March 1987 Add Set Translation and Show Translation commands to convert ; incoming serial port bytes while in Connect mode. ; Add full number parsing code (cnvlin, katio, decout, valout) here too. [jrd] ; 4 Jan 1987 Add jump to keyboard translator when invoking Set Key if global ; word stkadr (stored here) is non-zero; else use regular Set Key. Stkadr ; would hold the offset address of the replacement Set Key routine. [jrd] ; 19 Nov 1986 Update trans.(pad and padch) to use the Users preset values ; for I and S packets. [jrd] ; 1 Oct 1986 Version 2.29a ; 18 Sept 1986 Add 7-bit vs 8-bit flag to flags.remflg to control width ; of characters being displayed. Part of Set Display command. [jrd] ; 13 Sept 1986 Add \ooo octal # notation to Set Prompt command. [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] ; 14 August 1986 Introduce Set Send/Receive End-of-Line [jrd] ; 17 July 1986 Replace Status display proc with better code. [jrd] ; 14 July 1986 Add Long packet support for Set send/rec packet length. [jrd] ; Add Script support, Set Input, from James Sturdevant. [jrd] ; 26 June 1986 Update trans.seol in Set End-of-line so S packets use preferred ; (user specified) packet terminator. [jrd] ; 26 May 1986 Revise code to permit serial display. DISPLAY command now ; accepts Quiet, Regular, or Serial arguments. [jrd] ; [2.29] code frozen on 6 May 1986 [jrd] public setcom, status, baudprt, prmptr, dodef, stat0 public setcpt, docom, shomac, dmpname, widmsk, stkadr public setrx, shorx, rxtable include mssdef.h macmax equ 50 ; max # of macros maketab MACRO ; Assembler Macro to make rxtable [jrd] cnt = 0 rept 256 db cnt ; initialize table to 0 .. 255 cnt = cnt + 1 endm db 0 ; table off (0) or on (1) indicator ENDM datas segment public 'datas' extrn comand:byte, intake:byte, flags:byte, trans:byte, cptio:byte extrn takadr:word, taklev:byte, inichk:byte, portval:word extrn curdsk:byte, setktab:byte, setkhlp:byte, dtrans:byte extrn spause:byte, filtst:byte, maxtry:byte, imxtry:byte extrn indfto:word, inactv:byte, incasv:byte, inecho:byte extrn comptab:byte, termtb:byte kerm db 'Kermit-MS>$' crlf db cr,lf,'$' crlfsp db cr,lf,' ',' ','$' ; crlf space space eqs db ' = $' ermes1 db cr,lf,'?Too many macro names$' ermes2 db cr,lf,'?No room for macro definition$' ermes3 db cr,lf,'?Not confirmed$' ermes4 db cr,lf,'?No room in Take stack to expand macro$' ermes5 db cr,lf,'?Not implemented$' errcap db cr,lf,'?Unable to open that file$' filhlp db cr,lf,' Output filename for the log (def: Kermit.Log)$' dishlp db cr,lf,' Quiet (no screen writing), Regular (normal),' db ' Serial (non-formatted screen)' db cr,lf,' and/or 7-BIT (default) or 8-BIT wide characters.$' remhlp db cr,lf,' OFF to show file transfer statistics,' db ' ON for quiet screen$' macmsg db ' Specify macro name followed by body of macro, on same line$' shmmsg db ' Confirm with carriage return $' prmmsg db cr,lf db ' Enter new prompt string or nothing to regain regular prompt.' db cr,lf,' Use \123 notation for special chars (Escape is \27)$' srxhlp1 db cr,lf,' Enter code for received byte code for' db ' local byte ',cr,lf,' use ascii characters themselves or' db cr,lf,' numerical equivalents of \nnn decimal' db ' or \Onnn octal or \Xnnn hexadecimal',cr,lf db ' or keywords ON or OFF (translation is initially off)' db cr,lf,'$' badrx db cr,lf,' Bad byte code$' 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 '] $' rxoffmsg db cr,lf,' Input Translation is off.$' rxonmsg db cr,lf,' Input Translation is on.$' rxtable equ THIS BYTE ; build 256 byte Translation Input table maketab ; table rxtable is used by Connect mode. stkadr dw 0 ; non-zero if replacement keyboard xlator present prterr db '?Unrecognized value$' defpmp db 'Definition string: $' nonmsg db 'none$' delmsg db 'delete$' onmsg db 'on' offmsg db 'off' defcpt db 'KERMIT.LOG',0 ; default capture filename [jrd] dmpdefnam db 'KERMIT.SCN',0 ; asciiz default screen dump filename widmsk db 7FH ; non-pkt display width, def=7 bits tmp db ?,'$' min dw 0 max dw 0 numerr dw 0 numhlp dw 0 stflg db 0 ; Says if setting SEND or RECEIVE parameter. temp dw 0 temp1 dw ? ; Temporary storage. temp2 dw ? ; Temporary storage. modst db 'Mode line: $' locst db 'Local echo: $' belon db 'Ring bell after transfer$' beloff db 'No bell after transfer$' vtemst db 'Terminal emulation: $' ; terminal emulator [jrd] portst db 'Communications port: $' capmsg db 'Logging: $' dmpmsg db 'Dump screen file: $' eofmsg db 'EOF mode: $' flost db 'No flow control used$' floxmsg db 'Flow control: xon/xoff $' handst db 'Handshake used: $' destst db 'File destination: $' diskst db 'Path: $' blokst db 'Block check used: $' ;;ebyst db '8-bit quoting done only on request$' ;;ebvst db '8-bit quoting will be done with: $' sqcst db 'Send control char prefix: $' rqcst db 'Receive control char prefix: $' debon db 'Debug mode: $' flwon db 'Warning (filename change): $' parmsg db 'Parity: $' abfdst db 'Discard incomplete file$' abfkst db 'Keep incomplete file$' sndmsg db 'Send Delay: $' sndmsg2 db ' sec, Pause: $' sndmsg3 db ' ms$' ssohst db 'Send start-of-packet char: $' rsohst db 'Receive start-of-packet char: $' meolst db 'End-of-Line char S: ',5eh,'$' mseol2 db ' R: ',5eh,'$' stimst db 'Send timeout (seconds): $' rtimst db 'Receive timeout (seconds): $' spakst db 'Send packet size: $' rpakst db 'Receive packet size: $' snpdst db '# of send padding chars: $' rnpdst db '# of receive padding chars: $' retrymsg db 'Retry send/receive packet limit: $' dispst db 'Display (vs Remote):$' remost db 'Remote (vs Display) $' timmsg db 'Timer: $' escmes db 'Escape character: $' scpmsg db 'Scripts(Input):$' scpmsne db ' echo:off, $' scpmse db ' echo:on, $' casmsi db 'case:ignore, $' casmso db 'case:observe, $' scptms db 'def-tmo: $' scpmsp db ' sec, tmo-action:proceed$' scpmsq db ' sec, tmo-action:quit$' baudrt db 'Baud rate is $' unrec db 'unknown$' nummsg1 db cr,lf,'?Use a number between $' nummsg2 db ' and $' dmphlp db 'Enter name of disk file to hold screen dumps$' eolhlp db cr,lf,'Decimal number between 0 and 31$' timhlp db cr,lf,'Decimal number between 0 and 94$' quohlp db cr,lf,'Decimal number between 33 and 126$' pakerr db cr,lf,'Illegal packet length. Choose a decimal number ' db cr,lf,'from 20 to 94 (normal) or to 1000 (long)$' pakhlp db cr,lf,'Decimal number between 20 and 94 (normal) or ' db '1000 (long)$' npdhlp db cr,lf,'Decimal number between 0 and 99$' paderr db cr,lf,'Illegal pad character$' padhlp db cr,lf,'Decimal number between 0 and 31 or 127$' pauhlp db cr,lf,'Decimal number between 0 and 127$' retryhlp db cr,lf,'Decimal number between 1 and 63$' delyhlp db cr,lf,'Delay seconds before sending file (0-63)$' eschlp db cr,lf,'Press literal control code (ex: Cntrl ]) or' db ' enter numerical value in \### form$' escerr db cr,lf,'?Not a control code$' dskhlp db cr,lf,'Default disk drive to use, such as A:$' dskerr db cr,lf,'Invalid drive specification$' hnd1hlp db cr,lf,'xon (17), xoff (19), cr (13), lf (10), bell (7),' db ' esc (27), none (0)' db cr,lf,' or "code" followed by decimal number$' hnd2hlp db cr,lf,'Decimal number between 0 and 31$' intoms db 'number of seconds to wait before timeout',cr,lf,'$' loghlp db cr,lf,' PACKETS - during file transfers' db cr,lf,' SESSION - during Connect mode' db cr,lf,' followed by optional filename (default is KERMIT.LOG)$' debhlp db cr,lf,' PACKETS - during file transfers' db cr,lf,' SESSION - during Connect mode' db cr,lf,' ON - both packets and sessions' db cr,lf,' OFF - turns off all debugging$' sethlp db cr,lf,lf db ' Baud or Speed many speeds ' db ' Key key-ident definition ' db cr,lf db ' Bell on/off at end of xfers ' db ' Local-echo on/off' db cr,lf db ' Block-check-type checksum/CRC ' db ' Mode-line on/off' db cr,lf db ' Debug on/off display packets ' db ' Parity even/odd/mark/space/none' db cr,lf db ' Default-disk ' db ' Port for i/o 1/2/COM1/COM2' db cr,lf db ' Delay secs before Sending file ' db ' Prompt string (new Kermit prompt)' db cr,lf db ' Destination Disk/Screen/Printer ' db ' Receive parameter many things' db cr,lf db ' Display quiet/reg/serial show cnts?' db ' Remote on/off show xfer counts?' db cr,lf db ' Dump filespec screen to disk ' db ' Retry limit for packet send/receive' db cr,lf db ' End-of-line char cr or whatever ' db ' Send parameter many things' db cr,lf db ' EOF Ctrl-Z/NoCtrl-Z ^Z ends file? ' db ' Take-echo on/off display commands?' db cr,lf db ' Escape char ^] or whatever ' db ' Terminal none, Heath-19, VT52, VT102,' db cr,lf db ' Flow-control xon-xoff or none ' db ' and many terminal setup parameters' db cr,lf db ' Handshake xon/xoff/cr/lf/bell/esc..' db ' Timer on/off time packet waiting' db cr,lf db ' Incomplete file keep/discard ' db ' Translation IN Connect mode rcv',27h,'d char' db cr,lf db ' Input timeout, etc (for scripts) ' db ' Warning on/off if file renamed' db cr,lf,'$' settab db 32 mkeyw 'Baud',baudst mkeyw 'Bell',bellst mkeyw 'Block-check-type',blkset mkeyw 'Debug',debst mkeyw 'Default-disk',dskset mkeyw 'Delay',setdely mkeyw 'Destination',desset mkeyw 'Display',disply mkeyw 'Dump',setdmp mkeyw 'End-of-Line',eolset mkeyw 'EOF',seteof mkeyw 'Escape',escset mkeyw 'Flow-control',floset mkeyw 'Handshake',hndset mkeyw 'Incomplete',abfset mkeyw 'Input',inpset mkeyw 'Key',setkey mkeyw 'Local-echo',lcal mkeyw 'Mode-line',modl mkeyw 'Parity',setpar mkeyw 'Port',coms mkeyw 'Prompt',promset mkeyw 'Receive',recset mkeyw 'Remote',remset mkeyw 'Retry',retryset mkeyw 'Send',sendset mkeyw 'Speed',baudst mkeyw 'Take-echo',takset mkeyw 'Terminal',vts mkeyw 'Timer',timset mkeyw 'Translation',setrx mkeyw 'Warning',filwar seoftab db 2 mkeyw 'Ctrl-Z',1 mkeyw 'NoCtrl-Z',0 stsrtb db 8 ; Number of options. mkeyw 'End-of-Line',sreol mkeyw 'Packet-length',srpack mkeyw 'Padchar',srpad mkeyw 'Padding',srnpd mkeyw 'Pause',srpaus mkeyw 'Quote',srquo mkeyw 'Start-of-packet',srsoh mkeyw 'Timeout',srtim ontab db 2 mkeyw 'off',0 mkeyw 'on',1 destab db 3 ; Three choices mkeyw 'Disk',1 mkeyw 'Printer',0 mkeyw 'Screen',2 distab db 5 ; Set Display mode [jrd] mkeyw '7-bit',7 ; controls bit d8bit in flags.remflg mkeyw '8-bit',8 ; sets d8bit mkeyw 'Quiet',dquiet ; values defined in header file mkeyw 'Regular',dregular mkeyw 'Serial',dserial 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 ; What type of block check to use. blktab db 3 mkeyw '1-character-checksum',1 mkeyw '2-character-checksum',2 mkeyw '3-character-CRC-CCITT',3 ; If abort when receiving files, can keep what we have or discard abftab db 2 ; Only two options. mkeyw 'Discard',1 mkeyw 'Keep',0 partab db 5 ; Five entries mkeyw 'even',PAREVN mkeyw 'mark',PARMRK mkeyw 'none',PARNON mkeyw 'odd',PARODD mkeyw 'space',PARSPC flotab db 2 mkeyw 'none',flonon mkeyw 'xon/xoff',floxon hndtab db 8 mkeyw 'bell',bell mkeyw 'code',0ffh ; allow general numerial code [jrd] mkeyw 'cr',cr mkeyw 'esc',escape mkeyw 'lf',lf mkeyw 'none',0 mkeyw 'xoff',xoff mkeyw 'xon',xon inptab db 4 ; Scripts. Set Input mkeyw 'Case',inpcas ;[jrs] mkeyw 'Default-timeout',inptmo ;[jrs] mkeyw 'Echo',inpeco ;[jrs] mkeyw 'Timeout-action',inpact ;[jrs] 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] bdtab db 18 ; 18 entries mkeyw '110',b0110 mkeyw '115200',b115200 mkeyw '1200',b1200 mkeyw '134.5',b01345 mkeyw '150',b0150 mkeyw '1800',b1800 mkeyw '19200',b19200 mkeyw '2000',b2000 mkeyw '2400',b2400 mkeyw '300',b0300 mkeyw '38400',b38400 mkeyw '45.5',b00455 mkeyw '4800',b4800 mkeyw '50',b0050 mkeyw '57600',b57600 mkeyw '600',b0600 mkeyw '75',b0075 mkeyw '9600',b9600 debtab db 4 ; Set Debug command mkeyw 'Off',0 mkeyw 'On',logpkt+logses mkeyw 'Packets',logpkt mkeyw 'Session',logses logtab db 2 ; LOG command mkeyw 'Packets',logpkt mkeyw 'Session',logses logsta db 4 ; Log Status table mkeyw 'off',logoff ; suspended or no logging mkeyw 'Packets',logpkt mkeyw 'Session',logses mkeyw 'Packet+Session',logpkt+logses trnstab db 1 ; Set Translation table mkeyw 'Input',1 prmptr dw kerm ; pointer to prompt prm db 80 dup (?) ; Buffer for new prompt. dmpname db 'KERMIT.SCN',54 dup (0) ; file name for screen dumps [jrd] rdbuf db 128 dup (?) ; work space; room for macro def too ; and for Status display line mcctab db 1 ; macro name table, one initially mkeyw 'IBM',ibmmac ; offset of definition string (7 bytes) db (macmax*10 - 7) dup (?) ; room for rest of macro names mcclen equ $-mcctab ; length of mcctab mccptr dw mcctab + 8 ; ptr to first free byte in mcctab macbuf equ this byte ; buffer of macro strings ibmmac db imlen ; startup IBM macro definition db 'set timer on',cr,'set parity mark',cr db 'set local-echo on',cr,'set handshake xon',cr db 'set flow none',cr imlen equ $-ibmmac-1 db (macmax*60 -imlen-1) dup (?); space for additonal macro defs maclen equ $ - macbuf ; length of macbuf macptr dw macbuf+imlen+1 ; ptr to first free byte in macbuf shom9a db cr,lf,' Free space (bytes) for names: $' shom9c db ', for definitions: $' ; 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 sttab stent stent ; terminal emulator stent stent stent stent stent stent stent stent stent stent stent stent stent stent stent stent stent stent stent stent stent stent stent stent stent stent stent stent stent stent stent stent stent stent ; Terminal status, in MSX dw 0 ; end of table datas ends code segment public 'code' extrn prserr:near, comnd:near, dobaud:near, cmblnk:near, locate:near extrn cmgtch:near, repars:near, coms:near, defkey:near extrn inicpt:near, prompt:near, prtscr:near extrn getbaud:near, isfile:near, strlen:near extrn strcpy:near, cnvlin:near, katoi:near, decout:near, atoi:near extrn vts:near, vtstat:near assume cs:code, ds:datas, es:nothing ; DO defined macro command DOCOM PROC NEAR mov dx,offset mcctab mov bx,0 mov ah,cmkey call comnd jmp r mov temp,bx mov ah,cmcfm call comnd jmp r nop mov bx,temp cmp taklev,maxtak ; room in take level? jl docom2 ; yes, continue mov dx,offset ermes4 ; else complain jmp reterr docom2: inc taklev ; increment take level (overflow) add takadr,size takinfo mov si,bx ; point to macro definition mov cl,[si] ; get size from initial byte mov ch,0 inc si ; point to actual definition mov bx,takadr ; point to current buffer mov [bx].taktyp,0ffh ; flag as a macro mov [bx].takptr,si ; point to beginning of def mov [bx].takchl,cl ; # of chars left in buffer mov [bx].takcnt,cx ; and in definition mov word ptr [bx].takcnt+2,0 ; zero high order... jmp rskp DOCOM ENDP ; DEFINE macro command ; Data structures comments. Macro name is stored in table mcctab as if we ; had used macro mkeyw, such as mkeyw 'mymac',offset my_definition. ; In detail: db length of name ; db 'name' ; db '$' ; dw offset of definition string ; Mcctab begins with a byte holding the number of macros in the table; one, ; IBM, is established at assembly time. Mcctab is 10*macmax bytes long. ; Pointer mccptr holds the offset of the next free byte in mcctab. ; Definition strings are stored in table macbuf as ; db length of definition string below ; db 'definition string' ; Pointer macptr holds the offset of the next free byte in macbuf. Macbuf ; is nominally 100*macmax bytes long. ; A new definition is read into buffer rdbuf+1, where byte rdbuf is reserved ; to hold the length of the macro's name during intermediate processing. ; If the definition is absent then the macro is removed from the tables. ; Rewritten 13 June 1987 [jrd] DODEF PROC NEAR mov ah,cmtxt mov bx,offset rdbuf+1 ; buffer for keyword mov dx,offset macmsg call comnd jmp r nop xchg ah,al xor ah,ah mov temp,ax ; save length of command line cmp ax,0 ; is command line empty? jne dode1 ; ne = no ret ; return not confirmed dode1: mov ah,cmcfm ; get a confirm call comnd jmp r nop push ds ; address data segment pop es cld ; strings go forward mov cx,temp ; cmd line len, cx = running counter mov rdbuf,0 ; number of chars in keyword so far ; uppercase the keyword, look for end mov si,offset rdbuf+1 ; point at macro name text dode2: lodsb ; get a byte, dec cx cmp al,'a' ; map lower case to upper jb dode3 cmp al,'z' ja dode3 sub al,'a'-'A' mov [si-1],al ; uppercase if necessary dode3: inc rdbuf ; increment char count of keyword cmp al,' ' ; is this the break character? loopne dode2 ; no, loop thru rest of word jne dode4 ; ended with break char? dec rdbuf ; yes, don't count in length dode4: call remtab ; remove any duplicate keyword jcxz dode6 ; cx = 0 means no keyword ; check for free space for keyword and string mov al,rdbuf ; keyword text length add al,4 ; plus overhead bytes xor ah,ah add ax,mccptr ; add to free space pointer cmp ax,offset mcctab+mcclen ; enough room? jb dode5 ; b = yes mov dx,offset ermes1 ; too many macro names jmp reterr dode5: mov di,si ; scan after keyword name mov al,' ' ; remove leading spaces in string repe scasb je dode6 ; e = all spaces inc cx ; offset auto decrement of rep dec di ; offset auto increment of rep mov si,di ; point to start of string text mov dx,di ; source of definition text call strlen ; get length of string into cx mov ax,cx ; length of string mov temp,cx ; remember it here inc ax ; plus its count byte add ax,macptr ; plus free space pointer cmp ax,offset macbuf+maclen ; enough room? jb dode7 ; b = yes mov dx,offset ermes2 ; no room for definition jmp reterr dode6: jmp rskp ; install new keyword in mcctab dode7: cmp temp,0 ; temp = length of definition je dode10 ; e = no def, exit now mov bx,offset mcctab mov dx,offset rdbuf call addtab ; copy definition into buffer, changing commas to CRs mov di,macptr ; free space in string buffer mov bx,di ; look at count byte inc di ; skip over count byte mov cx,temp ; length of string text mov byte ptr[bx],cl ; store length of string dode8: lodsb ; get a byte cmp al,',' ; comma? jne dode9 ; no, keep going mov al,cr ; else replace with cr dode9: stosb loop dode8 ; keep copying mov cx,temp inc cx ; number of bytes copied overall add macptr,cx ; update free ptr dode10: jmp rskp DODEF ENDP ; add an entry to a keyword table ; enter with bx = table address, dx = ptr to new entry, macptr = string offset, ; mccptr = offset of free bytes in table mcctab. ; no check is made to see if the entry fits in the table. addtab proc near push cx push si push es cld mov ax,ds mov es,ax ; address data segment mov bp,bx ; remember where tbl starts mov cl,[bx] ; pick up length of table mov ch,0 inc bx ; point to actual table... jcxz addta4 ; cx = 0 if table is presently empty addta1: push cx ; preserve count mov si,dx ; point to entry lodsb ; get length of new entry mov cl,[bx] ; and length of table entry... mov ah,0 ; assume they're the same size cmp al,cl ; are they the same? lahf ; remember result of comparison... jae addta2 ; is new smaller? no, use table length mov cl,al ; else use length of new entry addta2: mov ch,0 lea di,[bx+1] ; point to actual keyword repe cmpsb ; compare strings pop cx ; restore count jb addta4 ; below, insert before this one jne addta3 ; not below or same, keep going sahf ; same. get back result of length comparison jb addta4 ; if new len is smaller, insert here jne addta3 ; if not same size, keep going mov si,bx ; else this is where entry goes jmp short addta6 ; no insertion required... addta3: mov al,[bx] mov ah,0 add bx,ax ; skip this entry add bx,4 ; len + $ + value... loop addta1 ; and keep looking addta4: mov si,bx ; this is first location to move mov di,bx inc ds:byte ptr [bp] ; remember we're adding one... jcxz addta6 ; no more entries, forget this stuff mov bh,0 ; this stays 0 addta5: mov bl,[di] ; get length lea di,[bx+di+4] ; end is origin + length + 4 for len, $, value loop addta5 ; loop thru remaining keywords mov cx,di sub cx,si ; compute # of bytes to move push si ; preserve loc for new entry mov si,di ; first to move is last dec si ; minus one mov di,dx ; new entry mov bl,[di] ; get length lea di,[bx+si+4] ; dest is source + length of new + 4 std ; move backwards rep movsb ; move the table down cld ; put flag back pop si addta6: mov di,si ; this is where new entry goes mov si,dx ; this is where it comes from mov cl,[si] ; length mov ch,0 add cx,1 ; count byte add mccptr,cx ; update free space pointer: cnt+name add mccptr,3 ; plus '$' and pointer to string rep movsb ; stick it in mov al,'$' ; add printing terminator stosb mov ax,macptr ; and string offset stosw pop es pop si pop cx ret addtab endp ; If new keyword matches an existing one then remove existing keyword, ; its string definition, compress tables mcctab and macbuf, readjust string ; pointers for each macro name, reduce number of macro table entries by one. ; Otherwise, exit with no changes. 13 June 1987 [jrd] remtab proc near push ax push bx push cx push si push di mov si,offset rdbuf+1 ; point to new macro name mov bx,offset mcctab+1 ; table of macro keywords mov temp,0 ; temp = current keyword cmp byte ptr mcctab,0 ; any macros defined? jne remta1 ; ne = yes jmp remtax ; else exit now remta1: ; match table keyword and text word mov cl,rdbuf ; length of user's macro name xor ch,ch cmp cl,byte ptr [bx] ; compare length vs table keyword jne remta4 ; ne = not equal lengths, try another push si ; lengths match, how about spelling? push bx inc bx ; point at start of keyword remta2: mov ah,byte ptr [bx] ; keyword char mov al,byte ptr [si] ; new text char cmp al,ah ; test characters jne remta3 ; ne = no match inc si ; move to next char inc bx loop remta2 ; loop through entire length remta3: pop bx pop si jcxz remta6 ; z: cx = 0, exit with match; ; else select next keyword remta4: inc temp ; number of keyword to test next mov cx,temp cmp cl,mcctab ; all done? Recall, temp starts at 0 jb remta5 ; b = not yet jmp remtax ; exhausted search, unsuccessfully remta5: mov al,byte ptr [bx] ; cnt (keyword length from macro) xor ah,ah add ax,4 ; skip over '$' and two byte value add bx,ax ; bx = start of next keyword slot jmp remta1 ; do another comparison ; new name already present as a macro remta6: cld ; clear macro string and macro name push ds pop es ; set es to datas segment mov temp,bx ; save ptr to found keyword mov al,byte ptr [bx] ; cnt (keyword length of macro) xor ah,ah add ax,2 ; skip cnt and '$' add bx,ax ; point to string offset field add ax,2 ; count offset field bytes sub mccptr,ax ; readjust free space ptr for names push bx mov bx,[bx] mov temp1,bx ; temp1 = offset of old string mov al,byte ptr[bx] ; length of old string xor ah,ah inc ax ; plus its count byte mov temp2,ax ; save here pop bx ; clear keyword table mcctab add bx,2 ; compute source = next keyword mov si,bx ; address of next keyword mov di,temp ; address of found keyword mov cx,offset mcctab+mcclen ; address of buffer end sub cx,si ; amount to move jcxz remtax ; cx = 0 means none rep movsb ; move down keywords (deletes current) ; revise other string offsets mov si,offset mcctab ; table of string offsets inc si ; skip count byte mov cl,mcctab ; current number of table entries xor ch,ch dec mcctab ; one less keyword mov dx,temp1 ; address of old string remta7: mov al,byte ptr[si] ; cnt of first keyword add al,2 ; plus cnt and '$' xor ah,ah add si,ax ; look at string offset cmp dx,[si] ; old address vs this string ja remta8 ; a = address not affected mov ax,temp2 ; size of old string sub [si],ax ; adjust offset downward remta8: add si,2 ; point to next table entry loop remta7 ; remove old string mov di,temp1 ; address of old string = destination mov ax,temp2 ; size of old string field mov si,di add si,ax ; plus length: source = next string sub macptr,ax ; readjust top of buf free string ptr mov cx,offset macbuf+maclen ; end of buffer sub cx,si ; number of bytes to move jcxz remtax ; cx = 0 means none rep movsb ; move down old strings remtax: pop di pop si pop cx pop bx pop ax ret remtab endp ; This is the SET command. SETCOM PROC NEAR mov dx,offset settab ; Parse a keyword from the set table. mov bx,offset sethlp mov ah,cmkey call comnd jmp r call bx jmp short setco2 nop setco1: jmp rskp setco2: cmp comand.cmstat,cmcfm ; is there a confirm at the end? je setco1 ; e = yes, ok ret ; return non-confirmed SETCOM endp ; SET BAUD or SET SPEED. BAUDST PROC NEAR mov dx,offset bdtab mov bx,0 mov ah,cmkey call comnd jmp r mov temp,bx mov ah,cmcfm call comnd ; Get a confirm. jmp r ; Didn't get one. nop mov bx,temp mov si,portval mov ax,[si].baud ; Remember original value mov [si].baud,bx ; Set the baud rate. call dobaud ; Use common code ret BAUDST ENDP ; SET BELL on or off BELLST PROC NEAR mov dx,offset ontab mov bx,0 mov ah,cmkey call comnd jmp r mov temp,bx mov ah,cmcfm call comnd jmp r nop mov bx,temp mov flags.belflg,bl ret BELLST ENDP ; SET BLOCK-CHECK BLKSET PROC NEAR mov dx,offset blktab mov bx,0 mov ah,cmkey call comnd jmp r mov temp,bx mov ah,cmcfm call comnd ; Get a confirm. jmp r ; Didn't get a confirm. nop mov bx,temp mov trans.chklen,bl ; Use this char as the handshake. mov inichk,bl ; Save here too. ret BLKSET ENDP ; SET DEBUG {OFF | ON | SESSSION | PACKETS} DEBST PROC NEAR mov dx,offset debtab mov bx,offset debhlp mov ah,cmkey call comnd jmp r mov temp,bx mov ah,cmcfm call comnd ; Get a confirm. jmp r ; Didn't get a confirm. nop mov bx,temp or flags.debug,bl ; set the mode, except for Off. cmp bx,0 ; OFF? jne deb0 ; ne = no mov flags.debug,0 ; Set the DEBUG flags off. deb0: ret DEBST ENDP ; SET DESTINATION of incoming files. DESSET PROC NEAR mov dx,offset destab mov bx,0 mov ah,cmkey call comnd jmp r mov temp,bx mov ah,cmcfm call comnd ; Get a confirm. jmp r ; Didn't get a confirm. nop mov bx,temp mov flags.destflg,bl ; Set the destination flag. cmp bl,2 ; Is dest the screen? jne desa ; No, then done mov flags.xflg,1 ; Remember it here ret desa: mov flags.xflg,0 ; Don't write to screen ret DESSET ENDP ; SET DEFAULT-DISK for sending/receiving, etc. DSKSET PROC NEAR mov ah,cmfile ; Parse for drive specification. [jrd] mov dx,offset rdbuf ; Read into handy buffer. mov bx,offset dskhlp ; Text of help message. call comnd jmp r mov ah,cmcfm call comnd jmp r mov ah,rdbuf ; Get the drive they said to use. cmp ah,0 ; Did they type a bare CR? je dsk0 ; Yes, complain. cmp ah,'a' ; alphabetic? jl dsk2 sub ah,'a'-1 ; convert to 1 = a, 2 = b, etc jmp dsk3 dsk2: cmp ah,'A' jl dsk0 ; opps, a non-alpha sub ah,'A'-1 ; convert to numeric dsk3: mov curdsk,ah ; And remember it. dec ah mov dl,ah mov ah,seldsk int dos mov ah,gcurdsk ; succeeded? get current disk int dos inc al ; map to 1 = a, etc cmp al,curdsk ; same? jne dsk4 ; ne = no ret dsk4: mov curdsk,al ; get back actual current disk dsk0: mov ah,prstr mov dx,offset dskerr ; Illegal drive specification. int dos ret DSKSET ENDP ; SET DELAY seconds Used only for SEND command in local mode SETDELY PROC NEAR mov min,0 ; smallest acceptable value mov max,63 ; largest acceptable value mov numhlp,offset delyhlp ; help message mov numerr,0 ; complaint message call num0 ; parse numerical input mov trans.sdelay,al ret SETDELY ENDP ; SET DISPLAY Quiet/Regular/Serial/7-Bit/8-Bit (inverse of Set Remote on/off) ; Accepts two keywords in one command. [jrd] disply proc near mov ah,cmkey mov dx,offset distab mov bx,offset dishlp call comnd jmp r mov temp1,bx ; save parsed value mov temp2,0ffh ; assume no second keyword cmp comand.cmsflg,0 ; first command ended with whitespace? je displ1 ; e = no, get a confirm mov comand.cmcr,1 ; bare CR's are allowed mov ah,cmkey ; parse for second keyword mov dx,offset distab mov bx,offset dishlp call comnd jmp displ1 ; no matching keyword nop nop mov temp2,bx ; get key value displ1: mov comand.cmcr,0 ; bare CR's are not allowed mov ah,cmcfm call comnd ; confirm jmp r ; return on failure nop mov bx,temp1 ; examine first key value cmp bx,0 ; check range jle displ3 ; le = not legal cmp bx,7 ; 7-8 bit value? jge displ2 ; ge = yes mov flags.remflg,bl ; set display mode jmp displ3 ; check next key value displ2: cmp bx,8 ; set 8-bit wide display? ja displ3 ; a = bad value and flags.remflg,not d8bit ; assume want 7 bit mode cmp bx,7 ; really want 7 bit mode? je displ3 ; e = yes or flags.remflg,d8bit ; set 8 bit flag displ3: mov bx,temp2 ; examine second key value cmp bx,0 ; check range jle displ5 ; le = not legal cmp bx,7 ; 7-8 bit value? jge displ4 ; ge = yes mov flags.remflg,bl ; set display mode jmp displ5 ; all done displ4: cmp bx,8 ; set 8-bit wide display? ja displ5 ; a = bad value and flags.remflg,not d8bit ; assume want 7 bit mode cmp bx,7 ; really want 7 bit mode? je displ5 ; e = yes or flags.remflg,d8bit ; set 8 bit flag displ5: ret disply endp ; Set Dump filename for saving screen images on disk. [jrd] ; Puts filename in global string dmpname. setdmp proc near mov dx,offset rdbuf ; work area mov byte ptr rdbuf,0 ; clear it mov bx,offset dmphlp ; help message mov ah,cmfile ; allow paths call comnd jmp r mov ah,cmcfm call comnd jmp r mov dx,offset rdbuf ; assume we will use this text call strlen ; filename given? mov si,dx ; for strcpy cmp cx,0 ; length of user's filename jg setdmp1 ; g = filename is given mov si,offset dmpdefnam ; no name, use default instead. setdmp1:mov di,offset dmpname ; copy to globally available loc. call strcpy ret setdmp endp ; SET EOF seteof proc near mov ah,cmkey mov bx,0 mov dx,offset seoftab call comnd jmp r mov temp,bx mov ah,cmcfm call comnd jmp r ; error return... nop mov bx,temp mov flags.eofcz,bl ; set value ret seteof endp ; SET EOL char (for Sent packets) ; Archic, here for downward compatibility EOLSET PROC NEAR mov stflg,'S' ; set send/receive flag to Send jmp sreol ; use Set Send/Rec routine do the work EOLSET ENDP ; SET ESCAPE character. ; Accept literal control codes and \### numbers. [jrd] 18 Oct 1987 ESCSET PROC NEAR mov ah,cmfile mov dx,offset rdbuf ; work space mov word ptr rdbuf,0 ; clear it mov bx,offset eschlp ; help call comnd jmp r nop cmp ah,0 ; anything given? jne escse1 ; ne = yes ret ; else return unconfirmed escse1: mov ah,cmcfm ; get a confirm call comnd jmp r nop mov si,offset rdbuf ; source of chars call katoi ; convert escaped numbers to binary cmp ax,spc ; is it a control code? jae escse2 ; ae = no, complain cmp ax,0 ; non-zero too? je escse2 ; e = zero mov trans.escchr,al ; Save new value. ret escse2: mov dx,offset escerr jmp reterr ESCSET ENDP ; SET FILEWARNING FILWAR PROC NEAR mov dx,offset ontab mov bx,0 mov ah,cmkey call comnd jmp r mov temp,bx mov ah,cmcfm call comnd ; Get a confirm. jmp r ; Didn't get a confirm. nop mov bx,temp mov flags.flwflg,bl ; Set the filewarning flag. ret FILWAR ENDP ; SET FLOW-CONTROL FLOSET PROC NEAR mov dx,offset flotab xor bx,bx mov ah,cmkey call comnd jmp r mov temp,bx mov ah,cmcfm call comnd ; Get a confirm. jmp r ; Didn't get a confirm. nop mov bx,temp mov si,portval mov [si].flowc,bx ; Flow control value. cmp bx,0 ; Turning it off? je flo0 ; Yes. mov [si].floflg,1 ; Say we're doing flow control. ret flo0: mov [si].floflg,bl ; Say we're not doing flow control. ret FLOSET ENDP ; SET HANDSHAKE ; Add ability to accept general decimal code. [jrd] HNDSET PROC NEAR mov dx,offset hndtab ; table to scan mov bx,offset hnd1hlp ; help message mov ah,cmkey call comnd jmp r cmp bl,0ffh ; want a general char code? jne hnd1 ; ne = no mov min,0 ; get decimal char code mov max,31 ; range is 0 to 31 decimal mov numhlp,offset hnd2hlp ; help message. mov numerr,0 ; error message call num0 ; convert number, return it in ax mov bx,ax ; recover numerical code hnd1: mov temp,bx ; handshake type mov ah,cmcfm call comnd ; Get a confirm. jmp r ; Didn't get a confirm. nop mov bx,temp ; recover bx mov si,portval cmp bl,0 ; Setting handshake off? je hnd0 ; Yes. mov [si].hndflg,1 ; And turn on handshaking. mov [si].hands,bl ; Use this char as the handshake. ret hnd0: mov [si].hndflg,0 ; No handshaking. ret HNDSET ENDP ; SET INCOMPLETE file disposition ABFSET PROC NEAR mov dx,offset abftab mov bx,0 mov ah,cmkey call comnd jmp r mov temp,bx mov ah,cmcfm call comnd ; Get a confirm. jmp r ; Didn't get a confirm. nop mov bx,temp mov flags.abfflg,bl ; Set the aborted file flag. ret ABFSET ENDP ; ; Set Input commands (default-timeout, timeout-action, case, echo) ; By Jim Strudevant [jrs]. INPSET PROC NEAR mov ah,cmkey ; key word mov dx,offset inptab ; from inputtable mov bx,0 ; no hints call comnd ; get the word jmp r ; they blew it call bx ; call the sub command jmp r ; bad return jmp rskp ; good return ; ; Set Input Default-timeout in seconds ; inptmo: mov ah,cmtxt ; get a line of text mov bx,offset rdbuf ; put it here mov dx,offset intoms ; here's some help call comnd ; get it jmp r ; nothing typed mov cl,ah ; get the length xor ch,ch mov si,offset rdbuf ; set up call atoi ; make it a number jmp r ; bad number mov indfto,ax ; save it jmp rskp ; good return ; ; Set Input Timeout action (proceed or quit) ; inpact: mov ah,cmkey ; get a keyword mov dx,offset inactb ; from this list mov bx,0 ; no hints call comnd ; get it jmp r ; bad input mov inactv,bl ; save the action jmp rskp ; good return ; ; Set Input Echo on or off ; inpeco: mov ah,cmkey ; get a keyword mov dx,offset ontab ; from this list mov bx,0 ; no hints call comnd ; get it jmp r ; bad input mov inecho,bl ; save the action jmp rskp ; good return ; ; Set Input Case observe or ignore ; inpcas: mov ah,cmkey ; get a keyword mov dx,offset incstb ; from this list mov bx,0 ; no hints call comnd ; get it jmp r ; bad input mov incasv,bl ; save the action jmp rskp ; good return INPSET ENDP ; SET KEY ; Jumps to new Set Key routine setkey proc near cmp stkadr,0 ; keyboard translator present? [jrd] je setk4 ; e = no, use this routine mov bx,stkadr ; yes, get offset of procedure jmp bx ; jump to keyboard translator [jrd] setk4: mov dx,offset ermes5 jmp reterr ; else print error message setkey endp ; SET LOCAL-ECHO {ON | OFF} LCAL PROC NEAR mov dx,offset ontab mov bx,0 mov ah,cmkey call comnd jmp r mov temp,bx ; Save the parsed value. mov ah,cmcfm call comnd ; Get a confirm. jmp r ; Didn't get a confirm. nop mov bx,temp mov si,portval mov [si].ecoflg,bl ; Set the local echo flag. ret LCAL ENDP ; LOG {PACKETS | SESSION} filename ; addition for capture of raw output ; revised by [jrd] to use full DOS 2.0 path name setcpt proc near mov dx,offset logtab ; kinds of logging mov bx,offset loghlp ; help on kind of logging mov ah,cmkey ; parse keyword call comnd jmp r mov temp,bx ; Save the parsed value. mov dx,offset cptio.string ; holds the complete filename mov bx,offset filhlp ; ask for filename mov ah,cmfile ; allow paths call comnd jmp r mov ah,cmcfm call comnd ; Get a confirm. jmp r ; Didn't get a confirm. cmp flags.capflg,0 ; is capturing active already? jne setcp5 ; ne = yes, just update kind mov dx,offset cptio.string call strlen ; filename given? cmp cx,0 ; length of user's filename jg setcp4 ; g = filename is given mov dx,offset defcpt ; use default name instead. setcp4: mov ax,dx ; place for filename for isfile. call isfile ; does file exist already? jc setcp3 ; c = does not exist. test byte ptr filtst.dta+21,1fh ; file attributes, ok to write? jnz setcp2 ; nz = no. mov ah,open2 ; open existing file. mov al,2 ; opened for reading and writing int dos ; do it jc setcp2 ; if carry bit set then error mov cptio.handle,ax ; save filehandle mov bx,ax ; file handle for seeking mov cx,0ffffh ; high order displacement (-1 ext) mov dx,-1 ; low order part of displacement mov ah,lseek ; seek to EOF (to do appending) mov al,2 ; says to EOF int dos call inicpt ; init capture variables setcp5: mov ax,temp ; kind of Logging or al,al ; is logging off? jne setcp4a ; ne = no, add this type to the list mov flags.capflg,al ; say capture routine is inactive setcp4a:or flags.capflg,al ; accumulate kinds of logging jmp rskp ; and return setcp3: test filtst.fstat,80h ; access problem? jnz setcp2 ; nz = yes, stop here mov ah,creat2 ; function is create, v 2.0 mov cl,20H ; turn on archive bit mov ch,0 int dos ; create the file, DOS 2.0 jc setcp2 ; if carry bit set then error mov cptio.handle,ax ; save filehandle call inicpt ; init capture variables mov ax,temp ; kind of logging or al,al ; is logging off? jne setcp3a ; ne = no, add this type to the list mov flags.capflg,al ; say capture routine is inactive setcp3a:or flags.capflg,al ; accumulate kinds of logging jmp rskp ; and return setcp2: mov dx,offset errcap ; give error message jmp reterr ; and display it setcpt endp ; SET MODE LINE MODL PROC NEAR mov dx,offset ontab ; parse an on or off mov bx,0 ; no special help... mov ah,cmkey call comnd jmp r mov temp,bx ; save value mov ah,cmcfm call comnd jmp r nop mov bx,temp mov flags.modflg,bl ; set flag appropriately ret MODL ENDP ; SET PARITY SETPAR PROC NEAR mov dx,offset partab mov bx,0 mov ah,cmkey call comnd jmp r mov temp,bx mov ah,cmcfm call comnd ; Get a confirm. jmp r ; Didn't get a confirm. nop mov bx,temp mov si,portval mov [si].parflg,bl ; Set the parity flag. cmp bl,parnon ; Resetting parity to none? je setp0 ; Yes, reset 8 bit quote character. mov trans.ebquot,dqbin ; Else, do quoting ret ; That's it setp0: mov trans.ebquot,'Y' ; If none, say will quote upon request ret SETPAR ENDP ; SET PROMPT Allow user to change the "Kermit-MS>" prompt. ; {string} and \number notation permitted to represent special chars. [jrd] PROMSET PROC NEAR mov ah,cmtxt mov bx,offset rdbuf ; Read in the prompt. mov word ptr [bx],0 ; clear buffer mov dx,offset prmmsg call comnd jmp r mov ah,cmcfm ; get a confirm call comnd jmp r cmp rdbuf,0 ; Just a bare CR? jne prom0 ; ne = no mov ax,offset kerm ; yes, restore default prompt jmp prom1 prom0: push si ; parse \### constants into push di ; 1 byte binary numbers inline. mov si,offset rdbuf ; source = new prompt string mov byte ptr [si-1+length rdbuf],0 ; plant null terminator mov di,offset prm ; destination call cnvlin ; convert \### in string to binary pop di pop si mov bx,cx ; get byte count add bx,offset prm ; point to null terminator mov byte ptr [bx],'$' ; End of string. mov ax,offset prm prom1: mov prmptr,ax ; Remember it. ret PROMSET ENDP ; SET RETRY value. Changes the packet retry limit. [jrd] RETRYSET PROC NEAR mov min,1 ; smallest acceptable value mov max,63 ; largest acceptable value mov numhlp,offset retryhlp ; help message mov numerr,0 ; complaint message call num0 ; parse numerical input mov maxtry,al shl al,1 ; quick multiply by two or three mov imxtry,al ; keep that much add al,maxtry ; try three times js retrys1 ; s = sign bit set, too much mov imxtry,al ; I packets get 3 times as many tries. retrys1:ret RETRYSET ENDP ; SET TAKE-ECHO on or off. TAKSET PROC NEAR mov dx,offset ontab mov bx,0 mov ah,cmkey call comnd jmp r mov temp,bx mov ah,cmcfm call comnd jmp r nop mov bx,temp mov flags.takflg,bl ret TAKSET ENDP ; SET TIMER on or off during file transfer. TIMSET PROC NEAR mov dx,offset ontab mov bx,0 mov ah,cmkey call comnd jmp r mov temp,bx mov ah,cmcfm call comnd jmp r nop mov bx,temp mov flags.timflg,bl ret TIMSET ENDP ; SET SEND parameters SENDSET PROC NEAR mov stflg,'S' ; Setting SEND parameter sndst0: mov dx,offset stsrtb ; Parse a keyword. mov bx,0 ; no specific help mov ah,cmkey call comnd jmp r ; bad user text call bx ; call the action routine nop nop nop jmp rskp SENDSET ENDP ; SET RECEIVE parameters recset: mov stflg,'R' ; Setting RECEIVE paramter. jmp sndst0 remset proc near ; Set REMOTE ON/OFF mov ah,cmkey mov dx,offset ontab mov bx,offset remhlp call comnd jmp r nop mov temp,bx ; save parsed value mov ah,cmcfm call comnd ; confirm jmp r ; return on failure nop mov bx,temp and flags.remflg,not (dquiet+dserial+dregular) ; no display bits or bl,bl ; want off state? (same as regular) jz remset1 ; z = yes or flags.remflg,dquiet ; else on = quiet display ret remset1:or flags.remflg,dregular ; off = regular display ret remset endp ; SET Send and Receive EOL char sreol PROC NEAR mov min,0 ; lowest acceptable value mov max,1FH ; largest acceptable value mov numhlp,offset eolhlp ; Reuse help message. mov numerr,0 ; error message address call num0 ; get numerical input cmp stflg,'S' ; Setting SEND paramter? je sreol1 mov trans.reol,al jmp short sreol2 sreol1: mov dtrans.seol,al sreol2: mov ah,dtrans.seol mov trans.seol,ah ret sreol ENDP ; SET SEND and RECEIVE start-of-header. srsoh: mov min,0 mov max,1FH mov numhlp,offset eolhlp ; Reuse help message. mov numerr,0 ; error message call num0 ; Common routine for parsing numerical input. cmp stflg,'S' ; Setting SEND paramter? je srsoh1 mov trans.rsoh,al ; set Receive soh ret srsoh1: mov trans.ssoh,al ; set Send soh ret ; SET SEND and RECEIVE TIMEOUT. srtim: mov min,0 mov max,94 mov numhlp,offset timhlp ; Reuse help message. mov numerr,0 ; error message call num0 ; Common routine for parsing numerical input. cmp stflg,'S' ; Setting SEND paramter? je srtim1 mov trans.rtime,al jmp short srtim2 srtim1: mov dtrans.stime,al srtim2: mov ah,dtrans.stime mov trans.stime,ah ret ; SET SEND and RECEIVE PACKET LENGTH. ; Upgraded for long packets. [jrd] srpack: mov min,20 mov max,maxpack mov numhlp,offset pakhlp ; help mov numerr,offset pakerr ; error message call num0 cmp stflg,'S' ; setting send value? jne srpakr ; ne = receive mov trans.slongp,ax ; set send value mov trans.slong,ax ; and remember what we Set. cmp ax,94 ; within normal packet range? ja srpak2 ; a = no mov trans.spsiz,al ; yes. update regular pkt size too srpak2: ret srpakr: mov trans.rlongp,ax ; set receive value cmp ax,94 ; within normal packet range? ja srpak4 ; a = no mov trans.rpsiz,al ; yes. update regular pkt size too. srpak4: ret ; SET SEND and RECEIVE number of padding characters. srnpd: mov min,0 mov max,99 mov numhlp,offset npdhlp ; help message mov numerr,0 ; error message call num0 ; Parse numerical input. cmp stflg,'S' ; Setting SEND paramter? je srnpd1 ; e = yes mov trans.rpad,al ; set Receive padding jmp short srnpd2 srnpd1: mov dtrans.spad,al ; set default Send padding srnpd2: mov al,dtrans.spad mov trans.spad,al ; update active array for I and S pkts [jrd] ret ; SET SEND and RECEIVE padding character. srpad: mov min,0 mov max,127 mov numhlp,offset padhlp mov numerr,offset paderr call num0 ; Parse numerical input. cmp ah,127 ; This is allowed. je srpad1 cmp ah,32 jb srpad1 ; Between 0 and 31 is OK too. mov ah,prstr mov dx,offset paderr int dos ret srpad1: cmp stflg,'S' ; Send? je srpad2 ; e = yes, else Receive mov trans.rpadch,al ; store receive pad char jmp short srpad3 srpad2: mov dtrans.spadch,al ; store Send pad char srpad3: mov ah,dtrans.spadch mov trans.spadch,ah ; update active array for I and S pkts [jrd] ret ; SET SEND and RECEIVE control character prefix. srquo: mov min,33 mov max,126 mov numhlp,offset quohlp ; help message mov numerr,0 ; error message call num0 ; Parse numerical input. cmp stflg,'S' ; Setting outgoing quote char? je srquo1 mov trans.rquote,al ; set Receive quote char jmp short srquo2 srquo1: mov dtrans.squote,al ; set Send quote char srquo2: mov ah,dtrans.spadch mov trans.spadch,ah ; update active array for I and S pkts [jrd] ret ; SET SEND Pause number of milliseconds ; [jrd] srpaus: mov min,0 mov max,127 mov numhlp,offset pauhlp mov numerr,0 call num0 ; Parse numerical input. cmp stflg,'S' ; Setting SEND paramter? je srpau0 mov dx,offset ermes5 ; "Not implemented" msg jmp reterr ; print error message srpau0: mov spause,al ; store value ret ; SET TRANSLATION INPUT Connect mode translate incoming characters. ; SET TRANS IN {Original-byte New-byte | ON | OFF} SETRX PROC NEAR ; translate incoming serial port char mov ah,cmkey mov dx,offset trnstab ; direction table (just one entry) mov bx,0 ; no help call comnd jmp r mov dx,offset rdbuf ; our work space mov word ptr rdbuf,0 ; insert terminator mov bx,offset srxhlp1 ; first help message mov ah,cmfile ; parse a word call comnd ; get incoming byte pattern jmp r ; error if none or ah,ah ; any text given? jz setr6 ; nz = no mov temp,ax ; save byte count here mov ax,word ptr rdbuf ; get first two characters or ax,2020h ; convert upper to lower case cmp ax,'fo' ; first part of word OFF? je setr6 ; e = yes, go analyze cmp ax,'no' ; word ON? je setr6 ; e = yes, go do it mov si,offset rdbuf ; convert text to number call katoi ; number converter procedure, to ax jnc setr1 ; nc = success cmp byte ptr temp+1,1 ; just one character given? jne setr6 ; ne = no, so bad code setr1: mov min,ax ; save byte code here mov dx,offset rdbuf ; our work space mov word ptr rdbuf,0 ; insert terminator mov bx,offset srxhlp1 ; first help message mov ah,cmfile ; parse a word call comnd ; get incoming byte pattern jmp r or ah,ah ; any text given? jz setr6 ; z = no mov temp,ax ; save byte count here mov si,offset rdbuf ; convert text to number call katoi ; number converter procedure jnc setr3 ; nc = success cmp byte ptr temp+1,1 ; just one character given? jne setr6 ; ne = no, so bad code or ON/OFF setr3: mov max,ax ; save byte code here mov ah,cmcfm ; get a confirm call comnd jmp r ; no confirm mov bx,min ; bl = incoming byte code xor bh,bh mov ax,max ; al = local (translated) byte code mov rxtable [bx],al ; store in rx translate table jmp rskp setr6: mov ah,cmcfm ; get a confirm call comnd jmp r ; no confirm mov dx,offset badrx ; assume bad construction or word ptr rdbuf,2020h ; convert to lower case or rdbuf+2,20h ; first three chars cmp word ptr rdbuf,'fo' ; key word OFF? jne setr8 ; ne = no cmp rdbuf+2,'f' ; last letter of OFF? jne setr8 mov rxtable+256,0 ; OFF is status byte = zero mov dx,offset rxoffmsg ; say translation is turned off jmp setr9 setr8: cmp word ptr rdbuf,'no' ; keyword ON? jne setr9a ; ne = no, error mov rxtable+256,1 ; ON is status byte non-zero mov dx,offset rxonmsg ; say translation is turned on setr9: cmp intake,0 ; executing from a Take file? je setr9a ; e = no cmp flags.takflg,0 ; echo contents of Take file? je setr10 ; e = no setr9a: mov ah,prstr ; bad number message int dos setr10: ret SETRX 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,cmcfm ; get a confirm call comnd jmp r ; no confirm 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 shoprt ; print 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 jmp rskp shoprt: cmp cx,4 ; done five entries for this line? jb shopr1 ; b = no mov ah,prstr mov dx,offset crlf ; break line now int dos xor cx,cx shopr1: 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 defined macros. SHOMAC PROC NEAR mov ah,cmtxt mov bx,offset rdbuf mov dx,offset shmmsg call comnd jmp r cmp ah,0 ; Bare CR means show all macros. je shom1 ; e = show all macros jmp shom6 ; No, he wants specific macro expanded. shom1: mov si,offset mcctab ; Table of macro names. cld lodsb mov cl,al ; Number of macro entries. mov ch,0 shom2: jcxz shom5 ; Done if none left to display. lodsb ; Length of macro name. push ax ; Don't forget it. mov ah,prstr mov dx,offset crlfsp ; Go to new line. int dos mov dx,si ; Print macro name. int dos mov dx,offset eqs ; display equals sign int dos pop ax ; recover length of macro name mov ah,0 add si,ax ; Skip over name. add si,1 ; skip '$' field push cx ; save regs push si mov si,[si] ; si = offset of count + string mov cl,byte ptr [si] ; length of string xor ch,ch inc si ; si = offset of string text proper mov ah,conout shom3: lodsb ; get a byte into al cmp al,' ' ; control char? jae shom3a ; ae = no cmp al,cr ; carriage return? je shom3a ; e = yes, handle separately push ax mov dl,5eh ; caret int dos pop ax add al,'A'-1 ; add offset to make printable letter shom3a: mov dl,al ; display it int dos cmp al,cr ; binary carriage return? jne shom4 ; ne = no mov dl,lf ; binary carriage returns are expanded int dos mov dl,' ' ; to cr/lf/space/space int dos int dos shom4: loop shom3 ; do whole string pop si pop cx dec cx add si,2 ; Skip over string offset jmp shom2 ; And do the rest. shom5: mov ah,prstr mov dx,offset shom9a ; 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 shom9c ; body characters int dos mov ax,offset macbuf+maclen sub ax,macptr call decout mov ah,prstr mov dx,offset crlf int dos jmp rskp shom6: mov ah,prstr mov dx,offset ermes3 int dos jmp rskp SHOMAC ENDP ; STATUS command. Revised by [jrd] STATUS PROC NEAR mov ah,cmcfm call comnd ; Get a confirm. jmp r ; Didn't get a confirm. mov dx,offset crlf mov ah,prstr int dos ; print a crlf STAT0: call cmblnk ; clear the screen call locate ; home the cursor push es ; STAT0 is an external ref (in mster) push bx push di mov bx,ds mov es,bx cld mov bx,offset sttab ; table to control printing xor cx,cx ; column counter stat1: cmp word ptr [bx],0 ; end of table? je statx ; e = yes cld ; string direction is forward 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 call prtscr ; print counted string pop cx 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 stat4 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 stat3a ; nothing to do mov ah,conout mov dl,' ' stat3: int dos ; fill with spaces loop stat3 ; do cx times stat3a: mov cx,38 ; current column number stat4: add bx,size stent ; look at next entry jmp stat1 ; and do it statx: pop di pop bx pop es jmp rskp 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 datas segment mov si,[bx].msg ; get message address stms1: lodsb ; get a byte stosb ; drop it off cmp al,'$' ; end of message? jne stms1 ; no, keep going 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 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 ; 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 mov ah,0 ; high order is 0 call outnum ; put number into buffer ret 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 call outnum ; put number into buffer ret stlnum endp ; Common routine for parsing numerical input. ; Enter with numhlp = offset of help message, numerr = offset of optional ; error message, min, max = allowable range of values. ; Returns value in ax, or does parse error return. ; Changes ax,bx,dx,si. [jrd] 18 Oct 1987 num0: mov dx,offset rdbuf+1 ; were to put text mov word ptr rdbuf,0 ; clear the buffer mov bx,numhlp ; help text mov ah,cmfile ; get a word call comnd jmp r mov ah,cmcfm call comnd ; Get a confirm. jmp r ; Didn't get one. nop mov si,offset rdbuf+1 cmp rdbuf+1,'\' ; already quoted? je num0a ; e = yes mov rdbuf,'\' ; add a numerical quote dec si ; point to our escape char num0a: call katoi ; convert number in rdbuf jc num0er ; c = no number, error cmp ax,max ; largest permitted value ja num0er ; a = error cmp ax,min ; smallest permitted value jb num0er ; b = error ret ; return value in ax num0er: mov ah,prstr mov dx,numerr ; comand-specific error message, if any cmp dx,0 ; was any given? je num0e1 ; e = no, use generic msg int dos ; show given error message jmp short num0e2 num0e1: mov dx,offset nummsg1 ; get address of numeric error message. int dos mov ax,min ; smallest permitted number call decout ; display decimal number in ax mov ah,prstr mov dx,offset nummsg2 ; "and" int dos mov ax,max ; largest permitted number call decout num0e2: jmp prserr ; parsing error ; translate the number in ax... outnum proc near cwd 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: 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 ; search a keyword table for a value, print that value srchkw proc near call stmsg ; first print message call stval mov al,[si] ; get value to hunt for mov ah,0 ; high order is 0 mov bx,[bx].val2 ; this is table address jmp prttab ; and look in table. srchkw endp ; Print the drive name. drnum proc near call stmsg ; copy message part first call stval ; pick up test value address ;;; mov al,[si] ; this is char to print 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 stosb mov byte ptr [di],':' inc di mov byte ptr [di],'\' inc di ; end with a colon and backslash mov dl,0 ; 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 cmp al,0 ; end of string? je drnum5 ; e = yes jmp short drnum4 ; do all drnum5: dec di ; offset inc of stosb ret drnum endp ; Print the screen-dump filename [jrd] dmpstat proc near call stmsg ; copy message part mov si,offset dmpname ; address of filename dmpstat1:lodsb ; get a byte cmp al,0 ; at end yet? je dmpstat2 ; e = yes stosb ; store in buffer jmp short dmpstat1 ; keep storing non-null chars dmpstat2:ret dmpstat endp ; print the End-of-Line characters preol proc near call stmsg ; display leadin part of message mov al,dtrans.seol ; send eol char add al,40H ; make it printable stosb mov si,offset mseol2 ; second part of message call stms1 ; add that mov al,trans.reol ; receive eol char add al,40H ; make it printable stosb ret preol 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. stosb mov al,[bx].hands add al,40H ; Make printable. stosb ; put in buffer ret ; and return ; Print the pad character in AL. prpad: cmp al,127 ; Are they using a delete? jne prpad0 mov ah,prstr mov dx,offset delmsg int dos ret prpad0: mov dl,5eh ; caret mov ah,conout push ax int dos pop ax mov dl,al add dl,40H ; Make printable. int dos ret ; Print value from table. BX/address of table, AL/value of variable. prttab: 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 jmp stms1 ; copy in message ret ; and return ; Print the baud rate BAUDPRT PROC NEAR mov si,offset baudrt ; "Baud rate is" call stms1 ; display that part call getbaud ; read baud rate first 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 call prttab ret BAUDPRT ENDP ; Scripts - Status scpprt proc near ; display script settings on a line call stmsg ; copy leading part of message mov si,offset scpmsne ; echo off cmp inecho,0 ; echo state je scppre ; e = off mov si,offset scpmse ; echo on scppre: call stms1 ; add to buffer mov si,offset casmsi ; "ignore" cmp incasv,0dfh ; case state je scpprc mov si,offset casmso ; "observe" scpprc: call stms1 ; add to buffer mov si,offset scptms ; default timeout call stms1 ; add to buffer mov ax,indfto ; timeout value call outnum ; add ascii rendition to buffer mov si,offset scpmsp ; "proceed" cmp inactv,0 ; action on timeout, proceed? je scppra ; e = yes mov si,offset scpmsq ; "quit" scppra: call stms1 ret scpprt 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 ; routine to print an error message, then retskp ; expects message in dx reterr proc near mov ah,prstr int dos jmp rskp reterr endp code ends if1 %out [End of pass 1] else %out [End of assembly] endif end