From 8df287832a408ed5e37385a3eee840e738884ad8 Mon Sep 17 00:00:00 2001 From: Tiger Date: Fri, 15 Sep 2023 22:14:15 +0200 Subject: [PATCH] Implemented 0x8XY* and fixed value parameter of register get and set functions from short to char since it's only 8 bits --- include/chip8.h | 4 +- include/instruction_handler.h | 5 +++ src/chip8.cpp | 4 +- src/instruction_handler.cpp | 77 +++++++++++++++++++++++++++++++++++ 4 files changed, 86 insertions(+), 4 deletions(-) diff --git a/include/chip8.h b/include/chip8.h index 56fc41f..cfd6a76 100644 --- a/include/chip8.h +++ b/include/chip8.h @@ -86,7 +86,7 @@ public: * @param i The index * @return */ - unsigned short getRegister(unsigned char i); + unsigned char getRegister(unsigned char i); /** * Sets a value in the register (V) @@ -94,6 +94,6 @@ public: * @param i The index of the register to set * @param value The value to be set */ - void setRegister(unsigned char i, unsigned short value); + void setRegister(unsigned char i, unsigned char value); }; #endif //CHIP8_CHIP8_H diff --git a/include/instruction_handler.h b/include/instruction_handler.h index d54da92..dc92c9a 100644 --- a/include/instruction_handler.h +++ b/include/instruction_handler.h @@ -59,6 +59,11 @@ private: * Handles Chip8 instruction 0x7000 */ static void handle7000(Chip8&, Instruction); + + /** + * Handles Chip8 instruction 0x8000 + */ + static void handle8000(Chip8&, Instruction); public: InstructionHandler(); diff --git a/src/chip8.cpp b/src/chip8.cpp index 0f21a5c..593a675 100644 --- a/src/chip8.cpp +++ b/src/chip8.cpp @@ -66,10 +66,10 @@ unsigned short Chip8::getProgramCounter() const { return this->pc; } -unsigned short Chip8::getRegister(unsigned char reg) { +unsigned char Chip8::getRegister(unsigned char reg) { return this->v[reg]; } -void Chip8::setRegister(unsigned char reg, unsigned short value) { +void Chip8::setRegister(unsigned char reg, unsigned char value) { this->v[reg] = value; } diff --git a/src/instruction_handler.cpp b/src/instruction_handler.cpp index 8dac06c..b51e8be 100644 --- a/src/instruction_handler.cpp +++ b/src/instruction_handler.cpp @@ -132,3 +132,80 @@ void InstructionHandler::handle6000(Chip8& chip8, Instruction instruction) { void InstructionHandler::handle7000(Chip8& chip8, Instruction instruction) { chip8.setRegister(instruction.x(), chip8.getRegister(instruction.x()) + instruction.kk()); } + +/** + * Handles the 0x8XY* opcodes (0x8XY0 to 0x8XY7 + 0x8XYE). + * The following opcodes are handled: + * - 0x8XY0 - Stores the value of register V[y] into register V[x] + * - 0x8XY1 - Stores the bitwise OR result of register V[x] and register V[y] into register V[x] + * - 0x8XY2 - Stores the bitwise AND result of register V[x] and register V[y] into register V[x] + * - 0x8XY3 - Stores the bitwise XOR result of register V[x] and register V[y] into register V[x] + * - 0x8XY4 - Sum of register V[y] and register V[x] is checked, if the result is greater than 8 bits, register V[F] is + * set to 1, otherwise 0. Only lowest 8 bits of the result are kept and stored into register V[x] + * - 0x8XY5 - If register V[x] is higher than register V[y], set register V[F] to 1, otherwise 0. + * Store the result of register V[x] - register V[y] into register V[x]. + * - 0x8XY6 - If the least significant bit of register V[x] is 1, set register V[F] to 1, otherwise 0. + * Divide register V[x] by 2 (shift right with 1) and store the result in register V[x]. + * - 0x8XY7 - If register V[y] is higher than register V[x], set register V[F] to 1, otherwise 0. + * Store the result of register V[y] - register V[x] into register V[x]. + * - 0x8XYE - If the most significant bit of register V[x] is 1, set register V[F] to 1, otherwise 0. + * Multiply register V[x] by 2 (shift left with 1) and store the result in register V[x]. + * + * @param chip8 The Chip8 instance + * @param instruction The Instruction instance + */ +void InstructionHandler::handle8000(Chip8& chip8, Instruction instruction) { + switch (instruction.n()) { + case 0: // 0x8XY0 + chip8.setRegister(instruction.x(), chip8.getRegister(instruction.y())); + break; + case 1: // 0x8XY1 + chip8.setRegister(instruction.x(), chip8.getRegister(instruction.x()) | chip8.getRegister(instruction.y())); + break; + case 2: // 0x8XY2 + chip8.setRegister(instruction.x(), chip8.getRegister(instruction.x()) & chip8.getRegister(instruction.y())); + break; + case 3: // 0x8XY3 + chip8.setRegister(instruction.x(), chip8.getRegister(instruction.x()) ^ chip8.getRegister(instruction.y())); + break; + case 4: // 0x8XY4 + { + unsigned short sum = chip8.getRegister(instruction.y()) + chip8.getRegister(instruction.x()); + chip8.setRegister(0xF, sum > 0xFF ? 1 : 0); + chip8.setRegister(instruction.x(), sum & 0xFF); + break; + } + case 5: // 0x8XY5 + { + unsigned short regX = chip8.getRegister(instruction.x()); + unsigned short regY = chip8.getRegister(instruction.y()); + + chip8.setRegister(0xF, regX > regY ? 1 : 0); + chip8.setRegister(instruction.x(), (regX - regY) & 0xFF); + break; + } + case 6: // 0x8XY6 + { + unsigned short regX = chip8.getRegister(instruction.x()); + chip8.setRegister(0xF, regX & 0x1); + chip8.setRegister(instruction.x(), regX >> 1); + break; + } + case 7: // 0x8XY7 + { + unsigned short regX = chip8.getRegister(instruction.x()); + unsigned short regY = chip8.getRegister(instruction.y()); + + chip8.setRegister(0xF, regY > regX ? 1 : 0); + chip8.setRegister(instruction.x(), (regY - regX) & 0xFF); + break; + } + case 0xE: // 0x8XYE + { + unsigned short regX = chip8.getRegister(instruction.x()); + chip8.setRegister(0xF, ((regX >> 7) & 0x1) == 1); + chip8.setRegister(instruction.x(), (regX << 1) & 0xFF); + break; + } + } +}