• Contact
  • Journal
  • Home
  • CoCo
  • Mega-Bug
  • Code
  • Site
  • Page
  • Amiga
    • Rainbow Islands
      • 1loader-dec
      • 1loader
      • boot
      • orig-boot
      • Journal
  • Arcade
    • Asteroids 80%
      • Hardware
      • RAMUse
      • Code

      • DVG
      • VectorROM

      • Journal
    • Crazy Climber 1%
      • BigSpriteGraphics.pdf
      • Buildings.pdf
      • cclimber.asm
      • CharEnc.inc
      • CrazyClimberMemoryMapInfo.pdf
      • GraphicsAndCharacterAssetInfo.pdf
      • MemoryMap.inc
    • Defender 75%
      • RAMUse
      • Hardware
      • Bank1
      • Bank2
      • Bank3
      • Bank7
      • BankFixed
      • Mapping.txt
      • SoundHardware
      • SoundRAMUse
      • SoundCode
      • Defender-Theory-Early.pdf
      • Defender-Theory-Later.pdf
      • Defender.CPU.jpg
      • Defender.ROM.B&W.jpg
      • Defender.Vid.B&W.jpg
      • SoundROM.txt
    • Frogger (Sound)
      • SoundHardware
      • SoundRAMUse
      • SoundCode

      • Hardware
      • RAMUse
      • Code

      • GFX

      • Journal
    • Galaga 5%
      • CPU1 (Main)
      • CPU2 (Secondary)
      • CPU3 (Sound)
      • GFX1 (Characters)
      • GFX2 (Sprites)
      • PROMcolors
      • PROMpaletteChar
      • PROMpaletteSprite

      • CPU1Fix

      • Journal
    • Moon Patrol 75%
      • Hardware
      • RAMUse
      • Code

      • GFX1 (Text)
      • GFX2 (Sprites)
      • GFX3 (Mountains)
      • GFX4 (Hills)
      • GFX5 (City)
      • ImageBackgroundColors
      • SpriteColors
      • SpriteColorSets
      • TextColors

      • MoonPatrolSound
      • SoundHardware
      • SoundRAMUse
      • SoundCode

      • Journal
    • Omega Race 10%
      • Hardware
      • RAMUse
      • MainBoard

      • SoundHardware
      • SoundRAMUse
      • SoundBoard

      • DVGPROM
      • VectorROM

      • Journal
    • Phoenix 35%
      • Hardware
      • RAMUse
      • Code

      • Background
      • Foreground

      • Journal

      • Scramble HHi
        • phoenixj-func-main2.pdf
        • phoenixj-func-main2.scap
        • phoenixj.asm-may2025.txt
        • phoenixj.asm-may2025.txt.pdf
    • Space Invaders
      • Hardware
      • RAMUse
      • Code

      • Journal
    • Time Pilot (Sound)
      • SoundHardware
      • SoundRAMUse
      • SoundCode

      • Hardware
      • RAMUse
      • Code

      • Journal
    • Sea Wolf 1%
      • Hardware
      • RAMUse
      • Code

      • Journal
    • Scramble 1%
      • SoundHardware
      • SoundRAMUse
      • SoundCode

      • Journal
  • Atari2600
    • Stella (Hardware Info)
    • Asteroids 5%
      • RAMUse
      • Code

      • Journal
    • Battle Zone 1%
      • RAMUse
      • Code

      • Journal
    • Chess 1%
      • RAMUse
      • Code

      • Journal
    • Combat 10%
      • RAMUse
      • Code
      • CodePAL

      • Journal
    • Double Gap
      • Code
      • DoubleGap.asm

      • Journal
    • Entombed 1%
      • RAMUse
      • Code

      • Journal
    • ET 1%
      • RAMUse
      • Code

      • Journal
    • Burger Time 1%
      • RAMUse
      • CodeBank0
      • CodeBank1
      • CodeBank2
      • CodeBank3
      • CodeBank4
      • CodeBank5
      • CodeBank6
      • CodeBank7

      • Journal
    • Missile Command 1%
      • RAMUse
      • Code

      • Journal
    • Space Invaders 1%
      • RAMUse
      • Code

      • Journal
  • CoCo
    • Hardware
    • Early Work
    • Pyramid
      • RAMUse
      • Code

      • Journal
    • Raaka Tu
      • RAMUse
      • Code

      • Journal
    • Bedlam
      • RAMUse
      • Code

      • Journal
    • Madness & Minotaur
      • Walk Through
        • after_start.txt
        • after_start.cas
        • after_1.txt
        • after_1.cas
        • after_2.txt
        • after_2.cas
        • after_3.txt
        • after_3.cas
        • after_4.txt
        • after_4.cas
        • after_5.txt
        • after_5.cas
        • after_6.txt
        • after_6.cas
        • after_7.txt
        • after_7.cas
        • after_8.txt
        • after_8.cas
        • after_9.txt
        • after_9.cas
        • after_10.txt
        • after_10.cas
        • after_11.txt
        • after_11.cas
        • after_12.txt
        • after_12.cas
        • after_13.txt
        • after_13.cas
        • after_14.txt
        • after_14.cas
        • after_15.txt
        • after_15.cas
        • after_16.txt
        • after_16.cas
        • after_17.txt
        • after_17.cas
        • after_18.txt
        • after_18.cas
        • after_19.txt
        • after_19.cas
        • after_20.txt
        • after_20.cas
        • after_21.txt
        • after_21.cas
        • after_22.txt
        • after_22.cas
        • after_23.txt
        • after_23.cas
        • after_24.txt
        • after_24.cas
        • after_25.txt
        • after_25.cas
      • RAMUse
      • Code

      • SaveGameViewer

      • Journal
    • Mega-Bug
      • RAMUse
      • Code

      • Journal
    • Daggorath
      • RAMUse
      • Code

      • Level Maps

      • Journal
    • Downland 5%
      • RAMUse
      • Code

      • Journal
    • Audio Analyzer 5%
      • RAMUse
      • Code

      • Journal
    • Doubleback
      • RAMUse
      • Code

      • Journal
  • NES
    • Zelda 5%
      • Hardware
      • RAMUse
      • Bank0
      • Bank1
      • Bank2
      • Bank3
      • Bank4
      • Bank5
      • Bank6
      • Bank7

      • Journal
    • Kid Icarus 1%
      • Hardware
      • RAMUse
      • Bank0
      • Bank1
      • Bank2
      • Bank3
      • Bank4
      • Bank5
      • Bank6
      • Bank7

      • Journal
  • Gameboy
    • Hardware
    • Link's Awakening 1%
      • RAMUse
      • Bank00
      • Bank01
      • Bank02
      • Bank03
      • Bank04
      • Bank05
      • Bank06
      • Bank07
      • Bank08
      • Bank09
      • Bank0A
      • Bank0B
      • Bank0C
      • Bank0D
      • Bank0E
      • Bank0F
      • Bank10
      • Bank11
      • Bank12
      • Bank13
      • Bank14
      • Bank15
      • Bank16
      • Bank17
      • Bank18
      • Bank19
      • Bank1A
      • Bank1B
      • Bank1C
      • Bank1D
      • Bank1E
      • Bank1F

      • Journal
    • Tetris 1%
      • RAMUse
      • Code

      • Journal
  • TRS80
    • Hardware
    • HauntedHouse
      • RAMUse1
      • Code1
      • RAMUse2
      • Code2

      • Journal
    • Pyramid
      • RAMUse
      • Code

      • RAMUse1
      • Code1

      • Journal
    • RaakaTu
      • RAMUse
      • Code

      • Journal
    • Bedlam
      • RAMUse
      • Code

      • Journal
  • Virus
    • Morris Worm 1%
      • Journal
    • Stoned
      • Journal

  • Tools
    • Blend
      • blend.zip

      • Journal
  • Mega-Bug Code
  • Screen management
  • Data
    • "We Gotcha" voice samples
    • Player graphics
    • Bug Graphics
    • Giant Bug Graphics
    • La Cucaracha Song
    • Character graphics
  • Start
  • Code bug
  • Splash mode
  • SetGraphicsMode
  • Player Died
  • Player wins
  • Delay for N syncs
  • Draw large bugs
  • Clear1200
  • Check for space-bar or button press
  • Sound of bug line
  • IRQ Service Routine
  • Text processing
    • Text strings
    • Print character
    • Print four digit number
    • Print two digit number
    • Print message
  • Audio
    • Play music
    • Play "We Gotcha!"
    • Play "gotcha" tone
  • Draw mouth
  • Draw bugs (magnified)
  • Read directional input
  • Move the player
  • Draw Magnifier
  • Erase magnifier
  • Pixel Color Mask
  • Copy screen
  • Copy3KtoLast
  • Draw the maze
  • Random number
  • White Line Scroll
  • Quirks
  • CoordToScrOffs
  • Move the Bugs
  • Check for wall
  • Bug dots
  • Check collision between bugs and player
  • Unused

Mega-Bug Code

RAM Usage

Hardware Info

C000: 7E CF DE        JMP     Start               ; Skip over data section

Screen management

The game uses 3 screen buffers: 0400, 0C00, and 1C00. I modified the ISR to continually show each screen (no switching). Thus I was able to see how they are being used.

In the splash mode (beginning of the game):

  • The splash message is drawn completely on 0400
  • The 1000 is blank except for a few pixels at the top left
  • The scroll bars and flashy color Mega-Bug are drawn completely on 1C00

In game mode:

  • The maze is drawn completely on 0400 along with the user's path
  • The users sees the graphics on 1000 and 1C00 alternately

In between rounds:

  • 0400 is blank
  • 1000 the entire message is printed on this screen
  • 1C00 shows the animations

Data

Looks like data from here to the start at CFDE.

"We Gotcha" voice samples

WeGotchaSamples:
C003: 1C C0 91 00 B1 00 59 B4 A3 54 4A E5 94 52 71 9E 94 4D 9B 7E 8E 52 70 A4 71 7F 38 AD 97 4E 4A A1
C023: 7B 61 4A 98 8B 44 4C 9C 6B 63 49 A0 66 01 02 4F 65 80 75 53 4D 87 04 01 6C 58 58 72 77 4E 52 7B
C043: 76 56 4B 6B 76 5A 46 6E 74 01 04 56 44 65 85 52 0A 05 12 7F 87 4B 0B 0C 0D 7A 89 4A 0A 0C 0E 77
C063: 87 4C 0A 0C 0E 59 02 16 88 0D 04 36 09 0F 0F 53 04 14 10 03 72 0C 08 1E 01 13 06 10 06 5B 04 12
C083: 0A 0B 71 0C 08 34 06 0F 09 57 05 11 0A 0C 70 08 0D 32 08 10 08 16 09 33 05 10 0B 0C 70 07 0E 31
C0A3: 08 11 07 1A 01 34 05 11 0A 0D 70 06 0E 32 07 11 06 51 05 12 0A 0C 71 04 10 0E 08 1A 05 11 07 4F
C0C3: 05 10 0B 06 03 01 07 01 64 04 10 0D 05 1F 02 14 05 4E 05 10 0B 06 0E 01 66 02 10 0D 05 39 04 4D
C0E3: 05 10 0A 07 0E 01 66 02 10 0B 08 37 05 4B 05 0F 0B 06 0E 02 65 02 11 0B 08 37 05 4A 05 0F 0B 06
C103: 0E 02 7A 0C 07 38 04 49 04 10 0B 06 0E 02 7A 0C 07 86 04 10 0B 06 0E 02 7A 0B 09 84 04 10 0B 06
C123: 0F 01 5F 01 17 0B 08 83 05 10 09 08 0F 01 5F 01 16 0C 07 83 05 0F 08 09 0F 02 5E 01 16 0C 08 82
C143: 04 10 07 0A 0F 01 5E 02 16 0C 07 82 04 10 06 0A 0F 02 5D 02 16 0B 08 13 04 67 05 10 06 0B 0E 02
C163: 5E 01 16 0C 07 13 04 68 04 07 01 04 06 0B 0F 02 5D 02 16 0C 07 13 04 67 05 10 06 0A 0E 03 5D 02
C183: 16 0C 07 13 04 67 04 07 01 04 06 0B 0F 02 5D 02 15 08 0C 12 05 66 04 07 01 04 06 0C 0E 02 5D 02
C1A3: 15 08 0C 12 05 65 04 07 01 05 05 0C 0E 03 5C 02 11 0C 0B 13 04 13 04 4B 04 07 02 04 06 0B 0F 02
C1C3: 5C 02 12 0B 0C 14 02 13 04 4A 04 07 01 05 05 0C 0E 02 5E 01 11 0B 0C 2E 04 4A 03 07 01 05 05 0C
C1E3: 0E 03 5C 02 10 0C 0B 7F 04 06 02 05 04 0D 0E 02 5E 01 11 0B 0A 2F 03 4A 04 06 03 04 05 0C 0E 03
C203: 72 0B 0A 2F 03 4A 05 06 02 04 05 0C 0F 02 75 08 0A 30 01 4C 03 07 02 05 05 0B 0F 02 74 09 0B 2E
C223: 03 4C 04 07 02 04 05 0C 0E 02 75 08 0C 2E 01 4D 04 08 01 04 06 0B 0F 02 76 07 0C 15 01 67 04 07
C243: 02 04 06 0B 0E 03 06 01 6E 04 0E 12 04 13 03 4E 04 08 01 04 06 0C 0D 02 07 01 53 01 18 03 0E 11
C263: 05 13 03 4F 05 07 02 04 06 0D 0B 03 06 02 53 01 17 02 10 07 03 03 05 11 06 52 04 08 01 04 05 0E
C283: 0C 03 05 02 84 07 0F 0F 06 5A 02 08 03 03 05 0C 0C 05 05 02 67 01 17 06 0E 11 07 13 04 12 01 33
C2A3: 01 08 01 19 0B 04 08 01 94 01 05 0D 05 17 01 13 01 6C 06 08 01 06 A4 03 0C 11 08 A6 EC AC 00 01
C2C3: A5 F1 BC E5 B6 DA C2 F1 C5 F6 C4 E2 DD EB D6 00 14 F2 E4 F9 F8 00 08 EF 00 1C 00 12 00 07 00 00
C2E3: 00 00 00 00 00 00 00 00 00 00 00 A0 07 05 04 0A 07 08 04 07 06 17 01 0D 04 0A 04 04 0B 02 05 05
C303: 0B 03 06 03 03 06 01 05 16 04 04 03 10 02 05 05 01 02 04 04 04 20 01 06 03 0F 03 06 02 01 01 01
C323: 01 01 07 08 06 06 04 07 06 08 05 06 05 05 0B 05 04 06 07 0A 01 05 0B 19 02 09 08 03 05 09 05 0A
C343: 01 0A 04 03 0C 06 03 06 19 09 06 02 0D 10 13 11 14 0E 3B 01 0C 4A 59 5F 73 08 11 0B 23 76 09 03
C363: 31 56 7E 58 4C 5C AB 4A 45 4B 44 16 5E 44 34 41 2F 38 7A 43 2A 41 25 35 8A 36 32 36 2B 33 34 18
C383: 42 28 31 04 05 33 2E 29 38 13 04 03 3B 26 34 2C 34 2D 30 1D 43 26 35 2B 32 2B 24 1D 4C 24 35 2C
C3A3: 2E 2B 25 1D 49 25 33 2E 21 36 22 19 4E 23 30 27 28 37 21 18 4C 22 20 04 08 2A 25 38 1A 1C 4C 21
C3C3: 1C 0A 03 2A 26 31 1D 20 46 21 1B 0A 04 2B 24 2E 20 1E 45 20 1A 0C 03 2C 23 2C 20 19 47 20 1A 0D
C3E3: 01 2D 22 1F 2D 19 45 21 19 0D 01 2D 20 1F 1E 25 47 20 18 0E 02 2D 1E 1D 24 25 42 21 17 0E 01 2E
C403: 1D 1D 23 23 43 21 17 0D 02 2D 1C 1E 22 25 40 20 17 0E 02 2D 1B 1F 22 24 3F 20 16 10 01 19 01 0F
C423: 1A 20 20 24 3E 20 16 2C 03 0E 1B 1F 1F 23 40 20 16 2B 04 0E 19 1F 20 22 40 1F 16 2C 02 0F 1C 20
C443: 1C 22 40 1F 15 40 1C 20 1C 02 02 1A 40 1F 15 3F 1C 21 23 1B 3E 20 16 06 08 2C 1E 20 25 1B 3A 20
C463: 28 2B 1E 28 24 18 37 21 29 2B 1F 1F 01 05 23 18 35 22 2E 03 03 1F 04 02 13 0D 02 22 1B 13 3A 21
C483: 37 29 08 03 18 20 1E 04 47 22 37 2B 06 06 18 1C 11 01 5A 34 28 34 27 20 01 04 56 34 01 03 23 35
C4A3: 30 21 5B 32 33 39 2D 2B 04 05 4F 42 1B 01 04 03 04 43 41 0B 5C 03 05 06 04 85 33 14 05 0A 07 09
C4C3: 0D 0E 15 01 12 2F 2A 71 13 37 1C 2F 3A 53 3B 3C 0F 30 0F 81 69 2B 2B 34 2C 6A 25 28 28 2A 24 29
C4E3: 39 4E 26 36 35 42 37 31 2B 3A AF 93 2F 47 30 98 A5 93 22 34 22 BB 29 19 2B 11 05 92 04 11 12 0F
C503: 07 4D 18 03 05 17 05 01 04 08 03 08 10 0F 03 10 02 06 02 16 05 01 06 17 06 2A 06 0A 04 1F 04 13
C523: 0A 10 02 28 04 0D 0B 0B 06 01 04 07 1E 0F 06 11 03 0A 05 05 04 05 02 05 04 06 04 09 06 0E 08 06
C543: 05 0A 03 04 03 05 04 0A 04 07 0A 05 02 05 02 04 07 06 05 05 02 0A 03 06 04 09 0A 06 07 07 0A 07
C563: 04 18 01 05 05 07 04 05 02 07 0D 06 02 03 04 0C 04 0F 04 06 04 07 04 05 03 06 06 04 05 07 05 06
C583: 04 05 03 07 05 0E 05 06 03 05 03 07 06 06 03 05 08 09 06 01 05 0C 05 03 02 07 03 05 04 08 03 06
C5A3: 06 06 03 05 05 06 04 04 05 0C 05 04 03 05 03 05 04 0B 03 04 02 09 05 0E 04 08 05 06 03 08 04 04
C5C3: 05 06 03 05 04 06 01 04 01 04 04 05 02 0B 04 09 06 0D 02 0B 05 05 03 05 0A 06 05 04 07 06 04 05
C5E3: 03 06 07 08 0D 07 06 06 03 05 05 06 03 04 05 0C 05 06 05 07 06 06 03 04 04 07 02 05 04 0E 04 04
C603: 03 07 06 04 04 05 06 08 04 05 08 06 04 05 05 05 05 04 04 06 02 05 06 09 05 07 06 05 04 07 05 05
C623: 04 05 03 02 0C 05 04 06 05 0C 08 06 05 0F 06 05 02 05 09 04 03 06 04 0D 01 05 03 04 03 04 04 0B
C643: 0B 02 02 04 05 03 04 05 04 01 03 08 06 04 01 08 06 04 01 06 06 05 05 07 01 01 03 05 05 06 03 08
C663: 05 05 03 08 08 0B 05 07 05 06 05 06 03 05 05 11 08 05 06 11 05 05 04 06 06 09 05 05 01 07 05 05
C683: 06 0B 02 07 0E 05 05 09 03 04 03 04 03 04 01 04 03 04 03 05 08 06 0C 07 05 05 04 05 02 04 08 09
C6A3: 03 07 06 06 04 04 05 07 05 02 04 07 03 0A 04 05 02 05 03 04 05 02 01 06 04 04 05 05 03 07 07 05
C6C3: 03 0A 04 04 04 05 01 04 01 04 04 0C 02 05 04 07 05 06 04 03 05 05 04 06 05 0B 04 04 04 07 06 05
C6E3: 04 06 05 06 04 07 05 06 06 05 03 05 06 06 03 06 06 04 05 07 05 06 06 03 03 06 04 04 04 05 03 04
C703: 03 05 02 05 0C 0A 02 02 03 05 08 0D 0A 0D 05 04 02 06 02 03 04 0B 05 0C 03 04 03 05 03 04 04 0C
C723: 09 06 04 05 04 05 03 04 03 05 03 07 04 06 07 03 03 05 02 04 02 03 03 04 04 05 0A 0D 03 05 03 0B
C743: 05 0B 04 05 04 02 03 05 04 09 05 06 01 05 02 05 03 04 02 05 04 0A 02 0A 05 0D 01 0D 06 0C 0A 07
C763: 03 04 03 05 04 05 05 05 04 05 0E 03 03 0C 07 02 0B 04 05 03 15 03 06 03 19 04 05 82 04 04 04 05
C783: 8D 01 1F 09 03 06 03 4D 05 0C 1C 22 03 1E 08 12 66 63 3D 47 07 0F 5E 5A 48 45 79 44 06 0E 31 58
C7A3: 7C 44 0F 06 2D 42 04 12 7F 44 10 04 2E 44 02 11 83 45 10 03 2F 4B 07 03 86 46 46 49 94 47 47 47
C7C3: 98 48 45 46 32 0A 0F 01 48 48 44 3E 30 2A 4B 48 38 43 33 2E 50 46 34 3C 3D 2B 5B 45 32 3C 33 34
C7E3: 67 41 2F 42 2C 38 73 3D 31 3F 2D 36 7A 3D 32 3C 2D 36 31 0A 43 39 31 40 2D 36 32 11 42 35 34 3C
C803: 2F 34 31 19 44 33 37 33 37 32 33 19 48 2F 3A 31 39 2D 37 20 49 25 05 02 39 2F 3B 2C 39 21 4C 26
C823: 44 2E 3A 2D 38 25 4F 29 42 2F 39 2E 34 2B 53 29 40 2F 38 2F 32 2E 5A 2B 3D 30 38 30 2F 32 5E 2C
C843: 3C 30 36 32 2B 35 66 2C 3B 2F 31 38 28 38 6F 2B 3A 30 2A 3E 28 38 7A 2A 2D 04 06 30 27 40 25 2F
C863: 91 28 2B 3F 28 3F 26 2F 99 29 2C 08 06 2C 27 41 23 2D 34 11 5D 2A 3E 2B 29 41 24 2D A8 2B 30 39
C883: 28 3E 27 2D 28 1F 6D 2D 3A 2E 29 3B 29 2D 31 1B 6E 2E 32 35 2A 3B 28 30 29 23 76 2E 31 36 2A 38
C8A3: 2C 2F 2B 1D 7F 2F 2E 39 29 37 2D 2E 2C 2A 7B 2D 2C 3B 29 34 32 2E 29 2F 85 2B 29 3F 28 32 35 2F
C8C3: 2B 2D 90 2B 2A 3F 28 33 33 31 2D 38 94 2A 2A 3F 27 35 32 30 2C 33 AE 2F 2D 39 29 34 32 32 2F 30
C8E3: C2 2F 2C 3C 29 35 32 30 2F 34 D1 2F 29 41 28 34 35 31 2F 35 D6 31 29 40 27 2C 3A 31 26 30 24 1D
C903: B8 30 26 45 23 2A 38 31 23 66 DE 2D 25 45 20 2D 30 38 00 17 01 1E 01 03 17 1F 33 1A 5C 10 69 27
C923: 25 D4 10 42 1D 24 53 05 D6 E2 09 2C 18 0D 01 0C 00 5B D8 05 09 0B 22 46 05 14 02 3A 1D C0 00 18
C943: 09 43 27 0D 10 08 50 07 EE 00 35 0B 1D 69 03 00 53 00 51 00 00 18 00 3F 00 00 87 00 3C 

Player graphics

6 bytes per image, 2 images per direction, 4 directions

PlayerGraphics:
C960: F8 A8 0C 0C A8 F8
; #####...
; #.#.#...
; ....##..
; ....##..
; #.#.#...
; #####...
 
C966: CC 84 CC 84 FC 30
; ##..##..
; #....#..
; ##..##..
; #....#..
; ######..
; ..##....
 
C96C: 7C 54 C0 C0 54 7C 
; .#####..
; .#.#.#..
; ##......
; ##......
; .#.#.#..
; .#####..

C972: 30 FC 84 CC 84 CC
; ..##....
; ######..
; #....#..
; ##..##..
; #....#..
; ##..##..
            
C978: 18 F8 AC AC F8 18
; ...##...
; #####...
; #.#.##..
; #.#.##..
; #####...
; ...##...
 
