This program draws a two-scoop ice cream cone using ZX81/TS1000 block graphics and lets the user choose from seven flavours for each scoop. The cone itself is built with CHR$ 136 (a solid block graphic character) across rows 11–20 in a widening pattern, creating a triangular silhouette. Each scoop is drawn as an approximate circle by printing the chosen flavour character (mapped from the menu number via VAL R$+127) in nested rectangular bands of decreasing width, stacking the second scoop above the first. The program loops indefinitely, clearing the screen and returning to the flavour menu after any keypress.
Program Analysis
Program Structure
The program divides into four logical phases:
- Menu display (lines 15–100): prints the title and seven flavour options.
- Input loop (lines 110–240): a
FOR X=1 TO 2loop collects one flavour choice per scoop, storing the result asI$(bottom scoop) andJ$(top scoop). - Drawing (lines 250–540): clears the screen, draws the cone body, then the two scoops.
- Repeat loop (lines 550–600): pauses, waits for a keypress, and jumps back to line 20 for another cone.
Flavour Encoding
The user presses a digit key 1–7. The code at line 170 validates by checking CODE R$ is between 29 and 35, which are the ZX81 internal codes for the characters ‘1’ through ‘7’. Line 190 computes R = VAL R$ + 127, mapping the digit to a character code in the 128–134 range (block graphic / inverse video territory). Two special cases patch the result:
- Line 200: if
R=129(choice 2), setR=137— selects a different block graphic for visual contrast. - Line 210: if
R=132(choice 5), setR=10— uses the newline character code, which on the ZX81 displays as a blank/space, giving a hollow appearance for “Molasses Lace”.
The resulting character is stored via CHR$ R into I$ or J$ and later used as the fill character for each scoop.
Cone Drawing Algorithm
The cone is drawn in lines 280–350. A FOR R=20 TO 11 STEP -2 loop iterates upward from the bottom of the screen. Variables A and B start at column 15 (a single point) and widen by one column on each side per iteration, building a triangular shape. Each row prints CHR$ 136 (a solid block) from column A to B on both the current row and the one above it, effectively doubling the vertical density.
Scoop Drawing Algorithm
Each scoop is approximated as a filled circle using three concentric rectangular bands of decreasing width, printed with the flavour character. The bottom scoop (I$) occupies roughly rows 5–10, and the top scoop (J$) rows 0–4. The technique for each scoop is identical:
| Band | Column range | Rows (bottom scoop) | Rows (top scoop) |
|---|---|---|---|
| Outer | 9–21 / 10–20 | 7, 8 | 2, 3 |
| Middle | 10–20 / 11–19 | 6, 9 | 1, 4 |
| Inner | 11–19 / 12–18 | 5, 10 | 0 |
The conditional jumps at lines 420 and 450 (and their equivalents 520 and 540 for the top scoop) skip inner-band printing when the column is outside the narrower range, efficiently controlling which cells are filled without nested loops.
Key BASIC Idioms
LET R$=INKEY$followed byIF R$="" THEN GOTOis the standard busy-wait input idiom on this platform.SLOWat line 10 switches to slow (display-sync) mode, ensuring the graphics render visibly rather than flashing.PAUSE 123at line 550 provides a brief enforced display pause before the “press any key” prompt.- Line 800 contains a bare
RUN, which has no effect when reached normally but serves as a safety net if execution somehow falls through.
Notable Techniques and Anomalies
- Using
CHR$ 10(newline) as a flavour tile character for choice 5 is an unorthodox trick; on the ZX81 this may produce unexpected display artefacts rather than a clean pattern. - The loop variable
Ris reused: first as the decoded character code (lines 190–210), then as the row counter in the cone-drawing loop (lines 280–350). This is safe becauseI$andJ$have already captured the character by line 240, but it is a potential source of confusion. - The cone step is
STEP -2and prints on both rowRandR-1, so rows 11–20 are covered, but the widening increments once per two-row pair, giving the cone a somewhat blocky profile. - Line 700 contains a
SAVEcommand with an inverse-video zero in the filename, which encodes auto-run behaviour on load.
Content
Source Code
5 REM ICE CREAM CONE
10 SLOW
15 PRINT "ICE CREAM CONE MAKER",,,
20 PRINT "1-CHOCOLATE"
30 PRINT "2-PEANUT BUTTER FUDGE"
40 PRINT "3-BUTTERSCOTCH"
50 PRINT "4-PEPPERMINT"
60 PRINT "5-MOLASSES LACE"
70 PRINT "6-CANDY STRIPE"
80 PRINT "7-CHOCOLATE CHIP"
90 PRINT
100 PRINT "ENTER NR OF CHOICE"
110 FOR X=1 TO 2
120 PRINT
130 PRINT "WHAT FLAVOR DO YOU WANT"
140 PRINT "FOR SCOOP NUMBER ";X;"? "
150 LET R$=INKEY$
160 IF R$="" THEN GOTO 150
170 IF CODE R$<29 OR CODE R$>35 THEN GOTO 150
180 PRINT R$
190 LET R=VAL R$+127
200 IF R=129 THEN LET R=137
210 IF R=132 THEN LET R=10
220 IF X=1 THEN LET I$=CHR$ R
230 IF X=2 THEN LET J$=CHR$ R
240 NEXT X
250 CLS
260 LET A=15
270 LET B=A
280 FOR R=20 TO 11 STEP -2
290 FOR C=A TO B
300 PRINT AT R,C;CHR$ 136
310 PRINT AT R-1,C;CHR$ 136
320 NEXT C
330 LET A=A-1
340 LET B=B+1
350 NEXT R
360 FOR C=9 TO 21
370 PRINT AT 7,C;I$
380 PRINT AT 8,C;I$
390 IF C<10 OR C>20 THEN GOTO 420
400 PRINT AT 6,C;I$
410 PRINT AT 9,C;I$
420 IF C<11 OR C>19 THEN GOTO 450
430 PRINT AT 5,C;I$
440 PRINT AT 10,C;I$
450 NEXT C
460 FOR C=10 TO 20
470 PRINT AT 2,C;J$
480 PRINT AT 3,C;J$
490 IF C<11 OR C>19 THEN GOTO 520
500 PRINT AT 1,C;J$
510 PRINT AT 4,C;J$
520 IF C<12 OR C>18 THEN GOTO 540
530 PRINT AT 0,C;J$
540 NEXT C
550 PAUSE 123
560 PRINT AT 21,1;"PRESS ANY KEY FOR ANOTHER CONE."
570 LET R$=INKEY$
580 IF R$="" THEN GOTO 570
590 CLS
600 GOTO 20
700 SAVE "1003%0"
800 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
