While a villain is on the screen it hums:
VILLAIN_WANDER calls
BLIP_FROM_TABLE (in
BLIP_BY_TURN) every turn, which plays twelve waves at a pitch
picked from sixteen by the turn counter's low four bits. Each villain was
meant to have its sixteen: the four tables at VILLAIN_PITCHES, between the
creature's table and the next routine (
BLIP_PITCHES), are exactly four times
sixteen bytes, patterns between $20 and $90 like the creature's. The code
misses them twice over. VILLAIN_WANDER loads the
tables' address into HL, but BLIP_FROM_TABLE builds its address from the turn
bits in HL plus BC, overwriting HL first; and the offset VILLAIN_WANDER puts
in BC, the graphic turned left two bits and cut with AND $F0, keeps the
graphic's bit 5 along with its kind, so it is $80, $90, $A0 or $B0 rather
than 0, 16, 32 or 48. Every villain's pitches come from the ROM, from
$0080 to $00BF -- a few bytes of code and the start of the ROM's table of
BASIC keywords, pitches anywhere from 1 to 254 -- and the four tables
are never read.
Run in the simulator (checked at every build): each villain put in the
knight's cell a little way off, the pitch read at $C347 came from $00B0 to
$00BF for the villain of graphics 108-111, $00A0-$00AF for 104-107,
$0090-$009F for 100-103 and $0080-$008F for 96-99. The only reference to the
tables in the code is VILLAIN_WANDER's LD HL (searched). Either half mended
alone would not do;
the poke mends both, and
the villains then read their own tables. What the hum sounds like is on
the sounds page.