; * * * * * * * * * * * * * * * version 2.1 * * * * * * * * * * * * * * * ; [B.E. 3-Jan-83] added DTR-code (in 86kermit and 86kerio) for RAINBO ; ; [16] Add file-mode ASCII or BINARY processing. ; RonB,01/02/84 ; [15] Clear screen lines before displaying packet debug. ; RonB,12/29/83 ; [14] Fix nout to print decimal. ; (in the KERPRO.A86 module) ; RonB,12/28/83 ; [13] Use control-Z's for filler in partial sectors instead of nulls. ; (in the KERPRO.A86 module) ; RonB,12/27/83 ; [12] Allow user abort from the keyboard in the send and receive routines. ; (in the KERPRO.A86 module) ; RonB,12/27/83 ; [11] Capitalize and parse filename being received. ; (in the KERFIL.A86 module) ; RonB,12/27/83 ; [10] Correct missing elements in the Show display. ; RonB,12/27/83 ; [9] Fix filename parsing, and add wildcard ability. ; (in the KERCMD.A86, KERPRO.A86, & KERFIL.A86 modules) ; RonB,12/26/83 ; [8] Show choices for ambiguous keywords, finish keyword on '?' ; (in the KERCMD.A86 module) ; RonB,12/26/83 ; [7] Do tab expansion and suppress nulls while in telnet mode. ; (in the KERUTL.A86 module) ; RonB,12/24/83 ; [6] Add support for changing baud rate. ; RonB,12/24/83 ; [5] Put OFF/ON command table in alphabetical order. ; RonB,12/24/83 ; [4] Change default escape character to '^' because NEC keyboard doesn't ; generate a control-\. ; RonB,12/24/83 ; [3] Change "esc,'[H'" to "esc,'[1;1H'" to get around bug in NEC BIOS. ; This should not affect operation on the Rainbow. ; RonB,12/23/83 ; [2] Add a de-initialization routine for the serial port, to restore ; changed interrupt vectors, etc. ; (in the KERIO.A86 module) ; RonB,12/23/83 ; [1] Add I/O support for the NEC Advanced Personal Computer ; (in the KERIO.A86 module) ; RonB,12/23/83 ; ; RonB is Ronald P. Blanford ; Dept. of Computer Science, FR-35 ; University of Washington ; Seattle, Washington 98195 ; ; ; * * * * * * * * * * * * * * * version 2.0 * * * * * * * * * * * * * * * ; KERMIT - KL10 Error-free Reciprocal Micro Interconnect over TTY-lines ; ; Kermit Protocol Version 2 ; ; Based on the KERMIT Protocol. ; ; Copyright (C) 1983 William B. Catchings III ; This program implements the Kermit Protocol developed at Columbia ; University. This version is being written specifically for the ; DEC Rainbow 100. It will hopefully take advantage of much of what ; was learned in implementing the CP/M-80, DEC-20 and other versions. ; Things to do: ; Add new features from Kermit-80, like local CP/M functions ; Make all commands the same as those in Kermit-80 TITLE 'Kermit' TRUE EQU 1 FALSE EQU 0 ; Currently only this module and 86KERIO have system-dependent code. ; Lets keep it that way - IO is obviously SYSTEM-dependent ; - and here we keep the commands , the version ; - HERALD ( i.e VERSIO ) and DTR-lighting ; ; ASM86 86KERMIT $PZ - will assemble without listing ; GENCMD 86KERMIT - will LOAD ; REN KERMIT.CMD=86KERMIT.CMD - will make it "real" after testing ; Conditional compilations: only one of the following should be TRUE necapc EQU FALSE ; NEC Advanced Personal Computer rainbo EQU TRUE ; DEC Rainbow-100 ; Definitions: soh EQU 01O bell EQU 07O tab EQU 11O lf EQU 12O ff EQU 14O cr EQU 15O xon EQU 21O xoff EQU 23O esc EQU 33O del EQU 177O parevn EQU 00H ; Even parity. parmrk EQU 01H ; Mark parity. parnon EQU 02H ; No parity. parodd EQU 03H ; Odd parity. parspc EQU 04H ; Space parity. defpar EQU parnon ; Default parity (none). ibmpar EQU parmrk ; IBM's parity (mark). if necapc defesc EQU '^' ; Caret by default ;[4] endif if rainbo defesc EQU '\'-100O ; Control backslash by default. endif diasw EQU 00H ; Default is diagnostics off. ; The actual program: CSEG ; Start coding! reboot: pushf ; Push flags on CCP's stack. ;[12] pop ax ; Save flags in AX. mov bx, ds ; Set SS to DS. mov ss, bx lea sp, stack ; Set up the stack pointer. push ax ; Restore the flags. popf lea dx, versio ; Print the version header. call tcmsgc if rainbo call serin3 ; establish DTR for Rainbow endif ;Rainbo [B.E. 3-Jan-84] ; This is the main KERMIT loop. It prompts for and gets the users commands. kermit: lea dx, kerm call prompt ; Prompt the user. lea dx, comtab lea bx, tophlp mov ah, cmkey call comnd jmp kermt2 ; Tell them about the error. call bx ; Call the routine returned. jmp kermt3 ; Tell them about the error. cmp extflg, 0 ; Check if the exit flag is set. je kermit ; If not, do it again. call serfin ; clean up serial port environment ;[2] call haltf ; If so, exit. ret ; Just in case! kermt2: lea dx, ermes1 ; Give an error. call tcrmsg jmp kermit kermt3: lea dx, ermes3 ; Give an error. call tcrmsg jmp kermit ; This is the EXIT command. It leaves KERMIT and returns to CP/M. exit: mov ah, cmcfm call comnd ; Get a confirm. jmp r mov extflg, 1 ; Set the exit flag. jmp rskp ; This is the HELP command. help: mov ah, cmcfm call comnd ; Get a confirm. jmp r lea dx, tophlp ; Print some help. call tmsg jmp rskp ; FINISH - tell remote KERSRV to exit. finish: mov ah,cmcfm ; Parse a confirm. call comnd jmp r mov ah, 'F' call gensen ; Send the finish command. jmp rskp ; BYE - tell remote KERSRV to logout and then exit to CP/M. bye: mov ah,cmcfm ; Parse a confirm. call comnd jmp r mov ah, 'L' call gensen ; Send the logout command. mov extflg,1 ; Set exit flag. jmp rskp ; LOGOUT- tell remote KERSRV to logout. logout: mov ah,cmcfm ; Parse a confirm. call comnd jmp r mov ah, 'L' call gensen ; Send the logout command. jmp rskp ; RECEIVE - Receive a file or files from the remote Kermit. For compati- ; bility the receive (now GET is the command.) rec: mov ah, cmtxt ; Parse an arbitrary text string. lea bx, data ; Where to put the parsed text. call comnd jmp r cmp ah, 0 ; Read in any chars? jne get1 ; If so, join the get code. call read ; Do the actual protocol work. jmp rskp ; GET - Get a file or files from the remote server Kermit. get: mov ah, cmtxt ; Parse an arbitrary text string. lea bx, data ; Where to put the parsed text. call comnd jmp r cmp ah, 0 ; Read in any chars? jne get1 ; If not give an error. lea dx, ermes5 call tcrmsg jmp rskp get1: mov al, ah mov ah, 0 mov argbk1, ax ; Remember number of chars we read. mov ah, '$' ; Used for printing. mov [bx], ah call init ; Clear line and initialize buffers. call clrfln ; Prepare to print filename. lea dx, data ; Print file name. call tmsg mov argblk, 0 ; Start at packet zero. mov ah, 'R' ; Receive init packet. call spack ; Send the packet. jmp r call read1 ; Join the read code. jmp rskp ; SEND - Send a file or files to the remote Kermit. sencom: mov ah, cmifi ; Parse an input file spec. lea dx, fcb ; Give the address for the FCB. call comnd jmp r ; Give up on bad parse. mov ah, cmcfm call comnd ; Get a confirm. jmp r ; Didn't get a confirm. call send jmp rskp ; SET - Set some Kermit parameter. setcom: lea dx, settab ; Parse a keyword from the set table. lea bx, sethlp mov ah,cmkey call comnd jmp r call bx ; Call the specific set routine. jmp rskp ; This is the SET Baud rate subcommand ;[6] begin if necapc bdset: lea dx, bdtab lea bx, bdhlp mov ah, cmkey call comnd jmp r mov temp1, bx mov ah, cmcfm call comnd ; Get a confirm. jmp r ; Didn't get a confirm. mov bx, temp1 mov mnbaud, bl ; Set the baud rate table index. call stbaud ret ;[6] end endif ; Sets debugging mode on and off. debset: lea dx, ontab lea bx, onhlp mov ah, cmkey call comnd jmp r mov temp1, bx mov ah, cmcfm call comnd ; Get a confirm. jmp r ; Didn't get a confirm. mov bx, temp1 mov debug, bl ; Set the debug flag. ret ; This is the End-of-line character SET subcommand. eolset: call cmgtch ; Get the first char into AH. cmp ah, 0 jns eol1 cmp ah, 0BFH ; Question mark? je eol4 jmp eol3 eol1: sub ah, 030H ; Digit --> real number. mov temp, ax ; Save the input. call cmcfrm jmp eol0 ; Got a char. mov ax, 0 mov bx, temp jmp eol2 eol0: sub ah, 030H ; Digit --> real number. mov temp1, ax call cmcfrm jmp eol3 ; Too many chars. mov bx, temp1 mov ax, temp xchg al, ah mov ah, 0 eol2: mov temp, ax ; Save our registers. mov temp1, bx call cmcfrm jmp eol3 mov bx, temp1 mov ax, temp mov temp2, 10 ; Get numerical value of char. mul temp2 add al, bh mov ah, 0 cmp al, 0 jl eol3 cmp al, 1FH jg eol3 mov seol, al ; Use new eol char. ret eol3: lea dx, eolerr ; Bad end-of-line char. call tmsg jmp prserr eol4: lea dx, eolhlp call tmsg lea dx, kerm call tcrmsg mov bx, cmdptr mov al, '$' mov [bx], al lea dx, cmdbuf call tmsg dec cmcptr ; Don't count the dollar sign. dec cmccnt ; Or the question mark. mov cmaflg, 0 ; Check for more input. jmp repars ; This is the ESCAPE character SET subcommand. escape: call cmgtch ; Get a char. cmp ah, 0 jns es1 ; Terminator or no? and ah, 7FH ; Turn off minus bit. cmp ah, '?' jne es0 lea dx, eschlp call tmsgcr lea dx, kerm call tmsg mov bx, cmdptr mov al, '$' mov [bx], al lea dx, cmdbuf call tmsg dec cmcptr ; Ignore dollar sign. dec cmccnt mov cmaflg, 0 jmp repars es0: lea dx, ermes3 call tmsg ret es1: mov temp, ax call cmcfrm jmp es0 mov ax, temp mov escchr, ah ; Save new value. ret ; This is the SET file-mode (ASCII or BINARY) command ;[16] begin fmset: lea dx, fmtab lea bx, fmhlp mov ah, cmkey call comnd jmp r mov temp1, bx mov ah, cmcfm call comnd ; Get a confirm. jmp r ; Didn't get a confirm. mov bx, temp1 mov binflg, bl ; Set the file-mode flag. ret ;[16] end ; This is the SET File-Warning command. filwar: lea dx, ontab lea bx, onhlp mov ah, cmkey call comnd jmp r mov temp1, bx mov ah, cmcfm call comnd ; Get a confirm. jmp r ; Didn't get a confirm. mov bx, temp1 mov flwflg, bl ; Set the file warning flag. ret ; This is the SET IBM command. ibmset: lea dx, ontab lea bx, onhlp mov ah, cmkey call comnd jmp r mov temp1, bx mov ah, cmcfm call comnd ; Get a confirm. jmp r ; Didn't get a confirm. mov bx, temp1 mov ibmflg, bl ; Set the IBM flag. cmp bl, 0 ; Turning on or off? je ibmst1 ; If off, set parity & local echo to defaults. mov ah, ibmpar ; Set IBM parity. mov al, 1 ; Set local echo on. jmp ibmst2 ibmst1: mov ah, defpar ; Reset parity to default. mov al, 0 ; Turn off local echo. ibmst2: mov parflg, ah ; Set parity. mov ecoflg, al ; And local echo. ret ; This is the LOCAL echo SET subcommand. local: lea dx, ontab lea bx, onhlp mov ah, cmkey call comnd jmp r mov temp1, bx ; Save the parsed value. mov ah, cmcfm call comnd ; Get a confirm. jmp r ; Didn't get a confirm. mov bx, temp1 mov ecoflg, bl ; Set the local echo flag. ret ; This is the SET Parity command. setpar: lea dx, partab lea bx, parhlp mov ah, cmkey call comnd jmp r mov temp1, bx mov ah, cmcfm call comnd ; Get a confirm. jmp r ; Didn't get a confirm. mov bx, temp1 mov parflg, bl ; Set the parity flag. ret ; STATUS - Give some statistics on the connection. (NYI) status: mov ah,cmcfm ; Parse a confirm. call comnd jmp r lea dx, infms6 ; Tell the user that it's not yet implemented. call tcrmsg jmp rskp ; This is the CONNECT command. It makes the local Kermit act as a terminal. telnet: mov ah,cmcfm call comnd ; Get a confirm. jmp r ; Didn't get a confirm. lea dx, inms01 call tcrmsg call escprt lea dx, inms02 call tmsgcr call serini ; Initialize serial port. telnt1: call conchr ; Check keyboard. jmp extln ; Exit from Telnet. telnt2: call prtchr ; Check serial port. jmp telnt1 ; No char, just loop. mov dl, al ; Get the character. call dbout jmp telnt2 ; Get next character from serial port. extln: lea dx, inms03 call tcmsgc jmp rskp prtchr: call instat ; Any characters available? jmp r ; No, just return call inchr ; Get a character. and al, 7FH ; Strip off parity bit. jmp rskp conchr: call dbinst ; Any chars out there? jmp rskp ; If not, give skip return. call dbin ; Yes, then get the char. cmp al, escchr ; Is it an escape char? jz intchr ; If so go process it. call dopar ; Set parity (if any). mov dx, ax call prtout ; Output the char to the port. cmp ecoflg, 0 ; Is the echo flag turned on? jnz cnc1x jmp rskp ; If not we're done here. cnc1x: call dbout ; Echo the character. jmp rskp intchr: call dbin ; Get a char. cmp al, 0 ; Is the char a null? jz intchr ; If so, go until we get a char. mov bl, al ; Save the actual char. and al, 137O ; Convert to upper case. cmp al, 'C' ; Is it close? jne intch0 ret intch0: cmp bl, escchr ; Is it the escape char? jne intch2 ; If not, go send a beep to the user. call dopar ; Set parity. intc11: mov al, bl call prtout ; Output it. jmp rskp ; Return, we are done here. intch2: mov dl, bell ; Otherwise send a beep. call dbout jmp rskp ; Set parity for character in Register AL. dopar: cmp parflg, parnon ; No parity? je parret ; Just return cmp parflg, parevn ; Even parity? jne dopar0 and al, 7FH ; Strip parity. jpe parret ; Already even, leave it. or al, 80H ; Make it even parity. jmp parret dopar0: cmp parflg, parmrk ; Mark parity? jne dopar1 or al, 80H ; Turn on the parity bit. jmp parret dopar1: cmp parflg, parodd ; Odd parity? jne dopar2 and al, 7FH ; Strip parity. jpo parret ; Already odd, leave it. or al, 80H ; Make it odd parity. jmp parret dopar2: and al, 7FH ; Space parity - turn off parity bit. parret: ret ;[10] begin ; This routine matches a table value and prints the corresponding ; keyword. On entry: ; al = value to match ; bx = beginning address of table tabprt: mov ah, 0 ; make it a word comparison mov ch, [bx] ; get the table size inc bx tabp1: mov dl, [bx] ; get the offset to the value inc bx ; point to beginning of the keyword mov dh, 0 mov si, dx cmp ax, 1[bx+si] ; does the value match? je tabp2 ; yes, go print the keyword at [bx]. add bx, dx ; otherwise go to next entry add bx, 3 dec ch ; any more entries jnz tabp1 ; if so, go check the next lea bx, erms20 ; else say value was not found tabp2: mov dx, bx call tmsg ; display the keyword ret ;[10] end ; This routine prints out the escape character in readable format. escprt: mov dl, escchr cmp dl, ' ' jge escpr2 lea dx, esctl ; Print "Control-" call tmsg mov dl, escchr add dl, 040H ; Make it printable. escpr2: call bout ret ; This routine prints "is on" if prior comparison was nonzero ; and otherwise prints "is off" ponoff: jz ponof2 ; If not say so. lea dx, onstr ; Say on. jmp ponof3 ponof2: lea dx, offstr ; Say off. ponof3: call tmsg ret ; SHOW - Show the state of the parameters available from the SET command. show: mov ah,cmcfm ; Parse a confirm. call comnd jmp r lea dx, cmcrlf call tmsg if necapc lea dx, bdst ; Baud rate string. ;[6] begin call tcrmsg mov al, mnbaud ; Print the keyword corresponding to the lea bx, bdtab ; current value of mnbaud call tabprt ;[6] end endif lea dx, debst ; Debugging string. call tcrmsg cmp debug, 0 ; Is the debugging flag on? call ponoff lea dx, eolst ; End of line string. ;[10] begin call tcrmsg mov al,seol mov ah,0 call nout ;[10] end lea dx, escst ; Escape string. call tcrmsg call escprt ; Print the escape char. lea dx, fmst ; Transfer mode string. ;[16] begin call tcrmsg mov al, binflg ; Print the keyword corresponding to the lea bx, fmtab ; current value of binflg call tabprt ;[16] end lea dx, filst ; File warning string. call tcrmsg cmp flwflg, 0 ; Is the file warning flag on? call ponoff lea dx, ibmst ; IBM string. call tcrmsg cmp ibmflg, 0 ; Is the IBM flag on? call ponoff lea dx, locst ; Get the address of the local echo string. call tcrmsg cmp ecoflg, 0 ; Is the local echo flag on? call ponoff ; Print on or off. lea dx, parst ; Parity string. call tcrmsg mov al, parflg ; Print the keyword corresponding ;[10] begin lea bx, partab ; to the current value of parflg call tabprt lea dx, crlf ; Get the address of a crlf. call tmsg jmp rskp DSEG ; Data segment. ORG 100H ; Leave room for system page. RW 80 ; Eighty word or so stack. stack RW 2 ; Impure storage extflg db 0 ; Exit flag; non zero to exit. ecoflg db 0 ; Echo flag; non zero for local echoing. escchr db defesc ; Escape character for the connect command. debug db diasw ; Are we in debug mode? ; COMND tables comtab db 0CH ; Twelve entries. db 03H,'BYE$' dw bye db 07H,'CONNECT$' dw telnet db 04H,'EXIT$' dw exit db 06H,'FINISH$' dw finish db 03H,'GET$' dw get db 04H,'HELP$' dw help db 06H,'LOGOUT$' dw logout db 07H,'RECEIVE$' dw rec db 04H,'SEND$' dw sencom db 03H,'SET$' dw setcom db 04H,'SHOW$' dw show db 06H,'STATUS$' dw status if necapc settab db 09H ;[6] begin db 04H,'BAUD$' dw bdset ;[6] end endif if rainbo settab db 08H endif db 05H,'DEBUG$' dw debset db 0BH,'END-OF-LINE$' dw eolset db 06H,'ESCAPE$' dw escape db 09H,'FILE-MODE$' ;[16] begin dw fmset ;[16] end db 0CH,'FILE-WARNING$' dw filwar db 03H,'IBM$' dw ibmset db 0AH,'LOCAL-ECHO$' dw local db 06H,'PARITY$' dw setpar ontab db 02H ; Two entries. db 03H,'OFF$' ;[5] begin dw 00H db 02H,'ON$' dw 01H ;[5] end yestab db 02H ; Two entries. db 02H,'NO$' dw 00H db 03H,'YES$' dw 01H if necapc bdtab db 0DH ; Thirteen entries ;[6] begin db 03H,'100$' dw 02H db 03H,'110$' dw 03H db 04H,'1200$' dw 08H db 03H,'150$' dw 04H db 05H,'19200$' dw 0CH db 03H,'200$' dw 05H db 04H,'2400$' dw 09H db 03H,'300$' dw 06H db 04H,'4800$' dw 0AH db 02H,'50$' dw 00H db 03H,'600$' dw 07H db 02H,'75$' dw 01H db 04H,'9600$' dw 0BH ;[6] end endif partab db 05H ; Five entries. db 04H,'EVEN$' dw parevn db 04H,'MARK$' dw parmrk db 04H,'NONE$' dw parnon db 03H,'ODD$' dw parodd db 05H,'SPACE$' dw parspc fmtab db 02H ; Two entries. ;[16] begin db 05H,'ASCII$' dw 00H db 06H,'BINARY$' dw 01H ;[16] end ; Pure storage. delstr db ' ',10O,10O,'$' ; Delete string. clrspc db ' ',10O,'$' ; Clear space. clrlin db cr,esc,'[K$' ; Clear line. clreol db esc,'[K$' ; Clear to end of line. clrscr db esc,'[1;1H',esc,'[J$' ; Home and clear screen. ;[3] homcur db esc,'[1;1H$' ; Home cursor. ;[3] kerm db 'Kermit-86>$' spmes db 'Spack: $' rpmes db 'Rpack: $' hibit db 'Warning - Non Ascii char$' foo db '$' ender db bell,bell,'$' inms01 db '[Connecting to host, type $' inms02 db ' C to return to PC]$' inms03 db '[Back at micro]$' infms3 db 'Completed $' infms4 db 'Failed $' infms5 db 'Renaming file to $' infms6 db '%Function not implemented$' ermes1 db '?Unrecognized command$' ermes2 db '?Illegal character$' ermes3 db '?Not confirmed$' ermes4 db 'Unable to rename file$' ermes5 db '?No receive file specification given$' ermes7 db '?Unable to receive initiate$' ermes8 db '?Unable to receive file name$' ermes9 db '?Unable to receive end of file$' erms10 db '?Unable to receive data$' erms11 db '?Disk full$' erms14 db '?Unable to receive an acknowledgement from the host$' erms15 db '?Unable to find file$' erms17 db 'Record length exceeds size of buffer$' erms18 db '?Unable to tell host that session is finished$' erms19 db '?Unable to tell host to logout$' erms20 db '?Illegal value$' ;[10] erms21 db '* Aborted *',esc,'[15;1h$' ;[12] cfrmes db ' Confirm with carriage return $' filhlp db ' Input file spec (possibly wild) $' esctl db 'Control-$' eschlp db cr,lf,'Enter literal value (ex: Cntrl ]) $' tophlp db cr,lf,'BYE to host (LOGOUT) and exit to CP/M' db cr,lf,'CONNECT to host on selected port' db cr,lf,'EXIT to CP/M' db cr,lf,'FINISH running Kermit on the host' db cr,lf,'GET file(s) from host' db cr,lf,'HELP by giving this message' db cr,lf,'LOGOUT the host' db cr,lf,'RECEIVE file(s) from host' db cr,lf,'SEND file(s) to host' db cr,lf,'SET a parameter' db cr,lf,'SHOW the parameters' db cr,lf,'STATUS of Kermit$' if necapc sethlp db cr,lf,'BAUD rate' ;[6] db cr,lf,'DEBUG' endif if rainbo sethlp db cr,lf,'DEBUG' endif db cr,lf,'END-OF-LINE character' db cr,lf,'ESCAPE character change' db cr,lf,'FILE-MODE (ASCII or BINARY)' ;[16] db cr,lf,'FILE-WARNING' db cr,lf,'IBM' db cr,lf,'LOCAL-ECHO echoing (half-duplex)' db cr,lf,'PARITY type' db '$' if necapc ;[6] begin bdhlp db cr,lf,' 50 100 150 300 1200 4800 19200' db cr,lf,' 75 110 200 600 2400 9600$' endif ;[6] end onhlp db cr,lf,'OFF ON$' yeshlp db cr,lf,'NO YES$' parhlp db cr,lf,'NONE MARK ODD EVEN SPACE$' fmhlp db cr,lf,'ASCII BINARY$' ;[16] eolhlp db cr,lf,'Decimal digit between 0 and 31$' eolerr db cr,lf,'Illegal end-of-line character$' timhlp db cr,lf,'Decimal digit between 1 and 94$' timerr db cr,lf,'Illegal timeout value$' inthlp db cr,lf,'? This message' db cr,lf,'C Close the connection' db cr,lf,'Typing the escape character will send it to the host' db cr,lf,cr,lf,'Command>$' onstr db ' is on$' offstr db ' is off$' bdst db 'Baud rate: $' debst db 'Debug mode$' eolst db 'End-of-line character: $' escst db 'Escape char: $' fmst db 'File mode is $' ;[16] filst db 'File warning$' ibmst db 'IBM flag$' locst db 'Local echo$' parst db 'Parity: $' timmes db 'Timeout is $' outlin db esc,3CH,esc,'[1;1H',esc,'[J',cr,lf,tab ;[3] if necapc versio db esc,'[23m NEC Advanced Personal Computer' ;[1] endif if rainbo versio db tab,esc,'[1m DEC Rainbow-100' endif db ' CP/M-86 Kermit-86 - V2.1' db esc,'[0m',cr,lf,'$' outln2 db cr,lf,'Number of packets: ' db cr,lf,'Number of retries: ' db cr,lf,'File name: $' ; Cursor addressing items. scrnp db esc,'[4;22H$' ; Place for number of packets. scrnrt db esc,'[5;22H$' ; Place for number of retries. scrfln db esc,'[6;12H',esc,'[K$' ; Place for file name. screrr db esc,'[12;1H$' ; Place for error messages. scrst db esc,'[4;53H$' ; Place for "Complete". scrrpr db esc,'[13;1H$' ; Place for prompt. ;scrhi db esc,'[5;53H$' ; 8th bit on in character. scrfr db esc,'[6;1H$' ; Rename file. ;[15] begin scrsp db esc,'[8;1H',esc,'[K',lf,esc,'[K',esc,'[8;1H$' ; Send packet. scrrp db esc,'[10;1H',esc,'[K',lf,esc,'[K',esc,'[10;1H$' ; Receive packet ;[15] end ESEG ; Extra segment. INCLUDE 86KERIO.A86 ; Get the I/O routines. INCLUDE 86KERFIL.A86 ; Get the file routines. INCLUDE 86KERUTL.A86 ; Get the utility routines. INCLUDE 86KERCMD.A86 ; Get the COMND routines. INCLUDE 86KERPRO.A86 ; Get the protocol routines. DSEG $ ; Resume data segment. DB 0 ; Is this really necessary? ; No, but without it you need to specify ; link options to GENCMD so as to make the ; load address include uninitialized storage. ; This bypasses that necessity by including ; all uninitialized storage in the load ; module. - RonB END