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>

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 listReceived on 2012-06-01 20:00:26

Archive generated by hypermail 2.2.0.