DaveTCode / GBADotnet

A C#/net core GBA emulator
MIT License
20 stars 1 forks source link

mgba countup timer tests hang after scheduler implementation merge #91

Closed DaveTCode closed 2 years ago

DaveTCode commented 2 years ago

Seems to hang before setting countup on any timer register so possibly related to IRQ entirely instead somehow

DaveTCode commented 2 years ago

I think there's some trouble here with how we handle cpu irq events when an irq is being fired on literally every cycle (timer prescaler 1 with reload 0xFFFF). Need to think carefully about what exactly we're expecting in that case.

Maybe the best way to think about this is to consider that the timer is just pulling a line high, that line is only ack'd by irq code so repeated irqs shouldn't really change anything unless it interacts poorly with setting the line low in the irq code

DaveTCode commented 2 years ago

Looks like the cpu is stuck in halt state here, not sure if it's supposed to be halting and is waiting for an irq that isn't coming or is supposed to not have halted in the first place

DaveTCode commented 2 years ago

Interrupts are set to only fire on TIM0 but at this point timer 0 is configured with IRQ disabled and is stopped. Maybe I need a cycle delay for halt control?

DaveTCode commented 2 years ago

I still don't know what the code actually does but the sequence is that timer 0 is configured for overflow and irq and turned on with reload FFFE, it overflows which causes an irq and then halt mode is set. Since IRQ has just fired I imagine there's an ordering issue there

DaveTCode commented 2 years ago

The IRQ code for those tests is:

IWRAM_CODE
static void testIrq(void) {
    --irqCounter;
    if (!irqCounter) {
        REG_TM0CNT_H = 0;
    }
}

which would disable TM0 in the way that I'm seeing. I can't see anywhere where halt mode is configured though! Maybe in the bios?!

DaveTCode commented 2 years ago

The HALTCNT bit is being set because a call is being made to SWI 4 (that is IntrWait) with r1 set to 8. That's basically saying "wait until TM0 interrupts". But our TM0 interrupt happens before it's set and then clears the control register so disabling it and not triggering the required interrupt!

The SWI happens on cycle 15674462 on one run, the HALT then happens on 15674641 ~180 cycles later. The latch happened on cycle 15674458 (so just 4 cycles before the SWI) and the overflow happened on cycle 15674458.

Given that the latch was for reload values of 0xFFFE and control values of 0x00C3 it doesn't make much sense that the overflow would happen on the same cycle!

DaveTCode commented 2 years ago

Fix was that timers could overflow and get disabled on the same cycle but the overflow should not occur in that case