Gekkio / gb-research

Game Boy hardware research
226 stars 10 forks source link

SM83: irq_ack #5

Closed paulb-nl closed 7 months ago

paulb-nl commented 7 months ago

First of all thank you for your hard work reverse engineering the SM83.

I encountered an issue with irq_ack: https://github.com/Gekkio/gb-research/blob/a58ce2a27596aed69cc012ddab5d516ca3b201f6/sm83-cpu-core/hdl/interrupts.vhd#L56

irq_ack goes high during cycle int_s110. This means it goes high when PHI is high.

irq_latch is latched when PHI is high. This makes sense because PHI stays high when the CPU is halted.

The issue is that this way irq_ack acknowledges the IRQ when PHI is high and so irq_latch immediately goes low before the address is read during writeback. It will always jump to address $0000.

Most likely it should be like this:

irq_ack <= irq_prio and int_s110 and writeback;

This way it acknowledges the IRQ when PHI is low and irq_latch has stopped latching.

PS irq_prio is a logic vector and int_s110 is a single logic signal. It is strange that these can be simply ANDed together. VHDL is usually very strict.

Gekkio commented 7 months ago

Good catch! You're 100% correct with your reasoning and I've fixed this in my private repo but unfortunately haven't backported the fix here. :sweat_smile:

The influence of writeback is indeed missing, and it's actually missing from all of the irq_prio signals and not irq_ack. Every irq_prio signal uses dynamic logic, and they're in precharge state (output=0) when writeback=0 and evaluation state otherwise.

I'll fix it and maybe merge #3 first to give this public repo a bit more love...

PS. I think that's a VHDL 2008 addition, and basically the standard logical operators have extra overloads to handle the special case where you apply it to a vector and a single bit.

Gekkio commented 7 months ago

Fixed by 40f579ec88ac46fa18ede0570b370f99c9f6553b