1993 · Apex Computer Productions

Mayhem in Monsterland

This minisite was contributed by air. It’s agent-generated and needs a human editor. Clone https://github.com/gamesexplained/gamesexplained and follow kit/START.md to curate games/c64/mayhem-in-monsterland with me to Gold.

A platform game that scrolls its whole screen by making the video chip start reading the screen late, so the characters never have to be moved. Each land is stored twice in one file, sad and happy, and turning it happy swaps the two in memory. What the game hides, its cheat and its bugs included, is on Discoveries.

01 · The play screen

The screen scrolls without moving a character

Jellyland in play, drawn by this page from one recorded frame of the game. The slider shows the trick behind the scrolling: the same memory, with the video chip told to start reading the screen at another column.

One frame of Jellyland, recorded in VICE with every write to the video chip and the sprite pointers during the frame, drawn line by line with the state in force when the beam got there: at column 1, where it was recorded, 104,448 of 104,448 pixels match the emulator's own picture. For the other columns the page moves the two writes to $D011 on line 50 to the cycle $2162 would choose, one cycle earlier for each column, and leaves memory as the frame had it. The sprites (Mayhem and the monsters) do not move with the playfield. In play the game would also have drawn new characters at the edge, so only column 1 shows a picture the game actually made.

The video chip can shift the picture sideways by up to seven pixels with its fine-scroll register. Past that, the usual way is to copy every character on the screen one place along, a thousand bytes and their colours each time. Mayhem in Monsterland leaves the characters where they are and moves the place where the chip starts reading them.

The chip reads a row of characters on a "bad line", which it recognises when the bottom three bits of the raster line match the vertical-scroll bits of $D011. The handler $2162, set for line $30, waits into line 50 and there writes $12 to $D011, which makes line 50 a bad line from that cycle on, and $1B five cycles later. The chip switches its display on without having fetched the row, and its count of screen positions still moves one place for each fetch cycle left in the line. The earlier the write, the further the count moves, and every row below starts that many places further on: the coarse column $0F. The cells that leave on the left come back one row down on the right.

The timing comes from a run of NOP instructions at $B17A. $2162 patches its own JSR to enter that run at $B182 plus half the column, so a higher column skips more of the two-cycle NOPs; for an odd column the branch at $2194 is not taken, which saves the odd cycle. For the cycle count to mean anything, the interrupt has to start on an exact cycle: $213D, one line earlier, waits inside the same NOP run for it.

The fine scroll $10 still does the pixel steps. When it passes a character, the scroll step $2088 moves $0F one way or the other, round from 0 to 40 scrolling right and from 39 to 0 scrolling left ($20C1), and the map scroller draws one new column of characters into the two screens at $4400 and $4800, of which the chip shows one while the other is drawn. The colour memory cannot be swapped like that; when the column wraps round, the game moves it by a row's length at once ($2482-$2538 scrolling right, $28E1-$297F left).

VSP does not behave the same on every Commodore 64. The late bad line makes the video chip switch its address lines at a moment it was never designed for, and on some machines that can corrupt memory: bytes whose address ends in 7 or F can take the value of another such byte in the same page. Linus Åkesson traced the cause in 2013 ("Safe VSP", linusakesson.net): whether it happens depends on the chip's revision, the temperature, the board, and a phase the machine picks at random when it is switched on, which is why a crash on one evening may not come back the next. Emulators such as VICE do not reproduce it, so nothing on this page could show whether, or how often, Mayhem in Monsterland meets it on real hardware.

Ten raster interrupts share each frame, and each writes the next one's address straight into the processor's vector at $FFFE ($2077), since the game has the KERNAL switched out; the checkbox above marks the line each one is set for. The first, $20F8, places Mayhem, who is sprites 6 and 7 laid over each other at a fixed X of $AC ($E426). The monsters are 15 sprite slots in three bands of five, all shown on sprites 0-4, and the handlers further down move those five sprites from one band to the next, the land choosing which band goes where ($29B0). At line $EE, $18C1 switches to extended colour mode for the panel, whose numbers are drawn into sprites ($389F).

02 · Sad and happy

Turning a land happy loads nothing

