Assembly: Detect when result rolls over from 255 to 0

Basic and Machine Language

Moderator: Moderators

Post Reply
SparkyNZ
Vic 20 Enthusiast
Posts: 153
Joined: Tue Jan 18, 2011 2:23 am

Assembly: Detect when result rolls over from 255 to 0

Post by SparkyNZ »

I have a loop for copying a block of more than 256 bytes using zero-page pointers

Code: Select all

        ;Increment src and dest pointers so we don't have to worry about Y register exceeding 255..
        lda SRC_PTR_LO ; Starts off at $22 in my case
        clc
        adc PIXEL_ROW_COUNT ; This is $60 (96) in my case, result becomes $82 (bit 7 and overflow are set after execution)

        ; increment HI if over flow bit set
        bvc inc_src_hi_ptr_done

        inc SRC_PTR_HI 
I thought (wrongly) that I could detect a rollover from 255 -> 0 using the overflow bit, but I see that the overflow bit gets set whenever bit 7 of A register is set (because +127 is exceeded).

When adding to the accumulator using ADC, how can I detect whether a zero roll-over has taken place? Would I need to test the accumulator first to see if its already negative/positive and then change the logic to see if the sign has changed after the ADC?
SparkyNZ
Vic 20 Enthusiast
Posts: 153
Joined: Tue Jan 18, 2011 2:23 am

Re: Assembly: Detect when result rolls over from 255 to 0

Post by SparkyNZ »

I think I was going about this the wrong way anyway. I've changed my code - now I'm checking for SRC_PTR_LO and DST_PTR_LO becoming zero instead. I'm using LDA (SRC_PTR_LO,y) but just keeping Y as zero the whole time and incrementing SRC_PTR_LO each time instead of using ADC and y as the counter.. It works..
User avatar
srowe
Vic 20 Scientist
Posts: 1340
Joined: Mon Jun 16, 2014 3:19 pm

Re: Assembly: Detect when result rolls over from 255 to 0

Post by srowe »

SparkyNZ wrote: Wed Oct 04, 2023 8:32 pm When adding to the accumulator using ADC, how can I detect whether a zero roll-over has taken place?
That's precisely what the carry bit is for, so your original code should have been

Code: Select all

bcc inc_src_hi_ptr_done
There are a number of implementations of block moves in the 6502.org code repository,

http://6502.org/source/general/memory_move.html
User avatar
Mike
Herr VC
Posts: 4841
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Assembly: Detect when result rolls over from 255 to 0

Post by Mike »

SparkyNZ wrote:[...] copying a block [...]
srowe wrote:There are a number of implementations of block moves in the 6502.org code repository, [...]
That repository also specifically cares about the direction the pointers within source and target block must run:
  • when the target address is lower than the source address, the pointers are first set to the start of both blocks and incremented until all bytes have been copied,
  • when the target address is higher than the source address, the pointers are first set to the end of both blocks and decremented until all bytes have been copied.
If these conditions are not honoured and the blocks overlap, then parts of the source block will be overwritten before they have been copied.

See also: Counting "trick"/memory copy, where pixel specifically fell over the fact that INC and DEC do not affect the C flag. :wink:
SparkyNZ
Vic 20 Enthusiast
Posts: 153
Joined: Tue Jan 18, 2011 2:23 am

Re: Assembly: Detect when result rolls over from 255 to 0

Post by SparkyNZ »

srowe wrote: Thu Oct 05, 2023 1:21 am That's precisely what the carry bit is for, so your original code should have been
Sigh.. Of course! Why didn't I see that? Thanks. I'll make a note for next time.
User avatar
chysn
Vic 20 Scientist
Posts: 1205
Joined: Tue Oct 22, 2019 12:36 pm
Website: http://www.beigemaze.com
Location: Michigan, USA
Occupation: Software Dev Manager

Re: Assembly: Detect when result rolls over from 255 to 0

Post by chysn »

SparkyNZ wrote: Wed Oct 04, 2023 8:32 pm

Code: Select all

        lda SRC_PTR_LO ; Starts off at $22 in my case
        clc
        adc PIXEL_ROW_COUNT ; This is $60 (96) in my case, result becomes $82 (bit 7 and overflow are set after execution)
Overflow is set in this case because you're adding two positive numbers, but the sign has apparently changed to negative. Basically, a single signed byte isn't long enough to hold a number that big. Since you don't care about signed arithmetic when dealing with 16-bit pointers, you don't care about the overflow flag.
I see that the overflow bit gets set whenever bit 7 of A register is set (because +127 is exceeded).
No, when an instruction sets bit 7, the Negative flag is set, which is tested with BMI (set) and BPL (clear). One useful application of the Negative flag in counters is when you want to include the zeroth index in your operation:

Code: Select all

        ldy #8
@@      lda src,y
        sta dest,y
        dey
        bpl @@
When you use Negative in a counter in this way, your starting index needs to be $80 or less, otherwise your loop ends prematurely. This takes advantage of the fact that lots of things affect Negative, while comparatively few things affect Carry. Fewer things still affect Overflow, only ADC and SBC*.

* This is a lie. There are other things that affect it, obviously CLV. Also PLP. Also--for a totally different reason--BIT. But it's basically true that Overflow is set because of signed arithmetic.
VIC-20 Projects: wAx Assembler, TRBo: Turtle RescueBot, Helix Colony, Sub Med, Trolley Problem, Dungeon of Dance, ZEPTOPOLIS, MIDI KERNAL, The Archivist, Ed for Prophet-5

WIP: MIDIcast BASIC extension

he/him/his
User avatar
Wilson
Vic 20 Enthusiast
Posts: 190
Joined: Mon Sep 28, 2009 7:19 am
Location: Brooklyn, NY

Re: Assembly: Detect when result rolls over from 255 to 0

Post by Wilson »

chysn wrote: Thu Oct 05, 2023 9:11 am CODE: SELECT ALL

ldy #8
@@ lda src,y
sta dest,y
dey
bpl @@
Although 9/10 times this will be

Code: Select all

ldy #8-1
:)

That or

Code: Select all

@@ lda src-1,y
     sta dest-1,y
     dey
     bne @@
Which has the benefit of allowing iteration for .Y values of [$80, $100). Of course, this only works with non-indirect addressing.
Post Reply