(back to project page)

GoldenVoyage Disassembly

                   ********************************************************************************
                   * Golden Voyage for the Apple II                                               *
                   * Game database created by William Demas and Scott Adams                       *
                   * Apple II interpreter reportedly written by Mak Jukic                         *
                   * Copyright 1981 Adventure International                                       *
                   ********************************************************************************
                   * Disassembly by Andy McFadden, using 6502bench SourceGen v1.7.5               *
                   * Last updated 2021/08/24                                                      *
                   ********************************************************************************
                   * The focus of this disassembly is on the interpreter.  The game data itself   *
                   * has received minimal formatting.                                             *
                   *                                                                              *
                   * The implementation uses 7 "virtual" 16-bit registers, stored in zero page    *
                   * locations $f0-f1 through $fc-fd.  Various operations are defined for these   *
                   * registers, which may hold values or addresses.  Most of the basic functions  *
                   * preserve all CPU registers when called, including the status register.       *
                   *                                                                              *
                   * This can make the code a bit inefficient at times, e.g. copying $f0-f1 to    *
                   * $f2-f3 requires a lot of pushing and popping, but the code is more compact   *
                   * that way.  The only other zero page locations used are those needed by the   *
                   * monitor text routines and disk or tape I/O.                                  *
                   *                                                                              *
                   * It looks like the source code was broken into several pieces, which were     *
                   * loaded at fixed addresses.  This was likely done to make development easier  *
                   * on a small system.  Each chunk starts with a table of JMP instructions, a    *
                   * few of which are actually just references to data tables with a JMP opcode   *
                   * added to make the listing nicer.                                             *
                   ********************************************************************************
                   ITEM_HELD       .eq     $ff    {const}    ;room number of player's inventory
                   MON_WNDWDTH     .eq     $21               ;width of scroll window
                   MON_WNDTOP      .eq     $22               ;top of scroll window
                   MON_CH          .eq     $24               ;cursor horizontal displacement
                   MON_CV          .eq     $25               ;cursor vertical displacement
                   MON_BASL        .eq     $28               ;base address for text output (lo)
                   MON_A1L         .eq     $3c               ;general purpose
                   MON_A1H         .eq     $3d               ;general purpose
                   MON_A2L         .eq     $3e               ;general purpose
                   MON_A2H         .eq     $3f               ;general purpose
                   STACK           .eq     $0100  {addr/256} ;CPU stack
                   MON_USRADDR     .eq     $03f8  {addr/3}   ;jump to function that handles monitor Ctrl-Y
                   KBD             .eq     $c000             ;R last key pressed + 128
                   KBDSTRB         .eq     $c010             ;RW keyboard strobe
                   MON_BASCALC     .eq     $fbc1             ;calculate text base address
                   MON_VIDOUT      .eq     $fbfd             ;output Acc as text
                   MON_BS          .eq     $fc10             ;move cursor left
                   MON_HOME        .eq     $fc58             ;clear screen and reset text output to top-left
                   MON_CR          .eq     $fc62             ;perform a carriage return
                   MON_CLREOLZ     .eq     $fc9e
                   MON_COUT        .eq     $fded             ;print Acc to output device via $36-37
                   MON_WRITE       .eq     $fecd             ;write data to cassette
                   MON_READ        .eq     $fefd             ;read data from cassette
                   MON_OLDRST      .eq     $ff59             ;RESET entry point

                                   .org    $0800
                   ; 
                   ; Program entry point.
                   ; 
0800: 4c 27 08     Entry           jmp     Start

0803: 4c cc 0b     J_PrintNonNull  jmp     PrintNonNull

0806: 4c c5 0b     J_PrintCR       jmp     PrintCR

0809: 4c 6b 0b     J_PrintL1Str    jmp     PrintL1Str

080c: 4c 62 0b     J_PrintNChars   jmp     PrintNChars

080f: 4c 95 0b     J_PrintString   jmp     PrintString

0812: 4c be 0b     J_PrintFlashStr jmp     PrintFlashStr

0815: 4c 37 0c     J_GetInput      jmp     GetInput

0818: 4c b1 0c     J_ClearScreen   jmp     ClearScreen

                   J_PrintSignedDec
081b: 4c ec 0f                     jmp     PrintSignedDec

                   J_GetItemLocation
081e: 4c ca 0f                     jmp     GetItemLocation

0821: 4c c2 0c     J_PushRegs      jmp     PushRegs

0824: 4c f2 0c     J_PopRegs       jmp     PopRegs

                   ; 
                   ; Program initialization.
                   ; 
0827: a9 4c        Start           lda     #$4c              ;point monitor Ctrl+Y vector at game loop
0829: 8d f8 03                     sta     MON_USRADDR
082c: a9 4e                        lda     #<MainLoop
082e: 8d f9 03                     sta     MON_USRADDR+1
0831: a9 08                        lda     #>MainLoop
0833: 8d fa 03                     sta     MON_USRADDR+2
0836: a2 ff                        ldx     #$ff
0838: 9a                           txs                       ;reset 6502 stack
0839: 20 3c 2e                     jsr     JJ_ClearScreen    ;clear screen
083c: 20 0c 0d                     jsr     GameInit          ;initialize game state
083f: 20 5c 10                     jsr     AskRestoreGame    ;restore saved game if desired
0842: 20 62 08                     jsr     PrintIntro        ;print intro message
0845: 20 3c 2e                     jsr     JJ_ClearScreen    ;clear screen
0848: 20 15 2e                     jsr     JJ_DescribeRoom   ;describe current room
084b: 4c 57 08                     jmp     MainLoop2         ;jump into main loop

                   ; 
                   ; Main game loop.
                   ; 
084e: 20 3c 0e     MainLoop        jsr     GetCommand        ;get a command from user
0851: 20 03 2e                     jsr     JJ_ProcessActions ;process actions for that verb/noun
0854: 20 b7 0d                     jsr     DecrementLampLevel ;decrement the lamp level
0857: a9 00        MainLoop2       lda     #$00
0859: 8d bc 30                     sta     parsed_verb_idx   ;zero out the verb
085c: 20 03 2e                     jsr     JJ_ProcessActions ;process occurrences
085f: 4c 4e 08                     jmp     MainLoop          ;loop

                   ; 
                   ; Prints the introductory screen.
                   ; 
0862: 20 3c 2e     PrintIntro      jsr     JJ_ClearScreen    ;clear text screen
0865: 20 54 2e                     jsr     InA_GetInlineData
0868: 96 08                        .dd2    msg_intro1
086a: 20 36 2e                     jsr     JJ_PrintString    ;print first part of message
086d: 20 93 2e                     jsr     InA_GetIndirectValue
0870: 53 30                        .dd2    adventure_vers
0872: 20 48 2e                     jsr     JJ_PrintSignedDec ;print version number
0875: 20 54 2e                     jsr     InA_GetInlineData
0878: b8 08                        .dd2    msg_intro2
087a: 20 36 2e                     jsr     JJ_PrintString
087d: 20 54 2e                     jsr     InA_GetInlineData
0880: 25 0b                        .dd2    msg_intro3
0882: 20 4b 2e                     jsr     JJ_PrintFlashing  ;please don't copy
0885: 20 54 2e                     jsr     InA_GetInlineData
0888: 37 0b                        .dd2    msg_intro4
088a: 20 36 2e                     jsr     JJ_PrintString
088d: 20 54 2e                     jsr     InA_GetInlineData ;get pointer to intro text again (why?)
0890: b8 08                        .dd2    msg_intro2
0892: 20 39 2e                     jsr     JJ_GetInput       ;wait for user to hit return
0895: 60                           rts

                   ; 
                   ; Intro message, formatted for 40 columns.
                   ; 
0896: 2a 20 41 44+ msg_intro1      .zstr   ‘* ADAMS ADVENTURE * (VERSION 1.2/’
08b8: 29 0d 28 43+ msg_intro2      .zstr   ‘)’,$0d,‘(C) ADVENTURE BOX 3435 LONGWOOD FL 327’
                                    +      ‘50’,$0d,‘  THIS PROGRAM WILL ALLOW YOU TO HAVE’
                                    +      ‘ AN ADVENTURE WITHOUT EVER LEAVING YOUR’,$0d
                                    +      ‘ ARMCHAIR! YOU WILL  FIND YOURSELF IN A’,$0d
                                    +      ‘ STRANGE NEW WORLD. YOU'LL BE ABLE TO’,$0d,‘ E’
                                    +      ‘XAMINE, TAKE AND OTHERWISE MANIPULATE  THE OBJ’
                                    +      ‘ECTS YOU FIND THERE. YOU WILL’,$0d,‘ ALSO BE A’
                                    +      ‘BLE TO TRAVEL FROM LOCATION TO LOCATION.’,$0d
                                    +      $0d,‘  I'LL BE YOUR PUPPET IN THIS ADVENTURE. Y’
                                    +      ‘OU COMMAND ME WITH 2 WORD ENGLISH’,$0d,‘ SENTE’
                                    +      ‘NCES. I DO HAVE OVER A 120 WORD’,$0d,‘ VOCABUL’
                                    +      ‘ARY SO IF A WORD DOESN'T WORK’,$0d,‘ TRY ANOTH’
                                    +      ‘ER!’,$0d,$0d,‘ SOME COMMANDS I KNOW: HELP, SAV’
                                    +      ‘E GAME,’,$0d,‘  QUIT, SCORE, TAKE INVENTORY.’
                                    +      $0d,$0d,‘THE AUTHOR HAS WORKED OVER A YEAR ON’
                                    +      $0d,‘THIS PROGRAM SO ’
0b25: 50 4c 45 41+ msg_intro3      .zstr   ‘PLEASE DON'T COPY’
0b37: 20 4f 52 0d+ msg_intro4      .zstr   ‘ OR’,$0d,‘ACCEPT A PIRATED COPY! NOW HIT RETUR’
                                    +      ‘N!’

                   ; 
                   ; Prints a string that is N characters long.  Does not output $00 bytes.
                   ; 
                   ; On entry:
                   ;   $f0-f1: pointer to string
                   ;   A-reg: length of string
                   ; 
                   ; On exit:
                   ;   (all registers preserved)
                   ; 
0b62: 20 57 2e     PrintNChars     jsr     JJ_PushRegs       ;preserve registers
0b65: 20 5d 2e                     jsr     JJ_PushF0F1       ;preserve $f0-f1
0b68: 4c 78 0b                     jmp     :Loop             ;jump into loop with string len in A-reg

                   ; 
                   ; Prints a string that starts with a length byte.  Does not output $00 bytes.
                   ; 
                   ; On entry:
                   ;   $f0-f1: pointer to start of string
                   ; 
                   ; On exit:
                   ;   (all registers preserved)
                   ; 
                   ]ptr            .var    $f0    {addr/2}

0b6b: 20 57 2e     PrintL1Str      jsr     JJ_PushRegs       ;preserve registers
0b6e: a0 00                        ldy     #$00
0b70: b1 f0                        lda     (]ptr),y          ;get length byte
0b72: 20 5d 2e                     jsr     JJ_PushF0F1       ;preserve $f0-f1
0b75: 20 51 2e                     jsr     JJ_IncF0F1        ;advance pointer past it
0b78: c9 00        :Loop           cmp     #$00              ;reached the end?
0b7a: f0 12                        beq     :PopReturn        ;yes, bail
0b7c: 38                           sec
0b7d: e9 01                        sbc     #$01              ;reduce by 1
0b7f: 48                           pha                       ;save remaining len
0b80: a0 00                        ldy     #$00
0b82: b1 f0                        lda     (]ptr),y          ;get char
0b84: 20 51 2e                     jsr     JJ_IncF0F1        ;advance pointer
0b87: 20 30 2e                     jsr     JJ_PrintNonNull   ;print char
0b8a: 68                           pla                       ;restore remaining len
0b8b: 4c 78 0b                     jmp     :Loop             ;loop

0b8e: 20 60 2e     :PopReturn      jsr     JJ_PopF0F1        ;restore $f0-f1
0b91: 20 5a 2e                     jsr     JJ_PopRegs        ;restore registers
0b94: 60                           rts

                   ; 
                   ; Prints a null-terminated string.
                   ; 
                   ; On entry:
                   ;   $f0-f1: pointer to string
                   ; 
                   ; On exit:
                   ;   (all registers preserved)
                   ; 
                   ]str_ptr        .var    $f0    {addr/2}

0b95: 20 57 2e     PrintString     jsr     JJ_PushRegs       ;preserve registers
0b98: a9 01                        lda     #$01              ;set not flashing
0b9a: 8d af 2e     PrintString1    sta     noflash_flag
0b9d: 20 5d 2e                     jsr     JJ_PushF0F1       ;preserve $f0-f1
0ba0: a0 00        :Loop           ldy     #$00              ;set to zero (and leave it there)
0ba2: b1 f0                        lda     (]str_ptr),y      ;get char
0ba4: f0 e8                        beq     :PopReturn        ;reached end, bail
0ba6: c9 0d                        cmp     #$0d              ;carriage return?
0ba8: f0 0b                        beq     :DoPrint          ;yes, print without modification
0baa: ac af 2e                     ldy     noflash_flag      ;flashing?
0bad: f0 04                        beq     :FlashMod         ;yes, branch
0baf: 29 7f                        and     #%01111111        ;make sure char has high bit clear
0bb1: d0 02                        bne     :DoPrint          ;(branch always, unless char was $80)
0bb3: 09 c0        :FlashMod       ora     #%11000000        ;set bits so it'll be flashing after EOR #$80
0bb5: 20 30 2e     :DoPrint        jsr     JJ_PrintNonNull   ;print char
0bb8: 20 51 2e                     jsr     JJ_IncF0F1        ;advance pointer
0bbb: 4c a0 0b                     jmp     :Loop

                   ; 
                   ; Prints a null-terminated string as flashing text.
                   ; 
                   ; On entry:
                   ;   $f0-f1: pointer to string
                   ; 
                   ; On exit:
                   ;   (all registers preserved)
                   ; 
0bbe: 20 57 2e     PrintFlashStr   jsr     JJ_PushRegs       ;preserve registers
0bc1: a9 00                        lda     #$00              ;set flashing
0bc3: f0 d5                        beq     PrintString1

                   ; 
                   ; Prints a carriage return (clear to EOL, move CH/CV to start of new line).
                   ; 
0bc5: 20 57 2e     PrintCR         jsr     JJ_PushRegs
0bc8: a9 0d                        lda     #$0d              ;carriage return
0bca: d0 03                        bne     PrintNonNull1     ;(always)

                   ; 
                   ; Prints a character, unless it's $00, in which case we return immediately.
                   ; 
                   ; If we output a non-space character at the start of a line, we back up to the
                   ; end of the previous text line and look for a non-space character.  If we find
                   ; one, we keep looking until we find a space, and then redraw all the characters
                   ; at the start of a new line.  (This is how sentences are broken across lines at
                   ; word boundaries.)
                   ; 
                   ; On entry:
                   ;   A-reg: character to print ($00-7f)
                   ; 
                   ; On exit:
                   ;   (all registers preserved)
                   ; 
0bcc: 20 57 2e     PrintNonNull    jsr     JJ_PushRegs       ;preserve registers
0bcf: c9 00        PrintNonNull1   cmp     #$00              ;is it a null byte?
0bd1: d0 04                        bne     :DoPrint          ;no, print it
0bd3: 20 5a 2e     :PullReturn     jsr     JJ_PopRegs        ;restore registers
0bd6: 60                           rts

0bd7: c9 61        :DoPrint        cmp     #‘a’              ;see if this is a lower-case letter
0bd9: 90 07                        bcc     :NotLower
0bdb: c9 7b                        cmp     #$7b              ;'z'+1
0bdd: b0 03                        bcs     :NotLower
0bdf: 38                           sec                       ;it is; convert to upper case
0be0: e9 20                        sbc     #$20
0be2: ea           :NotLower       nop
0be3: 49 80                        eor     #$80              ;flip high bit (to high for norm, low for flash)
0be5: c9 8a                        cmp     #$8a              ;linefeed?
0be7: d0 02                        bne     :NotLF            ;no, branch
0be9: a9 a0                        lda     #$a0              ;replace with space
0beb: 48           :NotLF          pha                       ;save character to print on stack
0bec: c9 8d                        cmp     #$8d              ;carriage return?
0bee: d0 0d                        bne     :NotCR            ;no, branch
                   ; Found a CR, clear screen to end of line.  MON_VIDOUT will set CH to zero and
                   ; increment CV.
0bf0: a4 21                        ldy     MON_WNDWDTH       ;get width of window
0bf2: 88           :EraseLoop      dey                       ;move left
0bf3: c4 24                        cpy     MON_CH            ;have we reached current output position?
0bf5: 30 06                        bmi     :NotCR            ;yes, continue on
0bf7: a9 a0                        lda     #$a0
0bf9: 91 28                        sta     (MON_BASL),y      ;store a space
0bfb: d0 f5                        bne     :EraseLoop

0bfd: 68           :NotCR          pla                       ;restore character to print
0bfe: 48                           pha                       ;save it again
0bff: 20 fd fb                     jsr     MON_VIDOUT        ;print it to the screen (updates CH/CV and BASL)
0c02: 68                           pla                       ;restore it
0c03: c9 8d                        cmp     #$8d              ;carriage return?
0c05: f0 cc                        beq     :PullReturn       ;yes, bail
0c07: a0 01                        ldy     #$01
0c09: c4 24                        cpy     MON_CH            ;at posn 1 (so char was output at posn 0)?
0c0b: d0 c6                        bne     :PullReturn       ;no, bail
0c0d: a4 25                        ldy     MON_CV            ;are we at the top of the screen?
0c0f: f0 c2                        beq     :PullReturn       ;yes, bail
0c11: a2 00                        ldx     #$00              ;init saved-char count to zero
0c13: c9 a0                        cmp     #$a0              ;was it a space?
0c15: f0 bc                        beq     :PullReturn       ;yes, return
                   ; We output a non-space character at offset 0.  Back up to the end of the
                   ; previous line to see if this was part of a longer word.  Push chars on the
                   ; stack as we erase them, output a CR, then output the chars.
                   ; 
                   ; For the case where this was not part of a longer word, we will erase and
                   ; redraw the original character.
0c17: ea           :BackupLoop     nop
0c18: 20 10 fc                     jsr     MON_BS            ;back up one space (updates CH/CV and BASL)
0c1b: a4 24                        ldy     MON_CH
0c1d: b1 28                        lda     (MON_BASL),y      ;get char
0c1f: c9 a0                        cmp     #“ ”              ;is it a space?
0c21: f0 08                        beq     :FoundBreak       ;yes, found break
0c23: e8                           inx                       ;no, increment count
0c24: 48                           pha                       ;push char on stack
0c25: a9 a0                        lda     #“ ”
0c27: 91 28                        sta     (MON_BASL),y      ;erase screen char
0c29: d0 ec                        bne     :BackupLoop       ;loop

0c2b: 20 62 fc     :FoundBreak     jsr     MON_CR            ;move to start of new line
0c2e: 68           :OutputLoop     pla                       ;pull char
0c2f: 20 fd fb                     jsr     MON_VIDOUT        ;write on screen
0c32: ca                           dex                       ;done yet?
0c33: d0 f9                        bne     :OutputLoop       ;no, loop
0c35: f0 9c                        beq     :PullReturn       ;yes, bail

                   ; 
                   ; Gets up to 18 characters of input from the player.  Returns when the player
                   ; hits Return or types the 18th character.  Handles backspace.
                   ; 
                   ; Keys are written to an input buffer, terminated with $00.
                   ; 
                   ]buf_ptr        .var    $f0    {addr/2}

0c37: 20 57 2e     GetInput        jsr     JJ_PushRegs       ;preserve registers
0c3a: 20 5d 2e                     jsr     JJ_PushF0F1       ;preserve $f0-f1
0c3d: 20 54 2e                     jsr     InA_GetInlineData ;get pointer to input buffer in $f0-f1
0c40: 32 2f                        .dd2    kbd_scratch_buf-1
0c42: a0 19                        ldy     #25               ;erase 24 bytes (+1)
0c44: a9 00                        lda     #$00
0c46: 91 f0        :ClearLoop      sta     (]buf_ptr),y
0c48: 88                           dey
0c49: d0 fb                        bne     :ClearLoop        ;stop before writting to offset zero
                   ; 
0c4b: 20 54 2e                     jsr     InA_GetInlineData
0c4e: 33 2f                        .dd2    kbd_scratch_buf
0c50: a4 24                        ldy     MON_CH            ;get current horizontal text position
0c52: a2 00                        ldx     #$00              ;set X-reg to zero so we can use as index
0c54: b1 28        :SetFlashCursor lda     (MON_BASL),y      ;read value from screen
0c56: 29 3f                        and     #%00111111        ;upper-case, low ASCII
0c58: 09 40                        ora     #%01000000        ;make it flash
0c5a: 91 28                        sta     (MON_BASL),y      ;store on screen
                   ; 
0c5c: ee b0 2e     :KeyLoop        inc     kbd_rng_seed      ;increment random seed
0c5f: d0 03                        bne     :NoInc
0c61: ee b1 2e                     inc     kbd_rng_seed+1
0c64: ad 00 c0     :NoInc          lda     KBD               ;check for input
0c67: 10 f3                        bpl     :KeyLoop
                   ; 
0c69: 91 28                        sta     (MON_BASL),y      ;store character on screen (incl. Ctrl+H / Ctrl+M)
0c6b: 49 80                        eor     #%10000000        ;strip high bit
0c6d: 2c 10 c0                     bit     KBDSTRB           ;reset keyboard strobe
0c70: c9 08                        cmp     #$08              ;backspace key?
0c72: d0 1e                        bne     :NotBackspace
                   ; 
0c74: 20 7e 2e                     jsr     InA_SubF0F1_Inline ;subtract current position from initial position
0c77: 33 2f                        .dd2    kbd_scratch_buf
0c79: d0 06                        bne     :NotAtStart       ;haven't backed up to start yet, branch
0c7b: a9 40                        lda     #$40              ;flashing space
0c7d: 91 28                        sta     (MON_BASL),y      ;store on screen
0c7f: d0 db                        bne     :KeyLoop          ;loop

0c81: 20 4e 2e     :NotAtStart     jsr     JJ_DecF0F1        ;decrement buffer pointer
0c84: 8a                           txa                       ;A-reg=0
0c85: 81 f0                        sta     (]buf_ptr,x)      ;write zero to buffer
0c87: a9 a0                        lda     #“ ”              ;high-ASCII space
0c89: 91 28                        sta     (MON_BASL),y      ;write to screen (replaces $88 we just wrote)
0c8b: c6 24                        dec     MON_CH            ;decrement text position
0c8d: 88                           dey
0c8e: 91 28                        sta     (MON_BASL),y      ;write to screen (replaces char we backed over)
0c90: d0 c2                        bne     :SetFlashCursor   ;(always, assuming there's prompt text so Y-reg != 0)
                   ; 
0c92: c9 0d        :NotBackspace   cmp     #$0d              ;return key?
0c94: d0 0a                        bne     :AddChar          ;no, branch
                   ; Return key hit, return input to caller.
0c96: 20 60 2e     :FinishInput    jsr     JJ_PopF0F1        ;restore $f0-f1
0c99: 20 33 2e                     jsr     JJ_PrintCR        ;clear to EOL, move CH/CV to start of new line
0c9c: 20 5a 2e                     jsr     JJ_PopRegs        ;restore registers
0c9f: 60                           rts

0ca0: 81 f0        :AddChar        sta     (]buf_ptr,x)      ;add character to buffer
0ca2: e6 24                        inc     MON_CH            ;advance text position
0ca4: c8                           iny
0ca5: 20 51 2e                     jsr     JJ_IncF0F1        ;advance buffer position
0ca8: 20 7e 2e                     jsr     InA_SubF0F1_Inline ;have we input 18 chars?
0cab: 45 2f                        .dd2    kbd_scratch_buf+18
0cad: f0 e7                        beq     :FinishInput      ;yes, accept line and bail
0caf: d0 a3                        bne     :SetFlashCursor   ;no, loop (always)

                   ; 
                   ; Clears the full screen.  Resets the scroll window top.
                   ; 
0cb1: 20 57 2e     ClearScreen     jsr     JJ_PushRegs       ;preserve registers
0cb4: a9 00                        lda     #$00
0cb6: 8d 59 30                     sta     screen_cleared?   ;?
0cb9: 85 22                        sta     MON_WNDTOP        ;reset scroll window
0cbb: 20 58 fc                     jsr     MON_HOME          ;clear it
0cbe: 20 5a 2e                     jsr     JJ_PopRegs        ;restore registers
0cc1: 60                           rts

                   ; 
                   ; Pushes registers onto stack and returns to caller.
                   ; Order: P A X Y.
                   ; 
                   ; On exit:
                   ;   (all registers preserved)
                   ; 
0cc2: 8d ab 2e     PushRegs        sta     regsv_tmp_a       ;save A-reg
0cc5: 08                           php                       ;save P-reg
0cc6: 68                           pla
0cc7: 8d ac 2e                     sta     regsv_tmp_p
0cca: 68                           pla                       ;pull return address off stack
0ccb: 8d ad 2e                     sta     regsv_ret_addr
0cce: 68                           pla
0ccf: 8d ae 2e                     sta     regsv_ret_addr+1
0cd2: ee ad 2e                     inc     regsv_ret_addr    ;increment return address so we jump to
0cd5: d0 03                        bne     :NoInc            ; byte after the JSR
0cd7: ee ae 2e                     inc     regsv_ret_addr+1
0cda: ea           :NoInc          nop
0cdb: ad ac 2e                     lda     regsv_tmp_p       ;push P-reg
0cde: 48                           pha
0cdf: ad ab 2e                     lda     regsv_tmp_a       ;push A-reg
0ce2: 48                           pha
0ce3: 8a                           txa                       ;push X-reg
0ce4: 48                           pha
0ce5: 98                           tya                       ;push Y-reg
0ce6: 48                           pha
0ce7: ad ac 2e                     lda     regsv_tmp_p       ;push P-reg
0cea: 48                           pha
0ceb: ad ab 2e                     lda     regsv_tmp_a       ;restore A-reg
0cee: 28                           plp                       ;restore P-reg
0cef: 6c ad 2e                     jmp     (regsv_ret_addr)  ;resume execution at caller (same as RTS)

                   ; 
                   ; Pops registers off stack and returns to caller.
                   ; Order: Y X A P
                   ; 
                   ; On exit:
                   ;   (all registers restored from stack)
                   ; 
0cf2: 68           PopRegs         pla                       ;pull return address
0cf3: 8d ad 2e                     sta     regsv_ret_addr
0cf6: 68                           pla
0cf7: 8d ae 2e                     sta     regsv_ret_addr+1
0cfa: ee ad 2e                     inc     regsv_ret_addr    ;increment return address so we jump to
0cfd: d0 03                        bne     :NoInc            ; byte after the JSR
0cff: ee ae 2e                     inc     regsv_ret_addr+1
0d02: ea           :NoInc          nop
0d03: 68                           pla                       ;pull Y-reg
0d04: a8                           tay
0d05: 68                           pla                       ;pull X-reg
0d06: aa                           tax
0d07: 68                           pla                       ;pull A-reg
0d08: 28                           plp                       ;pull P-reg
0d09: 6c ad 2e                     jmp     (regsv_ret_addr)

                   ; 
                   ; Initializes game state.  Puts objects in default locations, clears flags, etc.
                   ; 
                   ]item_init_ptr  .var    $f0    {addr/2}
                   ]item_cur_ptr   .var    $f2    {addr/2}
                   ]table_len      .var    $f5    {addr/1}

0d0c: 20 93 2e     GameInit        jsr     InA_GetIndirectValue ;get max item value into $f0-f1
0d0f: 6f 30                        .dd2    hdr_max_item
0d11: 20 84 2e                     jsr     JJ_SetF4F5_F0F1   ;copy to $f4-f5
0d14: 20 87 2e                     jsr     JJ_AddF0F1_F4F5   ;add to itself
0d17: 20 84 2e                     jsr     JJ_SetF4F5_F0F1   ;save in $f4-f5
0d1a: 20 93 2e                     jsr     InA_GetIndirectValue ;get pointer to item location data
0d1d: 26 2f                        .dd2    item_rooms_ptr
0d1f: 20 81 2e                     jsr     JJ_SetF2F3_F0F1   ;copy pointer to $f2-f3
0d22: 20 93 2e                     jsr     InA_GetIndirectValue ;get pointer to ? in $f0-f1
0d25: 2a 2f                        .dd2    item_initroom_ptr
                   ; Initialize item locations.
0d27: a0 00                        ldy     #$00
0d29: b1 f0        :Loop           lda     (]item_init_ptr),y ;get initial location
0d2b: 91 f2                        sta     (]item_cur_ptr),y ;copy to location data area
0d2d: 20 51 2e                     jsr     JJ_IncF0F1        ;advance src ptr
0d30: 20 6c 2e                     jsr     JJ_IncF2F3        ;advance dst ptr
0d33: 20 63 2e                     jsr     JJ_DecF4F5        ;decrement length
0d36: a5 f5                        lda     ]table_len        ;done yet?
0d38: 10 ef                        bpl     :Loop             ;no, loop
                   ; 
0d3a: ad 77 30                     lda     hdr_start_room    ;set initial player location
0d3d: 8d e9 30                     sta     current_room
0d40: ad 78 30                     lda     hdr_start_room+1
0d43: 8d ea 30                     sta     current_room+1
0d46: ad 7b 30                     lda     hdr_lamp_capacity ;fill lightsource object
0d49: 8d 01 31                     sta     lamp_fuel_level
0d4c: ad 7c 30                     lda     hdr_lamp_capacity+1
0d4f: 8d 02 31                     sta     lamp_fuel_level+1
0d52: a9 00                        lda     #$00              ;clear debug flag
0d54: 8d 7d 30                     sta     debug_flag
                   ; Clear all action flags (0-31).
0d57: 20 54 2e                     jsr     InA_GetInlineData ;get pointer to flags
0d5a: c9 30                        .dd2    action_flags
0d5c: a0 1f                        ldy     #31
0d5e: 91 f0        :Loop           sta     (]item_init_ptr),y ;store zero
0d60: 88                           dey
0d61: 10 fb                        bpl     :Loop
0d63: 60                           rts

                   ; 
                   ; Finds a match for the trimmed string in the list of words.  The caller points
                   ; to either the verb list or the noun list, which are padded to be the same
                   ; length.
                   ; 
                   ; The trimmed word buffer and the items in the word list are both padded with
                   ; trailing $00 bytes, so we can simply compare all N bytes (where N is
                   ; configurable, 4 in this case).
                   ; 
                   ; If we match on an alias, we return the index of the "base" word, and replace
                   ; the word in the trim buffer with the base.
                   ; 
                   ; On entry:
                   ;   $f0-f1: pointer to verb or noun collection
                   ;   (trimmed input word at $3080)
                   ; 
                   ; On exit:
                   ;   Z-flag set if match found
                   ;   (word index in $309d)
                   ; 
                   ]trim_verb      .var    $f0    {addr/2}
                   ]word_list      .var    $f2    {addr/2}

0d64: ad 6b 30     FindWord        lda     hdr_max_nounverb  ;get dictionary size
0d67: 8d 9e 30                     sta     tmp_save_reg2     ;use as counter
0d6a: 20 81 2e                     jsr     JJ_SetF2F3_F0F1   ;copy word collection pointer into $f2-f3
0d6d: a9 00                        lda     #$00
0d6f: 8d 9d 30                     sta     tmp_save_reg1
0d72: 20 54 2e                     jsr     InA_GetInlineData ;get pointer to trimmed word in $f0-f1
0d75: 80 30                        .dd2    word_trim_buf     ;this points at first char, but dictionary words
0d77: 20 4e 2e                     jsr     JJ_DecF0F1        ; start with $00 or '*', so back up 1 to match
                   ; 
0d7a: ac 69 30     :CmpWord        ldy     hdr_word_len      ;get word length (3/4/5)
0d7d: b1 f0        :CmpLoop        lda     (]trim_verb),y    ;get char from trimmed input buffer
0d7f: d1 f2                        cmp     (]word_list),y    ;compare to word in list
0d81: d0 22                        bne     :TryNext          ;didn't match, branch
0d83: 88                           dey                       ;tried all 4?
0d84: d0 f7                        bne     :CmpLoop          ;no, branch
                   ; If this word was an alias, back up until we find one that isn't.
0d86: b1 f2        :DeAlias        lda     (]word_list),y    ;get first char (Y-reg=0)
0d88: c9 2a                        cmp     #‘*’              ;is it an asterisk?
0d8a: d0 0e                        bne     :NotAlias         ;no, this word is not an alias
0d8c: ae 69 30                     ldx     hdr_word_len      ;back up a full word
0d8f: 20 69 2e     :BackLoop       jsr     JJ_DecF2F3        ;decrement pointer
0d92: ca                           dex                       ;done yet?
0d93: 10 fa                        bpl     :BackLoop         ;no, loop
0d95: ce 9d 30                     dec     tmp_save_reg1     ;adjust result value
0d98: d0 ec                        bne     :DeAlias          ;branch always (unless this was first word in list)
                   ; Copy word from list back to trim buffer.
0d9a: ac 69 30     :NotAlias       ldy     hdr_word_len      ;get word length
0d9d: b1 f2        :CopyLoop       lda     (]word_list),y    ;copy word from word list into trim buffer; this
0d9f: 91 f0                        sta     (]trim_verb),y    ; is a no-op unless the word was an alias
0da1: 88                           dey
0da2: d0 f9                        bne     :CopyLoop
0da4: 60                           rts                       ;return with Z-flag=1

0da5: ac 69 30     :TryNext        ldy     hdr_word_len      ;get full word length
0da8: 20 6c 2e     :IncrLoop       jsr     JJ_IncF2F3        ;increment pointer until we're at start of next
0dab: 88                           dey                       ;done yet?
0dac: 10 fa                        bpl     :IncrLoop         ;no, loop
0dae: ee 9d 30                     inc     tmp_save_reg1     ;increment result value
0db1: ce 9e 30                     dec     tmp_save_reg2     ;done yet?
0db4: 10 c4                        bpl     :CmpWord          ;no, loop
0db6: 60                           rts                       ;return with Z-flag=0

                   ; 
                   ; Reduces the lamp fuel level by 1, unless the lamp is in room 0 ("nowhere"). 
                   ; If we drop below 25, print a warning.  If we drop below 0, set the
                   ; "lightsource empty" flag.
                   ; 
                   ; It's up to the game to provide an action that removes the lightsource object
                   ; (#9) from the player's inventory, e.g. replacing it with "empty lamp".  If
                   ; they don't, the object will continue to provide light, and we will continue to
                   ; decrement the counter (until it rolls under).
                   ; 
                   ]item_room      .var    $f0    {addr/2}

                   DecrementLampLevel
0db7: 20 93 2e                     jsr     InA_GetIndirectValue
0dba: 26 2f                        .dd2    item_rooms_ptr
0dbc: a0 12                        ldy     #18               ;object #9 (lamp)
0dbe: b1 f0                        lda     (]item_room),y    ;get current room (low byte)
0dc0: c8                           iny
0dc1: 11 f0                        ora     (]item_room),y    ;OR with current room (high byte)
0dc3: f0 26                        beq     :Return           ;if it's in room zero, don't modify the fuel level
                   ; 
0dc5: 20 93 2e                     jsr     InA_GetIndirectValue ;get lamp level in $f0-f1
0dc8: 01 31                        .dd2    lamp_fuel_level
0dca: 20 4e 2e                     jsr     JJ_DecF0F1        ;decrement
0dcd: 20 90 2e                     jsr     InA_SetIndirectValue ;store value
0dd0: 01 31                        .dd2    lamp_fuel_level
0dd2: ad 02 31                     lda     lamp_fuel_level+1 ;fuel level high byte nonzero?
0dd5: d0 14                        bne     :Return           ;yes, got fuel, bail
0dd7: ad 01 31                     lda     lamp_fuel_level   ;check low byte
0dda: 30 0f                        bmi     :Return           ;sub-zero, we've already complained, bail
0ddc: d0 0e                        bne     :WarnLow          ;not zero yet, print warning
                   ; Counter just hit zero.  Tell the player the bad news.
0dde: a9 ff                        lda     #$ff
0de0: 8d d9 30                     sta     lamp_empty_flag   ;set flag #16, indicating lamp is empty
0de3: 20 54 2e                     jsr     InA_GetInlineData
0de6: 26 0e                        .dd2    msg_light_out
0de8: 20 4b 2e                     jsr     JJ_PrintFlashing  ;print "light has run out" message
0deb: 60           :Return         rts