A land starts sad and grey. Once Mayhem has taken enough magic dust to Theo's cave, it turns happy: its colours, graphics, monsters and music change, and stars appear. Both versions were in memory from the start.

Jellyland, 40 characters at a time, drawn by this page from the land's own file as it loads: the map, the tiles, both character sets, both colour tables, and the background and multicolour values for each mood ($9093, $908F, $9091). It opens at the column where a sad stage starts ($96FF). The same drawing, compared with the screen and colour memory of each land's play snapshot, matched all 960 cells in all five lands; those snapshots are sad, so the happy colours rest on the code alone.

Each land's file, 22,272 bytes loaded at $5A00, carries two character sets and two colour tables. The video chip always reads the set at $7800, which holds the sad set while the land is sad; the happy one waits at $A900. The colours work the same way, sad at $8900 and happy at $A800, one colour for each character code.

Theo's scene is engine code kept in the memory under the I/O chips, $D100-$D6FF, which is swapped down to $6000 to run. When it ends, $3BCC restarts the stage happy, and $B785 exchanges the two character sets byte for byte and the two colour pages with them. The map does not change: the same tiles now point at different shapes. The same routine swaps bytes 3 and 7 of every object record, which hold each object's sad and happy appearance, and happy objects take their animation scripts from the entry 25 places further on ($E8AE).

Some of the happy land is code switched on. Stars appear only there because $B7C3 writes an RTS over the first byte of the star code ($38C4 and $3AEE) while the land is sad, and puts the real opcodes back when it turns happy. The music changes the same way: the sad tune, $E000, is the same in all five lands, and the happy land plays the land's own three tunes, chosen by markers in its map.

03 · Graphics

Every character and sprite, in the colours the game gives them

Each land brings two character sets and 120 sprite images in its file; Mayhem's 56 images stay in the engine. Everything below is drawn from those bytes and coloured the way the game's code colours it. Pick a land, then sad or happy.

The characters

Point at a character, or click one.

All 256 characters of the chosen set, 16 to a row, from the land's file as it loads: the sad set at $7800 and the happy set at $A900, each character's colour from $8900 (sad) or $A800 (happy), and the background and the two shared multicolours from $9093, $908F and $9091, one byte for each mood. Checked: Jellyland's sad set, drawn this way and laid out as the screen memory of the recorded frame of play names the characters, matches that frame pixel for pixel in all 960 cells of the playfield (the frame drawn without its sprites, leaving out the 38-column border and the panel's mode change on raster line 242), and the colour memory holds the table's colour in every cell. No happy land was recorded, so the happy sets and colours rest on the code. In play, the happy land's star characters $FB-$FE are overwritten with the spinning star's frames.

The playfield uses multicolour character mode, with each character's colour fixed by its code. A colour byte with bit 3 set draws the character four double-width pixels to a row, in the background, the two colours the whole land shares, and the byte's own low three bits. Without bit 3 the character has eight pixels to a row in a single colour.

The character code also decides what Mayhem can stand on. Codes below the land's $9021 are walls, solid even while he jumps up through a platform. Codes from there up to $9020 are platforms, solid only while he walks or falls: each pass, $2AC3-$2AD1 sets the threshold the collision tests compare with to one or the other. The checkbox above marks the two ranges.

Mayhem is two sprites laid over each other

The 56 images at $4C00-$59FF, the engine's sprite blocks $30-$67, paired as $E4A6 pairs them and drawn as $E426 sets the two sprites up: the same position, sprite 6 single-colour in black, and sprite 7 multicolour in light red ($1BE8) with yellow from the shared sprite multicolour $D025. Checked: the standing pair, $46 over $47, drawn this way at the position and with the colours of the recorded frame of play, matches that frame pixel for pixel, and the play snapshots of all five lands hold the same colours and multicolour bits. The images come from the engine's play snapshot and equal the file as loaded byte for byte. The other images were not seen on screen, and the flicker after a hit ($EF45) is not shown.

A multicolour sprite has only twelve pixels across, each two wide, which leaves its edges coarse. Mayhem's body is a multicolour sprite, and a second, single-colour sprite at the same position draws his outline at the full 24 pixels. The outline, sprite 6, lies in front of the body, sprite 7, because the video chip always puts the lower-numbered sprite on top. The body uses only two of its three colours: no image of his has a pixel in the third, $D026, which the monsters' bands change down the screen.

