Movatterモバイル変換


[0]ホーム

URL:


RISCOS.com

www.riscos.com Technical Support:
Programmer's Reference Manual

 

Writing a FileCore module


Adding your own module to FileCore

FileCore does not know how to communicate directly with the hardware that your filing system uses. Your module must provide these facilities, and declare the entry points to FileCore.

This chapter describes how to add a filing system to FileCore. You should also see the chapter entitledModules for more information on how to write a module.

Declaring your module

When your moduleinitialises, it must inform FileCore of its existence. You must callFileCore_Create to do this. R0 tells FileCore where to find adescriptor block. This in turn tells FileCore the locations of all the entry points to your module's low level routines that interface with the hardware:

Descriptor block

This table shows the offsets from the start of the descriptor block, and the meaning of each word in the block:

OffsetContains
0Bit flags
3Filing system number (see the chapter entitled FileSwitch)
4Offset of filing system title from module base
8Offset of boot text from module base
12Offset of low-level disc op entry from module base
16Offset of low-level miscellaneous entry from module base

Theflag bits in the descriptor block have the following meanings:

BitMeaning when set
0Hard discs need FIQ
1Floppy discs need FIQ
2Reserved - must be zero (wassupports background operations under RISC OS 2).
3Use only scratch space when a temporary buffer is needed
4Hard discs support mount like floppies do (ie they fill in sector size, heads, sectors per track and density)
5Hard discs support poll change (ie the poll change call works for hard discs and returns a sensible value; also locking them gives a sensible result)
6Floppy discs support power-eject
7Hard discs support power-eject

RISC OS 2 only uses bits 0 - 3; it ignores other bits.

Wherever possible, you should make hard discs support mount like floppies do, and hence set bit 4. If you do not do so, FileCore may have trouble mounting discs that use an alien format, as it then has no way of determining their geometry, and so has to make some assumptions that may be invalid.

FileCore_Create starts a new instantiation of FileCore, and, on return to your module, R0 points to the workspace that has been reserved for that new instantiation of FileCore. You must store thispointer in your module's workspace for future calls to FileCore; it is this value that tells FileCore which filing system you are (as well as enabling it to find its workspace!).

Unlike filing systems that are added under FileSwitch, the boot text offset cannot be -1 to call a routine.

Temporary buffers

The table below shows areas which may be used for temporary buffers when bit 3 of the flag word is not set:

Scratch spaceSpare screen areaWimp free poolRMA heapSystem heapApplication areaDirectory cache
FSEntry_Func 8[YES][YES][YES][YES][YES][NO][NO]
FSEntry_Close[YES][YES][YES][YES][YES][NO][NO]
FSEntry_Args 7[YES][YES][YES][YES][YES][NO][NO]
AllocCompact[YES][YES][YES][YES][YES][NO][NO]
Compact[YES][YES][YES][YES][YES][NO][NO]
*Backup X X[NO][NO][YES][YES][YES][NO][YES]
*Backup X Y[YES][YES][YES][YES][YES][NO][NO]
*Backup X X q[NO][NO][YES][YES][YES][YES][YES]
*Backup X Y q[YES][YES][YES][YES][YES][YES][NO]
*Compact[YES][YES][YES][YES][YES][NO][NO]

where AllocCompact is the auto-compact triggered when allocating space for a file, and Compact is a normal auto-compact.

Selecting your filing system

Your filing system should provide a * Command to select itself, such as *ADFS or *Net. This must call OS_FSControl 14 to inform FileSwitch that the module has been selected, thus:

StarFilingSystemCommand        STMFD   r13!, {r14}        MOV     r0, #FSControl_SelectFS        ADR     r1, FilingSystemName        SWI     XOS_FSControl        LDMFD   r13!, {pc}

For full details of OS_FSControl 14, seeOS_FSControl 14.

Other * Commands

There are no other * Commands that your filing system must provide. For many FileCore-based systems the range it provides will be enough, and your module need add no more.

Implementing SWI calls

SWI calls in a FileCore module are usually implemented by simply:

  • loading R8 with the pointer to the FileCore instance private word for your module
  • calling the corresponding FileCore SWI.

