Massive WIP

This commit is contained in:
Stefan Arentz 2017-09-16 07:58:24 -04:00
parent 4ce641eada
commit b4a7f4e69b
10 changed files with 276 additions and 60 deletions

View File

@ -24,7 +24,7 @@ os: osx
language: c
before_install:
- brew update
- brew install sdl2
- brew install sdl2 lua
before_script:
- cd src
script:

132
src/cpu.c
View File

@ -21,6 +21,7 @@
// SOFTWARE.
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
@ -101,15 +102,6 @@ void _cpu_set_status(struct cpu_t *cpu, uint8_t status) {
static void ewm_lua_push_cpu(struct ewm_lua_t *lua, struct cpu_t *cpu) {
void *cpu_data = lua_newuserdata(lua->state, sizeof(struct cpu_t*));
*((struct cpu_t**) cpu_data) = cpu;
luaL_getmetatable(lua->state, "cpu_meta_table");
lua_setmetatable(lua->state, -2);
}
static int cpu_execute_instruction(struct cpu_t *cpu) {
/* Trace code - Refactor into its own function or module */
@ -155,23 +147,23 @@ static int cpu_execute_instruction(struct cpu_t *cpu) {
switch (i->bytes) {
case 1:
lua_rawgeti(cpu->lua->state, LUA_REGISTRYINDEX, xxx_fn);
ewm_lua_push_cpu(cpu->lua, cpu);
lua_pushinteger(cpu->lua->state, i->opcode);
lua_pushinteger(cpu->lua->state, 0);
ewm_lua_push_cpu(cpu->lua, cpu);
lua_call(cpu->lua->state, 3, 0);
break;
case 2:
lua_rawgeti(cpu->lua->state, LUA_REGISTRYINDEX, xxx_fn);
ewm_lua_push_cpu(cpu->lua, cpu);
lua_pushinteger(cpu->lua->state, i->opcode);
lua_pushinteger(cpu->lua->state, mem_get_byte(cpu, pc+1));
ewm_lua_push_cpu(cpu->lua, cpu);
lua_call(cpu->lua->state, 3, 0);
break;
case 3:
lua_rawgeti(cpu->lua->state, LUA_REGISTRYINDEX, xxx_fn);
ewm_lua_push_cpu(cpu->lua, cpu);
lua_pushinteger(cpu->lua->state, i->opcode);
lua_pushinteger(cpu->lua->state, mem_get_word(cpu, pc+1));
ewm_lua_push_cpu(cpu->lua, cpu);
lua_call(cpu->lua->state, 3, 0);
break;
}
@ -494,6 +486,7 @@ int cpu_step(struct cpu_t *cpu) {
// cpu state functions
#if 0
static int lua_cpu_get_a(lua_State *state) {
void *cpu_data = luaL_checkudata(state, 1, "cpu_meta_table");
struct cpu_t *cpu = *((struct cpu_t**) cpu_data);
@ -518,6 +511,94 @@ static int lua_cpu_get_pc(lua_State *state) {
lua_pushnumber(state, cpu->state.pc);
return 1;
}
#endif
static int lua_cpu_reset(lua_State *state) {
printf("This is cpu.reset()\n");
return 0;
}
static int lua_cpu_index(lua_State *state) {
printf("This is cpu.__index()\n");
void *cpu_data = luaL_checkudata(state, 1, "cpu_meta_table");
struct cpu_t *cpu = *((struct cpu_t**) cpu_data);
if(!lua_isstring(state, 2)) {
printf("TODO lua_cpu_index: arg 2 is not a string\n");
return 0;
}
const char *name = lua_tostring(state, 2);
if (strcmp(name, "a") == 0) {
lua_pushnumber(state, cpu->state.a);
return 1;
}
if (strcmp(name, "x") == 0) {
lua_pushnumber(state, cpu->state.x);
return 1;
}
if (strcmp(name, "y") == 0) {
lua_pushnumber(state, cpu->state.y);
return 1;
}
if (strcmp(name, "pc") == 0) {
lua_pushnumber(state, cpu->state.pc);
return 1;
}
printf("TODO lua_cpu_index: Unknown property so what do we do?\n");
return 0;
}
static int lua_cpu_new_index(lua_State *state) {
printf("This is cpu.__newindex()\n");
void *cpu_data = luaL_checkudata(state, 1, "cpu_meta_table");
struct cpu_t *cpu = *((struct cpu_t**) cpu_data);
if(!lua_isstring(state, 2)) {
printf("TODO lua_cpu_new_index: arg 2 is not a string\n");
return 0;
}
const char *name = lua_tostring(state, 2);
if(!lua_isnumber(state, 3)) {
printf("TODO lua_cpu_new_index: arg 3 is not a string\n");
return 0;
}
int value = lua_tointeger(state, 3);
if (strcmp(name, "a") == 0) {
cpu->state.a = (uint8_t) value;
return 0;
}
if (strcmp(name, "x") == 0) {
cpu->state.x = (uint8_t) value;
return 0;
}
if (strcmp(name, "y") == 0) {
cpu->state.y = (uint8_t) value;
return 0;
}
if (strcmp(name, "pc") == 0) {
cpu->state.pc = (uint16_t) value; // TODO Does this actually work?
return 0;
}
printf("TODO lua_cpu_newindex: Unknown property so what do we do?\n");
return 0;
}
// cpu module functions
@ -554,29 +635,26 @@ static int ewm_cpu_luaopen(lua_State *state) {
{NULL, NULL}
};
luaL_newlib(state, cpu_functions);
return 1;
}
int ewm_cpu_init_lua(struct cpu_t *cpu, struct ewm_lua_t *lua) {
cpu->lua = lua;
// Register the module
cpu->lua = lua; // TODO This needs to move to cpu_luaopen so that
// we don't actually enable lua support until this
// module is required in a script. Same for other
// components.
luaL_requiref(cpu->lua->state, "cpu", ewm_cpu_luaopen, 0);
// Register the cpu meta table
luaL_newmetatable(cpu->lua->state, "cpu_meta_table");
luaL_Reg cpu_functions[] = {
{"a", lua_cpu_get_a},
{"pc", lua_cpu_get_pc},
luaL_Reg functions[] = {
//{"a", lua_cpu_get_a},
//{"pc", lua_cpu_get_pc},
{"reset", lua_cpu_reset},
{"__index", lua_cpu_index},
{"__newindex", lua_cpu_new_index},
{NULL, NULL}
};
luaL_setfuncs(cpu->lua->state, cpu_functions, 0);
lua_pushvalue(cpu->lua->state, -1);
lua_setfield(cpu->lua->state, -1, "__index");
// Keep it around
lua_setglobal(cpu->lua->state, "CPU"); // TODO I don't think we actually need this
ewm_lua_register_component(lua->state, "cpu", functions);
return 0;
}

View File

@ -27,10 +27,6 @@
#include <stdint.h>
#include <stdio.h>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#define EWM_CPU_MODEL_6502 0
#define EWM_CPU_MODEL_65C02 1

View File

@ -30,6 +30,7 @@
#include "mem.h"
#include "cpu.h"
#include "utl.h"
#include "lua.h"
#include "dsk.h"
//
@ -553,3 +554,25 @@ int ewm_dsk_set_disk_file(struct ewm_dsk_t *dsk, uint8_t drive, bool readonly, c
return result;
}
// Lua Support
static int ewm_dsk_lua_hello(lua_State *lua) {
printf("This is dsk.hello()\n");
return 0;
}
int ewm_dsk_luaopen(lua_State *state) {
luaL_Reg functions[] = {
{"hello", ewm_dsk_lua_hello},
{NULL, NULL}
};
luaL_newlib(state, functions);
return 1;
}
int ewm_dsk_init_lua(struct ewm_dsk_t *dsk, struct ewm_lua_t *lua) {
dsk->lua = lua;
luaL_requiref(dsk->lua->state, "dsk", ewm_dsk_luaopen, 0);
return 0;
}

View File

@ -28,6 +28,7 @@
struct cpu_t;
struct mem_t;
struct ewm_lua_t;
#define EWM_DSK_DRIVE1 (0)
#define EWM_DSK_DRIVE2 (1)
@ -61,6 +62,7 @@ struct ewm_dsk_t {
struct ewm_dsk_drive_t drives[2];
uint8_t drive; // 0 based
int skip;
struct ewm_lua_t *lua;
};
#define EWM_DSK_TYPE_UNKNOWN (-1)
@ -72,4 +74,6 @@ struct ewm_dsk_t *ewm_dsk_create(struct cpu_t *cpu);
int ewm_dsk_set_disk_data(struct ewm_dsk_t *dsk, uint8_t index, bool readonly, void *data, size_t length, int type);
int ewm_dsk_set_disk_file(struct ewm_dsk_t *dsk, uint8_t index, bool readonly, char *path);
int ewm_dsk_init_lua(struct ewm_dsk_t *dsk, struct ewm_lua_t *lua);
#endif

View File

@ -28,18 +28,17 @@
#include <lualib.h>
#include "lua.h"
#include "two.h"
#include "cpu.h"
#include "dsk.h"
int ewm_lua_init(struct ewm_lua_t *lua) {
static int ewm_lua_init(struct ewm_lua_t *lua) {
memset(lua, 0x00, sizeof(struct ewm_lua_t));
lua->state = luaL_newstate();
luaL_openlibs(lua->state);
return 0;
}
int ewm_lua_load_script(struct ewm_lua_t *lua, char *script_path) {
return luaL_dofile(lua->state, script_path);
}
struct ewm_lua_t *ewm_lua_create() {
struct ewm_lua_t *lua = malloc(sizeof(struct ewm_lua_t));
if (ewm_lua_init(lua) != 0) {
@ -48,3 +47,50 @@ struct ewm_lua_t *ewm_lua_create() {
}
return lua;
}
int ewm_lua_load_script(struct ewm_lua_t *lua, char *script_path) {
return luaL_dofile(lua->state, script_path);
}
void ewm_lua_push_cpu(struct ewm_lua_t *lua, struct cpu_t *cpu) {
void *cpu_data = lua_newuserdata(lua->state, sizeof(struct cpu_t*));
*((struct cpu_t**) cpu_data) = cpu;
luaL_getmetatable(lua->state, "cpu_meta_table");
lua_setmetatable(lua->state, -2);
}
void ewm_lua_push_two(struct ewm_lua_t *lua, struct ewm_two_t *two) {
void *two_data = lua_newuserdata(lua->state, sizeof(struct ewm_two_t*));
*((struct ewm_two_t**) two_data) = two;
luaL_getmetatable(lua->state, "two_meta_table");
lua_setmetatable(lua->state, -2);
}
void ewm_lua_push_dsk(struct ewm_lua_t *lua, struct ewm_dsk_t *dsk) {
void *dsk_data = lua_newuserdata(lua->state, sizeof(struct ewm_dsk_t*));
*((struct ewm_dsk_t**) dsk_data) = dsk;
luaL_getmetatable(lua->state, "dsk_meta_table");
lua_setmetatable(lua->state, -2);
}
void ewm_lua_register_component(lua_State *state, char *name, luaL_Reg *functions) {
char table_name[64];
strncpy(table_name, name, sizeof(table_name)-1);
strncat(table_name, "_meta_table", sizeof(table_name)-1);
char global_name[64];
strncpy(global_name, name, sizeof(global_name)-1);
for (size_t i = 0; i < strlen(global_name); i++) {
global_name[i] = toupper(global_name[i]);
}
// Register the cpu meta table
luaL_newmetatable(state, table_name);
luaL_setfuncs(state, functions, 0);
//lua_pushvalue(state, -1);
//lua_setfield(state, -1, "__index");
// Keep it around
lua_setglobal(state, "CPU"); // TODO I don't think we actually need this
}

View File

@ -28,6 +28,8 @@
#include <lualib.h>
struct cpu_t;
struct ewm_two_t;
struct ewm_dsk_t;
struct ewm_lua_t {
lua_State *state;
@ -36,4 +38,10 @@ struct ewm_lua_t {
struct ewm_lua_t *ewm_lua_create();
int ewm_lua_load_script(struct ewm_lua_t *lua, char *script_path);
void ewm_lua_push_cpu(struct ewm_lua_t *lua, struct cpu_t *cpu);
void ewm_lua_push_two(struct ewm_lua_t *lua, struct ewm_two_t *two);
void ewm_lua_push_dsk(struct ewm_lua_t *lua, struct ewm_dsk_t *dsk);
void ewm_lua_register_component(lua_State *state, char *name, luaL_Reg *functions);
#endif // LUA_H

53
src/test.lua Normal file
View File

@ -0,0 +1,53 @@
-- EWM Meets Lua
local function myerrhandler(err)
print(err)
print(debug.traceback())
return false
end
xpcall(function()
local two = require 'two'
two.hello()
local cpu = require 'cpu'
cpu.hello()
local dsk = require 'dsk'
dsk.hello()
-- Intercept JSR COUT calls
-- cpu.onBeforeExecuteInstruction(0x20, function(cpu, opcode, operand)
-- if operand == 0xfded then
-- print(string.format("COUT was called from %.4x with A=%.2x", cpu:pc(), cpu:a()))
-- if cpu:a() >= 0xc1 and cpu:a() <= 0xda then
-- -- Lets inverse this character
-- cpu:a(cpu:a() - 0xC0)
-- end
-- end
-- end)
cpu.onBeforeExecuteInstruction(0x20, function(state, opcode, operand)
if operand == 0xfded then
print(string.format("COUT was called from %.4x with A=%.2x", state.a, state.pc))
if state.a >= 0xc1 and state.a <= 0xda then
-- Lets inverse this character
state.a = state.a - 0xC0
end
end
end)
-- Reset when the R key is pressed
--two.onKeyDown('R', function(two, key)
-- print('You pressed R')
-- two.reset()
--end)
-- Enter the Monitor when the M key is pressed
--two.onKeyDown('M', function(two, key)
-- print('You pressed B')
-- two.monitor()
--end)
end , myerrhandler )

View File

@ -350,12 +350,34 @@ void ewm_two_destroy(struct ewm_two_t *two) {
// TODO
}
// Lua support
static int ewm_two_lua_hello(lua_State *lua) {
printf("This is two.hello()\n");
return 0;
}
int ewm_two_luaopen(lua_State *state) {
luaL_Reg ewm_two_functions[] = {
{"hello", ewm_two_lua_hello},
{NULL, NULL}
};
luaL_newlib(state, ewm_two_functions);
return 1;
}
int ewm_two_init_lua(struct ewm_two_t *two, struct ewm_lua_t *lua) {
two->lua = lua;
luaL_requiref(two->lua->state, "two", ewm_two_luaopen, 0);
return 0;
}
// External API
int ewm_two_load_disk(struct ewm_two_t *two, int drive, char *path) {
return ewm_dsk_set_disk_file(two->dsk, drive, false, path);
}
static bool ewm_two_poll_event(struct ewm_two_t *two, SDL_Window *window) { // TODO Should window be part of ewm_two_t?
SDL_Event event;
while (SDL_PollEvent(&event) != 0) {
@ -566,8 +588,6 @@ static void usage() {
fprintf(stderr, " --lua <script> load lua script into the emulator\n");
}
int ewm_two_luaopen(lua_State *state);
int ewm_two_main(int argc, char **argv) {
// Parse options
@ -734,10 +754,13 @@ int ewm_two_main(int argc, char **argv) {
two->lua = ewm_lua_create();
luaL_requiref(two->lua->state, "ewm", ewm_two_luaopen, 0); // ewm_two_init_lua? that calls it for all its components?
ewm_two_init_lua(two, two->lua);
ewm_cpu_init_lua(two->cpu, two->lua);
ewm_dsk_init_lua(two->dsk, two->lua);
if (ewm_lua_load_script(two->lua, lua_script_path) != 0) {
printf("Lua script failed to load\n"); // TODO Errors would be nice
printf("Lua script failed to load\n"); // TODO Move errors reporting into C code
exit(1);
}
}
@ -804,20 +827,3 @@ int ewm_two_main(int argc, char **argv) {
return 0;
}
// Lua support
static int ewm_two_lua_hello(lua_State *lua) {
printf("This is ewm.hello()\n");
return 0;
}
int ewm_two_luaopen(lua_State *state) {
luaL_Reg ewm_two_functions[] = {
{"hello", ewm_two_lua_hello},
{NULL, NULL}
};
luaL_newlib(state, ewm_two_functions);
return 1;
}

View File

@ -56,7 +56,7 @@
struct mem_t;
struct ewm_dsk_t;
struct scr;
struct lua;
struct ewm_lua_t;
struct ewm_two_t {
int type;
@ -106,6 +106,8 @@ struct ewm_two_t {
struct ewm_two_t *ewm_two_create(int type, SDL_Renderer *renderer, SDL_Joystick *joystick);
void ewm_two_destroy(struct ewm_two_t *two);
int ewm_two_init_lua(struct ewm_two_t *two, struct ewm_lua_t *lua);
int ewm_two_load_disk(struct ewm_two_t *two, int drive, char *path);
int ewm_two_main(int argc, char **argv);