0dec: c9 19        :WarnLow        cmp     #25               ;do we have at least 25 moves left?
0dee: 10 fb                        bpl     :Return           ;yes, bail
0df0: 20 54 2e                     jsr     InA_GetInlineData ;no, print warning message
0df3: 09 0e                        .dd2    msg_light_runs_out
0df5: 20 4b 2e                     jsr     JJ_PrintFlashing  ;flashing for emphasis
0df8: 20 93 2e                     jsr     InA_GetIndirectValue ;get fuel level
0dfb: 01 31                        .dd2    lamp_fuel_level
0dfd: 20 48 2e                     jsr     JJ_PrintSignedDec ;print as integer
0e00: 20 54 2e                     jsr     InA_GetInlineData
0e03: 1e 0e                        .dd2    msg_light_turns
0e05: 20 4b 2e                     jsr     JJ_PrintFlashing
0e08: 60                           rts

                   msg_light_runs_out
0e09: 0d 20 4c 49+                 .zstr   $0d,‘ LIGHT RUNS OUT IN ’
0e1e: 20 54 55 52+ msg_light_turns .zstr   ‘ TURNS’,$0d
0e26: 0d 20 4c 49+ msg_light_out   .zstr   $0d,‘ LIGHT HAS RUN OUT!’,$0d

                   ; 
                   ; Gets a line of input from the player, tokenizes it, and parse it into
                   ; verb/noun.  Converts single-character built-in commands like "I" and "N" into
                   ; verbs.
                   ; 
                   ; This does not return until it has received valid input.
                   ; 
                   ; On exit:
                   ;   (parsed_verb_idx and parsed_noun_idx set)
                   ;   (input trim buffer holds trimmed noun)
                   ; 
                   ]kbd_buf        .var    $f4    {addr/2}

0e3c: 20 54 2e     GetCommand      jsr     InA_GetInlineData
0e3f: 3c 0f                        .dd2    msg_prompt
0e41: 20 36 2e                     jsr     JJ_PrintString    ;print prompt for command
0e44: 20 39 2e                     jsr     JJ_GetInput       ;get a buffer full of keystrokes
0e47: 20 54 2e                     jsr     InA_GetInlineData ;get pointer to input buffer
0e4a: 33 2f                        .dd2    kbd_scratch_buf
0e4c: 20 84 2e                     jsr     JJ_SetF4F5_F0F1   ;copy kbd input pointer to $f4-f5
                   ; Look for a verb.
0e4f: 20 94 0f                     jsr     TrimWord          ;copy to buf, trimming whitespace; advances $f4-f5
0e52: ad 81 30                     lda     word_trim_buf+1   ;test for single-char command
0e55: d0 51                        bne     :MultiChar        ;multi-char, branch
                   ; Handle some built-in single-character commands.
0e57: ad 80 30                     lda     word_trim_buf     ;get first char
0e5a: c9 58                        cmp     #‘X’              ;was it X?
0e5c: d0 06                        bne     :CheckP           ;no, branch
0e5e: a9 00                        lda     #$00              ;set debug flat to 0
0e60: 8d 7d 30     :SetDebug       sta     debug_flag
0e63: 60                           rts

0e64: c9 50        :CheckP         cmp     #‘P’              ;was it P?
0e66: d0 04                        bne     :CheckT           ;no, branch
0e68: a9 01                        lda     #$01              ;set debug flag to 1
0e6a: d0 f4                        bne     :SetDebug

0e6c: c9 54        :CheckT         cmp     #‘T’              ;was it T?
0e6e: d0 04                        bne     :CheckI           ;no, branch
0e70: a9 02                        lda     #$02              ;set debug flag to 2
0e72: d0 ec                        bne     :SetDebug

0e74: c9 49        :CheckI         cmp     #‘I’              ;inventory?
0e76: d0 17                        bne     :CheckDir         ;no, branch
0e78: a9 4e                        lda     #‘N’              ;yes, stuff in chars to make it "INVE"
0e7a: 8d 81 30                     sta     word_trim_buf+1
0e7d: a9 56                        lda     #‘V’
0e7f: 8d 82 30                     sta     word_trim_buf+2
0e82: a9 45                        lda     #‘E’
0e84: 8d 83 30                     sta     word_trim_buf+3
0e87: d0 1f                        bne     :MultiChar        ;handle as multi-char entry

                   :direction_chars
0e89: 4e 53 45 57+                 .str    ‘NSEWUD’          ;north/south/east/west/up/down

                   ]dc_ptr         .var    $f0    {addr/2}

0e8f: 20 54 2e     :CheckDir       jsr     InA_GetInlineData ;get pointer to direction chars, -1 so result
0e92: 88 0e                        .dd2    :direction_chars-1 ; will be [1,6] instead of [0,5]
0e94: a0 06                        ldy     #6                ;6 chars in direction_chars
0e96: d1 f0        :DirLoop        cmp     (]dc_ptr),y       ;match?
0e98: f0 05                        beq     :FoundDir         ;yes, branch
0e9a: 88                           dey                       ;done yet?
0e9b: d0 f9                        bne     :DirLoop          ;no, branch
0e9d: f0 09                        beq     :MultiChar        ;(always)

0e9f: 8c be 30     :FoundDir       sty     parsed_noun_idx   ;save noun index (1-6)
0ea2: a9 01                        lda     #$01
0ea4: 8d bc 30                     sta     parsed_verb_idx
0ea7: 60                           rts

                   ; Find a match for a multi-character verb.
0ea8: 20 93 2e     :MultiChar      jsr     InA_GetIndirectValue ;get pointer to verb table
0eab: 30 2f                        .dd2    verb_words_ptr
0ead: 20 64 0d                     jsr     FindWord          ;look for a matching word
0eb0: f0 1b                        beq     :GotVerb          ;found match, branch
0eb2: 20 54 2e                     jsr     InA_GetInlineData ;didn't match, complain
0eb5: 53 0f                        .dd2    msg_dont_how
0eb7: 20 36 2e                     jsr     JJ_PrintString
0eba: 20 54 2e                     jsr     InA_GetInlineData
0ebd: 80 30                        .dd2    word_trim_buf
0ebf: 20 4b 2e                     jsr     JJ_PrintFlashing  ;print verb, flashing
0ec2: 20 54 2e                     jsr     InA_GetInlineData
0ec5: 6a 0f                        .dd2    msg_dont_how2
0ec7: 20 36 2e                     jsr     JJ_PrintString
0eca: 4c 3c 0e                     jmp     GetCommand        ;go get a new command (w/o actions or lamp--)

0ecd: ad 9d 30     :GotVerb        lda     tmp_save_reg1     ;save verb index in global
0ed0: 8d bc 30                     sta     parsed_verb_idx
                   ; Now look for a noun.
0ed3: 20 94 0f                     jsr     TrimWord          ;copy to buf, trimming whitespace; advances $f4-f5
0ed6: ad 80 30                     lda     word_trim_buf     ;get first char of noun
0ed9: 8d be 30                     sta     parsed_noun_idx   ;if it's $00, set the noun index to zero
0edc: f0 2b                        beq     :Chk3             ; and branch (otherwise, parsed_noun_idx is garbage)
0ede: 20 93 2e                     jsr     InA_GetIndirectValue ;get pointer to noun table
0ee1: 2e 2f                        .dd2    noun_words_ptr
0ee3: 20 64 0d                     jsr     FindWord          ;look for a matching word
0ee6: f0 1b                        beq     :GotNoun          ;found match, branch
0ee8: 20 54 2e                     jsr     InA_GetInlineData ;didn't match, complain
0eeb: 78 0f                        .dd2    msg_dont_what
0eed: 20 36 2e                     jsr     JJ_PrintString
0ef0: 20 54 2e                     jsr     InA_GetInlineData ;print noun, flashing
0ef3: 80 30                        .dd2    word_trim_buf
0ef5: 20 4b 2e                     jsr     JJ_PrintFlashing
0ef8: 20 54 2e                     jsr     InA_GetInlineData
0efb: 8d 0f                        .dd2    msg_dont_what2
0efd: 20 36 2e                     jsr     JJ_PrintString
0f00: 4c 3c 0e                     jmp     GetCommand        ;go get a new command (w/o actions or lamp--)

0f03: ad 9d 30     :GotNoun        lda     tmp_save_reg1     ;save noun index in global
0f06: 8d be 30                     sta     parsed_noun_idx
                   ; Check for a third word.  $f4-f5 points at end of noun in kbd buf.
0f09: a0 00        :Chk3           ldy     #$00
0f0b: b1 f4        :Chk3Loop       lda     (]kbd_buf),y      ;get char
0f0d: d0 01                        bne     :AfterSpace       ;not $00, check it
0f0f: 60                           rts                       ;all good, return

0f10: c8           :AfterSpace     iny                       ;advance to next char
0f11: c9 20                        cmp     #$20              ;was this one a space?
0f13: f0 f6                        beq     :Chk3Loop         ;yes, keep looking
0f15: 20 54 2e                     jsr     InA_GetInlineData ;no, they entered 3+ words
0f18: 20 0f                        .dd2    msg_max_2words
0f1a: 20 4b 2e                     jsr     JJ_PrintFlashing  ;complain
0f1d: 4c 3c 0e                     jmp     GetCommand        ;go get a new command (w/o actions or lamp--)

0f20: 20 55 53 45+ msg_max_2words  .zstr   ‘ USE NO MORE THAN 2 WORDS!’,$0d ;max two per customer
0f3c: 20 2d 2d 3e+ msg_prompt      .zstr   ‘ --> WHAT SHALL I DO? ’ ;basic command prompt
0f53: 0d 49 20 44+ msg_dont_how    .zstr   $0d,‘I DON'T KNOW HOW TO "’ ;unknown verb
0f6a: 22 20 53 4f+ msg_dont_how2   .zstr   ‘" SOMETHING.’,$0d
0f78: 0d 49 20 44+ msg_dont_what   .zstr   $0d,‘I DON'T KNOW WHAT "’ ;unknown noun
0f8d: 22 20 49 53+ msg_dont_what2  .zstr   ‘" IS.’,$0d

                   ; 
                   ; Trims a word, copying it while stripping leading/trailing whitespace.
                   ; 
                   ; On entry:
                   ;   $f4-f5: pointer to source data (key input buffer)
                   ; 
                   ; On exit:
                   ;   $f4-f5: moved to first byte past end of input string
                   ;   (trimmed word in output buffer, terminated with $00)
                   ; 
                   • Clear variables
                   ]trim_buf       .var    $f0    {addr/2}
                   ]kbd_buf        .var    $f4    {addr/2}

0f94: 20 75 2e     TrimWord        jsr     JJ_PushF2F3       ;preserve $f2-f3
0f97: a9 00                        lda     #$00
0f99: a0 17                        ldy     #23
0f9b: 20 54 2e                     jsr     InA_GetInlineData ;get buffer pointer ($3080) in $f0-f1
0f9e: 80 30                        .dd2    word_trim_buf
0fa0: 20 81 2e                     jsr     JJ_SetF2F3_F0F1   ;copy $f0-f1 to $f2-f3 (why?)
0fa3: 91 f0        :ClearLoop      sta     (]trim_buf),y     ;clear buffer to zeroes
0fa5: 88                           dey
0fa6: 10 fb                        bpl     :ClearLoop
                   ; 
0fa8: a2 00                        ldx     #$00              ;found-non-space flag
0faa: a0 00                        ldy     #$00              ;always zero
0fac: b1 f4        :GetLoop        lda     (]kbd_buf),y      ;get char
0fae: 20 66 2e                     jsr     JJ_IncF4F5        ;advance kbd buf pointer (preserves flags)
0fb1: d0 04                        bne     :CheckSpace       ;if it's not $00, branch
0fb3: 20 78 2e     :PopReturn      jsr     JJ_PopF2F3        ;all done; restore $f2-f3
0fb6: 60                           rts

0fb7: c9 20        :CheckSpace     cmp     #‘ ’              ;is it a space?
0fb9: d0 06                        bne     :NotSpace         ;no, branch
0fbb: e0 00                        cpx     #$00              ;have we found a non-space char yet?
0fbd: f0 ed                        beq     :GetLoop          ;no, skip over leading space
0fbf: d0 f2                        bne     :PopReturn        ;yes, found end of word; branch

0fc1: 91 f0        :NotSpace       sta     (]trim_buf),y     ;copy to trim buffer
0fc3: 20 51 2e                     jsr     JJ_IncF0F1        ;advance output pointer
0fc6: a2 01                        ldx     #$01              ;set found-non-space flag
0fc8: d0 e2                        bne     :GetLoop          ;(always)

                   ; 
                   ; Get item's current location.
                   ; 
                   ; On entry:
                   ;   $f0-f1: index of item
                   ; 
                   ; On exit:
                   ;   $f0-f1: pointer to location data in item table
                   ;   A-reg: room number
                   ;   (X-reg and Y-reg preserved)
                   ; 
0fca: 8e 9d 30     GetItemLocation stx     tmp_save_reg1
0fcd: 20 6f 2e                     jsr     JJ_PushF4F5       ;preserve $f4-f5
0fd0: 20 84 2e                     jsr     JJ_SetF4F5_F0F1   ;set $f4-f5 = $f0-f1
0fd3: 20 87 2e                     jsr     JJ_AddF0F1_F4F5   ;$f0-f1 += $f4-f5 (i.e. double the value)
0fd6: 20 84 2e                     jsr     JJ_SetF4F5_F0F1   ;set $f4-f5 = $f0-f1
0fd9: 20 93 2e                     jsr     InA_GetIndirectValue ;get pointer to item room data
0fdc: 26 2f                        .dd2    item_rooms_ptr
0fde: 20 87 2e                     jsr     JJ_AddF0F1_F4F5   ;add doubled index
0fe1: 20 72 2e                     jsr     JJ_PopF4F5        ;restore $f4-f5
0fe4: a2 00                        ldx     #$00
0fe6: a1 f0                        lda     (]trim_buf,x)     ;get room number
0fe8: ae 9d 30                     ldx     tmp_save_reg1
0feb: 60                           rts

                   ; 
                   ; Prints a 16-bit integer as a signed decimal value.
                   ; 
                   ; On entry:
                   ;   $f0-f1: value to print
                   ; 
                   ]value          .var    $f0    {addr/2}
                   ]rem            .var    $f2    {addr/1}
                   ]out_ptr        .var    $f4    {addr/2}

0fec: 20 8a 2e     PrintSignedDec  jsr     JJ_PushFullState  ;preserve all regs and ZP
0fef: a5 f0                        lda     ]value            ;stash value in temporary mem
0ff1: 8d 9d 30                     sta     tmp_save_reg1
0ff4: a5 f1                        lda     ]value+1
0ff6: 8d 9e 30                     sta     tmp_save_reg2
0ff9: 20 54 2e                     jsr     InA_GetInlineData ;get pointer to output buffer, past the length byte
0ffc: b6 30                        .dd2    dec_outbuf+1
0ffe: a0 05                        ldy     #$05              ;max of six chars (e.g. "-32767")
1000: a9 00        :ClearLoop      lda     #$00
1002: 91 f0                        sta     (]value),y        ;zero out the output buffer
1004: 88                           dey
1005: 10 f9                        bpl     :ClearLoop
                   ; 
1007: ad 9e 30                     lda     tmp_save_reg2     ;check the high byte
100a: 10 16                        bpl     :IsPos            ;it's positive, branch
100c: a9 2d                        lda     #‘-’
100e: 8d b6 30                     sta     dec_outbuf+1      ;output a minus sign
1011: 38                           sec                       ;negate the value so we're working
1012: a9 00                        lda     #$00              ; with a positive number
1014: ed 9d 30                     sbc     tmp_save_reg1     ; (this has classic issue with -32768)
1017: 8d 9d 30                     sta     tmp_save_reg1
101a: a9 00                        lda     #$00
101c: ed 9e 30                     sbc     tmp_save_reg2
101f: 8d 9e 30                     sta     tmp_save_reg2
1022: 20 54 2e     :IsPos          jsr     InA_GetInlineData ;get pointer to output buffer
1025: b6 30                        .dd2    dec_outbuf+1
1027: 20 84 2e                     jsr     JJ_SetF4F5_F0F1   ;put pointer in $f4-f5
102a: 20 93 2e                     jsr     InA_GetIndirectValue ;load positive value into $f0-f1
102d: 9d 30                        .dd2    tmp_save_reg1
102f: a0 05                        ldy     #$05              ;start at offset 5
1031: 20 81 2e     :OutLoop        jsr     JJ_SetF2F3_F0F1   ;set $f2-f3 to $f0-f1
1034: 20 54 2e                     jsr     InA_GetInlineData ;set $f0-f1 to 10
1037: 0a 00                        .dd2    10
1039: 20 21 2e                     jsr     JJ_Divide16       ;divide by 10
103c: a5 f2                        lda     ]rem              ;get remainder
103e: 09 30                        ora     #‘0’              ;convert to ASCII digit
1040: 91 f4                        sta     (]out_ptr),y      ;store in output buffer
1042: a5 f0                        lda     ]value            ;are we done yet?
1044: 05 f1                        ora     ]value+1
1046: f0 03                        beq     :OutputDone       ;yes, branch
1048: 88                           dey                       ;no, reduce index
1049: d0 e6                        bne     :OutLoop          ;and loop
                   ; 
104b: a0 06        :OutputDone     ldy     #$06
104d: 8c b5 30                     sty     dec_outbuf        ;set the length to 6 characters
1050: 20 54 2e                     jsr     InA_GetInlineData ;get pointer to output buffer
1053: b5 30                        .dd2    dec_outbuf
1055: 20 42 2e                     jsr     JJ_PrintL1Str     ;print string, ignoring leading $00 bytes
1058: 20 8d 2e                     jsr     JJ_PopFullState   ;restore all regs and ZP
105b: 60                           rts

                   ; 
                   ; Asks the user if they want to restore a saved game.  If the answer is yes,
                   ; this proceeds to do the restore.
                   ; 
105c: 20 54 2e     AskRestoreGame  jsr     InA_GetInlineData
105f: 0a 11                        .dd2    msg_restore_game
1061: 20 36 2e                     jsr     JJ_PrintString    ;ask if they want to restore a game
1064: 20 39 2e                     jsr     JJ_GetInput       ;get line of input
1067: ad 33 2f                     lda     kbd_scratch_buf   ;check first char
106a: c9 59                        cmp     #‘Y’              ;yes?
106c: f0 05                        beq     :DoLoad           ;yes, do it
106e: c9 4e                        cmp     #‘N’              ;no?
1070: d0 ea                        bne     AskRestoreGame    ;none of the above, loop
1072: 60                           rts

1073: 20 1b 2e     :DoLoad         jsr     JJ_AskDiskOrTape  ;ask if they want disk or tape
1076: ad b2 2e                     lda     use_disk_flag     ;check flag
1079: f0 19                        beq     :FromTape1        ;go do tape
107b: 20 54 2e                     jsr     InA_GetInlineData ;get pointer to DOS command string
107e: e3 10                        .dd2    dos_load_cmd
1080: a9 31                        lda     #‘1’              ;set filename for part 1
1082: 8d ef 10                     sta     dos_load_cmd+12
1085: ad 57 30                     lda     adventure_num     ;set adventure number in filename
1088: 8d f0 10                     sta     dos_load_cmd+13   ; (will be a control character)
108b: 20 1e 2e                     jsr     JJ_PrintStringCOUT ;issue DOS command to load file #1
108e: ee ef 10                     inc     dos_load_cmd+12   ;increment digit for part 2
1091: 4c 97 10                     jmp     :CheckPart1

1094: 20 33 11     :FromTape1      jsr     ReadTape          ;read data from tape
                   ; 
1097: 20 93 2e     :CheckPart1     jsr     InA_GetIndirectValue ;get adventure number (12 in our case)
109a: 57 30                        .dd2    adventure_num
109c: 20 7b 2e                     jsr     InA_SubF0F1_Ind   ;subtract value we read from file
109f: 33 2f                        .dd2    kbd_scratch_buf
10a1: f0 0b                        beq     :Part1Good        ;if they match, continue
10a3: 20 54 2e                     jsr     InA_GetInlineData
10a6: f3 10                        .dd2    msg_bad_save
10a8: 20 36 2e                     jsr     JJ_PrintString    ;complain about saved game
10ab: 4c 5c 10                     jmp     AskRestoreGame    ;ask again

                   ; Copy $2f35-2f71 to $30c7-3103 (flags, counters, current room etc.).
10ae: a2 3c        :Part1Good      ldx     #$3c
10b0: bd 35 2f     :Loop           lda     save_game_data,x  ;read from scratch area
10b3: 9d c7 30                     sta     counter_register,x ;write to state area
10b6: ca                           dex
10b7: 10 f7                        bpl     :Loop
                   ; 
10b9: ad b2 2e                     lda     use_disk_flag     ;disk or tape?
10bc: f0 0b                        beq     :FromTape2        ;tape, branch
10be: 20 54 2e                     jsr     InA_GetInlineData
10c1: e3 10                        .dd2    dos_load_cmd
10c3: 20 1e 2e                     jsr     JJ_PrintStringCOUT ;issue DOS command to load file #2
10c6: 4c cc 10                     jmp     :ReadCommon

10c9: 20 33 11     :FromTape2      jsr     ReadTape          ;read part 2 from tape
                   ; Copy item location data from file #2.
                   ]item_room      .var    $f0    {addr/2}

10cc: a0 00        :ReadCommon     ldy     #$00
10ce: a2 ff                        ldx     #$ff              ;init to -1
10d0: 20 93 2e                     jsr     InA_GetIndirectValue
10d3: 26 2f                        .dd2    item_rooms_ptr
10d5: e8           :Loop           inx
10d6: bd 33 2f                     lda     kbd_scratch_buf,x ;copy location value
10d9: 91 f0                        sta     (]item_room),y
10db: c8                           iny
10dc: c8                           iny
10dd: ec 6f 30                     cpx     hdr_max_item      ;all items done?
10e0: d0 f3                        bne     :Loop             ;no, loop
10e2: 60                           rts

                   ; DOS 3.3 load command.  The last two characters are modified by the code.
10e3: 0d 04 42 4c+ dos_load_cmd    .zstr   $0d,$04,‘BLOAD AREC2’,$05,$0d
10f3: 20 42 41 44+ msg_bad_save    .zstr   ‘ BAD SAVE FILE FOUND!’,$0d
                   msg_restore_game
110a: 57 41 4e 54+                 .zstr   ‘WANT TO RESTORE PREVIOUSLY’,$0d,‘ SAVED GAME? ’

                   ; 
                   ; Reads data from tape.  We're expecting 256 bytes.
                   ; 
1133: a9 33        ReadTape        lda     #<kbd_scratch_buf ;set buffer pointer
1135: 85 3c                        sta     MON_A1L
1137: a9 2f                        lda     #>kbd_scratch_buf
1139: 85 3d                        sta     MON_A1H
113b: 20 fd fe                     jsr     MON_READ          ;invoke monitor tape read routine
113e: 60                           rts

113f: 74 68 72 6f+                 .align  $0400 (705 bytes)

                   J_SetIndirectValue
1400: 4c 55 14                     jmp     SetIndirectValue

1403: 4c eb 14     J_PushF0F1      jmp     PushF0F1

1406: 4c f3 14     J_PopF0F1       jmp     PopF0F1

1409: 4c db 14     J_PushF4F5      jmp     PushF4F5

140c: 4c e3 14     J_PopF4F5       jmp     PopF4F5

140f: 4c fb 14     J_PushF2F3      jmp     PushF2F3

1412: 4c 03 15     J_PopF2F3       jmp     PopF2F3

1415: 4c 34 15     J_PushFullState jmp     PushFullState

1418: 4c 69 15     J_PopFullState  jmp     PopFullState

141b: 4c 8e 15     J_IncF0F1       jmp     IncF0F1

141e: 4c 97 15     J_IncF4F5       jmp     IncF4F5

1421: 4c a1 15     J_IncF2F3       jmp     IncF2F3

1424: 4c c5 15     J_DecF0F1       jmp     DecF0F1

1427: 4c bd 15     J_DecF4F5       jmp     DecF4F5

142a: 4c cd 15     J_DecF2F3       jmp     DecF2F3

142d: 4c ea 15     J_SetF2F3_F0F1  jmp     SetF2F3_F0F1

1430: 4c e2 15     J_SetF4F5_F0F1  jmp     SetF4F5_F0F1

1433: 4c 29 16     J_SubF0F1_Ind   jmp     SubF0F1_Ind

                   J_SubF0F1_Inline
1436: 4c 18 16                     jmp     SubF0F1_Inline

1439: 4c 3d 16     J_AddF0F1_F4F5  jmp     AddF0F1_F4F5

143c: 4c 64 16     J_GetInlineData jmp     GetInlineData

                   J_GetIndirectValue
143f: 4c 4f 16                     jmp     GetIndirectValue

1442: 4c 13 15     J_PushF6F7      jmp     PushF6F7

1445: 4c 0b 15     J_PopF6F7       jmp     PopF6F7

1448: 4c 23 15     J_PushF8F9      jmp     PushF8F9

144b: 4c 1b 15     J_PopF8F9       jmp     PopF8F9

144e: 4c 2b 15     J_IncF8F9       jmp     IncF8F9

1451: 30 1a        ind_jmp_1       .dd2    $1a30
1453: d8 18        ind_jmp_2       .dd2    $18d8

                   ; 
                   ; Stores a 16-bit value to a location specified by a pointer in inline data that
                   ; follows the caller's caller.
                   ; 
                   ; On entry:
                   ;   $f0-f1: value to store
                   ; 
                   ; On exit:
                   ;   $fc-fd: pointer from inline data
                   ; 
                   ]arg            .var    $f0    {addr/2}
                   ]dest_ptr       .var    $fc    {addr/2}

                   SetIndirectValue
1455: 20 57 2e                     jsr     JJ_PushRegs
1458: 20 6a 14                     jsr     GetCCInlineValue  ;get pointer in $fc-fd
145b: a0 00                        ldy     #$00
145d: a5 f0                        lda     ]arg
145f: 91 fc                        sta     (]dest_ptr),y     ;write value to pointer
1461: c8                           iny
1462: a5 f1                        lda     ]arg+1
1464: 91 fc                        sta     (]dest_ptr),y
1466: 20 5a 2e                     jsr     JJ_PopRegs
1469: 60                           rts

                   ; 
                   ; Gets the inline data that follows the caller's caller, and modifies the return
                   ; address to skip over it.  The data is usually a pointer, so this is a way to
                   ; load a fixed address into $fc-fd.
                   ; 
                   ; The caller does this:
                   ;   JSR func
                   ;   .dd2 <addr>
                   ; Then func does this:
                   ;   JSR PushRegs (pushes 4 Y/X/A/P on stack)
                   ;   JSR <this function>
                   ; 
                   ; So the stack is:
                   ;   2 byte caller return address
                   ;   4 byte saved registers
                   ;   2 byte caller's caller return address
                   ; 
                   ; So we need to get the caller's caller address from SP +7/+8, and load the
                   ; values we find there.  We then want to modify the caller's caller return
                   ; address to skip over the data.
                   ; 
                   ; On entry:
                   ;   stack as described above
                   ; 
                   ; On exit:
                   ;   $fa-fb hold caller's caller address
                   ;   $fc-fd hold 16-bit inline data value
                   ; 
                   • Clear variables
                   ]caller_ptr     .var    $fa    {addr/2}
                   ]result_ptr     .var    $fc    {addr/2}

                   GetCCInlineValue
146a: ba                           tsx                       ;get stack pointer
146b: bd 07 01                     lda     STACK+7,x         ;get caller's caller address
146e: 85 fa                        sta     ]caller_ptr
1470: bd 08 01                     lda     STACK+8,x
1473: 85 fb                        sta     ]caller_ptr+1
1475: a0 01                        ldy     #$01              ;move past last byte of instruction
1477: b1 fa                        lda     (]caller_ptr),y   ;copy inline data to zero page
1479: 85 fc                        sta     ]result_ptr
147b: c8                           iny
147c: b1 fa                        lda     (]caller_ptr),y
147e: 85 fd                        sta     ]result_ptr+1
1480: bd 07 01                     lda     STACK+7,x         ;modify caller's caller address
1483: 18                           clc
1484: 69 02                        adc     #$02              ;add 2 to skip over inline data
1486: 9d 07 01                     sta     STACK+7,x
1489: bd 08 01                     lda     STACK+8,x
148c: 69 00                        adc     #$00
148e: 9d 08 01                     sta     STACK+8,x
1491: 60                           rts

                   ; 
                   ; Loads a 16-bit value from zero page and pushes it onto the stack.
                   ; 
                   ; On entry:
                   ;   X-reg: index into zero page
                   ;   (caller's previous X-reg value stashed at $14da)
                   ; 
                   ; On exit:
                   ;   value from ZP pushed on stack
                   ;   (all registers preserved)
                   ; 
                   • Clear variables
                   ]saved_areg     .var    $fa    {addr/1}
                   ]saved_preg     .var    $fb    {addr/1}
                   ]jmp_addr       .var    $fc    {addr/2}

1492: 85 fa        Push16Idx       sta     ]saved_areg       ;save A-reg
1494: 68                           pla                       ;pull P-reg we saved earlier
1495: 85 fb                        sta     ]saved_preg       ;save that
1497: 68                           pla                       ;pull return address
1498: 85 fc                        sta     ]jmp_addr
149a: 68                           pla
149b: 85 fd                        sta     ]jmp_addr+1
149d: e6 fc                        inc     ]jmp_addr         ;increment return addr so we jump past JSR
149f: d0 02                        bne     :NoInc
14a1: e6 fd                        inc     ]jmp_addr+1
14a3: ea           :NoInc          nop
14a4: b5 01                        lda     $01,x             ;get 16-bit value from zero page
14a6: 48                           pha                       ; and push on stack
14a7: b5 00                        lda     $00,x
14a9: 48                           pha
14aa: ae da 14                     ldx     tmp_save_x        ;restore X-reg
14ad: a5 fb                        lda     ]saved_preg
14af: 48                           pha
14b0: a5 fa                        lda     ]saved_areg       ;restore A-reg
14b2: 28                           plp                       ;restore P-reg
14b3: 6c fc 00                     jmp     ($00fc)           ;return to caller

                   ; 
                   ; Pulls a 16-bit value from the stack and stores it in zero page.
                   ; 
                   ; On entry:
                   ;   X-reg: index into zero page
                   ;   (caller's previous X-reg value stashed at $14da)
                   ; 
                   ; On exit:
                   ;   value from top of stack written to ZP
                   ;   (all registers preserved)
                   ; 
14b6: 85 fa        Pop16Idx        sta     ]saved_areg       ;save A-reg
14b8: 68                           pla                       ;pull P-reg we saved earlier
14b9: 85 fb                        sta     ]saved_preg       ;save that
14bb: 68                           pla                       ;pull return address
14bc: 85 fc                        sta     ]jmp_addr
14be: 68                           pla
14bf: 85 fd                        sta     ]jmp_addr+1
14c1: e6 fc                        inc     ]jmp_addr         ;increment return addr so we jump past JSR
14c3: d0 02                        bne     :NoInc
14c5: e6 fd                        inc     ]jmp_addr+1
14c7: ea           :NoInc          nop
14c8: 68                           pla                       ;pull 16-bit value from stack and store
14c9: 95 00                        sta     $00,x             ; in zero page
14cb: 68                           pla
14cc: 95 01                        sta     $01,x
14ce: ae da 14                     ldx     tmp_save_x        ;restore X-reg
14d1: a5 fb                        lda     ]saved_preg
14d3: 48                           pha
14d4: a5 fa                        lda     ]saved_areg       ;restore A-reg
14d6: 28                           plp                       ;restore P-reg
14d7: 6c fc 00                     jmp     ($00fc)           ;return to caller

14da: 05           tmp_save_x      .dd1    $05

                   ; 
                   ; Pushes $f4-f5 onto stack.
                   ; 
                   • Clear variables

14db: 08           PushF4F5        php
14dc: 8e da 14                     stx     tmp_save_x
14df: a2 f4                        ldx     #$f4
14e1: d0 af                        bne     Push16Idx         ;(always)

                   ; 
                   ; Pops $f4-f5 off of stack.
                   ; 
14e3: 8e da 14     PopF4F5         stx     tmp_save_x
14e6: 08                           php
14e7: a2 f4                        ldx     #$f4
14e9: d0 cb                        bne     Pop16Idx          ;(always)

                   ; 
                   ; Pushes $f0-f1 onto stack.
                   ; 
14eb: 08           PushF0F1        php                       ;save P-reg
14ec: 8e da 14                     stx     tmp_save_x        ;save X-reg
14ef: a2 f0                        ldx     #$f0
14f1: d0 9f                        bne     Push16Idx         ;(always)

                   ; 
                   ; Pops $f0-f1 off of stack.
                   ; 
14f3: 08           PopF0F1         php
14f4: 8e da 14                     stx     tmp_save_x
14f7: a2 f0                        ldx     #$f0
14f9: d0 bb                        bne     Pop16Idx          ;(always)

                   ; 
                   ; Pushes $f2-f3 onto stack.
                   ; 
14fb: 08           PushF2F3        php
14fc: 8e da 14                     stx     tmp_save_x
14ff: a2 f2                        ldx     #$f2
1501: d0 8f        B_Push16Idx     bne     Push16Idx         ;(always)

                   ; 
                   ; Pops $f2-f3 off of stack.
                   ; 
1503: 08           PopF2F3         php
1504: 8e da 14                     stx     tmp_save_x
1507: a2 f2                        ldx     #$f2
1509: d0 ab        B_Pop16Idx      bne     Pop16Idx          ;(always)

                   ; 
                   ; Pops $f6-f7 off of stack.
                   ; 
150b: 08           PopF6F7         php
150c: 8e da 14                     stx     tmp_save_x
150f: a2 f6                        ldx     #$f6
1511: d0 f6                        bne     B_Pop16Idx        ;(always)

                   ; 
                   ; Pushes $f6-f7 onto stack.
                   ; 
1513: 08           PushF6F7        php
1514: 8e da 14                     stx     tmp_save_x
1517: a2 f6                        ldx     #$f6
1519: d0 e6                        bne     B_Push16Idx       ;(always)

                   ; 
                   ; Pops $f8-f9 off of stack.
                   ; 
151b: 08           PopF8F9         php
151c: 8e da 14                     stx     tmp_save_x
151f: a2 f8                        ldx     #$f8
1521: d0 e6                        bne     B_Pop16Idx        ;(always)

                   ; 
                   ; Pushes $f8-f9 onto stack.
                   ; 
1523: 08           PushF8F9        php
1524: 8e da 14                     stx     tmp_save_x
1527: a2 f8                        ldx     #$f8
1529: d0 d6                        bne     B_Push16Idx       ;(always)

                   ; 
                   ; Increments $f8-f9.  Preserves all registers.
                   ; 
152b: 08           IncF8F9         php
152c: e6 f8                        inc     $f8
152e: d0 65                        bne     PlpReturn
1530: e6 f9                        inc     $f9
1532: 28                           plp
1533: 60                           rts

                   ; 
                   ; Pushes registers and $f0-f9 onto the stack.
                   ; 
                   ; Preserves all registers except parts of P.
                   ; 
1534: 08           PushFullState   php                       ;push P-reg
1535: 8d 51 14                     sta     ind_jmp_1         ;save A-reg
1538: 68                           pla                       ;get P-reg
1539: 8d 52 14                     sta     ind_jmp_1+1       ;save P-reg
153c: 68                           pla                       ;pull return address
153d: 8d 53 14                     sta     ind_jmp_2         ;store it
1540: 68                           pla
1541: 8d 54 14                     sta     ind_jmp_2+1
1544: ad 52 14                     lda     ind_jmp_1+1       ;get P-reg
1547: 48                           pha                       ;push on stack
1548: ad 51 14                     lda     ind_jmp_1         ;restore A-reg
154b: 28                           plp                       ;restore P-reg
                   ; 
154c: 20 57 2e                     jsr     JJ_PushRegs       ;push AXYP
154f: 20 5d 2e                     jsr     JJ_PushF0F1       ;push $f0 through $f9
1552: 20 6f 2e                     jsr     JJ_PushF4F5
1555: 20 75 2e                     jsr     JJ_PushF2F3
1558: 20 96 2e                     jsr     JJ_PushF6F7
155b: 20 9c 2e                     jsr     JJ_PushF8F9
155e: ee 53 14                     inc     ind_jmp_2         ;increment return address past end of JSR
1561: d0 03                        bne     :NoInc
1563: ee 54 14                     inc     ind_jmp_2+1
1566: 6c 53 14     :NoInc          jmp     (ind_jmp_2)       ;jump back to caller

                   ; 
                   ; Pops registers and $f0-f9 from the stack.
                   ; 
