nam Kermit68K ttl Protocol automaton subroutines module * Kermit68K: source file K68PRO * * 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 K68Protocol,0,0,Edition,0,0 ******************************** KPSwtch ******************************ok * * * Kermit protocol state table switcher. It loops until either it * * finishes, or an error is encountered. D7.W contains the present * * state of the automaton. The routines called by KPSwtch are * * responsible for changing the state. * * * * Entry conditions : D7.W initial state of the automaton * * * * Exit conditions : D0.B completion code * * * *********************************************************************** KPSwtch: TST.B Local(A6) Are we running in local mode ? BEQ.S KPSwtch1 No, no mind about speed TST.L Speed(A6) Is line speed setted ? BLT.S KPSwtch3 No, give error and return KPSwtch1 MOVEQ #RawMode,D0 Put line in raw mode MOVEQ #HostLine,D1 BSR ChanCtrl CMPI.B #AllOk,D0 All ok ? BEQ.S KPSwtch5 Yes, enter the protocol switcher KPSwtch2 LEA CCndLStr(PC),A1 No, point to the error message BRA.S KPSwtch4 Display this on the screen KPSwtch3 LEA StSpeStr(PC),A1 Point to the 'set speed' error message KPSwtch4 MOVEQ #ErrMessg,D0 Error message display request code BSR Screen Display on the screen RTS KPSwtch5 PEA KPSwtch5(PC) Provide return address MOVE.W D7,D0 Load the present state of the automaton ADD.W D0,D0 Scale it MOVE.W KPSwtch6(PC,D0.W),D0 Load index JMP KPSwtch6(PC,D0.W) Jump to the appropriate address KPSwtch6 DC.W SndInit-KPSwtch6 Send-Init DC.W OpnFile-KPSwtch6 Open-File DC.W SndFile-KPSwtch6 Send-File DC.W SndData-KPSwtch6 Send-Data DC.W SendEOF-KPSwtch6 Send-End-Of-File DC.W SendEOT-KPSwtch6 Send-Break DC.W RecInit-KPSwtch6 Receive-Init DC.W RecFile-KPSwtch6 Receive-File DC.W RecData-KPSwtch6 Receive-Data DC.W SndSrvI-KPSwtch6 Send-Server-Init DC.W SndGCmd-KPSwtch6 Send-Generic-Command DC.W Complete-KPSwtch6 Complete DC.W Abort-KPSwtch6 Abort ******************************** SndSrvI ******************************ok * * * Send Server Init, send this host's parameters and get other side's * * back, then enter Send Generic Command state. * * * * Entry conditions : none * * * * Exit conditions : D0.L destroyed * * D1.L destroyed * * D2.L destroyed * * D3.B destroyed * * D7.L next state of the automaton * * * *********************************************************************** SndSrvI MOVEQ #ClrInpBf,D0 Clear the input buffer MOVEQ #HostLine,D1 Host line channel, of course BSR ChanCtrl Call the channel control routine BSR SndParm Fill up the init info packet MOVEQ #'I',D1 Send an I packet MOVEQ #0,D2 Packet number (always 0) MOVE.B D0,D3 Packet length as returned by SndParm BSR SndPack Ok, send now BSR InpPack What was the reply ? CMPI.B #'Y',D1 ACK ? BEQ.S SndSrvI4 Yes CMPI.B #'E',D1 Error packet ? BNE BadPack No, bad packet CLR.B DataBuf(A6) Yes, ignore it, clear data buffer * Fall thru, use default parameters SndSrvI4 BSR RdParam Get other side's init info MOVE.B BlChkRq(A6),BlChkUs(A6) Setup block check type MOVEQ #SndGCmdS,D7 OK, switch state to Send-Generic-Command RTS ******************************** SndGCmd ******************************ok * * * Send Generic Command. * * * * Entry conditions : none * * * * Exit conditions : D0.L destroyed * * D1.L destroyed * * D2.L destroyed * * D3.B destroyed * * D7.L next state of the automaton * * A0.L destroyed * * * *********************************************************************** SndGCmd LEA CmdBuf(A6),A0 Point to command buffer BSR EncStrng Fill up the data buffer MOVE.B ServrCmd(A6),D1 Send a packet of the appropriate type MOVEQ #0,D2 Packet number (always 0) MOVE.B Size(A6),D3 Packet size BSR SndPack Ok, send now BSR InpPack What was the reply ? CMPI.B #'Y',D1 ACK ? BEQ.S SndGCmd2 Yes CMPI.B #'S',D1 Send-Init packet ? BEQ.S SndGCmd3 Yes CMPI.B #'X',D1 X packet ? BNE BadPack No, unknown packet type, abort ST TermOut(A6) Yes, set the terminal output flag BSR SendACK Acknowledge MOVEQ #RecDataS,D7 Enter Receive-Data state RTS SndGCmd2 LEA ConOut(PC),A0 ACK received BSR Decode Decode packet and output it BSR NewLine Start a new line on the screen MOVEQ #CompletS,D7 Ok, enter complete state RTS SndGCmd3 BSR RdParam Get the other side's init data BSR SndParm Fill up packet with my init info MOVEQ #'Y',D1 ACK my parameters MOVEQ #0,D2 Packet number (0) MOVE.B D0,D3 Packet length as returned by SndParm BSR SndPack OK, send now BSR BumpPckN Bump packet number, modulo 64 MOVE.B BlChkRq(A6),BlChkUs(A6) Setup block check type MOVEQ #RecFileS,D7 Enter Receive-File state RTS ******************************** Complete *****************************ok * * * Successful end of transaction. * * * * Entry conditions : none * * * * Exit conditions : D0.B positive completion code * * * *********************************************************************** Complete ADDQ.L #4,A7 Drop return address MOVEQ #TranCmpl,D0 Say transaction complete BSR Screen ST D0 Return a positive completion code RTS ********************************* Abort *******************************ok * * * Unsuccessful end of transaction. * * * * Entry conditions : none * * * * Exit conditions : D0.B negative completion code * * D4.B destroyed * * A0.L destroyed * * * *********************************************************************** Abort ADDQ.L #4,A7 Drop return address CMPI.B #'E',D1 Error packet received ? BNE.S Abort1 No, too many tries or invalid type BSR NewLine LEA ErFRHStr(PC),A0 Yes, point to error string BSR ConWrite Write it to terminal LEA DataBuf(A6),A0 Point to error packet contents BSR ConWrite Write it to terminal MOVE.B Quiet(A6),D4 Save the quiet flag ST Quiet(A6) Set the quiet flag on BSR ClsInpF Close the input file silently ST CtlZSeen(A6) Force discarding of the ouput file BSR ClsOutF Close the output file silently MOVE.B D4,Quiet(A6) Restore the quiet flag BRA.S Abort7 Abort1 CMPI.B #'N',D1 NAK packet ? BEQ.S Abort2 Yes CMPI.B #'T',D1 Timeout pseudo-packet ? BEQ.S Abort3 Yes CMPI.B #'Q',D1 Garbage pseudo-packet ? BEQ.S Abort4 Yes CMP.B PackNum(A6),D2 Packet out of sequence ? BNE.S Abort5 Yes BSR NewLine LEA UkUxPStr(PC),A0 No, unknown or unexpected packet type BSR ConWrite BRA.S Abort7 Abort2 PEA NAKRcStr(PC) NAK received string BRA.S Abort6 Abort3 PEA TimLEStr(PC) Timeout limit expired string BRA.S Abort6 Abort4 PEA GbPRcStr(PC) Garbage packet received string BRA.S Abort6 Abort5 PEA POuOSStr(PC) Packet out of sequence string Abort6 BSR NewLine LEA TooMTStr(PC),A0 Point to the abort string BSR ConWrite Write it to the terminal line MOVEA.L (A7)+,A0 Now write the last error string BSR ConWrite Abort7 BSR NewLine Start a new line SF D0 Return a negative completion code RTS BadPack MOVEQ #AbortS,D7 This is for code reduction RTS ********************************* SndInit *****************************ok * * * Send Initiate, send this host's parameters and get other side's * * back. * * * * Entry conditions : none * * * * Exit conditions : D0.L destroyed * * D1.L destroyed * * D2.L destroyed * * D3.B destroyed * * D7.L next state of the automaton * * A0.L destroyed * * A1.L destroyed * * * *********************************************************************** SndInit LEA Argumnt1(A6),A0 Pointer to file name BSR ExpandFN Expand it into a file names list TST.L D0 Check the returned number BLT.S SndInit4 Too many files match BNE.S SndInit1 Some files match, get the first one BSR CRemTLoc No files match, convert name to local BSR ExpandFN Try again the file name expansion TST.L D0 Check the returned number BLE.S SndInit3 If no or too many files match, error SndInit1 BSR NextFil Get the first file name into FilName TST.B D0 Check completion code BEQ.S SndInit5 Failed, exit protocol (don't enter it) MOVEQ #ClrInpBf,D0 Clear the input buffer MOVEQ #HostLine,D1 BSR ChanCtrl Call the channel control routine TST.B Local(A6) Are we running in local mode ? BNE.S SndInit2 Yes, no need for delay MOVE.B Delay(A6),D0 Load initial delay before sending BSR Sleep Sleep the requested amount of time SndInit2 BSR SndParm Fill up init info packet MOVEQ #'S',D1 Send an S packet MOVEQ #0,D2 Packet number (always 0) MOVE.B D0,D3 Packet length as returned by SndParm BSR SndPack Ok, send now BSR InpPack What was the reply ? CMPI.B #'Y',D1 ACK ? BNE BadPack No, bad packet BSR RdParam Yes, get other side's init info BSR BumpPckN Bump packet count MOVE.B BlChkRq(A6),BlChkUs(A6) Setup block check type MOVE.B RtryPack(A6),Retry(A6) Setup retry limit for normal packets MOVEQ #OpnFileS,D7 OK, switch state to Open-File RTS SndInit3 LEA FNFStr(PC),A1 Point to file not found error message BRA.S SndInit6 Join common part SndInit4 LEA TMFStr(PC),A1 Point to too many files error message BRA.S SndInit6 Join common part SndInit5 LEA NRFStr(PC),A1 Point to no readable files error message SndInit6 MOVEQ #ErrMessg,D0 Give bad news BSR Screen MOVEQ #CompletS,D7 Enter complete state RTS ********************************* OpnFile *****************************ok * * * Open File or set up text to send. * * * * Entry conditions : none * * * * Exit conditions : D0.L destroyed * * D7.L next state of the automaton * * A0.L destroyed * * A1.L destroyed * * * *********************************************************************** OpnFile LEA FilName(A6),A0 Point to file name BSR OpnInpF Try to open the file TST.B D0 Success ? BEQ.S OpnFile1 No MOVEQ #SndFileS,D7 Yes switch state to Send-File RTS OpnFile1 LEA FlOErStr(PC),A1 Point to open failed error message MOVEQ #ErrMessg,D0 Give bad news BSR Screen Screen return the pointer unchanged BSR SndEPack Send an Error packet MOVEQ #AbortS,D7 Abort RTS ******************************** SndFile ******************************ok * * * Send File Header. * * * * Entry conditions : none * * * * Exit conditions : D0.L destroyed * * D1.L destroyed * * D2.B destroyed * * D3.B destroyed * * D7.L next state of the automaton * * A0.L destroyed * * A1.L destroyed * * * *********************************************************************** SndFile LEA FilName(A6),A1 Point to the local file name MOVEQ #SFilName,D0 Display it on the screen BSR Screen LEA Argumnt2(A6),A0 Point to the file send-as name TST.B (A0) Has it been specified ? BNE.S SndFile1 Yes, send it in the packet data field LEA FilName(A6),A1 No, same as local file name MOVEQ #CmdBufLn,D0 Copy it to Argumnt2 BSR CopyStr TST.B FNameCnv(A6) Are we converting file names ? BEQ.S SndFile1 No BSR CLocTRem Yes, so convert file name in Argumnt2 SndFile1 MOVEA.L A0,A1 Display the file send-as name MOVEQ #FlAsName,D0 BSR Screen BSR EncStrng Encode the file name into the data field CLR.B (A0) Finally nullify Argumnt2 MOVEQ #'F',D1 Send a F packet MOVE.B PackNum(A6),D2 Packet number MOVE.B Size(A6),D3 Packet length BSR SndPack Ok, send now BSR InpPack What was the reply ? CMPI.B #'Y',D1 ACK ? BNE BadPack No, bad packet BSR BumpPckN Bump packet counters MOVE.B #1,First(A6) Init file character lookahead BSR GetPack Get the first buffer of data TST.B D0 Null file ? BNE.S SndFile4 No, enter Send-Data state MOVEQ #SendEOFS,D7 Enter Send-EOF state RTS SndFile4 MOVEQ #SndDataS,D7 Switch state to Send-Data RTS ******************************** SndData ******************************ok * * * Send File Data. * * * * Entry conditions : none * * * * Exit conditions : D0.B destroyed * * D1.L destroyed * * D2.B destroyed * * D3.B destroyed * * D7.L next state of the automaton * * * *********************************************************************** SndData MOVE.B CtlXSeen(A6),D0 Current file or file group cancelled ? OR.B CtlZSeen(A6),D0 BNE.S SndData4 Yes MOVEQ #'D',D1 No, send a D packet MOVE.B PackNum(A6),D2 Packet number MOVE.B Size(A6),D3 Packet length BSR SndPack Ok, send now BSR InpPack What was the reply ? SndData2 CMPI.B #'Y',D1 ACK ? BNE BadPack No, bad packet BSR BumpPckN Bump packet count TST.B D3 Empty ACK packet ? BEQ.S SndData5 Yes, get next data buffer MOVE.B DataBuf(A6),D0 No, get first character of data buffer CMPI.B #'X',D0 File interrupt directive ? SEQ CtlXSeen(A6) Yes, set the appropriate flag BEQ.S SndData4 And enter, Send-EOF state CMPI.B #'Z',D0 File group interrupt directive ? SEQ CtlZSeen(A6) Yes, set the appropriate flag BNE.S SndData5 No, ignore ACK contents SndData4 MOVEQ #SendEOFS,D7 Enter Send-EOF state RTS SndData5 BSR GetPack Get next data buffer TST.B D0 EOF or end of memory string ? BEQ.S SndData4 Yes, switch state to Send-EOF RTS No, remain in this state ******************************** SendEOF ******************************ok * * * Send End-Of-File. * * * * Entry conditions : none * * * * Exit conditions : D0.B destroyed * * D1.L destroyed * * D2.B destroyed * * D3.L destroyed * * D7.L next state of the automaton * * * *********************************************************************** SendEOF BSR ClsInpF Close the input file MOVEQ #'Z',D1 Send a Z packet MOVE.B PackNum(A6),D2 Packet number MOVE.B CtlXSeen(A6),D0 Current file or file group cancelled ? OR.B CtlZSeen(A6),D0 BEQ.S SendEOF1 No MOVE.B #'D',DataBuf(A6) Yes, put discard directive in data space MOVEQ #1,D3 Packet length (1, Z/D packet) BRA.S SendEOF2 SendEOF1 MOVEQ #0,D3 Packet length (0, empty Z packet) SendEOF2 BSR SndPack OK, send now BSR InpPack What was the reply ? CMPI.B #'Y',D1 ACK ? BNE BadPack No, bad packet BSR BumpPckN Bump packet counters BSR NextFil Look for another file TST.B D0 Is there ? BEQ.S SendEOF3 No, end of transaction MOVEQ #OpnFileS,D7 Yes, send it RTS SendEOF3 MOVEQ #SendEOTS,D7 Enter Send-EOT state RTS ******************************** SendEOT ******************************ok * * * Send Break (EOT). * * * * Entry conditions : none * * * * Exit conditions : D1.L destroyed * * D2.B destroyed * * D3.L destroyed * * D7.L next state of the automaton * * * *********************************************************************** SendEOT MOVEQ #'B',D1 Send a B packet MOVE.B PackNum(A6),D2 Packet number MOVEQ #0,D3 Packet length BSR SndPack Ok, send now CLR.B NextPckN(A6) If the expected ACK lost, the next * packet from the receiver will be NAK(0) BSR InpPack What was the reply ? CMPI.B #'Y',D1 ACK ? BNE BadPack No, bad packet MOVEQ #CompletS,D7 Yes, enter Complete state RTS ********************************* RecInit *****************************ok * * * Receive Initialization. * * * * Entry conditions : none * * * * Exit conditions : D1.L destroyed * * D2.L destroyed * * D3.B destroyed * * D7.L next state of the automaton * * * *********************************************************************** RecInit BSR InpPack Try to get a packet CMPI.B #'S',D1 Send-Init packet received ? BNE BadPack No, bad packet BSR RdParam Get the other side's init data BSR SndParm Fill up packet with my init info MOVEQ #'Y',D1 ACK my parameters MOVEQ #0,D2 Packet number (0) MOVE.B D0,D3 Packet length as returned by SndParm BSR SndPack OK, send now BSR BumpPckN Bump packet number, modulo 64 MOVE.B BlChkRq(A6),BlChkUs(A6) Setup block check type MOVE.B RtryPack(A6),Retry(A6) Setup retry limit for normal packets MOVEQ #RecFileS,D7 Enter Receive-File state RTS ********************************* RecFile *****************************ok * * * Receive File Header. * * * * Entry conditions : none * * * * Exit conditions : D0.L destroyed * * D1.L destroyed * * D2.B destroyed * * D3.B destroyed * * D7.L next state of the automaton * * A0.L destroyed * * A1.L destroyed * * * *********************************************************************** RecFile BSR InpPack Try to get a packet CMPI.B #'X',D1 Send-File packet received ? BEQ RecFile4 Yes CMPI.B #'B',D1 Break packet received ? BEQ RecFile5 Yes CMPI.B #'F',D1 Send-File packet received ? BNE BadPack No, abort CLR.B CmdBfPnt(A6) Yes, prepare CmdBuf to receive file name LEA CmdBfOut(PC),A0 File name decoded to CmdBuf BSR Decode LEA CmdBuf(A6),A0 Pointer to the file name just decoded TST.B (A0) The F packet was null ? BNE.S RecFile1 No LEA NoNamStr(PC),A1 Yes, provide a default name MOVEQ #CmdBufLn,D0 Copy it to CmdBuf BSR CopyStr RecFile1 MOVEA.L A0,A1 Display the file name on the screen MOVEQ #RFilName,D0 Load the appropriate request code BSR Screen Call the screen handler LEA Argumnt2(A6),A1 Check for alternate file name TST.B (A1) Has been specified ? BEQ.S RecFile2 No MOVEQ #CmdBufLn,D0 Yes, copy it to CmdBuf BSR CopyStr CLR.B (A1) Nullify Argumnt2 RecFile2 LEA FilName(A6),A1 Return here the actual name BSR OpnOutF Try to open (create) the file TST.B D0 Check the completion code BEQ.S RecFile3 Open fails MOVEA.L A1,A0 Open succeeds, here is the actual name MOVEQ #FlAsName,D0 Display it on the screen BSR Screen BSR EncStrng Encode the file name into the data field MOVEQ #'Y',D1 Send an ACK packet MOVE.B PackNum(A6),D2 Packet number MOVE.B Size(A6),D3 Packet length BSR SndPack Ok, send now BSR BumpPckN Bump packet counters MOVEQ #RecDataS,D7 Enter Receive-Data state RTS RecFile3 LEA FlCrEStr(PC),A1 Point to open failed error message MOVEQ #ErrMessg,D0 Give bad news BSR Screen Screen return the pointer unchanged BSR SndEPack Send an Error packet MOVEQ #AbortS,D7 Abort RTS RecFile4 ST TermOut(A6) Set the terminal output flag BSR SendACK Acknowledge MOVEQ #RecDataS,D7 Enter Receive-Data state RTS RecFile5 BSR SendACK Acknowledge MOVEQ #CompletS,D7 Enter Complete state RTS ********************************* RecData *****************************ok * * * Receive File Data. * * * * Entry conditions : none * * * * Exit conditions : D1.L destroyed * * D2.B destroyed * * D3.L destroyed * * D7.L next state of the automaton * * A0.L destroyed * * * *********************************************************************** RecData BSR InpPack Try to get a packet CMPI.B #'Z',D1 EOF packet received ? BEQ.S RecData6 Yes CMPI.B #'D',D1 Send-Data packet received ? BNE BadPack No, bad packet TST.B TermOut(A6) Output to the terminal channel wanted ? BEQ.S RecData1 No, file output LEA ConOut(PC),A0 Yes BRA.S RecData2 RecData1 LEA FileOut(PC),A0 Address of the file output function RecData2 BSR Decode Decode packet and output it LEA DataBuf(A6),A0 Pointer to data buffer TST.B CtlXSeen(A6) File transfer interrupt request ? BEQ.S RecData3 No, look for group transfer interrupt MOVE.B #'X',(A0)+ Put "X" in the ACK packet data space BRA.S RecData4 RecData3 TST.B CtlZSeen(A6) File group transfer interrupt request ? BEQ.S RecData5 No, send a normal (empty) ACK packet MOVE.B #'Z',(A0)+ Put "Z" in the ACK packet data space RecData4 CLR.B (A0)+ Mark end of data MOVEQ #'Y',D1 ACK packet type MOVE.B PackNum(A6),D2 Packet number MOVEQ #1,D3 Packet length (1, "X" or "Z") BSR SndPack OK, send now BSR BumpPckN Bump packet number, modulo 64 RTS Return, state unchanged RecData5 BSR SendACK Acknowledge RTS Return, state unchanged RecData6 TST.B CtlXSeen(A6) File transfer interrupted ? BNE.S RecData7 Yes, close file TST.B D3 Empty Z packet ? BEQ.S RecData7 Yes, close file CMPI.B #'D',DataBuf(A6) Discard directive ? SEQ CtlXSeen(A6) Set flag for ClsOutF RecData7 BSR ClsOutF Close the output file SF CtlXSeen(A6) Reset flag, necessary for next file BSR SendACK Acknowledge MOVEQ #RecFileS,D7 Enter Receive-File state RTS ends END