How do I redefine characters with 8k or more RAM?

Basic and Machine Language

Moderator: Moderators

Duke
Vic 20 Newbie
Posts: 13
Joined: Mon Jan 01, 2024 9:21 am
Location: Netherlands
Occupation: Teacher

How do I redefine characters with 8k or more RAM?

Post by Duke »

Good evening.

I am learning how to redefine characters and print them on the screen to make "mostly" full screen images. I can do it just fine for the stock system and with the 3k RAM expansion installed. It would seem that the process is not the same when using an 8k or higher RAM expansion. I'm not entirely sure exactly how to describe the issue I am having. I think I have the issue down to POKE 36869,255 and how the 8k+ RAM expansions reorder the memory map of the computer. I'm not sure how to alter the program to account for this. What I've read online has only confused me more. I'm hoping to understand my error which will hopefully help me to understand how to accomplish what I'm setting out to do. Here is the program that I've written that does the job on the stock machine or 3K expansion:

Code: Select all

10  POKE 36869,255
20  POKE 646,9
30  POKE 36879,136
40  POKE 36878,213
50  POKE 52,28:POKE 56,28:CLR
60  FOR X=0 TO 511
70  POKE 7176+X, PEEK(32768+X)
80  NEXT X
90  FOR X=0 TO 206
100  READ A:POKE 7176+X,A
110  NEXT X
I have a video of the program running on stock hardware and on 35k to see the difference. I'm using an original VC-20 with PET style keys. The RAM expansion comes from the Penultimate+2 cartridge. I captured the footage by hooking up a 5 pin DIN to composite cable into a composite to HDMI converter and used an HDMI video capture device that plugs into a USB-C port, so it's not terribly great (though incredible that it's possible).

(mod: program source put into code tags)
User avatar
Mike
Herr VC
Posts: 4841
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: How do I redefine characters with 8k or more RAM?

Post by Mike »

Welcome!
Duke wrote:Here is the program that I've written that does the job on the stock machine or 3K expansion: [...]
Please note: the example code you posted here is not the complete program. It is missing the character definitions in DATA lines and the actual PRINT or POKE statements to put the characters on screen. If you follow up with the complete program, then we can build a working version for the bigger RAM expansions from it.
User avatar
chysn
Vic 20 Scientist
Posts: 1205
Joined: Tue Oct 22, 2019 12:36 pm
Website: http://www.beigemaze.com
Location: Michigan, USA
Occupation: Software Dev Manager

Re: How do I redefine characters with 8k or more RAM?

Post by chysn »

The absence of actual DATA notwithstanding, the main problem here is your setting for 36869. When the VIC-20 gets 8K+ of expansion, the screen moves to 4096, and 36869 controls both character set address AND screen location.

If you want to keep your custom characters at $1C00, then

Code: Select all

POKE 36869, 207
A second issue is, you have your character set data going into 7176. I'm not sure if you meant that, but by the context of your existing code, I'd expect that to be 7168.

Reference: https://archive.org/details/COMPUTEs_Ma ... 1/mode/2up
VIC-20 Projects: wAx Assembler, TRBo: Turtle RescueBot, Helix Colony, Sub Med, Trolley Problem, Dungeon of Dance, ZEPTOPOLIS, MIDI KERNAL, The Archivist, Ed for Prophet-5

WIP: MIDIcast BASIC extension

he/him/his
Duke
Vic 20 Newbie
Posts: 13
Joined: Mon Jan 01, 2024 9:21 am
Location: Netherlands
Occupation: Teacher

Re: How do I redefine characters with 8k or more RAM?

Post by Duke »

My apologies. I didn't think the rest of the program was needed as it's just DATA statements and PRINT commands. Here is it in its entirety. If you type it into your machines, it'll make a pretty little picture of a park with 10 colors!

Code: Select all

10  POKE 36869,255
20  POKE 646,9
30  POKE 36879,136
40  POKE 36878,213
50  POKE 52,28:POKE 56,28:CLR
60  FOR X=0 TO 511
70  POKE 7176+X, PEEK(32768+X)
80  NEXT X
90  FOR X=0 TO 206
100  READ A:POKE 7176+X,A
110  NEXT X

120 PRINT "RJRJRJRJRJRJRJRJRJRJR"
125 POKE 646,11
130 PRINT "BBBBBBBBBBBBBBBBBBBBB"
140 PRINT "BBBBBBBBBBBBBBBBBBBBB"
150 PRINT "DEDEDEDEDEDEDEDEDEDED"
160 POKE 646,13
170 PRINT "CCCXTCCCXTCCCCXTCCCCX"
180 PRINT "HGHGHGHGHGHGHGHGHGHGH"
190 PRINT "WBBBBVBBBBBVBBBWBBBBV"
200 PRINT "BVBWBBWBBWBBWBBBBBWBB"
210 PRINT "BWVBBWVBWBVBBWBBVBBWV"
220 PRINT "IJIJIJIJIJIJIJIJIJIJI"
230 POKE 646,14
240 PRINT "MKBLMBKKBKBLMBKBKLMBK"
250 PRINT "MKBLMBKKBKBLMBKBKLMBK"
260 PRINT "MKBLMBKKBKBLMBKBKLMBK"
270 POKE 646,13
280 PRINT "MNOLMPNOPNOLMPNOBLMPN"
290 PRINT "NOPNNOBBFUPNNOBFUNNOB"
300 PRINT "TXTXTXTXYZXTXTXYZTXTX"
310 POKE 646,10
320 PRINT "CCCCCACCCCACCCCCCCCCA"
330 POKE 646,15
340 PRINT "CCSCCCCCCCCCCCCCCCSCC"
350 POKE 646,12
360 PRINT "CQQCCCCCCQCCCCCQCCCQC"
370 POKE 646,15
380 PRINT "SCCCSCCCCCCCCCCSCCCSC"

400 DATA 255,235,235,170,170,235,235,255
410 DATA 170,170,170,170,170,170,170,170
420 DATA 255,255,255,255,255,255,255,255
430 DATA 170,170,170,86,253,255,255,255
440 DATA 170,170,170,165,95,255,255,255
450 DATA 85,106,85,106,85,106,85,85
460 DATA 255,255,255,87,169,170,170,170
470 DATA 255,255,255,213,106,170,170,170
480 DATA 170,170,170,106,85,85,85,85
490 DATA 170,170,170,170,170,169,85,85
500 DATA 65,65,65,65,65,65,65,65
510 DATA 64,64,64,80,68,64,64,64
520 DATA 1,1,1,1,1,1,5,1
530 DATA 0,0,0,0,20,105,170,170
540 DATA 106,106,26,70,154,170,170,170
550 DATA 169,169,164,145,166,170,170,170
560 DATA 251,234,234,251,239,171,171,239
570 DATA 170,170,170,170,106,86,85,85
580 DATA 235,170,130,130,130,130,170,235
590 DATA 170,175,191,255,255,255,255,255
600 DATA 85,169,85,169,85,169,85,85
610 DATA 170,106,106,106,154,166,166,169
620 DATA 170,169,169,169,166,154,154,106
630 DATA 170,250,254,255,255,255,255,255
640 DATA 85,85,127,127,127,127,255,255
650 DATA 85,85,253,253,253,253,255,255
660 END
(mod: program source put into code tags)
Duke
Vic 20 Newbie
Posts: 13
Joined: Mon Jan 01, 2024 9:21 am
Location: Netherlands
Occupation: Teacher

Re: How do I redefine characters with 8k or more RAM?

Post by Duke »

A second issue is, you have your character set data going into 7176. I'm not sure if you meant that, but by the context of your existing code, I'd expect that to be 7168.
As far as I know, this allows me to start character redefinition at the letter A and not at the @. I think it's easier for me to make the art if I start at A. I don't know if that line truly does what I think it does, though.
Duke
Vic 20 Newbie
Posts: 13
Joined: Mon Jan 01, 2024 9:21 am
Location: Netherlands
Occupation: Teacher

Re: How do I redefine characters with 8k or more RAM?

Post by Duke »

POKE 36869, 207
HOLY COW it worked. I am able to print the image with 35k RAM making only this change. Thank you so much for the help. I'm pretty happy with how this picture turned out. I only know how to PRINT a line in one color of multicolor characters, so to change the character color at all, I have to wait for the next line. It's fun to find a way to get 10 colors to display this way. I realize also that the original program is one line too long, so you need to remove lines 370-380. This will let you see the clouds which are white and make up that precious 10th color.

I'll try to implement this change for another more animated picture I want to make and keep the rest the same. I'll share the project when I'm done.
User avatar
Mike
Herr VC
Posts: 4841
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: How do I redefine characters with 8k or more RAM?

Post by Mike »

chysn wrote:If you want to keep your custom characters at $1C00, then [...]
Point is: leaving the character set at $1C00 and lowering the BASIC limit locks away the entire expansion RAM. With the screen at $1000, this now leaves even less memory available for the BASIC program than with the unexpanded configuration!

With bigger RAM expansions, the character set must be moved under the BASIC program, and that requires one to raise the BASIC start.
Duke wrote:I'm not sure how to alter the program to account for this.
There are several methods how to do this, the one given here does not require a boot loader but you need to be wary when saving changes of the program.

With the bigger RAM expansion active (11775, 19967 or 28159 BYTES FREE in the startup prompt), first enter the following short program:

Code: Select all

10 POKE44,22:RUN
This is a BASIC stub which will automate the process later, when the program is adapted. Now raise the BASIC start by entering this similar line:

Code: Select all

POKE44,22:POKE5632,0:NEW
Note the NEW instead of RUN, this is intended and initialises the changed BASIC memory. You now proceed by loading in the original program:

Code: Select all

LOAD"PARK.PRG",8
Replace PARK.PRG with whatever filename you gave the original program. Now come the necessary changes to the program to accommodate for the screen at $1000 and the character set at $1400:
  • At first, delete line 50! No need anymore to lower the BASIC limit. To do this, enter the line number on its own and confirm by pressing [RETURN].
  • The correct value for VIC register 36869 now is 205. Change line 10 correspondingly.
  • Original purpose of lines 50..80 was to make a copy of the original character set. In line 70, change 7176 to 5120.
  • In line 100, change 7176 to 5128.
To save the adapted program, type:

Code: Select all

POKE44,18:SAVE"PARK2.PRG",8
Note the "POKE44,18" - this is necessary to save the BASIC stub you entered at first along with your adapted picture!

When you now LIST the program, all you see is that BASIC stub. Upon starting that with RUN, the POKE in the stub changes the BASIC start to the new position and issues another RUN which in turn starts your picture demo, with the character data at a protected place below the BASIC program. LIST also shows your program once again - but keep in mind, if you do further changes, always enter that POKE44,18 before SAVE.

Attached are both versions, "park.prg" for unexpanded or +3K, "park2.prg" for +8K or more (download park.zip).
Duke
Vic 20 Newbie
Posts: 13
Joined: Mon Jan 01, 2024 9:21 am
Location: Netherlands
Occupation: Teacher

Re: How do I redefine characters with 8k or more RAM?

Post by Duke »

Point is: leaving the character set at $1C00 and lowering the BASIC limit locks away the entire expansion RAM. With the screen at $1000, this now leaves even less memory available for the BASIC program than with the unexpanded configuration!
This makes another issue that I was having make more sense. I am working on animating a fireplace that will take up every place on the screen. The program is simple enough. I redefine the characters and poke them and their color into each place. It takes a lot of RAM for basic since there are so many poke statements that need to be typed in. As a test, I entered the program as I have it written on the stock machine and then with the 35k RAM. They both ran out of memory at the same place, so now that I have this piece of the puzzle I know why now and have a few more questions.

1. When I boot up the computer with 35k, do I need to always relocate the start of basic with

Code: Select all

POKE44,22:POKE5632,0:NEW
in order to access the 28k or so allocated to basic and displayed at the top?
2. How is the math best done on line 90? To get the number 206, I just randomly entered numbers until I got to this one and then it stopped saying "out of data" for line 100. I imagine this number will change with more data statements, but I'm not sure how to calculate the number correctly.
3. How did you get the number for POKE 36869,205?
If you want to keep your custom characters at $1C00, then

Code: Select all

POKE 36869, 207
4. How did you get the number for

Code: Select all

 POKE 36869,207
?

This has been a very exciting couple of days. I don't always have the time to devote to Vic-20 learning, and this is the farthest I've gotten. Working on some time developing a game for the ol' beast, but first I want to practice the mechanics by making some neat art.
User avatar
Mike
Herr VC
Posts: 4841
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: How do I redefine characters with 8k or more RAM?

Post by Mike »

Duke wrote:1. When I boot up the computer with 35k, do I need to always relocate the start of basic with

Code: Select all

POKE44,22:POKE5632,0:NEW
in order to access the 28k or so allocated to basic and displayed at the top?
No. The expanded memory as such is available right from the beginning. However, the procedure I highlighted above serves to protect the character set from the BASIC program, by restricting the BASIC memory. Not from the top, as you did before, but from the bottom - and it automates the whole process: users can simply load "PARK2.PRG" on the +8K expanded VIC-20 and start it with RUN.
2. How is the math best done on line 90?
You need to keep track of the number of DATA items by yourself. For N redefined characters, you have 8xN data items. The FOR loop then is supposed to run from 0 to 8xN-1 ... so 206 could not have been right anyhow, but you had defined enough data items to cover that issue.
3. How did you get the number for POKE 36869,205?
The VIC chip has its own view of how memory is arranged, see the following correspondence:

Code: Select all

 VIC (VA bus) | CPU (CA bus)
              |
 $0000..$1FFF | $8000..$9FFF
 $2000..$3FFF | $0000..$1FFF
Memory outside the two CPU ranges $0000..$1FFF or $8000..$9FFF does not exist for the VIC chip!

The upper four bits in VIC register 36869 together with the most sig. bit of 36866 define the position of the screen with 512 byte granularity, which is $1000 for the CPU but $3000 for the VIC chip. When you shift left $3000 by 2 binary digits, you get $C000, and it's only the upper nibble, $C, that's needed.

The lower four bits in 36869 define the position of the character set with 1K granularity. The CPU has the character set at $1400, VIC 'sees' it at $3400. Shift left $3400 by 2 binary digits, you get $D000, and we take the upper nibble, $D.

This gives $CD as result, which is 205 in decimal.

There's no need to change VIC register 36866, as that already has the correct value regardless what expansion is active. You only need to take it into regard if you move the screen memory by yourself.
4. How did [chysn] get the number for POKE 36869,207?
With the character set at $1C00 (for the CPU), the same procedure results in $CF = 207 decimal.

...

Reprising your question #2 -- obviously you have some method to generate the character data. I sincerily hope that you did not actually draw the character matrices on square paper, assign the colour sources and then work out the numbers by hand. If you however use a program for the task, that program should also offer some method to create the DATA statements and the FOR loop for you.
Duke
Vic 20 Newbie
Posts: 13
Joined: Mon Jan 01, 2024 9:21 am
Location: Netherlands
Occupation: Teacher

Re: How do I redefine characters with 8k or more RAM?

Post by Duke »

The upper four bits in VIC register 36869 together with the most sig. bit of 36866 define the position of the screen with 512 byte granularity, which is $1000 for the CPU but $3000 for the VIC chip. When you shift left $3000 by 2 binary digits, you get $C000, and it's only the upper nibble, $C, that's needed.

The lower four bits in 36869 define the position of the character set with 1K granularity. The CPU has the character set at $1400, VIC 'sees' it at $3400. Shift left $3400 by 2 binary digits, you get $D000, and we take the upper nibble, $D.

This gives $CD as result, which is 205 in decimal.
This is wonderfully helpful, though a lot to unpack. I think it would be a good idea to start learning how to convert the Hex into Decimal. Since I type all of the information into basic at the moment, which is usually the decimal and not Hex, it is easier to use the decimal numbers. Though that is probably making it more difficult for me to understand the help. I also have to learn what "lower four bits" means. Looks like I've got more reading and experimenting to do. The VIC manual is right. I need to experiment a LOT.
obviously you have some method to generate the character data. I sincerily hope that you did not actually draw the character matrices on square paper, assign the colour sources and then work out the numbers by hand. If you however use a program for the task, that program should also offer some method to create the DATA statements and the FOR loop for you.
I use the Vic-20 Screen Designer and copy the data statements that it generates. I didn't see anything to help me calculate line 90, but I will look for it. A link to the program can be found here: http://www.fox-ts.co.uk/vic20sdd/Vic20SDD.htm. Here is how I understand your explanation. A data statement such as

Code: Select all

1010 DATA 170,170,170,85,85,170,85,85
has 8 bits of data represented by the number of numbers separated by commas. So since my program has 26 Data statements and they each have 8 bits of data, 26*8=208. Since numbers start at zero, I need to subtract 1. 208-1=207.

Code: Select all

90 For X = 0 TO 207
would be a more accurate line. I just happened to get close due to random guessing (experimenting?) which really made me jump out of my seat when it printed the park the first time. Would this be correct?

Thank you for continued support on this. It's so cool that there are people out there that know so much about "The Wonder Computer of the 1980s". I'll be spending my free time this year learning how to perform all the different functions that a game has step by step. I'm starting with the art because that's my favorite part. I imagine learning this will help in other areas, if anything just to understand the logic of the computer and computing in general on a vic-20.
User avatar
Mike
Herr VC
Posts: 4841
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: How do I redefine characters with 8k or more RAM?

Post by Mike »

Duke wrote:Would this be correct?
Exactly. :mrgreen:

Just a small remark about your use of "bits": from context it is clear what you mean with "data bits", but in the field of computer science, bit is a established term to denote the smallest amount of information, with its value being either true or false. The numbers (or another things) contained in DATA statements should be referred to as items instead. :)
Duke
Vic 20 Newbie
Posts: 13
Joined: Mon Jan 01, 2024 9:21 am
Location: Netherlands
Occupation: Teacher

