Character set

From C64-Wiki
(Redirected from Character)
Jump to navigationJump to search

A character set is a body of information that describes the visual appearance of up to 256 characters: Since each character take 8 bytes of information, a full character set requires 256 × 8 bytes = 2 kB. While the text screen system was originally designed to provide the hardware facilities for a "console" text screen, it is also widely used along with user-supplied "character" sets to form graphics in games, demos etc.

The Character sets[edit | edit source]

Users can switch between character sets by holding SHIFT and pressing the Commodore Key, by printing control characters 14 or 142 or also with POKE 53272,23 for character set 2 and POKE 53272,21 for character set 1.

Overview of character set switching:

Char set POKE PRINT CHR$(x)
1 53272,21 14
2 53272,23 142

Defining a high-resolution character[edit | edit source]

 0  1  1  0  0  1  1  0  = 102/$66
 0  0  0  0  0  0  0  0  = 0/$00
 0  0  1  1  1  1  0  0  = 60/$3C
 0  0  0  0  0  1  1  0  = 6/$06
 0  0  1  1  1  1  1  0  = 62/$3E
 0  1  1  0  0  1  1  0  = 102/$66
 0  0  1  1  1  1  1  0  = 62/$3E
 0  0  0  0  0  0  0  0  = 0/$00

Each character in high resolution mode is formed by a matrix of 8 × 8 pixels, as illustrated to the right. Every pixel corresponds to a bit within these 8 bytes, and a bit that's "on" or "1" becomes visible in the "foreground" color for character in the Color RAM at 55296–56295/$D800–DBE7, whereas bits that are "off" or "0" appear in the background color.

Each horizontal row in the matrix corresponds to a byte, read with the most significant bit, or pixel, to the left, and the least sigificant one at the right-hand end. The first of the eight byte corresponds to the topmost row, and the last of the eight byte to the bottom row. In the example to the right, the eight byte values to render the letter "ä" as shown, are 102, 0, 60, 6, 62, 102, 62, and 0, or in hexadecimal: $66, $00, $3C, $06, $3E, $66, $3E, and $00.

Defining a multi-color character[edit | edit source]

 1  1  1  1  1  1  1  1  = 255/$FF
 1  1  1  1  1  1  0  1  = 253/$FD
 1  1  1  0  1  0  0  1  = 233/$E9
 1  1  1  0  1  0  0  1  = 233/$E9
 1  1  1  0  1  0  0  1  = 233/$E9
 1  1  1  0  1  0  0  1  = 233/$E9
 1  1  0  1  0  1  0  1  = 213/$D5
 0  1  0  1  0  1  0  1  = 85/$55

In multicolor mode, the pixels are "joined" two at a time to form "bit pairs", yielding a matrix of 4 "double-width" pixels by the same 8 rows as in high-resolution mode: An example of this principle is shown to the right.

Depending on the bit-pair combination, the color of each pixel will be:

  • Transparent, or "background" if the bit pair is "00"
  • The color indicated in address 53282/$D022 where the bit pair is "01"
  • The color indicated in address 53283/$D023 where the bit pair is "10"
  • The character's individual color (55296–56295/$D800–DBE7) where the bit pair is "11"

The text screen in multicolor mode uses the most significant of the four bits in each character's individual color: This means that the screen can display both multicolor and high resolution characters side-by-side, but the disadvantage is that the individual color for each multicolor character can only be chosen from the second half (color codes 8 thru 15) of the normal 16-color palette. The two colors stored in 53282/$D022 and 53283/$D023 are common for all multicolor characters on screen, but may assume any of the 16 available color codes.

  • Activate the multicolor mode: POKE 53270,PEEK(53270) OR 16
  • Deactivating the multicolor mode: POKE 53270,PEEK(53270) AND 239

Character sequence[edit | edit source]

The eight-byte "blocks" that form each character follows the same sequence as in the table of screen character codes, i.e. the very first 8 bytes form the visual appearance of the @ sign, the following 8 bytes form the letter "a", etc. The general rule is that if the whole character set starts at addres s, the character whose screen character code is n will start at address s + 8 × n.

"Reverse on" characters[edit | edit source]

