# Technical Overview
Game Genie codes are 6 or 8 characters.
6-character codes translate to a 15-bit address and 8-bit data byte.
8-character codes are the same but include a compare byte, which is used to conditionally return a value based on an existing in-memory value (which is largely there for [[bank switching]]).
## Code Mapping
Game Genie codes use the following mapping:
| A | 0 |
| --- | --- |
| P | 1 |
| Z | 2 |
| L | 3 |
| G | 4 |
| I | 5 |
| T | 6 |
| Y | 7 |
| E | 8 |
| O | 9 |
| X | 10 |
| U | 11 |
| K | 12 |
| S | 13 |
| V | 14 |
| N | 15 |
## Decoding
Decoding consists of:
1. Turning the code into numeric values.
2. Applying bitmask operations to generate an address and a data value.
The way this is done is dependent on the code length.
### 6-Character Codes
This is done as follows:
```python
n0, n1, n2, n3, n4, n5 = [
CODE_TABLE[c]
for c in code
]
address = (
0x8000 +
((n3 & 0b0111) << 12) |
((n5 & 0b0111) << 8) |
((n4 & 0b1000) << 8) |
((n2 & 0b0111) << 4) |
((n1 & 0b1000) << 4) |
(n4 & 0b0111) |
(n3 & 0b1000)
)
data = (
((n1 & 0b0111) << 4) |
((n0 & 0b1000) << 4) |
(n0 & 0b0111) |
(n5 & 0b1000)
)
```
### 8-Character Codes
This is similar. In fact, `address` is the same as before, but `data` has changed and we now set `compare`:
```python
n0, n1, n2, n3, n4, n5, n6, n7 = [
CODE_TABLE[c]
for c in code
]
address = (
0x8000 +
((n3 & 0b0111) << 12) |
((n5 & 0b0111) << 8) |
((n4 & 0b1000) << 8) |
((n2 & 0b0111) << 4) |
((n1 & 0b1000) << 4) |
(n4 & 0b0111) |
(n3 & 0b1000)
)
# Only the last OR value changes.
data = (
((n1 & 0b0111) << 4) |
((n0 & 0b1000) << 4) |
(n0 & 0b0111) |
(n7 & 0b1000)
)
compare = (
((n7 & 0b0111) << 4) |
((n6 & 0b1000) << 4) |
(n6 & 0b0111) |
(n5 & 0b1000)
)
```
### Combined
```python
n = [
CODE_TABLE[c]
for c in code
]
address = (
0x8000 +
((n[3] & 0b0111) << 12) |
((n[5] & 0b0111) << 8) |
((n[4] & 0b1000) << 8) |
((n[2] & 0b0111) << 4) |
((n[1] & 0b1000) << 4) |
(n[4] & 0b0111) |
(n[3] & 0b1000)
)
data = (
((n[1] & 0b0111) << 4) |
((n[0] & 0b1000) << 4) |
(n[0] & 0b0111)
)
if len(n) == 6:
data |= (n[5] & 0b1000)
compare = None
else:
data |= (n[7] & 0b1000)
compare = (
((n[7] & 0b0111) << 4) |
((n[6] & 0b1000) << 4) |
(n[6] & 0b0111) |
(n[5] & 0b1000)
)
return address, data, compare
```
## Encoding
To encode, we reverse those operations, turning an address and data into the individual code numeric values and then feeding them back through the translation table.
### 6-Character Codes
```python
n0 = ((data >> 4) & 0b1000) | (data & 0b0111)
n1 = ((address >> 4) & 0b1000) | ((data >> 4) & 0b0111)
n2 = (address >> 4) & 0b0111
n3 = ((address >> 12) & 0b0111) | (address & 0b1000)
n4 = ((address >> 8) & 0b1000) | (address & 0b0111)
n5 = ((address >> 8) & 0b0111) | (data & 0b1000)
code = ''.join(
REVERSE_CODE_TABLE[n]
for n in (n0, n1, n2, n3, n4, n5)
)
```
### 8-Character Codes
```python
n0 = ((data >> 4) & 0b1000) | (data & 0b0111)
n1 = ((address >> 4) & 0b1000) | ((data >> 4) & 0b0111)
n2 = (address >> 4) & 0b0111
n3 = ((address >> 12) & 0b0111) | (address & 0b1000)
n4 = ((address >> 8) & 0b1000) | (address & 0b0111)
n5 = ((address >> 8) & 0b0111) | (compare & 0b1000)
n6 = ((compare >> 4) & 0b1000) | (compare & 0b0111)
n7 = ((compare >> 4) & 0b0111) | (data & 0b1000)
code = ''.join(
REVERSE_CODE_TABLE[n]
for n in (n0, n1, n2, n3, n4, n5, n6, n7)
)
```
### Combined
```python
n = [
((data >> 4) & 0b1000) | (data & 0b0111),
((address >> 4) & 0b1000) | ((data >> 4) & 0b0111),
(address >> 4) & 0b0111,
((address >> 12) & 0b0111) | (address & 0b1000),
((address >> 8) & 0b1000) | (address & 0b0111),
]
if compare is None:
n.append(((address >> 8) & 0b0111) | (data & 0b1000))
else:
n += [
((address >> 8) & 0b0111) | (compare & 0b1000),
((compare >> 4) & 0b1000) | (compare & 0b0111),
((compare >> 4) & 0b0111) | (data & 0b1000),
]
return ''.join(
REVERSE_CODE_TABLE[i]
for i in n
)
```
## Resources
[Game Genie Technical Notes](https://tuxnes.sourceforge.net/gamegenie.html)