diff --git a/Makeconf b/Makeconf index 4e62aab..d4b9d3d 100644 --- a/Makeconf +++ b/Makeconf @@ -20,6 +20,7 @@ modules_libemu.a := memory/device.o \ cartridge/cartridge.o \ lcd/lcd.o \ lcd/palette.o \ + input/joypad.o \ modules_vgbc := main.o libemu.a verb_vgbc := link diff --git a/input/joypad.cpp b/input/joypad.cpp new file mode 100644 index 0000000..d9b9e33 --- /dev/null +++ b/input/joypad.cpp @@ -0,0 +1,64 @@ +#include + +Joypad::Joypad(Cpu& cpu) + : cpu(cpu), action_select(false), + direction_select(false), + keystates{false} +{} + +void Joypad::setKeyState(Key k, bool pressed) +{ + bool prevState = keystates[k]; + keystates[k] = pressed; + + if(!pressed || prevState == pressed) + return; + + switch(k) + { + case A: + case B: + case Select: + case Start: + if (action_select) + cpu.signalInterrupt(INT_Joypad); + break; + case Right: + case Left: + case Up: + case Down: + if (direction_select) + cpu.signalInterrupt(INT_Joypad); + break; + } +} + +void Joypad::write8(u16 /*addr*/, u8 data) +{ + action_select = !(data & P1ActionSelect); + direction_select = !(data & P1DirectionSelect); +} + +u8 Joypad::read8(u16 /*addr*/) +{ + u8 val = 0x0F; + + if(action_select) + val &= + (keystates[Start] ? 0 : P1Start) | + (keystates[Select] ? 0 : P1Select) | + (keystates[B] ? 0 : P1B) | + (keystates[A] ? 0 : P1A); + + if(direction_select) + val &= + (keystates[Down] ? 0 : P1Down) | + (keystates[Up] ? 0 : P1Up) | + (keystates[Left] ? 0 : P1Left) | + (keystates[Right] ? 0 : P1Right); + + val |= (action_select ? 0 : P1ActionSelect); + val |= (direction_select ? 0 : P1DirectionSelect); + + return val; +} diff --git a/input/joypad.h b/input/joypad.h new file mode 100644 index 0000000..4c124ea --- /dev/null +++ b/input/joypad.h @@ -0,0 +1,40 @@ +#pragma once + +#include +#include + +class Joypad : public Mem_device { +public: + enum Key { + A,B,Select,Start, + Right,Left,Up,Down, + }; + +private: + Cpu& cpu; + + bool keystates[8]; + bool action_select; + bool direction_select; + + enum P1Reg { + P1ActionSelect = 0b00100000, + P1DirectionSelect = 0b00010000, + P1Down = 0b00001000, + P1Start = 0b00001000, + P1Up = 0b00000100, + P1Select = 0b00000100, + P1Left = 0b00000010, + P1B = 0b00000010, + P1Right = 0b00000001, + P1A = 0b00000001, + }; + +public: + Joypad(Cpu& cpu); + + void setKeyState(Key k, bool pressed); + + virtual void write8(u16 addr, u8 data); + virtual u8 read8(u16 addr); +};