NintendoAge

Loading...

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!

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!

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

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.

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.

EVIL OVERLORD

Dain (223)

(Dain Anderson) <**Founder** >

Dain (223)

(Dain Anderson) <

Posts: 12084 - Joined: 08/14/2006

North Carolina
Profile
That bored in Hawaii?

That bored in Hawaii?

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

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

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

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

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

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

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

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:

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:

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

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

SoleGooseProductions
(120)

(Beau ) <**Ridley Wrangler** >

(Beau ) <

Posts: 2656 - Joined: 04/22/2013

Indiana
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..." ~

SoleGooseProductions.com

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?

(Beau ) <

Posts: 2656 - Joined: 04/22/2013

Indiana
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...

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..." ~

SoleGooseProductions.com

But this does:

LDA TempBinary

CLC

ADC HexValue

STA TempBinary

LDA TempBinary+1

CLC ; <-- WHY?

ADC HexValue+1

STA TempBinary+1

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:

STA TempBinary

LDA HexValue+1

STA TempBinary+1

But this does:

CLC

ADC HexValue

STA TempBinary

LDA TempBinary+1

CLC

ADC HexValue+1

STA TempBinary+1

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

HexValue = 2

TempBinary = 1

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

=======================================================================

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.

(Beau ) <

Posts: 2656 - Joined: 04/22/2013

Indiana
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..." ~

SoleGooseProductions.com

KHAN Games (88)

(Kevin Hanley) <

Posts: 7732 - Joined: 06/21/2007

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

- 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 TempBinaryis different than this code:

LDA TempBinary CLC ADC HexValue STA TempBinaryLet 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.

KHAN Games (88)

(Kevin Hanley) <

Posts: 7732 - 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.

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.

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.