1569: 68           PopFullState    pla                       ;pull return address
156a: 8d 51 14                     sta     ind_jmp_1         ;store it
156d: 68                           pla
156e: 8d 52 14                     sta     ind_jmp_1+1
1571: 20 9f 2e                     jsr     JJ_PopF8F9        ;pop $f0 through $f9
1574: 20 99 2e                     jsr     JJ_PopF6F7
1577: 20 78 2e                     jsr     JJ_PopF2F3
157a: 20 72 2e                     jsr     JJ_PopF4F5
157d: 20 60 2e                     jsr     JJ_PopF0F1
1580: 20 5a 2e                     jsr     JJ_PopRegs        ;pop AXYP
1583: ee 51 14                     inc     ind_jmp_1         ;increment return address past end of JSR
1586: d0 03                        bne     :NoInc
1588: ee 52 14                     inc     ind_jmp_1+1
158b: 6c 51 14     :NoInc          jmp     (ind_jmp_1)       ;jump back to caller

158e: 08           IncF0F1         php
158f: e6 f0                        inc     $f0
1591: d0 02                        bne     PlpReturn
1593: e6 f1                        inc     $f1
1595: 28           PlpReturn       plp
1596: 60                           rts

                   ; 
                   ; Increments $f4-f5.  Preserves all registers.
                   ; 
1597: 08           IncF4F5         php
1598: e6 f4                        inc     $f4
159a: d0 f9                        bne     PlpReturn
159c: e6 f5                        inc     $f5
159e: 4c 95 15                     jmp     PlpReturn

                   ; 
                   ; Increments $f2-f3.  Preserves all registers.
                   ; 
15a1: 08           IncF2F3         php
15a2: e6 f2                        inc     $f2
15a4: d0 ef                        bne     PlpReturn
15a6: e6 f3                        inc     $f3
15a8: 4c 95 15                     jmp     PlpReturn

                   ; 
                   ; Decrements a 16-bit zero-page value.
                   ; 
                   ; On entry:
                   ;   X-reg: index into zero page
                   ;   stack holds saved P-reg and A-reg
                   ; 
                   ; On exit:
                   ;   (all registers from original call preserved)
                   ; 
15ab: 38           Dec16Idx        sec
15ac: b5 00                        lda     $00,x
15ae: e9 01                        sbc     #$01
15b0: 95 00                        sta     $00,x
15b2: b5 01                        lda     $01,x
15b4: e9 00                        sbc     #$00
15b6: 95 01                        sta     $01,x
15b8: 68                           pla
15b9: aa                           tax
15ba: 68                           pla
15bb: 28                           plp
15bc: 60                           rts

                   ; 
                   ; Decrements $f4-f5.  Preserves all registers.
                   ; 
15bd: 08           DecF4F5         php
15be: 48                           pha
15bf: 8a                           txa
15c0: 48                           pha
15c1: a2 f4                        ldx     #$f4
15c3: d0 e6                        bne     Dec16Idx

                   ; 
                   ; Decrements $f0-f1.  Preserves all registers.
                   ; 
15c5: 08           DecF0F1         php
15c6: 48                           pha
15c7: 8a                           txa
15c8: 48                           pha
15c9: a2 f0                        ldx     #$f0
15cb: d0 de                        bne     Dec16Idx

                   ; 
                   ; Decrements $f2-f3.  Preserves all registers.
                   ; 
15cd: 08           DecF2F3         php
15ce: 48                           pha
15cf: 8a                           txa
15d0: 48                           pha
15d1: a2 f2                        ldx     #$f2
15d3: d0 d6                        bne     Dec16Idx

                   ; 
                   ; Sets a 16-bit zero-page value.
                   ; 
                   ; On entry:
                   ;   X-reg: index into zero page
                   ;   $f0-f1: value to store
                   ;   stack holds saved P-reg and A-reg
                   ; 
                   ; On exit:
                   ;   (all registers from original call preserved)
                   ; 
                   ]value          .var    $f0    {addr/2}

15d5: a5 f0        Set16Idx        lda     ]value            ;set ZP value
15d7: 95 00                        sta     $00,x
15d9: a5 f1                        lda     ]value+1
15db: 95 01                        sta     $01,x
15dd: 68                           pla
15de: aa                           tax
15df: 68                           pla
15e0: 28                           plp
15e1: 60                           rts

                   ; 
                   ; Sets $f4-f5 to the value in $f0-f1.  Preserves all registers.
                   ; 
15e2: 08           SetF4F5_F0F1    php
15e3: 48                           pha
15e4: 8a                           txa
15e5: 48                           pha
15e6: a2 f4                        ldx     #$f4
15e8: d0 eb                        bne     Set16Idx

                   ; 
                   ; Sets $f2-f3 to the value in $f0-f1.  Preserves all registers.
                   ; 
15ea: 08           SetF2F3_F0F1    php
15eb: 48                           pha
15ec: 8a                           txa
15ed: 48                           pha
15ee: a2 f2                        ldx     #$f2
15f0: d0 e3                        bne     Set16Idx

                   ; 
                   ; Computes (value1 - value2) and stores the result in value2.  Sets Z/C flags
                   ; based on result.
                   ; 
                   ; On entry:
                   ;   $f0-f1: value1
                   ;   $fa-fb: value2
                   ;   (preserved registers on stack)
                   ; 
                   ; On exit:
                   ;   $fa-fb: result
                   ;   (all registers preserved except P)
                   ;   Z-flag set if result is zero
                   ;   C-flag set if <= 0 or >= 256
                   ;   N-flag set if result < 0
                   ; 
                   ]value1         .var    $f0    {addr/2}
                   ]value2         .var    $fa    {addr/2}
                   ]saved_areg     .var    $fc    {addr/1}

15f2: 20 5a 2e     DoSubtract      jsr     JJ_PopRegs        ;restore all registers
15f5: 85 fc                        sta     ]saved_areg       ;save A-reg
15f7: 38                           sec                       ;perform 16-bit subtraction
15f8: a5 f0                        lda     ]value1
15fa: e5 fa                        sbc     ]value2
15fc: 85 fa                        sta     ]value2
15fe: a5 f1                        lda     ]value1+1
1600: e5 fb                        sbc     ]value2+1
1602: 08                           php                       ;save flags
1603: d0 09                        bne     :Return           ;result was nonzero, bail (C=?, N=?, Z=0)
1605: 05 fa                        ora     ]value2           ;check low byte
1607: d0 09                        bne     :HighZero         ;nonzero, branch
                   ; Result zero.
1609: 68                           pla                       ;pull saved P-reg
160a: 38                           sec                       ;set carry (no borrow)
160b: a9 00                        lda     #$00              ;set Z-flag, clear N flag
160d: 08           :PushReturn     php                       ;save registers
160e: a5 fc        :Return         lda     ]saved_areg       ;restore A-reg
1610: 28                           plp                       ;restore flags
1611: 60                           rts

1612: 68           :HighZero       pla                       ;pull saved P-reg
1613: 18                           clc                       ;clear carry (borrow)
1614: a9 01                        lda     #$01              ;clear Z-flag and N-flag
1616: d0 f5                        bne     :PushReturn       ;bail (C=0, N=0, Z=0)

                   ; 
                   ; Takes the value in $f0-f1 and subtracts the inline data value, storing the
                   ; result in $fa-fb.
                   ; 
                   ; (all registers preserved except P-reg; N/C/Z set)
                   ; 
                   ]inline_val     .var    $fc    {addr/2}

1618: 20 57 2e     SubF0F1_Inline  jsr     JJ_PushRegs       ;preserve registers
161b: 20 6a 14                     jsr     GetCCInlineValue  ;get inline value in $fc-fd
161e: a5 fc                        lda     ]inline_val       ;copy value from $fc-fd to $fa-fb
1620: 85 fa                        sta     ]value2
1622: a5 fd                        lda     ]inline_val+1
1624: 85 fb                        sta     ]value2+1
1626: 4c f2 15                     jmp     DoSubtract        ;perform subtraction

                   ; 
                   ; Takes the value in $f0-f1 and subtracts the value pointed to by the inline
                   ; pointer.  Stores the result in $fa-fb.
                   ; 
                   ; (all registers preserved except P-reg; N/C/Z set)
                   ; 
1629: 20 57 2e     SubF0F1_Ind     jsr     JJ_PushRegs       ;preserve registers
162c: 20 6a 14                     jsr     GetCCInlineValue  ;get inline value in $fc-fd
162f: a0 00                        ldy     #$00
1631: b1 fc                        lda     (]inline_val),y   ;get value pointed to by inline pointer
1633: 85 fa                        sta     ]value2
1635: c8                           iny
1636: b1 fc                        lda     (]inline_val),y
1638: 85 fb                        sta     ]value2+1
163a: 4c f2 15                     jmp     DoSubtract        ;perform subtraction

                   ; 
                   ; Adds the value in $f0-f1 to the value in $f4-f5, and stores the result in $f0-
                   ; f1.
                   ; 
                   ]value2         .var    $f4    {addr/2}

163d: 08           AddF0F1_F4F5    php                       ;save flags
163e: 48                           pha                       ;save A-reg
163f: a5 f4                        lda     ]value2           ;add values
1641: 18                           clc
1642: 65 f0                        adc     ]value1
1644: 85 f0                        sta     ]value1
1646: a5 f5                        lda     ]value2+1
1648: 65 f1                        adc     ]value1+1
164a: 85 f1                        sta     ]value1+1
164c: 68                           pla                       ;restore A-reg
164d: 28                           plp                       ;restore flags
164e: 60                           rts

                   ; 
                   ; Gets the value pointed to by an inline pointer.
                   ; 
                   ; On exit:
                   ;   $f0-f1: return value, from pointed-to location
                   ;   $fc-fd: pointer extracted from inline data
                   ; 
                   ]ret_val        .var    $f0    {addr/2}
                   ]ind_ptr        .var    $fc    {addr/2}

                   GetIndirectValue
164f: 20 57 2e                     jsr     JJ_PushRegs
1652: 20 6a 14                     jsr     GetCCInlineValue
1655: a0 00                        ldy     #$00
1657: b1 fc                        lda     (]ind_ptr),y
1659: 85 f0                        sta     ]ret_val
165b: c8                           iny
165c: b1 fc                        lda     (]ind_ptr),y
165e: 85 f1                        sta     ]ret_val+1
1660: 20 5a 2e     :PullReturn     jsr     JJ_PopRegs
1663: 60                           rts

                   ; 
                   ; Extracts the 16-bit inline value from the caller's caller.  This is usually a
                   ; pointer, but sometimes it's a constant.
                   ; 
                   ; On exit:
                   ;   $f0-f1: inline data value
                   ; 
                   ]ret_val        .var    $f0    {addr/2}
                   ]inline_val     .var    $fc    {addr/2}

1664: 20 57 2e     GetInlineData   jsr     JJ_PushRegs       ;save registers
1667: 20 6a 14                     jsr     GetCCInlineValue  ;get value
166a: a5 fc                        lda     ]inline_val       ;copy value to $f0-f1
166c: 85 f0                        sta     ]ret_val
166e: a5 fd                        lda     ]inline_val+1
1670: 85 f1                        sta     ]ret_val+1
1672: 4c 60 16                     jmp     :PullReturn

1675: 79 3f 22 1e+                 .junk   139

1700: 4c d5 18     J_DescribeRoom  jmp     DescribeRoom

1703: 4c 1a 18     J_ShowInventory jmp     ShowInventory

1706: 4c 9b 1a     J_GetActionArg  jmp     GetActionArg

1709: 4c 06 1b     J_SaveGame      jmp     SaveGame

170c: 4c           J_CondHandlers  .dd1    $4c               ;not used as a jump
170d: 18 17                        .dd2    cond_handlers

170f: 4c d8 1b     J_AskDiskOrTape jmp     AskDiskOrTape

                   J_PrintStringCOUT
1712: 4c f5 1a                     jmp     PrintStringCOUT

1715: 4c 9d 18     J_PrintItemName jmp     PrintItemName

                   ; 
                   ; Condition handlers.  These functions are called to perform a logic test.  For
                   ; all handlers:
                   ; 
                   ; On entry (see call at $208f):
                   ;   A-reg: room number for item [arg] (even if arg is not item#)
                   ;   X-reg: $ff
                   ;   Y-reg: $00
                   ;   $f0-f1: pointer to global that holds current room number
                   ;   $f2-f3: condition argument
                   ; 
                   ; On exit:
                   ;   X-reg: result ($00 or $ff)
                   ; 
1718: 40 17        cond_handlers   .dd2    C00_NoOp          ;$00 (no-op)
171a: 6b 17                        .dd2    C01_Carried       ;$01 carried
171c: 7f 17                        .dd2    C02_Here          ;$02 here
171e: 8c 17                        .dd2    C03_Accessible    ;$03 accessible
1720: 9a 17                        .dd2    C04_At            ;$04 at
1722: b1 17                        .dd2    C05_NotHere       ;$05 !here
1724: c5 17                        .dd2    C06_NotCarried    ;$06 !carried
1726: e0 17                        .dd2    C07_NotAt         ;$07 !at
1728: fd 17                        .dd2    C08_Flag          ;$08 flag
172a: 04 18                        .dd2    C09_NotFlag       ;$09 !flag
172c: 41 17                        .dd2    C0A_Loaded        ;$0a loaded
172e: 45 17                        .dd2    C0B_NotLoaded     ;$0b !loaded
1730: 71 17                        .dd2    C0C_NotAccessible ;$0c !accessible
1732: 86 17                        .dd2    C0D_Exists        ;$0d exists
1734: 95 17                        .dd2    C0E_NotExists     ;$0e !exists
1736: a1 17                        .dd2    C0F_CounterLE     ;$0f counter_le
1738: b6 17                        .dd2    C10_CounterGT     ;$10 counter_ge
173a: ca 17                        .dd2    C11_NotMoved      ;$11 !moved
173c: e7 17                        .dd2    C12_Moved         ;$12 moved
173e: 0d 18                        .dd2    C13_CounterEq     ;$13 counter_eq

                   ; 
                   ; Condition $00: no-op.
                   ; 
                   • Clear variables
                   ]cur_room_ptr   .var    $f0    {addr/2}
                   ]cond_arg       .var    $f2    {addr/2}
                   ]tmp            .var    $f4    {addr/1}

1740: 60           C00_NoOp        rts

                   ; 
                   ; Condition $0a: true if at least one item is in player's inventory.
                   ; 
1741: a2 ff        C0A_Loaded      ldx     #$ff              ;return true if inventory item found
1743: d0 02                        bne     CheckLoaded       ;(always)

                   ; 
                   ; Condition $0b: true if no items are in player's inventory.
                   ; 
1745: a2 00        C0B_NotLoaded   ldx     #$00              ;return false if inventory item found
1747: 20 93 2e     CheckLoaded     jsr     InA_GetIndirectValue ;get pointer to item location data
174a: 26 2f                        .dd2    item_rooms_ptr
174c: ac 6f 30                     ldy     hdr_max_item      ;count down from max item number
174f: 86 f4                        stx     ]tmp              ;save default return value
1751: a2 00                        ldx     #$00
1753: a1 f0        :Loop           lda     (]cur_room_ptr,x) ;get item's room #
1755: c9 ff                        cmp     #ITEM_HELD        ;in inventory?
1757: d0 03                        bne     :NonInv           ;no, branch
1759: a6 f4                        ldx     ]tmp              ;restore default return value
175b: 60                           rts

175c: 20 51 2e     :NonInv         jsr     JJ_IncF0F1        ;advance pointer
175f: 20 51 2e                     jsr     JJ_IncF0F1
1762: 88                           dey                       ;are we done?
1763: 10 ee                        bpl     :Loop             ;no, branch
1765: a5 f4                        lda     ]tmp              ;didn't find an inventory item, so
1767: 49 ff                        eor     #$ff              ; invert result
1769: aa                           tax                       ;put result in X-reg
176a: 60           :Return         rts

                   ; 
                   ; Condition $01: true if specified item is in player's inventory.
                   ; 
176b: c9 ff        C01_Carried     cmp     #$ff              ;(room # in A-reg) - in player inventory?
176d: f0 fb                        beq     :Return           ;yes, return true
176f: d0 12                        bne     ReturnXZero       ;no, return false

                   ; 
                   ; Condition $0c: true if item is NOT carried and NOT in current room.
                   ; 
                   C0C_NotAccessible
1771: a2 00                        ldx     #$00              ;set default return value to false
1773: c9 ff                        cmp     #ITEM_HELD        ;(room # in A-reg) - in player inventory?
1775: f0 f3                        beq     :Return           ;yes, accessible, return false
1777: d1 f0                        cmp     (]cur_room_ptr),y ;(ptr to current room in $f0-f1) in current room?
1779: f0 ef                        beq     :Return           ;yes, accessible, return false
177b: a2 ff                        ldx     #$ff              ;set return value to true
177d: d0 eb                        bne     :Return           ;(always)

                   ; 
                   ; Condition $02: true if item is in current room.
                   ; 
177f: d1 f0        C02_Here        cmp     (]cur_room_ptr),y ;(room # in A-reg, ptr to cur room in $f0-f1)
1781: f0 e7                        beq     :Return           ;if item is in current room, return default result
1783: a2 00        ReturnXZero     ldx     #$00              ;not in current room, return false
1785: 60                           rts

                   ; 
                   ; Condition $0d: return true if item is NOT in room zero ("nowhere").
                   ; 
1786: c9 00        C0D_Exists      cmp     #$00              ;(room # in A-reg) - in room zero?
1788: d0 e0                        bne     :Return           ;no, return true
178a: f0 f7                        beq     ReturnXZero       ;yes, return false

                   ; 
                   ; Condition $03: return true if item is carried OR is in current room.
                   ; 
178c: d1 f0        C03_Accessible  cmp     (]cur_room_ptr),y ;(room # in A-reg, ptr to cur room in $f0-f1)
178e: f0 da                        beq     :Return           ;if item is in current room, return default result
1790: c9 ff                        cmp     #ITEM_HELD        ;in inventory?
1792: d0 ef                        bne     ReturnXZero       ;no, return false
1794: 60                           rts

                   ; 
                   ; Condition $0e: true if item is in room zero ("nowhere").
                   ; 
1795: c9 00        C0E_NotExists   cmp     #$00              ;(room # in A-reg) - in room zero?
1797: d0 ea                        bne     ReturnXZero       ;no, return false
1799: 60                           rts

                   ; 
                   ; Condition $04: true if arg matches current room.
                   ; 
179a: a5 f2        C04_At          lda     ]cond_arg         ;get argument
179c: d1 f0                        cmp     (]cur_room_ptr),y ;compare to current room number
179e: d0 e3                        bne     ReturnXZero       ;didn't match, return false
17a0: 60           :Return         rts

                   ; 
                   ; Condition $0f: true if current counter value is <= arg.
                   ; 
17a1: 20 93 2e     C0F_CounterLE   jsr     InA_GetIndirectValue ;get pointer to "current counter"
17a4: c7 30                        .dd2    counter_register
17a6: 20 7b 2e                     jsr     InA_SubF0F1_Ind   ;subtract argument in $f2-f3
17a9: f2 00                        .dd2    $00f2             ; (in a slightly awkward way)
17ab: f0 f3                        beq     :Return           ;if arg is equal, return true
17ad: 30 f1                        bmi     :Return           ;if arg is smaller, return true
17af: d0 d2        BneRetXZero     bne     ReturnXZero       ;return false

                   ; 
                   ; Condition $05: true if item is NOT in current room.
                   ; 
17b1: d1 f0        C05_NotHere     cmp     (]cur_room_ptr),y ;(room # in A-reg, ptr to cur room in $f0-f1)
17b3: f0 ce                        beq     ReturnXZero       ;if item in current room, branch to return false
17b5: 60                           rts

                   ; 
                   ; Condition $10: true if current counter value is > arg.
                   ; 
17b6: 20 93 2e     C10_CounterGT   jsr     InA_GetIndirectValue ;get pointer to "current counter"
17b9: c7 30                        .dd2    counter_register
17bb: 20 7b 2e                     jsr     InA_SubF0F1_Ind   ;subtract argument in $f2-f3
17be: f2 00                        .dd2    $00f2             ; (in a slightly awkward way)
17c0: f0 c1                        beq     ReturnXZero       ;if arg is equal, return false
17c2: 30 bf                        bmi     ReturnXZero       ;if arg is smaller, return false
17c4: 60                           rts

                   ; 
                   ; Condition $06: true if player is NOT carrying item.
                   ; 
17c5: c9 ff        C06_NotCarried  cmp     #ITEM_HELD        ;(room # in A-reg) - item carried?
17c7: f0 ba                        beq     ReturnXZero       ;yes, return false
17c9: 60                           rts

                   ; 
                   ; Condition $11: true if item is in its original location.
                   ; 
17ca: 20 75 2e     C11_NotMoved    jsr     JJ_PushF2F3       ;copy cond arg in $f2-f3...
17cd: 20 72 2e                     jsr     JJ_PopF4F5        ;...to $f4-f5
17d0: 20 93 2e                     jsr     InA_GetIndirectValue ;get pointer to initial room data
17d3: 2a 2f                        .dd2    item_initroom_ptr
17d5: 20 87 2e                     jsr     JJ_AddF0F1_F4F5   ;double arg to convert index to offset
17d8: 20 87 2e                     jsr     JJ_AddF0F1_F4F5
17db: d1 f0                        cmp     (]cur_room_ptr),y ;(room # in A-reg) - compare to initial room #
17dd: d0 a4                        bne     ReturnXZero       ;not the same, branch to return false
17df: 60                           rts

                   ; 
                   ; Condition $07: true if player is NOT in the specified room.
                   ; 
17e0: a5 f2        C07_NotAt       lda     ]cond_arg         ;get argument
17e2: d1 f0                        cmp     (]cur_room_ptr),y ;compare to current room number
17e4: f0 9d                        beq     ReturnXZero       ;if they match, return false
17e6: 60                           rts

                   ; 
                   ; Condition $12: true if item is NOT in its original location.
                   ; 
17e7: 20 75 2e     C12_Moved       jsr     JJ_PushF2F3       ;copy cond arg in $f2-f3...
17ea: 20 72 2e                     jsr     JJ_PopF4F5        ;...to $f4-f5
17ed: 20 93 2e                     jsr     InA_GetIndirectValue ;get pointer to initial room data
17f0: 2a 2f                        .dd2    item_initroom_ptr
17f2: 20 87 2e                     jsr     JJ_AddF0F1_F4F5   ;double arg to convert index to offset
17f5: 20 87 2e                     jsr     JJ_AddF0F1_F4F5
17f8: d1 f0                        cmp     (]cur_room_ptr),y ;(room # in A-reg) - compare to initial room #
17fa: f0 87                        beq     ReturnXZero       ;same, branch to return false
17fc: 60                           rts

                   ; 
                   ; Condition $08: true if specified flag is true.
                   ; 
17fd: a4 f2        C08_Flag        ldy     ]cond_arg         ;use argument as index
17ff: b9 c9 30                     lda     action_flags,y    ;get flag
1802: aa                           tax                       ;return value in X-reg
1803: 60                           rts

                   ; 
                   ; Condition $09: true if the specified flag is NOT true.
                   ; 
1804: a4 f2        C09_NotFlag     ldy     ]cond_arg         ;use argument as index
1806: b9 c9 30                     lda     action_flags,y    ;get flag
1809: 49 ff                        eor     #$ff              ;flip it
180b: aa                           tax                       ;return value in X-reg
180c: 60                           rts

                   ; 
                   ; Condition $13: true if current counter value is equal to arg.
                   ; 
180d: 20 93 2e     C13_CounterEq   jsr     InA_GetIndirectValue ;get pointer to "current counter"
1810: c7 30                        .dd2    counter_register
1812: 20 7b 2e                     jsr     InA_SubF0F1_Ind   ;subtract argument in $f2-f3
1815: f2 00                        .dd2    $00f2             ; (in a slightly awkward way)
1817: d0 96                        bne     BneRetXZero       ;if not equal, branch to return false
1819: 60                           rts

                   ; 
                   ; Prints a list of items in the player's inventory.
                   ; 
                   ]name_ptrs      .var    $f0    {addr/2}
                   ]item_room_data .var    $f2    {addr/2}

181a: 20 8a 2e     ShowInventory   jsr     JJ_PushFullState  ;push registers and ZP data
181d: 20 33 2e                     jsr     JJ_PrintCR        ;move to start of new line
1820: 20 54 2e                     jsr     InA_GetInlineData
1823: 6f 18                        .dd2    msg_im_carrying
1825: 20 36 2e                     jsr     JJ_PrintString    ;print "I'm carrying"
1828: ac 6f 30                     ldy     hdr_max_item      ;going to loop through all items
182b: c8                           iny                       ;+1 to make it a count
182c: a9 00                        lda     #$00
182e: 8d 33 30                     sta     thing_found_flag  ;init "have something" flag
1831: 20 93 2e                     jsr     InA_GetIndirectValue ;get pointer to item room data
1834: 26 2f                        .dd2    item_rooms_ptr
1836: 20 81 2e                     jsr     JJ_SetF2F3_F0F1   ;copy pointer to $f2-f3
1839: 20 93 2e                     jsr     InA_GetIndirectValue ;get pointer to item name pointers
183c: 28 2f                        .dd2    item_names_ptr
                   ; 
183e: a2 00        :Loop           ldx     #$00
1840: a1 f2                        lda     (]item_room_data,x) ;get room number
1842: c9 ff                        cmp     #ITEM_HELD        ;in inventory?
1844: d0 06                        bne     :NotHeld          ;no, branch
1846: 8d 33 30                     sta     thing_found_flag  ;set "have something" flag to True
1849: 20 12 2e                     jsr     JJ_PrintItemName  ;print name of item
184c: 20 6c 2e     :NotHeld        jsr     JJ_IncF2F3        ;advance item name pointer
184f: 20 6c 2e                     jsr     JJ_IncF2F3
1852: 20 51 2e                     jsr     JJ_IncF0F1        ;advance item room data pointer
1855: 20 51 2e                     jsr     JJ_IncF0F1
1858: 88                           dey                       ;done yet?
1859: d0 e3                        bne     :Loop             ;no, branch
                   ; 
185b: ad 33 30                     lda     thing_found_flag  ;did we find anything?
185e: d0 08                        bne     :FoundSome        ;yes, branch
1860: 20 54 2e                     jsr     InA_GetInlineData
1863: 8d 18                        .dd2    msg_nothing_ata
1865: 20 36 2e                     jsr     JJ_PrintString    ;print "nothing at all"
1868: 20 33 2e     :FoundSome      jsr     JJ_PrintCR        ;finish with a newline
186b: 20 8d 2e                     jsr     JJ_PopFullState   ;restore registers and ZP data
186e: 60                           rts

186f: 0d 49 27 4d+ msg_im_carrying .zstr   $0d,‘I'M CARRYING THE FOLLOWING:’,$0d
188d: 20 4e 4f 54+ msg_nothing_ata .zstr   ‘ NOTHING AT ALL’

                   ; 
                   ; Prints an item name string.  Used for the "inventory" command and when drawing
                   ; the room description.
                   ; 
                   ; Names of get/drop items end with "/WORD/", which we want to ignore here.
                   ; 
                   ; On entry:
                   ;   $f0-f1: pointer to pointer to string
                   ; 
                   ]ptr            .var    $f0    {addr/2}

189d: 20 57 2e     PrintItemName   jsr     JJ_PushRegs       ;preserve registers
18a0: 20 5d 2e                     jsr     JJ_PushF0F1       ;preserve $f0-f1
18a3: a0 00                        ldy     #$00
18a5: b1 f0                        lda     (]ptr),y          ;get pointer low byte
18a7: 48                           pha                       ;stash it
18a8: c8                           iny
18a9: b1 f0                        lda     (]ptr),y          ;get pointer high byte
18ab: 85 f1                        sta     ]ptr+1            ;store in ZP
18ad: 68                           pla                       ;restore low byte
18ae: 85 f0                        sta     ]ptr              ;store that
18b0: 88                           dey                       ;set Y-reg=0
18b1: b1 f0                        lda     (]ptr),y          ;get first byte of string, which holds the length
18b3: aa                           tax                       ;copy to X-reg
18b4: 20 51 2e                     jsr     JJ_IncF0F1        ;advance pointer past the length byte
18b7: b1 f0        :Loop           lda     (]ptr),y          ;get char
18b9: c9 2f                        cmp     #‘/’              ;did we find a get/drop suffix?
18bb: f0 07                        beq     :StrEnd           ;yes, branch
18bd: 20 30 2e                     jsr     JJ_PrintNonNull   ;no, print char
18c0: c8                           iny                       ;advance to next char
18c1: ca                           dex                       ;done yet?
18c2: d0 f3                        bne     :Loop             ;no, loop
                   ; 
18c4: a9 2e        :StrEnd         lda     #‘.’              ;separate items with ". "
18c6: 20 30 2e                     jsr     JJ_PrintNonNull
18c9: a9 20                        lda     #‘ ’
18cb: 20 30 2e                     jsr     JJ_PrintNonNull
18ce: 20 60 2e                     jsr     JJ_PopF0F1        ;restore $f0-f1
18d1: 20 5a 2e                     jsr     JJ_PopRegs        ;restore registers
18d4: 60                           rts

                   ; 
                   ; Prints the room description at the top of the screen.  This includes the room
                   ; text, a list of all objects present, and a list of all "standard" exits.
                   ; 
18d5: 20 8a 2e     DescribeRoom    jsr     JJ_PushFullState  ;preserve regs and ZP
                   ; Start by clearing all the lines in the area above the scroll window.
18d8: a6 22                        ldx     MON_WNDTOP        ;get current top of screen
18da: f0 1c                        beq     :AtTop            ;empty window, branch
18dc: a9 00                        lda     #$00
18de: 85 25                        sta     MON_CV            ;start at top of screen
18e0: a5 25        :Loop           lda     MON_CV            ;get line number
18e2: 20 c1 fb                     jsr     MON_BASCALC       ;set BASL/BASH
18e5: a0 00                        ldy     #$00              ;start from column 0
18e7: 20 9e fc                     jsr     MON_CLREOLZ       ;clear to end of line
18ea: e6 25                        inc     MON_CV            ;move to next line
18ec: ca                           dex                       ;done yet?
18ed: d0 f1                        bne     :Loop             ;no, loop
                   ; 
18ef: a9 00                        lda     #$00
18f1: 85 22                        sta     MON_WNDTOP        ;reset scroll window top
18f3: 85 25                        sta     MON_CV            ;position at top line
18f5: 20 c1 fb                     jsr     MON_BASCALC       ;recalc BASL/BASH
18f8: ad d8 30     :AtTop          lda     darkness_flag     ;is the room dark?
18fb: f0 1d                        beq     :NotDark          ;no, branch
18fd: 20 93 2e                     jsr     InA_GetIndirectValue ;get pointer to item location data
1900: 26 2f                        .dd2    item_rooms_ptr
1902: a0 12                        ldy     #18               ;item #9 (lightsource)
1904: b1 f0                        lda     (]ptr),y          ;check current location
1906: c9 ff                        cmp     #ITEM_HELD        ;in inventory?
1908: f0 10                        beq     :NotDark          ;yes, not dark (must swap item when light expires)
190a: cd e9 30                     cmp     current_room      ;is lightsource in current room?
190d: f0 0b                        beq     :NotDark          ;yes, not dark
190f: 20 54 2e                     jsr     InA_GetInlineData ;complain about darkness
1912: 31 1a                        .dd2    msg_too_dark
1914: 20 4b 2e                     jsr     JJ_PrintFlashing
1917: 4c 09 1a                     jmp     :FinishDescr      ;nothing else to say, finish up

                   ]room_text      .var    $f2    {addr/2}

191a: 20 93 2e     :NotDark        jsr     InA_GetIndirectValue ;get pointer to room descr table in $f0-f1
191d: 16 2f                        .dd2    room_descrs_ptr
191f: ad e9 30                     lda     current_room      ;get current room number
1922: 18                           clc
1923: 6d e9 30                     adc     current_room      ;double it
1926: a8                           tay
1927: b1 f0                        lda     (]ptr),y          ;get ptr to text for the room (low byte)
1929: 85 f2                        sta     ]room_text
192b: c8                           iny
192c: b1 f0                        lda     (]ptr),y          ;repeat for high byte
192e: 85 f3                        sta     ]room_text+1
                   ; 
1930: a0 00                        ldy     #$00
1932: b1 f2                        lda     (]room_text),y    ;get string length
1934: aa                           tax                       ;hold in X-reg
1935: 20 6c 2e                     jsr     JJ_IncF2F3        ;advance pointer
1938: b1 f2                        lda     (]room_text),y    ;get first char
193a: c9 2a                        cmp     #‘*’              ;does it start with a '*'?
193c: d0 06                        bne     :PrintPfx         ;no, show standard "I'm in a" prefix
193e: ca                           dex                       ;yes, decrement string length
193f: 20 6c 2e                     jsr     JJ_IncF2F3        ;advance pointer (preserves flags)
1942: d0 08                        bne     :RoomCont         ;(branch always, assuming text follows '*')
1944: 20 54 2e     :PrintPfx       jsr     InA_GetInlineData
1947: 47 1a                        .dd2    msg_im_in_a
1949: 20 36 2e                     jsr     JJ_PrintString    ;print "I'm in a"
                   ; 
194c: 20 75 2e     :RoomCont       jsr     JJ_PushF2F3       ;copy room text string pointer from $f2-f3...
194f: 20 60 2e                     jsr     JJ_PopF0F1        ;...to $f0-f1
1952: 8a                           txa                       ;copy string length back to A-reg
1953: 20 3f 2e                     jsr     JJ_PrintNChars    ;print room description string
                   ; Now print a list of items found here.
                   ]item_room_ptr  .var    $f2    {addr/2}

1956: a0 00                        ldy     #$00
1958: 98                           tya
1959: 8d 33 30                     sta     thing_found_flag  ;clear the "thing found" flag (could STY?)
195c: ae 6f 30                     ldx     hdr_max_item      ;get max item #
195f: e8                           inx                       ;increment it to make it a count
1960: 20 93 2e                     jsr     InA_GetIndirectValue ;get pointer to item location data
1963: 26 2f                        .dd2    item_rooms_ptr
1965: 20 81 2e                     jsr     JJ_SetF2F3_F0F1   ;copy pointer to $f2-f3
1968: 20 93 2e                     jsr     InA_GetIndirectValue ;get pointer to item name table
196b: 28 2f                        .dd2    item_names_ptr
196d: ad e9 30     :ItemLoop       lda     current_room      ;get player's room #
1970: d1 f2                        cmp     (]item_room_ptr),y ;is the item in this room?
1972: d0 1b                        bne     :NotHere          ;no, branch
1974: ad 33 30                     lda     thing_found_flag  ;check "thing found" flag
1977: d0 0e                        bne     :NotFirst         ;not first item, branch
1979: 20 5d 2e                     jsr     JJ_PushF0F1       ;preserve $f0-f1
197c: 20 54 2e                     jsr     InA_GetInlineData
197f: 75 1a                        .dd2    msg_vis_items
1981: 20 36 2e                     jsr     JJ_PrintString    ;print "visible items:"
1984: 20 60 2e                     jsr     JJ_PopF0F1        ;restore $f0-f1
1987: 20 12 2e     :NotFirst       jsr     JJ_PrintItemName  ;print the item's name
198a: a9 01                        lda     #$01
198c: 8d 33 30                     sta     thing_found_flag  ;set the "thing found" flag
198f: 20 51 2e     :NotHere        jsr     JJ_IncF0F1        ;advance pointer to item descriptions
1992: 20 51 2e                     jsr     JJ_IncF0F1
1995: 20 6c 2e                     jsr     JJ_IncF2F3        ;advance pointer to item room data
1998: 20 6c 2e                     jsr     JJ_IncF2F3
199b: ca                           dex                       ;have we examined all items?
199c: d0 cf                        bne     :ItemLoop         ;not yet, branch
199e: 20 33 2e                     jsr     JJ_PrintCR        ;finish with a carriage return
                   ; Print visible exits.  For each of the 6 directions (NSEWUD), find the entry in
                   ; the appropriate table for the current room.  If the room # there is nonzero,
                   ; show that direction in the list.
                   ]dir_name_ptr   .var    $f2    {addr/2}
                   ]vis_exit_tab   .var    $f4    {addr/2}