In the two standard ROM character sets, the upper 128 characters in each set is a "reverse", or "negative image", of the first 128 characters: The KERNAL operating system depends on this for displaying the flashing cursor, control characters in LISTings, etc.

Configuring VIC for a character set[edit | edit source]

A user-supplied character set in RAM must begin at an address that divides with 2048 bytes leaving no remainder, and reside within the same 16 kB VIC bank as the screen character memory. Moreover, the VIC-II cannot see a character set in RAM beginning at either 4096/$1000, 6144/$1800, 36864/$9000, or 38912/$9800, since these areas are "overshadowed" by the ROM character sets, as seen in VIC-II's address space.

The pointers to the character set and the screen character memory both reside in address 53272/$D018. Also see Address 53272 for values to put in this address for given combinations of character set and screen RAM start addresses.

Programming[edit | edit source]

This slow BASIC routine copies the char set ROM into the RAM (12288 - 16383) for manipulating.

POKE 56334, PEEK(56334) AND 254                      (Interrupts deactivate)
POKE 1, PEEK(1) AND 251                              (E/A area deactivate, char set ROM online)
FOR A=53248 TO 57343: POKE A-40960, PEEK(A): NEXT A  (copy routine)
POKE 1, PEEK(1) OR 4                                 (E/A area activate)
POKE 56334, PEEK(56334) OR 1                         (Interrupts activate)
POKE 53272,PEEK(53272) AND 240 OR 12 : REM CHAR SET RAM AT $3000 (Sets soft character base address)
  • This short BASIC program deletes a char (here: @): FOR X=12288 TO 12295: POKE X,0: NEXT X
  • And this BASIC program creates a fully rectangle char for the @: FOR X=12288 TO 12295: POKE X,255: NEXT X

German Example[edit | edit source]

Example: 4 new chars for the C64 (German mutated vowel) on a test screen (written in german)

This listing has 2 parts: Firstly the copy routine (now a fast assembler routine) for copying char set ROM into RAM ($3000-$3FFF; lines 10-30) an secondly the modifying of the chars (keys; after line 60) [ , £ , ]  and   to the German mutated vowel Ä, Ö, Ü, ß. These can be made with POKE 1024,X (with 27, 28, 29, 30) or with PRINT CHR$(X) (with 91, 92, 93, 94) print on the screen (but not print on a printer!).

10 REM COPY ROUTINE
11 FOR I=0 TO 26: READ X: POKE 828+I,X: NEXT I
12 DATA 169,000,160,208,133,095,132,096 : REM LDA #0; LDY #$D0; STA 95, STY 96
13 DATA 169,000,160,224,133,090,132,091 : REM LDA #0; LDY #$E0; STA 90; STY 91
14 DATA 169,000,160,064,133,088,132,089 : REM LDA #0; LDY #$40; STA 88; STY 89
15 DATA 076,191,163 : REM JMP $A3BF
16 REM COPY $D000-$DFFF -> $3000-$3FFF
20 REM CHAR SET ROM INTO RAM 
21 POKE 56334,PEEK(56334) AND 254 : REM INTERRUPT OFF
22 POKE 1,PEEK(1) AND 251 : REM CHAR SET ROM ON
23 SYS 828 : REM START COPY
24 POKE 1,PEEK(1) OR 4 : REM CHAR SET ROM OFF
25 POKE 56334,PEEK(56334) OR 1 : REM INTERRUPT ON
26 POKE 53272,PEEK(53272) AND 240 OR 12 : REM CHAR SET RAM AT $3000
60 REM GERMAN MUTATED VOWEL
61 FOR A=12504 TO 12535: READ ZE: POKE A,ZE: POKE A+1024,255-ZE: NEXT A
62 DATA 195,024,102,126,102,102,102,000: REM AE-Ä
63 DATA 102,060,102,102,102,102,060,000: REM OE-Ö
64 DATA 102,000,102,102,102,102,060,000: REM UE-Ü
65 DATA 126,102,102,126,102,126,096,096: REM SS-ß

U5 Character ROM Failure Symptoms[edit | edit source]

  • Normal startup border, but "garbage" characters where startup page characters should be.
  • Cartridge works.

Links[edit | edit source]