optimized cx16.vpoke etc. to be asmsubroutines instead

This commit is contained in:
Irmen de Jong 2020-12-24 07:12:59 +01:00
parent 07b00bec61
commit 3307f673f6
3 changed files with 54 additions and 36 deletions

View File

@ -279,19 +279,18 @@ asmsub vpeek(ubyte bank @A, uword address @XY) -> ubyte @A {
} }
sub vaddr(ubyte bank, uword address, ubyte addrsel, byte incrdecr) { asmsub vaddr(uword address @R0, ubyte bank @R1, ubyte addrsel @A, byte incrdecr @Y) {
; -- setup the VERA's address register 0 or 1 ; -- setup the VERA's address register 0 or 1
%asm {{ %asm {{
lda addrsel
and #1 and #1
sta cx16.VERA_CTRL sta cx16.VERA_CTRL
lda address lda cx16.r0
sta cx16.VERA_ADDR_L sta cx16.VERA_ADDR_L
lda address+1 lda cx16.r0+1
sta cx16.VERA_ADDR_M sta cx16.VERA_ADDR_M
lda bank lda cx16.r1
and #1 and #1
ldy incrdecr cpy #0
bmi _decr bmi _decr
beq _seth beq _seth
ora #%00010000 ora #%00010000
@ -303,76 +302,70 @@ _decr ora #%00011000
} }
; TODO make asmsub versions once that no longer generates larger code... asmsub vpoke(uword address @R0, ubyte bank @A, ubyte value @Y) {
sub vpoke(ubyte bank, uword address, ubyte value) {
; -- write a single byte to VERA's video memory ; -- write a single byte to VERA's video memory
; note: inefficient when writing multiple sequential bytes! ; note: inefficient when writing multiple sequential bytes!
%asm {{ %asm {{
stz cx16.VERA_CTRL stz cx16.VERA_CTRL
lda bank
and #1 and #1
sta cx16.VERA_ADDR_H sta cx16.VERA_ADDR_H
lda address lda cx16.r0
sta cx16.VERA_ADDR_L sta cx16.VERA_ADDR_L
lda address+1 lda cx16.r0+1
sta cx16.VERA_ADDR_M sta cx16.VERA_ADDR_M
lda value sty cx16.VERA_DATA0
sta cx16.VERA_DATA0
rts rts
}} }}
} }
sub vpoke_or(ubyte bank, uword address, ubyte value) { asmsub vpoke_or(uword address @R0, ubyte bank @A, ubyte value @Y) {
; -- or a single byte to the value already in the VERA's video memory at that location ; -- or a single byte to the value already in the VERA's video memory at that location
; note: inefficient when writing multiple sequential bytes! ; note: inefficient when writing multiple sequential bytes!
%asm {{ %asm {{
stz cx16.VERA_CTRL stz cx16.VERA_CTRL
lda bank
and #1 and #1
sta cx16.VERA_ADDR_H sta cx16.VERA_ADDR_H
lda address lda cx16.r0
sta cx16.VERA_ADDR_L sta cx16.VERA_ADDR_L
lda address+1 lda cx16.r0+1
sta cx16.VERA_ADDR_M sta cx16.VERA_ADDR_M
lda value tya
ora cx16.VERA_DATA0 ora cx16.VERA_DATA0
sta cx16.VERA_DATA0 sta cx16.VERA_DATA0
rts rts
}} }}
} }
sub vpoke_and(ubyte bank, uword address, ubyte value) { asmsub vpoke_and(uword address @R0, ubyte bank @A, ubyte value @Y) {
; -- and a single byte to the value already in the VERA's video memory at that location ; -- and a single byte to the value already in the VERA's video memory at that location
; note: inefficient when writing multiple sequential bytes! ; note: inefficient when writing multiple sequential bytes!
%asm {{ %asm {{
stz cx16.VERA_CTRL stz cx16.VERA_CTRL
lda bank
and #1 and #1
sta cx16.VERA_ADDR_H sta cx16.VERA_ADDR_H
lda address lda cx16.r0
sta cx16.VERA_ADDR_L sta cx16.VERA_ADDR_L
lda address+1 lda cx16.r0+1
sta cx16.VERA_ADDR_M sta cx16.VERA_ADDR_M
lda value tya
and cx16.VERA_DATA0 and cx16.VERA_DATA0
sta cx16.VERA_DATA0 sta cx16.VERA_DATA0
rts rts
}} }}
} }
sub vpoke_xor(ubyte bank, uword address, ubyte value) { asmsub vpoke_xor(uword address @R0, ubyte bank @A, ubyte value @Y) {
; -- xor a single byte to the value already in the VERA's video memory at that location ; -- xor a single byte to the value already in the VERA's video memory at that location
; note: inefficient when writing multiple sequential bytes! ; note: inefficient when writing multiple sequential bytes!
%asm {{ %asm {{
stz cx16.VERA_CTRL stz cx16.VERA_CTRL
lda bank
and #1 and #1
sta cx16.VERA_ADDR_H sta cx16.VERA_ADDR_H
lda address lda cx16.r0
sta cx16.VERA_ADDR_L sta cx16.VERA_ADDR_L
lda address+1 lda cx16.r0+1
sta cx16.VERA_ADDR_M sta cx16.VERA_ADDR_M
lda value tya
eor cx16.VERA_DATA0 eor cx16.VERA_DATA0
sta cx16.VERA_DATA0 sta cx16.VERA_DATA0
rts rts

View File

@ -14,6 +14,12 @@ main {
ubyte mode ubyte mode
for mode in modes { for mode in modes {
gfx2.set_mode(mode) gfx2.set_mode(mode)
; gfx2.location(20, 50)
; repeat 200 {
; gfx2.next_pixel(255)
; }
draw() draw()
cx16.wait(120) cx16.wait(120)
} }
@ -129,12 +135,23 @@ gfx2 {
sub plot(uword x, uword y, ubyte color) { sub plot(uword x, uword y, ubyte color) {
ubyte[8] bits = [128, 64, 32, 16, 8, 4, 2, 1] ubyte[8] bits = [128, 64, 32, 16, 8, 4, 2, 1]
uword addr
ubyte value
when active_mode { when active_mode {
0 -> cx16.vpoke_or(0, y*(320/8) + x/8, bits[lsb(x)&7]) 0 -> {
128 -> cx16.vpoke_or(0, y*(640/8) + x/8, bits[lsb(x)&7]) addr = x/8 + y*(320/8)
value = bits[lsb(x)&7]
cx16.vpoke_or(addr, 0, value)
}
128 -> {
addr = x/8 + y*(640/8)
value = bits[lsb(x)&7]
cx16.vpoke_or(addr, 0, value)
}
1 -> { 1 -> {
void addr_mul_320_add_24(y, x) ; 24 bits result is in r0 and r1L void addr_mul_320_add_24(y, x) ; 24 bits result is in r0 and r1L
cx16.vpoke(lsb(cx16.r1), cx16.r0, color) ubyte bank = lsb(cx16.r1)
cx16.vpoke(cx16.r0, bank, color)
} }
} }
; activate vera auto-increment mode so next_pixel() can be used after this ; activate vera auto-increment mode so next_pixel() can be used after this
@ -143,12 +160,20 @@ gfx2 {
} }
sub location(uword x, uword y) { sub location(uword x, uword y) {
uword address
when active_mode { when active_mode {
0 -> cx16.vaddr(0, y*(320/8) + x/8, 0, 1) 0 -> {
128 -> cx16.vaddr(0, y*(640/8) + x/8, 0, 1) address = y*(320/8) + x/8
cx16.vaddr(address, 0, 0, 1)
}
128 -> {
address = y*(640/8) + x/8
cx16.vaddr(address, 0, 0, 1)
}
1 -> { 1 -> {
void addr_mul_320_add_24(y, x) ; 24 bits result is in r0 and r1L void addr_mul_320_add_24(y, x) ; 24 bits result is in r0 and r1L
cx16.vaddr(lsb(cx16.r1), cx16.r0, 0, 1) ubyte bank = lsb(cx16.r1)
cx16.vaddr(cx16.r0, bank, 0, 1)
} }
} }
} }

View File

@ -9,7 +9,6 @@
main { main {
; TODO asmsub version generates LARGER CODE , why is this?
sub vpoke(ubyte bank, uword address, ubyte value) { sub vpoke(ubyte bank, uword address, ubyte value) {
%asm {{ %asm {{
rts rts
@ -29,6 +28,7 @@ main {
ubyte value = 123 ubyte value = 123
bank++ bank++
vpoke(bank, address, value) vpoke(bank, address, value)
vpokeasm(address, bank, value) vpokeasm(address, bank, value) ; TODO generates params on stack if expression is used such as lsb(bank). CHECK STACK UNWINDING!!!
; TODO also see if we can do this via R0-R15 temp registers rather than using the estack???
} }
} }