6

Please tell me about flag changes in 16-bit operations on the MC6800.

I am writing a compiler for the Tiny language for the old MC6800 CPU.

This language handles 16-bit numbers, so there are many 16-bit comparisons. Executing this using only AccAB will make the program longer and slower.

Fortunately, the MC6800 has the X register, so I would like to optimize the program using the results (flag changes) of the CPX/LDX/STX instructions as well.

The N, Z, and V flags are affected by the MC6800 CPX/LDX/STX instructions. As is well known, the only correct result of a 16-bit comparison is the Z flag. N and V only reflect the results of the upper 8-bit comparison.

For this reason, most old programs branched (BEQ or BNE) by looking only at the Z flag.

Even if only the upper 8 bits are compared, there are cases where flag changes can be effectively utilized. If the result of CPX #0 is N=1, then X<0, and if N=0, then X>=0. The same applies to LDX/STX.

(If my understanding is incorrect, I would appreciate it if you could point it out.)

Also, in some MC6800 emulators, the changes in the CCR flag as a result of these instructions are incorrect. The execution results of multiple emulators do not match. This is because the flag changes in MC6800 16-bit comparisons are difficult to understand, making it difficult to implement correctly.

I am looking at M6800 Microprocessor Applications Manual (1975), p.1-19. I also looked at Hitachi's manual, but there is no big difference. In this manual, the N flag change of the CPX instruction is written as follows.

(Bit N) Test: Sign bit of most significant (MS) byte of result = I?

I think it is difficult to understand this is an 8-bit comparison. Of course, this description is different from LDX/STX, so we can guess that something strange is going on.

(Bit N)Test: Result less than zero? (Bit 15 = 1)

I would like a document that clearly explains these differences.

Question: Are there any articles that clearly explain the flag changes of MC6800 CPX/LDX/STX instructions? From what I have found, all the articles use the Z flag. I have not found any that use the remaining N and V flags.

5
  • 5
    What exact opcodes are you talking about, and why would not the CPU programming manual offer a correct description how each instruction works?
    – Justme
    Commented Aug 28 at 5:26
  • 2
    Welcome to SE/Retrocomputing! Please take the tour to learn how this site works, and read "How to Ask". Then come back and edit your question to clarify. What 6800 manual are you using to find out? And why does it not help you? Commented Aug 28 at 5:55
  • I am looking at M6800 Microprocessor Applications Manual (1975). p.1-19. I also looked at Hitachi's manual, but there is no big difference. In this manual, the N flag change of the CPX instruction is written as follows. "(Bit N) Test: Sign bit of most significant (MS) byte of result = I?" I think it is difficult to understand this is an 8-bit comparison. Of course, this description is different from LDX/STX, so we can guess that something strange is going on. "(Bit N)Test: Result less than zero? (Bit 15 = 1)" I would like a document that clearly explains these differences.
    – zu2
    Commented Aug 28 at 6:04
  • 3
    Please edit your question to add new information, I have done this for you now. You might also want to add the URLs of the mentioned manuals. Commented Aug 28 at 7:41
  • 1
    To clarify that I've understood the problem correctly: comparing 0 and 1 would give the same flags as comparing 1 and 0, because there is no carry from the bottom byte to the top byte, both top bytes are zero, so N and V are unset in either case? Commented Aug 29 at 6:31

3 Answers 3

10

A quick web research revealed the Motorola "M6800 PROGRAMMING REFERENCE MANUAL" at the Internet Archive.

For CPX it says:

Condition codes for CPX

That leaves little to be desired.

Just for completeness, for LDX it says:

Condition codes for LDX

And for STX it says:

Condition codes for STX

8
  • 4
    This is the answer I was looking for, thank you very much.
    – zu2
    Commented Aug 28 at 8:33
  • 1
    @zu2 If you had taken the tour, you would have noticed that "thank you" comments are frowned upon. :-D Please mark the answer as "accepted" that fits you best, and you may want to upvote if you think it is useful. This site is not a forum. Questions with marked answers stand out in the list of search results for other visitors to quickly find solutions. Commented Aug 28 at 8:39
  • Note that this only applies to the old M6800, not the newer M6801 or clones of it like the Hitachi HD6303 series which use real 16-bit arithmetic.
    – Justme
    Commented Aug 28 at 9:39
  • 5
    @thebusybee Whilst you are correct about accepting the answer, admonishment for a thank you comment isn't necessary.
    – JeremyP
    Commented Aug 28 at 11:23
  • @Justme See the question: "for the old MC6800 CPU", however your note is helpful for other cases. Commented Aug 28 at 12:17
6

You may find it confusing, because different MCUs do it differently.

The old M6800 MCUs do it as two unrelated 8-bit operations, but newer M6801 MCUs do it as a real 16-bit operation, and so do the Hitachi HD6303 MCUs that base on M6801.

The M6800 programming manuals explain the logic operations for the flag bits. I do not think they are so mysterious like you claim. I have never bothered to think that the N and V flags would be somewhat weird, and a emulator I quickly implemented has run all the 6303 code so far (which isn't much).

But it does appear that only Z bit is valid for the whole comparison operation if both high and low bytes are.

The N and V bits are updated, but not from the comparison of the whole 16-bit operation, but only from the last 8-bit compare operation result between the two high bytes.

So there is no carry between high and low bytes. Which is why the Programmer's Reference Manual of M6800 says are not intended for conditional branching, as in the general case they are not doing what you expect.

So CPX can't be used to compare if value $1234 in register X is larger or smaller than value $1233 in memory. You can know they are not equal (Z=0), the high bytes compared are not negative (N=0), and result had no overflow (V=0). C flag is not affected.

But in your case, using CPX #0, indeed the N flag only copies the MSB of the subtraction result, which must be the high byte of register X itself, to the N flag. So I believe you can use CPX #0 that for testing if X is currently holding a negative or non-negative 16-bit integer.

LDX and STX will set Z correctly from the 16-bit value, and N is the most significant bit of high byte as expected, so it can be used to check if value stored or loaded is negative or non-negative. V is set to 0 always.

However the Hitachi HD6303 manual does not explicitly tell how the comparison result is calculated, just how the result sets the flags, and that CPX affects the C flag too. Based on this documentation, I would expect there is a real 16-bit subtraction between X register and the 16-bit data in memory, not two separate 8-bit comparisons.

And the reason for that, is that the Hitachi HD6303 is based on M6801, not M6800.

Therefore, only the M6800 uses the separate comparison of two bytes. In the M6801 data sheet, it is said that it has many improvements, including the usage of CPX as a real 16-bit comparison opcode.

So if you want to generate code for different MCUs that utilize the CPX or other improved Motorola additions or the even further improvements made by Hitachi to it's full extent, you need to support generating code for different CPUs in the 6800 family.

4

While I myself has very little knowledge of MC6800, I can recommend using this netlist-level emulator http://visual6502.org/JSSim/expert-6800.html as the ultimate reference. It emulates real transistor-based reverse-engineered 6800 CPU.

1
  • So is that the original 6800, or the improved 6801? Specifically the CPX works differently.
    – Justme
    Commented Aug 28 at 9:37

You must log in to answer this question.

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