Compare commits

...
Author SHA1 Message Date
65563b0e79 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
2026-08-22 16:45:09 -07:00
23fa002f33 comments 2026-08-22 16:30:41 -07:00

View file

@ -593,32 +593,57 @@ 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
; top 2 bits are the table bank selector
; note we keep arg2 in X after this lookup as we need it later!
ldx arg2 ; 3 cyc
lda bank_switch_table,x ; 4 cyc
sta PORTB ; 4 cyc
; bottom 14 bits except the LSB are the per-bank table index
; add $4000 for the bank pointer
; note the low byte of ptr is assumed to remain at 0! do not clobber it!
txa ; 2 cyc
and #$3f ; 2 cyc
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
@ -627,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
@ -774,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
@ -794,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
@ -826,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)
@ -853,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