Jump to content
IGNORED

Interesting X/Y Graph programme


Fishsta
 Share

Recommended Posts

I just added this programme to www.fishsta.co.uk

 

xygraphp1.jpgxygraphp2.jpg

 

This is one from the British TI Home Computer Users Club Newsletters, but what got me was the clever way John Stocks has got the TI to convert X/Y Co-ordinates into a CHAR string to compute the graph.

 

Has anyone seen anything like this used anywhere else? To some here, it might seem simple, but to me, it's almost incredible that someone could convert a sequence of X/Y co-ords into Hexadecimal code by means of a formula, and produce these results.

 

He says the first few lines are editable, so in theory we could produce easy SIN/TAN/COS graphs, or even random graphs.

 

Admittedly very slowly. You will probably want to overdrive it.

 

Other well-known computers, such as the Spectrum, had the PLOT command, which is obviously sadly absent in standard TI Basic.

 

Anyway, if anyone can come up with interesting lines to replace lines 100-120 in this programme, I'd be curious to try them myself.

Link to comment
Share on other sites

I wrote such a program many, many years ago, too (I think I was inspired by a ZX81 program).

 

Miraculously, it's one that I still have. It's pure TI BASIC, and I wrote it to be like a subroutine that you dropped at the beginning of your own program. So the draw code is all prior to line 500, and post 500 is the demo app.

 

It has a couple of bugs, visible when the drawing crosses the axes, but it works for the most part and those bugs are probably a bit trivial. Note that the demo app cheats drawing the axes, it draws 8 pixels then copies the character across the screen. ;)

 

post-12959-129885019051_thumb.jpg

 

Code is here:

 

 

1 REM  DIM CC$ TO #  
2 REM  CHARACTERS 
3 REM  ALSO CHANGE LINE 11 
4 REM  ADJUST 20,25 
5 REM  START PROGRAM AT 500 
6 REM  MORE AT 310 
10 DIM CC$(125)
11 FOR A=1 TO 125
12 CC$(A)="0000000000000000"
13 NEXT A
20 CURCHAR=34
22 LOWCHAR=33
25 STARTCHAR=34
30 AND$="0000000100100011010001010110011110001001101010111100110111101111"
40 HEX$="0123456789ABCDEF"
50 GOTO 500
100 REM  *PLOT*  TI BASIC 
110 REM  HI-RES SUBROUTINE 
120 MR=INT(DOTROW/8)+1
130 MC=INT(DOTCOL/8)+1
140 CALL GCHAR(MR,MC,QW)
145 CH=QW
150 IF QW>=STARTCHAR THEN 160
151 IF QW<LOWCHAR THEN 155
154 CC$(CURCHAR-LOWCHAR-1)=CC$(QW-LOWCHAR-1)
155 CH=CURCHAR
157 CURCHAR=CURCHAR+1
160 TC$=CC$(CH-LOWCHAR-1)
170 XR=DOTROW-INT(DOTROW/8)*8
180 XC=DOTCOL-INT(DOTCOL/8)*8
190 P=XR*2-(XC>3)
200 P=P+1
210 XC=XC+4*(XC>3)
220 X$=SEG$(TC$,P,1)
230 X2$=SEG$(AND$,(POS(HEX$,X$,1)-1)*4+1,4)
240 X2$=SEG$(X2$,1,XC)&"1"&SEG$(X2$,XC+1,4-XC)
250 TT=-8*(SEG$(X2$,1,1)="1")-4*(SEG$(X2$,2,1)="1")-2*(SEG$(X2$,3,1)="1")-(SEG$(X2$,4,1)="1")
260 TT$=SEG$(HEX$,TT+1,1)
270 TC$=SEG$(TC$,1,P-1)&TT$&SEG$(TC$,P+1,16-P)
280 CALL CHAR(CH,TC$)
290 CC$(CH-LOWCHAR-1)=TC$
295 CALL HCHAR(MR,MC,CH)
300 RETURN
310 REM  PROGRAM NEEDS 
320 REM  'DOTROW' AND 
330 REM  'DOTCOL'. STARTCHAR 
340 REM  IS START CHARACTER 
350 REM  CURCHAR IS CURRENT 
360 REM  CHARACTER +1 
370 REM  LOWCHAR IS LOWEST  
380 REM  CHARACTER TO USE 
390 REM  THESE REMS CAN BE 
400 REM  DELETED (1-9 & 310- 
410 REM  410) 
500 REM  CIRCLE 
517 CURCHAR=STARTCHAR
520 FOR A=1 TO 16
530 CALL COLOR(A,16,2)
540 NEXT A
560 CALL CLEAR
561 CURCHAR=STARTCHAR
630 FOR I=0 TO 7
640 DOTROW=96
642 DOTCOL=I
644 GOSUB 100
650 DOTROW=I
652 DOTCOL=128
654 GOSUB 100
660 NEXT I
670 CALL HCHAR(13,2,CURCHAR-2,31)
680 CALL VCHAR(2,17,CURCHAR-1,23)
700 STARTCHAR=STARTCHAR+2
710 FOR I=128 TO 135
720 DOTROW=96
722 DOTCOL=I
724 GOSUB 100
730 NEXT I
760 F=1.18
770 PI=4*ATN(1)
780 FOR RAD=0 TO 2*PI STEP .08
790 DOTROW=96-INT(F*40*SIN(RAD)+.5)
800 DOTCOL=128+INT(40*COS(RAD)+.5)
810 GOSUB 100
820 NEXT RAD
830 FOR RAD=0 TO 2*PI STEP .08
870 DOTROW=96-INT(40*SIN(RAD)+.5)
880 DOTCOL=47+INT(25.46479*RAD+.5)
890 GOSUB 100
900 DOTROW=96-INT(40*COS(RAD)+.5)
910 GOSUB 100
920 NEXT RAD
930 GOTO 930

 

 

