diff --git a/lua.lyx b/lua.lyx index 939c57e6..405072a3 100644 --- a/lua.lyx +++ b/lua.lyx @@ -3326,51 +3326,66 @@ Reads the specified address
(if 's' variant is used, do undergo \end_layout \begin_layout Subsection -memory.read{,s}{byte,{,h,d,q}word}: Read memory +memory.{,s}read_sg: Scatter/Gather read memory \end_layout \begin_layout Itemize -Syntax: none memory.readbyte([string vma, ]number address) +Syntax: none memory.read_sg(string/boolean/number...) \end_layout \begin_layout Itemize -Syntax: none memory.readword([string vma, ]number address) -\end_layout - -\begin_layout Itemize -Syntax: none memory.readhword([string vma, ]number address) -\end_layout - -\begin_layout Itemize -Syntax: none memory.readdword([string vma, ]number address) -\end_layout - -\begin_layout Itemize -Syntax: none memory.readqword([string vma, ]number address) -\end_layout - -\begin_layout Itemize -Syntax: none memory.readsbyte([string vma, ]number address) -\end_layout - -\begin_layout Itemize -Syntax: none memory.readsword([string vma, ]number address) -\end_layout - -\begin_layout Itemize -Syntax: none memory.readshword([string vma, ]number address) -\end_layout - -\begin_layout Itemize -Syntax: none memory.readsdword([string vma, ]number address) -\end_layout - -\begin_layout Itemize -Syntax: none memory.readsqword([string vma, ]number address) +Syntax: none memory.sread_sg(string/boolean/number...) \end_layout \begin_layout Standard -Reads the specified address
+Perform (2s complement signed if using memory.sread_sg) scatter/gather read + of memory. + Each argument can be string, boolean or number: +\end_layout + +\begin_layout Itemize +String: Set VMA addresses are relative to (e.g. + 'WRAM'). +\end_layout + +\begin_layout Itemize +boolean: If true, increment relative address by 1, if false, decrement by + 1. + The new address is read as next higher byte. +\end_layout + +\begin_layout Itemize +integer: Set the relative address to specified value and read the address + as next higher byte. +\end_layout + +\begin_layout Subsection +memory.write_sg: Scatter/Gather write memory +\end_layout + +\begin_layout Itemize +Syntax: none memory.write_sg(number value, string/boolean/number...) +\end_layout + +\begin_layout Standard +Perform scatter/gather write of value on memory. + Each argument can be string, boolean or number: +\end_layout + +\begin_layout Itemize +String: Set VMA addresses are relative to (e.g. + 'WRAM'). +\end_layout + +\begin_layout Itemize +boolean: If true, increment relative address by 1, if false, decrement by + 1. + The new address is read as next higher byte. +\end_layout + +\begin_layout Itemize +integer: Set the relative address to specified value and read the address + as next higher byte. \end_layout \begin_layout Subsection diff --git a/lua.pdf b/lua.pdf index f35ba884..c797beae 100644 Binary files a/lua.pdf and b/lua.pdf differ diff --git a/src/lua/memory.cpp b/src/lua/memory.cpp index 610e9918..17e901cc 100644 --- a/src/lua/memory.cpp +++ b/src/lua/memory.cpp @@ -394,6 +394,55 @@ namespace return 1; }); + template int memory_scattergather(lua_state& L, const std::string& fname) + { + uint64_t val = 0; + int ptr = 1; + unsigned shift = 0; + uint64_t addr = 0; + uint64_t vmabase = 0; + if(write) + val = L.get_numeric_argument(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 if(L.type(ptr) == LUA_TSTRING) { + vmabase = get_vmabase(L, L.get_string(ptr++, fname.c_str())); + continue; + } else + addr = L.get_numeric_argument(ptr++, fname.c_str()); + if(write) + lsnes_memory.write(addr + vmabase, val >> shift); + else + val = val + ((uint64_t)lsnes_memory.read(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; + } + + function_ptr_luafun scattergather1(lua_func_misc, "memory.read_sg", [](lua_state& L, const std::string& fname) + -> int { + return memory_scattergather(L, fname); + }); + + function_ptr_luafun scattergather2(lua_func_misc, "memory.sread_sg", [](lua_state& L, + const std::string& fname) -> int { + return memory_scattergather(L, fname); + }); + + function_ptr_luafun scattergather3(lua_func_misc, "memory.write_sg", [](lua_state& L, + const std::string& fname) -> int { + return memory_scattergather(L, fname); + }); + lua_read_memory> rub("memory.readbyte"); lua_read_memory> rsb("memory.readsbyte"); lua_read_memory> ruw("memory.readword");