sceWork

//Get the 2 top bits

top2Bits = codeByte+1 >> 6

if(top2Bits == 1)

//not sure

else if (top2Bits > 1)

if (top2Bits == 2)

//Not sure

else if (top2Bits != 3)

//not sure

else if (top2Bit == 0)

lowByte = codeByte & 0xF


low2Bits = codeByte & 0x3

if(low2Bits == 1)

//not sure

else if (low2Bits > 1)

if (low2Bits == 2)

stringPtr = stack?

else if (low2Bits != 3)

low2Bits = stack?

else if (low2Bits == 0)

stringPtr = TODIRSCE_Strings


stringPtr += lowByte

So, there's a binary script inside the TOD1RSCE, whatever the other bytes do I don't care, but the 0x47 byte is the one that says where the text is


The format for the instruction is like so:

<- MINIMUM NEEDED -> <----------- OPTIONAL ------------>

| 0x47 | 0x## | 0x## | 0x## | 0x## | 0x## | 0x## | 0x## |

|------|------|------|------|------|------|------|------|

| 1st | 2nd | 3rd | 4th | 5th | 6th | 7th | 8th |

---------------------------------------------------------

So the instruction can be anywhere from 3 to 9 bytes, but how do we know the length (and the pointer, for that matter)?


All of that is encoded in the 2nd byte, how? Well, we got 8 bits to play with!


First we check what the 2 top bits (8 and 7) are

A number made from 2 bits spans from [0-3], so whatever the number is we add it to length of the instruction

Then we check what the bits (6 and 5) are, just like with the previous one we add wathever the binary gives us minus 1


As for the pointer to the text, depends on the length:

If it is the default length (8th and 7th bits from the 2nd byte are both 0) then the pointer is:

pointerToStrings+(2ndByte & 0xF)

so it's useful to point to any string in the first 0xF (15) bytes


If it is the default length + 1 (8th and 7th bits are 0 and 1 respectively) then the pointer is:

pointerToStrings+((2ndByte & 0xF) << 8) | 3rdByte

so it's useful to point to any string in the first 0xFFF (4095) bytes


If it is the default length + 2 (8th and 7th bits are 1 and 0 respectively) then the pointer is:

pointerToStrings+((2ndByte & 0xF) << 10) | 3rdByte | (4thByte << 8)

so it's useful to point to any string in the first 0xFFFF (65535) bytes


And I won't say the last one because you have more than enough with 65GB of addressing range xd


As for what sceWork does, it is bascally testing for the top nybble of the second byte to be either 1, 5, or 9, skipping the length calculation

This means that unless code jumps are relative some strings can't be moved

<----- POINTER ----> <------------- CODE ------------->

| 0x47 | 0x1F | 0x00 | 0x69 | 0x1F | 0x00 | 0x20 | 0x6F |

|------|------|------|------|------|------|------|------|

/\

\--- Game's executing this part

When it's done finding the text it jumps here:

|

\|/

|------|------|------|------|------|------|------|------|

| 0x47 | 0x1F | 0x00 | 0x69 | 0x1F | 0x00 | 0x20 | 0x6F |

<----- POINTER ----> <------------- CODE ------------->


The problem? When the pointer gets bigger sceWork overwrites that 0x69 with the pointer!