Today we have another guest post, this time from Anton, describing how he created the nice little Christmas Demo for the C64, C65 and MEGA65. This is a nice little program to explore, because it works out which machine you are on, and varies the display accordingly. But let's have Anton explain it in his own words...
Hi everybody, i wanted to present you with a small background info about the
MEGA65 BASIC 2 christmas demo I have just coded together with Paul.
A Forum64 member (ZeHa), started last year a project on forum64.
The idea was, to bring back the times of the 80’s, when you went to your local store, bought the latest computer magazine and started, once at home, to type the listings into your beloved 8-bit machine. So he collected last years, xmas themed BASIC listings from board members and put them together in a magazine.
So, this year, he contacted us, the MEGA65 team, if we wouldn’t be interested in providing a nice program as well. We’ve discussed this in the team and we all loved the idea. So I agreed to program something in BASIC. (I haven’t done any BASIC coding since the 80’s…..)
I knew from the beginning, that I would like to code something, that would run on every C64 but I also wanted to demonstrate, what the MEGA65 is capable of.
So that’s when I settled on BASIC 2. One of the biggest advantages of the MEGA65 really is, that you can be in normal C64 mode, you activate the VIC-IV features by Poking :
POKE
53295,71:POKE
53295,83
and you have all the VIC-IV features available at your hand. Easy as that !!!
I started to think about the demo and xmas-themed requirements and slowly an idea formed into my head. I contacted Paul and asked him, if there is a way to find out, if there is a VIC-II present, like on the c64 or a VIC-III like on the c65 or a VIC-IV, the MEGA65 is using. So after some testing we had a nice code snippet ready to check, what machine our program is running on:
(I love the name, we call it “Knock Knock”-routine)
13710
REM
*** "knock
knock"
TO CHECK WHAT VIC IS USED (c64/c65/MEGA65) ***
13720
REM
In c65 Mode we cannot safely write to 53295, so we test a different
way
13810
IF
PEEK(V+24)AND32THENGOTO14410
13910
POKEV,1:POKEV+47,71:POKEV+47,83
14010
POKEV+256,0:IFPEEK(V)=1THEN
VC=65:C$="VIC-IV":RETURN
14110
POKEV,1:POKEV+47,165:POKEV+47,150
14210
POKEV+256,0:IFPEEK(V)=1THEN
VC=65:C$="VIC-III":RETURN
14310
VC=64:C$="VIC-II":RETURN
14320
REM
we assume we have a c65 here
14410
V1=PEEK(V+80):V2=PEEK(V+80):V3=PEEK(V+80)
14510
IF
V1<>V2
OR
V1<>V3ORV2<>V3THEN
VC=65:C$="VIC-IV":RETURN
14610
GOTO14110
So after I was able now to check, what machine my code is getting executed on, I could start with my demo. I wanted to make something simple, nice to watch and completely in BASIC.
Several people have asked already, how the 15 colour sprites on the MEGA65 are working, so I thought, this should go into the demo as well.
The idea shaped. After I found out, with a lot of help from Paul (Thanks Paul !), how the 15 colour sprite works, I started to design a 15 color sprite.
For a rough understanding:
The c64 sprites are using in HiRes mode 24bit x 21 bits so a standard sprite is 24 by 21 pixels
The multicolor sprites are using 2 bits for each color which leaves us with 12 doublewide pixels x 21 pixels. So a sprite on the c64 is using 63B (64)Bytes (one Byte stays empty).
The MEGA65 VIC-IV is able to show a 15 color sprite, which is 16 pixels horizontally x 21 pixels vertically.
Each pixels colour is set by one Nibble (4bits) so a MEGA65 15colour sprite is 64bits horizontally and 21 bits vertically. This means:
4bits x 16 = 64 bits horizontally (8 Bytes)
64 x 21 = 1344 bits or 168 Bytes.
This means, that for a 15 color VIC-IV sprite you have 168B of Data.
The memory area at $0340 would be perfect. So I started drawing a concept.
Have a look: (PS, the blank middle line was removed by moving the right side of the tree one pixel to the left)
I have to say I was amazed, to see how much you can realize with a sprite with such dimensions !
Paul wrote a nice code snippet, which might not be the fastest routine to get the 15 colour sprite poked to the right memory address area, but it was a very good study example of HOW it works.
Have a look here:
(all the standard sprite commands like, positioning, sprite pointer, etc. remain exactly like it would be a normal HiRes sprite. here in this part you only see the commands, that are different from VIC-II)
(You can see, that I am using in this routine already the checks done in the previous code snippet, to see, what VIC is used.)
45
REM
IF MEGA65 ENABLE VIC-IV FEATURES
48
IFC$="VIC-IV"THEN
POKE
V+47,71:POKE
V+47,83
255
REM
*** VIC-IV 15 COLOR SPRITE SETUP ***
260
REM
IF NO MEGA65 JUMP TO 390
265
IF
C$="VIC-II"
OR
C$="VIC-III"
then
goto
390
270
REM
SET ADDRESS 15COL SPRITE TO $0340 (832)
275
AD=768+64
280
REM
MAKE SPRITE 3 - 8 AS 15COLOR SPRITES AND MAKE THEM USE 64 BIT
285
POKE
V+107,252:POKE
V+87,252
290
REM
COPY STANDARD COLORS OVER FOR MULTICOL SPRITES 3 - 8
295
FORI=16TO255:FORJ=1TO3:POKEV+256*J+I,PEEK(V+256*J+(I
AND
15)):NEXTJ,I
315
REM
READ 15COL SPRITE DATA
320
READN$:IFN$="end"THEN
390
325
REM
JUMP TO DECODE ROUTINE
330
GOSUB
345
335
GOTO
320
340
REM
DECODE STRING OF NYBLS IN N$ AT ADDRESS AD (832)
345
L=LEN(N$)
350
FOR
I=1
TO
(L/2+1):POKE
AD+I,0
355
FOR
I= 1
TO
L:N=ASC(MID$(N$,I,1))-64:IFN<0THEN
N=0
360
B=AD+INT((I-1)/2):IF
(I AND
1)=1
THEN
N=N*16
365
VA=PEEK(B):POKE
B,VA
OR
N:PRINT"{home}";VA:NEXTI
370
AD=AD+INT(I/2)375
IF
(L AND
1)
THEN
AD=AD+1
380
RETURN
1445
REM
15 COLOR TREESPRITE DATA
1450
REM
"-"
= TRANSPARENT, "A"-"O""
= COLOURS 1 TO 15
1455
DATA
"------HGH-------"
1460
DATA
"------GGG-------"
1465
DATA
"------HGH-------"
1470
DATA
"-------G--------"
1475
DATA
"------EEH-------"
1480
DATA
"-----E-EBE------"
1485
DATA
"------ENB-------"
1490
DATA
"-----EEEEM------"
1495
DATA
"----EHEEEEE-----"
1500
DATA
"---E-B-EE--E----"
1505
DATA
"----EBEEENE-H---"
1510
DATA
"---CEEEHEEEEB---"
1515
DATA
"--EE--EBE--EB---"
1520
DATA
"---HEEEBCEE-----"
1525
DATA
"---BEEEEEEEE----"
1530
DATA
"--EBE-EEEEEHE---"
1535
DATA
"-EE--EEMEE-BEE--"
1540
DATA
"H--EEEEECEEB----"
1545
DATA
"BEEENEEEEEEEEE--"
1550
DATA
"BEEEE--I--EECEE-"
1555
DATA
"-------I--------"
1560
DATA
"END"
I would like to mention, by setting the sprite color, you define the transparent color.
So if our Tree is sprite 3, by setting 53290 ($D02A) to 0 (Poke53290,0) you set Black(0) as transparent color for sprite 3 (53290).
Line 290 & 295 might also be worth mentioning as well. There we copy the RGB values of the 16 standard colors from Sprite 1 color bank over to the Sprite colour bank of sprite 3 – 8.
This means, you can set not only 15 colours per sprite, but also can define how these colors look like.
You have the RGB values under your control.
OK, but back to the demo. So I was drawing several other sprites (since I already knew, that people who have a normal c64 or a c65 wouldn’t be able to see the 15color sprite), and started to put everything together as I continued to program in BASIC 2 I realized soon, that on a normal c64 with 1 MHz I would not be able to realise all the things I wanted to show.
But the MEGA65 is able to switch between 1MHz/2MHz/3.5MHz and 40MHz !!!
This was the idea I was looking for !!! enable certain features of the demo, only if the machine is able to support a certain speed:
C64 max 1MHz.
C128 max 1MHz (2MHz not useable, since FAST mode on c128 disables screen)
C65 1MHz/3.5 MHz
MEGA65 max 40 MHz
So after I knew, what VIC my program is running on, I was able to tell what the maximum speed would be, that this machine can support.
So I needed some code to do the frequency change. After checking the VIC-III and VIC-IV registers, since the official MEGA65 manual is having all the necessary information:
I came up with this code snippet:
935
REM
*** FREQUENCY CHANGE ***
940
REM
SWITCH TO 2MHZ
945
IF
MH=1
AND
C$="VIC-IV"
THEN
GOSUB985:POKEV+48,1:MH=2:GOTO995
950
REM
SWITCH TO 3.5 MHZ
952
IF
MH=1
AND
C$="VIC-III"
THEN
POKEV+49,64:MH=3.5:RETURN
955
IF
MH=2
THEN
GOSUB985
POKE0,64:MH=3.5:GOTO995
960
REM
SWITCH TO 40MHZ
965
IF
MH=3.5
AND
C$="VIC-IV"THEN
GOSUB985:POKE0,65:MH=40:GOTO995
970
REM
SWITCH TO 1 MHZ
972
IF
MH=3.5
AND
C$="VIC-III"
THEN
POKEV+49,0:MH=1:RETURN
975
IF
MH=40
THEN
GOSUB985:POKE0,64:MH=1:GOTO995
980
REM
DISABLE VIC-IV FEATURES
985
POKEV+47,0:POKEV+48,0:RETURN
990
REM
ENABLE VIC-IV FEATURES
995
POKEV+47,71:POKEV+47,83
1000
IF
MH=40
THEN
POKEV+49,0
1005
IF
MH=3.5
THEN
POKEV+49,64
1010
RETURN
So the c64 would run our nice Christmas demo with the least functions, while on the MEGA65
You can see all the functions implemented (including the 15 colour demo Sprite).
So if the demo is running on a machine > c64/c128 an extra text is shown, which asks you to press
(depending again on what machine it’s running) “SPACE” to cycle between standard Multicolour Sprite and 15 colour VIC-IV Sprite, or “F” to cycle through the freqencies.
This is more or less, the main idea behind the demo. It will run on a c64 also on a c65 and on the MEGA65 and it shows some of the features the MEGA65 offers.
So if you are interested in the demo, hop over to forum64 (this is also the official MEGA65 forum)
Just mention in the Thread, that you want to receive a copy of the forum64 2019 christmas magazine.
So to conclude: I want to wish all of you a merry Christmas 80’s style...
Anton