Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scripting: add signed/unsigned read/write functions #3024

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ Misc:
- Qt: Handle multiple save game files for disparate games separately (fixes mgba.io/i/2887)
- Qt: Remove maligned double-click-to-fullscreen shortcut (closes mgba.io/i/2632)
- Scripting: Add `callbacks:oneshot` for single-call callbacks
- Scripting: Add signed/unsigned variations for memory read/write functions

0.10.2: (2023-04-23)
Emulation fixes:
Expand Down
138 changes: 126 additions & 12 deletions src/core/scripting.c
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,24 @@ static uint32_t mScriptMemoryDomainRead32(struct mScriptMemoryDomain* adapter, u
return adapter->core->rawRead32(adapter->core, segmentAddress, segment);
}

static int32_t mScriptMemoryDomainReadS8(struct mScriptMemoryDomain* adapter, uint32_t address) {
CALCULATE_SEGMENT_INFO;
CALCULATE_SEGMENT_ADDRESS;
return ((int32_t) adapter->core->rawRead8(adapter->core, segmentAddress, segment) << 24) >> 24;
}

static int32_t mScriptMemoryDomainReadS16(struct mScriptMemoryDomain* adapter, uint32_t address) {
CALCULATE_SEGMENT_INFO;
CALCULATE_SEGMENT_ADDRESS;
return ((int32_t) adapter->core->rawRead16(adapter->core, segmentAddress, segment) << 16) >> 16;
}

static int32_t mScriptMemoryDomainReadS32(struct mScriptMemoryDomain* adapter, uint32_t address) {
CALCULATE_SEGMENT_INFO;
CALCULATE_SEGMENT_ADDRESS;
return (int32_t) adapter->core->rawRead32(adapter->core, segmentAddress, segment);
}

static struct mScriptValue* mScriptMemoryDomainReadRange(struct mScriptMemoryDomain* adapter, uint32_t address, uint32_t length) {
CALCULATE_SEGMENT_INFO;
struct mScriptValue* value = mScriptStringCreateEmpty(length);
Expand Down Expand Up @@ -273,6 +291,24 @@ static void mScriptMemoryDomainWrite32(struct mScriptMemoryDomain* adapter, uint
adapter->core->rawWrite32(adapter->core, segmentAddress, segment, value);
}

static void mScriptMemoryDomainWriteS8(struct mScriptMemoryDomain* adapter, uint32_t address, int8_t value) {
CALCULATE_SEGMENT_INFO;
CALCULATE_SEGMENT_ADDRESS;
adapter->core->rawWrite8(adapter->core, segmentAddress, segment, (uint8_t) value);
}

static void mScriptMemoryDomainWriteS16(struct mScriptMemoryDomain* adapter, uint32_t address, int16_t value) {
CALCULATE_SEGMENT_INFO;
CALCULATE_SEGMENT_ADDRESS;
adapter->core->rawWrite16(adapter->core, segmentAddress, segment, (uint16_t) value);
}

static void mScriptMemoryDomainWriteS32(struct mScriptMemoryDomain* adapter, uint32_t address, int32_t value) {
CALCULATE_SEGMENT_INFO;
CALCULATE_SEGMENT_ADDRESS;
adapter->core->rawWrite32(adapter->core, segmentAddress, segment, (uint32_t) value);
}

static uint32_t mScriptMemoryDomainBase(struct mScriptMemoryDomain* adapter) {
return adapter->block.start;
}
Expand All @@ -293,10 +329,22 @@ mSCRIPT_DECLARE_STRUCT(mScriptMemoryDomain);
mSCRIPT_DECLARE_STRUCT_METHOD(mScriptMemoryDomain, U32, read8, mScriptMemoryDomainRead8, 1, U32, address);
mSCRIPT_DECLARE_STRUCT_METHOD(mScriptMemoryDomain, U32, read16, mScriptMemoryDomainRead16, 1, U32, address);
mSCRIPT_DECLARE_STRUCT_METHOD(mScriptMemoryDomain, U32, read32, mScriptMemoryDomainRead32, 1, U32, address);
mSCRIPT_DECLARE_STRUCT_METHOD(mScriptMemoryDomain, U32, readU8, mScriptMemoryDomainRead8, 1, U32, address);
mSCRIPT_DECLARE_STRUCT_METHOD(mScriptMemoryDomain, U32, readU16, mScriptMemoryDomainRead16, 1, U32, address);
mSCRIPT_DECLARE_STRUCT_METHOD(mScriptMemoryDomain, U32, readU32, mScriptMemoryDomainRead32, 1, U32, address);
mSCRIPT_DECLARE_STRUCT_METHOD(mScriptMemoryDomain, S32, readS8, mScriptMemoryDomainReadS8, 1, U32, address);
mSCRIPT_DECLARE_STRUCT_METHOD(mScriptMemoryDomain, S32, readS16, mScriptMemoryDomainReadS16, 1, U32, address);
mSCRIPT_DECLARE_STRUCT_METHOD(mScriptMemoryDomain, S32, readS32, mScriptMemoryDomainReadS32, 1, U32, address);
mSCRIPT_DECLARE_STRUCT_METHOD(mScriptMemoryDomain, WSTR, readRange, mScriptMemoryDomainReadRange, 2, U32, address, U32, length);
mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptMemoryDomain, write8, mScriptMemoryDomainWrite8, 2, U32, address, U8, value);
mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptMemoryDomain, write16, mScriptMemoryDomainWrite16, 2, U32, address, U16, value);
mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptMemoryDomain, write32, mScriptMemoryDomainWrite32, 2, U32, address, U32, value);
mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptMemoryDomain, writeU8, mScriptMemoryDomainWrite8, 2, U32, address, U8, value);
mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptMemoryDomain, writeU16, mScriptMemoryDomainWrite16, 2, U32, address, U16, value);
mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptMemoryDomain, writeU32, mScriptMemoryDomainWrite32, 2, U32, address, U32, value);
mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptMemoryDomain, writeS8, mScriptMemoryDomainWriteS8, 2, U32, address, S8, value);
mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptMemoryDomain, writeS16, mScriptMemoryDomainWriteS16, 2, U32, address, S16, value);
mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptMemoryDomain, writeS32, mScriptMemoryDomainWriteS32, 2, U32, address, S32, value);

