Skip navigation
NintendoAge
Welcome, Guest! Please Login or Join
Loading...

Nerdy Nights week 9 Numbers, Bin to Dec

May 16, 2010 at 12:30:13 AM
bunnyboy (81)
avatar
(Funktastic B) < Master Higgins >
Posts: 7704 - Joined: 02/28/2007
California
Profile
This Week: NES uses binary and hex, but your gamers want to read in decimal? Here are two solutions for displaying scores and other numbers in a readable way.

BCD Mode
The 6502 processor has a mode called BCD, or Binary Coded Decimal, where the adc/sbc instructions properly handle decimal numbers instead of binary numbers. The NES is not a full 6502 processor and does not include this mode. Be careful when you are searching for code to not copy any that uses that mode, or you will get incorrect results. If the code is doing a SED instruction, it is enabling the decimal mode and you should not use it. Instead you get to do all the decimal handling yourself!

Storing Digits
The first method uses more code, but may be easier to understand. Say your score is a 5 digit number. You will make 5 variables, one for each digit. Those variables will only count from 0 to 9 so you need to write code to handle addition and subtraction. Super Mario uses this method. It's lowest digit is always 0, so that isn't actually stored in a variable. Instead it is just a permanent part of the background.

We will start with just incrementing a 3 digit number to see how its done:
IncOnes:
  LDA onesDigit     ; load the lowest digit of the number
  CLC 
  ADC #$01          ; add one
  STA onesDigit
  CMP #$0A          ; check if it overflowed, now equals 10
  BNE IncDone       ; if there was no overflow, all done
IncTens:
  LDA #$00
  STA onesDigit     ; wrap digit to 0
  LDA tensDigit     ; load the next digit
  CLC 
  ADC #$01          ; add one, the carry from previous digit
  STA tensDigit
  CMP #$0A          ; check if it overflowed, now equals 10
  BNE IncDone       ; if there was no overflow, all done
IncHundreds:
  LDA #$00
  STA tensDigit     ; wrap digit to 0
  LDA hundredsDigit ; load the next digit
  CLC 
  ADC #$01          ; add one, the carry from previous digit
  STA hundredsDigit
IncDone:

When the subroutine starts, the ones digit is incremented. Then it is checked if it equals $0A which is decimal 10. That number doesn't fit in just one digit, so the ones digit is set to 0 and the tens digit is incremented. The tens digit is then checked in the same way, and the chain continues for as many digits as you want.

The same process is used for decrementing, except you check for underflow (digit=$FF) and wrap the digit to $09.

Adding two numbers is the same idea, except other than checking if each digit equals $0A you need to check if the digit is $0A or above. So instead of BEQ the opcode will be BCC.
AddOnes:
  LDA onesDigit      ; load the lowest digit of the number
  CLC 
  ADC onesAdd        ; add new number, no carry
  STA onesDigit
  CMP #$0A           ; check if digit went above 9. If accumulator >= $0A, carry is set
  BCC AddTens        ; if carry is clear, all done with ones digit
                     ; carry was set, so we need to handle wrapping
  LDA onesDigit
  SEC
  SBC #$0A           ; subtract off what doesnt fit in 1 digit
  STA onesDigit      ; then store the rest
  INC tensDigit      ; increment the tens digit
AddTens:
  LDA tensDigit      ; load the next digit
  CLC
  ADC tensAdd        ; add new number
  STA tensDigit
  CMP #$0A           ; check if digit went above 9
  BCC AddHundreds    ; no carry, digit done
  LDA tensDigit
  SEC
  SBC #$0A           ; subtract off what doesnt fit in 1 digit
  STA tensDigit      ; then store the rest
  INC hundredsDigit  ; increment the hundreds digit
AddHundreds:
  LDA hundredsDigit  ; load the next digit
  CLC
  ADC hundredsAdd    ; add new number
  STA hundredsDigit
AddDone:

When that code is all done, the ones/tens/hundreds digits will hold the new value. With both code samples there is no check at the end of the hundreds digit. That means when the full number is 999 and you add one more, the result will be wrong! In your code you can either wrap around all the digits to 0, or set all the digits to 999 again for a maximum value. Of course if your players are hitting the max they likely want more digits!


