This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

6502: Break if overflow or underflow

6502: Break if overflow or underflow
by on (#170112)
What do I have to write in 6502 Assembly if I want to check whether an operation produced an overflow or an underflow?
Code:
DEC Value

XXX @underflow
; --> If Value jumped from $00 to $FF, goto @underflow.
; --> What needs to be written for XXX?

JMP @noUnderflow

@underflow:
    ; ...

@noUnderflow:
    ; ...
Re: 6502: Break if overflow or underflow
by on (#170114)
If Value never needs to be greater than $7F, you can use BMI @underflow. Otherwise, you'll need to use an arithmetic opcode that modifies the carry flag, instead of using DEC.
Re: 6502: Break if overflow or underflow
by on (#170116)
You can't use dec because that doesn't affect the carry flag.

Code:
lda value
sec
sbc #$01
sta value
bcc underflow
Re: 6502: Break if overflow or underflow
by on (#170117)
Is this really the only way for one-step decrements? Because in this case, wouldn't the following be even better?
Code:
DEC Value
CMP #$FF
BEQ @underflow
Re: 6502: Break if overflow or underflow
by on (#170118)
CMP compares against A, DEC doesn't put the result in A, so that wouldn't work, unfortunately.
Re: 6502: Break if overflow or underflow
by on (#170119)
Oh, sorry, little correction:
Code:
DEC Value
LDA Value
CMP #$FF
BEQ @underflow

Still only four instead of five instructions.

So, is there a reason why I should still use this instead:
Code:
lda value
sec
sbc #$01
sta value
bcc underflow
Re: 6502: Break if overflow or underflow
by on (#170121)
I didn't realize we were playing Golf. This is faster (avoids the cmp), and the same size assuming zero page.

Code:
lda Value
beq underflow
dec Value

underflow:
dec Value
Re: 6502: Break if overflow or underflow
by on (#170123)
Yeah, that's even better.

Kasumi wrote:
I didn't realize we were playing Golf.

Well, whenever I program something in Assembly, it's usually for time-critical or for general purpose stuff. In both cases, it's good to do the best optimization.

In the current case, I'm implementing a countdown function where the number is stored in an array with each item being one decimal digit because the countdown needs to be displayed on the screen.
Re: 6502: Break if overflow or underflow
by on (#170124)
Pretty sure illegal instructions make this really simple. Haven't tried, but I'm guessing this is how you would do it:

Code:
    lda #$FF
    dcp value
    beq underflow
Re: 6502: Break if overflow or underflow
by on (#170127)
I can't test on my NES right now, but that does work in FCEUX and Nintendulator.
Re: 6502: Break if overflow or underflow
by on (#170128)
O.k., the countdown works, but now I'm programming on my IncrementScore function which also uses an array of digits.

Snippet:
Code:
    CLC
    LDA Score
    ADC IncrementScoreValue
    STA Score

How do I check if (Score >= 10)?
Re: 6502: Break if overflow or underflow
by on (#170129)
Code:
lda Score
cmp #10
bcc scoreisnotgreaterthan10
;stuff that happens when Score >= 10 here
scoreisnotgreaterthan10:
Re: 6502: Break if overflow or underflow
by on (#170130)
Thanks. That worked.
Re: 6502: Break if overflow or underflow
by on (#170134)
I tend to think of a multi-byte decrement as asymmetrical to the corresponding increment; backwards and inefficient. Sort of like how multiplying and dividing are asymmetric. Generically something like:
Code:
inc32:
   inc num+0
   bne :+++
      inc num+1
      bne :++
         inc num+2
         bne :+
            inc num+3
         :
      :
   :
   rts

dec32:
   lda num+0
   bne :+++
      lda num+1
      bne :++
         lda num+2
         bne :+
            dec num+3
         :
         dec num+2
      :
      dec num+1
   :
   dec num+0
   rts
Re: 6502: Break if overflow or underflow
by on (#170140)
Expanding on what Kasumi said, here's how you would add two BCD-style numbers together.
Code:
clc
.repeat num_digits, i
    lda score+i
    adc value+i
    cmp #10
    bcc :+
    sbc #10
:
    sta score+i
.endrepeat

Quote:
I can't test on my NES right now, but that does work in FCEUX and Nintendulator.

Thanks for checking.