home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
kermit.columbia.edu
/
kermit.columbia.edu.tar
/
kermit.columbia.edu
/
archives
/
trs80model4.zip
/
m4send.asm
< prev
next >
Wrap
Assembly Source File
|
1986-10-22
|
12KB
|
432 lines
; M4SEND/ASM
;
; SEND COMMAND
;
SEND EQU $
CALL NEWLIN
LD A,CMTXT ;PARSE A TEXT STRING
LD DE,MFNBUF ;GIVE THE ADDRESS FOR THE STRING
PUSH DE ;Save it
CALL COMND ;GET THE INPUT
JP KERMT2 ;GIVE UP ON BAD PARSE.
POP HL ;Get the pointer
LD (MFNPTR),HL ;Save it as the start
LD A,1 ;Set the log names flag
LD (LOGNAMES),A
CALL BUILDF ;Build a list doing wildcarding
LD A,(FILECNT) ;Get the number of files
IFNZ SEND11 ;Jump if some files were found
STROUT NOFILES ;Print the message
JP KERMIT
SEND11 LD (MFNPTR),HL ;Save the start of the found list
CALL MFNAME ;Get the next from the list
JR NC,SEND14 ;Jump if got a name
CALL NEWLIN
LD A,19 ;Issue system error, Illeagal filename
CALL XERROR
JP KERMIT ;GET A NEW COMMAND
SEND14 CALL INIT ;Clear the line and initialize buffers
XOR A
LD (PKTNUM),A
LD (NUMTRY),A ;SET THE NUMBER OF TRIES TO ZERO.
LD HL,0
LD (NUMPKT),HL ;SET THE NUMBER OF PACKETS TO ZERO.
LD (NUMRTR),HL ;SET THE NUMBER OF RETRIES TO ZERO.
LD (KTRANS),HL
LD A,'1' ;RESET TO USE SINGLE CHARACTER CHECKSUM
LD (CURCHK),A ;FOR STARTUP
NSTATE 'S'
LD (DISFLG),A ;Put in something non zero
CALL CONDCHR ;Display starting sendinit character 'S'
CALL CLRPRT ;CLEAR OUT ANY STACKED NAKS
STROUT HELPMSG
CALL PROTO ;Do protocol states
JP KERMIT ;Return to Kermit
;
; SEND ROUTINES
; SEND INITIATE
;
SINIT 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
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,(NUMPKT) ;GET THE PACKET NUMBER.
LD (ARGBLK),A
SRPACK 'S' ;Do send init, and get response
IFANOT 'Y',SINIT3 ;Was it an ACK? Jump if not
CALL CHKBLK
RET NZ ;IF NOT TRY AGAIN.
CALL DOINC ;Increment and reset
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 'F' ;Set the state
CALL CONDCHR
CALL GETFIL ;Open the file name given in FCB
JP SNDABORT ;Something is wrong if come to here
RET ;Next state in protocol
;
; Come here on bad answer to S packet
;
SINIT3 CP 'N' ;NAK?
JP NZ,BADERROR ;If not, then it is a fatal error
CALL CONDCHR ;Output N character
RET ;Back to protocol
;
; Terminate a transaction log because of an error
;
;
; SEND FILE HEADER
;
SFILE CALL CHKTRYS ;Check retry threshold
XOR A ;CLEAR A
LD (CZSEEN),A
LD DE,DATA ;GET A POINTER TO OUR DATA BLOCK.
LD HL,MFREQ ;Get filename
LD BC,255 ;B must be zero, C must be big for LDI
SF1 LD A,(HL)
IFA '/',SF2
IFA ':',SF4
IFALT ' ',SF4
LDI
INC B
JR SF1
SF2 LD (HL),'.'
LDI
INC B
SF3 LD A,(HL)
IFALT ' ',SF4
IFA ':',SF4
LDI
INC B
JR SF3
SF4 EQU $
LD (DATPTR),DE
LD (FCBPTR),HL
LD A,B ;NUMBER OF CHAR IN FILE NAME.
LD (ARGBLK+1),A
EX DE,HL
LD (HL),EOS ;Put in the print terminator
LD A,(PKTNUM) ;GET THE PACKET NUMBER.
LD (ARGBLK),A
SRPACK 'F' ;Send file header and get response
IFANOT 'Y',SFILE2 ;Jump if not an ACK
CALL CHKBLK ;Check packet number
RET NZ ;Return if not the right one
SFIL14 CALL DOINC ;Increment packet count
SFIL15 CALL RSETPKT ;Reinitialize GETPKT()
CALL GTCHR
JP SFIL16 ;ERROR GO SEE IF ITS EOF.
JR SFIL17 ;GOT THE CHARS, PROCEED.
SFIL16 CP 0FFH ;IS IT EOF?
JP NZ,SNDABORT ;IF NOT GIVE UP.
NSTATE 'Z' ;Set EOF state
CALL CONDCHR
RET
SFIL17 EQU $
NSTATE 'T' ;Set state to data send
LD (DISFLG),A ;Make sure display is on
RET
SFILE2 CP 'N' ;NAK?
JP NZ,BADERROR ;TRY IF ERROR PACKET.
CALL CONDCHR ;Display the packet character
CALL CHKBLKINC ;Check NAK for packet N+1
RET NZ ;If not, then try to resend
JR SFIL14 ;As good as an ACK, join the ack code
;
; Send transition state from Send file to Send data
;
SNDTRAN EQU $
STROUT KERSND ;Print SENDING message
STROUT TFILNAM ;Print the file name
LD A,(TRANLOG) ;Check if logging active
IFZ SNDTRAN2 ;If not, then jump
LD DE,TRFCB ;Get the log file FCB
TRLOG KERSND,SNDTRAN1 ;Log the SENDING=> message
TRLOG TFILNAM,SNDTRAN1 ;Log the file name
TRLOG TIMEMES,SNDTRAN1;Log the time: message
CALL PRTTIME ;Print the time
JR SNDTRAN2 ;Join other code
;
; Close up on a logging error
;
SNDTRAN1 EQU $
XOR A ;Reset the log open flag
LD (TRANLOG),A
LD DE,TRFCB ;Close the log file
CALL XCLOSE
SNDTRAN2 EQU $
NSTATE 'D' ;Set the state to SEND DATA
RET
;
; SEND DATA
;
SDATA CALL CHKTRYS ;Check the retry threshold
LD DE,DATA ;Get the data area
LD HL,FILBUF ;Get the file buffer
LD A,(SIZE) ;Get the number of bytes encoded
IFZ SDAT11 ;Jump if there are none
LD C,A ;Put LSB into C
LD B,0 ;Zero B
LDIR ;Move the bytes
SDAT11 LD A,(SIZE) ;Get the number of bytes back
LD (ARGBLK+1),A ;Store it as the length
LD A,(PKTNUM) ;Get the current packet number
LD (ARGBLK),A ;Put it in the packet
LD A,'D' ;Get the packet type
CALL SPACK ;Send a data packet
JP SNDABORT ;Abort if send fails
LD A,(NUMPKT) ;See if time to log progress
AND 3 ;Every 4 packets
LD A,'.' ;Get the character
CALL Z,CONDCHR ;Output if it is time
RPACKET ;Get a packet
IFANOT 'Y',SDATA2 ;Jump if not an ACK
CALL CHKBLK ;See if proper packet number
RET NZ ;Wait for more if not right number
CALL DOINC ;Increment and reset
LD A,(ARGBLK+1) ;Get the length of packet
IFANOT 1,SDAT15 ;Jump if not 1 character
LD A,(DATA) ;Get the character sent in ACK
IFANOT 'Z',SDAT14 ;Is it end of file? Jump if not
LD (CZSEEN),A ;Save it
JR SDAT15 ;Continue
SDAT14 IFANOT 'X',SDAT15 ;Was it EOT? Jump if not
LD (CZSEEN),A ;Save it
SDAT15 LD A,(CZSEEN) ;Get the character
IFZ SDAT12 ;Jump if nothing there
CALL CONDCHR ;Display the character
NSTATE 'Z' ;Set the state to EOF
RET ;Return to protocol
;
SDAT12 CALL GTCHR ;Get more data from input file
JP SDAT13 ;Jump if error occurs (might be EOF)
RET ;Continue sending
;
SDAT13 CP 0FFH ;Was the file error EOF?
JP NZ,SNDABORT ;If not, then file error, so abort
NSTATE 'Z' ;Set state to EOF
CALL CONDCHR ;Output the state
RET ;Return to protocol
;
SDATA2 CP 'N' ;Is it a NAK?
JP NZ,BADERROR ;Nope, check next type
CALL CONDCHR ;Display packet type
CALL CHKBLKINC ;NAK this packet plus one?
JR Z,SDAT12 ;Just as good as an ACK, Join ACK code.
CALL UPDRTR
RET
;
; Send the EOF packet
;
SEOF CALL CHKTRYS ;Check the retry threshold
CALL INITBLK ;Initialize ARGBLK
LD A,(CZSEEN) ;Check for ABORT
IFZ SEOF14 ;If not aborted, then keep going
LD A,(TRANLOG) ;Check if logging active
IFZ SEOF10 ;Jump if no logging
LD DE,TRFCB ;Get the log file FCB
TRLOG TRANCANC,SEOF19 ;Log the canceled message
SEOF10 LD A,(DISCARD) ;Should the file be deleted?
IFZ SEOF11 ;Skip delete if user want to keep it
LD A,'D' ;Tell other end to discard packet
LD (DATA),A ;Store the delete character
LD A,1 ;Length is one character
SEOF11 LD (ARGBLK+1),A ;Store the length
SEOF14 SRPACK 'Z' ;Send EOF, and get a response
IFANOT 'Y',SEOF2 ;Jump if not an ACK
CALL CHKBLK ;Check the packet number
RET NZ ;Return if not correct one
SEOF12 CALL DOINC ;Increment and reset
CALL CHKFCB ;Check for file, don't close *SO
CALL Z,XCLOSE ;Conditionally close it
LD A,(CZSEEN) ;Did the user force us to stop?
IFA 'Z',SEOF13 ;Jump if EOF was signaled by user
CALL MFNAME ;Get a new file name
JR C,SEOF13 ;Jump if no more
CALL GETFIL ;AND OPEN IT
JP SNDABORT ;SOMETHING IS WRONG, DIE.
XOR A ;CLEAR A
LD (CZSEEN),A
NSTATE 'F' ;Set state to file send
CALL CONDCHR
LD IX,STRANS ;Update transmission information
CALL UPDTRANS
RET ;Continue protocol
;
SEOF13 NSTATE 'B' ;Set state to EOT
CALL CONDCHR
LD IX,STRANS ;Update the transmission info
CALL UPDTRANS
RET
;
SEOF2 CP 'N' ;NAK?
JP NZ,BADERROR ;TRY AND SEE IF ITS AN ERROR PACKET.
CALL CONDCHR
CALL UPDRTR ;UPDATE THE NUMBER OF RETRIES.
CALL CHKBLKINC
RET NZ ;IF NOT GO TRY AGAIN.
JR SEOF12 ;Just as good as an ACK
;
SEOF19 XOR A ;Reset the log open flag
LD (TRANLOG),A
LD DE,TRFCB ;Close the file
CALL XCLOSE
JP SEOF10 ;Join other code
;
; Send EOT packet
;
SEOT CALL CHKTRYS ;Check the retry threshold
CALL INITBLK ;Initialize ARGBLK
SRPACK 'B' ;Send END of BATCH and get response
IFANOT 'Y',SEOT2 ;Jump if not ACK
CALL CHKBLK ;Check the packet number
RET NZ ;Return if not correct
SEOT12 CALL DOINC ;Increment and reset
NSTATE 'C' ;Set state to complete
RET
SEOT2 CP 'N' ;NAK?
JP NZ,BADERROR ;IS IT ERROR.
CALL CONDCHR
CALL UPDRTR ;UPDATE THE NUMBER OF RETRIES.
CALL CHKBLKINC
JP Z,SEOT12 ;Good as an ACK, so continue
OR A ;Is the other end starting over?
JR Z,SEOT12
RET
;
; Check the retry threshold
;
CHKTRYS EQU $ ;Check retry threshold
LD A,(MAXTRY) ;Get the maximum
LD B,A ;Save
LD A,(NUMTRY)
IFALT B,CHKTRYS1 ;Jump if not at limit
POP DE ;Remove the callers return addr
LD DE,ERMS14 ;Print the error message
CALL ERROR3
JP SNDABORT ;CHANGE THE STATE TO ABORT.
CHKTRYS1 EQU $
IFZ CHKTRYS2 ;Jump if first try
PUSH AF ;Save the count
LD A,'%' ;Print retrying message
CALL CONDCHR
POP AF ;Get the count back
CHKTRYS2 EQU $
INC A ;Increment it
LD (NUMTRY),A ;Save the new count
RET
;
; Increment the packet count modulo 64, A already has the old one.
;
INCPKT INC A
AND 3FH
LD (PKTNUM),A
RET
;
; Move numtry to oldtry and zero numtry
;
NUM2OLD EQU $
LD A,(NUMTRY) ;GET THE NUMBER OF TRIES.
LD (OLDTRY),A ;SAVE IT.
XOR A
LD (NUMTRY),A ;RESET THE NUMBER OF TRIES.
RET
;
; Increment display packet count
;
INCDISPKT EQU $
LD HL,(NUMPKT)
INC HL
LD (NUMPKT),HL
RET
;
; Do several things
;
DOINC CALL INCPKT
CALL INCDISPKT
JP NUM2OLD
;
; Check the packet number 'received plus 1' verses that sent
; return their relation, eg <, >, =, <>. This is used as a
; method to determine that a NAK for packet N+1 is equivelent
; to an ACK for packet N.
;
CHKBLKINC EQU $
LD A,(PKTNUM) ;Get the current packet number
INC A ;Plus one
LD B,A ;Save it
LD A,(ARGBLK) ;Get the packet number returned
CP B ;Are they equal?
RET ;Return the flags setting
;
; Conditionally display the character in A based on the value
; of DISFLG. This is used to print the characters during transfers
; that show the status of the transfer. eg '.', 'Q', 'S', 'Z', etc
;
CONDCHR EQU $
LD C,A ;Save the character
LD A,(DISFLG) ;Check if should display the character
OR A ;Set the flags
RET Z ;Return if flag not set
LD A,C ;Get the character back
JP CONOUT ;Print the terminal on the console
;
RSETPKT EQU $
XOR A ;GET A ZERO.
LD (EOFLAG),A ;INDICATE NOT EOF.
LD (SIZE),A ;Nothing in packet buffer
LD (OSIZE),A ;No old length
LD (LEFTOVER),A ;No leftovers from previous packet
LD (RPTCNT),A ;No repeated characters yet
LD (PREVCH),A ;Reset any previous character knowledge
LD HL,-1 ;Set NO next character
LD (NEXT),HL
LD (CH),HL
RET
;
BADERROR EQU $
CP 'E' ;IS IT AN ERROR PACKET.
JP NZ,SNDABORT
CALL ERROR
JP SNDABORT
;
INITBLK EQU $
LD A,(PKTNUM) ;GET THE PACKET NUMBER.
LD (ARGBLK),A
XOR A
LD (ARGBLK+1),A ;NO DATA.
RET
PRTTIME EQU $
PUSH AF ;Save the regs
PUSH BC
PUSH HL
PUSH DE ;Save the FILE FCB
LD HL,CLBUF ;Get the character buffer
PUSH HL ;Save the address
CALL XTIME ;Get the time
LD (HL),CR ;Get a new line
INC HL ;Point to next pos
LD (HL),EOS ;Terminate the string
POP HL ;Get the string to print back
POP DE ;Get the log file FCB
CALL OUTLOG
CALL TIMCLOSE ;Close up if error occurs
POP HL ;Restore the regs
POP BC
POP AF
RET
;
TIMCLOSE EQU $
XOR A ;Reset the file open flag
LD (LOGTRAN),A
LD DE,TRFCB ;Get the FCB
JP XCLOSE ;Close the file and return.
; end of file