C97E: 78 48 78 CC FC 30 
; .####...
; .#..#...
; .####...
; ##..##..
; ######..
; ..##....

C984: 60 7C D4 D4 7C 60
; .##.....
; .#####..
; #.##.#..
; #.##.#..
; .#####..
; .##.....
 
C98A: 30 FC CC 78 48 78
; ..##....
; ######..
; ##..##..
; .####...
; .#..#...
; .####...

Bug Graphics

3 columns of 6 rows (18 bytes each). 4 pictures each with 4 shifts (16 total).

BugGraphics:
C990:  08 20 15 15 20 82
C996:  20 80 00 00 80 00
C99C:  00 00 00 00 00 00
; ..%..%......
; .%..%.......
; .###........
; .###........
; .%..%.......
; %..%........

C9A2:  02 08 05 05 08 20
C9A8:  08 20 40 40 20 80
C9AE:  00 00 00 00 00 00
; ...%..%.....
; ..%..%......
; ..###.......
; ..###.......
; ..%..%......
; .%..%.......

C9B4:  00 02 01 01 02 08
C9BA:  82 08 50 50 08 20
C9C0:  00 00 00 00 00 00
; ....%..%....
; ...%..%.....
; ...###......
; ...###......
; ...%..%.....
; ..%..%......

C9C6:  00 00 00 00 00 02
C9CC:  20 82 54 54 82 08
C9D2:  80 00 00 00 00 00
; .....%..%...
; ....%..%....
; ....###.....
; ....###.....
; ....%..%....
; ...%..%.....

C9D8:  80 20 15 95 20 00
C9DE:  00 80 20 00 80 20
C9E4:  00 00 00 00 00 00
; %...........
; .%..%.......
; .###.%......
; %###........
; .%..%.......
; .....%......

SplashBug1:
C9EA:  20 08 05 25 08 00
C9F0:  00 20 48 40 20 08
C9F6:  00 00 00 00 00 00
; .%..........
; ..%..%......
; ..###.%.....
; .%###.......
; ..%..%......
; ......%.....

C9FC:  08 02 01 09 02 00
CA02:  00 08 52 50 08 02
CA08:  00 00 00 00 00 00
; ..%.........
; ...%..%.....
; ...###.%....
; ..%###......
; ...%..%.....
; .......%....

CA0E:  02 00 00 02 00 00
CA14:  00 82 54 54 82 00
CA1A:  00 00 80 00 00 80
; ...%........
; ....%..%....
; ....###.%...
; ...%###.....
; ....%..%....
; ........%...

CA20:  82 20 15 15 20 08
CA26:  00 80 00 00 80 20
CA2C:  00 00 00 00 00 00
; %..%........
; .%..%.......
; .###........
; .###........
; .%..%.......
; ..%..%......

CA32:  20 08 05 05 08 02
CA38:  80 20 40 40 20 08
CA3E:  00 00 00 00 00 00
; .%..%.......
; ..%..%......
; ..###.......
; ..###.......
; ..%..%......
; ...%..%.....

CA44:  08 02 01 01 02 00
CA4A:  20 08 50 50 08 82
CA50:  00 00 00 00 00 00
; ..%..%......
; ...%..%.....
; ...###......
; ...###......
; ...%..%.....
; ....%..%....

CA56:  02 00 00 00 00 00
CA5C:  08 82 54 54 82 20
CA62:  00 00 00 00 00 80
; ...%..%.....
; ....%..%....
; ....###.....
; ....###.....
; ....%..%....
; .....%..%...

CA68:  00 20 95 15 20 80
CA6E:  20 80 00 20 80 00
CA74:  00 00 00 00 00 00
; .....%......
; .%..%.......
; %###........
; .###.%......
; .%..%.......
; %...........

SplashBug2:
CA7A:  00 08 25 05 08 20
CA80:  08 20 40 48 20 00
CA86:  00 00 00 00 00 00
; ......%.....
; ..%..%......
; .%###.......
; ..###.%.....
; ..%..%......
; .%..........

CA8C:  00 02 09 01 02 08
CA92:  02 08 50 52 08 00
CA98:  00 00 00 00 00 00
; .......%....
; ...%..%.....
; ..%###......
; ...###.%....
; ...%..%.....
; ..%.........

CA9E:  00 00 02 00 00 02
CAA4:  00 82 54 54 82 00
CAAA:  80 00 00 80 00 00
; ........%...
; ....%..%....
; ...%###.....
; ....###.%...
; ....%..%....
; ...%........

Giant Bug Graphics

The bugs are defined as 32 rows by 5 columns (of 4 pixels) drawn column by column. Note that the colors on the CoCo screen are blended together in spots.

GraBugStanding:
CAB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 07 00 00 00 00 01 07 00 00 00 00 00 00 00 01
CAD0: 20 08 02 00 00 00 01 05 01 01 00 00 14 21 21 21 E0 80 14 21 21 21 E1 81 02 02 02 02 02 02 15 54
CAF0: 00 00 00 80 20 51 55 75 55 50 55 11 55 51 55 51 55 11 55 55 51 55 51 55 95 00 00 00 00 00 00 00
CB10: 00 00 02 08 20 40 50 D4 50 50 40 00 45 50 50 50 41 00 45 50 50 50 51 50 28 08 08 08 08 08 15 05
CB30: 20 80 00 00 00 00 00 00 00 00 00 00 00 80 80 80 E0 78 00 80 80 80 E0 78 00 00 00 00 00 00 00 50
; .....$...........$..
; ......$.........$...
; .......$.......$....
; ........$.....$.....
; .........$...$......
; ........++.++.......
; .......+++++++......
; ......+++#++#++.....
; .......+++++++......
; .......+++..++......
; ........+++++.......
; .........+.+........
; .....++.+++++.++....
; .....$.+++.+++..$...
; .....$.+++++++..$...
; .....$.+++.+++..$...
; ...+#$..+++++..+#$..
; ..+#$....+.+....+#$.
; .....++.+++++.++....
; .....$.+++++++..$...
; .....$.+++.+++..$...
; .....$.+++++++..$...
; ...+#$.+++.+++.+#$..
; ..+#$..+++++++..+#$.
; .......$$+++.$$.....
; .......$......$.....
; .......$......$.....
; .......$......$.....
; .......$......$.....
; .......$......$.....
; .....+++.....+++....
; ...++++.......++++..

GraBugJumping1:
CB50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 07 00 00 00 00 01 07 00 00 00 00 00 01 00 00
CB70: 20 08 02 00 00 00 01 05 01 01 00 00 14 21 21 21 E0 80 14 21 21 21 E1 81 02 02 02 02 15 54 00 00
CB90: 00 00 00 80 20 51 55 75 55 50 55 11 55 51 55 51 55 11 55 55 51 55 51 55 95 00 00 00 00 00 00 00
CBB0: 00 00 02 08 20 40 50 D4 51 50 40 00 45 50 51 50 40 00 45 50 50 50 50 50 28 08 08 08 08 08 15 05
CBD0: 20 80 00 00 00 00 00 78 E0 80 80 80 00 78 E0 80 80 80 00 00 00 00 00 00 00 00 00 00 00 00 00 50
; .....$...........$..
; ......$.........$...
; .......$.......$....
; ........$.....$.....
; .........$...$......
; ........++.++.......
; .......+++++++......
; ......+++#++#++.+#$.
; .......+++++++.+#$..
; .......+++..++..$...
; ........+++++...$...
; .........+.+....$...
; .....++.+++++.++....
; .....$.+++.+++..+#$.
; .....$.+++++++.+#$..
; .....$.+++.+++..$...
; ...+#$..+++++...$...
; ..+#$....+.+....$...
; .....++.+++++.++....
; .....$.+++++++......
; .....$.+++.+++......
; .....$.+++++++......
; ...+#$.+++.+++......
; ..+#$..+++++++......
; .......$$+++.$$.....
; .......$......$.....
; .......$......$.....
; .......$......$.....
; .....+++......$.....
; ...++++.......$.....
; .............+++....
; ..............++++..

GraBugJumping2:
CBF0: 00 00 00 00 00 00 00 07 01 00 00 00 00 07 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
CC10: 02 08 02 00 00 00 01 B5 E1 21 20 20 14 81 E1 21 20 20 14 01 01 01 01 01 02 02 02 02 02 02 15 54
CC30: 00 00 00 80 20 51 55 75 55 50 55 11 55 51 55 51 55 11 55 55 51 55 51 55 95 00 00 00 00 00 00 00
CC50: 02 00 02 08 20 40 50 D4 50 50 40 00 45 50 50 50 41 00 45 50 50 50 51 50 28 08 08 08 15 05 00 00
CC70: 00 80 00 00 00 00 00 00 00 00 00 00 00 80 80 80 E0 78 00 80 80 80 E0 78 00 00 00 00 00 50 00 00
; .......$.......$....
; ......$.........$...
; .......$.......$....
; ........$.....$.....
; .........$...$......
; ........++.++.......
; .......+++++++......
; ..+#$#+++#++#++.....
; ...+#$.+++++++......
; .....$.+++..++......
; .....$..+++++.......
; .....$...+.+........
; .....++.+++++.++....
; ..+#$..+++.+++..$...
; ...+#$.+++++++..$...
; .....$.+++.+++..$...
; .....$..+++++..+#$..
; .....$...+.+....+#$.
; .....++.+++++.++....
; .......+++++++..$...
; .......+++.+++..$...
; .......+++++++..$...
; .......+++.+++.+#$..
; .......+++++++..+#$.
; .......$$+++.$$.....
; .......$......$.....
; .......$......$.....
; .......$......$.....
; .......$.....+++....
; .......$......++++..
; .....+++............
; ...++++.............

La Cucaracha Song

39 notes (including rests)

NotesSplash:
CC90: 06 0A 10 2D 00 00           
CC96: 06 0A 10 2D 00 00   
CC9C: 06 0A 10 2D 00 00           
CCA2: 18 2B 15 98 0D 99 
CCA8: 06 0A 1B 35 10 2D 
CCAE: 06 0A 00 00 00 00 
CCB4: 06 0A 10 2D 00 00 
CCBA: 06 0A 10 2D 00 00 
CCC0: 06 0A 10 2D 00 00 
CCC6: 18 2B 15 98 0D 99 
CCCC: 06 0A 1B 35 10 2D 
CCD2: 1E 35 00 00 00 00 
CCD8: 06 0A 15 98 0D 99 
CCDE: 06 0A 15 98 0D 99 
CCE4: 06 0A 14 60 0C 19                     
CCEA: 06 0A 14 60 0C 19
CCF0: 06 0A 12 27 0A CB 
CCF6: 06 0A 12 27 0A CB 
CCFC: 18 2B 10 2D 0A 2F 
CD02: 06 0A 00 00 00 00 
CD08: 06 0A 10 2D 00 00 
CD0E: 06 0A 10 2D 00 00 
CD14: 06 0A 10 2D 00 00 
CD1A: 18 2B 14 60 0C 19         
CD20: 06 0A 18 35 10 2D 
CD26: 06 0A 00 00 00 00 
CD2C: 06 0A 10 2D 00 00 
CD32: 06 0A 10 2D 00 00 
CD38: 06 0A 10 2D 00 00 
CD3E: 18 2B 14 60 0C 19
CD44: 06 0A 18 35 10 2D 
CD4A: 1E 35 00 00 00 00 
CD50: 06 0A 20 5B 14 60 
CD56: 06 0A 24 51 15 98 
CD5C: 06 0A 20 5B 14 60 
CD62: 06 0A 1C D2 12 27 
CD68: 06 0A 1B 35 10 2D 
CD6E: 06 0A 18 35 18 F4 
CD74: 06 0A 15 98 0D 99

Character graphics

68 total characters:

  • 0-9
  • A-Z
  • a-z
  • <space>!-.:,
GraChars:
CD7A:  70 88 98 A8 C8 88 70 00 00
; .###....
; #...#...
; #..##...
; #.#.#...
; ##..#...
; #...#...
; .###....
; ........
; ........

CD83:  20 60 20 20 20 20 70 00 00
; ..#.....
; .##.....
; ..#.....
; ..#.....
; ..#.....
; ..#.....
; .###....
; ........
; ........

CD8C:  70 88 08 30 40 80 F8 00 00
; .###....
; #...#...
; ....#...
; ..##....
; .#......
; #.......
; #####...
; ........
; ........

CD95:  70 88 08 30 08 88 70 00 00
; .###....
; #...#...
; ....#...
; ..##....
; ....#...
; #...#...
; .###....
; ........
; ........

CD9E:  10 30 50 F8 10 10 10 00 00
; ...#....
; ..##....
; .#.#....
; #####...
; ...#....
; ...#....
; ...#....
; ........
; ........

CDA7:  F8 80 80 F0 08 08 F0 00 00
; #####...
; #.......
; #.......
; ####....
; ....#...
; ....#...
; ####....
; ........
; ........

CDB0:  70 88 80 F0 88 88 70 00 00
; .###....
; #...#...
; #.......
; ####....
; #...#...
; #...#...
; .###....
; ........
; ........

CDB9:  F8 88 10 10 20 20 20 00 00
; #####...
; #...#...
; ...#....
; ...#....
; ..#.....
; ..#.....
; ..#.....
; ........
; ........

CDC2:  70 88 88 70 88 88 70 00 00
; .###....
; #...#...
; #...#...
; .###....
; #...#...
; #...#...
; .###....
; ........
; ........

CDCB:  70 88 88 78 08 88 70 00 00
; .###....
; #...#...
; #...#...
; .####...
; ....#...
; #...#...
; .###....
; ........
; ........

CDD4:  20 50 88 F8 88 88 88 00 00
; ..#.....
; .#.#....
; #...#...
; #####...
; #...#...
; #...#...
; #...#...
; ........
; ........

CDDD:  F0 48 48 70 48 48 F0 00 00
; ####....
; .#..#...
; .#..#...
; .###....
; .#..#...
; .#..#...
; ####....
; ........
; ........

CDE6:  70 88 80 80 80 88 70 00 00
; .###....
; #...#...
; #.......
; #.......
; #.......
; #...#...
; .###....
; ........
; ........

CDEF:  F0 48 48 48 48 48 F0 00 00
; ####....
; .#..#...
; .#..#...
; .#..#...
; .#..#...
; .#..#...
; ####....
; ........
; ........

CDF8:  F8 80 80 F0 80 80 F8 00 00
; #####...
; #.......
; #.......
; ####....
; #.......
; #.......
; #####...
; ........
; ........

CE01:  F8 80 80 F0 80 80 80 00 00
; #####...
; #.......
; #.......
; ####....
; #.......
; #.......
; #.......
; ........
; ........

CE0A:  70 88 80 B8 88 88 70 00 00
; .###....
; #...#...
; #.......
; #.###...
; #...#...
; #...#...
; .###....
; ........
; ........

CE13:  88 88 88 F8 88 88 88 00 00
; #...#...
; #...#...
; #...#...
; #####...
; #...#...
; #...#...
; #...#...
; ........
; ........

CE1C:  F8 20 20 20 20 20 F8 00 00
; #####...
; ..#.....
; ..#.....
; ..#.....
; ..#.....
; ..#.....
; #####...
; ........
; ........

CE25:  38 10 10 10 10 90 60 00 00
; ..###...
; ...#....
; ...#....
; ...#....
; ...#....
; #..#....
; .##.....
; ........
; ........

CE2E:  88 90 A0 C0 A0 90 88 00 00
; #...#...
; #..#....
; #.#.....
; ##......
; #.#.....
; #..#....
; #...#...
; ........
; ........

CE37:  80 80 80 80 80 80 F0 00 00
; #.......
; #.......
; #.......
; #.......
; #.......
; #.......
; ####....
; ........
; ........

CE40:  88 D8 A8 A8 88 88 88 00 00
; #...#...
; ##.##...
; #.#.#...
; #.#.#...
; #...#...
; #...#...
; #...#...
; ........
; ........

CE49:  88 C8 C8 A8 98 98 88 00 00
; #...#...
; ##..#...
; ##..#...
; #.#.#...
; #..##...
; #..##...
; #...#...
; ........
; ........

CE52:  70 88 88 88 88 88 70 00 00
; .###....
; #...#...
; #...#...
; #...#...
; #...#...
; #...#...
; .###....
; ........
; ........

CE5B:  F0 88 88 F0 80 80 80 00 00
; ####....
; #...#...
; #...#...
; ####....
; #.......
; #.......
; #.......
; ........
; ........

CE64:  70 88 88 88 A8 90 68 00 00
; .###....
; #...#...
; #...#...
; #...#...
; #.#.#...
; #..#....
; .##.#...
; ........
; ........

CE6D:  F0 88 88 F0 A0 90 88 00 00
; ####....
; #...#...
; #...#...
; ####....
; #.#.....
; #..#....
; #...#...
; ........
; ........

CE76:  70 88 80 70 08 88 70 00 00
; .###....
; #...#...
; #.......
; .###....
; ....#...
; #...#...
; .###....
; ........
; ........

CE7F:  F8 A8 20 20 20 20 20 00 00
; #####...
; #.#.#...
; ..#.....
; ..#.....
; ..#.....
; ..#.....
; ..#.....
; ........
; ........

CE88:  88 88 88 88 88 88 70 00 00
; #...#...
; #...#...
; #...#...
; #...#...
; #...#...
; #...#...
; .###....
; ........
; ........

CE91:  88 88 88 88 50 50 20 00 00
; #...#...
; #...#...
; #...#...
; #...#...
; .#.#....
; .#.#....
; ..#.....
; ........
; ........

CE9A:  88 88 88 88 A8 A8 50 00 00
; #...#...
; #...#...
; #...#...
; #...#...
; #.#.#...
; #.#.#...
; .#.#....
; ........
; ........

CEA3:  88 88 50 20 50 88 88 00 00
; #...#...
; #...#...
; .#.#....
; ..#.....
; .#.#....
; #...#...
; #...#...
; ........
; ........

CEAC:  88 88 50 20 20 20 20 00 00
; #...#...
; #...#...
; .#.#....
; ..#.....
; ..#.....
; ..#.....
; ..#.....
; ........
; ........

CEB5:  F8 08 10 20 40 80 F8 00 00
; #####...
; ....#...
; ...#....
; ..#.....
; .#......
; #.......
; #####...
; ........
; ........

CEBE:  00 00 60 10 70 90 68 00 00
; ........
; ........
; .##.....
; ...#....
; .###....
; #..#....
; .##.#...
; ........
; ........

CEC7:  80 80 F0 88 88 88 F0 00 00
; #.......
; #.......
; ####....
; #...#...
; #...#...
; #...#...
; ####....
; ........
; ........

CED0:  00 00 70 88 80 88 70 00 00
; ........
; ........
; .###....
; #...#...
; #.......
; #...#...
; .###....
; ........
; ........

CED9:  08 08 78 88 88 88 78 00 00
; ....#...
; ....#...
; .####...
; #...#...
; #...#...
; #...#...
; .####...
; ........
; ........

CEE2:  00 00 70 88 F8 80 70 00 00
; ........
; ........
; .###....
; #...#...
; #####...
; #.......
; .###....
; ........
; ........

CEEB:  20 50 40 E0 40 40 40 00 00
; ..#.....
; .#.#....
; .#......
; ###.....
; .#......
; .#......
; .#......
; ........
; ........

CEF4:  00 00 70 88 88 78 08 88 70
; ........
; ........
; .###....
; #...#...
; #...#...
; .####...
; ....#...
; #...#...
; .###....

CEFD:  80 80 B0 C8 88 88 88 00 00
; #.......
; #.......
; #.##....
; ##..#...
; #...#...
; #...#...
; #...#...
; ........
; ........

CF06:  20 00 60 20 20 20 70 00 00
; ..#.....
; ........
; .##.....
; ..#.....
; ..#.....
; ..#.....
; .###....
; ........
; ........

CF0F:  20 00 60 20 20 20 20 A0 40
; ..#.....
; ........
; .##.....
; ..#.....
; ..#.....
; ..#.....
; ..#.....
; #.#.....
; .#......

CF18:  80 80 90 A0 C0 A0 90 00 00
; #.......
; #.......
; #..#....
; #.#.....
; ##......
; #.#.....
; #..#....
; ........
; ........

CF21:  60 20 20 20 20 20 70 00 00
; .##.....
; ..#.....
; ..#.....
; ..#.....
; ..#.....
; ..#.....
; .###....
; ........
; ........

CF2A:  00 00 D0 A8 A8 A8 A8 00 00
; ........
; ........
; ##.#....
; #.#.#...
; #.#.#...
; #.#.#...
; #.#.#...
; ........
; ........

CF33:  00 00 B0 C8 88 88 88 00 00
; ........
; ........
; #.##....
; ##..#...
; #...#...
; #...#...
; #...#...
; ........
; ........

CF3C:  00 00 70 88 88 88 70 00 00
; ........
; ........
; .###....
; #...#...
; #...#...
; #...#...
; .###....
; ........
; ........

CF45:  00 00 B0 C8 88 88 F0 80 80
; ........
; ........
; #.##....
; ##..#...
; #...#...
; #...#...
; ####....
; #.......
; #.......

CF4E:  00 00 68 98 88 98 68 08 08
; ........
; ........
; .##.#...
; #..##...
; #...#...
; #..##...
; .##.#...
; ....#...
; ....#...

CF57:  00 00 B0 C8 80 80 80 00 00
; ........
; ........
; #.##....
; ##..#...
; #.......
; #.......
; #.......
; ........
; ........

CF60:  00 00 70 80 70 08 70 00 00
; ........
; ........
; .###....
; #.......
; .###....
; ....#...
; .###....
; ........
; ........

CF69:  40 40 E0 40 40 50 20 00 00
; .#......
; .#......
; ###.....
; .#......
; .#......
; .#.#....
; ..#.....
; ........
; ........

CF72:  00 00 88 88 88 98 68 00 00
; ........
; ........
; #...#...
; #...#...
; #...#...
; #..##...
; .##.#...
; ........
; ........

CF7B:  00 00 88 88 88 50 20 00 00
; ........
; ........
; #...#...
; #...#...
; #...#...
; .#.#....
; ..#.....
; ........
; ........

CF84:  00 00 88 A8 A8 A8 50 00 00
; ........
; ........
; #...#...
; #.#.#...
; #.#.#...
; #.#.#...
; .#.#....
; ........
; ........

CF8D:  00 00 88 50 20 50 88 00 00
; ........
; ........
; #...#...
; .#.#....
; ..#.....
; .#.#....
; #...#...
; ........
; ........

CF96:  00 00 88 88 88 78 08 08 70
; ........
; ........
; #...#...
; #...#...
; #...#...
; .####...
; ....#...
; ....#...
; .###....

CF9F:  00 00 F8 10 20 40 F8 00 00
; ........
; ........
; #####...
; ...#....
; ..#.....
; .#......
; #####...
; ........
; ........

CFA8:  00 00 00 00 00 00 00 00 00
; ........
; ........
; ........
; ........
; ........
; ........
; ........
; ........
; ........

CFB1:  20 20 20 20 20 00 20 00 00
; ..#.....
; ..#.....
; ..#.....
; ..#.....
; ..#.....
; ........
; ..#.....
; ........
; ........

CFBA:  00 00 00 F8 00 00 00 00 00
; ........
; ........
; ........
; #####...
; ........
; ........
; ........
; ........
; ........

CFC3:  00 00 00 00 00 20 20 00 00
; ........
; ........
; ........
; ........
; ........
; ..#.....
; ..#.....
; ........
; ........

CFCC:  00 00 20 00 00 20 00 00 00
; ........
; ........
; ..#.....
; ........
; ........
; ..#.....
; ........
; ........
; ........

CFD5:  20 20 40 00 00 00 00 00 00
; ..#.....
; ..#.....
; .#......
; ........
; ........
; ........
; ........
; ........
; ........

Start

