(back to project page)

GAME2 Disassembly

                   ; 6502bench SourceGen v1.7.3
                   item_spiritLamp       .eq     $01    {const}
                   RWTSCMD_read          .eq     $01    {const}
                   STARVED_food          .eq     $01    {const}
                   PLAYER_Herd           .eq     $02    {const}
                   STARVED_rest          .eq     $02    {const}
                   PLAYER_Charn          .eq     $04    {const}
                   item_pan_bread        .eq     $05    {const}
                   item_fruit_nuts       .eq     $06    {const}
                   item_shuba            .eq     $07    {const}
                   item_berries          .eq     $0a    {const}
                   item_fallaKey         .eq     $0d    {const}
                   tile_brambles         .eq     $1c    {const}
                   tile_water            .eq     $20    {const}
                   LASTKEY               .eq     $02    {addr/1}         ;last key pressed via checkkey
                   TXTPTR                .eq     $03    {addr/2}         ;current tile position on text page 1
                   TXTCOL                .eq     $05    {addr/1}         ;prob col on 40x24 scrn
                   TXTROW                .eq     $06    {addr/1}         ;prob row on 40x24 scrn
                   temp08                .eq     $08
                   temp09                .eq     $09
                   temp0a                .eq     $0a
                   temp11_textlo         .eq     $11                     ; often used to hold text page address of tile (lo)
                   temp12_texthi         .eq     $12                     ; often used to hold text page address of tile (lo)
                   hires_addr            .eq     $14    {addr/2}
                   tileptr               .eq     $16    {addr/2}         ;pointer to current tile data
                   MASK                  .eq     $18    {addr/1}         ;may or may not be global
                   playerX               .eq     $19                     ; tile X of player
                   playerY               .eq     $1a                     ; tile Y of player
                   MAPPOS                .eq     $1b                     ; playfield position
                   MAPHALF               .eq     $1c                     ; playfield half (top/bottom); like top bit of MAPPOS
                   zp1d                  .eq     $1d    {addr/2}         ; used as a read ptr when drawing player; may be anim frame via $A3
                   zp1f                  .eq     $1f
                   PLAYER                .eq     $20                     ;active player (0-4)
                   timeOfDay             .eq     $21                     ; 0 (early morning) .. 7 (late night)
                   dayNum                .eq     $22                     ; day number (1-based)
                   levelSpirit           .eq     $23                     ; level of spirit
                   levelFood             .eq     $24                     ; level of food, max limit-1
                   levelRest             .eq     $25                     ; level of rest, max limit-1
                   levelStamina          .eq     $26                     ; level of stamina
                   limitSpirit           .eq     $27                     ; spirit limit
                   limitFood             .eq     $2a                     ; not shown, levelStamina/2 + 1
                   limitRest             .eq     $2b                     ; not shown, levelStamina/2 + 1
                   maxWeight             .eq     $2c                     ; max weight you can carry
                   homePos               .eq     $2d                     ; used when teleporting player home
                   homeHalf              .eq     $2e                     ; used when teleporting player home
                   homeX                 .eq     $2f                     ; used when teleporting player home
                   homeY                 .eq     $30                     ; used when teleporting player home
                   MON_INVFLAG           .eq     $32                     ;text mask (255=normal, 127=flash, 63=inv)
                   temp34_npctype        .eq     $34                     ; holds NPC type when $e0..$ef? Not really a temp.
                   doorNeshom            .eq     $35                     ; FF = door goes to Neshom house, 01 = Neshom realm
                   spokeTo               .eq     $37                     ; spoke to or bought from NPC while on this screen
                   fallaKeyOffered       .eq     $38                     ; if D'Ol Falla's key has been offered (?)
                   suppressSound0        .eq     $39                     ; $FF=suppress sound 0 for 1 call, set on inventory menu entry
                   litLamp               .eq     $3a                     ; slot number of lit lamp, or 0 if unlit
                   MON_PCH               .eq     $3b                     ;program counter save
                   STARVED               .eq     $3c                     ; 0 = ok, 1 = out of food, 2 = out of rest
                   GAMEOVER              .eq     $3d                     ;game over bool (0/1)
                   visionNum             .eq     $3e                     ; vision number to have next, 0..5
                   gainSpirit            .eq     $3f                     ; spirit gained so far, modulo 5
                   MON_A3H               .eq     $41                     ;general purpose
                   MON_A4L               .eq     $42                     ;general purpose
                   lampFuel              .eq     $44                     ; number of rooms left in lamp; 00..13
                   MON_A5H               .eq     $45                     ;general purpose
                   SOUNDFLG              .eq     $4a                     ;0 = sound off, 1 = on
                   NINEIDX               .eq     $55                     ;cur index into $900 block
                   ODDLINE_MASK          .eq     $5f    {addr/1}         ;and mask odd tile lines ($00 disables)
                   tileset               .eq     $60    {addr/1}         ;which tileset to use, 0 or 1
                   HTAB                  .eq     $64                     ; horiz text pos (next line at +$28)
                   INVTEXT               .eq     $66    {addr/1}         ;0=normal,1=inverse
                   INSIDE                .eq     $67                     ; Are we inside? Toggled when entering a door, or set manually on teleport.
                   zp6b_npcHere          .eq     $6b                     ; NPC is on this screen? (0=no, 1=yes)
                   npcX                  .eq     $6c                     ; NPC X location on this screen
                   npcY                  .eq     $6d                     ; NPC Y location on this screen
                   zp6e                  .eq     $6e                     ; set in NPC code; initial from RWTSBUF+227 & 0x0F
                   npcFacing             .eq     $6f                     ; NPC facing direction on this screen
                   WEIGHT                .eq     $70                     ; current item weight carried (< limitWeight)
                   MENUCOL               .eq     $71                     ;menu column (0..4)
                   MENUROW               .eq     $72                     ;menu row (0..3)
                   MENUCOL_NEXT          .eq     $73                     ;next menu col, used only during movement
                   MENUROW_NEXT          .eq     $74                     ;next menu row, used only during movement
                   temp75                .eq     $75
                   temp76                .eq     $76
                   selItemSlot           .eq     $77                     ; last selected item slot (00..FE or FF)
                   selItemNum            .eq     $78                     ; last selected item number (01..0E)
                   temp79                .eq     $79
                   temp7a                .eq     $7a
                   temp7b                .eq     $7b
                   TICKS                 .eq     $7c                     ; number of ticks until next minute (0..$FF)
                   MINUTES               .eq     $7d                     ; number of minutes until next time period (0..$25)
                   temp7e                .eq     $7e                     ; only used in $84CC sub
                   temp7f                .eq     $7f                     ; only used in $84CC sub
                   touchedWater          .eq     $80                     ; we touched water and will pass out
                   temp82                .eq     $82
                   waitMelody            .eq     $83                     ; always 0, but could be interrupt placeholder
                   VIRTBTN               .eq     $84                     ; virtual button press, used only in kbd handler
                   XDIR                  .eq     $85                     ;last x dir pressed, -1 (left) or 1 (right)
                   YDIR                  .eq     $86                     ;last y dir pressed, -1 (up) or 1 (down)
                   TICKING               .eq     $87                     ; 1 if timer is ticking, 0 if paused
                   animTimer             .eq     $88                     ; counts up to animDelay
                   temp89                .eq     $89    {addr/2}
                   temp8b                .eq     $8b
                   jumpFlag              .eq     $8c                     ; 1=jumping, 0=not
                   jumpFrame             .eq     $8d                     ; frame 1..4 (when jumpFlag=1)
                   nextRoomDir           .eq     $8f                     ; 00,01,02,03,04 -- next map room direction
                   animDelay             .eq     $90                     ; ticks to hold current player animation frame
                   FALLCNT               .eq     $92                     ;# of tiles we've fallen; $0A head bonked
                   bonkFrame             .eq     $93
                   flyFlag               .eq     $94                     ; # 1 when flying (button pressed in air after > 2 tiles fell)
                   FACING                .eq     $95                     ;FF=left, 01=right facing
                   takingStep            .eq     $96                     ; 0 or 1 depending on taking step in cycle
                   runFlag               .eq     $99                     ; 1=running, 0=not
                   crawlFlag             .eq     $9a                     ; 1=crawling, 0=not
                   crouchFlag            .eq     $9b                     ; 1=crouching; reset on next frame
                   playerXold            .eq     $9c
                   playerYold            .eq     $9d
                   doorTransit           .eq     $9e                     ; 1..3 (entering onscreen door #) or 0
                   enterMenu             .eq     $9f                     ; show menu on next frame
                   bonkAlt               .eq     $a1                     ; 0 or 1 to alternate bonk frames
                   MOVING                .eq     $a2                     ;1=moving,0=stationary
                   animFrame             .eq     $a3                     ; character anim frame (see $6ED6)
                   animFrame_unused      .eq     $a4                     ; always $A3+1; never read, seems unused
                   XMOVFLG               .eq     $af
                   YMOVFLG               .eq     $b0                     ;FF=up,01=down (edge at end of action)
                   JOYFLG                .eq     $b1                     ;01 = joystick, 00 = kbd
                   erasePlayer           .eq     $b2                     ; flag to erase player on next frame
                   longJump              .eq     $b4                     ; 2 (stamina >= 20) or 1 (stamina < 20); if 2, prolongs jump in frame 3
                   tempB7                .eq     $b7                     ; temp used only in handle_food_rest
                   foodRestTimer         .eq     $b8                     ; remaining time until food/rest decreases
                   zpBC_bellrings        .eq     $bc                     ; if 1, spirit bell rings, if 0, get attacked
                   DEMOWAIT              .eq     $c0                     ; number of frames to wait
                   DEMOPTR               .eq     $c2                     ; ptr to current demo byte
                   DEMOFLG               .eq     $c4                     ; 00 = game, 01 = demo mode
                   DEMOTEXT              .eq     $c8                     ; demo text to show (1..5, or 0 = none)
                   tileFeet              .eq     $e0                     ;  0, 0 tile at player's feet
                   tileFeetLeft          .eq     $e1                     ; -1, 0 tile left of player's feet
                   tileFeetRight         .eq     $e2                     ;  1, 0 tile right of player's feet
                   tileUnder             .eq     $e3                     ;  0, 1 tile under player's feet
                   tileUnderLeft         .eq     $e4                     ; -1, 1 left tile under player's feet
                   tileUnderRight        .eq     $e5                     ;  1, 1 right tile under player's feet
                   tileKnee              .eq     $e6                     ;  0,-1 tile 1 above player's feet
                   tileArm               .eq     $e7                     ;  0,-2 tile 2 at arm height (item on table/shelf)
                   tileShoulder          .eq     $e8                     ;  0,-3 tile at shoulder height
                   tileArmLeft           .eq     $e9                     ; -1,-2 tile left at arm level (table/shelf)
                   tileArmRight          .eq     $ea                     ;  1,-2 tile right at arm level (table/shelf)
                   ySolid                .eq     $f0                     ; selected tile is solid ground
                   xSolid                .eq     $f1                     ; selected tile prevents x motion
                   climbable             .eq     $f2                     ; selected tile is a ladder/vine
                   digits                .eq     $f9    {addr/5}         ; decimal digit output of num_to_str
                   RWTSBUF               .eq     $0200  {addr/256}       ; 256-byte sector r/w buffer
                   RWTSBUF_npc           .eq     $02e1                   ; nonzero if NPC is present; may contain data in top 4 bits
                   RWTSBUF_npcX          .eq     $02e4                   ; NPC initial X location
                   RWTSBUF_npcY          .eq     $02e5                   ; NPC initial Y location
                   RWTSBUF_npcnum        .eq     $02f1                   ; NPC number (00..??)  ; $49 raamo
                   RWTSBUF_npctype       .eq     $02f2                   ; 0 offers item, 1 animal, $d0 dol falla, $40 gain level, $20-$2f ??, $c0 door 1, $c1 door 2, $e0-$ef,
                   RWTS_IOB_track        .eq     $0304
                   RWTS_IOB_sector       .eq     $0305
                   RWTS_IOB_buf          .eq     $0308
                   RWTS_IOB_command      .eq     $030c
                   DIRECT_RWTS           .eq     $0315
                   SCREEN_0900           .eq     $0900
                   GAME1_player_names    .eq     $1ad0
                   GAME1_tileset_bitmap  .eq     $1d00
                   GAME1_hireslo         .eq     $1d40
                   GAME1_hireshi         .eq     $1d60
                   GAME1_texthi          .eq     $1d80
                   GAME1_textlo          .eq     $1da0
                   GAME1_BITTAB0         .eq     $1db8
                   GAME1_BITTAB1         .eq     $1db9
                   GAME1_BITTAB2         .eq     $1dba
                   GAME1_BITTAB3         .eq     $1dbb
                   GAME1_BITTAB4         .eq     $1dbc
                   GAME1_BITTAB5         .eq     $1dbd
                   GAME1_BITTAB6         .eq     $1dbe
                   GAME1_BITTAB7         .eq     $1dbf
                   GAME1_player_stats    .eq     $1dc0
                   GAME1_odd_col_mask    .eq     $1fa0
                   GAME1_even_col_mask   .eq     $1fb0
                   GAME1_odd_col_even_line_mask .eq $1fc0
                   GAME1_even_col_even_line_mask .eq $1fd0
                   GAME1_odd_col_odd_line_mask .eq $1fe0
                   GAME1_even_col_odd_line_mask .eq $1ff0
                   GAME1_chardata        .eq     $2c00
                   GAME1_tileset1_masks  .eq     $2e00
                   GAME1_tileset0_masks  .eq     $3700
                   SCRN_demo_handler     .eq     $9600
                   SCRN_show_demo_text   .eq     $9603
                   SCRN_heal             .eq     $9c00
                   SCRN_grunspreke       .eq     $9c03
                   SCRN_kiniport         .eq     $9c06
                   SCRN_speak            .eq     $9c0c
                   SCRN_pense            .eq     $9c0f
                   SCRN_sell             .eq     $9c15
                   SCRN_offer            .eq     $9c18
                   SCRN_triumph_melody   .eq     $9c1e
                   SCRN_warm_start       .eq     $a840
                   SCRN_sound_status     .eq     $a849
                   state_npc1            .eq     $b200
                   state_npc             .eq     $b280                   ; per npc bitfield; 7=gained a level from this NPC; 0..6=last spoken daynum or 0..4=time of day (NPC $E0..$EF)
                   itemStatePos          .eq     $b300  {addr/256}       ; 256 map positions, one per item
                   itemStateCol          .eq     $b400  {addr/256}       ; 256 column tile positions, one per item
                   itemState             .eq     $b500  {addr/256}       ; 7=mappos high bit, 6=in world, 5=in inv, 4..0=map row
                   inv_shuba             .eq     $b558  {addr/20}
                   inv_token             .eq     $b56c  {addr/75}
                   SCRN_play_melody      .eq     $b600
                   SCRN_play_sound       .eq     $b603
                   SCRN_play_sound_0     .eq     $b606
                   SCRN_chkkey           .eq     $b609
                   BUTN0                 .eq     $c061                   ;R switch input 0 / open-apple
                   BUTN1                 .eq     $c062                   ;R switch input 1 / closed-apple
                   MON_PREAD             .eq     $fb1e                   ;read paddle specifed by X-reg, return in Y-reg

                                         .org    $6000
6000: 4c 00 5b                           jmp     $5b00

                   ; Common external entry vectors for intermodule jumps.
6003: 4c a9 67     GAME2_drawtile        jmp     drawtile

6006: 4c e6 63     GAME2_cleartext       jmp     cleartext

                   GAME2_write_tiles_to_text
6009: 4c 8b 64                           jmp     write_tiles_to_text     ;local only

600c: 4c d6 66     GAME2_PRNTSTR         jmp     PRNTSTR

600f: 4c 09 67     GAME2_printchar       jmp     printchar

6012: 4c e1 69     GAME2_delayXtimes256  jmp     delayXtimes256

6015: 4c a2 69     GAME2_swapzp8         jmp     swapzp8

6018: 4c 6c 67                           jmp     drawfield               ;vector never used

601b: 4c a3 66     GAME2_teleport_home   jmp     teleport_home           ;local only

601e: 4c 3c 64     GAME2_read_playfield  jmp     read_playfield

6021: 4c 63 61     GAME2_read_0900       jmp     read_0900_next          ;read next byte at $0900

6024: 4c 00 b6     GAME2_play_melody     jmp     SCRN_play_melody

6027: 4c 57 60     GAME2_intro           jmp     intro?

602a: 4c a3 61                           jmp     move_room

602d: 4c 52 61                           jmp     @cont

6030: 4c b6 69     GAME2_copypages       jmp     copypages

6033: 4c cf 69     GAME2_clearpages      jmp     clearpages

6036: 4c ea 69     GAME2_delay2          jmp     delay2

6039: 4c 6f 61     GAME2_player_init     jmp     player_init             ;vector never used

603c: 4c 77 60                           jmp     L6077

603f: 4c bf 6a     GAME2_init_item_state jmp     init_item_state         ;Read T22,S00..02 into $B300..$B5FF

                   GAME2_calc_hires_textpos
6042: 4c 5b 68                           jmp     calc_hires_textpos

6045: 4c b3 67     GAME2_writetile       jmp     writetile

6048: 4c 82 60                           jmp     game_loop?

604b: 4c 7f 64     L604B                 jmp     L647F                   ;might redraw screen after drop/take lamp

                   ; MENUFLG is non-zero. Pop up menu, await selection, and return.
604e: 20 00 77     enter_menu            jsr     GAME2_action_menu
6051: a9 00                              lda     #$00
6053: 85 9f                              sta     enterMenu
6055: f0 2b                              beq     game_loop?              ;always

6057: 20 8e 62     intro?                jsr     L628E                   ;might be general game loop
605a: a5 c9                              lda     $c9
605c: c9 0d                              cmp     #$0d                    ;$c9 == #$0d during intro
605e: d0 17                              bne     L6077
6060: 20 e6 63                           jsr     cleartext
6063: a9 01                              lda     #$01                    ;set demo mode
6065: 85 c4                              sta     DEMOFLG
6067: a5 d0                              lda     $d0
6069: 10 09                              bpl     L6074                   ;if in gameplay mode (??)
606b: 20 e8 62                           jsr     L62E8
606e: 20 8e 62                           jsr     L628E
6071: 4c 77 60                           jmp     L6077

6074: 20 b2 62     L6074                 jsr     L62B2
6077: 20 9f 62     L6077                 jsr     L629F
607a: a9 00                              lda     #$00
607c: 85 88                              sta     animTimer
607e: a9 08                              lda     #$08
6080: 85 90                              sta     animDelay
                   NOTE: Multiple entries
6082: a9 01        game_loop?            lda     #$01                    ;start game timer
6084: 85 87                              sta     TICKING
6086: 20 00 6b     tick0                 jsr     GAME2_next_frame        ;entered from multiple subs
6089: a2 0a                              ldx     #$0a
608b: a5 6b                              lda     zp6b_npcHere            ;check $6b
608d: f0 02                              beq     @delay                  ;0, delay $0A * 256
608f: a2 06                              ldx     #$06                    ;!0, delay $06 * 256, allowing more time for NPC CPU?
6091: 20 e1 69     @delay                jsr     delayXtimes256          ;delay X * 256
6094: a5 87                              lda     TICKING
6096: d0 ee                              bne     tick0
6098: a5 8f                              lda     nextRoomDir
609a: d0 48                              bne     move_next_room
                   ; Below is a state machine which checks several flags/values in zero page in
                   ; order, and performs the first non-zero action it finds.
609c: a5 9e                              lda     doorTransit             ;transiting a door? (1..3)
609e: f0 03                              beq     @check_menu_entry
60a0: 4c d6 61                           jmp     enterDoor

60a3: a5 9f        @check_menu_entry     lda     enterMenu               ;enter menu on this frame?
60a5: f0 03                              beq     @no
60a7: 4c 4e 60                           jmp     enter_menu

60aa: a5 80        @no                   lda     touchedWater
60ac: f0 06                              beq     L60B4
60ae: 4c 6c 66                           jmp     found_near_water

60b1: 4c                                 .dd1    $4c
60b2: 86                                 .dd1    $86
60b3: 60                                 .dd1    $60

60b4: a5 c6        L60B4                 lda     $c6
60b6: f0 03                              beq     L60BB
60b8: 4c 0e 63                           jmp     L630E

                   ; Show demo text on this frame if DEMOTEXT is 1..5. Otherwise continue.
                   ; Note that demo text 5 is clears text; 0 simply checks the next action.
60bb: a5 c8        L60BB                 lda     DEMOTEXT                ;demo text to show 1..5, or 0 for not demo
60bd: f0 0a                              beq     check_gameover
60bf: 20 03 96                           jsr     SCRN_show_demo_text
60c2: a9 00                              lda     #$00                    ;do not update on next frame
60c4: 85 c8                              sta     DEMOTEXT
60c6: 4c 82 60                           jmp     game_loop?

60c9: a5 3d        check_gameover        lda     GAMEOVER
60cb: f0 03                              beq     check_starvation
60cd: 4c 36 6a                           jmp     game_over

60d0: a5 3c        check_starvation      lda     STARVED
60d2: f0 03                              beq     check_spirit_bell_rings ;we're fine
60d4: 4c 66 63                           jmp     spent_a_day_recovering  ;starved of food or rest

                   check_spirit_bell_rings
60d7: a5 bc                              lda     zpBC_bellrings
60d9: f0 03                              beq     @get_attacked
60db: 4c f4 69                           jmp     spirit_bell_rings

60de: 20 1e 77     @get_attacked         jsr     GAME2_attacked          ;unclear when this happens
60e1: 4c 82 60                           jmp     game_loop?

                   ; Based on the value in nextRoomDir, update the user's map position by 1 offset
                   ; to the top (01), right (02), bottom (03) or left (04). Then load the new room
                   ; and continue.
60e4: a5 8f        move_next_room        lda     nextRoomDir             ;this was already in A, in fact
60e6: c9 01                              cmp     #$01
60e8: d0 15                              bne     L60FF
60ea: 38                                 sec
60eb: a5 1b                              lda     MAPPOS
60ed: e9 20                              sbc     #$20
60ef: 85 1b                              sta     MAPPOS
60f1: b0 02                              bcs     L60F5
60f3: c6 1c                              dec     MAPHALF
60f5: 20 a3 61     L60F5                 jsr     move_room
60f8: a9 12                              lda     #$12
60fa: 85 1a                              sta     playerY
60fc: 4c 52 61                           jmp     @cont

60ff: c9 02        L60FF                 cmp     #$02
6101: d0 1d                              bne     L6120
6103: a5 1b                              lda     MAPPOS
6105: 29 1f                              and     #$1f
6107: c9 1f                              cmp     #$1f
6109: d0 09                              bne     L6114
610b: a5 1b                              lda     MAPPOS
610d: 29 e0                              and     #$e0
610f: 85 1b                              sta     MAPPOS
6111: 4c 16 61                           jmp     L6116

6114: e6 1b        L6114                 inc     MAPPOS
6116: 20 a3 61     L6116                 jsr     move_room
6119: a9 00                              lda     #$00
611b: 85 19                              sta     playerX
611d: 4c 52 61                           jmp     @cont

6120: c9 03        L6120                 cmp     #$03
6122: d0 15                              bne     L6139
6124: 18                                 clc
6125: a5 1b                              lda     MAPPOS
6127: 69 20                              adc     #$20
6129: 85 1b                              sta     MAPPOS
612b: 90 02                              bcc     L612F
612d: e6 1c                              inc     MAPHALF
612f: 20 a3 61     L612F                 jsr     move_room
6132: a9 00                              lda     #$00
6134: 85 1a                              sta     playerY
6136: 4c 52 61                           jmp     @cont

6139: a5 1b        L6139                 lda     MAPPOS
613b: 29 1f                              and     #$1f
613d: d0 0a                              bne     L6149
613f: 18                                 clc
6140: a5 1b                              lda     MAPPOS
6142: 69 1f                              adc     #$1f
6144: 85 1b                              sta     MAPPOS
6146: 4c 4b 61                           jmp     L614B

6149: c6 1b        L6149                 dec     MAPPOS
614b: 20 a3 61     L614B                 jsr     move_room
614e: a9 27                              lda     #$27
6150: 85 19                              sta     playerX
6152: a9 00        @cont                 lda     #$00
6154: 85 8f                              sta     nextRoomDir
6156: 20 03 6b                           jsr     GAME2_draw_player
6159: 20 82 68                           jsr     handle_npc2?
615c: a9 01                              lda     #$01                    ;resume tick, stopped when we started room transition
615e: 85 87                              sta     TICKING
6160: 4c 86 60                           jmp     tick0

                   ; Read next byte in $0900 block (pointed to by $55) and return it in A.
                   ; The $55 ptr is (pre)incremented. All access to $55 is encapsulated here.
                   xsav                  .var    $1e    {addr/1}         ;save x

6163: 86 1e        read_0900_next        stx     xsav
6165: e6 55                              inc     NINEIDX
6167: a6 55                              ldx     NINEIDX
6169: bd 00 09                           lda     SCREEN_0900,x
616c: a6 1e                              ldx     xsav
616e: 60                                 rts

                   ; Init player. Copies player's starting stats to active stats, resets the time,
                   ; and sets carry weight to 0 (note: inventory is not zeroed out here). The demo
                   ; player (5) has a shuba added.
616f: a6 20        player_init           ldx     PLAYER
6171: a5 c4                              lda     DEMOFLG
6173: f0 07                              beq     @notdemo
6175: a2 05                              ldx     #$05                    ;phantom character 5 during demo
6177: a9 60                              lda     #%01100000              ;give the demo player a shuba
6179: 8d 58 b5                           sta     inv_shuba
617c: bc 9d 61     @notdemo              ldy     player_stat_offsets,x
617f: a2 0d                              ldx     #$0d                    ;copy $0E bytes from player stats to cur stats
6181: b9 c0 1d     @loop                 lda     GAME1_player_stats,y    ;pointer to END of player's stats
6184: 95 23                              sta     levelSpirit,x
6186: 88                                 dey                             ;copy from end to beginning
6187: ca                                 dex
6188: 10 f7                              bpl     @loop
618a: a9 00                              lda     #$00
618c: 85 21                              sta     timeOfDay
618e: 85 70                              sta     WEIGHT
6190: 85 3e                              sta     visionNum
6192: 85 3f                              sta     gainSpirit
6194: a9 01                              lda     #$01
6196: 85 22                              sta     dayNum
6198: a9 23                              lda     #$23
619a: 85 7d                              sta     MINUTES
619c: 60                                 rts

                   ; Offset to END of player stats. E.g. $0D = $00..$0D, $1B = $0E..$1B.
619d: 0d           player_stat_offsets   .dd1    $0d
619e: 1b                                 .dd1    $1b
619f: 29                                 .dd1    $29
61a0: 37                                 .dd1    $37
61a1: 45                                 .dd1    $45
61a2: 53                                 .dd1    $53

                   ; Called when moving to another room. This will expend 1 lamp fuel (if the lamp
                   ; is lit), destroy your lit lamp if it runs out of fuel, and then read the new
                   ; room data from disk.
61a3: a5 44        move_room             lda     lampFuel
61a5: f0 14                              beq     L61BB                   ;already out of fuel
61a7: c6 44                              dec     lampFuel
61a9: d0 10                              bne     L61BB                   ;still has fuel left
61ab: a6 3a                              ldx     litLamp                 ;lamp goes out
61ad: a9 00                              lda     #$00
61af: 85 3a                              sta     litLamp
61b1: 9d 00 b5                           sta     itemState,x             ;destroy lamp item
61b4: 8a                                 txa
61b5: 20 03 77                           jsr     GAME2_slot_to_item
61b8: 20 12 77                           jsr     GAME2_lose_weight       ;remove its weight
61bb: 20 06 6b     L61BB                 jsr     GAME2_erase_player
61be: a5 67                              lda     INSIDE
61c0: d0 05                              bne     @light
61c2: 20 15 64                           jsr     select_tileset_harder
61c5: f0 04                              beq     @dark
61c7: 20 3c 64     @light                jsr     read_playfield
61ca: 60                                 rts

61cb: a9 00        @dark                 lda     #$00
61cd: 8d e1 02                           sta     RWTSBUF_npc             ;remove NPC presence by overwriting read map data
61d0: 20 c1 63                           jsr     clearfield
61d3: 4c 82 68                           jmp     handle_npc2?

                   ********************************************************************************
                   * $9E is non-zero here, implying we are transiting a door. The next 2          *
                   * subroutines are special teleports, based on whether $35 is FF or 01. That's  *
                   * because when you sleep in D'Ol Neshom's house, the door changes to send you  *
                   * to the cloud realm (01), and the return door sends you back to her house     *
                   * (FF). (It's possible the return door must be handled specially because it's  *
                   * not a standard door tile, so can't use normal door teleporting, but          *
                   * uncertain.)                                                                  *
                   *                                                                              *
                   * If $35 is 0, branch to the 3rd sub, which handles doors and repositioning    *
                   * more generally.                                                              *
                   ********************************************************************************
61d6: a5 35        enterDoor             lda     doorNeshom
61d8: f0 2e                              beq     @normal_door            ;zero, handle regular doors
                   ; 01 sends you to the cloud realm where D'Ol Neshom gives you the spirit bell.
61da: 30 17                              bmi     @to_dol_neshom          ;FF, go to her house
61dc: a9 be                              lda     #$be                    ;otherwise, teleport
61de: 85 1b                              sta     MAPPOS
61e0: a9 12                              lda     #$12
61e2: 85 19                              sta     playerX
61e4: a9 0e                              lda     #$0e
61e6: 85 1a                              sta     playerY
61e8: a9 00                              lda     #$00
61ea: 85 67                              sta     INSIDE
61ec: a9 ff                              lda     #$ff                    ;next door takes you back
61ee: 85 35                              sta     doorNeshom              ;to her house
61f0: 4c 68 62                           jmp     do_door_entry

                   ; FF sends you to the D'Ol Neshom's small house in the high trees where if you
                   ; sleep, you are transported to a cloud realm and she grants you the spirit
                   ; bell.
61f3: a9 09        @to_dol_neshom        lda     #$09
61f5: 85 1b                              sta     MAPPOS
61f7: a9 18                              lda     #$18
61f9: 85 19                              sta     playerX
61fb: a9 0d                              lda     #$0d
61fd: 85 1a                              sta     playerY
61ff: a9 00                              lda     #$00
6201: 85 67                              sta     INSIDE
6203: 85 35                              sta     doorNeshom
6205: 4c 68 62                           jmp     do_door_entry

                   NOTE: Handles, I think, entering doors. Checks $02F2 for $C0/C1, which I think
                   signify 2 types of locked doors. Then checks a location in game storage,
                   probably whether the player has one of 2 keys, and a final zp location which is
                   unknown. 
                   
                   If the door is unlocked, OR $02F2 is any other value, then teleports the user to
                   the new map position. It's unclear what the other values mean.
                   
                   From 02F3..F5, 02F6..8, or 02F9..B are a position triple consisting of the new
                   map position (including high bit), and probably character X and Y. Which one to
                   use is determined by $9E (unclear why).
6208: ad f2 02     @normal_door          lda     RWTSBUF_npctype
620b: c9 c0                              cmp     #$c0                    ;possibly locked door, or presence of certain NPC
620d: d0 2a                              bne     L6239
620f: ad 34 b2                           lda     $b234                   ;0=possibly locked (either has_key, or door_unlocked)
6212: d0 2e                              bne     L6242
6214: a5 42        L6214                 lda     MON_A4L                 ;0=locked (either has_key, or door_unlocked)
6216: d0 2a                              bne     L6242
6218: 20 d6 66                           jsr     PRNTSTR
621b: 01                                 .dd1    $01
621c: d4 c8 c5 a0+                       .str    ↑“THE DOOR IS LOCKED”
622e: ff                                 .dd1    $ff
622f: 20 06 77                           jsr     GAME2_message_wait
6232: a9 00                              lda     #$00
6234: 85 9e                              sta     doorTransit             ;note $9e is 1..3 below
6236: 4c 82 60                           jmp     game_loop?

6239: c9 c1        L6239                 cmp     #$c1                    ;possibly locked door, or presence of certain NPC
623b: d0 05                              bne     L6242
623d: ad 35 b2                           lda     $b235                   ;possibly inventory check for this key
6240: f0 d2                              beq     L6214
6242: a4 9e        L6242                 ldy     doorTransit             ;Y is 1..3 here (on entry must be nonzero)
6244: be 8a 62                           ldx     @posptr-1,y
6247: bd 01 02                           lda     RWTSBUF+1,x
624a: 85 1b                              sta     MAPPOS                  ;first byte is map position
624c: a0 00                              ldy     #$00
624e: bd 02 02                           lda     RWTSBUF+2,x             ;second byte is map side (bit 7) + something (0..6)
6251: 48                                 pha
6252: 29 80                              and     #$80                    ;check bit 7
6254: f0 01                              beq     L6257                   ;bit 7 unset, MAPSIDE=0
6256: c8                                 iny
6257: 84 1c        L6257                 sty     MAPHALF                 ;bit 7 set, MAPSIDE=1
6259: 68                                 pla
625a: 29 7f                              and     #$7f                    ;bits 0..6 of second byte
625c: 85 19                              sta     playerX
625e: bd 03 02                           lda     RWTSBUF+3,x
6261: 29 7f                              and     #$7f                    ;bits 0..6 of third byte
6263: 85 1a                              sta     playerY
6265: 20 06 6b                           jsr     GAME2_erase_player
6268: 20 3c 64     do_door_entry         jsr     read_playfield          ;read new map screen from disk
626b: a9 00                              lda     #$00                    ;Toggle FACING between 01 and FF
626d: 38                                 sec                             ;so the player faces the opposite direction
626e: e5 95                              sbc     FACING                  ;when entering/exiting a door
6270: 85 95                              sta     FACING
6272: 20 21 6b                           jsr     L6B21
6275: 20 03 6b                           jsr     GAME2_draw_player
6278: 20 82 68                           jsr     handle_npc2?
627b: a9 00                              lda     #$00                    ;reset triple posptr to 0
627d: 85 9e                              sta     doorTransit
627f: a5 67                              lda     INSIDE
6281: 49 01                              eor     #$01                    ;bitflip
6283: 85 67                              sta     INSIDE
6285: 20 20 6a                           jsr     L6A20
6288: 4c 82 60                           jmp     game_loop?

628b: f2           @posptr               .dd1    $f2                     ;$2f3,$2f4,$2f5
628c: f5                                 .dd1    $f5                     ;$2f6,$2f7,$2f8
628d: f8                                 .dd1    $f8                     ;$2f9,$2fa,$2fb

628e: 20 bf 6a     L628E                 jsr     init_item_state
6291: a9 b2                              lda     #$b2
6293: a2 01                              ldx     #$01
6295: 20 cf 69                           jsr     clearpages
6298: a9 ff                              lda     #$ff
629a: 85 b8                              sta     foodRestTimer
629c: 4c 6f 61                           jmp     player_init

629f: 20 21 6b     L629F                 jsr     L6B21
62a2: a5 31                              lda     $31
62a4: 85 19                              sta     playerX
62a6: a5 32                              lda     MON_INVFLAG
62a8: 85 1a                              sta     playerY
62aa: 20 03 6b                           jsr     GAME2_draw_player
62ad: a9 00                              lda     #$00
62af: 85 88                              sta     animTimer
62b1: 60                                 rts

62b2: a9 9d        L62B2                 lda     #$9d
62b4: 85 1b                              sta     MAPPOS
62b6: a9 00                              lda     #$00
62b8: 85 1c                              sta     MAPHALF
62ba: a9 01                              lda     #$01
62bc: 85 67                              sta     INSIDE
62be: 20 a3 61                           jsr     move_room
62c1: a9 10                              lda     #$10
62c3: 85 c2                              sta     DEMOPTR
62c5: a9 9b                              lda     #$9b
62c7: 85 c3                              sta     $c3
62c9: a9 06                              lda     #$06
62cb: 85 31                              sta     $31
62cd: a9 0e                              lda     #$0e
62cf: 85 32                              sta     MON_INVFLAG
62d1: a9 01                              lda     #$01
62d3: 85 9a                              sta     crawlFlag
62d5: 85 c0                              sta     DEMOWAIT
62d7: a9 ff                              lda     #$ff
62d9: 85 95                              sta     FACING
62db: 4c 8e 62                           jmp     L628E

62de: a0                                 .dd1    $a0
62df: b3                                 .dd1    $b3
62e0: a2                                 .dd1    $a2
62e1: 03                                 .dd1    $03
62e2: 4c                                 .dd1    $4c
62e3: b6                                 .dd1    $b6
62e4: 69                                 .dd1    $69
                   ; Pages that T22,S00..02 are read into
62e5: b3           item_state_pages      .dd1    $b3
62e6: b4                                 .dd1    $b4
62e7: b5                                 .dd1    $b5

62e8: a9 e4        L62E8                 lda     #$e4
62ea: 85 1b                              sta     MAPPOS
62ec: a9 00                              lda     #$00
62ee: 85 1c                              sta     MAPHALF
62f0: 85 67                              sta     INSIDE
62f2: 20 a3 61                           jsr     move_room
62f5: a9 00                              lda     #$00
62f7: 85 c2                              sta     DEMOPTR
62f9: a9 99                              lda     #$99
62fb: 85 c3                              sta     $c3
62fd: a9 18                              lda     #$18
62ff: 85 31                              sta     $31
6301: a9 0e                              lda     #$0e
6303: 85 32                              sta     MON_INVFLAG
6305: a9 01                              lda     #$01
6307: 85 c0                              sta     DEMOWAIT
6309: a9 ff                              lda     #$ff
630b: 85 95                              sta     FACING
630d: 60                                 rts

630e: a2 00        L630E                 ldx     #$00
6310: 86 c6                              stx     $c6
6312: c9 ff                              cmp     #$ff
6314: d0 03                              bne     L6319
6316: 4c 40 a8     L6316                 jmp     SCRN_warm_start

6319: c9 9d        L6319                 cmp     #$9d
631b: d0 06                              bne     L6323
631d: 20 b2 62                           jsr     L62B2
6320: 4c 77 60                           jmp     L6077

6323: a5 d0        L6323                 lda     $d0
6325: c9 01                              cmp     #$01
6327: f0 ed                              beq     L6316
6329: 20 e8 62                           jsr     L62E8
632c: 4c 77 60                           jmp     L6077

                   tileset_tmp           .var    $5c    {addr/1}

632f: a9 00        select_tileset        lda     #$00
6331: 85 5c                              sta     tileset_tmp             ;tileset 0 (temp var?)
6333: a5 1c                              lda     MAPHALF
6335: f0 0a                              beq     @choose                 ;top half, choose tileset
6337: a5 1b                              lda     MAPPOS                  ;bottom half, check pos
6339: c9 80                              cmp     #$80                    ;test pos top bit
633b: 90 04                              bcc     @choose                 ;side 1 pos 00..7F, choose tileset
633d: e6 5c        @tileset1             inc     tileset_tmp             ;set tileset 1 ($5C=1)
633f: d0 17                              bne     @set_tileset            ;always
6341: a5 1b        @choose               lda     MAPPOS
                   ; Special treatment for side 0 pos $9d,$9e, and side 0/1 pos $7d,$7e -- always
                   ; use tileset 0.
6343: c9 9d                              cmp     #$9d
6345: f0 11                              beq     @set_tileset
6347: c9 9e                              cmp     #$9e
6349: f0 0d                              beq     @set_tileset
634b: c9 7d                              cmp     #$7d
634d: f0 09                              beq     @set_tileset
634f: c9 7e                              cmp     #$7e
6351: f0 05                              beq     @set_tileset
                   ; Choose tileset for remaining positions -- 000..0FF and 100..17F -- using the
                   ; tileset bitmap. (Minus 4 special positions above.) Note that 0160..017F is
                   ; ground level.
6353: 20 15 64                           jsr     select_tileset_harder
6356: f0 e5                              beq     @tileset1               ;Z clear, use tileset 1
6358: a5 5c        @set_tileset          lda     tileset_tmp
635a: c5 60                              cmp     tileset                 ;looks useless; does set Z if tileset differed
635c: f0 02                              beq     @rts                    ;however Z is unused by caller
635e: 85 60                              sta     tileset
6360: 60           @rts                  rts

6361: a6 5d                              ldx     $5d
6363: 4c 82 60                           jmp     game_loop?

                   spent_a_day_recovering
6366: 20 a3 66                           jsr     teleport_home
6369: a9 04                              lda     #$04
636b: 20 d6 66                           jsr     PRNTSTR
636e: 01                                 .dd1    $01
636f: d9 cf d5 a0+                       .str    ↑“YOU SPENT A DAY RECOVERING”
6389: ff                                 .dd1    $ff
638a: 20 d6 66                           jsr     PRNTSTR
638d: 29                                 .dd1    $29
638e: c6 d2 cf cd+                       .str    ↑“FROM LACK OF ”
639b: ff                                 .dd1    $ff
639c: a5 3c                              lda     STARVED
639e: c9 01                              cmp     #STARVED_food           ;01 = lack of food
63a0: d0 0c                              bne     @of_rest
63a2: 20 d6 66                           jsr     PRNTSTR
63a5: 36                                 .dd1    $36
63a6: c6 cf cf c4                        .str    ↑“FOOD”
63aa: ff                                 .dd1    $ff
63ab: 4c b7 63                           jmp     @end

63ae: 20 d6 66     @of_rest              jsr     PRNTSTR
63b1: 36                                 .dd1    $36
63b2: d2 c5 d3 d4                        .str    ↑“REST”
63b6: ff                                 .dd1    $ff
63b7: a9 00        @end                  lda     #$00                    ;clear starved attr
63b9: 85 3c                              sta     STARVED
63bb: 20 06 77                           jsr     GAME2_message_wait
63be: 4c 82 60                           jmp     game_loop?

63c1: a9 00        clearfield            lda     #$00
63c3: 85 05                              sta     TXTCOL
63c5: 85 06                              sta     TXTROW
63c7: aa                                 tax
63c8: 20 93 67     @loop                 jsr     gettextaddr
63cb: a9 00                              lda     #$00
63cd: 81 03                              sta     (TXTPTR,x)
63cf: e6 05                              inc     TXTCOL
63d1: a5 05                              lda     TXTCOL
63d3: c9 28                              cmp     #40
63d5: d0 f1                              bne     @loop
63d7: a9 00                              lda     #$00
63d9: 85 05                              sta     TXTCOL
63db: e6 06                              inc     TXTROW
63dd: a5 06                              lda     TXTROW
63df: c9 14                              cmp     #20
63e1: d0 e5                              bne     @loop
63e3: 4c 6c 67                           jmp     drawfield

                   coltmp                .var    $08    {addr/1}         ;column counter (+216)
                   rowtmp                .var    $65    {addr/1}         ;row counter (+252)

63e6: a9 14        cleartext             lda     #$14                    ;from $6006 vec
63e8: 85 06                              sta     TXTROW
63ea: a9 fc                              lda     #252                    ;256 - 252 = 4 (rows)
63ec: 85 65                              sta     rowtmp
63ee: a9 d8        @row                  lda     #216                    ;256 - 16 = 40 (cols)
63f0: 85 08                              sta     coltmp
63f2: a9 00                              lda     #$00
63f4: 85 05                              sta     TXTCOL
63f6: a9 00        @col                  lda     #$00
63f8: 20 e6 67                           jsr     calc_tile
63fb: 20 5b 68                           jsr     calc_hires_textpos
63fe: 20 b3 67                           jsr     writetile
6401: e6 05                              inc     TXTCOL                  ;next column
6403: e6 08                              inc     coltmp                  ;40 times (counting up from 216!)
6405: d0 ef                              bne     @col
6407: e6 06                              inc     TXTROW                  ;next row
6409: e6 65                              inc     rowtmp                  ;4 times (counting up from 252!)
640b: d0 e1                              bne     @row
640d: 60                                 rts

640e: 20                                 .dd1    $20
640f: e6                                 .dd1    $e6
6410: 63 20 6c 67+                       .str    “c lg`”

                   ********************************************************************************
                   * Use the tileset bitmap to select tileset 0 or 1 based on the 9-bit map       *
                   * position. The top 6 bits select the bitmap byte, and the bottom 3 bits       *
                   * select the bit in that byte. This code is not called for certain positions   *
                   * (see select_tileset).                                                        *
                   *                                                                              *
                   * Clears Z for tileset 1, sets for tileset 0. (The bits are the opposite of    *
                   * the tileset #.)                                                              *
                   ********************************************************************************
                   maptmp                .var    $11    {addr/1}

6415: a5 1c        select_tileset_harder lda     MAPHALF
6417: 85 11                              sta     maptmp                  ;0 or 1 ($11=0000000S)
6419: a5 1b                              lda     MAPPOS                  ;A=PPPPPPPP
641b: a2 03                              ldx     #$03
641d: 46 11        @loop                 lsr     maptmp                  ;divide 16-bit value in $11/A by 8
641f: 6a                                 ror     A
6420: ca                                 dex
6421: d0 fa                              bne     @loop                   ;A=00SPPPPP (lowest 3 bits discarded)
6423: aa                                 tax                             ;X=00..3F
6424: bd 00 1d                           lda     GAME1_tileset_bitmap,x  ;get byte from tileset bitmap
6427: 85 11                              sta     maptmp
6429: a5 1b                              lda     MAPPOS                  ;now handle the lower 3 bits (0..7) of pos
642b: 29 07                              and     #$07
642d: aa                                 tax
642e: bd 34 64                           lda     tileset_bittab,x        ;each pos 0..7 corresponds to 1 bit in tileset byte
6431: 24 11                              bit     maptmp
6433: 60                                 rts

                   ; Used in previous subroutine to test bits 7..0 of $11 based on X=0..7.
6434: 80           tileset_bittab        .dd1    $80                     ;test bit 7 (x=0)
6435: 40                                 .dd1    $40
6436: 20                                 .dd1    $20
6437: 10                                 .dd1    $10
6438: 08                                 .dd1    $08
6439: 04                                 .dd1    $04
643a: 02                                 .dd1    $02
643b: 01                                 .dd1    $01                     ;test bit 0 (x=7)

643c: a9 00        read_playfield        lda     #$00
643e: 85 37                              sta     spokeTo
6440: 85 42                              sta     MON_A4L
6442: 85 6b                              sta     zp6b_npcHere
6444: a5 1b                              lda     MAPPOS                  ;lower 4 bits: sector
6446: 29 0f                              and     #$0f
6448: 8d 05 03                           sta     RWTS_IOB_sector
644b: a5 1b                              lda     MAPPOS                  ;upper 4 bits: track (-1)
644d: 4a                                 lsr     A
644e: 4a                                 lsr     A
644f: 4a                                 lsr     A
6450: 4a                                 lsr     A
6451: 8d 04 03                           sta     RWTS_IOB_track          ;track $01..$10
6454: ee 04 03                           inc     RWTS_IOB_track          ;track + 1
6457: a5 1c                              lda     MAPHALF                 ;high byte 
6459: f0 09                              beq     L6464                   ;0, track unchanged
645b: ad 04 03                           lda     RWTS_IOB_track          ;1, tracks $11..$20
645e: 18                                 clc
645f: 69 10                              adc     #$10                    ;(add $10 to track)
6461: 8d 04 03                           sta     RWTS_IOB_track
6464: a9 01        L6464                 lda     #RWTSCMD_read
6466: 8d 0c 03                           sta     RWTS_IOB_command
6469: 20 a2 69                           jsr     swapzp8                 ;save ZP
646c: 20 15 03                           jsr     DIRECT_RWTS
646f: 20 a2 69                           jsr     swapzp8                 ;restore ZP
6472: 20 2f 63                           jsr     select_tileset
6475: 20 8b 64                           jsr     write_tiles_to_text
6478: 20 6c 67                           jsr     drawfield
647b: 20 e6 63                           jsr     cleartext
647e: 60                                 rts

647f: 20 8b 64     L647F                 jsr     write_tiles_to_text
6482: 20 6c 67                           jsr     drawfield
6485: 20 03 6b                           jsr     GAME2_draw_player
6488: 4c 15 6b                           jmp     L6B15

                   ********************************************************************************
                   * Write tiles to text page, copying them from the run-length encoded RWTS      *
                   * buffer starting at $201. Continues until all text rows are written.          *
                   *                                                                              *
                   * Then, reads more data from RWTS and processes it (so it is kind of a         *
                   * misnomer to say it writes tiles). This is really the start point for reading *
                   * and handling all data for a new map screen.                                  *
                   *                                                                              *
                   * $09/$0A are temp vars but $09 at least is used through several subroutines   *
                   * here.                                                                        *
                   ********************************************************************************
                   tiletmp               .var    $08    {addr/1}
                   rwtsbuf_idx           .var    $09    {addr/1}
                   tilecnt               .var    $0a    {addr/1}         ;RLE

648b: a2 03        write_tiles_to_text   ldx     #$03                    ;copy from RWTSBUF into ZP
648d: bd fc 02     @loop                 lda     RWTSBUF+252,x           ;<- $2ff,$2fe,$2fd
6490: 95 0b                              sta     $0b,x                   ;-> $0e,$0d,$0c
6492: ca                                 dex
6493: 10 f8                              bpl     @loop
6495: a9 00                              lda     #$00
6497: 85 05                              sta     TXTCOL                  ;text col 0
6499: 85 06                              sta     TXTROW                  ;text row 0
649b: 20 93 67                           jsr     gettextaddr             ;get address on text page 1
649e: a9 01                              lda     #$01                    ;start with $201
64a0: 85 09                              sta     rwtsbuf_idx
64a2: a6 09        @next_tile            ldx     rwtsbuf_idx
64a4: e6 09                              inc     rwtsbuf_idx
64a6: bd 00 02                           lda     RWTSBUF,x               ;get tile
64a9: 30 0a                              bmi     @rle                    ;repeating tile 80..FF, branch
64ab: a0 00                              ldy     #$00
64ad: 91 03                              sta     (TXTPTR),y              ;write tile byte to text screen
64af: 20 d4 64                           jsr     @next_text_pos          ;does not return if all rows written
64b2: 4c a2 64                           jmp     @next_tile

                   ; When the tile byte has the high bit set, the next byte is a repeat count of
                   ; tile & 0x7F. In other words this is run-length encoded.
64b5: 29 7f        @rle                  and     #$7f                    ;tile 80..FF, strip high bit
64b7: 85 08                              sta     tiletmp                 ;tile 00..7F
64b9: a6 09                              ldx     rwtsbuf_idx
64bb: e6 09                              inc     rwtsbuf_idx
64bd: bd 00 02                           lda     RWTSBUF,x               ;read next tile byte
64c0: 85 0a                              sta     tilecnt
64c2: e6 0a                              inc     tilecnt
64c4: a0 00        @repeat_tile          ldy     #$00
64c6: a5 08                              lda     tiletmp
64c8: 91 03                              sta     (TXTPTR),y              ;write tile byte to text screen
64ca: 20 d4 64                           jsr     @next_text_pos          ;does not return if done
64cd: c6 0a                              dec     tilecnt
64cf: d0 f3                              bne     @repeat_tile            ;repeat tilecnt times
64d1: 4c a2 64                           jmp     @next_tile

64d4: 20 5e 65     @next_text_pos        jsr     bump_text_pos           ;check if done
64d7: d0 01                              bne     @read_combo_section     ;1 = finish up
64d9: 60                                 rts                             ;0 = more tiles

                   NOTE: $08, $11 and possibly $0a change meanings below.
                   ; Once the screen has been filled with tiles, read additional "combo" bytes
                   ; consisting of a command and a repeat count, followed by a tiled screen
                   ; position. 5 combos write a hardcoded tile triple N times, 1 writes a tile and
                   ; tile+1, and the last terminates the section (in practice, $E0).
64da: 68           @read_combo_section   pla                             ;remove caller address from stack
64db: 68                                 pla                             ;(we jsr'ed here)
64dc: a6 09        read_combo_byte       ldx     rwtsbuf_idx
64de: bd 00 02                           lda     RWTSBUF,x               ;read another byte
64e1: 48                                 pha                             ;save it temporarily
64e2: 29 1f                              and     #$1f
64e4: 85 0a                              sta     tilecnt                 ;save lower 5 bits in $0a
64e6: 68                                 pla                             ;restore the read byte
64e7: 29 e0                              and     #$e0                    ;check the top 3 bits only
64e9: c9 e0                              cmp     #$e0                    ;are all 3 top bits set? (in practice byte is $E0)
64eb: d0 07                              bne     @other_combos           ;no, check other combos
64ed: 20 b2 65                           jsr     display_map_items       ;yep, display items
64f0: 20 fc 65                           jsr     L65FC
64f3: 60                                 rts

                   ; Write 3 tiles (specified by top 3 bits in last RWTS byte), repeated N rows
                   ; (the low 5 bits in this byte). In other words, %TTTNNNNN. The starting
                   ; position is specified by the next two bytes (to be read).
                   ; 
                   ; Check for various combos of TTT (we handled 111 above, which terminates). 5 of
                   ; 6 combos map to hardcoded tile triples. If the tile is b4 or b7, it will write
                   ; b4,b5,b6 or b7,b8,b9. If ba, bb or bc, it will write ba,ba,ba (etc.) These are
                   ; for ladders, vines and doors, which are all 3 tiles across repeated for some
                   ; distance down the screen.
                   ; 
                   ; The last combo (011) writes double-wide tiles (letters) at the specified
                   ; position. Here N is the number of tile bytes to read from the stream, written
                   ; as consecutive double-wide tiles.
                   • Clear variables

64f4: c9 20        @other_combos         cmp     #%00100000              ;001 -> b4,b5,b6 -> outside green ladder
64f6: d0 02                              bne     L64FA
64f8: a0 b4                              ldy     #$b4
64fa: c9 40        L64FA                 cmp     #%01000000              ;010 -> b7,b8,b9 -> inside brown ladder
64fc: d0 02                              bne     L6500
64fe: a0 b7                              ldy     #$b7
6500: c9 80        L6500                 cmp     #%10000000              ;100 -> ba,ba,ba -> outside blue door
6502: d0 02                              bne     L6506
6504: a0 ba                              ldy     #$ba
6506: c9 a0        L6506                 cmp     #%10100000              ;101 -> bb,bb,bb -> outside purple door
6508: d0 02                              bne     L650C
650a: a0 bb                              ldy     #$bb
650c: c9 c0        L650C                 cmp     #%11000000              ;110 -> bc,bc,bc -> inside green / outside black door
650e: d0 02                              bne     L6512
6510: a0 bc                              ldy     #$bc
6512: c9 60        L6512                 cmp     #%01100000              ;011 -> read more data
6514: f0 28                              beq     @combo_011
6516: 84 11                              sty     temp11_textlo           ;store computed tile
6518: 20 7d 65                           jsr     readTilePos
651b: 86 09                              stx     temp09
651d: a0 00        @outer_loop           ldy     #$00
651f: a6 11                              ldx     temp11_textlo           ;computed tile
6521: a9 03                              lda     #$03
6523: 85 08                              sta     temp08
6525: 8a           @inner_loop           txa                             ;get tile in A
6526: 91 03                              sta     (TXTPTR),y              ;write tile to text screen
6528: e0 ba                              cpx     #$ba                    ;check tile number
652a: b0 01                              bcs     @no_inctile             ;>= $ba, repeat same tile
652c: e8                                 inx                             ;otherwise, increment tile
652d: c8           @no_inctile           iny                             ;next column
652e: c6 08                              dec     temp08
6530: d0 f3                              bne     @inner_loop             ;3 times
6532: e6 06                              inc     TXTROW                  ;next row
6534: 20 93 67                           jsr     gettextaddr
6537: c6 0a                              dec     temp0a                  ;repeat %NNNNN rows
6539: d0 e2                              bne     @outer_loop
653b: 4c dc 64                           jmp     read_combo_byte

                   ; Combo 011 reads the next 2 position bytes (as normal),
653e: 20 7d 65     @combo_011            jsr     readTilePos
                   ; and then reads NNNNN more bytes, each of which is a tile number of a double-
                   ; wide tile. It writes tile and tile+1 to the screen for each tile byte.
                   ; 
                   ; This is used, for example, when there are text banners on the screen such as
                   ; "TO TEMPLE GRUND". Each letter is double-width, and each word is (may be)
                   ; written as a separate command block, on top of the background. For example, TO
                   ; TEMPLE GRUND is 3 commands: 62, 66 and 65. (Command $60 with 2, 6, and 5
                   ; letters.)
6541: a0 00        @loop                 ldy     #$00
6543: bd 00 02                           lda     RWTSBUF,x
6546: e8                                 inx
6547: 91 03                              sta     (TXTPTR),y
6549: 18                                 clc
654a: 69 01                              adc     #$01
654c: c8                                 iny
654d: 91 03                              sta     (TXTPTR),y
654f: 20 5e 65                           jsr     bump_text_pos
6552: 20 5e 65                           jsr     bump_text_pos
6555: c6 0a                              dec     temp0a
6557: d0 e8                              bne     @loop
6559: 86 09                              stx     temp09
655b: 4c dc 64                           jmp     read_combo_byte         ;more rwts data

                   ; Bump text page 1 position for writing tiles. If we have not written a full
                   ; screen, return 0; if we have, return 1, which is the end condition for reading
                   ; tiles from the RWTS RLE tile buffer.
655e: e6 05        bump_text_pos         inc     TXTCOL
6560: e6 03                              inc     TXTPTR
6562: a5 05                              lda     TXTCOL
6564: c9 28                              cmp     #$28
6566: d0 12                              bne     @ret00
6568: a9 00                              lda     #$00
656a: 85 05                              sta     TXTCOL
656c: e6 06                              inc     TXTROW
656e: 20 93 67                           jsr     gettextaddr
6571: a5 06                              lda     TXTROW
6573: c9 14                              cmp     #$14
6575: d0 03                              bne     @ret00
6577: a9 01                              lda     #$01
6579: 60                                 rts

657a: a9 00        @ret00                lda     #$00                    ;we are not done
657c: 60                                 rts

                   NOTE: Unclear why we subtract $40 (or mask top bit) from 16-bit tile position in
                   combo byte data. If it is for metadata, there are 3 bits left with a simple 2
                   byte ROW (6 bits) and COL (7 bits) representation.
                   
                   Since this game was multiplatform, they may have (sanely) assumed contiguous
                   memory for a 40x20 screen, and kept that representation. The function of the
                   upper bit is unknown (an actual address?) but the real question is the
                   subtraction of $40 instead of ANDing it out.
                   ; Called just before any tile combo is written. Reads 2 position bytes from
                   ; RWTSBUF which become a 16-bit address into a 40x20 matrix. Converts that
                   ; address into a (row,col) tuple and returns the resulting address on text page
                   ; 1, where the tile will be written.
                   ; 
                   ; First, do some initial munging of the top byte, masking off its top bit, and
                   ; subtracting $40 (for some reason, instead of AND #$3F).
                   ; 
                   ; Then, divide the 16-bit value in $03/04 by the 8 bit value #40 (cols/row),
                   ; placing the quotient (row) in TXTROW and the remainder (col) in TXTCOL.
                   ; 
                   ; E.g. $A9 $C1 -> $A9 $01 -> $01A9
                   ;      $01A9 // 40 = 10 (row 10, 0..23)
                   ;      $01A9 %  40 = 25 (col 25, 0..39)
                   ; 
                   ; Last, call gettextaddr to compute the screen address of TXTROW/TXTCOL and
                   ; place it in TXTPTR for the caller. Note TXTPTR was used as a temp for the
                   ; divide, and is overwritten.
                   ; 
                   ; A simple 2-byte ROW/COL representation would have been easier to deal with and
                   ; still left 3 bits for metadata. This representation looks geared toward the
                   ; contiguous screen memory of other platforms this game was released for.
657d: e8           readTilePos           inx
657e: bd 00 02                           lda     RWTSBUF,x               ;read rwts byte into TXTPTR (temp) lo
6581: 85 03                              sta     TXTPTR                  ;used as a 16-bit temporary, overwritten at end
6583: e8                                 inx
6584: bd 00 02                           lda     RWTSBUF,x               ;read rwts byte into TXTPTR (temp) hi
6587: 29 7f                              and     #$7f                    ;ignoring top bit of second byte
6589: 38                                 sec
658a: e9 40                              sbc     #$40                    ;and subtracting $40 from second byte
658c: 85 04                              sta     TXTPTR+1
658e: e8                                 inx
658f: a9 00                              lda     #$00
6591: 85 06                              sta     TXTROW
6593: a5 03        @loop                 lda     TXTPTR                  ;16-bit subtract of #$0028 from tmpaddr
6595: 38                                 sec
6596: e9 28                              sbc     #40
6598: 85 03                              sta     TXTPTR
659a: a5 04                              lda     TXTPTR+1
659c: e9 00                              sbc     #$00                    ;propagate low-byte borrow to high byte
659e: 30 07                              bmi     @done                   ;finish up
65a0: 85 04                              sta     TXTPTR+1
65a2: e6 06                              inc     TXTROW
65a4: 4c 93 65                           jmp     @loop

65a7: a9 28        @done                 lda     #40
65a9: 18                                 clc
65aa: 65 03                              adc     TXTPTR                  ;overshot $03 by 40, add back in (didn't update $04)
65ac: 85 05                              sta     TXTCOL
65ae: 20 93 67                           jsr     gettextaddr             ;wipes out $03/04
65b1: 60                                 rts                             ;return to caller

                   ********************************************************************************
                   * Display all the free-standing items in this room, called after the           *
                   * background is displayed. These are all the items from $b500-$b5ff with bit 6 *
                   * set and bit 5 clear. For item x (00..ff),                                    *
                   *                                                                              *
                   * $b300,x is the item's map position (room)                                    *
                   * $b500,x bit 7 is the map position high bit                                   *
                   * $b500,x bit 6 must be set (unknown purpose)                                  *
                   * $b500,x bit 5 must be clear (used to indicate item is in your inventory)     *
                   * $b500,x bits 0..4 are the screen tile row 0..20                              *
                   * $b400,x is the screen tile column 0..39                                      *
                   *                                                                              *
                   * All items are 2 tiles in width and the tile number is $fd - (item * 2).      *
                   * Items are duplicated in both tilesets.                                       *
                   ********************************************************************************
65b2: a2 00        display_map_items     ldx     #$00
65b4: bd 00 b3     @loop                 lda     itemStatePos,x          ;256 possible item positions (map rooms)
65b7: c5 1b                              cmp     MAPPOS
65b9: d0 3d                              bne     @next_item
65bb: bd 00 b5                           lda     itemState,x
65be: 0a                                 asl     A
65bf: a9 00                              lda     #$00
65c1: 2a                                 rol     A                       ;bit 7 -- high bit of map position
65c2: c5 1c                              cmp     MAPHALF
65c4: d0 32                              bne     @next_item
65c6: bd 00 b5                           lda     itemState,x
65c9: 2c be 1d                           bit     GAME1_BITTAB6           ;bit 6 -- unknown (must be set here)
65cc: f0 2a                              beq     @next_item
65ce: 2c bd 1d                           bit     GAME1_BITTAB5           ;bit 5 -- item in inventory
65d1: d0 25                              bne     @next_item
65d3: 29 1f                              and     #$1f                    ;bits 0..4 (tile row)
65d5: a8                                 tay
65d6: b9 a0 1d                           lda     GAME1_textlo,y          ;Y is the text row
65d9: 85 11                              sta     temp11_textlo
65db: b9 80 1d                           lda     GAME1_texthi,y
65de: 85 12                              sta     temp12_texthi
65e0: 8a                                 txa
65e1: 20 03 77                           jsr     GAME2_slot_to_item
65e4: 84 08                              sty     temp08
65e6: 06 08                              asl     temp08                  ;because tiles are double-wide?
65e8: a9 fd                              lda     #$fd                    ;convert item num to tile ($fd-item*2)
65ea: 38                                 sec
65eb: e5 08                              sbc     temp08
65ed: bc 00 b4                           ldy     itemStateCol,x          ;item tile column
65f0: 91 11                              sta     (temp11_textlo),y
65f2: c8                                 iny
65f3: 18                                 clc
65f4: 69 01                              adc     #$01                    ;right half of tile
65f6: 91 11                              sta     (temp11_textlo),y
65f8: e8           @next_item            inx
65f9: d0 b9                              bne     @loop
65fb: 60                                 rts

65fc: a2 04        L65FC                 ldx     #$04
65fe: 86 08                              stx     temp08
6600: 20 4f 66                           jsr     L664F
6603: a5 60                              lda     tileset
6605: d0 0b                              bne     L6612
6607: a9 00                              lda     #$00
6609: 85 11                              sta     temp11_textlo
660b: a9 37                              lda     #$37
660d: 85 12                              sta     temp12_texthi
660f: 4c 1a 66                           jmp     L661A

6612: a9 00        L6612                 lda     #$00
6614: 85 11                              sta     temp11_textlo
6616: a9 2e                              lda     #$2e
6618: 85 12                              sta     temp12_texthi
661a: a9 59        L661A                 lda     #$59
661c: 85 03                              sta     TXTPTR
661e: a0 52                              ldy     #$52
6620: a5 0c                              lda     $0c
6622: 20 47 66                           jsr     L6647
6625: a9 73                              lda     #$73
6627: 85 03                              sta     TXTPTR
6629: a0 59                              ldy     #$59
662b: a5 0d                              lda     $0d
662d: 20 47 66                           jsr     L6647
6630: a9 77                              lda     #$77
6632: 85 03                              sta     TXTPTR
6634: a0 73                              ldy     #$73
6636: a5 0e                              lda     $0e
6638: 20 47 66                           jsr     L6647
663b: a9 b4                              lda     #$b4
663d: 85 03                              sta     TXTPTR
663f: a0 77                              ldy     #$77
6641: a5 0b                              lda     $0b
6643: 20 47 66                           jsr     L6647
6646: 60                                 rts

6647: 91 11        L6647                 sta     (temp11_textlo),y
6649: c8                                 iny
664a: c4 03                              cpy     TXTPTR
664c: d0 f9                              bne     L6647
664e: 60                                 rts

664f: a2 00        L664F                 ldx     #$00
6651: a5 1c                              lda     MAPHALF
6653: f0 14                              beq     L6669
6655: a5 1b                              lda     MAPPOS
6657: c9 80                              cmp     #$80
6659: 90 0e                              bcc     L6669
665b: ad 01 b5                           lda     itemState+1
665e: 2c bd 1d                           bit     GAME1_BITTAB5
6661: d0 06                              bne     L6669
6663: a5 3a                              lda     litLamp
6665: d0 02                              bne     L6669
6667: a2 01                              ldx     #$01
6669: 86 5e        L6669                 stx     $5e
666b: 60                                 rts

666c: 20 a3 66     found_near_water      jsr     teleport_home
666f: 20 d6 66                           jsr     PRNTSTR
6672: 29                                 .dd1    $29
6673: d9 cf d5 a0+                       .str    ↑“YOU WERE FOUND NEAR THE WATER.”
6691: ff                                 .dd1    $ff
6692: 20 09 77                           jsr     L7709
6695: 20 06 77                           jsr     GAME2_message_wait
6698: a9 00                              lda     #$00
669a: 85 80                              sta     touchedWater
669c: a9 01                              lda     #$01                    ;start the clock
669e: 85 87                              sta     TICKING
66a0: 4c 86 60                           jmp     tick0

66a3: a9 00        teleport_home         lda     #$00
66a5: 85 6b                              sta     zp6b_npcHere
66a7: a5 2d                              lda     homePos
66a9: 85 1b                              sta     MAPPOS
66ab: a5 2e                              lda     homeHalf
66ad: 85 1c                              sta     MAPHALF
66af: a9 01                              lda     #$01
66b1: 85 67                              sta     INSIDE
66b3: 20 3c 64                           jsr     read_playfield
66b6: a5 2f                              lda     homeX
66b8: 85 19                              sta     playerX
66ba: a5 30                              lda     homeY
66bc: 85 1a                              sta     playerY
66be: a2 2e                              ldx     #$2e
66c0: 86 a3                              stx     animFrame
66c2: e8                                 inx
66c3: 86 a4                              stx     animFrame_unused
66c5: 20 03 6b                           jsr     GAME2_draw_player
66c8: e6 22                              inc     dayNum                  ;lose a day
66ca: a5 27                              lda     limitSpirit             ;restore spirit
66cc: 85 23                              sta     levelSpirit
66ce: a6 2a                              ldx     limitFood               ;limitFood and limitRest are always identical, so
66d0: ca                                 dex                             ;I guess they realized checking 2 vars was pointless
66d1: 86 24                              stx     levelFood               ;restore food and rest (to limit - 1)
66d3: 86 25                              stx     levelRest
66d5: 60                                 rts

                   ********************************************************************************
                   * Print inline string to hires text area (last 4 lines). The inline data is:   *
                   *    1 byte -- hpos, the horizontal position of the string                     *
                   *    x bytes - high ascii string data                                          *
                   *  $ff       - string terminator                                               *
                   *                                                                              *
                   * The hpos byte starts from $00 (col 1, row 1) and wraps at $28 (col 1, row    *
                   * 2), $50 and $78, so it encodes vertical position as well. In practice,       *
                   * strings are indented by 1 so $01, $29 etc are typical. Strings will wrap at  *
                   * end of screen.                                                               *
                   *                                                                              *
                   * The use of $ff instead of $00 to terminate strings could be a cross-platform *
                   * concession, although platforms where $00 is a valid character would not be   *
                   * using high-ascii anyway.                                                     *
                   ********************************************************************************
                   inlinedata            .var    $61    {addr/2}
                   ysav                  .var    $63    {addr/1}

66d6: 68           PRNTSTR               pla                             ;inline data; store addr-1 in $61/$62
66d7: 85 61                              sta     inlinedata
66d9: 68                                 pla
66da: 85 62                              sta     inlinedata+1
66dc: a0 01                              ldy     #$01                    ;addr-1+1
66de: b1 61                              lda     (inlinedata),y
66e0: 85 64                              sta     HTAB                    ;first byte of inline data is indent
66e2: c8                                 iny
66e3: b1 61        @loop                 lda     (inlinedata),y          ;A=char
66e5: c9 ff                              cmp     #$ff                    ;end of string?
66e7: f0 0e                              beq     @continue
66e9: 84 63                              sty     ysav                    ;save y
66eb: 20 09 67                           jsr     printchar
66ee: e6 05                              inc     TXTCOL                  ;??
66f0: e6 64                              inc     HTAB
66f2: a4 63                              ldy     ysav                    ;restore y
66f4: c8                                 iny
66f5: d0 ec                              bne     @loop                   ;always, effectively
                   ; Offset the return address in $61/$62 with the inline data length, then jump to
                   ; it to continue.
66f7: c8           @continue             iny
66f8: 98                                 tya
66f9: 18                                 clc
66fa: 65 61                              adc     inlinedata
66fc: 85 61                              sta     inlinedata
66fe: 90 02                              bcc     @nowrap                 ;check for page wrap
6700: e6 62                              inc     inlinedata+1            ;and wrap page
6702: a9 00        @nowrap               lda     #$00
6704: 85 66                              sta     INVTEXT
6706: 6c 61 00                           jmp     ($0061)

                   ; Print char in A at horiz pos htab in text area. Converts position to
                   ; fullscreen TXTROW/COL. Indexes the char ($00..$3F) into hires char bitmap
                   ; $2C00 at 8 bytes per char. Then draws the char on the hires screen.
6709: 48           printchar             pha                             ;save char
670a: a9 13                              lda     #19                     ;screen line 19 (will be 20)
670c: 85 06                              sta     TXTROW
670e: a5 64                              lda     HTAB
                   ; Add quotient(htab,40)+1 to TXTROW -- implement wrapping.
6710: 38           @incrow               sec                             ;subtract 40 cols from htab
6711: e9 28                              sbc     #40
6713: e6 06                              inc     TXTROW
6715: b0 f9                              bcs     @incrow                 ;add 1 to TXTROW until htab < 0
6717: 18                                 clc
6718: 69 28                              adc     #40
671a: 85 05                              sta     TXTCOL                  ;adjust +40 (we overshot 1 iter of -40)
671c: 68                                 pla                             ;restore char
671d: 29 3f                              and     #$3f                    ;convert $C0..DF to $00..1F, $A0..BF to $20..3F (?)
671f: 85 16                              sta     tileptr                 ;store char # in $16/17
6721: a9 00                              lda     #$00
6723: 85 17                              sta     tileptr+1
6725: 06 16                              asl     tileptr                 ;mult $16 (addr/2) by 8 bytes (per char data)
6727: 26 17                              rol     tileptr+1
6729: 06 16                              asl     tileptr
672b: 26 17                              rol     tileptr+1
672d: 06 16                              asl     tileptr
672f: 26 17                              rol     tileptr+1
6731: a5 16                              lda     tileptr
6733: 18                                 clc
6734: 69 00                              adc     #<GAME1_chardata
6736: 85 16                              sta     tileptr
6738: a5 17                              lda     tileptr+1
673a: 69 2c                              adc     #>GAME1_chardata
673c: 85 17                              sta     tileptr+1
673e: 20 5b 68                           jsr     calc_hires_textpos      ;calc hires addr in $14
6741: 20 45 67                           jsr     drawchar                ;draw ($16) data at ($14)
6744: 60                                 rts

                   ; Draw 8 lines of character data at ($16) to the hires screen at ($14).
                   ; Actually, the first written line is blank, and then the first 7 lines of
                   ; actual data are written; the 8th line is ignored. This creates line spacing by
                   ; shifting everything down a pixel. This is a little odd, but perhaps let them
                   ; switch to top-spacing (which offsets text from the playfield) without changing
                   ; the char data.
                   lines                 .var    $07    {addr/1}         ;lines left to draw

6745: a2 00        drawchar              ldx     #$00                    ;this will draw normal pixels
6747: a5 66                              lda     INVTEXT                 ;inverse text?
6749: f0 02                              beq     @draw
674b: a2 7f                              ldx     #$7f                    ;this will flip (XOR) pixels (inverse?)
674d: 86 18        @draw                 stx     MASK                    ;mask. may be global var
674f: a9 08                              lda     #$08                    ;8 lines
6751: 85 07                              sta     lines
6753: a2 00                              ldx     #$00
6755: a0 00                              ldy     #$00
6757: a9 80                              lda     #$80                    ;first line empty (note bit 7 color set)
6759: 45 18        @loop                 eor     MASK                    ;possibly invert text
                   NOTE: Is $14/15 global?  Is $16/17?
675b: 81 14                              sta     (hires_addr,x)          ;$14 (addr/2) prob hires screen, unsure where set
675d: a5 15                              lda     hires_addr+1
675f: 18                                 clc
6760: 69 04                              adc     #$04                    ;next hires line (+$0400)
6762: 85 15                              sta     hires_addr+1
6764: b1 16                              lda     (tileptr),y
6766: c8                                 iny
6767: c6 07                              dec     lines
6769: d0 ee                              bne     @loop
676b: 60                                 rts

                   NOTE: Draws 20 lines of text, sourced from text page 1, to hires screen. This
                   looks like 40x20 tiled graphics data stored as text, made further apparent by
                   NOPing out the 4 instructions at $A857 to set HIRES2, leaving GR active. This
                   shows lores colored blocks in the obvious shape of game screens.
                   text1                 .var    $03    {addr/2}         ;FIXME: this is TXTPTR

676c: a9 00        drawfield             lda     #$00
676e: 85 05                              sta     TXTCOL
6770: 85 06                              sta     TXTROW
6772: 20 93 67     @line                 jsr     gettextaddr
6775: a0 00        @char                 ldy     #$00
6777: b1 03                              lda     (text1),y               ;load from text page 1
6779: 20 a9 67                           jsr     drawtile
677c: e6 03                              inc     text1                   ;page aligned, so no high byte inc
677e: e6 05                              inc     TXTCOL                  ;next col
6780: a5 05                              lda     TXTCOL
6782: c9 28                              cmp     #40                     ;comp $05 with 40; def looks like a column now
6784: d0 ef                              bne     @char
6786: a9 00                              lda     #$00
6788: 85 05                              sta     TXTCOL                  ;reset to column 1
678a: e6 06                              inc     TXTROW                  ;and bump row
678c: a5 06                              lda     TXTROW
678e: c9 14                              cmp     #20                     ;reached row 21?
6790: d0 e0                              bne     @line                   ;no, keep going
6792: 60                                 rts

                   ; Converting a col/row ($05/$06) to an address on text page 1. Output address is
                   ; in $03/04. X is preserved.
6793: 8a           gettextaddr           txa
6794: 48                                 pha
6795: a6 06                              ldx     TXTROW
6797: bd a0 1d                           lda     GAME1_textlo,x          ;low byte of text page line
679a: 18                                 clc
679b: 65 05                              adc     TXTCOL
679d: 85 03                              sta     text1
679f: bd 80 1d                           lda     GAME1_texthi,x          ;high byte of text page line
67a2: 69 00                              adc     #$00
67a4: 85 04                              sta     text1+1
67a6: 68                                 pla
67a7: aa                                 tax
67a8: 60                                 rts

                   ; Input: A = tile number.
67a9: 20 e6 67     drawtile              jsr     calc_tile
67ac: 20 5b 68                           jsr     calc_hires_textpos
67af: 20 b3 67                           jsr     writetile
67b2: 60                                 rts

67b3: a5 5e        writetile             lda     $5e
67b5: f0 05                              beq     L67BC
67b7: a9 00                              lda     #$00
67b9: 20 e6 67                           jsr     calc_tile
67bc: a9 00        L67BC                 lda     #$00
67be: a2 00                              ldx     #$00
67c0: a9 08                              lda     #$08                    ;8 lines in a tile
67c2: 85 07                              sta     lines
67c4: a0 00                              ldy     #$00
67c6: b1 16        @line                 lda     (tileptr),y             ;read tile data
67c8: 25 18                              and     MASK                    ;apply global mask
67ca: 81 14                              sta     (hires_addr,x)          ;write tile data
67cc: a5 07                              lda     lines
67ce: 6a                                 ror     A                       ;check if A (lines) is odd
67cf: 90 08                              bcc     @no_and                 ;ignore odd line mask on even lines
67d1: a5 5f                              lda     ODDLINE_MASK
67d3: f0 04                              beq     @no_and                 ;ignore odd line mask when zero
                   ; If the sta to $14 is removed, the purple odd-line hatching on the title screen
                   ; is gone, and houses are now a single color. The odd line mask is a clever way
                   ; to add shading/hatching. Note that odd lines are written twice if masked; the
                   ; second write clobbers the first.
67d5: 31 16                              and     (tileptr),y
67d7: 81 14                              sta     (hires_addr,x)
67d9: c8           @no_and               iny                             ;next line
67da: a5 15                              lda     hires_addr+1            ;next hires line (+$0400)
67dc: 18                                 clc
67dd: 69 04                              adc     #$04
67df: 85 15                              sta     hires_addr+1
67e1: c6 07                              dec     lines
67e3: d0 e1                              bne     @line                   ;write 8 lines
67e5: 60                                 rts

                   ********************************************************************************
                   * Calculate tile data. A is the tile number. There appear to be 2 tilesets,    *
                   * tileset 1 at $2E00 ($2F00), and tileset 0 at $3700 ($3800), selected by the  *
                   * value of $60.                                                                *
                   *                                                                              *
                   * The tile mask and odd line mask are retrieved from 6 possible 16-element     *
                   * mask arrays; the first $100 bytes of data are mask indices. Tiles $00-$49    *
                   * and $75..$ff use one mask array for even columns and a second array for odd  *
                   * columns; their oddline mask is disabled. Tiles $4a-$74 use a mask array for  *
                   * even columns/even lines, one for odd columns/even lines, one for even        *
                   * columns/odd lines, and one for odd columns/odd lines.                        *
                   *                                                                              *
                   * Finally, tileptr ($16) is set to the hires tile bitmap.                      *
                   ********************************************************************************
67e6: 85 16        calc_tile             sta     tileptr
67e8: a8                                 tay                             ;Y used in L681A
67e9: a9 00                              lda     #$00
67eb: 85 5f                              sta     ODDLINE_MASK            ;disable oddline mask by default
67ed: a5 60                              lda     tileset
67ef: d0 29                              bne     tileset_1
67f1: b9 00 37                           lda     GAME1_tileset0_masks,y  ;note very close to $3800
67f4: aa                                 tax
67f5: a5 16                              lda     tileptr
67f7: c9 4a                              cmp     #$4a                    ;is tile between $4a and $74?
67f9: 90 23                              bcc     @mask_tileset           ;no, use simple tileset mask
67fb: c9 75                              cmp     #$75
67fd: b0 1f                              bcs     @mask_tileset
67ff: a5 05                              lda     TXTCOL
6801: 6a                                 ror     A
6802: 90 0b                              bcc     @evencol                ;branch if column even
6804: bd e0 1f                           lda     GAME1_odd_col_odd_line_mask,x ;apply odd column odd line mask
6807: 85 5f                              sta     ODDLINE_MASK
6809: bd c0 1f                           lda     GAME1_odd_col_even_line_mask,x
680c: 4c 29 68                           jmp     @finalize

680f: bd f0 1f     @evencol              lda     GAME1_even_col_odd_line_mask,x ;apply even column odd line mask
6812: 85 5f                              sta     ODDLINE_MASK
6814: bd d0 1f                           lda     GAME1_even_col_even_line_mask,x
6817: 4c 29 68                           jmp     @finalize

681a: b9 00 2e     tileset_1             lda     GAME1_tileset1_masks,y  ;note very close to $2F00 (see just below)
681d: aa                                 tax
681e: a5 05        @mask_tileset         lda     TXTCOL
6820: 6a                                 ror     A
6821: bd b0 1f                           lda     GAME1_even_col_mask,x   ;even column mask
6824: 90 03                              bcc     @finalize
6826: bd a0 1f                           lda     GAME1_odd_col_mask,x    ;odd column mask
                   ; Everything ends up here to write A to MASK and calculate tileptr.
6829: 85 18        @finalize             sta     MASK
682b: a9 00                              lda     #$00
682d: 85 17                              sta     tileptr+1
682f: 06 16                              asl     tileptr                 ;16-bit mul $16 by 8
6831: 26 17                              rol     tileptr+1
6833: 06 16                              asl     tileptr
6835: 26 17                              rol     tileptr+1
6837: 06 16                              asl     tileptr
6839: 26 17                              rol     tileptr+1
683b: a5 60                              lda     tileset
683d: d0 0e                              bne     add_2F00_to_zp16        ;*$16 += $2F00 (when $60 is nonzero)
683f: a5 16                              lda     tileptr                 ;*$16 += $3800 (when $60 is zero)
6841: 18                                 clc
6842: 69 00                              adc     #$00
6844: 85 16                              sta     tileptr
6846: a5 17                              lda     tileptr+1
6848: 69 38                              adc     #$38
684a: 85 17                              sta     tileptr+1
684c: 60                                 rts

                   ; Add $2F00 to the 16-bit address in $16.
684d: a5 16        add_2F00_to_zp16      lda     tileptr
684f: 18                                 clc
6850: 69 00                              adc     #$00
6852: 85 16                              sta     tileptr
6854: a5 17                              lda     tileptr+1
6856: 69 2f                              adc     #$2f
6858: 85 17                              sta     tileptr+1
685a: 60                                 rts

                   ; Convert TEXTROW/TEXTCOL to hires address and stores addr in $14.
685b: a2 20        calc_hires_textpos    ldx     #$20                    ;offset into hireshi ($20+$20 will be page 2)
685d: 86 15                              stx     hires_addr+1
685f: a9 00                              lda     #$00
6861: 85 14                              sta     hires_addr
6863: a4 06                              ldy     TXTROW
6865: b9 40 1d                           lda     GAME1_hireslo,y         ;hires line table
6868: 18                                 clc
6869: 65 14                              adc     hires_addr
686b: 85 14                              sta     hires_addr
686d: b9 60 1d                           lda     GAME1_hireshi,y         ;hires page 2
6870: 65 15                              adc     hires_addr+1
6872: 85 15                              sta     hires_addr+1
6874: a5 05                              lda     TXTCOL
6876: 18                                 clc
6877: 65 14                              adc     hires_addr
6879: 85 14                              sta     hires_addr
687b: a9 00                              lda     #$00
687d: 65 15                              adc     hires_addr+1
687f: 85 15                              sta     hires_addr+1
6881: 60                                 rts

                   NOTE: There's already a handle_npc? so this is another temp name.
6882: a9 00        handle_npc2?          lda     #$00
6884: 85 6b                              sta     zp6b_npcHere
6886: a9 32                              lda     #$32
6888: 85 6c                              sta     npcX
688a: 85 6d                              sta     npcY
688c: ae f1 02                           ldx     RWTSBUF_npcnum
688f: bd 00 b2                           lda     state_npc1,x            ;differs from state_npc
6892: 2c bf 1d                           bit     GAME1_BITTAB7           ;test bit 7
6895: f0 01                              beq     @check_npc_present      ;if 0
6897: 60                                 rts

6898: ad e1 02     @check_npc_present    lda     RWTSBUF_npc
689b: d0 01                              bne     @npc_present
689d: 60                                 rts

689e: ad f2 02     @npc_present          lda     RWTSBUF_npctype
68a1: 29 f0                              and     #$f0
68a3: c9 e0                              cmp     #$e0
68a5: d0 1b                              bne     L68C2
68a7: bd 80 b2                           lda     state_npc,x             ;npctype $e0..$ef -- check state bits 0..4
68aa: 29 1f                              and     #$1f
68ac: c5 21                              cmp     timeOfDay
68ae: f0 12                              beq     L68C2
68b0: 20 63 61                           jsr     read_0900_next          ;probably pseudo-randomness
68b3: 29 03                              and     #$03                    ;test lowest 2 bits
68b5: f0 01                              beq     L68B8                   ;25% chance?
68b7: 60                                 rts

                   NOTE: May handle periodic NPC behavior... walking?
68b8: bd 80 b2     L68B8                 lda     state_npc,x
68bb: 29 e0                              and     #$e0
68bd: 05 21                              ora     timeOfDay               ;update NPC's state with current time of day
68bf: 9d 80 b2                           sta     state_npc,x
68c2: ad e1 02     L68C2                 lda     RWTSBUF_npc             ;the only place where the value (not bool) of NPC is used
68c5: 4a                                 lsr     A
68c6: 4a                                 lsr     A
68c7: 4a                                 lsr     A
68c8: 4a                                 lsr     A
68c9: 85 6a                              sta     $6a                     ;store top 4 bits (shifted to low bits)
68cb: aa                                 tax
68cc: bd 86 69                           lda     L6986,x
68cf: 85 11                              sta     temp11_textlo
68d1: bd 91 69                           lda     L6991,x
68d4: 85 12                              sta     temp12_texthi
68d6: a9 02                              lda     #$02
68d8: 85 08                              sta     temp08
68da: a6 08        L68DA                 ldx     temp08
68dc: bd 8b 69                           lda     L698B,x
68df: 85 09                              sta     temp09
68e1: bd 9c 69                           lda     L699C,x
68e4: 85 0a                              sta     temp0a
68e6: bd 8e 69                           lda     L698E,x
68e9: 85 68                              sta     $68
68eb: bd 9f 69                           lda     L699F,x
68ee: 85 69                              sta     $69
68f0: a0 7e                              ldy     #$7e
68f2: a2 08        L68F2                 ldx     #$08
68f4: b1 11                              lda     (temp11_textlo),y
68f6: 91 09                              sta     (temp09),y
68f8: 0a           L68F8                 asl     A
68f9: 66 65                              ror     $65
68fb: ca                                 dex
68fc: d0 fa                              bne     L68F8
68fe: a5 65                              lda     $65
6900: 91 68                              sta     ($68),y
6902: 88                                 dey
6903: 10 ed                              bpl     L68F2
6905: a0 7e                              ldy     #$7e
6907: b1 68        L6907                 lda     ($68),y
6909: 48                                 pha
690a: 88                                 dey
690b: 88                                 dey
690c: b1 68                              lda     ($68),y
690e: c8                                 iny
690f: c8                                 iny
6910: 91 68                              sta     ($68),y
6912: 88                                 dey
6913: 88                                 dey
6914: 68                                 pla
6915: 91 68                              sta     ($68),y
6917: c0 40                              cpy     #$40
6919: d0 01                              bne     L691C
691b: 88                                 dey
691c: 88           L691C                 dey
691d: 10 e8                              bpl     L6907
691f: 18                                 clc
6920: a5 11                              lda     temp11_textlo
6922: 69 80                              adc     #$80
6924: 90 02                              bcc     L6928
6926: e6 12                              inc     temp12_texthi
6928: 85 11        L6928                 sta     temp11_textlo
692a: c6 08                              dec     temp08
692c: 10 ac                              bpl     L68DA
692e: ad e4 02                           lda     RWTSBUF_npcX
6931: 85 6c                              sta     npcX
6933: ad e5 02                           lda     RWTSBUF_npcY
6936: 85 6d                              sta     npcY
6938: ad e3 02                           lda     RWTSBUF+227
693b: 48                                 pha
693c: 29 0f                              and     #$0f
693e: 85 6e                              sta     zp6e
6940: 68                                 pla
6941: 4a                                 lsr     A
6942: 4a                                 lsr     A
6943: 4a                                 lsr     A
6944: 4a                                 lsr     A
6945: 85 08                              sta     temp08
6947: 20 63 61     L6947                 jsr     read_0900_next
694a: 29 1f                              and     #$1f
694c: c5 08                              cmp     temp08
694e: b0 f7                              bcs     L6947
6950: 18                                 clc
6951: 65 6c                              adc     npcX
6953: 85 6c                              sta     npcX
6955: 20 63 61                           jsr     read_0900_next
6958: 29 01                              and     #$01
695a: d0 02                              bne     L695E
695c: a9 ff                              lda     #$ff
695e: 85 6f        L695E                 sta     npcFacing
6960: 20 18 6b                           jsr     L6B18
6963: 20 15 6b                           jsr     L6B15
6966: a9 00                              lda     #$00
6968: 85 50                              sta     $50
696a: 85 51                              sta     $51
696c: 85 52                              sta     $52
696e: 85 53                              sta     $53
6970: a9 04                              lda     #$04
6972: 85 54                              sta     $54
6974: ad e2 02                           lda     RWTSBUF+226
6977: 48                                 pha
6978: 29 0f                              and     #$0f                    ;lower 4 bits in $45
697a: 85 45                              sta     MON_A5H                 ;used only in LA065 in combo with $28
697c: 68                                 pla
697d: 4a                                 lsr     A
697e: 4a                                 lsr     A
697f: 4a                                 lsr     A
6980: 4a                                 lsr     A
6981: 85 46                              sta     $46                     ;upper 4 bits in $46 (shifted right 4)
6983: e6 6b                              inc     zp6b_npcHere
6985: 60                                 rts

6986: 80           L6986                 .dd1    $80
6987: 00                                 .dd1    $00
6988: 80                                 .dd1    $80
6989: 00                                 .dd1    $00
698a: 80                                 .dd1    $80
698b: 00           L698B                 .dd1    $00
698c: 80                                 .dd1    $80
698d: 00                                 .dd1    $00
698e: 80           L698E                 .dd1    $80
698f: 00                                 .dd1    $00
6990: 80                                 .dd1    $80
6991: 85           L6991                 .dd1    $85
6992: 87                                 .dd1    $87
6993: 88                                 .dd1    $88
6994: 8a                                 .dd1    $8a
6995: 8b                                 .dd1    $8b
6996: 8d                                 .dd1    $8d
6997: 8e                                 .dd1    $8e
6998: 90                                 .dd1    $90
6999: 91                                 .dd1    $91
699a: 93                                 .dd1    $93
699b: 94                                 .dd1    $94
699c: b0           L699C                 .dd1    $b0
699d: af                                 .dd1    $af
699e: af                                 .dd1    $af
699f: b1           L699F                 .dd1    $b1
69a0: b1                                 .dd1    $b1
69a1: b0                                 .dd1    $b0

                   ; Swap $0000..00FF with $0800..08FF. Generally called to save/restore
                   ; zero page when reading a new sector (screen) from disk.
69a2: a2 00        swapzp8               ldx     #$00
69a4: bd 00 00     @loop                 lda     a:$0000,x
69a7: 48                                 pha
69a8: bd 00 08                           lda     $0800,x
69ab: 9d 00 00                           sta     a:$0000,x
69ae: 68                                 pla
69af: 9d 00 08                           sta     $0800,x
69b2: e8                                 inx
69b3: d0 ef                              bne     @loop
69b5: 60                                 rts

                   ; Copy X pages of data from page A ($AA00) to page Y ($YY00).
                   dst                   .var    $09    {addr/2}
                   src                   .var    $11    {addr/2}

69b6: 85 12        copypages             sta     src+1
69b8: 84 0a                              sty     dst+1
69ba: a0 00                              ldy     #$00
69bc: 84 11                              sty     src
69be: 84 09                              sty     dst
69c0: b1 11        @loop                 lda     (src),y
69c2: 91 09                              sta     (dst),y
69c4: c8                                 iny
69c5: d0 f9                              bne     @loop
69c7: e6 12                              inc     src+1                   ;next page
69c9: e6 0a                              inc     dst+1
69cb: ca                                 dex
69cc: d0 f2                              bne     @loop
69ce: 60                                 rts

                   ; Zero out X pages starting from page A ($AA00).
                   dst                   .var    $11    {addr/2}

69cf: 85 12        clearpages            sta     dst+1
69d1: a9 00                              lda     #$00
69d3: 85 11                              sta     dst
69d5: a8                                 tay                             ;A and Y are now 0
69d6: 91 11        @loop                 sta     (dst),y
69d8: c8                                 iny
69d9: d0 fb                              bne     @loop
69db: e6 12                              inc     dst+1
69dd: ca                                 dex
69de: d0 f6                              bne     @loop
69e0: 60                                 rts

                   ; Delay loop. Decrement Y 256 times, X times. X and Y are 0 on exit.
69e1: a0 00        delayXtimes256        ldy     #$00
69e3: 88           @dey                  dey
69e4: d0 fd                              bne     @dey
69e6: ca                                 dex
69e7: d0 f8                              bne     delayXtimes256
69e9: 60                                 rts

                   ; Delay loop. Decrement Y 512 times, X times. X and Y are 0 on exit.
69ea: 88           delay2                dey
69eb: d0 fd                              bne     delay2
69ed: 88           @dey                  dey
69ee: d0 fd                              bne     @dey
69f0: ca                                 dex
69f1: d0 f7                              bne     delay2
69f3: 60                                 rts

69f4: 20 e6 63     spirit_bell_rings     jsr     cleartext
69f7: 20 d6 66                           jsr     PRNTSTR
69fa: 01                                 .dd1    $01
69fb: d4 c8 c5 a0+                       .str    ↑“THE SPIRIT BELL RINGS”
6a10: ff                                 .dd1    $ff
6a11: a2 0c                              ldx     #$0c
6a13: 20 03 b6                           jsr     SCRN_play_sound
6a16: 20 06 77                           jsr     GAME2_message_wait
6a19: a9 00                              lda     #$00
6a1b: 85 bc                              sta     zpBC_bellrings
6a1d: 4c 82 60                           jmp     game_loop?

6a20: a5 1c        L6A20                 lda     MAPHALF
6a22: d0 0a                              bne     L6A2E
6a24: a5 1b                              lda     MAPPOS
6a26: c9 be                              cmp     #$be
6a28: d0 03                              bne     L6A2D
6a2a: 20 1e 9c     L6A2A                 jsr     SCRN_triumph_melody
6a2d: 60           L6A2D                 rts

6a2e: a5 1b        L6A2E                 lda     MAPPOS
6a30: c9 80                              cmp     #$80
6a32: d0 f9                              bne     L6A2D
6a34: f0 f4                              beq     L6A2A

6a36: 20 d6 66     game_over             jsr     PRNTSTR
6a39: 01                                 .dd1    $01
6a3a: d4 c8 c5 a0+                       .str    ↑“THE LIGHT FADES INTO DARKNESS...”
6a5a: ff                                 .dd1    $ff
6a5b: 20 d6 66                           jsr     PRNTSTR
6a5e: 29                                 .dd1    $29
6a5f: d4 c8 c5 a0+                       .str    ↑“THE TIME FOR YOUR QUEST HAS ENDED.”
6a81: ff                                 .dd1    $ff
6a82: 20 d6 66                           jsr     PRNTSTR
6a85: 51                                 .dd1    $51
6a86: c7 d2 c5 c5+                       .str    ↑“GREEN-SKY AWAITS ANOTHER QUESTER.”
6aa7: ff                                 .dd1    $ff
6aa8: a9 00                              lda     #$00
6aaa: 20 00 b6                           jsr     SCRN_play_melody
6aad: a5 83        L6AAD                 lda     waitMelody
6aaf: d0 fc                              bne     L6AAD
6ab1: 20 09 6b     L6AB1                 jsr     GAME2_ongoing_input
6ab4: f0 fb                              beq     L6AB1
6ab6: a9 00                              lda     #$00
6ab8: 85 3d                              sta     GAMEOVER                ;unset gameover
6aba: 85 ba                              sta     $ba
6abc: 4c 40 a8                           jmp     SCRN_warm_start

                   ; Read T22,S00..02 into $B300..$B5FF. This sets the initial item state from the
                   ; game disk. Note the RWTS IOB r/w buffer points to $0200 by default, and that
                   ; is temporarily changed during this read.
6abf: a9 22        init_item_state       lda     #$22
6ac1: 8d 04 03                           sta     RWTS_IOB_track
6ac4: a9 00                              lda     #$00
6ac6: 85 41                              sta     MON_A3H
6ac8: 85 35                              sta     doorNeshom
6aca: 85 44                              sta     lampFuel
6acc: 85 3a                              sta     litLamp
6ace: 85 38                              sta     fallaKeyOffered
6ad0: 8d 05 03                           sta     RWTS_IOB_sector
6ad3: a9 01                              lda     #RWTSCMD_read
6ad5: 8d 0c 03                           sta     RWTS_IOB_command
6ad8: ae 05 03     L6AD8                 ldx     RWTS_IOB_sector
6adb: bd e5 62                           lda     item_state_pages,x      ;override page to read into
6ade: 8d 09 03                           sta     RWTS_IOB_buf+1
6ae1: 20 a2 69                           jsr     swapzp8
6ae4: 20 15 03                           jsr     DIRECT_RWTS
6ae7: 20 a2 69                           jsr     swapzp8
6aea: ee 05 03                           inc     RWTS_IOB_sector
6aed: ad 05 03                           lda     RWTS_IOB_sector
6af0: c9 03                              cmp     #$03
6af2: d0 e4                              bne     L6AD8                   ;read sectors 00..02
6af4: a9 02                              lda     #$02                    ;restore read buffer to page $02
6af6: 8d 09 03                           sta     RWTS_IOB_buf+1
6af9: 60                                 rts

6afa: 05                                 .dd1    $05
6afb: 03                                 .dd1    $03
6afc: ad                                 .dd1    $ad
6afd: 05                                 .dd1    $05
6afe: 03                                 .dd1    $03
6aff: c9                                 .dd1    $c9

                   NOTE: Jump vectors at $6b00
6b00: 4c 30 6b     GAME2_next_frame      jmp     frame                   ;game tick

6b03: 4c 4f 74     GAME2_draw_player     jmp     draw_player

6b06: 4c 20 75     GAME2_erase_player    jmp     erase_old_player

6b09: 4c c3 75     GAME2_ongoing_input   jmp     get_ongoing_input

6b0c: 4c 4c 74     GAME2_redraw_player   jmp     redraw_player

6b0f: 4c 2a 72     GAME2_adjacent_tiles  jmp     get_adjacent_tiles

6b12: 4c 7e 72     L6B12                 jmp     tile_to_f0_f1_f2

6b15: 4c 79 75     L6B15                 jmp     draw_npc?               ;called in SCREEN

6b18: 4c 62 75     L6B18                 jmp     L7562

6b1b: 4c                                 .dd1    $4c                     ;called in SCREEN
6b1c: a6                                 .dd1    $a6
6b1d: 75                                 .dd1    $75

6b1e: 4c 60 72     GAME2_tile_at_xy      jmp     get_tile_at_xy          ;get_tile_at_xy

6b21: 4c d6 72     L6B21                 jmp     stop_frame_ground

6b24: 4c f6 72     GAME2_win_game        jmp     win_game

6b27: 4c 09 b6     GAME2_chkkey          jmp     SCRN_chkkey             ;external entry point

6b2a: 4c b1 75     GAME2_menu_input      jmp     get_menu_input

6b2d: 4c                                 .dd1    $4c
6b2e: 7d                                 .dd1    $7d
6b2f: 71                                 .dd1    $71

6b30: 20 57 6b     frame                 jsr     maybe_tick
6b33: a5 b3                              lda     $b3
6b35: f0 03                              beq     L6B3A
6b37: 20 a6 75                           jsr     L75A6
6b3a: a5 b2        L6B3A                 lda     erasePlayer             ;May indicate player needs to be erased
6b3c: d0 05                              bne     @erase_and_draw
6b3e: a5 b3                              lda     $b3
6b40: d0 04                              bne     L6B46
6b42: 60                                 rts

6b43: 20 20 75     @erase_and_draw       jsr     erase_old_player
6b46: a5 6b        L6B46                 lda     zp6b_npcHere
6b48: f0 03                              beq     @draw
6b4a: 20 79 75                           jsr     draw_npc?               ;?
6b4d: 20 4f 74     @draw                 jsr     draw_player
6b50: a9 00                              lda     #$00
6b52: 85 b3                              sta     $b3
6b54: 85 b2                              sta     erasePlayer
6b56: 60                                 rts

                   ; Tick if the game timer is running.
6b57: a5 87        maybe_tick            lda     TICKING
6b59: d0 01                              bne     tick
6b5b: 60                                 rts

6b5c: 20 1b 77     tick                  jsr     GAME2_next_tick
6b5f: 20 a9 6f                           jsr     handle_npc?
6b62: e6 88                              inc     animTimer
6b64: a5 88                              lda     animTimer               ;? timer counting up until animDelay to update player frame
6b66: c5 90                              cmp     animDelay               ;why not just dec animDelay
6b68: f0 01                              beq     @update
6b6a: 60                                 rts

6b6b: a9 00        @update               lda     #$00
6b6d: 85 88                              sta     animTimer
6b6f: 20 2a 72                           jsr     get_adjacent_tiles
6b72: a5 e3                              lda     tileUnder
6b74: 20 7e 72                           jsr     tile_to_f0_f1_f2
6b77: a5 9b                              lda     crouchFlag
6b79: f0 03                              beq     L6B7E
6b7b: 4c cf 6e                           jmp     uncrouch                ;resets $9b and returns -- noop frame?

6b7e: a5 f0        L6B7E                 lda     ySolid
6b80: f0 14                              beq     L6B96
6b82: a5 92                              lda     FALLCNT
6b84: f0 10                              beq     L6B96                   ;not falling, branch
6b86: c9 06                              cmp     #$06                    ;did we fall less than 6 tiles?
6b88: 90 03                              bcc     @footfall
6b8a: 20 0e 6e                           jsr     fell_6_or_more          ;>=6 tiles, jsr
6b8d: a2 02        @footfall             ldx     #$02                    ;landing noise
6b8f: 20 03 b6                           jsr     SCRN_play_sound
6b92: a9 00                              lda     #$00                    ;reset fall count
6b94: 85 92                              sta     FALLCNT
6b96: a5 96        L6B96                 lda     takingStep
6b98: f0 03                              beq     check_bonk
6b9a: 4c d6 6e                           jmp     walk_crawl_cycle

6b9d: a5 93        check_bonk            lda     bonkFrame
6b9f: f0 03                              beq     check_jumping
6ba1: 4c cf 6d                           jmp     bonking

6ba4: a5 8c        check_jumping         lda     jumpFlag
6ba6: f0 03                              beq     check_flying
6ba8: 4c 12 6d                           jmp     jumping

6bab: a5 94        check_flying          lda     flyFlag
6bad: f0 03                              beq     @notflying_check_x
6baf: 4c 66 6e                           jmp     flying

6bb2: a5 85        @notflying_check_x    lda     XDIR
6bb4: 85 91                              sta     $91                     ;save old xdir ?
6bb6: 20 c3 75                           jsr     get_ongoing_input
6bb9: f0 54                              beq     check_non_door_tile     ;no button pressed
6bbb: a5 92                              lda     FALLCNT                 ;(virtual) button press
6bbd: c9 02                              cmp     #$02                    ;have we fallen >= 2 tiles?
6bbf: 90 0b                              bcc     button_check_x
6bc1: a5 f0                              lda     ySolid                  ;and no solid ground below us?
6bc3: d0 07                              bne     button_check_x
6bc5: a5 a0                              lda     $a0                     ;and ???
6bc7: d0 03                              bne     button_check_x
6bc9: 4c 40 6e                           jmp     check_has_shuba         ;then do shuba check, we may fly

                   ; Reached here after (virtual) button press, and not trying to deploy shuba.
                   ; Check X motion.
6bcc: a5 85        button_check_x        lda     XDIR
6bce: f0 1a                              beq     button_check_y
6bd0: a5 f0                              lda     ySolid                  ;ignore x motion if we are standing on air
6bd2: f0 3b                              beq     check_non_door_tile     ;this tile will be handled as air
6bd4: a5 85                              lda     XDIR
6bd6: c5 95                              cmp     FACING
6bd8: f0 0d                              beq     @jump
6bda: 85 95                              sta     FACING                  ;face the way we are moving
6bdc: 20 2e 6e                           jsr     is_climbing
6bdf: b0 06                              bcs     @jump                   ;when climbing, allow jump in opposite direction
6be1: 20 d6 72                           jsr     stop_frame_ground
6be4: 4c c0 6c                           jmp     finish_move

6be7: 4c 8a 6d     @jump                 jmp     try_jump

                   ; Virtual button press, check Y motion. (Remember, keyboard input is translated
                   ; into the joystick API, so SPACE -> JOY DOWN + BUTTON, which enters the menu
                   ; below.)
6bea: a5 86        button_check_y        lda     YDIR
6bec: f0 14                              beq     check_door_tile         ;not moving, check door etc.
6bee: 30 12                              bmi     check_door_tile         ;moving up, check door etc.
6bf0: a5 e3                              lda     tileUnder               ;moving down, check tile below us
6bf2: 20 7e 72                           jsr     tile_to_f0_f1_f2
6bf5: a5 f0                              lda     ySolid
6bf7: f0 09                              beq     check_door_tile         ;not solid, I guess we can enter doors while falling?
6bf9: a9 00                              lda     #$00                    ;solid ground, pressing button+down enters menu
6bfb: 85 87                              sta     TICKING
6bfd: a9 01                              lda     #$01
6bff: 85 9f                              sta     enterMenu
6c01: 60                                 rts

                   ; Check the tile we are in front of, and if it is a door tile (BA,BB,BC) then
                   ; handle it as a door (1..3). We will only reach this when the (virtual) button
                   ; is pressed.
6c02: a5 e0        check_door_tile       lda     tileFeet
6c04: c9 ba                              cmp     #$ba
6c06: 90 07                              bcc     check_non_door_tile     ;< $BA
6c08: c9 bd                              cmp     #$bd
6c0a: b0 03                              bcs     check_non_door_tile     ;> $BC
6c0c: 4c 97 71                           jmp     handle_door             ;$E0 == BA..BC; becomes door pointer 1..3

                   ; The button may or may not be pressed when we arrive here, but the selected
                   ; tile ($F0..$F2) is always the one under our feet. If the button is pressed, we
                   ; know we're not entering a door or the menu, as that was handled earlier.
6c0f: a5 f0        check_non_door_tile   lda     ySolid                  ;the tile under our feet, checked above
6c11: d0 16                              bne     check_on_ladder         ;branch if on solid ground
6c13: e6 1a                              inc     playerY                 ;only air below us, fall one tile
6c15: a9 04                              lda     #$04
6c17: 85 90                              sta     animDelay
6c19: e6 92                              inc     FALLCNT
6c1b: a5 92                              lda     FALLCNT
6c1d: c9 02                              cmp     #$02                    ;have we fallen 2 tiles
6c1f: d0 05                              bne     @cont
6c21: a2 09                              ldx     #$09                    ;yes, play this sound, which appears to make no sound
6c23: 20 03 b6                           jsr     SCRN_play_sound         ;change to #$01 to beep after falling 2 tiles
6c26: 4c c4 6c     @cont                 jmp     finish_move2            ;(skips resetting FALLCNT to 0)

                   ; Check if the player is centered on a ladder/vine, with a center ladder/vine
                   ; tile both at their feet and just under them. This implies the player is on a
                   ; ladder, since both tiles wouldn't be present if you are at the top or the
                   ; bottom of a ladder. Since horizontal motion on a ladder is disallowed, skip
                   ; XDIR handling if on the ladder.
6c29: a5 e0        check_on_ladder       lda     tileFeet
6c2b: c9 b5                              cmp     #$b5                    ;ladder middle tile
6c2d: f0 04                              beq     @atfeet
6c2f: c9 b8                              cmp     #$b8                    ;vine middle tile
6c31: d0 0d                              bne     @check_horiz_motion
6c33: a5 e3        @atfeet               lda     tileUnder
6c35: c9 b5                              cmp     #$b5
6c37: f0 04                              beq     @on_ladder
6c39: c9 b8                              cmp     #$b8
6c3b: d0 03                              bne     @check_horiz_motion
6c3d: 4c 5e 6c     @on_ladder            jmp     check_vert_motion       ;on ladder; skip horiz motion check

                   ; Check horizontal motion. If yes, and we are facing the opposite direction,
                   ; face the new direction and cancel motion.
6c40: a5 85        @check_horiz_motion   lda     XDIR
6c42: f0 1a                              beq     check_vert_motion       ;no horiz motion; check vertical
6c44: c5 95                              cmp     FACING
6c46: f0 0c                              beq     @facing_same_dir
6c48: 85 95                              sta     FACING                  ;moved opposite dir we are facing
6c4a: a9 00                              lda     #$00                    ;update facing direction, and cancel movement
6c4c: 85 af                              sta     XMOVFLG
6c4e: 20 d6 72                           jsr     stop_frame_ground
6c51: 4c c0 6c                           jmp     finish_move

6c54: 38           @facing_same_dir      sec                             ;toggle $97 between 0 and 2 (step frame offset)
6c55: a9 02                              lda     #$02                    ;2-2=0, 2-0=2
6c57: e5 97                              sbc     $97
6c59: 85 97                              sta     $97
6c5b: 4c d6 6e                           jmp     walk_crawl_cycle

                   ; Check vertical motion. If moving up, and the tile at our feet is climbable,
                   ; start climbing up; if it's not climbable then stand up from a crawl (if
                   ; needed).
                   ; 
                   ; (You can arrive here after already confirming we are on the ladder. The below
                   ; checks are more general though, since you don't need to be centered on the
                   ; ladder, and it may be above or below you.)
6c5e: 18           check_vert_motion     clc
6c5f: a5 86                              lda     YDIR
6c61: f0 54                              beq     @no_vert_motion         ;no vertical motion
6c63: 10 33                              bpl     @moving_down            ;moving down
6c65: a5 e0                              lda     tileFeet                ;we are moving up
6c67: 20 7e 72                           jsr     tile_to_f0_f1_f2
6c6a: a5 f2                              lda     climbable
6c6c: d0 0b                              bne     @climb_up
6c6e: a5 9a                              lda     crawlFlag
6c70: f0 4d                              beq     @rts
6c72: a9 00                              lda     #$00
6c74: 85 9a                              sta     crawlFlag
6c76: 4c bc 6e                           jmp     crouch

                   ; Climb; move player up 1 tile. Snap to the center of the ladder or vine.
6c79: a9 0a        @climb_up             lda     #$0a
6c7b: 85 90                              sta     animDelay
6c7d: c6 1a                              dec     playerY                 ;move up 1 tile
6c7f: a5 e0                              lda     tileFeet
6c81: c9 b4        @check_left_side      cmp     #$b4                    ;left ladder tile
6c83: f0 04                              beq     @adjust_right
6c85: c9 b7                              cmp     #$b7                    ;left vine tile
6c87: d0 02                              bne     @check_right_side
6c89: e6 19        @adjust_right         inc     playerX
6c8b: c9 b6        @check_right_side     cmp     #$b6                    ;right ladder tile
6c8d: f0 04                              beq     @adjust_left
6c8f: c9 b9                              cmp     #$b9                    ;right vine tile
6c91: d0 02                              bne     @cont
6c93: c6 19        @adjust_left          dec     playerX
6c95: 4c 4b 6f     @cont                 jmp     L6F4B

                   ; If moving down and the tile below us is climbable, start climbing down; if
                   ; it's not climbable, start crawling (if not already doing so).
6c98: a5 e3        @moving_down          lda     tileUnder
6c9a: 20 7e 72                           jsr     tile_to_f0_f1_f2
6c9d: a5 f2                              lda     climbable               ;is tile at knee climbable?
6c9f: d0 0b                              bne     @climb_down
6ca1: a5 9a                              lda     crawlFlag               ;no, try to crawl
6ca3: d0 1a                              bne     @rts                    ;already crawling, return
6ca5: a9 01                              lda     #$01
6ca7: 85 9a                              sta     crawlFlag               ;now set crawl flag
6ca9: 4c bc 6e                           jmp     crouch

                   ; Climb down; move down one tile. Snap to the center of the ladder or vine.
6cac: a9 0a        @climb_down           lda     #$0a                    ;signal climb start?
6cae: 85 90                              sta     animDelay
6cb0: e6 1a                              inc     playerY
6cb2: a5 e3                              lda     tileUnder
6cb4: 4c 81 6c                           jmp     @check_left_side

6cb7: a9 08        @no_vert_motion       lda     #$08
6cb9: 85 90                              sta     animDelay
6cbb: a9 00                              lda     #$00
6cbd: 85 99                              sta     runFlag
6cbf: 60           @rts                  rts

                   ********************************************************************************
                   * Finishes up player movement for this frame.                                  *
                   *                                                                              *
                   * Stops any falling motion; assumes called when on solid ground. In one case   *
                   * this is bypassed, when it is known the player is in the air.                 *
                   *                                                                              *
                   * Checks for collision with water and sets a flag handled next frame.          *
                   *                                                                              *
                   * Checks for collision with brambles or walls.                                 *
                   *                                                                              *
                   * Checks if the player is offscreen (presumably by one tile) in either or both *
                   * of the X or Y axes. The player is moved 1 tile in the onscreen X direction   *
                   * if needed (Y position is not modified), and zp $8f is set to                 *
                   *   01 -- was off top                                                          *
                   *   02 -- was off right                                                        *
                   *   03 -- was off bottom                                                       *
                   *   04 -- was off left                                                         *
                   * with the Y axis taking precedence.                                           *
                   *                                                                              *
                   * This is called via JMP, so we will continue in the caller's caller.          *
                   ********************************************************************************
                   tmp_offScreenFlag     .var    $81    {addr/1}         ;whether the player was offscreen

6cc0: a9 00        finish_move           lda     #$00                    ;stop falling, unless you enter this just below
6cc2: 85 92                              sta     FALLCNT
6cc4: 20 28 71     finish_move2          jsr     check_brambles
6cc7: 20 4a 71                           jsr     check_walls             ;(implicitly populates tileFeet)
                   ; Check if we touched water. If so, stop time and set a flag which will teleport
                   ; us home on the next frame. This subroutine continues but its offscreen
                   ; computations are irrelevant; it could just return instead.
6cca: a5 e0                              lda     tileFeet
6ccc: c9 20                              cmp     #tile_water
6cce: d0 08                              bne     @left
6cd0: a9 01                              lda     #$01
6cd2: 85 80                              sta     touchedWater
6cd4: a9 00                              lda     #$00                    ;halt timer in prep for teleport
6cd6: 85 87                              sta     TICKING
6cd8: a9 00        @left                 lda     #$00
6cda: 85 81                              sta     tmp_offScreenFlag
6cdc: a5 19                              lda     playerX
6cde: 10 08                              bpl     @right
6ce0: a2 04                              ldx     #$04                    ;player offscreen to left
6ce2: e6 19                              inc     playerX
6ce4: e6 81                              inc     tmp_offScreenFlag
6ce6: d0 0a                              bne     @top                    ;(always)
6ce8: c9 28        @right                cmp     #$28
6cea: d0 06                              bne     @top
6cec: a2 02                              ldx     #$02                    ;player offscreen to right
6cee: c6 19                              dec     playerX
6cf0: e6 81                              inc     tmp_offScreenFlag
6cf2: a5 1a        @top                  lda     playerY
6cf4: 10 04                              bpl     @bottom
6cf6: a2 01                              ldx     #$01                    ;player offscreen to top
6cf8: d0 0c                              bne     @offscreen              ;(always)

6cfa: c9 13        @bottom               cmp     #$13
6cfc: 90 04                              bcc     @is_onscreen
6cfe: a2 03                              ldx     #$03                    ;player offscreen to bottom
6d00: d0 04                              bne     @offscreen              ;(always)

6d02: a5 81        @is_onscreen          lda     tmp_offScreenFlag       ;was the player offscreen?
6d04: f0 07                              beq     @queue_erase            ;no, queue up player erase
                   ; X is guaranteed to be set to 01..04 when the offscreen flag is set.
6d06: 86 8f        @offscreen            stx     nextRoomDir             ;yes, record in which direction
6d08: a9 00                              lda     #$00                    ;and halt timer
6d0a: 85 87                              sta     TICKING
6d0c: 60                                 rts

6d0d: a9 01        @queue_erase          lda     #$01
6d0f: 85 b2                              sta     erasePlayer
6d11: 60                                 rts

                   • Clear variables

6d12: a9 04        jumping               lda     #$04
6d14: 85 90                              sta     animDelay
6d16: a2 18                              ldx     #$18                    ;left jump frame
6d18: a5 95                              lda     FACING
6d1a: 30 02                              bmi     @left
6d1c: a2 1c                              ldx     #$1c                    ;right jump frame
6d1e: 20 b2 6e     @left                 jsr     set_anim_frame
6d21: a5 8d                              lda     jumpFrame
6d23: c9 01                              cmp     #$01
6d25: f0 18                              beq     update_jump_pos         ;start of jump, do not check x solidity
6d27: a5 e3                              lda     tileUnder               ;check tile under our feet
6d29: 20 7e 72                           jsr     tile_to_f0_f1_f2
6d2c: a5 f1                              lda     xSolid
6d2e: f0 0f                              beq     update_jump_pos
6d30: a9 00                              lda     #$00                    ;tile is solid, so land on it (?)
6d32: 85 8c                              sta     jumpFlag
6d34: 20 d6 72                           jsr     stop_frame_ground
6d37: a2 02                              ldx     #$02                    ;footstep (landing sound)?
6d39: 20 03 b6                           jsr     SCRN_play_sound
6d3c: 4c 6b 6b                           jmp     @update

                   ; Update player position during jump. Player moves 1 tile horizontally during
                   ; each of 4 jump frames. During each of frames 1 & 2, player moves up 1 tile;
                   ; and down 1 tile during frames 3 & 4. If the player's stamina is 20 or more,
                   ; they jump farther by adding an extra frame (frame 3 is repeated, but the
                   ; player only moves horizontally).
6d3f: 18           update_jump_pos       clc
6d40: a5 95                              lda     FACING
6d42: 65 19                              adc     playerX
6d44: 85 19                              sta     playerX
6d46: a6 8d                              ldx     jumpFrame
6d48: e0 03                              cpx     #$03                    ;third frame?
6d4a: d0 04                              bne     @yupdate
6d4c: c6 b4                              dec     longJump                ;1 (stamina <20) or 2 (>=20), set at start of jump
6d4e: d0 1c                              bne     @finish                 ;if 2, keep player at same Y, repeat frame 3 (with longJump 1)
6d50: bd 85 6d     @yupdate              lda     jump_frame_yoffset-1,x  ;up,up,down,down
6d53: 18                                 clc
6d54: 65 1a                              adc     playerY
6d56: 85 1a                              sta     playerY
6d58: e8                                 inx
6d59: 86 8d                              stx     jumpFrame
6d5b: e0 04                              cpx     #$04                    ;was this the 3rd or 4th frame?
6d5d: b0 10                              bcs     land_player
6d5f: a6 8d        @chk_last_frame       ldx     jumpFrame
6d61: e0 05                              cpx     #$05
6d63: d0 07                              bne     @finish
6d65: a9 00                              lda     #$00                    ;last jump frame, always finish jump now
6d67: 85 8c                              sta     jumpFlag
6d69: 20 d6 72                           jsr     stop_frame_ground
6d6c: 4c c0 6c     @finish               jmp     finish_move

6d6f: a5 95        land_player           lda     FACING
6d71: 10 05                              bpl     @right
6d73: a5 e4                              lda     tileUnderLeft
6d75: 4c 7a 6d                           jmp     @check_ground

6d78: a5 e5        @right                lda     tileUnderRight
6d7a: 20 7e 72     @check_ground         jsr     tile_to_f0_f1_f2
6d7d: a5 f1                              lda     xSolid
6d7f: f0 de                              beq     @chk_last_frame
6d81: c6 1a                              dec     playerY
6d83: 4c 5f 6d                           jmp     @chk_last_frame

6d86: ff           jump_frame_yoffset    .dd1    $ff                     ;jump frame 1..4 y offset
6d87: ff                                 .dd1    $ff                     ;(move up 2, then down 2)
6d88: 01                                 .dd1    $01
6d89: 01                                 .dd1    $01

                   ; Underground, in the the bottom 4 map rows (positions $0180-$01FF), you cannot
                   ; jump while climbing. This is probably an easy way to handle most ladders being
                   ; surrounded by solid rock; the few that are not, you don't notice this.
6d8a: a5 1c        try_jump              lda     MAPHALF
6d8c: f0 0c                              beq     jump
6d8e: a5 1b                              lda     MAPPOS
6d90: c9 80                              cmp     #$80
6d92: 90 06                              bcc     jump
6d94: 20 2e 6e                           jsr     is_climbing
6d97: 90 01                              bcc     jump
6d99: 60                                 rts                             ;maphalf=$1,mappos>=$80,climbing

6d9a: a9 06        jump                  lda     #$06
6d9c: 85 90                              sta     animDelay
6d9e: a9 01                              lda     #$01
6da0: 85 8c                              sta     jumpFlag
6da2: 85 8d                              sta     jumpFrame
6da4: 85 99                              sta     runFlag
6da6: a9 00                              lda     #$00
6da8: 85 9a                              sta     crawlFlag
6daa: a2 16                              ldx     #$16                    ;left crouch frame (to start the jump)
6dac: a5 95                              lda     FACING
6dae: 30 02                              bmi     @set_frame
6db0: a2 1a                              ldx     #$1a                    ;right crouch frame
6db2: 86 a3        @set_frame            stx     animFrame
6db4: e8                                 inx
6db5: 86 a4                              stx     animFrame_unused
6db7: a2 06                              ldx     #$06
6db9: 20 03 b6                           jsr     SCRN_play_sound
6dbc: a2 05                              ldx     #$05
6dbe: 20 a2 71                           jsr     handle_food_rest
6dc1: a2 02                              ldx     #$02
6dc3: a5 26                              lda     levelStamina
6dc5: c9 14                              cmp     #$14
6dc7: b0 01                              bcs     @long
6dc9: ca                                 dex
6dca: 86 b4        @long                 stx     longJump                ;1 if stamina level < 20, 2 if >= 20
6dcc: 4c c0 6c                           jmp     finish_move

                   ; Handle frame of bonking head. Bonk frames 1..8 alternate frames $1E and $20
                   ; (rubbing head). Frame 9 is a crouch (getting up). Frame 10 stands up and
                   ; finishes.
6dcf: a5 93        bonking               lda     bonkFrame
6dd1: c9 02                              cmp     #$02
6dd3: d0 05                              bne     @nosound
6dd5: a2 07                              ldx     #$07                    ;Play bonk sound during frame 2
6dd7: 20 03 b6                           jsr     SCRN_play_sound
6dda: e6 93        @nosound              inc     bonkFrame
6ddc: a5 93                              lda     bonkFrame
6dde: c9 0a                              cmp     #$0a                    ;in frame 10, start getting up
6de0: f0 1f                              beq     @get_up
6de2: c9 0b                              cmp     #$0b
6de4: f0 0d                              beq     @end_bonk
6de6: a5 a1                              lda     bonkAlt                 ;alternate frames (why not just AND $93 with #$01)
6de8: 49 01                              eor     #$01
6dea: 85 a1                              sta     bonkAlt
6dec: a8                                 tay
6ded: be 0c 6e                           ldx     bonk_frame,y            ;frame 0 ($1e) or 1 ($20)
6df0: 4c b2 6e                           jmp     set_anim_frame

6df3: a9 00        @end_bonk             lda     #$00
6df5: 85 93                              sta     bonkFrame
6df7: a9 08                              lda     #$08
6df9: 85 90                              sta     animDelay
6dfb: 20 d6 72                           jsr     stop_frame_ground
6dfe: 4c 06 60                           jmp     GAME2_cleartext

6e01: a2 16        @get_up               ldx     #$16                    ;set left or right crouch frame to arise
6e03: a5 95                              lda     FACING
6e05: 30 02                              bmi     @ret
6e07: a2 1a                              ldx     #$1a
6e09: 4c b2 6e     @ret                  jmp     set_anim_frame

6e0c: 1e           bonk_frame            .dd1    $1e                     ;alternate bonk frames
6e0d: 20                                 .dd1    $20

6e0e: a9 01        fell_6_or_more        lda     #$01
6e10: 85 93                              sta     bonkFrame
6e12: a2 1e                              ldx     #$1e                    ;bonk start frame
6e14: 20 b2 6e                           jsr     set_anim_frame
6e17: a9 00                              lda     #$00                    ;not falling any more!
6e19: 85 92                              sta     FALLCNT
6e1b: 85 a0                              sta     $a0
6e1d: 85 af                              sta     XMOVFLG
6e1f: 20 7d 71                           jsr     reset_after_hurt
6e22: a9 0f                              lda     #$0f
6e24: 85 90                              sta     animDelay
6e26: a2 40                              ldx     #$40
6e28: 20 a2 71                           jsr     handle_food_rest
6e2b: 4c f2 71                           jmp     maybe_tear_shuba        ;and return to caller

                   ; Returns bool in carry. Returns true (set) if game timer is running AND $a3 is
                   ; between $10 and $15, implying player is climbing.
6e2e: a5 87        is_climbing           lda     TICKING
6e30: f0 0c                              beq     @clc                    ;game paused; clear carry
6e32: a5 a3                              lda     animFrame
6e34: c9 10                              cmp     #$10
6e36: 90 06                              bcc     @clc                    ;$a3 < $10 or
6e38: c9 16                              cmp     #$16                    ;$a3 > $15; clear carry
6e3a: b0 02                              bcs     @clc
6e3c: 38                                 sec
6e3d: 60                                 rts

6e3e: 18           @clc                  clc
6e3f: 60                                 rts

                   ; Check if we have a shuba in inventory. Reached when the button is pressed and
                   ; we have falled 2 or more tiles.
6e40: a2 13        check_has_shuba       ldx     #$13                    ;check all shuba slots
6e42: bd 58 b5     @loop                 lda     inv_shuba,x
6e45: 2c bd 1d                           bit     GAME1_BITTAB5
6e48: d0 06                              bne     @has_shuba
6e4a: ca                                 dex
6e4b: 10 f5                              bpl     @loop
6e4d: 4c 0f 6c                           jmp     check_non_door_tile     ;no shuba, return to normal processing

                   ; If we did have a shuba, stop falling (and crawling, if we crawled off a ledge)
                   ; and fly!
6e50: a9 01        @has_shuba            lda     #$01
6e52: 85 94                              sta     flyFlag                 ;whee!
6e54: 20 aa 6e                           jsr     L6EAA
6e57: a9 00                              lda     #$00
6e59: 85 92                              sta     FALLCNT
6e5b: 85 9a                              sta     crawlFlag
6e5d: a9 08                              lda     #$08
6e5f: 85 90                              sta     animDelay
6e61: a2 08                              ldx     #$08
6e63: 20 03 b6                           jsr     SCRN_play_sound
6e66: a5 e0        flying                lda     tileFeet                ;external entry, when already flying
6e68: 20 7e 72                           jsr     tile_to_f0_f1_f2
6e6b: a5 f1                              lda     xSolid
6e6d: f0 11                              beq     L6E80
6e6f: c6 1a                              dec     playerY
6e71: a9 00        @land                 lda     #$00
6e73: 85 94                              sta     flyFlag
6e75: 20 d6 72                           jsr     stop_frame_ground
6e78: a2 02                              ldx     #$02
6e7a: 20 03 b6                           jsr     SCRN_play_sound
6e7d: 4c c0 6c                           jmp     finish_move

6e80: a5 e3        L6E80                 lda     tileUnder
6e82: 20 7e 72                           jsr     tile_to_f0_f1_f2
6e85: a5 f1                              lda     xSolid
6e87: d0 e8                              bne     @land
                   ; We are clear of obstacles.
6e89: 20 c3 75                           jsr     get_ongoing_input
6e8c: a5 85                              lda     XDIR
6e8e: f0 0e                              beq     L6E9E
                   ; We pressed left or right, so if we are changing direction, face that way and
                   ; play a sound.
6e90: c5 95                              cmp     FACING
6e92: f0 0a                              beq     L6E9E
6e94: 85 95                              sta     FACING
6e96: 20 aa 6e                           jsr     L6EAA
6e99: a2 0b                              ldx     #$0b
6e9b: 20 03 b6                           jsr     SCRN_play_sound
6e9e: a5 95        L6E9E                 lda     FACING
6ea0: 18                                 clc
6ea1: 65 19                              adc     playerX
6ea3: 85 19                              sta     playerX
6ea5: e6 1a                              inc     playerY
6ea7: 4c c0 6c                           jmp     finish_move

6eaa: a2 0c        L6EAA                 ldx     #$0c
6eac: a5 95                              lda     FACING
6eae: 30 02                              bmi     set_anim_frame
6eb0: a2 0e                              ldx     #$0e
6eb2: 86 a3        set_anim_frame        stx     animFrame
6eb4: e8                                 inx
6eb5: 86 a4                              stx     animFrame_unused
6eb7: a9 01                              lda     #$01
6eb9: 85 b2                              sta     erasePlayer
6ebb: 60                                 rts

                   ; Crouch. Whether we are about to stand or about to crawl in the next frame is
                   ; encoded in crawlFlag.
6ebc: a9 01        crouch                lda     #$01
6ebe: 85 9b                              sta     crouchFlag              ;writes to $9b are contained here
6ec0: a9 05                              lda     #$05
6ec2: 85 90                              sta     animDelay
6ec4: a2 16                              ldx     #$16                    ;crouch left
6ec6: a4 95                              ldy     FACING
6ec8: 30 02                              bmi     @left
6eca: a2 1a                              ldx     #$1a                    ;crouch right
6ecc: 4c b2 6e     @left                 jmp     set_anim_frame

                   ; Called from main tick loop when crouching. Resets crouchFlag and sets the
                   ; player animation frame to stand or crawl. crawlFlag will be set along with
                   ; crouchFlag when crawling, effectively queueing a stand or crawl.
6ecf: a9 00        uncrouch              lda     #$00
6ed1: 85 9b                              sta     crouchFlag
6ed3: 4c d6 72                           jmp     stop_frame_ground

                   ********************************************************************************
                   * This appears to handle walk/run/crawl cycle. Sets the animation delay (hold  *
                   * time for current player animation frame) appropriately for the current       *
                   * action. Crawling is slow, walking is medium and running is fast. Each is 4   *
                   * frames long, with frames 0 and 2 being identical (standing still) and frames *
                   * 1 and 3 being left and right steps.                                          *
                   *                                                                              *
                   * $A3 animation frames:                                                        *
                   * Left walk animation: $00, $02, $00, $04                                      *
                   * Right walk animation: $06, $08, $06, $0A                                     *
                   * Left glide: $0C                                                              *
                   * Right glide: $0E                                                             *
                   * Climb: $10, $12                                                              *
                   * Unknown (unused?): $14                                                       *
                   * Left crouch: $16                                                             *
                   * Left jump: $18                                                               *
                   * Right crouch: $1A (between standing and crawling/bonk, or start of jump)     *
                   * Right jump: $1C                                                              *
                   * Bonk: $1E, $20, $1E, $20, $1E, $20                                           *
                   * Left crawl animation: $22, $24, $22, $26                                     *
                   * Right crawl animation: $28, $2A, $28, $2C                                    *
                   * Resting: $2E                                                                 *
                   ********************************************************************************
6ed6: a6 96        walk_crawl_cycle      ldx     takingStep              ;0 or 1, alternating frames; basically, taking a step
6ed8: bd 3f 6f                           lda     next_step_value,x
6edb: 85 96                              sta     takingStep
6edd: a5 9a                              lda     crawlFlag
6edf: f0 0b                              beq     @not_crawling
6ee1: bd 45 6f                           lda     crawling_delay,x        ;crawling
6ee4: 85 90                              sta     animDelay
6ee6: bd 49 6f                           lda     crawl_frames,x
6ee9: 4c fb 6e                           jmp     @facing

6eec: bd 41 6f     @not_crawling         lda     walking_delay,x
6eef: a4 99                              ldy     runFlag
6ef1: f0 03                              beq     @walking
6ef3: bd 43 6f                           lda     running_delay,x
6ef6: 85 90        @walking              sta     animDelay
6ef8: bd 47 6f                           lda     walk_frames,x
6efb: a6 95        @facing               ldx     FACING
6efd: 30 03                              bmi     @left
6eff: 18                                 clc
6f00: 69 06                              adc     #$06                    ;right facing frames are left facing + 6
6f02: a6 96        @left                 ldx     takingStep
6f04: f0 03                              beq     @step
6f06: 18                                 clc
6f07: 65 97                              adc     $97                     ;should add 2 only on right step
6f09: 85 a3        @step                 sta     animFrame               ;or maybe no step
6f0b: 85 a4                              sta     animFrame_unused
6f0d: e6 a4                              inc     animFrame_unused        ;maintain A4=A3+1
6f0f: a5 96                              lda     takingStep
6f11: d0 26                              bne     @nostep                 ;note meaning may be reversed
6f13: 18                                 clc
6f14: a5 95                              lda     FACING                  ;move the player
6f16: 65 19                              adc     playerX
6f18: 85 19                              sta     playerX
6f1a: a5 95                              lda     FACING                  ;and check left/right tile at feet, depending on facing
6f1c: 10 05                              bpl     @right                  ;note this is the tile we are now directly over
6f1e: a5 e1                              lda     tileFeetLeft
6f20: 4c 25 6f                           jmp     @gettile

6f23: a5 e2        @right                lda     tileFeetRight
6f25: 20 7e 72     @gettile              jsr     tile_to_f0_f1_f2
6f28: a5 f1                              lda     xSolid
6f2a: f0 02                              beq     @solid
6f2c: c6 1a                              dec     playerY                 ;tile was not solid, so fall through one tile
6f2e: a2 02        @solid                ldx     #$02                    ;footstep sound 1
6f30: a5 97                              lda     $97
6f32: d0 02                              bne     @sound
6f34: a2 03                              ldx     #$03                    ;footstep sound 2
6f36: 20 03 b6     @sound                jsr     SCRN_play_sound
6f39: 20 d1 71     @nostep               jsr     check_cave_door?
6f3c: 4c c0 6c                           jmp     finish_move

6f3f: 01           next_step_value       .dd1    $01
6f40: 00                                 .dd1    $00
6f41: 06           walking_delay         .dd1    $06
6f42: 04                                 .dd1    $04
6f43: 03           running_delay         .dd1    $03                     ;not crawling nor walking, unsure
6f44: 02                                 .dd1    $02
6f45: 08           crawling_delay        .dd1    $08
6f46: 08                                 .dd1    $08
6f47: 02           walk_frames           .dd1    $02
6f48: 00                                 .dd1    $00
6f49: 24           crawl_frames          .dd1    $24
6f4a: 22                                 .dd1    $22

6f4b: a9 00        L6F4B                 lda     #$00
6f4d: 85 99                              sta     runFlag
6f4f: 85 9a                              sta     crawlFlag
6f51: a5 1a                              lda     playerY
6f53: 30 4f                              bmi     L6FA4
6f55: f0 30                              beq     L6F87
6f57: c9 13                              cmp     #$13
6f59: f0 49                              beq     L6FA4
6f5b: a5 e6                              lda     tileKnee
6f5d: a6 86                              ldx     YDIR
6f5f: 30 02                              bmi     L6F63
6f61: a5 e3                              lda     tileUnder
6f63: 20 7e 72     L6F63                 jsr     tile_to_f0_f1_f2
6f66: a5 f2                              lda     climbable
6f68: d0 06                              bne     L6F70
6f6a: 20 bc 6e                           jsr     crouch
6f6d: 4c c0 6c                           jmp     finish_move

6f70: a5 e7        L6F70                 lda     tileArm
6f72: a6 86                              ldx     YDIR
6f74: 30 02                              bmi     L6F78
6f76: a5 e0                              lda     tileFeet
6f78: 20 7e 72     L6F78                 jsr     tile_to_f0_f1_f2
6f7b: a5 f2                              lda     climbable
6f7d: d0 08                              bne     L6F87
6f7f: a2 14                              ldx     #$14
6f81: 20 b2 6e                           jsr     set_anim_frame
6f84: 4c c0 6c                           jmp     finish_move

6f87: a5 98        L6F87                 lda     $98
6f89: 49 01                              eor     #$01
6f8b: 85 98                              sta     $98
6f8d: a8                                 tay
6f8e: be a7 6f                           ldx     L6FA7,y
6f91: 20 b2 6e                           jsr     set_anim_frame
6f94: a2 04                              ldx     #$04
6f96: a5 86                              lda     YDIR
6f98: 30 02                              bmi     L6F9C
6f9a: a2 05                              ldx     #$05
6f9c: 20 03 b6     L6F9C                 jsr     SCRN_play_sound
6f9f: a2 01                              ldx     #$01
6fa1: 20 a2 71                           jsr     handle_food_rest
6fa4: 4c c0 6c     L6FA4                 jmp     finish_move

6fa7: 10           L6FA7                 .dd1    $10
6fa8: 12                                 .dd1    $12

6fa9: a5 6b        handle_npc?           lda     zp6b_npcHere
6fab: d0 01                              bne     L6FAE
6fad: 60                                 rts

6fae: e6 53        L6FAE                 inc     $53
6fb0: a5 53                              lda     $53
6fb2: c5 54                              cmp     $54
6fb4: f0 01                              beq     L6FB7
6fb6: 60                                 rts

6fb7: a9 00        L6FB7                 lda     #$00
6fb9: 85 53                              sta     $53
6fbb: a5 6c                              lda     npcX
6fbd: 18                                 clc
6fbe: 65 6f                              adc     npcFacing
6fc0: aa                                 tax
6fc1: a4 6d                              ldy     npcY
6fc3: 20 60 72                           jsr     get_tile_at_xy
6fc6: 85 a7                              sta     $a7
6fc8: a6 6c                              ldx     npcX
6fca: a4 6d                              ldy     npcY
6fcc: c8                                 iny
6fcd: 20 60 72                           jsr     get_tile_at_xy
6fd0: 85 a8                              sta     $a8
6fd2: a5 50                              lda     $50
6fd4: f0 03                              beq     L6FD9
6fd6: 4c 9f 70                           jmp     L709F

6fd9: a5 a8        L6FD9                 lda     $a8
6fdb: 20 7e 72                           jsr     tile_to_f0_f1_f2
6fde: a5 f0                              lda     ySolid
6fe0: d0 0b                              bne     L6FED
6fe2: e6 6d                              inc     npcY
6fe4: a9 04                              lda     #$04
6fe6: 85 54                              sta     $54
6fe8: a9 01                              lda     #$01
6fea: 85 b3                              sta     $b3
6fec: 60                                 rts

6fed: a5 6a        L6FED                 lda     $6a
6fef: c9 08                              cmp     #$08
6ff1: f0 32                              beq     L7025
6ff3: c9 09                              cmp     #$09
6ff5: f0 2e                              beq     L7025
6ff7: ad f2 02                           lda     RWTSBUF_npctype
6ffa: 29 f0                              and     #$f0
6ffc: c9 e0                              cmp     #$e0
6ffe: d0 03                              bne     L7003
7000: 4c f5 70                           jmp     L70F5

7003: a5 6c        L7003                 lda     npcX
7005: 18                                 clc
7006: 65 6f                              adc     npcFacing
7008: c5 19                              cmp     playerX
700a: f0 07                              beq     L7013
700c: 18                                 clc
700d: 65 6f                              adc     npcFacing
700f: c5 19                              cmp     playerX
7011: d0 39                              bne     L704C
7013: a6 6d        L7013                 ldx     npcY
7015: e4 1a                              cpx     playerY
7017: f0 0b                              beq     L7024
7019: e8                                 inx
701a: e4 1a                              cpx     playerY
701c: f0 06                              beq     L7024
701e: ca                                 dex
701f: ca                                 dex
7020: e4 1a                              cpx     playerY
7022: d0 28                              bne     L704C
7024: 60           L7024                 rts

7025: a5 93        L7025                 lda     bonkFrame
7027: d0 23                              bne     L704C
7029: a6 6d                              ldx     npcY
702b: e4 1a                              cpx     playerY
702d: f0 05                              beq     L7034
702f: ca                                 dex
7030: e4 1a                              cpx     playerY
7032: d0 18                              bne     L704C
7034: a5 6c        L7034                 lda     npcX
7036: c5 19                              cmp     playerX
7038: f0 0e                              beq     L7048
703a: 18                                 clc
703b: 65 6f                              adc     npcFacing
703d: c5 19                              cmp     playerX
703f: f0 07                              beq     L7048
7041: 18                                 clc
7042: 65 6f                              adc     npcFacing
7044: c5 19                              cmp     playerX
7046: d0 04                              bne     L704C
                   NOTE: Setting fallcnt to $0A is observed to happen when you bump your head.
7048: a9 0a        L7048                 lda     #$0a
704a: 85 92                              sta     FALLCNT
704c: a5 52        L704C                 lda     $52
704e: d0 28                              bne     L7078
7050: a5 6c                              lda     npcX
7052: cd e6 02                           cmp     RWTSBUF+230
7055: f0 05                              beq     L705C
7057: cd e7 02                           cmp     RWTSBUF+231
705a: d0 1c                              bne     L7078
705c: a9 00        L705C                 lda     #$00
705e: 38                                 sec
705f: e5 6f                              sbc     npcFacing
7061: 85 6f                              sta     npcFacing
7063: 20 62 75                           jsr     L7562
7066: a9 01                              lda     #$01
7068: 85 b3                              sta     $b3
706a: a6 6e                              ldx     zp6e
706c: bd 76 70                           lda     L7076,x
706f: 85 54                              sta     $54
7071: a9 01                              lda     #$01
7073: 85 52                              sta     $52
7075: 60                                 rts

7076: 0c           L7076                 .dd1    $0c
7077: 08                                 .dd1    $08

7078: 20 21 60     L7078                 jsr     GAME2_read_0900
707b: 29 07                              and     #$07                    ;check lower 3 bits
707d: d0 12                              bne     L7091
707f: a6 6a                              ldx     $6a
7081: e0 08                              cpx     #$08
7083: f0 0b                              beq     @rts
7085: e0 09                              cpx     #$09
7087: f0 07                              beq     @rts
7089: 20 21 60                           jsr     GAME2_read_0900
708c: 29 7f                              and     #$7f
708e: 85 54                              sta     $54
7090: 60           @rts                  rts

7091: a5 52        L7091                 lda     $52
7093: d0 0a                              bne     L709F
7095: 20 21 60                           jsr     GAME2_read_0900
7098: 29 0f                              and     #$0f
709a: d0 03                              bne     L709F
709c: 4c 5c 70                           jmp     L705C

709f: a9 00        L709F                 lda     #$00
70a1: 85 52                              sta     $52
70a3: a5 50                              lda     $50
70a5: 49 01                              eor     #$01
70a7: 85 50                              sta     $50
70a9: a8                                 tay
70aa: b9 ef 70                           lda     L70EF,y
70ad: a6 6e                              ldx     zp6e
70af: f0 03                              beq     L70B4
70b1: b9 f1 70                           lda     L70F1,y
70b4: 85 54        L70B4                 sta     $54
70b6: b9 f3 70                           lda     L70F3,y
70b9: a6 6f                              ldx     npcFacing
70bb: 30 03                              bmi     L70C0
70bd: 18                                 clc
70be: 69 06                              adc     #$06
70c0: a6 50        L70C0                 ldx     $50
70c2: f0 0c                              beq     L70D0
70c4: 18                                 clc
70c5: 65 97                              adc     $97
70c7: 48                                 pha
70c8: a9 02                              lda     #$02
70ca: 38                                 sec
70cb: e5 51                              sbc     $51
70cd: 85 51                              sta     $51
70cf: 68                                 pla
70d0: aa           L70D0                 tax
70d1: 20 6d 75                           jsr     L756D
70d4: a5 50                              lda     $50
70d6: d0 12                              bne     L70EA
70d8: 18                                 clc
70d9: a5 6c                              lda     npcX
70db: 65 6f                              adc     npcFacing               ;move one tile in direction they are facing
70dd: 85 6c                              sta     npcX
70df: a5 a7                              lda     $a7
70e1: 20 7e 72                           jsr     tile_to_f0_f1_f2
70e4: a5 f1                              lda     xSolid
70e6: f0 02                              beq     L70EA
70e8: c6 6d                              dec     npcY
70ea: a9 01        L70EA                 lda     #$01
70ec: 85 b3                              sta     $b3
70ee: 60                                 rts

70ef: 08           L70EF                 .dd1    $08
70f0: 0c                                 .dd1    $0c
70f1: 06           L70F1                 .dd1    $06
70f2: 0a                                 .dd1    $0a
70f3: 00           L70F3                 .dd1    $00
70f4: 02                                 .dd1    $02

                   NOTE: Might control NPC behavior (stopping) near player.
70f5: a6 6c        L70F5                 ldx     npcX
70f7: e4 19                              cpx     playerX
70f9: f0 10                              beq     L710B
70fb: e8                                 inx
70fc: e4 19                              cpx     playerX
70fe: f0 0b                              beq     L710B
7100: ca                                 dex
7101: ca                                 dex
7102: e4 19                              cpx     playerX
7104: f0 05                              beq     L710B
7106: ca                                 dex
7107: e4 19                              cpx     playerX
7109: d0 1a                              bne     L7125
710b: a6 6d        L710B                 ldx     npcY
710d: e4 1a                              cpx     playerY
710f: f0 0b                              beq     L711C
7111: e8                                 inx
7112: e4 1a                              cpx     playerY
7114: f0 06                              beq     L711C
7116: ca                                 dex
7117: ca                                 dex
7118: e4 1a                              cpx     playerY
711a: d0 09                              bne     L7125
711c: ad f2 02     L711C                 lda     RWTSBUF_npctype
711f: 85 34                              sta     temp34_npctype
7121: a9 00                              lda     #$00
7123: 85 87                              sta     TICKING
7125: 4c 4c 70     L7125                 jmp     L704C

                   ; Checks and handles collision with brambles at foot level. Ignored when flying.
7128: 20 2a 72     check_brambles        jsr     get_adjacent_tiles
712b: a5 e0                              lda     tileFeet
712d: c9 1c                              cmp     #tile_brambles
712f: f0 01                              beq     @check_brambles
7131: 60           @rts                  rts

7132: a5 92        @check_brambles       lda     FALLCNT
7134: c9 02                              cmp     #$02
7136: b0 f9                              bcs     @rts
7138: a5 94                              lda     flyFlag                 ;ignore brambles if flying. only contact on ground
713a: d0 f5                              bne     @rts
713c: a5 9c                              lda     playerXold
713e: 85 19                              sta     playerX
7140: a5 9d                              lda     playerYold
7142: 85 1a                              sta     playerY
7144: 20 7d 71                           jsr     reset_after_hurt
7147: 4c 72 71                           jmp     @ouch

                   ; Checks and handles collision with wall tiles (locked gate, house wall) at foot
                   ; and shoulder level.
714a: a5 e0        check_walls           lda     tileFeet
714c: 20 8a 71                           jsr     @is_collision_tile
714f: f0 0c                              beq     @collide
7151: a5 9a                              lda     crawlFlag
7153: f0 01                              beq     @chk_collide_shoulder   ;if crawling, don't test collision at shoulder height
7155: 60           @rts                  rts

7156: a5 e8        @chk_collide_shoulder lda     tileShoulder
7158: 20 8a 71                           jsr     @is_collision_tile
715b: d0 f8                              bne     @rts
715d: a5 9c        @collide              lda     playerXold
715f: 85 19                              sta     playerX
7161: a5 9d                              lda     playerYold
7163: 85 1a                              sta     playerY
7165: a9 00                              lda     #$00
7167: 85 8c                              sta     jumpFlag
7169: 85 94                              sta     flyFlag
716b: 20 d6 72                           jsr     stop_frame_ground
716e: a9 01                              lda     #$01
7170: 85 a0                              sta     $a0
7172: a9 0a        @ouch                 lda     #$0a                    ;full stop, max fall, get hurt
7174: 85 92                              sta     FALLCNT
7176: a9 00                              lda     #$00
7178: 85 af                              sta     XMOVFLG
717a: 85 b0                              sta     YMOVFLG
717c: 60                                 rts

717d: a9 00        reset_after_hurt      lda     #$00
717f: 85 8c                              sta     jumpFlag
7181: 85 94                              sta     flyFlag
7183: 85 96                              sta     takingStep
7185: 85 99                              sta     runFlag
7187: 85 9a                              sta     crawlFlag
7189: 60                                 rts

                   ; Sets Z flag if tile in A is $07,$08 or $52. These are tiles that cause you to
                   ; get hurt when you contact them.
718a: c9 07        @is_collision_tile    cmp     #$07                    ;unknown; probably a wall
718c: f0 08                              beq     @rts
718e: c9 08                              cmp     #$08                    ;a locked gate (Temple Grund entrance)
7190: f0 04                              beq     @rts                    ;   or impassable wall (hostage house)
7192: c9 52                              cmp     #$52                    ;a checkerboard pattern (internal house wall)
7194: f0 00                              beq     @rts
7196: 60           @rts                  rts

                   ; Translate BA..BC (the 3 door tiles, in A) to a door slot number (1..3) and
                   ; store it in doorTransit.
7197: 38           handle_door           sec                             ;A is BA..BC on entry (the door tile)
7198: e9 b9                              sbc     #$b9                    ;subtract B9
719a: 85 9e                              sta     doorTransit             ;result is 1..3
719c: a9 00                              lda     #$00                    ;pause during transit
719e: 85 87                              sta     TICKING
71a0: a2 0a                              ldx     #$0a                    ;use 10 food during a door transit
                   ; (Multiple entry.) X is the amount to decrease food/rest by ($0A, $01, ...).
                   ; Subtract this from the food/rest timer, unless we are in the Neshom realm,
                   ; where time does not pass.
                   ; 
                   ; If the food/rest timer falls below zero, decrease food and rest by 1 each. The
                   ; timer ranges from 00..FF so no post-adjustment is needed.
71a2: a5 35        handle_food_rest      lda     doorNeshom              ;in neshom's house or realm?
71a4: d0 2a                              bne     @rts                    ;yep, return; never starve
71a6: 86 b7                              stx     tempB7                  ;temp used only for subtracting X from A
71a8: a5 b8                              lda     foodRestTimer
71aa: 38                                 sec
71ab: e5 b7                              sbc     tempB7
71ad: 85 b8                              sta     foodRestTimer
71af: 90 01                              bcc     @dec_food
71b1: 60                                 rts

71b2: c6 24        @dec_food             dec     levelFood
71b4: 10 0c                              bpl     @dec_rest
71b6: e6 24                              inc     levelFood
71b8: e6 24                              inc     levelFood
71ba: a9 01                              lda     #STARVED_food           ;starved of food
71bc: 85 3c                              sta     STARVED
71be: a9 00                              lda     #$00                    ;pause
71c0: 85 87                              sta     TICKING
71c2: c6 25        @dec_rest             dec     levelRest
71c4: 10 0a                              bpl     @rts
71c6: e6 25                              inc     levelRest
71c8: a9 02                              lda     #STARVED_rest           ;starved of rest
71ca: 85 3c                              sta     STARVED
71cc: a9 00                              lda     #$00                    ;pause
71ce: 85 87                              sta     TICKING
71d0: 60           @rts                  rts

                   NOTE: Suspect this is checking if we are in front of a certain type of door in
                   the caves, and if so, sets the flag for the spirit bell to ring.
71d1: a5 e0        check_cave_door?      lda     tileFeet
71d3: c9 bb                              cmp     #$bb                    ;a door tile
71d5: d0 1a                              bne     @rts
71d7: a5 1c                              lda     MAPHALF
71d9: f0 16                              beq     @rts
71db: a5 1b                              lda     MAPPOS
71dd: c9 80                              cmp     #$80
71df: 90 10                              bcc     @rts
71e1: ad 00 b5                           lda     itemState               ;might be checking spirit bell in inventory
71e4: 2c bd 1d                           bit     GAME1_BITTAB5
71e7: f0 08                              beq     @rts
71e9: a9 00                              lda     #$00
71eb: 85 87                              sta     TICKING
71ed: a9 01                              lda     #$01
71ef: 85 bc                              sta     zpBC_bellrings          ;spirit bell rings?
71f1: 60           @rts                  rts

71f2: 20 21 60     maybe_tear_shuba      jsr     GAME2_read_0900         ;pseudo-randomness?
71f5: c9 f0                              cmp     #$f0                    ;essentially, a 1 in 16 chance to tear
71f7: 90 0d                              bcc     @rts
71f9: a2 13                              ldx     #19                     ;20 shuba inventory slots
71fb: bd 58 b5     @loop                 lda     inv_shuba,x
71fe: 2c bd 1d                           bit     GAME1_BITTAB5           ;check if slot is occupied by a shuba
7201: d0 04                              bne     @shuba_has_torn
7203: ca                                 dex
7204: 10 f5                              bpl     @loop
7206: 60           @rts                  rts

7207: a9 00        @shuba_has_torn       lda     #$00                    ;clear inventory slot
7209: 9d 58 b5                           sta     inv_shuba,x
720c: a0 07                              ldy     #$07
720e: 20 12 77                           jsr     GAME2_lose_weight
7211: 20 0c 60                           jsr     GAME2_PRNTSTR
7214: 01                                 .dd1    $01
7215: d9 cf d5 d2+                       .str    ↑“YOUR SHUBA HAS TORN”  ;ow
7228: ff                                 .dd1    $ff
7229: 60                                 rts

                   ; Populates $E0..EA with tiles near the player's feet. See notes at @xoffset.
722a: a9 0a        get_adjacent_tiles    lda     #$0a
722c: 85 82                              sta     temp82
722e: a6 82        @loop                 ldx     temp82
7230: a5 1a                              lda     playerY
7232: 18                                 clc
7233: 7d 55 72                           adc     @yoffset,x
7236: a8                                 tay
7237: a5 19                              lda     playerX
7239: 18                                 clc
723a: 7d 4a 72                           adc     @xoffset,x
723d: aa                                 tax
723e: 20 60 72                           jsr     get_tile_at_xy
7241: a6 82                              ldx     temp82
7243: 95 e0                              sta     tileFeet,x
7245: c6 82                              dec     temp82
7247: 10 e5                              bpl     @loop                   ;loop 11 times
7249: 60                                 rts

                   ; the 3 tiles at the player's feet (center, left, right)
724a: 00           @xoffset              .dd1    $00                     ;E0:  0, 0
724b: ff                                 .dd1    $ff                     ;E1: -1, 0
724c: 01                                 .dd1    $01                     ;E2:  1, 0
                   ; the 3 tiles under the player (center, left, right)
724d: 00                                 .dd1    $00                     ;E3:  0, 1
724e: ff                                 .dd1    $ff                     ;E4: -1, 1
724f: 01                                 .dd1    $01                     ;E5:  1, 1
                   ; the 3 tiles at knee (-1), arm (-2) and shoulder (-3) height
7250: 00                                 .dd1    $00                     ;E6:  0,-1
7251: 00                                 .dd1    $00                     ;E7:  0,-2
7252: 00                                 .dd1    $00                     ;E8:  0,-3
                   ; the 2 tiles (left, right) at -2 (arm level), which is the height of items on
                   ; tables and shelves for taking
7253: ff                                 .dd1    $ff                     ;E9: -1,-2
7254: 01                                 .dd1    $01                     ;EA:  1,-2
7255: 00           @yoffset              .dd1    $00
7256: 00                                 .dd1    $00
7257: 00                                 .dd1    $00
7258: 01                                 .dd1    $01
7259: 01                                 .dd1    $01
725a: 01                                 .dd1    $01
725b: ff                                 .dd1    $ff
725c: fe                                 .dd1    $fe
725d: fd                                 .dd1    $fd
725e: fe                                 .dd1    $fe
725f: fe                                 .dd1    $fe

                   ; Input: X=col, Y=line. Output: A=tile at X,Y. A=0 if X=-1, X=40, or Y<0.
7260: e0 ff        get_tile_at_xy        cpx     #$ff
7262: f0 17                              beq     @tile0
7264: e0 28                              cpx     #$28
7266: f0 13                              beq     @tile0
7268: c0 00                              cpy     #$00
726a: 30 0f                              bmi     @tile0
726c: b9 a0 1d                           lda     GAME1_textlo,y
726f: 85 89                              sta     temp89                  ;$89 {addr/2} is temp
7271: b9 80 1d                           lda     GAME1_texthi,y
7274: 85 8a                              sta     temp89+1
7276: 8a                                 txa
7277: a8                                 tay
7278: b1 89                              lda     (temp89),y
727a: 60                                 rts

727b: a9 00        @tile0                lda     #$00
727d: 60                                 rts

                   ; Maps a tile in A to 3 output values in $F0, $F1, $F2.
                   ; 
                   ; On return ($F0,$F1,$F2) is (0,0,0) for all A except:
                   ;   (1,1,0) when A = 01..06, 19..1b (bush), 75, df
                   ;   (1,0,1) when A = b4..b6 (ladder) and b7..b9 (vine)
                   ;   (1,1,0) when A = e0 and $9A != 0
                   ; 
                   ; It's likely these denote permeability in different directions, with $F2=1 as
                   ; climbable. The (1,1,0) tiles appear to be solid.
727e: 48           tile_to_f0_f1_f2      pha
727f: a2 02                              ldx     #$02                    ;Store 0 in $F0..$F2
7281: a9 00                              lda     #$00
7283: 95 f0        @loop                 sta     ySolid,x
7285: ca                                 dex
7286: 10 fb                              bpl     @loop
7288: 68                                 pla
7289: c9 00                              cmp     #$00                    ;(0,0,0) -- $00
728b: f0 48                              beq     @rts
728d: c9 07                              cmp     #$07
728f: b0 06                              bcs     @p1
7291: e6 f0                              inc     ySolid                  ;(1,1,0) -- $01..06
7293: e6 f1                              inc     xSolid
7295: d0 3e                              bne     @rts
7297: c9 19        @p1                   cmp     #$19                    ;(0,0,0) -- $07..18
7299: 90 3a                              bcc     @rts
729b: c9 1c                              cmp     #$1c
729d: b0 06                              bcs     @p2
729f: e6 f0                              inc     ySolid                  ;(1,1,0) -- $19..1b
72a1: e6 f1                              inc     xSolid
72a3: d0 30                              bne     @rts                    ;always
72a5: c9 75        @p2                   cmp     #$75
72a7: d0 06                              bne     @p3
72a9: e6 f0                              inc     ySolid                  ;(1,1,0) -- $75
72ab: e6 f1                              inc     xSolid
72ad: d0 26                              bne     @rts
72af: c9 b4        @p3                   cmp     #$b4
72b1: 90 22                              bcc     @rts                    ;(0,0,0) -- $1c..74,76..b3
72b3: c9 ba                              cmp     #$ba
72b5: b0 06                              bcs     @p4
72b7: e6 f0                              inc     ySolid                  ;(1,0,1) -- $b4..b9
72b9: e6 f2                              inc     climbable
72bb: d0 18                              bne     @rts
72bd: c9 e0        @p4                   cmp     #$e0
72bf: d0 0a                              bne     @p5
72c1: a5 9a                              lda     crawlFlag
72c3: f0 10                              beq     @rts                    ;(0,0,0) -- $e0 (when $9a == 0)
72c5: e6 f0                              inc     ySolid                  ;(1,1,0) -- $e0 (when $9a == 1)
72c7: e6 f1                              inc     xSolid
72c9: d0 0a                              bne     @rts
72cb: c9 df        @p5                   cmp     #$df
72cd: d0 06                              bne     @rts                    ;(0,0,0) -- $ba..$de,$e1..$ff
72cf: e6 f0                              inc     ySolid                  ;(1,1,0) -- $df
72d1: e6 f1                              inc     xSolid
72d3: d0 00                              bne     @rts
72d5: 60           @rts                  rts

                   ; Sets animation frame to $00/$06 (crawling) or $22/$28 (standing), depending on
                   ; facing direction. Often called in tandem with FACING being updated.
                   ; Essentially, the initial animation frame when you are stopped on the ground.
72d6: a5 9a        stop_frame_ground     lda     crawlFlag
72d8: d0 0a                              bne     @crawling
72da: a2 00                              ldx     #$00
72dc: a5 95                              lda     FACING
72de: 30 0c                              bmi     @cont
72e0: a2 06                              ldx     #$06
72e2: d0 08                              bne     @cont                   ;always

72e4: a2 22        @crawling             ldx     #$22
72e6: a5 95                              lda     FACING
72e8: 30 02                              bmi     @cont                   ;if facing left
72ea: a2 28                              ldx     #$28
72ec: 86 a3        @cont                 stx     animFrame
72ee: e8                                 inx
72ef: 86 a4                              stx     animFrame_unused
72f1: a9 01                              lda     #$01
72f3: 85 b2                              sta     erasePlayer
72f5: 60                                 rts

72f6: 20 06 60     win_game              jsr     GAME2_cleartext
72f9: 20 0c 60                           jsr     GAME2_PRNTSTR
72fc: 01                                 .dd1    $01
72fd: c9 a0 c1 cd+                       .str    ↑“I AM RAAMO, THE SPIRIT GIFTED.”
731b: ff                                 .dd1    $ff
731c: 20 0c 60                           jsr     GAME2_PRNTSTR
731f: 29                                 .dd1    $29
7320: d9 cf d5 a0+                       .str    ↑“YOU HAVE SAVED MY LIFE AND FULFILLED    THE PROPHESY.  THE QU”
                                          +      “EST IS OVER AND    GREEN-SKY IS SAVED.”
7383: ff                                 .dd1    $ff
7384: a9 00                              lda     #$00
7386: 20 00 b6                           jsr     SCRN_play_melody
                   ; This weird test (which is always 0 so never loops) only occurs after a melody
                   ; is played, and only on win or lose. It might be a vestige of another platform,
                   ; as it would enter an infinite loop unless there is an interrupt handler
                   ; (music?) that updates this value.
7389: a5 83        @loop                 lda     waitMelody
738b: d0 fc                              bne     @loop
738d: a2 ff                              ldx     #$ff
738f: 20 12 60                           jsr     GAME2_delayXtimes256
7392: 20 06 60                           jsr     GAME2_cleartext
7395: 20 0c 60                           jsr     GAME2_PRNTSTR
7398: 01                                 .dd1    $01
7399: d9 cf d5 a0+                       .str    ↑“YOU HAVE FINISHED THE QUEST IN    DAYS. YOU ARE A”
73ca: ff                                 .dd1    $ff
73cb: a6 22                              ldx     dayNum
73cd: a0 00                              ldy     #$00
73cf: 20 18 77                           jsr     GAME2_num_to_str
73d2: a9 20                              lda     #$20
73d4: 85 64                              sta     HTAB
73d6: a5 fc                              lda     digits+3
73d8: 20 0f 60                           jsr     GAME2_printchar
73db: a9 21                              lda     #$21
73dd: 85 64                              sta     HTAB
73df: a5 fd                              lda     digits+4
73e1: 20 0f 60                           jsr     GAME2_printchar
73e4: a5 22                              lda     dayNum
73e6: c9 1e                              cmp     #30                     ;>= 30 days, gifted quester
73e8: 90 17                              bcc     @highly_gifted
73ea: 20 0c 60                           jsr     GAME2_PRNTSTR
73ed: 33                                 .dd1    $33
73ee: c7 c9 c6 d4+                       .str    ↑“GIFTED QUESTER.”
73fd: ff                                 .dd1    $ff
73fe: 4c 37 74                           jmp     @melody

7401: c9 0f        @highly_gifted        cmp     #15                     ;>= 15 days, highly gifted quester
7403: 90 1e                              bcc     @master_quester
7405: 20 0c 60                           jsr     GAME2_PRNTSTR
7408: 33                                 .dd1    $33
7409: c8 c9 c7 c8+                       .str    ↑“HIGHLY GIFTED QUESTER.”
741f: ff                                 .dd1    $ff
7420: 4c 37 74                           jmp     @melody

7423: 20 0c 60     @master_quester       jsr     GAME2_PRNTSTR           ;< 15 days, master quester
7426: 33                                 .dd1    $33
7427: cd c1 d3 d4+                       .str    ↑“MASTER QUESTER.”
7436: ff                                 .dd1    $ff
7437: a9 02        @melody               lda     #$02
7439: 20 00 b6                           jsr     SCRN_play_melody
743c: a5 83        @loop                 lda     waitMelody              ;again the weird loop that never loops
743e: d0 fc                              bne     @loop
7440: 20 c3 75     @wait_for_input       jsr     get_ongoing_input
7443: f0 fb                              beq     @wait_for_input
7445: a9 00                              lda     #$00
7447: 85 ba                              sta     $ba
7449: 4c 0c 77                           jmp     GAME2_await_button_up

744c: 20 20 75     redraw_player         jsr     erase_old_player
744f: a5 19        draw_player           lda     playerX                 ;Save old player X,Y for later erase
7451: 85 9c                              sta     playerXold
7453: a5 1a                              lda     playerY
7455: 85 9d                              sta     playerYold
                   ; Bit 0 (odd/even) in $A3 is discarded. Bit 1 becomes the high bit in A, and is
                   ; stored in $1d. Bits 7..2 are shifted to 5..0, and 32 added and stored in $1e.
7457: a5 a3                              lda     animFrame
7459: 4a                                 lsr     A
745a: 4a                                 lsr     A
745b: 85 82                              sta     temp82
745d: a9 00                              lda     #$00
745f: 6a                                 ror     A                       ;Bit 7 is carry (bit 1 from $A3); Bit 6-0 is 0
7460: 18                                 clc
7461: 69 00                              adc     #$00                    ;cannot understand this. clc+adc #$00 should be nop
7463: 85 1d                              sta     zp1d
7465: a5 82                              lda     temp82                  ;$a3/4
7467: 69 20                              adc     #$20                    ;carry should always be 0
7469: 85 1e                              sta     zp1d+1
746b: a5 19                              lda     playerX
746d: 85 05                              sta     TXTCOL
746f: c6 05                              dec     TXTCOL
7471: a5 1a                              lda     playerY                 ;playerY * 8 hires lines
7473: 0a           L7473                 asl     A
7474: 0a                                 asl     A
7475: 0a                                 asl     A
7476: 38                                 sec
7477: e9 22                              sbc     #$22
7479: 85 06                              sta     TXTROW
747b: a9 ff                              lda     #$ff
747d: 85 1f                              sta     zp1f
747f: a0 00                              ldy     #$00
7481: a5 05        L7481                 lda     TXTCOL
7483: 85 8b                              sta     temp8b
7485: a5 06                              lda     TXTROW
7487: 4a                                 lsr     A
7488: 4a                                 lsr     A
7489: 4a                                 lsr     A
748a: aa                                 tax
748b: bd 40 1d                           lda     GAME1_hireslo,x
748e: 85 0f                              sta     $0f
7490: bd 60 1d                           lda     GAME1_hireshi,x
7493: 85 10                              sta     $10
7495: a5 06                              lda     TXTROW
7497: 29 07                              and     #$07
7499: 0a                                 asl     A
749a: 0a                                 asl     A
749b: 18                                 clc
749c: 65 10                              adc     $10
749e: 18                                 clc
749f: 69 20                              adc     #$20
74a1: 85 10                              sta     $10
74a3: a5 05                              lda     TXTCOL
74a5: 10 0e                              bpl     L74B5
74a7: a5 0f                              lda     $0f
74a9: 38                                 sec
74aa: e9 01                              sbc     #$01
74ac: 85 0f                              sta     $0f
74ae: b0 12                              bcs     L74C2
74b0: c6 10                              dec     $10
74b2: 4c c2 74                           jmp     L74C2

74b5: a5 0f        L74B5                 lda     $0f
74b7: 18                                 clc
74b8: 65 05                              adc     TXTCOL
74ba: 85 0f                              sta     $0f
74bc: a9 00                              lda     #$00
74be: 65 10                              adc     $10
74c0: 85 10                              sta     $10
74c2: a9 03        L74C2                 lda     #$03
74c4: 85 07                              sta     $07
74c6: a2 00                              ldx     #$00
74c8: a5 8b                              lda     temp8b
74ca: 30 26                              bmi     L74F2
74cc: c9 28                              cmp     #$28
74ce: b0 22                              bcs     L74F2
74d0: a5 06                              lda     TXTROW
74d2: c9 a0                              cmp     #$a0
74d4: b0 1c                              bcs     L74F2
74d6: b1 1d                              lda     (zp1d),y
74d8: 4a                                 lsr     A
74d9: 4c ec 74                           jmp     L74EC

74dc: a5 8b        @line                 lda     temp8b
74de: 30 12                              bmi     L74F2
74e0: c9 28                              cmp     #$28
74e2: b0 0e                              bcs     L74F2
74e4: a5 06                              lda     TXTROW
74e6: c9 a0                              cmp     #$a0
74e8: b0 08                              bcs     L74F2
74ea: b1 1d                              lda     (zp1d),y
74ec: 29 7f        L74EC                 and     #$7f
74ee: 01 0f                              ora     ($0f,x)                 ;OR with hires screen
74f0: 81 0f                              sta     ($0f,x)                 ;note x=0; ora/sta ($0f)
74f2: c8           L74F2                 iny                             ;next zp1d index
74f3: e6 8b                              inc     temp8b
74f5: e6 0f                              inc     $0f                     ;16-bit inc $0f ptr
74f7: d0 02                              bne     @no16
74f9: e6 10                              inc     $10
74fb: c6 07        @no16                 dec     $07
74fd: d0 dd                              bne     @line                   ;loop 3 times total
74ff: e6 06                              inc     TXTROW
7501: 98                                 tya
7502: c9 3f                              cmp     #$3f                    ;processed 64 yet?
7504: f0 03                              beq     L7509
7506: 4c 81 74                           jmp     L7481

                   ; Increase $1d by 64 and continue. Do this twice.
7509: e6 1f        L7509                 inc     zp1f                    ;zp1f starts at #$FF
750b: d0 12                              bne     @rts                    ;so this loops twice
750d: a9 40                              lda     #$40                    ;16-bit add of 64 to $1d/$1e
750f: 18                                 clc
7510: 65 1d                              adc     zp1d
7512: 85 1d                              sta     zp1d
7514: a9 00                              lda     #$00
7516: 65 1e                              adc     zp1d+1
7518: 85 1e                              sta     zp1d+1
751a: a0 00                              ldy     #$00                    ;reset zp1d index
751c: 4c 81 74                           jmp     L7481

751f: 60           @rts                  rts

                   ; Redraw a 3x6 tile area at the old player position ($9c-1,$9d-5), copying tiles
                   ; from the text screen. This erases the old player.
7520: a5 9c        erase_old_player      lda     playerXold
7522: 85 05                              sta     TXTCOL
7524: c6 05                              dec     TXTCOL
7526: a5 9d                              lda     playerYold
7528: 38           L7528                 sec
7529: e9 05                              sbc     #$05                    ;probably related to the 6 tiles printed
752b: 85 06                              sta     TXTROW
752d: a9 00                              lda     #$00
752f: a9 06                              lda     #$06
7531: 85 8b                              sta     temp8b
7533: a5 06        @row                  lda     TXTROW
7535: 30 24                              bmi     @nextrow                ;skip to next row if row < 0
7537: c9 14                              cmp     #20
7539: b0 20                              bcs     @nextrow                ;or if row > 19 (why not just exit)
753b: a5 05                              lda     TXTCOL
753d: 48                                 pha
753e: a9 03                              lda     #$03
7540: 85 82                              sta     temp82
7542: a6 05        @col                  ldx     TXTCOL
7544: 30 0c                              bmi     @nextcol
7546: e0 28                              cpx     #$28
7548: b0 08                              bcs     @nextcol
754a: a4 06                              ldy     TXTROW
754c: 20 60 72                           jsr     get_tile_at_xy
754f: 20 03 60                           jsr     GAME2_drawtile          ;draw tile in A
7552: e6 05        @nextcol              inc     TXTCOL
7554: c6 82                              dec     temp82
7556: d0 ea                              bne     @col                    ;3 times
7558: 68                                 pla
7559: 85 05                              sta     TXTCOL
755b: e6 06        @nextrow              inc     TXTROW
755d: c6 8b                              dec     temp8b
755f: d0 d2                              bne     @row                    ;6 times
7561: 60                                 rts

7562: a2 00        L7562                 ldx     #$00
7564: a5 6f                              lda     npcFacing
7566: 30 02                              bmi     L756A
7568: a2 06                              ldx     #$06
756a: 4c 6d 75     L756A                 jmp     L756D

756d: 86 ad        L756D                 stx     $ad
756f: e8                                 inx
7570: 86 ae                              stx     $ae
7572: 60                                 rts

7573: 20 a6 75 4c+                       .junk   6                       ;unused code

7579: a5 6b        draw_npc?             lda     zp6b_npcHere
757b: d0 01                              bne     L757E
757d: 60                                 rts

757e: a6 ad        L757E                 ldx     $ad
7580: bd 9a 75                           lda     L759A,x
7583: 85 1d                              sta     zp1d
7585: e8                                 inx
7586: bd 9a 75                           lda     L759A,x
7589: 85 1e                              sta     zp1d+1
758b: a5 6c                              lda     npcX
758d: 85 ab                              sta     $ab
758f: 85 05                              sta     TXTCOL
7591: c6 05                              dec     TXTCOL
7593: a5 6d                              lda     npcY
7595: 85 ac                              sta     $ac
7597: 4c 73 74                           jmp     L7473

759a: 00           L759A                 .dd1    $00
759b: af                                 .dd1    $af
759c: 80                                 .dd1    $80
759d: af                                 .dd1    $af
759e: 00                                 .dd1    $00
759f: b0                                 .dd1    $b0
75a0: 80                                 .dd1    $80
75a1: b0                                 .dd1    $b0
75a2: 00                                 .dd1    $00
75a3: b1                                 .dd1    $b1
75a4: 80                                 .dd1    $80
75a5: b1                                 .dd1    $b1

75a6: a5 ab        L75A6                 lda     $ab
75a8: 85 05                              sta     TXTCOL
75aa: c6 05                              dec     TXTCOL
75ac: a5 ac                              lda     $ac
75ae: 4c 28 75                           jmp     L7528

                   NOTE: Wraps a call to input code at $6b09 ($75c3). It ensures any latched
                   keyboard motion is stopped, gets input, and ignores any returned button press if
                   we are moving upward (the keyboard handler adds a virtual button press for UP).
                   
                   This is the exact behavior you'd want in a menu.
                   
                   Returns 0 or 1 (button press status) in A.
75b1: a9 00        get_menu_input        lda     #$00                    ;clear the kbd movement latches
75b3: 85 b0                              sta     YMOVFLG
75b5: 85 af                              sta     XMOVFLG
75b7: 20 c3 75                           jsr     get_ongoing_input
75ba: a6 b0                              ldx     YMOVFLG
75bc: 10 02                              bpl     @ret                    ;branch if not moving up
75be: a9 00                              lda     #$00                    ;or clear button press if we are moving up
                   ; ORA #0 (AND #$FF, EOR #0) will make the N and Z flags reflect the value in A.
                   ; This is used to ensure the Z flag still reflects A (return value from $75C3)
                   ; after the LDX, so callers can BEQ/BNE.
75c0: 09 00        @ret                  ora     #$00                    ;update N and Z from A, even when LDA skipped
75c2: 60                                 rts

                   NOTE: Input code called via $6b09 vector or directly. Vector $6b29 ($75b1) also
                   calls this as its main action, but with a bit of wrapper code. This code
                   respects any latched keyboard movement.
                   
                   This code behaves in 1 of 2 ways after its preamble. If DEMOFLG is 0, it handles
                   keyboard/joystick input. If 1, it calls $9600, which calls back into this
                   handler in non-demo mode and does a bunch of processing, then we update
                   XDIR/YDIR/MOVING/BUTTON based on its return value, just as if we were handling
                   input.
                   
                   Amusingly, if you set $C4 to 0 while the sample quest or intro screen is
                   playing, you can take over.
75c3: a9 00        get_ongoing_input     lda     #$00                    ;from $6b09 or 
75c5: 85 85                              sta     XDIR
75c7: 85 86                              sta     YDIR
75c9: 85 a2                              sta     MOVING
75cb: 85 84                              sta     VIRTBTN
75cd: 20 2e 6e                           jsr     is_climbing
75d0: b0 04                              bcs     L75D6
75d2: a9 00                              lda     #$00
75d4: 85 b0                              sta     YMOVFLG
75d6: a5 92        L75D6                 lda     FALLCNT
75d8: c9 01                              cmp     #$01
75da: 10 04                              bpl     @falling                ;branch when falling, it seems
75dc: a5 94                              lda     flyFlag
75de: f0 04                              beq     L75E4
75e0: a9 00        @falling              lda     #$00                    ;cancel X movement when falling
75e2: 85 af                              sta     XMOVFLG
75e4: a5 c4        L75E4                 lda     DEMOFLG                 ;If not in demo mode,
75e6: f0 32                              beq     handle_kbd_or_joy       ;handle kbd/joy input and return to caller
75e8: 20 00 96                           jsr     SCRN_demo_handler       ;otherwise get demo movement for this frame in A
75eb: 2c bb 1d                           bit     GAME1_BITTAB3           ;test bit 3 of A
75ee: d0 04                              bne     @test_left
75f0: e6 85                              inc     XDIR                    ;moving right
75f2: e6 a2                              inc     MOVING                  ;we moved
75f4: 2c ba 1d     @test_left            bit     GAME1_BITTAB2           ;test bit 2 of A
75f7: d0 04                              bne     @test_down
75f9: c6 85                              dec     XDIR                    ;moving left
75fb: e6 a2                              inc     MOVING
75fd: 2c b9 1d     @test_down            bit     GAME1_BITTAB1           ;test bit 1 of A
7600: d0 04                              bne     @test_up
7602: e6 86                              inc     YDIR
7604: e6 a2                              inc     MOVING
7606: 2c b8 1d     @test_up              bit     GAME1_BITTAB0           ;test bit 0 of A
7609: d0 04                              bne     @test_button?
760b: c6 86                              dec     YDIR
760d: e6 a2                              inc     MOVING
760f: 2c bc 1d     @test_button?         bit     GAME1_BITTAB4           ;test bit 4 of A -- !button
7612: d0 03                              bne     @ret00                  ;set, return 0
7614: a9 01                              lda     #$01                    ;clear, return 1
7616: 60                                 rts

7617: a9 00        @ret00                lda     #$00
7619: 60                                 rts

761a: a5 b1        handle_kbd_or_joy     lda     JOYFLG
761c: f0 03                              beq     handle_ijkm_space
761e: 4c ac 76                           jmp     handle_joystick

                   ********************************************************************************
                   * Handle cursor/character motion. Supports both IJKM and RDFC for up-left-     *
                   * right-down, along with spacebar for execute/jump. The keyboard handler       *
                   * translates its inputs into the equivalent joystick actions (horiz/vert       *
                   * movement and button presses), and callers just handle joystick actions. It   *
                   * keeps some extra state since keys don't need to be held down to move.        *
                   *                                                                              *
                   * $84 (VIRTBTN) is a temporary used only in this handler. It represents a      *
                   * virtual joystick button press; this is returned in A to match the joystick   *
                   * API. For example, pressing UP (I) will return a virtual button press to the  *
                   * caller, because KBD UP enters a door, just like JOY BTN. As another example, *
                   * a double press of KBD LEFT/RIGHT will trigger a virtual button press because *
                   * this will switch to run mode, just like JOY BTN + LEFT/RIGHT. And KBD SPACE  *
                   * simulates JOY BTN + DOWN, which brings up the action menu.                   *
                   *                                                                              *
                   * $AF/$B0 are X/Y movement latches (-1, 0, +1), set on initial keypress and    *
                   * maintained until you hit something, press another movement key, etc.         *
                   *                                                                              *
                   * On return, XDIR and YDIR and MOVING are set as their joystick equivalents,   *
                   * along with A as the virtual button press.                                    *
                   ********************************************************************************
7621: 20 09 b6     handle_ijkm_space     jsr     SCRN_chkkey
7624: f0 70                              beq     @finish
7626: a5 02                              lda     LASTKEY
7628: c9 c6                              cmp     #‘F’ | $80
762a: f0 04                              beq     @right
762c: c9 cb                              cmp     #‘K’ | $80
762e: d0 0d                              bne     @chk_left
7630: e6 af        @right                inc     XMOVFLG
7632: a5 af                              lda     XMOVFLG
7634: c9 02                              cmp     #$02                    ;was x motion previously 1?
7636: d0 19                              bne     @move_horiz             ;no, move right
7638: c6 af                              dec     XMOVFLG                 ;yes, double press; set back to 1
763a: 4c 4f 76                           jmp     @run                    ;and start running

763d: c9 c4        @chk_left             cmp     #‘D’ | $80
763f: f0 04                              beq     @left
7641: c9 ca                              cmp     #‘J’ | $80
7643: d0 20                              bne     @chk_up
7645: c6 af        @left                 dec     XMOVFLG
7647: a5 af                              lda     XMOVFLG
7649: c9 fe                              cmp     #$fe                    ;was this previously -1?
764b: d0 04                              bne     @move_horiz             ;nope, we've just started to move left
764d: e6 af                              inc     XMOVFLG                 ;yes, double press; set back to -1
764f: e6 84        @run                  inc     VIRTBTN                 ;...and press button (to run)
7651: a9 00        @move_horiz           lda     #$00
7653: 85 b0                              sta     YMOVFLG                 ;halt vertical motion
7655: 20 2e 6e                           jsr     is_climbing
7658: b0 06                              bcs     L7660
765a: a5 92                              lda     FALLCNT                 ;might be, how many tiles we have fallen
765c: c9 03                              cmp     #$03                    ;because we can't fly until we fall a bit
765e: 30 36                              bmi     @finish
                   ; So far I can get here if we are falling and press right, or if we are on a
                   ; ladder and press right. VIRTBTN appears to be zero on entry.
7660: e6 84        L7660                 inc     VIRTBTN
7662: 4c 96 76                           jmp     @finish

7665: c9 d2        @chk_up               cmp     #‘R’ | $80
7667: f0 04                              beq     @up
7669: c9 c9                              cmp     #‘I’ | $80
766b: d0 0a                              bne     @chk_down
766d: a5 b0        @up                   lda     YMOVFLG
766f: 30 21                              bmi     @haltx                  ;if already moving up, stop x motion and return
7671: e6 84                              inc     VIRTBTN                 ;otherwise, press button (as if to enter door)
7673: c6 b0                              dec     YMOVFLG                 ;and also start moving up
7675: 30 1b                              bmi     @haltx
7677: c9 c3        @chk_down             cmp     #‘C’ | $80
7679: f0 04                              beq     @down
767b: c9 cd                              cmp     #‘M’ | $80
767d: d0 0b                              bne     @chk_space
767f: a5 b0        @down                 lda     YMOVFLG
7681: c9 01                              cmp     #$01                    ;were we already moving down?
7683: f0 0d                              beq     @haltx                  ;yes, just stop x motion and return
7685: e6 b0                              inc     YMOVFLG                 ;no, start moving down
7687: 4c 92 76                           jmp     @haltx                  ;stop x motion (and return)

768a: c9 a0        @chk_space            cmp     #‘ ’ | $80
768c: d0 08                              bne     @finish
768e: e6 84                              inc     VIRTBTN                 ;SPACE is JOY BTN + JOY DOWN
7690: e6 86                              inc     YDIR                    ;which will bring up the menu
7692: a9 00        @haltx                lda     #$00                    ;halt horizontal motion
7694: 85 af                              sta     XMOVFLG
7696: a5 af        @finish               lda     XMOVFLG
7698: f0 05                              beq     @no_x_motion
769a: 85 85                              sta     XDIR                    ;we are moving horizontally
769c: 4c a5 76                           jmp     @moving

769f: a5 b0        @no_x_motion          lda     YMOVFLG                 ;only check Y if no X motion, can't move diagonally
76a1: f0 06                              beq     @no_y_motion
76a3: 85 86                              sta     YDIR
76a5: a9 01        @moving               lda     #$01                    ;effectively, MOVING <- XDIR|YDIR
76a7: 85 a2                              sta     MOVING
76a9: a5 84        @no_y_motion          lda     VIRTBTN                 ;return virtual joystick button press in A
76ab: 60                                 rts                             ;end of cursor/character keypress handler

                   ; Joystick handling is less complicated than the keyboard. This subroutine
                   ; updates XDIR (when horizontal joystick movement), YDIR (vertical movement) and
                   ; MOVING (XDIR | YDIR).
                   ; 
                   ; On return, accumulator is 0 for no button currently pressed, or 1 for pressed.
76ac: a2 04        handle_joystick       ldx     #$04
76ae: 20 12 60                           jsr     GAME2_delayXtimes256
76b1: a2 00                              ldx     #$00
76b3: 20 1e fb                           jsr     MON_PREAD
76b6: 98                                 tya
76b7: a2 ff                              ldx     #$ff
76b9: c9 40                              cmp     #$40
76bb: 90 08                              bcc     L76C5
76bd: a2 01                              ldx     #$01
76bf: c9 c0                              cmp     #$c0
76c1: b0 02                              bcs     L76C5
76c3: a2 00                              ldx     #$00
76c5: 86 85        L76C5                 stx     XDIR
76c7: a2 04                              ldx     #$04
76c9: 20 12 60                           jsr     GAME2_delayXtimes256
76cc: a2 01                              ldx     #$01
76ce: 20 1e fb                           jsr     MON_PREAD
76d1: 98                                 tya
76d2: a0 ff                              ldy     #$ff
76d4: c9 40                              cmp     #$40
76d6: 90 08                              bcc     L76E0
76d8: a0 01                              ldy     #$01
76da: c9 c0                              cmp     #$c0
76dc: b0 02                              bcs     L76E0
76de: a0 00                              ldy     #$00
76e0: 84 86        L76E0                 sty     YDIR
76e2: a5 86                              lda     YDIR                    ;moving if XDIR or YDIR is non-zero
76e4: 05 85                              ora     XDIR
76e6: f0 04                              beq     @nomove                 ;stationary, branch
76e8: a9 01                              lda     #$01                    ;we are moving
76ea: 85 a2                              sta     MOVING
76ec: a2 04        @nomove               ldx     #$04
76ee: 20 12 60                           jsr     GAME2_delayXtimes256
76f1: a2 00                              ldx     #$00
76f3: ad 62 c0                           lda     BUTN1                   ;treat either button equally
76f6: 0d 61 c0                           ora     BUTN0
76f9: 10 02                              bpl     L76FD
76fb: a2 01                              ldx     #$01
76fd: 8a           L76FD                 txa                             ;return A=0 if no button press, 1 if press
76fe: 60                                 rts

76ff: 20                                 .dd1    $20

                   ; Vectors! This section deals with menus and actions.
7700: 4c 27 77     GAME2_action_menu     jmp     action_menu

7703: 4c c0 7f     GAME2_slot_to_item    jmp     slot_to_item            ;input slot $00-fe (A), output item 0-14 (Y)

7706: 4c e3 7f     GAME2_message_wait    jmp     message_wait            ;wait for input after a message

7709: 4c 4b 84     L7709                 jmp     time_has_passed

770c: 4c f2 7f     GAME2_await_button_up jmp     await_button_up

770f: 4c a2 7e     GAME2_print_item_desc jmp     print_item_desc

7712: 4c 48 7e     GAME2_lose_weight     jmp     lose_weight

7715: 4c dd 81                           jmp     L81DD

7718: 4c cc 84     GAME2_num_to_str      jmp     num_to_str

771b: 4c 61 84     GAME2_next_tick       jmp     next_tick

771e: 4c fd 79     GAME2_attacked        jmp     attacked

7721: 4c 90 7e     GAME2_txtpos_to_addr  jmp     txtpos_to_addr

7724: 4c 51 7e                           jmp     L7E51

7727: 20 2f 78     action_menu           jsr     display_actions
772a: a9 00                              lda     #$00
772c: 85 71                              sta     MENUCOL                 ;set top left of menu (0,0)
772e: 85 72                              sta     MENUROW
7730: 85 73                              sta     MENUCOL_NEXT            ;next menucol/row, so we can unhighlight old row
7732: 85 74                              sta     MENUROW_NEXT            ;these are really temp vars, only used here
7734: 85 9f                              sta     enterMenu
7736: 20 f6 78                           jsr     highlight_menu_action
7739: 20 f2 7f     action_menu_no_effect jsr     await_button_up         ;jmp here when no effect (RENEW in Neshom)
773c: 20 2a 6b     @check_input          jsr     GAME2_menu_input        ;get input
773f: f0 08                              beq     @check_moving           ;no button, branch
7741: a2 01                              ldx     #$01                    ;button pressed, boop
7743: 20 03 b6                           jsr     SCRN_play_sound
7746: 4c 92 77                           jmp     select_menu_item

                   tmpMoved              .var    $08    {addr/1}         ;did we actually move menu pos?

7749: a5 a2        @check_moving         lda     MOVING                  ;no button, check direction
774b: f0 ef                              beq     @check_input            ;no input, loop
774d: a9 00                              lda     #$00
774f: 85 08                              sta     tmpMoved
7751: 18                                 clc
7752: a5 85                              lda     XDIR                    ;FF (left), 01 (right)
7754: f0 0c                              beq     @check_ymove            ;no attempt to move
7756: 65 73                              adc     MENUCOL_NEXT
7758: 30 08                              bmi     @check_ymove            ;off left edge, don't move
775a: c9 05                              cmp     #$05                    ;off the right edge?
775c: f0 04                              beq     @check_ymove            ;yes, don't move
775e: 85 73                              sta     MENUCOL_NEXT            ;no, set next column
7760: e6 08                              inc     tmpMoved                ;and note that we moved
7762: 18           @check_ymove          clc
7763: a5 86                              lda     YDIR                    ;FF (up), 01 (down)
7765: f0 0c                              beq     @check_moved            ;no attempt to move vertically
7767: 65 74                              adc     MENUROW_NEXT
7769: 30 08                              bmi     @check_moved            ;off top edge, don't move
776b: c9 04                              cmp     #$04                    ;off the bottom?
776d: f0 04                              beq     @check_moved            ;yes, don't move
776f: 85 74                              sta     MENUROW_NEXT            ;no, set next row
7771: e6 08                              inc     tmpMoved                ;and note that we moved
7773: a5 08        @check_moved          lda     tmpMoved
7775: f0 c5                              beq     @check_input            ;no movement, get more input
7777: 20 10 79                           jsr     unhighlight_menu_action ;unhighlight old menu item
777a: a5 73                              lda     MENUCOL_NEXT
777c: 85 71                              sta     MENUCOL                 ;update menu position
777e: a5 74                              lda     MENUROW_NEXT
7780: 85 72                              sta     MENUROW
7782: 20 f6 78                           jsr     highlight_menu_action   ;and highlight new menu item
7785: a2 00                              ldx     #$00
7787: 20 03 b6                           jsr     SCRN_play_sound         ;beep
778a: a2 60                              ldx     #$60
778c: 20 12 60                           jsr     GAME2_delayXtimes256    ;delay repeat
778f: 4c 3c 77                           jmp     @check_input            ;get more input

7792: a5 71        select_menu_item      lda     MENUCOL                 ;col 0, row 0 (PAUSE)
7794: d0 18                              bne     menu_take
7796: a5 72                              lda     MENUROW
7798: d0 03                              bne     menu_speak
779a: 4c 06 60                           jmp     GAME2_cleartext

779d: c9 01        menu_speak            cmp     #$01                    ;row 1
779f: d0 03                              bne     menu_pense
77a1: 4c 0c 9c                           jmp     SCRN_speak

77a4: c9 02        menu_pense            cmp     #$02
77a6: d0 03                              bne     menu_offer
77a8: 4c 0f 9c                           jmp     SCRN_pense

77ab: 4c 18 9c     menu_offer            jmp     SCRN_offer

77ae: c9 01        menu_take             cmp     #$01                    ;col 1
77b0: d0 18                              bne     menu_drop
77b2: a5 72                              lda     MENUROW
77b4: d0 03                              bne     menu_buy
77b6: 4c e6 7b                           jmp     take

77b9: c9 01        menu_buy              cmp     #$01
77bb: d0 03                              bne     menu_use
77bd: 4c 12 9c                           jmp     $9c12

77c0: c9 02        menu_use              cmp     #$02
77c2: d0 03                              bne     menu_eat
77c4: 4c 09 9c                           jmp     $9c09

77c7: 4c fc 7f     menu_eat              jmp     what_will_you_eat

77ca: c9 02        menu_drop             cmp     #$02                    ;col 2
77cc: d0 18                              bne     menu_examine
77ce: a5 72                              lda     MENUROW
77d0: d0 03                              bne     menu_sell
77d2: 4c d0 7c                           jmp     L7CD0

77d5: c9 01        menu_sell             cmp     #$01
77d7: d0 03                              bne     menu_heal
77d9: 4c 15 9c                           jmp     SCRN_sell

77dc: c9 02        menu_heal             cmp     #$02
77de: d0 03                              bne     menu_rest
77e0: 4c 00 9c                           jmp     SCRN_heal

77e3: 4c b5 7a     menu_rest             jmp     L7AB5

77e6: c9 03        menu_examine          cmp     #$03                    ;col 3
77e8: d0 18                              bne     menu_status
77ea: a5 72                              lda     MENUROW
77ec: d0 03                              bne     menu_inventory
77ee: 4c 13 82     GAME2_examine         jmp     examine

77f1: c9 01        menu_inventory        cmp     #$01
77f3: d0 03                              bne     menu_grunspreke
77f5: 4c 65 82                           jmp     do_menu_inventory

77f8: c9 02        menu_grunspreke       cmp     #$02
77fa: d0 03                              bne     menu_kiniport
77fc: 4c 03 9c                           jmp     SCRN_grunspreke

77ff: 4c 06 9c     menu_kiniport         jmp     SCRN_kiniport

7802: a5 72        menu_status           lda     MENUROW                 ;col 4
7804: d0 03                              bne     menu_renew
7806: 4c c1 82                           jmp     do_menu_status          ;row 0

7809: c9 01        menu_renew            cmp     #$01                    ;row 1
780b: d0 0a                              bne     menu_menu
780d: a5 35                              lda     doorNeshom
780f: f0 03                              beq     @renew
7811: 4c 39 77                           jmp     action_menu_no_effect   ;RENEW does nothing in Neshom realm

7814: 4c 1f 84     @renew                jmp     renew

7817: c9 02        menu_menu             cmp     #$02                    ;row 2
7819: d0 08                              bne     menu_sound
781b: 20 06 60                           jsr     GAME2_cleartext
781e: 68                                 pla                             ;discard game loop
781f: 68                                 pla
7820: 4c 40 a8                           jmp     SCRN_warm_start         ;return to menu

7823: a9 01        menu_sound            lda     #$01                    ;row 3
7825: 45 4a                              eor     SOUNDFLG                ;toggle sound
7827: 85 4a                              sta     SOUNDFLG
7829: 20 49 a8                           jsr     SCRN_sound_status       ;display sound status
782c: 4c e3 7f                           jmp     message_wait

                   ; Display action menu. This is a single string that wraps around the screen as
                   ; it is printed in one shot.
782f: a9 00        display_actions       lda     #$00
7831: 85 64                              sta     HTAB
7833: a6 64        @char                 ldx     HTAB
7835: bd 44 78                           lda     action_text,x
7838: 20 0f 60                           jsr     GAME2_printchar
783b: e6 64                              inc     HTAB
783d: a5 64                              lda     HTAB
783f: c9 9f                              cmp     #$9f                    ;hardcoded length of action_text
7841: d0 f0                              bne     @char
7843: 60                                 rts

7844: a0 d0 c1 d5+ action_text           .str    ↑“ PAUSE  TAKE  DROP  EXAMINE     STATUS   SPEAK  BUY   SELL  I”
                                          +      “NVENTORY   RENEW    PENSE  USE   HEAL  GRUNSPREKE  MENU     OF”
                                          +      “FER  EAT   REST  KINIPORT    SOUND  ”

                   ; Given menu row # and col #, get entry's htab (in HTAB) and width (in $77).
                   tmp_menuwidth         .var    $77    {addr/1}         ;width of current menu column

78e3: a6 72        get_menu_pos          ldx     MENUROW                 ;menu row number we are on
78e5: bd 26 79                           lda     text_col1,x             ;get the htab of col 1 in row
78e8: a6 71                              ldx     MENUCOL                 ;menu column we are on
78ea: 18                                 clc
78eb: 7d 2a 79                           adc     text_colx,x             ;get htab of menu column
78ee: 85 64                              sta     HTAB
78f0: bd 2f 79                           lda     text_colw,x             ;get width of menu column
78f3: 85 77                              sta     tmp_menuwidth           ;save for later
78f5: 60                                 rts

                   ; Highlight text of currently selected action menu item by drawing it in inverse
                   ; text over the existing menu item.
78f6: 20 e3 78     highlight_menu_action jsr     get_menu_pos
78f9: a9 01                              lda     #$01
78fb: 85 66                              sta     INVTEXT                 ;enable inverse
78fd: a6 64        @char                 ldx     HTAB                    ;HTAB is also the index into the action text string
78ff: bd 44 78                           lda     action_text,x
7902: 20 0f 60                           jsr     GAME2_printchar
7905: e6 64                              inc     HTAB                    ;next screen col & string char
7907: c6 77                              dec     tmp_menuwidth
7909: d0 f2                              bne     @char
790b: a9 00                              lda     #$00
790d: 85 66                              sta     INVTEXT                 ;disable inverse
790f: 60                                 rts

                   ; Unhighlight selected menu action, after we have previously highlighted it and
                   ; are moving away.
                   unhighlight_menu_action
7910: 20 e3 78                           jsr     get_menu_pos
7913: a9 00                              lda     #$00
7915: 85 66                              sta     INVTEXT                 ;disable inverse
7917: a6 64        @char                 ldx     HTAB
7919: bd 44 78                           lda     action_text,x
791c: 20 0f 60                           jsr     GAME2_printchar
791f: e6 64                              inc     HTAB
7921: c6 77                              dec     tmp_menuwidth
7923: d0 f2                              bne     @char
7925: 60                                 rts

7926: 00 28 50 78  text_col1             .bulk   00285078                ;col #s of first col of text
792a: 00 07 0d 13+ text_colx             .bulk   00070d131f              ;col #s of each menu col
792f: 07 06 06 0c+ text_colw             .bulk   0706060c08              ;width of each menu col

                   • Clear variables

7934: a2 4a        L7934                 ldx     #$4a
7936: bd 6c b5     L7936                 lda     inv_token,x
7939: 2c bd 1d                           bit     GAME1_BITTAB5
793c: f0 0a                              beq     L7948
793e: a9 00                              lda     #$00
7940: 9d 6c b5                           sta     inv_token,x
7943: a0 08                              ldy     #$08
7945: 20 48 7e                           jsr     lose_weight
7948: ca           L7948                 dex
7949: 10 eb                              bpl     L7936
794b: 60                                 rts

794c: a2 13        L794C                 ldx     #$13
794e: bd 58 b5     @loop                 lda     inv_shuba,x
7951: 2c bd 1d                           bit     GAME1_BITTAB5
7954: f0 0a                              beq     L7960
7956: a9 00                              lda     #$00
7958: 9d 58 b5                           sta     inv_shuba,x
795b: a0 07                              ldy     #item_shuba
795d: 20 48 7e                           jsr     lose_weight
7960: ca           L7960                 dex
7961: 10 eb                              bpl     @loop
7963: 60                                 rts

7964: a9 1c        kidnapped_by_salaat   lda     #$1c
7966: 85 1b                              sta     MAPPOS
7968: a9 00                              lda     #$00
796a: 85 1c                              sta     MAPHALF
796c: a9 01                              lda     #$01
796e: 85 67                              sta     INSIDE
7970: 20 4c a8                           jsr     $a84c
7973: 20 1e 60                           jsr     GAME2_read_playfield
7976: a9 15                              lda     #$15
7978: 85 19                              sta     playerX
797a: a9 0f                              lda     #$0f
797c: 85 1a                              sta     playerY
797e: 20 0c 60                           jsr     GAME2_PRNTSTR
7981: 01                                 .dd1    $01
7982: d9 cf d5 a0+                       .str    ↑“YOU WERE KIDNAPPED BY THE FOLLOWERS     OF D'OL SALAAT”
79b8: ff                                 .dd1    $ff
79b9: 4c 03 6b     @cont                 jmp     GAME2_draw_player

79bc: a9 3b        kidnapped_by_nekom    lda     #$3b
79be: 85 1b                              sta     MAPPOS
79c0: a9 00                              lda     #$00
79c2: 85 1c                              sta     MAPHALF
79c4: a9 01                              lda     #$01
79c6: 85 67                              sta     INSIDE
79c8: 20 4c a8                           jsr     $a84c
79cb: 20 1e 60                           jsr     GAME2_read_playfield
79ce: a9 13                              lda     #$13
79d0: 85 19                              sta     playerX
79d2: a9 0f                              lda     #$0f
79d4: 85 1a                              sta     playerY
79d6: 20 0c 60                           jsr     GAME2_PRNTSTR
79d9: 01                                 .dd1    $01
79da: d9 cf d5 a0+                       .str    ↑“YOU WERE KIDNAPPED BY THE NEKOM”
79f9: ff                                 .dd1    $ff
79fa: 4c b9 79                           jmp     @cont

79fd: a5 34        attacked              lda     temp34_npctype
79ff: c9 e0                              cmp     #$e0                    ;E0 = kidnapped by salaat
7a01: d0 0a                              bne     @salaat_attack
7a03: 20 64 79                           jsr     kidnapped_by_salaat
7a06: a9 00        @finish_attack        lda     #$00
7a08: 85 34                              sta     temp34_npctype
7a0a: 4c e3 7f                           jmp     message_wait

7a0d: c9 e1        @salaat_attack        cmp     #$e1                    ;E1 = D'OL SALAAT attack
7a0f: d0 50                              bne     @nekom_kidnap
7a11: 20 1b 60                           jsr     GAME2_teleport_home
7a14: 20 0c 60                           jsr     GAME2_PRNTSTR
7a17: 01                                 .dd1    $01
7a18: d9 cf d5 a0+                       .str    ↑“YOU WERE ATTACKED BY A FOLLOWER OF      D'OL SALAAT. TIME HAS”
                                          +      “ PASSED.”
7a5d: ff                                 .dd1    $ff
7a5e: 4c 06 7a                           jmp     @finish_attack

7a61: c9 e2        @nekom_kidnap         cmp     #$e2                    ;E2 = kidnapped by nekom
7a63: d0 06                              bne     @nekom_attack
7a65: 20 bc 79                           jsr     kidnapped_by_nekom
7a68: 4c 06 7a                           jmp     @finish_attack

7a6b: 20 1b 60     @nekom_attack         jsr     GAME2_teleport_home     ;otherwise (E3..EF?) = NEKOM attack
7a6e: 20 0c 60                           jsr     GAME2_PRNTSTR
7a71: 01                                 .dd1    $01
7a72: d9 cf d5 a0+                       .str    ↑“YOU WERE ATTACKED BY A MEMBER OF THE    NEKOM. TIME HAS PASSE”
                                          +      “D.”
7ab1: ff                                 .dd1    $ff
7ab2: 4c 06 7a                           jmp     @finish_attack

7ab5: 20 06 60     L7AB5                 jsr     GAME2_cleartext
7ab8: a5 67                              lda     INSIDE
7aba: d0 03                              bne     L7ABF
7abc: 4c c7 7b                           jmp     no_nid_here

7abf: a5 e6        L7ABF                 lda     tileKnee
7ac1: c9 3c                              cmp     #$3c
7ac3: f0 03                              beq     L7AC8
7ac5: 4c c7 7b                           jmp     no_nid_here

7ac8: a5 1b        L7AC8                 lda     MAPPOS
7aca: c9 09                              cmp     #$09
7acc: d0 04                              bne     L7AD2
7ace: a5 1c                              lda     MAPHALF
7ad0: f0 37                              beq     L7B09
7ad2: a5 1b        L7AD2                 lda     MAPPOS
7ad4: c5 2d                              cmp     homePos
7ad6: d0 06                              bne     L7ADE
7ad8: a5 1c                              lda     MAPHALF
7ada: c5 2e                              cmp     homeHalf
7adc: f0 2b                              beq     L7B09
7ade: a5 37        L7ADE                 lda     spokeTo
7ae0: f0 07                              beq     L7AE9
7ae2: ad f0 02                           lda     RWTSBUF+240
7ae5: c9 10                              cmp     #$10
7ae7: f0 20                              beq     L7B09
7ae9: 20 0c 60     L7AE9                 jsr     GAME2_PRNTSTR
7aec: 01                                 .dd1    $01
7aed: ce cf a0 cf+                       .str    ↑“NO ONE OFFERED YOU A NID”
7b05: ff                                 .dd1    $ff
7b06: 4c e3 7f                           jmp     message_wait

7b09: e6 19        L7B09                 inc     playerX
7b0b: 20 0f 6b                           jsr     GAME2_adjacent_tiles
7b0e: a5 e6                              lda     tileKnee
7b10: c9 3d                              cmp     #$3d
7b12: d0 f5                              bne     L7B09
7b14: c6 19                              dec     playerX
7b16: a2 2e                              ldx     #$2e
7b18: 86 a3                              stx     animFrame
7b1a: e8                                 inx
7b1b: 86 a4                              stx     animFrame_unused
7b1d: 20 0c 6b                           jsr     GAME2_redraw_player
7b20: 4c 7d 7b                           jmp     sleep_loop

7b23: 20 75 84     L7B23                 jsr     next_time_period
7b26: a9 04                              lda     #$04
7b28: 18                                 clc
7b29: 65 25                              adc     levelRest
7b2b: 85 25                              sta     levelRest
7b2d: c5 2b                              cmp     limitRest
7b2f: 90 05                              bcc     L7B36
7b31: a6 2b                              ldx     limitRest               ;cap level of rest
7b33: ca                                 dex
7b34: 86 25                              stx     levelRest
7b36: a5 1c        L7B36                 lda     MAPHALF
7b38: d0 0a                              bne     L7B44
7b3a: a5 1b                              lda     MAPPOS
7b3c: c9 09                              cmp     #$09
7b3e: d0 04                              bne     L7B44
7b40: a9 01                              lda     #$01
7b42: 85 35                              sta     doorNeshom
7b44: ae f1 02     L7B44                 ldx     RWTSBUF_npcnum
7b47: bd 00 b2                           lda     state_npc1,x
7b4a: d0 31                              bne     sleep_loop
7b4c: ad f2 02                           lda     RWTSBUF_npctype
                   NOTE: Handle sleeping in NPC $20..$23 nid
7b4f: c9 20                              cmp     #$20
7b51: d0 06                              bne     L7B59
7b53: 20 34 79                           jsr     L7934
7b56: 4c 7d 7b                           jmp     sleep_loop

7b59: c9 22        L7B59                 cmp     #$22
7b5b: d0 06                              bne     L7B63
7b5d: 20 4c 79                           jsr     L794C
7b60: 4c 7d 7b                           jmp     sleep_loop

7b63: c9 21        L7B63                 cmp     #$21
7b65: d0 09                              bne     L7B70
7b67: 20 06 60                           jsr     GAME2_cleartext
7b6a: 20 64 79                           jsr     kidnapped_by_salaat
7b6d: 4c e3 7f                           jmp     message_wait

7b70: c9 23        L7B70                 cmp     #$23
7b72: d0 09                              bne     sleep_loop
7b74: 20 06 60                           jsr     GAME2_cleartext
7b77: 20 bc 79                           jsr     kidnapped_by_nekom
7b7a: 4c e3 7f                           jmp     message_wait

                   ; Looks like this does the sleeping loop, which goes tick-tock 3 times and then
                   ; boop. Any input during this loop terminates it and returns to caller.
7b7d: 20 d6 82     sleep_loop            jsr     display_status
7b80: 20 f2 7f                           jsr     await_button_up
7b83: 20 a9 7b                           jsr     @terminate_on_input
7b86: 20 a9 7b                           jsr     @terminate_on_input
7b89: a9 03                              lda     #$03                    ;thrice
7b8b: 85 79                              sta     temp79
7b8d: a2 0d        @loop                 ldx     #$0d                    ;tick
7b8f: 20 03 b6                           jsr     SCRN_play_sound
7b92: 20 a9 7b                           jsr     @terminate_on_input
7b95: a2 00                              ldx     #$00                    ;tock
7b97: 20 03 b6                           jsr     SCRN_play_sound
7b9a: 20 a9 7b                           jsr     @terminate_on_input
7b9d: c6 79                              dec     temp79
7b9f: d0 ec                              bne     @loop
7ba1: a2 01                              ldx     #$01                    ;boop
7ba3: 20 03 b6                           jsr     SCRN_play_sound
7ba6: 4c 23 7b                           jmp     L7B23

                   ; Read joystick (keyboard) input up to $15 times (effects a constant delay if no
                   ; input). If any input occurred, terminate the calling subroutine.
7ba9: a9 15        @terminate_on_input   lda     #$15
7bab: 85 08                              sta     temp08
7bad: 20 2a 6b     @loop                 jsr     GAME2_menu_input
7bb0: d0 09                              bne     @got_input
7bb2: a5 a2                              lda     MOVING
7bb4: d0 05                              bne     @got_input
7bb6: c6 08                              dec     temp08
7bb8: d0 f3                              bne     @loop                   ;try $15 times
7bba: 60                                 rts

7bbb: 68           @got_input            pla                             ;discard caller
7bbc: 68                                 pla
7bbd: 20 06 60                           jsr     GAME2_cleartext
7bc0: 20 21 6b                           jsr     L6B21
7bc3: 20 f2 7f                           jsr     await_button_up
7bc6: 60                                 rts

7bc7: 20 06 60     no_nid_here           jsr     GAME2_cleartext
7bca: 20 0c 60                           jsr     GAME2_PRNTSTR
7bcd: 29                                 .dd1    $29
7bce: d4 c8 c5 d2+                       .str    ↑“THERE IS NO NID HERE”
7be2: ff                                 .dd1    $ff
7be3: 4c e3 7f                           jmp     message_wait

7be6: 20 06 60     take                  jsr     GAME2_cleartext
7be9: 20 b5 81                           jsr     item_of_interest
7bec: 90 03                              bcc     take_item
7bee: 4c 88 7c                           jmp     nothing_to_take

7bf1: 20 c0 7f     take_item             jsr     slot_to_item            ;A=slot -> Y=item
7bf4: c0 0d                              cpy     #item_fallaKey
7bf6: d0 04                              bne     @std_item
7bf8: a5 38                              lda     fallaKeyOffered
7bfa: d0 4c                              bne     take_legally            ;otherwise fall thru, should fail
7bfc: a5 67        @std_item             lda     INSIDE
7bfe: f0 48                              beq     take_legally
7c00: a5 c4                              lda     DEMOFLG
7c02: d0 44                              bne     take_legally            ;anything can be taken during the demo
7c04: a5 1c                              lda     MAPHALF
7c06: d0 16                              bne     @side1
7c08: a5 1b                              lda     MAPPOS
7c0a: c5 2d                              cmp     homePos
7c0c: f0 3a                              beq     take_legally            ;anything in your house is fair game
7c0e: c9 1c                              cmp     #$1c                    ;or in room 1c, 3b, 4b or 51
7c10: f0 36                              beq     take_legally
7c12: c9 3b                              cmp     #$3b
7c14: f0 32                              beq     take_legally
7c16: c9 4b                              cmp     #$4b
7c18: f0 2e                              beq     take_legally
7c1a: c9 51                              cmp     #$51
7c1c: f0 2a                              beq     take_legally
7c1e: a5 37        @side1                lda     spokeTo
7c20: f0 05                              beq     not_offered
7c22: cc f0 02                           cpy     RWTSBUF+240
7c25: f0 21                              beq     take_legally
7c27: 20 0c 60     not_offered           jsr     GAME2_PRNTSTR
7c2a: 01                                 .dd1    $01
7c2b: c9 d4 a0 d7+                       .str    ↑“IT WAS NOT OFFERED TO YOU”
7c44: ff                                 .dd1    $ff
7c45: 4c e3 7f                           jmp     message_wait

7c48: b9 c1 7c     take_legally          lda     item_weights,y          ;can we carry this?
7c4b: 18                                 clc
7c4c: 65 70                              adc     WEIGHT
7c4e: c5 2c                              cmp     maxWeight
7c50: b0 52                              bcs     carry_no_more           ;too heavy!
7c52: 85 70                              sta     WEIGHT
7c54: bd 00 b5                           lda     itemState,x
7c57: 09 20                              ora     #%00100000              ;set bit 5 of inv slot -- item possession
7c59: 9d 00 b5                           sta     itemState,x
7c5c: 84 77                              sty     selItemSlot
7c5e: 98                                 tya
7c5f: 20 51 7e                           jsr     L7E51
7c62: 20 0c 60                           jsr     GAME2_PRNTSTR
7c65: 29                                 .dd1    $29
7c66: d9 cf d5 a0+                       .str    ↑“YOU FIND”
7c6e: ff                                 .dd1    $ff
7c6f: a4 77                              ldy     selItemSlot
7c71: a9 32                              lda     #$32
7c73: 85 64                              sta     HTAB
7c75: 20 a2 7e                           jsr     print_item_desc
7c78: a9 00                              lda     #$00
7c7a: 85 37                              sta     spokeTo
7c7c: a5 77                              lda     selItemSlot
7c7e: c9 01                              cmp     #item_spiritLamp
7c80: d0 03                              bne     L7C85
7c82: 20 4b 60                           jsr     L604B
7c85: 4c e3 7f     L7C85                 jmp     message_wait

7c88: 20 0c 60     nothing_to_take       jsr     GAME2_PRNTSTR
7c8b: 29                                 .dd1    $29
7c8c: ce cf d4 c8+                       .str    ↑“NOTHING HERE TO TAKE”
7ca0: ff                                 .dd1    $ff
7ca1: 4c e3 7f                           jmp     message_wait

7ca4: 20 0c 60     carry_no_more         jsr     GAME2_PRNTSTR
7ca7: 29                                 .dd1    $29
7ca8: d9 cf d5 a0+                       .str    ↑“YOU CAN CARRY NO MORE”
7cbd: ff                                 .dd1    $ff
7cbe: 4c e3 7f                           jmp     message_wait

                   ; Item weight table. Everything weighs 5 units except for tokens (1).
7cc1: 05           item_weights          .dd1    $05                     ;0 spirit bell
7cc2: 05                                 .dd1    $05
7cc3: 05                                 .dd1    $05
7cc4: 05                                 .dd1    $05
7cc5: 05                                 .dd1    $05
7cc6: 05                                 .dd1    $05
7cc7: 05                                 .dd1    $05
7cc8: 05                                 .dd1    $05
7cc9: 01                                 .dd1    $01                     ;8 token
7cca: 05                                 .dd1    $05
7ccb: 05                                 .dd1    $05
7ccc: 05                                 .dd1    $05
7ccd: 05                                 .dd1    $05
7cce: 05                                 .dd1    $05
7ccf: 05                                 .dd1    $05                     ;14 strange elixer

7cd0: 20 06 60     L7CD0                 jsr     GAME2_cleartext
7cd3: a5 19                              lda     playerX
7cd5: f0 04                              beq     L7CDB
7cd7: c9 27                              cmp     #$27
7cd9: d0 03                              bne     L7CDE
7cdb: 4c 35 7e     L7CDB                 jmp     L7E35

7cde: a5 67        L7CDE                 lda     INSIDE
7ce0: a5 67                              lda     INSIDE                  ;??
7ce2: f0 42                              beq     L7D26
7ce4: a5 2d                              lda     homePos
7ce6: c5 1b                              cmp     MAPPOS
7ce8: d0 06                              bne     L7CF0
7cea: a5 2e                              lda     homeHalf
7cec: c5 1c                              cmp     MAPHALF
7cee: f0 03                              beq     L7CF3
7cf0: 4c 35 7e     L7CF0                 jmp     L7E35

7cf3: a5 e6        L7CF3                 lda     tileKnee
7cf5: c9 57                              cmp     #$57
7cf7: 90 2d                              bcc     L7D26
7cf9: c9 59                              cmp     #$59
7cfb: b0 29                              bcs     L7D26
7cfd: a5 e7                              lda     tileArm
7cff: c9 e2                              cmp     #$e2
7d01: b0 23                              bcs     L7D26
7d03: a5 95                              lda     FACING
7d05: 30 0b                              bmi     L7D12
7d07: a5 ea                              lda     tileArmRight
7d09: c9 e2                              cmp     #$e2
7d0b: b0 19                              bcs     L7D26
7d0d: a6 19                              ldx     playerX
7d0f: 4c 1b 7d                           jmp     L7D1B

7d12: a5 e9        L7D12                 lda     tileArmLeft
7d14: c9 e2                              cmp     #$e2
7d16: b0 0e                              bcs     L7D26
7d18: a6 19                              ldx     playerX
7d1a: ca                                 dex
7d1b: 86 75        L7D1B                 stx     temp75
7d1d: a6 1a                              ldx     playerY
7d1f: ca                                 dex
7d20: ca                                 dex
7d21: 86 76                              stx     temp76
7d23: 4c 6d 7d                           jmp     what_will_you_drop

7d26: a5 e3        L7D26                 lda     tileUnder
7d28: c9 e0                              cmp     #$e0
7d2a: b0 3e                              bcs     L7D6A
7d2c: 20 12 6b                           jsr     L6B12
7d2f: a5 f1                              lda     xSolid
7d31: f0 37                              beq     L7D6A
7d33: a5 e0                              lda     tileFeet
7d35: c9 e2                              cmp     #$e2
7d37: b0 31                              bcs     L7D6A
7d39: a5 95                              lda     FACING
7d3b: 30 07                              bmi     L7D44
7d3d: a5 e2                              lda     tileFeetRight
7d3f: a6 19                              ldx     playerX
7d41: 4c 49 7d                           jmp     L7D49

7d44: a5 e1        L7D44                 lda     tileFeetLeft
7d46: a6 19                              ldx     playerX
7d48: ca                                 dex
7d49: 86 75        L7D49                 stx     temp75
7d4b: a6 1a                              ldx     playerY
7d4d: 86 76                              stx     temp76
7d4f: c9 e1                              cmp     #$e1
7d51: b0 17                              bcs     L7D6A
7d53: c9 07                              cmp     #$07
7d55: f0 13                              beq     L7D6A
7d57: c9 08                              cmp     #$08
7d59: f0 0f                              beq     L7D6A
7d5b: c9 52                              cmp     #$52
7d5d: f0 0b                              beq     L7D6A
7d5f: c9 1c                              cmp     #$1c
7d61: f0 07                              beq     L7D6A
7d63: 20 12 6b                           jsr     L6B12
7d66: a5 f1                              lda     xSolid
7d68: f0 03                              beq     what_will_you_drop
7d6a: 4c 35 7e     L7D6A                 jmp     L7E35

7d6d: 20 0c 60     what_will_you_drop    jsr     GAME2_PRNTSTR
7d70: 29                                 .dd1    $29
7d71: d7 c8 c1 d4+                       .str    ↑“WHAT WILL YOU DROP?”
7d84: ff                                 .dd1    $ff
7d85: a9 ff                              lda     #$ff                    ;iterate through all slots
7d87: 85 77                              sta     selItemSlot             ;holds current slot index
7d89: 85 39                              sta     suppressSound0
7d8b: 20 f2 7f                           jsr     await_button_up
7d8e: e6 77        @next_slot            inc     selItemSlot
7d90: a6 77                              ldx     selItemSlot
7d92: e0 ff                              cpx     #$ff                    ;0-fe items, ff=nothing
7d94: d0 18                              bne     @valid_slot
7d96: 20 0c 60                           jsr     GAME2_PRNTSTR
7d99: 3e                                 .dd1    $3e
7d9a: ce cf d4 c8+                       .str    ↑“NOTHING         ”
7daa: ff                                 .dd1    $ff
7dab: 4c c1 7d                           jmp     L7DC1

7dae: bd 00 b5     @valid_slot           lda     itemState,x
7db1: 2c bd 1d                           bit     GAME1_BITTAB5           ;do we have an item in this slot
7db4: f0 d8                              beq     @next_slot
7db6: 8a                                 txa                             ;yes
7db7: 20 c0 7f                           jsr     slot_to_item            ;get item in Y
7dba: a9 3e                              lda     #$3e
7dbc: 85 64                              sta     HTAB
7dbe: 20 a2 7e                           jsr     print_item_desc
7dc1: 20 06 b6     L7DC1                 jsr     SCRN_play_sound_0
7dc4: 20 2a 6b     L7DC4                 jsr     GAME2_menu_input
7dc7: d0 07                              bne     L7DD0
7dc9: a5 86                              lda     YDIR
7dcb: 10 f7                              bpl     L7DC4
7dcd: 4c 8e 7d                           jmp     @next_slot

7dd0: 20 06 60     L7DD0                 jsr     GAME2_cleartext
7dd3: a6 77                              ldx     selItemSlot
7dd5: e0 ff                              cpx     #$ff                    ;nothing
7dd7: f0 5b                              beq     @rts
7dd9: a5 1b                              lda     MAPPOS
7ddb: 9d 00 b3                           sta     itemStatePos,x
7dde: a5 75                              lda     temp75
7de0: 9d 00 b4                           sta     itemStateCol,x
7de3: a5 76                              lda     temp76
7de5: a4 1c                              ldy     MAPHALF
7de7: f0 02                              beq     L7DEB
7de9: 09 80                              ora     #$80
7deb: 09 40        L7DEB                 ora     #$40
7ded: 9d 00 b5                           sta     itemState,x
7df0: 20 51 7e                           jsr     L7E51
7df3: a6 77                              ldx     selItemSlot
7df5: a5 3a                              lda     litLamp
7df7: f0 2a                              beq     L7E23
7df9: e4 3a                              cpx     litLamp
7dfb: d0 26                              bne     L7E23
7dfd: a9 00                              lda     #$00
7dff: 9d 00 b5                           sta     itemState,x
7e02: 85 3a                              sta     litLamp
7e04: 85 3b                              sta     MON_PCH
7e06: 20 29 7e                           jsr     L7E29
7e09: 20 0c 60                           jsr     GAME2_PRNTSTR
7e0c: 01                                 .dd1    $01
7e0d: d9 cf d5 d2+                       .str    ↑“YOUR LAMP VANISHES”
7e1f: ff                                 .dd1    $ff
7e20: 4c e3 7f                           jmp     message_wait

7e23: a5 77        L7E23                 lda     selItemSlot
7e25: c9 01                              cmp     #$01
7e27: d0 03                              bne     L7E2C
7e29: 20 4b 60     L7E29                 jsr     L604B
7e2c: a5 77        L7E2C                 lda     selItemSlot
7e2e: 20 c0 7f                           jsr     slot_to_item
7e31: 20 48 7e                           jsr     lose_weight
7e34: 60           @rts                  rts

7e35: 20 06 60     L7E35                 jsr     GAME2_cleartext
7e38: 20 0c 60                           jsr     GAME2_PRNTSTR
7e3b: 29                                 .dd1    $29
7e3c: ce cf d4 a0+                       .str    ↑“NOT HERE”
7e44: ff                                 .dd1    $ff
7e45: 4c e3 7f                           jmp     message_wait

                   ; Subtracts weight of item (in Y) from current carry weight.
7e48: a5 70        lose_weight           lda     WEIGHT
7e4a: 38                                 sec
7e4b: f9 c1 7c                           sbc     item_weights,y
7e4e: 85 70                              sta     WEIGHT
7e50: 60                                 rts

7e51: 8a           L7E51                 txa
7e52: 48                                 pha
7e53: 20 09 60                           jsr     GAME2_write_tiles_to_text
7e56: 68                                 pla
7e57: aa                                 tax
7e58: bd 00 b5                           lda     itemState,x
7e5b: 29 1f                              and     #$1f
7e5d: 85 06                              sta     TXTROW
7e5f: bd 00 b4                           lda     itemStateCol,x
7e62: 85 05                              sta     TXTCOL
7e64: 20 90 7e                           jsr     txtpos_to_addr
7e67: 8a                                 txa
7e68: 20 c0 7f                           jsr     slot_to_item
7e6b: 84 08                              sty     temp08
7e6d: 06 08                              asl     temp08
7e6f: a9 fd                              lda     #$fd
7e71: 38                                 sec
7e72: e5 08                              sbc     temp08
7e74: a0 00                              ldy     #$00
7e76: b1 11                              lda     (temp11_textlo),y
7e78: 20 03 60                           jsr     GAME2_drawtile
7e7b: e6 05                              inc     TXTCOL
7e7d: e6 11                              inc     temp11_textlo
7e7f: d0 02                              bne     L7E83
7e81: e6 12                              inc     temp12_texthi
7e83: a0 00        L7E83                 ldy     #$00
7e85: b1 11                              lda     (temp11_textlo),y
7e87: 20 03 60                           jsr     GAME2_drawtile
7e8a: 20 03 6b                           jsr     GAME2_draw_player
7e8d: 4c 15 6b                           jmp     L6B15

                   ; Convert the text position in (TXTCOL,TXTROW) to a text page address and store
                   ; it in $11/12. Clobbers A,Y but preserves X.
7e90: a4 06        txtpos_to_addr        ldy     TXTROW
7e92: b9 a0 1d                           lda     GAME1_textlo,y
7e95: 18                                 clc
7e96: 65 05                              adc     TXTCOL
7e98: 85 11                              sta     temp11_textlo
7e9a: b9 80 1d                           lda     GAME1_texthi,y
7e9d: 69 00                              adc     #$00
7e9f: 85 12                              sta     temp12_texthi
7ea1: 60                                 rts

7ea2: be b0 7f     print_item_desc       ldx     item_desc_idx,y         ;item in Y
7ea5: 86 7a                              stx     temp7a                  ;item
7ea7: a9 10                              lda     #16                     ;length of item desc
7ea9: 85 7b                              sta     temp7b                  ;len
7eab: a6 7a        @printchar            ldx     temp7a
7ead: bd c0 7e                           lda     item_desc,x
7eb0: 20 0f 60                           jsr     GAME2_printchar
7eb3: e6 7a                              inc     temp7a
7eb5: e6 64                              inc     HTAB
7eb7: c6 7b                              dec     temp7b
7eb9: d0 f0                              bne     @printchar
7ebb: a9 00                              lda     #$00
7ebd: 85 66                              sta     INVTEXT
7ebf: 60                                 rts

                   ; There are 15 possible items, with 16 description indices in this string (the
                   ; last not used). Each is 16 bytes long so the indices aren't really needed.
7ec0: c1 a0 d3 d0+ item_desc             .str    ↑“A SPIRIT BELL   A SPIRIT LAMP   A HONEYLAMP     A WAND OF BEF”
                                          +      “AL A ROAST LAPAN   PAN BREAD       FRUIT & NUTS    A SHUBA    ”
                                          +      “     A TOKEN         A TRENCHER BEAK WISSENBERRIES   A VINE RO”
                                          +      “PE     THE TEMPLE KEY  D'OL FALLA'S KEYA STRANGE ELIXER”
7fb0: 00 10 20 30+ item_desc_idx         .bulk   00102030405060708090a0b0c0d0e0f0

                   ; Compute the item number (0-14) from the inventory slot ($00-$fe). Takes the
                   ; slot number in A, and sets Y to the index of the first byte in the item
                   ; address table that is less than that.
7fc0: a0 00        slot_to_item          ldy     #$00
7fc2: d9 d1 7f     @loop                 cmp     @item_slots,y
7fc5: 90 06                              bcc     @iny
7fc7: d9 d2 7f                           cmp     @item_slots+1,y
7fca: b0 01                              bcs     @iny
7fcc: 60                                 rts

7fcd: c8           @iny                  iny
7fce: d0 f2                              bne     @loop                   ;always--y<16
7fd0: 60                                 rts

                   ; One pair of overlapping bytes for each of 15 items, or looked at another way,
                   ; one byte for the first slot address an item can be in.
7fd1: 00           @item_slots           .dd1    $00                     ;spirit bell ($00)
7fd2: 01                                 .dd1    $01                     ;spirit lamp ($01)
7fd3: 02                                 .dd1    $02                     ;honeylamp ($02-$1a)
7fd4: 1b                                 .dd1    $1b                     ;wand of befal ($1b)
7fd5: 1c                                 .dd1    $1c                     ;roast lapan ($1c-$25)
7fd6: 26                                 .dd1    $26                     ;pan bread ($26-$3e)
7fd7: 3f                                 .dd1    $3f                     ;fruit and nuts
7fd8: 58                                 .dd1    $58                     ;shuba
7fd9: 6c                                 .dd1    $6c                     ;token
7fda: b7                                 .dd1    $b7                     ;trencher beak
7fdb: d0                                 .dd1    $d0                     ;wissenberries
7fdc: da                                 .dd1    $da                     ;vine rope
7fdd: f8                                 .dd1    $f8                     ;temple key ($f8)
7fde: f9                                 .dd1    $f9                     ;d'ol falla's key ($f9)
7fdf: fa                                 .dd1    $fa                     ;elixer ($fa-$fe)
7fe0: ff                                 .dd1    $ff                     ;(terminator)
7fe1: e6                                 .dd1    $e6                     ;unused
7fe2: ff                                 .dd1    $ff                     ;unused

                   ; Called, for example, after selecting SOUND menu item, which displays a status
                   ; screen / message immediately, so wait for the select button to be released.
                   ; Then, loop until a button or direction is pressed, clear the screen, and
                   ; return.
7fe3: 20 f2 7f     message_wait          jsr     await_button_up
7fe6: 20 2a 6b     @loop                 jsr     GAME2_menu_input
7fe9: d0 04                              bne     @ret
7feb: a5 a2                              lda     MOVING
7fed: f0 f7                              beq     @loop                   ;if no direction pressed
7fef: 4c 06 60     @ret                  jmp     GAME2_cleartext         ;and then rts

                   ; Loop until (menu select) button released (or at least not being pressed).
7ff2: 20 2a 6b     await_button_up       jsr     GAME2_menu_input
7ff5: d0 fb                              bne     await_button_up
7ff7: a2 10                              ldx     #$10
7ff9: 4c 12 60                           jmp     GAME2_delayXtimes256    ;and then rts

                   tempEatenFood         .var    $78    {addr/1}         ;which food was eaten

7ffc: 20 06 60     what_will_you_eat     jsr     GAME2_cleartext
7fff: 20 0c 60                           jsr     GAME2_PRNTSTR
8002: 01                                 .dd1    $01
8003: d7 c8 c1 d4+                       .str    ↑“WHAT WILL YOU EAT?”
8015: ff                                 .dd1    $ff
8016: a9 ff                              lda     #$ff
8018: 85 77                              sta     selItemSlot
801a: 85 78                              sta     tempEatenFood
801c: 85 39                              sta     suppressSound0
801e: 20 f2 7f                           jsr     await_button_up
8021: e6 77        L8021                 inc     selItemSlot
8023: a6 77                              ldx     selItemSlot
8025: e0 ff                              cpx     #$ff
8027: d0 1a                              bne     L8043
8029: 86 78                              stx     tempEatenFood           ;temp, which food
802b: 20 0c 60                           jsr     GAME2_PRNTSTR
802e: 15                                 .dd1    $15
802f: ce cf d4 c8+                       .str    ↑“NOTHING         ”
803f: ff                                 .dd1    $ff
8040: 4c 70 80                           jmp     L8070

8043: bd 00 b5     L8043                 lda     itemState,x
8046: 2c bd 1d                           bit     GAME1_BITTAB5
8049: f0 d6                              beq     L8021
804b: 8a                                 txa
804c: 20 c0 7f                           jsr     slot_to_item
804f: c4 78                              cpy     tempEatenFood
8051: f0 ce                              beq     L8021
8053: c0 04                              cpy     #$04
8055: f0 10                              beq     L8067
8057: c0 05                              cpy     #$05
8059: f0 0c                              beq     L8067
805b: c0 06                              cpy     #$06
805d: f0 08                              beq     L8067
805f: c0 0a                              cpy     #$0a
8061: f0 04                              beq     L8067
8063: c0 0e                              cpy     #$0e
8065: d0 ba                              bne     L8021
8067: 84 78        L8067                 sty     tempEatenFood
8069: a9 15                              lda     #$15
806b: 85 64                              sta     HTAB
806d: 20 a2 7e                           jsr     print_item_desc
8070: 20 06 b6     L8070                 jsr     SCRN_play_sound_0
8073: 20 2a 6b     L8073                 jsr     GAME2_menu_input
8076: d0 07                              bne     L807F
8078: a5 86                              lda     YDIR
807a: 10 f7                              bpl     L8073
807c: 4c 21 80                           jmp     L8021

807f: 20 06 60     L807F                 jsr     GAME2_cleartext
8082: a6 77                              ldx     selItemSlot
8084: e0 ff                              cpx     #$ff
8086: d0 01                              bne     L8089
8088: 60                                 rts

8089: a4 78        L8089                 ldy     tempEatenFood
808b: c0 04                              cpy     #$04
808d: d0 53                              bne     @is_pan_bread
808f: a5 20                              lda     PLAYER
8091: c9 02                              cmp     #PLAYER_Herd            ;only the 2 Erdling
8093: f0 34                              beq     @lapan_is_good
8095: c9 04                              cmp     #PLAYER_Charn           ;can eat lapan
8097: f0 30                              beq     @lapan_is_good
8099: 20 0c 60                           jsr     GAME2_PRNTSTR
809c: 01                                 .dd1    $01
809d: d4 c8 c5 a0+                       .str    ↑“THE LAPAN HAS A STRANGE TASTE”
80ba: ff                                 .dd1    $ff
80bb: a5 23                              lda     levelSpirit
80bd: 38                                 sec
80be: e9 0f                              sbc     #$0f
80c0: b0 02                              bcs     L80C4
80c2: a9 00                              lda     #$00
80c4: 85 23        L80C4                 sta     levelSpirit
80c6: 4c 25 81                           jmp     sate_hunger

80c9: 20 0c 60     @lapan_is_good        jsr     GAME2_PRNTSTR
80cc: 01                                 .dd1    $01
80cd: d4 c8 c5 a0+                       .str    ↑“THE LAPAN IS GOOD”
80de: ff                                 .dd1    $ff
80df: 4c 25 81                           jmp     sate_hunger

80e2: c0 05        @is_pan_bread         cpy     #item_pan_bread
80e4: d0 1d                              bne     @is_fruit_and_nuts
80e6: 20 0c 60                           jsr     GAME2_PRNTSTR
80e9: 01                                 .dd1    $01
80ea: d4 c8 c5 a0+                       .str    ↑“THE PAN BREAD IS GOOD”
80ff: ff                                 .dd1    $ff
8100: 4c 25 81                           jmp     sate_hunger

8103: c0 06        @is_fruit_and_nuts    cpy     #item_fruit_nuts
8105: d0 31                              bne     @is_wissenberries
8107: 20 0c 60                           jsr     GAME2_PRNTSTR
810a: 01                                 .dd1    $01
810b: d4 c8 c5 a0+                       .str    ↑“THE FRUIT & NUTS ARE GOOD”
8124: ff                                 .dd1    $ff
8125: a9 05        sate_hunger           lda     #$05                    ;gain 5 food
8127: 18                                 clc
8128: 65 24                              adc     levelFood
812a: 85 24                              sta     levelFood
812c: c5 2a                              cmp     limitFood               ;cap at limit - 1
812e: 90 05                              bcc     @done
8130: a6 2a                              ldx     limitFood
8132: ca                                 dex
8133: 86 24                              stx     levelFood
8135: 4c a6 81     @done                 jmp     L81A6

8138: c0 0a        @is_wissenberries     cpy     #item_berries
813a: d0 36                              bne     @strange_elixer
813c: 20 75 84                           jsr     next_time_period        ;lose 2 time periods
813f: 20 75 84                           jsr     next_time_period
8142: 20 0c 60                           jsr     GAME2_PRNTSTR
8145: 01                                 .dd1    $01
8146: d9 cf d5 a0+                       .str    ↑“YOU FEEL STRANGE. TIME PASSES”
8163: ff                                 .dd1    $ff
8164: a5 23                              lda     levelSpirit
8166: 38                                 sec
8167: e9 0f                              sbc     #$0f                    ;lose 10 spirit
8169: b0 02                              bcs     @done
816b: a9 00                              lda     #$00                    ;floor
816d: 85 23        @done                 sta     levelSpirit
816f: 4c a6 81                           jmp     L81A6

8172: 20 0c 60     @strange_elixer       jsr     GAME2_PRNTSTR
8175: 01                                 .dd1    $01
8176: d9 cf d5 a0+                       .str    ↑“YOU FEEL MUCH STRONGER”
818c: ff                                 .dd1    $ff
818d: a5 26                              lda     levelStamina
818f: 18                                 clc
8190: 69 05                              adc     #$05
8192: 85 26                              sta     levelStamina
8194: 4a                                 lsr     A
8195: aa                                 tax
8196: 86 25                              stx     levelRest
8198: 86 24                              stx     levelFood
819a: e8                                 inx
819b: 86 2b                              stx     limitRest
819d: 86 2a                              stx     limitFood
819f: a5 2c                              lda     maxWeight
81a1: 18                                 clc
81a2: 69 05                              adc     #$05
81a4: 85 2c                              sta     maxWeight
81a6: a6 77        L81A6                 ldx     selItemSlot
81a8: a9 00                              lda     #$00
81aa: 9d 00 b5                           sta     itemState,x
81ad: a4 78                              ldy     tempEatenFood
81af: 20 48 7e                           jsr     lose_weight
81b2: 4c e3 7f                           jmp     message_wait

                   ; Check for item of interest at arm-level (take height) or at feet. Clears carry
                   ; and sets A to the item slot if so. Sets carry if no item of interest.
                   • Clear variables

81b5: a5 e7        item_of_interest      lda     tileArm
81b7: c9 e0                              cmp     #$e0
81b9: 90 09                              bcc     L81C4
81bb: a6 1a                              ldx     playerY
81bd: ca                                 dex
81be: ca                                 dex
81bf: 86 65                              stx     $65
81c1: 4c d1 81                           jmp     L81D1

81c4: a5 e0        L81C4                 lda     tileFeet
81c6: c9 e0                              cmp     #$e0
81c8: b0 03                              bcs     L81CD
81ca: 4c 11 82                           jmp     L8211

81cd: a6 1a        L81CD                 ldx     playerY
81cf: 86 65                              stx     $65
81d1: a6 19        L81D1                 ldx     playerX
81d3: 2c b8 1d                           bit     GAME1_BITTAB0
81d6: d0 01                              bne     L81D9
81d8: ca                                 dex
81d9: 86 08        L81D9                 stx     temp08
81db: 85 79                              sta     temp79                  ;never used!
81dd: a2 00        L81DD                 ldx     #$00
81df: bd 00 b3     L81DF                 lda     itemStatePos,x
81e2: c5 1b                              cmp     MAPPOS
81e4: d0 28                              bne     L820E
81e6: bd 00 b5                           lda     itemState,x
81e9: 0a                                 asl     A
81ea: a9 00                              lda     #$00
81ec: 2a                                 rol     A
81ed: c5 1c                              cmp     MAPHALF
81ef: d0 1d                              bne     L820E
81f1: bd 00 b5                           lda     itemState,x
81f4: 2c be 1d                           bit     GAME1_BITTAB6
81f7: f0 15                              beq     L820E
81f9: 2c bd 1d                           bit     GAME1_BITTAB5
81fc: d0 10                              bne     L820E
81fe: 29 1f                              and     #$1f
8200: c5 65                              cmp     $65
8202: d0 0a                              bne     L820E
8204: bd 00 b4                           lda     itemStateCol,x
8207: c5 08                              cmp     temp08
8209: d0 03                              bne     L820E
820b: 8a                                 txa
820c: 18                                 clc
820d: 60                                 rts

820e: e8           L820E                 inx
820f: d0 ce                              bne     L81DF
8211: 38           L8211                 sec
8212: 60                                 rts

8213: 20 06 60     examine               jsr     GAME2_cleartext
8216: 20 b5 81                           jsr     item_of_interest
8219: 90 29                              bcc     it_looks_like
821b: 20 0c 60                           jsr     GAME2_PRNTSTR
821e: 01                                 .dd1    $01
821f: d4 c8 c5 d2+                       .str    ↑“THERE IS NOTHING OF INTEREST HERE”
8240: ff                                 .dd1    $ff
8241: 4c e3 7f                           jmp     message_wait

8244: 48           it_looks_like         pha
8245: 20 0c 60                           jsr     GAME2_PRNTSTR
8248: 01                                 .dd1    $01
8249: c9 d4 a0 cc+                       .str    ↑“IT LOOKS LIKE”
8256: ff                                 .dd1    $ff
8257: 68                                 pla
8258: 20 c0 7f                           jsr     slot_to_item
825b: a9 0f                              lda     #$0f
825d: 85 64                              sta     HTAB
825f: 20 a2 7e                           jsr     print_item_desc
8262: 4c e3 7f                           jmp     message_wait

8265: 20 06 60     do_menu_inventory     jsr     GAME2_cleartext
8268: 20 0c 60                           jsr     GAME2_PRNTSTR
826b: 01                                 .dd1    $01
826c: d9 cf d5 a0+                       .str    ↑“YOU HAVE”
8274: ff                                 .dd1    $ff
8275: a9 ff                              lda     #$ff
8277: 85 77                              sta     selItemSlot
8279: 85 78                              sta     selItemNum
827b: 85 39                              sta     suppressSound0          ;suppress beep for first item display
827d: e6 77        L827D                 inc     selItemSlot
827f: a6 77                              ldx     selItemSlot
8281: e0 ff                              cpx     #$ff
8283: d0 17                              bne     L829C
8285: e4 78                              cpx     selItemNum
8287: d0 10                              bne     @done
8289: 20 0c 60                           jsr     GAME2_PRNTSTR
828c: 0a                                 .dd1    $0a
828d: ce cf d4 c8+                       .str    ↑“NOTHING ”
8295: ff                                 .dd1    $ff
8296: 4c e3 7f                           jmp     message_wait

8299: 4c 06 60     @done                 jmp     GAME2_cleartext

829c: bd 00 b5     L829C                 lda     itemState,x
829f: 2c bd 1d                           bit     GAME1_BITTAB5
82a2: f0 d9                              beq     L827D
82a4: a9 00                              lda     #$00
82a6: 85 78                              sta     selItemNum
82a8: 8a                                 txa
82a9: 20 c0 7f                           jsr     slot_to_item
82ac: a9 0a                              lda     #$0a
82ae: 85 64                              sta     HTAB
82b0: 20 a2 7e                           jsr     print_item_desc
82b3: 20 06 b6                           jsr     SCRN_play_sound_0
82b6: 20 2a 6b     L82B6                 jsr     GAME2_menu_input
82b9: d0 c2                              bne     L827D
82bb: a5 86                              lda     YDIR
82bd: 30 be                              bmi     L827D
82bf: 10 f5                              bpl     L82B6

                   • Clear variables

82c1: 20 d3 82     do_menu_status        jsr     @status
82c4: 20 f2 7f                           jsr     await_button_up
82c7: 20 2a 6b     @loop                 jsr     GAME2_menu_input        ;await button or direction
82ca: d0 04                              bne     @ret
82cc: a5 a2                              lda     MOVING
82ce: f0 f7                              beq     @loop
82d0: 4c 06 60     @ret                  jmp     GAME2_cleartext

82d3: 20 06 60     @status               jsr     GAME2_cleartext
82d6: 20 0c 60     display_status        jsr     GAME2_PRNTSTR
82d9: 01                                 .dd1    $01
82da: c4 c1 d9                           .str    ↑“DAY”
82dd: ff                                 .dd1    $ff
82de: a6 20                              ldx     PLAYER
82e0: bd 94 83                           lda     player_name_idx,x
82e3: 85 7b                              sta     temp7b
82e5: a9 18                              lda     #$18
82e7: 85 64                              sta     HTAB
82e9: a4 7b        @loop1                ldy     temp7b
82eb: b9 d0 1a                           lda     GAME1_player_names,y
82ee: 20 0f 60                           jsr     GAME2_printchar
82f1: c6 7b                              dec     temp7b                  ;print name right-to-left
82f3: c6 64                              dec     HTAB
82f5: a5 64                              lda     HTAB
82f7: c9 13                              cmp     #$13                    ;each name is 5 chars -- use HTAB to track this
82f9: d0 ee                              bne     @loop1
82fb: a6 21                              ldx     timeOfDay
82fd: bd 17 84                           lda     time_of_day_idx,x
8300: 85 7b                              sta     temp7b
8302: a9 37                              lda     #$37
8304: 85 64                              sta     HTAB
8306: a4 7b        @loop2                ldy     temp7b
8308: b9 99 83                           lda     time_of_day_str,y
830b: 20 0f 60                           jsr     GAME2_printchar
830e: c6 7b                              dec     temp7b
8310: c6 64                              dec     HTAB
8312: a5 64                              lda     HTAB
8314: c9 28                              cmp     #$28                    ;each time of day is 15 chars long
8316: d0 ee                              bne     @loop2
8318: 20 0c 60                           jsr     GAME2_PRNTSTR
831b: 3c                                 .dd1    $3c
831c: cc c5 d6 c5+                       .str    ↑“LEVEL OF REST”
8329: ff                                 .dd1    $ff
832a: 20 0c 60                           jsr     GAME2_PRNTSTR
832d: 51                                 .dd1    $51
832e: d3 d0 c9 d2+                       .str    ↑“SPIRIT LIMIT”
833a: ff                                 .dd1    $ff
833b: 20 0c 60                           jsr     GAME2_PRNTSTR
833e: 64                                 .dd1    $64
833f: cc c5 d6 c5+                       .str    ↑“LEVEL OF FOOD”
834c: ff                                 .dd1    $ff
834d: 20 0c 60                           jsr     GAME2_PRNTSTR
8350: 79                                 .dd1    $79
8351: d3 d4 c1 cd+                       .str    ↑“STAMINA”
8358: ff                                 .dd1    $ff
8359: 20 0c 60                           jsr     GAME2_PRNTSTR
835c: 8c                                 .dd1    $8c
835d: cc c5 d6 c5+                       .str    ↑“LEVEL OF SPIRIT”
836c: ff                                 .dd1    $ff
836d: a9 05                              lda     #$05                    ;6 values, accessed in reverse order ($27..$22)
836f: 85 7b                              sta     temp7b
8371: a4 7b        @loop3                ldy     temp7b
8373: b6 22                              ldx     dayNum,y                ;status values are sequential in zero page
8375: a0 00                              ldy     #$00
8377: 20 cc 84                           jsr     num_to_str
837a: a4 7b                              ldy     temp7b
837c: b9 11 84                           lda     status_digit_pos,y      ;position to print each value
837f: 85 64                              sta     HTAB
8381: a5 fc                              lda     digits+3                ;write the 2-digit, zero-padded value
8383: 20 0f 60                           jsr     GAME2_printchar
8386: e6 64                              inc     HTAB
8388: a5 fd                              lda     digits+4
838a: 20 0f 60                           jsr     GAME2_printchar
838d: c6 7b                              dec     temp7b
838f: a5 7b                              lda     temp7b
8391: 10 de                              bpl     @loop3
8393: 60                                 rts

8394: 04           player_name_idx       .dd1    $04                     ;oddly, an index into player names at $1AD0
8395: 09                                 .dd1    $09                     ;(pointing to the last char of each)
8396: 0e                                 .dd1    $0e
8397: 13                                 .dd1    $13
8398: 18                                 .dd1    $18
8399: c5 c1 d2 cc+ time_of_day_str       .str    ↑“EARLY MORNING  ”
83a8: cc c1 d4 c5+                       .str    ↑“LATE MORNING   ”
83b7: c5 c1 d2 cc+                       .str    ↑“EARLY AFTERNOON”
83c6: cc c1 d4 c5+                       .str    ↑“LATE AFTERNOON ”
83d5: c5 c1 d2 cc+                       .str    ↑“EARLY EVENING  ”
83e4: cc c1 d4 c5+                       .str    ↑“LATE EVENING   ”
83f3: cd c9 c4 ce+                       .str    ↑“MIDNIGHT       ”
8402: cc c1 d4 c5+                       .str    ↑“LATE NIGHT     ”
8411: 05           status_digit_pos      .dd1    $05                     ;positions for the 6 status numbers
8412: 9c                                 .dd1    $9c
8413: 74                                 .dd1    $74
8414: 4c                                 .dd1    $4c
8415: 81                                 .dd1    $81
8416: 5e                                 .dd1    $5e
8417: 0e           time_of_day_idx       .dd1    $0e                     ;index into times of day
8418: 1d                                 .dd1    $1d                     ;(pointing to the last char of each)
8419: 2c                                 .dd1    $2c
841a: 3b                                 .dd1    $3b
841b: 4a                                 .dd1    $4a
841c: 59                                 .dd1    $59
841d: 68                                 .dd1    $68
841e: 77                                 .dd1    $77

841f: 20 06 60     renew                 jsr     GAME2_cleartext
8422: 20 1b 60                           jsr     GAME2_teleport_home
8425: 20 0c 60                           jsr     GAME2_PRNTSTR
8428: 29                                 .dd1    $29
8429: d9 cf d5 a0+                       .str    ↑“YOU WERE FOUND UNCONSCIOUS.”
8444: ff                                 .dd1    $ff
8445: 20 4b 84                           jsr     time_has_passed
8448: 4c e3 7f                           jmp     message_wait

844b: 20 0c 60     time_has_passed       jsr     GAME2_PRNTSTR
844e: 51                                 .dd1    $51
844f: d4 c9 cd c5+                       .str    ↑“TIME HAS PASSED.”
845f: ff                                 .dd1    $ff
8460: 60                                 rts

                   ; There are 256 ticks per minute, $25 (or $23) minutes per period, and 8 periods
                   ; per day.
8461: a5 35        next_tick             lda     doorNeshom              ;time does not pass automatically
8463: d0 04                              bne     @rts                    ;in the neshom realm
8465: c6 7c                              dec     TICKS
8467: f0 01                              beq     next_minute
8469: 60           @rts                  rts

846a: c6 7d        next_minute           dec     MINUTES
846c: d0 fb                              bne     @rts
846e: a9 25                              lda     #$25
8470: 85 7d                              sta     MINUTES
8472: 4c 75 84                           jmp     next_time_period

                   ; Usually reached when game timer is running and minutes reaches 0. May also be
                   ; called when we are resting, or when passing out drunk.
8475: e6 21        next_time_period      inc     timeOfDay
8477: a5 21                              lda     timeOfDay
8479: c9 08                              cmp     #$08                    ;end of day?
847b: d0 06                              bne     check_time_expired
847d: a9 00                              lda     #$00                    ;yes, go to next day
847f: 85 21                              sta     timeOfDay
8481: e6 22                              inc     dayNum
8483: a5 22        check_time_expired    lda     dayNum
8485: c9 33                              cmp     #$33                    ;game over on day 50
8487: 90 09                              bcc     update_period_stats
8489: a9 00                              lda     #$00                    ;pause timer (permanently!)
848b: 85 87                              sta     TICKING
848d: a9 01                              lda     #$01
848f: 85 3d                              sta     GAMEOVER                ;game over, man
8491: 60                                 rts

8492: c6 24        update_period_stats   dec     levelFood
8494: 10 10                              bpl     @has_food               ;branch if food left
8496: a9 00                              lda     #$00                    ;food floor is 0
8498: 85 24                              sta     levelFood
849a: a5 87                              lda     TICKING                 ;don't starve if paused
849c: f0 08                              beq     @has_food               ;(paused when we are resting)
849e: a9 01                              lda     #$01
84a0: 85 3c                              sta     STARVED
84a2: a9 00                              lda     #$00                    ;pause timer
84a4: 85 87                              sta     TICKING
84a6: c6 25        @has_food             dec     levelRest
84a8: 10 10                              bpl     L84BA
84aa: a9 00                              lda     #$00                    ;rest floor is 0
84ac: 85 25                              sta     levelRest
84ae: a5 87                              lda     TICKING
84b0: f0 08                              beq     L84BA
84b2: a9 02                              lda     #$02
84b4: 85 3c                              sta     STARVED
84b6: a9 00                              lda     #$00
84b8: 85 87                              sta     TICKING
84ba: a5 23        L84BA                 lda     levelSpirit             ;spirit increases by 5 every period
84bc: 18                                 clc
84bd: 69 05                              adc     #$05
84bf: c5 27                              cmp     limitSpirit
84c1: 90 02                              bcc     L84C5
84c3: a5 27                              lda     limitSpirit             ;cap spirit at limit
84c5: 85 23        L84C5                 sta     levelSpirit
84c7: a9 23                              lda     #$23
84c9: 85 7d                              sta     MINUTES
84cb: 60                                 rts

                   ; Convert unsigned 16-bit value in (Y,X) to 5-digit string in $F9..$FD, left-
                   ; padded with zeroes. Uses standard 10s division algorithm, implemented via
                   ; subtraction on the 6502, of course.
                   ; 
                   ; ($7e/$7f are temps and only used in this subroutine.)
84cc: 86 7e        num_to_str            stx     temp7e
84ce: 84 7f                              sty     temp7f
84d0: a9 b0                              lda     #‘0’ | $80              ;the digit 0
84d2: a2 06                              ldx     #$06                    ;#$05 would also work fine
84d4: 95 f8        @loop                 sta     digits-1,x              ;set $f9..$fe to #$b0 ($fe unused)
84d6: ca                                 dex
84d7: d0 fb                              bne     @loop
                   ; 16-bit subtract the highest decimal place's value from the total value, until
                   ; it would underflow, and increase the digit that many times. Then move on to
                   ; the next digit. In other words, take quotient(x,10000), set x=remainder, take
                   ; quotient(x,1000), and so on.
84d9: 38           @loop2                sec                             ;x=0 on entry
84da: a5 7e                              lda     temp7e
84dc: fd f6 84                           sbc     tenslo,x
84df: a8                                 tay                             ;save
84e0: a5 7f                              lda     temp7f
84e2: fd fb 84                           sbc     tenshi,x
84e5: 10 06                              bpl     @inc
84e7: e8                                 inx                             ;next digit
84e8: e0 05                              cpx     #$05                    ;digits 0..4
84ea: d0 ed                              bne     @loop2
84ec: 60                                 rts

84ed: f6 f9        @inc                  inc     digits,x                ;'0' -> '1', etc.
84ef: 85 7f                              sta     temp7f
84f1: 84 7e                              sty     temp7e
84f3: 4c d9 84                           jmp     @loop2

                   ; Low and high 8 bits of decimal 10s places. E.g. 0x2710 = 10,000.
84f6: 10 e8 64 0a+ tenslo                .bulk   10e8640a01              ;10000,1000,100,10,1 (low 8 bits)
84fb: 27 03 00 00+ tenshi                .bulk   2703000000              ;10000,1000,100,10,1 (high 8 bits)
                   NOTE: The rest of the file $8500-$95FF appears to be junk
8500: 00 00 00 00+                       .junk   4352

Symbol Table

GAME2_action_menu$7700
GAME2_attacked$771e
GAME2_await_button_up$770c
GAME2_calc_hires_textpos$6042
GAME2_chkkey$6b27
GAME2_clearpages$6033
GAME2_cleartext$6006
GAME2_copypages$6030
GAME2_delay2$6036
GAME2_delayXtimes256$6012
GAME2_draw_player$6b03
GAME2_drawtile$6003
GAME2_erase_player$6b06
GAME2_examine$77ee
GAME2_init_item_state$603f
GAME2_intro$6027
GAME2_lose_weight$7712
GAME2_menu_input$6b2a
GAME2_message_wait$7706
GAME2_next_frame$6b00
GAME2_next_tick$771b
GAME2_num_to_str$7718
GAME2_ongoing_input$6b09
GAME2_play_melody$6024
GAME2_player_init$6039
GAME2_print_item_desc$770f
GAME2_printchar$600f
GAME2_PRNTSTR$600c
GAME2_read_0900$6021
GAME2_read_playfield$601e
GAME2_redraw_player$6b0c
GAME2_slot_to_item$7703
GAME2_swapzp8$6015
GAME2_teleport_home$601b
GAME2_tile_at_xy$6b1e
GAME2_txtpos_to_addr$7721
GAME2_win_game$6b24
GAME2_write_tiles_to_text$6009
GAME2_writetile$6045