1986 · Palace Software

The Sacred Armour of Antiriad

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/the-sacred-armour-of-antiriad with me to Gold.

A line of the title that has never been on the screen, a recharge cell a quick player never sees, a bomb that one stone kills, and a bomb-thrower that never throws.

01 · The title screen

Secret: the title screen hides the words "The Sacred Armour of"

The title picture in memory has one more row than the game draws. It spells THE SACRED ARMOUR OF in red above the ANTIRIAD logo, and it has never been on the screen.

The title screen drawn from the listing in its own characters, the copy of $D000-$D7FF, as draw_title_screen ($8421) draws it: 19 rows of 26 codes from title_picture ($F52E). test_rooms.js checks the screen and colour RAM against the routine run on the simulator. Outside the two sprites, the drawing matches every pixel of the emulator's screenshot on the How it works page. The second button adds title_picture_top ($F514), the 26 codes just before it.

draw_title_screen starts its copy at $F52E, one row after the words. It colours every code from $EE up red and the rest grey, and the 19 rows it draws hold no code from $EE up: the red is there only for the row it skips.

02 · Room J14

Secret: kill J14's striped creature first and its recharge cell never appears

Room $40, J14 on the C64-Wiki's map, holds a recharge cell that waits for the round striped creature beside it. A player who kills the creature quickly never sees the cell, and the wiki's list of the rooms with a cell leaves this one out.

Room $40 and its sprite list at $CDBD, drawn as in Maps / levels. In the emulator the cell appeared about 100 frames after the room was built, and with the striped creature killed first the cell and the three creatures listed after it never appeared.

A room's list fills sprite slots from 7 down. When it is placed, hold_back_group ($8810) looks for the first round striped creature ($D0 or $D1) and gives every slot below it a wait of 100 frames before it starts to appear. When that wait is over, materialise_step ($A0EF) checks the striped creature, and if it has been killed it cancels the slot instead.

Seven rooms put creatures after a striped one, and only J14 puts a recharge cell there. Its list is the striped creature, then the cell, then three more creatures. The cell is one of nineteen, so a player who never sees it can still finish the game.

03 · The bomb

Secret: one stone kills the bomb

The bomb is the most dangerous thing in the game: it takes 32 energy, more than Tal has. It is also the easiest to kill, because it starts with no hit points at all.

DamageHit pointsKills it
A creature that takes 882two stones or one shot
A creature that takes 441one stone or one shot
The bomb320one stone

A creature's hit points are its damage divided by four, set by set_enemy_stats when the room's list is placed. The bomb is not in a room's list: place_bomb ($884F) puts it under the bomb-thrower and gives it an animation, a place and a path, but never calls set_enemy_stats, so its slot keeps the 0 that reset_sprite_slots left. Its 32 would have given it eight. In the emulator a stone on the bomb started its dissolve on the first frame they touched.

04 · Scoring

Secret: a stone kill scores double

A creature killed with a stone scores twice its points. Killed with the Pulsar Beam, or by running into Tal, it scores them once.

The points in enemy_points ($C631) for every creature that can be killed, as score_kill ($A83D) scores them. In the emulator the bomb, worth 20, scored 40 to a stone and 20 to a shot.

score_kill adds the creature's points to the score, then looks at sprite 2, the one the stone and the shot share. If its animation is the stone in flight, $BC, it adds them again. The Pulsar Beam kills more easily, and stones pay better.

05 · Room H11

Bug: the bomb-thrower in H11 never throws

Five rooms have a bomb-thrower, drawn as two sprites side by side. In four of them a bomb comes with it. In room $1E, H11, its two halves are listed the other way round, and the bomb never comes.

Each room with its sprites as a new game places them (room_sprite_ptrs, $CA16). In the emulator rooms $03, $07 and $3B each put the bomb on sprite 5, and room $1E never did.

The list's first entry goes on slot 7 and the second on slot 6. place_bomber ($8841) gives the bomb only when slot 7 holds the left half, animation $C9. Room $1E's list at $CBFF starts with the right half, $CA, at X 200, and then the left half at X 176, so the two halves still sit side by side on the screen and the check fails.

06 · Shared colours

Secret: the creatures change colour when Tal puts the armour on

All eight sprites share two of their colours. The suit needs different ones from Tal, so when he climbs in, every multicolour creature in the room changes too.

The multicolour creatures, the bomb-thrower and the empty armour from anim_ptrs ($FCA6), drawn in each pair of shared multicolours. In the frame recorded in room $2B with the suit worn, the chip held 14 and 11.

