Context:
I’m debugging a regression Failure: gen/ucgbz80/gcc-torture-execute-20050502-1/gcc-torture-execute-20050502-1, which I introduced with [r13045]
I’m on [r13110]
I’ve built the regression tests for sm83. (cd next/sdcc/support/regression && make test-ucgbz80 -j8)
Working directory is next/sdcc/support/regression/gen/ucgbz80/gcc-torture-execute-20050502-1
I’m running ../../../../../sim/ucsim/z80.src/sz80 -tlr35902 ./gcc-torture-execute-20050502-1.ihx
Pasted the commands
set error non-classified off
set error unknown_code off
set error memory off
set error stack off
set hw simif xram 0xbfff
pc 0x100
break 0x04a9
break 0x0510
break 0x05ff
Top of this is from ports/ucgbz80/uCsim.cmd
0x4a9 is where the code changed from
inc sp
inc sp
to
pop af
for throwing away arguments on the stack before returning.
0x0510 and 0x05ff are push af
0> run
Simulation started, PC=0x000100
--- Running: gen/ucgbz80/gcc-torture-execute-20050502-1/gcc-torture-execute-20050502-1
Running testTortureExecute
Stop at 0x0004a9: (104) Breakpoint
ZNHC--- Flags= 0x00 0 . A= 0x00 0 .
00000000
BC= 0xdfbf [BC]= 00 0 . DE= 0x0027 [DE]= 00 0 . HL= 0x04c5 [HL]= 00 0 .
SP= 0xdfb8 [SP]= 01 1 .
0x04a9 F? f1 POP AF
F 0x0004a9
Simulated 20613 ticks (1.864e-03 sec)
Host usage: 0.003423 sec, rate=0.544520
0> next
Stop at 0x0004aa: (109) stepped 10 ticks
ZNHC--- Flags= 0x01 1 . A= 0x00 0 .
00000010
BC= 0xdfbf [BC]= 00 0 . DE= 0x0027 [DE]= 00 0 . HL= 0x04c5 [HL]= 00 0 .
SP= 0xdfba [SP]= 61 97 a
0x04aa ? e9 JP (HL)
F 0x0004aa
Flags get set to 0x01 which is wrong, the lower nibble is always 0.
0> run
Simulation started, PC=0x0004aa
Stop at 0x000510: (104) Breakpoint
ZNHC--- Flags= 0x01 1 . A= 0x01 1 .
00000010
BC= 0xdfba [BC]= 61 97 a DE= 0xdffa [DE]= b1 177 . HL= 0xdffa [HL]= b1 177 .
SP= 0xdfba [SP]= 61 97 a
0x0510 F? f5 PUSH AF
F 0x000510
Simulated 708 ticks (6.402e-05 sec)
Host usage: 0.000114 sec, rate=0.561748
0> next
Stop at 0x000511: (109) stepped 11 ticks
ZNHC--- Flags= 0x01 1 . A= 0x01 1 .
00000010
BC= 0xdfba [BC]= 61 97 a DE= 0xdffa [DE]= b1 177 . HL= 0xdffa [HL]= b1 177 .
SP= 0xdfb8 [SP]= 01 1 .
0x0511 ? cd 32 04 CALL #0x0432
F 0x000511
0> dump xram 0xdfb8 0xdfb9
0xdfb8 01 01 ..
0>
Since the lower nibble aren’t flags, they don’t change and the next push af pushes a wrong number on the stack.
xor a
inc a
push af
Is supposed to push 0x0100
This is probably also what lead to
xor a, a
rra
push af
(push 0x0000)
failing regression test.
I suppose pop af and push af should both &0xf0 the flags.
Now that I think about it, I first tried to also enable that commit for z80, which broke regression tests. So it could be that z80 has similar issues, are the undocumented flags implemented for z80?
Further tests indicate that
malfunctions because the H flag isn’t set properly.
push afanddaaare the only instructions who use that flag.Last edit: Sebastian Riedel 2022-03-03
This is a little test file for Z80. Z80 should have similar flag leakage issues, since it appears to not set the two undocumented flags.
I took the comparison values from Emulicious.
I get different behaviour for:
0x40 vs 0x44
sub aresets overflow flag and sets carry flag.sz80 sets the P/V flag and unsets the carry flag for
rra, but it’s not supposed to touch P/V.https://clrhome.org/table/
0xFFBA vs 0xFF80
0x80 would mean that there is only the sign flag set.
Substract and half carry flag is not set, which might also break
daa.I don’t know if sz80 or Emulicious is wrong on the half carry flag.
And undocumented flags 5 and 3 have to be set to bits 5 and 3 of A.
http://www.z80.info/z80sflag.htm
0xFF7E vs 0xFF56
Undocumented flags 5 and 3 missing.
0x0054 vs 0x0044
According to the opcode table half carry flag always gets set by
andThe same happens for
andon sm83, there half carry should also be set, but isn’t.Ran with
sz80 -tz80 ./z80.ihxandI'm not author of z80 simulator but I'm pretty sure that undocumented flags are not handled. Are they mandatory for sdcc?
I’m undecided. On the one hand it could be abused for optimizations, on the other it seems soviet clones didn’t get the undocumented flags right. But it still feels like the simulator should behave like the original Z80.
https://www.cpushack.com/2021/01/26/the-story-of-the-soviet-z80-processor/
Possible optimizations would be things like
to
I think the best way is to implement them in the simulator, but not to use them in SDCC. Users that really want such optimizations can supply their own peephole rules in addition to the SDCC ones. Similarly to how we do not use the undocumented Z80 instructions in SDCC when targeting the Z80 (where AFAIK some of them do not work in early Zilog NMOS Z80).
Fixed in [r13124].
It seems the bitmask for
pop afgot implemented forpop bc.andnow sets half carry.I didn’t touch the undocumented registers of z80 yet.
Last edit: Sebastian Riedel 2022-03-06
the most accurate description of the z80 is here
http://www.z80.info/zip/z80-documented.pdf
the official zilog manual is sometimes wrong when dealing with flags
all instructions accessing to ixh ixl iyh iyl are safe
I'd like to ask, how z80 undocumented instructions behave on sm83?
They don’t, sm83 isn’t considered being a z80 descendant.
sm83 doesn’t have
DD,FD,ED,DDCB,FDCB.The undocumented instructions in CB are irrelevant, because sm83 has swap there.
sm83 is as far as I know more viewed as 8080 with some z80 extensions (
CBprefix,jr, N-flag) and z80 mnemonics. And some further custom replacements/additions or things completely removed (S-flag, P-flag, exchange). They probably introduced N to get the fixed daa from z80.jpis different from both z80 and 8080 as it is longer when it has to jump.Most instruction cycles could be viewed as being rounded to the next multiple of 4, but
retandcallare significantly slower than on z80 and 8080.But I don’t know 8080 asm, so I don’t know how much that’s really true. And it was never revealed what it was based on.
The flags are different from both: (
Auxiliary Carry andHalf Carry do the same)https://gbdev.io/pandocs/CPU_Comparison_with_Z80.html
Some extensions have similarities to zeropage instructions of 6502, which was used in Nintendo’s last console (NES).
ldh (a8), ais similar tosta a8andld (c), ais a short version ofsta 0,xLast edit: Sebastian Riedel 2022-03-14
No idea, but for sure those involving IXL,IXH,IYL,IYH cannot lead to anything very useful