PLUS4-Animated-Characters-Assembly --------------------------------------------------------------------------------------------------- TOOL: BASIC 3.5 and TURBO-ASSEMBLER-MACRO and built-in ML-Monitor Language: BASIC and Assembly Extra: none Author: Misel Zivanovic Note: (C) 26th JULY 2026 - www.lived.ch, mzretro.ch Credits 1: 8-bit BASIC - https://www.youtube.com/@8-BitBasic/videos Credits 2: Milasoft - https://www.youtube.com/@MilasoftSoftware/videos =================================================================================================== --------------------------------------------------------------------------------------------------- UPDATE: IMPORTANT ADDITIONAL UPDATE, 23:03 12.08.2026 {below the assembly source code!} --------------------------------------------------------------------------------------------------- CUSTOM ANIMATED and STATIC CHARACTERS in INTERRUPT mode! I got inspired after seeing the videos on YouTube, 8-bit BASIC and character anim code on Milasoft channel. Never before I had to do something with Commodore Plus 4, however Plus4 is similar to other Commodore computers and this wasn't so difficult to make. It was a medium challenge nevertheless to lure the addresses out of the darkness! And to check the MERLIN 7501 assembler. There are as always never any guides available. So i made my own during the coding journey! --------------------------------------------------------------------------------------------------- ************* SMALL UPDATE: ************* Now this code cannot be started 2x and it will not crash your BASIC if you would accidentally start it the 2nd time while it's already running! 2nd start is only possible if you first QUIT this INTERRUPT by pressing SHIFT + Q when the cursor is located in the LEFT UPPER corner! Otherwise it will just return to BASIC if you try! That were just a few bytes of code, but the impact is huge! Want to code yourself with MERLIN 7501 ASSEMBLER on COMMODRE PLUS4? Then do it! Haha... --------------------------------------------------------------------------------------------------- NOTE {MANDATORY TASK!} --------------------------------------------------------------------------------------------------- You MUST run these 4 commands as first {in direct mode} AFTER the start of MERLIN 7501 ASSEMBLER... poke 43,1:poke 44,80:poke 20480,0:new ...AND BEFORE you do load or copy/paste this source code below! --------------------------------------------------------------------------------------------------- That is necessary because default source code start address is $2100! We can't have that because we want our program to be compiled exactly at that address! These 4 commands are moving the MERLIN source code {precisely, the source code of your program to the address $5000 and up!} Also $2000 until $2100 is occupied by MERLIN 7501 ASSEMBLER and CANNOT be used as a start address for own programs! So the first possible address is $2100 and what we are using here! --------------------------------------------------------------------------------------------------- 10 com $2100 11 list 12 lda .stat 13 cmp #55 14 beq .nomore 15 bne .runit 16 .nomore 17 rts 18 .runit 19 lda #55 20 sta .stat 100 ;assembler merlin 7501 103 ;c= plus 4 - mzretro-ch 104 ;irq chars anim 105 ;rom to ram 106 ;sys 20480 107 ;credits: 108 ;8-bit basic & milasoft 109 ; 110 lda #$00 111 sta $03 112 sta $05 113 lda #$38 114 sta $04 115 lda #$d0 116 sta $06 117 ldy #$00 118 .loop1 119 lda ($05),y 120 sta ($03),y 122 iny 123 bne .loop1 124 inc $04 125 inc $06 126 lda #$d8 127 cmp $06 128 bne .loop1 129 lda $ff12 ;read status 130 and #251 ;switch 131 sta $ff12 ;ram characters 132 lda $ff13 ;set 133 and #3 134 ora #56 ;location 135 sta $ff13 ;$3800 136 ; 137 ldx #$00 ;custom chars 138 .more 139 lda .chars,x 140 sta $3a08,x 141 inx 142 cpx #104 ;13 chars 143 bne .more ; 150 sei 151 lda #$61 ;when code is added 152 sta $0314 ;check the low and 153 lda #$21 ;high byte address! 154 sta $0315 ;for the irq start 161 ldy #$00 ; 162 sty $0be8 ;main delay 167 cli 168 rts 169 ; 170 ldy $0be8 ;< irq start address 171 iny ; low high byte 172 sty $0be8 173 ldy $0be8 174 cpy #$10 ;keep y > 1! 175 beq .anim ;anim speed 176 ;---------- 177 lda $0c00 ;press shift+q 178 cmp #81 ;to exit the 189 beq .out ;interrupt mode! 190 .exit ;where: 191 jmp $ce0e ;left upper corner! 200 ; ;in capitol char mode 250 .out ;exit to basic, no irq 251 lda $ff12 ;read status 252 ora #4 ;set characters 253 sta $ff12 ;back to 254 lda $ff13 ;original 255 and #3 ;rom 256 ora #$d0 ;source 257 sta $ff13 ;$d000-53248 258 lda #$00 259 sta .stat 260 sei ;safe exit 261 lda #14 ;no reset needed! 262 sta $0314 263 lda #206 264 sta $0315 265 cli 266 pla 267 tay 268 pla 269 tax 270 pla 271 rti 272 rts 273 ; 280 .anim 290 ; shift + char 300 lda $3a08 ;a 301 sta $0fe9 ;a 302 lda $3a10 ;b 303 sta $0fea ;b 304 lda $3a18 ;c 305 sta $0feb ;c 306 lda $3a20 ;d 307 sta $0fec ;d 308 ;next... 309 ldx #$00 310 .loop2 311 lda $3a09,x ;a 312 sta $3a08,x ;a 313 lda $3a11,x ;b 314 sta $3a10,x ;b 315 lda $3a19,x ;c 316 sta $3a18,x ;c 317 lda $3a21,x ;d 318 sta $3a20,x ;d 319 ;next... 320 inx 321 cpx #$07 322 bne .loop2 323 lda $0fe9 ;a 324 sta $3a08,x ;a 325 lda $0fea ;b 326 sta $3a10,x ;b 327 lda $0feb ;c 328 sta $3a18,x ;c 329 lda $0fec ;d 330 sta $3a20,x ;d 331 ;next... 400 ;- 401 ;down--------- 402 ;- 403 ldx #$07 403 lda $3a28,x ;e 404 sta $0fe9 ;e 405 lda $3a30,x ;f 406 sta $0fea ;f 407 lda $3a38,x ;g 408 sta $0feb ;g 409 lda $3a40,x ;h 410 sta $0fec ;h 411 ;next... 412 dex 413 ; 414 .loop3 415 lda $3a28,x ;e 416 sta $3a29,x ;e 417 lda $3a30,x ;f 418 sta $3a31,x ;f 419 lda $3a38,x ;g 420 sta $3a39,x ;g 421 lda $3a40,x ;h 422 sta $3a41,x ;h 423 ;next... 424 dex 425 bpl .loop3 426 lda $0fe9 ;e` 427 sta $3a28 ;e 428 lda $0fea ;f 429 sta $3a30 ;f 430 lda $0feb ;g 431 sta $3a38 ;g 432 lda $0fec ;h 433 sta $3a40 ;h 434 ;next... 435 ; 700 ldy #$00 ;reset main delay 701 sty $0be8 ; 702 jmp .exit ;!mandatory! 703 ; 704 ;2nd run yes/no 705 .stat 706 *da $00 707 ; 800 .chars 801 ;move up - shift+a,b,c,d 802 *da $66,$bd,$db,$da,$da,$db,$a5,$7e 803 *da $e7,$db,$bd,$7e,$e7,$db,$bd,$7e 804 *da $99,$42,$24,$18,$18,$3c,$7e,$ff 805 *da $99,$5a,$bd,$7e,$66,$a5,$42,$81 806 ;move down - shift+e,f,g,h 807 *da $7e,$a5,$db,$5b,$5b,$db,$bd,$66 808 *da $7e,$bd,$db,$e7,$7e,$bd,$db,$e7 809 *da $ff,$7e,$3c,$18,$18,$24,$42,$99 810 *da $81,$42,$a5,$66,$7e,$bd,$5a,$99 820 ;still - shift+i,j,k,l,m 825 *da $3c,$7e,$e3,$cf,$df,$df,$7e,$3c 830 *da $6e,$d5,$89,$23,$88,$b3,$45,$95 835 *da $7f,$ff,$ff,$fb,$b7,$ff,$dd,$aa 840 *da $a5,$3c,$db,$76,$6e,$db,$3c,$a5 850 *da $24,$3c,$db,$6e,$76,$db,$3c,$24 900 end --------------------------------------------------------------------------------------------------- ********************************************* IMPORTANT ADDITIONAL UPDATE, 15:33 12.08.2026 {NEW KNOWLEDGE} ********************************************* COMMODORE C128 has a BLOAD function to load a binary file into memory inside of the BASIC line, so not just in DIRECT Mode. This was meant to be used with BASIC 3.5 and running in background and it does run in background. However, what i have found out today, is that as soon as I RUN this BASIC program, the RUN { in reality it is the GRAPHIC command} is disabling the new characters mapping and then you see nothing! Adding lines 125 and 126 did help! Starting your BASIC code like this will resolve the problem: This will re-active the new RAM characters set which means, you will see the custom characters even when they aren't animated. ................................................................................................... NOTE: this could have been also done by changing {relocating} a few assembler lines, however, I find this solution somehow cute, BASIC style workaround! Thumbs up!}Hehe... ................................................................................................... 100 graphic 1,0:graphic 0 110 color 0,2,1:color 4,5,3:color 1,8,5 120 print chr$(147):rem new char set! 125 poke 65299,(peek(65299)and3)or56 126 poke 65298,peek(65298)and251 130 rem your program... I am also working on a LOADER which will makes it possible to overcome the BLOAD problem {the load of binary files in program mode, meaning 100 load "anim",8,1 [that is not working in BASIC 3.5!]} LOADER will make things much easier for people willing to WORK with a MERLIN 7501 ASSEMBLER and BASIC 3.5 as a secret magic combo! --------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------- COLORS ON COMMODORE PLUS 4 --------------------------------------------------------------------------------------------------- BASIC - # COLOR command : COLOR color source {0-5}, color {1-16}, luminance {0-7} 0 screen background color 1 foreground color 2 multicolor mode extra color 1 3 multicolor mode extra color 2 4 screen border color --------------------------------------------------------------------- |1 = black | 5 = purple | 9 = orange | 13 = blue-green | |2 = white | 6 = green | 10 = brown | 14 = light blue | |3 = red | 7 = medium blue | 11 = yellow-green | 15 = dark blue | |4 = cyan | 8 = yellow | 12 = pink | 16 = light green | --------------------------------------------------------------------- ASSEMBLY - # ------------------------------------------------------------------------- |$00= black | $04= purple | $08= orange | $0c = blue-green | |$01= white | $05= green | $09 = brown | $0d = light blue | |$02= red | $06= medium blue | $0a = yellow-green | $0e = dark blue | |$03= cyan | $07= yellow | $0b = pink | $0f = light green | ------------------------------------------------------------------------- ASSEMBLY NOTES: Colors are # 0 to 15 and luminance values are from 0 to 112 {max value} Example; Poke 65301,1+(x*16), x=0 to 7, {7 * 16 = 112} --------------------------------------------------------------------------------------------------- DEMO: Note: I am using POKE command, with COLOR command, LUMINANCE values are 0-7. 10 print chr$(147) 15 for u=1 to 5 20 c=0:b=0:poke 65301,0 25 for a=0to112step16:fore=1 to 30:next 30 poke65301,1+(a) 35 ifu=5 then c=c+1: printc;"a=";a 37 next:c=9 40 fora=112to0 step-16:fore=1to 30:next 45 poke 65301,1+(a) 46 ifu=5 then c=c-1:printc;"b=";a 47 next 48 poke 65301,0 50 next u 60 poke 65301,4+(7*16) ready. 1 a= 0 2 a= 16 3 a= 32 4 a= 48 5 a= 64 6 a= 80 7 a= 96 8 a= 112 8 b= 112 7 b= 96 6 b= 80 5 b= 64 4 b= 48 3 b= 32 2 b= 16 1 b= 0 Border/Background Color --------------------------------------------------------------------------------------------------- 155 ;-------------------------------- 156 ;lda #3 ;not active 157 ;sta $ff19 ;border color 158 ;lda #3 ;not active 159 ;sta $ff15 ;background color 160 ;-------------------------------- ---------------------------------------------------------------------------------------------------