bmx: allow palette to be loaded into memory buffer instead of vram

This commit is contained in:
Irmen de Jong 2023-11-25 13:54:44 +01:00
parent c45fbe6310
commit 45debff89f
4 changed files with 117 additions and 61 deletions

View File

@ -1,7 +1,6 @@
; Routines to load and save "BMX" files (commander X16 bitmap format) Version 1.
; Only uncompressed images are supported for now.
; BMX Specification: https://cx16forum.com/forum/viewtopic.php?t=6945
; TODO: make read_palette() and write_palette() use an optional palette_buffer_ptr to store palette into system ram instead of directly into vram.
%import diskio
@ -19,9 +18,10 @@ bmx {
ubyte palette_start
ubyte compression
uword error_message ; pointer to error message, or 0 if all ok
uword max_width = 0 ; should you want load() to check for this
uword max_height = 0 ; should you want load() to check for this
uword error_message ; pointer to error message, or 0 if all ok
uword max_width = 0 ; should you want load() to check for this
uword max_height = 0 ; should you want load() to check for this
uword palette_buffer_ptr = 0 ; should you want to load the palette into main memory instead of directly into vram
sub load(ubyte drivenumber, str filename, ubyte vbank, uword vaddr, uword screen_width) -> bool {
; Loads a BMX bitmap image and palette into vram. (and Header info into the bmx.* variables)
@ -189,11 +189,21 @@ save_end:
sub read_palette() -> bool {
; load palette data from the currently active input file
; if palette_buffer_ptr is not 0, the palette data is read into that memory buffer,
; otherwise it is read directly into the palette in vram.
cx16.vaddr(1, $fa00+palette_start*2, 0, 1)
cx16.r1 = palette_buffer_ptr
cx16.r0L = palette_entries
do {
cx16.VERA_DATA0 = cbm.CHRIN()
cx16.VERA_DATA0 = cbm.CHRIN()
cx16.r2L = cbm.CHRIN()
cx16.r2H = cbm.CHRIN()
if cx16.r1 {
pokew(cx16.r1, cx16.r2) ; into memory
cx16.r1+=2
} else {
cx16.VERA_DATA0 = cx16.r2L ; into vram
cx16.VERA_DATA0 = cx16.r2H
}
cx16.r0L--
} until cx16.r0L==0
return not cbm.READST()

View File

@ -2,6 +2,8 @@
TODO
====
- optimize 6502 codegen: "for 0 to end" into repeat loops. (only for ubyte and uword, 6502 cpu)
- [on branch: shortcircuit] investigate McCarthy evaluation again? this may also reduce code size perhaps for things like if a>4 or a<2 ....
...

View File

@ -1,8 +1,12 @@
; viewer program for BMX image files.
; see https://cx16forum.com/forum/viewtopic.php?t=6945
; Viewer program for BMX image files.
; This program shows *one* way to do it, by checking the header upfront,
; and loading the palette into system ram first. The simplest way to load
; a BMX file is to just read everything into vram directly using a single bmx.load() call.
;
; BMX file format: see https://cx16forum.com/forum/viewtopic.php?t=6945
%import textio
%import palette
%import bmx
%option no_sysinit
%zeropage basicsafe
@ -15,20 +19,29 @@ main {
txt.print("\nenter bmx image filename: ")
if txt.input_chars(&filename) {
if bmx.load_header(8, filename) {
txt.print("\nwidth: ")
txt.print("\nsize: ")
txt.print_uw(bmx.width)
txt.print("\nheight: ")
txt.chrout('*')
txt.print_uw(bmx.height)
txt.print("\nbpp: ")
txt.print(" bpp: ")
txt.print_uw(bmx.bitsperpixel)
txt.nl()
sys.wait(100)
; tell the loader to put the palette into system memory instead
; also make palette black at first, to hide loading (even though it is very fast)
; (you could do a soft fade-in effect with this for instance)
bmx.palette_buffer_ptr = memory("palette", 512, 0)
sys.memset(bmx.palette_buffer_ptr, 512, 0)
palette.set_rgb(bmx.palette_buffer_ptr, 256)
; switch to correct screen mode and color depth
void cx16.screen_mode($80, false)
cx16.VERA_L0_CONFIG = cx16.VERA_L0_CONFIG & %11111100 | bmx.vera_colordepth
; actually load
; now load the image
if bmx.load(8, filename, 0, 0, 320) {
activate_palette()
void txt.waitkey()
}
}
@ -44,4 +57,17 @@ main {
}
}
}
sub activate_palette() {
; copies the pallette data from the memory buffer into vram
cx16.r1 = bmx.palette_buffer_ptr
cx16.r2L = bmx.palette_start
cx16.r3L = bmx.palette_entries
do {
palette.set_color(cx16.r2L, peekw(cx16.r1))
cx16.r1+=2
cx16.r2L++
cx16.r3L--
} until cx16.r3L==0
}
}

View File

@ -2,61 +2,79 @@
%zeropage basicsafe
main {
ubyte counter
uword wcounter
ubyte end=10
uword wend=10
sub start() {
cx16.r0=0
forloops()
txt.print_uw(cx16.r0)
txt.nl()
txt.print("for:\n")
for cx16.r0L in 10 to 20 {
txt.print_ub(cx16.r0L)
txt.print(" before...")
if cx16.r0L > 15
break
if cx16.r0L ==14
continue
txt.print("after\n")
cx16.r0=0
untilloops()
txt.print_uw(cx16.r0)
txt.nl()
}
sub forloops() {
end=10
for counter in 0 to end {
cx16.r0++
}
txt.nl()
txt.print("repeat:\n")
cx16.r0L=10
repeat 10 {
cx16.r0L++
txt.print_ub(cx16.r0L)
txt.print(" before...")
if cx16.r0L > 15
break
if cx16.r0L ==14
continue
txt.print("after\n")
end=0
for counter in 0 to end {
cx16.r0++
}
txt.nl()
txt.print("while:\n")
cx16.r0L=10
while cx16.r0L<20 {
cx16.r0L++
txt.print_ub(cx16.r0L)
txt.print(" before...")
if cx16.r0L > 15
break
if cx16.r0L ==14
continue
txt.print("after\n")
end=255
for counter in 0 to end {
cx16.r0++
}
txt.nl()
txt.print("until:\n")
cx16.r0L=10
do {
cx16.r0L++
txt.print_ub(cx16.r0L)
txt.print(" before...")
if cx16.r0L > 15
wend=1000
for wcounter in 0 to wend {
cx16.r0++
}
}
sub untilloops() {
end=10
counter = 0
repeat {
cx16.r0++
if counter==end
break
if cx16.r0L ==14
continue
txt.print("after\n")
} until cx16.r0L>20
txt.nl()
counter++
}
end=0
counter = 0
repeat {
cx16.r0++
if counter==end
break
counter++
}
counter = 0
end=255
repeat {
cx16.r0++
if counter==end
break
counter++
}
wcounter = 0
wend=1000
repeat {
cx16.r0++
if wcounter==wend
break
wcounter++
}
}
}