# Score, large numbers, and BCDs

7 replies to this topic

### #1 bjbest60OFFLINE

bjbest60

Chopper Commander

• 109 posts
• Location:Space Cactus Canyon

Posted Wed Nov 28, 2018 11:46 PM

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, Wed Nov 28, 2018 11:47 PM.

### #2 GemintronicOFFLINE

Gemintronic

Jason S. - Lead Developer & CEO

• 9,316 posts

Posted Thu Nov 29, 2018 8:04 AM

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.

### #3 bjbest60OFFLINE

bjbest60

Chopper Commander

• Topic Starter
• 109 posts
• Location:Space Cactus Canyon

Posted Thu Nov 29, 2018 9:48 AM

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.

### #4 Random TerrainONLINE

Random Terrain

Visual batari Basic User

• 28,966 posts
• Controlled Randomness
Replay Value
Nonlinear
• Location:North Carolina (USA)

Posted Sat Dec 1, 2018 7:34 PM

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.

### #5 bogaxOFFLINE

bogax

Dragonstomper

• 791 posts

Posted Sun Dec 2, 2018 11:07 AM

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

asm
sed
clc
lda sc1
sta sc1
lda sc2
sta sc2
lda sc3
sta sc3
cld
rts
end

score_sub
asm
sed
sec
lda sc1
sbc temp1
sta sc1
lda sc2
sbc temp2
sta sc2
lda sc3
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, Sun Dec 2, 2018 2:55 PM.

### #6 bogaxOFFLINE

bogax

Dragonstomper

• 791 posts

Posted Sun Dec 2, 2018 9:14 PM

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, Sun Dec 2, 2018 9:18 PM.

### #7 bjbest60OFFLINE

bjbest60

Chopper Commander

• Topic Starter
• 109 posts
• Location:Space Cactus Canyon

Posted Thu Dec 6, 2018 8:42 PM

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!

### #8 bogaxOFFLINE

bogax

Dragonstomper

• 791 posts

Posted Sat Dec 8, 2018 4:08 PM

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))

#### Attached Files

Edited by bogax, Sat Dec 8, 2018 4:57 PM.

#### 0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users