--- title: "Voyage of Peril" id: 51397 type: "computer_media" slug: "voyage-of-peril" url: "http://localhost/computer_media/voyage-of-peril/" markdown_url: "http://localhost/computer_media/voyage-of-peril.md" published_at: "2023-07-30T07:32:51+00:00" modified_at: "2026-04-04T20:18:08+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2023/07/SCRtoImage.png" excerpt: "Sail the HMS Seawitch across six treasure-filled maps, managing crew, food, and hull damage in this split-load sailing adventure with custom high-resolution sprites." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "TS 1000" slug: "ts1000" taxonomy: "post_tag" url: "http://localhost/tag/ts1000/" model: - name: "Timex/Sinclair 1000" slug: "ts-1000" taxonomy: "model" url: "http://localhost/model/ts-1000/" indiv: - name: "Gregory Harder" slug: "gregory-harder" taxonomy: "indiv" url: "http://localhost/indiv/gregory-harder/" genre: - name: "Game" slug: "game" taxonomy: "genre" url: "http://localhost/type/game/" media_type: "Cassette" programmers: - name: "Gregory Harder" slug: "gregory-harder" taxonomy: "indiv" url: "http://localhost/indiv/gregory-harder/" download_url: "https://archive.org/download/timex-sinclair-software-archive/Voyage%20of%20Peril%20%281987%29%28Harder%2C%20Gregory%29%28US%29%28TS1000%29%28Program%29.zip" images: - url: "http://localhost/wp-content/uploads/2023/07/SCRtoImage.png" media_type_tags: "Game" --- # Voyage of Peril Voyage of Peril, adapted by Greg Harder from a [ZX81 program in a British magazine](https://archive.org/details/zxcomputing-magazine-1985-08/page/n47/mode/2up), is a sailing adventure game in which the player captains the HMS Seawitch across six map regions, collecting treasure while managing crew, food, hull integrity, and gold. The program is split into two parts: Part I (this listing) handles UDG character definition, screen data storage, and introductory text, while Part II contains the main game loop. Custom UDG characters are loaded via LPRINT commands to an external high-resolution board (the “SHREB” sprite system) at address 19400, and the machine’s memory above 32K is used to store the six map grids without raising RAMTOP. Constants such as N0–N9, I0–I9, T0, T1, T4, T6, T8, HU, and P5 are precomputed at initialization (lines 9500–9530) to reduce token overhead throughout the program. Map transitions are handled by POKEing load/save addresses directly into machine code routines, then calling USR to swap map data in and out of high RAM. *** ## Program Analysis ### Program Structure The listing is divided into two separately saved parts. Part I (lines 10–9996 in the first segment) defines UDG characters, stores screen data, and presents the introductory text and instructions. It ends by loading Part II (`LOAD "VOYAGE2"`). Part II (lines 10–9995 in the second segment) contains the full game engine. The REM blocks at lines 0, 1, 2, and 3 in each part hold compiled machine code or packed data used by the SHREB sprite subsystem; their content is not valid BASIC but binary data embedded in REM storage. ### Initialization and Constant Table Lines 9500–9530 pre-calculate a large set of named constants using minimal BASIC tokens, a well-known size-saving technique. Integer and fractional values are derived from `PI`, `NOT PI`, and `CODE` of printable characters rather than being stored as numeric literals. Key constants include: - `N0` through `N9` — integers 0–9 derived from `NOT PI`, `PI/PI`, sums, `INT PI`, and `VAL "n"` - `I0` through `I9` — values 10–19, where `I0=CODE "\~~"` (10), `I2=CODE "£"` (12), etc., exploiting character codes - `T0=CODE "="` (61→used as 20 in context? Actually 61; used as the `POKE` multiplier for repairs), `T1=CODE "+"` (43), `HU=I0*I0` (100, the ship’s hull/crew capacity) - `T4=VAL "4500"`, `T6=VAL "6E3"`, `T8=VAL "8980"` — frequently-called subroutine/jump targets stored as variables to save repeated literal token space - `P5=VAL ".5"` — used in boundary checks throughout the movement loop ### SHREB Sprite System and USR Calls All graphical output — clearing the screen, printing sprites, moving the ship — is routed through an external high-resolution board whose machine code entry point is stored in `HR` (19400). The idiom `IF USR HR THEN ...` is used pervasively: the USR call either performs a hardware action and returns a non-zero value (allowing the THEN branch to execute a normal BASIC display statement as a fallback), or it handles rendering entirely. LPRINT is used as the communication channel to the sprite board, sending command codes such as `SD`, `SM`, `SS`, `SE`, and `SP` followed by parameters. Line 610 defines the ship sprite: `IF USR HR THEN LPRINT SD;1,"16,1C,3C,7C,FE,10,D7,7E"`. Lines 1173–1176 animate the ship on the legend screen using a sine-wave path computed in BASIC and sent as sprite move commands. ### UDG Character Definitions Part I defines a full set of UDG characters for the game’s map symbols and alphanumerics. Each definition is sent via `IF USR HR THEN LPRINT U;"X","HH HH HH HH HH HH HH HH"`, where `U` is a command byte and the quoted string contains eight hex byte pairs. Characters defined include: - Digits 0–9 and symbols `?`, `(` — custom numerals for the hi-res display - Full uppercase alphabet A–Z - Map hazard symbols: rocks (▞), reefs (=), icebergs ([~~]), sandbanks (*), Queen’s Castle ([*]) - Treasure chests (codes A–Z, lines 570–600) — a FOR loop at line 570 iterates through character codes 166–191, POKEing each into the UDG table address computed from system variables at 16425/16426, then sending a single chest bitmap - Three vegetation types for the three climate zones: palms (tropics), pines (temperate), mountains (northlands), each loaded or reloaded when the map zone changes (line 6200–6220) ### Map System and High-Memory Storage Six maps are stored above address 32768 without raising RAMTOP, as noted at line 9980. Map data addresses are assigned at lines 7250, 7500, 7750, 8000, 8250, and 8500 in steps of 375 bytes (375 = 25 columns × 15 rows for the `D$` array). The load/save mechanism at lines 6110–6180 works by POKEing the target address’s low and high bytes directly into machine code at fixed locations (20507/20508), then calling `USR VAL "20495"` or `USR VAL "20519"` to invoke the copy routines. This avoids any BASIC array copy overhead. The map display array `D$` is declared as `DIM D$(CODE "?", CODE ";")` = `DIM D$(63,59)` — though only 15×25 of those cells are actively used for the visible map grid. ### Main Game Loop The sailing loop (lines 100–600) runs each day’s turn: 1. Roll wind force (`WF`) and direction (`WD`) randomly 2. Accept course (`C`) and sail area (`A`) from the player 3. Check if course is within 45° of the wind — if so, branch to the “in irons” penalty (line 1200) 4. Compute distance sailed: `D=0.00001*A*WF^1.5*H` 5. Step along the course in a FOR loop, updating `X`, `Y` and moving the ship sprite 6. At each step, check `D$(L,K)` for a hazard and branch accordingly The hazard dispatch at line 430 is a single computed GOTO expression summing boolean products: `GOTO VAL "2E3"*(CODE D$(L,K)>=CODE "[A]")+VAL "2250"*(D$(L,K)="▞")+...` This evaluates each condition independently and sums the target line numbers, which works correctly only because exactly one condition can be true at a time. ### Event Subroutines | Line | Event | Effect | | --- | --- | --- | | 1000 | Becalmed | No movement; crew eats rations | | 1200 | In Irons | Sailed too close to wind; crew eats rations | | 1400 | Storm/Hurricane | Hull damage proportional to `(WF-N2)*I0` | | 2000 | Treasure | Gold added; chest replaced with land tile; `Q()` array updated | | 2250/2500/2750/3000 | Rocks/Reefs/Sandbanks/Icebergs | Random hull damage using `INT(H*(N1-RND/N2))-N2` formula | | 3250 | Pirates | All gold stolen; crew and hull randomly reduced | | 3500 | Home Port | Game end; hi-score check against `HG` | | 3750 | Land | Random branch: savages (R<0.2), maidens (R<0.4), or trade menu | | 5000/5250/5500/5750 | Lose conditions | Mutiny (no food), marooned (few crew on land), adrift (few crew at sea), shipwrecked (H5▟▝TAN PRINT # RETURN,C▌LN [*]RNDINT / LET TAN 6-RNDLN #? FASTLN LN + LPRINT TAN LN [H]RND PRINT LN [4]RND7LN [H]RND# LET #TAN 7# RETURN#C▀ RETURN;""6-RNDTAN A ##▞▌ACS 9ACS =( IF ,,▘ 4,,TAN 7LN [T]RNDLN [4]RNDLN ,,INKEY$ ##ACS ZACS ZACS Z##STR$ LN STR$ RND LET J NEW▛W#TAN Y3[)]K▌LN [*]RNDINT (Y[Z][(]SQR LN [*]RNDINT 25 6AT ZA4##<▘ COPY*Q GOSUB [K]TAN NEXT Y▞# ( CLEARLEN LIST W4 CLEAR▞"" CLEARACS ##C▝▞[K])4 5 4##INKEY$ ▌ASN #INKEY$ ;# GOSUB ###▛ INPUT E£RND ###) RUN ▙;Y2 GOSUB #Y PRINT ▘▛▝ CLEARACS ##CODE [P]▝LN [>]▝LN 4▝<>5GINKEY$ #[8]▝ CLEARACS #▚/▖ CLEARACS #LEN E£RND▘9 GOSUB PIF FOR 5 █;6#INKEY$ FOR GOSUB [K]LN F?<>5GINKEY$ TAN 7LN [T]RNDLN [4]RND##LN ▞INKEY$ VAL 7LN [H]RNDAT LN STR$ RND#TAN 2 COPY/▝2 STR$ 7LN [T]RNDLN ,,INKEY$ SGN GOSUB ##ZLN LET RND##?( CLEARACS .*PI▌4▝▞▒▛( CLEAR#TAN Y COPY/▘[J]MVAL Z CLEARACS #[:]7LN [T]RNDLN ,,INKEY$ # RETURN,4"7 GOSUB ##ZLN [T]RNDLN ,,INKEY$ ## GOSUB ##ZVAL #[)]-▘K▖ GOSUB #- COPY4▝- FAST##MSQR Z LET [(]2▘K▖ GOSUB #2 COPY4▝2 ##MINT Z#[W]S▞##- /▝2 GOSUB #SGN Z6PEEK Z#[B]3#A 6STR$ ZAT VAL Y[Z][(] PRINT UVAL Z# LET CLEARACS ##4▌LN SGN INKEY$ /▀LN ##UPEEK Z#▞ USTR$ Z##,,#MSTR$ Z GOSUB #SGN ZUUSR Z# GOSUB PIS▒#MSTR$ Z GOSUB #INT ZAT #▙##▄#5CHR$ ZOUUSR Z[Y]4[N] GOSUB ##ZTAN Y COPY/▘[J]MVAL Z7LN [T]RNDLN [4]RNDVAL 7LN [H]RND#I 6INT Z#6SGN ZAT Y▘ PRINT VAL VAL EINT Z GOSUB #SGN Z▞▌VAL ACS EACS .( IF [R] GOSUB #6INT Z GOSUB #SGN ZAT ACS GACS 1( IF ;6SGN Z GOSUB #INT ZAT #ACS <[~~]##ACS +[£]#Y[Z][(]S,, PRINT UVAL Z# LET LN SGN INKEY$ AT LET W RETURNASN S[O]TAN Y▘MINT ZLN COS RNDCOS LN [H]RNDMINT ZLN TAN RNDCOS 7LN [T]RNDLN [4]RND[S]S▀#INKEY$ #LN (INKEY$ #INKEY$ LN (INKEY$ #PI GOSUB #SQR Z[)]W PRINT 7LN [T]RND[S]K▀#INKEY$ # GOSUB #ABS Z[(]W4▘XSGN # GOSUB #USR ZUPEEK Z#USGN Z#[B]LN INPUT RND6CHR$ ZUABS Z#USGN Z#[B]LN INPUT RND6**Z£TAN LN +#4*UINT Z#5 4▘ /#J#7"#[L]4 RUN +4 INPUT TAN USTR$ ZECHR$ Z GOSUB #**Z6 AND Z GOSUB #>=Z PRINT FAST GOSUB # LPRINT C#UPEEK ZLN INKEY$ STR$ VAL #3ZACS <( IF AT ACS .*( CLS#SGN 7 FAST[B] GOSUB # LPRINT C▌#J#/ NEXT UABS ZLN INKEY$ Y,,[(]#VAL ,*ZACS 1( IF AT ACS +3( CLS>▘4 E>=Z,,6>=Z FOR E AND Z,,6 AND Z LET X4[A]5INT ZP4[?]TAN UUSR Z RETURN▒4▖,J/NOT UPEEK ZLN INKEY$ VAL ,3ZACS +( IF AT ACS 1*( CLS#UABS ZJ NEW▛C$#,VAL ?ACS 0( CLSAT ACS ▖( UNPLOT #/[E]E(RND#[T]COS RETURN█4▌LN [*]RNDINT ▘VAL LN PAUSE ,,AT FOR / GOTO PRINT SCROLL FAST:RND▟#LN ##7 FAST▞▌[J]#( CLEARSGN LPRINT LET TAN LN SCROLLRND#?( CLEARLN ##K▀Y▟>LN COS RNDTAB SQR #TAN LN SCROLLRND FASTAT LN 4+ FASTLN ##AT FAST##LN PLOT ;LN [~~]+ LPRINT / STEP LN SCROLLRND#▞ / SLOW###Y[Z][(]STR$ VAL PRINT LN SGN INKEY$ LET AT SGN TAN 2 COPY/▝2 STR$ LN C#SGN USTR$ Z#UPEEK Z5SGN Z PRINT FASTLN [D]#+C▞WLN [J]#/ RUN UUSR Z# LPRINT LET F FASTLN [D]#+C▞£LN [J]#/ RUN USTR$ Z# LPRINT UABS Z PRINT FASTLN [D]#+C▞XLN [J]#/ RUN UUSR Z# LPRINT LET 7LN [D]#+COS $LN [J]#/ SAVE LN 7?2"" CLEARACS ##C▝2[K]5 4[J]PEEK CLSLN #?ABS ▐▒<= CLS*K CLS-4▞▒#<= CLS3K CLS# NEW█PEEK CLSACS )( PAUSE 7+4 FOR <= CLS3K CLSLN ##/SGN 76-RNDLN #?LN [B]:##▘▘COS CLEARACS V#""( RAND $4 PLOT .#[N]4 INPUT TAN 7# RETURN#4,,LN OR #LN RUN #/L7# RETURN,C> RETURN;CG RETURN#C# RETURNAT C# RETURNTAB C#/# GOSUB #AT Z# NEW LIST LEN ( RETURNRNDCODE [O]#ATN [J]#/STR$ #LEN ▒#[J]# GOSUB #AT ZTAN ▞ COPY7# RETURN#COS RETURN,4▖Y▖/" RETURN;4VAL ▖# RETURN▀ASN SQR #M""Z/ STOP GOSUB #AT Z/SQR 7LN [T]RND## RETURN[T]ABS =INKEY$ # RETURNRNDABS "INKEY$ GOSUB #AT Z/[?]7LN [H]RND NEWZ GOSUB #AT Z[T]#K GOTO Y▒█#/ NEW6-RNDLN #? FAST CLEARACS ▘#CODE STR$ .LN SAVE < LPRINT FAST#[L]C£,VAL STR$ LN K#SGN AT <"/ LIST LPRINT /CODE RETURN""4▖Y"/U PRINT NEW# RETURNRNDK▛ LET CLEARACS ▘LEN /G CLEARACS ▘#C~~[J] CLEARACS ▘▚LN ##/▖ CLEARACS ▘LEN LET LN #,,~~ PRINT VAL NEW#LN ##AT ▀ LET RETURN█S LET CLEARACS ▘▚[J] GOSUB #AT Z PRINT YZ[)]>=[J]#LN RUN # LET VAL M<=Z[B]*[B]**- ACS >#5 2; FASTACS TLN STR$ RNDSGN U""Z RETURN▖ASN # RETURN▝C# RETURN▘CFY▒ PRINT STR$ , PRINT U""Z[B]4"U<=ZACS #C▖ LET J/▘ LET #)4 ;SGN LET =AT ▌# RETURN COPYC▒USQR Z##[U]KATN USGN Z#UPEEK Z#USTR$ Z# FASTVAL Y[Z][(]2 LN SGN INKEY$ AT ▌ LPRINT H4 LIST 5INT ZP4[6]TAN 7# RETURN0K▌LN [*]RNDINT 1 RETURNGK RUN CHR$ 0TAN LN ▝##ACS 4ACS 4ACS 4ACS 4LN ▝#█#7# RETURN"#TAN 7# RETURN"TAB SQR #7#ACS #C▝CHR$ RND) 77 FAST▞▒A # FOR ;( CLEAR FOR 5 S; FOR LPRINT 7LN =#>4▌76-RNDTAN =Z#J NEW▛WM#RND) STOPZ GOSUB #**ZY▒ PRINT #>~~VAL #U#RND RETURN▌S)JLEN ,,[B]##: C:3ACS ;( CLS/▛#[J]ACS )*( CLS[Q]#7<#>#[Q]#FLN ##=Z) STOPZ▞▒VAL ,#7<,#LN ##F#<( POKE TAN ▞4[J]##ACS [W]>#<( RUN TAN E-RND# RETURN;C# RETURN#C▌LN [*]RNDINT + LPRINT 6-RND▘ TAN TO RETURN THENC▌LN [*]RNDINT ) FAST SCROLL )""#STR$ RETURN LLIST ASN ## RETURN SCROLLASN [:]RND RETURN LOAD ASN ▛# RETURN LIST ASN 3# RETURN PAUSE ASN ## RETURN PRINT ASN ## RETURN PLOT ASN [Y]INKEY$ RETURN RUN ASN ▟INKEY$ RETURN SAVE ASN PEEK # RETURN RAND ASN ## RETURN CLSASN ;INKEY$ RETURN UNPLOT ASN TAB INKEY$ RETURN CLEARASN ▗INKEY$ RETURN RETURNASN [*]RND RETURN COPYASN /# RETURN LPRINT 4[9]SGN )[J]#STR$ 7# RETURNXC##7# RETURN#C[<] RETURN;4 PLOT # RETURNAASN [▒]# RETURNBASN [B]INKEY$ RETURNCASN [B]PI RETURNDASN SCROLLINKEY$ RETURNIASN ## RETURNLASN [5]# RETURNPASN ## RETURNRASN [T]# RETURNS42F#7 RETURNDASN ## RETURNEASN ▞# RETURNMASN 8# RETURNPASN [1]# RETURNSASN ##/# RETURNTASN ## RETURNUASN F# RETURNW4UF#7 RETURNDASN ## RETURNLASN "# RETURNRASN ▟# RETURNUASN LEN #/57#7# RETURN#C; RETURN;4 PLOT # RETURNCASN [F]PI RETURNDASN FOR INKEY$ RETURNRASN [X]# RETURNTASN ###SQR # 1 REM FAST SAVE LOAD ##LN SCROLL▝ SCROLLLN #?LN SAVE <#[K]C+ RETURN/K) TO RETURN#COS SCROLL RETURNSCOS RETURNVCOS RETURNCODE COS RETURNHCOS # POKE ▝, RETURN,C▖ RETURNCODE 4▝AT TAN .CHR$ 1**W,,X4 UNPLOT TAN FOR 5 .▘▘ LN ▒#:~~LN ▒#:#LN ▒#▘ CONT ▀LN ▒#▘(BLN ▒#TAN ▘▘COS ( RETURN$4 CLS.#[N]4 NEXT TAN ▞▛ACS 5>=##USR ##Y▀X4 CLEAR GOSUB #▌TAB ##ACS 5>=##USR ##TAN PEEK COPYY-X4 CLEAR<= RETURNY:X4 CLEAR#[(]####PEEK COPYY9X4 CLEAR<= RETURNY0X4 CLEARF7RTAN ▘ █VAL LN ##AT ▌TAB [=]#▀ GOSUB #LN ##LN SQR #$LN ## CLEAR FAST LET #:[E]LN ##LN SQR ##LN ##LN SQR ##LN ## CLEAR FAST LET ##LN ##7.#[N]4 PLOT TAN LN LLIST # RETURNHASN ▌#STR$ VAL PRINT LN LLIST ▒) ▝LN Z# LET M#RND RETURNS4£5 46#RND5 / /) RETURNV4>E(RND6#RND FOR E=RND[B] GOSUB #6#RND/O RETURNCODE C▌5,,RND/ CONT SCROLL RETURN,C£ RETURN0 AND POKE ▝ RETURNAABS POKE ▝/ LOAD LN 1#6#RND SCROLL RETURN#C~~ RETURN0S SCROLL RETURNAK CONT / LET LN 1#/SIN AT LPRINT )WRNDSTR$ GOSUB [K][J]E#RND GOSUB ##RND▚7.##[N]#4 RUN M#RNDF#M#RND LPRINT )4 LN [)]# GOSUB ##RND GOSUB ##RNDE#RNDLN [)]#/0 F#[J]E#RND GOSUB ##RND▚7.##[N]#4 RUN [T]C▝INT =LN LLIST ▒LN ▛▝TAN <= RETURN*S CLS: £<= RETURN*K IF #LEN FOR ACS 5▟▝TAN PRINT # RETURN,C▌LN [*]RNDINT / LET TAN 6-RNDLN #? FASTLN LN + LPRINT TAN LN [H]RND PRINT LN [4]RND7LN [H]RND# LET #TAN 7# RETURN#C▀ RETURN;""6-RNDTAN A ##▞▌ACS 9ACS =( IF ,,▘ 4,,TAN 7LN [T]RNDLN [4]RNDLN ,,INKEY$ ##ACS ZACS ZACS Z##STR$ LN STR$ RND LET J NEW▛W#TAN Y3[)]K▌LN [*]RNDINT (Y[Z][(]SQR LN [*]RNDINT 25 6AT ZA4##<▘ COPY*Q GOSUB [K]TAN NEXT Y▞# ( CLEARLEN LIST W4 CLEAR▞"" CLEARACS ##C▝▞[K])4 5 4##INKEY$ ▌ASN #INKEY$ ;# GOSUB ### RETURN PLOT E£RND ###) RUN ▙;Y2 GOSUB #Y PRINT ▘▛▝ CLEARACS ##CODE [P]▝LN [>]▝LN 4▝<>5GINKEY$ #[8]▝ CLEARACS #▚/▖ CLEARACS #LEN E£RND▘9 GOSUB PIF FOR 5 █;6#INKEY$ FOR GOSUB [K]LN F?<>5GINKEY$ TAN 7LN [T]RNDLN [4]RND##LN ▞INKEY$ VAL 7LN [H]RNDAT LN STR$ RND#TAN 2 COPY/▝2 STR$ 7LN [T]RNDLN ,,INKEY$ SGN GOSUB ##ZLN LET RND##?( CLEARACS .*PI▌4▝▞▒▛( CLEAR#TAN Y COPY/▘[J]MVAL Z CLEARACS #[:]7LN [T]RNDLN ,,INKEY$ # RETURN,4"7 GOSUB ##ZLN [T]RNDLN ,,INKEY$ ## GOSUB ##ZVAL #[)]-▘K▖ GOSUB #- COPY4▝- FAST##MSQR Z LET [(]2▘K▖ GOSUB #2 COPY4▝2 ##MINT Z#[W]S▞##- /▝2 GOSUB #SGN Z6PEEK Z#[B]3#A 6STR$ ZAT VAL Y[Z][(] PRINT UVAL Z# LET CLEARACS ##4▌LN SGN INKEY$ /▀LN ##UPEEK Z#▞ USTR$ Z##,,#MSTR$ Z GOSUB #SGN ZUUSR Z# GOSUB PIS▒#MSTR$ Z GOSUB #INT ZAT #▙##▄#5CHR$ ZOUUSR Z[Y]4[N] GOSUB ##ZTAN Y COPY/▘[J]MVAL Z7LN [T]RNDLN [4]RNDVAL 7LN [H]RND#I 6INT Z#6SGN ZAT Y▘ PRINT VAL VAL EINT Z GOSUB #SGN Z▞▌VAL ACS EACS .( IF [R] GOSUB #6INT Z GOSUB #SGN ZAT ACS GACS 1( IF ;6SGN Z GOSUB #INT ZAT #ACS <[~~]##ACS +[£]#Y[Z][(]S,, PRINT UVAL Z# LET LN SGN INKEY$ AT LET W RETURNASN S[O]TAN Y▘MINT ZLN COS RNDCOS LN [H]RNDMINT ZLN TAN RNDCOS 7LN [T]RNDLN [4]RND[S]S▀#INKEY$ #LN (INKEY$ #INKEY$ LN (INKEY$ #PI GOSUB #SQR Z[)]W PRINT 7LN [T]RND[S]K▀#INKEY$ # GOSUB #ABS Z[(]W4▘XSGN # GOSUB #USR ZUPEEK Z#USGN Z#[B]LN INPUT RND6CHR$ ZUABS Z#USGN Z#[B]LN INPUT RND6**Z£TAN LN +#4*UINT Z#5 4▘ /#J#7"#[L]4 RUN +4 INPUT TAN USTR$ ZECHR$ Z GOSUB #**Z6 AND Z GOSUB #>=Z PRINT FAST GOSUB # LPRINT C#UPEEK ZLN INKEY$ STR$ VAL #3ZACS <( IF AT ACS .*( CLS#SGN 7 FAST[B] GOSUB # LPRINT C▌#J#/ NEXT UABS ZLN INKEY$ Y,,[(]#VAL ,*ZACS 1( IF AT ACS +3( CLS>▘4 E>=Z,,6>=Z FOR E AND Z,,6 AND Z LET X4[A]5INT ZP4[?]TAN UUSR Z RETURN▒4▖,J/NOT UPEEK ZLN INKEY$ VAL ,3ZACS +( IF AT ACS 1*( CLS#UABS ZJ NEW▛C$#,VAL ?ACS 0( CLSAT ACS ▖( UNPLOT #/[E]E(RND#[T]COS RETURN█4▌LN [*]RNDINT ▘VAL LN PAUSE ,,AT FOR / GOTO PRINT SCROLL FAST:RND▟#LN ##7 FAST▞▌[J]#( CLEARSGN LPRINT LET TAN LN SCROLLRND#?( CLEARLN ##K▀Y▟>LN COS RNDTAB SQR #TAN LN SCROLLRND FASTAT LN 4+ FASTLN ##AT FAST##LN PLOT ;LN [~~]+ LPRINT / STEP LN SCROLLRND#▞ / SLOW###Y[Z][(]STR$ VAL PRINT LN SGN INKEY$ LET AT SGN TAN 2 COPY/▝2 STR$ LN C#SGN USTR$ Z#UPEEK Z5SGN Z PRINT FASTLN [D]#+C▞WLN [J]#/ RUN UUSR Z# LPRINT LET F FASTLN [D]#+C▞£LN [J]#/ RUN USTR$ Z# LPRINT UABS Z PRINT FASTLN [D]#+C▞XLN [J]#/ RUN UUSR Z# LPRINT LET 7LN [D]#+COS $LN [J]#/ SAVE LN 7?2"" CLEARACS ##C▝2[K]5 4[J]PEEK CLSLN #?ABS ▐▒<= CLS*K CLS-4▞▒#<= CLS3K CLS# NEW█PEEK CLSACS )( PAUSE 7+4 FOR <= CLS3K CLSLN ##/SGN 76-RNDLN #?LN [B]:##▘▘COS CLEARACS V#""( RAND $4 PLOT .#[N]4 INPUT TAN 7# RETURN#4,,LN OR #LN RUN #/L7# RETURN,C> RETURN;CG RETURN#C# RETURNAT C# RETURNTAB C#/# GOSUB #AT Z# NEW LIST LEN ( RETURNRNDCODE [O]#ATN [J]#/STR$ #LEN ▒#[J]# GOSUB #AT ZTAN ▞ COPY7# RETURN#COS RETURN,4▖Y▖/" RETURN;4VAL ▖# RETURN▀ASN SQR #M""Z/ STOP GOSUB #AT Z/SQR 7LN [T]RND## RETURN[T]ABS =INKEY$ # RETURNRNDABS "INKEY$ GOSUB #AT Z/[?]7LN [H]RND NEWZ GOSUB #AT Z[T]#K GOTO Y▒█#/ NEW6-RNDLN #? FAST CLEARACS ▘#CODE STR$ .LN SAVE < LPRINT FAST#[L]C£,VAL STR$ LN K#SGN AT <"/ LIST LPRINT /CODE RETURN""4▖Y"/U PRINT NEW# RETURNRNDK▛ LET CLEARACS ▘LEN /G CLEARACS ▘#C~~[J] CLEARACS ▘▚LN ##/▖ CLEARACS ▘LEN LET LN #,,~~ PRINT VAL NEW#LN ##AT ▀ LET RETURN█S LET CLEARACS ▘▚[J] GOSUB #AT Z PRINT YZ[)]>=[J]#LN RUN # LET VAL M<=Z[B]*[B]**- ACS >#5 2; FASTACS TLN STR$ RNDSGN U""Z RETURN▖ASN # RETURN▝C# RETURN▘CFY▒ PRINT STR$ , PRINT U""Z[B]4"U<=ZACS #C▖ LET J/▘ LET #)4 ;SGN LET =AT ▌# RETURN COPYC▒USQR Z##[U]KATN USGN Z#UPEEK Z#USTR$ Z# FASTVAL Y[Z][(]2 LN SGN INKEY$ AT ▌ LPRINT H4 LIST 5INT ZP4[6]TAN 7# RETURN0K▌LN [*]RNDINT 1 RETURNGK RUN CHR$ 0TAN LN ▝##ACS 4ACS 4ACS 4ACS 4LN ▝#█#7# RETURN"#TAN 7# RETURN"TAB SQR #7#ACS #C▝CHR$ RND) 77 FAST▞▒A # FOR ;( CLEAR FOR 5 S; FOR LPRINT 7LN =#>4▌76-RNDTAN =Z#J NEW▛WM#RND) STOPZ GOSUB #**ZY▒ PRINT #>~~VAL #U#RND RETURN▌S)JLEN ,,[B]##: C:3ACS ;( CLS/▛#[J]ACS )*( CLS[Q]#7<#>#[Q]#FLN ##=Z) STOPZ▞▒VAL ,#7<,#LN ##F#<( POKE TAN ▞4[J]##ACS [W]>#<( RUN TAN E-RND# RETURN;C# RETURN#C▌LN [*]RNDINT + LPRINT 6-RND▘ TAN TO RETURN THENC▌LN [*]RNDINT ) FAST SCROLL )""#STR$ RETURN LLIST ASN ## RETURN SCROLLASN [:]RND RETURN LOAD ASN ▛# RETURN LIST ASN 3# RETURN PAUSE ASN ## RETURN PRINT ASN ## RETURN PLOT ASN [Y]INKEY$ RETURN RUN ASN ▟INKEY$ RETURN SAVE ASN PEEK # RETURN RAND ASN ## RETURN CLSASN ;INKEY$ RETURN UNPLOT ASN TAB INKEY$ RETURN CLEARASN ▗INKEY$ RETURN RETURNASN [*]RND RETURN COPYASN /# RETURN LPRINT 4[9]SGN )[J]#STR$ 7# RETURNXC##7# RETURN#C[<] RETURN;4 PLOT # RETURNAASN [▒]# RETURNBASN [B]INKEY$ RETURNCASN [B]PI RETURNDASN SCROLLINKEY$ RETURNIASN ## RETURNLASN [5]# RETURNPASN ## RETURNRASN [T]# RETURNS42F#7 RETURNDASN ## RETURNEASN ▞# RETURNMASN 8# RETURNPASN [1]# RETURNSASN ##/# RETURNTASN ## RETURNUASN F# RETURNW4UF#7 RETURNDASN ## RETURNLASN "# RETURNRASN ▟# RETURNUASN LEN #/57#7# RETURN#C; RETURN;4 PLOT # RETURNCASN [F]PI RETURNDASN FOR INKEY$ RETURNRASN [X]# RETURNTASN ###SQR # 1 REM FAST SAVE LOAD ##LN SCROLL▝ SCROLLLN #?LN SAVE <#[K]C+ RETURN/K) TO RETURN#COS SCROLL RETURNSCOS RETURNVCOS RETURNCODE COS RETURNHCOS # POKE ▝, RETURN,C▖ RETURNCODE 4▝AT TAN .CHR$ 1**W,,X4 UNPLOT TAN FOR 5 .▘▘ LN ▒#:~~LN ▒#:#LN ▒#▘ CONT ▀LN ▒#▘(BLN ▒#TAN ▘▘COS ( RETURN$4 CLS.#[N]4 NEXT TAN ▞▛ACS 5>=##USR ##Y▀X4 CLEAR GOSUB #▌TAB ##ACS 5>=##USR ##TAN PEEK COPYY-X4 CLEAR<= RETURNY:X4 CLEAR#[(]####PEEK COPYY9X4 CLEAR<= RETURNY0X4 CLEARF7RTAN ▘ █VAL LN ##AT ▌TAB [=]#▀ GOSUB #LN ##LN SQR #$LN ## CLEAR FAST LET #:[E]LN ##LN SQR ##LN ##LN SQR ##LN ## CLEAR FAST LET ##LN ##7.#[N]4 PLOT TAN LN LLIST # RETURNHASN ▌#STR$ VAL PRINT LN LLIST ▒) ▝LN Z# LET M#RND RETURNS4£5 46#RND5 / /) RETURNV4>E(RND6#RND FOR E=RND[B] GOSUB #6#RND/O RETURNCODE C▌5,,RND/ CONT SCROLL RETURN,C£ RETURN0 AND POKE ▝ RETURNAABS POKE ▝/ LOAD LN 1#6#RND SCROLL RETURN#C~~ RETURN0S SCROLL RETURNAK CONT / LET LN 1#/SIN AT LPRINT )WRNDSTR$ GOSUB [K][J]E#RND GOSUB ##RND▚7.##[N]#4 RUN M#RNDF#M#RND LPRINT )4 LN [)]# GOSUB ##RND GOSUB ##RNDE#RNDLN [)]#/0 F#[J]E#RND GOSUB ##RND▚7.##[N]#4 RUN [T]C▝INT =LN LLIST ▒LN ▛▝TAN <= RETURN*S CLS: £<= RETURN*K IF #LEN FOR ACS CS) 154 LET T=T+N1 160 IF NOT WF THEN GOTO VAL "1E3" 170 IF USR HR THEN PRINT ", ";WD;" DEG.FROM";;;" N" 180 IF USR HR THEN PRINT TAB N2;"COURSE";;;;"? (DEG.CLOCKWISE FROM ";;;"N)" 190 INPUT C 200 IF C359 THEN GOTO CODE "[Y]" 210 IF USR HR THEN PRINT AT N3*N8,I4;" " 220 IF USR HR THEN PRINT AT N3*N8,I6;;;;C;" DEGREES FROM ";;;"N" 229 REM [C][H][E][C][K]█[C][O][U][R][S][E]█[W][I][T][H]█[W][I][N][D] 230 IF ABS ((C+360*(C<45 AND WD>315))-(WD+360*(C>315 AND WD<45)))<45 THEN GOTO VAL "1200" 240 LET C=PI*C/180 250 LET SA=50*CS 260 IF USR HR THEN PRINT TAB N2;;;"SAIL█AREA";;;;"? (MAX. ";SA;" SQ.FT.)" 270 INPUT A 280 IF ASA THEN GOTO VAL "270" 290 IF USR HR THEN PRINT AT N4*N8,T0;" " 300 IF USR HR THEN PRINT AT N4*N8,II*N2;A;" SQ.FT. HOISTED" 310 IF WF>N6 AND A>500*(12-WF) THEN GOSUB VAL "1400" 320 LET D=.00001*A*WF**1.5*H 330 FOR R=N0 TO D STEP N2 340 LET X=X2+R*SIN C 350 LET Y=Y2+R*COS C 360 IF X<-P5 OR X>=49.5 OR Y<-P5 OR Y>=29.5 THEN GOTO VAL "1600" 380 LET L1=I5-INT ((Y1+P5)/N2) 385 LET K1=N1+INT ((X1+P5)/N2) 390 LET L=I5-INT ((Y+P5)/N2) 395 LET K=N1+INT ((X+P5)/N2) 400 LET K2=(N5+K)*N8 410 LET L2=191-((N5+L)*N8) 415 IF (PEEK 16323<>K2 OR PEEK 16324<>L2) THEN IF USR HR THEN LPRINT SS;I2-WF;SM;N1,K2,L2 420 IF R=N0 OR D$(L,K)=" " THEN GOTO 500 430 GOTO VAL "2E3"*(CODE D$(L,K)>=CODE "[A]")+VAL "2250"*(D$(L,K)="▞")+VAL "2500"*(D$(L,K)="=")+VAL "2750"*(D$(L,K)="*")+VAL "3E3"*(D$(L,K)="[~~]")+VAL "3500"*(D$(L,K)="[*]")+VAL "3750"*(D$(L,K)="▒") 500 IF INT (RND*250+N1)=N5 THEN GOSUB VAL "3250" 510 LET X1=X 520 LET Y1=Y 530 NEXT R 540 LET X2=X 550 LET Y2=Y 600 GOTO T4 1000 REM [B][E][C][A][L][M][E][D] 1010 FOR R=N1 TO CODE "M" 1020 NEXT R 1025 GOSUB T6 1030 IF USR HR THEN PRINT AT I6,N2;;;"BECALMED";;;;" YOU DRIFT HELPLESS" 1040 IF USR HR THEN PRINT TAB II*N2;"WHILE YOUR CREW" 1050 IF USR HR THEN PRINT TAB II*N2;"EAT ";CS;S$ 1060 GOTO T4 1200 REM [I][N]█[I][R][O][N][S] 1205 GOSUB T6 1210 IF USR HR THEN PRINT AT I6,N2;;;"IN█IRONS";;;;" YOU HAVE SAILED TOO" 1220 IF USR HR THEN PRINT TAB II*N2;"CLOSE TO THE WIND." 1230 IF USR HR THEN PRINT TAB II*N2;"EAT ";CS;S$ 1390 GOTO T4 1400 REM [S][T][O][R][M]█[D][A][M][A][G][E][S] 1410 GOSUB T6 1420 LET H1=I0*(WF-N2) 1440 IF WFH1)+H*(H<=H1);R$ 1480 LET H=(H-H1)*(H>H1) 1490 RETURN 1600 REM [O][F][F]█[M][A][P] 1605 LET D=D-R 1610 IF (N/N2<>INT (N/N2)) AND (X>=VAL "47.5") THEN GOTO VAL "1700" 1620 IF (N/N2=INT (N/N2)) AND (X=VAL "27.5") THEN GOTO VAL "1750" 1640 IF (N>N2) AND (YHG THEN GOSUB VAL "3600" 3560 GOTO VAL "5800" 3610 FOR R=N1 TO CODE ";" 3620 IF USR HR THEN PRINT AT N8,I2*N2;;;;"HI-SCORE" 3630 IF USR HR THEN PRINT AT N8,I2*N2;;;"HI-SCORE" 3650 NEXT R 3690 RETURN 3750 REM [L][A][N][D] 3755 LET CS1=CS 3756 GOSUB T6 3760 LET R=RND 3770 IF R>=VAL ".4" THEN GOTO VAL "4E3" 3780 IF R>=VAL ".2" THEN GOTO VAL "3900" 3800 REM [S][A][V][A][G][E][S] 3810 LET CS=INT (CS*(N1-RND/N2))-N2 3830 IF USR HR THEN PRINT AT I6,N2;;;"LAND";;;;" ";"SAVAGES" AND (N=N1 OR N=N2);"AMAZONS" AND (N=N3 OR N=N4);"VIKINGS" AND (N=N5 OR N=N6);" ATTACK YOU." 3840 IF USR HR THEN PRINT TAB II*N2;CS1-CS;" CREWMEN KILLED." 3850 IF USR HR THEN PRINT TAB II*N2;"YOU JUST ESCAPED." 3860 GOTO VAL "4400" 3900 REM [M][A][I][D][E][N][S] 3910 LET CS=INT (CS*(N1-RND/N4))-N2 3920 IF USR HR THEN PRINT AT I6,N2;;;"LAND";;;;" ";"DUSKY MAIDENS" AND (N=N1 OR N=N2);"CUTE MERMAIDS" AND (N=N3 OR N=N4);"BUXOM SIRENS " AND (N=N5 OR N=N6);" LURE" 3930 IF USR HR THEN PRINT TAB II*N2;CS1-CS;" CREWMEN AWAY..." 3940 IF USR HR THEN PRINT TAB II*N2;">LUCKY LADS<" 3950 GOTO VAL "4400" 4000 REM [T][R][A][D][E] 4005 LET Z=N1 4006 GOSUB T4 4010 IF USR HR THEN PRINT AT I6,N2;;;"LAND";;;;" YOU MAY TRADE OR SAIL ON." 4020 IF USR HR THEN PRINT TAB I2;"FOOD(F),CREW(C),REPAIR(R)" 4030 IF USR HR THEN PRINT TAB I2;"SAIL(S).....WHICH OPTION?" 4040 IF INKEY$ <>"" THEN GOTO VAL "4040" 4042 IF INKEY$ ="" THEN GOTO VAL "4042" 4045 LET T$=INKEY$ 4048 GOSUB T6 4050 GOTO VAL "4E3"+HU*(T$="F")+CODE "COS "*(T$="C")+VAL "300"*(T$="R")+VAL "400"*(T$="S") 4075 IF USR HR THEN PRINT AT N3*N8,I0;" NOT ENOUGH GOLD IN HAND" 4080 IF USR HR THEN PRINT AT I0*N8,N0;"▌ ";AT I0*N8,VAL "(1-(G>9999))*2";G 4085 IF USR HR THEN PRINT ;;;AT N4*N8,I2;"PUSH█ANY█KEY█TO█CONTINUE ";;;; 4090 IF USR HR THEN PAUSE VAL "4E4" 4095 GOTO VAL "4010" 4100 REM [F][O][O][D] 4105 IF USR HR THEN PRINT ;;;AT I6,N2;"FOOD";;;;" 1 RATION ";;;"=";;;;" 1 GOLD PIECE." 4110 IF USR HR THEN PRINT TAB I2;"HOW MANY RATIONS?" 4120 INPUT R 4130 IF (G-R)VAL "2500" THEN IF USR HR THEN PRINT AT N4*N8,I2;"SHIP HOLD TOO SMALL." 4136 IF F+R>VAL "2500" THEN GOTO VAL "4120" 4140 LET F=F+R 4145 IF USR HR THEN PRINT AT I2*N8,N2;" ";AT I2*N8,N2;F 4150 LET G=G-R 4160 IF USR HR THEN PRINT AT N3*N8,I2;R;" RATIONS BOUGHT." 4170 GOTO VAL "4080" 4200 REM [C][R][E][W] 4205 IF USR HR THEN PRINT AT I6,N2;;;"CREW";;;;" 1 MAN ";;;"=";;;;" 10 GOLD PIECES" 4210 IF USR HR THEN PRINT TAB I2;"HOW MANY CREWMEN?" 4220 INPUT R 4225 IF CS+R>HU THEN IF USR HR THEN PRINT AT N4*N8,I2;"NOT ENOUGH ROOM ON BOARD." 4226 IF CS+R>HU THEN GOTO VAL "4220" 4230 IF (G-10*R)HU THEN GOTO VAL "4320" 4330 IF (G-T0*R)9999)";G;AT I2*N8,N2;F;AT I4*N8,N2;CS;AT I6*N8,N2;HU-H 4550 IF Z THEN RETURN 4750 REM [L][O][S][E][?] 4760 IF H" 9521 LET I9=CODE "<" 9522 LET T0=CODE "=" 9523 LET T4=VAL "4500" 9524 LET T6=VAL "6E3" 9525 LET P5=VAL ".5" 9526 LET T8=VAL "8980" 9527 LET HU=I0*I0 9528 LET T1=CODE "+" 9730 LET HG=N0 9740 RAND 9760 LET CS=HU 9770 LET N=N1 9780 LET HR=VAL "19400" 9800 LET H=CS 9810 LET G=VAL "1E3" 9820 LET F=VAL "2500" 9830 LET X1=N0 9840 LET Y1=N0 9850 LET X=N1 9860 LET Y=N1 9870 LET T=N0 9880 LET L=I5 9890 LET K=N1 9900 DIM Q(CODE ",") 9910 FOR R=N1 TO CODE "," 9920 LET Q(R)=CODE "[9]"+R 9930 NEXT R 9940 LET P$="BAD NAVIGATION." 9950 LET Q$="SHIP DAMAGE OF" 9960 LET R$=" PTS SUSTAINED." 9970 LET S$=" FOOD RATIONS" 9980 LET Z=N0 9982 IF USR VAL "20477" THEN REM [I][N][I][T][.]█[S][C][R][E][E][N]█[D][A][T][A] 9984 POKE VAL "20507",N0 9986 POKE VAL "20508",CODE "█" 9988 IF USR VAL "20495" THEN REM LOAD [M][A][P]█[1] 9990 RETURN 9995 SAVE "VOYAGE[2]" 9997 RUN ```