An estimate of reading speed
I chose a file from Gutenberg approximately 336kB in length (The Extraordinary Adventures of Arsène Lupin, Gentleman-Burglar

), read the file from the CF, and output it to the serial port, where it is displayed in miniterm as UTF-8.
This takes thirty seconds.
For comparison, 'cat'ing the same file to a terminal on this laptop completes before I can get my finger off the return key, let alone time it.
At first glance, then, a read speed of 11200 bytes per second. But we have to consider the transmission time at 115200 baud, or 11520 bytes per second. 336k/115.2k ~= 3 seconds, so we can subtract that from the initial time; that's obviously not part of the read time, so now we're looking at 336k/27 seconds = 12400 bytes per second.
And I fear that's about as fast as it's going to go, for a few reasons: firstly, in this example, I'm dealing directly with the transient area into which all sectors are read before display. In the final version, every open file is going to require its own buffer, to allow operation without affecting other files. That's going to take some time to move the data (it might be faster, but won't be easier) to rewrite the CF handling routines to use a variably defined buffer. I need to think about that.
There's obviously a lot of games being played with the FAT. Even with this file, which is in pretty much linear order with sequential clusters, at the end of each cluster I have to go back to the FAT with
fs_next_cluster (and through it,
clus_to_1st_sector) with multiple sectors being read before I get to the cluster/sector I need - in case it's _not_ the next one.
Finally, there's a chunk of code that has to happen between each character being read and output: I need to increment a 32-bit file pointer _and_ check whether it equals the file size:
Code: Select all
bne f_cat_11 ; else increment the file pointer
inc f_cat_ptr+1
bne f_cat_11
inc f_cat_ptr+2
bne f_cat_11
inc f_cat_ptr+3
f_cat_11:
and
Code: Select all
f_eof:
lda f_cat_ptr ; lsb most likely to be different, so first
cmp f_cat_size
bne f_eof_x
lda f_cat_ptr+1
cmp f_cat_size+1
bne f_eof_x
lda f_cat_ptr+2
cmp f_cat_size+2
bne f_eof_x
lda f_cat_ptr+3
cmp f_cat_size+3
f_eof_x:
rts
Even though both code fragments are intended to run as quickly as possible (starting with the low byte and ignoring the others if not required for the increment, and testing the low byte first as being the most likely not to match), I'm guesstimating that there's a couple of seconds minimum just in those two fragments.
Oh well, not as fast as I had hoped, but not as bad as it might be.
For file pointer operations, I'm thinking of a double slot. I want the per-file buffer to start on a page boundary for obvious reason, but I also need a small structure of perhaps 64 bytes (not sure yet) which can be allocated wherever. One entry in the cluster might be a pointer to the buffer... though I fear the 65c02 is not well suited to efficient pointers-to-pointers nor to 32 bit arithmetic.
But allocating this way might use the top couple of pages of RAM for the first buffer, part of the next page down for the file pointer info:
Code: Select all
$7E00 [buffer 1, $200 bytes]
$7DC0 [file pointer 1, $40 bytes]
$7D80 [file pointer 2, $40 bytes]
$7D40 [file pointer 3, $40 bytes]
$7B00 [buffer 2, $200 bytes]
$7900 [buffer 3, $200 bytes]
and so on. Possibly limiting things to a maximum of four, or maybe eight, files at a time. I really _don't_ want to get into malloc()...
Neil
Edit: I dropped a decimal place: the serial data rate is 11520 bytes per second, not 115200 - that's bits per second. So the transmission time is 336k/11.5k = 29 seconds... which is excellent news. The access is taking only a second or so.