mSCRIPT_DECLARE_STRUCT_METHOD(mScriptMemoryDomain, U32, base, mScriptMemoryDomainBase, 0);
mSCRIPT_DECLARE_STRUCT_METHOD(mScriptMemoryDomain, U32, bound, mScriptMemoryDomainEnd, 0);
Expand All @@ -308,20 +356,38 @@ mSCRIPT_DEFINE_STRUCT(mScriptMemoryDomain)
"An object used for access directly to a memory domain, e.g. the cartridge, "
"instead of through a whole address space, as with the functions directly on struct::mCore."
)
mSCRIPT_DEFINE_DOCSTRING("Read an 8-bit value from the given offset")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptMemoryDomain, read8)
mSCRIPT_DEFINE_DOCSTRING("Read a 16-bit value from the given offset")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptMemoryDomain, read16)
mSCRIPT_DEFINE_DOCSTRING("Read a 32-bit value from the given offset")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptMemoryDomain, read32)
mSCRIPT_DEFINE_DOCSTRING("Read an unsigned 8-bit value from the given offset")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptMemoryDomain, readU8)
mSCRIPT_DEFINE_DOCSTRING("Read an unsigned 16-bit value from the given offset")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptMemoryDomain, readU16)
mSCRIPT_DEFINE_DOCSTRING("Read an unsigned 32-bit value from the given offset")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptMemoryDomain, readU32)
mSCRIPT_DEFINE_DOCSTRING("Read a signed 8-bit value from the given offset")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptMemoryDomain, readS8)
mSCRIPT_DEFINE_DOCSTRING("Read a signed 16-bit value from the given offset")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptMemoryDomain, readS16)
mSCRIPT_DEFINE_DOCSTRING("Read a signed 32-bit value from the given offset")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptMemoryDomain, readS32)
mSCRIPT_DEFINE_DOCSTRING("Read byte range from the given offset")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptMemoryDomain, readRange)
mSCRIPT_DEFINE_DOCSTRING("Write an 8-bit value from the given offset")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptMemoryDomain, write8)
mSCRIPT_DEFINE_DOCSTRING("Write a 16-bit value from the given offset")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptMemoryDomain, write16)
mSCRIPT_DEFINE_DOCSTRING("Write a 32-bit value from the given offset")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptMemoryDomain, write32)
mSCRIPT_DEFINE_DOCSTRING("Write an unsigned 8-bit value to the given offset")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptMemoryDomain, writeU8)
mSCRIPT_DEFINE_DOCSTRING("Write an unsigned 16-bit value to the given offset")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptMemoryDomain, writeU16)
mSCRIPT_DEFINE_DOCSTRING("Write an unsigned 32-bit value to the given offset")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptMemoryDomain, writeU32)
mSCRIPT_DEFINE_DOCSTRING("Write a signed 8-bit value to the given offset")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptMemoryDomain, writeS8)
mSCRIPT_DEFINE_DOCSTRING("Write a signed 16-bit value to the given offset")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptMemoryDomain, writeS16)
mSCRIPT_DEFINE_DOCSTRING("Write a signed 32-bit value to the given offset")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptMemoryDomain, writeS32)

