summaryrefslogtreecommitdiff
path: root/6502/src/test.c
diff options
context:
space:
mode:
Diffstat (limited to '6502/src/test.c')
-rw-r--r--6502/src/test.c142
1 files changed, 142 insertions, 0 deletions
diff --git a/6502/src/test.c b/6502/src/test.c
new file mode 100644
index 0000000..1b4e241
--- /dev/null
+++ b/6502/src/test.c
@@ -0,0 +1,142 @@
+/* test harness - we build this to a shared object and then run it from Lua */
+/* see the ../test directory */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <lua.h>
+#include <lcq/6502.h>
+
+static l6502_emu *get_emu(lua_State *l) {
+ l6502_emu *e = lua_touserdata(l, 1);
+ if (!e) { lua_pushliteral(l, "expected emulator as first argument"); lua_error(l); }
+ return e;
+}
+
+int emu_summary(lua_State *l);
+int emu_summary(lua_State *l) {
+ l6502_emu *e = get_emu(l);
+ lua_newtable(l);
+ lua_pushinteger(l, e->pc); lua_setfield(l, -2, "pc");
+ lua_newtable(l);
+ lua_pushinteger(l, e->regs[L6502_REG_SP]); lua_setfield(l, -2, "sp");
+ lua_pushinteger(l, e->regs[L6502_REG_A]); lua_setfield(l, -2, "a");
+ lua_pushinteger(l, e->regs[L6502_REG_X]); lua_setfield(l, -2, "x");
+ lua_pushinteger(l, e->regs[L6502_REG_Y]); lua_setfield(l, -2, "y");
+ lua_setfield(l, -2, "regs");
+ lua_newtable(l);
+ lua_pushinteger(l, l6502_flag_get(e, L6502_FLAG_CARRY)); lua_setfield(l, -2, "carry");
+ lua_pushinteger(l, l6502_flag_get(e, L6502_FLAG_ZERO)); lua_setfield(l, -2, "zero");
+ lua_pushinteger(l, l6502_flag_get(e, L6502_FLAG_INTERRUPT_DISABLE)); lua_setfield(l, -2, "interrupt_disable");
+ lua_pushinteger(l, l6502_flag_get(e, L6502_FLAG_DECIMAL)); lua_setfield(l, -2, "decimal");
+ lua_pushinteger(l, l6502_flag_get(e, L6502_FLAG_BREAK_COMMAND)); lua_setfield(l, -2, "break_command");
+ lua_pushinteger(l, l6502_flag_get(e, L6502_FLAG_OVERFLOW)); lua_setfield(l, -2, "overflow");
+ lua_pushinteger(l, l6502_flag_get(e, L6502_FLAG_NEGATIVE)); lua_setfield(l, -2, "negative");
+ lua_setfield(l, -2, "flags");
+ return 1;
+}
+
+int emu_get_reg(lua_State *l);
+int emu_get_reg(lua_State *l) {
+ l6502_emu *e = get_emu(l);
+ l6502_reg r = lua_tointeger(l, 2);
+ if (r >= 0 && r < L6502_REG__MARKER) lua_pushinteger(l, e->regs[r]);
+ else { lua_pushliteral(l, "invalid register"); lua_error(l); }
+ return 1;
+}
+int emu_set_reg(lua_State *l);
+int emu_set_reg(lua_State *l) {
+ l6502_emu *e = get_emu(l);
+ l6502_reg r = lua_tointeger(l, 2);
+ u8 v = (u8) lua_tointeger(l, 3);
+ if (r >= 0 && r < L6502_REG__MARKER) e->regs[r] = v;
+ else { lua_pushliteral(l, "invalid register"); lua_error(l); }
+ lua_pushvalue(l, 1);
+ return 1;
+}
+
+int emu_get_flag(lua_State *l);
+int emu_get_flag(lua_State *l) {
+ l6502_emu *e = get_emu(l);
+ l6502_flag f = lua_tointeger(l, 2);
+ lua_pushinteger(l, l6502_flag_get(e, f));
+ return 1;
+}
+int emu_set_flag(lua_State *l);
+int emu_set_flag(lua_State *l) {
+ l6502_emu *e = get_emu(l);
+ l6502_flag f = lua_tointeger(l, 2);
+ u8 v = (u8) lua_tointeger(l, 3);
+ l6502_flag_set(e, f, v);
+ lua_pushvalue(l, 1);
+ return 1;
+}
+
+int emu_get_pc(lua_State *l);
+int emu_get_pc(lua_State *l) {
+ l6502_emu *e = get_emu(l);
+ lua_pushinteger(l, e->pc);
+ return 1;
+}
+
+int emu_set_pc(lua_State *l);
+int emu_set_pc(lua_State *l) {
+ l6502_emu *e = get_emu(l);
+ e->pc = (u16) lua_tointeger(l, 2);
+ lua_pushvalue(l, 1);
+ return 1;
+}
+
+int emu_emulate(lua_State *l);
+int emu_emulate(lua_State *l) {
+ l6502_emu *e = get_emu(l);
+ l6502_emulate(e);
+ return 1;
+}
+
+int new(lua_State *l);
+int new(lua_State *l) {
+ l6502_emu *e = lua_newuserdata(l, sizeof(l6502_emu));
+ l6502_mem_basic_new(&e->mem);
+ lua_newtable(l);
+ lua_newtable(l);
+ lua_pushcfunction(l, emu_summary); lua_setfield(l, -2, "summary");
+ lua_pushcfunction(l, emu_get_reg); lua_setfield(l, -2, "reg");
+ lua_pushcfunction(l, emu_set_reg); lua_setfield(l, -2, "set-reg");
+ lua_pushcfunction(l, emu_get_flag); lua_setfield(l, -2, "flag");
+ lua_pushcfunction(l, emu_set_flag); lua_setfield(l, -2, "set-flag");
+ lua_pushcfunction(l, emu_get_pc); lua_setfield(l, -2, "pc");
+ lua_pushcfunction(l, emu_set_pc); lua_setfield(l, -2, "set-pc");
+ lua_pushcfunction(l, emu_emulate); lua_setfield(l, -2, "emulate");
+ lua_setfield(l, -2, "__index");
+ lua_setmetatable(l, -2);
+ return 1;
+}
+
+#define PUSH_ENUM(enum, field) { lua_pushinteger(l, enum ## _ ## field); lua_setfield(l, -2, #field); }
+static void push_enum_flag(lua_State *l) {
+ lua_newtable(l);
+ PUSH_ENUM(L6502_FLAG, CARRY);
+ PUSH_ENUM(L6502_FLAG, ZERO);
+ PUSH_ENUM(L6502_FLAG, INTERRUPT_DISABLE);
+ PUSH_ENUM(L6502_FLAG, DECIMAL);
+ PUSH_ENUM(L6502_FLAG, BREAK_COMMAND);
+ PUSH_ENUM(L6502_FLAG, OVERFLOW);
+ PUSH_ENUM(L6502_FLAG, NEGATIVE);
+}
+static void push_enum_reg(lua_State *l) {
+ lua_newtable(l);
+ PUSH_ENUM(L6502_REG, SP);
+ PUSH_ENUM(L6502_REG, A);
+ PUSH_ENUM(L6502_REG, X);
+ PUSH_ENUM(L6502_REG, Y);
+ PUSH_ENUM(L6502_REG, FLAGS);
+}
+
+int luaopen_l6502(lua_State *l);
+int luaopen_l6502(lua_State *l) {
+ lua_newtable(l);
+ push_enum_flag(l); lua_setfield(l, -2, "flag");
+ push_enum_reg(l); lua_setfield(l, -2, "reg");
+ lua_pushcfunction(l, new); lua_setfield(l, -2, "new");
+ return 1;
+}