diff --git a/src/core/scripting.c b/src/core/scripting.c index e4a472d79..8adc5f55d 100644 --- a/src/core/scripting.c +++ b/src/core/scripting.c @@ -153,6 +153,13 @@ mSCRIPT_DECLARE_STRUCT_CD_METHOD(mCore, S32, frequency, 0); mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mCore, runFrame, 0); mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mCore, step, 0); +mSCRIPT_DECLARE_STRUCT_D_METHOD(mCore, U8, busRead8, 1, U32, address); +mSCRIPT_DECLARE_STRUCT_D_METHOD(mCore, U16, busRead16, 1, U32, address); +mSCRIPT_DECLARE_STRUCT_D_METHOD(mCore, U32, busRead32, 1, U32, address); +mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mCore, busWrite8, 2, U32, address, U8, value); +mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mCore, busWrite16, 2, U32, address, U16, value); +mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mCore, busWrite32, 2, U32, address, U32, value); + mSCRIPT_DEFINE_STRUCT(mCore) mSCRIPT_DEFINE_DOCSTRING("Get the number of the current frame") mSCRIPT_DEFINE_STRUCT_METHOD_NAMED(mCore, currentFrame, frameCounter) @@ -164,6 +171,19 @@ mSCRIPT_DEFINE_DOCSTRING("Run until the next frame") mSCRIPT_DEFINE_STRUCT_METHOD(mCore, runFrame) mSCRIPT_DEFINE_DOCSTRING("Run a single instruction") mSCRIPT_DEFINE_STRUCT_METHOD(mCore, step) + +mSCRIPT_DEFINE_DOCSTRING("Read an 8-bit value from the given bus address") +mSCRIPT_DEFINE_STRUCT_METHOD_NAMED(mCore, read8, busRead8) +mSCRIPT_DEFINE_DOCSTRING("Read a 16-bit value from the given bus address") +mSCRIPT_DEFINE_STRUCT_METHOD_NAMED(mCore, read16, busRead16) +mSCRIPT_DEFINE_DOCSTRING("Read a 32-bit value from the given bus address") +mSCRIPT_DEFINE_STRUCT_METHOD_NAMED(mCore, read32, busRead32) +mSCRIPT_DEFINE_DOCSTRING("Write an 8-bit value from the given bus address") +mSCRIPT_DEFINE_STRUCT_METHOD_NAMED(mCore, write8, busWrite8) +mSCRIPT_DEFINE_DOCSTRING("Write a 16-bit value from the given bus address") +mSCRIPT_DEFINE_STRUCT_METHOD_NAMED(mCore, write16, busWrite16) +mSCRIPT_DEFINE_DOCSTRING("Write a 32-bit value from the given bus address") +mSCRIPT_DEFINE_STRUCT_METHOD_NAMED(mCore, write32, busWrite32) mSCRIPT_DEFINE_END; void mScriptContextAttachCore(struct mScriptContext* context, struct mCore* core) { diff --git a/src/core/test/scripting.c b/src/core/test/scripting.c index cfe009601..b3af97742 100644 --- a/src/core/test/scripting.c +++ b/src/core/test/scripting.c @@ -12,9 +12,13 @@ #include #ifdef M_CORE_GBA +#include #define TEST_PLATFORM mPLATFORM_GBA +#define RAM_BASE BASE_WORKING_IRAM #elif defined(M_CORE_GB) +#include #define TEST_PLATFORM mPLATFORM_GB +#define RAM_BASE GB_BASE_WORKING_RAM_BANK0 #else #error "Need a valid platform for testing" #endif @@ -136,8 +140,73 @@ M_TEST_DEFINE(runFrame) { mScriptContextDeinit(&context); } +M_TEST_DEFINE(memoryRead) { + SETUP_LUA; + CREATE_CORE; + core->reset(core); + + LOAD_PROGRAM( + "a8 = emu:read8(base + 0)\n" + "b8 = emu:read8(base + 1)\n" + "c8 = emu:read8(base + 2)\n" + "d8 = emu:read8(base + 3)\n" + "a16 = emu:read16(base + 4)\n" + "b16 = emu:read16(base + 6)\n" + "a32 = emu:read32(base + 8)\n" + ); + + int i; + for (i = 0; i < 12; ++i) { + core->busWrite8(core, RAM_BASE + i, i + 1); + } + struct mScriptValue base = mSCRIPT_MAKE_S32(RAM_BASE); + lua->setGlobal(lua, "base", &base); + assert_true(lua->run(lua)); + + TEST_VALUE(S32, "a8", 1); + TEST_VALUE(S32, "b8", 2); + TEST_VALUE(S32, "c8", 3); + TEST_VALUE(S32, "d8", 4); + TEST_VALUE(S32, "a16", 0x0605); + TEST_VALUE(S32, "b16", 0x0807); + TEST_VALUE(S32, "a32", 0x0C0B0A09); + + TEARDOWN_CORE; + mScriptContextDeinit(&context); +} + +M_TEST_DEFINE(memoryWrite) { + SETUP_LUA; + CREATE_CORE; + core->reset(core); + + LOAD_PROGRAM( + "emu:write8(base + 0, 1)\n" + "emu:write8(base + 1, 2)\n" + "emu:write8(base + 2, 3)\n" + "emu:write8(base + 3, 4)\n" + "emu:write16(base + 4, 0x0605)\n" + "emu:write16(base + 6, 0x0807)\n" + "emu:write32(base + 8, 0x0C0B0A09)\n" + ); + + struct mScriptValue base = mSCRIPT_MAKE_S32(RAM_BASE); + lua->setGlobal(lua, "base", &base); + assert_true(lua->run(lua)); + + int i; + for (i = 0; i < 12; ++i) { + assert_int_equal(core->busRead8(core, RAM_BASE + i), i + 1); + } + + TEARDOWN_CORE; + mScriptContextDeinit(&context); +} + M_TEST_SUITE_DEFINE_SETUP_TEARDOWN(mScriptCore, cmocka_unit_test(globals), cmocka_unit_test(infoFuncs), cmocka_unit_test(runFrame), + cmocka_unit_test(memoryRead), + cmocka_unit_test(memoryWrite), )