bjbest60 Posted November 29, 2018 Share Posted November 29, 2018 (edited) 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 November 29, 2018 by bjbest60 1 Quote Link to comment https://forums.atariage.com/topic/285486-score-large-numbers-and-bcds/ Share on other sites More sharing options...
+Gemintronic Posted November 29, 2018 Share Posted November 29, 2018 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. Quote Link to comment https://forums.atariage.com/topic/285486-score-large-numbers-and-bcds/#findComment-4166578 Share on other sites More sharing options...
bjbest60 Posted November 29, 2018 Author Share Posted November 29, 2018 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 2 Quote Link to comment https://forums.atariage.com/topic/285486-score-large-numbers-and-bcds/#findComment-4166638 Share on other sites More sharing options...
+Random Terrain Posted December 2, 2018 Share Posted December 2, 2018 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. 1 Quote Link to comment https://forums.atariage.com/topic/285486-score-large-numbers-and-bcds/#findComment-4168373 Share on other sites More sharing options...
bogax Posted December 2, 2018 Share Posted December 2, 2018 (edited) 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 December 2, 2018 by bogax Quote Link to comment https://forums.atariage.com/topic/285486-score-large-numbers-and-bcds/#findComment-4168666 Share on other sites More sharing options...
bogax Posted December 3, 2018 Share Posted December 3, 2018 (edited) 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 December 3, 2018 by bogax Quote Link to comment https://forums.atariage.com/topic/285486-score-large-numbers-and-bcds/#findComment-4169056 Share on other sites More sharing options...
bjbest60 Posted December 7, 2018 Author Share Posted December 7, 2018 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! 1 Quote Link to comment https://forums.atariage.com/topic/285486-score-large-numbers-and-bcds/#findComment-4171976 Share on other sites More sharing options...
bogax Posted December 8, 2018 Share Posted December 8, 2018 (edited) 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 December 8, 2018 by bogax Quote Link to comment https://forums.atariage.com/topic/285486-score-large-numbers-and-bcds/#findComment-4172976 Share on other sites More sharing options...
Recommended Posts
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.