--- title: "Gulp" id: 58383 type: "computer_media" slug: "gulp" url: "http://localhost/computer_media/gulp/" markdown_url: "http://localhost/computer_media/gulp.md" published_at: "2024-11-17T04:03:12+00:00" modified_at: "2026-04-03T07:58:04+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/11/GulpScr.jpeg" excerpt: "A Pac-Man-inspired maze game with machine code acceleration, five selectable mazes, and adjustable speed and chaser aggression settings." 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: "Mindware" slug: "mindware" taxonomy: "post_tag" url: "http://localhost/tag/mindware/" - 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/" genre: - name: "Game" slug: "game" taxonomy: "genre" url: "http://localhost/type/game/" media_type: "Program" download_url: "https://archive.org/download/timex-sinclair-software-archive/Gulp%20%281982%29%28Mindware%29%28TS1000%29%28US%29%28Program%29.zip" mediadate: "1982" producer_company: - id: 11120 title: "Mindware, Inc." type: "company" url: "http://localhost/company/mindware/" images: - url: "http://localhost/wp-content/uploads/2024/11/GulpScr.jpeg" - url: "http://localhost/wp-content/uploads/2024/11/GulpInst1.jpeg" - url: "http://localhost/wp-content/uploads/2024/11/GulpInst2.jpeg" - url: "http://localhost/wp-content/uploads/2024/11/GulpMenu.jpeg" - url: "http://localhost/wp-content/uploads/2024/11/Tape-6.jpg" related_products: - id: 12792 title: "Gulp" type: "product" url: "http://localhost/product/gulp/" media_type_tags: "Game" --- # Gulp Gulp is a Pac-Man-style maze game in which the player steers a character (O) through a maze, eating food dots (.) while being chased by a hunter (X). The program uses machine code via RAND USR calls at addresses 17116, 16514, and 17030 for performance-critical operations such as game logic and display rendering. Five selectable mazes are stored as encoded strings within the M$ array, with maze data packed into LET M$(MK TO ) assignments using embedded BASIC keyword tokens as compressed graphical data. Menu-driven options allow the player to adjust speed (1–9), grade/acceleration (1–9), reset the best score, save the game to tape, and view instructions across two screens. *** ## Program Analysis ### Program Structure The program is organized into several functional blocks: - **Lines 1–80:** Initialization — REM block containing machine code, inverse-video title REM, dimension of `M$`, and constant setup. - **Lines 310–350:** Header display and string initialization for `M$` and `S$`. - **Lines 500–665:** Main menu loop — displays options, reads a key A–G, and dispatches via computed GOTO. - **Lines 550–582:** Maze selection (B), speed selection (C), grade selection (D), score reset (E), save (F). - **Lines 860–890:** Subroutine at `RN=860` — reads a numeric keypress (1–9) and converts it to `N`. - **Lines 900–910:** Subroutine at `SE=900` — prints “SELECT ” prompt. - **Lines 1000–1170:** Two-page instructions screen, reached via menu option G. ### Machine Code Integration The machine code payload is stored in the `REM` statement at line 1 as raw bytes. Three distinct entry points are called via `RAND USR`: | Address (decimal) | Address (hex) | Usage | | --- | --- | --- | | 17116 | 0x42DC | Screen/display initialization, called at menu entry and instruction screens | | 16514 | 0x4082 | Game-over handler, triggered when player occupies same cell as hunter | | 17030 | 0x4286 | Post-game-over reset/restart routine | The machine code occupies the REM at line 1, which begins at address 0x4009 (the standard ZX81 program area start). The loader noted in the program metadata transfers this block to the correct working addresses before execution. The REM data is 379 bytes long and contains a full Z80 routine including subroutine calls, block moves (`ED B0` = LDIR), and conditional branching. ### Maze Storage and Encoding Five mazes are stored as long string assignments into `M$(MK TO )`, where `MK=14`, within lines 574–582. The maze strings use a mix of printable characters and embedded BASIC keyword tokens (represented as single bytes in the tokenized string), allowing compact storage of maze layout data within a 101-character DIM’d string `M$`. Each maze string begins and ends with `" COPY COPY COPY COPY "` padding, which serves as sentinel or boundary markers readable by the machine code. The string contains tokens such as `COPY`, `CLEAR`, `PRINT`, `UNPLOT`, `STR$`, `RND`, `LN`, `AT`, and others — these are not executed as BASIC commands but rather stored as their single-byte token values, providing a dense encoding of maze cell types or directions recognizable by the machine code game engine. ### Menu Dispatch Technique Line 540 uses a computed GOTO to dispatch menu choices: `540 GOTO 550+20*(CODE K$-38)` Since valid keys are A–G (BASIC codes 38–44 after subtracting the offset used internally), this maps: | Key | CODE K$ | CODE K$-38 | Target line | | --- | --- | --- | --- | | A | 38 | 0 | 550 | | B | 39 | 1 | 570 | | C | 40 | 2 | 590 | | D | 41 | 3 | 610 | | E | 42 | 4 | 630 | | F | 43 | 5 | 650 | | G | 44 | 6 | 670 | ### Constant Definitions Using PI Lines 20 and 30 define the frequently used integer constants without embedding numeric literals directly: - `LET O=PI/PI` — sets `O=1` - `LET Z=O-O` — sets `Z=0` This avoids storing floating-point number representations in variables and is a common memory/token-count optimization in ZX81 BASIC. ### Speed and Grade Encoding Speed is stored into `M$(5)` via: `602 LET M$(5)=CHR$ (X*X-X*N)` With `X=10`, this gives `CHR$(100-10*N)`, mapping speed keys 1–9 to character codes 90–10. Grade is stored into `M$(X+O+O)` (i.e., `M$(12)`) via: `615 LET M$(X+O+O)=CHR$ (96-X*N)` Both values are single bytes within `M$` that the machine code reads directly as control parameters for game pacing and chaser acceleration. ### Numeric Input Subroutine The subroutine at line 860 (`RN=860`) polls `INKEY$` in a tight loop until a character in the range “1”–”9″ is detected, then computes `N=CODE K$-28` (mapping “1”–”9″ to 21–29) and returns. This integer `N` is subsequently used in the arithmetic that encodes speed and grade into `M$`. ### Save Functionality Line 660 uses `SAVE Z$` with a user-supplied name, followed by `SLOW` at line 662 before returning to the menu. This saves the entire program — including the current maze, speed, and grade settings embedded in `M$` — allowing a configured game state to be preserved to tape. ### Notable Anomalies - Line 553 checks `IF INKEY$<>CHR$ 118` in a loop — CHR$ 118 is the NEWLINE character, so this waits for NEWLINE to be pressed after game over before proceeding. - Line 340 initializes `M$` with `".\##O%XBH \ ' E0 "` — this string contains the character set used by the machine code to render maze elements (food dot, wall segments, player, hunter, spaces, and block graphics). - The variable `ME=500` serves as a “return to menu” jump target used pervasively throughout the program in place of a GOTO 500 literal, saving bytes and making the menu entry point easy to relocate. ## Source Code ``` 1 REM 2A10401609113C40EDEDB0EB2AC40E439616C564C5681A4F3A3C40CB213033A3D40772310F213C110E923C110E217C1CDD3403A3E40772250401F52CDD3403A3F407722524018C2AC4093A3D40BEC02B18FB000000CDBB297CB65203CB4CC8CB6C206CB5D2023EFFCB65206CB6C2023E21CB642023EDFCB5C2023E1CB5420197B72803244403A404047F5F110FC21454035202936202A50403A4440360604F17301593A3D40BE2032A50403A3C40BECC36423A3E4077225040CD5A42214340352093A414077CD6841CD5A42C3E5403A4640B728143A5540CDF4228597324640C93A4640CDF42C02A5040CDF541424B2A5240CDF541973246407BB93063E1CDF42C079BB3063EFFCDF42C07AB83063E21CDF42C078BA3063EDFCDF42C078BA20D7BB93E13823EFF21EF411893EDF3823E2121F14156235E722B7332554064E57E324640CDF42E1C02310F3C921DF1FF21DFE5C5160ED4BC4037ED421210ED423831418F995DC1E1C9C52A5240604F1730159C13A3D40BEC8E52A52403A564077E17E3256403A3F4077225240C9E5214840352083A474077214140352AC40140097E3C77FE26302E1C9361C2B18F22A5040ED4B5240B7ED42C02AC40134097E3D6AC68077CDD04210F8E1FE1CC83A3C40325640C3C440402AC4012709E5D1E169E5D5651ABE388202A231310F61824D1E16AC565D51AC680121310F9D1CDD042D5E5150EDB0E1D1CDD042C110E2182D1E165361C2310FBC9C5620E0D20FD10F9C1C92AC401430916166203602310FB231520F5C91B1B1B 10 REM %G%U%L%P% % %C%A%M%P%B%E%L%L% %S%Y%S%T%E%M%S 15 DIM M$(101) 20 LET O=PI/PI 30 LET Z=O-O 40 LET X=10 50 LET ME=500 60 LET SE=900 70 LET MK=14 80 LET RN=860 310 PRINT "%>%G%U%L%P%<% % %M%A%Z%E%= % %S%P%E%E%D%=5% %G%R%A%D%E%=5% % BEST=00000 LIVES=5 SCORE=00000" 340 LET M$=".##O%XBH ' E0 " 350 LET S$=" " 500 RAND USR 17116 510 PRINT AT 3,Z;S$;" MENU",,,,S$;"A...PLAY",,,S$;"B...MAZE",,,S$;"C...SPEED",,,S$;"D...GRADE",,,S$;"E...RESET",,,S$;"F...SAVE" 515 PRINT ,," PRESS G...INSTRUCTIONS" 520 LET K$=INKEY$ 530 IF K$<"A" OR K$>"G" THEN GOTO 520 540 GOTO 550+20*(CODE K$-38) 550 IF M$(MK+O)=" " THEN GOTO 570 552 RAND USR 16514 553 PRINT AT O+O,X;"% %G%A%M%E% %O%V%E%R% " 555 IF INKEY$<>CHR$ 118 THEN GOTO 555 560 RAND USR 17030 565 PRINT AT 1,18;"5" 567 GOTO ME 570 GOSUB SE 571 PRINT "MAZE 1 TO 5" 572 GOSUB RN 573 PRINT AT Z,MK-O;K$ 574 IF K$="1" THEN LET M$(MK TO )=" COPY COPY COPY COPY % ( ' %Z TO 7B CLEAR %4 : %J TO 7F PRINT %C50RND: %F*5FSTR$ % 50RND)%F575FSTR$ %CRND +%F5F TO VAL %C : %55F7D55%H50: 55;;555551%F555555%C)54+%JNOT 77 PRINT %4= ' %ZNOT %Y COPY % ' COPY COPY COPY COPY " 576 IF K$="2" THEN LET M$(MK TO )=" COPY COPY COPY COPY % ' %Z COPY 7F CLEAR %4 : %J COPY 7F PRINT %C +%F COPY 7FSTR$ %E 55%E COPY 7F55%E% ' 55% Z UNPLOT ' %E%Z CLEAR 55%E% ' 55%E COPY 7F55%E 55%F COPY 7FSTR$ %C +%J COPY 7F PRINT %4 : %Z COPY 7F CLEAR % ' COPY COPY COPY COPY " 578 IF K$="3" THEN LET M$(MK TO )=" COPY COPY COPY COPY % ' %4 ' %J COPY COPY CLEAR % : %Z COPY COPY PRINT %4 ' %J COPY COPY CLEAR % : %Z COPY COPY PRINT %4 ' %J COPY COPY CLEAR % : %Z COPY COPY PRINT %4 ' %J COPY COPY CLEAR % : %Z COPY COPY PRINT %4 ' %J COPY COPY COPY % ' COPY COPY COPY COPY " 580 IF K$="4" THEN LET M$(MK TO )=" COPY COPY COPY COPY %7 PRINT ,,%C: %4+ RETURN %5%ZUSR '%X% 57 REM .:%Z50~~ CLEAR .:5F REM : %X ~~ PRINT :STR$ %+ RETURN %455%= '%Z55%* REM .:51%(~~ CLEAR 5D%3 REM ' INKEY$% F CLEAR 7D%Z%C: ' % %J PRINT CLEAR % (' COPY COPY COPY COPY " 582 IF K$="5" THEN LET M$(MK TO )=" COPY COPY COPY COPY % ' %Z%N60 CLEAR %Z%N60 CLEAR %L%N60LN %L%N60LN %KN60LN %KN60LN %KN60LN %KN60LN %KN60LN %KN60LN %N%N60<>%N%N60<>%L%N60AT %L%N60AT %L%N60AT %L%N60AT %Z%Z% ' COPY COPY COPY COPY " 586 GOTO ME 590 GOSUB SE 592 PRINT "SPEED 1 TO 9" 595 GOSUB RN 600 PRINT AT Z,X+X+O;K$ 602 LET M$(5)=CHR$ (X*X-X*N) 605 GOTO ME 610 GOSUB SE 611 PRINT "GRADE 1 TO 9" 612 GOSUB RN 615 LET M$(X+O+O)=CHR$ (96-X*N) 620 PRINT AT Z,29;K$ 625 GOTO ME 630 PRINT AT O,5;"00000" 635 GOTO ME 650 GOSUB SE 652 PRINT "NAME AND START TAPE" 655 INPUT Z$ 660 SAVE Z$ 662 SLOW 665 GOTO ME 670 GOTO 1000 860 LET K$=INKEY$ 870 IF K$<"1" OR K$>"9" THEN GOTO 860 880 LET N=CODE K$-28 890 RETURN 900 PRINT AT X+X,Z;"SELECT "; 910 RETURN 1000 RAND USR 17116 1005 PRINT AT 3,Z;"%I%N%S%T%R%U%C%T%I%O%N%S" 1010 PRINT "IN GULP YOU STEER YOURSELF (O) THROUGH A MAZE, EATING FOOD (.) AS YOU GO. USE KEYS 5-8 FOR LEFT, DOWN, UP, RIGHT." 1020 PRINT "YOU GET POINTS AS YOU MOP UP THEFOOD, BUT LOOK OUT FOR YOU SHARETHE MAZE WITH A HUNTER (%X) AND IF HE CATCHES YOU, A LIFE IS LOST." 1030 PRINT "WORSE, THE MORE YOU EAT THE FASTER HE CHASES. AFTER EACH CAPTURE, CHASER STARTS AGAIN FROM BOTTOM RIGHT." 1040 PRINT "GAME ENDS WHEN LIVES=0 OR YOU PRESS ""0"" KEY. THEN NEWLINE TO UPDATE ""BEST"" SCORE IF DUE, AND YOU GET BACK TO THE MENU." 1050 PRINT "%N%E%W%L%I%N%E% %T%O% %C%O%N%T" 1060 INPUT K$ 1061 RAND USR 17116 1065 PRINT AT 3,Z;"%I%N%S%T%R%U%C%T%I%O%N%S%,% %C%O%N%T%.", 1070 PRINT "USE THE MENU TO CONTROL THUS..." 1080 PRINT """A"" TO PLAY A GAME" 1090 PRINT """B"" TO SELECT ONE OF 5 MAZES" 1100 PRINT """C"" TO SELECT SPEED OR PACE OF THE GAME." 1110 PRINT """D"" TO SELECT GRADE, WHICH IS" 1120 PRINT " THE CHASER ACCELERATION." 1130 PRINT """E"" RESETS ""BEST"" TO 00000." 1140 PRINT """F"" SAVES GULP GAME ON TAPE." 1150 PRINT """G"" DISPLAYS THESE INSTRUCTIONS." 1160 PRINT "%N%E%W%L%I%N%E% %B%A%C%K% %T%O% %M%E%N%U" 1165 INPUT K$ 1170 GOTO ME ```