Not one capture here. Every picture is drawn from the bytes of the ROM, by running in Python the very same decompressor, mirror and row builder the Z80 runs, and then checked byte for byte against the VRAM of openMSX: the title screen comes out with zero differences over all 16,384 bytes, and the five stages with zero across their 900 scenery tiles and the 2,048 bytes of sprite patterns. The listing and the numbers are reproducible with make, and reassembling gives back the ROM byte for byte.
For each sprite pattern the cartridge stores the left half: sixteen bytes. The right half is worked out by sube_patrones_de_sprite (0x4743), flipping every byte bit for bit with the eight rr l / rla at 0x4793. That is why everything that flies in Twin Bee is symmetric: both ships, the shots, the bells and the enemies. The same mirror drives the scenery, where sube_espejado (0x4695) uploads the block with bit 0 of C set. Checked: all 2,048 bytes of the sprite pattern table come out identical to the emulator in all five stages.
arranca_la_demostracion (0x5FBF) sets up a real game -same RAM, same stage, same code- and feeds the joystick in through the very same door the player's input uses. What gets played are the 28 values at 0x6016, one every 32 frames, until the 0xFF that cuts the game short. And for the same string of button presses to give the same game every time, the randomness has to be the same too: that is why 0x5FCF sets the Z80's R register to zero, which is where the game gets its random numbers from in the five ld a,r at 0xAF75, 0xB2CE, 0xB757, 0xBE0C and 0xBE36. Without that ld r,a the demo would derail on its own.
The 65 values at 0xB950 are 255 × cos(k × 90/64), and they are the same table as Knightmare's (RC-739): out of 65 bytes only three differ. And those three are exactly the ones Konami fixed. In Knightmare k=58 holds 47 while the previous entry holds 43 -so the table goes up, the one thing a cosine quadrant cannot do-; here it holds 37, which is right. The one that survives is k=46: 105 where 109 belongs, four units short at an angle of 64.7 degrees. It does not break monotonicity, and that is why nobody spotted it.
The script at 0x6D74 chains stretches from the table at 0x6E01, and out come 1,761 row codes. Each code indexes one of the 248 blocks of 32 tiles at 0x6F8F, which is one whole screen row, and 0x6D17 copies it with thirty-two consecutive ldi. The arithmetic closes by itself: between 0x6F8F and 0x8E8F there are 0x1F00 bytes, exactly 248 rows, and the highest code the stretches use is 0xF7 = 247. The strip is not one stage: the table at 0x6132 puts the bosses at rows 261, 585, 945, 1272 and 1760, and when one falls 0x613C uploads the next stage's tiles without moving the screen. So each stage plays its own stretch with its own artwork. Checked in openMSX: the list the game leaves at 0xE400 is this one byte for byte, and the name table is the blocks at (0xEBF0)-r.
sube_el_color_comun (0x9F41) looks at the stage and, if it is the third, uploads the same colour block as the others but with bit 7 of register C set. That bit turns on the permutation at 0x47B5, which swaps nibbles one by one: 12 becomes 6, 6 becomes 12 and 5 becomes 9. With that, the same tile sheet comes out in another palette and the cartridge saves a whole colour set.
This cartridge's decompressor can only write to VRAM: it pushes bytes out through port 0x98 and has no way of leaving them in RAM. So when a compressed table is needed in memory -the 81 values that decide how the two ships join hands- the game decompresses it at 0x3B80, an unused gap in the sprite attribute table, and brings it back to 0xEB00 with LDIRMV (0x5E0F). Video memory doubles as a workbench.
The TMS9918 draws four sprites per line and drops the higher-numbered ones, so a game with many enemies always flickers on the same ones. sube_los_sprites (0x46CE) keeps the first four fixed -the ships and their shots- and uploads the remaining twenty-eight in an order that rotates: (0xE00F) advances by 0x10 every frame and wraps at 0x1E, and inside the loop the step is 0x44. No enemy goes unpainted two frames running, and what you see is not a disappearance but a shared-out flicker.
0x4028, 0x4055 and 0x40FE write to 0x4195, 0x41A1 and 0x47F7, which sit inside the cartridge itself: the ld goes out on the bus and is lost. Had they any effect, the first would leave a pop hl / ret where a djnz is, the second a jp 0x0000 -a reset- and the third would blank the screen by touching the R1 byte of the register table. The first two are identical in Knightmare (RC-739) and The Goonies (RC-734), at the same relative offsets: they come from the framework, not from this game.
Four chunks -0x60CD, 0xBB18, 0xBB25 and 0xBB38- are valid, coherent instructions that no jump enters. At 0x60CD it shows clearly: the jr z at 0x60C9 lands on 0x60D2 and the jr at 0x60CB on 0x60D6, that is just below and just above. It does the same as 0x60DB, which is used. The other three are the 0x10 variants of code that is alive. It was also checked that the word of those addresses appears in no table of the cartridge.
A bell's prize does not come from the colour you see. It comes from a 32-step counter, (0xE364), that advances one place each time a bell is collected and indexes a 32-slot table starting at 0xEB88. That table is not in the ROM: empieza_la_partida writes it by hand with five ld and four rlca (0x5D41–0x5D51), so only five of the thirty-two slots carry a prize -1 power, 2 twin shot, 4 the arm, 8 the weapon and 0x10 the shield- and the other twenty-seven only give points. Read back in the emulator: at 0xEB88 there is 00 00 00 00 01 00 00 00 02 … 04 … 08.
(0xE07D) is the stage number you see, in BCD, and it climbs one at a time up to 99. (0xE076) is the scenery, and when its low nibble reaches six it goes back to 0x11, that is the first one with the high nibble at one (0x6169). From there on the game cycles through the same five sceneries, counting laps in the high nibble. Reaching stage 99 is the only way to finish Twin Bee: 0x618E sets the game-over flag.
At 0x4010 sits the Konami Game Master header, the house cheat cartridge: "CD" 07 40, that is RC-740. The bytes that follow are laid out under a flags byte and the layout adds up: it ends at 0x4025, exactly where code resumes. It declares the scene, the stage and how many there are, the lives, the high score, the score, the mode bits and a routine of this cartridge (0x4103) that the Game Master calls across slots. And right at the end, at 0xBFF7, sits Konami's hidden mark: ba b7 9a ac 81 91 06 40 aa, the title in katakana plus the RC-740. Its last six bytes are exactly the ones Nemesis (RC-742) goes hunting for through slots 0, 0x80, 0x84, 0x88 and 0x8C to know whether Twin Bee is plugged in next door.
Twin Bee's scenery is a 1,761-row strip that the five stages run through back to back: each map is its stage's stretch, with the bosses at rows 261, 585, 945, 1272 and 1760. Three columns, top to bottom and left to right, on the black background of play.
0x47B5.Under each picture is where it comes from and what is on it.
monta_el_titulo (0x4BD3). Checked against the emulator's VRAM it comes out with zero differences over all 16,384 bytes.baja_un_paso (0x4B0A).monta_las_veinticuatro_filas copies into the buffer, starting at map row 23 and going down.0x4B3C and written in three rows of eleven from tile 0xC0 (0x4BF9).0x1800 to 0x1D80: both ships, the arm that stretches out, the shots, the bombs, the bells, the clouds, the score pop-ups and the GAME OVER. Every one comes from half a template, with the right half worked out by the mirror at 0x4743.0x9177 from pattern 0xB0 on, out of the block the table at 0x9191 hands it.0x1D80, because by the time it shows up they are no longer needed.