********************************************************************************
* Golden Voyage for the Apple II *
* Game database created by William Demas and Scott Adams *
* Apple II interpreter reportedly written by Mak Jukic *
* Copyright 1981 Adventure International *
********************************************************************************
* Disassembly by Andy McFadden, using 6502bench SourceGen v1.7.5 *
* Last updated 2021/08/24 *
********************************************************************************
* The focus of this disassembly is on the interpreter. The game data itself *
* has received minimal formatting. *
* *
* The implementation uses 7 "virtual" 16-bit registers, stored in zero page *
* locations $f0-f1 through $fc-fd. Various operations are defined for these *
* registers, which may hold values or addresses. Most of the basic functions *
* preserve all CPU registers when called, including the status register. *
* *
* This can make the code a bit inefficient at times, e.g. copying $f0-f1 to *
* $f2-f3 requires a lot of pushing and popping, but the code is more compact *
* that way. The only other zero page locations used are those needed by the *
* monitor text routines and disk or tape I/O. *
* *
* It looks like the source code was broken into several pieces, which were *
* loaded at fixed addresses. This was likely done to make development easier *
* on a small system. Each chunk starts with a table of JMP instructions, a *
* few of which are actually just references to data tables with a JMP opcode *
* added to make the listing nicer. *
********************************************************************************
ITEM_HELD .eq $ff {const} ;room number of player's inventory
MON_WNDWDTH .eq $21 ;width of scroll window
MON_WNDTOP .eq $22 ;top of scroll window
MON_CH .eq $24 ;cursor horizontal displacement
MON_CV .eq $25 ;cursor vertical displacement
MON_BASL .eq $28 ;base address for text output (lo)
MON_A1L .eq $3c ;general purpose
MON_A1H .eq $3d ;general purpose
MON_A2L .eq $3e ;general purpose
MON_A2H .eq $3f ;general purpose
STACK .eq $0100 {addr/256} ;CPU stack
MON_USRADDR .eq $03f8 {addr/3} ;jump to function that handles monitor Ctrl-Y
KBD .eq $c000 ;R last key pressed + 128
KBDSTRB .eq $c010 ;RW keyboard strobe
MON_BASCALC .eq $fbc1 ;calculate text base address
MON_VIDOUT .eq $fbfd ;output Acc as text
MON_BS .eq $fc10 ;move cursor left
MON_HOME .eq $fc58 ;clear screen and reset text output to top-left
MON_CR .eq $fc62 ;perform a carriage return
MON_CLREOLZ .eq $fc9e
MON_COUT .eq $fded ;print Acc to output device via $36-37
MON_WRITE .eq $fecd ;write data to cassette
MON_READ .eq $fefd ;read data from cassette
MON_OLDRST .eq $ff59 ;RESET entry point
.org $0800
;
; Program entry point.
;
0800: 4c 27 08 Entry jmp Start
0803: 4c cc 0b J_PrintNonNull jmp PrintNonNull
0806: 4c c5 0b J_PrintCR jmp PrintCR
0809: 4c 6b 0b J_PrintL1Str jmp PrintL1Str
080c: 4c 62 0b J_PrintNChars jmp PrintNChars
080f: 4c 95 0b J_PrintString jmp PrintString
0812: 4c be 0b J_PrintFlashStr jmp PrintFlashStr
0815: 4c 37 0c J_GetInput jmp GetInput
0818: 4c b1 0c J_ClearScreen jmp ClearScreen
J_PrintSignedDec
081b: 4c ec 0f jmp PrintSignedDec
J_GetItemLocation
081e: 4c ca 0f jmp GetItemLocation
0821: 4c c2 0c J_PushRegs jmp PushRegs
0824: 4c f2 0c J_PopRegs jmp PopRegs
;
; Program initialization.
;
0827: a9 4c Start lda #$4c ;point monitor Ctrl+Y vector at game loop
0829: 8d f8 03 sta MON_USRADDR
082c: a9 4e lda #<MainLoop
082e: 8d f9 03 sta MON_USRADDR+1
0831: a9 08 lda #>MainLoop
0833: 8d fa 03 sta MON_USRADDR+2
0836: a2 ff ldx #$ff
0838: 9a txs ;reset 6502 stack
0839: 20 3c 2e jsr JJ_ClearScreen ;clear screen
083c: 20 0c 0d jsr GameInit ;initialize game state
083f: 20 5c 10 jsr AskRestoreGame ;restore saved game if desired
0842: 20 62 08 jsr PrintIntro ;print intro message
0845: 20 3c 2e jsr JJ_ClearScreen ;clear screen
0848: 20 15 2e jsr JJ_DescribeRoom ;describe current room
084b: 4c 57 08 jmp MainLoop2 ;jump into main loop
;
; Main game loop.
;
084e: 20 3c 0e MainLoop jsr GetCommand ;get a command from user
0851: 20 03 2e jsr JJ_ProcessActions ;process actions for that verb/noun
0854: 20 b7 0d jsr DecrementLampLevel ;decrement the lamp level
0857: a9 00 MainLoop2 lda #$00
0859: 8d bc 30 sta parsed_verb_idx ;zero out the verb
085c: 20 03 2e jsr JJ_ProcessActions ;process occurrences
085f: 4c 4e 08 jmp MainLoop ;loop
;
; Prints the introductory screen.
;
0862: 20 3c 2e PrintIntro jsr JJ_ClearScreen ;clear text screen
0865: 20 54 2e jsr InA_GetInlineData
0868: 96 08 .dd2 msg_intro1
086a: 20 36 2e jsr JJ_PrintString ;print first part of message
086d: 20 93 2e jsr InA_GetIndirectValue
0870: 53 30 .dd2 adventure_vers
0872: 20 48 2e jsr JJ_PrintSignedDec ;print version number
0875: 20 54 2e jsr InA_GetInlineData
0878: b8 08 .dd2 msg_intro2
087a: 20 36 2e jsr JJ_PrintString
087d: 20 54 2e jsr InA_GetInlineData
0880: 25 0b .dd2 msg_intro3
0882: 20 4b 2e jsr JJ_PrintFlashing ;please don't copy
0885: 20 54 2e jsr InA_GetInlineData
0888: 37 0b .dd2 msg_intro4
088a: 20 36 2e jsr JJ_PrintString
088d: 20 54 2e jsr InA_GetInlineData ;get pointer to intro text again (why?)
0890: b8 08 .dd2 msg_intro2
0892: 20 39 2e jsr JJ_GetInput ;wait for user to hit return
0895: 60 rts
;
; Intro message, formatted for 40 columns.
;
0896: 2a 20 41 44+ msg_intro1 .zstr ‘* ADAMS ADVENTURE * (VERSION 1.2/’
08b8: 29 0d 28 43+ msg_intro2 .zstr ‘)’,$0d,‘(C) ADVENTURE BOX 3435 LONGWOOD FL 327’
+ ‘50’,$0d,‘ THIS PROGRAM WILL ALLOW YOU TO HAVE’
+ ‘ AN ADVENTURE WITHOUT EVER LEAVING YOUR’,$0d
+ ‘ ARMCHAIR! YOU WILL FIND YOURSELF IN A’,$0d
+ ‘ STRANGE NEW WORLD. YOU'LL BE ABLE TO’,$0d,‘ E’
+ ‘XAMINE, TAKE AND OTHERWISE MANIPULATE THE OBJ’
+ ‘ECTS YOU FIND THERE. YOU WILL’,$0d,‘ ALSO BE A’
+ ‘BLE TO TRAVEL FROM LOCATION TO LOCATION.’,$0d
+ $0d,‘ I'LL BE YOUR PUPPET IN THIS ADVENTURE. Y’
+ ‘OU COMMAND ME WITH 2 WORD ENGLISH’,$0d,‘ SENTE’
+ ‘NCES. I DO HAVE OVER A 120 WORD’,$0d,‘ VOCABUL’
+ ‘ARY SO IF A WORD DOESN'T WORK’,$0d,‘ TRY ANOTH’
+ ‘ER!’,$0d,$0d,‘ SOME COMMANDS I KNOW: HELP, SAV’
+ ‘E GAME,’,$0d,‘ QUIT, SCORE, TAKE INVENTORY.’
+ $0d,$0d,‘THE AUTHOR HAS WORKED OVER A YEAR ON’
+ $0d,‘THIS PROGRAM SO ’
0b25: 50 4c 45 41+ msg_intro3 .zstr ‘PLEASE DON'T COPY’
0b37: 20 4f 52 0d+ msg_intro4 .zstr ‘ OR’,$0d,‘ACCEPT A PIRATED COPY! NOW HIT RETUR’
+ ‘N!’
;
; Prints a string that is N characters long. Does not output $00 bytes.
;
; On entry:
; $f0-f1: pointer to string
; A-reg: length of string
;
; On exit:
; (all registers preserved)
;
0b62: 20 57 2e PrintNChars jsr JJ_PushRegs ;preserve registers
0b65: 20 5d 2e jsr JJ_PushF0F1 ;preserve $f0-f1
0b68: 4c 78 0b jmp :Loop ;jump into loop with string len in A-reg
;
; Prints a string that starts with a length byte. Does not output $00 bytes.
;
; On entry:
; $f0-f1: pointer to start of string
;
; On exit:
; (all registers preserved)
;
]ptr .var $f0 {addr/2}
0b6b: 20 57 2e PrintL1Str jsr JJ_PushRegs ;preserve registers
0b6e: a0 00 ldy #$00
0b70: b1 f0 lda (]ptr),y ;get length byte
0b72: 20 5d 2e jsr JJ_PushF0F1 ;preserve $f0-f1
0b75: 20 51 2e jsr JJ_IncF0F1 ;advance pointer past it
0b78: c9 00 :Loop cmp #$00 ;reached the end?
0b7a: f0 12 beq :PopReturn ;yes, bail
0b7c: 38 sec
0b7d: e9 01 sbc #$01 ;reduce by 1
0b7f: 48 pha ;save remaining len
0b80: a0 00 ldy #$00
0b82: b1 f0 lda (]ptr),y ;get char
0b84: 20 51 2e jsr JJ_IncF0F1 ;advance pointer
0b87: 20 30 2e jsr JJ_PrintNonNull ;print char
0b8a: 68 pla ;restore remaining len
0b8b: 4c 78 0b jmp :Loop ;loop
0b8e: 20 60 2e :PopReturn jsr JJ_PopF0F1 ;restore $f0-f1
0b91: 20 5a 2e jsr JJ_PopRegs ;restore registers
0b94: 60 rts
;
; Prints a null-terminated string.
;
; On entry:
; $f0-f1: pointer to string
;
; On exit:
; (all registers preserved)
;
]str_ptr .var $f0 {addr/2}
0b95: 20 57 2e PrintString jsr JJ_PushRegs ;preserve registers
0b98: a9 01 lda #$01 ;set not flashing
0b9a: 8d af 2e PrintString1 sta noflash_flag
0b9d: 20 5d 2e jsr JJ_PushF0F1 ;preserve $f0-f1
0ba0: a0 00 :Loop ldy #$00 ;set to zero (and leave it there)
0ba2: b1 f0 lda (]str_ptr),y ;get char
0ba4: f0 e8 beq :PopReturn ;reached end, bail
0ba6: c9 0d cmp #$0d ;carriage return?
0ba8: f0 0b beq :DoPrint ;yes, print without modification
0baa: ac af 2e ldy noflash_flag ;flashing?
0bad: f0 04 beq :FlashMod ;yes, branch
0baf: 29 7f and #%01111111 ;make sure char has high bit clear
0bb1: d0 02 bne :DoPrint ;(branch always, unless char was $80)
0bb3: 09 c0 :FlashMod ora #%11000000 ;set bits so it'll be flashing after EOR #$80
0bb5: 20 30 2e :DoPrint jsr JJ_PrintNonNull ;print char
0bb8: 20 51 2e jsr JJ_IncF0F1 ;advance pointer
0bbb: 4c a0 0b jmp :Loop
;
; Prints a null-terminated string as flashing text.
;
; On entry:
; $f0-f1: pointer to string
;
; On exit:
; (all registers preserved)
;
0bbe: 20 57 2e PrintFlashStr jsr JJ_PushRegs ;preserve registers
0bc1: a9 00 lda #$00 ;set flashing
0bc3: f0 d5 beq PrintString1
;
; Prints a carriage return (clear to EOL, move CH/CV to start of new line).
;
0bc5: 20 57 2e PrintCR jsr JJ_PushRegs
0bc8: a9 0d lda #$0d ;carriage return
0bca: d0 03 bne PrintNonNull1 ;(always)
;
; Prints a character, unless it's $00, in which case we return immediately.
;
; If we output a non-space character at the start of a line, we back up to the
; end of the previous text line and look for a non-space character. If we find
; one, we keep looking until we find a space, and then redraw all the characters
; at the start of a new line. (This is how sentences are broken across lines at
; word boundaries.)
;
; On entry:
; A-reg: character to print ($00-7f)
;
; On exit:
; (all registers preserved)
;
0bcc: 20 57 2e PrintNonNull jsr JJ_PushRegs ;preserve registers
0bcf: c9 00 PrintNonNull1 cmp #$00 ;is it a null byte?
0bd1: d0 04 bne :DoPrint ;no, print it
0bd3: 20 5a 2e :PullReturn jsr JJ_PopRegs ;restore registers
0bd6: 60 rts
0bd7: c9 61 :DoPrint cmp #‘a’ ;see if this is a lower-case letter
0bd9: 90 07 bcc :NotLower
0bdb: c9 7b cmp #$7b ;'z'+1
0bdd: b0 03 bcs :NotLower
0bdf: 38 sec ;it is; convert to upper case
0be0: e9 20 sbc #$20
0be2: ea :NotLower nop
0be3: 49 80 eor #$80 ;flip high bit (to high for norm, low for flash)
0be5: c9 8a cmp #$8a ;linefeed?
0be7: d0 02 bne :NotLF ;no, branch
0be9: a9 a0 lda #$a0 ;replace with space
0beb: 48 :NotLF pha ;save character to print on stack
0bec: c9 8d cmp #$8d ;carriage return?
0bee: d0 0d bne :NotCR ;no, branch
; Found a CR, clear screen to end of line. MON_VIDOUT will set CH to zero and
; increment CV.
0bf0: a4 21 ldy MON_WNDWDTH ;get width of window
0bf2: 88 :EraseLoop dey ;move left
0bf3: c4 24 cpy MON_CH ;have we reached current output position?
0bf5: 30 06 bmi :NotCR ;yes, continue on
0bf7: a9 a0 lda #$a0
0bf9: 91 28 sta (MON_BASL),y ;store a space
0bfb: d0 f5 bne :EraseLoop
0bfd: 68 :NotCR pla ;restore character to print
0bfe: 48 pha ;save it again
0bff: 20 fd fb jsr MON_VIDOUT ;print it to the screen (updates CH/CV and BASL)
0c02: 68 pla ;restore it
0c03: c9 8d cmp #$8d ;carriage return?
0c05: f0 cc beq :PullReturn ;yes, bail
0c07: a0 01 ldy #$01
0c09: c4 24 cpy MON_CH ;at posn 1 (so char was output at posn 0)?
0c0b: d0 c6 bne :PullReturn ;no, bail
0c0d: a4 25 ldy MON_CV ;are we at the top of the screen?
0c0f: f0 c2 beq :PullReturn ;yes, bail
0c11: a2 00 ldx #$00 ;init saved-char count to zero
0c13: c9 a0 cmp #$a0 ;was it a space?
0c15: f0 bc beq :PullReturn ;yes, return
; We output a non-space character at offset 0. Back up to the end of the
; previous line to see if this was part of a longer word. Push chars on the
; stack as we erase them, output a CR, then output the chars.
;
; For the case where this was not part of a longer word, we will erase and
; redraw the original character.
0c17: ea :BackupLoop nop
0c18: 20 10 fc jsr MON_BS ;back up one space (updates CH/CV and BASL)
0c1b: a4 24 ldy MON_CH
0c1d: b1 28 lda (MON_BASL),y ;get char
0c1f: c9 a0 cmp #“ ” ;is it a space?
0c21: f0 08 beq :FoundBreak ;yes, found break
0c23: e8 inx ;no, increment count
0c24: 48 pha ;push char on stack
0c25: a9 a0 lda #“ ”
0c27: 91 28 sta (MON_BASL),y ;erase screen char
0c29: d0 ec bne :BackupLoop ;loop
0c2b: 20 62 fc :FoundBreak jsr MON_CR ;move to start of new line
0c2e: 68 :OutputLoop pla ;pull char
0c2f: 20 fd fb jsr MON_VIDOUT ;write on screen
0c32: ca dex ;done yet?
0c33: d0 f9 bne :OutputLoop ;no, loop
0c35: f0 9c beq :PullReturn ;yes, bail
;
; Gets up to 18 characters of input from the player. Returns when the player
; hits Return or types the 18th character. Handles backspace.
;
; Keys are written to an input buffer, terminated with $00.
;
]buf_ptr .var $f0 {addr/2}
0c37: 20 57 2e GetInput jsr JJ_PushRegs ;preserve registers
0c3a: 20 5d 2e jsr JJ_PushF0F1 ;preserve $f0-f1
0c3d: 20 54 2e jsr InA_GetInlineData ;get pointer to input buffer in $f0-f1
0c40: 32 2f .dd2 kbd_scratch_buf-1
0c42: a0 19 ldy #25 ;erase 24 bytes (+1)
0c44: a9 00 lda #$00
0c46: 91 f0 :ClearLoop sta (]buf_ptr),y
0c48: 88 dey
0c49: d0 fb bne :ClearLoop ;stop before writting to offset zero
;
0c4b: 20 54 2e jsr InA_GetInlineData
0c4e: 33 2f .dd2 kbd_scratch_buf
0c50: a4 24 ldy MON_CH ;get current horizontal text position
0c52: a2 00 ldx #$00 ;set X-reg to zero so we can use as index
0c54: b1 28 :SetFlashCursor lda (MON_BASL),y ;read value from screen
0c56: 29 3f and #%00111111 ;upper-case, low ASCII
0c58: 09 40 ora #%01000000 ;make it flash
0c5a: 91 28 sta (MON_BASL),y ;store on screen
;
0c5c: ee b0 2e :KeyLoop inc kbd_rng_seed ;increment random seed
0c5f: d0 03 bne :NoInc
0c61: ee b1 2e inc kbd_rng_seed+1
0c64: ad 00 c0 :NoInc lda KBD ;check for input
0c67: 10 f3 bpl :KeyLoop
;
0c69: 91 28 sta (MON_BASL),y ;store character on screen (incl. Ctrl+H / Ctrl+M)
0c6b: 49 80 eor #%10000000 ;strip high bit
0c6d: 2c 10 c0 bit KBDSTRB ;reset keyboard strobe
0c70: c9 08 cmp #$08 ;backspace key?
0c72: d0 1e bne :NotBackspace
;
0c74: 20 7e 2e jsr InA_SubF0F1_Inline ;subtract current position from initial position
0c77: 33 2f .dd2 kbd_scratch_buf
0c79: d0 06 bne :NotAtStart ;haven't backed up to start yet, branch
0c7b: a9 40 lda #$40 ;flashing space
0c7d: 91 28 sta (MON_BASL),y ;store on screen
0c7f: d0 db bne :KeyLoop ;loop
0c81: 20 4e 2e :NotAtStart jsr JJ_DecF0F1 ;decrement buffer pointer
0c84: 8a txa ;A-reg=0
0c85: 81 f0 sta (]buf_ptr,x) ;write zero to buffer
0c87: a9 a0 lda #“ ” ;high-ASCII space
0c89: 91 28 sta (MON_BASL),y ;write to screen (replaces $88 we just wrote)
0c8b: c6 24 dec MON_CH ;decrement text position
0c8d: 88 dey
0c8e: 91 28 sta (MON_BASL),y ;write to screen (replaces char we backed over)
0c90: d0 c2 bne :SetFlashCursor ;(always, assuming there's prompt text so Y-reg != 0)
;
0c92: c9 0d :NotBackspace cmp #$0d ;return key?
0c94: d0 0a bne :AddChar ;no, branch
; Return key hit, return input to caller.
0c96: 20 60 2e :FinishInput jsr JJ_PopF0F1 ;restore $f0-f1
0c99: 20 33 2e jsr JJ_PrintCR ;clear to EOL, move CH/CV to start of new line
0c9c: 20 5a 2e jsr JJ_PopRegs ;restore registers
0c9f: 60 rts
0ca0: 81 f0 :AddChar sta (]buf_ptr,x) ;add character to buffer
0ca2: e6 24 inc MON_CH ;advance text position
0ca4: c8 iny
0ca5: 20 51 2e jsr JJ_IncF0F1 ;advance buffer position
0ca8: 20 7e 2e jsr InA_SubF0F1_Inline ;have we input 18 chars?
0cab: 45 2f .dd2 kbd_scratch_buf+18
0cad: f0 e7 beq :FinishInput ;yes, accept line and bail
0caf: d0 a3 bne :SetFlashCursor ;no, loop (always)
;
; Clears the full screen. Resets the scroll window top.
;
0cb1: 20 57 2e ClearScreen jsr JJ_PushRegs ;preserve registers
0cb4: a9 00 lda #$00
0cb6: 8d 59 30 sta screen_cleared? ;?
0cb9: 85 22 sta MON_WNDTOP ;reset scroll window
0cbb: 20 58 fc jsr MON_HOME ;clear it
0cbe: 20 5a 2e jsr JJ_PopRegs ;restore registers
0cc1: 60 rts
;
; Pushes registers onto stack and returns to caller.
; Order: P A X Y.
;
; On exit:
; (all registers preserved)
;
0cc2: 8d ab 2e PushRegs sta regsv_tmp_a ;save A-reg
0cc5: 08 php ;save P-reg
0cc6: 68 pla
0cc7: 8d ac 2e sta regsv_tmp_p
0cca: 68 pla ;pull return address off stack
0ccb: 8d ad 2e sta regsv_ret_addr
0cce: 68 pla
0ccf: 8d ae 2e sta regsv_ret_addr+1
0cd2: ee ad 2e inc regsv_ret_addr ;increment return address so we jump to
0cd5: d0 03 bne :NoInc ; byte after the JSR
0cd7: ee ae 2e inc regsv_ret_addr+1
0cda: ea :NoInc nop
0cdb: ad ac 2e lda regsv_tmp_p ;push P-reg
0cde: 48 pha
0cdf: ad ab 2e lda regsv_tmp_a ;push A-reg
0ce2: 48 pha
0ce3: 8a txa ;push X-reg
0ce4: 48 pha
0ce5: 98 tya ;push Y-reg
0ce6: 48 pha
0ce7: ad ac 2e lda regsv_tmp_p ;push P-reg
0cea: 48 pha
0ceb: ad ab 2e lda regsv_tmp_a ;restore A-reg
0cee: 28 plp ;restore P-reg
0cef: 6c ad 2e jmp (regsv_ret_addr) ;resume execution at caller (same as RTS)
;
; Pops registers off stack and returns to caller.
; Order: Y X A P
;
; On exit:
; (all registers restored from stack)
;
0cf2: 68 PopRegs pla ;pull return address
0cf3: 8d ad 2e sta regsv_ret_addr
0cf6: 68 pla
0cf7: 8d ae 2e sta regsv_ret_addr+1
0cfa: ee ad 2e inc regsv_ret_addr ;increment return address so we jump to
0cfd: d0 03 bne :NoInc ; byte after the JSR
0cff: ee ae 2e inc regsv_ret_addr+1
0d02: ea :NoInc nop
0d03: 68 pla ;pull Y-reg
0d04: a8 tay
0d05: 68 pla ;pull X-reg
0d06: aa tax
0d07: 68 pla ;pull A-reg
0d08: 28 plp ;pull P-reg
0d09: 6c ad 2e jmp (regsv_ret_addr)
;
; Initializes game state. Puts objects in default locations, clears flags, etc.
;
]item_init_ptr .var $f0 {addr/2}
]item_cur_ptr .var $f2 {addr/2}
]table_len .var $f5 {addr/1}
0d0c: 20 93 2e GameInit jsr InA_GetIndirectValue ;get max item value into $f0-f1
0d0f: 6f 30 .dd2 hdr_max_item
0d11: 20 84 2e jsr JJ_SetF4F5_F0F1 ;copy to $f4-f5
0d14: 20 87 2e jsr JJ_AddF0F1_F4F5 ;add to itself
0d17: 20 84 2e jsr JJ_SetF4F5_F0F1 ;save in $f4-f5
0d1a: 20 93 2e jsr InA_GetIndirectValue ;get pointer to item location data
0d1d: 26 2f .dd2 item_rooms_ptr
0d1f: 20 81 2e jsr JJ_SetF2F3_F0F1 ;copy pointer to $f2-f3
0d22: 20 93 2e jsr InA_GetIndirectValue ;get pointer to ? in $f0-f1
0d25: 2a 2f .dd2 item_initroom_ptr
; Initialize item locations.
0d27: a0 00 ldy #$00
0d29: b1 f0 :Loop lda (]item_init_ptr),y ;get initial location
0d2b: 91 f2 sta (]item_cur_ptr),y ;copy to location data area
0d2d: 20 51 2e jsr JJ_IncF0F1 ;advance src ptr
0d30: 20 6c 2e jsr JJ_IncF2F3 ;advance dst ptr
0d33: 20 63 2e jsr JJ_DecF4F5 ;decrement length
0d36: a5 f5 lda ]table_len ;done yet?
0d38: 10 ef bpl :Loop ;no, loop
;
0d3a: ad 77 30 lda hdr_start_room ;set initial player location
0d3d: 8d e9 30 sta current_room
0d40: ad 78 30 lda hdr_start_room+1
0d43: 8d ea 30 sta current_room+1
0d46: ad 7b 30 lda hdr_lamp_capacity ;fill lightsource object
0d49: 8d 01 31 sta lamp_fuel_level
0d4c: ad 7c 30 lda hdr_lamp_capacity+1
0d4f: 8d 02 31 sta lamp_fuel_level+1
0d52: a9 00 lda #$00 ;clear debug flag
0d54: 8d 7d 30 sta debug_flag
; Clear all action flags (0-31).
0d57: 20 54 2e jsr InA_GetInlineData ;get pointer to flags
0d5a: c9 30 .dd2 action_flags
0d5c: a0 1f ldy #31
0d5e: 91 f0 :Loop sta (]item_init_ptr),y ;store zero
0d60: 88 dey
0d61: 10 fb bpl :Loop
0d63: 60 rts
;
; Finds a match for the trimmed string in the list of words. The caller points
; to either the verb list or the noun list, which are padded to be the same
; length.
;
; The trimmed word buffer and the items in the word list are both padded with
; trailing $00 bytes, so we can simply compare all N bytes (where N is
; configurable, 4 in this case).
;
; If we match on an alias, we return the index of the "base" word, and replace
; the word in the trim buffer with the base.
;
; On entry:
; $f0-f1: pointer to verb or noun collection
; (trimmed input word at $3080)
;
; On exit:
; Z-flag set if match found
; (word index in $309d)
;
]trim_verb .var $f0 {addr/2}
]word_list .var $f2 {addr/2}
0d64: ad 6b 30 FindWord lda hdr_max_nounverb ;get dictionary size
0d67: 8d 9e 30 sta tmp_save_reg2 ;use as counter
0d6a: 20 81 2e jsr JJ_SetF2F3_F0F1 ;copy word collection pointer into $f2-f3
0d6d: a9 00 lda #$00
0d6f: 8d 9d 30 sta tmp_save_reg1
0d72: 20 54 2e jsr InA_GetInlineData ;get pointer to trimmed word in $f0-f1
0d75: 80 30 .dd2 word_trim_buf ;this points at first char, but dictionary words
0d77: 20 4e 2e jsr JJ_DecF0F1 ; start with $00 or '*', so back up 1 to match
;
0d7a: ac 69 30 :CmpWord ldy hdr_word_len ;get word length (3/4/5)
0d7d: b1 f0 :CmpLoop lda (]trim_verb),y ;get char from trimmed input buffer
0d7f: d1 f2 cmp (]word_list),y ;compare to word in list
0d81: d0 22 bne :TryNext ;didn't match, branch
0d83: 88 dey ;tried all 4?
0d84: d0 f7 bne :CmpLoop ;no, branch
; If this word was an alias, back up until we find one that isn't.
0d86: b1 f2 :DeAlias lda (]word_list),y ;get first char (Y-reg=0)
0d88: c9 2a cmp #‘*’ ;is it an asterisk?
0d8a: d0 0e bne :NotAlias ;no, this word is not an alias
0d8c: ae 69 30 ldx hdr_word_len ;back up a full word
0d8f: 20 69 2e :BackLoop jsr JJ_DecF2F3 ;decrement pointer
0d92: ca dex ;done yet?
0d93: 10 fa bpl :BackLoop ;no, loop
0d95: ce 9d 30 dec tmp_save_reg1 ;adjust result value
0d98: d0 ec bne :DeAlias ;branch always (unless this was first word in list)
; Copy word from list back to trim buffer.
0d9a: ac 69 30 :NotAlias ldy hdr_word_len ;get word length
0d9d: b1 f2 :CopyLoop lda (]word_list),y ;copy word from word list into trim buffer; this
0d9f: 91 f0 sta (]trim_verb),y ; is a no-op unless the word was an alias
0da1: 88 dey
0da2: d0 f9 bne :CopyLoop
0da4: 60 rts ;return with Z-flag=1
0da5: ac 69 30 :TryNext ldy hdr_word_len ;get full word length
0da8: 20 6c 2e :IncrLoop jsr JJ_IncF2F3 ;increment pointer until we're at start of next
0dab: 88 dey ;done yet?
0dac: 10 fa bpl :IncrLoop ;no, loop
0dae: ee 9d 30 inc tmp_save_reg1 ;increment result value
0db1: ce 9e 30 dec tmp_save_reg2 ;done yet?
0db4: 10 c4 bpl :CmpWord ;no, loop
0db6: 60 rts ;return with Z-flag=0
;
; Reduces the lamp fuel level by 1, unless the lamp is in room 0 ("nowhere").
; If we drop below 25, print a warning. If we drop below 0, set the
; "lightsource empty" flag.
;
; It's up to the game to provide an action that removes the lightsource object
; (#9) from the player's inventory, e.g. replacing it with "empty lamp". If
; they don't, the object will continue to provide light, and we will continue to
; decrement the counter (until it rolls under).
;
]item_room .var $f0 {addr/2}
DecrementLampLevel
0db7: 20 93 2e jsr InA_GetIndirectValue
0dba: 26 2f .dd2 item_rooms_ptr
0dbc: a0 12 ldy #18 ;object #9 (lamp)
0dbe: b1 f0 lda (]item_room),y ;get current room (low byte)
0dc0: c8 iny
0dc1: 11 f0 ora (]item_room),y ;OR with current room (high byte)
0dc3: f0 26 beq :Return ;if it's in room zero, don't modify the fuel level
;
0dc5: 20 93 2e jsr InA_GetIndirectValue ;get lamp level in $f0-f1
0dc8: 01 31 .dd2 lamp_fuel_level
0dca: 20 4e 2e jsr JJ_DecF0F1 ;decrement
0dcd: 20 90 2e jsr InA_SetIndirectValue ;store value
0dd0: 01 31 .dd2 lamp_fuel_level
0dd2: ad 02 31 lda lamp_fuel_level+1 ;fuel level high byte nonzero?
0dd5: d0 14 bne :Return ;yes, got fuel, bail
0dd7: ad 01 31 lda lamp_fuel_level ;check low byte
0dda: 30 0f bmi :Return ;sub-zero, we've already complained, bail
0ddc: d0 0e bne :WarnLow ;not zero yet, print warning
; Counter just hit zero. Tell the player the bad news.
0dde: a9 ff lda #$ff
0de0: 8d d9 30 sta lamp_empty_flag ;set flag #16, indicating lamp is empty
0de3: 20 54 2e jsr InA_GetInlineData
0de6: 26 0e .dd2 msg_light_out
0de8: 20 4b 2e jsr JJ_PrintFlashing ;print "light has run out" message
0deb: 60 :Return rts
0dec: c9 19 :WarnLow cmp #25 ;do we have at least 25 moves left?
0dee: 10 fb bpl :Return ;yes, bail
0df0: 20 54 2e jsr InA_GetInlineData ;no, print warning message
0df3: 09 0e .dd2 msg_light_runs_out
0df5: 20 4b 2e jsr JJ_PrintFlashing ;flashing for emphasis
0df8: 20 93 2e jsr InA_GetIndirectValue ;get fuel level
0dfb: 01 31 .dd2 lamp_fuel_level
0dfd: 20 48 2e jsr JJ_PrintSignedDec ;print as integer
0e00: 20 54 2e jsr InA_GetInlineData
0e03: 1e 0e .dd2 msg_light_turns
0e05: 20 4b 2e jsr JJ_PrintFlashing
0e08: 60 rts
msg_light_runs_out
0e09: 0d 20 4c 49+ .zstr $0d,‘ LIGHT RUNS OUT IN ’
0e1e: 20 54 55 52+ msg_light_turns .zstr ‘ TURNS’,$0d
0e26: 0d 20 4c 49+ msg_light_out .zstr $0d,‘ LIGHT HAS RUN OUT!’,$0d
;
; Gets a line of input from the player, tokenizes it, and parse it into
; verb/noun. Converts single-character built-in commands like "I" and "N" into
; verbs.
;
; This does not return until it has received valid input.
;
; On exit:
; (parsed_verb_idx and parsed_noun_idx set)
; (input trim buffer holds trimmed noun)
;
]kbd_buf .var $f4 {addr/2}
0e3c: 20 54 2e GetCommand jsr InA_GetInlineData
0e3f: 3c 0f .dd2 msg_prompt
0e41: 20 36 2e jsr JJ_PrintString ;print prompt for command
0e44: 20 39 2e jsr JJ_GetInput ;get a buffer full of keystrokes
0e47: 20 54 2e jsr InA_GetInlineData ;get pointer to input buffer
0e4a: 33 2f .dd2 kbd_scratch_buf
0e4c: 20 84 2e jsr JJ_SetF4F5_F0F1 ;copy kbd input pointer to $f4-f5
; Look for a verb.
0e4f: 20 94 0f jsr TrimWord ;copy to buf, trimming whitespace; advances $f4-f5
0e52: ad 81 30 lda word_trim_buf+1 ;test for single-char command
0e55: d0 51 bne :MultiChar ;multi-char, branch
; Handle some built-in single-character commands.
0e57: ad 80 30 lda word_trim_buf ;get first char
0e5a: c9 58 cmp #‘X’ ;was it X?
0e5c: d0 06 bne :CheckP ;no, branch
0e5e: a9 00 lda #$00 ;set debug flat to 0
0e60: 8d 7d 30 :SetDebug sta debug_flag
0e63: 60 rts
0e64: c9 50 :CheckP cmp #‘P’ ;was it P?
0e66: d0 04 bne :CheckT ;no, branch
0e68: a9 01 lda #$01 ;set debug flag to 1
0e6a: d0 f4 bne :SetDebug
0e6c: c9 54 :CheckT cmp #‘T’ ;was it T?
0e6e: d0 04 bne :CheckI ;no, branch
0e70: a9 02 lda #$02 ;set debug flag to 2
0e72: d0 ec bne :SetDebug
0e74: c9 49 :CheckI cmp #‘I’ ;inventory?
0e76: d0 17 bne :CheckDir ;no, branch
0e78: a9 4e lda #‘N’ ;yes, stuff in chars to make it "INVE"
0e7a: 8d 81 30 sta word_trim_buf+1
0e7d: a9 56 lda #‘V’
0e7f: 8d 82 30 sta word_trim_buf+2
0e82: a9 45 lda #‘E’
0e84: 8d 83 30 sta word_trim_buf+3
0e87: d0 1f bne :MultiChar ;handle as multi-char entry
:direction_chars
0e89: 4e 53 45 57+ .str ‘NSEWUD’ ;north/south/east/west/up/down
]dc_ptr .var $f0 {addr/2}
0e8f: 20 54 2e :CheckDir jsr InA_GetInlineData ;get pointer to direction chars, -1 so result
0e92: 88 0e .dd2 :direction_chars-1 ; will be [1,6] instead of [0,5]
0e94: a0 06 ldy #6 ;6 chars in direction_chars
0e96: d1 f0 :DirLoop cmp (]dc_ptr),y ;match?
0e98: f0 05 beq :FoundDir ;yes, branch
0e9a: 88 dey ;done yet?
0e9b: d0 f9 bne :DirLoop ;no, branch
0e9d: f0 09 beq :MultiChar ;(always)
0e9f: 8c be 30 :FoundDir sty parsed_noun_idx ;save noun index (1-6)
0ea2: a9 01 lda #$01
0ea4: 8d bc 30 sta parsed_verb_idx
0ea7: 60 rts
; Find a match for a multi-character verb.
0ea8: 20 93 2e :MultiChar jsr InA_GetIndirectValue ;get pointer to verb table
0eab: 30 2f .dd2 verb_words_ptr
0ead: 20 64 0d jsr FindWord ;look for a matching word
0eb0: f0 1b beq :GotVerb ;found match, branch
0eb2: 20 54 2e jsr InA_GetInlineData ;didn't match, complain
0eb5: 53 0f .dd2 msg_dont_how
0eb7: 20 36 2e jsr JJ_PrintString
0eba: 20 54 2e jsr InA_GetInlineData
0ebd: 80 30 .dd2 word_trim_buf
0ebf: 20 4b 2e jsr JJ_PrintFlashing ;print verb, flashing
0ec2: 20 54 2e jsr InA_GetInlineData
0ec5: 6a 0f .dd2 msg_dont_how2
0ec7: 20 36 2e jsr JJ_PrintString
0eca: 4c 3c 0e jmp GetCommand ;go get a new command (w/o actions or lamp--)
0ecd: ad 9d 30 :GotVerb lda tmp_save_reg1 ;save verb index in global
0ed0: 8d bc 30 sta parsed_verb_idx
; Now look for a noun.
0ed3: 20 94 0f jsr TrimWord ;copy to buf, trimming whitespace; advances $f4-f5
0ed6: ad 80 30 lda word_trim_buf ;get first char of noun
0ed9: 8d be 30 sta parsed_noun_idx ;if it's $00, set the noun index to zero
0edc: f0 2b beq :Chk3 ; and branch (otherwise, parsed_noun_idx is garbage)
0ede: 20 93 2e jsr InA_GetIndirectValue ;get pointer to noun table
0ee1: 2e 2f .dd2 noun_words_ptr
0ee3: 20 64 0d jsr FindWord ;look for a matching word
0ee6: f0 1b beq :GotNoun ;found match, branch
0ee8: 20 54 2e jsr InA_GetInlineData ;didn't match, complain
0eeb: 78 0f .dd2 msg_dont_what
0eed: 20 36 2e jsr JJ_PrintString
0ef0: 20 54 2e jsr InA_GetInlineData ;print noun, flashing
0ef3: 80 30 .dd2 word_trim_buf
0ef5: 20 4b 2e jsr JJ_PrintFlashing
0ef8: 20 54 2e jsr InA_GetInlineData
0efb: 8d 0f .dd2 msg_dont_what2
0efd: 20 36 2e jsr JJ_PrintString
0f00: 4c 3c 0e jmp GetCommand ;go get a new command (w/o actions or lamp--)
0f03: ad 9d 30 :GotNoun lda tmp_save_reg1 ;save noun index in global
0f06: 8d be 30 sta parsed_noun_idx
; Check for a third word. $f4-f5 points at end of noun in kbd buf.
0f09: a0 00 :Chk3 ldy #$00
0f0b: b1 f4 :Chk3Loop lda (]kbd_buf),y ;get char
0f0d: d0 01 bne :AfterSpace ;not $00, check it
0f0f: 60 rts ;all good, return
0f10: c8 :AfterSpace iny ;advance to next char
0f11: c9 20 cmp #$20 ;was this one a space?
0f13: f0 f6 beq :Chk3Loop ;yes, keep looking
0f15: 20 54 2e jsr InA_GetInlineData ;no, they entered 3+ words
0f18: 20 0f .dd2 msg_max_2words
0f1a: 20 4b 2e jsr JJ_PrintFlashing ;complain
0f1d: 4c 3c 0e jmp GetCommand ;go get a new command (w/o actions or lamp--)
0f20: 20 55 53 45+ msg_max_2words .zstr ‘ USE NO MORE THAN 2 WORDS!’,$0d ;max two per customer
0f3c: 20 2d 2d 3e+ msg_prompt .zstr ‘ --> WHAT SHALL I DO? ’ ;basic command prompt
0f53: 0d 49 20 44+ msg_dont_how .zstr $0d,‘I DON'T KNOW HOW TO "’ ;unknown verb
0f6a: 22 20 53 4f+ msg_dont_how2 .zstr ‘" SOMETHING.’,$0d
0f78: 0d 49 20 44+ msg_dont_what .zstr $0d,‘I DON'T KNOW WHAT "’ ;unknown noun
0f8d: 22 20 49 53+ msg_dont_what2 .zstr ‘" IS.’,$0d
;
; Trims a word, copying it while stripping leading/trailing whitespace.
;
; On entry:
; $f4-f5: pointer to source data (key input buffer)
;
; On exit:
; $f4-f5: moved to first byte past end of input string
; (trimmed word in output buffer, terminated with $00)
;
• Clear variables
]trim_buf .var $f0 {addr/2}
]kbd_buf .var $f4 {addr/2}
0f94: 20 75 2e TrimWord jsr JJ_PushF2F3 ;preserve $f2-f3
0f97: a9 00 lda #$00
0f99: a0 17 ldy #23
0f9b: 20 54 2e jsr InA_GetInlineData ;get buffer pointer ($3080) in $f0-f1
0f9e: 80 30 .dd2 word_trim_buf
0fa0: 20 81 2e jsr JJ_SetF2F3_F0F1 ;copy $f0-f1 to $f2-f3 (why?)
0fa3: 91 f0 :ClearLoop sta (]trim_buf),y ;clear buffer to zeroes
0fa5: 88 dey
0fa6: 10 fb bpl :ClearLoop
;
0fa8: a2 00 ldx #$00 ;found-non-space flag
0faa: a0 00 ldy #$00 ;always zero
0fac: b1 f4 :GetLoop lda (]kbd_buf),y ;get char
0fae: 20 66 2e jsr JJ_IncF4F5 ;advance kbd buf pointer (preserves flags)
0fb1: d0 04 bne :CheckSpace ;if it's not $00, branch
0fb3: 20 78 2e :PopReturn jsr JJ_PopF2F3 ;all done; restore $f2-f3
0fb6: 60 rts
0fb7: c9 20 :CheckSpace cmp #‘ ’ ;is it a space?
0fb9: d0 06 bne :NotSpace ;no, branch
0fbb: e0 00 cpx #$00 ;have we found a non-space char yet?
0fbd: f0 ed beq :GetLoop ;no, skip over leading space
0fbf: d0 f2 bne :PopReturn ;yes, found end of word; branch
0fc1: 91 f0 :NotSpace sta (]trim_buf),y ;copy to trim buffer
0fc3: 20 51 2e jsr JJ_IncF0F1 ;advance output pointer
0fc6: a2 01 ldx #$01 ;set found-non-space flag
0fc8: d0 e2 bne :GetLoop ;(always)
;
; Get item's current location.
;
; On entry:
; $f0-f1: index of item
;
; On exit:
; $f0-f1: pointer to location data in item table
; A-reg: room number
; (X-reg and Y-reg preserved)
;
0fca: 8e 9d 30 GetItemLocation stx tmp_save_reg1
0fcd: 20 6f 2e jsr JJ_PushF4F5 ;preserve $f4-f5
0fd0: 20 84 2e jsr JJ_SetF4F5_F0F1 ;set $f4-f5 = $f0-f1
0fd3: 20 87 2e jsr JJ_AddF0F1_F4F5 ;$f0-f1 += $f4-f5 (i.e. double the value)
0fd6: 20 84 2e jsr JJ_SetF4F5_F0F1 ;set $f4-f5 = $f0-f1
0fd9: 20 93 2e jsr InA_GetIndirectValue ;get pointer to item room data
0fdc: 26 2f .dd2 item_rooms_ptr
0fde: 20 87 2e jsr JJ_AddF0F1_F4F5 ;add doubled index
0fe1: 20 72 2e jsr JJ_PopF4F5 ;restore $f4-f5
0fe4: a2 00 ldx #$00
0fe6: a1 f0 lda (]trim_buf,x) ;get room number
0fe8: ae 9d 30 ldx tmp_save_reg1
0feb: 60 rts
;
; Prints a 16-bit integer as a signed decimal value.
;
; On entry:
; $f0-f1: value to print
;
]value .var $f0 {addr/2}
]rem .var $f2 {addr/1}
]out_ptr .var $f4 {addr/2}
0fec: 20 8a 2e PrintSignedDec jsr JJ_PushFullState ;preserve all regs and ZP
0fef: a5 f0 lda ]value ;stash value in temporary mem
0ff1: 8d 9d 30 sta tmp_save_reg1
0ff4: a5 f1 lda ]value+1
0ff6: 8d 9e 30 sta tmp_save_reg2
0ff9: 20 54 2e jsr InA_GetInlineData ;get pointer to output buffer, past the length byte
0ffc: b6 30 .dd2 dec_outbuf+1
0ffe: a0 05 ldy #$05 ;max of six chars (e.g. "-32767")
1000: a9 00 :ClearLoop lda #$00
1002: 91 f0 sta (]value),y ;zero out the output buffer
1004: 88 dey
1005: 10 f9 bpl :ClearLoop
;
1007: ad 9e 30 lda tmp_save_reg2 ;check the high byte
100a: 10 16 bpl :IsPos ;it's positive, branch
100c: a9 2d lda #‘-’
100e: 8d b6 30 sta dec_outbuf+1 ;output a minus sign
1011: 38 sec ;negate the value so we're working
1012: a9 00 lda #$00 ; with a positive number
1014: ed 9d 30 sbc tmp_save_reg1 ; (this has classic issue with -32768)
1017: 8d 9d 30 sta tmp_save_reg1
101a: a9 00 lda #$00
101c: ed 9e 30 sbc tmp_save_reg2
101f: 8d 9e 30 sta tmp_save_reg2
1022: 20 54 2e :IsPos jsr InA_GetInlineData ;get pointer to output buffer
1025: b6 30 .dd2 dec_outbuf+1
1027: 20 84 2e jsr JJ_SetF4F5_F0F1 ;put pointer in $f4-f5
102a: 20 93 2e jsr InA_GetIndirectValue ;load positive value into $f0-f1
102d: 9d 30 .dd2 tmp_save_reg1
102f: a0 05 ldy #$05 ;start at offset 5
1031: 20 81 2e :OutLoop jsr JJ_SetF2F3_F0F1 ;set $f2-f3 to $f0-f1
1034: 20 54 2e jsr InA_GetInlineData ;set $f0-f1 to 10
1037: 0a 00 .dd2 10
1039: 20 21 2e jsr JJ_Divide16 ;divide by 10
103c: a5 f2 lda ]rem ;get remainder
103e: 09 30 ora #‘0’ ;convert to ASCII digit
1040: 91 f4 sta (]out_ptr),y ;store in output buffer
1042: a5 f0 lda ]value ;are we done yet?
1044: 05 f1 ora ]value+1
1046: f0 03 beq :OutputDone ;yes, branch
1048: 88 dey ;no, reduce index
1049: d0 e6 bne :OutLoop ;and loop
;
104b: a0 06 :OutputDone ldy #$06
104d: 8c b5 30 sty dec_outbuf ;set the length to 6 characters
1050: 20 54 2e jsr InA_GetInlineData ;get pointer to output buffer
1053: b5 30 .dd2 dec_outbuf
1055: 20 42 2e jsr JJ_PrintL1Str ;print string, ignoring leading $00 bytes
1058: 20 8d 2e jsr JJ_PopFullState ;restore all regs and ZP
105b: 60 rts
;
; Asks the user if they want to restore a saved game. If the answer is yes,
; this proceeds to do the restore.
;
105c: 20 54 2e AskRestoreGame jsr InA_GetInlineData
105f: 0a 11 .dd2 msg_restore_game
1061: 20 36 2e jsr JJ_PrintString ;ask if they want to restore a game
1064: 20 39 2e jsr JJ_GetInput ;get line of input
1067: ad 33 2f lda kbd_scratch_buf ;check first char
106a: c9 59 cmp #‘Y’ ;yes?
106c: f0 05 beq :DoLoad ;yes, do it
106e: c9 4e cmp #‘N’ ;no?
1070: d0 ea bne AskRestoreGame ;none of the above, loop
1072: 60 rts
1073: 20 1b 2e :DoLoad jsr JJ_AskDiskOrTape ;ask if they want disk or tape
1076: ad b2 2e lda use_disk_flag ;check flag
1079: f0 19 beq :FromTape1 ;go do tape
107b: 20 54 2e jsr InA_GetInlineData ;get pointer to DOS command string
107e: e3 10 .dd2 dos_load_cmd
1080: a9 31 lda #‘1’ ;set filename for part 1
1082: 8d ef 10 sta dos_load_cmd+12
1085: ad 57 30 lda adventure_num ;set adventure number in filename
1088: 8d f0 10 sta dos_load_cmd+13 ; (will be a control character)
108b: 20 1e 2e jsr JJ_PrintStringCOUT ;issue DOS command to load file #1
108e: ee ef 10 inc dos_load_cmd+12 ;increment digit for part 2
1091: 4c 97 10 jmp :CheckPart1
1094: 20 33 11 :FromTape1 jsr ReadTape ;read data from tape
;
1097: 20 93 2e :CheckPart1 jsr InA_GetIndirectValue ;get adventure number (12 in our case)
109a: 57 30 .dd2 adventure_num
109c: 20 7b 2e jsr InA_SubF0F1_Ind ;subtract value we read from file
109f: 33 2f .dd2 kbd_scratch_buf
10a1: f0 0b beq :Part1Good ;if they match, continue
10a3: 20 54 2e jsr InA_GetInlineData
10a6: f3 10 .dd2 msg_bad_save
10a8: 20 36 2e jsr JJ_PrintString ;complain about saved game
10ab: 4c 5c 10 jmp AskRestoreGame ;ask again
; Copy $2f35-2f71 to $30c7-3103 (flags, counters, current room etc.).
10ae: a2 3c :Part1Good ldx #$3c
10b0: bd 35 2f :Loop lda save_game_data,x ;read from scratch area
10b3: 9d c7 30 sta counter_register,x ;write to state area
10b6: ca dex
10b7: 10 f7 bpl :Loop
;
10b9: ad b2 2e lda use_disk_flag ;disk or tape?
10bc: f0 0b beq :FromTape2 ;tape, branch
10be: 20 54 2e jsr InA_GetInlineData
10c1: e3 10 .dd2 dos_load_cmd
10c3: 20 1e 2e jsr JJ_PrintStringCOUT ;issue DOS command to load file #2
10c6: 4c cc 10 jmp :ReadCommon
10c9: 20 33 11 :FromTape2 jsr ReadTape ;read part 2 from tape
; Copy item location data from file #2.
]item_room .var $f0 {addr/2}
10cc: a0 00 :ReadCommon ldy #$00
10ce: a2 ff ldx #$ff ;init to -1
10d0: 20 93 2e jsr InA_GetIndirectValue
10d3: 26 2f .dd2 item_rooms_ptr
10d5: e8 :Loop inx
10d6: bd 33 2f lda kbd_scratch_buf,x ;copy location value
10d9: 91 f0 sta (]item_room),y
10db: c8 iny
10dc: c8 iny
10dd: ec 6f 30 cpx hdr_max_item ;all items done?
10e0: d0 f3 bne :Loop ;no, loop
10e2: 60 rts
; DOS 3.3 load command. The last two characters are modified by the code.
10e3: 0d 04 42 4c+ dos_load_cmd .zstr $0d,$04,‘BLOAD AREC2’,$05,$0d
10f3: 20 42 41 44+ msg_bad_save .zstr ‘ BAD SAVE FILE FOUND!’,$0d
msg_restore_game
110a: 57 41 4e 54+ .zstr ‘WANT TO RESTORE PREVIOUSLY’,$0d,‘ SAVED GAME? ’
;
; Reads data from tape. We're expecting 256 bytes.
;
1133: a9 33 ReadTape lda #<kbd_scratch_buf ;set buffer pointer
1135: 85 3c sta MON_A1L
1137: a9 2f lda #>kbd_scratch_buf
1139: 85 3d sta MON_A1H
113b: 20 fd fe jsr MON_READ ;invoke monitor tape read routine
113e: 60 rts
113f: 74 68 72 6f+ .align $0400 (705 bytes)
J_SetIndirectValue
1400: 4c 55 14 jmp SetIndirectValue
1403: 4c eb 14 J_PushF0F1 jmp PushF0F1
1406: 4c f3 14 J_PopF0F1 jmp PopF0F1
1409: 4c db 14 J_PushF4F5 jmp PushF4F5
140c: 4c e3 14 J_PopF4F5 jmp PopF4F5
140f: 4c fb 14 J_PushF2F3 jmp PushF2F3
1412: 4c 03 15 J_PopF2F3 jmp PopF2F3
1415: 4c 34 15 J_PushFullState jmp PushFullState
1418: 4c 69 15 J_PopFullState jmp PopFullState
141b: 4c 8e 15 J_IncF0F1 jmp IncF0F1
141e: 4c 97 15 J_IncF4F5 jmp IncF4F5
1421: 4c a1 15 J_IncF2F3 jmp IncF2F3
1424: 4c c5 15 J_DecF0F1 jmp DecF0F1
1427: 4c bd 15 J_DecF4F5 jmp DecF4F5
142a: 4c cd 15 J_DecF2F3 jmp DecF2F3
142d: 4c ea 15 J_SetF2F3_F0F1 jmp SetF2F3_F0F1
1430: 4c e2 15 J_SetF4F5_F0F1 jmp SetF4F5_F0F1
1433: 4c 29 16 J_SubF0F1_Ind jmp SubF0F1_Ind
J_SubF0F1_Inline
1436: 4c 18 16 jmp SubF0F1_Inline
1439: 4c 3d 16 J_AddF0F1_F4F5 jmp AddF0F1_F4F5
143c: 4c 64 16 J_GetInlineData jmp GetInlineData
J_GetIndirectValue
143f: 4c 4f 16 jmp GetIndirectValue
1442: 4c 13 15 J_PushF6F7 jmp PushF6F7
1445: 4c 0b 15 J_PopF6F7 jmp PopF6F7
1448: 4c 23 15 J_PushF8F9 jmp PushF8F9
144b: 4c 1b 15 J_PopF8F9 jmp PopF8F9
144e: 4c 2b 15 J_IncF8F9 jmp IncF8F9
1451: 30 1a ind_jmp_1 .dd2 $1a30
1453: d8 18 ind_jmp_2 .dd2 $18d8
;
; Stores a 16-bit value to a location specified by a pointer in inline data that
; follows the caller's caller.
;
; On entry:
; $f0-f1: value to store
;
; On exit:
; $fc-fd: pointer from inline data
;
]arg .var $f0 {addr/2}
]dest_ptr .var $fc {addr/2}
SetIndirectValue
1455: 20 57 2e jsr JJ_PushRegs
1458: 20 6a 14 jsr GetCCInlineValue ;get pointer in $fc-fd
145b: a0 00 ldy #$00
145d: a5 f0 lda ]arg
145f: 91 fc sta (]dest_ptr),y ;write value to pointer
1461: c8 iny
1462: a5 f1 lda ]arg+1
1464: 91 fc sta (]dest_ptr),y
1466: 20 5a 2e jsr JJ_PopRegs
1469: 60 rts
;
; Gets the inline data that follows the caller's caller, and modifies the return
; address to skip over it. The data is usually a pointer, so this is a way to
; load a fixed address into $fc-fd.
;
; The caller does this:
; JSR func
; .dd2 <addr>
; Then func does this:
; JSR PushRegs (pushes 4 Y/X/A/P on stack)
; JSR <this function>
;
; So the stack is:
; 2 byte caller return address
; 4 byte saved registers
; 2 byte caller's caller return address
;
; So we need to get the caller's caller address from SP +7/+8, and load the
; values we find there. We then want to modify the caller's caller return
; address to skip over the data.
;
; On entry:
; stack as described above
;
; On exit:
; $fa-fb hold caller's caller address
; $fc-fd hold 16-bit inline data value
;
• Clear variables
]caller_ptr .var $fa {addr/2}
]result_ptr .var $fc {addr/2}
GetCCInlineValue
146a: ba tsx ;get stack pointer
146b: bd 07 01 lda STACK+7,x ;get caller's caller address
146e: 85 fa sta ]caller_ptr
1470: bd 08 01 lda STACK+8,x
1473: 85 fb sta ]caller_ptr+1
1475: a0 01 ldy #$01 ;move past last byte of instruction
1477: b1 fa lda (]caller_ptr),y ;copy inline data to zero page
1479: 85 fc sta ]result_ptr
147b: c8 iny
147c: b1 fa lda (]caller_ptr),y
147e: 85 fd sta ]result_ptr+1
1480: bd 07 01 lda STACK+7,x ;modify caller's caller address
1483: 18 clc
1484: 69 02 adc #$02 ;add 2 to skip over inline data
1486: 9d 07 01 sta STACK+7,x
1489: bd 08 01 lda STACK+8,x
148c: 69 00 adc #$00
148e: 9d 08 01 sta STACK+8,x
1491: 60 rts
;
; Loads a 16-bit value from zero page and pushes it onto the stack.
;
; On entry:
; X-reg: index into zero page
; (caller's previous X-reg value stashed at $14da)
;
; On exit:
; value from ZP pushed on stack
; (all registers preserved)
;
• Clear variables
]saved_areg .var $fa {addr/1}
]saved_preg .var $fb {addr/1}
]jmp_addr .var $fc {addr/2}
1492: 85 fa Push16Idx sta ]saved_areg ;save A-reg
1494: 68 pla ;pull P-reg we saved earlier
1495: 85 fb sta ]saved_preg ;save that
1497: 68 pla ;pull return address
1498: 85 fc sta ]jmp_addr
149a: 68 pla
149b: 85 fd sta ]jmp_addr+1
149d: e6 fc inc ]jmp_addr ;increment return addr so we jump past JSR
149f: d0 02 bne :NoInc
14a1: e6 fd inc ]jmp_addr+1
14a3: ea :NoInc nop
14a4: b5 01 lda $01,x ;get 16-bit value from zero page
14a6: 48 pha ; and push on stack
14a7: b5 00 lda $00,x
14a9: 48 pha
14aa: ae da 14 ldx tmp_save_x ;restore X-reg
14ad: a5 fb lda ]saved_preg
14af: 48 pha
14b0: a5 fa lda ]saved_areg ;restore A-reg
14b2: 28 plp ;restore P-reg
14b3: 6c fc 00 jmp ($00fc) ;return to caller
;
; Pulls a 16-bit value from the stack and stores it in zero page.
;
; On entry:
; X-reg: index into zero page
; (caller's previous X-reg value stashed at $14da)
;
; On exit:
; value from top of stack written to ZP
; (all registers preserved)
;
14b6: 85 fa Pop16Idx sta ]saved_areg ;save A-reg
14b8: 68 pla ;pull P-reg we saved earlier
14b9: 85 fb sta ]saved_preg ;save that
14bb: 68 pla ;pull return address
14bc: 85 fc sta ]jmp_addr
14be: 68 pla
14bf: 85 fd sta ]jmp_addr+1
14c1: e6 fc inc ]jmp_addr ;increment return addr so we jump past JSR
14c3: d0 02 bne :NoInc
14c5: e6 fd inc ]jmp_addr+1
14c7: ea :NoInc nop
14c8: 68 pla ;pull 16-bit value from stack and store
14c9: 95 00 sta $00,x ; in zero page
14cb: 68 pla
14cc: 95 01 sta $01,x
14ce: ae da 14 ldx tmp_save_x ;restore X-reg
14d1: a5 fb lda ]saved_preg
14d3: 48 pha
14d4: a5 fa lda ]saved_areg ;restore A-reg
14d6: 28 plp ;restore P-reg
14d7: 6c fc 00 jmp ($00fc) ;return to caller
14da: 05 tmp_save_x .dd1 $05
;
; Pushes $f4-f5 onto stack.
;
• Clear variables
14db: 08 PushF4F5 php
14dc: 8e da 14 stx tmp_save_x
14df: a2 f4 ldx #$f4
14e1: d0 af bne Push16Idx ;(always)
;
; Pops $f4-f5 off of stack.
;
14e3: 8e da 14 PopF4F5 stx tmp_save_x
14e6: 08 php
14e7: a2 f4 ldx #$f4
14e9: d0 cb bne Pop16Idx ;(always)
;
; Pushes $f0-f1 onto stack.
;
14eb: 08 PushF0F1 php ;save P-reg
14ec: 8e da 14 stx tmp_save_x ;save X-reg
14ef: a2 f0 ldx #$f0
14f1: d0 9f bne Push16Idx ;(always)
;
; Pops $f0-f1 off of stack.
;
14f3: 08 PopF0F1 php
14f4: 8e da 14 stx tmp_save_x
14f7: a2 f0 ldx #$f0
14f9: d0 bb bne Pop16Idx ;(always)
;
; Pushes $f2-f3 onto stack.
;
14fb: 08 PushF2F3 php
14fc: 8e da 14 stx tmp_save_x
14ff: a2 f2 ldx #$f2
1501: d0 8f B_Push16Idx bne Push16Idx ;(always)
;
; Pops $f2-f3 off of stack.
;
1503: 08 PopF2F3 php
1504: 8e da 14 stx tmp_save_x
1507: a2 f2 ldx #$f2
1509: d0 ab B_Pop16Idx bne Pop16Idx ;(always)
;
; Pops $f6-f7 off of stack.
;
150b: 08 PopF6F7 php
150c: 8e da 14 stx tmp_save_x
150f: a2 f6 ldx #$f6
1511: d0 f6 bne B_Pop16Idx ;(always)
;
; Pushes $f6-f7 onto stack.
;
1513: 08 PushF6F7 php
1514: 8e da 14 stx tmp_save_x
1517: a2 f6 ldx #$f6
1519: d0 e6 bne B_Push16Idx ;(always)
;
; Pops $f8-f9 off of stack.
;
151b: 08 PopF8F9 php
151c: 8e da 14 stx tmp_save_x
151f: a2 f8 ldx #$f8
1521: d0 e6 bne B_Pop16Idx ;(always)
;
; Pushes $f8-f9 onto stack.
;
1523: 08 PushF8F9 php
1524: 8e da 14 stx tmp_save_x
1527: a2 f8 ldx #$f8
1529: d0 d6 bne B_Push16Idx ;(always)
;
; Increments $f8-f9. Preserves all registers.
;
152b: 08 IncF8F9 php
152c: e6 f8 inc $f8
152e: d0 65 bne PlpReturn
1530: e6 f9 inc $f9
1532: 28 plp
1533: 60 rts
;
; Pushes registers and $f0-f9 onto the stack.
;
; Preserves all registers except parts of P.
;
1534: 08 PushFullState php ;push P-reg
1535: 8d 51 14 sta ind_jmp_1 ;save A-reg
1538: 68 pla ;get P-reg
1539: 8d 52 14 sta ind_jmp_1+1 ;save P-reg
153c: 68 pla ;pull return address
153d: 8d 53 14 sta ind_jmp_2 ;store it
1540: 68 pla
1541: 8d 54 14 sta ind_jmp_2+1
1544: ad 52 14 lda ind_jmp_1+1 ;get P-reg
1547: 48 pha ;push on stack
1548: ad 51 14 lda ind_jmp_1 ;restore A-reg
154b: 28 plp ;restore P-reg
;
154c: 20 57 2e jsr JJ_PushRegs ;push AXYP
154f: 20 5d 2e jsr JJ_PushF0F1 ;push $f0 through $f9
1552: 20 6f 2e jsr JJ_PushF4F5
1555: 20 75 2e jsr JJ_PushF2F3
1558: 20 96 2e jsr JJ_PushF6F7
155b: 20 9c 2e jsr JJ_PushF8F9
155e: ee 53 14 inc ind_jmp_2 ;increment return address past end of JSR
1561: d0 03 bne :NoInc
1563: ee 54 14 inc ind_jmp_2+1
1566: 6c 53 14 :NoInc jmp (ind_jmp_2) ;jump back to caller
;
; Pops registers and $f0-f9 from the stack.
;
1569: 68 PopFullState pla ;pull return address
156a: 8d 51 14 sta ind_jmp_1 ;store it
156d: 68 pla
156e: 8d 52 14 sta ind_jmp_1+1
1571: 20 9f 2e jsr JJ_PopF8F9 ;pop $f0 through $f9
1574: 20 99 2e jsr JJ_PopF6F7
1577: 20 78 2e jsr JJ_PopF2F3
157a: 20 72 2e jsr JJ_PopF4F5
157d: 20 60 2e jsr JJ_PopF0F1
1580: 20 5a 2e jsr JJ_PopRegs ;pop AXYP
1583: ee 51 14 inc ind_jmp_1 ;increment return address past end of JSR
1586: d0 03 bne :NoInc
1588: ee 52 14 inc ind_jmp_1+1
158b: 6c 51 14 :NoInc jmp (ind_jmp_1) ;jump back to caller
158e: 08 IncF0F1 php
158f: e6 f0 inc $f0
1591: d0 02 bne PlpReturn
1593: e6 f1 inc $f1
1595: 28 PlpReturn plp
1596: 60 rts
;
; Increments $f4-f5. Preserves all registers.
;
1597: 08 IncF4F5 php
1598: e6 f4 inc $f4
159a: d0 f9 bne PlpReturn
159c: e6 f5 inc $f5
159e: 4c 95 15 jmp PlpReturn
;
; Increments $f2-f3. Preserves all registers.
;
15a1: 08 IncF2F3 php
15a2: e6 f2 inc $f2
15a4: d0 ef bne PlpReturn
15a6: e6 f3 inc $f3
15a8: 4c 95 15 jmp PlpReturn
;
; Decrements a 16-bit zero-page value.
;
; On entry:
; X-reg: index into zero page
; stack holds saved P-reg and A-reg
;
; On exit:
; (all registers from original call preserved)
;
15ab: 38 Dec16Idx sec
15ac: b5 00 lda $00,x
15ae: e9 01 sbc #$01
15b0: 95 00 sta $00,x
15b2: b5 01 lda $01,x
15b4: e9 00 sbc #$00
15b6: 95 01 sta $01,x
15b8: 68 pla
15b9: aa tax
15ba: 68 pla
15bb: 28 plp
15bc: 60 rts
;
; Decrements $f4-f5. Preserves all registers.
;
15bd: 08 DecF4F5 php
15be: 48 pha
15bf: 8a txa
15c0: 48 pha
15c1: a2 f4 ldx #$f4
15c3: d0 e6 bne Dec16Idx
;
; Decrements $f0-f1. Preserves all registers.
;
15c5: 08 DecF0F1 php
15c6: 48 pha
15c7: 8a txa
15c8: 48 pha
15c9: a2 f0 ldx #$f0
15cb: d0 de bne Dec16Idx
;
; Decrements $f2-f3. Preserves all registers.
;
15cd: 08 DecF2F3 php
15ce: 48 pha
15cf: 8a txa
15d0: 48 pha
15d1: a2 f2 ldx #$f2
15d3: d0 d6 bne Dec16Idx
;
; Sets a 16-bit zero-page value.
;
; On entry:
; X-reg: index into zero page
; $f0-f1: value to store
; stack holds saved P-reg and A-reg
;
; On exit:
; (all registers from original call preserved)
;
]value .var $f0 {addr/2}
15d5: a5 f0 Set16Idx lda ]value ;set ZP value
15d7: 95 00 sta $00,x
15d9: a5 f1 lda ]value+1
15db: 95 01 sta $01,x
15dd: 68 pla
15de: aa tax
15df: 68 pla
15e0: 28 plp
15e1: 60 rts
;
; Sets $f4-f5 to the value in $f0-f1. Preserves all registers.
;
15e2: 08 SetF4F5_F0F1 php
15e3: 48 pha
15e4: 8a txa
15e5: 48 pha
15e6: a2 f4 ldx #$f4
15e8: d0 eb bne Set16Idx
;
; Sets $f2-f3 to the value in $f0-f1. Preserves all registers.
;
15ea: 08 SetF2F3_F0F1 php
15eb: 48 pha
15ec: 8a txa
15ed: 48 pha
15ee: a2 f2 ldx #$f2
15f0: d0 e3 bne Set16Idx
;
; Computes (value1 - value2) and stores the result in value2. Sets Z/C flags
; based on result.
;
; On entry:
; $f0-f1: value1
; $fa-fb: value2
; (preserved registers on stack)
;
; On exit:
; $fa-fb: result
; (all registers preserved except P)
; Z-flag set if result is zero
; C-flag set if <= 0 or >= 256
; N-flag set if result < 0
;
]value1 .var $f0 {addr/2}
]value2 .var $fa {addr/2}
]saved_areg .var $fc {addr/1}
15f2: 20 5a 2e DoSubtract jsr JJ_PopRegs ;restore all registers
15f5: 85 fc sta ]saved_areg ;save A-reg
15f7: 38 sec ;perform 16-bit subtraction
15f8: a5 f0 lda ]value1
15fa: e5 fa sbc ]value2
15fc: 85 fa sta ]value2
15fe: a5 f1 lda ]value1+1
1600: e5 fb sbc ]value2+1
1602: 08 php ;save flags
1603: d0 09 bne :Return ;result was nonzero, bail (C=?, N=?, Z=0)
1605: 05 fa ora ]value2 ;check low byte
1607: d0 09 bne :HighZero ;nonzero, branch
; Result zero.
1609: 68 pla ;pull saved P-reg
160a: 38 sec ;set carry (no borrow)
160b: a9 00 lda #$00 ;set Z-flag, clear N flag
160d: 08 :PushReturn php ;save registers
160e: a5 fc :Return lda ]saved_areg ;restore A-reg
1610: 28 plp ;restore flags
1611: 60 rts
1612: 68 :HighZero pla ;pull saved P-reg
1613: 18 clc ;clear carry (borrow)
1614: a9 01 lda #$01 ;clear Z-flag and N-flag
1616: d0 f5 bne :PushReturn ;bail (C=0, N=0, Z=0)
;
; Takes the value in $f0-f1 and subtracts the inline data value, storing the
; result in $fa-fb.
;
; (all registers preserved except P-reg; N/C/Z set)
;
]inline_val .var $fc {addr/2}
1618: 20 57 2e SubF0F1_Inline jsr JJ_PushRegs ;preserve registers
161b: 20 6a 14 jsr GetCCInlineValue ;get inline value in $fc-fd
161e: a5 fc lda ]inline_val ;copy value from $fc-fd to $fa-fb
1620: 85 fa sta ]value2
1622: a5 fd lda ]inline_val+1
1624: 85 fb sta ]value2+1
1626: 4c f2 15 jmp DoSubtract ;perform subtraction
;
; Takes the value in $f0-f1 and subtracts the value pointed to by the inline
; pointer. Stores the result in $fa-fb.
;
; (all registers preserved except P-reg; N/C/Z set)
;
1629: 20 57 2e SubF0F1_Ind jsr JJ_PushRegs ;preserve registers
162c: 20 6a 14 jsr GetCCInlineValue ;get inline value in $fc-fd
162f: a0 00 ldy #$00
1631: b1 fc lda (]inline_val),y ;get value pointed to by inline pointer
1633: 85 fa sta ]value2
1635: c8 iny
1636: b1 fc lda (]inline_val),y
1638: 85 fb sta ]value2+1
163a: 4c f2 15 jmp DoSubtract ;perform subtraction
;
; Adds the value in $f0-f1 to the value in $f4-f5, and stores the result in $f0-
; f1.
;
]value2 .var $f4 {addr/2}
163d: 08 AddF0F1_F4F5 php ;save flags
163e: 48 pha ;save A-reg
163f: a5 f4 lda ]value2 ;add values
1641: 18 clc
1642: 65 f0 adc ]value1
1644: 85 f0 sta ]value1
1646: a5 f5 lda ]value2+1
1648: 65 f1 adc ]value1+1
164a: 85 f1 sta ]value1+1
164c: 68 pla ;restore A-reg
164d: 28 plp ;restore flags
164e: 60 rts
;
; Gets the value pointed to by an inline pointer.
;
; On exit:
; $f0-f1: return value, from pointed-to location
; $fc-fd: pointer extracted from inline data
;
]ret_val .var $f0 {addr/2}
]ind_ptr .var $fc {addr/2}
GetIndirectValue
164f: 20 57 2e jsr JJ_PushRegs
1652: 20 6a 14 jsr GetCCInlineValue
1655: a0 00 ldy #$00
1657: b1 fc lda (]ind_ptr),y
1659: 85 f0 sta ]ret_val
165b: c8 iny
165c: b1 fc lda (]ind_ptr),y
165e: 85 f1 sta ]ret_val+1
1660: 20 5a 2e :PullReturn jsr JJ_PopRegs
1663: 60 rts
;
; Extracts the 16-bit inline value from the caller's caller. This is usually a
; pointer, but sometimes it's a constant.
;
; On exit:
; $f0-f1: inline data value
;
]ret_val .var $f0 {addr/2}
]inline_val .var $fc {addr/2}
1664: 20 57 2e GetInlineData jsr JJ_PushRegs ;save registers
1667: 20 6a 14 jsr GetCCInlineValue ;get value
166a: a5 fc lda ]inline_val ;copy value to $f0-f1
166c: 85 f0 sta ]ret_val
166e: a5 fd lda ]inline_val+1
1670: 85 f1 sta ]ret_val+1
1672: 4c 60 16 jmp :PullReturn
1675: 79 3f 22 1e+ .junk 139
1700: 4c d5 18 J_DescribeRoom jmp DescribeRoom
1703: 4c 1a 18 J_ShowInventory jmp ShowInventory
1706: 4c 9b 1a J_GetActionArg jmp GetActionArg
1709: 4c 06 1b J_SaveGame jmp SaveGame
170c: 4c J_CondHandlers .dd1 $4c ;not used as a jump
170d: 18 17 .dd2 cond_handlers
170f: 4c d8 1b J_AskDiskOrTape jmp AskDiskOrTape
J_PrintStringCOUT
1712: 4c f5 1a jmp PrintStringCOUT
1715: 4c 9d 18 J_PrintItemName jmp PrintItemName
;
; Condition handlers. These functions are called to perform a logic test. For
; all handlers:
;
; On entry (see call at $208f):
; A-reg: room number for item [arg] (even if arg is not item#)
; X-reg: $ff
; Y-reg: $00
; $f0-f1: pointer to global that holds current room number
; $f2-f3: condition argument
;
; On exit:
; X-reg: result ($00 or $ff)
;
1718: 40 17 cond_handlers .dd2 C00_NoOp ;$00 (no-op)
171a: 6b 17 .dd2 C01_Carried ;$01 carried
171c: 7f 17 .dd2 C02_Here ;$02 here
171e: 8c 17 .dd2 C03_Accessible ;$03 accessible
1720: 9a 17 .dd2 C04_At ;$04 at
1722: b1 17 .dd2 C05_NotHere ;$05 !here
1724: c5 17 .dd2 C06_NotCarried ;$06 !carried
1726: e0 17 .dd2 C07_NotAt ;$07 !at
1728: fd 17 .dd2 C08_Flag ;$08 flag
172a: 04 18 .dd2 C09_NotFlag ;$09 !flag
172c: 41 17 .dd2 C0A_Loaded ;$0a loaded
172e: 45 17 .dd2 C0B_NotLoaded ;$0b !loaded
1730: 71 17 .dd2 C0C_NotAccessible ;$0c !accessible
1732: 86 17 .dd2 C0D_Exists ;$0d exists
1734: 95 17 .dd2 C0E_NotExists ;$0e !exists
1736: a1 17 .dd2 C0F_CounterLE ;$0f counter_le
1738: b6 17 .dd2 C10_CounterGT ;$10 counter_ge
173a: ca 17 .dd2 C11_NotMoved ;$11 !moved
173c: e7 17 .dd2 C12_Moved ;$12 moved
173e: 0d 18 .dd2 C13_CounterEq ;$13 counter_eq
;
; Condition $00: no-op.
;
• Clear variables
]cur_room_ptr .var $f0 {addr/2}
]cond_arg .var $f2 {addr/2}
]tmp .var $f4 {addr/1}
1740: 60 C00_NoOp rts
;
; Condition $0a: true if at least one item is in player's inventory.
;
1741: a2 ff C0A_Loaded ldx #$ff ;return true if inventory item found
1743: d0 02 bne CheckLoaded ;(always)
;
; Condition $0b: true if no items are in player's inventory.
;
1745: a2 00 C0B_NotLoaded ldx #$00 ;return false if inventory item found
1747: 20 93 2e CheckLoaded jsr InA_GetIndirectValue ;get pointer to item location data
174a: 26 2f .dd2 item_rooms_ptr
174c: ac 6f 30 ldy hdr_max_item ;count down from max item number
174f: 86 f4 stx ]tmp ;save default return value
1751: a2 00 ldx #$00
1753: a1 f0 :Loop lda (]cur_room_ptr,x) ;get item's room #
1755: c9 ff cmp #ITEM_HELD ;in inventory?
1757: d0 03 bne :NonInv ;no, branch
1759: a6 f4 ldx ]tmp ;restore default return value
175b: 60 rts
175c: 20 51 2e :NonInv jsr JJ_IncF0F1 ;advance pointer
175f: 20 51 2e jsr JJ_IncF0F1
1762: 88 dey ;are we done?
1763: 10 ee bpl :Loop ;no, branch
1765: a5 f4 lda ]tmp ;didn't find an inventory item, so
1767: 49 ff eor #$ff ; invert result
1769: aa tax ;put result in X-reg
176a: 60 :Return rts
;
; Condition $01: true if specified item is in player's inventory.
;
176b: c9 ff C01_Carried cmp #$ff ;(room # in A-reg) - in player inventory?
176d: f0 fb beq :Return ;yes, return true
176f: d0 12 bne ReturnXZero ;no, return false
;
; Condition $0c: true if item is NOT carried and NOT in current room.
;
C0C_NotAccessible
1771: a2 00 ldx #$00 ;set default return value to false
1773: c9 ff cmp #ITEM_HELD ;(room # in A-reg) - in player inventory?
1775: f0 f3 beq :Return ;yes, accessible, return false
1777: d1 f0 cmp (]cur_room_ptr),y ;(ptr to current room in $f0-f1) in current room?
1779: f0 ef beq :Return ;yes, accessible, return false
177b: a2 ff ldx #$ff ;set return value to true
177d: d0 eb bne :Return ;(always)
;
; Condition $02: true if item is in current room.
;
177f: d1 f0 C02_Here cmp (]cur_room_ptr),y ;(room # in A-reg, ptr to cur room in $f0-f1)
1781: f0 e7 beq :Return ;if item is in current room, return default result
1783: a2 00 ReturnXZero ldx #$00 ;not in current room, return false
1785: 60 rts
;
; Condition $0d: return true if item is NOT in room zero ("nowhere").
;
1786: c9 00 C0D_Exists cmp #$00 ;(room # in A-reg) - in room zero?
1788: d0 e0 bne :Return ;no, return true
178a: f0 f7 beq ReturnXZero ;yes, return false
;
; Condition $03: return true if item is carried OR is in current room.
;
178c: d1 f0 C03_Accessible cmp (]cur_room_ptr),y ;(room # in A-reg, ptr to cur room in $f0-f1)
178e: f0 da beq :Return ;if item is in current room, return default result
1790: c9 ff cmp #ITEM_HELD ;in inventory?
1792: d0 ef bne ReturnXZero ;no, return false
1794: 60 rts
;
; Condition $0e: true if item is in room zero ("nowhere").
;
1795: c9 00 C0E_NotExists cmp #$00 ;(room # in A-reg) - in room zero?
1797: d0 ea bne ReturnXZero ;no, return false
1799: 60 rts
;
; Condition $04: true if arg matches current room.
;
179a: a5 f2 C04_At lda ]cond_arg ;get argument
179c: d1 f0 cmp (]cur_room_ptr),y ;compare to current room number
179e: d0 e3 bne ReturnXZero ;didn't match, return false
17a0: 60 :Return rts
;
; Condition $0f: true if current counter value is <= arg.
;
17a1: 20 93 2e C0F_CounterLE jsr InA_GetIndirectValue ;get pointer to "current counter"
17a4: c7 30 .dd2 counter_register
17a6: 20 7b 2e jsr InA_SubF0F1_Ind ;subtract argument in $f2-f3
17a9: f2 00 .dd2 $00f2 ; (in a slightly awkward way)
17ab: f0 f3 beq :Return ;if arg is equal, return true
17ad: 30 f1 bmi :Return ;if arg is smaller, return true
17af: d0 d2 BneRetXZero bne ReturnXZero ;return false
;
; Condition $05: true if item is NOT in current room.
;
17b1: d1 f0 C05_NotHere cmp (]cur_room_ptr),y ;(room # in A-reg, ptr to cur room in $f0-f1)
17b3: f0 ce beq ReturnXZero ;if item in current room, branch to return false
17b5: 60 rts
;
; Condition $10: true if current counter value is > arg.
;
17b6: 20 93 2e C10_CounterGT jsr InA_GetIndirectValue ;get pointer to "current counter"
17b9: c7 30 .dd2 counter_register
17bb: 20 7b 2e jsr InA_SubF0F1_Ind ;subtract argument in $f2-f3
17be: f2 00 .dd2 $00f2 ; (in a slightly awkward way)
17c0: f0 c1 beq ReturnXZero ;if arg is equal, return false
17c2: 30 bf bmi ReturnXZero ;if arg is smaller, return false
17c4: 60 rts
;
; Condition $06: true if player is NOT carrying item.
;
17c5: c9 ff C06_NotCarried cmp #ITEM_HELD ;(room # in A-reg) - item carried?
17c7: f0 ba beq ReturnXZero ;yes, return false
17c9: 60 rts
;
; Condition $11: true if item is in its original location.
;
17ca: 20 75 2e C11_NotMoved jsr JJ_PushF2F3 ;copy cond arg in $f2-f3...
17cd: 20 72 2e jsr JJ_PopF4F5 ;...to $f4-f5
17d0: 20 93 2e jsr InA_GetIndirectValue ;get pointer to initial room data
17d3: 2a 2f .dd2 item_initroom_ptr
17d5: 20 87 2e jsr JJ_AddF0F1_F4F5 ;double arg to convert index to offset
17d8: 20 87 2e jsr JJ_AddF0F1_F4F5
17db: d1 f0 cmp (]cur_room_ptr),y ;(room # in A-reg) - compare to initial room #
17dd: d0 a4 bne ReturnXZero ;not the same, branch to return false
17df: 60 rts
;
; Condition $07: true if player is NOT in the specified room.
;
17e0: a5 f2 C07_NotAt lda ]cond_arg ;get argument
17e2: d1 f0 cmp (]cur_room_ptr),y ;compare to current room number
17e4: f0 9d beq ReturnXZero ;if they match, return false
17e6: 60 rts
;
; Condition $12: true if item is NOT in its original location.
;
17e7: 20 75 2e C12_Moved jsr JJ_PushF2F3 ;copy cond arg in $f2-f3...
17ea: 20 72 2e jsr JJ_PopF4F5 ;...to $f4-f5
17ed: 20 93 2e jsr InA_GetIndirectValue ;get pointer to initial room data
17f0: 2a 2f .dd2 item_initroom_ptr
17f2: 20 87 2e jsr JJ_AddF0F1_F4F5 ;double arg to convert index to offset
17f5: 20 87 2e jsr JJ_AddF0F1_F4F5
17f8: d1 f0 cmp (]cur_room_ptr),y ;(room # in A-reg) - compare to initial room #
17fa: f0 87 beq ReturnXZero ;same, branch to return false
17fc: 60 rts
;
; Condition $08: true if specified flag is true.
;
17fd: a4 f2 C08_Flag ldy ]cond_arg ;use argument as index
17ff: b9 c9 30 lda action_flags,y ;get flag
1802: aa tax ;return value in X-reg
1803: 60 rts
;
; Condition $09: true if the specified flag is NOT true.
;
1804: a4 f2 C09_NotFlag ldy ]cond_arg ;use argument as index
1806: b9 c9 30 lda action_flags,y ;get flag
1809: 49 ff eor #$ff ;flip it
180b: aa tax ;return value in X-reg
180c: 60 rts
;
; Condition $13: true if current counter value is equal to arg.
;
180d: 20 93 2e C13_CounterEq jsr InA_GetIndirectValue ;get pointer to "current counter"
1810: c7 30 .dd2 counter_register
1812: 20 7b 2e jsr InA_SubF0F1_Ind ;subtract argument in $f2-f3
1815: f2 00 .dd2 $00f2 ; (in a slightly awkward way)
1817: d0 96 bne BneRetXZero ;if not equal, branch to return false
1819: 60 rts
;
; Prints a list of items in the player's inventory.
;
]name_ptrs .var $f0 {addr/2}
]item_room_data .var $f2 {addr/2}
181a: 20 8a 2e ShowInventory jsr JJ_PushFullState ;push registers and ZP data
181d: 20 33 2e jsr JJ_PrintCR ;move to start of new line
1820: 20 54 2e jsr InA_GetInlineData
1823: 6f 18 .dd2 msg_im_carrying
1825: 20 36 2e jsr JJ_PrintString ;print "I'm carrying"
1828: ac 6f 30 ldy hdr_max_item ;going to loop through all items
182b: c8 iny ;+1 to make it a count
182c: a9 00 lda #$00
182e: 8d 33 30 sta thing_found_flag ;init "have something" flag
1831: 20 93 2e jsr InA_GetIndirectValue ;get pointer to item room data
1834: 26 2f .dd2 item_rooms_ptr
1836: 20 81 2e jsr JJ_SetF2F3_F0F1 ;copy pointer to $f2-f3
1839: 20 93 2e jsr InA_GetIndirectValue ;get pointer to item name pointers
183c: 28 2f .dd2 item_names_ptr
;
183e: a2 00 :Loop ldx #$00
1840: a1 f2 lda (]item_room_data,x) ;get room number
1842: c9 ff cmp #ITEM_HELD ;in inventory?
1844: d0 06 bne :NotHeld ;no, branch
1846: 8d 33 30 sta thing_found_flag ;set "have something" flag to True
1849: 20 12 2e jsr JJ_PrintItemName ;print name of item
184c: 20 6c 2e :NotHeld jsr JJ_IncF2F3 ;advance item name pointer
184f: 20 6c 2e jsr JJ_IncF2F3
1852: 20 51 2e jsr JJ_IncF0F1 ;advance item room data pointer
1855: 20 51 2e jsr JJ_IncF0F1
1858: 88 dey ;done yet?
1859: d0 e3 bne :Loop ;no, branch
;
185b: ad 33 30 lda thing_found_flag ;did we find anything?
185e: d0 08 bne :FoundSome ;yes, branch
1860: 20 54 2e jsr InA_GetInlineData
1863: 8d 18 .dd2 msg_nothing_ata
1865: 20 36 2e jsr JJ_PrintString ;print "nothing at all"
1868: 20 33 2e :FoundSome jsr JJ_PrintCR ;finish with a newline
186b: 20 8d 2e jsr JJ_PopFullState ;restore registers and ZP data
186e: 60 rts
186f: 0d 49 27 4d+ msg_im_carrying .zstr $0d,‘I'M CARRYING THE FOLLOWING:’,$0d
188d: 20 4e 4f 54+ msg_nothing_ata .zstr ‘ NOTHING AT ALL’
;
; Prints an item name string. Used for the "inventory" command and when drawing
; the room description.
;
; Names of get/drop items end with "/WORD/", which we want to ignore here.
;
; On entry:
; $f0-f1: pointer to pointer to string
;
]ptr .var $f0 {addr/2}
189d: 20 57 2e PrintItemName jsr JJ_PushRegs ;preserve registers
18a0: 20 5d 2e jsr JJ_PushF0F1 ;preserve $f0-f1
18a3: a0 00 ldy #$00
18a5: b1 f0 lda (]ptr),y ;get pointer low byte
18a7: 48 pha ;stash it
18a8: c8 iny
18a9: b1 f0 lda (]ptr),y ;get pointer high byte
18ab: 85 f1 sta ]ptr+1 ;store in ZP
18ad: 68 pla ;restore low byte
18ae: 85 f0 sta ]ptr ;store that
18b0: 88 dey ;set Y-reg=0
18b1: b1 f0 lda (]ptr),y ;get first byte of string, which holds the length
18b3: aa tax ;copy to X-reg
18b4: 20 51 2e jsr JJ_IncF0F1 ;advance pointer past the length byte
18b7: b1 f0 :Loop lda (]ptr),y ;get char
18b9: c9 2f cmp #‘/’ ;did we find a get/drop suffix?
18bb: f0 07 beq :StrEnd ;yes, branch
18bd: 20 30 2e jsr JJ_PrintNonNull ;no, print char
18c0: c8 iny ;advance to next char
18c1: ca dex ;done yet?
18c2: d0 f3 bne :Loop ;no, loop
;
18c4: a9 2e :StrEnd lda #‘.’ ;separate items with ". "
18c6: 20 30 2e jsr JJ_PrintNonNull
18c9: a9 20 lda #‘ ’
18cb: 20 30 2e jsr JJ_PrintNonNull
18ce: 20 60 2e jsr JJ_PopF0F1 ;restore $f0-f1
18d1: 20 5a 2e jsr JJ_PopRegs ;restore registers
18d4: 60 rts
;
; Prints the room description at the top of the screen. This includes the room
; text, a list of all objects present, and a list of all "standard" exits.
;
18d5: 20 8a 2e DescribeRoom jsr JJ_PushFullState ;preserve regs and ZP
; Start by clearing all the lines in the area above the scroll window.
18d8: a6 22 ldx MON_WNDTOP ;get current top of screen
18da: f0 1c beq :AtTop ;empty window, branch
18dc: a9 00 lda #$00
18de: 85 25 sta MON_CV ;start at top of screen
18e0: a5 25 :Loop lda MON_CV ;get line number
18e2: 20 c1 fb jsr MON_BASCALC ;set BASL/BASH
18e5: a0 00 ldy #$00 ;start from column 0
18e7: 20 9e fc jsr MON_CLREOLZ ;clear to end of line
18ea: e6 25 inc MON_CV ;move to next line
18ec: ca dex ;done yet?
18ed: d0 f1 bne :Loop ;no, loop
;
18ef: a9 00 lda #$00
18f1: 85 22 sta MON_WNDTOP ;reset scroll window top
18f3: 85 25 sta MON_CV ;position at top line
18f5: 20 c1 fb jsr MON_BASCALC ;recalc BASL/BASH
18f8: ad d8 30 :AtTop lda darkness_flag ;is the room dark?
18fb: f0 1d beq :NotDark ;no, branch
18fd: 20 93 2e jsr InA_GetIndirectValue ;get pointer to item location data
1900: 26 2f .dd2 item_rooms_ptr
1902: a0 12 ldy #18 ;item #9 (lightsource)
1904: b1 f0 lda (]ptr),y ;check current location
1906: c9 ff cmp #ITEM_HELD ;in inventory?
1908: f0 10 beq :NotDark ;yes, not dark (must swap item when light expires)
190a: cd e9 30 cmp current_room ;is lightsource in current room?
190d: f0 0b beq :NotDark ;yes, not dark
190f: 20 54 2e jsr InA_GetInlineData ;complain about darkness
1912: 31 1a .dd2 msg_too_dark
1914: 20 4b 2e jsr JJ_PrintFlashing
1917: 4c 09 1a jmp :FinishDescr ;nothing else to say, finish up
]room_text .var $f2 {addr/2}
191a: 20 93 2e :NotDark jsr InA_GetIndirectValue ;get pointer to room descr table in $f0-f1
191d: 16 2f .dd2 room_descrs_ptr
191f: ad e9 30 lda current_room ;get current room number
1922: 18 clc
1923: 6d e9 30 adc current_room ;double it
1926: a8 tay
1927: b1 f0 lda (]ptr),y ;get ptr to text for the room (low byte)
1929: 85 f2 sta ]room_text
192b: c8 iny
192c: b1 f0 lda (]ptr),y ;repeat for high byte
192e: 85 f3 sta ]room_text+1
;
1930: a0 00 ldy #$00
1932: b1 f2 lda (]room_text),y ;get string length
1934: aa tax ;hold in X-reg
1935: 20 6c 2e jsr JJ_IncF2F3 ;advance pointer
1938: b1 f2 lda (]room_text),y ;get first char
193a: c9 2a cmp #‘*’ ;does it start with a '*'?
193c: d0 06 bne :PrintPfx ;no, show standard "I'm in a" prefix
193e: ca dex ;yes, decrement string length
193f: 20 6c 2e jsr JJ_IncF2F3 ;advance pointer (preserves flags)
1942: d0 08 bne :RoomCont ;(branch always, assuming text follows '*')
1944: 20 54 2e :PrintPfx jsr InA_GetInlineData
1947: 47 1a .dd2 msg_im_in_a
1949: 20 36 2e jsr JJ_PrintString ;print "I'm in a"
;
194c: 20 75 2e :RoomCont jsr JJ_PushF2F3 ;copy room text string pointer from $f2-f3...
194f: 20 60 2e jsr JJ_PopF0F1 ;...to $f0-f1
1952: 8a txa ;copy string length back to A-reg
1953: 20 3f 2e jsr JJ_PrintNChars ;print room description string
; Now print a list of items found here.
]item_room_ptr .var $f2 {addr/2}
1956: a0 00 ldy #$00
1958: 98 tya
1959: 8d 33 30 sta thing_found_flag ;clear the "thing found" flag (could STY?)
195c: ae 6f 30 ldx hdr_max_item ;get max item #
195f: e8 inx ;increment it to make it a count
1960: 20 93 2e jsr InA_GetIndirectValue ;get pointer to item location data
1963: 26 2f .dd2 item_rooms_ptr
1965: 20 81 2e jsr JJ_SetF2F3_F0F1 ;copy pointer to $f2-f3
1968: 20 93 2e jsr InA_GetIndirectValue ;get pointer to item name table
196b: 28 2f .dd2 item_names_ptr
196d: ad e9 30 :ItemLoop lda current_room ;get player's room #
1970: d1 f2 cmp (]item_room_ptr),y ;is the item in this room?
1972: d0 1b bne :NotHere ;no, branch
1974: ad 33 30 lda thing_found_flag ;check "thing found" flag
1977: d0 0e bne :NotFirst ;not first item, branch
1979: 20 5d 2e jsr JJ_PushF0F1 ;preserve $f0-f1
197c: 20 54 2e jsr InA_GetInlineData
197f: 75 1a .dd2 msg_vis_items
1981: 20 36 2e jsr JJ_PrintString ;print "visible items:"
1984: 20 60 2e jsr JJ_PopF0F1 ;restore $f0-f1
1987: 20 12 2e :NotFirst jsr JJ_PrintItemName ;print the item's name
198a: a9 01 lda #$01
198c: 8d 33 30 sta thing_found_flag ;set the "thing found" flag
198f: 20 51 2e :NotHere jsr JJ_IncF0F1 ;advance pointer to item descriptions
1992: 20 51 2e jsr JJ_IncF0F1
1995: 20 6c 2e jsr JJ_IncF2F3 ;advance pointer to item room data
1998: 20 6c 2e jsr JJ_IncF2F3
199b: ca dex ;have we examined all items?
199c: d0 cf bne :ItemLoop ;not yet, branch
199e: 20 33 2e jsr JJ_PrintCR ;finish with a carriage return
; Print visible exits. For each of the 6 directions (NSEWUD), find the entry in
; the appropriate table for the current room. If the room # there is nonzero,
; show that direction in the list.
]dir_name_ptr .var $f2 {addr/2}
]vis_exit_tab .var $f4 {addr/2}
19a1: a9 00 lda #$00
19a3: 8d 33 30 sta thing_found_flag ;clear "thing found" flag
19a6: a2 06 ldx #$06 ;six directions
19a8: 20 54 2e jsr InA_GetInlineData ;get pointer to exit name strings
19ab: 51 1a .dd2 msg_exit_name
19ad: 20 81 2e jsr JJ_SetF2F3_F0F1 ;copy pointer to $f2-f3
19b0: 20 54 2e jsr InA_GetInlineData ;get pointer to room exit table pointers
19b3: 18 2f .dd2 vis_exits_n_ptr
19b5: 20 84 2e jsr JJ_SetF4F5_F0F1 ;copy pointer to $f4-f5
19b8: a0 00 :ExitsLoop ldy #$00
19ba: b1 f4 lda (]vis_exit_tab),y ;get pointer to table for this direction
19bc: 85 f0 sta ]ptr ;store in ZP
19be: c8 iny
19bf: b1 f4 lda (]vis_exit_tab),y ;repeat for high byte
19c1: 85 f1 sta ]ptr+1
19c3: ad e9 30 lda current_room ;get current room number
19c6: 18 clc
19c7: 6d e9 30 adc current_room ;double it
19ca: a8 tay ;move to Y-reg for use as index
19cb: b1 f0 lda (]ptr),y ;get exit for this room in this direction
19cd: f0 1b beq :NotThisDir ;if zero, we can't go that way
;
19cf: ad 33 30 lda thing_found_flag ;did we already find something?
19d2: d0 0d bne :NotFirst ;yes, skip this
19d4: 20 54 2e jsr InA_GetInlineData
19d7: 88 1a .dd2 msg_some_exits
19d9: 20 36 2e jsr JJ_PrintString ;print "some exits are"
19dc: a9 01 lda #$01
19de: 8d 33 30 sta thing_found_flag ;set "thing found" flag
19e1: 20 75 2e :NotFirst jsr JJ_PushF2F3 ;copy pointer to direction string from $f2-f3...
19e4: 20 60 2e jsr JJ_PopF0F1 ;...to $f0-f1
19e7: 20 36 2e jsr JJ_PrintString ;print direction string
;
19ea: 20 66 2e :NotThisDir jsr JJ_IncF4F5 ;advance to next direction table
19ed: 20 66 2e jsr JJ_IncF4F5
19f0: a0 00 :NxtDirStrLp ldy #$00 ;move to next direction string
19f2: b1 f2 lda (]dir_name_ptr),y ; by walking through the strings to find a $00
19f4: f0 05 beq :FoundZ ;found it, branch
19f6: 20 6c 2e jsr JJ_IncF2F3 ;advance pointer (preserves flags)
19f9: d0 f5 bne :NxtDirStrLp ;(always)
19fb: 20 6c 2e :FoundZ jsr JJ_IncF2F3 ;advance pointer past the $00 byte
19fe: ca dex ;done yet?
19ff: d0 b7 bne :ExitsLoop ;no, keep going
1a01: ad 33 30 lda thing_found_flag ;did we print any exits?
1a04: f0 03 beq :FinishDescr ;no, branch
1a06: 20 33 2e jsr JJ_PrintCR ;yes, finish it with a newline
; Finish up by printing "<------->" (full width of screen).
1a09: a9 3c :FinishDescr lda #‘<’
1a0b: 20 30 2e jsr JJ_PrintNonNull
1a0e: a9 2d lda #‘-’
1a10: a2 26 ldx #38
1a12: 20 30 2e :DashLoop jsr JJ_PrintNonNull
1a15: ca dex
1a16: d0 fa bne :DashLoop
1a18: a9 3e lda #‘>’
1a1a: 20 30 2e jsr JJ_PrintNonNull
; Set top of scrolling text window to be below separator line.
1a1d: a6 25 ldx MON_CV ;get current vertical position
1a1f: e8 inx ;add one so it's below current line
1a20: 86 22 stx MON_WNDTOP ;set as top
1a22: a9 00 lda #0 ;set text position to left edge
1a24: 85 24 sta MON_CH
1a26: a9 17 lda #23 ;bottom of screen
1a28: 85 25 sta MON_CV
1a2a: 20 c1 fb jsr MON_BASCALC ;set BASL
1a2d: 20 8d 2e jsr JJ_PopFullState ;restore regs and ZP
1a30: 60 rts
1a31: 49 54 53 20+ msg_too_dark .zstr ‘ITS TOO DARK TO SEE!’,$0d
1a47: 49 27 4d 20+ msg_im_in_a .zstr ‘I'M IN A ’
1a51: 4e 4f 52 54+ msg_exit_name .zstr ‘NORTH ’
1a58: 53 4f 55 54+ .zstr ‘SOUTH ’
1a5f: 45 41 53 54+ .zstr ‘EAST ’
1a65: 57 45 53 54+ .zstr ‘WEST ’
1a6b: 55 50 20 00 .zstr ‘UP ’
1a6f: 44 4f 57 4e+ .zstr ‘DOWN ’
1a75: 2e 20 56 49+ msg_vis_items .zstr ‘. VISIBLE ITEMS:’,$0d,$0d
1a88: 0d 20 53 4f+ msg_some_exits .zstr $0d,‘ SOME EXITS ARE: ’
;
; Finds the argument for an action operation. The arguments are stored in the
; condition table, using entries where the condition opcode is zero.
;
; This is only called when an arg is needed, so action ops without arguments
; don't consume slots in the condition table.
;
; On entry:
; $f6-f7: action index
; (actionop_arg_idx at $3067 specifies first table to check)
;
; On exit:
; $f0-f1: argument
;
]argval .var $f2 {addr/2}
1a9b: 20 57 2e GetActionArg jsr JJ_PushRegs ;preserve registers
1a9e: 20 75 2e jsr JJ_PushF2F3 ;preserve $f2-f3
1aa1: 20 6f 2e jsr JJ_PushF4F5 ;preserve $f4-f5
; Search the condition table entries for this action index for an entry with
; condition opcode $00, starting with the table specified by the action opcode
; argument index.
1aa4: 20 54 2e :Loop jsr InA_GetInlineData ;get pointer to pointers to condition data
1aa7: 0c 2f .dd2 condition0_ptr
1aa9: ad 67 30 lda actionop_arg_idx ;get index to arg
1aac: 18 clc
1aad: 6d 67 30 adc actionop_arg_idx ;double it
1ab0: a8 tay ;use as index into table
1ab1: ee 67 30 inc actionop_arg_idx ;incr index for next time
1ab4: b1 f0 lda (]ptr),y ;get pointer to table N (where N is arg index)
1ab6: 85 f2 sta ]argval
1ab8: c8 iny
1ab9: b1 f0 lda (]ptr),y
1abb: 85 f3 sta ]argval+1
1abd: 20 96 2e jsr JJ_PushF6F7 ;copy action index in $f6-f7...
1ac0: 20 60 2e jsr JJ_PopF0F1 ;...into $f0-f1
1ac3: 20 84 2e jsr JJ_SetF4F5_F0F1 ;...and $f4-f5
1ac6: 20 87 2e jsr JJ_AddF0F1_F4F5 ;set $f0-f1 to double the action index
1ac9: 20 75 2e jsr JJ_PushF2F3 ;copy cond table pointer in $f2-f3...
1acc: 20 72 2e jsr JJ_PopF4F5 ;...into $f4-f5
1acf: 20 87 2e jsr JJ_AddF0F1_F4F5 ;add to 2*index to get pointer to condition
;
1ad2: a0 00 ldy #$00
1ad4: b1 f0 lda (]ptr),y ;get low byte of condition
1ad6: 85 f2 sta ]argval
1ad8: c8 iny
1ad9: b1 f0 lda (]ptr),y ;get high byte of condition
1adb: 85 f3 sta ]argval+1 ;save in $f2-f3
1add: 20 54 2e jsr InA_GetInlineData ;load 20 into $f0-f1
1ae0: 14 00 .dd2 20
1ae2: 20 21 2e jsr JJ_Divide16 ;set $f0-f1 to condition / 20 (cond arg)
1ae5: a5 f3 lda ]argval+1 ; and $f2-f3 to the remainder (cond opcode)
1ae7: 05 f2 ora ]argval ;was opcode zero?
1ae9: d0 b9 bne :Loop ;no, branch
1aeb: 20 72 2e jsr JJ_PopF4F5 ;restore $f4-f5
1aee: 20 78 2e jsr JJ_PopF2F3 ;restore $f2-f3
1af1: 20 5a 2e jsr JJ_PopRegs ;restore regs
1af4: 60 :Return rts
;
; Prints a null-terminated string using COUT. Useful for DOS commands.
;
1af5: a0 00 PrintStringCOUT ldy #$00
1af7: b1 f0 lda (]ptr),y ;get char
1af9: f0 f9 beq :Return ;if it's $00, bail
1afb: 09 80 ora #$80 ;convert to to high ASCII
1afd: 20 ed fd jsr MON_COUT ;output in a way that DOS will see
1b00: 20 51 2e jsr JJ_IncF0F1 ;advance pointer
1b03: 4c f5 1a jmp PrintStringCOUT ;loop
;
; Saves a game to disk or tape.
;
1b06: 20 8a 2e SaveGame jsr JJ_PushFullState ;preserve all regs and ZP
1b09: 20 54 2e jsr InA_GetInlineData
1b0c: 9d 1b .dd2 msg_save_game
1b0e: 20 36 2e jsr JJ_PrintString ;confirm that we're saving the game
1b11: 20 1b 2e jsr JJ_AskDiskOrTape ;ask if they want disk or tape
1b14: ad 57 30 lda adventure_num ;copy adventure number into start of buffer
1b17: 8d 33 2f sta kbd_scratch_buf
1b1a: ad 58 30 lda adventure_num+1
1b1d: 8d 34 2f sta adv_num_hi
; Copy $30c7-3103 to $2f35-2f71 (counters, flags, current room, etc.).
1b20: a0 3c ldy #$3c
1b22: b9 c7 30 :Loop lda counter_register,y
1b25: 99 35 2f sta save_game_data,y
1b28: 88 dey
1b29: 10 f7 bpl :Loop
1b2b: ad b2 2e lda use_disk_flag ;disk or tape?
1b2e: f0 19 beq :Tape1 ;tape, branch
;
1b30: 20 54 2e jsr InA_GetInlineData ;get pointer to DOS save command
1b33: ac 1b .dd2 dos_save_cmd
1b35: ad 57 30 lda adventure_num ;put adventure number in filename (as control char)
1b38: 8d b9 1b sta dos_save_cmd+13
1b3b: a9 31 lda #‘1’ ;file #1
1b3d: 8d b8 1b sta dos_save_cmd+12
1b40: 20 1e 2e jsr JJ_PrintStringCOUT ;issue DOS command for file #1
1b43: ee b8 1b inc dos_save_cmd+12 ;update filename for next part
1b46: 4c 4c 1b jmp :Part2
1b49: 20 05 1c :Tape1 jsr WriteTape ;write part 1
1b4c: ea :Part2 nop
1b4d: a0 00 ldy #$00
1b4f: a2 ff ldx #$ff ;init to -1, so first iteration uses X-reg=0
1b51: 20 93 2e jsr InA_GetIndirectValue ;get pointer to item location data
1b54: 26 2f .dd2 item_rooms_ptr
1b56: e8 :Loop inx
1b57: b1 f0 lda (]ptr),y ;get item room #
1b59: 9d 33 2f sta kbd_scratch_buf,x ;copy to save buffer
1b5c: c8 iny ;(we always write 256 bytes, so max 128 items)
1b5d: c8 iny
1b5e: ec 6f 30 cpx hdr_max_item ;have we copied all items?
1b61: d0 f3 bne :Loop ;no, branch
;
1b63: ad b2 2e lda use_disk_flag ;disk or tape?
1b66: f0 0b beq :Tape2 ;tape, branch
1b68: 20 54 2e jsr InA_GetInlineData
1b6b: ac 1b .dd2 dos_save_cmd
1b6d: 20 1e 2e jsr JJ_PrintStringCOUT ;issue DOS command for file #2
1b70: 4c 76 1b jmp :Done
1b73: 20 05 1c :Tape2 jsr WriteTape ;write part 2
1b76: ea :Done nop
1b77: 20 8d 2e jsr JJ_PopFullState ;restore regs and ZP
1b7a: 60 rts
1b7b: 20 52 45 41+ msg_ready_tape .zstr ‘ READY SAVE TAPE. THEN HIT ENTER.’
1b9d: 20 53 41 56+ msg_save_game .zstr ‘ SAVING GAME ’,$0d
1bac: 0d 04 42 53+ dos_save_cmd .zstr $0d,$04,‘BSAVE AREC2’,$05,‘,A$2F33,L256’,$0d
msg_disk_or_tape
1bc8: 20 44 49 53+ .zstr ‘ DISK OR TAPE? ’
;
; Asks the player if the want to load/save from disk or tape. If tape, the
; player is prompted to get their recorder ready.
;
; On exit:
; global flag set to $00 for tape, $01 for disk
;
1bd8: 20 54 2e AskDiskOrTape jsr InA_GetInlineData
1bdb: c8 1b .dd2 msg_disk_or_tape
1bdd: 20 36 2e jsr JJ_PrintString ;ask for preference
1be0: 20 39 2e jsr JJ_GetInput ;get line of input
1be3: ad 33 2f lda kbd_scratch_buf ;check first char
1be6: c9 44 cmp #‘D’ ;disk?
1be8: d0 06 bne :NotDisk ;no, branch
1bea: a9 01 lda #$01
1bec: 8d b2 2e sta use_disk_flag
1bef: 60 rts
1bf0: c9 54 :NotDisk cmp #‘T’ ;tape?
1bf2: d0 e4 bne AskDiskOrTape ;no, try again
1bf4: a9 00 lda #$00
1bf6: 8d b2 2e sta use_disk_flag
1bf9: 20 54 2e jsr InA_GetInlineData
1bfc: 7b 1b .dd2 msg_ready_tape
1bfe: 20 36 2e jsr JJ_PrintString ;prompt player to prepare tape
1c01: 20 39 2e jsr JJ_GetInput ;wait for player to hit return
1c04: 60 rts
;
; Invokes the tape write routine.
;
1c05: a9 33 WriteTape lda #<kbd_scratch_buf ;set up start/end (inclusive bounds)
1c07: 85 3c sta MON_A1L
1c09: a9 2f lda #>kbd_scratch_buf
1c0b: 85 3d sta MON_A1H
1c0d: a9 32 lda #<save_state_end
1c0f: 85 3e sta MON_A2L
1c11: a9 30 lda #>save_state_end
1c13: 85 3f sta MON_A2H
1c15: 20 cd fe jsr MON_WRITE ;call monitor write routine
1c18: 60 rts
1c19: 69 6e 67 20+ .junk 743 ;bunch of data from another game in this area
J_ProcessActions
1f00: 4c 08 1f jmp ProcessActions
1f03: 4c 6e 21 J_ActionLoopEnd jmp ActionLoopEnd
1f06: 00 fail_msg_index .dd1 $00 ;holds a failure code (see e.g. $2327)
1f07: 00 action_opcode .dd1 $00 ;written, never read
;
; Process action list. Called from main loop.
;
; On entry:
; (first time: verb and noun indices set)
; (second time: verb index set to zero)
;
1f08: a9 00 ProcessActions lda #$00
1f0a: 8d c4 30 sta continue_flag ;init the "continue" flag
1f0d: 8d c3 30 sta occur_flag ;clear the "processing occurrences" flag
1f10: a9 ff lda #$ff
1f12: 8d c2 30 sta accum_cond_result ;init cumulative condition test result
1f15: 8d c0 30 sta cmd_not_hnd_flag ;init "command not handled" flag to true
1f18: ad bc 30 lda parsed_verb_idx ;get the verb index
1f1b: c9 01 cmp #$01 ;is it "GO" (actual or implied)?
1f1d: d0 0b bne :FindAction ;no, branch
1f1f: ad be 30 lda parsed_noun_idx ;check the noun
1f22: c9 07 cmp #$07 ;is it missing (0) or NSEWUD (1-6)?
1f24: 10 04 bpl :FindAction ;no, branch
1f26: 20 f7 23 jsr HandleGo ;handle GO command
1f29: 60 :Return rts
]action_index .var $f6 {addr/2}
1f2a: a9 ff :FindAction lda #$ff ;init index to -1
1f2c: 85 f6 sta ]action_index
1f2e: 85 f7 sta ]action_index+1
1f30: e6 f6 :FindActionLoop inc ]action_index ;increment index
1f32: d0 02 bne :NoInc
1f34: e6 f7 inc ]action_index+1
1f36: ea :NoInc nop
1f37: 20 96 2e jsr JJ_PushF6F7 ;push index
1f3a: 20 60 2e jsr JJ_PopF0F1 ;copy to $f0-f1
1f3d: 20 4e 2e jsr JJ_DecF0F1 ;decrement it
1f40: 20 7b 2e jsr InA_SubF0F1_Ind ;subtract max action; this is just comparing
1f43: 6d 30 .dd2 hdr_max_action ; the index to see if we've reached the end
1f45: d0 23 bne :NotEnd ;not end of list, branch
; We didn't find a matching action for this noun/verb. Look for implicit
; get/drop action (from /WORD/ in item descriptions).
1f47: ad bc 30 :CheckGetDrop lda parsed_verb_idx ;is verb index zero (doing occurrences)?
1f4a: f0 dd beq :Return ;yes, done
1f4c: 20 e6 21 jsr ImplicitGetDrop ;look for /WORD/ matches if this is TAKE or DROP
1f4f: 20 54 2e jsr InA_GetInlineData
1f52: 7e 21 .dd2 msg_be_stupid
1f54: ad c0 30 lda cmd_not_hnd_flag ;is command still unhandled?
1f57: f0 03 beq :NotUnhand ;no, getdrop handler took care of it; branch
1f59: 20 36 2e jsr JJ_PrintString ;print "I don't understand" (WEAR MERCHANT)
1f5c: 20 54 2e :NotUnhand jsr InA_GetInlineData
1f5f: bd 21 .dd2 msg_cant_yet
1f61: ad c2 30 lda accum_cond_result ;were all conditions true?
1f64: d0 c3 bne :Return ;yes, branch
1f66: 20 36 2e jsr JJ_PrintString ;some cond not satisfied, print "can't do that yet"
1f69: 60 :Return rts
]verb_ptr .var $f4 {addr/2}
1f6a: 20 96 2e :NotEnd jsr JJ_PushF6F7 ;copy action index in $f6-f7...
1f6d: 20 72 2e jsr JJ_PopF4F5 ;...to $f4-f5
1f70: 20 93 2e jsr InA_GetIndirectValue ;get pointer to action verb table
1f73: 00 2f .dd2 action_verb_ptr
1f75: 20 87 2e jsr JJ_AddF0F1_F4F5 ;add action index to pointer
1f78: a0 00 ldy #$00
1f7a: b1 f0 lda (]ptr),y ;get verb index for this action
1f7c: 8d c6 30 sta action_verb_idx ;save it
1f7f: 20 93 2e jsr InA_GetIndirectValue ;get pointer to noun index or occurrence percent
1f82: 02 2f .dd2 action_nou_prc_ptr
1f84: 20 87 2e jsr JJ_AddF0F1_F4F5 ;add action index to pointer
1f87: b1 f0 lda (]ptr),y ;get percent chance of occurrence firing
1f89: 8d c5 30 sta noun_or_percent ;save it
1f8c: ad bc 30 lda parsed_verb_idx ;get command verb index
1f8f: d0 05 bne :Cont ;nonzero (looking for match), branch
1f91: ad c6 30 lda action_verb_idx ;get action's verb index
1f94: d0 d3 bne :Return ;nonzero, end of occurrences reached; bail
;
1f96: ad c4 30 :Cont lda continue_flag ;are we continuing a previous item?
1f99: f0 12 beq :NotCont ;no, branch
1f9b: ad c5 30 lda noun_or_percent
1f9e: d0 05 bne :HaveNoun
1fa0: ad c6 30 lda action_verb_idx ;is this action an occurrence?
1fa3: f0 4f beq :TestConds ;yes, branch
1fa5: ad bc 30 :HaveNoun lda parsed_verb_idx
1fa8: d0 bf bne :Return
1faa: 8d c4 30 sta continue_flag ;(A-reg=0) clear the continue flag
;
1fad: ad bc 30 :NotCont lda parsed_verb_idx ;get command verb index
1fb0: cd c6 30 cmp action_verb_idx ;compare to action verb index
1fb3: d0 13 bne :WordMismatch ;mismatch, branch
1fb5: c9 00 cmp #$00 ;is verb zero (looking for occurrences)?
1fb7: d0 12 bne :NotOccur ;no, branch
1fb9: a9 00 lda #$00
1fbb: 8d c0 30 sta cmd_not_hnd_flag ;clear the not-handled flag
1fbe: 20 d4 23 jsr GetRandom ;get a random number (1-100)
1fc1: cd c5 30 cmp noun_or_percent ;compare to value specified in occurrence
1fc4: f0 2e beq :TestConds ;if we rolled <= value, do the occurrence
1fc6: 90 2c bcc :TestConds
1fc8: 4c 30 1f :WordMismatch jmp :FindActionLoop
1fcb: ad c5 30 :NotOccur lda noun_or_percent ;get noun index from action
1fce: cd be 30 cmp parsed_noun_idx ;compare to noun index from command
1fd1: f0 04 beq :NounMatch ;match, branch
1fd3: c9 00 cmp #$00 ;does action require a noun?
1fd5: d0 f1 bne :WordMismatch ;yes, this action doesn't apply; branch
;
1fd7: ad 7d 30 :NounMatch lda debug_flag ;check debug flag
1fda: c9 01 cmp #$01 ;'P' mode?
1fdc: d0 16 bne :TestConds ;no, "T" mode or off, don't show this message
1fde: 20 54 2e jsr InA_GetInlineData
1fe1: de 21 .dd2 msg_psbl
1fe3: 20 36 2e jsr JJ_PrintString
1fe6: 20 96 2e jsr JJ_PushF6F7 ;push action index
1fe9: 20 60 2e jsr JJ_PopF0F1
1fec: 20 48 2e jsr JJ_PrintSignedDec ;print action index
1fef: a9 20 lda #‘ ’
1ff1: 20 30 2e jsr JJ_PrintNonNull
]cond_tab_ptr .var $f8 {addr/2}
1ff4: a9 00 :TestConds lda #$00
1ff6: 8d c0 30 sta cmd_not_hnd_flag ;clear the command-not-handled flag
1ff9: a9 ff lda #$ff
1ffb: 8d c2 30 sta accum_cond_result ;init result to "true"
1ffe: 8d c3 30 sta occur_flag
2001: a9 0c lda #<condition0_ptr ;get pointer to first condition table
2003: 85 f8 sta ]cond_tab_ptr
2005: a9 2f lda #>condition0_ptr
2007: 85 f9 sta ]cond_tab_ptr+1
; Test up to 5 conditions, all of which must evaluate to True. Each condition
; is a 16-bit value that holds both the operation and the argument (value = op +
; value * 20). If an operation returns false, we bail.
]cond_raw .var $f2 {addr/2}
2009: a2 05 ldx #$05 ;5 conditions max
200b: a0 00 :Loop ldy #$00
200d: b1 f8 lda (]cond_tab_ptr),y ;get pointer to first table
200f: 85 f0 sta ]ptr
2011: c8 iny
2012: b1 f8 lda (]cond_tab_ptr),y
2014: 85 f1 sta ]ptr+1
2016: 20 5d 2e jsr JJ_PushF0F1 ;preserve table pointer
2019: 20 96 2e jsr JJ_PushF6F7 ;copy action index in $f6-f7...
201c: 20 60 2e jsr JJ_PopF0F1 ;...to $f0-f1
201f: 20 84 2e jsr JJ_SetF4F5_F0F1 ;copy that to $f4-f5
2022: 20 87 2e jsr JJ_AddF0F1_F4F5 ;add it to itself (i.e. double the index)
2025: 20 72 2e jsr JJ_PopF4F5 ;pop table pointer
2028: 20 87 2e jsr JJ_AddF0F1_F4F5 ;set pointer to (pointer + index*2)
202b: b1 f0 lda (]ptr),y ;get condition table entry (note Y-reg=1)
202d: 85 f3 sta ]cond_raw+1 ;save high byte
202f: 88 dey
2030: b1 f0 lda (]ptr),y ;get low byte of condition table entry
2032: 85 f2 sta ]cond_raw ;save it
2034: 20 54 2e jsr InA_GetInlineData
2037: 14 00 .dd2 20
2039: 20 21 2e jsr JJ_Divide16 ;divide value by 20 to separate pieces
203c: 20 5d 2e jsr JJ_PushF0F1 ;push quotient (arg)
203f: 20 75 2e jsr JJ_PushF2F3 ;push remainder (cond op code)
2042: 20 81 2e jsr JJ_SetF2F3_F0F1 ;set $f2-f3 to quotient
2045: 20 60 2e jsr JJ_PopF0F1 ;set $f0-f1 to remainder
2048: 20 84 2e jsr JJ_SetF4F5_F0F1 ;set $f4-f5 to remainder
204b: 20 87 2e jsr JJ_AddF0F1_F4F5 ;double it
204e: 20 84 2e jsr JJ_SetF4F5_F0F1 ;store op code * 2 in $f4-f5
2051: 20 93 2e jsr InA_GetIndirectValue ;get a pointer to the cond op handlers table pointer
2054: 0d 2e .dd2 cond_handlers_ind
2056: c8 iny ;skip past the fake JMP instruction
2057: b1 f0 lda (]ptr),y ;get low byte of pointer to table
2059: 48 pha ;save it
205a: c8 iny
205b: b1 f0 lda (]ptr),y ;get high byte
205d: 85 f1 sta ]ptr+1 ;overwrite $f0-f1 with table pointer
205f: 68 pla
2060: 85 f0 sta ]ptr
;
2062: a0 00 ldy #$00
2064: 20 87 2e jsr JJ_AddF0F1_F4F5 ;add doubled op code to $f0-f1 to get entry pointer
2067: 20 72 2e jsr JJ_PopF4F5 ;pop quotient (arg) into $f4-f5
206a: b1 f0 lda (]ptr),y ;get pointer to func, low byte
206c: 8d 90 20 sta _CondCall+1 ;self-modify the JSR
206f: c8 iny
2070: b1 f0 lda (]ptr),y ;same for high byte
2072: 8d 91 20 sta _CondCall+2
; We have the cond op arg in $f2-f3 and $f4-f5. Set up registers and ZP with
; values we're likely to need.
2075: 20 93 2e jsr InA_GetIndirectValue ;get pointer to item location data
2078: 26 2f .dd2 item_rooms_ptr
207a: 20 87 2e jsr JJ_AddF0F1_F4F5 ;add cond arg
207d: 20 87 2e jsr JJ_AddF0F1_F4F5 ;twice (16-bit data)
2080: a0 00 ldy #$00
2082: 8a txa ;X-reg still holds the condition counter
2083: 48 pha ;preserve it
2084: b1 f0 lda (]ptr),y ;set A-reg to room number of item N
2086: 20 54 2e jsr InA_GetInlineData ;get pointer to current room in $f0-f1
2089: e9 30 .dd2 current_room
208b: a2 ff ldx #$ff ;set X-reg to default return value
208d: a0 00 ldy #$00 ;set Y-reg to zero
208f: 20 9a 17 _CondCall jsr C04_At ;self-mod; call relevant condition handler
2092: 8a txa ;copy result ($00 or $ff) to A-reg
2093: 2d c2 30 and accum_cond_result ;merge with previous results
2096: 8d c2 30 sta accum_cond_result
2099: 68 pla ;restore count
209a: aa tax
209b: 20 a2 2e jsr JJ_IncF8F9 ;advance condition table pointer
209e: 20 a2 2e jsr JJ_IncF8F9
20a1: ad c2 30 lda accum_cond_result ;check current result
20a4: d0 03 bne :NotFalse ;not yet false, so keep going
20a6: 4c 30 1f jmp :FindActionLoop ;condition failed, go find another action
20a9: ca :NotFalse dex ;done yet?
20aa: f0 03 beq :DoActionOps ;yes, do action operations
20ac: 4c 0b 20 jmp :Loop ;no, loop
; All conditions for this action have succeeded. Invoke operations.
]index .var $f4 {addr/2}
]table_ptr .var $f8 {addr/2}
20af: ea :DoActionOps nop
20b0: ad 7d 30 lda debug_flag ;check debug flag
20b3: f0 16 beq :NoDebug ;not enabled, skip
20b5: 20 54 2e jsr InA_GetInlineData ;show for 'P' or 'T' mode
20b8: d7 21 .dd2 msg_did
20ba: 20 36 2e jsr JJ_PrintString
20bd: 20 96 2e jsr JJ_PushF6F7 ;push action index
20c0: 20 60 2e jsr JJ_PopF0F1
20c3: 20 48 2e jsr JJ_PrintSignedDec ;print action index
20c6: a9 20 lda #‘ ’
20c8: 20 30 2e jsr JJ_PrintNonNull
20cb: a9 00 :NoDebug lda #$00
20cd: 8d 67 30 sta actionop_arg_idx ;init action op arg index to zero
20d0: 8d 68 30 sta actionop_arg_idx+1
20d3: 20 54 2e jsr InA_GetInlineData ;get pointer to pointers to action opcodes
20d6: 04 2f .dd2 action_op0_ptr
20d8: 20 5d 2e jsr JJ_PushF0F1 ;copy table pointer in $f0-f1...
20db: 20 9f 2e jsr JJ_PopF8F9 ;...to $f8-f9
;
20de: a2 04 ldx #$04 ;at most four operations
20e0: ea :OpLoop nop
20e1: a0 00 ldy #$00
20e3: b1 f8 lda (]table_ptr),y ;get pointer to table N
20e5: 85 f0 sta ]ptr ;store in $f0-f1
20e7: c8 iny
20e8: b1 f8 lda (]table_ptr),y
20ea: 85 f1 sta ]ptr+1
20ec: 20 96 2e jsr JJ_PushF6F7 ;copy action index in $f6-f7
20ef: 20 72 2e jsr JJ_PopF4F5 ; to $f4-f5
20f2: 20 87 2e jsr JJ_AddF0F1_F4F5 ;add to index to get pointer to opcode
20f5: 88 dey ;set Y-reg=0
20f6: b1 f0 lda (]ptr),y ;get action opcode
20f8: 8d 07 1f sta action_opcode ;store (not used?)
20fb: f0 65 beq :NextOp ;opcode $00, do nothing
20fd: 30 08 bmi :HighMsg ;negative value, must be message 51-99; branch
20ff: c9 34 cmp #$34 ;message 1-50?
2101: 30 07 bmi :LowMsg ;yes, branch
2103: c9 66 cmp #$66 ;msg 51-99?
2105: 30 2a bmi :OpNotMsg ;no, branch
; Print a message.
2107: 38 :HighMsg sec
2108: e9 32 sbc #$32 ;change [$66,$96] to [$34,$64] (52-100)
210a: 85 f4 :LowMsg sta ]index ;save message index
210c: a9 00 lda #$00
210e: 85 f5 sta ]index+1 ;set high byte of index to zero
2110: 20 93 2e jsr InA_GetIndirectValue ;get pointer to pointers to messages
2113: 24 2f .dd2 messages_ptr
2115: 20 87 2e jsr JJ_AddF0F1_F4F5 ;add index
2118: 20 87 2e jsr JJ_AddF0F1_F4F5 ;twice (16-bit address values)
211b: a0 00 ldy #$00
211d: b1 f0 lda (]ptr),y ;get pointer to message N
211f: 48 pha ;push low byte
2120: c8 iny
2121: b1 f0 lda (]ptr),y ;get high byte
2123: 85 f1 sta ]ptr+1 ;set $f0-f1 to string pointer
2125: 68 pla
2126: 85 f0 sta ]ptr
2128: 20 42 2e jsr JJ_PrintL1Str ;print message string
212b: 20 33 2e jsr JJ_PrintCR ;follow with CR
212e: 4c 62 21 jmp :NextOp ;loop
; Perform non-message operation. At this point, $f4-f5 and $f6-f7 hold the
; action index.
2131: 38 :OpNotMsg sec
2132: e9 34 sbc #$34 ;remap [$34,$65] to [$00,$31]
2134: 85 f4 sta ]index ;save opcode index
2136: a9 00 lda #$00
2138: 85 f5 sta ]index+1 ;set high byte of index to zero
213a: 20 93 2e jsr InA_GetIndirectValue ;get pointer to pointer to op func table
213d: 2b 2e .dd2 act_oper_ind
213f: a0 01 ldy #$01 ;move past JMP operand
2141: b1 f0 lda (]ptr),y ;get pointer and replace $f0-f1
2143: 48 pha
2144: c8 iny
2145: b1 f0 lda (]ptr),y
2147: 85 f1 sta ]ptr+1
2149: 68 pla
214a: 85 f0 sta ]ptr ;now pointing to opcode table ($270c)
214c: 20 87 2e jsr JJ_AddF0F1_F4F5 ;add opcode index
214f: 20 87 2e jsr JJ_AddF0F1_F4F5 ;add index again to double it (16-bit addrs)
;
2152: a0 00 ldy #$00
2154: b1 f0 lda (]ptr),y ;get pointer to action op function
2156: 8d 60 21 sta _OpCall+1 ;store in self-modified JSR
2159: c8 iny
215a: b1 f0 lda (]ptr),y
215c: 8d 61 21 sta _OpCall+2
215f: 20 0f 28 _OpCall jsr O49_Continue ;self mod; call action operation
2162: 20 a2 2e :NextOp jsr JJ_IncF8F9 ;advance to next table
2165: 20 a2 2e jsr JJ_IncF8F9 ; (16-bit pointers to tables)
2168: ca dex ;done yet?
2169: f0 03 beq ActionLoopEnd ;yes, branch
216b: 4c e0 20 jmp :OpLoop
; Note: we jump here after GET action op fails due to excess inventory,
; presumably to skip the remaining part of the action after the op failed.
216e: ad c4 30 ActionLoopEnd lda continue_flag ;is this a continuation of the previous action?
2171: f0 03 beq :NotCont ;no, branch
2173: 4c 30 1f :JLoop jmp :FindActionLoop ;yes, back to the loop
2176: ad bc 30 :NotCont lda parsed_verb_idx ;is the verb index zero (processing occurrences)?
2179: f0 f8 beq :JLoop ;yes, branch
217b: 4c 47 1f jmp :CheckGetDrop ;no, go check for implicit TAKE and DROP
217e: 0d 49 20 4d+ msg_be_stupid .zstr $0d,‘I MUST BE STUPID, BUT I JUST DON'T’,$0d,‘ ’ ;words are valid, but no action found
+ ‘UNDERSTAND WHAT YOU MEAN’,$0d
21bd: 0d 49 20 43+ msg_cant_yet .zstr $0d,‘I CAN'T DO THAT... YET!’,$0d ;found matching action, but conditions failed
21d7: 20 44 49 44+ msg_did .zstr ‘ DID: ’ ;debug
21de: 20 50 53 42+ msg_psbl .zstr ‘ PSBL: ’ ;debug ("possible?")
;
; See if an implict get/drop action applies here. If we handle the command, we
; clear the "command not handled" flag ($30c0) whether or not the action was
; successful.
;
; On entry:
; (parsed verb and noun indices set)
;
; On exit:
; "command not handled" flag ($30c0) cleared if handled
;
]count .var $f4 {addr/1}
21e6: ad bc 30 ImplicitGetDrop lda parsed_verb_idx ;get verb index
21e9: c9 0a cmp #10 ;TAKE?
21eb: f0 05 beq :HandleTakeDrop ;yes, handle it
21ed: c9 12 cmp #18 ;DROP?
21ef: f0 01 beq :HandleTakeDrop ;yes, handle it
21f1: 60 :Return rts
21f2: ad c3 30 :HandleTakeDrop lda occur_flag ;processing occurrences?
21f5: d0 fa bne :Return ;yes, bail
21f7: ad be 30 lda parsed_noun_idx ;get noun index
21fa: d0 0b bne :HaveNoun
21fc: 20 54 2e jsr InA_GetInlineData
21ff: 62 23 .dd2 msg_huh
2201: 20 36 2e jsr JJ_PrintString ;no noun provided (or GET ANY); act confused
2204: 4c 21 23 jmp :ActionHandled ;bail
2207: ad bc 30 :HaveNoun lda parsed_verb_idx ;get verb index
220a: c9 0a cmp #10 ;TAKE?
220c: d0 48 bne :SkipInvCount ;no, must be drop; branch
; Handle TAKE action.
220e: 20 a5 2e jsr JJ_CountHeldObjs ;count objects
2211: ac 75 30 ldy hdr_max_held ;get limit
2214: 88 dey ;reduce by one (for >= comparison)
2215: c4 f4 cpy ]count ;are we over limit?
2217: 10 3d bpl :SkipInvCount ;no, branch to common processing
2219: 20 54 2e jsr InA_GetInlineData
221c: 24 22 .dd2 msg_carry_2_much
221e: 20 36 2e jsr JJ_PrintString ;print "carrying too much" message
2221: 4c 21 23 jmp :ActionHandled ;bail
msg_carry_2_much
2224: 0d 20 49 27+ .zstr $0d,‘ I'M CARRYING TOO MUCH!’,$0d,‘ TRY: "TAKE ’
+ ‘INVENTORY"’,$0d,$0d
; Search the item names for /WORD/. We do this by walking through the strings
; as a pile. This is a little imprecise because the getdrop strings in the item
; list both start and end with a '/', but in practice it's unlikely to false-
; positive since the next character will be an item number, followed by a string
; length.
]item_str_ptr .var $f2 {addr/2}
]remain_len .var $f4 {addr/2}
2256: a9 00 :SkipInvCount lda #$00
2258: 8d 06 1f sta fail_msg_index ;clear flag
225b: 20 93 2e jsr InA_GetIndirectValue ;get total length of item name string pool
225e: 03 31 .dd2 item_names_len
2260: 20 84 2e jsr JJ_SetF4F5_F0F1 ;copy to $f4-f5
2263: 20 93 2e jsr InA_GetIndirectValue ;get pointer to table of pointers to names ($439f)
2266: 28 2f .dd2 item_names_ptr
2268: a0 00 ldy #$00
226a: b1 f0 lda (]ptr),y ;get pointer to item 0
226c: c8 iny
226d: 48 pha
226e: b1 f0 lda (]ptr),y
2270: 85 f1 sta ]ptr+1 ;put in $f0-f1
2272: 68 pla
2273: 85 f0 sta ]ptr
;
2275: ea :SearchLoop nop
2276: 20 51 2e :SearchLoop1 jsr JJ_IncF0F1 ;advance string pointer
2279: 20 63 2e jsr JJ_DecF4F5 ;decrement remaining len
227c: a5 f5 lda ]remain_len+1 ;check for zero: load high byte
227e: 30 06 bmi :JDone ;if negative, we're done
2280: d0 07 bne :InnerLoop ;if nonzero, keep going
2282: c5 f4 cmp ]remain_len ;must be zero; is low byte also zero?
2284: d0 03 bne :InnerLoop ;no, keep going
2286: 4c 27 23 :JDone jmp :SearchDone ;len at zero, exit loop
2289: a0 00 :InnerLoop ldy #$00
228b: a9 2f lda #‘/’ ;looking for a '/'
228d: d1 f0 cmp (]ptr),y ;test char
228f: f0 0f beq :FoundSlash ;got match, check further
2291: 20 51 2e jsr JJ_IncF0F1 ;advance string pointer
2294: 20 63 2e jsr JJ_DecF4F5 ;decrement remaining len
2297: a5 f4 lda ]remain_len ;check remaining len
2299: 05 f5 ora ]remain_len+1
229b: d0 ec bne :InnerLoop ;not zero, loop
229d: 4c 27 23 jmp :SearchDone ;done with search, exit loop
22a0: 20 81 2e :FoundSlash jsr JJ_SetF2F3_F0F1 ;copy string pointer to $f2-f3
22a3: 20 6c 2e jsr JJ_IncF2F3 ;advance past '/'
22a6: a0 00 ldy #$00
22a8: b9 80 30 :MatchLoop lda word_trim_buf,y ;compare to trimmed noun string
22ab: f0 0a beq :FoundMatch ;if we hit end of user input, branch
22ad: d1 f2 cmp (]item_str_ptr),y ;compare to string in item list
22af: d0 c4 bne :SearchLoop ;if we didn't match, branch to loop
22b1: c8 iny ;advance pointer
22b2: cc 69 30 cpy hdr_word_len ;have we matched the max chars required?
22b5: 30 f1 bmi :MatchLoop ;not yet, branch
;
]item_num .var $f4 {addr/2}
22b7: a9 2f :FoundMatch lda #‘/’ ;all chars matched; if the trimmed noun was < 4
22b9: d1 f2 cmp (]item_str_ptr),y ; chars, make sure the item string is as well
22bb: d0 b8 bne :SearchLoop ;no, partial match only; branch to loop
22bd: c8 iny ;advance past '/'
22be: 20 6f 2e jsr JJ_PushF4F5 ;preserve $f4-f5
22c1: 20 5d 2e jsr JJ_PushF0F1 ;preserve $f0-f1
22c4: b1 f2 lda (]item_str_ptr),y ;get item number (follows closing '/')
22c6: 85 f4 sta ]item_num
22c8: a9 00 lda #$00 ;set item number high byte to zero
22ca: 85 f5 sta ]item_num+1
22cc: 20 93 2e jsr InA_GetIndirectValue ;get pointer to item location data
22cf: 26 2f .dd2 item_rooms_ptr
22d1: 20 87 2e jsr JJ_AddF0F1_F4F5 ;add item number to pointer
22d4: 20 87 2e jsr JJ_AddF0F1_F4F5 ;add it again (16-bit values)
22d7: 20 81 2e jsr JJ_SetF2F3_F0F1 ;copy pointer to item's room data to $f2-f3
22da: 20 60 2e jsr JJ_PopF0F1 ;restore $f0-f1
22dd: 20 72 2e jsr JJ_PopF4F5 ;restore $f4-f5
; We've identified the desired item. Do the actual TAKE or DROP.
22e0: ad bc 30 lda parsed_verb_idx ;get verb index
22e3: a0 00 ldy #$00
22e5: c9 0a cmp #10 ;TAKE?
22e7: f0 16 beq :DoTake ;yes, branch
22e9: b1 f2 lda (]item_str_ptr),y ;get item location
22eb: c9 ff cmp #ITEM_HELD ;is it in player's inventory?
22ed: f0 08 beq :DropIt ;yes, branch
22ef: a9 01 lda #$01
22f1: 8d 06 1f :SetFailure sta fail_msg_index ;set failure code
22f4: 4c 76 22 jmp :SearchLoop1 ;search for another match (why?)
22f7: ad e9 30 :DropIt lda current_room
22fa: 91 f2 sta (]item_str_ptr),y ;set item location to the current room
22fc: 4c 16 23 jmp :SayOkay
22ff: b1 f2 :DoTake lda (]item_str_ptr),y ;get item location
2301: c9 ff cmp #ITEM_HELD ;already in inventory?
2303: d0 04 bne :NotInInv ;no, branch
2305: a9 04 lda #$04
2307: d0 e8 bne :SetFailure ;set failure code and loop
2309: cd e9 30 :NotInInv cmp current_room ;is item in the current room?
230c: f0 04 beq :TakeIt ;yes, branch
230e: a9 02 lda #$02
2310: d0 df bne :SetFailure ;set failure code and loop
2312: a9 ff :TakeIt lda #ITEM_HELD
2314: 91 f2 sta (]item_str_ptr),y ;move item to player's inventory
2316: 20 54 2e :SayOkay jsr InA_GetInlineData
2319: 69 23 .dd2 msg_ok
231b: 20 36 2e jsr JJ_PrintString ;print "ok"
231e: 20 15 2e jsr JJ_DescribeRoom ;redraw room description
2321: a9 00 :ActionHandled lda #$00
2323: 8d c0 30 sta cmd_not_hnd_flag ;clear flag to indicate that command was handled
2326: 60 :Return rts
; Search complete, report appropriate failure message.
2327: ad 06 1f :SearchDone lda fail_msg_index ;get failure code
232a: c9 01 cmp #$01
232c: d0 08 bne :Not1
232e: 20 54 2e jsr InA_GetInlineData
2331: 6e 23 .dd2 msg_not_carrying
2333: 20 36 2e jsr JJ_PrintString ;failure #1: DROP on item not carried
2336: c9 02 :Not1 cmp #$02
2338: d0 08 bne :Not2
233a: 20 54 2e jsr InA_GetInlineData
233d: 86 23 .dd2 msg_dont_see
233f: 20 36 2e jsr JJ_PrintString ;failure #2: TAKE on item not present
2342: c9 04 :Not2 cmp #$04
2344: d0 08 bne :Not4
2346: 20 54 2e jsr InA_GetInlineData
2349: 9d 23 .dd2 msg_already_have
234b: 20 36 2e jsr JJ_PrintString ;failure #4: TAKE on item already in inventory
234e: c9 00 :Not4 cmp #$00
2350: d0 cf bne :ActionHandled
2352: ad c3 30 lda occur_flag ;processing an occurrence?
2355: d0 cf bne :Return ;yes, don't show message
2357: 20 54 2e jsr InA_GetInlineData
235a: b2 23 .dd2 msg_beyond_power
235c: 20 36 2e jsr JJ_PrintString ;failure #0: incompatible noun ("TAKE MERCHANT")
235f: 4c 21 23 jmp :ActionHandled
2362: 20 48 55 48+ msg_huh .zstr ‘ HUH?’,$0d
2369: 20 4f 4b 0d+ msg_ok .zstr ‘ OK’,$0d
msg_not_carrying
236e: 0d 20 49 27+ .zstr $0d,‘ I'M NOT CARRYING IT!’,$0d
2386: 0d 49 20 44+ msg_dont_see .zstr $0d,‘I DON'T SEE IT HERE!’,$0d
msg_already_have
239d: 0d 20 49 20+ .zstr $0d,‘ I ALREADY HAVE IT’,$0d
msg_beyond_power
23b2: 0d 49 54 53+ .zstr $0d,‘ITS BEYOND MY POWER TO DO THAT.’,$0d
;
; Generates a crude random number from 1-100.
;
; The first call uses the keyboard input counter, so is reasonably random.
; Subsequent calls without keyboard input will have a short cycle.
;
; On exit:
; A-reg: result (1-100)
; (X-reg and Y-reg preserved)
;
23d4: 8e 35 30 GetRandom stx tmp_save_x2 ;preserve X-reg
23d7: ad b0 2e lda kbd_rng_seed ;get random seed
23da: a2 0c ldx #12 ;multiply by 12 (by adding)
23dc: 18 :MulLoop clc
23dd: 6d b0 2e adc kbd_rng_seed
23e0: ca dex
23e1: d0 f9 bne :MulLoop
23e3: 69 01 adc #$01 ;add 1
23e5: 8d b0 2e sta kbd_rng_seed ;update seed
23e8: ae 35 30 ldx tmp_save_x2 ;restore X-reg
23eb: c9 64 :ModLoop cmp #100 ;is it < 100?
23ed: 90 05 bcc :Done ;yes, branch
23ef: 38 sec ;subtract 100
23f0: e9 64 sbc #100
23f2: d0 f7 bne :ModLoop ;loop (unless we hit zero)
23f4: 69 01 :Done adc #$01 ;add 1 to make it 1-100
23f6: 60 rts
;
; Handles a "GO" command, such as "GO NORTH" or "N".
;
]dir_index .var $f0 {addr/2}
23f7: a9 00 HandleGo lda #$00
23f9: 8d 06 1f sta fail_msg_index ;init failure message index
23fc: ad d8 30 lda darkness_flag ;is this a dark area?
23ff: f0 1d beq :Lit ;no, branch
2401: 20 93 2e jsr InA_GetIndirectValue ;get pointer to item location data
2404: 26 2f .dd2 item_rooms_ptr
2406: a0 12 ldy #18 ;lightsource object (#9)
2408: b1 f0 lda (]dir_index),y ;get current location
240a: c9 ff cmp #ITEM_HELD ;in inventory?
240c: f0 10 beq :Lit ;yes, branch
240e: cd e9 30 cmp current_room ;in current room?
2411: f0 0b beq :Lit ;yes, branch
2413: 8c 06 1f sty fail_msg_index ;store nonzero value
2416: 20 54 2e jsr InA_GetInlineData
2419: bf 24 .dd2 msg_dark_danger
241b: 20 4b 2e jsr JJ_PrintFlashing ;don't have light, print warning
;
241e: ad be 30 :Lit lda parsed_noun_idx ;get noun (1-6), or 0 if not specified
2421: 38 sec
2422: e9 01 sbc #$01 ;subtract 1
2424: 10 0b bpl :HaveDir ;if it went negative, no direction was specified
2426: 20 54 2e jsr InA_GetInlineData
2429: e5 24 .dd2 msg_need_dir
242b: 20 36 2e jsr JJ_PrintString ;print "I also need a direction"
242e: 4c 99 24 jmp :Return
2431: 85 f0 :HaveDir sta ]dir_index ;save direction index
2433: a9 00 lda #$00
2435: 85 f1 sta ]dir_index+1 ;set high byte to zero
2437: 20 84 2e jsr JJ_SetF4F5_F0F1 ;copy direction index to $f4-f5
243a: 20 87 2e jsr JJ_AddF0F1_F4F5 ;add it to itself
243d: 20 84 2e jsr JJ_SetF4F5_F0F1 ;copy doubled value to $f4-f5
2440: 20 54 2e jsr InA_GetInlineData ;get pointer to table of pointers to exit tables
2443: 18 2f .dd2 vis_exits_n_ptr
2445: 20 87 2e jsr JJ_AddF0F1_F4F5 ;add doubled direction index to it
]ptr .var $f0 {addr/2}
]exit_ptr .var $f4 {addr/2}
2448: a0 00 ldy #$00
244a: b1 f0 lda (]ptr),y ;get pointer low byte from table entry
244c: 85 f4 sta ]exit_ptr ;store in ZP
244e: c8 iny
244f: b1 f0 lda (]ptr),y ;repeat for high byte
2451: 85 f5 sta ]exit_ptr+1 ;now $f4-f5 points to exit table for this direction
2453: 20 93 2e jsr InA_GetIndirectValue ;get current room
2456: e9 30 .dd2 current_room
2458: 20 87 2e jsr JJ_AddF0F1_F4F5 ;add to exit table pointer
245b: ac e9 30 ldy current_room ;get current room as index (effectively doubling it)
245e: b1 f0 lda (]ptr),y ;get exit room # (just the low byte of 16-bit value)
2460: d0 29 bne :ValidExit ;if nonzero, this is valid
;
2462: ae 06 1f ldx fail_msg_index ;is the room dark?
2465: d0 0b bne :DarkFail ;yes, branch
2467: 20 54 2e jsr InA_GetInlineData
246a: 01 25 .dd2 msg_cant_go
246c: 20 36 2e jsr JJ_PrintString ;tell them they can't go that way
246f: 4c 99 24 jmp :Return
2472: 20 54 2e :DarkFail jsr InA_GetInlineData ;going the wrong way in the dark is fatal
2475: 9a 24 .dd2 msg_fell_broke
2477: 20 36 2e jsr JJ_PrintString ;let them know
247a: a9 00 lda #$00
247c: 8d d8 30 sta darkness_flag ;reset darkness flag
247f: ad 73 30 lda hdr_max_room ;limbo room
2482: 8d e9 30 sta current_room ;move them there
2485: 20 15 2e jsr JJ_DescribeRoom ;redraw room description
2488: 4c 99 24 jmp :Return ;enjoy the afterlife
248b: 8d e9 30 :ValidExit sta current_room
248e: 20 54 2e jsr InA_GetInlineData
2491: 69 23 .dd2 msg_ok
2493: 20 36 2e jsr JJ_PrintString
2496: 20 15 2e jsr JJ_DescribeRoom
2499: 60 :Return rts
249a: 0d 20 49 20+ msg_fell_broke .zstr $0d,‘ I FELL & BROKE MY NECK!’,$0d,‘I'M DEAD!’
+ $0d
24bf: 0d 20 49 54+ msg_dark_danger .zstr $0d,‘ ITS DANGEROUS TO MOVE IN THE DARK!’,$0d
24e5: 0d 20 49 20+ msg_need_dir .zstr $0d,‘ I ALSO NEED A DIRECTION.’,$0d
2501: 0d 20 49 20+ msg_cant_go .zstr $0d,‘ I CAN'T GO IN THAT DIRECTION.’,$0d
2522: 00 00 00 00+ .junk 478
2700: 4c 38 2b jmp Divide16
2703: 4c 0c 27 J_act_oper_tab jmp act_oper_tab ;not used as a jump
2706: 4c 56 27 J_CountHeldObjs jmp CountHeldObjs
2709: 4c 38 2b J_Divide16 jmp Divide16
270c: 7c 27 act_oper_tab .dd2 O34_Get ;$34 get ITEM#
270e: a6 27 .dd2 O35_Drop ;$35 drop ITEM#
2710: c7 27 .dd2 O36_MoveTo ;$36 moveto ROOM#
2712: ff 27 .dd2 O37_Destroy ;$37 destroy ITEM#
2714: 15 28 .dd2 O38_SetDark ;$38 set_dark
2716: 56 28 .dd2 O39_ClearDark ;$39 clear_dark
2718: d4 28 .dd2 O3A_SetFlag ;$3a set_flag FLAG#
271a: ff 27 .dd2 O37_Destroy ;$3b destroy2 (same as $37)
271c: f2 28 .dd2 O3C_ClearFlag ;$3c clear_flag FLAG#
271e: fd 28 .dd2 O3D_Die ;$3d die
2720: 20 29 .dd2 O3E_Put ;$3e put ITEM#, ROOM#
2722: 4a 29 .dd2 O3F_GameOver ;$3f game_over
2724: 66 29 .dd2 O40_DescribeRoom ;$40 look
2726: d9 29 .dd2 O41_Score ;$41 score
2728: d9 2a .dd2 O42_Inventory ;$42 inventory
272a: dd 2a .dd2 O43_Set0 ;$43 set_0
272c: e2 2a .dd2 O44_Clear0 ;$44 clear_0
272e: e7 2a .dd2 O45_RefillLamp ;$45 refill_lamp
2730: 06 2b .dd2 O46_ClearScreen ;$46 clear_screen
2732: b5 27 .dd2 O47_SaveGame ;$47 save_game
2734: d3 27 .dd2 O48_Swap ;$48 swap ITEM#, ITEM#
2736: 0f 28 .dd2 O49_Continue ;$49 continue
2738: 96 27 .dd2 O4A_SuperGet ;$4a superget ITEM#
273a: 07 2b .dd2 O4B_PutWith ;$4b put_with ITEM#, ITEM#
273c: 66 29 .dd2 O40_DescribeRoom ;$4c look2 (same as $40)
273e: 1a 28 .dd2 O4D_DecreaseCounter ;$4d decrease_counter
2740: 2d 28 .dd2 O4E_PrintCounter ;$4e print_counter
2742: 3b 28 .dd2 O4F_SetCounter ;$4f set_counter VALUE
2744: 49 28 .dd2 O50_SwapLocDefault ;$50 swap_loc_default
2746: 5b 28 .dd2 O51_SelectCounter ;$51 select_counter
2748: 8b 28 .dd2 O52_AddCounter ;$52 add_counter
274a: a7 28 .dd2 O53_SubtractCounter ;$53 subtract_counter
274c: bf 28 .dd2 O54_PrintNoun ;$54 print_noun
274e: c8 28 .dd2 O55_PrintNounNl ;$55 print_noun_nl
2750: d0 28 .dd2 O56_Nl ;$56 nl
2752: df 28 .dd2 O57_SwapLoc ;$57 swap_loc ALT#
2754: b9 27 .dd2 O58_Pause ;$58 pause
;
; Counts the number of items in the player's inventory.
;
; On exit:
; $f4: number of items
;
• Clear variables
]ptr .var $f0 {addr/2}
]counter .var $f4 {addr/1}
2756: 20 57 2e CountHeldObjs jsr JJ_PushRegs ;preserve registers
2759: ae 6f 30 ldx hdr_max_item ;run through full set of items
275c: a9 00 lda #$00
275e: 85 f4 sta ]counter ;init count to zero
2760: 20 93 2e jsr InA_GetIndirectValue ;get pointer to item room data
2763: 26 2f .dd2 item_rooms_ptr
2765: a0 00 ldy #$00
2767: b1 f0 :Loop lda (]ptr),y ;get item's room
2769: c9 ff cmp #ITEM_HELD ;in player inventory?
276b: d0 02 bne :NotHeld ;no, branch
276d: e6 f4 inc ]counter ;yes, increment count
276f: 20 51 2e :NotHeld jsr JJ_IncF0F1 ;advance pointer
2772: 20 51 2e jsr JJ_IncF0F1 ; twice (16-bit data)
2775: ca dex ;done yet?
2776: d0 ef bne :Loop ;no, loop
2778: 20 5a 2e jsr JJ_PopRegs ;restore registers
277b: 60 rts
;
; Action op $34: get item. Checks to see if inventory is full.
;
]action_arg .var $f0 {addr/2}
]count .var $f4 {addr/1}
277c: 20 a5 2e O34_Get jsr JJ_CountHeldObjs ;get count of held items into $f4
277f: ad 75 30 lda hdr_max_held ;get inventory limit
2782: 38 sec
2783: e9 01 sbc #$01 ;subtract one
2785: c5 f4 cmp ]count ;compare to current count
2787: 10 0d bpl O4A_SuperGet ;if (max-1) >= count, branch to grab item
2789: 68 pla ;failed, pull return address off stack
278a: 68 pla
278b: 20 54 2e jsr InA_GetInlineData
278e: a7 29 .dd2 msg_overburden
2790: 20 36 2e jsr JJ_PrintString ;display failure message
2793: 4c 06 2e jmp JJ_ActionLoopEnd ;skip remaining actions
;
; Action op $4a: get item, regardless of inventory count.
;
2796: 20 18 2e O4A_SuperGet jsr JJ_GetActionArg ;item index in $f0-f1
2799: 20 45 2e jsr JJ_GetItemLocation ;get location; puts room pointer in $f0-f1
279c: a9 ff lda #ITEM_HELD ;put in inventory
279e: a0 00 ldy #$00
27a0: 91 f0 sta (]action_arg),y ;update location
27a2: 20 15 2e :DescribeReturn jsr JJ_DescribeRoom ;redraw room description
27a5: 60 rts
;
; Action op $35: drop item.
;
27a6: 20 18 2e O35_Drop jsr JJ_GetActionArg
27a9: 20 45 2e jsr JJ_GetItemLocation ;get location; puts room pointer in $f0-f1
27ac: ad e9 30 lda current_room ;move to current room
27af: a0 00 ldy #$00
27b1: 91 f0 sta (]action_arg),y ;update location
27b3: f0 ed beq :DescribeReturn ;(always)
;
; Action op $47: save game.
;
27b5: 20 09 2e O47_SaveGame jsr JJ_SaveGame
27b8: 60 rts
;
; Action op $58: pause briefly. Inner loop is 256*8 cycles, outer loop adds 8
; cycles, total is 256*(8+256*8-1)-1 = 526079. With the complicated
; initialization call it's about 526355, which is about half a second.
;
27b9: 20 54 2e O58_Pause jsr InA_GetInlineData ;set $f0-f1 to zero
27bc: 00 00 .dd2 $0000
27be: e6 f0 :DelayLoop inc ]action_arg
27c0: d0 fc bne :DelayLoop
27c2: e6 f1 inc ]action_arg+1
27c4: d0 f8 bne :DelayLoop
27c6: 60 rts
;
; Action op $36: move to specified room.
;
27c7: 20 18 2e O36_MoveTo jsr JJ_GetActionArg ;get argument in $f0-f1
27ca: a5 f0 lda ]action_arg
27cc: 8d e9 30 sta current_room ;set current room
27cf: 20 15 2e :RedrawReturn jsr JJ_DescribeRoom ;redraw room description
27d2: 60 rts
;
; Action op $48: swap the locations of two items.
;
; If both items are in the current room, the screen will be redrawn twice.
;
]item2_loc .var $f0 {addr/2}
]item1_loc .var $f2 {addr/2}
27d3: 20 18 2e O48_Swap jsr JJ_GetActionArg ;get argument in $f0-f1
27d6: 20 45 2e jsr JJ_GetItemLocation ;get location ptr in $f0-f1
27d9: 20 5d 2e jsr JJ_PushF0F1 ;push item #1 location ptr
27dc: 20 18 2e jsr JJ_GetActionArg ;get argument in $f0-f1
27df: 20 45 2e jsr JJ_GetItemLocation ;get item #2 location ptr in $f0-f1
27e2: 20 78 2e jsr JJ_PopF2F3 ;pop item #1 location ptr into $f2-f3
27e5: 48 pha ;push room # of item #2
27e6: a0 00 ldy #$00
27e8: b1 f2 lda (]item1_loc),y ;get location of item #1
27ea: 91 f0 sta (]item2_loc),y ;move item #2 there
27ec: 68 pla ;pull room # of item #2
27ed: 91 f2 sta (]item1_loc),y ;move item #1 there
27ef: cd e9 30 cmp current_room ;is item #1 now in the current room?
27f2: d0 03 bne :NotHere1 ;no, branch
27f4: 20 15 2e jsr JJ_DescribeRoom ;yes, redraw room description
27f7: b1 f0 :NotHere1 lda (]item2_loc),y
27f9: cd e9 30 cmp current_room ;is item #2 now in the current room?
27fc: f0 d1 beq :RedrawReturn ;yes, redraw room description
27fe: 60 rts
;
; Action op $37: destroy item (move to room zero).
;
]ptr .var $f0 {addr/2}
27ff: 20 18 2e O37_Destroy jsr JJ_GetActionArg ;get argument in $f0-f1
2802: 20 45 2e jsr JJ_GetItemLocation ;get location ptr in $f0-f1
2805: a9 00 lda #$00 ;nowhere
2807: a0 00 ldy #$00
2809: 91 f0 sta (]ptr),y ;set location
280b: 20 15 2e jsr JJ_DescribeRoom ;redraw room description
280e: 60 rts
;
; Action $49: continue into next action slot.
;
280f: a9 ff O49_Continue lda #$ff
2811: 8d c4 30 sta continue_flag ;set flag, read by action loop
2814: 60 rts
;
; Action $38: set the darkness flag (#15).
;
2815: a0 0f O38_SetDark ldy #15 ;set flag 15
2817: 4c d9 28 jmp SetFlagN
;
; Action $4d: decrease current counter.
;
]counter_value .var $f0 {addr/2}
O4D_DecreaseCounter
281a: 20 93 2e jsr InA_GetIndirectValue ;get value of "current counter" in $f0-f1
281d: c7 30 .dd2 counter_register
281f: 20 4e 2e jsr JJ_DecF0F1 ;decrement it
2822: a5 f0 lda ]counter_value ;save it
2824: 8d c7 30 sta counter_register
2827: a5 f1 lda ]counter_value+1
2829: 8d c8 30 sta counter_register+1
282c: 60 rts
;
; Action $4e: print current counter.
;
O4E_PrintCounter
282d: 20 93 2e jsr InA_GetIndirectValue ;get value of "current counter" in $f0-f1
2830: c7 30 .dd2 counter_register
2832: 20 48 2e jsr JJ_PrintSignedDec ;print as signed decimal
2835: a9 20 lda #‘ ’
2837: 20 30 2e jsr JJ_PrintNonNull ;add a space
283a: 60 rts
;
; Action $4f: set value of current counter.
;
283b: 20 18 2e O4F_SetCounter jsr JJ_GetActionArg ;get new value in $f0-f1
283e: a5 f0 lda ]counter_value ;copy value to "current counter"
2840: 8d c7 30 sta counter_register
2843: a5 f1 lda ]counter_value+1
2845: 8d c8 30 sta counter_register+1
2848: 60 rts
;
; Action $50: swaps "current" and "default alternate" locations.
;
O50_SwapLocDefault
2849: ad e9 30 lda current_room
284c: ac eb 30 ldy def_alt_room
284f: 8c e9 30 sty current_room
2852: 8d eb 30 sta def_alt_room
2855: 60 rts
;
; Action $39: clear darkness flag.
;
2856: a0 0f O39_ClearDark ldy #15 ;clear flag 15
2858: 4c f7 28 jmp ClearFlagN
;
; Action $51: swap current counter with numbered storage location.
;
; Most docs refer to this as "selecting" a counter, but it's more like swapping
; the contents of the "current counter" register with a value in RAM.
;
]ptr .var $f0 {addr/2}
O51_SelectCounter
285b: 20 18 2e jsr JJ_GetActionArg ;get argument in $f0-f1
285e: 20 84 2e jsr JJ_SetF4F5_F0F1 ;copy to $f4-f5
2861: 20 87 2e jsr JJ_AddF0F1_F4F5 ;double it
2864: 20 84 2e jsr JJ_SetF4F5_F0F1 ;copy doubled value to $f4-f5
2867: 20 54 2e jsr InA_GetInlineData ;get pointer to counter storage
286a: f1 30 .dd2 game_counters
286c: 20 87 2e jsr JJ_AddF0F1_F4F5 ;add doubled arg
;
286f: a0 00 ldy #$00
2871: ad c7 30 lda counter_register ;get current value
2874: 48 pha ;push on stack
2875: b1 f0 lda (]ptr),y ;get value from counter array
2877: 8d c7 30 sta counter_register ;replace current value
287a: 68 pla ;pull previous current value from stack
287b: 91 f0 sta (]ptr),y ;store into array
287d: c8 iny ;repeat for high byte
287e: b1 f0 lda (]ptr),y
2880: 48 pha
2881: ad c8 30 lda counter_register+1
2884: 91 f0 sta (]ptr),y
2886: 68 pla
2887: 8d c8 30 sta counter_register+1
288a: 60 rts
;
; Action $52: add argument to the "current counter".
;
]new_value .var $f0 {addr/2}
288b: 20 18 2e O52_AddCounter jsr JJ_GetActionArg ;get argument in $f0-f1
288e: 20 84 2e jsr JJ_SetF4F5_F0F1 ;copy to $f4-f5
2891: 20 93 2e jsr InA_GetIndirectValue ;get current counter value
2894: c7 30 .dd2 counter_register
2896: 20 87 2e jsr JJ_AddF0F1_F4F5 ;add argument to it
2899: a0 00 ldy #$00 ;?
289b: a5 f0 lda ]new_value ;copy new value to the counter
289d: 8d c7 30 sta counter_register
28a0: c8 iny ;?
28a1: a5 f1 lda ]new_value+1
28a3: 8d c8 30 sta counter_register+1
28a6: 60 rts
;
; Action $53: subtract argument from the "current counter".
;
O53_SubtractCounter
28a7: 20 18 2e jsr JJ_GetActionArg ;get argument in $f0-f1
28aa: a0 00 ldy #$00 ;?
28ac: 38 sec
28ad: ad c7 30 lda counter_register ;do the subtraction manually
28b0: e5 f0 sbc ]new_value
28b2: 8d c7 30 sta counter_register
28b5: c8 iny ;?
28b6: ad c8 30 lda counter_register+1
28b9: e5 f1 sbc ]new_value+1
28bb: 8d c8 30 sta counter_register+1
28be: 60 rts
;
; Action op $54: prints the noun the user typed.
;
; The command parser left the noun, with whitespace trimmed away, in the trim
; buffer.
;
28bf: 20 54 2e O54_PrintNoun jsr InA_GetInlineData ;get pointer to trim buf
28c2: 80 30 .dd2 word_trim_buf
28c4: 20 36 2e jsr JJ_PrintString ;print it
28c7: 60 rts
;
; Action op $55: print the noun the user typed, then a newline.
;
28c8: 20 54 2e O55_PrintNounNl jsr InA_GetInlineData ;get pointer to trim buf
28cb: 80 30 .dd2 word_trim_buf
28cd: 20 36 2e jsr JJ_PrintString ;print it, fall through to print newline
;
; Action op $56: print a newline.
;
28d0: 20 33 2e O56_Nl jsr JJ_PrintCR ;print a newline
28d3: 60 rts
;
; Action op $3a: set flag to true.
;
]arg_val .var $f0 {addr/2}
28d4: 20 18 2e O3A_SetFlag jsr JJ_GetActionArg ;get arg in $f0-f1
28d7: a4 f0 ldy ]arg_val ;use low byte as index
; Sets game flag N, specified by Y-reg.
28d9: a9 ff SetFlagN lda #$ff
28db: 99 c9 30 sta action_flags,y ;set flag
28de: 60 rts
;
; Action op $57: swap the player's current location with the Nth alternate room
; slot.
;
; NOTE: this is using the action argument as a pointer. Since the argument is a
; small integer, this will use low zero-page addresses for storage, which is bad
; since it won't be saved/restored. Another weird thing is that it's using the
; room number from the default alt slot as an index. (Compare to implementation
; of O50_SwapLocDefault at $2849.)
;
; I suspect this is broken, but I haven't found a game that uses it.
;
28df: 20 18 2e O57_SwapLoc jsr JJ_GetActionArg ;get action argument (should be alt room slot number)
28e2: ac eb 30 ldy def_alt_room ;get default alt room number
28e5: b1 f0 lda (]arg_val),y ;get ?!
28e7: 48 pha
28e8: ad e9 30 lda current_room ;get current room
28eb: 91 f0 sta (]arg_val),y ;store ?!
28ed: 68 pla
28ee: 8d e9 30 sta current_room ;update current room
28f1: 60 rts
;
; Action op $3c: clear flag.
;
28f2: 20 18 2e O3C_ClearFlag jsr JJ_GetActionArg ;get arg in $f0-f1
28f5: a4 f0 ldy ]arg_val ;use low byte as index
; Clears game flag N, specified by Y-reg.
28f7: a9 00 ClearFlagN lda #$00
28f9: 99 c9 30 sta action_flags,y ;clear flag
28fc: 60 rts
;
; Action op $3d: die.
;
28fd: 20 54 2e O3D_Die jsr InA_GetInlineData
2900: 14 29 .dd2 msg_im_dead
2902: 20 36 2e jsr JJ_PrintString ;print "I'm dead" message
2905: ad 73 30 lda hdr_max_room ;get last room defined (limbo)
2908: 8d e9 30 sta current_room ;make current
290b: a9 00 lda #$00
290d: 8d d8 30 sta darkness_flag ;clear darkness flag
2910: 20 15 2e jsr JJ_DescribeRoom ;redraw room description
2913: 60 rts
2914: 20 49 27 4d+ msg_im_dead .zstr ‘ I'M DEAD!’,$0d
;
; Action op $3e: put item in specified room.
;
2920: 20 18 2e O3E_Put jsr JJ_GetActionArg ;get item # arg
2923: 20 45 2e jsr JJ_GetItemLocation ;get item location ptr in $f0-f1
2926: 20 5d 2e jsr JJ_PushF0F1 ;push that
2929: 20 18 2e jsr JJ_GetActionArg ;get room # arg
292c: 20 78 2e jsr JJ_PopF2F3 ;pop item location ptr into $f2-f3
;
292f: a0 00 ldy #$00
2931: b1 f2 lda (]item1_loc),y ;get item's current location
2933: 48 pha ;save on stack
2934: a5 f0 lda ]arg_val ;get new room #
2936: 91 f2 sta (]item1_loc),y ;move item there
2938: cd e9 30 cmp current_room ;is current room the new room?
293b: d0 03 bne :NotNew ;no, branch
293d: 20 15 2e jsr JJ_DescribeRoom ;redraw room description
2940: 68 :NotNew pla ;pull item's previous room #
2941: cd e9 30 cmp current_room ;was it in this room?
2944: d0 03 bne :Return ;no, branch
2946: 20 15 2e jsr JJ_DescribeRoom ;redraw room description
2949: 60 :Return rts
;
; Action op $3f: game over. Inform the user and ask if they want to play again.
;
294a: 20 54 2e O3F_GameOver jsr InA_GetInlineData
294d: 6a 29 .dd2 msg_advent_over
294f: 20 36 2e jsr JJ_PrintString ;print game over, ask if they want to go again
2952: 20 39 2e jsr JJ_GetInput ;get input
2955: ad 33 2f lda kbd_scratch_buf
2958: c9 4e cmp #‘N’ ;no?
295a: d0 03 bne :NotN
295c: 4c 59 ff jmp MON_OLDRST ;exit to monitor
295f: c9 59 :NotN cmp #‘Y’ ;yes?
2961: d0 e7 bne O3F_GameOver
2963: 4c 2d 2e jmp J_Start ;restart game
;
; Action op $40: describe room.
;
O40_DescribeRoom
2966: 20 15 2e jsr JJ_DescribeRoom ;redraw room description
2969: 60 rts
296a: 20 54 48 49+ msg_advent_over .zstr ‘ THIS ADVENTURE IS OVER.’,$0d,‘ WANT TO TRY TH’
+ ‘IS ADVENTURE AGAIN? ’
29a7: 0d 20 49 27+ msg_overburden .zstr $0d,‘ I'M CARRYING TOO MUCH.’,$0d,‘ TRY: "TAKE ’
+ ‘INVENTORY"’,$0d,$0d
;
; Action op $41: display score.
;
; If all treasures are in the treasure room, this will print the victory message
; and jump to the game-over handler.
;
; (preserves X-reg)
;
• Clear variables
]name_ptr .var $f0 {addr/2}
]str_ptr .var $f2 {addr/2}
]tr_count .var $f4 {addr/1}
]room_ptr .var $f8 {addr/2}
29d9: a9 00 O41_Score lda #$00 ;init treasure counter
29db: 85 f4 sta ]tr_count
29dd: 8a txa ;preserve X-reg (why?)
29de: 48 pha
29df: ae 6f 30 ldx hdr_max_item ;get max item #
29e2: e8 inx ;add one to make it a count
29e3: 20 9c 2e jsr JJ_PushF8F9 ;preserve $f8-f9
29e6: 20 93 2e jsr InA_GetIndirectValue ;get pointer to item room data
29e9: 26 2f .dd2 item_rooms_ptr
29eb: 20 5d 2e jsr JJ_PushF0F1 ;copy $f0-f1...
29ee: 20 9f 2e jsr JJ_PopF8F9 ;...into $f8-f9
29f1: 20 93 2e jsr InA_GetIndirectValue ;get pointer to item name data
29f4: 28 2f .dd2 item_names_ptr
;
29f6: a0 00 :CountLoop ldy #$00
29f8: b1 f0 lda (]name_ptr),y ;get pointer to name, low byte
29fa: 85 f2 sta ]str_ptr ;copy into $f2
29fc: 20 51 2e jsr JJ_IncF0F1 ;advance ptr
29ff: b1 f0 lda (]name_ptr),y ;repeat for high byte
2a01: 85 f3 sta ]str_ptr+1
2a03: 20 51 2e jsr JJ_IncF0F1
2a06: 20 6c 2e jsr JJ_IncF2F3 ;step over length byte
2a09: b1 f2 lda (]str_ptr),y ;get first char of name
2a0b: c9 2a cmp #‘*’ ;is this a treasure item?
2a0d: d0 09 bne :NotTreasure ;no, branch
2a0f: ad 7e 30 lda hdr_treasure_room ;is it in the treasure room?
2a12: d1 f8 cmp (]room_ptr),y
2a14: d0 02 bne :NotTreasure ;no, branch
2a16: e6 f4 inc ]tr_count ;yes, this one counts
2a18: 20 a2 2e :NotTreasure jsr JJ_IncF8F9 ;advance room pointer to next room
2a1b: 20 a2 2e jsr JJ_IncF8F9
2a1e: ca dex ;done yet?
2a1f: d0 d5 bne :CountLoop ;no, loop
;
]count16 .var $f0 {addr/2}
2a21: 20 9f 2e jsr JJ_PopF8F9 ;restore $f8-f9
2a24: 20 54 2e jsr InA_GetInlineData
2a27: 88 2a .dd2 msg_i_stored
2a29: 20 36 2e jsr JJ_PrintString ;print "I stored"
2a2c: a5 f4 lda ]tr_count ;copy treasure count to $f0-f1
2a2e: 85 f0 sta ]count16
2a30: 48 pha ;stash count on stack
2a31: a9 00 lda #$00 ;high byte always 0 (max 255 treasures)
2a33: 85 f1 sta ]count16+1
2a35: 20 48 2e jsr JJ_PrintSignedDec ;print count
2a38: 20 54 2e jsr InA_GetInlineData
2a3b: 93 2a .dd2 msg_treasures
2a3d: 20 36 2e jsr JJ_PrintString ;print "treasures"
2a40: 20 54 2e jsr InA_GetInlineData
2a43: a0 2a .dd2 msg_scale_of
2a45: 20 36 2e jsr JJ_PrintString ;"on scale of 0-100"...
; Compute score. We add 100 for every treasure we've found and stored, then
; divide by the max number of treasures.
]score .var $f0 {addr/2}
2a48: a9 00 lda #$00
2a4a: 85 f0 sta ]score
2a4c: 85 f1 sta ]score+1
2a4e: a6 f4 ldx ]tr_count
2a50: f0 1c beq :NoTreasure ;avoid divide-by-zero
2a52: 20 54 2e jsr InA_GetInlineData
2a55: 64 00 .dd2 100
2a57: 20 84 2e jsr JJ_SetF4F5_F0F1 ;set $f4-f5 to 100
2a5a: ca dex
2a5b: f0 06 beq :OneTreasure
2a5d: 20 87 2e :AddLoop jsr JJ_AddF0F1_F4F5 ;$f0-f1 += $f4-f5
2a60: ca dex
2a61: d0 fa bne :AddLoop
2a63: 20 81 2e :OneTreasure jsr JJ_SetF2F3_F0F1 ;set $f2-f3 to $f0-f1 (found * 100)
2a66: 20 93 2e jsr InA_GetIndirectValue ;set $f0-f1 to number of treasures
2a69: 79 30 .dd2 hdr_num_treasures
2a6b: 20 21 2e jsr JJ_Divide16 ;divide, quotient in $f0-f1
2a6e: 20 48 2e :NoTreasure jsr JJ_PrintSignedDec ;print score
2a71: 20 33 2e jsr JJ_PrintCR
2a74: 68 pla ;pull saved count off stack
2a75: cd 79 30 cmp hdr_num_treasures ;compare to max treasures
2a78: f0 03 beq :Victory ;it matches, game won; branch
2a7a: 68 pla ;restore X-reg
2a7b: aa tax
2a7c: 60 rts
2a7d: 20 54 2e :Victory jsr InA_GetInlineData
2a80: bc 2a .dd2 msg_victory
2a82: 20 36 2e jsr JJ_PrintString ;print victory message
2a85: 4c 4a 29 jmp O3F_GameOver ;jump to game-over handler
2a88: 20 49 20 53+ msg_i_stored .zstr ‘ I STORED ’
2a93: 20 54 52 45+ msg_treasures .zstr ‘ TREASURES.’,$0d
2aa0: 4f 4e 20 41+ msg_scale_of .zstr ‘ON A SCALE OF 0-100 THATS: ’
2abc: 20 46 41 4e+ msg_victory .zstr ‘ FANTASTIC! YOU'VE DONE IT!’,$0d
;
; Action $42: show inventory.
;
2ad9: 20 0f 2e O42_Inventory jsr JJ_ShowInventory
2adc: 60 rts
;
; Action $43: set flag 0 to true.
;
2add: a0 00 O43_Set0 ldy #$00
2adf: 4c d9 28 jmp SetFlagN ;set flag #0
;
; Action $44: clear flag 0.
;
2ae2: a0 00 O44_Clear0 ldy #$00
2ae4: 4c f7 28 jmp ClearFlagN ;clear flag #0
;
; Action op $45: refill lightsource.
;
]ptr .var $f0 {addr/2}
2ae7: ad 7b 30 O45_RefillLamp lda hdr_lamp_capacity ;reset lamp fuel level to max
2aea: 8d 01 31 sta lamp_fuel_level
2aed: ad 7c 30 lda hdr_lamp_capacity+1
2af0: 8d 02 31 sta lamp_fuel_level+1
2af3: 20 93 2e jsr InA_GetIndirectValue ;get pointer to $42ff
2af6: 26 2f .dd2 item_rooms_ptr
2af8: a0 12 ldy #18 ;lamp is always object 9
2afa: a9 ff lda #ITEM_HELD
2afc: 91 f0 sta (]ptr),y ;add lightsource object to inventory
2afe: a9 00 lda #$00 ; (in case torch disappeared when it went out?)
2b00: 8d d9 30 sta lamp_empty_flag ;clear lamp-empty flag
2b03: 20 15 2e jsr JJ_DescribeRoom ;redraw room description
;
; Action op $45: clear screen. (This is a no-op.)
;
2b06: 60 O46_ClearScreen rts
;
; Action op $4b: put item A in the same location as item B.
;
; If item A and item B are in the same location, we will redraw the room
; description twice.
;
2b07: 20 18 2e O4B_PutWith jsr JJ_GetActionArg ;get item A index in $f0-f1
2b0a: 20 45 2e jsr JJ_GetItemLocation ;get pointer to item A room data in $f0-f1
2b0d: 20 5d 2e jsr JJ_PushF0F1 ;push on stack
2b10: 20 18 2e jsr JJ_GetActionArg ;get item B index in $f0-f1
2b13: 20 45 2e jsr JJ_GetItemLocation ;get item B room # in A-reg
2b16: 20 60 2e jsr JJ_PopF0F1 ;restore $f0-f1
2b19: a0 00 ldy #$00
2b1b: cd e9 30 cmp current_room ;is item B (destination) in the current room?
2b1e: d0 03 bne :NotCur ;no, branch
2b20: 20 15 2e jsr JJ_DescribeRoom ;yes, redraw room description
2b23: 48 :NotCur pha ;save item B (destination) room
2b24: b1 f0 lda (]ptr),y ;get item A's room
2b26: 8d 99 30 sta div_q_tmp ;save it
2b29: 68 pla ;restore item B's room
2b2a: 91 f0 sta (]ptr),y ;set item A's location to that
2b2c: ad 99 30 lda div_q_tmp ;get item A's original location
2b2f: cd e9 30 cmp current_room ;was it in the current room?
2b32: d0 03 bne :Return ;no, branch
2b34: 20 15 2e jsr JJ_DescribeRoom ;yes, redraw room description
2b37: 60 :Return rts
;
; Computes $f2-f3 / $f0-f1.
;
; On exit:
; $f0-f1: quotient
; $f2-f3: remainder
;
; (preserves all registers)
;
• Clear variables
]denom .var $f0 {addr/2}
]numer .var $f2 {addr/2}
2b38: 20 57 2e Divide16 jsr JJ_PushRegs ;preserve registers
2b3b: a2 10 ldx #16
2b3d: 20 6f 2e jsr JJ_PushF4F5 ;preserve $f4-f5 (why?)
2b40: a9 00 lda #$00
2b42: 8d 99 30 sta div_q_tmp
2b45: 8d 9a 30 sta div_q_tmp+1
2b48: 8d 9b 30 sta div_r_tmp
2b4b: 8d 9c 30 sta div_r_tmp+1
2b4e: 0e 99 30 :Loop asl div_q_tmp
2b51: 2e 9a 30 rol div_q_tmp+1
2b54: 06 f2 asl ]numer
2b56: 26 f3 rol ]numer+1
2b58: 2e 9b 30 rol div_r_tmp
2b5b: 2e 9c 30 rol div_r_tmp+1
2b5e: 20 5d 2e jsr JJ_PushF0F1 ;save denominator
2b61: 38 sec
2b62: a5 f0 lda ]denom
2b64: ed 9b 30 sbc div_r_tmp
2b67: 85 f0 sta ]denom
2b69: a5 f1 lda ]denom+1
2b6b: ed 9c 30 sbc div_r_tmp+1
2b6e: 85 f1 sta ]denom+1
2b70: 05 f0 ora ]denom
2b72: f0 04 beq :Den0
2b74: a5 f1 lda ]denom+1
2b76: 10 17 bpl :DenPos
2b78: ee 99 30 :Den0 inc div_q_tmp
2b7b: d0 03 bne :NoInc
2b7d: ee 9a 30 inc div_q_tmp+1
2b80: 38 :NoInc sec
2b81: a9 00 lda #$00
2b83: e5 f0 sbc ]denom
2b85: 8d 9b 30 sta div_r_tmp
2b88: a9 00 lda #$00
2b8a: e5 f1 sbc ]denom+1
2b8c: 8d 9c 30 sta div_r_tmp+1
2b8f: 20 60 2e :DenPos jsr JJ_PopF0F1 ;restore denominator
2b92: ca dex ;done all bits?
2b93: d0 b9 bne :Loop ;no, branch
;
2b95: ad 99 30 lda div_q_tmp ;copy results to zero page
2b98: 85 f0 sta ]denom
2b9a: ad 9a 30 lda div_q_tmp+1
2b9d: 85 f1 sta ]denom+1
2b9f: ad 9b 30 lda div_r_tmp
2ba2: 85 f2 sta ]numer
2ba4: ad 9c 30 lda div_r_tmp+1
2ba7: 85 f3 sta ]numer+1
2ba9: 20 72 2e jsr JJ_PopF4F5 ;restore $f4-f5
2bac: 20 5a 2e jsr JJ_PopRegs ;restore registers
2baf: 60 rts
2bb0: 00 00 00 00+ .junk 592
2e00: 4c 00 08 jmp Entry
JJ_ProcessActions
2e03: 4c 00 1f jmp J_ProcessActions ;process actions and occurrences
JJ_ActionLoopEnd
2e06: 4c 03 1f jmp J_ActionLoopEnd ;jump to end of action scan loop
2e09: 4c 09 17 JJ_SaveGame jmp J_SaveGame ;save the game
2e0c: 4c .dd1 $4c ;not used as a jump
cond_handlers_ind
2e0d: 0c 17 .dd2 J_CondHandlers
JJ_ShowInventory
2e0f: 4c 03 17 jmp J_ShowInventory ;print the player's inventory
JJ_PrintItemName
2e12: 4c 15 17 jmp J_PrintItemName ;print the name of an item
2e15: 4c 00 17 JJ_DescribeRoom jmp J_DescribeRoom ;redraw room description
2e18: 4c 06 17 JJ_GetActionArg jmp J_GetActionArg ;$f0-f1 = action argument
JJ_AskDiskOrTape
2e1b: 4c 0f 17 jmp J_AskDiskOrTape ;ask player: "disk or tape?"
JJ_PrintStringCOUT
2e1e: 4c 12 17 jmp J_PrintStringCOUT ;print null-terminated string through COUT routine
2e21: 4c 09 27 JJ_Divide16 jmp J_Divide16 ;$f0-f1 = $f2-f3 / $f0-f1 (rem in $f2-f3)
2e24: 4c a8 2e jmp NopRts
2e27: 4c a8 2e jmp NopRts
2e2a: 4c .dd1 $4c
2e2b: 03 27 act_oper_ind .dd2 J_act_oper_tab
2e2d: 4c 00 08 J_Start jmp Entry ;begin (or restart)
2e30: 4c 03 08 JJ_PrintNonNull jmp J_PrintNonNull ;prints char ($01-7f) unless it's $00
2e33: 4c 06 08 JJ_PrintCR jmp J_PrintCR ;prints CR (clear to EOL, move to start of new line)
2e36: 4c 0f 08 JJ_PrintString jmp J_PrintString ;prints a null-terminated string ($f0-f1)
2e39: 4c 15 08 JJ_GetInput jmp J_GetInput ;get player input into key buffer
2e3c: 4c 18 08 JJ_ClearScreen jmp J_ClearScreen ;clear screen
2e3f: 4c 0c 08 JJ_PrintNChars jmp J_PrintNChars ;print the next N chars
2e42: 4c 09 08 JJ_PrintL1Str jmp J_PrintL1Str ;print a string start starts with a len byte
JJ_GetItemLocation
2e45: 4c 1e 08 jmp J_GetItemLocation ;$f0-f1 point into room data; A-reg=room#
JJ_PrintSignedDec
2e48: 4c 1b 08 jmp J_PrintSignedDec ;print $f0-f1 as decimal value
JJ_PrintFlashing
2e4b: 4c 12 08 jmp J_PrintFlashStr ;print null-terminated string ($f0-f1), flash mode
2e4e: 4c 24 14 JJ_DecF0F1 jmp J_DecF0F1 ;$f0-f1 --
2e51: 4c 1b 14 JJ_IncF0F1 jmp J_IncF0F1 ;$f0-f1 ++
InA_GetInlineData
2e54: 4c 3c 14 jmp J_GetInlineData ;$f0-f1 = inline (copy in $fc-fd)
2e57: 4c 21 08 JJ_PushRegs jmp J_PushRegs ;AXYP -> stack
2e5a: 4c 24 08 JJ_PopRegs jmp J_PopRegs ;stack -> AXYP
2e5d: 4c 03 14 JJ_PushF0F1 jmp J_PushF0F1 ;$f0-f1 -> stack
2e60: 4c 06 14 JJ_PopF0F1 jmp J_PopF0F1 ;stack -> $f0-f1
2e63: 4c 27 14 JJ_DecF4F5 jmp J_DecF4F5 ;$f4-f5 --
2e66: 4c 1e 14 JJ_IncF4F5 jmp J_IncF4F5 ;$f4-f5 ++
2e69: 4c 2a 14 JJ_DecF2F3 jmp J_DecF2F3 ;$f2-f3 --
2e6c: 4c 21 14 JJ_IncF2F3 jmp J_IncF2F3 ;$f2-f3 ++
2e6f: 4c 09 14 JJ_PushF4F5 jmp J_PushF4F5 ;$f4-f5 -> stack
2e72: 4c 0c 14 JJ_PopF4F5 jmp J_PopF4F5 ;stack -> $f4-f5
2e75: 4c 0f 14 JJ_PushF2F3 jmp J_PushF2F3 ;$f2-f3 -> stack
2e78: 4c 12 14 JJ_PopF2F3 jmp J_PopF2F3 ;stack -> $f2-f3
2e7b: 4c 33 14 InA_SubF0F1_Ind jmp J_SubF0F1_Ind ;$fa-fb = $f0-f1 - (*inline); N/Z/C set
InA_SubF0F1_Inline
2e7e: 4c 36 14 jmp J_SubF0F1_Inline ;$fa-fb = $f0-f1 - inline; N/Z/C set
2e81: 4c 2d 14 JJ_SetF2F3_F0F1 jmp J_SetF2F3_F0F1 ;$f2-f3 = $f0-f1
2e84: 4c 30 14 JJ_SetF4F5_F0F1 jmp J_SetF4F5_F0F1 ;$f4-f5 = $f0-f1
2e87: 4c 39 14 JJ_AddF0F1_F4F5 jmp J_AddF0F1_F4F5 ;$f0-f1 += $f4-f5
JJ_PushFullState
2e8a: 4c 15 14 jmp J_PushFullState ;AXYP $f0-f9 -> stack
2e8d: 4c 18 14 JJ_PopFullState jmp J_PopFullState ;stack -> AXYP $f0-f9
InA_SetIndirectValue
2e90: 4c 00 14 jmp J_SetIndirectValue ;(*inline) = $f0-f1
InA_GetIndirectValue
2e93: 4c 3f 14 jmp J_GetIndirectValue ;$f0-f1 = (*inline)
2e96: 4c 42 14 JJ_PushF6F7 jmp J_PushF6F7 ;$f6-f7 -> stack
2e99: 4c 45 14 JJ_PopF6F7 jmp J_PopF6F7 ;stack -> $f6-f7
2e9c: 4c 48 14 JJ_PushF8F9 jmp J_PushF8F9 ;$f8-f9 -> stack
2e9f: 4c 4b 14 JJ_PopF8F9 jmp J_PopF8F9 ;stack -> $f8-f9
2ea2: 4c 4e 14 JJ_IncF8F9 jmp J_IncF8F9 ;$f8-f9 ++
JJ_CountHeldObjs
2ea5: 4c 06 27 jmp J_CountHeldObjs ;$f4 = number of objects in inventory
2ea8: ea NopRts nop
2ea9: 60 rts
2eaa: 00 .dd1 $00
2eab: 00 regsv_tmp_a .dd1 $00 ;temporary storage
2eac: 32 regsv_tmp_p .dd1 $32 ;temporary storage
2ead: 63 16 regsv_ret_addr .dd2 $1663 ;temporary storage
2eaf: 01 noflash_flag .dd1 $01 ;used for text output
2eb0: bc f4 kbd_rng_seed .dd2 $f4bc ;random number seed, updated while waiting for key
2eb2: 01 use_disk_flag .dd1 $01 ;0=tape, 1=disk
2eb3: 00 00 00 00+ .align $0100 (77 bytes)
;
; Pointers to tables.
;
2f00: df 44 action_verb_ptr .dd2 action_verb ;pointer to table with verb indices for actions
action_nou_prc_ptr
2f02: db 45 .dd2 action_nou_prc ;pointer to table with noun or percent values for act
2f04: d7 46 action_op0_ptr .dd2 action_op0_tab ;pointer to action opcodes
2f06: d3 47 .dd2 action_op1_tab ; (max 4 per action)
2f08: cf 48 .dd2 action_op2_tab
2f0a: cb 49 .dd2 action_op3_tab
2f0c: c7 4a condition0_ptr .dd2 condition0_tab ;pointer to action conditions
2f0e: bf 4c .dd2 condition1_tab ; (max 5 per action)
2f10: b7 4e .dd2 condition2_tab
2f12: af 50 .dd2 condition3_tab
2f14: a7 52 .dd2 condition4_tab
2f16: 9f 54 room_descrs_ptr .dd2 room_descrs ;pointer to room description text pointers
2f18: eb 54 vis_exits_n_ptr .dd2 visible_exits_n ;pointer to north exits table
2f1a: 37 55 .dd2 visible_exits_s ;pointer to south exits table
2f1c: 83 55 .dd2 visible_exits_e ;pointer to east exits table
2f1e: cf 55 .dd2 visible_exits_w ;pointer to west exits table
2f20: 1b 56 .dd2 visible_exits_u ;pointer to up exits table
2f22: 67 56 .dd2 visible_exits_d ;pointer to down exits table
2f24: b3 56 messages_ptr .dd2 messages ;pointer to messages table
2f26: ff 42 item_rooms_ptr .dd2 item_rooms ;pointer to item location data table
2f28: 9f 43 item_names_ptr .dd2 item_names ;pointer to item name table
item_initroom_ptr
2f2a: 3f 44 .dd2 item_initrooms ;pointer to item initial location table
2f2c: fe 42 .dd2 T42FE ;(not used? points to end of item name string pool)
2f2e: 38 31 noun_words_ptr .dd2 noun_words ;pointer to noun list
2f30: af 32 verb_words_ptr .dd2 verb_words ;pointer to verb list
2f32: 01 .dd1 $01
;
; Player command input buffer. The first 24 bytes are zeroed, though we accept
; at most 18 characters. (I have a sneaking suspicion somebody mixed up "18"
; and "$18" in the sources, though it's necessary to be at least 19 so that the
; contents are properly null-terminated.)
;
; The first 256 bytes is also used as a buffer for game state while loading or
; saving it.
;
2f33: 00 kbd_scratch_buf .dd1 $00 ;saved game: adventure number (low)
2f34: 00 adv_num_hi .dd1 $00 ;saved game: adventure number (high)
;
; The next 61 bytes ($2f35-2f71) are copied out to $30c7-3103 when the game is
; loaded, and back before it's saved.
2f35: 00 00 00 00+ save_game_data .junk 61
;
2f72: 0d 22 22 0d+ .junk 192
3032: 00 save_state_end .dd1 $00 ;last byte in saved-game scratch area
;
thing_found_flag
3033: 50 .dd1 $50
3034: 6f .junk 1
3035: 50 tmp_save_x2 .dd1 $50
3036: 6f 50 6f d0+ .junk 29
3053: b4 00 adventure_vers .dd2 180 ;version number
3055: 59 57 .junk 2
3057: 0c 00 adventure_num .dd2 12 ;adventure #12
3059: 40 screen_cleared? .dd1 $40 ;written, never read
305a: 3c 50 6f 50+ .junk 13
actionop_arg_idx
3067: ff 8a .dd2 $8aff ;current index into action op args (really 8-bit)
;
; These values are defined in the header of an adventure data file on other
; systems. They're global values that affect the interpretation of the other
; structures.
;
3069: 04 00 hdr_word_len .dd2 $0004 ;char length of nouns and verbs
hdr_max_nounverb
306b: 4a 00 .dd2 $004a ;max verb/noun number (one list is padded to match)
306d: fb 00 hdr_max_action .dd2 $00fb ;max action number
306f: 4f 00 hdr_max_item .dd2 $004f ;maximum item number (count - 1)
3071: 52 00 hdr_max_msg .dd2 $0052 ;maximum message number (count - 1)
3073: 25 00 hdr_max_room .dd2 $0025 ;maximum room number (count - 1)
3075: 07 00 hdr_max_held .dd2 $0007 ;maximum number of objects player can hold
3077: 04 00 hdr_start_room .dd2 $0004 ;initial room number
hdr_num_treasures
3079: 00 00 .dd2 $0000 ;number of treasures in the game (victory cond)
hdr_lamp_capacity
307b: 64 00 .dd2 $0064 ;maximum capacity of lightsource obj
307d: 00 debug_flag .dd1 $00 ;debug level: 0 (off), 1, or 2
hdr_treasure_room
307e: 00 00 .dd2 $0000 ;room# where treasures are stored
;
; Input trim buffer. Holds up to 24 bytes.
3080: 00 43 59 43+ word_trim_buf .junk 24
;
3098: 6f .junk 1
3099: 00 00 div_q_tmp .dd2 $0000
309b: 00 00 div_r_tmp .dd2 $0000
309d: 5b tmp_save_reg1 .dd1 $5b
309e: b0 tmp_save_reg2 .dd1 $b0
309f: a7 b0 f3 b0+ .junk 22
30b5: 06 2d 00 00+ dec_outbuf .junk 7 ;output buf for decimal print: len byte + 6 chars
30bc: 00 parsed_verb_idx .dd1 $00 ;index of parsed verb (0-74 here)
30bd: 00 .junk 1
30be: 00 parsed_noun_idx .junk 1 ;index of parsed noun (uses 0 "ANY" if none)
30bf: 00 .junk 1
cmd_not_hnd_flag
30c0: 00 .dd1 $00 ;true until command is handled
30c1: 00 .junk 1
accum_cond_result
30c2: 00 .dd1 $00 ;cumulative result of testing conditions
30c3: ff occur_flag .dd1 $ff ;set if we're processing occurrences (vs. ops)?
30c4: 00 continue_flag .dd1 $00 ;set by "continue" action op
30c5: 27 noun_or_percent .dd1 $27 ;action noun index, or occurrence percent chance
30c6: 0a action_verb_idx .dd1 $0a
;
; $30c7-3103 are stored in save game file part 1. This includes the flags,
; counters, and current/alternate rooms.
;
counter_register
30c7: d6 00 .dd2 $00d6 ;counter register, a/k/a "current counter"
;
; 32 action flags. Action conditions and operations can set/clear/test these as
; boolean values. They hold $00 for false and $ff for true.
;
30c9: 00 00 00 00+ action_flags .fill 15,$00 ;flags 0-14
30d8: 00 darkness_flag .dd1 $00 ;flag 15: room is dark (so you need to bring light)
30d9: 00 lamp_empty_flag .dd1 $00 ;flag 16: nonzero if lightsource is empty
30da: 00 00 00 00+ .fill 15,$00 ;flags 17-31
;
30e9: 04 00 current_room .dd2 $0004 ;number of room player is currently in
30eb: 00 6f def_alt_room .dd2 $6f00 ;default "alternate room"
30ed: 00 6f 00 6f .junk 4
;
; Nine storage slots for the 16-bit counters.
;
30f1: 03 00 50 6f+ game_counters .junk 16 ;counters 0-7
3101: 64 00 lamp_fuel_level .dd2 $0064 ;counter #8 is time remaining on lamp
;
; (Byte at $3103 is saved and restored, but shouldn't be.)
3103: 15 04 item_names_len .dd2 $0415 ;total length of item name data
;
3105: 50 6f 50 6f+ .junk 51
;
; Nouns 0-74. These aren't really null-terminated strings; rather, they are 4-
; character words that begin with $00 or '*', indicating whether they are
; distinct words or aliases. They're formatted as strings because it's
; (usually) easier to read that way.
;
3138: 00 noun_words .dd1 $00
3139: 41 4e 59 00 .zstr ‘ANY’ ;noun 0 (implied when no noun provided)
313d: 00 .dd1 $00
313e: 4e 4f 52 54+ .zstr ‘NORT’ ;nouns 1-6 must be the directions
3143: 53 4f 55 54+ .zstr ‘SOUT’
3148: 45 41 53 54+ .zstr ‘EAST’
314d: 57 45 53 54+ .zstr ‘WEST’
3152: 55 50 00 .zstr ‘UP’
3155: 00 .dd1 $00
3156: 00 .dd1 $00
3157: 44 4f 57 4e+ .zstr ‘DOWN’
315c: 4b 49 4e 47+ .zstr ‘KING’
3161: 47 55 41 52+ .zstr ‘GUAR’
3166: 50 41 4c 41+ .zstr ‘PALA’
316b: 4d 45 52 43+ .zstr ‘MERC’
3170: 53 48 49 50+ .zstr ‘SHIP*BOAT*ABOA’
317f: 4d 41 53 54+ .zstr ‘MAST’
3184: 53 41 49 4c+ .zstr ‘SAIL’
3189: 4d 45 44 49+ .zstr ‘MEDI’ ;$10
318e: 41 52 4f 55+ .zstr ‘AROU’
3193: 4f 43 45 41+ .zstr ‘OCEA*WATE*LIQU’
31a2: 50 41 53 53+ .zstr ‘PASS’
31a7: 48 41 4c 4c+ .zstr ‘HALL’
31ac: 43 41 56 45+ .zstr ‘CAVE’
31b1: 54 41 42 4c+ .zstr ‘TABL’
31b6: 53 54 4f 4e+ .zstr ‘STON’
31bb: 53 4b 45 4c+ .zstr ‘SKEL*BONE’
31c5: 4d 41 4e 00 .zstr ‘MAN’
31c9: 00 .dd1 $00
31ca: 46 4c 49 4e+ .zstr ‘FLIN*STEE’
31d4: 53 48 4f 56+ .zstr ‘SHOV’
31d9: 48 55 54 00 .zstr ‘HUT’ ;$20
31dd: 00 .dd1 $00
31de: 4d 4f 55 4e+ .zstr ‘MOUN’
31e3: 43 52 45 56+ .zstr ‘CREV’
31e8: 42 4f 58 00 .zstr ‘BOX’
31ec: 00 .dd1 $00
31ed: 53 54 41 49+ .zstr ‘STAI’
31f2: 43 49 54 59+ .zstr ‘CITY’
31f7: 53 54 41 54+ .zstr ‘STAT’
31fc: 53 43 4f 52+ .zstr ‘SCOR’
3201: 41 4c 54 41+ .zstr ‘ALTA’
3206: 43 48 45 53+ .zstr ‘CHES’
320b: 4b 45 59 00 .zstr ‘KEY’
320f: 00 .dd1 $00
3210: 43 59 43 4c+ .zstr ‘CYCL’
3215: 4a 55 4e 47+ .zstr ‘JUNG’
321a: 50 49 54 00 .zstr ‘PIT’
321e: 00 .dd1 $00
321f: 43 41 42 49+ .zstr ‘CABI’
3224: 46 4f 55 4e+ .zstr ‘FOUN’
3229: 4e 4f 54 45+ .zstr ‘NOTE’ ;$30
322e: 43 4f 54 00 .zstr ‘COT’
3232: 00 .dd1 $00
3233: 4d 41 52 4b+ .zstr ‘MARK’
3238: 42 4c 4f 43+ .zstr ‘BLOC’
323d: 54 4f 52 43+ .zstr ‘TORC’
3242: 52 55 42 42+ .zstr ‘RUBB’
3247: 54 45 4c 45+ .zstr ‘TELE’
324c: 43 4f 4d 50+ .zstr ‘COMP’
3251: 53 41 4e 44+ .zstr ‘SAND’
3256: 47 4c 4f 42+ .zstr ‘GLOB’
325b: 4d 41 53 4b+ .zstr ‘MASK’
3260: 43 48 41 4c+ .zstr ‘CHAL’
3265: 49 4e 56 45+ .zstr ‘INVE’
326a: 53 55 4e 00 .zstr ‘SUN’
326e: 00 .dd1 $00
326f: 53 57 4f 52+ .zstr ‘SWOR’
3274: 53 54 52 41+ .zstr ‘STRA’
3279: 42 45 41 43+ .zstr ‘BEAC’ ;$40
327e: 49 53 4c 41+ .zstr ‘ISLA’
3283: 41 4e 43 48+ .zstr ‘ANCH’
3288: 41 53 48 4f+ .zstr ‘ASHO’
328d: 47 41 4d 45+ .zstr ‘GAME’
3292: 53 54 41 4c+ .zstr ‘STAL’
3297: 47 52 4f 55+ .zstr ‘GROU*FLOO’
32a1: 52 4f 50 45+ .zstr ‘ROPE’
32a6: 42 41 47 00 .zstr ‘BAG’
32aa: 2a 47 4f 4c+ .str ‘*GOLD’ ;$4a
;
; Like the nouns, these are four-character strings that begin with $00 or '*'.
;
32af: 00 verb_words .dd1 $00
32b0: 41 55 54 4f+ .zstr ‘AUTO’ ;verb 0 (used for "continue" actions)
32b5: 47 4f 00 .zstr ‘GO’ ;verb 1 must be GO
32b8: 00 .dd1 $00
32b9: 2a 50 52 4f+ .zstr ‘*PROC*RIDE*RUN’
32c8: 2a 43 4c 49+ .zstr ‘*CLIM*ENTE*EXIT’
32d8: 53 41 56 45+ .zstr ‘SAVE’
32dd: 44 49 47 00 .zstr ‘DIG’
32e1: 00 .dd1 $00
32e2: 54 41 4b 45+ .zstr ‘TAKE*GET’ ;verb 10 must be TAKE
32eb: 2a 43 41 52+ .zstr ‘*CARR*GRAB*HOLD*STEA’
3300: 46 49 4c 4c+ .zstr ‘FILL’ ;$10
3305: 47 49 56 45+ .zstr ‘GIVE’
330a: 44 52 4f 50+ .zstr ‘DROP*LOWE*PUT’ ;verb 18 must be DROP
3318: 2a 54 48 52+ .zstr ‘*THRO’
331e: 45 58 41 4d+ .zstr ‘EXAM*STUD*LOOK*SEE’
3331: 2a 57 41 54+ .zstr ‘*WATC’
3337: 53 41 49 4c+ .zstr ‘SAIL*NAVI’
3341: 50 55 53 48+ .zstr ‘PUSH*SHOV*MOVE*SHAK’ ;$20 (SHAK)
3355: 4f 50 45 4e+ .zstr ‘OPEN*UNLO’
335f: 4c 49 47 48+ .zstr ‘LIGH*IGNI*BURN’
336e: 42 52 45 41+ .zstr ‘BREA*DEST*SMAS’
337d: 41 54 54 41+ .zstr ‘ATTA*KILL’
3387: 45 4d 50 54+ .zstr ‘EMPT’
338c: 50 4f 55 52+ .zstr ‘POUR*SPIL’
3396: 55 4e 54 49+ .zstr ‘UNTI’
339b: 55 4e 4c 49+ .zstr ‘UNLI’
33a0: 52 45 41 44+ .zstr ‘READ’ ;$30
33a5: 53 4c 45 45+ .zstr ‘SLEE’
33aa: 57 45 41 52+ .zstr ‘WEAR’
33af: 52 45 4d 4f+ .zstr ‘REMO’
33b4: 44 52 49 4e+ .zstr ‘DRIN’
33b9: 48 45 4c 50+ .zstr ‘HELP’
33be: 53 41 59 00 .zstr ‘SAY’
33c2: 2a 53 43 52+ .zstr ‘*SCRE*YELL*HOLL’
33d2: 51 55 49 54+ .zstr ‘QUIT’
33d7: 49 4e 56 45+ .zstr ‘INVE’
33dc: 4a 55 4d 50+ .zstr ‘JUMP’
33e1: 50 52 41 59+ .zstr ‘PRAY’
33e6: 54 49 45 00 .zstr ‘TIE’
33ea: 00 .dd1 $00
33eb: 54 4f 00 .zstr ‘TO’
33ee: 00 .dd1 $00
33ef: 00 .dd1 $00
33f0: 42 55 59 00 .zstr ‘BUY’ ;$40
33f4: 2a 50 55 52+ .zstr ‘*PURC’
33fa: 4f 4e 00 .zstr ‘ON’
33fd: 00 .dd1 $00
33fe: 2a 41 54 00 .zstr ‘*AT’
3402: 00 .dd1 $00
3403: 00 .dd1 $00
3404: 49 4e 00 .zstr ‘IN’
3407: 00 .dd1 $00
3408: 00 .dd1 $00
3409: 52 41 49 53+ .zstr ‘RAIS*LIFT*WEIG’
3418: 53 54 45 50+ .zstr ‘STEP*WALK’
3422: 57 41 49 54+ .zstr ‘WAIT’ ;$4a
;
; Room description text.
;
; On screen, these are prefixed with "I'm in a". If something different is
; desired, such as "I'm in an" or "I'm on a", a leading '*' suppresses the
; prefix string.
;
3427: 0c 52 6f 79+ T3427 .l1str ‘Royal palace’ ;room #1
3434: 0c 50 65 72+ T3434 .l1str ‘Persian city’
3441: 0c 50 65 72+ T3441 .l1str ‘Persian city’
344e: 0c 50 65 72+ T344E .l1str ‘Persian city’
345b: 16 2a 49 20+ T345B .l1str ‘*I am at a Persian bay’
3472: 15 2a 49 20+ T3472 .l1str ‘*I am on a large ship’
3488: 15 2a 49 27+ T3488 .l1str ‘*I'm on a sandy beach’
349e: 00 T349E .dd1 $00
349f: 0c 64 65 6e+ T349F .l1str ‘dense jungle’
34ac: 0c 64 65 6e+ T34AC .l1str ‘dense jungle’
34b9: 09 64 61 6d+ T34B9 .l1str ‘damp cave’
34c3: 0b 63 72 6f+ T34C3 .l1str ‘crow's-nest’
34cf: 16 2a 49 27+ T34CF .l1str ‘*I'm on a small island’
34e6: 16 2a 49 27+ T34E6 .l1str ‘*I'm on a small island’
34fd: 09 67 72 61+ T34FD .l1str ‘grass hut’
3507: 0b 64 61 72+ T3507 .l1str ‘dark cavern’
3513: 12 2a 49 27+ T3513 .l1str ‘*I'm on a mountain’
3526: 16 2a 49 27+ T3526 .l1str ‘*I'm on a small island’
353d: 16 2a 49 27+ T353D .l1str ‘*I'm on a rocky strand’
3554: 18 2a 49 27+ T3554 .l1str ‘*I'm on a long staircase’
356d: 0d 73 61 63+ T356D .l1str ‘sacred temple’
357b: 0d 73 61 63+ T357B .l1str ‘sacred temple’
3589: 0e 68 69 64+ T3589 .l1str ‘hidden chamber’
3598: 0e 68 69 64+ T3598 .l1str ‘hidden chamber’
35a7: 0d 73 61 63+ T35A7 .l1str ‘sacred temple’
35b5: 00 T35B5 .dd1 $00
35b6: 0d 6d 75 73+ T35B6 .l1str ‘musty hallway’
35c4: 0b 73 6d 61+ T35C4 .l1str ‘small cabin’
35d0: 08 63 6f 7a+ T35D0 .l1str ‘cozy cot’
35d9: 0b 64 61 6d+ T35D9 .l1str ‘damp grotto’
35e5: 00 T35E5 .dd1 $00
35e6: 16 2a 49 27+ T35E6 .l1str ‘*I'm on a grassy plain’
35fd: 08 64 65 65+ T35FD .l1str ‘deep pit’
3606: 08 64 65 65+ T3606 .l1str ‘deep pit’
360f: 18 2a 49 27+ T360F .l1str ‘*I'm in an enormous cave’
3628: 18 2a 49 27+ T3628 .l1str ‘*I'm in an enormous cave’
3641: 0f 4c 4f 54+ T3641 .l1str ‘LOT OF TROUBLE!’ ;limbo room
;
; Message text.
;
3651: 00 T3651 .dd1 $00
3652: 6b 57 65 6c+ T3652 .l1str ‘Welcome to Adventure 12: "THE GOLDEN VOYAGE"’
+ $0a,‘by William Demas & Scott Adams’,$0a,‘Dedic’
+ ‘ated: British band "QUEEN"’
36be: 0a 73 6f 6d+ T36BE .l1str ‘something!’
36c9: 06 57 68 65+ T36C9 .l1str ‘Where?’
36d0: 12 53 6f 6d+ T36D0 .l1str ‘Something rattles.’
36e3: 23 54 68 65+ T36E3 .l1str ‘The statue topples down the stairs.’
3707: 07 49 20 66+ T3707 .l1str ‘I found’
370f: 08 6e 6f 74+ T370F .l1str ‘nothing.’
3718: 36 49 74 20+ T3718 .l1str ‘It appears to be broken. Strange markings are ’
+ ‘present.’
374f: 1e 54 68 65+ T374F .l1str ‘The stones mysteriously unite!’
376e: 15 49 74 20+ T376E .l1str ‘It contains medicine.’
3784: 18 45 76 65+ T3784 .l1str ‘Everything appears grey.’
379d: 02 4f 4b T379D .l1str ‘OK’
37a0: 05 4f 55 43+ T37A0 .l1str ‘OUCH!’
37a6: 16 49 20 73+ T37A6 .l1str ‘I see nothing special.’
37bd: 1d 48 65 27+ T37BD .l1str ‘He's been stung by scorpions.’
37db: 08 4c 41 4e+ T37DB .l1str ‘LAND HO!’
37e4: 06 49 20 68+ T37E4 .l1str ‘I hear’
37eb: 2e 4f 6e 65+ T37EB .l1str ‘One great big EYE has a focus in my direction!’
381a: 30 49 20 73+ T381A .l1str ‘I see a picture of a mountain and the word "SU’
+ ‘N"’
384b: 1f 49 20 63+ T384B .l1str ‘I can't tell which way that is!’
386b: 2e 4d 65 72+ T386B .l1str ‘Merchant calls me a thief and slits my throat!’
389a: 24 54 68 65+ T389A .l1str ‘There's a tremendous flash of light!’
38bf: 0a 49 27 6d+ T38BF .l1str ‘I'm blind!’
38ca: 18 48 65 20+ T38CA .l1str ‘He gives a great big CRY’
38e3: 24 48 69 67+ T38E3 .l1str ‘High atop the mast is a crow's-nest.’
3908: 7e 4b 49 4e+ T3908 .l1str ‘KING: I have been given only 3 days to live. Y’
+ ‘ou are to seek for a way to restore my vi’
+ ‘tality. The gold is yours. Go now!’
3987: 14 4f 48 20+ T3987 .l1str ‘OH NO! I can't swim!’
399c: 07 43 79 63+ T399C .l1str ‘Cyclops’
39a4: 0c 49 74 27+ T39A4 .l1str ‘It's locked.’
39b1: 1a 49 20 73+ T39B1 .l1str ‘I see a picture of a cave.’
39cc: 1b 67 72 61+ T39CC .l1str ‘grabs me and eats me alive!’
39e8: 19 54 68 65+ T39E8 .l1str ‘The statue comes to life!’
3a02: 15 49 74 27+ T3A02 .l1str ‘It's holding a sword.’
3a18: 16 53 6f 72+ T3A18 .l1str ‘Sorry, it won't BUDGE!’
3a2f: 0c 54 65 6c+ T3A2F .l1str ‘Tell me how?’
3a3c: 47 4d 41 4e+ T3A3C .l1str ‘MAN: I'm afraid it's too late for me. Appeal t’
+ ‘o the’,$0a,‘ Gods for help!’
3a84: 1c 54 68 65+ T3A84 .l1str ‘The ground shakes violently!’
3aa1: 44 49 27 76+ T3AA1 .l1str ‘I've desecrated the holy fountain.’,$0a,‘I'm s’
+ ‘truck down by a THUNDERBOLT!’
3ae6: 11 54 68 65+ T3AE6 .l1str ‘The King grabs it’
3af8: 22 61 6e 64+ T3AF8 .l1str ‘and DIES! Guards have me beheaded.’
3b1b: 19 49 20 68+ T3B1B .l1str ‘I have failed my mission.’
3b35: 12 49 74 27+ T3B35 .l1str ‘It's getting dark!’
3b48: 0f 4d 6f 72+ T3B48 .l1str ‘Morning! I have’
3b58: 0a 47 6f 6f+ T3B58 .l1str ‘Goodnight.’
3b63: 06 32 20 64+ T3B63 .l1str ‘2 days’
3b6a: 05 31 20 64+ T3B6A .l1str ‘1 day’
3b70: 1c 6c 65 66+ T3B70 .l1str ‘left to complete my mission.’
3b8d: 10 54 68 65+ T3B8D .l1str ‘The sun has set.’
3b9e: 2d 4e 69 67+ T3B9E .l1str ‘Night air is COLD!’,$0a,‘I catch pneumonia and’
+ ‘ die.’
3bcc: 12 66 61 69+ T3BCC .l1str ‘failed my mission.’
3bdf: 12 49 27 6d+ T3BDF .l1str ‘I'm in great PAIN!’
3bf2: 22 4d 79 20+ T3BF2 .l1str ‘My whole body has become infected.’
3c15: 12 53 74 61+ T3C15 .l1str ‘Statue follows me.’
3c28: 18 53 74 61+ T3C28 .l1str ‘Statue swings its sword.’
3c41: 0d 49 74 20+ T3C41 .l1str ‘It missed me!’
3c4f: 15 49 27 76+ T3C4F .l1str ‘I've been cut in two!’
3c65: 16 49 20 66+ T3C65 .l1str ‘I fend off its attack.’
3c7c: 42 49 27 6d+ T3C7C .l1str ‘I'm lynched by angry mourners.’,$0a,‘Their Kin’
+ ‘g is dead. (AND SO AM I)!!’
3cbf: 10 54 68 65+ T3CBF .l1str ‘The man is dead!’
3cd0: 3b 47 65 74+ T3CD0 .l1str ‘Get your copy of "FROG" from Adventure Interna’
+ ‘tional today!’
3d0c: 15 54 68 65+ T3D0C .l1str ‘The ship drifts away.’
3d22: 10 4e 6f 74+ T3D22 .l1str ‘Nothing happens.’
3d33: 0c 49 74 27+ T3D33 .l1str ‘It's full of’
3d40: 06 77 61 74+ T3D40 .l1str ‘water.’
3d47: 11 61 20 73+ T3D47 .l1str ‘a strange liquid.’
3d59: 48 61 6e 64+ T3D59 .l1str ‘and transforms into a young man. CONGRATULATIO’
+ ‘NS!!’,$0a,‘Mission accomplished.’
3da2: 11 64 72 69+ T3DA2 .l1str ‘drinks the liquid’
3db4: 18 61 6e 64+ T3DB4 .l1str ‘and yells "It's EMPTY!".’
3dcd: 0d 77 6f 6e+ T3DCD .l1str ‘won't let me.’
3ddb: 21 43 79 63+ T3DDB .l1str ‘Cyclops staggers and steps on me!’
3dfd: 18 49 27 6c+ T3DFD .l1str ‘I'll only defend myself.’
3e16: 08 4d 65 72+ T3E16 .l1str ‘Merchant’
3e1f: 18 50 6c 65+ T3E1F .l1str ‘Please be more specific.’
3e38: 13 49 20 66+ T3E38 .l1str ‘I feel much better.’
3e4c: 09 45 6d 70+ T3E4C .l1str ‘Empty it?’
3e56: 06 53 6f 72+ T3E56 .l1str ‘Sorry.’
3e5d: 13 48 65 20+ T3E5D .l1str ‘He has me executed.’
3e71: 32 53 75 72+ T3E71 .l1str ‘Surprised merchant grabs it and runs like a th’
+ ‘ief!’
3ea4: 1d 53 74 61+ T3EA4 .l1str ‘Statue attacks while I sleep!’
3ec2: 19 52 6f 70+ T3EC2 .l1str ‘Rope slides into the pit.’
3edc: 06 50 4c 4f+ T3EDC .l1str ‘PLOOSH’
3ee3: 05 59 55 43+ T3EE3 .l1str ‘YUCK!’
;
; Item name data, stored as strings with a leading length byte. If the name
; ends with "/WORD/", the item will effectively have GET/DROP actions created
; for it. The byte that follows the slash is the item number.
;
; (The item number could be inferred from the string's position in the list, but
; it's a little simpler to make it explicit.)
;
3ee9: 00 L3EE9 .dd1 $00 ;item 0 doesn't exist
3eea: 0d 50 61 6c+ L3EEA .l1str ‘Palace guards’
3ef8: 09 41 67 65+ L3EF8 .l1str ‘Aged King’
3f02: 06 50 61 6c+ L3F02 .l1str ‘Palace’
3f09: 0a 4c 61 72+ L3F09 .l1str ‘Large ship’
3f14: 04 4d 61 73+ L3F14 .l1str ‘Mast’
3f19: 04 53 61 69+ L3F19 .l1str ‘Sail’
3f1e: 06 41 6e 63+ L3F1E .l1str ‘Anchor’
3f25: 0e 53 6b 65+ L3F25 .l1str ‘Skeleton/SKEL/’
3f34: 08 .dd1 $08
3f35: 0f 4c 69 74+ L3F35 .l1str ‘Lit torch/TORC/’ ;light source is always item #9
3f45: 09 .dd1 $09
3f46: 0c 4f 6c 64+ L3F46 .l1str ‘Old box/BOX/’
3f53: 0a .dd1 $0a
3f54: 10 53 74 72+ L3F54 .l1str ‘Strange fountain’
3f65: 07 43 72 65+ L3F65 .l1str ‘Crevice’
3f6d: 03 4d 61 6e L3F6D .l1str ‘Man’
3f71: 06 4a 75 6e+ L3F71 .l1str ‘Jungle’
3f78: 0e 48 69 64+ L3F78 .l1str ‘Hidden passage’
3f87: 12 47 6f 6c+ L3F87 .l1str ‘Gold chalice/CHAL/’
3f9a: 10 .dd1 $10
3f9b: 04 43 61 76+ L3F9B .l1str ‘Cave’
3fa0: 0e 4c 6f 6e+ L3FA0 .l1str ‘Long staircase’
3faf: 13 46 6c 69+ L3FAF .l1str ‘Flint & steel/FLIN/’
3fc3: 13 .dd1 $13
3fc4: 0f 47 6f 6c+ L3FC4 .l1str ‘Gold mask/MASK/’
3fd4: 14 .dd1 $14
3fd5: 0e 49 27 6d+ L3FD5 .l1str ‘I'm wearing it’
3fe4: 0b 53 6d 61+ L3FE4 .l1str ‘Small stone’
3ff0: 0b 53 6d 61+ L3FF0 .l1str ‘Small stone’
3ffc: 0b 53 6d 61+ L3FFC .l1str ‘Small stone’
4008: 0d 53 74 6f+ L4008 .l1str ‘Stone Goddess’
4016: 11 57 68 69+ L4016 .l1str ‘White globe/GLOB/’
4028: 1a .dd1 $1a
4029: 09 47 72 61+ L4029 .l1str ‘Grass hut’
4033: 08 4d 65 72+ L4033 .l1str ‘Merchant’
403c: 08 4d 65 72+ L403C .l1str ‘Merchant’
4045: 08 4d 65 72+ L4045 .l1str ‘Merchant’
404e: 0c 53 68 6f+ L404E .l1str ‘Shovel/SHOV/’
405b: 1f .dd1 $1f
405c: 0d 53 61 6e+ L405C .l1str ‘Sandals/SAND/’
406a: 20 .dd1 $20
406b: 10 49 27 6d+ L406B .l1str ‘I'm wearing them’
407c: 0d 43 6f 6d+ L407C .l1str ‘Compass/COMP/’
408a: 22 .dd1 $22
408b: 0f 54 65 6c+ L408B .l1str ‘Telescope/TELE/’
409b: 23 .dd1 $23
409c: 08 44 65 61+ L409C .l1str ‘Dead man’
40a5: 08 4b 65 79+ L40A5 .l1str ‘Key/KEY/’
40ae: 25 .dd1 $25
40af: 14 50 69 6c+ L40AF .l1str ‘Pile of rubble/RUBB/’
40c4: 26 .dd1 $26
40c5: 08 4d 6f 75+ L40C5 .l1str ‘Mountain’
40ce: 0b 53 74 6f+ L40CE .l1str ‘Stone block’
40da: 12 4f 72 6e+ L40DA .l1str ‘Ornate chest/CHES/’
40ed: 29 .dd1 $29
40ee: 03 43 6f 74 L40EE .l1str ‘Cot’
40f2: 0a 4e 6f 74+ L40F2 .l1str ‘Note/NOTE/’
40fd: 2b .dd1 $2b
40fe: 08 44 65 65+ L40FE .l1str ‘Deep pit’
4107: 07 43 79 63+ L4107 .l1str ‘Cyclops’
410f: 04 43 61 76+ L410F .l1str ‘Cave’
4114: 14 4d 61 67+ L4114 .l1str ‘Magnificent fountain’
4129: 05 4f 63 65+ L4129 .l1str ‘Ocean’
412f: 14 50 69 6c+ L412F .l1str ‘Pile of rubble/RUBB/’
4144: 31 .dd1 $31
4145: 00 L4145 .dd1 $00
4146: 10 4f 70 65+ L4146 .l1str ‘Open chest/CHES/’
4157: 33 .dd1 $33
4158: 0d 59 6f 75+ L4158 .l1str ‘Youthful King’
4166: 10 42 61 67+ L4166 .l1str ‘Bag of gold/BAG/’
4177: 35 .dd1 $35
4178: 0c 42 72 6f+ L4178 .l1str ‘Broken globe’
4185: 09 53 63 6f+ L4185 .l1str ‘Scorpions’
418f: 0b 54 6f 72+ L418F .l1str ‘Torch/TORC/’
419b: 38 .dd1 $38
419c: 11 43 72 6f+ L419C .l1str ‘Crowd of mourners’
41ae: 0c 53 74 6f+ L41AE .l1str ‘Stone tablet’
41bb: 05 41 6c 74+ L41BB .l1str ‘Altar’
41c1: 0f 53 63 6f+ L41C1 .l1str ‘Scorpion stings’
41d1: 19 46 65 73+ L41D1 .l1str ‘Festering scorpion stings’
41eb: 0f 41 6e 69+ L41EB .l1str ‘Animated statue’
41fb: 0b 53 77 6f+ L41FB .l1str ‘Sword/SWOR/’
4207: 3f .dd1 $3f
4208: 0c 52 6f 63+ L4208 .l1str ‘Rocky strand’
4215: 0b 53 61 6e+ L4215 .l1str ‘Sandy beach’
4221: 0c 53 6d 61+ L4221 .l1str ‘Small island’
422e: 10 53 68 69+ L422E .l1str ‘Ship is anchored’
423f: 0c 53 74 6f+ L423F .l1str ‘Stone tablet’
424c: 0d 42 6c 69+ L424C .l1str ‘Blind cyclops’
425a: 0a 53 74 61+ L425A .l1str ‘Stalagmite’
4265: 04 52 6f 70+ L4265 .l1str ‘Rope’
426a: 17 52 6f 70+ L426A .l1str ‘Rope tied to stalagmite’
4282: 15 4f 74 68+ L4282 .l1str ‘Other end of the rope’
4298: 1a 52 6f 70+ L4298 .l1str ‘Rope leading down into pit’
42b3: 1b 52 6f 70+ L42B3 .l1str ‘Rope leading out of the pit’
42cf: 0c 44 61 72+ L42CF .l1str ‘Dark hallway’
42dc: 05 43 61 62+ L42DC .l1str ‘Cabin’
42e2: 0c 50 65 72+ L42E2 .l1str ‘Persian city’
42ef: 0e 4c 6f 6e+ L42EF .l1str ‘Long staircase’
42fe: 00 T42FE .dd1 $00
;
; 16-bit value indicating which room an item is in. There are 80 entries, but
; entry 0 isn't used.
;
; (Unlike everything else nearby, this is mutable state.)
;
42ff: 00 00 01 00+ item_rooms .bulk $00,$00,$01,$00,$01,$00,$02,$00,$05,$00,$06,$00
+ $06,$00,$00,$00,$0d,$00,$00,$00,$0f,$00,$0b,$00
+ $00,$00,$07,$00,$07,$00,$00,$00,$00,$00,$0a,$00
+ $13,$00,$14,$00,$00,$00,$00,$00,$18,$00,$00,$00
+ $00,$00,$13,$00,$00,$00,$0e,$00,$04,$00,$03,$00
+ $05,$00,$12,$00,$04,$00,$00,$00,$03,$00,$03,$00
+ $00,$00,$00,$00,$00,$00,$0e,$00,$17,$00,$19,$00
+ $1c,$00,$1d,$00,$1e,$00,$22,$00,$22,$00,$24,$00
+ $05,$00,$00,$00,$00,$00,$00,$00,$00,$00,$08,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$03,$00,$16,$00
+ $00,$00,$00,$00,$00,$00,$11,$00,$00,$00,$00,$00
+ $00,$00,$06,$00,$24,$00,$00,$00,$1e,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$21,$00,$00,$00,$06,$00
+ $00,$00,$15,$00
;
; Pointers to item names (0-79).
;
439f: e9 3e item_names .dd2 L3EE9 ;item #0 (doesn't exist)
43a1: ea 3e .dd2 L3EEA
43a3: f8 3e .dd2 L3EF8
43a5: 02 3f .dd2 L3F02
43a7: 09 3f .dd2 L3F09
43a9: 14 3f .dd2 L3F14
43ab: 19 3f .dd2 L3F19
43ad: 1e 3f .dd2 L3F1E
43af: 25 3f .dd2 L3F25
43b1: 35 3f .dd2 L3F35 ;item #9 (lightsource)
43b3: 46 3f .dd2 L3F46
43b5: 54 3f .dd2 L3F54
43b7: 65 3f .dd2 L3F65
43b9: 6d 3f .dd2 L3F6D
43bb: 71 3f .dd2 L3F71
43bd: 78 3f .dd2 L3F78
43bf: 87 3f .dd2 L3F87
43c1: 9b 3f .dd2 L3F9B
43c3: a0 3f .dd2 L3FA0
43c5: af 3f .dd2 L3FAF
43c7: c4 3f .dd2 L3FC4
43c9: d5 3f .dd2 L3FD5
43cb: e4 3f .dd2 L3FE4
43cd: f0 3f .dd2 L3FF0
43cf: fc 3f .dd2 L3FFC
43d1: 08 40 .dd2 L4008
43d3: 16 40 .dd2 L4016
43d5: 29 40 .dd2 L4029
43d7: 33 40 .dd2 L4033
43d9: 3c 40 .dd2 L403C
43db: 45 40 .dd2 L4045
43dd: 4e 40 .dd2 L404E
43df: 5c 40 .dd2 L405C
43e1: 6b 40 .dd2 L406B
43e3: 7c 40 .dd2 L407C
43e5: 8b 40 .dd2 L408B
43e7: 9c 40 .dd2 L409C
43e9: a5 40 .dd2 L40A5
43eb: af 40 .dd2 L40AF
43ed: c5 40 .dd2 L40C5 ;$27
43ef: ce 40 .dd2 L40CE
43f1: da 40 .dd2 L40DA
43f3: ee 40 .dd2 L40EE
43f5: f2 40 .dd2 L40F2
43f7: fe 40 .dd2 L40FE
43f9: 07 41 .dd2 L4107
43fb: 0f 41 .dd2 L410F
43fd: 14 41 .dd2 L4114
43ff: 29 41 .dd2 L4129
4401: 2f 41 .dd2 L412F
4403: 45 41 .dd2 L4145
4405: 46 41 .dd2 L4146
4407: 58 41 .dd2 L4158
4409: 66 41 .dd2 L4166
440b: 78 41 .dd2 L4178
440d: 85 41 .dd2 L4185
440f: 8f 41 .dd2 L418F
4411: 9c 41 .dd2 L419C
4413: ae 41 .dd2 L41AE
4415: bb 41 .dd2 L41BB
4417: c1 41 .dd2 L41C1
4419: d1 41 .dd2 L41D1
441b: eb 41 .dd2 L41EB
441d: fb 41 .dd2 L41FB
441f: 08 42 .dd2 L4208
4421: 15 42 .dd2 L4215
4423: 21 42 .dd2 L4221
4425: 2e 42 .dd2 L422E
4427: 3f 42 .dd2 L423F
4429: 4c 42 .dd2 L424C
442b: 5a 42 .dd2 L425A
442d: 65 42 .dd2 L4265
442f: 6a 42 .dd2 L426A
4431: 82 42 .dd2 L4282
4433: 98 42 .dd2 L4298
4435: b3 42 .dd2 L42B3
4437: cf 42 .dd2 L42CF
4439: dc 42 .dd2 L42DC
443b: e2 42 .dd2 L42E2
443d: ef 42 .dd2 L42EF
;
; Initial room numbers for items. This is copied into item_rooms during game
; init.
;
443f: 00 00 01 00+ item_initrooms .bulk $00,$00,$01,$00,$01,$00,$02,$00,$05,$00,$06,$00
+ $06,$00,$00,$00,$0d,$00,$00,$00,$0f,$00,$0b,$00
+ $00,$00,$07,$00,$07,$00,$00,$00,$00,$00,$0a,$00
+ $13,$00,$14,$00,$00,$00,$00,$00,$18,$00,$00,$00
+ $00,$00,$13,$00,$00,$00,$0e,$00,$04,$00,$03,$00
+ $05,$00,$12,$00,$04,$00,$00,$00,$03,$00,$03,$00
+ $00,$00,$00,$00,$00,$00,$0e,$00,$17,$00,$19,$00
+ $1c,$00,$1d,$00,$1e,$00,$22,$00,$22,$00,$24,$00
+ $05,$00,$00,$00,$00,$00,$00,$00,$00,$00,$08,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$03,$00,$16,$00
+ $00,$00,$00,$00,$00,$00,$11,$00,$00,$00,$00,$00
+ $00,$00,$06,$00,$24,$00,$00,$00,$1e,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$21,$00,$00,$00,$06,$00
+ $00,$00,$15,$00
;
; Verb for action N (0-251). Will be $00 for occurrences.
;
; Occurrences must come first in the list.
;
44df: 00 00 00 00+ action_verb .bulk $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$0a,$01,$01,$01,$01,$01,$01,$01,$01
+ $01,$01,$01,$01,$01,$08,$09,$09,$0a,$01,$0a,$0a
+ $0a,$0a,$09,$09,$01,$09,$0a,$0a,$0a,$0a,$0a,$0a
+ $0a,$0a,$0a,$0a,$0a,$0a,$16,$4a,$0a,$0a,$11,$01
+ $11,$00,$11,$00,$11,$00,$11,$00,$3d,$11,$11,$11
+ $00,$31,$3c,$01,$01,$01,$01,$01,$01,$01,$01,$01
+ $01,$01,$0a,$10,$10,$10,$10,$10,$10,$12,$34,$12
+ $12,$12,$12,$12,$12,$16,$16,$16,$16,$16,$16,$16
+ $16,$16,$16,$16,$16,$16,$16,$16,$16,$16,$16,$16
+ $16,$16,$01,$01,$0a,$0a,$0a,$1b,$1b,$1b,$1b,$1b
+ $1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1d,$1d,$1d
+ $1d,$42,$12,$00,$00,$21,$23,$26,$21,$29,$2b,$2c
+ $16,$2e,$2e,$2f,$30,$32,$32,$0a,$33,$33,$2b,$42
+ $12,$36,$36,$3a,$3b,$48,$48,$45,$3e,$3f,$12,$42
+ $44,$44,$40,$40,$40,$40,$40,$01,$01,$01,$01,$35
+ $44,$3d,$44,$44,$34,$34,$16,$16,$12,$1b,$12,$12
;
; For occurrences (verb=$00), this is the percent chance of the action
; happening. For actions (verb!=$00), this is the index of the noun (NOT the
; item).
;
45db: 64 00 64 64+ action_nou_prc .bulk $64,$00,$64,$64,$64,$64,$64,$64,$64,$64,$64,$64
+ $00,$64,$00,$64,$64,$64,$32,$00,$64,$00,$00,$00
+ $64,$2d,$28,$46,$27,$64,$3c,$2d,$64,$64,$64,$00
+ $64,$64,$00,$2d,$64,$64,$00,$64,$64,$64,$64,$3c
+ $64,$64,$64,$64,$64,$64,$64,$64,$64,$64,$64,$64
+ $64,$64,$64,$27,$2d,$2f,$31,$3f,$40,$41,$43,$43
+ $43,$48,$48,$15,$16,$44,$00,$00,$3c,$09,$10,$10
+ $10,$12,$00,$00,$0b,$00,$19,$19,$19,$18,$18,$18
+ $36,$36,$37,$37,$38,$38,$2f,$00,$48,$48,$10,$2f
+ $3b,$00,$3b,$00,$3b,$00,$3b,$00,$00,$49,$49,$49
+ $00,$00,$2d,$43,$25,$2e,$0b,$0e,$12,$2c,$17,$20
+ $21,$22,$05,$3b,$3b,$3b,$3b,$3b,$3b,$10,$12,$19
+ $19,$19,$18,$18,$48,$0e,$18,$18,$19,$19,$19,$1c
+ $23,$26,$26,$28,$29,$2b,$30,$36,$36,$36,$35,$3b
+ $3b,$3b,$17,$17,$3e,$3e,$3e,$00,$04,$03,$02,$03
+ $02,$01,$03,$01,$04,$03,$04,$04,$00,$26,$26,$26
+ $00,$46,$39,$00,$00,$29,$34,$00,$29,$00,$3b,$12
+ $2f,$48,$48,$34,$30,$38,$3a,$48,$38,$3a,$3b,$46
+ $42,$3d,$00,$00,$00,$05,$06,$42,$48,$45,$48,$46
+ $2f,$2f,$0b,$38,$37,$36,$18,$22,$24,$24,$24,$00
+ $2d,$00,$2f,$2f,$12,$12,$2f,$00,$3a,$00,$38,$38
;
; Action opcode table. See the operations function table at $270c.
;
; One table for each of the four possible operations per action.
;
46d7: 01 51 4d 35+ action_op0_tab .bulk $01,$51,$4d,$35,$30,$38,$3a,$3c,$48,$81,$39,$58
+ $31,$58,$4f,$2d,$2e,$32,$0d,$51,$51,$33,$66,$51
+ $67,$68,$20,$6b,$6a,$69,$18,$1f,$3c,$3c,$58,$3d
+ $3b,$25,$48,$78,$3c,$09,$3b,$38,$2a,$38,$39,$6f
+ $35,$38,$39,$35,$35,$35,$35,$35,$39,$39,$35,$35
+ $1a,$3a,$39,$84,$0c,$0c,$0c,$0c,$0c,$0c,$0c,$0c
+ $0c,$0c,$0c,$0c,$0c,$47,$06,$06,$42,$0c,$0c,$0c
+ $0c,$0c,$06,$06,$0c,$06,$34,$34,$34,$34,$34,$34
+ $34,$34,$34,$34,$34,$34,$71,$0c,$34,$0c,$56,$0c
+ $27,$58,$27,$58,$27,$58,$27,$58,$0c,$37,$37,$37
+ $3a,$2c,$0c,$0c,$36,$0c,$0c,$0c,$0c,$0c,$0c,$0c
+ $0c,$0c,$0c,$7e,$7e,$7e,$0c,$0c,$0c,$0c,$0c,$0c
+ $0c,$0c,$03,$03,$03,$19,$13,$1e,$08,$08,$08,$0f
+ $0a,$21,$21,$06,$06,$12,$7b,$10,$10,$10,$06,$71
+ $71,$71,$0c,$0c,$22,$22,$34,$7e,$0c,$0c,$0c,$0c
+ $0c,$0c,$0c,$0c,$0c,$0c,$0c,$0c,$14,$04,$3b,$70
+ $23,$0c,$35,$58,$58,$0c,$0c,$7e,$7e,$7e,$70,$7d
+ $06,$3b,$37,$0c,$6e,$0c,$0c,$0c,$0c,$0c,$0c,$0c
+ $0c,$0c,$0c,$29,$42,$0c,$0c,$0c,$0c,$0c,$0c,$0c
+ $0c,$0c,$0c,$0c,$0c,$0c,$0c,$0c,$36,$36,$7b,$7e
+ $0c,$0c,$0c,$0c,$0c,$0c,$71,$0e,$0c,$0c,$0c,$00
47d3: 4f 4f 00 00+ action_op1_tab .bulk $4f,$4f,$00,$00,$00,$00,$38,$00,$00,$3c,$00,$49
+ $3d,$39,$51,$2f,$2f,$51,$4a,$4f,$4d,$48,$3d,$00
+ $35,$58,$48,$3c,$39,$3c,$58,$3d,$00,$00,$58,$3f
+ $3b,$3a,$3e,$3d,$00,$3b,$35,$40,$00,$40,$40,$37
+ $00,$40,$40,$00,$00,$00,$00,$00,$40,$40,$00,$00
+ $35,$00,$40,$7e,$23,$26,$36,$36,$36,$36,$36,$36
+ $36,$36,$36,$36,$36,$00,$02,$02,$00,$36,$3b,$3b
+ $70,$23,$02,$02,$36,$07,$0c,$0c,$0c,$0c,$0c,$0c
+ $0c,$0c,$0c,$0c,$0c,$0c,$73,$58,$0c,$3b,$24,$26
+ $75,$70,$75,$28,$75,$48,$58,$76,$11,$80,$80,$80
+ $3a,$3a,$3d,$36,$35,$36,$58,$36,$1b,$36,$36,$36
+ $36,$36,$36,$00,$00,$00,$3a,$3a,$3a,$35,$3d,$35
+ $35,$35,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$02,$02,$00,$00,$3a,$3a,$3a,$02,$72
+ $73,$73,$58,$36,$00,$00,$0c,$00,$58,$58,$58,$58
+ $58,$58,$58,$58,$58,$58,$58,$58,$00,$00,$05,$00
+ $00,$35,$48,$3a,$48,$48,$48,$00,$1d,$79,$00,$00
+ $02,$3b,$37,$48,$00,$4a,$4a,$4a,$37,$37,$3c,$35
+ $48,$55,$55,$3f,$00,$36,$36,$48,$03,$35,$35,$35
+ $3b,$3b,$3a,$3a,$3a,$3a,$3a,$36,$00,$00,$00,$00
+ $3b,$70,$3e,$3e,$3c,$3d,$73,$00,$35,$58,$35,$00
48cf: 3a 3a 00 00+ action_op2_tab .bulk $3a,$3a,$00,$00,$00,$00,$40,$00,$00,$3d,$00,$00
+ $29,$49,$53,$3c,$3c,$3e,$49,$51,$49,$49,$49,$00
+ $00,$58,$00,$00,$3d,$00,$58,$00,$00,$00,$6c,$00
+ $3b,$3a,$83,$00,$00,$3b,$00,$00,$00,$00,$00,$00
+ $00,$00,$29,$00,$00,$00,$00,$00,$00,$3c,$00,$00
+ $00,$00,$00,$00,$00,$3d,$00,$35,$35,$35,$35,$35
+ $35,$00,$00,$38,$00,$00,$35,$35,$00,$00,$7c,$7c
+ $00,$00,$35,$35,$35,$00,$00,$00,$00,$15,$00,$00
+ $15,$00,$15,$00,$15,$00,$00,$53,$00,$4a,$48,$3d
+ $58,$7f,$58,$3d,$58,$74,$49,$7f,$02,$3a,$3a,$3a
+ $3b,$58,$00,$35,$00,$00,$7a,$00,$3d,$00,$3a,$00
+ $00,$35,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$35,$35,$00,$00,$00,$00,$00,$35,$00
+ $00,$00,$1c,$00,$00,$00,$00,$00,$3c,$3c,$3c,$3c
+ $3c,$3c,$3c,$3c,$3c,$3c,$3c,$3c,$00,$00,$3e,$00
+ $00,$00,$16,$49,$00,$00,$00,$00,$00,$00,$00,$00
+ $3c,$82,$35,$00,$00,$00,$0b,$00,$00,$00,$3c,$3e
+ $3a,$25,$70,$00,$00,$00,$00,$3c,$00,$48,$00,$00
+ $83,$83,$00,$00,$00,$00,$00,$35,$00,$00,$00,$00
+ $35,$00,$83,$83,$84,$00,$00,$00,$37,$00,$37,$00
49cb: 49 3a 00 00+ action_op3_tab .bulk $49,$3a,$00,$00,$00,$00,$17,$00,$00,$37,$00,$00
+ $3f,$00,$2b,$51,$51,$00,$00,$3a,$00,$00,$00,$00
+ $00,$3a,$00,$00,$3c,$00,$3a,$00,$00,$00,$49,$00
+ $3b,$49,$00,$00,$00,$49,$00,$00,$00,$00,$00,$00
+ $00,$00,$3f,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$35,$35,$35,$35,$35
+ $35,$00,$00,$3a,$00,$00,$00,$00,$00,$00,$3c,$3c
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$3d,$00,$00
+ $3d,$00,$3d,$00,$3d,$00,$00,$00,$00,$00,$6d,$00
+ $49,$3d,$49,$00,$49,$3f,$00,$3d,$35,$3b,$3b,$49
+ $00,$00,$00,$00,$00,$00,$77,$00,$00,$00,$35,$00
+ $00,$35,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$77,$00,$00,$00,$00,$00,$3a,$3a,$3a,$3a
+ $3a,$3a,$3a,$3a,$3a,$3a,$3a,$3a,$00,$00,$00,$00
+ $00,$00,$49,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $35,$00,$0c,$00,$00,$00,$00,$00,$00,$00,$3c,$35
+ $00,$35,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$3c,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
;
; Action conditions table. Each 16-bit entry holds the condition opcode and
; argument, which have been merged as (opcode + arg * 20).
;
; There is one table for each of the 5 possible conditions per action.
;
; Entries with an opcode of zero hold the arguments for action opcodes. (So if
; you have 3 conditions and 3 actions with arguments, you can't hold the whole
; thing in a single action slot.)
;
4ac7: 75 02 00 00+ condition0_tab .bulk $75,$02,$00,$00,$00,$00,$52,$00,$13,$00,$c0,$00
+ $20,$01,$bc,$01,$b7,$00,$4c,$02,$b7,$00,$4c,$02
+ $4b,$02,$4c,$02,$cc,$10,$4c,$02,$4c,$02,$4c,$02
+ $9a,$02,$3c,$00,$d4,$01,$77,$00,$0f,$00,$d4,$01
+ $dd,$04,$da,$04,$e6,$04,$fc,$01,$fc,$01,$fc,$01
+ $70,$01,$10,$02,$10,$02,$4c,$02,$76,$04,$00,$00
+ $7c,$00,$96,$04,$f8,$02,$81,$00,$71,$05,$ba,$01
+ $e0,$01,$c0,$00,$d7,$00,$44,$01,$1c,$01,$85,$01
+ $08,$00,$c0,$00,$e8,$02,$08,$00,$1c,$00,$1c,$00
+ $6c,$00,$6c,$00,$35,$01,$cc,$00,$7c,$00,$f4,$00
+ $18,$00,$ac,$02,$bc,$01,$4e,$04,$5c,$02,$de,$00
+ $34,$02,$02,$05,$16,$05,$2a,$05,$7c,$00,$7c,$00
+ $7c,$00,$ca,$05,$de,$05,$2e,$01,$f2,$05,$00,$00
+ $84,$02,$b8,$00,$00,$00,$2c,$00,$cb,$00,$cb,$00
+ $cb,$00,$00,$00,$cc,$00,$cc,$00,$52,$00,$6d,$02
+ $ba,$01,$ce,$01,$e2,$01,$8a,$04,$8a,$04,$52,$05
+ $be,$02,$be,$02,$aa,$02,$aa,$02,$82,$02,$82,$02
+ $de,$00,$78,$00,$8e,$05,$ca,$05,$06,$01,$d4,$02
+ $18,$00,$00,$00,$18,$00,$00,$00,$18,$00,$28,$00
+ $18,$00,$00,$00,$bc,$01,$27,$04,$27,$04,$27,$04
+ $3c,$00,$44,$02,$5c,$02,$7c,$00,$1a,$06,$7c,$00
+ $52,$00,$7c,$00,$c2,$03,$90,$00,$cc,$00,$1c,$01
+ $1c,$01,$f2,$00,$48,$02,$41,$01,$41,$01,$41,$01
+ $de,$00,$c2,$03,$ae,$03,$c9,$00,$41,$01,$b9,$01
+ $cd,$01,$e1,$01,$89,$04,$51,$05,$b5,$05,$7c,$00
+ $53,$05,$8b,$04,$e3,$01,$cf,$01,$bb,$01,$06,$01
+ $cb,$00,$f6,$01,$da,$04,$bc,$01,$ff,$03,$86,$03
+ $5f,$03,$bd,$02,$bd,$02,$bd,$02,$d7,$03,$43,$01
+ $43,$01,$43,$01,$ac,$02,$ac,$02,$f6,$01,$da,$04
+ $ee,$04,$7c,$00,$7c,$00,$7c,$00,$7c,$00,$7c,$00
+ $7c,$00,$7c,$00,$7c,$00,$7c,$00,$7c,$00,$7c,$00
+ $7c,$00,$7c,$00,$7c,$00,$f6,$01,$da,$04,$00,$00
+ $00,$00,$b5,$05,$09,$02,$aa,$01,$86,$03,$37,$03
+ $63,$04,$00,$00,$37,$03,$00,$00,$41,$01,$41,$01
+ $de,$00,$a2,$05,$a2,$05,$b7,$00,$5f,$03,$81,$02
+ $91,$01,$b6,$05,$95,$02,$a5,$01,$41,$01,$89,$04
+ $7c,$00,$1c,$01,$00,$00,$00,$00,$00,$00,$94,$01
+ $94,$01,$7c,$00,$8d,$05,$5c,$02,$8d,$05,$51,$05
+ $89,$04,$51,$05,$52,$00,$82,$02,$aa,$02,$be,$02
+ $8a,$04,$f2,$00,$80,$01,$a8,$01,$94,$01,$00,$00
+ $b5,$05,$00,$00,$89,$04,$51,$05,$41,$01,$41,$01
+ $d4,$02,$00,$00,$91,$01,$7c,$00,$81,$02,$81,$02
4cbf: 3c 00 cc 10+ condition1_tab .bulk $3c,$00,$cc,$10,$00,$00,$c0,$03,$00,$00,$0f,$00
+ $40,$01,$21,$01,$48,$01,$e5,$04,$21,$01,$00,$00
+ $00,$00,$00,$00,$00,$00,$3b,$00,$27,$00,$0f,$00
+ $ca,$04,$c8,$00,$3c,$00,$b0,$04,$00,$00,$3c,$00
+ $e5,$04,$f4,$01,$f6,$01,$ed,$04,$f4,$01,$f4,$01
+ $86,$03,$00,$00,$08,$02,$44,$02,$00,$00,$00,$00
+ $00,$05,$5e,$05,$20,$03,$66,$05,$78,$00,$ce,$01
+ $50,$05,$a8,$00,$10,$00,$c0,$00,$10,$00,$52,$00
+ $7c,$00,$34,$01,$00,$00,$f4,$00,$7c,$00,$f4,$00
+ $7c,$00,$f4,$00,$21,$01,$10,$00,$5c,$01,$5c,$01
+ $35,$04,$68,$01,$10,$00,$00,$00,$00,$00,$00,$00
+ $44,$02,$7c,$00,$7c,$00,$7c,$00,$02,$05,$16,$05
+ $2a,$05,$94,$02,$58,$02,$cc,$01,$1c,$02,$00,$00
+ $f2,$02,$9a,$05,$00,$00,$14,$00,$bd,$04,$d1,$04
+ $00,$00,$00,$00,$6e,$04,$ee,$01,$30,$00,$00,$00
+ $b8,$01,$cc,$01,$e0,$01,$81,$00,$88,$04,$50,$05
+ $95,$00,$bc,$02,$45,$00,$a8,$02,$59,$00,$80,$02
+ $61,$02,$00,$00,$8c,$05,$c8,$05,$04,$01,$00,$00
+ $41,$01,$00,$00,$41,$01,$00,$00,$41,$01,$10,$04
+ $41,$01,$00,$00,$31,$01,$68,$00,$54,$00,$40,$00
+ $8c,$00,$00,$00,$00,$00,$1a,$06,$7c,$00,$30,$02
+ $31,$00,$f0,$00,$00,$00,$b4,$00,$dc,$00,$2c,$01
+ $54,$01,$1c,$01,$30,$02,$d0,$00,$e4,$00,$f8,$00
+ $41,$01,$41,$01,$41,$01,$c8,$00,$e4,$00,$b8,$01
+ $cc,$01,$e0,$01,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$4e,$01,$9e,$01,$00,$00
+ $00,$00,$f4,$00,$f4,$00,$f4,$00,$da,$01,$d0,$00
+ $e4,$00,$f8,$00,$91,$03,$bc,$02,$f1,$04,$f1,$04
+ $ec,$04,$3e,$05,$5c,$01,$5c,$01,$5c,$01,$98,$01
+ $98,$01,$ac,$01,$ac,$01,$c0,$01,$c0,$01,$24,$02
+ $24,$02,$38,$02,$b4,$02,$00,$00,$94,$01,$00,$00
+ $00,$00,$b4,$05,$08,$02,$18,$01,$84,$03,$e5,$02
+ $7f,$01,$00,$00,$00,$00,$00,$00,$d1,$00,$00,$00
+ $60,$02,$ca,$05,$a0,$05,$b4,$00,$00,$00,$9a,$02
+ $aa,$01,$b4,$05,$94,$02,$a4,$01,$c8,$00,$88,$04
+ $8e,$00,$53,$05,$00,$00,$00,$00,$00,$00,$a4,$01
+ $7c,$01,$3e,$05,$00,$00,$8f,$05,$8c,$05,$50,$05
+ $e0,$00,$44,$01,$25,$04,$25,$04,$25,$04,$25,$04
+ $25,$04,$44,$01,$90,$01,$90,$01,$00,$00,$00,$00
+ $b4,$05,$00,$00,$44,$01,$e0,$00,$d0,$00,$f8,$00
+ $00,$00,$00,$00,$90,$01,$00,$00,$80,$02,$00,$00
4eb7: 7c 01 6c 02+ condition2_tab .bulk $7c,$01,$6c,$02,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$a0,$00,$b4,$00,$48,$02,$00,$00,$00,$00
+ $00,$00,$00,$00,$14,$00,$44,$02,$44,$02,$00,$00
+ $b6,$04,$3c,$00,$00,$00,$c4,$04,$00,$00,$00,$00
+ $d8,$04,$00,$00,$f4,$01,$f4,$01,$00,$00,$00,$00
+ $08,$02,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $14,$05,$bd,$00,$f0,$05,$00,$00,$00,$00,$e2,$01
+ $00,$00,$00,$00,$00,$00,$00,$00,$21,$01,$50,$00
+ $c0,$01,$00,$00,$00,$00,$c0,$01,$98,$01,$98,$01
+ $38,$02,$38,$02,$00,$00,$21,$01,$18,$06,$18,$06
+ $24,$04,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$7c,$01,$8c,$00,$04,$01,$7c,$01,$8c,$00
+ $04,$01,$00,$00,$00,$00,$a0,$00,$00,$00,$00,$00
+ $6d,$02,$6d,$02,$00,$00,$00,$00,$b0,$04,$c4,$04
+ $00,$00,$00,$00,$6d,$02,$6d,$02,$78,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$88,$04,$00,$00,$00,$00
+ $bc,$02,$00,$00,$a8,$02,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$b4,$05,$d0,$02,$00,$00
+ $d0,$00,$00,$00,$e4,$00,$00,$00,$f8,$00,$00,$00
+ $00,$00,$00,$00,$2c,$01,$24,$04,$24,$04,$24,$04
+ $44,$02,$00,$00,$00,$00,$64,$00,$64,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$a0,$00,$00,$00
+ $00,$00,$40,$01,$00,$00,$00,$00,$00,$00,$00,$00
+ $d1,$00,$e5,$00,$d1,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$40,$01,$90,$01,$00,$00
+ $00,$00,$c0,$01,$38,$02,$98,$01,$cc,$01,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$ab,$02,$ab,$02,$ab,$02,$ab,$02
+ $ab,$02,$ab,$02,$ab,$02,$ab,$02,$ab,$02,$ab,$02
+ $ab,$02,$ab,$02,$00,$00,$00,$00,$d8,$04,$00,$00
+ $00,$00,$00,$00,$08,$02,$00,$00,$64,$05,$34,$03
+ $49,$01,$00,$00,$00,$00,$00,$00,$e5,$00,$00,$00
+ $58,$02,$a0,$05,$b4,$05,$60,$04,$00,$00,$94,$02
+ $a4,$01,$00,$00,$00,$00,$00,$00,$dc,$00,$88,$04
+ $3c,$05,$f0,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$3c,$05,$00,$00,$a0,$05,$00,$00,$00,$00
+ $88,$04,$50,$05,$31,$00,$59,$00,$45,$00,$95,$00
+ $81,$00,$18,$01,$00,$00,$00,$00,$00,$00,$00,$00
+ $c8,$05,$00,$00,$88,$04,$50,$05,$c8,$00,$00,$00
+ $00,$00,$00,$00,$a4,$01,$00,$00,$94,$02,$00,$00
50af: 00 00 54 01+ condition3_tab .bulk $00,$00,$54,$01,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$60,$04,$44,$02,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$74,$04
+ $4f,$04,$cc,$01,$00,$00,$3c,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$d8,$04,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $28,$05,$58,$02,$cc,$01,$00,$00,$00,$00,$b8,$01
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$05,$00,$00,$00,$00,$00,$05,$28,$05,$28,$05
+ $14,$05,$14,$05,$00,$00,$a0,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$4c,$04,$4c,$04,$4c,$04,$4c,$04,$4c,$04
+ $4c,$04,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $e4,$02,$8c,$05,$00,$00,$00,$00,$cc,$01,$cc,$01
+ $00,$00,$00,$00,$60,$04,$e0,$01,$c0,$03,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$28,$00,$50,$00,$78,$00
+ $00,$00,$00,$00,$00,$00,$50,$00,$50,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$dc,$00,$00,$00
+ $00,$00,$f0,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $f9,$00,$f9,$00,$e5,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$0e,$05,$22,$05,$36,$05,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$54,$01,$54,$01,$54,$01,$90,$01
+ $90,$01,$a4,$01,$a4,$01,$b8,$01,$b8,$01,$1c,$02
+ $1c,$02,$30,$02,$00,$00,$00,$00,$d4,$03,$00,$00
+ $00,$00,$00,$00,$38,$04,$00,$00,$00,$00,$fc,$03
+ $60,$04,$00,$00,$00,$00,$00,$00,$f9,$00,$00,$00
+ $08,$02,$c8,$05,$8c,$05,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$f0,$00,$58,$02
+ $8c,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$8c,$00,$00,$00,$b4,$05,$00,$00,$00,$00
+ $00,$00,$00,$00,$28,$00,$50,$00,$3c,$00,$8c,$00
+ $78,$00,$f0,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$a0,$00,$a0,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
52a7: 00 00 00 00+ condition4_tab .bulk $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$d8,$04,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$28,$00
+ $b0,$04,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $18,$06,$b4,$00,$00,$00,$00,$00,$00,$00,$cc,$01
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$50,$00,$50,$00,$50,$00,$50,$00,$50,$00
+ $50,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$58,$02,$30,$02,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$dc,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $dc,$00,$c8,$00,$f0,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$64,$00,$14,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$90,$01,$1c,$02,$b8,$01,$54,$01
+ $a4,$01,$90,$01,$b8,$01,$54,$01,$a4,$01,$30,$02
+ $54,$01,$1c,$02,$00,$00,$00,$00,$7c,$01,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $b4,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$f8,$02
+ $7c,$01,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$7c,$01,$00,$00,$8c,$05,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$a0,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
;
; Pointers to room descriptions.
;
; There are 38 rooms (0-37), though room 0 is "nowhere".
;
549f: 26 34 room_descrs .dd2 T3427-1
54a1: 27 34 .dd2 T3427
54a3: 34 34 .dd2 T3434
54a5: 41 34 .dd2 T3441
54a7: 4e 34 .dd2 T344E
54a9: 5b 34 .dd2 T345B
54ab: 72 34 .dd2 T3472
54ad: 88 34 .dd2 T3488
54af: 9e 34 .dd2 T349E
54b1: 9f 34 .dd2 T349F
54b3: ac 34 .dd2 T34AC
54b5: b9 34 .dd2 T34B9
54b7: c3 34 .dd2 T34C3
54b9: cf 34 .dd2 T34CF
54bb: e6 34 .dd2 T34E6
54bd: fd 34 .dd2 T34FD
54bf: 07 35 .dd2 T3507
54c1: 13 35 .dd2 T3513
54c3: 26 35 .dd2 T3526
54c5: 3d 35 .dd2 T353D
54c7: 54 35 .dd2 T3554
54c9: 6d 35 .dd2 T356D
54cb: 7b 35 .dd2 T357B
54cd: 89 35 .dd2 T3589
54cf: 98 35 .dd2 T3598
54d1: a7 35 .dd2 T35A7
54d3: b5 35 .dd2 T35B5
54d5: b6 35 .dd2 T35B6
54d7: c4 35 .dd2 T35C4
54d9: d0 35 .dd2 T35D0
54db: d9 35 .dd2 T35D9
54dd: e5 35 .dd2 T35E5
54df: e6 35 .dd2 T35E6
54e1: fd 35 .dd2 T35FD
54e3: 06 36 .dd2 T3606
54e5: 0f 36 .dd2 T360F
54e7: 28 36 .dd2 T3628
54e9: 41 36 .dd2 T3641
;
; Destination rooms for visible exits. Each exit direction has a separate
; table; each table has one 16-bit entry per room. If the room has no exit in
; that direction, the entry will be zero.
;
54eb: 00 00 00 00+ visible_exits_n .bulk $00,$00,$00,$00,$00,$00,$02,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$0a,$00,$0a,$00,$00,$00
+ $00,$00,$0e,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$19,$00,$16,$00
+ $00,$00,$00,$00,$00,$00,$17,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$13,$00,$00,$00,$21,$00,$22,$00
+ $00,$00,$00,$00
5537: 00 00 00 00+ visible_exits_s .bulk $00,$00,$00,$00,$03,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$09,$00,$09,$00,$00,$00
+ $00,$00,$00,$00,$0d,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$20,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$16,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$22,$00,$00,$00,$00,$00
+ $00,$00,$00,$00
5583: 00 00 02 00+ visible_exits_e .bulk $00,$00,$02,$00,$00,$00,$04,$00,$00,$00,$03,$00
+ $00,$00,$00,$00,$00,$00,$09,$00,$0a,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$0e,$00,$00,$00,$00,$00
+ $0d,$00,$00,$00,$00,$00,$00,$00,$15,$00,$00,$00
+ $17,$00,$00,$00,$00,$00,$1e,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $23,$00,$00,$00
55cf: 00 00 00 00+ visible_exits_w .bulk $00,$00,$00,$00,$00,$00,$05,$00,$03,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$07,$00,$0a,$00,$0a,$00
+ $00,$00,$12,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$16,$00,$00,$00,$18,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $1b,$00,$00,$00,$00,$00,$00,$00,$00,$00,$24,$00
+ $00,$00,$00,$00
561b: 00 00 00 00+ visible_exits_u .bulk $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$06,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00
5667: 00 00 00 00+ visible_exits_d .bulk $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $06,$00,$00,$00,$00,$00,$00,$00,$00,$00,$0e,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00
;
; Pointers to messages.
;
; There are 83 messages (0-82), though message 0 is empty.
;
56b3: 51 36 messages .dd2 T3651
56b5: 52 36 .dd2 T3652
56b7: be 36 .dd2 T36BE
56b9: c9 36 .dd2 T36C9
56bb: d0 36 .dd2 T36D0
56bd: e3 36 .dd2 T36E3
56bf: 07 37 .dd2 T3707
56c1: 0f 37 .dd2 T370F
56c3: 18 37 .dd2 T3718
56c5: 4f 37 .dd2 T374F
56c7: 6e 37 .dd2 T376E
56c9: 84 37 .dd2 T3784
56cb: 9d 37 .dd2 T379D
56cd: a0 37 .dd2 T37A0
56cf: a6 37 .dd2 T37A6
56d1: bd 37 .dd2 T37BD
56d3: db 37 .dd2 T37DB
56d5: e4 37 .dd2 T37E4
56d7: eb 37 .dd2 T37EB
56d9: 1a 38 .dd2 T381A
56db: 4b 38 .dd2 T384B
56dd: 6b 38 .dd2 T386B
56df: 9a 38 .dd2 T389A
56e1: bf 38 .dd2 T38BF
56e3: ca 38 .dd2 T38CA
56e5: e3 38 .dd2 T38E3
56e7: 08 39 .dd2 T3908
56e9: 87 39 .dd2 T3987
56eb: 9c 39 .dd2 T399C
56ed: a4 39 .dd2 T39A4
56ef: b1 39 .dd2 T39B1
56f1: cc 39 .dd2 T39CC
56f3: e8 39 .dd2 T39E8
56f5: 02 3a .dd2 T3A02
56f7: 18 3a .dd2 T3A18
56f9: 2f 3a .dd2 T3A2F
56fb: 3c 3a .dd2 T3A3C
56fd: 84 3a .dd2 T3A84
56ff: a1 3a .dd2 T3AA1
5701: e6 3a .dd2 T3AE6
5703: f8 3a .dd2 T3AF8
5705: 1b 3b .dd2 T3B1B
5707: 35 3b .dd2 T3B35
5709: 48 3b .dd2 T3B48
570b: 58 3b .dd2 T3B58
570d: 63 3b .dd2 T3B63
570f: 6a 3b .dd2 T3B6A
5711: 70 3b .dd2 T3B70
5713: 8d 3b .dd2 T3B8D
5715: 9e 3b .dd2 T3B9E
5717: cc 3b .dd2 T3BCC
5719: df 3b .dd2 T3BDF
571b: f2 3b .dd2 T3BF2
571d: 15 3c .dd2 T3C15
571f: 28 3c .dd2 T3C28
5721: 41 3c .dd2 T3C41
5723: 4f 3c .dd2 T3C4F
5725: 65 3c .dd2 T3C65
5727: 7c 3c .dd2 T3C7C
5729: bf 3c .dd2 T3CBF
572b: d0 3c .dd2 T3CD0
572d: 0c 3d .dd2 T3D0C
572f: 22 3d .dd2 T3D22
5731: 33 3d .dd2 T3D33
5733: 40 3d .dd2 T3D40
5735: 47 3d .dd2 T3D47
5737: 59 3d .dd2 T3D59
5739: a2 3d .dd2 T3DA2
573b: b4 3d .dd2 T3DB4
573d: cd 3d .dd2 T3DCD
573f: db 3d .dd2 T3DDB
5741: fd 3d .dd2 T3DFD
5743: 16 3e .dd2 T3E16
5745: 1f 3e .dd2 T3E1F
5747: 38 3e .dd2 T3E38
5749: 4c 3e .dd2 T3E4C
574b: 56 3e .dd2 T3E56
574d: 5d 3e .dd2 T3E5D
574f: 71 3e .dd2 T3E71
5751: a4 3e .dd2 T3EA4
5753: c2 3e .dd2 T3EC2
5755: dc 3e .dd2 T3EDC
5757: e3 3e .dd2 T3EE3
;
5759: 00 00 00 00+ .junk 23