void CalculateWhichCycleTheTimerWillFire() { if (CascadeMode || !Enabled) { FiresOnCycle = 0xFFFFFFFF; return; } UInt32 cycle = (UInt32)(gba.Cpu.Cycles + ((0xFFFF - TimerValue) * timers.TimerPeriods[Freq])); FiresOnCycle = cycle; // Keep track of when we next need to update timers timers.CalculateWhenToNextUpdate(); }
public GbaTimer(Timers timers, GameboyAdvance gba, int timerNumber) { this.timers = timers; this.gba = gba; this.timerNumber = timerNumber; FiresOnCycle = 0xFFFFFFFF; UInt32 baseAddr = (UInt32)(0x4000100 + (timerNumber * 4)); TimerValueRegister r0 = new TimerValueRegister(gba, this, gba.Memory, baseAddr); TimerValueRegister r1 = new TimerValueRegister(gba, this, gba.Memory, baseAddr + 1); TimerValueRegister = new MemoryRegister16(gba.Memory, baseAddr, true, false, r0, r1); ReloadValue = new MemoryRegister16(gba.Memory, baseAddr, false, true); baseAddr = (UInt32)(0x4000102 + (timerNumber * 4)); MemoryRegister8WithSetHook reg = new MemoryRegister8WithSetHook(gba.Memory, baseAddr, true, true); MemoryRegister8 unused = new MemoryRegister8(gba.Memory, baseAddr + 1, true, true); TimerControlRegister = new MemoryRegister16(gba.Memory, baseAddr, true, true, reg, unused); reg.OnSet = (oldValue, newValue) => { CalculateWhichCycleTheTimerWillFire(); timers.CalculateWhenToNextUpdate(); // When a timer is enabled, it reloads it's starting value. When it is disabled it just maintains its current values bool wasEnabled = ((oldValue & 0x80) != 0); bool enabled = ((newValue & 0x80) != 0); if (wasEnabled == false && enabled) { startCycle = gba.Cpu.Cycles; timers.ScheduledUpdate(); TimerValue = ReloadValue.Value; } }; }