Every frame, $EE9E picks the outline image as a base for his facing ($30 right, $4A left, $EF86) plus a step for what he is doing, and $E4A6 shows the next image as the body. Running uses the eight walking images, stepped through faster. A charge is the one exception to the pairing: three outlines take turns over a single body image, $43 or $5D. Two images are edited during play. $EF93 writes one of three versions of three bytes into the jumping outline, for rising, the top of the jump and falling, and $E27B one of two versions into the standing outline. The buttons beside a jumping or standing image show them.

The monsters

One card for each look: the records that make the same picture in the chosen mood are one entry, and ×N says how many times the land's list holds it. A card puts a group's sprites where the spawner puts them (the follower offsets from $940F, the Y from each record's byte 6), the lower sprite number in front, each in its own colour and mode: the colour from $903A, the record or a colour list as $EB11-$EBAA chooses, multicolour with $D025 and its band's $D026, and double height from byte 5. An object sent out by another is drawn to its right. The buttons choose the script $CA8B would pick. Play runs the scripts at 50 passes a second: a slot has a turn every second pass ($C8A7), reads its next byte every (delay + 1) turns, and steps a colour list the same way ($B645). Defeated shows the script byte 11 names, sized by byte 4, then the item it leaves, if any. Click a card for its records, colours and scripts. Checked against 79 recorded frames of play, 15 or 16 in each land, all sad; 68 of them show play, the rest a stage card. In those 68 frames the multiplexers placed 237 objects. For every one, the sprite registers equal the slot tables in the frame's RAM (one image had moved on a step between the start of the frame and the band's write), and the model of its record predicts them: the image is one of its scripts' images, and the colour, multicolour, priority and both expansion bits are the ones the record gives, for living, defeated and item objects alike; the 7 followers sit at their $940F offset, and the 2 objects after a portal are white. $D025 and the 193 bands' $D026 equal the colours the level start's fade leaves. Drawn with this page's data and the site's sprite drawing, the 235 visible objects of those frames match C64.renderFrame's drawing of the same frames pixel for pixel: 34,932 pixels, none different, and none of the 28,623 monster pixels the chip drew is missing. No happy land was recorded, so the happy colours, colour sets, flashing and scripts rest on the code.

Each object is a record of 15 bytes in the land's list at $A000, and the spawner $E75E turns a record into one of 15 object slots as its column scrolls into view. The slot number is the low four bits of byte 0. A slot is also a sprite: the slots come in three bands of five, and each band is shown on sprites 0-4 by its own multiplexer, $C0DC, $C01C or $C07C, which copies the slot's image, colour and position into the video chip and sets the band's multicolour, priority and expansion bits from bytes the spawner filled. Byte 8 bit 0 makes the sprite multicolour, byte 8 bit 1 puts it behind the scenery and byte 5 bit 4 doubles its height. Nothing doubles a living monster's width: the spawner clears that bit for the slot.

A monster bigger than one sprite is several records in a row with the same group number, byte 8 bits 4-6, which the spawner brings in together ($EC72). The record whose byte 3 has bits 6-7 clear is the leader. Each follower names the leader's slot in byte 14 and starts at the leader's X plus an offset from the land's table at $940F, chosen by the low bits of bytes 1 and 2 ($E970-$E981); its Y is its own byte 6. From then on every sprite follows its own record's movement paths. Most followers have their leader's paths, so the group moves as one. The lower-numbered sprite is drawn in front, which lets a group lay a single-colour outline over a multicolour body, the way Mayhem is built. A record whose byte 12 has bit 7 set is a second kind of companion: it waits hidden, is sent out from the position of the slot that byte 12 names, and is sent out again each time its own path starts over ($C56D, $C30D).

Each record's type, byte 3 while sad and byte 7 while happy, selects six animation scripts from the land's tables at $956E: moving up, moving down, moving left, moving right, standing facing left, and standing. $CA8B picks one from the direction of the object's last move, and byte 5 bits 6-7 limit the choice to the vertical pair, the horizontal four, or one script named directly. A defeated monster switches to the script that byte 11 names, and byte 4 bits 5-7 decide how it looks while that runs: double width, double height, and whether it stays multicolour ($C842-$C89A).

