Menu

#38 Wizard's Lair.rzx does not playback on 0.7.0.1

closed-fixed
None
5
2005-04-27
2005-03-15
Anonymous
No

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/

Related

Bugs: #336

Discussion

  • Nobody/Anonymous

    Wizard's Lair.rzx

     
  • Fredrick Meunier

    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.

     
  • Philip Kendall

    Philip Kendall - 2005-04-03

    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.

     
  • Nobody/Anonymous

    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.

     
  • Philip Kendall

    Philip Kendall - 2005-04-27
    • assigned_to: nobody --> pak21
    • status: open --> closed-fixed
     
  • Philip Kendall

    Philip Kendall - 2005-04-27

    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 ]

     

Log in to post a comment.