diff options
| author | Jeff Armstrong <jeff@approximatrix.com> | 2026-10-25 17:42:06 -0400 |
|---|---|---|
| committer | Jeff Armstrong <jeff@approximatrix.com> | 2026-10-25 17:42:06 -0400 |
| commit | ebb2ff2af569d5822b70ee555a32d27cf7494816 (patch) | |
| tree | 7ac5e7b3fa73f7a8d996129086932ecce66374ad /src/cpsrem.asm | |
| download | kermit-80-main.tar.gz kermit-80-main.zip | |
Diffstat (limited to 'src/cpsrem.asm')
| -rw-r--r-- | src/cpsrem.asm | 1149 |
1 files changed, 1149 insertions, 0 deletions
diff --git a/src/cpsrem.asm b/src/cpsrem.asm new file mode 100644 index 0000000..2f480b9 --- /dev/null +++ b/src/cpsrem.asm @@ -0,0 +1,1149 @@ +; CPSREM.ASM +; KERMIT - (Celtic for "FREE") +; +; This is the CP/M-80 implementation of the Columbia University +; KERMIT file transfer protocol. +; +; Version 4.0 +; +; Copyright June 1981,1982,1983,1984 +; Columbia University +; +; Originally written by Bill Catchings of the Columbia University Center for +; Computing Activities, 612 W. 115th St., New York, NY 10025. +; +; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, +; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many +; others. +; +; This file contains the (system-independent) routines that implement +; the REMOTE commands of the KERMIT protocol. +; +; revision history: +; +;edit 13, 21-Mar-1991 by MF. Renamed REMOTE SET FILE COLLISION REPLACE to +; REMOTE SET FILE COLLISION OVERWRITE and modified the corresponding +; help text slightly. +;edit 12, 13-Feb-1991 by MF. Simplified code at "remcl0" to get REMOTE +; command arguments by calling "cmgtch" in order to get command-line +; characters directly. This means that command-line characters are +; passed literally (except for prefixingand space-compression) to the +; remote Kermit and that one need not send "?" or <esc> as "\"-prefixed +; octal numbers in order to avoid immediate action by CP/M Kermit. +;edit 11, 30-Jan-1991 by MF. Corrected code to always require entry of at least +; one argument in the REMOTE COPY, REMOTE DELETE (REMOTE ERASE), +; REMOTE MESSAGE, REMOTE RENAME and REMOTE TYPE commands. This is +; done by branching to KERMT3 (the "not confirmed" code) if the +; first argument isn't given. This should correct a bug which occurred +; in numerous places in which the character immediately following +; that specifying the flavor of a Generic command was not defined if +; the first of multiple (at least two) arguments was left blank but +; subsequent arguments were not. This should correct a problem +; encountered by Russell Lang of Monash University In Australia when +; he did a REMOTE MESSAGE command with a blank first argument (the +; user id) and a nonblank second argument (the message text) from +; CP/M Kermit to Ms-Kermit in Server mode. +;edit 10, 14-Dec-1990 by MF. Put "<<>>" around "x" or "F" packet replies +; to REMOTE commands as in VMS Bliss Kermit and eliminate unnecessary +; instruction before label remc2d. +;edit 9, 1-Nov-1990 by MF. Changed REMOTE CWD to REMOTE CD in the quest for +; uniformity of nomenclature (per request of FDC). +;edit 8, 29-Oct-1990 by MF. Corrected Remote command code to properly +; prefix control characters (repeat prefix (~) isn't done in CP/M +; yet). +;edit 7, 17-Oct-1990 by MF. Changed verb "REMOTE SEND-MESSAGE" to +; "REMOTE MESSAGE" to conform with the nomenclature suggested in +; Chapter 10 of the 6th edition of the Kermit Protocol Manual. +;edit 6, 10-Oct-1990 by MF. Corrected Remote command code to +; properly prefix the control-character prefix character and the +; eighth-bit quotation prefix character. Remote Set commands +; now function correctly. +; Also change the REMOTE SET FILE COLLISION ASK value to 5 per +; Kermit Digest V12 #6 (though I still have no idea how the local +; Kermit is supposed to answer). +;edit 5, 5-Oct-1990 by MF. Coded many Remote Set commands. +; The commands I have omitted deal with Attribute packets which +; don't make much sense on a CP/M system. +; Note also that for those Remote Set commands which take a +; numeric argument, no range-checking is done here. +; Also note that, for now, REMOTE SET FILE-COLLISION ASK is +; equivalent to REMOTE SET FILE-COLLISION DISCARD because +; (a) that's what the Kermit Digest indicated and (b) no mechanism +; has been proposed for the Remote Kermit to query the Local Kermit. +;edit 4, 29-Sep-1990 by MF. Corrected code to ignore error packets in +; response to sending an "I" packet, per KPROTO.DOC +;edit 3, 9-Sep-1990 by MF. Extensively revised this file to implement +; Remote commands except for the following: +; REMOTE JOURNAL, REMOTE MAIL, REMOTE PRINT, REMOTE PROGRAM, +; REMOTE SET, REMOTE VARIABLE. +;edit 2 ... MF Dunno where edit 2 went (shown in Version string). +; edit 1: September 8th, 1987. Created this file from bits of the two packet files. +; The commands supported by this system are all the REMOTE commands, +; to allow users to acces remote host systems via Kermit. Added REMOTE +; command table and REMOTE DIR command. +; +; +remver: db 'CPSREM.ASM (13) 21-Mar-1991$' ; name, edit number, date + +; +; REMOTE command - quite similar to the SET command +remote: call selmdm ;Select modem + call flsmdm ;Flush buffers + call selcon ;Back to keyboard + lxi d,remtab ; remote commands table + lxi h,remhlp ; remote help table + call keycmd ; get result + xchg + pchl ; and do it + + + + +; REMOTE command table. Works the same way as every other table etc. +; +remtab: db 19 ; nineteen commands so far + db 2,'CD$' + dw remcd ; remote cd command + db 4,'COPY$' + dw remcpy ; remote copy command + db 6,'DELETE$' + dw remdel ; remote delete command + db 9,'DIRECTORY$' + dw remdir ; remote directory command + db 10,'DISK-USAGE$' + dw remdsk ; remote disk-usage command + db 5,'ERASE$' + dw remdel ; remote erase command (same as delete) + db 6,'FINISH$' + dw finish ; same as finish + db 4,'HELP$' + dw remhep ; remote help command + db 4,'HOST$' + dw remhos ; remote host command + db 6,'KERMIT$' + dw remker ; remote Kermit command + db 5,'LOGIN$' + dw remlgi ; remote login + db 6,'LOGOUT$' + dw logout ; same as logout + db 7,'MESSAGE$' + dw remmsg ; remote message command + db 6,'RENAME$' + dw remren ; remote rename + db 3,'SET$' + dw remset ; remote set command + db 5,'SPACE$' + dw remdsk ; remote space command (same as disk-usage) + db 6,'STATUS$' + dw remsta ; remote status (of server) command + db 4,'TYPE$' + dw remtyp ; remote type command + db 3,'WHO$' + dw remwho ; remote who command + +remhlp: db cr,lf,'CD - change default directory for remote server' + db ' operations' + db cr,lf,'COPY - copy files on a remote system' + db cr,lf,'DELETE - delete files on a remote system' + db cr,lf,'DIRECTORY - list a directory on a remote system' + db cr,lf,'DISK-USAGE - show disk usage on a remote system' + db cr,lf,'FINISH - stop a remote server' + db cr,lf,'HELP - get help from a remote server' + db cr,lf,'HOST - execute a command on a remote system' + db cr,lf,'KERMIT - tell a remote server to execute a Kermit ' + db 'command' + db cr,lf,'LOGIN - send user-identification to a remote server' + db cr,lf,'LOGOUT - stop and logout a remote server' + db cr,lf,'MESSAGE - send a message to a remote system user' + db cr,lf,'RENAME - rename files on a remote system' + db cr,lf,'SET - set remote server parameters' + db cr,lf,'SPACE - show disk-usage on a remote system' + db cr,lf,'STATUS - Get status of a remote server' + db cr,lf,'TYPE - type files on a remote system' + db cr,lf,'WHO - show current users on a remote system' + db '$' + + +;Description of remote commands + +; +; Packets start with an I packet in place of S/R packet. An X +; packet is the same as an F (filename) packet except the 'file' +; is not applicable. Copy X packet data field to display. Set +; options so that no data is written to disk during D packets. +; (REMTXT <> 0) +; +;Packets: +; we we comments +; send receive +; I +; ACK +; Command packet +; Ack or +; Init +; ACK +; X Dummy header. +; ACK +; D listing from remote end +; ACK We got it +; .... +; ACK last packet received ok +; Z +; ACK +; B +; ACK end of transaction. +; +;**Note** If the Remote system gives a simple ack to the command packet, +;that is, a "short reply" is given, the data, if any, in the packet +;is displayed and the transaction ends. The outline shown above is for a +;"long reply". +; +; Remote commands +; +; Remote Copy - Copy file(s) on remote system +; +remcpy: lxi h,newfms ;Second argument prompt + shld rprmpt ;... + mvi a,'K' ;Generic type +remcp0: sta remdat ;into packet + mvi a,2 ;Packet has at least two characters + sta rdl ;... + mvi a,'G' ;Generic command + sta rcom ;... + lxi d,remdat+2 ;Point to data buffer + call remcli ;Get filespec (if any) from command line + ora a ;Anything typed? + jz kermt3 ;No, we must have an argument + mov b,a ;Save length + adi space ;Yes, make encoded field length + sta remdat+1 ;and store in packet data area + lda rdl ;Get packet length so far + add b ;Count answer length + sta rdl ;and remember new packet size + lhld rprmpt ;Point to "new file" prompt + xchg ;... + shld rptr ;Save data pointer + call prompt ;Prompt the user + lhld rptr ;Get data pointer again + inx h ;Skip encoded field-length + xchg ;... + call remcli ;get user's answer + lhld rptr ;Restore pointer + mov c,a ;Save answer length + adi space ;Convert to encoded field length + mov m,a ;Put length in packet + lda rdl ;Get accumulated data length + add c ;plus data length + adi 1 ;plus field length character + sta rdl ;and remember it + jmp remcom ;and branch to common code +; +; Remote Cd - Change Directory +; +remcd: lxi h,pswdms ;Second argument prompt + shld rprmpt ;... + mvi a,'C' ;Generic cd +remcd0: sta remdat ;into packet + mvi a,1 ;Packet is at least one character long + sta rdl ;... + mvi a,'G' ;Generic command + sta rcom ;... + lxi d,remdat+2 ;Point to data buffer + call remcli ;Get filespec (if any) from command line + mov b,a ;Save answer length (may be zero) + adi space ;Make encoded field length + sta remdat+1 ;and store in packet data area + lda rdl ;Get length so far + add b ;Count answer length + adi 1 ;and field length character + sta rdl ;and remember current packet-size + lda remdat ;Get generic packet flavor + cpi 'C' ;Remote CD? + jnz remcd1 ;No + mov a,b ;Get length of possible directory spec + ora a ;Did the user give a directory spec? + jz remcom ;No, we can process the command immediately + mvi a,0ffH ;Yes, password follows, make it not echo + sta cmqflg ;... +remcd1: lhld rprmpt ;Point to "password" prompt + xchg ;... + shld rptr ;Save data pointer + mvi a,0ffH ;Allow blank password + sta cmbflg ;... + call prompt ;Prompt the user + lhld rptr ;Restore data pointer + xchg ;... + inx d ;and increment it + call remcli ;Get user's answer + ora a ;Password given? + jz remcom ;No, proceed with command + mov c,a ;Yes, save answer length + adi space ;Convert to encoded field length + lhld rptr ;Get data pointer + mov m,a ;Put length in packet + lda rdl ;Get accumulated data length + adi 1 ;Count encoded field length + add c ;plus data length + sta rdl ;and remember packet-size + jmp remcom ;Branch to common code +; +; Remote Delete (Erase) command +; +remdel: mvi a,'E' ;Delete (Erase) command +remdl0: sta remdat ;... + mvi a,1 ;At least one character in packet + sta rdl ;... + mvi a,'G' ;Generic command + sta rcom ;... + lxi d,remdat+2 ;Point to data field + call remcli ;Get filespec + mov b,a ;Save length + lda remdat ;Get packet type + cpi 'E' ;If Generic Delete + jz remdl1 ;We must have an argument + cpi 'T' ;Ditto for Generic Type + jz remdl1 ;... + mov a,b ;Else get back character count + ora a ;Answer typed? + jz remcom ;No, process packet as is +remdl1: mov a,b ;Get character count again + ora a ;Anything typed? + jz kermt3 ;No, we must have an argument (Delete/Type) + adi space ;Yes, encode field length + sta remdat+1 ;and put in packet + lda rdl ;Get packet length so far + add b ;Count length of filespec + adi 1 ;Count field length character + sta rdl ;and store packet length + jmp remcom ;and do our stuff +; +; Remote Directory command +; +remdir: mvi a,'D' ;generic directory command + jmp remdl0 ;Do common code +; +; Remote Disk-usage (Space) command +; +remdsk: mvi a,'U' ;Disk-usage generic command + jmp remdl0 ;Do common code +; +; Remote Help command +; +remhep: mvi a,'H' ;generic help command + jmp remdl0 ;Do common code +; +; Remote Host command +; +remhos: mvi a,'C' ;Remote Host command +remho0: sta rcom ;... + xra a ;Zero packet length + sta rdl ;... + lxi d,remdat ;Point to packet data buffer + call remcli ;Get host command + ora a ;Anything typed? + jz kermt3 ;No, don't let the user get away with this + sta rdl ;Yes, store packet length + jmp remcom ;and do the command +; +; Remote Kermit command +; +remker: mvi a,'K' ;Remote Kermit command + jmp remho0 ;Do common code +; +; Remote Login command +; +remlgi: mvi a,'G' ;Generic command + sta rcom ;... + mvi a,'I' ;Generic type + sta remdat ;into packet + mvi a,1 ;At least one character in packet + sta rdl ;... + lxi d,remdat+2 ;Point to data buffer + call remcli ;Get userid (if any) from command line + ora a ;Userid typed? + jz remcom ;No, nothing more to do + mov b,a ;Yes, save length + adi space ;Make encoded field length + sta remdat+1 ;and store in packet data area + lda rdl ;Get packet length + add b ;Count id length + adi 1 ;and field length character + sta rdl ;and remember accumulated length + xchg ;Save data pointer + shld rptr ;... + mvi a,0ffH ;Allow blank answers + sta cmbflg ;... + sta cmqflg ;Passwords don't echo + lxi d,pswdms ;Point to "password" prompt + call prompt ;Prompt the user + lhld rptr ;Get data pointer + xchg ;Put in DE + inx d ;Skip encoded field-length + call remcli ;Get password, if any + ora a ;Anything typed? + jz remcom ;No, do command immediately + mov c,a ;Yes, save answer length + adi space ;Convert to encoded field length + lhld rptr ;Get pointer + mov m,a ;Put length in packet + lda rdl ;Get accumulated data length + adi 1 ;Count encoded field length + add c ;Count "password" field length + sta rdl ;and remember new packet length + xchg ;Save data pointer + shld rptr ;... + xra a ;Allow echoing again for "account" field + sta cmqflg ;... + lxi d,acctms ;Point to "account" prompt + call prompt ;Prompt the user + lhld rptr ;Get data pointer + xchg ;into DE + inx d ;Skip encoded field length + call remcli ;Get "account" field, if any + ora a ;Anything typed? + jz remcom ;No, do the command now + mov c,a ;Yes, save length of answer + adi space ;Convert to encoded field length + lhld rptr ;Get data pointer + mov m,a ;Put length in packet + lda rdl ;Get accumulated data length + adi 1 ;Count encoded field length + add c ;plus "account" length + sta rdl ;and remember it + jmp remcom ;Branch to common code +; +; Remote Rename command +; +remren: lxi h,newfms ;Second argument prompt + shld rprmpt ;... + mvi a,'R' ;generic rename + jmp remcp0 ;Do common code +; +; Remote Message command +; +remmsg: lxi h,msgms ;Second argument prompt + shld rprmpt ;... + mvi a,'M' ;generic message + jmp remcp0 ;Do common code +; +;Remote Set command +; +remset: mvi a,6 ;Packet data area has at least six chars + sta rdl ;... + mvi a,'S' ;Remote Set command + sta remdat ;... + mvi a,'G' ;It's a generic command + sta rcom ;... + mvi a,'#' ;Encoded field-length for SET type + sta remdat+1 ;which is three chars long + lxi d,rmstab ;Point to Set command table + lxi h,rmshlp ;and the help table + call keycmd ;Find out which command is to be executed + xchg ;Put dispatch address in HL + pchl ;Go do the command +; +; Common code for Remote Set commands that take an argument +; +remscm: lxi d,remdat+6 ;We get an argument from the user + mvi a,cmtxt ;... + call comnd ;... + jmp kermt3 ;Couldn't get one. + ora a ;Did the user give one? + jz kermt3 ;a blank answer isn't acceptable + mov c,a ;Save length of answer + adi space ;Convert to encoded field-length + sta remdat+5 ;and put in packet data area + lda rdl ;Get current data length + add c ;Count length of answer + sta rdl ;and store new data length + call cfmcmd ;Get a "confirm" + jmp remcom ;Do common Remote command code +; +; Common code for Remote Set commands requiring another table lookup +; +remsc1: call chkkey ;Get user's selection + sta remdat+6 ;and put into the packet data area + mvi a,'!' ;Encoded field length for 1 char + sta remdat+5 ;Put in packet + lda rdl ;Get accumulated packet data length + adi 1 ;Count length of answer (1 char) + sta rdl ;and store as new packet data length + jmp remcom ;Go do common Remote command processing +; +; Remote Status (of server) command +; +remsta: call cfmcmd ;Get return + mvi a,'Q' ;Command type (Server Status) + sta remdat ;... + mvi a,'G' ;Generic Kermit command + sta rcom ;... + mvi a,1 ;1 character in packet + sta rdl ;... + jmp remcom ;Do common code +; +; Remote Type command +; +remtyp: mvi a,'T' ;generic type command + jmp remdl0 ;Do common code +; +; Remote Who command +; +remwho: lxi h,optms ;Second argument prompt + shld rprmpt ;... + mvi a,'W' ;generic who + jmp remcd0 ;Do common code + +; Common code for Remote commands +; +remcom: + mvi a,0ffH ; Make sure returned info is sent + sta remtxt ;to the user's screen rather than to a file + lda rcom ;Get packet-type + cpi 'G' ;Is it a generic command? + jnz remc0e ;No, go clear the screen + lda remdat ;Yes, get generic command type + cpi 'S' ;Is it a Remote Set command? + jz remc0f ;Yes, don't clear the screen +remc0e: call clrtop ; clear the screen +remc0f: xra a + sta numtry ; reset retries + sta czseen + sta pktnum + lxi h,0 + shld numpkt + shld numrtr ; clear some variables + + mvi a,'1' ; reset block check type + sta curchk +remcm0: mvi a,'I' ; init state + sta state + call sinit ; do sendinit with I packet (??) + lda state ; now see if we are in the 'X' state + cpi 'X' + jz remco0 ;Yup, all is in order + cpi 'A' ;No, in abort state? + jnz remcm0 ;No, try I-packet again + jmp kermit ;Yes, like Danny Boy, we must die. + ;If we get this far, either the "I" packet + ;was understood or the Server couldn't + ;handle it and we ignored the error. + ;In either case, we can proceed. + + + +remco0: xra a + sta numtry ; reset retries + sta czseen + sta pktnum + lxi h,0 + shld numpkt + shld numrtr ; clear some variables + mvi a,'1' ;Make sure we use + sta curchk ;1-character checksum + lda rdl ;Get packet-length (number of bytes to copy) + ora a ;Anything to copy? + jz remcm1 ;No + sta temp1 ;Yes, save loop counter + lda spsiz ;Get max packet size + sui 5 ;less overhead + sta temp2 ;gives max chars we can send + lxi d,remdat ;Copy from private buffer + lxi h,data ;to packet data area + lda qbchr ;Get eightgh-bit quoting prefix char + mov b,a ;Save it + lda squote ;Get control-char quoting char + mov c,a ;and save it +remc0a: lda temp2 ;Get characters to go in packet + dcr a ;and decrement it + sta temp2 ;... + jm remc0x ;We can't copy any more + ldax d ;Get a packet data character + cpi space ;Is it a control char? + jm remc0b ;Yes, quote it + cmp c ;Is it the control-char prefix? + jz remc0b ;Yes, quote it + lda quot8 ;No, is eighth-bit quoting in effect? + ora a ;... + jz remc0c ;No, just copy the character + ldax d ;Get character again + cmp b ;Is it the eighth-bit quote char? + jnz remc0d ;No, just copy it +remc0b: mov m,c ;Yes, quote the character + inx h ;Increment the dest. pointer + lda temp2 ;Get chars to go + dcr a ;Decrement + sta temp2 ;... + jm remc0x ;Can't copy any more + lda rdl ;Count quote prefix + inr a ;... + sta rdl ;... +remc0c: ldax d ;Get character again + cpi space ;If not a control char, + jp remc0d ;just copy the character, else + adi 40H ;Convert to printing character + ani 7fH ;modulo 128 +remc0d: mov m,a ;Copy the character + inx h ;Increment the pointers + inx d ;... +remc0x: lda temp1 ;Get loop counter + dcr a ;and decrement it + sta temp1 ;... + jnz remc0a ;Copy entire packet data area +; +remcm1: xra a + sta argblk ; set packet no zero + lda rdl ;Number of bytes in packet + sta argblk+1 ;into argument block + lda rcom ;Remote command + call spack ;Send the packet + jmp kermt3 ;Nogo, die! + jmp remco2 ;Try to get an answer + +remco1: call nak0 ;Nak packet +; + +remco2: lda numtry ;Get number of retries + inr a ; update retries + cpi maxtry ;To many retries? + jm remc2a ;No + lxi d,erms28 ;Yes, complain + call prtstr ;... + jmp kermit ;and abort + +remc2a: sta numtry + call rpack ;Get a packet + jmp remco1 ;Couldn't get one. + cpi 'E' ;Error packet? + jnz remc2b ;No + lda rcom ;What kind of packet did we send? + cpi 'G' ;If it wasn't generic, + jnz remc2f ;there is no need to start a new message line + lda remdat ;Packet was generic + cpi 'S' ;Was it a Remote Set? + cz prcrlf ;Yes, start a new line since the screen + ;isn't blank and we would clobber the command- + ;line otherwise +remc2f: call error0 ;Yes, inform the user + jmp kermit ;and abort to main command loop +remc2b: cpi 'S' ;Send-init? + jnz remc2c ;No + call rini2a ;Initialize parameters + lda state ;Get state + cpi 'A' ;If abort, + jz kermit ;Go back to main command loop + mvi a,'X' ;Set state to text-display + sta state ;... + jmp read2 ;Get more packets +remc2c: cpi 'N' ;Nacked packet? + jz remco2 ;Yes, try again + sta state ;Save packet type + call selcon ;Select Console + lxi h,data ;Point to data + lda argblk+1 ;Anything in packet data? + ora a ;... + jz remco6 ;No + push h ;Yes, save pointer + push psw ;and character count + mvi e,'<' ;Type "<<" as in VMSKermit + push d ;... + call outcon ;... + pop d ;... + call outcon ;... + pop psw ;Restore character counter + pop h ;and data pointer +remc2d: ora a ;... + jz remc2e ;No more characters + dcr a ;Decrement loop counter +mov e,m ;Get character + inx h ;Increment pointer + push psw ;Save loop counter + push h ;Save data pointer + call outcon ;Type on Console + pop h ;Restore pointer + pop psw ;Restore loop counter + jmp remc2d ;Type all packet data +remc2e: mvi e,'>' ;Type ">>" as in VMSKermit + push d ;... + call outcon ;... + pop d ;... + call outcon ;... + call prcrlf ;End the line +remco6: lda state ;Get packet type again + cpi 'Y' ;If simple ack, + jz kermit ;Done, else + call ackp ;Acknoledge the packet + call countp ;Count the packet + mvi a,'D' ;Set to data-receive + sta state ;... + jmp read2 ; do the same as read a file, but echo + ; to the screen.. Dont close non-open files. +; +; +;REMCLI - Get command-line for Remote commands +; +remcli: xra a ;Zero accumulated length + sta rcl ;... + mov b,a ;[12]... +; +;[MF][12]Eliminate following code which calls "comnd" in favor of code which +;[MF][12]calls "cmgtch" directly so that characters are sent without +;[MF][12]alteration or inadvertent action ("?" or <esc>). The only thing +;[MF][12]lost is the ability to produce any ASCII character via +;[MF][12]octal numbers prefixed with "\" but this isn't used much in remote +;[MF][12]commands anyway. +; +;remcl0: mvi a,cmtxt ;We get arbitrary text +; call comnd ;from the command-line +; jmp kermt3 ;We couldn't get any. +; ora a ;Anything given? +; jz remcl1 ;No, done +; push b ;Save BC +; mov c,a ;Save length +; lda rcl ;Get accumulated length +; add c ;plus current word length +; adi 1 ;plus a space +; sta rcl ;and save accumulated length +; mvi a,space ;Put in a space separator +; stax d ;... +; inx d ;Increment pointer +; pop b ;Restore BC +; jmp remcl0 ;Get text to end-of-line +;remcl1: lda rcl ;Get accumulated length +; ora a ;Anything typed? +; rz ;No +; dcr a ;Yes, don't count final space +; push psw ;Save count +; dcx d ;Point to final space +; xra a ;Zap it +; stax d ;... +; pop psw ;Restore count +; +;[MF][12]Simplified code follows +; +remcl0: call cmgtch ;[12]Get a character from the user + ani 7fh ;[12]Turn off minus bit + cpi cr ;[12]If end-of-line, + jz remclx ;[12]We're done + cpi lf ;[12]... + jz remclx ;[12]... + stax d ;[12]else store the character + inr b ;[12]and count it + inx d ;[12]Increment character buffer pointer + cpi esc ;[12]is character an <esc>? + jz remcl2 ;[12]Yes + cpi ff ;[12]an <ff>? + jz remcl1 ;[12]Yes, diddle command buffer pointer + cpi '?' ;[12]a "?"? + jnz remcl0 ;[12]No, just get more characters +remcl1: push h ;[12]Protect HL + lhld cmdptr ;[12]get "cmgtch"'s character pointer + inx h ;[12]and reverse the action at "cmgtc4" + ;[12]since we don't need a "confirm" and + ;[12]infinite loops are beaucoup bad news + shld cmdptr ;[12]... + pop h ;[12]Restore HL +remcl2: push psw ;[12]Save the character + xra a ;[12]Zero the action flag so we get input + sta cmaflg ;[12]to end-of-line without special action + pop psw ;[12]Restore the character + jmp remcl0 ;[12]Get more characters +remclx: mov a,b ;[12]Get accumulated text length + sta rcl ;[12]and remember it +; + ret ;Return +; +;Remote set values +; +; REMOTE SET FILE TYPE 300 0 = TEXT, 1 = BINARY +; REMOTE SET FILE NAMES 301 0 = CONVERTED, 1 = LITERAL +; REMOTE SET FILE COLLISION 302 0 = RENAME, 1 = OVERWRITE, +; 2 = BACKUP, 3 = APPEND, +; 4 = DISCARD, 5 = ASK +; REMOTE SET FILE REPLACE 303 0 = PRESERVE, 1 = DEFAULT +; REMOTE SET FILE INCOMPLETE 310 0 = DISCARD, 1 = KEEP +; REMOTE SET INCOMPLETE (same as above) +; REMOTE SET BLOCK-CHECK 400 number (1, 2, or 3) +; REMOTE SET RECEIVE PACKET-LENGTH 401 number (10-9024) +; REMOTE SET RECEIVE TIMEOUT 402 number (any, 0 = no timeout) +; REMOTE SET RETRY 403 number (any, 0 = no limit) +; REMOTE SET SERVER TIMEOUT 404 number (any, 0 = no timeout) +;REMOTE SET FILE BLOCKSIZE 311 number +;REMOTE SET FILE RECORD-LENGTH 312 number +;REMOTE SET FILE RECORD-FORMAT 313 F (fixed), V (variable), etc... +;This is just for the record, to assign these numbers to these commands +;for somebody who needed them. Details to be filled in later. +; +;Remote Set command table +; +rmstab: db 7 ;seven entries + db 16,'BLOCK-CHECK-TYPE$' + dw remsbc ;Remote Set Block Check + db 4,'FILE$' + dw remsfl ;Remote Set File + db 10,'INCOMPLETE$' + dw remsfi ;Remote Set (file) Incomplete + db 7,'RECEIVE$' + dw remsrc ;Remote Set Receive + db 7,'REPLACE$' + dw remsfr ;Remote Set (file) Replace + db 5,'RETRY$' + dw remsry ;Remote Set Retry + db 14,'SERVER-TIMEOUT$' + dw remsst ;Remote Set Server Timeout +; +rmshlp: db cr,lf,'BLOCK-CHECK-TYPE for a remote server' + db cr,lf,'FILE parameters for a remote server' + db cr,lf,'INCOMPLETE file disposition for a remote server' + db cr,lf,'RECEIVE parameters for a remote server' + db cr,lf,'REPLACE file attribute handling for a remote server' + db cr,lf,'RETRY maximum for a remote server' + db cr,lf,'SERVER-TIMEOUT interval for a remote server' + db '$' +; +;Remote Set File tables +; +rsftab: db 8 ;eight entries + db 10,'BLOCK-SIZE$' + dw remsbs ;Remote Set File Block-size command + db 9,'COLLISION$' + dw remsfc ;Remote Set File Collision command + db 10,'INCOMPLETE$' + dw remsfi ;Remote Set File Incomplete command + db 5,'NAMES$' + dw remsfn ;Remote Set File Names command + db 13,'RECORD-FORMAT$' + dw remsrf ;Remote Set File Record-format + db 13,'RECORD-LENGTH$' + dw remsrl ;Remote Set File Record-length + db 7,'REPLACE$' + dw remsfr ;Remote Set File Replace command + db 4,'TYPE$' + dw remsft ;Remote Set File Type command +; +rsfhlp: db cr,lf,'BLOCK-SIZE of files for a remote server' + db cr,lf,'COLLISION action on filename conflicts for a remote' + db ' server' + db cr,lf,'INCOMPLETE file disposition for a remote server' + db cr,lf,'NAMES translation of files for a remote server' + db cr,lf,'RECORD-FORMAT of files for a remote server' + db cr,lf,'RECORD-LENGTH for a remote server' + db cr,lf,'REPLACE file attribute handling for a remote server' + db cr,lf,'TYPE of files for a remote server' + db '$' +; +;Remote Set File Record-format tables +; +rcftab: db 2 ;two entries + db 5,'FIXED$' + db 'F','F' ;Remote Set File Record-format Fixed command + db 8,'VARIABLE$' + db 'V','V' ;Remote Set File Record-format Variable cmd +; +rcfhlp: db cr,lf,'FIXED VARIABLE' + db '$' +; +;Remote Set Receive tables +; +rrctab: db 2 ;two entries + db 13,'PACKET-LENGTH$' + dw remrpl ;Remote Set Receive Packet-length command + db 7,'TIMEOUT$' + dw remsrt ;Remote Set Receive Timeout command +; +rrchlp: db cr,lf,'PACKET-length TIMEOUT' + db '$' +; +;Remote Set File-collision table +; +rfctab: db 6 ;six entries + db 6,'APPEND$' + db '3','3' ;Set collision append + db 3,'ASK$' + db '5','5' ;Set collision ask + db 6,'BACKUP$' + db '2','2' ;Set collision backup + db 7,'DISCARD$' + db '4','4' ;Set collision discard + db 9,'OVERWRITE$' + db '1','1' ;Set collision overwrite + db 6,'RENAME$' + db '0','0' ;Set collision rename +; +rfchlp: db cr,lf,'ASK about existing files on a remote system' + db cr,lf,'APPEND to existing files on a remote system' + db cr,lf,'BACKUP (rename) existing files on a remote system' + db cr,lf,'DISCARD new versions of existing files on a' + db ' remote system' + db cr,lf,'OVERWRITE existing files on a remote system' + db cr,lf,'RENAME new versions of existing files on a' + db ' remote system' + db '$' +; +;Remote Set File-Incomplete tables +; +rfitab: db 2 ;2 entries + db 7,'DISCARD$' + db '0','0' ;Remote Set File Incomplete Discard + db 4,'KEEP$' + db '1','1' ;Remote Set File Incomplete Keep +; +rfihlp: db cr,lf,'DISCARD KEEP' + db '$' +; +;Remote Set File-Names tables +; +rfntab: db 2 ;two entries + db 9,'CONVERTED$' + db '0','0' ;Remote Set File Names Converted + db 7,'LITERAL$' + db '1','1' ;Remote Set File Names Literal +; +rfnhlp: db cr,lf,'CONVERTED LITERAL' + db '$' +; +;Remote Set File Replace tables +; +rfrtab: db 2 ;two entries + db 8,'PRESERVE$' + db '0','0' ;Remote Set File Replace Preserve + db 7,'DEFAULT$' + db '1','1' ;Remote Set File Replace Default +; +rfrhlp: db cr,lf,'PRESERVE DEFAULT' + db '$' +; +;Remote Set File Type tables +; +rfttab: db 2 ;two entries + db 6,'BINARY$' + db '1','1' ;Remote Set File Type Binary + db 4,'TEXT$' + db '0','0' ;Remote Set File Type Text +; +rfthlp: db cr,lf,'BINARY TEXT' + db '$' +; +; Remote Set Block-check +; +remsbc: +IF lasm + lxi h,'40' ;1st 2 chars of "400" +ENDIF ;lasm +IF NOT lasm + lxi h,'04' +ENDIF ;NOT lasm + shld remdat+2 ;Store in correct order + mvi a,'0' ;Put last char of type in buffer + sta remdat+4 ;... + lxi d,blktab ;Point to block-check table + lxi h,blkhlp ;and help table + jmp remsc1 ;Do common code +; +;Remote Set File command +; +remsfl: lxi d,rsftab ;Point to Remote Set File tables + lxi h,rsfhlp ;... +remsf0: call keycmd ;Get user's selection + xchg ;Put dispatch address in HL + pchl ;and obey the user's most fervent desires +; +;Remote Set Receive command +; +remsrc: lxi d,rrctab ;Point to the appropriate tables + lxi h,rrchlp ;... + jmp remsf0 ;and do command +; +;Remote Set Block-size command +; +remsbs: +IF lasm + lxi h,'31' ;1st 2 chars of Set code +ENDIF ;lasm +IF NOT lasm + lxi h,'13' +ENDIF ;NOT lasm + shld remdat+2 ;Store chars in correct order + mvi a,'1' ;Put last char in buffer + sta remdat+4 ;... + jmp remscm ;and do common Remote Set code +; +;Remote Set File-collision command +; +remsfc: +IF lasm + lxi h,'30' ;Put set type code in buffer +ENDIF ;lasm +IF NOT lasm + lxi h,'03' +ENDIF ;NOT lasm + shld remdat+2 ;... + mvi a,'2' ;... + sta remdat+4 ;... + lxi d,rfctab ;Point to tables + lxi h,rfchlp ;... + jmp remsc1 ;and do common code +; +;Remote Set File Incomplete command +; +remsfi: +IF lasm + lxi h,'31' ;Establish command keyword code +ENDIF ;lasm +IF NOT lasm + lxi h,'13' +ENDIF ;NOT lasm + shld remdat+2 ;... + mvi a,'0' ;... + sta remdat+4 ;... + lxi d,rfitab ;Point to tables + lxi h,rfihlp ;... + jmp remsc1 ;and do common code +; +;Remote Set File-Names command +; +remsfn: +IF lasm + lxi h,'30' ;Set command code +ENDIF ;lasm +IF NOT lasm + lxi h,'03' +ENDIF ;NOT lasm + shld remdat+2 ;... + mvi a,'1' ;... + sta remdat+4 ;... + lxi d,rfntab ;Point to the appropriate tables + lxi h,rfnhlp ;... + jmp remsc1 ;and do common code +; +;Remote Set File Record Format command +; +remsrf: +IF lasm + lxi h,'31' ;Set command code +ENDIF ;lasm +IF NOT lasm + lxi h,'13' +ENDIF ;NOT lasm + shld remdat+2 ;... + mvi a,'3' ;... + sta remdat+4 ;... + lxi d,rcftab ;Point to proper tables + lxi h,rcfhlp ;... + jmp remsc1 ;and do common code +; +;Remote Set File Record Length command +; +remsrl: +IF lasm + lxi h,'31' ;Set command code +ENDIF ;lasm +IF NOT lasm + lxi h,'13' +ENDIF ;NOT lasm + shld remdat+2 ;... + mvi a,'2' ;... + sta remdat+4 ;... + jmp remscm ;and do common code +; +;Remote Set File Replace command +; +remsfr: +IF lasm + lxi h,'30' ;Set command code +ENDIF ;lasm +IF NOT lasm + lxi h,'03' +ENDIF ;NOT lasm + shld remdat+2 ;... + mvi a,'3' ;... + sta remdat+4 ;... + lxi d,rfrtab ;Point to tables + lxi h,rfrhlp ;... + jmp remsc1 ;and do common code +; +;Remote Set File Type command +; +remsft: +IF lasm + lxi h,'30' ;Set command code +ENDIF ;lasm +IF NOT lasm + lxi h,'03' +ENDIF ;NOT lasm + shld remdat+2 ;... + mvi a,'0' ;... + sta remdat+4 ;... + lxi d,rfttab ;Point to tables + lxi h,rfthlp ;... + jmp remsc1 ;and go to common code +; +;Remote Set Receive Packet-length command +; +remrpl: +IF lasm + lxi h,'40' ;Set command code +ENDIF ;lasm +IF NOT lasm + lxi h,'04' +ENDIF ;NOT lasm + shld remdat+2 ;... + mvi a,'1' ;... + sta remdat+4 ;... + jmp remscm ;and do common code +; +;Remote Set Receive Timeout command +; +remsrt: +IF lasm + lxi h,'40' ;Set code +ENDIF ;lasm +IF NOT lasm + lxi h,'04' +ENDIF ;NOT lasm + shld remdat+2 ;... + mvi a,'2' ;... + sta remdat+4 ;... + jmp remscm ;and do common code +; +;Remote Set Retry command +; +remsry: +IF lasm + lxi h,'40' ;Set code +ENDIF ;lasm +IF NOT lasm + lxi h,'04' +ENDIF ;NOT lasm + shld remdat+2 ;... + mvi a,'3' ;... + sta remdat+4 ;... + jmp remscm ;Go to common code +; +;Remote Set Server Timeout command +; +remsst: +IF lasm + lxi h,'40' ;Set code +ENDIF ;lasm +IF NOT lasm + lxi h,'04' +ENDIF ;NOT lasm + shld remdat+2 ;... + mvi a,'4' ;... + sta remdat+4 ;... + jmp remscm ;Do common code + + + + + +; Little code to allow some expansion of code without changing +; every futher address, only up to the end of this file. +; TO BE REMOVED FOR RELEASE + +; ORG ($+100H) AND 0FF00H + + +IF lasm + LINK CPSSER +ENDIF ;lasm |
