(Link to AcmlmWiki) Offline: thank ||bass
Register | Login
Views: 13,040,846
Main | Memberlist | Active users | Calendar | Chat | Online users
Ranks | FAQ | ACS | Stats | Color Chart | Search | Photo album
05-16-24 10:20 PM
0 users currently in Programming.
Acmlm's Board - I3 Archive - Programming - Doing a modulus with limited resources New poll | |
Add to favorites | Next newer thread | Next older thread
User Post
MathOnNapkins

1100

In SPC700 HELL


 





Since: 11-18-05

Last post: 6297 days
Last view: 6296 days
Posted on 04-05-06 11:09 AM Link | Quote
I don't really need this per se, but I'm curious if anyone has any ideas on how to implement the function a mod b with no hardware divide or division. Assume a and b are signed 16-bit integers. (SNES or NES pretty much). And yes I know the SNES has hardware division of sorts, but it takes 8 cycles to complete. I can't think of any bitwise trickery that would work, so I'm looking for a fairly fast algorithm in assembly.

Disch

Red Cheep-cheep


 





Since: 12-10-05

Last post: 6576 days
Last view: 6576 days
Posted on 04-05-06 12:34 PM Link | Quote
There's no shortcut... only way to mimic division/mod is to repeatedly subtract until you can't subtract anymore (painfully slow). This has been a topic with me in the past when trying to find a quick way to convert hex numbers to decimal strings in NES games (ie, 02 01 --> 0 2 5 8) -- I never found one. And all the resources I've checked (6502.org, various video game sources) all did it the "long" way or some variant.

The only way you can shortcut it is if you're dividing by a perfect power-of-two... in which case you can mod by ANDing out the low bits (AND #$3F == mod 64) -- but then that only works when unsigned.
sloat



 





Since: 11-18-05
From: Delaware, US

Last post: 6400 days
Last view: 6400 days
Posted on 04-05-06 03:34 PM Link | Quote
for SNES, it might be possible to multiply by the (reciprocal * 2^8)+1 if you're using a constant. I've never tried it on SNES, but with GBA and x86 asm, it works. The result would be in the high-byte of the multiplication result.

You could multiply the result by the divisor and subtract from the original number to get the remainder. I have no idea if all this would be slower than the regular divide function though.

Here's an example:

;123 / 10 = 12
(1/10 * 2^8)+1 = 0x1A

123 * 0x1A = 0x0C7E

As you can see, the high-byte of the result is 0x0C, which is 12.
Add to favorites | Next newer thread | Next older thread
Acmlm's Board - I3 Archive - Programming - Doing a modulus with limited resources |


ABII

Acmlmboard 1.92.999, 9/17/2006
©2000-2006 Acmlm, Emuz, Blades, Xkeeper

Page rendered in 0.008 seconds; used 357.50 kB (max 422.61 kB)