Compare commits
1 Commits
19506dd218
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| bba46296b1 |
@@ -5,5 +5,5 @@ SET(CMAKE_BUILD_TYPE Debug)
|
|||||||
add_subdirectory(submodules/sdl2)
|
add_subdirectory(submodules/sdl2)
|
||||||
|
|
||||||
SET(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
SET(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
add_executable(chocochip8 main.cpp Interpreter.cpp DisplaySDL.cpp BuzzerSDL.cpp CountdownTimerSDL.cpp)
|
add_executable(chocochip8 main.cpp Interpreter.cpp DisplaySDL.cpp BuzzerSDL.cpp CountdownTimerSDL.cpp KeypadSDL.cpp)
|
||||||
target_link_libraries(chocochip8 SDL2::SDL2-static)
|
target_link_libraries(chocochip8 SDL2::SDL2-static)
|
||||||
|
|||||||
@@ -139,13 +139,37 @@ void Interpreter::tick() {
|
|||||||
case 0xD000: // DXYN - draw
|
case 0xD000: // DXYN - draw
|
||||||
executeDraw(mvReg[iRegDst], mvReg[iRegSrc], opcode);
|
executeDraw(mvReg[iRegDst], mvReg[iRegSrc], opcode);
|
||||||
break;
|
break;
|
||||||
case 0xE000: // EX9E, EXA1 - keypad access
|
case 0xE000: // keypad access
|
||||||
|
switch(inst & 0xF0FF) {
|
||||||
|
case 0xE09E: // EX9E - skip if key pressed
|
||||||
|
if(mrKeypad.isKeyPressed(mvReg[iRegDst])) {
|
||||||
|
mvSpecialReg[SR_PC] += 2;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0xE0A1: // EXA1 - skip if key not pressed
|
||||||
|
if(!mrKeypad.isKeyPressed(mvReg[iRegDst])) {
|
||||||
|
mvSpecialReg[SR_PC] += 2;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw std::invalid_argument("not implemented");
|
||||||
|
break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 0xF000: // several unique instructions
|
case 0xF000: // several unique instructions
|
||||||
switch(inst & 0xF0FF) {
|
switch(inst & 0xF0FF) {
|
||||||
case 0xF007: // FX07 - read timer register
|
case 0xF007: // FX07 - read timer register
|
||||||
mvReg[iRegDst] = mrDelayTimer.get();
|
mvReg[iRegDst] = mrDelayTimer.get();
|
||||||
break;
|
break;
|
||||||
|
case 0xF00A: // FX0A - wait for a keypress
|
||||||
|
mvSpecialReg[SR_PC] -= 2;
|
||||||
|
for(int i = KEY_0; i < KEY_0 + KEY_COUNT; i++) {
|
||||||
|
if(mrKeypad.isKeyPressed(i)) {
|
||||||
|
mvSpecialReg[SR_PC] += 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 0xF015: // FX15 - set timer register
|
case 0xF015: // FX15 - set timer register
|
||||||
mrDelayTimer.set(mvReg[iRegDst]);
|
mrDelayTimer.set(mvReg[iRegDst]);
|
||||||
break;
|
break;
|
||||||
|
|||||||
36
KeypadSDL.cpp
Normal file
36
KeypadSDL.cpp
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#include "KeypadSDL.hpp"
|
||||||
|
|
||||||
|
bool KeypadSDL::isKeyPressed(int key) const {
|
||||||
|
return mvKeyDown.at(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeypadSDL::processEvent(SDL_Event &e) {
|
||||||
|
auto keymap = [](int sdlKeyCode) -> int {
|
||||||
|
switch(sdlKeyCode) {
|
||||||
|
case SDLK_1: return chocochip8::KEY_1;
|
||||||
|
case SDLK_2: return chocochip8::KEY_2;
|
||||||
|
case SDLK_3: return chocochip8::KEY_3;
|
||||||
|
case SDLK_4: return chocochip8::KEY_C;
|
||||||
|
case SDLK_q: return chocochip8::KEY_4;
|
||||||
|
case SDLK_w: return chocochip8::KEY_5;
|
||||||
|
case SDLK_e: return chocochip8::KEY_6;
|
||||||
|
case SDLK_r: return chocochip8::KEY_D;
|
||||||
|
case SDLK_a: return chocochip8::KEY_7;
|
||||||
|
case SDLK_s: return chocochip8::KEY_8;
|
||||||
|
case SDLK_d: return chocochip8::KEY_9;
|
||||||
|
case SDLK_f: return chocochip8::KEY_E;
|
||||||
|
case SDLK_z: return chocochip8::KEY_A;
|
||||||
|
case SDLK_x: return chocochip8::KEY_0;
|
||||||
|
case SDLK_c: return chocochip8::KEY_B;
|
||||||
|
case SDLK_v: return chocochip8::KEY_F;
|
||||||
|
default : return -1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if(e.type == SDL_KEYUP || e.type == SDL_KEYDOWN) {
|
||||||
|
int k = keymap(e.key.keysym.sym);
|
||||||
|
if(k != -1) {
|
||||||
|
mvKeyDown[k] = (e.type == SDL_KEYDOWN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
12
KeypadSDL.hpp
Normal file
12
KeypadSDL.hpp
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#include "Peripherals.hpp"
|
||||||
|
|
||||||
|
#include <SDL2/SDL_events.h>
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
class KeypadSDL : public chocochip8::Keypad {
|
||||||
|
public:
|
||||||
|
bool isKeyPressed(int key) const override;
|
||||||
|
void processEvent(SDL_Event &e);
|
||||||
|
private:
|
||||||
|
std::array<bool, chocochip8::KEY_COUNT> mvKeyDown;
|
||||||
|
};
|
||||||
@@ -8,11 +8,12 @@ namespace chocochip8 {
|
|||||||
constexpr size_t gcHeight = 64;
|
constexpr size_t gcHeight = 64;
|
||||||
using Scanline = std::bitset<gcWidth>;
|
using Scanline = std::bitset<gcWidth>;
|
||||||
|
|
||||||
enum class Key {
|
enum {
|
||||||
KEY_0, KEY_1, KEY_2, KEY_3,
|
KEY_0, KEY_1, KEY_2, KEY_3,
|
||||||
KEY_4, KEY_5, KEY_6, KEY_7,
|
KEY_4, KEY_5, KEY_6, KEY_7,
|
||||||
KEY_8, KEY_9, KEY_A, KEY_B,
|
KEY_8, KEY_9, KEY_A, KEY_B,
|
||||||
KEY_C, KEY_D, KEY_E, KEY_F
|
KEY_C, KEY_D, KEY_E, KEY_F,
|
||||||
|
KEY_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
class Display {
|
class Display {
|
||||||
@@ -32,7 +33,7 @@ namespace chocochip8 {
|
|||||||
class Keypad {
|
class Keypad {
|
||||||
public:
|
public:
|
||||||
virtual ~Keypad() = default;
|
virtual ~Keypad() = default;
|
||||||
virtual bool isKeyPressed(Key key) = 0;
|
virtual bool isKeyPressed(int key) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CountdownTimer {
|
class CountdownTimer {
|
||||||
|
|||||||
13
main.cpp
13
main.cpp
@@ -8,9 +8,8 @@
|
|||||||
#include "BuzzerSDL.hpp"
|
#include "BuzzerSDL.hpp"
|
||||||
#include "CountdownTimerSDL.hpp"
|
#include "CountdownTimerSDL.hpp"
|
||||||
#include "DisplaySDL.hpp"
|
#include "DisplaySDL.hpp"
|
||||||
|
#include "KeypadSDL.hpp"
|
||||||
#include "Interpreter.hpp"
|
#include "Interpreter.hpp"
|
||||||
#include "Peripherals.hpp"
|
|
||||||
#include "SDL2/SDL_events.h"
|
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
if (SDL_Init(SDL_INIT_EVERYTHING) < 0) {
|
if (SDL_Init(SDL_INIT_EVERYTHING) < 0) {
|
||||||
@@ -18,17 +17,13 @@ int main(int argc, char* argv[]) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
class TestKeypad : public chocochip8::Keypad {
|
|
||||||
bool isKeyPressed(chocochip8::Key) override { return false; }
|
|
||||||
};
|
|
||||||
|
|
||||||
BuzzerSDL buzzer(440);
|
BuzzerSDL buzzer(440);
|
||||||
int N = 4;
|
int N = 4;
|
||||||
DisplaySDL display(128*N, 64*N);
|
DisplaySDL display(128*N, 64*N);
|
||||||
TestKeypad keypad;
|
KeypadSDL keypad;
|
||||||
CountdownTimerSDL delayTimer(60);
|
CountdownTimerSDL delayTimer(60);
|
||||||
CountdownTimerSDL soundTimer(60);
|
CountdownTimerSDL soundTimer(60);
|
||||||
CountdownTimerSDL displayTimer(20);
|
CountdownTimerSDL displayTimer(60);
|
||||||
chocochip8::Interpreter chip8(display, buzzer, keypad, delayTimer, soundTimer);
|
chocochip8::Interpreter chip8(display, buzzer, keypad, delayTimer, soundTimer);
|
||||||
|
|
||||||
auto rom = std::vector<char>();
|
auto rom = std::vector<char>();
|
||||||
@@ -46,6 +41,8 @@ int main(int argc, char* argv[]) {
|
|||||||
while(SDL_PollEvent(&event)) {
|
while(SDL_PollEvent(&event)) {
|
||||||
if(event.type == SDL_QUIT) {
|
if(event.type == SDL_QUIT) {
|
||||||
done = true;
|
done = true;
|
||||||
|
} else {
|
||||||
|
keypad.processEvent(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
chip8.tick();
|
chip8.tick();
|
||||||
|
|||||||
Reference in New Issue
Block a user