From 228b9d1718cd44d055f622d81c0975c1c4d0dc48 Mon Sep 17 00:00:00 2001 From: Greg King Date: Sun, 11 May 2014 01:08:27 -0400 Subject: [PATCH] Added a fast subroutine to multiply two signed 8-bit numbers. --- libsrc/common/cc65_imul8x8r16.s | 22 ++++++++++ libsrc/runtime/imul8x8r16.s | 75 +++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+) create mode 100644 libsrc/common/cc65_imul8x8r16.s create mode 100644 libsrc/runtime/imul8x8r16.s diff --git a/libsrc/common/cc65_imul8x8r16.s b/libsrc/common/cc65_imul8x8r16.s new file mode 100644 index 000000000..0e7d5479b --- /dev/null +++ b/libsrc/common/cc65_imul8x8r16.s @@ -0,0 +1,22 @@ +; +; 2014-03-27, Oliver Schmidt +; 2014-05-08, Greg King +; +; CC65 library: 8x8 => 16 signed multiplication +; + + .export _cc65_imul8x8r16 + .import imul8x8r16, popa, ptr1:zp + + +;--------------------------------------------------------------------------- +; 8x8 => 16 signed multiplication routine. + + +.proc _cc65_imul8x8r16 + + sta ptr1 + jsr popa + jmp imul8x8r16 + +.endproc diff --git a/libsrc/runtime/imul8x8r16.s b/libsrc/runtime/imul8x8r16.s new file mode 100644 index 000000000..017297e4b --- /dev/null +++ b/libsrc/runtime/imul8x8r16.s @@ -0,0 +1,75 @@ +; +; 2010-11-02, Ullrich von Bassewitz +; 2014-05-10, Greg King +; +; CC65 runtime: 8x8 => 16 signed multiplication +; + + .export imul8x8r16, imul8x8r16m + .importzp ptr1, ptr3, tmp1 + + .macpack generic + +;--------------------------------------------------------------------------- +; 8x8 => 16 signed multiplication routine. +; +; multiplicand multiplier product +; LHS RHS result +; ------------------------------------------------------------- +; .A (ptr3-low) ptr1-low .XA +; + +imul8x8r16: + sta ptr3 + +imul8x8r16m: + ldx #>0 + bit ptr3 + bpl @L7 + dex +@L7: stx ptr3+1 ; Extend sign of Left-Hand Side + ldy #<0 ; Clear .XY accumulator + ldx #>0 + lda ptr1 + bmi NegMult + bpl @L2 ; Branch always + +@L0: tya ; Add current multiplicand + add ptr3 + tay + txa + adc ptr3+1 + tax + +@L1: asl ptr3 + rol ptr3+1 +@L2: lsr ptr1 ; Get next bit of Right-Hand Side into carry + bcs @L0 + bnz @L1 ; Loop if more one-bits in multiplier + + tya ; Put result into cc65's accumulator + rts + +; The multiplier is negative. +; Therefore, make it positive; and, subtract when multiplying. +NegMult: + eor #%11111111 + sta ptr1 + inc ptr1 + bnz @L2 ; Branch always + +@L0: tya ; Subtract current multiplicand + sub ptr3 + tay + txa + sbc ptr3+1 + tax + +@L1: asl ptr3 + rol ptr3+1 +@L2: lsr ptr1 ; Get next bit of Right-Hand Side into carry + bcs @L0 + bnz @L1 ; Loop if more one-bits in multiplier + + tya ; Put result into cc65's accumulator + rts