rudla.kudla wrote:
IamRob wrote:
Methinks that if you have the memory to store a whole disk image, it would be better used as a RamDisk than a cache.
The idea is that you may have the memory (extended memory in banks) and you may not. In which case the cache will be smaller and program will be slower, but it will run.
That is one reason for not having a cache, so you don't take away precious memory from your program when caching sectors from the disk, if you don't have the extended memory.
Cache will always be faster unless a sector needs to be newly loaded or reloaded. Searching for a file within a directory of files can also be time-consuming. Using a cache shouldn't be about speed, but it comes down to having enough RAM for your program. And keeping an index into what each sector holds.
Here is a simple method that was revised from Forth in how it is used to cache its screens and takes very little memory, but does not keep track of indexes for what is in each sector.
Each cached sector requires 3x ID bytes and 1 page (256 bytes) of memory. The table of ID bytes looks like this:
bytes 1 and 2 - sector # 0 - 559 (or how many sectors disk holds)( or can be used for Track and Slot)
byte 3 - counter ( byte #3 is zero if slot is empty otherwise counts from 1 to 255)
3 bytes per ID means that 1 page of memory can cache 85 sectors or pages in the cache.
The order of the search in the ID table would then be:
1) initialize counters
- set ID counter to 0
- set lowest ID to 0
- set lowest counter-so-far to $FF
2) multiply ID by 3
- load byte 3 - check if zero for empty slot
- if slot is empty (byte 3=0), then goto step 7
- if count is not zero then load byte 2 for a valid sector # and compare with hi-byte of requested sector
- if they do not match then go to step 4
- if they match then fall thru to step 3
3) load byte 1 - compare with lo-byte of requested sector
- if they match then increment byte 3 and goto step 8
- if they don't match then fall thru to step 4
4) get byte 3 again and compare with the lowest count
- if count is <= lowest count so far, then store the lowest count and ID # ( this ensures the ID farthest up the table is used, that has the lowest count, only if there are no empty slots left)
5) advance ID # by 1
- chk for end of table
- if not end of table goto step 2
- if end of table fall thru to step 6
6) get lowest ID, multiply by 3 and use that slot
7) store sector # in bytes 1 and 2 of the current ID and store the count of 1 in byte 3
- calculate address in cache where ( page# = cache_start_hi_byte + ID#)
- load sector in cache
- return to calling program with hi-byte of cache in Accumulator
8) calculate address in cache where (page# = cache_start_hi_byte + ID#)
- return to calling program with hi-byte of cache in Accumulator