changed 'c64colors' module to 'palette' and added more general Cx16 palette manipulation routines in there.

This commit is contained in:
Irmen de Jong 2020-12-26 13:38:14 +01:00
parent 170a0183f8
commit 4c03950c28
13 changed files with 231 additions and 152 deletions

View File

@ -1,87 +0,0 @@
%target cx16
c64colors {
uword[] colorpalette_dark = [ ; this is a darker palette with more contrast
$000, ; 0 = black
$FFF, ; 1 = white
$632, ; 2 = red
$7AB, ; 3 = cyan
$638, ; 4 = purple
$584, ; 5 = green
$327, ; 6 = blue
$BC6, ; 7 = yellow
$642, ; 8 = orange
$430, ; 9 = brown
$965, ; 10 = light red
$444, ; 11 = dark grey
$666, ; 12 = medium grey
$9D8, ; 13 = light green
$65B, ; 14 = light blue
$999 ; 15 = light grey
]
uword[] colorpalette_pepto = [ ; # this is Pepto's Commodore-64 palette http://www.pepto.de/projects/colorvic/
$000, ; 0 = black
$FFF, ; 1 = white
$833, ; 2 = red
$7cc, ; 3 = cyan
$839, ; 4 = purple
$5a4, ; 5 = green
$229, ; 6 = blue
$ef7, ; 7 = yellow
$852, ; 8 = orange
$530, ; 9 = brown
$c67, ; 10 = light red
$444, ; 11 = dark grey
$777, ; 12 = medium grey
$af9, ; 13 = light green
$76e, ; 14 = light blue
$bbb ; 15 = light grey
]
uword[] colorpalette_light = [ ; this is a lighter palette
$000, ; 0 = black
$FFF, ; 1 = white
$944, ; 2 = red
$7CC, ; 3 = cyan
$95A, ; 4 = purple
$6A5, ; 5 = green
$549, ; 6 = blue
$CD8, ; 7 = yellow
$963, ; 8 = orange
$650, ; 9 = brown
$C77, ; 10 = light red
$666, ; 11 = dark grey
$888, ; 12 = medium grey
$AE9, ; 13 = light green
$87C, ; 14 = light blue
$AAA ; 15 = light grey
]
ubyte color
sub set_palette_pepto() {
for color in 0 to 15 {
uword cc = colorpalette_pepto[color]
cx16.vpoke(1, $fa00 + color*2, lsb(cc)) ; G, B
cx16.vpoke(1, $fa01 + color*2, msb(cc)) ; R
}
}
sub set_palette_light() {
for color in 0 to 15 {
uword cc = colorpalette_light[color]
cx16.vpoke(1, $fa00 + color*2, lsb(cc)) ; G, B
cx16.vpoke(1, $fa01 + color*2, msb(cc)) ; R
}
}
sub set_palette_dark() {
for color in 0 to 15 {
uword cc = colorpalette_dark[color]
cx16.vpoke(1, $fa00 + color*2, lsb(cc)) ; G, B
cx16.vpoke(1, $fa01 + color*2, msb(cc)) ; R
}
}
}

View File

@ -4,7 +4,7 @@
; Custom routines to use the full-screen 640x480 and 320x240 screen modes.
; This only works on the Cx16. No text layer is currently shown, text can be drawn as part of the bitmap itself.
; Note: for compatible graphics code that words on C64 too, use the "graphics" module instead.
; Note: there is no color palette manipulation here, you have to do that yourself or use the "palette" module.
; TODO this is in development. Add line drawing, circles and discs (like the graphics module has)

View File