19a1: a9 00                        lda     #$00
19a3: 8d 33 30                     sta     thing_found_flag  ;clear "thing found" flag
19a6: a2 06                        ldx     #$06              ;six directions
19a8: 20 54 2e                     jsr     InA_GetInlineData ;get pointer to exit name strings
19ab: 51 1a                        .dd2    msg_exit_name
19ad: 20 81 2e                     jsr     JJ_SetF2F3_F0F1   ;copy pointer to $f2-f3
19b0: 20 54 2e                     jsr     InA_GetInlineData ;get pointer to room exit table pointers
19b3: 18 2f                        .dd2    vis_exits_n_ptr
19b5: 20 84 2e                     jsr     JJ_SetF4F5_F0F1   ;copy pointer to $f4-f5
19b8: a0 00        :ExitsLoop      ldy     #$00
19ba: b1 f4                        lda     (]vis_exit_tab),y ;get pointer to table for this direction
19bc: 85 f0                        sta     ]ptr              ;store in ZP
19be: c8                           iny
19bf: b1 f4                        lda     (]vis_exit_tab),y ;repeat for high byte
19c1: 85 f1                        sta     ]ptr+1
19c3: ad e9 30                     lda     current_room      ;get current room number
19c6: 18                           clc
19c7: 6d e9 30                     adc     current_room      ;double it
19ca: a8                           tay                       ;move to Y-reg for use as index
19cb: b1 f0                        lda     (]ptr),y          ;get exit for this room in this direction
19cd: f0 1b                        beq     :NotThisDir       ;if zero, we can't go that way
                   ; 
19cf: ad 33 30                     lda     thing_found_flag  ;did we already find something?
19d2: d0 0d                        bne     :NotFirst         ;yes, skip this
19d4: 20 54 2e                     jsr     InA_GetInlineData
19d7: 88 1a                        .dd2    msg_some_exits
19d9: 20 36 2e                     jsr     JJ_PrintString    ;print "some exits are"
19dc: a9 01                        lda     #$01
19de: 8d 33 30                     sta     thing_found_flag  ;set "thing found" flag
19e1: 20 75 2e     :NotFirst       jsr     JJ_PushF2F3       ;copy pointer to direction string from $f2-f3...
19e4: 20 60 2e                     jsr     JJ_PopF0F1        ;...to $f0-f1
19e7: 20 36 2e                     jsr     JJ_PrintString    ;print direction string
                   ; 
19ea: 20 66 2e     :NotThisDir     jsr     JJ_IncF4F5        ;advance to next direction table
19ed: 20 66 2e                     jsr     JJ_IncF4F5
19f0: a0 00        :NxtDirStrLp    ldy     #$00              ;move to next direction string
19f2: b1 f2                        lda     (]dir_name_ptr),y ; by walking through the strings to find a $00
19f4: f0 05                        beq     :FoundZ           ;found it, branch
19f6: 20 6c 2e                     jsr     JJ_IncF2F3        ;advance pointer (preserves flags)
19f9: d0 f5                        bne     :NxtDirStrLp      ;(always)

19fb: 20 6c 2e     :FoundZ         jsr     JJ_IncF2F3        ;advance pointer past the $00 byte
19fe: ca                           dex                       ;done yet?
19ff: d0 b7                        bne     :ExitsLoop        ;no, keep going
1a01: ad 33 30                     lda     thing_found_flag  ;did we print any exits?
1a04: f0 03                        beq     :FinishDescr      ;no, branch
1a06: 20 33 2e                     jsr     JJ_PrintCR        ;yes, finish it with a newline
                   ; Finish up by printing "<------->" (full width of screen).
1a09: a9 3c        :FinishDescr    lda     #‘<’
1a0b: 20 30 2e                     jsr     JJ_PrintNonNull
1a0e: a9 2d                        lda     #‘-’
1a10: a2 26                        ldx     #38
1a12: 20 30 2e     :DashLoop       jsr     JJ_PrintNonNull
1a15: ca                           dex
1a16: d0 fa                        bne     :DashLoop
1a18: a9 3e                        lda     #‘>’
1a1a: 20 30 2e                     jsr     JJ_PrintNonNull
                   ; Set top of scrolling text window to be below separator line.
1a1d: a6 25                        ldx     MON_CV            ;get current vertical position
1a1f: e8                           inx                       ;add one so it's below current line
1a20: 86 22                        stx     MON_WNDTOP        ;set as top
1a22: a9 00                        lda     #0                ;set text position to left edge
1a24: 85 24                        sta     MON_CH
1a26: a9 17                        lda     #23               ;bottom of screen
1a28: 85 25                        sta     MON_CV
1a2a: 20 c1 fb                     jsr     MON_BASCALC       ;set BASL
1a2d: 20 8d 2e                     jsr     JJ_PopFullState   ;restore regs and ZP
1a30: 60                           rts

1a31: 49 54 53 20+ msg_too_dark    .zstr   ‘ITS TOO DARK TO SEE!’,$0d
1a47: 49 27 4d 20+ msg_im_in_a     .zstr   ‘I'M IN A ’
1a51: 4e 4f 52 54+ msg_exit_name   .zstr   ‘NORTH ’
1a58: 53 4f 55 54+                 .zstr   ‘SOUTH ’
1a5f: 45 41 53 54+                 .zstr   ‘EAST ’
1a65: 57 45 53 54+                 .zstr   ‘WEST ’
1a6b: 55 50 20 00                  .zstr   ‘UP ’
1a6f: 44 4f 57 4e+                 .zstr   ‘DOWN ’
1a75: 2e 20 56 49+ msg_vis_items   .zstr   ‘. VISIBLE ITEMS:’,$0d,$0d
1a88: 0d 20 53 4f+ msg_some_exits  .zstr   $0d,‘ SOME EXITS ARE: ’

                   ; 
                   ; Finds the argument for an action operation.  The arguments are stored in the
                   ; condition table, using entries where the condition opcode is zero.
                   ; 
                   ; This is only called when an arg is needed, so action ops without arguments
                   ; don't consume slots in the condition table.
                   ; 
                   ; On entry:
                   ;   $f6-f7: action index
                   ;   (actionop_arg_idx at $3067 specifies first table to check)
                   ; 
                   ; On exit:
                   ;   $f0-f1: argument
                   ; 
                   ]argval         .var    $f2    {addr/2}

1a9b: 20 57 2e     GetActionArg    jsr     JJ_PushRegs       ;preserve registers
1a9e: 20 75 2e                     jsr     JJ_PushF2F3       ;preserve $f2-f3
1aa1: 20 6f 2e                     jsr     JJ_PushF4F5       ;preserve $f4-f5
                   ; Search the condition table entries for this action index for an entry with
                   ; condition opcode $00, starting with the table specified by the action opcode
                   ; argument index.
1aa4: 20 54 2e     :Loop           jsr     InA_GetInlineData ;get pointer to pointers to condition data
1aa7: 0c 2f                        .dd2    condition0_ptr
1aa9: ad 67 30                     lda     actionop_arg_idx  ;get index to arg
1aac: 18                           clc
1aad: 6d 67 30                     adc     actionop_arg_idx  ;double it
1ab0: a8                           tay                       ;use as index into table
1ab1: ee 67 30                     inc     actionop_arg_idx  ;incr index for next time
1ab4: b1 f0                        lda     (]ptr),y          ;get pointer to table N (where N is arg index)
1ab6: 85 f2                        sta     ]argval
1ab8: c8                           iny
1ab9: b1 f0                        lda     (]ptr),y
1abb: 85 f3                        sta     ]argval+1
1abd: 20 96 2e                     jsr     JJ_PushF6F7       ;copy action index in $f6-f7...
1ac0: 20 60 2e                     jsr     JJ_PopF0F1        ;...into $f0-f1
1ac3: 20 84 2e                     jsr     JJ_SetF4F5_F0F1   ;...and $f4-f5
1ac6: 20 87 2e                     jsr     JJ_AddF0F1_F4F5   ;set $f0-f1 to double the action index
1ac9: 20 75 2e                     jsr     JJ_PushF2F3       ;copy cond table pointer in $f2-f3...
1acc: 20 72 2e                     jsr     JJ_PopF4F5        ;...into $f4-f5
1acf: 20 87 2e                     jsr     JJ_AddF0F1_F4F5   ;add to 2*index to get pointer to condition
                   ; 
1ad2: a0 00                        ldy     #$00
1ad4: b1 f0                        lda     (]ptr),y          ;get low byte of condition
1ad6: 85 f2                        sta     ]argval
1ad8: c8                           iny
1ad9: b1 f0                        lda     (]ptr),y          ;get high byte of condition
1adb: 85 f3                        sta     ]argval+1         ;save in $f2-f3
1add: 20 54 2e                     jsr     InA_GetInlineData ;load 20 into $f0-f1
1ae0: 14 00                        .dd2    20
1ae2: 20 21 2e                     jsr     JJ_Divide16       ;set $f0-f1 to condition / 20 (cond arg)
1ae5: a5 f3                        lda     ]argval+1         ; and $f2-f3 to the remainder (cond opcode)
1ae7: 05 f2                        ora     ]argval           ;was opcode zero?
1ae9: d0 b9                        bne     :Loop             ;no, branch
1aeb: 20 72 2e                     jsr     JJ_PopF4F5        ;restore $f4-f5
1aee: 20 78 2e                     jsr     JJ_PopF2F3        ;restore $f2-f3
1af1: 20 5a 2e                     jsr     JJ_PopRegs        ;restore regs
1af4: 60           :Return         rts

                   ; 
                   ; Prints a null-terminated string using COUT.  Useful for DOS commands.
                   ; 
1af5: a0 00        PrintStringCOUT ldy     #$00
1af7: b1 f0                        lda     (]ptr),y          ;get char
1af9: f0 f9                        beq     :Return           ;if it's $00, bail
1afb: 09 80                        ora     #$80              ;convert to to high ASCII
1afd: 20 ed fd                     jsr     MON_COUT          ;output in a way that DOS will see
1b00: 20 51 2e                     jsr     JJ_IncF0F1        ;advance pointer
1b03: 4c f5 1a                     jmp     PrintStringCOUT   ;loop

                   ; 
                   ; Saves a game to disk or tape.
                   ; 
1b06: 20 8a 2e     SaveGame        jsr     JJ_PushFullState  ;preserve all regs and ZP
1b09: 20 54 2e                     jsr     InA_GetInlineData
1b0c: 9d 1b                        .dd2    msg_save_game
1b0e: 20 36 2e                     jsr     JJ_PrintString    ;confirm that we're saving the game
1b11: 20 1b 2e                     jsr     JJ_AskDiskOrTape  ;ask if they want disk or tape
1b14: ad 57 30                     lda     adventure_num     ;copy adventure number into start of buffer
1b17: 8d 33 2f                     sta     kbd_scratch_buf
1b1a: ad 58 30                     lda     adventure_num+1
1b1d: 8d 34 2f                     sta     adv_num_hi
                   ; Copy $30c7-3103 to $2f35-2f71 (counters, flags, current room, etc.).
1b20: a0 3c                        ldy     #$3c
1b22: b9 c7 30     :Loop           lda     counter_register,y
1b25: 99 35 2f                     sta     save_game_data,y
1b28: 88                           dey
1b29: 10 f7                        bpl     :Loop
1b2b: ad b2 2e                     lda     use_disk_flag     ;disk or tape?
1b2e: f0 19                        beq     :Tape1            ;tape, branch
                   ; 
1b30: 20 54 2e                     jsr     InA_GetInlineData ;get pointer to DOS save command
1b33: ac 1b                        .dd2    dos_save_cmd
1b35: ad 57 30                     lda     adventure_num     ;put adventure number in filename (as control char)
1b38: 8d b9 1b                     sta     dos_save_cmd+13
1b3b: a9 31                        lda     #‘1’              ;file #1
1b3d: 8d b8 1b                     sta     dos_save_cmd+12
1b40: 20 1e 2e                     jsr     JJ_PrintStringCOUT ;issue DOS command for file #1
1b43: ee b8 1b                     inc     dos_save_cmd+12   ;update filename for next part
1b46: 4c 4c 1b                     jmp     :Part2

1b49: 20 05 1c     :Tape1          jsr     WriteTape         ;write part 1
1b4c: ea           :Part2          nop
1b4d: a0 00                        ldy     #$00
1b4f: a2 ff                        ldx     #$ff              ;init to -1, so first iteration uses X-reg=0
1b51: 20 93 2e                     jsr     InA_GetIndirectValue ;get pointer to item location data
1b54: 26 2f                        .dd2    item_rooms_ptr
1b56: e8           :Loop           inx
1b57: b1 f0                        lda     (]ptr),y          ;get item room #
1b59: 9d 33 2f                     sta     kbd_scratch_buf,x ;copy to save buffer
1b5c: c8                           iny                       ;(we always write 256 bytes, so max 128 items)
1b5d: c8                           iny
1b5e: ec 6f 30                     cpx     hdr_max_item      ;have we copied all items?
1b61: d0 f3                        bne     :Loop             ;no, branch
                   ; 
1b63: ad b2 2e                     lda     use_disk_flag     ;disk or tape?
1b66: f0 0b                        beq     :Tape2            ;tape, branch
1b68: 20 54 2e                     jsr     InA_GetInlineData
1b6b: ac 1b                        .dd2    dos_save_cmd
1b6d: 20 1e 2e                     jsr     JJ_PrintStringCOUT ;issue DOS command for file #2
1b70: 4c 76 1b                     jmp     :Done

1b73: 20 05 1c     :Tape2          jsr     WriteTape         ;write part 2
1b76: ea           :Done           nop
1b77: 20 8d 2e                     jsr     JJ_PopFullState   ;restore regs and ZP
1b7a: 60                           rts

1b7b: 20 52 45 41+ msg_ready_tape  .zstr   ‘ READY SAVE TAPE. THEN HIT ENTER.’
1b9d: 20 53 41 56+ msg_save_game   .zstr   ‘ SAVING GAME ’,$0d
1bac: 0d 04 42 53+ dos_save_cmd    .zstr   $0d,$04,‘BSAVE AREC2’,$05,‘,A$2F33,L256’,$0d
                   msg_disk_or_tape
1bc8: 20 44 49 53+                 .zstr   ‘ DISK OR TAPE? ’

                   ; 
                   ; Asks the player if the want to load/save from disk or tape.  If tape, the
                   ; player is prompted to get their recorder ready.
                   ; 
                   ; On exit:
                   ;   global flag set to $00 for tape, $01 for disk
                   ; 
1bd8: 20 54 2e     AskDiskOrTape   jsr     InA_GetInlineData
1bdb: c8 1b                        .dd2    msg_disk_or_tape
1bdd: 20 36 2e                     jsr     JJ_PrintString    ;ask for preference
1be0: 20 39 2e                     jsr     JJ_GetInput       ;get line of input
1be3: ad 33 2f                     lda     kbd_scratch_buf   ;check first char
1be6: c9 44                        cmp     #‘D’              ;disk?
1be8: d0 06                        bne     :NotDisk          ;no, branch
1bea: a9 01                        lda     #$01
1bec: 8d b2 2e                     sta     use_disk_flag
1bef: 60                           rts

1bf0: c9 54        :NotDisk        cmp     #‘T’              ;tape?
1bf2: d0 e4                        bne     AskDiskOrTape     ;no, try again
1bf4: a9 00                        lda     #$00
1bf6: 8d b2 2e                     sta     use_disk_flag
1bf9: 20 54 2e                     jsr     InA_GetInlineData
1bfc: 7b 1b                        .dd2    msg_ready_tape
1bfe: 20 36 2e                     jsr     JJ_PrintString    ;prompt player to prepare tape
1c01: 20 39 2e                     jsr     JJ_GetInput       ;wait for player to hit return
1c04: 60                           rts

                   ; 
                   ; Invokes the tape write routine.
                   ; 
1c05: a9 33        WriteTape       lda     #<kbd_scratch_buf ;set up start/end (inclusive bounds)
1c07: 85 3c                        sta     MON_A1L
1c09: a9 2f                        lda     #>kbd_scratch_buf
1c0b: 85 3d                        sta     MON_A1H
1c0d: a9 32                        lda     #<save_state_end
1c0f: 85 3e                        sta     MON_A2L
1c11: a9 30                        lda     #>save_state_end
1c13: 85 3f                        sta     MON_A2H
1c15: 20 cd fe                     jsr     MON_WRITE         ;call monitor write routine
1c18: 60                           rts

1c19: 69 6e 67 20+                 .junk   743               ;bunch of data from another game in this area

                   J_ProcessActions
1f00: 4c 08 1f                     jmp     ProcessActions

1f03: 4c 6e 21     J_ActionLoopEnd jmp     ActionLoopEnd

1f06: 00           fail_msg_index  .dd1    $00               ;holds a failure code (see e.g. $2327)
1f07: 00           action_opcode   .dd1    $00               ;written, never read

                   ; 
                   ; Process action list.  Called from main loop.
                   ; 
                   ; On entry:
                   ;   (first time: verb and noun indices set)
                   ;   (second time: verb index set to zero)
                   ; 
1f08: a9 00        ProcessActions  lda     #$00
1f0a: 8d c4 30                     sta     continue_flag     ;init the "continue" flag
1f0d: 8d c3 30                     sta     occur_flag        ;clear the "processing occurrences" flag
1f10: a9 ff                        lda     #$ff
1f12: 8d c2 30                     sta     accum_cond_result ;init cumulative condition test result
1f15: 8d c0 30                     sta     cmd_not_hnd_flag  ;init "command not handled" flag to true
1f18: ad bc 30                     lda     parsed_verb_idx   ;get the verb index
1f1b: c9 01                        cmp     #$01              ;is it "GO" (actual or implied)?
1f1d: d0 0b                        bne     :FindAction       ;no, branch
1f1f: ad be 30                     lda     parsed_noun_idx   ;check the noun
1f22: c9 07                        cmp     #$07              ;is it missing (0) or NSEWUD (1-6)?
1f24: 10 04                        bpl     :FindAction       ;no, branch
1f26: 20 f7 23                     jsr     HandleGo          ;handle GO command
1f29: 60           :Return         rts

                   ]action_index   .var    $f6    {addr/2}

1f2a: a9 ff        :FindAction     lda     #$ff              ;init index to -1
1f2c: 85 f6                        sta     ]action_index
1f2e: 85 f7                        sta     ]action_index+1
1f30: e6 f6        :FindActionLoop inc     ]action_index     ;increment index
1f32: d0 02                        bne     :NoInc
1f34: e6 f7                        inc     ]action_index+1
1f36: ea           :NoInc          nop
1f37: 20 96 2e                     jsr     JJ_PushF6F7       ;push index
1f3a: 20 60 2e                     jsr     JJ_PopF0F1        ;copy to $f0-f1
1f3d: 20 4e 2e                     jsr     JJ_DecF0F1        ;decrement it
1f40: 20 7b 2e                     jsr     InA_SubF0F1_Ind   ;subtract max action; this is just comparing
1f43: 6d 30                        .dd2    hdr_max_action    ; the index to see if we've reached the end
1f45: d0 23                        bne     :NotEnd           ;not end of list, branch
                   ; We didn't find a matching action for this noun/verb.  Look for implicit
                   ; get/drop action (from /WORD/ in item descriptions).
1f47: ad bc 30     :CheckGetDrop   lda     parsed_verb_idx   ;is verb index zero (doing occurrences)?
1f4a: f0 dd                        beq     :Return           ;yes, done
1f4c: 20 e6 21                     jsr     ImplicitGetDrop   ;look for /WORD/ matches if this is TAKE or DROP
1f4f: 20 54 2e                     jsr     InA_GetInlineData
1f52: 7e 21                        .dd2    msg_be_stupid
1f54: ad c0 30                     lda     cmd_not_hnd_flag  ;is command still unhandled?
1f57: f0 03                        beq     :NotUnhand        ;no, getdrop handler took care of it; branch
1f59: 20 36 2e                     jsr     JJ_PrintString    ;print "I don't understand" (WEAR MERCHANT)
1f5c: 20 54 2e     :NotUnhand      jsr     InA_GetInlineData
1f5f: bd 21                        .dd2    msg_cant_yet
1f61: ad c2 30                     lda     accum_cond_result ;were all conditions true?
1f64: d0 c3                        bne     :Return           ;yes, branch
1f66: 20 36 2e                     jsr     JJ_PrintString    ;some cond not satisfied, print "can't do that yet"
1f69: 60           :Return         rts

                   ]verb_ptr       .var    $f4    {addr/2}

1f6a: 20 96 2e     :NotEnd         jsr     JJ_PushF6F7       ;copy action index in $f6-f7...
1f6d: 20 72 2e                     jsr     JJ_PopF4F5        ;...to $f4-f5
1f70: 20 93 2e                     jsr     InA_GetIndirectValue ;get pointer to action verb table
1f73: 00 2f                        .dd2    action_verb_ptr
1f75: 20 87 2e                     jsr     JJ_AddF0F1_F4F5   ;add action index to pointer
1f78: a0 00                        ldy     #$00
1f7a: b1 f0                        lda     (]ptr),y          ;get verb index for this action
1f7c: 8d c6 30                     sta     action_verb_idx   ;save it
1f7f: 20 93 2e                     jsr     InA_GetIndirectValue ;get pointer to noun index or occurrence percent
1f82: 02 2f                        .dd2    action_nou_prc_ptr
1f84: 20 87 2e                     jsr     JJ_AddF0F1_F4F5   ;add action index to pointer
1f87: b1 f0                        lda     (]ptr),y          ;get percent chance of occurrence firing
1f89: 8d c5 30                     sta     noun_or_percent   ;save it
1f8c: ad bc 30                     lda     parsed_verb_idx   ;get command verb index
1f8f: d0 05                        bne     :Cont             ;nonzero (looking for match), branch
1f91: ad c6 30                     lda     action_verb_idx   ;get action's verb index
1f94: d0 d3                        bne     :Return           ;nonzero, end of occurrences reached; bail
                   ; 
1f96: ad c4 30     :Cont           lda     continue_flag     ;are we continuing a previous item?
1f99: f0 12                        beq     :NotCont          ;no, branch
1f9b: ad c5 30                     lda     noun_or_percent
1f9e: d0 05                        bne     :HaveNoun
1fa0: ad c6 30                     lda     action_verb_idx   ;is this action an occurrence?
1fa3: f0 4f                        beq     :TestConds        ;yes, branch
1fa5: ad bc 30     :HaveNoun       lda     parsed_verb_idx
1fa8: d0 bf                        bne     :Return
1faa: 8d c4 30                     sta     continue_flag     ;(A-reg=0) clear the continue flag
                   ; 
1fad: ad bc 30     :NotCont        lda     parsed_verb_idx   ;get command verb index
1fb0: cd c6 30                     cmp     action_verb_idx   ;compare to action verb index
1fb3: d0 13                        bne     :WordMismatch     ;mismatch, branch
1fb5: c9 00                        cmp     #$00              ;is verb zero (looking for occurrences)?
1fb7: d0 12                        bne     :NotOccur         ;no, branch
1fb9: a9 00                        lda     #$00
1fbb: 8d c0 30                     sta     cmd_not_hnd_flag  ;clear the not-handled flag
1fbe: 20 d4 23                     jsr     GetRandom         ;get a random number (1-100)
1fc1: cd c5 30                     cmp     noun_or_percent   ;compare to value specified in occurrence
1fc4: f0 2e                        beq     :TestConds        ;if we rolled <= value, do the occurrence
1fc6: 90 2c                        bcc     :TestConds
1fc8: 4c 30 1f     :WordMismatch   jmp     :FindActionLoop

1fcb: ad c5 30     :NotOccur       lda     noun_or_percent   ;get noun index from action
1fce: cd be 30                     cmp     parsed_noun_idx   ;compare to noun index from command
1fd1: f0 04                        beq     :NounMatch        ;match, branch
1fd3: c9 00                        cmp     #$00              ;does action require a noun?
1fd5: d0 f1                        bne     :WordMismatch     ;yes, this action doesn't apply; branch
                   ; 
1fd7: ad 7d 30     :NounMatch      lda     debug_flag        ;check debug flag
1fda: c9 01                        cmp     #$01              ;'P' mode?
1fdc: d0 16                        bne     :TestConds        ;no, "T" mode or off, don't show this message
1fde: 20 54 2e                     jsr     InA_GetInlineData
1fe1: de 21                        .dd2    msg_psbl
1fe3: 20 36 2e                     jsr     JJ_PrintString
1fe6: 20 96 2e                     jsr     JJ_PushF6F7       ;push action index
1fe9: 20 60 2e                     jsr     JJ_PopF0F1
1fec: 20 48 2e                     jsr     JJ_PrintSignedDec ;print action index
1fef: a9 20                        lda     #‘ ’
1ff1: 20 30 2e                     jsr     JJ_PrintNonNull
                   ]cond_tab_ptr   .var    $f8    {addr/2}

1ff4: a9 00        :TestConds      lda     #$00
1ff6: 8d c0 30                     sta     cmd_not_hnd_flag  ;clear the command-not-handled flag
1ff9: a9 ff                        lda     #$ff
1ffb: 8d c2 30                     sta     accum_cond_result ;init result to "true"
1ffe: 8d c3 30                     sta     occur_flag
2001: a9 0c                        lda     #<condition0_ptr  ;get pointer to first condition table
2003: 85 f8                        sta     ]cond_tab_ptr
2005: a9 2f                        lda     #>condition0_ptr
2007: 85 f9                        sta     ]cond_tab_ptr+1
                   ; Test up to 5 conditions, all of which must evaluate to True.  Each condition
                   ; is a 16-bit value that holds both the operation and the argument (value = op +
                   ; value * 20).  If an operation returns false, we bail.
                   ]cond_raw       .var    $f2    {addr/2}

2009: a2 05                        ldx     #$05              ;5 conditions max
200b: a0 00        :Loop           ldy     #$00
200d: b1 f8                        lda     (]cond_tab_ptr),y ;get pointer to first table
200f: 85 f0                        sta     ]ptr
2011: c8                           iny
2012: b1 f8                        lda     (]cond_tab_ptr),y
2014: 85 f1                        sta     ]ptr+1
2016: 20 5d 2e                     jsr     JJ_PushF0F1       ;preserve table pointer
2019: 20 96 2e                     jsr     JJ_PushF6F7       ;copy action index in $f6-f7...
201c: 20 60 2e                     jsr     JJ_PopF0F1        ;...to $f0-f1
201f: 20 84 2e                     jsr     JJ_SetF4F5_F0F1   ;copy that to $f4-f5
2022: 20 87 2e                     jsr     JJ_AddF0F1_F4F5   ;add it to itself (i.e. double the index)
2025: 20 72 2e                     jsr     JJ_PopF4F5        ;pop table pointer
2028: 20 87 2e                     jsr     JJ_AddF0F1_F4F5   ;set pointer to (pointer + index*2)
202b: b1 f0                        lda     (]ptr),y          ;get condition table entry (note Y-reg=1)
202d: 85 f3                        sta     ]cond_raw+1       ;save high byte
202f: 88                           dey
2030: b1 f0                        lda     (]ptr),y          ;get low byte of condition table entry
2032: 85 f2                        sta     ]cond_raw         ;save it
2034: 20 54 2e                     jsr     InA_GetInlineData
2037: 14 00                        .dd2    20
2039: 20 21 2e                     jsr     JJ_Divide16       ;divide value by 20 to separate pieces
203c: 20 5d 2e                     jsr     JJ_PushF0F1       ;push quotient (arg)
203f: 20 75 2e                     jsr     JJ_PushF2F3       ;push remainder (cond op code)
2042: 20 81 2e                     jsr     JJ_SetF2F3_F0F1   ;set $f2-f3 to quotient
2045: 20 60 2e                     jsr     JJ_PopF0F1        ;set $f0-f1 to remainder
2048: 20 84 2e                     jsr     JJ_SetF4F5_F0F1   ;set $f4-f5 to remainder
204b: 20 87 2e                     jsr     JJ_AddF0F1_F4F5   ;double it
204e: 20 84 2e                     jsr     JJ_SetF4F5_F0F1   ;store op code * 2 in $f4-f5
2051: 20 93 2e                     jsr     InA_GetIndirectValue ;get a pointer to the cond op handlers table pointer
2054: 0d 2e                        .dd2    cond_handlers_ind
2056: c8                           iny                       ;skip past the fake JMP instruction
2057: b1 f0                        lda     (]ptr),y          ;get low byte of pointer to table
2059: 48                           pha                       ;save it
205a: c8                           iny
205b: b1 f0                        lda     (]ptr),y          ;get high byte
205d: 85 f1                        sta     ]ptr+1            ;overwrite $f0-f1 with table pointer
205f: 68                           pla
2060: 85 f0                        sta     ]ptr
                   ; 
2062: a0 00                        ldy     #$00
2064: 20 87 2e                     jsr     JJ_AddF0F1_F4F5   ;add doubled op code to $f0-f1 to get entry pointer
2067: 20 72 2e                     jsr     JJ_PopF4F5        ;pop quotient (arg) into $f4-f5
206a: b1 f0                        lda     (]ptr),y          ;get pointer to func, low byte
206c: 8d 90 20                     sta     _CondCall+1       ;self-modify the JSR
206f: c8                           iny
2070: b1 f0                        lda     (]ptr),y          ;same for high byte
2072: 8d 91 20                     sta     _CondCall+2
                   ; We have the cond op arg in $f2-f3 and $f4-f5.  Set up registers and ZP with
                   ; values we're likely to need.
2075: 20 93 2e                     jsr     InA_GetIndirectValue ;get pointer to item location data
2078: 26 2f                        .dd2    item_rooms_ptr
207a: 20 87 2e                     jsr     JJ_AddF0F1_F4F5   ;add cond arg
207d: 20 87 2e                     jsr     JJ_AddF0F1_F4F5   ;twice (16-bit data)
2080: a0 00                        ldy     #$00
2082: 8a                           txa                       ;X-reg still holds the condition counter
2083: 48                           pha                       ;preserve it
2084: b1 f0                        lda     (]ptr),y          ;set A-reg to room number of item N
2086: 20 54 2e                     jsr     InA_GetInlineData ;get pointer to current room in $f0-f1
2089: e9 30                        .dd2    current_room
208b: a2 ff                        ldx     #$ff              ;set X-reg to default return value
208d: a0 00                        ldy     #$00              ;set Y-reg to zero
208f: 20 9a 17     _CondCall       jsr     C04_At            ;self-mod; call relevant condition handler
2092: 8a                           txa                       ;copy result ($00 or $ff) to A-reg
2093: 2d c2 30                     and     accum_cond_result ;merge with previous results
2096: 8d c2 30                     sta     accum_cond_result
2099: 68                           pla                       ;restore count
209a: aa                           tax
209b: 20 a2 2e                     jsr     JJ_IncF8F9        ;advance condition table pointer
209e: 20 a2 2e                     jsr     JJ_IncF8F9
20a1: ad c2 30                     lda     accum_cond_result ;check current result
20a4: d0 03                        bne     :NotFalse         ;not yet false, so keep going
20a6: 4c 30 1f                     jmp     :FindActionLoop   ;condition failed, go find another action

20a9: ca           :NotFalse       dex                       ;done yet?
20aa: f0 03                        beq     :DoActionOps      ;yes, do action operations
20ac: 4c 0b 20                     jmp     :Loop             ;no, loop

                   ; All conditions for this action have succeeded.  Invoke operations.
                   ]index          .var    $f4    {addr/2}
                   ]table_ptr      .var    $f8    {addr/2}

20af: ea           :DoActionOps    nop
20b0: ad 7d 30                     lda     debug_flag        ;check debug flag
20b3: f0 16                        beq     :NoDebug          ;not enabled, skip
20b5: 20 54 2e                     jsr     InA_GetInlineData ;show for 'P' or 'T' mode
20b8: d7 21                        .dd2    msg_did
20ba: 20 36 2e                     jsr     JJ_PrintString
20bd: 20 96 2e                     jsr     JJ_PushF6F7       ;push action index
20c0: 20 60 2e                     jsr     JJ_PopF0F1
20c3: 20 48 2e                     jsr     JJ_PrintSignedDec ;print action index
20c6: a9 20                        lda     #‘ ’
20c8: 20 30 2e                     jsr     JJ_PrintNonNull
20cb: a9 00        :NoDebug        lda     #$00
20cd: 8d 67 30                     sta     actionop_arg_idx  ;init action op arg index to zero
20d0: 8d 68 30                     sta     actionop_arg_idx+1
20d3: 20 54 2e                     jsr     InA_GetInlineData ;get pointer to pointers to action opcodes
20d6: 04 2f                        .dd2    action_op0_ptr
20d8: 20 5d 2e                     jsr     JJ_PushF0F1       ;copy table pointer in $f0-f1...
20db: 20 9f 2e                     jsr     JJ_PopF8F9        ;...to $f8-f9
                   ; 
20de: a2 04                        ldx     #$04              ;at most four operations
20e0: ea           :OpLoop         nop
20e1: a0 00                        ldy     #$00
20e3: b1 f8                        lda     (]table_ptr),y    ;get pointer to table N
20e5: 85 f0                        sta     ]ptr              ;store in $f0-f1
20e7: c8                           iny
20e8: b1 f8                        lda     (]table_ptr),y
20ea: 85 f1                        sta     ]ptr+1
20ec: 20 96 2e                     jsr     JJ_PushF6F7       ;copy action index in $f6-f7
20ef: 20 72 2e                     jsr     JJ_PopF4F5        ; to $f4-f5
20f2: 20 87 2e                     jsr     JJ_AddF0F1_F4F5   ;add to index to get pointer to opcode
20f5: 88                           dey                       ;set Y-reg=0
20f6: b1 f0                        lda     (]ptr),y          ;get action opcode
20f8: 8d 07 1f                     sta     action_opcode     ;store (not used?)
20fb: f0 65                        beq     :NextOp           ;opcode $00, do nothing
20fd: 30 08                        bmi     :HighMsg          ;negative value, must be message 51-99; branch
20ff: c9 34                        cmp     #$34              ;message 1-50?
2101: 30 07                        bmi     :LowMsg           ;yes, branch
2103: c9 66                        cmp     #$66              ;msg 51-99?
2105: 30 2a                        bmi     :OpNotMsg         ;no, branch
                   ; Print a message.
2107: 38           :HighMsg        sec
2108: e9 32                        sbc     #$32              ;change [$66,$96] to [$34,$64] (52-100)
210a: 85 f4        :LowMsg         sta     ]index            ;save message index
210c: a9 00                        lda     #$00
210e: 85 f5                        sta     ]index+1          ;set high byte of index to zero
2110: 20 93 2e                     jsr     InA_GetIndirectValue ;get pointer to pointers to messages
2113: 24 2f                        .dd2    messages_ptr
2115: 20 87 2e                     jsr     JJ_AddF0F1_F4F5   ;add index
2118: 20 87 2e                     jsr     JJ_AddF0F1_F4F5   ;twice (16-bit address values)
211b: a0 00                        ldy     #$00
211d: b1 f0                        lda     (]ptr),y          ;get pointer to message N
211f: 48                           pha                       ;push low byte
2120: c8                           iny
2121: b1 f0                        lda     (]ptr),y          ;get high byte
2123: 85 f1                        sta     ]ptr+1            ;set $f0-f1 to string pointer
2125: 68                           pla
2126: 85 f0                        sta     ]ptr
2128: 20 42 2e                     jsr     JJ_PrintL1Str     ;print message string
212b: 20 33 2e                     jsr     JJ_PrintCR        ;follow with CR
212e: 4c 62 21                     jmp     :NextOp           ;loop

                   ; Perform non-message operation.  At this point, $f4-f5 and $f6-f7 hold the
                   ; action index.
2131: 38           :OpNotMsg       sec
2132: e9 34                        sbc     #$34              ;remap [$34,$65] to [$00,$31]
2134: 85 f4                        sta     ]index            ;save opcode index
2136: a9 00                        lda     #$00
2138: 85 f5                        sta     ]index+1          ;set high byte of index to zero
213a: 20 93 2e                     jsr     InA_GetIndirectValue ;get pointer to pointer to op func table
213d: 2b 2e                        .dd2    act_oper_ind
213f: a0 01                        ldy     #$01              ;move past JMP operand
2141: b1 f0                        lda     (]ptr),y          ;get pointer and replace $f0-f1
2143: 48                           pha
2144: c8                           iny
2145: b1 f0                        lda     (]ptr),y
2147: 85 f1                        sta     ]ptr+1
2149: 68                           pla
214a: 85 f0                        sta     ]ptr              ;now pointing to opcode table ($270c)
214c: 20 87 2e                     jsr     JJ_AddF0F1_F4F5   ;add opcode index
214f: 20 87 2e                     jsr     JJ_AddF0F1_F4F5   ;add index again to double it (16-bit addrs)
                   ; 
2152: a0 00                        ldy     #$00
2154: b1 f0                        lda     (]ptr),y          ;get pointer to action op function
2156: 8d 60 21                     sta     _OpCall+1         ;store in self-modified JSR
2159: c8                           iny
215a: b1 f0                        lda     (]ptr),y
215c: 8d 61 21                     sta     _OpCall+2
215f: 20 0f 28     _OpCall         jsr     O49_Continue      ;self mod; call action operation
2162: 20 a2 2e     :NextOp         jsr     JJ_IncF8F9        ;advance to next table
2165: 20 a2 2e                     jsr     JJ_IncF8F9        ; (16-bit pointers to tables)
2168: ca                           dex                       ;done yet?
2169: f0 03                        beq     ActionLoopEnd     ;yes, branch
216b: 4c e0 20                     jmp     :OpLoop

                   ; Note: we jump here after GET action op fails due to excess inventory,
                   ; presumably to skip the remaining part of the action after the op failed.
