<<< k6gsys.asm >>> * Kermit68K: source file K68SYS * * 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 ********************************* InpChar ***************************** * * * Try to read a character from the specified logical channel. * * * * Entry conditions : D1.B logical channel number * * * * Exit conditions : D0.B character received, if any * * D1.B Completion Code (see below) * * * * CC symbol Meaning * * * * AllOk No errors, character in D0 * * BadChan Inexistent channel * * ResChan Access reserved, permission denied * * DevNotRd Device not ready (e.g. unmounted) * * NotInpCh Input impossible on this channel * * NotOpRd File not open for read * * UnrInpF Unrecoverable failure during input * * InChLost Input character lost * * InpBreak Break received on input * * BufEmpty Input buffer empty * * BufOvflw Input buffer overflow * * EndOfFil End of file reached on input * * * *********************************************************************** InpChar: RTS ********************************* OutChar ***************************** * * * Try to write a character to the specified logical channel. * * * * Entry conditions : D0.B character to write * * D1.B logical channel number * * * * Exit conditions : D0.B character just sent * * D1.B Completion Code (see below) * * * * CC symbol Meaning * * * * AllOk No errors * * BadChan Inexistent channel * * ResChan Access reserved, permission denied * * DevNotRd Device not ready (e.g. unmounted) * * NotOutCh Output impossible on this channel * * NotOpWr File not open for write * * UnrOutF Unrecoverable failure during output * * DevFull Device full, not enough space * * * *********************************************************************** OutChar: RTS ********************************* ChanCtrl **************************** * * * Performs control operations on logical channels. * * * * Entry conditions : D0.B Request Code (see below) * * * * RC symbol Meaning * * * * SetBaud Set baud rate on port * * RawMode Enable raw mode * * TextMode Enable text mode * * DoXCntrl Enable XON/XOFF protocol * * NoXCntrl Disable XON/XOFF protocol * * SndBreak Send a break over RS 232 C line * * ClrInpBf Clear input buffer * * ClrOutBf Clear output buffer * * * * D1.B channel number * * D2.L additional data (only requested * * baud rate now) * * * * Exit conditions : D0.B Completion Code (see below) * * * * CC symbol Meaning * * * * AllOk No errors * * BadChan Inexistent channel * * ResChan Access reserved, permission denied * * DevNotRd Device not ready (e.g. unmounted) * * BadCtReq I/O control request code invalid * * * *********************************************************************** ChanCtrl: RTS ********************************* SysInit ***************************** * * * Initialize any system dependent thing. * * * * Entry conditions : none * * * * Exit conditions : none * * * *********************************************************************** SysInit: RTS ********************************* SysExod ***************************** * * * Return control to system. * * * * Entry conditions : D0.B completion code, exit status * * * * Exit conditions : none * * * *********************************************************************** SysExod: ********************************** System ***************************** * * * Performs system commands. Called with a request code and 0, 1 or 2 * * null terminated argument strings, depending on request code. * * * * Entry conditions : D0.B Request Code (see below) * * * * RC symbol Meaning * * * * Directry Display a directory listing * * SpacInfo Display informations about disk usage * * DeletFil Delete file(s) * * CopyFile Copy file(s) * * ChangDir Change the default directory * * PrntFile Print file(s) * * RenamFil Rename file(s) * * TypeFile Type file(s) * * * * A0.L pointer to argument 1 (see below) * * A1.L pointer to argument 2 (see below) * * * * RC symbol Arguments number and meaning * * * * Directry 0 or 1 directory path * * SpacInfo 0 or 1 device or account name * * DeletFil 1 file name * * CopyFile 2 source and target file names * * ChangDir 0 or 1 path to new directory * * PrntFile 1 file name * * RenamFil 2 old and new file names * * TypeFile 1 file name * * * * Exit conditions : D0.B completion code * * * *********************************************************************** System: RTS ******************************** GetCmdLP ***************************** * * * Try to return a pointer to the command line, null terminated. * * * * Entry conditions : none * * * * Exit conditions : A0.L pointer to the command line, if any * * D0.B completion code * * * *********************************************************************** GetCmdLP RTS ********************************* FilOpen ***************************** * * * Open a disk file or an I/O channel. * * * * Entry conditions : D0.B Request Code (see below) * * * * RC symbol Meaning * * * * RdWrOp Open for read/write * * ReadOp Open for read * * WriteOp Open for write * * AppendOp Open for append * * * * D1.B logical channel number. * * A0.L points to file name null terminated * * * * Exit conditions : D0.B completion code * * A0.L still points to the file name * * * *********************************************************************** FilOpen: RTS ******************************** FilClose ***************************** * * * Close a disk file or an I/O channel. * * * * Entry conditions : D1.B logical channel number. * * * * Exit conditions : D0.B completion code * * * *********************************************************************** FilClose: RTS ********************************* FilDelet **************************** * * * Delete a file. * * * * Entry conditions : A0.L points to file name null terminated * * * * Exit conditions : D0.B completion code * * * *********************************************************************** FilDelet: RTS ********************************* ExpandFN **************************** * * * Expand a wildcard file name into an array of file names, returns * * the number of files that match the passed string, with data * * structures set up so that the first file name (if any) will be * * returned by the next GetNxtF call. * * * * Entry conditions : A0.L points to file name null terminated * * * * Exit conditions : D0.L number of matches found, negative * * if too many matches for user buffer * * A0.L still points to the file name * * * *********************************************************************** ExpandFN: RTS ********************************* GetNxtF ***************************** * * * Get the next file name from the list created by ExpandFN, returns * * a true completion code if there's another file, copying its name * * into the target string, or false if no more file names in list. * * * * Entry conditions : A0.L points to the target string * * * * Exit conditions : D0.B completion code * * A0.L points to the target string * * * *********************************************************************** GetNxtF: RTS ********************************* CRemTLoc **************************** * * * Convert filenames from remote system in a form suitable for the * * local system. * * * * Entry conditions : A0.L points to the string to be * * converted * * * * Exit conditions : A0.L points to the same string suitably * * converted * * * *********************************************************************** CRemTLoc: RTS ********************************* CLocTRem **************************** * * * Convert filenames in local system syntax in a form suitable for * * the remote Kermit system. The job that this routine must do is * * explained here in detail. * * * * Adapted from the "Kermit Protocol Manual", Sixth Edition, p. 16 * * * * 1. Delete all pathnames and attributes from the file * * specification. The file name should not contain directory * * or device names; if it does, it may cause the recipient to * * try to store the file in an inaccessible or nonexistent area, * * or it may result in a very strange filename. * * * * 2. After stripping any pathname, convert the remainder of the * * file specification to the form "name.type", with no * * restriction on length (except that it fit in the data field * * of the F packet), and: * * * * a. Include no more than one dot. * * b. Not begin or end with a dot. * * c. The name and type fields contain digits and uppercase * * letters only. * * * * Entry conditions : A0.L points to the string to be * * converted * * * * Exit conditions : A0.L points to the same string suitably * * converted * * * *********************************************************************** CLocTRem: RTS ********************************** NewName **************************** * * * Make a new name for the given file to avoid file name collisions. * * * * Entry conditions : A0.L points to the file name string * * * * Exit conditions : A0.L points to the same string suitably * * modified * * * *********************************************************************** NewName: RTS ********************************** Sleep ****************************** * * * Puts the process to sleep. * * * * Entry conditions : D0.B time interval to wait (seconds) * * * * Exit conditions : none * * * *********************************************************************** Sleep: RTS END <<< k6ocm2.asm >>> nam Kermit68K ttl SET command subroutines module * Kermit68K: source file K68CM2 * * 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 K68Commands2,0,0,Edition,0,0 DoSET: LEA SETTable(PC),A1 Pointer to SET parameters table ST D1 BSR ParsKyW Look for a valid SET parameter TST.B D0 Ok ? BLT.S DoSET1 No, return LEA DoSetTab(PC),A1 Pointer to SET jump table BRA IndxJump Join common jump routine DoSET1 RTS DoSSEND: LEA SSRTable(PC),A1 Point to SET SEND/RECEIVE params table ST D1 BSR ParsKyW Look for a valid SET SEND/RECEIVE param TST.B D0 Ok ? BLT.S DoSSEND1 No, return LEA DoSetSTb(PC),A1 Pointer to SET SEND jump table BRA IndxJump Join common jump routine DoSSEND1 RTS DoSRECV: LEA SSRTable(PC),A1 Point to SET SEND/RECEIVE params table ST D1 BSR ParsKyW Look for a valid SET SEND/RECEIVE param TST.B D0 Ok ? BLT.S DoSRECV1 No, return LEA DoSetRTb(PC),A1 Pointer to SET RECEIVE jump table BRA IndxJump Join common jump routine DoSRECV1 RTS DoSFILE: LEA SFILTabl(PC),A1 Point to SET FILE parameters table ST D1 BSR ParsKyW Look for a valid SET FILE parameter TST.B D0 Ok ? BLT.S DoSFILE1 No, return LEA DoSFlTab(PC),A1 Pointer to SET FILE jump table BRA IndxJump Join common jump routine DoSFILE1 RTS DoSRTRY: LEA SRETTabl(PC),A1 Point to SET RETRY parameters table ST D1 BSR ParsKyW Look for a valid SET RETRY parameter TST.B D0 Ok ? BLT.S DoSRTRY1 No, return LEA DoSRtTab(PC),A1 Pointer to SET RETRY jump table BRA IndxJump Join common jump routine DoSRTRY1 RTS DoStPRM: LEA DataBuf(A6),A1 Pointer to temporary buffer MOVEA.L A1,A0 Pass it to ParsTxt BSR ParsTxt Get a text string from the command line TST.B D0 Ok ? BLT.S DoStPRM1 No, return LEA Prompt(A6),A0 Pointer to the prompt string MOVEQ #PromptML,D0 Max prompt length BSR CopyStr Copy DoStPRM1 RTS DoSetESC: MOVEQ #Escape,D7 Relative address escape character BRA.S SetCtCh Join common parameter setter DoStRMrk: MOVEQ #IStPckCh,D7 Relative address receive pack marker BRA.S SetCtCh Join common parameter setter DoStSMrk: MOVEQ #OStPckCh,D7 Relative address send packet marker BRA.S SetCtCh Join common parameter setter DoStRPdC: MOVEQ #IPadChar,D7 Relative address receive pad character BRA.S SetCtCh Join common parameter setter DoStSPdC: MOVEQ #OPadChar,D7 Relative address send pad character BRA.S SetCtCh Join common parameter setter DoStREOL: MOVEQ #IEOL,D7 Relative address receive EOL character BRA.S SetCtCh Join common parameter setter DoStSEOL: MOVEQ #OEOL,D7 Relative address send EOL character * BRA.S SetCtCh Join common parameter setter ********************************* SetCtCh **************************** * * * Look for a control character ASCII code specification, then set * * the addressed variable. * * * * Entry conditions : D7.L Relative (to A6) address of the * * variable to set * * * * Exit conditions : none * * * *********************************************************************** SetCtCh MOVEQ #Asc_Nul,D1 Valid range lower bound MOVEQ #Asc_Del,D2 Valid range upper bound BSR ParsNm Try to get a number TST.B D1 Invalid number ? BLT.S SetCtCh2 Yes, return CMPI.B #Asc_US,D0 No, check for ASCII control range BLS.S SetCtCh1 Ok, set the parameter CMPI.L #Asc_Del,D0 Delete ? BEQ.S SetCtCh1 Yes, set the parameter LEA SetCtStr(PC),A1 No, not in control range LEA DataBuf(A6),A0 Point to the guilty number BSR ParsErr Give appropriate error message BRA.S SetCtCh2 SetCtCh1 MOVE.B D0,(A6,D7.L) Finally set the parameter SetCtCh2 RTS DoStRPdN: MOVEQ #IPadNumb,D7 Relative address receive pad number MOVEQ #0,D1 Valid range lower bound MOVEQ #100,D2 Valid range upper bound BRA.S SetNPar Join common parameter setter DoStSPdN: MOVEQ #OPadNumb,D7 Relative address send pad number MOVEQ #0,D1 Valid range lower bound MOVEQ #100,D2 Valid range upper bound BRA.S SetNPar Join common parameter setter DoStRTIM: ST TimInFlg(A6) Set flag to allow overriding Send-Init MOVEQ #ITimInt,D7 Relative address receive timeout MOVEQ #1,D1 Valid range lower bound MOVEQ #50,D2 Valid range upper bound BRA.S SetNPar Join common parameter setter DoStSTIM: MOVEQ #OTimInt,D7 Relative address send timeout interval MOVEQ #1,D1 Valid range lower bound MOVEQ #50,D2 Valid range upper bound BRA.S SetNPar Join common parameter setter DoStRMPS: MOVEQ #IMPckSiz,D7 Relative address receive max packet size MOVEQ #10,D1 Valid range lower bound MOVEQ #94,D2 Valid range upper bound BRA.S SetNPar Join common parameter setter DoStSMPS: ST SndPSFlg(A6) Set flag to allow overriding Send-Init MOVEQ #OMPckSiz,D7 Relative address send max packet size MOVEQ #10,D1 Valid range lower bound MOVEQ #94,D2 Valid range upper bound BRA.S SetNPar Join common parameter setter DoStDLAY: MOVEQ #Delay,D7 Relative address delay time before send MOVEQ #0,D1 Valid range lower bound MOVEQ #100,D2 Valid range upper bound BRA.S SetNPar Join common parameter setter DoSetRtI: MOVEQ #RtryInit,D7 Relative address initial retry limit MOVEQ #0,D1 Valid range lower bound MOVEQ #100,D2 Valid range upper bound BRA.S SetNPar Join common parameter setter DoSetRtP: MOVEQ #RtryPack,D7 Relative address normal retry limit MOVEQ #0,D1 Valid range lower bound MOVEQ #100,D2 Valid range upper bound * BRA.S SetNPar Join common parameter setter ********************************* SetNPar *************************** * * * Look for a number specification, then set the addressed variable. * * * * Entry conditions : D7.L Relative (to A6) address of the * * variable to set * * D1.L range specification, lower bound * * D2.L range specification, upper bound * * * * Exit conditions : none * * * *********************************************************************** SetNPar BSR ParsNm Try to get a number TST.B D1 Invalid number ? BLT.S SetNPar1 Yes, return MOVE.B D0,(A6,D7.L) No, set the parameter SetNPar1 RTS DoStPAR: LEA ParTable(PC),A1 Pointer to parity keywords table ST D1 BSR ParsKyW Look for a valid parity specification TST.B D0 Ok ? BLT.S DoStPAR1 No, return MOVE.B D0,Parity(A6) Yes, set parity to the requested value DoStPAR1 RTS DoStBCT: LEA BlCkTabl(PC),A1 Pointer to block check type table ST D1 A keyword is mandatory BSR ParsKyW Look for valid block check specification TST.B D0 Ok ? BLT.S DoStBCT1 No, return MOVE.B D0,BlChkRq(A6) Yes, set block check to requested value DoStBCT1 RTS DoStIFD: LEA IFlDTabl(PC),A1 Points to incomplete file disp table ST D1 BSR ParsKyW Look for valid disposition specification TST.B D0 Ok ? BLT.S DoStIFD1 No, return SNE Keep(A6) Yes, set the keep flag accordingly DoStIFD1 RTS DoStFNm: LEA FNamTabl(PC),A1 Points to incomplete file disp table ST D1 BSR ParsKyW Look for valid disposition specification TST.B D0 Ok ? BLT.S DoStFNm1 No, return SNE FNameCnv(A6) Yes, set conversion flag accordingly DoStFNm1 RTS DoStFDs: LEA OnOfTabl(PC),A1 Points to on/off keywords table ST D1 BSR ParsKyW Look for valid on/off specification TST.B D0 Ok ? BLT.S DoStFDs1 No, return SEQ Quiet(A6) Yes, set the quiet flag accordingly DoStFDs1 RTS DoStFTp: LEA FTypTabl(PC),A1 Points to file type keywords table ST D1 BSR ParsKyW Look for a valid file type specification TST.B D0 Ok ? BLT.S DoStFTp1 No, return SNE Binary(A6) Yes, set the binary flag accordingly DoStFTp1 RTS DoStFWn: LEA OnOfTabl(PC),A1 Points to on/off keywords table ST D1 BSR ParsKyW Look for valid on/off specification TST.B D0 Ok ? BLT.S DoStFWn1 No, return SNE Warning(A6) Yes, set the warning flag accordingly DoStFWn1 RTS DoStDUP: LEA DuplTabl(PC),A1 Points to duplex keywords table ST D1 BSR ParsKyW Look for valid duplex specification TST.B D0 Ok ? BLT.S DoStDUP1 No, return SNE Duplex(A6) Yes, set the duplex flag accordingly DoStDUP1 RTS DoStFLW: LEA FlowTabl(PC),A1 Points to flow control keywords table ST D1 BSR ParsKyW Look for valid flow specification TST.B D0 Ok ? BLT.S DoStFLW1 No, return MOVE.B D0,Flow(A6) Yes, set the flow control variable DoStFLW1 RTS DoStHND: LEA HandTabl(PC),A1 Points to handshake chars keywords table ST D1 BSR ParsKyW Look for valid handshake specification TST.B D0 Ok ? BLT.S DoStHND1 No, return SNE TurnFlag(A6) Yes, set the handshake flag accordingly MOVE.B D0,TurnChar(A6) Line turnaround character DoStHND1 RTS DoStLIN: LEA DataBuf(A6),A1 Pointer to temporary buffer MOVEA.L A1,A0 Pass it to ParsTxt BSR ParsTxt Get a text string from the command line TST.B D0 Ok ? BLT.S DoStLIN1 No, return MOVEQ #HostLine,D1 Yes, close the old line BSR FilClose MOVEQ #RdWrOp,D0 Try to open the new line MOVEQ #HostLine,D1 This is the channel number MOVEA.L A1,A0 Point to the new line name BSR FilOpen Open, if possible TST.B D0 Ok ? BEQ.S DoStLIN2 No, give error message, reopen old line LEA LineName(A6),A0 Yes, point to the line name string MOVEQ #LinNamML,D0 Max line name length BSR CopyStr Copy LEA ConLinNm(PC),A1 Point to the console line name BSR CompStr Compare the two line names TST.B D0 Are equal ? SEQ Local(A6) If not we are local, remote otherwise BEQ.S DoStLIN1 If local, leave speed unchanged MOVE.L #-1,Speed(A6) If remote, say speed unknown DoStLIN1 RTS DoStLIN2 LEA OpLnEStr(PC),A1 Point to the error message string BSR ParsErr Say that we can't open the new line LEA LineName(A6),A0 Point to the line name string MOVEQ #RdWrOp,D0 Reopen the old line MOVEQ #HostLine,D1 This is the channel number BSR FilOpen Open now RTS DoStSPE: MOVEQ #50,D1 Valid range lower bound MOVE.L #19200,D2 Valid range upper bound BSR ParsNm Try to get a valid number specification TST.B D1 Valid number on input ? BLT.S DoStSPE1 No, return BSR.S ChkBaud Check if requested speed is supported TST.B D1 Ok ? BEQ.S DoStSPE1 No, return MOVE.L D0,Speed(A6) Yes, set the baud rate variable MOVE.L D0,D2 Pass baud rate to ChanCtrl MOVEQ #HostLine,D1 Pass channel number to ChanCtrl MOVEQ #SetBaud,D0 Pass request code to ChanCtrl BSR ChanCtrl Physically set the host line baud rate DoStSPE1 RTS ChkBaud: LEA SpeedTbl(PC),A0 Pointer to baud rates table ChkBaud1 TST.L (A0) End of table ? BLT.S ChkBaud2 Yes, unsupported baud rate CMP.L (A0)+,D0 No, compare, baud rate found ? BNE.S ChkBaud1 No, loop until found or end of table ST D1 Yes, set completion code accordingly RTS ChkBaud2 LEA DataBuf(A6),A0 Point to the guilty number LEA UnsBRStr(PC),A1 Point to the error message BSR ParsErr Give error message SF D1 Return a negative completion code RTS SpeedTbl DC.L 50 DC.L 110 DC.L 150 DC.L 300 DC.L 600 DC.L 1200 DC.L 2400 DC.L 4800 DC.L 9600 DC.L 19200 DC.L 38400 DC.L -1 ends END <<< k6ocm3.asm >>> nam Kermit68K ttl REMOTE and SHOW commands subroutines module * Kermit68K: source file K68CM3 * * 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 K68Commands3,0,0,Edition,0,0 *** Code for REMOTE commands execution *** Rm1FlOp MOVE.B D0,D7 Save command LEA DataBuf(A6),A1 Pointer to temporary buffer MOVEA.L A1,A0 Pass it to ParsTxt BSR ParsTxt Get a text string from the command line TST.B D0 Remote file specified ? BLT.S Rm1FlOp1 No, give error message MOVEA.L A1,A2 Yes MOVE.B D7,D0 Restore command SUBA.L A3,A3 Terminate the SetGCmd arguments list BSR SetGCmd Setup data buffer and involved variables MOVEQ #SndSrvIS,D7 BSR KPSwtch Enter the protocol automaton switcher RTS Rm1FlOp1 LEA Rm1FOStr(PC),A0 BSR ConWrite RTS Rm2FlOp MOVE.B D0,D7 Save command LEA DataBuf(A6),A1 Pointer to temporary buffer MOVEA.L A1,A0 Pass it to ParsTxt BSR ParsWrd Get a text string from the command line TST.B D0 Remote file 1 specified ? BLT.S Rm2FlOp1 No, give error message MOVEA.L A1,A2 Yes LEA 1(A0),A1 MOVEA.L A1,A0 Pass it to ParsTxt BSR ParsTxt Get a text string from the command line TST.B D0 Remote file 2 specified ? BLT.S Rm2FlOp1 No, give error message MOVEA.L A1,A3 Yes MOVE.B D7,D0 Restore command SUBA.L A4,A4 Terminate the SetGCmd arguments list BSR SetGCmd Setup data buffer and involved variables MOVEQ #SndSrvIS,D7 BSR KPSwtch Enter the protocol automaton switcher RTS Rm2FlOp1 LEA Rm2FOStr(PC),A0 BSR ConWrite RTS *** REMOTE command *** DoREMOT: BSR ChkLocl Check mode LEA REMTable(PC),A1 Pointer to REMOTE commands table ST D1 Keyword specification is mandatory BSR ParsKyW Look for a valid REMOTE command TST.B D0 Ok ? BLT.S DoREMOT1 No, return LEA DoRemTab(PC),A1 Pointer to REMOTE jump table BRA IndxJump Join common jump routine DoREMOT1 RTS *** REMOTE COPY command *** DoRemCOP: MOVEQ #'K',D0 Copy command BSR Rm2FlOp Call the remote file operation routine RTS *** REMOTE CWD command *** DoRmCWD: SUBA.L A2,A2 No SetGCmd arguments by default LEA DataBuf(A6),A1 Pointer to temporary buffer MOVEA.L A1,A0 Pass it to ParsTxt BSR ParsTxt Get a text string from the command line TST.B D0 Remote directory specified ? BLT.S DoRmCWD1 No, no arguments MOVEA.L A1,A2 Yes SUBA.L A3,A3 Nullify next argument pointer DoRmCWD1 MOVEQ #'C',D0 Change working directory command BSR SetGCmd MOVEQ #SndGCmdS,D7 BSR KPSwtch Enter the protocol automaton switcher RTS *** REMOTE DELETE command *** DoRemDEL: MOVEQ #'E',D0 Delete command BSR Rm1FlOp Call the remote file operation routine RTS *** REMOTE DIRECTORY command *** DoRmDIR: SUBA.L A2,A2 No SetGCmd arguments by default LEA DataBuf(A6),A1 Pointer to temporary buffer MOVEA.L A1,A0 Pass it to ParsTxt BSR ParsTxt Get a text string from the command line TST.B D0 Remote file or directory specified ? BLT.S DoRmDIR1 No, no arguments MOVEA.L A1,A2 Yes SUBA.L A3,A3 Nullify next argument pointer DoRmDIR1 MOVEQ #'D',D0 Remote directory command BSR SetGCmd Setup data buffer and involved variables MOVEQ #SndSrvIS,D7 BSR KPSwtch Enter the protocol automaton switcher RTS *** REMOTE HELP command *** DoRmHELP: SUBA.L A2,A2 No arguments for SetGCmd MOVEQ #'H',D0 Remote help command BSR SetGCmd Setup data buffer and involved variables MOVEQ #SndSrvIS,D7 BSR KPSwtch Enter the protocol automaton switcher RTS *** REMOTE HOST command *** DoRemHOS: LEA DataBuf(A6),A1 MOVEA.L A1,A0 BSR ParsTxt LEA CmdBuf(A6),A0 MOVEQ #CmdBufLn,D0 BSR CopyStr BSR TrnsInit MOVE.B #'C',ServrCmd(A6) MOVEQ #SndSrvIS,D7 BSR KPSwtch Enter the protocol automaton switcher RTS *** REMOTE KERMIT command *** DoRemKER: RTS *** REMOTE PRINT command *** DoRemPRI: MOVEQ #'S',D0 BSR Rm1FlOp Call the remote file operation routine RTS *** REMOTE RENAME command *** DoRemREN: MOVEQ #'R',D0 Rename command BSR Rm2FlOp Call the remote file operation routine RTS *** REMOTE SET command *** DoRemSET: RTS *** REMOTE SPACE command *** DoRmSPA: SUBA.L A2,A2 No SetGCmd arguments by default LEA DataBuf(A6),A1 Pointer to temporary buffer MOVEA.L A1,A0 Pass it to ParsTxt BSR ParsTxt Get a text string from the command line TST.B D0 Remote directory specified ? BLT.S DoRmSPA1 No, no arguments MOVEA.L A1,A2 Yes SUBA.L A3,A3 Nullify next argument pointer DoRmSPA1 MOVEQ #'U',D0 Remote space query command BSR SetGCmd Setup for generic commands MOVEQ #SndGCmdS,D7 BSR KPSwtch Enter the protocol automaton switcher RTS *** REMOTE SUBMIT command *** DoRemSUB: MOVEQ #'P',D0 Submit command BSR Rm1FlOp Call the remote file operation routine RTS *** REMOTE TYPE command *** DoRemTYP: MOVEQ #'T',D0 Type command BSR Rm1FlOp Call the remote file operation routine RTS *** REMOTE WHO command *** DoRmWHO: SUBA.L A2,A2 No SetGCmd arguments by default LEA DataBuf(A6),A1 Pointer to temporary buffer MOVEA.L A1,A0 Pass it to ParsTxt BSR ParsTxt Get a text string from the command line TST.B D0 Remote user name specified ? BLT.S DoRmWHO1 No, no arguments MOVEA.L A1,A2 Yes SUBA.L A3,A3 Nullify next argument pointer DoRmWHO1 MOVEQ #'W',D0 Remote who command BSR SetGCmd Setup data buffer and involved variables MOVEQ #SndSrvIS,D7 BSR KPSwtch Enter the protocol automaton switcher RTS *** SHOW command *** DoSHOW: LEA SHOWTabl(PC),A1 Pointer to SHOW parameters table ST D1 BSR ParsKyW Look for a valid SHOW option TST.B D0 Ok ? BLT.S DoSHOW1 No, return LEA DoShoTab(PC),A1 Pointer to SHOW jump table BRA IndxJump Join common jump routine DoSHOW1 RTS *** SHOW VERSION command *** DoShoVer: LEA VersStr(PC),A0 Show the current Kermit68K version BSR ConWrite LEA ShVerStr(PC),A0 And then the warning BSR ConWrite RTS *** SHOW PARAMETERS command *** DoShoP: LEA ShPStr1(PC),A0 Line name BSR ConWrite LEA LineName(A6),A0 BSR ConWrite LEA ShPStr2(PC),A0 Line speed BSR ConWrite MOVE.L Speed(A6),D0 Load it BLT.S DoShoP0 Negative, unknown speed BSR TypeUNum Write the baud rate BRA.S DoShoP01 DoShoP0 LEA ShPStr3(PC),A0 Say unknown speed BSR ConWrite DoShoP01 LEA ShPStr4(PC),A0 Mode BSR ConWrite TST.B Local(A6) BEQ.S DoShoP1 LEA ShPStr5(PC),A0 BRA.S DoShoP2 DoShoP1 LEA ShPStr6(PC),A0 DoShoP2 BSR ConWrite LEA ShPStr7(PC),A0 Parity selected BSR ConWrite MOVE.B Parity(A6),D0 CMPI.B #'E',D0 BEQ.S DoShoP3 CMPI.B #'O',D0 BEQ.S DoShoP4 CMPI.B #'M',D0 BEQ.S DoShoP5 CMPI.B #'S',D0 BEQ.S DoShoP6 LEA ShPStr12(PC),A0 none BRA.S DoShoP7 DoShoP3 LEA ShPStr8(PC),A0 even BRA.S DoShoP7 DoShoP4 LEA ShPStr9(PC),A0 odd BRA.S DoShoP7 DoShoP5 LEA ShPStr10(PC),A0 mark BRA.S DoShoP7 DoShoP6 LEA ShPStr11(PC),A0 space DoShoP7 BSR ConWrite LEA ShPStr13(PC),A0 Duplex BSR ConWrite TST.B Duplex(A6) BEQ.S DoShoP8 LEA ShPStr14(PC),A0 BRA.S DoShoP9 DoShoP8 LEA ShPStr15(PC),A0 DoShoP9 BSR ConWrite LEA ShPStr16(PC),A0 Flow control BSR ConWrite MOVE.B Flow(A6),D0 BEQ.S DoShoP11 CMPI.B #1,D0 Flow(A6) BNE.S DoShoP10 LEA ShPStr17(PC),A0 BRA.S DoShoP12 DoShoP10 MOVEQ #0,D2 BSR DoShoP42 BRA.S DoShoP13 DoShoP11 LEA ShPStr12(PC),A0 DoShoP12 BSR ConWrite DoShoP13 LEA ShPStr18(PC),A0 Handshake BSR ConWrite TST.B TurnFlag(A6) BNE.S DoShoP14 LEA ShPStr12(PC),A0 BSR ConWrite BRA.S DoShoP15 DoShoP14 MOVE.B TurnChar(A6),D0 MOVEQ #0,D2 BSR DoShoP42 DoShoP15 LEA ShPStr19(PC),A0 BSR ConWrite MOVE.B TimInFlg(A6),D0 OR.B SndPSFlg(A6),D0 BEQ.S DoShoP16 LEA ShPStr20(PC),A0 BSR ConWrite DoShoP16 LEA ShPStr21(PC),A0 BSR ConWrite MOVE.B OTimInt(A6),D0 Send timeout interval BSR DoShoP40 MOVE.B ITimInt(A6),D0 Receive timeout interval BSR DoShoP41 TST.B TimInFlg(A6) BEQ.S DoShoP17 MOVEQ #'*',D0 BSR ConOut DoShoP17 LEA ShPStr22(PC),A0 BSR ConWrite MOVE.B OPadNumb(A6),D0 Send padding BSR DoShoP40 MOVE.B IPadNumb(A6),D0 Receive padding BSR DoShoP41 LEA ShPStr23(PC),A0 BSR ConWrite MOVE.B OPadChar(A6),D0 Send padding character BSR DoShoP40 MOVE.B IPadChar(A6),D0 Receive padding character BSR DoShoP41 LEA ShPStr24(PC),A0 BSR ConWrite MOVE.B OStPckCh(A6),D0 Send packet start character BSR DoShoP40 MOVE.B IStPckCh(A6),D0 Receive packet start character BSR DoShoP41 LEA ShPStr25(PC),A0 BSR ConWrite MOVE.B OEOL(A6),D0 Send End-Of-Line character BSR DoShoP40 MOVE.B IEOL(A6),D0 Receive End-Of-Line character BSR DoShoP41 LEA ShPStr26(PC),A0 BSR ConWrite MOVE.B OMPckSiz(A6),D0 Send max packet size BSR DoShoP40 TST.B SndPSFlg(A6) BEQ.S DoShoP18 MOVEQ #'*',D0 BRA.S DoShoP19 DoShoP18 MOVEQ #' ',D0 DoShoP19 BSR ConOut MOVE.B IMPckSiz(A6),D0 Receive max packet size MOVEQ #8,D2 BSR DoShoP42 LEA ShPStr27(PC),A0 BSR ConWrite MOVE.B BlChkRq(A6),D0 Block check type MOVEQ #0,D2 BSR DoShoP42 LEA ShPStr28(PC),A0 BSR ConWrite MOVE.B Delay(A6),D0 Delay MOVEQ #0,D2 BSR DoShoP42 LEA ShPStr29(PC),A0 BSR ConWrite MOVE.B RtryInit(A6),D0 Retry limit for initial connection MOVEQ #0,D2 BSR DoShoP42 LEA ShPStr30(PC),A0 BSR ConWrite MOVE.B RtryPack(A6),D0 Retry limit for normal packets MOVEQ #0,D2 BSR DoShoP42 TST.B Bit8Flag(A6) BEQ.S DoShoP20 LEA ShPStr31(PC),A0 BSR ConWrite MOVE.B Bit8Quot(A6),D0 8-th bit prefix BSR ConOut DoShoP20 TST.B ReptFlag(A6) BEQ.S DoShoP21 LEA ShPStr32(PC),A0 BSR ConWrite MOVE.B ReptQuot(A6),D0 Repeat prefix BSR ConOut DoShoP21 LEA ShPStr33(PC),A0 BSR ConWrite TST.B FNameCnv(A6) File name BEQ.S DoShoP22 LEA ShPStr34(PC),A0 BRA.S DoShoP23 DoShoP22 LEA ShPStr35(PC),A0 DoShoP23 BSR ConWrite LEA ShPStr36(PC),A0 BSR ConWrite TST.B Binary(A6) File type BEQ.S DoShoP24 LEA ShPStr37(PC),A0 BRA.S DoShoP25 DoShoP24 LEA ShPStr38(PC),A0 DoShoP25 BSR ConWrite LEA ShPStr39(PC),A0 BSR ConWrite TST.B Warning(A6) File warning BEQ.S DoShoP26 LEA ShPStr40(PC),A0 BRA.S DoShoP27 DoShoP26 LEA ShPStr41(PC),A0 DoShoP27 BSR ConWrite LEA ShPStr42(PC),A0 BSR ConWrite TST.B Quiet(A6) File display BNE.S DoShoP28 LEA ShPStr40(PC),A0 BRA.S DoShoP29 DoShoP28 LEA ShPStr41(PC),A0 DoShoP29 BSR ConWrite LEA ShPStr43(PC),A0 BSR ConWrite TST.B Keep(A6) Incomplete file disposition BEQ.S DoShoP30 LEA ShPStr44(PC),A0 BRA.S DoShoP31 DoShoP30 LEA ShPStr45(PC),A0 DoShoP31 BSR ConWrite BSR NewLine RTS DoShoP40 MOVEQ #11,D2 Use a 11 characters field BRA.S DoShoP42 Join common part DoShoP41 MOVEQ #9,D2 Use a 9 characters field DoShoP42 LEA DataBuf+34(A6),A0 Point to the end of a temporary buffer EXT.W D0 Extend to word EXT.L D0 Extend to long word ST D1 Unsigned conversion wanted MOVEQ #10,D3 Base is 10 BSR IntToAs Convert the number into a string BSR ConWrite Write the obtained string RTS ends END <<< k6ocm4.asm >>> nam Kermit68K ttl Command line parser module * Kermit68K: source file K68CM4 * * 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 K68Commands4,0,0,Edition,0,0 ********************************** CmdLnP ***************************** * * * Kermit68K command line parser. * * * * Entry conditions : none * * * * Exit conditions : none * * * *********************************************************************** CmdLnP: BSR GetCmdLP Try to get the command line pointer TST.B D0 Success ? BEQ CmdLnP10 No, return MOVEA.L A0,A5 Yes, load pointer for parser functions MOVEQ #-1,D7 Say no protocol commands yet SF D5 Set the connect before flag to false SF D6 Set the connect after flag to false CmdLnP1 LEA RecBuf(A6),A4 This pointer is used by DoCmLA MOVEA.L A4,A0 Put here the command line options BSR ParsWrd Try to get a word from command line TST.B D0 Success ? BLT.S CmdLnP2 No, exit loop CMPI.B #'-',(A4)+ Options begins with dash BNE DoCmLA4 Not an options, give usage info BSR DoCmLA Got an option, handle it BRA.S CmdLnP1 Loop until the whole line is parsed CmdLnP2 TST.B Local(A6) Are we running in local mode ? BNE.S CmdLnP4 Yes, no problem CMPI.B #SndSrvIS,D7 Are we issuing a get command ? BEQ.S CmdLnP3 Yes, fatal error MOVEQ #SndGCmdS,D7 Are we issuing a finish command ? BEQ.S CmdLnP3 Yes, fatal error TST.B D5 Are we connecting trough the host line ? BEQ.S CmdLnP4 No, all ok CmdLnP3 LEA LBReqStr(PC),A0 Give message about -l and -b need BRA FatalEr Return to system CmdLnP4 CMPI.B #SndFileS,D7 Are we sending a file ? BEQ.S CmdLnP5 Yes, set the display flag CMPI.B #RecFileS,D7 Are we receiving a file ? BEQ.S CmdLnP5 Yes, set the display flag CMPI.B #SndSrvIS,D7 Are we getting a file ? BEQ.S CmdLnP5 Yes, set the display flag TST.B Argumnt2(A6) No, has a file as-name been specified ? BEQ.S CmdLnP5 No, all is fine LEA ABadUStr(PC),A0 Yes, bad use of the -a option BRA FatalEr Give message and exit the program CmdLnP5 TST.B Local(A6) Are we running in local mode ? BEQ.S CmdLnP6 No ST Display(A6) Yes, set the display flag on CmdLnP6 TST.B TermOut(A6) Are we outputting to the terminal ? BEQ.S CmdLnP7 No SF Display(A6) Yes, set the display flag off CmdLnP7 TST.B Quiet(A6) Has quiet been requested ? BEQ.S CmdLnP8 No SF Display(A6) Yes, set the display flag off TST.B D5 Is the connect before flag on ? BEQ.S CmdLnP8 No BSR DoCONN Yes, connect to the remote host CmdLnP8 TST.B D7 We must invoke the protocol switcher ? BLT.S CmdLnP10 No, let's return BSR TrnsInit Yes, initialize any protocol thing BSR KPSwtch Enter the protocol switcher TST.B D6 Is the connect after flag on ? BEQ.S CmdLnP9 No, return the cc from the automaton BSR DoCONN Yes, connect to the remote host ST D0 Return a positive completion code CmdLnP9 BRA SysExod CmdLnP10 RTS ********************************** DoCmLA ***************************** * * * Handle command line arguments. * * * * Entry conditions : A4.L pointer to a null terminated * * string containing the command line * * argument(s) * * * * Exit conditions : none * * * *********************************************************************** DoCmLA TST.B (A4) Null option ? BEQ.S DoCmLA4 Yes, give an error message DoCmLA1 MOVE.B (A4)+,D0 Get the option letter BNE.S DoCmLA2 Not null, handle it RTS End of option bundling, return DoCmLA2 SUBI.B #97,D0 Map the option letter from zero on CMPI.B #22,D0 Above 'w' ? BHI DoCmLA4 Yes, error EXT.W D0 No, extend to word size ADD.W D0,D0 Scale by a factor of two MOVE.W DoCmLA3(PC,D0.W),D0 Load service routine relative address JMP DoCmLA3(PC,D0.W) Jump to the option service routine DoCmLA3 DC.W DoCmLA16-DoCmLA3 -a option, file as-name DC.W DoCmLA14-DoCmLA3 -b option, line baud rate DC.W DoCmLA25-DoCmLA3 -c command, connect before DC.W DoCmLA4-DoCmLA3 -d invalid DC.W DoCmLA4-DoCmLA3 -e invalid DC.W DoCmLA24-DoCmLA3 -f option, finish remote server DC.W DoCmLA23-DoCmLA3 -g command, get file(s) from server DC.W DoCmLA18-DoCmLA3 -h request, give usage informations DC.W DoCmLA7-DoCmLA3 -i option, treate files as binary DC.W DoCmLA4-DoCmLA3 -j invalid DC.W DoCmLA20-DoCmLA3 -k command, receive file(s) to terminal DC.W DoCmLA11-DoCmLA3 -l option, set communication line DC.W DoCmLA4-DoCmLA3 -m invalid DC.W DoCmLA4-DoCmLA26 -n command, connect after DC.W DoCmLA4-DoCmLA3 -o invalid DC.W DoCmLA15-DoCmLA3 -p option, communication line parity DC.W DoCmLA9-DoCmLA3 -q option, be quiet DC.W DoCmLA19-DoCmLA3 -r command, receive file(s) DC.W DoCmLA21-DoCmLA3 -s command, send file(s) DC.W DoCmLA10-DoCmLA3 -t option, line turnaround handshake DC.W DoCmLA4-DoCmLA3 -u invalid DC.W DoCmLA4-DoCmLA3 -v invalid DC.W DoCmLA8-DoCmLA3 -w option, file collisions warnings DoCmLA4 LEA InvArStr(PC),A0 No, invalid argument, fatal error BRA FatalEr DoCmLA5 LEA InvABStr(PC),A0 Invalid argument bundling, fatal error BRA FatalEr DoCmLA6 LEA CnfAcStr(PC),A0 Conflicting commands, fatal error BRA FatalEr *** -i image option *** DoCmLA7 ST Binary(A6) Treat files as binary BRA DoCmLA1 See if options are bundled *** -w warning option *** DoCmLA8 ST Warning(A6) Give file collisions warnings BRA DoCmLA1 See if options are bundled *** -q quiet option *** DoCmLA9 ST Quiet(A6) Yes, be quiet during file transfers BRA DoCmLA1 See if options are bundled *** -t line turnaround option *** DoCmLA10 ST Duplex(A6) Set half duplex on SF Flow(A6) Set flow control off ST TurnFlag(A6) Set line turnaround handshake on MOVE.B Asc_DC1,TurnChar(A6) Set XON as the turnaround character BRA DoCmLA1 See if options are bundled *** -l set line option *** DoCmLA11 TST.B (A4) Invalid argument bundling ? BNE.S DoCmLA5 Yes, error LEA DataBuf(A6),A0 No, put here the line name BSR ParsWrd Get the line name, if any TST.B D0 Has the line name been specified ? BLT.S DoCmLA12 No, error LEA DataBuf(A6),A0 Reload pointer to the parsed line name MOVEQ #RdWrOp,D0 Try to open the new line MOVEQ #HostLine,D1 This is the channel number BSR FilOpen Open, if possible TST.B D0 Ok ? BEQ.S DoCmLA13 No, give an error message LEA LineName(A6),A1 This is the line name string EXG A0,A1 Adjust pointers MOVEQ #LinNamML,D0 Maximum line name length BSR CopyStr Copy now LEA ConLinNm(PC),A1 Point to the console line name BSR CompStr Compare the two line names TST.B D0 Are equal ? SEQ Local(A6) If not we are local, remote otherwise BEQ DoCmLA1 If local, leave speed unchanged MOVE.L #-1,Speed(A6) If remote, say speed unknown RTS DoCmLA12 LEA MisLNStr(PC),A0 Give missing line name error BRA FatalEr DoCmLA13 LEA UnOpLStr(PC),A0 Give unable to open line error BRA FatalEr *** -b set line baud rate option *** DoCmLA14 TST.B (A4) Invalid argument bundling ? BNE DoCmLA5 Yes, error MOVEQ #50,D1 Valid range lower bound MOVE.L #19200,D2 Valid range upper bound BSR ParsNm Try to get a valid number specification TST.B D1 Valid number on input ? BLT FatalEr1 No, fatal error BSR ChkBaud Check if requested speed is supported TST.B D1 Ok ? BEQ FatalEr1 No, fatal error MOVE.L D0,Speed(A6) Yes, set the baud rate variable MOVE.L D0,D2 Pass baud rate to ChanCtrl MOVEQ #HostLine,D1 Pass channel number to ChanCtrl MOVEQ #SetBaud,D0 Pass request code to ChanCtrl BSR ChanCtrl Physically set the host line baud rate RTS *** -p set parity option *** DoCmLA15 TST.B (A4) Invalid argument bundling ? BNE DoCmLA5 Yes, error LEA ParTable(PC),A1 No, point to the parity keywords table ST D1 This keyword is mandatory BSR ParsKyW Look for a valid parity specification TST.B D0 Ok ? BLT FatalEr1 No, fatal error MOVE.B D0,Parity(A6) Yes, set parity to the requested value RTS *** -a file as-name option *** DoCmLA16 TST.B (A4) Invalid argument bundling ? BNE DoCmLA5 Yes, error LEA Argumnt2(A6),A0 No, put here the file as-name BSR ParsWrd Get the file as-name, if any TST.B D0 Has it been specified ? BLT.S DoCmLA17 No, error RTS DoCmLA17 LEA MsFlNStr(PC),A0 Give missing file name error message BSR FatalEr *** -h help request *** DoCmLA18 LEA UsageStr(PC),A0 Point to the usage string BSR ConWrite Write it to the terminal BRA DoCmLA1 See if options are bundled *** -r receive command *** DoCmLA19 TST.B D7 Conflicting commands ? BGE DoCmLA6 Yes, error MOVEQ #RecInitS,D7 Start state for the protocol automaton BRA DoCmLA1 See if options are bundled *** -k receive to terminal command *** DoCmLA20 TST.B D7 Conflicting commands ? BGE DoCmLA6 Yes, error ST TermOut(A6) We want output to the terminal line MOVEQ #RecInitS,D7 Start state for the protocol automaton BRA DoCmLA1 See if options are bundled *** -s send command *** DoCmLA21 TST.B D7 Conflicting commands ? BGE DoCmLA6 Yes, error TST.B (A4) Invalid argument bundling ? BNE DoCmLA5 Yes, error LEA Argumnt1(A6),A0 Point to file name string BSR ParsInF Try to get a valid input file name TST.B D0 Some error ? BLT.S DoCmLA22 Yes MOVEQ #SndInitS,D7 No, Send-Init is the start state RTS DoCmLA22 CMPI.B #-3,D0 Has a file name been specified ? BEQ.S DoCmLA17 No, give missing file name message RTS Yes, message already given, return *** -g get command *** DoCmLA23 TST.B D7 Conflicting commands ? BGE DoCmLA6 Yes, error TST.B (A4) Invalid argument bundling ? BNE DoCmLA5 Yes, error LEA Argumnt1(A6),A0 Point to file name string BSR ParsWrd Try to get a file name TST.B D0 Missing file name ? BLT.S DoCmLA17 Yes, give error message MOVE.B #'R',ServrCmd(A6) Get command MOVEQ #SndSrvIS,D7 Send-Server-Init is the start state RTS *** -f finish command *** DoCmLA24 TST.B D7 Conflicting commands ? BGE DoCmLA6 Yes, error SUBA.L A2,A2 No arguments for SetGCmd MOVEQ #'F',D0 Finish server command BSR SetGCmd Set up for generic commands MOVEQ #SndGCmdS,D7 BRA DoCmLA1 See if options are bundled *** -c connect before *** DoCmLA25 ST D5 Set the connect before flag on BRA DoCmLA1 See if options are bundled *** -n connect after *** DoCmLA26 ST D6 Set the connect after flag on BRA DoCmLA1 See if options are bundled FatalEr BSR ConWrite Write the message FatalEr1 SF D0 Set a bad completion code BRA SysExod Return it to system ends END <<< k6ocmd.asm >>> nam Kermit68K ttl Top-level commands subroutines module * Kermit68K: source file K68CMD * * 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 K68Commands,0,0,Edition,0,0 ********************************** Parser *****************************ok * * * Kermit68K interactive command parser. * * * * Entry conditions : none * * * * Exit conditions : D1.B destroyed * * A0.L destroyed * * * *********************************************************************** Parser: LEA VersStr(PC),A0 Give version informations BSR ConWrite Parser1 TST.B IntMacro(A6) Are we interpreting a macro ? BEQ.S Parser2 No, see if we are interpreting a file BSR McCmdIn Yes, get the next line of the macro TST.B D0 End of macro ? BNE.S Parser4 No, join the common part SF IntMacro(A6) Yes, we're no longer interpreting a macro Parser2 MOVE.B TakLevel(A6),D1 Are we interpreting a take file ? BLT.S Parser3 No, get a command from terminal ADD.B #TakeFil0,D1 Yes, compute its channel number BSR FlCmdIn Get a command line from file TST.B D0 End of file ? BNE.S Parser4 No, join the common part MOVE.B TakLevel(A6),D1 Yes, compute the file channel number ADD.B #TakeFil0,D1 Add this offset BSR FilClose Close it SUBQ.B #1,TakLevel(A6) Continue with outer take file, if any BRA.S Parser1 Parser3 LEA Prompt(A6),A0 Point to the prompt string BSR ConWrite Write it BSR CCmdIn Input a command line TST.B D0 EOF ? SEQ Done(A6) Set the termination flag accordingly BSR NewLine Start a new line Parser4 SF Display(A6) Turn off the display flag LEA CmdBuf(A6),A0 Command to parse is here BSR DoCommd Parse command and execute it TST.B Done(A6) Done ? BEQ.S Parser1 No, stay in loop RTS Yes, return to main ********************************** DoCommd ****************************ok * * * Main switcher for commands execution. * * * * Entry conditions : A0.L points to the command line * * * * Exit conditions : D1.B destroyed * * A1.L destroyed * * * *********************************************************************** DoCommd MOVEA.L A0,A5 This is the pointer to command line TST.B IntMacro(A6) Are we interpreting a macro ? BNE.S DoCommd6 Yes, don't search in macro table MOVE.L A5,-(A7) No, save the pointer to command line LEA Argumnt1(A6),A0 Put here the command verb, if any BSR ParsWrd Try to get the command verb TST.B D0 Success ? BLT.S DoCommd2 No, return LEA Argumnt1(A6),A0 Yes, here is the macro name to find BSR MacFind Search this name in macro table TST.B D0 Found ? BEQ.S DoCommd4 No, search in command table DoCommd1 TST.B (A0)+ Yes, skip the macro name BNE.S DoCommd1 Loop until end of macro name MOVE.L A0,MacroPnt(A6) Setup this pointer for reading the macro ST IntMacro(A6) NOW we are intepreting a macro ! DoCommd2 ADDQ.L #4,A7 Remove the line pointer from stack DoCommd3 RTS DoCommd4 MOVE.L (A7)+,A5 Restore the pointer to command line DoCommd6 LEA CmdTable(PC),A1 Pointer to command table SF D1 The command verb is not mandatory BSR ParsKyW Look for a valid command verb TST.B D0 Ok ? BLT.S DoCommd3 No, return LEA DoCmdTab(PC),A1 Start of jump table BRA IndxJump Jump to appropriate command handler *** Code for top level commands execution *** ChkLocl: TST.B Local(A6) Are we running in local mode ? BNE.S ChkLocl1 Yes, all ok LEA StLnFStr(PC),A0 No, load pointer to the error message BSR ConWrite Give error message ADDQ.L #4,A7 Remove caller's return address ChkLocl1 RTS DoBYE: BSR ChkLocl Check mode SUBA.L A2,A2 No arguments for SetGCmd MOVEQ #'L',D0 Logout command BSR SetGCmd Setup for generic commands MOVEQ #SndGCmdS,D7 BSR KPSwtch Enter the protocol automaton switcher RTS *** % command (Treat the rest of the line as a comment) *** DoCOMMNT: LEA DataBuf(A6),A0 Pointer to temporary buffer BSR ParsWrd Get a word from the command line TST.B D0 End of line ? BGE.S DoCOMMNT No, continue RTS Yes, return *** CONNECT command *** DoCONN: BSR ChkLocl Check mode TST.L Speed(A6) Is line speed setted ? BGT.S DoCONN1 Yes, continue LEA StSpeStr(PC),A0 No, give error message and return BSR ConWrite RTS DoCONN1 LEA ConnStr1(PC),A0 Yes, give the start of connection message BSR ConWrite LEA LineName(A6),A0 Write the line name BSR ConWrite LEA ConnStr3(PC),A0 Line speed BSR ConWrite MOVE.L Speed(A6),D0 Load speed BSR TypeUNum Write the baud rate LEA ConnStr5(PC),A0 Escape character BSR ConWrite MOVE.B Escape(A6),D0 Get the escape character CMPI.B #' ',D0 Printable character ? BGE.S DoCONN3 Yes, print it out ADDI.B #64,D0 Make it printable MOVEQ #'^',D2 Prefix character for control EXG D0,D2 Exchange BSR ConOut Output prefix EXG D0,D2 Exchange DoCONN3 BSR ConOut Output character MOVEQ #' ',D0 Write a blank BSR ConOut MOVEQ #'(',D0 Write an open parenthesis BSR ConOut MOVEQ #0,D0 Write the ASCII code of the escape char MOVE.B Escape(A6),D0 BSR TypeUNum LEA ConnStr6(PC),A0 Close the parenthesis and give some info BSR ConWrite MOVEQ #TextMode,D0 Put line in text mode MOVEQ #HostLine,D1 BSR ChanCtrl CMPI.B #AllOk,D0 All ok ? BEQ.S DoCONN4 Yes, enter the connect loop LEA CCndLStr(PC),A0 No, point to the error message BSR ConWrite Write it on the screen RTS DoCONN4 MOVEQ #Terminal,D1 Try to get a character from terminal BSR InpChar TST.B D1 Character received ? BNE DoCONN14 No, look at the host line CMP.B Escape(A6),D0 Escape character ? BNE DoCONN13 No BSR ConInp Get a single character command MOVE.B D0,D3 Uppercase it BSR UppCase CMPI.B #'C',D3 Close command ? BEQ DoCONN12 Yes CMPI.B #'?',D3 Help command ? BNE.S DoCONN5 No LEA ConnStr8(PC),A0 Yes, give the help message BSR ConWrite BRA DoCONN14 DoCONN5 CMPI.B #'0',D3 Send null command ? BNE.S DoCONN6 No MOVEQ #0,D0 Yes, obey it BSR HostOut BRA.S DoCONN14 DoCONN6 CMPI.B #'B',D3 Send break command ? BNE.S DoCONN7 MOVEQ #SndBreak,D0 Request code MOVEQ #HostLine,D1 Logical channel number BSR ChanCtrl Call the channel control routine BRA.S DoCONN14 DoCONN7 CMPI.B #'S',D3 Show status command ? BNE.S DoCONN9 No LEA ConnStr2(PC),A0 Yes, show the communication status BSR ConWrite LEA LineName(A6),A0 Write the line name BSR ConWrite LEA ConnStr3(PC),A0 Write the line speed BSR ConWrite MOVE.L Speed(A6),D0 Load speed BSR TypeUNum Write the baud rate BSR NewLine Start a new line BRA.S DoCONN14 DoCONN9 CMPI.B #'H',D3 Hangup and close command ? BNE.S DoCONN10 No * * Place code for hangup here * BRA.S DoCONN12 Close the connection DoCONN10 CMP.B Escape(A6),D3 Escape character again ? BNE.S DoCONN11 No MOVE.B Escape(A6),D0 Yes, send it BSR HostOut BRA.S DoCONN14 DoCONN11 MOVEQ #Asc_Bel,D0 Invalid command, ring bell BSR ConOut BRA.S DoCONN14 DoCONN12 LEA ConnStr7(PC),A0 Yes, give the end of connection message BSR ConWrite RTS Exit from transparent mode DoCONN13 BSR HostOut Output the character just received TST.B Duplex(A6) Half duplex ? BEQ.S DoCONN14 No BSR ConOut Yes, echo the character to the terminal DoCONN14 MOVEQ #HostLine,D1 Try to get a character from host BSR InpChar TST.B D1 Character received ? BNE DoCONN4 No, look at the terminal line BSR HndlPar Yes, handle the parity bit BSR ConOut Output the character just received BRA DoCONN4 *** (Local) COPY command *** DoCOPY: LEA Argumnt1(A6),A0 Source file specification BSR ParsWrd Get it, if any LEA Argumnt2(A6),A0 Target file specification BSR ParsTxt Get it, if any LEA Argumnt1(A6),A0 Pass arguments addresses ... LEA Argumnt2(A6),A1 ... to the System subroutine MOVEQ #CopyFile,D0 Copy file system function wanted BSR System Call the external handler LEA NoCopStr(PC),A0 This is the "on failure" error message BRA CSysErr Check cc and, on failure, give message *** (Local) CWD command *** DoCWD: LEA Argumnt1(A6),A0 Directory specification BSR ParsTxt Get it, if any LEA Argumnt1(A6),A0 Pass argument address to System MOVEQ #ChangDir,D0 Change working directory function BSR System Call the external handler LEA NoCWDStr(PC),A0 This is the "on failure" error message BRA CSysErr Check cc and, on failure, give message *** DEFINE command *** DoDEFN: TST.B IntMacro(A6) Are we interpreting from a macro ? BNE DoDEFN11 Yes, error LEA Argumnt1(A6),A0 Put here the macro name, if any BSR ParsWrd Try to get it TST.B D0 Success ? BLT DoLIST3 No, notify that macro name is missing LEA Argumnt1(A6),A0 Yes, point to the parsed macro name BSR MacFind Check if this macro is already defined TST.B D0 Found ? BEQ.S DoDEFN4 No, create it * Yes, erase it from macro table DoDEFN1 MOVEA.L A0,A1 Macro definition start address BSR MacSkip Skip to end of macro body TST.B D0 It was the last one ? BNE.S DoDEFN3 Yes, simply adjust pointer to table end MOVE.L MTNxtChF(A6),D0 No, load address of the next byte free DoDEFN2 MOVE.B (A1)+,(A0)+ Shift the macro table CMP.L A1,D0 At end of macro table ? BNE.S DoDEFN2 No, stay in loop DoDEFN3 MOVE.L A0,MTNxtChF(A6) Next byte free in macro table is here DoDEFN4 LEA Argumnt1(A6),A1 Point to the parsed macro name DoDEFN5 MOVE.B (A1)+,(A0)+ Store the macro name in macro table BNE.S DoDEFN5 Loop until end of macro name BSR ParsTxt Try to get a one-line macro body TST.B D0 Success ? BLT.S DoDEFN6 No, it's a multi-line macro ADDQ.L #1,A0 Yes, skip the termination null BRA.S DoDEFN10 Adjust the end pointer and return DoDEFN6 MOVE.L A0,-(A7) Save the pointer to the macro table MOVE.B TakLevel(A6),D1 Are we defining from a take file ? BLT.S DoDEFN7 No, get next macro line from terminal ADD.B #TakeFil0,D1 Yes, compute its channel number BSR FlCmdIn Get the next macro line from file TST.B D0 End of file ? BEQ.S DoDEFN9 Yes, end of macro body SF D2 No, set the termination flag to false BNE.S DoDEFN8 Join the common part DoDEFN7 BSR CCmdIn Get another line of text from terminal TST.B D0 EOF on input ? SEQ D2 Set the termination flag accordingly BSR NewLine Start a new line on the terminal DoDEFN8 LEA CmdBuf(A6),A5 The macro line is here MOVE.L (A7)+,A0 Restore the pointer to the macro table BSR ParsTxt Try to get it into the macro table MOVE.B #Asc_CR,(A0)+ Terminate the line whit a CR TST.B D0 The line was null ? BLT.S DoDEFN9 Yes, this is an end condition TST.B D2 Is the termination flag true ? BEQ.S DoDEFN6 No, continue entering macro lines DoDEFN9 CLR.B -1(A0) Null terminate the macro body DoDEFN10 MOVE.L A0,MTNxtChF(A6) Update next byte free in macro table RTS DoDEFN11 SUBA.L A0,A0 No guilty LEA MNstAStr(PC),A1 Error message, can't nest macros BSR ParsErr Write it RTS *** (Local) DELETE command *** DoDELETE: LEA Argumnt1(A6),A0 File to delete specification BSR ParsTxt Get it, if any LEA Argumnt1(A6),A0 Pass argument address to System MOVEQ #DeletFil,D0 Delete file function wanted BSR System Call the external handler LEA NoDelStr(PC),A0 This is the "on failure" error message BRA CSysErr Check cc and, on failure, give message *** (Local) DIRECTORY command *** DoDIR: LEA Argumnt1(A6),A0 File or directory specification BSR ParsTxt Get it, if any LEA Argumnt1(A6),A0 Pass argument address to System MOVEQ #Directry,D0 Directory function wanted BSR System Call the external handler LEA NoDirStr(PC),A0 This is the "on failure" error message BRA CSysErr Check cc and, on failure, give message *** ECHO command *** DoECHO: LEA DataBuf(A6),A1 Pointer to temporary buffer MOVEA.L A1,A0 Pass it to ParsTxt BSR ParsTxt Get a text string from the command line TST.B D0 Ok ? BLT.S DoECHO1 No, return MOVEA.L A1,A0 Reload pointer BSR ConWrite Write the string to the terminal line BSR NewLine Start a new line DoECHO1 RTS *** EXIT command *** DoEXIT: ST Done(A6) Set the termination flag RTS *** FINISH command *** DoFINISH: BSR ChkLocl Check mode SUBA.L A2,A2 No arguments for SetGCmd MOVEQ #'F',D0 Finish server command BSR SetGCmd Set up for generic commands MOVEQ #SndGCmdS,D7 BSR KPSwtch Enter the protocol automaton switcher RTS *** GET command *** DoGET: BSR ChkLocl Check mode LEA Argumnt1(A6),A0 Point to file name string BSR ParsWrd Try to get a file name TST.B D0 Missing file name ? BLT.S DoGET1 Yes, give error message LEA Argumnt2(A6),A0 Point to file as-name string BSR ParsOuF Look for a valid output file name LEA CmdBuf(A6),A0 Put here the file name LEA Argumnt1(A6),A1 Copy from here MOVEQ #CmdBufLn,D0 Buffers length BSR CopyStr Copy now TST.B Local(A6) Are we in local mode ? SNE Display(A6) Set transaction display flag accordingly BSR TrnsInit Initialize transaction related variables MOVE.B #'R',ServrCmd(A6) Get command MOVEQ #SndSrvIS,D7 Send-Server-Init is the start state BSR KPSwtch Enter protocol switcher RTS DoGET1 SUBA.L A0,A0 No guilty LEA MsFSpStr(PC),A1 Point to error message BSR ParsErr Write it RTS *** HELP command *** ScrnMxLL EQU 78 ColumnLn EQU 12 DoHELP: LEA KerCmStr(PC),A0 Write introduction to Kermit68K commands BSR ConWrite LEA CmdTable(PC),A0 Point to top-level commands table start CLR.B D2 Initialize the line length counter DoHELP1 MOVE.B (A0)+,D0 Get a character from command table CMP.B #-1,D0 End of table ? BEQ.S DoHELP2 Yes, now write macro names BSR.S DoHELP5 No, write the command name BRA.S DoHELP1 Loop until end of table DoHELP2 BSR NewLine Start a new line on the screen CLR.B D2 Re-initialize the line length counter LEA MacroTbl(A6),A1 Load start address of macro table CMPA.L MTNxtChF(A6),A1 The macro table is empty ? BEQ.S DoHELP4 Yes, notify this and return LEA MacCmStr(PC),A0 No, write introduction to user macros BSR ConWrite DoHELP3 MOVEA.L A1,A0 Now A0 points to tha macro name BSR.S DoHELP5 Write the macro name BSR MacSkip Skip to next macro name TST.B D0 The previous was the last macro ? BEQ.S DoHELP3 No, so write this one BSR NewLine Yes, start a new line and return RTS DoHELP4 LEA NoMacStr(PC),A0 Say that there are no user macros BSR ConWrite RTS DoHELP5 MOVEQ #ColumnLn,D3 Initialize the column length counter DoHELP6 MOVE.B (A0)+,D0 Get a character from the source string BEQ.S DoHELP7 End of name, write separators BSR ConOut Output this character ADDQ.B #1,D2 Count it SUBQ.B #1,D3 Decrement the column length counter BEQ.S DoHELP5 If zero reload it BRA.S DoHELP6 Loop until end of name DoHELP7 CMPI.B #ScrnMxLL-ColumnLn,D2 There is room for another column ? BGT.S DoHELP9 No, start a new line on the screen MOVEQ #' ',D0 Yes, let's pad the column with blanks DoHELP8 BSR ConOut Write one blank ADDQ.B #1,D2 Count it SUBQ.B #1,D3 At end of column ? BNE.S DoHELP8 No, repeat RTS DoHELP9 BSR NewLine Start a new line on the terminal screen CLR.B D2 Re-initialize the line length counter RTS *** LIST command *** DoLIST: LEA Argumnt1(A6),A0 Put here the macro name, if any BSR ParsWrd Try to get the macro name TST.B D0 Success ? BLT.S DoLIST3 No, give error and return LEA Argumnt1(A6),A0 Yes, point to the parsed macro name BSR MacFind Search it in the macro table TST.B D0 Found ? BEQ.S DoLIST4 No, give error and return DoLIST0 TST.B (A0)+ Skip the macro name BNE.S DoLIST0 DoLIST1 MOVE.B (A0)+,D0 Type the macro body, get a character BEQ.S DoLIST2 End of macro body, exit BSR ConOut Output the character just read CMPI.B #Asc_CR,D0 It was a carriage return ? BNE.S DoLIST1 No, continue MOVEQ #Asc_LF,D0 Yes, output a line feed BSR ConOut BRA.S DoLIST1 Stay in loop DoLIST2 BSR NewLine Start a new line on the terminal RTS DoLIST3 SUBA.L A0,A0 No guilty LEA MsMcNStr(PC),A1 Error message, missing macro name BSR ParsErr Write it RTS DoLIST4 LEA Argumnt1(A6),A0 Here is the guilty word LEA UnkMcStr(PC),A1 Error message, macro not found BSR ParsErr Write it RTS *** PRINT command *** DoPRINT: LEA Argumnt1(A6),A0 File to print specification BSR ParsTxt Get it, if any LEA Argumnt1(A6),A0 Pass argument address to System MOVEQ #PrntFile,D0 Print file function wanted BSR System Call the external handler LEA NoPriStr(PC),A0 This is the "on failure" error message BRA CSysErr Check cc and, on failure, give message *** RECEIVE command *** DoRECVE: LEA Argumnt2(A6),A0 Point to file as-name string BSR ParsOuF Look for a valid output file name TST.B D0 Ok ? BGE.S DoRECVE1 Yes, file must be stored under this name CMPI.B #-3,D0 Missing file specification ? BEQ.S DoRECVE1 Yes, no problem RTS No, some other error, return DoRECVE1 TST.B Local(A6) Are we in local mode ? SNE Display(A6) Set transaction display flag accordingly BSR TrnsInit Setup transaction related variables MOVEQ #RecInitS,D7 Receive-Init is the start state BSR KPSwtch Enter protocol switcher RTS *** RENAME command *** DoRENAME: LEA Argumnt1(A6),A0 Old file name specification BSR ParsWrd Get it, if any LEA Argumnt2(A6),A0 New file name specification BSR ParsTxt Get it, if any LEA Argumnt1(A6),A0 Pass arguments addresses ... LEA Argumnt2(A6),A1 ... to the System subroutine MOVEQ #RenamFil,D0 Rename file function wanted BSR System Call the external handler LEA NoRenStr(PC),A0 This is the "on failure" error message BRA CSysErr Check cc and, on failure, give message *** SEND command *** DoSEND: LEA Argumnt1(A6),A0 Point to file name string BSR ParsInF Try to get a valid input file name TST.B D0 Some error ? BLT.S DoSEND1 Yes, handle it LEA Argumnt2(A6),A0 Point to file as-name string BSR ParsTxt Try to get an as name for this file TST.B Local(A6) Are we in local mode ? SNE Display(A6) Set transaction display flag accordingly BSR TrnsInit Initialize transaction related variables MOVEQ #SndInitS,D7 Send-Init is the start state BSR KPSwtch Enter protocol switcher RTS DoSEND1 CMPI.B #-3,D0 Missing file specification ? BNE.S DoSEND2 No, error already given SUBA.L A0,A0 No guilty LEA MsFSpStr(PC),A1 Point to error message BSR ParsErr Write it DoSEND2 RTS *** (Local) SPACE command *** DoSPACE: LEA Argumnt1(A6),A0 Directory or device specification BSR ParsTxt Get it, if any LEA Argumnt1(A6),A0 Pass argument address to System MOVEQ #SpacInfo,D0 Disk usage query function wanted BSR System Call the external handler LEA NoSpaStr(PC),A0 This is the "on failure" error message BRA CSysErr Check cc and, on failure, give message *** STATISTICS command *** DoSTATS: LEA StatStr1(PC),A0 Header line and characters sent string MOVE.L ChrsSent(A6),D6 Characters sent this transaction MOVE.L TChsSent(A6),D7 Total characters sent BSR.S DoSTATS1 Display this LEA StatStr2(PC),A0 Data characters sent string MOVE.L DChsSent(A6),D6 Data characters sent this transaction MOVE.L TDChSent(A6),D7 Total data characters sent BSR.S DoSTATS1 Display this LEA StatStr3(PC),A0 NAKs received string MOVE.L NAKsRecd(A6),D6 NAKs received this transaction MOVE.L TNAKRecd(A6),D7 Total NAKs received BSR.S DoSTATS1 Display this LEA StatStr4(PC),A0 Packets sent string MOVE.L PcksSent(A6),D6 Packets sent this transaction MOVE.L TPckSent(A6),D7 Total packets sent BSR.S DoSTATS1 Display this LEA StatStr5(PC),A0 Characters received string MOVE.L ChrsRecd(A6),D6 Characters received this transaction MOVE.L TChsRecd(A6),D7 Total characters received BSR.S DoSTATS1 Display this LEA StatStr6(PC),A0 Data characters received string MOVE.L DChsRecd(A6),D6 Data characters received this transaction MOVE.L TDChRecd(A6),D7 Total data characters received BSR.S DoSTATS1 Display this LEA StatStr7(PC),A0 NAKs received string MOVE.L NAKsSent(A6),D6 NAKs sent this transaction MOVE.L TNAKSent(A6),D7 Total NAKs sent BSR.S DoSTATS1 Display this LEA StatStr8(PC),A0 Packets received string MOVE.L PcksRecd(A6),D6 Packets received this transaction MOVE.L TPckRecd(A6),D7 Total packets received BSR.S DoSTATS1 Display this RTS DoSTATS1 BSR ConWrite Write the string MOVE.L D6,D0 Total for last transaction BSR.S DoSTATS2 Write number MOVE.L D7,D0 Total since start of Krmit68K BSR.S DoSTATS2 Write number BSR NewLine Start a new line RTS DoSTATS2 SF D1 Unsigned conversion wanted MOVEQ #12,D2 Field length MOVEQ #10,D3 Base 10 LEA DataBuf+34(A6),A0 Point to the end of a temporary buffer BSR IntToAs Convert the number into a string BSR ConWrite Write the obtained string RTS *** % command (Forward the rest of line to system command processor) *** DoSYSCMD: LEA Argumnt1(A6),A0 Put here the system command BSR ParsTxt Get it, if any LEA Argumnt1(A6),A0 Pass argument address to System MOVEQ #SysCommd,D0 System command function wanted BSR System Call the external handler LEA NoSyCStr(PC),A0 This is the "on failure" error message BRA CSysErr Check cc and, on failure, give message *** TAKE command *** DoTAKE: CMPI.B #MaxTakeF,TakLevel(A6) Take level number at our limit ? BEQ.S DoTAKE1 Yes, give error and return LEA Argumnt1(A6),A0 Point to the file name buffer BSR ParsInF Try to get a valid input file name TST.B D0 Some error ? BLT.S DoTAKE2 Yes BSR ChkWild Check the specified file name TST.B D0 Wildcarded name ? BNE.S DoTAKE4 Yes, give error and return MOVE.B TakLevel(A6),D1 Get the take level number ADDQ.B #1,D1 Increment this temporary variable ADD.B #TakeFil0,D1 Compute the new file channel number MOVEQ #ReadOp,D0 We want open the file for input BSR FilOpen Open the new take file * * Warning, the cc is not checked !!! * ADDQ.B #1,TakLevel(A6) Finally increment the take level RTS DoTAKE1 LEA TFNDpStr(PC),A1 Say take file nested too deeply SUBA.L A0,A0 No guilty word BSR ParsErr Call the error messages routine RTS DoTAKE2 CMPI.B #-3,D0 Has a file name been specified ? BNE.S DoTAKE3 Yes, message already given, return LEA MsFSpStr(PC),A1 Give missing file specification error SUBA.L A0,A0 No guilty word BSR ParsErr Write the error message DoTAKE3 RTS DoTAKE4 LEA POuFStr1(PC),A1 Give illegal wildcard error message BSR ParsErr Call the error messages routine RTS *** (Local) TYPE command *** DoTYPE: LEA Argumnt1(A6),A0 File to type specification BSR ParsTxt Get it, if any LEA Argumnt1(A6),A0 Pass argument address to System MOVEQ #TypeFile,D0 Type file function wanted BSR System Call the external handler LEA NoTypStr(PC),A0 This is the "on failure" error message * BRA CSysErr Check cc and, on failure, give message CSysErr TST.B D0 System operation failed ? BNE.S CSysErr1 No, return BSR ConWrite Yes, write corresponding error message BSR NewLine Start a new line CSysErr1 RTS ends END <<< k6octb.asm >>> nam Kermit68K ttl Commands keywords tables module * Kermit68K: source file K68CTB * * 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 K68CmdTables,0,0,Edition,0,0 * Values associated with top-level commands. CmdBYE EQU 0 BYE CmdCONCT EQU 1 CONNECT CmdCOPY EQU 2 COPY CmdCWD EQU 3 CWD (Change Working Directory) CmdDEFIN EQU 4 DEFINE (a command macro) CmdDELET EQU 5 (Local) DELETE CmdDIR EQU 6 (Local) DIRECTORY CmdECHO EQU 7 ECHO CmdEXIT EQU 8 EXIT CmdFINSH EQU 9 FINISH CmdGET EQU 10 GET CmdHELP EQU 11 HELP CmdLIST EQU 12 LIST CmdPRINT EQU 13 (Local) PRINT CmdRCEIV EQU 14 RECEIVE CmdREMOT EQU 15 REMOTE CmdRENAM EQU 16 (Local) RENAME CmdSEND EQU 17 SEND CmdSET EQU 18 SET CmdSHOW EQU 19 SHOW CmdSPACE EQU 20 (Local) SPACE CmdSTATS EQU 21 STATISTICS CmdTAKE EQU 22 TAKE CmdTYPE EQU 23 (Local) TYPE CmdCOMMN EQU 24 Comment CmdSYSC EQU 25 System command * Top-level commands string table. CmdTable: DC.B CmdBYE,"BYE",Asc_Nul DC.B CmdCONCT,"C",Asc_Nul DC.B CmdCONCT,"CONNECT",Asc_Nul DC.B CmdCOPY,"COPY",Asc_Nul DC.B CmdCWD,"CWD",Asc_Nul DC.B CmdDEFIN,"DEFINE",Asc_Nul DC.B CmdDELET,"DELETE",Asc_Nul DC.B CmdDIR,"DIRECTORY",Asc_Nul DC.B CmdECHO,"ECHO",Asc_Nul DC.B CmdEXIT,"EXIT",Asc_Nul DC.B CmdFINSH,"FINISH",Asc_Nul DC.B CmdGET,"GET",Asc_Nul DC.B CmdHELP,"HELP",Asc_Nul DC.B CmdLIST,"LIST",Asc_Nul DC.B CmdPRINT,"PRINT",Asc_Nul DC.B CmdEXIT,"QUIT",Asc_Nul DC.B CmdRCEIV,"R",Asc_Nul DC.B CmdRCEIV,"RECEIVE",Asc_Nul DC.B CmdREMOT,"REMOTE",Asc_Nul DC.B CmdRENAM,"RENAME",Asc_Nul DC.B CmdSEND,"S",Asc_Nul DC.B CmdSEND,"SEND",Asc_Nul DC.B CmdSET,"SET",Asc_Nul DC.B CmdSHOW,"SHOW",Asc_Nul DC.B CmdSPACE,"SPACE",Asc_Nul DC.B CmdSTATS,"STATISTICS",Asc_Nul DC.B CmdTAKE,"TAKE",Asc_Nul DC.B CmdTYPE,"TYPE",Asc_Nul DC.B CmdCOMMN,"%",Asc_Nul DC.B CmdSYSC,"!",Asc_Nul DC.B -1 DC.B "command verb",Asc_Nul * Top-level commands jump table. DoCmdTab: DC.W DoBYE-DoCmdTab CmdBYE DC.W DoCONN-DoCmdTab CmdCONCT DC.W DoCOPY-DoCmdTab CmdCOPY DC.W DoCWD-DoCmdTab CmdCWD DC.W DoDEFN-DoCmdTab CmdDEFIN DC.W DoDELETE-DoCmdTab CmdDELET DC.W DoDIR-DoCmdTab CmdDIR DC.W DoECHO-DoCmdTab CmdECHO DC.W DoEXIT-DoCmdTab CmdEXIT DC.W DoFINISH-DoCmdTab CmdFINSH DC.W DoGET-DoCmdTab CmdGET DC.W DoHELP-DoCmdTab CmdHELP DC.W DoLIST-DoCmdTab CmdLIST DC.W DoPRINT-DoCmdTab CmdPRINT DC.W DoRECVE-DoCmdTab CmdRCEIV DC.W DoREMOT-DoCmdTab CmdREMOT DC.W DoRENAME-DoCmdTab CmdRENAM DC.W DoSEND-DoCmdTab CmdSEND DC.W DoSET-DoCmdTab CmdSET DC.W DoSHOW-DoCmdTab CmdSHOW DC.W DoSPACE-DoCmdTab CmdSPACE DC.W DoSTATS-DoCmdTab CmdSTATS DC.W DoTAKE-DoCmdTab CmdTAKE DC.W DoTYPE-DoCmdTab CmdTYPE DC.W DoCOMMNT-DoCmdTab CmdCOMMN DC.W DoSYSCMD-DoCmdTab CmdSYSC * Values associated with SET command qualifiers. SetBCHKT EQU 0 Block check type SetDELAY EQU 1 Delay SetDUPLX EQU 2 Duplex SetESCAP EQU 3 Escape character SetFILE EQU 4 File Parameters SetFLOW EQU 5 Flow Control SetHNDSH EQU 6 Handshake SetINCFD EQU 7 Incomplete File Disposition SetLINE EQU 8 Communication line to use SetPRITY EQU 9 Parity SetPRMPT EQU 10 Program prompt string SetRETRY EQU 11 Retry limits SetSPEED EQU 12 Line speed (baud rate) SetSEND EQU 13 SEND parameters SetRCEIV EQU 14 RECEIVE parameters * SET command qualifiers string table. SETTable: DC.B SetSPEED,"BAUD",Asc_Nul DC.B SetBCHKT,"BLOCK_CHECK_TYPE",Asc_Nul DC.B SetDELAY,"DELAY",Asc_Nul DC.B SetDUPLX,"DUPLEX",Asc_Nul DC.B SetESCAP,"ESCAPE_CHARACTER",Asc_Nul DC.B SetFILE,"FILE",Asc_Nul DC.B SetFLOW,"FLOW_CONTROL",Asc_Nul DC.B SetHNDSH,"HANDSHAKE",Asc_Nul DC.B SetINCFD,"INCOMPLETE_FILE_DISPOSITION",Asc_Nul DC.B SetLINE,"LINE",Asc_Nul DC.B SetPRITY,"PARITY",Asc_Nul DC.B SetPRMPT,"PROMPT",Asc_Nul DC.B SetRCEIV,"RECEIVE",Asc_Nul DC.B SetRETRY,"RETRY",Asc_Nul DC.B SetSEND,"SEND",Asc_Nul DC.B SetSPEED,"SPEED",Asc_Nul DC.B -1 DC.B "SET option or parameter",Asc_Nul * SET command qualifiers jump table. DoSetTab: DC.W DoStBCT-DoSetTab SetBCHKT DC.W DoStDLAY-DoSetTab SetDELAY DC.W DoStDUP-DoSetTab SetDUPLX DC.W DoSetESC-DoSetTab SetESCAP DC.W DoSFILE-DoSetTab SetFILE DC.W DoStFLW-DoSetTab SetFLOW DC.W DoStHND-DoSetTab SetHNDSH DC.W DoStIFD-DoSetTab SetINCFD DC.W DoStLIN-DoSetTab SetLINE DC.W DoStPAR-DoSetTab SetPRITY DC.W DoStPRM-DoSetTab SetPRMPT DC.W DoSRTRY-DoSetTab SetRETRY DC.W DoStSPE-DoSetTab SetSPEED DC.W DoSSEND-DoSetTab SetSEND DC.W DoSRECV-DoSetTab SetRCEIV * Values associated with SET SEND/RECEIVE parameters. SetEOL EQU 0 End-Of-Line (packet terminator) SetMARKR EQU 1 Start of Packet marker SetMXPLN EQU 2 Maximum packet length to send SetNPAD EQU 3 Amount of padding SetPDCHR EQU 4 Pad character SetTMOUT EQU 5 Timeout interval * SET SEND/RECEIVE parameters string table. SSRTable: DC.B SetEOL,"END_OF_LINE",Asc_Nul DC.B SetMARKR,"MARKER",Asc_Nul DC.B SetMXPLN,"PACKET_LENGTH",Asc_Nul DC.B SetNPAD,"PADDING",Asc_Nul DC.B SetPDCHR,"PAD_CHARACTER",Asc_Nul DC.B SetTMOUT,"TIMEOUT",Asc_Nul DC.B -1 DC.B "SET SEND/RECEIVE parameter",Asc_Nul * SET SEND parameters jump table. DoSetSTb: DC.W DoStSEOL-DoSetSTb SetEOL DC.W DoStSMrk-DoSetSTb SetMARKR DC.W DoStSMPS-DoSetSTb SetMXPLN DC.W DoStSPdN-DoSetSTb SetNPAD DC.W DoStSPdC-DoSetSTb SetPDCHR DC.W DoStSTIM-DoSetSTb SetTMOUT * SET RECEIVE parameters jump table. DoSetRTb: DC.W DoStREOL-DoSetRTb SetEOL DC.W DoStRMrk-DoSetRTb SetMARKR DC.W DoStRMPS-DoSetRTb SetMXPLN DC.W DoStRPdN-DoSetRTb SetNPAD DC.W DoStRPdC-DoSetRTb SetPDCHR DC.W DoStRTIM-DoSetRTb SetTMOUT * Values associated with REMOTE command qualifiers. RemCOPY EQU 0 Copy RemCWD EQU 1 Change Working Directory RemDELET EQU 2 Delete RemDIR EQU 3 Directory RemHELP EQU 4 Help RemHOST EQU 5 Host RemKRMIT EQU 6 Kermit RemPRINT EQU 7 Print RemRENAM EQU 8 Rename RemSET EQU 9 SET RemSPACE EQU 10 Space RemSUBMT EQU 11 Submit RemTYPE EQU 12 Type RemWHO EQU 13 Who * REMOTE command qualifiers string table. REMTable: DC.B RemCOPY,"COPY",Asc_Nul DC.B RemCWD,"CWD",Asc_Nul DC.B RemDELET,"DELETE",Asc_Nul DC.B RemDIR,"DIRECTORY",Asc_Nul DC.B RemHELP,"HELP",Asc_Nul DC.B RemHOST,"HOST",Asc_Nul DC.B RemKRMIT,"KERMIT",Asc_Nul DC.B RemPRINT,"PRINT",Asc_Nul DC.B RemRENAM,"RENAME",Asc_Nul DC.B RemSET,"SET",Asc_Nul DC.B RemSPACE,"SPACE",Asc_Nul DC.B RemSUBMT,"SUBMIT",Asc_Nul DC.B RemTYPE,"TYPE",Asc_Nul DC.B RemWHO,"WHO",Asc_Nul DC.B -1 DC.B "REMOTE Kermit server command",Asc_Nul * REMOTE command qualifiers jump table. DoRemTab: DC.W DoRemCOP-DoRemTab RemCOPY DC.W DoRmCWD-DoRemTab RemCWD DC.W DoRemDEL-DoRemTab RemDELET DC.W DoRmDIR-DoRemTab RemDIR DC.W DoRmHELP-DoRemTab RemHELP DC.W DoRemHOS-DoRemTab RemHOST DC.W DoRemKER-DoRemTab RemKRMIT DC.W DoRemPRI-DoRemTab RemPRINT DC.W DoRemREN-DoRemTab RemRENAM DC.W DoRemSET-DoRemTab RemSET DC.W DoRmSPA-DoRemTab RemSPACE DC.W DoRemSUB-DoRemTab RemSUBMT DC.W DoRemTYP-DoRemTab RemTYPE DC.W DoRmWHO-DoRemTab RemWHO * Values associated with SHOW command qualifiers. ShoPARAM EQU 0 Parameters ShoVERS EQU 1 Version * SHOW command qualifiers table. SHOWTabl: DC.B ShoPARAM,"PARAMETERS",Asc_Nul DC.B ShoVERS,"VERSION",Asc_Nul DC.B -1 DC.B "SHOW option",Asc_Nul * SHOW command options jump table. DoShoTab: DC.W DoShoP-DoShoTab ShoPARAM DC.W DoShoVer-DoShoTab ShoVERS * Values associated with SET FILE command parameters. SetFDISP EQU 0 File display SetFNAME EQU 1 File naming SetFTYPE EQU 2 File type SetFWARN EQU 3 File warning * SET FILE command parameters table. SFILTabl: DC.B SetFDISP,"DISPLAY",Asc_Nul DC.B SetFNAME,"NAMES",Asc_Nul DC.B SetFTYPE,"TYPE",Asc_Nul DC.B SetFWARN,"WARNING",Asc_Nul DC.B -1 DC.B "file parameter",Asc_Nul * SET FILE command parameters jump table. DoSFlTab: DC.W DoStFDs-DoSFlTab SetFDISP DC.W DoStFNm-DoSFlTab SetFNAME DC.W DoStFTp-DoSFlTab SetFTYPE DC.W DoStFWn-DoSFlTab SetFWARN * Values associated with SET RETRY command parameters. SetRtINI EQU 0 Set retry initial connection packet SetRtPAK EQU 1 Set retry normal packet * SET RETRY command parameters table. SRETTabl: DC.B SetRtINI,"INITIAL_CONNECTION",Asc_Nul DC.B SetRtPAK,"PACKET",Asc_Nul DC.B -1 DC.B "retry parameter",Asc_Nul * SET RETRY command parameters jump table. DoSRtTab: DC.W DoSetRtI-DoSRtTab SetRtINI DC.W DoSetRtP-DoSRtTab SetRtPAK * On/Off specification keyword table. OnOfTabl: DC.B 0,"FALSE",Asc_Nul DC.B 0,"OFF",Asc_Nul DC.B 0,"NO",Asc_Nul DC.B 0,"0",Asc_Nul DC.B 1,"TRUE",Asc_Nul DC.B 1,"ON",Asc_Nul DC.B 1,"YES",Asc_Nul DC.B 1,"1",Asc_Nul DC.B -1 DC.B "on/off specification",Asc_Nul * Block check specification keyword table. BlCkTabl: DC.B 1,"1",Asc_Nul DC.B 1,"ONE",Asc_Nul DC.B 2,"2",Asc_Nul DC.B 2,"TWO",Asc_Nul DC.B 3,"3",Asc_Nul DC.B 3,"THREE",Asc_Nul DC.B -1 DC.B "block check type specification",Asc_Nul * Parity specification keyword table. ParTable: DC.B 0,"NONE",Asc_Nul DC.B "O","ODD",Asc_Nul DC.B "E","EVEN",Asc_Nul DC.B "M","MARK",Asc_Nul DC.B "S","SPACE",Asc_Nul DC.B -1 DC.B "parity specification",Asc_Nul * Incomplete file disposition keyword table. IFlDTabl: DC.B 0,"DISCARD",Asc_Nul DC.B 1,"KEEP",Asc_Nul DC.B -1 DC.B "incomplete file disposition",Asc_Nul * File type specification keyword table. FTypTabl: DC.B 0,"TEXT",Asc_Nul DC.B 1,"BINARY",Asc_Nul DC.B -1 DC.B "file type specification",Asc_Nul * File naming specification keyword table. FNamTabl: DC.B 0,"LITERAL",Asc_Nul DC.B 1,"CONVERTED",Asc_Nul DC.B -1 DC.B "file naming specification",Asc_Nul * Flow control specification keyword table. FlowTabl: DC.B 0,"NONE",Asc_Nul DC.B 1,"XON/XOFF",Asc_Nul DC.B -1 DC.B "flow control specification",Asc_Nul * Duplex specification keyword table. DuplTabl: DC.B 0,"FULL",Asc_Nul DC.B 1,"HALF",Asc_Nul DC.B -1 DC.B "duplex specification",Asc_Nul * Handshake characters specification keyword table. HandTabl: DC.B 0,"NONE",Asc_Nul DC.B Asc_Bel,"BELL",Asc_Nul DC.B Asc_LF,"LF",Asc_Nul DC.B Asc_CR,"CR",Asc_Nul DC.B Asc_DC1,"XON",Asc_Nul DC.B Asc_DC3,"XOFF",Asc_Nul DC.B Asc_Esc,"ESC",Asc_Nul DC.B -1 DC.B "handshake character specification",Asc_Nul align Following code aligned on word boundary ends END <<< k6odef.asm >>> * Kermit68K: source file K68DEF * * 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 * ?????? ?????? Steve Williams Modified for OS9 (see below) * This file is adapted in a very straightforward manner from the original * k68def.src file. * * Since the OS-9 assembler will not allow the declaration of labels inside * a macro definition (ala the'\3 equ VarIndex' used previously) the do.b, * do.w, and do.l pseudo instructions are used instead. These perform a * very similiar offset definition function. * * This file has been converted to its own psect for the following reasons: * * 1. It makes defining the dependencies in the make utility makefile much * easier, since each object file depends on only one source file. * * 2. It greatly decreases the development cycle time by reducing the disk * accesses needed during reassembly. * * 3. The OS-9 symobolic debugger needs global symbols in order to provide * meaningful interpretation of programs being debugged. Edition set 1 psect K68Definitions,0,0,Edition,0,0 * Truth values True: EQU -1 True value, in the sense of Scc opcode False: EQU 0 False value, in the sense of Scc opcode * ASCII control characters Asc_Nul: EQU 0 Nul or tape feed Asc_SOH: EQU 1 Start of heading Asc_STx: EQU 2 Start of text Asc_ETx: EQU 3 End of text Asc_EOT: EQU 4 End of transmission Asc_Enq: EQU 5 Enquire Asc_Ack: EQU 6 Acknowledge Asc_Bel: EQU 7 Bell Asc_BS: EQU 8 Backspace Asc_HT: EQU 9 Horizontal tab Asc_LF: EQU 10 Line feed Asc_VT: EQU 11 Vertical tab Asc_FF: EQU 12 Form feed Asc_CR: EQU 13 Carriage return Asc_SO: EQU 14 Shift out Asc_SI: EQU 15 Shift in Asc_DLE: EQU 16 Data link escape Asc_DC1: EQU 17 Device control 1 Asc_DC2: EQU 18 Device control 2 Asc_DC3: EQU 19 Device control 3 Asc_DC4: EQU 20 Device control 4 Asc_NAk: EQU 21 Negative acknowledge Asc_Syn: EQU 22 Synchronous idle Asc_ETB: EQU 23 End of transmission block Asc_Can: EQU 24 Cancel Asc_EM: EQU 25 End of medium Asc_Sub: EQU 26 Substitute Asc_Esc: EQU 27 Escape, prefix Asc_FS: EQU 28 File separator Asc_GS: EQU 29 Group separator Asc_RS: EQU 30 Record separator Asc_US: EQU 31 Unit separator Asc_Del: EQU 127 Delete * Buffers and strings sizes StkMDpth: EQU 512 Max stack depth (long words) McrTblLn: equ 2000 Mcaro table length RBufLen: EQU 200 Receive buffer length CmdBufLn: EQU 200 Command buffer length PromptML: EQU 32 Prompt string max length LinNamML: EQU 32 Line name string max length FilNamML: EQU 28 File names max length (for OS9--was 40) MxPckSiz: EQU 94 Maximum packet size MaxTakeF: EQU 20 Maximum number of nested take files * Kermit protocol automaton states SndInitS: EQU 0 Send-Init OpnFileS: EQU 1 Open-File SndFileS: EQU 2 Send-File SndDataS: EQU 3 Send-Data SendEOFS: EQU 4 Send-End-Of-File SendEOTS: EQU 5 Send-Break RecInitS: EQU 6 Receive-Init RecFileS: EQU 7 Receive-File RecDataS: EQU 8 Receive-Data SndSrvIS: EQU 9 Send-Server-Init SndGCmdS: EQU 10 Send-Generic-Command CompletS: EQU 11 Complete AbortS: EQU 12 Abort * Logical channels Null: EQU 0 Null logical channel number Terminal: EQU 1 Terminal line logical channel number HostLine: EQU 2 Host line logical channel number IOFile: EQU 3 I/O file logical channel number TakeFil0: EQU 4 Outer level take file ... TakeFil1: EQU 5 ... and so on * System I/O routines InpChar, OutChar and ChanCtrl completion codes AllOk: EQU 0 No errors BadChan: EQU 1 Inexistent channel ResChan: EQU 2 Access reserved, permission denied DevNotRd: EQU 3 Device not ready (e.g. unmounted) NotInpCh: EQU 4 Input impossible on this channel NotOutCh: EQU 5 Output impossible on this channel NotOpRd: EQU 6 File not open for read NotOpWr: EQU 7 File not open for write UnrInpF: EQU 8 Unrecoverable failure during input UnrOutF: EQU 9 Unrecoverable failure during output InChLost: EQU 10 Input character lost InpBreak: EQU 11 Break received on input BufEmpty: EQU 12 Input buffer empty BufOvflw: EQU 13 Input buffer overflow EndOfFil: EQU 14 End of file reached on input DevFull: EQU 15 Device full, not enough space BadCtReq: EQU 16 I/O control request code invalid * FilOpen function request codes RdWrOp: EQU 0 Open for read/write ReadOp: EQU 1 Open for read WriteOp: EQU 2 Open for write AppendOp: EQU 3 Open for append * I/O channel control requests SetBaud: EQU 0 Set baud rate on port RawMode: EQU 1 Enable raw mode TextMode: EQU 2 Enable text mode DoXCntrl: EQU 3 Enable XON/XOFF protocol NoXCntrl: EQU 4 Disable XON/XOFF protocol SndBreak: EQU 5 Send a break over RS 232 C line ClrInpBf: EQU 6 Clear input buffer ClrOutBf: EQU 7 Clear output buffer * System function request codes SysCommd: equ 0 Forward a command to system Directry: EQU 1 Display a directory listing SpacInfo: EQU 2 Display informations about disk usage DeletFil: EQU 3 Delete file(s) CopyFile: EQU 4 Copy file(s) ChangDir: EQU 5 Change the default directory PrntFile: EQU 6 Print file(s) RenamFil: EQU 7 Rename file(s) TypeFile: EQU 8 Type file(s) * Screen request codes SFilName: EQU 0 Outgoing file name RFilName: EQU 1 Inbound file name FlAsName: EQU 2 File as-name XPckData: EQU 3 X packet data FlTranOk: EQU 4 File transfer ok FlDiscrd: EQU 5 File discarded FlIntrrp: EQU 6 File interrupted FlSkippd: EQU 7 File skipped PackType: EQU 8 Packet type TranCmpl: EQU 9 Transaction complete ErrMessg: EQU 10 Error message WarnMess: EQU 11 Warning message UndelTxt: EQU 12 Undelimited text TxtDlBeg: EQU 13 Text delimited at the beginning TxtDlEnd: EQU 14 Text delimited at the end ScrnMxRq: EQU 14 Screen function max request code * Program variables defaults DefDuplx: equ False Default duplex DefPrity: EQU 0 Default parity DefEscap: EQU 5 Default escape character for connect DefFlow: EQU 1 Default line flow control DefLocal: EQU True Default mode, local or remote DefSpeed: EQU 9600 Default line speed DefDelay: EQU 5 Default initial delay before sending DefRetIn: EQU 16 Defaulut retry limit initial connection DefRetPk: EQU 10 Defaulut retry limit normal packets * Send Init parameters MyMxPSiz: EQU 90 Biggest packet I want receive MyTimOut: EQU 10 When I want to be timed out MyPad: EQU 0 How much padding I need MyPadChr: EQU Asc_Nul Padding character I want MyEOL: EQU Asc_CR End-Of-Line character I want MyCtlQot: EQU '#' Control-Quote character I send MyRptQot: EQU $7E Repeat-Quote character I send My8BQuot: EQU '&' 8th-Bit prefix char I will use * Receive Init default parameters DefMxPSz: EQU 80 Default biggest packet you can receive DefTmOut: EQU 10 Default when you want to be timed out DefPadNm: EQU 0 Default how much padding you need DefPadCr: EQU Asc_Nul Default padding character you want DefEOL: EQU Asc_CR Default End-Of-Line character you want DefCtlQt: EQU '#' Default Control-Quote character you send * System variables * OS-9 will not accept a macro argument as a label, so the variable * declarations have been done in another way. The do.s directive keeps * a running offset location counter (separate from the code counter) that * can be reset at any time using the org directive. org 0 * Packet related variables PackNum: do.b 1 Packet number PrevPckN: do.b 1 Previous packet number NextPckN: do.b 1 Next packet number SendType: do.b 1 Packet type just sent IStPckCh: do.b 1 Incoming packet start character OStPckCh: do.b 1 Outbound packet start character Size: do.b 1 Current output data packet size OldSize: do.b 1 Previous output data packet size First: do.b 1 Flag for first character from input Current: do.b 1 Current character from input Next: do.b 1 Next character from input * Communication line variables Speed: do.l 1 Line speed, -1 if unknown Parity: do.b 1 Parity specified, 0, 'E', 'O', 'M', 'S' Flow: do.b 1 Flow control, 1 for xon/xoff TurnFlag: do.b 1 Line turnaround handshake flag TurnChar: do.b 1 Line turnaround character Delay: do.b 1 Initial delay before sending Duplex: do.b 1 Duplex, full by default Escape: do.b 1 Escape character for connect * Program variables CmdBfPnt: do.b 1 Relative pointer to command buffer ServrCmd: do.b 1 Server command to send Retry: do.b 1 Retry limit currently in use RtryInit: do.b 1 Retry limit initial connection packets RtryPack: do.b 1 Retry limit for normal packets TakLevel: do.b 1 Take file level LFSave: do.b 1 This is for newline processing * If the system uses a single character for text file line delimitation, * assign to NewLinCh the ASCII value of that character. For text files, * that character will be converted to CRLF upon output, and CRLF will be * converted to that character on input. NewLinCh: EQU Asc_CR Line delimiter for text files * Variables for Send-Init parameters ICtlQuot: do.b 1 Control prefix in incoming data OCtlQuot: do.b 1 Control prefix in outgoing data IEOL: do.b 1 End-Of-Line character to look for OEOL: do.b 1 End-Of-Line character to send IPadNumb: do.b 1 How much padding to ask for OPadNumb: do.b 1 How much padding to send IPadChar: do.b 1 Padding character to ask for OPadChar: do.b 1 Padding character to send ITimInt: do.b 1 Timeout interval I use OTimInt: do.b 1 Timeout interval I want you to use IMPckSiz: do.b 1 Biggest packet size I want to receive OMPckSiz: do.b 1 Biggest packet size I can send BlChkUs: do.b 1 Block check type used BlChkRq: do.b 1 Block check type requested ReptCnt: do.b 1 Repeat count ReptQuot: do.b 1 Repeat prefix ReptFlag: do.b 1 Repeat processing flag Bit8Quot: do.b 1 8th bit prefix Bit8Flag: do.b 1 8th bit quoting flag TimInFlg: do.b 1 Flag to override the timeout requested SndPSFlg: do.b 1 Flag to override the size requested * Flags MStrFlag: do.b 1 Flag for input from memory string TermOut: do.b 1 Flag for output to the terminal channel CtlXSeen: do.b 1 Flag for cancelling a file CtlZSeen: do.b 1 Flag for cancelling a file group Binary: do.b 1 Flag for binary file FNameCnv: do.b 1 Flag for converting file names Keep: do.b 1 Flag for incomplete file disposition Warning: do.b 1 Flag for file warning Display: do.b 1 Flag for file transfer display Quiet: do.b 1 Be quiet during file transfer Local: do.b 1 Flag for running in local mode IntMacro: do.b 1 Flag for interpreting macros Done: do.b 1 Flag for exiting the command parser * String and buffer variables LeftOver: do.b 6 Small buffer for optimal packet filling Prompt: do.b PromptML Prompt string LineName: do.b LinNamML Communication line name FilName: do.b FilNamML Current file name Argumnt1: do.b CmdBufLn First command argument Argumnt2: do.b CmdBufLn Second command argument DataBuf: do.b MxPckSiz+4 Packet data buffer SendBuf: do.b MxPckSiz+4 Send packet buffer RecBuf: do.b RBufLen Receive packet buffer CmdBuf: do.b CmdBufLn Buffer for command interpretation MacroTbl: do.b McrTblLn Macro definitions table * Statistic variables ChrsSent: do.l 1 Chars sent last transaction TChsSent: do.l 1 Total characters sent ChrsRecd: do.l 1 Chars received last transaction TChsRecd: do.l 1 Total characters received DChsSent: do.l 1 Data chars sent last transaction TDChSent: do.l 1 Total data characters sent DChsRecd: do.l 1 Data chars received last transaction TDChRecd: do.l 1 Total data characters received PcksSent: do.l 1 Packets sent last transaction TPckSent: do.l 1 Total packet sent PcksRecd: do.l 1 Packets received last transaction TPckRecd: do.l 1 Total packet received NAKsSent: do.l 1 NAKs sent last transaction TNAKSent: do.l 1 Total NAKs sent NAKsRecd: do.l 1 NAKs received last transaction TNAKRecd: do.l 1 Total NAKs received * Pointers MStrgPnt: do.l 1 Pointer for input from memory string MacroPnt: do.l 1 Pointer for macro interpretation MTNxtChF: do.l 1 Pointer to the end of the macro table * System dependent routines variables LinLngth: do.b 1 For the dumb terminal Screen routine MyFNBuff: do.b FilNamML This is for tests on my system * OS-9/68000 specific variables CR_Last: do.b 1 Flag for CR/LF stripping on terminal TermFlag: do.b 1 Flag used in OutChar for terminal. Pathnums: do.w 20 OS-9 path numbers for logical channels NumFiles: do.l 1 Number of files left to process NextFile: do.l 1 Pointer to next file name CmdLinPt: do.l 1 Pointer to the OS-9 command arguments FNBuffer: do.b 50*FilNamML File names buffer for ExpandFN ShellCmd: do.b 128 Buffer for constructing shell commands OptBuff: do.b 128 Save area for terminal input PD options * Must set the VarIndex variable to the current offset location counter * so that the variable section can be set up properly VarIndex: do.w 1 Seems reasonable to be word aligned vsect VarArea: ds.b VarIndex Storage definition for the variables area ends ends end <<< k6oiof.asm >>> nam Kermit68K ttl IO subroutines module * Kermit68K: source file K68IOF * * 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 K68IOFunctions,0,0,Edition,0,0 ********************************* ConInp ******************************ok * * * Expect a character from the terminal line. * * * * Entry conditions : none * * * * Exit conditions : D0.B character received * * D1.B AllOk completion code * * * *********************************************************************** ConInp: MOVEQ #Terminal,D1 Terminal line I/O channel BSR InpChar Try to read a character TST.B D1 All ok ? BNE.S ConInp No, assume not ready for input, wait RTS Yes, return ********************************* ConOut ******************************ok * * * Send a character to the terminal line. * * * * Entry conditions : D0.B character to send * * * * Exit conditions : D0.B character just sent * * D1.B completion code * * * *********************************************************************** ConOut: MOVEQ #Terminal,D1 Terminal line I/O channel BSR OutChar Try to send the character RTS Return completion code from OutChar ********************************* HostOut *****************************ok * * * Send a character to the host line adding a parity bit. * * * * Entry conditions : D0.B character to send * * * * Exit conditions : D0.B character just sent * * D1.B completion code * * * *********************************************************************** HostOut: BSR DoPrity Add an appropriate parity bit MOVEQ #HostLine,D1 Terminal line I/O channel BSR OutChar Try to send the character RTS Return completion code from OutChar ********************************* FileOut *****************************ok * * * Write a character to the current I/O file. If an error occurs * * during output then set an interruption flag to stop the file * * transfer. * * * * Entry conditions : D0.B character to send * * * * Exit conditions : D0.B character just sent * * D1.B completion code * * * *********************************************************************** FileOut: MOVEQ #IOFile,D1 Current file I/O channel BSR OutChar Output the character to it TST.B D1 Some error ? BEQ.S FileOut1 No, return ST CtlZSeen(A6) Yes, interrupt the file transfer FileOut1 RTS ******************************* ConWrite ******************************ok * * * Write a null terminated string on the terminal line. * * * * Entry conditions : A0.L pointer to string buffer * * * * Exit conditions : D1.L destroyed * * * *********************************************************************** ConWrite: MOVEQ #Terminal,D1 Terminal line I/O channel BSR.S Write Write now RTS ******************************* TypeUNum ******************************ok * * * Write a decimal unsigned number to the terminal line. * * * * Entry conditions : D0.L number to be typed * * * * Exit conditions : none * * * *********************************************************************** TypeUNum: MOVEM.L D1-D3,-(A7) Save working registers SF D1 Unsigned conversion wanted MOVEQ #0,D2 Null field MOVEQ #10,D3 Base 10 LEA DataBuf+34(A6),A0 Point to the end of a temporary buffer BSR IntToAs Convert the number into a string BSR ConWrite Write the obtained string MOVEM.L (A7)+,D1-D3 Restore working registers RTS ********************************* Write *******************************ok * * * Write a null terminated string on a logical channel. * * * * Entry conditions : D1.B channel number * * A0.L pointer to string buffer * * * * Exit conditions : D1.B channel number * * * *********************************************************************** Write: MOVE.W D2,-(A7) Save working register MOVE.B D1,D2 Save channel number Write1 MOVE.B (A0)+,D0 Get a character BEQ.S Write2 Leave if end of string reached BSR OutChar Send the character, assume no errors MOVE.B D2,D1 Restore channel number BRA.S Write1 Repeat until end of string Write2 MOVE.W (A7)+,D2 Restore working register RTS ********************************* NewLine *****************************ok * * * Send a newline sequence (CR+LF) to the terminal line. * * * * Entry conditions : none * * * * Exit conditions : D0.L destroyed * * * *********************************************************************** NewLine: MOVE.L D1,-(A7) Save this register, destroyed by ConOut MOVEQ #Asc_CR,D0 Send a CR BSR ConOut MOVEQ #Asc_LF,D0 And then a LF BSR ConOut MOVE.L (A7)+,D1 Restore working register RTS ********************************* CCmdIn ******************************ok * * * Input a command line from the terminal line, store it to CmdBuf. * * * * Entry conditions : none * * * * Exit conditions : D0.B completion code, false on EOF * * * *********************************************************************** CCmdIn: MOVEM.L A0-A1/D1-D3,-(A7) Save working registers LEA CmdBuf(A6),A0 Start address MOVEA.L A0,A1 Save start address CCmdIn1 BSR ConInp Get a character CMPI.B #Asc_Sub,D0 EOF character ? BEQ.S CCmdIn10 Yes CMPI.B #Asc_CR,D0 CR ? BEQ.S CCmdIn8 Yes CMPI.B #Asc_LF,D0 CR ? BEQ.S CCmdIn8 Yes CMPI.B #Asc_FF,D0 CR ? BEQ.S CCmdIn8 Yes CMPI.B #Asc_Del,D0 Delete ? BEQ.S CCmdIn2 Yes CMPI.B #Asc_BS,D0 Backspace ? BNE.S CCmdIn3 No CCmdIn2 CMPA.L A1,A0 At line begin ? BEQ.S CCmdIn1 Yes, no action BSR.S CCmdIn11 No, delete last character BRA.S CCmdIn1 Another character please ! CCmdIn3 CMPI.B #Asc_Can,D0 Ctrl X ? BNE.S CCmdIn5 No CCmdIn4 CMPA.L A1,A0 At line begin ? BEQ.S CCmdIn1 Yes, exit BSR.S CCmdIn11 No, delete last character BRA.S CCmdIn4 Repeat until the whole line is deleted CCmdIn5 MOVE.B D0,(A0)+ Store the character CMPI.B #' ',D0 Printable character ? BGE.S CCmdIn6 Yes, print it out CMPI.B #Asc_HT,D0 Horizontal tab ? BEQ.S CCmdIn6 Yes, print it out ADDI.B #64,D0 Make it printable MOVEQ #'^',D2 Prefix character for control EXG D0,D2 Exchange BSR ConOut Output prefix EXG D0,D2 Exchange CCmdIn6 BSR ConOut Output character CCmdIn7 MOVE.L A0,D3 Other characters to read ? SUB.L A1,D3 CMPI.W #CmdBufLn,D3 BLT.S CCmdIn1 Yes, again please !!! CCmdIn8 ST D0 Return a positive completion code CCmdIn9 CLR.B (A0)+ Null as terminator MOVEM.L (A7)+,A0-A1/D1-D3 Restore working registers RTS CCmdIn10 SF D0 Return a negative cc, EOF on input BRA.S CCmdIn9 Join common part CCmdIn11 MOVE.B -(A0),D0 Back off CMPI.B #' ',D0 Printable character ? BGE.S CCmdIn12 Yes, only one character to delete BSR.S CCmdIn13 No, delete the prefix CCmdIn12 BSR.S CCmdIn13 Delete character RTS CCmdIn13 MOVEQ #Asc_BS,D0 Delete the last character BSR ConOut MOVEQ #' ',D0 BSR ConOut MOVEQ #Asc_BS,D0 BSR ConOut RTS ********************************* FlCmdIn *****************************ok * * * Input a command line from a take file, store it to CmdBuf. * * * * Entry conditions : D1.B take file channel number * * * * Exit conditions : D0.B completion code * * D1.B destroyed * * D2.B destroyed * * A0.L destroyed * * * *********************************************************************** FlCmdIn: LEA CmdBuf(A6),A0 Pointer to target buffer MOVE.B D1,D2 Save the channel number FlCmdIn1 BSR InpChar Try to get a character CMP.B #AllOk,D1 Ok ? BEQ.S FlCmdIn3 Yes CMP.B #EndOfFil,D1 End of file ? BEQ.S FlCmdIn2 Yes, return the proper completion code LEA FlCmdStr(PC),A0 No, some error during read BSR ConWrite Give this message FlCmdIn2 SF D0 RTS FlCmdIn3 CMPI.B #NewLinCh,D0 End of line ? BEQ.S FlCmdIn4 Yes, exit loop MOVE.B D0,(A0)+ No, store the character just read MOVE.B D2,D1 Reload channel number for the next read BRA.S FlCmdIn1 Stay in loop FlCmdIn4 CLR.B (A0) Terminate the command buffer ST D0 Return a positive completion code RTS ********************************* McCmdIn *****************************ok * * * Input a command line from a macro, store it to CmdBuf. * * * * Entry conditions : none * * * * Exit conditions : D0.B completion code * * A0.L destroyed * * A1.L destroyed * * * *********************************************************************** McCmdIn: LEA CmdBuf(A6),A0 Pointer to target buffer MOVEA.L MacroPnt(A6),A1 Pointer to source buffer TST.B (A1) Are we at the end of the macro body ? BEQ.S McCmdIn4 Yes, end of macro, return false McCmdIn1 MOVE.B (A1)+,D0 Get a character BEQ.S McCmdIn2 If null, this is the last line CMPI.B #Asc_CR,D0 End of line ? BEQ.S McCmdIn3 Yes, ... MOVE.B D0,(A0)+ Store the character in target buffer BRA.S McCmdIn1 Loop until end of line McCmdIn2 SUBQ.L #1,A1 Still point to the null, next time ... McCmdIn3 MOVE.L A1,MacroPnt(A6) Save the pointer to next macro line CLR.B (A0) Terminate the command buffer ST D0 Return a positive completion code RTS McCmdIn4 SF D0 End of macro, return a negative cc RTS ********************************* SendPad *****************************ok * * * Send padding characters to the communication line. * * * * Entry conditions : none * * * * Exit conditions : D0.B destroyed * * * *********************************************************************** SendPad: MOVEM.L D1-D2,-(A7) Save working registers CLR.W D2 Clear counter register MOVE.B OPadNumb(A6),D2 Number of padding char to send BRA.S SendPad2 Enter loop SendPad1 MOVE.B OPadChar(A6),D0 Padding character to send BSR HostOut Send padding character to host line SendPad2 DBF D2,SendPad1 Repeat MOVEM.L (A7)+,D1-D2 Restore working registers RTS ********************************* TxPackt *****************************ok * * * Send the packet stored in SendBuf to the host line. * * * * Entry conditions : none * * * * Exit conditions : none * * * *********************************************************************** TxPackt: MOVEM.L D1/A0,-(A7) Save working registers BSR SendPad Do any requested padding LEA SendBuf(A6),A0 Packet buffer start TxPackt1 MOVE.B (A0)+,D0 Get a character BEQ.S TxPackt2 Leave if end of string reached BSR HostOut Send the character ADDQ.L #1,ChrsSent(A6) Increment chars sent this transaction ADDQ.L #1,TChsSent(A6) Increment total characters sent BRA.S TxPackt1 Repeat until end of string TxPackt2 ADDQ.L #1,PcksSent(A6) Increment packets sent this trans ADDQ.L #1,TPckSent(A6) Increment total packets sent MOVEM.L (A7)+,D1/A0 Restore working registers RTS ******************************** InpLine ******************************ok * * * Input a line (up to the break char) from the communication line. * * * * Entry conditions : none * * * * Exit conditions : D0.L number of characters received * * D1.B completion code * * A0.L destroyed * * D2.L destroyed * * D3.W destroyed * * D4.B destroyed * * * *********************************************************************** InpLine: LEA RecBuf(A6),A0 Point to receive buffer CLR.L D2 Clear the character counter CLR.W D3 Clear the timeout counter TST.B TurnFlag(A6) Is the turnaround handshake flag on ? BEQ.S InpLine0 No, look for Input EOL as terminator MOVE.B TurnChar(A6),D4 Yes, turnaround character as terminator BRA.S InpLine1 InpLine0 MOVE.B IEOL(A6),D4 Load the Input End Of Line character InpLine1 MOVE.B ITimInt(A6),D3 Preset the timeout counter InpLine2 BSR RdChrTO Get a character TST.B D1 Timed out ? BNE.S InpLine3 No, continue DBF D3,InpLine2 Yes, repeat unless timeout limit reached SF D1 Provide a negative completion code RTS InpLine3 CMP.B D4,D0 End Of Line or turnaround character ? BEQ.S InpLine4 Yes MOVE.B D0,(A0)+ No, got a character, save it ADDQ.L #1,D2 Increment the character counter CMPI.B #RBufLen,D2 Receive buffer full ? BNE.S InpLine1 No, again please ! InpLine4 CLR.B (A0) Mark the end of buffer ADD.L D2,ChrsRecd(A6) Increment chars received this transaction ADD.L D2,TChsRecd(A6) Increment total characters received MOVE.L D2,D0 Return number of characters received ST D1 Return a positive completion code RTS ******************************** RdChrTO ******************************ok * * * Called only by InpLine, read a character from the host line with * * 1 second software timeout limit. Warning, this routine is * * absolutely provisory. * * * * Entry conditions : none * * * * Exit conditions : D0.B character received * * D1.B completion code * * * *********************************************************************** MaxIter SET 10000 To set the timeout value * RdChrTO MOVE.W D2,-(A7) Save the counter register MOVE.W #MaxIter,D2 Set up the timeout counter RdChrTO1 MOVEQ #HostLine,D1 Try to read the host line BSR InpChar TST.B D1 Check completion code BEQ.S RdChrTO2 Character received, handle 8th bit DBF D2,RdChrTO1 Timeout period expired ? SF D1 Yes, return negative completion code MOVE.W (A7)+,D2 Restore the counter register RTS RdChrTO2 BSR HndlPar Handle the parity bit ST D1 Return positive completion code MOVE.W (A7)+,D2 Restore the counter register RTS ********************************* ChkInpF *****************************ok * * * Check if an input file exists and is readable. * * * * Entry conditions : none * * * * Exit conditions : D0.B completion code * * * * -3 file exists but protected from read * * -2 file exists but is not readable * * -1 inexistent or inaccessable file * * 0 all ok * * * * D1.L destroyed * * D2.B destroyed * * * *********************************************************************** ChkInpF: MOVEQ #ReadOp,D0 Try to open for read the input file MOVEQ #IOFile,D1 Assign it to this channel number BSR FilOpen Open now TST.B D0 Some failure ? BEQ.S ChkInpF1 Yes, return this bad completion code MOVEQ #IOFile,D1 No, try to read a character BSR InpChar MOVE.B D1,D2 Save the returned completion code MOVEQ #IOFile,D1 Close the file just opened BSR FilClose TST.B D2 The read was successful ? BEQ.S ChkInpF0 Yes, all ok CMPI.B #EndOfFil,D2 No, end of file ? BEQ.S ChkInpF0 Yes, the file is null, but ok CMPI.B #ResChan,D2 No privilege to read this file ? BEQ.S ChkInpF2 Yes, return this bad completion code MOVEQ #-2,D0 No, some other error, unreadable file cc RTS ChkInpF0 MOVEQ #0,D0 Return all ok RTS ChkInpF1 MOVEQ #-1,D0 Return inexistent file cc RTS ChkInpF2 MOVEQ #-3,D0 Return protected file cc RTS ********************************* ChkOutF *****************************ok * * * Check if an output file can be created. * * * * Entry conditions : none * * * * Exit conditions : D0.B completion code * * * * -1 permission denied * * 0 all ok * * * *********************************************************************** ChkOutF: MOVEQ #0,D0 Always succeeds for now RTS ********************************* OpnInpF *****************************ok * * * Try to open an existing file for input. * * * * Entry conditions : A0.L pointer to the file name * * * * Exit conditions : A0.L pointer to the file name * * D0.B completion code * * D1.L destroyed * * * *********************************************************************** OpnInpF: MOVE.B MStrFlag(A6),D0 Input from memory string ? BNE.S OpnInpF1 Yes, return a positive cc MOVEQ #ReadOp,D0 Try to open the input file MOVEQ #IOFile,D1 BSR FilOpen TST.B D0 Open succeed ? BEQ.S OpnInpF1 Yes, return this completion code BSR CRemTLoc No, convert name to local form MOVEQ #ReadOp,D0 Try again to open the input file MOVEQ #IOFile,D1 BSR FilOpen OpnInpF1 RTS Return cc from FilOpen ********************************* OpnOutF *****************************ok * * * Try to open an existing file for output. * * * * Entry conditions : A0.L pointer to the file name * * A1.L pointer to the file name * * target buffer * * * * Exit conditions : A0.L pointer to the file name target * * buffer containing the file name * * under wich the file was opened * * D0.B completion code * * D1.L destroyed * * * *********************************************************************** OpnOutF: MOVE.B TermOut(A6),D0 Terminal output wanted ? BNE.S OpnOutF3 Yes, return a positive cc MOVE.B CtlXSeen(A6),D0 Some interruption ? OR.B CtlZSeen(A6),D0 BNE.S OpnOutF3 Yes, don't destroy existing file EXG A0,A1 Exchange buffers pointers MOVEQ #FilNamML,D0 Load buffers length BSR CopyStr Fill target buffer, copy from source TST.B FNameCnv(A6) File names conversion ? BEQ.S OpnOutF1 No, proceed BSR CRemTLoc Yes, convert file name to local form OpnOutF1 TST.B Warning(A6) File collision avoidance ? BEQ.S OpnOutF2 No, proceed BSR ChkInpF Yes, check if file exists CMPI.B #-1,D0 File exists ? BEQ.S OpnOutF2 No, proceed BSR NewName Yes, make a new name OpnOutF2 MOVEQ #WriteOp,D0 Finally open the file for output MOVEQ #IOFile,D1 BSR FilOpen OpnOutF3 RTS Return the completion code ********************************* ClsInpF *****************************ok * * * Close the current input file. * * * * Entry conditions : none * * * * Exit conditions : D0.L destroyed * * D1.L destroyed * * * *********************************************************************** ClsInpF: TST.B MStrFlag(A6) Input from memory string ? BEQ.S ClsInpF1 No, close the input file SF MStrFlag(A6) Yes, reset flag BRA.S ClsInpF2 ClsInpF1 MOVEQ #IOFile,D1 Close the output file BSR FilClose ClsInpF2 MOVE.B CtlXSeen(A6),D0 File interrupt ... OR.B CtlZSeen(A6),D0 ... or file group interrupt ? BNE.S ClsInpF3 Yes, give discard message MOVEQ #FlTranOk,D0 No, give comforting messages BSR Screen BRA.S ClsInpF4 ClsInpF3 MOVEQ #FlDiscrd,D0 Give discard message BSR Screen ClsInpF4 SF CtlXSeen(A6) Reset file interrupt flag CLR.B FilName(A6) Nullify current file name RTS ********************************* ClsOutF *****************************ok * * * Close the current output file. * * * * Entry conditions : none * * * * Exit conditions : D0.L destroyed * * D1.L destroyed * * A0.L destroyed * * * *********************************************************************** ClsOutF: TST.B TermOut(A6) Output to the terminal line ? BNE.S ClsOutF3 Yes, just reset flag and return LEA FilName(A6),A0 No, point to current file name TST.B (A0) File open ? BEQ.S ClsOutF1 No MOVEQ #IOFile,D1 Yes, close the output file BSR FilClose MOVE.B CtlXSeen(A6),D0 File interrupt ... OR.B CtlZSeen(A6),D0 ... or file group interrupt ? BEQ.S ClsOutF1 No, just keep it TST.B Keep(A6) Yes, keeping incomplete files ? BNE.S ClsOutF1 Yes BSR FilDelet No, discard it MOVEQ #FlDiscrd,D0 Give discard message BSR Screen BRA.S ClsOutF2 Nullify file name and return ClsOutF1 MOVEQ #FlTranOk,D0 Give comforting messages BSR Screen ClsOutF2 CLR.B (A0) Nullify current file name RTS ClsOutF3 SF TermOut(A6) Clear the terminal output flag RTS ********************************* ChekInt *****************************ok * * * Terminal interrupts handler. * * * * Entry conditions : none * * * * Exit conditions : D0.L destroyed * * D1.L destroyed * * A1.L destroyed * * * *********************************************************************** ChekInt: TST.B Local(A6) Are we running in local mode ? BEQ.S ChekInt1 No, return TST.B Quiet(A6) Quiet requested ? BNE.S ChekInt1 Yes, return MOVEQ #Terminal,D1 Try to get a character from terminal BSR InpChar TST.B D1 Success ? BNE.S ChekInt1 No, return CMPI.B #Asc_Sub,D0 Control Z ? BEQ.S ChekInt2 Yes CMPI.B #Asc_Can,D0 Control X ? BEQ.S ChekInt3 Yes, set the file interrupt flag CMPI.B #Asc_DC2,D0 Control R ? BEQ.S ChekInt4 Yes, resend the last packet MOVEQ #Asc_Bel,D0 No, ignore, ring the bell BSR ConOut ChekInt1 RTS ChekInt2 LEA CnBchStr(PC),A1 Cancel batch MOVEQ #TxtDlBeg,D0 Give message BSR Screen ST CtlZSeen(A6) Set the file batch interrupt flag RTS ChekInt3 LEA CnFilStr(PC),A1 Cancel file MOVEQ #TxtDlBeg,D0 Give message BSR Screen ST CtlXSeen(A6) Set the file interrupt flag RTS ChekInt4 LEA ReSndStr(PC),A1 Resend packet MOVEQ #TxtDlBeg,D0 Give message BSR Screen BSR Resend Resend the last packet RTS ********************************** Screen *****************************ok * * * Screen diplay routine. * * * * Entry conditions : D0.B request code * * D1.B packet type or pseudotype * * D2.B packet number * * D3.B packet length * * A1.L pointer to a string to write * * * * Exit conditions : none * * * *********************************************************************** ScrnMxLL EQU 78 Maximum line length Screen: TST.B Display(A6) The display flag is off ? BEQ.S Screen1 Yes, no update TST.B Quiet(A6) Are we requested to be quiet ? BEQ.S Screen2 No, update the screen Screen1 RTS Screen2 MOVEM.L A0-A1/D1-D7,-(A7) Save some registers MOVE.B LinLngth(A6),D6 Length of the current screen line CLR.W D4 Compute the length of the passed string Screen3 TST.B (A1,D4.W) End of line ? BEQ.S Screen4 Yes, continue ADDQ.B #1,D4 No, count BRA.S Screen3 Repeat until end of line Screen4 MOVEQ #ScrnMxRq,D5 Maximum request code CMP.W D5,D0 Request code out of range ? BHI Screen30 Yes, return ADD.W D0,D0 No, scale it MOVE.W Screen5(PC,D0.W),D0 Relative address of the service routine JMP Screen5(PC,D0.W) Jump to it Screen5 DC.W Screen6-Screen5 SFilName DC.W Screen7-Screen5 RFilName DC.W Screen9-Screen5 FlAsName DC.W Screen11-Screen5 XPckData DC.W Screen12-Screen5 FlTranOk DC.W Screen14-Screen5 FlDiscrd DC.W Screen16-Screen5 FlIntrrp DC.W Screen18-Screen5 FlSkippd DC.W Screen19-Screen5 PackType DC.W Screen22-Screen5 TranCmpl DC.W Screen23-Screen5 ErrMessg DC.W Screen24-Screen5 WarnMess DC.W Screen25-Screen5 UndelTxt DC.W Screen27-Screen5 TxtDlBeg DC.W Screen28-Screen5 TxtDlEnd Screen6 LEA ScrnStr1(PC),A0 Display outgoing file name BRA.S Screen8 Screen7 LEA ScrnStr2(PC),A0 Display inbound file name Screen8 BSR NewLine Display file name BSR ConWrite MOVE.B #10,D6 MOVEA.L A1,A0 BSR ConWrite MOVEQ #' ',D0 BSR ConOut ADD.B D4,D6 ADDQ.B #1,D6 BRA Screen30 Screen9 MOVE.B D4,D5 Display file as-name ADD.B D6,D5 CMPI.B #ScrnMxLL-3,D5 BLS.S Screen10 BSR NewLine CLR.B D6 Screen10 LEA ScrnStr3(PC),A0 BSR ConWrite MOVEA.L A1,A0 BSR ConWrite MOVEQ #' ',D0 BSR ConOut ADD.B D4,D6 ADDQ.B #3+1,D6 CMPI.B #ScrnMxLL,D6 BLS Screen30 BSR NewLine CLR.B D6 BRA Screen30 Screen11 BSR NewLine Display X-packet data MOVEA.L A1,A0 BSR ConWrite BSR NewLine CLR.B D6 BRA Screen30 Screen12 CMPI.B #ScrnMxLL-5,D6 Successful file transfer message BLS.S Screen13 BSR NewLine CLR.B D6 Screen13 LEA ScrnStr4(PC),A0 BSR ConWrite ADDQ.B #5,D6 BRA Screen30 Screen14 CMPI.B #ScrnMxLL-12,D6 File discarded message BLS.S Screen15 BSR NewLine CLR.B D6 Screen15 LEA ScrnStr5(PC),A0 BSR ConWrite ADDI.B #12,D6 BRA Screen30 Screen16 CMPI.B #ScrnMxLL-14,D6 File transfer interrupted message BLS.S Screen17 BSR NewLine CLR.B D6 Screen17 LEA ScrnStr6(PC),A0 BSR ConWrite ADDI.B #14,D6 BRA Screen30 Screen18 BSR NewLine File skipped message LEA ScrnStr7(PC),A0 BSR ConWrite MOVEA.L A1,A0 BSR ConWrite BSR NewLine CLR.B D6 BRA Screen30 * Display packet type or pseudo-type Screen19 CMPI.B #'Y',D1 ACK packet ? BEQ Screen30 Yes, return CMPI.B #'D',D1 Data packet ? BNE.S Screen20 No ANDI.B #3,D2 Yes, only display every 4 packets BNE Screen30 Return MOVEQ #'.',D0 BRA.S Screen21 Screen20 MOVE.B D1,D0 Display the packet type Screen21 BSR ConOut ADDQ.B #1,D6 Increment current line length CMPI.B #ScrnMxLL,D6 Near the right margin ? BLS.S Screen30 No, return BSR NewLine Yes, start a new line CLR.B D6 Reset the counter BRA.S Screen30 Screen22 MOVEQ #Asc_Bel,D0 Transaction complete message (bell) BSR ConOut BSR NewLine Start a new line BRA.S Screen30 Screen23 BSR NewLine Error message MOVEQ #'?',D0 BSR ConOut MOVEA.L A1,A0 BSR ConWrite BSR NewLine CLR.B D6 BRA.S Screen30 Screen24 BSR NewLine Warning message MOVEA.L A1,A0 BSR ConWrite BSR NewLine CLR.B D6 BRA.S Screen30 Screen25 ADD.B D4,D6 Undelimited text CMPI.B #ScrnMxLL,D6 BLS.S Screen26 BSR NewLine MOVE.B D4,D6 Screen26 MOVEA.L A1,A0 BSR ConWrite BRA.S Screen30 Screen27 BSR NewLine Text delimited at beginning MOVEA.L A1,A0 BSR ConWrite MOVE.B D4,D6 BRA.S Screen30 Screen28 ADD.B D4,D6 Text delimited at end CMPI.B #ScrnMxLL,D6 BLS.S Screen29 BSR NewLine MOVE.B D4,D6 Screen29 MOVEA.L A1,A0 BSR ConWrite BSR NewLine * BRA.S Screen30 Screen30 MOVE.B D6,LinLngth(A6) MOVEM.L (A7)+,A0-A1/D1-D7 RTS ends END <<< k6omai.asm >>> nam Kermit68K ttl Main program module * Kermit68K: source file K68MAI ******************************************************************************** ******************************************************************************** * **** * * *** ***** * * *** ** ** **** * * *** ** ******* *** ** *** * **** ***** ****** **** * *** ** * ** *** ******* **** ** * * * * **** **** ******* **** * ** *** * * **** ******* *** ** ** ** * **** **** ******* **** * * **** * ***** *** *** *** *** * **** **** *** ** ***** * * **** ******* ** **** ******* * **** **** **** * **** * * **** * ** *** ******* *** *** ******* * **** **** **** * **** * ** *** * *** ** ******* **** ** ******* * **** **** **** * **** * *** ** * **** * * ***** * ******* * **** ***** *** ** **** * ******************************************************************************** ******************************************************************************** * * * Kermit implementation for the MC68000 microprocessors family * * * * * * Author: Roberto Bagnara, Physics Department, Bologna University * * * * Started: 02 May 1986 by rb * * Last modified: 01 July 1987 by rb * * * * Modified by: Steve Williams, University of Texas at Austin * * * * Status : INCOMPLETE * * * * * * Modification History: * * * * Version Date Who Comments * * * * 1.0.00 870701 Roberto Bagnara First official release * * * ******************************************************************************** use DefsFile TypeLang equ (Prgrm<<8)+Objct Executable 68000 native code AttrRev equ (ReEnt<<8)+0 Re-entrant code, revision 0 Edition equ 0 Edition number Stack equ 8192 Stack space needed psect Kermit,TypeLang,AttrRev,Edition,Stack,Kerm68K ********************************* Kerm68K *****************************ok * * * Kermit68K main program. * * * * Entry conditions : none * * * * Exit conditions : none * * * *********************************************************************** Kerm68K: LEA VarArea(A6),A6 Correct the $8000 bias of OS-9 BSR InitAll Initialize all Kermit68K variables BSR SysInit Initialize any system dependent thing BSR CmdLnP Parse the command line, if possible LEA InitFile(PC),A0 Point to the init file name MOVEQ #ReadOp,D0 We want to read it MOVEQ #TakeFil0,D1 This is the channel number BSR FilOpen Try to open the init file TST.B D0 Success ? BEQ.S Kerm68K1 No, no message, parse user commands CLR.B TakLevel(A6) Yes, we are interpreting the take file 0 Kerm68K1 BSR Parser Parse interactive commands until done ST D0 Finally return a positive cc ... BRA SysExod ... and the control to system ******************************** InitAll ******************************ok * * * Startup initialization routine. * * * * Entry conditions : none * * * * Exit conditions : D0.L destroyed * * * *********************************************************************** InitAll MOVE.B #MyEOL,IEOL(A6) Set EOL for incoming packets MOVE.B #DefEOL,OEOL(A6) Set EOL for outgoing packets MOVE.B #DefCtlQt,ICtlQuot(A6) Set incoming packets control quote MOVE.B #MyCtlQot,OCtlQuot(A6) Set outgoing packets control quote MOVE.B #MyPad,IPadNumb(A6) Set how much padding to ask for MOVE.B #DefPadNm,OPadNumb(A6) Set how much padding to send MOVE.B #MyPadChr,IPadChar(A6) Set padding character to ask for MOVE.B #DefPadCr,OPadChar(A6) Set padding character to send MOVEQ #Asc_SOH,D0 Default packet start character MOVE.B D0,IStPckCh(A6) Set incoming packet start char MOVE.B D0,OStPckCh(A6) Set outgoing packet start char MOVE.B #DefTmOut,ITimInt(A6) Set when I should time out MOVE.B #MyTimOut,OTimInt(A6) Set when I want to be timed out MOVE.B #MyMxPSiz,IMPckSiz(A6) Set max packet size I want receive MOVE.B #DefMxPSz,OMPckSiz(A6) Set max packet size I can send MOVE.B #MyRptQot,ReptQuot(A6) Set the default repeat prefix MOVE.B #My8BQuot,Bit8Quot(A6) Set the default 8th bit prefix MOVE.B #1,BlChkRq(A6) Set the default block check type MOVE.B #DefDuplx,Duplex(A6) Set default duplex MOVE.B #DefFlow,Flow(A6) Set default flow control MOVE.B #DefPrity,Parity(A6) Set default parity MOVE.B #DefEscap,Escape(A6) Set default escape character MOVE.B #DefDelay,Delay(A6) Set default delay before sending MOVE.B #DefRetIn,RtryInit(A6) Set default retry init limit MOVE.B #DefRetPk,RtryPack(A6) Set default retry normal limit LEA MacroTbl(A6),A0 MOVE.L A0,MTNxtChF(A6) CLR.B LinLngth(A6) For the dumb terminal Screen routine SF ReptFlag(A6) No repeat processing by default SF TimInFlg(A6) No timeout overriding SF SndPSFlg(A6) No packet size overriding SF Binary(A6) File type is text SF Quiet(A6) File display is on SF FNameCnv(A6) File names conversion is off SF Warning(A6) File warning is off SF Keep(A6) Don't keep incomplete files SF IntMacro(A6) CLR.L ChrsSent(A6) Clear the statistic variables CLR.L TChsSent(A6) CLR.L ChrsRecd(A6) CLR.L TChsRecd(A6) CLR.L DChsSent(A6) CLR.L TDChSent(A6) CLR.L DChsRecd(A6) CLR.L TDChRecd(A6) CLR.L PcksSent(A6) CLR.L TPckSent(A6) CLR.L PcksRecd(A6) CLR.L TPckRecd(A6) CLR.L NAKsSent(A6) CLR.L TNAKSent(A6) CLR.L NAKsRecd(A6) CLR.L TNAKRecd(A6) MOVE.B #DefLocal,Local(A6) Setup the initial mode MOVE.L #DefSpeed,Speed(A6) Setup the default line speed LEA DefLinNm(PC),A1 Setup the default line, if any LEA LineName(A6),A0 This is the line name string MOVEQ #LinNamML,D0 Maximum line name length BSR CopyStr Copy now TST.B (A0) The default line name was null ? BEQ.S InitAll2 Yes, we hope that somebody does this job MOVEQ #RdWrOp,D0 No, try to open it MOVEQ #HostLine,D1 This is the channel number BSR FilOpen Open, if possible TST.B D0 Ok ? BNE.S InitAll1 Yes CLR.B (A0) No, nullify the line name BEQ.S InitAll2 Proceed initialization, no error messages InitAll1 LEA ConLinNm(PC),A1 Yes, point to the console line name BSR CompStr Compare the two line names TST.B D0 Are equal ? SEQ Local(A6) If not we are local, remote otherwise BEQ.S InitAll2 If local, leave speed unchanged MOVE.L #-1,Speed(A6) If remote, say speed unknown InitAll2 MOVE.B #-1,TakLevel(A6) No files to take yet SF TermOut(A6) No terminal output, by now SF Done(A6) Set to false the parser exit flag CLR.B Argumnt1(A6) Nullify the first command argument CLR.B Argumnt2(A6) Nullify the second command argument CLR.B FilName(A6) Nullify current file name CLR.B LinLngth(A6) *** To be removed -rb- *** LEA DefPrmpt(PC),A1 Set up the default prompt LEA Prompt(A6),A0 This is the prompt string MOVEQ #PromptML,D0 Maximum prompt length BSR CopyStr Copy now RTS ends END Kerm68K <<< k6opro.asm >>> 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 <<< k6opsf.asm >>> nam Kermit68K ttl Parser subroutines module * Kermit68K: source file K68PSF * * 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 K68ParserSubs,0,0,Edition,0,0 ******************************** ParsWrd ******************************ok * * * Parse a word string. * * * * Entry conditions : A0.L points to the target string * * A5.L points to the current position * * in the source line * * * * Exit conditions : A0.L points to the last byte of * * the target string * * A5.L points to the current position * * in the source line * * D0.B completion code * * * * -3 nothing to look up (source was null) * * 0 all ok * * * *********************************************************************** ParsWrd: BSR SkipSpr Skip leading separators TST.B (A5) Null source ? BEQ.S ParsWrd4 Yes, return this ParsWrd1 MOVE.B (A5)+,D0 No, get the first character BEQ.S ParsWrd2 End of line, exit loop CMPI.B #' ',D0 Blank ? BEQ.S ParsWrd3 Yes, exit loop CMPI.B #Asc_HT,D0 Tab ? BEQ.S ParsWrd3 Yes, exit loop MOVE.B D0,(A0)+ No, store the character BRA.S ParsWrd1 Loop until end of word ParsWrd2 SUBQ.L #1,A5 Backup line pointer ParsWrd3 CLR.B (A0) Terminate target MOVEQ #0,D0 Return positive completion code RTS ParsWrd4 CLR.B (A0) Terminate target MOVEQ #-3,D0 Return null source completion code RTS ******************************** ParsTxt ******************************ok * * * Parse a text string, quoted or unquoted, this is to allow the * * specification of trailing delimiters. * * * * Entry conditions : A0.L points to the target string * * A5.L points to the current position * * in the source line * * * * Exit conditions : A0.L points to the last byte of * * the target string * * A5.L points to the current position * * in the source line * * D0.B completion code * * D1.B destroyed * * * * -3 nothing to look up (source was null) * * 0 all ok * * * *********************************************************************** ParsTxt: BSR SkipSpr Skip leading separators MOVE.B (A5)+,D0 Get the first character, null source ? BEQ.S ParsTxt7 Yes, return null target cc CMPI.B #$22,D0 Look for a quote character (") BEQ.S ParsTxt1 CMPI.B #$27,D0 Look for a quote character (') BEQ.S ParsTxt1 CMPI.B #$60,D0 Look for a quote character (`) BNE.S ParsTxt2 ParsTxt1 MOVE.B D0,D1 Save the quote character BRA.S ParsTxt4 ParsTxt2 CLR.B D1 Clear the quote register ParsTxt3 MOVE.B D0,(A0)+ Write character to target string ParsTxt4 MOVE.B (A5)+,D0 Get a character BEQ.S ParsTxt6 If end of line exit loop CMP.B D0,D1 Quote character again ? BNE.S ParsTxt3 No, write char to target, stay in loop CLR.B (A0) Yes, terminate target ParsTxt5 MOVEQ #0,D0 Return positive completion code RTS ParsTxt6 MOVE.B -(A5),(A0) Backup line pointer and terminate target BRA.S ParsTxt5 Return positive completion code ParsTxt7 MOVE.B -(A5),(A0) Backup line pointer and terminate target MOVEQ #-3,D0 Return null source completion code RTS ******************************** ParsNm *******************************ok * * * Parse a number. * * * * Entry conditions : D1.L range specification, lower bound * * D2.L range specification, upper bound * * A5.L points to the current position * * in the source line * * * * Exit conditions : D0.L parsed number (if any) * * D1.B completion code * * A0.L destroyed * * A1.L destroyed * * A5.L points to the current position * * in the source line * * * * -3 nothing to parse (source was null) * * -2 number out of range * * -1 illegal number specification * * 0 all ok, number in D0.L * * * *********************************************************************** ParsNm: MOVEM.L D3-D6,-(A7) Save working registers LEA DataBuf(A6),A1 Pointer to temporary buffer MOVEA.L A1,A0 Put here the parsed word BSR ParsWrd Get a word from the source line TST.B D0 Null source ? BLT ParsNm12 Yes, return this condition code MOVEA.L A1,A0 Set up for addressing CLR.L D0 Clear the number register CLR.L D3 Clear the character register MOVE.B (A0)+,D3 Get the first character CMPI.B #'$',D3 Hexadecimal ? BEQ.S ParsNm1 Yes, set base register CMPI.B #'\',D3 Octal ? BEQ.S ParsNm2 Yes, set base register CMPI.B #'%',D3 Binary ? BEQ.S ParsNm3 Yes, set base register to binary MOVEQ #10,D4 No, set base register to decimal BRA.S ParsNm5 ParsNm1 MOVEQ #16,D4 Set base register to hexadecimal BRA.S ParsNm4 ParsNm2 MOVEQ #8,D4 Set base register to octal BRA.S ParsNm4 ParsNm3 MOVEQ #2,D4 Set base register to binary ParsNm4 MOVE.B (A0)+,D3 Got a base specification, get next BEQ.S ParsNm10 End of word, invalid number ParsNm5 CMPI.B #'-',D3 Look for a minus sign SEQ D5 Set a flag accordingly BNE.S ParsNm6 Enter the conversion loop MOVE.B (A0)+,D3 Got a minus sign, get next BEQ.S ParsNm10 End of word, invalid number ParsNm6 BSR UppCase SUBI.B #'0',D3 First offset BLT.S ParsNm10 Less than '0', invalid number CMPI.B #9,D3 Above 9 ? BLE.S ParsNm7 No SUBQ.B #7,D3 Yes, second offset ParsNm7 CMP.B D4,D3 Above the base value ? BGE.S ParsNm10 Yes, invalid number specification MOVE.L D0,D6 Make some computation MULU D4,D0 SWAP D6 MULU D4,D6 SWAP D6 CLR.W D6 ADD.L D6,D0 ADD.L D3,D0 MOVE.B (A0)+,D3 Get the next character, if any BNE.S ParsNm6 Repeat until end of word TST.B D5 Negative number ? BEQ.S ParsNm8 No NEG.L D0 Yes, negate it ParsNm8 CMP.L D1,D0 Less than lower bound ? BLT.S ParsNm11 Yes, return the proper cc CMP.L D2,D0 Greater than upper bound ? BGT.S ParsNm11 Yes, return the proper cc MOVEQ #0,D1 Provide positive completion code ParsNm9 MOVEM.L (A7)+,D3-D6 Restore working registers RTS ParsNm10 MOVEA.L A1,A0 Pointer to the guilty word LEA PrNmStr1(PC),A1 Pointer to the error message string BSR ParsErr Give the appropriate message MOVEQ #-1,D1 Return invalid number cc BRA.S ParsNm9 ParsNm11 MOVEA.L A1,A0 Pointer to the guilty word LEA PrNmStr2(PC),A1 Pointer to the error message string BSR ParsErr Give the appropriate message MOVEQ #-2,D1 Return number out of range cc BRA.S ParsNm9 ParsNm12 SUBA.L A0,A0 No guilty word in this case LEA PrNmStr3(PC),A1 Pointer to the error message string BSR ParsErr Give the appropriate message MOVEQ #-3,D1 Return missing number specification cc BRA.S ParsNm9 ******************************** ParsKyW ******************************ok * * * Parse a keyword, giving, on error, appropriate messages. * * * * Entry conditions : D1.B flag for mandatory keywords * * A1.L points to keywords table * * A5.L points to the current position * * in the source line * * * * Exit conditions : D0.B completion code * * * * -3 nothing to look up (source was null) * * -2 ambiguous keyword * * -1 keyword not found * * n >= 0 value associated with keyword * * * * D2.B destroyed * * A0.L destroyed * * A1.L destroyed * * A2.L destroyed * * * *********************************************************************** ParsKyW: LEA DataBuf(A6),A2 Pointer to temporary buffer MOVEA.L A2,A0 Put here the parsed word BSR ParsWrd Get a word from the source line MOVEA.L A2,A0 Set up for addressing BSR Lookup Search the keyword in the given table TST.B D0 Some error condition reported ? BGE.S ParsKyW5 No, return value in D0.B MOVE.B D0,D2 Yes, save the completion code ADDQ.B #1,D0 Unrecognized keyword ? BEQ.S ParsKyW1 Yes, give error message ADDQ.B #1,D0 Ambiguous keyword ? BEQ.S ParsKyW2 Yes, give error message TST.B D1 No, missing keyword, was it mandatory ? BEQ.S ParsKyW4 No, no message, return bad cc LEA PrKyStr3(PC),A0 Yes, give missing keyword error message BSR ConWrite Write the message MOVEA.L A1,A0 Write the requested object name BSR ConWrite BSR NewLine Start a new line BRA.S ParsKyW4 Newline and return ParsKyW1 LEA PrKyStr1(PC),A0 Give unrecognized keyword error message BRA.S ParsKyW3 Join common part ParsKyW2 LEA PrKyStr2(PC),A0 Give ambiguous keyword error message ParsKyW3 BSR ConWrite Write the error type string MOVEA.L A1,A0 Write the requested object name BSR ConWrite MOVEA.L A2,A0 Write the guilty word SUBA.L A1,A1 Error message already given BSR ParsErr ParsKyW4 MOVE.B D2,D0 Restore the completion code from LookUp ParsKyW5 RTS ******************************* ParsInF *******************************ok * * * Parse an input file name specification. * * * * Entry conditions : A0.L point to the target string * * A5.L points to the current position * * in the source line * * * * Exit conditions : D0.B completion code * * * * -3 nothing to parse (source was null) * * -2 illegal file name specification * * 0 all ok * * * * A1.L destroyed * * A5.L points to the current position * * in the source line * * * *********************************************************************** ParsInF: MOVEA.L A0,A1 Save the target pointer BSR ParsWrd Get a word from the command line TST.B D0 Null source ? BLT.S ParsInF2 Yes, return this MOVEA.L A1,A0 Reload target pointer BSR ChkWild Check for wild characters TST.B D0 Wild filename ? BNE.S ParsInF3 Yes, try to expand it BSR ChkInpF Check if file exists and is readable TST.B D0 Inexistent or unreadable file ? BLT.S ParsInF5 Yes, give error message ParsInF1 MOVEQ #0,D0 No, all ok, return positive cc ParsInF2 RTS ParsInF3 BSR ExpandFN Try to expand the wild file name TST.L D0 Check the result BGT.S ParsInF1 All ok, at least one match BLT.S ParsInF4 Too many matches, give error message LEA PrIFStr4(PC),A0 No matches, error BRA.S ParsInF8 Join common part ParsInF4 LEA PrIFStr5(PC),A0 Notify overflow during name expansion BRA.S ParsInF8 Join common part ParsInF5 ADDQ.B #1,D0 File not found ? BEQ.S ParsInF6 Yes ADDQ.B #1,D0 File not readable ? BEQ.S ParsInF7 Yes LEA PrIFStr3(PC),A0 No, read permission denied BRA.S ParsInF8 Join common part ParsInF6 LEA PrIFStr1(PC),A0 File not found error message BRA.S ParsInF8 Join common part ParsInF7 LEA PrIFStr2(PC),A0 File not readable error message ParsInF8 EXG A0,A1 Setup pointers BSR ParsErr Call the error messages routine MOVEQ #-2,D0 Return a negative completion code RTS ******************************* ParsOuF *******************************ok * * * Parse an output file name specification. * * * * Entry conditions : A0.L point to the target string * * A5.L points to the current position * * in the source line * * * * Exit conditions : A5.L points to the current position * * in the source line * * D0.B completion code * * * * -3 nothing to parse (source was null) * * -2 illegal output file name * * 0 all ok * * * *********************************************************************** ParsOuF: MOVEA.L A0,A1 Save the target pointer BSR ParsWrd Get a word from the command line TST.B D0 Null source ? BLT.S ParsOuF1 Yes, return this MOVEA.L A1,A0 Reload target pointer BSR ChkWild Check for wild characters TST.B D0 Wild filename ? BNE.S ParsOuF2 Yes, give error message BSR ChkOutF Check if file can be created TST.B D0 Permission denied ? BLT.S ParsOuF3 Yes, give error message MOVEQ #0,D0 No, all ok, return positive cc ParsOuF1 RTS ParsOuF2 LEA POuFStr1(PC),A0 Give wildcard not allowed error message BRA.S ParsOuF4 Join common part ParsOuF3 LEA POuFStr2(PC),A0 Give permission denied error message ParsOuF4 EXG A0,A1 Setup pointers BSR ParsErr Call the error messages routine MOVEQ #-2,D0 Return negative completion code RTS ******************************* ChkWild *******************************ok * * * Check a string for wildcard character presence. * * * * Entry conditions : A0.L points to the string to check * * * * Exit conditions : D0.B completion code * * A0.L points to the checked string * * * *********************************************************************** ChkWild: MOVE.L A0,-(A7) Save the string pointer ChkWild1 MOVE.B (A0)+,D0 Get a character BEQ.S ChkWild3 End of string, exit loop, return false CMPI.B #'*',D0 Match-all wildcard character ? BEQ.S ChkWild2 Yes, the file name is wild CMPI.B #'?',D0 Match-one wildcard character ? BNE.S ChkWild1 No, loop until end of string ChkWild2 ST D0 Yes, exit loop, return true ChkWild3 MOVE.L (A7)+,A0 Restore the string pointer RTS ********************************* Lookup ******************************ok * * * Lookup a keyword in the given array of keywords. * * * * Entry conditions : A0.L points to the source string * * null terminated * * A1.L points to the keywords table * * * * Exit conditions : D0.B completion code * * * * -3 nothing to look up (target was null) * * -2 ambiguous keyword * * -1 keyword not found * * n >= 0 value associated with keyword * * * * A0.L points to the source string * * null terminated * * A1.L points to the object name * * * *********************************************************************** Lookup MOVEM.L A2/D1-D4,-(A7) Save working registers CLR.B D1 Clear matchs counter TST.B (A0) Null keyword ? BNE.S Lookup2 No, continue Lookup1 MOVE.B (A1)+,D4 Yes, skip to end of table CMPI.B #-1,D4 End of table ? BNE.S Lookup1 No, loop MOVEQ #-3,D0 Return nothing to look up cc BRA.S Lookup8 Lookup2 MOVE.B (A1)+,D4 Get the value associated to this word CMPI.B #-1,D4 End of table ? BEQ.S Lookup7 Yes, check if match(s) occurred MOVEA.L A0,A2 Lookup3 MOVE.B (A2)+,D3 Get next character from command line BEQ.S Lookup4 End of word, match ! BSR UppCase Upper case it for compare MOVE.B (A1)+,D2 Get a character from table BEQ.S Lookup2 End of word, no match, try the next CMP.B D3,D2 Match ? BNE.S Lookup5 No, skip to the next table element BRA.S Lookup3 Yes, look to the next character Lookup4 TST.B (A1) Match found, is a supermatch ? BEQ.S Lookup6 Yes, stop searching ADDQ.B #1,D1 No, increment matchs counter MOVE.B D4,D0 Load the return value Lookup5 MOVE.B (A1)+,D2 Skip to next table element BNE.S Lookup5 Skip characters until end of word BRA.S Lookup2 Scan all the table elements Lookup6 MOVE.B D4,D0 Supermatch found, load the return value BRA.S Lookup8 Lookup7 CMPI.B #1,D1 Check matchs counter BLT.S Lookup9 If no match return keyword not found cc BGT.S Lookup10 More than 1, ambiguous keyword cc Lookup8 MOVEM.L (A7)+,A2/D1-D4 Restore working registers RTS Lookup9 MOVEQ #-1,D0 Return the keyword not found cc BRA.S Lookup8 Lookup10 MOVEQ #-2,D0 Return the ambiguous keyword cc BRA.S Lookup8 ********************************* ParsErr *****************************ok * * * Give a parsing error message. * * * * Entry conditions : A0.L point to the guilty word * * null terminated, no guilty word * * to print if null pointer passed * * A1.L point to the error message, no * * message to print if null pointer * * passed * * * * Exit conditions : D0.L destroyed * * D1.L destroyed * * * *********************************************************************** ParsErr: EXG A0,A1 Write the error string first, if any MOVE.L A0,D1 Null pointer passed ? BEQ.S ParsErr1 Yes, no error message BSR ConWrite No, write it ParsErr1 MOVE.L A1,D1 Null pointer passed ? BEQ.S ParsErr4 Yes, no guilty word LEA PrErStr1(PC),A0 No, point to separator string BSR ConWrite Write it to terminal MOVEQ #'"',D0 Type the leading quotation mark BSR ConOut ParsErr2 MOVE.B (A1)+,D0 And then the guilty word BEQ.S ParsErr3 If end of word, exit loop BSR ConOut Write a character BRA.S ParsErr2 And the next, if any ParsErr3 MOVEQ #'"',D0 Type the trailing quotation mark BSR ConOut ParsErr4 BSR NewLine Start a new line RTS ******************************* SkipSpr *******************************ok * * * Skip leading separators from the command line. * * * * Entry conditions : A5.L point to the current position * * in the command line * * * * Exit conditions : D0.B destroyed * * A5.L point to the current position * * in the command line * * * *********************************************************************** SkipSpr MOVE.B (A5)+,D0 Get a character BEQ.S SkipSpr1 End of buffer, exit CMPI.B #' ',D0 Blank ? BEQ.S SkipSpr Yes, skip CMPI.B #Asc_HT,D0 Tab ? BEQ.S SkipSpr Yes, skip SkipSpr1 SUBQ.L #1,A5 Backup line pointer RTS ends END <<< k6opt2.asm >>> nam Kermit68K ttl Low-level protocol subroutines module * Kermit68K: source file K68PT2 * * 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 K68ProtoFuncs2,0,0,Edition,0,0 ******************************* TrnsInit ******************************ok * * * Initialize a transaction. * * * * Entry conditions : none * * * * Exit conditions : none * * * *********************************************************************** TrnsInit: MOVE.B #1,BlChkUs(A6) Reset block check type to 1 SF Bit8Flag(A6) Reset 8th bit quoting stuff MOVE.B #1,NextPckN(A6) Reset packet counters MOVE.B #0,PackNum(A6) MOVE.B #-1,PrevPckN(A6) SF MStrFlag(A6) Reset memory string flag CLR.L MStrgPnt(A6) Reset memory string pointer SF CtlXSeen(A6) Reset interrupts flag SF CtlZSeen(A6) CLR.B SendBuf(A6) Clear send buffer CLR.B FilName(A6) Clear current file name MOVE.B RtryInit(A6),Retry(A6) Initialize the retry limit CLR.L ChrsSent(A6) Clear the statistic variables CLR.L ChrsRecd(A6) CLR.L DChsSent(A6) CLR.L DChsRecd(A6) CLR.L PcksSent(A6) CLR.L PcksRecd(A6) CLR.L NAKsSent(A6) CLR.L NAKsRecd(A6) RTS *********************************** SetGCmd ***************************ok * * * Setup for generic commands. * * * * Entry conditions : D0.B command type * * A0.L destroyed * * A1.L destroyed * * A2.L first argument address, if any * * A3.L second argument address, if any * * A4.L third argument address, if any * * * * Exit conditions : D0.L destroyed * * * *********************************************************************** SetGCmd: LEA CmdBuf(A6),A1 Load pointer to command buffer MOVE.B D0,(A1)+ Write command type CLR.B (A1) Terminate it MOVE.L A2,D0 First argument pointer null ? BEQ.S SetGCmd1 Yes, exit TST.B (A2) No, first argument null ? BEQ.S SetGCmd1 Yes, exit MOVEA.L A2,A0 Load pointer to first argument BSR CpStrLn Copy it to data buffer MOVE.L A3,D0 Second argument pointer null ? BEQ.S SetGCmd1 Yes, exit TST.B (A3) No, second argument null ? BEQ.S SetGCmd1 Yes, exit MOVEA.L A3,A0 Load pointer to second argument BSR CpStrLn Copy it to data buffer MOVE.L A4,D0 Third argument pointer null ? BEQ.S SetGCmd1 Yes, exit TST.B (A4) No, third argument null ? BEQ.S SetGCmd1 Yes, exit MOVEA.L A4,A0 Load pointer to third argument BSR CpStrLn Copy it to data buffer SetGCmd1 MOVE.B #'G',ServrCmd(A6) Generic command packet type BSR TrnsInit Initialize the transaction RTS ********************************* Decode ******************************ok * * * Kermit packet decoding procedure, decodes from DataBuf and call an * * output function at the given address. * * * * Entry conditions : A0.L address of the output function * * * * Exit conditions : D0.B completion code * * * *********************************************************************** Decode: MOVEM.L A1/D1-D3,-(A7) Save working registers LEA DataBuf(A6),A1 Pointer to data buffer Decode1 MOVEQ #1,D3 Setup the repeat counter MOVE.B (A1)+,D0 Get a character BEQ.S Decode9 Exit at end of buffer TST.B ReptFlag(A6) Repeat processing ? BEQ.S Decode2 No CMP.B ReptQuot(A6),D0 Yes, got a repeat prefix ? BNE.S Decode2 No MOVE.B (A1)+,D3 Yes, get the repeat count SUBI.B #32,D3 Convert it ... MOVE.B (A1)+,D0 ... and get the prefixed character Decode2 MOVEQ #$00,D1 Clear the 8th bit register TST.B Bit8Flag(A6) 8th bit prefixing ? BEQ.S Decode3 No CMP.B Bit8Quot(A6),D0 Yes, got an 8th bit prefix ? BNE.S Decode3 No MOVEQ #$80,D1 Yes, remember this ... MOVE.B (A1)+,D0 ... and get the prefixed character Decode3 CMP.B ICtlQuot(A6),D0 Got a control prefix ? BNE.S Decode6 No MOVE.B (A1)+,D0 Yes, get its operand MOVE.B D0,D2 Make a copy ANDI.B #$7F,D2 Only look at lower 7 bits CMPI.B #$40,D2 Above Null ? BLT.S Decode4 No, look for Delete CMPI.B #$5F,D2 Yes, between Null and US ? BLE.S Decode5 Yes, uncontrollify Decode4 CMPI.B #'?',D2 Delete ? BNE.S Decode6 No, character not in control range Decode5 EORI.B #64,D0 Uncontrollify Decode6 OR.B D1,D0 OR in the 8th bit TST.B Binary(A6) Are we in binary mode ? BNE.S Decode8 Yes, CRLF-nl mapping not needed CMPI.B #Asc_CR,D0 Carriage Return ? BEQ.S Decode1 Yes, discard it CMPI.B #Asc_LF,D0 No, Line Feed ? BNE.S Decode8 No MOVEQ #NewLinCh,D0 Yes, convert it into newline character BRA.S Decode8 Ok, ready for output Decode7 JSR (A0) Call the output function TST.B D1 Check completion code BNE.S Decode9 If failure return ADDQ.L #1,DChsRecd(A6) Increment data chars received this trans ADDQ.L #1,TDChRecd(A6) Increment total data characters received Decode8 DBF D3,Decode7 Output char repeat times (at least 1) BRA.S Decode1 Decode9 MOVEM.L (A7)+,A1/D1-D3 Restore working registers RTS ******************************** CmdBfOut *****************************ok * * * Output to command buffer, called by Decode. * * * * Entry conditions : D0.B character to output * * * * Exit conditions : D1.B AllOk completion code (0) * * * *********************************************************************** CmdBfOut: MOVE.L A0,-(A7) Save register LEA CmdBuf(A6),A0 Point to command buffer start address CLR.W D1 Clear the index register MOVE.B CmdBfPnt(A6),D1 Load relative pointer to command buffer MOVE.B D0,(A0,D1.W) Write the character ADDQ.B #1,D1 Increment the index register CLR.B (A0,D1.W) Make sure buffer is null-terminated MOVE.B D1,CmdBfPnt(A6) Save the index register MOVEQ #AllOk,D1 Return a positive competion code (0) MOVE.L (A7)+,A0 Restore register RTS ********************************* Encode ******************************ok * * * Kermit packet encoding procedure, encodes to DataBuf. * * * * Entry conditions : D0.B character to be encoded * * D2.W current size of output data packet * * * * Exit conditions : D2.W current size of output data packet * * D1.L destroyed * * D3.B destroyed * * A1.L destroyed * * * *********************************************************************** Encode: LEA DataBuf(A6),A1 Pointer to data buffer TST.B ReptFlag(A6) Repeat processing ? BEQ.S Encode5 No, do prefixing CMP.B Next(A6),D0 Current and next character are equal ? BNE.S Encode4 No TST.B First(A6) Input in progress BNE.S Encode4 No, first time called ADDQ.B #1,ReptCnt(A6) Increment the repeat counter CMPI.B #94,ReptCnt(A6) Below max ? BEQ.S Encode2 No, max reached, must dump RTS Yes, just count and return Encode1 ADDQ.B #1,ReptCnt(A6) More than 2 character to repeat Encode2 MOVE.B ReptQuot(A6),(A1,D2.W) Write the repeat quote ADDQ.W #1,D2 Increment the pointer register MOVE.B ReptCnt(A6),D1 Get the repeat count ADDI.B #32,D1 Convert it into a character MOVE.B D1,(A1,D2.W) Write the repeat count ADDQ.W #1,D2 Increment the pointer register Encode3 CLR.B ReptCnt(A6) Reset the repeat counter BRA.S Encode5 Done repeat processing, do prefixing Encode4 CMPI.B #1,ReptCnt(A6) Run broken, only 2 ? BLT.S Encode5 No, only 1, do it BGT.S Encode1 No, more than 2 MOVE.B D0,D3 Yes, do the character twice, save char BSR.S Encode5 Do it the first time MOVE.B D3,D0 Restore the character CMP.B OMPckSiz(A6),D2 Max packet size exceded ? BGT.S Encode3 Yes, do the character again MOVE.B D2,OldSize(A6) No, update OldSize BRA.S Encode3 Do the character again Encode5 MOVEQ #$7F,D1 Isolate ASCII part AND.B D0,D1 BTST #7,D0 Do 8th bit prefixing if necessary BEQ.S Encode6 TST.B Bit8Flag(A6) BEQ.S Encode6 MOVE.B Bit8Quot(A6),(A1,D2.W) Write the 8th bit quote ADDQ.W #1,D2 Increment the pointer register MOVE.B D1,D0 Encode6 CMPI.B #' ',D1 Do control prefixing if necessary BLT.S Encode7 CMPI.B #Asc_Del,D1 Delete ? BNE.S Encode8 No, character not in control range Encode7 EORI.B #64,D0 Uncotrollify BRA.S Encode10 Encode8 CMPI.B #MyCtlQot,D1 Prefix the control prefix BEQ.S Encode10 CMP.B ReptQuot(A6),D1 If it's the repeat prefix ... BNE.S Encode9 TST.B ReptFlag(A6) ... quote it if doing repeat counts BEQ.S Encode11 BRA.S Encode10 Encode9 CMP.B Bit8Quot(A6),D1 Prefix the 8th bit prefix ... BNE.S Encode11 TST.B Bit8Flag(A6) ... if doing 8th-bit prefixes BEQ.S Encode11 Encode10 MOVE.B #MyCtlQot,(A1,D2.W) Write the control quote ADDQ.W #1,D2 Increment the pointer register Encode11 MOVE.B D0,(A1,D2.W) Finally, insert the character ADDQ.W #1,D2 Increment the pointer register CLR.B (A1,D2.W) Mark the end RTS ********************************* SndParm *****************************ok * * * Fill the data buffer with my send-init parameters. * * * * Entry conditions : none * * * * Exit conditions : D0.L data length * * D1.L destroyed * * A0.L destroyed * * * *********************************************************************** SndParm: LEA DataBuf(A6),A0 Pointer to send buffer MOVEQ #32,D1 Load register for quick addition MOVE.B IMPckSiz(A6),D0 Biggest packet I can receive ADD.B D1,D0 Conversion into a printable character MOVE.B D0,(A0)+ Put it into data buffer MOVE.B OTimInt(A6),D0 When I want to be timed out ADD.B D1,D0 Conversion into a printable character MOVE.B D0,(A0)+ Put it into data buffer MOVE.B IPadNumb(A6),D0 How much padding I need ADD.B D1,D0 Conversion into a printable character MOVE.B D0,(A0)+ Put it into data buffer MOVE.B IPadChar(A6),D0 Padding character I want EORI.B #64,D0 Uncontrollify it MOVE.B D0,(A0)+ Put it into data buffer MOVE.B IEOL(A6),D0 End-Of-Line character I want ADD.B D1,D0 Conversion into a printable character MOVE.B D0,(A0)+ Put it into data buffer MOVE.B OCtlQuot(A6),(A0)+ Control-Quote character I send MOVE.B Parity(A6),D0 Parity is enabled or the ... OR.B Bit8Flag(A6),D0 ... 8th bit processing flag is on ? BEQ.S SndParm1 No, no need for 8th bit quoting MOVE.B #My8BQuot,(A0)+ Send my 8th bit quote character MOVE.B Bit8Quot(A6),D0 Get quote CMPI.B #'Y',D0 If other side say YES to do ... SEQ Bit8Flag(A6) ... 8th bit quoting BEQ.S SndParm2 BSR ChkQuot If other side specify a valid quote ... MOVE.B D0,Bit8Flag(A6) ... turn the 8th bit quoting flag on BRA.S SndParm2 SndParm1 MOVE.B #'Y',(A0)+ Normally just say we're willing SndParm2 MOVE.B BlChkRq(A6),D0 Block check type ADDI.B #'0',D0 Conversion into a printable character MOVE.B D0,(A0)+ Send it MOVE.B #MyRptQot,(A0)+ Do repeat counts CLR.B (A0) Terminator MOVEQ #9,D0 Return length RTS ******************************** RdParam ******************************ok * * * Get the other host's send-init parameters. * * * * Entry conditions : none * * * * Exit conditions : D0.B destroyed * * D1.B destroyed * * D2.L destroyed * * A0.L destroyed * * * *********************************************************************** RdParam: LEA DataBuf(A6),A0 Pointer to data buffer MOVEQ #32,D2 Load register for quick subtraction MOVE.B #DefMxPSz,OMPckSiz(A6) Maximum send packet size MOVE.B #DefTmOut,ITimInt(A6) When I should time out MOVE.B #DefPadNm,OPadNumb(A6) Number of pads to send MOVE.B #DefPadCr,OPadChar(A6) Padding character to send MOVE.B #DefEOL,OEOL(A6) EOL character I must send MOVE.B #DefCtlQt,ICtlQuot(A6) Incoming data quote character MOVE.B Bit8Flag(A6),D1 Save 8th bit processing flag SF Bit8Flag(A6) No 8th bit quoting by default MOVE.B #1,BlChkRq(A6) Block check type requested SF ReptFlag(A6) No repeat processing by default MOVE.B (A0)+,D0 Maximum send packet size BEQ RdParam9 SUB.B D2,D0 TST.B SndPSFlg(A6) Override privilege ? BEQ.S RdParam1 No, continue CMPI.B #10,D0 Yes, less than 10 ? BLT.S RdParam2 Yes, leave unchanged the default value RdParam1 MOVE.B D0,OMPckSiz(A6) No, update RdParam2 MOVE.B (A0)+,D0 When I should time out BEQ RdParam9 SUB.B D2,D0 TST.B TimInFlg(A6) Override privilege ? BEQ.S RdParam3 No, continue TST.B D0 Yes, less than 0 ? BLT.S RdParam4 Yes, leave unchanged the default value RdParam3 MOVE.B D0,ITimInt(A6) No, update RdParam4 MOVE.B (A0)+,D0 Number of pads to send BEQ RdParam9 SUB.B D2,D0 MOVE.B D0,OPadNumb(A6) MOVE.B (A0)+,D0 Padding character to send BEQ.S RdParam9 EORI.B #64,D0 MOVE.B D0,OPadChar(A6) MOVE.B (A0)+,D0 EOL character I must send BEQ.S RdParam9 SUB.B D2,D0 CMPI.B #Asc_STx,D0 Valid range EOL character ? BCS.S RdParam5 No, leave unchanged the default value CMPI.B #Asc_US,D0 Valid range EOL character ? BHI.S RdParam5 No, leave unchanged the default value MOVE.B D0,OEOL(A6) RdParam5 MOVE.B (A0)+,D0 Incoming data quote character BEQ.S RdParam9 MOVE.B D0,ICtlQuot(A6) MOVE.B (A0)+,D0 8th bit quote character BEQ.S RdParam9 MOVE.B D0,Bit8Quot(A6) CMPI.B #'Y',D0 If flag off, then turn it on ... BNE.S RdParam6 ... if other side has asked us to OR.B Parity(A6),D1 ... or if we need it on BEQ.S RdParam7 ST Bit8Flag(A6) MOVE.B #My8BQuot,Bit8Quot(A6) BRA.S RdParam7 RdParam6 BSR ChkQuot MOVE.B D0,Bit8Flag(A6) RdParam7 MOVE.B (A0)+,D0 Block check type BEQ.S RdParam9 SUBI.B #'0',D0 Range adjust CMPI.B #1,D0 Less than 1 ? BCS.S RdParam8 Yes, invalid CMPI.B #3,D0 Greater than 3 ? BHI.S RdParam8 Yes, invalid MOVE.B D0,BlChkRq(A6) Ok, store block check type requested RdParam8 MOVE.B (A0)+,D0 Repeat prefix BEQ.S RdParam9 MOVE.B D0,ReptQuot(A6) BSR ChkQuot MOVE.B D0,ReptFlag(A6) RdParam9 RTS ******************************** Check1 *******************************ok * * * Perform a type 1 block check. * * * * Entry conditions : A0.L pointer to string buffer * * * * Exit conditions : D0.B type 1 block check * * * *********************************************************************** Check1: MOVE.W D1,-(A7) Save working register BSR Check2 Compute numeric sum MOVE.W D0,D1 Compute a type 1 checksum ANDI.W #192,D1 LSR.W #6,D1 ADD.W D1,D0 ANDI.W #63,D0 MOVE.W (A7)+,D1 Restore working register RTS ******************************** Check2 *******************************ok * * * Perform a type 2 block check. * * * * Entry conditions : A0.L pointer to string buffer * * * * Exit conditions : D0.W type 2 block check (numeric sum). * * * *********************************************************************** Check2: MOVE.W D1,-(A7) Save working register CLR.W D1 Clear the sum register CLR.W D0 Check21 MOVE.B (A0)+,D0 Get a character BEQ.S Check22 Exit if EOL BSR HndlPar Handle parity ADD.W D0,D1 Sum BRA.S Check21 Repeat until EOL Check22 MOVE.W D1,D0 Return numeric sum MOVE.W (A7)+,D1 Restore working register RTS ******************************** Check3 *******************************ok * * * Perform a type 3 block check, calculates the 16-bit CRC using a * * byte oriented tableless algorithm invented by Andy Lowry from * * Columbia University. The magic number $1081 is derived from the * * CRC-CCITT polynomial x^16+x^12+x^5+1. * * * * Entry conditions : A0.L pointer to string buffer * * * * Exit conditions : D0.L type 3 block check (CRC-CCITT). * * * *********************************************************************** Check3: MOVEM.L D1-D3,-(A7) Save working registers CLR.L D1 Clear character register CLR.L D2 Clear CRC register Check31 MOVE.B (A0)+,D0 Get a character BEQ.S Check32 Null, end of string buffer BSR HndlPar Remove parity bit if necessary MOVE.B D0,D1 Load the character register MOVE.L D1,D3 Low order nibble EOR.L D2,D3 MOVEQ #$0F,D0 AND.L D0,D3 ASR.L #4,D2 MULU #$1081,D3 EOR.L D3,D2 MOVE.L D1,D3 High order nibble LSR.L #4,D3 EOR.L D2,D3 MOVEQ #$0F,D0 AND.L D0,D3 ASR.L #4,D2 MULU #$1081,D3 EOR.L D3,D2 BRA.S Check31 Repeat until end of string buffer Check32 MOVE.L D2,D0 Return CRC-CCITT MOVEM.L (A7)+,D1-D3 Restore working registers RTS ******************************** BumpPckN *****************************ok * * * Bump packet counters. * * * * Entry conditions : none * * * * Exit conditions : none * * * *********************************************************************** BumpPckN: MOVE.B PackNum(A6),PrevPckN(A6) Save previous packet number MOVE.B NextPckN(A6),PackNum(A6) Update current packet number ADDQ.B #1,NextPckN(A6) Increment next packet number ANDI.B #63,NextPckN(A6) Modulo 64 RTS *********************************** CpStrLn ***************************ok * * * Copy a null terminated string to a buffer adding a leading * * encoded character count. * * * * Entry conditions : A0.L source string buffer address * * A1.L target buffer address * * * * Exit conditions : A1.L target buffer next char address * * D0.L destroyed * * D1.B destroyed * * * *********************************************************************** CpStrLn: MOVEQ #0,D0 Preset the counter/index register CpStrLn1 MOVE.B (A0)+,1(A1,D0.W) Move a character BEQ.S CpStrLn2 Exit on end of string ADDQ.W #1,D0 Increment the counter/index register BRA.S CpStrLn1 Loop for all characters CpStrLn2 MOVE.B D0,D1 Get the length BEQ.S CpStrLn3 Return if source was null ADDI.B #32,D1 Encode length MOVE.B D1,(A1) Write it on the first target buffer byte LEA 1(A1,D0.W),A1 Address of next available buffer byte CpStrLn3 RTS ******************************** ChkQuot ******************************ok * * * Check if a character is a valid quote. * * * * Entry conditions : D0.B character to check * * * * Exit conditions : D0.B completion code * * * *********************************************************************** ChkQuot CMPI.B #'!',D0 BCS.S ChkQuot2 CMPI.B #'>',D0 BLS.S ChkQuot1 CMPI.B #'`',D0 BCS.S ChkQuot2 CMPI.B #$7E,D0 ChkQuot1 SLS D0 RTS ChkQuot2 SF D0 RTS ends END <<< k6optf.asm >>> 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 <<< k6ostr.asm >>> nam Kermit68K ttl Character strings module * Kermit68K: source file K68STR * * 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 K68Strings,0,0,Edition,0,0 *** Strings from the K68SystemPart module *** ConLinNm: DC.B "/Term",Asc_Nul Console line name DefLinNm: DC.B "/T1",Asc_Nul Default line name for connect DefPrmpt: DC.B "Kermit68K> ",Asc_Nul Default prompt string InitFile: DC.B "Kermit.ini",Asc_Nul Init file name *** Strings from the K68Commands module *** StLnFStr: DC.B "You must 'set line' before issuing this command" DC.B Asc_CR,Asc_LF,Asc_Nul NoCopStr: DC.B "Can't copy file(s)",Asc_Nul NoCWDStr: DC.B "Can't change working directory",Asc_Nul NoDelStr: DC.B "Can't delete file(s)",Asc_Nul NoDirStr: DC.B "Can't list directory",Asc_Nul NoPriStr: DC.B "Can't print file(s)",Asc_Nul NoRenStr: DC.B "Can't rename file(s)",Asc_Nul NoSpaStr: DC.B "Can't show disk usage",Asc_Nul NoTypStr: DC.B "Can't type file(s)",Asc_Nul NoSyCStr: DC.B "Can't forward command to system",Asc_Nul TFNDpStr: DC.B "?Take files nested too deeply",Asc_Nul MsFSpStr: DC.B "?Missing file specification",Asc_Nul KerCmStr: DC.B Asc_LF,"Kermit68K commands:" DC.B Asc_CR,Asc_LF,Asc_LF,Asc_Nul MacCmStr: DC.B Asc_LF,"User defined macros:" DC.B Asc_CR,Asc_LF,Asc_LF,Asc_Nul NoMacStr: DC.B Asc_LF,"There are no user defined macros." DC.B Asc_CR,Asc_LF,Asc_LF,Asc_Nul MNstAStr: DC.B "?Can't nest macro definitions",Asc_Nul MsMcNStr: DC.B "?Missing macro name",Asc_Nul UnkMcStr: DC.B "?Unknown macro",Asc_Nul ConnStr1: DC.B Asc_CR,Asc_LF DC.B "Connecting thru ",Asc_Nul ConnStr2: DC.B Asc_CR,Asc_LF DC.B "Connected thru ",Asc_Nul ConnStr3: DC.B ", speed ",Asc_Nul ConnStr5: DC.B Asc_CR,Asc_LF DC.B "The escape character is ",Asc_Nul ConnStr6: DC.B ")",Asc_CR,Asc_LF DC.B "Type the escape character followed by C to get" DC.B Asc_CR,Asc_LF DC.B "back, or followed by ? to see other options." DC.B Asc_CR,Asc_LF,Asc_LF,Asc_Nul ConnStr7: DC.B Asc_CR,Asc_LF,Asc_LF DC.B "Kermit68K disconnected." DC.B Asc_CR,Asc_LF,Asc_Nul ConnStr8: DC.B Asc_CR,Asc_LF,Asc_LF DC.B "C to close the connection, or:" DC.B Asc_CR,Asc_LF DC.B " 0 (zero) to send a NULL" DC.B Asc_CR,Asc_LF DC.B " B to send a BREAK" DC.B Asc_CR,Asc_LF DC.B " H to hangup and close connection" DC.B Asc_CR,Asc_LF DC.B " S for status" DC.B Asc_CR,Asc_LF DC.B " ? for help" DC.B Asc_CR,Asc_LF DC.B " escape character twice to send the escape character." DC.B Asc_CR,Asc_LF,Asc_LF,Asc_Nul StatStr1: DC.B "Statistics Transaction Total" DC.B Asc_CR,Asc_LF DC.B " Characters sent ",Asc_Nul StatStr2: DC.B " Data characters sent ",Asc_Nul StatStr3: DC.B " NAKs received ",Asc_Nul StatStr4: DC.B " Packets sent ",Asc_Nul StatStr5: DC.B " Characters received ",Asc_Nul StatStr6: DC.B " Data characters received",Asc_Nul StatStr7: DC.B " NAKs sent ",Asc_Nul StatStr8: DC.B " Packets received ",Asc_Nul *** Strings from the K68Commands2 module *** OpLnEStr: DC.B "Can't open line",Asc_Nul UnsBRStr: DC.B "?Unsupported baud rate",Asc_Nul SetCtStr: DC.B "?Not in ASCII control range",Asc_Nul *** Strings from the K68Commands3 module *** Rm1FOStr: DC.B "?A file specification is required" DC.B Asc_CR,Asc_LF,Asc_Nul Rm2FOStr: DC.B "?Two file specifications are required" DC.B Asc_CR,Asc_LF,Asc_Nul VersStr: DC.B Asc_CR,Asc_LF DC.B "Kermit68K version 1.0.00 from 01 July 1987" DC.B Asc_CR,Asc_LF,Asc_LF DC.B Asc_Nul ShVerStr: DC.B "Warning, this is a preliminary version, for any" DC.B Asc_CR,Asc_LF DC.B "problem or suggestion please contact the author:" DC.B Asc_CR,Asc_LF,Asc_LF DC.B "Roberto Bagnara Bitnet address Bagnara@Iboinfn" DC.B Asc_CR,Asc_LF DC.B "Physics Department DECnet address 39937::BAGNARA" DC.B Asc_CR,Asc_LF DC.B "Bologna University" DC.B Asc_CR,Asc_LF,Asc_LF DC.B "OS-9/68000 Modifications by:" DC.B Asc_CR,Asc_LF DC.B "Steve Williams Arpanet address " DC.B "stevew@sally.utexas.edu" DC.B Asc_CR,Asc_LF,Asc_LF,Asc_Nul ShPStr1: DC.B Asc_CR,Asc_LF DC.B "Communications Parameters:" DC.B Asc_CR,Asc_LF DC.B " Line: ",Asc_Nul ShPStr2: DC.B ", speed: ",Asc_Nul ShPStr3: DC.B "unknown",Asc_Nul ShPStr4: DC.B ", mode: ",Asc_Nul ShPStr5: DC.B "local",Asc_Nul ShPStr6: DC.B "remote",Asc_Nul ShPStr7: DC.B Asc_CR,Asc_LF DC.B " Parity: ",Asc_Nul ShPStr8: DC.B "even",Asc_Nul ShPStr9: DC.B "odd",Asc_Nul ShPStr10: DC.B "mark",Asc_Nul ShPStr11: DC.B "space",Asc_Nul ShPStr12: DC.B "none",Asc_Nul ShPStr13: DC.B ", duplex: ",Asc_Nul ShPStr14: DC.B "half, ",Asc_Nul ShPStr15: DC.B "full, ",Asc_Nul ShPStr16: DC.B "flow: ",Asc_Nul ShPStr17: DC.B "xon/xoff",Asc_Nul ShPStr18: DC.B ", handshake: ",Asc_Nul ShPStr19: DC.B Asc_CR,Asc_LF,Asc_LF DC.B "Protocol Parameters: Send Receive",Asc_Nul ShPStr20: DC.B " (* = override)",Asc_Nul ShPStr21: DC.B Asc_CR,Asc_LF," Timeout: ",Asc_Nul ShPStr22: DC.B Asc_CR,Asc_LF," Padding: ",Asc_Nul ShPStr23: DC.B Asc_CR,Asc_LF," Pad Character:",Asc_Nul ShPStr24: DC.B Asc_CR,Asc_LF," Packet Start: ",Asc_Nul ShPStr25: DC.B Asc_CR,Asc_LF," Packet End: ",Asc_Nul ShPStr26: DC.B Asc_CR,Asc_LF," Packet Length:",Asc_Nul ShPStr27: DC.B Asc_CR,Asc_LF DC.B Asc_CR,Asc_LF,"Block Check Type: ",Asc_Nul ShPStr28: DC.B ", Delay: ",Asc_Nul ShPStr29: DC.B Asc_CR,Asc_LF DC.B "Retry Limits: Initial ",Asc_Nul ShPStr30: DC.B ", Normal ",Asc_Nul ShPStr31: DC.B Asc_CR,Asc_LF,"8th-Bit Prefix: ",Asc_Nul ShPStr32: DC.B Asc_CR,Asc_LF,"Repeat-Count Prefix: ",Asc_Nul ShPStr33: DC.B Asc_CR,Asc_LF,Asc_LF DC.B "File parameters:",Asc_CR,Asc_LF DC.B " File Names: ",Asc_Nul ShPStr34: DC.B "converted",Asc_Nul ShPStr35: DC.B "literal",Asc_Nul ShPStr36: DC.B Asc_CR,Asc_LF," File Type: ",Asc_Nul ShPStr37: DC.B "binary",Asc_Nul ShPStr38: DC.B "text",Asc_Nul ShPStr39: DC.B Asc_CR,Asc_LF," File Warning: ",Asc_Nul ShPStr40: DC.B "on",Asc_Nul ShPStr41: DC.B "off",Asc_Nul ShPStr42: DC.B Asc_CR,Asc_LF," File Display: ",Asc_Nul ShPStr43: DC.B Asc_CR,Asc_LF,"Incomplete File Disposition: ",Asc_Nul ShPStr44: DC.B "keep",Asc_Nul ShPStr45: DC.B "discard",Asc_Nul ShPStr46: DC.B ", Init file: ",Asc_Nul ShPStr47: DC.B " Packet Log: ",Asc_Nul *** Strings from the K68Commands4 module *** LBReqStr: DC.B "?-l and -b required",Asc_CR,Asc_LF,Asc_Nul ABadUStr: DC.B "?-a without -s, -r, or -g" CnfAcStr: DC.B "?Conflicting commands",Asc_CR,Asc_LF,Asc_Nul MsFlNStr: DC.B "?Missing file name",Asc_CR,Asc_LF,Asc_Nul MisLNStr: DC.B "?Communication line device name missing" DC.B Asc_CR,Asc_LF,Asc_Nul UnOpLStr: DC.B "?Unable to open the requested line" DC.B Asc_CR,Asc_LF,Asc_Nul InvABStr: DC.B "?Invalid argument bundling",Asc_CR,Asc_LF,Asc_Nul InvArStr: DC.B "?Invalid argument, type 'kermit -h' for help" DC.B Asc_CR,Asc_LF,Asc_Nul UsageStr: DC.B Asc_CR,Asc_LF DC.B " Usage: kermit [-x arg [-x arg]...[-yyy]...]]" DC.B Asc_CR,Asc_LF DC.B " x is an option that requires an argument," DC.B " y an option with no argument:" DC.B Asc_CR,Asc_LF DC.B " commands (* options also require -l and -b) --" DC.B Asc_CR,Asc_LF DC.B " -s file(s) send " DC.B Asc_CR,Asc_LF DC.B " -r receive" DC.B Asc_CR,Asc_LF DC.B " -k receive to terminal" DC.B Asc_CR,Asc_LF DC.B " * -g file(s) get remote file(s) from server" DC.B Asc_CR,Asc_LF DC.B " -a name alternate name, used with -s, -r, -g" DC.B Asc_CR,Asc_LF DC.B " * -f finish remote server" DC.B Asc_CR,Asc_LF DC.B " -h help - type this message" DC.B Asc_CR,Asc_LF DC.B " settings --" DC.B Asc_CR,Asc_LF DC.B " -l line communication line device" DC.B Asc_CR,Asc_LF DC.B " -b baud line speed, e.g. 1200" DC.B Asc_CR,Asc_LF DC.B " -i binary file" DC.B Asc_CR,Asc_LF DC.B " -p x parity, x is one of e,o,m,s,n" DC.B Asc_CR,Asc_LF DC.B " -t line turnaround handshake = xon," DC.B " half duplex" DC.B Asc_CR,Asc_LF DC.B " -w don't write over preexisting files" DC.B Asc_CR,Asc_LF DC.B " -q be quiet during file transfer" DC.B Asc_CR,Asc_LF DC.B " If no command is included, enter interactive mode" DC.B Asc_CR,Asc_LF,Asc_Nul *** Strings from the K68IOFunctions module *** FlCmdStr: DC.B "Error reading take file",Asc_CR,Asc_LF,Asc_Nul CnBchStr: DC.B "^Z - Cancelling Batch ",Asc_Nul CnFilStr: DC.B "^X - Cancelling File ",Asc_Nul ReSndStr: DC.B "^R - Resending ",Asc_Nul ScrnStr1: DC.B "Sending ",Asc_Nul ScrnStr2: DC.B "Receiving ",Asc_Nul ScrnStr3: DC.B "as ",Asc_Nul ScrnStr4: DC.B " [OK]",Asc_CR,Asc_LF,Asc_Nul ScrnStr5: DC.B " [discarded]",Asc_CR,Asc_LF,Asc_Nul ScrnStr6: DC.B " [interrupted]",Asc_CR,Asc_LF,Asc_Nul ScrnStr7: DC.B "Skipping ",Asc_Nul *** Strings from the K68Protocol module *** CCndLStr: DC.B "Can't condition line",Asc_Nul StSpeStr: DC.B "Sorry, you must 'set speed' first",Asc_Nul ErFRHStr: DC.B "Error from remote host :",Asc_CR,Asc_LF,Asc_Nul TooMTStr: DC.B "Too many tries, last error is ",Asc_Nul NAKRcStr: DC.B "'NAK packet received'",Asc_Nul TimLEStr: DC.B "'timeout limit expired'",Asc_Nul GbPRcStr: DC.B "'garbled packet received'",Asc_Nul POuOSStr: DC.B "'packet out of sequence'",Asc_Nul UkUxPStr: DC.B "Unknown or unexpected packet type",Asc_Nul FNFStr: DC.B "File not found",Asc_Nul TMFStr: DC.B "Too many files",Asc_Nul NRFStr: DC.B "No readable file to send",Asc_Nul FlOErStr: DC.B "Can't open file",Asc_Nul NoNamStr: DC.B "NONAME",Asc_Nul FlCrEStr: DC.B "Can't create file",Asc_Nul *** Strings from the K68ParserSubs module *** PrNmStr1: DC.B "?Invalid number specification",Asc_Nul PrNmStr2: DC.B "?Number out of range",Asc_Nul PrNmStr3: DC.B "?Number specification expected",Asc_Nul PrKyStr1: DC.B "?Unrecognized ",Asc_Nul PrKyStr2: DC.B "?Ambiguous ",Asc_Nul PrKyStr3: DC.B "?Missing ",Asc_Nul PrIFStr1: DC.B "?File not found",Asc_Nul PrIFStr2: DC.B "?File not readable",Asc_Nul PrIFStr3: DC.B "?Read permission denied",Asc_Nul PrIFStr4: DC.B "?No files match",Asc_Nul PrIFStr5: DC.B "?Too many files match",Asc_Nul POuFStr1: DC.B "?Wildcards not allowed",Asc_Nul POuFStr2: DC.B "?Write permission denied",Asc_Nul PrErStr1: DC.B " - ",Asc_Nul align Following code aligned on word boundary ends END <<< k6osys.asm >>> nam Kermit68K ttl OS-9/68000 Dependent module (part 1) * Kermit68K: source file K68SYS.A * * Author: Roberto Bagnara (Bagnara@Iboinfn.Bitnet), * Bologna University, Physics Department, May 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. * * OS9/68000 Modifications performed by Steve Williams * University of Texas at Austin, March 1987 * * Revision History: * Edition Date Author Description * 0 87/03/25 spw Initial implementation for OS-9/68K * 1 87/04/22 spw Added code for ChanCtrl * 2 87/04/23 spw Modifications to SysInit to handle command line * 3 87/05/05 spw Changes to ChanCtrl and SysInit * 4 87/06/05 spw Stripped parity bit on OutChar to Terminal * 5 87/06/20 spw Added line-feed stripping to Terminal output * 6 87/07/02 spw Rejoined sys, sy2 and sy3 for distribution use DefsFile Edition set 6 psect K68sys,0,0,Edition,0,0 ********************************* InpChar ***************************** * * * Try to read a character from the specified logical channel. * * * * Entry conditions : D1.B logical channel number * * * * Exit conditions : D0.B character received, if any * * D1.B Completion Code (see below) * * * * CC symbol Meaning * * * * AllOk No errors, character in D0 * * BadChan Inexistent channel * * ResChan Access reserved, permission denied * * DevNotRd Device not ready (e.g. unmounted) * * NotInpCh Input impossible on this channel * * NotOpRd File not open for read * * UnrInpF Unrecoverable failure during input * * InChLost Input character lost * * InpBreak Break received on input * * BufEmpty Input buffer empty * * BufOvflw Input buffer overflow * * EndOfFil End of file reached on input * * * * NOTES: This routine uses a0, d0, and d1, and restores a0 * *********************************************************************** InpChar: move.l a0,-(sp) Save working register. clr.w -(sp) Make a temporary buffer on the stack add.w d1,d1 Convert to offset in path numbers table lea Pathnums(a6),a0 Base of path numbers table move.w (a0,d1.w),d0 Get the OS-9 path number bne.s InpChar1 Has logical channel been used yet? move.b #NotOpRd,d1 No, complain bra.s InpChar3 InpChar1 move.w #SS_Ready,d1 Check to see if data available os9 I$GetStt bcc.s InpChar2 Data ready, go and read it. cmp.w #E$NotRdy,d1 The not ready code (means no data) bne.s InpChar5 Another OS-9 error code move.b #BufEmpty,d1 Tell caller no data ready bra.s InpChar3 InpChar2 lea 1(sp),a0 pass address of buffer moveq #1,d1 Read one character os9 I$Read bcs.s InpChar5 An OS-9 error move.b #AllOk,d1 Everything OK InpChar3 move.w (sp)+,d0 Get the character read move.l (sp)+,a0 Restore working register rts InpChar5 cmp.b #E$FNA,d1 A permission violation? bne.s InpChar6 move.b #ResChan,d1 bra.s InpChar3 InpChar6 cmp.b #E$EOF,d1 End of file? bne.s InpChar7 move.b #EndOfFil,d1 bra.s InpChar3 InpChar7 move.w #$0707,-(sp) moveq #2,d0 move.l sp,a0 moveq #1,d1 os9 I$Write addq #2,sp move.b #UnrInpF,d1 bra.s InpChar3 ********************************* OutChar ***************************** * * * Try to write a character to the specified logical channel. * * * * Entry conditions : D0.B character to write * * D1.B logical channel number * * * * Exit conditions : D0.B character just sent * * D1.B Completion Code (see below) * * * * CC symbol Meaning * * * * AllOk No errors * * BadChan Inexistent channel * * ResChan Access reserved, permission denied * * DevNotRd Device not ready (e.g. unmounted) * * NotOutCh Output impossible on this channel * * NotOpWr File not open for write * * UnrOutF Unrecoverable failure during output * * DevFull Device full, not enough space * * * * NOTES: This routine uses a0, d0, and d1, and restores a0 * *********************************************************************** OutChar: move.l a0,-(sp) Save working pointer reg. cmp #Terminal,d1 Output to terminal? seq TermFlag(a6) bne.s OutChar0 and.w #$007f,d0 Strip the parity bit cmp.b #Asc_LF,d0 Is it a linefeed? bne.s OutChar_0 tst.b CR_Last(a6) Did we just do a CR? beq.s OutChar_0 ...no, so go ahead and print it. clr.b CR_Last(a6) OK for next LF to be printed move.l (sp)+,a0 Restore working reg rts OutChar_0 cmp.b #Asc_CR,d0 Is carriage return? seq CR_Last(a6) Set the flag. OutChar0 move.w d0,-(sp) Save the character being written lea Pathnums(a6),a0 Get path number table base address add.w d1,d1 Offset in table for this logical channel move.w (a0,d1.w),d0 Get OS-9 output path for channel bne.s OutChar2 It is open, so go ahead with write move.b #NotOpWr,d1 OutChar1 move.w (sp)+,d0 get the character written move.l (sp)+,a0 get the old contents of the pointer rts OutChar2 lea 1(sp),a0 Point to character (in memory on stack) moveq #1,d1 ...and get ready tst TermFlag(a6) Output to terminal? beq.s OutChar21 ...no, use I$Write tst.b CR_Last(a6) a Carriage return? beq.s OutChar21 ...no, use I$Write os9 I$WritLn Use WritLn to make sure... bra.s OutChar22 ...that CR is handled properly. OutChar21 os9 I$Write Just write the character in plain mode OutChar22 bcs.s OutChar3 Something went wrong move.b #AllOk,d1 bra.s OutChar1 Exit through clean-up routine OutChar3 cmp.b #E$Full,d1 Device full? bne.s OutChar4 move.b #DevFull,d1 bra.s OutChar1 OutChar4 cmp.b #E$NotRdy,d1 Device not ready? bne.s OutChar5 move.b #DevNotRd,d1 bra.s OutChar1 OutChar5 cmp.b #E$FNA,d1 Permission violation? bne.s OutChar6 move.b #ResChan,d1 bra.s OutChar1 OutChar6 move.b #UnrOutF,d1 bra.s OutChar1 ********************************* ChanCtrl **************************** * * * Performs control operations on logical channels. * * * * Entry conditions : D0.B Request Code (see below) * * * * RC symbol Meaning * * * * SetBaud Set baud rate on port * * RawMode Enable raw mode * * TextMode Enable text mode * * DoXCntrl Enable XON/XOFF protocol * * NoXCntrl Disable XON/XOFF protocol * * SndBreak Send a break over RS 232 C line * * ClrInpBf Clear input buffer * * ClrOutBf Clear output buffer * * * * D1.B channel number * * D2.L additional data (only requested * * baud rate now) * * * * Exit conditions : D0.B Completion Code (see below) * * * * CC symbol Meaning * * * * AllOk No errors * * BadChan Inexistent channel * * ResChan Access reserved, permission denied * * DevNotRd Device not ready (e.g. unmounted) * * BadCtReq I/O control request code invalid * * * *********************************************************************** ChanCtrl: add.w d0,d0 Get offset into jump table move.w ChanRCLk(pc,d0.w),d0 Get offset to start of routine jmp ChanRCLk(pc,d0.w) Jump into it. ChanRCLk dc.w CCSetBaud-ChanRCLk dc.w CCRawMode-ChanRCLk dc.w CCTxtMode-ChanRCLk dc.w CCDoXON-ChanRCLk dc.w CCNoXON-ChanRCLk dc.w CCSndBrk-ChanRCLk dc.w CCClrBuf-ChanRCLk * Set Baud rate * * This routine simply changes the PD_BAU parameter in the path descriptor of * the designated logical channel. Standard OS-9 baud rates are supported, * as per the table listed below and in the SCF section of the OS-9/68000 * Technical Manual. * * Note: although many OS9 serial port drivers support software selectable * baud rates, many will only set the baud rate when they are first INIZed. * The standard 6850 ACIA driver falls in this class. It is a relatively * simple procedure to add on-the-fly baud rate selection to the Read and * Write routines of most drivers, if source code is available, and if the * hardware supports baud rate selection. CCSetBaud move.l a0,-(sp) lea BaudRates(pc),a0 Point to baud rate table. SetBaud2 move.l (a0)+,d0 Get a baud rate/code number pair bmi CCError Past end of table cmp.w d0,d2 Baud rates match? bne.s SetBaud2 No, check another swap d0 Get the baud rate code number move d0,d2 Save it around the I$GetStt call add d1,d1 Offset to path number table lea Pathnums(a6),a0 move (a0,d1),d0 Get the path number lea OptBuff(a6),a0 Point to the options buffer moveq #SS_Opt,d1 os9 I$GetStt bcs CCError move.b d2,PD_BAU-PD_OPT(a0) Set the baud rate moveq #SS_Opt,d1 os9 I$SetStt bcs CCError move.l (sp)+,a0 Restore working register. moveq #AllOk,d0 rts BaudRates dc.w 0,50 These are the OS-9 baud rate numbers/buad rates dc.w 1,75 Found in the Technical Manual section on SCF dc.w 2,110 dc.w 3,134 NOTE: Not all device drivers support baud rate dc.w 4,150 selection after the device has been INIZed!! dc.w 5,300 dc.w 6,600 dc.w 7,1200 dc.w 8,1800 dc.w 9,2000 dc.w 10,2400 dc.w 11,3600 dc.w 12,4800 dc.w 13,7200 dc.w 14,9600 dc.w 15,19200 dc.w -1,-1 Mark end of table. * Send break out RS232 line * * This routine relies on an undocumented feature of the I$GetStt call * It may not (and probably won't) work on very many serial drivers. CCSndBrk move.l a0,-(sp) add d1,d1 Offset into path table lea Pathnums(a6),a0 move (a0,d1),d0 Path number to use moveq #SS_Break,d1 Request a break os9 I$SetStt bcs CCError move.l (sp)+,a0 moveq #AllOk,d0 rts CCError move.l (sp)+,a0 moveq #BadCtReq,d0 rts * Raw Mode--sets options suitable for raw (binary) data transfer mode CCRawMode move.l a0,-(sp) add.w d1,d1 Get offset into path number lookup table lea Pathnums(a6),a0 Get base of input path lookup table move.w (a0,d1.w),d0 Get the OS9 path number lea OptBuff(a6),a0 ...point to a buffer move.w #SS_Opt,d1 ...and read in the option block os9 I$GetStt bcs CCError clr.b PD_EKO-PD_OPT(a0) No echo clr.b PD_PAU-PD_OPT(a0) No page pause clr.b PD_EOF-PD_OPT(a0) No end of file character clr.b PD_PSC-PD_OPT(a0) No pause character clr.b PD_INT-PD_OPT(a0) No interrupt character clr.b PD_QUT-PD_OPT(a0) No abort character moveq #SS_Opt,d1 Now, set 'em back os9 I$SetStt bcs CCError move.l (sp)+,a0 moveq #AllOk,d0 No error rts * Text Mode--sets options suitable for text transfer mode CCTxtMode move.l a0,-(sp) add.w d1,d1 Get offset into path number lookup table lea Pathnums(a6),a0 move.w (a0,d1.w),d0 Get the OS9 path number moveq #255,d1 os9 I$GetStt lea OptBuff(a6),a0 Restore the text mode options move.w #SS_Opt,d1 ...and read in the option block os9 I$GetStt bcs CCError clr.b PD_EKO-PD_OPT(a0) No echo clr.b PD_PAU-PD_OPT(a0) No page pause clr.b PD_EOF-PD_OPT(a0) No end of file character clr.b PD_PSC-PD_OPT(a0) No pause character clr.b PD_INT-PD_OPT(a0) No interrupt character clr.b PD_QUT-PD_OPT(a0) No abort character move.w #SS_Opt,d1 os9 I$SetStt Set to raw mode bcs CCError move.l (sp)+,a0 moveq #AllOk,d0 No error rts * DoXON--turns on XON/XOFF processing CCDoXON move.l a0,-(sp) add.w d1,d1 lea Pathnums(a6),a0 move.w (a0,d1.w),d0 Get the OS9 path number lea OptBuff(a6),a0 move.w #SS_Opt,d1 ...and read in the option block os9 I$GetStt bcs CCError move.b #Asc_DC1,PD_XON-PD_OPT(a0) move.b #Asc_DC3,PD_XOFF-PD_OPT(a0) move.w #SS_Opt,d1 os9 I$SetStt Set to XON/XOFF mode bcs CCError move.l (sp)+,a0 moveq #AllOk,d0 No error rts * NoXON--This turns XON/XOFF processing off for the selected path. CCNoXON move.l a0,-(sp) add.w d1,d1 lea Pathnums(a6),a0 move.w (a0,d1.w),d0 Get the OS9 path number lea OptBuff(a6),a0 move.w #SS_Opt,d1 ...and read in the option block os9 I$GetStt bcs CCError clr.b PD_XON-PD_OPT(a0) clr.b PD_XOFF-PD_OPT(a0) move.w #SS_Opt,d1 os9 I$SetStt Set to XON/XOFF mode bcs CCError move.l (sp)+,a0 moveq #AllOk,d0 No error rts * Clear out the input buffer. * * This routine uses the OS-9 I$GetStt call with the SS_Ready function request * to determine how much data is available. Most OS-9 drivers implement the * SS_Ready function code, but some of them incorrectly return 0 or 1 instead * the true number of characters in the buffer. Due to this the routine will * check multiple times. CCClrBuf move.l a0,-(sp) add.w d1,d1 Offset into path number lookup table lea Pathnums(a6),a0 move (a0,d1.w),d0 Get the actual OS-9 path number CCClrB2 moveq #SS_Ready,d1 os9 I$GetStt Check for data available bcs.s CCClrB3 D1 SHOULD return number of chars in buff lea ShellCmd(a6),a0 An unused buffer for reading os9 I$Read Try to read the characters in the buffer bcc.s CCClrB2 Check one more time for data. CCClrB3 cmp.w #E$NotRdy,d1 Is the error data not ready? beq.s CCClrB4 ...yes, we've flushed the buffer cmp.w #E$Read,d1 Was it a buffer over-run? beq.s CCClrB2 Go back and empty some more. CCClrB4 move.l (sp)+,a0 moveq #AllOk,d0 rts ********************************* SysInit ***************************** * * * Initialize any system dependent thing. * * * * Entry conditions : none * * * * Exit conditions : none * * * * OS-9/68000 Notes: * * This routine grabs the command line parameter list and makes * * sure that it is null-terminated (OS-9 usually puts a carriage * * return or two). Also, in order to avoid possible problems with * * locking up the user's terminal, the I$GetStt function SS_DevNm * * is used to open an independent path to the user's terminal. * * I$Dup is not used, because any changes made to the option * * section would have to be remembered and un-done before Kermit * * could safely exit. This was a major problem in debugging since * * crashing Kermit locked up the terminal until this solution was * * used. * *********************************************************************** SysInit: move.l a5,CmdLinPt(a6) Save address of command line parms move.l a5,a0 SysInit2 move.b (a0)+,d0 beq.s SysInit3 cmp.b #Asc_CR,d0 bne.s SysInit2 clr.b -(a0) Make sure it is NULL terminated!! * Connect the Terminal channel to the same device as stdin SysInit3 clr d0 Stdin moveq #SS_DevNm,d1 Ask for name of device lea ShellCmd(a6),a0 An empty buffer to retrieve name move.b #'/',(a0)+ os9 I$GetStt Find out the name. bcs.s SysInit4 moveq #RdWrOp,d0 Want a read/write access moveq #Terminal,d1 ...to the terminal lea ShellCmd(a6),a0 bsr FilOpen open it up. tst.b d0 beq.s SysInit4 * Set proper terminal operating modes moveq #Terminal,d1 Channel number of terminal bsr CCTxtMode Set text mode I/O parameters. rts * OS-9 reported an error while we were trying to initialize the terminal SysInit4 lea SysInErr(pc),a0 moveq #1,d0 Stdout moveq #127,d1 Long length os9 I$WritLn os9 F$Exit SysInErr dc.b "Can't initialize terminal path properly, exiting." dc.b Asc_CR,Asc_Nul align ********************************* SysExod ***************************** * * * Return control to system. * * * * Entry conditions : D0.B completion code, exit status * * * * Exit conditions : none * * * *********************************************************************** SysExod: clr.b d1 No error os9 F$Exit Closes all files for us, exits to system ******************************** GetCmdLP ***************************** * * * Try to return a pointer to the command line, null terminated. * * * * Entry conditions : none * * * * Exit conditions : A0.L pointer to the command line, if any * * D0.B completion code * * * *********************************************************************** GetCmdLP: move.l CmdLinPt(a6),a0 tst.b (a0) Command line null? sne d0 Set completion code accordingly RTS pag nam Kermit68K ttl OS-9/68000 Dependent module (part 2) * Kermit68K: source file K68SY2 * * Author: Roberto Bagnara (Bagnara@Iboinfn.Bitnet), * Bologna University, Physics Department, May 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. * * OS9/68000 Modifications performed by Steve Williams * University of Texas at Austin, June, 1987 * * Revision History: * Edition Date Author Description * 0 87/03/25 spw Initial implementation for OS-9/68K * 1 87/04/16 spw Rough code for ExpandFN (no wildcarding) * 2 87/04/22 spw Changes to SysExod * 3 87/04/24 spw Added the System services * 4 87/05/05 spw Revised FilOpen, FilClose for new path number * handling. Split ExpandFN, GetNxtF, CRemTLoc, * NewName, and Sleep to k68os9p3.a * 5 87/06/05 spw Added SysCommd handling to System function ********************************** System ***************************** * * * Performs system commands. Called with a request code and 0, 1 or 2 * * null terminated argument strings, depending on request code. * * * * Entry conditions : D0.B Request Code (see below) * * * * RC symbol Meaning * * * * SysCommd Forward command to operating system * * Directry Display a directory listing * * SpacInfo Display informations about disk usage * * DeletFil Delete file(s) * * CopyFile Copy file(s) * * ChangDir Change the default directory * * PrntFile Print file(s) * * RenamFil Rename file(s) * * TypeFile Type file(s) * * * * A0.L pointer to argument 1 (see below) * * A1.L pointer to argument 2 (see below) * * * * RC symbol Arguments number and meaning * * * * Directry 0 or 1 directory path * * SpacInfo 0 or 1 device or account name * * DeletFil 1 file name * * CopyFile 2 source and target file names * * ChangDir 0 or 1 path to new directory * * PrntFile 1 file name * * RenamFil 2 old and new file names * * TypeFile 1 file name * * * * Exit conditions : D0.B completion code * * * * NOTES: This routine saves all of the registers that it uses and * * restores all of them on return, except of course, d0 * *********************************************************************** System: movem.l d1-d4/a0-a3,-(sp) Save the working registers. add.w d0,d0 Compute offset in... move.w SysCmdTbl(pc,d0.w),d1 ...command routine offset table jmp SysCmdTbl(pc,d1.w) Jump to the routine. SysCmdTbl dc.w SysHandle-SysCmdTbl for SysCommd dc.w SysFork-SysCmdTbl for Directry dc.w SysFork-SysCmdTbl for SpacInfo dc.w FilDel_0-SysCmdTbl DeletFil dc.w SysFork-SysCmdTbl CopyFile dc.w SysCWD-SysCmdTbl ChangDir dc.w SysFork-SysCmdTbl PrntFile dc.w SysFork-SysCmdTbl Rename dc.w SysFork-SysCmdTbl TypeFile SysHandle lea ShellCmd(a6),a1 SysHnd_1 move.b (a0)+,(a1)+ Move the command line to the shell buffer bne.s SysHnd_1 bra.s SysFork3 rts SysCWD tst.b (a0) Null string? beq.s SysCWD2 move.w #Updat_,d0 Change data directory os9 I$ChgDir SysCWD2 scc d0 Set condition code movem.l (sp)+,d1-d4/a0-a3 rts * Come here for those commands that we can just fork to a shell SysFork move.w ShellOff(pc,d0.w),d1 Got offset to string in string table move.w ShellOps(pc,d0.w),d2 Get number of operands. lea ShellOff(pc,d1.w),a2 Got address of string. lea ShellCmd(a6),a3 Need to set up the shell command bra.s SysFork2 * Table of number of command arguments for each command. For those commands * with optional arguments, these are the maximum number of arguments. * * The -1 entries in this table are for the commands that are taken care * of directly in Kermit. ShellOps dc.w -1 SysCmd dc.w 1 Directry dc.w 1 SpacInfo dc.w -1 DeletFil dc.w 2 CopyFile dc.w -1 ChangDir dc.w 1 PrntFile dc.w 2 RenamFil dc.w 1 TypeFile * Table of offsets to the actual command strings ShellOff dc.w -1 SysCmd dc.w Directry-ShellOff dc.w SpacInfo-ShellOff dc.w -1 dc.w CopyFile-ShellOff dc.w -1 dc.w PrntFile-ShellOff dc.w RenamFil-ShellOff dc.w TypeFile-ShellOff * Build the shell paramter list in ShellCmd(a6) SysFork2 move.b (a2)+,(a3)+ Move byte of the command name bne.s SysFork2 move.b #' ',-1(a3) Put in a space separator move.l a0,a2 Move on-deck to batter's box move.l a1,a0 In the hole -> on-deck dbf d2,SysFork2 Go until the parameters are out. move.b #Asc_CR,-1(a3) Terminate the command with a CR clr.b (a3) ...and then a nul * Fork a shell to process the newly constructed command line at this point, * the registers a0-a3 and d2-d4 have been stacked with a movem instruction. SysFork3 move.w #(Prgrm<<8)+Objct,d0 moveq #0,d1 No extra memory move.l a3,d2 End of parameter list lea ShellCmd(a6),a1 Beginning of parameter list sub.l a1,d2 Length of parameter list lea ShellNam(pc),a0 Address of shell's name move.w #3,d3 Inherit all my stdio paths. clr.w d4 Don't care about the priority os9 F$Fork bcs.s SysErr Error, must put terminal back... * ...to proper mode. * Wait for the child process to die. os9 F$Wait SysErr scc d0 If no OS-9 error, return good completion. movem.l (sp)+,d1-d4/a0-a3 RTS Directry dc.b "dir",Asc_Nul SpacInfo dc.b "free",Asc_Nul CopyFile dc.b "copy",Asc_Nul PrntFile dc.b "list >/p",Asc_Nul RenamFil dc.b "rename",Asc_Nul TypeFile dc.b "list",Asc_Nul ShellNam: dc.b "Shell",Asc_Nul align ********************************* FilOpen ***************************** * * * Open a disk file or an I/O channel. * * * * Entry conditions : D0.B Request Code (see below) * * * * RC symbol Meaning * * * * RdWrOp Open for read/write * * ReadOp Open for read * * WriteOp Open for write * * AppendOp Open for append * * * * D1.B logical channel number. * * A0.L points to file name null terminated * * * * Exit conditions : D0.B completion code * * A0.L still points to the file name * * * *********************************************************************** FilOpen: movem.l d1-d3/a0-a1,-(sp) Save the working registers move.w d0,d2 Save a copy of the file access mode add.w d1,d1 Convert channel number to offset... * ...in OS-9 lookup table move.w d1,d3 Save a copy of the logical... * ...(Kermit68K) channel number add.w d0,d0 Compute offset into lookup table... * ...for mode lea OS9OpCd(pc),a1 move.w (a1,d0.w),d0 Get the OS-9 open code corresponding FilOp_1 cmp.w #WriteOp,d2 Are we going to write to file? beq.s FilOp_6 Yes, handle differently. os9 I$Open No, try to open it bcc.s FilOp_2 No error on the open cmp.w #E$PNNF,d1 Path name not found? bne.s FilOp_5 Other error, get out of here. cmp.w #ReadOp,d2 Trying to read this file? beq.s FilOp_5 Can't read from inexistent files move.w d2,d0 Get the access mode value again add.w d0,d0 lea OS9OpCd(pc),a1 move.w (a1,d0.w),d0 Get the access mode needed move.w #Updat_,d1 Set read/write permanent permission bits move.l (sp),a0 Restore the file name address os9 I$Create Create the file bcs.s FilOp_5 Can't even come close to open, get out * Connect the logical channel to the returned OS-9 path number FilOp_2 lea Pathnums(a6),a0 Set the path number move.w d0,(a0,d3.w) cmp.b #AppendOp,d2 Doing an append? bne.s FilOp_4 No, leave the file where it is... * ...(d0 is non-zero) * For an append, find out how big the file is (with I$GetStt) * and then seek to end move.w #SS_Ready,d1 Going to find out how big the file is. os9 I$GetStt bcs.s FilOp_5 move.l d2,d1 Copy the current size os9 I$Seek So we can seek to current end + 1 bcs.s FilOp_5 FilOp_4 st d0 return good completion movem.l (sp)+,d1-d3/a0-a1 rts FilOp_5 sf d0 return bad completion code. movem.l (sp)+,d1-d3/a0-a1 restore the working registers rts * Code to handle opening for write access FilOp_6 bsr FilDelet Try to delete the file move.w #Write_,d0 Write mode access move.w #Updat_,d1 Read and write attributes (permanent) os9 I$Create bcs.s FilOp_5 Error, quit now. bra FilOp_2 Go into code to set path number properly * Lookup/translation table to convert the open request modes of Kermit68K to * the standard modes of OS-9 OS9OpCd dc.w Updat_ OS-9 Updat_ mode <--> RdWrOp of Kermit dc.w Read_ <--> ReadOp of Kermit dc.w Write_ <--> WriteOp of Kermit dc.w Write_ <--> AppendOp of Kermit (with seek) ******************************** FilClose ***************************** * * * Close a disk file or an I/O channel. * * * * Entry conditions : D1.B logical channel number. * * * * Exit conditions : D0.B completion code * * * *********************************************************************** FilClose: movem.l d1/a0,-(sp) add.w d1,d1 Double channel number for offset lea Pathnums(a6),a0 Base of path number lookup table move.w (a0,d1.w),d0 Get the path number for the channel clr.w (a0,d1.w) Mark path as unused tst.w d0 Was the path ever used? beq.s FilCls_1 ...no, don't close it. os9 I$Close Close the path FilCls_1 movem.l (sp)+,d1/a0 st d0 return success RTS ********************************* FilDelet **************************** * * * Delete a file. * * * * Entry conditions : A0.L points to file name null terminated * * * * Exit conditions : D0.B completion code * * * *********************************************************************** FilDel_0 movem.l (sp)+,d1-d4/a0-a3 Restore regs pushed by System FilDelet: move.l a0,-(sp) I$Delete clobbers a0 move.w #Read_,d0 Get the file in current DATA directory os9 I$Delete scc d0 Return success move.l (sp)+,a0 Restore file name pointer rts align pag nam Kermit68K ttl OS-9/68000 Dependent module (part 3) * Kermit68K: source file K68SY3 * * Author: Roberto Bagnara (Bagnara@Iboinfn.Bitnet), * Bologna University, Physics Department, February 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. * * OS9/68000 Modifications performed by Steve Williams * University of Texas at Austin, June, 1987 * * Revision History: * Edition Date Author Description * 0 87/05/05 spw Separated from k68os9p2.a * 1 87/05/25 spw Added code to handle wildcards * 2 87/06/05 spw Added CLocTRem for converted file names ********************************* ExpandFN **************************** * * * Expand a wildcard file name into an array of file names, returns * * the number of files that match the passed string, with data * * structures set up so that the first file name (if any) will be * * returned by the next GetNxtF call. * * * * Entry conditions : A0.L points to file name null terminated * * * * Exit conditions : D0.L number of matches found, negative * * if too many matches for user buffer * * A0.L still points to the file name * * * *********************************************************************** ExpandFN: movem.l d1-d4/a0-a3,-(sp) Save working registers moveq #0,d0 Clear character pointer. lea FNBuffer(a6),a1 Point to first file name in buffer move.l a1,NextFile(a6) Save address of first file name ExpFN_1 move.b (a0,d0.l),d1 move.b d1,(a1,d0.l) Copy the file name. beq.s ExpFN_2 End of string and no wild card cmp.b #'?',d1 beq.s ExpandWC Handle the wildcard case. cmp.b #'*',d1 beq.s ExpandWC Do wildcard expansion. addq #1,d0 bra.s ExpFN_1 ExpFN_2 moveq #1,d0 One match move.l d0,NumFiles(a6) Set up for GetNxtF movem.l (sp)+,d1-d4/a0-a3 rts * The file name contains wildcards a0 still points to beginning of * wild card file name. * * This version will handle wildcards if they are in the current directory. ExpandWC move.b #'/',d0 Going to look for a directory specifier. move.l a0,a1 Copy beginning of string pointer. sf d1 Haven't found a directory terminator moveq #64,d2 Set a limiting count ExpWC_1 cmp.b (a1),d0 Is this a directory separator? seq d3 Set a flag or.b d3,d1 Keep a permanent indicator tst.b (a1)+ End of string? dbeq d2,ExpWC_1 Go back until we find end of string. tst.b d1 Was there a directory separator? beq.s ExpWC_2 ...no, do the expansion. move.l a0,-(sp) Save the file name pointer lea BadWCMsg(pc),a0 moveq #1,d0 Stdout moveq #127,d1 Long length os9 I$WritLn move.l (sp)+,a0 Restore the file name pointer moveq #0,d0 Signal no matches move.l d0,NumFiles(a6) movem.l (sp)+,d1-d4/a0-a3 rts BadWCMsg dc.b "Wildcarded filenames must be in current directory." dc.b Asc_CR,Asc_Nul align * The files should all be in the current directory, so a shell can be forked * to execute an 'echo' command which will return a list of matches. ExpWC_2 lea EchoOpts(pc),a1 Pointer to the option list needed lea ShellCmd(a6),a2 Point to parameter list ExpWC_3 move.b (a1)+,(a2)+ Set up the command options bne.s ExpWC_3 subq #1,a2 Backup move.l a0,a1 Copy file name pointer ExpWC_4 move.b (a1)+,(a2)+ Set up the wild card name bne.s ExpWC_4 * Set up a pipe to read back the output of the echo command moveq #1,d0 StdOut os9 I$Dup Duplicate current standard output path move d0,-(sp) Save the duplicated path number moveq #1,d0 os9 I$Close close stdout lea PipeName(pc),a0 move.w #Updat_,d0 I need to read, he needs to write os9 I$Open Open up the pipe (it will become path 1) * Now that the pipe is open, fork a shell to process the command move.w #(Prgrm<<8)+Objct,d0 moveq #0,d1 No extra memory move.l a2,d2 End of parameter list lea ShellCmd(a6),a1 Beginning of parameter list sub.l a1,d2 Length of parameter list lea ShellNam(pc),a0 Address of shell command name move.w #3,d3 Inherit all my stdio paths. clr.w d4 Don't care about the priority os9 F$Fork * Now, read the lines of output that match the wild card. lea FNBuffer(a6),a0 Pointer to where to put file name moveq #0,d3 Counter for file names. ExpWC_5 moveq #1,d0 The path number of the pipe moveq #80,d1 read a line's worth os9 I$ReadLn read a line bcs.s ExpWC_8 End of file? * Got a name read in, now, update the pointer and count and go back for more move.b #Asc_CR,d0 ExpWC_6 cmp.b (a0)+,d0 Is it a Carriage return? bne.s ExpWC_6 ...no, go back. clr.b -1(a0) Change the CR to a string terminator addq #1,d3 Bump the file name count cmp.l #50,d3 A limit on the number of files blo.s ExpWC_5 * too many file names matched, so read pipe until empty then quit. ExpWC_7 lea FNBuffer(a6),a0 moveq #1,d0 moveq #80,d1 os9 I$ReadLn bcc.s ExpWC_7 moveq #-1,d3 Signal too many matches ExpWC_8 os9 F$Wait Wait for the child to exit. moveq #1,d0 Must close the pipe os9 I$Close move.w (sp),d0 Get the saved path number for our stdout os9 I$Dup move.w (sp)+,d0 Close the duplicated stdout os9 I$Close move.l d3,NumFiles(a6) move.l d3,d0 Return number of files matching. movem.l (sp)+,d1-d4/a0-a3 rts PipeName dc.b "/pipe",0 EchoOpts dc.b "echo -n ",0 align ********************************* GetNxtF ***************************** * * * Get the next file name from the list created by ExpandFN, returns * * a true completion code if there's another file, copying its name * * into the target string, or false if no more file names in list. * * * * Entry conditions : A0.L points to the target string * * * * Exit conditions : D0.B completion code * * A0.L points to the target string * * * *********************************************************************** GetNxtF: move.l NumFiles(a6),d0 any left to get? beq.s GetNF_2 No, so get on out of here. subq #1,d0 move.l d0,NumFiles(a6) Re-set number of files left movem.l a0-a1,-(sp) movea.l NextFile(a6),a1 Get address of this file name string GetNF_1 move.b (a1)+,(a0)+ Move a byte bne.s GetNF_1 Until null encountered move.l a1,NextFile(a6) Save updated pointer movem.l (sp)+,a0-a1 st d0 true result rts GetNF_2 sf d0 false result rts ********************************* CRemTLoc **************************** * * * Convert filenames from remote system in a form suitable for the * * local system. * * * * Entry conditions : A0.L points to the string to be * * converted * * * * Exit conditions : A0.L points to the same string suitably * * converted * * * * OS-9/68000 Notes: * * This routine will replace any illegal punctuation characters * * including the directory separator '/' and device raw-mode specifer * * '@' with the underline character, which is legal for OS-9 path * * names. * *********************************************************************** CRemTLoc: move.l d1,-(sp) clr.w d0 Zero out counter moveq #FilNamML-1,d1 File name string maximum length in OS-9 CRTL_1 tst.b (a0,d0.w) Find length of string. beq.s CRTL_2 Found the null addq #1,d0 Keep counting dbf d1,CRTL_1 ...until length exceeded clr.b 0(a0,d0.w) Terminate the string properly. CRTL_2 subq #1,d0 Backup to last byte of string CRTL_3 move.b 0(a0,d0.w),d1 cmp.b #'/',d1 beq.s CRTL_4 A slash foul (means a directory). cmp.b #'.',d1 beq.s CRTL_5 A period is ok cmp.b #'_',d1 beq.s CRTL_5 An underscore is ok cmp.b #'0',d1 blo.s CRTL_4 Other punctuation $20-$2f is foul cmp.b #'9',d1 bls.s CRTL_5 Digits are OK cmp.b #'A',d1 blo.s CRTL_4 ':;<=>?@' are bad cmp.b #'Z',d1 bls.s CRTL_5 Capital letters ok cmp.b #'a',d1 blo.s CRTL_4 '[\]^' are bad cmp.b #'z',d1 bls.s CRTL_5 Lower case letters OK CRTL_4 move.b #'_',0(a0,d0.w) Replace the illegal character CRTL_5 dbf d0,CRTL_3 Loop backwards through the string move.b (a0),d0 Check first character of string... * ...for alphabetic cmp.b #'A',d0 blo.s CRTL_6 Less than 'A' -> not alpha cmp.b #'Z',d0 bls.s CRTL_7 In 'A'..'Z' -> alpha cmp.b #'a',d0 blo.s CRTL_6 Less than 'a' -> not alpha cmp.b #'z',d0 bls.s CRTL_7 In 'a'..'z' -> alpha CRTL_6 sf d0 Invalid file name move.l (sp)+,d1 restore working reg. rts CRTL_7 st d0 Valid file name move.l (sp)+,d1 restore working reg. rts ********************************* CLocTRem **************************** * * * Convert filenames in local system syntax in a form suitable for * * the remote Kermit system. The job that this routine must do is * * explained here in detail. * * * * Adapted from the "Kermit Protocol Manual", Sixth Edition, p. 16 * * * * 1. Delete all pathnames and attributes from the file * * specification. The file name should not contain directory * * or device names if it does, it may cause the recipient to * * try to store the file in an inaccessible or nonexistent area, * * or it may result in a very strange filename. * * * * 2. After stripping any pathname, convert the remainder of the * * file specification to the form "name.type", with no * * restriction on length (except that it fit in the data field * * of the F packet), and: * * * * a. Include no more than one dot. * * b. Not begin or end with a dot. * * c. The name and type fields contain digits and uppercase * * letters only. * * * * Entry conditions : A0.L points to the string to be * * converted * * * * Exit conditions : A0.L points to the same string suitably * * converted * * * *********************************************************************** CLocTRem: movem.l d1-d3/a1,-(sp) clr.w d0 Zero out counter moveq #FilNamML-1,d1 File name string Maximum length in OS-9 CTRL_1 tst.b (a0,d0.w) Find length of string. beq.s CTRL_2 Found the null addq #1,d0 Keep counting dbf d1,CTRL_1 ...until length exceeded clr.b 0(a0,d0.w) Terminate the string properly. CTRL_2 move.l a0,a1 point to start of string move.w d0,d3 Save string length subq #1,d0 one less for dbf loop. * Is there a leading pathname? move.b #'/',d1 Looking for a directory mark. CTRL_21 cmp.b (a1,d0.w),d1 dbeq d0,CTRL_21 Exit loop when one found. bne CTRL_29 None found * Move the simple file name forward in the name buffer. lea 1(a1,d0.w),a1 Point to first character of file name move.w d3,d1 Get original length of string. sub.w d0,d1 Get length of simple file name. subq #1,d1 ...minus one for dbf loop CTRL_22 move.b (a1,d1.w),(a0,d1.w) Move the simple file name forward dbf d1,CTRL_22 * Restore the counter and pointer for the next loop CTRL_29 move.l a0,a1 Copy start of string address move.w d3,d0 Get count of string length subq #1,d0 ...minus one for the dbf loop. * Replace any punctuation with periods. CTRL_3 move.b (a1)+,d1 cmp.b #'0',d1 blo.s CTRL_4 Punctuation $20-$2f is foul cmp.b #'9',d1 bls.s CTRL_5 Digits are OK cmp.b #'A',d1 blo.s CTRL_4 ':;<=>?@' are bad cmp.b #'Z',d1 bls.s CTRL_5 Capital letters ok cmp.b #'a',d1 blo.s CTRL_4 '[\]^' are bad cmp.b #'z',d1 bls.s CTRL_5 Lower case letters OK CTRL_4 move.b #'.',-1(a1) Replace the illegal character CTRL_5 dbf d0,CTRL_3 Loop backwards through the string * Make the string all capitals move.l a0,a1 Point to start of string move.w d3,d0 Count of characters. subq.w #1,d0 Account for dbf loop. CTRL_6 move.b (a1)+,d1 Get a byte of string. cmp.b #'a',d1 blo.s CTRL_7 Less than 'a' -> not lower case alpha cmp.b #'z',d1 bhi.s CTRL_7 Not in 'a'..'z' -> not lower case alpha sub.b #'a'-'A',d1 move.b d1,-1(a1) Replace character CTRL_7 dbf d0,CTRL_6 Go back for more. * Can't begin or end with a '.' move.b #'.',d1 cmp.b (a0),d1 Is first character a period? bne.s CTRL_8 move.b #'X',(a0) Replace with an 'X' CTRL_8 cmp.b -1(a0,d3),d1 Last character a period? bne.s CTRL_9 move.b #'X',-1(a0,d3) * Replace all but first period with 'X' CTRL_9 move.l a0,a1 Point to start of string. sf d2 Haven't found a period yet. move d3,d0 Counter subq #1,d0 account for dbf loop. CTRL_10 cmp.b (a1)+,d1 Get a byte of the string bne.s CTRL_12 Not a period, leave it alone tst.b d2 Seen a period? beq.s CTRL_11 ...not yet, leave this one alone move.b #'X',-1(a1) mask out the period CTRL_11 st d2 We've seen a period now. CTRL_12 dbf d0,CTRL_10 st d0 Valid file name movem.l (sp)+,d1-d3/a1 rts ********************************** NewName **************************** * * * Make a new name for the given file to avoid file name collisions. * * * * Entry conditions : A0.L points to the file name string * * * * Exit conditions : A0.L points to the same string suitably * * modified * * * * OS-9 Note: This routine just places an underscore character at * * beginning of the file name to rename it. * *********************************************************************** NewName: move.l a1,-(sp) move.l a0,a1 Copy string pointer moveq #FilNamML-2,d0 Start from the end of longest file name NewNm_1 move.b 0(a0,d0.w),1(a0,d0.w) Move the current name one byte forward dbf d0,NewNm_1 Keep counting back through string move.b #'_',(a0) Put an underscore at start of string clr.b FilNamML(a0) Make sure string is null terminated. st d0 Set a good completion code move.l (sp)+,a1 rts ********************************** Sleep ****************************** * * * Puts the process to sleep. * * * * Entry conditions : D0.B time interval to wait (seconds) * * * * Exit conditions : none * * * *********************************************************************** Sleep: move.l d1,-(sp) ext.w d0 Need to pass a long tick count ext.l d0 ...extending some more. asl.l #8,d0 Compute 256ths of second to sleep moveq #31,d1 Need to set the high bit... bset d1,d0 ...of the tick count, in order... os9 F$Sleep ...to achieve system independence. move.l (sp)+,d1 rts align ends end <<< k6outf.asm >>> nam Kermit68K ttl Utility subroutines module * Kermit68K: source file K68UTF * * 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 K68UtilitySubs,0,0,Edition,0,0 ********************************* CopyStr *****************************ok * * * Null terminated strings copy subroutine. * * * * Entry conditions : D0.W target string maximum length * * A0.L pointer to target string * * A1.L pointer to source string * * * * Exit conditions : A0.L pointer to target string * * A1.L pointer to source string * * * *********************************************************************** CopyStr: TST.W D0 Null strings ? BEQ.S CopyStr4 Yes, do nothing MOVEM.L A0-A1,-(A7) Save pointers CopyStr1 SUBQ.W #1,D0 Decrement counter BNE.S CopyStr2 Continue copy, if there is room MOVE.B D0,(A0) End of target string, write terminator BRA.S CopyStr3 Restore pointers and return CopyStr2 MOVE.B (A1)+,(A0)+ Copy a character BNE.S CopyStr1 Repeat until end of source string CopyStr3 MOVEM.L (A7)+,A0-A1 Restore pointers CopyStr4 RTS ********************************* CompStr *****************************ok * * * Null terminated strings compare subroutine. * * * * Entry conditions : A0.L pointer to string 1 * * A1.L pointer to string 2 * * * * Exit conditions : D0.B completion code * * A0.L pointer to string 1 * * A1.L pointer to string 2 * * * *********************************************************************** CompStr: MOVEM.L A0-A1,-(A7) Save pointers CompStr1 MOVE.B (A0)+,D0 Get a character from string 1 CMP.B (A1)+,D0 Compare whit string 2 correspondent char BNE.S CompStr2 Compare failed, exit loop TST.B D0 Compare succeed, end of strings ? BNE.S CompStr1 No, stay in loop CompStr2 SEQ D0 Set completion code accordingly MOVEM.L (A7)+,A0-A1 Restore pointers RTS ********************************* DoPrity *****************************ok * * * Add an appropriate parity bit to a character. * * * * Entry conditions : D0.B 7-bit character * * * * Exit conditions : D0.B character with parity bit added * * * *********************************************************************** DoPrity: MOVEM.L D1-D2,-(A7) Save working registers MOVE.B Parity(A6),D1 Some kind of parity enabled ? BEQ.S DoPrity5 No, return ANDI.B #$7F,D0 Clear bit 7 CMPI.B #'M',D1 Mark ? BNE.S DoPrity1 No ORI.B #$80,D0 Yes, set bit 7 BRA.S DoPrity5 Return DoPrity1 CMPI.B #'S',D1 Space ? BEQ.S DoPrity5 Yes, return, bit 7 already cleared CLR.B D2 Clear the ones counter CMPI.B #'O',D1 Odd ? BNE.S DoPrity2 No ADDQ.B #1,D2 Yes, the ones counter starts from 1 DoPrity2 MOVEQ #6,D1 Set up for bit addressing DoPrity3 BTST D1,D0 Bit setted ? BEQ.S DoPrity4 No, try the next ADDQ.B #1,D2 Yes, increment the counter DoPrity4 DBF D1,DoPrity3 Repeat for bits 6-0 LSL.B #7,D2 Position the parity bit OR.B D2,D0 Ok, that's all DoPrity5 MOVEM.L (A7)+,D1-D2 Restore working registers RTS ****************************** HndlPar ********************************ok * * * Handle 8-th bit accordingly to parity selected. * * * * Entry conditions : D0.B character to be processed * * * * Exit conditions : D0.B processed character * * * *********************************************************************** HndlPar: TST.B Parity(A6) Parity selected ? BEQ.S HndlPar1 No, do nothing ANDI.B #$7F,D0 Yes, mask parity bit HndlPar1 RTS ********************************* UDiv ********************************ok * * * 32-bit/16-bit unsigned division. * * * * Entry conditions : D2.L dividend * * D3.W divisor * * * * Exit conditions : D0.L quotient * * D1.L remainder * * * *********************************************************************** UDiv: MOVE.L D2,D0 Get Dividend CLR.W D0 Clear lower part SWAP D0 Upper Dividend DIVU D3,D0 Divide MOVE.W D0,-(A7) Save upper quotient MOVE.W D2,D0 Remainder and lower Dividend DIVU D3,D0 Divide SWAP D0 CLR.L D1 MOVE.W D0,D1 Final remainder MOVE.W (A7)+,D0 Lower and upper quotients SWAP D0 Final quotient RTS Return ******************************* IntToAs *******************************ok * * * Integer to ASCII string conversion routine. * * * * Entry conditions : A0.L pointer to string buffer end * * D0.L number to convert * * D1.B flag for signed or unsigned number * * D2.L field length * * D3.L number base * * * * Exit conditions : A0.L pointer to string buffer start * * * *********************************************************************** IntToAs: MOVEM.W D4-D6,-(A7) Save working registers MOVE.B D1,D4 Load our flag for negative numbers BEQ.S IntToAs1 Unsigned number processing wanted TST.L D0 Signed, negative number ? SLT D4 Set our flag accordingly BGE.S IntToAs1 If positive number then continue NEG.L D0 Else negate it IntToAs1 MOVE.B D2,D5 Save field length CLR.B -(A0) Mark the end of string CLR.B D6 Clear the character counter IntToAs2 MOVE.L D0,D2 Dividend BSR UDiv Divide number by base (in D3) CMPI.B #9,D1 Convert remainder to ascii BGT.S IntToAs3 ADDI.B #$30,D1 BRA.S IntToAs4 IntToAs3 ADDI.B #$37,D1 IntToAs4 MOVE.B D1,-(A0) Store the obtained character ADDQ.B #1,D6 Increment the character counter TST.L D0 End of conversion ? BNE.S IntToAs2 No, repeat TST.B D4 Yes, was a negative number ? BEQ.S IntToAs5 No, continue MOVE.B #'-',-(A0) Yes, insert the minus sign ADDQ.B #1,D6 Increment the character counter IntToAs5 CMP.B D6,D5 Field full ? BLE.S IntToAs6 Yes MOVE.B #' ',-(A0) No, write a leading blank ADDQ.B #1,D6 Increment the character counter BRA.S IntToAs5 Continue padding until the field is full IntToAs6 MOVEM.W (A7)+,D4-D6 Restore working registers RTS ******************************* UppCase *******************************ok * * * Make a character upper-cased. * * * * Entry conditions : D3.B character to be converted * * * * Exit conditions : D3.B converted character * * * *********************************************************************** UppCase: CMPI.B #'a',D3 Below a ? BCS.S UppCase1 Yes, return CMPI.B #'z',D3 Above z ? BHI.S UppCase1 Yes, return SUBI.B #32,D3 No, make the character upper-cased UppCase1 RTS ******************************* IndxJump ******************************ok * * * Indexed jump, extract an address from a relative addresses table * * and jump to it. * * * * Entry conditions : D0.B index to jump table * * A1.L jump table start address * * * * Exit conditions : none, don't return * * * *********************************************************************** IndxJump: ANDI.W #$FF,D0 Make sure upper byte is cleared LSL.W #1,D0 Scale factor of 2 MOVE.W (A1,D0.W),D0 Load relative pointer JMP (A1,D0.W) Jump to service subroutine MacFind: BSR UppCasS Make the macro name upper-cased LEA MacroTbl(A6),A1 Load start address of macro table CMPA.L MTNxtChF(A6),A1 The macro table is empty ? BEQ.S MacFind2 Yes, return a bad completion code MacFind1 BSR CompStr Compare the two names TST.B D0 The two names are equal ? BNE.S MacFind3 Yes, return the macro address BSR MacSkip No, skip to next macro name TST.B D0 It was the last macro ? BEQ.S MacFind1 No, so check this one MacFind2 MOVEA.L A1,A0 Yes, this points to table end SF D0 Return a bad completion code RTS MacFind3 MOVEA.L A1,A0 This is the desired macro address ST D0 Return a positive completion code RTS MacSkip: TST.B (A1)+ Find the end of the macro name BNE.S MacSkip Loop until end of macro name found MacSkip1 TST.B (A1)+ Find the end of the macro body BNE.S MacSkip1 Loop until end of macro body found CMPA.L MTNxtChF(A6),A1 End of macro table ? SEQ D0 Set the completion code accordingly RTS UppCasS MOVE.L A0,-(A7) UppCasS1 MOVE.B (A0),D3 BEQ.S UppCasS2 BSR UppCase MOVE.B D3,(A0)+ BRA.S UppCasS1 UppCasS2 MOVE.L (A7)+,A0 RTS ends END