========================================== IMPLEMENTING A FILING SYSTEM WITH FILECORE ========================================== ============ Introduction ============ You must provide a parent module that starts up another instantiation of FileCore, handles various high level filing system specific operations and services the requests for low level operations. ============= FileCore SWIs ============= These are provided by FileCore for the use of the driver module. For those marked with a * the caller must prove it's identity by passing in R8 the address of the private word of it's instantiation of FileCore. &40540 DiscOp * ------------- For fuller details on parameters and results see low level below. entry R1 bits 0-7 reason code and option bits, bits 8-31 if non zero are bits 2-25 of a word aligned ptr to an alternative disc record R2 disc address R3 RAM ptr R4 length R8 ->FileCore instance private word exit R0 IF V set error pointer else preserved R1 preserved R2-R4 adjusted to reflect amount transferred &40541 Create - This creates a new instantiation of an ADFS like filng system ------------- entry R0 -> descriptor block R1 -> module base R2 -> parent modules private word R3 b0 -b7 number of floppies b8 -b15 number of winnies b16-b24 default drive b25-b31 start up options all 0 except bit 30 set <=> No dir state R4 suggested size for directory cache R5 suggested number of buffers for file cache 1K + 48 bytes each a zero value indicates that the drivers do not support background transfers R6 winnie map sizes, 1 byte for each winnie = map size/256, ie 2 for old map this is just a good guess eg held in CMOS and should not involve starting up the drives to read from them exit R0 if error V set R0->error block else R0->FileCore instance private word R1 address to call after completing background floppy op R2 address to call after completing background winnie op R3 address to call to release FIQ after low level op the layout of the descriptor block is offset length entry 0 3 bit 0 set if winnie needs FIQ bit 1 set if floppy needs FIQ bit 2 set if able to support background ops 3 1 filing system number 4 4 offset of filing system title from module base 8 4 offset of boot text from module base 12 4 offset of low level disc op entry from module base 16 4 offset of miscellaneous low level from module base Calling the addresses returned in R1-R3 should be done in supervisor mode with R12 holding the value of R0 returned by this SWI. R0-R11,R13 will be preserved. &40542 Drives * ------------- entry R8 ->FileCore instance private word exit R0 default drive R1 number of floppies R2 number of winnies &40543 FreeSpace * ---------------- entry R0 ->zero terminated disc specifier R8 ->FileCore instance private word exit R0 if error V set r0-> error block else total free space on disc R1 largest object than can be created &40544 FloppyStructure * - creates a RAM image of a floppy map and root dir ---------------------- entry R0 ->buffer R1 ->disc record describing shape and format R2 = b7 set for old dir, b6 set for old map, other bits 0 R3 -> list of defects (byte addresses of defective sector starts), end marked by &20000000. New map only exit R0,V if error R3 total size of structure created &40545 DescribeDisc ------------------- entry R0 -> disc specifier R1 -> 64 byte block to fill with disc record ============================================================ THE FOLLOWING CALLS MUST BE IMPLEMENTED BY THE DRIVER MODULE ============================================================ ======================================= Low level disc op call to parent module ======================================= Entry Exit R0 irrelevant IF successful 0 else see below R1 reason code Unchanged R2 disc address Incremented by amount transferred R3 RAM address (or ptr to scatter list) Incremented appropriately R4 length in bytes Decremented by amount transferred R5 disc record describing disc R6 -> boot block (winnie only) Other exit conditions NZC preserved V set <=> error If error R0 returned must be one of following R0 < &100 Internal filecore error number &100 <= R0 < 2^31 pointer to error block R0 >= 2^31 disc error bits as below b0 to b20 disc byte address / 256 b21 t0 b23 drive b24 to b29 disc error number b30 0 R1 REASON CODE -------------- bit 0 to bit 3 0 Verify R2,R4 1 Read sectors R2,R3,R4 2 Write sectors R2,R3,R4 3 Read track on floppy, Read Id on hard discs R2,R3 4 Write track R2,R3 5 Seek R2 6 Restore R2 7 Step in, floppy only 8 Step out floppy only 15 Specify, hard discs only, DESCRIPTION BELOW R2 Only reason codes 0,1,2,5,6 are essential. Seek is actually only used for park. Only reasn codes 0-2 modify R2-R4 on exit bit 4 ----- This bit is set if an alternate defect list for a hard disc is to be used. This is assumed to be in RAM 64 bytes after the start of the disc record R5 bit 5 ----- If this bit is set rather than R3 being the RAM address for the transfer it is a pointer to a word aligned list of address,length word pairs for the transfer. All lengths except the final one must be a multiple of the sector size. These are used in turn until the total length as specified in R4 has been transferred. R3 is incremented to point to the first pair that has not been fully used and this address,length pair is modified so that a subsequent call would continue from where this call has finished. This in only supported for reason codes 0 to 2. bit 6 ----- If this is set ESCAPE is ignored. bit 7 ----- If this bit is set the floppies will not timeout if the drive does not go ready within 1s but will wait indefinitely. bit 8 ----- If this is set the transfer may be wholly or partially in the background. See description of background operations. R2 disc address --------------- bits 0 to 28 This specifies the start byte on the disc and must be at a sector or track boundary as appropriate. Sectors, heads and tracks are numbered from 0. = ((track * heads + head) * sectors_per_track + sector - x) * sectors_size + byte x is an adjustment for defect skipping applied for reason codes 0-2 with old map hard discs, and is the number of defective sectors earlier on the disc. bits 29 to 31 This is the drive number, 0 to 3 floppies, 4 to 7 hard discs. R5 Disc Record entries marked * should be 0 for old map offset length 0 1 log to base 2 of sector size 1 1 sectors per track 2 1 heads (1 for L format floppy) 3 1 density 1/2/4 single double quad if applicable * 4 1 length of id field of map fragment in bits * 5 1 log to base 2 of bytes for each map bit * 6 1 track to track sector skew for random access file allocation 7 1 boot option * 8 1 RESERVED * 9 1 zones in the map * 10 2 bits in zone which are neither map bits nor special zone 0 bytes 12 4 disc address of root directory 16 4 disc size in bytes 20 2 disc id 22 10 disc name 32 4 R6 Boot Block ------------- Sectors 12 and 13 of a hard disc contain a &200 byte boot block as below any unused bytes should be set to 0. 0 1 2 0 C 0 0 0 0 ------------------------------------------------------------------------ | Hardware | Disc record | |==>Defect list Specific <==| describing | | Parameters | disc | ------------------------------------------------------------------------ The drivers are responsible for doing defect skipping on old format hard discs. The defect list is a word list of disc addresses in bytes of the start of sectors which are defective. These do not have drive bits set and are absolute, rather than adjusted for earlier defects. The end of the defect list is marked by &200000xx where xx is a check byte calculated as follows entry Ra -> list start exit Ra corrupt Rb check byte Rc corrupt MOV Rb,#0 ;init check loop LDR Rc,[Ra],#4 ;get next entry CMPS Rc,#&20000000 ;all done ? EORCC Rb,Rc,Rb,ROR #13 BCC loop EOR Rb,Rb,Rb,LSR #16;compress word to byte EOR Rb,Rb,Rb,LSR #8 AND Rb,Rb,#&FF &1BC-&1BF unadjusted parking disc address The boot block should also have the same check byte at the end as an old format map. ==================== Background transfers ==================== This is an optional extension to improve performance. To reduce rotational latency the protocol also provides for transfers of indeterminate length. If the background bit is set in the reason code (only possible for read sectors and write sectors) then the length given in R4 is treated as the length of the foreground part of the transfer. The drivers should return to the caller leaving a background process scheduled by interrupts from the controller when the foreground part is complete. This process should terminate when it finds an address length pair with a zero length field (background ops always use the scatter option and an exact number of sectors). The foreground process can add pairs to the list at any time and to get the maximum decoupling between the processes the drivers should update the scatter list after each sector. The drivers must be able to retry in the background. The scatter list is extended as below -8 Process error | Process status -4 ------------------------------------------------------------- 0 1st address | 1st length 4 ------------------------------------------------------------- 8 2nd address | 2nd length C ------------------------------------------------------------- 10 3rd address | 3rd length 14 ------------------------------------------------------------- etc ------------------------------------------------------------- N Loop back marker -N | ------------------------------------------------------------- Process error is set by the caller to 0, on an error the drivers should set this to describe the error in the format described above. The bits in process status are b31 process active b30 process can be extended other bits are reserved Both bits are set by the caller and are cleared by the drivers. The drivers must have IRQs disabled from updating the final pair in the list to clearing the active bit. A negative address of -N indicates that the drivers have reached then end of the scatter table and should get the next address length pair from the start of the scatter list N bytes earlier. The drivers may be called with the scatter pointer (R3) not pointing to the first (address,length) pair. So to find the addresses of Process error and Process status the end of list must be searched for. From this the start of the scatter block may be calculated. ======================= Low Level Miscellaneous ======================= R0 reason code R1 drive NZC preserved V set <=> error (only Mount is allowed to give error) 0 Mount ------- entry R2 disc address R3 RAM address R4 length to read R5 disc rec to fill in exit IF error R0 as for low level disc op, V set R1-R5 preserved Floppy This asks you to read in the free space map and identify the format. The suggested density to try first is given in the disc record. Identify the format consits of filling in the density and for old format sector size, sectors per track, heads, disc size and root dir. Hard disc This asks you to read in the boot block if it doesn't have one you will have to fudge it 1 Poll changed -------------- entry R2 sequence number exit R2 sequence number R3 result flags The sequence number is to ensure no changes are lost due to reset being pressed. Both the parent module and the file core incarnation should start with a sequence number of 0 for each drive. The parent module increments the sequence number with each change of state. If the parent module finds the entry sequence number does not match its copy it should return changed/maybe changed depending on whether the disc changed line works/doesn't work. result flags (exactly one of b0-b3 must be set) set<=>true b0 not changed b1 maybe changed b2 changed b3 empty b6 empty works may never return 0 after returning 1 for this drive b7 changed works may never return 0 after returning 1 for this drive 2 Lock Drive floppy only - at least ensure drive light stays on till unlock ------------ 3 Unlock drive floppy only -------------- 4 Poll period floppy only ------------- exit R5 minimum period (in centi-seconds) worth polling to see if disc has been inserted or -1 if disc changed doesn't work R6 media title string eg 'disc' This call informs FileCore of the minimum period between polling for disc insertion. This is so that drive lights do not remain continously illuminated. The values are re-exported by FileCore in the up calls MediaNotPresent and MediaNotKnown. The value applies to all drives rather than a particular drive.