diff --git a/compiler/res/prog8lib/cx16/bmx.p8 b/compiler/res/prog8lib/cx16/bmx.p8 index f83ad184d..147a53a0a 100644 --- a/compiler/res/prog8lib/cx16/bmx.p8 +++ b/compiler/res/prog8lib/cx16/bmx.p8 @@ -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() diff --git a/docs/source/todo.rst b/docs/source/todo.rst index b79ffce3f..04bdb6a2c 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -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 .... ... diff --git a/examples/cx16/showbmx.p8 b/examples/cx16/showbmx.p8 index d9020d5af..21fb81a8e 100644 --- a/examples/cx16/showbmx.p8 +++ b/examples/cx16/showbmx.p8 @@ -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 + } } diff --git a/examples/test.p8 b/examples/test.p8 index 0919ebfce..4806dbb92 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -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++ + } } }