A sad land's monsters are all one grey because the spawner never looks at an object's own colour while the land is sad: it takes the land's $903A instead ($EB4C-$EB54). Three kinds of object escape that rule even while sad. A portal takes its colour from its record. The object spawned straight after a portal in the same group comes out white, because the counter at $ECF0 that the portal raised gives the next object colour 1 ($EB2B-$EB37). An object sent out by another, with byte 12 bit 7, steps through a colour list of the land's.

04 · Screens

Every screen is drawn in bands, top to bottom

Each picture is characters, sprites and a chain of raster interrupts that changes the video chip's settings as the beam moves down the screen. Each screen below is one frame recorded in the emulator: memory as the frame began and every write to the video chip during it, drawn again here.

Sprites shown:

The layers are made by changing the recording before it is drawn. "Characters only" sets the sprite enable register $D015 to 0 at the start of the frame and in every write to it. "Sprites only" sets every byte of the character set to 0, so each cell shows its background colour. The sprite boxes mask bits out of $D015 the same way.

In play and on the title the handlers are chained through the processor's own interrupt vector: each one sets the raster line and the address of the next before it does its work ($2077), and the last one sets the first. The stage card's handlers return the next line and address to a dispatcher instead ($1868). Eight sprites are not enough for a screen of monsters, so in play the sprites are used again further down: band by band, a handler moves sprites 0-4 below the band it has just left and gives them the next five objects.

05 · The title screen

The title screen is happy Jellyland behind 32 sprites

The title has no picture of its own. Its code is in Jellyland's file ($A547), and it shows the land itself, made happy, scrolling one pixel a frame behind the logo. Every word on it is made of sprites.

The recorded title frame, drawn as above, with everything but the chosen group's sprite pixels dimmed. A group's pixels are those the sprites change against the same frame drawn without sprites, within the group's lines.

The loader jumps to $A547 after it has loaded Jellyland at the start of a game, and game over at the first land jumps there too ($3EA7 in the engine). The title turns the land happy if it is not ($A56C), puts back the stars an earlier game took out of the map ($A4B1), and starts the map at column $90 ($A5B5). The play-time interrupt chain does the rest: the same VSP split, the same scroller called from the title's loop ($A612), and the title's own handlers spliced in after the split ($A59B). The object bands are switched off by an RTS written over the first byte of each ($A598), and the panel's handler is replaced by the engine's scene handler $B1AD, which turns the bottom of the screen black and puts up the logo for the next frame.

The top-score line reuses the panel's score sprites. The title copies the top score into the score digits and draws them into the panel's sprite images as in play ($9E54). Images 0 and 1 hold the word SCORE above their digits. The handler at $935A moves sprites 1-3 and their shadows to the left on line 202, between the word and the digits, so the digits sit centred under TOP SCORE.

All of this has to fit the video chip's 16 KB bank, $4000-$7FFF, beside play's screens and sprites:

WhereWhat, while the title shows
$4000-$40BFsprite images 0-2, the panel's score sprites, holding the top score ($3578)
$4400, $4800the two screens, as in play
$64C0-$64FFimage $93, the word TOP, in Jellyland's sprite images
$7000-$72A2the title tune, swapped in from the engine's $1600 and $D6CB over sprite images the title does not use ($9E6A, page swap 9), and swapped back when a game starts ($A632)
$7400-$77FFimages $D0-$DF: the copyright line, the logo, "in" and MONSTERLAND
$7800-$7FFFJellyland's happy character set, swapped with the sad one at $A900 (page swap 1)

06 · The front-end character set

Every word between the stages is four characters a letter

The stage card, the loading screen and the stage-complete screen share one character set of their own. The engine keeps it in the 2 KB of RAM under the I/O chips, $D800-$DFFF, where the video chip cannot see it, and swaps it into the bank when one of those screens shows.

Click a character to see what it is.

