From 65563b0e79b0b17f8de4a72795f82c36fdd66fbc Mon Sep 17 00:00:00 2001 From: Brooke Vibber Date: Sat, 22 Aug 2026 16:45:09 -0700 Subject: [PATCH] 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 --- mandel-core.s | 69 +++++++++++++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 29 deletions(-) diff --git a/mandel-core.s b/mandel-core.s index 1f7234b..5159e2f 100644 --- a/mandel-core.s +++ b/mandel-core.s @@ -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