optimized gfx2.text() for hires 4c mode

This commit is contained in:
Irmen de Jong 2023-07-26 04:17:44 +02:00
parent 3b90be2d9e
commit 970642244b
4 changed files with 62 additions and 28 deletions

View File

@ -1112,26 +1112,61 @@ skip:
; hires 4c ; hires 4c
; we're going to use a few cx16 registers to make sure every variable is in zeropage in the inner loop. ; 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.r11L = color
cx16.r8 = y
while @(sctextptr) { while @(sctextptr) {
chardataptr = charset_addr + (@(sctextptr) as uword)*8 chardataptr = charset_addr + (@(sctextptr) as uword)*8
cx16.vaddr(charset_bank, chardataptr, 1, true) ; for reading the chardata from Vera data channel 1 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 { repeat 8 {
; TODO rewrite this in assembly, don't call plot for every pixel cx16.r10L = cx16.VERA_DATA1 ; get the next 8 horizontal character bits
; 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.r7 = x cx16.r7 = x
repeat 8 { repeat 8 {
cx16.r9L <<= 1 cx16.r10L <<= 1
if_cs if_cs {
plot(cx16.r7, cx16.r8, cx16.r11L) 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++ 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 x+=8
cx16.r8-=8
sctextptr++ sctextptr++
} }
} }

View File

@ -47,7 +47,6 @@ Libraries:
- fix the problems in atari target, and flesh out its libraries. - fix the problems in atari target, and flesh out its libraries.
- c128 target: make syslib more complete (missing kernal routines)? - c128 target: make syslib more complete (missing kernal routines)?
- c64: make the graphics.BITMAP_ADDRESS configurable (VIC banking) - 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) - 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: 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 - 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. - only as a reference type (uword pointer). This removes a lot of the problems related to introducing a variable length value type.
- no arrays of struct -- because too slow on 6502 to access those, rather use struct of arrays instead. - arrays of struct is just an array of uword pointers. Can even be @split?
can we make this a compiler/codegen only issue? i.e. syntax is just as if it was an array of structs? - need to introduce typed pointer datatype in prog8
or make it explicit in the syntax so that it is clear what the memory layout of it is. - str is then syntactic sugar for pointer to character/byte?
- ability to assign struct variable to another? this is slow but can be quite handy sometimes. - arrays are then syntactic sugar for pointer to byte/word/float?
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

View File

@ -175,7 +175,7 @@ widget {
const ubyte height = 11 const ubyte height = 11
widget.highlightedrect(x+widget.window_close_icon.width, y, width-64, height, true, active) 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.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_close_icon(x, y, active)
widget.window_order_icon(x+width-22, y, active) widget.window_order_icon(x+width-22, y, active)
widget.window_flipsize_icon(x+width-44, y, active) widget.window_flipsize_icon(x+width-44, y, active)

View File

@ -1,20 +1,27 @@
%import gfx2 %import gfx2
%import textio
main { main {
sub start() { 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 uword xx
gfx2.rect(10, 10, 180, 140, 3) gfx2.rect(10, 10, 180, 140, 3)
gfx2.rect(12, 12, 180, 140, 3) gfx2.rect(12, 12, 180, 140, 3)
cbm.SETTIM(0,0,0)
for xx in 5 to 100 { for xx in 5 to 100 {
gfx2.text(xx, xx, 1, sc:"hello world! should be pixel-aligned.") gfx2.text(xx, xx, 1, sc:"hello world! should be pixel-aligned.")
sys.waitvsync() gfx2.text(xx, xx, 2, sc:"hello world! should be pixel-aligned.")
sys.waitvsync() 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.text(xx, xx, 0, sc:"hello world! should be pixel-aligned.")
} }
gfx2.screen_mode(0)
txt.print_uw(cbm.RDTIM16())
txt.print(" jiffies")
repeat { } repeat { }
} }
} }