home *** CD-ROM | disk | FTP | other *** search
- ; CP4PKT.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 KERMIT protocol, and the commands that use them:
- ; RECEIVE, SEND, FINISH, and LOGOUT.
- ;
- ; revision history:
- ; edir 6: November 22, 1984
- ; Change SEND's 'Unable to find file' error exit from calling
- ; error3 to calling prtstr instead. I don't know about you, but
- ; I greatly dislike having messages dumped into pre-existing
- ; junk on the screen where I have to spend lots of time hunting
- ; for them. [Hal Hostetler]
- ;
- ; edit 5: September 9, 1984
- ; Call flsmdm in init to flush old input when starting transfers.
- ; Select console before returning from inpkt.
- ; Replace inline code with calls to makfil/clofil to set up for
- ; multisector buffering on output.
- ; Remove superfluous call to clrlin in error3.
- ;
- ; edit 4: August 21, 1984 (CJC)
- ; Fix comment in inpkt: packet is terminated by NUL on return, not CR.
- ; If debugging, display the outgoing packet before putting the EOL
- ; character on, so the dumped packet doesn't get overwritten.
- ;
- ; edit 3: July 27, 1984
- ; add link directive for LASM. CP4PKT is linked by CP4MIT, and links
- ; to CP4TT. Add Toad Hall TACtrap to permit operations through a TAC.
- ;
- ; edit 2: June 8, 1984
- ; formatting and documentation; remove some unused labels; move setpar
- ; to cp4mit.m80; add module version string; make all arithmetic on
- ; 'pktnum' modulo 64; apply defaults correctly for missing parameters
- ; in send-init packet (and corresponding ack).
- ;
- ; edit 1: May, 1984
- ; extracted from CPMBASE.M80 version 3.9; modifications are described
- ; in the accompanying .UPD file.
- ;
- pktver: db 'CP4PKT.ASM (6) 22-Nov-84$' ; name, edit number, date
-
- ; RECEIVE command
- ; here from: kermit
-
- read: lxi d,data ;Where to put the text (if any.)
- mvi a,cmtxt
- call comnd ;Get either some text or a confirm.
- jmp kermt3 ; Didn't get anything.
- ora a ;Get any chars?
- jz read1 ;Nope, just a regular send.
- sta argblk+1 ;Store the number of chars.
- xchg ;Get pointer into HL.
- mvi m,'$' ;Put in a dollar sign for printing.
- call init ;Clear the line and initialize the buffers.
- call scrfln ;Position cursor
- lxi d,data ;Print the file name
- call prtstr
- mvi a,'1' ;Start with single character checksum
- sta curchk ;Save the type
- xra a ;Start a packet zero.
- sta argblk
- mvi a,'R' ;Receive init packet.
- call spack ;Send the packet.
- jmp kermt3 ; Die!
- jmp read12
-
- read1: call init ;Clear the line and initialize the buffers.
- read12: xra a
- sta czseen ;Clear the ^X/^Z flag initially.
- lxi h,0
- shld numpkt ;Set the number of packets to zero.
- shld numrtr ;Set the number of retries to zero.
- sta pktnum ;Set the packet number to zero.
- sta numtry ;Set the number of tries to zero.
- call scrnrt ;Position cursor
- lxi h,0
- call nout ;Write the number of retries.
- mvi a,'R'
- sta state ;Set the state to receive initiate.
- ;...
- ;
- ;RECEIVE state table switcher.
-
- read2: call scrnp ;Position cursor
- lhld numpkt
- call nout ;Write the current packet number.
- lda state ;Get the state.
- cpi 'D' ;Are we in the DATA receive state?
- jnz read3
- call rdata
- jmp read2
-
- read3: cpi 'F' ;Are we in the FILE receive state?
- jnz read4
- call rfile ;Call receive file.
- jmp read2
-
- read4: cpi 'R' ;Are we in the Receive-Initiate state?
- jnz read5
- call rinit
- lda state ;[jd] get new state
- cpi 'F' ;[jd] went into receive state?
- jnz read2 ;[jd] no
- lxi d,inms24 ;[jd] yes, get receiving... message
- call finmes ;[jd] go print it
- jmp read2
-
- read5: cpi 'C' ;Are we in the Receive-Complete state?
- jnz read6
- lxi d,infms3 ;Put in "Complete" message.
- lda czseen ;Or was it interrupted?
- ora a ; . . .
- jz read5a ;No.
- xra a ;Yes, clear flag.
- sta czseen ; ...
- lxi d,inms13 ;Issue "interrupted" message.
- read5a: call finmes ;Print completion message in right place.
- jmp kermit
-
- read6: cpi 'A' ;Are we in the Receive-"Abort" state?
- jnz read7
- read7: lxi d,infms4 ;Anything else is equivalent to "abort".
- call finmes
- jmp kermit
- ;
- ; Receive routines
-
- ; Receive init
- ; called by: read
-
- rinit: lda numtry ;Get the number of tries.
- cpi imxtry ;Have we reached the maximum number of tries?
- jm rinit2
- lxi d,ermes4
- call error3 ;Move cursor and print an error message.
- jmp abort ;Change the state to abort.
-
- rinit2: inr a ;Increment it.
- sta numtry ;Save the updated number of tries.
- mvi a,'1' ;Reset block check type to single character
- sta curchk ;Store as current type for initialization
- call rpack ;Get a packet.
- jmp nak ; Trashed packet: nak, retry.
- cpi 'S' ;Is it a send initiate packet?
- jnz rinit3 ;If not see if its an error.
- lda numtry ;Get the number of tries.
- sta oldtry ;Save it.
- xra a
- sta numtry ;Reset the number of tries.
- lda argblk ;Returned packet number. (Synchronize them.)
- call countp
- lda argblk+1 ;Get the number of arguments received.
- lxi h,data ;Get a pointer to the data.
- call spar ;Get the data into the proper variables.
- lxi h,data ;Get a pointer to our data block.
- call rpar ;Set up the receive parameters.
- sta argblk+1 ;Store the returned number of arguments.
- mvi a,'Y' ;Acknowledge packet.
- call spack ;Send the packet.
- jmp abort ; Failed, abort.
- lda inichk ;Now switch to agreed upon check-type
- sta curchk ;For all future packets
- mvi a,'F' ;Set the state to file send.
- sta state
- ret
-
- rinit3: cpi 'E' ;Is it an error packet.
- jnz nak0 ;If not NAK whatever it is.
- call error
- jmp abort
- ;
- ; Receive file
- ; called by: read
-
- rfile: lda numtry ;Get the number of tries.
- cpi maxtry ;Have we reached the maximum number of tries?
- jm rfile1
- lxi d,ermes5
- call error3 ;Move cursor and print an error message.
- jmp abort ;Change the state to abort.
-
- rfile1: inr a ;Increment it.
- sta numtry ;Save the updated number of tries.
- call rpack ;Get a packet.
- jmp nak ; Trashed packet: nak, retry.
- cpi 'S' ;Is it a send initiate packet?
- jnz rfile2 ; No, try next type.
- lda oldtry ;Get the number of tries.
- cpi imxtry ;Have we reached the maximum number of tries?
- jm rfil12 ;If not proceed.
- lxi d,ermes4
- call error3 ;Move cursor and print an error message.
- jmp abort ;Change the state to abort.
-
- rfil12: inr a ;Increment it.
- sta oldtry ;Save the updated number of tries.
- lda pktnum ;Get the present packet number.
- dcr a ;Decrement
- ani 3FH ; modulo 64
- mov b,a
- lda argblk ;Get the packet's number
- cmp b ;Is the packet's number one less than now?
- jnz nak0 ;No, NAK and try again.
- call updrtr ;Update the retry count.
- xra a
- sta numtry ;Reset the number of tries.
- lxi h,data ;Get a pointer to our data block.
- call rpar ;Set up the parameter information.
- sta argblk+1 ;Save the number of arguments.
- mvi a,'Y' ;Acknowledge packet.
- call spack ;Send the packet.
- jmp abort ; Failed, abort.
- ret
-
- rfile2: cpi 'Z' ;Is it an EOF packet?
- jnz rfile3 ; No, try next type.
- lda oldtry ;Get the number of tries.
- cpi maxtry ;Have we reached the maximum number of tries?
- jm rfil21 ;If not proceed.
- lxi d,ermes6
- call error3 ;Move cursor and print an error message.
- jmp abort ;Change the state to abort.
-
- rfil21: call tryagn
- ret
-
- rfile3: cpi 'F' ;Start of file?
- jnz rfile4
- call compp
- jnz nak0 ;No, NAK it and try again.
- call countp
- call gofil ;Get a file to write to, and init output buffer.
- jmp abort
- lda numtry ;Get the number of tries.
- sta oldtry ;Save it.
- call ackp
- mvi a,'D' ;Set the state to data receive.
- sta state
- lda czseen ;Check if we punted a file
- cpi 'Z' ;and didn't want any more
- rz ;If that was the request, keep telling other end
- xra a ;Otherwise, clear flag (^X is only for one file)
- sta czseen ;And store the flag back
- ret
-
- rfile4: cpi 'B' ;End of transmission.
- jnz rfile5
- call compp
- jnz nak0 ;No, NAK it and try again.
- xra a ;No data. (Packet number already in argblk).
- sta argblk+1
- mvi a,'Y' ;Acknowledge packet.
- call spack ;Send the packet.
- jmp abort
- mvi a,'C' ;Set the state to complete.
- sta state
- ret
-
- rfile5: cpi 'E' ;Is it an error packet.
- jnz abort
- call error
- jmp abort
- ;
- ; Receive data
- ; called by: read
-
- rdata: lda numtry ;Get the number of tries.
- cpi maxtry ;Have we reached the maximum number of tries?
- jm rdata1
- lxi d,erms10
- call error3 ;Display error message.
- jmp abort ;Change the state to abort.
-
- rdata1: inr a ;Increment it.
- sta numtry ;Save the updated number of tries.
- call rpack ;Get a packet.
- jmp nak ; Trashed packet: nak, retry.
- cpi 'D' ;Is it a data packet?
- jnz rdata2 ; No, try next type.
- call compp
- jz rdat14
- lda oldtry ;Get the number of tries.
- cpi maxtry ;Have we reached the maximum number of tries?
- jm rdat12 ;If not proceed.
- lxi d,erms10
- call error3 ;Display err msg.
- jmp abort ;Change the state to abort.
-
- rdat12: call tryagn
- ret
-
- rdat14: call countp
- lda numtry ;Get the number of tries.
- sta oldtry ;Save it.
- lda argblk+1 ;Get the length of the data.
- call ptchr
- jmp abort ; Unable to write out chars;abort.
- xra a
- sta numtry ;Reset the number of tries.
- sta argblk+1 ;No data. (Packet number still in argblk.)
- mov c,a ;Assume no data
- lda czseen ;Check if control-X typed
- ora a ; . . .
- jz rdat15 ;Zero if not typed
- mov c,a ;Get the type of character typed
- mvi a,1 ;One data character
- sta argblk+1 ;Save the count
- mov a,c ;Get the possible data character
- sta data ;Store in data area
- rdat15: mvi a,'Y' ;Acknowledge packet.
- call spack ;Send the packet.
- jmp abort
- ret
-
- rdata2: cpi 'F' ;Start of file?
- jnz rdata3 ; No, try next type.
- lda oldtry ;Get the number of tries.
- cpi maxtry ;Have we reached the maximum number of tries?
- jm rdat21 ;If not proceed.
- lxi d,ermes5
- call error3 ;Display err msg.
- jmp abort ;Change the state to abort.
-
- rdat21: call tryagn
- ret
-
- rdata3: cpi 'Z' ;Is it a EOF packet?
- jnz rdata4 ;Try and see if its an error.
- call compp
- jnz nak0 ;No, NAK it and try again.
- call countp
- lda argblk+1 ;Get the data length
- cpi 1 ;Have one item?
- jnz rdat33 ;If not, ignore data
- lda data ;Yes, get the character
- cpi 'D' ;Is it a 'D' for discard?
- jz rdat36 ;If so, punt file
- rdat33: call clofil ;Finish off the file.
- jmp rdat37 ; Give up if the disk is full.
- xra a ;Since we kept the file,
- sta czseen ;don't say it was discarded.
- rdat36: lda numtry ;Get the number of tries.
- sta oldtry ;Save it.
- call ackp
- mvi a,'F'
- sta state
- ret
-
- rdat37: lxi d,erms11 ; "?Disk full"
- call error3 ; put it on the error line
- jmp abort ; abort transfer
-
- rdata4: cpi 'E' ;Is it an error packet.
- jnz abort
- call error
- jmp abort
- ;
- ; SEND command
- ; here from: kermit
-
- send: mvi a,cmifi ;Parse an input file spec.
- lxi d,fcb ;Give the address for the FCB.
- call comnd
- jmp kermit ; Give up on bad parse.
- call cfmcmd
- call mfname ;handle (multi) files
- jnc send14 ;got a valid file-name
- lxi d,erms15
- call prtstr ;Display error msg. ([hh] where it's visible)
- jmp kermit
-
- send14: call init ;Clear the line and initialize the buffers.
- xra a
- sta pktnum ;Set the packet number to zero.
- sta numtry ;Set the number of tries to zero.
- sta wrn8 ;[jd] we haven't sent the 8-bit-lost warning
- lxi h,0
- shld numpkt ;Set the number of packets to zero.
- shld numrtr ;Set the number of retries to zero.
- call scrnrt ;Position cursor
- lxi h,0
- call nout ;Write the number of retries.
- mvi a,'1' ;Reset to use single character checksum
- sta curchk ;For startup
- mvi a,'S'
- sta state ;Set the state to receive initiate.
- ;...
- ;
- ;SEND state table switcher
-
- send2: call scrnp ;Position cursor
- lhld numpkt
- call nout ;Write the packet number.
- lda state ;Get the state.
- cpi 'D' ;Are we in the data send state?
- jnz send3
- call sdata
- jmp send2
-
- send3: cpi 'F' ;Are we in the file send state?
- jnz send4
- call sfile ;Call send file.
- jmp send2
-
- send4: cpi 'Z' ;Are we in the EOF state?
- jnz send5
- call seof
- jmp send2
-
- send5: cpi 'S' ;Are we in the send initiate state?
- jnz send6
- call sinit
- lda state ;[jd] get state back
- cpi 'F' ;[jd] into file send state yet?
- jnz send2 ;[jd] no
- lxi d,inms23 ;[jd] yes, print sending...
- call finmes ;[jd]
- jmp send2
-
- send6: cpi 'B' ;Are we in the eot state?
- jnz send7
- call seot
- jmp send2
-
- send7: cpi 'C' ;Are we in the send complete state?
- jnz send8 ;No...
- lxi d,infms3 ;Yes, write "Complete" message.
- lda czseen ;Or was it interrupted?
- ora a ; . . .
- jz send7a ;No.
- lxi d,inms13 ;Yes, then say "Interrupted" instead.
- send7a: call finmes
- jmp kermit
-
- send8: cpi 'A' ;Are we in the send "abort" state?
- jnz send9
- lxi d,infms4 ;Print message.
- call finmes
- jmp kermit
-
- send9: lxi d,infms4 ;Anything else is equivalent to "abort".
- call finmes
- jmp kermit
- ;
- ; Send routines
-
- ; Send initiate
- ; called by: send
-
- sinit: lda numtry ;Get the number of tries.
- cpi imxtry ;Have we reached the maximum number of tries?
- jm sinit2
- lxi d,erms14
- call error3 ;Display ermsg
- jmp abort ;Change the state to abort.
-
- sinit2: inr a ;Increment it.
- sta numtry ;Save the updated number of tries.
- mvi a,'1' ;Reset to use single character checksum
- sta curchk ;For startup
- lda chktyp ;Get our desired block check type
- sta inichk ;Store so we tell other end
- lxi h,data ;Get a pointer to our data block.
- call rpar ;Set up the parameter information.
- sta argblk+1 ;Save the number of arguments.
- lda numpkt ;Get the packet number.
- sta argblk
- mvi a,'S' ;Send initiate packet.
- call spack ;Send the packet.
- jmp abort ; Failed, abort.
- call rpack ;Get a packet.
- jmp r ; Trashed packet don't change state, retry.
- cpi 'Y' ;ACK?
- jnz sinit3 ;If not try next.
- call compp
- rnz ;If not try again.
- call countp
- lda argblk+1 ;Get the number of pieces of data.
- lxi h,data ;Pointer to the data.
- call spar ;Read in the data.
- lda numtry ;Get the number of tries.
- sta oldtry ;Save it.
- xra a
- sta numtry ;Reset the number of tries.
- lda inichk ;Get the agreed upon block check type
- sta curchk ;Store as type to use for packets now
- mvi a,'F' ;Set the state to file send.
- sta state
- call getfil ;Open the file.
- ret ; assume success; mfname thinks the file exists.
-
- sinit3: cpi 'N' ;NAK?
- jnz sinit4 ;If not see if its an error.
- call updrtr ;Update the number of retries.
- lda pktnum ;Get the present packet number.
- inr a ;Increment
- ani 3FH ; modulo 64
- mov b,a
- lda argblk ;Get the packet's number.
- cmp b ;Is the packet's number one more than now?
- rnz ;If not assume its for this packet, go again.
- xra a
- sta numtry ;Reset number of tries.
- mvi a,'F' ;Set the state to file send.
- sta state
- ret
-
- sinit4: cpi 'E' ;Is it an error packet.
- jnz abort
- call error
- jmp abort
- ;
- ; Send file header
- ; called by: send
-
- sfile: lda numtry ;Get the number of tries.
- cpi maxtry ;Have we reached the maximum number of tries?
- jm sfile1
- lxi d,erms14
- call error3
- jmp abort ;Change the state to abort.
-
- sfile1: inr a ;Increment it.
- sta numtry ;Save the updated number of tries.
- xra a ;Clear A
- sta czseen ;No control-Z or X seen
- lxi h,data ;Get a pointer to our data block.
- shld datptr ;Save it.
- lxi h,fcb+1 ;Pointer to the file name in the FCB.
- shld fcbptr ;Save position in FCB.
- mvi b,0 ;No chars yet.
- mvi c,0
- sfil11: mov a,b
- cpi 8H ;Is this the ninth char?
- jnz sfil12 ;If not proceed.
- mvi a,'.' ;Get a dot.
- lhld datptr
- mov m,a ;Put the char in the data packet.
- inx h
- shld datptr ;Save position in data packet.
- inr c
- sfil12: inr b ;Increment the count.
- mov a,b
- cpi 0CH ;Twelve?
- jp sfil13
- lhld fcbptr
- mov a,m
- ani 7fH ;Turn off CP/M 2 or 3's high bits.
- inx h
- shld fcbptr ;Save position in FCB.
- cpi '!' ;Is it a good character?
- jm sfil11 ;If not get the next.
- lhld datptr
- mov m,a ;Put the char in the data packet.
- inx h
- shld datptr ;Save position in data packet.
- inr c
- jmp sfil11 ;Get another.
-
- sfil13: mov a,c ;Number of char in file name.
- sta argblk+1
- lhld datptr
- mvi a,'$'
- mov m,a ;Put in a dollar sign for printing.
- call scrfln ;Position cursor
- lxi d,data ;Print the file name
- call prtstr
- lda pktnum ;Get the packet number.
- sta argblk
- mvi a,'F' ;File header packet.
- call spack ;Send the packet.
- jmp abort ; Failed, abort.
- call rpack ;Get a packet.
- jmp r ; Trashed packet don't change state, retry.
- cpi 'Y' ;ACK?
- jnz sfile2 ;If not try next.
- call compp
- rnz ;If not hold out for the right one.
- sfil14: call countp
- lda numtry ;Get the number of tries.
- sta oldtry ;Save it.
- xra a
- sta numtry ;Reset the number of tries.
- call gtchr ;Fill the first data packet
- jmp sfil16 ;Error go see if its EOF.
- ; ;Got the chars, proceed.
- sta size ;Save the size of the data gotten.
- mvi a,'D' ;Set the state to data send.
- sta state
- ret
-
- sfil16: cpi 0FFH ;Is it EOF?
- jnz abort ;If not give up.
- mvi a,'Z' ;Set the state to EOF.
- sta state
- ret
-
- sfile2: cpi 'N' ;NAK?
- jnz sfile3 ;Try if error packet.
- call updrtr ;Update the number of retries.
- lda pktnum ;Get the present packet number.
- inr a ;Increment
- ani 3FH ; modulo 64
- mov b,a
- lda argblk ;Get the packet's number.
- cmp b ;Is the packet's number one more than now?
- rnz ;If not go try again.
- jmp sfil14 ;Just as good as a ACK;go to the ACK code.
-
- sfile3: cpi 'E' ;Is it an error packet.
- jnz abort
- call error
- jmp abort
- ;
- ; Send data
- ; called by: send
-
- sdata: lda numtry ;Get the number of tries.
- cpi maxtry ;Have we reached the maximum number of tries?
- jm sdata1
- lxi d,erms14
- call error3
- jmp abort ;Change the state to abort.
-
- sdata1: inr a ;Increment it.
- sta numtry ;Save the updated number of tries.
- lxi h, data ;Get a pointer to our data block.
- shld datptr ;Save it.
- lxi h,filbuf ;Pointer to chars to be sent.
- shld cbfptr ;Save position in char buffer.
- mvi b,1 ;First char.
- sdat11: lhld cbfptr
- mov a,m
- inx h
- shld cbfptr ;Save position in char buffer.
- mov c,a ;[jd] preserve character temporarily
- lda quot8 ;[jd] doing eighth-bit quoting?
- ora a ;[jd]
- mov a,c ;[jd] restore char
- jnz sdat4 ;[jd] using eighth-bit quoting, no warning
- lda parity ;[jd] get parity
- cpi parnon ;[jd] none?
- mov a,c ;[jd] restore character
- jz sdat4 ;[jd] no parity, leave char alone
- lda wrn8 ;[jd] look at warning flag
- ora a ;[jd] have we already given the warning?
- jnz sdat5 ;[jd] yes, skip this
- mov a,c ;[jd] restore character...
- ani 80h ;[jd] examine parity
- jz sdat5 ;[jd] no parity, no warning.
- call parwrn ;[jd] ...print warning - parity lost
- mvi a,0ffh ;[jd] remember that we sent the message
- sta wrn8 ;[jd]
- sdat5: mov a,c ;[jd] restore character again
- ani 7fh ;[jd] strip parity so not checksummed
- sdat4: lhld datptr
- mov m,a ;Put the char in the data packet.
- inx h
- shld datptr ;Save position in data packet.
- inr b ;Increment the count.
- lda size ;Get the number of chars in char buffer.
- cmp b ;Have we transfered that many?
- jp sdat11 ;If not get another.
- lda size ;Number of char in char buffer.
- sta argblk+1
- lda pktnum ;Get the packet number.
- sta argblk
- mvi a,'D' ;Data packet.
- call spack ;Send the packet.
- jmp abort ; Failed, abort.
- call rpack ;Get a packet.
- jmp r ; Trashed packet don't change state, retry.
- cpi 'Y' ;ACK?
- jnz sdata2 ;If not try next.
- call compp
- rnz ;If not hold out for the right one.
- lda argblk ;Get the packet number back
- call countp
- lda numtry ;Get the number of tries.
- sta oldtry ;Save it.
- xra a
- sta numtry ;Reset the number of tries.
- lda argblk+1 ;Get the data length
- cpi 1 ;Check if only 1 character?
- jnz sdat15 ;If not, just continue
- lda data ;Got one character, get it from data
- cpi 'Z' ;Want to abort entire stream?
- jnz sdat14 ;If not, check for just this file
- sta czseen ;Yes, remember it
- sdat14: cpi 'X' ;Desire abort of current file?
- jnz sdat15 ;If not, just continue
- sta czseen ;Yes, remember that
- sdat15: lda czseen ;Also get control-Z flag
- ora a ;Check if either given
- jz sdat12 ;If neither given, continue
- mvi a,'Z' ;Change state to EOF
- sta state ; . . .
- ret ;And return
-
- sdat12: call gtchr
- jmp sdat13 ;Error go see if its EOF.
- sta size ;Save the size of the data gotten.
- ret
-
- sdat13: cpi 0FFH ;Is it EOF?
- jnz abort ;If not give up.
- mvi a,'Z' ;Set the state to EOF.
- sta state
- ret
-
- sdata2: cpi 'N' ;NAK?
- jnz sdata3 ;See if is an error packet.
- call updrtr ;Update the number of retries.
- lda pktnum ;Get the present packet number.
- inr a ;Increment
- ani 3FH ; modulo 64
- mov b,a
- lda argblk ;Get the packet's number.
- cmp b ;Is the packet's number one more than now?
- rnz ;If not go try again.
- jmp sdat12 ;Just as good as a ACK;go to the ACK code.
-
- sdata3: cpi 'E' ;Is it an error packet.
- jnz abort
- call error
- jmp abort
- ;
- ; Send EOF
- ; called by: send
-
- seof: lda numtry ;Get the number of tries.
- cpi maxtry ;Have we reached the maximum number of tries?
- jm seof1
- lxi d,erms14
- call error3
- jmp abort ;Change the state to abort.
-
- seof1: inr a ;Increment it.
- sta numtry ;Save the updated number of tries.
- lda pktnum ;Get the packet number.
- sta argblk
- xra a
- sta argblk+1 ;No data.
- lda czseen ;Check if C-Z or C-X typed
- ora a ; . . .
- jz seof14 ;If not aborted, just keep going
- mvi a,'D' ;Tell other end to discard packet
- sta data ;Store in data portion
- mvi a,1 ;One character
- sta argblk+1 ;Store the length
- seof14: mvi a,'Z' ;EOF packet.
- call spack ;Send the packet.
- jmp abort ; Failed, abort.
- call rpack ;Get a packet.
- jmp r ; Trashed packet don't change state, retry.
- cpi 'Y' ;ACK?
- jnz seof2 ;If not try next.
- call compp
- rnz ;If not hold out for the right one.
- seof12: call countp
- lda numtry ;Get the number of tries.
- sta oldtry ;Save it.
- xra a
- sta numtry ;Reset the number of tries.
- mvi c,closf ;Close the file.
- lxi d,fcb
- call bdos
- ;* Check if successful
- lda czseen ;Desire abort of entire stream?
- cpi 'Z' ;Desire abort of entire stream?
- jz seof13 ;If so, just give up now
- call mfname ;Get the next file.
- jc seof13 ; No more.
- call getfil ;and open it (assume success)
- xra a ;Clear A
- sta czseen ;Since we have not aborted this file
- mvi a,'F' ;Set the state to file send.
- sta state
- ret
-
- seof13: mvi a,'B' ;Set the state to EOT.
- sta state
- ret
-
- seof2: cpi 'N' ;NAK?
- jnz seof3 ;Try and see if its an error packet.
- call updrtr ;Update the number of retries.
- lda pktnum ;Get the present packet number.
- inr a ;Increment
- ani 3FH ; modulo 64
- mov b,a
- lda argblk ;Get the packet's number.
- cmp b ;Is the packet's number one more than now?
- rnz ;If not go try again.
- jmp seof12 ;Just as good as a ACK;go to the ACK code.
-
- seof3: cpi 'E' ;Is it an error packet.
- jnz abort
- call error
- jmp abort
- ;
- ; Send EOT
- ; called by: send
-
- seot: lda numtry ;Get the number of tries.
- cpi maxtry ;Have we reached the maximum number of tries?
- jm seot1
- lxi d,erms14
- call error3
- jmp abort ;Change the state to abort.
-
- seot1: inr a ;Increment it.
- sta numtry ;Save the updated number of tries.
- lda pktnum ;Get the packet number.
- sta argblk
- xra a
- sta argblk+1 ;No data.
- mvi a,'B' ;EOF packet.
- call spack ;Send the packet.
- jmp abort ; Failed, abort.
- call rpack ;Get a packet.
- jmp r ; Trashed packet don't change state, retry.
- cpi 'Y' ;ACK?
- jnz seot2 ;If not try next.
- call compp
- rnz ;If not hold out for the right one.
- seot12: call countp
- lda numtry ;Get the number of tries.
- sta oldtry ;Save it.
- xra a
- sta numtry ;Reset the number of tries.
- mvi a,'C' ;Set the state to file send.
- sta state
- ret
-
- seot2: cpi 'N' ;NAK?
- jnz seot3 ;Is it error.
- call updrtr ;Update the number of retries.
- lda pktnum ;Get the present packet number.
- inr a ;Increment
- ani 3FH ; modulo 64
- mov b,a
- lda argblk ;Get the packet's number.
- cmp b ;Is the packet's number one more than now?
- rnz ;If not go try again.
- jmp seot12 ;Just as good as a ACK;go to the ACK code.
-
- seot3: cpi 'E' ;Is it an error packet.
- jnz abort
- call error
- jmp abort
- ;
- ; This routine sets up the data for init packet (either the
- ; Send_init or ACK packet).
- ; called by: rinit, rfile, sinit
-
- rpar: lda rpsiz ;Get the receive packet size.
- adi ' ' ;Add a space to make it printable.
- mov m,a ;Put it in the packet.
- inx h ;Point to the next char.
- lda rtime ;Get the receive packet time out.
- adi ' ' ;Add a space.
- mov m,a ;Put it in the packet.
- inx h
- lda rpad ;Get the number of padding chars.
- adi ' '
- mov m,a
- inx h
- lda rpadch ;Get the padding char.
- adi 100O ;Uncontrol it.
- ani 7FH
- mov m,a
- inx h
- lda reol ;Get the EOL char.
- adi ' '
- mov m,a
- inx h
- lda rquote ;Get the quote char.
- mov m,a
- inx h
- mvi m,'Y' ;[jd] we know how to do 8-bit quoting
- lda parity ;[jd]
- cpi parnon ;[jd] parity none?
- jz rpar1 ;[jd] yes, keep going
- lda qbchr ;[jd] no, better request 8-bit quoting
- mov m,a
-
- rpar1:
- inx h ;Advance to next
- lda chktyp ;Get desired block check type
- mov m,a ;Store it
- inx h ;Advance pointer
- mvi a,08H ;Six pieces of data.
- ret
- ;
- ; This routine reads in all the send_init packet information.
- ; called by: rinit, sinit
-
- spar: sta temp4 ;Save the number of arguments.
- ; Initialize some variables to their required default values, so we use
- ; the right values even if the remote Kermit doesn't send the full packet:
- ; ; we don't do anything with timeout values yet.
- ; ; no default pad count/pad character?
- mvi a,cr ; EOL character = carriage-return
- sta seol
- mvi a,'#' ; quote character = '#'
- sta squote
- mvi a,'&' ; eighth-bit quote character = '&'
- sta qbchr
- mvi a,'1' ; block-check = 1-character-checksum
- sta inichk
- ;
- mov a,m ;Get the max packet size.
- sbi ' ' ;Subtract a space.
- sta spsiz ;Save it.
- lda temp4
- cpi 3 ;Fewer than three pieces?
- rm ;If so we are done.
- inx h
- inx h ;Increment past the time out info.
- mov a,m ;Get the number of padding chars.
- sbi ' '
- sta spad
- lda temp4
- cpi 4 ;Fewer than four pieces?
- rm ;If so we are done.
- inx h
- mov a,m ;Get the padding char.
- adi 100O ;Re-controlify it.
- ani 7FH
- sta spadch
- lda temp4
- cpi 5 ;Fewer than five pieces?
- rm ;If so we are done.
- inx h
- mov a,m ;Get the EOL char.
- sbi ' '
- sta seol
- lda temp4
- cpi 6 ;Fewer than six pieces?
- rm ;If so we are done.
- inx h
- mov a,m ;Get the quote char.
- sta squote
- lda temp4 ;Get the amount of data supplied
- cpi 7 ;Have an 8-bit quote?
- rm ;If not there, all done
- inx h ;Yes, get the character
- mvi a,0 ;[jd]
- sta quot8 ;[jd] assume not quoting
- mov a,m ;Get the supplied character
- cpi 'N' ;[jd] No?
- jz spar1 ;[jd] then don't try to do it
- cpi ' ' ;[jd] maybe they don't know about it...
- jz spar1 ;[jd] then don't try to do it.
- cpi 'Y' ;[jd] Yes?
- jnz spar2 ;[jd] if not 'Y', assume it's a quote char.
- lda parity ;[jd] using parity?
- cpi parnon ;[jd] no, don't need quoting...
- jz spar1 ;[jd]
- mvi a,0ffh ;[jd] else turn on...
- sta quot8 ;[jd] ...quote flag
- jmp spar1
-
- spar2: sta qbchr ;[jd] use their quote char (should validate)
- mvi a,0ffh
- sta quot8 ;[jd] turn quote flag and fall thru...
-
- spar1: lda temp4 ;Determine if block check type given
- cpi 8 ;Is the field there?
- rm ;If not, all done
- inx h ;Point to the character
- mov a,m ;Get the value
- mov b,a ;Copy value
- lda chktyp ;Get our type
- cmp b ;Is it our desired type?
- rnz ; If not, use default (1-character-checksum)
- sta inichk ; Match, store as type to use after init
- ret ; and return
- ;
-
- ; Copy characters from packet to disk
- ; called by: rdata
-
- ptchr: sta temp1 ;Save the size.
- lxi h,data ;Beginning of received packet data.
- shld outpnt ;Remember where we are.
- lda rquote
- mov b,a ;Keep the quote char in b.
- mvi c,0 ;[jd] assume no 8-bit quote char
- lda quot8 ;[jd] doing 8-bit quoting?
- ora a
- jz ptchr1 ;[jd] no, keep going
- lda qbchr ;[jd] else get 8-bit quote char
- mov c,a ;[jd] keep this in c
- ptchr1: lxi h,temp1
- dcr m ;Decrement # of chars in packet.
- jm rskp ;Return successfully if done.
- lxi h,chrcnt ;Number of chars remaining in dma.
- dcr m ;Decrement.
- jp ptchr2 ;Continue if space left.
- call outbuf ;Output it if full.
- jmp ptchr9 ; Error return if disk is full.
- ptchr2: lhld outpnt ;Get position in output buffer.
- mov a,m ;Grab a char.
- inx h
- shld outpnt ;and bump pointer.
- mvi e,0 ;[jd] assume nothing to OR in.
- cmp c ;[jd] is it the binary quote char?
- jnz ptch2a ;[jd] no, keep going
- mvi e,80h ;[jd] include parity bit
- lda temp1
- dcr a
- sta temp1 ;[jd] decrement character count
- mov a,m ;[jd] get next character
- inx h
- shld outpnt
- ptch2a: cmp b ;Is it the quote char?
- jnz ptchr3 ;[jd] changed to ptchr3 so includes parity
- mov a,m ;Get the quoted character
- inx h
- shld outpnt ;and bump pointer.
- lxi h,temp1
- dcr m ;Decrement # of chars in packet.
- mov d,a ;Save the char.
- ani 80H ;Turn off all but the parity bit.
- ora e ;[jd] let parity come from either (???)
- mov e,a ;Save the parity bit.
- mov a,d ;Get the char.
- ani 7FH ;Turn off the parity bit.
- cmp b ;Is it the quote char?
- jz ptchr3 ;If so just go write it out.
- cmp c ;[jd] maybe it's the 8-bit prefix character?
- jz ptchr3 ;[jd] then don't controllify.
- mov a,d ;Get the char.
- adi 40H ;Make the character a control char again.
- ani 7FH ;Modulo 128.
- ptchr3: ora e ;Or in the parity bit.
- lhld bufpnt ;Destination buffer.
- mov m,a ;Store it.
- inx h
- shld bufpnt ;Update the pointer
- jmp ptchr1 ;and loop to next char.
-
- ptchr9: lxi d,erms11 ; "?Disk full"
- call error3 ; put it on the error line
- ret ; take error return.
- ;
- ; Fill a data packet from file
- ; called by: sfile, sdata
-
- gtchr: lda squote ;Get the quote char.
- mov c,a ;Keep quote char in c.
- lda curchk ;Get current block check type
- sui '1' ;Get the extra overhead
- mov b,a ;Get a copy
- lda spsiz ;Get the maximum packet size.
- sui 5 ;Subtract the overhead.
- sub b ;Determine max packet length
- sta temp1 ;This is the number of chars we are to get.
- lxi h,filbuf ;Where to put the data.
- shld cbfptr ;Remember where we are.
- mvi b,0 ;No chars.
- gtchr1: lda temp1
- dcr a ;Decrement the number of chars left.
- jp gtchr2 ;Go on if there is more than one left.
- mov a,b ;Return the count in A.
- jmp rskp
-
- gtchr2: sta temp1
- lda chrcnt ;Space left in the DMA.
- dcr a
- ;* Can improve order here.
- jm gtchr3
- sta chrcnt
- jmp gtchr4
-
- gtchr3: call inbuf ;Get another buffer full.
- jmp gtch30 ; If no more return what we got.
- jmp gtchr4 ;If we got some, proceed.
-
- gtch30: mov a,b ;Return the count in A.
- ora a ;Get any chars?
- jnz rskp ;If so return them.
- jmp gtceof ;If not, say we found the end of the file.
-
- gtchr4: lhld bufpnt ;Position in DMA.
- mov a,m ;Get a char from the file.
- inx h
- shld bufpnt
- mov d,a ;Save the char.
- ani 80H ;Turn off all but parity.
- mov e,a ;Save the parity bit.
- jz gtch4a ;[jd] no parity, skip this check...
- lda quot8 ;[jd] doing eighth-bit quoting?
- ora a
- jz gtch4a ;[jd] no, just proceed normally
- lda temp1 ;[jd] get space remaining
- cpi 2 ;[jd] 3 chrs left (one cnted already)?
- jm gtchr9 ;[jd] no, skip this
- dcr a ;[jd] decrement space remaining
- sta temp1 ;[jd] put back.
- lhld cbfptr ;[jd] Position in character buffer.
- lda qbchr ;[jd] get quote character
- mov m,a ;]jd] Put the quote char in the buffer.
- inx h ;[jd] increment destination buffer pointer
- shld cbfptr ;[jd] store the pointer back
- inr b ;[jd] Increment the char count.
- mvi e,0 ;[jd] no parity bit to OR in.
- ;[jd] fall thru...
-
- gtch4a: mov a,d ;Restore the char.
- ani 7FH ;Turn off the parity.
- mov d,a ;[jd] save here for later...
- cpi ' ' ;Compare to a space.
- jm gtchr5 ;If less then its a control char, handle it.
- cpi del ;Is the char a delete?
- jz gtchr5 ;Go quote it.
- lda quot8 ; Are we doing 8th-bit quoting?
- ora a
- jz gtch4c ; if not, skip this test and restore character.
- lda qbchr ; get 8th-bit quote character
- cmp d ; same as current character?
- jz gtch4b ; yes, have to quote it...
- gtch4c: mov a,d ; no. get character back again.
- cmp c ;Is it the quote char?
- jnz gtchr8 ;If not proceed.
- gtch4b: lxi h,temp1 ;[jd] point to char count
- dcr m ;[jd] decrement (know room for at least one)
- lhld cbfptr ;Position in character buffer.
- mov m,c ;Put the (quote) char in the buffer.
- inx h
- shld cbfptr
- inr b ;Increment the char count.
- mov a,d ;[jd] restore character again
- jmp gtchr8
-
- gtchr5: ora e ;Turn on the parity bit.
- cpi ('Z'-100O) ;Is it a ^Z?
- jnz gtchr7 ;If not just proceed.
- lda cpmflg ;Was the file created by CPM...
- cpi 1 ;in ASCII-mode ?
- jz gtch52 ;Control-Z stops text
- cpi 2 ;in BINARY mode?
- jz gtchr6 ;Yes, pass the ^Z
- ;At this point file-mode is DEFAULT.
- ;If the rest of the record is filled with ^Zs, we're at EOF, otherwise
- ;its a regular character.
- lhld bufpnt ;since CHRCNT is ZERO at EOF-time
- lda chrcnt ;(set by INBUF5 B.G.E)
- mov d,a ;Get the number of chars left in the DMA.
- gtch51: dcr d
- mov a,d
- jp gtch53 ;Any chars left?
- gtch52: xra a ;If not, get a zero.
- sta chrcnt ;Say no more chars in buffer.
- mov a,b ;Return the count in A.
- jmp rskp
-
- ;Scan rest of buffer for non ^Z -- If we find a non ^Z, fall into gtchr6.
- ;If we get to the end of the buffer before finding a non ^Z, fall into gtch52.
- gtch53: mov a,m ;Get the next char.
- inx h ;Move the pointer.
- cpi ('Z'-100O) ;Is it a ^Z?
- jz gtch51 ;If so see if the rest are.
-
- gtchr6: mvi a,('Z'-100O) ;Restore the ^Z.
- gtchr7: sta temp2 ;Save the char.
- lxi h,temp1 ;Point to the char total remaining.
- dcr m ;Decrement it.
- lhld cbfptr ;Position in character buffer.
- mov m,c ;Put the quote in the buffer.
- inx h
- shld cbfptr
- inr b ;Increment the char count.
- lda temp2 ;Get the control char back.
- adi 40H ;Make the non-control.
- ani 7fH ;Modulo 200 octal.
- gtchr8: lhld cbfptr ;Position in character buffer.
- ora e ;Or in the parity bit.
- mov m,a ;Put the char in the buffer.
- inx h
- shld cbfptr
- inr b ;Increment the char count.
- jmp gtchr1 ;Go around again.
-
- gtchr9: ;[jd] not enough room left in buffer...
- lhld bufpnt
- dcx h
- shld bufpnt ;[jd] back up over last character
- lxi h,chrcnt ;[jd] point to character count
- inr m ;[jd] increment it
- mov a,b ;[jd] count of chars transferred
- jmp rskp ;[jd] return it
-
- gtceof: mvi a,0FFH ;Get a minus one.
- ret
- ;
- ; Get the file name (including host to micro translation)
- ; called by: rfile
-
- gofil: lxi h,data ;Get the address of the file name.
- shld datptr ;Store the address.
- lxi h,fcb+1 ;Address of the FCB.
- shld fcbptr ;Save it.
- xra a
- sta temp1 ;Initialize the char count.
- sta temp2
- sta fcb ;Set the drive to default to current.
- mvi b,' '
- gofil1: mov m,b ;Blank the FCB.
- inx h
- inr a
- cpi 0CH ;Twelve?
- jm gofil1
- gofil2: lhld datptr ;Get the NAME field.
- mov a,m
- cpi 'a' ;Force upper case
- jm gofl2a ;
- ani 5FH ;
- gofl2a: inx h
- cpi '.' ;Seperator?
- jnz gofil3
- shld datptr ;[jd] update ptr (moved from above)
- lxi h,fcb+9H
- shld fcbptr
- lda temp1
- sta temp2
- mvi a,9H
- sta temp1
- jmp gofil6
-
- gofil3: ora a ;Trailing null?
- jz gofil7 ;Then we're done.
- shld datptr ;[jd] no, can update ptr now.
- lhld fcbptr
- mov m,a
- inx h
- shld fcbptr
- lda temp1 ;Get the char count.
- inr a
- sta temp1
- cpi 8H ;Are we finished with this field?
- jm gofil2
- gofil4: sta temp2
- lhld datptr
- mov a,m
- inx h
- shld datptr
- ora a
- jz gofil7
- cpi '.' ;Is this the terminator?
- jnz gofil4 ;Go until we find it.
- gofil6: lhld datptr ;Get the TYPE field.
- mov a,m
- cpi 'a' ;Force upper case
- jm gofl6a ;
- ani 5FH ;
- gofl6a: ora a ;Trailing null?
- jz gofil7 ;Then we're done.
- ;[jd] move above two lines so we don't increment pointer if char is null
- inx h
- shld datptr
- lhld fcbptr
- mov m,a
- inx h
- shld fcbptr
- lda temp1 ;Get the char count.
- inr a
- sta temp1
- cpi 0CH ;Are we finished with this field?
- jm gofil6
- gofil7: lhld datptr
- mvi m,'$' ;Put in a dollar sign for printing.
- call scrfln ;Position cursor
- lxi d,data ;Print the file name
- call prtstr
- lda flwflg ;Is file warning on?
- ora a
- jz gofil9 ;If not, just proceed.
- mvi c,openf ;See if the file exists.
- lxi d,fcb
- call bdos
- cpi 0FFH ;Does it exist?
- jz gofil9 ;If not create it.
- lxi d,infms5
- call error3
- lda temp2 ;Get the number of chars in the file name.
- ora a
- jnz gofil8
- lda temp1
- sta temp2
- gofil8: mvi b,0
- mov d,b ;Zero d for dad index into filename
- inr a ;Replace next character after filename
- cpi 9H ;Is the first field full?
- jnz gofl80
- mvi b,0FFH ;Set a flag saying so.
- dcr a
- gofl80: mov e,a ;Keep current, replace index in d,e.
- gofl81: lxi h,fcb ;Get the FCB.
- dad d ;Add in the character number.
- mvi m,'&' ;Replace the char with an ampersand.
- push b
- push d
- lxi h,fcb ;Trim off any CP/M 2.2 attribute bits
- mvi c,1+8+3 ;so they do not affect the new file
- gofl82: mov a,m ;
- ani 7FH ;
- mov m,a ;
- inx h ;
- dcr c ;
- jnz gofl82 ;
- mvi c,openf ;See if the file exists.
- lxi d,fcb
- call bdos
- pop d
- pop b
- cpi 0FFH ;Does it exist?
- jz gofl89 ;If not create it.
- mov a,b ;Get the field-full flag.
- ora a ;Incr. or decr. ?
- jz gofl83 ;Jump if increment
- dcr e ;Decrement the number of chars.
- mov a,e
- ora a
- jz gofl88 ;If no more, die.
- jmp gofl81
-
- gofl83: inr e ;Increment the number of chars.
- mov a,e
- cpi 9H ;Are we to the end?
- jm gofl81 ;If not try again.
- lda temp2 ;Get the original size.
- mov e,a
- mvi b,0FFH ;Set flag saying field-full, decrement
- jmp gofl81
-
- gofl88: lxi d,erms16 ;Tell user that we can't rename it.
- call prtstr
- ret
-
- gofl89: mvi c,8 ;[jd] # of chars in name
- lxi d,fnbuf ;[jd] point to destination
- lxi h,fcb+1 ;[jd] source of name
- mvi b,0 ;[jd] first-time-thru flag
- gof89a: mov a,m ;[jd] get a char from the name
- inx h ;[jd] pass it
- cpi ' ' ;[jd] end of this part of name?
- jz gof89b ;[jd] yes, skip rest...
- stax d ;[jd] else drop char off
- inx d ;[jd] increment dest ptr
- dcr c ;[jd] decrement count
- jnz gof89a ;[jd] and continue if more to go
- gof89b: mov a,b ;[jd]
- ora a ;[jd] first time thru?
- jnz gof89c ;[jd] no, no period
- mvi a,'.' ;[jd] period between parts
- stax d ;[jd]
- inx d ;[jd]
- mvi b,0ffh ;[jd] not first time thru anymore
- mvi c,3 ;[jd] length of this part
- lxi h,fcb+9 ;[jd] start of extension
- jmp gof89a ;[jd] keep copying
-
- gof89c: mvi a,'$'
- stax d ;[jd] end the name string
- lxi d,fnbuf ;[jd] Print the file name
- call prtstr
- gofil9: call makfil ; Create the file.
- jmp gofl91 ; Disk was full.
- jmp rskp ; Success.
-
- gofl91: lxi d,erms11
- call error3
- ret
- ;
- ; This is the FINISH command. It tells the remote KERSRV to exit.
- ; here from kermit
-
- finish: call cfmcmd
- xra a
- sta numtry ;Inititialize count.
- mvi a,'1' ;Reset block check type to single character
- sta curchk ; . . .
-
- finsh1: lda numtry ;How many times have we tried?
- cpi maxtry ;Too many times?
- jm finsh3 ;No, try it.
- finsh2: lxi d,erms18 ;Say we couldn't do it.
- call prtstr
- jmp kermit ;Go home.
-
- finsh3: inr a ;Increment the number of tries.
- sta numtry
- xra a
- sta argblk ;Make it packet number zero.
- mvi a,1
- sta argblk+1 ;One piece of data.
- lxi h,data
- mvi m,'F' ;Finish running Kermit.
- mvi a,'G' ;Generic command packet.
- call spack
- jmp finsh2 ; Tell the user and die.
- call rpack ;Get an acknowledgement.
- jmp finsh1 ; Go try again.
- cpi 'Y' ;ACK?
- jz kermit ;Yes, we are done.
- cpi 'E' ;Is it an error packet?
- jnz finsh1 ;Try sending the packet again.
- call error1 ;Print the error message.
- jmp kermit
- ;
- ; This is the LOGOUT command. It tells the remote KERSRV to logout.
- ; here from: kermit
-
- logout: call cfmcmd
- call logo ;Send the logout packet.
- jmp kermit ;Go get another command
- jmp kermit ; whether we succeed or not.
-
- ; do logout processing.
- ; called by: bye, logout
-
- logo: xra a
- sta numtry ;Inititialize count.
- mvi a,'1' ;Reset block check type to single character
- sta curchk ; . . .
-
- logo1: lda numtry ;How many times have we tried?
- cpi maxtry ;Too many times?
- jm logo3 ;No, try it.
- logo2: lxi d,erms19 ;Say we couldn't do it.
- call prtstr
- ret ;Finished.
-
- logo3: inr a ;Increment the number of tries.
- sta numtry
- xra a
- sta argblk ;Make it packet number zero.
- mvi a,1
- sta argblk+1 ;One piece of data.
- lxi h,data
- mvi m,'L' ;Logout the remote host.
- mvi a,'G' ;Generic command packet.
- call spack
- jmp logo2 ; Tell the user and die.
- call rpack ;Get an acknowledgement
- jmp logo1 ; Go try again.
- cpi 'Y' ;ACK?
- jz rskp ;Yes, we are done.
- cpi 'E' ;Is it an error packet?
- jnz logo1 ;Try sending the packet again.
- call error1 ;Print the error message.
- ret ;All done.
- ;
- ; Packet routines
-
- ; Send_Packet
- ; This routine assembles a packet from the arguments given and sends it
- ; to the host.
- ;
- ; Expects the following:
- ; A - Type of packet (D,Y,N,S,R,E,F,Z,T)
- ; ARGBLK - Packet sequence number
- ; ARGBLK+1 - Number of data characters
- ; Returns: nonskip if failure
- ; skip if success
- ; called by: read, rinit, rfile, rdata, sinit, sfile, sdata, seof, seot,
- ; finish, logout, nak, ackp
-
- spack: sta argblk+2
- lxi h,packet ;Get address of the send packet.
- mvi a,soh ;Get the start of header char.
- mov m,a ;Put in the packet.
- inx h ;Point to next char.
- lda curchk ;Get current checksum type
- sui '1' ;Determine extra length of checksum
- mov b,a ;Copy length
- lda argblk+1 ;Get the number of data chars.
- adi ' '+3 ;Real packet character count made printable.
- add b ;Determine overall length
- mov m,a ;Put in the packet.
- inx h ;Point to next char.
- lxi b,0 ;Zero the checksum AC.
- mov c,a ;Start the checksum.
- lda argblk ;Get the packet number.
- adi ' ' ;Add a space so the number is printable.
- mov m,a ;Put in the packet.
- inx h ;Point to next char.
- add c
- mov c,a ;Add the packet number to the checksum.
- mvi a,0 ;Clear A (Cannot be XRA A, since we can't
- ; touch carry flag)
- adc b ;Get high order portion of checksum
- mov b,a ;Copy back to B
- lda argblk+2 ;Get the packet type.
- mov m,a ;Put in the packet.
- inx h ;Point to next char.
- add c
- mov c,a ;Add the packet number to the checksum.
- mvi a,0 ;Clear A
- adc b ;Get high order portion of checksum
- mov b,a ;Copy back to B
- spack2: lda argblk+1 ;Get the packet size.
- ora a ;Are there any chars of data?
- jz spack3 ; No, finish up.
- dcr a ;Decrement the char count.
- sta argblk+1 ;Put it back.
- mov a,m ;Get the next char.
- inx h ;Point to next char.
- add c
- mov c,a ;Add the packet number to the checksum.
- mvi a,0 ;Clear A
- adc b ;Get high order portion of checksum
- mov b,a ;Copy back to B
- jmp spack2 ;Go try again.
-
- spack3: lda curchk ;Get the current checksum type
- cpi '2' ;Two character?
- jz spack4 ;Yes, go handle it
- jnc spack5 ;No, go handle CRC if '3'
- mov a,c ;Get the character total.
- ani 0C0H ;Turn off all but the two high order bits.
- ;Shift them into the low order position.
- rlc ;Two left rotates same as 6 rights
- rlc ; . . .
- add c ;Add it to the old bits.
- ani 3FH ;Turn off the two high order bits. (MOD 64)
- adi ' ' ;Add a space so the number is printable.
- mov m,a ;Put in the packet.
- inx h ;Point to next char.
- jmp spack7 ;Go store eol character
-
- ;Here for 3 character CRC-CCITT
-
- spack5: mvi m,0 ;Store a null for current end
- push h ;Save H
- lxi h,packet+1 ;Point to first checksumed character
- call crcclc ;Calculate the CRC
- pop h ;Restore the pointer
- mov c,e ;Get low order half for later
- mov b,d ;Copy the high order
- mov a,d ;Get the high order portion
- rlc ;Shift off low 4 bits
- rlc ; . . .
- rlc ; . . .
- rlc ; . . .
- ani 0FH ;Keep only low 4 bits
- adi ' ' ;Put into printing range
- mov m,a ;Store the character
- inx h ;Point to next position
-
- ;Here for two character checksum
-
- spack4: mov a,b ;Get high order portion
- ani 0FH ;Only keep last four bits
- rlc ;Shift up two bits
- rlc ; . . .
- mov b,a ;Copy back into safe place
- mov a,c ;Get low order half
- rlc ;Shift high two bits
- rlc ;to low two bits
- ani 03H ;Keep only two low bits
- ora b ;Get high order portion in
- adi ' ' ;Convert to printing character range
- mov m,a ;Store the character
- inx h ;Point to next character
- mov a,c ;get low order portion
- ani 3FH ;Keep only six bits
- adi ' ' ;Convert to printing range
- mov m,a ;Store it
- inx h ;Bump the pointer
-
- spack7: lda dbgflg
- ora a ; is debugging enabled?
- jz spack8
- push h ; yes. save address of end of packet
- mvi m,0 ; null-terminate the packet for display
- call sppos ; position cursor
- lxi h,packet+1 ; print the packet
- call dmptxt
- pop h ; restore address of end of packet
- spack8: lda seol ;Get the EOL the other host wants.
- mov m,a ;Put in the packet.
- inx h ;Point to next char.
- xra a ;Get a null.
- mov m,a ;Put in the packet.
- ; Write out the packet.
- outpkt: call selmdm ; Set up for output to comm port if iobyt
- lda spad ;Get the number of padding chars.
- sta temp1
- outpk2: lda temp1 ;Get the count.
- dcr a
- ora a
- jm outpk6 ;If none left proceed.
- sta temp1
- lda spadch ;Get the padding char.
- call setpar ;Set parity appropriately
- mov e,a ;Put the char in right AC.
- call outmdm ;Output it.
- jmp outpk2
-
- outpk6: lxi h,packet ; Point to the packet.
- outlup: mov a,m ; Get the next character.
- ora a ; Is it a null?
- jz outlud ; If so return success.
- call setpar ; Set parity for the character
- mov e,a ; Put it in right AC
- call outmdm ; and output it.
- ; TAC trap: If this character is the TAC intercept character, and the TAC
- ; trap is enabled, we have to output it twice. If the TAC trap is enabled,
- ; tacflg contains the intercept character. (The current character cannot
- ; be NUL, so we don't have to worry about doubling nulls in the message)
- lda tacflg ; get current intercept character, or zero.
- cmp m ; compare against current data character.
- jnz outpk8 ; if different, do nothing.
- call setpar ; match. set appropriate parity,
- mov e,a ; put it in the right register,
- call outmdm ; and output it a second time.
- outpk8:
- inx h ; Increment the char pointer.
- jmp outlup
-
- outlud: call selcon ; select console
- jmp rskp ; and return success
- ;
- ; Receive_Packet
- ; This routine waits for a packet to arrive from the host. It reads
- ; characters until it finds a SOH. It then reads the packet into packet.
- ;
- ; Returns: nonskip if failure (checksum wrong or packet trashed)
- ; skip if success, with
- ; A - message type
- ; ARGBLK - message number
- ; ARGBLK+1 - length of data
- ; called by: rinit, rfile, rdata,
- ; sinit, sfile, sdata, seof, seot, finish, logout
-
- rpack: call inpkt ;Read up to the end-of-line character
- jmp r ; Return bad.
- rpack0: call getchr ;Get a character.
- jmp rpack ; Hit eol;null line;just start over.
- cpi soh ;Is the char the start of header char?
- jnz rpack0 ; No, go until it is.
- rpack1: call getchr ;Get a character.
- jmp r ; Hit end of line, return bad.
- cpi soh ;Is the char the start of header char?
- jz rpack1 ; Yes, then go start over.
- sta packet+1 ;Store in packet also
- mov c,a ;Start the checksum.
- lda curchk ;Get block check type
- sui '1' ;Determine extra length of block check
- mov b,a ;Get a copy
- mov a,c ;Get back length character
- sui ' '+3 ;Get the real data count.
- sub b ;Get total length
- sta argblk+1
- mvi b,0 ;Clear high order half of checksum
- call getchr ;Get a character.
- jmp r ; Hit end of line, return bad.
- cpi soh ;Is the char the start of header char?
- jz rpack1 ; Yes, then go start over.
- sta argblk
- sta packet+2 ;Save also in packet
- add c
- mov c,a ;Add the character to the checksum.
- mvi a,0 ;Clear A
- adc b ;Get high order portion of checksum
- mov b,a ;Copy back to B
- lda argblk
- sui ' ' ;Get the real packet number.
- sta argblk
- call getchr ;Get a character.
- jmp r ; Hit end of line, return bad.
- cpi soh ;Is the char the start of header char?
- jz rpack1 ; Yes, then go start over.
- sta temp1 ;Save the message type.
- sta packet+3 ;Save in packet
- add c
- mov c,a ;Add the character to the checksum.
- mvi a,0 ;Clear A
- adc b ;Get high order portion of checksum
- mov b,a ;Copy back to B
- lda argblk+1 ;Get the number of data characters.
- sta temp2
- lxi h,data ;Point to the data buffer.
- shld datptr
- rpack2: lda temp2
- sui 1 ;Any data characters?
- jm rpack3 ; If not go get the checksum.
- sta temp2
- call getchr ;Get a character.
- jmp r ; Hit end of line, return bad.
- cpi soh ;Is the char the start of header char?
- jz rpack1 ; Yes, then go start over.
- lhld datptr
- mov m,a ;Put the char into the packet.
- inx h ;Point to the next character.
- shld datptr
- add c
- mov c,a ;Add the character to the checksum.
- mvi a,0 ;Clear A
- adc b ;Get high order portion of checksum
- mov b,a ;Copy back to B
- jmp rpack2 ;Go get another.
-
- rpack3: call getchr ;Get a character.
- jmp r ; Hit end of line, return bad.
- cpi soh ;Is the char the start of header char?
- jz rpack1 ; Yes, then go start over.
- sui ' ' ;Turn the char back into a number.
- sta temp3
- ;Determine type of checksum
-
- lda curchk ;Get the current checksum type
- cpi '2' ;1, 2 or 3 character?
- jz rpack4 ;If zero, 2 character
- jnc rpack5 ;Go handle 3 character
- mov a,c ;Get the character total.
- ani 0C0H ;Turn off all but the two high order bits.
- ;Shift them into the low order position.
- rlc ;Two left rotates same as six rights
- rlc ; . . .
- add c ;Add it to the old bits.
- ani 3FH ;Turn off the two high order bits. (MOD 64)
- mov b,a
- lda temp3 ;Get the real received checksum.
- cmp b ;Are they equal?
- jz rpack7 ;If so, proceed.
- rpack9: call updrtr ;If not, update the number of retries.
- ret ;Return error.
-
- ;Here for three character CRC-CCITT
-
- rpack5: lhld datptr ;Get the address of the data
- mvi m,0 ;Store a zero in the buffer to terminate packet
- lxi h,packet+1 ;Point at start of checksummed region
- call crcclc ;Calculate the CRC
- mov c,e ;Save low order half for later
- mov b,d ;Also copy high order
- mov a,d ;Get high byte
- rlc ;Want high four bits
- rlc ; . . .
- rlc ;And shift two more
- rlc ; . . .
- ani 0FH ;Keep only 4 bits
- mov d,a ;Back into D
- lda temp3 ;Get first value back
- cmp d ;Correct?
- jnz rpack9 ;No, punt
- call getchr ;Get a character.
- jmp r ; Hit end of line, return bad.
- cpi soh ;Is the char the start of header char?
- jz rpack1 ; Yes, then go start over.
- sui ' ' ;Remove space offset
- sta temp3 ;Store for later check
- ;...
-
- ;Here for a two character checksum and last two characters of CRC
-
- rpack4: mov a,b ;Get high order portion
- ani 0FH ;Only four bits
- rlc ;Shift up two bits
- rlc ; . . .
- mov b,a ;Save back in B
- mov a,c ;Get low order
- rlc ;move two high bits to low bits
- rlc ; . . .
- ani 03H ;Save only low two bits
- ora b ;Get other 4 bits
- mov b,a ;Save back in B
- lda temp3 ;Get this portion of checksum
- cmp b ;Check first half
- jnz rpack9 ;If bad, go give up
- call getchr ;Get a character.
- jmp r ; Hit end of line, return bad.
- cpi soh ;Is the char the start of header char?
- jz rpack1 ; Yes, then go start over.
- sui ' ' ;Remove space offset
- mov b,a ;Save in safe place
- mov a,c ;Get low 8 bits of checksum
- ani 3FH ;Keep only 6 bits
- cmp b ;Correct value
- jnz rpack9 ;Bad, give up
- rpack7: lhld datptr
- mvi m,0 ;Put a null at the end of the data.
- lda temp1 ;Get the type.
- jmp rskp
- ;
- ; inpkt - receive and buffer packet
- ; returns: nonskip if error (timeout)
- ; skip if success; packet starts at recpkt (which holds the SOH)
- ; and is terminated by a null.
- ; console is selected in either case.
- ; called by: rpack
-
- inpkt: lxi h,recpkt ;Point to the beginning of the packet.
- shld pktptr
- inpkt1: call inchr ;Get first character
- jmp r ;Return failure
- cpi soh ;is it the beginning of a packet?
- jnz inpkt1 ;if not, ignore leading junk
- jmp inpkt3 ;else go put it in packet
-
- inpkt2: call inchr ;Get a character.
- jmp r ; Return failure.
- cpi soh ;is it a new beginning of packet?
- jnz inpkt3 ;if not continue
- lxi h,recpkt ;else throw away what we've got so far
- shld pktptr ;
- inpkt3: lhld pktptr ;
- mov m,a ;Put the char in the packet.
- inx h
- shld pktptr
- mov b,a
- lxi d,-recpkx ;Start over if packet buffer overflow
- dad d ;
- jc inpkt ;
- lda reol ;Get the EOL char.
- cmp b
- jnz inpkt2 ;If not loop for another.
- ;...
-
- ;Begin IBM change/fdc
- ;This moved from OUTPK7 -- it appears that waiting until we're
- ;ready to send a packet before looking for turnaround character
- ;is long enough for it to get lost. Better to look now.
-
- lda ibmflg ;Is this the IBM?
- ora a
- jz inpkt6 ;If not then proceed.
- lda state ;Check if this is the Send-Init packet.
- cpi 'S'
- jz inpkt6 ;If so don't wait for the XON.
- inpkt5: call inchr ;Wait for the turn around char.
- jmp inpkt6
- cpi xon ;Is it the IBM turn around character?
- jnz inpkt5 ;If not, go until it is.
- inpkt6: lhld pktptr ;Reload packet pointer
- ;End IBM change/fdc.
- dcx h ;Back up to end of line character
- mvi m,0 ;Replace it with a null to stop rpack:
- call selcon ;We've got the packet. Return to console.
-
- lda dbgflg ; Is debugging enabled?
- ora a
- jz inpkt7
- inx h ; Point to next char.
- call rppos ; position cursor
- lxi h,recpkt+1 ; print the packet
- call dmptxt
- inpkt7: lxi h,recpkt
- shld pktptr ;Save the packet pointer.
- jmp rskp ;If so we are done.
-
- ; getchr - get next character from buffered packet.
- ; returns nonskip at end of packet.
- ; called by: rpack
-
- getchr: lhld pktptr ;Get the packet pointer.
- mov a,m ;Get the char.
- inx h
- shld pktptr
- ora a ;Is it the null we put at the end of the packet?
- jnz rskp ;If not return retskp.
- ret ;If so return failure.
- ;
- ;
- ; inchr - character input loop for file transfer
- ; returns: nonskip if timeout or character typed on console
- ; (console selected)
- ; skip with character from modem in A (parity stripped
- ; if necessary; modem selected)
- ; preserves bc, de, hl in either case.
- ; called by: inpkt
-
- inchr: push h ; save hl and bc
- push b
- lhld timout ;Get initial value for timeout
- shld timval ;[jd]
- inchr0: call selmdm ;select modem
- call inpmdm ;Try to get a character from the modem
- ora a
- jz inchr2 ;if zero, nothing there.
- mov b,a
- lda parity ;Is the parity none?
- cpi parnon
- mov a,b
- jz inchr1 ;If so just return.
- ani 7FH ;Turn off the parity bit.
- inchr1: pop b ;restore registers
- pop h
- jmp rskp ;take skip return, character in A
-
- inchr2: call selcon ;select console
- call inpcon ; Try to get a character from the console
- ora a
- jz inchr6 ;If not go do timer thing
- cpi cr ;Is it a carriage return?
- jz inchr4 ;If so return
- cpi ('Z'-100O) ;Control-Z?
- jz inchr5 ;Yes, go flag it
- cpi ('C'-100O) ;Control-C?
- jz inchr7 ;re-enter, he wants to get out
- cpi ('X'-100O) ;Control-X?
- jnz inchr6 ;No, ignore it. do timer thing.
- inchr5: adi 100O ;Convert to printing range
- sta czseen ;Flag we saw a control-Z
- inchr4: pop b ; restore registers
- pop h
- ret ;And return
-
- inchr6: lda timflg ;[jd] pick up timer flag
- ora a ;[jd] are we allowed to use timer?
- jz inchr0 ;[jd] no, don't time out
- lhld timval ; decrement fuzzy time-out
- dcx h ;
- shld timval ;((timout-1) * loop time)
- mov a,h ;(Retry if not time-out)
- ora l ;
- jnz inchr0 ;
- call updrtr ;Count as retry (?)
- pop b ;restore registers
- pop h
- ret ;and return to do retry
-
- inchr7: call clrtop ;[hh] clear screen and home cursor
- jmp kermit ;[hh] then re-enter kermit
-
- ;
- ; CRCCLC - Routine to calculate a CRC-CCITT for a string.
- ;
- ; This routine will calculate a CRC using the CCITT polynomial for
- ; a string.
- ;
- ; call with: HL/ Address of null-terminated string
- ; 16-bit CRC value is returned in DE.
- ; Registers BC and HL are preserved.
- ;
- ; called by: spack, rpack
-
- crcclc: push h ;Save HL
- push b ;And BC
- lxi d,0 ;Initial CRC value is 0
-
- crccl0: mov a,m ;Get a character
- ora a ;Check if zero
- jz crccl1 ;If so, all done
- push h ;Save the pointer
- xra e ;Add in with previous value
- mov e,a ;Get a copy
- ani 0FH ;Get last 4 bits of combined value
- mov c,a ;Get into C
- mvi b,0 ;And make high order zero
- lxi h,crctb2 ;Point at low order table
- dad b ;Point to correct entry
- dad b ; . . .
- push h ;Save the address
- mov a,e ;Get combined value back again
- rrc ;Shift over to make index
- rrc ; . . .
- rrc ; . . .
- ani 1EH ;Keep only 4 bits
- mov c,a ;Set up to offset table
- lxi h,crctab ;Point at high order table
- dad b ;Correct entry
- mov a,m ;Get low order portion of entry
- xra d ;XOR with previous high order half
- inx h ;Point to high order byte
- mov d,m ;Get into D
- pop h ;Get back pointer to other table entry
- xra m ;Include with new high order half
- mov e,a ;Copy new low order portion
- inx h ;Point to other portion
- mov a,m ;Get the other portion of the table entry
- xra d ;Include with other high order portion
- mov d,a ;Move back into D
-
- pop h ;And H
- inx h ;Point to next character
- jmp crccl0 ;Go get next character
-
- crccl1: pop b ;Restore B
- pop h ;And HL
-
- ret ;And return, DE=CRC-CCITT
-
- CRCTAB: DW 00000H
- DW 01081H
- DW 02102H
- DW 03183H
- DW 04204H
- DW 05285H
- DW 06306H
- DW 07387H
- DW 08408H
- DW 09489H
- DW 0A50AH
- DW 0B58BH
- DW 0C60CH
- DW 0D68DH
- DW 0E70EH
- DW 0F78FH
-
- CRCTB2: DW 00000H
- DW 01189H
- DW 02312H
- DW 0329BH
- DW 04624H
- DW 057ADH
- DW 06536H
- DW 074BFH
- DW 08C48H
- DW 09DC1H
- DW 0AF5AH
- DW 0BED3H
- DW 0CA6CH
- DW 0DBE5H
- DW 0E97EH
- DW 0F8F7H
- ;
- ; This is where we go if we get an error during a protocol communication.
- ; error prints the error packet on line 6 or so, and aborts the
- ; transfer.
- ; called by: rinit, rfile, rdata, sinit, sfile, sdata, seof, seot
- ; error1 print CRLF followed by the error packet.
- ; called by: finish, logout
- ; error2 just prints the error packet.
- ; error3 positions cursor and prints error message specified in DE.
- ; called by: rinit, rfile, rdata, sinit, sfile, sdata, seof,
- ; seot, parwrn, gofil, outbuf
-
- error: call screrr ;Position the cursor.
- mvi a,'A' ;Set the state to abort.
- sta state
- jmp error2
-
- error1: lxi d,crlf ;Print a CRLF.
- call prtstr
- error2: lda argblk+1 ;Get the length of the data.
- mov c,a
- mvi b,0 ;Put it into BC
- lxi h,data ;Get the address of the data.
- dad b ;Get to the end of the string.
- mvi a,'$' ;Put a dollar sign at the end.
- mov m,a
- lxi d,data ;Print error message
- call prtstr
- ret
-
- error3: push d ;Save the pointer to the message.
- call screrr ;Position the cursor.
- pop d ;Get the pointer back.
- call prtstr ;Print error message
- ret
- ;
- ; Set up for file transfer.
- ; called by read, send.
-
- init: lxi d,version ; point at Kermit's version string
- call sysscr ; fix up screen
- call selmdm ; select modem
- call flsmdm ; purge any pending data
- call selcon ; select console again.
- ret
-
- ; Set state to ABORT
- ; called by: rinit, rfile, rdata, sinit, sfile, sdata, seof, seot,
- ; nak, ackp
-
- abort: mvi a,'A' ;Otherwise abort.
- sta state
- ret
-
- ; nak - send NAK packet
- ; here from: rinit, rfile, rdata
- ; nak0 - update retry count and send NAK packet
- ; here from: rinit, rfile, rdata, tryagn
-
- nak0: call updrtr ;Update number of retries.
- nak: lda pktnum ;Get the packet number we're waiting for.
- sta argblk
- xra a ;No data.
- sta argblk+1
- mvi a,'N' ;NAK that packet.
- call spack
- jmp abort ; Give up.
- ret ;Go around again.
-
- ; increment and display retry count
- ; called by: rfile, sinit, sfile, sdata, seof, seot,
- ; nak, rpack, inchr, tryagn
-
- updrtr: call scrnrt ;Position cursor
- lhld numrtr
- inx h ;Increment the number of retries
- shld numrtr
- call nout ;Write the number of retries.
- ret
-
- ; [jd] this routine prints parity warnings. All registers are
- ; saved except for a.
- ; called by: sdata
-
- parwrn: push b
- push d
- push h
- lxi d,inms25
- call error3
- pop h
- pop d
- pop b
- ret
- ;[jd] end of addition
-
- ; print message in status field. address of message is in DE.
- ; called by: read, send
-
- finmes: push d ;Save message.
- call scrst ;Position cursor
- pop d ;Print the termination message
- call prtstr
- call scrend ;Position cursor for prompt
- ret
-
- ; Compare expected packet number against received packet number.
- ; return with flags set (Z = packet number valid)
- ; called by: rfile, rdata, sinit, sfile, sdata, seof, seot
-
- compp: lda pktnum ;Get the packet Nr.
- mov b,a
- lda argblk
- cmp b
- ret
-
- ; Increment the packet number, modulo 64.
- ; called by: rinit, rfile, rdata, sinit, sfile, sdata, seof, seot
-
- countp: inr a ;Increment packet Nr.
- ani 3FH ;Turn off the two high order bits
- sta pktnum ;Save modulo 64 of number
- lhld numpkt
- inx h ;Increment Nr. of packets
- shld numpkt
- ret
-
- ; Send an ACK-packet
- ; called by: rfile, rdata, tryagn
-
- ackp: xra a
- sta numtry ;Reset number of retries
- sta argblk+1 ;No data. (The packet number is in argblk)
- mvi a,'Y' ;Acknowledge packet
- call spack ;Send packet
- jmp abort
- ret
-
- ; ?
- ; called with A/ current retry count
- ; called by: rfile, rdata
-
- tryagn: inr a ;Increment it.
- sta oldtry ;Save the updated number of tries.
- lda pktnum ;Get the present packet number.
- dcr a ;Decrement
- ani 3FH ; modulo 64
- mov b,a
- lda argblk ;Get the packet's number
- cmp b ;Is the packet's number one less than now?
- jnz nak0 ;No, NAK it and try again.
- call updrtr ;Update the number of retries.
- call ackp
- ret
-
- ; Output a null-terminated string to the console. We assume that the
- ; console has been selected. Called with HL = address of string.
- ; called by: spack, inpkt
-
- dmptxt: mov a,m ; get character from string
- ora a
- rz ; done if null
- push h ; save string address
- mov e,a ; move character to E for outcon
- call outcon ; output character to console
- pop h ; restore string address
- inx h ; point past printed character
- jmp dmptxt ; go output rest of string
- ;
- IF lasm
- LINK CP4TT
- ENDIF;lasm
-