; Disassembly of the file "F:\GAMES\SPECCY\A\ARTICADV\Advent_a.sna" ; ; Created with dZ80 v1.30a ; ; on Wednesday, 05 of August 1998 at 11:33 PM ; ; PLANET OF DEATH ; An Adventure game originally released for the ZX80/ZX81/ZX Spectrum by ARTIC COMPUTING in 1981. ; Disassembled, annotated and converted for use with CP/M by Paul Taylor, 18-Aug-1998. ; With special thanks to Tim Olmstead. ; ; Bugs - SAVE/RESTORE game doesn't work. Needs to implemented using CP/M file handling. ; Search for ROM_SAV and ROM_LD for details on how to do this. ; Minor modifications to original game: ; ; - To break the stalactites, use the stones. ; - To avoid turning green and dying, wear the gloves. ; ; Apologies if the indentation looks awful. .org $0100 jp START ROM_SAV .equ $04c2 ; Spectrum ROM routine ROM_LD .equ $0556 ; Spectrum ROM routine ; item location codes #define ITEM_NEXIST $fc #define ITEM_WORN $fd #define ITEM_HELD $fe ; ix offsets (negative - the positive ones are game variables, see below) #define OFFS_F_NTYET -$08 #define OFFS_PARAM1 -$07 #define OFFS_VERB_TK -$04 #define OFFS_CMDFLG -$06 #define OFFS_PREDIX -$05 #define OFFS_NOUN_TK -$03 #define OFFS_FLAG -$02 #define OFFS_CUR_RM -$01 F_NTYET .equ $-$2c ; ix+OFFS_F_NTYET points here PARAM1 .equ $-$2b ; ix+OFFS_PARAM1 points here CMDFLG .equ $-$2a ; ix+OFFS_CMDFLG points here PREDIX .equ $-$29 ; ix+OFFS_PREDIX points here VERB_TK .equ $-$28 ; ix+OFFS_VERB_TK points here NOUN_TK .equ $-$27 ; ix+OFFS_NOUN_TK points here FLAG .equ $-$26 ; ix+OFFS_FLAG points here CUR_RM .equ $-$25 ; ix+OFFS_CUR_RM points here GVARS .equ $-$24 ; workspace of $1e bytes of game variables - ix points here ; offsets of game variables #define GVAR_NO_ITEMS $01 #define GVAR_02 $02 #define GVAR_03 $03 #define GVAR_04 $04 #define GVAR_05 $05 #define GVAR_06 $06 #define GVAR_07 $07 #define GVAR_08 $08 #define GVAR_09 $09 #define GVAR_0a $0a #define GVAR_0b $0b #define GVAR_0c $0c #define GVAR_0d $0d #define GVAR_0e $0e #define GVAR_0f $0f #define GVAR_10 $10 #define GVAR_11 $11 #define GVAR_12 $12 #define GVAR_13 $13 #define GVAR_14 $14 #define GVAR_15 $15 #define GVAR_16 $16 #define GVAR_17 $17 #define GVAR_18 $18 #define GVAR_19 $19 #define GVAR_1a $1a #define GVAR_1b $1b #define GVAR_1c $1c #define GVAR_1d $1d #define GVAR_1e $1e TOK_BUF .equ $-$06 ; workspace of $04 bytes to hold a token SPARE_3 .equ $-$05 ; three unused bytes SCORE .equ $-$02 ; 2 bytes, the current score as a 16-bit word ; main program starts here START ld hl,GVARS ; zero all game variables ld b,$1e INITLP ld (hl),$00 inc hl djnz INITLP ld hl,$0000 ld (SCORE),hl call INSTR ; display instructions ld hl,ITRM_ST ld de,ITEM_RM ld bc,$001d ldir ; copy data from ITRM_ST to ITEM_RM at start of game ld ix,GVARS ; initialize ix to point at the game variables ld (ix+OFFS_CUR_RM),$00 ; set current room to 0 (starting room) push hl ; save hl (points at ITEM_RM) jr RESTG ; skip message data... RESTG_M .text "WANT TO RESTORE A GAME?" .byte $0d,$00 RESTG ld hl,RESTG_M ; prompt - restore game? call PRT_STR ; print it pop hl ; restore hl (points at ITEM_RM) call GETCH cp 'Y' call z,LCASS ; user typed 'Y', go and restore game ; main execution loop MAIN call CLR_SCR xor a cp (ix+$00) ; if (ix+$00) is zero, jr z,ROOM ; go and display the room description cp (ix+$03) ; if (ix+$03) is zero, jr z,DARK_CH ; go straight to the dark check dec (ix+$03) ; otherwise, decrement (ix+$03) DARK_CH ld a,(ITEM_RM) ; get location of item $00 cp (ix+OFFS_CUR_RM) ; check whether it's in the current room jr z,ROOM ; if it is, it's not dark push hl jr DARK ; skip message data... DARK_M .text "EVERYTHING IS DARK.I CANT SEE." .byte $0d,$00 DARK ld hl,DARK_M ; say it's dark and we can't see call PRT_STR pop hl xor a cp (ix+$04) ; if (ix+$04) is zero, jr z,DARK_ND ; go straight to ???????? dec (ix+$04) ; otherwise, decrement (ix+$04) DARK_ND jr DO_AUTO ; (96) ; display description for current room ROOM ld de,ROOM_V ; start at first room ld l,(ix+OFFS_CUR_RM) ; fetch current room number ld h,$00 add hl,hl ; double it (address = 2 bytes) add hl,de ; add it on ld e,(hl) inc hl ld d,(hl) ex de,hl ; retrieve description address into hl call PRT_STR ; print it ld (ix+OFFS_FLAG),$00 ; set "items printed" flag to 0 ld hl,ITEM_RM ; start of item location list ld c,$00 ; current item number ITEM_LP ld a,(hl) ; get room number for location of current item cp $ff ; end of list? jr z,DO_AUTO ; yes, go to ...... cp (ix+OFFS_CUR_RM) ; in current room? jr nz,ITEM_NX ; no, skip to next item xor a cp (ix+OFFS_FLAG) ; first item to be printed? jr nz,ISEE_1 ; no, don't print heading push hl jr ISEE ; skip message data... ISEE_M .text "I CAN ALSO SEE :" .byte $0d,$00 ISEE ld hl,ISEE_M ; heading call PRT_STR ; print it pop hl inc (ix+OFFS_FLAG) ; set "items printed" flag to 1 ISEE_1 push hl ld hl,ITEM_V ; look up item description by position ld b,$00 ; c already holds item number add hl,bc add hl,bc ld e,(hl) ; fetch description address from vector inc hl ld d,(hl) ex de,hl call PRT_STR ; print it call PRT_CR ; new line pop hl ITEM_NX inc hl ; move onto next item in ITEM_RM list inc c ; increment current item number jr ITEM_LP ; next item ; ====================================================================== ; perform regular automatic functions, e.g. the little green man ; ====================================================================== DO_AUTO ld hl,AUT_LST ; select the auto command list (wildcards, every command matches) jp PARS_LP ; and restart parser ; ====================================================================== ; system command - TELL command ; generates the "tell me what to do" prompt ; ====================================================================== SH_TELL pop bc pop hl xor a cp (ix+GVAR_02) jr z,S2_TELL dec (ix+GVAR_02) S2_TELL cp (ix+GVAR_05) jr z,S3_TELL dec (ix+GVAR_05) S3_TELL jr TELL TELL_M .text "TELL ME WHAT TO DO " .byte $0d,$00 TELL ld hl,TELL_M ; select the "tell me what to do" message call PRT_STR ; print it call GETLN ; fetch user's command ld (ix+OFFS_F_NTYET),$00 ; clear the not-yet flag ready for parsing ; ====================================================================== ; fetch verb token from the input buffer ; ====================================================================== GT_VERB call GET_TOK ; fetch the next token (4 chars) ld (VERB_TK),a ; store its token code cp $ff ; unrecognized? jr nz,VERB_OK ; nope - go to next stage ld a,(hl) ; take a look at the next character cp $0d ; end of line? jr z,DONT ; print "I don't understand" or a ; end of data? jr nz,VERB_UN ; no - skip on to try next word in input buffer DONT push hl jr DONT_1 ; skip message data... DONT_M .text "I DONT UNDERSTAND" .byte $0d,$00 DONT_1 ld hl,DONT_M ; don't understand message call PRT_STR ; print it pop hl jr DO_AUTO ; verb unknown VERB_UN ld a,(hl) ; fetch current byte of input buffer cp $20 ; space? jr nz,VERB_SK ; no... inc hl ; yes - skip the space, jr GT_VERB ; and try again to recognize the verb VERB_SK cp $00 ; end of data? jr z,DONT ; give up - don't understand cp $0d ; end of line? jr z,DONT ; give up - don't understand inc hl ; skip over unknown character, jr VERB_UN ; and try again ; verb recognized VERB_OK ld (ix+OFFS_NOUN_TK),$ff ; assume noun unrecognized before reading on ; trim off excess characters from the verb VERB_LP ld a,(hl) ; take a look at next character in the edit line cp $20 ; space? jr z,GT_NOUN ; goto to fetch the noun cp $00 ; end of data? jp z,P_DIR ; no noun, then cp $0d ; end of line? jp z,P_DIR ; no noun, then inc hl ; skip extra character jr VERB_LP ; loop back ; ====================================================================== ; fetch noun token from the input buffer ; ====================================================================== GT_NOUN inc hl ; skip the space after the verb call GET_TOK ; fetch the next token (4 chars) ld (NOUN_TK),a ; store its token code cp $ff ; unrecognized? jr nz,P_DIR ; nope - go to next stage NOUN_LP ld a,(hl) ; take a look at the next character cp $00 ; end of data jr z,P_DIR ; allow the unknown noun through cp $0d ; end of line? jr z,P_DIR ; allow the unknown noun through cp $20 ; space? jr z,GT_NOUN ; try again - user typed an extra word, e.g. 'the' inc hl ; ignore excess characters of unknown noun jr NOUN_LP ; loop back ; ====================================================================== ; attempt to parse a direction verb ; ====================================================================== P_DIR ld d,$00 ld e,(ix+OFFS_CUR_RM) ld hl,DIR_V add hl,de add hl,de ; fetch address for current room from vector DIR_V ld e,(hl) inc hl ld d,(hl) ex de,hl ; address of directional data now in HL DIR_LP ld a,(hl) ; fetch a byte from the direction list cp $ff ; reached $ff termination byte? jr z,PARSE ; yes - exit loop cp (ix+OFFS_VERB_TK) ; compare byte with verb - is it a match? jr nz,DIR_NXT ; no - go to fetch the next byte inc hl ; yes - increment pointer ld a,(hl) ; fetch the destination room number ld (ix+OFFS_CUR_RM),a ; use it to set the new current room jp MAIN ; restart main execution loop from new room DIR_NXT inc hl ; skip destination room number inc hl ; move onto next direction entry jr DIR_LP ; loop back ; ====================================================================== ; main parser ; ====================================================================== PARSE ld hl,VN_DEFS ld (ix+OFFS_CMDFLG),$00 ; clear command flag - no commands executed yet PARS_LP ld a,(hl) ; fetch verb token from list or a ; zero byte (terminator)? jr nz,P_VERB ; no - proceed to parse the verb ; at this point we've reached the end of VN_DEFS, and A=0 cp (ix+OFFS_CMDFLG) ; has command flag been set to 1? jp nz,DO_AUTO ; yes - jump to auto command handling ld a,(ix+OFFS_VERB_TK) ; is verb token < $0d? cp $0d ; i.e. it's a directional command jr c,NOGO ; yes - display "I can't go in that direction" message ld a,(ix+OFFS_F_NTYET) ; not-yet flag set? or a jr nz,NOTYET ; yes - display "I can't do that yet" message push hl jr CANT ; skip message data... CANT_M .text "I CANT" .byte $0d,$00 CANT ld hl,CANT_M ; select "I can't" message call PRT_STR ; display it pop hl jp DO_AUTO ; proceed to carry out automatic processing (such as the little green man) NOTYET push hl jr NOTYT_2 ; skip message data... NOTYT_M .text "I CANT DO THAT YET" .byte $0d,$00 NOTYT_2 ld hl,NOTYT_M ; select "I can't do that yet" message call PRT_STR ; display it pop hl jp DO_AUTO ; proceed to carry out automatic processing (such as the little green man) NOGO push hl jr NOGO_2 ; skip message data... NOGO_M .text "I CANT GO IN THAT DIRECTION" .byte $0d,$00 NOGO_2 ld hl,NOGO_M call PRT_STR pop hl jp DO_AUTO .byte $00 ; spare P_VERB cp $ff ; wildcard verb? jr z,P_NOUN ; yes - assume a match cp (ix+OFFS_VERB_TK) ; same verb that user entered? jr z,P_NOUN ; yes - proceed to parse the noun PARS_NX ld de,$0006 ; skip over the add hl,de ; non-matching entry jp PARS_LP ; loop back to process the next entry P_NOUN inc hl ; fetch next byte from list ld a,(hl) ; i.e. the noun token cp $ff ; wildcard noun? jr z,P_EXEC ; yes - assume a match cp (ix+OFFS_NOUN_TK) ; same noun that user entered? jr z,P_EXEC ; yes - execute appropriate command dec hl ; no - backtrack to start of entry jr PARS_NX ; then skip forward to next entry ; verb and noun match - now decide what to do P_EXEC inc hl ld c,(hl) ; fetch the address of the predicate list entry inc hl ld b,(hl) ; into BC inc hl P_NEXT ld a,(bc) ; if there are no more bytes in cp $ff ; the predicate list entry, jp z,SYS_EXC ; then proceed to a execute any system commands ld (PREDIX),a ; store the predicate index in PREDIX inc bc ld a,(bc) ld (PARAM1),a ; store the parameter in PARAM1 push hl ; store current VN_DEFS position on the stack ld hl,PRED_V ; start at beginning of predicate vector array ld d,$00 ld e,(ix+OFFS_PREDIX) ; use PREDIX to calculate offset add hl,de add hl,de ld e,(hl) ; fetch the address of the handler routine inc hl ld d,(hl) ; from the vector ex de,hl jp (hl) ; jump to the handler routine (NB: current VN_DEFS position is on the stack) ; predicates ; predicate CHKROOM - this tests the current room number to make sure it's the specified room number. ; if it is, we move on to the next command, otherwise we trigger a "i can't do that yet" response. ; this handler interprets PARAM1 as the room number CHKROOM ld a,(PARAM1) ; compare current parameter cp (ix+OFFS_CUR_RM) ; with current room number jr z,NXT_CMD ; if we're in that room - then skip on to the next parameter ; otherwise fall through to the "not yet" failure routine below ; command failed - cannot be executed yet ERR_NY pop hl ; restore current VN_DEFS position into HL inc hl ; skip forward to inc hl ; next entry ld (ix+OFFS_F_NTYET),$01 ; set flag to indicate "not yet" jp PARS_LP ; predicate for GET and DROP commands ; this handler interprets PARAM1 as the item number CHKHERE ld hl,ITEM_RM ; obtain the current location ld d,$00 ; of the item ld e,(ix+OFFS_PARAM1) add hl,de ld a,(hl) ; into A cp (ix+OFFS_CUR_RM) ; is the item in the current room? jr z,NXT_CMD ; yes - we can get it cp ITEM_WORN ; item location >= ITEM_WORN? (i.e. it's carried/worn) jr nc,NXT_CMD ; yes - we can drop it jr ERR_NY ; not yet - item is not available ; predicate CHKRAND - randomly allows or disallows the user's command. ; if allowed, we move on to the next command, otherwise we trigger a "i can't do that yet" response. CHKRAND ld a,r sub (ix+OFFS_PARAM1) jr c,NXT_CMD ; (52) jr ERR_NY ; (-40) ; predicate CHKAWAY - checks that the specified item is not carried, held or in the current room. ; if it is NOT, we move on to the next command, otherwise we trigger a "i can't do that yet" response. ; this handler interprets PARAM1 as the item number CHKAWAY ld hl,ITEM_RM ; look up location of ld d,$00 ; item referred to by ld e,(ix+OFFS_PARAM1) ; PARAM1 add hl,de ld a,(hl) cp (ix+OFFS_CUR_RM) ; is it in the current room? jr z,ERR_NY ; yes - then say "not yet" cp ITEM_WORN ; item location >= ITEM_WORN? (i.e. it's carried/worn) jr nc,ERR_NY ; yes - say not yet jr NXT_CMD ; item is in another room, or non-existant so move on to next command ; predicate CHKWORN - checks that the specified item is being worn. ; if it is, we move on to the next command, otherwise we trigger a "i can't do that yet" response. ; this handler interprets PARAM1 as the item number CHKWORN ld hl,ITEM_RM ld d,$00 ld e,(ix+OFFS_PARAM1) add hl,de ld a,(hl) cp ITEM_WORN jr z,NXT_CMD ; (15) jr ERR_NY ; (-77) ; predicate CHKSETF - checks the game variable specified by PARAM1. ; if it is non-zero, we move on to the next command, otherwise we trigger a "i can't do that yet" response. ; this handler interprets PARAM1 as the game variable number ; used by "field" and "look up" CHKSETF ld hl,GVARS ; game variables... ld d,$00 ld e,(ix+OFFS_PARAM1) add hl,de ld a,(hl) ; examine specified variable or a ; zero? jr z,ERR_NY ; yes - trigger the "not yet" message ; otherwise fall through to allow the next command to be executed ; move on to next command NXT_CMD pop hl ; restore current VN_DEFS position into HL inc bc ; increment pointer, to point to the next byte jp P_NEXT ; predicate TSTGVAR - compares the game variable specified by PARAM1 with the value specified as ; the next byte after the command. ; if it is equal, we move on to the next command, otherwise we trigger a "i can't do that yet" response. ; this handler interprets PARAM1 as the game variable number TSTGVAR inc bc ; fetch next parameter ld a,(bc) ld hl,GVARS ld d,$00 ld e,(ix+OFFS_PARAM1) add hl,de cp (hl) ; compare it with specified game variable jr nz,ERR_NY ; not equal? then trigger "not yet" jr NXT_CMD ; otherwise move on to next command ; predicate CHKCLRF - checks the game variable specified by PARAM1. ; if it is zero, we move on to the next command, otherwise we trigger a "i can't do that yet" response. ; this handler interprets PARAM1 as the game variable number CHKCLRF ld hl,GVARS ; fetch specified game variable ld d,$00 ld e,(ix+OFFS_PARAM1) add hl,de ld a,(hl) or a ; equal to zero? jp nz,ERR_NY ; no - trigger "not yet" message jr NXT_CMD ; yes - proceed with next command ; predicate CHKHELD - checks that the specified item is being carried (or worn!). ; if it is, we move on to the next command, otherwise we trigger a "i can't do that yet" response. ; this handler interprets PARAM1 as the item number CHKHELD ld hl,ITEM_RM ; fetch location of specified item ld d,$00 ld e,(ix+OFFS_PARAM1) add hl,de ld a,(hl) cp ITEM_HELD ; are we carrying it? jr z,NXT_CMD ; yes - proceed with next command cp ITEM_WORN ; are we wearing it? jr z,NXT_CMD ; yes - proceed with next command jp ERR_NY ; no - trigger "not yet" message ; a table of predicates #define COM_CHKROOM $00 #define COM_CHKHERE $01 #define COM_CHKRAND $02 #define COM_CHKAWAY $03 #define COM_CHKWORN $04 #define COM_CHKSETF $05 #define COM_TSTGVAR $06 #define COM_CHKCLRF $07 #define COM_CHKHELD $08 PRED_V .word CHKROOM ; $00 .word CHKHERE ; $01 .word CHKRAND ; $02 .word CHKAWAY ; $03 .word CHKWORN ; $04 .word CHKSETF ; $05 .word TSTGVAR ; $06 .word CHKCLRF ; $07 .word CHKHELD ; $08 SYS_EXC ld c,(hl) ; fetch the address of the command list from COM_LIST inc hl ; into BC ld b,(hl) inc hl ld (ix+OFFS_CMDFLG),$01 ; set command flag = 1 SYS_NXT ld a,(bc) ; fetch system command index from the list cp $ff ; reached $ff terminating byte? jp z,PARS_LP ; Yes - then continue with parsing loop ld (PREDIX),a ; store system command index in PREDIX inc bc ; move on to next byte ld a,(bc) ; fetch item number from list ld (PARAM1),a ; store in PARAM1 push hl ; push current VN_DEFS position onto stack push bc ; push current command list position onto stack ld hl,SYS_V ld d,$00 ld e,(ix+OFFS_PREDIX) ; use system command index as an offset into vector SYS_V add hl,de ; to obtain address of system command to execute add hl,de ld e,(hl) inc hl ld d,(hl) ex de,hl jp (hl) ; execute handler ; fetch location for an item ; item number is in PARAM1 ; location is returned in A ; address of location entry is returned in HL GET_LOC ld hl,ITEM_RM ld b,$00 ld c,(ix+OFFS_PARAM1) add hl,bc ld a,(hl) ret GETLN ld hl,EDITLN jp GETLN_1 ; the edit buffer, into which the user enters commands ; this buffer is $20 bytes long, and initially contains ; fairly obscure stuff - left-over source code, perhaps? EDITLN .byte $b3 .byte $b2 .byte $b8 .text " " .byte $09 .text "RET" .byte $0d .byte $b0 .byte $b0 .byte $b3 .byte $b3 .byte $b0 .text " " .byte $09 .text "END" .byte $09 .text "MAIN" .byte $0d .byte $1a .text "LL" .byte $09 .text "GETB" ; addresses of various system function handlers SYS_V .word SH_INVE .word SH_REMO .word SH_GET .word SH_DROP .word SH_WEAR .word SH_MSG .word SH_REDE .word SH_AUTO .word SH_GOTO .word SH_SETF .word SH_CLRF .word SH_SWAP .word SH_DEAD .word SH_OK .word SH_QUIT .word SH_SETV .word SH_CREA .word SH_DEST .word SH_ADSC .word SH_SCOR .word SH_FAIL .word SH_TELL .word SH_FAIL .word SH_FAIL .word SH_FAIL SH_INVE push hl jr INVENT ; (31) INV_M .text "I HAVE WITH ME THE FOLLOWING:" .byte $0d,$00 INVENT ld hl,INV_M call PRT_STR pop hl ld (ix+OFFS_FLAG),$00 ld hl,ITEM_RM ld c,$00 INV_LP ld a,(hl) cp $ff ; end of item location list? jr z,INV_END ; yes - then we're finished cp ITEM_WORN ; < ITEM_WORN? jr c,INV_SKP ; yes - not carried or worn, so skip ld (ix+OFFS_FLAG),$01 push hl ld hl,ITEM_V ld b,$00 add hl,bc add hl,bc ld e,(hl) inc hl ld d,(hl) ex de,hl call PRT_STR pop hl ld a,(hl) cp ITEM_WORN jr nz,INV_CR ; (30) push hl ld hl,WEAR_M call PRT_STR pop hl jr INV_CR ; skip message data... WEAR_M .text " WHICH I AM WEARING" .byte $00 INV_CR call PRT_CR INV_SKP inc hl inc c jr INV_LP ; (-71) INV_END xor a cp (ix+OFFS_FLAG) jp nz,SH_FAIL push hl jr NOWT ; (16) NOWT_M .text "NOTHING AT ALL" .byte $0d,$00 NOWT ld hl,NOWT_M call PRT_STR pop hl jp SH_FAIL ; ====================================================================== ; system command - REMOVE command ; item to be removed is specified in PARAM1 ; ====================================================================== SH_REMO call GET_LOC ; get location of item cp ITEM_WORN ; is it being worn? jr z,S2_REMO ; yes - carry on to next stage push hl jr NWEAR ; skip message data... NWEAR_M .text "I AM NOT WEARING IT" .byte $0d,$00 NWEAR ld hl,NWEAR_M ; select message "I am not wearing it" call PRT_STR ; display it pop hl jp SH_FAIL ; clean up S2_REMO ld a,(ix+GVAR_NO_ITEMS) ; are we already carrying six items? cp $06 jr nz,S3_REMO ; no - proceed to remove item push hl jr FULL ; skip message data... FULL_M .text "I CANT. MY HANDS ARE FULL" .byte $0d,$00 FULL ld hl,FULL_M ; select message "my hands are full" call PRT_STR ; display it pop hl jp SH_FAIL ; clean up S3_REMO ld (hl),ITEM_HELD ; mark item as carried (not worn) inc (ix+GVAR_NO_ITEMS) ; increment item count jp SH_SUCC ; clean up ; ====================================================================== ; system command - GET command ; item to be got is specified in PARAM1 ; ====================================================================== SH_GET ld a,(ix+GVAR_NO_ITEMS) ; check how many items we're carrying cp $06 ; six already? jr nz,S2_GET ; no - continue with handler below... push hl jr CARRY ; skip message data... CARRY_M .text "I CANT CARRY ANY MORE" .byte $0d,$00 CARRY ld hl,CARRY_M ; select "I can't carry any more" message call PRT_STR ; display it pop hl jp SH_FAIL ; clean up S2_GET call GET_LOC ; obtain the current location of the item (in A and HL) cp (ix+OFFS_CUR_RM) ; is the item in the current room? jr nz,S3_GET ; no - then it can't be picked up ld (hl),ITEM_HELD ; yes - mark it as carried inc (ix+GVAR_NO_ITEMS) ; and increment item count jp SH_SUCC ; clean up S3_GET cp ITEM_WORN ; wearing it? jr z,S4_GET ; yes - then we already have it cp ITEM_HELD ; carrying it already? jr z,S4_GET ; yes - then we already have it ld hl,NOSEE_M ; it's not here, and we don't have it call PRT_STR ; print "I don't see it here" jp SH_FAIL ; clean up NOSEE_M .text "I DON'T SEE IT HERE" .byte $0d,$00 S4_GET push hl jr AHAVE ; skip over message data... AHAVE_M .text "I ALREADY HAVE IT" .byte $0d,$00 AHAVE ld hl,AHAVE_M ; select "I already have it" message call PRT_STR ; display it pop hl jp SH_FAIL ; clean up ; ====================================================================== ; system command - DROP command ; item to be dropped is specified in PARAM1 ; ====================================================================== SH_DROP call GET_LOC ; obtain the current location of the item (in A and HL) cp (ix+OFFS_CUR_RM) ; is the item in the current room? jr nz,S3_DROP ; no - perhaps we are carrying it S2_DROP push hl ; we are not carrying the item jr DHAVE ; skip message data... DHAVE_M .text "I DONT HAVE IT" .byte $0d,$00 DHAVE ld hl,DHAVE_M ; select "I don't have it" message call PRT_STR ; display it pop hl jp SH_FAIL ; clean up S3_DROP cp ITEM_WORN ; are we wearing the item? jr z,S4_DROP ; yes - go ahead and drop it cp ITEM_HELD ; are we carrying the item? jr nz,S2_DROP ; no - then we can't drop it dec (ix+GVAR_NO_ITEMS) ; decrement the count of items (if we weren't wearing the item) S4_DROP ld a,(ix+OFFS_CUR_RM) ; set items current location ld (hl),a ; to be the current room jp SH_SUCC ; clean up ; ====================================================================== ; system command - WEAR command ; item to be worn is specified in PARAM1 ; ====================================================================== SH_WEAR call GET_LOC ; get location of item cp ITEM_HELD ; is it being carried? jr nz,S2_WEAR ; no - then we can't wear it ld (hl),ITEM_WORN ; mark item as worn dec (ix+GVAR_NO_ITEMS) ; decrement item count jp SH_SUCC ; clean up S2_WEAR cp ITEM_WORN ; is it already being worn? jr nz,S3_WEAR ; no - we don't have it push hl jr AWEAR ; skip over message data... AWEAR_M .text "I AM ALREADY WEARING IT" .byte $0d,$00 AWEAR ld hl,AWEAR_M ; select message "I am already wearing it" call PRT_STR ; display it pop hl jp SH_FAIL ; clean up S3_WEAR push hl jr DHAV2 ; skip over message data... DHAV2_M .text "I DONT HAVE IT" .byte $0d,$00 DHAV2 ld hl,DHAV2_M ; select message "I don't have it" call PRT_STR ; display it pop hl jp SH_FAIL ; clean up ; ====================================================================== ; system command - display a response ; index of response to be displayed is specified in PARAM1 ; ====================================================================== SH_MSG ld hl,MSG_V ld b,$00 ld c,(ix+OFFS_PARAM1) add hl,bc add hl,bc ld e,(hl) inc hl ld d,(hl) ex de,hl call PRT_STR jr SH_SUCC ; (42) ; ====================================================================== ; system command - REDE ; redescribe current room, terminating execution of system commands ; ====================================================================== SH_REDE pop bc pop hl jp MAIN ; ====================================================================== ; exactly the same effect as SH_FAIL - it halts further system command ; processing, ; and proceeds to execute the auto commands. ; ====================================================================== SH_AUTO pop bc pop hl jp DO_AUTO ; ====================================================================== ; system command - go directly to specific room (do not pass go) ; index of room is specified in PARAM1 ; NB: room description not automatically displayed ; ====================================================================== SH_GOTO ld a,(ix+OFFS_PARAM1) ld (ix+OFFS_CUR_RM),a jr SH_SUCC ; (24) ; ====================================================================== ; system command SETF - set game variable to $ff ; index of variable to set is specified in PARAM1 ; ====================================================================== SH_SETF ld hl,GVARS ld b,$00 ld c,(ix+OFFS_PARAM1) add hl,bc ld (hl),$ff jr SH_SUCC ; (11) ; ====================================================================== ; system command CLRF - clear game variable to $00 ; index of variable to clear is specified in PARAM1 ; ====================================================================== SH_CLRF ld hl,GVARS ld b,$00 ld c,(ix+OFFS_PARAM1) add hl,bc ld (hl),$00 ; fall through to SH_SUCC ; ====================================================================== ; system command SUCC ; clean up and continue with next system command ; ====================================================================== SH_SUCC pop bc pop hl inc bc jp SYS_NXT ; ====================================================================== ; system command - SWAP ; swap an item's location with the location of the following item ; item to be swapped is specified in PARAM1 ; ====================================================================== SH_SWAP call GET_LOC inc hl ld b,(hl) ld (hl),a dec hl ld (hl),b jr SH_SUCC ; (-16) ; ====================================================================== ; system command - DEAD ; immediately terminate game, stop executing system commands ; ====================================================================== SH_DEAD jp GM_OVER ; display "OK.." prompt and cease processing system commands SH_OK push hl jr S2_OK ; skip message data... OK_M .text "OK.." .byte $0d,$00 S2_OK ld hl,OK_M call PRT_STR pop hl jp SH_FAIL SH_QUIT push hl jr SAVEG ; (31) SAVEG_M .text "DO YOU WANT TO SAVE THE GAME?" .byte $0d,$00 SAVEG ld hl,SAVEG_M call PRT_STR pop hl call GETCH cp 'Y' jr nz,GM_OVER ; (103) push ix ld ix,FLAG ld de,$002b push hl jr SCASS ; (16) SCASS_M .text "READY CASSETTE" .byte $0d,$00 SCASS ld hl,SCASS_M call PRT_STR pop hl call GETCH ld a,$ff scf ; call ROM_SAV ; save starting from IX, no. bytes = DE ld ix,ITEM_RM ld de,$001d ld a,$ff scf ; call ROM_SAV ; save starting from IX, no. bytes = DE pop ix push hl jr CONT ; (26) CONT_M .text "DO YOU WISH TO CONTINUE?" .byte $0d,$00 CONT ld hl,CONT_M call PRT_STR pop hl call GETCH cp 'Y' jp z,SH_FAIL GM_OVER push hl jr AGAIN ; (27) AGAIN_M .text "DO YOU WISH TO TRY AGAIN?" .byte $0d,$00 AGAIN ld hl,AGAIN_M call PRT_STR pop hl YESNO push hl jr YESNO_2 ; skip message data... YESNO_M .text "ANSWER YES OR NO" .byte $0d,$00 YESNO_2 ld hl,YESNO_M call PRT_STR pop hl call GETCH nop nop nop cp 'Y' jp z,START cp 'N' jp z,$0000 jr YESNO ; (-46) ; ====================================================================== ; system command SETV - set game variable to a specific value ; index of variable to set is specified in PARAM1 ; the new value is specified as the byte after this command ; ====================================================================== SH_SETV pop bc inc bc push bc ld a,(bc) ld (PREDIX),a ld hl,GVARS ld b,$00 ld c,(ix+OFFS_PARAM1) add hl,bc ld (hl),a jp SH_SUCC ; ====================================================================== ; system command CREA - create item in current room ; index of item to be created is specified in PARAM1 ; ====================================================================== SH_CREA ld hl,ITEM_RM ld b,$00 ld c,(ix+OFFS_PARAM1) add hl,bc ld a,(ix+OFFS_CUR_RM) ld (hl),a jp SH_SUCC ; ====================================================================== ; system command DEST - destroy item in current room ; index of item to be destoyed is specified in PARAM1 ; ====================================================================== SH_DEST ld hl,ITEM_RM ld b,$00 ld c,(ix+OFFS_PARAM1) add hl,bc ld (hl),ITEM_NEXIST jp SH_SUCC ; clean-up and abort execution of system commands, continuing with auto commands SH_FAIL pop bc ; restore BC pop hl ; and HL from the stack jp DO_AUTO ; and perform regular auto commands (e.g. green man) ; ====================================================================== ; system command ADSC - add value to the current score. ; value to be added is specified in PARAM1 ; ====================================================================== SH_ADSC ld a,(SCORE) ld b,a ld a,(PARAM1) add a,b daa ld (SCORE),a pop hl inc hl push hl ld a,(SCORE+1) adc a,(hl) daa ld (SCORE+1),a jp SH_SUCC SH_SC_M .text "YOU HAVE A SCORE OF " .byte $00 SH_SCOR ld hl,SH_SC_M call PRT_STR ld a,(SCORE+1) call PRT_HX ld a,(SCORE) call PRT_HX call PRT_CR pop bc pop hl jp SYS_NXT ; prints a two-digit hex number, the byte held in A PRT_HX push af rra rra rra rra call PRT_HX1 pop af ; prints a single hex digit, the lower nibble of A PRT_HX1 push af and $0f add a,'0' call PUTCH pop af ret ; ====================================================================== ; fetch command token from the input buffer, starting at position HL ; on return, A contains the token code (or $ff if not recognized) ; and HL points to the character after the token ; ====================================================================== GET_TOK push hl ld hl,$2020 ; clear the token buffer to spaces ld (TOK_BUF),hl ld (TOK_BUF+$02),hl pop hl ld de,TOK_BUF ; store chars in token buffer ld b,$04 ; up to four characters TOK_LP ld a,(hl) ; fetch character from edit line cp $20 ; space? jr z,TOK_END ; stop fetching, move on to next stage cp $00 ; zero byte? jr z,TOK_END ; stop fetching, move on to next stage cp $0d ; newline? jr z,TOK_END ; stop fetching, move on to next stage ld (de),a ; store character in token buffer inc hl ; move on to next character in edit line inc de ; move on to next position in token buffer djnz TOK_LP ; loop TOK_END push hl ; store HL ld hl,TOKENS ; point hl at array of tokens ld a,$ff push af TOK_LP2 ld (ix+OFFS_FLAG),$00 ; clear flag ld b,$04 ld de,TOK_BUF TOK_LP3 ld a,(hl) ; fetch byte from token list entry cp $ff ; $ff indicates the end of the list jr z,TOK_FIN ; exit the loop with A=$ff (not found) ld a,(de) ; compare byte of token buffer cp (hl) ; with byte of token list entry jr z,TOK_SKP ; if they match, carry on with flag=0 ld (ix+OFFS_FLAG),$01 ; set flag=1 - they didn't match TOK_SKP inc hl ; move on to next byte in token list inc de ; move on to next byte in token buffer djnz TOK_LP3 ; loop for 4 chars xor a ; ok, did they match? cp (ix+OFFS_FLAG) ; flag=0 if they did match jr nz,TOK_NXT ; if not, go to ?????? to try next token in list pop af ld a,(hl) ; set A=token code push af TOK_FIN pop af pop hl ret TOK_NXT inc hl ; skip token code, to move on to next token jr TOK_LP2 ; go back for another try ; ====================================================================== LCASS push hl jr LCASS_1 ; (16) LCASS_M .text "READY CASSETTE" .byte $0d,$00 LCASS_1 ld hl,LCASS_M call PRT_STR pop hl call GETCH push ix ld ix,FLAG ld de,$0029 ld a,$ff scf ; call ROM_LD ; load starting at IX, no. bytes = DE ld ix,ITEM_RM ld de,$001d ld a,$ff scf ; call ROM_LD ; load starting at IX, no. bytes = DE pop ix ret ; ====================================================================== ; clear screen, display instructions and wait for keypress ; ====================================================================== INSTR call CLR_SCR ld hl,INSTR_M call PRT_STR jp GETCH INSTR_M .text "WELCOME TO ADVENTURE 'A'" .byte $0d .text "THE PLANET OF DEATH" .byte $0d,$0d .text "IN THIS ADVENTURE YOU FIND " .text "YOURSELF STRANDED ON AN " .text "ALIEN PLANET. YOUR AIM IS " .text "TO ESCAPE FROM THIS PLANET " .text "BY FINDING YOUR, NOW " .text "CAPTURED AND DISABLED, " .text "SPACE SHIP" .byte $0d .text "YOU WILL MEET VARIOUS " .text "HAZARDS AND DANGERS ON YOUR " .text "ADVENTURE, SOME NATURAL, " .text "SOME NOT, ALL OF WHICH YOU " .text "MUST OVERCOME TO SUCCEED" .byte $0d,$0d .text "GOOD LUCK, YOU WILL NEED IT!" .byte $0d,$0d .text "PRESS ANY KEY TO START" .byte $0d,$00 ; ====================================================================== ; output a character to the display ; ====================================================================== PUTCH push ix ; preserve all registers push hl push de push bc push af ld c,$02 ld e,a call $0005 pop af push af cp $0d jr nz,PUTCH_E ld c,$02 ld e,$0a call $0005 call SET_REM PUTCH_E pop af ; restore all registers pop bc pop de pop hl pop ix ret ; ====================================================================== ; fetch key from buffer ; waits for keypress, returns ascii code in A ; ====================================================================== GETCH push hl push de push bc call GETCHlp pop bc pop de pop hl ret GETCHlp ld c,$06 ld e,$ff call $0005 or a ; still zero? jr z,GETCHlp ; yes, try again... cp $90 ; >= 144? jr nc,GETCHlp ; yes, try again... cp $08 ; < 8? jr c,GETCHlp ; yes, try again... cp $60 ; < 96 (i.e. uppercase)? ret c ; yes, finished. sub $20 ; make uppercase ret ; finished ; unused keyboard-reading code (left over from ZX81 version?) push de ld d,a ld a,$7f in a,($fe) rra jr c,ZX_END2 ld a,$fe in a,($fe) rra jr c,ZX_END2 ld a,$01 or a ZX_END ld a,d pop de ret ZX_END2 xor a jr ZX_END ; (-6) ; ====================================================================== ; get a line of input from the user ; store the data in the buffer pointed to by HL ; ====================================================================== GETLN_1 push hl ; preserve hl ld b,$20 ; $20 = buffer size GL_LP1 ld (hl),$00 ; insert end-of-line marker call GETCH ; fetch a character from the keyboard cp $08 ; is it DELETE? jr nz,GL_SKP ; no - enter the character into the buffer ld a,$20 ; cp b ; b = $20? i.e. buffer empty? jr z,GL_LP1 ; yes - ignore delete, go back for another character inc b ; increment chars remaining count dec hl ; decrement buffer pointer GL_LP2 ld a,$08 ; erase the character from the screen call PUTCH ld a,$20 call PUTCH ld a,$08 call PUTCH jr GL_LP1 ; go back for another character GL_SKP call PUTCH ; display the character cp $0d ; RETURN? jr z,GL_END ; yes - we've finished inc b dec b jr z,GL_LP2 ; no space in buffer? dec b ; dec char count ld (hl),a ; add char to buffer inc hl ; increment buffer pointer jr GL_LP1 ; go back for another character GL_END pop hl ; finished - restore hl ret ; ====================================================================== ; throw a new line on the display ; ====================================================================== PRT_CR push af ld a,$0d call PUTCH pop af ret ; ====================================================================== ; clear the screen ; ====================================================================== CLR_SCR push hl push de push bc push af ld a,$0c ; form-feed (VT52 terminal) call PUTCH call SET_REM pop af pop bc pop de pop hl ret ; ====================================================================== ; reset CH_REM to indicate whole line is available ; ====================================================================== SET_REM ld a,32 ; 32-character display ld (CH_REM),a ret ; ====================================================================== ; print a space on the screen ; ====================================================================== PRT_SPC push af ld a,$20 call PUTCH pop af dec a ret ; number of chars remaining on current line ; used to implement word-wrap CH_REM .byte $20 ; ====================================================================== ; print the zero-terminated string pointed to by HL ; performing word-wrap and scrolling if necessary ; ====================================================================== PRT_STR nop PRT_LP ld a,(hl) ; fetch character from string inc hl ; move on to the next character or a ret z ; finished when zero byte reached cp $0d ; newline? call z,PRT_CR ; throw new line jr z,PRT_LP ; and skip to next character cp $20 ; space? jr z,PRT_LP ; don't display it yet - skip to next character dec hl ; decrement pointer, back to the character in A again push hl ; remember this position ld b,$00 ; zero the character count WORD_LP ld a,(hl) ; take a look at the character cp $20 ; if it's a space, jr z,WORD_EX ; skip to the next stage or a ; if it's a zero byte (end of string), jr z,WORD_EX ; skip to the next stage cp $0d ; if it's a newline, jr z,WORD_EX ; skip to the next stage inc b ; increment the count of characters in the word inc hl ; move on to the next character jr WORD_LP ; carry on for the rest of the word WORD_EX ld a,(CH_REM) ; fetch the number of characters remaining on the line cp b ; compare with number of characters in the word call c,PRT_CR ; if not enough space, throw a new line first pop hl ; restore position to first char of word WORD_PR ld a,(hl) ; fetch character from string cp $20 ; if it's a space, jr z,WORD_SP ; we've finished printing the word or a ; if it's a zero byte (end of string), jr z,WORD_SP ; we've finished printing the word cp $0d ; if it's a newline, jr z,WORD_SP ; we've finished printing the word call PUTCH ; print the character to the screen inc hl ; move on to the next character jr WORD_PR ; carry on for the rest of the word WORD_SP ld a,(CH_REM) ; deduct the size of the word from the remaining sub b ; characters available on the line call nz,PRT_SPC ; output a space after the word (adjusts CH_REM) ld (CH_REM),a ; store the new chars remaining count jr PRT_STR ; loop back for next character in the string ; ====================================================================== ; array of pointers to room descriptions ; ====================================================================== ROOM_V .word ROOM_00 .word ROOM_01 .word ROOM_02 .word ROOM_03 .word ROOM_04 .word ROOM_05 .word ROOM_06 .word ROOM_MZ ; maze .word ROOM_MZ ; maze .word ROOM_MZ ; maze .word ROOM_MZ ; maze .word ROOM_0B .word ROOM_0C .word ROOM_0D .word ROOM_0E .word ROOM_0F .word ROOM_10 .word ROOM_11 .word ROOM_12 .word ROOM_13 .word ROOM_14 .word $0000 ; ====================================================================== ; each room description, terminated by a zero byte ; ====================================================================== ROOM_00 .text "I AM ON A MOUNTAIN PLATEAU\r" .text "TO THE NORTH THERE IS A STEEP CLIFF\r" .text "OBVIOUS EXITS ARE DOWN,EAST AND WEST\r\000" ROOM_01 .text "I AM AT THE EDGE OF A DEEP PIT\r" .text "OBVIOUS EXITS ARE EAST\r\000" ROOM_02 .text "I AM IN A DAMP LIMESTONE CAVE WITH STALACTITES HANGING DOWN.\r" .text "THE EXIT IS TO THE WEST\r" .text "THERE IS A PASSAGE TO THE NORTH\r\000" ROOM_03 .text "I AM IN A DENSE FOREST\r" .text "THERE IS A ROPE HANGING FROM ONE TREE\r" .text "OBVIOUS EXITS ARE SOUTH AND WEST\r\000" ROOM_04 .text "I AM BESIDE A LAKE\r" .text "EXITS ARE EAST AND NORTH.THERE IS A RAVINE TO THE WEST\r\000" ROOM_05 .text "I AM IN A STRANGE HOUSE\r" .text "THE DOOR IS TO THE NORTH\r\000" ROOM_06 .text "I AM IN AN OLD SHED\r" .text "THE EXIT IS TO THE EAST\r\000" ROOM_MZ .text "I AM IN A MAZE.THERE ARE PASSAGES EVERYWHERE\r\000" ROOM_0B .text "I AM IN AN ICE CAVERN\r" .text "THERE IS AN EXIT TO THE EAST\r\000" ROOM_0C .text "I AM IN A QUIET CAVERN\r" .text "THERE ARE EXITS WEST,EAST AND SOUTH\r\000" ROOM_0D .text "I AM IN A WIND TUNNEL\r" .text "THERE IS A CLOSED DOOR AT THE END\r" .text "THERE IS ALSO AN EXIT TO THE WEST\r\000" ROOM_0E .text "I AM IN A ROOM WITH A COMPUTER IN\r" .text "THE COMPUTER IS WORKING AND HAS A KEYBOARD\r" .text "THE EXIT IS WEST\r\000" ROOM_0F .text "I AM IN A PASSAGE\r" .text "THERE IS A FORCE FIELD TO THE SOUTH : BEWARE OF SECURITY\r" .text "THERE ARE EXITS TO NORTH,EAST AND WEST\r\000" ROOM_10 .text "I AM IN A LARGE HANGER\r" .text "THERE IS A LOCKED DOOR TO THE WEST\r" .text "THERE ARE ALSO EXITS EAST,NORTH AND SOUTH\r\000" ROOM_11 .text "I AM IN A TALL LIFT.THE BUTTONS ARE VERY HIGH\r" .text "THE EXIT IS WEST\r\000" ROOM_12 .text "I AM IN THE LIFT CONTROL ROOM\r" .text "THERE ARE THREE SWITCHES ON THE WALL.THEY ARE ALL OFF\r" .text "A SIGN SAYS : 5,4 NO DUSTY BIN RULES\r" .text "THE EXIT IS EAST\r\000" ROOM_13 .text "I AM IN A PRISON CELL\r\000" ROOM_14 .text "I AM IN A SPACE SHIP.THERE IS NO VISIBLE EXIT\r" .text "THERE IS A SMALL OPEN WINDOW IN THE SIDE\r" .text "THERE ARE ALSO TWO BUTTONS,ONE MARKED MAIN AND THE OTHER AUX.\r\000" ; ====================================================================== ; initial positions of items - 1 byte per item, holds room number ; ITEM_NEXIST indicates item doesn't exist yet ; $ff indicates end of list ; ====================================================================== ITRM_ST .byte $05 .byte $11 .byte $0e .byte $06 .byte $11 .byte ITEM_NEXIST .byte ITEM_NEXIST .byte $0c .byte ITEM_NEXIST .byte $0d .byte ITEM_NEXIST .byte $05 .byte ITEM_NEXIST .byte ITEM_NEXIST .byte $0b .byte ITEM_NEXIST .byte $0c .byte ITEM_NEXIST .byte $13 .byte ITEM_NEXIST .byte $13 .byte ITEM_NEXIST .byte $10 .byte $10 .byte $00 .byte $01 .byte $02 .byte $0f .byte $ff ; ====================================================================== ; current positions of items - 1 byte per item, holds room number ; initialized from ITRM_ST at start, updated during the game ; data below is garbage, but once initialized with the above data: ; ITEM_NEXIST indicates item doesn't exist yet ; $ff indicates end of list ; ====================================================================== ITEM_RM .byte $00 .byte $01 .byte $00 .byte $01 .byte $00 .byte $01 .byte $00 .byte $01 .byte $00 .byte $01 .byte $00 .byte $01 .byte $00 .byte $01 .byte $00 .byte $01 .byte $00 .byte $01 .byte $00 .byte $ff .byte $fe .byte $ff .byte $14 .byte $ff .byte $fe .byte $ff .byte $54 .byte $ff .byte $fe ; ====================================================================== ; array of pointers to item descriptions ; ====================================================================== ITEM_V .word ITEM_00 .word ITEM_01 .word ITEM_02 .word ITEM_03 .word ITEM_04 .word ITEM_05 .word ITEM_06 .word ITEM_07 .word ITEM_08 .word ITEM_09 .word ITEM_0A .word ITEM_0B .word ITEM_0C .word ITEM_0D .word ITEM_0E .word ITEM_0F .word ITEM_10 .word ITEM_11 .word ITEM_12 .word ITEM_13 .word ITEM_14 .word ITEM_15 .word ITEM_16 .word ITEM_17 .word ITEM_18 .word ITEM_19 .word ITEM_1A .word ITEM_1B .word $0000 ; ====================================================================== ; each item description, terminated by a zero byte ; ====================================================================== ITEM_00 .text "A PAIR OF BOOTS\000" ITEM_01 .text "A STARTER MOTOR\000" ITEM_02 .text "A KEY\000" ITEM_03 .text "A LASER GUN\000" ITEM_04 .text "AN OUT OF ORDER SIGN\000" ITEM_05 .text "A METAL BAR\000" ITEM_06 .text "A GOLD COIN\000" ITEM_07 .text "A MIRROR\000" ITEM_08 .text "BROKEN GLASS\000" ITEM_09 .text "A PAIR OF SLIMY GLOVES\000" ITEM_0A .text "A ROPE\000" ITEM_0B .text "A FLOOR BOARD\000" ITEM_0C .text "A BROKEN FLOOR BOARD\000" ITEM_0D .text "STALACTITES\000" ITEM_0E .text "A BLOCK OF ICE\000" ITEM_0F .text "A POOL OF WATER\000" ITEM_10 .text "A SMALL GREEN MAN SLEEPING ON THE MIRROR\000" ITEM_11 .text "A SLEEPING GREEN MAN\000" ITEM_12 .text "A LOCKED DOOR\000" ITEM_13 .text "AN OPEN DOOR\000" ITEM_14 .text "A BARRED WINDOW\000" ITEM_15 .text "A HOLE IN THE WALL\000" ITEM_16 .text "A SMALL BUT POWERFULL SPACE SHIP\000" ITEM_17 .text "A SLEEPING SECURITY MAN\000" ITEM_18 .text "A PIECE OF SHARP FLINT\000" ITEM_19 .text "SOME STONES\000" ITEM_1A .text "A DRAWING ON THE WALL\000" ITEM_1B .text "A LOUDSPEAKER WITH DANCE MUSIC COMING OUT\000" ; the commands and their synonyms ; each token is 4 characters, followed by a 1 byte token code ; $ff indicates end of list ; first define the token codes #define TOK_DOWN $01 #define TOK_NORT $02 #define TOK_SOUT $03 #define TOK_EAST $04 #define TOK_WEST $05 #define TOK_GET $0d #define TOK_DROP $0e #define TOK_FIRE $0f #define TOK_BOOT $10 #define TOK_STAR $11 #define TOK_KEY $12 #define TOK_GUN $13 #define TOK_USED $14 #define TOK_BAR $15 #define TOK_COIN $16 #define TOK_MIRR $17 #define TOK_BROK $18 #define TOK_GLOV $19 #define TOK_ROPE $1a #define TOK_BOAR $1b #define TOK_STAL $1c #define TOK_ICE $1d #define TOK_WATE $1e #define TOK_MAN $1f #define TOK_DOOR $20 #define TOK_OPEN $21 #define TOK_WIND $22 #define TOK_SHIP $23 #define TOK_SECU $24 #define TOK_FLIN $25 #define TOK_STON $26 #define TOK_DRAW $27 #define TOK_HELP $28 #define TOK_INVE $29 #define TOK_QUIT $2a #define TOK_YES $2b #define TOK_NO $2c #define TOK_COMP $2d #define TOK_TYPE $2e #define TOK_TURN $2f #define TOK_HAND $30 #define TOK_KILL $31 #define TOK_DANC $32 #define TOK_REMO $33 #define TOK_BREA $34 #define TOK_BRIB $35 #define TOK_USE $36 #define TOK_PUSH $37 #define TOK_THRE $38 #define TOK_TWO $39 #define TOK_ONE $3a #define TOK_MEND $3b #define TOK_FOUR $3c #define TOK_LOOK $3d #define TOK_STAN $3e #define TOK_TREE $3f #define TOK_CUT $40 #define TOK_WEAR $41 #define TOK_CROS $42 #define TOK_JUMP $43 #define TOK_RAVI $44 #define TOK_UP $45 #define TOK_FUSE $46 #define TOK_REDE $47 #define TOK_MAIN $48 #define TOK_AUX $49 #define TOK_FIEL $4a ; now map the codes to their character representations TOKENS .text "DOWN" \ .byte TOK_DOWN .text "D " \ .byte TOK_DOWN .text "NORT" \ .byte TOK_NORT .text "N " \ .byte TOK_NORT .text "SOUT" \ .byte TOK_SOUT .text "S " \ .byte TOK_SOUT .text "EAST" \ .byte TOK_EAST .text "E " \ .byte TOK_EAST .text "WEST" \ .byte TOK_WEST .text "W " \ .byte TOK_WEST .text "GET " \ .byte TOK_GET .text "PICK" \ .byte TOK_GET .text "DROP" \ .byte TOK_DROP .text "PUT " \ .byte TOK_DROP .text "FIRE" \ .byte TOK_FIRE .text "SHOO" \ .byte TOK_FIRE .text "BOOT" \ .byte TOK_BOOT .text "STAR" \ .byte TOK_STAR .text "MOTO" \ .byte TOK_STAR .text "KEY " \ .byte TOK_KEY .text "LASE" \ .byte TOK_GUN .text "GUN " \ .byte TOK_GUN .text "USED" \ .byte TOK_USED .text "BAR " \ .byte TOK_BAR .text "BARS" \ .byte TOK_BAR .text "GOLD" \ .byte TOK_COIN .text "COIN" \ .byte TOK_COIN .text "MIRR" \ .byte TOK_MIRR .text "BROK" \ .byte TOK_BROK .text "GLOV" \ .byte TOK_GLOV .text "ROPE" \ .byte TOK_ROPE .text "FLOO" \ .byte TOK_BOAR .text "BOAR" \ .byte TOK_BOAR .text "PLAN" \ .byte TOK_BOAR .text "STAL" \ .byte TOK_STAL .text "BLOC" \ .byte TOK_ICE .text "ICE " \ .byte TOK_ICE .text "POOL" \ .byte TOK_WATE .text "WATE" \ .byte TOK_WATE .text "LAKE" \ .byte TOK_WATE .text "SLEE" \ .byte TOK_MAN .text "GREE" \ .byte TOK_MAN .text "MAN " \ .byte TOK_MAN .text "DOOR" \ .byte TOK_DOOR .text "OPEN" \ .byte TOK_OPEN .text "UNLO" \ .byte TOK_OPEN .text "WIND" \ .byte TOK_WIND .text "SMAL" \ .byte TOK_SHIP .text "SPAC" \ .byte TOK_SHIP .text "SHIP" \ .byte TOK_SHIP .text "SECU" \ .byte TOK_SECU .text "FLIN" \ .byte TOK_FLIN .text "STON" \ .byte TOK_STON .text "DRAW" \ .byte TOK_DRAW .text "HELP" \ .byte TOK_HELP .text "INVE" \ .byte TOK_INVE .text "I " \ .byte TOK_INVE .text "QUIT" \ .byte TOK_QUIT .text "STOP" \ .byte TOK_QUIT .text "ABOR" \ .byte TOK_QUIT .text "YES " \ .byte TOK_YES .text "Y " \ .byte TOK_YES .text "NO " \ .byte TOK_NO .text "COMP" \ .byte TOK_COMP .text "KEYB" \ .byte TOK_COMP .text "TYPE" \ .byte TOK_TYPE .text "TURN" \ .byte TOK_TURN .text "HAND" \ .byte TOK_HAND .text "KILL" \ .byte TOK_KILL .text "DANC" \ .byte TOK_DANC .text "WALT" \ .byte TOK_DANC .text "REMO" \ .byte TOK_REMO .text "KICK" \ .byte TOK_BREA .text "BREA" \ .byte TOK_BREA .text "HIT " \ .byte TOK_BREA .text "BANG" \ .byte TOK_BREA .text "BRIB" \ .byte TOK_BRIB .text "USE " \ .byte TOK_USE .text "WITH" \ .byte TOK_USE .text "PUSH" \ .byte TOK_PUSH .text "THRE" \ .byte TOK_THRE .text "3 " \ .byte TOK_THRE .text "TWO " \ .byte TOK_TWO .text "2 " \ .byte TOK_TWO .text "ONE " \ .byte TOK_ONE .text "1 " \ .byte TOK_ONE .text "MEND" \ .byte TOK_MEND .text "FIX " \ .byte TOK_MEND .text "REPA" \ .byte TOK_MEND .text "FOUR" \ .byte TOK_FOUR .text "4 " \ .byte TOK_FOUR .text "LOOK" \ .byte TOK_LOOK .text "STAN" \ .byte TOK_STAN .text "TREE" \ .byte TOK_TREE .text "CUT " \ .byte TOK_CUT .text "SAW " \ .byte TOK_CUT .text "WEAR" \ .byte TOK_WEAR .text "CROS" \ .byte TOK_CROS .text "JUMP" \ .byte TOK_JUMP .text "RAVI" \ .byte TOK_RAVI .text "UP " \ .byte TOK_UP .text "U " \ .byte TOK_UP .text "CLIM" \ .byte TOK_UP .text "FUSE" \ .byte TOK_FUSE .text "REDE" \ .byte TOK_REDE .text "R " \ .byte TOK_REDE .text "MAIN" \ .byte TOK_MAIN .text "AUX " \ .byte TOK_AUX .text "FIEL" \ .byte TOK_FIEL .text "SHIE" \ .byte TOK_FIEL .byte $ff A_MISC .byte $ff ; used for auto commands - no predicates required ; list of predicate entries ; first byte is the index of the predicate, see PRED_V ; second byte is stored in PARAM1 ; subsequent bytes of entry are terminated with a $ff A_GD_BOOT .byte COM_CHKHERE,$00 .byte $ff A_GD_STAR .byte COM_CHKHERE,$01 .byte $ff A_GD_KEY .byte COM_CHKHERE,$02 .byte $ff A_GD_GUN .byte COM_CHKHERE,$03 .byte $ff A_GD_BAR .byte COM_CHKHERE,$05 .byte $ff A_GD_COIN .byte COM_CHKHERE,$06 .byte $ff A_G_MIRR_1 .byte COM_CHKHERE,$07 .byte COM_CHKAWAY,$10 .byte $ff A_GD_MIRR_2 .byte COM_CHKHERE,$08 .byte $ff A_GD_GLOV .byte COM_CHKHERE,$09 .byte $ff A_GD_ROPE .byte COM_CHKHERE,$0a .byte $ff A_GD_BOAR_1 .byte COM_CHKHERE,$0b .byte $ff A_GD_BOAR_2 .byte COM_CHKHERE,$0c .byte $ff A_GD_STAL .byte COM_CHKHERE,$0d .byte $ff A_GD_ICE .byte COM_CHKHERE,$0e .byte $ff A_GD_FLIN .byte COM_CHKHERE,$18 .byte $ff A_GD_STON .byte COM_CHKHERE,$19 .byte $ff A_D_MIRR .byte COM_CHKHERE,$07 .byte $ff A_DRAW_STAL .byte COM_CHKROOM,$02 .byte $ff A_U_STON .byte COM_CHKROOM,$02 .byte COM_CHKHERE,$19 .byte $ff A_CUT_ROPE .byte COM_CHKROOM,$03 .byte $ff A_USE_FLIN .byte COM_CHKROOM,$03 .byte COM_CHKHERE,$18 .byte $ff A_C_RAVI_1 .byte COM_CHKROOM,$04 .byte $ff A_C_RAVI_2 .byte COM_CHKROOM,$06 .byte $ff A_C_RAVI_3 .byte COM_CHKROOM,$04 .byte COM_CHKHERE,$0b .byte $ff A_USE_BOAR .byte COM_CHKROOM,$06 .byte COM_CHKHERE,$0b .byte $ff A_DOWN .byte COM_CHKROOM,$0b .byte $ff A_U_ICE_2 .byte COM_CHKROOM,$0b .byte COM_CHKHELD,$0e .byte $ff A_G_MAN_1 .byte COM_CHKHERE,$10 .byte COM_CHKHERE,$09 .byte COM_CHKWORN,$09 .byte $ff A_G_MAN_2 .byte COM_CHKHERE,$10 .byte COM_CHKHERE,$09 .byte $ff A_G_MAN_3 .byte COM_CHKHERE,$10 .byte $ff A_KD_MAN_1 .byte COM_CHKHERE,$11 .byte $ff A_G_MIRR_3 .byte COM_CHKHERE,$07 .byte COM_CHKAWAY,$10 .byte $ff A_K_MAN_2 .byte COM_CHKHERE,$10 .byte $ff A_U_GUN_1 .byte COM_CHKHERE,$10 .byte COM_CHKHERE,$03 .byte $ff A_U_GUN_2 .byte COM_CHKHERE,$11 .byte COM_CHKHERE,$03 .byte COM_CHKHELD,$11 .byte $ff A_U_GUN_3 .byte COM_CHKHERE,$11 .byte COM_CHKHERE,$03 .byte $ff A_TYPE_HELP .byte COM_CHKROOM,$0e .byte $ff A_FIRE_GUN .byte COM_CHKROOM,$0f .byte $ff A_FIEL_1 .byte COM_CHKROOM,$0f .byte COM_CHKCLRF,GVAR_07 .byte COM_CHKHERE,$03 .byte $ff A_FIEL_2 .byte COM_CHKSETF,GVAR_07 .byte COM_CHKCLRF,GVAR_08 .byte COM_CHKROOM,$0f .byte COM_CHKHERE,$03 .byte $ff A_FIEL_3 .byte COM_CHKSETF,GVAR_08 .byte COM_CHKROOM,$0f .byte COM_CHKHERE,$03 .byte $ff A_DANC_1 .byte COM_CHKROOM,$0f .byte COM_CHKHELD,$07 .byte COM_CHKSETF,GVAR_08 .byte $ff A_DANC_2 .byte COM_CHKROOM,$0f .byte $ff A_O_DOOR_1 .byte COM_CHKROOM,$10 .byte $ff A_USE_KEY .byte COM_CHKROOM,$10 .byte COM_CHKHERE,$02 .byte $ff A_K_SECU .byte COM_CHKROOM,$10 .byte COM_CHKHERE,$03 .byte $ff A_LUP_BREA .byte COM_CHKROOM,$13 .byte $ff ; above list continues further on... #define I_SH_INVE $00 ; terminates bytecode processing #define I_SH_REMO $01 #define I_SH_GET $02 #define I_SH_DROP $03 #define I_SH_WEAR $04 #define I_SH_MSG $05 #define I_SH_REDE $06 ; terminates bytecode processing #define I_SH_AUTO $07 ; terminates bytecode processing #define I_SH_GOTO $08 #define I_SH_SETF $09 #define I_SH_CLRF $0a #define I_SH_SWAP $0b #define I_SH_DEAD $0c ; terminates bytecode processing #define I_SH_OK $0d ; terminates bytecode processing #define I_SH_QUIT $0e ; terminates bytecode processing #define I_SH_SETV $0f #define I_SH_CREA $10 #define I_SH_DEST $11 #define I_SH_ADSC $12 #define I_SH_SCOR $13 #define I_SH_FAIL1 $14 #define I_SH_TELL $15 #define I_SH_FAIL2 $16 #define I_SH_FAIL3 $17 #define I_SH_FAIL4 $18 ; bytecodes for the various commands a user can enter SGET_00 .byte I_SH_GET,$00,I_SH_OK SGET_01 .byte I_SH_GET,$01,I_SH_OK SGET_02 .byte I_SH_GET,$02,I_SH_OK SGET_03 .byte I_SH_GET,$03,I_SH_OK SGET_05 .byte I_SH_GET,$05,I_SH_OK SGET_06 .byte I_SH_GET,$06,I_SH_OK SGET_07 .byte I_SH_GET,$07,I_SH_OK SGET_08 .byte I_SH_GET,$08,I_SH_OK SGET_09 .byte I_SH_GET,$09,I_SH_OK SGET_0A .byte I_SH_GET,$0a,I_SH_OK SGET_0B .byte I_SH_GET,$0b,I_SH_OK SGET_0C .byte I_SH_GET,$0c,I_SH_OK SGET_0D .byte I_SH_GET,$0d,I_SH_OK SGET_0E .byte I_SH_GET,$0e,I_SH_SETV,GVAR_02,$09,I_SH_OK SGET_18 .byte I_SH_GET,$18,I_SH_OK SGET_19 .byte I_SH_GET,$19,I_SH_OK SINVENT .byte I_SH_INVE,$07 ; the $07 is ignored SQUIT .byte I_SH_QUIT SPUT_00 .byte I_SH_DROP,$00,I_SH_OK SPUT_01 .byte I_SH_DROP,$01,I_SH_OK SPUT_02 .byte I_SH_DROP,$02,I_SH_OK SPUT_03 .byte I_SH_DROP,$03,I_SH_OK SPUT_05 .byte I_SH_DROP,$05,I_SH_OK SPUT_06 .byte I_SH_DROP,$06,I_SH_OK SPUT_07 .byte I_SH_DROP,$07,I_SH_OK SPUT_08 .byte I_SH_DROP,$08,I_SH_OK SPUT_09 .byte I_SH_DROP,$09,I_SH_OK SPUT_0A .byte I_SH_DROP,$0a,I_SH_OK SPUT_0B .byte I_SH_DROP,$0b,I_SH_OK SPUT_0C .byte I_SH_DROP,$0c,I_SH_OK SPUT_0D .byte I_SH_DROP,$0d,I_SH_OK SPUT_0E .byte I_SH_DROP,$0e,I_SH_OK SPUT_18 .byte I_SH_DROP,$18,I_SH_OK SPUT_19 .byte I_SH_DROP,$19,I_SH_OK SLK_DRW .byte I_SH_MSG,$00,I_SH_AUTO SBRK_ST .byte I_SH_MSG,$01,I_SH_AUTO SUSE_SN .byte I_SH_CREA,$0d,I_SH_MSG,$02,I_SH_AUTO SCUT_RP .byte I_SH_MSG,$03,I_SH_AUTO SUSE_FL .byte I_SH_CREA,$0a,I_SH_MSG,$02,I_SH_AUTO SWR_00 .byte I_SH_WEAR,$00,I_SH_OK SRM_00 .byte I_SH_REMO,$00,I_SH_OK SCR_RV .byte I_SH_MSG,$03,I_SH_AUTO SUSE_BO .byte I_SH_GOTO,$06,I_SH_REDE SUS2_BO .byte I_SH_GOTO,$04,I_SH_DEST,$0b,I_SH_CREA,$0c,I_SH_REDE SJMP_RV .byte I_SH_MSG,$04,I_SH_DEAD SUSE_I2 .byte I_SH_GOTO,$0c,I_SH_DROP,$0e,I_SH_SWAP,$0e,I_SH_SETV,GVAR_02,$07,I_SH_REDE SGET_MN .byte I_SH_GET,$10,I_SH_SWAP,$10,I_SH_MSG,$05,I_SH_SETV,GVAR_05,$0a,I_SH_SETF,$06,I_SH_AUTO SGET_M2 .byte I_SH_GET,$10,I_SH_SWAP,$10,I_SH_OK SPUT_11 .byte I_SH_DROP,$11,I_SH_OK SGE2_07 .byte I_SH_GET,$07,I_SH_OK SGE2_08 .byte I_SH_GET,$08,I_SH_OK SPU2_07 .byte I_SH_DROP,$07,I_SH_OK SPU2_08 .byte I_SH_DROP,$08,I_SH_OK SDO_HOW .byte I_SH_MSG,$03,I_SH_AUTO SUSE_GN .byte I_SH_DEST,$10,I_SH_SWAP,$07,I_SH_MSG,$06,I_SH_MSG,$07,I_SH_AUTO SFIR_GN .byte I_SH_MSG,$26,I_SH_AUTO SUS2_GN .byte I_SH_DEST,$11,I_SH_MSG,$06,I_SH_AUTO SHLP_CM .byte I_SH_MSG,$08,I_SH_AUTO SFLD_1 .byte I_SH_SETF,$07,I_SH_MSG,$09,I_SH_AUTO SFLD_2 .byte I_SH_SETF,$08,I_SH_MSG,$09,I_SH_AUTO SFLD_3 .byte I_SH_MSG,$0a,I_SH_AUTO SDANCE .byte I_SH_GOTO,$10,I_SH_SETV,GVAR_02,$09,I_SH_REDE SDANCE2 .byte I_SH_MSG,$0b,I_SH_GOTO,$13,I_SH_REDE SUSE_KY .byte I_SH_GOTO,$12,I_SH_REDE SKIL_SG .byte I_SH_DEST,$17,I_SH_OK SLK_UP .byte I_SH_MSG,$0c,I_SH_AUTO SBRK_BA .byte I_SH_SWAP,$14,I_SH_CREA,$05,I_SH_REDE ; list of available verb/noun combinations ; along with their defining predicates and ; command lists ; terminated with a zero byte ; for each entry: ; 1st = verb token code ; 2nd = noun token code ; 3rd = address of predicate list entry ; 4th = address of system command list entry VN_DEFS .byte TOK_GET .byte TOK_BOOT .word A_GD_BOOT .word SGET_00 .byte TOK_GET .byte TOK_STAR .word A_GD_STAR .word SGET_01 .byte TOK_GET .byte TOK_KEY .word A_GD_KEY .word SGET_02 .byte TOK_GET .byte TOK_GUN .word A_GD_GUN .word SGET_03 .byte TOK_GET .byte TOK_BAR .word A_GD_BAR .word SGET_05 .byte TOK_GET .byte TOK_COIN .word A_GD_COIN .word SGET_06 .byte TOK_GET .byte TOK_MIRR .word A_G_MIRR_1 .word SGET_07 .byte TOK_GET .byte TOK_MIRR .word A_GD_MIRR_2 .word SGET_08 .byte TOK_GET .byte TOK_BROK .word A_GD_MIRR_2 .word SGET_08 .byte TOK_GET .byte TOK_GLOV .word A_GD_GLOV .word SGET_09 .byte TOK_GET .byte TOK_ROPE .word A_GD_ROPE .word SGET_0A .byte TOK_GET .byte TOK_BOAR .word A_GD_BOAR_1 .word SGET_0B .byte TOK_GET .byte TOK_BOAR .word A_GD_BOAR_2 .word SGET_0C .byte TOK_GET .byte TOK_BROK .word A_GD_BOAR_2 .word SGET_0C .byte TOK_GET .byte TOK_STAL .word A_GD_STAL .word SGET_0D .byte TOK_GET .byte TOK_ICE .word A_GD_ICE .word SGET_0E .byte TOK_GET .byte TOK_FLIN .word A_GD_FLIN .word SGET_18 .byte TOK_GET .byte TOK_STON .word A_GD_STON .word SGET_19 .byte TOK_INVE .byte $ff .word A_MISC .word SINVENT .byte TOK_QUIT .byte $ff .word A_MISC .word SQUIT .byte TOK_DROP .byte TOK_BOOT .word A_GD_BOOT .word SPUT_00 .byte TOK_DROP .byte TOK_STAR .word A_GD_STAR .word SPUT_01 .byte TOK_DROP .byte TOK_KEY .word A_GD_KEY .word SPUT_02 .byte TOK_DROP .byte TOK_GUN .word A_GD_GUN .word SPUT_03 .byte TOK_DROP .byte TOK_BAR .word A_GD_BAR .word SPUT_05 .byte TOK_DROP .byte TOK_COIN .word A_GD_COIN .word SPUT_06 .byte TOK_DROP .byte TOK_MIRR .word A_D_MIRR .word SPUT_07 .byte TOK_DROP .byte TOK_MIRR .word A_GD_MIRR_2 .word SPUT_08 .byte TOK_DROP .byte TOK_BROK .word A_GD_MIRR_2 .word SPUT_08 .byte TOK_DROP .byte TOK_GLOV .word A_GD_GLOV .word SPUT_09 .byte TOK_DROP .byte TOK_ROPE .word A_GD_ROPE .word SPUT_0A .byte TOK_DROP .byte TOK_BOAR .word A_GD_BOAR_1 .word SPUT_0B .byte TOK_DROP .byte TOK_BOAR .word A_GD_BOAR_2 .word SPUT_0C .byte TOK_FIRE .byte TOK_BROK .word A_GD_BOAR_2 .word SPUT_0C .byte TOK_DROP .byte TOK_STAL .word A_GD_STAL .word SPUT_0D .byte TOK_DROP .byte TOK_ICE .word A_GD_ICE .word SPUT_0E .byte TOK_DROP .byte TOK_FLIN .word A_GD_FLIN .word SPUT_18 .byte TOK_DROP .byte TOK_STON .word A_GD_STON .word SPUT_19 .byte TOK_LOOK .byte TOK_DRAW .word A_DRAW_STAL .word SLK_DRW .byte TOK_BREA .byte TOK_STAL .word A_DRAW_STAL .word SBRK_ST .byte TOK_USE .byte TOK_STON .word A_U_STON .word SUSE_SN .byte TOK_CUT .byte TOK_ROPE .word A_CUT_ROPE .word SCUT_RP .byte TOK_USE .byte TOK_FLIN .word A_USE_FLIN .word SUSE_FL .byte TOK_WEAR .byte TOK_BOOT .word A_MISC .word SWR_00 .byte TOK_REMO .byte TOK_BOOT .word A_MISC .word SRM_00 .byte TOK_CROS .byte TOK_RAVI .word A_C_RAVI_1 .word SCR_RV .byte TOK_CROS .byte TOK_RAVI .word A_C_RAVI_2 .word SCR_RV .byte TOK_USE .byte TOK_BOAR .word A_C_RAVI_3 .word SUSE_BO .byte TOK_USE .byte TOK_BOAR .word A_USE_BOAR .word SUS2_BO .byte TOK_JUMP .byte TOK_RAVI .word A_C_RAVI_3 .word SJMP_RV .byte TOK_JUMP .byte TOK_RAVI .word A_C_RAVI_2 .word SJMP_RV .byte TOK_DOWN .byte $ff .word A_DOWN .word SCR_RV .byte TOK_USE .byte TOK_ICE .word A_U_ICE_2 .word SUSE_I2 .byte TOK_GET .byte TOK_MAN .word A_G_MAN_1 .word SGET_M2 .byte TOK_GET .byte TOK_MAN .word A_G_MAN_2 .word SGET_MN .byte TOK_GET .byte TOK_MAN .word A_G_MAN_3 .word SGET_MN .byte TOK_DROP .byte TOK_MAN .word A_KD_MAN_1 .word SPUT_11 .byte TOK_GET .byte TOK_MIRR .word A_G_MIRR_3 .word SGE2_07 .byte TOK_GET .byte TOK_BROK .word A_GD_MIRR_2 .word SGE2_08 .byte TOK_DROP .byte TOK_MIRR .word A_D_MIRR .word SPU2_07 .byte TOK_DROP .byte TOK_BROK .word A_GD_MIRR_2 .word SPU2_08 .byte TOK_KILL .byte TOK_MAN .word A_K_MAN_2 .word SDO_HOW .byte TOK_KILL .byte TOK_MAN .word A_KD_MAN_1 .word SDO_HOW .byte TOK_USE .byte TOK_GUN .word A_U_GUN_1 .word SUSE_GN .byte TOK_USE .byte TOK_GUN .word A_U_GUN_2 .word SFIR_GN .byte TOK_USE .byte TOK_GUN .word A_U_GUN_3 .word SUS2_GN .byte TOK_TYPE .byte TOK_HELP .word A_TYPE_HELP .word SHLP_CM .byte TOK_FIRE .byte TOK_GUN .word A_FIRE_GUN .word SFIR_GN .byte TOK_FIEL .byte $ff .word A_FIEL_1 .word SFLD_1 .byte TOK_FIEL .byte $ff .word A_FIEL_2 .word SFLD_2 .byte TOK_FIEL .byte $ff .word A_FIEL_3 .word SFLD_3 .byte TOK_DANC .byte $ff .word A_DANC_1 .word SDANCE .byte TOK_DANC .byte $ff .word A_DANC_2 .word SDANCE2 .byte TOK_OPEN .byte TOK_DOOR .word A_O_DOOR_1 .word SDO_HOW .byte TOK_USE .byte TOK_KEY .word A_USE_KEY .word SUSE_KY .byte TOK_KILL .byte TOK_SECU .word A_K_SECU .word SKIL_SG .byte TOK_LOOK .byte TOK_UP .word A_LUP_BREA .word SLK_UP .byte TOK_BREA .byte TOK_BAR .word A_LUP_BREA .word SBRK_BA .byte TOK_UP .byte $ff .word A_UP .word SGO_UP .byte TOK_BRIB .byte TOK_SECU .word A_BRSEC .word SBRBSEC .byte TOK_USE .byte TOK_COIN .word A_U_COIN .word SUSE_CN .byte TOK_DOOR .byte $ff .word A_B_DOOR .word SBDOOR .byte TOK_LOOK .byte TOK_WATE .word A_L_WATE .word SLK_WAT .byte TOK_GET .byte TOK_COIN .word A_G_COIN .word SGET_CN .byte TOK_WATE .byte $ff .word A_WATE_1 .word SWATER1 .byte TOK_WATE .byte $ff .word A_WATE_2 .word SWATER2 .byte TOK_WATE .byte $ff .word A_L_WATE .word SL2_WAT .byte TOK_OPEN .byte TOK_DOOR .word A_O_DOOR_2 .word SODOOR2 .byte TOK_PUSH .byte TOK_THRE .word A_PUSH_THRE .word SPSH3A .byte TOK_PUSH .byte TOK_THRE .word A_PUSH_DIG .word SPSHDG .byte TOK_PUSH .byte TOK_TWO .word A_PUSH_TWO .word SPSH2A .byte TOK_PUSH .byte TOK_TWO .word A_PUSH_DIG .word SPSHDG .byte TOK_PUSH .byte TOK_ONE .word A_PUSH_ONE .word SPSH1A .byte TOK_PUSH .byte TOK_ONE .word A_PUSH_DIG .word SPSHDG .byte TOK_MEND .byte TOK_FUSE .word A_MEND_FUSE .word SMNDFUS .byte TOK_USE .byte TOK_BAR .word A_USE_BAR .word SUSE_BA .byte TOK_LOOK .byte $ff .word A_LOOK .word SLOOK1 .byte TOK_HELP .byte $ff .word A_HELP_1 .word SHELP1 .byte TOK_HELP .byte $ff .word A_HELP_2 .word SHELP2 .byte TOK_HELP .byte $ff .word A_HELP_3 .word SHELP3 .byte TOK_HELP .byte $ff .word A_HELP_4 .word SHELP4 .byte TOK_HELP .byte $ff .word A_HELP_5 .word SHELP4 .byte TOK_HELP .byte $ff .word A_HELP_6 .word SHELP4 .byte TOK_HELP .byte $ff .word A_HELP_7 .word SHELP4 .byte TOK_HELP .byte $ff .word A_HELP_8 .word SHELP1 .byte TOK_LOOK .byte TOK_UP .word A_LUP .word SLK_UP2 .byte TOK_WEST .byte $ff .word A_WEST .word SQUIET .byte TOK_NORT .byte $ff .word A_HELP_2 .word SQUIET .byte TOK_WEAR .byte TOK_GLOV .word A_MISC .word SWR_09 .byte TOK_REMO .byte TOK_GLOV .word A_MISC .word SRM_09 .byte TOK_REDE .byte $ff .word A_MISC .word SREDE .byte TOK_DOWN .byte $ff .word A_JUMP .word SJUMP_D .byte TOK_USE .byte TOK_ROPE .word A_USEROPE .word SUSE_RP .byte TOK_JUMP .byte $ff .word A_JUMP .word SJUMP .byte TOK_UP .byte TOK_ROPE .word A_UPROPE .word SUP_ROP .byte TOK_SHIP .byte $ff .word A_SHIP .word SSHIP .byte TOK_PUSH .byte TOK_MAIN .word A_P_MAUX .word SPSH_MN .byte TOK_PUSH .byte TOK_AUX .word A_P_MAUX .word SPSH_AU .byte TOK_PUSH .byte TOK_THRE .word A_P_32 .word SPSH_32 .byte TOK_PUSH .byte TOK_TWO .word A_P_32 .word SPSH_32 .byte TOK_PUSH .byte TOK_FOUR .word A_P_41 .word SPSH_4 .byte TOK_PUSH .byte TOK_ONE .word A_PSH_ONE_2 .word SPSH_1C .byte TOK_PUSH .byte TOK_ONE .word A_P_41 .word SPSH_1B .byte TOK_HELP .byte $ff .word A_MISC .word SHELP5 .byte TOK_LOOK .byte $ff .word A_MISC .word SLOOK2 .byte $00 ; list of predicate entries (continued from above) ; first byte is the index of the predicate, see PRED_V ; second byte is stored in PARAM1 ; subsequent bytes of entry are terminated with a $ff A_UP .byte COM_CHKROOM,$13 .byte COM_CHKHERE,$15 .byte $ff A_BRSEC .byte COM_CHKROOM,$13 .byte $ff A_U_COIN .byte COM_CHKROOM,$13 .byte COM_CHKHERE,$06 .byte $ff A_B_DOOR .byte COM_CHKROOM,$13 .byte COM_CHKHERE,$13 .byte $ff A_G_COIN: A_L_WATE .byte COM_CHKROOM,$04 .byte COM_CHKAWAY,$06 .byte $ff A_WATE_1 .byte COM_CHKROOM,$04 .byte COM_CHKAWAY,$06 .byte COM_CHKWORN,$00 .byte COM_CHKHERE,$00 .byte $ff A_WATE_2 .byte COM_CHKROOM,$04 .byte COM_CHKAWAY,$06 .byte COM_CHKHERE,$00 .byte $ff A_O_DOOR_2 .byte COM_CHKROOM,$0d .byte $ff A_PUSH_THRE .byte COM_CHKROOM,$12 .byte COM_CHKCLRF,GVAR_09 .byte COM_CHKCLRF,GVAR_0a .byte $ff A_PUSH_DIG .byte COM_CHKROOM,$12 .byte COM_CHKCLRF,GVAR_0a .byte $ff A_PUSH_TWO .byte COM_CHKROOM,$12 .byte COM_TSTGVAR,GVAR_09,$01 .byte COM_CHKCLRF,GVAR_0a .byte $ff A_PUSH_ONE .byte COM_CHKROOM,$12 .byte COM_TSTGVAR,GVAR_09,$02 .byte COM_CHKCLRF,GVAR_0a .byte $ff A_MEND_FUSE .byte COM_CHKROOM,$12 .byte COM_CHKSETF,GVAR_0a .byte $ff A_USE_BAR .byte COM_CHKROOM,$12 .byte COM_CHKHERE,$05 .byte COM_CHKSETF,GVAR_0a .byte $ff A_LOOK .byte COM_CHKROOM,$0b .byte $ff A_HELP_1 .byte COM_CHKROOM,$11 .byte $ff A_HELP_2 .byte COM_CHKROOM,$0f .byte $ff A_HELP_3 .byte COM_CHKROOM,$0e .byte $ff A_HELP_4 .byte COM_CHKROOM,$07 .byte $ff A_HELP_5 .byte COM_CHKROOM,$08 .byte $ff A_HELP_6 .byte COM_CHKROOM,$09 .byte $ff A_HELP_7 .byte COM_CHKROOM,$0a .byte $ff A_HELP_8 .byte COM_CHKROOM,$14 .byte COM_CHKSETF,GVAR_0c .byte $ff A_LUP .byte COM_CHKSETF,GVAR_0b .byte COM_CHKROOM,$0c .byte $ff A_WEST .byte COM_CHKROOM,$0d .byte $ff A_JUMP .byte COM_CHKROOM,$01 .byte $ff A_USEROPE: .byte COM_CHKROOM,$01 .byte COM_CHKHELD,$0a .byte $ff A_UPROPE .byte COM_CHKROOM,$0c .byte COM_CHKSETF,GVAR_0b .byte $ff A_SHIP .byte COM_CHKHERE,$16 .byte $ff A_P_MAUX .byte COM_CHKROOM,$14 .byte COM_CHKHERE,$01 .byte $ff A_P_32 .byte COM_CHKROOM,$14 .byte COM_CHKSETF,GVAR_0c .byte $ff A_P_41 .byte COM_CHKROOM,$14 .byte COM_CHKSETF,GVAR_0c .byte COM_TSTGVAR,GVAR_09,$03 .byte $ff A_PSH_ONE_2 .byte COM_CHKROOM,$14 .byte COM_CHKSETF,GVAR_0c .byte COM_CHKWORN,$00 .byte COM_TSTGVAR,GVAR_09,$03 .byte $ff ; bytecodes for the various commands a user can enter (continued from earlier list) SGO_UP .byte I_SH_GOTO,$0c,I_SH_SWAP,$14,I_SH_REDE SBRBSEC .byte I_SH_MSG,$0d,I_SH_AUTO SUSE_CN .byte I_SH_SWAP,$12,I_SH_DEST,$06,I_SH_REDE SBDOOR .byte I_SH_GOTO,$0c,I_SH_SWAP,$12,I_SH_REDE SLK_WAT .byte I_SH_MSG,$0e,I_SH_AUTO SGET_CN .byte I_SH_MSG,$01,I_SH_AUTO SWATER2 .byte I_SH_MSG,$0f,I_SH_AUTO SWATER1 .byte I_SH_CREA,$06,I_SH_GET,$06,I_SH_OK SL2_WAT .byte I_SH_MSG,$0f,I_SH_AUTO SODOOR2 .byte I_SH_GOTO,$0e,I_SH_REDE SPSH3A .byte I_SH_SETV,GVAR_09,$01,I_SH_OK SPSHDG .byte I_SH_MSG,$10,I_SH_CLRF,$09,I_SH_SETF,$0a,I_SH_AUTO SPSH2A .byte I_SH_SETV,GVAR_09,$02,I_SH_OK SPSH1A .byte I_SH_MSG,$11,I_SH_SETV,GVAR_09,$03,I_SH_AUTO SMNDFUS .byte I_SH_MSG,$0d,I_SH_AUTO SUSE_BA .byte I_SH_CLRF,$0a,I_SH_DEST,$05,I_SH_OK SLOOK1 .byte I_SH_MSG,$18,I_SH_AUTO SHELP1 .byte I_SH_MSG,$13,I_SH_AUTO SHELP2 .byte I_SH_MSG,$14,I_SH_AUTO SHELP3 .byte I_SH_MSG,$15,I_SH_AUTO SHELP4 .byte I_SH_MSG,$16,I_SH_AUTO SLK_UP2 .byte I_SH_MSG,$1a,I_SH_AUTO SQUIET .byte I_SH_GOTO,$0c,I_SH_SETV,GVAR_02,$07,I_SH_REDE SWR_09 .byte I_SH_WEAR,$09,I_SH_OK SRM_09 .byte I_SH_REMO,$09,I_SH_OK SREDE .byte I_SH_REDE SJUMP_D .byte I_SH_MSG,$03,I_SH_AUTO SUSE_RP .byte I_SH_SETF,$0b,I_SH_DROP,$0a,I_SH_GOTO,$0c,I_SH_REDE SJUMP .byte I_SH_MSG,$1b,I_SH_AUTO SUP_ROP .byte I_SH_GOTO,$01,I_SH_REDE SSHIP .byte I_SH_GOTO,$14,I_SH_REDE SPSH_MN .byte I_SH_MSG,$1c,I_SH_DEAD SPSH_AU .byte I_SH_SETF,$0c,I_SH_MSG,$1d,I_SH_AUTO SPSH_32 .byte I_SH_MSG,$19,I_SH_DEAD SPSH_4 .byte I_SH_MSG,$1e,I_SH_QUIT SPSH_1B .byte I_SH_MSG,$1f,I_SH_MSG,$20,I_SH_DEAD SPSH_1C .byte I_SH_MSG,$1f,I_SH_MSG,$21,I_SH_MSG,$1e,I_SH_QUIT SHELP5 .byte I_SH_MSG,$17,I_SH_AUTO SLOOK2 .byte I_SH_MSG,$12,I_SH_AUTO ; this vector list contains an address for every room DIR_V .word DIR_00 .word DIR_01 .word DIR_02 .word DIR_03 .word DIR_04 .word DIR_05 .word DIR_06 .word DIR_07 .word DIR_08 .word DIR_09 .word DIR_0A .word DIR_0B .word DIR_0C .word DIR_0D .word DIR_0E .word DIR_0F .word DIR_10 .word DIR_11 .word DIR_12 .word DIR_13 .word DIR_13 ; room $14 shares room $13's data - it's just an $ff anyway ; the directional information, one list for each room ; each list entry is of the form , ; each list is terminated with $ff DIR_00 .byte TOK_DOWN,$03 .byte TOK_EAST,$02 .byte TOK_WEST,$01 .byte $ff DIR_01 .byte TOK_EAST,$00 .byte $ff DIR_02 .byte TOK_NORT,$07 .byte TOK_WEST,$00 .byte $ff DIR_03 .byte TOK_SOUT,$04 .byte TOK_WEST,$00 .byte $ff DIR_04 .byte TOK_NORT,$03 .byte TOK_EAST,$05 .byte $ff DIR_05 .byte TOK_NORT,$04 .byte $ff DIR_06 .byte $ff DIR_07 .byte TOK_DOWN,$07 .byte TOK_NORT,$08 .byte TOK_SOUT,$07 .byte TOK_EAST,$07 .byte TOK_WEST,$07 .byte $ff DIR_08 .byte TOK_DOWN,$07 .byte TOK_NORT,$07 .byte TOK_SOUT,$09 .byte TOK_EAST,$07 .byte TOK_WEST,$07 .byte $ff DIR_09 .byte TOK_DOWN,$07 .byte TOK_NORT,$07 .byte TOK_SOUT,$07 .byte TOK_EAST,$0a .byte TOK_WEST,$07 .byte $ff DIR_0A .byte TOK_DOWN,$07 .byte TOK_NORT,$02 .byte TOK_SOUT,$07 .byte TOK_EAST,$07 .byte TOK_WEST,$0b .byte $ff DIR_0B .byte TOK_EAST,$07 .byte $ff DIR_0C .byte TOK_SOUT,$0f .byte TOK_EAST,$0d .byte TOK_WEST,$13 .byte $ff DIR_0D .byte $ff DIR_0E .byte TOK_WEST,$0d .byte $ff DIR_0F .byte TOK_EAST,$13 .byte TOK_WEST,$13 .byte $ff DIR_10 .byte TOK_NORT,$0f .byte TOK_SOUT,$13 .byte TOK_EAST,$11 .byte $ff DIR_11 .byte TOK_WEST,$10 .byte $ff DIR_12 .byte TOK_EAST,$10 .byte $ff DIR_13 .byte $ff MSG_V .word MSG_00 .word MSG_01 .word MSG_02 .word MSG_03 .word MSG_04 .word MSG_05 .word MSG_06 .word MSG_07 .word MSG_08 .word MSG_09 .word MSG_0A .word MSG_0B .word MSG_0C .word MSG_0D .word MSG_0E .word MSG_0F .word MSG_10 .word MSG_11 .word MSG_12 .word MSG_13 .word MSG_14 .word MSG_15 .word MSG_16 .word MSG_17 .word MSG_18 .word MSG_19 .word MSG_1A .word MSG_1B .word MSG_1C .word MSG_1D .word MSG_1E .word MSG_1F .word MSG_20 .word MSG_21 .word MSG_22 .word MSG_23 .word MSG_24 .word MSG_25 .word MSG_26 .word $0000 ; response messages MSG_00 .text "IT SHOWS A MAN CLIMBING DOWN A PIT USING A ROPE\r\000" MSG_01 .text "HOW? I CANT REACH\r\000" MSG_02 .text "IT HAS FALLEN TO THE FLOOR\r\000" MSG_03 .text "HOW?\r\000" MSG_04 .text "ITS TOO WIDE.I FELL AND BROKE MY NECK\r\000" MSG_05 .text "UGH! HE IS ALL SLIMY\r\000" MSG_06 .text "HE VANISHED IN A PUFF OF SMOKE\r\000" MSG_07 .text "YOU ALSO BROKE THE MIRROR\r\000" MSG_08 .text "COMPUTER SAYS: 2 WEST,2 SOUTH FOR SPACE FLIGHT\r\000" MSG_09 .text "IT HAS WEAKENED IT\r\000" MSG_0A .text "IT HAD NO EFFECT\r\000" MSG_0B .text "I FELL AND KNOCKED MYSELF OUT.\r\000" MSG_0C .text "THE BARS LOOK LOOSE\r\000" MSG_0D .text "WHAT WITH?\r\000" MSG_0E .text "I SEE A GOLD COIN\r\000" MSG_0F .text "BRRR.THE WATERS TOO COLD\r\000" MSG_10 .text "THE FUSE HAS JUST BLOWN\r\000" MSG_11 .text "THE LIFT HAS BEEN ACTIVATED\r\000" MSG_12 .text "I SEE NOTHING SPECIAL\r\000" MSG_13 .text "KEEP OFF THE MIDDLE MEN,ONE MAY BE SHOCKING!\r\000" MSG_14 .text "VANITY WALTZ!\r\000" MSG_15 .text "TRY HELP\r\000" MSG_16 .text "POINTS OF COMPASS\r\000" MSG_17 .text "TRY LOOKING AROUND\r\000" MSG_18 .text "I CAN SEE A STEEP SLOPE\r\000" MSG_19 .text "AN ALARM SOUNDS.THE SECURITY GUARD SHOT ME FOR TRESPASSING.\r\000" MSG_1A .text "I CAN SEE A ROPE HANGING DOWN THE CHIMNEY.\r\000" MSG_1B .text "I AM NOT THAT DAFT.IT IS TOO DEEP.\r\000" MSG_1C .text "THE SPACE SHIP BLEW UP AND KILLED ME.\r\000" MSG_1D .text "THE SHIP HAS FLOWN INTO THE LARGE LIFT AND IS HOVERING THERE.\r" .text "THERE ARE FOUR BUTTONS OUTSIDE THE WINDOW MARKED 1,2,3 AND 4\r\000" MSG_1E .text "THE LIFT HAS TAKEN ME UP TO A PLATEAU.\r" .text "CONGRATULATIONS, YOU HAVE MANAGED TO COMPLETE THIS ADVENTURE\r" .text "WITHOUT GETTING KILLED.\r\000" MSG_1F .text "THE LIFT HAS BECOME ELECTRIFIED\r\000" MSG_20 .text "I HAVE BEEN ELECTROCUTED\r\000" MSG_21 .text "IT IS A GOOD JOB I WAS WEARING RUBBER SOLED BOOTS.\r\000" MSG_22 .text "I WOULD KILL MYSELF IF I DID.\r\000" MSG_23 .text "I HAVE TURNED GREEN AND DROPPED DEAD.\r\000" MSG_24 .text "THE GREEN MAN AWOKE AND THROTTLED ME.\r\000" MSG_25 .text "THE GUARD WOKE AND SHOT ME.\r\000" MSG_26 .text "WHAT AT?\r\000" #define COM_CHKROOM $00 #define COM_CHKHERE $01 #define COM_CHKRAND $02 #define COM_CHKAWAY $03 #define COM_CHKWORN $04 #define COM_CHKSETF $05 #define COM_TSTGVAR $06 #define COM_CHKCLRF $07 #define COM_CHKHELD $08 ; list of predicate entries for Auto Commands ; first byte is the index of the predicate, see PRED_V ; second byte is stored in PARAM1 ; subsequent bytes of entry are terminated with a $ff ; check if we have turned green and died A_CHGRN .byte COM_TSTGVAR,GVAR_05,$01 ; if game variable $05 = 1 .byte COM_CHKSETF,GVAR_06 ; and game variable $06 is set .byte $ff ; check if the small green man is to throttle us (version 1) A_CHTHR .byte COM_TSTGVAR,GVAR_02,$01 ; if game variable $02 = 1 .byte COM_CHKHERE,$10 ; if is-present the small green man sleeping on the mirror .byte $ff ; check if the small green man is to throttle us (version 2) A_C2THR .byte COM_TSTGVAR,GVAR_02,$01 ; if game variable $02 = 1 .byte COM_CHKHERE,$11 ; if is-present the sleeping green man (moved off mirror) .byte $ff ; check if we're to be shot by the security guard A_SHOT .byte COM_TSTGVAR,GVAR_02,$01 ; if game variable $02 = 1 .byte COM_CHKHERE,$17 ; if is-present the sleeping security man .byte $ff ; check if ice has melted A_MELTD .byte COM_TSTGVAR,GVAR_02,$01 ; if game variable $02 = 1 .byte COM_CHKHERE,$0e ; if is-present the block of ice .byte $ff ; an empty action entry A_NULL .byte $ff ; bytecodes for the auto commands STURNGR .byte I_SH_MSG,$23,I_SH_DEAD STHROTL .byte I_SH_MSG,$24,I_SH_DEAD SSHOT .byte I_SH_MSG,$25,I_SH_DEAD SMELT_I .byte I_SH_SWAP,$0e ; fall through to following command STELLME .byte I_SH_TELL ; list of auto command combinations ; terminated with a zero byte ; these processed at the end of each parse cycle ; for each entry: ; 1st = verb token code (wildcard, matches any verb) ; 2nd = noun token code (wildcard, matches any noun) ; 3rd = address of predicate list entry ; 4th = unknown address AUT_LST .byte $ff .byte $ff .word A_CHGRN .word STURNGR .byte $ff .byte $ff .word A_CHTHR .word STHROTL .byte $ff .byte $ff .word A_C2THR .word STHROTL .byte $ff .byte $ff .word A_SHOT .word SSHOT .byte $ff .byte $ff .word A_MELTD .word SMELT_I .byte $ff .byte $ff .word A_NULL .word STELLME ; spurious data found in the original game GARBAGE .word $5200,$4c4f,$5220,$004f .end