In the last day or two I've been focusing on testing.

I've been able to run

Patrick Rak's emulator test suite on my Spectrum +2 and capture a trace of the results:

- this includes 152 test cases

- test takes 5-6 minutes to run and produces a 2.24GB capture file

- Z80 Decode takes 7-8 minutes to run and produces a 24.3GB output file

Here's a list of the test cases:

Code: Select all

```
1 SELF TEST
2 SCF
3 CCF
4 SCF+CCF
5 CCF+SCF
6 DAA
7 CPL
8 NEG
9 NEG'
10 ADD A,N
11 ADC A,N
12 SUB A,N
13 SBC A,N
14 AND N
15 XOR N
16 OR N
17 CP N
18 ALO A,A
19 ALO A,[B,C]
20 ALO A,[D,E]
21 ALO A,[H,L]
22 ALO A,(HL)
23 ALO A,[HX,LX]
24 ALO A,[HY,LY]
25 ALO A,(XY)
26 RLCA
27 RRCA
28 RLA
29 RRA
30 RLD
31 RRD
32 RLC A
33 RRC A
34 RL A
35 RR A
36 SLA A
37 SRA A
38 SLIA A
39 SRL A
40 RLC [R,(HL)]
41 RRC [R,(HL)]
42 RL [R,(HL)]
43 RR [R,(HL)]
44 SLA [R,(HL)]
45 SRA [R,(HL)]
46 SLIA [R,(HL)]
47 SRL [R,(HL)]
48 SRO (XY)
49 SRO (XY),R
50 INC A
51 DEC A
52 INC [R,(HL)]
53 DEC [R,(HL)]
54 INC X
55 DEC X
56 INC (XY)
57 DEC (XY)
58 INC RR
59 DEC RR
60 INC XY
61 DEC XY
62 ADD HL,RR
63 ADD IX,RR
64 ADD IY,RR
65 ADC HL,RR
66 SBC HL,RR
67 BIT N,A
68 BIT N,(HL)
69 BIT N,[R,(HL)]
70 BIT N,(XY)
71 BIT N,(XY),-
72 SET N,A
73 SET N,(HL)
74 SET N,[R,(HL)]
75 SET N,(XY)
76 SET N,(XY),R
77 RES N,A
78 RES N,(HL)
79 RES N,[R,(HL)]
80 RES N,(XY)
81 RES N,(XY),R
82 LDI
83 LDD
84 LDIR
85 LDDR
86 CPI
87 CPD
88 CPIR
89 CPDR
90 IN A,(N)
91 IN R,(C)
92 IN (C)
93 INI
94 IND
95 INIR
96 INDR
97 OUT (N),A
98 OUT (C),R
99 OUT (C),0
100 OUTI
101 OUTD
102 OTIR
103 OTDR
104 JP NN
105 JP CC,NN
106 JP (HL)
107 JP (XY)
108 JR N
109 JR CC,N
110 DJNZ N
111 CALL NN
112 CALL CC,NN
113 RET
114 RET CC
115 RETN
116 RETI
117 RETI/RETN
118 PUSH+POP RR
119 POP+PUSH AF
120 PUSH+POP XY
121 EX DE,HL
122 EX AF,AF'
123 EXX
124 EX (SP),HL
125 EX (SP),XY
126 LD [R,(HL)],[R,(HL)]
127 LD [X,(XY)],[X,(XY)]
128 LD R,(XY)
129 LD (XY),R
130 LD [R,(HL)],N
131 LD X,N
132 LD (XY),N
133 LD A,([BC,DE])
134 LD ([BC,DE]),A
135 LD A,(NN)
136 LD (NN),A
137 LD RR,NN
138 LD XY,NN
139 LD HL,(NN)
140 LD XY,(NN)
141 LD RR,(NN)
142 LD (NN),HL
143 LD (NN),XY
144 LD (NN),RR
145 LD SP,HL
146 LD SP,XY
147 LD I,A
148 LD R,A
149 LD A,I
150 LD A,R
151 EI+DI
152 IM N
```