Binary to Decimal Conversion
The second method of handling number displays uses less code, but could use much more CPU time. The idea is to keep you numbers in plain binary form (8 or 16 bit variables) for the math, then convert them to decimal for displaying only. An 8 bit binary value will give you 3 decimal digits, and a 16 bit binary will give 5 decimal digits.

This first example is coded to be understandable, not fast or small. Each step compares the binary value to a significant decimal value (100 and then 10). If the binary is larger, that value is subtracted from the binary and the final decimal digit is incremented. So for a text example:
initial binary: 124
initial decimal: 000
1: compare to 100
2: 124 greater than 100, so subtract 100 and increment the decimal hundreds digit
3: repeat hundreds again
current binary: 024
current decimal: 100
1: compare to 100
2: 024 less than 100, so all done with hundreds digit
current binary: 024
current decimal: 100
1: compare to 10
2: 024 greater than 10, so subtract 10 and increment the decimal tens digit
3 repeat tens again
current binary: 014
current decimal: 110
1: compare to 10
2: 014 greater than 10, so subtract 10 and increment the decimal tens digit
3 repeat tens again
current binary: 004
current decimal: 120
etc for ones digit

You can see this will transfer the binary to decimal one digit at a time. For numbers with large digits (like 249) this will take longer than numbers with small digits (like 112). Here is the code:
HundredsLoop:
  LDA binary
  CMP #100             ; compare binary to 100
  BCC TensLoop         ; if binary < 100, all done with hundreds digit
  LDA binary
  SEC
  SBC #100
  STA binary           ; subtract 100, store whats left
  INC hundredsDigit    ; increment the digital result
  JMP HundredsLoop     ; run the hundreds loop again
TensLoop:
  LDA binary
  CMP #10              ; compare binary to 10
  BCC OnesLoop         ; if binary < 10, all done with hundreds digit
  LDA binary
  SEC
  SBC #10
  STA binary           ; subtract 10, store whats left
  INC tensDigit        ; increment the digital result
  JMP TensLoop         ; run the tens loop again
OnesLoop:
  LDA binary
  STA onesDigit        ; result is already under 10, can copy directly to result

This code can be expanded to 16 bit numbers, but the compares become harder. Instead a more complex series of loops and shifts with a table is used. This code does shifting of the binary value into the carry bit to tell when to add numbers to the final decimal result. I did not write this code, it came from a post by Tokumaru at http://nesdev.parodius.com/bbs/vi... There are many more examples of different conversion styles at that forum thread.

Notice there are no branches other than the loop running 16 times (one for each binary input bit), so the conversion always takes the same number of cycles.
  tempBinary - 16 bits input binary value
  decimalResult - 5 bytes for the decimal result
BinaryToDecimal:
   lda #$00 
   sta decimalResult+0
   sta decimalResult+1
   sta decimalResult+2
   sta decimalResult+3
   sta decimalResult+4
   ldx #$10 
BitLoop: 
   asl tempBinary+0 
   rol tempBinary+1
   ldy decimalResult+0
   lda BinTable, y 
   rol a
   sta decimalResult+0
   ldy decimalResult+1
   lda BinTable, y 
   rol a
   sta decimalResult+1
   ldy decimalResult+2
   lda BinTable, y 
   rol a
   sta decimalResult+2
   ldy decimalResult+3
   lda BinTable, y 
   rol a
   sta decimalResult+3
   rol decimalResult+4
   dex 
   bne BitLoop 
   rts 
BinTable:
   .db $00, $01, $02, $03, $04, $80, $81, $82, $83, $84


Displaying Numbers
Once you have your numbers in decimal format you need to display them on the screen. With the code above all the results have 00000 = $00 $00 $00 $00 $00. If your background tiles for digits start at tile 0 then that will work fine. However if you are using ASCII you will need to add an offset to each digit. The ASCII code for the digit 0 is $30, so you just add $30 to each digit before writing it to the background. If your code uses the first method of compare/wrapping digits, then you could compare to $3A and wrap to $30 to automatically handle this. You would just need to make sure you set each digit to $30 instead of $00 when clearing the number to 00000. You have control over where background tiles are located, so the offset for the digit tiles can be whatever you choose.

Putting It All Together
Download and unzip the pong2.zip sample files. The playing game state and ball movement code is in the pong2.asm file. Make sure that file, mario.chr, and pong2.bat is in the same folder as NESASM3, then double click on pong1.bat. That will run NESASM3 and should produce pong2.nes. Run that NES file in FCEUXD SP to see the score! Right now the score just increments every time the ball bounces off a side wall.

Try making two scoring variables and drawing them both. You can also use the other binary to decimal converters to add more than 1 to the score each time. In the DrawScore you can also check the score digits and not draw any leading zeros. Instead replace them with spaces when you are drawing to the background.


Edited: 05/16/2010 at 02:45 AM by bunnyboy

May 16, 2010 at 8:50:03 AM
EVIL OVERLORD
Dain (226)
avatar
(Dain Anderson) < Founder >
Posts: 12134 - Joined: 08/14/2006
North Carolina
Profile
That bored in Hawaii?

May 16, 2010 at 9:12:51 AM
arch_8ngel (68)
avatar
(Nathan ?) < Mario >
Posts: 35263 - Joined: 06/12/2007
Virginia
Profile
Originally posted by: Dain

That bored in Hawaii?


A few years back when I took a vacation to Hawaii, I had my best game of Tetris DX ever

-------------------------
 

May 16, 2010 at 10:19:26 AM
albailey (55)
avatar
(Al Bailey) < Lolo Lord >
Posts: 1523 - Joined: 04/10/2007
Ontario
Profile
I should point out that this particular activity is extremely useful for homebrewers, and not just beginners.

When I did sudoku I was storing my score values as hex. When I wanted to display them on the screen as decimal, I figured it would be a simple activity. Not so much. Every snippet of 6502 source code on the web for doing the conversion assumes you are using a NORMAL 6502 with decimal mode, instead of the NES 6502 where it has been removed.
As a result I ended up redesigning my scoring system to do what Bunny shows in the first algorithm, which is to store each digit in a separate variable.

Nowadays I use the exact same BCD algorithm that bunny has shown here. It's definitely one you want to add to your code library.

Thanks B,
Al

-------------------------

My Gameboy collection  97% complete.          My N64 collection   88% complete



 My Gamecube collection  99% complete        My NES collection   97% complete


May 16, 2010 at 11:23:48 AM
udisi (88)
avatar
< King Solomon >
Posts: 3270 - Joined: 11/15/2006
United States
Profile
This is awesomo 5000. Not that I had a lot of time lately, but this will be helpful

May 16, 2010 at 12:30:18 PM
Mario's Right Nut (352)
avatar
(Cunt Punch) < Bowser >
Posts: 6634 - Joined: 11/21/2008
Texas
Profile
Yes, this is very helpful. I posted a variant of the first method in my dev blog sometime back. It took me a VERY long time to make it work correctly, and after that, make it work as a loop for all the different counters visable on screen...then add stuff to make it maximum and minimum out. I never thought to look on nesdev for it. I'll have to experiment with the second one. Looks nifty. Thanks again!

-------------------------

This is my shiny thing, and if you try to take it off me, I may have to eat you.

Check out my dev blog.


Apr 8, 2011 at 9:40:47 AM
Mario's Right Nut (352)
avatar
(Cunt Punch) < Bowser >
Posts: 6634 - Joined: 11/21/2008
Texas
Profile

I modified this to convert a 24-bit number to an 8 bit decimal.  But it takes like 2200 cycles or 18 scan lines.  Surely there's a faster way.  Can anyone point me in the right direction?

;-----------------------------------------------------------------------------------------------------

;  tempBinary - 16 bits input binary value
;  decimalResult - 5 bytes for the decimal result
BinaryToDecimal:
   lda #$00                              ;2
   sta decimalResult+0        ;4
   sta decimalResult+1        ;4
   sta decimalResult+2        ;4
   sta decimalResult+3        ;4
   sta decimalResult+4        ;4
   sta decimalResult+5        ;4
   sta decimalResult+6        ;4
   sta decimalResult+7        ;4
   ldx #$18                               ;2