216e: ad c4 30     ActionLoopEnd   lda     continue_flag     ;is this a continuation of the previous action?
2171: f0 03                        beq     :NotCont          ;no, branch
2173: 4c 30 1f     :JLoop          jmp     :FindActionLoop   ;yes, back to the loop

2176: ad bc 30     :NotCont        lda     parsed_verb_idx   ;is the verb index zero (processing occurrences)?
2179: f0 f8                        beq     :JLoop            ;yes, branch
217b: 4c 47 1f                     jmp     :CheckGetDrop     ;no, go check for implicit TAKE and DROP

217e: 0d 49 20 4d+ msg_be_stupid   .zstr   $0d,‘I MUST BE STUPID, BUT I JUST DON'T’,$0d,‘ ’ ;words are valid, but no action found
                                    +      ‘UNDERSTAND WHAT YOU MEAN’,$0d
21bd: 0d 49 20 43+ msg_cant_yet    .zstr   $0d,‘I CAN'T DO THAT... YET!’,$0d ;found matching action, but conditions failed
21d7: 20 44 49 44+ msg_did         .zstr   ‘ DID: ’          ;debug
21de: 20 50 53 42+ msg_psbl        .zstr   ‘ PSBL: ’         ;debug ("possible?")

                   ; 
                   ; See if an implict get/drop action applies here.  If we handle the command, we
                   ; clear the "command not handled" flag ($30c0) whether or not the action was
                   ; successful.
                   ; 
                   ; On entry:
                   ;   (parsed verb and noun indices set)
                   ; 
                   ; On exit:
                   ;   "command not handled" flag ($30c0) cleared if handled
                   ; 
                   ]count          .var    $f4    {addr/1}

21e6: ad bc 30     ImplicitGetDrop lda     parsed_verb_idx   ;get verb index
21e9: c9 0a                        cmp     #10               ;TAKE?
21eb: f0 05                        beq     :HandleTakeDrop   ;yes, handle it
21ed: c9 12                        cmp     #18               ;DROP?
21ef: f0 01                        beq     :HandleTakeDrop   ;yes, handle it
21f1: 60           :Return         rts

21f2: ad c3 30     :HandleTakeDrop lda     occur_flag        ;processing occurrences?
21f5: d0 fa                        bne     :Return           ;yes, bail
21f7: ad be 30                     lda     parsed_noun_idx   ;get noun index
21fa: d0 0b                        bne     :HaveNoun
21fc: 20 54 2e                     jsr     InA_GetInlineData
21ff: 62 23                        .dd2    msg_huh
2201: 20 36 2e                     jsr     JJ_PrintString    ;no noun provided (or GET ANY); act confused
2204: 4c 21 23                     jmp     :ActionHandled    ;bail

2207: ad bc 30     :HaveNoun       lda     parsed_verb_idx   ;get verb index
220a: c9 0a                        cmp     #10               ;TAKE?
220c: d0 48                        bne     :SkipInvCount     ;no, must be drop; branch
                   ; Handle TAKE action.
220e: 20 a5 2e                     jsr     JJ_CountHeldObjs  ;count objects
2211: ac 75 30                     ldy     hdr_max_held      ;get limit
2214: 88                           dey                       ;reduce by one (for >= comparison)
2215: c4 f4                        cpy     ]count            ;are we over limit?
2217: 10 3d                        bpl     :SkipInvCount     ;no, branch to common processing
2219: 20 54 2e                     jsr     InA_GetInlineData
221c: 24 22                        .dd2    msg_carry_2_much
221e: 20 36 2e                     jsr     JJ_PrintString    ;print "carrying too much" message
2221: 4c 21 23                     jmp     :ActionHandled    ;bail

                   msg_carry_2_much
2224: 0d 20 49 27+                 .zstr   $0d,‘ I'M CARRYING TOO MUCH!’,$0d,‘ TRY: "TAKE ’
                                    +      ‘INVENTORY"’,$0d,$0d

                   ; Search the item names for /WORD/.  We do this by walking through the strings
                   ; as a pile.  This is a little imprecise because the getdrop strings in the item
                   ; list both start and end with a '/', but in practice it's unlikely to false-
                   ; positive since the next character will be an item number, followed by a string
                   ; length.
                   ]item_str_ptr   .var    $f2    {addr/2}
                   ]remain_len     .var    $f4    {addr/2}

2256: a9 00        :SkipInvCount   lda     #$00
2258: 8d 06 1f                     sta     fail_msg_index    ;clear flag
225b: 20 93 2e                     jsr     InA_GetIndirectValue ;get total length of item name string pool
225e: 03 31                        .dd2    item_names_len
2260: 20 84 2e                     jsr     JJ_SetF4F5_F0F1   ;copy to $f4-f5
2263: 20 93 2e                     jsr     InA_GetIndirectValue ;get pointer to table of pointers to names ($439f)
2266: 28 2f                        .dd2    item_names_ptr
2268: a0 00                        ldy     #$00
226a: b1 f0                        lda     (]ptr),y          ;get pointer to item 0
226c: c8                           iny
226d: 48                           pha
226e: b1 f0                        lda     (]ptr),y
2270: 85 f1                        sta     ]ptr+1            ;put in $f0-f1
2272: 68                           pla
2273: 85 f0                        sta     ]ptr
                   ; 
2275: ea           :SearchLoop     nop
2276: 20 51 2e     :SearchLoop1    jsr     JJ_IncF0F1        ;advance string pointer
2279: 20 63 2e                     jsr     JJ_DecF4F5        ;decrement remaining len
227c: a5 f5                        lda     ]remain_len+1     ;check for zero: load high byte
227e: 30 06                        bmi     :JDone            ;if negative, we're done
2280: d0 07                        bne     :InnerLoop        ;if nonzero, keep going
2282: c5 f4                        cmp     ]remain_len       ;must be zero; is low byte also zero?
2284: d0 03                        bne     :InnerLoop        ;no, keep going
2286: 4c 27 23     :JDone          jmp     :SearchDone       ;len at zero, exit loop

2289: a0 00        :InnerLoop      ldy     #$00
228b: a9 2f                        lda     #‘/’              ;looking for a '/'
228d: d1 f0                        cmp     (]ptr),y          ;test char
228f: f0 0f                        beq     :FoundSlash       ;got match, check further
2291: 20 51 2e                     jsr     JJ_IncF0F1        ;advance string pointer
2294: 20 63 2e                     jsr     JJ_DecF4F5        ;decrement remaining len
2297: a5 f4                        lda     ]remain_len       ;check remaining len
2299: 05 f5                        ora     ]remain_len+1
229b: d0 ec                        bne     :InnerLoop        ;not zero, loop
229d: 4c 27 23                     jmp     :SearchDone       ;done with search, exit loop

22a0: 20 81 2e     :FoundSlash     jsr     JJ_SetF2F3_F0F1   ;copy string pointer to $f2-f3
22a3: 20 6c 2e                     jsr     JJ_IncF2F3        ;advance past '/'
22a6: a0 00                        ldy     #$00
22a8: b9 80 30     :MatchLoop      lda     word_trim_buf,y   ;compare to trimmed noun string
22ab: f0 0a                        beq     :FoundMatch       ;if we hit end of user input, branch
22ad: d1 f2                        cmp     (]item_str_ptr),y ;compare to string in item list
22af: d0 c4                        bne     :SearchLoop       ;if we didn't match, branch to loop
22b1: c8                           iny                       ;advance pointer
22b2: cc 69 30                     cpy     hdr_word_len      ;have we matched the max chars required?
22b5: 30 f1                        bmi     :MatchLoop        ;not yet, branch
                   ; 
                   ]item_num       .var    $f4    {addr/2}

22b7: a9 2f        :FoundMatch     lda     #‘/’              ;all chars matched; if the trimmed noun was < 4
22b9: d1 f2                        cmp     (]item_str_ptr),y ; chars, make sure the item string is as well
22bb: d0 b8                        bne     :SearchLoop       ;no, partial match only; branch to loop
22bd: c8                           iny                       ;advance past '/'
22be: 20 6f 2e                     jsr     JJ_PushF4F5       ;preserve $f4-f5
22c1: 20 5d 2e                     jsr     JJ_PushF0F1       ;preserve $f0-f1
22c4: b1 f2                        lda     (]item_str_ptr),y ;get item number (follows closing '/')
22c6: 85 f4                        sta     ]item_num
22c8: a9 00                        lda     #$00              ;set item number high byte to zero
22ca: 85 f5                        sta     ]item_num+1
22cc: 20 93 2e                     jsr     InA_GetIndirectValue ;get pointer to item location data
22cf: 26 2f                        .dd2    item_rooms_ptr
22d1: 20 87 2e                     jsr     JJ_AddF0F1_F4F5   ;add item number to pointer
22d4: 20 87 2e                     jsr     JJ_AddF0F1_F4F5   ;add it again (16-bit values)
22d7: 20 81 2e                     jsr     JJ_SetF2F3_F0F1   ;copy pointer to item's room data to $f2-f3
22da: 20 60 2e                     jsr     JJ_PopF0F1        ;restore $f0-f1
22dd: 20 72 2e                     jsr     JJ_PopF4F5        ;restore $f4-f5
                   ; We've identified the desired item.  Do the actual TAKE or DROP.
22e0: ad bc 30                     lda     parsed_verb_idx   ;get verb index
22e3: a0 00                        ldy     #$00
22e5: c9 0a                        cmp     #10               ;TAKE?
22e7: f0 16                        beq     :DoTake           ;yes, branch
22e9: b1 f2                        lda     (]item_str_ptr),y ;get item location
22eb: c9 ff                        cmp     #ITEM_HELD        ;is it in player's inventory?
22ed: f0 08                        beq     :DropIt           ;yes, branch
22ef: a9 01                        lda     #$01
22f1: 8d 06 1f     :SetFailure     sta     fail_msg_index    ;set failure code
22f4: 4c 76 22                     jmp     :SearchLoop1      ;search for another match (why?)

22f7: ad e9 30     :DropIt         lda     current_room
22fa: 91 f2                        sta     (]item_str_ptr),y ;set item location to the current room
22fc: 4c 16 23                     jmp     :SayOkay

22ff: b1 f2        :DoTake         lda     (]item_str_ptr),y ;get item location
2301: c9 ff                        cmp     #ITEM_HELD        ;already in inventory?
2303: d0 04                        bne     :NotInInv         ;no, branch
2305: a9 04                        lda     #$04
2307: d0 e8                        bne     :SetFailure       ;set failure code and loop

2309: cd e9 30     :NotInInv       cmp     current_room      ;is item in the current room?
230c: f0 04                        beq     :TakeIt           ;yes, branch
230e: a9 02                        lda     #$02
2310: d0 df                        bne     :SetFailure       ;set failure code and loop

2312: a9 ff        :TakeIt         lda     #ITEM_HELD
2314: 91 f2                        sta     (]item_str_ptr),y ;move item to player's inventory
2316: 20 54 2e     :SayOkay        jsr     InA_GetInlineData
2319: 69 23                        .dd2    msg_ok
231b: 20 36 2e                     jsr     JJ_PrintString    ;print "ok"
231e: 20 15 2e                     jsr     JJ_DescribeRoom   ;redraw room description
2321: a9 00        :ActionHandled  lda     #$00
2323: 8d c0 30                     sta     cmd_not_hnd_flag  ;clear flag to indicate that command was handled
2326: 60           :Return         rts

                   ; Search complete, report appropriate failure message.
2327: ad 06 1f     :SearchDone     lda     fail_msg_index    ;get failure code
232a: c9 01                        cmp     #$01
232c: d0 08                        bne     :Not1
232e: 20 54 2e                     jsr     InA_GetInlineData
2331: 6e 23                        .dd2    msg_not_carrying
2333: 20 36 2e                     jsr     JJ_PrintString    ;failure #1: DROP on item not carried
2336: c9 02        :Not1           cmp     #$02
2338: d0 08                        bne     :Not2
233a: 20 54 2e                     jsr     InA_GetInlineData
233d: 86 23                        .dd2    msg_dont_see
233f: 20 36 2e                     jsr     JJ_PrintString    ;failure #2: TAKE on item not present
2342: c9 04        :Not2           cmp     #$04
2344: d0 08                        bne     :Not4
2346: 20 54 2e                     jsr     InA_GetInlineData
2349: 9d 23                        .dd2    msg_already_have
234b: 20 36 2e                     jsr     JJ_PrintString    ;failure #4: TAKE on item already in inventory
234e: c9 00        :Not4           cmp     #$00
2350: d0 cf                        bne     :ActionHandled
2352: ad c3 30                     lda     occur_flag        ;processing an occurrence?
2355: d0 cf                        bne     :Return           ;yes, don't show message
2357: 20 54 2e                     jsr     InA_GetInlineData
235a: b2 23                        .dd2    msg_beyond_power
235c: 20 36 2e                     jsr     JJ_PrintString    ;failure #0: incompatible noun ("TAKE MERCHANT")
235f: 4c 21 23                     jmp     :ActionHandled

2362: 20 48 55 48+ msg_huh         .zstr   ‘ HUH?’,$0d
2369: 20 4f 4b 0d+ msg_ok          .zstr   ‘ OK’,$0d
                   msg_not_carrying
236e: 0d 20 49 27+                 .zstr   $0d,‘ I'M NOT CARRYING IT!’,$0d
2386: 0d 49 20 44+ msg_dont_see    .zstr   $0d,‘I DON'T SEE IT HERE!’,$0d
                   msg_already_have
239d: 0d 20 49 20+                 .zstr   $0d,‘ I ALREADY HAVE IT’,$0d
                   msg_beyond_power
23b2: 0d 49 54 53+                 .zstr   $0d,‘ITS BEYOND MY POWER TO DO THAT.’,$0d

                   ; 
                   ; Generates a crude random number from 1-100.
                   ; 
                   ; The first call uses the keyboard input counter, so is reasonably random. 
                   ; Subsequent calls without keyboard input will have a short cycle.
                   ; 
                   ; On exit:
                   ;   A-reg: result (1-100)
                   ;   (X-reg and Y-reg preserved)
                   ; 
23d4: 8e 35 30     GetRandom       stx     tmp_save_x2       ;preserve X-reg
23d7: ad b0 2e                     lda     kbd_rng_seed      ;get random seed
23da: a2 0c                        ldx     #12               ;multiply by 12 (by adding)
23dc: 18           :MulLoop        clc
23dd: 6d b0 2e                     adc     kbd_rng_seed
23e0: ca                           dex
23e1: d0 f9                        bne     :MulLoop
23e3: 69 01                        adc     #$01              ;add 1
23e5: 8d b0 2e                     sta     kbd_rng_seed      ;update seed
23e8: ae 35 30                     ldx     tmp_save_x2       ;restore X-reg
23eb: c9 64        :ModLoop        cmp     #100              ;is it < 100?
23ed: 90 05                        bcc     :Done             ;yes, branch
23ef: 38                           sec                       ;subtract 100
23f0: e9 64                        sbc     #100
23f2: d0 f7                        bne     :ModLoop          ;loop (unless we hit zero)
23f4: 69 01        :Done           adc     #$01              ;add 1 to make it 1-100
23f6: 60                           rts

                   ; 
                   ; Handles a "GO" command, such as "GO NORTH" or "N".
                   ; 
                   ]dir_index      .var    $f0    {addr/2}

23f7: a9 00        HandleGo        lda     #$00
23f9: 8d 06 1f                     sta     fail_msg_index    ;init failure message index
23fc: ad d8 30                     lda     darkness_flag     ;is this a dark area?
23ff: f0 1d                        beq     :Lit              ;no, branch
2401: 20 93 2e                     jsr     InA_GetIndirectValue ;get pointer to item location data
2404: 26 2f                        .dd2    item_rooms_ptr
2406: a0 12                        ldy     #18               ;lightsource object (#9)
2408: b1 f0                        lda     (]dir_index),y    ;get current location
240a: c9 ff                        cmp     #ITEM_HELD        ;in inventory?
240c: f0 10                        beq     :Lit              ;yes, branch
240e: cd e9 30                     cmp     current_room      ;in current room?
2411: f0 0b                        beq     :Lit              ;yes, branch
2413: 8c 06 1f                     sty     fail_msg_index    ;store nonzero value
2416: 20 54 2e                     jsr     InA_GetInlineData
2419: bf 24                        .dd2    msg_dark_danger
241b: 20 4b 2e                     jsr     JJ_PrintFlashing  ;don't have light, print warning
                   ; 
241e: ad be 30     :Lit            lda     parsed_noun_idx   ;get noun (1-6), or 0 if not specified
2421: 38                           sec
2422: e9 01                        sbc     #$01              ;subtract 1
2424: 10 0b                        bpl     :HaveDir          ;if it went negative, no direction was specified
2426: 20 54 2e                     jsr     InA_GetInlineData
2429: e5 24                        .dd2    msg_need_dir
242b: 20 36 2e                     jsr     JJ_PrintString    ;print "I also need a direction"
242e: 4c 99 24                     jmp     :Return

2431: 85 f0        :HaveDir        sta     ]dir_index        ;save direction index
2433: a9 00                        lda     #$00
2435: 85 f1                        sta     ]dir_index+1      ;set high byte to zero
2437: 20 84 2e                     jsr     JJ_SetF4F5_F0F1   ;copy direction index to $f4-f5
243a: 20 87 2e                     jsr     JJ_AddF0F1_F4F5   ;add it to itself
243d: 20 84 2e                     jsr     JJ_SetF4F5_F0F1   ;copy doubled value to $f4-f5
2440: 20 54 2e                     jsr     InA_GetInlineData ;get pointer to table of pointers to exit tables
2443: 18 2f                        .dd2    vis_exits_n_ptr
2445: 20 87 2e                     jsr     JJ_AddF0F1_F4F5   ;add doubled direction index to it
                   ]ptr            .var    $f0    {addr/2}
                   ]exit_ptr       .var    $f4    {addr/2}

2448: a0 00                        ldy     #$00
244a: b1 f0                        lda     (]ptr),y          ;get pointer low byte from table entry
244c: 85 f4                        sta     ]exit_ptr         ;store in ZP
244e: c8                           iny
244f: b1 f0                        lda     (]ptr),y          ;repeat for high byte
2451: 85 f5                        sta     ]exit_ptr+1       ;now $f4-f5 points to exit table for this direction
2453: 20 93 2e                     jsr     InA_GetIndirectValue ;get current room
2456: e9 30                        .dd2    current_room
2458: 20 87 2e                     jsr     JJ_AddF0F1_F4F5   ;add to exit table pointer
245b: ac e9 30                     ldy     current_room      ;get current room as index (effectively doubling it)
245e: b1 f0                        lda     (]ptr),y          ;get exit room # (just the low byte of 16-bit value)
2460: d0 29                        bne     :ValidExit        ;if nonzero, this is valid
                   ; 
2462: ae 06 1f                     ldx     fail_msg_index    ;is the room dark?
2465: d0 0b                        bne     :DarkFail         ;yes, branch
2467: 20 54 2e                     jsr     InA_GetInlineData
246a: 01 25                        .dd2    msg_cant_go
246c: 20 36 2e                     jsr     JJ_PrintString    ;tell them they can't go that way
246f: 4c 99 24                     jmp     :Return

2472: 20 54 2e     :DarkFail       jsr     InA_GetInlineData ;going the wrong way in the dark is fatal
2475: 9a 24                        .dd2    msg_fell_broke
2477: 20 36 2e                     jsr     JJ_PrintString    ;let them know
247a: a9 00                        lda     #$00
247c: 8d d8 30                     sta     darkness_flag     ;reset darkness flag
247f: ad 73 30                     lda     hdr_max_room      ;limbo room
2482: 8d e9 30                     sta     current_room      ;move them there
2485: 20 15 2e                     jsr     JJ_DescribeRoom   ;redraw room description
2488: 4c 99 24                     jmp     :Return           ;enjoy the afterlife

248b: 8d e9 30     :ValidExit      sta     current_room
248e: 20 54 2e                     jsr     InA_GetInlineData
2491: 69 23                        .dd2    msg_ok
2493: 20 36 2e                     jsr     JJ_PrintString
2496: 20 15 2e                     jsr     JJ_DescribeRoom
2499: 60           :Return         rts

249a: 0d 20 49 20+ msg_fell_broke  .zstr   $0d,‘ I FELL & BROKE MY NECK!’,$0d,‘I'M DEAD!’
                                    +      $0d
24bf: 0d 20 49 54+ msg_dark_danger .zstr   $0d,‘ ITS DANGEROUS TO MOVE IN THE DARK!’,$0d
24e5: 0d 20 49 20+ msg_need_dir    .zstr   $0d,‘ I ALSO NEED A DIRECTION.’,$0d
2501: 0d 20 49 20+ msg_cant_go     .zstr   $0d,‘ I CAN'T GO IN THAT DIRECTION.’,$0d
2522: 00 00 00 00+                 .junk   478

2700: 4c 38 2b                     jmp     Divide16

2703: 4c 0c 27     J_act_oper_tab  jmp     act_oper_tab      ;not used as a jump

2706: 4c 56 27     J_CountHeldObjs jmp     CountHeldObjs

2709: 4c 38 2b     J_Divide16      jmp     Divide16

270c: 7c 27        act_oper_tab    .dd2    O34_Get           ;$34 get ITEM#
270e: a6 27                        .dd2    O35_Drop          ;$35 drop ITEM#
2710: c7 27                        .dd2    O36_MoveTo        ;$36 moveto ROOM#
2712: ff 27                        .dd2    O37_Destroy       ;$37 destroy ITEM#
2714: 15 28                        .dd2    O38_SetDark       ;$38 set_dark
2716: 56 28                        .dd2    O39_ClearDark     ;$39 clear_dark
2718: d4 28                        .dd2    O3A_SetFlag       ;$3a set_flag FLAG#
271a: ff 27                        .dd2    O37_Destroy       ;$3b destroy2 (same as $37)
271c: f2 28                        .dd2    O3C_ClearFlag     ;$3c clear_flag FLAG#
271e: fd 28                        .dd2    O3D_Die           ;$3d die
2720: 20 29                        .dd2    O3E_Put           ;$3e put ITEM#, ROOM#
2722: 4a 29                        .dd2    O3F_GameOver      ;$3f game_over
2724: 66 29                        .dd2    O40_DescribeRoom  ;$40 look
2726: d9 29                        .dd2    O41_Score         ;$41 score
2728: d9 2a                        .dd2    O42_Inventory     ;$42 inventory
272a: dd 2a                        .dd2    O43_Set0          ;$43 set_0
272c: e2 2a                        .dd2    O44_Clear0        ;$44 clear_0
272e: e7 2a                        .dd2    O45_RefillLamp    ;$45 refill_lamp
2730: 06 2b                        .dd2    O46_ClearScreen   ;$46 clear_screen
2732: b5 27                        .dd2    O47_SaveGame      ;$47 save_game
2734: d3 27                        .dd2    O48_Swap          ;$48 swap ITEM#, ITEM#
2736: 0f 28                        .dd2    O49_Continue      ;$49 continue
2738: 96 27                        .dd2    O4A_SuperGet      ;$4a superget ITEM#
273a: 07 2b                        .dd2    O4B_PutWith       ;$4b put_with ITEM#, ITEM#
273c: 66 29                        .dd2    O40_DescribeRoom  ;$4c look2 (same as $40)
273e: 1a 28                        .dd2    O4D_DecreaseCounter ;$4d decrease_counter
2740: 2d 28                        .dd2    O4E_PrintCounter  ;$4e print_counter
2742: 3b 28                        .dd2    O4F_SetCounter    ;$4f set_counter VALUE
2744: 49 28                        .dd2    O50_SwapLocDefault ;$50 swap_loc_default
2746: 5b 28                        .dd2    O51_SelectCounter ;$51 select_counter
2748: 8b 28                        .dd2    O52_AddCounter    ;$52 add_counter
274a: a7 28                        .dd2    O53_SubtractCounter ;$53 subtract_counter
274c: bf 28                        .dd2    O54_PrintNoun     ;$54 print_noun
274e: c8 28                        .dd2    O55_PrintNounNl   ;$55 print_noun_nl
2750: d0 28                        .dd2    O56_Nl            ;$56 nl
2752: df 28                        .dd2    O57_SwapLoc       ;$57 swap_loc ALT#
2754: b9 27                        .dd2    O58_Pause         ;$58 pause

                   ; 
                   ; Counts the number of items in the player's inventory.
                   ; 
                   ; On exit:
                   ;   $f4: number of items
                   ; 
                   • Clear variables
                   ]ptr            .var    $f0    {addr/2}
                   ]counter        .var    $f4    {addr/1}

2756: 20 57 2e     CountHeldObjs   jsr     JJ_PushRegs       ;preserve registers
2759: ae 6f 30                     ldx     hdr_max_item      ;run through full set of items
275c: a9 00                        lda     #$00
275e: 85 f4                        sta     ]counter          ;init count to zero
2760: 20 93 2e                     jsr     InA_GetIndirectValue ;get pointer to item room data
2763: 26 2f                        .dd2    item_rooms_ptr
2765: a0 00                        ldy     #$00
2767: b1 f0        :Loop           lda     (]ptr),y          ;get item's room
2769: c9 ff                        cmp     #ITEM_HELD        ;in player inventory?
276b: d0 02                        bne     :NotHeld          ;no, branch
276d: e6 f4                        inc     ]counter          ;yes, increment count
276f: 20 51 2e     :NotHeld        jsr     JJ_IncF0F1        ;advance pointer
2772: 20 51 2e                     jsr     JJ_IncF0F1        ; twice (16-bit data)
2775: ca                           dex                       ;done yet?
2776: d0 ef                        bne     :Loop             ;no, loop
2778: 20 5a 2e                     jsr     JJ_PopRegs        ;restore registers
277b: 60                           rts

                   ; 
                   ; Action op $34: get item.  Checks to see if inventory is full.
                   ; 
                   ]action_arg     .var    $f0    {addr/2}
                   ]count          .var    $f4    {addr/1}

277c: 20 a5 2e     O34_Get         jsr     JJ_CountHeldObjs  ;get count of held items into $f4
277f: ad 75 30                     lda     hdr_max_held      ;get inventory limit
2782: 38                           sec
2783: e9 01                        sbc     #$01              ;subtract one
2785: c5 f4                        cmp     ]count            ;compare to current count
2787: 10 0d                        bpl     O4A_SuperGet      ;if (max-1) >= count, branch to grab item
2789: 68                           pla                       ;failed, pull return address off stack
278a: 68                           pla
278b: 20 54 2e                     jsr     InA_GetInlineData
278e: a7 29                        .dd2    msg_overburden
2790: 20 36 2e                     jsr     JJ_PrintString    ;display failure message
2793: 4c 06 2e                     jmp     JJ_ActionLoopEnd  ;skip remaining actions

                   ; 
                   ; Action op $4a: get item, regardless of inventory count.
                   ; 
2796: 20 18 2e     O4A_SuperGet    jsr     JJ_GetActionArg   ;item index in $f0-f1
2799: 20 45 2e                     jsr     JJ_GetItemLocation ;get location; puts room pointer in $f0-f1
279c: a9 ff                        lda     #ITEM_HELD        ;put in inventory
279e: a0 00                        ldy     #$00
27a0: 91 f0                        sta     (]action_arg),y   ;update location
27a2: 20 15 2e     :DescribeReturn jsr     JJ_DescribeRoom   ;redraw room description
27a5: 60                           rts

                   ; 
                   ; Action op $35: drop item.
                   ; 
27a6: 20 18 2e     O35_Drop        jsr     JJ_GetActionArg
27a9: 20 45 2e                     jsr     JJ_GetItemLocation ;get location; puts room pointer in $f0-f1
27ac: ad e9 30                     lda     current_room      ;move to current room
27af: a0 00                        ldy     #$00
27b1: 91 f0                        sta     (]action_arg),y   ;update location
27b3: f0 ed                        beq     :DescribeReturn   ;(always)

                   ; 
                   ; Action op $47: save game.
                   ; 
27b5: 20 09 2e     O47_SaveGame    jsr     JJ_SaveGame
27b8: 60                           rts

                   ; 
                   ; Action op $58: pause briefly.  Inner loop is 256*8 cycles, outer loop adds 8
                   ; cycles, total is 256*(8+256*8-1)-1 = 526079.  With the complicated
                   ; initialization call it's about 526355, which is about half a second.
                   ; 
27b9: 20 54 2e     O58_Pause       jsr     InA_GetInlineData ;set $f0-f1 to zero
27bc: 00 00                        .dd2    $0000
27be: e6 f0        :DelayLoop      inc     ]action_arg
27c0: d0 fc                        bne     :DelayLoop
27c2: e6 f1                        inc     ]action_arg+1
27c4: d0 f8                        bne     :DelayLoop
27c6: 60                           rts

                   ; 
                   ; Action op $36: move to specified room.
                   ; 
27c7: 20 18 2e     O36_MoveTo      jsr     JJ_GetActionArg   ;get argument in $f0-f1
27ca: a5 f0                        lda     ]action_arg
27cc: 8d e9 30                     sta     current_room      ;set current room
27cf: 20 15 2e     :RedrawReturn   jsr     JJ_DescribeRoom   ;redraw room description
27d2: 60                           rts

                   ; 
                   ; Action op $48: swap the locations of two items.
                   ; 
                   ; If both items are in the current room, the screen will be redrawn twice.
                   ; 
                   ]item2_loc      .var    $f0    {addr/2}
                   ]item1_loc      .var    $f2    {addr/2}

27d3: 20 18 2e     O48_Swap        jsr     JJ_GetActionArg   ;get argument in $f0-f1
27d6: 20 45 2e                     jsr     JJ_GetItemLocation ;get location ptr in $f0-f1
27d9: 20 5d 2e                     jsr     JJ_PushF0F1       ;push item #1 location ptr
27dc: 20 18 2e                     jsr     JJ_GetActionArg   ;get argument in $f0-f1
27df: 20 45 2e                     jsr     JJ_GetItemLocation ;get item #2 location ptr in $f0-f1
27e2: 20 78 2e                     jsr     JJ_PopF2F3        ;pop item #1 location ptr into $f2-f3
27e5: 48                           pha                       ;push room # of item #2
27e6: a0 00                        ldy     #$00
27e8: b1 f2                        lda     (]item1_loc),y    ;get location of item #1
27ea: 91 f0                        sta     (]item2_loc),y    ;move item #2 there
27ec: 68                           pla                       ;pull room # of item #2
27ed: 91 f2                        sta     (]item1_loc),y    ;move item #1 there
27ef: cd e9 30                     cmp     current_room      ;is item #1 now in the current room?
27f2: d0 03                        bne     :NotHere1         ;no, branch
27f4: 20 15 2e                     jsr     JJ_DescribeRoom   ;yes, redraw room description
27f7: b1 f0        :NotHere1       lda     (]item2_loc),y
27f9: cd e9 30                     cmp     current_room      ;is item #2 now in the current room?
27fc: f0 d1                        beq     :RedrawReturn     ;yes, redraw room description
27fe: 60                           rts

                   ; 
                   ; Action op $37: destroy item (move to room zero).
                   ; 
                   ]ptr            .var    $f0    {addr/2}

27ff: 20 18 2e     O37_Destroy     jsr     JJ_GetActionArg   ;get argument in $f0-f1
2802: 20 45 2e                     jsr     JJ_GetItemLocation ;get location ptr in $f0-f1
2805: a9 00                        lda     #$00              ;nowhere
2807: a0 00                        ldy     #$00
2809: 91 f0                        sta     (]ptr),y          ;set location
280b: 20 15 2e                     jsr     JJ_DescribeRoom   ;redraw room description
280e: 60                           rts

                   ; 
                   ; Action $49: continue into next action slot.
                   ; 
280f: a9 ff        O49_Continue    lda     #$ff
2811: 8d c4 30                     sta     continue_flag     ;set flag, read by action loop
2814: 60                           rts

                   ; 
                   ; Action $38: set the darkness flag (#15).
                   ; 
2815: a0 0f        O38_SetDark     ldy     #15               ;set flag 15
2817: 4c d9 28                     jmp     SetFlagN

                   ; 
                   ; Action $4d: decrease current counter.
                   ; 
                   ]counter_value  .var    $f0    {addr/2}

                   O4D_DecreaseCounter
281a: 20 93 2e                     jsr     InA_GetIndirectValue ;get value of "current counter" in $f0-f1
281d: c7 30                        .dd2    counter_register
281f: 20 4e 2e                     jsr     JJ_DecF0F1        ;decrement it
2822: a5 f0                        lda     ]counter_value    ;save it
2824: 8d c7 30                     sta     counter_register
2827: a5 f1                        lda     ]counter_value+1
2829: 8d c8 30                     sta     counter_register+1
282c: 60                           rts

                   ; 
                   ; Action $4e: print current counter.
                   ; 
                   O4E_PrintCounter
282d: 20 93 2e                     jsr     InA_GetIndirectValue ;get value of "current counter" in $f0-f1
2830: c7 30                        .dd2    counter_register
2832: 20 48 2e                     jsr     JJ_PrintSignedDec ;print as signed decimal
2835: a9 20                        lda     #‘ ’
2837: 20 30 2e                     jsr     JJ_PrintNonNull   ;add a space
283a: 60                           rts

                   ; 
                   ; Action $4f: set value of current counter.
                   ; 
283b: 20 18 2e     O4F_SetCounter  jsr     JJ_GetActionArg   ;get new value in $f0-f1
283e: a5 f0                        lda     ]counter_value    ;copy value to "current counter"
2840: 8d c7 30                     sta     counter_register
2843: a5 f1                        lda     ]counter_value+1
2845: 8d c8 30                     sta     counter_register+1
2848: 60                           rts

                   ; 
                   ; Action $50: swaps "current" and "default alternate" locations.
                   ; 
                   O50_SwapLocDefault
2849: ad e9 30                     lda     current_room
284c: ac eb 30                     ldy     def_alt_room
284f: 8c e9 30                     sty     current_room
2852: 8d eb 30                     sta     def_alt_room
2855: 60                           rts

                   ; 
                   ; Action $39: clear darkness flag.
                   ; 
2856: a0 0f        O39_ClearDark   ldy     #15               ;clear flag 15
2858: 4c f7 28                     jmp     ClearFlagN

                   ; 
                   ; Action $51: swap current counter with numbered storage location.
                   ; 
                   ; Most docs refer to this as "selecting" a counter, but it's more like swapping
                   ; the contents of the "current counter" register with a value in RAM.
                   ; 
                   ]ptr            .var    $f0    {addr/2}

                   O51_SelectCounter
285b: 20 18 2e                     jsr     JJ_GetActionArg   ;get argument in $f0-f1
285e: 20 84 2e                     jsr     JJ_SetF4F5_F0F1   ;copy to $f4-f5
2861: 20 87 2e                     jsr     JJ_AddF0F1_F4F5   ;double it
2864: 20 84 2e                     jsr     JJ_SetF4F5_F0F1   ;copy doubled value to $f4-f5
2867: 20 54 2e                     jsr     InA_GetInlineData ;get pointer to counter storage
286a: f1 30                        .dd2    game_counters
286c: 20 87 2e                     jsr     JJ_AddF0F1_F4F5   ;add doubled arg
                   ; 
286f: a0 00                        ldy     #$00
2871: ad c7 30                     lda     counter_register  ;get current value
2874: 48                           pha                       ;push on stack
2875: b1 f0                        lda     (]ptr),y          ;get value from counter array
2877: 8d c7 30                     sta     counter_register  ;replace current value
287a: 68                           pla                       ;pull previous current value from stack
287b: 91 f0                        sta     (]ptr),y          ;store into array
287d: c8                           iny                       ;repeat for high byte
287e: b1 f0                        lda     (]ptr),y
2880: 48                           pha
2881: ad c8 30                     lda     counter_register+1
2884: 91 f0                        sta     (]ptr),y
2886: 68                           pla
2887: 8d c8 30                     sta     counter_register+1
288a: 60                           rts

                   ; 
                   ; Action $52: add argument to the "current counter".
                   ; 
                   ]new_value      .var    $f0    {addr/2}