After fixing a few bugs, I'm now able to decode this trace without any failures being flagged by my Z80 emulation code.

So I'm pretty happy now that the emulation is in good shape.

There are just two cases I know of now where I'm not able to predict the correct values for the undocumented F5/F3 flags (a.k.a. YF and XF):

- following SCF (Set carry) or CCF (Complement carry)

- following LDIR (and probably LDDR/LDI/LDD)

The first case (with SCF/CCF) I understand. It turns out the setting of the undocumented F5/F3 flags in SCF and CCF actually depends on whether the preceding instruction modified the flags or not. This is described in

this post. I don't see any problem in implementing this, I just haven't done so yet,

The second case (with LDIR) has me very confused. It seems that the current understanding is that F5 and F3 flags take on bits 1 and 3 of (data + A). I'm doing this, and still seeing errors.

Code: Select all

```
FETCH 0 0 1 0 1 1 1 0 ed *
FETCH 0 0 1 0 1 1 1 0 b0 *
MEMRD 1 0 1 0 1 1 1 0 38 * : Rd=38
MEMWR 1 1 0 0 1 1 1 0 38 * : Wd=38
0E82 : ED B0 : LDIR : 21/ 0 : A=38 F= Z0 0V BC=00B0 DE=5A50 HL=5A4F IX=F7FF IY=5C3A SP=FF50
FETCH 0 0 1 0 1 1 1 0 ed *
FETCH 0 0 1 0 1 1 1 0 b0 *
MEMRD 1 0 1 0 1 1 1 0 38 * : Rd=38
MEMWR 1 1 0 0 1 1 1 0 38 * : Wd=38
0E82 : ED B0 : LDIR : 23/ 0 : A=38 F= Z0 0V BC=00AF DE=5A51 HL=5A50 IX=F7FF IY=5C3A SP=FF50
INTACK 0 1 1 1 0 1 1 0 ff *
MEMWR 1 1 0 0 1 1 1 0 0e *
MEMWR 1 1 0 0 1 1 1 0 82 * : Rd=38
0E82 : : INT : 11/ 0 : A=38 F= Z0 0V BC=00AF DE=5A51 HL=5A50 IX=F7FF IY=5C3A SP=FF4E
FETCH 0 0 1 0 1 1 1 0 f5 * : Wd=38
MEMWR 1 1 0 0 1 1 1 0 38 *
MEMWR 1 1 0 0 1 1 1 0 4c *
0038 : F5 : PUSH AF : 11/ 0 : A=38 F= Z0 1V BC=00AF DE=5A51 HL=5A50 IX=F7FF IY=5C3A SP=FF4C : fail
```

If you look at the flags value in the final line (marked fail), you can see the F3 flags has been "corrected" from 0 to 1 based on what was PUSHed to memory. This represents reality, i.e. what the Z80 actually set them to.

The unofficial documentation says these should be based on (data + A) = (0x38 + 0x38) = 0x70. So F5 should be bit 1 and F3 should be bit 3, both 0. That how I'm calculating them. But it seems the Z80 is actually doing something different, as the value pushed shows F3 is actually 1.

My implementation of this is quite simple:

Code: Select all

```
// Set the flags, see: page 16 of http://www.z80.info/zip/z80-documented.pdf
if (reg_a >= 0) {
int result = reg_a + arg_read;
flag_f5 = (result >> 1) & 1;
flag_f3 = (result >> 3) & 1;
} else {
flag_f5 = -1;
flag_f3 = -1;
}
```

For comparison, here's the same code from MAME:

Code: Select all

```
F &= SF | ZF | CF;
if ((A + io) & 0x02) F |= YF; /* bit 1 -> flag 5 */
if ((A + io) & 0x08) F |= XF; /* bit 3 -> flag 3 */
```

(YF is F5 and XF is F3).

I'm sure I'm missing something here, but I can't for the life of me figure it out.

Dave