This program draws a pie chart on screen using BASIC combined with TASWIDE — a utility that switches the display to a 64-column wide text mode. The user inputs the number of slices, a percentage and label for each, and a flag to “pull” (offset) individual slices outward from the centre. Drawing uses PLOT and DRAW with the three-argument arc form (DRAW dx,dy,-angle) to render each sector. Labels are positioned using trigonometry to place them outside the circle, with a horizontal nudge applied for slices in the left half of the chart. The program also formats percentage output with conditional string concatenation to ensure consistent decimal display (e.g. appending “.00” or “0” as needed).
Program Structure
The program is organised into a linear sequence of phases:
- Lines 1–8: Header REMs, display initialisation, and a guard warning the user to load the TASWIDE machine-code utility before continuing.
- Lines 10–34: Data entry loop — number of slices, percentage, “pull” flag, and label for each slice; a running total is shown at line 21.
- Line 35: Rounds each percentage to two decimal places using
INT(e(a)*100+.5)/100. - Lines 43–46: Collects chart titles, then calls the TASWIDE routine and switches to 64-column mode via
PRINT CHR$ 3. - Lines 50–70: Main drawing loop — computes angles, places labels, and draws each pie sector.
- Lines 80–91: Prints the percentage legend and titles.
- Lines 100–130: Post-display menu: copy to printer (
COPY), start a new graph (RUN), or loop.
Machine Code Usage
RANDOMIZE USR 64300 is called twice (lines 46 and 91). This invokes TASWIDE, a machine-code extension resident at address 64300 in RAM. The first call (line 46) presumably switches the display to 64-column mode; PRINT CHR$ 3 immediately after is a control code interpreted by TASWIDE. The second call (line 91) re-enters the 64-column mode, followed by PRINT CHR$ 2, likely switching back to 32-column mode for the main title at line 0. Without TASWIDE present, RANDOMIZE USR 64300 would crash or produce undefined behaviour — hence the prominent warning at lines 6–8.
Pie Sector Drawing
Each slice occupies an angular span A3 = PI/50 * E(A). This maps 100% to 2π (a full circle), since PI/50 × 100 = 2π. Each sector is drawn as two radial lines and an arc:
- Line 60: PLOT to centre (optionally offset by the pull vector), DRAW the leading radius.
- Line 61: PLOT to the same centre, DRAW the trailing radius.
- Line 62: DRAW arc closing the sector using the three-argument
DRAW dx,dy,-A3form, where the third argument is the arc angle in radians (negative = clockwise).
The centre is at pixel coordinates (132, 83) and the radius is 50 pixels. Pulled slices are offset by 10 pixels along the midpoint angle vector using the AND trick: 10*g1 AND P(A) evaluates to 10*g1 if P(A) is non-zero, or 0 otherwise.
Label Positioning
Line 52 positions each label outside the circle using PRINT AT row,col computed from the midpoint angle A2:
- Row:
11 - (60 + (10 AND P(A))) * g2 / 8— scales the sine of the midpoint angle into character rows. - Column:
32 + (60 + (10 AND P(A))) * g1 / 4 - (9 AND a2 > PI/2 AND a2 < 3*PI/2)— the subtraction of 9 nudges labels in the left semicircle leftward, compensating for text extending rightward from the AT position.
The use of boolean expressions as numeric values (e.g. 9 AND condition) is a classic Spectrum BASIC idiom where a true condition yields the left operand and false yields 0.
Percentage Formatting
Line 80 uses conditional string concatenation to produce consistent decimal output:
" " AND e(a)<10— prepends a space for single-digit values to align the legend.".00" AND e(a)=INT e(a)— appends.00if the value is a whole number."0" AND e(a)*10=INT(e(a)*10) AND e(a)<>INT e(a)— appends a trailing0if there is exactly one decimal digit.
Notable Techniques and Idioms
| Technique | Location | Purpose |
|---|---|---|
AND as conditional multiplier | Lines 52, 60, 61 | Applies pull offset only when P(A) is set |
| Three-argument DRAW (arc) | Line 62 | Draws curved sector boundary |
| PAUSE 0 keypress wait | Line 8 | Halts until any key is pressed |
| STR$ in INPUT prompt | Line 30 | Embeds the loop counter in the prompt string dynamically |
| RUN (no line number) | Line 120 | Restarts from line 1 for a new graph, clearing variables |
Content
Image Gallery
Source Code
1 REM PIE CHART
2 REM RESET by Ryan Gray, 9/30/84; ALL RIGHTS RESERVED
5 PAPER 0: INK 7: BRIGHT 0: OVER 0: INVERSE 0: FLASH 0: BORDER 0: CLS
6 PRINT "CAUTION! If TASWIDE is NOT in memory at this time, BREAK the program now and load TASWIDE then re-RUN PIE CHART"
7 PRINT ''"Otherwise press any key..."
8 PAUSE 0
10 INPUT "# OF PIECES:";N
11 IF N<2 THEN STOP
20 DIM E(N)
21 DIM P(N): DIM l$(n,10)
22 LET t=0: PRINT AT 21,16;"# OF PIECES:";n
30 FOR A=1 TO N: INPUT "PERCENT FOR #";STR$ A;":";E(A)
31 LET t=t+e(a): PRINT AT 21,0;"TOTAL:";t;"% "
32 INPUT "PULL PIECE? (1/0) ";P(A)
33 INPUT "LABEL:";l$(a)
34 NEXT a
35 FOR a=1 TO n: LET e(a)=INT (e(a)*100+.5)/100: NEXT a
43 PRINT AT 21,0;" "
44 INPUT "MAIN TITLE:";T$: INPUT "SUB TITLE:";s$
45 LET A1=0
46 RANDOMIZE USR 64300: PRINT CHR$ 3;
50 FOR A=1 TO N: LET A3=PI/50*E(A): LET A2=A1+A3/2
51 LET g1=COS a2: LET g2=SIN a2: LET h1=COS a1: LET h2=SIN a1: LET i1=COS (a1+a3): LET i2=SIN (a1+a3)
52 PRINT AT 11-(60+(10 AND P(A)))*g2/8,32+(60+(10 AND P(A)))*g1/4-(9 AND a2>PI/2 AND a2<3*PI/2);A;":";l$(a)
60 PLOT 132+(10*g1 AND P(A)),83+(10*g2 AND P(A)): DRAW 50*h1,50*h2
61 PLOT 132+(10*g1 AND P(A)),83+(10*g2 AND P(A)): DRAW 50*i1,50*i2
62 DRAW 50*h1-50*i1,50*h2-50*i2,-A3
65 LET A1=A1+A3
66 REM
70 NEXT A
80 FOR A=1 TO N: PRINT AT A+2,0;A;":";" " AND e(a)<10;E(A);".00" AND e(a)=INT e(a);"0" AND e(a)*10=INT (e(a)*10) AND e(a)<>INT e(a);"%": NEXT A
90 PRINT AT 1,INT ((64-LEN s$)/2);s$
91 RANDOMIZE USR 64300: PRINT CHR$ 2;AT 0,INT ((32-LEN T$)/2);T$
100 INPUT "C to COPY, N for new graph:";n$
110 IF n$="C" OR n$="c" THEN BEEP .01,0: COPY : BEEP .01,5: GO TO 100
120 IF n$="N" OR n$="n" THEN RUN
130 GO TO 100
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.