Cracking Super Trivia Master (1986)
Enerdyne's Super Trivia Master hid its questions in an LZ-style self-referential phrase table spread across eight banks, read through a single I/O port. Token decoder reverse-engineered from the Z80 firmware; 4447 questions recovered.
April 19, 2026 · crack, enerdyne, strvmstr, z80
Super Trivia Master
Enerdyne Technologies / PGD Inc. · 1986 · ettrivia board · Z80 @ 4 MHz · 4447 records across 8 category banks
The Cabinet
Super Trivia Master1 shipped in 1986 from Enerdyne Technologies
of El Cajon, California, published by PGD Inc. Enerdyne was a small
West Coast outfit best remembered for producing cabinets distributed
through PGD into bars and bowling alleys. The game ran on a Z80 @ 4 MHz
with three AY-3-8910 sound chips and eight 32 KB question ROMs organized
into four banks of paired hi/lo-byte chips. MAME tracks the hardware
under its ettrivia driver.
Eight categories, one per chip pair:
- Sports (sports.hi0)
- Sex II (sex2.lo0)
- Movies & TV (movies.lo1)
- Rock and Pop (rock-pop.hi1)
- Cars, Boats and Planes (cars.hi2)
- Science Fiction (sci-fi.lo2)
- Entertainment (entrtn.hi3)
- Potpourri II (potprri.lo3)
The Data
All 4447 records browse at /browse?source=enerdyne_strvmstr . 8 categories, all multiple-choice, decoded straight from the ettrivia phrase tables. A sister cabinet, Progressive Music Trivia , shares the same decoder and adds 4199 more records.
- Extractor:
scripts/enerdyne/strvmstr.py - MAME driver:
mame/src/mame/misc/ettrivia.cpp
How We Cracked It
The I/O Mapping
Unlike Merit’s 6221 (question ROMs in memory space) or GEI’s T3 (ROMs
compressed to 5-bit packed words), Enerdyne’s board puts the question
ROMs in the Z80’s I/O space. The Z80 selects a bank by writing bits
3-4 of memory port 0x9000 (control_w in MAME), then reads
successive bytes by issuing IN A,(C) with C = 0x08. Bank offsets
are kept by the program code, not by the hardware.
The Encoding
Each chip stores three things concatenated:
- A 12-byte pointer header at byte 0, six little-endian 16-bit
words pointing to sub-regions of the chip:
- W0, W1: secondary content pointers
- W2: start of the phrase-length table (one byte per phrase, values 1-15)
- W3: start of the phrase-text blob (concatenated uppercase ASCII, no separators)
- W4, W5: repeated marker (unused)
- A 22-byte chip-name string followed by 0xFF padding to offset
0x30. - The record stream starting at
0x30.
For the HI chips (loaded at bank offset 0x8000) the header offsets
are chip-relative and need +0x8000 to become bank-absolute; for the
LO chips they’re already absolute.
The Record Stream
At chip offset 0x30 the record stream begins. It’s a sequence of
length-prefixed blocks, one per question: the first byte is the
length of the whole block, counting itself, so the next block starts
N bytes on. Inside each block the encoding interleaves ASCII
characters with token references:
| Byte range | Meaning |
|---|---|
0x01-0x17 | Two-byte phrase token, index = ((byte « 8) | next) − 0x60 |
0x18-0x1E | Field separator (between Q and answers, and between each answer; only 0x1E is ever used) |
0x1F | Tune cue (consumes 2 trailing bytes, the tune to play) |
0x20-0x5F | Literal ASCII, uppercase letters, digits, punctuation |
0x60-0xFF | Single-byte phrase token, index = byte − 0x60 |
The Phrase Decoder
The Z80 decoder at program-ROM offset ~0x0ED0 takes a token byte (or
token byte-pair), computes an index, and walks forward through the
chip’s phrase-length table accumulating lengths to step over
earlier phrases. When it reaches the target phrase’s slot it reads
that phrase’s length, then issues that many IN A,(C) reads from the
phrase-text blob. Each byte is decoded by subtracting 0x20 and the
result is written directly as a tile index into video RAM at
0xC000/0xE000, the font tile ordering matches the ASCII ordering,
so no separate character table is needed for phrase expansion. The
earlier research notes claimed a 64-char ASCII lookup at 0x2B7A was
used by the decoder; that table is actually for the name-entry /
high-score path at 0x0F31, not for question rendering.
For two-byte tokens (first byte 0x01-0x17) the decoder initialises
H = first_byte, L = 1 and iterates over ((L-1)*256 + H_init - 1)
phrases. Phrase indices are per-chip, so a record’s tokens all resolve
inside the same chip’s phrase table.
Splitting Records
Walk the blocks from 0x30, hopping by each length byte. That lands
exactly on the phrase table (header word W2) on every chip, which is a
nice check that the walk is right. Each block is one question: split it
on 0x1E to get exactly four fields, question, correct answer, wrong
answer 1, wrong answer 2.
We used to think the length byte didn’t count itself. That’s one byte off, and it meant every block swallowed the next block’s length byte. Questions got glued together (“What Is Merkin A Pubic Wig An Aphrodisiac A Courting Dance!how Did Mata Hari Meet Her Death”), the first one lost its answers, and bits of text went missing. Counting the length byte fixed all of it and more than doubled the yield.
Yield
Sports (sports_leisure) 702
Science Fiction (entertainment) 626
Rock and Pop (entertainment) 615
Entertainment (entertainment) 565
Movies & TV (entertainment) 514
Potpourri II (wild_card) 510
Cars, Boats and Planes (wild_card) 459
Sex II (wild_card) 456
─────────────────────────────────────────
Total 4447
What’s Unresolved
Almost nothing. We used to think some two-byte tokens pointed into a secondary table in another bank, and we dropped those records. That was the off-by-one again. With the blocks read correctly every token on every chip resolves in its own chip’s phrase table.
Three Sports records (the John Havlicek / Red Auerbach Hall of Fame block) are chopped into fixed 15-byte pieces in the ROM, so their fields come out rotated. The real cabinet shows them garbled too, so we leave them out.
References
Related
More cracks
Cross-archive analyses
Super Trivia Master (1986, Enerdyne Technologies) · Arcade-Museum · MAME romset:
strvmstr↩︎