Gulp

Products: Gulp
Date: 1982
Type: Program
Platform(s): TS 1000
Tags: Game

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
171160x42DCScreen/display initialization, called at menu entry and instruction screens
165140x4082Game-over handler, triggered when player occupies same cell as hunter
170300x4286Post-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:

KeyCODE K$CODE K$-38Target line
A380550
B391570
C402590
D413610
E424630
F435650
G446670

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.

Content

Appears On

Related Products

Fast paced game of chase and escape. Dash through 5 different mazes; pick up points by gulping food along the...

Related Articles

Related Content

Image Gallery

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

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

People

No people associated with this content.

Scroll to Top