CFS/RFS Documentation ===================== All 8-bit Acorn computers except the Compact include the dual cassette/ROM filing system. The prototype BBC OS 0.10 only included CFS. CFS/RFS implements a cut-down filing system that does not fully comply with all filing system requirements and does not implement some of the filing system calls. Filing System API ================= OSFILE ~~~~~~ On entry: A = action, only &00=Save and &FF=Load are implemented XY=>control block On exit: A = preserved if call not implemented A = &00 if call actioned XY= corrupted The filename is parsed before checking the action, so FNfile("averylongname",5) will give a 'Bad string' error but FNfile("validname",5) will return A=5. The control block is only updated after Load, it is not updated after Save. BBC: A is normally returned holding &00. Load only returns Size at XY+10 updated, all other fields are unchanged. Save does not update the control block at all. *BUG* The returned Size value is only valid if messages have been turned on with *OPT 1,1 or *OPT 1,2. Electron: A is normally returned holding &00. Load returns all fields updated with Attr at XY+14 holding the RFS address field. Save ??? The Size bug has been fixed. Load newline bug?? Master: A is normally returned holding &00. Load returns all fields updated with Attr at XY+14 returned as &00000000. Save ??? FileSwitch ensures XY are returned preserved. OSARGS ~~~~~~ On entry: A = action Y = channel X =>control block in zero page On exit: A = preserved if call unimplemented Y = preserved X = preserved X =>control block may be updated BBC/Electron: Only responds to Y=0,A=0 returning A=filing system number. All other calls return with registers preserved. In particular, Y=0,A=1 to read the command line pointer is not implemented. As all calls leave the control block untouched, when calling =PTR and =EXT from BASIC this results in returning the channel number, and BASIC uses the Integer Accummulator in zero page to collect the result, and the last value in the Integer Accummulator will be the channel number that has just been evaluated. So, for example, PTR#1 and EXT#1 will always return 1. Master: Y=0,A=0 - returns A=filing system number Y=0,A=1 - return command line address to zeropage+0,X to zeropage+3,X Y=0,A=2 - returns A=1 Y=0,A=3 - returns A=libfs filing system number Y=0,A>3 - returns all unchanged Y>0,A=0 - returns PTR, A=b16-b23 of PTR so usually &00 Y>0,A>0 - returns all unchanged FileSwitch implemements the calls with Y=0. OSFIND ~~~~~~ On entry: A = &00 for close, <>&00 for open Y = channel for close XY=>filename for open On exit: A = preserved for close, channel for open XY= preserved If A is nonzero, only bit 6 is checked for the action. %x0xxxxxx opens for output and %x1xxxxxx opens for input, so A=&01-&3F opens a file for output. &01 is always used for a CFS input file, &02 for a CFS output file and &03 for a RFS input file. Attempting to open an output file to RFS generates a 'Bad command' error. OSBGET, OSBPUT ~~~~~~~~~~~~~~ On entry: A = byte to write for OSBPUT Y = channel On exit: A = preserved Y = preserved X = preserved Cy= EOF met Nothing unusual. OSGBPB ~~~~~~ On entry: A = action XY=>control block On exit: A= XY= Cy=EOF met BBC, Electron: Returns immediately with all registers preserved, including flags. Master: Only supports A=2 (write from current PTR) and A=4 (read from current PTR). All other calls return with A corrupted and Carry set. ....... FSC ~~~ On entry: A = action XY= parameters or XY=>string On exit: A = unchanged if not implemented Actions: &00 *OPT X,Y &06 new filing system taking over &01 EOF#X &07 request handle range &02 */filename &08 OSCLI warning &03 unknown *command &09 *EX &04 *RUN filename &0A *INFO &05 *CAT &0B *RUN from libfs BBC: Only 0-6 implemented &00: *OPT --------- *OPT 0 resets to *OPT 1,1 and *OPT 2,1 for load/save, and *OPT1,0 and *OPT 2,2 for bget/bput *OPT 3,0 and *OPT 3,n>127 - defaults to 25 *OPT 4+ generates a 'Bad command' error instead of 'Bad option' returns A,X,Y corrupted (actual value is newly set options byte) &01: EOF -------- =EOF returns all registers preserved, with X=EOF status as &00 or &40 =EOF#0 gives generates a 'Channel' error &03: unknown command -------------------- Generates an 'Bad command' error &02: */filename &04: *RUN filename ------------------ BBC, Electron: Does not set or return a command line pointer registers return whatever the called code returns code not entered with A=1, is entered with A=exec high word so usually &00 or &FF code is entered with CS if Tube present *BUG* *RUN calls the OSFILE Load code, and so attempts to update an OSFILE control block pointed to by &C8/9. If &C8/9 does not point somewhere suitable then memory will be overwritten. The BBC overwrites four bytes at &C8/9+10 with the length calculated by Load (which may itself be incorrect), the Electron overwrites a full 16 bytes at &C8/9+2. &C8/9 will normally be pointing to the control block used by the last OSFILE call, such as a previous LOAD or *LOAD command, unless a different filing system has been used, or &C8/9 has been otherwise changed. &05: *CAT --------- &06: New filing system ---------------------- Jumps directly to OSBYTE 119 to close Spool/Exec files. Master: The *RUN control block bug has been fixed. Service calls MOS deosn't know what the service calls do, as long as they return data, update f6/7, etc. so can extract from compressed data, or from locations other than the ROM the service handler is in, as long as returned values cpomply with api, etc. can check CFS_Progress to decide what to do. Can use spare space in CFS workspace for, eg decompression space. Filing System Workspace at &00B0-&00CF ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When CFS/RFS is the current filing system it uses the workspace as follows -------------------------------------------------------------------------- &00B0-&B3 load address or start address &00B4-&B7 exec address or end address or current block number &00B6-&B7 or next block number &00B8-&B9 => error to print or execute &00BA current block flag: bit 7=last block bit 6=empty block bit 0=locked file &00BB current options, set from half of &E3 Bit 7-6: %0x no messages Bit 5-4: %00 ignore errors %10 short messages %01 abort on error %11 long messages %1x retry on error &00BC offset into current block or CRC being loaded, also temp ws &00BD b7=last byte from block, also temp ws &00BE-&BF CRC workspace &00C0 Buffer flag &00C1 Checksum result &00C2 Progress flag &00 - idle &03 - sync byte found &01 - waiting for header &04 - fetching byte from data block &02 - &05 - fetching CRC &00C3 Current file handle during *MOTOR call &00C4 temp &00C6 Baud rate to write to serial port, 5=300, 6=1200 &00C7 Interblock flag, 6 for save, *OPT3 value for BPUT &00C8/&C9 => OSFILE control block &00CA OR'd with &C6 to write to serial control register &00CB CRC bit counter &00CC-&CD file size &00CE-&CF unused (high word of file size) Private CFS/RFS Zero Page Workspace ----------------------------------- &00E2 Cassette/RFS filing system status Bit 0 - Input file open 1 - Output file open 2 - Unused, Master: 0=TAPE300, 1=TAPE1200 3 - Set if cataloguing 4 - Unused 5 - Unused 6 - At end of file 7 - End of file warning given &00E3 CFS/RFS filing system options Bit 7-4 Options used for LOAD/SAVE Bit 3-0 Options used for BGET/BPUT &00EA Serial timeout &00EB CFS critical - b7=CFS being used by BGET/BPUT Private CFS/RFS Main Workspace ------------------------------ &02E8-&ED - odd that these are here are as there are eight spare bytes in the main CFS/RFS workspace &0380-&DF - CFS/RFS workspace