To reproduce, do the following:
1.) Load and run diskside 1 (NoBounds-GP-Side1.d64) of https://csdb.dk/release/?id=232957
2.) Run the demo until the "tasting the colours" part (that's the one with the face on the right, and colors / plasma / vector graphics on the left), then do a hard reset (alt+f12).
3.) Restart the demo by entering load "*",8 followed by run.
After this point, doing a snapshot will make the bug disappear. Warping works, but only if started a few second in, and only until the "no bounds" bitmap scroll.
4.) Once the trailblazer runs (that's the slanted chessboard right after the "no bounds" bitmap scroll), enter the monitor and set a breakpoint at $0844.
5.) Once the breakpoint activates, step over the following instructions using the "next" command:
.C:0844 A2 7F LDX #$7F
.C:0846 8E 0D DC STX $DC0D
.C:0849 8E 0D DD STX $DD0D
.C:084c BD 8E DC LDA $DC8E,X
Note that there's a half-second delay on the "STX $DD0D". This happens in older versions of vice, too (I also tested 2.4), and also happens if sound is disabled.
The code position where the delay happens is ciat_update() in https://github.com/VICE-Team/svn-mirror/blob/main/vice/src/core/ciatimer.h which is called via ciacore.c.
I see the while (state->clk < cclk) loop doing 108000902 iterations. For me, the function is entered with state->clk=10975911 and cclk=118976201. Note how those two values differ by exactly said 108000902.
Interesting! That's not supposed to happen like that. There is an "idle alarm", which runs at least every
CIA_MAX_IDLE_CYCLES(5000) cycles, that updates timers if there is nothing else that does this.The call path would be
ciacore_idle->cia_update_ta(alsocia_update_tb) ->cia_do_update_ta->ciat_updatewhich then should update thestate->clkfor that timer. Same for timer B.Can you see if maybe
ciacore_idledoes not get called any more? Or maybe the timer'sclkvalue jumps backward? None of these things should of course happen, but they might explain the phenomenon.Oh, by the way, did you try it with a recent snapshot build, or a release version? Recent snapshot builds can be found at https://github.com/VICE-Team/svn-mirror/releases
Is that delay supposed to happen in "emulation time" or is it "just" that the emul stalls for half a second? At least in "emulation time" it seems to work for me with trunk:
The version I tested with is built from svn source, on 2023-05-07.
I can confirm that there's no calls to
ciacore_idlebetween the reset and when the bug occurs. After the bug, calls tociacore_idlekick back in.USE_IDLE_CALLBACKis true for me.That is useful information. That should be after the latest change to ciacore.c was made.
I could not yet reproduce the issue on a version of today r44071) though. But it could also be that I didn't do the reset at exactly the right time. In any case, it sounds like the issue happens around the time the reset occurs. It may be something that only happens if the reset occurs at just the wrong time.
I didn't measure it, but the issue would happen about 108 seconds after the reset (that's 108 000 902 / 1 000 000).
Does it make a difference if you add a line
alarm_set(cia_context->idle_alarm, rclk + CIA_MAX_IDLE_CYCLES);to the function
ciacore_reset()?I expect it would (although it would not explain yet why this would be needed to keep the idle alarms going... maybe there is something general in the reset routine of the emulator that disables all alarms? just speculating out loud here...)
The emulator stalls. The behavior of the emulated machine itself is fine.
Last edit: Matthias Kramm 2023-06-20
Upon reset,
maincpu_clk(and thus,*cia_context->clk_ptr) is set back down to 6. However, I don't see anything that would re-addidle_alarmbased on the new clock value?Ahhh yes that would explain it. Then the suggestion from my previous entry should certainly help.
I committed a fix along the lines I sketched above in r44076. Please retest.
I think this bug has been there ever since the idle alarm has been created. It was made precisely to avoid the emulator stalls you saw, but what happened to clk when you reset the emu was not taken into account. Should be better now...
Looks good! I can confirm that at SVN revision r44076 (which has the fix), the issue doesn't show up anymore.
Nice work! That was quick turnaround.
Fortunately your information made me think in the right direction quickly and then the further details made it obvious. Thanks for retesting.
So in summary, the issue would happen if you would do the hard emu reset some time after the first CIA access, which would need to be fairly long after the reset. The idle alarm clock value would then be still in the future when the CIA access happens, while the CIA has a lot of time to catch up on since the reset.