home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Columbia Kermit
/
kermit.zip
/
archives
/
os968ka.tar.gz
/
os968ka.tar
/
k6ker.src
< prev
next >
Wrap
Text File
|
1987-07-01
|
409KB
|
8,100 lines
<<< 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