Re: Problem with opencbm, xu1541 and xubuntu12.04

From: Segher Boessenkool <segher_at_kernel.crashing.org>
Date: Fri, 1 Jun 2012 21:47:07 +0200
Message-Id: <7D4EEA9C-132D-4B3B-BF94-F34ACDF0F3C2@kernel.crashing.org>
>> One wrong thing about the x86 is that it expects and sets the Carry
>> flag in the wrong way in SBC operations (subtract with carry). I
>> find the 6502 more logical.
>
> Technically, you are right, as the behaviour of the 6502 is exactly  
> what
> you get when you do the calculations by hand.
>
> Practically, (almost?) all other CPUs of that time used the carry as
> carry/borrow. That is, for subtractions, carry in and carry out were
> inverted. It seems people felt better this way, although it is further
> away from what the hardware actually does.

I would say it is the other way around: such CPUs used a dual-function
carry/borrow because that _was_ what the hardware does!

The 6502 does subtraction by adding the ones' complement of the input
number, and one more via the carry, so that you get the two's
complement of the second input.  For this, it has extra inverters
on all the eight input bits of that second input.  It doesn't have
to do anything with the carry since it doesn't have addition/subtraction
instructions without carry in (but it still needs to do so for the
various compare, increment, branch, and return instructions).

On most old CPUs that implemented their ALUs with manchester carry
chains, subtraction was implemented directly, so the hardware uses
a borrow flag.  [Of course the first CPU that I check for this, the
6800a, does the two's complement thing!  Oh well].

It is of course not necessary at all to expose these implementation
details in the programming model, but that was rather common at the
time (every gate counts, heh).


To expand a little: say A[] and B[] are the inputs, S[] is the
result of addition or subtraction, and C[] are the various carries/
borrows (C[0] is the carry in, C[8] is the carry out).  We use the
carry generate / carry propagate thing (very directly, in manchester
carry chains!); call those signals G[] and P[].

For addition, we have:
G[x] = A[x] and B[x]
P[x] = A[x] xor B[x]
C[x+1] = G[x] or (P[x] and C[x])
S[x] = A[x] xor B[x] xor C[x]

For subtraction, we have:
G[x] = not A[x] and B[x]
P[x] = not (A[x] xor B[x])
C[x+1] = G[x] or (P[x] and C[x])
S[x] = A[x] xor B[x] xor C[x]

This shows that you can implement subtraction by inverting the
_first_ input for the carry G/P circuit only; the two's complement
scheme inverts the _second_ input for everything, and inverts the
borrow bit (to become a carry bit; the 6502 (as well as most later
CPUs) of course actually stores it inverted, so there is nothing
to do there).


Segher


       Message was sent through the cbm-hackers mailing list
Received on 2012-06-01 20:00:26

Archive generated by hypermail 2.2.0.