diff --git a/emulator/src/components.c b/emulator/src/components.c index 5a90d37..788746a 100644 --- a/emulator/src/components.c +++ b/emulator/src/components.c @@ -34,7 +34,7 @@ static word_t rotl(word_t a, word_t n) { return (a << n) | (a >> (sizeof(word_t) */ word_t alu(ALUOperation op, word_t a, word_t b, uint8_t *flags) { - word_t result; + word_t result = 0; *flags = 0; switch (op) { @@ -61,7 +61,10 @@ word_t alu(ALUOperation op, word_t a, word_t b, uint8_t *flags) { result = a * b; break; case ALU_DIV: - result = a / b; + if (b == 0) + result = 0; + else + result = a / b; break; case ALU_LSL: result = a << b; @@ -76,12 +79,11 @@ word_t alu(ALUOperation op, word_t a, word_t b, uint8_t *flags) { result = rotr(a, b); break; case ALU_NOOP: - result = 0; break; } // TODO implement flags for all operations - if (result == 0) *flags |= (0xFF & FLAG_ZERO); + if (result == 0 && op != ALU_NOOP) *flags |= (0xFF & FLAG_ZERO); if (result & 0x8000) *flags |= (0xFF & FLAG_NEGATIVE); return result; diff --git a/emulator/tests/main.c b/emulator/tests/main.c index 09744ad..5f8932e 100644 --- a/emulator/tests/main.c +++ b/emulator/tests/main.c @@ -1,8 +1,10 @@ #include "../src/components.h" #include +#include #include static void test_alu_add(void) { + // TODO revisit when carry and overflow are added uint8_t flags; assert(alu(ALU_ADD, 1, 3, &flags) == 4); @@ -16,6 +18,20 @@ static void test_alu_add(void) { assert(flags & FLAG_NEGATIVE); } +static void test_alu_sub(void) { + // TODO revisit when carry and overflow are added + uint8_t flags; + + assert(alu(ALU_SUB, 5, 1, &flags) == 4); + assert(flags == 0); + + assert(alu(ALU_SUB, 1, 1, &flags) == 0); + assert(flags & FLAG_ZERO); + + assert(alu(ALU_SUB, 1, 2, &flags) == 0xFFFF); + assert(flags & FLAG_NEGATIVE); +} + static void test_alu_and(void) { uint8_t flags; @@ -69,6 +85,7 @@ static void test_alu_rb(void) { } static void test_alu_mul(void) { + // TODO revisit when carry and overflow are added uint8_t flags; assert(alu(ALU_MUL, 5, 5, &flags) == 25); @@ -84,6 +101,23 @@ static void test_alu_mul(void) { assert(flags == 0); } +static void test_alu_div(void) { + // TODO revisit when carry and overflow are added + uint8_t flags; + + assert(alu(ALU_DIV, 5, 5, &flags) == 1); + assert(flags == 0); + + assert(alu(ALU_DIV, 0, 10, &flags) == 0); + assert(flags & FLAG_ZERO); + + assert(alu(ALU_DIV, 1, 0, &flags) == 0); + assert(flags & FLAG_ZERO); + + assert(alu(ALU_DIV, 0xFFFF, 13107, &flags) == 5); + assert(flags == 0); +} + static void test_alu_lsl(void) { uint8_t flags; @@ -97,18 +131,79 @@ static void test_alu_lsl(void) { assert(flags & FLAG_NEGATIVE); } +static void test_alu_lsr(void) { + uint8_t flags; + + assert(alu(ALU_LSR, 2, 1, &flags) == 1); + assert(flags == 0); + + assert(alu(ALU_LSR, 0x1, 1, &flags) == 0); + assert(flags & FLAG_ZERO); + + assert(alu(ALU_LSR, 0x8000, 2, &flags) == 0x2000); + assert(flags == 0); +} + +static void test_alu_noop(void) { + uint8_t flags; + + assert(alu(ALU_NOOP, 7, 3, &flags) == 0); + assert(flags == 0); + + assert(alu(ALU_NOOP, 4, 0, &flags) == 0); + assert(flags == 0); + + assert(alu(ALU_NOOP, 18, 10002, &flags) == 0); + assert(flags == 0); +} + +static void test_alu_rol(void) { + uint8_t flags; + + assert(alu(ALU_ROL, 0x8000, 2, &flags) == 0x0002); + assert(flags == 0); + + assert(alu(ALU_ROL, 0x4000, 1, &flags) == 0x8000); + assert(flags & FLAG_NEGATIVE); + + assert(alu(ALU_ROL, 0x4000, 2, &flags) == 0x0001); + assert(flags == 0); + + assert(alu(ALU_ROL, 0x4010, 1, &flags) == 0x8020); + assert(flags & FLAG_NEGATIVE); +} + +static void test_alu_ror(void) { + uint8_t flags; + + assert(alu(ALU_ROR, 0x8000, 2, &flags) == 0x2000); + assert(flags == 0); + + assert(alu(ALU_ROR, 0x0001, 1, &flags) == 0x8000); + assert(flags & FLAG_NEGATIVE); + + assert(alu(ALU_ROR, 0x4010, 1, &flags) == 0x2008); + assert(flags == 0); +} + int main(void) { puts("Running tests..."); /* ALU TESTS */ test_alu_add(); + test_alu_sub(); test_alu_and(); test_alu_or(); test_alu_not(); test_alu_rb(); test_alu_mul(); + test_alu_div(); test_alu_lsl(); + test_alu_lsr(); + test_alu_rol(); + test_alu_ror(); + test_alu_noop(); return 0; }