Grafixx v1.9

Developer(s): Mark Szabo
Date: 198x
Type: Program
Platform(s): TS 2068
Tags: Graphics

A drawing program for the TS2068. A machine code routine moves the drawing cursor and shows its coordinates; when it returns, the program reads the cursor position and puts the first of three command menus on the bottom line. Menu 1 holds quit, clear, save and load SCREEN$, colours, text and block move. Menu 2 draws circles, lines, boxes and fills, and mirrors the picture. Menu 3 adds arcs, a coloured frame round the screen, a printer copy, “superfile” saving, a pixel magnifier, and paper and ink changes. Commands are upper-case letters, and several of them are steered with a joystick through STICK.

The REM lines read “GRAFIXX by Mark Szabo Version 1.9”. The title picture, shown with a chord from the AY sound chip, reads “BY MARK K. SZABO” and “THE ROAD TO FUN”, with T/S 2068 badges in the corners and “MKS 85” on the road.

Program Analysis

Structure

  • Line 60: loads grafixx C, 18000 bytes of machine code and data at 45500.
  • Line 90: plays a rising sweep with BEEP, shows the title picture with RANDOMIZE USR 58000 and sets the AY registers with SOUND. Line 110 silences the chip again.
  • Lines 120–250: the cursor call (LIST USR 60000), which leaves the X and Y coordinates in 55000 and 55001, and menu 1.
  • Lines 260–350: menu 2. Lines 360–470: menu 3.
  • Lines 480–600: places a line of text with the joystick, toggling it with OVER 1 until fire is pressed.
  • Lines 610–1010: the bottom-line beep, the 20-pixel selection frame, block capture into Q$, block stamping and the magnifier.
  • Lines 1030–1200: the box command, which stretches a box with the joystick and can fill it line by line.
  • Line 1210: saves the program and its code.

Commands

  • Menu 1: Q quit (after typing YES the program runs NEW), C clear, S and L save and load the screen as a SCREEN$ file, K border, ink and paper colours, P print text, M move a block.
  • Menu 2: C circle of a given radius at the cursor, L line to a second cursor point marked with D (LIST USR 62000, which returns it in 55002–55003), B box, M mirror (LIST USR 45500), F fill from a cursor point (USR 58100).
  • Menu 3: A arc (DRAW x,y,angle from the last point), F frame of chosen thickness and colour, C printer copy, S superfile, M magnify, P paper, I ink.
  • Keys 1, 2 and 3 switch between the menus.

Move, Magnify and Superfile

Move and magnify both start with a 20-pixel frame that is steered with the joystick and drawn and undrawn with OVER 1. Pressing fire copies the 19×19 pixels inside it into Q$ by testing each one with POINT. Move then stamps the block wherever the frame is next fixed. Magnify calls USR 57000, clears the screen and shows the block as a 19×19 grid of character cells on a cyan panel. You steer an X cursor and press fire to toggle cells, and any key calls USR 58000 to bring the picture back and plots the edited block in place. The superfile command calls USR 57000 and then saves 6910 bytes from 50000 under your file name, followed by the 78-byte routine at 58000 as SUPERFILE. USR 57000 appears to copy the screen into a buffer at 50000, and USR 58000 appears to copy it back. The same routine draws the title picture.

Notable Techniques

  • LIST USR 60000, LIST USR 62000 and LIST USR 45500 call machine code from a statement that discards the result. The routines pass coordinates back through PEEK 55000–55003.
  • Fill is called inside an expression, PLOT PEEK 55000,PEEK 55001-USR 58100.
  • The colour command repaints the attributes by printing blank lines with OVER 1, so the colours change without erasing the drawing.
  • The joystick is read with the TS2068 STICK function: STICK (1,1) for direction and STICK (2,1) for the fire button.

