A3020 8-bit RGB332 Colour

bbc micro/electron/atom/risc os coding queries and routines
Post Reply
Snial
Posts: 8
Joined: Tue Mar 10, 2020 8:34 pm
Contact:

A3020 8-bit RGB332 Colour

Post by Snial »

I've been having a bit of fun generating a non-tint based 8-bit palette for my A3020. I found that in mode 13 or mode 28 I could create this palette:

Code: Select all

20 DATA 0,0,0,0,0,2,0,0,4,0,0,6
30 DATA 0,2,0,0,2,2,0,2,4,0,2,6
40 DATA 4,0,0,4,0,2,4,0,4,4,0,6
50 DATA 4,2,0,4,2,2,4,2,4,4,2,6
60 FOR entry%=0 TO 15:READ b%,g%,r%:VDU 19,entry%,16,r%*16,g%*16,b%*16:NEXT
Then generate an RGB332 (really BGR233) colour range which I tried on Archimedes Live! https://archi.medes.live/#preset=a3020&ff=14000 before running on my real A3020 (in mode 28):
A3020Rgb332.jpg
With this little BASIC V program:

Code: Select all

10 MODE 13:OFF
15 DIM iBlock% 8
17 DIM oBlock% 4
20 DATA 0,0,0,0,0,2,0,0,4,0,0,6
30 DATA 0,2,0,0,2,2,0,2,4,0,2,6
40 DATA 4,0,0,4,0,2,4,0,4,4,0,6
50 DATA 4,2,0,4,2,2,4,2,4,4,2,6
60 FOR entry%=0 TO 15:READ b%,g%,r%:VDU 19,entry%,16,r%*16,g%*16,b%*16:NEXT
65 !iBlock%=148:!(iBlock%+4)=-1:REM ScreenStart
70 SYS &31,iBlock%,oBlock%
80 PRINT iBlock%, oBlock%, !iBlock%, !(iBlock%+4), !oBlock%
90 screen%=!oBlock%
100 FOR y%=0 TO 15
110 FOR x%=0 TO 15
120 c%=(y%<<4)+x%: REM RrrG:GgBb => BGGR:bgrr, BGGgbRrr => BGGR:bgrr
130 rgb%=((c% AND 1)<<3)+((c% AND 2)<<6)+(c% AND 4)+((c% AND 24)<<2)+((c% AND 96)>>5)+((c% AND 128)>>3)
132 c%=(c% AND &eb)+((c% AND 16)>>2)+((c% AND 4)<<2)
140 FOR h%=0 TO 7
150 FOR w%=0 TO 7
165 ?(screen%+(y%*8+h%)*320+x%*8+w%)=c%
170 NEXT:NEXT:NEXT:NEXT
I wrote a blog post: https://oneweekwonder.blogspot.com/2024 ... 8-bit.html to go along with it, but I was just wondering: in my code I simply wrote directly to screen memory, because I understood that GCOL expected a 64-colour Palette + Tint. I'll experiment to see if I can use it, but maybe someone knows if it simply generates pixels of the form (PaletteColour<<2)+Tint, in which case I'd be able to translate RGB332 properly into that format.
steve3000
Posts: 2909
Joined: Sun Nov 25, 2012 12:43 am
Contact:

Re: A3020 8-bit RGB332 Colour

Post by steve3000 »

Great work! Really nice to see you redefining the Archie 256 colour palette so successfully - very few people ventured into this BITD, probably in part because it was poorly explained, with no examples of how to redefine the 256 colour palette in general Archie documentation of the time (often treating it as effectively a fixed palette or just said it wasn't possible to redefine individual colours without impacting others - but didn't explain why).

To work out pixel values to GCOL and TINT, I wrote this years ago:

Code: Select all

10 MODE 13
20 DIM in 8,out 4
30 !in=148:in!4=-1
40 SYS"OS_ReadVduVariables",in,out
50 scr=!out
60 FOR pix=0 TO 255
70  CLS
80  ?scr=pix
90  PRINTTAB(0,10)"Pixel byte ";pix;" = GCOL ";POINT(0,1020);" TINT ";TINT(0,1020)''"Press a key for next...";
100  key=GET
110 NEXT
Snial
Posts: 8
Joined: Tue Mar 10, 2020 8:34 pm
Contact:

Re: A3020 8-bit RGB332 Colour

Post by Snial »

Thanks for that, @steve3000.
Archie documentation of the time (often treating it as effectively a fixed palette or just said it wasn't possible to redefine individual colours without impacting others - but didn't explain why).
I've come across a few threads along those lines.
To work out pixel values to GCOL and TINT, I wrote this years ago:
Great, I've used your technique in a new version of my Colour Space demo:

Code: Select all

