• Contact
  • Journal
  • Home
  • CoCo
  • Daggorath
  • 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
  • Daggorath Code
  • Start
  • Tasks
    • Task pool
    • Task timers
      • T0: Player Input Task
      • T1: Draw 3D Screen
      • T2: Update Heart Rate
      • T3: Update Torch
      • T4: Make Creature
      • T5: Handle Creature
  • Game Loop
  • Interrupt Service
  • SWI Handler
  • LOOK command
  • SWI Function Table
  • ATTACK command
  • CLIMB command
  • EXAMINE command
  • GET command
  • DROP command
  • STOW command
  • PULL command
  • INCANT command
  • REVEAL command
  • TURN command
  • MOVE command
  • USE command
  • ZLOAD command
  • ZSAVE command
  • Initial Backpack Objects
  • Screen Descriptors
  • First Words
  • Second Words
  • Proper Names
  • Class Names
  • Check List
    • Start With
    • Level 0
    • Level 1
    • Level 2
    • Level 3
    • Level 4
  • Text Characters
  • Heart Pictures
  • Object Pictures
  • Walls and Doors
  • Holes and Ladders
  • Club Giant Picture
  • Hatchet Giant Picture
  • Galdrog Picture
  • Wraith Picture
  • Spider Picture
  • Scorpion Picture
  • Blob Picture
  • Knight Picture
  • Shield Knight Picture
  • Moon Wizard Picture
  • Star Wizard Picture
  • Demon Picture
  • Snake Picture

Daggorath Code

Cool things to do: - Get this working enough in the emulator to walk down the halls - Map-drawing step function. Allow the user to pick existing seeds or put in new ones. - Write up on Task timing - Write up on structure contents

RAM Usage

Hardware Info

Good info on the math here: http://archive.li/mJKIz

TODO: what areas are mirrored? how does the flip happen? are graphics/text areas ended differently?

Start

Start:
C000: CE C0 D1        LDU     #$C0D1              ; Play demo game code
C003: 20 03           BRA     PlayGame            ; Do Demo
;
C005: CE C1 24        LDU     #$C124              ; Play normal game code
;
PlayGame:
C008: 10 CE 10 00     LDS     #$1000              ; Stacks builds to lower from $1000
C00C: 8E FF 00        LDX     #$FF00              ; PIA0
C00F: CC 34 FA        LDD     #$34FA              ; A=34, B=FA
C012: A7 03           STA     3,X                 ; CTRL-B = 0_0_110_1_00 : IRQs off ...
C014: A7 01           STA     1,X                 ; CTRL_A = 0_0_110_1_00 : ... output register select
C016: 8E FF 20        LDX     #$FF20              ; PIA1
C019: A7 01           STA     1,X                 ; CTRL-B = 0_0_110_1_00 : IRQs off
C01B: 6F 03           CLR     3,X                 ; DDR selected for B
C01D: E7 02           STB     2,X                 ; DDRB = 11111010 (mem and serial inputs)
C01F: 86 3C           LDA     #$3C                ; 0_0_111_1_00
C021: A7 03           STA     3,X                 ; Turn off FIRQs
C023: CC 20 46        LDD     #$2046              ; 001000__0001000_110
C026: BD C2 66        JSR     WriteToSAM          ; Graphics=G6R,G6C  Display=8*512 (0x1000)
C029: 86 F8           LDA     #$F8                ; Upper bits ...
C02B: A7 02           STA     2,X                 ; ... of display mode (256x192 color)
C02D: 8E 02 00        LDX     #$0200              ; Clear ...
C030: 6F 80           CLR     ,X+                 ; ... all ...
C032: 8C 40 00        CMPX    #$4000              ; ... temporary ...
C035: 25 F9           BCS     $C030               ; ... memory (base page)
C037: EF E3           STU     ,--S                ; Store return to demo or game
C039: 86 02           LDA     #$02                ; DP = ...
C03B: 1F 8B           TFR     A,DP                ; ... 0200
C03D: 10 8E D7 E8     LDY     #$D7E8              ; Table of inits
C041: A6 A0           LDA     ,Y+                 ; Get count
C043: 27 41           BEQ     $C086               ; All done ... move on
C045: AE A1           LDX     ,Y++                ; Get destination
C047: 8D 02           BSR     CopyYtoX            ; Do copy
C049: 20 F6           BRA     $C041               ; Do all

CopyYtoX:
; Copy bytes (A is count) from Y to X
C04B: E6 A0           LDB     ,Y+                 ; Value from Y
C04D: E7 80           STB     ,X+                 ; Store to X
C04F: 4A              DECA                        ; All done?
C050: 26 F9           BNE     CopyYtoX            ; No ... do all
C052: 39              RTS                         ; Out

InitTasks:
C053: 34 77           PSHS    U,Y,X,B,A,CC        ; Save all registers
C055: 1A 10           ORCC    #$10                ; Turn OFF the IRQ interrupt
C057: 8E 02 9F        LDX     #$029F              ; Clear the ...
C05A: 6F 80           CLR     ,X+                 ; ... linked list ...
C05C: 8C 02 AD        CMPX    #$02AD              ; ... of ...
C05F: 25 F9           BCS     $C05A               ; ... task pointers
C061: 8E 09 FD        LDX     #$09FD              ; First game-task structure
C064: 9F B9           STX     <nextTask           ; Next available task
C066: 6F 80           CLR     ,X+                 ; Zero out  ...
C068: 8C 0B 07        CMPX    #$0B07              ; ... game-task structures
C06B: 25 F9           BCS     $C066               ; ... slots
;
C06D: 10 8E D7 DC     LDY     #$D7DC              ; Initial task routines
C071: 0A BB           DEC     <taskListsRebuilt   ; 
C073: CC 00 0C        LDD     #$000C              ; Offset to last index in the task linked list (tasks are going on the end)
C076: AE A1           LDX     ,Y++                ; Get next task entry
C078: 27 0A           BEQ     $C084               ; All tasks have been made ... out
C07A: BD C2 5C        JSR     ReserveTask         ; Reserve a task structure (pointer returned in U)
C07D: AF 43           STX     3,U                 ; Save code pointer in structure
C07F: BD C2 1D        JSR     ChainTaskToEnd      ; Chain the task to the end of the list and set counter to 0
C082: 20 F2           BRA     $C076               ; Do all tasks
C084: 35 F7           PULS    CC,A,B,X,Y,U,PC     ; Done

; Initialization continues from C043
C086: 8D CB           BSR     InitTasks           ; Initialize game tasks
C088: CE DA 91        LDU     #$DA91              ; Object distribution table
C08B: 4F              CLRA                        ; First object in table is type 0 (SUPREME RING)
C08C: E6 C4           LDB     ,U                  ; Get the info
C08E: C4 0F           ANDB    #$0F                ; Hold ...
C090: D7 8C           STB     <numObjs            ; ... number of objects
C092: E6 C0           LDB     ,U+                 ; Get the info
C094: 54              LSRB                        ; Hold ...
C095: 54              LSRB                        ; ... ...
C096: 54              LSRB                        ; ... ...
C097: 54              LSRB                        ; ... ...
C098: D7 8D           STB     <m028D              ; ... first appear on level
C09A: 3F              SWI                         ; Make an instance of the object
C09B: 17                                          ; 17: Create object structure
C09C: 6A 05           DEC     5,X                 ; Object isn't in any list (room, player, monster)
C09E: 5C              INCB                        ; Next object on next level
C09F: C1 05           CMPB    #$05                ; Past level 4?
C0A1: 2F 02           BLE     $C0A5               ; No ... use next level
C0A3: D6 8D           LDB     <m028D              ; use
C0A5: 0A 8C           DEC     <numObjs            ; Decrement number of objects
C0A7: 26 F1           BNE     $C09A               ; Go back to create more of this type
C0A9: 4C              INCA                        ; Next object type
C0AA: 11 83 DA A3     CMPU    #$DAA3              ; All object types done?
C0AE: 25 DC           BCS     $C08C               ; Not end of table ... go back
;
C0B0: CE 03 88        LDU     #$0388              ; Hand line screen descriptor
C0B3: 0A B7           DEC     <whereToPrint       ; Printing goes to desired descriptor
C0B5: 3F              SWI                         ; Clear the hand line
C0B6: 0A                                          ; 0A: Clear hand descriptor
C0B7: 3F              SWI                         ; Print the copyright in the hand line
C0B8: 02                                          ; 02: Uncompress message m and display
C0B9: F8 DF 0C C9 27 45 00 02 65 C1 03 52 39      ; "COPYRIGHT  DYNA MICRO  MCMLXXXII"
C0C6: 3C 00 68 DA CC 63 09 48                     ;
;
C0CE: 0F B7           CLR     <whereToPrint       ; Printing now goes to command area
C0D0: 39              RTS                         ; Done

PlayDemo:
C0D1: 0A 77           DEC     <gameMode           ; Demo mode flag
C0D3: 8D 3F           BSR     EndOfTapeAccess     ; Configure interrupts
C0D5: 8E DF 10        LDX     #$DF10              ; Wizard picture
C0D8: 0A 9E           DEC     <initBeamIn         ; Initialize the beam in
C0DA: 3F              SWI                         ; Beam on the wizard
C0DB: 14                                          ; SWI_14:Beam wizard in:
C0DC: 3F              SWI                         ; Print the first part of the message
C0DD: 02                                          ; SWI_2:Uncompress message m and display:
C0DE: 9F D2 02 06 45 06 4A 02 BA 85 97 BD EF 80   ; "_1F_I DARE YE ENTER..._1F_"
;
C0EC: 3F              SWI                         ; Print the second part of the message
C0ED: 02                                          ; SWI_2:Uncompress message m and display:
C0EE: F7 BD EA 20 A0 25 5C 72 BD D3 03 CC 02 04   ; "...THE DUNGEONS OF DAGGORATH!!!"
C0FC: E7 7C 83 44 6F 7B                           ;
;
C102: 3F              SWI                         ; Wait 1.35 seconds
C103: 10                                          ; SWI_10:Pause for 1.35 seconds:
C104: 3F              SWI                         ; Another 1.35 seconds
C105: 10                                          ; SWI_10:Pause for 1.35 seconds:
C106: 3F              SWI                         ; Beam off the wizard
C107: 15                                          ; SWI_15:Beam wizard out:
C108: 3F              SWI                         ; Wait 1.35 seconds
C109: 09                                          ; SWI_9:Clear secondary screen:
C10A: 0A B4           DEC     <flipScreens        ; Trigger a screen flip
C10C: 13              SYNC                        ; Wait for the draw
C10D: 86 02           LDA     #$02                ; Initial map level for demo is 2 (where the demon lives)
C10F: CE D7 D5        LDU     #$D7D5              ; Demo objects
C112: 20 1D           BRA     $C131               ; Play the demo

EndOfTapeAccess:
C114: CC 34 3C        LDD     #$343C              ; 0011_0100 and 0011_1100
C117: B7 FF 21        STA     PIA1_CA             ; Motor off
C11A: F7 FF 23        STB     PIA1_CB             ; 6-bit Sound enabled
C11D: 4C              INCA                        ; Re-enable ...
C11E: B7 FF 03        STA     PIA0_CB             ; ... 60Hz interrupt
C121: 3C EF           CWAI    $EF                 ; Wait for a 60Hz interrupt to happen
C123: 39              RTS                         ; Done

PlayGame:
C124: 8D EE           BSR     EndOfTapeAccess     ; Configure interrupts and sound
C126: CC 10 0B        LDD     #$100B              ; Starting cell (Y=16, X=0B)
C129: DD 13           STD     <playerY            ; 
C12B: 0F 17           CLR     <pStrength          ; MSB of strength (start out weak)
C12D: 4F              CLRA                        ; Initial map level for a new game is 0 (the first level)
C12E: CE D7 D9        LDU     #$D7D9              ; List of game objects (not demo objects)
;
C131: 3F              SWI                         ; Print "PREPARE!"
C132: 16                                          ; SWI_16:Print PREPARE:
C133: 3F              SWI                         ; Setup the level
C134: 1A                                          ; SWI_1A:Set up level:
C135: 10 8E 02 29     LDY     #$0229              ; Pointer to 1st game object in Y
C139: A6 C0           LDA     ,U+                 ; From the list of objects to make
C13B: 2B 12           BMI     $C14F               ; All done ... start the game
C13D: 3F              SWI                         ; Create the game object (type in A)
C13E: 17                                          ; SWI_17:Create object structure:
C13F: 6C 05           INC     5,X                 ; Object starts out in pack
C141: 1E 13           EXG     X,U                 ; X->U (SWI 18 needs it in U)
C143: 3F              SWI                         ; Initial objects start off revealed
C144: 18                                          ; SWI_18:Change object to proper name and data:
C145: 1E 13           EXG     X,U                 ; Restore X and U
C147: 6F 0B           CLR     11,X                ; Already revealed
C149: AF A4           STX     ,Y                  ; Link this object to last
C14B: 1F 12           TFR     X,Y                 ; This is now last
C14D: 20 EA           BRA     $C139               ; Do all game objects
;
C14F: 0D 77           TST     <gameMode           ; Are we in play-game mode (not demo)?
C151: 27 13           BEQ     $C166               ; Yes ... don't start with the map
C153: 0A 9B           DEC     <suspendTaskTime    ; Suspend the tasks while we show the map for a bit
C155: 8E CD B2        LDX     #$CDB2              ; The routine for drawing ...
C158: 9F B2           STX     <displayFunction    ; ... the scroll (seer and vision)
C15A: 0A 94           DEC     <scrollType         ; This is a SEER scroll
C15C: 3F              SWI                         ; Redraw the display
C15D: 0E                                          ; SWI_E:Display playing screen:
C15E: 3F              SWI                         ; Wait for 1.35 seconds
C15F: 10                                          ; SWI_10:Pause for 1.35 seconds:
C160: 3F              SWI                         ; Another 1.35. Total: 1.35*2 = 2.7 seconds
C161: 10                                          ; SWI_10:Pause for 1.35 seconds:
C162: 0F 9B           CLR     <suspendTaskTime    ; 
C164: 13              SYNC                        ; Wait for two ...
C165: 13              SYNC                        ; ... interrupts
;
C166: 3F              SWI                         ; Draw the screen
C167: 19                                          ; SWI_19:Bring up normal display:
C168: 3F              SWI                         ; Show the command prompt
C169: 0F                                          ; SWI_F:Ready command prompt:
C16A: 7E C1 F5        JMP     GameLoop            ; Back to top of the game loop

ReadCheckError:
; Read a block from tape to buffer. Restart the computer on an error.
; X points to the buffer to fill. Block type returned in B.
C16D: BF 00 7E        STX     CASSPTR             ; Read buffer
C170: 10 3F           SWI2                        ; Read a block ...
C172: 06                                          ; ... (A006: BLKIN) from tape
C173: 4D              TSTA                        ; Error?
C174: 10 26 DE AF     LBNE    $A027               ; Yes ... restart the CoCo
C178: F6 00 7C        LDB     CASSBLKTYPE         ; Return block type
C17B: 39              RTS                         ; Done
 
StartOfTapeAccess:                
C17C: CE FF 00        LDU     #$FF00              ; Base of PIA 0
C17F: CC 34 3C        LDD     #$343C              ; 0011_0100  and 0011_1100
C182: A7 43           STA     3,U                 ; Disable 60Hz interrupt
C184: B7 FF 23        STA     PIA1_CB             ; Disable cartridge-detect interrupt and sound off
C187: F7 FF 21        STB     PIA1_CA             ; Disable RS-232 interrupt and Cassette motor ON
C18A: 39              RTS                         ; Done
                 
QuarterSecDelay:
C18B: 9E 00           LDX     <CONST_00           ; 
C18D: 30 1F           LEAX    -1,X                ; Long ...
C18F: 26 FC           BNE     $C18D               ; ... delay loop
C191: 39              RTS                         ; Done
                 
SaveToTape:
C192: 8D E8           BSR     StartOfTapeAccess   ; Tape motor on
C194: 8D F5           BSR     QuarterSecDelay     ; Wait
C196: 8D F3           BSR     QuarterSecDelay     ; Wait (1/2 second total)
C198: 10 3F           SWI2                        ; Write the tape header
C19A: 0C                                          ; A00C: WRTLDR
C19B: 10 3F           SWI2                        ; Write the filename (we setup this block at D7C9)
C19D: 08                                          ; A008: BLKOUT
C19E: 8D EB           BSR     QuarterSecDelay     ; Wait
C1A0: 10 3F           SWI2                        ; Write the tape header again
C1A2: 0C                                          ; A00C: WRTLDR
C1A3: 8E 02 00        LDX     #$0200              ; Start of variables (the direct page)
C1A6: CC 01 80        LDD     #$0180              ; Block type = 1 (data) ...
C1A9: FD 00 7C        STD     CASSBLKTYPE         ; ... block size = 128 bytes
C1AC: BF 00 7E        STX     CASSPTR             ; Store for BASIC
C1AF: 10 3F           SWI2                        ; Write the block
C1B1: 08                                          ; A008: BLKOUT
C1B2: 8C 0F 05        CMPX    #$0F05              ; Written all of our memory?
C1B5: 25 EF           BCS     $C1A6               ; No ... back for more
C1B7: FF 00 7C        STU     CASSBLKTYPE         ; U was last set at C17C. Clever. Block type = FF (end of file), length = 0
C1BA: 10 3F           SWI2                        ; Write an end block
C1BC: 08                                          ; A008: BLKOUT
C1BD: 8D CC           BSR     QuarterSecDelay     ; Delay
C1BF: 20 2B           BRA     $C1EC               ; Turn off motor and fall into game loop

LoadFromTape:      
C1C1: 8D B9           BSR     StartOfTapeAccess   ; Start tape access
C1C3: 10 3F           SWI2                        ; Tape on and start reading
C1C5: 04                                          ; A004: CRSDON
C1C6: DE 0B           LDU     <backScreen         ; Off screen buffer ...
C1C8: AE C4           LDX     ,U                  ; ... to use as scratch
C1CA: 8D A1           BSR     ReadCheckError      ; Read block
C1CC: 26 F8           BNE     $C1C6               ; Is this a header? No ... keep looking
C1CE: AE C4           LDX     ,U                  ; Where we read the header
C1D0: CE 03 13        LDU     #$0313              ; Parsed filename
C1D3: C6 08           LDB     #$08                ; Is this the ...
C1D5: A6 80           LDA     ,X+                 ; ... requested ...
C1D7: A1 C0           CMPA    ,U+                 ; ... data file?
C1D9: 26 E6           BNE     LoadFromTape        ; No ... find the right header
C1DB: 5A              DECB                        ; Check 8 byte ...
C1DC: 26 F7           BNE     $C1D5               ; ... filename
C1DE: 10 3F           SWI2                        ; Tape on and start reading
C1E0: 04                                          ; A004: CRSDON
C1E1: 8E 02 00        LDX     #$0200              ; Start of variables to load (direct page)
C1E4: 8D 87           BSR     ReadCheckError      ; Read a block
C1E6: 2A FC           BPL     $C1E4               ; Keep reading if block type was not FF (end of file)
C1E8: 10 CE 10 00     LDS     #$1000              ; Reset stack
;
C1EC: BD C1 14        JSR     EndOfTapeAccess     ; Turn off tape and reenable interrupts
C1EF: 0F B8           CLR     <tapeTrigger        ; Tape operation complete
C1F1: 3F              SWI                         ; Draw normal display
C1F2: 19                                          ; SWI_19:Bring up normal display:
C1F3: 3F              SWI                         ; Draw ready prompt
C1F4: 0F                                          ; SWI_F:Ready command prompt:
; Fall into game loop

Tasks

The code runs as a sequence of timed tasks that are re-queued/removed as needed.

A task structure is 7 bytes as follows:

  00:01  Next task in the list or 0 if the last task in the list.
  02     Countdown to run. When this reaches 0, the task is moved to the ready-to-run list.
  03:04  Handler entry point. This is the task's code.
  05:06  Pointer to the monster structure (only for monster tasks)

Task pool

There is a pool of task structures from 09FD through 0B05 (38 total structures). The word at 02B9 points to the next-available task structure. Tasks are created by advancing this pointer to remove a structure from the pool.

All tasks are removed and recreated as part of setting up the level. No task survives between levels.

Task timers

Tasks can appear on seven different timed lists. The timer interval is how often the task's counter is decremented. When the counter reaches zero, the task is moved to the "ready-to-run" list.

There are seven different lists that a task can be placed on: - Instant tasks. A list is reserved for this, but the use is not implemented. - ISR count tasks. These tasks are timed directly by the ISR (60Hz). - Tenths of a second tasks. These are timed down every 6 ISRs (10 times a second). - Seconds tasks. These are timed down once a second. - Minutes tasks. Timed down once a minute. - Hours tasks. Timed down once an hour. - Ready to run. Tasks are moved here to be run by the game loop and then moved back to the other lists.

There are five game tasks that manage general game play. And each monster gets a "handler task". There are 32 maximum monsters on a level (usually less) plus the 5 game tasks means a max of 37 task structures. The pool has room for 38. It is nicely sized.

The list at D7DC contains the game tasks: - D1EB T0_PlayerInput - D1C2 T1_Draw3DScreen - D1D5 T2_UpdateHeart - D19B T3_UpdateTorch - D7E4 T4_MakeCreature

Each creature gets a copy of the handler task: - D041 T5_MoveCreature

T0: Player Input Task

This tasks processes input from the user (or demo commands). It runs every single ISR tick (60Hz).

T1: Draw 3D Screen

This task redraws the 3D maze. It does NOT redraw the inventory screen or the map display. It runs on the tenths-of-a-second list with a countdown of 3 (every 3 tenths of a second).

T2: Update Heart Rate

This task updates the heart rate and handles fainting/recovery. It runs on the ISR tick, but the countdown depends on the heartrate itself.

T3: Update Torch

Torches burn down over time. This task manages the timing on the one-minute tick list -- one bump every minute.

T4: Make Creature

This task runs on the minute list -- once every 5 minutes. Every time it runs, the task creates a random creature that will appear on the CURRENT level when/if the player returns to this level. This is your punishment for climbing up to previous levels. The longer you hang out on a level, the more creatures will be waiting for you next time you come.

The task creates a random creature (but not: Wizard, Demon, Spider, Snake). There is a max of 32 creatures on any level. This task could refill all 32 creatures in 32*5 minutes ... just over two and a half hours.

T5: Handle Creature

Every monster gets a handler task. The task structure includes a pointer to the monster's data. Among other things, this structure contains the task reload rate for the tenth-of-a-second list. Faster creatures have lower reload rates.

TODO

- ReserveTask C25C - InitTasks C053 - UnchainTask C238 - TimeDownTasks C242 - Task timers by ISR (counter ends at C324) - Ready-to-run task list - Task runners in main loop - Running/reinitialize a task - CreateCreature makes task CFA5

Game Loop

This is the game loop. The interrupt service routine times all the game tasks and moves them to the "ready-to-run" list when they are ready to go. This loop runs the tasks that are ready to run.

This code also handles the tape save/loads.

The game tasks themselves can re-initialize all the task lists. This happens when the game switches level. When that happens, the game loop needs to restart at the top of the list instead of continuing to the next task. The flag at $BB tells the loop to restart.

GameLoop: 
C1F5: CE 02 AB        LDU     #$02AB              ; Start of ready-to-run tasks
C1F8: 0F BB           CLR     <taskListsRebuilt   ; We are starting at the top of the task list
C1FA: 1F 32           TFR     U,Y                 ; Hold start of list
C1FC: 0D B8           TST     <tapeTrigger        ; ZSAVE or ZLOAD requested?
C1FE: 2E 92           BGT     SaveToTape          ; ZSAVE ... go do it
C200: 2B BF           BMI     LoadFromTape        ; ZLOAD ... go do it
C202: EE C4           LDU     ,U                  ; Next runable task
C204: 27 EF           BEQ     GameLoop            ; No more tasks to run ... back to top
;
C206: 34 60           PSHS    U,Y                 ; Hold registers
C208: AD D8 03        JSR     [$03,U]             ; Execute game task (return reload in A, list number in B)
C20B: 35 60           PULS    Y,U                 ; Restore
;
C20D: 0D BB           TST     <taskListsRebuilt   ; Task list was rebuilt (as in change of level)?
C20F: 26 E4           BNE     GameLoop            ; Yes ... restart the task-run from the first
C211: C1 0C           CMPB    #$0C                ; Task needs running again?
C213: 27 E5           BEQ     $C1FA               ; Yes ... keep running it
C215: 8D 21           BSR     UnchainTask         ; Remove the task from its current list
C217: 8D 04           BSR     ChainTaskToEnd      ; Add it to the end of its target list
C219: 1F 23           TFR     Y,U                 ; Next task
C21B: 20 DF           BRA     $C1FC               ; Do all tasks

ChainTaskToEnd:
; Add the task U to the end of a linked task list
; U is task to add
; A is countdown timer reload
; B is offset to the target list -- the index in the list of lists
C21D: 34 17           PSHS    X,B,A,CC            ; Preserve
C21F: 1A 10           ORCC    #$10                ; Turn OFF the IRQ interrupt
C221: A7 42           STA     2,U                 ; Reload the countdown timer
C223: 8E 02 9F        LDX     #$029F              ; Start of task slots
C226: 3A              ABX                         ; Where to insert in the list
C227: 4F              CLRA                        ; This target task is ...
C228: 5F              CLRB                        ; ... now ...
C229: ED C4           STD     ,U                  ; ... the end of the list
C22B: 10 A3 84        CMPD    ,X                  ; Are we at the previous ...
C22E: 27 04           BEQ     $C234               ; ... end of list?
C230: AE 84           LDX     ,X                  ; No ... move to next task and ...
C232: 20 F7           BRA     $C22B               ; ... keep looking for end
C234: EF 84           STU     ,X                  ; Chain the target task to the end
C236: 35 97           PULS    CC,A,B,X,PC         ; Restore

UnchainTask:
; Remove a task from its linked list of tasks
; U points to target task to remove
; Y points to parent of target task
C238: 34 11           PSHS    X,CC                ; Preserve
C23A: 1A 10           ORCC    #$10                ; Turn OFF the IRQ interrupt
C23C: AE C4           LDX     ,U                  ; Get pointer to next task (or end marker)
C23E: AF A4           STX     ,Y                  ; Change parent to point to next
C240: 35 91           PULS    CC,X,PC             ; Restore

TimeDownTasks:
; Decrement the counters on all tasks of a single list. When they reach zero, move
; the tasks to the ready-to-run list
C242: 34 74           PSHS    U,Y,X,B             ; Preserve
C244: 0D 9B           TST     <suspendTaskTime    ; Is the main loop showing demo scroll?
C246: 26 12           BNE     $C25A               ; Yes ... skip task timing
C248: 1F 32           TFR     U,Y                 ; Y=Parent of task
C24A: EE C4           LDU     ,U                  ; U=Current task
C24C: 27 0C           BEQ     $C25A               ; End of list ... we are done
C24E: 6A 42           DEC     2,U                 ; Time for this task to run?
C250: 26 F6           BNE     $C248               ; No ... leave it be
C252: 8D E4           BSR     UnchainTask         ; Pull the task from its list
C254: C6 0C           LDB     #$0C                ; Move the task ...
C256: 8D C5           BSR     ChainTaskToEnd      ; ... to the ready to run list
C258: 20 EE           BRA     $C248               ; Keep timing down all tasks
C25A: 35 F4           PULS    B,X,Y,U,PC          ; Restore

ReserveTask:
; Move the next-task-pointer to the next seven-byte slot.
; Return reserved slot pointer in U.
C25C: 34 10           PSHS    X                   ; Hold X
C25E: DE B9           LDU     <nextTask           ; Get the next-free structure pointer
C260: 30 47           LEAX    7,U                 ; Point to next structure
C262: 9F B9           STX     <nextTask           ; New next-free structure pointer
C264: 35 90           PULS    X,PC                ; Out

WriteToSAM:
; The SAM chip is mapped only to the address bus. Writing to an even adress
; clears the target register bit. Writing to the next (odd) address sets the
; bit. This routine copies the 10-bit value in D to the first 10 SAM registers.
;
; The SAM is 16 bits and the value passed is 16 bits, and looks correct for
; the full register set. But this routine only changes the lowest 10 bits.
;
; F6 F5 F4 F3 F2 F1 F0 V2 V1 V0
;
; V is the video mode
; F is the video memory address (F*512 is the address)
;
C266: 34 16           PSHS    X,B,A               ; Preserve the registers
C268: 8E FF C0        LDX     #$FFC0              ; Start of SAM memory
C26B: 44              LSRA                        ; Next bit ...
C26C: 56              RORB                        ; ... into carry
C26D: 25 03           BCS     $C272               ; It is a one ... set the bit
C26F: A7 84           STA     ,X                  ; Set the zero (even address)
C271: 8C                  ; CMPX  opcode to skip next instruction
C272: A7 01           STA     1,X                 ; Set the one (odd address)
C274: 30 02           LEAX    2,X                 ; Next register bit
C276: 8C FF D4        CMPX    #$FFD4              ; All done?
C279: 25 F0           BCS     $C26B               ; No ... keep going
C27B: 35 96           PULS    A,B,X,PC            ; Restore and out

Interrupt Service

InterruptServiceRoutine: 
C27D: 8E FF 20        LDX     #$FF20              ; 6-bit sound value
C280: A6 88 E3        LDA     -$1D,X              ; FF03 ... 16.67MS (60Hz) interrupt status
C283: 10 2A 00 99     LBPL    $C320               ; Upper bit 0 ... must have been the horizontal ... ignore
C287: 86 02           LDA     #$02                ; Set DP to ...
C289: 1F 8B           TFR     A,DP                ; ... base 02xx (in case we are interrupting a BASIC routine)
C28B: 0D B4           TST     <flipScreens        ; Time to flip screens?
C28D: 27 0E           BEQ     $C29D               ; No ... keep what we have
C28F: DC 09           LDD     <activeScreen       ; Get the current visible
C291: DE 0B           LDU     <backScreen         ; Get the current drawing
C293: DD 0B           STD     <backScreen         ; Flip the ...
C295: DF 09           STU     <activeScreen       ; ... visible and drawing screens
C297: EC 44           LDD     4,U                 ; Get the SAM settings for the new visible screen
C299: 8D CB           BSR     WriteToSAM          ; Set the SAM registers to flip the screen
C29B: 0F B4           CLR     <flipScreens        ; Acknowledge the flip
;
C29D: 0D 9C           TST     <beamSound          ; Is the wizard beaming in or out (cut scenes)?
C29F: 27 08           BEQ     $C2A9               ; No ... skip it
C2A1: 03 9D           COM     <beamSoundVal       ; Toggle the wizard sound square wave
C2A3: 96 9D           LDA     <beamSoundVal       ; Get sound value
C2A5: 48              ASLA                        ; 8 bit to ...
C2A6: 48              ASLA                        ; ... 6 bit value (divide by 4)
C2A7: A7 84           STA     ,X                  ; Store to FF20 (6 bit sound)
;
C2A9: 0D B1           TST     <hearHeart          ; Are we between rounds?
C2AB: 27 2F           BEQ     $C2DC               ; Yes .. no heart
C2AD: 0A AE           DEC     <heartCounter       ; Time to change heart pattern?
C2AF: 26 2B           BNE     $C2DC               ; No ... skip it
C2B1: 96 AF           LDA     <heartCounterRel    ; Reload the ...
C2B3: 97 AE           STA     <heartCounter       ; ... heart counter
C2B5: E6 02           LDB     2,X                 ; FF22 ... current single-bit sound
C2B7: C8 02           EORB    #$02                ; Toggle the single-bit ...
C2B9: E7 02           STB     2,X                 ; ... sound (makes a pop)
C2BB: 0D AD           TST     <scrollShowing      ; Scroll showing?
C2BD: 27 1D           BEQ     $C2DC               ; Yes ... skip drawing the heart
C2BF: CE 03 88        LDU     #$0388              ; Hand line area ?active or inactive?
C2C2: AE 44           LDX     4,U                 ; Hold onto current cursor (we might be printing)
C2C4: CC 00 0F        LDD     #$000F              ; New cursor ...
C2C7: ED 44           STD     4,U                 ; ... middle of the line
C2C9: 86 20           LDA     #$20                ; 20, 21 ... small-heart characters
C2CB: 03 B0           COM     <heartPicture       ; Toggle heart picture tracking
C2CD: 27 02           BEQ     $C2D1               ; Zero now? Draw the small heart
C2CF: 86 22           LDA     #$22                ; 22, 23 ... large-heart characters
C2D1: BD CA 17        JSR     PrintRegChar        ; Draw the first heart character
C2D4: 6C 45           INC     5,U                 ; Bump the cursor for the second picture
C2D6: 4C              INCA                        ; Second heart picture
C2D7: BD CA 17        JSR     PrintRegChar        ; Draw the second heart character
C2DA: AF 44           STX     4,U                 ; Restore the text cursor
;
C2DC: CE 02 A1        LDU     #$02A1              ; Run quick tasks ...
C2DF: BD C2 42        JSR     TimeDownTasks       ; ... once every interrupt
;
C2E2: 8E 02 95        LDX     #$0295              ; Start of counters for tasks
C2E5: 10 8E C3 24     LDY     #$C324              ; Counter end points
C2E9: 6C 84           INC     ,X                  ; Bump this counter
C2EB: 8C 02 9A        CMPX    #$029A              ; All counters done? (did we just bump days)
C2EE: 27 0F           BEQ     $C2FF               ; Yes ... done (nothing runs on the day bump)
C2F0: A6 84           LDA     ,X                  ; Get the counter value
C2F2: A1 A0           CMPA    ,Y+                 ; Overflowed?
C2F4: 2D 09           BLT     $C2FF               ; No ... not time to do anything
C2F6: 6F 80           CLR     ,X+                 ; Restart the counter
C2F8: 33 42           LEAU    2,U                 ; Pointer to list
C2FA: BD C2 42        JSR     TimeDownTasks       ; Time down the list of tasks and queue any that are ready to run
C2FD: 20 EA           BRA     $C2E9               ; Carry over into next timed task
;
C2FF: 0D 28           TST     <fainting           ; Are we fainting?
C301: 26 1D           BNE     $C320               ; Yes .. ignore the keyboard
C303: 0D 77           TST     <gameMode           ; Are we in a live game?
C305: 27 11           BEQ     $C318               ; Yes ... don't restart the game on a key
C307: 7F FF 02        CLR     PIA0_DB             ; Activate all keyboard columns
C30A: B6 FF 00        LDA     PIA0_DA             ; Check all rows
C30D: 84 7F           ANDA    #$7F                ; Ignore the joystick bit
C30F: 81 7F           CMPA    #$7F                ; Any key pressed?
C311: 27 0D           BEQ     $C320               ; No ... skip processing the key
C313: 8E C0 05        LDX     #$C005              ; Any key was pressed ... start a new game
C316: AF 6A           STX     10,S                ; Return address
C318: 10 3F           SWI2                        ; BASIC function ...
C31A: 00                                          ; ... POLCAT
C31B: 4D              TSTA                        ; Was it a valid key (not, say, SHIFT)
C31C: 27 02           BEQ     $C320               ; No ... don't store it (but we are still starting a new game)
C31E: 8D 20           BSR     CharToBuf           ; Store character in ring buffer
;
C320: B6 FF 02        LDA     PIA0_DB             ; Acknowledge the interrupt so it can fire again
C323: 3B              RTI                         ; Return from interrupt

; Counter end points for task timings
C324: 06 ; Every 6 interrupts ... once every 0.1 seconds
C325: 0A ; Every 10 ... once every second
C326: 3C ; Every 60 ... once every minute
C327: 3C ; Every 60 ... once every hour
C328: 18 ; Every 24 ... once every day

CharFromBuf:
; Read character A from input ring buffer and advance the tail. Return 0
; if nothing to read.
C329: 34 15           PSHS    X,B,CC              ; Save
C32B: 1A 10           ORCC    #$10                ; Turn OFF the IRQ interrupt
C32D: 4F              CLRA                        ; Initial return ... no key in buffer
C32E: 8E 02 D1        LDX     #$02D1              ; 32-byte input ring buffer
C331: D6 BC           LDB     <inputHead          ; The ring-buffer head
C333: D1 BD           CMPB    <inputTail          ; Same as the ring-buffer tail?
C335: 27 07           BEQ     $C33E               ; Yes ... return 0 (no input)
C337: A6 85           LDA     B,X                 ; Get the next character from the head
C339: 5C              INCB                        ; Advance the head ...
C33A: C4 1F           ANDB    #$1F                ; ... and wrap ...
C33C: D7 BC           STB     <inputHead          ; ... if needed
C33E: 35 95           PULS    CC,B,X,PC           ; Done

CharToBuf:
; Save character A to input ring buffer and advance tail
C340: 34 15           PSHS    X,B,CC              ; Save all
C342: 1A 10           ORCC    #$10                ; Turn OFF the IRQ interrupt
C344: 8E 02 D1        LDX     #$02D1              ; 32-byte ring buffer
C347: D6 BD           LDB     <inputTail          ; Get tail index
C349: A7 85           STA     B,X                 ; Store the character to the tail
C34B: 5C              INCB                        ; Advance the tail ...
C34C: C4 1F           ANDB    #$1F                ; ... and wrap ...
C34E: D7 BD           STB     <inputTail          ; ... if needed
C350: 35 95           PULS    CC,B,X,PC           ; Done

SWI Handler

TODO discussion about this technique

TODO Immediate data and address links

