In my game I sometimes have to deal with numbers that won't fit into a 16 bit register because the high score will become so large. This becomes a problem because I am using the _VPutS. I also tried _DispHL but that only works with a 16 bit number as well. I have functions to do addition and other operations with 32 bit numbers and store them into a 4 byte section of memory but I can't figure out how to display a 32 bit number as a string on the screen. If anyone could help me out I would be extremely grateful. Thanks.
The typical way to display numbers involves repeated division by 10. In pseudocode:
Code:
def formatNumber(x) {
    s = "";
    while x != 0 {
        s += '0' + (x % 10);
        x /= 10;
    }
    return s.reverse();
}
Thanks. I will try that. This is going to be a little more complicated since I can't use _DivHLBy10.
dennis48309 wrote:
Thanks. I will try that. This is going to be a little more complicated since I can't use _DivHLBy10.
You said that you came up with a number of 32-bit arithmetic functions for yourself; is division not among them? If not, then z80 Bits has you covered. Also, I urge you to Introduce Yourself when you get a chance.
KermMartian wrote:
dennis48309 wrote:
Thanks. I will try that. This is going to be a little more complicated since I can't use _DivHLBy10.
You said that you came up with a number of 32-bit arithmetic functions for yourself; is division not among them? If not, then z80 Bits has you covered. Also, I urge you to Introduce Yourself when you get a chance.


I am actually fairly new to z80 and assembly. I've been learning the basics and am writing a fairly simple text based game. The only problems I'm running into is the fact that I will end up with integer dollar amounts that will not fit in a 16 bit variable. The 32 bit addition I was using came from http://z80-heaven.wikidot.com/advanced-math. I really don't want to give up but I have done so much research and haven't got anywhere. I also want to understand it without just stealing somebody else's code. Sad
It may be easier to use Binary-Coded Decimal to represent values like scores which you want to easily display. If you don't know what that is, basically each 4 bits of the value is a single decimal digit. So for example, the decimal value 12345678 would be represented as the BCD value 0x12345678. The z80 processor has an opcode called DAA which allows you to easily add or subtract BCD numbers. How you use it is by adding (or subtracting) two 8-bit values and following that with DAA to adjust the result. You can also use add-with-carry to extend the operation to larger bit sizes.
One particularly easy/cheesy way is to make the OS do it. Although there's no universal B_CALL for displaying 32-bit integers, there are multiple useful ones for displaying TI's floating point numbers. So in the past, I've converted my values to floats to display them. This is what I came up with once to convert a 32-bit integer in DE:HL into a float at OP1:


Code:

   push   de
   B_CALL(_SetXXXXOP2)
   B_CALL(_OP2ToOP1)
   ld   hl,32768
   B_CALL(_SetXXXXOP2)
   B_CALL(_FPMult)
   rst   rOP1TOOP2
   rst   rFPADD
   pop   hl
   B_CALL(_SetXXXXOP2)
   rst   rFPADD


This converts the high 16 bits to a float, multiplies them by 32768, adds the result to itself for a total multiplier of 65536, then converts the low 16 bits to a float, and finally adds the two parts together.

From there, I know of two options. You can either display the number to the screen/graph screen directly with B_CALL(_DispOP1A), or you can get its string representation at OP3 with B_CALL(_FormEReal). Both expect the floating point number to be at OP1, which the approach above would do, and for the maximum number of digits to display to be in A, which you probably want to set to 10 or higher to make sure all digits are displayed.
Thanks for the great examples. I'm going to experiment with this now.
Or there's also the ROM call _Disp32, which does exactly what you want : http://wikiti.brandonw.net/index.php?title=83Plus:BCALLs:51CD
matrefeytontias wrote:
Or there's also the ROM call _Disp32, which does exactly what you want : http://wikiti.brandonw.net/index.php?title=83Plus:BCALLs:51CD


I would recommend not relying on this, as it is only present on the 84+, not on the 83+. It also prints the result to the home screen, which may not be what you want. Although if you do want it printed to the home screen and are making something that's 84+ only for other reasons, go ahead and use it.
Everything seems to work fine. I am using _DispOP1A and it works perfectly. Thanks for all the help guys.
dennis48309 wrote:
Everything seems to work fine. I am using _DispOP1A and it works perfectly. Thanks for all the help guys.
Glad we could help. Feel free to stick around with any further questions you might have, and I hope you'll show us your project as it progresses in the Your Projects subforum.
We also discussed this last year here:
http://www.cemetech.net/forum/viewtopic.php?t=9084

There are a couple routines posted there you might be interested in (24- and 32-bit)
chickendude wrote:
We also discussed this last year here:
http://www.cemetech.net/forum/viewtopic.php?t=9084

There are a couple routines posted there you might be interested in (24- and 32-bit)
I'm moderately amused that out of all of us, you're the only one who remembered that we've dealt with this issue before. I now remember liking your method of accelerating the repeated division and subtraction operation necessary for this as well. Smile
I'm having difficulty understanding pointers in ASM.

Code:
ld hl,(Score)

I know that this will get the 16 bits at Score.

Let's say I have 8 different 16 bit numbers stored at Score continuously. How could I use Score as a pointer and use an offset to access all 8 values.

Code:
ld hl,Score

I tried doing this to store the address of Score in HL. I tried doing the following code but it won't work:

Code:
ld hl,(hl)
ld de,(hl)

I don't understand how to use pointers correctly and it won't let me use the registers with parentheses.
Correction: I have found out how to store data at the address stored in HL but don't know how to retrieve data from that address stored in HL.

Code:
ld (hl),$FFFF

I am failing to understand why these commands don't work:

Code:
ld de,(hl)
ld hl,(de)
dennis48309 wrote:
Correction: I have found out how to store data at the address stored in HL but don't know how to retrieve data from that address stored in HL.

Code:
ld (hl),$FFFF
This is not a valid command. This is:
Code:
ld (hl),$FF
inc hl
ld (hl),$FF

Quote:
I am failing to understand why these commands don't work:

Code:
ld de,(hl)
ld hl,(de)
Indirection can only be used to load 1 byte at a time. You could do the following:

Code:
; For ld de,(hl):
ld e,(hl)
inc hl
ld d,(hl)

;For ld hl,(de):
ld a,(de)
ld l,a
inc de
ld a,(de)
ld h,a
Notice that you can load to arbitrary registers from (hl), but you can only load to the accumulator (a) from (de).
So now that I have the address stored in HL, I can get the remaining values by incrementing HL twice?

Code:

ld hl,Scores
inc hl
inc hl
ld e,(hl)
ld d,(hl)

Would this be the proper way to get the next 16 bits located at the address stored in HL?
Try reading your five-line code segment line-by-line, and imagine that you're the processor.
1. First, you increment hl, making it hold the address Scores+1.
2. Then, you increment hl again, making it hold the address Scores+2.
3. Then, you load the contents of the address stored in hl (namely Scores+2) into the register e.
4. Then you load the contents of the address stored at hl (namely Scores+2) into the register d.

See what you did wrong? Smile
I don't see the problem. I want the value at Scores+2. Let's just assume I've already got the value at Scores and I'm moving on to the next one.
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 2
» All times are UTC - 5 Hours
 
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 vote in polls in this forum

 

Advertisement