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:
Vas Crabb 2020-11-29 19:09:48 +11:00
parent a3a7129197
commit 738b60d531

View File

@ -14,6 +14,35 @@
namespace { namespace {
template <typename T>
struct memory_object_map
{
memory_object_map(T const &m) : map(m) { }
T const &map;
};
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> // region_read - templated region readers for <sign>,<size>
// -> manager:machine():memory().regions[":maincpu"]:read_i8(0xC000) // -> 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; T mem_content = 0;
const offs_t lowmask = share.bytewidth() - 1; 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++) for (int i = 0; i < sizeof(T); i++)
{ {
int addr = share.endianness() == ENDIANNESS_LITTLE ? address + sizeof(T) - 1 - i : address + 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) void share_write(memory_share &share, offs_t address, T val)
{ {
const offs_t lowmask = share.bytewidth() - 1; 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++) for (int i = 0; i < sizeof(T); i++)
{ {
int addr = share.endianness() == ENDIANNESS_BIG ? address + sizeof(T) - 1 - i : address + 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> // mem_read - templated memory readers for <sign>,<size>
// -> manager:machine().devices[":maincpu"].spaces["program"]:read_i8(0xC000) // -> 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++) for (int i = 0; i < sizeof(T); i++)
{ {
int addr = space.endianness() == ENDIANNESS_LITTLE ? address + sizeof(T) - 1 - i : address + 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 (base)
{ {
if constexpr (sizeof(T) > 1) 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++) for (int i = 0; i < sizeof(T); i++)
{ {
int addr = space.endianness() == ENDIANNESS_BIG ? address + sizeof(T) - 1 - i : address + 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 (base)
{ {
if (space.endianness() == ENDIANNESS_BIG) 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) * 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 &>>()); auto addr_space_type = sol().registry().new_usertype<addr_space>(
addr_space_type.set("read_i8", &addr_space::mem_read<int8_t>); "addr_space",
addr_space_type.set("read_u8", &addr_space::mem_read<uint8_t>); sol::call_constructor,
addr_space_type.set("read_i16", &addr_space::mem_read<int16_t>); sol::constructors<sol::types<address_space &, device_memory_interface &>>());
addr_space_type.set("read_u16", &addr_space::mem_read<uint16_t>); addr_space_type["read_i8"] = &addr_space::mem_read<s8>;
addr_space_type.set("read_i32", &addr_space::mem_read<int32_t>); addr_space_type["read_u8"] = &addr_space::mem_read<u8>;
addr_space_type.set("read_u32", &addr_space::mem_read<uint32_t>); addr_space_type["read_i16"] = &addr_space::mem_read<s16>;
addr_space_type.set("read_i64", &addr_space::mem_read<int64_t>); addr_space_type["read_u16"] = &addr_space::mem_read<u16>;
addr_space_type.set("read_u64", &addr_space::mem_read<uint64_t>); addr_space_type["read_i32"] = &addr_space::mem_read<s32>;
addr_space_type.set("write_i8", &addr_space::mem_write<int8_t>); addr_space_type["read_u32"] = &addr_space::mem_read<u32>;
addr_space_type.set("write_u8", &addr_space::mem_write<uint8_t>); addr_space_type["read_i64"] = &addr_space::mem_read<s64>;
addr_space_type.set("write_i16", &addr_space::mem_write<int16_t>); addr_space_type["read_u64"] = &addr_space::mem_read<u64>;
addr_space_type.set("write_u16", &addr_space::mem_write<uint16_t>); addr_space_type["write_i8"] = &addr_space::mem_write<s8>;
addr_space_type.set("write_i32", &addr_space::mem_write<int32_t>); addr_space_type["write_u8"] = &addr_space::mem_write<u8>;
addr_space_type.set("write_u32", &addr_space::mem_write<uint32_t>); addr_space_type["write_i16"] = &addr_space::mem_write<s16>;
addr_space_type.set("write_i64", &addr_space::mem_write<int64_t>); addr_space_type["write_u16"] = &addr_space::mem_write<u16>;
addr_space_type.set("write_u64", &addr_space::mem_write<uint64_t>); addr_space_type["write_i32"] = &addr_space::mem_write<s32>;
addr_space_type.set("read_log_i8", &addr_space::log_mem_read<int8_t>); addr_space_type["write_u32"] = &addr_space::mem_write<u32>;
addr_space_type.set("read_log_u8", &addr_space::log_mem_read<uint8_t>); addr_space_type["write_i64"] = &addr_space::mem_write<s64>;
addr_space_type.set("read_log_i16", &addr_space::log_mem_read<int16_t>); addr_space_type["write_u64"] = &addr_space::mem_write<u64>;
addr_space_type.set("read_log_u16", &addr_space::log_mem_read<uint16_t>); addr_space_type["read_log_i8"] = &addr_space::log_mem_read<s8>;
addr_space_type.set("read_log_i32", &addr_space::log_mem_read<int32_t>); addr_space_type["read_log_u8"] = &addr_space::log_mem_read<u8>;
addr_space_type.set("read_log_u32", &addr_space::log_mem_read<uint32_t>); addr_space_type["read_log_i16"] = &addr_space::log_mem_read<s16>;
addr_space_type.set("read_log_i64", &addr_space::log_mem_read<int64_t>); addr_space_type["read_log_u16"] = &addr_space::log_mem_read<u16>;
addr_space_type.set("read_log_u64", &addr_space::log_mem_read<uint64_t>); addr_space_type["read_log_i32"] = &addr_space::log_mem_read<s32>;
addr_space_type.set("write_log_i8", &addr_space::log_mem_write<int8_t>); addr_space_type["read_log_u32"] = &addr_space::log_mem_read<u32>;
addr_space_type.set("write_log_u8", &addr_space::log_mem_write<uint8_t>); addr_space_type["read_log_i64"] = &addr_space::log_mem_read<s64>;
addr_space_type.set("write_log_i16", &addr_space::log_mem_write<int16_t>); addr_space_type["read_log_u64"] = &addr_space::log_mem_read<u64>;
addr_space_type.set("write_log_u16", &addr_space::log_mem_write<uint16_t>); addr_space_type["write_log_i8"] = &addr_space::log_mem_write<s8>;
addr_space_type.set("write_log_i32", &addr_space::log_mem_write<int32_t>); addr_space_type["write_log_u8"] = &addr_space::log_mem_write<u8>;
addr_space_type.set("write_log_u32", &addr_space::log_mem_write<uint32_t>); addr_space_type["write_log_i16"] = &addr_space::log_mem_write<s16>;
addr_space_type.set("write_log_i64", &addr_space::log_mem_write<int64_t>); addr_space_type["write_log_u16"] = &addr_space::log_mem_write<u16>;
addr_space_type.set("write_log_u64", &addr_space::log_mem_write<uint64_t>); addr_space_type["write_log_i32"] = &addr_space::log_mem_write<s32>;
addr_space_type.set("read_direct_i8", &addr_space::direct_mem_read<int8_t>); addr_space_type["write_log_u32"] = &addr_space::log_mem_write<u32>;
addr_space_type.set("read_direct_u8", &addr_space::direct_mem_read<uint8_t>); addr_space_type["write_log_i64"] = &addr_space::log_mem_write<s64>;
addr_space_type.set("read_direct_i16", &addr_space::direct_mem_read<int16_t>); addr_space_type["write_log_u64"] = &addr_space::log_mem_write<u64>;
addr_space_type.set("read_direct_u16", &addr_space::direct_mem_read<uint16_t>); addr_space_type["read_direct_i8"] = &addr_space::direct_mem_read<s8>;
addr_space_type.set("read_direct_i32", &addr_space::direct_mem_read<int32_t>); addr_space_type["read_direct_u8"] = &addr_space::direct_mem_read<u8>;
addr_space_type.set("read_direct_u32", &addr_space::direct_mem_read<uint32_t>); addr_space_type["read_direct_i16"] = &addr_space::direct_mem_read<s16>;
addr_space_type.set("read_direct_i64", &addr_space::direct_mem_read<int64_t>); addr_space_type["read_direct_u16"] = &addr_space::direct_mem_read<u16>;
addr_space_type.set("read_direct_u64", &addr_space::direct_mem_read<uint64_t>); addr_space_type["read_direct_i32"] = &addr_space::direct_mem_read<s32>;
addr_space_type.set("write_direct_i8", &addr_space::direct_mem_write<int8_t>); addr_space_type["read_direct_u32"] = &addr_space::direct_mem_read<u32>;
addr_space_type.set("write_direct_u8", &addr_space::direct_mem_write<uint8_t>); addr_space_type["read_direct_i64"] = &addr_space::direct_mem_read<s64>;
addr_space_type.set("write_direct_i16", &addr_space::direct_mem_write<int16_t>); addr_space_type["read_direct_u64"] = &addr_space::direct_mem_read<u64>;
addr_space_type.set("write_direct_u16", &addr_space::direct_mem_write<uint16_t>); addr_space_type["write_direct_i8"] = &addr_space::direct_mem_write<s8>;
addr_space_type.set("write_direct_i32", &addr_space::direct_mem_write<int32_t>); addr_space_type["write_direct_u8"] = &addr_space::direct_mem_write<u8>;
addr_space_type.set("write_direct_u32", &addr_space::direct_mem_write<uint32_t>); addr_space_type["write_direct_i16"] = &addr_space::direct_mem_write<s16>;
addr_space_type.set("write_direct_i64", &addr_space::direct_mem_write<int64_t>); addr_space_type["write_direct_u16"] = &addr_space::direct_mem_write<u16>;
addr_space_type.set("write_direct_u64", &addr_space::direct_mem_write<uint64_t>); addr_space_type["write_direct_i32"] = &addr_space::direct_mem_write<s32>;
addr_space_type.set("read_range", [](addr_space &sp, sol::this_state s, u64 first, u64 last, int width, sol::object opt_step) { 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; lua_State *L = s;
luaL_Buffer buff; luaL_Buffer buff;
offs_t space_size = sp.space.addrmask(); offs_t space_size = sp.space.addrmask();
@ -436,58 +573,46 @@ void lua_engine::initialize_memory()
switch (width) switch (width)
{ {
case 8: case 8:
{ {
u8 *dest = (u8 *)luaL_buffinitsize(L, &buff, byte_count); u8 *dest = (u8 *)luaL_buffinitsize(L, &buff, byte_count);
for(; first <= last; first += step) for ( ; first <= last; first += step)
*dest++ = sp.mem_read<u8>(first); *dest++ = sp.mem_read<u8>(first);
break; break;
} }
case 16: case 16:
{ {
u16 *dest = (u16 *)luaL_buffinitsize(L, &buff, byte_count); u16 *dest = (u16 *)luaL_buffinitsize(L, &buff, byte_count);
for(; first <= last; first += step) for ( ; first <= last; first += step)
*dest++ = sp.mem_read<u16>(first); *dest++ = sp.mem_read<u16>(first);
break; break;
} }
case 32: case 32:
{ {
u32 *dest = (u32 *)luaL_buffinitsize(L, &buff, byte_count); u32 *dest = (u32 *)luaL_buffinitsize(L, &buff, byte_count);
for(; first <= last; first += step) for(; first <= last; first += step)
*dest++ = sp.mem_read<u32>(first); *dest++ = sp.mem_read<u32>(first);
break; break;
} }
case 64: case 64:
{ {
u64 *dest = (u64 *)luaL_buffinitsize(L, &buff, byte_count); u64 *dest = (u64 *)luaL_buffinitsize(L, &buff, byte_count);
for(; first <= last; first += step) for(; first <= last; first += step)
*dest++ = sp.mem_read<u64>(first); *dest++ = sp.mem_read<u64>(first);
break; break;
} }
default: default:
luaL_error(L, "Invalid width. Must be 8/16/32/64"); luaL_error(L, "Invalid width. Must be 8/16/32/64");
return sol::make_reference(L, nullptr); return sol::make_reference(L, nullptr);
} }
luaL_pushresultsize(&buff, byte_count); luaL_pushresultsize(&buff, byte_count);
return sol::make_reference(L, sol::stack_reference(L, -1)); 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["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["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["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["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["data_width"] = sol::property([] (addr_space &sp) { return sp.space.data_width(); });
addr_space_type.set("endianness", sol::property([](addr_space &sp) { addr_space_type["endianness"] = sol::property([] (addr_space &sp) { return get_endianness_name(sp.space); });
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;
}));
/* address_map_entry library /* address_map_entry library
@ -499,20 +624,22 @@ void lua_engine::initialize_memory()
* mapentry.readtype * mapentry.readtype
* mapentry.writetype * mapentry.writetype
*/ */
addr_space_type.set("map", sol::property([this](addr_space &sp) { addr_space_type["map"] = sol::property(
address_space &space = sp.space; [this] (addr_space &sp)
sol::table map = sol().create_table();
for (address_map_entry &entry : space.map()->m_entrylist)
{ {
sol::table mapentry = sol().create_table(); address_space &space = sp.space;
mapentry["offset"] = entry.m_addrstart & space.addrmask(); sol::table map = sol().create_table();
mapentry["endoff"] = entry.m_addrend & space.addrmask(); for (address_map_entry &entry : space.map()->m_entrylist)
mapentry["readtype"] = entry.m_read.m_type; {
mapentry["writetype"] = entry.m_write.m_type; sol::table mapentry = sol().create_table();
map.add(mapentry); mapentry["offset"] = entry.m_addrstart & space.addrmask();
} mapentry["endoff"] = entry.m_addrend & space.addrmask();
return map; mapentry["readtype"] = entry.m_read.m_type;
})); mapentry["writetype"] = entry.m_write.m_type;
map.add(mapentry);
}
return map;
});
/* memory_manager library /* memory_manager library
@ -524,25 +651,23 @@ void lua_engine::initialize_memory()
* memory.shares[] - table of memory shares (k=tag, v=memory_share) * 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); auto memory_type = sol().registry().new_usertype<memory_manager>("memory", sol::no_constructor);
memory_type.set("banks", sol::property([this](memory_manager &mm) { memory_type["banks"] = sol::property([] (memory_manager &mm) { return standard_memory_object_map<memory_bank>(mm.banks()); });
sol::table table = sol().create_table(); memory_type["regions"] = sol::property([] (memory_manager &mm) { return standard_memory_object_map<memory_region>(mm.regions()); });
for (auto &bank : mm.banks()) memory_type["shares"] = sol::property([] (memory_manager &mm) { return standard_memory_object_map<memory_share>(mm.shares()); });
table[bank.second->tag()] = bank.second.get();
return table;
})); /* memory_bank library
memory_type.set("regions", sol::property([this](memory_manager &mm) { *
sol::table table = sol().create_table(); * manager:machine():memory().banks[bank_tag]
for (auto &region : mm.regions()) *
table[region.second->name()] = region.second.get(); * region.tag - absolute tag of the bank
return table; * bank.entry - get/set the selected entry
})); */
memory_type.set("shares", sol::property([this](memory_manager &mm) {
sol::table table = sol().create_table(); auto bank_type = sol().registry().new_usertype<memory_bank>("membank", sol::no_constructor);
for (auto &share : mm.shares()) bank_type["tag"] = sol::property(&memory_bank::tag);
table[share.first] = share.second.get(); bank_type["entry"] = sol::property(&memory_bank::entry, &memory_bank::set_entry);
return table;
}));
/* memory_region library /* memory_region library
@ -553,27 +678,37 @@ void lua_engine::initialize_memory()
* region:read_*(addr) * region:read_*(addr)
* region:write_*(addr, val) * 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); auto region_type = sol().registry().new_usertype<memory_region>("region", sol::no_constructor);
region_type.set("read_i8", &region_read<int8_t>); region_type["read_i8"] = &region_read<s8>;
region_type.set("read_u8", &region_read<uint8_t>); region_type["read_u8"] = &region_read<u8>;
region_type.set("read_i16", &region_read<int16_t>); region_type["read_i16"] = &region_read<s16>;
region_type.set("read_u16", &region_read<uint16_t>); region_type["read_u16"] = &region_read<u16>;
region_type.set("read_i32", &region_read<int32_t>); region_type["read_i32"] = &region_read<s32>;
region_type.set("read_u32", &region_read<uint32_t>); region_type["read_u32"] = &region_read<u32>;
region_type.set("read_i64", &region_read<int64_t>); region_type["read_i64"] = &region_read<s64>;
region_type.set("read_u64", &region_read<uint64_t>); region_type["read_u64"] = &region_read<u64>;
region_type.set("write_i8", &region_write<int8_t>); region_type["write_i8"] = &region_write<s8>;
region_type.set("write_u8", &region_write<uint8_t>); region_type["write_u8"] = &region_write<u8>;
region_type.set("write_i16", &region_write<int16_t>); region_type["write_i16"] = &region_write<s16>;
region_type.set("write_u16", &region_write<uint16_t>); region_type["write_u16"] = &region_write<u16>;
region_type.set("write_i32", &region_write<int32_t>); region_type["write_i32"] = &region_write<s32>;
region_type.set("write_u32", &region_write<uint32_t>); region_type["write_u32"] = &region_write<u32>;
region_type.set("write_i64", &region_write<int64_t>); region_type["write_i64"] = &region_write<s64>;
region_type.set("write_u64", &region_write<uint64_t>); region_type["write_u64"] = &region_write<u64>;
region_type.set("size", sol::property(&memory_region::bytes)); 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 /* memory_share library
@ -584,26 +719,36 @@ void lua_engine::initialize_memory()
* share:read_*(addr) * share:read_*(addr)
* share:write_*(addr, val) * 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); auto share_type = sol().registry().new_usertype<memory_share>("share", sol::no_constructor);
share_type.set("read_i8", &share_read<int8_t>); share_type["read_i8"] = &share_read<s8>;
share_type.set("read_u8", &share_read<uint8_t>); share_type["read_u8"] = &share_read<u8>;
share_type.set("read_i16", &share_read<int16_t>); share_type["read_i16"] = &share_read<s16>;
share_type.set("read_u16", &share_read<uint16_t>); share_type["read_u16"] = &share_read<u16>;
share_type.set("read_i32", &share_read<int32_t>); share_type["read_i32"] = &share_read<s32>;
share_type.set("read_u32", &share_read<uint32_t>); share_type["read_u32"] = &share_read<u32>;
share_type.set("read_i64", &share_read<int64_t>); share_type["read_i64"] = &share_read<s64>;
share_type.set("read_u64", &share_read<uint64_t>); share_type["read_u64"] = &share_read<u64>;
share_type.set("write_i8", &share_write<int8_t>); share_type["write_i8"] = &share_write<s8>;
share_type.set("write_u8", &share_write<uint8_t>); share_type["write_u8"] = &share_write<u8>;
share_type.set("write_i16", &share_write<int16_t>); share_type["write_i16"] = &share_write<s16>;
share_type.set("write_u16", &share_write<uint16_t>); share_type["write_u16"] = &share_write<u16>;
share_type.set("write_i32", &share_write<int32_t>); share_type["write_i32"] = &share_write<s32>;
share_type.set("write_u32", &share_write<uint32_t>); share_type["write_u32"] = &share_write<u32>;
share_type.set("write_i64", &share_write<int64_t>); share_type["write_i64"] = &share_write<s64>;
share_type.set("write_u64", &share_write<uint64_t>); share_type["write_u64"] = &share_write<u64>;
share_type.set("size", sol::property(&memory_share::bytes)); 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);
} }