A multicolour sprite has one colour of its own and two that every sprite shares, in $D025 and $D026. start_new_game and leave_armour set them to 8 and 9, orange and brown, for Tal. When Tal has dissolved into the armour, dissolve_step ($9F60) sets them to 14 and 11, light blue and dark grey, for the suit. Every multicolour creature in the room takes the same two colours, so its picture changes the moment Tal is in the suit.

07 · Tuning

Music: every note is tuned for an American C64

On a European PAL machine every note of the music plays about two thirds of a semitone flat. On an American NTSC machine it is in tune.

The game's own driver, as on the How it works page, run at the clock of an NTSC C64, 1,022,727 cycles a second. Every note comes out at the pitch the table meant, and the tempo is 3.8 per cent faster, as it would be on that machine.

The SID plays a frequency in proportion to the machine's clock, and the clocks differ: 985,248 cycles a second on a PAL C64, 1,022,727 on an NTSC one. The driver takes its notes from a table of 192 frequencies a quarter tone apart (note_freqs), and its entry for the A above middle C is $1C31.

MachineClock$1C31 plays
NTSC1,022,727 Hz439.9 Hz
PAL985,248 Hz423.8 Hz

On the American clock $1C31 plays 440 Hz, concert pitch, so the table was worked out for that machine. On a PAL machine the same entry plays 424 Hz, and every note is 65 cents flat, about two thirds of a semitone. The tempo is set by CIA timers counted in cycles, so on a PAL machine it is 3.7 per cent slower too.

08 · Room J13

Bug: room J13 has an exit down to a room that does not exist

Every room lists the room beyond each of its four edges. Room $32, J13, names room $45 below it, and there are only 69 rooms, $00 to $44.

Room $32 with the cells that stop a fall marked, and its links from room_links ($F25A + 4 × room). In the emulator its bottom row was solid in colour RAM across all 40 columns.

The exit is never used, because the floor of J13 is solid from edge to edge and Tal cannot fall through it. Room $45 has no map, and the 70th pointer in the sprite lists, the one it would use, points at the empty list.

09 · The start

Secret: the first game after switching on always starts in B14

A new game starts at one of the two ends of the bottom row, B14 or N14. The first game after the machine is switched on always starts at the left end.

Rooms $38 and $44, the two in start_room ($C5DB). In the emulator the first game after switching on began in $38.

start_new_game ($8E43) picks the end by bit 0 of zp_pass_count, a count of passes of the main loop. The count starts at 0 and the title screen does not run the main loop, so on the first game it is still 0 and Tal starts in $38. Every later game starts at whichever end the last game's count left.

10 · The first stone

Bug: until Tal's first stone lands, a doorway can take him two rooms on

The game keeps a flag for a stone Tal has asked to throw, and nothing clears it when a game starts. On a machine that has just loaded the game the flag is already set, and until his first stone has landed, walking out of a room at the side can carry him straight through the next one too.

The eight instructions at $A3BE-$A3CD in throw_stone, run on a 6502 from the listing, with the exit to the right in move_right ($99FA-$9A0B) put in where the raster interrupt takes it. Tal starts at X 292 with both his high bits set and no stone out. In the emulator, from this build's start with no stone thrown, Tal walked out of room $3E at the right and was in $40 seven frames later. With $7C set to 0 first, the same walk stopped in $3F.

zp_throw ($7C) has bit 7 set while Tal has asked to throw. The game sets it when he throws, and clears it only when the stone has gone, off the screen or broken on the scenery. Bytes $73 to $8F of zero page are where the KERNAL copies BASIC's routine for reading the next character of a line, and the seed of its random numbers, when the machine is switched on. $7C is that routine's CMP instruction, $C9, which has bit 7 set.

While the flag is set and the stone's sprite is free, throw_stone runs on every pass of the main loop, dozens of times a frame, waiting for Tal's throwing picture. Each time it copies bit 0 of spr_xhi, the ninth bit of Tal's X, into bit 2, the stone's, reading and writing spr_xhi twice. When Tal walks out at the right, the raster interrupt moves him to X 50 and clears his high bits. If it comes between a read and the write after it, that write puts the old bits back. Tal is then at X 306, past the right edge, and he goes straight out of the new room as well. Walking out at the left it works the other way round: he is put back at X 44, past the left edge.

The first stone Tal throws ends it. When that stone lands the flag is cleared, and it stays clear for every later game until the machine is switched off.

11 · The alphabet

Secret: the panel can spell German words

Besides A to Z, the panel's text has eight more marks. Three of them are A, O and U with umlauts, which no message in this release uses.

The panel's characters from its set at $7000: the plain letters at their codes (the letter's ASCII value plus $5B), and the marks from text_punct ($C5CB) at the codes in text_punct_chars ($C5D3).

A message writes the marks as lower-case a, o and u, which scroll_message turns into characters $C6 to $C8. The UK text never writes them.