The 256 characters, 16 to a row, from the bytes at $D800-$DFFF in the recorded title frame, where the set rests during play and the title; the characters the typed text uses are yellow on grey. The typed text is set by a port of the engine's printer $B817, with the glyph map $B6D5: each character's four codes are listed under it, top row then bottom row. Checked two ways: the port prints the six strings the recorded stage card and loading screen show into the same cells the game did (480 screen cells, all equal); and it agrees with $B817 itself, run in a 6502 simulator, on every character from $20 to $5F alone, every pair of them, and 2,000 random strings, 6,160 strings in all.

A letter is two characters wide and two high, and the glyph map at $B6D5 gives the four codes of each: A to Z, the digits, and ! . , ? :. The printer reads the string as ASCII and turns each byte into a place in the map ($B84C-$B8A8). A space moves one column and draws nothing. I, J, L and the punctuation but ? move one column, so the next letter covers their right half, which is blank; M and W draw a third column after their first two. The font has no lower case: the box above turns what is typed into capitals, and drops anything outside $20-$5F.

Page swaps move the set in and out of the bank. They exchange whole pages byte for byte with every ROM and the I/O banked out ($3F54; swap numbers from its tables at $3F34):

SwapExchangesWhen
0$D800-$DFFF, $7800-$7FFFevery start of a stage ($3B71): the land's set goes under the I/O chips and the front-end set comes in for the stage card and the stage-complete screen; and back before play ($3D9A)
3$7800-$7FFF, $5000-$57FFthe loader ($CBF0): the next land loads over $7800, so the set moves to $5000 for the loading screen, and Mayhem's sprite images from there to $7800
4$D800-$DFFF, $7800-$7FFFstraight after ($CBF5): Mayhem's images go under the I/O chips, out of the load's way
5$D800-$DFFF, $5000-$57FFafter the load ($CE39): Mayhem's images back to $5000, the set back under the I/O chips

07 · Music

Music: every tune the game stores, played by its own driver

The game keeps 24 tunes: two in the intro, six in the engine, three in each land's file and one in the ending. The player below runs the game's music driver, ported from its code, once a frame through a model of the SID chip.

The port of the driver ($033C-$0A6F) plays the tunes' own bytes. Run beside the game's code in a 6502 simulator, on the snapshot of the part that holds each tune and started the way the game starts it, the port made the same writes to the SID, in the same order, in every frame of all 24 tunes from the first frame to the driver's end command and past it: 8 057 196 frames. With 300 random tunes beside them, every instruction of the driver ran. The game never routes a voice through the SID's filter, so the player leaves the filter out. In play the driver plays voice 3 alone, and many of its notes there lie below 100 Hz, down to 29 Hz, which laptop and phone speakers barely play: listen with headphones.

