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; 745 questions recovered.

April 19, 2026 · crack, enerdyne, strvmstr, z80


← Archive

Super Trivia Master

Enerdyne Technologies / PGD Inc. · 1986 · ettrivia board · Z80 @ 4 MHz · 745 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:

The Data

All 745 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 852 more records.


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:

  1. 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)
  2. A 22-byte chip-name string followed by 0xFF padding to offset 0x30.
  3. 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: the first byte is the remaining byte count, the next N bytes are the block body. Inside each block the encoding interleaves ASCII characters with token references:

Byte rangeMeaning
0x01-0x17Two-byte phrase token, index = ((byte « 8) | next) − 0x60
0x18-0x1DNew-question separator (renders as space, splits Q/A units)
0x1EInline field separator (between Q and answers, and between each answer)
0x1FSection boundary (consumes 2 trailing pointer bytes)
0x20-0x5FLiteral ASCII, uppercase letters, digits, punctuation
0x60-0xFFSingle-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

Flatten all blocks end-to-end, then split on 0x18-0x1D to break the stream into one logical record per “new-question” marker. Inside each unit, split again on 0x1E to get exactly four fields: question, correct answer, wrong answer 1, wrong answer 2.

Yield

Rock and Pop (entertainment)          121
Potpourri II (wild_card)              119
Movies & TV (entertainment)           116
Sports (sports_leisure)                98
Entertainment (entertainment)          82
Cars, Boats and Planes (wild_card)     79
Science Fiction (entertainment)        67
Sex II (wild_card)                     63
─────────────────────────────────────────
Total                                 745

What’s Unresolved

Two-byte tokens whose prefix is >= 0x10 reference phrase-table indices beyond each chip’s dictionary size (4,096+ entries into tables of only 1,500-2,400 phrases). The Z80 counter arithmetic does compute those indices, they are not truncated, but the actual lookup routes through CALL 0x04A9 which pulls from a secondary table populated at startup by a probe at 0x13F0 that reads magic bytes from port 0x0A/0x0B of each bank. Resolving those cross-bank tokens cleanly requires either running the full Z80 init path in an emulator or capturing the populated table via hardware trace. Records that contained unresolved cross-bank tokens were dropped rather than guessed, this costs ~20-30% potential yield per chip.


References


More cracks

Cross-archive analyses


  1. Super Trivia Master (1986, Enerdyne Technologies) · Arcade-Museum · MAME romset: strvmstr ↩︎