Q4 Low level fileq Qentry pointsq   This chapter details the filing system entry points as well as some OSWORD and OSBYTE calls provided by HADFS. DOSFILEd DEntry address: &FFDD File and directory informationd On entry: A function code On exit: A object type XY pointer to control block XY preserved control block updated Control block: &00 Address of filename &02 Load address &06 Execution address &0A Length, or start address for SAVE &0E Attributes, or end address for SAVE, or start sector for &FD &12 Functions: &FD Read an object's extra catalogue information into the control block. The load field returns the account numbers, main account in XY+2,3 and auxillary account in XY+4,5. The contents of the execution field is currently undefined. The length field returns the length. The attributes field returns holding the start sector and drive of the object. A is returned holding the object type. &FE Verify a file. Unsupported, returns A=&FE. &FF Load a file into memory. If the low byte of the execution address is zero, it loads to the supplied load address, else it loads to the file's own load address. If the filename does not exist, or is a directory, or an execute-only file, or does not have read access, then an error is generated. &00 Save a file. If a file already exists with the same name, it is overwritten. If the file is locked, or a directory exists with the same name, then an error is generated. &01 Write a file's reload address, execution address and attributes. &02 Write a file's reload address. &03 Write a file's execution address. &04 Write a file's attributes. &05 Read object's catalogue information into the control block. &06 Delete object. If the object does not exist, A returned as &00. If the object is locked, or is not owned, then an error is generated. &07 Create an empty file of defined length. Block as for SAVE. &08 Create a directory. If a directory already exists, there is no error. If a file already exists, an error is generated. &09 Object types returned in the A register are: &FF Execute-only file &00 Object not found &01 File found &02 Directory found, the length field holds the amount of disk space that the directory's catalogue takes up. &03 Image file &04 Symbolic link When reading information on I$i, then A returns 0 if the specified drive does not exist, or 2 if it does exist. The disk size in bytes is returned at XY+2, the disk ID at XY+6,7 and the disk flags at XY+8,9. The date the disk was created is returned in the date field of the attributes. File attributes are returned in four bytes as follows: Byte &0E bit 7 Private 6 Execute only by others 5 Writable by others 4 Readable by others 3 Locked 2 Execute only for owner 1 Writable by owner 0 Readable by owner Byte &0F bits 0-4 Date: day of month 5-7 Date: years since 1981, bits 4-6 Byte &10 bits 0-3 Date: month of year 4-7 Date: years since 1981, bits 0-3 Byte &11 bits 0-3 Undefined (zero) 4-7 Undefined (zero) All the calls update the control block with the catalogue information and return the object type in A. If a call is unsupported, then A is returned preserved. DOSARGSd DEntry address: &FFDA Attribute of open objectd On entry: A function code On exit: A usually preserved X points to zero page location X preserved Y file handle or 0 Y preserved Functions: Y=0 &FD Return HADFS version*100 in A and version and capability flags in zero page. The flags show what code is available in the HADFS ROM: zp+0, b0: *COPY in ROM b4: Date provided b1: Passwords used b5: Full INSTALL b2: *COMPACT/*BACKUP in ROM b6: Fast OSGBPB b3: Time provided b7: Random access output zp+1: b0: Scattered workspace b4: Mouse driver provided b1: New workspace b5: Only small disks supported b2: - b6: Hard disk supported b3: - b7: FRED/JIM ramdisk supported zp+2: version number x of x.yy zp+3: BCD version number yy of x.yy &FE Return last drive used to zero page. &FF Update all files to media, zero page ignored. &00 Return filing system number in A, zero page ignored: 0 No current filing system 12 Ram filing system 1 1200 baud cassette 13 2 300 baud cassette 14 3 ROM filing system 15 4 Disk filing system 16 Harston ADFS 5 Econet filing system 17 6 Teletext/Prestel telesoftware 7 IEEE filing system 29 DOS filing system 8 Acorn ADFS 45 Nexus filing system 9 Host filing system 71 BeebItFS 10 Videodisk filing system 92 LinkFS 11 Coprocessor filing system The filing system number in HADFS can be changed using B*OPT 2b to any value between 5 and 16. &01 Return address of any parameters after a filename to zero page. &02 Return version number in A, zero page ignored. &03 Return libfs number in A, zero page ignored. &04 Read disk space used to zero page. &05 Read disk free space to zero page. &06 Y<>0 &80 Read information about an open file to zero page (unimplemented). &FD Read/write system parameters to zero page. Y=&04..&0D reads the values and Y=&84..&8D writes the values: Y=&05/&85 USERNUM Y=&06/&86 CURR - current directory in memory Y=&07/&87 reserved Y=&08/&88 CSD - Currently Selected Directory disk address Y=&09/&89 LIB - Current library disk address Y=&0A/&8A URD - User Root Directory disk address Only CURR, CSD, LIB and URD are guaranteed to be valid. All other values are liable to change from version to version. &FE Unsupported, zero page ignored. &FF Update file on channel Y to media, zero page ignored. &00 Read PTR for channel Y to zero page. &01 Write PTR for channel Y from zero page. If the PTR is moved past the end of the file, the file is extended with zerosS*s and zero is returned in A. &02 Read EXT for channel Y to zero page. &03 Write EXT for channel Y from zero page. If the length of the file is reduced, the end disappears. If the length is increased, the file is extendedS*s as with &01 and zero is returned in A. &04 Read size allocated to file on channel Y to zero page. &05 Read EOF status of file on channel Y. If PTR=EXT then zero page is set to -1, else zero page is set to 0. &06 Ensure file size of file on channel Y of at least the value in zero page. Actual size allocated is returned in zero page. Where zero page is ignored X is ignored and so can be left set to anything on entry. S*sCurrently, extending a file does not pad it with zeros. The extra length of file will contain whatever was originally on the disk. DOSBGETd DEntry address: &FFD7 Read (get) a byted On entry: Y channel number On exit: A byte read Y preserved Cy EOF status. If the byte read is after the end of file, the carry flag is set on exit. After the EOF byte has been read, the next read produces an error. DOSBPUTd DEntry address: &FFD4 Write (put) a byted On entry: A byte to be written On exit: All preserved Y channel number DOSGBPBd DEntry address: &FFD1 Read or write multiple bytesd On entry: A function code On exit: A 0 if call supported XY pointer to control block <>0 if unsupported XY preserved control block updated Control block: &00 Channel number/cycle number &01 Data address &05 Number of bytes/filenames to transfer &09 PTR for transfer/directory pointer &0D Functions: &01 Write bytes to media using new PTR &02 Write bytes to media ignoring new PTR &03 Read bytes from media using new PTR &04 Read bytes from media ignoring new PTR On exit from calls &01 to &04 the 'number of bytes' field holds the number of bytes not transfered. The 'data address' field is updated to point to the next location for data transfer. The PTR for the file is updated by the number of bytes transfered and placed in the 'PTR' field. In functions &01 and &03 the PTR is first set to the supplied value before transfering data. The carry flag is returned set if EOF was met. The EOF-error-flag is reset. &05 Get media title of CSD disk and boot option into data block: &00 length of title (n) &01 title in ASCII characters &01+n startup option &02+n drive number &03+n &06 Get currently selected directory name into data block: &00 length of drive identity (n) &01 ASCII drive identity (drive number) &01+n length of directory name (m) &02+n directory name in ASCII characters &02+n+m ownership: &00 - owner, &FF - public &03+n+m &07 Get current library name into data block: &00 length of drive identity (n) &01 ASCII drive identity (drive number) &01+n length of library name (m) &02+n library name in ASCII characters &02+n+m ownership: &00 - owner, &FF - public &03+n+m &08 Read filenames from current directory into data block: &00 length of filename 1 (n) &01 filename 1 in ASCII characters &01+n length of filename 2 (m) &02+n filename 2 in ASCII characters &02+n+m etc... The first call to function &08 should be made with the directory pointer set to zero. This will read the first filename, and the pointer will be updated so that the next call will read the next filename. On exit, the 'number of filenames' field holds the number of filenames EInotie returned. When no filenames are left, the call returns with the 'number of filenames' left unchanged and the carry flag set. &09 Reads work/login filename or entries from specified directory. If XY+0 is zero, reads command line parameters after a BASIC bootstrap: &00 length of text string (n) &01 Any command line parameters &02+n If XY+0 is a channel number of an open directory, reads a null- terminated list of directory entries. The function is called as for OSGBPB 8, but XY+5 returns the number of filenames read. &0A Read entries and information from the opened directory whose channel number is in XY+0 or the CSD if XY+0 contains zero. This function is called as for OSGBPB 8, but XY+5 returns the number of filenames read. Each record is a whole multiple of four bytes long: &00 Load address &04 Execution address &08 Length &0C Attributes &10 Object type (1=file, 2=directory) &14 Object name, null terminated xxx next record &0B Read entries and information from the opened directory whose channel number is in XY+0 or the CSD if XY+0 contains zero. This function is called as for OSGBPB 8, but XY+5 returns the number of filenames read. Each record is a whole multiple of four bytes long: &00 Load address &04 Execution address &08 Length &0C Attributes &10 Object type (1=file, 2=directory) &14 Sector start address &18 Five zeros (reserved for centisecond time since 1900) &1D Object name, null terminated xxx next record &0C Note: Calls with A=&09, &0A, &0B are only available from version 0.49 onwards. DOSFINDd DEntry address: &FFCE Open or close a filed On entry: A function code On exit: A channel number, or Y channel number for A=0 or 0 if no file opened XY pointer to filename XY preseved If function not supported, A is returned as zero. Functions: &00 Close the file on channel in Y. If Y=0 then close all files. &4X Open file for input. If no file exists, A is returned as 0. &8X Open file for output. If file already exists, tries to delete it first. If no file exists, a file is created with load and execution addresses set to &FFFFFFFF. &CX Open file for update. If no file exists, A is returned as 0. The bottom four bits of A control how the file is opened: If b3 is set, returns an error if file not found, instead of zero handle. If b2 is set, error is generated if attempt to open a directory. File attributes determine how a file can be opened. Directories can be opened for input, but the open channel can only be used for reading information. Trying to do a BBGETb will close the channel and return an error. DFSCVd DVectored Filing system controld This vector is only called by the operating system, and should not be called directly. This list just shows the calls implemented in HADFS. Functions: &00 B*OPTb command. X and Y hold parameters &01 EOF being checked with OSBYTE &7F. On exit, X=&FF if EOF, X=&00 otherwise. &02 B*/b command. XY points to the command text. HADFS tries to run the command from the CSD or the LIB. &03 Unrecognised OSCLI. XY points to the command text. HADFS checks the command against its own commands, then tries to run it from disk as with function &02. &04 B*RUNb command. XY points to filename. HADFS tries to run this from the CSD only. &05 B*CATb command. XY points to any pathname. &06 A new filing system is about to take over. This call is generated by filing systems themselves before they start their initialisation. &07 File handle range request. Lowest returned in X, highest in Y. HADFS uses handles 25 to 29. &08 OSCLI command being processed. This is used to facilitate the B*ENABLEb command. &09 B*EXb command. XY points to any pathname. &0A B*INFOb command. XY points to the filename. &0B B*RUNb from library. Currently not implemented. &0C B*RENAMEb command. XY points to the filenames after the command. &0D DOSWORDd DEntry address: &FFF1 OSWORD functionsd On entry: A function code On exit: A,X,Y usually preserved XY pointer to control block HADFS provides two OSWORD functions, 14 (&0E) and 90 (&5A). &0E Read real-time clock If there is no on-board clock provided (such as in the Master), then the B*SETDATEb command can be used to set a date. This date is then used by HADFS to date-stamp files, and can be read using the standard RTC call. The time part can be set from BASIC using: BTIME=((hours*60+minutes)*60+seconds)*100b TIME is preserved over Ctrl-Break. There may be a few seconds discrepency depending on when the last ROM service call or HADFS filing system call was made. On entry: &00 &00 - read time and date string. On exit: &00 Time and date is returned in the format: Mon,25 Oct 1987.12:24:30 On entry: &00 &01 - read time and date in BCD format. On exit: &00 year (&00-&99) &01 month (&01-&12) &02 day of month (&01-&31) &03 day of week (&01-&07, Sun-Sat) &04 hours (&00-&23) &05 minutes (&00-&59) &06 seconds (&00-&59) A year value of >&80 implies a century number of &19, a year value of <&81 implies a century number of &20. On entry: &00 &02 - convert BCD time and date to string. &01 BCD time and date as for call &01. &08 On exit: &00 Time and date string as with &00. &5A Read/Write sectors This call allows you to read and write sectors of a disk in an internal or external drive. HADFS translates this call into the required low-level calls with OSWORD &7F or OSWORD 90. On entry: &00 &00 \ These two values &01 &06 / identify this call &02 Address &06 Sector start \ Sector &09 Drive number / address &0A Number of sectors &0B Call number, and returned result byte &0C The call numbers are: &80 read sectors &81 write sectors If the call was successful, then the return byte is zero. If not, then one of the following values is returned: &12 Drive read only &14 Track zero not found &18 Sector not found &FE Drive not present HADFS low-level calls also use OSWORD 90, using call numbers 1-7. DOSBYTEd DEntry address: &FFF4 OSBYTE functionsd On entry: A function code On exit: A preserved X,Y any parameters X,Y any returned values A=127 (&7F) - Read EOF status On entry: X=channel number On exit: X=0 if EOF has not been reached X<>0 if EOF has been reached A, Y preserved If PTR=EXT on the channel specified, then EOF is returned true. This call is used to provide BASIC's EOF# function. A=90 (&5A) - JGH sideways ROM service call OSBYTE 90 - General All the ROMs that I write conform to my ROM selection standard that allows interrogation of the roms in a uniform manner. This is the OSBYTE 90 call, used to enable and disable the rom, and to ask for status information about it. The arrangement of the OSBYTE 90 call is: On entry: A=90 X=ID number, or zero Y=call number On exit: A=90 X=b7-b6 rom status, b5-b0 other specific info. Y=other info. All ROMs respond to X=0, Y=0 on entry (B*FX90,0b or just B*FX90b) by displaying their ID number and their name, eg: B>*FX90 6: Harston ADFS 9: Z80 BASICb With X set to non-zero, it is a specific call to a particular ROM, with Y containing the call number. All ROMs respond to calls with Y=0 to enable the ROM, Y=1 to disable the ROM and Y=255 to request the ROM's status, eg: >B*FX90,9,1b will disable the ROM with program ID 9, ie Z80 BASIC. On return from calls 0, 1 and 255, the top two bits of X hold information about whether the ROM is present, and whether it is enabled or not. Bit 7 holds if the ROM is enabled or disabled, and bit 6 holds if the ROM is actually present of not. This is summarised as: X=11xxxxxx rom not present (X returned as &FF) X=10xxxxxx rom present, but disabled X=0yxxxxxx rom present and enabled If the ROM is enabled (ie bit 7 is zero), then it must also be present, so bit 6 is an implied zero. This allows bit 6 to be used to return information on other things. The other six bits of X can be used to return specific information about the ROM. The top two bits of X hold the status of the ROM before the call, so if the ROM is disabled, and you enable it with Y=0, then X will return %10xxxxxx. When calling from a second processor using the OSBYTE call, the Y register is ignored and zero is used instead for calls below OSBYTE &80. This means that if you use a call with Y=255 to read the status, and it returns saying that the ROM was disabled, the ROM will actually have been enabled, because Y=0 has been used instead. To get round this, use something like: BA%=90:X%=number:Y%=255:S%=(USR&FFF4 AND&FF00)DIV256 IF (S% AND &C0)=&80 THEN OSCLI "FX90,"+STR$(number)+",1"b This will redisable a ROM found to be actually disabled. Some of the program IDs that I have used so far are: 1: CharROM - Character set ROM 2: NewMOS 3: 4: 5: Games Auto Boot ROM 6: HADFS - Harston Advanced Disk Filing System 7: Z80 Emulator - Emulates a Z80 CPU 8: 9: Z80 BASIC - BBC BASIC(Z80) with BBC file i/o 10: 11: Dissem ROM - Various disassembly routines 12: 13: 14: 15: 16: NFS Front End If anyone else wants to adhere to this method for a ROM that they are writing, write to me, and I will assign you a number and give you the routine I use for service call 7 to provide the OSBYTE 90 call. OSBYTE 90 - In HADFS The HADFS ROM has program ID 6, and by default it is enabled. To disable it, you can use B*FX90,6,1b. The ROM will re-enable itself on a power-on reset or a memory-clear reset. The X register returns the following information: bit6: HADFS owns workspace from &E00 bit5,4: Number of channels - 2 bit3-0: Private workspace pointer - &14 The call values in Y used by HADFS are: Y=0 Enable ROM Y=1 Disable ROM Y=2 Enable ROM, select HADFS, and do B*I AM BOOTb Y=3 As Y=2, but without B*I AM BOOTb Y=4..Y=63 Unused HADFS calls Y=64 Look for default drive, return drive in X Y=65 Look for default library drive, return drive in X Y=66 Look for default user drive, return drive in X Y=67..Y=127 Unused external HADFS calls Y=128..Y=254 Unused HADFS calls Y=255 Return status Calls from 64 to 127 are only used from version 0.49 onwards