home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
kermit.columbia.edu
/
kermit.columbia.edu.tar
/
kermit.columbia.edu
/
archives
/
trs80model4.zip
/
m4rmt.asm
< prev
next >
Wrap
Assembly Source File
|
1986-10-22
|
11KB
|
426 lines
; M4RMT/ASM
; REMOTE KERMIT COMMAND
REMOTE LD A,CMKEY
LD DE,RMTTAB
CALL COMND
JP KERMT2
LD C,A ;SAVE THE TYPE
CALL NEWLIN
LD B,0
LD HL,RMTJTB ;GET THE JUMP TABLE
ADD HL,BC ;COMPUTE THE ADDRESS
LD A,'G'
LD (PKTTYPE),A ;Set to generic packet
JP (HL)
; REMOTE COMMAND JUMP TABLE
RMTJTB JP RMTCWD ;CHANGE WORKING DIRECTORIES
JP RMTDEL ;DELETE A FILE
JP RMTDIR ;DISPLAY A DIRECTORY
JP RMTDSK ;DO A REMOTE DISK ALLOCATION
JP RMTHLP ;GET REMOTE HELP
JP RMTHST ;DO REMOTE HOST COMMAND
JP RMTKER ;DO REMOTE KERMIT COMMAND
JP RMTWHO ;RUN A REMOTE PROGRAM
JP RMTREN ;SEND DATA TO A REMOTE PROGRAM
JP RMTTYPE ;DISPLAY A REMOTE FILE
JP RMTCOPY ;Copy a file
JP RMTMSG ;Send a message
JP RMTSET ;Set a variable
JP RMTQUERY ;Query a variable
JP RMTCLOSE ;Close the log
JP RMTSEND ;Send the log
JP RMTSTART ;Start logging
JP RMTSTOP ;Stop logging
JP RMTLOGIN ;Login to dedicated server
JP RMTPRG ;Remote program manipulation
JP RMTSRV ;Remote server status query
;
; DO A GENERIC REMOTE COMMAND
;
GENCMD LD DE,RMTDATA ;Set the initial destination
LD B,0 ;Set the initial counters
LD (GENTYPE),A ;Save the type
IFA 'J',GENCMD1 ;Jump if journaling
IFANOT 'V',GENCMD2 ;Jump if not variable
GENCMD1 LD A,C ;Get the second attribute
LD (DE),A ;Store it
INC DE ;Point ahead
INC B ;Plus one for the extra attribute
GENCMD2 LD C,0 ;Reset the beginning field length
GENCMD3 LD (INITRMT),DE ;Save the values
LD (INITCNT),BC
CALL ENCFLDS ;Get the input fields
GENCMD5 LD A,'1' ;SET CURRENT CHECK SUM
LD (CURCHK),A
XOR A ;Set the packet number to zero
LD (ARGBLK),A
NSTATE 'I' ;Set the state to I-initiate
CALL INIT ;Initialize buffers
LD HL,0 ;Set packet count to zero
LD (NUMPKT),HL
LD (NUMRTR),HL ;Reset number of retries
XOR A ;Set mode to display on screen
LD (DISFLG),A
LD (PKTNUM),A ;Zero current packet number
LD (NUMTRY),A ;Zero retries for current packet
LD (CZSEEN),A
CALL CLRPRT
CALL PROTO
JP KERMIT
;
; State G of the protocol. Build a G or C packet, and send it
;
DOGEN EQU $
CALL CHKTRYS ;Check the retry count
LD A,(PKTNUM) ;Set the packet number to current
LD (ARGBLK),A
LD HL,FILBUF ;Transfer data to the buffer
LD DE,DATA ;Get the DATA area
LD A,(PKTTYPE) ;Get the requested type, 'G' or 'C'
IFA 'C',DOGEN6 ;If COMMAND then jump
INC DE ;Point to data+1 if not remote host
DOGEN6 LD A,(GENLEN) ;Get the length
IFZ DOGEN1 ;Jump if no length
LD C,A ;Make BC the count
LD B,0
LDIR ;Move the bytes
DOGEN1 LD C,A ;Store the length
LD A,(PKTTYPE) ;Check the type again
IFA 'C',DOGEN7 ;If COMMAND then jump
LD A,(GENTYPE) ;Get the GENERIC type
LD (DATA),A ;Store it
INC C ;Add one to DATA length
LD A,'G' ;Send a generic packet
DOGEN7 PUSH AF ;Save the packet type
LD A,C ;Get the length of DATA
LD (ARGBLK+1),A ;Store it
LD A,'1' ;Always 1 character checksum
LD (CURCHK),A
LD A,(CHKTYP) ;Get the desired checksum type
LD (INICHK),A ;Save it for later
POP AF ;Get the packet type back
CALL SPACK ;Send the packet
JP ABORT ;Abort on an error
RPACKET ;Receive a packet
IFANOT 'S',DOGEN2 ;Skip if not send_init
LD A,(ARGBLK+1) ;Get the length
LD HL,DATA ;Get the DATA area
CALL SPAR ;Get parameters from packet
LD HL,DATA ;Get the DATA area
CALL RPAR ;Put our capabilities in
LD (ARGBLK+1),A ;Store the length that is returned
SPACKET 'Y' ;Send ACK with parameters
LD A,(INICHK) ;Get the requested checksum type
LD (CURCHK),A ;Store it as current
NSTATE 'f' ;Set state to file receive
RET ;Return to protocol switch
DOGEN2 IFANOT 'X',DOGEN3 ;X packet? Jump if not
CALL SETUPDIS ;Set up for terminal display
CALL PRTPKTOUT ;Print the packet contents
CALL DOINC ;Increment everything
LD (ARGBLK+1),A ;A is zero, so use for zero length
SPACKET 'Y' ;Send ACK
NSTATE 'd' ;Set state to receive DATA
RET
;
DOGEN3 IFANOT 'Y',DOGEN4 ;Jump if not ACK
CALL NEWLIN ;Get a new line for data
CALL PRTPKTOUT ;Print the packets contents on screen
NSTATE 'C' ;Set state to complete
RET ;Return to proto switch
;
DOGEN4 CP 'N' ;Was it NAK?
RET Z ;If so, stay in this state
IFANOT 'E',DOGEN5 ;If not Error packet, then go
CALL ERROR ;Print error message
CALL NEWLIN ;Get a new line
JP KERMIT ;Get a new command
;
DOGEN5 STROUT UNKNOWN ;Print unknown packet type message
XOR A
LD (ARGBLK+1),A ;Set DATA length to zero
SPACKET 'E' ;Send an error packet
JP KERMIT ;Get a new command
;
; Do remote directory
;
RMTDIR EQU $
GENCASE 'D',1
;
; Remote delete file
;
RMTDEL EQU $
GENCASE 'E',1
;
; Remote disk utilization
;
RMTDSK EQU $
GENCASE 'U',1
;
; Remote Help
;
RMTHLP EQU $
GENCASE 'H',1
;
; Remote Program control
;
RMTPRG EQU $
GENCASE 'P',2
;
; Remote Kermit Command
;
RMTKER EQU $
GENCASE 'P',1
;
; Remote type command
;
RMTTYPE EQU $
GENCASE 'T',1
;
; Remote who command
;
RMTWHO EQU $
GENCASE 'W',2
;
; Remote change directory
;
RMTCWD EQU $
GENCASE 'C',2
;
; Remote rename a file
;
RMTREN EQU $
GENCASE 'R',2
;
; Remote copy a file
;
RMTCOPY EQU $
GENCASE 'K',2
;
; Remote send a message
;
RMTMSG EQU $
GENCASE 'M',2
;
; Remote set a variable
;
RMTSET EQU $
LD C,'S'
GENCASE 'V',2
;
; Remote query a variable
;
RMTQUERY EQU $
LD C,'Q'
GENCASE 'V',2
;
; Remote close the log file
;
RMTCLOSE EQU $
LD C,'c'
GENCASE 'J',1
;
; Remote send log file
;
RMTSEND EQU $
LD C,'s'
GENCASE 'J',1
;
; Remote start logging
;
RMTSTART EQU $
LD C,'+'
GENCASE 'J',1
;
; Remote stop logging
;
RMTSTOP EQU $
LD C,'-'
GENCASE 'J',1
;
; Remote login
;
RMTLOGIN EQU $
GENCASE 'l',3
;
; Remote server status query
;
RMTSRV EQU $
GENCASE 'Q',1
;
; Remote host command
;
RMTHST EQU $
LD DE,FILBUF
LD A,CMTXT
CALL COMND
JP KERMT2
LD (TEMP4),A
LD A,CMCFM
CALL COMND
JP KERMT3
LD A,(TEMP4)
LD (GENLEN),A
LD C,A
LD B,0
LD HL,FILBUF
ADD HL,BC
LD (HL),0
LD A,1
LD (FLDLEN),A
LD A,'C'
LD (PKTTYPE),A
JP GENCMD5
;
; Get users response, and put it into the buffer
;
ENCFLDS LD A,CMTXT
LD DE,DATA ;Get the text
CALL COMND
JP KERMT2
CALL ENCOLEN ;Length encode each argument
JP GETFIELD1 ;On error jump
LD HL,RMTDATA ;Get the input buffer
CALL ENCSTR ;Encode the contents
LD A,(SIZE) ;Get the length
LD (GENLEN),A ;Save it for later
RET ;Return
;
GETFIELD1 EQU $ ;Bad string found in encodelen
STROUT TOOLONG ;Print string too long message
JP KERMIT ;Abort completely
;
; Protocol switch code
;
PROTO EQU $
LD A,(STATE)
SWITCH 'D',SDATA ;Send data
SWITCH 'F',SFILE ;Send file
SWITCH 'T',SNDTRAN ;Transition from 'F' to 'D'
SWITCH 'Z',SEOF ;Send EOF
SWITCH 'S',SINIT ;Send init
SWITCH 'B',SEOT ;End of transmittion
SWITCH 'C',COMP ;Completed
SWITCH 'A',SABORT ;Abort
SWITCH 'd',RDATA ;Receive data
SWITCH 'f',RFILE ;Receive file
SWITCH 't',RECTRAN ;Transition from 'f' to 'd'
SWITCH 'R',RINIT ;Receive init
SWITCH 'r',RINITF ;Receive init with filename (GET command)
SWITCH 'G',DOGEN ;Generic server command
SWITCH 'I',IINIT ;Generic init packet
CALL SABORT ;Bad protocol state
JP KERMIT ;Abort
;
; SEND I-INITIATE
;
IINIT CALL CHKTRYS ;Check retry threshold
LD A,'1' ;RESET TO USE SINGLE CHARACTER CHECKSUM
LD (CURCHK),A ;FOR STARTUP
LD A,(CHKTYP) ;GET OUR DESIRED BLOCK CHECK TYPE
LD (INICHK),A ;Store it as the initial value
LD HL,DATA ;GET A POINTER TO OUR DATA BLOCK.
CALL RPAR ;SET UP THE PARAMETER INFORMATION.
LD (ARGBLK+1),A ;SAVE THE NUMBER OF ARGUMENTS.
LD A,(PKTNUM) ;GET THE PACKET NUMBER.
LD (ARGBLK),A
SPACKET 'I' ;Send the I packet
RPACKET ;Get the answer packet
CP 'Y' ;Is it an ACK?
JP NZ,IINIT3 ;IF NOT TRY NEXT.
CALL CHKBLK
RET NZ ;IF NOT TRY AGAIN.
CALL DOINC
LD A,(ARGBLK+1) ;GET THE NUMBER OF PIECES OF DATA.
LD HL,DATA ;POINTER TO THE DATA.
CALL SPAR ;READ IN THE DATA.
LD A,(INICHK) ;GET THE AGREED UPON BLOCK-CHECK-TYPE
LD (CURCHK),A ;STORE AS TYPE TO USE FOR PACKETS NOW
NSTATE 'G'
RET
IINIT3 IFANOT 'N',IINIT4 ;NAK?
CALL UPDRTR ;UPDATE THE NUMBER OF RETRIES.
RET
IINIT4 CP 'E' ;IS IT AN ERROR PACKET.
JP NZ,ABORT ;JUMP IF NOT
LD A,80 ;SET UP ALL DEFAULT PARAMETERS
LD (SPSIZ),A
XOR A
LD (SPAD),A
LD (SPADCH),A
LD A,13
LD (SEOL),A
LD A,'1'
LD (CURCHK),A
LD A,'#'
LD (SQUOTE),A
NSTATE 'G'
RET
;
; This routine encodes the length of the blank separated fields
; into a packet for the generic routines. If there are more
; blank separated fields than FLDLEN says there should be, the
; remaining fields are added to the end of the last field,
; separated by blanks.
;
ENCOLEN LD HL,DATA ;Get the source
LD DE,(INITRMT) ;Get the initial location
LD BC,(INITCNT) ;Get the initial counters
PUSH DE ;Save the store address for length
PUSH BC
INC DE ;Point to where the data goes
LD A,(FLDLEN) ;Get the number of fields
LD B,A ;Put it into the counter
POP AF ;Get the initial length
LD (FLDLEN),A ;Set the length to zero initially
ENCLEN1 LD A,(HL) ;Get a character
IFANOT 20H,ENCLEN4 ;Jump if not space
ENCLEN2 INC HL ;Point to next character
IFA (HL),ENCLEN2 ;Loop while we are looking at a space
DJNZ ENCLEN3 ;See if we have done all fields
INC B ;Reset the counter back to one if so
LD (DE),A ;Store a space
INC DE ;Point to next place to store at
INC C ;Increment the field length
JR ENCLEN1 ;Process next character
ENCLEN3 LD A,C ;Get the field length
TOCHAR ;Make it printable
EX (SP),HL ;Get the store address for the length
LD (HL),A ;Store the length byte
POP HL ;Restore the old HL
PUSH DE ;Save the new length byte address
INC DE ;Point to the data store address
LD C,0 ;Reset the count of characters
LD A,(FLDLEN) ;Get the total length
INC A ;Add one to the length
LD (FLDLEN),A ;Store the new length
JR NZ,ENCLEN1 ;Continue if OK
POP DE ;Restore the stack
RET ;Return error
ENCLEN4 JR C,ENCLEN5 ;If this is a control character then stop
INC C ;Correct for the comming decrement
LDI ;Move one char, and increment counter
INC C ;Plus one more for the length
LD A,(FLDLEN) ;Get the length
INC A ;Add one for current character
LD (FLDLEN),A ;Store the new length
JR NZ,ENCLEN1 ;Top of the loop if no overflow
POP DE ;Restore the stack
RET ;Return error
ENCLEN5 POP HL ;Get the length address
LD A,C ;Get the length
TOCHAR ;Make it printable
LD (HL),A ;Store this fields length
XOR A ;Terminate the packet
LD (DE),A
LD A,(FLDLEN) ;Get the overall length
LD (GENLEN),A ;Save it for later
OR A ;Is it a null length string?
JP Z,RSKP ;Return if it is
INC A ;Add one to length for field length byte
CP MAXPKT-4 ;Too big for packet?
RET P ;Return error if string too long
LD (GENLEN),A ;Save it
JP RSKP ;Return to the caller
;end of file