Start:
CFDE: 12              NOP                         
CFDF: 10 CE 03 F0     LDS     #$03F0              ; Stack starts here (builds towards 0000)
CFE3: 0F B3           CLR     <HighScore          ; Clear ...
CFE5: 0F B4           CLR     <HighScore+1        ; ... high score
CFE7: 0F B1           CLR     <Score              ; Clear ...
CFE9: 0F B2           CLR     <Score+1            ; ... current score
CFEB: 86 A5           LDA     #$A5                ; Test value ...
CFED: B7 10 00        STA     $1000               ; ... to 1000 (4K)
CFF0: 0F 00           CLR     <$00                ; Clears 1000 if it ghosts
CFF2: A1 8D 40 0A     CMPA    $1000,PC            ; Did we change the memory (and it isn't a ghost)?
CFF6: 27 1D           BEQ     $D015               ; Yes ... we have enough memory to run

;CFF6: 12 12 ; NOP NOP ; This removes the branch and forces the code to always fall into the error message

Code bug

This next line should be "JSR $D2DE" to set the graphics mode. I tested with the change and I get the error message. Otherwise the text screen shows garbage. (NOP out the "CFF6: BEQ $D015" to see the error)

"D2DE" instead of "D2BE". Interesting that it is off by 32. Wasn't this assembled by a tool that managed the addresses?

CFF8: BD D2 BE        JSR     $D2BE               ; BUG. This address is a section of data ... not code

;CFF8: BD D2 DE ;      JSR     $D2DE ; This will change the mode ... but not the display page

CFFB: CE 04 00        LDU     #$0400              ; Start of the first ...
CFFE: DF 9E           STU     <ScreenPtr          ; ... screen buffer
D000: BD D4 AE        JSR     Clear1200           ; Clear the screen
D003: 8E D2 A1        LDX     #Need16K            ; "16k or more memory is needed..." string
D006: EC 81           LDD     ,X++                ; Reached end of message lines list?
D008: 27 FE           BEQ     $D008               ; Yes ... just spin here forever (we can't run)
D00A: DD AB           STD     <PixCoords          ; Store the coordinates
D00C: A6 80           LDA     ,X+                 ; Get color mask
D00E: 97 AD           STA     <ColorMask          ; Store the color
D010: BD D6 FA        JSR     PrintMsg            ; Print message
D013: 20 F1           BRA     $D006               ; Next message line

; Hold ENTER down for "pro mode" -- start with 16 bugs instead of the usual 8
D015: 86 FE           LDA     #$FE                ; Column with ENTER key
D017: C6 08           LDB     #$08                ; Game usually starts with 8 bugs
D019: B7 FF 02        STA     PIA0_DB             ; Set the keyboard column
D01C: B6 FF 00        LDA     PIA0_DA             ; Read the rows
D01F: 84 40           ANDA    #$40                ; Row with the ENTER key
D021: 26 02           BNE     $D025               ; Not pressed ... start with 8 bugs
D023: C6 10           LDB     #$10                ; Pressed ... start with 16 bugs
;
D025: D7 C5           STB     <NumStartBugs       ; Number of bugs to start the game with
D027: BD D2 DE        JSR     SetGraphicsMode     ; Set the graphics mode
D02A: CE 04 00        LDU     #$0400              ; Start of first screen buffer
D02D: BD D4 AE        JSR     Clear1200           ; Clear the first screen buffer
D030: 8E CF DE        LDX     #Start              ; Start routine
D033: 9F 72           STX     <$72                ; The BASIC ROM warm-start vector
D035: 86 55           LDA     #$55                ; Flag that reset should ...
D037: 97 71           STA     <$71                ; ... jump to warm-start vector
D039: 1A 50           ORCC    #$50                ; IRQ off
D03B: 8E D5 46        LDX     #IRQ                ; New IRQ ...
D03E: BF 01 0D        STX     $010D               ; ... interrupt vector
D041: 0F C7           CLR     <VisiblePage        ; (force setting on next interrupt)
D043: 86 04           LDA     #$04                ; Display graphics page 400
D045: 97 92           STA     <RequestedPage      ; CURRENT VISIBILE PAGE
D047: 0F B6           CLR     <ISRCountScore      ; Initialize 1 sec timer for losing a point
D049: 0F C1           CLR     <ShowingGame        ; We are NOT showing the game screen
D04B: 86 34           LDA     #$34                ; Initialize ...
D04D: B7 FF 01        STA     PIA0_CA             ; ... PIA1 A ...
D050: B7 FF 21        STA     PIA1_CA             ; ... and PIA1 B
D053: 8A 08           ORA     #$08                ; Enable ...
D055: A7 8D 2E CA     STA     PIA1_CB,PC          ; ... six-bit sound
D059: 86 35           LDA     #$35                ; Enable ...
D05B: B7 FF 03        STA     PIA0_CB             ; ... 60ms interrupt
D05E: 3C EF           CWAI    $EF                 ; Wait for the first interrupt

Splash mode

Scroll the credit text onto the screen. Then play the music while reprinting the "Mega-Bug" name in rolling colors changing after each note. Then play a demo game with random direction changes.

SplashMode:
D060: 10 CE 03 F0     LDS     #$03F0              ; Set stack just below 1st screen
D064: 0F C1           CLR     <ShowingGame        ; We are NOT showing the game screen
D066: 0F B1           CLR     <Score              ; Initialize current score ...
D068: 0F B2           CLR     <Score+1            ; ... to zero
D06A: 0F B9           CLR     <DrawCountSecs      ; Don't draw the seconds-count
D06C: 0F B8           CLR     <DrawScore          ; Don't draw the score
D06E: 0F B7           CLR     <ISRCountTime       ; Initialize 1 sec timer for TIME display
D070: 0F B6           CLR     <ISRCountScore      ; Initialize 1 sec timer for losing a point
D072: 0F C6           CLR     <PlayShortSong      ; We have not played the full song
D074: 96 C5           LDA     <NumStartBugs       ; Number of bugs to start the game (8 or 16)
D076: 97 A0           STA     <NumBugs            ; Initialize the number of bugs
D078: CE 10 00        LDU     #$1000              ; Start buffer 1000 as the ...
D07B: DF 9C           STU     <VisibleScreenPtr   ; ... screen to show while drawing
D07D: CC 1C 00        LDD     #$1C00              ; Start buffer 1C00 as the ...
D080: DD 9A           STD     <DrawingScreenPtr   ; ... screen to draw on
D082: BD DB 6D        JSR     CopyScreen          ; Copy screen 0400 to 1C00 and show 1C00
D085: CE 04 00        LDU     #$0400              ; Clear the ...
D088: BD D4 AE        JSR     Clear1200           ; ... first screen buffer
D08B: 8E D5 EF        LDX     #StrsCredits        ; Pointer to the credits strings
D08E: EC 81           LDD     ,X++                ; Get the screen coordinates for the next string?
D090: 27 10           BEQ     $D0A2               ; All done ... play the music
D092: DD AB           STD     <PixCoords          ; Store the coords
D094: A6 80           LDA     ,X+                 ; And the ...
D096: 97 AD           STA     <ColorMask          ; ... color mask
D098: CC 04 00        LDD     #$0400              ; Drawing to ...
D09B: DD 9E           STD     <ScreenPtr          ; ... the first screen buffer
D09D: BD D6 FA        JSR     PrintMsg            ; Print the next string
D0A0: 20 EC           BRA     $D08E               ; Go back and print all the credit strings
;
D0A2: 86 01           LDA     #$01                ; Scroll the text ...
D0A4: BD DE 01        JSR     WhiteLineScroll     ; ... outside to inside
D0A7: 86 FF           LDA     #$FF                ; Set the color mask ...
D0A9: 97 AD           STA     <ColorMask          ; ... to white
D0AB: CE CC 90        LDU     #NotesSplash        ; Song table
D0AE: C6 27           LDB     #$27                ; 39 notes (including rests) in the song
D0B0: D7 98           STB     <Temp2              ; Note counter
D0B2: BD D5 01        JSR     CheckSpaceOrButton  ; User pressed space or joystick button?
D0B5: 25 1D           BCS     LiveGame            ; Yes ... break out to play game
D0B7: EC C4           LDD     ,U                  ; Get duration
D0B9: 27 10           BEQ     $D0CB               ; It never is 0000 in our table. Skip printing for whatever reason.
D0BB: 8E D5 EF        LDX     #StrsCredits        ; "Mega-Bug" text
D0BE: DC 9A           LDD     <DrawingScreenPtr   ; The screen buffer ...
D0C0: DD 9E           STD     <ScreenPtr          ; ... to draw on
D0C2: EC 81           LDD     ,X++                ; Destination of "Mega-Bug" string
D0C4: DD AB           STD     <PixCoords          ; Store screen coordinates
D0C6: 30 01           LEAX    1,X                 ; Skip over color mask
D0C8: BD D6 F4        JSR     PrintMsgChgCol      ; Print with alternating colors
D0CB: BD D7 3F        JSR     PlayTwoNotes        ; Play dual note
D0CE: 0A 98           DEC     <Temp2              ; All notes played?
D0D0: 26 E0           BNE     $D0B2               ; No ... keep playing notes
D0D2: 20 52           BRA     $D126               ; Time for the demo game

LiveGame: 
D0D4: 86 FF           LDA     #$FF                ; This is a ...
D0D6: 97 B5           STA     <LiveOrDemo         ; ... live-player game
D0D8: BD DB 6D        JSR     CopyScreen          ; Copy screen 0400 to 1C00 and show 1C00
D0DB: 4F              CLRA                        ; 0 minutes
D0DC: 5F              CLRB                        ; 0 seconds
D0DD: DD AF           STD     <NumMinutes         ; Initialize game time to 00:00
D0DF: DD B1           STD     <Score              ; Initialize score to 0000
D0E1: CE 04 00        LDU     #$0400              ; Clear ...
D0E4: BD D4 AE        JSR     Clear1200           ; ... first screen buffer
;
LiveGameLoop:
D0E7: CC 05 21        LDD     #$0521              ; (5,33) 5 rows down, 33 pixels across
D0EA: DD AB           STD     <PixCoords          ; Store screen coordinates
D0EC: CC 04 00        LDD     #$0400              ; Drawing on ...
D0EF: DD 9E           STD     <ScreenPtr          ; ... first screen buffer
D0F1: 86 AA           LDA     #$AA                ; Set ...
D0F3: 97 AD           STA     <ColorMask          ; ... message color
D0F5: 8E D5 E8        LDX     #StrTime            ; Pointer to string "Time:_"
D0F8: BD D6 FA        JSR     PrintMsg            ; Print "Time:_"
D0FB: 96 AF           LDA     <NumMinutes         ; Number of minutes
D0FD: BD D6 D7        JSR     PrintTwoDigits      ; print minutes
D100: 86 42           LDA     #$42                ; Colon
D102: BD D6 79        JSR     PrintChar           ; print colon in time
D105: 96 AC           LDA     <PixCoords+1        ; Next ...
D107: 8B 06           ADDA    #$06                ; ... screen location to ...
D109: 97 AC           STA     <PixCoords+1        ; ... the right
D10B: 96 B0           LDA     <NumSeconds         ; Number of seconds
D10D: BD D6 D7        JSR     PrintTwoDigits      ; print seconds
D110: CC 54 21        LDD     #$5421              ; (84,33) 84 rows down, 33 pixels across
D113: DD AB           STD     <PixCoords          ; Screen coordinates
D115: 8E D5 E0        LDX     #StrScore           ; Message string
D118: BD D6 FA        JSR     PrintMsg            ; Print "Score:_"
D11B: 9E B1           LDX     <Score              ; Print ...
D11D: BD D6 CB        JSR     PrintFourDigits     ; ... the score
D120: 86 C0           LDA     #$C0                ; Initial maze "loopiness" ...
D122: 97 C0           STA     <MazeLoopiness      ; ... as levels progress, they become more "dead-end-y"
D124: 20 38           BRA     $D15E               ; Jump to game play

; Start demo game
D126: 0F B5           CLR     <LiveOrDemo         ; This is a demo game
D128: BD DB 6D        JSR     CopyScreen          ; Copy screen 0400 to 1C00 and show 1C00
D12B: 8E 08 34        LDX     #$0834              ; Number of passes in ...
D12E: 9F C3           STX     <DemoTimer          ; ... demo game
D130: CE 04 00        LDU     #$0400              ; Clear the ...
D133: BD D4 AE        JSR     Clear1200           ; ... first screen buffer
D136: 86 AA           LDA     #$AA                ; Set the ...
D138: 97 AD           STA     <ColorMask          ; ... color
D13A: CC 04 13        LDD     #$0413              ; (4,19) 4 rows down, 19 pixels across
D13D: DD AB           STD     <PixCoords          ; screen coords
D13F: CC 04 00        LDD     #$0400              ; Use the first ...
D142: DD 9E           STD     <ScreenPtr          ; ... screen buffer
D144: 8E D5 C2        LDX     #StrHighScore       ; "High Score" string
D147: BD D6 FA        JSR     PrintMsg            ; print "High Score"
D14A: 9E B3           LDX     <HighScore          ; Get the high score
D14C: BD D6 CB        JSR     PrintFourDigits     ; Print 4 digits
D14F: CC 54 04        LDD     #$5404              ; (84,4) 84 rows down, 4 pixels across
D152: DD AB           STD     <PixCoords          ; Set coordinates
D154: 8E D5 CE        LDX     #StrPlayMega        ; "Play Mega-Bug" string
D157: BD D6 FA        JSR     PrintMsg            ; Print "Play Mega-Bug"
D15A: 86 C0           LDA     #$C0                ; Initial maze "loopiness" ...
D15C: 97 C0           STA     <MazeLoopiness      ; ... as levels progress, they become more "dead-end-y"
;
D15E: BD DB 6D        JSR     CopyScreen          ; Copy the visible screen to 1C00 and show it
D161: 0F B6           CLR     <ISRCountScore      ; Once per second counter for score decrement
D163: 0F B7           CLR     <ISRCountTime       ; Once per second counter for time increment
D165: 86 31           LDA     #$31                ; Player starting Y coordinate 49
D167: C6 41           LDB     #$41                ; Player starting X coordinate 65
D169: DD A2           STD     <PlayerCoords       ; Set player coordinates
D16B: 0F A4           CLR     <PlayerDir          ; Player direction (facing up)
D16D: BD D4 BD        JSR     PlaceBugs           ; Place the bugs in the maze
D170: BD DC 56        JSR     DrawMaze            ; Draw the random maze
D173: 0F BA           CLR     <MakeEatSound       ; 
D175: 8E 06 00        LDX     #$0600              ; Copy ...
D178: CE 04 00        LDU     #$0400              ; ... screen buffer 0400 ...
D17B: EC C4           LDD     ,U                  ; ... to ...
D17D: ED C9 0C 00     STD     $0C00,U             ; ...
D181: ED C9 18 00     STD     $1800,U             ; ...
D185: 33 42           LEAU    2,U                 ; ... screen 1000
D187: 30 1F           LEAX    -1,X                ; ...
D189: 26 F0           BNE     $D17B               ; ... and 1C00
D18B: 0F A1           CLR     <MouthOpen          ; Mouth starts open
D18D: 0D B5           TST     <LiveOrDemo         ; Live or demo?
D18F: 27 1F           BEQ     $D1B0               ; Demo ... skip playing music
;
D191: C6 13           LDB     #$13                ; Limited 19 notes
D193: 0D C6           TST     <PlayShortSong      ; Have we already played this music?
D195: 26 02           BNE     $D199               ; Yes ... use a shorter version
D197: C6 27           LDB     #$27                ; No ... use the full version
D199: D7 98           STB     <Temp2              ; Number of notes to play
D19B: CE CC 90        LDU     #NotesSplash        ; Splash music table
D19E: BD D7 3F        JSR     PlayTwoNotes        ; Play a note from the song
D1A1: 8E 12 00        LDX     #$1200              ; Long ...
D1A4: 30 1F           LEAX    -1,X                ; ... delay ...
D1A6: 26 FC           BNE     $D1A4               ; ... between notes
D1A8: 0A 98           DEC     <Temp2              ; Have we played all the notes?
D1AA: 26 F2           BNE     $D19E               ; No ... go back for them all
D1AC: 86 FF           LDA     #$FF                ; Note that we ...
D1AE: 97 C6           STA     <PlayShortSong      ; ... have played the full song
;
D1B0: BD DA 33        JSR     DrawMagnifier       ; Draw the magnifier
D1B3: BD D4 A2        JSR     SwapScreenPointers  ; Swap screen pointers
D1B6: 97 92           STA     <RequestedPage      ; A set to same as 9C by swap
D1B8: 86 0F           LDA     #$0F                ; Delay ...
D1BA: 13              SYNC                        ; ... for ...
D1BB: 4A              DECA                        ; ... 16 ...
D1BC: 26 FC           BNE     $D1BA               ; Syncs
D1BE: 86 FF           LDA     #$FF                ; This is the ...
D1C0: 97 C1           STA     <ShowingGame        ; ... main game screen display
D1C2: BD DF 70        JSR     EraseBugDot         ; Erase the bugs as dots
D1C5: BD DB 1F        JSR     EraseMagnifier      ; Erase magnifier
D1C8: 03 A1           COM     <MouthOpen          ; Change mouth (open or closed)
D1CA: 2A 03           BPL     $D1CF               ; Don't move the bugs when mouth is open
D1CC: BD DE 7A        JSR     MoveBugs            ; Move the bugs
D1CF: BD DF 68        JSR     DrawBugDot          ; Draw bugs as dots
D1D2: BD D9 35        JSR     MovePlayer          ; Move the player
D1D5: DC BE           LDD     <DotsLeft           ; How many dots are left to be eaten?
D1D7: 10 27 01 69     LBEQ    PlayerWins          ; None ... player wins
D1DB: 96 B8           LDA     <DrawScore          ; Draw the score?
D1DD: 94 B5           ANDA    <LiveOrDemo         ; Is this the demo game?
D1DF: 27 25           BEQ     $D206               ; Either of those ... skip drawing score
;
; Draw score
D1E1: 86 AA           LDA     #$AA                ; Score ...
D1E3: 97 AD           STA     <ColorMask          ; ... color
D1E5: CC 54 4B        LDD     #$544B              ; (84,75) 84 rows down, 75 pixels across
D1E8: DD AB           STD     <PixCoords          ; Set coordinates
D1EA: DC 9A           LDD     <DrawingScreenPtr   ; Draw on the ...
D1EC: DD 9E           STD     <ScreenPtr          ; ... invisible screen
D1EE: 9E B1           LDX     <Score              ; Current score
D1F0: BD D6 CB        JSR     PrintFourDigits     ; print score
D1F3: 0A B8           DEC     <DrawScore          ; Need to draw the score?
D1F5: 27 0F           BEQ     $D206               ; No ... skip it on the background
D1F7: CC 54 4B        LDD     #$544B              ; Coordinates for ...
D1FA: DD AB           STD     <PixCoords          ; ... the score
D1FC: CC 04 00        LDD     #$0400              ; Draw on the ...
D1FF: DD 9E           STD     <ScreenPtr          ; ... 1st screen buffer
D201: 9E B1           LDX     <Score              ; Current score
D203: BD D6 CB        JSR     PrintFourDigits     ; print score
;
D206: 96 B9           LDA     <DrawCountSecs      ; Flag to draw time ...
D208: 94 B5           ANDA    <LiveOrDemo         ; ... and live/demo flag
D20A: 27 3B           BEQ     $D247               ; Skip drawing the seconds-count
;
; Print time
D20C: 86 AA           LDA     #$AA                ; Set ...
D20E: 97 AD           STA     <ColorMask          ; ... color
D210: CC 05 45        LDD     #$0545              ; (5,69) 5 rows down, 69 pixels across
D213: DD AB           STD     <PixCoords          ; set coords
D215: DC 9A           LDD     <DrawingScreenPtr   ; Draw on the ...
D217: DD 9E           STD     <ScreenPtr          ; ... invisible screen
D219: 96 AF           LDA     <NumMinutes         ; Print ...
D21B: BD D6 D7        JSR     PrintTwoDigits      ; ... minutes
D21E: 96 AC           LDA     <PixCoords+1        ; Next ...
D220: 8B 06           ADDA    #$06                ; ... to ...
D222: 97 AC           STA     <PixCoords+1        ; ... right
D224: 96 B0           LDA     <NumSeconds         ; Print ...
D226: BD D6 D7        JSR     PrintTwoDigits      ; ... seconds
D229: 0A B9           DEC     <DrawCountSecs      ; Need to draw the seconds-count?
D22B: 27 1A           BEQ     $D247               ; No ... skip it
D22D: CC 05 45        LDD     #$0545              ; Coordinates on the screen ...
D230: DD AB           STD     <PixCoords          ; ... for the seconds-count
D232: CC 04 00        LDD     #$0400              ; Draw on ...
D235: DD 9E           STD     <ScreenPtr          ; ... 1st screen buffer
D237: 96 AF           LDA     <NumMinutes         ; Print ...
D239: BD D6 D7        JSR     PrintTwoDigits      ; ... number of minutes
D23C: 96 AC           LDA     <PixCoords+1        ; Skip to where ...
D23E: 8B 06           ADDA    #$06                ; ... seconds are ...
D240: 97 AC           STA     <PixCoords+1        ; ... printed
D242: 96 B0           LDA     <NumSeconds         ; Print ...
D244: BD D6 D7        JSR     PrintTwoDigits      ; ... number of seconds
;
;
D247: BD DA 33        JSR     DrawMagnifier       ; Draw the magnifier
D24A: 0D BA           TST     <MakeEatSound       ; Do we make the eat dot sound?
D24C: 27 02           BEQ     $D250               ; No ... skip doing it
D24E: 0A BA           DEC     <MakeEatSound       ; Yes ... make the sound
D250: BD D7 D8        JSR     DrawMouth           ; Draw the mouth
D253: BD D8 20        JSR     DrawBugs            ; Draw the bugs on the magnifier
D256: BD D4 A2        JSR     SwapScreenPointers  ; Swap drawing ...
D259: 97 92           STA     <RequestedPage      ; ... and display screens
D25B: 13              SYNC                        ; Wait for screens to swap
D25C: DC A2           LDD     <PlayerCoords       ; Player coordinates
D25E: DD 8E           STD     <Temp1              ; The collision checker uses this temporary
D260: BD DF CC        JSR     CheckCollision      ; Did the player collide with a bug?
D263: 10 25 00 8C     LBCS    PlayerDied          ; Yes ... end of game
D267: 0D B5           TST     <LiveOrDemo         ; Are we in demo mode?
D269: 27 1F           BEQ     $D28A               ; Yes ... skip the pause
D26B: AD 9F A0 00     JSR     [POLCAT]            ; Get a character from the keyboard
D26F: 81 03           CMPA    #$03                ; BREAK?
D271: 10 27 FD EB     LBEQ    SplashMode          ; Yes ... jump to splash mode
D275: 81 0D           CMPA    #$0D                ; ENTER?
D277: 10 26 FF 47     LBNE    $D1C2               ; No ... back to top of game loop
D27B: 1A 50           ORCC    #$50                ; Turn interrupts off
D27D: AD 9F A0 00     JSR     [POLCAT]            ; Get a character from the keyboard
D281: 81 0D           CMPA    #$0D                ; ENTER to un-pause?
D283: 26 F8           BNE     $D27D               ; No ... keep waiting
D285: 1C EF           ANDCC   #$EF                ; Re-enable interrupts
D287: 7E D1 C2        JMP     $D1C2               ; Back to top of game loop
;
; We know we are in demo mode
D28A: BD D5 01        JSR     CheckSpaceOrButton  ; User wants to start a game?
D28D: 10 25 FE 43     LBCS    LiveGame            ; Yes ... start a live game
D291: 8E 08 00        LDX     #$0800              ; Short ...
D294: 30 1F           LEAX    -1,X                ; ... ...
D296: 26 FC           BNE     $D294               ; ... delay
D298: 9E C3           LDX     <DemoTimer          ; Time to end the demo game?
D29A: 10 27 FD C2     LBEQ    SplashMode          ; Yes ... back to the top of splash mode
D29E: 7E D1 C2        JMP     $D1C2               ; No ... keep playing the demo game

Need16K:
D2A1: 0A 01 AA 
D2A4: 31 36 6B 20 6F 72 20 6D 6F 72 65 20 6F 66 20 6D 65 6D 6F 72 79 00
; 16k_or_more_of_memory
 
D2BA: 1E 0D 55
D2BD: 69 73 20 6E 65 65 64 65 64 20 74 6F 20 70 6C 61 79 00        
; is_needed_to_play

D2CF: 32 2A FF
D2D2: 4D 65 67 61 22 42 75 67 00 
; Mega-Bug

D2DB: 00 00 00 

SetGraphicsMode

SetGraphicsMode:
; 128x96 4 colors (4 pixels per byte)
D2DE: B7 FF C0        STA     dispMode            ; V0 = 0
D2E1: B7 FF C2        STA     dispMode+2          ; V1 = 0
D2E4: B7 FF C5        STA     dispMode+5          ; V2 = 1
D2E7: B7 FF C7        STA     dispOffset+1        ; F0 = 1
D2EA: B7 FF C8        STA     dispOffset+2        ; F1 = 0
D2ED: 86 FF           LDA     #$FF                ; VDG ...
D2EF: B7 FF 22        STA     PIA1_DB             ; ... all 1s
D2F2: 39              RTS                         ; Done

Player Died

When the player touches a bug, the code comes here. The code plays the "we gotcha" tone, and if it is a demo game then the code returns to the splash mode.

If this is a live game, the code updates the high score if needed and plays the "we gotcha" audio samples. Then the large bugs on the side dance a little.

The code waits 3 seconds for the player to immediately start a new game. Otherwise the code goes to the splash mode.

PlayerDied:
D2F3: 0F C1           CLR     <ShowingGame        ; We are NOT showing the game screen
D2F5: BD D7 A7        JSR     PlayGotchaTone      ; Play the "we gotcha" tone
D2F8: 0D B5           TST     <LiveOrDemo         ; Are we in demo mode (don't say "we gotcha")?
D2FA: 10 27 FD 62     LBEQ    SplashMode          ; Yes ... restart splash
D2FE: DC B1           LDD     <Score              ; Is the current score ...
D300: 10 93 B3        CMPD    <HighScore          ; ... a new high score
D303: 25 02           BCS     $D307               ; No ... leave old high score
D305: DD B3           STD     <HighScore          ; this is the new high score
D307: BD D7 7C        JSR     PlayWeGotcha        ; Play "We Gotcha"
;
D30A: 86 04           LDA     #$04                ; Show the ...
D30C: 97 92           STA     <RequestedPage      ; ... maze screen in buffer 1
D30E: 86 0E           LDA     #$0E                ; Set counter ...
D310: 97 98           STA     <Temp2              ; ... for 14 jumping animations
D312: CE CB 50        LDU     #GraBugJumping1     ; Graphics first position
D315: 96 98           LDA     <Temp2              ; Is this an ...
D317: 84 01           ANDA    #$01                ; ... even count?
D319: 27 03           BEQ     $D31E               ; Yes ... use 1st graphics
D31B: CE CB F0        LDU     #GraBugJumping2     ; No ... use second graphics
D31E: BD D4 81        JSR     DrawLargeBugs       ; Draw the jumping bug
D321: 86 0A           LDA     #$0A                ; Pause ...
D323: 13              SYNC                        ; ... for ...
D324: 4A              DECA                        ; ... 10 ...
D325: 26 FC           BNE     $D323               ; ... interrupts
D327: 0A 98           DEC     <Temp2              ; Decrement the jump count
D329: 26 E7           BNE     $D312               ; Do all jumps
D32B: CE CA B0        LDU     #GraBugStanding     ; Back to ...
D32E: BD D4 81        JSR     DrawLargeBugs       ; ... standing bug
;
; Give the user 3 seconds to start another game immediately.
; Otherwise go back to the splash mode.
D331: 8E 01 2C        LDX     #$012C              ; About 3 seconds
D334: 9F C3           STX     <DemoTimer          ; Let the ISR count this down
D336: BD D5 01        JSR     CheckSpaceOrButton  ; User press button or space?
D339: 10 25 FD 97     LBCS    LiveGame            ; Yes ... start a live game
D33D: 9E C3           LDX     <DemoTimer          ; Timer expired?
D33F: 26 F5           BNE     $D336               ; No ... keep waiting
D341: 7E D0 60        JMP     SplashMode          ; Yes ... restart the splash mode

Player wins

The code copies the maze to all three screen buffer and changes the color of the maze walls on each. Then, it loops the screen one by one for a flashing effect.

Next, the code wipes the screen using the white scrolling lines.

A line of bugs marches down the screen from top to bottom leaving the text "We'll getcha next time" in their wake. Then a lone bug quickly marches down to draw the exclamation point. The maze loopiness is divided by two (starts at 192), there is a small delay, and the next game begins.

; Player wins
PlayerWins:
D344: 0F C1           CLR     <ShowingGame        ; We are NOT showing the game screen
D346: BD DA 33        JSR     DrawMagnifier       ; Why draw ...
D349: BD DA 33        JSR     DrawMagnifier       ; ... the magnifier ...
D34C: BD DA 33        JSR     DrawMagnifier       ; ... three times? Maybe for a small delay?
;
; Copy the source maze to the other two screen buffers
D34F: 86 04           LDA     #$04                ; Switch to the ...
D351: 97 92           STA     <RequestedPage      ; ... first page (with the maze on it)
D353: 13              SYNC                        ; Wait for the screen to change
D354: 8E 06 00        LDX     #$0600              ; 1.5K words = 3.0K bytes
D357: CE 04 00        LDU     #$0400              ; Start of first screen buffer
D35A: EC C1           LDD     ,U++                ; Copy maze source ...
D35C: ED C9 0B FE     STD     $0BFE,U             ; To second screen buffer and ...
D360: ED C9 17 FE     STD     $17FE,U             ; ... third screen buffer
D364: 30 1F           LEAX    -1,X                ; All done?
D366: 26 F2           BNE     $D35A               ; No ... copy all of screen
;
; Change the maze colors on the other two screen buffers
D368: 86 02           LDA     #$02                ; Two screens to change
D36A: 97 98           STA     <Temp2              ; Keep the counter here
D36C: 86 AA           LDA     #$AA                ; First color ...
D36E: 97 AD           STA     <ColorMask          ; ... mask
D370: 86 C0           LDA     #$C0                ; First ...
D372: 97 88           STA     <BitPos             ; ... pixel
D374: DE 9A           LDU     <DrawingScreenPtr   ; 
D376: 33 C9 01 C5     LEAU    $01C5,U             ; Where the maze starts on the drawing screen
D37A: 8E 05 C5        LDX     #$05C5              ; Where the maze starts on the original source screen
D37D: 96 88           LDA     <BitPos             ; Get bit position
D37F: 94 AD           ANDA    <ColorMask          ; Set the color
D381: 97 89           STA     <BitPosSrc          ; Hold the target color
D383: 86 43           LDA     #$43                ; 67 rows in the maze
D385: 97 99           STA     <Temp3              ; Counter here
D387: C6 16           LDB     #$16                ; 22 bytes across maze
D389: A6 80           LDA     ,X+                 ; Value from maze source
D38B: 88 55           EORA    #$55                ; Is this bit part ...
D38D: 94 88           ANDA    <BitPos             ; ... of the maze?
D38F: 26 06           BNE     $D397               ; No ... leave this byte alone
D391: 96 89           LDA     <BitPosSrc          ; Target color mask
D393: A8 C4           EORA    ,U                  ; Change the color ...
D395: A7 C4           STA     ,U                  ; ... on the drawing screen
D397: 33 41           LEAU    1,U                 ; Next byte in maze on drawing screen
D399: 5A              DECB                        ; All bytes on this row done?
D39A: 26 ED           BNE     $D389               ; No ... go do all 22 bytes
D39C: 30 0A           LEAX    10,X                ; 10 bytes to ...
D39E: 33 4A           LEAU    10,U                ; ... start of next row in maze
D3A0: 0A 99           DEC     <Temp3              ; All 67 rows done?
D3A2: 26 E3           BNE     $D387               ; No ... do them all
D3A4: 04 88           LSR     <BitPos             ; Next bit ...
D3A6: 04 88           LSR     <BitPos             ; ... to the right
D3A8: 26 CA           BNE     $D374               ; All sets of 4 pixels done? No ... go back and do the next
D3AA: BD D4 A2        JSR     SwapScreenPointers  ; Switch drawing screens
D3AD: 96 AD           LDA     <ColorMask          ; Change ...
D3AF: 8B 55           ADDA    #$55                ; ... to next ...
D3B1: 97 AD           STA     <ColorMask          ; ... color
D3B3: 0A 98           DEC     <Temp2              ; All screens done?
D3B5: 26 B9           BNE     $D370               ; No ... back for all
;
; Flash the maze wall as a reward
D3B7: 86 04           LDA     #$04                ; Start with first ...
D3B9: 97 A5           STA     <HorzDoubler        ; ... screen buffer
D3BB: C6 28           LDB     #$28                ; Flashing 24 times
D3BD: 96 A5           LDA     <HorzDoubler        ; Get current screen offset
D3BF: 8B 0C           ADDA    #$0C                ; Move to the next screen buffer
D3C1: 81 28           CMPA    #$28                ; All 3 screens shown?
D3C3: 25 02           BCS     $D3C7               ; No ... keep this
D3C5: 86 04           LDA     #$04                ; Yes ... back up to first screen
D3C7: 97 A5           STA     <HorzDoubler        ; New screen to show
D3C9: 97 92           STA     <RequestedPage      ; Request ISR to switch to this one
D3CB: 86 06           LDA     #$06                ; Delay ...
D3CD: 13              SYNC                        ; ... of ...
D3CE: 4A              DECA                        ; ... six ...
D3CF: 26 FC           BNE     $D3CD               ; ... interrupts
D3D1: 5A              DECB                        ; All 28 flashes done?
D3D2: 26 E9           BNE     $D3BD               ; No ... do all flashes
;
; White-line-scroll the screen to erase it
D3D4: 86 04           LDA     #$04                ; Show the source ...
D3D6: 97 92           STA     <RequestedPage      ; ... screen ...
D3D8: 13              SYNC                        ; ... buffer
D3D9: BD DB 6D        JSR     CopyScreen          ; Copy screen 0400 to 1C00 and show 1C00
D3DC: CE 04 00        LDU     #$0400              ; Clear the ...
D3DF: BD D4 AE        JSR     Clear1200           ; ... first screen buffer
D3E2: 86 01           LDA     #$01                ; Scroll the screen ...
D3E4: BD DE 01        JSR     WhiteLineScroll     ; ... outside to inside
D3E7: 04 C0           LSR     <MazeLoopiness      ; Make the next maze tougher -- less loopy
D3E9: 96 A0           LDA     <NumBugs            ; Number of bugs in the game
D3EB: 4C              INCA                        ; Getting tougher ... one more bug
D3EC: 81 20           CMPA    #$20                ; Max of 32 reached?
D3EE: 24 02           BCC     $D3F2               ; Yes ... leave it at 32
D3F0: 97 A0           STA     <NumBugs            ; New number of bugs
;
; Ready the "We'll get you next time!" text
D3F2: CE 10 00        LDU     #$1000              ; Using 2nd ...
D3F5: DF 9E           STU     <ScreenPtr          ; ... screen buffer for drawing
D3F7: BD D4 AE        JSR     Clear1200           ; Clear the screen
D3FA: 8E D6 5A        LDX     #StrNextTime        ; The "we'll getcha next time" string
D3FD: EC 81           LDD     ,X++                ; Set the ...
D3FF: DD AB           STD     <PixCoords          ; ... destination coordinates
D401: 27 09           BEQ     $D40C               ; All strings printed ... move on
D403: A6 80           LDA     ,X+                 ; Set the ...
D405: 97 AD           STA     <ColorMask          ; ... color mask
D407: BD D6 FA        JSR     PrintMsg            ; Print this message
D40A: 20 F1           BRA     $D3FD               ; Go back for all messages
;
; Line of bugs to scroll the text onto the screen
D40C: 86 01           LDA     #$01                ; Start the line of bugs ...
D40E: 97 98           STA     <Temp2              ; ... on line 1
D410: 8E C0 00        LDX     #$C000              ; This is ROM ... first call to "erase" won't do anything (ROM is read-only)
D413: 9F A5           STX     <HorzDoubler        ; Where to erase (filled in by the draw-line-of-bugs)
D415: 86 06           LDA     #$06                ; Delay for ...
D417: 8D 4E           BSR     DelaySyncs          ; ... 6 interrupts (10th of a second)
D419: 8D 51           BSR     EraseBugLine        ; Erase the last bug line (do nothing first pass)
D41B: 96 98           LDA     <Temp2              ; Move the ...
D41D: 8B 02           ADDA    #$02                ; ... bug line ...
D41F: 97 98           STA     <Temp2              ; ... down 2 pixels
D421: 81 59           CMPA    #$59                ; All done?
D423: 24 0A           BCC     $D42F               ; Yes ... move on
D425: BD DB B1        JSR     DrawSplashBugLine   ; Draw the line of bugs
D428: 03 A1           COM     <MouthOpen          ; Flip between bug pictures each time
D42A: BD D5 27        JSR     SoundBugLine        ; Make the sound of the bugs moving
D42D: 20 E6           BRA     $D415               ; Move the bugs all the way down the screen
;
; Lone-bug scroll the "!" onto the screen
D42F: 0F 98           CLR     <Temp2              ; Start the lone bug at Y=0
D431: CC 28 5D        LDD     #$285D              ; Location to print ...
D434: DD AB           STD     <PixCoords          ; ... the "!"
D436: 86 FF           LDA     #$FF                ; White ...
D438: 97 AD           STA     <ColorMask          ; ... color
D43A: 86 3F           LDA     #$3F                ; The "!" character
D43C: BD D6 79        JSR     PrintChar           ; print the "!"
D43F: 86 2D           LDA     #$2D                ; Delay for ...
D441: BD D4 67        JSR     DelaySyncs          ; ... 3/4th second
D444: 86 02           LDA     #$02                ; Delay for ...
D446: 8D 1F           BSR     DelaySyncs          ; ... two interrupts
D448: BD DB DD        JSR     EraseLoneSplash     ; Erase the lone bug
D44B: 96 98           LDA     <Temp2              ; Y coordinate
D44D: 8B 02           ADDA    #$02                ; Add two ...
D44F: 97 98           STA     <Temp2              ; ... rows
D451: 81 58           CMPA    #$58                ; Reached the bottom?
D453: 24 0A           BCC     $D45F               ; Yes ... done
D455: BD DB E0        JSR     DrawLoneSplash      ; Draw the lone bug
D458: 03 A1           COM     <MouthOpen          ; Next bug picture
D45A: BD D5 27        JSR     SoundBugLine        ; Make the bug sound
D45D: 20 E5           BRA     $D444               ; Move the lone bug all the way down
;
; Delay and back to live game loop
D45F: 86 64           LDA     #$64                ; Long 1.6 second ...
D461: BD D4 67        JSR     DelaySyncs          ; ... delay
D464: 7E D0 E7        JMP     LiveGameLoop        ; Back to the live game loop

Delay for N syncs

DelaySyncs:
D467: 13              SYNC                        ; Wait for interrupt
D468: 4A              DECA                        ; all syncs done?
D469: 26 FC           BNE     DelaySyncs          ; No ... keep syncing
D46B: 39              RTS                         ; Done

EraseBugLine:
; A bug occupies 6 rows. Erasing the row means 4 rows of blank at the bottom and 2 rows of
; text at the top.
D46C: 9E A5           LDX     <HorzDoubler        ; Current end of bug row
D46E: C6 80           LDB     #$80                ; Erase ...
D470: 6F 82           CLR     ,-X                 ; ... four ...
D472: 5A              DECB                        ; ... ...
D473: 26 FB           BNE     $D470               ; ... rows
D475: C6 40           LDB     #$40                ; Copy two rows
D477: A6 89 F3 FF     LDA     $F3FF,X             ; -3073 ... from the text screen
D47B: A7 82           STA     ,-X                 ; To this screen
D47D: 5A              DECB                        ; Copy ...
D47E: 26 F7           BNE     $D477               ; ... two rows of the text
D480: 39              RTS                         ; Done

Draw large bugs

Since the bugs are single-pixel dots on the maze screen, they are drawn in graphics on the magnifier if they are seen.

; Draw large bugs on both sides of the screen

DrawLargeBugs:
D481: 8E 08 00        LDX     #$0800              ; Start spot on screen
D484: 86 05           LDA     #$05                ; Count five ...
D486: 97 99           STA     <Temp3              ; ... columns
D488: C6 20           LDB     #$20                ; 32 rows
D48A: 34 10           PSHS    X                   ; Hold start of column
D48C: A6 C0           LDA     ,U+                 ; Get graphics data
D48E: A7 88 1B        STA     $1B,X               ; Right side of screen
D491: A7 84           STA     ,X                  ; Left side of screen
D493: 30 88 20        LEAX    $20,X               ; Next row
D496: 5A              DECB                        ; All rows done?
D497: 26 F3           BNE     $D48C               ; Do all 32 rows
D499: 35 10           PULS    X                   ; Start of column
D49B: 30 01           LEAX    1,X                 ; One column over
D49D: 0A 99           DEC     <Temp3              ; All 5 columns done?
D49F: 26 E7           BNE     $D488               ; No ... do all columns
D4A1: 39              RTS                         ; Done

SwapScreenPointers:
D4A2: 34 10           PSHS    X                   ; Preserve X
D4A4: DC 9A           LDD     <DrawingScreenPtr   ; Swap ...
D4A6: 9E 9C           LDX     <VisibleScreenPtr   ; ... 9A (drawing) ...
D4A8: DD 9C           STD     <VisibleScreenPtr   ; ... and ...
D4AA: 9F 9A           STX     <DrawingScreenPtr   ; ... 9C (visible)
D4AC: 35 90           PULS    X,PC                ; Done

Clear1200

Clear1200:
; Clear $1200 bytes at X
D4AE: 34 10           PSHS    X                   ; Hold X
D4B0: 8E 06 00        LDX     #$0600              ; $600 words ($1200 bytes)
D4B3: 4F              CLRA                        ; 0 to ...
D4B4: 5F              CLRB                        ; ... D
D4B5: ED C1           STD     ,U++                ; Clear memory
D4B7: 30 1F           LEAX    -1,X                ; All words done?
D4B9: 26 FA           BNE     $D4B5               ; No ... do all
D4BB: 35 90           PULS    X,PC                ; Restore X and out

PlaceBugs:
D4BD: 8E 28 08        LDX     #$2808              ; Data on bugs (3 bytes each)
D4C0: 96 A0           LDA     <NumBugs            ; Number of bugs to place
D4C2: 97 98           STA     <Temp2              ; Use this as a counter
D4C4: BD DD 52        JSR     GetRandom           ; Get random Y coordinate
D4C7: 84 7C           ANDA    #$7C                ; Power of 4 and no negatives
D4C9: 81 40           CMPA    #$40                ; 64 ... height of maze
D4CB: 24 F7           BCC     $D4C4               ; Out of bounds ... try again
D4CD: 8B 11           ADDA    #$11                ; Offset to 1st row in maze
D4CF: A7 88 60        STA     $60,X               ; Store bug's second set of X coordinate
D4D2: A7 84           STA     ,X                  ; Store bug's X coordinate
D4D4: BD DD 52        JSR     GetRandom           ; Get random X coordinate
D4D7: 84 7C           ANDA    #$7C                ; Power of 4 and no negatives
D4D9: 81 50           CMPA    #$50                ; 80 ... width of maze
D4DB: 24 F7           BCC     $D4D4               ; Out of bounds ... try again
D4DD: 8B 19           ADDA    #$19                ; Offset to first column in maze
D4DF: A7 88 61        STA     $61,X               ; Store bug's second set of Y coordinate
D4E2: A7 01           STA     1,X                 ; The bug's Y coordinate
D4E4: EC 84           LDD     ,X                  ; The bug coordinates we just set
D4E6: 90 A2           SUBA    <PlayerCoords       ; Compare the Y to the player's Y
D4E8: 2A 01           BPL     $D4EB               ; Absolute ...
D4EA: 40              NEGA                        ; ... value
D4EB: 81 0A           CMPA    #$0A                ; Too close to the player?
D4ED: 25 D5           BCS     $D4C4               ; Yes ... try again
D4EF: D0 A3           SUBB    <PlayerCoords+1     ; Compare the X to the player's X
D4F1: 2A 01           BPL     $D4F4               ; Absolute ...
D4F3: 50              NEGB                        ; ... value
D4F4: C1 0A           CMPB    #$0A                ; Too close to the player?
D4F6: 25 CC           BCS     $D4C4               ; Yes ... try again
D4F8: 6F 02           CLR     2,X                 ; Bugs always start moving up
D4FA: 30 03           LEAX    3,X                 ; Next bug structure
D4FC: 0A 98           DEC     <Temp2              ; Place all ...
D4FE: 26 C4           BNE     $D4C4               ; ... bugs
D500: 39              RTS                         ; Done

Check for space-bar or button press

Return carry=1 if yes or carry=0 if no. Return FF in C2 if joystick or 00 in C2 if keyboard.

CheckSpaceOrButton:
D501: 86 FF           LDA     #$FF                ; All columns ...
D503: B7 FF 02        STA     PIA0_DB             ; ... turned off
D506: F6 FF 00        LDB     PIA0_DA             ; Check the ...
D509: C4 01           ANDB    #$01                ; ... right joystick button
D50B: 26 05           BNE     $D512               ; No ... go try the keyboard
D50D: 97 C2           STA     <JoyOrKey           ; Yes ... C2=FF ... using joysticks
D50F: 1A 01           ORCC    #$01                ; Carry = 1
D511: 39              RTS                         ; Out
D512: 86 7F           LDA     #$7F                ; Turn on ...
D514: B7 FF 02        STA     PIA0_DB             ; ... upper column
D517: A6 8D 29 E5     LDA     PIA0_DA,PC          ; Read rows
D51B: 84 08           ANDA    #$08                ; Space bar pressed?
D51D: 26 05           BNE     $D524               ; No ... keep looking
D51F: 0F C2           CLR     <JoyOrKey           ; C2=0 ... using keyboard
D521: 1A 01           ORCC    #$01                ; Carry = 1
D523: 39              RTS                         ; Out
D524: 1C FE           ANDCC   #$FE                ; Carry = 0
D526: 39              RTS                         ; Out

Sound of bug line

SoundBugLine:
D527: 86 02           LDA     #$02                ; Sound loop "magic" here ...
D529: B7 FF 20        STA     PIA1_DA             ; ...
D52C: C6 23           LDB     #$23                ; ...
D52E: 1F 98           TFR     B,A                 ; ...
D530: 4A              DECA                        ; ...
D531: 26 FD           BNE     $D530               ; ...
D533: B6 FF 20        LDA     PIA1_DA             ; ...
D536: 88 40           EORA    #$40                ; ...
D538: B7 FF 20        STA     PIA1_DA             ; ...
D53B: 5C              INCB                        ; ...
D53C: C1 41           CMPB    #$41                ; ...
D53E: 25 EE           BCS     $D52E               ; ...
D540: 86 02           LDA     #$02                ; ...
D542: B7 FF 20        STA     PIA1_DA             ; ...
D545: 39              RTS                         ; Done

IRQ Service Routine

First, this routine changes the hardware graphics page to any requested new page.

Then it bumps the time value every second. Every second the player doesn't eat a dot, the score drops by 1.

IRQ:
; Set the desired display page
D546: 96 92           LDA     <RequestedPage      ; Desired page (256-byte boundary)
D548: 91 C7           CMPA    <VisiblePage        ; Already set?
D54A: 27 16           BEQ     $D562               ; Yes ... nothing to do
D54C: 97 C7           STA     <VisiblePage        ; This is the new set page
D54E: 44              LSRA                        ; Offset is 512 byte boundary ... ignore the LSB
D54F: C6 05           LDB     #$05                ; 6 registers (bits) to poke

;D54E: CC 02 05 ; Always show the 0400 screen (or pick another screen)

D551: 8E FF C6        LDX     #$FFC6              ; Display offset
D554: 44              LSRA                        ; Is this bit a 0?
D555: 24 06           BCC     $D55D               ; Yes ... go clear it
D557: 30 01           LEAX    1,X                 ; Next register is the 1 register
D559: A7 80           STA     ,X+                 ; Write a 1
D55B: 20 02           BRA     $D55F               ; Next bit
D55D: A7 81           STA     ,X++                ; Write a 0
D55F: 5A              DECB                        ; All bits done?
D560: 26 F2           BNE     $D554               ; No ... set all 5 bits

D562: 96 C1           LDA     <ShowingGame        ; Is the game screen being shown and ...
D564: 94 B5           ANDA    <LiveOrDemo         ; ... are we in the demo?
D566: 27 48           BEQ     $D5B0               ; Yes ... skip score count down
D568: 96 B6           LDA     <ISRCountScore      ; Bump ...
D56A: 4C              INCA                        ; ... interrupt ...
D56B: 97 B6           STA     <ISRCountScore      ; ... counter
D56D: 81 3C           CMPA    #$3C                ; Has it been 60 interrupts (1 second) without eating a dot?
D56F: 25 1C           BCS     $D58D               ; No ... not time to adjust the score
D571: 0F B6           CLR     <ISRCountScore      ; Yes ... reset interrupt counter back to 0
D573: DC B1           LDD     <Score              ; Is the score 0000?
D575: 27 16           BEQ     $D58D               ; Yes ... leave it alone
;
; The player loses 1 point a second if no dot is eaten
D577: 86 02           LDA     #$02                ; Draw the score for ...
D579: 97 B8           STA     <DrawScore          ; ... two interrupts (both screens)
D57B: 96 B2           LDA     <Score+1            ; Get score LSB
D57D: 8B 99           ADDA    #$99                ; Subtract 1 (BCD math)
D57F: 19              DAA                         ; Adjust for BCD
D580: 97 B2           STA     <Score+1            ; New score LSB
D582: 81 99           CMPA    #$99                ; Do we need to take 1 from MSB?
D584: 26 07           BNE     $D58D               ; No ... just the LSB
D586: 96 B1           LDA     <Score              ; Get score MSB
D588: 8B 99           ADDA    #$99                ; Subtract 1 (BCD math)
D58A: 19              DAA                         ; Adjust for BCD
D58B: 97 B1           STA     <Score              ; New score MSB
;
D58D: 96 B7           LDA     <ISRCountTime       ; Bump ...
D58F: 4C              INCA                        ; ... interrupt ...
D590: 97 B7           STA     <ISRCountTime       ; ... counter
D592: 81 3C           CMPA    #$3C                ; Has it been 60 interrupts (1 second) ?
D594: 25 1A           BCS     $D5B0               ; No ... not time to adjust the time
D596: 0F B7           CLR     <ISRCountTime       ; Yes ... reset interrupt counter back to 0
D598: 86 02           LDA     #$02                ; Redraw the seconds-count for ...
D59A: 97 B9           STA     <DrawCountSecs      ; ... two interrupts (both screen buffers)
;
; The timer goes up once a second
D59C: 96 B0           LDA     <NumSeconds         ; Add ...
D59E: 8B 01           ADDA    #$01                ; ... one to  number of seconds
D5A0: 19              DAA                         ; Adjust for BCD
D5A1: 97 B0           STA     <NumSeconds         ; New number of seconds
D5A3: 81 60           CMPA    #$60                ; Did we overflow into minutes?
D5A5: 25 09           BCS     $D5B0               ; No ... this is it
D5A7: 0F B0           CLR     <NumSeconds         ; Roll seconds back to 0
D5A9: 96 AF           LDA     <NumMinutes         ; Add ...
D5AB: 8B 01           ADDA    #$01                ; ... one to number of minutes
D5AD: 19              DAA                         ; Adjust for BCD
D5AE: 97 AF           STA     <NumMinutes         ; New number of minutes
;
D5B0: 9E C3           LDX     <DemoTimer          ; Count ...
D5B2: 27 04           BEQ     $D5B8               ; ... down ...
D5B4: 30 1F           LEAX    -1,X                ; ... the ...
D5B6: 9F C3           STX     <DemoTimer          ; ... demo game timer
;
; Allow interrupt to happen again
D5B8: B6 FF 03        LDA     PIA0_CB             ; Enable interrupt ...
D5BB: B6 FF 02        LDA     PIA0_DB             ; ... to fire again
D5BE: BD DD 52        JSR     GetRandom           ; Advance the random number generator
D5C1: 3B              RTI                         ; Done with interrupt

Text processing

Text strings

StrHighScore:
D5C2: 48 69 67 68 20 53 63 6F 72 65 20 00
; High_Score_

StrPlayMega:
D5CE: 20 20 20 50 6C 61 79 20 20 4D 65 67 61 22 42 75 67 00
; ___Play__Mega-Bug

StrScore:
D5E0: 53 63 6F 72 65 24 20 00 
; Score:_

StrTime:
D5E8: 54 69 6D 65 24 20 00
; Time:_

StrsCredits:
D5EF: 07 2A FF
D5F2: 4D 65 67 61 22 42 75 67 00
; Mega-Bug
    
D5FB: 17 3C 55 
D5FE: 42 79 00 
; By

D601: 21 21 55
D604: 53 74 65 76 65 20 42 6A 6F 72 6B 00
; Steve_Bjork
 
D610: 31 18 AA
D613: 43 6F 70 79 72 69 67 68 74 20 31 39 38 32 00
; Copyright_1982
   
D622: 3B 1B AA 
D625: 44 61 74 61 73 6F 66 74 20 49 6E 63 23 00
; Datasoft_Inc.

D633: 4B 1E 55 
D636: 4C 69 63 65 6E 73 65 64 20 74 6F 00
; Licensed_to
    
D642: 55 0C 55     
D645: 54 61 6E 64 79 20 43 6F 72 70 6F 72 61 74 69 6F 6E 00
; Tandy_Corporation

D657: 00 00 00 

StrNextTime:
D65A: 1B 1E 55 
D65D: 57 65 25 6C 6C 20 47 65 74 63 68 61 00
; We'll_Getcha
 
D66A: 28 27 AA 
D66D: 4E 65 78 74 20 54 69 6D 65 00
; Next_Time
 
D677: 00 00 

Print character

Print the given character to the given X,Y pixel coordinate.

  • A = character
  • <$AB,<$AC = (y,x)
  • <$AD = color mask
  • <$9E = top of screen
PrintChar:
D679: 34 40           PSHS    U                   ; Of all the registers, preserve U
D67B: DE 90           LDU     <RndSeed            ; Copy protection ...
D67D: 6F C9 C0 00     CLR     $C000,U             ; ... mangle random part of code if running in all-ram mode
D681: CE CD 7A        LDU     #GraChars           ; Start of character graphics
D684: C6 09           LDB     #$09                ; 9 bytes per character
D686: 3D              MUL                         ; Point to ...
D687: 33 CB           LEAU    D,U                 ; ... graphics
D689: DC AB           LDD     <PixCoords          ; (y,x) coordinate
D68B: 9E 9E           LDX     <ScreenPtr          ; Top of screen pointer
D68D: BD DE 5F        JSR     CoordToScrOffs      ; Get screen pointer and bit mask
D690: 86 09           LDA     #$09                ; Row counter ...
D692: A7 E2           STA     ,-S                 ; ... on stack
;
D694: A6 C0           LDA     ,U+                 ; Get next pixel data
D696: 34 16           PSHS    X,B,A               ; Save screen pointer and bit mask
D698: D7 88           STB     <BitPos             ; First pixel bit mask
D69A: C6 06           LDB     #$06                ; 6 pixels per character row
D69C: 96 88           LDA     <BitPos             ; Pixel pattern becomes ...
D69E: 43              COMA                        ; ... bit mask
D69F: A4 84           ANDA    ,X                  ; Get byte from screen and mask off pixel
D6A1: 68 E4           ASL     ,S                  ; Check bit from graphics data
D6A3: 24 08           BCC     $D6AD               ; A zero. Leave the pixel off
D6A5: 34 02           PSHS    A                   ; Hold the screen byte with pixel off
D6A7: 96 88           LDA     <BitPos             ; Get the pixel mask
D6A9: 94 AD           ANDA    <ColorMask          ; Mask in the desired color
D6AB: AA E0           ORA     ,S+                 ; Add the pixel color to the byte from the screen
D6AD: A7 84           STA     ,X                  ; Set pixel on the screen
D6AF: 04 88           LSR     <BitPos             ; Shift mask over ...
D6B1: 04 88           LSR     <BitPos             ; ... one pixel
D6B3: 26 06           BNE     $D6BB               ; Still a good mask ... skip reset
D6B5: 30 01           LEAX    1,X                 ; Next screen byte on row
D6B7: 86 C0           LDA     #$C0                ; Reset mask to ...
D6B9: 97 88           STA     <BitPos             ; ... 11_00_00_00
D6BB: 5A              DECB                        ; All 6 pixels done?
D6BC: 26 DE           BNE     $D69C               ; No ... finish this row
D6BE: 35 16           PULS    A,B,X               ; Restore screen pointer and bit mask
;
D6C0: 30 88 20        LEAX    $20,X               ; Next row on screen
D6C3: 6A E4           DEC     ,S                  ; All 9 bytes of data done?
D6C5: 26 CD           BNE     $D694               ; No ... keep going
D6C7: 32 61           LEAS    1,S                 ; Remove counter from stack
D6C9: 35 C0           PULS    U,PC                ; Done

Print four digit number

Color set to AA, value in X.

PrintFourDigits:
D6CB: 86 AA           LDA     #$AA                ; Set ...
D6CD: 97 AD           STA     <ColorMask          ; ... color mask
D6CF: 34 10           PSHS    X                   ; Two byte value to stack
D6D1: 35 02           PULS    A                   ; Get the upper most 2 digits
D6D3: 8D 02           BSR     PrintTwoDigits      ; Print upper 2 digits
D6D5: 35 02           PULS    A                   ; Get the lower 2 digits and fall into print

Print two digit number

BCD number in A.

PrintTwoDigits:
D6D7: 34 02           PSHS    A                   ; Hold number
D6D9: 44              LSRA                        ; Isolate ...
D6DA: 44              LSRA                        ; ...
D6DB: 44              LSRA                        ; ... upper ...
D6DC: 44              LSRA                        ; ... digit
D6DD: BD D6 79        JSR     PrintChar           ; Print upper digit
D6E0: 35 02           PULS    A                   ; Restore number
D6E2: D6 AC           LDB     <PixCoords+1        ; Skip ...
D6E4: CB 06           ADDB    #$06                ; ... to ...
D6E6: D7 AC           STB     <PixCoords+1        ; ... next on screen
D6E8: 84 0F           ANDA    #$0F                ; Isolate lower digit
D6EA: BD D6 79        JSR     PrintChar           ; Print lower digit
D6ED: D6 AC           LDB     <PixCoords+1        ; Skip ...
D6EF: CB 06           ADDB    #$06                ; ... to ...
D6F1: D7 AC           STB     <PixCoords+1        ; ... next on screen
D6F3: 39              RTS                         ; Done

Print message

Print a message on the screen:

  • X pointer to message
  • <$AB,$AC,$AD coordinates and color
  • <$AE set to one to rotate the color after every letter
PrintMsgChgCol:
D6F4: 0F AE           CLR     <ChangeColor        ; Set auto color ...
D6F6: 03 AE           COM     <ChangeColor        ; ... to true
D6F8: 20 02           BRA     $D6FC               ; Do printing

PrintMsg:
D6FA: 0F AE           CLR     <ChangeColor        ; Don't change the color each time
D6FC: A6 80           LDA     ,X+                 ; Get character
D6FE: 84 7F           ANDA    #$7F                ; Drop the upper bit
D700: 80 20           SUBA    #$20                ; No ASCII below this
D702: 25 EF           BCS     $D6F3               ; Less than SPACE ... out
D704: 81 06           CMPA    #$06                ; Is it a symbol (<space>!-.:,)
D706: 24 04           BCC     $D70C               ; No ... continue
D708: 8B 3E           ADDA    #$3E                ; Yes ... these are at the end of the letters (3E,3F,40,41,42,43)
D70A: 20 16           BRA     $D722               ; Print this character
D70C: 80 10           SUBA    #$10                ; Is this a symbol less than a number
D70E: 25 E3           BCS     $D6F3               ; Yes ... we don't know this one ... out
D710: 81 0A           CMPA    #$0A                ; Is this a plain digit?
D712: 25 0E           BCS     $D722               ; Yes ... we have it decoded ... print it
D714: 80 07           SUBA    #$07                ; A symbol between numbers and 'A' ?
D716: 25 DB           BCS     $D6F3               ; Yes ... we don't know this one ... out
D718: 81 24           CMPA    #$24                ; An upper-case letter?
D71A: 25 06           BCS     $D722               ; Yes ... we have it decoded ... print it
D71C: 80 06           SUBA    #$06                ; Skip 6 symbols between upper and lower case
D71E: 81 3E           CMPA    #$3E                ; Is this a lower case letter?
D720: 24 D1           BCC     $D6F3               ; No ... we don't know this one ... out
;
D722: 34 10           PSHS    X                   ; Hold the pointer into the message
D724: BD D6 79        JSR     PrintChar           ; Print the character
D727: 35 10           PULS    X                   ; Restore pointer into the message
D729: 96 AC           LDA     <PixCoords+1        ; get the X coordinate
D72B: 8B 06           ADDA    #$06                ; Next character goes 6 pixels over
D72D: 97 AC           STA     <PixCoords+1        ; coordinate for next character
D72F: 0D AE           TST     <ChangeColor        ; auto color?
D731: 27 C9           BEQ     $D6FC               ; No ... just print it
D733: 96 AD           LDA     <ColorMask          ; Current color
D735: 8B 55           ADDA    #$55                ; Cycle among 55, AA, FF
D737: 24 02           BCC     $D73B               ; Didn't overflow ... keep this color
D739: 86 55           LDA     #$55                ; Restart at color 55
D73B: 97 AD           STA     <ColorMask          ; New color mask
D73D: 20 BD           BRA     $D6FC               ; Do the print

Audio

Play music

; Play dual notes (splash music)
PlayTwoNotes:
D73F: 34 01           PSHS    CC                  ; Hold interrupt status
D741: 1A 50           ORCC    #$50                ; Turn interrupts off (sound timing loop)
D743: EC C4           LDD     ,U                  ; Duration
D745: 44              LSRA                        ; Divide by 2 ...
D746: 56              RORB                        ; ...
D747: 44              LSRA                        ; ... 4 ...
D748: 56              RORB                        ; ...
D749: 44              LSRA                        ; ... 8 ...
D74A: 56              RORB                        ;
D74B: 34 06           PSHS    B,A                 ; Duration/8 to stack
D74D: EC C1           LDD     ,U++                ; Duration again (advance U)
D74F: A3 E1           SUBD    ,S++                ;
D751: 1F 01           TFR     D,X                 ; Duration to X
D753: EC C1           LDD     ,U++                ; Note 1 (advance U)
D755: DD 80           STD     <Note1              ; 
D757: EC C1           LDD     ,U++                ; Note 2 (advance U)
D759: DD 82           STD     <Note2              ; 
D75B: 6F E4           CLR     ,S                  ; Sound ...
D75D: DC 86           LDD     <NoteC2             ; ...
D75F: D3 82           ADDD    <Note2              ; ...
D761: DD 86           STD     <NoteC2             ; ...
D763: 66 E4           ROR     ,S                  ; ...
D765: DC 84           LDD     <NoteC1             ; ...
D767: D3 80           ADDD    <Note1              ; ...
D769: DD 84           STD     <NoteC1             ; ...
D76B: A6 E4           LDA     ,S                  ; ...
D76D: 46              RORA                        ; ...
D76E: 44              LSRA                        ; ...
D76F: 44              LSRA                        ; ... magic
D770: B8 FF 20        EORA    PIA1_DA             ; 6-bit ...
D773: B7 FF 20        STA     PIA1_DA             ; ... sound
D776: 30 1F           LEAX    -1,X                ; Note finished?
D778: 26 E1           BNE     $D75B               ; No ... keep playing
;
D77A: 35 81           PULS    CC,PC               ; Restore interrupts and out

Play "We Gotcha!"

PlayWeGotcha:         
D77C: 34 01           PSHS    CC                  ; Preserve interrupt status
D77E: 1A 50           ORCC    #$50                ; Disable interrupts
D780: CE C0 03        LDU     #WeGotchaSamples    ; Audio sample table for "we gotcha"
D783: 8E 09 5D        LDX     #$095D              ; 2397 samples
D786: 86 02           LDA     #$02                ; 6-bit ...
D788: B7 FF 20        STA     PIA1_DA             ; ... sound off
D78B: A6 C0           LDA     ,U+                 ; Get next on/off time
D78D: 27 08           BEQ     $D797               ; Pure delay - don't advance the sound waveform
D78F: F6 FF 20        LDB     PIA1_DA             ; Toggle ...
D792: C8 F0           EORB    #$F0                ; ... upper 4 bits ...
D794: F7 FF 20        STB     PIA1_DA             ; ... of 6-bit sound
D797: 21 FE           BRN     $D797               ; Branch-never - for timing
D799: 4A              DECA                        ; Time the delay ...
D79A: 26 FB           BNE     $D797               ; ... down to zero
D79C: 30 1F           LEAX    -1,X                ; All samples played?
D79E: 26 EB           BNE     $D78B               ; No ... go do them all
D7A0: 86 02           LDA     #$02                ; 6-bit ...
D7A2: B7 FF 20        STA     PIA1_DA             ; ... sound off
D7A5: 35 81           PULS    CC,PC               ; Restore interrupts and out

Play "gotcha" tone

PlayGotchaTone:
D7A7: 86 01           LDA     #$01                ; Sound ...
D7A9: 97 A5           STA     <HorzDoubler        ; ... magic
D7AB: 34 01           PSHS    CC                  ; Hold interrupt bit
D7AD: 1A 50           ORCC    #$50                ; Disable interrupts
D7AF: C6 02           LDB     #$02                ; Sound ...
D7B1: 96 A5           LDA     <HorzDoubler        ; ...
D7B3: 4A              DECA                        ; ...
D7B4: 12              NOP                         ; ...
D7B5: 26 FC           BNE     $D7B3               ; ...
D7B7: 86 C2           LDA     #$C2                ; ...
D7B9: B7 FF 20        STA     PIA1_DA             ; ...
D7BC: 96 A5           LDA     <HorzDoubler        ; ...
D7BE: 40              NEGA                        ; ...
D7BF: 4A              DECA                        ; ...
D7C0: 12              NOP                         ; ...
D7C1: 26 FC           BNE     $D7BF               ; ...
D7C3: 86 02           LDA     #$02                ; ...
D7C5: B7 FF 20        STA     PIA1_DA             ; ...
D7C8: 5A              DECB                        ; ...
D7C9: 26 E6           BNE     $D7B1               ; ...
D7CB: 0C A5           INC     <HorzDoubler        ; ...
D7CD: 26 E0           BNE     $D7AF               ; ... magic
D7CF: 8E 40 00        LDX     #$4000              ; Long ...
D7D2: 30 1F           LEAX    -1,X                ; ... delay ...
D7D4: 26 FC           BNE     $D7D2               ; ... loop
D7D6: 35 81           PULS    CC,PC               ; Restore interrupts and out

Draw mouth

A1 is 0 for open or 1 for closed mouth.

DrawMouth:
D7D8: DC A2           LDD     <PlayerCoords       ; Get the player's coordinates
D7DA: 80 02           SUBA    #$02                ; From center pixel ...
D7DC: C0 02           SUBB    #$02                ; ... to upper left corner
D7DE: BD DE 59        JSR     CoordToScrOffs9A    ; Draw pointer
D7E1: 33 84           LEAU    ,X                  ; Keep it in U
D7E3: D7 88           STB     <BitPos             ; Keep the bit position
D7E5: 10 8E C9 60     LDY     #PlayerGraphics     ; Mouth graphics
D7E9: D6 A4           LDB     <PlayerDir          ; Player's direction
D7EB: 86 06           LDA     #$06                ; 6 bytes per ...
D7ED: 3D              MUL                         ; ... direction
D7EE: 0D A1           TST     <MouthOpen          ; Odd/even counter for mouth
D7F0: 2A 02           BPL     $D7F4               ; Yes ... keep this open mouth image
D7F2: CB 18           ADDB    #$18                ; No ... use the ...
D7F4: 31 A5           LEAY    B,Y                 ; ... closed-mouth image
D7F6: 86 06           LDA     #$06                ; 6 columns ...
D7F8: 97 99           STA     <Temp3              ; ... to draw
D7FA: A6 A0           LDA     ,Y+                 ; Get the next row of graphics data
D7FC: 34 40           PSHS    U                   ; Hold the draw pointer
D7FE: 4D              TSTA                        ; Check the next graphics bit
D7FF: 2A 06           BPL     $D807               ; Not set ... skip drawing it
D801: E6 C4           LDB     ,U                  ; From the screen
D803: DA 88           ORB     <BitPos             ; Set the bit
D805: E7 C4           STB     ,U                  ; Back to the screen
D807: 33 C8 20        LEAU    $20,U               ; Next row on screen
D80A: 48              LSLA                        ; Next bit in graphics
D80B: 26 F2           BNE     $D7FF               ; Go back for all pixels in this graphics
D80D: 35 40           PULS    U                   ; Restore the draw pointer to the top of the picture
D80F: 96 88           LDA     <BitPos             ; Advance ...
D811: 44              LSRA                        ; ... the ...
D812: 44              LSRA                        ; ... pixel position
D813: 26 04           BNE     $D819               ; Still good ... use it
D815: 86 C0           LDA     #$C0                ; Reset to first bit position ...
D817: 33 41           LEAU    1,U                 ; ... in next byte to the right
D819: 97 88           STA     <BitPos             ; New bit position
D81B: 0A 99           DEC     <Temp3              ; All columns done?
D81D: 26 DB           BNE     $D7FA               ; No ... do them all
D81F: 39              RTS                         ; Out

Draw bugs (magnified)

DrawBugs:
D820: 10 8E 28 08     LDY     #$2808              ; Bugs data structure
D824: 96 A0           LDA     <NumBugs            ; Counter for ...
D826: 97 98           STA     <Temp2              ; ... number of bugs
D828: EC A4           LDD     ,Y                  ; Get the bug's coordinates
D82A: 90 A2           SUBA    <PlayerCoords       ; Compare to player's Y
D82C: 2A 01           BPL     $D82F               ; Absolute ...
D82E: 40              NEGA                        ; ... value
D82F: 81 0B           CMPA    #$0B                ; 13 or less (visible in the magnifier) ?
D831: 24 0B           BCC     $D83E               ; No ... this bug isn't visible
D833: D0 A3           SUBB    <PlayerCoords+1     ; Compare to player's X
D835: 2A 01           BPL     $D838               ; Absolute ...
D837: 50              NEGB                        ; ... value
D838: C1 0B           CMPB    #$0B                ; 13 or less (visible in the magnifier) ?
D83A: 24 02           BCC     $D83E               ; No ... this bug isn't visible
D83C: 8D 07           BSR     DrawOneBug          ; This bug is visible ... draw it
D83E: 31 23           LEAY    3,Y                 ; Next bug structure
D840: 0A 98           DEC     <Temp2              ; Do ...
D842: 26 E4           BNE     $D828               ; ... all bugs
D844: 39              RTS                         ; Out

DrawOneBug:
D845: 34 20           PSHS    Y                   ; Hold pointer to data structure
D847: EC A4           LDD     ,Y                  ; Get the bug's coordinates
D849: 90 A2           SUBA    <PlayerCoords       ; (Yb - Yp)*2 + Yp
D84B: D0 A3           SUBB    <PlayerCoords+1     ; (Xb - Xp)*2 + Xp
D84D: 48              LSLA                        ; ...
D84E: 58              LSLB                        ; ...
D84F: 9B A2           ADDA    <PlayerCoords       ; ...
D851: DB A3           ADDB    <PlayerCoords+1     ; ...
D853: C0 02           SUBB    #$02                ; Offset from center of bug ...
D855: 80 02           SUBA    #$02                ; ... to upper left
D857: DD 8E           STD     <Temp1              ; Hold these pixel coordinates
D859: A6 22           LDA     2,Y                 ; Get the bug's direction
D85B: 84 01           ANDA    #$01                ; 1=up/down, 0=left/right
D85D: 88 01           EORA    #$01                ; Reverse that: 1=left/right, 0=up/down
D85F: C6 48           LDB     #$48                ; Each set of pictures is 18 bytes * 4 pictures = $48
D861: 3D              MUL                         ; D points to the left/right or up/down pictures
D862: 0D A1           TST     <MouthOpen          ; First or second position?
D864: 27 03           BEQ     $D869               ; First ... use the pointer we have
D866: C3 00 90        ADDD    #$0090              ; Offset to the next set of pictures
D869: CE C9 90        LDU     #BugGraphics        ; Pointer to graphics
D86C: 33 CB           LEAU    D,U                 ; Point to the correct set of pictures (same pic, 4 shifts)
D86E: 86 12           LDA     #$12                ; 18 bytes per picture
D870: D6 8F           LDB     <Temp1+1            ; X coordinate
D872: C4 03           ANDB    #$03                ; 4 shifts and 4 pixels per byte
D874: 3D              MUL                         ; Offset to ...
D875: 33 C5           LEAU    B,U                 ; ... target shifted picture
D877: DC 8E           LDD     <Temp1              ; Bug coordinates
D879: BD DE 59        JSR     CoordToScrOffs9A    ; Get screen pointer
D87C: 86 03           LDA     #$03                ; 3 columns ...
D87E: 97 99           STA     <Temp3              ; ... in the bug
D880: D6 8F           LDB     <Temp1+1            ; X coordinate
D882: 54              LSRB                        ; Divide by ...
D883: 54              LSRB                        ; ... 4 (4 pixels per byte)
D884: C4 1F           ANDB    #$1F                ; Now we have a screen column number
D886: 10 8E 28 C8     LDY     #$28C8              ; Column-has-content flags
D88A: 31 A5           LEAY    B,Y                 ; The draw-magnifier ...
D88C: A6 A4           LDA     ,Y                  ; ... made a note if this column has magnified data
D88E: 27 1E           BEQ     $D8AE               ; No data ... skip this column
D890: 34 50           PSHS    U,X                 ; Hold these while we draw
D892: C6 06           LDB     #$06                ; 6 rows
D894: 9C A9           CMPX    <MagnifierEnd       ; The end of the magnifier
D896: 24 0C           BCC     $D8A4               ; Not in the magnifier ... skip
D898: 9C A7           CMPX    <MagnifierStart     ; The beginning of the magnifier
D89A: 25 08           BCS     $D8A4               ; Not in the magnifier ... skip
D89C: A6 C4           LDA     ,U                  ; Get the bug graphics
D89E: A4 A4           ANDA    ,Y                  ; Color the graphics
D8A0: AA 84           ORA     ,X                  ; Add in existing pixels from the screen
D8A2: A7 84           STA     ,X                  ; And back to the screen
D8A4: 33 41           LEAU    1,U                 ; Next graphics byte
D8A6: 30 88 20        LEAX    $20,X               ; Next row
D8A9: 5A              DECB                        ; All 6 rows done?
D8AA: 26 E8           BNE     $D894               ; No ... go do them all
D8AC: 35 50           PULS    X,U                 ; Restore top of bug and graphics
D8AE: 30 01           LEAX    1,X                 ; 1 byte over on the screen
D8B0: 33 46           LEAU    6,U                 ; 6 bytes over in the graphics to the next column
D8B2: 31 21           LEAY    1,Y                 ; Next column-has-content flag
D8B4: 0A 99           DEC     <Temp3              ; All 3 columns of the bug done?
D8B6: 26 D4           BNE     $D88C               ; Do all 3 columns (3*6 = 18 bytes)
D8B8: 35 A0           PULS    Y,PC                ; Out

Read directional input

Keyboard or joystick -- depending on how the user started the game.

If B comes in as 1 or 3, then this routine looks for left/right. Otherwise this routine looks for up/down. This matches the direction bits.

Returns direction in B: 0=Up,1=Left,2=Down,3=Right. Upper bit set if nothing selected.

UserDirInput:
D8BA: 96 C2           LDA     <JoyOrKey           ; Using joystick or keyboard
D8BC: 26 28           BNE     $D8E6               ; joystick ... skip to that
;
; Read keyboard
;
D8BE: 86 F7           LDA     #$F7                ; Column 4 (Up arrow)
D8C0: C4 01           ANDB    #$01                ; 1 means up/down, 0 means left/right
D8C2: D7 A5           STB     <HorzDoubler        ; hold onto this
D8C4: 27 02           BEQ     $D8C8               ; B==0 ... up/down requested
D8C6: 86 DF           LDA     #$DF                ; Column 5 (Left arrow)
D8C8: B7 FF 02        STA     PIA0_DB             ; First column on
D8CB: 5F              CLRB                        ; Value added to <$A5 for UP/LEFT
D8CC: B6 FF 00        LDA     PIA0_DA             ; Read the arrow row
D8CF: 84 08           ANDA    #$08                ; Arrow pressed?
D8D1: 27 10           BEQ     $D8E3               ; Yes ... record and out
D8D3: 1A 01           ORCC    #$01                ; Shifting in a 1 to upper column
D8D5: 79 FF 02        ROL     PIA0_DB             ; Try the next column to the right
D8D8: C6 02           LDB     #$02                ; Value added to <$A5 for DOWN/RIGHT
D8DA: B6 FF 00        LDA     PIA0_DA             ; Read the arrow row
D8DD: 84 08           ANDA    #$08                ; Arrow pressed?
D8DF: 27 02           BEQ     $D8E3               ; Yes ... record and out
D8E1: C6 80           LDB     #$80                ; Upper bit set means nothing pressed
D8E3: DB A5           ADDB    <HorzDoubler        ; Result in B
D8E5: 39              RTS                         ; Done
;
; Read joystick
;
D8E6: B6 FF 23        LDA     PIA1_CB             ; Hold onto value ...
D8E9: 34 02           PSHS    A                   ; ... we need to change it to find the joystick values
D8EB: 84 F7           ANDA    #$F7                ; Disable ...
D8ED: B7 FF 23        STA     PIA1_CB             ; ... sound
D8F0: B6 FF 20        LDA     PIA1_DA             ; Hold current ...
D8F3: 34 02           PSHS    A                   ; Sound value
D8F5: C4 01           ANDB    #$01                ; 1=Left/Right, 0=Up/Down
D8F7: D7 A5           STB     <HorzDoubler        ; Hold onto requested direction
D8F9: C8 01           EORB    #$01                ; FE=Left/Right, FF=Up/Down
D8FB: 58              LSLB                        ; Direction ...
D8FC: 58              LSLB                        ; ... to ...
D8FD: 58              LSLB                        ; ... SEL 1 (LSB of two analog MUX select lines)
D8FE: 34 04           PSHS    B                   ; For easy math
D900: F6 FF 01        LDB     PIA0_CA             ; Get the current MUX value
D903: C4 F7           ANDB    #$F7                ; Set to 0 ...
D905: EA E0           ORB     ,S+                 ; ... and then to 1 or 0 based on direction
D907: F7 FF 01        STB     PIA0_CA             ; Activate the right analog axis
D90A: 5F              CLRB                        ; Value added to <$A5 for UP/LEFT
D90B: 86 22           LDA     #$22                ; Low output analog ...
D90D: B7 FF 20        STA     PIA1_DA             ; ... threshold value
D910: 7D FF 00        TST     PIA0_DA             ; Axis under the threshold?
D913: 2A 0E           BPL     $D923               ; Yes ... keep UP/LEFT
D915: 86 DF           LDA     #$DF                ; High output analog ...
D917: B7 FF 20        STA     PIA1_DA             ; ... threshold value
D91A: C6 02           LDB     #$02                ; Value added to <$A5 for DOWN/RIGHT
D91C: 7D FF 00        TST     PIA0_DA             ; Axis over the threshold?
D91F: 2B 02           BMI     $D923               ; Yes ... keep DOWN/RIGHT
D921: C6 80           LDB     #$80                ; Upper bit means nothing selected
;
D923: 86 34           LDA     #$34                ; Put FF01 to ...
D925: B7 FF 01        STA     PIA0_CA             ; ... 0 for SEL 1
D928: 35 02           PULS    A                   ; Restore ...
D92A: B7 FF 20        STA     PIA1_DA             ; ... sound value
D92D: 35 02           PULS    A                   ; Re-enable ...
D92F: B7 FF 23        STA     PIA1_CB             ; ... sound
D932: DB A5           ADDB    <HorzDoubler        ; Result in B
D934: 39              RTS                         ; Done

Move the player

MovePlayer:                     
D935: 0D B5           TST     <LiveOrDemo         ; Is this a demo game?
D937: 10 27 00 AA     LBEQ    DemoMoves           ; Yes ... move at random
D93B: DC A2           LDD     <PlayerCoords       ; Get the player coordinates
D93D: BD DA 24        JSR     CheckAlignOddEven   ; Might be over a dot that needs changing?
D940: 24 0C           BCC     $D94E               ; No ... skip it
;
; This changes the dot to a trail, but this code is only for the live game. And it isn't
; needed since the code at the bottom (common to live and demo) draws the trail too.
;
D942: DC A2           LDD     <PlayerCoords       ; Our coordinates
D944: BD DE 5C        JSR     CoordToScrOffs400   ; Offset from top of first screen
D947: C4 55           ANDB    #$55                ; Change ...
D949: 53              COMB                        ; ... any ...
D94A: E4 84           ANDB    ,X                  ; ... dot ...
D94C: E7 84           STB     ,X                  ; ... to trail
;
D94E: DC A2           LDD     <PlayerCoords       ; Player's coordinate
D950: BD DA 12        JSR     CheckWallAlign      ; Are we between cells?
D953: 24 1D           BCC     $D972               ; Yes ... skip orthogonal change (can still reverse)
D955: D6 A4           LDB     <PlayerDir          ; Player's current direction
D957: C8 01           EORB    #$01                ; Check for changing ...
D959: BD D8 BA        JSR     UserDirInput        ; ... orthogonally
D95C: 2B 14           BMI     $D972               ; Nothing requested ... look for reversing
D95E: D7 A5           STB     <HorzDoubler        ; This is the requested direction
D960: DC A2           LDD     <PlayerCoords       ; Player coordinates
D962: BD DE 5C        JSR     CoordToScrOffs400   ; Pointer to source maze
D965: 96 A5           LDA     <HorzDoubler        ; Requested direction
D967: BD DF 42        JSR     CheckForWall        ; Check for a wall in that direction
D96A: 25 06           BCS     $D972               ; There is a wall ... we can't go that way
D96C: 96 A5           LDA     <HorzDoubler        ; No wall ... this is ...
D96E: 97 A4           STA     <PlayerDir          ; ... the new direction
D970: 20 09           BRA     $D97B               ; Continue
;
D972: D6 A4           LDB     <PlayerDir          ; Current direction
D974: BD D8 BA        JSR     UserDirInput        ; Maybe reversing?
D977: 2B 02           BMI     $D97B               ; No ... move on
D979: D7 A4           STB     <PlayerDir          ; Yes ... either same direction or reversing
;
; Common to live/demo
D97B: DC A2           LDD     <PlayerCoords       ; Player's coordinates
D97D: BD DA 12        JSR     CheckWallAlign      ; Are we between cells?
D980: 24 0C           BCC     $D98E               ; Yes ... we know we can move forward
D982: DC A2           LDD     <PlayerCoords       ; Players coordinate
D984: BD DE 5C        JSR     CoordToScrOffs400   ; Pointer to source maze
D987: 96 A4           LDA     <PlayerDir          ; Is there a wall ...
D989: BD DF 42        JSR     CheckForWall        ; ... in our current direction?
D98C: 25 0F           BCS     $D99D               ; Yes ... no more moving in that direction
D98E: 8E DE 4F        LDX     #DirOffset          ; Get ...
D991: D6 A4           LDB     <PlayerDir          ; ... coordinate ...
D993: 58              LSLB                        ; ... offsets for ...
D994: 3A              ABX                         ; ... current direction
D995: DC A2           LDD     <PlayerCoords       ; Move ...
D997: AB 84           ADDA    ,X                  ; ... the ...
D999: EB 01           ADDB    1,X                 ; ... player
D99B: DD A2           STD     <PlayerCoords       ; New corrdiantes
;
D99D: DC A2           LDD     <PlayerCoords       ; Player coordinates
D99F: BD DA 24        JSR     CheckAlignOddEven   ; Could we be over a dot?
D9A2: 24 40           BCC     $D9E4               ; No ... no need to check
D9A4: DC A2           LDD     <PlayerCoords       ; Pointer to ...
D9A6: BD DE 5C        JSR     CoordToScrOffs400   ; ... maze source
D9A9: E7 E2           STB     ,-S                 ; Bit position to the stack
D9AB: A6 84           LDA     ,X                  ; Is the ...
D9AD: A8 E4           EORA    ,S                  ; ... player over ...
D9AF: A4 E0           ANDA    ,S+                 ; ... a dot?
D9B1: 26 24           BNE     $D9D7               ; Not a dot ... skip sound
;
D9B3: 86 03           LDA     #$03                ; Make eat-a-dot-sound ...
D9B5: 97 BA           STA     <MakeEatSound       ; ... next time we draw the magnifier
D9B7: 96 B5           LDA     <LiveOrDemo         ; Is this a demo game?
D9B9: 27 1C           BEQ     $D9D7               ; Yes ... skip adjusting the score
D9BB: 96 B2           LDA     <Score+1            ; 10 points ...
D9BD: 8B 10           ADDA    #$10                ; ... for ...
D9BF: 19              DAA                         ; ... eating ...
D9C0: 97 B2           STA     <Score+1            ; ... a dot
D9C2: 96 B1           LDA     <Score              ; Carry ...
D9C4: 89 00           ADCA    #$00                ; ... into ...
D9C6: 19              DAA                         ; ... upper ...
D9C7: 97 B1           STA     <Score              ; ... byte
D9C9: 86 02           LDA     #$02                ; Draw the score ...
D9CB: 97 B8           STA     <DrawScore          ; ... two times (two screen buffers)
D9CD: 0F B6           CLR     <ISRCountScore      ; Flag to update the score
D9CF: DE BE           LDU     <DotsLeft           ; Current count of dots eaten
D9D1: 27 04           BEQ     $D9D7               ; Why would this ever be 0? We stop the game when it reaches 0
D9D3: 33 5F           LEAU    -1,U                ; Player just ate ...
D9D5: DF BE           STU     <DotsLeft           ; ... a dot
;
D9D7: 1F 98           TFR     B,A                 ; Bit position
D9D9: 53              COMB                        ; Leave ...
D9DA: E4 84           ANDB    ,X                  ; ...
D9DC: 34 04           PSHS    B                   ; ... a ...
D9DE: 84 AA           ANDA    #$AA                ; ...
D9E0: AA E0           ORA     ,S+                 ; ... trail ...
D9E2: A7 84           STA     ,X                  ; ... behind
D9E4: 39              RTS                         ; Done
 
DemoMoves:
D9E5: D6 A4           LDB     <PlayerDir          ; Get the player's direction
D9E7: 58              LSLB                        ; 2 offset bytes per direction
D9E8: 8E DE 4F        LDX     #DirOffset          ; Point to ...
D9EB: 3A              ABX                         ; ... the offsets for current direction
D9EC: DC A2           LDD     <PlayerCoords       ; Add player's ...
D9EE: AB 84           ADDA    ,X                  ; ... coordinates to ...
D9F0: EB 01           ADDB    1,X                 ; ... the offset
D9F2: DD 8E           STD     <Temp1              ; This is where we go
D9F4: BD DF CC        JSR     CheckCollision      ; Did we run into a bug?
D9F7: 24 08           BCC     $DA01               ; No ... keep going
D9F9: 96 A4           LDA     <PlayerDir          ; Turn the ...
D9FB: 88 02           EORA    #$02                ; ... player ...
D9FD: 97 A4           STA     <PlayerDir          ; ... around 180 degrees
D9FF: 20 0E           BRA     $DA0F               ; And keep going
;
DA01: DC A2           LDD     <PlayerCoords       ; Player coordinates
DA03: BD DA 12        JSR     CheckWallAlign      ; Did the player hit a wall?
DA06: 24 07           BCC     $DA0F               ; No ... keep going in that direction
DA08: 10 8E 00 A2     LDY     #$00A2              ; Point to player coordinates
DA0C: BD DE FD        JSR     $DEFD               ; Make a random turn
DA0F: 7E D9 7B        JMP     $D97B               ; Common demo/live code

CheckWallAlign:
; Return Carry=1 if object is aligned to where a wall might be
DA12: 80 11           SUBA    #$11                ; Offset Y to top of maze
DA14: 84 03           ANDA    #$03                ; Y coordinate aligned?
DA16: 26 09           BNE     $DA21               ; No ... return not-aligned
DA18: C0 19           SUBB    #$19                ; Offset X from left of maze
DA1A: C4 03           ANDB    #$03                ; X coordinate aligned?
DA1C: 26 03           BNE     $DA21               ; No ... return not-aligned
;
DA1E: 1A 01           ORCC    #$01                ; X and Y are aligned to the edge of the cell
DA20: 39              RTS                         ; Done
;
DA21: 1C FE           ANDCC   #$FE                ; Object is not aligned to the edge of the cell
DA23: 39              RTS                         ; Done

CheckAlignOddEven:
; Return Carry=1 for "even" and Carry=0 for odd
DA24: 80 11           SUBA    #$11                ; Offset Y to top of maze
DA26: 84 01           ANDA    #$01                ; Is this an "odd" position?
DA28: 26 F7           BNE     $DA21               ; Yes ... return Carry=0
DA2A: C0 19           SUBB    #$19                ; Offset X to left of maze
DA2C: C4 01           ANDB    #$01                ; Is this an "odd" position?
DA2E: 26 F1           BNE     $DA21               ; Yes ... return Carry=0
;
DA30: 1A 01           ORCC    #$01                ; This is an "even" position. Carry =1
DA32: 39              RTS                         ; Done

Draw Magnifier

Draw the magnified area of the screen and make the eat-dot sound if requested.

DrawMagnifier:
DA33: 8E 28 C8        LDX     #$28C8              ; Clear ...
DA36: C6 20           LDB     #$20                ; ... the ...
DA38: 6F 80           CLR     ,X+                 ; ... 32 column ...
DA3A: 5A              DECB                        ; ... has content ...
DA3B: 26 FB           BNE     $DA38               ; ... flags
;
DA3D: 6F 8D 26 7B     CLR     EatSnd2,PC          ; Sound magic
DA41: 86 02           LDA     #$02                ; Sound level ...
DA43: B7 FF 20        STA     PIA1_DA             ; ... off
DA46: DC A2           LDD     <PlayerCoords       ; Get the player's coordinates
DA48: 80 11           SUBA    #$11                ; Back up to ...
DA4A: C0 11           SUBB    #$11                ; ... upper left corner
DA4C: BD DE 59        JSR     CoordToScrOffs9A    ; Get the screen pointer/bit-pos
DA4F: 33 84           LEAU    ,X                  ; Memory pointer to U
DA51: D7 88           STB     <BitPos             ; Bit position to 88
DA53: BD DB 10        JSR     MagVertLine         ; Draw the left side of the magnifier
DA56: 33 88 20        LEAU    $20,X               ; Remember where ...
DA59: DF A7           STU     <MagnifierStart     ; ... the magnifier starts
DA5B: 33 84           LEAU    ,X                  ; Back to the top of the magnifier
DA5D: 04 88           LSR     <BitPos             ; Shift over ...
DA5F: 04 88           LSR     <BitPos             ; ... one pixel
DA61: 26 06           BNE     $DA69               ; We didn't overflow ... keep it
DA63: 33 41           LEAU    1,U                 ; We overflowed ...
DA65: C6 C0           LDB     #$C0                ; ... start over with the first pixel next byte
DA67: D7 88           STB     <BitPos             ; New pixel position
DA69: 86 22           LDA     #$22                ; 34 pixels in horizontal line (we already have 2 on the edges)
DA6B: 97 99           STA     <Temp3              ; Keep the pixel counter
DA6D: 0F BD           CLR     <EatSnd3            ; Sound magic
DA6F: 0F A5           CLR     <HorzDoubler        ; Clear the doubler flag
DA71: DC A2           LDD     <PlayerCoords       ; Player's coordiante
DA73: 83 08 08        SUBD    #$0808              ; 8 cells left, 8 cells up -- that's where the magnifier starts
DA76: BD DE 5C        JSR     CoordToScrOffs400   ; Get the pointer to the screen and the bit mask
DA79: 31 84           LEAY    ,X                  ; Y now points to source maze
DA7B: D7 89           STB     <BitPosSrc          ; Bit position on the source maze

DA7D: 8E 28 C8        LDX     #$28C8              ; Column-has-content flags
DA80: 1F 30           TFR     U,D                 ; Screen pointer to D for math
DA82: C4 1F           ANDB    #$1F                ; Just the column number
DA84: 30 85           LEAX    B,X                 ; Offset to the first column-has-content flag

DA86: 86 11           LDA     #$11                ; 17 rows (doubles to 34)
DA88: 97 98           STA     <Temp2              ; Row counter
DA8A: 34 70           PSHS    U,Y,X               ; Hold these for next pass
DA8C: 96 88           LDA     <BitPos             ; Bit position
DA8E: AA C4           ORA     ,U                  ; Top of the ...
DA90: A7 C4           STA     ,U                  ; ... magnifier is solid
DA92: 33 C8 20        LEAU    $20,U               ; Next row down

DA95: 96 88           LDA     <BitPos             ; Bit position
DA97: AA 84           ORA     ,X                  ; Mark this screen column ...
DA99: A7 84           STA     ,X                  ; ... as having content (a bug can now be drawn in this column)

DA9B: 96 BA           LDA     <MakeEatSound       ; Make the eat-dot sound?
DA9D: 27 0A           BEQ     $DAA9               ; No ... skip the sound change
DA9F: 96 BD           LDA     <EatSnd3            ; Do ...
DAA1: 88 40           EORA    #$40                ; ... the ...
DAA3: 97 BD           STA     <EatSnd3            ; ... sound ...
DAA5: 8B 40           ADDA    #$40                ; ...  ...
DAA7: 97 BC           STA     <EatSnd2            ; ... magic
;
DAA9: 8E DB 5C        LDX     #PixelColorDouble   ; Pixel color mask lookup table (fast)
DAAC: 4F              CLRA                        ; MSB of offset is 0
DAAD: D6 89           LDB     <BitPosSrc          ; Take the bit position from the source screen ...
DAAF: E4 A4           ANDB    ,Y                  ; ... and get the isolated pixel value (aa_bb_cc_dd)
DAB1: A6 8B           LDA     D,X                 ; Look that value up in the sparse table to get a color mask
;
DAB3: 94 88           ANDA    <BitPos             ; That's the color of the magnified bit
DAB5: 34 02           PSHS    A                   ; Put the value on the stack for easy access
DAB7: 96 88           LDA     <BitPos             ; Current bit position
DAB9: 43              COMA                        ; Now a mask
DABA: A4 C4           ANDA    ,U                  ; Erase pixel coming from screen
DABC: AA E4           ORA     ,S                  ; Add in our new pixel
DABE: A7 C4           STA     ,U                  ; Update the screen
DAC0: 96 88           LDA     <BitPos             ; Current bit position again
DAC2: 43              COMA                        ; Now a mask
DAC3: A4 C8 20        ANDA    $20,U               ; Erase pixel coming from screen (next row down)
DAC6: AA E0           ORA     ,S+                 ; Add in our new pixel
DAC8: A7 C8 20        STA     $20,U               ; Update the screen (next row down)
DACB: 33 C8 40        LEAU    $40,U               ; Advance the screen 2 rows (we are doubling)
DACE: 96 BB           LDA     <EatSnd1            ; Do the ...
DAD0: 9B BC           ADDA    <EatSnd2            ; ... sound ...
DAD2: 97 BB           STA     <EatSnd1            ; ... magic
DAD4: 24 09           BCC     $DADF               ; Skip sound (there are two beeps played when a dot is eaten)
;
DAD6: 86 40           LDA     #$40                ; Toggle ...
DAD8: A8 8D 24 44     EORA    PIA1_DA,PC          ; ... sound ...
DADC: B7 FF 20        STA     PIA1_DA             ; ... value
;
DADF: 31 A8 20        LEAY    $20,Y               ; Next row in the source maze
DAE2: 0A 98           DEC     <Temp2              ; All rows done?
DAE4: 26 C6           BNE     $DAAC               ; No ... do all 34 rows
DAE6: DF A9           STU     <MagnifierEnd       ; Remember the bottom of the magnifier
DAE8: D6 88           LDB     <BitPos             ; Magnifier ...
DAEA: EA C4           ORB     ,U                  ; ... bottom edge ...
DAEC: E7 C4           STB     ,U                  ; ... is solid
DAEE: DC 88           LDD     <BitPos             ; Bit positions
DAF0: 35 70           PULS    X,Y,U               ; Restore
DAF2: 03 A5           COM     <HorzDoubler        ; Only advance the source ...
DAF4: 26 08           BNE     $DAFE               ; ... every other pass (we are doubling)
DAF6: 54              LSRB                        ; Next pixel ...
DAF7: 54              LSRB                        ; ... from the source maze
DAF8: 26 04           BNE     $DAFE               ; Hasn't overflowed ... keep it
DAFA: 31 21           LEAY    1,Y                 ; It did overflow ... next byte over and ...
DAFC: C6 C0           LDB     #$C0                ; ... first pixel
DAFE: 44              LSRA                        ; Next bit position ...
DAFF: 44              LSRA                        ; ... on the screen
DB00: 26 06           BNE     $DB08               ; Hasn't overflowed ... keep it
DB02: 86 C0           LDA     #$C0                ; It did overflow ... first pixel and ...
DB04: 33 41           LEAU    1,U                 ; Next byte over
DB06: 30 01           LEAX    1,X                 ; Advance our mystery table pointer (table is never read)
DB08: DD 88           STD     <BitPos             ; New bit position (source and destination)
DB0A: 0A 99           DEC     <Temp3              ; Do all ...
DB0C: 10 26 FF 76     LBNE    $DA86               ; ... the columns
 
;Vertical line of 36 pixels
MagVertLine: 
DB10: C6 24           LDB     #$24                ; 36 pixels down the screen for the magnifier
DB12: 96 88           LDA     <BitPos             ; Bit position for the line
DB14: AA C4           ORA     ,U                  ; Set the bit ...
DB16: A7 C4           STA     ,U                  ; ... on the screen
DB18: 33 C8 20        LEAU    $20,U               ; Next row down
DB1B: 5A              DECB                        ; All 36 rows done?
DB1C: 26 F4           BNE     $DB12               ; No ... keep doing them all
DB1E: 39              RTS                         ; Out

Erase magnifier

This code copies the maze from the source screen buffer over the magnifier to erase it back to ground state on the current drawing buffer.

EraseMagnifier:
DB1F: EC 8D 25 7F     LDD     PlayerCoords,PC     ; Player coordinates
DB23: 80 12           SUBA    #$12                ; Top of magnifier
DB25: 2A 01           BPL     $DB28               ; Limit to the ...
DB27: 4F              CLRA                        ; ... top of the screen
DB28: C0 16           SUBB    #$16                ; Left of magnifier
DB2A: 34 06           PSHS    B,A                 ; Hold upper left X,Y
DB2C: BD DE 59        JSR     CoordToScrOffs9A    ; Get a screen offset ...
DB2F: 1F 13           TFR     X,U                 ; ... to U (where we are erasing)
DB31: 35 06           PULS    A,B                 ; Pull the coordinates
DB33: 97 A5           STA     <HorzDoubler        ; Keep Y coordinate here
DB35: BD DE 5C        JSR     CoordToScrOffs400   ; Pointer to pure maze (source of erase)
DB38: 86 26           LDA     #$26                ; 38 rows
DB3A: 97 99           STA     <Temp3              ; Counter here
DB3C: 9B A5           ADDA    <HorzDoubler        ; This is how far we'll go in Y
DB3E: 81 60           CMPA    #$60                ; Past the end of the screen?
DB40: 25 06           BCS     $DB48               ; No ... keep it
DB42: 86 60           LDA     #$60                ; Yes ... limit
DB44: 90 A5           SUBA    <HorzDoubler        ; ... number ...
DB46: 97 99           STA     <Temp3              ; ... of rows
;
DB48: C6 0C           LDB     #$0C                ; 12 bytes
DB4A: A6 80           LDA     ,X+                 ; Copy from base ...
DB4C: A7 C0           STA     ,U+                 ; ... to drawing page
DB4E: 5A              DECB                        ; All bytes on the row done?
DB4F: 26 F9           BNE     $DB4A               ; No ... go back for all
DB51: 30 88 14        LEAX    $14,X               ; Start of ...
DB54: 33 C8 14        LEAU    $14,U               ; ... next row
DB57: 0A 99           DEC     <Temp3              ; Do ...
DB59: 26 ED           BNE     $DB48               ; ... all rows
DB5B: 39              RTS                         ; Done

Pixel Color Mask

The pixel doubler routine needs a function to convert a pixel value like 00_00_00_10 from the small (original) screen to a color mask like 10_10_10_10 to use in two bits on the magnified screen.

The doubler always works on one pixel value like 00_00_00_10 or 00_00_10_00 or 00_10_00_00 or 10_00_00_00. All four of these values must yield 10_10_10_10.

The mapping function needs to be very fast since it is used to magnify 34*34 bits. A lookup table is the fastest way -- take the pixel's value and look it up in a 256 byte table. Trade ROM space for speed.

There are four possible pixels. Each pixel has 2 bits -- 4 possible values per pixel. The possible values for our mask-making can be enumerated:

  • 00,01,02,03 (far right pixel)
  • 00,04,08,0C (second from right)
  • 00,10,20,30
  • 00,40,80,C0 (left most pixel)

The zeros are all the same (producing 00_00_00_00). Thus there are only 13 possible values out of 256 that need to be converted. The rest of the values in the 256 byte table don't matter since they will never be used.

Rather than waste this space, the game sprinkles code into the large sections between values. The lookup table goes from DB5C to DC5B. But several routines fill in the unused areas.

PixelColorDouble: 
;     00 01 02 03 04          08          0C          10
DB5C: 00 55 AA FF 55 FF FF FF AA FF FF FF FF FF FF FF 55

Copy screen

The destination is always 1C00. Copy the screen we are currently showing to 1C00 (skip this if we are already showing 1C00). Ensure that the copied screen 1C00 is visible.

CopyScreen:
DB6D: 96 92           LDA     <RequestedPage      ; Are we showing ...
DB6F: 81 1C           CMPA    #$1C                ; ... the last screen?
DB71: 27 03           BEQ     $DB76               ; Yes ... skip the copy
DB73: 5F              CLRB                        ; LSB is 0
DB74: 8D 07           BSR     Copy3KtoLast        ; Copy screen point to by 92 to the 1C00
DB76: 86 1C           LDA     #$1C                ; Now switch visible ...
DB78: 97 92           STA     <RequestedPage      ; ... to 1C00
DB7A: 13              SYNC                        ; Wait for ISR to change the page
DB7B: 39              RTS                         ; Done
;
;     20
DB7C: AA                                  ; Continued DB5C table

Copy3KtoLast

; Copy 3K (one screen) from screen pointed to by D to 3rd screen buffer at 1C00
Copy3KtoLast:
DB7D: 8E 1C 00        LDX     #$1C00              ; Pointer to last screen buffer
DB80: 1F 03           TFR     D,U                 ; Pointer to U
DB82: EC C1           LDD     ,U++                ; From the other buffer ...
DB84: ED 81           STD     ,X++                ; ... to the buffer starting at 1C00
DB86: 8C 28 00        CMPX    #$2800              ; All Done?
DB89: 25 F7           BCS     $DB82               ; No ... keep copying
DB8B: 39              RTS                         ; Done

;     30                                              40
DB8C: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 55 ; Continued DB5C table

GetSplashBugInfo:
; Return start of bug row in X
; Return bug graphics pointer in U
; A1 0 or not 0 picks picture
; 98 y coordinate
DB9D: CE C9 EA        LDU     #SplashBug1         ; Picture of bug
DBA0: 0D A1           TST     <MouthOpen          ; Use this picture or the other?
DBA2: 27 03           BEQ     $DBA7               ; Keep this one or ...
DBA4: CE CA 7A        LDU     #SplashBug2         ; ... use the other
DBA7: 96 98           LDA     <Temp2              ; Get the Y coordinate
DBA9: C6 20           LDB     #$20                ; Convert to ...
DBAB: 3D              MUL                         ; ... row offset
DBAC: 8B 1C           ADDA    #$1C                ; Drawing on the 3rd screen buffer
DBAE: 1F 01           TFR     D,X                 ; To X for return
DBB0: 39              RTS                         ; Done

DrawSplashBugLine:
DBB1: 8D EA           BSR     GetSplashBugInfo    ; Get the splash bug info (X=screen, U=picture)
DBB3: 86 06           LDA     #$06                ; 6 rows in the bug graphics
DBB5: 97 99           STA     <Temp3              ; Counter
DBB7: C6 10           LDB     #$10                ; 16 words (32 bytes) across the screen
DBB9: D7 A5           STB     <HorzDoubler        ; Counter
DBBB: E6 46           LDB     6,U                 ; 1st byte of second column of graphics
DBBD: A6 C0           LDA     ,U+                 ; 1st byte of first column graphics
DBBF: ED 81           STD     ,X++                ; 2 bytes to the screen
DBC1: 0A A5           DEC     <HorzDoubler        ; All done on this row of bugs?
DBC3: 26 FA           BNE     $DBBF               ; No ... do them all
DBC5: 0A 99           DEC     <Temp3              ; All 6 rows done?
DBC7: 26 EE           BNE     $DBB7               ; No .. do them all
DBC9: 9F A5           STX     <HorzDoubler        ; Remember this for erasing
DBCB: 39              RTS                         ; Done

;     70                                              80
DBCC: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF AA ; Continued DB5C table

EraseLoneSplash:
DBDD: C6 FF           LDB     #$FF                ; Erasing splash bug
DBDF: 86           ; LDA     #$5F (hides the CLRB)
DrawLoneSplash: 
DBE0: 5F              CLRB                        ; Drawing splash bug
DBE1: D7 88           STB     <BitPos             ; Hold the OR pattern
DBE3: 8D B8           BSR     GetSplashBugInfo    ; Get info on the splash bug row (U=graphics, X=screen)
DBE5: 30 88 17        LEAX    $17,X               ; Lone bug is 23 columns over
DBE8: 86 02           LDA     #$02                ; 2 columns to do
DBEA: 34 12           PSHS    X,A                 ; Hold the pointer and the count
DBEC: C6 06           LDB     #$06                ; 6 rows to do
DBEE: 96 88           LDA     <BitPos             ; Get the OR pattern
DBF0: 43              COMA                        ; Now a mask
DBF1: A4 C0           ANDA    ,U+                 ; Keep or ditch the graphics
DBF3: 34 02           PSHS    A                   ; Hold the new graphics byte
DBF5: 96 88           LDA     <BitPos             ; The OR pattern again
DBF7: A4 89 F4 00     ANDA    $F400,X             ; -3K (other screen where the text is printed)
DBFB: AA E0           ORA     ,S+                 ; Combine graphics (if any) and text
DBFD: A7 84           STA     ,X                  ; To the screen
DBFF: 30 88 20        LEAX    $20,X               ; Next row
DC02: 5A              DECB                        ; All 6 rows done?
DC03: 26 E9           BNE     $DBEE               ; No ... go pack
DC05: 35 12           PULS    A,X                 ; Pop the pointer and the count
DC07: 30 01           LEAX    1,X                 ; To the right one byte
DC09: 4A              DECA                        ; All 2 columns done?
DC0A: 26 DE           BNE     $DBEA               ; No ... go do them all
DC0C: 39              RTS                         ; Done

;     B1                                           C0
DC0D: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ; Continued DB5C table

; Draw a 67 pixel line down the maze
DrawVertLine:
DC1D: 34 06           PSHS    B,A                 ; Hold D
DC1F: C4 03           ANDB    #$03                ; Get ...
DC21: 8E DE 76        LDX     #BitPosTable        ; ... the
DC24: E6 85           LDB     B,X                 ; ... bitmask for the X coordinate
DC26: C4 55           ANDB    #$55                ; Mask in the color
DC28: D7 88           STB     <BitPos             ; We'll use this a lot
DC2A: E6 61           LDB     1,S                 ; Restore the X coordinate
DC2C: 8E 05 C0        LDX     #$05C0              ; 14 rows down the 1st screen buffer
DC2F: 54              LSRB                        ; 4 pixels ...
DC30: 54              LSRB                        ; ... per byte
DC31: 3A              ABX                         ; Point to screen where the line goes
DC32: C6 43           LDB     #$43                ; 67 rows down
DC34: 96 88           LDA     <BitPos             ; Line bit position
DC36: AA 84           ORA     ,X                  ; Add the line ...
DC38: A7 84           STA     ,X                  ; ... to the screen
DC3A: 30 88 20        LEAX    $20,X               ; Next row
DC3D: 5A              DECB                        ; All the way down?
DC3E: 26 F4           BNE     $DC34               ; Do all pixels
DC40: 35 86           PULS    A,B,PC              ; Done

; Draw an 80 pixel line across maze
DrawHorzLine:
DC42: 34 06           PSHS    B,A                 ; Hold D
DC44: 86 20           LDA     #$20                ; Number of rows in B ...
DC46: 3D              MUL                         ; ... to offset in D
DC47: C3 04 06        ADDD    #$0406              ; First screen buffer plus 6 columns over to maze
DC4A: 1F 01           TFR     D,X                 ; To index register
DC4C: CC 55 14        LDD     #$5514              ; 20 bytes of 55
DC4F: A7 80           STA     ,X+                 ; Draw an 80 pixel ...
DC51: 5A              DECB                        ; ... horizontal ...
DC52: 26 FB           BNE     $DC4F               ; ... line
DC54: 35 86           PULS    A,B,PC              ; Done

Draw the maze

The maze is drawn right onto the first screen buffer (0400). The code draws all possible walls and then carves the maze out with a number of runs. A run twists and turns for a random number of cells or until it is blocked.

At the end of each run, the last wall is either left in place (dead-end) or opened into the neighbor (a loop). The choice is a random picked weighted by a "loopiness" variable. The higher the "loopiness" value, the more likely the run will end in a loop. A value of zero means all runs end in a dead end.

With each level cleared, the loopiness divides down. The mazes become harder and harder (fewer loops ... more dead-ends to get trapped in.

As a run clears out walls, the code builds a list of cells to "revisit" as the starting point of the next run. When the list is empty, the maze is full and ready for play.

You can see the actual maze generation code in action below. A 6809 emulator runs the real maze-drawing code to generate the maze in the canvas below.


Loopiness:
DrawMaze:
DC56: CE 06 00        LDU     #$0600              ; 16 rows down on 1st screen buffer
DC59: 8E 08 00        LDX     #$0800              ; 64 rows for maze area
DC5C: 6F C0           CLR     ,U+                 ; Clear ...
DC5E: 30 1F           LEAX    -1,X                ; ... the ...
DC60: 26 FA           BNE     $DC5C               ; ... maze area
DC62: CE CA B0        LDU     #GraBugStanding     ; Draw the ...
DC65: BD D4 81        JSR     DrawLargeBugs       ; ... large bugs on each side of the maze
DC68: C6 0E           LDB     #$0E                ; 15 rows down to top of maze
DC6A: 8D D6           BSR     DrawHorzLine        ; Draw line
DC6C: 5C              INCB                        ; Make it a ...
DC6D: 8D D3           BSR     DrawHorzLine        ; ... 2 row double line
DC6F: 86 10           LDA     #$10                ; 16 cell rows in the maze
DC71: CB 04           ADDB    #$04                ; Start of next row
DC73: BD DC 42        JSR     DrawHorzLine        ; Draw a line
DC76: 4A              DECA                        ; Do all ...
DC77: 26 F8           BNE     $DC71               ; ... 16 rows
DC79: 5C              INCB                        ; Double line ...
DC7A: BD DC 42        JSR     DrawHorzLine        ; ... at bottom of maze
DC7D: C6 16           LDB     #$16                ; Maze starts at X=22
DC7F: BD DC 1D        JSR     DrawVertLine        ; Draw a single line down the maze
DC82: 5C              INCB                        ; Make it ...
DC83: BD DC 1D        JSR     DrawVertLine        ; ... a double line
DC86: 86 14           LDA     #$14                ; 20 cell columns in the maze
DC88: CB 04           ADDB    #$04                ; Start of next column
DC8A: BD DC 1D        JSR     DrawVertLine        ; Draw a line
DC8D: 4A              DECA                        ; All columns done?
DC8E: 26 F8           BNE     $DC88               ; No ... do all 20 columns
DC90: 5C              INCB                        ; Make the right side of ...
DC91: BD DC 1D        JSR     DrawVertLine        ; ... the maze a double line
;
DC94: CE 28 E8        LDU     #$28E8              ; "visited" flags: one byte per cell data structure
DC97: 8E 01 40        LDX     #$0140              ; 16*20 = 320 cells in the maze
DC9A: 6F C0           CLR     ,U+                 ; Clear the has-been-visited flags
DC9C: 30 1F           LEAX    -1,X                ; All done?
DC9E: 26 FA           BNE     $DC9A               ; Do all
;
DCA0: 73 29 92        COM     $2992               ; Cell 170 (y=8, x=10) close to center ... mark it visited
DCA3: CE DE 4F        LDU     #DirOffset          ; Direction offset table
DCA6: 10 8E 2A 28     LDY     #$2A28              ; Build a list of cells to ...
DCAA: 10 9F 8A        STY     <HeadCellList       ; ... visit
;
DCAD: CC 08 0A        LDD     #$080A              ; y=8,x=10 ... the middle cell of the maze
DCB0: DD 8E           STD     <Temp1              ; The target square
DCB2: EC C4           LDD     ,U                  ; Get the offset for this direction
DCB4: BD DD 63        JSR     GetPtrToNeighborCell; Get cell pointer
DCB7: 63 84           COM     ,X                  ; Note it is visited
DCB9: EC C1           LDD     ,U++                ; Get the offset for this direction and advance pointer
DCBB: BD DD 83        JSR     OpenCellWall        ; Erase the wall in this direction (the center cell is always all open)
DCBE: DC 95           LDD     <TargetCell         ; Target cell in direction
DCC0: ED A1           STD     ,Y++                ; Add this cell to our list of cells to re-visit
DCC2: EC C4           LDD     ,U                  ; Done all directions?
DCC4: 26 EC           BNE     $DCB2               ; No ... keep going
DCC6: 10 9F 8C        STY     <EndCellList        ; This is the end of the list of cells to re-visit
;
DCC9: 9E 8A           LDX     <HeadCellList       ; Are there any ...
DCCB: 9C 8C           CMPX    <EndCellList        ; ... cells to re-visit?
DCCD: 10 27 00 FA     LBEQ    DrawDots            ; No ... done with maze. Draw dots and out.
;
DCD1: EC 81           LDD     ,X++                ; Pop next cell to visit from the head of the list
DCD3: DD 8E           STD     <Temp1              ; This is our target cell now
DCD5: 9F 8A           STX     <HeadCellList       ; Update the head of the list pointer
DCD7: 86 FF           LDA     #$FF                ; We'll clear this ...
DCD9: 97 97           STA     <WallOpened         ; ... if we open a wall
;
; Build a list of directions to unvisited cells.
; 2800 holds the list
; 88 holds the number in the list
DCDB: DC 8E           LDD     <Temp1              ; Get the "visited" data pointer ...
DCDD: BD DD 6F        JSR     GetPtrToNeighNoCheck; ... for the current cell
DCE0: 86 FF           LDA     #$FF                ; Mark the ...
DCE2: A7 84           STA     ,X                  ; ... cell as visited
DCE4: 0F 88           CLR     <BitPos             ; Number of unvisited neighbors
DCE6: CE DE 4F        LDU     #DirOffset          ; Start of direction-offset table
DCE9: EC C1           LDD     ,U++                ; Get next direction offset
DCEB: 27 19           BEQ     $DD06               ; All four directions done ... move on
DCED: BD DD 63        JSR     GetPtrToNeighborCell; Get pointer to the neighbor cell
DCF0: 25 F7           BCS     $DCE9               ; Not valid ... try next direction
DCF2: A6 84           LDA     ,X                  ; Is this cell visited
DCF4: 26 F3           BNE     $DCE9               ; Yes ... try next direction
DCF6: D6 88           LDB     <BitPos             ; Bump the ...
DCF8: 5C              INCB                        ; ... count of ...
DCF9: D7 88           STB     <BitPos             ; ... unvisited neighbors
DCFB: 58              LSLB                        ; * 2 entries in table
DCFC: 8E 27 FE        LDX     #$27FE              ; We start with 1 ... at 2800
DCFF: 3A              ABX                         ; Offset into
DD00: EC 5E           LDD     -2,U                ; This is the direction we are using (we did a U++ on it earlier)
DD02: ED 84           STD     ,X                  ; Store this direction offset
DD04: 20 E3           BRA     $DCE9               ; Do all 4
;
DD06: 96 88           LDA     <BitPos             ; Number of directions we can go
DD08: 27 2E           BEQ     EndOfRun            ; We are blocked ... end of run
DD0A: CE 28 00        LDU     #$2800              ; Start of possible directions
DD0D: 4A              DECA                        ; Just one item in the list?
DD0E: 27 0C           BEQ     $DD1C               ; Yes ... only one choice to make
DD10: BD DD 52        JSR     GetRandom           ; Get random ...
DD13: 84 03           ANDA    #$03                ; ... direction
DD15: 91 88           CMPA    <BitPos             ; Make sure the random ...
DD17: 24 F7           BCC     $DD10               ; ... number is in our table
DD19: 48              LSLA                        ; Two bytes each
DD1A: 33 C6           LEAU    A,U                 ; Offset into table
DD1C: EC C4           LDD     ,U                  ; Store ...
DD1E: DD 93           STD     <GenDirection       ; ... new direction
DD20: BD DD 83        JSR     OpenCellWall        ; Open wall in the new direction
DD23: 0F 97           CLR     <WallOpened         ; Note that we opened a wall
DD25: 0A 88           DEC     <BitPos             ; Was there only one free neighbor?
DD27: 27 08           BEQ     $DD31               ; Yes ... no need to revisit this
DD29: DC 8E           LDD     <Temp1              ; Otherwise ...
DD2B: 9E 8C           LDX     <EndCellList        ; ... add this ...
DD2D: ED 81           STD     ,X++                ; ... to the ...
DD2F: 9F 8C           STX     <EndCellList        ; ... need to visit list
;
DD31: DC 95           LDD     <TargetCell         ; Continue to ...
DD33: DD 8E           STD     <Temp1              ; ... the cell we just ...
DD35: 7E DC DB        JMP     $DCDB               ; ... opened into
 
EndOfRun:
DD38: 0D 97           TST     <WallOpened         ; Did we open a wall?
DD3A: 26 13           BNE     $DD4F               ; No ... no loops allowed here
DD3C: DC 93           LDD     <GenDirection       ; Direction we came in
DD3E: BD DD 63        JSR     GetPtrToNeighborCell; If the neighbor in this direction ...
DD41: 25 0C           BCS     $DD4F               ; ... is not a valid cell then skip opening to it
DD43: BD DD 52        JSR     GetRandom           ; There is a chance that this run ends as a loop or as a block
DD46: 91 C0           CMPA    <MazeLoopiness      ; The "loopiness" divides down level by level
DD48: 24 05           BCC     $DD4F               ; Skip the final open ... leave this run as a dead-end
DD4A: DC 93           LDD     <GenDirection       ; Join this run ...
DD4C: BD DD 83        JSR     OpenCellWall        ; ... to another cell (make a loop)
DD4F: 7E DC C9        JMP     $DCC9               ; Back for another run

Random number

The random number generator pulls values from the BASIC ROM from A000 to BFFF. The pointer starts at A000 and bumps up by 21 before each new number.

GetRandom:
DD52: DC 90           LDD     <RndSeed            ; Get pointer for random numbers
DD54: C3 00 15        ADDD    #$0015              ; Bump it by 21
DD57: 84 1F           ANDA    #$1F                ; Confine pointer to ROM
DD59: DD 90           STD     <RndSeed            ; New pointer for random numbers
DD5B: C3 A0 00        ADDD    #$A000              ; Offset into ROM
DD5E: 34 06           PSHS    B,A                 ; Get randomish ...
DD60: A6 F1           LDA     [,S++]              ; ... byte from ROM
DD62: 39              RTS                         ; Return it

GetPtrToNeighborCell:
; 8E:8F = reference cell
; A = y offset
; B = x offset
; Return C=1 if invalid
; Return C=0 if valid and X=pointer to target cell data
;
DD63: DB 8F           ADDB    <Temp1+1            ; Target cell X coordinate
DD65: C1 14           CMPB    #$14                ; Is the X >= 20? (too far right)
DD67: 24 17           BCC     $DD80               ; Yes ... return Carry=1
DD69: 9B 8E           ADDA    <Temp1              ; Target cell Y coordinate
DD6B: 81 10           CMPA    #$10                ; Is the Y >= 16? (too far down)
DD6D: 24 11           BCC     $DD80               ; Yes ... return Carry=1
;
GetPtrToNeighNoCheck:
DD6F: 34 04           PSHS    B                   ; Hold target cell X coordinate
DD71: 6F E2           CLR     ,-S                 ; Make a MSB of 0 (stack is now 00:B)
DD73: C6 14           LDB     #$14                ; 20 cells ...
DD75: 3D              MUL                         ; ... per row
DD76: E3 E1           ADDD    ,S++                ; X,Y cell number to single cell index
DD78: 8E 28 E8        LDX     #$28E8              ; Pointer into ...
DD7B: 30 8B           LEAX    D,X                 ; ... "visited" structure
DD7D: 1C FE           ANDCC   #$FE                ; Valid cell (X points to data visited data)
DD7F: 39              RTS                         ; Done
;
DD80: 1A 01           ORCC    #$01                ; Invalid cell
DD82: 39              RTS                         ; Done

OpenCellWall:
; 8E:8F = reference cell
; A = y offset
; B = x offset
; Return target cell Y,X in 95:96
DD83: 9B 8E           ADDA    <Temp1              ; add offset Y to reference Y
DD85: DB 8F           ADDB    <Temp1+1            ; add offset X to reference X
DD87: DD 95           STD     <TargetCell         ; Hold target cell Y,X
DD89: D1 8F           CMPB    <Temp1+1            ; did we change X (left or right)?
DD8B: 26 1C           BNE     $DDA9               ; Yes ... go do left/right
;
DD8D: 91 8E           CMPA    <Temp1              ; did we go up?
DD8F: 25 02           BCS     $DD93               ; Yes ... use the wall in target cell
DD91: 96 8E           LDA     <Temp1              ; No ... use the wall in the reference cell
;
DD93: 48              LSLA                        ; Y multiplied ...
DD94: 48              LSLA                        ; ... by 4
DD95: 34 04           PSHS    B                   ; Hold the X
DD97: C6 20           LDB     #$20                ; 32 bytes ...
DD99: 3D              MUL                         ; ... per row
DD9A: C3 06 66        ADDD    #$0666              ; Start of wall (bottom wall of cell)
DD9D: 1F 01           TFR     D,X                 ; Pointer to X
DD9F: E6 E0           LDB     ,S+                 ; Get the X coordinate back
DDA1: 3A              ABX                         ; 4-pixels per cell ... point to the cell lower/left corner (because 666)
DDA2: A6 84           LDA     ,X                  ; Get the 4 pixels from the screen
DDA4: 84 03           ANDA    #$03                ; Mask off left most 3
DDA6: A7 84           STA     ,X                  ; Erase the line on the screen
DDA8: 39              RTS                         ; Done
;
DDA9: 25 02           BCS     $DDAD               ; Going left ... use the target cell wall
DDAB: D6 8F           LDB     <Temp1+1            ; Going right ... use the reference cell wall
;
DDAD: 48              LSLA                        ; Four pixels ...
DDAE: 48              LSLA                        ; ... per cell
DDAF: 34 04           PSHS    B                   ; Hold X
DDB1: C6 20           LDB     #$20                ; 32 bytes ...
DDB3: 3D              MUL                         ; ... per row
DDB4: C3 06 06        ADDD    #$0606              ; Start of wall (upper left corner ... erasing right wall)
DDB7: 1F 01           TFR     D,X                 ; Pointer to X
DDB9: E6 E0           LDB     ,S+                 ; Get the X coordinate back
DDBB: 3A              ABX                         ; 4-pixels per cell ... point to the cell upper/left corner
DDBC: C6 03           LDB     #$03                ; 3 pixels to erase down the right side of the cell
DDBE: A6 84           LDA     ,X                  ; From screen
DDC0: 84 FC           ANDA    #$FC                ; Mask off the far right bit
DDC2: A7 84           STA     ,X                  ; Back to the screen
DDC4: 30 88 20        LEAX    $20,X               ; Next row
DDC7: 5A              DECB                        ; All pixels done?
DDC8: 26 F4           BNE     $DDBE               ; Do them all
DDCA: 39              RTS                         ; Done
                     
DrawDots:
DDCB: 8E 06 26        LDX     #$0626              ; First dot in maze
DDCE: 86 10           LDA     #$10                ; 16 Rows in the maze
DDD0: 97 98           STA     <Temp2              ; row counter
DDD2: 5F              CLRB                        ; Column counter starts at 0
DDD3: A6 85           LDA     B,X                 ; Get the value from the screen
DDD5: 8A 30           ORA     #$30                ; Add a white ...
DDD7: A7 85           STA     B,X                 ; ... dot to the cell
DDD9: 5C              INCB                        ; Next column
DDDA: C1 14           CMPB    #$14                ; Done 20 across?
DDDC: 25 F5           BCS     $DDD3               ; No ... finish this row
DDDE: 30 89 00 80     LEAX    $0080,X             ; 4 rows per cell ... next row of cells
DDE2: 0A 98           DEC     <Temp2              ; All 16 cells done?
DDE4: 26 EC           BNE     $DDD2               ; No ... do all rows

;DDE6: CC 00 04 ; End level after just 4 dots (quick access to the reward screen)

DDE6: CC 01 3F        LDD     #$013F              ; Number of dots ...
DDE9: ED 8D 22 D1     STD     DotsLeft,PC         ; ... left in the maze
DDED: 8E 0A 30        LDX     #$0A30              ; Center cell of the maze
DDF0: 86 CF           LDA     #$CF                ; Erase ...
DDF2: A4 84           ANDA    ,X                  ; ... the center ...
DDF4: A7 84           STA     ,X                  ; ... dot
DDF6: 86 FF           LDA     #$FF                ; Scroll from ...
DDF8: 97 A5           STA     <HorzDoubler        ; ... inside to outside
DDFA: 8D 05           BSR     WhiteLineScroll     ; Scroll 0400 onto the visible screen
DDFC: 86 04           LDA     #$04                ; Request to show ...
DDFE: 97 92           STA     <RequestedPage      ; ... page 0400 (so we can draw on 1C00)
DE00: 39              RTS                         ; Out

White Line Scroll

A=-1 for inside out or 1 for outside in. This always scrolls the data from 0400 to 1C00.

WhiteLineScroll:
DE01: C6 20           LDB     #$20                ; A is -1 or 1
DE03: 3D              MUL                         ; Now -32 or 32
DE04: D7 A5           STB     <HorzDoubler        ; Scroll offset (scroll on or scroll off)
DE06: 86 30           LDA     #$30                ; 48 rows + 48 rows = 96 (full screen)
DE08: 97 98           STA     <Temp2              ; Count passes
DE0A: 8E 21 E0        LDX     #$21E0              ; Middle ...
DE0D: 33 88 20        LEAU    $20,X               ; ... two rows
DE10: 0D A5           TST     <HorzDoubler        ; Scrolling inside out or outside in?
DE12: 2B 28           BMI     $DE3C               ; Inside out ... keep the center of the screen
DE14: 8E 1C 00        LDX     #$1C00              ; Else use the top of screen ...
DE17: CE 27 E0        LDU     #$27E0              ; ... and bottom of screen
DE1A: 20 20           BRA     $DE3C               ; Start outside-in by drawing the line
;
; Copy a row from buffer at 0400 to buffer at 1C00
DE1C: C6 20           LDB     #$20                ; 32 bytes in the row
DE1E: 34 50           PSHS    U,X                 ; Hold the pointers
DE20: A6 89 E8 00     LDA     $E800,X             ; 1C00 + E800 = 0400 ... from the first screen buffer ...
DE24: A7 80           STA     ,X+                 ; ... to the visible screen
DE26: A6 C9 E8 00     LDA     $E800,U             ; The second scroll line ...
DE2A: A7 C0           STA     ,U+                 ; ... to the visible screen
DE2C: 5A              DECB                        ; All the row done?
DE2D: 26 F1           BNE     $DE20               ; No ... do the whole row
DE2F: 35 50           PULS    X,U                 ; Restore the pointers
DE31: 96 A5           LDA     <HorzDoubler        ; Scroll line offset
DE33: 30 86           LEAX    A,X                 ; The top line goes one way ...
DE35: 40              NEGA                        ; ... and the bottom goes ...
DE36: 33 C6           LEAU    A,U                 ; ... the other
DE38: 0A 98           DEC     <Temp2              ; All done?
DE3A: 27 C4           BEQ     $DE00               ; Yes ... out
;
DE3C: 34 50           PSHS    U,X                 ; Hold the line pointers
DE3E: CC FF 20        LDD     #$FF20              ; 32 FFs ... this is the white line

Quirks

There are several areas of questionable code here. These little quirks give the code personality. For instance, why are we branching to the next line? Search for "?Why?" on this page to see others.

DE41: 2B 00           BMI     $DE43               ; ?Why? Branching to the next line? Code personality.
DE43: A7 80           STA     ,X+                 ; Draw the two ....
DE45: A7 C0           STA     ,U+                 ; ... white lines
DE47: 5A              DECB                        ; Row done?
DE48: 26 F9           BNE     $DE43               ; No ... do whole row
DE4A: 35 50           PULS    X,U                 ; Restore the line pointers
DE4C: 13              SYNC                        ; Wait for horizontal blanking
DE4D: 20 CD           BRA     $DE1C               ; Keep going

DirOffset: 
DE4F: FF 00 ; 0 (up)    Y-1, X
DE51: 00 FF ; 1 (left)  Y,   X-1
DE53: 01 00 ; 2 (down)  Y+1, X
DE55: 00 01 ; 3 (right) Y,   X+1
DE57: 00 00 ; end of list

CoordToScrOffs

Coordinate (y,x) comes in as registers A,B. The top of the screen comes in as register X. Or we can look up <$9A or we can use 0400.

Return memory offset in X and pixel map in B.

CoordToScrOffs9A:
DE59: 9E 9A           LDX     <DrawingScreenPtr   ; Top of the drawing screen
DE5B: 10                                                    ; Hiding "LDX #$0400" entry at DE5C. Becomes "LDY #$0400".
CoordToScrOffs400:                                                
DE5C: 8E 04 00        LDX     #$0400              ; Top of first screen
CoordToScrOffs: 
DE5F: 34 04           PSHS    B                   ; Hold X coordinate
DE61: C6 20           LDB     #$20                ; Multiply ...
DE63: 3D              MUL                         ; A (Y coordinate) by 32
DE64: 30 8B           LEAX    D,X                 ; Row offset
DE66: E6 E4           LDB     ,S                  ; Get the X coordinate back
DE68: 54              LSRB                        ; Divide by ...
DE69: 54              LSRB                        ; ... four (four pixels per byte)
DE6A: 3A              ABX                         ; Offset to screen memory
DE6B: E6 E0           LDB     ,S+                 ; Pop the X coordinate back
DE6D: C4 03           ANDB    #$03                ; Pixel number (left to right)
DE6F: 10 8E DE 76     LDY     #BitPosTable        ; Pixel number to white-pixel-pattern
DE73: E6 A5           LDB     B,Y                 ; Get the byte for the pixel
DE75: 39              RTS                         ; Done

BitPosTable:
DE76: C0 ; 11000000
DE77: 30 ; 00110000
DE78: 0C ; 00001100
DE79: 03 ; 00000011

Move the Bugs

This code drives the bugs. First it makes sure that the bug is completely in a cell (not between two cells).

First, erase any player trail dot. Then build a list of directions with player trail dots. If there are any, pick one of these directions.

Otherwise, build a list of directions that are open. There must be at least one (the bug can always go back the way it came). Pick one of these directions.

MoveBugs:            
DE7A: 96 A0           LDA     <NumBugs            ; Number of bugs in the game
DE7C: 97 98           STA     <Temp2              ; To a temporary counter
DE7E: 10 8E 28 08     LDY     #$2808              ; Data on all the bugs
DE82: BD DE B6        JSR     $DEB6               ; Return if this bug is between cells
DE85: 8E DE 4F        LDX     #DirOffset          ; Direction table
DE88: E6 22           LDB     2,Y                 ; Bug's direction
DE8A: 58              LSLB                        ; Two bytes per direction
DE8B: 3A              ABX                         ; Get direction offset
DE8C: EC A4           LDD     ,Y                  ; Get the bug's current coordinate
DE8E: AB 84           ADDA    ,X                  ; Offset the Y ...
DE90: EB 01           ADDB    1,X                 ; ... and the X
DE92: ED A4           STD     ,Y                  ; New coordinate
DE94: BD DA 24        JSR     CheckAlignOddEven   ; Is the coordinate an "even" one?
DE97: 24 16           BCC     $DEAF               ; No ... skip erasing the player trail
;
DE99: EC A4           LDD     ,Y                  ; Bug's coordinates
DE9B: 34 20           PSHS    Y                   ; Hold for a second
DE9D: BD DE 5C        JSR     CoordToScrOffs400   ; Get the screen pointer to X
DEA0: 35 20           PULS    Y                   ; Y coordinates again
DEA2: 1F 98           TFR     B,A                 ; Pixel map of the bug on the screen
DEA4: 84 55           ANDA    #$55                ; Set the color
DEA6: A4 84           ANDA    ,X                  ; Is there an edible dot here (a regular dot results in not-zero)
DEA8: 26 05           BNE     $DEAF               ; Yes ... leave it alone
DEAA: 53              COMB                        ; Now a mask
DEAB: E4 84           ANDB    ,X                  ; Erase whatever dot ...
DEAD: E7 84           STB     ,X                  ; ... is there (erases player-trail)
;
DEAF: 31 23           LEAY    3,Y                 ; Next bug structure
DEB1: 0A 98           DEC     <Temp2              ; Do all ...
DEB3: 26 CD           BNE     $DE82               ; ... the bugs
DEB5: 39              RTS                         ; Done
;
DEB6: EC A4           LDD     ,Y                  ; Get the bug's Y,X coordinate
DEB8: BD DA 24        JSR     CheckAlignOddEven   ; Odd or even coordinates?
DEBB: 24 F8           BCC     $DEB5               ; Not time to change ... out
;
; Look for player-trail in all directions
DEBD: CE DE 4F        LDU     #DirOffset          ; Direction offset table
DEC0: 0F 88           CLR     <BitPos             ; Number of possible directions found
DEC2: 0F 99           CLR     <Temp3              ; Current direction we are checking
DEC4: EC C1           LDD     ,U++                ; Get offset for this direction
DEC6: 48              LSLA                        ; 2 pixels in Y direction
DEC7: 58              LSLB                        ; 2 pixels in X direction
DEC8: AB A4           ADDA    ,Y                  ; Add offset ...
DECA: EB 21           ADDB    1,Y                 ; ... to coordinate
DECC: 34 20           PSHS    Y                   ; Hold for a second
DECE: BD DE 5C        JSR     CoordToScrOffs400   ; screen pointer to X (bit pos to B)
DED1: 35 20           PULS    Y                   ; Restore the coordinate
DED3: 34 04           PSHS    B                   ; Bit pos to stack
DED5: E6 84           LDB     ,X                  ; From screen
DED7: C8 AA           EORB    #$AA                ; Color
DED9: E4 E0           ANDB    ,S+                 ; Check bit on screen
DEDB: 26 0C           BNE     $DEE9               ; This is NOT a player-trail. Don't record this direction
DEDD: D6 88           LDB     <BitPos             ; Number of player-trail directions
DEDF: 8E 28 00        LDX     #$2800              ; List of player-trail directions
DEE2: 3A              ABX                         ; Offset to next entry
DEE3: 96 99           LDA     <Temp3              ; Remember we should ...
DEE5: A7 84           STA     ,X                  ; ... go this way
DEE7: 0C 88           INC     <BitPos             ; Bump number of player-trail directions
DEE9: 96 99           LDA     <Temp3              ; Count up ...
DEEB: 4C              INCA                        ; ... to next ...
DEEC: 97 99           STA     <Temp3              ; ... direction
DEEE: 81 04           CMPA    #$04                ; All 4 directions checked?
DEF0: 25 D2           BCS     $DEC4               ; No ... go back for all
;
DEF2: 0D 88           TST     <BitPos             ; Did we find any player-trail directions?
DEF4: 26 29           BNE     $DF1F               ; Yes ... go pick one of these
DEF6: EC A4           LDD     ,Y                  ; Bug coordinates
DEF8: BD DA 12        JSR     CheckWallAlign      ; Are we between cells?
DEFB: 24 B8           BCC     $DEB5               ; Yes ... can't change directions here ... out
;
; Get a random available direction (but not a 180 turn unless we have to)
DEFD: EC A4           LDD     ,Y                  ; Get coordinates
DEFF: 34 20           PSHS    Y                   ; Hold this over function call
DF01: BD DE 5C        JSR     CoordToScrOffs400   ; convert to screen coordinates
DF04: 35 20           PULS    Y                   ; Restore after function call
DF06: CE 28 00        LDU     #$2800              ; List of available directions
DF09: 0F 88           CLR     <BitPos             ; Number of available directions
DF0B: 4F              CLRA                        ; Start with direction 0
DF0C: 34 12           PSHS    X,A                 ; Hold this over the function call
DF0E: 8D 32           BSR     CheckForWall        ; Check the direction
DF10: 35 12           PULS    A,X                 ; Restore after call
DF12: 25 06           BCS     $DF1A               ; There is a wall in that direction ... don't add this
DF14: D6 88           LDB     <BitPos             ; ?Why? This is never used? Code personality.
DF16: A7 C0           STA     ,U+                 ; Add the available direction to our list
DF18: 0C 88           INC     <BitPos             ; Bump the count of availables
DF1A: 4C              INCA                        ; Next direction
DF1B: 81 04           CMPA    #$04                ; All directions tried?
DF1D: 25 ED           BCS     $DF0C               ; No ... go back for them all
;
DF1F: 96 88           LDA     <BitPos             ; Number of available directions
DF21: CE 28 00        LDU     #$2800              ; List of availables
DF24: 4A              DECA                        ; Just one available?
DF25: 27 16           BEQ     $DF3D               ; Yes ... we have to use the only one
DF27: BD DD 52        JSR     GetRandom           ; Get a random ...
DF2A: 84 03           ANDA    #$03                ; ... number
DF2C: 91 88           CMPA    <BitPos             ; More than the number of directions we have?
DF2E: 24 F7           BCC     $DF27               ; Yes ... go back and try again
DF30: CE 28 00        LDU     #$2800              ; ?Why? Hey ... U already has this in it. Code personality.
DF33: 33 C6           LEAU    A,U                 ; Get desired ...
DF35: A6 C4           LDA     ,U                  ; ... direction
DF37: A8 22           EORA    2,Y                 ; Are we picking ...
DF39: 81 02           CMPA    #$02                ; ... a 180 degree turn?
DF3B: 27 EA           BEQ     $DF27               ; Yes ... don't do that ... try again
DF3D: A6 C4           LDA     ,U                  ; Get the new direction
DF3F: A7 22           STA     2,Y                 ; Store it
DF41: 39              RTS                         ; Done

Check for wall

A holds the direction. This code assumes that the coordinate to test is not between cells. The calling code must make sure that a wall is at least possible.

Return:

  • C=1 if there IS a wall
  • C=0 if there is NOT a wall
CheckForWall:
DF42: 85 01           BITA    #$01                ; Up or down?
DF44: 27 0F           BEQ     $DF55               ; Yes ... go handle up/down
DF46: 85 02           BITA    #$02                ; Must be left/right. Is it right?
DF48: 26 02           BNE     $DF4C               ; Yes ... use what we got
DF4A: 30 1F           LEAX    -1,X                ; Back up one byte on screen
DF4C: E6 84           LDB     ,X                  ; Get value from screen
DF4E: C4 01           ANDB    #$01                ; Is there a wall there?
DF50: 27 13           BEQ     $DF65               ; No ... go clear the carry
DF52: 1A 01           ORCC    #$01                ; Yes ... set the carry if there is a wall
DF54: 39              RTS                         ; Done
;
DF55: 30 88 40        LEAX    $40,X               ; 2 rows down
DF58: 85 02           BITA    #$02                ; This is up/down. Is it down?
DF5A: 26 03           BNE     $DF5F               ; Yes ... use what we got
DF5C: 30 88 80        LEAX    $80,X               ; 4 rows down to next cell
DF5F: E6 84           LDB     ,X                  ; Get value from screen
DF61: C4 10           ANDB    #$10                ; Is there a wall there?
DF63: 26 ED           BNE     $DF52               ; Yes ... set the carry
DF65: 1C FE           ANDCC   #$FE                ; Carry clear means no wall
DF67: 39              RTS                         ; Done

Bug dots

Drawing and erasing the bugs on the non-magnified maze. They are just 1-pixel dots in the maze.

There are two functions here: one to draw the dots and one to erase them.

DrawBugDot:
DF68: C6 FF           LDB     #$FF                ; We are drawing the bug
DF6A: 10 8E 28 08     LDY     #$2808              ; First set of bug coordinates
DF6E: 20 0D           BRA     $DF7D               ; Common code
;
EraseBugDot:
DF70: 5F              CLRB                        ; We are erasing the bug
DF71: 10 8E 28 08     LDY     #$2808              ; Second set of bug coordinates
DF75: 0D A1           TST     <MouthOpen          ; Is the mouth open?
DF77: 2A 04           BPL     $DF7D               ; Yes ... keep the first set of coordinates
DF79: 10 8E 28 68     LDY     #$2868              ; No ... switch to the second set of coordinates
;
DF7D: D7 88           STB     <BitPos             ; Store the color mask
DF7F: 96 A0           LDA     <NumBugs            ; Number of bugs
DF81: 97 98           STA     <Temp2              ; Use this as a counter
DF83: E6 21           LDB     1,Y                 ; X coordinate
DF85: C4 03           ANDB    #$03                ; Make a ...
DF87: 8E DE 76        LDX     #BitPosTable        ; ... quick ...
DF8A: E6 85           LDB     B,X                 ; ... bit position
DF8C: 34 04           PSHS    B                   ; Hold the bit position
DF8E: A6 A4           LDA     ,Y                  ; Y coordinate
DF90: C6 20           LDB     #$20                ; 32 bytes ...
DF92: 3D              MUL                         ; ... per row
DF93: 34 06           PSHS    B,A                 ; Store row pointer
DF95: 4F              CLRA                        ; MSB of 0
DF96: E6 21           LDB     1,Y                 ; Y coordinate again
DF98: 54              LSRB                        ; 4 pixels ...
DF99: 54              LSRB                        ; ... per byte
DF9A: E3 E1           ADDD    ,S++                ; Now screen pointer to bug in D
DF9C: 8E 04 00        LDX     #$0400              ; Offset on ...
DF9F: 30 8B           LEAX    D,X                 ; ... the first screen buffer (to X)
DFA1: D3 9A           ADDD    <DrawingScreenPtr   ; Offset to drawing ...
DFA3: 1F 03           TFR     D,U                 ; ... buffer (to U)
DFA5: A6 E4           LDA     ,S                  ; Bug's bit position
DFA7: 94 88           ANDA    <BitPos             ; color mask (either on or off)
DFA9: 43              COMA                        ; Mask the bug's bit from ...
DFAA: A4 84           ANDA    ,X                  ; ... the screen
DFAC: E6 E0           LDB     ,S+                 ; Bit position
DFAE: 34 02           PSHS    A                   ; Now store the screen value on the stack
DFB0: C4 55           ANDB    #$55                ; Bug's color
DFB2: D4 88           ANDB    <BitPos             ; Draw the bug ...
DFB4: EA E0           ORB     ,S+                 ; ... on the screen (or leave it off)
DFB6: E7 C4           STB     ,U                  ; And on the drawing screen
DFB8: 96 A1           LDA     <MouthOpen          ; Is the mouth open?
DFBA: 2A 09           BPL     $DFC5               ; Yes ... skip copy
DFBC: 96 88           LDA     <BitPos             ; Are we drawing or erasing a bug?
DFBE: 26 05           BNE     $DFC5               ; Drawing ... skip copy
DFC0: EC A8 A0        LDD     $A0,Y               ; Copy 2nd set of coordinates ...
DFC3: ED A4           STD     ,Y                  ; ... to first set
DFC5: 31 23           LEAY    3,Y                 ; Next bug
DFC7: 0A 98           DEC     <Temp2              ; Do ...
DFC9: 26 B8           BNE     $DF83               ; ... all the bugs
DFCB: 39              RTS                         ; Done

Check collision between bugs and player

The check is a simple rectangle comparison. If the player's coordinates are within 2x2 of a bug then a collision has occurred.

Return:

  • C=0 No collision
  • C=1 Collision
CheckCollision:
DFCC: 8E 28 08        LDX     #$2808              ; Bugs data structure. 3 bytes each (y,x,dir)
DFCF: 96 A0           LDA     <NumBugs            ; Number of bugs in the 2808 structure
DFD1: 97 98           STA     <Temp2              ; Counter
DFD3: EC 84           LDD     ,X                  ; Get the bug coordinate
DFD5: 90 8E           SUBA    <Temp1              ; Compare the Y coordinate
DFD7: 2A 01           BPL     $DFDA               ; Absolute ...
DFD9: 40              NEGA                        ; ... value
DFDA: 81 02           CMPA    #$02                ; Within 2?
DFDC: 24 09           BCC     $DFE7               ; No ... can't be a collision
DFDE: D0 8F           SUBB    <Temp1+1            ; Now compare the X coordinate
DFE0: 2A 01           BPL     $DFE3               ; Absolute ...
DFE2: 50              NEGB                        ; ... value
DFE3: C1 02           CMPB    #$02                ; Within 2?
DFE5: 25 09           BCS     $DFF0               ; Yes! This is a hit. Return the status
DFE7: 30 03           LEAX    3,X                 ; Next bug data
DFE9: 0A 98           DEC     <Temp2              ; All bugs checked?
DFEB: 26 E6           BNE     $DFD3               ; No ... keep looking
;
DFED: 1C FE           ANDCC   #$FE                ; Return C=0 ... the player did NOT hit a bug
DFEF: 39              RTS                         ; Done
;
DFF0: 1A 01           ORCC    #$01                ; Return C=1 ... the player hit a bug
DFF2: 39              RTS                         ; Done

Unused

; Unused at end
DFF3: FF FF FF FF FF FF FF FF FF FF FF FF FF