It is currently Tue Dec 18, 2018 6:32 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 13 posts ] 
Author Message
PostPosted: Tue Nov 20, 2018 2:33 pm 
Offline
User avatar

Joined: Sat Sep 07, 2013 2:59 pm
Posts: 1765
For my new game, I need a way to convert a two-byte unsigned integer value into an array of byte values where each array item represents one decimal digit.

So, if this is my variable:

static uint number = 24680;

then the converted array (byte numberArray[5]) shall have these values:

numberArray[0] == 2
numberArray[1] == 4
numberArray[2] == 6
numberArray[3] == 8
numberArray[4] == 0

If it's faster and easier to calculate, this would also work:

numberArray[0] == 0
numberArray[1] == 8
numberArray[2] == 6
numberArray[3] == 4
numberArray[4] == 2

Which is the fastest way to do this in Assembly? Is there any established best method for it?

_________________
Available now: My game "City Trouble".
Website: https://megacatstudios.com/products/city-trouble
Trailer: https://youtu.be/IYXpP59qSxA
Gameplay: https://youtu.be/Eee0yurkIW4
German Retro Gamer article: http://i67.tinypic.com/345o108.jpg


Top
 Profile  
 
PostPosted: Tue Nov 20, 2018 2:49 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 11016
Location: Rio de Janeiro - Brazil
Isn't this just the same old binary to decimal problem that was discussed to death recently and so many times in the past?


Top
 Profile  
 
PostPosted: Tue Nov 20, 2018 2:52 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 7027
Location: Canada
If you want to find previous conversations on this topic, this is usually referred to as a conversion to decimal. You might search for "decimal" or for threads about division by 10 / divide by 10 which are almost always the same underlying topic.

The "fastest" way to do this is usually to store the number in decimal form to begin with so you don't have to convert, doing operations on it in decimal as needed.


Top
 Profile  
 
PostPosted: Tue Nov 20, 2018 3:00 pm 
Offline
User avatar

Joined: Sat Sep 07, 2013 2:59 pm
Posts: 1765
tokumaru wrote:
Isn't this just the same old binary to decimal problem that was discussed to death recently and so many times in the past?

Well, that's exactly the thing: There are a bazillion threads with several functions per thread.

So, should people who look for an efficient algorithm search through all those threads, trying out each and every attempt manually?

If this topic has been discussed to death, isn't there a final solution? A definite function that does the conversion in the best way possible?

rainwarrior wrote:
The "fastest" way to do this is usually to store the number in decimal form to begin with so you don't have to convert, doing operations on it in decimal as needed.

This might be the fastest way for output. But if you have an energy value that can be decreased by an attack value minus a base defense value minus a temporary status defense value, then is it really the best way to store all these values in five byte long arrays and calculate byte by byte in decimal mode?

_________________
Available now: My game "City Trouble".
Website: https://megacatstudios.com/products/city-trouble
Trailer: https://youtu.be/IYXpP59qSxA
Gameplay: https://youtu.be/Eee0yurkIW4
German Retro Gamer article: http://i67.tinypic.com/345o108.jpg


Top
 Profile  
 
PostPosted: Tue Nov 20, 2018 3:12 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 7027
Location: Canada
DRW wrote:
If this topic has been discussed to death, isn't there a final solution? A definite function that does the conversion in the best way possible?

No. Like with most things there are many ways to approach the problem, and every situation has different needs.

Here's a solution tepples put on the wiki though, along with links to a few others:
http://wiki.nesdev.com/w/index.php/16-bit_BCD

DRW wrote:
This might be the fastest way for output. But if you have an energy value that can be decreased by an attack value minus a base defense value minus a temporary status defense value, then is it really the best way to store all these values in five byte long arrays and calculate byte by byte in decimal mode?

Sometimes yes, sometimes no. It depends on your specific situation. I can't answer that question for you, you're the one that knows how often you're going to need to convert, but here you asked for the fastest converter rather than the fastest attack calculation.


Top
 Profile  
 
PostPosted: Tue Nov 20, 2018 3:13 pm 
Offline
User avatar

Joined: Thu Mar 31, 2016 11:15 am
Posts: 448
viewtopic.php?f=2&t=11341


Top
 Profile  
 
PostPosted: Tue Nov 20, 2018 5:26 pm 
Offline
User avatar

Joined: Sat Sep 07, 2013 2:59 pm
Posts: 1765
Thanks for your help.

The HexToDec999 code by Omegamatrix is the one that fits my needs best.

