From 27d046011eacc929b05a6ab7a4daab806ad3069d Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Fri, 30 Dec 2022 00:43:44 -0800 Subject: [PATCH] looks workable --- mandel.s | 85 ++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 67 insertions(+), 18 deletions(-) diff --git a/mandel.s b/mandel.s index 24e77db..4b6ad10 100644 --- a/mandel.s +++ b/mandel.s @@ -43,12 +43,11 @@ LOG10 = $ded1 .local plus .local minus lda arg+1 - bpl plus + asl ; sign -> carry lda #$ff - jmp minus -plus: + bcc plus lda #$00 -minus: +plus: sta arg+2 sta arg+3 .endmacro @@ -68,6 +67,26 @@ minus: copy 4, arg1, arg2 .endmacro +; 2 + 8 * byte cycles +.macro neg bytes, arg + sec ; 2 cyc + .repeat bytes, byte ; 8 * byte cycles + lda #00 ; 2 cyc + sbc arg + byte ; 3 cyc + sta arg + byte ; 3 cyc + .endrepeat +.endmacro + +; 18 cycles +.macro neg16 arg + neg 2, arg +.endmacro + +; 34 cycles +.macro neg32 arg + neg 4, arg +.endmacro + .macro add bytes, arg1, arg2 clc .repeat bytes, byte @@ -126,6 +145,10 @@ minus: .macro bitmul16 arg1, arg2, result, bitnum .local next + ; does 16-bit adds + ; arg1 must be 0 or positive + ; arg2 must be 0 or positive + clc ; check if arg1 has 0 or 1 bit in this place @@ -159,21 +182,45 @@ next: .endif .endmacro -.proc imul16 - ; 16-bit arg in FR0 - ; 16-bit arg in FR1 - ; 32-bit result in FR2 +.macro check_sign arg + ; Check sign bit and flip argument to postive, + ; keeping a count of sign bits in the X register. + .local positive + lda arg + 1 + bpl positive + neg16 arg + inx +positive: +.endmacro +.proc imul16 + arg1 = FR0 ; 16-bit arg (clobbered) + arg2 = FR1 ; 16-bit arg (clobbered) + result = FR2 ; 32-bit result + + ldx #0 + ; counts the number of sign bits in X + check_sign arg1 + check_sign arg2 + ; zero out the 32-bit temp's top 16 bits lda #0 - sta FR2 + 2 - sta FR2 + 3 + sta result + 2 + sta result + 3 ; the bottom two bytes will get cleared by the shifts + ; unrolled loop for maximum speed, at the cost + ; of a larger routine .repeat 16, bitnum - bitmul16 FR0, FR1, FR2, bitnum + bitmul16 arg1, arg2, result, bitnum .endrepeat + ; In case of mixed input signs, return a negative result. + cpx #1 + bne positive_result + neg32 result +positive_result: + rts .endproc @@ -202,19 +249,21 @@ loop: .endproc .proc start - ; FR0 = 3 - ; FR1 = 5 - lda #3 - sta FR0 + +loop: + ; FR0 = 5 + ; FR1 = -3 lda #5 - sta FR1 + sta FR0 lda #0 sta FR0 + 1 + lda #$fd + sta FR1 + lda #$ff sta FR1 + 1 jsr imul16 - ; should have 32-bit 15 in FR2 + ; should have 32-bit -15 in FR2 -loop: jmp loop .endproc