A.N.A.L.O.G. ISSUE 27 / FEBRUARY 1985 / PAGE 73

Adventure at Vandenberg A.F.B.

16K Cassette or 24K Disk

by Tom Hudson

Adventure games have been with us for quite a while, but for the longest time, I was not too thrilled about playing them. Perhaps it was because the first adventure I ever played was poorly written, slow and contained numerous bugs.

I never wrote any adventure programs, either, since it’s obviously no fun solving a puzzle you created in the first place.

All this was true, until Brian Moriarty wrote the text adventure, Crash Dive, for issue 18. I had nothing to do one evening, so I sat down and played it. I enjoyed the puzzle-solving nature of Crash Dive so much, I went back and played Brian’s Adventure in the 5th Dimension, from issue 11 of ANALOG Computing. I was hooked.

The night I finished Crash Dive, I was reading an article on the space shuttle complex at Vandenberg Air Force Base. The idea for an adventure program hit me like a brick. Two weeks later. Adventure at Vandenberg A.F.B. was complete.

The scenario.

You’re a nosy reporter for the Daily Babble, a large metropolitan gossip tabloid, following a hot story. You’ve overheard several terrorists discussing a diabolical plot: the destruction of the Air Force’s newest space shuttle seconds before launch! The bomb has already been placed somewhere on the base, its timer set to detonate at 09:00.

Shocked, you rush to the local police station, to warn them to stop the launch. Unfortunately, they’ve read your stories about Bigfoot actually being a UFO alien, and they won’t believe the shuttle story, either. Now it’s up to you alone to save the shuttle and its five crew members.

Using all your reporter’s cunning, you manage to sneak past the gate guards. You duck into a small storage shed, knowing that the hardest part of your job is still ahead of you.

And you’ve only got one hour.

Typing it in.

Using Atari BASIC, type Listing 1 into your computer. It must be typed exactly as printed, or the adventure could be rendered unsolvable.

The other listings are the assembly language source code for the USR calls used by the program. You don’t have to type in these listings to play the game. They are included for the benefit of assembly language programmers.

After you’ve typed in the BASIC code, Unicheck should be used to check your typing. When you are certain the program is typed correctly, SAVE it to tape or disk before running it.

Gameplay.

When RUN, Adventure at Vandenberg will display the title screen, along with the message INITIALIZING. And, after a few seconds, you’ll see the prompt:

  Press  START  to begin new game.
Press  OPTION  to restore old game.
Now press the START key. The screen should look like this:
Your location:
Storage shed.


You can go: N

You see: Spray can
         Closed cabinet




Okay.
>>>>> What next? 

The screen is divided into five imaginary text areas or “windows.” The black response window at the bottom accepts commands from the user and displays descriptions of objects and the results of your actions. A blinking cursor in the response window indicates that the program is waiting for new commands.

The location window at the top of the screen gives you a brief description of your immediate surroundings. Underneath it is the compass window, which indicates all of the possible exits from that location. The objects window shows a list of all objects visible at the current location. The bottom of the blue screen area is the inventory window, which lists the items you are carrying.

Like most text adventures. Adventure at Vandenberg understands two-word sentences in the form of VERB-(space)-NOUN. Try typing the sentence TAKE CAN on the starting screen. The “spray can” will vanish from the objects window and reappear on your inventory window.

You can interact with objects on the screen just as you can in real life. Watch the response window as you type EXAMINE CAN. If you type DROP CAN, the can will return to the object window.

This adventure will understand several nouns and verbs. You’ll have to experiment to find out just which ones are valid. If you type something the computer can’t decipher, you’ll see the message, “I don’t understand — try again,” in the response window.

Single-character commands.

Adventure at Vandenberg also understands a limited number of single-commands. These commands control movement and other special functions.


MOVEMENT COMMANDS
N — North S — South E — East W — West
U — Up D — Down

OTHER COMMANDS
I — Inventory Q — Quit/Save Game

The movement commands let you head in any of the directions shown in the compass window. The I command displays the objects you are carrying in the inventory window. This window is also updated whenever you TAKE or DROP anything.

Saving and loading games.

Adventure at Vandenberg allows you to save your current game status to tape or disk. To use this feature, make sure your storage device is properly connected and is loaded with a blank tape or formatted disk. Type the command Q (quit) and answer Y to the Save Game? prompt. Then indicate whether you are saving to disk or tape.

To prevent the screen from going crazy during this process, it will go black for a few seconds while the game is saved. When the save is complete, the screen will return, so the game can be continued. I/O errors will result in a “beep,” and the Disk or Tape prompt will reappear.

