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


← Archive

Trivial Pursuit (Genus / Boomer / Young Players)

Bally Sente · 1984-85 · SAC-1 board · Motorola 6809 · 3,489 records across 4 editions

Trivial Pursuit marquee


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


More cracks

Cross-archive analyses


  1. Trivial Pursuit (Genus Edition)1 (1984, Bally Sente / Horn Abbot Ltd.) · Arcade-Museum · Flyer · MAME romset: triviag1 ↩︎