BitLoop:
   asl tempBinary+0              ;6
   rol tempBinary+1               ;6
   rol tempBinary+2               ;6
   ldy decimalResult+0         ;4
   lda BinTable, y                    ;4
   rol a                                       ;2
   sta decimalResult+0        ;4
   ldy decimalResult+1        ;4
   lda BinTable, y                   ;4
   rol a                                     ;2
   sta decimalResult+1        ;4
   ldy decimalResult+2        ;4
   lda BinTable, y                    ;4
   rol a                                      ;2
   sta decimalResult+2        ;4
   ldy decimalResult+3        ;4
   lda BinTable, y                   ;4
   rol a                                     ;2
   sta decimalResult+3        ;4
   ldy decimalResult+4        ;4
   lda BinTable, y                    ;4
   rol a                                     ;2
   sta decimalResult+4        ;4
   ldy decimalResult+5        ;4
   lda BinTable, y                    ;4
   rol a                                      ;2
   sta decimalResult+5        ;4
   ldy decimalResult+6        ;4
   lda BinTable, y                   ;4
   rol a                                     ;2
   sta decimalResult+6        ;4
   rol decimalResult+7        ;6
   dex                                       ;2
   bne BitLoop                       ;2
   rts

BinTable:
   .db $00, $01, $02, $03, $04, $80, $81, $82, $83, $84

;-----------------------------------------------------------------------------------------------------

 


-------------------------

This is my shiny thing, and if you try to take it off me, I may have to eat you.

Check out my dev blog.


May 13, 2013 at 3:54:54 PM
Roth (67)
avatar
(Rob Bryant) < Lolo Lord >
Posts: 1777 - Joined: 09/14/2006
Illinois
Profile
Yeah, this was helpful for me too! I found a need to modify it to do multiple stats for characters, so I went ahead and made a pastebin of it. Here's the link for any that want to check it out. It's a modification of the second example:

http://pastebin.com/u8gzgPCN...

-------------------------
http://slydogstudios.org...

Jan 19, 2014 at 3:45:34 PM
Vectrex28 (130)
avatar
(CD-i Kraid) < Master Higgins >
Posts: 7789 - Joined: 07/28/2012
Switzerland
Profile
Finally got a score system working. For now, it only increments by 25, but I added a little part that keeps track of an eventual Hi Score
Yes, it's from what I'm trying to program, so there are some weird values that refer to the score sprites I've used.

UpdateScore:

AddOnes:
LDA score1 ; load the lowest digit of the number
CLC
ADC #$05 ; add new number, no carry
STA score1
STA $0285
CMP #$2A ; check if digit went above 9. If accumulator >= $0A, carry is set
BCC AddTens ; if carry is clear, all done with ones digit
; carry was set, so we need to handle wrapping
LDA score1
SEC
SBC #$0A ; subtract off what doesnt fit in 1 digit
STA score1
STA $0285 ; then store the rest
INC score10
INC $0281 ; increment the tens digit
AddTens:
LDA score10 ; load the tens digit of the number
CLC
ADC #$02 ; add new number, no carry
STA score10
STA $0281
CMP #$2A ; check if digit went above 9. If accumulator >= $0A, carry is set
BCC AddHundreds ; if carry is clear, all done with tens digit
; carry was set, so we need to handle wrapping
LDA score10
SEC
SBC #$0A ; subtract off what doesnt fit in 1 digit
STA score10
STA $0281 ; then store the rest
INC score100
INC $027D ; increment the hundreds digit
AddHundreds:
LDA score100 ; load the hundreds digit of the number
CMP #$2A ; check if digit went above 9. If accumulator >= $0A, carry is set
BCC AddThousands ; if carry is clear, all done with ones digit
; carry was set, so we need to handle wrapping
LDA score100
SEC
SBC #$0A ; subtract off what doesnt fit in 1 digit
STA score100
STA $027D ; then store the rest
INC score1000
INC $0279 ; increment the thousands digit
AddThousands:
LDA score1000 ; load the thousands digit of the number
CMP #$2A ; check if digit went above 9. If accumulator >= $0A, carry is set
BCC AddTThousands ; if carry is clear, all done with T digit
; carry was set, so we need to handle wrapping
LDA score1000
SEC
SBC #$0A ; subtract off what doesnt fit in 1 digit
STA score1000
STA $0279 ; then store the rest
INC score10000
INC $0275 ; increment the ten thousands digit
AddTThousands:
LDA score10000 ; load the ten thousands digit of the number
CMP #$2A ; check if digit went above 9. If accumulator >= $0A, carry is set
BCC EndScore ; if carry is clear, all done with TT digit
; carry was set, so we need to handle wrapping
LDA score10000
SEC
SBC #$0A ; subtract off what doesnt fit in 1 digit
STA score10000
STA $0275 ; then store the rest
INC score100000
INC $0271 ; increment the Hundred Thousands digit
EndScore:


HiScoreCheck:
LDA score100000
CMP hiscore100000
BEQ TenThousandsCheck
BCS WriteHi
JMP EndHi
TenThousandsCheck:
LDA score10000
CMP hiscore10000
BEQ ThousandsCheck
BCS WriteHi
JMP EndHi
ThousandsCheck:
LDA score1000
CMP hiscore1000
BEQ HundredsCheck
BCS WriteHi
JMP EndHi
HundredsCheck:
LDA score100
CMP hiscore100
BEQ TensCheck
BCS WriteHi
JMP EndHi
TensCheck:
LDA score10
CMP hiscore10
BEQ OnesCheck
BCS WriteHi
JMP EndHi
OnesCheck:
LDA score1
CMP hiscore1
BEQ EndHi
BCS WriteHi
JMP EndHi
WriteHi:

LDA $0285
STA $02A5
LDA $0281
STA $02A1
LDA $027D
STA $029D
LDA $0279
STA $0299
LDA $0275
STA $0295
LDA $0271
STA $0291
LDA $0285
STA hiscore1
LDA $0281
STA hiscore10
LDA $027D
STA hiscore100
LDA $0279
STA hiscore1000
LDA $0275
STA hiscore10000
LDA $0271
STA hiscore100000
EndHi:

-------------------------
"Energy Tanks, Missiles, Power Bombs... You want it? It's yours my friend! As long as you have enough credits!"



Edited: 01/19/2014 at 03:51 PM by Vectrex28

Jan 20, 2014 at 3:38:57 AM
KHAN Games (89)
avatar
(Kevin Hanley) < Master Higgins >
Posts: 8124 - Joined: 06/21/2007
Florida
Profile
Was there a question in here or just posting code?

-------------------------

gauauu: look, we all paid $10K at some point in our lives for the privilege of hanging out with Kevin


Jan 20, 2014 at 5:31:39 AM
Vectrex28 (130)
avatar
(CD-i Kraid) < Master Higgins >
Posts: 7789 - Joined: 07/28/2012
Switzerland
Profile
Originally posted by: KHAN Games

Was there a question in here or just posting code?



That was a code post

-------------------------
"Energy Tanks, Missiles, Power Bombs... You want it? It's yours my friend! As long as you have enough credits!"


May 4, 2014 at 11:27:25 AM
Vectrex28 (130)
avatar
(CD-i Kraid) < Master Higgins >
Posts: 7789 - Joined: 07/28/2012
Switzerland
Profile
A few months later, I finally came back to this thread with a new, updated scoring routine that puts the old one to shame. It does the same thing as the old one, except it is much more compact and the score loops at 999990. This time, you have to do .rs 5 when declaring the "score" and "hiscore" variables. All other variables are "normal" .rs 1 variables

CheckScores:
  LDX #$04  ;Lowest digit in score RAM is score+4
