This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

Doing some division...

Doing some division...
by on (#46520)
Hey all. I have a Q on a good way to divide 2 8 bit numbers to end up getting a "decimal point" answer. I'm using this for some fractional movement with things.

Anyway, how can I get it so 1/2 = $80, 1/3 = 1/3 = $55, etc.

I have found routines that get remainders, but I'm looking for this instead. Thanks!

by on (#46521)
Try a 16-bit dividend: $100 / 2 = $80. Do you want me to paste code that does this?

by on (#46522)
tepples wrote:
Try a 16-bit dividend: $100 / 2 = $80. Do you want me to paste code that does this?


Hey there. I actually found a routine from 6502.org that has this. I translated it into my game and it seems to work. I wrote the answer to a random place to check it with the hex viewer.

http://pastebin.ca/1412961

I guess I was over-complicating it with the desire to use 8-bits only, heh. Thanks.

by on (#46532)
Try this:
Code:
      lda #$01
      sta reciprocal
loop: asl
      cmp divisor
      bcc fits
      sbc divisor
fits: rol reciprocal
      bcc loop
      ;15 bytes, 141+/-8 cycles

Note that attempting to take the inverse of one results in a quotient of $ff but I should think that would be more useful than overflowing and returning $00 anyway.
Not that I've actually tested it or anything, aside from a manual test run or two during my database class ;)

edit: I forgot the bloody branch. Thanks tepples..

by on (#46536)
In this code fragment, I notice that you use the carry flag as a loop counter. I do the same thing in my division routine and controller reading routine. But you subtract the reciprocal regardless of the result of the comparison. Was this intended? And for divisors bigger than 128, what happens when asl ends up turning on the carry flag?

by on (#46538)
tepples wrote:
But you subtract the reciprocal regardless of the result of the comparison. Was this intended?
No, it certainly wasn't. I completely missed it when copying the code from my notebook.

Quote:
And for divisors bigger than 128, what happens when asl ends up turning on the carry flag?
Nothing good happens, that's what. Lets hope Sivak can make do with 7-bits or I'll have to put in a check at the top.

by on (#46539)
What's a coincidence, I wrote this not long ago...http://www.6502asm.com/chat/viewtopic.php?p=327&sid=b9e4680cad92c2d67023c00bf006c14d#327... If it looks strange, it's because I wrote that code first on a PIC16F (=no compare instruction)... An even if it's slower, I'm still proud of it because I just poop that without even read math routines on any site. You can divide any number by any number (except zero ;) ), and get the modulo too.

by on (#46560)
One thing I like to do is reciprocal multiplication. I have a 512 byte look up table that contains 256 different 16-bit entries, where each entry is 1/x. So it starts with 1/0 1/1, 1/2, 1/3, 1/4.... all the way to 1/255.

So for 1/2 I have $8000, for 1/3 I have $5555, 1/4 = $4000, 1/5 = $3333, 1/6 = $2AAA. It's all of the numbers beyond the decimal point, 16 bits precision. However, the first two entries are inaccurate and shouldn't even be used. 1/0 and 1/1 = $FFFF in the table. Though 1/1 = $FFFF is more accurate. Anyways, take those values from the look up table an multiply them by what you are trying to divide. So 20/43 would be 20 * 1/43, which gives you more precision and speed than a division routine.