22

The Z80 is "binary compatible" with the 8080. It adds a bunch of new instructions, but places them all in unused (well, undocumented) opcodes.

Does this mean that if I disassemble an 8080 program (which doesn't use any undocumented opcodes, naturally) using a Z80 disassembler, will the result be correct 8080 assembly code? Or are there any hidden gotchas?

The reason I'm asking is because Supersoft Associates' CPU Diagnostics II program from 1981 contains both 8080 and Z80 code; it checks which CPU it's running on in the beginning, jumping to CPU-specific testing code. Therefore I obviously need to disassemble it using a Z80 disassembler. Will the 8080 tests be valid 8080 assembly code?

4
  • Speaking rigorously, Z80 is NOT binary compatible with 8080. It has different flags (P/V instead of just 'parity', a bunch of some new ones and even two unused/undocumented bits in flag register) which is enough to say there's no (strict) binary compatibility.
    – lvd
    Oct 4, 2021 at 21:06
  • @lvd You're saying that the Z80 doesn't execute 8080 instructions identically to a stock 8080? Does the P/V flag operate differently from the P flag when executing just 8080 instructions? Do you have a reference documenting the differences between 8080 instructions run on an 8080 and a Z80? Oct 4, 2021 at 22:56
  • @WillHartung yes this is exactly what I'm saying. P flag in 8080 is always a parity flag, while in Z80 it is overflow flag during additions/subtractions.
    – lvd
    Oct 5, 2021 at 15:35
  • Z80 also has more flags in F, so the data pushed after other opcodes in OP: PUSH AF will differ. The last difference is that POP AF:PUSH AF in Z80 will preserve TOS completely, which is not the case for 8080.
    – lvd
    Oct 5, 2021 at 15:37

2 Answers 2

21

The Z80 is "binary compatible" with the 8080. It adds a bunch of new instructions, but places them all in unused (well, undocumented) opcodes.

yes .. err, no, they placed them on redundant opcodes.

For example the whole 00-xxx-000 group were NOP instructions for the 8080, while Zilog only left 00h as NOP, while the others became jumps (and EX). Likewise the 'alternate' opcodes CBh/DDh/EDh/FDh that all produced JMP and CALL on the 8080 became prefix bytes (*1).

Does this mean that if I disassemble an 8080 program (which doesn't use any undocumented opcodes, naturally) using a Z80 disassembler, will the result be correct 8080 assembly code? Or are there any hidden gotchas?

No hidden gotchas, but then again, it will come out as Z80 assembly, not 8080, as the Zilog changed the words of the assembly language. For example:

Opcodes      8080        Z80            (8008       )
79           MOV  A,C    LD A,C         (C2 LAC     )
02           STAX B      LD (BC),A      (--         )
16           MVI  D,12h  LD D,12h       (1E LDI  12h)
3A 34 12     LDA  1234h  LD A,(1234h)   (--         ) 
ED 4B 34 12  --          LD BC,(1234h)  (--         )  

So essentially it will produce an all Z80 Assembly source code (Z80 column), but certain operations are not used in 8080 sections.

The reason I'm asking is because Supersoft Associates' CPU Diagnostics II program from 1981 contains both 8080 and Z80 code; it checks which CPU it's running on in the beginning, jumping to CPU-specific testing code. Therefore I obviously need to disassemble it using a Z80 disassembler. Will the 8080 tests be valid 8080 assembly code?

It must. After all, on binary level all 8080 is as well valid Z80. Only on Assembler the above mentioned different 'spelling' is visible - think of it like Mancunian English vs. Texan English.


*1 - I understand that the A zeroing opcodes (SUB A/XRA A) haven't been touched, because some used them. Likewise, to a lesser extend, the 'flagging' NOPs ANA A, ORA A and CMP A (*2). But I always found it strange why they didn't touch the MOV-NOPs (*3) which would have brought 7 additional opcodes.

They would relieve plenty of room from the 8080 code set. Especially since the prefixes take away much of the advantage of many of the 16 bit opcodes.

The only reason I can think of is that Mr. Faggin somehow knew (*4) that the 8085 would as well not touch any of these opcodes, so the level of incompatibility between Z80 and 8080 would be about the same as Intel introduced with the 8085

*2 - All of them do trigger flags, so while the result is forseable, it may be used on purpose to prepare some flag.

*3 - 7Fh/40h/49h/etc. are MOV A,A, MOV B,B, MOV C,C ... they move data between the same register, thus making it effectively as well NOPs since MOVs don't trigger any flags.

*4 - Since both (Z80, 8085) were launched in March 1976, it's not very likely that this was without early knowledge of the changes Intel did.

9
  • 1
    "I always found it strange why they didn't touch the MOV-NOPs (*2) which would have brought 7 additional opcodes." - perhaps because it would have made the (not micro-coded) instruction decoder more complex for little benefit (only a few extra instructions created, prefixes would still have been needed). May 19, 2020 at 9:09
  • 1
    Thanks a lot for the great answer. Were the "redundant" 8080 opcodes that Zilog chose to repurpose not undocumented initially? If so, wouldn't that mean it's not binary compatible? If the opcodes were official but reduntant (which is how I'm interpreting your correction of my statement), surely people would have been expected to use them. I guess I can just look up an 8080 manual to check how they were presented.
    – tobiasvl
    May 19, 2020 at 19:41
  • 1
    @tobiasvl Only 00h was named as NOP, but there areaswell Intel documentation calling all of the 00-xxx-000 series as NOP. Much like they did with the 'illegal' CALLs. Or in other words, usage was not encuraged.
    – Raffzahn
    May 19, 2020 at 19:59
  • 1
    It's a shame the Z80 tried to squeeze all of the IX/IY functionality into one prefix for each, rather than repurposing some "redundant move NOPs". Having separate prefixes for instructions with and without displacements could not only have saved one byte and eight cycles off the cost of each no-displacement instruction, but it could also have saved four cycles off the cost of each instruction that had a displacement by allowing computation of the displacement to overlap the fetch of the "main" opcode.
    – supercat
    Oct 4, 2021 at 21:21
  • 1
    @TobySpeight Not really. All the Intel originated syntax (including Zilog) are based on the Datapoint dest,src structure. Just instruction names changed Datapoint 2200 LAC (Load A with C) stayed LAC with 8008, became MOV A,C with the straightened 8080 mnemonics just to be turned LD A,C with the Z80 - kind of going back to the origins. Maybe see this answer as well.
    – Raffzahn
    Oct 5, 2021 at 12:41
1

Will the 8080 tests be valid 8080 assembly code?

Only if they do not contain any undocumented 8080 opcodes, they will remain valid after Z80 disassembler.

You must log in to answer this question.

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