Multiplication (signed/unsigned)

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems.

Moderator: Moderators

Post Reply
nullmind
Posts: 8
Joined: Thu Feb 03, 2005 4:23 am

Multiplication (signed/unsigned)

Post by nullmind » Thu Feb 03, 2005 4:26 am

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

User avatar
Memblers
Site Admin
Posts: 3878
Joined: Mon Sep 20, 2004 6:04 am
Location: Indianapolis
Contact:

Post by Memblers » Thu Feb 03, 2005 11:48 am

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

nullmind
Posts: 8
Joined: Thu Feb 03, 2005 4:23 am

Post by nullmind » Thu Feb 03, 2005 8:58 pm

Does NESASM support those types of labels? (non-literal labels)

User avatar
Disch
Posts: 1849
Joined: Wed Nov 10, 2004 6:47 pm

Post by Disch » Thu Feb 03, 2005 9:31 pm

eeewwww.... nesasm


awful assembler

nullmind
Posts: 8
Joined: Thu Feb 03, 2005 4:23 am

Post by nullmind » Thu Feb 03, 2005 11:33 pm

Which assembler do you use?

User avatar
Memblers
Site Admin
Posts: 3878
Joined: Mon Sep 20, 2004 6:04 am
Location: Indianapolis
Contact:

Post by Memblers » Fri Feb 04, 2005 12:43 am

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.

nullmind
Posts: 8
Joined: Thu Feb 03, 2005 4:23 am

Post by nullmind » Fri Feb 04, 2005 2:06 pm

Does anyone else know about signed multiplication routines?

User avatar
Disch
Posts: 1849
Joined: Wed Nov 10, 2004 6:47 pm

Post by Disch » Fri Feb 04, 2005 2:17 pm

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


nullmind
Posts: 8
Joined: Thu Feb 03, 2005 4:23 am

Post by nullmind » Fri Feb 04, 2005 10:08 pm

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]

Post Reply