Q4 Low level fileqQentry pointsq										This chapter details the filing system entry points as well as some OSWORDand OSBYTE calls provided by HADFS.DOSFILEdDEntry address: &FFDD			File and directory informationd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.DOSARGSdDEntry address: &FFDA				Attribute of open objectd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 2b 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 zerosS*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 extendedS*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.DOSBGETdDEntry address: &FFD7				Read (get) a byted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.DOSBPUTdDEntry address: &FFD4				Write (put) a bytedOn entry:  A	byte to be written	  On exit:  All preserved	    Y	channel numberDOSGBPBdDEntry address: &FFD1				Read or write multiple bytesd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   EInotie 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.DOSFINDdDEntry address: &FFCE				Open or close a filed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 BBGETb will close the channel and return anerror.DFSCVdDVectored					Filing system controld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*OPTb 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*RUNb command. XY points to filename. HADFS tries to run this from	the CSD only. &05  B*CATb 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*ENABLEb command. &09  B*EXb command. XY points to any pathname. &0A  B*INFOb command. XY points to the filename. &0B  B*RUNb from library. Currently not implemented. &0C  B*RENAMEb command. XY points to the filenames after the command. &0DDOSWORDdDEntry address: &FFF1					  OSWORD functionsd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*SETDATEb 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)*100b     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.DOSBYTEdDEntry address: &FFF4					OSBYTE functionsd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,0b or just B*FX90b) bydisplaying their ID number and their name, eg:	B>*FX90	6: Harston ADFS	9: Z80 BASICb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,1b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,1b. 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 BOOTb	Y=3		As Y=2, but without B*I AM BOOTb	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