This one should really be put into the wiki.
(But it should be cleaned up. For some reason, there are a few compiler errors, like when he forgets to add a : after a label name. I'm not sure how such an error could ever happen.)

_________________
Available now: My game "City Trouble".
Website: https://megacatstudios.com/products/city-trouble
Trailer: https://youtu.be/IYXpP59qSxA
Gameplay: https://youtu.be/Eee0yurkIW4
German Retro Gamer article: http://i67.tinypic.com/345o108.jpg


Top
 Profile  
 
PostPosted: Tue Nov 20, 2018 5:41 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 11016
Location: Rio de Janeiro - Brazil
Not all assemblers require labels to be followed by colons.


Top
 Profile  
 
PostPosted: Wed Nov 21, 2018 1:49 am 
Offline
User avatar

Joined: Thu Sep 15, 2016 6:29 am
Posts: 836
Location: Denmark (PAL)
rainwarrior wrote:
The "fastest" way to do this is usually to store the number in decimal form to begin with so you don't have to convert, doing operations on it in decimal as needed.

Maybe I just suck at ASM programming, but in my experience this is also a shortcut to terrible hard-to-discover bugs in the way you calculate values. The NES CPU really isn't geared for decimal calculations.

If you only ever add/subtract by one you should be fine though.

But I'd absolutely recommend storing your value in a 16 bit space and using tepples 16-bit BCD every time you need to update your visual output.


Top
 Profile  
 
PostPosted: Wed Nov 21, 2018 2:43 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 11016
Location: Rio de Janeiro - Brazil
I personally prefer to keep numbers that are not used in complex calculations in decimal to begin with. Things like scores, number of coins, and other stuff that only goes through simple addition and subtraction.

Sumez wrote:
The NES CPU really isn't geared for decimal calculations.

Well, it wasn't designed for running SMB3 either, but people made it do that anyway. :wink:

Doing calculations on decimal digits is exactly the same as working with multi-byte binary numbers, except you have to manually handle the carry and wrapping around. If you write a couple of macros to do it, you don't have to think about this ever again.


Top
 Profile  
 
PostPosted: Wed Nov 21, 2018 2:56 am 
Offline
User avatar

Joined: Sat Sep 07, 2013 2:59 pm
Posts: 1765
Sumez wrote:
But I'd absolutely recommend storing your value in a 16 bit space and using tepples 16-bit BCD every time you need to update your visual output.

tepples' version is slower than the one by Omegamatrix. Especially in situations where your values only need to go to 999. That's the one I'm using now.

Although I had to change it a bit.
For example, he stored the high byte of the integer value in A and the low byte in X.
But passing an integer as a parameter to a function from C, A is the low byte and X the high byte.

Even without C, this is a general inconsistency:

His HexToDec99 and HexToDec255 functions expect their single byte value to be in A.

But HexToDec999 and HexToDec65535 expect the high byte in A and the low byte in X, even though a single byte value is basically the equivalent to the low byte value of an integer, so it's only logical that an integer stored in A and X has the low byte in A and the high byte in X.

_________________
Available now: My game "City Trouble".
Website: https://megacatstudios.com/products/city-trouble
Trailer: https://youtu.be/IYXpP59qSxA
Gameplay: https://youtu.be/Eee0yurkIW4
German Retro Gamer article: http://i67.tinypic.com/345o108.jpg


Top
 Profile  
 
PostPosted: Wed Nov 21, 2018 3:18 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 7027
Location: Canada
Sumez wrote:
rainwarrior wrote:
The "fastest" way to do this is usually to store the number in decimal form to begin with so you don't have to convert, doing operations on it in decimal as needed.

Maybe I just suck at ASM programming, but in my experience this is also a shortcut to terrible hard-to-discover bugs in the way you calculate values. The NES CPU really isn't geared for decimal calculations.

Well, "fast" and "simple" or "safe" are often in opposition. ;P

Though TBH it doesn't really seem much worse than a regular multi-byte add.

For Lizard I wrote some routines for this (1, 2), but I don't think it's a very good example. I didn't need it to be fast, or even simple, it just needed to work, and it did. :P


Top
 Profile  
 
PostPosted: Wed Nov 21, 2018 8:55 am 
Offline
User avatar

Joined: Mon Oct 06, 2014 12:37 am
Posts: 203
tokumaru wrote:
Not all assemblers require labels to be followed by colons.

Precisely. My own assembler requires labels to be prefixed with an asterisk (*) for example.

Code:
*main_init
(code)
*main_loop
(code)


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 13 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group