Re: How do I redefine characters with 8k or more RAM?

Post by Duke »

Good morning.

I'm a bit frustrated with the vic-20 at the moment. I am trying to write a program for an 8k+ RAM expanded machine. Similar to my other programs, it is going to draw a picture of a tower reaching for the sky. Before POKEing the characters into their screen positions and then POKEing the colors into their screen positions, I like to make sure that the program is first redefining the characters correctly. I've written a program with everything I've learned from the previous parts of this thread, and I've hit a road block that I don't know if I'm capable of breaking by myself.

The error is so strange and I'm not sure how to describe it. When I enter the code into the machine, I get a syntax error that says "error in 20". This is a data statement that is written correctly. When I list line 20, it shows a few other things in the line that I didn't type, and just shows a block of letters for the rest of the data statements. I must be doing something wrong, but I can't for the life of me figure it out. If I can get this program working properly, I will be able to make a rinse and repeat template for drawing pictures with 26 characters. I plan to post the project here to help people start drawing in 35k with some ease, but I just need to get past this hurdle. Here is my code:

Code: Select all

1 POKE36869,205:POKE646,10:POKE36879,168:POKE36878,225
2 FOR X=0 TO 511: POKE5120+X,PEEK(32768+X): NEXT X
3 FOR X=0 TO 207: READ A: POKE5128+X,A: NEXT X

