In the emulator

The pictures are built from the ROM, not captured. openMSX is used for two things: to check those pictures against the real VRAM and to test what the code says about the game.

Everything with openMSX and the C-BIOS_MSX1_JP machine, one emulator at a time.

The check

tools/omsx_vuelca.tcl dumps the VRAM, the RAM from 0xE000 to 0xFFFF and the VDP registers at the given seconds, pressing space where needed. tools/omsx_fase.tcl starts the game on any stage: it writes the stage to 0xE111 at the call monta_la_fase at 0x4209, only once, and dumps a few seconds later.

tools/coteja_todo.py builds each screen with tools/pantallas.py and compares it with its dump: the whole name table, the pattern and colour of every tile in use, the visible sprites and their patterns. The time, the lives, the objects and the sprite turn of that frame come from the dump's RAM.

screendifferences
Konami logo0
title0
stage 10
stage 110
stage 210
stage 410
stage 500
duel, stage 310
bonus after stage 30
0x6757 viewer over stage 10
0x6757 viewer over the title0

In both viewers the tiles each screen builds are compared; the rest are leftovers from earlier ones. The title, besides, is built on top of the Konami logo's VRAM: nine of its tiles keep the colour the logo left them.

Two measurement traps. The sprite table is written at the start of the frame and the objects move afterwards: a dump taken mid-frame has the RAM's Y one step ahead of the VRAM's. And the copy of the name table is sent a quarter at a time, one per frame: a digit of the time can be one frame behind.

The tests

tools/omsx_prueba.tcl reads a list of timed orders (write a byte, press a key, dump) and tools/lanza_prueba.sh runs it. The five in tools/pruebas/:

testwhat is donewhat happens
linea.txton stage 1, five cubes on row 4 marked as finishedstage cleared (game steps 2, 4 and 5) and the time is paid: 430 points for 43 seconds
vida.txtthe streak of three set to 1, 1, 1the object appears at Q\*bert's Y, crosses, and the lives go from 2 to 3
continue.txtno lives and the time at 1GAME OVER; with F5, the game again with two lives in reserve
pausa.txtF1 twicethe time stays at 99 until the second F1
bonus.txtstage 3 and stage clearedbit 0 of the mode turns on and the bonus stage starts

The twelve pieces nobody calls

tools/omsx_huerfanos.tcl runs them in a game, one per frame: at 0x40C5 it stacks the return, jumps to the piece with the registers it needs and records what it did. The last one is the viewer, and the emulator stays paused with it on screen (tools/lanza_huerfanos.sh).

piecewhat it does
0x640Dwith stage 0x23 it returns A=09: the minimum of the stage minus one and 9
0x45FDswaps 4 bytes between HL and DE
0x4643sets up a VRAM read and leaves port 0x98 in C'
0x705Estores joystick 2: with A=05, 0xE32F=05 and 0xE330=05
0x7068reads E, S, F and C: with E held, A=01 (up)
0x722Cthe cube under Q\*bert against the model: not equal
0x77CCwrites 0x5A into fourteen objects in a row
0x833Cthe other player is not falling (with one player there is no other)
0x9032the life object against the second sprite: they do not touch, and it moves one pixel
0x821Atakes a life (from 2 to 1) and draws the duel score line
0x8275makes Q\*bert fall dead: state 12 and the falling arc
0x6757the pattern viewer

Running it

tools/lanza_vuelca.sh work/v1 "6 12" "10"
tools/lanza_fase.sh "11 0 0 3"
tools/lanza_prueba.sh tools/pruebas/vida.txt
tools/lanza_huerfanos.sh
make coteja