Replies: 1 comment 2 replies
-
I've dug deeper into the IRQ handling of the Atari ST and just learned that the ST makes use of user-vectored interrupts. This is new terrain for me, too, as the Amiga solely utilizes auto-vectored interrupts. If I understand your explanations correctly, you run Moira with interrupt type u16
Moira::getIrqVector(u8 level) const {
assert(level < 8);
switch (irqMode) {
case IRQ_AUTO: return 24 + level;
case IRQ_USER: return readIrqUserVector(level) & 0xFF;
case IRQ_SPURIOUS: return 24;
case IRQ_UNINITIALIZED: return 15;
default:
fatalError;
}
} Timing is likely imprecise in Moira for this kind of interrupt since I have tested Moira solely against Amiga hardware. However, you can always call BTW, to make interrupt timing 100% accurate in vAmiga, I had to implement additional delays on the Amiga side. This is done by managing a short pipeline that delays the IPL changes for a couple of cycles until they are fed into the CPU. In vAmiga, the code looks like this: void
Paula::checkInterrupt()
{
u8 level = interruptLevel();
if ((iplPipe & 0xFF) != level) {
iplPipe = (iplPipe & ~0xFF) | level;
agnus.scheduleRel<SLOT_IPL>(0, IPL_CHANGE, 5);
trace(CPU_DEBUG, "iplPipe: %016llx\n", iplPipe);
}
}
void
Paula::serviceIplEvent()
{
assert(agnus.id[SLOT_IPL] == IPL_CHANGE);
// Update the value on the CPU's IPL pin
cpu.setIPL((iplPipe >> 24) & 0xFF);
// Shift the pipe
iplPipe = (iplPipe & 0x00FF'FFFF'FFFF'FFFF) << 8 | (iplPipe & 0xFF);
// Reschedule the event until the pipe has been shifted through entirely
i64 repeat = agnus.data[SLOT_IPL];
if (repeat) {
agnus.scheduleRel<SLOT_IPL>(DMA_CYCLES(1), IPL_CHANGE, repeat - 1);
} else {
agnus.cancel<SLOT_IPL>();
}
} I am unsure if something similar is also needed for Atari ST emulation. |
Beta Was this translation helpful? Give feedback.
-
sorry but i wasn't fully able to work this out, i'm a bit of a n00b. my understanding is that any irq consumes 44 cycles. since the ST MFP needs its own vector, i am using the interrupt acknowledge api function that returns this value for IRQ6, or the autovector (24+level) for any other. when i did some logging, only 12 cycles were consume between the interrupt request the the acknowledge function being called.
are the rest called later in the process, or am i expected to account for the cycles in the acknowledge function? (i think there is an extra 4 cycles to add on an ST anyway)
Beta Was this translation helpful? Give feedback.
All reactions