summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatarGravatar feos <vadosnaprimer@users.noreply.github.com>2020-01-19 00:41:08 +0300
committerGravatarGravatar R. Belmont <rb6502@users.noreply.github.com>2020-01-18 16:41:08 -0500
commit0706ebf694df8ceffdb12b8f4fd7a929c357e450 (patch) (github)
tree32d6d8facb0ba3cba9f02d9bc38f5c4a587dadb8
parentcc89ef6f2d66b5c0ff7eb462837539675d90ea45 (diff)
downloadmame-0706ebf694df8ceffdb12b8f4fd7a929c357e450.tar.bz2
mame-0706ebf694df8ceffdb12b8f4fd7a929c357e450.zip
luaengine: addr_space:read_range() (#6120)
* luaengine: allow reading a block of raw bytes for addr_space * redo space:read_block() to be more rebust and flexible
-rw-r--r--src/frontend/mame/luaengine.cpp59
1 files changed, 59 insertions, 0 deletions
diff --git a/src/frontend/mame/luaengine.cpp b/src/frontend/mame/luaengine.cpp
index 88a1c35634f..cc9c597b037 100644
--- a/src/frontend/mame/luaengine.cpp
+++ b/src/frontend/mame/luaengine.cpp
@@ -1669,6 +1669,8 @@ void lua_engine::initialize()
* space:write_log_*(addr, val)
* space:read_direct_*(addr)
* space:write_direct_*(addr, val)
+ * space:read_range(first_addr, last_addr, width, [opt] step) - read range of addresses and
+ * return as a binary string
*
* space.name - address space name
* space.shift - address bus shift, bitshift required for a bytewise address
@@ -1731,6 +1733,63 @@ void lua_engine::initialize()
addr_space_type.set("write_direct_u32", &addr_space::direct_mem_write<uint32_t>);
addr_space_type.set("write_direct_i64", &addr_space::direct_mem_write<int64_t>);
addr_space_type.set("write_direct_u64", &addr_space::direct_mem_write<uint64_t>);
+ addr_space_type.set("read_range", [](addr_space &sp, sol::this_state s, u64 first, u64 last, int width, sol::object opt_step) {
+ lua_State *L = s;
+ luaL_Buffer buff;
+ offs_t space_size = sp.space.addrmask();
+ u64 step = 1;
+ if (opt_step.is<u64>())
+ {
+ step = opt_step.as<u64>();
+ if (step < 1 || step > last - first)
+ {
+ luaL_error(L, "Invalid step");
+ return sol::make_reference(L, nullptr);
+ }
+ }
+ if (first > space_size || last > space_size || last < first)
+ {
+ luaL_error(L, "Invalid offset");
+ return sol::make_reference(L, nullptr);
+ }
+ int byte_count = width / 8 * (last - first + 1) / step;
+ switch (width)
+ {
+ case 8:
+ {
+ u8 *dest = (u8 *)luaL_buffinitsize(L, &buff, byte_count);
+ for(; first <= last; first += step)
+ *dest++ = sp.mem_read<u8>(first);
+ break;
+ }
+ case 16:
+ {
+ u16 *dest = (u16 *)luaL_buffinitsize(L, &buff, byte_count);
+ for(; first <= last; first += step)
+ *dest++ = sp.mem_read<u16>(first);
+ break;
+ }
+ case 32:
+ {
+ u32 *dest = (u32 *)luaL_buffinitsize(L, &buff, byte_count);
+ for(; first <= last; first += step)
+ *dest++ = sp.mem_read<u32>(first);
+ break;
+ }
+ case 64:
+ {
+ u64 *dest = (u64 *)luaL_buffinitsize(L, &buff, byte_count);
+ for(; first <= last; first += step)
+ *dest++ = sp.mem_read<u64>(first);
+ break;
+ }
+ default:
+ luaL_error(L, "Invalid width. Must be 8/16/32/64");
+ return sol::make_reference(L, nullptr);
+ }
+ luaL_pushresultsize(&buff, byte_count);
+ return sol::make_reference(L, sol::stack_reference(L, -1));
+ });
addr_space_type.set("name", sol::property([](addr_space &sp) { return sp.space.name(); }));
addr_space_type.set("shift", sol::property([](addr_space &sp) { return sp.space.addr_shift(); }));
addr_space_type.set("index", sol::property([](addr_space &sp) { return sp.space.spacenum(); }));