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

Basic and Machine Language

Moderator: Moderators

User avatar
Mike
Herr VC
Posts: 5130
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:[...] Now when I run the program again, the reverse characters come out redefined even though the redefinition is for the first 64 characters only. This is just a jumbled mess. What is weirder is that if you turn on the lower case character set, the text comes out readable, but it doesn't seem reversed. [...]
The video chip takes the base address of the character generator and applies it to the whole screen (unless you use some advanced programming techniques far beyond the scope of this thread here).

PRINT with RVS OFF only prints screen codes in the range 0..127. When you use RVS ON with PRINT, PRINT outputs characters in the top half of the character set, screen codes 128..255. It is just their definition as inverses of the lower half characters in the ROM character generator (for each of the two complete ROM character sets), that makes them appear inverse. That does not (need to) hold in general for user defined characters. You are free to define all 256 of them as you want, which means that the character with the screen code 128+X is not necessarily the inverse of screen code X.

That also means, if you want to use 'inverse' characters (or any other form of highlighting) with own, user defined characters, that has to go into the definition itself. If you miss out on the defining part there, VIC merrily displays what is there in RAM otherwise - which just is the 'jumbled mess' you see. :)

...

That the notion of RVS ON has to be taken with a grain of salt also shows in the fairly standard trick of accessing the upper case non inverse ROM characters with POKE36869,255. With the screen at 7680, the character set at 7168 and the latter in turn protected with POKE55,0:POKE56,28:CLR this gives 64 UDGs (screen codes 0..63), the screen codes 64..127 overlap with the text screen and cannot sensibly be used, and RVS ON accesses screen codes 128..255, but due to an address wraparound in the VIC-20 hardware, these screen codes now map to the upper case non inverse ROM characters!

On an unexpanded VIC-20, or with +3K RAM expansion, this trick saves some memory which otherwise would be necessary to provide a readable text character set - as long as you are content with the ROM definitions for that. With a bigger RAM expansion, you do not normally want to keep the UDGs at the position 7168 = $1C00, as they then there block a substantial amount of RAM in the middle of BASIC memory ($1201..$3FFF/$5FFF/$7FFF).

Two possible options with +8K or more, and with a full(!) UDG character set are:
  • keep the text screen at 4096 = $1000, place the UDGs at 5120 = $1400 .. 7167 = $1BFF. Raise the BASIC start to $1C01 with POKE7168,0:POKE44,28:NEW
  • place the UDGs at 4096 = $1000, move the text screen to 6144 = $1800 and raise the BASIC start to $1A01 with POKE6656,0:POKE44,26:NEW
The first option is compatible with the BASIC stub method I explained earlier in this thread, but lays some memory waste between BASIC stub and UDGs, in the range $12xx..$13FF. The second option gives some extra memory, but overwrites the BASIC stub with the UDGs upon first execution and is more suitable for a finalised program version.

Starting from a freshly powered on VIC-20 and +8K (or more) RAM expansion, you would install the first option as follows (recapitulating the BASIC stub method here):

1. Enter the BASIC stub:

Code: Select all

2025 POKE44,28:RUN
2. Raise the BASIC start manually:

Code: Select all

POKE44,28:POKE7168,0:NEW
3. Make a copy of the upper case character set into RAM, in direct mode. Note, this only needs to be done once and then can be left out of the main program, unless you overwrite a part of the ROM copy by accident:

Code: Select all

FORT=0TO2047:POKE5120+T,PEEK(32768+T):NEXT
4. Enter this small program that activates the UDGs at $1400 upon RUN, keeping the text screen at $1000:

Code: Select all

1 POKE36869,205
Upon RUN, nothing seems to change, but VIC now accesses the RAM copy at 5120 for the character definitions.

5. Save the whole lot - BASIC stub, UDGs and payload - with:

Code: Select all

POKE44,18:SAVE"name",8
Upon LIST, you now only see the BASIC stub from step 1. When RUN, the BASIC start is raised automatically, and the RUN in the BASIC stub does not re-run the BASIC stub, but starts the payload - at the moment, the small program with POKE36869,205. You can now edit the payload or load in a complete new program as payload. To retain the BASIC stub and UDGs upon SAVE, then always proceed as per step 5.
Post Reply