288b: 20 18 2e     O52_AddCounter  jsr     JJ_GetActionArg   ;get argument in $f0-f1
288e: 20 84 2e                     jsr     JJ_SetF4F5_F0F1   ;copy to $f4-f5
2891: 20 93 2e                     jsr     InA_GetIndirectValue ;get current counter value
2894: c7 30                        .dd2    counter_register
2896: 20 87 2e                     jsr     JJ_AddF0F1_F4F5   ;add argument to it
2899: a0 00                        ldy     #$00              ;?
289b: a5 f0                        lda     ]new_value        ;copy new value to the counter
289d: 8d c7 30                     sta     counter_register
28a0: c8                           iny                       ;?
28a1: a5 f1                        lda     ]new_value+1
28a3: 8d c8 30                     sta     counter_register+1
28a6: 60                           rts

                   ; 
                   ; Action $53: subtract argument from the "current counter".
                   ; 
                   O53_SubtractCounter
28a7: 20 18 2e                     jsr     JJ_GetActionArg   ;get argument in $f0-f1
28aa: a0 00                        ldy     #$00              ;?
28ac: 38                           sec
28ad: ad c7 30                     lda     counter_register  ;do the subtraction manually
28b0: e5 f0                        sbc     ]new_value
28b2: 8d c7 30                     sta     counter_register
28b5: c8                           iny                       ;?
28b6: ad c8 30                     lda     counter_register+1
28b9: e5 f1                        sbc     ]new_value+1
28bb: 8d c8 30                     sta     counter_register+1
28be: 60                           rts

                   ; 
                   ; Action op $54: prints the noun the user typed.
                   ; 
                   ; The command parser left the noun, with whitespace trimmed away, in the trim
                   ; buffer.
                   ; 
28bf: 20 54 2e     O54_PrintNoun   jsr     InA_GetInlineData ;get pointer to trim buf
28c2: 80 30                        .dd2    word_trim_buf
28c4: 20 36 2e                     jsr     JJ_PrintString    ;print it
28c7: 60                           rts

                   ; 
                   ; Action op $55: print the noun the user typed, then a newline.
                   ; 
28c8: 20 54 2e     O55_PrintNounNl jsr     InA_GetInlineData ;get pointer to trim buf
28cb: 80 30                        .dd2    word_trim_buf
28cd: 20 36 2e                     jsr     JJ_PrintString    ;print it, fall through to print newline
                   ; 
                   ; Action op $56: print a newline.
                   ; 
28d0: 20 33 2e     O56_Nl          jsr     JJ_PrintCR        ;print a newline
28d3: 60                           rts

                   ; 
                   ; Action op $3a: set flag to true.
                   ; 
                   ]arg_val        .var    $f0    {addr/2}

28d4: 20 18 2e     O3A_SetFlag     jsr     JJ_GetActionArg   ;get arg in $f0-f1
28d7: a4 f0                        ldy     ]arg_val          ;use low byte as index
                   ; Sets game flag N, specified by Y-reg.
28d9: a9 ff        SetFlagN        lda     #$ff
28db: 99 c9 30                     sta     action_flags,y    ;set flag
28de: 60                           rts

                   ; 
                   ; Action op $57: swap the player's current location with the Nth alternate room
                   ; slot.
                   ; 
                   ; NOTE: this is using the action argument as a pointer.  Since the argument is a
                   ; small integer, this will use low zero-page addresses for storage, which is bad
                   ; since it won't be saved/restored.  Another weird thing is that it's using the
                   ; room number from the default alt slot as an index.  (Compare to implementation
                   ; of O50_SwapLocDefault at $2849.)
                   ; 
                   ; I suspect this is broken, but I haven't found a game that uses it.
                   ; 
28df: 20 18 2e     O57_SwapLoc     jsr     JJ_GetActionArg   ;get action argument (should be alt room slot number)
28e2: ac eb 30                     ldy     def_alt_room      ;get default alt room number
28e5: b1 f0                        lda     (]arg_val),y      ;get ?!
28e7: 48                           pha
28e8: ad e9 30                     lda     current_room      ;get current room
28eb: 91 f0                        sta     (]arg_val),y      ;store ?!
28ed: 68                           pla
28ee: 8d e9 30                     sta     current_room      ;update current room
28f1: 60                           rts

                   ; 
                   ; Action op $3c: clear flag.
                   ; 
28f2: 20 18 2e     O3C_ClearFlag   jsr     JJ_GetActionArg   ;get arg in $f0-f1
28f5: a4 f0                        ldy     ]arg_val          ;use low byte as index
                   ; Clears game flag N, specified by Y-reg.
28f7: a9 00        ClearFlagN      lda     #$00
28f9: 99 c9 30                     sta     action_flags,y    ;clear flag
28fc: 60                           rts

                   ; 
                   ; Action op $3d: die.
                   ; 
28fd: 20 54 2e     O3D_Die         jsr     InA_GetInlineData
2900: 14 29                        .dd2    msg_im_dead
2902: 20 36 2e                     jsr     JJ_PrintString    ;print "I'm dead" message
2905: ad 73 30                     lda     hdr_max_room      ;get last room defined (limbo)
2908: 8d e9 30                     sta     current_room      ;make current
290b: a9 00                        lda     #$00
290d: 8d d8 30                     sta     darkness_flag     ;clear darkness flag
2910: 20 15 2e                     jsr     JJ_DescribeRoom   ;redraw room description
2913: 60                           rts

2914: 20 49 27 4d+ msg_im_dead     .zstr   ‘ I'M DEAD!’,$0d

                   ; 
                   ; Action op $3e: put item in specified room.
                   ; 
2920: 20 18 2e     O3E_Put         jsr     JJ_GetActionArg   ;get item # arg
2923: 20 45 2e                     jsr     JJ_GetItemLocation ;get item location ptr in $f0-f1
2926: 20 5d 2e                     jsr     JJ_PushF0F1       ;push that
2929: 20 18 2e                     jsr     JJ_GetActionArg   ;get room # arg
292c: 20 78 2e                     jsr     JJ_PopF2F3        ;pop item location ptr into $f2-f3
                   ; 
292f: a0 00                        ldy     #$00
2931: b1 f2                        lda     (]item1_loc),y    ;get item's current location
2933: 48                           pha                       ;save on stack
2934: a5 f0                        lda     ]arg_val          ;get new room #
2936: 91 f2                        sta     (]item1_loc),y    ;move item there
2938: cd e9 30                     cmp     current_room      ;is current room the new room?
293b: d0 03                        bne     :NotNew           ;no, branch
293d: 20 15 2e                     jsr     JJ_DescribeRoom   ;redraw room description
2940: 68           :NotNew         pla                       ;pull item's previous room #
2941: cd e9 30                     cmp     current_room      ;was it in this room?
2944: d0 03                        bne     :Return           ;no, branch
2946: 20 15 2e                     jsr     JJ_DescribeRoom   ;redraw room description
2949: 60           :Return         rts

                   ; 
                   ; Action op $3f: game over.  Inform the user and ask if they want to play again.
                   ; 
294a: 20 54 2e     O3F_GameOver    jsr     InA_GetInlineData
294d: 6a 29                        .dd2    msg_advent_over
294f: 20 36 2e                     jsr     JJ_PrintString    ;print game over, ask if they want to go again
2952: 20 39 2e                     jsr     JJ_GetInput       ;get input
2955: ad 33 2f                     lda     kbd_scratch_buf
2958: c9 4e                        cmp     #‘N’              ;no?
295a: d0 03                        bne     :NotN
295c: 4c 59 ff                     jmp     MON_OLDRST        ;exit to monitor

295f: c9 59        :NotN           cmp     #‘Y’              ;yes?
2961: d0 e7                        bne     O3F_GameOver
2963: 4c 2d 2e                     jmp     J_Start           ;restart game

                   ; 
                   ; Action op $40: describe room.
                   ; 
                   O40_DescribeRoom
2966: 20 15 2e                     jsr     JJ_DescribeRoom   ;redraw room description
2969: 60                           rts

296a: 20 54 48 49+ msg_advent_over .zstr   ‘ THIS ADVENTURE IS OVER.’,$0d,‘ WANT TO TRY TH’
                                    +      ‘IS ADVENTURE AGAIN? ’
29a7: 0d 20 49 27+ msg_overburden  .zstr   $0d,‘ I'M CARRYING TOO MUCH.’,$0d,‘ TRY: "TAKE ’
                                    +      ‘INVENTORY"’,$0d,$0d

                   ; 
                   ; Action op $41: display score.
                   ; 
                   ; If all treasures are in the treasure room, this will print the victory message
                   ; and jump to the game-over handler.
                   ; 
                   ; (preserves X-reg)
                   ; 
                   • Clear variables
                   ]name_ptr       .var    $f0    {addr/2}
                   ]str_ptr        .var    $f2    {addr/2}
                   ]tr_count       .var    $f4    {addr/1}
                   ]room_ptr       .var    $f8    {addr/2}

29d9: a9 00        O41_Score       lda     #$00              ;init treasure counter
29db: 85 f4                        sta     ]tr_count
29dd: 8a                           txa                       ;preserve X-reg (why?)
29de: 48                           pha
29df: ae 6f 30                     ldx     hdr_max_item      ;get max item #
29e2: e8                           inx                       ;add one to make it a count
29e3: 20 9c 2e                     jsr     JJ_PushF8F9       ;preserve $f8-f9
29e6: 20 93 2e                     jsr     InA_GetIndirectValue ;get pointer to item room data
29e9: 26 2f                        .dd2    item_rooms_ptr
29eb: 20 5d 2e                     jsr     JJ_PushF0F1       ;copy $f0-f1...
29ee: 20 9f 2e                     jsr     JJ_PopF8F9        ;...into $f8-f9
29f1: 20 93 2e                     jsr     InA_GetIndirectValue ;get pointer to item name data
29f4: 28 2f                        .dd2    item_names_ptr
                   ; 
29f6: a0 00        :CountLoop      ldy     #$00
29f8: b1 f0                        lda     (]name_ptr),y     ;get pointer to name, low byte
29fa: 85 f2                        sta     ]str_ptr          ;copy into $f2
29fc: 20 51 2e                     jsr     JJ_IncF0F1        ;advance ptr
29ff: b1 f0                        lda     (]name_ptr),y     ;repeat for high byte
2a01: 85 f3                        sta     ]str_ptr+1
2a03: 20 51 2e                     jsr     JJ_IncF0F1
2a06: 20 6c 2e                     jsr     JJ_IncF2F3        ;step over length byte
2a09: b1 f2                        lda     (]str_ptr),y      ;get first char of name
2a0b: c9 2a                        cmp     #‘*’              ;is this a treasure item?
2a0d: d0 09                        bne     :NotTreasure      ;no, branch
2a0f: ad 7e 30                     lda     hdr_treasure_room ;is it in the treasure room?
2a12: d1 f8                        cmp     (]room_ptr),y
2a14: d0 02                        bne     :NotTreasure      ;no, branch
2a16: e6 f4                        inc     ]tr_count         ;yes, this one counts
2a18: 20 a2 2e     :NotTreasure    jsr     JJ_IncF8F9        ;advance room pointer to next room
2a1b: 20 a2 2e                     jsr     JJ_IncF8F9
2a1e: ca                           dex                       ;done yet?
2a1f: d0 d5                        bne     :CountLoop        ;no, loop
                   ; 
                   ]count16        .var    $f0    {addr/2}

2a21: 20 9f 2e                     jsr     JJ_PopF8F9        ;restore $f8-f9
2a24: 20 54 2e                     jsr     InA_GetInlineData
2a27: 88 2a                        .dd2    msg_i_stored
2a29: 20 36 2e                     jsr     JJ_PrintString    ;print "I stored"
2a2c: a5 f4                        lda     ]tr_count         ;copy treasure count to $f0-f1
2a2e: 85 f0                        sta     ]count16
2a30: 48                           pha                       ;stash count on stack
2a31: a9 00                        lda     #$00              ;high byte always 0 (max 255 treasures)
2a33: 85 f1                        sta     ]count16+1
2a35: 20 48 2e                     jsr     JJ_PrintSignedDec ;print count
2a38: 20 54 2e                     jsr     InA_GetInlineData
2a3b: 93 2a                        .dd2    msg_treasures
2a3d: 20 36 2e                     jsr     JJ_PrintString    ;print "treasures"
2a40: 20 54 2e                     jsr     InA_GetInlineData
2a43: a0 2a                        .dd2    msg_scale_of
2a45: 20 36 2e                     jsr     JJ_PrintString    ;"on scale of 0-100"...
                   ; Compute score.  We add 100 for every treasure we've found and stored, then
                   ; divide by the max number of treasures.
                   ]score          .var    $f0    {addr/2}

2a48: a9 00                        lda     #$00
2a4a: 85 f0                        sta     ]score
2a4c: 85 f1                        sta     ]score+1
2a4e: a6 f4                        ldx     ]tr_count
2a50: f0 1c                        beq     :NoTreasure       ;avoid divide-by-zero
2a52: 20 54 2e                     jsr     InA_GetInlineData
2a55: 64 00                        .dd2    100
2a57: 20 84 2e                     jsr     JJ_SetF4F5_F0F1   ;set $f4-f5 to 100
2a5a: ca                           dex
2a5b: f0 06                        beq     :OneTreasure
2a5d: 20 87 2e     :AddLoop        jsr     JJ_AddF0F1_F4F5   ;$f0-f1 += $f4-f5
2a60: ca                           dex
2a61: d0 fa                        bne     :AddLoop
2a63: 20 81 2e     :OneTreasure    jsr     JJ_SetF2F3_F0F1   ;set $f2-f3 to $f0-f1 (found * 100)
2a66: 20 93 2e                     jsr     InA_GetIndirectValue ;set $f0-f1 to number of treasures
2a69: 79 30                        .dd2    hdr_num_treasures
2a6b: 20 21 2e                     jsr     JJ_Divide16       ;divide, quotient in $f0-f1
2a6e: 20 48 2e     :NoTreasure     jsr     JJ_PrintSignedDec ;print score
2a71: 20 33 2e                     jsr     JJ_PrintCR
2a74: 68                           pla                       ;pull saved count off stack
2a75: cd 79 30                     cmp     hdr_num_treasures ;compare to max treasures
2a78: f0 03                        beq     :Victory          ;it matches, game won; branch
2a7a: 68                           pla                       ;restore X-reg
2a7b: aa                           tax
2a7c: 60                           rts

2a7d: 20 54 2e     :Victory        jsr     InA_GetInlineData
2a80: bc 2a                        .dd2    msg_victory
2a82: 20 36 2e                     jsr     JJ_PrintString    ;print victory message
2a85: 4c 4a 29                     jmp     O3F_GameOver      ;jump to game-over handler

2a88: 20 49 20 53+ msg_i_stored    .zstr   ‘ I STORED ’
2a93: 20 54 52 45+ msg_treasures   .zstr   ‘ TREASURES.’,$0d
2aa0: 4f 4e 20 41+ msg_scale_of    .zstr   ‘ON A SCALE OF 0-100 THATS: ’
2abc: 20 46 41 4e+ msg_victory     .zstr   ‘ FANTASTIC! YOU'VE DONE IT!’,$0d

                   ; 
                   ; Action $42: show inventory.
                   ; 
2ad9: 20 0f 2e     O42_Inventory   jsr     JJ_ShowInventory
2adc: 60                           rts

                   ; 
                   ; Action $43: set flag 0 to true.
                   ; 
2add: a0 00        O43_Set0        ldy     #$00
2adf: 4c d9 28                     jmp     SetFlagN          ;set flag #0

                   ; 
                   ; Action $44: clear flag 0.
                   ; 
2ae2: a0 00        O44_Clear0      ldy     #$00
2ae4: 4c f7 28                     jmp     ClearFlagN        ;clear flag #0

                   ; 
                   ; Action op $45: refill lightsource.
                   ; 
                   ]ptr            .var    $f0    {addr/2}

2ae7: ad 7b 30     O45_RefillLamp  lda     hdr_lamp_capacity ;reset lamp fuel level to max
2aea: 8d 01 31                     sta     lamp_fuel_level
2aed: ad 7c 30                     lda     hdr_lamp_capacity+1
2af0: 8d 02 31                     sta     lamp_fuel_level+1
2af3: 20 93 2e                     jsr     InA_GetIndirectValue ;get pointer to $42ff
2af6: 26 2f                        .dd2    item_rooms_ptr
2af8: a0 12                        ldy     #18               ;lamp is always object 9
2afa: a9 ff                        lda     #ITEM_HELD
2afc: 91 f0                        sta     (]ptr),y          ;add lightsource object to inventory
2afe: a9 00                        lda     #$00              ; (in case torch disappeared when it went out?)
2b00: 8d d9 30                     sta     lamp_empty_flag   ;clear lamp-empty flag
2b03: 20 15 2e                     jsr     JJ_DescribeRoom   ;redraw room description
                   ; 
                   ; Action op $45: clear screen.  (This is a no-op.)
                   ; 
2b06: 60           O46_ClearScreen rts

                   ; 
                   ; Action op $4b: put item A in the same location as item B.
                   ; 
                   ; If item A and item B are in the same location, we will redraw the room
                   ; description twice.
                   ; 
2b07: 20 18 2e     O4B_PutWith     jsr     JJ_GetActionArg   ;get item A index in $f0-f1
2b0a: 20 45 2e                     jsr     JJ_GetItemLocation ;get pointer to item A room data in $f0-f1
2b0d: 20 5d 2e                     jsr     JJ_PushF0F1       ;push on stack
2b10: 20 18 2e                     jsr     JJ_GetActionArg   ;get item B index in $f0-f1
2b13: 20 45 2e                     jsr     JJ_GetItemLocation ;get item B room # in A-reg
2b16: 20 60 2e                     jsr     JJ_PopF0F1        ;restore $f0-f1
2b19: a0 00                        ldy     #$00
2b1b: cd e9 30                     cmp     current_room      ;is item B (destination) in the current room?
2b1e: d0 03                        bne     :NotCur           ;no, branch
2b20: 20 15 2e                     jsr     JJ_DescribeRoom   ;yes, redraw room description
2b23: 48           :NotCur         pha                       ;save item B (destination) room
2b24: b1 f0                        lda     (]ptr),y          ;get item A's room
2b26: 8d 99 30                     sta     div_q_tmp         ;save it
2b29: 68                           pla                       ;restore item B's room
2b2a: 91 f0                        sta     (]ptr),y          ;set item A's location to that
2b2c: ad 99 30                     lda     div_q_tmp         ;get item A's original location
2b2f: cd e9 30                     cmp     current_room      ;was it in the current room?
2b32: d0 03                        bne     :Return           ;no, branch
2b34: 20 15 2e                     jsr     JJ_DescribeRoom   ;yes, redraw room description
2b37: 60           :Return         rts

                   ; 
                   ; Computes $f2-f3 / $f0-f1.
                   ; 
                   ; On exit:
                   ;   $f0-f1: quotient
                   ;   $f2-f3: remainder
                   ; 
                   ; (preserves all registers)
                   ; 
                   • Clear variables
                   ]denom          .var    $f0    {addr/2}
                   ]numer          .var    $f2    {addr/2}

2b38: 20 57 2e     Divide16        jsr     JJ_PushRegs       ;preserve registers
2b3b: a2 10                        ldx     #16
2b3d: 20 6f 2e                     jsr     JJ_PushF4F5       ;preserve $f4-f5 (why?)
2b40: a9 00                        lda     #$00
2b42: 8d 99 30                     sta     div_q_tmp
2b45: 8d 9a 30                     sta     div_q_tmp+1
2b48: 8d 9b 30                     sta     div_r_tmp
2b4b: 8d 9c 30                     sta     div_r_tmp+1
2b4e: 0e 99 30     :Loop           asl     div_q_tmp
2b51: 2e 9a 30                     rol     div_q_tmp+1
2b54: 06 f2                        asl     ]numer
2b56: 26 f3                        rol     ]numer+1
2b58: 2e 9b 30                     rol     div_r_tmp
2b5b: 2e 9c 30                     rol     div_r_tmp+1
2b5e: 20 5d 2e                     jsr     JJ_PushF0F1       ;save denominator
2b61: 38                           sec
2b62: a5 f0                        lda     ]denom
2b64: ed 9b 30                     sbc     div_r_tmp
2b67: 85 f0                        sta     ]denom
2b69: a5 f1                        lda     ]denom+1
2b6b: ed 9c 30                     sbc     div_r_tmp+1
2b6e: 85 f1                        sta     ]denom+1
2b70: 05 f0                        ora     ]denom
2b72: f0 04                        beq     :Den0
2b74: a5 f1                        lda     ]denom+1
2b76: 10 17                        bpl     :DenPos
2b78: ee 99 30     :Den0           inc     div_q_tmp
2b7b: d0 03                        bne     :NoInc
2b7d: ee 9a 30                     inc     div_q_tmp+1
2b80: 38           :NoInc          sec
2b81: a9 00                        lda     #$00
2b83: e5 f0                        sbc     ]denom
2b85: 8d 9b 30                     sta     div_r_tmp
2b88: a9 00                        lda     #$00
2b8a: e5 f1                        sbc     ]denom+1
2b8c: 8d 9c 30                     sta     div_r_tmp+1
2b8f: 20 60 2e     :DenPos         jsr     JJ_PopF0F1        ;restore denominator
2b92: ca                           dex                       ;done all bits?
2b93: d0 b9                        bne     :Loop             ;no, branch
                   ; 
2b95: ad 99 30                     lda     div_q_tmp         ;copy results to zero page
2b98: 85 f0                        sta     ]denom
2b9a: ad 9a 30                     lda     div_q_tmp+1
2b9d: 85 f1                        sta     ]denom+1
2b9f: ad 9b 30                     lda     div_r_tmp
2ba2: 85 f2                        sta     ]numer
2ba4: ad 9c 30                     lda     div_r_tmp+1
2ba7: 85 f3                        sta     ]numer+1
2ba9: 20 72 2e                     jsr     JJ_PopF4F5        ;restore $f4-f5
2bac: 20 5a 2e                     jsr     JJ_PopRegs        ;restore registers
2baf: 60                           rts

2bb0: 00 00 00 00+                 .junk   592

2e00: 4c 00 08                     jmp     Entry

                   JJ_ProcessActions
2e03: 4c 00 1f                     jmp     J_ProcessActions  ;process actions and occurrences

                   JJ_ActionLoopEnd
2e06: 4c 03 1f                     jmp     J_ActionLoopEnd   ;jump to end of action scan loop

2e09: 4c 09 17     JJ_SaveGame     jmp     J_SaveGame        ;save the game

2e0c: 4c                           .dd1    $4c               ;not used as a jump
                   cond_handlers_ind
2e0d: 0c 17                        .dd2    J_CondHandlers

                   JJ_ShowInventory
2e0f: 4c 03 17                     jmp     J_ShowInventory   ;print the player's inventory

                   JJ_PrintItemName
2e12: 4c 15 17                     jmp     J_PrintItemName   ;print the name of an item

2e15: 4c 00 17     JJ_DescribeRoom jmp     J_DescribeRoom    ;redraw room description

2e18: 4c 06 17     JJ_GetActionArg jmp     J_GetActionArg    ;$f0-f1 = action argument

                   JJ_AskDiskOrTape
2e1b: 4c 0f 17                     jmp     J_AskDiskOrTape   ;ask player: "disk or tape?"

                   JJ_PrintStringCOUT
2e1e: 4c 12 17                     jmp     J_PrintStringCOUT ;print null-terminated string through COUT routine

2e21: 4c 09 27     JJ_Divide16     jmp     J_Divide16        ;$f0-f1 = $f2-f3 / $f0-f1 (rem in $f2-f3)

2e24: 4c a8 2e                     jmp     NopRts

2e27: 4c a8 2e                     jmp     NopRts

2e2a: 4c                           .dd1    $4c
2e2b: 03 27        act_oper_ind    .dd2    J_act_oper_tab

2e2d: 4c 00 08     J_Start         jmp     Entry             ;begin (or restart)

2e30: 4c 03 08     JJ_PrintNonNull jmp     J_PrintNonNull    ;prints char ($01-7f) unless it's $00

2e33: 4c 06 08     JJ_PrintCR      jmp     J_PrintCR         ;prints CR (clear to EOL, move to start of new line)

2e36: 4c 0f 08     JJ_PrintString  jmp     J_PrintString     ;prints a null-terminated string ($f0-f1)

2e39: 4c 15 08     JJ_GetInput     jmp     J_GetInput        ;get player input into key buffer

2e3c: 4c 18 08     JJ_ClearScreen  jmp     J_ClearScreen     ;clear screen

2e3f: 4c 0c 08     JJ_PrintNChars  jmp     J_PrintNChars     ;print the next N chars

2e42: 4c 09 08     JJ_PrintL1Str   jmp     J_PrintL1Str      ;print a string start starts with a len byte

                   JJ_GetItemLocation
2e45: 4c 1e 08                     jmp     J_GetItemLocation ;$f0-f1 point into room data; A-reg=room#

                   JJ_PrintSignedDec
2e48: 4c 1b 08                     jmp     J_PrintSignedDec  ;print $f0-f1 as decimal value

                   JJ_PrintFlashing
2e4b: 4c 12 08                     jmp     J_PrintFlashStr   ;print null-terminated string ($f0-f1), flash mode

2e4e: 4c 24 14     JJ_DecF0F1      jmp     J_DecF0F1         ;$f0-f1 --

2e51: 4c 1b 14     JJ_IncF0F1      jmp     J_IncF0F1         ;$f0-f1 ++

                   InA_GetInlineData
2e54: 4c 3c 14                     jmp     J_GetInlineData   ;$f0-f1 = inline (copy in $fc-fd)

2e57: 4c 21 08     JJ_PushRegs     jmp     J_PushRegs        ;AXYP -> stack

2e5a: 4c 24 08     JJ_PopRegs      jmp     J_PopRegs         ;stack -> AXYP

2e5d: 4c 03 14     JJ_PushF0F1     jmp     J_PushF0F1        ;$f0-f1 -> stack

2e60: 4c 06 14     JJ_PopF0F1      jmp     J_PopF0F1         ;stack -> $f0-f1

2e63: 4c 27 14     JJ_DecF4F5      jmp     J_DecF4F5         ;$f4-f5 --

2e66: 4c 1e 14     JJ_IncF4F5      jmp     J_IncF4F5         ;$f4-f5 ++

2e69: 4c 2a 14     JJ_DecF2F3      jmp     J_DecF2F3         ;$f2-f3 --

2e6c: 4c 21 14     JJ_IncF2F3      jmp     J_IncF2F3         ;$f2-f3 ++

2e6f: 4c 09 14     JJ_PushF4F5     jmp     J_PushF4F5        ;$f4-f5 -> stack

2e72: 4c 0c 14     JJ_PopF4F5      jmp     J_PopF4F5         ;stack -> $f4-f5

2e75: 4c 0f 14     JJ_PushF2F3     jmp     J_PushF2F3        ;$f2-f3 -> stack

2e78: 4c 12 14     JJ_PopF2F3      jmp     J_PopF2F3         ;stack -> $f2-f3

2e7b: 4c 33 14     InA_SubF0F1_Ind jmp     J_SubF0F1_Ind     ;$fa-fb = $f0-f1 - (*inline); N/Z/C set

                   InA_SubF0F1_Inline
2e7e: 4c 36 14                     jmp     J_SubF0F1_Inline  ;$fa-fb = $f0-f1 - inline; N/Z/C set

2e81: 4c 2d 14     JJ_SetF2F3_F0F1 jmp     J_SetF2F3_F0F1    ;$f2-f3 = $f0-f1

2e84: 4c 30 14     JJ_SetF4F5_F0F1 jmp     J_SetF4F5_F0F1    ;$f4-f5 = $f0-f1

2e87: 4c 39 14     JJ_AddF0F1_F4F5 jmp     J_AddF0F1_F4F5    ;$f0-f1 += $f4-f5

                   JJ_PushFullState
2e8a: 4c 15 14                     jmp     J_PushFullState   ;AXYP $f0-f9 -> stack

2e8d: 4c 18 14     JJ_PopFullState jmp     J_PopFullState    ;stack -> AXYP $f0-f9

                   InA_SetIndirectValue
2e90: 4c 00 14                     jmp     J_SetIndirectValue ;(*inline) = $f0-f1

                   InA_GetIndirectValue
2e93: 4c 3f 14                     jmp     J_GetIndirectValue ;$f0-f1 = (*inline)

2e96: 4c 42 14     JJ_PushF6F7     jmp     J_PushF6F7        ;$f6-f7 -> stack

2e99: 4c 45 14     JJ_PopF6F7      jmp     J_PopF6F7         ;stack -> $f6-f7

2e9c: 4c 48 14     JJ_PushF8F9     jmp     J_PushF8F9        ;$f8-f9 -> stack

2e9f: 4c 4b 14     JJ_PopF8F9      jmp     J_PopF8F9         ;stack -> $f8-f9

2ea2: 4c 4e 14     JJ_IncF8F9      jmp     J_IncF8F9         ;$f8-f9 ++

                   JJ_CountHeldObjs
2ea5: 4c 06 27                     jmp     J_CountHeldObjs   ;$f4 = number of objects in inventory

2ea8: ea           NopRts          nop
2ea9: 60                           rts

2eaa: 00                           .dd1    $00
2eab: 00           regsv_tmp_a     .dd1    $00               ;temporary storage
2eac: 32           regsv_tmp_p     .dd1    $32               ;temporary storage
2ead: 63 16        regsv_ret_addr  .dd2    $1663             ;temporary storage
2eaf: 01           noflash_flag    .dd1    $01               ;used for text output
2eb0: bc f4        kbd_rng_seed    .dd2    $f4bc             ;random number seed, updated while waiting for key
2eb2: 01           use_disk_flag   .dd1    $01               ;0=tape, 1=disk
2eb3: 00 00 00 00+                 .align  $0100 (77 bytes)
                   ; 
                   ; Pointers to tables.
                   ; 
2f00: df 44        action_verb_ptr .dd2    action_verb       ;pointer to table with verb indices for actions
                   action_nou_prc_ptr
2f02: db 45                        .dd2    action_nou_prc    ;pointer to table with noun or percent values for act
2f04: d7 46        action_op0_ptr  .dd2    action_op0_tab    ;pointer to action opcodes
2f06: d3 47                        .dd2    action_op1_tab    ; (max 4 per action)
2f08: cf 48                        .dd2    action_op2_tab
2f0a: cb 49                        .dd2    action_op3_tab
2f0c: c7 4a        condition0_ptr  .dd2    condition0_tab    ;pointer to action conditions
2f0e: bf 4c                        .dd2    condition1_tab    ; (max 5 per action)
2f10: b7 4e                        .dd2    condition2_tab
2f12: af 50                        .dd2    condition3_tab
2f14: a7 52                        .dd2    condition4_tab
2f16: 9f 54        room_descrs_ptr .dd2    room_descrs       ;pointer to room description text pointers
2f18: eb 54        vis_exits_n_ptr .dd2    visible_exits_n   ;pointer to north exits table
2f1a: 37 55                        .dd2    visible_exits_s   ;pointer to south exits table
2f1c: 83 55                        .dd2    visible_exits_e   ;pointer to east exits table
2f1e: cf 55                        .dd2    visible_exits_w   ;pointer to west exits table
2f20: 1b 56                        .dd2    visible_exits_u   ;pointer to up exits table
2f22: 67 56                        .dd2    visible_exits_d   ;pointer to down exits table
2f24: b3 56        messages_ptr    .dd2    messages          ;pointer to messages table
2f26: ff 42        item_rooms_ptr  .dd2    item_rooms        ;pointer to item location data table
2f28: 9f 43        item_names_ptr  .dd2    item_names        ;pointer to item name table
                   item_initroom_ptr
2f2a: 3f 44                        .dd2    item_initrooms    ;pointer to item initial location table
2f2c: fe 42                        .dd2    T42FE             ;(not used? points to end of item name string pool)
2f2e: 38 31        noun_words_ptr  .dd2    noun_words        ;pointer to noun list
2f30: af 32        verb_words_ptr  .dd2    verb_words        ;pointer to verb list
2f32: 01                           .dd1    $01
                   ; 
                   ; Player command input buffer.  The first 24 bytes are zeroed, though we accept
                   ; at most 18 characters.  (I have a sneaking suspicion somebody mixed up "18"
                   ; and "$18" in the sources, though it's necessary to be at least 19 so that the
                   ; contents are properly null-terminated.)
                   ; 
                   ; The first 256 bytes is also used as a buffer for game state while loading or
                   ; saving it.
                   ; 
2f33: 00           kbd_scratch_buf .dd1    $00               ;saved game: adventure number (low)
2f34: 00           adv_num_hi      .dd1    $00               ;saved game: adventure number (high)
                   ; 
                   ; The next 61 bytes ($2f35-2f71) are copied out to $30c7-3103 when the game is
                   ; loaded, and back before it's saved.
2f35: 00 00 00 00+ save_game_data  .junk   61
                   ; 
2f72: 0d 22 22 0d+                 .junk   192
3032: 00           save_state_end  .dd1    $00               ;last byte in saved-game scratch area
                   ; 
                   thing_found_flag
3033: 50                           .dd1    $50
3034: 6f                           .junk   1
3035: 50           tmp_save_x2     .dd1    $50
3036: 6f 50 6f d0+                 .junk   29
3053: b4 00        adventure_vers  .dd2    180               ;version number
3055: 59 57                        .junk   2
3057: 0c 00        adventure_num   .dd2    12                ;adventure #12
3059: 40           screen_cleared? .dd1    $40               ;written, never read
305a: 3c 50 6f 50+                 .junk   13
                   actionop_arg_idx
3067: ff 8a                        .dd2    $8aff             ;current index into action op args (really 8-bit)
                   ; 
                   ; These values are defined in the header of an adventure data file on other
                   ; systems.  They're global values that affect the interpretation of the other
                   ; structures.
                   ; 
3069: 04 00        hdr_word_len    .dd2    $0004             ;char length of nouns and verbs
                   hdr_max_nounverb
306b: 4a 00                        .dd2    $004a             ;max verb/noun number (one list is padded to match)
306d: fb 00        hdr_max_action  .dd2    $00fb             ;max action number
306f: 4f 00        hdr_max_item    .dd2    $004f             ;maximum item number (count - 1)
3071: 52 00        hdr_max_msg     .dd2    $0052             ;maximum message number (count - 1)
3073: 25 00        hdr_max_room    .dd2    $0025             ;maximum room number (count - 1)
3075: 07 00        hdr_max_held    .dd2    $0007             ;maximum number of objects player can hold
3077: 04 00        hdr_start_room  .dd2    $0004             ;initial room number
                   hdr_num_treasures
3079: 00 00                        .dd2    $0000             ;number of treasures in the game (victory cond)
                   hdr_lamp_capacity
307b: 64 00                        .dd2    $0064             ;maximum capacity of lightsource obj
307d: 00           debug_flag      .dd1    $00               ;debug level: 0 (off), 1, or 2
                   hdr_treasure_room
307e: 00 00                        .dd2    $0000             ;room# where treasures are stored
                   ; 
                   ; Input trim buffer.  Holds up to 24 bytes.
3080: 00 43 59 43+ word_trim_buf   .junk   24
                   ; 
3098: 6f                           .junk   1
3099: 00 00        div_q_tmp       .dd2    $0000
309b: 00 00        div_r_tmp       .dd2    $0000
309d: 5b           tmp_save_reg1   .dd1    $5b
309e: b0           tmp_save_reg2   .dd1    $b0
309f: a7 b0 f3 b0+                 .junk   22
30b5: 06 2d 00 00+ dec_outbuf      .junk   7                 ;output buf for decimal print: len byte + 6 chars
30bc: 00           parsed_verb_idx .dd1    $00               ;index of parsed verb (0-74 here)
30bd: 00                           .junk   1
30be: 00           parsed_noun_idx .junk   1                 ;index of parsed noun (uses 0 "ANY" if none)
30bf: 00                           .junk   1
                   cmd_not_hnd_flag
30c0: 00                           .dd1    $00               ;true until command is handled
30c1: 00                           .junk   1
                   accum_cond_result
30c2: 00                           .dd1    $00               ;cumulative result of testing conditions
30c3: ff           occur_flag      .dd1    $ff               ;set if we're processing occurrences (vs. ops)?
30c4: 00           continue_flag   .dd1    $00               ;set by "continue" action op
30c5: 27           noun_or_percent .dd1    $27               ;action noun index, or occurrence percent chance
30c6: 0a           action_verb_idx .dd1    $0a
                   ; 
                   ; $30c7-3103 are stored in save game file part 1.  This includes the flags,
                   ; counters, and current/alternate rooms.
                   ; 
                   counter_register
30c7: d6 00                        .dd2    $00d6             ;counter register, a/k/a "current counter"
                   ; 
                   ; 32 action flags.  Action conditions and operations can set/clear/test these as
                   ; boolean values.  They hold $00 for false and $ff for true.
                   ; 
