-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathnesgenie_enc.py
47 lines (41 loc) · 1.45 KB
/
nesgenie_enc.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import sys
def encode_code(addr, repl, comp=None):
# encode an NES Game Genie code
# see https://www.nesdev.org/nesgg.txt
# create 24/32-bit int; clear/set MSB of address to get correct 3rd letter
# later (one of APZLGITY for 6-letter codes, one of EOXUKSVN for 8-letter
# codes)
if comp is None:
codeLen = 6
addr &= 0x7fff
bigint = (addr << 8) | repl
else:
codeLen = 8
addr |= 0x8000
bigint = (addr << 16) | (repl << 8) | comp
# convert into 4-bit ints
encoded = codeLen * [0]
for loPos in (3, 5, 2, 4, 1, 0, 7, 6)[codeLen-1::-1]:
hiPos = (loPos - 1) % codeLen
encoded[loPos] |= bigint & 0b111
encoded[hiPos] |= bigint & 0b1000
bigint >>= 4
# convert into letters
return "".join("APZLGITYEOXUKSVN"[i] for i in encoded)
def main():
if not 3 <= len(sys.argv) <= 4:
sys.exit(
"Encode an NES Game Genie code. Arguments: AAAA RR or AAAA RR CC "
"(AAAA = CPU address, RR = replacement value, CC = compare value; "
"all in hexadecimal)."
)
try:
values = [int(n, 16) for n in sys.argv[1:]]
except ValueError:
sys.exit("Arguments must be hexadecimal integers.")
if not 0 <= values[0] <= 0xffff \
or not 0 <= values[1] <= 0xff \
or len(values) == 3 and not 0 <= values[2] <= 0xff:
sys.exit("Arguments out of range.")
print(encode_code(*values))
main()