aboutsummaryrefslogtreecommitdiff
path: root/putest.c
diff options
context:
space:
mode:
authorGravatar Moon Flower <moon@coffin.ir> 2025-08-06 22:26:40 +0330
committerGravatar Moon Flower <moon@coffin.ir> 2025-08-06 22:26:40 +0330
commitf693a74d6e08c65fcf621ad049e103e761f01064 (patch)
treef3ec25b54143c9c5f62c1026bcd70c8304cdc80b /putest.c
wowie
Diffstat (limited to 'putest.c')
-rw-r--r--putest.c325
1 files changed, 325 insertions, 0 deletions
diff --git a/putest.c b/putest.c
new file mode 100644
index 0000000..d223a42
--- /dev/null
+++ b/putest.c
@@ -0,0 +1,325 @@
+#include <stdio.h>
+#include <string.h>
+
+#define __WRAPPER
+#include "pu.c"
+
+void reset() {
+ memset(m, 0, sizeof(m));
+ a = 0;
+ c = 0;
+}
+
+void test_opcode_0() {
+ printf("Testing opcode 0 (hlt)... ");
+ reset();
+ m[0] = 0; // hlt instruction
+ m[7] = 0; // pc starts at 0
+ pu();
+ printf("PASS\n");
+}
+
+void test_opcode_1() {
+ printf("Testing opcode 1 (const in r0)... ");
+ reset();
+ m[0] = 1; // const instruction
+ m[1] = 42; // constant value
+ m[2] = 0; // hlt
+ m[7] = 0; // pc starts at 0
+ pu();
+ printf("r0=%d (expected 42): %s\n", m[0], m[0] == 42 ? "PASS" : "FAIL");
+}
+
+void test_opcode_2() {
+ printf("Testing opcode 4 (r0 in r2 if acc non-zero)... ");
+ reset();
+ m[0] = 123; // r0 = 123
+ a = 1; // acc = 1 (non-zero)
+ m[10] = 4; // opcode 4
+ m[11] = 0; // hlt
+ m[7] = 10; // pc starts at 10
+ pu();
+ printf("r2=%d (expected 123): %s\n", m[2], m[2] == 123 ? "PASS" : "FAIL");
+}
+
+void test_opcode_2_zero_acc() {
+ printf("Testing opcode 4 with zero acc (should not store)... ");
+ reset();
+ m[0] = 123; // r0 = 123
+ m[2] = 999; // r2 = 999 initially
+ a = 0; // acc = 0
+ m[10] = 4; // opcode 4
+ m[11] = 0; // hlt
+ m[7] = 10; // pc starts at 10
+ pu();
+ printf("r2=%d (expected 999): %s\n", m[2], m[2] == 999 ? "PASS" : "FAIL");
+}
+
+void test_opcode_10() {
+ printf("Testing opcode 12 (r2 in r0)... ");
+ reset();
+ m[2] = 456; // r2 = 456
+ m[10] = 12; // opcode 12
+ m[11] = 0; // hlt
+ m[7] = 10; // pc starts at 10
+ pu();
+ printf("r0=%d (expected 456): %s\n", m[0], m[0] == 456 ? "PASS" : "FAIL");
+}
+
+void test_opcode_18() {
+ printf("Testing opcode 18 (r0 in m[r1])... ");
+ reset();
+ m[0] = 789; // r0 = 789
+ m[1] = 100; // r1 = 100 (address)
+ m[10] = 18; // opcode 18
+ m[11] = 0; // hlt
+ m[7] = 10; // pc starts at 10
+ pu();
+ printf("m[100]=%d (expected 789): %s\n", m[100], m[100] == 789 ? "PASS" : "FAIL");
+}
+
+void test_opcode_19() {
+ printf("Testing opcode 19 (acc in r0)... ");
+ reset();
+ a = 555; // acc = 555
+ m[10] = 19; // opcode 19
+ m[11] = 0; // hlt
+ m[7] = 10; // pc starts at 10
+ pu();
+ printf("r0=%d (expected 555): %s\n", m[0], m[0] == 555 ? "PASS" : "FAIL");
+}
+
+void test_opcode_20() {
+ printf("Testing opcode 20 (acc += r0)... ");
+ reset();
+ a = 10; // acc = 10
+ m[0] = 5; // r0 = 5
+ m[10] = 20; // opcode 20
+ m[11] = 0; // hlt
+ m[7] = 10; // pc starts at 10
+ pu();
+ printf("acc=%d (expected 15): %s\n", a, a == 15 ? "PASS" : "FAIL");
+}
+
+void test_opcode_21() {
+ printf("Testing opcode 21 (acc -= r0)... ");
+ reset();
+ a = 20; // acc = 20
+ m[0] = 7; // r0 = 7
+ m[10] = 21; // opcode 21
+ m[11] = 0; // hlt
+ m[7] = 10; // pc starts at 10
+ pu();
+ printf("acc=%d (expected 13): %s\n", a, a == 13 ? "PASS" : "FAIL");
+}
+
+void test_opcode_22() {
+ printf("Testing opcode 22 (acc = !acc)... ");
+ reset();
+ a = 5; // acc = 5 (non-zero)
+ m[10] = 22; // opcode 22
+ m[11] = 0; // hlt
+ m[7] = 10; // pc starts at 10
+ pu();
+ printf("acc=%d (expected 0): %s\n", a, a == 0 ? "PASS" : "FAIL");
+}
+
+void test_opcode_23() {
+ printf("Testing opcode 23 (acc = 0)... ");
+ reset();
+ a = 999; // acc = 999
+ m[10] = 23; // opcode 23
+ m[11] = 0; // hlt
+ m[7] = 10; // pc starts at 10
+ pu();
+ printf("acc=%d (expected 0): %s\n", a, a == 0 ? "PASS" : "FAIL");
+}
+
+// Helper to compare output array with expected values
+int check_output(int *O, int *expected, int len, const char *test_name) {
+ int i;
+ for (i = 0; i < len; i++) {
+ if (O[i] != expected[i]) {
+ printf("%s: output[%d]=%d (expected %d): FAIL\n", test_name, i, O[i], expected[i]);
+ return 0;
+ }
+ }
+ printf("%s: PASS\n", test_name);
+ return 1;
+}
+
+// Reset output array
+void reset_output(int *O, int size) {
+ memset(O, 0, size * sizeof(int));
+}
+
+void test_hlt() {
+ printf("Testing hlt (opcode 0)... ");
+ int O[10];
+ reset_output(O, 10);
+ int expected[] = {0};
+ int ret = as("hlt", O);
+ printf("return=%d (expected 0): %s\n", ret, ret == 0 ? check_output(O, expected, 1, "hlt") ? "PASS" : "FAIL" : "FAIL");
+}
+
+void test_con() {
+ printf("Testing con 123 (opcode 1, 123)... ");
+ int O[10];
+ reset_output(O, 10);
+ int expected[] = {1, 123};
+ int ret = as("con 123", O);
+ printf("return=%d (expected 0): %s\n", ret, ret == 0 ? check_output(O, expected, 2, "con") ? "PASS" : "FAIL" : "FAIL");
+}
+
+void test_ar1() {
+ printf("Testing ar1 (opcode 2)... ");
+ int O[10];
+ reset_output(O, 10);
+ int expected[] = {2};
+ int ret = as("ar1", O);
+ printf("return=%d (expected 0): %s\n", ret, ret == 0 ? check_output(O, expected, 1, "ar1") ? "PASS" : "FAIL" : "FAIL");
+}
+
+void test_ar8() {
+ printf("Testing ar8 (opcode 9)... ");
+ int O[10];
+ reset_output(O, 10);
+ int expected[] = {9};
+ int ret = as("ar8", O);
+ printf("return=%d (expected 0): %s\n", ret, ret == 0 ? check_output(O, expected, 1, "ar8") ? "PASS" : "FAIL" : "FAIL");
+}
+
+void test_r1a() {
+ printf("Testing r1a (opcode 10)... ");
+ int O[10];
+ reset_output(O, 10);
+ int expected[] = {10};
+ int ret = as("r1a", O);
+ printf("return=%d (expected 0): %s\n", ret, ret == 0 ? check_output(O, expected, 1, "r1a") ? "PASS" : "FAIL" : "FAIL");
+}
+
+void test_r8a() {
+ printf("Testing r8a (opcode 17)... ");
+ int O[10];
+ reset_output(O, 10);
+ int expected[] = {17};
+ int ret = as("r8a", O);
+ printf("return=%d (expected 0): %s\n", ret, ret == 0 ? check_output(O, expected, 1, "r8a") ? "PASS" : "FAIL" : "FAIL");
+}
+
+void test_mem() {
+ printf("Testing mem (opcode 18)... ");
+ int O[10];
+ reset_output(O, 10);
+ int expected[] = {18};
+ int ret = as("mem", O);
+ printf("return=%d (expected 0): %s\n", ret, ret == 0 ? check_output(O, expected, 1, "mem") ? "PASS" : "FAIL" : "FAIL");
+}
+
+void test_aca() {
+ printf("Testing aca (opcode 19)... ");
+ int O[10];
+ reset_output(O, 10);
+ int expected[] = {19};
+ int ret = as("aca", O);
+ printf("return=%d (expected 0): %s\n", ret, ret == 0 ? check_output(O, expected, 1, "aca") ? "PASS" : "FAIL" : "FAIL");
+}
+
+void test_add() {
+ printf("Testing add (opcode 20)... ");
+ int O[10];
+ reset_output(O, 10);
+ int expected[] = {20};
+ int ret = as("add", O);
+ printf("return=%d (expected 0): %s\n", ret, ret == 0 ? check_output(O, expected, 1, "add") ? "PASS" : "FAIL" : "FAIL");
+}
+
+void test_sub() {
+ printf("Testing sub (opcode 21)... ");
+ int O[10];
+ reset_output(O, 10);
+ int expected[] = {21};
+ int ret = as("sub", O);
+ printf("return=%d (expected 0): %s\n", ret, ret == 0 ? check_output(O, expected, 1, "sub") ? "PASS" : "FAIL" : "FAIL");
+}
+
+void test_not() {
+ printf("Testing not (opcode 22)... ");
+ int O[10];
+ reset_output(O, 10);
+ int expected[] = {22};
+ int ret = as("not", O);
+ printf("return=%d (expected 0): %s\n", ret, ret == 0 ? check_output(O, expected, 1, "not") ? "PASS" : "FAIL" : "FAIL");
+}
+
+void test_clr() {
+ printf("Testing clr (opcode 23)... ");
+ int O[10];
+ reset_output(O, 10);
+ int expected[] = {23};
+ int ret = as("clr", O);
+ printf("return=%d (expected 0): %s\n", ret, ret == 0 ? check_output(O, expected, 1, "clr") ? "PASS" : "FAIL" : "FAIL");
+}
+
+void test_multi_instruction() {
+ printf("Testing multi-instruction (hlt con 123 ar1 clr)... ");
+ int O[10];
+ reset_output(O, 10);
+ int expected[] = {0, 1, 123, 2, 23};
+ int ret = as("hlt con 123 ar1 clr", O);
+ printf("return=%d (expected 0): %s\n", ret, ret == 0 ? check_output(O, expected, 5, "multi-instruction") ? "PASS" : "FAIL" : "FAIL");
+}
+
+void test_whitespace() {
+ printf("Testing whitespace handling (hlt \\t\\n con 456 \\n clr)... ");
+ int O[10];
+ reset_output(O, 10);
+ int expected[] = {0, 1, 456, 23};
+ int ret = as("hlt \t\n con 456 \n clr", O);
+ printf("return=%d (expected 0): %s\n", ret, ret == 0 ? check_output(O, expected, 4, "whitespace") ? "PASS" : "FAIL" : "FAIL");
+}
+
+void test_error() {
+ printf("Testing error case (invalid instruction)... ");
+ int O[10];
+ reset_output(O, 10);
+ int ret = as("xyz", O);
+ printf("return=%d (expected 1): %s\n", ret, ret == 1 ? "PASS" : "FAIL");
+}
+
+int main() {
+ printf("Running CPU unit tests...\n\n");
+
+ test_opcode_0();
+ test_opcode_1();
+ test_opcode_2();
+ test_opcode_2_zero_acc();
+ test_opcode_10();
+ test_opcode_18();
+ test_opcode_19();
+ test_opcode_20();
+ test_opcode_21();
+ test_opcode_22();
+ test_opcode_23();
+
+ printf("\n\nRunning assembler unit tests...\n\n");
+
+ test_hlt();
+ test_con();
+ test_ar1();
+ test_ar8();
+ test_r1a();
+ test_r8a();
+ test_mem();
+ test_aca();
+ test_add();
+ test_sub();
+ test_not();
+ test_clr();
+ test_multi_instruction();
+ test_whitespace();
+ test_error();
+
+
+ return 0;
+} \ No newline at end of file