Last active
December 26, 2023 04:14
-
-
Save s5bug/33ad59da7b5e68b4fae2ed1417dd5f50 to your computer and use it in GitHub Desktop.
Kingdom Hearts 2 AI VM Language notes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
???? ???? ???? 0000: | |
[TODO: document special cases related to Xemnas] | |
???? ???? ??0? 0000: | |
???? ???? ??00 0000 iiii iiii iiii iiii iiii iiii iiii iiii: | |
load immediate INT | |
push to TP | |
???? ???? ??01 0000 ffff ffff ffff ffff ffff ffff ffff ffff: | |
load immediate FLOAT | |
push to TP | |
iiii iiii ii1m 0000 oooo oooo oooo oooo: | |
if(i == 0): | |
address = &(SP[o]) | |
if(i == 1): | |
address = &(WP[o]) | |
if(i == 2): | |
address = LookupAddressEntrySafe(SP[0]) + o | |
if(i == 3): | |
address = 0 | |
if(i == 4): | |
if(m == 0): | |
address = &(TEXT[o]) | |
if(m == 1): | |
*tmpReg = TEXT[o] | |
address = tmpReg | |
if(m == 0): | |
push GetOrInsertAddressEntrySafe(address) to TP | |
if(m == 1): | |
push *((DWORD*)address) to TP | |
???? ???? ???? 0001: | |
[TODO document delta-time specific behavior] | |
iiii iiii ii?? 0001 oooo oooo oooo oooo: | |
if(i == 0): | |
address = &(SP[o]) | |
if(i == 1): | |
address = &(WP[o]) | |
if(i == 2): | |
address = LookupAddressEntrySafe(SP[0]) + o | |
if(i == 3): | |
*tmpReg = TEXT[o] | |
address = tmpReg | |
else: | |
address = 0 | |
pop TP to address | |
iiii iiii ii?? 0010 aaaa aaaa aaaa aaaa bbbb bbbb bbbb bbbb: | |
pop TP to source | |
if(i == 0): | |
destination = &(SP[b]) | |
if(i == 1): | |
destination = &(WP[b]) | |
if(i == 2): | |
destination = LookupAddressEntrySafe(SP[0]) + o | |
if(i == 3): | |
destination = undefined | |
else: | |
destination = 0 | |
does a memcpy of size a from source into destination | |
???? ???? ???? 0011 iiii iiii iiii iiii: | |
pop TP to hash | |
address = LookupAddressEntrySafe(hash) + i | |
push *address to TP | |
iiii iiii ii?? 0100: | |
pop TP to X | |
pop TP to Y | |
if(i == 0): | |
*LookupAddressEntrySafe(Y) = X | |
else: | |
memcpy of size i from LookupAddressEntrySafe(X) to LookupAddressEntrySafe(Y) | |
???? ???? ???? 0101: | |
???? ???? ??00 0101: | |
0000 0000 0000 0101: | |
TP[0].Float = (float) TP[0].Int | |
0000 0000 1000 0101: | |
TP[0].Int = -(TP[0].Int) | |
0000 0000 1100 0101: | |
TP[0].Int = ~TP[0] | |
0000 0001 0000 0101: | |
TP[0].Int = (TP[0] == 0) | |
0000 0001 0100 0101: | |
TP[0].Int = Abs(TP[0].Int) | |
0000 0001 1000 0101: | |
TP[0].Int = TP[0] >> 31 | |
0000 0001 1100 0101: | |
TP[0].Int = (TP[0] <= 0) | |
0000 0010 0000 0101: | |
TP[0].Int = (TP[0] == 0) | |
0000 0010 0100 0101: | |
TP[0].Int = (TP[0] != 0) | |
0000 0010 1000 0101: | |
TP[0].Int = (~TP[0]) >> 31 | |
0000 0010 1100 0101: | |
TP[0].Int = (TP[0] > 0) | |
???? ???? ??01 0101: | |
0000 0000 0101 0101: | |
TP[0].Int = (int) TP[0].Float | |
0000 0000 1001 0101: | |
TP[0].Float = -(TP[0].Float) | |
0000 0001 0101 0101: | |
TP[0].Float = Abs(TP[0].Float) | |
0000 0001 1001 0101: | |
TP[0].Int = (TP[0].Float < 0.0f) | |
0000 0001 1101 0101: | |
TP[0].Int = (TP[0].Float <= 0.0f) | |
0000 0010 0001 0101: | |
TP[0].Int = (TP[0].Float == 0.0f) | |
0000 0010 0101 0101: | |
TP[0].Int = (TP[0].Float != 0.0f) | |
0000 0010 1001 0101: | |
TP[0].Int = (TP[0].Float >= 0.0f) | |
0000 0010 1101 0101: | |
TP[0].Int = (TP[0].Float > 0.0f) | |
???? ???? ???? 0110: | |
pop TP to Y | |
pop TP to X | |
???? ???? ??00 0110: | |
0000 0000 0000 0110: | |
if X or Y is a hash: look them up, do pointer addition | |
else: do int addition | |
push addition result to TP | |
0000 0000 0100 0110: | |
push (X.Int - Y.Int) to TP | |
0000 0000 1000 0110: | |
push (X.Int * Y.Int) to TP | |
0000 0000 1100 0110 if Y.Int is nonzero: | |
push (X.Int / Y.Int) to TP | |
0000 0001 0000 0110: | |
push (X.Int % Y.Int) to TP | |
0000 0001 0100 0110: | |
push (X.Int & Y.Int) to TP | |
0000 0001 1000 0110: | |
push (X.Int | Y.Int) to TP | |
0000 0001 1100 0110: | |
push (X.Int ^ Y.Int) to TP | |
0000 0010 0000 0110: | |
push (X.Int << Y.Int) to TP | |
0000 0010 0100 0110: | |
push (X.Int >> Y.Int) to TP | |
0000 0010 1000 0110: | |
push (X.Int && Y.Int) to TP | |
0000 0010 1100 0110: | |
push (X.Int || Y.Int) to TP | |
???? ???? ??01 0110: | |
0000 0000 0001 0110: | |
push (X.Float + Y.Float) to TP | |
0000 0000 0101 0110: | |
push (X.Float - Y.Float) to TP | |
0000 0000 1001 0110: | |
push (X.Float * Y.Float) to TP | |
0000 0000 1101 0110 if Y.Float is nonzero: | |
push (X.Float / Y.Float) to TP | |
0000 0001 0001 0110: | |
push (X.Float % Y.Float) to TP | |
xxxx xxxx xx?? 0111 iiii iiii iiii iiii: | |
if(x == 0): | |
pc = pc + i | |
if(x == 1): | |
pop TP to X | |
if(X == 0) | |
pc = pc + i | |
if(x == 2): | |
pop TP to X | |
if(X != 0) | |
pc = pc + i | |
xxxx xxxx xxyy 1000 iiii iiii iiii iiii: | |
allocates x DWORDs of space on the stack | |
places LR at the top of the stack | |
places 0000 xxxx xxxx xxyy at the second slot of the stack | |
pc = pc + i | |
xxxx xxxx xx?? 1001: | |
0000 0000 00?? 1001: | |
halt! | |
0000 0000 01?? 1001: | |
exit! | |
0000 0000 10?? 1001: | |
return from JALR call | |
if stack does not have return address, return from VM | |
0000 0000 11?? 1001: | |
pop TP to X | |
0000 0001 01?? 1001: | |
pop TP to X | |
push X to TP | |
push X to TP | |
0000 0001 10?? 1001: | |
TP[0].Float = Sin(TP[0].Float) | |
0000 0001 11?? 1001: | |
TP[0].Float = Cos(TP[0].Float) | |
0000 0010 00?? 1001: | |
TP[0].Float = DegreesToRadians(TP[0].Float) | |
0000 0010 01?? 1001: | |
TP[0].Float = RadiansToDegrees(TP[0].Float) | |
iiii iiii ii?? 1010 aaaa aaaa aaaa aaaa: | |
syscall = SyscallTable[i][a] | |
args = { map [0, syscall.argcount): pop TP } | |
syscall(args) | |
if(syscall.hasReturnValue): | |
push args[0] to TP | |
xxxx xxxx xx?? 1011 aaaa aaaa aaaa aaaa bbbb bbbb bbbb bbbb: | |
jump +((b << 16) + a), link with frame size x |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment