16 bit subtraction

Let's talk about anything related to the 6502 microprocessor.
Post Reply
xlar54
Posts: 28
Joined: 18 Oct 2017

16 bit subtraction

Post by xlar54 »

Hey guys, this is likely a noob question, but Ive seen some other 16 bit subtractions that dont seem to take into account a rollover. What I mean is:

C000: 01 FF


If I subtract $05, and the carry is set, then i know I can DEC $C001. But if its zero, I cant. So my subtraction code is no good, since im using BCS.

The most Id be adding or subtracting is less than 256, so its going to only be a single byte. Can someone show some code for this (apparently pretty simple) issue?
User avatar
GARTHWILSON
Forum Moderator
Posts: 8775
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: 16 bit subtraction

Post by GARTHWILSON »

It's not very clear what you mean here—which might be why you're having problems.  Subtracting 5 from 1 or 0, either way, regardless of what the C flag was when you started, will end up with it clear (because 1-5, or 0-5, either way, had to borrow), and your BCS will be correct, to branch, or not branch, around the DEC $C001, to whatever the next lower number is, regardless of rollover, like from $FF to $FE, or 00 to $FF.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
barnacle
Posts: 1831
Joined: 19 Jan 2004
Location: Potsdam, DE
Contact:

Re: 16 bit subtraction

Post by barnacle »

Looks like you're subtracting an eight-bit value from a sixteen bit minuend, no?
Why not just subtract zero from the second byte, irrespective of the carry value? It'll all sort itself out.

Or are you desperate for space or speed?

Code: Select all

	lda $c000
	sbc #5
	sta $c000
	lda $c001		; 4 cycles
	sbc #0			; 2 cycles
	sta $c000		; 4 cycles
	
	lda $c000
	sbc #5
	sta $c000
	bcs label		; 2 cycles
	dec $c001		; 6 cycles
label:
I would submit that while the first version is both smaller and faster, it more clearly shows your intent. Unless I've misunderstood you.

Neil
xlar54
Posts: 28
Joined: 18 Oct 2017

Re: 16 bit subtraction

Post by xlar54 »

Correct. Subtracting an 8 bit number from a 16.

Looking at your examples, i think i see my issue. Im putzing around with the carry flag, doing a SEC before the SBC, etc. Seems your code works without worrying about the carry.

Im still scratching my head though trying to understand why subtracting 0 from the second byte ($FF) results in $FE
xlar54
Posts: 28
Joined: 18 Oct 2017

Re: 16 bit subtraction

Post by xlar54 »

If any Commodore 128 users (or VICE) would like to see what Im working on:

https://github.com/Commodore64128/ataripac128

Movement is still a bit wrong.. its taking me some time to figure things out.
User avatar
Dr Jefyll
Posts: 3526
Joined: 11 Dec 2009
Location: Ontario, Canada
Contact:

Re: 16 bit subtraction

Post by Dr Jefyll »

xlar54 wrote:
Seems your code works without worrying about the carry.
That seems to be a small booboo on barnacle's part, xlar54.

(I know what kind of dodgy excuses I make when I slip up, but in this case I'll leave Neil to deal with the matter himself! :wink: )

Unless the programmer has reason to be sure Carry is already set, there needs to be a SEC somewhere before the first SBC.

Code: Select all

        sec
        lda $c000
        sbc #5
        sta $c000
        lda $c001		; 4 cycles
        sbc #0			; 2 cycles
        sta $c000		; 4 cycles
	
        lda $c000
        sec
        sbc #5
        sta $c000
        bcs label		; 2 cycles
        dec $c001		; 6 cycles
label:
Quote:
Im still scratching my head though trying to understand why subtracting 0 from the second byte ($FF) results in $FE
You need to review the exact definition of what the SBC instruction does, and how it enables multi-byte subtract operations. (It might be helpful to firstly review how the ADC instruction enables multi-byte addition operations.

-- Jeff
Last edited by Dr Jefyll on Tue Mar 14, 2023 10:45 pm, edited 1 time in total.
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
User avatar
GARTHWILSON
Forum Moderator
Posts: 8775
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: 16 bit subtraction

Post by GARTHWILSON »

xlar54 wrote:
I'm still scratching my head though trying to understand why subtracting 0 from the second byte ($FF) results in $FE
The carry flag being clear is the same as a borrow flag (if such a flag existed) being set; so $FF, minus 0, minus 1 for the borrow, is $FE.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
barnacle
Posts: 1831
Joined: 19 Jan 2004
Location: Potsdam, DE
Contact:

Re: 16 bit subtraction

Post by barnacle »

Oh, of course the carry should be set before the start of a subtraction chain; er, er, I just didn't want to clutter up the discussion. Yes, that's it. Or a big boy did it and ran away. Um. Or cosmic rays?

Also, the line
Quote:
I would submit that while the first version is both smaller and faster, it more clearly shows your intent.
should read
Quote:
I would submit that the second version is both smaller and faster, the first more clearly shows your intent.
Here I go again, contributing to the total amount of wrong on the internet! Obviously I shouldn't post late at night.

(When I had to work with PIC assembly ten or a dozen years ago, I had to do multi-precision arithmetic. The PIC didn't have add-with-carry or subtract-with-borrow and as a result the carry had to be rippled through after every addition/subtraction. At the time, *every* example on the net with the sole exception of a single Microchip datasheet got that wrong...)

Though with my statement 'shows intent' I suspect that many of the code writers here would agree with this premise: optimising too early is always a bad idea. In initial code, write for clarity of intent and simplicity of logic; that way you will have more chance of remembering what it's supposed to do when you come back to it in six months, or next week. Come up with clever tricks to optimise code length or clock cycles if and only if it turns out to be necessary, or aesthetically desirable.

Neil
Post Reply