diff --git a/compiler/res/prog8lib/cx16/gfx2.p8 b/compiler/res/prog8lib/cx16/gfx2.p8 index ef78721be..ae499c03a 100644 --- a/compiler/res/prog8lib/cx16/gfx2.p8 +++ b/compiler/res/prog8lib/cx16/gfx2.p8 @@ -1112,26 +1112,61 @@ skip: ; hires 4c ; we're going to use a few cx16 registers to make sure every variable is in zeropage in the inner loop. cx16.r11L = color - cx16.r8 = y while @(sctextptr) { chardataptr = charset_addr + (@(sctextptr) as uword)*8 cx16.vaddr(charset_bank, chardataptr, 1, true) ; for reading the chardata from Vera data channel 1 + position(x, y) ; only calculated once, we update vera address in the loop instead + cx16.VERA_ADDR_H &= $0f ; no auto increment repeat 8 { - ; TODO rewrite this in assembly, don't call plot for every pixel - ; requires expanding the charbits to 2-bits per pixel (based on color) - ; also it's way more efficient to draw whole horizontal spans instead of per-character - cx16.r9L = cx16.VERA_DATA1 ; get the next 8 horizontal character bits + cx16.r10L = cx16.VERA_DATA1 ; get the next 8 horizontal character bits cx16.r7 = x repeat 8 { - cx16.r9L <<= 1 - if_cs - plot(cx16.r7, cx16.r8, cx16.r11L) + cx16.r10L <<= 1 + if_cs { + cx16.r2L = cx16.r7L & 3 ; xbits + when cx16.r11L & 3 { + 1 -> cx16.r12L = gfx2.plot.shiftedleft_4c_1[cx16.r2L] + 2 -> cx16.r12L = gfx2.plot.shiftedleft_4c_2[cx16.r2L] + 3 -> cx16.r12L = gfx2.plot.shiftedleft_4c_3[cx16.r2L] + else -> cx16.r12L = 0 + } + cx16.VERA_DATA0 = cx16.VERA_DATA0 & gfx2.plot.mask4c[cx16.r2L] | cx16.r12L + } cx16.r7++ + if (cx16.r7 & 3) == 0 { + ; increment the pixel address by one + %asm {{ + stz cx16.VERA_CTRL + clc + lda cx16.VERA_ADDR_L + adc #1 + sta cx16.VERA_ADDR_L + lda cx16.VERA_ADDR_M + adc #0 + sta cx16.VERA_ADDR_M + lda cx16.VERA_ADDR_H + adc #0 + sta cx16.VERA_ADDR_H + }} + } } - cx16.r8++ + + ; increment pixel address to the next line + %asm {{ + stz cx16.VERA_CTRL + clc + lda cx16.VERA_ADDR_L + adc #(640-8)/4 + sta cx16.VERA_ADDR_L + lda cx16.VERA_ADDR_M + adc #0 + sta cx16.VERA_ADDR_M + lda cx16.VERA_ADDR_H + adc #0 + sta cx16.VERA_ADDR_H + }} } x+=8 - cx16.r8-=8 sctextptr++ } } diff --git a/docs/source/todo.rst b/docs/source/todo.rst index a02a7d6b6..60a794167 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -47,7 +47,6 @@ Libraries: - fix the problems in atari target, and flesh out its libraries. - c128 target: make syslib more complete (missing kernal routines)? - c64: make the graphics.BITMAP_ADDRESS configurable (VIC banking) -- optimize several inner loops in gfx2 even further? - actually implement modes 3 and perhaps even 2 to gfx2 (lores 16 color and 4 color) @@ -75,15 +74,8 @@ STRUCTS again? What if we were to re-introduce Structs in prog8? Some thoughts: - can contain only numeric types (byte,word,float) - no nested structs, no reference types (strings, arrays) inside structs -- is just some syntactic sugar for a scoped set of variables -> ast transform to do exactly this before codegen. Codegen doesn't know about struct. -- no arrays of struct -- because too slow on 6502 to access those, rather use struct of arrays instead. - can we make this a compiler/codegen only issue? i.e. syntax is just as if it was an array of structs? - or make it explicit in the syntax so that it is clear what the memory layout of it is. -- ability to assign struct variable to another? this is slow but can be quite handy sometimes. - however how to handle this in a function that gets the struct passed as reference? Don't allow it there? (there's no pointer dereferencing concept in prog8) -- ability to be passed as argument to a function (by reference)? - however there is no typed pointer in prog8 at the moment so this can't be implemented in a meaningful way yet, - because there is no way to reference it as the struct type again. (current ast gets the by-reference parameter - type replaced by uword) - So-- maybe don't replace the parameter type in the ast? Should fix that for str and array types as well then - +- only as a reference type (uword pointer). This removes a lot of the problems related to introducing a variable length value type. +- arrays of struct is just an array of uword pointers. Can even be @split? +- need to introduce typed pointer datatype in prog8 +- str is then syntactic sugar for pointer to character/byte? +- arrays are then syntactic sugar for pointer to byte/word/float? diff --git a/examples/cx16/amiga.p8 b/examples/cx16/amiga.p8 index e3a9a13d2..605a72b4f 100644 --- a/examples/cx16/amiga.p8 +++ b/examples/cx16/amiga.p8 @@ -175,7 +175,7 @@ widget { const ubyte height = 11 widget.highlightedrect(x+widget.window_close_icon.width, y, width-64, height, true, active) gfx2.plot(x+widget.window_close_icon.width, y+height-1, 1) ; correct bottom left corner - gfx2.text(x+32, y+1, 1, titlestr) + gfx2.text(x+26, y+1, 1, titlestr) widget.window_close_icon(x, y, active) widget.window_order_icon(x+width-22, y, active) widget.window_flipsize_icon(x+width-44, y, active) diff --git a/examples/test.p8 b/examples/test.p8 index ef5088a65..2e97cdea7 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,20 +1,27 @@ %import gfx2 - +%import textio main { sub start() { - gfx2.screen_mode(1) ; 1 and 5 are lo-res and hi-res monochrome + gfx2.screen_mode(6) ; 1 and 5 are lo-res and hi-res monochrome uword xx gfx2.rect(10, 10, 180, 140, 3) gfx2.rect(12, 12, 180, 140, 3) + + cbm.SETTIM(0,0,0) + for xx in 5 to 100 { gfx2.text(xx, xx, 1, sc:"hello world! should be pixel-aligned.") - sys.waitvsync() - sys.waitvsync() + gfx2.text(xx, xx, 2, sc:"hello world! should be pixel-aligned.") + gfx2.text(xx, xx, 3, sc:"hello world! should be pixel-aligned.") gfx2.text(xx, xx, 0, sc:"hello world! should be pixel-aligned.") } + gfx2.screen_mode(0) + txt.print_uw(cbm.RDTIM16()) + txt.print(" jiffies") + repeat { } } }