12

Does SUB B on Intel 8080 set the auxiliary carry flag when the accumulator and the B register are 1 and 0, respectively? On Z80, which was designed to be a backward-compatible, albeit not fully, extension to 8080, the half-carry flag is defined so that it gets set if subtraction results in a borrow from bit 4 (Z80 CPU User Manual, p. 68). Therefore, "1 - 0" will reset the flag on Z80 because no borrow occurs in the subtraction. Is it also the case on 8080? More generally, does the auxiliary carry flag on 8080 behave in the exactly same way as the half-carry flag on Z80?

The official 8080 manuals appear less clear about when subtraction turns on the auxiliary carry flag than the Z80 manual. I have observed that some 8080 emulators turn the flag on for "1 - 0" but others do not. As another example, the first and second algorithms in Can someone explain this algorithm used to compute the auxiliary carry flag? will reset and set the flag for the subtraction, respectively.

3
  • 1
    The auxiliary carry flag on 8080 does not appear to be defined in terms of borrowing. "Intel 8080 Assembly Language Programming Manual, Rev. C, p. 18" and "Intel 8080/8085 Assembly Language Programming Manual, p. 3-64" state that SUB A will turn the flag on. Note that no borrow occurs in SUB A (or A - A).
    – dkim
    Oct 21, 2019 at 11:29
  • Just to comment "Z80, which was designed to be a backward-compatible extension to 8080". It is actually NOT binary-compatible with i8080 with the simple counter-example: whether i8080 sets parity flag after additions and subtractions, Z80 re-uses the same flag as an overflow flag. From this point on, binary compatibility is broken.
    – lvd
    Oct 21, 2019 at 14:07
  • 2
    For future readers, I added "albeit not fully" to the question to make it clear that Z80 is not fully backward-compatible with Intel 8080. Oct 30, 2019 at 12:25

1 Answer 1

8

To get the correct answer, one should take a real i8080 system and make simple experiments with it. However, if no such system is available, one can take the result of reverse engineering of i8080 and make simple experiments in HDL simulator. So did I. The program suggested to the CPU:

// simple ROM
reg [7:0] rom [0:15] = 
'{
    8'h31, //
    8'h10, //
    8'h80, // ld   sp,#8010

    8'h3e, //
    8'h00, // ld   a,#00

    8'h06, //
    8'h01, // ld   b,#01

    8'h90, // sub  b

    8'hf5, // push af

    8'h3e, //
    8'h01, // ld   a,#01

    8'h06, //
    8'h00, // ld   b,#00

    8'h90, // sub  b

    8'hf5, // push af

    8'h76  // halt
};

(I used Z80 mnemonics because they are more concise).

The full testbench is here, it contains the model (vm80a, called so after the name of russian i8080 clone, КР580ВМ80А), simple ROM and simple RAM.

The result is here: i8080 simulation

You can see that auxiliary carry (psw_ac on the picture) set to 0 when, in the first subtraction, subtracting one from zero and set to 1 when subtracting zero from one.

The same info is in the data pushed on the stack: PSW is 0x87 for the first subtraction (0-1) and 0x12 for the second (1-0). Look for bit position 4, which is exactly AC.

The reason for such 'unintuitive' behaviour is actually simple. Given the adder with two arguments, carry in and carry out, one does subtraction by simply inverting the second (subtrahend) argument and inverting carry that ins and carry that outs as well.

However, as there was no need in i8080 to make DAA after subtractions, the auxiliary carry was cared only for additions and was taken directly from the middle of carry chain in the ALU, without any extra optional inversions.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .