I've added a new addressing type, currently called cheatscript. When it is selected, the cheat engine will look (either in the comment field or directly after the cheat) for a program in this format. When the cheat is activated, the program will be run until termination. For simple cheats, all the program would do would be display a dialog asking for information (board position, piece to place, etc.), calculate the cheat address, then return the calculated address back to the cheat.
I'm also including the capability to have the cheat script execute once per frame (by not setting the "program done" flag in the halt instruction) allowing many possible creative uses.
Code: Select all
cheatscript virtual machine 0.1 documentation
Register List:
32 main registers, labeled r0 to r31
r31 acts as condition register
divided in to 8 segments, labeled cr0 to cr7
x--- less than
-x-- greater than
--x- equal to
---x unused
65536 bytes of local memory
Memory Organization:
00000000 - 0000FFFF local memory
00010000 - 0001FFFF program
00020000 - 0002FFFF memory maintained across invocations (must be allocated in first cheat)
Instruction Categories:
data movement
load/store local memory
load/store remote memory
set target cpu (immediate + from register)
indexed (ea = rx + ry)
relative (ea = rx + simm)
get
arithmetic
add
add immediate
subtract
negate
multiply
multiply immediate
divide
divide immediate
logical
and
and immediate
and bit
or
or immediate
or bit
xor
xor immediate
xor bit
sign extend
rotate
shift
branch
jump
conditional jump
function call
function return
comparison
compare unsigned/signed
compare unsigned/signed with immediate
management
halt
dialog
asynchronous dialog
wait for user input
dialog
to be determined later
Opcode List:
33222222222211111111110000000000
10987654321098765432109876543210
000----------------------------- [ memory transfer relative ]
---xxx-------------------------- opcode/type
000 = load byte ldb
001 = load signed byte ldbs
010 = load word ldw
011 = load signed word ldws
100 = load long ldl
101 = store byte stb
110 = store word stw
111 = store long stl
------xxxxx--------------------- base register (ignored if r0)
-----------xxxxx---------------- source/dest register
----------------xxxxxxxxxxxxxxxx offset
001000-------------------------- [ memory transfer indexed ]
------xxxxx--------------------- base register
-----------xxxxx---------------- index register
----------------xxxxx----------- source/dest register
---------------------xxx-------- type
000 = load byte ldxb
001 = load signed byte ldxbs
010 = load word ldxw
011 = load signed word ldxws
100 = load long ldxl
101 = store byte stxb
110 = store word stxw
111 = store long stxl
001001-------------------------- [ compare immediate ] cmpi
------xxxxx--------------------- left-hand side
-----------xxxxx---------------- condition register bit
----------------xxxxxxxxxxxxxxxx immediate
001010-------------------------- [ compare immediate signed ] cmpis
------xxxxx--------------------- left-hand side
-----------xxxxx---------------- condition register bit
----------------xxxxxxxxxxxxxxxx immediate
100000-------------------------- [ bit move ]
------xxxxx--------------------- source register
-----------xxxxx---------------- source bit
----------------xxxxx----------- dest register
---------------------xxxxx------ dest bit
100001-------------------------- [ bit xor ]
------xxxxx--------------------- lhs register
-----------xxxxx---------------- lhs bit
----------------xxxxx----------- rhs register
---------------------xxxxx------ rhs bit
--------------------------xxxxx- target bit (of rhs register)
100010-------------------------- [ bit or ]
100011-------------------------- [ bit and ]
110101-------------------------- [ xor immediate ] xori
------xxxxx--------------------- lhs (ignored if r0)
-----------xxxxx---------------- target
----------------xxxxxxxxxxxxxxxx unsigned immediate
110110-------------------------- [ xor immediate shifted ] xoris
110111-------------------------- [ or immediate ] ori
111000-------------------------- [ or immediate shifted ] oris
111001-------------------------- [ and immediate ] andi
111010-------------------------- [ and immediate shifted ] andi
111011-------------------------- [ add immediate ] addi
------xxxxx--------------------- lhs (ignored if r0)
-----------xxxxx---------------- target
----------------xxxxxxxxxxxxxxxx signed immediate
111100-------------------------- [ multiply immediate ] muli
111101-------------------------- [ divide immediate ] divi
1111100000000000---------------- [ add ] add
----------------xxxxx----------- lhs
---------------------xxxxx------ rhs
--------------------------xxxxx- target
1111100000000001---------------- [ subtract ] sub
1111100000000010---------------- [ multiply ] mul
1111100000000011---------------- [ divide ] div
1111100000000100---------------- [ negate ] neg (ignore rhs field)
1111100000010000---------------- [ shift left ] shl
1111100000010001---------------- [ shift left immediate ] shli (treat rhs field as immediate)
1111100000010010---------------- [ shift right ] shr
1111100000010011---------------- [ shift right immediate ] shri (treat rhs field as immediate)
1111100000010100---------------- [ rotate left ] rol
1111100000010101---------------- [ rotate left immediate ] roli (treat rhs field as immediate)
11111100000--------------------- [ set target cpu ] stc
--------------------------x----- direction (0 = to register 1 = from register)
---------------------------xxxxx source/dest register
11111100001--------------------- [ dialog ] dia
----------------xxxxxxxxxxxxxxxx offset of dialog descriptor
11111100010--------------------- [ async dialog ] adia
----------------xxxxxxxxxxxxxxxx offset of dialog descriptor
11111100011--------------------- [ wait for user input ] wait
11111100100--------------------- [ compare ] cmp
-----------xxxxx---------------- left-hand side
----------------xxxxx----------- right-hand side
---------------------xxx-------- condition register bit
------------------------x------- signed comparison
11111100101--------------------- [ jump ] jmp
-----------xxxxxxxxxxxxxxxxxxxxx offset
11111100110--------------------- [ jump conditional set ] jmps
-----------xxxxx---------------- condition register bit
----------------xxxxxxxxxxxxxxxx offset
11111100111--------------------- [ jump conditional clear ] jmpc
-----------xxxxx---------------- condition register bit
----------------xxxxxxxxxxxxxxxx offset
11111101000--------------------- [ call function ] call
-----------xxxxxxxxxxxxxxxxxxxxx offset
11111101001--------------------- [ return from function ] ret
11111101010--------------------- [ jump to register ]
-----------xxxxx---------------- target register
11111101011--------------------- [ call to register ]
-----------xxxxx---------------- target register
11111111111--------------------- [ halt ]
-------------------------------x program done
And, yes, I have heard of overkill.
Anyway, keeping in mind that I'd like to make a general case solution to this problem, is something like this too complex or unneeded? Also if there's anything you'd like implemented or see missing, please tell me.