The current URL is datacrystal.tcrf.net.
EarthBound/ASM/Memory And String Util Routines: Difference between revisions
(Describe more routines) |
(Finish documenting routines) |
||
Line 6: | Line 6: | ||
Copy memory similarly to the [https://cplusplus.com/reference/cstring/memcpy/ C memcpy function]. Memory is copied in 16-bit words, ignoring the final byte if an odd length is requested. Implemented using trivial repeated <tt>LDA</tt> and <tt>STA</tt> calls. | Copy memory similarly to the [https://cplusplus.com/reference/cstring/memcpy/ C memcpy function]. Memory is copied in 16-bit words, ignoring the final byte if an odd length is requested. Implemented using trivial repeated <tt>LDA</tt> and <tt>STA</tt> calls. | ||
''Note: Unclear why EarthBound uses this | ''Note: Unclear why EarthBound uses this subroutine instead of using the typically faster <tt>MVN</tt> or <tt>MVP</tt> CPU instructions.'' | ||
===Inputs=== | ===Inputs=== | ||
* <tt>x</tt>: Num bytes to copy. Because | * <tt>x</tt>: Num bytes to copy. Because the subroutine only copies in 16-bit words, only copies <tt>x - 1</tt> if <tt>x % 2 == 1</tt> | ||
* <tt>accumulator</tt>: Destination immediate pointer | * <tt>accumulator</tt>: Destination immediate pointer | ||
* <tt>$0e..$10</tt>: Source long pointer | * <tt>$0e..$10</tt>: Source long pointer | ||
Line 18: | Line 18: | ||
Copy memory similarly to the [https://cplusplus.com/reference/cstring/memcpy/ C memcpy function]. Memory is copied byte-by-byte. Implemented using trivial repeated <tt>LDA</tt> and <tt>STA</tt> calls with the accumulator set to 8-bit mode. | Copy memory similarly to the [https://cplusplus.com/reference/cstring/memcpy/ C memcpy function]. Memory is copied byte-by-byte. Implemented using trivial repeated <tt>LDA</tt> and <tt>STA</tt> calls with the accumulator set to 8-bit mode. | ||
''Note: Unclear why EarthBound uses this | ''Note: Unclear why EarthBound uses this subroutine instead of using the typically faster <tt>MVN</tt> or <tt>MVP</tt> CPU instructions.'' | ||
===Inputs=== | ===Inputs=== | ||
Line 30: | Line 30: | ||
Fill a block of memory with a given 8-bit value, similarly to the [https://cplusplus.com/reference/cstring/memset/ C memset function]. Memory is set in 16-bit words, ignoring the final byte if an odd length is requested. Implemented by filling both bytes of the accumulator with the input byte value and then using trivial repeated <tt>STA</tt> calls. | Fill a block of memory with a given 8-bit value, similarly to the [https://cplusplus.com/reference/cstring/memset/ C memset function]. Memory is set in 16-bit words, ignoring the final byte if an odd length is requested. Implemented by filling both bytes of the accumulator with the input byte value and then using trivial repeated <tt>STA</tt> calls. | ||
''Note: Unclear why EarthBound uses this | ''Note: Unclear why EarthBound uses this subroutine instead of applying the typically faster <tt>MVN</tt> or <tt>MVP</tt> CPU instructions to overlapping memory regions.'' | ||
===Inputs=== | ===Inputs=== | ||
* <tt>x</tt>: Num bytes to fill. Because | * <tt>x</tt>: Num bytes to fill. Because the subroutine only fills in 16-bit words, only fills <tt>x - 1</tt> if <tt>x % 2 == 1</tt> | ||
* <tt>accumulator</tt>: Memory start immediate pointer | * <tt>accumulator</tt>: Memory start immediate pointer | ||
* <tt>$0e</tt>: 8-bit value | * <tt>$0e</tt>: 8-bit value | ||
Line 42: | Line 42: | ||
Fill a block of memory with a given 8-bit value, similarly to the [https://cplusplus.com/reference/cstring/memset/ C memset function]. Memory is set byte-by-byte. Implemented using trivial repeated <tt>STA</tt> calls with the accumulator set to 8-bit mode. | Fill a block of memory with a given 8-bit value, similarly to the [https://cplusplus.com/reference/cstring/memset/ C memset function]. Memory is set byte-by-byte. Implemented using trivial repeated <tt>STA</tt> calls with the accumulator set to 8-bit mode. | ||
''Note: Unclear why EarthBound uses this | ''Note: Unclear why EarthBound uses this subroutine instead of applying the typically faster <tt>MVN</tt> or <tt>MVP</tt> CPU instructions to overlapping memory regions.'' | ||
===Inputs=== | ===Inputs=== | ||
Line 77: | Line 77: | ||
==<tt>$C08F42-$C08F67</tt>: Copy CPU state to memory== | ==<tt>$C08F42-$C08F67</tt>: Copy CPU state to memory== | ||
Saves the bank register, subroutine return pointer, P register (processor flags), direct page register, and stack register to 8 bytes of memory in the <tt>$00</tt> bank, starting at an input pointer. Used to create a saved state that can be later restored using the subroutine at <tt>$C08F68-$C08F8A</tt>. | |||
===Inputs=== | |||
* <tt>accumulator</tt>: Destination memory pointer (in bank <tt>$00</tt>) | |||
==<tt>$C08F68-$C08F8A</tt>: Load CPU state from memory== | ==<tt>$C08F68-$C08F8A</tt>: Load CPU state from memory== | ||
Restores the bank register, subroutine return pointer, P register (processor flags), direct page register, and stack register from 8 bytes of memory in the <tt>$00</tt> bank, starting at an input pointer. Used to restore a saved state saved by the subroutine at <tt>$C08F42-$C08F67</tt>. | |||
Because this subroutine overwrites the subroutine return pointer, on completion, on the <tt>RTL</tt> instruction, this subroutine will return to the code location where the save-state subroutine at <tt>$C08F42-$C08F67</tt> was called, not the code location where this subroutine was called. This subroutine therefore acts as a jump to a saved location. | |||
''Warning: Because this subroutine restores the stack register but not stack contents (except the subroutine return pointer), it can create unintended behavior if the call location of the save or restore subroutine makes assumptions about stack contents. Ideally, the restore subroutine should be called from the same context or a context where the stack has only been added to from the context where the save subroutine was called, thus ensuring the stack register restore simply returns the stack to the same contents from when the save subroutine was called.'' | |||
===Inputs=== | |||
* <tt>accumulator</tt>: Source memory pointer (in bank <tt>$00</tt>) | |||
* <tt>x</tt>: Value to output | |||
===Outputs=== | |||
* <tt>accumulator</tt>: Value from the <tt>x</tt> input | |||
[[Category:EarthBound:ASM|Memory And String Util Routines]] | [[Category:EarthBound:ASM|Memory And String Util Routines]] | ||
{{Internal Data|game=EarthBound}} | {{Internal Data|game=EarthBound}} | ||
Revision as of 19:43, 30 May 2023
This is a sub-page of EarthBound/ASM.
$C08ED2-$C08EEC: 16-bit memcpy
memcpy(a, $0e..$10, x)
Copy memory similarly to the C memcpy function. Memory is copied in 16-bit words, ignoring the final byte if an odd length is requested. Implemented using trivial repeated LDA and STA calls.
Note: Unclear why EarthBound uses this subroutine instead of using the typically faster MVN or MVP CPU instructions.
Inputs
- x: Num bytes to copy. Because the subroutine only copies in 16-bit words, only copies x - 1 if x % 2 == 1
- accumulator: Destination immediate pointer
- $0e..$10: Source long pointer
$C08EED-$C08EFB: 8-bit memcpy
memcpy($0e..$10, $12..$15, a)
Copy memory similarly to the C memcpy function. Memory is copied byte-by-byte. Implemented using trivial repeated LDA and STA calls with the accumulator set to 8-bit mode.
Note: Unclear why EarthBound uses this subroutine instead of using the typically faster MVN or MVP CPU instructions.
Inputs
- accumulator: Num bytes to copy
- $0e..$10: Destination long pointer
- $12..$15: Source long pointer
$C08EFC-$C08F14: 16-bit memset
memset(a, $0e, x)
Fill a block of memory with a given 8-bit value, similarly to the C memset function. Memory is set in 16-bit words, ignoring the final byte if an odd length is requested. Implemented by filling both bytes of the accumulator with the input byte value and then using trivial repeated STA calls.
Note: Unclear why EarthBound uses this subroutine instead of applying the typically faster MVN or MVP CPU instructions to overlapping memory regions.
Inputs
- x: Num bytes to fill. Because the subroutine only fills in 16-bit words, only fills x - 1 if x % 2 == 1
- accumulator: Memory start immediate pointer
- $0e: 8-bit value
$C08F15-$C08F21: 8-bit memset
memset($0e..$10, a, x)
Fill a block of memory with a given 8-bit value, similarly to the C memset function. Memory is set byte-by-byte. Implemented using trivial repeated STA calls with the accumulator set to 8-bit mode.
Note: Unclear why EarthBound uses this subroutine instead of applying the typically faster MVN or MVP CPU instructions to overlapping memory regions.
Inputs
- x: Num bytes to fill
- $0e..$10: Memory start long pointer
- accumulator[0]: 8-bit value
$C08F22-$C08F2E: strlen
strlen($0e..$10)
Count number of bytes in a memory block before a #$00 value, not including the #$00 byte. Used to find the length of a null-terminated string, similarly to the C strlen function. Implemented trivially by incrementing an index register until LDA instructions using the index loads zero.
Warning: Because an 8-bit register is used to count string bytes, will loop and hang if the input string does not contain a zero byte within the first 256 bytes.
Inputs
- $0e..$10: Memory start long pointer
Outputs
- accumulator[0]: 8-bit length (num bytes)
$C08F2F-$C08F41: strcmp(ish)
strcmpish($0e..$10, $12..$14)
Determine if one string (s1) is the same as the start to another string (s2). Implementing by comparing the strings byte-by-byte until the end (#$00 byte) of s1 is found or the compared bytes of s1 and s2 are not equal.
Note: Behaves quite differently from the C strcmp function. Only compares input strings for the length of s1 and has different return values.
Inputs
- $0e..$10: s1 long pointer
- $12..$14: s2 long pointer
Outputs
- accumulator[0]: #$00 if s2 begins with s1, otherwise #$01
$C08F42-$C08F67: Copy CPU state to memory
Saves the bank register, subroutine return pointer, P register (processor flags), direct page register, and stack register to 8 bytes of memory in the $00 bank, starting at an input pointer. Used to create a saved state that can be later restored using the subroutine at $C08F68-$C08F8A.
Inputs
- accumulator: Destination memory pointer (in bank $00)
$C08F68-$C08F8A: Load CPU state from memory
Restores the bank register, subroutine return pointer, P register (processor flags), direct page register, and stack register from 8 bytes of memory in the $00 bank, starting at an input pointer. Used to restore a saved state saved by the subroutine at $C08F42-$C08F67.
Because this subroutine overwrites the subroutine return pointer, on completion, on the RTL instruction, this subroutine will return to the code location where the save-state subroutine at $C08F42-$C08F67 was called, not the code location where this subroutine was called. This subroutine therefore acts as a jump to a saved location.
Warning: Because this subroutine restores the stack register but not stack contents (except the subroutine return pointer), it can create unintended behavior if the call location of the save or restore subroutine makes assumptions about stack contents. Ideally, the restore subroutine should be called from the same context or a context where the stack has only been added to from the context where the save subroutine was called, thus ensuring the stack register restore simply returns the stack to the same contents from when the save subroutine was called.
Inputs
- accumulator: Source memory pointer (in bank $00)
- x: Value to output
Outputs
- accumulator: Value from the x input
Internal Data for EarthBound
| |
---|---|