Add special addressing functions for X, Y, N, etc
This commit is contained in:
parent
5d82b8ee40
commit
67b3e37c72
1 changed files with 63 additions and 44 deletions
107
src/emu.cpp
107
src/emu.cpp
|
@ -32,6 +32,31 @@ void EmulatorState::reset() {
|
|||
draw_dirty = true;
|
||||
}
|
||||
|
||||
// reads 0x0NNN
|
||||
uint16_t readAddress(const uint16_t opcode) {
|
||||
return opcode & 0x0fff;
|
||||
}
|
||||
|
||||
// reads 0x00NN
|
||||
uint8_t readNN(const uint16_t opcode) {
|
||||
return opcode & 0x00ff;
|
||||
}
|
||||
|
||||
// reads 0x000N
|
||||
uint8_t readN(const uint16_t opcode) {
|
||||
return (opcode & 0x000f);
|
||||
}
|
||||
|
||||
// reads 0x0X00
|
||||
uint8_t readX(const uint16_t opcode) {
|
||||
return (opcode & 0x0f00) >> 8;
|
||||
}
|
||||
|
||||
// reads 0x00Y0
|
||||
uint8_t readY(const uint16_t opcode) {
|
||||
return (opcode & 0x00f0) >> 4;
|
||||
}
|
||||
|
||||
typedef void (*cpu_func)(const uint16_t opcode);
|
||||
|
||||
void null_func(const uint16_t opcode) {
|
||||
|
@ -91,24 +116,23 @@ void operation0(const uint16_t opcode) {
|
|||
|
||||
// 1NNN
|
||||
void operation1(const uint16_t opcode) {
|
||||
const uint16_t nnn = opcode & 0x0fff;
|
||||
const auto nnn = readAddress(opcode);
|
||||
|
||||
state.PC = nnn;
|
||||
}
|
||||
|
||||
// 2NNN
|
||||
void operation2(const uint16_t opcode) {
|
||||
const uint16_t nnn = opcode & 0x0fff;
|
||||
const auto nnn = readAddress(opcode);
|
||||
|
||||
state.stack[state.stack_pointer] = state.PC;
|
||||
state.stack_pointer++;
|
||||
state.stack[state.stack_pointer++] = state.PC;
|
||||
state.PC = nnn;
|
||||
}
|
||||
|
||||
// 3XNN
|
||||
void operation3(const uint16_t opcode) {
|
||||
const uint8_t x = (opcode & 0x0f00) >> 8;
|
||||
const uint8_t nn = opcode & 0x00ff;
|
||||
const auto x = readX(opcode);
|
||||
const auto nn = readNN(opcode);
|
||||
|
||||
if(state.v[x] == nn)
|
||||
state.PC += 4;
|
||||
|
@ -118,8 +142,8 @@ void operation3(const uint16_t opcode) {
|
|||
|
||||
// 4XNN
|
||||
void operation4(const uint16_t opcode) {
|
||||
const uint8_t x = (opcode & 0x0f00) >> 8;
|
||||
const uint8_t nn = opcode & 0x00ff;
|
||||
const auto x = readX(opcode);
|
||||
const auto nn = readNN(opcode);
|
||||
|
||||
if(state.v[x] != nn)
|
||||
state.PC += 4;
|
||||
|
@ -129,28 +153,26 @@ void operation4(const uint16_t opcode) {
|
|||
|
||||
// 6XNN
|
||||
void operation6(const uint16_t opcode) {
|
||||
const uint8_t x = (opcode & 0x0f00) >> 8;
|
||||
const uint8_t nn = opcode & 0x00ff;
|
||||
const auto x = readX(opcode);
|
||||
const auto nn = readNN(opcode);
|
||||
|
||||
state.v[x] = nn;
|
||||
|
||||
state.PC += 2;
|
||||
}
|
||||
|
||||
// &XNN
|
||||
void operation7(const uint16_t opcode) {
|
||||
const uint8_t x = (opcode & 0x0f00) >> 8;
|
||||
const uint8_t nn = opcode & 0x00ff;
|
||||
const auto x = readX(opcode);
|
||||
const auto nn = readNN(opcode);
|
||||
|
||||
state.v[x] += nn;
|
||||
|
||||
state.PC += 2;
|
||||
}
|
||||
|
||||
// 8XY0
|
||||
void op8_func0(const uint16_t opcode) {
|
||||
const uint8_t x = (opcode & 0x0f00) >> 8;
|
||||
const uint8_t y = (opcode & 0x00f0) >> 4;
|
||||
const auto x = readX(opcode);
|
||||
const auto y = readY(opcode);
|
||||
|
||||
state.v[x] = state.v[y];
|
||||
state.PC += 2;
|
||||
|
@ -158,8 +180,8 @@ void op8_func0(const uint16_t opcode) {
|
|||
|
||||
// 8XY1
|
||||
void op8_func2(const uint16_t opcode) {
|
||||
const uint8_t x = (opcode & 0x0f00) >> 8;
|
||||
const uint8_t y = (opcode & 0x00f0) >> 4;
|
||||
const auto x = readX(opcode);
|
||||
const auto y = readY(opcode);
|
||||
|
||||
state.v[x] = state.v[x] & state.v[y];
|
||||
state.PC += 2;
|
||||
|
@ -167,8 +189,8 @@ void op8_func2(const uint16_t opcode) {
|
|||
|
||||
// 8XY3
|
||||
void op8_func3(const uint16_t opcode) {
|
||||
const uint8_t x = (opcode & 0x0f00) >> 8;
|
||||
const uint8_t y = (opcode & 0x00f0) >> 4;
|
||||
const auto x = readX(opcode);
|
||||
const auto y = readY(opcode);
|
||||
|
||||
state.v[x] = state.v[x] ^ state.v[y];
|
||||
state.PC += 2;
|
||||
|
@ -176,8 +198,8 @@ void op8_func3(const uint16_t opcode) {
|
|||
|
||||
// 8XY4
|
||||
void op8_func4(const uint16_t opcode) {
|
||||
const uint8_t x = (opcode & 0x0f00) >> 8;
|
||||
const uint8_t y = (opcode & 0x00f0) >> 4;
|
||||
const auto x = readX(opcode);
|
||||
const auto y = readY(opcode);
|
||||
|
||||
// TODO: implement tests
|
||||
if(state.v[y] < (0xFF - state.v[x]))
|
||||
|
@ -191,8 +213,8 @@ void op8_func4(const uint16_t opcode) {
|
|||
|
||||
// 8XY5
|
||||
void op8_func5(const uint16_t opcode) {
|
||||
const uint8_t x = (opcode & 0x0f00) >> 8;
|
||||
const uint8_t y = (opcode & 0x00f0) >> 4;
|
||||
const auto x = readX(opcode);
|
||||
const auto y = readY(opcode);
|
||||
|
||||
// TODO: implement tests
|
||||
if(state.v[y] > state.v[x])
|
||||
|
@ -206,7 +228,7 @@ void op8_func5(const uint16_t opcode) {
|
|||
|
||||
// 8XY6
|
||||
void op8_func6(const uint16_t opcode) {
|
||||
const uint8_t x = (opcode & 0x0f00) >> 8;
|
||||
const auto x = readX(opcode);
|
||||
|
||||
state.v[0xF] = (state.v[x] & 1);
|
||||
state.v[x] >>= 1;
|
||||
|
@ -230,8 +252,8 @@ void operation8(const uint16_t opcode) {
|
|||
|
||||
// 9XY0
|
||||
void operation9(const uint16_t opcode) {
|
||||
const uint8_t x = (opcode & 0x0f00) >> 8;
|
||||
const uint8_t y = (opcode & 0x00f0) >> 4;
|
||||
const auto x = readX(opcode);
|
||||
const auto y = readY(opcode);
|
||||
|
||||
if(state.v[x] != state.v[y])
|
||||
state.PC += 4;
|
||||
|
@ -241,7 +263,7 @@ void operation9(const uint16_t opcode) {
|
|||
|
||||
// ANNN
|
||||
void operationA(const uint16_t opcode) {
|
||||
const uint16_t nnn = opcode & 0x0fff;
|
||||
const auto nnn = readAddress(opcode);
|
||||
|
||||
state.I = nnn;
|
||||
state.PC += 2;
|
||||
|
@ -249,8 +271,8 @@ void operationA(const uint16_t opcode) {
|
|||
|
||||
// CXNN
|
||||
void operationC(const uint16_t opcode) {
|
||||
const uint8_t x = (opcode & 0x0f00) >> 8;
|
||||
const uint8_t nn = opcode & 0x00ff;
|
||||
const auto x = readX(opcode);
|
||||
const auto nn = readNN(opcode);
|
||||
|
||||
srand(time(nullptr));
|
||||
state.v[x] = (rand() % 0xFF) & nn;
|
||||
|
@ -259,9 +281,9 @@ void operationC(const uint16_t opcode) {
|
|||
|
||||
// DXYN
|
||||
void operationD(const uint16_t opcode) {
|
||||
const uint8_t x = (opcode & 0x0f00) >> 8;
|
||||
const uint8_t y = (opcode & 0x00f0) >> 4;
|
||||
const uint8_t n = opcode & 0x000f;
|
||||
const auto x = readX(opcode);
|
||||
const auto y = readY(opcode);
|
||||
const auto n = readN(opcode);
|
||||
|
||||
const uint8_t x_pos = state.v[x];
|
||||
const uint8_t y_pos = state.v[y];
|
||||
|
@ -295,7 +317,7 @@ void operationD(const uint16_t opcode) {
|
|||
|
||||
// EX9E & EXA1
|
||||
void operationE(const uint16_t opcode) {
|
||||
const uint8_t x = (opcode & 0x0f00) >> 8;
|
||||
const auto x = readX(opcode);
|
||||
|
||||
switch(opcode & 0x00ff) {
|
||||
case 0x9E:
|
||||
|
@ -319,7 +341,7 @@ void operationE(const uint16_t opcode) {
|
|||
|
||||
// FX07
|
||||
void opF_func7(const uint16_t opcode) {
|
||||
const uint8_t x = (opcode & 0x0f00) >> 8;
|
||||
const auto x = readX(opcode);
|
||||
|
||||
state.v[x] = state.delay_timer;
|
||||
|
||||
|
@ -328,7 +350,7 @@ void opF_func7(const uint16_t opcode) {
|
|||
|
||||
// FX0A
|
||||
void opF_funcA(const uint16_t opcode) {
|
||||
const uint8_t x = (opcode & 0x0f00) >> 8;
|
||||
const auto x = readX(opcode);
|
||||
|
||||
for(int i = 0; i < 16; i++) {
|
||||
if(state.keys[i] != 0) {
|
||||
|
@ -340,7 +362,7 @@ void opF_funcA(const uint16_t opcode) {
|
|||
|
||||
// FX55/FX65 & FX15
|
||||
void opF_func5(const uint16_t opcode) {
|
||||
const uint8_t x = (opcode & 0x0f00) >> 8;
|
||||
const auto x = readX(opcode);
|
||||
|
||||
switch((opcode & 0x00F0) >> 4) {
|
||||
case 0x6:
|
||||
|
@ -377,25 +399,23 @@ void opF_func5(const uint16_t opcode) {
|
|||
|
||||
// FX18
|
||||
void opF_func8(const uint16_t opcode) {
|
||||
const uint8_t x = (opcode & 0x0f00) >> 8;
|
||||
const auto x = readX(opcode);
|
||||
|
||||
state.sound_timer = state.v[x];
|
||||
|
||||
state.PC += 2;
|
||||
}
|
||||
|
||||
// FX29
|
||||
void opF_func9(const uint16_t opcode) {
|
||||
const uint8_t x = (opcode & 0x0f00) >> 8;
|
||||
const auto x = readX(opcode);
|
||||
|
||||
state.I = state.v[x] * 0x5;
|
||||
|
||||
state.PC += 2;
|
||||
}
|
||||
|
||||
// FX1E
|
||||
void opF_funcE(const uint16_t opcode) {
|
||||
const uint8_t x = (opcode & 0x0f00) >> 8;
|
||||
const auto x = readX(opcode);
|
||||
|
||||
if((state.I + state.v[x]) > 0xFFF)
|
||||
state.v[15] = 1;
|
||||
|
@ -403,13 +423,12 @@ void opF_funcE(const uint16_t opcode) {
|
|||
state.v[15] = 0;
|
||||
|
||||
state.I += state.v[x];
|
||||
|
||||
state.PC += 2;
|
||||
}
|
||||
|
||||
// FX33
|
||||
void opF_func3(const uint16_t opcode) {
|
||||
const uint8_t x = (opcode & 0x0f00) >> 8;
|
||||
const auto x = readX(opcode);
|
||||
|
||||
int decimal_rep = state.v[x];
|
||||
|
||||
|
|
Reference in a new issue