mirror of
https://github.com/holub/mame
synced 2025-06-04 03:46:29 +03:00
luaengine_mem.cpp: Cleanup and enhancements.
* Changed memory manager banks, regions and shares to lightweight wrappers. * Exposed tag, width and Endianness of regions and shares. * Exposed memory tag and entry of banks (scripts can change entry). * Modernised syntax and switched to abbreviated integer types.
This commit is contained in:
parent
a3a7129197
commit
738b60d531
@ -14,6 +14,35 @@
|
||||
|
||||
namespace {
|
||||
|
||||
template <typename T>
|
||||
struct memory_object_map
|
||||
{
|
||||
memory_object_map(T const &m) : map(m) { }
|
||||
|
||||
T const ↦
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using standard_memory_object_map = memory_object_map<std::unordered_map<std::string, std::unique_ptr<T> > >;
|
||||
|
||||
|
||||
template <typename T>
|
||||
std::string get_endianness_name(T const &obj)
|
||||
{
|
||||
std::string endianness;
|
||||
switch (obj.endianness())
|
||||
{
|
||||
case endianness_t::ENDIANNESS_BIG:
|
||||
endianness = "big";
|
||||
break;
|
||||
case endianness_t::ENDIANNESS_LITTLE:
|
||||
endianness = "little";
|
||||
break;
|
||||
}
|
||||
return endianness;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// region_read - templated region readers for <sign>,<size>
|
||||
// -> manager:machine():memory().regions[":maincpu"]:read_i8(0xC000)
|
||||
@ -75,7 +104,7 @@ T share_read(memory_share &share, offs_t address)
|
||||
{
|
||||
T mem_content = 0;
|
||||
const offs_t lowmask = share.bytewidth() - 1;
|
||||
uint8_t *ptr = (uint8_t *)share.ptr();
|
||||
u8 *ptr = (u8 *)share.ptr();
|
||||
for (int i = 0; i < sizeof(T); i++)
|
||||
{
|
||||
int addr = share.endianness() == ENDIANNESS_LITTLE ? address + sizeof(T) - 1 - i : address + i;
|
||||
@ -102,7 +131,7 @@ template <typename T>
|
||||
void share_write(memory_share &share, offs_t address, T val)
|
||||
{
|
||||
const offs_t lowmask = share.bytewidth() - 1;
|
||||
uint8_t *ptr = (uint8_t *)share.ptr();
|
||||
u8 *ptr = (u8 *)share.ptr();
|
||||
for (int i = 0; i < sizeof(T); i++)
|
||||
{
|
||||
int addr = share.endianness() == ENDIANNESS_BIG ? address + sizeof(T) - 1 - i : address + i;
|
||||
@ -122,6 +151,109 @@ void share_write(memory_share &share, offs_t address, T val)
|
||||
|
||||
|
||||
|
||||
namespace sol {
|
||||
|
||||
template <typename T> struct is_container<memory_object_map<T> > : std::true_type { };
|
||||
|
||||
|
||||
template <typename T>
|
||||
struct usertype_container<memory_object_map<T> > : lua_engine::immutable_container_helper<memory_object_map<T>, T const, typename T::const_iterator>
|
||||
{
|
||||
private:
|
||||
template <bool Indexed>
|
||||
static int next_pairs(lua_State *L)
|
||||
{
|
||||
typename usertype_container::indexed_iterator &i(stack::unqualified_get<user<typename usertype_container::indexed_iterator> >(L, 1));
|
||||
if (i.src.end() == i.it)
|
||||
return stack::push(L, lua_nil);
|
||||
int result;
|
||||
if constexpr (Indexed)
|
||||
result = stack::push(L, i.ix + 1);
|
||||
else
|
||||
result = stack::push(L, i.it->first);
|
||||
result += stack::push_reference(L, *i.it->second);
|
||||
++i;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <bool Indexed>
|
||||
static int start_pairs(lua_State *L)
|
||||
{
|
||||
memory_object_map<T> &self(usertype_container::get_self(L));
|
||||
stack::push(L, next_pairs<Indexed>);
|
||||
stack::push<user<typename usertype_container::indexed_iterator> >(L, self.map, self.map.begin());
|
||||
stack::push(L, lua_nil);
|
||||
return 3;
|
||||
}
|
||||
|
||||
public:
|
||||
static int at(lua_State *L)
|
||||
{
|
||||
memory_object_map<T> &self(usertype_container::get_self(L));
|
||||
std::ptrdiff_t const index(stack::unqualified_get<std::ptrdiff_t>(L, 2));
|
||||
if ((0 >= index) || (self.map.size() < index))
|
||||
return stack::push(L, lua_nil);
|
||||
auto const found(std::next(self.map.begin(), index - 1));
|
||||
if (!found->second)
|
||||
return stack::push(L, lua_nil);
|
||||
else
|
||||
return stack::push_reference(L, *found->second);
|
||||
}
|
||||
|
||||
static int get(lua_State *L)
|
||||
{
|
||||
memory_object_map<T> &self(usertype_container::get_self(L));
|
||||
char const *const tag(stack::unqualified_get<char const *>(L));
|
||||
auto const found(self.map.find(tag));
|
||||
if ((self.map.end() == found) || !found->second)
|
||||
return stack::push(L, lua_nil);
|
||||
else
|
||||
return stack::push_reference(L, *found->second);
|
||||
}
|
||||
|
||||
static int index_get(lua_State *L)
|
||||
{
|
||||
return get(L);
|
||||
}
|
||||
|
||||
static int index_of(lua_State *L)
|
||||
{
|
||||
memory_object_map<T> &self(usertype_container::get_self(L));
|
||||
auto &obj(stack::unqualified_get<decltype(*self.map.begin()->second)>(L, 2));
|
||||
auto it(self.map.begin());
|
||||
std::ptrdiff_t ix(0);
|
||||
while ((self.map.end() != it) && (it->second.get() != &obj))
|
||||
{
|
||||
++it;
|
||||
++ix;
|
||||
}
|
||||
if (self.map.end() == it)
|
||||
return stack::push(L, lua_nil);
|
||||
else
|
||||
return stack::push(L, ix + 1);
|
||||
}
|
||||
|
||||
static int size(lua_State *L)
|
||||
{
|
||||
memory_object_map<T> &self(usertype_container::get_self(L));
|
||||
return stack::push(L, self.map.size());
|
||||
}
|
||||
|
||||
static int empty(lua_State *L)
|
||||
{
|
||||
memory_object_map<T> &self(usertype_container::get_self(L));
|
||||
return stack::push(L, self.map.empty());
|
||||
}
|
||||
|
||||
static int next(lua_State *L) { return stack::push(L, next_pairs<false>); }
|
||||
static int pairs(lua_State *L) { return start_pairs<false>(L); }
|
||||
static int ipairs(lua_State *L) { return start_pairs<true>(L); }
|
||||
};
|
||||
|
||||
} // namespace sol
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// mem_read - templated memory readers for <sign>,<size>
|
||||
// -> manager:machine().devices[":maincpu"].spaces["program"]:read_i8(0xC000)
|
||||
@ -291,7 +423,7 @@ T lua_engine::addr_space::direct_mem_read(offs_t address)
|
||||
for (int i = 0; i < sizeof(T); i++)
|
||||
{
|
||||
int addr = space.endianness() == ENDIANNESS_LITTLE ? address + sizeof(T) - 1 - i : address + i;
|
||||
uint8_t *base = (uint8_t *)space.get_read_ptr(addr & ~lowmask);
|
||||
u8 *base = (u8 *)space.get_read_ptr(addr & ~lowmask);
|
||||
if (base)
|
||||
{
|
||||
if constexpr (sizeof(T) > 1)
|
||||
@ -318,7 +450,7 @@ void lua_engine::addr_space::direct_mem_write(offs_t address, T val)
|
||||
for (int i = 0; i < sizeof(T); i++)
|
||||
{
|
||||
int addr = space.endianness() == ENDIANNESS_BIG ? address + sizeof(T) - 1 - i : address + i;
|
||||
uint8_t *base = (uint8_t *)space.get_read_ptr(addr & ~lowmask);
|
||||
u8 *base = (u8 *)space.get_read_ptr(addr & ~lowmask);
|
||||
if (base)
|
||||
{
|
||||
if (space.endianness() == ENDIANNESS_BIG)
|
||||
@ -364,56 +496,61 @@ void lua_engine::initialize_memory()
|
||||
* space.map[] - table of address map entries (k=index, v=address_map_entry)
|
||||
*/
|
||||
|
||||
auto addr_space_type = sol().registry().new_usertype<addr_space>("addr_space", sol::call_constructor, sol::constructors<sol::types<address_space &, device_memory_interface &>>());
|
||||
addr_space_type.set("read_i8", &addr_space::mem_read<int8_t>);
|
||||
addr_space_type.set("read_u8", &addr_space::mem_read<uint8_t>);
|
||||
addr_space_type.set("read_i16", &addr_space::mem_read<int16_t>);
|
||||
addr_space_type.set("read_u16", &addr_space::mem_read<uint16_t>);
|
||||
addr_space_type.set("read_i32", &addr_space::mem_read<int32_t>);
|
||||
addr_space_type.set("read_u32", &addr_space::mem_read<uint32_t>);
|
||||
addr_space_type.set("read_i64", &addr_space::mem_read<int64_t>);
|
||||
addr_space_type.set("read_u64", &addr_space::mem_read<uint64_t>);
|
||||
addr_space_type.set("write_i8", &addr_space::mem_write<int8_t>);
|
||||
addr_space_type.set("write_u8", &addr_space::mem_write<uint8_t>);
|
||||
addr_space_type.set("write_i16", &addr_space::mem_write<int16_t>);
|
||||
addr_space_type.set("write_u16", &addr_space::mem_write<uint16_t>);
|
||||
addr_space_type.set("write_i32", &addr_space::mem_write<int32_t>);
|
||||
addr_space_type.set("write_u32", &addr_space::mem_write<uint32_t>);
|
||||
addr_space_type.set("write_i64", &addr_space::mem_write<int64_t>);
|
||||
addr_space_type.set("write_u64", &addr_space::mem_write<uint64_t>);
|
||||
addr_space_type.set("read_log_i8", &addr_space::log_mem_read<int8_t>);
|
||||
addr_space_type.set("read_log_u8", &addr_space::log_mem_read<uint8_t>);
|
||||
addr_space_type.set("read_log_i16", &addr_space::log_mem_read<int16_t>);
|
||||
addr_space_type.set("read_log_u16", &addr_space::log_mem_read<uint16_t>);
|
||||
addr_space_type.set("read_log_i32", &addr_space::log_mem_read<int32_t>);
|
||||
addr_space_type.set("read_log_u32", &addr_space::log_mem_read<uint32_t>);
|
||||
addr_space_type.set("read_log_i64", &addr_space::log_mem_read<int64_t>);
|
||||
addr_space_type.set("read_log_u64", &addr_space::log_mem_read<uint64_t>);
|
||||
addr_space_type.set("write_log_i8", &addr_space::log_mem_write<int8_t>);
|
||||
addr_space_type.set("write_log_u8", &addr_space::log_mem_write<uint8_t>);
|
||||
addr_space_type.set("write_log_i16", &addr_space::log_mem_write<int16_t>);
|
||||
addr_space_type.set("write_log_u16", &addr_space::log_mem_write<uint16_t>);
|
||||
addr_space_type.set("write_log_i32", &addr_space::log_mem_write<int32_t>);
|
||||
addr_space_type.set("write_log_u32", &addr_space::log_mem_write<uint32_t>);
|
||||
addr_space_type.set("write_log_i64", &addr_space::log_mem_write<int64_t>);
|
||||
addr_space_type.set("write_log_u64", &addr_space::log_mem_write<uint64_t>);
|
||||
addr_space_type.set("read_direct_i8", &addr_space::direct_mem_read<int8_t>);
|
||||
addr_space_type.set("read_direct_u8", &addr_space::direct_mem_read<uint8_t>);
|
||||
addr_space_type.set("read_direct_i16", &addr_space::direct_mem_read<int16_t>);
|
||||
addr_space_type.set("read_direct_u16", &addr_space::direct_mem_read<uint16_t>);
|
||||
addr_space_type.set("read_direct_i32", &addr_space::direct_mem_read<int32_t>);
|
||||
addr_space_type.set("read_direct_u32", &addr_space::direct_mem_read<uint32_t>);
|
||||
addr_space_type.set("read_direct_i64", &addr_space::direct_mem_read<int64_t>);
|
||||
addr_space_type.set("read_direct_u64", &addr_space::direct_mem_read<uint64_t>);
|
||||
addr_space_type.set("write_direct_i8", &addr_space::direct_mem_write<int8_t>);
|
||||
addr_space_type.set("write_direct_u8", &addr_space::direct_mem_write<uint8_t>);
|
||||
addr_space_type.set("write_direct_i16", &addr_space::direct_mem_write<int16_t>);
|
||||
addr_space_type.set("write_direct_u16", &addr_space::direct_mem_write<uint16_t>);
|
||||
addr_space_type.set("write_direct_i32", &addr_space::direct_mem_write<int32_t>);
|
||||
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) {
|
||||
auto addr_space_type = sol().registry().new_usertype<addr_space>(
|
||||
"addr_space",
|
||||
sol::call_constructor,
|
||||
sol::constructors<sol::types<address_space &, device_memory_interface &>>());
|
||||
addr_space_type["read_i8"] = &addr_space::mem_read<s8>;
|
||||
addr_space_type["read_u8"] = &addr_space::mem_read<u8>;
|
||||
addr_space_type["read_i16"] = &addr_space::mem_read<s16>;
|
||||
addr_space_type["read_u16"] = &addr_space::mem_read<u16>;
|
||||
addr_space_type["read_i32"] = &addr_space::mem_read<s32>;
|
||||
addr_space_type["read_u32"] = &addr_space::mem_read<u32>;
|
||||
addr_space_type["read_i64"] = &addr_space::mem_read<s64>;
|
||||
addr_space_type["read_u64"] = &addr_space::mem_read<u64>;
|
||||
addr_space_type["write_i8"] = &addr_space::mem_write<s8>;
|
||||
addr_space_type["write_u8"] = &addr_space::mem_write<u8>;
|
||||
addr_space_type["write_i16"] = &addr_space::mem_write<s16>;
|
||||
addr_space_type["write_u16"] = &addr_space::mem_write<u16>;
|
||||
addr_space_type["write_i32"] = &addr_space::mem_write<s32>;
|
||||
addr_space_type["write_u32"] = &addr_space::mem_write<u32>;
|
||||
addr_space_type["write_i64"] = &addr_space::mem_write<s64>;
|
||||
addr_space_type["write_u64"] = &addr_space::mem_write<u64>;
|
||||
addr_space_type["read_log_i8"] = &addr_space::log_mem_read<s8>;
|
||||
addr_space_type["read_log_u8"] = &addr_space::log_mem_read<u8>;
|
||||
addr_space_type["read_log_i16"] = &addr_space::log_mem_read<s16>;
|
||||
addr_space_type["read_log_u16"] = &addr_space::log_mem_read<u16>;
|
||||
addr_space_type["read_log_i32"] = &addr_space::log_mem_read<s32>;
|
||||
addr_space_type["read_log_u32"] = &addr_space::log_mem_read<u32>;
|
||||
addr_space_type["read_log_i64"] = &addr_space::log_mem_read<s64>;
|
||||
addr_space_type["read_log_u64"] = &addr_space::log_mem_read<u64>;
|
||||
addr_space_type["write_log_i8"] = &addr_space::log_mem_write<s8>;
|
||||
addr_space_type["write_log_u8"] = &addr_space::log_mem_write<u8>;
|
||||
addr_space_type["write_log_i16"] = &addr_space::log_mem_write<s16>;
|
||||
addr_space_type["write_log_u16"] = &addr_space::log_mem_write<u16>;
|
||||
addr_space_type["write_log_i32"] = &addr_space::log_mem_write<s32>;
|
||||
addr_space_type["write_log_u32"] = &addr_space::log_mem_write<u32>;
|
||||
addr_space_type["write_log_i64"] = &addr_space::log_mem_write<s64>;
|
||||
addr_space_type["write_log_u64"] = &addr_space::log_mem_write<u64>;
|
||||
addr_space_type["read_direct_i8"] = &addr_space::direct_mem_read<s8>;
|
||||
addr_space_type["read_direct_u8"] = &addr_space::direct_mem_read<u8>;
|
||||
addr_space_type["read_direct_i16"] = &addr_space::direct_mem_read<s16>;
|
||||
addr_space_type["read_direct_u16"] = &addr_space::direct_mem_read<u16>;
|
||||
addr_space_type["read_direct_i32"] = &addr_space::direct_mem_read<s32>;
|
||||
addr_space_type["read_direct_u32"] = &addr_space::direct_mem_read<u32>;
|
||||
addr_space_type["read_direct_i64"] = &addr_space::direct_mem_read<s64>;
|
||||
addr_space_type["read_direct_u64"] = &addr_space::direct_mem_read<u64>;
|
||||
addr_space_type["write_direct_i8"] = &addr_space::direct_mem_write<s8>;
|
||||
addr_space_type["write_direct_u8"] = &addr_space::direct_mem_write<u8>;
|
||||
addr_space_type["write_direct_i16"] = &addr_space::direct_mem_write<s16>;
|
||||
addr_space_type["write_direct_u16"] = &addr_space::direct_mem_write<u16>;
|
||||
addr_space_type["write_direct_i32"] = &addr_space::direct_mem_write<s32>;
|
||||
addr_space_type["write_direct_u32"] = &addr_space::direct_mem_write<u32>;
|
||||
addr_space_type["write_direct_i64"] = &addr_space::direct_mem_write<s64>;
|
||||
addr_space_type["write_direct_u64"] = &addr_space::direct_mem_write<u64>;
|
||||
addr_space_type["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();
|
||||
@ -436,58 +573,46 @@ void lua_engine::initialize_memory()
|
||||
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;
|
||||
}
|
||||
{
|
||||
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;
|
||||
}
|
||||
{
|
||||
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;
|
||||
}
|
||||
{
|
||||
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;
|
||||
}
|
||||
{
|
||||
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(); }));
|
||||
addr_space_type.set("address_mask", sol::property([](addr_space &sp) { return sp.space.addrmask(); }));
|
||||
addr_space_type.set("data_width", sol::property([](addr_space &sp) { return sp.space.data_width(); }));
|
||||
addr_space_type.set("endianness", sol::property([](addr_space &sp) {
|
||||
std::string endianness;
|
||||
switch (sp.space.endianness())
|
||||
{
|
||||
case endianness_t::ENDIANNESS_BIG:
|
||||
endianness = "big";
|
||||
break;
|
||||
case endianness_t::ENDIANNESS_LITTLE:
|
||||
endianness = "little";
|
||||
break;
|
||||
}
|
||||
return endianness;
|
||||
}));
|
||||
};
|
||||
addr_space_type["name"] = sol::property([] (addr_space &sp) { return sp.space.name(); });
|
||||
addr_space_type["shift"] = sol::property([] (addr_space &sp) { return sp.space.addr_shift(); });
|
||||
addr_space_type["index"] = sol::property([] (addr_space &sp) { return sp.space.spacenum(); });
|
||||
addr_space_type["address_mask"] = sol::property([] (addr_space &sp) { return sp.space.addrmask(); });
|
||||
addr_space_type["data_width"] = sol::property([] (addr_space &sp) { return sp.space.data_width(); });
|
||||
addr_space_type["endianness"] = sol::property([] (addr_space &sp) { return get_endianness_name(sp.space); });
|
||||
|
||||
|
||||
/* address_map_entry library
|
||||
@ -499,20 +624,22 @@ void lua_engine::initialize_memory()
|
||||
* mapentry.readtype
|
||||
* mapentry.writetype
|
||||
*/
|
||||
addr_space_type.set("map", sol::property([this](addr_space &sp) {
|
||||
address_space &space = sp.space;
|
||||
sol::table map = sol().create_table();
|
||||
for (address_map_entry &entry : space.map()->m_entrylist)
|
||||
addr_space_type["map"] = sol::property(
|
||||
[this] (addr_space &sp)
|
||||
{
|
||||
sol::table mapentry = sol().create_table();
|
||||
mapentry["offset"] = entry.m_addrstart & space.addrmask();
|
||||
mapentry["endoff"] = entry.m_addrend & space.addrmask();
|
||||
mapentry["readtype"] = entry.m_read.m_type;
|
||||
mapentry["writetype"] = entry.m_write.m_type;
|
||||
map.add(mapentry);
|
||||
}
|
||||
return map;
|
||||
}));
|
||||
address_space &space = sp.space;
|
||||
sol::table map = sol().create_table();
|
||||
for (address_map_entry &entry : space.map()->m_entrylist)
|
||||
{
|
||||
sol::table mapentry = sol().create_table();
|
||||
mapentry["offset"] = entry.m_addrstart & space.addrmask();
|
||||
mapentry["endoff"] = entry.m_addrend & space.addrmask();
|
||||
mapentry["readtype"] = entry.m_read.m_type;
|
||||
mapentry["writetype"] = entry.m_write.m_type;
|
||||
map.add(mapentry);
|
||||
}
|
||||
return map;
|
||||
});
|
||||
|
||||
|
||||
/* memory_manager library
|
||||
@ -524,25 +651,23 @@ void lua_engine::initialize_memory()
|
||||
* memory.shares[] - table of memory shares (k=tag, v=memory_share)
|
||||
*/
|
||||
|
||||
auto memory_type = sol().registry().new_usertype<memory_manager>("memory", "new", sol::no_constructor);
|
||||
memory_type.set("banks", sol::property([this](memory_manager &mm) {
|
||||
sol::table table = sol().create_table();
|
||||
for (auto &bank : mm.banks())
|
||||
table[bank.second->tag()] = bank.second.get();
|
||||
return table;
|
||||
}));
|
||||
memory_type.set("regions", sol::property([this](memory_manager &mm) {
|
||||
sol::table table = sol().create_table();
|
||||
for (auto ®ion : mm.regions())
|
||||
table[region.second->name()] = region.second.get();
|
||||
return table;
|
||||
}));
|
||||
memory_type.set("shares", sol::property([this](memory_manager &mm) {
|
||||
sol::table table = sol().create_table();
|
||||
for (auto &share : mm.shares())
|
||||
table[share.first] = share.second.get();
|
||||
return table;
|
||||
}));
|
||||
auto memory_type = sol().registry().new_usertype<memory_manager>("memory", sol::no_constructor);
|
||||
memory_type["banks"] = sol::property([] (memory_manager &mm) { return standard_memory_object_map<memory_bank>(mm.banks()); });
|
||||
memory_type["regions"] = sol::property([] (memory_manager &mm) { return standard_memory_object_map<memory_region>(mm.regions()); });
|
||||
memory_type["shares"] = sol::property([] (memory_manager &mm) { return standard_memory_object_map<memory_share>(mm.shares()); });
|
||||
|
||||
|
||||
/* memory_bank library
|
||||
*
|
||||
* manager:machine():memory().banks[bank_tag]
|
||||
*
|
||||
* region.tag - absolute tag of the bank
|
||||
* bank.entry - get/set the selected entry
|
||||
*/
|
||||
|
||||
auto bank_type = sol().registry().new_usertype<memory_bank>("membank", sol::no_constructor);
|
||||
bank_type["tag"] = sol::property(&memory_bank::tag);
|
||||
bank_type["entry"] = sol::property(&memory_bank::entry, &memory_bank::set_entry);
|
||||
|
||||
|
||||
/* memory_region library
|
||||
@ -553,27 +678,37 @@ void lua_engine::initialize_memory()
|
||||
* region:read_*(addr)
|
||||
* region:write_*(addr, val)
|
||||
*
|
||||
* region.size
|
||||
* region.tag - absolute tag of the region
|
||||
* region.size - size in bytes
|
||||
* region.length - length in items
|
||||
* region.endianness - endiannes as string ("big" or "little")
|
||||
* region.bitwidth - item width in bits
|
||||
* region.bytewidth - item width in bytes
|
||||
*/
|
||||
|
||||
auto region_type = sol().registry().new_usertype<memory_region>("region", "new", sol::no_constructor);
|
||||
region_type.set("read_i8", ®ion_read<int8_t>);
|
||||
region_type.set("read_u8", ®ion_read<uint8_t>);
|
||||
region_type.set("read_i16", ®ion_read<int16_t>);
|
||||
region_type.set("read_u16", ®ion_read<uint16_t>);
|
||||
region_type.set("read_i32", ®ion_read<int32_t>);
|
||||
region_type.set("read_u32", ®ion_read<uint32_t>);
|
||||
region_type.set("read_i64", ®ion_read<int64_t>);
|
||||
region_type.set("read_u64", ®ion_read<uint64_t>);
|
||||
region_type.set("write_i8", ®ion_write<int8_t>);
|
||||
region_type.set("write_u8", ®ion_write<uint8_t>);
|
||||
region_type.set("write_i16", ®ion_write<int16_t>);
|
||||
region_type.set("write_u16", ®ion_write<uint16_t>);
|
||||
region_type.set("write_i32", ®ion_write<int32_t>);
|
||||
region_type.set("write_u32", ®ion_write<uint32_t>);
|
||||
region_type.set("write_i64", ®ion_write<int64_t>);
|
||||
region_type.set("write_u64", ®ion_write<uint64_t>);
|
||||
region_type.set("size", sol::property(&memory_region::bytes));
|
||||
auto region_type = sol().registry().new_usertype<memory_region>("region", sol::no_constructor);
|
||||
region_type["read_i8"] = ®ion_read<s8>;
|
||||
region_type["read_u8"] = ®ion_read<u8>;
|
||||
region_type["read_i16"] = ®ion_read<s16>;
|
||||
region_type["read_u16"] = ®ion_read<u16>;
|
||||
region_type["read_i32"] = ®ion_read<s32>;
|
||||
region_type["read_u32"] = ®ion_read<u32>;
|
||||
region_type["read_i64"] = ®ion_read<s64>;
|
||||
region_type["read_u64"] = ®ion_read<u64>;
|
||||
region_type["write_i8"] = ®ion_write<s8>;
|
||||
region_type["write_u8"] = ®ion_write<u8>;
|
||||
region_type["write_i16"] = ®ion_write<s16>;
|
||||
region_type["write_u16"] = ®ion_write<u16>;
|
||||
region_type["write_i32"] = ®ion_write<s32>;
|
||||
region_type["write_u32"] = ®ion_write<u32>;
|
||||
region_type["write_i64"] = ®ion_write<s64>;
|
||||
region_type["write_u64"] = ®ion_write<u64>;
|
||||
region_type["tag"] = sol::property(&memory_region::name);
|
||||
region_type["size"] = sol::property(&memory_region::bytes);
|
||||
region_type["length"] = sol::property([] (memory_region &r) { return r.bytes() / r.bytewidth(); });
|
||||
region_type["endianness"] = sol::property(&get_endianness_name<memory_region>);
|
||||
region_type["bitwidth"] = sol::property(&memory_region::bitwidth);
|
||||
region_type["bytewidth"] = sol::property(&memory_region::bytewidth);
|
||||
|
||||
|
||||
/* memory_share library
|
||||
@ -584,26 +719,36 @@ void lua_engine::initialize_memory()
|
||||
* share:read_*(addr)
|
||||
* share:write_*(addr, val)
|
||||
*
|
||||
* region.size
|
||||
* share.tag - absolute tag of the share
|
||||
* share.size - size in bytes
|
||||
* share.length - length in items
|
||||
* region.endianness - endiannes as string ("big" or "little")
|
||||
* share.bitwidth - item width in bits
|
||||
* share.bytewidth - item width in bytes
|
||||
*/
|
||||
|
||||
auto share_type = sol().registry().new_usertype<memory_share>("share", "new", sol::no_constructor);
|
||||
share_type.set("read_i8", &share_read<int8_t>);
|
||||
share_type.set("read_u8", &share_read<uint8_t>);
|
||||
share_type.set("read_i16", &share_read<int16_t>);
|
||||
share_type.set("read_u16", &share_read<uint16_t>);
|
||||
share_type.set("read_i32", &share_read<int32_t>);
|
||||
share_type.set("read_u32", &share_read<uint32_t>);
|
||||
share_type.set("read_i64", &share_read<int64_t>);
|
||||
share_type.set("read_u64", &share_read<uint64_t>);
|
||||
share_type.set("write_i8", &share_write<int8_t>);
|
||||
share_type.set("write_u8", &share_write<uint8_t>);
|
||||
share_type.set("write_i16", &share_write<int16_t>);
|
||||
share_type.set("write_u16", &share_write<uint16_t>);
|
||||
share_type.set("write_i32", &share_write<int32_t>);
|
||||
share_type.set("write_u32", &share_write<uint32_t>);
|
||||
share_type.set("write_i64", &share_write<int64_t>);
|
||||
share_type.set("write_u64", &share_write<uint64_t>);
|
||||
share_type.set("size", sol::property(&memory_share::bytes));
|
||||
auto share_type = sol().registry().new_usertype<memory_share>("share", sol::no_constructor);
|
||||
share_type["read_i8"] = &share_read<s8>;
|
||||
share_type["read_u8"] = &share_read<u8>;
|
||||
share_type["read_i16"] = &share_read<s16>;
|
||||
share_type["read_u16"] = &share_read<u16>;
|
||||
share_type["read_i32"] = &share_read<s32>;
|
||||
share_type["read_u32"] = &share_read<u32>;
|
||||
share_type["read_i64"] = &share_read<s64>;
|
||||
share_type["read_u64"] = &share_read<u64>;
|
||||
share_type["write_i8"] = &share_write<s8>;
|
||||
share_type["write_u8"] = &share_write<u8>;
|
||||
share_type["write_i16"] = &share_write<s16>;
|
||||
share_type["write_u16"] = &share_write<u16>;
|
||||
share_type["write_i32"] = &share_write<s32>;
|
||||
share_type["write_u32"] = &share_write<u32>;
|
||||
share_type["write_i64"] = &share_write<s64>;
|
||||
share_type["write_u64"] = &share_write<u64>;
|
||||
share_type["tag"] = sol::property(&memory_share::name);
|
||||
share_type["size"] = sol::property(&memory_share::bytes);
|
||||
share_type["length"] = sol::property([] (memory_share &s) { return s.bytes() / s.bytewidth(); });
|
||||
share_type["endianness"] = sol::property(&get_endianness_name<memory_share>);
|
||||
share_type["bitwidth"] = sol::property(&memory_share::bitwidth);
|
||||
share_type["bytewidth"] = sol::property(&memory_share::bytewidth);
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user