by sixxie » Wed Jul 07, 2010 8:36 am
Ok, here's what's going on. Hope this helps understand how it works,
and why it sometimes doesn't!
The XRoar "-tapehack" mode employs a crazy heuristic to try and both
accurately reflect data blocks read by the standard ROM routines, and
format data bytes on nice boundaries to create "readable" .cas files.
It only works well for (most) programs that only use the ROM calls
when loading. For anything else (Superkid, Fire Force, ...) I still
need to study what's going on and specifically patch to account for it.
No data is written until the state is considered synced. State is
initially desynced with a long leader required to be written on the next
"sync".
Four ROM routines are trapped:
At $B94D, partway into the BLKIN call at $B93E, once a block sync byte
is recognised, a leader is written (long or short) and the state is
marked synced. The sync byte itself is also written ($3C).
At $B97E, about to return from BLKIN, the state is set to desynced, but
only a short (2 byte) leader is requested for the next sync. Most data
blocks will trigger this.
At $BDAC, returning from the BITIN call at $BDAD, a bit is written if
the state is synced.
At $BDE7, CASON, the state is marked desynced with a long leader required
for the next sync.
Additionally, whenever the cassette motor changes state to OFF, the state
is desynced with long leader required for next sync. Whenever the state
is desynced, zero bits are output to ensure the last byte is complete.
For a standard data stream, that basically amounts to a long leader being
written before the filename block and the first data block (because the
motor will switch off) with short leaders between all other blocks.
Some games use a "gapped loader", with the motor switching off and on
between all data blocks, and these will result in lots of long leaders
appearing in the output.