CheckScoresX:
  CPX #$FF  ;If all 5 digits have been done (If the game has 6 digits, the 6th is in the BG)
  BEQ ScoreCheckDone ;Go to the end of the subroutine
  LDA score,x  ;Loads a score digit in the accumulator
  CMP #$0B  ;Compares it to 0B (A in CHR)
  BCC ScoreOK  ;And goes to ScoreOK if it's smaller than 0A
  SEC   ;If not, substract 10 to the score
  SBC #$0A
  STA score,x
  DEX
  INC score,x  ;And increments the next digit
  JMP CheckScoresX
ScoreOK:
  DEX
  JMP CheckScoresX
ScoreCheckDone:
  LDX #$00  ;This time, we start at the highest digit
HiScoreCheck:
  LDA score,x  ;Load the score and compare it to the HiScore (first 10K, then 1K, etc.)
  CMP hiscore,x
  BEQ NextHiDigit ;If it's equal, check the next digit
  BCS WriteHi  ;If it's higher, it's higher than our hiscore! Write it then
  JMP HiScoreCheckDone ;If not, check the next digit
NextHiDigit:
  INX
  JMP HiScoreCheck
WriteHi:
  LDX #$00
WriteHiX:
  LDA score,x  ;Takes the score variable
  STA hiscore,x  ;And rams them in the HiScore variables
  INX
  CPX #$05
  BNE WriteHiX
HiScoreCheckDone:
  RTS

-------------------------
"Energy Tanks, Missiles, Power Bombs... You want it? It's yours my friend! As long as you have enough credits!"



Edited: 05/04/2014 at 12:40 PM by Vectrex28

Oct 11, 2015 at 8:49:12 AM
SoleGooseProductions (129)
avatar
(Beau ) < King Solomon >
Posts: 3504 - Joined: 04/22/2013
Michigan
Profile
So I have the 16-bit example working (the last one), but it is doing some screwy things. Like, when a button changes the values, it resets to zero (once) before adding/subtracting at the correct rate. Unless I run the routine twice when loading the game state, then the desired number is preserved, and the addition/subtraction adds or subtracts from that value. So I guess my question is, using the last example, how does one modify the values correctly? I could keep making it work the way that I have it, but frankly it bothers me that I cannot figure out why it is doing this. It (or something else) is also messing with my subtraction routines some, I think.

-------------------------
"The light that burns twice as bright burns half as long..." ~ Blade Runner

SoleGooseProductions.com



Edited: 10/11/2015 at 08:49 AM by SoleGooseProductions

Oct 11, 2015 at 9:36:45 AM
user (6)

< El Ripper >
Posts: 1462 - Joined: 05/30/2014
Profile
Originally posted by: SoleGooseProductions

So I have the 16-bit example working (the last one), but it is doing some screwy things. Like, when a button changes the values, it resets to zero (once) before adding/subtracting at the correct rate. Unless I run the routine twice when loading the game state, then the desired number is preserved, and the addition/subtraction adds or subtracts from that value. So I guess my question is, using the last example, how does one modify the values correctly? I could keep making it work the way that I have it, but frankly it bothers me that I cannot figure out why it is doing this. It (or something else) is also messing with my subtraction routines some, I think.

I'll be happy to help, but without seeing the code it is hard to tell what is wrong with it.
Also, by "the last one", do you mean the last (second) one bunnyboy posted in the first post of this thread, or the one Vec posted just above your post?

 

Oct 11, 2015 at 9:53:56 AM
SoleGooseProductions (129)
avatar
(Beau ) < King Solomon >
Posts: 3504 - Joined: 04/22/2013
Michigan
Profile
The 16-bit one in the OP. I guess I am also curious why I cannot add to the TempBinary variables directly, but have to buffer them through another variable instead (i.e. load a value into a variable, and then add this to TempBinary).

EDIT: regardless, what I am curious about is how to modify these values correctly, and not necessarily how to correct my own code.

Double Edit: took a break and figured it out. Well, re-figured it out since I had it figured out a couple weeks ago, but I lost it due to not being able to work on it. The TempBinary is not the value itself (duh!), therefore it does not matter what I do to it. Though I still feel as though there should be a way to alter it directly. Anyways...

So the only question that I have left is: why does the value have to be added to TempBinary? Why cannot it simply be stored? In other words, this does not work:

