ADFSBuffer 4.89 KB
Newer Older
Neil Turton's avatar
Neil Turton committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17

These are my general notes on ADFSBuffers support (FileCore80) as I attempt to
understand the code within (here be demons!).  I intend to list every ADFSBuffers 
function that I examine here along with what changes are required.  I'll also list 
those functions which I consider to not need updating at all.  I'll also generate 
some notes of general ADFSBuffers working.  Hopefully this documentation should be
useful to others in the future.


Each buffer is a 1K buffer.  It can however be considered
as two sub-buffers of 512 bytes or four sub-buffers of
256 bytes.

18 19 20 21 22 23 24 25 26 27 28 29 30
The buffers are controlled by 'BufFlags' which is a 32 bit word arranged as 4 bytes,
one for each sub-buffer. The value of 'BufSz' describes how the buffer is to be
divided, for example a drive with 512 byte sectors would divide it in two.
But BufSz is only an 8 bit variable, so the actual number of bytes in a buffer
is expressed by first shifting down by 'BufScale', which is 5. In other words

  1024 -> 32; 512 -> 16; 256 -> 8.

We can see these cunningly allow the BufFlags to be manipulated using shifts
which exactly correspond to the number of bytes of flags which would be needed to
describe the corresponding number of sub-buffers. The downside to this scheme
is the buffers are stuck at 1K without some serious rewriting of the code.  

Neil Turton's avatar
Neil Turton committed
31 32 33 34 35 36 37 38 39 40

Each 'process' contains a process block which tells us what this
process is actually doing.  Tacked onto the end of the process is
a scatter list - everyone likes scatter lists don't they?  Luckily
for us, pair extension is disabled.  That is, the scatter list never
gets extended just when the driver least expects it, as it causes
all sorts of headaches - allegedly, of course.

41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
There's one process per controller (one for floppies and one for fixed discs).

Each process maintains some state in its respective process control block,
this is kept for the duration of the processing:
 * The drive number (so that scatter lists can be sent to the
   right drive on that controller)
 * Start offset & end offset, in bytes, for the portion of the transfer
   currently being scattered. Note that scatter lists are just attached
   blindly by the foreground process without any consideration of where
   they cross fragment boundaries - it is only when a new chunk of a
   scatter list is being passed (via the DiscOp low level entry) to the
   client filing system that the fragment boundaries are respected
 * Fcb, the file control block to which the scatter list entries relate
 * FragEnd, the end offset, in bytes, of the portion of the scatter list
   that is currently being processed.
 * Error & Status (part of the client API) defined to be held at -4
   and -8 from the scatter list start

When idle FileCore will look to see if any more background work could be
started. If writes are possible the first buffer (attached to the Fcb) will
be picked and using its BufFileOff this is mapped to a fragment. More buffers
will be considered (using SkipWriteBehind and BackwardsSkipWriteBehind) to
Robert Sprowson's avatar
Robert Sprowson committed
see how many buffer s cover the corresponding fragment. These are then inserted
64 65 66 67
in one go onto a scatter list and consumed.
Later, the above steps will repeat. Due to the way the buffers are attached
to the Fcb this results in writing backwards through the file as it happens.

Neil Turton's avatar
Neil Turton committed
68 69 70 71 72 73 74 75 76 77 78 79
Process Scatter Lists
------- ------- -----

As mentioned above, the process scatter lists cannot be extended
by adding more pairs.  Indeed, enough pairs must be available
in each process to satisfy the maximum number of buffers that
can be in use.  Thus each process has a scatter list upto
MaxFileBuffers in length.  Each scatter list entry must correspond
to either a buffer or a direct transfer.  A scatter list entry
cannot cover multiple buffers as data for adjacent buffers in
a transfer will not conjoin.  Does this apply for sub-buffers?

80 81 82 83 84 85 86 87

This is an adjustment offset which expresses either the originating
buffer (when RamAdjust) or target disc address (when DiscAdjust)
relative to the file offset.

By example
Neil Turton's avatar
Neil Turton committed

89 90 91 92 93 94 95 96
  Buffer    = 0x12340000
  FileOff   = 0x00010000
  RamAdjust = 0x12330000

so as you read bytes at FileOff, there's no need to keep two indexes
in sync, the buffer address can be recreated by just adding RamAdjust.

DiscAdjust works the same, only it's a disc address rather than RAM.
Neil Turton's avatar
Neil Turton committed
97 98
I'm thinking that DiscAdjust must be always sector aligned.  If
this assumption breaks I'll have fun.
Robert Sprowson's avatar
Robert Sprowson committed
99 100 101 102 103 104 105 106 107 108 109 110 111

OS_File Load

At least as far back as FileCore 2.41, and throughout all CVS history, FileCore
has registered with FileSwitch with bit 20 (fsinfo_dontuseload) of the FS
info word set.

This is rationalised as being so that the GetBytes entry gets used in the
hope that some of the request can be met from the read ahead cache.

The code to handle OS_File 255 (DoOsFileLoad in FileCore45.s) bypasses the
read ahead cache, using IndDiscOp directly, but the function is never called.