Art for All Ages is a full-featured pixel art and text drawing program that combines joystick-controlled cursor movement with keyboard input to let users create images on the high-resolution screen. The program uses STICK to read a joystick on port 2 for a paint/erase toggle and port 1 for eight-directional cursor movement, mapping the stick value directly to subroutine addresses via computed GO SUB (e.g., line 160: `GO SUB (500+(a*10))`). Machine code routines are POKEd into memory starting at address 59000 during initialization and called via USR for operations including PICK, PUT, block fill, screen backup/restore, and erase mode. The status line is maintained in a 32-character string variable `x$` whose individual character positions track current mode indicators such as ink color, paper color, caps lock state, flash, bright, over, inverse, and erase flags. Screen attributes are manipulated directly via PEEK and POKE on the display file at address 22528, and ON ERR is used for error trapping throughout.
Program Analysis
Program Structure
The program begins at line 10 with GO TO 9040, jumping to an initialization block that loads external screen and code files, POKEs machine code into high memory, sets up variables, and then drops into the main loop at line 20. The main loop (lines 20–420) reads the cursor position from system variables, handles attribute display, polls the keyboard and joystick, and dispatches to appropriate subroutines. Direction subroutines occupy lines 510–680, command/mode subroutines occupy lines 1003–2209, utility/input routines span lines 2300–3560, validation code is at 3700–3920, and the error handler is at 4000–4140. Settings and configuration live at lines 5000–5300. Initialization code at lines 9000–9300 handles loading, machine code installation, and variable setup.
Main Loop and Input Dispatch
The main loop at lines 20–420 performs several tasks each iteration. Lines 20–30 read the current text cursor position using PEEK 23688 and PEEK 23689 (the system variable COORDS equivalents for the print position). Lines 67–68 handle the plot cursor display. Line 70 reads a keypress via CODE INKEY$ into variable a. Lines 75–95 implement a key-repeat suppression mechanism using variables r (last key) and s (repeat counter). Line 100 reads joystick port 2 via STICK (2,1) to check for a draw/erase toggle, while line 115 reads joystick port 1 via STICK (1,1) for directional movement.
Computed GO SUB for Direction Dispatch
Eight-directional movement is dispatched via the computed subroutine call at line 160:GO SUB (500+(a*10))
Since STICK (1,1) returns values 1–8 for the eight directions, this maps neatly to subroutines at lines 510, 520, 540, 550, 560, 580, 590, and 600, each adjusting xx and yy accordingly and jumping to the shared boundary-clamp and plot code at line 640. Line 630 sets c=4 to signal cursor movement without drawing.
Machine Code Installation and USR Calls
The initialization block at lines 9120–9290 POKEs 277 bytes of Z80 machine code into addresses 59000–59276 using a FOR/READ/POKE loop reading from DATA statements. The installed routines include:
- 59000 — Auto-backup toggle / screen save
- 59001 — Screen backup
- 59013 — Screen restore
- 59039 — PICK (copy region from screen to buffer)
- 59128 — Plot PUT (paste buffer pixel by pixel)
- 59183 — Block PUT (paste buffer as block)
These routines are called throughout the program using LET z= USR addr, with setup parameters POKEd into specific addresses within the machine code block immediately before each call. The variable l holds the active PUT routine address (either 59128 or 59183), selectable via the settings menu.
PICK and PUT Implementation
The PICK operation (line 2185–2189) captures a rectangular region defined by corner coordinates (z6,z7) and (xx,yy). It calculates width (w1), height (w2), bit offsets, and attribute file address (w3), then POKEs all parameters into the machine code block before calling USR 59039. The PUT operation (lines 2150–2154, 2400–2430) pastes the picked region at the cursor position, with options for block or transparent placement, attribute copying, and alignment. The variable l1 controls whether the destination is erased before pasting.
Status Line Maintenance
A 32-character string x$ is used as a live status bar displayed on the lower screen. Individual character positions track distinct state flags:
| Position(s) | Content |
|---|---|
| 1–12 | Mode name (e.g., “NORMAL LOCK”, “COMMAND MODE”, “GRAPHIC MODE”) |
| 17 | Current INK color digit |
| 24 | Current PAPER color digit |
| 26 | “I” when INVERSE is on |
| 27 | “E” when ERASE MODE is on |
| 28 | “f”/”F” for FLASH state |
| 29 | “b”/”B” for BRIGHT state |
| 30 | “O” when OVER is on |
| 32 | “W”/”M” for draw mode |
Attribute Manipulation
The program directly manipulates screen attributes via the display file. Lines 45–65 compute the attribute address as ad = ((y*32)+x)+22528, save the original attribute in at, and force the high bit set (au=au+128 if au<128) to create a block cursor effect via POKE. When the cursor moves or a key is processed, the original attribute is restored with POKE ad,at at line 200.
Error Handling
ON ERR is used extensively for graceful recovery. Line 9110 establishes a global handler pointing to line 4000. The error handler at lines 4000–4140 inspects system variables (PEEK 23739 for error code, PEEK 23736/23737 for error line) and offers either silent recovery or an end-of-session prompt. Temporary ON ERR overrides are placed at lines 138, 1007 (during backup), 3860 (during DRAW), and 3890 (after DRAW) to localize error recovery for specific risky operations, with ON ERR CONTINUE used at line 4110 to resume if the user declines to end the session.
Graphics Operations
The program supports PLOT, DRAW (with arc parameter), CIRCLE, and square drawing, all entered via INPUT prompts. Coordinate validation at lines 3700–3830 checks all parameters against screen bounds before executing the operation. The block fill routine at lines 2090–2094 uses PLOT/DRAW to fill a rectangular region, supporting fill, invert (OVER 1), and erase (INVERSE 1) modes. A shape-fill routine at lines 2205–2209 attempts scanline fill using POINT to detect boundaries, though lines 2207–2209 appear after a RETURN at line 2206, making them unreachable dead code.
UDG Definition
Lines 3400–3560 provide an interactive UDG (user-defined graphics) editor. The user selects a letter (a–u), then enters eight rows as binary strings of ‘0’ and ‘1’ characters. Each row is converted to a byte by summing 2^(8-i) for each ‘1’ bit, stored in array u(), then POKEd into the UDG area via POKE USR z$+i, u(i+1).
Initialization Details
The DATA at line 9080 initializes most variables to 0 by chaining them: cs=0, then gr=cs (=0), cl=cs (=0), etc. Notable non-zero initial values are i1=1 (INVERSE on), w4=9 (no PICK done yet, used as sentinel at line 2150), and l=59183 (block PUT mode). The NOT PI expression evaluates to 0 and is used throughout the DATA statements and initialization as a zero literal, a common memory-saving idiom. The string x$ is initialized at line 9100 to " NORMAL LOCK INK0 PAPER7 W", pre-populating all status positions.
Notable Anomalies
- Line 9140 (
NEXT o) appears after the FOR/READ/POKE loop already has its ownNEXT oat line 9130, creating a syntax anomaly — this line would cause aNEXT without FORerror and is likely a duplicate artifact. - Lines 2207–2209 are unreachable because line 2206 ends with
RETURN; the shape-fill logic is incomplete dead code. - Line 9170 contains
NOT PI,Zin DATA — sinceZis an uninitialized variable at that point (value 0), this is equivalent to0,0, likely intentional. - Line 95 references
LET r=S— uppercaseSis a separate variable from lowercases, making this assignment setrto whateverSholds (likely 0), which appears to be the intended reset behavior. - Line 210 sets
LET p=M(uppercase), a separate variable from lowercasemset to 0 on the same line — likely intentional use of a persistent variable.
Content
Source Code
10 GO TO 9040
20 LET x=33- PEEK 23688
30 LET y=24- PEEK 23689
40 IF a7=1 THEN GO TO 67
45 LET ad=((y*32)+x)+22528
50 LET at= PEEK ad
55 LET au=at
60 IF au<128 THEN LET au=au+128
65 POKE ad,au
67 IF dt=1 THEN IF a5=1 THEN LET p= POINT (xx,yy)
68 IF a6=0 THEN PLOT OVER 1; INK 8; PAPER 8; INVERSE 0;xx,yy:LET p= NOT p
70 LET a= CODE INKEY$
75 IF a=0 THEN GO TO 95
80 IF r <>a THEN GO TO 180
85 IF s>0 THEN GO TO 190
90 LET s=s+1:GO TO 100
95 LET s=0:LET r=S
100 LET a=STICK (2,1)
105 IF a=1 THEN IF q=0 THEN GO SUB 2175
110 LET q=a
115 LET a=STICK (1,1)
120 IF a <>0 THEN GO TO 150
122 IF m <>0 THEN GO TO 68
125 IF c=4 THEN LET c=0:GO TO 20
128 LET m=1
130 IF p1=0 THEN GO TO 68
135 PRINT #1; AT 1,4;"x-";xx;" y-";yy;" "
138 ON ERR GO TO 4000
140 PRINT #1;p$;x$:GO TO 68
150 IF p=1 THEN PLOT OVER 1; INK 8; PAPER 8; INVERSE 0;xx,yy:LET p=0
160 GO SUB (500+(a*10))
170 GO TO 65
180 LET s=0
190 IF p=1 THEN PLOT OVER 1; INK 8; PAPER 8; INVERSE 0;xx,yy
200 IF a7=0 THEN POKE ad,at
210 LET r=a:LET m=0:LET p=M
220 LET b=a+1000
230 LET c=0
240 IF a<97 THEN GO TO 270
250 IF a>122 THEN GO TO 330
260 IF cl=1 THEN IF cs=0 THEN IF gr=0 THEN LET a=a-32:LET b=b-32:GO TO 330
265 GO TO 290
270 IF a<48 THEN GO TO 330
280 IF a>57 THEN GO TO 320
290 IF cs=2 THEN LET b=1600+(a*5):LET c=3
300 IF gr <>0 THEN LET b=a+1300:LET c=0
310 IF cs=1 THEN LET b=1600+(a*5):LET c=1
320 IF cl=1 THEN IF cs=0 THEN IF gr=CS THEN IF a>64 THEN IF a<91 THEN LET a=a+32:LET b=b+32
330 GO SUB b
340 IF c=4 THEN GO TO 67
350 IF c=3 THEN GO TO 20
360 IF cs=1 THEN LET cs=cs1:LET x$( TO 12)=w$
370 IF gr=1 THEN LET gr=gr1:LET x$( TO 12)=w$
380 IF c=2 THEN IF DT=1 THEN PRINT " "; CHR$ 8;
390 IF c <>0 THEN GO TO 20
400 PRINT CHR$ a;
410 IF x=31 THEN IF y=21 THEN POKE 23692,255:PRINT AT y,x;
420 GO TO 20
510 LET yy=yy+1:GO TO 640
520 LET yy=yy-1:GO TO 640
540 LET xx=xx-1:GO TO 640
550 LET yy=yy+1:LET xx=xx-1:GO TO 640
560 LET yy=yy-1:LET xx=xx-1:GO TO 640
580 LET xx=xx+1:GO TO 640
590 LET yy=yy+1:LET xx=xx+1:GO TO 640
600 LET yy=yy-1:LET xx=xx+1:GO TO 640
630 LET c=4
640 IF xx<0 THEN LET xx=0
650 IF yy<0 THEN LET yy=0
660 IF xx>255 THEN LET xx=255
670 IF yy>175 THEN LET yy=175
680 IF a5=0 THEN PLOT xx,yy
685 PRINT #1; AT 1,4;"x-";xx;" y-";yy;" "
690 RETURN
1003 LET c=2:RETURN
1004 LET c=1:LET cs=2:LET gr=0:LET cl=GR:LET x$( TO 12)="COMMAND LOCK":RETURN
1005 LET c=1:LET cl=0:LET dt=CL:LET cs=CL:LET gr=CL:LET x$( TO 12)=" NORMAL LOCK":RETURN
1006 LET c=1:LET cl=C:LET gr=0:LET cs=GR:LET x$( TO 12)=" CAPS LOCK":RETURN
1007 PRINT #1;p$;" BACKUP",:LET z= USR 59001:LET c=1:PAUSE 20:INPUT "":RETURN
1008 IF x+y <>0 THEN PRINT CHR$ 8;:LET c=2:RETURN
1011 GO TO 3000
1012 IF x+y <>0 THEN PRINT INVERSE 0; OVER 0; BRIGHT 0; FLASH 0; CHR$ 8;" "; CHR$ 8;:LET c=1:RETURN
1013 GO TO 3000
1014 LET cs1=cs:LET cs=1:LET c=3:LET w$=x$( TO 12):LET x$( TO 12)="COMMAND MODE":RETURN
1015 LET gr1=gr:LET gr=1:LET c=3:LET w$=x$( TO 12):LET x$( TO 12)="GRAPHIC MODE":RETURN
1031 LET c=1
1171 RETURN
1172 LET a=127
1194 RETURN
1195 LET c=1:RETURN
1197 LET a=93:RETURN
1198 LET a=91
1201 RETURN
1203 LET a=125:RETURN
1204 LET a=123:RETURN
1205 LET a=92
1225 RETURN
1255 LET c=1:RETURN
1355 LET a=a+80:RETURN
1356 LET a=128:RETURN
1396 LET c=2:RETURN
1417 LET a=(a+47):RETURN
1555 LET c=2
1839 RETURN
1840 INPUT "Restore screen? <n,y>";z$:IF z$ <>"Y" THEN IF z$ <>"y" THEN RETURN
1841 LET z= USR 59013:LET c=1:RETURN
1845 LET i1= NOT i1
1846 INVERSE i1
1847 IF i1=1 THEN LET x$(26)="I"
1848 IF i1=0 THEN LET x$(26)=" "
1849 LET c=1:RETURN
1850 INPUT "PLOT CURSOR on/off? <n,y>";z$:IF z$ <>"Y" THEN IF z$ <>"y" THEN GO TO 1852
1851 LET a6= NOT a6:GO TO 1852
1852 INPUT "BLOCK CURSOR on/off? <n,y>";z$:IF z$ <>"Y" THEN IF z$ <>"y" THEN RETURN
1853 LET a7= NOT a7:RETURN
1855 INPUT "LOAD picture? <n,y>";z$:IF z$ <>"Y" THEN IF z$ <>"y" THEN RETURN
1856 INPUT "PICTURE filename? ";f$
1857 IF LEN f$>10 THEN LET f$=f$( TO 10)
1858 INPUT "start tape, then press ENTER ";z$
1859 LOAD f$ SCREEN$ :RETURN
1860 INPUT "SAVE picture? <n,y>";z$:IF z$ <>"Y" THEN IF z$ <>"y" THEN RETURN
1861 INPUT "PICTURE filename? ";f$:IF LEN f$=0 THEN LET f$="picture"
1862 IF LEN f$>10 THEN LET f$=f$( TO 10)
1863 SAVE f$ SCREEN$
1864 RETURN
1865 INPUT "LOAD graphics? <n,y>";z$:IF z$ <>"Y" THEN IF z$ <>"y" THEN RETURN
1866 INPUT "start tape, then press ENTER ";z$
1867 LET z= USR 59001:LOAD "graphics"CODE USR "a",168:LET z= USR 59013:RETURN
1870 INPUT "SAVE graphics? <n,y>";z$:IF z$ <>"Y" THEN IF z$ <>"y" THEN RETURN
1871 SAVE "graphics"CODE USR "a",168:RETURN
1875 IF dt=1 THEN GO TO 1878
1876 INPUT "switch ERASE MODE ON? <n,y>";z$:IF z$ <>"Y" THEN IF z$ <>"y" THEN RETURN
1877 LET z= USR 59000:LET dt=1:LET x$(27)="E":RETURN
1878 INPUT "switch ERASE MODE OFF? <n,y>";z$:IF z$ <>"Y" THEN IF z$ <>"y" THEN RETURN
1879 LET z= USR 59000:LET dt=0:LET x$(27)=" ":RETURN
1880 INPUT "Clear the screen? <n,y> ";z$
1881 IF z$ <>"Y" THEN IF z$ <>"y" THEN RETURN
1882 LET z= USR 59001:CLS
1883 LET xx=0:LET yy=XX:PLOT xx,yy
1884 RETURN
1885 LET cs=0:LET cl=CS
1886 LET x$( TO 12)="GRAPHIC LOCK"
1887 LET gr=2
2084 RETURN
2085 LET xx=xx-1:GO TO 630
2090 LET z= USR 59000:INPUT "BLOCK (Fill,Invert,Erase)?";z$:IF z$ <>"f" THEN IF z$ <>"i" THEN IF z$ <>"e" THEN IF z$ <>"F" THEN IF z$ <>"I" THEN IF z$ <>"E" THEN RETURN
2091 IF z6>xx OR yy>z7 THEN GO SUB 2300
2092 OVER 0:INVERSE 0:IF z$="i" OR z$="I" THEN OVER 1
2093 LET i=xx-z6:IF z$="e" OR z$="E" THEN INVERSE 1
2094 FOR j=z7 TO yy STEP -1:PLOT z6,j:DRAW i,0:NEXT j:PLOT xx,yy:OVER a3:INVERSE i1:RETURN
2095 LET yy=yy-1:LET xx=xx+1:GO TO 630
2100 LET xx=xx+1:GO TO 630
2105 LET yy=yy+1:LET xx=xx+1:GO TO 630
2110 LET z= USR 59000
2111 INPUT "PLOT x- ";z1;" y- ";z2
2112 GO TO 3700
2113 LET xx=z1:LET yy=z2
2114 PLOT INVERSE a5;z1,z2:RETURN
2115 LET z= USR 59000
2116 INPUT "DRAW x-";z1;" y-";z2;" arc-";z3
2117 GO TO 3700
2120 LET z= USR 59000
2121 INPUT "CIRCLE x-";z1;" y-";z2;" radius-";z3
2122 GO TO 3700
2123 CIRCLE z1,z2,z3:RETURN
2125 INPUT "INK COLOR- ", LINE z$:GO TO 3300
2130 LET z= USR 59000
2131 INPUT "SQUARE x-";z1;" y-";z2;" sides-";z3
2132 LET z3=(z3/2):GO TO 3700
2133 PLOT z1-z3,z2+z3:DRAW (z3*2),0:DRAW 0,-(z3*2)
2134 DRAW -(z3*2),0:DRAW 0,(z3*2):RETURN
2135 GO TO 3400
2140 INPUT "BORDER COLOR- ", LINE z$
2141 GO TO 3300
2145 GO TO 5000
2150 IF w4=9 THEN PRINT #1;p$;" YOU MUST PICK BEFORE YOU PUT",:BEEP .5,7:PAUSE 40:RETURN
2151 PRINT #1;p$;" PUT",:LET z= USR 59000:LET w6=(yy+w4-(yy- INT (yy/8)*8)):LET x1=((INT (xx/8))*8)+w9:IF l <>59183 THEN LET w6=yy:LET x1=xx:LET w9=xx-((INT (xx/8))*8)
2152 LET x2=(255-x1):IF w5<x2 THEN LET x2=w5
2153 POKE 59129,2↑(7-(xx-((INT (xx/8))*8))):LET w7=w6+1:IF w7>w2 THEN LET w7=w2
2154 LET w3=22528+(INT ((175-w6)/8)*32)+ INT (xx/8):GO TO 2400
2155 INPUT "PAPER COLOR- ", LINE z$:GO TO 3300
2160 INPUT "PRINTER Ready? <n,y>";z$:IF z$ <>"Y" THEN IF z$ <>"y" THEN RETURN
2161 COPY :RETURN
2165 LET yy=yy+1:LET xx=xx-1:GO TO 630
2170 PRINT #1;p$;" DEFINE AREA",:PAUSE 20:INPUT ""
2171 LET z6=xx:LET z7=yy:RETURN
2175 LET c=4:LET m=0
2176 IF a5=1 THEN LET a5=0:LET x$(32)="W":RETURN
2177 IF a5=0 THEN LET a5=1:LET x$(32)="M":RETURN
2180 LET z= USR 59000:PLOT z6,z7
2181 DRAW xx-z6,yy-z7
2182 RETURN
2185 PRINT #1;p$;" PICK",:IF z6>xx OR yy>z7 THEN GO SUB 2300
2186 LET w1= INT (INT (xx/8)- INT (z6/8)+1):LET w2=(1+z7)-yy:LET w4=z7-(INT (z7/8)*8):POKE 59082,2↑(7-(xx-((INT (xx/8))*8))):LET w9=(z6-((INT (z6/8))*8)):POKE 59135,2↑(7-w9):POKE 59065,2↑(7-w9)
2187 LET w5=xx-z6:LET w3=22528+(INT ((175-z7)/8)*32)+ INT (z6/8):POKE 59121, INT (w3/256):POKE 59120,(w3-(INT (w3/256)*256))
2188 POKE 59038,w2:POKE 59054,z7:POKE 59053,z6:POKE 59062,w1
2189 LET z= USR 59039:POKE 59059,32:POKE 59060,203:RETURN
2190 GO TO 2750
2195 LET yy=yy+1:GO TO 630
2200 LET yy=yy-1:GO TO 630
2205 PRINT #1;p$;" FILLING SHAPE",:IF z6>xx OR yy>z7 THEN GO SUB 2300
2206 FOR j=z7 TO yy STEP -1:LET z9=0:LET z8=i1:FOR i=z6 TO xx:IF POINT (i,j)=0 THEN LET z9=z9+1:NEXT i:NEXT j:RETURN
2207 IF z8=0 OR z9<2 THEN PLOT i,j:LET z8=1:LET z9=0
2208 IF z9 <>0 THEN IF z8=1 THEN DRAW z9,0:LET z8=0:LET z9=Z8
2209 NEXT i:NEXT j:RETURN
2210 LET yy=yy-1:LET xx=xx-1:GO TO 630
2300 IF yy>z7 THEN LET z=z7:LET z7=yy:LET yy=z
2310 IF z6>xx THEN LET z=z6:LET z6=xx:LET xx=z
2320 RETURN
2400 LET w8= INT ((263-xx)/8):IF w8>w1 THEN LET w8=w1
2410 IF l1=0 THEN FOR j=w6 TO ((w6-w7)+1) STEP -1:PLOT OVER 0; INVERSE 1;x1,j:DRAW OVER 0; INVERSE 1;x2,0:NEXT j:PLOT INVERSE 1;xx,yy
2420 POKE 59240, INT (w3/256):POKE 59239,(w3-(INT (w3/256)*256)):POKE 59276,w7:POKE 59185,w6:POKE 59184,xx:POKE 59275, INT ((w7/8)+((w6/8)- INT (w6/8))+.85)
2430 POKE 59194,w8:POKE 59233,w8:LET z= USR l:POKE 59191,32:POKE 59192,203:POKE 59236,33:POKE 59237,227:RETURN
2750 INPUT ("BRIGHT <";a2;"> <0,1,8> ");z$
2760 IF z$="" THEN GO TO 2790
2770 IF z$ <>"0" THEN IF z$ <>"1" THEN IF z$ <>"8" THEN GO TO 2750
2780 LET a2= VAL z$
2790 INPUT ("FLASH <";a1;"> <0,1,8> ");z$
2800 IF z$="" THEN GO TO 2830
2810 IF z$ <>"0" THEN IF z$ <>"1" THEN IF z$ <>"8" THEN GO TO 2790
2820 LET a1= VAL z$
2830 INPUT ("OVER <";a3;"> <0,1> ");z$
2840 IF z$="" THEN GO TO 2870
2850 IF z$ <>"0" THEN IF z$ <>"1" THEN GO TO 2830
2860 LET a3= VAL z$
2870 IF a1=8 THEN LET x$(28)="f":FLASH 8
2880 IF a1=1 THEN LET x$(28)="F":FLASH 1
2890 IF a1=0 THEN LET x$(28)=" ":FLASH 0
2900 IF a2=8 THEN LET x$(29)="b":BRIGHT 8
2910 IF a2=1 THEN LET x$(29)="B":BRIGHT 1
2920 IF a2=0 THEN LET x$(29)=" ":BRIGHT 0
2930 IF a3=1 THEN LET x$(30)="O":OVER 1
2940 IF a3=0 THEN LET x$(30)=" ":OVER 0
2950 RETURN
3000 LET c=3
3010 LET x=33- PEEK 23688
3020 LET y=24- PEEK 23689
3030 IF a=10 THEN LET y=y+1
3040 IF a=11 THEN LET y=y-1
3050 IF a=9 THEN LET x=x+1
3060 IF a=13 THEN LET y=y+1:LET x=0
3070 IF y<0 THEN LET y=0
3080 IF x<0 THEN LET x=0
3090 IF y>21 THEN LET y=21
3100 IF x>31 THEN LET x=31
3110 PRINT AT y,x;
3120 RETURN
3300 LET z=(CODE z$)-48
3310 IF z<0 THEN GO TO 3900
3320 IF z>9 THEN GO TO 3900
3330 IF a=111 THEN PAPER z:LET x$(24 TO 24)= STR$ z
3340 IF a=105 THEN INK z:LET x$(17 TO 17)= STR$ z
3350 IF z>7 THEN GO TO 3900
3360 IF a=108 THEN BORDER z:INPUT ""
3370 LET c=1:RETURN
3400 INPUT "define GRAPHICS? <n,y>";z$:IF z$ <>"Y" THEN IF z$ <>"y" THEN RETURN
3405 INPUT "GRAPHICS define letter - ";z$
3410 LET z=(CODE z$)-96
3420 IF z<1 THEN RETURN
3430 IF z>21 THEN RETURN
3440 LET z$= CHR$ (z+64)
3450 FOR j=1 TO 8
3460 INPUT ("define ROW ";j;" -"), LINE g$
3470 LET u(j)=0
3480 LET g= LEN g$:IF g>8 THEN LET g=8
3490 FOR i=1 TO g
3500 IF g$(i)="1" THEN LET u(j)=u(j)+2↑(8-i)
3510 NEXT i
3520 NEXT j
3530 FOR i=0 TO 7
3540 POKE USR z$+i,u(i+1)
3550 NEXT i
3560 RETURN
3700 LET z4= PEEK 23677
3710 LET z5= PEEK 23678
3720 IF z1>255 THEN GO TO 3900
3730 IF z1<0 THEN GO TO 3900
3740 IF z2>175 THEN GO TO 3900
3750 IF z2<0 THEN GO TO 3900
3760 IF a=102 THEN GO TO 2113
3770 IF a=103 THEN GO TO 3840
3780 IF z3<0 THEN GO TO 3900
3790 IF z1+z3>255 THEN GO TO 3900
3800 IF z2-z3<0 THEN GO TO 3900
3810 IF z2+z3>175 THEN GO TO 3900
3820 IF z1-z3<0 THEN GO TO 3900
3830 GO TO b+3
3840 IF z1-z4<-255 THEN GO TO 3900
3850 IF z2-z5<-175 THEN GO TO 3900
3860 ON ERR GO TO 3900
3870 DRAW z1-z4,z2-z5,z3
3880 LET xx=z1:LET yy=z2
3890 PLOT z1,z2:ON ERR GO TO 4000:RETURN
3900 PRINT #1;p$;" ERROR",:BEEP .5,7:PAUSE 40
3910 ON ERR GO TO 4000
3920 GO TO 20
4000 IF PEEK 23739=21 THEN GO TO 4100
4010 IF (PEEK 23736+256* PEEK 23737)>999 THEN GO TO 20
4020 INPUT ("ERR"; PEEK 23739;" LINE ";(PEEK 23736+256* PEEK 23737);":"; PEEK 23738;);z$
4100 INPUT "END of session? <n,y>";z$
4110 IF z$ <>"Y" THEN IF z$ <>"y" THEN ON ERR CONTINUE
4120 LET z= USR 59000
4130 ON ERR RESET
4140 STOP
5000 IF p1=0 THEN GO TO 5030
5010 INPUT "Display Line off? <n,y>";z$:IF z$ <>"Y" THEN IF z$ <>"y" THEN GO TO 5050
5020 LET p1=0:GO TO 5050
5030 INPUT "Display Line on? <n,y>";z$:IF z$ <>"Y" THEN IF z$ <>"y" THEN GO TO 5050
5040 LET p1=1
5050 IF PEEK 59000=0 THEN GO TO 5080
5070 POKE 59000,0:GO TO 5100
5080 INPUT "Auto Backup off? <n,y>";z$:IF z$ <>"Y" THEN IF z$ <>"y" THEN GO TO 5100
5090 POKE 59000,201
5100 INPUT "change PUT setup? <n,y>";z$:IF z$ <>"Y" THEN IF z$ <>"y" THEN GO TO 5300
5110 IF l=59183 THEN GO TO 5140
5120 INPUT "Block PUT ? <n,y>";z$:IF z$ <>"Y" THEN IF z$ <>"y" THEN GO TO 5160
5130 LET l=59183:GO TO 5160
5140 INPUT "Plot PUT ? <n,y>";z$:IF z$ <>"Y" THEN IF z$ <>"y" THEN GO TO 5160
5150 LET l=59128
5160 IF PEEK 59231=0 THEN GO TO 5190
5170 INPUT "Move PUT ATTRIBUTES? <n,y>";z$:IF z$ <>"Y" THEN IF z$ <>"y" THEN GO TO 5210
5180 POKE 59231,0:GO TO 5210
5190 INPUT "No ATTRIBUTES on PUT ? <n,y>";z$:IF z$ <>"Y" THEN IF z$ <>"y" THEN GO TO 5210
5200 POKE 59231,201
5210 IF l1=1 THEN GO TO 5240
5220 INPUT "Transparent PUT ? <n,y>";z$:IF z$ <>"Y" THEN IF z$ <>"y" THEN GO TO 5300
5230 LET l1=1:GO TO 5300
5240 INPUT "Erase before PUT ? <n,y>";z$:IF z$ <>"Y" THEN IF z$ <>"y" THEN GO TO 5300
5250 LET l1=0
5300 INPUT "RUN User Routine? <n,y>";z$:IF z$ <>"Y" THEN IF z$ <>"y" THEN RETURN
5310 PRINT #1;p$;" RUNNING User Routine",
8999 RETURN
9000 BRIGHT NOT PI:OVER NOT PI:FLASH NOT PI:INVERSE NOT PI:INK 7:PAPER 7:CLEAR 44999:PRINT AT 19,0:LOAD "art 2.27 C"SCREEN$ :PAUSE 300
9010 LOAD "art 2.27 D"CODE USR "a",168
9020 REM 21,;;"THE TAPE"
9030 INPUT " press ENTER to start ";z$
9040 BORDER 5:PAPER 7:INK NOT PI
9050 LET p$= CHR$ 22+ CHR$ 0+ CHR$ 0
9060 PRINT #1; AT 1, NOT PI;" INITIALIZING"," ART FOR ALL AGES ©1983 CONLON"
9070 RESTORE :READ cs,gr,cl,dt,xx,yy,a7,a6,a5,a4,a3,a2,a1,z6,z7,c,m,p,q,r,s,t,i1,l1,p1,w4,l
9080 DATA 0,cs,cs,cs,cs,cs,cs,cs,cs,cs,cs,cs,cs,cs,cs,cs,c,c,c,c,c,q,1,i1,i1,9,59183
9090 DIM u(8)
9100 LET x$=" NORMAL LOCK INK0 PAPER7 W"
9110 ON ERR GO TO 4000
9120 FOR o=59000 TO 59276
9130 READ z:POKE o,z:NEXT o
9140 NEXT o
9150 DATA 0,1, NOT PI,27,33, NOT PI,64,17,200,175,237,176,201
9160 DATA 1, NOT PI,27,33,200,175,17, NOT PI,64,237,176,201
9170 DATA 33, NOT PI,Z,229,Z,33,87, NOT PI,229,205, NOT PI,98,201
9180 DATA 0,33,32,203,1,194,26,54, NOT PI,237,161,234,165,230
9190 DATA 1, NOT PI,Z,205,145,230
9200 DATA 17,32,203,1,Z, NOT PI,62, NOT PI,Z,203,39,214,1,166,18,19,237,161,226,201,230,237,176
9210 DATA 62,1,214,1,47,235,43,166,119,33,174,230,70,5,112
9220 DATA 237,91,179,230,33,32, NOT PI,25,34,179,230
9230 DATA 33,158,230,126,61,119,194,172,230
9240 DATA 1, NOT PI,3,33, NOT PI,88,17,33,227,237,176,201
9250 DATA 62, NOT PI,1, NOT PI,22,245,254, NOT PI,202,40,231,210,23,231,167,33,32,203,Z,30,237,161,234,10,231,241,7, NOT PI,195,250,230
9260 DATA 167,33,32,225,203,22,237,169,234,27,231,241,15, NOT PI,195,250,230,241,58,249,230,50,255,230,1, NOT PI,Z,205,145,230
9270 DATA 235,33,32,203,1,Z, NOT PI,26,182,18,19,237,161,234,60,231,33,49,231,70,5,112,237,91,55,231,33,32, NOT PI,25,34,55,231,33,140,231,126,61,119,194,47,231,0
9280 DATA 1,Z, NOT PI,33,Z,227,17, NOT PI,88,237,176,237,91,100,231,33,32, NOT PI,25,34,100,231,237,91,103,231,33,32, NOT PI,25,34,103,231,33,139,231,126,61,119,194,96,231,201, NOT PI,Z
9290 POKE 23692,255
9300 GO TO 20
9310 REM for TIMEX 2068 Ver. 2.27 11/16/83 1983 by R.E. Conlon
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
