ADFSBuffers ----------- 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. Buffers ------- 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. 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. Processes --------- 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. 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 see how many buffer s cover the corresponding fragment. These are then inserted 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. 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? DiscAdjust/RamAdjust -------------------- 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 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. I'm thinking that DiscAdjust must be always sector aligned. If this assumption breaks I'll have fun. 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.