SWI Immediate Data Address Function
00 Set light level
01 Draw picture X on screen
02 Uncompress message m and display
03 Display uncompressed message X
04 Display a single character A
05 Uncompress message X to buffer
06 Uncompress message X to buffer U
07 Get random number
08 Clear display screen
09 Clear secondary screen
0A Clear hand descriptor
0B Clear play field
0C Update heart rate
0D Print hands
0E Display playing screen
0F Ready command prompt
10 Pause for 1.35 seconds
11 Fill X to U with 0s
12 Fill X to U with FFs
13 Beam on picture X
14 Beam subroutine
15 Beam subroutine
16 Print PREPARE
17 Create object structure
18 Change object to proper
19 Bring up normal display
1A Build level
1B Play sound i at full volume
1C Play sound A at volume B
SWIHandler:
;
C352: 1C EF           ANDCC   #$EF                ; Re-enable the IRQ
C354: AE 6A           LDX     10,S                ; The Program Counter in the calling frame
C356: A6 80           LDA     ,X+                 ; Get the interrupt number immediate
C358: AF 6A           STX     10,S                ; Update the calling frame program counter
C35A: 8E C3 84        LDX     #$C384              ; Offset of first routine
C35D: CE C9 95        LDU     #$C995              ; SWI routine offset bytes
C360: E6 C0           LDB     ,U+                 ; Get offset byte to routine
C362: 3A              ABX                         ; Add it to code pointer
C363: 4A              DECA                        ; Found the one we are looking for?
C364: 2A FA           BPL     $C360               ; No ... keep off-setting
C366: AF E3           STX     ,--S                ; Push the address of the routine on the stack
C368: EC 63           LDD     3,S                 ; A and B passed from caller
C36A: AE 66           LDX     6,S                 ; X from the caller
C36C: EE 6A           LDU     10,S                ; U from the caller
C36E: AD F1           JSR     [,S++]              ; Call the SWI routine
C370: 3B              RTI                         ; Return to caller

SWI2Handler:
; Execute one of the vectored routines in the BASIC ROM
; 00 = POLCAT
; 02 = CHROUT
; 04 = CSRDON
; 06 = BLKIN
; 08 = BLKOUT
; 0A = JOYIN
; 0C = WRTLDR
;
C371: 5F              CLRB                        ; BASIC functions need ...
C372: 1F 9B           TFR     B,DP                ; ... DP = 0
C374: EE 6A           LDU     10,S                ; The Program Counter in the calling frame
C376: E6 C0           LDB     ,U+                 ; Get the interrupt number immediate
C378: EF 6A           STU     10,S                ; Update the calling frame program counter
C37A: CE A0 00        LDU     #$A000              ; BASIC function jump table
C37D: AD D5           JSR     [B,U]               ; Call the BASIC function
C37F: A7 61           STA     1,S                 ; Return A value to caller
C381: AF 64           STX     4,S                 ; Return Y value to caller
C383: 3B              RTI                         ; Return to caller

SWI_0:
; Light level
C384: 96 6E           LDA     <m026E              ; 
C386: 0D 75           TST     <m0275              ; 
C388: 27 04           BEQ     $C38E               ; 
C38A: 96 6F           LDA     <m026F              ; 
C38C: 0F 75           CLR     <m0275              ; 
C38E: 5F              CLRB                        
C38F: 80 07           SUBA    #$07                
C391: 90 8B           SUBA    <drwMazeCellNum     ; 
C393: 2C 0A           BGE     $C39F               ; 
C395: 5A              DECB                        
C396: 81 F9           CMPA    #$F9                
C398: 2F 05           BLE     $C39F               ; 
C39A: 8E CB 96        LDX     #$CB96              
C39D: E6 86           LDB     A,X                 
C39F: D7 2D           STB     <dotFrequency       ; New dot frequency
C3A1: 39              RTS                         

SWI_1: 
; Draw picture X on screen
;  X: points to picture script
;
C3A2: 0F 51           CLR     <continueLine       ; Starting new line segment
C3A4: 96 2D           LDA     <dotFrequency       ; Dot Frequency
C3A6: 4C              INCA                        ; Anything to draw?
C3A7: 27 4D           BEQ     $C3F6               ; No, out
;
C3A9: E6 84           LDB     ,X                  ; Else get command
C3AB: C0 FA           SUBB    #$FA                ; Is this a command?
C3AD: 25 20           BCS     $C3CF               ; No, go to standard line
C3AF: 30 01           LEAX    1,X                 ; Next in list
C3B1: 10 8E C3 B9     LDY     #$C3B9              ; Graphics Commands
C3B5: E6 A5           LDB     B,Y                 ; Get offset
C3B7: 6E A5           JMP     B,Y                 ; Go to command
;
; Special graphics commands
;        00-FA: Standard line command
C3B9: 10  ; FA: Return from graphics subroutine
C3BA: 06  ; FB: Jump to subroutine
C3BB: 5E  ; FC: Multiple short segments
C3BC: 0D  ; FD: Jump to xxxx
C3BD: 3D  ; FE: Exit
C3BE: 12  ; FF: Start a new segment
;
; Command FB: Jump to subroutine
C3BF: EC 81           LDD     ,X++                ; Get new address
C3C1: AF E3           STX     ,--S                ; Save return
C3C3: 1F 01           TFR     D,X                 ; D->X
; Command FD: Jump to XXXX
C3C5: 8C                  ; CMPX  opcode to skip next instruction
C3C6: AE 84           LDX     ,X                  ; Jump address from X
; Command FA: Return from graphics subroutine
C3C8: 8C                  ; CMPX  opcode to skip next instruction
C3C9: AE E1           LDX     ,S++                ; Jump address from stack
; Command FF: Start a new segment
C3CB: 0F 51           CLR     <continueLine       ; New segment
C3CD: 20 DA           BRA     $C3A9               ; Continue
;
; Regular line command
C3CF: 0D 51           TST     <continueLine       ; Already have start point?
C3D1: 26 06           BNE     $C3D9               ; Yes ... get second coordinate and draw line
C3D3: 8D 0D           BSR     $C3E2               ; No ... get first coordinate and return (nothing drawn)
C3D5: 0A 51           DEC     <continueLine       ; Flag that now we have a continuation point
C3D7: 20 D0           BRA     $C3A9               ; Continue
;
C3D9: 8D 05           BSR     $C3E0               ; Set up one coordinate continued for line
C3DB: BD CA B7        JSR     DrawLine            ; Draw line
C3DE: 20 C9           BRA     $C3A9               ; Back for more
;
C3E0: 8D 15           BSR     $C3F7               ; Move old end to new start
C3E2: E6 80           LDB     ,X+                 ; Y coordinate
C3E4: D7 54           STB     <m0254              ; Hold on to it
C3E6: 8D 18           BSR     ScaleYCoord         ; Scale the Y coordinate
C3E8: D3 07           ADDD    <m0207              ; Y center of screen
C3EA: DD 33           STD     <oldPointY          ; Store new end Y
C3EC: E6 80           LDB     ,X+                 ; X coordinate
C3EE: D7 52           STB     <m0252              ; Hold on to it
C3F0: 8D 14           BSR     ScaleXCoord         ; Scale the X coordinate
C3F2: D3 05           ADDD    <m0205              ; X center of screen
C3F4: DD 35           STD     <oldPointX          ; Store new end X
; Command FE: Exit
C3F6: 39              RTS                         ; Done
;
C3F7: DC 33           LDD     <oldPointY          ; Move old Y...
C3F9: DD 2F           STD     <newPointY          ; ... to new Y
C3FB: DC 35           LDD     <oldPointX          ; Move old X
C3FD: DD 31           STD     <newPointX          ; ... to new X
C3FF: 39              RTS                         ; Done
;
; The scaling factor is a fractional value with 128 treated as one. Values above 128 expand the picture.
; Values below 128 shrink the picture.
;
ScaleYCoord:
C400: 96 50           LDA     <yScaleFactor       ; Y Scale factor
C402: D0 08           SUBB    <m0207+1            ; Offset coordinate from Y center of screen
C404: 20 04           BRA     $C40A               ; Handle signed multiply
;
ScaleXCoord:
C406: 96 4F           LDA     <xScaleFactor       ; X scale factor
C408: D0 06           SUBB    <m0205+1            ; Offset coordinate from X center of screen
;
C40A: 25 03           BCS     $C40F               ; Value is negative ... handle the sign manually
;
C40C: 3D              MUL                         ; Value is positive ... normal multiply
C40D: 20 05           BRA     $C414               ; And divide by 128
;
C40F: 50              NEGB                        ; Make the negative value a positive
C410: 3D              MUL                         ; Do multiply
C411: BD CA 99        JSR     NegativeD           ; Negate D
;
C414: 7E D3 77        JMP     DRight7             ; Divide D by 128 (fractional math)
;
; Command FC: Multiple short segments
C417: A6 80           LDA     ,X+                 ; Next description
C419: 27 B0           BEQ     $C3CB               ; 0 means done
C41B: 8D DA           BSR     $C3F7               ; Move old end to new beginning
C41D: E6 1F           LDB     -1,X                ; Byte
C41F: 57              ASRB                        ; Upper ...
C420: 57              ASRB                        ; ... 4 bits ...
C421: 57              ASRB                        ; ... ...
C422: 57              ASRB                        ; ... ...
C423: 58              ASLB                        ; ... *2
C424: DB 54           ADDB    <m0254              ; Add to old Y
C426: D7 54           STB     <m0254              ; New Y
C428: 8D D6           BSR     ScaleYCoord         ; Do multiply and prepare
C42A: D3 07           ADDD    <m0207              ; Offset center of screen
C42C: DD 33           STD     <oldPointY          ; Save new Y
C42E: E6 1F           LDB     -1,X                ; Descriptor
C430: C4 0F           ANDB    #$0F                ; Lower four bits
C432: C5 08           BITB    #$08                ; Is this negative?
C434: 27 02           BEQ     $C438               ; No,
C436: CA F0           ORB     #$F0                ; Else make it negative
C438: 58              ASLB                        ; *2
C439: DB 52           ADDB    <m0252              ; Offset X coordinate
C43B: D7 52           STB     <m0252              ; Store New
C43D: 8D C7           BSR     ScaleXCoord         ; Scale it
C43F: D3 05           ADDD    <m0205              ; Add offset to center
C441: DD 35           STD     <oldPointX          ; Absolute coordinate
C443: BD CA B7        JSR     DrawLine            ; Draw line segment
C446: 20 CF           BRA     $C417               ; Continue multiple segments

SWI_2:
; Uncompress message m and display
;  Message bytes are in the code at the call site. Flow continues
;  after the compressed data.
;
C448: AE 6C           LDX     12,S                ; PC from stack
C44A: 3F              SWI                         ; Decompress the message
C44B: 05                                          ; SWI_5:Uncompress message X to buffer:
C44C: AF 6C           STX     12,S                ; Update the PC to skip message
C44E: 8E 03 35        LDX     #$0335              ; Temporary buffer
C451: 8C                  ; CMPX  opcode to skip next instruction
C452: 3F              SWI                         ; Print character in A
C453: 04                                          ; SWI_4:Display a single character in A:

SWI_3:
; Display uncompressed message pointed to by X
;  X: points to uncompressed data
C454: A6 80           LDA     ,X+                 ; Next character from X
C456: 2A FA           BPL     $C452               ; Printable ... do it
C458: 39              RTS                         ; End of string

SWI_4:
; Display a single character in A
;  The destination depends on $B7. If B7==0, the command-area descriptor is used. If
;  B7!=0, then the descriptor is passed in U.
;  A: the character
;  U: the area descriptor (ignored if $B7==0)
C459: 0D B7           TST     <whereToPrint       ; Put text in command window?
C45B: 26 03           BNE     $C460               ; No ... use the requested descriptor
C45D: CE 03 90        LDU     #$0390              ; Yes ... print on the upper half of the screen
C460: AE 44           LDX     4,U                 ; Current cursor
C462: BD C9 B2        JSR     PrintCharCRBS       ; Draw the character and advance the cursor
C465: AC 42           CMPX    2,U                 ; Filled this area up?
C467: 25 03           BCS     $C46C               ; No ... no scrolling
C469: BD C9 D4        JSR     ScrollTextArea      ; Yes ... scroll the text area
C46C: AF 44           STX     4,U                 ; New text cursor offset
C46E: 39              RTS                         ; Done

SWI_5:
; Uncompress message X to buffer
;  X: the compressed message
C46F: CE 03 35        LDU     #$0335              

SWI_6:
; Uncompress message X to given buffer U
;  X: the compressed message
;  U: the buffer
C472: 31 5F           LEAY    -1,U                ; First in buffer holds the algorithm spot
C474: 6F A4           CLR     ,Y                  ; Start with 0
C476: 8D 14           BSR     $C48C               ; Get next byte to B
C478: 1F 98           TFR     B,A                 ; A holds the length
C47A: 8D 10           BSR     $C48C               ; Get the byte
C47C: E7 C0           STB     ,U+                 ; Store to buffer
C47E: 4A              DECA                        ; All done?
C47F: 2A F9           BPL     $C47A               ; No ... keep going
C481: A7 C4           STA     ,U                  ; Store terminator FF
C483: 6D A4           TST     ,Y                  ; Did the algorithm finish on a byte boundary?
C485: 27 02           BEQ     $C489               ; Yes ... X is pointing to next correctly
C487: 30 01           LEAX    1,X                 ; Advance ...
C489: AF 66           STX     6,S                 ; ... X to next message
C48B: 39              RTS                         ; Done

; Uncompress routine
; Y points to algorithm number
; Return byte in B (5 bits)
; Advance compression to next
;
; The algorithm decompresses 8 5-bit values into 5 bytes
; There are 8 algorithm steps to peel out the 5 bit value and advance the pointer
; if the next step needs it advanced.
;
; AAAAABBB BBCCCCCD DDDDEEEE EFFFFFGG GGGHHHHH
;
C48C: 34 42           PSHS    U,A                 ; Hold buffer and length
C48E: A6 A4           LDA     ,Y                  ; Get algorithm spot
C490: CE C4 A2        LDU     #$C4A2              ; Offset table
C493: A6 C6           LDA     A,U                 ; Get offset
C495: AD C6           JSR     A,U                 ; Execute next decompress step
C497: A6 A4           LDA     ,Y                  ; Bump ...
C499: 4C              INCA                        ; ... to next step
C49A: 84 07           ANDA    #$07                ; Rolls back to 0
C49C: A7 A4           STA     ,Y                  ; Next step
C49E: C4 1F           ANDB    #$1F                ; Decompressed is 5 bit
C4A0: 35 C2           PULS    A,U,PC              ; Return
;
C4A2: 08 ; C4A2 + 08 = C4AA  AAAAA
C4A3: 0E ; C4A2 + 0E = C4B0  BBBBB
C4A4: 13 ; C4A2 + 13 = C4B5  CCCCC
C4A5: 17 ; C4A2 + 17 = C4B9  DDDDD
C4A6: 1C ; C4A2 + 1C = C4BE  EEEEE
C4A7: 21 ; C4A2 + 21 = C4C3  FFFFF
C4A8: 25 ; C4A2 + 25 = C4C7  GGGGG
C4A9: 2A ; C4A2 + 2A = C4CC  HHHHH
;
; Get AAAAA
C4AA: E6 84           LDB     ,X                  ; B = [X]
C4AC: 54              LSRB                        ; B = B >> 3  (0 in bit 7)
C4AD: 54              LSRB                        ; ...
C4AE: 54              LSRB                        ; ...
C4AF: 39              RTS                         ; Done
;
; Get BBBBB
C4B0: EC 80           LDD     ,X+                 ; D = [X++]
C4B2: 7E D3 79        JMP     DRight6             ; D = D>>6
;
; Get CCCCC
C4B5: E6 84           LDB     ,X                  ; B = [X]
C4B7: 20 F5           BRA     $C4AE               ; B = B>>1
;
; Get DDDDD
C4B9: EC 80           LDD     ,X+                 ; D = [X++]
C4BB: 7E D3 7D        JMP     DRight4             ; D = D>>4
;
; Get EEEEE
C4BE: EC 80           LDD     ,X+                 ; D = [X++]
C4C0: 7E D3 77        JMP     DRight7             ; D = D>>7
;
; Get FFFFF
C4C3: E6 84           LDB     ,X                  ; B = [X]
C4C5: 20 E6           BRA     $C4AD               ; B = B>>2
;
; Get GGGGG
C4C7: EC 80           LDD     ,X+                 ; D = [X++]
C4C9: 7E D3 7B        JMP     DRight5             ; D = D>>5
;
; Get HHHHH
C4CC: E6 80           LDB     ,X+                 ; B = [X++]
C4CE: 39              RTS                         ; Done

SWI_7:
; Get random number
;  Return A: random byte
C4CF: 8E 00 08        LDX     #$0008              ; 8 rolls
;
C4D2: 5F              CLRB                        ; Count of 1's
C4D3: 10 8E 00 08     LDY     #$0008              ; Counting 8 bits in the byte
C4D7: 96 6D           LDA     <rndSeedC           ; Upper most seed
C4D9: 84 E1           ANDA    #$E1                ; 1110_0001
C4DB: 48              ASLA                        ; Count ...
C4DC: 24 01           BCC     $C4DF               ; ... the ...
C4DE: 5C              INCB                        ; ... 1's ...
C4DF: 31 3F           LEAY    -1,Y                ; ... in the ...
C4E1: 26 F8           BNE     $C4DB               ; ... value in A
;
C4E3: 54              LSRB                        ; 1 to carry if number of 1's was odd
C4E4: 09 6B           ROL     <rndSeedA           ; Three ...
C4E6: 09 6C           ROL     <rndSeedB           ; ... byte ...
C4E8: 09 6D           ROL     <rndSeedC           ; ... roll ...
C4EA: 30 1F           LEAX    -1,X                ; ... with B going ...
C4EC: 26 E4           BNE     $C4D2               ; ... far right ...
;
C4EE: 96 6B           LDA     <rndSeedA           ; 
C4F0: A7 63           STA     3,S                 ; Return the value in A
C4F2: 39              RTS                         ; Done

SWI_8:
; Clear display screen
;
C4F3: DE 09           LDU     <activeScreen       ; U = Visible screen descriptor
C4F5: 8C                  ; CMPX  opcode to skip next instruction
;
SWI_9:
; Clear secondary screen
;
C4F6: DE 0B           LDU     <backScreen         ; Drawing screen descriptor
C4F8: D6 2C           LDB     <backgroundColor    ; Background color (00 or FF)
C4FA: 8D 1B           BSR     $C517               ; Clear the area
C4FC: EF 6A           STU     10,S                ; Return pointer to the descriptor
C4FE: 39              RTS                         ; Done

SWI_A:
; Clear hand descriptor
;  (both screen buffers)
C4FF: 8E 03 88        LDX     #$0388              ; Hand descriptor space
C502: CE D8 7C        LDU     #$D87C              ; Clearing Data
C505: 20 06           BRA     $C50D               ; Clear out hand descriptor

SWI_B:
; Clear play field
;  (both screen buffers)
C507: 8E 03 90        LDX     #$0390              ; Playing field
C50A: CE D8 88        LDU     #$D888              ; 1st screen buffer area
;
C50D: 6F 04           CLR     4,X                 ; Move cursor...
C50F: 6F 05           CLR     5,X                 ; ... to beginning
C511: E6 06           LDB     6,X                 ; Color
C513: 8D 02           BSR     $C517               ; Clear space pointed to by U
C515: 33 46           LEAU    6,U                 ; Now clear 2nd screen buffer area
;
C517: 34 76           PSHS    U,Y,X,B,A           ; Hold all
C519: 1D              SEX                         ; Expand color mask to word
C51A: 1F 02           TFR     D,Y                 ; D->Y for a double word
C51C: 30 C4           LEAX    ,U                  ; First address in space
C51E: EE 42           LDU     2,U                 ; Last address in space
C520: 36 26           PSHU    Y,B,A               ; Wipe 2 word area, back up two
C522: 11 A3 84        CMPU    ,X                  ; Done?
C525: 26 F9           BNE     $C520               ; No, do all
C527: 35 F6           PULS    A,B,X,Y,U,PC        ; Out

SWI_C:
; Update heart rate
C529: 0F C1           CLR     <temp1              ; 
C52B: DC 17           LDD     <pStrength          ; Strength
C52D: DD C2           STD     <m02C2              ; 
C52F: 86 06           LDA     #$06                
C531: 08 C3           LSL     <m02C3              ; 
C533: 09 C2           ROL     <m02C2              ; 
C535: 09 C1           ROL     <temp1              ; 
C537: 4A              DECA                        
C538: 26 F7           BNE     $C531               ; 
C53A: 0F C4           CLR     <m02C4              ; 
C53C: DC 21           LDD     <m0221              ; 
C53E: DD C5           STD     <m02C5              ; 
C540: 08 C6           LSL     <m02C6              ; 
C542: 09 C5           ROL     <m02C5              ; 
C544: 09 C4           ROL     <m02C4              ; 
C546: DC 17           LDD     <pStrength          ; 
C548: D3 C5           ADDD    <m02C5              ; 
C54A: DD C5           STD     <m02C5              ; 
C54C: D6 C4           LDB     <m02C4              ; 
C54E: C9 00           ADCB    #$00                
C550: D7 C4           STB     <m02C4              ; 
C552: 0F C7           CLR     <m02C7              ; 
C554: DC C2           LDD     <m02C2              ; 
C556: 93 C5           SUBD    <m02C5              ; 
C558: DD C2           STD     <m02C2              ; 
C55A: 96 C1           LDA     <temp1              ; 
C55C: 92 C4           SBCA    <m02C4              ; 
C55E: 97 C1           STA     <temp1              ; 
C560: 0C C7           INC     <m02C7              ; 
C562: 24 F0           BCC     $C554               ; 
C564: 96 C7           LDA     <m02C7              ; 
C566: 80 13           SUBA    #$13                
C568: 97 AF           STA     <heartCounterRel    ; 
C56A: 0D 28           TST     <fainting           ; Are we fainting?
C56C: 26 27           BNE     $C595               ; Yes ... ??
C56E: 81 03           CMPA    #$03                
C570: 2E 3C           BGT     $C5AE               ; 
C572: 3F              SWI                         
C573: 0B                                          ; SWI_B:Clear play field:
C574: 96 6E           LDA     <m026E              ; 
C576: 97 70           STA     <m0270              ; 
C578: 0A 6F           DEC     <m026F              ; 
C57A: AD 9F 02 B2     JSR     [displayFunction]   ; Display playing screen
C57E: 0A B4           DEC     <flipScreens        ; 
C580: 13              SYNC                        ; Wait for display
C581: 0A 6E           DEC     <m026E              ; Light level down
C583: 96 6E           LDA     <m026E              ; Down
C585: 81 F8           CMPA    #$F8                ; All fainted out?
C587: 2E EF           BGT     $C578               ; No, keep going
C589: 3F              SWI                         ; Clear screen
C58A: 09                                          ; SWI_9:Clear secondary screen:
C58B: 0A B4           DEC     <flipScreens        ; 
C58D: 0A 28           DEC     <fainting           ; Decrement the faint counter
C58F: 0F BC           CLR     <inputHead          ; Drop ...
C591: 0F BD           CLR     <inputTail          ; ... input keys
C593: 20 19           BRA     $C5AE               ; 
;
C595: 81 04           CMPA    #$04                
C597: 2F 15           BLE     $C5AE               ; 
C599: AD 9F 02 B2     JSR     [displayFunction]   ; Display playing screen
C59D: 0A B4           DEC     <flipScreens        ; 
C59F: 13              SYNC                        ; Wait a display
C5A0: 0C 6F           INC     <m026F              ; 
C5A2: 0C 6E           INC     <m026E              ; 
C5A4: 96 6E           LDA     <m026E              ; 
C5A6: 91 70           CMPA    <m0270              ; 
C5A8: 2F EF           BLE     $C599               ; 
C5AA: 0F 28           CLR     <fainting           ; No longer fainting
C5AC: 3F              SWI                         ; Display playing screen
C5AD: 0F                                          ; SWI_F:Ready command prompt:
;
C5AE: 9E 17           LDX     <pStrength          ; Strength
C5B0: 9C 21           CMPX    <m0221              ; Heart level
C5B2: 25 01           BCS     $C5B5               ; Can not support it, die
C5B4: 39              RTS                         

; Player is dead!

C5B5: 8E DF 10        LDX     #$DF10              ; Beam on Moon Wizard (not Star Wizard)
C5B8: 0A 9E           DEC     <initBeamIn         ; Initialize the beam in
C5BA: 3F              SWI                         ; Beam on the wizard
C5BB: 13                                          ; SWI_13:Beam on picture pointed to by X:
C5BC: 3F              SWI                         ; Print "Yet Another Does Not Return"
C5BD: 02                                          ; SWI_2:Uncompress message m and display:
C5BE: FF C1 92 D0 01 73 E8 82 C8 04 79 66 07 3E   ; "_1F_ YET ANOTHER DOES NOT RETURN..."
C5CC: 80 91 69 59 3B DE F0
 ;
C5D3: 0F 28           CLR     <fainting           ; No longer fainting
C5D5: 0A 77           DEC     <gameMode           ; 
;
C5D7: 20 FE           BRA     $C5D7               ; Endless loop

SWI_D:
; Print contents of hands on status line
;
C5D9: CE 03 88        LDU     #$0388              ; Hand line descriptor
C5DC: 0A B7           DEC     <whereToPrint       ; Force print to desired descriptor
C5DE: 96 2C           LDA     <backgroundColor    ; Base color
C5E0: 43              COMA                        ; Hands are reverse color
C5E1: A7 46           STA     6,U                 ; New color
C5E3: 4F              CLRA                        ; Coordinates...
C5E4: 5F              CLRB                        ; ...far left
C5E5: 8D 22           BSR     $C609               ; Blank left hand slot
C5E7: ED 44           STD     4,U                 ; Reposition cursor
C5E9: 9E 1D           LDX     <leftHand           ; Left hand object
C5EB: 8D 2A           BSR     GetObjDscrpt        ; Create string
C5ED: 3F              SWI                         ; And print
C5EE: 03                                          ; SWI_3:Display uncompressed message pointed to by X:
C5EF: CC 00 11        LDD     #$0011              ; Start of right hand space
C5F2: 8D 15           BSR     $C609               ; Blank right hand area
C5F4: 9E 1F           LDX     <rightHand          ; Right hand object
C5F6: 8D 1F           BSR     GetObjDscrpt        ; Decode it
C5F8: 1F 12           TFR     X,Y                 ; Over to Y
C5FA: CC 00 21        LDD     #$0021              ; Far right coordinates
C5FD: 5A              DECB                        ; Shift right hand from right
C5FE: 6D A0           TST     ,Y+                 ; All accounted for?
C600: 2A FB           BPL     $C5FD               ; No, keep counting from right
C602: ED 44           STD     4,U                 ; Coordinates for right hand
C604: 3F              SWI                         ; Print right hand contents
C605: 03                                          ; SWI_3:Display uncompressed message pointed to by X:
C606: 0F B7           CLR     <whereToPrint       ; Printing goes to command line area now
C608: 39              RTS                         ; Done
;
C609: 34 06           PSHS    B,A                 ; Hold these
C60B: ED 44           STD     4,U                 ; Coordinates
C60D: CC 00 0F        LDD     #$000F              ; 15
C610: 3F              SWI                         ; Print a space
C611: 04                                          ; SWI_4:Display a single character in A:
C612: 5A              DECB                        ; All blanked?
C613: 26 FB           BNE     $C610               ; No, blank all
C615: 35 86           PULS    A,B,PC              ; Done

GetObjDscrpt:
; Unpack the words to build the description for the given object.
; X = pointer to object
; Return X = pointer to buffer
C617: 34 66           PSHS    U,Y,B,A             ; Hold these
C619: 31 84           LEAY    ,X                  ; Get pointer to object
C61B: 26 05           BNE     $C622               ; Yes, it is something
C61D: 8E C6 50        LDX     #$C650              ; EMPTY message
C620: 20 1A           BRA     $C63C               ; Skip all decoding and use EMPTY
C622: CE 03 13        LDU     #$0313              ; Buffer for hand printing
C625: 6D 2B           TST     11,Y                ; Revealed?
C627: 26 09           BNE     $C632               ; No, skip proper name
C629: A6 29           LDA     9,Y                 ; Get proper name token
C62B: 8E D8 F4        LDX     #$D8F4              ; Proper name table
C62E: 8D 0E           BSR     $C63E               ; Find proper name
C630: 6F 5F           CLR     -1,U                ; Stick space on end of proper name
C632: A6 2A           LDA     10,Y                ; Object class
C634: 8E D9 6B        LDX     #$D96B              ; Class name table
C637: 8D 05           BSR     $C63E               ; Find class name
C639: 8E 03 13        LDX     #$0313              ; Return pointer to buffer
C63C: 35 E6           PULS    A,B,Y,U,PC          ; Done
;
C63E: 34 12           PSHS    X,A                 ; Hold these
C640: 3F              SWI                         ; Uncompress message
C641: 05                                          ; SWI_5:Uncompress message X to buffer:
C642: 4A              DECA                        ; Found proper one?
C643: 2A FB           BPL     $C640               ; No, keep going
C645: 8E 03 36        LDX     #$0336              ; Uncompress buffer
C648: A6 80           LDA     ,X+                 ; Copy from uncompressed...
C64A: A7 C0           STA     ,U+                 ; ... to hand string
C64C: 2A FA           BPL     $C648               ; Copy all, including end marker
C64E: 35 92           PULS    A,X,PC              ; Done

C650: 05 0D 10 14 19      ; 'EMPTY'
C655: FF                  ; END

SWI_E:
; Display playing screen
;
C656: 0D 28           TST     <fainting           ; Fainting?
C658: 26 05           BNE     $C65F               ; Yes, skip this
C65A: 8D 04           BSR     $C660               ; Refresh display
C65C: 0A B4           DEC     <flipScreens        ; 
C65E: 13              SYNC                        ; Wait on display
C65F: 39              RTS                         ; Out
;
C660: 34 76           PSHS    U,Y,X,B,A           ; Hold these
C662: DC 26           LDD     <m0226              ; Ambient light level
C664: DE 24           LDU     <torchPtr           ; Torch pointer
C666: 27 04           BEQ     $C66C               ; No torch lit, go with ambient level
C668: AB 47           ADDA    7,U                 ; Add ambient...
C66A: EB 48           ADDB    8,U                 ; ... to torch's power
C66C: DD 6E           STD     <m026E              ; Light level to display things with
C66E: AD 9F 02 B2     JSR     [displayFunction]   ; Refresh screen
C672: 35 F6           PULS    A,B,X,Y,U,PC        ; Done

SWI_F:
; Ready command prompt
C674: 8E C6 7A        LDX     #$C67A              ; Prompt CR and cursor
C677: 3F              SWI                         ; Print the prompt and back up over cursor
C678: 03                                          ; SWI_3:Display uncompressed message pointed to by X:
C679: 39              RTS                         ; Done

C67A: 1F 1E 1C 24 FF     ; CR "." "_" BACK END

SWI_10:
; Pause for 1.35 seconds
C67F: C6 51           LDB     #$51                ; 81 / 60 = 1.35 seconds
C681: 13              SYNC                        ; Wait for 60Hz interrupt
C682: 5A              DECB                        ; Wait ...
C683: 26 FC           BNE     $C681               ; ... for all interrupts
C685: 39              RTS                         ; Done

SWI_11:
; Fill X to U with 0s
C686: 4F              CLRA                        ; Fill with 0's (black background)
C687: 8C                  ; CMPX  opcode to skip next instruction
SWI_12:
; Fill X to U with FFs
C688: 86 FF           LDA     #$FF                ; Fill with FF's (white background)
C68A: A7 80           STA     ,X+                 ; Clear the ...
C68C: AC 6A           CMPX    10,S                ; ... entire ... (calling U)
C68E: 26 FA           BNE     $C68A               ; ... buffer
C690: 39              RTS                         ; Done

; Execute a BASIC ROM routine
; This is never used. Instead the code uses SWI2, which is structured identically but
; designed for an RTI instead of RTS.
C691: 5F              CLRB                        ; Set DP to ...
C692: 1F 9B           TFR     B,DP                ; ... zero for BASIC
C694: EE 6C           LDU     12,S                ; Read immediate ...
C696: E6 C0           LDB     ,U+                 ; ... byte from code ...
C698: EF 6C           STU     12,S                ; Update the return
C69A: CE A0 00        LDU     #$A000              ; Execute the ...
C69D: AD D5           JSR     [B,U]               ; ... ROM routine
C69F: A7 63           STA     3,S                 ; Return A
C6A1: AF 66           STX     6,S                 ; Return X
C6A3: 39              RTS                         ; Done

SWI_13:
; Beam in picture pointed to by X (demon, wizard, star-wizard)
C6A4: 0F B1           CLR     <hearHeart          ; Disable heart beat
C6A6: 3F              SWI                         ; Clear the hand line
C6A7: 0A                                          ; SWI_A:Clear hand descriptor:

