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