Chainsaw

This file is part of Synchro-Sette December 1982 . Download the collection to get this file.
Date: December 1982
Type: Program
Platform(s): TS 1000

This program implements a carnival shooting-gallery style game called “CHAIN-SAW” for the ZX81/TS1000. Three rows of a scrolling marquee — built from inverse-video characters — move across the screen in opposite directions, simulating a moving target belt; the top and bottom rows scroll left-to-right and right-to-left respectively. The player presses any key to fire a “bullet” (an asterisk) that travels upward from row 21, and the program checks whether it strikes a target on row 12 (the lower belt, string C$) or row 10 (the upper belt, string A$), awarding points equal to the character code of the hit symbol minus 156. The game ends after 10 shots, displaying total shots and score before restarting via RUN.


Program Analysis

Program Structure

The program is organized into a main animation loop and two subroutines:

  1. Initialization (lines 5–6): Score S and shots J are set to zero.
  2. String setup (lines 10–30): Three 32-character display strings A$, B$, and C$ are defined.
  3. Main loop (lines 40–80): Prints the three-row display, scrolls A$ and C$ in opposite directions, then calls the input/bullet subroutine before repeating.
  4. Input and bullet subroutine (lines 100–220): Checks for a keypress; if pressed, animates a bullet travelling upward from row 21 to row 0, calling hit-detection subroutines at rows 12 and 10.
  5. Hit detection — lower belt (lines 300–340): Increments shot count, scores if target at position 11 of C$ is not already blank, then blanks it.
  6. Hit detection — upper belt (lines 400–430): Scores and blanks if target at position 11 of A$ is not already blank, then advances the scroll.
  7. Game over (lines 500–550): Displays result, waits for ENTER, and restarts via RUN.

Display Strings and Scrolling

A$ (line 10) and C$ (line 30) are 32-character strings. Each character pair consists of a block graphic followed by an inverse-video digit or letter (0–9, A–F), making 16 pairs that fill the 32-column display exactly. B$ (line 20) is a static 32-character string spelling “CHAIN-SAW” in inverse video, centred with inverse spaces.

Scrolling is achieved by simple string slicing each frame:

  • A$ scrolls left: A$(2 TO 32)+A$(1) — drops the first character and appends it to the end.
  • C$ scrolls right: C$(32)+C$( TO 31) — moves the last character to the front.

Because the marquee characters are two-character pairs (graphic + label), scrolling by one character per frame causes the pairs to break up midway through a cycle, giving an asymmetric visual shimmer rather than a clean per-symbol scroll.

Bullet Animation

When a key is detected (line 110–120), the bullet loop (lines 140–190) runs from row 20 down to row 0 in STEP -1, printing an asterisk * at the current row and erasing the previous position one row below. The horizontal position I starts at 1 and increments each step, so the bullet travels diagonally upward-right rather than straight up. Hit-detection subroutines are called when N=12 and N=10, corresponding to the rows occupied by C$ and A$ respectively.

Scoring Mechanism

Scoring exploits the character codes of the block graphics used in the target strings. The formula CODE C$(11)-156 (line 320) and CODE A$(11)-156 (line 410) extract a numeric value from whichever symbol the bullet strikes at column position 11. The block graphic (ZX81 char 156) used in C$ and the block graphic (ZX81 char 154) used in A$ both yield small non-negative differences from 156, effectively giving a score of 0 or −2 respectively for a blank hit — though the blank-check guard (lines 310, 400) prevents scoring a previously-hit cell. Targets that have already been hit are replaced with the respective “blank” graphic.

Notable Techniques and Idioms

  • Inverse video in strings: The %X escape encodes inverse-video characters directly in string literals, used extensively for the title bar and score display.
  • Block graphics as target markers: \..
    (▖) marks an active upper-belt target; \'\' (▀) marks an active lower-belt target; hitting changes the cell to the same graphic, effectively making it look identical but registering as spent — a subtle visual bug.
  • FAST/SLOW around restart: Lines 520–540 bracket CLS with FAST/SLOW to clear the screen quickly without display flicker.

Bugs and Anomalies

LocationIssue
Lines 310 / 400The “already hit” check compares C$(11) to \'\' (▀) and A$(11) to \.. (▖), but these are the same graphics used to represent active targets, so an un-hit cell and a previously-hit cell are visually and logically identical. Scoring is blocked by the guard but the player receives no visual feedback that a target was already spent.
Line 150The erase step prints a space at AT N+1,I-1 using the previous row and column. When N=20 (first iteration), this prints at row 21, column 0 — overwriting the inverse-asterisk prompt printed at line 100.
Line 430The upper belt A$ is scrolled an extra step inside the hit-detection subroutine (line 430), meaning a hit causes the belt to advance one extra character that frame, creating a slight lurch in the animation.
Lines 310–320 vs 400–410Shot counter J is only incremented in the lower-belt subroutine (line 300/310), not in the upper-belt subroutine (line 400). Hitting the upper belt does not consume a shot, potentially allowing more than 10 scoring events.

Content

Appears On

Cassette to accompany the December 1982 issue of Synchro-Sette.

Related Products

Related Articles

Related Content

Image Gallery

Chainsaw

Source Code

   5 LET S=0
   6 LET J=0
  10 LET A$="\..%0\..%1\..%2\..%3\..%4\..%5\..%6\..%7\..%8\..%9\..%A\..%B\..%C\..%D\..%E\..%F"
  20 LET B$="% % % % % % % % % % % %C%H%A%I%N%-%S%A%W% % % % % % % % % % % % "
  30 LET C$="\''%0\''%1\''%2\''%3\''%4\''%5\''%6\''%7\''%8\''%9\''%A\''%B\''%C\''%D\''%E\''%F"
  40 PRINT AT 10,0;A$;AT 11,0;B$;AT 12,0;C$
  50 LET A$=A$(2 TO 32)+A$(1)
  60 LET C$=C$(32)+C$( TO 31)
  70 GOSUB 100
  80 GOTO 40
 100 PRINT AT 21,0;"%*"
 110 LET D$=INKEY$
 120 IF D$="" THEN RETURN 
 130 LET I=1
 140 FOR N=20 TO 0 STEP -1
 150 PRINT AT N,I;"*";AT N+1,I-1;" "
 160 IF N=12 THEN GOSUB 300
 170 IF N=10 THEN GOSUB 400
 180 LET I=I+1
 190 NEXT N
 200 PRINT AT 0,0;"%S%H%O%T%S% %= ";J;AT 0,12;" %S%C%O%R%E% %= ";S
 210 IF J=10 THEN GOTO 500
 220 GOTO 40
 300 LET J=J+1
 310 IF C$(11)="\''" THEN GOTO 480
 320 LET S=S+CODE C$(11)-156
 330 LET C$(11)="\''"
 340 RETURN 
 400 IF A$(11)="\.." THEN RETURN 
 410 LET S=S+CODE A$(11)-156
 420 LET A$(11)="\.."
 430 LET A$=A$(2 TO 32)+A$(1)
 480 RETURN 
 500 PRINT AT 6,0;"GAME OVER - PRESS ENTER","TO RESTART :::"
 510 INPUT A$
 520 FAST 
 530 CLS 
 540 SLOW 
 550 RUN 
\n9998 SAVE "CHAINSA%W"
\n9999 RUN 

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

People

No people associated with this content.

Scroll to Top