├── .gitattributes
├── readme.md
├── .gitignore
├── MyZ80.vcxproj.filters
├── MyZ80.sln
├── MyZ80.vcxproj
└── main.cpp
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 |
7 | # Standard to msysgit
8 | *.doc diff=astextplain
9 | *.DOC diff=astextplain
10 | *.docx diff=astextplain
11 | *.DOCX diff=astextplain
12 | *.dot diff=astextplain
13 | *.DOT diff=astextplain
14 | *.pdf diff=astextplain
15 | *.PDF diff=astextplain
16 | *.rtf diff=astextplain
17 | *.RTF diff=astextplain
18 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | ## MyZ80 - Mockba's yet another Z80 emulator
2 |
3 | This is a project I am writing with the intent to have a Z80 emulator code on my RunCPM and at the same time use the same code as a model on Proteus.
4 |
5 | The code is still in its infancy, but some of the Z80 instructions are already working.
6 |
7 | There's still a lot to be done, but it is here in case anyone is interested.
8 |
9 | The method I am using to emulate the Z80 is the one described on http://www.z80.info/decoding.htm
10 |
11 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Windows image file caches
2 | Thumbs.db
3 | ehthumbs.db
4 |
5 | # Folder config file
6 | Desktop.ini
7 |
8 | # Recycle Bin used on file shares
9 | $RECYCLE.BIN/
10 |
11 | # Windows Installer files
12 | *.cab
13 | *.msi
14 | *.msm
15 | *.msp
16 |
17 | # Windows shortcuts
18 | *.lnk
19 |
20 | # =========================
21 | # Operating System Files
22 | # =========================
23 |
24 | # OSX
25 | # =========================
26 |
27 | .DS_Store
28 | .AppleDouble
29 | .LSOverride
30 |
31 | # Thumbnails
32 | ._*
33 |
34 | # Files that might appear in the root of a volume
35 | .DocumentRevisions-V100
36 | .fseventsd
37 | .Spotlight-V100
38 | .TemporaryItems
39 | .Trashes
40 | .VolumeIcon.icns
41 |
42 | # Directories potentially created on remote AFP share
43 | .AppleDB
44 | .AppleDesktop
45 | Network Trash Folder
46 | Temporary Items
47 | .apdisk
48 |
--------------------------------------------------------------------------------
/MyZ80.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 |
18 |
19 | Source Files
20 |
21 |
22 |
--------------------------------------------------------------------------------
/MyZ80.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.25420.1
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MyZ80", "MyZ80.vcxproj", "{AAF4208E-4584-468F-8E34-DA0FC05F6C01}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|x64 = Debug|x64
11 | Debug|x86 = Debug|x86
12 | Release|x64 = Release|x64
13 | Release|x86 = Release|x86
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {AAF4208E-4584-468F-8E34-DA0FC05F6C01}.Debug|x64.ActiveCfg = Debug|x64
17 | {AAF4208E-4584-468F-8E34-DA0FC05F6C01}.Debug|x64.Build.0 = Debug|x64
18 | {AAF4208E-4584-468F-8E34-DA0FC05F6C01}.Debug|x86.ActiveCfg = Debug|Win32
19 | {AAF4208E-4584-468F-8E34-DA0FC05F6C01}.Debug|x86.Build.0 = Debug|Win32
20 | {AAF4208E-4584-468F-8E34-DA0FC05F6C01}.Release|x64.ActiveCfg = Release|x64
21 | {AAF4208E-4584-468F-8E34-DA0FC05F6C01}.Release|x64.Build.0 = Release|x64
22 | {AAF4208E-4584-468F-8E34-DA0FC05F6C01}.Release|x86.ActiveCfg = Release|Win32
23 | {AAF4208E-4584-468F-8E34-DA0FC05F6C01}.Release|x86.Build.0 = Release|Win32
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | EndGlobal
29 |
--------------------------------------------------------------------------------
/MyZ80.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 | Debug
14 | x64
15 |
16 |
17 | Release
18 | x64
19 |
20 |
21 |
22 | {AAF4208E-4584-468F-8E34-DA0FC05F6C01}
23 | MyZ80
24 | 8.1
25 |
26 |
27 |
28 | Application
29 | true
30 | v140
31 | MultiByte
32 |
33 |
34 | Application
35 | false
36 | v140
37 | true
38 | MultiByte
39 |
40 |
41 | Application
42 | true
43 | v140
44 | MultiByte
45 |
46 |
47 | Application
48 | false
49 | v140
50 | true
51 | MultiByte
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 | Level3
75 | Disabled
76 | true
77 |
78 |
79 |
80 |
81 | Level3
82 | Disabled
83 | true
84 |
85 |
86 |
87 |
88 | Level3
89 | MaxSpeed
90 | true
91 | true
92 | true
93 |
94 |
95 | true
96 | true
97 |
98 |
99 |
100 |
101 | Level3
102 | MaxSpeed
103 | true
104 | true
105 | true
106 |
107 |
108 | true
109 | true
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
--------------------------------------------------------------------------------
/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #define BIG_ENDIAN // Define if host CPU is Big Endian
5 |
6 | typedef bool pin;
7 |
8 | typedef uint8_t Byte;
9 | typedef uint16_t Word;
10 | typedef uint8_t Reg8;
11 | typedef uint16_t Reg16;
12 | typedef uint32_t Reg32;
13 |
14 | #define RAMSIZE 65536
15 |
16 | Byte Ram[RAMSIZE]; // RAM Memory
17 |
18 | pin Clock = 1;
19 | pin nReset = 1;
20 |
21 | Byte Instr; // Current (fetched) instruction
22 | Byte M; // Current (fetched) memory byte
23 |
24 | // Instruction Decoding x x y y y z z z
25 | // - - p p q - - -
26 | //
27 | #define GetX(i) ((i & 0b11000000) >> 6)
28 | #define GetY(i) ((i & 0b00111000) >> 3)
29 | #define GetZ(i) (i & 0b00000111)
30 | #define GetP(i) ((i & 0b00110000) >> 4)
31 | #define GetQ(i) ((i & 0b00001000) >> 3)
32 |
33 | // Register table
34 | // 0 1 2 3 4 5 6 7 8 9 10 12 14 15 16 17 18 19 20 21 22 23 24 25
35 | // B C D E H L IXh IXl IYh IYl SP PC A F B' C' D' E' H' L' A' F' I R
36 | Reg8 Regs[26];
37 |
38 | #ifdef BIG_ENDIAN
39 | //Pointers to the 8 bit registers
40 | Reg8 *pB = &Regs[1];
41 | Reg8 *pC = &Regs[0];
42 | Reg8 *pD = &Regs[3];
43 | Reg8 *pE = &Regs[2];
44 | Reg8 *pH = &Regs[5];
45 | Reg8 *pL = &Regs[4];
46 | Reg8 *pIXh = &Regs[7];
47 | Reg8 *pIXl = &Regs[6];
48 | Reg8 *pIYh = &Regs[9];
49 | Reg8 *pIYl = &Regs[8];
50 | Reg8 *pA = &Regs[15];
51 | Reg8 *pF = &Regs[14];
52 | Reg8 *pB_ = &Regs[17];
53 | Reg8 *pC_ = &Regs[16];
54 | Reg8 *pD_ = &Regs[19];
55 | Reg8 *pE_ = &Regs[18];
56 | Reg8 *pH_ = &Regs[21];
57 | Reg8 *pL_ = &Regs[20];
58 | Reg8 *pA_ = &Regs[23];
59 | Reg8 *pF_ = &Regs[22];
60 | Reg8 *pI = &Regs[25];
61 | Reg8 *pR = &Regs[24];
62 | #else
63 | Reg8 *pB = &Regs[0];
64 | Reg8 *pC = &Regs[1];
65 | Reg8 *pD = &Regs[2];
66 | Reg8 *pE = &Regs[3];
67 | Reg8 *pH = &Regs[4];
68 | Reg8 *pL = &Regs[5];
69 | Reg8 *pIXh = &Regs[6];
70 | Reg8 *pIXl = &Regs[7];
71 | Reg8 *pIYh = &Regs[8];
72 | Reg8 *pIYl = &Regs[9];
73 | Reg8 *pA = &Regs[14];
74 | Reg8 *pF = &Regs[15];
75 | Reg8 *pB_ = &Regs[16];
76 | Reg8 *pC_ = &Regs[17];
77 | Reg8 *pD_ = &Regs[18];
78 | Reg8 *pE_ = &Regs[19];
79 | Reg8 *pH_ = &Regs[20];
80 | Reg8 *pL_ = &Regs[21];
81 | Reg8 *pA_ = &Regs[22];
82 | Reg8 *pF_ = &Regs[23];
83 | Reg8 *pI = &Regs[24];
84 | Reg8 *pR = &Regs[25];
85 | #endif
86 |
87 | // Pointers to the 16 bit registers
88 | Reg16 *pBC = (Reg16*)&Regs[0];
89 | Reg16 *pDE = (Reg16*)&Regs[2];
90 | Reg16 *pHL = (Reg16*)&Regs[4];
91 | Reg16 *pIX = (Reg16*)&Regs[6];
92 | Reg16 *pIY = (Reg16*)&Regs[8];
93 | Reg16 *pSP = (Reg16*)&Regs[10];
94 | Reg16 *pPC = (Reg16*)&Regs[12];
95 | Reg16 *pAF = (Reg16*)&Regs[14];
96 | Reg16 *pBC_ = (Reg16*)&Regs[16];
97 | Reg16 *pDE_ = (Reg16*)&Regs[18];
98 | Reg16 *pHL_ = (Reg16*)&Regs[20];
99 | Reg16 *pAF_ = (Reg16*)&Regs[22];
100 |
101 | // 8 Bit registers (renaming the pointers)
102 | #define B (*pB)
103 | #define C (*pC)
104 | #define D (*pD)
105 | #define E (*pE)
106 | #define H (*pH)
107 | #define L (*pL)
108 | #define IXh (*pIXh)
109 | #define IXl (*pIXl)
110 | #define IYh (*pIYh)
111 | #define IYl (*pIYl)
112 | #define A (*pA)
113 | #define F (*pF)
114 | #define B_ (*pB_)
115 | #define C_ (*pC_)
116 | #define D_ (*pD_)
117 | #define E_ (*pE_)
118 | #define H_ (*pH_)
119 | #define L_ (*pL_)
120 | #define A_ (*pA_)
121 | #define F_ (*pF_)
122 | #define I (*pI)
123 | #define R (*pR)
124 |
125 | // 16 Bit registers (renaming the pointers)
126 | #define BC (*pBC)
127 | #define DE (*pDE)
128 | #define HL (*pHL)
129 | #define IX (*pIX)
130 | #define IY (*pIY)
131 | #define SP (*pSP)
132 | #define PC (*pPC)
133 | #define AF (*pAF)
134 | #define BC_ (*pBC_)
135 | #define DE_ (*pDE_)
136 | #define HL_ (*pHL_)
137 | #define AF_ (*pAF_)
138 |
139 | // Flags (SZ5H3PNC)
140 | #define fS (F & 0b10000000)
141 | #define fZ (F & 0b01000000)
142 | #define fY (F & 0b00100000)
143 | #define fH (F & 0b00010000)
144 | #define fX (F & 0b00001000)
145 | #define fP (F & 0b00000100)
146 | #define fN (F & 0b00000010)
147 | #define fC (F & 0b00000001)
148 |
149 | // Data tables
150 | Reg16 *rp[4]; // BC DE HL SP
151 | Reg16 *rp2[4]; // BC DE HL AF
152 | Reg8 *r[8]; // B C D E H L (HL) A
153 |
154 | /* parityTable[i] = (number of 1's in i is odd) ? 0 : 4, i = 0..255 */
155 | static const Byte parityTable[256] = {
156 | 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4,
157 | 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0,
158 | 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0,
159 | 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4,
160 | 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0,
161 | 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4,
162 | 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4,
163 | 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0,
164 | 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0,
165 | 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4,
166 | 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4,
167 | 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0,
168 | 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4,
169 | 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0,
170 | 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0,
171 | 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4,
172 | };
173 |
174 | /* incTable[i] = (i & 0xa8) | (((i & 0xff) == 0) << 6) | (((i & 0xf) == 0) << 4), i = 0..256 */
175 | static const Byte incTable[257] = {
176 | 80, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8,
177 | 16, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8,
178 | 48, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40,
179 | 48, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40,
180 | 16, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8,
181 | 16, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8,
182 | 48, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40,
183 | 48, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40,
184 | 144,128,128,128,128,128,128,128,136,136,136,136,136,136,136,136,
185 | 144,128,128,128,128,128,128,128,136,136,136,136,136,136,136,136,
186 | 176,160,160,160,160,160,160,160,168,168,168,168,168,168,168,168,
187 | 176,160,160,160,160,160,160,160,168,168,168,168,168,168,168,168,
188 | 144,128,128,128,128,128,128,128,136,136,136,136,136,136,136,136,
189 | 144,128,128,128,128,128,128,128,136,136,136,136,136,136,136,136,
190 | 176,160,160,160,160,160,160,160,168,168,168,168,168,168,168,168,
191 | 176,160,160,160,160,160,160,160,168,168,168,168,168,168,168,168, 80
192 | };
193 |
194 | /* decTable[i] = (i & 0xa8) | (((i & 0xff) == 0) << 6) | (((i & 0xf) == 0xf) << 4) | 2, i = 0..255 */
195 | static const Byte decTable[256] = {
196 | 66, 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 26,
197 | 2, 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 26,
198 | 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 42, 58,
199 | 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 42, 58,
200 | 2, 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 26,
201 | 2, 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 26,
202 | 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 42, 58,
203 | 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 42, 58,
204 | 130,130,130,130,130,130,130,130,138,138,138,138,138,138,138,154,
205 | 130,130,130,130,130,130,130,130,138,138,138,138,138,138,138,154,
206 | 162,162,162,162,162,162,162,162,170,170,170,170,170,170,170,186,
207 | 162,162,162,162,162,162,162,162,170,170,170,170,170,170,170,186,
208 | 130,130,130,130,130,130,130,130,138,138,138,138,138,138,138,154,
209 | 130,130,130,130,130,130,130,130,138,138,138,138,138,138,138,154,
210 | 162,162,162,162,162,162,162,162,170,170,170,170,170,170,170,186,
211 | 162,162,162,162,162,162,162,162,170,170,170,170,170,170,170,186,
212 | };
213 |
214 | /* cbitsTable[i] = (i & 0x10) | ((i >> 8) & 1), i = 0..511 */
215 | static const Byte cbitsTable[512] = {
216 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
217 | 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
218 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
219 | 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
220 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
221 | 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
222 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
223 | 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
224 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
225 | 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
226 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
227 | 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
228 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
229 | 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
230 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
231 | 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
232 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
233 | 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
234 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
235 | 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
236 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
237 | 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
238 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
239 | 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
240 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
241 | 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
242 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
243 | 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
244 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
245 | 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
246 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
247 | 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
248 | };
249 |
250 | /* addTable[i] = ((i & 0xff) << 8) | (i & 0xa8) | (((i & 0xff) == 0) << 6), i = 0..511 */
251 | static const Word addTable[512] = {
252 | 0x0040,0x0100,0x0200,0x0300,0x0400,0x0500,0x0600,0x0700,
253 | 0x0808,0x0908,0x0a08,0x0b08,0x0c08,0x0d08,0x0e08,0x0f08,
254 | 0x1000,0x1100,0x1200,0x1300,0x1400,0x1500,0x1600,0x1700,
255 | 0x1808,0x1908,0x1a08,0x1b08,0x1c08,0x1d08,0x1e08,0x1f08,
256 | 0x2020,0x2120,0x2220,0x2320,0x2420,0x2520,0x2620,0x2720,
257 | 0x2828,0x2928,0x2a28,0x2b28,0x2c28,0x2d28,0x2e28,0x2f28,
258 | 0x3020,0x3120,0x3220,0x3320,0x3420,0x3520,0x3620,0x3720,
259 | 0x3828,0x3928,0x3a28,0x3b28,0x3c28,0x3d28,0x3e28,0x3f28,
260 | 0x4000,0x4100,0x4200,0x4300,0x4400,0x4500,0x4600,0x4700,
261 | 0x4808,0x4908,0x4a08,0x4b08,0x4c08,0x4d08,0x4e08,0x4f08,
262 | 0x5000,0x5100,0x5200,0x5300,0x5400,0x5500,0x5600,0x5700,
263 | 0x5808,0x5908,0x5a08,0x5b08,0x5c08,0x5d08,0x5e08,0x5f08,
264 | 0x6020,0x6120,0x6220,0x6320,0x6420,0x6520,0x6620,0x6720,
265 | 0x6828,0x6928,0x6a28,0x6b28,0x6c28,0x6d28,0x6e28,0x6f28,
266 | 0x7020,0x7120,0x7220,0x7320,0x7420,0x7520,0x7620,0x7720,
267 | 0x7828,0x7928,0x7a28,0x7b28,0x7c28,0x7d28,0x7e28,0x7f28,
268 | 0x8080,0x8180,0x8280,0x8380,0x8480,0x8580,0x8680,0x8780,
269 | 0x8888,0x8988,0x8a88,0x8b88,0x8c88,0x8d88,0x8e88,0x8f88,
270 | 0x9080,0x9180,0x9280,0x9380,0x9480,0x9580,0x9680,0x9780,
271 | 0x9888,0x9988,0x9a88,0x9b88,0x9c88,0x9d88,0x9e88,0x9f88,
272 | 0xa0a0,0xa1a0,0xa2a0,0xa3a0,0xa4a0,0xa5a0,0xa6a0,0xa7a0,
273 | 0xa8a8,0xa9a8,0xaaa8,0xaba8,0xaca8,0xada8,0xaea8,0xafa8,
274 | 0xb0a0,0xb1a0,0xb2a0,0xb3a0,0xb4a0,0xb5a0,0xb6a0,0xb7a0,
275 | 0xb8a8,0xb9a8,0xbaa8,0xbba8,0xbca8,0xbda8,0xbea8,0xbfa8,
276 | 0xc080,0xc180,0xc280,0xc380,0xc480,0xc580,0xc680,0xc780,
277 | 0xc888,0xc988,0xca88,0xcb88,0xcc88,0xcd88,0xce88,0xcf88,
278 | 0xd080,0xd180,0xd280,0xd380,0xd480,0xd580,0xd680,0xd780,
279 | 0xd888,0xd988,0xda88,0xdb88,0xdc88,0xdd88,0xde88,0xdf88,
280 | 0xe0a0,0xe1a0,0xe2a0,0xe3a0,0xe4a0,0xe5a0,0xe6a0,0xe7a0,
281 | 0xe8a8,0xe9a8,0xeaa8,0xeba8,0xeca8,0xeda8,0xeea8,0xefa8,
282 | 0xf0a0,0xf1a0,0xf2a0,0xf3a0,0xf4a0,0xf5a0,0xf6a0,0xf7a0,
283 | 0xf8a8,0xf9a8,0xfaa8,0xfba8,0xfca8,0xfda8,0xfea8,0xffa8,
284 | 0x0040,0x0100,0x0200,0x0300,0x0400,0x0500,0x0600,0x0700,
285 | 0x0808,0x0908,0x0a08,0x0b08,0x0c08,0x0d08,0x0e08,0x0f08,
286 | 0x1000,0x1100,0x1200,0x1300,0x1400,0x1500,0x1600,0x1700,
287 | 0x1808,0x1908,0x1a08,0x1b08,0x1c08,0x1d08,0x1e08,0x1f08,
288 | 0x2020,0x2120,0x2220,0x2320,0x2420,0x2520,0x2620,0x2720,
289 | 0x2828,0x2928,0x2a28,0x2b28,0x2c28,0x2d28,0x2e28,0x2f28,
290 | 0x3020,0x3120,0x3220,0x3320,0x3420,0x3520,0x3620,0x3720,
291 | 0x3828,0x3928,0x3a28,0x3b28,0x3c28,0x3d28,0x3e28,0x3f28,
292 | 0x4000,0x4100,0x4200,0x4300,0x4400,0x4500,0x4600,0x4700,
293 | 0x4808,0x4908,0x4a08,0x4b08,0x4c08,0x4d08,0x4e08,0x4f08,
294 | 0x5000,0x5100,0x5200,0x5300,0x5400,0x5500,0x5600,0x5700,
295 | 0x5808,0x5908,0x5a08,0x5b08,0x5c08,0x5d08,0x5e08,0x5f08,
296 | 0x6020,0x6120,0x6220,0x6320,0x6420,0x6520,0x6620,0x6720,
297 | 0x6828,0x6928,0x6a28,0x6b28,0x6c28,0x6d28,0x6e28,0x6f28,
298 | 0x7020,0x7120,0x7220,0x7320,0x7420,0x7520,0x7620,0x7720,
299 | 0x7828,0x7928,0x7a28,0x7b28,0x7c28,0x7d28,0x7e28,0x7f28,
300 | 0x8080,0x8180,0x8280,0x8380,0x8480,0x8580,0x8680,0x8780,
301 | 0x8888,0x8988,0x8a88,0x8b88,0x8c88,0x8d88,0x8e88,0x8f88,
302 | 0x9080,0x9180,0x9280,0x9380,0x9480,0x9580,0x9680,0x9780,
303 | 0x9888,0x9988,0x9a88,0x9b88,0x9c88,0x9d88,0x9e88,0x9f88,
304 | 0xa0a0,0xa1a0,0xa2a0,0xa3a0,0xa4a0,0xa5a0,0xa6a0,0xa7a0,
305 | 0xa8a8,0xa9a8,0xaaa8,0xaba8,0xaca8,0xada8,0xaea8,0xafa8,
306 | 0xb0a0,0xb1a0,0xb2a0,0xb3a0,0xb4a0,0xb5a0,0xb6a0,0xb7a0,
307 | 0xb8a8,0xb9a8,0xbaa8,0xbba8,0xbca8,0xbda8,0xbea8,0xbfa8,
308 | 0xc080,0xc180,0xc280,0xc380,0xc480,0xc580,0xc680,0xc780,
309 | 0xc888,0xc988,0xca88,0xcb88,0xcc88,0xcd88,0xce88,0xcf88,
310 | 0xd080,0xd180,0xd280,0xd380,0xd480,0xd580,0xd680,0xd780,
311 | 0xd888,0xd988,0xda88,0xdb88,0xdc88,0xdd88,0xde88,0xdf88,
312 | 0xe0a0,0xe1a0,0xe2a0,0xe3a0,0xe4a0,0xe5a0,0xe6a0,0xe7a0,
313 | 0xe8a8,0xe9a8,0xeaa8,0xeba8,0xeca8,0xeda8,0xeea8,0xefa8,
314 | 0xf0a0,0xf1a0,0xf2a0,0xf3a0,0xf4a0,0xf5a0,0xf6a0,0xf7a0,
315 | 0xf8a8,0xf9a8,0xfaa8,0xfba8,0xfca8,0xfda8,0xfea8,0xffa8,
316 | };
317 |
318 | /* subTable[i] = ((i & 0xff) << 8) | (i & 0xa8) | (((i & 0xff) == 0) << 6) | 2, i = 0..255 */
319 | static const Word subTable[256] = {
320 | 0x0042,0x0102,0x0202,0x0302,0x0402,0x0502,0x0602,0x0702,
321 | 0x080a,0x090a,0x0a0a,0x0b0a,0x0c0a,0x0d0a,0x0e0a,0x0f0a,
322 | 0x1002,0x1102,0x1202,0x1302,0x1402,0x1502,0x1602,0x1702,
323 | 0x180a,0x190a,0x1a0a,0x1b0a,0x1c0a,0x1d0a,0x1e0a,0x1f0a,
324 | 0x2022,0x2122,0x2222,0x2322,0x2422,0x2522,0x2622,0x2722,
325 | 0x282a,0x292a,0x2a2a,0x2b2a,0x2c2a,0x2d2a,0x2e2a,0x2f2a,
326 | 0x3022,0x3122,0x3222,0x3322,0x3422,0x3522,0x3622,0x3722,
327 | 0x382a,0x392a,0x3a2a,0x3b2a,0x3c2a,0x3d2a,0x3e2a,0x3f2a,
328 | 0x4002,0x4102,0x4202,0x4302,0x4402,0x4502,0x4602,0x4702,
329 | 0x480a,0x490a,0x4a0a,0x4b0a,0x4c0a,0x4d0a,0x4e0a,0x4f0a,
330 | 0x5002,0x5102,0x5202,0x5302,0x5402,0x5502,0x5602,0x5702,
331 | 0x580a,0x590a,0x5a0a,0x5b0a,0x5c0a,0x5d0a,0x5e0a,0x5f0a,
332 | 0x6022,0x6122,0x6222,0x6322,0x6422,0x6522,0x6622,0x6722,
333 | 0x682a,0x692a,0x6a2a,0x6b2a,0x6c2a,0x6d2a,0x6e2a,0x6f2a,
334 | 0x7022,0x7122,0x7222,0x7322,0x7422,0x7522,0x7622,0x7722,
335 | 0x782a,0x792a,0x7a2a,0x7b2a,0x7c2a,0x7d2a,0x7e2a,0x7f2a,
336 | 0x8082,0x8182,0x8282,0x8382,0x8482,0x8582,0x8682,0x8782,
337 | 0x888a,0x898a,0x8a8a,0x8b8a,0x8c8a,0x8d8a,0x8e8a,0x8f8a,
338 | 0x9082,0x9182,0x9282,0x9382,0x9482,0x9582,0x9682,0x9782,
339 | 0x988a,0x998a,0x9a8a,0x9b8a,0x9c8a,0x9d8a,0x9e8a,0x9f8a,
340 | 0xa0a2,0xa1a2,0xa2a2,0xa3a2,0xa4a2,0xa5a2,0xa6a2,0xa7a2,
341 | 0xa8aa,0xa9aa,0xaaaa,0xabaa,0xacaa,0xadaa,0xaeaa,0xafaa,
342 | 0xb0a2,0xb1a2,0xb2a2,0xb3a2,0xb4a2,0xb5a2,0xb6a2,0xb7a2,
343 | 0xb8aa,0xb9aa,0xbaaa,0xbbaa,0xbcaa,0xbdaa,0xbeaa,0xbfaa,
344 | 0xc082,0xc182,0xc282,0xc382,0xc482,0xc582,0xc682,0xc782,
345 | 0xc88a,0xc98a,0xca8a,0xcb8a,0xcc8a,0xcd8a,0xce8a,0xcf8a,
346 | 0xd082,0xd182,0xd282,0xd382,0xd482,0xd582,0xd682,0xd782,
347 | 0xd88a,0xd98a,0xda8a,0xdb8a,0xdc8a,0xdd8a,0xde8a,0xdf8a,
348 | 0xe0a2,0xe1a2,0xe2a2,0xe3a2,0xe4a2,0xe5a2,0xe6a2,0xe7a2,
349 | 0xe8aa,0xe9aa,0xeaaa,0xebaa,0xecaa,0xedaa,0xeeaa,0xefaa,
350 | 0xf0a2,0xf1a2,0xf2a2,0xf3a2,0xf4a2,0xf5a2,0xf6a2,0xf7a2,
351 | 0xf8aa,0xf9aa,0xfaaa,0xfbaa,0xfcaa,0xfdaa,0xfeaa,0xffaa,
352 | };
353 |
354 | /* andTable[i] = (i << 8) | (i & 0xa8) | ((i == 0) << 6) | 0x10 | parityTable[i], i = 0..255 */
355 | static const Byte andTable[256] = {
356 | 0x54,0x10,0x10,0x14,0x10,0x14,0x14,0x10,
357 | 0x18,0x1c,0x1c,0x18,0x1c,0x18,0x18,0x1c,
358 | 0x10,0x14,0x14,0x10,0x14,0x10,0x10,0x14,
359 | 0x1c,0x18,0x18,0x1c,0x18,0x1c,0x1c,0x18,
360 | 0x30,0x34,0x34,0x30,0x34,0x30,0x30,0x34,
361 | 0x3c,0x38,0x38,0x3c,0x38,0x3c,0x3c,0x38,
362 | 0x34,0x30,0x30,0x34,0x30,0x34,0x34,0x30,
363 | 0x38,0x3c,0x3c,0x38,0x3c,0x38,0x38,0x3c,
364 | 0x10,0x14,0x14,0x10,0x14,0x10,0x10,0x14,
365 | 0x1c,0x18,0x18,0x1c,0x18,0x1c,0x1c,0x18,
366 | 0x14,0x10,0x10,0x14,0x10,0x14,0x14,0x10,
367 | 0x18,0x1c,0x1c,0x18,0x1c,0x18,0x18,0x1c,
368 | 0x34,0x30,0x30,0x34,0x30,0x34,0x34,0x30,
369 | 0x38,0x3c,0x3c,0x38,0x3c,0x38,0x38,0x3c,
370 | 0x30,0x34,0x34,0x30,0x34,0x30,0x30,0x34,
371 | 0x3c,0x38,0x38,0x3c,0x38,0x3c,0x3c,0x38,
372 | 0x90,0x94,0x94,0x90,0x94,0x90,0x90,0x94,
373 | 0x9c,0x98,0x98,0x9c,0x98,0x9c,0x9c,0x98,
374 | 0x94,0x90,0x90,0x94,0x90,0x94,0x94,0x90,
375 | 0x98,0x9c,0x9c,0x98,0x9c,0x98,0x98,0x9c,
376 | 0xb4,0xb0,0xb0,0xb4,0xb0,0xb4,0xb4,0xb0,
377 | 0xb8,0xbc,0xbc,0xb8,0xbc,0xb8,0xb8,0xbc,
378 | 0xb0,0xb4,0xb4,0xb0,0xb4,0xb0,0xb0,0xb4,
379 | 0xbc,0xb8,0xb8,0xbc,0xb8,0xbc,0xbc,0xb8,
380 | 0x94,0x90,0x90,0x94,0x90,0x94,0x94,0x90,
381 | 0x98,0x9c,0x9c,0x98,0x9c,0x98,0x98,0x9c,
382 | 0x90,0x94,0x94,0x90,0x94,0x90,0x90,0x94,
383 | 0x9c,0x98,0x98,0x9c,0x98,0x9c,0x9c,0x98,
384 | 0xb0,0xb4,0xb4,0xb0,0xb4,0xb0,0xb0,0xb4,
385 | 0xbc,0xb8,0xb8,0xbc,0xb8,0xbc,0xbc,0xb8,
386 | 0xb4,0xb0,0xb0,0xb4,0xb0,0xb4,0xb4,0xb0,
387 | 0xb8,0xbc,0xbc,0xb8,0xbc,0xb8,0xb8,0xbc,
388 | };
389 |
390 | /* xororTable[i] = (i << 8) | (i & 0xa8) | ((i == 0) << 6) | parityTable[i], i = 0..255 */
391 | static const Byte xororTable[256] = {
392 | 0x44,0x00,0x00,0x04,0x00,0x04,0x04,0x00,
393 | 0x08,0x0c,0x0c,0x08,0x0c,0x08,0x08,0x0c,
394 | 0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04,
395 | 0x0c,0x08,0x08,0x0c,0x08,0x0c,0x0c,0x08,
396 | 0x20,0x24,0x24,0x20,0x24,0x20,0x20,0x24,
397 | 0x2c,0x28,0x28,0x2c,0x28,0x2c,0x2c,0x28,
398 | 0x24,0x20,0x20,0x24,0x20,0x24,0x24,0x20,
399 | 0x28,0x2c,0x2c,0x28,0x2c,0x28,0x28,0x2c,
400 | 0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04,
401 | 0x0c,0x08,0x08,0x0c,0x08,0x0c,0x0c,0x08,
402 | 0x04,0x00,0x00,0x04,0x00,0x04,0x04,0x00,
403 | 0x08,0x0c,0x0c,0x08,0x0c,0x08,0x08,0x0c,
404 | 0x24,0x20,0x20,0x24,0x20,0x24,0x24,0x20,
405 | 0x28,0x2c,0x2c,0x28,0x2c,0x28,0x28,0x2c,
406 | 0x20,0x24,0x24,0x20,0x24,0x20,0x20,0x24,
407 | 0x2c,0x28,0x28,0x2c,0x28,0x2c,0x2c,0x28,
408 | 0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84,
409 | 0x8c,0x88,0x88,0x8c,0x88,0x8c,0x8c,0x88,
410 | 0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80,
411 | 0x88,0x8c,0x8c,0x88,0x8c,0x88,0x88,0x8c,
412 | 0xa4,0xa0,0xa0,0xa4,0xa0,0xa4,0xa4,0xa0,
413 | 0xa8,0xac,0xac,0xa8,0xac,0xa8,0xa8,0xac,
414 | 0xa0,0xa4,0xa4,0xa0,0xa4,0xa0,0xa0,0xa4,
415 | 0xac,0xa8,0xa8,0xac,0xa8,0xac,0xac,0xa8,
416 | 0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80,
417 | 0x88,0x8c,0x8c,0x88,0x8c,0x88,0x88,0x8c,
418 | 0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84,
419 | 0x8c,0x88,0x88,0x8c,0x88,0x8c,0x8c,0x88,
420 | 0xa0,0xa4,0xa4,0xa0,0xa4,0xa0,0xa0,0xa4,
421 | 0xac,0xa8,0xa8,0xac,0xa8,0xac,0xac,0xa8,
422 | 0xa4,0xa0,0xa0,0xa4,0xa0,0xa4,0xa4,0xa0,
423 | 0xa8,0xac,0xac,0xa8,0xac,0xa8,0xa8,0xac,
424 | };
425 |
426 | #define SET_PVS(s) (((Tmp16_2 >> 6) ^ (Tmp16_2 >> 5)) & 4)
427 | #define SET_PV (SET_PVS(Tmp16_1))
428 | #define SET_PV2(x) ((Tmp8_1 == (x)) << 2)
429 |
430 | // Memory manipulation functions
431 | // (Must be different for hardware based emulation)
432 | Byte Fetch8(Word Addr) {
433 | return(Ram[Addr]);
434 | }
435 |
436 | void Write8(Word Addr, Byte Value) {
437 | Ram[Addr] = Value;
438 | }
439 |
440 | Word Fetch16(Word Addr) {
441 | #ifdef BIG_ENDIAN
442 | return((Ram[Addr + 1] << 8) + Ram[Addr]);
443 | #else
444 | return((Ram[Addr] << 8) + Ram[Addr + 1]);
445 | #endif
446 | }
447 |
448 | void Write16(Word Addr, Word Value) {
449 | #ifdef BIG_ENDIAN
450 | Ram[Addr + 1] = (Value & 0xff);
451 | Ram[Addr] = ((Value >> 8) & 0xff);
452 | #else
453 | Ram[Addr] = (Value & 0xff);
454 | Ram[Addr + 1] = ((Value >> 8) & 0xff);
455 | #endif
456 | }
457 |
458 | void TestLoad(void) { // Loads the memory with a small test application
459 | int i = 0;
460 |
461 | // Ram[i++] = 0x00; // NOP
462 | Ram[i++] = 0x01; // LD BC, 0x0F29
463 | Ram[i++] = 0x29;
464 | Ram[i++] = 0x0F;
465 | // Ram[i++] = 0x02; // LD (BC), A
466 | // Ram[i++] = 0x03; // INC BC
467 | // Ram[i++] = 0x04; // INC B
468 | // Ram[i++] = 0x05; // DEC B
469 | // Ram[i++] = 0x06; // LD B, 0x7F
470 | // Ram[i++] = 0x7F;
471 | // Ram[i++] = 0x06; // LD B, 0x00
472 | // Ram[i++] = 0x00;
473 | // Ram[i++] = 0x0E; // LD C, 0x03
474 | // Ram[i++] = 0x03;
475 | // Ram[i++] = 0x08; // EX AF, AF'
476 | // Ram[i++] = 0x10; // DJNZ, -2
477 | // Ram[i++] = 0xFE;
478 | Ram[i++] = 0x21; // LD HL, 0x0200
479 | Ram[i++] = 0x00;
480 | Ram[i++] = 0x02;
481 | Ram[i++] = 0x09; // ADD HL, BC
482 | Ram[i++] = 0x76; // HLT
483 |
484 | }
485 |
486 | void Z80Init(void) { // Must be called before anything else
487 |
488 | // Prepare register pair table
489 | rp[0] = pBC;
490 | rp[1] = pDE;
491 | rp[2] = pHL;
492 | rp[3] = pSP;
493 |
494 | // Prepare second register pair table
495 | rp2[0] = pBC;
496 | rp2[1] = pDE;
497 | rp2[2] = pHL;
498 | rp2[3] = pAF;
499 |
500 | // Prepare register table
501 | r[0] = pB;
502 | r[1] = pC;
503 | r[2] = pD;
504 | r[3] = pE;
505 | r[4] = pH;
506 | r[5] = pL;
507 | r[7] = pA;
508 |
509 | }
510 |
511 | void Z80Reset(void) { // Resets all Z80 registers (and other stuff) to their initial values
512 | Byte i;
513 | for (i = 0; i < 26; i++) {
514 | Regs[i] = 0;
515 | }
516 | }
517 |
518 | Byte Z80DecodeCB(void) { // Decodes and executes the CB prefix instruction
519 | Byte Result = 0;
520 | Byte x, y, z, p, q;
521 | Reg8 Tmp8;
522 | Reg16 Tmp16;
523 |
524 | Instr = Fetch8(PC++);
525 | x = GetX(Instr);
526 | y = GetY(Instr);
527 | z = GetZ(Instr);
528 | p = GetP(Instr);
529 | q = GetQ(Instr);
530 |
531 | R++;
532 |
533 | if (x == 0) { // rot[y] r[z]
534 |
535 | }
536 | if (x == 1) { // BIT y, r[z]
537 |
538 | }
539 | if (x == 2) { // RES y, r[z]
540 |
541 | }
542 | if (x == 3) { // SET y, r[z]
543 |
544 | }
545 | return(Result);
546 | }
547 |
548 | Byte Z80DecodeDD(void) { // Decodes and executes the CB prefix instruction
549 | Byte Result = 0;
550 | Byte x, y, z, p, q;
551 | Reg8 Tmp8;
552 | Reg16 Tmp16;
553 |
554 | Instr = Fetch8(PC++);
555 | x = GetX(Instr);
556 | y = GetY(Instr);
557 | z = GetZ(Instr);
558 | p = GetP(Instr);
559 | q = GetQ(Instr);
560 |
561 | R++;
562 |
563 | return(Result);
564 | }
565 |
566 | Byte Z80DecodeED(void) { // Decodes and executes the CB prefix instruction
567 | Byte Result = 0;
568 | Byte x, y, z, p, q;
569 | Reg8 Tmp8;
570 | Reg16 Tmp16;
571 |
572 | Instr = Fetch8(PC++);
573 | x = GetX(Instr);
574 | y = GetY(Instr);
575 | z = GetZ(Instr);
576 | p = GetP(Instr);
577 | q = GetQ(Instr);
578 |
579 | R++;
580 |
581 | return(Result);
582 | }
583 |
584 | Byte Z80DecodeFD(void) { // Decodes and executes the CB prefix instruction
585 | Byte Result = 0;
586 | Byte x, y, z, p, q;
587 | Reg8 Tmp8;
588 | Reg16 Tmp16;
589 |
590 | Instr = Fetch8(PC++);
591 | x = GetX(Instr);
592 | y = GetY(Instr);
593 | z = GetZ(Instr);
594 | p = GetP(Instr);
595 | q = GetQ(Instr);
596 |
597 | R++;
598 |
599 | return(Result);
600 | }
601 |
602 | Byte Z80Decode(void) { // Decodes and executes the instruction pointed at by PC
603 | Byte Result = 0;
604 | Byte x, y, z, p, q;
605 | Reg8 Tmp8_1;
606 | Reg16 Tmp16_1, Tmp16_2;
607 | Reg32 Tmp32;
608 |
609 | if (Clock) {
610 | Instr = Fetch8(PC++);
611 | x = GetX(Instr);
612 | y = GetY(Instr);
613 | z = GetZ(Instr);
614 | p = GetP(Instr);
615 | q = GetQ(Instr);
616 |
617 | R++;
618 |
619 | if (x == 0) {
620 | if (z == 0) {
621 | if (y == 0) { // NOP
622 | // Do nothing
623 | }
624 | if (y == 1) { // EX AF,AF'
625 | Tmp16_1 = AF; AF = AF_; AF_ = Tmp16_1;
626 | }
627 | if (y == 2) { // DJNZ d
628 | Tmp8_1 = Fetch8(PC++);
629 | if (--BC) {
630 | PC += (int8_t)Tmp8_1;
631 | }
632 | }
633 | if (y == 3) { // JR d
634 | Tmp8_1 = Fetch8(PC++);
635 | PC += (int8_t)Tmp8_1;
636 | }
637 | if (y > 3) { // JR cc[y-4], d
638 | Tmp8_1 = Fetch8(PC++);
639 | if (y == 4) { // JR NZ, d
640 | if (!fZ)
641 | PC += (int8_t)Tmp8_1;
642 | }
643 | if (y == 5) { // JR Z, d
644 | if (fZ)
645 | PC += (int8_t)Tmp8_1;
646 | }
647 | if (y == 6) { // JR NC, d
648 | if (!fC)
649 | PC += (int8_t)Tmp8_1;
650 | }
651 | if (y == 7) { // JR C, d
652 | if (fC)
653 | PC += (int8_t)Tmp8_1;
654 | }
655 | }
656 | }
657 | if (z == 1) {
658 | if (q == 0) { // LD rp[p], nn
659 | Tmp16_1 = Fetch16(PC); PC += 2;
660 | *rp[p] = Tmp16_1;
661 | }
662 | if (q == 1) { // ADD HL, rp[p]
663 | Tmp32 = HL + *rp[p];
664 | F = (F & ~0x3b) | ((Tmp32 >> 8) & 0x28) | cbitsTable[(HL ^ *rp[p] ^ Tmp32) >> 8];
665 | HL = Tmp32;
666 | }
667 | }
668 | if (z == 2) {
669 | if (q == 0) {
670 | if (p == 0) { // LD (BC), A
671 | Write8(BC, A);
672 | }
673 | if (p == 1) { // LD (DE), A
674 | Write8(DE, A);
675 | }
676 | if (p == 2) { // LD (nn), HL
677 | Tmp16_1 = Fetch16(PC); PC += 2;
678 | Write16(Tmp16_1, HL);
679 | }
680 | if (p == 3) { // LD (nn), A
681 | Tmp16_1 = Fetch16(PC); PC += 2;
682 | Write8(Tmp16_1, A);
683 | }
684 | }
685 | if (q == 1) {
686 | if (p == 0) { // LD A, (BC)
687 | A = Fetch8(BC);
688 | }
689 | if (p == 1) { // LD A, (DE)
690 | A = Fetch8(DE);
691 | }
692 | if (p == 2) { // LD HL, (nn)
693 | Tmp16_1 = Fetch16(PC); PC += 2;
694 | HL = Fetch16(Tmp16_1);
695 | }
696 | if (p == 3) { // LD A, (nn)
697 | Tmp16_1 = Fetch16(PC); PC += 2;
698 | A = Fetch8(Tmp16_1);
699 | }
700 | }
701 | }
702 | if (z == 3) {
703 | if (q == 0) { // INC rp[p]
704 | (*rp[p])++;
705 | }
706 | if (q == 1) { // DEC rp[p]
707 | (*rp[p])--;
708 | }
709 | }
710 | if (z == 4) { // INC r[y]
711 | if (y == 6) {
712 | Tmp8_1 = Fetch8(HL);
713 | Tmp8_1++;
714 | Write8(HL, Tmp8_1);
715 | } else {
716 | Tmp8_1 = (*r[y]);
717 | Tmp8_1++;
718 | }
719 | F = (F & ~0xfe) | incTable[*r[y]] | SET_PV2(0x80);
720 | }
721 | if (z == 5) { // DEC r[y]
722 | if (y == 6) {
723 | Tmp8_1 = Fetch8(HL);
724 | Tmp8_1--;
725 | Write8(HL, Tmp8_1);
726 | } else {
727 | Tmp8_1 = (*r[y]);
728 | Tmp8_1--;
729 | }
730 | F = (F & ~0xfe) | decTable[*r[y]] | SET_PV2(0x7f);
731 | }
732 | if (z == 6) { // LD r[y], n
733 | Tmp8_1 = Fetch8(PC++);
734 | if (y == 6) {
735 | Write8(HL, Tmp8_1);
736 | } else {
737 | (*r[y]) = Tmp8_1;
738 | }
739 | }
740 | if (z == 7) {
741 | if (y == 0) { // RLCA
742 | Tmp8_1 = (A & 0x80) >> 7;
743 | A = (A << 1) & Tmp8_1;
744 | F = (F & 0xc4) | (A & 0x28) | Tmp8_1;
745 | }
746 | if (y == 1) { // RRCA
747 | Tmp8_1 = (A & 0x01);
748 | A = (A >> 1) & (Tmp8_1 << 7);
749 | F = (F & 0xc4) | (A & 0x28) | Tmp8_1;
750 | }
751 | if (y == 2) { // RLA
752 | Tmp8_1 = (A & 0x80) >> 7;
753 | A = (A << 1) & (F & 0x01);
754 | F = (F & 0xc4) | (A & 0x28) | Tmp8_1;
755 | }
756 | if (y == 3) { // RRA
757 | Tmp8_1 = (A & 0x01);
758 | A = (A >> 1) & (F << 7);
759 | F = (F & 0xc4) | (A & 0x28) | Tmp8_1;
760 | }
761 | if (y == 4) { // DAA
762 | Tmp8_1 = A;
763 | if (fN) {
764 | if (fH || (A & 0x0f) > 9) Tmp8_1 -= 6;
765 | if (fC || A > 0x99) Tmp8_1 -= 0x60;
766 | } else {
767 | if (fH || (A & 0x0f) > 9) Tmp8_1 += 6;
768 | if (fC || A > 0x99) Tmp8_1 += 0x60;
769 | }
770 | F = (F & 0x03) | parityTable[Tmp8_1] | (A > 0x99) | ((A^Tmp8_1) & 0x10);
771 | A = Tmp8_1;
772 | }
773 | if (y == 5) { // CPL
774 | A = ~A;
775 | F = (F & 0xc5) | (A & 0x28) | 0x12;
776 | }
777 | if (y == 6) { // SCF
778 | F = (F & 0xc4) | (A & 0x28) | 0x01;
779 | }
780 | if (y == 7) { // CCF
781 | Tmp8_1 = ~F & 0x01;
782 | F = (F & 0xc4) | (A & 0x28) | (fC << 4) | Tmp8_1;
783 | }
784 | }
785 | }
786 | if (x == 1) {
787 | if (z == 6) {
788 | if (y == 6) { // HLT (replaces LD (HL), (HL))
789 | Result = 1;
790 | } else { // LD r[y], (HL)
791 | Tmp8_1 = Fetch8(HL);
792 | (*r[y]) = Tmp8_1;
793 | }
794 | } else {
795 | if (y == 6) { // LD (HL), r[z]
796 | Write8(HL, (*r[z]));
797 | } else { // LD r[y], r[z]
798 | (*r[y]) = (*r[z]);
799 | }
800 | }
801 | }
802 | if (x == 2) { // alu[y] r[z]
803 | if (z == 6) {
804 | Tmp8_1 = Fetch8(HL);
805 | } else {
806 | Tmp8_1 = (*r[z]);
807 | }
808 | if (y == 0) { // ADD A, r[z]
809 | Tmp16_1 = A + Tmp8_1;
810 | Tmp16_2 = A ^ Tmp8_1 ^ Tmp16_1;
811 | AF = addTable[Tmp16_1] | cbitsTable[Tmp16_2] | (SET_PV);
812 | }
813 | if (y == 1) { // ADC A, r[z]
814 | Tmp16_1 = A + Tmp8_1 + (fC != 0);
815 | Tmp16_2 = A ^ Tmp8_1 ^ Tmp16_1;
816 | AF = addTable[Tmp16_1] | cbitsTable[Tmp16_2] | (SET_PV);
817 | }
818 | if (y == 2) { // SUB r[z]
819 | Tmp16_1 = A - Tmp8_1;
820 | Tmp16_2 = A ^ Tmp8_1 ^ Tmp16_1;
821 | AF = subTable[Tmp16_1 & 0xff] | cbitsTable[Tmp16_2 & 0x1ff] | (SET_PV);
822 | }
823 | if (y == 3) { // SBC A,
824 | Tmp16_1 = A - Tmp8_1 - (fC != 0);
825 | Tmp16_2 = A ^ Tmp8_1 ^ Tmp16_1;
826 | AF = subTable[Tmp16_1 & 0xff] | cbitsTable[Tmp16_2 & 0x1ff] | (SET_PV);
827 | }
828 | if (y == 4) { // AND
829 | A = A & Tmp8_1;
830 | F = andTable[A];
831 | }
832 | if (y == 5) { // XOR
833 | A = A ^ Tmp8_1;
834 | F = xororTable[A];
835 | }
836 | if (y == 6) { // OR
837 | A = A | Tmp8_1;
838 | F = xororTable[A];
839 | }
840 | if (y == 7) { // CP
841 |
842 | }
843 | }
844 | if (x == 3) {
845 | if (z == 0) { // RET cc[y]
846 |
847 | }
848 | if (z == 1) {
849 | if (q == 0) { // POP rp2[p]
850 |
851 | } else {
852 | if (p == 0) { // RET
853 |
854 | }
855 | if (p == 1) { // EXX
856 |
857 | }
858 | if (p == 2) { // JP HL
859 |
860 | }
861 | if (p == 3) { // LD SP,HL
862 |
863 | }
864 | }
865 |
866 | }
867 | if (z == 2) { // JP cc[y], nn
868 |
869 | }
870 | if (z == 3) {
871 | if (y == 0) { // JP nn
872 |
873 | }
874 | if (y == 1) { // (CB prefix)
875 | Z80DecodeCB();
876 | }
877 | if (y == 2) { // OUT (n), A
878 |
879 | }
880 | if (y == 3) { // IN A, (n)
881 |
882 | }
883 | if (y == 4) { // EX (SP), HL
884 |
885 | }
886 | if (y == 5) { // EX DE, HL
887 |
888 | }
889 | if (y == 6) { // DI
890 |
891 | }
892 | if (y == 7) { // EI
893 |
894 | }
895 | }
896 | if (z == 4) { // CALL cc[y], nn
897 |
898 | }
899 | if (z == 5) {
900 | if (q == 0) { // PUSH rp2[p]
901 |
902 | } else {
903 | if (p == 0) { // CALL nn
904 |
905 | }
906 | if (p == 1) { // (DD prefix)
907 | Z80DecodeDD();
908 | }
909 | if (p == 2) { // (ED prefix)
910 | Z80DecodeED();
911 | }
912 | if (p == 3) { // (FD prefix)
913 | Z80DecodeFD();
914 | }
915 | }
916 | if (z == 6) { // alu[y] n
917 |
918 | }
919 | if (z == 7) { // RST y*8
920 |
921 | }
922 | }
923 | }
924 | }
925 | return(Result);
926 | }
927 |
928 | int main(void) {
929 | printf("MyZ80 Test Interface\n");
930 | printf("Copyright (C) 2016 Marcelo F. Dantas\n");
931 |
932 | Z80Init();
933 |
934 | TestLoad();
935 |
936 | Z80Reset();
937 | while (true) {
938 | if (Z80Decode()) {
939 | break;
940 | }
941 | }
942 | }
--------------------------------------------------------------------------------