I have not attempted to figure out this code over again, hehe. This one probably dates back to '87 or '88, before I had XB.

Link to comment
Share on other sites

I couldn't resist, I went back and optimized the speed of that old code a bit, and also fixed the bug crossing the Y axis (it was a look-up error getting the old pattern definition caused by the way I cheated on those characters, turns out the original routine was fine).

 

The way that the code worked is by taking the pixel row/column in. It divides by 8 to get the character row and column, and the remainder is the pixel row and column inside that character. It converted the pixel row/col into a position in the hex string to get the appropriate nibble/character to modify. Then it took the character out of the string, converted it to decimal, used that value to look up in the binary table to get a 4-character binary string. The appropriate bit inside the binary string was changed to a '1', then the binary was converted back to decimal, and the decimal back to hex, and the hex character was spliced back into the hex string for CALL CHAR (followed by a CALL HCHAR to get the character up on the screen).

 

The new approach is a fair bit simpler in the middle there. I defined not only the hex string, but a string of results when a character is ORd with each of the 4 possible pixels in a nibble. This way once I know which character and which bit in that character, I can just pull the new hex character from the appropriate string without all the fiddling around converting bases.

 

The rest is pretty straightforward. Variables define which characters the routine is allowed to redefine, and which ones it already has redefined. If the screen position contains a character already redefined, then it just updates that definition. If it's one that it is tracking but not allowed to redefine (such as the axes after they are drawn), then it makes a copy of the definition and works as for a new character. And everything else really IS a new character. Since TI BASIC doesn't have CALL CHARPAT, an array tracks the definitions as we know them.

 

Assembly would be able to do this pretty darn fast, I'd expect. Anyway, here's the faster, bugfixed version.

 

 

