News: 11 March 2016 - Forum Rules
Current Moderators - DarkSol, KingMike, MathOnNapkins, Azkadellia, Danke

Author Topic: 6502 ASM - Multiplying a value by 2?  (Read 2735 times)

RetroRain

  • Sr. Member
  • ****
  • Posts: 287
    • View Profile
6502 ASM - Multiplying a value by 2?
« on: March 04, 2016, 08:39:59 pm »
I need to take a value that the game loads into the accumulator, the values that are on the left, and get them to be the values on the right.  I have to multiply by 2 to get the value on the right.  I never had to deal with multiplication before, so I don't know how to do it.

Code: [Select]
Original New

   00 00
   01 02
   02 04
   03 06
   04 08
   05 0a
   06 0c
   07 0e
   08 10

Any help would be appreciated.  Thank you.

mziab

  • Sr. Member
  • ****
  • Posts: 320
    • View Profile
    • mteam
Re: 6502 ASM - Multiplying a value by 2?
« Reply #1 on: March 04, 2016, 08:46:54 pm »
You need to use the ASL opcode (Arithmetic Shift Left). As the name suggests, it shifts the operand one bit left, effectively multiplying it by 2. Multiplying by numbers which aren't powers of 2 is more involved, but fortunately you don't need to worry about that in this case.

RetroRain

  • Sr. Member
  • ****
  • Posts: 287
    • View Profile
Re: 6502 ASM - Multiplying a value by 2?
« Reply #2 on: March 04, 2016, 09:00:48 pm »
I figured that was the case, but I guess I'm going to have to keep playing around with it.  I'm trying to get this bankswitch routine I have to work properly.  So I'll just keep at it.  Thank you for your help.

KingMike

  • Forum Moderator
  • Hero Member
  • *****
  • Posts: 7154
  • *sigh* A changed avatar. Big deal.
    • View Profile
Re: 6502 ASM - Multiplying a value by 2?
« Reply #3 on: March 04, 2016, 09:57:57 pm »
Yes, (integer) multiplication is easy.
For power-of-2 multiplication you can just use shifts.
For non-power-of-2, you can combine shifts with adds:

x3 = STA Original : ASL A : CLC : ADC Original
x5 = STA Original : ASL A : ASL A: CLC : ADC Oirginal
x6 = ASL A : STA Temp : ASL A : CLC : ADC Temp
etc.

If I wanted I could probably even write a (slow) function to multiply any two values.

Now it's division (even integer division), I don't think is so easy to do.
"My watch says 30 chickens" Google, 2018

Disch

  • Hero Member
  • *****
  • Posts: 2814
  • NES Junkie
    • View Profile
Re: 6502 ASM - Multiplying a value by 2?
« Reply #4 on: March 05, 2016, 02:21:17 am »
Arbitrary multiplication of 2 values from FF1 source:

input:
  X, A = the values you want to multiply
output:
  X = high 8 bits of result
  A = low 8 bits

3 bytes of temp ram used

Code: [Select]
MultiplyXA:
    STA btltmp_multA    ; store the values we'll be multiplying
    STX btltmp_multB
    LDX #$08            ; Use x as a loop counter.  X=8 for 8 bits
   
    LDA #$00            ; A will be the high byte of the product
    STA btltmp_multC    ; multC will be the low byte
   
    ; For each bit in multA
  @Loop:
      LSR btltmp_multA      ; shift out the low bit
      BCC :+
        CLC                 ; if it was set, add multB to our product
        ADC btltmp_multB
    : ROR A                 ; then rotate down our product
      ROR btltmp_multC
      DEX
      BNE @Loop
   
    TAX                     ; put high bits of product in X
    LDA btltmp_multC        ; put low bits in A
    RTS

RetroRain

  • Sr. Member
  • ****
  • Posts: 287
    • View Profile
Re: 6502 ASM - Multiplying a value by 2?
« Reply #5 on: March 05, 2016, 01:43:08 pm »
Crazy how much you have to do just to multiply two values in 6502 ASM.  Anyway, this is a good reference thread for the future if I need it.  I needed to confirm what I suspected about ASL because it was used in a bankswitch routine of a game that I've had a hard time with.

Thank you for the information guys.

Disch

  • Hero Member
  • *****
  • Posts: 2814
  • NES Junkie
    • View Profile
Re: 6502 ASM - Multiplying a value by 2?
« Reply #6 on: March 05, 2016, 02:50:46 pm »
Crazy how much you have to do just to multiply two values in 6502 ASM.  Anyway, this is a good reference thread for the future if I need it.  I needed to confirm what I suspected about ASL because it was used in a bankswitch routine of a game that I've had a hard time with.

Thank you for the information guys.

Well... keep in mind ASL is a shift operation, not really a multiply operation:

Code: [Select]
00100110  <-  some value
01001100  <-  the value left shift 1 (after 1 ASL)
10011000  <-  the value left shift 2 (after 2 ASLs)

ASL moves each bit in a byte left 1 position.  The bit that gets "shifted out" gets put in the C flag.

It just so happens that due to the way 2's compliment works, this doubles the weight of each bit, resulting in doubling the number.