10 DATA 255,255,255,255,255,255,255,255
11 DATA 255,255,247,217,105,105,215,255
12 DATA 85,169,169,85,85,106,106,85
13 DATA 85,106,106,106,106,106,106,85
14 DATA 85,169,169,169,169,169,169,85
15 DATA 102,102,102,102,102,102,102,102
16 DATA 170,170,170,170,170,170,170,170
17 DATA 105,105,85,105,150,170,105,85
18 DATA 85,105,170,150,105,85,105,105
19 DATA 85,85,86,86,102,102,102,102
20 DATA 85,85,101,101,102,102,102,102
21 DATA 170,170,101,85,152,34,136,34
22 DATA 136,34,136,34,8,0,0,0
23 DATA 102,153,101,150,170,170,170,170
24 DATA 0,0,0,0,64,144,164,169
25 DATA 64,144,164,169,170,170,170,170
26 DATA 0,0,0,0,1,6,26,106
27 DATA 1,6,26,106,170,170,170,170
28 DATA 170,170,170,170,106,154,166,169
29 DATA 106,154,166,169,170,170,170,170
30 DATA 170,170,170,170,169,166,154,106
31 DATA 169,166,154,106,170,170,170,170
32 DATA 255,255,255,127,247,253,255,255
33 DATA 221,119,221,119,221,119,221,119
34 DATA 85,105,105,85,85,105,105,85
35 DATA 0,0,65,65,150,170,170,170
I haven't added any POKE statements yet. I don't usually write those until I'm sure that the characters will redefine properly. Otherwise it's difficult to troubleshoot errors with the picture.
User avatar
tokra
Vic 20 Scientist
Posts: 1123
Joined: Tue Apr 27, 2010 5:32 pm
Location: Scheessel, Germany