30c9: 00 00 00 00+ action_flags    .fill   15,$00            ;flags 0-14
30d8: 00           darkness_flag   .dd1    $00               ;flag 15: room is dark (so you need to bring light)
30d9: 00           lamp_empty_flag .dd1    $00               ;flag 16: nonzero if lightsource is empty
30da: 00 00 00 00+                 .fill   15,$00            ;flags 17-31
                   ; 
30e9: 04 00        current_room    .dd2    $0004             ;number of room player is currently in
30eb: 00 6f        def_alt_room    .dd2    $6f00             ;default "alternate room"
30ed: 00 6f 00 6f                  .junk   4
                   ; 
                   ; Nine storage slots for the 16-bit counters.
                   ; 
30f1: 03 00 50 6f+ game_counters   .junk   16                ;counters 0-7
3101: 64 00        lamp_fuel_level .dd2    $0064             ;counter #8 is time remaining on lamp
                   ; 
                   ; (Byte at $3103 is saved and restored, but shouldn't be.)
3103: 15 04        item_names_len  .dd2    $0415             ;total length of item name data
                   ; 
3105: 50 6f 50 6f+                 .junk   51
                   ; 
                   ; Nouns 0-74.  These aren't really null-terminated strings; rather, they are 4-
                   ; character words that begin with $00 or '*', indicating whether they are
                   ; distinct words or aliases.  They're formatted as strings because it's
                   ; (usually) easier to read that way.
                   ; 
3138: 00           noun_words      .dd1    $00
3139: 41 4e 59 00                  .zstr   ‘ANY’             ;noun 0 (implied when no noun provided)
313d: 00                           .dd1    $00
313e: 4e 4f 52 54+                 .zstr   ‘NORT’            ;nouns 1-6 must be the directions
3143: 53 4f 55 54+                 .zstr   ‘SOUT’
3148: 45 41 53 54+                 .zstr   ‘EAST’
314d: 57 45 53 54+                 .zstr   ‘WEST’
3152: 55 50 00                     .zstr   ‘UP’
3155: 00                           .dd1    $00
3156: 00                           .dd1    $00
3157: 44 4f 57 4e+                 .zstr   ‘DOWN’
315c: 4b 49 4e 47+                 .zstr   ‘KING’
3161: 47 55 41 52+                 .zstr   ‘GUAR’
3166: 50 41 4c 41+                 .zstr   ‘PALA’
316b: 4d 45 52 43+                 .zstr   ‘MERC’
3170: 53 48 49 50+                 .zstr   ‘SHIP*BOAT*ABOA’
317f: 4d 41 53 54+                 .zstr   ‘MAST’
3184: 53 41 49 4c+                 .zstr   ‘SAIL’
3189: 4d 45 44 49+                 .zstr   ‘MEDI’            ;$10
318e: 41 52 4f 55+                 .zstr   ‘AROU’
3193: 4f 43 45 41+                 .zstr   ‘OCEA*WATE*LIQU’
31a2: 50 41 53 53+                 .zstr   ‘PASS’
31a7: 48 41 4c 4c+                 .zstr   ‘HALL’
31ac: 43 41 56 45+                 .zstr   ‘CAVE’
31b1: 54 41 42 4c+                 .zstr   ‘TABL’
31b6: 53 54 4f 4e+                 .zstr   ‘STON’
31bb: 53 4b 45 4c+                 .zstr   ‘SKEL*BONE’
31c5: 4d 41 4e 00                  .zstr   ‘MAN’
31c9: 00                           .dd1    $00
31ca: 46 4c 49 4e+                 .zstr   ‘FLIN*STEE’
31d4: 53 48 4f 56+                 .zstr   ‘SHOV’
31d9: 48 55 54 00                  .zstr   ‘HUT’             ;$20
31dd: 00                           .dd1    $00
31de: 4d 4f 55 4e+                 .zstr   ‘MOUN’
31e3: 43 52 45 56+                 .zstr   ‘CREV’
31e8: 42 4f 58 00                  .zstr   ‘BOX’
31ec: 00                           .dd1    $00
31ed: 53 54 41 49+                 .zstr   ‘STAI’
31f2: 43 49 54 59+                 .zstr   ‘CITY’
31f7: 53 54 41 54+                 .zstr   ‘STAT’
31fc: 53 43 4f 52+                 .zstr   ‘SCOR’
3201: 41 4c 54 41+                 .zstr   ‘ALTA’
3206: 43 48 45 53+                 .zstr   ‘CHES’
320b: 4b 45 59 00                  .zstr   ‘KEY’
320f: 00                           .dd1    $00
3210: 43 59 43 4c+                 .zstr   ‘CYCL’
3215: 4a 55 4e 47+                 .zstr   ‘JUNG’
321a: 50 49 54 00                  .zstr   ‘PIT’
321e: 00                           .dd1    $00
321f: 43 41 42 49+                 .zstr   ‘CABI’
3224: 46 4f 55 4e+                 .zstr   ‘FOUN’
3229: 4e 4f 54 45+                 .zstr   ‘NOTE’            ;$30
322e: 43 4f 54 00                  .zstr   ‘COT’
3232: 00                           .dd1    $00
3233: 4d 41 52 4b+                 .zstr   ‘MARK’
3238: 42 4c 4f 43+                 .zstr   ‘BLOC’
323d: 54 4f 52 43+                 .zstr   ‘TORC’
3242: 52 55 42 42+                 .zstr   ‘RUBB’
3247: 54 45 4c 45+                 .zstr   ‘TELE’
324c: 43 4f 4d 50+                 .zstr   ‘COMP’
3251: 53 41 4e 44+                 .zstr   ‘SAND’
3256: 47 4c 4f 42+                 .zstr   ‘GLOB’
325b: 4d 41 53 4b+                 .zstr   ‘MASK’
3260: 43 48 41 4c+                 .zstr   ‘CHAL’
3265: 49 4e 56 45+                 .zstr   ‘INVE’
326a: 53 55 4e 00                  .zstr   ‘SUN’
326e: 00                           .dd1    $00
326f: 53 57 4f 52+                 .zstr   ‘SWOR’
3274: 53 54 52 41+                 .zstr   ‘STRA’
3279: 42 45 41 43+                 .zstr   ‘BEAC’            ;$40
327e: 49 53 4c 41+                 .zstr   ‘ISLA’
3283: 41 4e 43 48+                 .zstr   ‘ANCH’
3288: 41 53 48 4f+                 .zstr   ‘ASHO’
328d: 47 41 4d 45+                 .zstr   ‘GAME’
3292: 53 54 41 4c+                 .zstr   ‘STAL’
3297: 47 52 4f 55+                 .zstr   ‘GROU*FLOO’
32a1: 52 4f 50 45+                 .zstr   ‘ROPE’
32a6: 42 41 47 00                  .zstr   ‘BAG’
32aa: 2a 47 4f 4c+                 .str    ‘*GOLD’           ;$4a
                   ; 
                   ; Like the nouns, these are four-character strings that begin with $00 or '*'.
                   ; 
32af: 00           verb_words      .dd1    $00
32b0: 41 55 54 4f+                 .zstr   ‘AUTO’            ;verb 0 (used for "continue" actions)
32b5: 47 4f 00                     .zstr   ‘GO’              ;verb 1 must be GO
32b8: 00                           .dd1    $00
32b9: 2a 50 52 4f+                 .zstr   ‘*PROC*RIDE*RUN’
32c8: 2a 43 4c 49+                 .zstr   ‘*CLIM*ENTE*EXIT’
32d8: 53 41 56 45+                 .zstr   ‘SAVE’
32dd: 44 49 47 00                  .zstr   ‘DIG’
32e1: 00                           .dd1    $00
32e2: 54 41 4b 45+                 .zstr   ‘TAKE*GET’        ;verb 10 must be TAKE
32eb: 2a 43 41 52+                 .zstr   ‘*CARR*GRAB*HOLD*STEA’
3300: 46 49 4c 4c+                 .zstr   ‘FILL’            ;$10
3305: 47 49 56 45+                 .zstr   ‘GIVE’
330a: 44 52 4f 50+                 .zstr   ‘DROP*LOWE*PUT’   ;verb 18 must be DROP
3318: 2a 54 48 52+                 .zstr   ‘*THRO’
331e: 45 58 41 4d+                 .zstr   ‘EXAM*STUD*LOOK*SEE’
3331: 2a 57 41 54+                 .zstr   ‘*WATC’
3337: 53 41 49 4c+                 .zstr   ‘SAIL*NAVI’
3341: 50 55 53 48+                 .zstr   ‘PUSH*SHOV*MOVE*SHAK’ ;$20 (SHAK)
3355: 4f 50 45 4e+                 .zstr   ‘OPEN*UNLO’
335f: 4c 49 47 48+                 .zstr   ‘LIGH*IGNI*BURN’
336e: 42 52 45 41+                 .zstr   ‘BREA*DEST*SMAS’
337d: 41 54 54 41+                 .zstr   ‘ATTA*KILL’
3387: 45 4d 50 54+                 .zstr   ‘EMPT’
338c: 50 4f 55 52+                 .zstr   ‘POUR*SPIL’
3396: 55 4e 54 49+                 .zstr   ‘UNTI’
339b: 55 4e 4c 49+                 .zstr   ‘UNLI’
33a0: 52 45 41 44+                 .zstr   ‘READ’            ;$30
33a5: 53 4c 45 45+                 .zstr   ‘SLEE’
33aa: 57 45 41 52+                 .zstr   ‘WEAR’
33af: 52 45 4d 4f+                 .zstr   ‘REMO’
33b4: 44 52 49 4e+                 .zstr   ‘DRIN’
33b9: 48 45 4c 50+                 .zstr   ‘HELP’
33be: 53 41 59 00                  .zstr   ‘SAY’
33c2: 2a 53 43 52+                 .zstr   ‘*SCRE*YELL*HOLL’
33d2: 51 55 49 54+                 .zstr   ‘QUIT’
33d7: 49 4e 56 45+                 .zstr   ‘INVE’
33dc: 4a 55 4d 50+                 .zstr   ‘JUMP’
33e1: 50 52 41 59+                 .zstr   ‘PRAY’
33e6: 54 49 45 00                  .zstr   ‘TIE’
33ea: 00                           .dd1    $00
33eb: 54 4f 00                     .zstr   ‘TO’
33ee: 00                           .dd1    $00
33ef: 00                           .dd1    $00
33f0: 42 55 59 00                  .zstr   ‘BUY’             ;$40
33f4: 2a 50 55 52+                 .zstr   ‘*PURC’
33fa: 4f 4e 00                     .zstr   ‘ON’
33fd: 00                           .dd1    $00
33fe: 2a 41 54 00                  .zstr   ‘*AT’
3402: 00                           .dd1    $00
3403: 00                           .dd1    $00
3404: 49 4e 00                     .zstr   ‘IN’
3407: 00                           .dd1    $00
3408: 00                           .dd1    $00
3409: 52 41 49 53+                 .zstr   ‘RAIS*LIFT*WEIG’
3418: 53 54 45 50+                 .zstr   ‘STEP*WALK’
3422: 57 41 49 54+                 .zstr   ‘WAIT’            ;$4a
                   ; 
                   ; Room description text.
                   ; 
                   ; On screen, these are prefixed with "I'm in a".  If something different is
                   ; desired, such as "I'm in an" or "I'm on a", a leading '*' suppresses the
                   ; prefix string.
                   ; 
3427: 0c 52 6f 79+ T3427           .l1str  ‘Royal palace’    ;room #1
3434: 0c 50 65 72+ T3434           .l1str  ‘Persian city’
3441: 0c 50 65 72+ T3441           .l1str  ‘Persian city’
344e: 0c 50 65 72+ T344E           .l1str  ‘Persian city’
345b: 16 2a 49 20+ T345B           .l1str  ‘*I am at a Persian bay’
3472: 15 2a 49 20+ T3472           .l1str  ‘*I am on a large ship’
3488: 15 2a 49 27+ T3488           .l1str  ‘*I'm on a sandy beach’
349e: 00           T349E           .dd1    $00
349f: 0c 64 65 6e+ T349F           .l1str  ‘dense jungle’
34ac: 0c 64 65 6e+ T34AC           .l1str  ‘dense jungle’
34b9: 09 64 61 6d+ T34B9           .l1str  ‘damp cave’
34c3: 0b 63 72 6f+ T34C3           .l1str  ‘crow's-nest’
34cf: 16 2a 49 27+ T34CF           .l1str  ‘*I'm on a small island’
34e6: 16 2a 49 27+ T34E6           .l1str  ‘*I'm on a small island’
34fd: 09 67 72 61+ T34FD           .l1str  ‘grass hut’
3507: 0b 64 61 72+ T3507           .l1str  ‘dark cavern’
3513: 12 2a 49 27+ T3513           .l1str  ‘*I'm on a mountain’
3526: 16 2a 49 27+ T3526           .l1str  ‘*I'm on a small island’
353d: 16 2a 49 27+ T353D           .l1str  ‘*I'm on a rocky strand’
3554: 18 2a 49 27+ T3554           .l1str  ‘*I'm on a long staircase’
356d: 0d 73 61 63+ T356D           .l1str  ‘sacred temple’
357b: 0d 73 61 63+ T357B           .l1str  ‘sacred temple’
3589: 0e 68 69 64+ T3589           .l1str  ‘hidden chamber’
3598: 0e 68 69 64+ T3598           .l1str  ‘hidden chamber’
35a7: 0d 73 61 63+ T35A7           .l1str  ‘sacred temple’
35b5: 00           T35B5           .dd1    $00
35b6: 0d 6d 75 73+ T35B6           .l1str  ‘musty hallway’
35c4: 0b 73 6d 61+ T35C4           .l1str  ‘small cabin’
35d0: 08 63 6f 7a+ T35D0           .l1str  ‘cozy cot’
35d9: 0b 64 61 6d+ T35D9           .l1str  ‘damp grotto’
35e5: 00           T35E5           .dd1    $00
35e6: 16 2a 49 27+ T35E6           .l1str  ‘*I'm on a grassy plain’
35fd: 08 64 65 65+ T35FD           .l1str  ‘deep pit’
3606: 08 64 65 65+ T3606           .l1str  ‘deep pit’
360f: 18 2a 49 27+ T360F           .l1str  ‘*I'm in an enormous cave’
3628: 18 2a 49 27+ T3628           .l1str  ‘*I'm in an enormous cave’
3641: 0f 4c 4f 54+ T3641           .l1str  ‘LOT OF TROUBLE!’ ;limbo room
                   ; 
                   ; Message text.
                   ; 
3651: 00           T3651           .dd1    $00
3652: 6b 57 65 6c+ T3652           .l1str  ‘Welcome to Adventure 12: "THE GOLDEN VOYAGE"’
                                    +      $0a,‘by William Demas & Scott Adams’,$0a,‘Dedic’
                                    +      ‘ated: British band "QUEEN"’
36be: 0a 73 6f 6d+ T36BE           .l1str  ‘something!’
36c9: 06 57 68 65+ T36C9           .l1str  ‘Where?’
36d0: 12 53 6f 6d+ T36D0           .l1str  ‘Something rattles.’
36e3: 23 54 68 65+ T36E3           .l1str  ‘The statue topples down the stairs.’
3707: 07 49 20 66+ T3707           .l1str  ‘I found’
370f: 08 6e 6f 74+ T370F           .l1str  ‘nothing.’
3718: 36 49 74 20+ T3718           .l1str  ‘It appears to be broken. Strange markings are ’
                                    +      ‘present.’
374f: 1e 54 68 65+ T374F           .l1str  ‘The stones mysteriously unite!’
376e: 15 49 74 20+ T376E           .l1str  ‘It contains medicine.’
3784: 18 45 76 65+ T3784           .l1str  ‘Everything appears grey.’
379d: 02 4f 4b     T379D           .l1str  ‘OK’
37a0: 05 4f 55 43+ T37A0           .l1str  ‘OUCH!’
37a6: 16 49 20 73+ T37A6           .l1str  ‘I see nothing special.’
37bd: 1d 48 65 27+ T37BD           .l1str  ‘He's been stung by scorpions.’
37db: 08 4c 41 4e+ T37DB           .l1str  ‘LAND HO!’
37e4: 06 49 20 68+ T37E4           .l1str  ‘I hear’
37eb: 2e 4f 6e 65+ T37EB           .l1str  ‘One great big EYE has a focus in my direction!’
381a: 30 49 20 73+ T381A           .l1str  ‘I see a picture of a mountain and the word "SU’
                                    +      ‘N"’
384b: 1f 49 20 63+ T384B           .l1str  ‘I can't tell which way that is!’
386b: 2e 4d 65 72+ T386B           .l1str  ‘Merchant calls me a thief and slits my throat!’
389a: 24 54 68 65+ T389A           .l1str  ‘There's a tremendous flash of light!’
38bf: 0a 49 27 6d+ T38BF           .l1str  ‘I'm blind!’
38ca: 18 48 65 20+ T38CA           .l1str  ‘He gives a great big CRY’
38e3: 24 48 69 67+ T38E3           .l1str  ‘High atop the mast is a crow's-nest.’
3908: 7e 4b 49 4e+ T3908           .l1str  ‘KING: I have been given only 3 days to live. Y’
                                    +      ‘ou are to seek for      a way to restore my vi’
                                    +      ‘tality. The gold is yours. Go now!’
3987: 14 4f 48 20+ T3987           .l1str  ‘OH NO! I can't swim!’
399c: 07 43 79 63+ T399C           .l1str  ‘Cyclops’
39a4: 0c 49 74 27+ T39A4           .l1str  ‘It's locked.’
39b1: 1a 49 20 73+ T39B1           .l1str  ‘I see a picture of a cave.’
39cc: 1b 67 72 61+ T39CC           .l1str  ‘grabs me and eats me alive!’
39e8: 19 54 68 65+ T39E8           .l1str  ‘The statue comes to life!’
3a02: 15 49 74 27+ T3A02           .l1str  ‘It's holding a sword.’
3a18: 16 53 6f 72+ T3A18           .l1str  ‘Sorry, it won't BUDGE!’
3a2f: 0c 54 65 6c+ T3A2F           .l1str  ‘Tell me how?’
3a3c: 47 4d 41 4e+ T3A3C           .l1str  ‘MAN: I'm afraid it's too late for me. Appeal t’
                                    +      ‘o the’,$0a,‘     Gods for help!’
3a84: 1c 54 68 65+ T3A84           .l1str  ‘The ground shakes violently!’
3aa1: 44 49 27 76+ T3AA1           .l1str  ‘I've desecrated the holy fountain.’,$0a,‘I'm s’
                                    +      ‘truck down by a THUNDERBOLT!’
3ae6: 11 54 68 65+ T3AE6           .l1str  ‘The King grabs it’
3af8: 22 61 6e 64+ T3AF8           .l1str  ‘and DIES! Guards have me beheaded.’
3b1b: 19 49 20 68+ T3B1B           .l1str  ‘I have failed my mission.’
3b35: 12 49 74 27+ T3B35           .l1str  ‘It's getting dark!’
3b48: 0f 4d 6f 72+ T3B48           .l1str  ‘Morning! I have’
3b58: 0a 47 6f 6f+ T3B58           .l1str  ‘Goodnight.’
3b63: 06 32 20 64+ T3B63           .l1str  ‘2 days’
3b6a: 05 31 20 64+ T3B6A           .l1str  ‘1 day’
3b70: 1c 6c 65 66+ T3B70           .l1str  ‘left to complete my mission.’
3b8d: 10 54 68 65+ T3B8D           .l1str  ‘The sun has set.’
3b9e: 2d 4e 69 67+ T3B9E           .l1str  ‘Night air is COLD!’,$0a,‘I catch pneumonia and’
                                    +      ‘ die.’
3bcc: 12 66 61 69+ T3BCC           .l1str  ‘failed my mission.’
3bdf: 12 49 27 6d+ T3BDF           .l1str  ‘I'm in great PAIN!’
3bf2: 22 4d 79 20+ T3BF2           .l1str  ‘My whole body has become infected.’
3c15: 12 53 74 61+ T3C15           .l1str  ‘Statue follows me.’
3c28: 18 53 74 61+ T3C28           .l1str  ‘Statue swings its sword.’
3c41: 0d 49 74 20+ T3C41           .l1str  ‘It missed me!’
3c4f: 15 49 27 76+ T3C4F           .l1str  ‘I've been cut in two!’
3c65: 16 49 20 66+ T3C65           .l1str  ‘I fend off its attack.’
3c7c: 42 49 27 6d+ T3C7C           .l1str  ‘I'm lynched by angry mourners.’,$0a,‘Their Kin’
                                    +      ‘g is dead. (AND SO AM I)!!’
3cbf: 10 54 68 65+ T3CBF           .l1str  ‘The man is dead!’
3cd0: 3b 47 65 74+ T3CD0           .l1str  ‘Get your copy of "FROG" from Adventure Interna’
                                    +      ‘tional today!’
3d0c: 15 54 68 65+ T3D0C           .l1str  ‘The ship drifts away.’
3d22: 10 4e 6f 74+ T3D22           .l1str  ‘Nothing happens.’
3d33: 0c 49 74 27+ T3D33           .l1str  ‘It's full of’
3d40: 06 77 61 74+ T3D40           .l1str  ‘water.’
3d47: 11 61 20 73+ T3D47           .l1str  ‘a strange liquid.’
3d59: 48 61 6e 64+ T3D59           .l1str  ‘and transforms into a young man. CONGRATULATIO’
                                    +      ‘NS!!’,$0a,‘Mission accomplished.’
3da2: 11 64 72 69+ T3DA2           .l1str  ‘drinks the liquid’
3db4: 18 61 6e 64+ T3DB4           .l1str  ‘and yells "It's EMPTY!".’
3dcd: 0d 77 6f 6e+ T3DCD           .l1str  ‘won't let me.’
3ddb: 21 43 79 63+ T3DDB           .l1str  ‘Cyclops staggers and steps on me!’
3dfd: 18 49 27 6c+ T3DFD           .l1str  ‘I'll only defend myself.’
3e16: 08 4d 65 72+ T3E16           .l1str  ‘Merchant’
3e1f: 18 50 6c 65+ T3E1F           .l1str  ‘Please be more specific.’
3e38: 13 49 20 66+ T3E38           .l1str  ‘I feel much better.’
3e4c: 09 45 6d 70+ T3E4C           .l1str  ‘Empty it?’
3e56: 06 53 6f 72+ T3E56           .l1str  ‘Sorry.’
3e5d: 13 48 65 20+ T3E5D           .l1str  ‘He has me executed.’
3e71: 32 53 75 72+ T3E71           .l1str  ‘Surprised merchant grabs it and runs like a th’
                                    +      ‘ief!’
3ea4: 1d 53 74 61+ T3EA4           .l1str  ‘Statue attacks while I sleep!’
3ec2: 19 52 6f 70+ T3EC2           .l1str  ‘Rope slides into the pit.’
3edc: 06 50 4c 4f+ T3EDC           .l1str  ‘PLOOSH’
3ee3: 05 59 55 43+ T3EE3           .l1str  ‘YUCK!’
                   ; 
                   ; Item name data, stored as strings with a leading length byte.  If the name
                   ; ends with "/WORD/", the item will effectively have GET/DROP actions created
                   ; for it.  The byte that follows the slash is the item number.
                   ; 
                   ; (The item number could be inferred from the string's position in the list, but
                   ; it's a little simpler to make it explicit.)
                   ; 
3ee9: 00           L3EE9           .dd1    $00               ;item 0 doesn't exist
3eea: 0d 50 61 6c+ L3EEA           .l1str  ‘Palace guards’
3ef8: 09 41 67 65+ L3EF8           .l1str  ‘Aged King’
3f02: 06 50 61 6c+ L3F02           .l1str  ‘Palace’
3f09: 0a 4c 61 72+ L3F09           .l1str  ‘Large ship’
3f14: 04 4d 61 73+ L3F14           .l1str  ‘Mast’
3f19: 04 53 61 69+ L3F19           .l1str  ‘Sail’
3f1e: 06 41 6e 63+ L3F1E           .l1str  ‘Anchor’
3f25: 0e 53 6b 65+ L3F25           .l1str  ‘Skeleton/SKEL/’
3f34: 08                           .dd1    $08
3f35: 0f 4c 69 74+ L3F35           .l1str  ‘Lit torch/TORC/’ ;light source is always item #9
3f45: 09                           .dd1    $09
3f46: 0c 4f 6c 64+ L3F46           .l1str  ‘Old box/BOX/’
3f53: 0a                           .dd1    $0a
3f54: 10 53 74 72+ L3F54           .l1str  ‘Strange fountain’
3f65: 07 43 72 65+ L3F65           .l1str  ‘Crevice’
3f6d: 03 4d 61 6e  L3F6D           .l1str  ‘Man’
3f71: 06 4a 75 6e+ L3F71           .l1str  ‘Jungle’
3f78: 0e 48 69 64+ L3F78           .l1str  ‘Hidden passage’
3f87: 12 47 6f 6c+ L3F87           .l1str  ‘Gold chalice/CHAL/’
3f9a: 10                           .dd1    $10
3f9b: 04 43 61 76+ L3F9B           .l1str  ‘Cave’
3fa0: 0e 4c 6f 6e+ L3FA0           .l1str  ‘Long staircase’
3faf: 13 46 6c 69+ L3FAF           .l1str  ‘Flint & steel/FLIN/’
3fc3: 13                           .dd1    $13
3fc4: 0f 47 6f 6c+ L3FC4           .l1str  ‘Gold mask/MASK/’
3fd4: 14                           .dd1    $14
3fd5: 0e 49 27 6d+ L3FD5           .l1str  ‘I'm wearing it’
3fe4: 0b 53 6d 61+ L3FE4           .l1str  ‘Small stone’
3ff0: 0b 53 6d 61+ L3FF0           .l1str  ‘Small stone’
3ffc: 0b 53 6d 61+ L3FFC           .l1str  ‘Small stone’
4008: 0d 53 74 6f+ L4008           .l1str  ‘Stone Goddess’
4016: 11 57 68 69+ L4016           .l1str  ‘White globe/GLOB/’
4028: 1a                           .dd1    $1a
4029: 09 47 72 61+ L4029           .l1str  ‘Grass hut’
4033: 08 4d 65 72+ L4033           .l1str  ‘Merchant’
403c: 08 4d 65 72+ L403C           .l1str  ‘Merchant’
4045: 08 4d 65 72+ L4045           .l1str  ‘Merchant’
404e: 0c 53 68 6f+ L404E           .l1str  ‘Shovel/SHOV/’
405b: 1f                           .dd1    $1f
405c: 0d 53 61 6e+ L405C           .l1str  ‘Sandals/SAND/’
406a: 20                           .dd1    $20
406b: 10 49 27 6d+ L406B           .l1str  ‘I'm wearing them’
407c: 0d 43 6f 6d+ L407C           .l1str  ‘Compass/COMP/’
408a: 22                           .dd1    $22
408b: 0f 54 65 6c+ L408B           .l1str  ‘Telescope/TELE/’
409b: 23                           .dd1    $23
409c: 08 44 65 61+ L409C           .l1str  ‘Dead man’
40a5: 08 4b 65 79+ L40A5           .l1str  ‘Key/KEY/’
40ae: 25                           .dd1    $25
40af: 14 50 69 6c+ L40AF           .l1str  ‘Pile of rubble/RUBB/’
40c4: 26                           .dd1    $26
40c5: 08 4d 6f 75+ L40C5           .l1str  ‘Mountain’
40ce: 0b 53 74 6f+ L40CE           .l1str  ‘Stone block’
40da: 12 4f 72 6e+ L40DA           .l1str  ‘Ornate chest/CHES/’
40ed: 29                           .dd1    $29
40ee: 03 43 6f 74  L40EE           .l1str  ‘Cot’
40f2: 0a 4e 6f 74+ L40F2           .l1str  ‘Note/NOTE/’
40fd: 2b                           .dd1    $2b
40fe: 08 44 65 65+ L40FE           .l1str  ‘Deep pit’
4107: 07 43 79 63+ L4107           .l1str  ‘Cyclops’
410f: 04 43 61 76+ L410F           .l1str  ‘Cave’
4114: 14 4d 61 67+ L4114           .l1str  ‘Magnificent fountain’
4129: 05 4f 63 65+ L4129           .l1str  ‘Ocean’
412f: 14 50 69 6c+ L412F           .l1str  ‘Pile of rubble/RUBB/’
4144: 31                           .dd1    $31
4145: 00           L4145           .dd1    $00
4146: 10 4f 70 65+ L4146           .l1str  ‘Open chest/CHES/’
4157: 33                           .dd1    $33
4158: 0d 59 6f 75+ L4158           .l1str  ‘Youthful King’
4166: 10 42 61 67+ L4166           .l1str  ‘Bag of gold/BAG/’
4177: 35                           .dd1    $35
4178: 0c 42 72 6f+ L4178           .l1str  ‘Broken globe’
4185: 09 53 63 6f+ L4185           .l1str  ‘Scorpions’
418f: 0b 54 6f 72+ L418F           .l1str  ‘Torch/TORC/’
419b: 38                           .dd1    $38
419c: 11 43 72 6f+ L419C           .l1str  ‘Crowd of mourners’
41ae: 0c 53 74 6f+ L41AE           .l1str  ‘Stone tablet’
41bb: 05 41 6c 74+ L41BB           .l1str  ‘Altar’
41c1: 0f 53 63 6f+ L41C1           .l1str  ‘Scorpion stings’
41d1: 19 46 65 73+ L41D1           .l1str  ‘Festering scorpion stings’
41eb: 0f 41 6e 69+ L41EB           .l1str  ‘Animated statue’
41fb: 0b 53 77 6f+ L41FB           .l1str  ‘Sword/SWOR/’
4207: 3f                           .dd1    $3f
4208: 0c 52 6f 63+ L4208           .l1str  ‘Rocky strand’
4215: 0b 53 61 6e+ L4215           .l1str  ‘Sandy beach’
4221: 0c 53 6d 61+ L4221           .l1str  ‘Small island’
422e: 10 53 68 69+ L422E           .l1str  ‘Ship is anchored’
423f: 0c 53 74 6f+ L423F           .l1str  ‘Stone tablet’
424c: 0d 42 6c 69+ L424C           .l1str  ‘Blind cyclops’
425a: 0a 53 74 61+ L425A           .l1str  ‘Stalagmite’
4265: 04 52 6f 70+ L4265           .l1str  ‘Rope’
426a: 17 52 6f 70+ L426A           .l1str  ‘Rope tied to stalagmite’
4282: 15 4f 74 68+ L4282           .l1str  ‘Other end of the rope’
4298: 1a 52 6f 70+ L4298           .l1str  ‘Rope leading down into pit’
42b3: 1b 52 6f 70+ L42B3           .l1str  ‘Rope leading out of the pit’
42cf: 0c 44 61 72+ L42CF           .l1str  ‘Dark hallway’
42dc: 05 43 61 62+ L42DC           .l1str  ‘Cabin’
42e2: 0c 50 65 72+ L42E2           .l1str  ‘Persian city’
42ef: 0e 4c 6f 6e+ L42EF           .l1str  ‘Long staircase’
42fe: 00           T42FE           .dd1    $00
                   ; 
                   ; 16-bit value indicating which room an item is in.  There are 80 entries, but
                   ; entry 0 isn't used.
                   ; 
                   ; (Unlike everything else nearby, this is mutable state.)
                   ; 
42ff: 00 00 01 00+ item_rooms      .bulk   $00,$00,$01,$00,$01,$00,$02,$00,$05,$00,$06,$00
                                    +      $06,$00,$00,$00,$0d,$00,$00,$00,$0f,$00,$0b,$00
                                    +      $00,$00,$07,$00,$07,$00,$00,$00,$00,$00,$0a,$00
                                    +      $13,$00,$14,$00,$00,$00,$00,$00,$18,$00,$00,$00
                                    +      $00,$00,$13,$00,$00,$00,$0e,$00,$04,$00,$03,$00
                                    +      $05,$00,$12,$00,$04,$00,$00,$00,$03,$00,$03,$00
                                    +      $00,$00,$00,$00,$00,$00,$0e,$00,$17,$00,$19,$00
                                    +      $1c,$00,$1d,$00,$1e,$00,$22,$00,$22,$00,$24,$00
                                    +      $05,$00,$00,$00,$00,$00,$00,$00,$00,$00,$08,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$03,$00,$16,$00
                                    +      $00,$00,$00,$00,$00,$00,$11,$00,$00,$00,$00,$00
                                    +      $00,$00,$06,$00,$24,$00,$00,$00,$1e,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$21,$00,$00,$00,$06,$00
                                    +      $00,$00,$15,$00
                   ; 
                   ; Pointers to item names (0-79).
                   ; 
439f: e9 3e        item_names      .dd2    L3EE9             ;item #0 (doesn't exist)
43a1: ea 3e                        .dd2    L3EEA
43a3: f8 3e                        .dd2    L3EF8
43a5: 02 3f                        .dd2    L3F02
43a7: 09 3f                        .dd2    L3F09
43a9: 14 3f                        .dd2    L3F14
43ab: 19 3f                        .dd2    L3F19
43ad: 1e 3f                        .dd2    L3F1E
43af: 25 3f                        .dd2    L3F25
43b1: 35 3f                        .dd2    L3F35             ;item #9 (lightsource)
43b3: 46 3f                        .dd2    L3F46
43b5: 54 3f                        .dd2    L3F54
43b7: 65 3f                        .dd2    L3F65
43b9: 6d 3f                        .dd2    L3F6D
43bb: 71 3f                        .dd2    L3F71
43bd: 78 3f                        .dd2    L3F78
43bf: 87 3f                        .dd2    L3F87
43c1: 9b 3f                        .dd2    L3F9B
43c3: a0 3f                        .dd2    L3FA0
43c5: af 3f                        .dd2    L3FAF
43c7: c4 3f                        .dd2    L3FC4
43c9: d5 3f                        .dd2    L3FD5
43cb: e4 3f                        .dd2    L3FE4
43cd: f0 3f                        .dd2    L3FF0
43cf: fc 3f                        .dd2    L3FFC
43d1: 08 40                        .dd2    L4008
43d3: 16 40                        .dd2    L4016
43d5: 29 40                        .dd2    L4029
43d7: 33 40                        .dd2    L4033
43d9: 3c 40                        .dd2    L403C
43db: 45 40                        .dd2    L4045
43dd: 4e 40                        .dd2    L404E
43df: 5c 40                        .dd2    L405C
43e1: 6b 40                        .dd2    L406B
43e3: 7c 40                        .dd2    L407C
43e5: 8b 40                        .dd2    L408B
43e7: 9c 40                        .dd2    L409C
43e9: a5 40                        .dd2    L40A5
43eb: af 40                        .dd2    L40AF
43ed: c5 40                        .dd2    L40C5             ;$27
43ef: ce 40                        .dd2    L40CE
43f1: da 40                        .dd2    L40DA
43f3: ee 40                        .dd2    L40EE
43f5: f2 40                        .dd2    L40F2
43f7: fe 40                        .dd2    L40FE
43f9: 07 41                        .dd2    L4107
43fb: 0f 41                        .dd2    L410F
43fd: 14 41                        .dd2    L4114
43ff: 29 41                        .dd2    L4129
4401: 2f 41                        .dd2    L412F
4403: 45 41                        .dd2    L4145
4405: 46 41                        .dd2    L4146
4407: 58 41                        .dd2    L4158
4409: 66 41                        .dd2    L4166
440b: 78 41                        .dd2    L4178
440d: 85 41                        .dd2    L4185
440f: 8f 41                        .dd2    L418F
4411: 9c 41                        .dd2    L419C
4413: ae 41                        .dd2    L41AE
4415: bb 41                        .dd2    L41BB
4417: c1 41                        .dd2    L41C1
4419: d1 41                        .dd2    L41D1
441b: eb 41                        .dd2    L41EB
441d: fb 41                        .dd2    L41FB
441f: 08 42                        .dd2    L4208
4421: 15 42                        .dd2    L4215
4423: 21 42                        .dd2    L4221
4425: 2e 42                        .dd2    L422E
4427: 3f 42                        .dd2    L423F
4429: 4c 42                        .dd2    L424C
442b: 5a 42                        .dd2    L425A
442d: 65 42                        .dd2    L4265
442f: 6a 42                        .dd2    L426A
4431: 82 42                        .dd2    L4282
4433: 98 42                        .dd2    L4298
4435: b3 42                        .dd2    L42B3
4437: cf 42                        .dd2    L42CF
4439: dc 42                        .dd2    L42DC
443b: e2 42                        .dd2    L42E2
443d: ef 42                        .dd2    L42EF
                   ; 
                   ; Initial room numbers for items.  This is copied into item_rooms during game
                   ; init.
                   ; 
443f: 00 00 01 00+ item_initrooms  .bulk   $00,$00,$01,$00,$01,$00,$02,$00,$05,$00,$06,$00
                                    +      $06,$00,$00,$00,$0d,$00,$00,$00,$0f,$00,$0b,$00
                                    +      $00,$00,$07,$00,$07,$00,$00,$00,$00,$00,$0a,$00
                                    +      $13,$00,$14,$00,$00,$00,$00,$00,$18,$00,$00,$00
                                    +      $00,$00,$13,$00,$00,$00,$0e,$00,$04,$00,$03,$00
                                    +      $05,$00,$12,$00,$04,$00,$00,$00,$03,$00,$03,$00
                                    +      $00,$00,$00,$00,$00,$00,$0e,$00,$17,$00,$19,$00
                                    +      $1c,$00,$1d,$00,$1e,$00,$22,$00,$22,$00,$24,$00
                                    +      $05,$00,$00,$00,$00,$00,$00,$00,$00,$00,$08,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$03,$00,$16,$00
                                    +      $00,$00,$00,$00,$00,$00,$11,$00,$00,$00,$00,$00
                                    +      $00,$00,$06,$00,$24,$00,$00,$00,$1e,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$21,$00,$00,$00,$06,$00
                                    +      $00,$00,$15,$00
                   ; 
                   ; Verb for action N (0-251).  Will be $00 for occurrences.
                   ; 
                   ; Occurrences must come first in the list.
                   ; 
44df: 00 00 00 00+ action_verb     .bulk   $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$0a,$01,$01,$01,$01,$01,$01,$01,$01
                                    +      $01,$01,$01,$01,$01,$08,$09,$09,$0a,$01,$0a,$0a
                                    +      $0a,$0a,$09,$09,$01,$09,$0a,$0a,$0a,$0a,$0a,$0a
                                    +      $0a,$0a,$0a,$0a,$0a,$0a,$16,$4a,$0a,$0a,$11,$01
                                    +      $11,$00,$11,$00,$11,$00,$11,$00,$3d,$11,$11,$11
                                    +      $00,$31,$3c,$01,$01,$01,$01,$01,$01,$01,$01,$01
                                    +      $01,$01,$0a,$10,$10,$10,$10,$10,$10,$12,$34,$12
                                    +      $12,$12,$12,$12,$12,$16,$16,$16,$16,$16,$16,$16
                                    +      $16,$16,$16,$16,$16,$16,$16,$16,$16,$16,$16,$16
                                    +      $16,$16,$01,$01,$0a,$0a,$0a,$1b,$1b,$1b,$1b,$1b
                                    +      $1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1d,$1d,$1d
                                    +      $1d,$42,$12,$00,$00,$21,$23,$26,$21,$29,$2b,$2c
                                    +      $16,$2e,$2e,$2f,$30,$32,$32,$0a,$33,$33,$2b,$42
                                    +      $12,$36,$36,$3a,$3b,$48,$48,$45,$3e,$3f,$12,$42
                                    +      $44,$44,$40,$40,$40,$40,$40,$01,$01,$01,$01,$35
                                    +      $44,$3d,$44,$44,$34,$34,$16,$16,$12,$1b,$12,$12
                   ; 
                   ; For occurrences (verb=$00), this is the percent chance of the action
                   ; happening.  For actions (verb!=$00), this is the index of the noun (NOT the
                   ; item).
                   ; 
45db: 64 00 64 64+ action_nou_prc  .bulk   $64,$00,$64,$64,$64,$64,$64,$64,$64,$64,$64,$64
                                    +      $00,$64,$00,$64,$64,$64,$32,$00,$64,$00,$00,$00
                                    +      $64,$2d,$28,$46,$27,$64,$3c,$2d,$64,$64,$64,$00
                                    +      $64,$64,$00,$2d,$64,$64,$00,$64,$64,$64,$64,$3c
                                    +      $64,$64,$64,$64,$64,$64,$64,$64,$64,$64,$64,$64
                                    +      $64,$64,$64,$27,$2d,$2f,$31,$3f,$40,$41,$43,$43
                                    +      $43,$48,$48,$15,$16,$44,$00,$00,$3c,$09,$10,$10
                                    +      $10,$12,$00,$00,$0b,$00,$19,$19,$19,$18,$18,$18
                                    +      $36,$36,$37,$37,$38,$38,$2f,$00,$48,$48,$10,$2f
                                    +      $3b,$00,$3b,$00,$3b,$00,$3b,$00,$00,$49,$49,$49
                                    +      $00,$00,$2d,$43,$25,$2e,$0b,$0e,$12,$2c,$17,$20
                                    +      $21,$22,$05,$3b,$3b,$3b,$3b,$3b,$3b,$10,$12,$19
                                    +      $19,$19,$18,$18,$48,$0e,$18,$18,$19,$19,$19,$1c
                                    +      $23,$26,$26,$28,$29,$2b,$30,$36,$36,$36,$35,$3b
                                    +      $3b,$3b,$17,$17,$3e,$3e,$3e,$00,$04,$03,$02,$03
                                    +      $02,$01,$03,$01,$04,$03,$04,$04,$00,$26,$26,$26
                                    +      $00,$46,$39,$00,$00,$29,$34,$00,$29,$00,$3b,$12
                                    +      $2f,$48,$48,$34,$30,$38,$3a,$48,$38,$3a,$3b,$46
                                    +      $42,$3d,$00,$00,$00,$05,$06,$42,$48,$45,$48,$46
                                    +      $2f,$2f,$0b,$38,$37,$36,$18,$22,$24,$24,$24,$00
                                    +      $2d,$00,$2f,$2f,$12,$12,$2f,$00,$3a,$00,$38,$38
                   ; 
                   ; Action opcode table.  See the operations function table at $270c.
                   ; 
                   ; One table for each of the four possible operations per action.
                   ; 
46d7: 01 51 4d 35+ action_op0_tab  .bulk   $01,$51,$4d,$35,$30,$38,$3a,$3c,$48,$81,$39,$58
                                    +      $31,$58,$4f,$2d,$2e,$32,$0d,$51,$51,$33,$66,$51
                                    +      $67,$68,$20,$6b,$6a,$69,$18,$1f,$3c,$3c,$58,$3d
                                    +      $3b,$25,$48,$78,$3c,$09,$3b,$38,$2a,$38,$39,$6f
                                    +      $35,$38,$39,$35,$35,$35,$35,$35,$39,$39,$35,$35
                                    +      $1a,$3a,$39,$84,$0c,$0c,$0c,$0c,$0c,$0c,$0c,$0c
                                    +      $0c,$0c,$0c,$0c,$0c,$47,$06,$06,$42,$0c,$0c,$0c
                                    +      $0c,$0c,$06,$06,$0c,$06,$34,$34,$34,$34,$34,$34
                                    +      $34,$34,$34,$34,$34,$34,$71,$0c,$34,$0c,$56,$0c
                                    +      $27,$58,$27,$58,$27,$58,$27,$58,$0c,$37,$37,$37
                                    +      $3a,$2c,$0c,$0c,$36,$0c,$0c,$0c,$0c,$0c,$0c,$0c
                                    +      $0c,$0c,$0c,$7e,$7e,$7e,$0c,$0c,$0c,$0c,$0c,$0c
                                    +      $0c,$0c,$03,$03,$03,$19,$13,$1e,$08,$08,$08,$0f
                                    +      $0a,$21,$21,$06,$06,$12,$7b,$10,$10,$10,$06,$71
                                    +      $71,$71,$0c,$0c,$22,$22,$34,$7e,$0c,$0c,$0c,$0c
                                    +      $0c,$0c,$0c,$0c,$0c,$0c,$0c,$0c,$14,$04,$3b,$70
                                    +      $23,$0c,$35,$58,$58,$0c,$0c,$7e,$7e,$7e,$70,$7d
                                    +      $06,$3b,$37,$0c,$6e,$0c,$0c,$0c,$0c,$0c,$0c,$0c
                                    +      $0c,$0c,$0c,$29,$42,$0c,$0c,$0c,$0c,$0c,$0c,$0c
                                    +      $0c,$0c,$0c,$0c,$0c,$0c,$0c,$0c,$36,$36,$7b,$7e
                                    +      $0c,$0c,$0c,$0c,$0c,$0c,$71,$0e,$0c,$0c,$0c,$00
47d3: 4f 4f 00 00+ action_op1_tab  .bulk   $4f,$4f,$00,$00,$00,$00,$38,$00,$00,$3c,$00,$49
                                    +      $3d,$39,$51,$2f,$2f,$51,$4a,$4f,$4d,$48,$3d,$00
                                    +      $35,$58,$48,$3c,$39,$3c,$58,$3d,$00,$00,$58,$3f
                                    +      $3b,$3a,$3e,$3d,$00,$3b,$35,$40,$00,$40,$40,$37
                                    +      $00,$40,$40,$00,$00,$00,$00,$00,$40,$40,$00,$00
                                    +      $35,$00,$40,$7e,$23,$26,$36,$36,$36,$36,$36,$36
                                    +      $36,$36,$36,$36,$36,$00,$02,$02,$00,$36,$3b,$3b
                                    +      $70,$23,$02,$02,$36,$07,$0c,$0c,$0c,$0c,$0c,$0c
                                    +      $0c,$0c,$0c,$0c,$0c,$0c,$73,$58,$0c,$3b,$24,$26
                                    +      $75,$70,$75,$28,$75,$48,$58,$76,$11,$80,$80,$80
                                    +      $3a,$3a,$3d,$36,$35,$36,$58,$36,$1b,$36,$36,$36
                                    +      $36,$36,$36,$00,$00,$00,$3a,$3a,$3a,$35,$3d,$35
                                    +      $35,$35,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$02,$02,$00,$00,$3a,$3a,$3a,$02,$72
                                    +      $73,$73,$58,$36,$00,$00,$0c,$00,$58,$58,$58,$58
                                    +      $58,$58,$58,$58,$58,$58,$58,$58,$00,$00,$05,$00
                                    +      $00,$35,$48,$3a,$48,$48,$48,$00,$1d,$79,$00,$00
                                    +      $02,$3b,$37,$48,$00,$4a,$4a,$4a,$37,$37,$3c,$35
                                    +      $48,$55,$55,$3f,$00,$36,$36,$48,$03,$35,$35,$35
                                    +      $3b,$3b,$3a,$3a,$3a,$3a,$3a,$36,$00,$00,$00,$00
                                    +      $3b,$70,$3e,$3e,$3c,$3d,$73,$00,$35,$58,$35,$00
48cf: 3a 3a 00 00+ action_op2_tab  .bulk   $3a,$3a,$00,$00,$00,$00,$40,$00,$00,$3d,$00,$00
                                    +      $29,$49,$53,$3c,$3c,$3e,$49,$51,$49,$49,$49,$00
                                    +      $00,$58,$00,$00,$3d,$00,$58,$00,$00,$00,$6c,$00
                                    +      $3b,$3a,$83,$00,$00,$3b,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$29,$00,$00,$00,$00,$00,$00,$3c,$00,$00
                                    +      $00,$00,$00,$00,$00,$3d,$00,$35,$35,$35,$35,$35
                                    +      $35,$00,$00,$38,$00,$00,$35,$35,$00,$00,$7c,$7c
                                    +      $00,$00,$35,$35,$35,$00,$00,$00,$00,$15,$00,$00
                                    +      $15,$00,$15,$00,$15,$00,$00,$53,$00,$4a,$48,$3d
                                    +      $58,$7f,$58,$3d,$58,$74,$49,$7f,$02,$3a,$3a,$3a
                                    +      $3b,$58,$00,$35,$00,$00,$7a,$00,$3d,$00,$3a,$00
                                    +      $00,$35,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$35,$35,$00,$00,$00,$00,$00,$35,$00
                                    +      $00,$00,$1c,$00,$00,$00,$00,$00,$3c,$3c,$3c,$3c
                                    +      $3c,$3c,$3c,$3c,$3c,$3c,$3c,$3c,$00,$00,$3e,$00
                                    +      $00,$00,$16,$49,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $3c,$82,$35,$00,$00,$00,$0b,$00,$00,$00,$3c,$3e
                                    +      $3a,$25,$70,$00,$00,$00,$00,$3c,$00,$48,$00,$00
                                    +      $83,$83,$00,$00,$00,$00,$00,$35,$00,$00,$00,$00
                                    +      $35,$00,$83,$83,$84,$00,$00,$00,$37,$00,$37,$00
49cb: 49 3a 00 00+ action_op3_tab  .bulk   $49,$3a,$00,$00,$00,$00,$17,$00,$00,$37,$00,$00
                                    +      $3f,$00,$2b,$51,$51,$00,$00,$3a,$00,$00,$00,$00
                                    +      $00,$3a,$00,$00,$3c,$00,$3a,$00,$00,$00,$49,$00
                                    +      $3b,$49,$00,$00,$00,$49,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$3f,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$35,$35,$35,$35,$35
                                    +      $35,$00,$00,$3a,$00,$00,$00,$00,$00,$00,$3c,$3c
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$3d,$00,$00
                                    +      $3d,$00,$3d,$00,$3d,$00,$00,$00,$00,$00,$6d,$00
                                    +      $49,$3d,$49,$00,$49,$3f,$00,$3d,$35,$3b,$3b,$49
                                    +      $00,$00,$00,$00,$00,$00,$77,$00,$00,$00,$35,$00
                                    +      $00,$35,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$77,$00,$00,$00,$00,$00,$3a,$3a,$3a,$3a
                                    +      $3a,$3a,$3a,$3a,$3a,$3a,$3a,$3a,$00,$00,$00,$00
                                    +      $00,$00,$49,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $35,$00,$0c,$00,$00,$00,$00,$00,$00,$00,$3c,$35
                                    +      $00,$35,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$3c,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                   ; 
                   ; Action conditions table.  Each 16-bit entry holds the condition opcode and
                   ; argument, which have been merged as (opcode + arg * 20).
                   ; 
                   ; There is one table for each of the 5 possible conditions per action.
                   ; 
                   ; Entries with an opcode of zero hold the arguments for action opcodes.  (So if
                   ; you have 3 conditions and 3 actions with arguments, you can't hold the whole
                   ; thing in a single action slot.)
                   ; 
4ac7: 75 02 00 00+ condition0_tab  .bulk   $75,$02,$00,$00,$00,$00,$52,$00,$13,$00,$c0,$00
                                    +      $20,$01,$bc,$01,$b7,$00,$4c,$02,$b7,$00,$4c,$02
                                    +      $4b,$02,$4c,$02,$cc,$10,$4c,$02,$4c,$02,$4c,$02
                                    +      $9a,$02,$3c,$00,$d4,$01,$77,$00,$0f,$00,$d4,$01
                                    +      $dd,$04,$da,$04,$e6,$04,$fc,$01,$fc,$01,$fc,$01
                                    +      $70,$01,$10,$02,$10,$02,$4c,$02,$76,$04,$00,$00
                                    +      $7c,$00,$96,$04,$f8,$02,$81,$00,$71,$05,$ba,$01
                                    +      $e0,$01,$c0,$00,$d7,$00,$44,$01,$1c,$01,$85,$01
                                    +      $08,$00,$c0,$00,$e8,$02,$08,$00,$1c,$00,$1c,$00
                                    +      $6c,$00,$6c,$00,$35,$01,$cc,$00,$7c,$00,$f4,$00
                                    +      $18,$00,$ac,$02,$bc,$01,$4e,$04,$5c,$02,$de,$00
                                    +      $34,$02,$02,$05,$16,$05,$2a,$05,$7c,$00,$7c,$00
                                    +      $7c,$00,$ca,$05,$de,$05,$2e,$01,$f2,$05,$00,$00
                                    +      $84,$02,$b8,$00,$00,$00,$2c,$00,$cb,$00,$cb,$00
                                    +      $cb,$00,$00,$00,$cc,$00,$cc,$00,$52,$00,$6d,$02
                                    +      $ba,$01,$ce,$01,$e2,$01,$8a,$04,$8a,$04,$52,$05
                                    +      $be,$02,$be,$02,$aa,$02,$aa,$02,$82,$02,$82,$02
                                    +      $de,$00,$78,$00,$8e,$05,$ca,$05,$06,$01,$d4,$02
                                    +      $18,$00,$00,$00,$18,$00,$00,$00,$18,$00,$28,$00
                                    +      $18,$00,$00,$00,$bc,$01,$27,$04,$27,$04,$27,$04
                                    +      $3c,$00,$44,$02,$5c,$02,$7c,$00,$1a,$06,$7c,$00
                                    +      $52,$00,$7c,$00,$c2,$03,$90,$00,$cc,$00,$1c,$01
                                    +      $1c,$01,$f2,$00,$48,$02,$41,$01,$41,$01,$41,$01
                                    +      $de,$00,$c2,$03,$ae,$03,$c9,$00,$41,$01,$b9,$01
                                    +      $cd,$01,$e1,$01,$89,$04,$51,$05,$b5,$05,$7c,$00
                                    +      $53,$05,$8b,$04,$e3,$01,$cf,$01,$bb,$01,$06,$01
                                    +      $cb,$00,$f6,$01,$da,$04,$bc,$01,$ff,$03,$86,$03
                                    +      $5f,$03,$bd,$02,$bd,$02,$bd,$02,$d7,$03,$43,$01
                                    +      $43,$01,$43,$01,$ac,$02,$ac,$02,$f6,$01,$da,$04
                                    +      $ee,$04,$7c,$00,$7c,$00,$7c,$00,$7c,$00,$7c,$00
                                    +      $7c,$00,$7c,$00,$7c,$00,$7c,$00,$7c,$00,$7c,$00
                                    +      $7c,$00,$7c,$00,$7c,$00,$f6,$01,$da,$04,$00,$00
                                    +      $00,$00,$b5,$05,$09,$02,$aa,$01,$86,$03,$37,$03
                                    +      $63,$04,$00,$00,$37,$03,$00,$00,$41,$01,$41,$01
                                    +      $de,$00,$a2,$05,$a2,$05,$b7,$00,$5f,$03,$81,$02
                                    +      $91,$01,$b6,$05,$95,$02,$a5,$01,$41,$01,$89,$04
                                    +      $7c,$00,$1c,$01,$00,$00,$00,$00,$00,$00,$94,$01
                                    +      $94,$01,$7c,$00,$8d,$05,$5c,$02,$8d,$05,$51,$05
                                    +      $89,$04,$51,$05,$52,$00,$82,$02,$aa,$02,$be,$02
                                    +      $8a,$04,$f2,$00,$80,$01,$a8,$01,$94,$01,$00,$00
                                    +      $b5,$05,$00,$00,$89,$04,$51,$05,$41,$01,$41,$01
                                    +      $d4,$02,$00,$00,$91,$01,$7c,$00,$81,$02,$81,$02
4cbf: 3c 00 cc 10+ condition1_tab  .bulk   $3c,$00,$cc,$10,$00,$00,$c0,$03,$00,$00,$0f,$00
                                    +      $40,$01,$21,$01,$48,$01,$e5,$04,$21,$01,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$3b,$00,$27,$00,$0f,$00
                                    +      $ca,$04,$c8,$00,$3c,$00,$b0,$04,$00,$00,$3c,$00
                                    +      $e5,$04,$f4,$01,$f6,$01,$ed,$04,$f4,$01,$f4,$01
                                    +      $86,$03,$00,$00,$08,$02,$44,$02,$00,$00,$00,$00
                                    +      $00,$05,$5e,$05,$20,$03,$66,$05,$78,$00,$ce,$01
                                    +      $50,$05,$a8,$00,$10,$00,$c0,$00,$10,$00,$52,$00
                                    +      $7c,$00,$34,$01,$00,$00,$f4,$00,$7c,$00,$f4,$00
                                    +      $7c,$00,$f4,$00,$21,$01,$10,$00,$5c,$01,$5c,$01
                                    +      $35,$04,$68,$01,$10,$00,$00,$00,$00,$00,$00,$00
                                    +      $44,$02,$7c,$00,$7c,$00,$7c,$00,$02,$05,$16,$05
                                    +      $2a,$05,$94,$02,$58,$02,$cc,$01,$1c,$02,$00,$00
                                    +      $f2,$02,$9a,$05,$00,$00,$14,$00,$bd,$04,$d1,$04
                                    +      $00,$00,$00,$00,$6e,$04,$ee,$01,$30,$00,$00,$00
                                    +      $b8,$01,$cc,$01,$e0,$01,$81,$00,$88,$04,$50,$05
                                    +      $95,$00,$bc,$02,$45,$00,$a8,$02,$59,$00,$80,$02
                                    +      $61,$02,$00,$00,$8c,$05,$c8,$05,$04,$01,$00,$00
                                    +      $41,$01,$00,$00,$41,$01,$00,$00,$41,$01,$10,$04
                                    +      $41,$01,$00,$00,$31,$01,$68,$00,$54,$00,$40,$00
                                    +      $8c,$00,$00,$00,$00,$00,$1a,$06,$7c,$00,$30,$02
                                    +      $31,$00,$f0,$00,$00,$00,$b4,$00,$dc,$00,$2c,$01
                                    +      $54,$01,$1c,$01,$30,$02,$d0,$00,$e4,$00,$f8,$00
                                    +      $41,$01,$41,$01,$41,$01,$c8,$00,$e4,$00,$b8,$01
                                    +      $cc,$01,$e0,$01,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$4e,$01,$9e,$01,$00,$00
                                    +      $00,$00,$f4,$00,$f4,$00,$f4,$00,$da,$01,$d0,$00
                                    +      $e4,$00,$f8,$00,$91,$03,$bc,$02,$f1,$04,$f1,$04
                                    +      $ec,$04,$3e,$05,$5c,$01,$5c,$01,$5c,$01,$98,$01
                                    +      $98,$01,$ac,$01,$ac,$01,$c0,$01,$c0,$01,$24,$02
                                    +      $24,$02,$38,$02,$b4,$02,$00,$00,$94,$01,$00,$00
                                    +      $00,$00,$b4,$05,$08,$02,$18,$01,$84,$03,$e5,$02
                                    +      $7f,$01,$00,$00,$00,$00,$00,$00,$d1,$00,$00,$00
                                    +      $60,$02,$ca,$05,$a0,$05,$b4,$00,$00,$00,$9a,$02
                                    +      $aa,$01,$b4,$05,$94,$02,$a4,$01,$c8,$00,$88,$04
                                    +      $8e,$00,$53,$05,$00,$00,$00,$00,$00,$00,$a4,$01
                                    +      $7c,$01,$3e,$05,$00,$00,$8f,$05,$8c,$05,$50,$05
                                    +      $e0,$00,$44,$01,$25,$04,$25,$04,$25,$04,$25,$04
                                    +      $25,$04,$44,$01,$90,$01,$90,$01,$00,$00,$00,$00
                                    +      $b4,$05,$00,$00,$44,$01,$e0,$00,$d0,$00,$f8,$00
                                    +      $00,$00,$00,$00,$90,$01,$00,$00,$80,$02,$00,$00
4eb7: 7c 01 6c 02+ condition2_tab  .bulk   $7c,$01,$6c,$02,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$a0,$00,$b4,$00,$48,$02,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$14,$00,$44,$02,$44,$02,$00,$00
                                    +      $b6,$04,$3c,$00,$00,$00,$c4,$04,$00,$00,$00,$00
                                    +      $d8,$04,$00,$00,$f4,$01,$f4,$01,$00,$00,$00,$00
                                    +      $08,$02,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $14,$05,$bd,$00,$f0,$05,$00,$00,$00,$00,$e2,$01
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$21,$01,$50,$00
                                    +      $c0,$01,$00,$00,$00,$00,$c0,$01,$98,$01,$98,$01
                                    +      $38,$02,$38,$02,$00,$00,$21,$01,$18,$06,$18,$06
                                    +      $24,$04,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$7c,$01,$8c,$00,$04,$01,$7c,$01,$8c,$00
                                    +      $04,$01,$00,$00,$00,$00,$a0,$00,$00,$00,$00,$00
                                    +      $6d,$02,$6d,$02,$00,$00,$00,$00,$b0,$04,$c4,$04
                                    +      $00,$00,$00,$00,$6d,$02,$6d,$02,$78,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$88,$04,$00,$00,$00,$00
                                    +      $bc,$02,$00,$00,$a8,$02,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$b4,$05,$d0,$02,$00,$00
                                    +      $d0,$00,$00,$00,$e4,$00,$00,$00,$f8,$00,$00,$00
                                    +      $00,$00,$00,$00,$2c,$01,$24,$04,$24,$04,$24,$04
                                    +      $44,$02,$00,$00,$00,$00,$64,$00,$64,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$a0,$00,$00,$00
                                    +      $00,$00,$40,$01,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $d1,$00,$e5,$00,$d1,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$40,$01,$90,$01,$00,$00
                                    +      $00,$00,$c0,$01,$38,$02,$98,$01,$cc,$01,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$ab,$02,$ab,$02,$ab,$02,$ab,$02
                                    +      $ab,$02,$ab,$02,$ab,$02,$ab,$02,$ab,$02,$ab,$02
                                    +      $ab,$02,$ab,$02,$00,$00,$00,$00,$d8,$04,$00,$00
                                    +      $00,$00,$00,$00,$08,$02,$00,$00,$64,$05,$34,$03
                                    +      $49,$01,$00,$00,$00,$00,$00,$00,$e5,$00,$00,$00
                                    +      $58,$02,$a0,$05,$b4,$05,$60,$04,$00,$00,$94,$02
                                    +      $a4,$01,$00,$00,$00,$00,$00,$00,$dc,$00,$88,$04
                                    +      $3c,$05,$f0,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$3c,$05,$00,$00,$a0,$05,$00,$00,$00,$00
                                    +      $88,$04,$50,$05,$31,$00,$59,$00,$45,$00,$95,$00
                                    +      $81,$00,$18,$01,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $c8,$05,$00,$00,$88,$04,$50,$05,$c8,$00,$00,$00
                                    +      $00,$00,$00,$00,$a4,$01,$00,$00,$94,$02,$00,$00
50af: 00 00 54 01+ condition3_tab  .bulk   $00,$00,$54,$01,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$60,$04,$44,$02,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$74,$04
                                    +      $4f,$04,$cc,$01,$00,$00,$3c,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$d8,$04,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $28,$05,$58,$02,$cc,$01,$00,$00,$00,$00,$b8,$01
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$05,$00,$00,$00,$00,$00,$05,$28,$05,$28,$05
                                    +      $14,$05,$14,$05,$00,$00,$a0,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$4c,$04,$4c,$04,$4c,$04,$4c,$04,$4c,$04
                                    +      $4c,$04,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $e4,$02,$8c,$05,$00,$00,$00,$00,$cc,$01,$cc,$01
                                    +      $00,$00,$00,$00,$60,$04,$e0,$01,$c0,$03,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$28,$00,$50,$00,$78,$00
                                    +      $00,$00,$00,$00,$00,$00,$50,$00,$50,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$dc,$00,$00,$00
                                    +      $00,$00,$f0,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $f9,$00,$f9,$00,$e5,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$0e,$05,$22,$05,$36,$05,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$54,$01,$54,$01,$54,$01,$90,$01
                                    +      $90,$01,$a4,$01,$a4,$01,$b8,$01,$b8,$01,$1c,$02
                                    +      $1c,$02,$30,$02,$00,$00,$00,$00,$d4,$03,$00,$00
                                    +      $00,$00,$00,$00,$38,$04,$00,$00,$00,$00,$fc,$03
                                    +      $60,$04,$00,$00,$00,$00,$00,$00,$f9,$00,$00,$00
                                    +      $08,$02,$c8,$05,$8c,$05,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$f0,$00,$58,$02
                                    +      $8c,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$8c,$00,$00,$00,$b4,$05,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$28,$00,$50,$00,$3c,$00,$8c,$00
                                    +      $78,$00,$f0,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$a0,$00,$a0,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
52a7: 00 00 00 00+ condition4_tab  .bulk   $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$d8,$04,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$28,$00
                                    +      $b0,$04,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $18,$06,$b4,$00,$00,$00,$00,$00,$00,$00,$cc,$01
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$50,$00,$50,$00,$50,$00,$50,$00,$50,$00
                                    +      $50,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$58,$02,$30,$02,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$dc,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $dc,$00,$c8,$00,$f0,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$64,$00,$14,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$90,$01,$1c,$02,$b8,$01,$54,$01
                                    +      $a4,$01,$90,$01,$b8,$01,$54,$01,$a4,$01,$30,$02
                                    +      $54,$01,$1c,$02,$00,$00,$00,$00,$7c,$01,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $b4,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$f8,$02
                                    +      $7c,$01,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$7c,$01,$00,$00,$8c,$05,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$a0,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                   ; 
                   ; Pointers to room descriptions.
                   ; 
                   ; There are 38 rooms (0-37), though room 0 is "nowhere".
                   ; 
549f: 26 34        room_descrs     .dd2    T3427-1
54a1: 27 34                        .dd2    T3427
54a3: 34 34                        .dd2    T3434
54a5: 41 34                        .dd2    T3441
54a7: 4e 34                        .dd2    T344E
54a9: 5b 34                        .dd2    T345B
54ab: 72 34                        .dd2    T3472
54ad: 88 34                        .dd2    T3488
54af: 9e 34                        .dd2    T349E
54b1: 9f 34                        .dd2    T349F
54b3: ac 34                        .dd2    T34AC
54b5: b9 34                        .dd2    T34B9
54b7: c3 34                        .dd2    T34C3
54b9: cf 34                        .dd2    T34CF
54bb: e6 34                        .dd2    T34E6
54bd: fd 34                        .dd2    T34FD
54bf: 07 35                        .dd2    T3507
54c1: 13 35                        .dd2    T3513
54c3: 26 35                        .dd2    T3526
54c5: 3d 35                        .dd2    T353D
54c7: 54 35                        .dd2    T3554
54c9: 6d 35                        .dd2    T356D
54cb: 7b 35                        .dd2    T357B
54cd: 89 35                        .dd2    T3589
54cf: 98 35                        .dd2    T3598
54d1: a7 35                        .dd2    T35A7
54d3: b5 35                        .dd2    T35B5
54d5: b6 35                        .dd2    T35B6
54d7: c4 35                        .dd2    T35C4
54d9: d0 35                        .dd2    T35D0
54db: d9 35                        .dd2    T35D9
54dd: e5 35                        .dd2    T35E5
54df: e6 35                        .dd2    T35E6
54e1: fd 35                        .dd2    T35FD
54e3: 06 36                        .dd2    T3606
54e5: 0f 36                        .dd2    T360F
54e7: 28 36                        .dd2    T3628
54e9: 41 36                        .dd2    T3641
                   ; 
                   ; Destination rooms for visible exits.  Each exit direction has a separate
                   ; table; each table has one 16-bit entry per room.  If the room has no exit in
                   ; that direction, the entry will be zero.
                   ; 
54eb: 00 00 00 00+ visible_exits_n .bulk   $00,$00,$00,$00,$00,$00,$02,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$0a,$00,$0a,$00,$00,$00
                                    +      $00,$00,$0e,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$19,$00,$16,$00
                                    +      $00,$00,$00,$00,$00,$00,$17,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$13,$00,$00,$00,$21,$00,$22,$00
                                    +      $00,$00,$00,$00
5537: 00 00 00 00+ visible_exits_s .bulk   $00,$00,$00,$00,$03,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$09,$00,$09,$00,$00,$00
                                    +      $00,$00,$00,$00,$0d,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$20,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$16,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$22,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00
5583: 00 00 02 00+ visible_exits_e .bulk   $00,$00,$02,$00,$00,$00,$04,$00,$00,$00,$03,$00
                                    +      $00,$00,$00,$00,$00,$00,$09,$00,$0a,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$0e,$00,$00,$00,$00,$00
                                    +      $0d,$00,$00,$00,$00,$00,$00,$00,$15,$00,$00,$00
                                    +      $17,$00,$00,$00,$00,$00,$1e,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $23,$00,$00,$00
55cf: 00 00 00 00+ visible_exits_w .bulk   $00,$00,$00,$00,$00,$00,$05,$00,$03,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$07,$00,$0a,$00,$0a,$00
                                    +      $00,$00,$12,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$16,$00,$00,$00,$18,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $1b,$00,$00,$00,$00,$00,$00,$00,$00,$00,$24,$00
                                    +      $00,$00,$00,$00
561b: 00 00 00 00+ visible_exits_u .bulk   $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$06,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00
5667: 00 00 00 00+ visible_exits_d .bulk   $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $06,$00,$00,$00,$00,$00,$00,$00,$00,$00,$0e,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
                                    +      $00,$00,$00,$00
                   ; 
                   ; Pointers to messages.
                   ; 
                   ; There are 83 messages (0-82), though message 0 is empty.
                   ; 
56b3: 51 36        messages        .dd2    T3651
56b5: 52 36                        .dd2    T3652
56b7: be 36                        .dd2    T36BE
56b9: c9 36                        .dd2    T36C9
56bb: d0 36                        .dd2    T36D0
56bd: e3 36                        .dd2    T36E3
56bf: 07 37                        .dd2    T3707
56c1: 0f 37                        .dd2    T370F
56c3: 18 37                        .dd2    T3718
56c5: 4f 37                        .dd2    T374F
56c7: 6e 37                        .dd2    T376E
56c9: 84 37                        .dd2    T3784
56cb: 9d 37                        .dd2    T379D
56cd: a0 37                        .dd2    T37A0
56cf: a6 37                        .dd2    T37A6
56d1: bd 37                        .dd2    T37BD
56d3: db 37                        .dd2    T37DB
56d5: e4 37                        .dd2    T37E4
56d7: eb 37                        .dd2    T37EB
56d9: 1a 38                        .dd2    T381A
56db: 4b 38                        .dd2    T384B
56dd: 6b 38                        .dd2    T386B
56df: 9a 38                        .dd2    T389A
56e1: bf 38                        .dd2    T38BF
56e3: ca 38                        .dd2    T38CA
56e5: e3 38                        .dd2    T38E3
56e7: 08 39                        .dd2    T3908
56e9: 87 39                        .dd2    T3987
56eb: 9c 39                        .dd2    T399C
56ed: a4 39                        .dd2    T39A4
56ef: b1 39                        .dd2    T39B1
56f1: cc 39                        .dd2    T39CC
56f3: e8 39                        .dd2    T39E8
56f5: 02 3a                        .dd2    T3A02
56f7: 18 3a                        .dd2    T3A18
56f9: 2f 3a                        .dd2    T3A2F
56fb: 3c 3a                        .dd2    T3A3C
56fd: 84 3a                        .dd2    T3A84
56ff: a1 3a                        .dd2    T3AA1
5701: e6 3a                        .dd2    T3AE6
5703: f8 3a                        .dd2    T3AF8
5705: 1b 3b                        .dd2    T3B1B
5707: 35 3b                        .dd2    T3B35
5709: 48 3b                        .dd2    T3B48
570b: 58 3b                        .dd2    T3B58
570d: 63 3b                        .dd2    T3B63
570f: 6a 3b                        .dd2    T3B6A
5711: 70 3b                        .dd2    T3B70
5713: 8d 3b                        .dd2    T3B8D
5715: 9e 3b                        .dd2    T3B9E
5717: cc 3b                        .dd2    T3BCC
5719: df 3b                        .dd2    T3BDF
571b: f2 3b                        .dd2    T3BF2
571d: 15 3c                        .dd2    T3C15
571f: 28 3c                        .dd2    T3C28
5721: 41 3c                        .dd2    T3C41
5723: 4f 3c                        .dd2    T3C4F
5725: 65 3c                        .dd2    T3C65
5727: 7c 3c                        .dd2    T3C7C
5729: bf 3c                        .dd2    T3CBF
572b: d0 3c                        .dd2    T3CD0
572d: 0c 3d                        .dd2    T3D0C
572f: 22 3d                        .dd2    T3D22
5731: 33 3d                        .dd2    T3D33
5733: 40 3d                        .dd2    T3D40
5735: 47 3d                        .dd2    T3D47
5737: 59 3d                        .dd2    T3D59
5739: a2 3d                        .dd2    T3DA2
573b: b4 3d                        .dd2    T3DB4
573d: cd 3d                        .dd2    T3DCD
573f: db 3d                        .dd2    T3DDB
5741: fd 3d                        .dd2    T3DFD
5743: 16 3e                        .dd2    T3E16
5745: 1f 3e                        .dd2    T3E1F
5747: 38 3e                        .dd2    T3E38
5749: 4c 3e                        .dd2    T3E4C
574b: 56 3e                        .dd2    T3E56
574d: 5d 3e                        .dd2    T3E5D
574f: 71 3e                        .dd2    T3E71
5751: a4 3e                        .dd2    T3EA4
5753: c2 3e                        .dd2    T3EC2
5755: dc 3e                        .dd2    T3EDC
5757: e3 3e                        .dd2    T3EE3
                   ; 
5759: 00 00 00 00+                 .junk   23

Symbol Table

Entry$0800
MainLoop$084e