10 MODE 13:OFF
15 DIM iBlock% 8, oBlock% 4, gcols% 256, tints% 256
20 DATA 0,0,0,0,0,2,0,0,4,0,0,6
30 DATA 0,2,0,0,2,2,0,2,4,0,2,6
40 DATA 4,0,0,4,0,2,4,0,4,4,0,6
50 DATA 4,2,0,4,2,2,4,2,4,4,2,6
60 FOR entry%=0 TO 15:READ b%,g%,r%:VDU 19,entry%,16,r%*16,g%*16,b%*16:NEXT
65 !iBlock%=148:!(iBlock%+4)=-1:REM ScreenStart
70 SYS &31,iBlock%,oBlock%
80 PRINT iBlock%, oBlock%, !iBlock%, !(iBlock%+4), !oBlock%
90 screen%=!oBlock%
100 FOR rgb%=0 TO 255
110  ?screen%=rgb%
120  ?(gcols%+rgb%)=POINT(0,1020):?(tints%+rgb%)=TINT(0,1020)
170 NEXT
200 FOR y%=0 TO 15:FOR x%=0 TO 15
210 c%=y%*16+x%:REM c% is BGGgbRrr, need BGGRbgrr
220 rgb%=(c% AND &eb)+((c% AND 4)<<2)+((c% AND 16)>>2)
230 GCOL ?(gcols%+rgb%) TINT ?(tints%+rgb%)
240 PLOT 68,x%<<5,988-(y%<<5):PLOT 97,32,32
300 NEXT:NEXT
310 PRINT TAB(0,17);
Which generates this:
Rgb332SpaceGcolTint.jpg
It's a massive step forward because it means I can now use standard graphics commands instead of having to poke to the screen.

I printed it out to begin with, so I can see there's a pattern. TINT is the bottom 2 bits as expected. The POINT value involves some kind of bit shifting, which I haven't figured out, but I'm not sure it matters, because the quickest translation technique is just to index via rgb%. In the next version I'll make it a bit simpler to translate, by making rgb% order RrrGGgBb instead of BGGRbgrr (by changing line 110 to convert to BGGRbgrr and line 220 to convert to BbGGgRrr). In my notation here, capital letter components denote the direct palette bits (BGGR) and lower-case denotes the colour components mapped to palette entries (bgrr).

Then I can add a simple DEFPROCrgbSet(rgb%), DEFFNtoRgb(r%, g%, b%)=(r%<<5)+(g%<<2)+b% and DEFPROCrgbCol(r%, g%, b%) to make it a bit more usable.
Snial
Posts: 8
Joined: Tue Mar 10, 2020 8:34 pm
Contact:

Re: A3020 8-bit RGB332 Colour

Post by Snial »

OK, I found a bit of time to do make it a bit more friendly. I worked out the bit patterns to generate the GCOLs and TINTs without having to set a pixel and do POINT(x,y) and TINT(x,y). Then I removed the line numbers; added the procedures to setup RGB palettes in a given mode (I've tested mode 10, 13, 15, 28) and pasting this into the BASIC editing window at:

https://archi.medes.live/#preset=a3020&ff=14000

will generate the two palettes, the first using PROCrgbSet and the second using PROCrgbCol (which uses FNtoRgb). It looks like this in mode 10 (which is two of the same colour palettes which differ to previous palettes because green and red are swapped).
RgbPalWithProcs.jpg
Next I might try with a more useful demo.

Code: Select all

AUTO
PROCrgbSetup(13)
FOR y%=0 TO 15:FOR x%=0 TO 15
  c%=y%*16+x%:REM c% is BGGgbRrr, need BGGRRbgrr
  PROCrgbSet(((c% AND 7)<<2)+((c% AND 8)>>3)+((c% AND &70)<<1)+((c% AND 128)>>6))
  PLOT 68,x%<<5,988-(y%<<5):PLOT 97,32,32
NEXT:NEXT
FOR r%=0 TO 7:FOR g%=0 TO 7: FOR b%=0 TO 3
  x%=g%+((b% AND 1)<<3):y%=r%+((b% AND 2)<<2)
  PROCrgbCol(r%,g%,b%)
  PLOT 68,544+(x%<<5),988-(y%<<5):PLOT 97,32,32
NEXT:NEXT:NEXT
PRINT TAB(0,17);
END
DEFPROCrgbSetup(aMode%)
MODE aMode%:OFF
DIM iBlock% 8, oBlock% 4, gcols% 256, tints% 256
DATA 0,0,0,0,0,2,0,0,4,0,0,6
DATA 0,2,0,0,2,2,0,2,4,0,2,6
DATA 4,0,0,4,0,2,4,0,4,4,0,6
DATA 4,2,0,4,2,2,4,2,4,4,2,6
FOR entry%=0 TO 15:READ b%,g%,r%:VDU 19,entry%,16,r%*16,g%*16,b%*16:NEXT
!iBlock%=148:!(iBlock%+4)=-1:REM ScreenStart
SYS &31,iBlock%,oBlock%
PRINT iBlock%, oBlock%, !iBlock%, !(iBlock%+4), !oBlock%
screen%=!oBlock%
FOR rgb%=0 TO 255
  ?(gcols%+rgb%)=((rgb% AND 128)>>6)+((rgb% AND 24)>>1)+((rgb% AND 4)>>2)+((rgb% AND 3)<<4)
  ?(tints%+rgb%)=((rgb% AND 96)<<1)
NEXT
ENDPROC
DEFFNtoRgb(r%, g%, b%)=(r%<<5)+(g%<<2)+b%
DEFPROCrgbSet(rgb%)
rgb%=rgb% AND 255
GCOL ?(gcols%+rgb%) TINT ?(tints%+rgb%)
ENDPROC
DEFPROCrgbCol(r%, g%, b%)
LOCAL rgb%:rgb%=FNtoRgb(r%, g%, b%)
GCOL ?(gcols%+rgb%) TINT ?(tints%+rgb%)
ENDPROC
END
Post Reply

Return to “programming”