1 REM   DIM CC$ TO #    
2 REM   CHARACTERS   
3 REM   ALSO CHANGE LINE 11       
4 REM   ADJUST 20,25   
5 REM   START PROGRAM AT 500      
6 REM   MORE AT 310   
10 DIM CC$(125),HPAT$(4)
11 FOR A=0 TO 125
12 CC$(A)="0000000000000000"
13 NEXT A
20 CURCHAR=34
22 LOWCHAR=33
25 STARTCHAR=34
30 HEX$="0123456789ABCDEF"
32 HPAT$(0)="89ABCDEF89ABCDEF"
34 HPAT$(1)="45674567CDEFCDEF"
36 HPAT$(2)="23236767ABABEFEF"
38 HPAT$(3)="1133557799BBDDFF"
50 GOTO 500
100 REM   *PLOT*  TI BASIC   
110 REM   HI-RES SUBROUTINE       
120 MR=INT(DOTROW/8)+1
130 MC=INT(DOTCOL/8)+1
140 CALL GCHAR(MR,MC,QW)
145 CH=QW
150 IF QW>=STARTCHAR THEN 160
151 IF QW<LOWCHAR THEN 155
154 CC$(CURCHAR-LOWCHAR-1)=CC$(QW-LOWCHAR-1)
155 CH=CURCHAR
157 CURCHAR=CURCHAR+1
160 TC$=CC$(CH-LOWCHAR-1)
170 XR=DOTROW-(MR-1)*8
180 XC=DOTCOL-(MC-1)*8
190 P=XR*2+1
210 IF XC<4 THEN 220
212 P=P+1
214 XC=XC-4
220 X$=SEG$(TC$,P,1)
260 TT$=SEG$(HPAT$(XC),POS(HEX$,X$,1),1)
270 TC$=SEG$(TC$,1,P-1)&TT$&SEG$(TC$,P+1,16-P)
280 CALL CHAR(CH,TC$)
290 CC$(CH-LOWCHAR-1)=TC$
295 CALL HCHAR(MR,MC,CH)
300 RETURN
310 REM   PROGRAM NEEDS   
320 REM   'DOTROW' AND   
330 REM   'DOTCOL'. STARTCHAR     
340 REM   IS START CHARACTER      
350 REM   CURCHAR IS CURRENT      
360 REM   CHARACTER +1   
370 REM   LOWCHAR IS LOWEST       
380 REM   CHARACTER TO USE   
390 REM   THESE REMS CAN BE       
400 REM   DELETED (1-9 & 310-     
410 REM   410)   
500 REM   CIRCLE   
517 CURCHAR=STARTCHAR
520 FOR A=1 TO 16
530 CALL COLOR(A,16,2)
540 NEXT A
560 CALL CLEAR
561 CURCHAR=STARTCHAR
630 FOR I=0 TO 7
640 DOTROW=96
642 DOTCOL=I
644 GOSUB 100
650 DOTROW=I
652 DOTCOL=128
654 GOSUB 100
660 NEXT I
670 CALL HCHAR(13,2,CURCHAR-2,31)
680 CALL VCHAR(2,17,CURCHAR-1,23)
700 STARTCHAR=STARTCHAR+2
710 DOTROW=96
720 FOR I=128 TO 135
722 DOTCOL=I
724 GOSUB 100
730 NEXT I
760 F=1.18
770 PI=4*ATN(1)
780 FOR RAD=0 TO 2*PI STEP .04
790 DOTROW=96-INT(F*40*SIN(RAD)+.5)
800 DOTCOL=128+INT(40*COS(RAD)+.5)
810 GOSUB 100
820 NEXT RAD
830 FOR RAD=0 TO 2*PI STEP .04
870 DOTROW=96-INT(40*SIN(RAD)+.5)
880 DOTCOL=47+INT(25.46479*RAD+.5)
890 GOSUB 100
900 DOTROW=96-INT(40*COS(RAD)+.5)
910 GOSUB 100
920 NEXT RAD
930 GOTO 930

 

Link to comment
Share on other sites

Ha... I always hated doing this on my TI-83 back in the day. Matt Rhynik was super fast and great at math and I hated him for it. Had to sit next to that jerk in class. And he had the TI-83+. =)

 

Seeing it on the /4a though... =) Makes me want to try and write some stuff for my old TI-83 again.

Link to comment
Share on other sites

  • 2 weeks later...

I couldn't resist, I went back and optimized the speed of that old code a bit, and also fixed the bug crossing the Y axis (it was a look-up error getting the old pattern definition caused by the way I cheated on those characters, turns out the original routine was fine).

 

The way that the code worked is by taking the pixel row/column in. It divides by 8 to get the character row and column, and the remainder is the pixel row and column inside that character. It converted the pixel row/col into a position in the hex string to get the appropriate nibble/character to modify. Then it took the character out of the string, converted it to decimal, used that value to look up in the binary table to get a 4-character binary string. The appropriate bit inside the binary string was changed to a '1', then the binary was converted back to decimal, and the decimal back to hex, and the hex character was spliced back into the hex string for CALL CHAR (followed by a CALL HCHAR to get the character up on the screen).

 

The new approach is a fair bit simpler in the middle there. I defined not only the hex string, but a string of results when a character is ORd with each of the 4 possible pixels in a nibble. This way once I know which character and which bit in that character, I can just pull the new hex character from the appropriate string without all the fiddling around converting bases.

 

The rest is pretty straightforward. Variables define which characters the routine is allowed to redefine, and which ones it already has redefined. If the screen position contains a character already redefined, then it just updates that definition. If it's one that it is tracking but not allowed to redefine (such as the axes after they are drawn), then it makes a copy of the definition and works as for a new character. And everything else really IS a new character. Since TI BASIC doesn't have CALL CHARPAT, an array tracks the definitions as we know them.

 