To load a previously saved game, type Q/RETURN and then RETURN again, to exit. RUN the program again and press the OPTION key when initialization is complete. When the screen appears, the game will be restored to exactly the way it was when you last saved it.

Don’t try aborting the game with the BREAK key. This key is disabled to prevent you from crashing the machine-language routine that makes the cursor blink. Whenever you want to stop the program for any reason, press SYSTEM RESET

Helpful hints.

  1. Stay out of sight. As you can imagine, security at a military base like Vandenberg is extremely tight. Standing out in the open for too long will allow you to be spotted by security personnel.
  2. Draw a map. The base grounds and underground tunnel system at Vandenberg are confusing, with few landmarks. It’s a good idea to draw a map as you go along. Be careful, though — the base security guards are diligent!
  3. Examine everything. Objects may have important features that will not be evident unless you examine them closely. You should also keep track of the objects you discover — most of them are essential to your success.
  4. Save your game frequently. Use the Q command to save your current status after every important discovery…and before you try anything that might be dangerous. Otherwise, you’ll have to go back to the storage shed and start all over again.
  5. Try anything. Don’t be afraid to find out what you can or can’t do.
  6. Don’t give up. The space shuttle can be saved! If you’re stuck, ask for other people’s advice. A fresh outlook might uncover a solution you didn’t think of.
  7. Don’t call ANALOG Computing. We are not — absolutely, positively and definitely not — giving adventure hints over the telephone! If you run into an impasse, drop me a letter (include a pre-addressed, stamped envelope), and I’ll try to help you out. Whatever you do, verify your typing with Unicheck. One mistyped line is all it takes to make Adventure at Vandenberg A.F.B. truly impossible to win.

The credits.

I’d like to thank Brian Moriarty for his Adventure in the 5th Dimension. Rather than re-invent the wheel, 1 used the basic structure of his program for this one. This allowed me to write Adventure at Vandenberg in under two weeks of spare time.

BASIC listing.

