Close

Fastloader bug

A project log for Unlimited tile world on a Commodore 64

Unfinished childhood project

lion-mclionheadlion mclionhead 08/03/2024 at 21:450 Comments

Noticed the emulator showed unnecessary seeks to track 1 in the middle of reading multiple sectors from the same track.   It seeks directly to the right track, reads 1 sector, then seeks to track 1, then seeks back to the right track to read a few more sectors. The ROM source code implies it's a head bumping operation caused by an error & in real life, it would be a familiar knocking.

  In lion opinion, the knocking sound was not the head impacting anything but the sound of a stepper motor stalling & slipping out of phase.  The head probably experienced much less force.  There are no useful recordings of that sound.

After much poking, the Steil fastloader had a bug where address $05 has to be 0 before calling DOREAD or it'll head bump.  He used $05 as a counter & either the values he stored in it got lucky or it's another Vice bug.  It's unlikely 10 year old lion would have figured that out.

There's a useful table of d64 track offsets not in any goog searches:

http://unusedino.de/ec64/technical/formats/d64.html

The working fastloader did the 9 tile cache fill in 9.1 seconds or 1.01 seconds per tile, with no concurrency.  This would allow 6.1fps of vertical scrolling with only the 2 visible tiles read or 4.1fps with a complete row read.  Things are going to be much slower with concurrent scrolling.  There's also going to be a time quantization where it starts reading a 3rd tile even though not enough time remanes.  Since it can't interrupt a tile read, it's always going to load a complete row.

-----------------------------------------------------------------------------------------------------------------------------------------------

The best optimizations lions could come up with were making it load 1 row of the tile cache at a time, storing all the tiles for a row on 1 track, & packing multiple tiles in each sector to reduce the sector reads.  It would need an offset table to pack sectors.  Currently, the world is limited to 256 tiles & 10 rows of tiles to save on data types.

Sadly, there is no way to abort a sector read.   Testing for ATN low to allow partial sector reads would slow down the reads too much.

It's slower to buffer complete sectors than to decompress 1 byte at a time.  Buffering a complete sector requires shifting in all the unused bits while aborting a read requires just driving the clock.  Because of the way multitasking works, it has to switch the kernal ROM for every RLE code whether the sectors are loaded previously or not.

Packing the tiles only works if they're read from lowest to highest & a complete row is read.  It's always going to throw away the start of the 1st sector in each row.  It's usually going to slow down sideways movement because now a start & end of a sector is thrown away instead of just the end.  It could slightly benefit vertical movement because 1 out of 3 tiles wouldn't require throwing away any data.  There's a small chance the packing could reduce seeking enough to have an improvement.  The complexity of it makes it a pass.

Sadly, storing 1 row per track was actually slower than packing multiple rows in each track.  It seems to cut just enough seeking if the tracks contain multiple rows.

Filling the cache forwards or backwards makes no difference.  It seeks more when reading backwards.

---------------------------------------------------------------------------------------------------------------

A hybrid of scrolling & paging seems in order.  Allow the player to traverse the entire screen while scrolling.  When the player hits an edge, redraw the whole screen.  This would result in a more general purpose game engine which did either scrolling or paging.

The long feared tile renderer converged on something that always renders 4 tiles.  It determines the 4 visible tiles & draws a hard coded corner of each visible tile.  A scratch built tile renderer for each scrolling direction + a 5th renderer which draws the entire screen seems unavoidable.

Discussions