Compare commits

...

2 Commits

  1. 22
      libplip/Core/GameBoy/GameBoyInstance.Timer.cpp
  2. 8
      libplip/Cpu/SharpLr35902/SharpLr35902.cpp

22
libplip/Core/GameBoy/GameBoyInstance.Timer.cpp

@ -27,7 +27,7 @@ namespace Plip::Core::GameBoy {
// Quirk: If IF is written during the interrupt cycle, the
// written value will override this.
if(m_lastWrite.address == Plip::Cpu::SharpLr35902::MemInterruptFlag)
if(m_lastWrite.address != Plip::Cpu::SharpLr35902::MemInterruptFlag)
m_cpu->Interrupt(INTERRUPT_TIMER);
}
@ -59,12 +59,19 @@ namespace Plip::Core::GameBoy {
inline void GameBoyInstance::TimerIncreaseTima() {
uint8_t tima = m_ioRegisters->GetByte(m_regTima) + 1;
m_ioRegisters->SetByte(m_regTima, tima);
if(tima == 0) {
// TIMA overflow.
m_timerTimaOverflow = true;
if(m_lastWrite.address == m_addrRegisters + m_regTima) {
// Quirk: If TIMA is written to during the cycle that causes it to
// overflow, the pending reset and interrupt are cancelled.
tima = m_lastWrite.value;
} else {
// TIMA overflow.
m_timerTimaOverflow = true;
}
}
m_ioRegisters->SetByte(m_regTima, tima);
}
void GameBoyInstance::TimerTima() {
@ -86,13 +93,6 @@ namespace Plip::Core::GameBoy {
TimerIncreaseTima();
}
if(m_lastWrite.address == m_addrRegisters + m_regTima && m_timerTimaOverflow) {
// Quirk: If TIMA is written to during the cycle that causes it to
// overflow, the pending reset and interrupt are cancelled.
m_timerTimaOverflow = false;
m_ioRegisters->SetByte(m_regTima, m_lastWrite.value);
}
m_timerTacLast = tac;
// Write TAC back into memory to ensure that only the low 3 bits are set.

8
libplip/Cpu/SharpLr35902/SharpLr35902.cpp

@ -50,7 +50,6 @@ namespace Plip::Cpu {
if(m_isr) {
STACK_PUSH_PC(3);
CYCLE(5) {
m_halt = false;
m_isr = false;
m_reg.pc = 0x40 + (m_isrIdx * 0x8);
m_memory->SetByte(MemInterruptFlag, iFlag ^ (1 << m_isrIdx));
@ -193,7 +192,12 @@ namespace Plip::Cpu {
auto iFlag = m_memory->GetByte(MemInterruptFlag);
iFlag |= irq;
m_memory->SetByte(MemInterruptFlag, iFlag);
m_halt = false;
// Take the CPU out of halt mode if this particular interrupt is
// enabled, even if the IME is disabled.
auto iEnabled = m_memory->GetByte(MemInterruptEnabled);
if(iEnabled & iFlag)
m_halt = false;
}
void SharpLr35902::PerformReset() {

Loading…
Cancel
Save