Assembly would be able to do this pretty darn fast, I'd expect. Anyway, here's the faster, bugfixed version.

 

 

1 REM   DIM CC$ TO #    
2 REM   CHARACTERS   
3 REM   ALSO CHANGE LINE 11       
4 REM   ADJUST 20,25   
5 REM   START PROGRAM AT 500      
6 REM   MORE AT 310   
10 DIM CC$(125),HPAT$(4)
11 FOR A=0 TO 125
12 CC$(A)="0000000000000000"
13 NEXT A
20 CURCHAR=34
22 LOWCHAR=33
25 STARTCHAR=34
30 HEX$="0123456789ABCDEF"
32 HPAT$(0)="89ABCDEF89ABCDEF"
34 HPAT$(1)="45674567CDEFCDEF"
36 HPAT$(2)="23236767ABABEFEF"
38 HPAT$(3)="1133557799BBDDFF"
50 GOTO 500
100 REM   *PLOT*  TI BASIC   
110 REM   HI-RES SUBROUTINE       
120 MR=INT(DOTROW/8)+1
130 MC=INT(DOTCOL/8)+1
140 CALL GCHAR(MR,MC,QW)
145 CH=QW
150 IF QW>=STARTCHAR THEN 160
151 IF QW<LOWCHAR THEN 155
154 CC$(CURCHAR-LOWCHAR-1)=CC$(QW-LOWCHAR-1)
155 CH=CURCHAR
157 CURCHAR=CURCHAR+1
160 TC$=CC$(CH-LOWCHAR-1)
170 XR=DOTROW-(MR-1)*8
180 XC=DOTCOL-(MC-1)*8
190 P=XR*2+1
210 IF XC<4 THEN 220
212 P=P+1
214 XC=XC-4
220 X$=SEG$(TC$,P,1)
260 TT$=SEG$(HPAT$(XC),POS(HEX$,X$,1),1)
270 TC$=SEG$(TC$,1,P-1)&TT$&SEG$(TC$,P+1,16-P)
280 CALL CHAR(CH,TC$)
290 CC$(CH-LOWCHAR-1)=TC$
295 CALL HCHAR(MR,MC,CH)
300 RETURN
310 REM   PROGRAM NEEDS   
320 REM   'DOTROW' AND   
330 REM   'DOTCOL'. STARTCHAR     
340 REM   IS START CHARACTER      
350 REM   CURCHAR IS CURRENT      
360 REM   CHARACTER +1   
370 REM   LOWCHAR IS LOWEST       
380 REM   CHARACTER TO USE   
390 REM   THESE REMS CAN BE       
400 REM   DELETED (1-9 & 310-     
410 REM   410)   
500 REM   CIRCLE   
517 CURCHAR=STARTCHAR
520 FOR A=1 TO 16
530 CALL COLOR(A,16,2)
540 NEXT A
560 CALL CLEAR
561 CURCHAR=STARTCHAR
630 FOR I=0 TO 7
640 DOTROW=96
642 DOTCOL=I
644 GOSUB 100
650 DOTROW=I
652 DOTCOL=128
654 GOSUB 100
660 NEXT I
670 CALL HCHAR(13,2,CURCHAR-2,31)
680 CALL VCHAR(2,17,CURCHAR-1,23)
700 STARTCHAR=STARTCHAR+2
710 DOTROW=96
720 FOR I=128 TO 135
722 DOTCOL=I
724 GOSUB 100
730 NEXT I
760 F=1.18
770 PI=4*ATN(1)
780 FOR RAD=0 TO 2*PI STEP .04
790 DOTROW=96-INT(F*40*SIN(RAD)+.5)
800 DOTCOL=128+INT(40*COS(RAD)+.5)
810 GOSUB 100
820 NEXT RAD
830 FOR RAD=0 TO 2*PI STEP .04
870 DOTROW=96-INT(40*SIN(RAD)+.5)
880 DOTCOL=47+INT(25.46479*RAD+.5)
890 GOSUB 100
900 DOTROW=96-INT(40*COS(RAD)+.5)
910 GOSUB 100
920 NEXT RAD
930 GOTO 930

 

 

 

What would that look like speeded up with XB and using Sprites to run the plots per pixels. Use lower 8K to save the pixel locations after each calculation then just load and run the entire plotted path with Sprites going in the up and down paths.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...