Open skiselev opened 3 months ago
What clock rate have you used in your tests? maybe it could have some effect on YF and XF?
Some of the flags behavior tested by Z80_XCF_Flavor is incorrect, incomplete, or redundant. It is quite possible that the reported results are bogus.
More specifically:
The behavior as it documented for NEC NMOS and ST CMOS seems to be incorrect. I get a different behavior:
NEC NMOS - very similar to Zilog, although, in certain conditions that are not thoroughly tested by your utility, it produces a non-deterministic result when setting XF in the case where A = 0 and XF = 1 prior to executing SCF/CCF. It is possible that other bits, static charges, silicon manufacturing process, the phase of the moon, etc. affect the result in this case
The following 3 results from real hardware reveal that NEC NMOS CPUs take YF and XF from A, at least on the CPUs tested (we have tested a few more):
You can compare the CRCs against the logs obtained emulating a NEC NMOS:
- ST CMOS - sets YF = 0 and XF = 1 in Q0_F0_A1 test case. As a matter of the fact, most CMOS CPUs do that, with only exception being NEC CMOS CPUs, that have some randomness in setting the XF here
Interesting. According to our testing, ST CMOS behaves as Zilog:
z80ccfscr.tap
(see patterns here):
We have tested x3 ST Z84C00AB6 from this set:
Interestingly, at least this model of ST CMOS has the IFF2 bug in ld a,{i|r}
characteristic of the Zilog NMOS:
- It doesn't make sense to include tests with the same deterministic results, that are the same on all CPUs. That is all tests where SCF or CCF instruction is executed after executing an ALU instruction
- Q0_F0_A0 - always sets YF = 0 and XF = 0
- Q1_F1_A0 - always sets YF = 0 and XF = 0
- Q0_F1_A1 - always sets YF = 1 and XF = 1 - although in this case SCF/CCF follow a NOP instruction, the fact that all of the relevant bits - FLAGS.5, FLAGS.3, A.5, and A.3 are set to 1 always seem to result in YF = 1 and XF = 1
- Q1_F1_A1 - always sets YF = 1 and XF = 1
It makes sense if you want to find new behaviors. The test includes all possible combinations of Q, F and A so that people test their CPUs and we can see whether or not there are any surprises.
- This leaves only two interesting test cases Q0_F1_A0 and Q0_F0_A1.
- These tests actually seem to ignore the "Q" part of the equation, and the final result is CPU dependent
- Moreover, not all CPUs produce a reliable result in this (or similar) cases, where an SCF or CCF instruction follows an instruction that doesn't set FLAGS.
We have learned that the behavior is unstable. Ped7g wrote a test to detect and visualize the instability:
Red squares indicate that unstable behavior has been detected.
You can also use z80ccfscr.tap
(included in Patrik Rak's Zilog Z80 CPU Test Suite) to visualize the flag behavior of ccf/scf
and its instability. The unstable behavior makes pixels blink here and there. There are videos in the link above, for example the following ones from 2 NEC CPUs:
I tried to document my findings here. These findings are based on my testing of about 20 real CPUs of different types
Thank you for sharing your findings, I will study them carefully.
My friend Marta Sevillano, author of SpecIde, has been kind enough to run the test on two of her machines with NEC NMOS CPU (more info here), confirming that the test works correctly:
Thanks to ZjoyKiLer for pointing me at this thread.
Back in 2018 when I working on the Z80Decoder and was looking at the X/Y flags after CCF, this was the ST CMOS Z80 I was using:
(I was testing in a Spectrum +2B)
The current version of XCF Flavour does not recognise this processor:
Here's the Q0_F1_A1 test case, where Y ends up as 0 rather than 1:
8035 : AF : XOR A : A=00 F= Z V BC=8126 DE=0081 HL=82AF IX=83BB IY=5C3A SP=7FE8
8036 : 3E FF : LD A,FFh : A=FF F= Z V BC=8126 DE=0081 HL=82AF IX=83BB IY=5C3A SP=7FE8
8038 : 3F : CCF : A=FF F= Z XV C BC=8126 DE=0081 HL=82AF IX=83BB IY=5C3A SP=7FE8
8039 : CD E4 80 : CALL 80E4h : A=FF F= Z XV C BC=8126 DE=0081 HL=82AF IX=83BB IY=5C3A SP=7FE6
80E4 : F5 : PUSH AF : A=FF F= Z XV C BC=8126 DE=0081 HL=82AF IX=83BB IY=5C3A SP=7FE4
80E5 : D1 : POP DE : A=FF F= Z XV C BC=8126 DE=FF4D HL=82AF IX=83BB IY=5C3A SP=7FE6
80E6 : 7B : LD A,E : A=4D F= Z XV C BC=8126 DE=FF4D HL=82AF IX=83BB IY=5C3A SP=7FE6
80E7 : E6 28 : AND 28h : A=08 F= HX BC=8126 DE=FF4D HL=82AF IX=83BB IY=5C3A SP=7FE6
80E9 : 02 : LD (BC),A : A=08 F= HX BC=8126 DE=FF4D HL=82AF IX=83BB IY=5C3A SP=7FE6
80EA : 03 : INC BC : A=08 F= HX BC=8127 DE=FF4D HL=82AF IX=83BB IY=5C3A SP=7FE6
80EB : C9 : RET : A=08 F= HX BC=8127 DE=FF4D HL=82AF IX=83BB IY=5C3A SP=7FE8
My Z80 decoder actually tracks this case without any errors.
The code that is using is here:
case CPU_CMOS:
if (reg_a >= 0 && reg_q >= 0) {
if (reg_q) {
new_flag_f5 = (reg_a >> 5) & 1;
} else {
new_flag_f5 = flag_f5;
}
new_flag_f3 = (reg_a >> 3) & 1;
}
break;
}
Unfortunately, in 2018 when I transcribed this to my wiki page I made an error:
And with the ST CMOS Z80 it is:
XF = A.3
if <previous instruction modified the flags> then
YF = A.5
else
YF = YF | A.5
endif
The correct version (which matches the code) is:
And with the ST CMOS Z80 it is:
XF = A.3
if <previous instruction modified the flags> then
YF = A.5
else
YF = YF (i.e. unchanged)
endif
I've just run the latest version of Partick Rak's Z80CCF on this ST CMOS Z80. There are 371,743 individual test cases in this test. By test case, I mean CCF preceeded by some other instruction/state. My Z80Decoder fails to correctly calculate the CCF X/Y flags in 391 of these. The failing ones are:
LD A,00h
LD A,01h
LD A,02h
LD A,04h
LD A,40h
LD A,80h
LD I,A
LD R,A
OUT (FEh),A
POP AF
RES 3,A
RES 4,(IX+0),A
RES 4,(IX+1),A
RES 4,(IY+0),A
RES 4,(IY+1),A
RES 5,A
RES 5,(IX+0),A
RES 5,(IY+0),A
It may be the these cases are yielding unstable behaviour. I'll try to investigate this further over the next few days.
Dave
@hoglet67 Interesting... BTW, we have learned that 128K Amstrad machines with gate array produce more unstable behavior than 48K Sinclair machines with ULA. One of my theories is that the clock rate could be affecting the flags somehow (the shorter the clock signal, the more unstable the behavior?).
Thank you very much for testing this.
I have found another ST CMOS model in my inventory. I'm going to build a ZX Spectrum issue 3B to test it.
@hoglet67 please try this new version of the test when you have some time:
That now correctly detects the ST CMOS CPU
@hoglet67 please try this new version of the test when you have some time:
That now correctly detects the ST CMOS CPU
Great!
I've added the correct behavior to my emulator. And I've generated logs (emulating a ST CMOS) for v1.2a of Patrik's test suite, so that you can compare the CRC errors against yours: z80test-1.2a-log.txt
Here's the output from two successive run's of Patrick's Z80 CCF test (v1.2a) on a Spectrum +2B with a ST CMOS Z80: rak_z80ccf_run5_st_cmos_12.txt rak_z80ccf_run6_st_cmos_12.txt This looks is very different from your emulator.
What's interesting is the CRCs are not consistent between the two runs in the following tests:
104 OUT (N),A
126 POP+PUSH AF
154 LD I,A
155 LD R,A
These unstable tests are a sub-set of the cases where my Z80Decoder is failing to correctly calculate Y/Z after a SCF/CCF. Here's that list, posted earlier.
LD A,00h
LD A,01h
LD A,02h
LD A,04h
LD A,40h
LD A,80h
LD I,A
LD R,A
OUT (FEh),A
POP AF
RES 3,A
RES 4,(IX+0),A
RES 4,(IX+1),A
RES 4,(IY+0),A
RES 4,(IY+1),A
RES 5,A
RES 5,(IX+0),A
RES 5,(IY+0),A
I need to gather a bit more data.
Am I the only person running Patrik's CCF tests on a ST CMOS Z80 on real hardware, or do you know of other reports?
I need to gather a bit more data.
Am I the only person running Patrik's CCF tests on a ST CMOS Z80 on real hardware, or do you know of other reports?
No sorry, I don't know of anyone else who is concerned about this issue or testing the ST CMOS :(
I've corrected my emulation and now it almost matches your results, but these are different:
Yours:
080 RES N,A FAILED
CRC:830398A2 Expected:7675BFCF
082 RES N,[R,(HL)] FAILED
CRC:10883532 Expected:86080FA1
084 RES N,(XY),R FAILED
CRC:39FDE2E2 Expected:43588B31
104 OUT (N),A FAILED
CRC:17B22460 Expected:04270B9E [run 5]
CRC:A901B1D3 Expected:04270B9E [run 6]
126 POP+PUSH AF FAILED
CRC:192E2E97 Expected:4D06617F [run 5]
CRC:46C18F24 Expected:4D06617F [run 6]
137 LD [R,(HL)],N FAILED
CRC:88F038F7 Expected:8BD6D3CD
154 LD I,A FAILED
CRC:4D95C443 Expected:04270B9E [run 5]
CRC:D44BE357 Expected:04270B9E [run 6]
155 LD R,A FAILED
CRC:409B7E34 Expected:04270B9E [run 5]
CRC:351B28EC Expected:04270B9E [run 6]
Mine: z80ccf-log.txt
080 RES N,A FAILED
CRC:A9B9B486 Expected:7675BFCF
082 RES N,[R,(HL)] FAILED
CRC:42EF9D65 Expected:86080FA1
084 RES N,(XY),R FAILED
CRC:BB2CBF15 Expected:43588B31
104 OUT (N),A FAILED
CRC:8496982B Expected:04270B9E
126 POP+PUSH AF FAILED
CRC:77C40310 Expected:4D06617F
137 LD [R,(HL)],N FAILED
CRC:1CC50D48 Expected:8BD6D3CD
154 LD I,A FAILED
CRC:8496982B Expected:04270B9E
155 LD R,A FAILED
CRC:8496982B Expected:04270B9E
OUT (N),A
, POP+PUSH AF
, LD I,A
and LD R,A
are obviously being affected by the unstable behavior.
What's interesting is the CRCs are not consistent between the two runs in the following tests:
104 OUT (N),A 126 POP+PUSH AF 154 LD I,A 155 LD R,A
Perhaps running the test many times would get those to match my CRCs?
What's interesting is the CRCs are not consistent between the two runs in the following tests:
104 OUT (N),A 126 POP+PUSH AF 154 LD I,A 155 LD R,A
In these results from a NEC NMOS, 126 POP+PUSH AF
and 154 LD I,A
are producing an unexpected CRC error in z80ccf.tap
(others do not match either, but many do):
https://github.com/redcode/Z80/wiki/Zilog-Z80-CPU-Test-Suite#v12-nec-d780c-1--zx-spectrum-48k-issue-3-ula-6c001e-6
And in these another results, only 126 POP+PUSH AF
is producing an unexpected CRC error:
https://github.com/redcode/Z80/wiki/Zilog-Z80-CPU-Test-Suite#v12-nec-d780c-1--zx-spectrum--es-issue-6a
It seems that at least stack instructions and ld i,a
(and possibly ld r,a
) are very prone to produce unstable behavior during a subsequent ccf/scf
.
The reference values for NEC NMOS are here.
Your NEC NMOS results are interesting... that's definitely not what I am seeing. Are you 100% sure you're testing NEC NMOS Z80 CPUs - that is D780C and not NEC CMOS Z80 CPUs - D70008AC? Because your results would be consistent with the results I am seeing on the latter.
I tested 3 NEC NMOS ICs, and 3 NEC CMOS ICs...
Most definitely when I run your tests on NEC NMOS CPUs they behave exactly as Zilog Z80 - either CMOS or NMOS...
With that being said, two of my NEC NMOS Z80, do have some randomness in YF/XF after executing SCF result, when I go over all 2^16 possible values of FLAGS and A.
Attached is the code, based on your tests, that I use for testing: z80xcf.txt
Output: NEC D780C - 8401XD (NMOS)
A>z80xcf
Z80 SCF/CCF Test (C) 2024 Sergey Kiselev
XF/YF flags test: 0000FFFF0000FFFFFFFFFFFF80808077
Output: NEC D780C-1 - 8220X5 (NMOS)
A>z80xcf
Z80 SCF/CCF Test (C) 2024 Sergey Kiselev
XF/YF flags test: 0000FFFF0000FFFFFFFFFFFF80808080
Output: NEC D70008AC-6 - 8648LX (CMOS)
B>z80xcf
Z80 SCF/CCF Test (C) 2024 Sergey Kiselev
XF/YF flags test: 00000000000000FFFFFFFFFF007E4003
I am running my CPUs at 3.6864 MHz. I can also test them at 1.8432 MHz, or 8 MHz (probably too high for NEC NMOS).
Your NEC NMOS results are interesting... that's definitely not what I am seeing. Are you 100% sure you're testing NEC NMOS Z80 CPUs - that is D780C and not NEC CMOS Z80 CPUs - D70008AC? Because your results would be consistent with the results I am seeing on the latter.
I'm 1000,000,000% sure. This is one of the 2 chips tested by Marta:
I am running my CPUs at 3.6864 MHz. I can also test them at 1.8432 MHz, or 8 MHz (probably too high for NEC NMOS).
It would be a good idea to test the CPUs at these two speeds, maybe we will get some surprises, who knows...
More results (a bit old) from a Russian friend who tried time ago a beta of the test on East German and Soviet Z80 clones. Interestingly, both CPUs exhibit the old (now incorrect) ST behavior specified by @hoglet67. The testing machine was a Profi, and the CPU was running at 3.5 MHz.
MME, I don't know exactly the model, possibly the 80A-CPU in the photo:
Soviet T34VM1:
That's extremely weird. Is it possible that the MEMPTR or similar undocumented internal state / registers affect the outcome? In my SCF/CCF tests, MME U880 behaves exactly like Zilog Z80. (There is a difference in OUTI instruction, though)
That's extremely weird. Is it possible that the MEMPTR or similar undocumented internal state / registers affect the outcome? In my SCF/CCF tests, MME U880 behaves exactly like Zilog Z80. (There is a difference in OUTI instruction, though)
It could. There are several MME models and there may be differences between them. Some are similar or even have the same die as some Soviet clones; others are different from them.
BTW, I have many Soviet and East German models and will test them soon.
I have more results from a 80A-CPU:
Some tests fail in the flags section, specifically BIT n,(HL)
, which depends on MEMPTR. However, the CPU surprisingly passes all tests from the MEMPTR section:
Take a look at my Z80 test collection. There are real hardware results for several models. I also maintain another collection of ZX Spectrum tests.
You might find this new data interesting: https://github.com/hoglet67/Z80Decoder/wiki/Unstable-CCF-SCF-Behaviour
Sorry there is quite a lot there to digest. I need to have a go at summarizing this.
You might find this new data interesting: https://github.com/hoglet67/Z80Decoder/wiki/Unstable-CCF-SCF-Behaviour
Sorry there is quite a lot there to digest. I need to have a go at summarizing this.
Grat job Dave!
For my part, I will test another ST Z84C00HB6 like yours soon to confirm that the detected behavior is not an aberration of that particular unit, but is typical of at least that model. I will also check other ST CMOS models I have in my inventory, as well as Soviet and East German clones, which seemed to exhibit the "old" ST behavior.
It is possible that there are several versions of the ST CMOS die. If you can, please check if your CMOS ST has the IFF2 bug, which causes the P/V flag to reset when a maskable interrupt is accepted during the execution of the ld a,{i|r}
instructions, and also if the instruction out (c),0
behaves as out (c),255
. The ST CMOS Z84C00AB6 we checked time ago had these two bugs and, as I mentioned in a previous comment, exhibited the ccf/scf
behavior of Zilog models.
IFF2 bug tester for 128K machines (like your ZX Spectrum +2B): https://github.com/redcode/Z80/wiki/IFF2-Bug-128K IFF2 bug tester for 48K machines: https://github.com/redcode/Z80/wiki/IFF2-Bug
out (c),255
tester: https://github.com/redcode/Z80/wiki/Z80-INT-Skip
out (c),0
(black border):
out (c),255
bug (white border):
If you can, please check if your CMOS ST has the IFF2 bug, which causes the P/V flag to reset when a maskable interrupt is accepted during the execution of the
ld a,{i|r}
instructions, and also if the instructionout (c),0
behaves asout (c),255
.
Here you go:
Sorry for the poor quality; I must get my RGBtoHDMI setup!
Dave
@hoglet67 Thank you for testing it so quickly.
These results seem to confirm that yes, ST CMOS models have both bugs.
Regarding your tests of the unstable flag behavior of ccf/scf
, the most explosive findings seem to be:
Two questions are now open:
~((Q ^ F) | A)
, doesn't it?I just remembered some comments that a friend of mine read on a forum some time ago (I don't have the URL, sorry):
По zilog nmos сразу могу сказать, что в тестах раксофт очень много не совпадений crc! Пробовал пока только три разных проца (писал выше) Они точно все не с Китая! Буду пробовать ещё другие процы (их только повыпаивать нужно из всяких АОНов и прочего :)
Translation:
On Zilog NMOS I can immediately say that in raxoft tests there are a lot of CRC mismatches! > I tried so far only three different processors (wrote above) They are definitely not all from China! I will try more other processors (they only need to be soldered out of all kinds of AONs and other things :).
- What is the quasi-stable behavior of NEC at 6 MHz? It looks like
~((Q ^ F) | A)
, doesn't it?
The behaviour seems to be tending towards:
if <previous instruction modified the flags> then
XF = A.3
YF = A.5
else
XF = XF & A.3
YF = YF & A.5
endif
I'm not sure it's possible to write that using the Q notation.
- Could your Zilog NMOS 8811 be fake (i.e., a remarked CPU)? It is very strange that, being the exact same model as the 8644, it presents such a clearly different behavior. If it is not a remarked CPU, perhaps the manufacturing process was improved and this corrected, so to speak, the "leakage" of Q?
I don't think it's likely to have been remarked, as I got it in a job lot of computer chips from a radio rally about 10 years ago. All of the chips appear to be original.
I've got an NEC CMOS Z80 on order to test as well.
I don't think it's likely to have been remarked, as I got it in a job lot of computer chips from a radio rally about 10 years ago. All of the chips appear to be original.
Actually, after a bit more researchm the Zilog NMOS 8810 date code part was I think the original CPU in my Spectrum +2B. There is an identical one in a photo here: https://upload.wikimedia.org/wikipedia/commons/b/bb/Sinclair_ZX_Spectrum_%2B2B_Z70833_Issue_1_Motherboard.jpg
Actually, after a bit more researchm the Zilog NMOS 8810 date code part was I think the original CPU in my Spectrum +2B. There is an identical one in a photo here: https://upload.wikimedia.org/wikipedia/commons/b/bb/Sinclair_ZX_Spectrum_%2B2B_Z70833_Issue_1_Motherboard.jpg
OK, that seems conclusive. Besides, I have found evidence from another colleague of mine showing two Zilog processors with NEC behavior. I thought they would be remarked, but it looks like I was wrong.
Both are the same model as yours: Z0840004PSC
Ignore the test on the left, the failures (in red) were caused by certain instabilities in the I/O values of the test machine and because the turbo was enabled, so the interrupt did not occur at the correct time to be able to break the loop of the block instruction under test.
Results are in for the NEC CMOS processor, and it's also an unstable one, but quite different to the others: https://github.com/hoglet67/Z80Decoder/wiki/Results-NEC-CMOS
Results are in for the NEC CMOS processor, and it's also an unstable one, but quite different to the others: https://github.com/hoglet67/Z80Decoder/wiki/Results-NEC-CMOS
Oh, this one is amazing! in addition to being different, the instability of YF seems almost deterministic. Almost, not quite.
Thank you for all the fantastic work you are doing.
BTW @hoglet67, could you also check your NEC CMOS for the ld a,{i|r}
and out (c),255
bugs?
Yes of course, I can do that tomorrow.
Here are the various test results of the NEC CMOS Z80 in a Spectrum +2B:
The x80ccfscr is showing unstable behaviour, with some dots flickering.
I don't have a Kempton Joystick interface, which I think is needed for the block flag tests.
Thank you very much for checking it. It's confirmed that as far as those 2 bugs are concerned, it behaves the same as the Zilog CMOS.
Some of the flags behavior tested by Z80_XCF_Flavor is incorrect, incomplete, or redundant. It is quite possible that the reported results are bogus.
More specifically:
I tried to document my findings here. These findings are based on my testing of about 20 real CPUs of different types