home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
CPM
/
KERMIT
/
CP411SRC.ARK
/
cpsrem.asm
< prev
next >
Wrap
Assembly Source File
|
1991-08-27
|
34KB
|
1,150 lines
; 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