LDA HexValue
STA TempBinary
LDA HexValue+1
STA TempBinary+1

But this does:

LDA TempBinary
CLC
ADC HexValue
STA TempBinary

LDA TempBinary+1
CLC
ADC HexValue+1
STA TempBinary+1

I'm bracing for a lesson in the Carry...

-------------------------
"The light that burns twice as bright burns half as long..." ~ Blade Runner

SoleGooseProductions.com



Edited: 10/11/2015 at 10:44 AM by SoleGooseProductions

Oct 11, 2015 at 11:55:54 AM
user (6)

< El Ripper >
Posts: 1462 - Joined: 05/30/2014
Profile
Originally posted by: SoleGooseProductions

But this does:

LDA TempBinary
CLC
ADC HexValue
STA TempBinary

LDA TempBinary+1
CLC  ;                      <-- WHY?
ADC HexValue+1
STA TempBinary+1
I admit that I'm not too sure about what you are trying to achieve here, but if in your code in case of overflow of the first ADC the second ADC must be increased by an extra 01, then I think you should not clear the carry before the second ADC. Again, probably I misunderstood your goals here, I see no references to this snippet of code in bunnyboy post.

Oct 12, 2015 at 2:58:23 PM
Mega Mario Man (63)
avatar
(Tim ) < Ridley Wrangler >
Posts: 2743 - Joined: 02/13/2014
Nebraska
Profile
Originally posted by: SoleGooseProductions

The 16-bit one in the OP. I guess I am also curious why I cannot add to the TempBinary variables directly, but have to buffer them through another variable instead (i.e. load a value into a variable, and then add this to TempBinary).

EDIT: regardless, what I am curious about is how to modify these values correctly, and not necessarily how to correct my own code.

Double Edit: took a break and figured it out. Well, re-figured it out since I had it figured out a couple weeks ago, but I lost it due to not being able to work on it. The TempBinary is not the value itself (duh!), therefore it does not matter what I do to it. Though I still feel as though there should be a way to alter it directly. Anyways...

So the only question that I have left is: why does the value have to be added to TempBinary? Why cannot it simply be stored? In other words, this does not work:

LDA HexValue
STA TempBinary
LDA HexValue+1
STA TempBinary+1


But this does:

LDA TempBinary
CLC
ADC HexValue
STA TempBinary

LDA TempBinary+1
CLC
ADC HexValue+1
STA TempBinary+1


I'm bracing for a lesson in the Carry...
Assume for this example
HexValue = 2
TempBinary = 1


LDA HexValue
STA TempBinary
LDA HexValue+1
STA TempBinary+1


This would replace the values in TempBinary and TempBinary+1 with the values in HexValue and HexValue+1. So, HexValue = TempBinary. or 2=2
=======================================================================

LDA TempBinary
CLC
ADC HexValue
STA TempBinary

LDA TempBinary+1
CLC
ADC HexValue+1
STA TempBinary+1


This would Load the value of TempBinary, add HexValue, and then write the sum value to TempBinary. So, TempBinary+HexValue = TempBinary.  1+2=3

Hope that is what you were asking.
 

-------------------------
Current Project
Isometric Survival Horror

Older Projects
Tailgate Party, Power Pad Demo, Happy Hour

Links
Store, Facebook, Twitter


Edited: 10/12/2015 at 03:05 PM by Mega Mario Man

