Page 1 of 1

Multiplication (signed/unsigned)

Posted: Thu Feb 03, 2005 4:26 am
by nullmind
I've got a working multiplication routine (I think?), does it need editing to work with both signed and unsigned values? I've only tested it with unsigned values:

arg0 and arg1 are the numbers, res0 is the result. (the _0 is the low (only) byte in 8-bit, the same memory locations are being used for 16-bit calculations as well)

Code: Select all

mul88:
	clc
	lda #00
	sta res0_0
	sta arg1_0
	ldx #8
mul88_2:
	lsr arg0_1
	bcc mul88_3
	clc
	lda res0_0
	adc arg0_1
	sta res0_0
mul88_3:
	asl arg0_1
	ror arg1_0
	dex
	bne mul88_2
	rts

Posted: Thu Feb 03, 2005 11:48 am
by Memblers
Yeah, signed multiplication would be different. Maybe a little more complex. I haven't used signed stuff very much, so hopefully someone else has better info than me.

I've used a multiplication routine that's pretty much like yours, except I removed the DEX / BNE part and made it an unrolled loop for a little extra speed. (42 cycles or so?)

Code: Select all

multiply:       ; 8-bit multiply.

        lda #0
        sta result_lo

        lsr mult1
        bcc :+
        clc
        adc mult2
:
        ror
        ror result_lo

        lsr mult1
        bcc :+
        clc
        adc mult2
:
        ror
        ror result_lo

        lsr mult1
        bcc :+
        clc
        adc mult2
:
        ror
        ror result_lo

        lsr mult1
        bcc :+
        clc
        adc mult2
:
        ror
        ror result_lo

        lsr mult1
        bcc :+
        clc
        adc mult2
:
        ror
        ror result_lo

        lsr mult1
        bcc :+
        clc
        adc mult2
:
        ror
        ror result_lo

        lsr mult1
        bcc :+
        clc
        adc mult2
:
        ror
        ror result_lo

        lsr mult1
        bcc :+
        clc
        adc mult2
:
        ror
        ror result_lo

        sta result_hi

        rts

Posted: Thu Feb 03, 2005 8:58 pm
by nullmind
Does NESASM support those types of labels? (non-literal labels)

Posted: Thu Feb 03, 2005 9:31 pm
by Disch
eeewwww.... nesasm


awful assembler

Posted: Thu Feb 03, 2005 11:33 pm
by nullmind
Which assembler do you use?

Posted: Fri Feb 04, 2005 12:43 am
by Memblers
I don't think there are unnamed labels in NESASM.

I use CA65.

Really, the code I posted would look a lot nicer if the main part was a macro and the label was local to the macro.

Posted: Fri Feb 04, 2005 2:06 pm
by nullmind
Does anyone else know about signed multiplication routines?

Posted: Fri Feb 04, 2005 2:17 pm
by Disch
Couldn't you just take the absolute value of both factors and then figure out whether the product should be positive or negative and adjust it accordingly?

like check each factor -- if one negative, set a flag and convert the number to its positive counterpart (EOR #$FF CLC ADC #$01) -- do normal, unsigned multiplication with the two factors... and if the product is supposed to be negative (one factor -- but not both negative), negate it.

edit: code to help suggest the idea in case my explaination isn't clear. This isn't the quickest way to do it, but it should give the general idea

Code: Select all

  CLC
  LDA #$00
  STA sign_flag

  LDA factor_1
  BPL :+
  EOR #$FF
  ADC #$01
  STA factor_1
  LDA sign_flag
  EOR #$01
  STA sign_flag

:
  LDA factor_2
  BPL :+
  EOR #$FF
  ADC #$01
  STA factor_2
  LDA sign_flag
  EOR #$01
  STA sign_flag

:
  JSR unsigned_mult_routine

  LDA sign_flag
  BEQ :+

  CLC
  LDA product_lo
  EOR #$FF
  ADC #$01
  STA product_lo
  LDA product_hi
  EOR #$FF
  ADC #$00
  STA product_hi

:
  RTS


Posted: Fri Feb 04, 2005 10:08 pm
by nullmind
That makes sense, I'll check it and post my results when I get back. It's Friday night guys, party!

Thanks for your help, I assume the same method can be done with division?

Thanks,
Chris

[edit]
By the way, is there a better way for doing 8-bit multiplication (without using tables, or should I?) That method I am using is basically just 16-bit one modified.
[/edit]