home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Columbia Kermit
/
kermit.zip
/
os968ka
/
k6osys.asm
< prev
next >
Wrap
Assembly Source File
|
2020-01-01
|
62KB
|
1,288 lines
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