Art for All Ages

Developer(s): Bob Conlon
Date: 1983
Type: Program
Platform(s): TS 2068
Tags: Art

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–12Mode name (e.g., “NORMAL LOCK”, “COMMAND MODE”, “GRAPHIC MODE”)
17Current INK color digit
24Current 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 own NEXT o at line 9130, creating a syntax anomaly — this line would cause a NEXT without FOR error 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,Z in DATA — since Z is an uninitialized variable at that point (value 0), this is equivalent to 0,0, likely intentional.
  • Line 95 references LET r=S — uppercase S is a separate variable from lowercase s, making this assignment set r to whatever S holds (likely 0), which appears to be the intended reset behavior.
  • Line 210 sets LET p=M (uppercase), a separate variable from lowercase m set to 0 on the same line — likely intentional use of a persistent variable.

Content

Appears On

Related Products

Related Articles

Last month we explored the world of music through the program MUSICOLA for the TS2068. This month we continue our...

Related Content

Image Gallery

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.

Scroll to Top