mSCRIPT_DEFINE_DOCSTRING("Get the address of the base of this memory domain")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptMemoryDomain, base)
Expand Down Expand Up @@ -380,6 +446,18 @@ static int32_t _mScriptCoreGetKey(struct mCore* core, int32_t key) {
return (core->getKeys(core) >> key) & 1;
}

static int32_t _mScriptCoreReadS8(struct mCore* core, uint32_t address) {
return ((int32_t) core->busRead8(core, address) << 24) >> 24;
}

static int32_t _mScriptCoreReadS16(struct mCore* core, uint32_t address) {
return ((int32_t) core->busRead8(core, address) << 16) >> 16;
}

static int32_t _mScriptCoreReadS32(struct mCore* core, uint32_t address) {
return (int32_t) core->busRead8(core, address);
}

static struct mScriptValue* _mScriptCoreReadRange(struct mCore* core, uint32_t address, uint32_t length) {
struct mScriptValue* value = mScriptStringCreateEmpty(length);
char* buffer = value->value.string->buffer;
Expand All @@ -390,6 +468,18 @@ static struct mScriptValue* _mScriptCoreReadRange(struct mCore* core, uint32_t a
return value;
}

static void _mScriptCoreWriteS8(struct mCore* core, uint32_t address, int8_t value) {
core->busWrite8(core, address, (uint8_t) value);
}

static void _mScriptCoreWriteS16(struct mCore* core, uint32_t address, int16_t value) {
core->busWrite8(core, address, (uint16_t) value);
}

static void _mScriptCoreWriteS32(struct mCore* core, uint32_t address, int32_t value) {
core->busWrite8(core, address, (uint32_t) value);
}

static struct mScriptValue* _mScriptCoreReadRegister(const struct mCore* core, const char* regName) {
int32_t out;
if (!core->readRegister(core, regName, &out)) {
Expand Down Expand Up @@ -512,10 +602,16 @@ mSCRIPT_DECLARE_STRUCT_D_METHOD(mCore, U32, getKeys, 0);
mSCRIPT_DECLARE_STRUCT_D_METHOD(mCore, U32, busRead8, 1, U32, address);
mSCRIPT_DECLARE_STRUCT_D_METHOD(mCore, U32, busRead16, 1, U32, address);
mSCRIPT_DECLARE_STRUCT_D_METHOD(mCore, U32, busRead32, 1, U32, address);
mSCRIPT_DECLARE_STRUCT_METHOD(mCore, U32, busReadS8, _mScriptCoreReadS8, 1, S32, address);
mSCRIPT_DECLARE_STRUCT_METHOD(mCore, U32, busReadS16, _mScriptCoreReadS16, 1, S32, address);
mSCRIPT_DECLARE_STRUCT_METHOD(mCore, U32, busReadS32, _mScriptCoreReadS32, 1, S32, address);
mSCRIPT_DECLARE_STRUCT_METHOD(mCore, WSTR, readRange, _mScriptCoreReadRange, 2, U32, address, U32, length);
mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mCore, busWrite8, 2, U32, address, U8, value);
mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mCore, busWrite16, 2, U32, address, U16, value);
mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mCore, busWrite32, 2, U32, address, U32, value);
mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mCore, busWriteS8, _mScriptCoreWriteS8, 2, S32, address, S8, value);
mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mCore, busWriteS16, _mScriptCoreWriteS16, 2, S32, address, S16, value);
mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mCore, busWriteS32, _mScriptCoreWriteS32, 2, S32, address, S32, value);

// Register functions
mSCRIPT_DECLARE_STRUCT_METHOD(mCore, WSTR, readRegister, _mScriptCoreReadRegister, 1, CHARP, regName);
Expand Down Expand Up @@ -584,20 +680,38 @@ mSCRIPT_DEFINE_STRUCT(mCore)
mSCRIPT_DEFINE_DOCSTRING("Get the currently active keys as a bitmask")
mSCRIPT_DEFINE_STRUCT_METHOD(mCore, getKeys)

