I submitted an RZX of Wizard's Lair to the archive today and it plays
back correctly on Spectaculator (all versions), SPIN (all versions)
and EmuzWin. I did not test RS32 because I can't be arsed fannying
about with DOS programs anymore ;-)
Fuse 0.7.0.1 (Mac OS X / 10.3.8) reports this error:
Fuse - Error
libspectrum: libspectrum_rzx_playback_frame: wrong number of INs
in frame 15839: expected 10, got 0
However on Fuse 0.6.2.1 (Mac version again), it plays fine.
Not sure what's what really.
Cheers,
Jon.
--
Jonathan Needle
Spectaculator Creator
http://www.spectaculator.com/
Wizard's Lair.rzx
Logged In: YES
user_id=11017
Thanks for the bug report!
I am no expert on RZX workings, and I have not conducted a detailed
examination of the problem file, I can confirm that the file also fails to
playback on the latest CVS version of Fuse.
Given that the file plays back correctly on 0.6.2.1 and fails on 0.7.01 the
problem is almost certainly the same as that in bug 995896, and
happening as Fuse applies it's retriggered interrupt code to the RZX
playback, and because the RZX spec is imprecise and incomplete. I
believe we've agreed on implementing the same workarounds as
Spectaculator, hopefully it will be fixed for the next version.
Logged In: YES
user_id=29214
What happens:
* 9858 instructions (69884 tstates, not that that matters
much) into frame 15838, we execute the EI at 0xc739.
* Frame 15838 has 9859 instructions in it, so we end the
frame here.
* We don't accept an interrupt immediately, as we're
directly after an EI.
* We execute the HALT at 0xc73a. Normally, we would accept
the "retriggered" interrupt just after this, but we don't as
we're doing RZX playback.
* We then just carry on executing HALTs until the end of the
frame (11426 instructions), when we notice the desync and
bail out.
Jon, I thought Spectaculator wouldn't output the end of an
RZX frame just after an EI to avoid this potential problem.
Am I wrong, or is there a more subtle desync going on here?
FWIW, bodging Fuse such that it will accept interrupts
immediately after an EI makes the RZX play back fully. I
don't know if this is relevant or not.
Logged In: NO
Hi Phil,
I make it
15837 $c739 EI at cycle 57659
15838 $c739 EI at cycle 69679, HALT until EOF (last HALT at
cycle 69887)
15839 $c739 EI at cycle 56705
Although Fuse should always take the int at the end of a
frame (if INTs are enabled) regardless of whether the last
instruction was an EI.
This was the only way to get your head over heels RZX to
play on other emulators... although I can't see a mention of
this in the spec. (IIRC Fuse 0.6.x didn't delay ints after
an EI).
I definitely got an e-mail from you confirming this when I
mailed to say I couldn't get head.rzx to play past a certain
point ;-)
Cheers,
Jon.
Cheers,
Jon.
Logged In: YES
user_id=29214
Got it. This one's more than a little subtle.
What _actually_ happens:
* 9806 (not 9858) instructions into frame 15838, we execute
the EI at 0xc739. Fuse thinks this happens at 69884 tstates
after interrupt, so sets its internal 'interrupts enabled
at' flag to be 69888 tstates.
* We execute another the HALT at 0xc73a 52 times, taking our
tstates value up to 70100.
* We begin to accept an interrupt.
* As the first step of interrupt processing, we call
event.c:event_force_events(). This is designed to ensure
that all expected events happen in the case that Fuse has
run 'fast' (ie that its current tstates value is less than
the normal frame length). At the bottom, this contains the
line "tstates = machine_current->timings.tstates_per_frame",
which happily resets tstates to 69888 (can you see the
problem yet?)
* We think about actually accepting the interrupt. We
compare our 'interrupts last enabled' flag (69888) to the
current tstates value (69888) and decide not to accept the
interrupt at this time.
* Everything does pear-shaped.
I think the correct action here is just to remove the tstate
resetting at the end of event_force_events(). This appears
to work.
What a evil edge case!
[ I'll deal with a couple of other issues raised by this bug
report on -devel ]