Graph plotting

Basic and Machine Language

Moderator: Moderators

User avatar
cercamon
Vic 20 Amateur
Posts: 42
Joined: Sun Dec 28, 2014 4:41 am

Graph plotting

Post by cercamon »

From Czes Kosniowski's "Fun Mathematics on your Microcomputer", I typed a little program in VICE XVic emulator, unexpanded Vic-20. The program runs fine and it starts plotting the chosen predefined function in hi-res screen. But then it stops while still in hi-res mode so I can't read the error message. I've checked the BASIC listing line after line, couldn't find any mistyping. I enclose here the D64 image if someone's willing to help with this. TIA.

https://1drv.ms/u/s!AlIzYwFc-VDvhMwASxn ... A?e=f2drti
User avatar
srowe
Vic 20 Scientist
Posts: 1340
Joined: Mon Jun 16, 2014 3:19 pm

Re: Graph plotting

Post by srowe »

If you drop into the monitor and run

Code: Select all

> 9000  0c 26 96 2e  00 f0 57 ea  ff ff 00 00  00 00 00 1b
it will reset the VIC registers back to their defaults. I tried your image, there wasn't an error for the values I tried (the ones on page 35). It just seems to exit.
User avatar
cercamon
Vic 20 Amateur
Posts: 42
Joined: Sun Dec 28, 2014 4:41 am

Re: Graph plotting

Post by cercamon »

Thanks for your reply.
Did you see the crash screen? Maybe it's some values of the selected function that go over the limits, maybe it's a computing error. I can't say.
While running I can see the hi-res screen cleaning and then I expect the function to be plotted for the X range (-0.1 and 0.1, to follow the example of the book). But all I get is that garbage on the screen. So surely the program exits, but the question is why?
User avatar
Mike
Herr VC
Posts: 4841
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Graph plotting

Post by Mike »

A quick overview tells me the two programs are not supposed to run on an unexpanded VIC-20. At least a +3K RAM expansion is required. With +8K RAM or more, it is necessary to move the start of BASIC upwards to 8192, with: POKE44,32:POKE8192,0:NEW - there's a check inside the two programs for this.

When you actually run the program on an unexpanded VIC-20, the POKEs into the character generator/bitmap 'shoot' into the program code or variable space, which most probably stops the program with a ?SYNTAX error or may even hang the BASIC interpreter, as vital data structures in BASIC memory have been clobbered with.

You seriously should consider porting the programs over to MINIGRAFIK. Not only will this eliminate all the slow BASIC statements necessary for setting up the bitmap and plotting pixels by replacing those with the @ON, @CLR, @RETURN and @1,x,y draw commands; MINIGRAFIK also takes care of the necessary reorganisation of BASIC memory and will automatically return from hires to text mode when a BASIC error message is displayed.
User avatar
srowe
Vic 20 Scientist
Posts: 1340
Joined: Mon Jun 16, 2014 3:19 pm

Re: Graph plotting

Post by srowe »

The code runs fine with 3K if you fix line 1160.
User avatar
cercamon
Vic 20 Amateur
Posts: 42
Joined: Sun Dec 28, 2014 4:41 am

Re: Graph plotting

Post by cercamon »

Mike wrote: Wed Apr 15, 2020 5:46 am A quick overview tells me the two programs are not supposed to run on an unexpanded VIC-20. At least a +3K RAM expansion is required. With +8K RAM or more, it is necessary to move the start of BASIC upwards to 8192, with: POKE44,32:POKE8192,0:NEW - there's a check inside the two programs for this.

When you actually run the program on an unexpanded VIC-20, the POKEs into the character generator/bitmap 'shoot' into the program code or variable space, which most probably stops the program with a ?SYNTAX error or may even hang the BASIC interpreter, as vital data structures in BASIC memory have been clobbered with.

You seriously should consider porting the programs over to MINIGRAFIK. Not only will this eliminate all the slow BASIC statements necessary for setting up the bitmap and plotting pixels by replacing those with the @ON, @CLR, @RETURN and @1,x,y draw commands; MINIGRAFIK also takes care of the necessary reorganisation of BASIC memory and will automatically return from hires to text mode when a BASIC error message is displayed.
Yes, the code runs with +3K RAM more, but the functions are not plotted correctly, yet.
I know about Minigrafik, it's amazing and I'll surely port this code for more speed and control.
User avatar
cercamon
Vic 20 Amateur
Posts: 42
Joined: Sun Dec 28, 2014 4:41 am

