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!