NEW_LIFE takes a life with DEC (HL) at TAKE_LIFE ($CBDD), and
goes to the game over when that leaves less than none. The usual poke, a NOP
there, does not work: before each new life NEW_LIFE reads that very byte, and
unless it is still DEC (HL) it jumps to address 0 and the Spectrum starts
again (see the facts). So leave the DEC
where it is and aim it elsewhere: the LD HL before it gets ROM address 2
instead of LIVES. DEC (HL) cannot change the ROM, and the byte there, $11 in
the 48K ROM and in the 128's 48 BASIC ROM, less one is positive, so the JP M
after it never goes to the game over.
Tested in the simulator: a villain put on the knight at the start of every
life. Without the poke LIVES went 5, 4, 3, 2, 1, 0 and the sixth death was the
game over. With it, twelve deaths the same way and LIVES stayed at 5, the
panel showing five knights throughout. With the NOP instead, at the first
death the Spectrum started again from its copyright message:
POKE 52187,2: POKE 52188,0
Nothing can kill him
Two things end his lives. A monster or the creature that touches him takes one
of his three hits at MONSTER_HITS_KNIGHT (in WANDERING_MONSTER), and the third ends the
life; a villain's touch ends it at once (VILLAIN_WANDER, into KNIGHT_KILLED). Make
the DEC (HL) that takes the hit a RET -- the monster has already been made to
vanish -- and the RET NC with which a villain gives up when it is not
touching him a plain RET, and neither can hurt him. The monsters still score
when they meet him.
Tested in the simulator, in cell (16,16): a villain put on him at the start of
every turn cost 13 lives in 300 turns without the pokes and none with them;
a monster of graphic 112 put on him whenever its record was free cost 29
hits and 9 lives in 300 turns without, and nothing with, the hits staying at
three.
POKE 52930,201: POKE 55668,201
The top speeds the numbers say
The knight never reaches TOP_SPEED (see the
bugs): he stops two short. Give TOP_SPEED two more wherever it is set --
12 at a new game (NEW_GAME) and when the faster walk ends (UPDATE_KNIGHT),
20 for the faster walk (SPEED_BONUS) -- and he walks at the 10 and 18
the code names.
Tested in the simulator, walk held along an open street: without the pokes
his speed went 4, 6, 8 and stayed at 8, and after the bonus 8, 12, 14, 16 and
stayed at 16; with them 6, 8, 10 and 10, and after the bonus 10, 14, 16, 18
and 18. He still came to rest on the eight-unit grid when the key was let go.
POKE 48716,12: POKE 55958,12: POKE 55105,20
No monsters and no creature
Monsters are brought in by SPAWN_MONSTER every fourth turn, and the
creature by SPAWN_CREATURE every 256th. A RET as the first
instruction of each and none ever comes; the villains still wander, and still
kill at a touch, and the antibodies have nothing to strike.
Tested in the simulator, 1000 turns in cell (16,16): without the pokes the
six monster records were busy 5833 record-turns in all -- nearly all six all
the time -- and the creature was there for 52 turns; with them the records
stayed empty.
POKE 52712,201: POKE 49045,201
A hundred per cent printed as 100
PRINT_PERCENTAGE prints a hundred in whatever font was used last
(see the bugs). These pokes put eleven bytes
into UNUSED_F195, which the game never touches -- PUSH HL, LD HL,$6CDE (the
digits), LD ($BBAC),HL (FONT_BASE), POP HL, JP $C327 -- and point
PRINT_PERCENTAGE's jump there instead of straight at PRINT_BCD_LOW. The
routine is outside the tape's block, so the pokes go in after loading.
Tested in the simulator, the same finished game as the bug's: FONT_BASE held
the digits' font when the percentage was printed, and the screen said 100:
Each villain was meant to hum from a table of its own, and hums from the ROM
instead (see the bugs). These pokes rewrite the
seven bytes of VILLAIN_WANDER from the AND onwards: AND $30, so the
offset is the kind alone, 0 to 48; then ADD A,$5D : LD C,A : LD B,$C3 and a
NOP, so that BC is the table itself, where LD C,A : LD B,0 and the unused LD
HL,$C35D were. BLIP_FROM_TABLE adds the turn's four bits to BC as it always
did.
Tested in the simulator (at every build), each villain put near the knight:
the pitches were read from $C38D-$C39C for the villain of 108-111, $C37D-$C38C for the villain of 104-107, $C36D-$C37C for the villain of 100-103 and $C35D-$C36C for the villain of 96-99, one table each.
READ_KEYS sends the half-rows it is about to read to port $FD
before reading port $FE, an OUT that does nothing on a 48K and pages memory on
a 128K (see the bugs). The IN after it selects
the half-rows by itself, so the OUT can simply go: two NOPs.
Tested in the emulator's 128K, from the loaded game put into a 128K snapshot
with the 48 BASIC ROM and bank 0 paged in and the paging unlocked: without
the poke the game crashed at the end of its first turn of play; with it, 300
turns of play with the paging as it started ($10: bank 0, the 48 BASIC ROM,
unlocked). On a 48K it changes nothing but the refresh register, which counts
one fetch for the OUT where it counts two for the NOPs, and with it the
random numbers.