MULTICOLOR-CHARACTERS-VIC-20 -------------------------------------------------------------------------------------------------- TOOL: COMMODORE VIC-20 - BASIC 2 {Commodore C128 SPRDEF, SPRite DEFinition Tool/Editor} Language: BASIC Extra: - Author: Misel Zivanovic Note: (C) 4th JAN 2026 - www.lived.ch, mzretro.ch --------------------------------------------------------------------------------------------------- Last time we created normal Characters, and with this lesson MultiColor version of the same Characters will be made. It just need a slight adaptation. How MultiColor is working is already known! In case you missed that lesson, you probably will have your issues here. Don't blame me for your failures, haha... C128 SPRDEF COLOR CHOICE Commands: {to work with correct colors} SPRCOLOR 7,8 SPRITE 1,1,4 {00 - 01 } - POKE 36879,INV+{border col}+{screen col x 16} - Border/BG {1} & {2} SPRDEF : COLOR N#2/N#1 {DEL,Screen} 10 - POKE 38400,X+MC - Color MAP {3} SPRDEF : COLOR N#3 11 - POKE 36878,SND+{COLOR x 16} - MC Register {4} SPRDEF : COLOR N#4 INV = 8 = normal INV = 0 = reverse I created the everything by using Commodore C128, SPRDEF {SPRite DEFinition Editor}. SPRDEF is a SPRITE Editor, however, you can literally do everything else too! E.g. normal characters, multicolor characters, graphic elements... What is equal to what you can see already listed above this. Here a little bit more detailed explanation for better understanding: POKE 36879,8+6+(0x16) : --------------------------------------------------------------------------------------------------- {8 is RVSOFF, 6 is the blue color and 0x16 black background} This represents SPRDEF COLOR N#2 {blue, 6} and 0x16 = black, is N#1 in SPRDEF or SCREEN/BG color {actually used for deletion}. With this address you are covering bit 00 and 01 --------------------------------------------------------------------------------------------------- POKE 38400,8+7 : --------------------------------------------------------------------------------------------------- {limited to 8 colors maximum!} {8 is MULTICOLOR ON + COLOR 0-7} This is SPRDEF Color N#3. COLOR MAP is a field of 506 bytes. And as i have found out {unless i did something wrong}, you need to do this step and the very end when the characters are on the screen already! {See the full source code below or here} 301 for e=0 to 505 302 poke 38400+e,3+8 303 next 304 poke 646,3+8:rem cyan {POKE 646,3+8 is also setting MULTICOLOR ON and cyan color to continue with the MC-Text} --------------------------------------------------------------------------------------------------- POKE 36878,(0x16) : --------------------------------------------------------------------------------------------------- This is a 4th, last color of the MultiColor registers and actually its LOW-Nibble values are impacting the sound volume and in HIGH-Nibble area it is delivering colors when MultiColor is active. We aren't using any sound and can type POKE 36878,5x16 to get the needed color. However, because this address is impacting also the sound volume, this would set any existing sound volume to 0 and you would stay without it. Let's say we have the sound volume set to 8 = POKE 36878,8, and later we want the orange color, which is POKE 36878,8x16. Writing just POKE 36878,8x16 would set the volume to zero! Not what you want, trust me! To avoid that and make sure you'll have no problems with such registers in general, you have 2 options! That is making sure you'll keep the existing tasks running and add your values to it! OPTION 1: POKE 36878,8 POKE 36878,(peek(36878) AND 15) OR (8x16) = 136 {8x16=128 + 8 = 136) OPTION 2: POKE 36878,8 {Set Volume level} v=peek(36878):POKE 36878,8x16+v {ADD Color to it} = 136 x = * --------------------------------------------------------------------------------------------------- SOURCE CODE - ALL IN ONE - {can be copy/pasted into VICE VIC-20 Emulator} --------------------------------------------------------------------------------------------------- 50 a=643:b=644 51 poke51,0:poke52,24 52 poke55,0:poke56,24 53 poke a,0:poke b,24 54 clr 100 sys 58719:rem cls 101 poke 36869,254 102 rem top blue 103 rem also border 104 poke 36879,8+6+(0*16) 105 rem bottom yellow 106 poke 36878,7*16 107 rem 110 t=6144:s=32768 111 for a=0 to 1023 112 poket+a,peek(a+s) 113 next 114 forc=0 to 207:readd 115 poket+8+(c),d:next 116 data 0,20,68,136,168,204,204,204 117 data 0,20,68,136,160,204,204,240 118 data 0,20,68,128,128,192,204,252 119 data 0,80,68,136,136,204,204,240 120 data 0,20,68,128,160,192,204,252 121 data 0,20,68,128,160,192,192,192 122 data 0,20,68,128,152,204,204,252 123 data 0,4,68,136,168,204,204,204 124 data 0,4,16,32,32,48,48,48 125 data 0,4,4,8,8,12,204,60 126 data 0,4,68,144,160,196,204,204 127 data 0,16,64,128,128,192,204,252 128 data 0,4,68,152,136,204,204,204 129 data 0,4,68,136,104,220,196,204 130 data 0,20,68,136,136,204,204,252 131 data 0,20,68,136,168,192,192,192 132 data 0,20,68,136,136,204,220,244 133 data 0,20,68,136,168,240,204,204 134 data 0,20,68,128,168,12,204,252 135 data 0,84,36,32,32,48,48,48 136 data 0,4,68,136,136,204,204,252 137 data 0,4,68,136,136,204,60,12 138 data 0,4,68,136,136,68,220,204 139 data 0,4,68,136,32,48,204,204 140 data 0,4,68,136,168,48,48,48 141 data 0,84,4,8,32,48,192,252 142 rem numbers 0 - 10 (48-57) 144 form=208 to 287:readn 145 poke 6320+m,n:next 146 data 0,16,68,136,136,204,204,48 147 data 0,16,80,32,32,48,48,48 148 data 0,84,68,8,40,48,192,252 149 data 0,84,68,8,32,8,204,252 150 data 0,4,20,136,168,12,12,12 151 data 0,84,64,128,168,12,12,252 152 data 0,84,68,128,168,204,204,252 153 data 0,84,68,8,40,48,48,48 154 data 0,84,68,136,168,204,204,252 155 data 0,84,68,136,168,12,204,252 156 rem gfx shift+abcdef 157 form=288 to 335:readn 158 poke 6376+m+(0*8),n:next 159 data 97,121,77,121,109,113,109,73 160 data 20,116,85,34,136,85,116,20 161 data 20,29,85,34,136,85,29,20 162 data 170,100,24,9,36,144,32,8 163 data 66,36,8,2,8,9,38,170 164 data 81,69,81,69,81,69,81,69 200 rem cursor 201 poke 7424,0 202 poke 7425,85 203 poke 7426,109 204 poke 7427,56 205 poke 7428,109 206 poke 7429,56 207 poke 7430,109 208 poke 7431,85 209 print "lived.ch, mzretro.ch" 210 print "font made for vic-20" 211 print 212 print "abcdefghijklm" 213 print "nopqrstuvwxyz" 214 print 215 print "0123456789" 216 print 217 print "shift + abcdef" 218 print "for gfx elements!" 300 rem middle cyan 301 for e=0 to 505 302 poke 38400+e,3+8 303 next 304 poke 646,3+8 --------------------------------------------------------------------------------------------------- SPRDEF EXPORT: {BEHIND THE SCENES} --------------------------------------------------------------------------------------------------- I wrote this small program to export the characters from SPRDEF {Commodore C128} {Note: C128 program, not VIC-20!} 10 print chr$(147):for a=0 to 2:forb=3584+ato3605+astep3 20 printpeek(b);chr$(20);chr$(44);:next:printchr$(20):printchr$(13):next 30 for a=0 to 2:forb=3608+ato3629+astep3 40 printpeek(b);chr$(20);chr$(44);:next:printchr$(20):printchr$(13):next It really isn't much and you need to clean it, add line numbers and DATA. OUTPUT: 97, 121, 77, 121, 109, 113, 109, 73 20, 116, 85, 34, 136, 85, 116, 20 20, 29, 85, 34, 136, 85, 29, 20 170, 100, 24, 9, 36, 144, 32, 8 66, 36, 8, 2, 8, 9, 38, 170 81, 69, 81, 69, 81, 69, 81, 69 Ready. Then you need to clean it a bit, add, as said, line numbers and data command to it. End result: Order is ABCDEF. Line 101 = A ... Line 106 = F 101 data 97, 121, 77, 121, 109, 113, 109, 73 102 data 20, 116, 85, 34, 136, 85, 116, 20 103 data 20, 29, 85, 34, 136, 85, 29, 20 104 data 170, 100, 24, 9, 36, 144, 32, 8 105 data 66, 36, 8, 2, 8, 9, 38, 170 106 data 81, 69, 81, 69, 81, 69, 81, 69 Then I squeeze lines by replacing ,{SPACE} with just , {CONTROL + H in Windows EDIT program for REPLACE} End result: 101 data 97,121,77,121,109,113,109,73 102 data 20,116,85,34,136,85,116,20 103 data 20,29,85,34,136,85,29,20 104 data 170,100,24,9,36,144,32,8 105 data 66,36,8,2,8,9,38,170 106 data 81,69,81,69,81,69,81,69 --------------------------------------------------------------------------------------------------- Now you're sure asking yourself why don't i write a program which will do that automatically! Well, good question, haha... {I'll leave that task to you} I love to keep my brain working! --------------------------------------------------------------------------------------------------- To be honest, i wrote one which is exporting .byte data i used in EDASS 128 assembler to write the level editor {in assembler} {Note: C128 program, not VIC-20!} 0 l1$=" .byte ":l2$=" .byte ":scnclr 5 char0,0,0:fora=0to2:char0,0,0+a,l1$ 10 l1$=" .byte " 15 forb=3584+ato3605+astep3:dd=peek(b) 20 gosub 60 25 printright$(hex$(dd),2);:next:next 30 for a=0to2:char0,0,4+a,l2$ 35 l2$=" .byte " 40 forb=3608+ato3629+astep3:ee=peek(b) 45 gosub 80 50 printright$(hex$(ee),2);:next:next 55 char 0,0,16:end 60 p$=",$":ifb=3584thenp$="$" 65 ifb=3585thenp$="$" 70 ifb=3586thenp$="$" 75 print p$;:return 80 p$=",$":ifb=3608thenp$="$" 85 ifb=3609thenp$="$" 90 ifb=3610thenp$="$" 95 print p$;:return