aboutsummaryrefslogtreecommitdiff
path: root/src/cpsrem.asm
diff options
context:
space:
mode:
authorJeff Armstrong <jeff@approximatrix.com>2026-10-25 17:42:06 -0400
committerJeff Armstrong <jeff@approximatrix.com>2026-10-25 17:42:06 -0400
commitebb2ff2af569d5822b70ee555a32d27cf7494816 (patch)
tree7ac5e7b3fa73f7a8d996129086932ecce66374ad /src/cpsrem.asm
downloadkermit-80-ebb2ff2af569d5822b70ee555a32d27cf7494816.tar.gz
kermit-80-ebb2ff2af569d5822b70ee555a32d27cf7494816.zip
Initial import of 4.11HEADmain
Diffstat (limited to 'src/cpsrem.asm')
-rw-r--r--src/cpsrem.asm1149
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