+SvOlli Posted May 1, 2013 Share Posted May 1, 2013 (edited) Hey there! I'm trying to paint a rainbow effect on a PAL console. Since the colors are ordered very "strange" on a PAL console, I tried to write some code to "reorder" the color table for me. It didn't need to be a mapping NTSC -> PAL as close as possible, it should just a one nice rainbow, not two interlacing. A bit about the code: The X register is the base for color calculation. Painting a "bad" rainbow would look something like this: tax asl sta COLUPF This way each line (not just ever other) gets a new color. Here's what I came up with so far: txa ; optional color conversion ntsc -> pal ; adds $1b = 27 bytes ; 2 %0010 <- 2 %0010 ; 4 %0100 <- 3 %0011 ; 6 %0110 <- 4 %0100 ; 8 %1000 <- 5 %0101 ; A %1010 <- 6 %0110 ; C %1100 <- 7 %0111 ; ; D %1101 <- 8 %1000 ; B %1011 <- 9 %1001 ; 9 %1001 <- A %1010 ; 7 %0111 <- B %1011 ; 5 %0101 <- C %1100 ; 3 %0011 <- D %1101 and #$07 sta $82 txa cmp #$c0 ; <- this should be and #$7f : cmp #$40, but X is always > $80 while drawing, saving 2 bytes bcs @upper and #$38 asl sbc #$0f ; <- shound be: sec : sbc #$10, but C is always 0 bpl @skip ; <- always true because of and #$38 @upper: and #$B8 asl sta $83 lda #$68 sbc $83 @skip: ora $82 ; optional color conversion end asl sta COLUPF Anyone got an idea on how to do it with less bytes of rom? Greetings, SvOlli [Edit: added some more comments] Edited May 1, 2013 by SvOlli Quote Link to comment Share on other sites More sharing options...
Omegamatrix Posted May 1, 2013 Share Posted May 1, 2013 If you are just converting colors from NTSC to PAL, then maybe you can do something like this: ;NTSC $0x = PAL $0x no change ;NTSC $1x = PAL $2x <-- ($10to$18 PAL $30to$38) ($1Ato$1F PAL $2Ato$2F) ;NTSC $2x = PAL $2x no change ;NTSC $3x = PAL $4x +$10 ;NTSC $4x = PAL $6x +$20 ;NTSC $5x = PAL $8x +$30 ;NTSC $6x = PAL $Ax +$40 ;NTSC $7x = PAL $Cx +$50 ;NTSC $8x = PAL $Dx +$50 ;NTSC $9x = PAL $Bx +$20 ;NTSC $Ax = PAL $9x -$10 ;NTSC $Bx = PAL $7x -$40 ;NTSC $Cx = PAL $5x -$70 ;NTSC $Dx = PAL $3x -$A0 ;NTSC $Ex = PAL $3x <-- -$B0 ;NTSC $Fx = PAL $2x <-- -$D0 txa ; holds current NTSC color lsr lsr lsr lsr tay txa eor ColTabPal,Y ; color is now PAL asl sta COLUPF ColTabPal: .byte $00 ; $0x .byte $30 ; $2x .byte $00 ; $2x .byte $70 ; $4x .byte $20 ; $6x .byte $D0 ; $8x .byte $C0 ; $Ax .byte $B0 ; $Cx .byte $50 ; $Dx .byte $20 ; $Bx .byte $30 ; $9x .byte $C0 ; $7x .byte $90 ; $5x .byte $E0 ; $3x .byte $D0 ; $3x .byte $D0 ; $2x I got the color equates from SeaGtGruff, and added a few notes from someone else who said yellow ($10 to $18) was closer in $3x then $2x. I just whipped up this EOR table right now, and it doesn't account for that odd ball case with the yellow. Everything else should work reasonably well though. Maybe you can overlap the data table with something to save a few more bytes. Quote Link to comment Share on other sites More sharing options...
SeaGtGruff Posted May 1, 2013 Share Posted May 1, 2013 I'm trying to paint a rainbow effect on a PAL console. Since the colors are ordered very "strange" on a PAL console, I tried to write some code to "reorder" the color table for me. It didn't need to be a mapping NTSC -> PAL as close as possible, it should just a one nice rainbow, not two interlacing. If you just want to do a rainbow effect in PAL without worrying about mapping the NTSC palette to the PAL palette, just skip every other hue in increasing order, then skip every other hue in decreasing order: Increasing: $2x $4x $6x $8x $Ax $Cx Decreasing: $Dx $Bx $9x $7x $5x $3x This assumes you don't need/want to include the gray shades ($0x and $1x, as well as $Ex and $Fx). So a PAL rainbow effect could be programmed as follows: ; Taste the PAL Rainbow! ; Version 1 - No Shades of Gray Allowed PROCESSOR 6502 VSYNC = $00 VBLANK = $01 WSYNC = $02 COLUBK = $09 PF0 = $0D PF1 = $0E PF2 = $0F AUDV0 = $19 AUDV1 = $1A GRP0 = $1B GRP1 = $1C ENAM0 = $1D ENAM1 = $1E ENABL = $1F TIM64T = $0296 TIMINT = $0285 first_color = $80 line_color = $81 hue_increment = $82 ORG $F800 Boot_Routine CLD LDA #0 STA PF0 STA PF1 STA PF2 STA AUDV0 STA AUDV1 STA GRP0 STA GRP1 STA ENAM0 STA ENAM1 STA ENABL LDA #$0E STA first_color Vertical_Blank LDA #2 STA VBLANK LDA #32*76/64 STA TIM64T Front_Porch BIT TIMINT BPL Front_Porch STA WSYNC LDA #2 STA VSYNC STA WSYNC STA WSYNC STA WSYNC LDA #0 STA VSYNC LDA #46*76/64 STA TIM64T LDA #$10 STA hue_increment LDA first_color AND #$10 BEQ Load_Color LDA #$D0 STA hue_increment Load_Color LDA first_color JSR Next_Color STY first_color STY line_color Back_Porch BIT TIMINT BPL Back_Porch STA WSYNC LDA #0 STA VBLANK LDX #230 Active_Video LDA line_color STA COLUBK JSR Next_Color STY line_color STY WSYNC DEX BNE Active_Video JMP Vertical_Blank Next_Color CLC ADC #$02 TAY AND #$0F BEQ Next_Hue RTS Next_Hue TYA CLC ADC hue_increment TAY BIT hue_increment BMI Decreasing_Hues CPY #$E0 BEQ Start_Decreasing RTS Start_Decreasing LDY #$D0 STY hue_increment RTS Decreasing_Hues CPY #$10 BEQ Start_Increasing RTS Start_Increasing LDA #$10 STA hue_increment LDY #$20 RTS ORG $FFFC WORD Boot_Routine WORD Boot_Routine END It isn't very elegant code, and there's probably a better way to do it, but it works! Taste_the_PAL_Rainbow.asm Taste_the_PAL_Rainbow.asm.bin Quote Link to comment Share on other sites More sharing options...
+SvOlli Posted May 1, 2013 Author Share Posted May 1, 2013 First of all: thanks, you two! If you just want to do a rainbow effect in PAL without worrying about mapping the NTSC palette to the PAL palette, just skip every other hue in increasing order, then skip every other hue in decreasing order: [...] It isn't very elegant code, and there's probably a better way to do it, but it works! I don't care about elegant, it just has to work in less bytes. Anyway, I tried to implement that inside my code and it took up slightly more than my "algorithm". I took your code, and merged it with mine to get an example on how the code is intended to be used. If you are just converting colors from NTSC to PAL, then maybe you can do something like this: [...] I just whipped up this EOR table right now, and it doesn't account for that odd ball case with the yellow. Everything else should work reasonably well though. Maybe you can overlap the data table with something to save a few more bytes. That's an appoach that beat my code by 5 bytes, taking into account that the table only converts non-grey colors (on the PAL side: $00-$1f, $e0-$ff), and therefore only uses 12 bytes instead of 16. I attached the code of a non-converting version as a template, a "port" of omegamatrix's idea and my original code for comparison. They print out the size of the code used in the marked sections during assembly. omegamatrix1.asm svolli1.asm svolli2.asm Quote Link to comment Share on other sites More sharing options...
Tjoppen Posted May 1, 2013 Share Posted May 1, 2013 Haven't really looked at the code, but just use a LUT Quote Link to comment Share on other sites More sharing options...
+SvOlli Posted May 1, 2013 Author Share Posted May 1, 2013 Haven't really looked at the code, but just use a LUT A special form of LUT is what omegamatrix suggested, and it beats my solution in the test environment, but unfortunately not in the real code. As the main goal is to minimize the number of bytes in ROM, a generic LUT wouldn't cut it. Quote Link to comment Share on other sites More sharing options...
Omegamatrix Posted May 2, 2013 Share Posted May 2, 2013 I should have grabbed the color after the shift, so here is a new version. Also, it is optimized for a more rainbow PAL palette, and not every color is there. Finally I trash Y, but reload it after. txa asl pha lsr lsr lsr lsr tay ; trash Y pla eor ColPalTab-2,Y sta COLUPF ldy #0 ; reload Y with zero ColPalTab: .byte $00 .byte $70 .byte $20 .byte $D0 .byte $C0 .byte $B0 .byte $50 .byte $20 .byte $30 .byte $C0 .byte $90 .byte $E0 Quote Link to comment Share on other sites More sharing options...
Tjoppen Posted May 2, 2013 Share Posted May 2, 2013 That looks similar to some old code of mine, for scrolling rainbow bars: ColorTab byte $20 byte $40 byte $60 byte $80 byte $A0 byte $C0 byte $D0 byte $B0 byte $90 byte $70 byte $50 byte $30 byte $20 byte $40 byte $60 byte $80 shyKernel ldx #LINES-1 shyKernelLoop txa adc frame tay and #$0F sta temp+1 tya lsr lsr lsr lsr tay lda ColorTab,Y ora temp+1 sta WSYNC sta COLUBK dex bne shyKernelLoop Quote Link to comment Share on other sites More sharing options...
Omegamatrix Posted May 2, 2013 Share Posted May 2, 2013 You can also preserve Y, but it costs and extra byte as well as a temp register. TXA PHA ; save X ASL PHA LSR LSR LSR LSR TAX ; trash X instead PLA EOR ColPalTab-2,X STA COLUPF PLA ; reload X value TAX Or, you could use the stack pointer, but that would require resetting it if you doing an JSR's. Quote Link to comment Share on other sites More sharing options...
+SvOlli Posted May 2, 2013 Author Share Posted May 2, 2013 I managed to scape off 4 bytes in my version: txa ; 2 %0010 <- 2 %0010 ; 4 %0100 <- 3 %0011 ; 6 %0110 <- 4 %0100 ; 8 %1000 <- 5 %0101 ; A %1010 <- 6 %0110 ; C %1100 <- 7 %0111 and #$07 sta $82 txa asl ; a > $80 => sec bmi @upper and #$70 sbc #$10 bpl @skip @upper: ; D %1101 <- 8 %1000 ; B %1011 <- 9 %1001 ; 9 %1001 <- A %1010 ; 7 %0111 <- B %1011 ; 5 %0101 <- C %1100 ; 3 %0011 <- D %1101 and #$70 eor #$ff adc #$68 @skip: ora $82 asl sta COLUPF Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.