mirror of https://github.com/Washi1337/Emux.git
100 lines
2.7 KiB
C#
100 lines
2.7 KiB
C#
using System;
|
|
using Emux.GameBoy.Cpu;
|
|
|
|
namespace Emux.GameBoy.Timer
|
|
{
|
|
public class GameBoyTimer
|
|
{
|
|
private readonly GameBoy _device;
|
|
public const int DivFrequency = 16384;
|
|
|
|
private int _divClock;
|
|
private int _timerClock;
|
|
|
|
public byte Div;
|
|
public byte Tima;
|
|
public byte Tma;
|
|
public TimerControlFlags Tac;
|
|
|
|
public GameBoyTimer(GameBoy device)
|
|
{
|
|
if (device == null)
|
|
throw new ArgumentNullException(nameof(device));
|
|
_device = device;
|
|
}
|
|
|
|
public int GetTimaFrequency()
|
|
{
|
|
switch (Tac & TimerControlFlags.ClockMask)
|
|
{
|
|
case TimerControlFlags.Clock4096Hz:
|
|
return 4096;
|
|
case TimerControlFlags.Clock16384Hz:
|
|
return 16384;
|
|
case TimerControlFlags.Clock65536Hz:
|
|
return 65536;
|
|
case TimerControlFlags.Clock262144Hz:
|
|
return 262144;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
public void TimerStep(int cycles)
|
|
{
|
|
_divClock += cycles;
|
|
if (_divClock >= DivFrequency)
|
|
{
|
|
_divClock -= DivFrequency;
|
|
Div = (byte) ((Div + 1) % 0xFF);
|
|
}
|
|
|
|
if ((Tac & TimerControlFlags.EnableTimer) == TimerControlFlags.EnableTimer)
|
|
{
|
|
_timerClock += cycles;
|
|
int timaSpeed = GetTimaFrequency();
|
|
if (_timerClock > timaSpeed)
|
|
{
|
|
_timerClock -= timaSpeed;
|
|
Tima = Tma;
|
|
_device.Cpu.Registers.IF |= InterruptFlags.Timer;
|
|
}
|
|
}
|
|
}
|
|
|
|
public byte ReadRegister(ushort address)
|
|
{
|
|
switch (address)
|
|
{
|
|
case 0x04:
|
|
return Div;
|
|
case 0x05:
|
|
return Tima;
|
|
case 0x06:
|
|
return Tma;
|
|
case 0x07:
|
|
return (byte) Tac;
|
|
}
|
|
throw new ArgumentOutOfRangeException(nameof(address));
|
|
}
|
|
|
|
public void WriteRegister(ushort address, byte value)
|
|
{
|
|
switch (address)
|
|
{
|
|
case 0x04:
|
|
Div = 0;
|
|
break;
|
|
case 0x05:
|
|
Tima = value;
|
|
break;
|
|
case 0x06:
|
|
Tma = value;
|
|
break;
|
|
case 0x07:
|
|
Tac = (TimerControlFlags) (value & 0b111);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|