Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
// This file: // http://angg.twu.net/RETRO/luaretro.c.html // http://angg.twu.net/RETRO/luaretro.c // See: // http://angg.twu.net/RETRO/README.html // http://angg.twu.net/RETRO/VERSION.html // Author: Eduardo Ochs <eduardoochs@gmail.com> // Version: 2011apr17 05:50 // but see above. // // (find-angg "peek/peek.c") // (find-luamanualw3m "#luaL_checkint") // (find-luamanualw3m "#luaL_checklstring") // (find-luamanualw3m "#lua_pushinteger") // (find-luamanualw3m "#lua_pushlstring") // (find-node "(libc)Function Index" "memcpy") // (find-node "(libc)Function Index" "* malloc") // (find-node "(libc)Function Index" "* free") // Note: the "string evaluation" function - to be done - will probably // be quite similar to "lua_poke" below, but calling some function in // Retro instead of memcpy. // «.low-level-build-.so» (to "low-level-build-.so") // «.low-level-lua-test» (to "low-level-lua-test") // «.test-makefile» (to "test-makefile") #include <stdlib.h> // (find-man "3 malloc") #include <string.h> // (find-man "3 memcpy") #include <lua.h> #include <lauxlib.h> #include <termios.h> static int lua_peek(lua_State* L) { int addr = luaL_checkint(L, 1); int len = luaL_checkint(L, 2); lua_pushlstring(L, (void *)addr, len); return 1; } static int lua_poke(lua_State* L) { int addr = luaL_checkint(L, 1); int len = 0; const char* straddr = luaL_checklstring(L, 2, &len); memcpy((void *)addr, straddr, len); return 0; } static int lua_malloc(lua_State* L) { int len = luaL_checkint(L, 1); lua_pushinteger(L, (int)malloc(len)); return 1; } static int lua_free(lua_State* L) { int addr = luaL_checkint(L, 1); free((void *)addr); return 0; } // (find-anggfile "RETRO/libretro.c") // (find-anggfile "RETRO/test.c") #define CELL int32_t #define IMAGE_SIZE 1000000 #define ADDRESSES 1024 #define STACK_DEPTH 128 #define PORTS 32 #define MAX_FILE_NAME 1024 #define MAX_REQUEST_LENGTH 1024 #define MAX_OPEN_FILES 8 #define GLOBAL "/usr/local/share/retro/retroImage" #define LOCAL "retroImage" enum vm_opcode {VM_NOP, VM_LIT, VM_DUP, VM_DROP, VM_SWAP, VM_PUSH, VM_POP, VM_LOOP, VM_JUMP, VM_RETURN, VM_GT_JUMP, VM_LT_JUMP, VM_NE_JUMP,VM_EQ_JUMP, VM_FETCH, VM_STORE, VM_ADD, VM_SUB, VM_MUL, VM_DIVMOD, VM_AND, VM_OR, VM_XOR, VM_SHL, VM_SHR, VM_ZERO_EXIT, VM_INC, VM_DEC, VM_IN, VM_OUT, VM_WAIT }; #define NUM_OPS VM_WAIT + 1 typedef struct { CELL sp, rsp, ip; CELL data[STACK_DEPTH]; CELL address[ADDRESSES]; CELL ports[PORTS]; FILE *files[MAX_OPEN_FILES]; FILE *input[MAX_OPEN_FILES]; CELL isp; CELL inputSource; char *inputString; CELL strIndex; CELL image[IMAGE_SIZE]; CELL shrink, padding; int stats[NUM_OPS + 1]; int max_sp, max_rsp; char filename[MAX_FILE_NAME]; char request[MAX_REQUEST_LENGTH]; struct termios new_termios, old_termios; } VM; void rxWriteConsole(VM *vm, CELL c); CELL rxReadConsole(VM *vm); void rxIncludeFile(VM *vm, char *s); void rxPrepareInput(VM *vm); void rxPrepareOutput(VM *vm); void rxRestoreIO(VM *vm); void rxAddInputSource(VM *vm); CELL rxLoadImage(VM *vm, char *image); CELL rxSaveImage(VM *vm, char *image); void rxDeviceHandler(VM *vm); void rxProcessOpcode(VM *vm); void rxDisplayStats(VM *vm); VM *vm; static int lua_retro_initialize(lua_State* L) { vm = calloc(sizeof(VM), sizeof(char)); strcpy(vm->filename, "retroImage"); rxLoadImage(vm, "retroImage"); rxPrepareInput(vm); rxPrepareOutput(vm); return 0; } static int lua_retro_finish(lua_State* L) { rxRestoreIO(vm); return 0; } static int lua_retro_eval(lua_State* L) { rxEvaluateString(vm, lua_tostring(L, -1)); return 0; } static int lua_retro_main(lua_State* L) { for (vm->ip = 0; vm->ip < IMAGE_SIZE; vm->ip++) rxProcessOpcode(vm); return 0; } LUALIB_API int luaopen_retro(lua_State *L) { lua_register(L, "peek_", lua_peek); lua_register(L, "poke_", lua_poke); lua_register(L, "malloc_", lua_malloc); lua_register(L, "free_", lua_free); lua_register(L, "retro_main", lua_retro_main); lua_register(L, "retro_eval", lua_retro_eval); lua_register(L, "retro_initialize", lua_retro_initialize); lua_register(L, "retro_finish", lua_retro_finish); return 0; } /* // IGNORE THIS! // (find-angg "peek/peek-0.0.1-0.rockspec" "build") // (find-angg "peek/peek-0.0.1-0.rockspec" "test") // (find-angg "peek/olm-peek") // (find-angg ".zshrc" "lua") # «low-level-build-.so» (to ".low-level-build-.so") * (eepitch-shell) * (eepitch-kill) * (eepitch-shell) cd ~/RETRO/ gcc -g -O0 -Wall -fPIC -I$LUA51SRC/include -c luaretro.c -o luaretro.o gcc -g -O0 -Wall -fPIC -DNOMAIN -c libretro.c -o libretro.o gcc -shared -o retro.so -L$LUA51SRC/lib libretro.o luaretro.o # «low-level-lua-test» (to ".low-level-lua-test") * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) assert(package.loadlib("./retro.so", "luaopen_retro"))() = retro_main_ retro_main_() # «test-makefile» (to ".test-makefile") * (eepitch-shell) * (eepitch-kill) * (eepitch-shell) # (find-angg "RETRO/Makefile" "libretro.so") cd ~/RETRO/ make clean make runtest make LUA51SRC=$LUA51SRC LUA51=$HOME/bin/lua51 runluatest make lua51 make runluatest * (eepitch-shell) * (eepitch-kill) * (eepitch-shell) cd ~/RETRO/ make clean make tgz ls -l luaretro.tgz make runluatest */ /* * Local Variables: * coding: raw-text-unix * ee-anchor-format: "«%s»" * End: */