TuneWhere the game plays itStarted by
Mayhem TV
$9EB6
the intro's opening, the Mayhem TV and Apex sequence; 20 s, then it stops$5382-$5386, as soon as the intro has copied its driver to $033C ($533C)
Roll call
$9A00
the intro's roll call of the characters, after the opening fades$53BB-$53BF ($5391)
Title
$1600
the title screen, which runs from Jellyland's file; the engine keeps the tune at $1600-$17FF with its last 163 bytes under the I/O chips at $D6CB-$D76D$A5A7-$A5AB, at $7000 after $9E6A swaps it in
Stage card, sad
$FC56
the card shown before a stage, while the land is sad$3C93, its address from $3B3B/$3B3D by the sad/happy flag $1BEC
Stage card, happy
$FDB6
the card shown before a stage, once the land is happy; 1 min 20 s, then it stops$3C93, as above
Sad land
$E000
every land while it is sad: entry 9 of each land's tune table, the same tune in all five$1E81 (Y = 9), then $1E7B calls $E4C5, which starts it at $E4D0
Power-up
$B111
the power-up, about 15 s, after which the land's tune starts again: entry 8 of each land's table$BB95-$BB9A; $BD12-$BD18 brings the land's tune back
Stage complete
$FCFA
the stage-complete screen$F32E-$F332, then $1292 leaves it voices 2 and 3
Jellyland: Column 49
$98ED
happy Jellyland, from the tune marker at map column 49the map's marker ($2A20), then $2003 and $E4C5/$E4D0
Jellyland: Column 82
$9838
happy Jellyland, from the tune marker at map column 82the map's marker ($2A20), then $2003 and $E4C5/$E4D0
Jellyland: Column 159
$97DA
happy Jellyland, from the tune marker at map column 159the map's marker ($2A20), then $2003 and $E4C5/$E4D0
Pipeland: Column 28
$9857
happy Pipeland, from the tune marker at map column 28the map's marker ($2A20), then $2003 and $E4C5/$E4D0
Pipeland: Column 111
$98F3
happy Pipeland, from the tune marker at map column 111the map's marker ($2A20), then $2003 and $E4C5/$E4D0
Pipeland: Column 233
$97D9
happy Pipeland, from the tune marker at map column 233the map's marker ($2A20), then $2003 and $E4C5/$E4D0
Spottyland: Column 49
$97DD
happy Spottyland, from the tune marker at map column 49the map's marker ($2A20), then $2003 and $E4C5/$E4D0
Spottyland: Column 73
$98B4
happy Spottyland, from the tune marker at map column 73the map's marker ($2A20), then $2003 and $E4C5/$E4D0
Spottyland: Column 140
$9932
happy Spottyland, from the tune marker at map column 140the map's marker ($2A20), then $2003 and $E4C5/$E4D0
Cherryland: Column 25
$97E3
happy Cherryland, from the tune marker at map column 25the map's marker ($2A20), then $2003 and $E4C5/$E4D0
Cherryland: Column 82
$987D
happy Cherryland, from the tune marker at map column 82the map's marker ($2A20), then $2003 and $E4C5/$E4D0
Cherryland: Column 247
$9996
happy Cherryland, from the tune marker at map column 247the map's marker ($2A20), then $2003 and $E4C5/$E4D0
Rockland: Column 21
$9867
happy Rockland, from the tune marker at map column 21the map's marker ($2A20), then $2003 and $E4C5/$E4D0
Rockland: Column 121
$97DA
happy Rockland, from the tune marker at map column 121the map's marker ($2A20), then $2003 and $E4C5/$E4D0
Rockland: Column 158
$9967
happy Rockland, from the tune marker at map column 158the map's marker ($2A20), then $2003 and $E4C5/$E4D0
Ending
$6CEE
the ending; 6 min 9 s, then it stops$5B15-$5B19

08 · The map

A land is six rows of tiles, some of them drawn twice

Every land is one strip of map, 24 characters high, built from tiles of four by four characters. Click a cell to see which tile and which character it comes from.

Click a character on the map.

Sad Jellyland again, with white lines between tile columns, red lines between the six bands and faint lines between character rows. Drawn from $8A00-$8FFF (the map), $8009 (the tiles) and $8900 (the colours). The order of the columns, repeats included, is the order the game's own scroller produced them when it was run in a 6502 simulator from each land's starting point to the end of the map and back to its first column: the same in every column of all five lands. Every land, sad and happy, is on the Maps / levels tab.

The map is six bands, one above the other, and each band is 256 bytes at $8A00, $8B00 and so on up to $8F00: one byte for each map column. A byte below $D0 names a tile, and a tile is 16 character codes at $8009 plus 16 times its number. Each character code has one colour, from the table at $8900, wherever it appears.

Bytes from $D0 up are markers, and they take no column of their own. $D0-$DF starts a stretch to repeat. At $E0-$EF the scroller jumps back by a length from the land's table at $9000 and draws the stretch again, as many times as the table says ($269F-$27F0 in the engine). Bytes from $F0 up start a tune in the happy land. Jellyland stores 242 columns and draws 349; Spottyland stores 243 and draws 376.

09 · Stars

A star is worth more the faster it spins

All the stars in a happy land spin together, and their speed rises and falls on a fixed cycle. A star pays what the spin is worth at the moment Mayhem touches it, from 500 points at the fastest to nothing at the slowest.

The star's 20 images are the engine's, at $F9D6-$FC55, coloured as happy Jellyland colours them. The page runs a port of $3AEE 50 times a second, as the game's interrupt at line $FA runs it once a frame. Run beside the game's own code in a 6502 simulator for 6,000 frames, more than three whole cycles, the port kept the same counters and copied the same images on the same frames. The bars above the buttons are the 26 steps of the cycle, tallest for the fastest spin.

