diff options
| author | 2025-08-11 11:34:18 +0330 | |
|---|---|---|
| committer | 2025-08-11 11:34:18 +0330 | |
| commit | 2fc20ad0b11e60ecfacc653024f2b582acad6e86 (patch) | |
| tree | d7e3f793f32928e40a18c56d00875a5b8e74dc62 /pu2/pu2test.c | |
| parent | vscode theme extension (diff) | |
ir2 initial release!
Diffstat (limited to 'pu2/pu2test.c')
| -rw-r--r-- | pu2/pu2test.c | 227 |
1 files changed, 227 insertions, 0 deletions
diff --git a/pu2/pu2test.c b/pu2/pu2test.c new file mode 100644 index 0000000..93d76aa --- /dev/null +++ b/pu2/pu2test.c @@ -0,0 +1,227 @@ +#define __WRAPPER +#include "pu2.c" +#include <stdio.h> +#include <string.h> + +/* ANSI colors */ +#define CLR_GREEN "\x1b[32m" +#define CLR_RED "\x1b[31m" +#define CLR_YEL "\x1b[33m" +#define CLR_RST "\x1b[0m" + +/* test counters */ +static int total_tests = 0; +static int passed_tests = 0; + +/* helper: load program at pc and set PC (m[7]) */ +void load_prog(int pc, int *prog, int len) { + int i; + /* clear memory (keeps tests isolated) */ + for (i = 0; i < S; ++i) m[ i ] = 0; + for (i = 0; i < len; ++i) m[ pc + i ] = prog[ i ]; + m[ 7 ] = pc; +} + +/* unified expect function (increments counters and prints colored output) */ +void expect_int(const char *name, int got, int want) { + ++total_tests; + if (got == want) { + ++passed_tests; + printf("%sPASS%s: %s == %d\n", CLR_GREEN, CLR_RST, name, want); + } else { + printf("%sFAIL%s: %s == %d (want %d)\n", CLR_RED, CLR_RST, name, got, want); + } +} + +unsigned char outbuf[ 512 ]; + +void zero_Y(void) { + int ii; + for (ii = 0; ii < (1 << 10); ++ii) Y[ ii ] = 0; +} + +void set_outbuf(void) { + memset(outbuf, 0, sizeof outbuf); + O = (char *) outbuf; + zero_Y(); +} + +/* small helper to run a CPU test with a program loaded at 1024 */ +void run_cpu_test(int *prog, int len, void (*setup)(void), const char *name, int (*check)(void)) { + load_prog(1024, prog, len); + if (setup) setup(); + pu2(); + if (check) { + /* check should call expect_int internally or return 1 on success */ + check(); + } + (void) name; /* kept for future extension */ +} + +/* example setups and checks for clarity */ +int check_a_is_42(void) { + expect_int("a (load imm 42)", a, 42); + return 0; +} + +int main(void) { + /* CPU tests */ + { + int prog[] = { 1, 42, 0, 0 }; /* [opcode, imm, halt, dummy] */ + load_prog(1024, prog, sizeof prog / sizeof prog[ 0 ]); + a = b = v = c = 0; + pu2(); + expect_int("a (load imm 42)", a, 42); + } + + { + int prog[] = { 2, 0, 0, 0 }; + load_prog(1024, prog, 4); + /* place value at memory index 500 and set b=500 */ + m[ 500 ] = 99; + b = 500; + a = 0; + pu2(); + expect_int("a (a = m[b])", a, 99); + } + + { + int prog[] = { 3, 0, 0, 0 }; + load_prog(1024, prog, 4); + a = 600; + b = 1234; + pu2(); + expect_int("m[600] (m[a]=b)", m[ 600 ], 1234); + } + + { + int prog[] = { 4, 0, 0, 0 }; + load_prog(1024, prog, 4); + a = 7; + b = 11; + v = 0; + pu2(); + expect_int("a (after swap)", a, 11); + expect_int("b (after swap)", b, 7); + } + + { + int prog[] = { 5, 0, 0, 0 }; + load_prog(1024, prog, 4); + a = 5; + b = 8; + pu2(); + expect_int("a (a += b)", a, 13); + } + + { + int prog[] = { 6, 0, 0, 0 }; + load_prog(1024, prog, 4); + a = 20; + b = 3; + pu2(); + expect_int("a (a -= b)", a, 17); + } + + { + int prog[] = { 7, 0, 0, 0 }; + load_prog(1024, prog, 4); + a = 5; + b = 2; + pu2(); + expect_int("a (5 && 2)", a, 1); + load_prog(1024, prog, 4); + a = 0; + b = 3; + pu2(); + expect_int("a (0 && 3)", a, 0); + } + + { + int prog[] = { 8, 0, 0, 0 }; + load_prog(1024, prog, 4); + a = 1; + b = 1; + pu2(); + expect_int("a (!a)", a, 0); + load_prog(1024, prog, 4); + a = 0; + b = 1; + pu2(); + expect_int("a (!a)", a, 1); + } + + // .. TODO: implement test case for ACC instruction .. + + { + int prog[] = { 1, 9, 4, 0, 3, 0, 0, 0 }; + /* sequence: load imm 9 into a, swap, store b into m[a], halt */ + load_prog(1024, prog, sizeof prog / sizeof prog[ 0 ]); + a = 2; + b = 87; /* after load & swap: a=87, b=9 ; then m[87]=9 */ + pu2(); + expect_int("m[87] (from multi-op)", m[ 87 ], 9); + } + + /* Assembler (as2) tests: use outbuf */ + { + unsigned char *o; + + set_outbuf(); + as2("hlt"); + o = outbuf; + expect_int("hlt:opcode", o[ 0 ], 0); + expect_int("hlt:imm", o[ 1 ], 0); + + set_outbuf(); + as2("imm 42"); + o = outbuf; + expect_int("imm:opcode", o[ 0 ], 1); + expect_int("imm:imm", o[ 1 ], 42); + + set_outbuf(); + as2("add sub"); + o = outbuf; + expect_int("add:opcode", o[ 0 ], 5); + expect_int("add:imm", o[ 1 ], 0); + expect_int("sub:opcode", o[ 2 ], 6); + expect_int("sub:imm", o[ 3 ], 0); + + set_outbuf(); + as2("(0 hlt) @0"); + o = outbuf; + expect_int("macro-hlt:opcode", o[ 0 ], 0); + expect_int("macro-hlt:imm", o[ 1 ], 0); + + set_outbuf(); + as2("(0 imm 7) @0"); + o = outbuf; + expect_int("macro-imm:opcode", o[ 0 ], 1); + expect_int("macro-imm:imm", o[ 1 ], 7); + + set_outbuf(); + as2("(0 imm 3 add) @0"); + o = outbuf; + expect_int("macro-mix:imm-op", o[ 0 ], 1); + expect_int("macro-mix:imm-val", o[ 1 ], 3); + expect_int("macro-mix:add-op", o[ 2 ], 5); + expect_int("macro-mix:add-imm", o[ 3 ], 0); + } + + /* Summary */ + printf( + "\n%sTest summary%s: %d total, %d passed, %d failed\n", + CLR_YEL, + CLR_RST, + total_tests, + passed_tests, + total_tests - passed_tests); + + if (passed_tests == total_tests) { + printf("%sALL TESTS PASSED%s\n", CLR_GREEN, CLR_RST); + return 0; + } else { + printf("%sSOME TESTS FAILED%s\n", CLR_RED, CLR_RST); + return 1; + } +} |
