home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
kermit.columbia.edu
/
kermit.columbia.edu.tar
/
kermit.columbia.edu
/
os968ka
/
k6optf.asm
< prev
next >
Wrap
Assembly Source File
|
1987-06-30
|
32KB
|
564 lines
nam Kermit68K
ttl Protocol subroutines module
* Kermit68K: source file K68PTF
*
* Author: Roberto Bagnara (Bagnara@Iboinfn.Bitnet),
* Bologna University, Physics Department, July 1987.
*
* All rights reserved to Bologna University, Italy.
*
* Permission is granted to any individual or institution
* to use, copy, or redistribute this software so long as
* it is not sold for profit, provided this copyright
* notice is retained.
*
* Modification History:
*
* Version Date Who Comments
*
* 1.0.00 870701 Roberto Bagnara First official release
use DefsFile
Edition equ 0
psect K68ProtoFuncs,0,0,Edition,0,0
******************************** NextFil ******************************ok
* *
* Try to get the next file name copying it to FilName. *
* *
* Entry conditions : none *
* *
* Exit conditions : D0.B completion code *
* A0.L destroyed *
* *
***********************************************************************
NextFil: TST.B CtlZSeen(A6) Interrupt flag setted ?
BNE.S NextFil2 Yes, return with bad completion code
NextFil1 LEA FilName(A6),A0 Points to file name target string
BSR GetNxtF Try to get the next file name
TST.B D0 Check the completion code
BEQ.S NextFil2 No files, return with bad cc
BSR ChkInpF Check if file is readable
TST.B D0 Ok ?
BEQ.S NextFil3 Yes, return this
MOVEQ #FlSkippd,D0 No, notify that we are skipping it
BSR Screen
BRA.S NextFil1 Try another
NextFil2 SF D0 Set a bad completion code
RTS
NextFil3 ST D0
RTS
******************************** SndPack ******************************ok
* *
* Send a packet. *
* *
* Entry conditions : D1.B packet type *
* D2.B packet number *
* D3.B packet length *
* *
* Exit conditions : D4.W destroyed *
* D5.L destroyed *
* A0.L destroyed *
* A1.L destroyed *
* *
***********************************************************************
SndPack: LEA SendBuf(A6),A1 Packet buffer start
MOVEQ #32,D5 Load register for quick addition
MOVE.B OStPckCh(A6),(A1)+ Packet marker
MOVE.B D3,D0 Packet length
ADDQ.B #2,D0 Add 2 + block_check_type to packet ...
ADD.B BlChkUs(A6),D0 length to obtain the character count
ADD.B D5,D0 and convert it into a printable character
MOVE.B D0,(A1)+ Send the character count
ADD.B D5,D2 Make the packet number printable
MOVE.B D2,(A1)+ Send the packet number
MOVE.B D1,(A1)+ Send the packet type
MOVE.B D1,SendType(A6) And save it for echos removal
LEA DataBuf(A6),A0 Pointer to data buffer
CLR.W D0 Clear the counter register
MOVE.B D3,D0 Data length
BRA.S SndPack2 Loop for all data characters
SndPack1 MOVE.B (A0)+,(A1)+ Get a character and put it in the packet
SndPack2 DBF D0,SndPack1 Repeat
CLR.B (A1) Mark end for block check
LEA SendBuf+1(A6),A0 First char for checksum computation
MOVE.B BlChkUs(A6),D0 Block check type in use
SUBQ.B #1,D0 Type 1 block check ?
BNE.S SndPack3 No, try another
BSR Check1 Yes, compute it
ADD.B D5,D0 Convert the checksum into printable
MOVE.B D0,(A1)+ Send it
BRA.S SndPack5 Join common part
SndPack3 SUBQ.B #1,D0 Type 2 block check ?
BNE.S SndPack4 No, type 3 block check
BSR Check2 Yes, compute it
MOVE.B D0,D4 Save the lower portion of the result
LSR.W #6,D0 Process bits 6 --> 11, right adjusting
ANDI.B #$3F,D0 Mask extra bits
ADD.B D5,D0 Conversion into a printable character
MOVE.B D0,(A1)+ Send the first character
MOVE.B D4,D0 Reload the copy
ANDI.B #$3F,D0 Now bits 0 --> 5
ADD.B D5,D0 Conversion into a printable character
MOVE.B D0,(A1)+ Send the second character
BRA.S SndPack5 Join common part
SndPack4 BSR Check3 Compute a type 3 block check
MOVE.W D0,D4 Make a copy of the result
LSR.W #8,D0 Process bits 12 --> 15, right adjusting
LSR.W #4,D0 Right adjusting
ADD.B D5,D0 Conversion into a printable character
MOVE.B D0,(A1)+ Send the first character
MOVE.W D4,D0 Reload the copy
LSR.W #6,D0 Now process bits 6 --> 11, right adjust
ANDI.B #$3F,D0 Mask extra bits
ADD.B D5,D0 Conversion into a printable character
MOVE.B D0,(A1)+ Send the second character
MOVE.B D4,D0 Reload the lower portion of the result
ANDI.B #$3F,D0 Now bits 0 --> 5
ADD.B D5,D0 Conversion into a printable character
MOVE.B D0,(A1)+ Send the third character
SndPack5 MOVE.B OEOL(A6),(A1)+ Extra-packet line terminator
CLR.B (A1) End-Of-Buffer marker
BSR TxPackt Transmit the packet now prepared
MOVEQ #PackType,D0 Display the packet type on the screen
BSR Screen
RTS
******************************** RdPack *******************************ok
* *
* Attempts to read a packet. *
* *
* Entry conditions : none *
* *
* Exit conditions : D1.B packet type or pseudo-type *
* D2.B packet number *
* D3.B packet length *
* D5.L destroyed *
* D6.L destroyed *
* A0.L destroyed *
* A1.L destroyed *
* A2.L destroyed *
* *
***********************************************************************
RdPack: MOVE.L D4,-(A7) Save working register
SUBQ.L #4,A7 Allocate some space on the stack
MOVEQ #3-1,D6 Try 3 times to get a line that has
RdPack1 BSR InpLine a start-of-packet char in it
TST.B D1 Check InpLine completion code
BEQ RdPack16 Failed, return a timeout pseudo-packet
* Ok, search the start-of-packet char
RdPack2 LEA RecBuf(A6),A0 Pointer to receive buffer
CLR.W D1 Clear the character counter
RdPack3 MOVE.B (A0)+,D2 Get a character
CMP.B IStPckCh(A6),D2 Start-of-packet char ?
BEQ.S RdPack4 Yes, first goal satisfied !
ADDQ.W #1,D1 Increment character counter
CMP.W D0,D1 Last character ?
BNE.S RdPack3 No, try the next
DBF D6,RdPack1 Repeat max 3 times
MOVEQ #'Q',D1 Failed, return a garbage pseudo-packet
BRA RdPack19
RdPack4 MOVEQ #32,D6 Load for quick addition/subtraction
RdPack5 MOVEA.L A0,A1 Remember where packet started
MOVE.B (A0)+,D0 Get character
BEQ RdPack15 EOL, garbled packet
CMP.B IStPckCh(A6),D0 Start-of-packet char ?
BEQ.S RdPack5 Yes, resynchronize
MOVE.B D0,D3 This is the packet length
SUB.B D6,D3 Convert it to numeric
MOVE.B (A0)+,D0 Get character
BEQ RdPack15 EOL, garbled packet
CMP.B IStPckCh(A6),D0 Start-of-packet char ?
BEQ.S RdPack5 Yes, resynchronize
MOVE.B D0,D2 This is the packet number
SUB.B D6,D2 Convert it to numeric
MOVE.B (A0)+,D0 Get character
BEQ RdPack15 EOL, garbled packet
CMP.B IStPckCh(A6),D0 Start-of-packet char ?
BEQ.S RdPack5 Yes, resynchronize
MOVE.B D0,D1 This is the packet type
* Heuristics for syncing block check type
MOVEQ #1,D5 Type 1 block check by default
CMPI.B #'S',D1 Send-Init packet ?
BEQ.S RdPack7 Yes, type 1 block check
CMPI.B #'I',D1 Initialize packet ?
BEQ.S RdPack7 Yes, type 1 block check
CMPI.B #'N',D1 NAK packet ?
BNE.S RdPack6 No
MOVE.B D3,D5 Yes, block check type is
SUBQ.B #2,D5 bct = packet_length - 2
BRA.S RdPack7
RdPack6 MOVE.B BlChkUs(A6),D5 Otherwise block check type in use
RdPack7 SUB.B D5,D3 Now compute data length by subtracting
SUBQ.B #2,D3 (block_check_type + 2)
LEA DataBuf(A6),A2 Pointer to data buffer
CLR.W D4 Clear the counter register
MOVE.B D3,D4 Data length
BRA.S RdPack9 Read data, if any
RdPack8 MOVE.B (A0)+,D0 Get character
BEQ RdPack15 EOL, garbled packet
CMP.B IStPckCh(A6),D0 Start-of-packet char ?
BEQ.S RdPack5 Yes, resynchronize
MOVE.B D0,(A2)+ Write character to data buffer
RdPack9 DBF D4,RdPack8
CLR.B (A2)+ Mark the end of buffer
MOVEA.L A7,A2 Point to temporary storage space
CLR.W D4 Clear the counter register
MOVE.B D5,D4 Block check type
BRA.S RdPack11 Get the block check
RdPack10 MOVE.B (A0),D0 Get character
BEQ RdPack15 EOL, garbled packet
CMP.B IStPckCh(A6),D0 Start-of-packet char ?
BEQ RdPack5 Yes, resynchronize
MOVE.B D0,(A2)+ Store the block check character
CLR.B (A0)+ Nullify checksum characters in RecBuf
RdPack11 DBF D4,RdPack10 Repeat
* Got packet, now check the block check
MOVEA.L A1,A0 Pointer to packet start
MOVEA.L A7,A1 Point to received block check characters
SUBQ.B #1,D5 Type 1 block check ?
BEQ.S RdPack13 Yes, compute it
SUBQ.B #1,D5 Type 2 block check ?
BEQ.S RdPack12 Yes, compute it
SUBQ.B #1,D5 Type 3 block check ?
BNE.S RdPack15 No, return garbage pseudo-packet
* Yes, compute it, (fall thru)
BSR Check3 Compute
MOVEQ #$3F,D4 Process bits 0 --> 5
AND.B D0,D4 Move and mask extra bits
ADD.B D6,D4 Conversion into a printable character
CMP.B 2(A1),D4 Ok, now compare, third byte
BNE RdPack15 Compare fails, garbled packet
LSR.W #6,D0 Now process bits 6 --> 11, right adjust
MOVEQ #$3F,D4 To mask extra bits
AND.B D0,D4 Move and mask extra bits
ADD.B D6,D4 Conversion into a printable character
CMP.B 1(A1),D4 Compare the second byte
BNE RdPack15 Compare fails, garbled packet
LSR.W #6,D0 Process bits 12 --> 15, right adjusting
ADD.B D6,D0 Conversion into a printable character
CMP.B (A1),D0 Compare the first byte
BRA.S RdPack14 Join common part
RdPack12 BSR Check2 Compute
MOVEQ #$3F,D4 Process bits 0 --> 5
AND.B D0,D4 Move and mask extra bits
ADD.B D6,D4 Conversion into a printable character
CMP.B 1(A1),D4 Ok, now compare, second byte
BNE RdPack15 Compare fails, garbled packet
LSR.W #6,D0 Process bits 6 --> 11, right adjusting
ANDI.B #$3F,D0 Mask extra bits
ADD.B D6,D0 Conversion into a printable character
CMP.B (A1),D0 Compare the first byte
BRA.S RdPack14 Join common part
RdPack13 BSR Check1 Compute
ADD.B D6,D0 Convert it to a printable character
CMP.B (A1),D0 Compare it with the received block check
* Join common part, (fall thru)
RdPack14 BEQ.S RdPack17 If compare succeeds return packet type
RdPack15 MOVEQ #'Q',D1 Return a garbage pseudo-packet
BRA.S RdPack18
RdPack16 MOVEQ #'T',D1 Return a timeout pseudo-packet
BRA.S RdPack18
RdPack17 ADDQ.L #1,PcksRecd(A6) Increment packets received this trans
ADDQ.L #1,TPckRecd(A6) Increment total packets received
RdPack18 MOVEQ #PackType,D0 We want display the packet type
BSR Screen Update the screen, if necessary
RdPack19 ADDQ.L #4,A7 Deallocate space on the stack
MOVE.L (A7)+,D4 Restore working register
RTS
******************************** InpPack ******************************ok
* *
* Loop until the expected packet arrives or the maximum tries number *
* exceeded. If a packet arrives with the same type of the last *
* packet sent, it's treated as an echo and another one is expected. *
* If the previous packet arrives again, the last packet is resent *
* and a new one is expected to come in. *
* *
* Entry conditions : none *
* *
* Exit conditions : D1.B packet type or pseudo-type *
* D2.B packet number *
* D3.B packet length *
* D4.B destroyed *
* *
***********************************************************************
InpPack: CLR.B D4 Clear the retry counter
InpPack1 BSR ChekInt Check for console interrupts
BSR RdPack Try to read a packet
CMP.B SendType(A6),D1 It's the same just sent ?
BNE.S InpPack2 No
BSR RdPack Yes, it's an echo, read another
InpPack2 CMP.B PrevPckN(A6),D2 Previous packet ?
BEQ.S InpPack4 Yes, keep trying
CMPI.B #'T',D1 Timeout pseudo-packet ?
BEQ.S InpPack4 Yes, keep trying
CMPI.B #'Q',D1 Garbage pseudo-packet ?
BEQ.S InpPack4 Yes, keep trying
CMPI.B #'N',D1 NAK packet ?
BNE.S InpPack3 No, return the received packet
ADDQ.L #1,NAKsRecd(A6) Yes, increment NAKs received counter
ADDQ.L #1,TNAKRecd(A6) Increment total NAKs received counter
CMP.B NextPckN(A6),D2 It's a NAK for the next packet ?
BNE.S InpPack4 No
MOVEQ #'Y',D1 Yes, it's like an ACK ...
MOVE.B PackNum(A6),D2 ... for current packet
InpPack3 MOVE.B D1,D4 Save this for parameter passing
MOVEQ #ClrInpBf,D0 Clear the input buffer ...
MOVEQ #HostLine,D1 ... of the host line
BSR ChanCtrl Call the channel control routine
MOVE.B D4,D1 Restore the packet (pseudo) type
RTS
InpPack4 CMP.B Retry(A6),D4 Too many tries ?
BCC.S InpPack3 Yes, return
BSR Resend No, send last packet again
ADDQ.B #1,D4 Increment the retry counter
BRA.S InpPack1 Stay in loop
********************************* GetPack *****************************ok
* *
* Gets characters from the current source, file or memory string. *
* Encodes the data into the packet, filling the packet optimally. *
* Returns TRUE on success with Size containing the number of *
* characters in DataBuf, or FALSE if DataBuf is empty (Size = 0, *
* EOF for file, end of string for memory string). *
* *
* Entry conditions : none *
* *
* Exit conditions : D0.B completion code *
* *
***********************************************************************
GetPack: MOVEM.L A0/D1-D2,-(A7) Save working registers
LEA DataBuf(A6),A0 Pointer to data buffer
MOVEQ #0,D2 Clear index register
TST.B First(A6) First time ?
BLT.S GetPack1 No, EOF from last time
BEQ.S GetPack2 No, input in progress
CLR.B First(A6) Yes, remember
BSR GetChx Get first character of file
MOVE.B D0,Current(A6) Save current character
TST.B D1 Null file ?
BNE.S GetPack3 No
GetPack1 MOVE.B #1,First(A6) Yes, setup for next time
SF D0 Return negative completion code
BRA.S GetPack9
GetPack2 MOVE.B LeftOver(A6,D2.W),(A0,D2.W) Do any left-overs
BEQ.S GetPack3 Exit if null
ADDQ.W #1,D2 Increment index
BRA.S GetPack2 Repeat
GetPack3 CLR.B LeftOver(A6) Nullify the left-overs buffer
CLR.B ReptCnt(A6) Clear out any old repeat count
GetPack4 TST.B First(A6) EOF reached ?
BLT.S GetPack8 Yes, return partially (?) filled packet
BSR GetChx Get a character from file or memory
MOVE.B D0,Next(A6) Save next character for lookahead
TST.B D1 EOF ?
BNE.S GetPack5 No
MOVE.B #-1,First(A6) Yes, flag it for next time
GetPack5 MOVE.B D2,OldSize(A6) Remember current position
MOVE.B Current(A6),D0 Get the current character
BSR Encode Encode the current character
MOVE.B Next(A6),Current(A6) Next is now current
CMP.B OMPckSiz(A6),D2 Check packet size
BLT.S GetPack4 Keep filling
BEQ.S GetPack8 Return exactly full packet
MOVEQ #0,D0 Clear for indexing the left-overs buffer
MOVEQ #0,D1 Clear for indexing the data buffer
MOVE.B OldSize(A6),D1 Set up the data buffer index
GetPack6 MOVE.B (A0,D1.W),LeftOver(A6,D0.W) Save some for next time
BEQ.S GetPack7 Exit if null
ADDQ.W #1,D0 Increment the first index
ADDQ.W #1,D1 Increment the second index
BRA.S GetPack6 Repeat
GetPack7 MOVE.B OldSize(A6),D2 Size of the truncated packet
GetPack8 ST D0 Provide positive completion code
GetPack9 MOVE.B D2,Size(A6)
CLR.B (A0,D2.W) Write buffer terminator
MOVEM.L (A7)+,A0/D1-D2 Restore working registers
RTS
********************************* EncStrng ****************************ok
* *
* Encode a string from memory. *
* *
* Entry conditions : A0.L memory string start address *
* *
* Exit conditions : A0.L memory string start address *
* *
***********************************************************************
EncStrng: MOVE.B MStrFlag(A6),-(A7) Save the old flag
MOVE.L MStrgPnt(A6),-(A7) Save the old pointer
ST MStrFlag(A6) Say input from memory string
MOVE.L A0,MStrgPnt(A6) Point to the memory string
MOVE.B #1,First(A6) Initialize character lookahead
BSR GetPack Get a packet from the string
MOVE.L (A7)+,MStrgPnt(A6) Restore the old pointer
MOVE.B (A7)+,MStrFlag(A6) Restore the old flag
MOVE.B #1,First(A6) Re-initialize character lookahead
RTS
********************************* GetChx ******************************ok
* *
* Try to get the next character from file or memory string. *
* Returns TRUE on success with D0.B set to the character, or FALSE *
* on failure (EOF for file, enf of string for memory string). *
* *
* Entry conditions : none *
* *
* Exit conditions : D0.B character (if any) *
* D1.B completion code *
* *
***********************************************************************
GetChx MOVE.L A0,-(A7) Save working register
TST.B LFSave(A6) Do we have a linefeed saved ?
BEQ.S GetChx1 No
SF LFSave(A6) Yes, nullify the flag
MOVEQ #Asc_LF,D0 Return the saved LF
ST D1 Also return a positive cc
BRA.S GetChx4
GetChx1 TST.B MStrFlag(A6) Try to get the next character, memory ?
BEQ.S GetChx2 No, get it from current file
MOVEA.L MStrgPnt(A6),A0 Load pointer to the memory string
MOVE.B (A0)+,D0 Get a character
SNE D1 Set cc to false if end of string reached
MOVE.L A0,MStrgPnt(A6) Save pointer for next time
BRA.S GetChx3 Join the common part
GetChx2 MOVEQ #IOFile,D1 Get a char from the the current file
BSR InpChar
TST.B D1 Check the returned completion code
SEQ D1 Set completion code accordingly
GetChx3 TST.B D1 Have we got a character ?
BEQ.S GetChx4 No, return
ADDQ.L #1,DChsSent(A6) Yes, count it
ADDQ.L #1,TDChSent(A6)
TST.B Binary(A6) Are we in binary mode ?
BNE.S GetChx4 Yes, nl-CRLF mapping not needed
CMPI.B #NewLinCh,D0 No, newline character ?
BNE.S GetChx4 No
ST LFSave(A6) Yes, remember a linefeed
MOVEQ #Asc_CR,D0 Return a carriage return
GetChx4 MOVE.L (A7)+,A0 Restore working register
RTS
********************************* Resend ******************************ok
* *
* Resend the last packet sent (the one in SendBuf), if any, send *
* a NAK otherwise. *
* *
* Entry conditions : none *
* *
* Exit conditions : D0.L destroyed *
* D1.L destroyed *
* *
***********************************************************************
Resend: MOVEQ #ClrInpBf,D0 Clear the input buffer
MOVEQ #HostLine,D1 Host line channel
BSR ChanCtrl Call the channel control routine
TST.B SendBuf(A6) Send buffer empty ?
BNE.S Resend1 No, send last packet again
BSR SendNAK Yes, send a NAK packet
RTS
Resend1 BSR TxPackt Send the previous packet again
MOVEQ #PackType,D0 Update the screen
MOVEQ #'%',D1 This is the symbol for a resent packet
BSR Screen
RTS
******************************** SndEPack *****************************ok
* *
* Send an Error packet. *
* *
* Entry conditions : A1.L point to the reason string *
* *
* Exit conditions : D0.L destroyed *
* D1.L destroyed *
* D2.B destroyed *
* D3.B destroyed *
* A0.L destroyed *
* *
***********************************************************************
SndEPack: MOVEA.L A1,A0 Point to the reason string
BSR EncStrng Encode it
MOVEQ #'E',D1 Error packet
MOVE.B PackNum(A6),D2 Packet number
MOVE.B Size(A6),D3 Packet length
BSR SndPack OK, send now
BSR ClsInpF Close the input file, if open
ST CtlZSeen(A6) This is an interrupted file transfer
BSR ClsOutF Close (and maybe delete) the output file
MOVEQ #TranCmpl,D0 Give transaction complete message
BSR Screen
RTS
********************************* SendACK *****************************ok
* *
* Send an empty ACK packet. *
* *
* Entry conditions : none *
* *
* Exit conditions : D1.L destroyed *
* D2.B destroyed *
* D3.L destroyed *
* *
***********************************************************************
SendACK: MOVEQ #'Y',D1 ACK
MOVE.B PackNum(A6),D2 Packet number
MOVEQ #0,D3 Packet length (0, empty packet)
BSR SndPack OK, send now
BSR BumpPckN Bump packet number, modulo 64
RTS
********************************* SendNAK *****************************ok
* *
* Send a NAK packet (always empty). *
* *
* Entry conditions : none *
* *
* Exit conditions : D1.L destroyed *
* D2.B destroyed *
* D3.L destroyed *
* *
***********************************************************************
SendNAK MOVEQ #'N',D1 NAK
MOVE.B PackNum(A6),D2 Packet number
MOVEQ #0,D3 Packet length (0, empty packet)
BSR SndPack OK, send now
ADDQ.L #1,NAKsSent(A6) Increment NAKs sent this transaction
ADDQ.L #1,TNAKSent(A6) Increment total NAKs sent
RTS
ends
END