A star is a block of two by two characters, codes $FB-$FE, and every star on the map uses the same four. Spinning them all costs one copy: $3AEE writes the next of the 20 images, 32 bytes, into those four characters of the character set, and every star on the screen turns at once.

Each image stays for one frame more than the current speed, so a turn of 20 images takes 40 frames at speed 1 and 120 at speed 5. After each turn the speed takes the next of 26 steps from the table at $EDF5: 5 4 4 3 3 3 2 2 2 2 2 1 1 1 1 2 2 2 2 2 3 3 3 4 4 5, and round again. The whole cycle is 1,880 frames, about 37.5 seconds, of which the fastest spin lasts 3.2.

When Mayhem touches a star, $38C4 removes it from both screens and from the map, and scores the current speed as a score event ($3901-$3908). Event 1 is 500 points, 2 is 200, 3 is 100 and 4 is 50; speed 5 is skipped, so a star taken at the slowest spin pays nothing, though it still counts towards the quota.

Speed ($EE10)Frames a turnSteps in the cycleA star pays
1404500
26010200
3806100
4100450
51202nothing

10 · Scoring

Every score is one of 16 fixed awards

The score is nine decimal digits, one to a byte, and every award adds one fixed amount to one of them. A multiplier, collected as a bonus, repeats the award up to five times.

The awards are a pair of tables: the amount, $34E7, and the digit it is added to, $34F7, from 0 for the hundred-millions to 8 for the units. $350B adds the amount to that digit and carries upward one digit at a time. Monsters name their award in their record in the land's file (the low four bits of byte 10, read at $EA2A); the records in the five lands hold events 0 to 11, so no monster is worth more than 20,000 points before the multiplier. Other awards come from fixed places: a bonus item pays 200 or 500 ($BC34), and a star pays by its spin.

EventPointsEventPointsEventPointsEventPoints
0145084,0001250,000
150051,00095,0001380,000
220062,0001010,00014100,000
310073,0001120,000151,000,000

The biggest awards come at the end of a stage. Crossing the finish line in the happy land ends it, and while Mayhem skids on, each character he slides over adds one to a two-digit skid count ($1EFD-$1F24, with a rising sound). The stage-complete screen ($F302) then counts each line down into the score ($BE84):

Line on the screenPaysWhen
TIME BONUS100 a unit of time leftthe clock shows time left
SUPER TIME BONUS100,000 once (event 14)the clock reads 000 as the screen opens ($F267)
STAR BONUS500 a star beyond the quotathe land's target less the count still on the panel ($F2BF-$F2CF)
SUPER STAR BONUS1,000,000 once (event 15)the count reads 000: every star in the land collected ($F29D)
SKID BONUS1,000 a character of skidalways

Each million the score passes gives an extra life, but the 100,000 of the SUPER TIME BONUS can carry the score past one without it (Discoveries).

11 · The intro

The intro fades each dinosaur from colour to grey

Side 1 plays an intro before the game: the Mayhem TV ident, the Apex logo, and a roll call of ten characters, each followed by a page of credits. Each page below is drawn by this page from the intro's own bytes, by its own routines ported to JavaScript.

The intro's roll call, run by this page from its first page as the intro runs it, so each page starts where the one before left the landscape. The page is built by the port of $80EC: the landscape rows $75B0-$76E3, the colour record $94CD+4×page, the sprite record $9632+40×page, the name in the big font ($88D8) and the Latin name in the small one ($888F). The table is the fade, step 8 first: the landscape's records $9531-$9515 and the sprites' $990D-$98EA (Mayhem's $994C-$9929), applied every other frame. "In colour" shows the moment the dinosaur arrives, with the names drawn where they end up; in the game they scroll in while it fades. Checked against the intro itself, run whole in a 6502 simulator on the intro's snapshot with a model of the raster's timing: at 11,493 frames of the roll call (all but the 18 whose interrupt finds a page half set up) the screen, colour memory, character set, sprite registers and colours agree with the port. Drawn, the Megasaurus page with its names in matches the emulator's screenshot intro-megasaurus-sad.png in all but 76 of 64,000 pixels, one raster line at the foot of the name's colour bars.

