Smuggler’s Cove is a text adventure set in 1753, in the caves and tunnels under the north Cornish coast where Blackbeard is said to have hidden his treasure. You type a verb in capitals and a noun in lower case (TAKE torch, OPEN door), move with N, E, S, W, U and D, and the top of the screen shows a line drawing of each location. INVENTORY, LOOK and SCORE work at any time, and SAVE and LOAD keep a game position on tape. Dark tunnels need a light, and some deaths can be undone if the omens favour your birthdate.
The 1983 Quicksilva tape’s title line reads “By John Keneally”; the copy on Bob Swoger’s disk had changed it to “BY J.R. KENEALLY”. The zip also holds the command sheet Joan Kealy wrote for it, as text.
Program Analysis
The BASIC is a thin shell around about 30 KB of machine code at 32768, which holds the parser, the room and object database, the messages and the pictures. BASIC passes requests through two addresses: it POKEs a function number into PR (35407) and calls USR U0 (35390), so 43 describes the room, 36 followed by 35 or 41 lists the objects carried or present, and 40 fetches a message. USR u1 (32768) parses the command in a$ and USR u2 (33304) handles the turn. Line 2500 picks the location picture from the string P$ and draws it with USR 62892.
Notable Techniques
- Long messages are built into the blank string
Z$by the machine code and word-wrapped by BASIC at lines 500–535. - Game positions are saved as the 12,600-byte block
CODE 33400,12600, the part of the code that holds the game state. - Line 9999 is the original tape-mastering routine that saves the BASIC, the title screen and the code.
Potential Issues
- The machine code finds the BASIC variables by their position: the program must keep the 1983 layout exactly, with
a$saved as the first variable. The copy on the Larken disk had extra lines and saved variables, and reset the computer the first time you moved; this download restores the original layout.
This copy came from a Larken disk. The BASIC was put back to the 1983 release’s lines (the disk version’s renamed files, extra help line and disk prefixes would not run), one game-state byte that had been saved mid-game was reset to the release value, and the Quicksilva logo loader from the disk runs first. Tested in ZEsarUX on a stock TS2068: moving, taking objects and scoring work.
Source Code
5 CLEAR 32767: BORDER 3: LOAD "p"SCREEN$ : PRINT #0;AT 1,0; INK 9;" * QUICKSILVA 1983 ": PRINT #0;AT 0,0; INK 9;" By John Keneally ": LOAD "p"CODE
10 INK 0: PAPER 4: FLASH 0: BRIGHT 0: OVER 0: INVERSE 0: POKE 23658,8: BORDER 3: POKE 23609,40: CLS : PRINT AT 0,0; PAPER 5; INK 0;,,,,,,,,,,,,,,,,;: PAPER 8: INK 8
15 LET U0=35390: LET PR=35407: POKE PR+1,0: PRINT AT 8,0;: POKE PR,46: LET J=USR U0: LET P$="0123745677879:8;<998===>>?@282A"
16 POKE PR,44: LET J=USR U0
20 LET j=0: LET k=0: LET l=0: LET m=0: LET n=0: LET p=0: LET q=0: LET r=0
30 LET u1=32768: LET u2=33304
40 LET ai=35528: LET aj=35529: LET at=36815
50 LET a$="": LET am=35550
60 GO TO 800
100 LET r=0: PRINT "_______________________________": GO SUB 2500: INPUT "What now? ";a$: PRINT AT 8,0;: POKE PR,48: LET M=USR U0: IF a$="INVENTORY" OR a$="INV" THEN GO TO 200
101 IF A$="SAVE" THEN CLS : PRINT AT 12,0; FLASH 1;"GAME SAVE": SAVE "dat"CODE 33400,12600: GO TO 100
102 IF a$="LOOK" THEN GO SUB 3500: PRINT : LET r=1: GO TO 250
103 IF A$="LOAD" THEN GO SUB 750: GO TO 800
104 IF A$="SCORE" THEN POKE PR,48: LET M=USR U0: PRINT AT 8,0;"YOUR SCORE IS: ";PEEK 35562: GO TO 100
105 IF a$="" THEN GO TO 100
106 LET a$=a$+" ": LET a$=a$: POKE PR+2,PEEK 23666: LET j=USR u1
107 IF j=1 THEN LET j=0: LET r=1: POKE ai,0: PRINT a$;" what?"
108 IF PEEK ai>0 AND PEEK ai<3 THEN LET r=1
110 IF j<=0 OR J>100 THEN GO TO 150
120 IF j=38 THEN GO TO 820
130 IF j=39 THEN PAUSE 100: CLS : PRINT AT 10,11;"WELL DONE"'"Few have lived to tell the tale.You have survived, but will you brave the dangers once again to find a better route?": LET j=INT (PEEK (at)/2): LET j=j-2*INT (j/2): PRINT "Without the treasure, you have nothing to prove to the world your prowess and skill" AND (1-j): PRINT : GO TO 3000
135 IF j=41 THEN GO TO 250
140 POKE pr,j: LET j=USR u0
150 IF PEEK ai=0 AND PEEK aj=0 THEN GO TO 195
170 LET l=0
175 LET K=PEEK (AJ+L): IF K<>0 THEN LET L=L+1: GO TO 175
180 FOR L=L-1 TO -1 STEP -1: LET K=PEEK (AJ+L): POKE AJ+L,0: IF K<>0 THEN GO SUB 500: PRINT
185 NEXT L
190 GO TO 110
195 IF r=0 THEN LET r=1: LET j=USR u2: GO TO 110
196 GO TO 100
200 POKE pr,36: LET m=USR u0: LET r=1: PRINT "You are carrying:-"
210 POKE pr,35: LET m=USR u0: IF m<>0 THEN PRINT "A ";: GO SUB 600: GO TO 210
220 PRINT "_______________________________": GO TO 150
250 LET j=0: POKE pr,36: LET M=USR U0: PRINT "Objects here are:-"
260 POKE pr,41: LET m=USR u0: IF m<>0 THEN PRINT "A ";: GO SUB 600: GO TO 260
270 PRINT "_______________________________": GO TO 150
500 LET P=0: POKE am,k: POKE pr,40: LET m=USR u0
510 LET Z$=" ": POKE PR+2,226: POKE PR,45: LET N=USR U0: FOR P=31 TO 256 STEP 31: IF Z$(P TO P+2)=" " THEN LET N=P: LET P=256: NEXT P: GO TO 530
515 FOR Q=P TO P-30 STEP -1: IF Z$(Q)=" " THEN PRINT Z$(P-30 TO Q-1): LET P=Q: LET Q=0
520 NEXT Q
525 NEXT P: RETURN
530 FOR Q=N TO N-30 STEP -1: IF Z$(Q)<>" " THEN LET P=Q: LET Q=0
535 NEXT Q: PRINT Z$(N-30 TO P);: RETURN
600 LET P=0: LET k=PEEK ai: IF k=0 THEN GO SUB 510: PRINT : RETURN
610 POKE ai,0: LET l=PEEK 36335: LET Z=PEEK 36336:: GO SUB 500: PRINT " ";: POKE 36335,L: POKE 36336,Z: GO SUB 510: PRINT : RETURN
750 CLS : PRINT AT 12,0; FLASH 1;"START TAPE": LOAD "dat"CODE : CLS : RETURN
800 LET J=PEEK (34223+PEEK 35559): POKE AI,J: LET J=0: LET R=1: GO TO 150
820 PRINT ''"Just a second, if the omens are propitious, you might be saved": INPUT FLASH 1;"What is your birthdate? ";a$: PAUSE 200: IF RND<.37 THEN CLS : PRINT AT 12,0;"Sorry, your stars are in the wrong house."'' FLASH 1;"REST IN PEACE": GO TO 3000
830 CLS : PRINT AT 12,0;"Yep. Your in luck. Stand by....": FOR j=1 TO 40: BORDER RND*7: PAUSE 9: NEXT j: POKE 36383,0: BORDER 3: CLS : PRINT PAPER 5;AT 0,0;,,,,,,,,,,,,,,,,: PRINT AT 8,0;:: GO TO 800
2500 LET j=PEEK 35559: LET M=CODE P$(j): POKE 62887,M-48
2510 IF J=27 AND PEEK (at-3)=3 THEN POKE 62887,18
2520 IF (J=3 OR J=28) AND PEEK (36703)=169 THEN POKE PR,47: LET m=USR U0: LET m=USR 62892: POKE 62887,19: LET m=USR 62892: RETURN
2530 IF J=6 AND PEEK 36541=166 THEN POKE 62887,20
2540 IF J=16 AND PEEK 36797=43 THEN POKE PR,47: LET m=USR U0: LET m=USR 62892: POKE 62887,21: LET j=USR 62892: RETURN
2550 POKE PR,47: LET m=USR U0: LET m=USR 62892: RETURN
3000 PRINT '"YOUR SCORE IS: ";PEEK 35562: INPUT "WANT TO TRY AGAIN? (Y/N) ";A$: IF A$="Y" THEN POKE 36383,0: POKE PR,47: LET J=USR U0: PRINT AT 8,0;"";: GO TO 10
3010 NEW : STOP
3500 IF PEEK 35559=11 THEN RETURN
3510 POKE pr,43: LET n=USR u0: GO SUB 510: RETURN
9998 CLEAR 32767: LOAD "p"CODE : LOAD "p"SCREEN$
9999 INPUT "LOAD A BLANK, PRESS ENTER";a$: SAVE "smugl" LINE 1: SAVE "p"SCREEN$ : SAVE "p"CODE 32768,30300: GO TO 9999Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.


