http://ftp.amigascne.org/pub/amiga/Groups/P/Pygmy_Projects/PP-Extension.dms
This demo shows an image for a while and then it turns black. At this point the demo should be starting and music playing, but in vAmiga 0.9.9 it doesn't progress while it works fine in fs-uae
It seems to be stuck on this code
.loop
btst #5,$dff01f
beq.s .loop
Perfect test case! It fails almost immediately and it works fine in SAE with lowest compatibility settings.

vAmiga still has some fundamental bugs (see #348). With some luck, this one helps to rule out at least one of them.
Great! I'm testing a bunch of demos currently as (you have seen) I'm thinking of using vAmiga as a base for "my" Amiga emulator.
Preliminary findings: All Blitter operations are similar to SAE while the demo loads (last cylinder = 62). After that, SAE starts a CIAB timer. vAmiga gets stuck before:

Interesting. So it may be a timer issue then?
Interesting. So it may be a timer issue then?
Not necessarily, because vAmiga didn't even reach the point where the CIA register is written to. In the next step, I'll dump all all chipset register accesses that happen after the last Blitter operation. With some luck, this narrow down the error source.
Not sure if you have checked but perhaps this issue is similar/related to #385 ?
Time to come up with a new hypothesis. 🤓
We already know the demo gets stuck here:

The code waits until the VERTB bit is set in INTREQ. Because the VERTB interrupt is enabled, this bit never reads back as 1 in vAmiga (the breakpoint at $170C is never reached). When I read my SAE debug output correctly (it’s a mess right now), the bit reads back as 1 before the interrupt hits. Hence, this could be a simple timing problem related to the point in time where the VERTB bit is set and the beginning of the IRQ routine.
I’ve already written a test case for that and the test case „proved“ that the bit always reads back as 0 (if the VERTB interrupt is enabled). I need to revisit this test case… it may be plain wrong...
Setting VERTB in INTREQ early gives vAmiga wings 😎.

The correct fix is not so obvious though. I need to write some test cases exhibiting the exact relationship between the VERTB bit and the time the IRQ hits in.
Finally 😎. The code fix explains the bug...
Old code:
void
Agnus::serviceVblEvent()
{
switch (slot[VBL_SLOT].id) {
case VBL_STROBE:
assert(pos.v == 0 || pos.v == 1);
assert(pos.h == 1);
// Trigger the vertical blank interrupt
paula.raiseIrq(INT_VERTB);
// Schedule the next VBL_END event
schedulePos<VBL_SLOT>(5, 209, VBL_END);
break;
case VBL_END:
assert(pos.v == 5);
assert(pos.h == 209);
// Increment the TOD counter of CIA A
amiga.ciaA.incrementTOD();
// Schedule the next VBL_STROBE event
schedulePos<VBL_SLOT>(frame.numLines() + vStrobeLine(), 1, VBL_STROBE);
break;
default:
assert(false);
}
}
New code:
void
Agnus::serviceVblEvent()
{
switch (slot[VBL_SLOT].id) {
case VBL_STROBE0:
assert(pos.v == 0 || pos.v == 1);
assert(pos.h == 0);
// Trigger the vertical blank interrupt
paula.raiseIrq(INT_VERTB);
// Schedule next event
scheduleRel<VBL_SLOT>(1, VBL_STROBE1);
break;
case VBL_STROBE1:
assert(pos.v == 0 || pos.v == 1);
assert(pos.h == 1);
// This cycle is unused at the moment. Until v0.9.9, the VERTB
// interrupt was triggered here which turned out to be wrong.
// It can be deleted once the new code stands the test of time.
// Schedule next event
schedulePos<VBL_SLOT>(5, 209, VBL_END);
break;
case VBL_END:
assert(pos.v == 5);
assert(pos.h == 209);
// Increment the TOD counter of CIA A
amiga.ciaA.incrementTOD();
// Schedule the next VBL_STROBE event
schedulePos<VBL_SLOT>(frame.numLines() + vStrobeLine(), 0, VBL_STROBE0);
break;
default:
assert(false);
}
}
This event driven coding style looks so crazy cool 😍...
🙋🏿♂️when the hardware labs designing a new computer today would they also write first a event driven simulation of it like this to rule out design faults ? 💁🏼♂️Or would they rather tend to use a hardware description language like VHDL ?
This event driven coding style looks so crazy cool 😍...
For writing an Amiga emulator, the event driven approach turned out to be the right thing to do, because it's not necessary to emulate each and every cycle in a single chunk. E.g., if the CPU is busy processing a DIV instruction and Agnus doesn't do anything with the bus, the emulator can process many cycles at once. And it's super easy to adjust timing parameters such as in this case.
Or would they rather tend to use a hardware description language like VHDL ?
They use HDLs such as Verilog, SystemC, or VHDL. I'm not sure if VHDL is still used so much. I think most people use Verilog.
They use HDLs such as Verilog, SystemC, or VHDL. I'm not sure if VHDL is still used so much. I think most people use Verilog.
That means event driven software modelling is difficult to translate into hardware, right? Because it abstracts the parallelism which has to happen in real hardware ...
Most helpful comment
Great! I'm testing a bunch of demos currently as (you have seen) I'm thinking of using vAmiga as a base for "my" Amiga emulator.