@ -6,6 +6,8 @@
; wraps the graphics functions that are in ROM.
; only black/white monchrome 320x200 for now. (i.e. truncated at the bottom)
; For full-screen 640x480 or 320x240 graphics, use the "gfx2" module instead. (but that is Cx16-specific)
; Note: there is no color palette manipulation here, you have to do that yourself or use the "palette" module.
graphics {
const uword WIDTH = 320

View File

@ -0,0 +1,171 @@
%target cx16
; Manipulate the Commander X16's display color palette.
; Should you want to restore the default palette, you have to reinitialize the Vera yourself.
palette {
uword vera_palette_ptr
ubyte c
sub set_color(ubyte index, uword color) {
cx16.vpoke(1, $fa00+index*2, lsb(color))
cx16.vpoke(1, $fa01+index*2, msb(color))
}
sub set_rgb4(uword palletteptr, uword num_colors) {
; 2 bytes per color entry, the Vera uses this, but the R/GB bytes order is swapped
vera_palette_ptr = $fa00
repeat num_colors {
cx16.vpoke(1, vera_palette_ptr+1, @(palletteptr))
palletteptr++
cx16.vpoke(1, vera_palette_ptr, @(palletteptr))
palletteptr++
vera_palette_ptr+=2
}
}
sub set_rgb8(uword palletteptr, uword num_colors) {
; 3 bytes per color entry, adjust color depth from 8 to 4 bits per channel.
vera_palette_ptr = $fa00
ubyte red
ubyte greenblue
repeat num_colors {
red = @(palletteptr) >> 4
palletteptr++
greenblue = @(palletteptr) & %11110000
palletteptr++
greenblue |= @(palletteptr) >> 4 ; add Blue
palletteptr++
cx16.vpoke(1, vera_palette_ptr, greenblue)
vera_palette_ptr++
cx16.vpoke(1, vera_palette_ptr, red)
vera_palette_ptr++
}
}
sub set_monochrome() {
vera_palette_ptr = $fa00
cx16.vpoke(1, vera_palette_ptr, 0)
vera_palette_ptr++
cx16.vpoke(1, vera_palette_ptr, 0)
vera_palette_ptr++
repeat 255 {
cx16.vpoke(1, vera_palette_ptr, 255)
vera_palette_ptr++
cx16.vpoke(1, vera_palette_ptr, 255)
vera_palette_ptr++
}
}
sub set_grayscale() {
vera_palette_ptr = $fa00
repeat 16 {
c=0
repeat 16 {
cx16.vpoke(1, vera_palette_ptr, c)
vera_palette_ptr++
cx16.vpoke(1, vera_palette_ptr, c)
vera_palette_ptr++
c += $11
}
}
}
uword[] C64_colorpalette_dark = [ ; this is a darker palette with more contrast
$000, ; 0 = black
$FFF, ; 1 = white
$632, ; 2 = red
$7AB, ; 3 = cyan
$638, ; 4 = purple
$584, ; 5 = green
$327, ; 6 = blue
$BC6, ; 7 = yellow
$642, ; 8 = orange
$430, ; 9 = brown
$965, ; 10 = light red
$444, ; 11 = dark grey
$666, ; 12 = medium grey
$9D8, ; 13 = light green
$65B, ; 14 = light blue
$999 ; 15 = light grey
]
uword[] C64_colorpalette_pepto = [ ; # this is Pepto's Commodore-64 palette http://www.pepto.de/projects/colorvic/
$000, ; 0 = black
$FFF, ; 1 = white
$833, ; 2 = red
$7cc, ; 3 = cyan
$839, ; 4 = purple
$5a4, ; 5 = green
$229, ; 6 = blue
$ef7, ; 7 = yellow
$852, ; 8 = orange
$530, ; 9 = brown
$c67, ; 10 = light red
$444, ; 11 = dark grey
$777, ; 12 = medium grey
$af9, ; 13 = light green
$76e, ; 14 = light blue
$bbb ; 15 = light grey
]
uword[] C64_colorpalette_light = [ ; this is a lighter palette
$000, ; 0 = black
$FFF, ; 1 = white
$944, ; 2 = red
$7CC, ; 3 = cyan
$95A, ; 4 = purple
$6A5, ; 5 = green
$549, ; 6 = blue
$CD8, ; 7 = yellow
$963, ; 8 = orange
$650, ; 9 = brown
$C77, ; 10 = light red
$666, ; 11 = dark grey
$888, ; 12 = medium grey
$AE9, ; 13 = light green
$87C, ; 14 = light blue
$AAA ; 15 = light grey
]
sub set_c64pepto() {
vera_palette_ptr = $fa00
repeat 16 {
for c in 0 to 15 {
uword cc = C64_colorpalette_pepto[c]
cx16.vpoke(1, vera_palette_ptr, lsb(cc)) ; G, B
vera_palette_ptr++
cx16.vpoke(1, vera_palette_ptr, msb(cc)) ; R
vera_palette_ptr++
}
}
}
sub set_c64light() {
vera_palette_ptr = $fa00
repeat 16 {
for c in 0 to 15 {
uword cc = C64_colorpalette_light[c]
cx16.vpoke(1, vera_palette_ptr, lsb(cc)) ; G, B
vera_palette_ptr++
cx16.vpoke(1, vera_palette_ptr, msb(cc)) ; R
vera_palette_ptr++
}
}
}
sub set_c64dark() {
vera_palette_ptr = $fa00
repeat 16 {
for c in 0 to 15 {
uword cc = C64_colorpalette_dark[c]
cx16.vpoke(1, vera_palette_ptr, lsb(cc)) ; G, B
vera_palette_ptr++
cx16.vpoke(1, vera_palette_ptr, msb(cc)) ; R
vera_palette_ptr++
}
}
}
}

View File

@ -31,6 +31,13 @@ internal class AstIdentifiersChecker(private val program: Program, private val e
else
blocks[block.name] = block
if(!block.isInLibrary) {
val libraries = program.modules.filter { it.isLibraryModule }
val libraryBlockNames = libraries.flatMap { it.statements.filterIsInstance<Block>().map { b -> b.name } }
if(block.name in libraryBlockNames)
errors.err("block is already defined in an included library module", block.position)
}
super.visit(block)
}

View File

@ -73,13 +73,37 @@ point variables. This includes ``print_f``, the routine used to print floating
graphics
--------
High-res monochrome bitmap graphics routines:
Monochrome bitmap graphics routines, fixed 320*200 resolution:
- clearing the screen
- drawing lines
- drawing circles and discs (filled circles)
- plotting individual pixels
This library is available both on the C64 and the Cx16.
It uses the ROM based graphics routines on the latter, and it is a very small library because of that.
That also means though that it is constrained to 320*200 resolution on the Cx16 as well.
Use the ``gfx2`` library if you want full-screen graphics or non-monochrome drawing.
gfx2 (cx16 only)
-----------------
Full-screen multicolor bitmap graphics routines, available on the Cx16 machine only.
- multiple full-screen resolutions: 640 * 480 monochrome, and 320 * 240 monochrome and 256 colors
- clearing screen, switching screen mode
- drawing pixels
- drawing text inside the bitmap
- **TODO:** lines, circles, discs.
palette (cx16 only)
--------------------
Available for the Cx16 target. Various routines to set the display color palette.
There are also a few better looking Commodore-64 color palettes available here,
because the Commander X16's default colors for this (the first 16 colors) are too saturated
and are quite different than how they looked on a VIC-II chip in a C-64.
math
----
@ -93,15 +117,6 @@ A 'fun' module that contains the Commander X16 logo and that allows you
to print it anywhere on the screen.
c64colors
---------
Available for the CommanderX16 target, a module that contains a few better
color palettes for how the colors of the VIC-II looked on the Commodore-64.
There are subroutines to activate one of the several palettes of your liking.
The Commander X16's default colors for this (the first 16 colors) are too saturated
and are quite different than how a C-64 looked.
prog8_lib
---------
Low level language support. You should not normally have to bother with this directly.

View File

@ -632,6 +632,13 @@ Defining a subroutine
Subroutines are parts of the code that can be repeatedly invoked using a subroutine call from elsewhere.
Their definition, using the ``sub`` statement, includes the specification of the required parameters and return value.
Subroutines can be defined in a Block, but also nested inside another subroutine. Everything is scoped accordingly.
With ``asmsub`` you can define a low-level subroutine that is implemented in inline assembly and takes any parameters
in registers directly.
Trivial subroutines can be tagged as inline to tell the compiler to copy their code
in-place to the locations where the subroutine is called, rather than inserting an actual call and return to the
subroutine. This may increase code size significantly and can only be used in limited scenarios, so YMMV.
Calling a subroutine
^^^^^^^^^^^^^^^^^^^^

View File

@ -531,7 +531,7 @@ Subroutine definitions
The syntax is::
sub <identifier> ( [parameters] ) [ -> returntype ] {
[inline] sub <identifier> ( [parameters] ) [ -> returntype ] {
... statements ...
}
@ -544,6 +544,9 @@ The open curly brace must immediately follow the subroutine result specification
and can have nothing following it. The close curly brace must be on its own line as well.
The parameters is a (possibly empty) comma separated list of "<datatype> <parametername>" pairs specifying the input parameters.
The return type has to be specified if the subroutine returns a value.
The ``inline`` keyword makes their code copied in-place to the locations where the subroutine is called,
rather than having an actual call and return to the subroutine. This is meant for trivial subroutines only
as it can increase code size significantly.
Assembly / ROM subroutines
@ -580,6 +583,13 @@ what cpu registers should take the routine's arguments. You can use the regular
(A, X, Y), the special 16-bit register pairs to take word values (AX, AY and XY) and even a processor status
flag such as Carry (Pc).
.. note::
Asmsubs can also be tagged as ``inline asmsub`` to make trivial pieces of assembly inserted
directly instead of a call to them. Note that it is literal copy-paste of code that is done,
so make sure the assembly is actually written to behave like such - which probably means you
don't want a ``rts`` or ``jmp`` in it!
.. note::
The 'virtual' 16-bit registers from the Commander X16 can also be used as ``R0`` .. ``R15`` .
This means you don't have to set them up manually before calling a subroutine that takes

View File

@ -3,7 +3,6 @@ TODO
====
- why are unused vars not removed in gfx2 module
- document the 'inline' keyword on asmsub and sub declarations + the restriction
- hoist all variable declarations up to the subroutine scope *before* even the constant folding takes place (to avoid undefined symbol errors when referring to a variable from another nested scope in the subroutine)
- make it possible to use cpu opcodes such as 'nop' as variable names by prefixing all asm vars with something such as '_'
- option to load the built-in library files from a directory instead of the embedded ones (for easier library development/debugging)
@ -22,7 +21,6 @@ Add more compiler optimizations to the existing ones.
- binexpr splitting (beware self-referencing expressions and asm code ballooning though)
- more optimizations on the language AST level
- more optimizations on the final assembly source level
- note: subroutine inlining is abandoned because of problems referencing non-local stuff. Can't move everything around.
Eval stack redesign? (lot of work)

View File

@ -47,7 +47,7 @@ bmp_module {
repeat bm_data_offset - total_read
void c64.CHRIN()
gfx2.clear_screen()
palette.set_bgra(&palette0, num_colors)
custompalette.set_bgra(&palette0, num_colors)
decode_bitmap()
load_ok = true
}

View File

@ -131,38 +131,7 @@ main {
}
palette {
sub set_rgb4(uword palletteptr, uword num_colors) {
; 2 bytes per color entry, the Vera uses this, but the R/GB bytes order is swapped
uword vera_palette_ptr = $fa00
repeat num_colors {
cx16.vpoke(1, vera_palette_ptr+1, @(palletteptr))
palletteptr++
cx16.vpoke(1, vera_palette_ptr, @(palletteptr))
palletteptr++
vera_palette_ptr+=2
}
}
sub set_rgb8(uword palletteptr, uword num_colors) {
; 3 bytes per color entry, adjust color depth from 8 to 4 bits per channel.
uword vera_palette_ptr = $fa00
ubyte red
ubyte greenblue
repeat num_colors {
red = @(palletteptr) >> 4
palletteptr++
greenblue = @(palletteptr) & %11110000
palletteptr++
greenblue |= @(palletteptr) >> 4 ; add Blue
palletteptr++
cx16.vpoke(1, vera_palette_ptr, greenblue)
vera_palette_ptr++
cx16.vpoke(1, vera_palette_ptr, red)
vera_palette_ptr++
}
}
custompalette {
sub set_bgra(uword palletteptr, uword num_colors) {
uword vera_palette_ptr = $fa00
@ -182,21 +151,8 @@ palette {
}
}
sub set_monochrome() {
uword vera_palette_ptr = $fa00
cx16.vpoke(1, vera_palette_ptr, 0)
vera_palette_ptr++
cx16.vpoke(1, vera_palette_ptr, 0)
vera_palette_ptr++
repeat 255 {
cx16.vpoke(1, vera_palette_ptr, 255)
vera_palette_ptr++
cx16.vpoke(1, vera_palette_ptr, 255)
vera_palette_ptr++
}
}
sub set_grayscale() {
sub set_grayscale256() {
; grays $000- $fff stretched out over all the 256 colors
ubyte c = 0
uword vera_palette_ptr = $fa00
repeat 16 {

View File

@ -1,7 +1,7 @@
%target cx16
%import gfx2
%import diskio
%import c64colors
%import palette
koala_module {
const uword load_location = $6000
@ -13,7 +13,7 @@ koala_module {
if size==2 {
diskio.f_read_exact(load_location, 10001)
; set a better C64 color palette, the Cx16's default is too saturated
c64colors.set_palette_pepto()
palette.set_c64pepto()
convert_koalapic()
load_ok = true
}

View File

@ -24,7 +24,7 @@ pcx_module {
if (width & 7) == 0 {
gfx2.clear_screen()
if palette_format==2
palette.set_grayscale()
custompalette.set_grayscale256()
else if num_colors == 16
palette.set_rgb8(&header + $10, 16)
else if num_colors == 2