For example, here is how a module might implement a DiscOp SWI:

        STMFD   r13!, {r8, r14}     ; R12 points to module workspace        LDR     r8, [r12, #offset]  ; R8 <- pointer to FileCore private word        SWI     XFileCore_DiscOp        LDMFD   r13!, {r8, pc}

Usually DiscOp, Drives, FreeSpace and DescribeDisc are implemented like this. Of course you can add any extra SWI calls that are necessary.

Removing your filing system

The finalise entry of your module must remove its instantiation of FileCore. For full details of how to do so, see the chapter entitledFinalisation Code.

Returning errors

Your module has to return errors through FileCore as follows:

The V flag must be set, and R0 is used to indicate the error:

  • If bit 30 of R0 is set then, after clearing bit 30 of R0, it is a pointer to an error block.
  • If bit 31 of R0 is set and bit 30 is clear, then R0 is a disc error:

    bits 0 - 20 are the disc byte address / 256
    bits 21 - 23 are the drive number
    bits 24 - 29 are the disc error number

  • Else bits 30 - 31 are clear, and R0 is an error number:

    bits 0 - 7 are an error number (see list below)
    bits 8 - 29 are clear

In the latter two cases FileCore will generate a suitable error block.

Theerror numbers that may be returned are:

ErrorTokenDefault text
11ExtEscapeEscape
94DefectCan't map defect out
95TooManyDefectsToo many defects
96CantDelCsdCan't delete current directory
97CantDelLibCan't delete library
98CompactReqCompaction required
99MapFullFree space map full
9ABadDiscDisc not formatted (not ADFS format)
9BTooManyDiscsToo many discs
9DBadUpIllegal use of ^
9EAmbigDiscAmbiguous disc name
9FNotRefDiscNot same disc
A0InUseFileCore in use
A1BadParmsBad parameters
A2CantDelUrdCan't delete user root directory
A5BufferNo room for buffer
A6WorkspaceFileCore Workspace corrupt
A7MultipleCloseMultiple file closing errors
A8BrokenDirBroken directory
A9BadFsMapBad free space map
AAOneBadFsMapOne copy of map corrupt (use *CheckMap)
ABBadDefectListBad defect list
ACBadDriveBad drive
ADSizeSizes don't match (backups)
AFDestDefectsDestination disc has defects (backups)
B0BadRenameBad RENAME
B3DirFullDirectory full
B4DirNotEmptyDirectory not empty
BDAccessAccess violation
C0TooManyOpenToo many open files
C2OpenFile open
C3LockedLocked
C4ExistsAlready exists
C5TypesTypes don't match
C6DiscFullDisc full
C7DiscDisc error
C9WriteProtProtected disc
CADataLostData lost
CCBadNameBad name
CFBadAttBad attribute
D3DriveEmptyDrive empty
D4DiscNotFoundDisc not found
D5DiscNotPresentDisc not present
D6NotFoundNot found
D7DiscNotFileCoreFileCore does not understand this disc
D8NotToAnImageYouDontOperation inapplicable to disc images
DEChannelChannel
FDWildCardsWild cards
FEBadComBad command

Module interfaces

The next section describes the interfaces to FileCore that your module must provide.

Module interfaces

Your module must provide two interfaces to FileCore: one for DiscOps, and one for other miscellaneous functions.

DiscOp entry

The entry for DiscOps does much of the work for a DiscOp SWI. It is passed the same values as FileCore_DiscOp (seeFileCore_DiscOp), except:

  • an extra reason code is added to R1 allow background processing
  • consequently R1 is no longer used to point to an alternative disc record instead R5always points to adisc record
  • R6 points to aboot block (for hard disc operations only), with the special value &80000000 indicating that none is available.

These are the reason codes that may be passed in R1:

ValueMeaningUsesUpdates
0VerifyR2, R4R2, R4
1Read sectorsR2, R3, R4R2, R3, R4
2Write sectorsR2, R3, R4R2, R3, R4
3Floppy disc: read trackR2, R3
Hard disc: read IdR2, R3
4Write trackR2, R3
5Seek (used only to park)R2
6RestoreR2
7Floppy disc: step in
8Floppy disc: step out
15Hard disc: specifyR2

The reason codes youmust support are 0, 1, 2, 5 and 6. You must complete the entire operation requested, or give an error if you are unable to do so.

Your routine must preserve R1 - R13 inclusive, except where noted otherwise above, ie:

  • R2 must be incremented by the amount transferred for Ops 0, 1 and 2
  • R3 must be incremented appropriately for Ops 1 and 2
  • R4 must be decremented by the amount transferred for Ops 0, 1 and 2

You must also preserve the N, Z and C flags.

Returning errors

If there is no error then R0 must be zero on exit and the V flag clear. If there is an error then V must be set and R0 must be one of the following:

ValueMeaning
R0 < &100internal FileCore error number
Bit 30 set, bit 31 clearpointer to error block
Bit 30 clear, bit 31 setdisc error bits:
bits 0 - 20 = disc byte address / 256
bits 21 - 23 = drive
bits 24 - 29 = disc error number

For a list of internal FileCore error numbers, see the chapter entitledDisc errors.

Background transfer

If bit 8 of R1 is set, then transfer may be wholly or partially in the background. This is an optional extension to improve performance. To reduce rotational latency the protocol also provides for transfers of indeterminate length.

R3 points to a list of address/length word pairs, specifying an exact number of sectors. The length given in R4 is treated as the length of the foreground part of the transfer. R5 is a pointer to the disc record.

Your module should return to the caller when the foreground part is complete, leaving a background process scheduled by interrupts from the controller. This process should terminate when it finds an address/length pair with a zero length field.

The foreground process can add pairs to the list at any time. To get the maximum decoupling between the processes your module should update the list after each sector. This updatingmust be atomic (use the STMIA instruction). Your module must be able to retry in the background.

The list is extended as below:

OffsetContents
-8Process error
-4Process status
01st address
41st length
82nd address
122nd length
163rd address
203rd length
etc
nLoop back marker -n (wheren is a multiple of 8)
n+4Length of zero

Process error is set by the caller to 0; on an error your module should set this to describe the error in the format described above.

The bits in process status are:

BitMeaning when set
31process active
30process can be extended
0 - 29pointer to block giving position of any error

Bits 31 and 30 are set by the caller and cleared by your module. Your module must have IRQs disabled from updating the final pair in the list to clearing the active bit.

A negative address of -n indicates that your module has reached the end of the table, and should get the next address/length pair from the start of the scatter listn bytes earlier.

Your module 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, you must search for the end of list. From this you may then calculate the start of the scatter block.

MiscOp entry

The entry for MiscOps does much of the work for a MiscOp SWI. It is passed the same values as FileCore_MiscOp (seeFileCore_MiscOp) - save for one reason code, noted below, which can be passed extra parameters.

  • Although FileCore_MiscOp is not available in RISC OS 2, you must still provide this entry point, as other SWIs also use it. (The MiscOp SWI merely provides a convenient way of directly calling this entry point.)

These are the reason codes that may be passed in R0:

ValueMeaning
0Mount
1Poll changed
2Lock drive
3Unlock drive
4Poll period
5Eject disc

The reason codes you must support are 0, 2 and 3; for floppy drives, youmust also support reason codes 1 and 4.

Your routine must preserve registers, and the N, Z and C flags - except where specifically stated otherwise.

When this entry point is called, R12 is a pointer to your FileCore module's private word.

You may only return an error from reason code 0 (Mount). This must be done in the same way as for the DiscOp entry; see the chapter entitledReturning errors.

For drives with disc sensing, reason code 1 (Poll changed) must always returnchanged in thespun-down state. If the drive is spun-up, you must returnmaybe changed if the drive has been permanently spun-up since the last 'Poll changed'; other wise you must returnchanged:


'Poll changed' returns for drives with disc sensing

Under RISC OS 2, the values returned from MiscOp 1 (Poll changed) in bits 4, 5, and 8 - 10 of R3 are ignored by FileCore.

Reason codes 2 and 3 (Lock/Unlock drive) must always perform that action. You must not try to track the state of the drive locking; FileCore counts lock/unlock calls itself, and only calls your module when it should actually lock or unlock the drive.

Reason code 5 (Eject disc) will never be called if bits 6 and 7 of the descriptor block are clear, since this indicates that no drives support power-ejection. Otherwise it may get called in a variety of situations: for example, after dismounting all discs as part of shutting down all filing systems.

Reason code 5 is also called whenever FileCore issues an UpCall 1 (medium not present), or an UpCall 2 (medium not known). In this case, the top bit of the drive number is set, indicating that a disc should be ejected from the drive considered to be most appropriate. The values passed to the UpCall in R4 (the iteration count) and in R5 (the minimumtimeout period) are also passed on in the same registers to the MiscOp entry point. The filing system may treat these as appropriate; for example, it may choose to eject only on iteration 0 for an auto-insert detect drive, as doing further ejects may make it hard to get a new disc into the drive.

For more details of OS_UpCall 1 and 2, seeOS_UpCall 1 and 2.

This edition Copyright © 3QD Developments Ltd 2015
Last Edit: Tue,03 Nov 2015


[8]ページ先頭

©2009-2025 Movatter.jp