NES math in general - How does one shift to 6 (not 4 or 8)

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
NES math in general - How does one shift to 6 (not 4 or 8)
by on (#131365)
There is a very big problem when shifting in ASM, I wanted to multiply by 6 without losing contents of A, X, or Y...

This is required to make a hack that enhances the Podoboo and other enemy graphics in Mario 1 by multiplying 6 from a value instead of internally screwing with all the enemy graphics to work externally and to save space as well.

Will credit when someone thinks of a way, as well as a thank you for helping!
Re: NES math in general - How does one shift to 6 (not 4 or
by on (#131366)
Something like... A*B = A*(B-c)+A*(c)

As in 3*6 = 3*4 + 3*2.

So Var<<2 + Var<<1.

If you don't want to lose the contents of A/X/Y, push them to the stack.
Re: NES math in general - How does one shift to 6 (not 4 or
by on (#131370)
This is just a rehash of what tomaitheous was saying, but to clarify:

Any multiplication by a constant can be broken down into a series of shifts and adds:
6a = (4+2)a = 4a + 2a = a<<2 + a<<1

Or another example:
123a = (64+32+16+8+2+1)a = a<<6 + a<<5 + a<<4 + a<<3 + a<<1 + a
Re: NES math in general - How does one shift to 6 (not 4 or
by on (#131371)
It might look like this:
Code:
sta temp
asl a     ; a = temp*2
adc temp  ; a = temp * 3
asl a     ; a = temp * 6

Or do you need it with more bits?
Re: NES math in general - How does one shift to 6 (not 4 or
by on (#131375)
You would want a clc before that adc temp if there is a possibility that the high bit of a might be set. For instance: if this operation is to be done on a signed number.
Re: NES math in general - How does one shift to 6 (not 4 or
by on (#133290)
There's a nice book on programming called "numerical methods" that is a bit dated (has some Fortran examples) but covers quite a bit of this sort of question. Of course, since it's mostly a list of algorithms and explanations, it can be applied to any language. It's more aimed at people trying to find Integrals or do fast sorts. For 6502 assembly-aimed advice, look below.

http://codebase64.org/doku.php?id=base:6502_6510_maths You can find quite a bit of optimized math routines and such on that site. You'll probably be reading for days - it's the C64 motherload! I guess all those demo/intro programmers had to find ways to stretch the hardware to do fast graphical effects. If you can't find SNES examples (which can be adapted to NES most of the time), then the home computers like the Apple II and Commodore lines have additional resources.

Edit: Ugh, there's sooooo many books called "Numerical Methods" so I can't provide the ISBN or URL! I was mentioning that name from memory. ;(
Re: NES math in general - How does one shift to 6 (not 4 or
by on (#134755)
Lots of neat 6502 math tricks available here, by the way: http://www.6502.org/source/

See especially the "Integer Math" section. "Fast multiply by 10" uses the same shift-and-add trick that others mentioned in this thread.
Re: NES math in general - How does one shift to 6 (not 4 or
by on (#134783)
And we do have some mathematics examples on the nesdev wiki as well, just for the record:

http://wiki.nesdev.com/w/index.php/Category:Arithmetic