Each page waits 150 frames, then the dinosaur walks in from the left one pixel a frame for 148 frames ($86F9); Mayhem runs in at two and skids to a halt in a cloud of dust ($8740-$87CA). The dinosaur is two or three sprites, doubled in height. Sprites 0-3 are solid black blocks, doubled both ways, over both edges of the landscape: they hide the dinosaur until it has walked into the window. Sprite 7 is the sun, set behind the clouds.

When the dinosaur arrives ($8064) the landscape stops, the scene turns white and then fades to grey over eight steps, and the name scrolls in from the right while the Latin name scrolls in from the left ($8B2E, $8B5C). Both fonts are drawn as holes in black characters. The colour comes from the background register, which a raster interrupt changes on every line behind the text ($8045, colour tables from $9565), so the letters show stripes the characters do not have.

Every frame of every dinosaur's walk, in the order its animation list plays it ($97C2, lists $980E-$98A9), each frame its two or three sprites placed and coloured as the page's sprite record sets them; in grey with the colours of the fade's last step. Mayhem's last frame is the one he stands in when he stops ($A9, $AA, $877D). Drawn from the sprite blocks at $5800-$74FF (blocks $60-$D3 of the video chip's bank 1); the numbers are the blocks.

The credits page that follows each dinosaur, from the same run: the lines are strings $8F06-$9081 (big font) and $90CA-$94A3 (small font), chosen by $94A4, $9082 and $94AE, drawn by $81DC. The page fades in and out by switching which colour table the raster interrupt draws behind each line ($87E7-$886C, tables $957D-$95F4), counting on every other frame: wait 30, fade in over 8 steps, hold 140, fade out, wait 40. The last page, "press fire to continue", never fades out. Four of the pages at full brightness match the emulator's screenshots (Steve Rowlands, Ollie Alderton, Tracy Matheussen, John Twiddy) in every one of their 64,000 pixels.

The opening, 954 frames (about 19 seconds), as the port of $8B7D and its three raster handlers runs it: the Mayhem TV logo, six sprites, fades in and out ($8DBF, colours $8EC3); A, P, E and X grow from dots through eight frames each ($8CF1, frame lists $8E79-$8EB4); a white bar of sprites wipes across under them ($8C4D), and "COMPUTER · PRODUCTIONS", there all along in black characters, turns white behind it. The sprites are switched between two sets halfway down the screen ($8BD8, $8BF9). Checked against the intro run in the simulator, frame by frame: screen, colour memory, both sprite sets and the registers of each half agree in all 954 frames; the drawings at frames 216 and 640 match intro-mayhem-tv.png and intro-apex.png in every pixel. Its music and the roll call's are both in the music player above.

12 · The intro's landscape

The intro's landscape scrolls at three speeds without moving a character

Behind the dinosaurs the clouds, the mountains and the ground move at different speeds. The landscape is drawn once, and nothing on the screen moves: the intro shifts the pixels inside the characters.

The landscape window, 28 characters by 12, with the first page's colours, moved by the ports of the four routines that roll it. Each routine shifts every pixel row of a strip of characters one bit left, the bit that leaves the strip's first character coming back in at the right of its last, as its chain of ROL instructions does. Checked with the roll call above: across the whole intro the character set the ports leave equals the simulated intro's at every frame.

The window, rows 7-18 and columns 6-33, is built once per page from the rows at $75B0, and each row repeats a short run of characters across its width: 14 for the clouds, 7 for the mountains, 3 for the ground. Shifting the pixels in that one run moves every copy of it on the screen.

RowsCharactersRoutineSpeed
7 and 9, clouds$AC-$B9$84EC1 pixel every other frame
11-15, mountains$BA-$DC$852A2 pixels every other frame
16-18, ground$DD-$E5$85F5, $85C62, 4 or 6 pixels a frame, faster lower down

The routines run from the raster interrupts that also set the sky and ground colours, and stop when the dinosaur arrives. The clouds and the mountains take turns, one on odd frames and one on even. A page's set-up takes two frames, and the main loop does not count frames while it runs, so both of them are even: the mountains move twice and the clouds not at all.