Cracking Bally Sente Trivial Pursuit
How we decoded base-40 radix encoding to extract 3,489 Trivial Pursuit questions from 1984 arcade ROMs
April 4, 2026 · crack, bally-sente, trivial-pursuit, 6809
Trivial Pursuit (Genus / Boomer / Young Players)
Bally Sente · 1984-85 · SAC-1 board · Motorola 6809 · 3,489 records across 4 editions

The Game
In December 1984, if you paid the coin-op price of a can of soda at a bar or bowling alley, you could sit down at a Bally Sente Trivial Pursuit cabinet and play the year’s most-talked-about board game as an arcade. The cabinet was a small cocktail-style table with a color monitor embedded face-up under a glass top, surrounded by four colored trackball-less buttons (blue, pink, orange, green), each one matching a Trivial Pursuit category wedge. You picked a category, answered a question, and racked up wedges. Five correct answers in a single game bought you your initials on the high-score screen. Ten dollars’ worth of quarters could carry a bar night.
Bally Sente started as Videa in 1982, founded by ex-Atari engineers Roger Hector, Howard Delman, and Ed Rotberg. Nolan Bushnell announced the acquisition in January 1983, renamed it Sente Technologies that October, and folded it into his Pizza Time Theatre. When Pizza Time hit Chapter 11 in early 1984, Bally Manufacturing bought Sente in May 1984 for $3.9M and rebranded it Bally Sente. Sente’s pitch to operators was the SAC-1 board, a Motorola 6809 “Sente Arcade Computer” that could swap entire games by changing a single ROM cartridge (a concept Bushnell had wanted for Atari and never built). Trivial Pursuit was the SAC-1’s breakout title. Bally Sente licensed the board game from Horn Abbot and shipped six Trivial Pursuit editions on the same cabinet between late 1984 and 1987: Genus, Genus II, All Star Sports, Baby Boomer, Young Players, and the Spanish-language Ataque Trivial (via Maibesa). Same cabinet, new question packs, early rotating-content arcade DLC.
The Data
3,489 questions across 4 editions live at
/browse?source=bally_triviag1
and the
sibling source IDs (bally_triviag2, bally_triviabb, bally_triviayp).
A fifth edition, All Star Sports, uses different ROM naming and a
rearranged pointer table; we cracked it separately →
.
How We Cracked It
The Question
The ROMs were dumped into MAME decades ago, but nobody extracted the questions. Open one in a hex editor and every byte looked like noise. No plaintext strings, no ASCII runs, no obvious repeating structure. The encoding was undocumented, invisible to standard tools, and uniform across all four Genus-family editions.
Base-40 Radix
The trick is radix encoding. Every 2 bytes encode exactly 3 characters using base-40 arithmetic:
val = (hi << 8) | lo max value: 65,535
char0 = val / 1600 (40 × 40)
char1 = (val % 1600) / 40
char2 = val % 40
Why 40? Because 40^3 = 64,000, which fits neatly in a 16-bit unsigned integer (max 65,535). Three characters in two bytes, that is a 33% savings over ASCII, which needs 3 bytes for 3 characters. On a 6809 system with 48KB of question ROMs, that savings means hundreds of extra questions.
The 40-Symbol Alphabet
The character set is minimal but clever:
Index Symbol
───── ──────
0-9 '0'-'9' (digits)
10-35 'A'-'Z' (uppercase letters)
36 capitalize (next letter becomes uppercase)
37 '.' (period)
38 ''' (apostrophe)
39 ' ' (space)
Everything decodes as lowercase by default. Symbol 36 is a shift flag, it does not emit a character, but marks the next letter as uppercase. This is how proper nouns and sentence starts work without needing both upper and lowercase in the alphabet (which would require 66+ symbols and break the base-40 math).
Decoding Example
Take the bytes 0x27 0xA4:
val = (0x27 << 8) | 0xA4 = 10148
char0 = 10148 / 1600 = 6 → '6' (digit)
char1 = (10148 % 1600) / 40 = 13 → 'D' → 'd'
char2 = 10148 % 40 = 28 → 'S' → 's'
Result: "6ds"
A more interesting example, how capitalization works. The bytes encoding
“What” would decode as four raw symbols: [36, 33, 17, 10, 30], that is
[capitalize, W, H, A, T]. The capitalize flag fires, making W uppercase,
then the remaining letters emit lowercase: "What".
The decoder in Python:
ALPHA = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
def decode_b40(data, addr):
raw = []; i = addr
while i + 1 < len(data):
hi, lo = data[i], data[i+1]
if hi == 0xFF: # terminator
break
val = (hi << 8) | lo
raw.extend([val // 1600, (val % 1600) // 40, val % 40])
i += 2
text = []; cap = False
for d in raw:
if d == 39: text.append(' '); cap = False
elif d == 36: cap = True
elif d == 37: text.append('.')
elif d == 38: text.append("'")
elif d < 36:
c = ALPHA[d]
text.append(c.upper() if cap else c.lower())
cap = False
return ''.join(text).strip()
Each string is terminated by 0xFF.
Genus I: Pointer Tables
The first edition (triviag1, December 1984) stores questions in 6 x 8KB ROMs (48KB total). Two pointer tables index into this data:
Question table: 545 entries × 4 bytes
[prefix_byte] [unused] [ptr_hi] [ptr_lo]
Answer table: 545 entries × 8 bytes
4 × [ptr_hi] [ptr_lo] (correct answer first, then 3 wrong)
The prefix_byte is a pointer to one of 15 pre-stored question prefixes.
common openings like “What”, “Who”, “Where”, “How many”, “What is the”. The
game concatenates the prefix with the question fragment to form the full
question. This saves additional ROM space: instead of storing “What is the”
hundreds of times, it is stored once and referenced by index.
Prefix table (15 entries):
[0] "What"
[1] "What is the"
[2] "Who"
[3] "Where"
[4] "How many"
...
Split AB/CD Format
By March 1985, Bally Sente had shipped three more editions, Genus II, Baby Boomer, and Young Players, using a different ROM layout. Instead of a single concatenated ROM, the data is split:
AB ROMs (4 × 16KB = 64KB): Base-40 encoded text
- AB[0..14]: 15 prefix phrases
- AB[15..974]: Question fragment strings
- AB[975..]: Answer strings (correct + wrong)
CD ROMs (2 × 16KB = 32KB): Index tables
- 0x0000-0x0B3F: Question table, 960 × 3-byte entries
[prefix_offset] [ptr_hi] [ptr_lo]
- 0x2000-0x3DFF: Answer table, 960 × 8-byte entries
4 × [ptr_hi] [ptr_lo] per question
The question table entry is 3 bytes: one byte for the prefix offset (pointing into the AB ROM’s prefix table), and a 16-bit pointer to the question fragment in the AB ROM. The answer table has four 16-bit pointers per question, correct answer first, then three wrong answers.
This split design let Bally Sente keep the same game code while swapping question content. Each edition was just a new set of AB/CD ROM chips.
Results
3,489 unique questions extracted across 4 editions:
Trivial Pursuit Genus I (Dec 1984): 545 questions
Trivial Pursuit Genus II (Mar 1985): 960 questions
Trivial Pursuit Baby Boomer (Mar 1985): 992 questions
Trivial Pursuit Young Players (Mar 1985): 992 questions
Sample (Genus II):
[Q] What is the largest planet in our solar system?
✓ Jupiter ✗ Saturn / Neptune / Mars
[Q] Who wrote "The Catcher in the Rye"?
✓ J.d. Salinger ✗ Ernest Hemingway / F. Scott Fitzgerald / John Steinbeck
The base-40 encoding was a smart trade-off for 1984: sacrifice the full ASCII range (you cannot represent lowercase distinctly, and punctuation is limited to period and apostrophe) in exchange for 33% compression. For a trivia game that only needs letters, digits, and a few symbols, it is exactly enough.
Arcade Trivia Archive, data extracted from MAME ROM dumps using custom Python decoders.
Extractors: scripts/bally_sente/extract.py, scripts/bally_sente/analyze_g2.py
References
Related
More cracks
Cross-archive analyses
Trivial Pursuit (Genus Edition)1 (1984, Bally Sente / Horn Abbot Ltd.) · Arcade-Museum · Flyer · MAME romset:
triviag1↩︎