Decent speedup in XE mode

Noticed that the separate addition for the low 1 bit case was
doing some dupe memory loads. Ended up making separate code
paths for even and odd values so the even saves two cycles
(from 52 down to 50 cycles) and the odd saves 14 cycles (from
69 down to 55 cycles). nice!

This gets the XE runtime on default view down from 3m38s to 3m33s,
a 5 second runtime improvement
This commit is contained in:
Brooke Vibber 2026-08-22 16:45:09 -07:00
commit 65563b0e79

View file

@ -593,7 +593,9 @@ bank_switch_table:
.macro imul8 dest, arg1, arg2, xe
.if xe
; using 64KB lookup table
; 52-69 cycles
; 50-55 cycles
; min: 11 + 9 + 9 + 21 = 50
; max: 11 + 9 + 9 + 26 = 55
; clobbers x, y, dest, ptr
.scope
output = dest
@ -612,15 +614,36 @@ bank_switch_table:
ora #$40 ; 2 cyc
sta ptr + 1 ; 3 cyc
; copy the entry into output
; mask off the low bit for the index, as the table contains
; entries for every other arg1 value...
lda arg1 ; 3 cyc
and #$fe ; 2 cyc
tay ; 2 cyc
lda (ptr),y ; 5 cyc
sta output ; 3 cyc
iny ; 2 cyc
lda (ptr),y ; 5 cyc
sta output+1 ; 3 cyc
and #1 ; 2 cyc
bne odd ; 2 cyc
even:
; copy the entry into output
lda (ptr),y ; 5 cyc
sta output ; 3 cyc
iny ; 2 cyc
lda (ptr),y ; 5 cyc
sta output + 1 ; 3 cyc
jmp done ; 3 cyc
odd:
; skip the LSB for the index
dey ; 2 cyc
; add arg2 one last time for the skipped bit
txa ; 2 cyc
clc ; 2 cyc
adc (ptr), y ; 5 cyc
sta output ; 3 cyc
lda #0 ; 2 cyc
iny ; 2 cyc
adc (ptr),y ; 5 cyc
sta output + 1 ; 3 cyc
; note: we are not restoring memory to save 6 cycles!
; this means those 16kb have to be switched back to base RAM
@ -629,18 +652,6 @@ bank_switch_table:
;;lda #$81 ; 2 cyc - disabled
;;sta PORTB ; 4 cyc - disabled
; check that 1 bit we skipped to fit into space
lda arg1 ; 3 cyc
and #1 ; 2 cyc
beq done ; 2 cyc
; add arg2 one last time for the skipped bit
clc ; 2 cyc
txa ; 2 cyc
adc output ; 3 cyc
sta output ; 3 cyc
add_carry output + 1 ; 2-7 cyc
done:
.endscope
.else
@ -776,8 +787,8 @@ inner_loop:
; min base mem: 81 * 4 + 22 * 2 + 10 + 6 = 384 cyc
; max base mem: 92 * 4 + 27 * 2 + 50 + 6 = 478 cyc
; min ext-mem: 52 * 4 + 22 * 2 + 10 + 6 = 268 cyc
; max ext-mem: 69 * 4 + 27 * 2 + 50 + 6 = 386 cyc
; min ext-mem: 50 * 4 + 22 * 2 + 10 + 6 = 260 cyc
; max ext-mem: 55 * 4 + 27 * 2 + 50 + 6 = 330 cyc
.macro imul16_impl xe
.local arg1
.local arg2
@ -796,18 +807,18 @@ inner_loop:
; h1*h2*256*256 + h1*l2*256 + h2*l1*256 + l1*l2
; l1 * l2
imul8 result, arg1, arg2, xe ; 81-92 or 52-69
imul8 result, arg1, arg2, xe ; 81-92 or 50-55
; 256 * 256 * h1 * h2
imul8 result + 2, arg1 + 1, arg2 + 1, xe ; 81-92 or 52-69
imul8 result + 2, arg1 + 1, arg2 + 1, xe ; 81-92 or 50-55
; 256 * h1 * l1
imul8 inter, arg1 + 1, arg2, xe ; 81-92 or 52-69
imul8 inter, arg1 + 1, arg2, xe ; 81-92 or 50-55
add16 result + 1, result + 1, inter ; 20 cyc
add_carry result + 3 ; 2-7 cyc
; 256 * l1 * h2
imul8 inter, arg1, arg2 + 1, xe ; 81-92 or 52-69
imul8 inter, arg1, arg2 + 1, xe ; 81-92 or 50-55
add16 result + 1, result + 1, inter ; 20 cyc
add_carry result + 3 ; 2-7 cyc
@ -828,8 +839,8 @@ arg2_pos:
; min base ram: 5 + 19 * 2 + 81 + 22 * 2 + 6 = 174
; max base ram: 23 + 19 * 2 + 92 + 27 * 2 + 6 = 213
; min ext ram: 5 + 19 * 2 + 52 + 22 * 2 + 6 = 145
; max ext ram: 23 + 19 * 2 + 69 + 27 * 2 + 6 = 190
; min ext ram: 5 + 19 * 2 + 50 + 22 * 2 + 6 = 143
; max ext ram: 23 + 19 * 2 + 55 + 27 * 2 + 6 = 176
.macro sqr16_impl xe
.scope
arg = FR0 ; 16-bit arg (clobbered)
@ -855,7 +866,7 @@ arg2_pos:
sqr8 result + 2, arg + 1 ; 19 cyc
; 2 * h * l * 256
imul8 inter, arg + 1, arg, xe ; 81-92 / 52-69 cyc
imul8 inter, arg + 1, arg, xe ; 81-92 / 50-55 cyc
add16 result + 1, result + 1, inter ; 20 cyc
add_carry result + 3 ; 2-7 cyc
add16 result + 1, result + 1, inter ; 20 cyc