10 CLR :GOTO 212
11 GRAPHICS C0:ST$=M$(401,405):Z=ASC(ST$(C5,C5)):OPEN #C2,C8,C0,"S:":GOSUB 15:POKE 703,C4
12 DL=PEEK(560)+PEEK(561)*256:FOR I=DL+31 TO DL+24 STEP −C1:POKE I,PEEK(I−C1):NEXT I:POKE DL+25,C16
13 Q=USR(1648,1680):POKE 54286,192:POKE C16,112:POKE 53774,112:GOTO 75
14 POKE C710,C0:POKE C709,C14:RETURN 
15 POKE C709,C14:POKE C710,148:RETURN 
16 FOR I=C0 TO C12 STEP C4:X1=USR(FAD,I):NEXT I
17 X1=USR(FAD,C15):RETURN 
18 SOUND C0,25,C10,C15:FOR I=C1 TO C4:NEXT I:SOUND C0,C0,C0,C0:RETURN 
19 SC=SC−C1:? "I don't understand.  Try again.":GOTO 50
20 ? "That is impossible.":RETURN 
21 ? "There isn't enough room here.":RETURN 
22 ? "It isn't here.":RETURN 
23 X=USR(LOOK,CL7,N,C8):RETURN 
24 Y=USR(LOOK,ST,N,C4):RETURN 
25 GOSUB 24:IF Y THEN RETURN 
26 POP :POP :? DH$:GOTO 50
27 Q=C15*(ASC(ST$(C5,C5))−65)+C1:RETURN 
28 POP :FLAG=C1:GOTO 80
29 ? #C2;"On base grounds.":RETURN 
30 ? #C2;"Payload prep. center.":RETURN 
31 ? #C2;"South of Headquarters.":RETURN 
32 ? #C2;"North of Security.":RETURN 
33 ? #C2;"Storage shed.":RETURN 
34 ? #C2;"Security office.":RETURN 
35 ? #C2;"Headquarters.":RETURN 
36 ? #C2;"Maze of tunnels.":RETURN 
37 ? #C2;"Materials distribution.":RETURN 
38 ? #C2;"Instrument bay.":RETURN 
39 ? #C2;"Escape bunker.":RETURN 
40 ? #C2;"Pipe trunk.":RETURN 
41 ? #C2;"Fuel pumping station.":RETURN 
42 CLOSE #C2:GRAPHICS C0:GOSUB 14:RETURN 
43 POP :GOSUB 42:POSITION C12,C10:? "Congratulations!":? "↓   The bomb has been deactivated!↓↓↓↓":END 
44 POP :GOSUB 42:POKE 752,C1:ON DR GOTO 45,46,48
45 ? "↓↓►►OUT OF TIME!"
46 ? "↓↓↓    The bomb explodes, killing you"
47 ? "    and destroying the shuttle!":GOTO 49
48 ? "↓↓↓  Before you can act, a guard appears":? "  and shoots you DEAD!"
49 ? "↓►      RE−INITIALIZING ":GOTO 217
50 POP :IF SFLG=C1 THEN SFLG=C0:GOTO 55
51 SC=SC+C1:IF  NOT USR(LOOK,ADR("ABDEFGHK"),CL,C8) THEN SC=C0
52 IF CL$(1,1)<>"K" THEN 55
53 IF M$(397,397)="*" THEN 55
54 M$(392,392)="*":M$(397,397)="*":? "A guard leaves Security and":? "walks out of sight."
55 ? ">>>>> What next";:GOSUB 18:TRAP 50:INPUT K$:TRAP OFF:L=LEN(K$):IF  NOT L THEN 19
56 IF L=C1 AND (K$="I" OR K$="Q") THEN 58
57 IF L=C1 AND USR(LOOK,CL7,ADR("A"),C8) AND M$(392,392)="?" THEN M$(394,394)="*"
58 IF SC>4 THEN 211
59 IF L=C1 THEN V$=K$:GOTO 71
60 Q=USR(LOOK,ADR(K$),ADR(" "),L):IF Q<C3 THEN 19
61 V$=K$(C1,Q−C1):N$=K$(Q+C1,L):IF LEN(N$)<C3 THEN 19
62 Z=USR(1536,ADR(VERB$)−C4,V):IF  NOT Z THEN 19
63 Q=USR(1536,ADR(NOUN$)−C4,N):IF  NOT Q AND Z<>76 THEN 19
64 GOSUB 210:N$=CHR$(Q):IF N$="\" OR N$="]" THEN ? "Refer to it by color.":GOTO 50
65 GOSUB 69:IF  NOT USR(LOOK,CL7,ADR("A"),C8) OR M$(392,392)="*" THEN 68
66 IF (Z=65 OR Z=70) AND Q=65 THEN 68
67 M$(394,394)="*"
68 Z=Z−64:ON Z GOSUB 95,124,139,150,163,169,174,177,181,185,189,198:GOTO 50
69 SS=SS+C15:IF SS=C60 THEN SS=C0:MM=MM+C1:IF MM=C60 THEN DR=C1:GOTO 44
70 RETURN 
71 Q=USR(LOOK,ADR(C$),V,C8):IF  NOT Q THEN 19
72 IF Q>C6 THEN Q=Q−C6:ON Q GOTO 85,89
73 Q=Q+C1:Z=ASC(CL$(Q,Q)):IF Z=63 THEN ? "You can't go that way.":GOTO 50
74 GOSUB 69
75 GOSUB 210:GOSUB 16:GOSUB 27:M$(Q,Q+C14)=CL$:ST$(C5,C5)=CHR$(Z):GOSUB 27:CL$=M$(Q,Q+C14)
76 ? OK$:POSITION C2,C0:? #C2;"Your location:";:POSITION C2,C1
77 Z=Z−64:ON Z GOSUB 29,29,30,31,29,29,29,29,33,34,32,35,36,36,36,37,36,36,36,36,36,36,38,39,40,41
78 POSITION C2,C4:? #C2;"You can go: ";:FOR I=C1 TO C6:IF CL$(I+C1,I+C1)<>"?" THEN ? #C2;C$(I,I);" ";
79 NEXT I
80 X1=USR(FAD,C6):X1=USR(FAD,C10):POSITION C2,C6:? #C2;"You see: ";:X=C6
81 FOR I=C1 TO C8:Q=ASC(CL$(I+C7,I+C7))−64:IF Q<>−C1 THEN RESTORE 247+Q:READ K$:POSITION 11,X:? #C2;K$:X=X+C1
82 NEXT I:IF X=C6 THEN POSITION 11,X:? #C2;"Nothing interesting"
83 IF FLAG=C1 THEN FLAG=C0:GOTO 85
84 GOTO 50
85 ? OK$:GOSUB 17:POSITION C2,C15:? #C2;"You have: ";
86 X=C15:FOR I=C1 TO C4:Q=ASC(ST$(I,I))−64:IF Q<>−C1 THEN RESTORE 247+Q:READ K$:POSITION C12,X:? #C2;K$:X=X+C1
87 NEXT I:IF X=C15 THEN POSITION 12,X:? #C2;"Nothing"
88 GOTO 50
89 ? "Type Y to save, RETURN to quit";:INPUT K$:IF K$<>"Y" THEN CLOSE #C2:GRAPHICS C0:END 
90 CLOSE #C1:POKE 559,34:? "Position Save: Disk or Tape";:INPUT N$:IF N$<>"D" AND N$<>"T" THEN 50
91 TRAP 90:K$="D1:SAVE.DAT":IF N$="T" THEN K$="C:"
92 POKE 559,C0:POKE 54272,C0:OPEN #C1,C8,C0,K$:M$(401,405)=ST$:GOSUB 27:M$(Q,Q+C14)=CL$
93 FOR I=325 TO C1 STEP −81:? #C1;M$(I,I+80):NEXT I:? #C1;NOUN$:? #C1;CE$:? #C1;CI$:? #1;MM:? #1;SS:? #1;SC
94 CLOSE #C1:POKE 559,34:POKE 54286,192:GOTO 55
95 Q=Q−64:GOSUB 23:IF  NOT X AND N$="A" THEN N$="B":Q=C2:GOSUB 23:IF  NOT X THEN 22
96 IF  NOT X THEN GOSUB 24:IF  NOT Y THEN 22
97 ON Q GOTO 101,103,104,106,99,99,107,99,99,109,110,99,99,112,114,117,117,115,100,99,116,117
98 ON Q-22 GOTO 122,111,118,121
99 ? "Seems ordinary.":RETURN 
100 ? "Looks dangerous.":RETURN 
101 IF M$(392,392)="?" THEN ? "Has a red light!":RETURN 
102 ? "It's deactivated.":RETURN 
103 ? "Paint covers lens.":RETURN 
104 IF M$(391,391)<>"0" THEN ? "Not much paint left.":RETURN 
105 ? "It's empty!":RETURN 
106 ? "Says: Cameras off.  Back after launch.":RETURN 
107 ? "Door is securely locked.":RETURN 
108 ? "It's unlocked.":RETURN 
109 ? "Says: ";CE$(C6,C10):RETURN 
110 ? "Says: ";CE$(C1,C5):RETURN 
111 ? "Says:   WARNING − LIQUID OXYGEN":? "►►EXTREME COLD":RETURN 
112 IF USR(LOOK,CL7,ADR("["),C8) THEN ? "It's bolted shut.":RETURN 
113 GOTO 99
114 ? "It's filled with a freezing mist.":RETURN 
115 ? "It's screwed shut.":RETURN 
116 ? "It's securely nailed shut.":RETURN 
117 ? "It's ticking!":RETURN 
118 ? "Time is 08:";:IF MM<C10 THEN ? "0";
119 ? MM;":";:IF SS<C10 THEN ? "0";
120 ? SS:RETURN 
121 ? "Hopelessly wrecked!":RETURN 
122 IF M$(393,393)<>"?" THEN 105
123 ? "There's a clock inside!":RETURN 
124 GOSUB 24:IF Y THEN ? "You already have that.":RETURN 
125 Z=USR(LOOK,ST,ADR("?"),C4):IF  NOT Z THEN ? "You can't carry any more.":RETURN 
126 GOSUB 23:IF  NOT X THEN 22
127 IF USR(LOOK,ADR("ABGHINORSTVWX["),N,C14) THEN 20
128 IF N$="P" THEN DR=C2:GOTO 44
129 IF N$="Y" THEN M$(393,393)="*"
130 IF N$="U" THEN ? "You can't lift it.":RETURN 
131 IF N$<>"Q" THEN 137
132 IF NOUN$(64,64)<>"T" THEN 44
133 HO=C0:FOR HT=C1 TO C4:IF ST$(HT,HT)="?" THEN HO=HO+C1:IF HO<C4 THEN HO(HO)=HT
134 NEXT HT:IF HO<C3 THEN ? "You'll have to drop something.":RETURN 
135 ST$(HO(C1),HO(C1))="Q":ST$(HO(C2),HO(C2))="R":ST$(HO(C3),HO(C3))="T":GOSUB 138:N$="R":GOSUB 23
136 GOSUB 138:N$="T":GOSUB 23:GOSUB 138:GOTO 28
137 GOSUB 138:ST$(Z,Z)=N$:GOTO 28
138 CL$(X+C7,X+C7)="?":RETURN 
139 GOSUB 25:IF N$="Q" AND CL$(C1,C1)="U" AND USR(LOOK,CL7,ADR("O"),C8) THEN 43
140 IF USR(LOOK,ADR("QRT"),N,C3) THEN 145
141 X=USR(LOOK,CL7,ADR("?"),C8):IF  NOT X THEN 21
142 ST$(Y,Y)="?":IF CL$(C1,C1)="U" AND USR(LOOK,CL7,ADR("O"),C8) THEN ? "It falls into the hatch!":GOTO 28
143 IF N$="Y" THEN N$="Z":NOUN$(80,80)="Z":? "It smashes into a thousand pieces!"
144 CL$(X+C7,X+C7)=N$:GOTO 28
145 GOSUB 148:IF HO<C3 THEN 21
146 CL$(HO(C1),HO(C1))="Q":CL$(HO(C2),HO(C2))="R":CL$(HO(C3),HO(C3))="T":N$="Q":GOSUB 24:ST$(Y,Y)="?"
147 N$="R":GOSUB 24:ST$(Y,Y)="?":N$="T":GOSUB 24:ST$(Y,Y)="?":GOTO 28
148 HO=C0:FOR HT=C8 TO C15:IF CL$(HT,HT)="?" THEN HO=HO+C1:IF HO<C4 THEN HO(HO)=HT
149 NEXT HT:RETURN 
150 GOSUB 23:IF  NOT X THEN 161
151 IF N$="U" THEN 116
152 IF N$="G" THEN ? "The door won't budge.":RETURN 
153 IF N$="P" OR N$="Q" THEN 44
154 IF N$="R" AND USR(LOOK,ST,ADR("L"),C4) THEN DR=C2:GOTO 44
155 IF N$="R" THEN 115
156 IF N$="N" AND M$(396,396)="*" THEN CL$(X+C7,X+C7)="O":NOUN$(52,52)="O":GOTO 28
157 IF N$="N" THEN ? "Bolts won't let you.":RETURN 
158 IF N$<>"V" THEN 161
159 N$="?":XS=X:GOSUB 23:IF  NOT X THEN 21
160 CL$(XS+C7,XS+C7)="W":NOUN$(72,72)="W":CL$(X+C7,X+C7)="Y":GOSUB 123:GOTO 28
161 GOSUB 25:IF N$="P" OR N$="Q" THEN 44
162 GOTO 20
163 IF N$<>"G" THEN 20
164 GOSUB 23:IF  NOT X THEN 22
165 IF CL$(C1,C1)<>"K" THEN ? "There's no keyhole!":RETURN 
166 Y=USR(LOOK,ST,ADR("F"),C4):IF  NOT Y THEN ? "You don't have a key.":RETURN 
167 CL$(C3,C3)="J":CL$(C8,C8)="?":GOSUB 168:POP :GOTO 78
168 ? "The door slides open and disappears!":RETURN 
169 Y=USR(LOOK,ST,ADR("C"),C4):IF  NOT Y THEN ? "You don't have any paint.":RETURN 
170 PAINT=VAL(M$(391,391)):IF  NOT PAINT THEN ? "Can is empty!":RETURN 
171 GOSUB 23:IF  NOT X THEN GOSUB 25
172 PAINT=PAINT−C1:M$(391,391)=STR$(PAINT):IF N$="A" THEN CL$(X+C7,X+C7)="B":GOTO 28
173 ? "What a nice color!":RETURN 
174 IF  NOT USR(LOOK,ADR("DJKXYZ"),N,6) THEN 20
175 GOSUB 23:GOSUB 24:IF  NOT X AND  NOT Y THEN 22
176 GOTO 95
177 IF N$<>"R" THEN 20
178 GOSUB 23:GOSUB 24:IF  NOT X AND  NOT Y THEN 22
179 IF  NOT USR(LOOK,ST,ADR("L"),C4) THEN ? "You have nothing to unscrew it with.":RETURN 
180 DR=C2:GOTO 44
181 IF N$<>"[" THEN 20
182 GOSUB 23:IF  NOT X THEN 22
183 IF  NOT USR(LOOK,ST,ADR("M"),C4) THEN ? "Bolts are too tight.":RETURN 
184 CL$(C10,C10)="?":M$(396,396)="*":POP :? OK$:GOTO 80
185 GOSUB 23:IF  NOT X THEN 22
186 IF N$<>"U" THEN 188
187 CL$(C4,C4)="Y":? "You found something!":POP :GOTO 78
188 ? "Why bother?":RETURN 
189 GOSUB 23:IF  NOT X THEN 22
190 CC=398:CS=C0:IF CL$(1,1)="Z" THEN CC=399:CS=C5
191 CODE=VAL(M$(CC,CC)):IF CODE=C6 THEN 188
192 IF N$<>CI$(CS+CODE,CS+CODE) THEN 208
193 CODE=CODE+C1:M$(CC,CC)=STR$(CODE):IF CODE<C6 THEN ? "The button beeps softly.":RETURN 
194 GOSUB 168:IF CL$(C1,C1)="R" THEN CL$(C3,C3)="V":CL$(C9,C9)="?":M$(317,317)="R":M$(323,323)="?":GOTO 197
195 IF CL$(C1,C1)="V" THEN CL$(C2,C2)="R":CL$(C8,C8)="?":M$(258,258)="V":M$(264,264)="?":GOTO 197
196 CL$(C6,C6)="W":CL$(C8,C8)="?"
197 POP :GOTO 78
198 GOSUB 23:IF  NOT X THEN GOSUB 25
199 IF  NOT USR(LOOK,ST,ADR("E"),C4) THEN ? "You have nothing to cut it with.":RETURN 
200 IF N$="Q" OR N$="T" THEN ? "It's already cut.":RETURN 
201 IF N$="D" OR N$="J" OR N$="K" THEN 188
202 IF N$="P" THEN 205
203 IF N$<>"S" THEN 20
204 NOUN$(64,64)="T":CL$(X+C7,X+C7)="T":GOTO 207
205 GOSUB 148:IF HO<C2 THEN 21
206 CL$(X+C7,X+C7)="Q":NOUN$(56,56)="Q":CL$(HO(C1),HO(C1))="R":CL$(HO(C2),HO(C2))="S"
207 ? OK$:POP :GOTO 80
208 ? "You hear a siren!"
209 M$(394,394)="*":RETURN 
210 IF M$(394,394)="?" THEN RETURN 
211 DR=C3:GOTO 44
212 READ OFF,FLAG,C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C12,C14,C15,C16,C60,C709,C710
213 GOSUB 14:POKE 752,C1:? "↰↓↓↓↓↓►►Tom Hudson's":? "↓    ADVENTURE at Vandenberg A.F.B. "
214 ? "↓►  (C)1984 ANALOG Computing":POSITION C12,C16:? "   INITIALIZING  "
215 DIM M$(406),CL$(15),K$(24),N$(4),V$(4),VERB$(68),NOUN$(92),C$(9),ST$(5)
216 DIM HO(3),OK$(5),DH$(20),CE$(10),CI$(10):OK$="Okay.":DH$="You don't have that."
217 FOR X=C1 TO C10:CE$(X)="W":CI$(X)="H":IF RND(C0)<0.5 THEN CE$(X)="G":CI$(X)="I"
218 NEXT X:IF CI$(C1,C5)=CI$(C6,C10) THEN 217
219 NOUN$="CAMACANCNOTDSCIEKEYFDOOGWHIHGRAIBLUJPINKSCRLWREMHATNBAGPPANRWIRSCRAUCABVSIGXCLOYBOL[BUT\PAP]"
220 VERB$="EXAALOOATAKBGETBDROCLEACOPEDUNLESPRFPAIFREAGUNSHREMIMOVJPUSKPREKCUTL"
221 C$="NSEWUDIQ":LOOK=1605:CL=ADR(CL$):CL7=CL+C7:V=ADR(V$):N=ADR(N$):ST=ADR(ST$):FAD=1712:MM=C0:SS=C0
222 RESTORE 235:M$(C1)="?":M$(406)="?":M$(C2)=M$:FOR I=C1 TO 376 STEP C15:READ CL$:M$(I,I+LEN(CL$))=CL$:NEXT I
223 M$(391,405)="2??????11?????I":CL$=M$(121):FOR I=1536 TO 1753:READ Q:POKE I,Q:NEXT I
224 POSITION C4,C16:? " Press  START  to begin new game.":? "↓  Press  OPTIO to restore old game."
225 IF PEEK(53279)=C6 THEN 11
226 IF PEEK(53279)=C3 THEN 228
227 GOTO 225
228 CLOSE #C1:POKE 559,34:POSITION C8,20:? "Load from Disk or Tape";:INPUT N$:IF N$<>"D" AND N$<>"T" THEN 228
229 POKE 559,C0:POKE 54272,C0:TRAP 228:K$="D1:SAVE.DAT":IF N$="T" THEN K$="C:"
230 OPEN #C1,C4,C0,K$:TRAP 32767:FOR I=325 TO C1 STEP −81
231 INPUT #C1,M$:M$(I,I+80)=M$:NEXT I:M$(406,406)="":INPUT #C1,NOUN$:INPUT #C1,CE$:INPUT #C1,CI$
232 INPUT #C1,MM:INPUT #C1,SS:INPUT #C1,SC:CLOSE #C1:ST$=M$(401,405):GOSUB 27:CL$=M$(Q,Q+C14)
233 SFLG=C1:POKE 559,34:GOTO 11
234 DATA 40000,0,0,1,2,3,4,5,6,7,8,9,10,12,14,15,16,60,709,710
235 DATA ADFBA,BB?BA?N,C?H???UF,DLAEK,EEIFD,FAKFE,GHKHG,HCGHG,IE?????CV,JK????VD,KF?GD??G,L?D????AJ
236 DATA MNMNQ,NMRNMB?A,OSSTO,P?????SAE,QMRQQ??AL,RN?SQ??AGHI,SORTOP,TTSUO,UU??TC?NX[,V?X??J?GHI
237 DATA W?????ZAPK,XV?????AU,Y??ZX??M,Z???Y??GHI
238 DATA 104,104,133,206,104,133,205,104,133,204,104,133,203,169,0,133,213,162,25,202,240,42,24,165,205
239 DATA 105,4,133,205,165,206,105,0,133,206,24,160,0,177,203,209,205,208,231,200,177,203,209,205,208
240 DATA 224,200,177,203,209,205,208,217,200,177,205,133,212,96,169,0,133,212,96
241 DATA 104,104,133,206,104,133,205,104,133,204,104,133,203,169,0,168,133,213,177,203,133,207,104,104,168
242 DATA 136,48,10,165,207,209,205,208,247,200,132,212,96,169,0,133,212,96
243 DATA 104,104,141,1,2,104,141,0,2,173,48,2,133,203,173,49,2,133,204,160,24,169,130,145,203
244 DATA 169,0,141,243,2,96,0,72,138,72,169,0,162,10,141,10,212,141,24,208,142,23,208,230,208
245 DATA 165,208,41,16,74,74,74,141,1,212,104,170,104,64
246 DATA 104,104,104,170,165,88,133,203,165,89,133,204,216,24,202,48,15,165,203,105,40,133,203,165,204
247 DATA 105,0,133,204,24,144,238,160,159,169,0,145,203,136,208,251,96
248 DATA Surveillance camera
249 DATA Painted camera
250 DATA Spray can
251 DATA Note
252 DATA Scissors
253 DATA Keys
254 DATA Door
255 DATA White button
256 DATA Gray button
257 DATA Blue paper
258 DATA Pink paper
259 DATA Screwdriver
260 DATA Wrench
261 DATA Hatch
262 DATA Open hatch
263 DATA Bag
264 DATA Bag with gaping hole
265 DATA Metal panel
266 DATA Wire
267 DATA Severed Wire
268 DATA Wooden crate
269 DATA Closed cabinet
270 DATA Open cabinet
271 DATA Sign
272 DATA Clock
273 DATA Broken clock
274 DATA Bolts

Assembly listing.

0100 ; NOUN/VERB DECODER
0105 ;
0110 ; Syntax: N=USR(ML,TL-4,NL)
0115 ; ML=addr of this routine
0120 ; TL=addr of lookup table
0125 ; NL=addr of current noun/verb
0130 ;
0135 ; Program equates
0140 ;
0145 NOUN=$CB  ; noun addr pointer
0150 TABLE=$CD ; table addr pointer
0155 NRET=$D4  ; BASIC return addr
0160 ;
0165      PLA           ; # arguments
0170      PLA           ; msb of table addr
0175      STA TABLE+1
0180      PLA           ; lsb
0185      STA TABLE
0190      PLA           ; msb of noun addr
0195      STA NOUN+1
0200      PLA           ; lsb
0205      STA NOUN
0210      LDA #$00
0215      STA NRET+1    ; zero msb
0220      LDX #$19      ; noun/verb count
0225 NEXT DEX
0230      BEQ NOPE      ; illegal entry
0235      CLC
0240      LDA TABLE     ; +5 to pointer
0245      ADC #$04
0250      STA TABLE
0255      LDA TABLE+1
0260      ADC #$00
0265      STA TABLE+1
0270      CLC
0275      LDY #$00      ; init index
0280      LDA (NOUN),Y  ; get 1st char
0285      CMP (TABLE),Y ; equal?
0290      BNE NEXT      ; no; next noun
0295      INY           ; in-line for speed
0300      LDA (NOUN),Y  ; try 2nd char
0305      CMP (TABLE),Y
0310      BNE NEXT
0315      INY
0320      LDA (NOUN),Y  ; try 3rd char
0325      CMP (TABLE),Y
0330      BNE NEXT
0355      INY           ; must be legal
0360      LDA (TABLE),Y ; get iden #
0365      STA NRET      ; give to BASIC
0370      RTS           ; and return
0375 NOPE LDA #$00      ; 0=illegal entry
0380      STA NRET      ; give to BASIC
0385      RTS           ; and return
0100 ; CHARACTER SEARCH ROUTINE
0105 ;
0110 ; Syntax: X=USR(ML,SVT,V,R)
0115 ; ML=addr of this routine
0120 ; SVT=addr of $ to be searched
0125 ; V=addr of search character
0130 ; R=# bytes to search
0135 ;
0140 ; Program equates
0145 ;
0150 CADR=$CB  ; char addr pointer
0155 TABLE=$CD ; verb table pointer
0160 CHAR=$CF  ; character buffer
0165 BRET=$D4  ; BASIC return addr
0170 ;
0175      PLA             ; # arguments
0180      PLA             ; msb of table addr
0185      STA TABLE+1
0190      PLA             ; lsb
0195      STA TABLE
0200      PLA             ; msb of verb addr
0205      STA CADR+1
0210      PLA             ; lsb
0215      STA CADR
0220      LDA #$00
0225      TAY
0230      STA BRET+1      ; zero msb
0235      LDA (CADR),Y    ; get the char
0240      STA CHAR        ; save for later
0245      PLA             ; msb of range (ignore)
0250      PLA             ; lsb
0255      TAY             ; use as the index
0260 NEXT DEY
0265      BMI NOPE        ; must be illegal
0270      LDA CHAR        ; get char
0275      CMP (TABLE),Y   ; match?
0280      BNE NEXT        ; no; try another
0285      INY             ; yes; give position
0290      STY BRET        ; to BASIC
0295      RTS             ; and return
0300 NOPE LDA #$00        ; 0=char not found
0305      STA BRET        ; give to BASIC
0310      RTS             ; and return
0100 ; DLI/BLINK ROUTINE
0105 ;
0110 ; Syntax: USR(DLI,DLI+X)
0115 ; DLI=addr of this routine
0120 ; X=offset to DLI handler
0125 ;
0130 ; Program equates
0135 ;
0140 COLPF1=$D017
0145 COLPF2=$D018
0150 WSYNC=$D40A
0155 SDLSTL=$0230
0160 VDSLST=$0200
0165 CHACTL=$D401
0170 CHACT=$02F3
0175 BUFFER=$CB
0180 BLINCT=$D0
0185 ;
0190 ; First set up the DLI
0195 ;
0200      PLA            ; # arguments
0205      PLA            ; msb of DLI addr
0210      STA VDSLST+1
0215      PLA            ; lsb
0220      STA VDSLST
0225      LDA SDLSTL     ; find start of
0230      STA BUFFER     ; display list
0235      LDA SDLSTL+1
0240      STA BUFFER+1
0245      LDY #$18       ; mode line 20
0250      LDA #$82       ; DL instruction
0255      STA (BUFFER),Y
0260      LDA #$00       ; turn off
0265      STA CHACT      ; inverse video
0270      RTS
0275      BRK            ; mark end of init
0280 ;
0285 ; This is the actual DLI handler
0290 ;
0295      PHA            ; save accumulator
0300      TXA
0305      PHA            ; save X
0310      LDA #$00       ; black bkgrnd
0315      LDX #$0A       ; white chars
0320      STA WSYNC
0325      STA COLPF2
0330      STX COLPF1
0335      INC BLINCT     ; Blink cursor
0340      LDA BLINCT
0345      AND #$10
0350      LSR A
0355      LSR A
0360      LSR A
0365      STA CHACTL
0370      PLA            ; restore A and X
0375      TAX
0380      PLA
0385      RTI            ; back to BASIC
0100 ; SCREEN ERASE SUBROUTINE
0105 ; CLEARS IN 4-LINE BLOCKS
0110 ;
0115 ; Syntax: X=USR(ML,ST)
0120 ; ML=addr of this routine
0125 ; ST=starting line number
0130 ;
0135 ; PROGRAM EQUATES
0140 ;
0145 BUFFER=$CB ; scr address buffer
0150 SAVMSC=$58 ; screentop pointer
0155 ;
0160       PLA            ; # arguments
0165       PLA            ; msb of line#; ignore
0170       PLA            ; lsb
0175       TAX            ; save in x-register
0180       LDA SAVMSC     ; get screen
0185       STA BUFFER     ; address
0190       LDA SAVMSC+1
0195       STA BUFFER+1
0200       CLD            ; clear decimal mode
0205       CLC
0210 ADD40 DEX            ; find window addr
0215       BMI CLEAR
0220       LDA BUFFER     ; add 40
0225       ADC #$28
0230       STA BUFFER
0235       LDA BUFFER+1
0240       ADC #$00
0245       STA BUFFER+1
0250       CLC
0255       BCC ADD40
0260 CLEAR LDY #$9F       ; clear 4 lines
0265       LDA #$00       ; space char
0270 SPACE STA (BUFFER),Y
0275       DEY
0280       BNE SPACE
0285       RTS