Oct 12, 2015 at 4:06:16 PM
SoleGooseProductions (129)
avatar
(Beau ) < King Solomon >
Posts: 3504 - Joined: 04/22/2013
Michigan
Profile
To be honest, I'm not sure at this point . Sadly, all I know is that my addition and subtraction routines work flawlessly, so far as I've been able to test them. Can't really argue with results, but I'm still curious about the transfer of values (or why a simple transfer won't work, but an addition is required).

-------------------------
"The light that burns twice as bright burns half as long..." ~ Blade Runner

SoleGooseProductions.com


Oct 12, 2015 at 5:42:42 PM
KHAN Games (89)
avatar
(Kevin Hanley) < Master Higgins >
Posts: 8124 - Joined: 06/21/2007
Florida
Profile
I'd like to see a real life example, since you already caught your mistake on why your previous example didn't make any sense.

-------------------------

gauauu: look, we all paid $10K at some point in our lives for the privilege of hanging out with Kevin


Oct 12, 2015 at 6:19:54 PM
user (6)

< El Ripper >
Posts: 1462 - Joined: 05/30/2014
Profile
Originally posted by: SoleGooseProductions

To be honest, I'm not sure at this point . Sadly, all I know is that my addition and subtraction routines work flawlessly, so far as I've been able to test them. Can't really argue with results, but I'm still curious about the transfer of values (or why a simple transfer won't work, but an addition is required).
The way I see it, there are 3 values:
- HexValue
- TempBinary
- carry


The Carry flag can be either 1 (if the flag is set) or 0 (if the flag is not set, or reset).

CLC means that you reset the carry flag to 00, so when you sum the value in the accumulator with the value after the opcode ADC, you will not add also +01.
Since there is not an instruction ADD WITHOUT CARRY, when you use ADC and you don't want the carry flag to influence the result, you just set the carry to 0.
In the example you posted above, you CLC twice, which is ok if it is what you need. Instead if you wish that an overflow in the first ADC adds +01 to the result of the second ADC, then you avoid that second CLC instruction.

As MegaMarioMan pointed out, this code:
  LDA HexValue
  STA TempBinary
is different than this code:

  LDA TempBinary
  CLC
  ADC HexValue
  STA TempBinary
Let say HexValue is == "x", TempBinary is == "y".
("x" and "y" are two values)

In the first case, after running your code, TempBinary will be == "x", because that is what you store into it with such code.

In the second case, after running your code TempBinary will be == "y"+Hex00+"x", since you load the old value, then you add the carry, and you add HexValue. In the socond case you are not moving a value from a variable to another, but you are summing, adding also the carry, the two values, and you are storing that result into TempBinary.

I feel like likely I am missing something you are trying to explain, but I think that if you look at your own two snippets of code for like 20 seconds, you will immediately realize that they don't do the same thing at all, math wise.

Hope this helps.

Oct 12, 2015 at 6:33:20 PM
KHAN Games (89)
avatar
(Kevin Hanley) < Master Higgins >
Posts: 8124 - Joined: 06/21/2007
Florida
Profile
He already realized that, Jack. That's why I asked for another actual example that contains the problem that he has questions with.

-------------------------

gauauu: look, we all paid $10K at some point in our lives for the privilege of hanging out with Kevin


Oct 12, 2015 at 6:46:04 PM
user (6)

< El Ripper >
Posts: 1462 - Joined: 05/30/2014
Profile
Originally posted by: KHAN Games

He already realized that, Jack. That's why I asked for another actual example that contains the problem that he has questions with.

That's what I was thinking too. That's why I said in my post above there is something I likely still miss about his question.
I've been reading the bunnyboy examples in the first post, and none match this snippet of code he posted, but probably is just me not understanding exactely what this snippet of code he posted is for.
HexValue and TempBinary are names that suggest me nothing pratical: there are two values, which seems have to be added. If I knew what they refer to I could understand (and hopefully help) better.
However, I was just trying to help, hope my post didn't sound redundant, that was not the intention.

Oct 13, 2015 at 12:50:05 PM
Mega Mario Man (63)
avatar
(Tim ) < Ridley Wrangler >
Posts: 2743 - Joined: 02/13/2014
Nebraska
Profile
Originally posted by: SoleGooseProductions

To be honest, I'm not sure at this point . Sadly, all I know is that my addition and subtraction routines work flawlessly, so far as I've been able to test them. Can't really argue with results, but I'm still curious about the transfer of values (or why a simple transfer won't work, but an addition is required).

I would need to see the bad code and the rom in action so I can watch the hex values change. Otherwise, I'm just blindly shooting answers from the hip.

If you don't want to post it here, hit me with a pm and we can email or something.
 

-------------------------
Current Project
Isometric Survival Horror

Older Projects
Tailgate Party, Power Pad Demo, Happy Hour

Links
Store, Facebook, Twitter