Re: Graph plotting

Post by cercamon »

srowe wrote: Wed Apr 15, 2020 5:55 am The code runs fine with 3K if you fix line 1160.
Yes, this morning I've found out that the +3K expansion is the one that works fine with this listing. Yet the functions plotting is not correct and not continuous. You mention the line 1160:

1160 W=RR+I*288+J*16+K
1170 POKE W, PEEK(W) OR 2^(7-L)

What do you think it should look like? W must be the current memory location of the hires area. I checked with the original listing and I can't see any difference. But I will investigate more. Many thanks for your suggestions.
User avatar
cercamon
Vic 20 Amateur
Posts: 42
Joined: Sun Dec 28, 2014 4:41 am

Re: Graph plotting

Post by cercamon »

Ok, mistery solved - a friend of mine who originally gave me the listings of the book, now sent me the correct pages of the Vic-20 programs.
In this D64 file, you can find the correct full code: https://1drv.ms/u/s!AlIzYwFc-VDvhMwELm7 ... A?e=jJMKag
It requires a +3KB expansion to run.

Last thing to solve (or understand) is the screen that appears after the end of the plotting phase, where the program asks the user if he wants to proceed with another plotting. The message "Another go? Y or N" appears on a screen which shows the full set of the Vic-20 character ROM (see the enclosed jpg file called "restore-screen.jpg". It seems like the program doesn't or can't correctly clear the screen or there's a problem with the memory area being used by the program.
User avatar
srowe
Vic 20 Scientist
Posts: 1340
Joined: Mon Jun 16, 2014 3:19 pm

Re: Graph plotting

Post by srowe »

I don't see how this was supposed to work. The variable CS$ is used to clear the screen, this results in 147 being stored in string storage right at the top of BASIC memory ($1DFF). Line 1020 clears the region $1000 to $1DFF, trashing the value.

If you type

Code: Select all

POKE56,16
before loading the program it seems to work.
User avatar
cercamon
Vic 20 Amateur
Posts: 42
Joined: Sun Dec 28, 2014 4:41 am

Re: Graph plotting

Post by cercamon »

Many thanks, srowe, for your help. I'll try and modify the code in order to make it more readable and a bit faster.
In VICE/XVic I'm using Warp Mode so speed isn't really a problem. But on a real Vic-20... then I'll try to port everything on MINIGRAFIK. :-)
User avatar
Mike
Herr VC
Posts: 4841
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Graph plotting

Post by Mike »

For what matters, here's a quick port of the first program on the *.d64, GP.PRG, to MINIGRAFIK:

Code: Select all

10 REM VIC 20
20 REM GRAPH PLOTTING
30 REM **************
120 SX=160
130 SY=191
140 HY=SY/2
150 PRINTCHR$(147)
160 PRINT"    GRAPH PLOTTING"
170 PRINT
180 PRINT"1.Y=X*X*SIN(1/X)"
190 PRINT
200 PRINT"2.Y=X*SIN(1/X)"
210 PRINT
220 PRINT"3.Y=SQR(X*X+2)"
230 PRINT
240 PRINT"4.Y=COS(X*EXP(-X/5))"
250 PRINT
260 PRINT"5.Y=6+2*X*X-X*X*X*X"
270 PRINT
280 PRINT"TYPE IN THE NUMBER OF"
290 PRINT"THE EQUATION";
300 INPUT N
310 IFN=1THENDEFFNA(X)=X*X*SIN(1/X)
320 IFN=2THENDEFFNA(X)=X*SIN(1/X)
330 IFN=3THENDEFFNA(X)=SQR(X*X+2)
340 IFN=4THENDEFFNA(X)=COS(X*EXP(-X/5))
350 IFN=5THENDEFFNA(X)=6+2*X*X-X*X*X*X
360 PRINT
370 PRINT"VALUES OF X FOR PLOT"
380 PRINT
390 PRINT"LOWEST VALUE";
400 INPUTA
410 PRINT
420 PRINT"HIGHEST VALUE";
430 INPUTB
440 PRINT
450 IFA>=BTHENPRINT"ERROR-TRY AGAIN"
460 IFA>=BTHENGOTO360
500 REM ***CALCULATING RANGE OF Y ***
510 PRINT"CALCULATING RANGE OF Y"
520 C=(B-A)/100
530 M=1.0E-30
540 FORX=ATOBSTEPC
550 IFX=0THENGOTO580
560 Y=ABS(FNA(X))
570 IFM<YTHENM=Y
580 NEXT X
590 PRINT"READY FOR PLOTTING"
600 FORI=1TO1000
610 NEXT I
620 PRINTCHR$(147)
630 GOSUB1010:REM PREP SCREEN
700 REM *** PLOTTING
710 C=C/10:REM TRY C/5 OR C/20
720 FORX=ATOBSTEPC
730 IFX=0THENGOTO790
740 Y=FNA(X)
750 U=SX*(X-A)/(B-A)
760 V=HY+HY*Y/M
770 IFV<0ORV>SYTHENGOTO790
780 GOSUB1110:REM PLOT U,V
790 NEXT X
800 REM *** ENDING
810 GETG$:REM G$=INKEY$
820 IFG$=""THENGOTO810
830 GOSUB1210:REM RESTORE SCREEN
840 PRINTCHR$(147)
850 PRINT" ANOTHER GO? Y OR N"
860 GETG$
870 IFG$<>"Y"ANDG$<>"N"THENGOTO860
880 IFG$="Y"THEN GOTO150
890 END:REM STOP
1000 REM *** PREP HI-SCREEN
1010 @ON
1020 @CLR
1030 :
1040 RETURN
1100 REM *** PLOT
1110 @1,U,SY-V
1180 RETURN
1200 REM *** RESTORE SCREEN
1210 @RETURN:POKE198,0
1220 RETURN
The code actually goes through a few hoops to make the transforms between axes values and screen co-ordinates, especially the FOR loop in line 720 is prone to accumulating round-off error. For this kind of application, it's always more sensible to calculate the X-axis value from the X screen coordinate, not the other way round.

On the plus side, the program contained an abstraction of the actual screen size in lines 120 and 130. I only needed to change these two numbers to adapt the program to the slightly different resolution of 160x192 with MINIGRAFIK.

Lines 1000 following show what remains when MINIGRAFIK gets to do the job ... :mrgreen: ... (BTW, the single remaining POKE to address 198 only serves to empty the keyboard buffer for the loop in lines 860..880 beforehand and has nothing to do with the intended action of returning to text mode) ... what's left in those subroutines could quite as well be inlined into the main program.


P.S. Here's another function plotter I wrote some years ago (link), which I then also ported to MG and which is contained in the disk image of the MG batch suite.
User avatar
cercamon
Vic 20 Amateur
Posts: 42
Joined: Sun Dec 28, 2014 4:41 am

Re: Graph plotting

Post by cercamon »

It works with POKE56,16. But that's a bit confusing to me.

The unexpanded VIC-20 should use:
Total memory: $1000 - $1fff (4096-8191)
Screen memory: $1e00 - $1fff (7680-8191)
Basic memory: $1000 - $1dff (4096-7679) -> 3583 bytes free

The +3K Vic-20 should use:
Total memory: $0400 - $1fff (1024-8191)
Screen memory: $1e00 - $1fff (7680-8191)
Basic memory: $0400 - $1dff (1024-7679) -> 6655 bytes free


So when I turn on my +3K Vic-20, Basic area for programs should start at $0400 (1024).
The BASIC program "Graph Plot" makes calculation about memory when started (lines 1300-1340) and qthen clears the memory from 4096 to 7679, not the screen memory only.

Code: Select all

1310 Q = PEEK(44)>=18: PP = 7680 + Q*512: QQ = 38400+Q*512
1320 IF Q = -1 AND PEEK(44) < 32 THEN "PROGRAM ABORTED": END
1330 RR = 4096-Q*512: SS=RR+3583:R8 = PEEK(36869): R6=PEEK(36867)
1340 RETURN
With a +3K system (6655 bytes free), the Q gets the value of 0 (zero). So PP=7680, QQ=38400, RR=4096 and SS=7679. Therefore, line

Code: Select all

1020 FOR I=RR TO SS: POKE I,0: NEXT I
, seems completely useless. It clears the top BASIC memory area, not the screen memory.
And line

Code: Select all

1030 FOR I = 0 TO 219: POKE PP+I,I-32*Q: POKE QQ+I,2:NEXT I
, seems to clear 220 locations starting from 7680, not 506 or 512 bytes of the memory screen.

As said, I'm a bit confused. But it works fine with your POKE 56,16, which reduces the memory available to BASIC to 3583 bytes starting from 6655 bytes. So maybe the program is written for the unexpanded Vic-20, but when I do start the program without memory I get a crashed hi-res screen and only a portion of the correct plotted function.

Now investigating on location 56 of the zero page, to understand the magic of pokeing in the value of 16.
User avatar
Mike
Herr VC
Posts: 4841
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Graph plotting

Post by Mike »

cercamon wrote:[...] line

Code: Select all

1020 FOR I=RR TO SS: POKE I,0: NEXT I
seems completely useless. It clears the top BASIC memory area, not the screen memory.
This FOR loop clears the bitmap.
And line

Code: Select all

1030 FOR I = 0 TO 219: POKE PP+I,I-32*Q: POKE QQ+I,2:NEXT I
seems to clear 220 locations starting from 7680, not 506 or 512 bytes of the memory screen.
This FOR fills the text screen with unique characters that serve as address generator for the VIC chip to access the bitmap.

With double-height characters (8x16 pixels) and a graphics resolution of 176x160=28160 pixels, those are 220 characters.
Now investigating on location 56 of the zero page, to understand the magic of pokeing in the value of 16.
Nothing magic about it. It sets the top of BASIC memory to 4096 (with the +3K RAM expansion), so BASIC program+variables are kept separate from bitmap and address generating text screen. BASIC program and variables then 'live' in $0400..$0FFF, and bitmap + text screen live in $1000..$1FFF.

Actually the program discussed here makes non-optimal use of the memory in $1000..$1FFF. The resolution of 176x160 pixels only needs those 220 bytes for the text screen and 3520 bytes for the bitmap, which are 3740 bytes in total. Of the 4096 bytes available, 356 bytes are laid waste.

The 160x192 resolution of MINIGRAFIK instead uses 240 bytes for the text screen and 3840 bytes for the bitmap, 4080 bytes in total. Only 16 bytes remaining of $1000..$1FFF, but MG indeed has a use for those spare bytes while executing the @LOAD and @SAVE commands.

MINIGRAFIK only uses these 'upper' 4K of the internal RAM for text screen and bitmap on purpose, for interoperability with BASIC and KERNAL. Even though it is possible to move the text screen down to $0000..$03FF and produce an even slightly larger graphics screen, this would come at the expense of compatibility to the operating system. For a BASIC extension, this is out of question.


(... as has been written elsewhere, the VIC chip can only access the character ROM ($8000..$8FFF) and the internal RAM ($0000..$03FF and $1000..$1FFF) for text screen and character pattern data. Nothing on the cartridge port is 'visible' to VIC! Especially, the +3K RAM expansion cannot be accessed by VIC even though there exist register values which would suggest the VIC chip taps into the $0400..$0FFF range - but it just doesn't work. The technical details, again, are explained elsewhere ...)
User avatar
cercamon
Vic 20 Amateur
Posts: 42
Joined: Sun Dec 28, 2014 4:41 am

Re: Graph plotting

Post by cercamon »

Thank you Mike, for all the explanations here. I did try MINIGRAFIK last year and found it great, now I'll definitely have a second go, and get some fun out of it. :-)
User avatar
cercamon
Vic 20 Amateur
Posts: 42
Joined: Sun Dec 28, 2014 4:41 am

Re: Graph plotting

Post by cercamon »

I played a bit with MINIGRAFIK and found it amazing. And it's so fast if compared to bare BASIC commands.
I think I'm going to write a review for the next issue of RetroMagazine, an Italian free online magazine dedicated to retrocomputing and retrogaming.
I've already read the thread about MINIGRAFIK that you, Mike, showed me. I've also downloaded the MINIPAINT/MINIGRAFIK PDF manual. If there's more documentation about your amazing routines, examples coded by other Denial members or anything else which you think is worth it, please do point me in the right direction.

RetroMagazine will also be published in English very soon. - https://www.retromagazine.net
Post Reply