PLUS4-INVERSE-IT-AGAIN-IN-COLOR -------------------------------------------------------------------------------------------------- TOOL: MERLIN 7501 ASSEMBLER {Commodore PLUS4} Language: Assembler Extra: none Author: Misel Zivanovic Note: (C) 1st of August 2026 - www.lived.ch, mzretro.ch --------------------------------------------------------------------------------------------------- Last time it was easy going... Just converting an existing code to be Commodore Plus4 compatible. Was done and it's working! Now, it would be interesting to see what else could be done to extend this a bit without having to write 10 pages of assembly code! Base code is already existing... So let's do something with it! --------------------------------------------------------------------------------------------------- SOME SMALL ADDITIONAL EXPLANATIONS: {at the end of the day we indeed are here to also learn a thing or two!} Why delay was added? We are using a {low byte} timer {jiffy clock.} {$a5} values to generate color values between 0 and 15 {and #$0f} That is using only 4 bits {0-3} which is resulting in 15 when all of them are active. The initial result is responsible for what it's going to be activated withing those 4 bits! Continue reading to understand what i mean! Now how do we get it random in first place? Timer values are constantly changing, however, assembler is so fast that the changes are not happening fast enough. Which means that we would not get enough random colors on the screen! EXAMPLE: A timer value of 100 is activating a bit 2 {value 4} %0110 0100 {because of "and #$15", only bits 0,1,2,3 are considered}.You can test that like this: poke 3072,100:print peek(3072)and15 - It will result in 4! Now the next value we could catch e.g. 101, %0110 1001 = 9 {we count only 1001 = 8 + 1 =9 The problem is, our code already finished 80% of the task and we would basically have just 2 different colors on the screen. No sign of randomness there! So we need to let time works for as! We did that with delays which are delaying long enough to achieve a good effect of randomness. You can test that by changing the "delay time" values {see comments in the code} Or check the picture 2 and 3 to see the difference {they were made with short and long delays} --------------------------------------------------------------------------------------------------- {MERLIN 7501 ASSEMBLER source code}: inverse with random colors! 100 com $3000 110 list 120 ldx #$00 130 .loop 140 lda $0c00,x 150 cmp #$20 160 beq .j1st 170 lda #$20 180 sta $0c00,x 190 .ret1 200 lda $0cf0,x 205 cmp #$20 210 beq .j2nd 215 lda #$20 220 sta $0cf0,x 225 .next 230 inx 235 cpx #$f0 240 bne .loop 245 rts 300 ;------------------------ 305 .j1st 310 lda #$a0 ;rvs space 320 sta $0c00,x 330 ;------------------------ 340 ldy #$00 ;delay loops 350 .wait1 360 iny 370 cpy #$e0 ;delay time 380 bne .wait1 390 ldy #$00 400 .wait2 410 iny 420 cpy #$e0 430 bne .wait2 435 ;------------------------ 440 lda $a5 ;get low byte 450 and #$0f ;timer to handle 460 adc #76 ;random colors 470 sta $0800,x 480 jmp .ret1 600 ;------------------------ 610 .j2nd 620 lda #$a0 ;rvs space 630 sta $0cf0,x 640 ;------------------------ 650 ldy #$00 ;delay loops 660 .wait3 670 iny 680 cpy #$e0 ;delay time 690 bne .wait3 700 ldy #$00 710 .wait4 720 iny 730 cpy #$e0 740 bne .wait4 750 ;------------------------ 760 lda $a5 ;get low byte 770 and #$0f ;timer to handle 780 adc #32 ;random colors 790 sta $08f0,x 800 jmp .next 810 end --------------------------------------------------------------------------------------------------- THIS IS THE CODE FROM WHERE WE STARTED! It's the same as in previous example {lesson}! I left it here so you can better see what was added to make it be colorful with some delay touch to produce more random colors! 100 com $3000 - start address, dec 12288 110 list - list the compiled/assembled code 120 ldx #$00 - reg x to zero 130 .loop - jump lable 140 lda $0c00,x - read the screen from $0c00, 3072 150 cmp #$20 - check if it is #$20 {dec 32, space} 160 beq .j1st - if yes, then jump to .j1st mem address 170 lda #$20 - if it wasn't 10 then make it #$20! 180 sta $0c00,x - and write the value to screen coordinates 190 .ret1 - jmp lable 200 lda $0cf0,x - read the screen location from $0cf0 210 cmp #$20 - is it #$20 from there? 220 beq .j2nd - yes, then jump to j2nd and do the job there 225 lda #$20 - value #$20 to accumulator 230 sta $0cf0,x - write that value to x location of the screen 240 .next - jump lable 250 inx - increment x register 260 cpx #$f0 - is x already #$f0 {dec 240}? 270 bne .loop - not equal to #$f0, then cycle the loop until it is 280 rts - and when it is, return to BASIC 290 .j1st 300 lda #$51 - small ball 310 sta $0c00,x - this will add a small ball where empty space was {within range} 320 jmp .ret1 330 .j2nd 340 lda #$51 - small ball 350 sta $0cf0,x - this will add a small ball where empty space was {within range} 360 jmp .next 370 end --------------------------------------------------------------------------------------------------- Very small and very practical code! Hope It'll come handy in your 8-bit retro projects projects! ---------------------------------------------------------------------------------------------------