Potential Issues

  • Line 1030 tests IF q<0 AND Q>7. Sinclair BASIC treats q and Q as the same variable, and no value can be both, so the box ink is never checked. A colour outside 0–9 then stops the program with an error.
  • The box routine sets its fill step a1 only when the height is below 1 or above 1 (lines 1150–1160). A filled box exactly one pixel high appears to fail with “Variable not found” or use a stale step. A box of height 0 jumps to line 120 from inside the subroutine without returning.

This program came from an Oliger (JLO SAFE) disk in the SNUG library set and was converted for tape. The Oliger slashes were removed from the LOAD and SAVE commands in lines 60, 210, 220, 450 and 1210, and the JLO printer command COPY / in line 380 became a plain COPY. It was tested in ZEsarUX on a stock TS2068 through the title screen and the drawing cursor screen.

Related Content

Image Gallery

Source Code

   10 REM                     
   20 REM     GRAFIXX    
   30 REM  by Mark Szabo 
   40 REM   Version 1.9  
   50 REM                         
   60 PAPER 7: INK 0: BORDER 7: CLS : PRINT AT 10,2;"PLEASE WAIT  -  LOADING CODE ": INK 7: LOAD /"grafixx C"CODE 
   70 INK 0
   80 CLS : PRINT AT 10,10;"STOP THE TAPE": FOR I=1 TO 5: BEEP .3,19: BEEP .3,-8: NEXT I
   90 INK 7: CLS : FOR I=-20 TO 40: BEEP .01,I: BEEP .01,I+10: NEXT I: RANDOMIZE USR 58000: BORDER 1: PRINT #1;AT 1,31; PAPER 1;" ": SOUND 0,1;1,161;2,1;3,162;4,1;5,163;6,31;7,56;8,16;9,11;10,11;12,20;13,14
  100 PRINT AT 21,5; PAPER 0; INK 6;"PRESS ANY KEY TO START": PAUSE 0
  110 PAPER 7: BORDER 7: INK 0: CLS : SOUND 8,0;9,0;10,0
  120 PRINT #1;AT 0,15;"PRESS M FOR MENU": LIST USR 60000: OVER 0
  130 LET X=PEEK 55000: LET Y=PEEK 55001: BEEP .04,0: BEEP .04,10: BEEP .04,20
  140 PRINT #1;"Q=QUIT C=CLS S=SVE L=LD K=COLOR P=PRINT M=MOVE 2=MENU 2 3=MENU 3"
  150 PAUSE 0: LET I$=INKEY$
  160 IF I$="Q" THEN INPUT "ARE YOU SURE?(YES/NO):";A$: IF A$="YES" THEN NEW 
  170 IF I$="M" THEN GO SUB 610: GO SUB 690: GO SUB 920
  180 IF I$="P" THEN INPUT "MESSAGE?:";A$: GO SUB 480: OVER 0: PRINT AT X1,Y1;A$
  190 IF I$="3" THEN GO TO 360
  200 IF I$="C" THEN INPUT "CONFIRM CLEAR:(Y/N):";A$: IF A$="Y" THEN CLS 
  210 IF I$="S" THEN INPUT "FILENAME?:";A$: PRINT AT 21,0; OVER 0,,: SAVE /A$SCREEN$ 
  220 IF I$="L" THEN FLASH 0: PRINT AT 0,0;" ": INPUT "NAME ?";A$: LOAD /A$SCREEN$ 
  230 IF I$="K" THEN INPUT " BORDER COLOR?:";B: BORDER B: INPUT " INK COLOR?:";I: INPUT " PAPER COLOR?:";P: PAPER P: FOR Q=0 TO 21: OVER 1: PRINT AT Q,0,,: NEXT Q: INK I
  240 IF I$="2" THEN GO TO 260
  250 GO SUB 610: GO TO 120
  260 GO SUB 610: PRINT #1;"C=CIRCLE L=LINE B=BOX M=MIRROR  F=FILL 1=MENU 1 3=MENU 3"
  270 PAUSE 0: LET I$=INKEY$
  280 IF I$="C" THEN INPUT " INPUT RADIUS:";R: CIRCLE X,Y,R
  290 IF I$="L" THEN GO SUB 610: PRINT #1;"POSITION CURSOR AND PRESS 'D'.   ": LIST USR 62000: PLOT X,Y: DRAW PEEK 55002-X,PEEK 55003-Y: GO SUB 610
  300 IF I$="F" THEN GO SUB 610: PRINT #1;"POSITION CURSOR AND PRESS 'D'.   ": LIST USR 62000: POKE 55000,PEEK 55002: POKE 55001,PEEK 55003: PLOT PEEK 55000,PEEK 55001-USR 58100: GO SUB 610
  310 IF I$="1" THEN GO TO 130
  320 IF I$="3" THEN GO TO 360
  330 IF i$="M" THEN GO SUB 610: LIST USR 45500
  340 IF i$="B" THEN GO SUB 1030
  350 GO SUB 610: GO TO 120
  360 GO SUB 610: PRINT #1;"A=ARC F=FRAME C=CPY S=SUPERFILE M=MAGNIFY P=PAPER I=INK 1&2=MENU"
  370 PAUSE 0: LET I$=INKEY$
  380 IF I$="C" THEN PRINT AT 21,0; OVER 0,,: COPY /
  390 IF I$="1" THEN GO TO 130
  400 IF I$="2" THEN GO TO 260
  410 IF I$="A" THEN INPUT " DRAW X?:";X1: INPUT " DRAW Y?:";Y1: INPUT "ARC?:";A: DRAW X1,Y1,A: GO TO 120
  420 IF I$="F" THEN OVER 0: INPUT " INPUT THICKNESS(1-10)";A: INPUT "COLOR:";C: FOR I=0 TO A: INK C: PLOT 0,I+8: DRAW 255,0: PLOT I,8: DRAW 0,167: PLOT 255-I,8: DRAW 0,167: PLOT 255,175-I: DRAW -255,0: NEXT I
  430 IF I$="I" THEN INPUT "COLOR?:";C: INK C
  440 IF I$="P" THEN INPUT "COLOR?:";p: PAPER (p AND p>0 AND p<9)
  450 IF I$="S" THEN INPUT "FILENAME? ";A$: PLOT 127,57087-USR 57000: SAVE /A$CODE 50000,6910: SAVE /"SUPERFILE"CODE 58000,78
  460 IF I$="M" THEN GO SUB 630
  470 GO SUB 610: GO TO 120
  480 LET X1=10: LET Y1=x1: LET Q=|(1,1)
  490 LET Q=|(1,1)
  500 OVER 1: PRINT AT X1,Y1;A$: PAUSE 2: PRINT AT X1,Y1;A$
  510 IF Q=1 THEN LET X1=X1-1
  520 IF Q=2 THEN LET X1=X1+1
  530 IF Q=4 THEN LET Y1=Y1-1
  540 IF Q=8 THEN LET Y1=Y1+1
  550 IF X1>20 THEN LET X1=20
  560 IF X1<0 THEN LET X1=0
  570 LET A=32-LEN A$: IF Y1>A THEN LET Y1=A
  580 IF Y1<0 THEN LET Y1=0
  590 IF |(2,1)=1 THEN PRINT AT X1,Y1;A$: RETURN 
  600 GO TO 490
  610 PRINT #1,,,,: BEEP .04,0: BEEP .04,10: BEEP .04,20: RETURN 
  620 PLOT X,Y: DRAW 20,0: DRAW 0,20: DRAW -20,0: DRAW 0,-19: RETURN 
  630 OVER 1: GO SUB 690: GO SUB 790: RETURN 
  640 IF |(1,1)=1 THEN LET Y=Y+(1 AND Y<150)
  650 IF |(1,1)=2 THEN LET Y=Y-(1 AND Y>7)
  660 IF |(1,1)=4 THEN LET X=X-(1 AND X>4)
  670 IF |(1,1)=8 THEN LET X=X+(1 AND X<230)
  680 RETURN 
  690 OVER 1: INVERSE 0: GO SUB 620
  700 GO SUB 620
  710 GO SUB 640
  720 IF |(2,1)=0 THEN GO TO 690
  730 DIM Q$(20,20): FOR I=19 TO 1 STEP -1
  740 FOR J=1 TO 19
  750 IF POINT (J+X,Y+I)=1 THEN LET Q$(J,I)="::": GO TO 770
  760 LET Q$(J,I)=" "
  770 NEXT J: NEXT I
  780 RETURN 
  790 PRINT AT 0,0;USR 57000: CLS 
  800 PRINT AT 0,0;"                     ": FOR I=1 TO 19: PRINT PAPER 5;"                     ": NEXT I: PRINT "                     ": FOR I=19 TO 1 STEP -1
  810 FOR J=1 TO 19
  820 PRINT AT 20-I,J;Q$(J,I): NEXT J: NEXT I
  830 OVER 0: LET X1=1: LET Y1=1
  840 PRINT AT X1,Y1; OVER 1;"X": PAUSE 11: PRINT AT X1,Y1; OVER 1;"X"
  850 LET X1=X1+(1 AND X1<19 AND |(1,1)=2)+(-1 AND X1>1 AND |(1,1)=1)
  860 LET Y1=Y1+(1 AND Y1<19 AND |(1,1)=8)+(-1 AND Y1>1 AND |(1,1)=4)
  870 IF INKEY$<>"" THEN GO TO 910
  880 IF |(2,1)=0 THEN GO TO 840
  890 IF Q$(Y1,20-X1)=CHR$ CODE "::" THEN LET Q$(Y1,20-X1)=" ": PRINT AT X1,Y1;" ": GO TO 840
  900 IF Q$(Y1,20-X1)=CHR$ CODE " " THEN LET Q$(Y1,20-X1)="::": PRINT AT X1,Y1;"::": GO TO 840
  910 RANDOMIZE USR 58000: GO SUB 970: RETURN 
  920 OVER 1: GO SUB 930: RETURN 
  930 OVER 1: GO SUB 620
  940 OVER 1: GO SUB 620: OVER 0
  950 GO SUB 640
  960 IF |(2,1)=0 THEN GO TO 930
  970 FOR I=19 TO 1 STEP -1
  980 FOR J=1 TO 19
  990 IF Q$(J,I)="::" THEN PLOT J+X,Y+I: GO TO 1010
 1000 PLOT INVERSE 1;X+J,Y+I
 1010 NEXT J: NEXT I: RETURN 
 1020 STOP 
 1030 INPUT " INK ? ";q: IF q<0 AND Q>7 THEN GO TO 1030
 1040 INK q
 1050 INPUT "FILLED OR UNFILLED(1 OR 2):";A: IF A<1 OR A>2 THEN GO TO 1050
 1060 LET x1=0: LET y1=x1
 1070 IF |(1,1)=1 THEN LET y1=y1+1
 1080 IF |(1,1)=2 THEN LET y1=y1-1
 1090 IF |(1,1)=4 THEN LET x1=x1-1
 1100 IF |(1,1)=8 THEN LET x1=x1+1
 1110 PLOT x,y: DRAW X1,0: DRAW 0,Y1: DRAW -X1,0: DRAW 0,-Y1
 1120 IF |(2,1)=1 THEN GO TO 1150
 1130 INVERSE 1: PLOT x,y: DRAW X1,0: DRAW 0,Y1: DRAW -X1,0: DRAW 0,-Y1
 1140 INVERSE 0: GO TO 1070
 1150 IF y1<1 THEN LET a1=-1
 1160 IF y1>1 THEN LET a1=1
 1170 IF y1=0 THEN GO TO 120
 1180 IF A=2 THEN RETURN 
 1190 FOR i=0 TO y1 STEP a1: PLOT x,i+y: DRAW x1,0: NEXT i
 1200 RETURN 
 1210 SAVE /"GRAFIXX" LINE 10: SAVE /"grafixx C"CODE 45500,18000

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