Re: How do I redefine characters with 8k or more RAM?

Post by tokra »

You are overwriting your BASIC-program with the chars you are reading. Essentially you are cutting down the tree you are sitting on. You need to protect your BASIC-memory from the character-definitions you are writing to memory. As mentioned earlier in this thread you need to increase the BASIC-start-address so that the chracter-definitions can reside in memory below them. And for that you need to:

Code: Select all

POKE44,22:POKE5632,0:NEW
before typing in or loading the program you mentioned above. This puts the BASIC-start at decimal 5632 and your program writes the characters from 5120 to 5631. This way the both do not interfere.
User avatar
Mike
Herr VC
Posts: 4841
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: How do I redefine characters with 8k or more RAM?

Post by Mike »

For more details, please read this post in the thread "How to reinit 16k expansion?", and to quote from there:
Mike wrote:It all boils down to what contiguous address range in RAM is available for a BASIC program and its variables, what address range of RAM is accessible for the VIC chip and whether these two address ranges might collide and need to be separated.
and
Mike wrote:With user defined graphics, VIC not only needs to read text screen data from its restricted memory range, but also the character matrixes of the user defined graphics. It must be ensured, that the user defined graphics do not collide with the BASIC program or its variables: when the program POKEs the character matrixes from DATA lines, it could inadvertently overwrite itself; likewise the variables (especially strings) might overwrite the character data that has already been defined in RAM.
Emphasis added.

Also note that this very post is linked to from the sticky post "VIC-20 Memory Layout" in the Programming section.
Duke
Vic 20 Newbie
Posts: 13
Joined: Mon Jan 01, 2024 9:21 am
Location: Netherlands
Occupation: Teacher

Re: How do I redefine characters with 8k or more RAM?

Post by Duke »

Thanks for all the help. I have successfully drawn a full screen image using 8k+ RAM configuration. Here is the image.
success.jpg
I'll post more later. Just happy that it works.
Post Reply