SWI_14:
; Beam wizard in
C6A8: 3F              SWI                         ; Clear the play field
C6A9: 0B                                          ; SWI_B:Clear play field:
C6AA: CC 80 80        LDD     #$8080              ; X and Y scaling factors to ...
C6AD: DD 4F           STD     <xScaleFactor       ; ... one
C6AF: D6 9E           LDB     <initBeamIn         ; Init the beam in?
C6B1: 27 04           BEQ     $C6B7               ; No ... continue where we were (I don't think this is ever used)
C6B3: C6 20           LDB     #$20                ; Start with 32 for dot spacing as we beam on
C6B5: 0A 9C           DEC     <beamSound          ; Trigger the beam sound in the ISR
C6B7: 8D 1E           BSR     DrawBeamingWizard   ; Draw the new wizard image
C6B9: 5A              DECB                        ; Decrease the ...
C6BA: 5A              DECB                        ; ... space between dots
C6BB: 2A FA           BPL     $C6B7               ; Loop until the wizard is solid
C6BD: 0F 9C           CLR     <beamSound          ; Stop the beam sound
C6BF: 0F 9E           CLR     <initBeamIn         ; Beaming is done
C6C1: 3F              SWI                         ; Play wizard strike AFTER beaming on
C6C2: 1B                                          ; SWI_1B:Play sound i at full volume:
C6C3: 16                                          ; Sound 16 = Wizard strike
C6C4: 39              RTS                         ; Done

SWI_15:
; Beam wizard out
; Always follows a beam-in, so center of screen is still set
C6C5: 3F              SWI                         ; Clear the play field
C6C6: 0B                                          ; SWI_B:Clear play field:
C6C7: 8D F8           BSR     $C6C1               ; Play the wizard strike BEFORE beaming out
C6C9: 5F              CLRB                        ; Start with solid picture
C6CA: 0A 9C           DEC     <beamSound          ; Trigger the beam sound in the ISR
C6CC: 8D 09           BSR     DrawBeamingWizard   ; Draw the new wizard image
C6CE: 5C              INCB                        ; Increase the ...
C6CF: 5C              INCB                        ; ... space between dots
C6D0: C1 20           CMPB    #$20                ; Beamed out as far as we want?
C6D2: 26 F8           BNE     $C6CC               ; No ... keep beaming
C6D4: 0F 9C           CLR     <beamSound          ; Stop the beam sound
C6D6: 39              RTS                         ; Done

DrawBeamingWizard:
C6D7: 34 50           PSHS    U,X                 ; Preserve
C6D9: D7 2D           STB     <dotFrequency       ; 
C6DB: D7 9D           STB     <beamSoundVal       ; 
C6DD: 3F              SWI                         ; Clear the secondary screen
C6DE: 09                                          ; SWI_9:Clear secondary screen:
C6DF: 3F              SWI                         ; Draw the new dot-frequency picture
C6E0: 01                                          ; SWI_1:Draw picture X on screen:
C6E1: 0A B4           DEC     <flipScreens        ; Trigger a screen flip
C6E3: 13              SYNC                        ; Wait for draw
C6E4: 35 D0           PULS    X,U,PC              ; Restore

SWI_16:
; Print PREPARE
C6E6: BD D4 89        JSR     SetForExamine       ; 
C6E9: CC 01 2C        LDD     #$012C              
C6EC: ED 44           STD     4,U                 
C6EE: 3F              SWI                         
C6EF: 02                                          ; SWI_2:Uncompress message m and display:
C6F0: 3C 24 58 06 45 D8                           ; "PREPARE!"
;
C6F6: 0F B7           CLR     <whereToPrint       ; Printing goes to command area now
C6F8: 0A B4           DEC     <flipScreens        ; 
C6FA: 39              RTS                         

SWI_17:
; Create object structure
;
; The object structure is filled out with all the class information for
; the object. If the object is a torch, shield, or sword then the base
; class info is used instead (pine, leather, wooden). When the object
; is revealed then it takes its own properties.
;
; A = type
; B = maze level
; Return X = pointer to object
;
C6FB: DE 0F           LDU     <nextObjSlot        ; Current object pointer
C6FD: EF 66           STU     6,S                 ; Return this
C6FF: 30 4E           LEAX    14,U                ; Point to ...
C701: 9F 0F           STX     <nextObjSlot        ; ... next object
C703: A7 49           STA     9,U                 ; Object type
C705: E7 44           STB     4,U                 ; Maze level
C707: 3F              SWI                         ; Fill out object ...
C708: 18                                          ; SWI_18:Change object to proper name and data:
C709: E6 4A           LDB     10,U                ; Object class
C70B: 8E C7 19        LDX     #$C719              ; Base type table
C70E: A6 85           LDA     B,X                 ; Get the basic model for this class
C710: 2B 06           BMI     $C718               ; There is no basic ... skip
C712: E6 4B           LDB     11,U                ; Preserve needed-to-reveal
C714: 3F              SWI                         ; Copy over the basic ...
C715: 18                                          ; SWI_18:Change object to proper name and data:
C716: E7 4B           STB     11,U                ; Preserve the needed-to-reveal
C718: 39              RTS                         ; Done

; Basic type for each class (if applicable). This is used when the object is
; not revealed. Thus unrevealed IRON SWORD acts like the basic WOODEN SWORD.
C719: FF  ; Flask   no basic type
C71A: FF  ; Ring    no basic type
C71B: FF  ; Scroll  no basic type
C71C: 10  ; Shield  (10 = LEATHER SHIELD)
C71D: 11  ; Sword   (11 = WOODEN SWORD)
C71E: 0F  ; Torch   (0F = PINE TORCH)

SWI_18:
; Change object to proper name and data
; Change object to proper name and data
; A = object type
C71F: 48              ASLA                        ; Type times ...
C720: 48              ASLA                        ; ... 4 bytes per entry
C721: 8E DA 00        LDX     #$DA00              ; Object descriptors
C724: 31 86           LEAY    A,X                 ; Get the object data
C726: 30 4A           LEAX    10,U                ; Destination in structure
C728: 86 04           LDA     #$04                ; Four bytes
C72A: BD C0 4B        JSR     CopyYtoX            ; Copy 4 bytes from Y to X
C72D: 8E DA 60        LDX     #$DA60              ; Special object properties (backed up one slot)
C730: 30 04           LEAX    4,X                 ; Point to next object
C732: A6 84           LDA     ,X                  ; Object's type
C734: 2B 0C           BMI     $C742               ; End of list ... out
C736: A1 63           CMPA    3,S                 ; Is this special data for us?
C738: 26 F6           BNE     $C730               ; No ... keep looking
C73A: EC 01           LDD     1,X                 ; Copy ...
C73C: ED 46           STD     6,U                 ; ... 3 ...
C73E: A6 03           LDA     3,X                 ; ... bytes of ...
C740: A7 48           STA     8,U                 ; ... special data
C742: 39              RTS                         ; Done

SWI_19:
; Bring up normal display
C743: 3F              SWI                         
C744: 0A                                          ; SWI_A:Clear hand descriptor:
C745: 3F              SWI                         
C746: 0B                                          ; SWI_B:Clear play field:
C747: 3F              SWI                         
C748: 0C                                          ; SWI_C:Update heart rate:
C749: 0C AE           INC     <heartCounter       ; 
C74B: 0A AD           DEC     <scrollShowing      ; Scroll is NOT showing
C74D: 0A B1           DEC     <hearHeart          ; 
C74F: 3F              SWI                         
C750: 0D                                          ; SWI_D:Print contents of hands on status line:
; Fall into LOOK

LOOK command

CmdLOOK:
C751: 8E CE 66        LDX     #$CE66              ; The routine for drawing ...
C754: 9F B2           STX     <displayFunction    ; ... then normal game screen
C756: 3F              SWI                         ; Redraw the screen
C757: 0E                                          ; SWI_E:Display playing screen:
C758: 39              RTS                         ; Done

SWI_1A:
; Set up level
;
C759: 97 81           STA     <currentLevel       ; Current level
C75B: C6 0C           LDB     #$0C                ; 12 bytes each (one byte to count each type of creature)
C75D: 3D              MUL                         ; Pointer to ...
C75E: C3 03 98        ADDD    #$0398              ; ... creature count on level
C761: DD 82           STD     <creatureCounts     ; Hold pointer to creature count
;
C763: D6 81           LDB     <currentLevel       ; Current level
C765: 8E CF FD        LDX     #$CFFD              ; Table of holes and ladders
C768: 9F 86           STX     <currentHoles       ; 
C76A: A6 80           LDA     ,X+                 
C76C: 2A FC           BPL     $C76A               ; 
C76E: 5A              DECB                        
C76F: 2A F7           BPL     $C768               ; 
C771: 8E 03 D4        LDX     #$03D4              
C774: CE 05 F4        LDU     #$05F4              
C777: 3F              SWI                         
C778: 11                                          ; SWI_11:Fill X to U with 0s:
C779: BD C0 53        JSR     InitTasks           ; Re-create the game tasks
C77C: BD CC 9C        JSR     MakeMazeLevel       ; Create the maze level
;
C77F: DE 82           LDU     <creatureCounts     ; Pointer to creature counts
C781: 86 0B           LDA     #$0B                ; Start with most powerful
C783: E6 C6           LDB     A,U                 ; Get count of creature type in A
C785: 27 06           BEQ     $C78D               ; None to make ... skip
C787: BD CF A5        JSR     CreateCreature      ; Make a creature of type in A
C78A: 5A              DECB                        ; Make all ...
C78B: 26 FA           BNE     $C787               ; ... of that creature type
C78D: 4A              DECA                        ; Next creature type
C78E: 2A F3           BPL     $C783               ; Do all creature types
;
C790: CE 03 C3        LDU     #$03C3              ; (03D4 - 11) Start of monsters on this level
C793: 0F 91           CLR     <restartFind        ; Scan from start of objects
C795: BD CF 63        JSR     GetNextOject        ; Find next object on this level
C798: 27 1C           BEQ     $C7B6               ; No objects ... done
C79A: 6D 05           TST     5,X                 ; Somebody already holding this object?
C79C: 2A F7           BPL     $C795               ; Yes ... leave it alone
C79E: 33 C8 11        LEAU    $11,U               ; Point to next monster on this level
C7A1: 11 83 05 F4     CMPU    #$05F4              ; At end of list?
C7A5: 25 03           BCS     $C7AA               ; No ... leave pointer
C7A7: CE 03 D4        LDU     #$03D4              ; Yes ... start back with 1st monster
C7AA: 6D 4C           TST     12,U                ; Is this monster alive?
C7AC: 27 F0           BEQ     $C79E               ; No ... go to next monster (?? there better be at least one or this is an infinite loop)
C7AE: EC 48           LDD     8,U                 ; Chain ....
C7B0: AF 48           STX     8,U                 ; ... object ...
C7B2: ED 84           STD     ,X                  ; ... to monster
C7B4: 20 DF           BRA     $C795               ; Keep going
;
; Set the colors of the screen areas
C7B6: 96 81           LDA     <currentLevel       ; 
C7B8: 84 01           ANDA    #$01                ; Just the lower bit
C7BA: 40              NEGA                        ; 0->00000000, 1->11111111
C7BB: 97 2C           STA     <backgroundColor    ; ? color
C7BD: B7 03 96        STA     comColor            ; 
C7C0: B7 03 86        STA     examineColor        ; 
C7C3: 43              COMA                        ; Toggle color for hands
C7C4: B7 03 8E        STA     hndColor            ; Color of hands area
C7C7: 39              RTS                         ; Done

SWI_1B:
; Play sound i at full volume
;
C7C8: AE 6C           LDX     12,S                ; Caller's PC
C7CA: A6 80           LDA     ,X+                 ; Get the effect number
C7CC: AF 6C           STX     12,S                ; Restore the caller's PC
C7CE: C6 FF           LDB     #$FF                ; Full volume
;
SWI_1C:
; Play sound A at volume B
;
C7D0: D7 61           STB     <m0261              ; Store the volume
C7D2: 8E C7 DC        LDX     #$C7DC              ; Effect table
C7D5: 48              ASLA                        ; Sound number to offset
C7D6: AD 96           JSR     [A,X]               ; Execute the sound routine
C7D8: 7F FF 20        CLR     PIA1_DA             ; All sound off
C7DB: 39              RTS                         ; Done

SoundEffectsRoutines:
; Sound effects routine entry points
;
C7DC: C8 2B ; 00 Spider
C7DE: C8 50 ; 01 Snake
C7E0: C9 51 ; 02 Giant
C7E2: C8 3C ; 03 Blob
C7E4: C8 E2 ; 04 Knight
C7E6: C9 55 ; 05 Hatchet Giant
C7E8: C8 4A ; 06 Scorpion
C7EA: C8 DE ; 07 Shielded Knight
C7EC: C8 4D ; 08 Wraith
C7EE: C9 59 ; 09 Galdrog
C7F0: C8 77 ; 0A Demon
C7F2: C8 77 ; 0B Wizard
;
C7F4: C8 0A ; 0C Flask
C7F6: C8 11 ; 0D Ring
C7F8: C8 27 ; 0E Scroll
C7FA: C8 DA ; 0F Shield
C7FC: C8 A6 ; 10 Sword
C7FE: C8 B2 ; 11 Torch
;
C800: C9 3F ; 12 Player hit
C802: C8 E6 ; 13 Wizard beam
C804: C8 72 ; 14 Wall hit
C806: C8 6D ; 15 Creature dying
C808: C8 8A ; 16 Wizard strike

SoundFlask:
C80A: CE C8 23        LDU     #$C823              ;
C80D: 86 04           LDA     #$04                ;
C80F: 20 05           BRA     $C816               ; 

SoundRing:
C811: CE C8 1F        LDU     #$C81F              ;
C814: 86 0A           LDA     #$0A                ;
C816: 97 5F           STA     <m025F              ; 
C818: AD C4           JSR     ,U                  ;
C81A: 0A 5F           DEC     <m025F              ; 
C81C: 26 FA           BNE     $C818               ; 
C81E: 39              RTS                         
                 
C81F: 8E 00 40        LDX     #$0040              ;
C822: 10                  ;CMPY opcode to skip next instruction
C823: 8E 00 80        LDX     #$0080              ;
C826: 10                  ;CMPY opcode to skip next instruction

SoundScroll:
C827: 8E 01 00        LDX     #$0100              ;
C82A: 10                  ;CMPY opcode to skip next instruction

SoundSpider:
C82B: 8E 00 20        LDX     #$0020              ;
C82E: 8D 05           BSR     $C835               ; 
C830: 30 1F           LEAX    -1,X                ;
C832: 26 FA           BNE     $C82E               ; 
C834: 39              RTS                         ;

C835: 86 FF           LDA     #$FF                ;
C837: 8D 30           BSR     $C869               ; 
C839: 4F              CLRA                        ;
C83A: 20 2D           BRA     $C869               ; 

SoundBlob:     
C83C: 8E 05 00        LDX     #$0500              ;
C83F: 8D F4           BSR     $C835               ; 
C841: 30 88 30        LEAX    $30,X               ;
C844: 8C 08 00        CMPX    #$0800              ;
C847: 25 F6           BCS     $C83F               ; 
C849: 39              RTS                         ;

SoundScorpion:
C84A: 86 02           LDA     #$02                ; Two shakes
C84C: 8C                  ; CMPX  opcode to skip next instruction

SoundWraith:
C84D: 86 01           LDA     #$01                ; One shake
C84F: 8C                  ; CMPX  opcode to skip next instruction

SoundSnake:
C850: 86 0A           LDA     #$0A                ; 10 shakes
C852: 97 62           STA     <m0262              ; 
C854: 10 8E 00 C0     LDY     #$00C0              ;
C858: 8D 74           BSR     $C8CE               ; 
C85A: 8D 69           BSR     $C8C5               ; 
C85C: 31 3F           LEAY    -1,Y                ;
C85E: 26 F8           BNE     $C858               ; 
C860: 8D 58           BSR     $C8BA               ; 
C862: 0A 62           DEC     <m0262              ; 
C864: 26 EE           BNE     $C854               ; 
C866: 39              RTS                         ;

C867: 8D 65           BSR     $C8CE               ; 
C869: 8D 5A           BSR     $C8C5               ; 
C86B: 20 50           BRA     $C8BD               ; 

SoundMonsDeath: 
C86D: CE DB DA        LDU     #$DBDA              ;
C870: 20 21           BRA     $C893               ; 

SoundWallHit:
C872: CE DB D2        LDU     #$DBD2              ;
C875: 20 1C           BRA     $C893               ; 

SoundWizard:
SoundDemon:       
C877: 86 08           LDA     #$08                ;
C879: 97 5F           STA     <m025F              ; 
C87B: 8D 51           BSR     $C8CE               ; 
C87D: 4F              CLRA                        ;
C87E: 54              LSRB                        ;
C87F: 26 01           BNE     $C882               ; 
C881: 5C              INCB                        ;
C882: 1F 01           TFR     D,X                 ;
C884: 8D A8           BSR     $C82E               ; 
C886: 0A 5F           DEC     <m025F              ; 
C888: 26 F1           BNE     $C87B               ; 

SoundWizStrike:  
C88A: CE DB D2        LDU     #$DBD2              ;
C88D: 8D 04           BSR     $C893               ; 
C88F: 8D 29           BSR     $C8BA               ; 
C891: 33 44           LEAU    4,U                 ;
C893: AE C4           LDX     ,U                  ;
C895: 10 AE 42        LDY     2,U                 ;
C898: 8D CD           BSR     $C867               ; 
C89A: 31 3F           LEAY    -1,Y                ;
C89C: 26 FA           BNE     $C898               ; 
C89E: 30 02           LEAX    2,X                 ;
C8A0: 8C 01 50        CMPX    #$0150              ;
C8A3: 26 F0           BNE     $C895               ; 
C8A5: 39              RTS                         ;

SoundSword:
C8A6: BD C9 31        JSR     $C931               ; 
C8A9: 80 ; Consumed by routine
C8AA: 8D 76           BSR     $C922               ; 
C8AC: 25 04           BCS     SoundTorch          ; 
C8AE: 8D 15           BSR     $C8C5               ; 
C8B0: 20 F8           BRA     $C8AA               ; 

SoundTorch:
C8B2: BD C9 2E        JSR     $C92E               ; 
C8B5: A0 ; Consumed by routine
C8B6: 8D 6E           BSR     $C926               ; 
C8B8: 20 FC           BRA     $C8B6               ; 
;
C8BA: 8E 10 00        LDX     #$1000              ;
C8BD: 34 10           PSHS    X                   ;
C8BF: 30 1F           LEAX    -1,X                ;
C8C1: 26 FC           BNE     $C8BF               ; 
C8C3: 35 90           PULS    X,PC                ;

C8C5: D6 61           LDB     <m0261              ; 
C8C7: 3D              MUL                         ;
C8C8: 84 FC           ANDA    #$FC                ;
C8CA: B7 FF 20        STA     PIA1_DA             ; 
C8CD: 39              RTS                         ;

C8CE: DC 56           LDD     <m0256              ; 
C8D0: 58              ASLB                        ;
C8D1: 49              ROLA                        ;
C8D2: 58              ASLB                        ;
C8D3: 49              ROLA                        ;
C8D4: D3 56           ADDD    <m0256              ; 
C8D6: 5C              INCB                        ;
C8D7: DD 56           STD     <m0256              ; 
C8D9: 39              RTS                         ;

SoundShield:
C8DA: 8D 39           BSR     $C915               ; 
C8DC: 64 24  ; Consumed by routine. Returns to the one who called this.

SoundShldKnight:
C8DE: 8D 35           BSR     $C915               ; 
C8E0: 32 12  ; Consumed by routine. Returns to the one who called this.

SoundKnight:
C8E2: 8D 31           BSR     $C915               ; 
C8E4: AF 36  ; Consumed by routine. Returns to the one who called this.

SoundWizBeam:
C8E6: 8D 2D           BSR     $C915               ; 
C8E8: 19 09 ; Consumed by routine. Returns to the one who called this.

C8EA: 8D 42           BSR     $C92E               ; 
C8EC: 60    ; Consumed by routine
C8ED: 9E 63           LDX     <m0263              ; 
C8EF: 10 9E 65        LDY     <m0265              ; 
C8F2: 4F              CLRA                        ;
C8F3: 30 1F           LEAX    -1,X                ;
C8F5: 26 06           BNE     $C8FD               ; 
C8F7: 9E 63           LDX     <m0263              ; 
C8F9: 88 7F           EORA    #$7F                ;
C8FB: 8D 0D           BSR     $C90A               ; 
C8FD: 31 3F           LEAY    -1,Y                ;
C8FF: 26 F2           BNE     $C8F3               ; 
C901: 10 9E 65        LDY     <m0265              ; 
C904: 88 80           EORA    #$80                ;
C906: 8D 02           BSR     $C90A               ; 
C908: 20 E9           BRA     $C8F3               ; 
C90A: 97 59           STA     <m0259              ; 
C90C: 8D 70           BSR     $C97E               ; 
C90E: 23 B3           BLS     $C8C3               ; 
C910: 8D B3           BSR     $C8C5               ; 
C912: 96 59           LDA     <m0259              ; 
C914: 39              RTS                         ;
                 
C915: AE E1           LDX     ,S++                ; Pull return from the stack (returning up a frame)
C917: E6 80           LDB     ,X+                 ; Get the immediate byte
C919: 4F              CLRA                        ;
C91A: DD 63           STD     <m0263              ; 
C91C: E6 80           LDB     ,X+                 ; Get the next byte
C91E: DD 65           STD     <m0265              ; 
C920: 20 C8           BRA     $C8EA               ; 

C922: 8D AA           BSR     $C8CE               ; 
C924: 20 67           BRA     $C98D               ; 
C926: 8D A6           BSR     $C8CE               ; 
C928: 8D 54           BSR     $C97E               ; 
C92A: 23 97           BLS     $C8C3               ; 
C92C: 20 97           BRA     $C8C5               ; 
   
C92E: 9E 03           LDX     <CONST_FF           ; 
C930: 10                  ;LDY opcode to skip next instruction
C931: 9E 00           LDX     <CONST_00           ; 
C933: 9F 5B           STX     <m025B              ; 
C935: AE E4           LDX     ,S                  ; Return location
C937: E6 80           LDB     ,X+                 ; Get the immediate byte
C939: 4F              CLRA                        ;
C93A: DD 5D           STD     <m025D              ; 
C93C: AF E4           STX     ,S                  ; Corrected return address
C93E: 39              RTS                         ; Done

SoundPlayerHit:
C93F: 8D ED           BSR     $C92E               ; 
C941: 60 ; Consumed by routine
C942: BD C8 CE        JSR     $C8CE               ; 
C945: 44              LSRA                        ;
C946: 8D E0           BSR     $C928               ; 
C948: BD C8 CE        JSR     $C8CE               ; 
C94B: 8A 80           ORA     #$80                ;
C94D: 8D D9           BSR     $C928               ; 
C94F: 20 F1           BRA     $C942               ; 

SoundGiant: 
C951: 8E 03 00        LDX     #$0300              ;
C954: 10                  ;CMPY skip next instruction

SoundHchGiant:
C955: 8E 02 00        LDX     #$0200              ;
C958: 10                  ;CMPY skip next instruction

SoundGaldrog:
C959: 8E 01 00        LDX     #$0100              ;
C95C: 9F 5D           STX     <m025D              ; 
C95E: 4F              CLRA                        ;
C95F: 5F              CLRB                        ;
C960: DD 5B           STD     <m025B              ; 
C962: 8D BE           BSR     $C922               ; 
C964: 25 0B           BCS     $C971               ; 
C966: BD C8 C5        JSR     $C8C5               ; 
C969: 8E 00 F0        LDX     #$00F0              ;
C96C: BD C8 BD        JSR     $C8BD               ; 
C96F: 20 F1           BRA     $C962               ; 
C971: 8D BB           BSR     $C92E               ; 
C973: 40              NEGA                        ;
C974: 8D B0           BSR     $C926               ; 
C976: 8E 00 60        LDX     #$0060              ;
C979: BD C8 BD        JSR     $C8BD               ; 
C97C: 20 F6           BRA     $C974               ; 
C97E: 34 02           PSHS    A                   ;
C980: DC 5B           LDD     <m025B              ; 
C982: 93 5D           SUBD    <m025D              ; 
C984: 34 01           PSHS    CC                  ;
C986: DD 5B           STD     <m025B              ; 
C988: E6 61           LDB     1,S                 ;
C98A: 3D              MUL                         ;
C98B: 35 85           PULS    CC,B,PC             ;

C98D: 34 02           PSHS    A                   ;
C98F: DC 5B           LDD     <m025B              ; 
C991: D3 5D           ADDD    <m025D              ; 
C993: 20 EF           BRA     $C984               ; 

SWI Function Table

SWIOffsetTable:
;
;            Address   Description
C995: 00 ;   C384      SWI_0:  Light level
C996: 1E ;   C3A2      SWI_1:  Draw picture X on screen
C997: A6 ;   C448      SWI_2:  Uncompress message m and display
C998: 0C ;   C454      SWI_3:  Display uncompressed message pointed to by X
C999: 05 ;   C459      SWI_4:  Display a single character in A
C99A: 16 ;   C46F      SWI_5:  Uncompress message X to buffer
C99B: 03 ;   C472      SWI_6:  Uncompress message X to given buffer U
C99C: 5D ;   C4CF      SWI_7:  Get random number
C99D: 24 ;   C4F3      SWI_8:  Clear display screen
C99E: 03 ;   C4F6      SWI_9:  Clear secondary screen
C99F: 09 ;   C4FF      SWI_A:  Clear hand descriptor
C9A0: 08 ;   C507      SWI_B:  Clear play field
C9A1: 22 ;   C529      SWI_C:  Update heart rate
C9A2: B0 ;   C5D9      SWI_D:  Print contents of hands on status line
C9A3: 7D ;   C656      SWI_E:  Display playing screen
C9A4: 1E ;   C674      SWI_F:  Ready command prompt
C9A5: 0B ;   C67F      SWI_10: Pause for 1.35 seconds
C9A6: 07 ;   C686      SWI_11: Fill X to U with 0s
C9A7: 02 ;   C688      SWI_12: Fill X to U with FFs
C9A8: 1C ;   C6A4      SWI_13: Beam on picture pointed to by X
C9A9: 04 ;   C6A8      SWI_14: Beam wizard in
C9AA: 1D ;   C6C5      SWI_15: Beam wizard out
C9AB: 21 ;   C6E6      SWI_16: Print PREPARE
C9AC: 15 ;   C6FB      SWI_17: Create object structure
C9AD: 24 ;   C71F      SWI_18: Change object to proper name and data
C9AE: 24 ;   C743      SWI_19: Bring up normal display
C9AF: 16 ;   C759      SWI_1A: Set up level
C9B0: 6F ;   C7C8      SWI_1B: Play sound i at full volume
C9B1: 08 ;   C7D0      SWI_1C: Play sound A at volume B

PrintCharCRBS:
; Print character ... handle backspace and carriage return
; 0 - 1E = " ABCDEFGHIJKLMNOPQRSTUVWXYZ!_?."
; 1F = CR
; 20 = small heart (left)
; 21 = small heart (right)
; 22 = large heart (left)
; 23 = large heart (right)
; 24 = backspace
;
C9B2: 81 24           CMPA    #$24                ; Is it backspace?
C9B4: 27 09           BEQ     $C9BF               ; Yes ... go do a backspace
C9B6: 81 1F           CMPA    #$1F                ; Is it CR character?
C9B8: 27 10           BEQ     $C9CA               ; Yes ... go do a CR
C9BA: 8D 5B           BSR     PrintRegChar        ; Print the character
C9BC: 30 01           LEAX    1,X                 ; Advance the cursor
C9BE: 39              RTS                         ; Done
;
; Backspace (wrap to end of area)
C9BF: 30 1F           LEAX    -1,X                ; Back cursor up one space
C9C1: 9C 03           CMPX    <CONST_FF           ; Did we underflow?
C9C3: 26 04           BNE     $C9C9               ; No ... keep it
C9C5: AE 42           LDX     2,U                 ; Yes ... wrap ...
C9C7: 30 1F           LEAX    -1,X                ; ... to end of area
C9C9: 39              RTS                         ; Done
;
; Carriage return
C9CA: 30 88 20        LEAX    $20,X               ; Drop to next row
C9CD: 1E 01           EXG     D,X                 ; Mask row offset ...
C9CF: C4 E0           ANDB    #$E0                ; ... back to beginning ...
C9D1: 1E 01           EXG     D,X                 ; ... of row
C9D3: 39              RTS                         ; Done

ScrollTextArea:
; Scroll the text area pointed to by U. Return the new cursor offset.
C9D4: 34 36           PSHS    Y,X,B,A             ; Hold all
C9D6: AE C4           LDX     ,U                  ; Start of area
C9D8: EC 42           LDD     2,U                 ; Number of characters in the area
C9DA: 83 00 20        SUBD    #$0020              ; Back up 32 characters (one row)
C9DD: ED 62           STD     2,S                 ; Return the new cursor offset
C9DF: 8D 2F           BSR     Dleft3              ; D = D * 8 (8 bytes per character)
C9E1: 1F 02           TFR     D,Y                 ; Number of bytes to move in Y
C9E3: EC 89 01 00     LDD     $0100,X             ; Data from next text row (32 columns * 8 rows)
C9E7: 6D 47           TST     7,U                 ; Mirroring into both screen buffers?
C9E9: 26 04           BNE     $C9EF               ; No ... skip the 2nd screen
C9EB: ED 89 18 00     STD     $1800,X             ; Yes ... store it to 2nd screen
C9EF: ED 81           STD     ,X++                ; Store to first screen
C9F1: 31 3E           LEAY    -2,Y                ; All pixels moved up?
C9F3: 26 EE           BNE     $C9E3               ; No ... keep scrolling
; Blank the new bottom line
C9F5: E6 46           LDB     6,U                 ; Get color of area
C9F7: 1D              SEX                         ; Make it a double
C9F8: 10 8E 01 00     LDY     #$0100              ; 32 columns * 8 rows
C9FC: 6D 47           TST     7,U                 ; Mirroring to second screen?
C9FE: 26 04           BNE     $CA04               ; No ... only one screen
CA00: ED 89 18 00     STD     $1800,X             ; Mirror data to second screen
CA04: ED 81           STD     ,X++                ; Blank the area
CA06: 31 3E           LEAY    -2,Y                ; Entire row blanked?
CA08: 26 F2           BNE     $C9FC               ; No ... keep blanking
CA0A: 35 B6           PULS    A,B,X,Y,PC          ; Done

; Shift-D-to-the-left entry points
Dleft5:
CA0C: 58              ASLB                        ; D << 5 starts here
CA0D: 49              ROLA                        ;
Dleft4:
CA0E: 58              ASLB                        ; D << 4 starts here
CA0F: 49              ROLA                        ;
Dleft3:
CA10: 58              ASLB                        ; D << 3 starts here
CA11: 49              ROLA                        ;
Dleft2:
CA12: 58              ASLB                        ; D << 2 starts here
CA13: 49              ROLA                        ;
Dleft1:
CA14: 58              ASLB                        ; D << 1 starts here
CA15: 49              ROLA                        ;
;
CA16: 39              RTS                         ; Done

PrintRegChar:
; Print character image or heart image
; U = screen descriptor
CA17: 34 76           PSHS    U,Y,X,B,A           ; Save everything
CA19: 81 20           CMPA    #$20                ; Letter?
CA1B: 25 0C           BCS     $CA29               ; Yes ... go handle
CA1D: 80 20           SUBA    #$20                ; Must be heart picture
CA1F: C6 07           LDB     #$07                ; 7 bytes ...
CA21: 3D              MUL                         ; ... per heart picture
CA22: C3 DB B6        ADDD    #$DBB6              ; Offset ...
CA25: 1F 01           TFR     D,X                 ; ... to bit mask
CA27: 20 1B           BRA     $CA44               ; Already have the pattern -- use it
; Uncompress the character pattern
CA29: C6 05           LDB     #$05                ; Five bytes in each character image
CA2B: 3D              MUL                         ; Pointer now in D
CA2C: C3 DB 1B        ADDD    #$DB1B              ; Offset into character image table
CA2F: 1F 01           TFR     D,X                 ; To X
CA31: CE 03 57        LDU     #$0357              ; Expansion buffer
CA34: 3F              SWI                         ; Decompress the pattern
CA35: 06                                          ; SWI_6:Uncompress message X to given buffer U:
CA36: 8E 03 5E        LDX     #$035E              ; Shift ...
CA39: 68 82           ASL     ,-X                 ; ... image two times to ...
CA3B: 68 84           ASL     ,X                  ; ... middle of ...
CA3D: 8C 03 57        CMPX    #$0357              ; ... raster ...
CA40: 22 F7           BHI     $CA39               ; ... buffer
CA42: EE 66           LDU     6,S                 ; Pointer to screen area
; Draw the raster image
CA44: EC 44           LDD     4,U                 ; Current cursor
CA46: 8D C8           BSR     Dleft3              ; Offset = (cur/32)*256 + (cur%32). From yyyxxxxx to yyy_000xxxxx ...
CA48: 54              LSRB                        ; ... y is number of whole rows (32*8 = 256 bytes) ...
CA49: 54              LSRB                        ; ... then x is the ...
CA4A: 54              LSRB                        ; ... offset on the final row. Clever.
CA4B: E3 C4           ADDD    ,U                  ; Offset from beginning of area
CA4D: 1F 02           TFR     D,Y                 ; To Y for indexing
CA4F: C6 07           LDB     #$07                ; 7 rows in an image
CA51: A6 80           LDA     ,X+                 ; Get next row pattern
CA53: A8 46           EORA    6,U                 ; Use the color from the area
CA55: A7 A4           STA     ,Y                  ; Store the pattern on the screen
CA57: 6D 47           TST     7,U                 ; Are we mirroring?
CA59: 26 04           BNE     $CA5F               ; No ... skip 2nd screen
CA5B: A7 A9 18 00     STA     $1800,Y             ; Pattern to 2nd screen
CA5F: 31 A8 20        LEAY    $20,Y               ; Next row
CA62: 5A              DECB                        ; All rows done?
CA63: 26 EC           BNE     $CA51               ; No ... go do them all
CA65: 35 F6           PULS    A,B,X,Y,U,PC        ; Done

CA67: 34 16           PSHS    X,B,A               
CA69: 6F E4           CLR     ,S                  
CA6B: 6F 61           CLR     1,S                 
CA6D: 0F C1           CLR     <temp1              ; 
CA6F: DD C2           STD     <m02C2              ; 
CA71: 27 24           BEQ     $CA97               ; 
CA73: 10 A3 62        CMPD    2,S                 
CA76: 26 04           BNE     $CA7C               ; 
CA78: 6C E4           INC     ,S                  
CA7A: 20 1B           BRA     $CA97               ; 
CA7C: 8E 00 10        LDX     #$0010              
CA7F: 08 C3           LSL     <m02C3              ; 
CA81: 09 C2           ROL     <m02C2              ; 
CA83: 09 C1           ROL     <temp1              ; 
CA85: 68 61           ASL     1,S                 
CA87: 69 E4           ROL     ,S                  
CA89: DC C1           LDD     <temp1              ; 
CA8B: A3 62           SUBD    2,S                 
CA8D: 25 04           BCS     $CA93               ; 
CA8F: DD C1           STD     <temp1              ; 
CA91: 6C 61           INC     1,S                 
CA93: 30 1F           LEAX    -1,X                
CA95: 26 E8           BNE     $CA7F               ; 
CA97: 35 96           PULS    A,B,X,PC            
    
NegativeD:
; Take the 2s complement of D.
; Signed D becomes -D
CA99: 43              COMA                        ; D = ...
CA9A: 53              COMB                        ; ... ...
CA9B: C3 00 01        ADDD    #$0001              ; ... ...
CA9E: 39              RTS                         ; ... -D

CA9F: 34 16           PSHS    X,B,A               
CAA1: 9E 43           LDX     <m0243              ; 
CAA3: EC E4           LDD     ,S                  ;
CAA5: 2A 07           BPL     $CAAE               ; 
CAA7: 8D F0           BSR     NegativeD           ; 
CAA9: 8D BC           BSR     $CA67               ; 
CAAB: 8D EC           BSR     NegativeD           ; 
CAAD: 8C                  ; CMPX  opcode to skip next instruction
CAAE: 8D B7           BSR     $CA67               ; 
CAB0: ED E4           STD     ,S                  
CAB2: 35 96           PULS    A,B,X,PC            
    
CAB4: 7E CB 8A        JMP     $CB8A               ; 

DrawLine:
CAB7: 34 76           PSHS    U,Y,X,B,A           
CAB9: 0C 2D           INC     <dotFrequency       ; 
CABB: 27 F7           BEQ     $CAB4               ; 
CABD: 96 2D           LDA     <dotFrequency       ; 
CABF: 97 2E           STA     <m022E              ; 
CAC1: DC 35           LDD     <oldPointX          ; 
CAC3: 93 31           SUBD    <newPointX          ; 
CAC5: DD 3E           STD     <m023E              ; 
CAC7: 2A 02           BPL     $CACB               ; 
CAC9: 8D CE           BSR     NegativeD           ; 
CACB: DD 43           STD     <m0243              ; 
CACD: DC 33           LDD     <oldPointY          ; 
CACF: 93 2F           SUBD    <newPointY          ; 
CAD1: DD 41           STD     <m0241              ; 
CAD3: 2A 02           BPL     $CAD7               ; 
CAD5: 8D C2           BSR     NegativeD           ; 
CAD7: 10 93 43        CMPD    <m0243              ; 
CADA: 2D 04           BLT     $CAE0               ; 
CADC: DD 43           STD     <m0243              ; 
CADE: 27 D4           BEQ     $CAB4               ; 
CAE0: DC 3E           LDD     <m023E              ; 
CAE2: 8D BB           BSR     $CA9F               ; 
CAE4: DD 3E           STD     <m023E              ; 
CAE6: 1F 89           TFR     A,B                 
CAE8: 1D              SEX                         
CAE9: C6 01           LDB     #$01                
CAEB: 97 3D           STA     <m023D              ; 
CAED: 2A 01           BPL     $CAF0               ; 
CAEF: 50              NEGB                        
CAF0: D7 45           STB     <m0245              ; 
CAF2: DC 41           LDD     <m0241              ; 
CAF4: 8D A9           BSR     $CA9F               ; 
CAF6: DD 41           STD     <m0241              ; 
CAF8: 1F 89           TFR     A,B                 
CAFA: 1D              SEX                         
CAFB: C6 20           LDB     #$20                
CAFD: 97 40           STA     <m0240              ; 
CAFF: 2A 01           BPL     $CB02               ; 
CB01: 50              NEGB                        
CB02: D7 46           STB     <m0246              ; 
CB04: DC 31           LDD     <newPointX          ; 
CB06: DD 37           STD     <m0237              ; 
CB08: DC 2F           LDD     <newPointY          ; 
CB0A: DD 3A           STD     <m023A              ; 
CB0C: 86 80           LDA     #$80                
CB0E: 97 39           STA     <m0239              ; 
CB10: 97 3C           STA     <m023C              ; 
CB12: AE 42           LDX     2,U                 
CB14: 9F 49           STX     <m0249              ; 
CB16: AE C4           LDX     ,U                  
CB18: 9F 47           STX     <m0247              ; 
CB1A: DC 3A           LDD     <m023A              ; 
CB1C: BD CA 0C        JSR     Dleft5              ; 
CB1F: 30 8B           LEAX    D,X                 
CB21: DC 37           LDD     <m0237              ; 
CB23: BD D3 7F        JSR     DRight3             ; 
CB26: 30 8B           LEAX    D,X                 
CB28: CE CB 8E        LDU     #$CB8E              ; Bit table (80,40,20,10,08,04,02,01)
CB2B: 10 9E 43        LDY     <m0243              ; 
CB2E: 0A 2E           DEC     <m022E              ; 
CB30: 26 22           BNE     $CB54               ; 
CB32: 96 2D           LDA     <dotFrequency       ; 
CB34: 97 2E           STA     <m022E              ; 
CB36: 0D 37           TST     <m0237              ; 
CB38: 26 1A           BNE     $CB54               ; 
CB3A: 9C 47           CMPX    <m0247              ; 
CB3C: 25 16           BCS     $CB54               ; 
CB3E: 9C 49           CMPX    <m0249              ; 
CB40: 24 12           BCC     $CB54               ; 
CB42: D6 38           LDB     <m0238              ; 
CB44: C4 07           ANDB    #$07                
CB46: A6 C5           LDA     B,U                 ; A = 2^b
CB48: 0D 2C           TST     <backgroundColor    ; 
CB4A: 27 04           BEQ     $CB50               ; 
CB4C: 43              COMA                        
CB4D: A4 84           ANDA    ,X                  
CB4F: 8C                  ; CMPX  opcode to skip next instruction
CB50: AA 84           ORA     ,X                  
CB52: A7 84           STA     ,X                  
CB54: 96 38           LDA     <m0238              ; 
CB56: 84 F8           ANDA    #$F8                
CB58: 97 C1           STA     <temp1              ; 
CB5A: DC 38           LDD     <m0238              ; 
CB5C: D3 3E           ADDD    <m023E              ; 
CB5E: DD 38           STD     <m0238              ; 
CB60: D6 37           LDB     <m0237              ; 
CB62: D9 3D           ADCB    <m023D              ; 
CB64: D7 37           STB     <m0237              ; 
CB66: 84 F8           ANDA    #$F8                
CB68: 91 C1           CMPA    <temp1              ; 
CB6A: 27 04           BEQ     $CB70               ; 
CB6C: D6 45           LDB     <m0245              ; 
CB6E: 30 85           LEAX    B,X                 
CB70: DC 3B           LDD     <m023B              ; 
CB72: 97 C1           STA     <temp1              ; 
CB74: D3 41           ADDD    <m0241              ; 
CB76: DD 3B           STD     <m023B              ; 
CB78: D6 3A           LDB     <m023A              ; 
CB7A: D9 40           ADCB    <m0240              ; 
CB7C: D7 3A           STB     <m023A              ; 
CB7E: 91 C1           CMPA    <temp1              ; 
CB80: 27 04           BEQ     $CB86               ; 
CB82: D6 46           LDB     <m0246              ; 
CB84: 30 85           LEAX    B,X                 
CB86: 31 3F           LEAY    -1,Y                
CB88: 26 A4           BNE     $CB2E               ; 
CB8A: 0A 2D           DEC     <dotFrequency       ; 
CB8C: 35 F6           PULS    A,B,X,Y,U,PC        

BitNumbers:
; Left to right
CB8E: 80 40 20 10 08 04 02 01
        
GetNextWord:               
CB96: 34 52           PSHS    U,X,A               ; Hold these
CB98: 9E 11           LDX     <m0211              ; Unparsed user input
CB9A: CE 03 13        LDU     #$0313              ; Decode buffer
CB9D: A6 80           LDA     ,X+                 ; Next character
CB9F: 27 FC           BEQ     $CB9D               ; Skip to ...
CBA1: 20 02           BRA     $CBA5               ; ... first non-space
CBA3: A6 80           LDA     ,X+                 
CBA5: 2F 08           BLE     $CBAF               ; End of the input line
CBA7: A7 C0           STA     ,U+                 ; Store the non-space character
CBA9: 11 83 03 33     CMPU    #$0333              ; Only 32 characters input ...
CBAD: 25 F4           BCS     $CBA3               ; ... allowed
CBAF: 86 FF           LDA     #$FF                ; Mark the end ...
CBB1: A7 C0           STA     ,U+                 ; ... of the input
CBB3: 9F 11           STX     <m0211              ; 
CBB5: 7D 03 13        TST     tmpBuffer1          ; Is there anything?
CBB8: 35 D2           PULS    A,X,U,PC            ; Done
    
CBBA: 0F 90           CLR     <m0290              ; 
CBBC: 8E D9 6A        LDX     #$D96A              ; Class names
CBBF: 8D 2B           BSR     DecodeInput         ; 
CBC1: 2B 05           BMI     $CBC8               ; 
CBC3: 27 1A           BEQ     $CBDF               ; 
CBC5: DD 8E           STD     <holdIncantWord     ; 
CBC7: 39              RTS                         
;
CBC8: 0A 90           DEC     <m0290              ; 
CBCA: 8E D8 F3        LDX     #$D8F3              ; Proper names
CBCD: 8D 18           BSR     $CBE7               ; 
CBCF: 2F 0E           BLE     $CBDF               ; 
CBD1: DD 8E           STD     <holdIncantWord     ; 
CBD3: 8E D9 6A        LDX     #$D96A              ; Class names
CBD6: 8D 14           BSR     DecodeInput         ; 
CBD8: 2F 05           BLE     $CBDF               ; 
CBDA: D1 8F           CMPB    <holdIncantLen      ; 
CBDC: 26 01           BNE     $CBDF               ; 
CBDE: 39              RTS                         
CBDF: 32 62           LEAS    2,S                 ; Skip a stack frame to return error
CBE1: 3F              SWI                         ; Print "???"
CBE2: 02                                          ; SWI_2:Uncompress message m and display:
CBE3: 17 7B D0                                    ; "???"
CBE6: 39              RTS                         ; Done

CBE7: 34 76           PSHS    U,Y,X,B,A           
CBE9: 4F              CLRA                        
CBEA: 20 08           BRA     $CBF4               ; 

DecodeInput:
; Find the next input word in the given table of words.
; X=pointer to word table
; $313 is the input word
; Return Z=1 if no input
; Return Z=0 if input but no match
; ?? Need to look at the flags more ... callers do BLE
; Return A=word number, FF=no match (or multiple matches)
; Return B=length of command word
; Return $7B=FF if exact match, 0 if not (important to incantation)
CBEC: 34 76           PSHS    U,Y,X,B,A           ; Hold these
CBEE: 4F              CLRA                        ; Word number to return
CBEF: 5F              CLRB                        ; Command word length
CBF0: 8D A4           BSR     GetNextWord         ; Get the next user input word
CBF2: 2B 39           BMI     $CC2D               ; Nothing on the input. Return nothing.
CBF4: 0F 78           CLR     <foundMatch         ; Found-a-match flag
CBF6: 0F 7B           CLR     <perfectMatch       ; Perfect input match
CBF8: E6 80           LDB     ,X+                 ; Get the number ...
CBFA: D7 79           STB     <numWords           ; ... of words in table
CBFC: CE 03 13        LDU     #$0313              ; Start of typed word
CBFF: 3F              SWI                         ; Uncompress the command word
CC00: 05                                          ; SWI_5:Uncompress message X to buffer:
CC01: 10 8E 03 36     LDY     #$0336              ; 335 is the length, 336 starts the text
CC05: E6 C0           LDB     ,U+                 ; Char from uncompressed
CC07: 2B 0E           BMI     $CC17               ; We reached the end of the word ... a match
CC09: E1 A0           CMPB    ,Y+                 ; User input match the command word?
CC0B: 26 15           BNE     $CC22               ; No ...
CC0D: 6D A4           TST     ,Y                  ; More in the user buffer?
CC0F: 2A F4           BPL     $CC05               ; Yes ... keep checking against the command word
CC11: 6D C4           TST     ,U                  ; No more. Did we check all of the command word?
CC13: 2A 0D           BPL     $CC22               ; Yes ... we have a match
CC15: 0A 7B           DEC     <perfectMatch       ; FF means there was an exact match
CC17: 0D 78           TST     <foundMatch         ; Do we already have a match?
CC19: 26 10           BNE     $CC2B               ; Error ... this could match multiple words
CC1B: 0C 78           INC     <foundMatch         ; Now we have a match
CC1D: F6 03 35        LDB     tmpBuffer2          ; Length of command word
CC20: ED E4           STD     ,S                  ; Store potential match on the stack to return
CC22: 4C              INCA                        ; Word number for next test word
CC23: 0A 79           DEC     <numWords           ; Tried all words?
CC25: 26 D5           BNE     $CBFC               ; No ... keep looking
CC27: 0D 78           TST     <foundMatch         ; Did we find a match?
CC29: 26 04           BNE     $CC2F               ; Yes ... leave it as it on the stack
CC2B: DC 03           LDD     <CONST_FF           ; 
CC2D: ED E4           STD     ,S                  ; No matches ... store error to return in D
CC2F: 35 F6           PULS    A,B,X,Y,U,PC        ; Done

GetUserHand:
; The second word is LEFT or RIGHT. Return the pointer to the pointer in U and the
; pointer to the object in X.
CC31: 8E D8 D9        LDX     #$D8D9              ; Second words
CC34: 8D B6           BSR     DecodeInput         ; Decode the input word
CC36: 2F A7           BLE     $CBDF               ; Didn't get a match ... print "???" and abort
CC38: CE 02 1F        LDU     #$021F              ; Pointer to right hand
CC3B: 81 01           CMPA    #$01                ; Word was "RIGHT" ?
CC3D: 27 07           BEQ     $CC46               ; Yes. Return slot and object
CC3F: CE 02 1D        LDU     #$021D              ; Pointer to left hand
CC42: 81 00           CMPA    #$00                ; Word was "LEFT" ?
CC44: 26 99           BNE     $CBDF               ; No ... error and abort
CC46: AE C4           LDX     ,U                  ; Yes. Return slot and object
CC48: 39              RTS                         ; Done

GetNeighborCells:
; This function gets the cell values for the 8 cells surrounding a given cell (and the
; value of the center square as well). If a cell is on the edge of the map then the
; invalid neighbor value is FF ... just as if it were solid.
;
; Param A,B: The Y,X coordinate of the center cell
; Param U: The 9-byte buffer to store results in
;
; The cell values are stored in the U buffer in this order from the maze map.
; 0 1 2
; 3 4 5
; 6 7 8
;
CC49: 34 56           PSHS    U,X,B,A             ; Preserve registers
CC4B: 4A              DECA                        ; Y-1
CC4C: 8D 08           BSR     $CC56               ; Check row (Y-1,*)
CC4E: 4C              INCA                        ; Back to center
CC4F: 8D 05           BSR     $CC56               ; Check row (Y,*)
CC51: 4C              INCA                        ; Y+1
CC52: 8D 02           BSR     $CC56               ; Check row (Y+1,*)
CC54: 35 D6           PULS    A,B,X,U,PC          ; Restore and out
;
CC56: 34 06           PSHS    B,A                 ; Hold Y,X coordinates
CC58: 5A              DECB                        ; X-1
CC59: 8D 05           BSR     $CC60               ; Check Y,X-1
CC5B: 5C              INCB                        ; Back to center
CC5C: 8D 02           BSR     $CC60               ; Check Y,X
CC5E: 5C              INCB                        ; X+1
CC5F: 8C                  ; CMPX  opcode to skip next instruction
CC60: 34 06           PSHS    B,A                 
CC62: 8D 2A           BSR     IsValidCell         ; Is the cell valid?
CC64: 26 05           BNE     $CC6B               ; No ... Store FF to cell buffer
CC66: 8D 13           BSR     GetCellPointer      ; Get the pointer to the cell
CC68: A6 84           LDA     ,X                  ; Get the value from the maze
CC6A: 8C                  ; CMPX  opcode to skip next instruction
CC6B: 86 FF           LDA     #$FF                
CC6D: A7 C0           STA     ,U+                 ; Store the result in the buffer
CC6F: 35 86           PULS    A,B,PC              ; Done

GetRandomCell:
; This function returns a random X,Y coordinate in the maze
; and the pointer to the cell memory in X.
;
; Return A: 0-31 (Y coordinate)
; Return B: 0-31 (X coordinate)
; Return X: Pointer to cell in memory
;
CC71: 3F              SWI                         ; Get random number in A
CC72: 07                                          ; SWI_7:Get random number:
CC73: 84 1F           ANDA    #$1F                ; 0-31 ... X coordinate
CC75: 1F 89           TFR     A,B                 ; Coordinate to B
CC77: 3F              SWI                         ; Get random number in A
CC78: 07                                          ; SWI_7:Get random number:
CC79: 84 1F           ANDA    #$1F                ; 0-31 ... Y coordinate
;
GetCellPointer:
; Return the pointer to cell memory in X for the Y,X coordinate in A,B
;
CC7B: 34 06           PSHS    B,A                 ; Hold these
CC7D: 84 1F           ANDA    #$1F                ; Limit coordiantes ...
CC7F: C4 1F           ANDB    #$1F                ; ... (another entry point)
CC81: 1F 01           TFR     D,X                 ; Hold in X
CC83: C6 20           LDB     #$20                ; Multiply A (Y coordinate) ...
CC85: 3D              MUL                         ; ... by 32 (one row)
CC86: C3 05 F4        ADDD    #$05F4              ; Offset to maze
CC89: 1E 01           EXG     D,X                 ; X coordinate back to B
CC8B: 3A              ABX                         ; Add in the X coordinate
CC8C: 35 86           PULS    A,B,PC              ; Return coordinate and pointer

IsValidCell:
; This function tests a given X,Y coordinate and returns
; Z=1 if within (31,31) or Z=0 if the coordinate is out
; of bounds.
;
; Param A: Y coordinate
; Param B: X coordinate
;
; Return Z: 1 if OK or 0 if out-of-bounds
;
CC8E: 34 06           PSHS    B,A                 ; Push the coordinates on the stack
CC90: 84 1F           ANDA    #$1F                ; Mask the coordinate to within range
CC92: A1 E4           CMPA    ,S                  ; Is the coordinate within range?
CC94: 26 04           BNE     $CC9A               ; No ... out
CC96: C4 1F           ANDB    #$1F                ; Mask the coordinate to within range
CC98: E1 61           CMPB    1,S                 ; Is the coordinate within range? (return Z=1 if so)
CC9A: 35 86           PULS    A,B,PC              ; Return with Z=1 if OK or Z=0 if out of range
  
MakeMazeLevel:
; The maze is a 32x32 cell (one byte per cell) table at $05F4. Each cell has 4 2-bit fields that
; describe the wall in a given direction. A value of 00 means the wall in that direction is open.
; A value of 01 is a normal door in that direction. A value of 10 is a magic door in that direction.
; A value of 11 is a solid wall. The 4 fields are stored in the byte as: LL_DD_RR_UU with UU being
; the least significant 2 bits.
;
; The maze is generated by carving out a series of random "runs". The code picks a random starting
; cell and a random direction. It picks a random "number of crossings" for the run from 1 to 8.
; Then it starts opening cells in that direction one by one until one of the following occurs:
; - The run crosses the randomly chosen number of other runs
; - The run reaches the edge of the map
; - The cell would create a block of 4 adjacent open cells
;
; The 3D display during game play can only draw hallways. Four adjacent open cells would create an
; open space that the display can't handle. Thus the check in the run algorithm.
;
; The algorithm keeps count of each new open cell created. Runs are generated until exactly 500 cells
; have been opened. Each level has exactly 500 open cells in it.
;
; Once the 500 cells are open the code adds exactly 70 regular doors and 45 magic doors between adjacent
; cells. Both cells get a copy of the door in opposite directions.
;
; It is possible (though unlikely) to create a run that does not overlap another. This would be an
; unreachable area that would trap the player or required monsters. Each level is drawn with a pre-chosen
; random number seed. Thus the level is always the same, and the designers chose seeds that produce good
; mazes.
;
; Holes and ladders are manually defined for each level and are kept in a separate table.
;
; Maze value: LL_DD_RR_UU
; 00 = open
; 01 = normal door
; 10 = magic door
; 11 = blocked
;
CC9C: 8E 05 F4        LDX     #$05F4              ; Start of level
CC9F: CE 09 F4        LDU     #$09F4              ; One past end of level (32*32=1024 byte)
CCA2: 3F              SWI                         ; Fill the buffer with FFs
CCA3: 12                                          ; SWI_12:Fill X to U with FFs:
CCA4: 8E CD 9F        LDX     #$CD9F              ; Random number seeds
CCA7: D6 81           LDB     <currentLevel       ; Offset into seeds ...
CCA9: 3A              ABX                         ; ... for this level
CCAA: EC 81           LDD     ,X++                ; Copy the ...
CCAC: DD 6B           STD     <rndSeedA           ; ... 3 byte ...
CCAE: A6 84           LDA     ,X                  ; ... seed to ...
CCB0: 97 6D           STA     <rndSeedC           ; ... current seed
CCB2: 10 8E 01 F4     LDY     #$01F4              ; Make 500 cells in the "run" process
CCB6: BD CC 71        JSR     GetRandomCell       ; Get a random coordinate
CCB9: DD 7C           STD     <drwMazeY           ; Hold the starting point
;
; Start a new maze "run" of cells
CCBB: 3F              SWI                         ; Get a random number
CCBC: 07                                          ; SWI_7:Get random number:
CCBD: 84 03           ANDA    #$03                ; Now a random direction (0-3)
CCBF: 97 8A           STA     <drwMazeDir         ; Hold current direction
CCC1: 3F              SWI                         ; Get a random number
CCC2: 07                                          ; SWI_7:Get random number:
CCC3: 84 07           ANDA    #$07                ; Random 0..7
CCC5: 4C              INCA                        ; Random 1..8
CCC6: 97 7E           STA     <drwMazeCross       ; Store number of crossings
CCC8: 20 08           BRA     $CCD2               ; Start this run with a step

CCCA: DC 88           LDD     <drwMazeTmp         ; Get the potential new coordinate
CCCC: DD 7C           STD     <drwMazeY           ; Make it the new cell
CCCE: 0A 7E           DEC     <drwMazeCross       ; All crossings in this run placed?
CCD0: 27 E9           BEQ     $CCBB               ; Yes ... start a new run (done with this one)
;
CCD2: DC 7C           LDD     <drwMazeY           ; Get the current cell pointer
CCD4: BD D1 1B        JSR     StepInDirection     ; Move in the random direction
CCD7: 8D B5           BSR     IsValidCell         ; Is this cell out of bounds?
CCD9: 26 E0           BNE     $CCBB               ; Yes ... start a new run
CCDB: DD 88           STD     <drwMazeTmp         ; Hold the new coordinates
CCDD: 6D 84           TST     ,X                  ; Already an open cell there?
CCDF: 27 E9           BEQ     $CCCA               ; Yes ... count it and keep going (no need to check it)
CCE1: CE 09 F4        LDU     #$09F4              ; Buffer to hold cell values
;
; These checks prevent opening a cell if it would make a block-of-4-opens. An open block can't be
; drawn during game play.
CCE4: BD CC 49        JSR     GetNeighborCells    ; Get the neighbor cell values
CCE7: A6 43           LDA     3,U                 ; Cell to the left
CCE9: AB C4           ADDA    ,U                  ; Cell to the upper left
CCEB: AB 41           ADDA    1,U                 ; Cell above
CCED: 27 CC           BEQ     $CCBB               ; This would make the upper left corner 4-opens together. Skip
;
CCEF: A6 41           LDA     1,U                 ; Cell above
CCF1: AB 42           ADDA    2,U                 ; Cell to the upper right
CCF3: AB 45           ADDA    5,U                 ; Cell to the right
CCF5: 27 C4           BEQ     $CCBB               ; This would make the upper right corner 4-opens together. Skip
;
CCF7: A6 45           LDA     5,U                 ; Cell to the right
CCF9: AB 48           ADDA    8,U                 ; Cell to the lower right
CCFB: AB 47           ADDA    7,U                 ; Cell below
CCFD: 27 BC           BEQ     $CCBB               ; This would make the lower right corner 4-opens together. Skip
;
CCFF: A6 47           LDA     7,U                 ; Cell below
CD01: AB 46           ADDA    6,U                 ; Cell to the lower left
CD03: AB 43           ADDA    3,U                 ; Cell to the left
CD05: 27 B4           BEQ     $CCBB               ; This would make the lower left corner 4-opens together. Skip
;
CD07: 6F 84           CLR     ,X                  ; Open this cell up
CD09: 31 3F           LEAY    -1,Y                ; All 500 cells done?
CD0B: 26 BD           BNE     $CCCA               ; No ... use this and keep going
;
; This loops over the cells and sets the "solid wall" bits for directions that are blocked.
CD0D: 0F 7C           CLR     <drwMazeY           ; Start with ...
CD0F: 0F 7D           CLR     <drwMazeX           ; ... Y,X = 0,0
CD11: DC 7C           LDD     <drwMazeY           ; Get the current coordinate
CD13: BD CC 7B        JSR     GetCellPointer      ; Get the cell pointer
CD16: A6 84           LDA     ,X                  ; Get the cell value
CD18: 4C              INCA                        ; Is this a solid?
CD19: 27 26           BEQ     $CD41               ; Yes ... skip it
CD1B: DC 7C           LDD     <drwMazeY           ; Coordinates again
CD1D: CE 09 F4        LDU     #$09F4              ; Status buffer
CD20: BD CC 49        JSR     GetNeighborCells    ; Get the status of the neighbors
CD23: A6 84           LDA     ,X                  ; Get the value of the cell
CD25: C6 FF           LDB     #$FF                ; Value FF (solid) for compares
CD27: E1 41           CMPB    1,U                 ; Cell above us open?
CD29: 26 02           BNE     $CD2D               ; No ... leave the bits open
CD2B: 8A 03           ORA     #$03                ; Set the "up" bits to solid wall
CD2D: E1 43           CMPB    3,U                 ; Cell to the left open?
CD2F: 26 02           BNE     $CD33               ; No ... leave the bits open
CD31: 8A C0           ORA     #$C0                ; Set the "left" bits to solid wall
CD33: E1 45           CMPB    5,U                 ; Cell to the right open?
CD35: 26 02           BNE     $CD39               ; No ... leave the bits open
CD37: 8A 0C           ORA     #$0C                ; Set the "right" bits to solid wall
CD39: E1 47           CMPB    7,U                 ; Cell to the bottom open?
CD3B: 26 02           BNE     $CD3F               ; No ... leave the bits open
CD3D: 8A 30           ORA     #$30                ; Set the "down" bits to solid wall
CD3F: A7 84           STA     ,X                  ; Set solid walls on the edge cells
;
; Add walls next to solid cells
CD41: C6 20           LDB     #$20                ; 32 for compare
CD43: 0C 7D           INC     <drwMazeX           ; Bump the X coordinate
CD45: D1 7D           CMPB    <drwMazeX           ; Reached end of row?
CD47: 26 C8           BNE     $CD11               ; No ... keep going
CD49: 0F 7D           CLR     <drwMazeX           ; Back to X=0
CD4B: 0C 7C           INC     <drwMazeY           ; Bump the Y coordinate
CD4D: D1 7C           CMPB    <drwMazeY           ; End of maze?
CD4F: 26 C0           BNE     $CD11               ; No ... keep going
;
; Add 70 regular doors
CD51: C6 46           LDB     #$46                ; 70 regular doors to make
CD53: CE CD AA        LDU     #$CDAA              ; Table of bit patterns for regular doors
CD56: 8D 15           BSR     $CD6D               ; Make a random regular door
CD58: 5A              DECB                        ; All done?
CD59: 26 FB           BNE     $CD56               ; No ... do all
;
; Add 45 magic doors
CD5B: C6 2D           LDB     #$2D                ; 45 magic doors to make
CD5D: CE CD AE        LDU     #$CDAE              ; Table of bit patterns for magic doors
CD60: 8D 0B           BSR     $CD6D               ; Make a random magic door
CD62: 5A              DECB                        ; All done?
CD63: 26 FB           BNE     $CD60               ; No ... do all
;
; Reseed the random number based on the number of seconds in the ISR counter
CD65: D6 97           LDB     <counterSeconds     ; Number of seconds passed (random 0 to 59)
CD67: 3F              SWI                         ; Get next ...
CD68: 07                                          ; SWI_7:Get random number:
CD69: 5A              DECB                        ; Randomized the full count?
CD6A: 26 FB           BNE     $CD67               ; No ... do all
CD6C: 39              RTS                         ; Out
;
; Make a door (regular or magic) between two adjacent cells
CD6D: 34 76           PSHS    U,Y,X,B,A           ; Preserve registers
CD6F: 10 8E CD A6     LDY     #$CDA6              ; Bit patterns for solid walls in each direction
CD73: BD CC 71        JSR     GetRandomCell       ; Get random cell
CD76: DD 88           STD     <drwMazeTmp         ; Hold coordinates
CD78: E6 84           LDB     ,X                  ; Get cell value
CD7A: C1 FF           CMPB    #$FF                ; Is it solid?
CD7C: 27 F5           BEQ     $CD73               ; Yes ... find an open cell
CD7E: 3F              SWI                         ; Get a random number
CD7F: 07                                          ; SWI_7:Get random number:
CD80: 84 03           ANDA    #$03                ; Make it a direction
CD82: 97 8A           STA     <drwMazeDir         ; Store the direction
CD84: E5 A6           BITB    A,Y                 ; Is that direction open (no solid and no existing door)?
CD86: 26 EB           BNE     $CD73               ; No ... find another
CD88: EA C6           ORB     A,U                 ; Or in the pattern for the door (magic or regular)
CD8A: E7 84           STB     ,X                  ; Set the new pattern
CD8C: DC 88           LDD     <drwMazeTmp         ; Get coordinates
CD8E: BD D1 1B        JSR     StepInDirection     ; Step in that direction
CD91: D6 8A           LDB     <drwMazeDir         ; Get the direction we came in
CD93: CB 02           ADDB    #$02                ; Flip it ...
CD95: C4 03           ANDB    #$03                ; ... around
CD97: A6 84           LDA     ,X                  ; Get value
CD99: AA C5           ORA     B,U                 ; Make same door in ...
CD9B: A7 84           STA     ,X                  ; ... on both sides
CD9D: 35 F6           PULS    A,B,X,Y,U,PC        ; Restore and out

RandomSeeds:
; These seeds control the shape of the dungeon and placement
; of creatures. Three bytes instead of over 1K of data -- good
; idea. The levels overlap seeds as shown below.
;     0-------
;        1-------
;           2-------
;              3-------
;                 4-------
CD9F: 73 C7 5D 97 F3 13 87   
            
; Bit positions for walls in a given direction (0-3)
;     0U 1R 2D 3L
CDA6: 03 0C 30 C0

; Bit positions to add a regular door in a given direction
CDAA: 01 04 10 40

; Bit positions to add a magic door in a give direction
CDAE: 02 08 20 80                                    

ShowMap:
; This is the draw-screen function for the scroll
CDB2: DE 0B           LDU     <backScreen         ; Drawing screen descriptor
CDB4: CC 1F 1F        LDD     #$1F1F              ; 32x32
CDB7: DD 7C           STD     <drwMazeY           ; Store the count
;
; First draw the open/closed states of all cells in the maze;
CDB9: DC 7C           LDD     <drwMazeY           ; Get the current map coordinate
CDBB: 8D 54           BSR     GetMapCellMem       ; Get a screen pointer to the cell in Y
CDBD: BD CC 7B        JSR     GetCellPointer      ; Get a pointer to the maze memory
CDC0: 5F              CLRB                        ; Initial cell state (open)
CDC1: A6 84           LDA     ,X                  ; Get the cell wall state
CDC3: 4C              INCA                        ; Is it FF (solid)?
CDC4: 26 01           BNE     $CDC7               ; No ... draw it open
CDC6: 5A              DECB                        ; Cell state is solid
CDC7: 86 06           LDA     #$06                ; Six rows per cell
CDC9: E7 A4           STB     ,Y                  ; Draw ...
CDCB: 31 A8 20        LEAY    $20,Y               ; ... six ...
CDCE: 4A              DECA                        ; ... row ...
CDCF: 26 F8           BNE     $CDC9               ; ... block
CDD1: 0A 7D           DEC     <drwMazeX           ; Move left one cell
CDD3: 2A E4           BPL     $CDB9               ; Do all of the row
CDD5: 86 1F           LDA     #$1F                ; Restart row at ...
CDD7: 97 7D           STA     <drwMazeX           ; ... far right
CDD9: 0A 7C           DEC     <drwMazeY           ; Move up a row
CDDB: 2A DC           BPL     $CDB9               ; Do all rows
;
CDDD: 0D 94           TST     <scrollType         ; Is this a "seer" scroll?
CDDF: 27 4A           BEQ     $CE2B               ; No ... skip drawing monsters and objects
;
; Show objects on floor (Seer Scroll)
CDE1: 0F 91           CLR     <restartFind        ; Start at top of list
CDE3: BD CF 63        JSR     GetNextOject        ; Get next object on floor
CDE6: 27 0F           BEQ     $CDF7               ; All done ... do monsters
CDE8: 6D 05           TST     5,X                 ; Is this on the floor?
CDEA: 26 F7           BNE     $CDE3               ; No ... don't show it
CDEC: EC 02           LDD     2,X                 ; Get the Y,X coordinate
CDEE: 8D 21           BSR     GetMapCellMem       ; Get map screen pointer for coordinate
CDF0: CC 00 08        LDD     #$0008              ; 4 byte graphics pattern (small dot) for object
CDF3: 8D 28           BSR     DrawMapSymbol       ; Draw an object on the map
CDF5: 20 EC           BRA     $CDE3               ; Draw next object on floor
;
; Show monsters (Seer Scroll)
CDF7: 8E 03 C3        LDX     #$03C3              ; First monster (actually one slot before)
CDFA: 30 88 11        LEAX    $11,X               ; Next monster
CDFD: 8C 05 F4        CMPX    #$05F4              ; All done?
CE00: 27 29           BEQ     $CE2B               ; Yes ... draw holes and ladders
CE02: 6D 0C           TST     12,X                ; Is this creature active?
CE04: 27 F4           BEQ     $CDFA               ; No ... skip it
CE06: EC 0F           LDD     15,X                ; Get the creature coordinates
CE08: 8D 07           BSR     GetMapCellMem       ; Get a pointer to the map screen
CE0A: CC 10 54        LDD     #$1054              ; 4 byte graphics pattern (large dot) for monster
CE0D: 8D 0E           BSR     DrawMapSymbol       ; Draw a creature on the map
CE0F: 20 E9           BRA     $CDFA               ; Do all creatures

GetMapCellMem:
; This functions returns a pointer to the screen for a given cell (Y,X coordinate).
; On the screen, cells are 6-rows high and 8-pixels (one byte) wide.
;
; Param A,B: The Y,X cell coordinate
; Param U:   Start of screen memory
; Return Y:  Pointer to the screen memory for the cell
;
CE11: 1F 02           TFR     D,Y                 ; Hold the coordinate
CE13: C6 C0           LDB     #$C0                ; Multiply Y time ...
CE15: 3D              MUL                         ; ... 32*6 (6 rows per cell)
CE16: E3 C4           ADDD    ,U                  ; Offset to screen row
CE18: 1E 02           EXG     D,Y                 ; X to B (pointer to Y)
CE1A: 31 A5           LEAY    B,Y                 ; Add in the column offset
CE1C: 39              RTS                         ; Done

DrawMapSymbol:
; Map symbols are 4 bytes on the screen. They are symmetrical in that the
; top and bottom row are the same and the middle two rows are the same.
;
; Param A: top and bottom pixel pattern
; Param B: middle 2 rows pixel pattern
;
CE1D: A7 A8 20        STA     $20,Y               ; Top row pattern (A)
CE20: E7 A8 40        STB     $40,Y               ; Middle row pattern (B)
CE23: E7 A8 60        STB     $60,Y               ; Middle row pattern (B)
CE26: A7 A9 00 80     STA     $0080,Y             ; Bottom row pattern (A)
CE2A: 39              RTS                         ; Done

; Draws holes and player on map (both scroll types)
CE2B: DC 13           LDD     <playerY            ; Player Y,X coordinate
CE2D: 8D E2           BSR     GetMapCellMem       ; Player's cell on map screen
CE2F: CC 24 18        LDD     #$2418              ; 4 byte pattern (X) for player
CE32: 8D E9           BSR     DrawMapSymbol       ; Draw player on the map
;
; Two passes here. 1st draw the holes in the current ceiling. Then draw the holes
; in the current floor.
CE34: 9E 86           LDX     <currentHoles       ; Pointer to ceiling holes/ladders for current level
CE36: 8D 00           BSR     $CE38               ; Draw the holes in this floor's ceiling (fall through to show floor holes)
CE38: A6 80           LDA     ,X+                 ; Get hole type
CE3A: 2B EE           BMI     $CE2A               ; End of list? Yes ... out
CE3C: EC 81           LDD     ,X++                ; Get the hole's Y,X coordinate
CE3E: 8D D1           BSR     GetMapCellMem       ; Convert to screen pointer
CE40: CC 3C 24        LDD     #$3C24              ; 4 byte pattern (open circle) for hole
CE43: 8D D8           BSR     DrawMapSymbol       ; Draw the hole
CE45: 20 F1           BRA     $CE38               ; Keep going

SetCellScaleFactor:
CE47: 34 12           PSHS    X,A                 ; Preserve
CE49: 8E CF 48        LDX     #$CF48              ; Scale factor table
CE4C: 0D 73           TST     <halfStepForward    ; Are we drawing the maze stepped forward half step?
CE4E: 26 0C           BNE     $CE5C               ; Yes ... keep this "no draw" entry
CE50: 30 89 00 01     LEAX    $0001,X             ; No ... keep the half-step entry
CE54: 0D 74           TST     <halfStepBack       ; Are we drawing the maze stepped backward half step?
CE56: 26 04           BNE     $CE5C               ; Yes ... keep this entry
CE58: 30 89 FF F5     LEAX    -$000B,X            ; No ... use the regular factors
CE5C: 96 8B           LDA     <drwMazeCellNum     ; Get the room offset
CE5E: A6 86           LDA     A,X                 ; Set ...
CE60: 97 4F           STA     <xScaleFactor       ; ... the cells ...
CE62: 97 50           STA     <yScaleFactor       ; ... scaling factor
CE64: 35 92           PULS    A,X,PC              ; Restore

NormalDisplay:
; This is the routine called to draw the normal game display
CE66: 3F              SWI                         ; Clear the back buffer
CE67: 09                                          ; SWI_9:Clear secondary screen:
CE68: 0F 8B           CLR     <drwMazeCellNum     ; Start with room 0 in the line of rooms (player's room)
CE6A: DC 13           LDD     <playerY            ; Get the player's ...
CE6C: DD 7C           STD     <drwMazeY           ; ... X and Y coordinate
CE6E: 8D D7           BSR     SetCellScaleFactor  ; Set the scaling factor to draw the room
CE70: DC 7C           LDD     <drwMazeY           ; Currently drawing room coordinate
CE72: BD CC 7B        JSR     GetCellPointer      ; Get the info ...
CE75: A6 84           LDA     ,X                  ; ... about this cell
CE77: CE 09 F4        LDU     #$09F4              ; A temporary decode buffer for wall status
CE7A: 8E 00 04        LDX     #$0004              ; 4 wall values
CE7D: 1F 89           TFR     A,B                 ; Status ...
CE7F: C4 03           ANDB    #$03                ; ... of one door
CE81: E7 44           STB     4,U                 ; Hold ...
CE83: E7 C0           STB     ,U+                 ; ... the status
CE85: 44              LSRA                        ; Shift ...
CE86: 44              LSRA                        ; ... to next ...
CE87: 30 1F           LEAX    -1,X                ; ... door in the info
CE89: 26 F2           BNE     $CE7D               ; Do all 4 directions
CE8B: D6 23           LDB     <playerDir          ; Player's direction
CE8D: CE 09 F4        LDU     #$09F4              ; Decoded wall status
CE90: 33 C5           LEAU    B,U                 ; Get the status of the wall the player is facing
CE92: 10 8E DB DE     LDY     #$DBDE              ; Wall pictures
;
CE96: A6 A0           LDA     ,Y+                 ; Wall status offset (from the wall table)
CE98: 2B 3E           BMI     $CED8               ; End of wall table ... done
CE9A: E6 C6           LDB     A,U                 ; Offset into wall table
CE9C: 58              ASLB                        ; Two bytes each
CE9D: C1 04           CMPB    #$04                ; Magic door?
CE9F: 26 08           BNE     $CEA9               ; No ... draw the one image door
CEA1: AE A5           LDX     B,Y                 ; Yes ... we draw two images. Get the magic triangle picture
CEA3: 0A 75           DEC     <m0275              ; ?? stop drawing down the hall? Hit a wall?
CEA5: 8D 27           BSR     $CECE               ; Draw the wall
CEA7: C6 06           LDB     #$06                ; Solid wall
CEA9: AE A5           LDX     B,Y                 ; Draw the ...
CEAB: 8D 21           BSR     $CECE               ; ... specific wall image
CEAD: 31 28           LEAY    8,Y                 ; Next wall
CEAF: 20 E5           BRA     $CE96               ; Do all 3 walls

CEB1: 39              RTS                         ; Done

CEB2: 1F 12           TFR     X,Y                 
CEB4: 6D C5           TST     B,U                 
CEB6: 26 F9           BNE     $CEB1               ; Done
CEB8: DB 23           ADDB    <playerDir          ; 
CEBA: D7 8A           STB     <drwMazeDir         ; 
CEBC: DC 7C           LDD     <drwMazeY           ; 
CEBE: BD D1 1B        JSR     StepInDirection     ; 
CEC1: BD CF 82        JSR     GetCreatureAt       ; Is there a creature in this cell?
CEC4: 27 EB           BEQ     $CEB1               ; No ... skip drawing it
CEC6: 1E 12           EXG     X,Y                 
CEC8: 6D 22           TST     2,Y                 
CECA: 27 02           BEQ     $CECE               ; 
CECC: 0A 75           DEC     <m0275              ; 
CECE: 34 40           PSHS    U                   ; Preserve
CED0: 3F              SWI                         ; Set the light level for the room
CED1: 00                                          ; SWI_0:Light level:
CED2: DE 0B           LDU     <backScreen         ; Back screen buffer
CED4: 3F              SWI                         ; Draw the picture on the back screen
CED5: 01                                          ; SWI_1:Draw picture X on screen:
CED6: 35 C0           PULS    U,PC                ; Done

CED8: DC 7C           LDD     <drwMazeY           ; 
CEDA: BD CF 82        JSR     GetCreatureAt       ; 
CEDD: 27 0C           BEQ     $CEEB               ; 
CEDF: 1F 12           TFR     X,Y                 
CEE1: E6 2D           LDB     13,Y                
CEE3: 58              ASLB                        
CEE4: 8E DA A3        LDX     #$DAA3              ; Get the picture ...
CEE7: AE 85           LDX     B,X                 ; ... of the creature
CEE9: 8D DD           BSR     $CEC8               ; 
CEEB: C6 03           LDB     #$03                
CEED: 8E DC B0        LDX     #$DCB0              ; Draw creature coming ...
CEF0: 8D C0           BSR     $CEB2               ; ... from left
CEF2: C6 01           LDB     #$01                
CEF4: 8E DC B9        LDX     #$DCB9              ; Draw creature coming ...
CEF7: 8D B9           BSR     $CEB2               ; ... from right
CEF9: 8E DD 3C        LDX     #$DD3C              ; ?? Part of the hole-in-floor
CEFC: DC 7C           LDD     <drwMazeY           ; 
CEFE: BD CF E1        JSR     ScanForHole         ; 
CF01: 2B 06           BMI     $CF09               ; 
CF03: 8E DC C2        LDX     #$DCC2              ; Holes and ladders pictures
CF06: 48              ASLA                        
CF07: AE 86           LDX     A,X                 
CF09: 8D C3           BSR     $CECE               ; 
CF0B: 0F 91           CLR     <restartFind        ; 
CF0D: DC 7C           LDD     <drwMazeY           ; 
CF0F: BD CF 53        JSR     GetObjectAtCoor     ; 
CF12: 27 10           BEQ     $CF24               ; 
CF14: A6 0A           LDA     10,X                
CF16: 48              ASLA                        
CF17: 8E D9 EE        LDX     #$D9EE              ; Object pictures (by class)
CF1A: AE 86           LDX     A,X                 
CF1C: 0A 75           DEC     <m0275              ; 
CF1E: 8D AE           BSR     $CECE               ; 
CF20: 8D AC           BSR     $CECE               ; 
CF22: 20 E9           BRA     $CF0D               ; 
CF24: 6D C4           TST     ,U                  
CF26: 26 15           BNE     $CF3D               ; 
CF28: 96 23           LDA     <playerDir          ; 
CF2A: 97 8A           STA     <drwMazeDir         ; 
CF2C: DC 7C           LDD     <drwMazeY           ; 
CF2E: BD D1 1B        JSR     StepInDirection     ; 
CF31: DD 7C           STD     <drwMazeY           ; 
CF33: 0C 8B           INC     <drwMazeCellNum     ; 
CF35: 96 8B           LDA     <drwMazeCellNum     ; 
CF37: 81 09           CMPA    #$09                
CF39: 10 2F FF 31     LBLE    $CE6E               ; 
CF3D: 39              RTS                         

CellZoomFactors:
; Used to draw the 3D rooms of the maze
CF3E: C8 80 50 32 1F 14 0C 08 04 02 ; Full step zooms (10 rooms ... current room drawn larger)
CF48: FF                            ; For step forward, first cell is NOT drawn
CF49: 9C 64 41 28 1A 10 0A 06 03 01 ; Half step zooms (10 rooms ... current room drawn larger)

GetObjectAtCoor:
; Get the next object on this level at the given coordinates
CF53: 8D 0E           BSR     GetNextOject        ; Get the next object
CF55: 27 0B           BEQ     $CF62               ; End of list ... out
CF57: 10 A3 02        CMPD    2,X                 ; Do the coordinates match?
CF5A: 26 F7           BNE     GetObjectAtCoor     ; No ... keep looking
CF5C: 6D 05           TST     5,X                 ; Is the object on the floor?
CF5E: 26 F3           BNE     GetObjectAtCoor     ; No ... keep looking
CF60: 1C FB           ANDCC   #$FB                ; Clear the zero flag (object found)
CF62: 39              RTS                         ; Done

GetNextOject:
; Get the next (or first) object on this level. Start over at top of list
; if requested or continue from last iteration.
;
; This walks the objects in memory without looking at their chain pointers.
;
; Param >$91 0 to start at top of list, 1 to continue from last
; Return object descriptor in X (if found)
; Return Z=1 if no more, Z=0 if next is in X
;
CF63: 34 02           PSHS    A                   ; Preserve A
CF65: 96 81           LDA     <currentLevel       ; Get current level number
CF67: 9E 92           LDX     <objIterator        ; Get current object pointer
CF69: 0D 91           TST     <restartFind        ; Start at top of list?
CF6B: 26 05           BNE     $CF72               ; No ... continue from last time
CF6D: 8E 0B 07        LDX     #$0B07              ; Start of list (-14 ... one slot before)
CF70: 0A 91           DEC     <restartFind        ; Next time through we won't restart
CF72: 30 0E           LEAX    14,X                ; Get pointer to next object
CF74: 9F 92           STX     <objIterator        ; Remember it
CF76: 9C 0F           CMPX    <nextObjSlot        ; Have we reached the end of the list?
CF78: 27 06           BEQ     $CF80               ; Yes ... out with nothing found
CF7A: A1 04           CMPA    4,X                 ; Level the same as what we want?
CF7C: 26 F4           BNE     $CF72               ; No ... next object
CF7E: 1C FB           ANDCC   #$FB                ; Clear the Z flag meaning there is a next object
CF80: 35 82           PULS    A,PC                ; Restore A and out

GetCreatureAt:
; Find the creature (if any) at the given Y,X coordinate.
; Param A,Y: The Y,X coordinate
; Return X: Pointer to creature if found
; Return NZ if found or Z if not found
;
CF82: 8E 03 C3        LDX     #$03C3              ; Start of creatures (minus pre-decrement)
CF85: 30 88 11        LEAX    $11,X               ; Point to next creature
CF88: 8C 05 F4        CMPX    #$05F4              ; Reached the end of the list?
CF8B: 27 09           BEQ     $CF96               ; Yes ... return Z set (not found)
CF8D: 10 A3 0F        CMPD    15,X                ; Right coordinates?
CF90: 26 F3           BNE     $CF85               ; No ... keep looking
CF92: 6D 0C           TST     12,X                ; Creature is active?
CF94: 27 EF           BEQ     $CF85               ; No ... keep looking (yes, Z=0)
CF96: 39              RTS                         ; Return

GetRandCell:
; Get a random open cell in the current maze.
; Return A,B: The Y,X coordinate of the random open cell
;
CF97: 34 16           PSHS    X,B,A               ; Preserve registers
CF99: BD CC 71        JSR     GetRandomCell       ; Get a random cell
CF9C: ED E4           STD     ,S                  ; Put it in return in case it is good
CF9E: A6 84           LDA     ,X                  ; Get the cell value
CFA0: 4C              INCA                        ; FF means all walls (solid)
CFA1: 27 F6           BEQ     $CF99               ; This is not a valid cell ... keep looking
CFA3: 35 96           PULS    A,B,X,PC            ; Return the random cell in A,B

CreateCreature:
; Create a new creature of the given type at the next available monster slot.
; The new creature is given a random valid coordinate. A handler task is created
; for the creature and queued on the tenths-of-a-second list
;
; Param A: The monster type
;
CFA5: 34 76           PSHS    U,Y,X,B,A           ; Preserve registers
CFA7: CE 03 C3        LDU     #$03C3              ; Start of creatures (03D4 minus 11 pre-increment)
CFAA: 33 C8 11        LEAU    $11,U               ; Point to next creature slot
CFAD: 6D 4C           TST     12,U                ; Is this a living creature?
CFAF: 26 F9           BNE     $CFAA               ; Yes ... find an empty slot
CFB1: 6A 4C           DEC     12,U                ; Mark this creature living
CFB3: A7 4D           STA     13,U                ; Set the type
CFB5: C6 08           LDB     #$08                ; 8 bytes of init data
CFB7: 3D              MUL                         ; Type * 8
CFB8: C3 DA BB        ADDD    #$DABB              ; Add to creature-class data table
CFBB: 1F 02           TFR     D,Y                 ; Source to Y
CFBD: 1F 31           TFR     U,X                 ; Destination to X
CFBF: 86 08           LDA     #$08                ; Bytes to copy = 8
CFC1: BD C0 4B        JSR     CopyYtoX            ; Copy the 8 bytes of initial data
CFC4: 8D D1           BSR     GetRandCell         ; Get a random cell
CFC6: 8D BA           BSR     GetCreatureAt       ; Is there already a creature there?
CFC8: 26 FA           BNE     $CFC4               ; Yes ... keep looking
CFCA: ED 4F           STD     15,U                ; Put the creature in the random cell
CFCC: 1F 31           TFR     U,X                 ; Hold the monster structure
CFCE: BD C2 5C        JSR     ReserveTask         ; Get a new task
CFD1: AF 45           STX     5,U                 ; Link the task to the monster structure
CFD3: CC D0 41        LDD     #$D041              ; Set the task ...
CFD6: ED 43           STD     3,U                 ; ... handler entry
CFD8: A6 06           LDA     6,X                 ; Task reload rate (speed of task) in tenths of a second
CFDA: C6 04           LDB     #$04                ; Place task on the ...
CFDC: BD C2 1D        JSR     ChainTaskToEnd      ; ... tenths-second-tick list
CFDF: 35 F6           PULS    A,B,X,Y,U,PC        ; Restore

ScanForHole:
; There can only be one hole in the current cell. This scans for a hole in the current
; cell and returns the type in A (or A is negative for none).
;
; Param A,B: Y,X cell coordinate to check
; Return A: Hole type (if found: 00=hole in ceiling, 01=ladder in ceiling, 10=hole in floor, 11=ladder in floor)
; Return Negative if not found, positive if found
;
CFE1: 34 56           PSHS    U,X,B,A             ; Preserve registers
CFE3: DE 86           LDU     <currentHoles       ; Holes in ceiling of current level
CFE5: 8D 0B           BSR     $CFF2               ; Check for a hole in the ceiling
CFE7: 4D              TSTA                        ; Is there one?
CFE8: 2A 04           BPL     $CFEE               ; Yes ... keep the data and skip the floor
CFEA: 8D 06           BSR     $CFF2               ; Check for a hole in the floor
CFEC: 8B 02           ADDA    #$02                ; Flag that it is in the floor
CFEE: A7 E4           STA     ,S                  ; Save the hole result (returns in A)
CFF0: 35 D6           PULS    A,B,X,U,PC          ; Out
;
; Run a list of holes and return the type of the hole
; that has the check coordiantes (or bit 7 set if not found)
CFF2: A6 C0           LDA     ,U+                 ; Get hole type
CFF4: 2B 06           BMI     $CFFC               ; End of list ... out
CFF6: AE C1           LDX     ,U++                ; Get hole coordinate
CFF8: AC 62           CMPX    2,S                 ; Matches the test coordinate?
CFFA: 26 F6           BNE     $CFF2               ; No ... keep looking
CFFC: 39              RTS                         ; Return A is hole type or bit 7 set if not found

HolesAndLadders:
; The game maintains a pointer-to-holes-in-current-ceiling in $286. The next list
; after is the list of holes-in-current-floor.
;
; Holes between surface and level 0 (none ... no surface)
CFFD: 80 
;
; Holes between levels 0 and 1
CFFE: 01 00 17 ; Ladder Y=00, X=17
D001: 00 0F 04 ; Hole   Y=0F, X=04
D004: 00 14 11 ; Hole   Y=14, X=11
D007: 01 1C 1E ; Ladder Y=1C, X=1E
D00A: 80 
;
; Holes between levels 1 and 2
D00B: 01 02 03 ; Ladder Y=02, X=03
D00E: 00 03 1F ; Hole   Y=03, X=1F
D011: 00 13 14 ; Hole   Y=13, X=14
D014: 00 1F 00 ; Hole   Y=1F, X=00
D017: 80
;
; Holes between levels 3 and 4 (none)
D018: 80 
;
; Holes between levels 4 and 5
D019: 00 00 1F ; Hole   Y=00, X=1F
D01C: 00 05 00 ; Hole   Y=05, X=00
D01F: 00 16 1C ; Hole   Y=16, X=1C
D022: 00 1F 10 ; Hole   Y=1F, X=10
D025: 80 
;
; Holes between levels 5 and 6 (none ... no level 6)
D026: 80

T4_MakeCreature:
D027: 9E 82           LDX     <creatureCounts     ; Creature count table
D029: C6 0B           LDB     #$0B                ; Last creature type (wizard)
D02B: 4F              CLRA                        ; Count of creatures on level
D02C: AB 85           ADDA    B,X                 ; Add up ...
D02E: 5A              DECB                        ; ... total ...
D02F: 2A FB           BPL     $D02C               ; ... creatures on level
D031: 81 20           CMPA    #$20                ; Already at a max of 32?
D033: 24 08           BCC     $D03D               ; Yes ... skip
D035: 3F              SWI                         ; Get a random creature number
D036: 07                                          ; SWI_7:Get random number:
D037: 84 07           ANDA    #$07                ; From ... 0 through 7
D039: 8B 02           ADDA    #$02                ; From ... 2 through 9 (not spider, snake, demon, or wizard)
D03B: 6C 86           INC     A,X                 ; Creature is created next time we init the level
D03D: CC 05 08        LDD     #$0508              ; Reloads to 5 on the minute-tick list
D040: 39              RTS                         ; Done

T_MoveCreature:
; U points to the task structure (contains a pointer to the creature)
D041: 10 AE 45        LDY     5,U                 ; Get pointer to creature from task structure
D044: 0D 2B           TST     <wizardDead         ; Is the wizard dead?
D046: 26 22           BNE     $D06A               ; Yes ... skip all actions
D048: E6 2C           LDB     12,Y                ; Is this creature alive?
D04A: 26 01           BNE     $D04D               ; Yes ... let it move
D04C: 39              RTS                         ; No ... done with this one
;
D04D: A6 2D           LDA     13,Y                ; Creature type
D04F: 81 06           CMPA    #$06                ; SCORPION?
D051: 27 1A           BEQ     $D06D               ; Yes ... they don't pick up things
D053: 81 0A           CMPA    #$0A                ; DEMON or WIZARD?
D055: 2C 16           BGE     $D06D               ; Yes ... they don't pick up things
D057: EC 2F           LDD     15,Y                ; Monster's coordinates
D059: 0F 91           CLR     <restartFind        ; Reset find cursor to 1st object
D05B: BD CF 53        JSR     GetObjectAtCoor     ; Get an object on the floor here
D05E: 27 0D           BEQ     $D06D               ; Nothing to pick up
D060: EC 28           LDD     8,Y                 ; This monster's list of held items
D062: AF 28           STX     8,Y                 ; Push this object to ...
D064: ED 84           STD     ,X                  ; ... the top of the list
D066: 6A 05           DEC     5,X                 ; Set object location to MONSTER
D068: 3F              SWI                         ; Update the screen (stuff was picked up)
D069: 0E                                          ; SWI_E:Display playing screen:
;
D06A: 7E D1 03        JMP     $D103               ; Skip further action
;
D06D: EC 2F           LDD     15,Y                ; Monster's coordinates
D06F: 10 93 13        CMPD    <playerY            ; Same as the players?
D072: 26 3E           BNE     $D0B2               ; No ... no attack
D074: A6 2D           LDA     13,Y                ; Play creature ...
D076: C6 FF           LDB     #$FF                ; ... sound ...
D078: 3F              SWI                         ; ... at full volume
D079: 1C                                          ; SWI_1C:Play sound A at volume B:
D07A: CC 80 80        LDD     #$8080              
D07D: 9E 1D           LDX     <leftHand           ; 
D07F: 8D 1D           BSR     $D09E               ; 
D081: 9E 1F           LDX     <rightHand          ; 
D083: 8D 19           BSR     $D09E               ; 
D085: 97 1A           STA     <m021A              ; 
D087: D7 1C           STB     <m021C              ; 
D089: 1F 21           TFR     Y,X                 
D08B: CE 02 17        LDU     #$0217              
D08E: BD D3 D7        JSR     $D3D7               ; 
D091: 2B 06           BMI     $D099               ; 
D093: 3F              SWI                         ; Play player hit sound at full volume
D094: 1B                                          ; SWI_1B:Play sound i at full volume:
D095: 13                                           ; 13 = Player hit
D096: BD D4 0C        JSR     $D40C               ; ??
D099: 3F              SWI                         ; Update the heart rate
D09A: 0C                                          ; SWI_C:Update heart rate:
D09B: 7E D1 0F        JMP     $D10F               ; 
;
D09E: 34 16           PSHS    X,B,A               
D0A0: 27 0E           BEQ     $D0B0               ; 
D0A2: A6 0A           LDA     10,X                
D0A4: 81 03           CMPA    #$03                
D0A6: 26 08           BNE     $D0B0               ; 
D0A8: AE 06           LDX     6,X                 
D0AA: AC E4           CMPX    ,S                  
D0AC: 24 02           BCC     $D0B0               ; 
D0AE: AF E4           STX     ,S                  
D0B0: 35 96           PULS    A,B,X,PC            

; We can see the player
D0B2: 91 13           CMPA    <playerY            ; 
D0B4: 26 0D           BNE     $D0C3               ; 
D0B6: A6 A8 10        LDA     $10,Y               
D0B9: C6 01           LDB     #$01                
D0BB: 90 14           SUBA    <playerX            ; 
D0BD: 2B 11           BMI     $D0D0               ; 
D0BF: C6 03           LDB     #$03                
D0C1: 20 0D           BRA     $D0D0               ; 
D0C3: EC 2F           LDD     15,Y                
D0C5: D1 14           CMPB    <playerX            ; 
D0C7: 26 1B           BNE     $D0E4               ; 
D0C9: C6 02           LDB     #$02                
D0CB: 90 13           SUBA    <playerY            ; 
D0CD: 2B 01           BMI     $D0D0               ; 
D0CF: 5F              CLRB                        
D0D0: D7 8A           STB     <drwMazeDir         ; 
D0D2: EC 2F           LDD     15,Y                
D0D4: 8D 60           BSR     $D136               ; 
D0D6: 26 0C           BNE     $D0E4               ; 
D0D8: 10 93 13        CMPD    <playerY            ; 
D0DB: 26 F7           BNE     $D0D4               ; 
D0DD: D6 8A           LDB     <drwMazeDir         ; 
D0DF: E7 2E           STB     14,Y                
D0E1: 5F              CLRB                        
D0E2: 20 1D           BRA     $D101               ; 
D0E4: 8E D1 14        LDX     #$D114              
D0E7: 3F              SWI                         
D0E8: 07                                          ; SWI_7:Get random number:
D0E9: 4D              TSTA                        
D0EA: 2B 02           BMI     $D0EE               ; 
D0EC: 30 03           LEAX    3,X                 
D0EE: 84 03           ANDA    #$03                
D0F0: 26 02           BNE     $D0F4               ; 
D0F2: 30 01           LEAX    1,X                 
D0F4: 86 03           LDA     #$03                
D0F6: E6 80           LDB     ,X+                 
D0F8: 8D 55           BSR     $D14F               ; 
D0FA: 27 07           BEQ     $D103               ; 
D0FC: 4A              DECA                        
D0FD: 26 F7           BNE     $D0F6               ; 

D0FF: C6 02           LDB     #$02                ; ?? returned if not in player's room
D101: 8D 4C           BSR     $D14F               ; 
;
; Different reload rate if the player is in the same room
;
D103: A6 26           LDA     6,Y                 ; Normal task speed reload
D105: AE 2F           LDX     15,Y                ; Is the creature with ...
D107: 9C 13           CMPX    <playerY            ; ... the player?
D109: 26 06           BNE     $D111               ; No ... use the normal rate
D10B: 3F              SWI                         ; Update the screen
D10C: 0E                                          ; SWI_E:Display playing screen:
D10D: 0F B5           CLR     <m02B5              ; 
D10F: A6 27           LDA     7,Y                 ; Task rate (tenths of a second)
D111: C6 04           LDB     #$04                ; Add task back to tenth-second-tick list
D113: 39              RTS                         ; Done

D114: 00 03 01 00 01 03 00

StepInDirection:
; This function moves the Y,X coordinates in A,B in the direction in $8A.
;
; Param A,B: The Y,X coordinates
;
; Return A,B: The new Y,X coordinates
; Return X: Pointer to the new cell
;
D11B: 34 06           PSHS    B,A                 ; Hold coordinates
D11D: D6 8A           LDB     <drwMazeDir         ; Get direction
D11F: C4 03           ANDB    #$03                ; Only four
D121: 58              ASLB                        ; 2 bytes for each table entry
D122: 8E D1 2E        LDX     #$D12E              ; Table of X,Y offsets for direction
D125: EC 85           LDD     B,X                 ; Get the X,Y offsets
D127: AB E0           ADDA    ,S+                 ; Offset the Y
D129: EB E0           ADDB    ,S+                 ; Offset the X
D12B: 7E CC 7B        JMP     GetCellPointer      ; Get cell pointer and return
;
; Y,X offsets for each direction
;
D12E: FF 00 ; 00 Up    (Y-1, X)
D130: 00 01 ; 01 Right (Y,   X+1)
D132: 01 00 ; 02 Down  (y+1, X)
D134: 00 FF ; 03 Left  (Y,   X-1)
                        
D136: 34 76           PSHS    U,Y,X,B,A           
D138: 8D E1           BSR     StepInDirection     ; 
D13A: BD CC 8E        JSR     IsValidCell         ; 
D13D: 26 0E           BNE     $D14D               ; 
D13F: 1F 03           TFR     D,U                 
D141: A6 84           LDA     ,X                  
D143: 4C              INCA                        
D144: 27 06           BEQ     $D14C               ; 
D146: EF E4           STU     ,S                  
D148: AF 62           STX     2,S                 
D14A: 86 01           LDA     #$01                
D14C: 4A              DECA                        
D14D: 35 F6           PULS    A,B,X,Y,U,PC        

D14F: 34 16           PSHS    X,B,A               
D151: EB 2E           ADDB    14,Y                
D153: C4 03           ANDB    #$03                
D155: D7 8A           STB     <drwMazeDir         ; 
D157: EC 2F           LDD     15,Y                
D159: 8D DB           BSR     $D136               ; 
D15B: 26 3C           BNE     $D199               ; 
D15D: BD CF 82        JSR     GetCreatureAt       ; 
D160: 26 37           BNE     $D199               ; 
D162: ED 2F           STD     15,Y                
D164: D6 8A           LDB     <drwMazeDir         ; 
D166: E7 2E           STB     14,Y                
D168: EC 2F           LDD     15,Y                
D16A: 90 13           SUBA    <playerY            ; 
D16C: 2A 01           BPL     $D16F               ; 
D16E: 40              NEGA                        
D16F: D0 14           SUBB    <playerX            ; 
D171: 2A 01           BPL     $D174               ; 
D173: 50              NEGB                        
D174: D7 C1           STB     <temp1              ; 
D176: 91 C1           CMPA    <temp1              ; 
D178: 2C 02           BGE     $D17C               ; 
D17A: 1E 89           EXG     A,B                 
D17C: 97 C1           STA     <temp1              ; 
D17E: 81 08           CMPA    #$08                
D180: 2E 16           BGT     $D198               ; 
D182: C1 02           CMPB    #$02                
D184: 2E 12           BGT     $D198               ; 
D186: 3F              SWI                         
D187: 07                                          ; SWI_7:Get random number:
D188: 85 01           BITA    #$01                
D18A: 27 0A           BEQ     $D196               ; 
D18C: 96 C1           LDA     <temp1              ; 
D18E: C6 1F           LDB     #$1F                
D190: 3D              MUL                         
D191: 53              COMB                        
D192: A6 2D           LDA     13,Y                
D194: 3F              SWI                         
D195: 1C                                          ; SWI_1C:Play sound A at volume B:
D196: 0A B5           DEC     <m02B5              ; 
D198: 4F              CLRA                        
D199: 35 96           PULS    A,B,X,PC            

T3_TimeTorch: 
D19B: DE 24           LDU     <torchPtr           ; Currently lit torch
D19D: 27 1D           BEQ     $D1BC               ; None ... skip timing down
D19F: A6 46           LDA     6,U                 ; Time already at 0? (dead torch)
D1A1: 27 19           BEQ     $D1BC               ; Yes ... skip it
D1A3: 4A              DECA                        ; Drop the ...
D1A4: A7 46           STA     6,U                 ; ... count
D1A6: 81 05           CMPA    #$05                ; More than 5 minutes remain on this one?
D1A8: 2E 06           BGT     $D1B0               ; Yes ... ??
D1AA: C6 18           LDB     #$18                
D1AC: E7 49           STB     9,U                 
D1AE: 6F 4B           CLR     11,U                
D1B0: A1 47           CMPA    7,U                 
D1B2: 2C 02           BGE     $D1B6               ; 
D1B4: A7 47           STA     7,U                 
D1B6: A1 48           CMPA    8,U                 
D1B8: 2C 02           BGE     $D1BC               ; 
D1BA: A7 48           STA     8,U                 
D1BC: 0A B5           DEC     <m02B5              ; 
D1BE: CC 01 08        LDD     #$0108              ; Reload task one tick on minute-tick list
D1C1: 39              RTS                         ; Done

T1_Draw3DScreen:               
D1C2: 0D B5           TST     <m02B5              ; 
D1C4: 26 07           BNE     $D1CD               ; 
D1C6: 8E CD B2        LDX     #$CDB2              ; Are we showing the ...
D1C9: 9C B2           CMPX    <displayFunction    ; ... map display?
D1CB: 26 04           BNE     $D1D1               ; 
D1CD: 0F B5           CLR     <m02B5              ; 
D1CF: 3F              SWI                         
D1D0: 0E                                          ; SWI_E:Display playing screen:
D1D1: CC 03 04        LDD     #$0304              
D1D4: 39              RTS                         

T2_UpdateHeart:               
D1D5: 4F              CLRA                        
D1D6: 5F              CLRB                        
D1D7: 93 21           SUBD    <m0221              ; 
D1D9: BD D3 79        JSR     DRight6             ; 
D1DC: D3 21           ADDD    <m0221              ; 
D1DE: 2E 02           BGT     $D1E2               ; 
D1E0: 4F              CLRA                        
D1E1: 5F              CLRB                        
D1E2: DD 21           STD     <m0221              ; 
D1E4: 3F              SWI                         
D1E5: 0C                                          ; SWI_C:Update heart rate:
D1E6: 96 AF           LDA     <heartCounterRel    ; 
D1E8: C6 02           LDB     #$02                
D1EA: 39              RTS                         

T0_PlayerInput:               
D1EB: 0D 77           TST     <gameMode           ; Are we in a demo?
D1ED: 26 2C           BNE     $D21B               ; Yes ... handle demo commands
;
D1EF: BD C3 29        JSR     CharFromBuf         ; 
D1F2: 4D              TSTA                        
D1F3: 27 53           BEQ     $D248               ; 
D1F5: 0D 28           TST     <fainting           ; Fainting?
D1F7: 26 F6           BNE     $D1EF               ; Yes ... drop all characters from the buffer
D1F9: 81 20           CMPA    #$20                
D1FB: 27 18           BEQ     $D215               ; 
D1FD: C6 1F           LDB     #$1F                
D1FF: 81 0D           CMPA    #$0D                
D201: 27 0F           BEQ     $D212               ; 
D203: C6 24           LDB     #$24                
D205: 81 08           CMPA    #$08                
D207: 27 09           BEQ     $D212               ; 
D209: 5F              CLRB                        
D20A: 81 41           CMPA    #$41                
D20C: 25 04           BCS     $D212               ; 
D20E: 81 5A           CMPA    #$5A                
D210: 23 03           BLS     $D215               ; 
D212: 1F 98           TFR     B,A                 
D214: 8C                  ; CMPX  opcode to skip next instruction
D215: 84 1F           ANDA    #$1F                
D217: 8D 33           BSR     $D24C               ; 
D219: 20 D4           BRA     $D1EF               ; 

D21B: 10 9E 0D        LDY     <nextDemoCommand    ; 
D21E: E6 A0           LDB     ,Y+                 
D220: 2A 07           BPL     $D229               ; 
D222: 3F              SWI                         ; Wait for 1.35 seconds
D223: 10                                          ; SWI_10:Pause for 1.35 seconds:
D224: 3F              SWI                         ; Another 1.35 seconds (total 2.7 seconds)
D225: 10                                          ; SWI_10:Pause for 1.35 seconds:
D226: 7E C0 00        JMP     Start               ; Restart

D229: AE A1           LDX     ,Y++                
D22B: CE 03 61        LDU     #$0361              
D22E: 3F              SWI                         
D22F: 06                                          ; SWI_6:Uncompress message X to given buffer U:
D230: 33 41           LEAU    1,U                 
D232: 3F              SWI                         ; Wait for 1.35 seconds
D233: 10                                          ; SWI_10:Pause for 1.35 seconds:
D234: 8C                  ; CMPX  opcode to skip next instruction
D235: 8D 15                     
D237: A6 C0           LDA     ,U+                 
D239: 2A FA           BPL     $D235               ; 
D23B: 4F              CLRA                        
D23C: 8D 0E           BSR     $D24C               ; 
D23E: 5A              DECB                        
D23F: 26 E8           BNE     $D229               ; 
D241: 86 1F           LDA     #$1F                
D243: 8D 07           BSR     $D24C               ; 
D245: 10 9F 0D        STY     <nextDemoCommand    ; 
D248: CC 01 02        LDD     #$0102              ; Reload task every 60Hz (as fast as possible)
D24B: 39              RTS                         ; Done
                 
D24C: 34 76           PSHS    U,Y,X,B,A           ; Hold these
D24E: 0D AD           TST     <scrollShowing      ; Is a scroll showing?
D250: 26 04           BNE     $D256               ; No ... skip closing the scroll
D252: 3F              SWI                         ; Bring up normal display
D253: 19                                          ; SWI_19:Bring up normal display:
D254: 3F              SWI                         ; Show the command prompt
D255: 0F                                          ; SWI_F:Ready command prompt:
D256: DE 11           LDU     <m0211              ; 
D258: 81 1F           CMPA    #$1F                ; User press ENTER?
D25A: 27 13           BEQ     $D26F               ; Yes ... go process the input
D25C: 81 24           CMPA    #$24                ; A backspace?
D25E: 27 1D           BEQ     $D27D               ; Yes ... handle it
D260: 3F              SWI                         ; Print the character in A
D261: 04                                          ; SWI_4:Display a single character in A:
D262: A7 C0           STA     ,U+                 ; Put this character in the buffer
D264: 8E C6 7C        LDX     #$C67C              ; Cursor data
D267: 3F              SWI                         ; Print cursor
D268: 03                                          ; SWI_3:Display uncompressed message pointed to by X:
D269: 11 83 03 11     CMPU    #$0311              ; Have we reached the 32 char limit?
D26D: 26 45           BNE     $D2B4               ; No ... keep waiting for ENTER
D26F: 4F              CLRA                        ; Print a ...
D270: 3F              SWI                         ; ... space on the end of the line
D271: 04                                          ; SWI_4:Display a single character in A:
D272: DC 03           LDD     <CONST_FF           ; 
D274: ED C1           STD     ,U++                ; End mark on the end of the buffer
D276: CE 02 F1        LDU     #$02F1              ; Reset input parse ...
D279: DF 11           STU     <m0211              ; ... pointer to the beginning of the input
D27B: 20 15           BRA     $D292               ; Execute the command
;
; Backspace
D27D: 11 83 02 F1     CMPU    #$02F1              ; Already at the beginning?
D281: 27 31           BEQ     $D2B4               ; Yes ... ignore it
D283: 33 5F           LEAU    -1,U                ; No ... back up one
D285: 8E D2 8C        LDX     #$D28C              ; Back cursor ...
D288: 3F              SWI                         ; ... up one spot
D289: 03                                          ; SWI_3:Display uncompressed message pointed to by X:
D28A: 20 28           BRA     $D2B4               ; Out

; String to back cursor up over character
D28C: 00 24 24 1C 24 FF   ; BACK BACK "_" BACK END
       
; Execute the command
D292: 8E D8 94        LDX     #$D894              ; Command first words
D295: BD CB EC        JSR     DecodeInput         ; Check for word match
D298: 27 0D           BEQ     $D2A7               ; Blank input ... skip execution
D29A: 2A 05           BPL     $D2A1               ; Good command word ... execute the command
D29C: BD CB E1        JSR     $CBE1               ; Print three question marks (error)
D29F: 20 06           BRA     $D2A7               ; Continue ... skip execution
;
D2A1: 48              ASLA                        ; 2 bytes per pointer
D2A2: 8E D9 D0        LDX     #$D9D0              ; Pointer to command functions
D2A5: AD 96           JSR     [A,X]               ; Execute the command
D2A7: CE 02 F1        LDU     #$02F1              ; Start of input buffer
D2AA: 0D AD           TST     <scrollShowing      ; Is a scroll showing?
D2AC: 27 06           BEQ     $D2B4               ; Yes ... skip the command prompt
D2AE: 0D 28           TST     <fainting           ; Are we fainting?
D2B0: 26 02           BNE     $D2B4               ; Yes ... skip the prompt
D2B2: 3F              SWI                         ; Print the command prompt
D2B3: 0F                                          ; SWI_F:Ready command prompt:
D2B4: DF 11           STU     <m0211              ; New start of command
D2B6: 35 F6           PULS    A,B,X,Y,U,PC        ; Done

ATTACK command

CmdATTACK:
D2B8: BD CC 31        JSR     GetUserHand         ; 
D2BB: EE C4           LDU     ,U                  
D2BD: 26 03           BNE     $D2C2               ; 
D2BF: CE 0B 07        LDU     #$0B07              
D2C2: 1F 32           TFR     U,Y                 
D2C4: A6 4C           LDA     12,U                
D2C6: 97 19           STA     <m0219              ; 
D2C8: A6 4D           LDA     13,U                
D2CA: 97 1B           STA     <m021B              ; 
D2CC: 9B 19           ADDA    <m0219              ; 
D2CE: 46              RORA                        
D2CF: 44              LSRA                        
D2D0: 44              LSRA                        
D2D1: 9E 17           LDX     <pStrength          ; Strength
D2D3: BD D4 36        JSR     $D436               ; 
D2D6: D3 21           ADDD    <m0221              ; 
D2D8: DD 21           STD     <m0221              ; 
D2DA: A6 4A           LDA     10,U                ; Object class
D2DC: 8B 0C           ADDA    #$0C                ; Sound table offset
D2DE: C6 FF           LDB     #$FF                ; Full volume
D2E0: 3F              SWI                         ; Play sound of object
D2E1: 1C                                          ; SWI_1C:Play sound A at volume B:
D2E2: A6 49           LDA     9,U                 ; Proper name
D2E4: 81 13           CMPA    #$13                ; Ring range?
D2E6: 2D 0F           BLT     $D2F7               ; Too low
D2E8: 81 15           CMPA    #$15                ; Ring Range?
D2EA: 2E 0B           BGT     $D2F7               ; Too high
D2EC: 6A 46           DEC     6,U                 ; Subtract one from ring counter
D2EE: 26 07           BNE     $D2F7               ; Still good, go on
D2F0: 86 16           LDA     #$16                ; GOLD token
D2F2: A7 49           STA     9,U                 ; Now a gold ring
D2F4: BD D6 38        JSR     $D638               ; Change object
D2F7: DC 13           LDD     <playerY            ; Our coordinates
D2F9: BD CF 82        JSR     GetCreatureAt       ; Find creature
D2FC: 27 77           BEQ     $D375               ; None found ignore attack
D2FE: CE 02 17        LDU     #$0217              ; Pointer to player's raw strength
D301: 1E 13           EXG     X,U                 
D303: A6 2A           LDA     10,Y                ; Class
D305: 81 01           CMPA    #$01                ; Is it a ring?
D307: 27 16           BEQ     $D31F               ; Yes-- can't miss
D309: BD D3 D7        JSR     $D3D7               ; Otherwise get calculate hit chance
D30C: 2B 67           BMI     $D375               ; Oops, missed
D30E: 10 9E 24        LDY     <torchPtr           ; Torch pointer
D311: 27 06           BEQ     $D319               ; Oh, no! No torch ...
D313: A6 29           LDA     9,Y                 ; Proper name of torch
D315: 81 18           CMPA    #$18                ; Well, it is dead!
D317: 26 06           BNE     $D31F               ; No, go on
D319: 3F              SWI                         ; Random number
D31A: 07                                          ; SWI_7:Get random number:
D31B: 84 03           ANDA    #$03                ; Between 0 and 3
D31D: 26 56           BNE     $D375               ; Only one in three will hit
D31F: 3F              SWI                         ; Sound a hit
D320: 1B                                          ; SWI_1B:Play sound i at full volume:
D321: 12                                          ; 12 = Player hit
D322: 3F              SWI                         ; Print !!!
D323: 02                                          ; SWI_2:Uncompress message m and display:
D324: 16 F7 B0                                    ; "!!!"
;
D327: BD D4 0C        JSR     $D40C               ; 
D32A: 22 49           BHI     $D375               ; 
;
; Monster drops all objects
D32C: 30 48           LEAX    8,U                 ; First in object link for monster
D32E: AE 84           LDX     ,X                  ; Get pointer to next object in list
D330: 27 08           BEQ     $D33A               ; That's all
D332: 6F 05           CLR     5,X                 ; Drop on floor
D334: EC 4F           LDD     15,U                ; Coordinate from monster
D336: ED 02           STD     2,X                 ; Now to object
D338: 20 F4           BRA     $D32E               ; Keep going for all
;
D33A: 9E 82           LDX     <creatureCounts     ; Creature counts on this level
D33C: E6 4D           LDB     13,U                ; Creature type
D33E: 6A 85           DEC     B,X                 ; Take one of these types from the counts
D340: 6F 4C           CLR     12,U                ; Monster dead
D342: 3F              SWI                         ; Redraw screen without monster
D343: 0E                                          ; SWI_E:Display playing screen:
D344: 3F              SWI                         ; Sound monster dead
D345: 1B                                          ; SWI_1B:Play sound i at full volume:
D346: 15                                          ; 15 = Creature dying
D347: EC C4           LDD     ,U                  ; Monster strength ...
D349: 8D 34           BSR     DRight3             ; ... divided by 8
D34B: D3 17           ADDD    <pStrength          ; Add to our strength
D34D: 2A 02           BPL     $D351               ; No overflow
D34F: 86 7F           LDA     #$7F                ; Maximum positive value
D351: DD 17           STD     <pStrength          ; New strength
D353: A6 4D           LDA     13,U                ; What did we just kill?
D355: 81 0A           CMPA    #$0A                ; Demon...
D357: 27 2D           BEQ     $D386               ; ...go to level 4
D359: 81 0B           CMPA    #$0B                ; Killed the Wizard?
D35B: 26 18           BNE     $D375               ; No. It was a normal creature. Done.
D35D: 0A 2B           DEC     <wizardDead         ; Wizard is dead (creatures don't move)
D35F: CC 07 13        LDD     #$0713              ; Light level
D362: DD 26           STD     <m0226              ; Ambient light
D364: 8E 0B 23        LDX     #$0B23              ; Drop all but ...
D367: 9F 0F           STX     <nextObjSlot        ; ... first object (the Supreme Ring)
D369: DC 00           LDD     <CONST_00           ; Zero constant
D36B: DD 29           STD     <firstPackObject    ; Nothing in pack
D36D: DD 24           STD     <torchPtr           ; No torch
D36F: DD 1F           STD     <rightHand          ; Left hand empty
D371: DD 1D           STD     <leftHand           ; Right hand empty
D373: 3F              SWI                         ; Draw the display
D374: 19                                          ; SWI_19:Bring up normal display:
D375: 3F              SWI                         ; Update the heart rate (might have died)
D376: 0C                                          ; SWI_C:Update heart rate:
;
; Interesting ... fall through the divide-D-by-7 code. We'll take the time instead of
; adding an RTS op here.

; Shift D right routine entries
DRight7:
D377: 47              ASRA                        ; 7 (divide by 128)
D378: 56              RORB                        
DRight6:                    
D379: 47              ASRA                        ; 6 (divide by 64)
D37A: 56              RORB                        
DRight5:                
D37B: 47              ASRA                        ; 5 (divide by 32)
D37C: 56              RORB                        
DRight4:                
D37D: 47              ASRA                        ; 4 (divide by 16)
D37E: 56              RORB                        
DRight3:                
D37F: 47              ASRA                        ; 3 (divide by 8)
D380: 56              RORB                        
DRight2:                
D381: 47              ASRA                        ; 2 (divide by 4)
D382: 56              RORB                        
DRight1:                
D383: 47              ASRA                        ; 1 (divide by 2)
D384: 56              RORB                        
D385: 39              RTS                         ; Done

; Demon killed

D386: 8E DF 10        LDX     #$DF10              ; Wizard picture
D389: 3F              SWI                         ; Beam him onto the screen
D38A: 13                                          ; SWI_13:Beam on picture pointed to by X:
D38B: 3F              SWI                         ; Print first part of message
D38C: 02                                          ; SWI_2:Uncompress message m and display:
D38D: FF C0 57 3E A7 46 C0 90 51 32 28 1E 60 51   ; "_1F_ ENOUGH! I TIRE OF THIS PLAY..."
D39B: 09 98 20 C0 E7 DE F0
;
D3A2: 3F              SWI                         ; Print second part of message
D3A3: 02                                          ; SWI_2:Uncompress message m and display:
D3A4: E8 00 08 48 B0 0C 8A 0A 3C 0D 29 68 0A 23   ; "   PREPARE TO MEET THY DOOM!!!"
D3B2: 20 23 DE DD EF 60
;
D3B8: 3F              SWI                         ; Pause for 1.35 seconds
D3B9: 10                                          ; SWI_10:Pause for 1.35 seconds:
D3BA: DE 24           LDU     <torchPtr           ; Keep only the ...
D3BC: DF 29           STU     <firstPackObject    ; ... torch in the pack
D3BE: 27 04           BEQ     $D3C4               ; There was no torch ... no need to unlink it
D3C0: 4F              CLRA                        ; Clear any ...
D3C1: 5F              CLRB                        ; ... object chained ...
D3C2: ED C4           STD     ,U                  ; ... after torch in pack
D3C4: CC 00 C8        LDD     #$00C8              ; Drop a big ...
D3C7: DD 15           STD     <playerWeight       ; ... strain on the user
D3C9: 86 03           LDA     #$03                ; Level 4
D3CB: 3F              SWI                         ; Prepare level
D3CC: 1A                                          ; SWI_1A:Set up level:
D3CD: BD CF 97        JSR     GetRandCell         ; Get random coordinates
D3D0: DD 13           STD     <playerY            ; New coordinates
D3D2: 3F              SWI                         ; Beam off the wizard
D3D3: 15                                          ; SWI_15:Beam wizard out:
D3D4: 3F              SWI                         ; Beam on the wizard
D3D5: 19                                          ; SWI_19:Bring up normal display:
D3D6: 39              RTS                         ; Done

D3D7: 34 56           PSHS    U,X,B,A             
D3D9: 86 0F           LDA     #$0F                
D3DB: 97 C1           STA     <temp1              ; 
D3DD: EC C4           LDD     ,U                  
D3DF: A3 4A           SUBD    10,U                
D3E1: BD CA 12        JSR     Dleft2              ; 
D3E4: A3 84           SUBD    ,X                  
D3E6: 25 04           BCS     $D3EC               ; 
D3E8: 0A C1           DEC     <temp1              ; 
D3EA: 26 F8           BNE     $D3E4               ; 
D3EC: D6 C1           LDB     <temp1              ; 
D3EE: C0 03           SUBB    #$03                
D3F0: 2A 09           BPL     $D3FB               ; 
D3F2: 50              NEGB                        
D3F3: 86 19           LDA     #$19                
D3F5: 3D              MUL                         
D3F6: BD CA 99        JSR     NegativeD           ; 
D3F9: 20 03           BRA     $D3FE               ; 
D3FB: 86 0A           LDA     #$0A                
D3FD: 3D              MUL                         
D3FE: ED E3           STD     ,--S                
D400: 3F              SWI                         
D401: 07                                          ; SWI_7:Get random number:
D402: 1F 89           TFR     A,B                 
D404: 4F              CLRA                        
D405: E3 E1           ADDD    ,S++                
D407: 83 00 7F        SUBD    #$007F              
D40A: 35 D6           PULS    A,B,X,U,PC          
D40C: 34 76           PSHS    U,Y,X,B,A           
D40E: 1F 12           TFR     X,Y                 
D410: AE A4           LDX     ,Y                  
D412: A6 22           LDA     2,Y                 
D414: 8D 20           BSR     $D436               ; 
D416: 1F 01           TFR     D,X                 
D418: A6 43           LDA     3,U                 
D41A: 8D 1A           BSR     $D436               ; 
D41C: E3 4A           ADDD    10,U                
D41E: ED 4A           STD     10,U                
D420: AE A4           LDX     ,Y                  
D422: A6 24           LDA     4,Y                 
D424: 8D 10           BSR     $D436               ; 
D426: 1F 01           TFR     D,X                 
D428: A6 45           LDA     5,U                 
D42A: 8D 0A           BSR     $D436               ; 
D42C: E3 4A           ADDD    10,U                
D42E: ED 4A           STD     10,U                
D430: AE C4           LDX     ,U                  
D432: AC 4A           CMPX    10,U                
D434: 35 F6           PULS    A,B,X,Y,U,PC        
D436: 34 16           PSHS    X,B,A               
D438: 0F C1           CLR     <temp1              ; 
D43A: E6 63           LDB     3,S                 
D43C: 3D              MUL                         
D43D: DD C2           STD     <m02C2              ; 
D43F: A6 E4           LDA     ,S                  
D441: E6 62           LDB     2,S                 
D443: 3D              MUL                         
D444: D3 C1           ADDD    <temp1              ; 
D446: 08 C3           LSL     <m02C3              ; 
D448: 59              ROLB                        
D449: 49              ROLA                        
D44A: ED E4           STD     ,S                  
D44C: 35 96           PULS    A,B,X,PC            

CLIMB command

CmdCLIMB:
D44E: DC 13           LDD     <playerY            ; Player's coordinates
D450: BD CF E1        JSR     ScanForHole         ; Is there a hole here?
D453: 2B 1A           BMI     $D46F               ; No ... error
D455: 97 C1           STA     <temp1              ; Hold this for a bit
D457: 8E D8 D9        LDX     #$D8D9              ; Second words
D45A: BD CB EC        JSR     DecodeInput         ; Are we going up or down?
D45D: 2F 10           BLE     $D46F               ; Syntax error on second word ... error
D45F: D6 C1           LDB     <temp1              ; The hole in this room
D461: 81 04           CMPA    #$04                ; Word is "UP" ?
D463: 27 0D           BEQ     $D472               ; Yes ... try that
D465: 81 05           CMPA    #$05                ; Word is "DOWN" ?
D467: 26 06           BNE     $D46F               ; No ... error
D469: 86 01           LDA     #$01                ; +1
D46B: C5 02           BITB    #$02                ; Is there a hole or ladder going down?
D46D: 26 09           BNE     $D478               ; Yes ... change levels (no error)
;
D46F: 7E CB E1        JMP     $CBE1               ; Print three "???" and out
;
D472: 86 FF           LDA     #$FF                ; -1
D474: C1 01           CMPB    #$01                ; Is there a ladder going up?
D476: 26 F7           BNE     $D46F               ; No ... error
;
; Change the level
D478: 3F              SWI                         ; Print "PREPARE"
D479: 16                                          ; SWI_16:Print PREPARE:
D47A: 9B 81           ADDA    <currentLevel       ; Change level (up or down)
D47C: 3F              SWI                         ; Setup the level
D47D: 1A                                          ; SWI_1A:Set up level:
D47E: 3F              SWI                         ; Normal display
D47F: 19                                          ; SWI_19:Bring up normal display:
D480: 39              RTS                         ; Back to command processing

EXAMINE command

CmdEXAMINE:             
D481: 8E D4 95        LDX     #$D495              ; Set the display function ...
D484: 9F B2           STX     <displayFunction    ; ... to draw the inventory
D486: 3F              SWI                         ; Redraw the screen
D487: 0E                                          ; SWI_E:Display playing screen:
D488: 39              RTS                         ; Done

SetForExamine:
; Clear the scratch screen, set the physical screen, set the "print to desired area" flag.
; Return the examine descriptor (#$0380).
D489: 3F              SWI                         ; Clear the scratch screen, return pointer to descriptor
D48A: 09                                          ; SWI_9:Clear secondary screen:
D48B: AE C4           LDX     ,U                  ; This is the physical start of the scratch screen
D48D: CE 03 80        LDU     #$0380              ; Descriptor for the "EXAMINE" screen area
D490: AF C4           STX     ,U                  ; Point to the off-screen area
D492: 0A B7           DEC     <whereToPrint       ; Printing goes to desired descriptor
D494: 39              RTS                         

DrawInventory:
; Function for drawing the inventory screen
D495: 8D F2           BSR     SetForExamine       ; Activate the "examine" area
D497: 0F B6           CLR     <tabOrCR            ; We are at the start of a line
D499: CC 00 0A        LDD     #$000A              ; Start "IN THIS ROOM" ...
D49C: ED 44           STD     4,U                 ; ... indented 10 spaces
D49E: 3F              SWI                         ; Print "IN THIS ROOM"
D49F: 02                                          ; SWI_2:Uncompress message m and display:
D4A0: 62 5C 0A 21 33 04 9E F6 FC                  ; "IN THIS ROOM_1F_"
;
D4A9: DC 13           LDD     <playerY            ; Player's coordinates
D4AB: BD CF 82        JSR     GetCreatureAt       ; Is there a creature here?
D4AE: 27 10           BEQ     $D4C0               ; No ... skip indicator
D4B0: AE 44           LDX     4,U                 ; Set the cursor to ...
D4B2: 30 0B           LEAX    11,X                ; ... center "!CREATURE!" ...
D4B4: AF 44           STX     4,U                 ; ... on the line
D4B6: 3F              SWI                         ; Print "!CREATURE!"
D4B7: 02                                          ; SWI_2:Uncompress message m and display:
D4B8: 56 C7 22 86 95 91 77 F0                     ; "!CREATURE!_1F_"
;
D4C0: 0F 91           CLR     <restartFind        ; 
D4C2: DC 13           LDD     <playerY            ; Player's coordinates
D4C4: BD CF 53        JSR     GetObjectAtCoor     ; Find object on floor
D4C7: 27 04           BEQ     $D4CD               ; No more on floor ... move to the pack
D4C9: 8D 3A           BSR     $D505               ; Print object description
D4CB: 20 F5           BRA     $D4C2               ; Keep going
;
D4CD: 0D B6           TST     <tabOrCR            ; At the start of the line?
D4CF: 27 02           BEQ     $D4D3               ; Yes ... no need for a CR
D4D1: 8D 2B           BSR     $D4FE               ; No ... print a CR
D4D3: CC 1B 20        LDD     #$1B20              ; A = character "!", B = count 32
D4D6: 3F              SWI                         ; Print "!"
D4D7: 04                                          ; SWI_4:Display a single character in A:
D4D8: 5A              DECB                        ; Print line ...
D4D9: 26 FB           BNE     $D4D6               ; ... of "!"
D4DB: AE 44           LDX     4,U                 ; Skip cursor to ...
D4DD: 30 0C           LEAX    12,X                ; ... center ...
D4DF: AF 44           STX     4,U                 ; ... "BACKPACK"
D4E1: 3F              SWI                         ; Print "BACKPACK"
D4E2: 02                                          ; SWI_2:Uncompress message m and display:
D4E3: 40 82 35 C0 23 5F C0                        ; "BACKPACK_1F_"
;
D4EA: 8E 02 29        LDX     #$0229              ; Head of object list
D4ED: AE 84           LDX     ,X                  ; Get next object
D4EF: 27 0A           BEQ     $D4FB               ; All done
D4F1: 9C 24           CMPX    <torchPtr           ; Is this the lit torch?
D4F3: 26 02           BNE     $D4F7               ; No ... leave it
D4F5: 63 46           COM     6,U                 ; Flip the color to show the torch is lit (we change this back every loop)
D4F7: 8D 0C           BSR     $D505               ; Print object description
D4F9: 20 F2           BRA     $D4ED               ; Next object
;
D4FB: 0F B7           CLR     <whereToPrint       ; Printing goes to command line area
D4FD: 39              RTS                         ; Done
;
D4FE: 86 1F           LDA     #$1F                ; Print a ...
D500: 3F              SWI                         ; ... line feed
D501: 04                                          ; SWI_4:Display a single character in A:
D502: 0F B6           CLR     <tabOrCR            ; Next print a tab (note this was already 0)
D504: 39              RTS                         ; Done

D505: 34 16           PSHS    X,B,A               ; Hold these
D507: BD C6 17        JSR     GetObjDscrpt        ; Unpack the text to make this object description (X points to buffer)
D50A: 3F              SWI                         ; Print the object description
D50B: 03                                          ; SWI_3:Display uncompressed message pointed to by X:
D50C: 96 2C           LDA     <backgroundColor    ; Set the background ...
D50E: A7 46           STA     6,U                 ; ... color (we may have flipped it printing the torch)
D510: 03 B6           COM     <tabOrCR            ; Whether to print a tab or CR
D512: 27 0A           BEQ     $D51E               ; 0 = Print the CR
D514: EC 44           LDD     4,U                 ; Cursor
D516: C3 00 10        ADDD    #$0010              ; FF = Skip to ...
D519: C4 F0           ANDB    #$F0                ; ... second ...
D51B: ED 44           STD     4,U                 ; ... column
D51D: 8C                  ; CMPX  opcode to skip next instruction
D51E: 8D DE           BSR     $D4FE               ; Print a line feed
D520: 35 96           PULS    A,B,X,PC            ; Done

GET command

CmdGET:
D522: 8D 52           BSR     $D576               ; Pointer for requested hand
D524: 26 4D           BNE     $D573               ; Hand isn't empty ... error
D526: BD CB BA        JSR     $CBBA               ; ??
D529: 0F 91           CLR     <restartFind        ; Reset the iterator to the first object
;
D52B: DC 13           LDD     <playerY            ; Players coordinates
D52D: BD CF 53        JSR     GetObjectAtCoor     ; Get the next object on this level at this coordinate
D530: 27 41           BEQ     $D573               ; End of list ... no match
D532: 0D 90           TST     <m0290              ; 
D534: 26 06           BNE     $D53C               ; Do proper match
D536: A6 0A           LDA     10,X                ; Class match
D538: 91 8F           CMPA    <holdIncantLen      ; 
D53A: 20 04           BRA     $D540               ; Skip proper match
D53C: A6 09           LDA     9,X                 ; Proper match
D53E: 91 8E           CMPA    <holdIncantWord     ; 
D540: 26 E9           BNE     $D52B               ; Try next object
D542: AF C4           STX     ,U                  ; Object now in hand
D544: 6C 05           INC     5,X                 ; 1 means carried
D546: E6 0A           LDB     10,X                ; Class
D548: 8E D9 FA        LDX     #$D9FA              ; Weight table
D54B: E6 85           LDB     B,X                 ; Get the weight
D54D: 4F              CLRA                        ; Two byte value (positive value)
D54E: 20 1B           BRA     $D56B               ; Update the player's weight and screen

DROP command

CmdDROP:   
D550: 8D 24           BSR     $D576               ; Get left or right hand object pointer
D552: 27 1F           BEQ     $D573               ; Nothing to drop ... syntax error
D554: 4F              CLRA                        ; Hand ...
D555: 5F              CLRB                        ; ... is now ...
D556: ED C4           STD     ,U                  ; ... empty
D558: 6F 05           CLR     5,X                 ; 0 = on floor
D55A: DC 13           LDD     <playerY            ; Drop at ...
D55C: ED 02           STD     2,X                 ; ... player's position ...
D55E: 96 81           LDA     <currentLevel       ; Object on ...
D560: A7 04           STA     4,X                 ; ... player's level
D562: E6 0A           LDB     10,X                ; Object class
D564: 8E D9 FA        LDX     #$D9FA              ; Weight table
D567: E6 85           LDB     B,X                 ; Get the weight of the object
D569: 50              NEGB                        ; Negative (removing the weight)
D56A: 1D              SEX                         ; Two byte value
;
D56B: D3 15           ADDD    <playerWeight       ; Update ...
D56D: DD 15           STD     <playerWeight       ; ... carried weight
D56F: 3F              SWI                         ; Update the heart after the change in load
D570: 0C                                          ; SWI_C:Update heart rate:
D571: 20 44           BRA     $D5B7               ; Update hands and screen and done
;
D573: 7E CB E1        JMP     $CBE1               ; Print "???" error
;
D576: 7E CC 31        JMP     GetUserHand         ; Get user-requested hand object

STOW command

CmdSTOW:  
D579: 8D FB           BSR     $D576               ; Get the left or right hand object
D57B: 27 F6           BEQ     $D573               ; Nothing in that hand ... error
D57D: DC 29           LDD     <firstPackObject    ; Move this ...
D57F: ED 84           STD     ,X                  ; ... object to ...
D581: 9F 29           STX     <firstPackObject    ; ... beginning of list
D583: 4F              CLRA                        ; Now ...
D584: 5F              CLRB                        ; ... empty ...
D585: ED C4           STD     ,U                  ; ... hand
D587: 20 2E           BRA     $D5B7               ; Update hands, draw screen, done

PULL command

CmdPULL:   
D589: 8D EB           BSR     $D576               ; Get the left or right hand object
D58B: 26 E6           BNE     $D573               ; It isn't empty ... error and out
D58D: BD CB BA        JSR     $CBBA               ; 
D590: 8E 02 29        LDX     #$0229              ; First pack object
D593: 1F 12           TFR     X,Y                 ;
D595: AE 84           LDX     ,X                  ;
D597: 27 DA           BEQ     $D573               ; End of list ... object not found ... error
D599: 0D 90           TST     <m0290              ; ?? two words given?
D59B: 26 06           BNE     $D5A3               ; 
D59D: A6 0A           LDA     10,X                ; Class type
D59F: 91 8F           CMPA    <holdIncantLen      ; 
D5A1: 20 04           BRA     $D5A7               ; Only check the class type
;
D5A3: A6 09           LDA     9,X                 ; Proper type
D5A5: 91 8E           CMPA    <holdIncantWord     ; 
D5A7: 26 EA           BNE     $D593               ; Not a match ... keep looking
D5A9: EC 84           LDD     ,X                  ; Pointer to next object
D5AB: ED A4           STD     ,Y                  ; Pull the current object out of the object chain
D5AD: AF C4           STX     ,U                  ; Object now in hand
D5AF: 4F              CLRA                        ; We might use this to ...
D5B0: 5F              CLRB                        ; ... extinguish the torch
D5B1: 9C 24           CMPX    <torchPtr           ; Did we just pull the lit torch?
D5B3: 26 02           BNE     $D5B7               ; No ... move on
D5B5: DD 24           STD     <torchPtr           ; Clear the lit-torch pointer
;
D5B7: 3F              SWI                         ; Update the hands
D5B8: 0D                                          ; SWI_D:Print contents of hands on status line:
D5B9: 3F              SWI                         ; Redraw the screen
D5BA: 0E                                          ; SWI_E:Display playing screen:
D5BB: 39              RTS                         ; Done

INCANT command

CmdINCANT:
D5BC: 8E D8 F3        LDX     #$D8F3              ; Proper names
D5BF: BD CB EC        JSR     DecodeInput         ; Decode the input word
D5C2: 2F 2B           BLE     $D5EF               ; Word not found ... fail silently
D5C4: 0D 7B           TST     <perfectMatch       ; 
D5C6: 27 27           BEQ     $D5EF               ; Not an exact word match ... fail silently
D5C8: DD 8E           STD     <holdIncantWord     ; Hold this for a second
D5CA: DE 1D           LDU     <leftHand           ; Try object ...
D5CC: 8D 02           BSR     $D5D0               ; ... in left hand
D5CE: DE 1F           LDU     <rightHand          ; Now try object in right
;
D5D0: 27 1D           BEQ     $D5EF               ; No object in this hand ... skip
D5D2: A6 4A           LDA     10,U                ; Is this a ...
D5D4: 81 01           CMPA    #$01                ; ... ring?
D5D6: 26 17           BNE     $D5EF               ; No ... skip
D5D8: A6 47           LDA     7,U                 ; Already revealed?
D5DA: 27 13           BEQ     $D5EF               ; Yes ... fail silently
D5DC: 91 8E           CMPA    <holdIncantWord     ; Input word matches this ring?
D5DE: 26 0F           BNE     $D5EF               ; No ... skip
D5E0: A7 49           STA     9,U                 ; Yes ... this is the new proper name
D5E2: 3F              SWI                         ; Change the ring to the powerful one
D5E3: 18                                          ; SWI_18:Change object to proper name and data:
D5E4: 3F              SWI                         ; Play the ring sound
D5E5: 1B                                          ; SWI_1B:Play sound i at full volume:
D5E6: 0D                                          ; 0D = Ring
D5E7: 3F              SWI                         ; Update the hand display
D5E8: 0D                                          ; SWI_D:Print contents of hands on status line:
D5E9: 6F 47           CLR     7,U                 ; Mark as revealed
D5EB: 81 12           CMPA    #$12                ; Did we just incant the "FINAL" ring?
D5ED: 27 01           BEQ     PlayerWins          ; Yes ... player wins the game
D5EF: 39              RTS                         ; Done

PlayerWins:
D5F0: 8E DF 39        LDX     #$DF39              ; Star Wizard picture
D5F3: 0A 9E           DEC     <initBeamIn         ; Initialize the beam in
D5F5: 3F              SWI                         ; Beam on the Star Wizard
D5F6: 13                                          ; SWI_13:Beam on picture pointed to by X:
D5F7: 3F              SWI                         ; Print the final message
D5F8: 02                                          ; SWI_2:Uncompress message m and display:
D5F9: FF C4 54 3D 84 D8 08 59 D1 2E C8 03 70 A6   ; "_1F_BEHOLD! DESTINY AWAITS THE HAND"
D607: 93 05 10 50 20 2E 20
;
D60E: 3F              SWI                         ; More final message
D60F: 02                                          ; SWI_2:Uncompress message m and display:
D610: C8 00 00 00 00 03 CC 00 81 C5 B8 2E 9D 06   ; "        OF A NEW WIZARD..."
D61E: 44 F7 BC 
;
D621: 20 FE           BRA     $D621               ; Infinite loop

REVEAL command

CmdREVEAL:
D623: BD CC 31        JSR     GetUserHand         ; Get requested left/right hand object
D626: EE C4           LDU     ,U                  ; 0 if there is no object (EMPTY)
D628: 27 14           BEQ     $D63E               ; Empty ... nothing to do
D62A: A6 4B           LDA     11,U                ; Already revealed?
D62C: 27 10           BEQ     $D63E               ; Yes, skip it now
D62E: C6 19           LDB     #$19                ; Base multiplier
D630: 3D              MUL                         ; Multiply
D631: 10 93 17        CMPD    <pStrength          ; Are we strong enough?
D634: 2E 08           BGT     $D63E               ; No, leave it unrevealed
D636: A6 49           LDA     9,U                 ; Get proper name
D638: 3F              SWI                         ; Change object types
D639: 18                                          ; SWI_18:Change object to proper name and data:
D63A: 6F 4B           CLR     11,U                ; Revealed
D63C: 3F              SWI                         ; Update the hands line
D63D: 0D                                          ; SWI_D:Print contents of hands on status line:
D63E: 39              RTS                         ; Done

TURN command

CmdTURN:
D63F: 8E D8 D9        LDX     #$D8D9              ; Second words
D642: BD CB EC        JSR     DecodeInput         ; Decode the user input
D645: 2F 4C           BLE     $D693               ; Not found ... syntax error
D647: D6 23           LDB     <playerDir          ; Current direction
D649: 81 00           CMPA    #$00                ; Turning LEFT?
D64B: 26 07           BNE     $D654               ; No ... try right
D64D: 5A              DECB                        ; Decrease direction ... turning CCW
D64E: 8D 1D           BSR     $D66D               ; Wrap direction and draw the screen
D650: 8D 22           BSR     LineMovesRight      ; Turn left
D652: 20 15           BRA     $D669               ; Continue
;
D654: 81 01           CMPA    #$01                ; Turning RIGHT?
D656: 26 05           BNE     $D65D               ; No ... try around
D658: 5C              INCB                        ; Increase direction ... turning CW
D659: 8D 12           BSR     $D66D               ; Wrap direction and draw the screen
D65B: 20 0A           BRA     $D667               ; Do the turn
;
D65D: 81 03           CMPA    #$03                ; Turning AROUND?
D65F: 26 32           BNE     $D693               ; No ... syntax error
D661: CB 02           ADDB    #$02                ; Flip direction
D663: 8D 08           BSR     $D66D               ; Wrap direction and draw the screen
D665: 8D 1D           BSR     LineMovesLeft       ; Turn right
D667: 8D 1B           BSR     LineMovesLeft       ; Turn right
D669: 0A B4           DEC     <flipScreens        ; 
D66B: 13              SYNC                        ; Wait for the refresh
D66C: 39              RTS                         ; Done
;
D66D: C4 03           ANDB    #$03                ; Limit direction (wrap around)
D66F: D7 23           STB     <playerDir          ; New direction
D671: 7E C6 60        JMP     $C660               ; Draw the screen
;
LineMovesRight:
; For moving/turning left
D674: 8D 20           BSR     $D696               ; Prepare the display and draw the horizontal lines to frame the turn
D676: 26 0B           BNE     $D683               ; Nothing to display ... abort
D678: CC 00 08        LDD     #$0008              ; Y=0, X=8
D67B: 8D 3D           BSR     DrawTurningLine     ; Draw the turning line
D67D: C3 00 20        ADDD    #$0020              ; Move X right
D680: 4D              TSTA                        ; Keep going till ...
D681: 27 F8           BEQ     $D67B               ; ... we flow off the right side
D683: 39              RTS                         ; Done
;
LineMovesLeft:
; For moving/turning right
D684: 8D 10           BSR     $D696               ; Prepare the display and draw the horizontal lines to frame the turn
D686: 26 0A           BNE     $D692               ; Nothing to display ... abort
D688: CC 00 F8        LDD     #$00F8              ; Y=0, X=F8
D68B: 8D 2D           BSR     DrawTurningLine     ; Draw the vertical line
D68D: 83 00 20        SUBD    #$0020              ; Move X left
D690: 2A F9           BPL     $D68B               ; Keep going till we flow off the left side
D692: 39              RTS                         ; Done
;
D693: 7E CB E1        JMP     $CBE1               ; Print "???" syntax error

D696: DE B2           LDU     <displayFunction    ; Are we showing ...
D698: 11 83 CE 66     CMPU    #$CE66              ; ... the normal game screen?
D69C: 26 1B           BNE     $D6B9               ; No, then out. Nothing to display in EXAMINE mode.
D69E: 8E 80 80        LDX     #$8080              ; ?? Zoom ?
D6A1: 9F 4F           STX     <xScaleFactor       ; ?? Zoom ?
D6A3: 0F 8B           CLR     <drwMazeCellNum     ; 
D6A5: 3F              SWI                         ; Set the light level to animate turning
D6A6: 00                                          ; SWI_0:Light level:
D6A7: 3F              SWI                         ; Clear the screen
D6A8: 08                                          ; SWI_8:Clear display screen:
D6A9: 8E D6 C6        LDX     #$D6C6              ; Top and bottom lines shown while moving
D6AC: 3F              SWI                         ; Draw the two horizontal lines
D6AD: 01                                          ; SWI_1:Draw picture X on screen:
D6AE: 8E 00 11        LDX     #$0011              ; Top Y coordinate ... 17 (line + 1)
D6B1: 9F 2F           STX     <newPointY          ; First Y coordinate
D6B3: 8E 00 87        LDX     #$0087              ; Bottom Y coordinate ... 135 (line -1)
D6B6: 9F 33           STX     <oldPointY          ; Second Y coordinate
D6B8: 4F              CLRA                        ; Return that we ARE going to draw something
D6B9: 39              RTS                         ; Done
     
DrawTurningLine:            
D6BA: DD 31           STD     <newPointX          ; First X coordinate
D6BC: DD 35           STD     <oldPointX          ; Second X coordinate
D6BE: 8D 00           BSR     $D6C0               ; ?? drawing then erasing? Two different screens?
D6C0: BD CA B7        JSR     DrawLine            ; Draw the vertical line
D6C3: 03 2C           COM     <backgroundColor    ; ?? two passes ... we set it back
D6C5: 39              RTS                         ; Done

; Top and bottom horizontal lines while turning
D6C6: 10 00          ; Move to absolute (16,0)
D6C8: 10 FF          ; Line to absolute (255,16)
D6CA: FF             ; New line
D6CB: 88 00          ; Move to absolute (0,136)
D6CD: 88 FF          ; Line to absolute (255,136)
D6CF: FE             ; End

MOVE command

CmdMOVE:
D6D0: 8E D8 D9        LDX     #$D8D9              ; Second words
D6D3: BD CB EC        JSR     DecodeInput         ; Decode the input word
D6D6: 2D BB           BLT     $D693               ; Bad input ... error
D6D8: 2E 09           BGT     $D6E3               ; Requested direction ... go do it
D6DA: 0A 73           DEC     <halfStepForward    ; No direction ... half step forward
D6DC: 3F              SWI                         ; Draw maze half step moving forward
D6DD: 0E                                          ; SWI_E:Display playing screen:
D6DE: 5F              CLRB                        ; Moving direction 0 (forward)
D6DF: 0F 73           CLR     <halfStepForward    ; Draw maze regularly now
D6E1: 20 0C           BRA     $D6EF               ; Make the move and add the stress of moving
;
D6E3: 81 02           CMPA    #$02                ; Word is "BACK" ?
D6E5: 26 0C           BNE     $D6F3               ; No ... try others
D6E7: 0A 74           DEC     <halfStepBack       ; Half step backward
D6E9: 3F              SWI                         ; Draw maze half step backards
D6EA: 0E                                          ; SWI_E:Display playing screen:
D6EB: C6 02           LDB     #$02                ; Moving direction 2 (backwards)
D6ED: 0F 74           CLR     <halfStepBack       ; Clear half-step flag
D6EF: 8D 2F           BSR     MoveCheckWall       ; Try the move
D6F1: 20 1B           BRA     $D70E               ; Add the stress of moving
;
D6F3: 81 01           CMPA    #$01                ; Word is "RIGHT" ?
D6F5: 26 0A           BNE     $D701               ; No ... try others
D6F7: C6 01           LDB     #$01                ; Moving direction 1 (right)
D6F9: 8D 25           BSR     MoveCheckWall       ; Try the move
D6FB: 26 11           BNE     $D70E               ; Add the stress of moving
D6FD: 8D 85           BSR     LineMovesLeft       ; Line moving left (player moving right)
D6FF: 20 0D           BRA     $D70E               ; Add the stress of moving

D701: 81 00           CMPA    #$00                ; Word is "LEFT" ?
D703: 26 8E           BNE     $D693               ; No ... error and out
D705: C6 03           LDB     #$03                ; Moving direction 3 (left)
D707: 8D 17           BSR     MoveCheckWall       ; Try the move
D709: 26 03           BNE     $D70E               ; Add the stress of moving
D70B: BD D6 74        JSR     LineMovesRight      ; Line moving right (player moving left)
;
; Stress from moving
D70E: DC 15           LDD     <playerWeight       ; Player's weight ...
D710: BD D3 7F        JSR     DRight3             ; ... divided by 8 ...
D713: C3 00 03        ADDD    #$0003              ; ... plus 3
D716: D3 21           ADDD    <m0221              ; Add ...
D718: DD 21           STD     <m0221              ; ... exertion
D71A: 3F              SWI                         ; Update the heart rate
D71B: 0C                                          ; SWI_C:Update heart rate:
D71C: 0A B4           DEC     <flipScreens        ; 
D71E: 13              SYNC                        ; Wait for heart rate change
D71F: 39              RTS                         ; Out

MoveCheckWall:
D720: 34 06           PSHS    B,A                 ; Hold
D722: 6F E2           CLR     ,-S                 ; Temporary on stack for return boolean (init to OK)
D724: DB 23           ADDB    <playerDir          ; Get the player's direction
D726: C4 03           ANDB    #$03                ; Mask it (only 4 directions)
D728: D7 8A           STB     <drwMazeDir         ; Movement direction
D72A: DC 13           LDD     <playerY            ; Player's coordinates
D72C: BD D1 36        JSR     $D136               ; Try to step in direction
D72F: 27 07           BEQ     $D738               ; Step made ... no wall hit
D731: 3F              SWI                         ; Play sound of hitting wall
D732: 1B                                          ; SWI_1B:Play sound i at full volume:
D733: 14                                          ; 14 = Wall hit
D734: 6A E4           DEC     ,S                  ; Return not-0 ... did not move
D736: DC 13           LDD     <playerY            ; Coordinates did not change
;
D738: DD 13           STD     <playerY            ; Set new (if OK) coordinates
D73A: BD C6 60        JSR     $C660               ; Redraw the maze
D73D: 6D E0           TST     ,S+                 ; Return not-zero if hit wall
D73F: 35 86           PULS    A,B,PC              ; Restore

USE command

CmdUSE:
D741: BD CC 31        JSR     GetUserHand         ; Get requested hand
D744: 27 21           BEQ     $D767               ; Nothing in the hand ... fail silently
D746: EC 09           LDD     9,X                 ; Get the object data
D748: C1 05           CMPB    #$05                ; Class is TORCH?
D74A: 26 0B           BNE     $D757               ; No ... try others
D74C: 9F 24           STX     <torchPtr           ; This is our new torch
D74E: BD D5 7D        JSR     $D57D               ; Automatically stow it
D751: 3F              SWI                         ; Play TORCH sound
D752: 1B                                          ; SWI_1B:Play sound i at full volume:
D753: 11                                          ; 11 = Torch
D754: 3F              SWI                         ; Update the display
D755: 0E                                          ; SWI_E:Display playing screen:
D756: 39              RTS                         ; Done
;
D757: 1F 13           TFR     X,U                 ; Object pointer now to U
D759: 8E D7 6B        LDX     #$D76B              ; USE routines per proper name
D75C: A1 84           CMPA    ,X                  ; Is this our object's routine?
D75E: 27 08           BEQ     $D768               ; Yes ... do it
D760: 30 03           LEAX    3,X                 ; Next in table
D762: 8C D7 7A        CMPX    #$D77A              ; Tried them all?
D765: 25 F5           BCS     $D75C               ; No ... keep looking
D767: 39              RTS                         ; No routine ... fail silently
;
D768: 6E 98 01        JMP     [$01,X]             ; Execute the routine

UseFunctions:     
D76B: 05          ; THEWS flask
D76C: D7 7A       ; Routine address
;
D76E: 09          ; HALE flask
D76F: D7 83       ; Routine address
;
D771: 08          ; ABYE flask
D772: D7 87       ; Routine address
;
D774: 04          ; SEER scroll
D775: D7 A2       ; Routine address
;
D777: 07          ; VISION scroll
D778: D7 A0       ; Routine address
 
UseTHEWS:
D77A: CC 03 E8        LDD     #$03E8              ; Big increase in strength
D77D: D3 17           ADDD    <pStrength          ; Update ...
D77F: DD 17           STD     <pStrength          ; ... player strength
D781: 20 0F           BRA     $D792               ; Make the FLASK sound

UseHALE:
D783: 4F              CLRA                        ; Clear all ...
D784: 5F              CLRB                        ; ... exertion
D785: 20 09           BRA     $D790               ; Update and make the FLASK sound

UseABYE:       
D787: 9E 17           LDX     <pStrength          ; Strength ...
D789: 86 66           LDA     #$66                ; ... times $66 ...
D78B: BD D4 36        JSR     $D436               ; ... is new ...
D78E: D3 21           ADDD    <m0221              ; ... exertion
D790: DD 21           STD     <m0221              ; Store new exertion
D792: C6 17           LDB     #$17                ; Now an EMPTY ...
D794: E7 49           STB     9,U                 ; ... FLASK
D796: 6F 4B           CLR     11,U                ; We revealed it by drinking it
D798: 3F              SWI                         ; Play the FLASH sound
D799: 1B                                          ; SWI_1B:Play sound i at full volume:
D79A: 0C                                          ; 0C = Flask
D79B: 3F              SWI                         ; Update the hands
D79C: 0D                                          ; SWI_D:Print contents of hands on status line:
D79D: 3F              SWI                         ; Update the heart rate
D79E: 0C                                          ; SWI_C:Update heart rate:
D79F: 39              RTS                         ; Done

UseVISION:
D7A0: 4F              CLRA                        ; 0 means VISION scroll
D7A1: 8C                  ; CMPX  opcode to skip next instruction
UseSEER:  
D7A2: 86 FF           LDA     #$FF                ; FF means SEER scroll
D7A4: 97 94           STA     <scrollType         ; set the scroll type
D7A6: 6D 4B           TST     11,U                ; Has this been revealed?
D7A8: 26 0C           BNE     $D7B6               ; No ... fail silently
D7AA: 3F              SWI                         ; Play open-scroll sound
D7AB: 1B                                          ; SWI_1B:Play sound i at full volume:
D7AC: 0E                                          ; 0E = Scroll
D7AD: 0F AD           CLR     <scrollShowing      ; 0 means scroll is showing
D7AF: 8E CD B2        LDX     #$CDB2              ; Set display to ...
D7B2: 9F B2           STX     <displayFunction    ; ... the map display
D7B4: 3F              SWI                         ; Redraw the screen
D7B5: 0E                                          ; SWI_E:Display playing screen:
D7B6: 39              RTS                         ; Done

ZLOAD command

CmdZLOAD:
D7B7: 8D 03           BSR     $D7BC               ; Parse the next word
D7B9: 0A B8           DEC     <tapeTrigger        ; Trigger ZLOAD
D7BB: 39              RTS                         ; Done

D7BC: 8E 03 13        LDX     #$0313              ; Start of scratch buffer
D7BF: 33 88 20        LEAU    $20,X               ; End is 16 bytes later
D7C2: 3F              SWI                         ; Fill scratch buffer with FFs
D7C3: 12                                          ; SWI_12:Fill X to U with FFs:
D7C4: 7E CB 96        JMP     GetNextWord         ; Parse the next word and return

ZSAVE command

CmdZSAVE:
D7C7: 8D F3           BSR     $D7BC               ; Parse the next word into the scratch buffer
D7C9: BF 00 7E        STX     CASSPTR             ; This will be the name of the file
D7CC: CC 00 0F        LDD     #$000F              ; Block type 0 (header) length = 16
D7CF: FD 00 7C        STD     CASSBLKTYPE         ; Prepare for first BLKOUT
D7D2: 0C B8           INC     <tapeTrigger        ; Trigger ZSAVE
D7D4: 39              RTS                         ; Done

; ############################################### Data from here down ##########################################################

Initial Backpack Objects

;Initial backpack objects
;
DemoObjects:
D7D5: 0D ; Iron sword     (Elvish = 02)
D7D6: 0F ; Pine torch     (Solar  = 0A)
D7D7: 10 ; Leather shield (Seer   = 04)
D7D8: FF ; End of list
;
GameObjects:
D7D9: 11 ; Wooden sword
D7DA: 0F ; Pine torch
D7DB: FF ; End of list

GameTasks:
D7DC: D1 EB ; T0_PlayerInput
D7DE: D1 C2 ; T1_Draw3DScreen
D7E0: D1 D5 ; T2_UpdateHeart
D7E2: D1 9B ; T3_UpdateTorch
D7E4: D0 27 ; T4_MakeCreature
D7E6: 00 00 ; End of task list

InitCopyTable:
D7E8: 0C 01 03   ; Copy 0C bytes to 103
D7EB: 7E C3 71   ; SWI2 Vector: JMP $C371
D7EE: 7E C3 52   ; SWI  Vector: JMP $C352
D7F1: 7E C2 7D   ; IRQ  Vector: JMP $C27D
D7F4: 7E C2 7D   ; FIRQ Vector: JMP $C27D
;
; Initialize a few local variables
D7F7: 17 02 02 ; Copy 17 bytes to 202
D7FA: 01       ; 202     Constant 1
D7FB: FF FF    ; 203:204 Constant FFFF
D7FD: 00 80    ; 205:206 X Center of screen
D7FF: 00 4C    ; 207:208 Y Center of screen
D801: D8 70    ; 209:20A Pointer to visible screen descriptor
D803: D8 76    ; 20B:20C Pointer to drawing screen descriptor
D805: D9 88    ; 20D:20E Pointer to demo commands
D807: 0B 15    ; 20F:210 Pointer to next available game object slot
D809: 02 F1    ; 211 Next input to parse
D80B: 0C 16    ; 213:214 Player starting point (for demo)
D80D: 00 23    ; 215:216 Player weight
D80F: 17 A0    ; 217:218 Player strength
;
; Examine area: 19 rows
; Hand area:     1 rows
; Command area:  4 rows
;               -------
;               24 rows (24 * 8 bytes = 192 ... the screen height)
;
; $380
; "Examine" area text descriptor
D811: 54 03 80 ; Copy 54 bytes to 380
D814: 10 00    ; Starts at $1000
D816: 02 60    ; 608 characters (19 rows of 32)
D818: 00 00    ; Cursor starts at beginning
D81A: 00       ; Normal color (background is black)
D81B: FF       ; Do not mirror to second screen buffer
;
; $388
; "Hand line" area text descriptor
; Two rows allows for a character at the very end of row 1 without
; scrolling the 1 line.
D81C: 23 00    ; Starts at $2300
D81E: 00 40    ; 64 characters (2 rows of 32)
D820: 00 00    ; Cursor starts at beginning
D822: FF       ; Reversed color (background is white)
D823: 00       ; Auto mirror to second screen buffer
;
; $390
; "Command Area" text descriptor
D824: 24 00    ; Starts at $2400
D826: 00 80    ; 128 bytes (4 rows of 32)
D828: 00 00    ; Cursor starts at beginning
D82A: 00       ; Normal color (background is black)
D82B: 00       ; Auto mirror to second screen buffer

CreaturesOnLevels:      
; $0398
;1
D82C: 09 09 04 02 ; 9 spiders, 9 snakes, 4 giants, 2 blobs
D830: 00 00 00 00 ; 0 knights, 0 hatchet-giants, 0 scorpions, 0 shield-knights
D834: 00 00 00 00 ; 0 wraiths, 0 galdrogs, 0 demons, 0 wizards
;
;2
D838: 02 04 00 06 ; 2 spiders, 4 snakes, 0 giants, 6 blobs
D83C: 06 06 00 00 ; 6 knights, 6 hatchet-giants
D840: 00 00 00 00 ; 0 wraiths, 0 galdrogs, 0 demons, 0 wizards
;
;3
D844: 00 00 00 04 ; 0 spiders, 0 snakes, 0 giants, 4 blobs
D848: 00 06 08 04 ; 0 knights, 6 hatchet-giants, 8 scorpions, 4 shield-knights
D84C: 00 00 01 00 ; 0 wraiths, 0 galdrogs, 1 demons, 0 wizards
;
;4
D850: 00 00 00 00 ; 0 spiders, 0 snakes, 0 giants, 0 blobs
D854: 00 00 08 06 ; 0 knights, 0 hatchet-giants, 8 scorpions, 6 shield-knights
D858: 06 04 00 00 ; 6 wraiths, 4 galdrogs, 0 demons, 0 wizards
;
;5
D85C: 02 02 02 02 ; 2 spiders, 2 snakes, 2 giants, 2 blobs
D860: 02 02 02 04 ; 2 knights, 2 hatchet-giants, 2 scorpions, 4 shield-knights
D864: 04 08 00 01 ; 4 wraiths, 8 galdrogs, 0 demons, 1 wizards

; $0B11
D868: 04 0B 11 ; Copy 4 bytes to B11 ??
; ??
D86B: 04 00 00 05                       
 
D86F: 00                                    ; End of initialization copy list

Screen Descriptors

There are two graphics pages. One is displayed while the other is being drawn on. RAM 0x209 points to the visible screen. RAM 0x20B points to the drawing screen. To flip the pages the pointers are swapped.

Each screen is divided into three sections (3*2 = 6 descriptors below):

  • Play field
  • Hands/heart
  • 4 lines of text
ScreenDescriptors:
D870: 10 00 ; Start of upper play-field 0x1000
D872: 23 00 ; End of play-field (152 rows)
D874: 20 46 ; SAM value 0010000__001000_110 (G6R,G6C Display=8*512=0x1000)
;
D876: 28 00 ; Start of upper play-field 0x2800
D878: 3B 00 ; End of play-field (152 rows)
D87A: 20 A6 ; SAM value 0010000__010100_110 (G6R,G6C Display=20*512=0x2800)

D87C: 23 00 ; Start of hand/heart row
D87E: 24 00 ; End of hand/heart row (8 rows)
D880: 00 00 
;
D882: 3B 00 ; Start of hand/heart row
D884: 3C 00 ; End of hand/heart row (8 rows)
D886: 00 00 

D888: 24 00 ; Start of text lines
D88A: 28 00 ; End of text lines (4*8 rows)
D88C: 00 00 
;
D88E: 3C 00 ; Start of text lines
D890: 40 00 ; End of text lines (4*8 rows)
D892: 00 00    

First Words

; FirstWords:
D894: 0F
D895: 30 03 4A 04 6B    ; 00 "ATTACK"
D89A: 28 06 C4 B4 40    ; 01 "CLIMB"
D89F: 20 09 27 C0       ; 02 "DROP"
D8A3: 38 0B 80 B5 2E 28 ; 03 "EXAMINE"
D8A9: 18 0E 5A 00       ; 04 "GET"
D8AD: 30 12 E1 85 D4    ; 05 "INCANT"
D8B2: 20 18 F7 AC       ; 06 "LOOK"
D8B6: 20 1A FB 14       ; 07 "MOVE"
D8BA: 20 21 56 30       ; 08 "PULL"
D8BE: 30 24 5B 14 2C    ; 09 "REVEAL"
D8C3: 20 27 47 DC       ; 0A "STOW"
D8C7: 20 29 59 38       ; 0B "TURN"
D8CB: 18 2B 32 80       ; 0C "USE"
D8CF: 28 34 C7 84 80    ; 0D "ZLOAD"
D8D4: 28 35 30 D8 A0    ; 0E "ZSAVE"

Second Words

SecondWords:
D8D9: 06 
D8DA: 20 18 53 50      ; 00 "LEFT"
D8DE: 28 24 93 A2 80   ; 01 "RIGHT"
D8E3: 20 04 11 AC      ; 02 "BACK"
D8E7: 30 03 27 D5 C4   ; 03 "AROUND"
D8EC: 10 2B 00         ; 04 "UP"
D8EF: 20 08 FB B8      ; 05 "DOWN"

Proper Names

ProperNames:
;                           index class text
D8F3: 19
D8F4: 38 67 58 48 AD 28   ;  00:  01   "SUPREME"
D8FA: 28 54 FA B0 A0      ;  01:  01   "JOULE"
D8FF: 31 0A CB 26 68      ;  02:  04   "ELVISH"
D904: 38 DA 9A 22 49 60   ;  03:  03   "MITHRIL"
D90A: 20 A6 52 C8         ;  04:  02   "SEER"
D90E: 28 28 82 DE 60      ;  05:  00   "THEWS"
D913: 20 64 96 94         ;  06:  01   "RIME"
D917: 30 AC 99 A5 EE      ;  07:  02   "VISION"
D91C: 20 02 2C 94         ;  08:  00   "ABYE"
D920: 20 10 16 14         ;  09:  00   "HALE"
D924: 29 66 F6 06 40      ;  0A:  05   "SOLAR"
D929: 30 C5 27 BB 45      ;  0B:  03   "BRONZE"
D92E: 30 6D 56 0C 2E      ;  0C:  01   "VULCAN"
D933: 21 13 27 B8         ;  0D:  04   "IRON"
D937: 29 59 57 06 40      ;  0E:  05   "LUNAR"
D93C: 21 60 97 14         ;  0F:  05   "PINE"
D940: 38 D8 50 D1 05 90   ;  10:  03   "LEATHER"
D946: 31 2E F7 90 AE      ;  11:  04   "WOODEN"
D94B: 28 4C 97 05 80      ;  12:  01   "FINAL"
D950: 30 4A E2 C8 F9      ;  13:  01   "ENERGY"
D955: 18 52 32 80         ;  14:  01   "ICE"
D959: 20 4C 99 14         ;  15:  01   "FIRE"
D95D: 20 4E F6 10         ;  16:  01   "GOLD"
D961: 28 0A D8 53 20      ;  17:  00   "EMPTY"
D966: 21 48 50 90         ;  18:  05   "DEAD"

Class Names

ClassNames:
D96A: 06     
D96B: 28 0C C0 CD 60  ; 00 "FLASK"
D970: 20 64 97 1C     ; 01 "RING"
D974: 30 A6 39 3D 8C  ; 02 "SCROLL"
D979: 30 E6 84 95 84  ; 03 "SHIELD"
D97E: 29 27 77 C8 80  ; 04 "SWORD"
D983: 29 68 F9 0D 00  ; 05 "TORCH"

DemoCommands:
D988: 01           ; one word
D989: D8 A3        ; EXAMINE
;
D98B: 03           ; three words
D98C: D8 BA        ; PULL
D98E: D8 DE        ; RIGHT
D990: D9 83        ; TORCH
;
D992: 02           ; two words
D993: D8 CB        ; USE
D995: D8 DE        ; RIGHT
;
D997: 01           ; one word
D998: D8 B2        ; LOOK
;
D99A: 01           ; one word
D99B: D8 B6        ; MOVE
;
D99D: 03           ; three words
D99E: D8 BA        ; PULL
D9A0: D8 DA        ; LEFT
D9A2: D9 79        ; SHIELD
;
D9A4: 03           ; three words
D9A5: D8 BA        ; PULL
D9A7: D8 DE        ; RIGHT
D9A9: D9 7E        ; SWORD
;
D9AB: 01           ; one word
D9AC: D8 B6        ; MOVE
;
D9AE: 01           ; one word
D9AF: D8 B6        ; MOVE
;
D9B1: 02           ; two words
D9B2: D8 95        ; ATTACK
D9B4: D8 DE        ; RIGHT
;
D9B6: 02           ; two words
D9B7: D8 C7        ; TURN
D9B9: D8 DE        ; RIGHT
;
D9BB: 01           ; one word
D9BC: D8 B6        ; MOVE
;
D9BE: 01           ; one word
D9BF: D8 B6        ; MOVE
;
D9C1: 01           ; one word
D9C2: D8 B6        ; MOVE
;
D9C4: 02           ; two words
D9C5: D8 C7        ; TURN
D9C7: D8 DE        ; RIGHT
;
D9C9: 01           ; one word
D9CA: D8 B6        ; MOVE
;
D9CC: 01           ; one word
D9CD: D8 B6        ; MOVE
;
D9CF: FF           ; End of list

; Command function jump table
CommandTable:
D9D0: D2 B8 ; 00 ATTACK
D9D2: D4 4E ; 01 CLIMB
D9D4: D5 50 ; 02 DROP
D9D6: D4 81 ; 03 EXAMINE
D9D8: D5 22 ; 04 GET
D9DA: D5 BC ; 05 INCANT
D9DC: C7 51 ; 06 LOOK
D9DE: D6 D0 ; 07 MOVE
D9E0: D5 89 ; 08 PULL
D9E2: D6 23 ; 09 REVEAL
D9E4: D5 79 ; 0A STOW
D9E6: D6 3F ; 0B TURN
D9E8: D7 41 ; 0C USE
D9EA: D7 B7 ; 0D ZLOAD
D9EC: D7 C7 ; 0E ZSAVE

; Object pictures by class
ClassPictures:
D9EE: DC 19 ; Flask
D9F0: DC 21 ; Ring
D9F2: DC 2A ; Scroll
D9F4: DB FA ; Shield
D9F6: DC 0F ; Sword
D9F8: DC 07 ; Torch

; Object weights by class
ClassWeights:
D9FA: 05    ; Flask
D9FB: 01    ; Ring
D9FC: 0A    ; Scroll
D9FD: 19    ; Shield
D9FE: 19    ; Sword
D9FF: 0A    ; Torch

ObjectData:
; Object descriptors by object index
;     CC RR MM PP: Class, Reveal, Magic Attack, Physical Attack
;                   nn Class   Proper
DA00: 01 FF 00 05 ; 00 Ring    Supreme
DA04: 01 AA 00 05 ; 01 Ring    Joule
DA08: 04 96 40 40 ; 02 Sword   Elvish
DA0C: 03 8C 0D 1A ; 03 Shield  Mithril
DA10: 02 82 00 05 ; 04 Scroll  Seer
DA14: 00 46 00 05 ; 05 Flask   Thews
DA18: 01 34 00 05 ; 06 Ring    Rime
DA1C: 02 32 00 05 ; 07 Scroll  Vision
DA20: 00 30 00 05 ; 08 Flask   Abye
DA24: 00 28 00 05 ; 09 Flask   Hale
DA28: 05 46 00 05 ; 0A Torch   Solar
DA2C: 03 19 00 1A ; 0B Shield  Bronze
DA30: 01 0D 00 05 ; 0C Ring    Vulcan
DA34: 04 0D 00 28 ; 0D Sword   Iron
DA38: 05 19 00 05 ; 0E Torch   Lunar
DA3C: 05 05 00 05 ; 0F Torch   Pine
DA40: 03 05 00 0A ; 10 Shield  Leather
DA44: 04 05 00 10 ; 11 Sword   Wooden
DA48: 01 00 00 00 ; 12 Ring    Final
DA4C: 01 00 FF FF ; 13 Ring    Energy
DA50: 01 00 FF FF ; 14 Ring    Ice
DA54: 01 00 FF FF ; 15 Ring    Fire
DA58: 01 00 00 05 ; 16 Ring    Gold
DA5C: 00 00 00 05 ; 17 Flask   Empty
DA60: 05 05 00 05 ; 18 Torch   Dead
 
ObjectSpecial:
; Special object properties by proper-index
;
; Thanks to Aaron Oliver for pointing out:
; Note that the physical and magic defense of the shields is swapped. This is a well known
; bug in the code. These values are multipliers. 80 means 1. 40 means 0.5.
;
; In this table the leather and bronze shields have a little reduction for magic and no
; reduction for physical. Since these are purely physical shields, the numbers should be
; reversed. The mithril shield has 0.5 for both physical and magic.
;
DA64: 00 03 12 00 ; Supreme Ring    (proper, strikes, ??, ??)
DA68: 01 03 13 00 ; Joule Ring      (proper, strikes, ??, ??)
DA6C: 03 40 40 00 ; Mithril Shield  (proper, magic defense, physical defense, ??)
DA70: 06 03 14 00 ; Rime Ring       (proper, strikes, ??, ??)
DA74: 0A 3C 0D 0B ; Solar Torch     (proper, minutes, physical illumination, magic illumination)
DA78: 0B 60 80 00 ; Bronze Shield   (proper, magic defense, physical defense, ??)
DA7C: 0C 03 15 00 ; Vulcan Ring     (proper, strikes, ??, ??)
DA80: 0E 1E 0A 04 ; Lunar Torch     (proper, minutes, physical illumination, magic illumination)
DA84: 0F 0F 07 00 ; Pine Torch      (proper, minutes, physical illumination, magic illumination)
DA88: 10 6C 80 00 ; Leather Shield  (proper, magic defense, physical defense, ??)
DA8C: 18 00 00 00 ; Dead Torch      (proper, minutes, physical illumination, magic illumination)
DA90: FF          ; End of list

ObjectDist:
; This table defines how objects are distributed to creatures on the various
; levels. There are 18 types of objects from most powerful to least. Each
; type of object gets one byte ... two nibbles. The first nibble indicates
; where the object first appears. The second nibble indicates how many there
; are. For instance, the ABYE FLASK first appears on level 1. There are 6 of them.
; They are assigned to 1, 2, 3, 4, 5, and then wrapping back around to level 1 again
; for the last one. The most powerful creatures on each level are given the most
; important objects. The Demon on level 2 gets a SEER SCROLL, though you can never
; pick it up.
;
; Note that the code assigns objects through level 5 even though there isn't a
; level 5. Based on the types of objects assigned to level 5, I believe this is
; a bug in the wrapping code and not a level that got left out.
;
;                                  Level   0       1       2       3       4      ?5?
DA91: 41 ; 00 Supreme Ring    1 start 4    --      --      --      --      00      --
DA92: 31 ; 01 Joule Ring      1 start 3    --      --      --      01      --      --
DA93: 31 ; 02 Elvish Sword    1 start 3    --      --      --      02      --      --
DA94: 32 ; 03 Mithril Shield  2 start 3    --      --      --      03      04      --
DA95: 23 ; 04 Seer Scroll     3 start 2    --      --      05      06      07      --
DA96: 23 ; 05 Thews Flask     3 start 2    --      --      08      09      0A      --
DA97: 11 ; 06 Rime Ring       1 start 1    --      0B      --      --      --      --
DA98: 13 ; 07 Vision Scroll   3 start 1    --      0C      0D      0E      --      --
DA99: 16 ; 08 Abye Flask      6 start 1    --      0F 14   10      11      12      13
DA9A: 14 ; 09 Hale Flask      4 start 1    --      15      16      17      18      --
DA9B: 14 ; 0A Solar Torch     4 start 1    --      19      1A      1B      1C      --
DA9C: 16 ; 0B Bronze Shield   6 start 1    --      1D 22   1E      1F      20      21
DA9D: 01 ; 0C Vulcan Ring     1 start 0    23      --      --      --      --      --
DA9E: 04 ; 0D Iron Sword      4 start 0    24      25      26      27      --      --
DA9F: 08 ; 0E Lunar Torch     8 start 0    28 2E   29 2F   2A      2B      2C      2D
DAA0: 08 ; 0F Pine Torch      8 start 0    30 36   31 37   32      33      34      35
DAA1: 03 ; 10 Leather Shield  3 start 0    38      39      3A      --      --      --
DAA2: 04 ; 11 Wooden Sword    4 start 0    3B      3C      3D      3E      --      --
;
; These are added to the backpack after all other objects have been created:
;          11 Wooden Sword       3F
;          0F Pine Torch         40
;
; These are the objects created for the demo:
;          0D Iron Sword         3F
;          0F Pine Torch         40
;          10 Leather Shield     41

Check List

TODO put these tables side-by-side

Start With

  • WOODEN SWORD
  • PINE TORCH

Level 0

Creature Carrying
BLOB VULCAN RING
BLOB IRON SWORD
CLUB GIANT LUNAR TORCH
CLUB GIANT LUNAR TORCH
CLUB GIANT PINE TORCH
CLUB GIANT PINE TORCH
SNAKE LEATHER SHIELD
SNAKE WOODEN SWORD
SNAKE
SNAKE
SNAKE
SNAKE
SNAKE
SNAKE
SNAKE
SPIDER
SPIDER
SPIDER
SPIDER
SPIDER
SPIDER
SPIDER
SPIDER
SPIDER

Level 1

Creature Carrying
HATCHET GIANT RIME RING
HATCHET GIANT VISION SCROLL
HATCHET GIANT ABYE FLASK
HATCHET GIANT ABYE FLASK
HATCHET GIANT HALE FLASK
HATCHET GIANT SOLAR TORCH
PLAIN KNIGHT BRONZE SHIELD
PLAIN KNIGHT BRONZE SHIELD
PLAIN KNIGHT IRON SWORD
PLAIN KNIGHT LUNAR TORCH
PLAIN KNIGHT LUNAR TORCH
PLAIN KNIGHT PINE TORCH
BLOB PINE TORCH
BLOB LEATHER SHIELD
BLOB WOODEN SWORD
BLOB
BLOB
BLOB
SNAKE
SNAKE
SNAKE
SNAKE
SPIDER
SPIDER

Level 2

Creature Carrying
DEMON SEER SCROLL
SHIELD KNIGHT THEWES FLASK
SHIELD KNIGHT VISION SCROLL
SHIELD KNIGHT ABYE FLASK
SHIELD KNIGHT HALE FLASK
SCORPION SOLAR TORCH
SCORPION BRONZE SHIELD
SCORPION IRON SWORD
SCORPION LUNAR TORCH
SCORPION PINE TORCH
SCORPION LEATHER SHIELD
SCORPION WOODEN SWORD
SCORPION
HATCHET GIANT
HATCHET GIANT
HATCHET GIANT
HATCHET GIANT
HATCHET GIANT
HATCHET GIANT
BLOB
BLOB
BLOB
BLOB

Level 3

Creature Carrying
GALDROG JOULE RING
GALDROG ELVISH SWORD
GALDROG MITHRIL SHIELD
GALDROG SEER SCROLL
WRAITH THEWS FLASK
WRAITH VISION SCROLL
WRAITH ABYE FLASK
WRAITH HALE FLASK
WRAITH SOLAR TORCH
WRAITH BRONZE SHIELD
SHIELD KNIGHT IRON SWORD
SHIELD KNIGHT LUNAR TORCH
SHIELD KNIGHT PINE TORCH
SHIELD KNIGHT WOODEN SWORD
SHIELD KNIGHT
SHIELD KNIGHT
SCORPION
SCORPION
SCORPION
SCORPION
SCORPION
SCORPION
SCORPION
SCORPION

Level 4

Creature Carrying
WIZARD SUPREME RING
GALDROG MITHRIL SHIELD
GALDROG SEER SCROLL
GALDROG THEWS FLASK
GALDROG ABYE FLASK
GALDROG HALE FLASK
GALDROG SOLAR TORCH
GALDROG BRONZE SHIELD
GALDROG LUNAR TORCH
WRAITH PINE TORCH
WRAITH
WRAITH
WRAITH
SHIELD KNIGHT
SHIELD KNIGHT
SHIELD KNIGHT
SHIELD KNIGHT
SCORPION
SCORPION
HATCHET GIANT
HATCHET GIANT
PLAIN KNIGHT
PLAIN KNIGHT
BLOB
BLOB
CLUB GIANT
CLUB GIANT
SNAKE
SNAKE
SPIDER
SPIDER
CreaturePictures:
DAA3: DE 26 ; Spider
DAA5: DF CA ; Snake
DAA7: DD 41 ; Giant
DAA9: DE 59 ; Blob
DAAB: DE 82 ; Knight
DAAD: DD 51 ; Hatchet-giant
DAAF: DE 3F ; Scorpion
DAB1: DE 9D ; Shield-knight
DAB3: DE 07 ; Wraith
DAB5: DD A3 ; Galdrog
DAB7: DF 65 ; Demon
DAB9: DF 10 ; Wizard

MonsterData:
;     To-kill  See  MShield  Damage  PShield  task-speed (tenths of seconds)
DABB: 00 20    00   FF       80      FF       17 0B ; Spider
DAC3: 00 38    00   FF       50      80       0F 07 ; Snake
DACB: 00 C8    00   FF       34      C0       1D 17 ; Giant
DAD3: 01 30    00   FF       60      A7       1F 1F ; Blob
DADB: 01 F8    00   80       60      3C       0D 07 ; Knight
DAE3: 02 C0    00   80       80      30       11 0D ; Hatchet-giant
DAEB: 01 90    FF   80       FF      80       05 04 ; Scorpion
DAF3: 03 20    00   40       FF      08       0D 07 ; Shield-knight
DAFB: 03 20    C0   10       C0      08       03 03 ; Wraith
DB03: 03 E8    FF   05       FF      03       04 03 ; Galdrog
DB0B: 03 E8    FF   06       FF      00       0D 07 ; Demon
DB13: 1F 40    FF   06       FF      00       0D 07 ; Wizard

Text Characters

Characters are 5x7 printed on 8x8 boundaries. The "extra" rows/columns allow for spacing between the characters. All 7 rows of a character are 5-bit-packed into 5 bytes and unpacked every single time needed.

TextCharacters:
DB1B: 30 00 00 00 00 ; SPACE 00110 > 00000 00000 00000 00000 00000 00000 00000  .....  ..X..  XXXX.  .XXX.  XXXX.  XXXXX  XXXXX  .XXXX
DB20: 31 15 18 FE 31 ; A     00110 > 00100 01010 10001 10001 11111 10001 10001  .....  .X.X.  X...X  X...X  X...X  X....  X....  X...X
DB25: 37 A3 1F 46 3E ; B     00110 > 11110 10001 10001 11110 10001 10001 11110  .....  X...X  X...X  X....  X...X  X....  X....  X....
DB2A: 33 A3 08 42 2E ; C     00110 > 01110 10001 10000 10000 10000 10001 01110  .....  X...X  XXXX.  X....  X...X  XXXX.  XXXX.  X....
DB2F: 37 A3 18 C6 3E ; D     00110 > 11110 10001 10001 10001 10001 10001 11110  .....  XXXXX  X...X  X....  X...X  X....  X....  X..XX
DB34: 37 E1 0F 42 1F ; E     00110 > 11111 10000 10000 11110 10000 10000 11111  .....  X...X  X...X  X...X  X...X  X....  X....  X...X
DB39: 37 E1 0F 42 10 ; F     00110 > 11111 10000 10000 11110 10000 10000 10000  .....  X...X  XXXX.  .XXX.  XXXX.  XXXXX  X....  .XXXX
DB3E: 33 E3 08 4E 2F ; G     00110 > 01111 10001 10000 10000 10011 10001 01111
DB43: 34 63 1F C6 31 ; H     00110 > 10001 10001 10001 11111 10001 10001 10001  X...X  .XXX.  ....X  X...X  X....  X...X  X...X  .XXX.
DB48: 33 88 42 10 8E ; I     00110 > 01110 00100 00100 00100 00100 00100 01110  X...X  ..X..  ....X  X..X.  X....  XX.XX  X...X  X...X
DB4D: 30 42 10 86 2E ; J     00110 > 00001 00001 00001 00001 00001 10001 01110  X...X  ..X..  ....X  X.X..  X....  X.X.X  XX..X  X...X
DB52: 34 65 4C 52 51 ; K     00110 > 10001 10010 10100 11000 10100 10010 10001  XXXXX  ..X..  ....X  XX...  X....  X.X.X  X.X.X  X...X
DB57: 34 21 08 42 1F ; L     00110 > 10000 10000 10000 10000 10000 10000 11111  X...X  ..X..  ....X  X.X..  X....  X.X.X  X..XX  X...X
DB5C: 34 77 5A D6 31 ; M     00110 > 10001 11011 10101 10101 10101 10001 10001  X...X  ..X..  X...X  X..X.  X....  X...X  X...X  X...X
DB61: 34 63 9A CE 31 ; N     00110 > 10001 10001 11001 10101 10011 10001 10001  X...X  .XXX.  .XXX.  X...X  XXXXX  X...X  X...X  .XXX.
DB66: 33 A3 18 C6 2E ; O     00110 > 01110 10001 10001 10001 10001 10001 01110
DB6B: 37 A3 1F 42 10 ; P     00110 > 11110 10001 10001 11110 10000 10000 10000  XXXX.  .XXX.  XXXX.  .XXX.  XXXXX  X...X  X...X  X...X
DB70: 33 A3 18 D6 4D ; Q     00110 > 01110 10001 10001 10001 10101 10010 01101  X...X  X...X  X...X  X...X  X.X.X  X...X  X...X  X...X
DB75: 37 A3 1F 52 51 ; R     00110 > 11110 10001 10001 11110 10100 10010 10001  X...X  X...X  X...X  X....  ..X..  X...X  X...X  X...X
DB7A: 33 A3 07 06 2E ; S     00110 > 01110 10001 10000 01110 00001 10001 01110  XXXX.  X...X  XXXX.  .XXX.  ..X..  X...X  .X.X.  X.X.X
DB7F: 37 EA 42 10 84 ; T     00110 > 11111 10101 00100 00100 00100 00100 00100  X....  X.X.X  X.X..  ....X  ..X..  X...X  .X.X.  X.X.X
DB84: 34 63 18 C6 2E ; U     00110 > 10001 10001 10001 10001 10001 10001 01110  X....  X..X.  X..X.  X...X  ..X..  X...X  ..X..  XX.XX
DB89: 34 63 15 28 84 ; V     00110 > 10001 10001 10001 01010 01010 00100 00100  X....  .XX.X  X...X  .XXX.  ..X..  .XXX.  ..X..  X...X
DB8E: 34 63 1A D7 71 ; W     00110 > 10001 10001 10001 10101 10101 11011 10001
DB93: 34 62 A2 2A 31 ; X     00110 > 10001 10001 01010 00100 01010 10001 10001  X...X  X...X  XXXXX  ..X..  .....  .XXX.  .....
DB98: 34 62 A2 10 84 ; Y     00110 > 10001 10001 01010 00100 00100 00100 00100  X...X  X...X  ....X  ..X..  .....  X...X  .....
DB9D: 37 C2 22 22 1F ; Z     00110 > 11111 00001 00010 00100 01000 10000 11111  .X.X.  .X.X.  ...X.  ..X..  .....  ....X  .....
DBA2: 31 08 42 10 04 ; !     00110 > 00100 00100 00100 00100 00100 00000 00100  ..X..  ..X..  ..X..  ..X..  .....  ..XX.  .....
DBA7: 30 00 00 00 1F ; _     00110 > 00000 00000 00000 00000 00000 00000 11111  .X.X.  ..X..  .X...  ..X..  .....  ..X..  .....
DBAC: 33 A2 13 10 04 ; ?     00110 > 01110 10001 00001 00110 00100 00000 00100  X...X  ..X..  X....  .....  .....  .....  .....
DBB1: 30 00 00 00 04 ; .     00110 > 00000 00000 00000 00000 00000 00000 00100  X...X  ..X..  XXXXX  ..X..  XXXXX  ..X..  ..X..

Heart Pictures

DBB6: 00 00 01 01 00 00 00
; ........
; ........
; .......X
; .......X
; ........
; ........
; ........

DBBD: 00 A0 F0 F0 E0 40 00
; ........
; X.X.....
; XXXX....
; XXXX....
; XXX.....
; .X......
; ........

DBC4: 00 01 03 03 01 00 00
; ........
; .......X
; ......XX
; ......XX
; .......X
; ........
; ........

DBCB: 00 B0 F8 F8 F0 E0 40
; ........
; X.XX....
; XXXXX...
; XXXXX...
; XXXX....
; XXX.....
; .X......

; Sound effect parameters/samples ??
DBD2: 00 80 00 01 ; Wall-hit and 1st part of wizard strike
DBD6: 00 50 00 04 ; 2nd part of wizard strike
DBDA: 00 50 00 05 ; Monster death

WallPictures:
DBDE: 03    ; Left
DBDF: DC 4F ; Left wall open
DBE1: DC 6B ; Left wall with physical door
DBE3: DC 9B ; Left magic door
DBE5: DC 33 ; Left wall solid
DBE7: 00    ; Front
DBE8: DC 6A ; Front wall open (draw nothing)
DBEA: DC 8B ; Front wall with physical door
DBEC: DC A9 ; Front wall magic door
DBEE: DC 45 ; Front wall (lines at top and bottom)
DBF0: 01    ; Right
DBF1: DC 5D ; Right wall open
DBF3: DC 7B ; Right wall with physical door
DBF5: DC A2 ; Right magic door
DBF7: DC 3C ; Right wall solid
DBF9: FF    ; End

Object Pictures


ShieldPic:       
; Shield
DBFA: 86 AC         ; Move to absolute (172,134)
DBFC: 80 C0         ; Line to absolute (192,128)
DBFE: 7A BA         ; Line to absolute (186,122)
DC00: 80 A8         ; Line to absolute (168,128)
DC02: FC            ; Draw short lines
DC03: 3E            ;     Short line to relative (-4,6)
DC04: 04            ;     Short line to relative (8,0)
DC05: 00            ;     End of short lines
DC06: FE            ; End of image
; Torch
DC07: 76 3C         ; Move to absolute (60,118)
DC09: FC            ; Draw short lines
DC0A: F7            ;     Short line to relative (14,-2)
DC0B: FF            ;     Short line to relative (-2,-2)
DC0C: 2A            ;     Short line to relative (-12,4)
DC0D: 00            ;     End of short lines
DC0E: FE            ; End of image
; Sword
DC0F: 72 50         ; Move to absolute (80,114)
DC11: 7C 64         ; Line to absolute (100,124)
DC13: FF            ; Start new line
DC14: 76 52         ; Move to absolute (82,118)
DC16: 72 56         ; Line to absolute (86,114)
DC18: FE            ; End of image
; Flask
DC19: 6E A2         ; Move to absolute (162,110)
DC1B: FC            ; Draw short lines
DC1C: 51            ;     Short line to relative (2,10)
DC1D: 0E            ;     Short line to relative (-4,0)
DC1E: B1            ;     Short line to relative (2,-10)
DC1F: 00            ;     End of short lines
DC20: FE            ; End of image
; Ring
DC21: 7A 3C         ; Move to absolute (60,122)
DC23: FC            ; Draw short lines
DC24: 11            ;     Short line to relative (2,2)
DC25: 1F            ;     Short line to relative (-2,2)
DC26: FF            ;     Short line to relative (-2,-2)
DC27: F1            ;     Short line to relative (2,-2)
DC28: 00            ;     End of short lines
DC29: FE            ; End of image
; Scroll
DC2A: 76 C2         ; Move to absolute (194,118)
DC2C: FC            ; Draw short lines
DC2D: 1F            ;     Short line to relative (-2,2)
DC2E: 34            ;     Short line to relative (8,6)
DC2F: F1            ;     Short line to relative (2,-2)
DC30: DC            ;     Short line to relative (-8,-6)
DC31: 00            ;     End of short lines
DC32: FE            ; End of image

Walls and Doors

; Left wall
DC33: 10 1B         ; Move to absolute (27,16)
DC35: 26 40         ; Line to absolute (64,38)
DC37: 72 40         ; Line to absolute (64,114)
DC39: 88 1B         ; Line to absolute (27,136)
DC3B: FE            ; End of image

; Right wall
DC3C: 10 E5         ; Move to absolute (229,16)
DC3E: 26 C0         ; Line to absolute (192,38)
DC40: 72 C0         ; Line to absolute (192,114)
DC42: 88 E5         ; Line to absolute (229,136)
DC44: FE            ; End of image

; Front wall (line at top and bottom)
DC45: 26 40         ; Move to absolute (64,38)
DC47: 26 C0         ; Line to absolute (192,38)
DC49: FF            ; Start new line
DC4A: 72 40         ; Move to absolute (64,114)
DC4C: 72 C0         ; Line to absolute (192,114)
DC4E: FE            ; End of image

; Left wall open
DC4F: 26 1D         ; Move to absolute (29,38)
DC51: 26 40         ; Line to absolute (64,38)
DC53: 72 40         ; Line to absolute (64,114)
DC55: 72 1B         ; Line to absolute (27,114)
DC57: FF            ; Start new line
DC58: 10 1B         ; Move to absolute (27,16)
DC5A: 26 40         ; Line to absolute (64,38)
DC5C: FE            ; End of image

; Right wall open
DC5D: 26 E5         ; Move to absolute (229,38)
DC5F: 26 C0         ; Line to absolute (192,38)
DC61: 72 C0         ; Line to absolute (192,114)
DC63: 72 E5         ; Line to absolute (229,114)
DC65: FF            ; Start new line
DC66: 10 E5         ; Move to absolute (229,16)
DC68: 26 C0         ; Line to absolute (192,38)
DC6A: FE            ; End of image

; Left wall physical door
DC6B: 80 28         ; Move to absolute (40,128)
DC6D: 41 28         ; Line to absolute (40,65)
DC6F: 44 38         ; Line to absolute (56,68)
DC71: 77 38         ; Line to absolute (56,119)
DC73: FF            ; Start new line
DC74: 5C 30         ; Move to absolute (48,92)
DC76: 5D 34         ; Line to absolute (52,93)
DC78: FD DC 33      ; Jump to DC33

; Right wall with physical door
DC7B: 80 D8         ; Line to absolute (216,128)
DC7D: 41 D8         ; Line to absolute (216,65)
DC7F: 44 C8         ; Line to absolute (200,68)
DC81: 77 C8         ; Line to absolute (200,119)
DC83: FF            ; Start new line
DC84: 5C D0         ; Move to absolute (208,92)
DC86: 5D CC         ; Line to absolute (204,93)
DC88: FD DC 3C      ; Jump to DC3C

;Front wall with physical door
DC8B: 72 6C         ; Line to absolute (108,114)
DC8D: 43 6C         ; Line to absolute (108,67)
DC8F: 43 94         ; Line to absolute (148,67)
DC91: 72 94         ; Line to absolute (148,114)
DC93: FF            ; Start new line
DC94: 5E 7E         ; Move to absolute (126,94)
DC96: 5E 82         ; Line to absolute (130,94)
DC98: FD DC 45      ; Jump to DC45

; Left magic door
DC9B: 80 28         ; Line to absolute (40,128)
DC9D: 42 32         ; Line to absolute (50,66)
DC9F: 75 3A         ; Line to absolute (58,117)
DCA1: FE            ; End of image

; Right magic door
DCA2: 80 D8         ; Move to absolute (216,128)
DCA4: 42 CE         ; Line to absolute (206,66)
DCA6: 75 C6         ; Line to absolute (198,117)
DCA8: FE            ; End of image

; Front magic door
DCA9: 71 6C         ; Move to absolute (108,113)
DCAB: 43 80         ; Line to absolute (128,67)
DCAD: 72 94         ; Line to absolute (148,114)
DCAF: FE            ; End of image

; Creature on left
DCB0: 64 1C         ; Move to absolute (28,100)
DCB2: FC            ; Draw short lines
DCB3: 44            ;     Short line to relative (8,8)
DCB4: 2E            ;     Short line to relative (-4,4)
DCB5: 42            ;     Short line to relative (4,8)
DCB6: 4C            ;     Short line to relative (-8,8)
DCB7: 00            ;     End of short lines
DCB8: FE            ; End of image

; Creature on right
DCB9: 64 E4         ; Move to absolute (228,100)
DCBB: FC            ; Draw short lines
DCBC: 4C            ;     Short line to relative (-8,8)
DCBD: 22            ;     Short line to relative (4,4)
DCBE: 4E            ;     Short line to relative (-4,8)
DCBF: 44            ;     Short line to relative (8,8)
DCC0: 00            ;     End of short lines
DCC1: FE            ; End of image

HoleList:
; Table for drawing holes/ladders
DCC2: DD 0E  ; Hole in ceiling
DCC4: DC CA  ; Ladder through ceiling
DCC6: DD 2A  ; Hole in floor
DCC8: DC D0  ; Ladder through floor

Holes and Ladders

; Ladder through ceiling
DCCA: FB DC D6 ; Ladder subroutine
DCCD: FD DD 0E ; Hole in ceiling

; Ladder through floor
DCD0: FB DC D6 ; Ladder subroutine
DCD3: FD DD 2A ; Hole in floor

; Ladder subroutine
DCD6: 18 74         ; Move to absolute (116,24)
DCD8: 80 74         ; Line to absolute (116,128)
DCDA: FF            ; Start new line
DCDB: 18 8C         ; Move to absolute (140,24)
DCDD: 80 8C         ; Line to absolute (140,128)
DCDF: FF            ; Start new line
DCE0: 1C 74         ; Move to absolute (116,28)
DCE2: 1C 8C         ; Line to absolute (140,28)
DCE4: FF            ; Start new line
DCE5: 28 74         ; Move to absolute (116,40)
DCE7: 28 8C         ; Line to absolute (140,40)
DCE9: FF            ; Start new line
DCEA: 34 74         ; Move to absolute (116,52)
DCEC: 34 8C         ; Line to absolute (140,52)
DCEE: FF            ; Start new line
DCEF: 40 74         ; Move to absolute (116,64)
DCF1: 40 8C         ; Line to absolute (140,64)
DCF3: FF            ; Start new line
DCF4: 4C 74         ; Move to absolute (116,76)
DCF6: 4C 8C         ; Line to absolute (140,76)
DCF8: FF            ; Start new line
DCF9: 58 74         ; Move to absolute (116,88)
DCFB: 58 8C         ; Line to absolute (140,88)
DCFD: FF            ; Start new line
DCFE: 64 74         ; Move to absolute (116,100)
DD00: 64 8C         ; Line to absolute (140,100)
DD02: FF            ; Start new line
DD03: 70 74         ; Move to absolute (116,112)
DD05: 70 8C         ; Line to absolute (140,112)
DD07: FF            ; Start new line
DD08: 7B 74         ; Move to absolute (116,123)
DD0A: 7B 8C         ; Line to absolute (140,123)
DD0C: FF            ; Start new line
DD0D: FA            ; Return
 
; Hole in ceiling
DD0E: 22 64         ; Move to absolute (100,34)
DD10: 18 5C         ; Line to absolute (92,24)
DD12: 18 A4         ; Line to absolute (164,24)
DD14: 22 9C         ; Line to absolute (156,34)
DD16: 22 64         ; Line to absolute (100,34)
DD18: 18 64         ; Line to absolute (100,24)
DD1A: FF            ; Start new line
DD1B: 22 9C         ; Move to absolute (156,34)
DD1D: 18 9C         ; Line to absolute (156,24)
DD1F: FF            ; Start new line
DD20: 1C 2F         ; Move to absolute (47,28)
DD22: 1C 60         ; Line to absolute (96,28)
DD24: FF            ; Start new line
DD25: 1C A1         ; Move to absolute (161,28)
DD27: 1C D2         ; Line to absolute (210,28)
DD29: FE            ; End of image

; Hole in floor
DD2A: 76 64         ; Move to absolute (100,118)
DD2C: 80 5C         ; Line to absolute (92,128)
DD2E: 80 A4         ; Line to absolute (164,128)
DD30: 76 9C         ; Line to absolute (156,118)
DD32: 76 64         ; Line to absolute (100,118)
DD34: 80 64         ; Line to absolute (100,128)
DD36: FF            ; Start new line
DD37: 76 9C         ; Move to absolute (156,118)
DD39: 80 9C         ; Line to absolute (156,128)
DD3B: FF            ; Start new line
DD3C: 1C 2F         ; Move to absolute (47,28)
DD3E: 1C D2         ; Line to absolute (210,28)
DD40: FE            ; End of image

Club Giant Picture


ClubGiantPic:       
DD41: 68 62         ; Move to absolute (98,104)
DD43: FC            ; Draw short lines
DD44: D7            ;     Short line to relative (14,-6)
DD45: D4            ;     Short line to relative (8,-6)
DD46: 14            ;     Short line to relative (8,2)
DD47: 12            ;     Short line to relative (4,2)
DD48: 30            ;     Short line to relative (0,6)
DD49: 1D            ;     Short line to relative (-6,2)
DD4A: 0D            ;     Short line to relative (-6,0)
DD4B: FD            ;     Short line to relative (-6,-2)
DD4C: 29            ;     Short line to relative (-14,4)
DD4D: 00            ;     End of short lines
DD4E: FD DD 62      ; Jump to DD62
;

Hatchet Giant Picture


HatchetGiantPic:        
; Giant (with hatchet)
DD51: 68 62         ; Move to absolute (98,104)
DD53: 5E 7C         ; Line to absolute (124,94)
DD55: 60 7E         ; Line to absolute (126,96)
DD57: 6A 64         ; Line to absolute (100,106)
DD59: FF            ; Start new line
DD5A: 66 84         ; Move to absolute (132,102)
DD5C: 5C 72         ; Line to absolute (114,92)
DD5E: 66 76         ; Line to absolute (118,102)
DD60: 6E 72         ; Line to absolute (114,110)
;
; Common Giant
DD62: 66 84         ; Line to absolute (132,102)
DD64: FC            ; Draw short lines
DD65: 02            ;     Short line to relative (4,0)
DD66: 56            ;     Short line to relative (12,10)
DD67: 56            ;     Short line to relative (12,10)
DD68: 17            ;     Short line to relative (14,2)
DD69: EE            ;     Short line to relative (-4,-4)
DD6A: 02            ;     Short line to relative (4,0)
DD6B: EA            ;     Short line to relative (-12,-4)
DD6C: BB            ;     Short line to relative (-10,-10)
DD6D: BB            ;     Short line to relative (-10,-10)
DD6E: EA            ;     Short line to relative (-12,-4)
DD6F: EA            ;     Short line to relative (-12,-4)
DD70: 00            ;     End of short lines
DD71: 4E 5C         ; Move to absolute (92,78)
DD73: FC            ; Draw short lines
DD74: C2            ;     Short line to relative (4,-8)
DD75: 51            ;     Short line to relative (2,10)
DD76: 3E            ;     Short line to relative (-4,6)
DD77: CF            ;     Short line to relative (-2,-8)
DD78: FC            ;     Short line to relative (-8,-2)
DD79: 42            ;     Short line to relative (4,8)
DD7A: 13            ;     Short line to relative (6,2)
DD7B: 00            ;     End of short lines
DD7C: 6A 5A         ; Move to absolute (90,106)
DD7E: FC            ; Draw short lines
DD7F: 1E            ;     Short line to relative (-4,2)
DD80: 11            ;     Short line to relative (2,2)
DD81: F3            ;     Short line to relative (6,-2)
DD82: 62            ;     Short line to relative (4,12)
DD83: 39            ;     Short line to relative (-14,6)
DD84: E2            ;     Short line to relative (4,-4)
DD85: 0C            ;     Short line to relative (-8,0)
DD86: E4            ;     Short line to relative (8,-4)
DD87: 8A            ;     Short line to relative (-12,-16)
DD88: E2            ;     Short line to relative (4,-4)
DD89: 00            ;     End of short lines
DD8A: 56 54         ; Move to absolute (84,86)
DD8C: FC            ; Draw short lines
DD8D: 54            ;     Short line to relative (8,10)
DD8E: 65            ;     Short line to relative (10,12)
DD8F: 2E            ;     Short line to relative (-4,4)
DD90: CA            ;     Short line to relative (-12,-8)
DD91: BA            ;     Short line to relative (-12,-10)
DD92: A1            ;     Short line to relative (2,-12)
DD93: D4            ;     Short line to relative (8,-6)
DD94: EE            ;     Short line to relative (-4,-4)
DD95: 12            ;     Short line to relative (4,2)
DD96: D2            ;     Short line to relative (4,-6)
DD97: 13            ;     Short line to relative (6,2)
DD98: E1            ;     Short line to relative (2,-4)
DD99: 20            ;     Short line to relative (0,4)
DD9A: F6            ;     Short line to relative (12,-2)
DD9B: 24            ;     Short line to relative (8,4)
DD9C: 72            ;     Short line to relative (4,14)
DD9D: 58            ;     Short line to relative (-16,10)
DD9E: EE            ;     Short line to relative (-4,-4)
DD9F: C5            ;     Short line to relative (10,-8)
DDA0: BE            ;     Short line to relative (-4,-10)
DDA1: 00            ;     End of short lines
DDA2: FE            ; End of image

Galdrog Picture

GaldrogPic:       
DDA3: 50 7C         ; Move to absolute (124,80)
DDA5: 5E 72         ; Line to absolute (114,94)
DDA7: 6E 78         ; Line to absolute (120,110)
DDA9: 84 70         ; Line to absolute (112,132)
DDAB: 68 4E         ; Line to absolute (78,104)
DDAD: 84 30         ; Line to absolute (48,132)
DDAF: 44 48         ; Line to absolute (72,68)
DDB1: 54 20         ; Line to absolute (32,84)
DDB3: 16 58         ; Line to absolute (88,22)
DDB5: 34 72         ; Line to absolute (114,52)
DDB7: 5C 80         ; Line to absolute (128,92)
DDB9: 34 8E         ; Line to absolute (142,52)
DDBB: 16 A8         ; Line to absolute (168,22)
DDBD: 58 E0         ; Line to absolute (224,88)
DDBF: 44 B8         ; Line to absolute (184,68)
DDC1: 84 D0         ; Line to absolute (208,132)
DDC3: 70 B2         ; Line to absolute (178,112)
DDC5: 84 90         ; Line to absolute (144,132)
DDC7: 6E 88         ; Line to absolute (136,110)
DDC9: 5E 8E         ; Line to absolute (142,94)
DDCB: 50 84         ; Line to absolute (132,80)
DDCD: FF            ; Start new line
DDCE: 84 70         ; Move to absolute (112,132)
DDD0: FC            ; Draw short lines
DDD1: C5            ;     Short line to relative (10,-8)
DDD2: 92            ;     Short line to relative (4,-14)
DDD3: BE            ;     Short line to relative (-4,-10)
DDD4: C3            ;     Short line to relative (6,-8)
DDD5: 43            ;     Short line to relative (6,8)
DDD6: 5E            ;     Short line to relative (-4,10)
DDD7: 72            ;     Short line to relative (4,14)
DDD8: 45            ;     Short line to relative (10,8)
DDD9: 00            ;     End of short lines
DDDA: 52 7A         ; Move to absolute (122,82)
DDDC: FC            ; Draw short lines
DDDD: 78            ;     Short line to relative (-16,14)
DDDE: E9            ;     Short line to relative (-14,-4)
DDDF: 8D            ;     Short line to relative (-6,-16)
DDE0: EC            ;     Short line to relative (-8,-4)
DDE1: 33            ;     Short line to relative (6,6)
DDE2: 0C            ;     Short line to relative (-8,0)
DDE3: 24            ;     Short line to relative (8,4)
DDE4: 72            ;     Short line to relative (4,14)
DDE5: 47            ;     Short line to relative (14,8)
DDE6: E7            ;     Short line to relative (14,-4)
DDE7: 00            ;     End of short lines
DDE8: 16 A8         ; Move to absolute (168,22)
DDEA: FC            ; Draw short lines
DDEB: 2D            ;     Short line to relative (-6,4)
DDEC: C2            ;     Short line to relative (4,-8)
DDED: 3D            ;     Short line to relative (-6,6)
DDEE: 30            ;     Short line to relative (0,6)
DDEF: 4B            ;     Short line to relative (-10,8)
DDF0: 4B            ;     Short line to relative (-10,8)
DDF1: ED            ;     Short line to relative (-6,-4)
DDF2: B2            ;     Short line to relative (4,-10)
DDF3: 9D            ;     Short line to relative (-6,-14)
DDF4: 71            ;     Short line to relative (2,14)
DDF5: 3D            ;     Short line to relative (-6,6)
DDF6: DD            ;     Short line to relative (-6,-6)
DDF7: 91            ;     Short line to relative (2,-14)
DDF8: 7D            ;     Short line to relative (-6,14)
DDF9: 52            ;     Short line to relative (4,10)
DDFA: 63            ;     Short line to relative (6,12)
DDFB: A3            ;     Short line to relative (6,-12)
DDFC: 2D            ;     Short line to relative (-6,4)
DDFD: ED            ;     Short line to relative (-6,-4)
DDFE: 2D            ;     Short line to relative (-6,4)
DDFF: CB            ;     Short line to relative (-10,-8)
DE00: CB            ;     Short line to relative (-10,-8)
DE01: D0            ;     Short line to relative (0,-6)
DE02: DD            ;     Short line to relative (-6,-6)
DE03: 42            ;     Short line to relative (4,8)
DE04: ED            ;     Short line to relative (-6,-4)
DE05: 00            ;     End of short lines
DE06: FE            ; End of image

Wraith Picture


WraithPic:       
DE07: 3E 44         ; Move to absolute (68,62)
DE09: 44 58         ; Line to absolute (88,68)
DE0B: 38 64         ; Line to absolute (100,56)
DE0D: FF            ; Start new line
DE0E: 4A 5A         ; Move to absolute (90,74)
DE10: 46 4A         ; Line to absolute (74,70)
DE12: FC            ; Draw short lines
DE13: 33            ;     Short line to relative (6,6)
DE14: F5            ;     Short line to relative (10,-2)
DE15: F5            ;     Short line to relative (10,-2)
DE16: C1            ;     Short line to relative (2,-8)
DE17: 5A            ;     Short line to relative (-12,10)
DE18: 62            ;     Short line to relative (4,12)
DE19: 0E            ;     Short line to relative (-4,0)
DE1A: 00            ;     End of short lines
DE1B: 64 50         ; Move to absolute (80,100)
DE1D: FC            ; Draw short lines
DE1E: B3            ;     Short line to relative (6,-10)
DE1F: 17            ;     Short line to relative (14,2)
DE20: 34            ;     Short line to relative (8,6)
DE21: EB            ;     Short line to relative (-10,-4)
DE22: 0A            ;     Short line to relative (-12,0)
DE23: 3D            ;     Short line to relative (-6,6)
DE24: 00            ;     End of short lines
DE25: FE            ; End of image

Spider Picture


SpiderPic:       
DE26: 7C A0         ; Move to absolute (160,124)
DE28: FC            ; Draw short lines
DE29: C2            ;     Short line to relative (4,-8)
DE2A: 22            ;     Short line to relative (4,4)
DE2B: E4            ;     Short line to relative (8,-4)
DE2C: 24            ;     Short line to relative (8,4)
DE2D: 2C            ;     Short line to relative (-8,4)
DE2E: EC            ;     Short line to relative (-8,-4)
DE2F: 04            ;     Short line to relative (8,0)
DE30: 04            ;     Short line to relative (8,0)
DE31: E2            ;     Short line to relative (4,-4)
DE32: 42            ;     Short line to relative (4,8)
DE33: 00            ;     End of short lines
DE34: 7C A8         ; Move to absolute (168,124)
DE36: FC            ; Draw short lines
DE37: C1            ;     Short line to relative (2,-8)
DE38: 21            ;     Short line to relative (2,4)
DE39: 12            ;     Short line to relative (4,2)
DE3A: F2            ;     Short line to relative (4,-2)
DE3B: E1            ;     Short line to relative (2,-4)
DE3C: 41            ;     Short line to relative (2,8)
DE3D: 00            ;     End of short lines
DE3E: FE            ; End of image

Scorpion Picture


ScorpionPic:                     
DE3F: 70 4A         ; Move to absolute (74,112)
DE41: FC            ; Draw short lines
DE42: E0            ;     Short line to relative (0,-4)
DE43: EE            ;     Short line to relative (-4,-4)
DE44: 2C            ;     Short line to relative (-8,4)
DE45: 42            ;     Short line to relative (4,8)
DE46: 14            ;     Short line to relative (8,2)
DE47: 14            ;     Short line to relative (8,2)
DE48: 20            ;     Short line to relative (0,4)
DE49: 0C            ;     Short line to relative (-8,0)
DE4A: CC            ;     Short line to relative (-8,-8)
DE4B: 22            ;     Short line to relative (4,4)
DE4C: 0C            ;     Short line to relative (-8,0)
DE4D: 22            ;     Short line to relative (4,4)
DE4E: 00            ;     End of short lines
DE4F: 7C 5A         ; Move to absolute (90,124)
DE51: FC            ; Draw short lines
DE52: E0            ;     Short line to relative (0,-4)
DE53: 0C            ;     Short line to relative (-8,0)
DE54: 2C            ;     Short line to relative (-8,4)
DE55: 20            ;     Short line to relative (0,4)
DE56: 04            ;     Short line to relative (8,0)
DE57: 00            ;     End of short lines
DE58: FE            ; End of image

Blob Picture


BlobPic:
;
; Body outline
DE59: 52 82         ; Move to absolute (130,82)
DE5B: FC            ; Draw short lines
DE5C: 28            ;     Short line to relative (-16,4)
DE5D: 7D            ;     Short line to relative (-6,14)
DE5E: 5F            ;     Short line to relative (-2,10)
DE5F: 50            ;     Short line to relative (0,10)
DE60: 5B            ;     Short line to relative (-10,10)
DE61: F5            ;     Short line to relative (10,-2)
DE62: 2F            ;     Short line to relative (-2,4)
DE63: D5            ;     Short line to relative (10,-6)
DE64: 17            ;     Short line to relative (14,2)
DE65: 17            ;     Short line to relative (14,2)
DE66: F3            ;     Short line to relative (6,-2)
DE67: 22            ;     Short line to relative (4,4)
DE68: E1            ;     Short line to relative (2,-4)
DE69: 14            ;     Short line to relative (8,2)
DE6A: DD            ;     Short line to relative (-6,-6)
DE6B: 8F            ;     Short line to relative (-2,-16)
DE6C: 8D            ;     Short line to relative (-6,-16)
DE6D: DB            ;     Short line to relative (-10,-6)
DE6E: EC            ;     Short line to relative (-8,-4)
DE6F: 00            ;     End of short lines
;
; Eyes
DE70: 56 82         ; Move to absolute (130,86)
DE72: FC            ; Draw short lines
DE73: 33            ;     Short line to relative (6,6)
DE74: 31            ;     Short line to relative (2,6)
DE75: 1B            ;     Short line to relative (-10,2)
DE76: 91            ;     Short line to relative (2,-14)
DE77: 3B            ;     Short line to relative (-10,6)
DE78: 5F            ;     Short line to relative (-2,10)
DE79: F5            ;     Short line to relative (10,-2)
DE7A: 00            ;     End of short lines
;
; Mouth
DE7B: 6C 74         ; Move to absolute (116,108)
DE7D: 72 76         ; Line to (118,114)
DE7F: 78 90         ; Line to (144,120)
DE81: FE            ; End of image

Knight Picture


KnightPic:       
DE82: 22 7C         ; Move to absolute (124,34)
DE84: FC            ; Draw short lines
DE85: 04            ;     Short line to relative (8,0)
DE86: 1F            ;     Short line to relative (-2,2)
DE87: 0E            ;     Short line to relative (-4,0)
DE88: FF            ;     Short line to relative (-2,-2)
DE89: 00            ;     End of short lines
DE8A: 50 8E         ; Move to absolute (142,80)
DE8C: 40 88         ; Line to absolute (136,64)
DE8E: 2E 92         ; Line to absolute (146,46)
DE90: 40 9C         ; Line to absolute (156,64)
DE92: 52 8C         ; Line to absolute (140,82)
DE94: 4C 88         ; Line to absolute (136,76)
DE96: 40 92         ; Line to absolute (146,64)
DE98: 3A 8C         ; Line to absolute (140,58)
DE9A: FD DE B3      ; Jump to DEB3
;

Shield Knight Picture


ShieldKnightPic:       
DE9D: 1E 7E         ; Line to absolute (126,30)
DE9F: FC            ; Draw short lines
DEA0: 50            ;     Short line to relative (0,10)
DEA1: 0F            ;     Short line to relative (-2,0)
DEA2: E0            ;     Short line to relative (0,-4)
DEA3: 00            ;     End of short lines
DEA4: 2C 96         ; Move to absolute (150,44)
DEA6: 34 A6         ; Line to absolute (166,52)
DEA8: 4C A4         ; Line to absolute (164,76)
DEAA: 5C 96         ; Line to absolute (150,92)
DEAC: 4C 88         ; Line to absolute (136,76)
DEAE: 34 86         ; Line to absolute (134,52)
DEB0: 2C 96         ; Line to absolute (150,44)
DEB2: FF            ; Start new line
;
; Common knight
DEB3: 50 8C         ; Move to absolute (140,80)
DEB5: 80 98         ; Line to absolute (152,128)
DEB7: 84 A0         ; Line to absolute (160,132)
DEB9: 84 90         ; Line to absolute (144,132)
DEBB: 7E 90         ; Line to absolute (144,126)
DEBD: 54 82         ; Line to absolute (130,84)
DEBF: FF            ; Start new line
DEC0: 54 7E         ; Move to absolute (126,84)
DEC2: 7E 6E         ; Line to absolute (110,126)
DEC4: 84 6E         ; Line to absolute (110,132)
DEC6: 84 5C         ; Line to absolute (92,132)
DEC8: 80 66         ; Line to absolute (102,128)
DECA: 50 74         ; Line to absolute (116,80)
DECC: FF            ; Start new line
DECD: 50 8C         ; Move to absolute (140,80)
DECF: FC            ; Draw short lines
DED0: 3A            ;     Short line to relative (-12,6)
DED1: D9            ;     Short line to relative (-14,-6)
DED2: 83            ;     Short line to relative (6,-16)
DED3: DE            ;     Short line to relative (-4,-6)
DED4: AD            ;     Short line to relative (-6,-12)
DED5: E6            ;     Short line to relative (12,-4)
DED6: A1            ;     Short line to relative (2,-12)
DED7: E2            ;     Short line to relative (4,-4)
DED8: 22            ;     Short line to relative (4,4)
DED9: 61            ;     Short line to relative (2,12)
DEDA: 26            ;     Short line to relative (12,4)
DEDB: EA            ;     Short line to relative (-12,-4)
DEDC: 20            ;     Short line to relative (0,4)
DEDD: 3D            ;     Short line to relative (-6,6)
DEDE: DD            ;     Short line to relative (-6,-6)
DEDF: E0            ;     Short line to relative (0,-4)
DEE0: 00            ;     End of short lines
DEE1: 34 80         ; Move to absolute (128,52)
DEE3: 14 80         ; Line to absolute (128,20)
DEE5: FC            ; Draw short lines
DEE6: 0E            ;     Short line to relative (-4,0)
DEE7: 21            ;     Short line to relative (2,4)
DEE8: 02            ;     Short line to relative (4,0)
DEE9: E1            ;     Short line to relative (2,-4)
DEEA: 0E            ;     Short line to relative (-4,0)
DEEB: 00            ;     End of short lines
DEEC: 4A 66         ; Move to absolute (102,74)
DEEE: FC            ; Draw short lines
DEEF: E0            ;     Short line to relative (0,-4)
DEF0: 02            ;     Short line to relative (4,0)
DEF1: D0            ;     Short line to relative (0,-6)
DEF2: 08            ;     Short line to relative (-16,0)
DEF3: 30            ;     Short line to relative (0,6)
DEF4: 02            ;     Short line to relative (4,0)
DEF5: 20            ;     Short line to relative (0,4)
DEF6: 01            ;     Short line to relative (2,0)
DEF7: 30            ;     Short line to relative (0,6)
DEF8: 02            ;     Short line to relative (4,0)
DEF9: D0            ;     Short line to relative (0,-6)
DEFA: 01            ;     Short line to relative (2,0)
DEFB: 87            ;     Short line to relative (14,-16)
DEFC: 00            ;     End of short lines
DEFD: 2E 6E         ; Move to absolute (110,46)
DEFF: 40 66         ; Line to absolute (102,64)
DF01: 40 64         ; Line to absolute (100,64)
DF03: 1E 66         ; Line to absolute (102,30)
DF05: 14 62         ; Line to absolute (98,20)
DF07: 1E 5E         ; Line to absolute (94,30)
DF09: 40 60         ; Line to absolute (96,64)
DF0B: 40 62         ; Line to absolute (98,64)
DF0D: 14 62         ; Line to absolute (98,20)
DF0F: FE            ; End of image

Moon Wizard Picture

MoonWizardPic:        
DF10: 2E 62         ; Move to absolute (98,46)
DF12: FC            ; Draw short lines
DF13: 21            ;     Short line to relative (2,4)
DF14: 2F            ;     Short line to relative (-2,4)
DF15: 2D            ;     Short line to relative (-6,4)
DF16: FD            ;     Short line to relative (-6,-2)
DF17: CE            ;     Short line to relative (-4,-8)
DF18: C2            ;     Short line to relative (4,-8)
DF19: F2            ;     Short line to relative (4,-2)
DF1A: 12            ;     Short line to relative (4,2)
DF1B: 0F            ;     Short line to relative (-2,0)
DF1C: 1E            ;     Short line to relative (-4,2)
DF1D: 3F            ;     Short line to relative (-2,6)
DF1E: 21            ;     Short line to relative (2,4)
DF1F: 12            ;     Short line to relative (4,2)
DF20: E3            ;     Short line to relative (6,-4)
DF21: E0            ;     Short line to relative (0,-4)
DF22: 00            ;     End of short lines
DF23: 68 9A         ; Move to absolute (154,104)
DF25: FC            ; Draw short lines
DF26: 21            ;     Short line to relative (2,4)
DF27: 2F            ;     Short line to relative (-2,4)
DF28: 2D            ;     Short line to relative (-6,4)
DF29: FD            ;     Short line to relative (-6,-2)
DF2A: CE            ;     Short line to relative (-4,-8)
DF2B: C2            ;     Short line to relative (4,-8)
DF2C: F2            ;     Short line to relative (4,-2)
DF2D: 12            ;     Short line to relative (4,2)
DF2E: 0F            ;     Short line to relative (-2,0)
DF2F: 1E            ;     Short line to relative (-4,2)
DF30: 3F            ;     Short line to relative (-2,6)
DF31: 22            ;     Short line to relative (4,4)
DF32: 12            ;     Short line to relative (4,2)
DF33: E2            ;     Short line to relative (4,-4)
DF34: E0            ;     Short line to relative (0,-4)
DF35: 00            ;     End of short lines
DF36: FD DF 65      ; Jump to DF65

Star Wizard Picture

StarWizardPic:
DF39: 28 56         ; Move to absolute (86,40)
DF3B: 40 5C         ; Line to absolute (92,64)
DF3D: 2A 64         ; Line to absolute (100,42)
DF3F: 36 52         ; Line to absolute (82,54)
DF41: 38 68         ; Line to absolute (104,56)
DF43: 28 56         ; Line to absolute (86,40)
DF45: FF            ; Start new line
DF46: 42 8C         ; Move to absolute (140,66)
DF48: FC            ; Draw short lines
DF49: 70            ;     Short line to relative (0,14)
DF4A: AD            ;     Short line to relative (-6,-12)
DF4B: 35            ;     Short line to relative (10,6)
DF4C: 1B            ;     Short line to relative (-10,2)
DF4D: B3            ;     Short line to relative (6,-10)
DF4E: 00            ;     End of short lines
DF4F: 60 92         ; Move to absolute (146,96)
DF51: 78 94         ; Line to absolute (148,120)
DF53: 64 88         ; Line to absolute (136,100)
DF55: 6A 9A         ; Line to absolute (154,106)
DF57: 74 8A         ; Line to absolute (138,116)
DF59: 60 92         ; Line to absolute (146,96)
DF5B: FF            ; Start new line
DF5C: 50 74         ; Move to absolute (116,80)
DF5E: FC            ; Draw short lines
DF5F: 53            ;     Short line to relative (6,10)
DF60: EC            ;     Short line to relative (-8,-4)
DF61: E4            ;     Short line to relative (8,-4)
DF62: 4D            ;     Short line to relative (-6,8)
DF63: B0            ;     Short line to relative (0,-10)
DF64: 00            ;     End of short lines

Demon Picture

DemonPic:        
DF65: 40 7C         ; Move to absolute (124,64)
DF67: FC            ; Draw short lines
DF68: 4E            ;     Short line to relative (-4,8)
DF69: C0            ;     Short line to relative (0,-8)
DF6A: 7B            ;     Short line to relative (-10,14)
DF6B: 9C            ;     Short line to relative (-8,-14)
DF6C: D4            ;     Short line to relative (8,-6)
DF6D: E4            ;     Short line to relative (8,-4)
DF6E: E1            ;     Short line to relative (2,-4)
DF6F: E1            ;     Short line to relative (2,-4)
DF70: DD            ;     Short line to relative (-6,-6)
DF71: 1C            ;     Short line to relative (-8,2)
DF72: 96            ;     Short line to relative (12,-14)
DF73: 03            ;     Short line to relative (6,0)
DF74: 00            ;     End of short lines
DF75: 1C 82         ; Move to absolute (130,28)
DF77: FC            ; Draw short lines
DF78: 03            ;     Short line to relative (6,0)
DF79: 45            ;     Short line to relative (10,8)
DF7A: 71            ;     Short line to relative (2,14)
DF7B: DA            ;     Short line to relative (-12,-6)
DF7C: 1E            ;     Short line to relative (-4,2)
DF7D: 11            ;     Short line to relative (2,2)
DF7E: E1            ;     Short line to relative (2,-4)
DF7F: 00            ;     End of short lines
DF80: 30 86         ; Move to absolute (134,48)
DF82: 36 8E         ; Line to absolute (142,54)
DF84: 74 A4         ; Line to absolute (164,116)
DF86: 84 84         ; Line to absolute (132,132)
DF88: 82 76         ; Line to absolute (118,130)
DF8A: 78 5E         ; Line to absolute (94,120)
DF8C: 5A 6E         ; Line to absolute (110,90)
DF8E: 84 84         ; Line to absolute (132,132)
DF90: 48 6A         ; Line to absolute (106,72)
DF92: FF            ; Start new line
DF93: 40 66         ; Move to absolute (102,64)
DF95: FC            ; Draw short lines
DF96: 1F            ;     Short line to relative (-2,2)
DF97: BD            ;     Short line to relative (-6,-10)
DF98: F1            ;     Short line to relative (2,-2)
DF99: 53            ;     Short line to relative (6,10)
DF9A: 00            ;     End of short lines
DF9B: 42 66         ; Move to absolute (102,66)
DF9D: FC            ; Draw short lines
DF9E: 1E            ;     Short line to relative (-4,2)
DF9F: 32            ;     Short line to relative (4,6)
DFA0: 11            ;     Short line to relative (2,2)
DFA1: 73            ;     Short line to relative (6,14)
DFA2: 00            ;     End of short lines
DFA3: 58 70         ; Move to absolute (112,88)
DFA5: 48 78         ; Line to absolute (120,72)
DFA7: FF            ; Start new line
DFA8: 3E 84         ; Move to absolute (132,62)
DFAA: 14 80         ; Line to absolute (128,20)
DFAC: 34 7A         ; Line to absolute (122,52)
DFAE: 40 7A         ; Line to absolute (122,64)
DFB0: 3C 7C         ; Line to absolute (124,60)
DFB2: 72 80         ; Line to absolute (128,114)
DFB4: 50 82         ; Line to absolute (130,80)
DFB6: 44 82         ; Line to absolute (130,68)
DFB8: 3E 84         ; Line to absolute (132,62)
DFBA: FF            ; Start new line
DFBB: 28 82         ; Move to absolute (130,40)
DFBD: FC            ; Draw short lines
DFBE: FF            ;     Short line to relative (-2,-2)
DFBF: 1E            ;     Short line to relative (-4,2)
DFC0: 11            ;     Short line to relative (2,2)
DFC1: F2            ;     Short line to relative (4,-2)
DFC2: 3F            ;     Short line to relative (-2,6)
DFC3: 20            ;     Short line to relative (0,4)
DFC4: 0F            ;     Short line to relative (-2,0)
DFC5: C0            ;     Short line to relative (0,-8)
DFC6: FF            ;     Short line to relative (-2,-2)
DFC7: 31            ;     Short line to relative (2,6)
DFC8: 00            ;     End of short lines
DFC9: FE            ; End of image

Snake Picture


SnakePic:        
DFCA: 84 82         ; Move to absolute (130,132)
DFCC: 70 7A         ; Line to absolute (122,112)
DFCE: 5C 7C         ; Line to absolute (124,92)
DFD0: 5E 7E         ; Line to absolute (126,94)
DFD2: 5E 82         ; Line to absolute (130,94)
DFD4: 5C 84         ; Line to absolute (132,92)
DFD6: 70 82         ; Line to absolute (130,112)
DFD8: 80 8C         ; Line to absolute (140,128)
DFDA: 84 88         ; Line to absolute (136,132)
DFDC: 84 72         ; Line to absolute (114,132)
DFDE: 78 6C         ; Line to absolute (108,120)
DFE0: 6A 76         ; Line to absolute (118,106)
DFE2: 78 70         ; Line to absolute (112,120)
DFE4: 7C 74         ; Line to absolute (116,124)
DFE6: 7C 7E         ; Line to absolute (126,124)
DFE8: FF            ; Start new line
DFE9: 64 78         ; Move to absolute (120,100)
DFEB: FC            ; Draw short lines
DFEC: E0            ;     Short line to relative (0,-4)
DFED: E2            ;     Short line to relative (4,-4)
DFEE: EE            ;     Short line to relative (-4,-4)
DFEF: E0            ;     Short line to relative (0,-4)
DFF0: F1            ;     Short line to relative (2,-2)
DFF1: 22            ;     Short line to relative (4,4)
DFF2: EE            ;     Short line to relative (-4,-4)
DFF3: 06            ;     Short line to relative (12,0)
DFF4: 2E            ;     Short line to relative (-4,4)
DFF5: E2            ;     Short line to relative (4,-4)
DFF6: 11            ;     Short line to relative (2,2)
DFF7: 20            ;     Short line to relative (0,4)
DFF8: 2E            ;     Short line to relative (-4,4)
DFF9: 22            ;     Short line to relative (4,4)
DFFA: 20            ;     Short line to relative (0,4)
DFFB: 00            ;     End of short lines
DFFC: FE            ; End of image

DFFD: 4B 53 4B ; "KSK" Initials of Keith S. Kiyohara, co-creator of the game