feat(input): add joypad register and button state handling
This commit is contained in:
1 parent
485e61c8ef
commit
42b357550f
1 file changed
+81
@@ -0,0 +1,81 @@
|
||||
using System.IO;
|
||||
using GameBoy.Cpu;
|
||||
|
||||
namespace GameBoy.Input
|
||||
{
|
||||
public enum JoypadButton
|
||||
{
|
||||
Right = 0,
|
||||
Left = 1,
|
||||
Up = 2,
|
||||
Down = 3,
|
||||
A = 4,
|
||||
B = 5,
|
||||
Select = 6,
|
||||
Start = 7
|
||||
}
|
||||
|
||||
public sealed class Joypad
|
||||
{
|
||||
private readonly InterruptController interrupts;
|
||||
private byte selectLines = 0x30;
|
||||
private byte directions;
|
||||
private byte actions;
|
||||
|
||||
public Joypad(InterruptController interrupts)
|
||||
{
|
||||
this.interrupts = interrupts;
|
||||
}
|
||||
|
||||
public void SetButton(JoypadButton button, bool pressed)
|
||||
{
|
||||
int index = (int)button;
|
||||
byte mask = (byte)(1 << (index & 3));
|
||||
bool isDirection = index < 4;
|
||||
byte before = ReadLines();
|
||||
|
||||
if (isDirection)
|
||||
directions = pressed ? (byte)(directions | mask) : (byte)(directions & ~mask);
|
||||
else
|
||||
actions = pressed ? (byte)(actions | mask) : (byte)(actions & ~mask);
|
||||
|
||||
byte after = ReadLines();
|
||||
if ((before & ~after & 0x0F) != 0)
|
||||
interrupts.Request(Interrupt.Joypad);
|
||||
}
|
||||
|
||||
private byte ReadLines()
|
||||
{
|
||||
byte lines = 0x0F;
|
||||
if ((selectLines & 0x10) == 0)
|
||||
lines &= (byte)~directions;
|
||||
if ((selectLines & 0x20) == 0)
|
||||
lines &= (byte)~actions;
|
||||
return lines;
|
||||
}
|
||||
|
||||
public byte Read()
|
||||
{
|
||||
return (byte)(0xC0 | selectLines | ReadLines());
|
||||
}
|
||||
|
||||
public void Write(byte value)
|
||||
{
|
||||
selectLines = (byte)(value & 0x30);
|
||||
}
|
||||
|
||||
public void SaveState(BinaryWriter writer)
|
||||
{
|
||||
writer.Write(selectLines);
|
||||
writer.Write(directions);
|
||||
writer.Write(actions);
|
||||
}
|
||||
|
||||
public void LoadState(BinaryReader reader)
|
||||
{
|
||||
selectLines = reader.ReadByte();
|
||||
directions = reader.ReadByte();
|
||||
actions = reader.ReadByte();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user