mSCRIPT_DEFINE_DOCSTRING("Read an 8-bit value from the given bus address")
mSCRIPT_DEFINE_STRUCT_METHOD_NAMED(mCore, read8, busRead8)
mSCRIPT_DEFINE_DOCSTRING("Read a 16-bit value from the given bus address")
mSCRIPT_DEFINE_STRUCT_METHOD_NAMED(mCore, read16, busRead16)
mSCRIPT_DEFINE_DOCSTRING("Read a 32-bit value from the given bus address")
mSCRIPT_DEFINE_STRUCT_METHOD_NAMED(mCore, read32, busRead32)
mSCRIPT_DEFINE_DOCSTRING("Read an unsigned 8-bit value from the given bus address")
mSCRIPT_DEFINE_STRUCT_METHOD_NAMED(mCore, readU8, busRead8)
mSCRIPT_DEFINE_DOCSTRING("Read an unsigned 16-bit value from the given bus address")
mSCRIPT_DEFINE_STRUCT_METHOD_NAMED(mCore, readU16, busRead16)
mSCRIPT_DEFINE_DOCSTRING("Read an unsigned 32-bit value from the given bus address")
mSCRIPT_DEFINE_STRUCT_METHOD_NAMED(mCore, readU32, busRead32)
mSCRIPT_DEFINE_DOCSTRING("Read a signed 8-bit value from the given bus address")
mSCRIPT_DEFINE_STRUCT_METHOD_NAMED(mCore, readS8, busReadS8)
mSCRIPT_DEFINE_DOCSTRING("Read a signed 16-bit value from the given bus address")
mSCRIPT_DEFINE_STRUCT_METHOD_NAMED(mCore, readS16, busReadS16)
mSCRIPT_DEFINE_DOCSTRING("Read a signed 32-bit value from the given bus address")
mSCRIPT_DEFINE_STRUCT_METHOD_NAMED(mCore, readS32, busReadS32)
mSCRIPT_DEFINE_DOCSTRING("Read byte range from the given offset")
mSCRIPT_DEFINE_STRUCT_METHOD(mCore, readRange)
mSCRIPT_DEFINE_DOCSTRING("Write an 8-bit value from the given bus address")
mSCRIPT_DEFINE_STRUCT_METHOD_NAMED(mCore, write8, busWrite8)
mSCRIPT_DEFINE_DOCSTRING("Write a 16-bit value from the given bus address")
mSCRIPT_DEFINE_STRUCT_METHOD_NAMED(mCore, write16, busWrite16)
mSCRIPT_DEFINE_DOCSTRING("Write a 32-bit value from the given bus address")
mSCRIPT_DEFINE_STRUCT_METHOD_NAMED(mCore, write32, busWrite32)
mSCRIPT_DEFINE_DOCSTRING("Write an unsigned 8-bit value from the given bus address")
mSCRIPT_DEFINE_STRUCT_METHOD_NAMED(mCore, writeU8, busWrite8)
mSCRIPT_DEFINE_DOCSTRING("Write an unsigned 16-bit value from the given bus address")
mSCRIPT_DEFINE_STRUCT_METHOD_NAMED(mCore, writeU16, busWrite16)
mSCRIPT_DEFINE_DOCSTRING("Write an unsigned 32-bit value from the given bus address")
mSCRIPT_DEFINE_STRUCT_METHOD_NAMED(mCore, writeU32, busWrite32)
mSCRIPT_DEFINE_DOCSTRING("Write a signed 8-bit value from the given bus address")
mSCRIPT_DEFINE_STRUCT_METHOD_NAMED(mCore, writeS8, busWriteS8)
mSCRIPT_DEFINE_DOCSTRING("Write a signed 16-bit value from the given bus address")
mSCRIPT_DEFINE_STRUCT_METHOD_NAMED(mCore, writeS16, busWriteS16)
mSCRIPT_DEFINE_DOCSTRING("Write a signed 32-bit value from the given bus address")
mSCRIPT_DEFINE_STRUCT_METHOD_NAMED(mCore, writeS32, busWriteS32)

mSCRIPT_DEFINE_DOCSTRING("Read the value of the register with the given name")
mSCRIPT_DEFINE_STRUCT_METHOD(mCore, readRegister)
Expand Down