Scatter-gather value read/write

This commit is contained in:
Ilari Liusvaara 2013-09-15 18:02:58 +03:00
parent 982c617a4d
commit a6c13a7c9d
3 changed files with 76 additions and 0 deletions

42
lua.lyx
View file

@ -3495,6 +3495,48 @@ Read/Write value from/to given VMA <vma> at given offset <offset> (must
's' signifies that value is treated as signed (not available for floating-point).
\end_layout
\begin_layout Subsection
memory2.<vma>:read: Scatter-gather value read
\end_layout
\begin_layout Itemize
Syntax: number memory2.<vma>:read(number addr...)
\end_layout
\begin_layout Standard
Read value from given VMA <vma> at byte offsets <addr>..., given in order of
increasing significance.
Value of true and false are special.
True increments address by 1, and false decrements address by 1.
\end_layout
\begin_layout Subsection
memory2.<vma>:sread: Signed scatter-gather value read
\end_layout
\begin_layout Itemize
Syntax: number memory2.<vma>:sread(number addr...)
\end_layout
\begin_layout Standard
Like memory2.<vma>:read, but reads signed values.
\end_layout
\begin_layout Subsection
memory2.<vma>:write: Scatter-gather value write
\end_layout
\begin_layout Itemize
Syntax: number memory2.<vma>:write(number val, number addr...)
\end_layout
\begin_layout Standard
Write value <val> to given VMA <vma> at byte offsets <addr>..., given in order
of increasing significance.
Value of true and false are special.
True increments address by 1, and false decrements address by 1.
\end_layout
\begin_layout Standard
\begin_inset Newpage pagebreak
\end_inset

BIN
lua.pdf

Binary file not shown.

View file

@ -52,6 +52,7 @@ namespace
lua_vma(lua_state& L, memory_region* r);
int info(lua_state& L, const std::string& fname);
template<class T, bool _bswap> int rw(lua_state& L, const std::string& fname);
template<bool write, bool sign> int scattergather(lua_state& L, const std::string& fname);
private:
std::string vma;
uint64_t vmabase;
@ -78,6 +79,9 @@ namespace
{
objclass<lua_vma>().bind_multi(L, {
{"info", &lua_vma::info},
{"read", &lua_vma::scattergather<false, false>},
{"sread", &lua_vma::scattergather<false, true>},
{"write", &lua_vma::scattergather<true, false>},
{"sbyte", &lua_vma::rw<int8_t, false>},
{"byte", &lua_vma::rw<uint8_t, false>},
{"sword", &lua_vma::rw<int16_t, false>},
@ -140,6 +144,36 @@ namespace
(stringfmt() << fname << ": Parameter #3 must be integer if present").throwex();
}
template<bool write, bool sign> int lua_vma::scattergather(lua_state& L, const std::string& fname)
{
uint64_t val = 0;
int ptr = 2;
unsigned shift = 0;
uint64_t addr = 0;
if(write)
val = L.get_numeric_argument<uint64_t>(ptr++, fname.c_str());
while(L.type(ptr) != LUA_TNIL && L.type(ptr) != LUA_TNONE) {
if(L.type(ptr) == LUA_TBOOLEAN) {
if(L.toboolean(ptr++))
addr++;
else
addr--;
} else
addr = L.get_numeric_argument<uint64_t>(ptr++, fname.c_str());
if(write)
lsnes_memory.write<uint8_t>(addr + vmabase, val >> shift);
else
val = val + ((uint64_t)lsnes_memory.read<uint8_t>(addr + vmabase) << shift);
shift += 8;
}
if(!write) {
int64_t sval = val;
if(val >= (1ULL << (shift - 1))) sval -= (1ULL << shift);
if(sign) L.pushnumber(sval); else L.pushnumber(val);
}
return write ? 0 : 1;
}
lua_vma_list::lua_vma_list(lua_state& L)
{
objclass<lua_vma_list>().bind_multi(L, {