Jump to content
IGNORED

Score, large numbers, and BCDs


Recommended Posts

Every time I've tried to add a variable to a score, I feel like I've quickly gone wrong because I can't seem to figure out BCDs and the dec statement. Often my solution is a simple loop:

for x = 1 to level : score = score + 50 : next

That works well for small, repeatable instances. But I've got a game concept I'd like to implement where the score can be large, and with that amount (let's assume it's money), you can purchase things that have variable prices and are larger than 255.

 

So, for example, with a score of 25,000, I could purchase an item that costs 9,876.

 

The question is how to make this work. I understand the _sc1, _sc2, and _sc3 parts of the score. My idea would be to store prices in data arrays similarly named, with two digits per price. So, for something that costs 9,876, item1 would have an entry of $00 (first two digits), item2 would be $98 (second two digits), and item3 would have an entry of $76. I also understand how to store _sc1 et al. into other variables and replace them when necessary. But I can't figure out the math and the proper way to store things to have the calculations come out correctly. Ideally, I'd like the score to display the cost upon hovering over a graphic of the item to be bought (by using a missile as a mouse pointer, say), then you could press fire to buy the item, and then upon leaving the correct new score would display (old score - price of item). I'm trying to do this by comparing each pair of digits and subtracting where appropriate (and "carrying the one" when necessary).

 

I've fought with BCDs and dec statements and trying to parse how the score works and I can't seem to get anywhere. I'm running into some hex issues where if I store $10 into my data array and load it into _sc3, It's actually hex 10 = decimal 16. (And I think I've tried every combination of dec statements and dollar signs to combat this, to no avail.) So there's some definite hex / dec conversion issues I'm failing to navigate.

 

Anyway, I'd really appreciate any assistance in trying to make this work. I've looked at RT's page, sample programs, the forums, etc., and haven't found the right combination of operations yet. Thanks.

Edited by bjbest60
  • Like 1
Link to comment
https://forums.atariage.com/topic/285486-score-large-numbers-and-bcds/
Share on other sites

The score supports only a small subset of math operations as bB only directly supports 8-bit (0-255) variables. I usually end up just treating the score as a display then use 8-bit variables internally.

 

For instance: in my latest game I used the score to display a timer BUT internally I counted the time down using a variable that decrements down to 0 when the timer display also happens to run down to 0.

 

You could do the same thing with purchasable items in your game. Internally you could store a 1 but display a score of 1000 for the end user.

Ok, I think I've figured it out. It's a matter of keeping everything decimal all the time. So every mathematical operation needs to be preceded by dec, and every number needs to be preceded by a dollar sign. "Carrying the one" is a bit tricky. So, for 1234 - 57, you have to reduce the number 12 by 1. That's easy (and needs to be done with a dec statement and a dollar sign). But then you need to add 100 to the 34. This needs to be done in two terms because $100 isn't a valid BCD. So instead it's $99 - 57 + 34 + $01 (where 57 and 34 would actually be variables).

 

I'm attaching the files that show how this works; press fire to "buy" a rectangle when hovering over it. (It changes color when you hover, and then again when you buy.) I'm hopeful this is the correct and robust solution, but I will post further if I find mistakes.

priceexample2.bas

priceexample2.bas.bin

  • Like 2

When I can get back to using my computer more than a couple times a week, I'll link to your finished example from the bB page. After you are sure that you have it totally figured out, maybe you can make a new thread about, even if it's just an adapted version of what you posted above.

  • Like 1

Ok, I think I've figured it out. It's a matter of keeping everything decimal all the time. So every mathematical operation needs to be preceded by dec, and every number needs to be preceded by a dollar sign. "Carrying the one" is a bit tricky. So, for 1234 - 57, you have to reduce the number 12 by 1. That's easy (and needs to be done with a dec statement and a dollar sign). But then you need to add 100 to the 34. This needs to be done in two terms because $100 isn't a valid BCD. So instead it's $99 - 57 + 34 + $01 (where 57 and 34 would actually be variables).

 

I'm attaching the files that show how this works; press fire to "buy" a rectangle when hovering over it. (It changes color when you hover, and then again when you buy.) I'm hopeful this is the correct and robust solution, but I will post further if I find mistakes.

 

Not exactly sure what you're trying to do
dec wont have any effect on simple assignment statements
Somewhere I think RevEng posted some BCD routines for use with the score
You would do something like
 
 dim sc1 = score + 2
 dim sc2 = score + 1
 dim sc3 = score
 
score_add
 asm
 sed
 clc
 lda sc1
 adc temp1
 sta sc1
 lda sc2
 adc temp2
 sta sc2
 lda sc3
 adc temp3
 sta sc3
 cld
 rts
end
 
 
score_sub
 asm
 sed
 sec
 lda sc1
 sbc temp1
 sta sc1
 lda sc2
 sbc temp2
 sta sc2
 lda sc3
 adc temp3
 sbc sc3
 cld
 rts
end
 
You can do that in Bb but (as you're learning) it gets messy
If you just have to do it in Bb I think I'd do it a nybble at a time and use tables
Edited by bogax

 

If you just have to do it in Bb I think I'd do it a nybble at a time and use tables

 

On second thought, since you've got decimal mode math in Bb I think you could do it byte wise like this (untested)
 
  dim sc1 = score + 2
  dim sc2 = score + 1
  dim sc3 = score
  dim carry = temp5
 
 
  temp4 = sc1
  dec sc1 = sc1 + temp1
  carry = 0 : if sc1 < temp4 then carry = carry + 1
  temp4 = sc2
  dec sc2 = sc2 + temp2 + carry
  carry = 0 : if sc2 < temp4 then carry = carry + 1 
  dec sc3 = sc3 + temp3 + carry
 
Edited by bogax

Thanks for both suggestions. I have a feeling they're both probably more efficient than what I came up with. But the file I posted above does seem to work, so I went with those strategies. I'll make a more complete post as RT suggests with a "final" version of my code, but I'll also link here. Thanks!

  • Like 1


BCD is Binary Coded Decimal, ie base ten digits represented by binary.

Binary is base 2 and you need 4 bits to represent the largest decimal digit 9.

A byte is eight bits so you can have two BCD digits per byte.

4 bits gives you numbers 0..15.

Hexadecimal is 0..15 and corresponds more or less directly to 4 bits (hexadecimal is base 16, 16 is 2^4)

For hexadecimal you have 0..9 with A..F for 10..15d so 14d is $0E, 16d is $10

10d is represented by 16d (which is $10 in hexadecimal)

If you add two BCD digits and they add up to < 10d all is good

If you add two BCD digits and they add up to >= 10d you're 6 short so you add 6

So eg 9 + 5 = 14d, 14 + 6 = 20 which is 16 + 4 or $14

You have 2 digits per byte and you have to do that for both digits which is why

I suggested nybbles ie a digit at a time


But with decimal mode the processor does it for you a byte (two BCD digits) at a time


The score is 6 BCD digits, but think of a byte as a single 0..99 digit and the score

as three digits and you can do it bytewise just like you'd do any other digits


I can't think of a simple way to explain, but if you add two digits

you'll have a carry iff the result is less than either of the two digits

So you can generate a carry by looking at how the digit changed



here's your code after I got through mangling it


(I reversed the order of the bytes, the screen displays left to right

but I prefer the math to be right (least significant) to (left most signicant))

priceexample2_mod.bas

Edited by bogax

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...