summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Olivier Galibert <galibert@pobox.com>2014-12-24 11:53:36 +0100
committer Olivier Galibert <galibert@pobox.com>2014-12-24 11:53:36 +0100
commitf19ef3e2078365924bb4f2942539af34929792a1 (patch)
treeabe0abe2ac7aca59620c7d215a61b015e6e81a8e
parent00180d3f6747488899e99b341a6f162c99bc2854 (diff)
parent0a46c8b8d786b8ef59beeb2cff4f38115c9b96db (diff)
Merge pull request #89 from lucab/lucab/mame-lua/mem-v2
luaengine: add memory-reading capabilities [Luca Bruno]
-rw-r--r--src/emu/luaengine.c120
-rw-r--r--src/emu/luaengine.h17
2 files changed, 137 insertions, 0 deletions
diff --git a/src/emu/luaengine.c b/src/emu/luaengine.c
index 128b6716194..843c873233e 100644
--- a/src/emu/luaengine.c
+++ b/src/emu/luaengine.c
@@ -8,6 +8,7 @@
***************************************************************************/
+#include <limits>
#include "lua/lua.hpp"
#include "lua/lib/lualibs.h"
#include "lua/bridge/LuaBridge.h"
@@ -335,6 +336,107 @@ int lua_engine::l_emu_hook_output(lua_State *L)
return 0;
}
+//-------------------------------------------------
+// machine_get_devices - return table of available devices userdata
+// -> manager:machine().devices[":maincpu"]
+//-------------------------------------------------
+
+luabridge::LuaRef lua_engine::l_machine_get_devices(const running_machine *r)
+{
+ running_machine *m = const_cast<running_machine *>(r);
+ lua_State *L = luaThis->m_lua_state;
+ luabridge::LuaRef devs_table = luabridge::LuaRef::newTable(L);
+
+ device_t *root = &(m->root_device());
+ devs_table = devtree_dfs(root, devs_table);
+
+ return devs_table;
+}
+
+// private helper for get_devices - DFS visit all devices in a running machine
+luabridge::LuaRef lua_engine::devtree_dfs(device_t *root, luabridge::LuaRef devs_table)
+{
+ if (root) {
+ for (device_t *dev = root->first_subdevice(); dev != NULL; dev = dev->next()) {
+ if (dev && dev->configured() && dev->started()) {
+ devs_table[dev->tag()] = dev;
+ devtree_dfs(dev, devs_table);
+ }
+ }
+ }
+ return devs_table;
+}
+
+//-------------------------------------------------
+// device_get_memspaces - return table of available address spaces userdata
+// -> manager:machine().devices[":maincpu"].spaces["program"]
+//-------------------------------------------------
+
+luabridge::LuaRef lua_engine::l_dev_get_memspaces(const device_t *d)
+{
+ device_t *dev = const_cast<device_t *>(d);
+ lua_State *L = luaThis->m_lua_state;
+ luabridge::LuaRef sp_table = luabridge::LuaRef::newTable(L);
+
+ for (address_spacenum sp = AS_0; sp < ADDRESS_SPACES; sp++) {
+ if (dev->memory().has_space(sp)) {
+ sp_table[dev->memory().space(sp).name()] = &(dev->memory().space(sp));
+ }
+ }
+
+ return sp_table;
+}
+
+//-------------------------------------------------
+// mem_read - templated memory readers for <sign>,<size>
+// -> manager:machine().devices[":maincpu"].spaces["program"]:read_i8(0xC000)
+//-------------------------------------------------
+
+template <typename T>
+int lua_engine::lua_addr_space::l_mem_read(lua_State *L)
+{
+ address_space &sp = luabridge::Stack<address_space &>::get(L, 1);
+ luaL_argcheck(L, lua_isnumber(L, 2), 2, "address (integer) expected");
+ offs_t address = lua_tounsigned(L, 2);
+ T mem_content = 0;
+ switch(sizeof(mem_content) * 8) {
+ case 8:
+ mem_content = sp.read_byte(address);
+ break;
+ case 16:
+ if ((address & 1) == 0) {
+ mem_content = sp.read_word(address);
+ } else {
+ mem_content = sp.read_word_unaligned(address);
+ }
+ break;
+ case 32:
+ if ((address & 3) == 0) {
+ mem_content = sp.read_dword(address);
+ } else {
+ mem_content = sp.read_dword_unaligned(address);
+ }
+ break;
+ case 64:
+ if ((address & 7) == 0) {
+ mem_content = sp.read_qword(address);
+ } else {
+ mem_content = sp.read_qword_unaligned(address);
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (std::numeric_limits<T>::is_signed) {
+ lua_pushinteger(L, mem_content);
+ } else {
+ lua_pushunsigned(L, mem_content);
+ }
+
+ return 1;
+
+}
void *lua_engine::checkparam(lua_State *L, int idx, const char *tname)
{
@@ -564,6 +666,7 @@ void lua_engine::initialize()
.addFunction ("hard_reset", &running_machine::schedule_hard_reset)
.addFunction ("soft_reset", &running_machine::schedule_soft_reset)
.addFunction ("system", &running_machine::system)
+ .addProperty <luabridge::LuaRef, void> ("devices", &lua_engine::l_machine_get_devices)
.endClass ()
.beginClass <game_driver> ("game_driver")
.addData ("name", &game_driver::name)
@@ -571,6 +674,23 @@ void lua_engine::initialize()
.addData ("year", &game_driver::year)
.addData ("manufacturer", &game_driver::manufacturer)
.endClass ()
+ .beginClass <device_t> ("device")
+ .addFunction("name", &device_t::tag)
+ .addProperty <luabridge::LuaRef, void> ("spaces", &lua_engine::l_dev_get_memspaces)
+ .endClass()
+ .beginClass <lua_addr_space> ("lua_addr_space")
+ .addCFunction ("read_i8", &lua_addr_space::l_mem_read<INT8>)
+ .addCFunction ("read_u8", &lua_addr_space::l_mem_read<UINT8>)
+ .addCFunction ("read_i16", &lua_addr_space::l_mem_read<INT16>)
+ .addCFunction ("read_u16", &lua_addr_space::l_mem_read<UINT16>)
+ .addCFunction ("read_i32", &lua_addr_space::l_mem_read<INT32>)
+ .addCFunction ("read_u32", &lua_addr_space::l_mem_read<UINT32>)
+ .addCFunction ("read_i64", &lua_addr_space::l_mem_read<INT64>)
+ .addCFunction ("read_u64", &lua_addr_space::l_mem_read<UINT64>)
+ .endClass()
+ .deriveClass <address_space, lua_addr_space> ("addr_space")
+ .addFunction("name", &address_space::name)
+ .endClass()
.endNamespace ();
luabridge::push (m_lua_state, machine_manager::instance());
diff --git a/src/emu/luaengine.h b/src/emu/luaengine.h
index 62399dbd281..ae1221415ff 100644
--- a/src/emu/luaengine.h
+++ b/src/emu/luaengine.h
@@ -19,6 +19,15 @@
#include <map>
+// None is typedef'd already in SDL/X11 libs
+#ifdef None
+#undef None
+#endif
+
+#include "lua/lua.hpp"
+#include "lua/lib/lualibs.h"
+#include "lua/bridge/LuaBridge.h"
+
struct lua_State;
class lua_engine
@@ -89,6 +98,14 @@ private:
static int l_emu_pause(lua_State *L);
static int l_emu_unpause(lua_State *L);
+ // "emu.machine" namespace
+ static luabridge::LuaRef l_machine_get_devices(const running_machine *r);
+ static luabridge::LuaRef l_dev_get_memspaces(const device_t *d);
+ static luabridge::LuaRef devtree_dfs(device_t *root, luabridge::LuaRef dev_table);
+ struct lua_addr_space {
+ template<typename T> int l_mem_read(lua_State *L);
+ };
+
void resume(void *L, INT32 param);
void report_errors(int status);
void start();