1 /** Z80: portable Z80 emulator *******************************/
2 /**                                                         **/
3 /**                           Z80.c                         **/
4 /**                                                         **/
5 /** This file contains implementation for Z80 CPU. Don't    **/
6 /** forget to provide RdZ80(), WrZ80(), InZ80(), OutZ80(),  **/
7 /** LoopZ80(), and PatchZ80() functions to accomodate the   **/
8 /** emulated machine's architecture.                        **/
9 /**                                                         **/
10 /** Copyright (C) Marat Fayzullin 1994,1995,1996,1997       **/
11 /**     You are not allowed to distribute this software     **/
12 /**     commercially. Please, notify me, if you make any    **/
13 /**     changes to this file.                               **/
14 /*************************************************************/
15 
16 /* $Id: mz80.c,v 1.7 2001/02/25 21:47:47 nyef Exp $ */
17 
18 #include "mz80.h"
19 #include "tool.h"
20 #include "ui.h"
21 
22 #include <stdlib.h>
23 
24 static byte z80_Cycles[256] =
25 {
26    4,10, 7, 6, 4, 4, 7, 4, 4,11, 7, 6, 4, 4, 7, 4,
27    8,10, 7, 6, 4, 4, 7, 4,12,11, 7, 6, 4, 4, 7, 4,
28    7,10,16, 6, 4, 4, 7, 4, 7,11,16, 6, 4, 4, 7, 4,
29    7,10,13, 6,11,11,10, 4, 7,11,13, 6, 4, 4, 7, 4,
30    4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
31    4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
32    4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
33    7, 7, 7, 7, 7, 7, 4, 7, 4, 4, 4, 4, 4, 4, 7, 4,
34    4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
35    4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
36    4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
37    4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
38    5,10,10,10,10,11, 7,11, 5,10,10, 0,10,17, 7,11,
39    5,10,10,11,10,11, 7,11, 5, 4,10,11,10, 0, 7,11,
40    5,10,10,19,10,11, 7,11, 5, 4,10, 4,10, 0, 7,11,
41    5,10,10, 4,10,11, 7,11, 5, 6,10, 4,10, 0, 7,11
42 };
43 
44 static byte z80_CyclesCB[256] =
45 {
46    8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
47    8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
48    8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
49    8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
50    8, 8, 8, 8, 8, 8,12, 8, 8, 8, 8, 8, 8, 8,12, 8,
51    8, 8, 8, 8, 8, 8,12, 8, 8, 8, 8, 8, 8, 8,12, 8,
52    8, 8, 8, 8, 8, 8,12, 8, 8, 8, 8, 8, 8, 8,12, 8,
53    8, 8, 8, 8, 8, 8,12, 8, 8, 8, 8, 8, 8, 8,12, 8,
54    8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
55    8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
56    8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
57    8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
58    8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
59    8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
60    8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
61    8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8
62 };
63 
64 static byte z80_CyclesED[256] =
65 {
66    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
67    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
68    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
69    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
70   12,12,15,20, 8,14, 8, 9,12,12,15,20, 0,14, 0, 9,
71   12,12,15,20, 0, 0, 8, 9,12,12,15,20, 0, 0, 8, 9,
72   12,12,15,20, 0, 0, 0,18,12,12,15,20, 0, 0, 0,18,
73   12, 0,15,20, 0, 0, 0, 0,12,12,15,20, 0, 0, 0, 0,
74    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
75    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
76   16,16,16,16, 0, 0, 0, 0,16,16,16,16, 0, 0, 0, 0,
77    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
78    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
79    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
80    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
81    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
82 };
83 
84 static byte z80_CyclesXX[256] =
85 {
86    0, 0, 0, 0, 0, 0, 0, 0, 0,15, 0, 0, 0, 0, 0, 0,
87    0, 0, 0, 0, 0, 0, 0, 0, 0,15, 0, 0, 0, 0, 0, 0,
88    0,14,20,10, 9, 9, 9, 0, 0,15,20,10, 9, 9, 9, 0,
89    0, 0, 0, 0,23,23,19, 0, 0,15, 0, 0, 0, 0, 0, 0,
90    0, 0, 0, 0, 9, 9,19, 0, 0, 0, 0, 0, 9, 9,19, 0,
91    0, 0, 0, 0, 9, 9,19, 0, 0, 0, 0, 0, 9, 9,19, 0,
92    9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
93   19,19,19,19,19,19,19,19, 0, 0, 0, 0, 9, 9,19, 0,
94    0, 0, 0, 0, 9, 9,19, 0, 0, 0, 0, 0, 9, 9,19, 0,
95    0, 0, 0, 0, 9, 9,19, 0, 0, 0, 0, 0, 9, 9,19, 0,
96    0, 0, 0, 0, 9, 9,19, 0, 0, 0, 0, 0, 9, 9,19, 0,
97    0, 0, 0, 0, 9, 9,19, 0, 0, 0, 0, 0, 9, 9,19, 0,
98    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
99    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
100    0,14, 0,23, 0,15, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0,
101    0, 0, 0, 0, 0, 0, 0, 0, 0,10, 0, 0, 0, 0, 0, 0
102 };
103 
104 static byte z80_CyclesXXCB[256] =
105 {
106    0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0,
107    0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0,
108    0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0,
109    0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0,
110   20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
111   20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
112   20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
113   20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
114    0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0,
115    0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0,
116    0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0,
117    0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0,
118    0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0,
119    0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0,
120    0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0,
121    0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0
122 };
123 
124 static byte ZSTable[256] =
125 {
126   Z_FLAG,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
127   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
128   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
129   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
130   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
131   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
132   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
133   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
134   S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
135   S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
136   S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
137   S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
138   S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
139   S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
140   S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
141   S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
142   S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
143   S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
144   S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
145   S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
146   S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
147   S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
148   S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,
149   S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG,S_FLAG
150 };
151 
152 static byte PZSTable[256] =
153 {
154   Z_FLAG|P_FLAG,0,0,P_FLAG,0,P_FLAG,P_FLAG,0,
155   0,P_FLAG,P_FLAG,0,P_FLAG,0,0,P_FLAG,
156   0,P_FLAG,P_FLAG,0,P_FLAG,0,0,P_FLAG,P_FLAG,0,0,P_FLAG,0,P_FLAG,P_FLAG,0,
157   0,P_FLAG,P_FLAG,0,P_FLAG,0,0,P_FLAG,P_FLAG,0,0,P_FLAG,0,P_FLAG,P_FLAG,0,
158   P_FLAG,0,0,P_FLAG,0,P_FLAG,P_FLAG,0,0,P_FLAG,P_FLAG,0,P_FLAG,0,0,P_FLAG,
159   0,P_FLAG,P_FLAG,0,P_FLAG,0,0,P_FLAG,P_FLAG,0,0,P_FLAG,0,P_FLAG,P_FLAG,0,
160   P_FLAG,0,0,P_FLAG,0,P_FLAG,P_FLAG,0,0,P_FLAG,P_FLAG,0,P_FLAG,0,0,P_FLAG,
161   P_FLAG,0,0,P_FLAG,0,P_FLAG,P_FLAG,0,0,P_FLAG,P_FLAG,0,P_FLAG,0,0,P_FLAG,
162   0,P_FLAG,P_FLAG,0,P_FLAG,0,0,P_FLAG,P_FLAG,0,0,P_FLAG,0,P_FLAG,P_FLAG,0,
163   S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
164   S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
165   S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
166   S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
167   S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
168   S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
169   S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
170   S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
171   S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
172   S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
173   S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
174   S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
175   S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
176   S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
177   S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
178   S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
179   S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
180   S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
181   S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
182   S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
183   S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
184   S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
185   S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
186   S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
187   S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
188   S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
189   S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
190   S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
191   S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG,
192   S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
193   S_FLAG,S_FLAG|P_FLAG,S_FLAG|P_FLAG,S_FLAG,
194   S_FLAG|P_FLAG,S_FLAG,S_FLAG,S_FLAG|P_FLAG
195 };
196 
197 static word DAATable[2048] =
198 {
199   0x0044,0x0100,0x0200,0x0304,0x0400,0x0504,0x0604,0x0700,
200   0x0808,0x090C,0x1010,0x1114,0x1214,0x1310,0x1414,0x1510,
201   0x1000,0x1104,0x1204,0x1300,0x1404,0x1500,0x1600,0x1704,
202   0x180C,0x1908,0x2030,0x2134,0x2234,0x2330,0x2434,0x2530,
203   0x2020,0x2124,0x2224,0x2320,0x2424,0x2520,0x2620,0x2724,
204   0x282C,0x2928,0x3034,0x3130,0x3230,0x3334,0x3430,0x3534,
205   0x3024,0x3120,0x3220,0x3324,0x3420,0x3524,0x3624,0x3720,
206   0x3828,0x392C,0x4010,0x4114,0x4214,0x4310,0x4414,0x4510,
207   0x4000,0x4104,0x4204,0x4300,0x4404,0x4500,0x4600,0x4704,
208   0x480C,0x4908,0x5014,0x5110,0x5210,0x5314,0x5410,0x5514,
209   0x5004,0x5100,0x5200,0x5304,0x5400,0x5504,0x5604,0x5700,
210   0x5808,0x590C,0x6034,0x6130,0x6230,0x6334,0x6430,0x6534,
211   0x6024,0x6120,0x6220,0x6324,0x6420,0x6524,0x6624,0x6720,
212   0x6828,0x692C,0x7030,0x7134,0x7234,0x7330,0x7434,0x7530,
213   0x7020,0x7124,0x7224,0x7320,0x7424,0x7520,0x7620,0x7724,
214   0x782C,0x7928,0x8090,0x8194,0x8294,0x8390,0x8494,0x8590,
215   0x8080,0x8184,0x8284,0x8380,0x8484,0x8580,0x8680,0x8784,
216   0x888C,0x8988,0x9094,0x9190,0x9290,0x9394,0x9490,0x9594,
217   0x9084,0x9180,0x9280,0x9384,0x9480,0x9584,0x9684,0x9780,
218   0x9888,0x998C,0x0055,0x0111,0x0211,0x0315,0x0411,0x0515,
219   0x0045,0x0101,0x0201,0x0305,0x0401,0x0505,0x0605,0x0701,
220   0x0809,0x090D,0x1011,0x1115,0x1215,0x1311,0x1415,0x1511,
221   0x1001,0x1105,0x1205,0x1301,0x1405,0x1501,0x1601,0x1705,
222   0x180D,0x1909,0x2031,0x2135,0x2235,0x2331,0x2435,0x2531,
223   0x2021,0x2125,0x2225,0x2321,0x2425,0x2521,0x2621,0x2725,
224   0x282D,0x2929,0x3035,0x3131,0x3231,0x3335,0x3431,0x3535,
225   0x3025,0x3121,0x3221,0x3325,0x3421,0x3525,0x3625,0x3721,
226   0x3829,0x392D,0x4011,0x4115,0x4215,0x4311,0x4415,0x4511,
227   0x4001,0x4105,0x4205,0x4301,0x4405,0x4501,0x4601,0x4705,
228   0x480D,0x4909,0x5015,0x5111,0x5211,0x5315,0x5411,0x5515,
229   0x5005,0x5101,0x5201,0x5305,0x5401,0x5505,0x5605,0x5701,
230   0x5809,0x590D,0x6035,0x6131,0x6231,0x6335,0x6431,0x6535,
231   0x6025,0x6121,0x6221,0x6325,0x6421,0x6525,0x6625,0x6721,
232   0x6829,0x692D,0x7031,0x7135,0x7235,0x7331,0x7435,0x7531,
233   0x7021,0x7125,0x7225,0x7321,0x7425,0x7521,0x7621,0x7725,
234   0x782D,0x7929,0x8091,0x8195,0x8295,0x8391,0x8495,0x8591,
235   0x8081,0x8185,0x8285,0x8381,0x8485,0x8581,0x8681,0x8785,
236   0x888D,0x8989,0x9095,0x9191,0x9291,0x9395,0x9491,0x9595,
237   0x9085,0x9181,0x9281,0x9385,0x9481,0x9585,0x9685,0x9781,
238   0x9889,0x998D,0xA0B5,0xA1B1,0xA2B1,0xA3B5,0xA4B1,0xA5B5,
239   0xA0A5,0xA1A1,0xA2A1,0xA3A5,0xA4A1,0xA5A5,0xA6A5,0xA7A1,
240   0xA8A9,0xA9AD,0xB0B1,0xB1B5,0xB2B5,0xB3B1,0xB4B5,0xB5B1,
241   0xB0A1,0xB1A5,0xB2A5,0xB3A1,0xB4A5,0xB5A1,0xB6A1,0xB7A5,
242   0xB8AD,0xB9A9,0xC095,0xC191,0xC291,0xC395,0xC491,0xC595,
243   0xC085,0xC181,0xC281,0xC385,0xC481,0xC585,0xC685,0xC781,
244   0xC889,0xC98D,0xD091,0xD195,0xD295,0xD391,0xD495,0xD591,
245   0xD081,0xD185,0xD285,0xD381,0xD485,0xD581,0xD681,0xD785,
246   0xD88D,0xD989,0xE0B1,0xE1B5,0xE2B5,0xE3B1,0xE4B5,0xE5B1,
247   0xE0A1,0xE1A5,0xE2A5,0xE3A1,0xE4A5,0xE5A1,0xE6A1,0xE7A5,
248   0xE8AD,0xE9A9,0xF0B5,0xF1B1,0xF2B1,0xF3B5,0xF4B1,0xF5B5,
249   0xF0A5,0xF1A1,0xF2A1,0xF3A5,0xF4A1,0xF5A5,0xF6A5,0xF7A1,
250   0xF8A9,0xF9AD,0x0055,0x0111,0x0211,0x0315,0x0411,0x0515,
251   0x0045,0x0101,0x0201,0x0305,0x0401,0x0505,0x0605,0x0701,
252   0x0809,0x090D,0x1011,0x1115,0x1215,0x1311,0x1415,0x1511,
253   0x1001,0x1105,0x1205,0x1301,0x1405,0x1501,0x1601,0x1705,
254   0x180D,0x1909,0x2031,0x2135,0x2235,0x2331,0x2435,0x2531,
255   0x2021,0x2125,0x2225,0x2321,0x2425,0x2521,0x2621,0x2725,
256   0x282D,0x2929,0x3035,0x3131,0x3231,0x3335,0x3431,0x3535,
257   0x3025,0x3121,0x3221,0x3325,0x3421,0x3525,0x3625,0x3721,
258   0x3829,0x392D,0x4011,0x4115,0x4215,0x4311,0x4415,0x4511,
259   0x4001,0x4105,0x4205,0x4301,0x4405,0x4501,0x4601,0x4705,
260   0x480D,0x4909,0x5015,0x5111,0x5211,0x5315,0x5411,0x5515,
261   0x5005,0x5101,0x5201,0x5305,0x5401,0x5505,0x5605,0x5701,
262   0x5809,0x590D,0x6035,0x6131,0x6231,0x6335,0x6431,0x6535,
263   0x0604,0x0700,0x0808,0x090C,0x0A0C,0x0B08,0x0C0C,0x0D08,
264   0x0E08,0x0F0C,0x1010,0x1114,0x1214,0x1310,0x1414,0x1510,
265   0x1600,0x1704,0x180C,0x1908,0x1A08,0x1B0C,0x1C08,0x1D0C,
266   0x1E0C,0x1F08,0x2030,0x2134,0x2234,0x2330,0x2434,0x2530,
267   0x2620,0x2724,0x282C,0x2928,0x2A28,0x2B2C,0x2C28,0x2D2C,
268   0x2E2C,0x2F28,0x3034,0x3130,0x3230,0x3334,0x3430,0x3534,
269   0x3624,0x3720,0x3828,0x392C,0x3A2C,0x3B28,0x3C2C,0x3D28,
270   0x3E28,0x3F2C,0x4010,0x4114,0x4214,0x4310,0x4414,0x4510,
271   0x4600,0x4704,0x480C,0x4908,0x4A08,0x4B0C,0x4C08,0x4D0C,
272   0x4E0C,0x4F08,0x5014,0x5110,0x5210,0x5314,0x5410,0x5514,
273   0x5604,0x5700,0x5808,0x590C,0x5A0C,0x5B08,0x5C0C,0x5D08,
274   0x5E08,0x5F0C,0x6034,0x6130,0x6230,0x6334,0x6430,0x6534,
275   0x6624,0x6720,0x6828,0x692C,0x6A2C,0x6B28,0x6C2C,0x6D28,
276   0x6E28,0x6F2C,0x7030,0x7134,0x7234,0x7330,0x7434,0x7530,
277   0x7620,0x7724,0x782C,0x7928,0x7A28,0x7B2C,0x7C28,0x7D2C,
278   0x7E2C,0x7F28,0x8090,0x8194,0x8294,0x8390,0x8494,0x8590,
279   0x8680,0x8784,0x888C,0x8988,0x8A88,0x8B8C,0x8C88,0x8D8C,
280   0x8E8C,0x8F88,0x9094,0x9190,0x9290,0x9394,0x9490,0x9594,
281   0x9684,0x9780,0x9888,0x998C,0x9A8C,0x9B88,0x9C8C,0x9D88,
282   0x9E88,0x9F8C,0x0055,0x0111,0x0211,0x0315,0x0411,0x0515,
283   0x0605,0x0701,0x0809,0x090D,0x0A0D,0x0B09,0x0C0D,0x0D09,
284   0x0E09,0x0F0D,0x1011,0x1115,0x1215,0x1311,0x1415,0x1511,
285   0x1601,0x1705,0x180D,0x1909,0x1A09,0x1B0D,0x1C09,0x1D0D,
286   0x1E0D,0x1F09,0x2031,0x2135,0x2235,0x2331,0x2435,0x2531,
287   0x2621,0x2725,0x282D,0x2929,0x2A29,0x2B2D,0x2C29,0x2D2D,
288   0x2E2D,0x2F29,0x3035,0x3131,0x3231,0x3335,0x3431,0x3535,
289   0x3625,0x3721,0x3829,0x392D,0x3A2D,0x3B29,0x3C2D,0x3D29,
290   0x3E29,0x3F2D,0x4011,0x4115,0x4215,0x4311,0x4415,0x4511,
291   0x4601,0x4705,0x480D,0x4909,0x4A09,0x4B0D,0x4C09,0x4D0D,
292   0x4E0D,0x4F09,0x5015,0x5111,0x5211,0x5315,0x5411,0x5515,
293   0x5605,0x5701,0x5809,0x590D,0x5A0D,0x5B09,0x5C0D,0x5D09,
294   0x5E09,0x5F0D,0x6035,0x6131,0x6231,0x6335,0x6431,0x6535,
295   0x6625,0x6721,0x6829,0x692D,0x6A2D,0x6B29,0x6C2D,0x6D29,
296   0x6E29,0x6F2D,0x7031,0x7135,0x7235,0x7331,0x7435,0x7531,
297   0x7621,0x7725,0x782D,0x7929,0x7A29,0x7B2D,0x7C29,0x7D2D,
298   0x7E2D,0x7F29,0x8091,0x8195,0x8295,0x8391,0x8495,0x8591,
299   0x8681,0x8785,0x888D,0x8989,0x8A89,0x8B8D,0x8C89,0x8D8D,
300   0x8E8D,0x8F89,0x9095,0x9191,0x9291,0x9395,0x9491,0x9595,
301   0x9685,0x9781,0x9889,0x998D,0x9A8D,0x9B89,0x9C8D,0x9D89,
302   0x9E89,0x9F8D,0xA0B5,0xA1B1,0xA2B1,0xA3B5,0xA4B1,0xA5B5,
303   0xA6A5,0xA7A1,0xA8A9,0xA9AD,0xAAAD,0xABA9,0xACAD,0xADA9,
304   0xAEA9,0xAFAD,0xB0B1,0xB1B5,0xB2B5,0xB3B1,0xB4B5,0xB5B1,
305   0xB6A1,0xB7A5,0xB8AD,0xB9A9,0xBAA9,0xBBAD,0xBCA9,0xBDAD,
306   0xBEAD,0xBFA9,0xC095,0xC191,0xC291,0xC395,0xC491,0xC595,
307   0xC685,0xC781,0xC889,0xC98D,0xCA8D,0xCB89,0xCC8D,0xCD89,
308   0xCE89,0xCF8D,0xD091,0xD195,0xD295,0xD391,0xD495,0xD591,
309   0xD681,0xD785,0xD88D,0xD989,0xDA89,0xDB8D,0xDC89,0xDD8D,
310   0xDE8D,0xDF89,0xE0B1,0xE1B5,0xE2B5,0xE3B1,0xE4B5,0xE5B1,
311   0xE6A1,0xE7A5,0xE8AD,0xE9A9,0xEAA9,0xEBAD,0xECA9,0xEDAD,
312   0xEEAD,0xEFA9,0xF0B5,0xF1B1,0xF2B1,0xF3B5,0xF4B1,0xF5B5,
313   0xF6A5,0xF7A1,0xF8A9,0xF9AD,0xFAAD,0xFBA9,0xFCAD,0xFDA9,
314   0xFEA9,0xFFAD,0x0055,0x0111,0x0211,0x0315,0x0411,0x0515,
315   0x0605,0x0701,0x0809,0x090D,0x0A0D,0x0B09,0x0C0D,0x0D09,
316   0x0E09,0x0F0D,0x1011,0x1115,0x1215,0x1311,0x1415,0x1511,
317   0x1601,0x1705,0x180D,0x1909,0x1A09,0x1B0D,0x1C09,0x1D0D,
318   0x1E0D,0x1F09,0x2031,0x2135,0x2235,0x2331,0x2435,0x2531,
319   0x2621,0x2725,0x282D,0x2929,0x2A29,0x2B2D,0x2C29,0x2D2D,
320   0x2E2D,0x2F29,0x3035,0x3131,0x3231,0x3335,0x3431,0x3535,
321   0x3625,0x3721,0x3829,0x392D,0x3A2D,0x3B29,0x3C2D,0x3D29,
322   0x3E29,0x3F2D,0x4011,0x4115,0x4215,0x4311,0x4415,0x4511,
323   0x4601,0x4705,0x480D,0x4909,0x4A09,0x4B0D,0x4C09,0x4D0D,
324   0x4E0D,0x4F09,0x5015,0x5111,0x5211,0x5315,0x5411,0x5515,
325   0x5605,0x5701,0x5809,0x590D,0x5A0D,0x5B09,0x5C0D,0x5D09,
326   0x5E09,0x5F0D,0x6035,0x6131,0x6231,0x6335,0x6431,0x6535,
327   0x0046,0x0102,0x0202,0x0306,0x0402,0x0506,0x0606,0x0702,
328   0x080A,0x090E,0x0402,0x0506,0x0606,0x0702,0x080A,0x090E,
329   0x1002,0x1106,0x1206,0x1302,0x1406,0x1502,0x1602,0x1706,
330   0x180E,0x190A,0x1406,0x1502,0x1602,0x1706,0x180E,0x190A,
331   0x2022,0x2126,0x2226,0x2322,0x2426,0x2522,0x2622,0x2726,
332   0x282E,0x292A,0x2426,0x2522,0x2622,0x2726,0x282E,0x292A,
333   0x3026,0x3122,0x3222,0x3326,0x3422,0x3526,0x3626,0x3722,
334   0x382A,0x392E,0x3422,0x3526,0x3626,0x3722,0x382A,0x392E,
335   0x4002,0x4106,0x4206,0x4302,0x4406,0x4502,0x4602,0x4706,
336   0x480E,0x490A,0x4406,0x4502,0x4602,0x4706,0x480E,0x490A,
337   0x5006,0x5102,0x5202,0x5306,0x5402,0x5506,0x5606,0x5702,
338   0x580A,0x590E,0x5402,0x5506,0x5606,0x5702,0x580A,0x590E,
339   0x6026,0x6122,0x6222,0x6326,0x6422,0x6526,0x6626,0x6722,
340   0x682A,0x692E,0x6422,0x6526,0x6626,0x6722,0x682A,0x692E,
341   0x7022,0x7126,0x7226,0x7322,0x7426,0x7522,0x7622,0x7726,
342   0x782E,0x792A,0x7426,0x7522,0x7622,0x7726,0x782E,0x792A,
343   0x8082,0x8186,0x8286,0x8382,0x8486,0x8582,0x8682,0x8786,
344   0x888E,0x898A,0x8486,0x8582,0x8682,0x8786,0x888E,0x898A,
345   0x9086,0x9182,0x9282,0x9386,0x9482,0x9586,0x9686,0x9782,
346   0x988A,0x998E,0x3423,0x3527,0x3627,0x3723,0x382B,0x392F,
347   0x4003,0x4107,0x4207,0x4303,0x4407,0x4503,0x4603,0x4707,
348   0x480F,0x490B,0x4407,0x4503,0x4603,0x4707,0x480F,0x490B,
349   0x5007,0x5103,0x5203,0x5307,0x5403,0x5507,0x5607,0x5703,
350   0x580B,0x590F,0x5403,0x5507,0x5607,0x5703,0x580B,0x590F,
351   0x6027,0x6123,0x6223,0x6327,0x6423,0x6527,0x6627,0x6723,
352   0x682B,0x692F,0x6423,0x6527,0x6627,0x6723,0x682B,0x692F,
353   0x7023,0x7127,0x7227,0x7323,0x7427,0x7523,0x7623,0x7727,
354   0x782F,0x792B,0x7427,0x7523,0x7623,0x7727,0x782F,0x792B,
355   0x8083,0x8187,0x8287,0x8383,0x8487,0x8583,0x8683,0x8787,
356   0x888F,0x898B,0x8487,0x8583,0x8683,0x8787,0x888F,0x898B,
357   0x9087,0x9183,0x9283,0x9387,0x9483,0x9587,0x9687,0x9783,
358   0x988B,0x998F,0x9483,0x9587,0x9687,0x9783,0x988B,0x998F,
359   0xA0A7,0xA1A3,0xA2A3,0xA3A7,0xA4A3,0xA5A7,0xA6A7,0xA7A3,
360   0xA8AB,0xA9AF,0xA4A3,0xA5A7,0xA6A7,0xA7A3,0xA8AB,0xA9AF,
361   0xB0A3,0xB1A7,0xB2A7,0xB3A3,0xB4A7,0xB5A3,0xB6A3,0xB7A7,
362   0xB8AF,0xB9AB,0xB4A7,0xB5A3,0xB6A3,0xB7A7,0xB8AF,0xB9AB,
363   0xC087,0xC183,0xC283,0xC387,0xC483,0xC587,0xC687,0xC783,
364   0xC88B,0xC98F,0xC483,0xC587,0xC687,0xC783,0xC88B,0xC98F,
365   0xD083,0xD187,0xD287,0xD383,0xD487,0xD583,0xD683,0xD787,
366   0xD88F,0xD98B,0xD487,0xD583,0xD683,0xD787,0xD88F,0xD98B,
367   0xE0A3,0xE1A7,0xE2A7,0xE3A3,0xE4A7,0xE5A3,0xE6A3,0xE7A7,
368   0xE8AF,0xE9AB,0xE4A7,0xE5A3,0xE6A3,0xE7A7,0xE8AF,0xE9AB,
369   0xF0A7,0xF1A3,0xF2A3,0xF3A7,0xF4A3,0xF5A7,0xF6A7,0xF7A3,
370   0xF8AB,0xF9AF,0xF4A3,0xF5A7,0xF6A7,0xF7A3,0xF8AB,0xF9AF,
371   0x0047,0x0103,0x0203,0x0307,0x0403,0x0507,0x0607,0x0703,
372   0x080B,0x090F,0x0403,0x0507,0x0607,0x0703,0x080B,0x090F,
373   0x1003,0x1107,0x1207,0x1303,0x1407,0x1503,0x1603,0x1707,
374   0x180F,0x190B,0x1407,0x1503,0x1603,0x1707,0x180F,0x190B,
375   0x2023,0x2127,0x2227,0x2323,0x2427,0x2523,0x2623,0x2727,
376   0x282F,0x292B,0x2427,0x2523,0x2623,0x2727,0x282F,0x292B,
377   0x3027,0x3123,0x3223,0x3327,0x3423,0x3527,0x3627,0x3723,
378   0x382B,0x392F,0x3423,0x3527,0x3627,0x3723,0x382B,0x392F,
379   0x4003,0x4107,0x4207,0x4303,0x4407,0x4503,0x4603,0x4707,
380   0x480F,0x490B,0x4407,0x4503,0x4603,0x4707,0x480F,0x490B,
381   0x5007,0x5103,0x5203,0x5307,0x5403,0x5507,0x5607,0x5703,
382   0x580B,0x590F,0x5403,0x5507,0x5607,0x5703,0x580B,0x590F,
383   0x6027,0x6123,0x6223,0x6327,0x6423,0x6527,0x6627,0x6723,
384   0x682B,0x692F,0x6423,0x6527,0x6627,0x6723,0x682B,0x692F,
385   0x7023,0x7127,0x7227,0x7323,0x7427,0x7523,0x7623,0x7727,
386   0x782F,0x792B,0x7427,0x7523,0x7623,0x7727,0x782F,0x792B,
387   0x8083,0x8187,0x8287,0x8383,0x8487,0x8583,0x8683,0x8787,
388   0x888F,0x898B,0x8487,0x8583,0x8683,0x8787,0x888F,0x898B,
389   0x9087,0x9183,0x9283,0x9387,0x9483,0x9587,0x9687,0x9783,
390   0x988B,0x998F,0x9483,0x9587,0x9687,0x9783,0x988B,0x998F,
391   0xFABE,0xFBBA,0xFCBE,0xFDBA,0xFEBA,0xFFBE,0x0046,0x0102,
392   0x0202,0x0306,0x0402,0x0506,0x0606,0x0702,0x080A,0x090E,
393   0x0A1E,0x0B1A,0x0C1E,0x0D1A,0x0E1A,0x0F1E,0x1002,0x1106,
394   0x1206,0x1302,0x1406,0x1502,0x1602,0x1706,0x180E,0x190A,
395   0x1A1A,0x1B1E,0x1C1A,0x1D1E,0x1E1E,0x1F1A,0x2022,0x2126,
396   0x2226,0x2322,0x2426,0x2522,0x2622,0x2726,0x282E,0x292A,
397   0x2A3A,0x2B3E,0x2C3A,0x2D3E,0x2E3E,0x2F3A,0x3026,0x3122,
398   0x3222,0x3326,0x3422,0x3526,0x3626,0x3722,0x382A,0x392E,
399   0x3A3E,0x3B3A,0x3C3E,0x3D3A,0x3E3A,0x3F3E,0x4002,0x4106,
400   0x4206,0x4302,0x4406,0x4502,0x4602,0x4706,0x480E,0x490A,
401   0x4A1A,0x4B1E,0x4C1A,0x4D1E,0x4E1E,0x4F1A,0x5006,0x5102,
402   0x5202,0x5306,0x5402,0x5506,0x5606,0x5702,0x580A,0x590E,
403   0x5A1E,0x5B1A,0x5C1E,0x5D1A,0x5E1A,0x5F1E,0x6026,0x6122,
404   0x6222,0x6326,0x6422,0x6526,0x6626,0x6722,0x682A,0x692E,
405   0x6A3E,0x6B3A,0x6C3E,0x6D3A,0x6E3A,0x6F3E,0x7022,0x7126,
406   0x7226,0x7322,0x7426,0x7522,0x7622,0x7726,0x782E,0x792A,
407   0x7A3A,0x7B3E,0x7C3A,0x7D3E,0x7E3E,0x7F3A,0x8082,0x8186,
408   0x8286,0x8382,0x8486,0x8582,0x8682,0x8786,0x888E,0x898A,
409   0x8A9A,0x8B9E,0x8C9A,0x8D9E,0x8E9E,0x8F9A,0x9086,0x9182,
410   0x9282,0x9386,0x3423,0x3527,0x3627,0x3723,0x382B,0x392F,
411   0x3A3F,0x3B3B,0x3C3F,0x3D3B,0x3E3B,0x3F3F,0x4003,0x4107,
412   0x4207,0x4303,0x4407,0x4503,0x4603,0x4707,0x480F,0x490B,
413   0x4A1B,0x4B1F,0x4C1B,0x4D1F,0x4E1F,0x4F1B,0x5007,0x5103,
414   0x5203,0x5307,0x5403,0x5507,0x5607,0x5703,0x580B,0x590F,
415   0x5A1F,0x5B1B,0x5C1F,0x5D1B,0x5E1B,0x5F1F,0x6027,0x6123,
416   0x6223,0x6327,0x6423,0x6527,0x6627,0x6723,0x682B,0x692F,
417   0x6A3F,0x6B3B,0x6C3F,0x6D3B,0x6E3B,0x6F3F,0x7023,0x7127,
418   0x7227,0x7323,0x7427,0x7523,0x7623,0x7727,0x782F,0x792B,
419   0x7A3B,0x7B3F,0x7C3B,0x7D3F,0x7E3F,0x7F3B,0x8083,0x8187,
420   0x8287,0x8383,0x8487,0x8583,0x8683,0x8787,0x888F,0x898B,
421   0x8A9B,0x8B9F,0x8C9B,0x8D9F,0x8E9F,0x8F9B,0x9087,0x9183,
422   0x9283,0x9387,0x9483,0x9587,0x9687,0x9783,0x988B,0x998F,
423   0x9A9F,0x9B9B,0x9C9F,0x9D9B,0x9E9B,0x9F9F,0xA0A7,0xA1A3,
424   0xA2A3,0xA3A7,0xA4A3,0xA5A7,0xA6A7,0xA7A3,0xA8AB,0xA9AF,
425   0xAABF,0xABBB,0xACBF,0xADBB,0xAEBB,0xAFBF,0xB0A3,0xB1A7,
426   0xB2A7,0xB3A3,0xB4A7,0xB5A3,0xB6A3,0xB7A7,0xB8AF,0xB9AB,
427   0xBABB,0xBBBF,0xBCBB,0xBDBF,0xBEBF,0xBFBB,0xC087,0xC183,
428   0xC283,0xC387,0xC483,0xC587,0xC687,0xC783,0xC88B,0xC98F,
429   0xCA9F,0xCB9B,0xCC9F,0xCD9B,0xCE9B,0xCF9F,0xD083,0xD187,
430   0xD287,0xD383,0xD487,0xD583,0xD683,0xD787,0xD88F,0xD98B,
431   0xDA9B,0xDB9F,0xDC9B,0xDD9F,0xDE9F,0xDF9B,0xE0A3,0xE1A7,
432   0xE2A7,0xE3A3,0xE4A7,0xE5A3,0xE6A3,0xE7A7,0xE8AF,0xE9AB,
433   0xEABB,0xEBBF,0xECBB,0xEDBF,0xEEBF,0xEFBB,0xF0A7,0xF1A3,
434   0xF2A3,0xF3A7,0xF4A3,0xF5A7,0xF6A7,0xF7A3,0xF8AB,0xF9AF,
435   0xFABF,0xFBBB,0xFCBF,0xFDBB,0xFEBB,0xFFBF,0x0047,0x0103,
436   0x0203,0x0307,0x0403,0x0507,0x0607,0x0703,0x080B,0x090F,
437   0x0A1F,0x0B1B,0x0C1F,0x0D1B,0x0E1B,0x0F1F,0x1003,0x1107,
438   0x1207,0x1303,0x1407,0x1503,0x1603,0x1707,0x180F,0x190B,
439   0x1A1B,0x1B1F,0x1C1B,0x1D1F,0x1E1F,0x1F1B,0x2023,0x2127,
440   0x2227,0x2323,0x2427,0x2523,0x2623,0x2727,0x282F,0x292B,
441   0x2A3B,0x2B3F,0x2C3B,0x2D3F,0x2E3F,0x2F3B,0x3027,0x3123,
442   0x3223,0x3327,0x3423,0x3527,0x3627,0x3723,0x382B,0x392F,
443   0x3A3F,0x3B3B,0x3C3F,0x3D3B,0x3E3B,0x3F3F,0x4003,0x4107,
444   0x4207,0x4303,0x4407,0x4503,0x4603,0x4707,0x480F,0x490B,
445   0x4A1B,0x4B1F,0x4C1B,0x4D1F,0x4E1F,0x4F1B,0x5007,0x5103,
446   0x5203,0x5307,0x5403,0x5507,0x5607,0x5703,0x580B,0x590F,
447   0x5A1F,0x5B1B,0x5C1F,0x5D1B,0x5E1B,0x5F1F,0x6027,0x6123,
448   0x6223,0x6327,0x6423,0x6527,0x6627,0x6723,0x682B,0x692F,
449   0x6A3F,0x6B3B,0x6C3F,0x6D3B,0x6E3B,0x6F3F,0x7023,0x7127,
450   0x7227,0x7323,0x7427,0x7523,0x7623,0x7727,0x782F,0x792B,
451   0x7A3B,0x7B3F,0x7C3B,0x7D3F,0x7E3F,0x7F3B,0x8083,0x8187,
452   0x8287,0x8383,0x8487,0x8583,0x8683,0x8787,0x888F,0x898B,
453   0x8A9B,0x8B9F,0x8C9B,0x8D9F,0x8E9F,0x8F9B,0x9087,0x9183,
454   0x9283,0x9387,0x9483,0x9587,0x9687,0x9783,0x988B,0x998F
455 };
456 
457 /** INLINE ***************************************************/
458 /** Different compilers inline C functions differently.     **/
459 /*************************************************************/
460 #ifdef __GNUC__
461 #define INLINE inline
462 #else
463 #define INLINE static
464 #endif
465 
466 /** System-Dependent Stuff ***********************************/
467 /** This is system-dependent code put here to speed things  **/
468 /** up. It has to stay inlined to be fast.                  **/
469 /*************************************************************/
470 #define WrZ80(addr, value) (R->writefunc(R->User, addr, value))
471 #define RdZ80(addr) (R->readfunc(R->User, addr))
472 
mz80_cache_ip(Z80 * R)473 void mz80_cache_ip(Z80 *R)
474 {
475     ranged_mmu *mmu;
476 
477     mmu = R->mmu;
478 
479     while (mmu->end < R->PC.W) {
480 	mmu++;
481     }
482 
483     if (mmu->start > R->PC.W) {
484 	deb_printf("mz80.c: mz80_cache_ip(): Region not in MMU.\n");
485 	deb_printf("    Now crashing system.\n");
486     }
487 
488     R->cur_ip = mmu->data + R->PC.W;
489     R->ip_left = mmu->end - R->PC.W;
490 }
491 
492 #if 1
OpZ80(Z80 * R)493 INLINE unsigned char OpZ80(Z80 *R)
494 {
495     unsigned char retval;
496 
497     retval = *R->cur_ip++;
498 
499     R->PC.W++;
500 
501     if (!R->ip_left--) {
502 	mz80_cache_ip(R);
503     }
504 
505     return retval;
506 }
507 
OpZ80_1(Z80 * R)508 INLINE void OpZ80_1(Z80 *R)
509 {
510     R->PC.W++;
511     R->cur_ip++;
512     if (!R->ip_left--) {
513 	mz80_cache_ip(R);
514     }
515 }
516 
OpZ80_2(Z80 * R)517 INLINE void OpZ80_2(Z80 *R)
518 {
519     R->PC.W+=2;
520     if (R->ip_left < 2) {
521 	mz80_cache_ip(R);
522     } else {
523 	R->ip_left -= 2;
524 	R->cur_ip += 2;
525     }
526 }
527 #else
OpZ80(Z80 * R)528 INLINE unsigned char OpZ80(Z80 *R)
529 {
530     return RdZ80(R->PC.W++);
531 }
532 
OpZ80_1(Z80 * R)533 INLINE void OpZ80_1(Z80 *R)
534 {
535     R->PC.W++;
536 }
537 
OpZ80_2(Z80 * R)538 INLINE void OpZ80_2(Z80 *R)
539 {
540     R->PC.W+=2;
541 }
542 #endif
543 
544 #define S(Fl)        R->AF.B.l|=Fl
545 #define R(Fl)        R->AF.B.l&=~(Fl)
546 #define FLAGS(Rg,Fl) R->AF.B.l=Fl|ZSTable[Rg]
547 
548 #define M_RLC(Rg)      \
549   R->AF.B.l=Rg>>7;Rg=(Rg<<1)|R->AF.B.l;R->AF.B.l|=PZSTable[Rg]
550 #define M_RRC(Rg)      \
551   R->AF.B.l=Rg&0x01;Rg=(Rg>>1)|(R->AF.B.l<<7);R->AF.B.l|=PZSTable[Rg]
552 #define M_RL(Rg)       \
553   if(Rg&0x80)          \
554   {                    \
555     Rg=(Rg<<1)|(R->AF.B.l&C_FLAG); \
556     R->AF.B.l=PZSTable[Rg]|C_FLAG; \
557   }                    \
558   else                 \
559   {                    \
560     Rg=(Rg<<1)|(R->AF.B.l&C_FLAG); \
561     R->AF.B.l=PZSTable[Rg];        \
562   }
563 #define M_RR(Rg)       \
564   if(Rg&0x01)          \
565   {                    \
566     Rg=(Rg>>1)|(R->AF.B.l<<7);     \
567     R->AF.B.l=PZSTable[Rg]|C_FLAG; \
568   }                    \
569   else                 \
570   {                    \
571     Rg=(Rg>>1)|(R->AF.B.l<<7);     \
572     R->AF.B.l=PZSTable[Rg];        \
573   }
574 
575 #define M_SLA(Rg)      \
576   R->AF.B.l=Rg>>7;Rg<<=1;R->AF.B.l|=PZSTable[Rg]
577 #define M_SRA(Rg)      \
578   R->AF.B.l=Rg&C_FLAG;Rg=(Rg>>1)|(Rg&0x80);R->AF.B.l|=PZSTable[Rg]
579 
580 #define M_SLL(Rg)      \
581   R->AF.B.l=Rg>>7;Rg=(Rg<<1)|0x01;R->AF.B.l|=PZSTable[Rg]
582 #define M_SRL(Rg)      \
583   R->AF.B.l=Rg&0x01;Rg>>=1;R->AF.B.l|=PZSTable[Rg]
584 
585 #define M_BIT(Bit,Rg)  \
586   R->AF.B.l=(R->AF.B.l&~(N_FLAG|Z_FLAG))|H_FLAG|(Rg&(1<<Bit)? 0:Z_FLAG)
587 
588 #define M_SET(Bit,Rg) Rg|=1<<Bit
589 #define M_RES(Bit,Rg) Rg&=~(1<<Bit)
590 
591 #define M_POP(Rg)      \
592   R->Rg.B.l=RdZ80(R->SP.W++);R->Rg.B.h=RdZ80(R->SP.W++)
593 #define M_PUSH(Rg)     \
594   WrZ80(--R->SP.W,R->Rg.B.h);WrZ80(--R->SP.W,R->Rg.B.l)
595 
596 #define M_CALL         \
597   J.B.l=OpZ80(R);J.B.h=OpZ80(R);         \
598   WrZ80(--R->SP.W,R->PC.B.h);WrZ80(--R->SP.W,R->PC.B.l); \
599   R->PC.W=J.W;mz80_cache_ip(R)
600 
601 #define M_JP  J.B.l=OpZ80(R);J.B.h=OpZ80(R);R->PC.W=J.W;mz80_cache_ip(R)
602 #define M_JR  J.B.l=OpZ80(R);R->PC.W+=(offset)J.B.l;mz80_cache_ip(R)
603 #define M_RET R->PC.B.l=RdZ80(R->SP.W++);R->PC.B.h=RdZ80(R->SP.W++);mz80_cache_ip(R)
604 
605 #define M_RST(Ad)      \
606   WrZ80(--R->SP.W,R->PC.B.h);WrZ80(--R->SP.W,R->PC.B.l);R->PC.W=Ad;mz80_cache_ip(R)
607 
608 #define M_LDWORD(Rg)   \
609   R->Rg.B.l=OpZ80(R);R->Rg.B.h=OpZ80(R)
610 
611 #define M_ADD(Rg)      \
612   J.W=R->AF.B.h+Rg;     \
613   R->AF.B.l=            \
614     (~(R->AF.B.h^Rg)&(Rg^J.B.l)&0x80? V_FLAG:0)| \
615     J.B.h|ZSTable[J.B.l]|                        \
616     ((R->AF.B.h^Rg^J.B.l)&H_FLAG);               \
617   R->AF.B.h=J.B.l
618 
619 #define M_SUB(Rg)      \
620   J.W=R->AF.B.h-Rg;    \
621   R->AF.B.l=           \
622     ((R->AF.B.h^Rg)&(R->AF.B.h^J.B.l)&0x80? V_FLAG:0)| \
623     N_FLAG|-J.B.h|ZSTable[J.B.l]|                      \
624     ((R->AF.B.h^Rg^J.B.l)&H_FLAG);                     \
625   R->AF.B.h=J.B.l
626 
627 #define M_ADC(Rg)      \
628   J.W=R->AF.B.h+Rg+(R->AF.B.l&C_FLAG); \
629   R->AF.B.l=                           \
630     (~(R->AF.B.h^Rg)&(Rg^J.B.l)&0x80? V_FLAG:0)| \
631     J.B.h|ZSTable[J.B.l]|              \
632     ((R->AF.B.h^Rg^J.B.l)&H_FLAG);     \
633   R->AF.B.h=J.B.l
634 
635 #define M_SBC(Rg)      \
636   J.W=R->AF.B.h-Rg-(R->AF.B.l&C_FLAG); \
637   R->AF.B.l=                           \
638     ((R->AF.B.h^Rg)&(R->AF.B.h^J.B.l)&0x80? V_FLAG:0)| \
639     N_FLAG|-J.B.h|ZSTable[J.B.l]|      \
640     ((R->AF.B.h^Rg^J.B.l)&H_FLAG);     \
641   R->AF.B.h=J.B.l
642 
643 #define M_CP(Rg)       \
644   J.W=R->AF.B.h-Rg;    \
645   R->AF.B.l=           \
646     ((R->AF.B.h^Rg)&(R->AF.B.h^J.B.l)&0x80? V_FLAG:0)| \
647     N_FLAG|-J.B.h|ZSTable[J.B.l]|                      \
648     ((R->AF.B.h^Rg^J.B.l)&H_FLAG)
649 
650 #define M_AND(Rg) R->AF.B.h&=Rg;R->AF.B.l=H_FLAG|PZSTable[R->AF.B.h]
651 #define M_OR(Rg)  R->AF.B.h|=Rg;R->AF.B.l=PZSTable[R->AF.B.h]
652 #define M_XOR(Rg) R->AF.B.h^=Rg;R->AF.B.l=PZSTable[R->AF.B.h]
653 #define M_IN(Rg)  Rg=InZ80(R->BC.B.l);R->AF.B.l=PZSTable[Rg]|(R->AF.B.l&C_FLAG)
654 
655 #define M_INC(Rg)       \
656   Rg++;                 \
657   R->AF.B.l=            \
658     (R->AF.B.l&C_FLAG)|ZSTable[Rg]|           \
659     (Rg==0x80? V_FLAG:0)|(Rg&0x0F? 0:H_FLAG)
660 
661 #define M_DEC(Rg)       \
662   Rg--;                 \
663   R->AF.B.l=            \
664     N_FLAG|(R->AF.B.l&C_FLAG)|ZSTable[Rg]| \
665     (Rg==0x7F? V_FLAG:0)|((Rg&0x0F)==0x0F? H_FLAG:0)
666 
667 #define M_ADDW(Rg1,Rg2) \
668   J.W=(R->Rg1.W+R->Rg2.W)&0xFFFF;                        \
669   R->AF.B.l=                                             \
670     (R->AF.B.l&~(H_FLAG|N_FLAG|C_FLAG))|                 \
671     ((R->Rg1.W^R->Rg2.W^J.W)&0x1000? H_FLAG:0)|          \
672     (((long)R->Rg1.W+(long)R->Rg2.W)&0x10000? C_FLAG:0); \
673   R->Rg1.W=J.W
674 
675 #define M_ADCW(Rg)      \
676   I=R->AF.B.l&C_FLAG;J.W=(R->HL.W+R->Rg.W+I)&0xFFFF;           \
677   R->AF.B.l=                                                   \
678     (((long)R->HL.W+(long)R->Rg.W+(long)I)&0x10000? C_FLAG:0)| \
679     (~(R->HL.W^R->Rg.W)&(R->Rg.W^J.W)&0x8000? V_FLAG:0)|       \
680     ((R->HL.W^R->Rg.W^J.W)&0x1000? H_FLAG:0)|                  \
681     (J.W? 0:Z_FLAG)|(J.B.h&S_FLAG);                            \
682   R->HL.W=J.W
683 
684 #define M_SBCW(Rg)      \
685   I=R->AF.B.l&C_FLAG;J.W=(R->HL.W-R->Rg.W-I)&0xFFFF;           \
686   R->AF.B.l=                                                   \
687     N_FLAG|                                                    \
688     (((long)R->HL.W-(long)R->Rg.W-(long)I)&0x10000? C_FLAG:0)| \
689     ((R->HL.W^R->Rg.W)&(R->HL.W^J.W)&0x8000? V_FLAG:0)|        \
690     ((R->HL.W^R->Rg.W^J.W)&0x1000? H_FLAG:0)|                  \
691     (J.W? 0:Z_FLAG)|(J.B.h&S_FLAG);                            \
692   R->HL.W=J.W
693 
694 enum Codes
695 {
696   NOP,LD_BC_WORD,LD_xBC_A,INC_BC,INC_B,DEC_B,LD_B_BYTE,RLCA,
697   EX_AF_AF,ADD_HL_BC,LD_A_xBC,DEC_BC,INC_C,DEC_C,LD_C_BYTE,RRCA,
698   DJNZ,LD_DE_WORD,LD_xDE_A,INC_DE,INC_D,DEC_D,LD_D_BYTE,RLA,
699   JR,ADD_HL_DE,LD_A_xDE,DEC_DE,INC_E,DEC_E,LD_E_BYTE,RRA,
700   JR_NZ,LD_HL_WORD,LD_xWORD_HL,INC_HL,INC_H,DEC_H,LD_H_BYTE,DAA,
701   JR_Z,ADD_HL_HL,LD_HL_xWORD,DEC_HL,INC_L,DEC_L,LD_L_BYTE,CPL,
702   JR_NC,LD_SP_WORD,LD_xWORD_A,INC_SP,INC_xHL,DEC_xHL,LD_xHL_BYTE,SCF,
703   JR_C,ADD_HL_SP,LD_A_xWORD,DEC_SP,INC_A,DEC_A,LD_A_BYTE,CCF,
704   LD_B_B,LD_B_C,LD_B_D,LD_B_E,LD_B_H,LD_B_L,LD_B_xHL,LD_B_A,
705   LD_C_B,LD_C_C,LD_C_D,LD_C_E,LD_C_H,LD_C_L,LD_C_xHL,LD_C_A,
706   LD_D_B,LD_D_C,LD_D_D,LD_D_E,LD_D_H,LD_D_L,LD_D_xHL,LD_D_A,
707   LD_E_B,LD_E_C,LD_E_D,LD_E_E,LD_E_H,LD_E_L,LD_E_xHL,LD_E_A,
708   LD_H_B,LD_H_C,LD_H_D,LD_H_E,LD_H_H,LD_H_L,LD_H_xHL,LD_H_A,
709   LD_L_B,LD_L_C,LD_L_D,LD_L_E,LD_L_H,LD_L_L,LD_L_xHL,LD_L_A,
710   LD_xHL_B,LD_xHL_C,LD_xHL_D,LD_xHL_E,LD_xHL_H,LD_xHL_L,HALT,LD_xHL_A,
711   LD_A_B,LD_A_C,LD_A_D,LD_A_E,LD_A_H,LD_A_L,LD_A_xHL,LD_A_A,
712   ADD_B,ADD_C,ADD_D,ADD_E,ADD_H,ADD_L,ADD_xHL,ADD_A,
713   ADC_B,ADC_C,ADC_D,ADC_E,ADC_H,ADC_L,ADC_xHL,ADC_A,
714   SUB_B,SUB_C,SUB_D,SUB_E,SUB_H,SUB_L,SUB_xHL,SUB_A,
715   SBC_B,SBC_C,SBC_D,SBC_E,SBC_H,SBC_L,SBC_xHL,SBC_A,
716   AND_B,AND_C,AND_D,AND_E,AND_H,AND_L,AND_xHL,AND_A,
717   XOR_B,XOR_C,XOR_D,XOR_E,XOR_H,XOR_L,XOR_xHL,XOR_A,
718   OR_B,OR_C,OR_D,OR_E,OR_H,OR_L,OR_xHL,OR_A,
719   CP_B,CP_C,CP_D,CP_E,CP_H,CP_L,CP_xHL,CP_A,
720   RET_NZ,POP_BC,JP_NZ,JP,CALL_NZ,PUSH_BC,ADD_BYTE,RST00,
721   RET_Z,RET,JP_Z,PFX_CB,CALL_Z,CALL,ADC_BYTE,RST08,
722   RET_NC,POP_DE,JP_NC,OUTA,CALL_NC,PUSH_DE,SUB_BYTE,RST10,
723   RET_C,EXX,JP_C,INA,CALL_C,PFX_DD,SBC_BYTE,RST18,
724   RET_PO,POP_HL,JP_PO,EX_HL_xSP,CALL_PO,PUSH_HL,AND_BYTE,RST20,
725   RET_PE,LD_PC_HL,JP_PE,EX_DE_HL,CALL_PE,PFX_ED,XOR_BYTE,RST28,
726   RET_P,POP_AF,JP_P,DI,CALL_P,PUSH_AF,OR_BYTE,RST30,
727   RET_M,LD_SP_HL,JP_M,EI,CALL_M,PFX_FD,CP_BYTE,RST38
728 };
729 
730 enum CodesCB
731 {
732   RLC_B,RLC_C,RLC_D,RLC_E,RLC_H,RLC_L,RLC_xHL,RLC_A,
733   RRC_B,RRC_C,RRC_D,RRC_E,RRC_H,RRC_L,RRC_xHL,RRC_A,
734   RL_B,RL_C,RL_D,RL_E,RL_H,RL_L,RL_xHL,RL_A,
735   RR_B,RR_C,RR_D,RR_E,RR_H,RR_L,RR_xHL,RR_A,
736   SLA_B,SLA_C,SLA_D,SLA_E,SLA_H,SLA_L,SLA_xHL,SLA_A,
737   SRA_B,SRA_C,SRA_D,SRA_E,SRA_H,SRA_L,SRA_xHL,SRA_A,
738   SLL_B,SLL_C,SLL_D,SLL_E,SLL_H,SLL_L,SLL_xHL,SLL_A,
739   SRL_B,SRL_C,SRL_D,SRL_E,SRL_H,SRL_L,SRL_xHL,SRL_A,
740   BIT0_B,BIT0_C,BIT0_D,BIT0_E,BIT0_H,BIT0_L,BIT0_xHL,BIT0_A,
741   BIT1_B,BIT1_C,BIT1_D,BIT1_E,BIT1_H,BIT1_L,BIT1_xHL,BIT1_A,
742   BIT2_B,BIT2_C,BIT2_D,BIT2_E,BIT2_H,BIT2_L,BIT2_xHL,BIT2_A,
743   BIT3_B,BIT3_C,BIT3_D,BIT3_E,BIT3_H,BIT3_L,BIT3_xHL,BIT3_A,
744   BIT4_B,BIT4_C,BIT4_D,BIT4_E,BIT4_H,BIT4_L,BIT4_xHL,BIT4_A,
745   BIT5_B,BIT5_C,BIT5_D,BIT5_E,BIT5_H,BIT5_L,BIT5_xHL,BIT5_A,
746   BIT6_B,BIT6_C,BIT6_D,BIT6_E,BIT6_H,BIT6_L,BIT6_xHL,BIT6_A,
747   BIT7_B,BIT7_C,BIT7_D,BIT7_E,BIT7_H,BIT7_L,BIT7_xHL,BIT7_A,
748   RES0_B,RES0_C,RES0_D,RES0_E,RES0_H,RES0_L,RES0_xHL,RES0_A,
749   RES1_B,RES1_C,RES1_D,RES1_E,RES1_H,RES1_L,RES1_xHL,RES1_A,
750   RES2_B,RES2_C,RES2_D,RES2_E,RES2_H,RES2_L,RES2_xHL,RES2_A,
751   RES3_B,RES3_C,RES3_D,RES3_E,RES3_H,RES3_L,RES3_xHL,RES3_A,
752   RES4_B,RES4_C,RES4_D,RES4_E,RES4_H,RES4_L,RES4_xHL,RES4_A,
753   RES5_B,RES5_C,RES5_D,RES5_E,RES5_H,RES5_L,RES5_xHL,RES5_A,
754   RES6_B,RES6_C,RES6_D,RES6_E,RES6_H,RES6_L,RES6_xHL,RES6_A,
755   RES7_B,RES7_C,RES7_D,RES7_E,RES7_H,RES7_L,RES7_xHL,RES7_A,
756   SET0_B,SET0_C,SET0_D,SET0_E,SET0_H,SET0_L,SET0_xHL,SET0_A,
757   SET1_B,SET1_C,SET1_D,SET1_E,SET1_H,SET1_L,SET1_xHL,SET1_A,
758   SET2_B,SET2_C,SET2_D,SET2_E,SET2_H,SET2_L,SET2_xHL,SET2_A,
759   SET3_B,SET3_C,SET3_D,SET3_E,SET3_H,SET3_L,SET3_xHL,SET3_A,
760   SET4_B,SET4_C,SET4_D,SET4_E,SET4_H,SET4_L,SET4_xHL,SET4_A,
761   SET5_B,SET5_C,SET5_D,SET5_E,SET5_H,SET5_L,SET5_xHL,SET5_A,
762   SET6_B,SET6_C,SET6_D,SET6_E,SET6_H,SET6_L,SET6_xHL,SET6_A,
763   SET7_B,SET7_C,SET7_D,SET7_E,SET7_H,SET7_L,SET7_xHL,SET7_A
764 };
765 
766 enum CodesED
767 {
768   DB_00,DB_01,DB_02,DB_03,DB_04,DB_05,DB_06,DB_07,
769   DB_08,DB_09,DB_0A,DB_0B,DB_0C,DB_0D,DB_0E,DB_0F,
770   DB_10,DB_11,DB_12,DB_13,DB_14,DB_15,DB_16,DB_17,
771   DB_18,DB_19,DB_1A,DB_1B,DB_1C,DB_1D,DB_1E,DB_1F,
772   DB_20,DB_21,DB_22,DB_23,DB_24,DB_25,DB_26,DB_27,
773   DB_28,DB_29,DB_2A,DB_2B,DB_2C,DB_2D,DB_2E,DB_2F,
774   DB_30,DB_31,DB_32,DB_33,DB_34,DB_35,DB_36,DB_37,
775   DB_38,DB_39,DB_3A,DB_3B,DB_3C,DB_3D,DB_3E,DB_3F,
776   IN_B_xC,OUT_xC_B,SBC_HL_BC,LD_xWORDe_BC,NEG,RETN,IM_0,LD_I_A,
777   IN_C_xC,OUT_xC_C,ADC_HL_BC,LD_BC_xWORDe,DB_4C,RETI,DB_,LD_R_A,
778   IN_D_xC,OUT_xC_D,SBC_HL_DE,LD_xWORDe_DE,DB_54,DB_55,IM_1,LD_A_I,
779   IN_E_xC,OUT_xC_E,ADC_HL_DE,LD_DE_xWORDe,DB_5C,DB_5D,IM_2,LD_A_R,
780   IN_H_xC,OUT_xC_H,SBC_HL_HL,LD_xWORDe_HL,DB_64,DB_65,DB_66,RRD,
781   IN_L_xC,OUT_xC_L,ADC_HL_HL,LD_HL_xWORDe,DB_6C,DB_6D,DB_6E,RLD,
782   IN_F_xC,DB_71,SBC_HL_SP,LD_xWORDe_SP,DB_74,DB_75,DB_76,DB_77,
783   IN_A_xC,OUT_xC_A,ADC_HL_SP,LD_SP_xWORDe,DB_7C,DB_7D,DB_7E,DB_7F,
784   DB_80,DB_81,DB_82,DB_83,DB_84,DB_85,DB_86,DB_87,
785   DB_88,DB_89,DB_8A,DB_8B,DB_8C,DB_8D,DB_8E,DB_8F,
786   DB_90,DB_91,DB_92,DB_93,DB_94,DB_95,DB_96,DB_97,
787   DB_98,DB_99,DB_9A,DB_9B,DB_9C,DB_9D,DB_9E,DB_9F,
788   LDI,CPI,INI,OUTI,DB_A4,DB_A5,DB_A6,DB_A7,
789   LDD,CPD,IND,OUTD,DB_AC,DB_AD,DB_AE,DB_AF,
790   LDIR,CPIR,INIR,OTIR,DB_B4,DB_B5,DB_B6,DB_B7,
791   LDDR,CPDR,INDR,OTDR,DB_BC,DB_BD,DB_BE,DB_BF,
792   DB_C0,DB_C1,DB_C2,DB_C3,DB_C4,DB_C5,DB_C6,DB_C7,
793   DB_C8,DB_C9,DB_CA,DB_CB,DB_CC,DB_CD,DB_CE,DB_CF,
794   DB_D0,DB_D1,DB_D2,DB_D3,DB_D4,DB_D5,DB_D6,DB_D7,
795   DB_D8,DB_D9,DB_DA,DB_DB,DB_DC,DB_DD,DB_DE,DB_DF,
796   DB_E0,DB_E1,DB_E2,DB_E3,DB_E4,DB_E5,DB_E6,DB_E7,
797   DB_E8,DB_E9,DB_EA,DB_EB,DB_EC,DB_ED,DB_EE,DB_EF,
798   DB_F0,DB_F1,DB_F2,DB_F3,DB_F4,DB_F5,DB_F6,DB_F7,
799   DB_F8,DB_F9,DB_FA,DB_FB,DB_FC,DB_FD,DB_FE,DB_FF
800 };
801 
CodesCB(register Z80 * R)802 static void CodesCB(register Z80 *R)
803 {
804   register byte I;
805 
806   I=OpZ80(R);
807   R->ICount-=z80_CyclesCB[I];
808   switch(I)
809   {
810 #include "mz80opc2.h"
811     default:
812 /*       if(R->TrapBadOps) */
813 /*         printf */
814 /*         (    */
815 /*           "[Z80 %lX] Unrecognized instruction: CB %02X at PC=%04X\n", */
816 /*           (long)(R->User),RdZ80(R->PC.W-1),R->PC.W-2 */
817 /*         ); */
818 	system_flags |= F_UNIMPL;
819 	break;
820   }
821 }
822 
CodesDDCB(register Z80 * R)823 static void CodesDDCB(register Z80 *R)
824 {
825   register pair J;
826   register byte I;
827 
828 #define XX IX
829   J.W=R->XX.W+(offset)OpZ80(R);
830   I=OpZ80(R);
831   R->ICount-=z80_CyclesXXCB[I];
832   switch(I)
833   {
834 #include "mz80opc3.h"
835     default:
836 /*       if(R->TrapBadOps) */
837 /*         printf */
838 /*         ( */
839 /*           "[Z80 %lX] Unrecognized instruction: DD CB %02X %02X at PC=%04X\n", */
840 /*           (long)(R->User),RdZ80(R->PC.W-2),RdZ80(R->PC.W-1),R->PC.W-4 */
841 /*         ); */
842 	system_flags |= F_UNIMPL;
843 	break;
844   }
845 #undef XX
846 }
847 
CodesFDCB(register Z80 * R)848 static void CodesFDCB(register Z80 *R)
849 {
850   register pair J;
851   register byte I;
852 
853 #define XX IY
854   J.W=R->XX.W+(offset)OpZ80(R);
855   I=OpZ80(R);
856   R->ICount-=z80_CyclesXXCB[I];
857   switch(I)
858   {
859 #include "mz80opc3.h"
860     default:
861 /*       if(R->TrapBadOps) */
862 /*         printf */
863 /*         ( */
864 /*           "[Z80 %lX] Unrecognized instruction: FD CB %02X %02X at PC=%04X\n", */
865 /*           (long)R->User,RdZ80(R->PC.W-2),RdZ80(R->PC.W-1),R->PC.W-4 */
866 /*         ); */
867 	  system_flags |= F_UNIMPL;
868 	  break;
869   }
870 #undef XX
871 }
872 
CodesED(register Z80 * R)873 static void CodesED(register Z80 *R)
874 {
875   register byte I;
876   register pair J;
877 
878   I=OpZ80(R);
879   R->ICount-=z80_CyclesED[I];
880   switch(I)
881   {
882 #include "mz80opc4.h"
883     case PFX_ED:
884       R->PC.W--;mz80_cache_ip(R);break;
885     default:
886 /*       if(R->TrapBadOps) */
887 /*         printf */
888 /*         ( */
889 /*           "[Z80 %lX] Unrecognized instruction: ED %02X at PC=%04X\n", */
890 /*           (long)R->User,RdZ80(R->PC.W-1),R->PC.W-2 */
891 /*         ); */
892 	system_flags |= F_UNIMPL;
893 	break;
894   }
895 }
896 
CodesDD(register Z80 * R)897 static void CodesDD(register Z80 *R)
898 {
899   register byte I;
900   register pair J;
901 
902 #define XX IX
903   I=OpZ80(R);
904   R->ICount-=z80_CyclesXX[I];
905   switch(I)
906   {
907 #include "mz80opc5.h"
908     case PFX_FD:
909     case PFX_DD:
910       R->PC.W--;mz80_cache_ip(R);break;
911     case PFX_CB:
912       CodesDDCB(R);break;
913     case HALT:
914       R->PC.W--;R->IFF|=0x80;R->ICount=0;mz80_cache_ip(R);break;
915     default:
916 /*       if(R->TrapBadOps) */
917 /*         printf */
918 /*         ( */
919 /*           "[Z80 %lX] Unrecognized instruction: DD %02X at PC=%04X\n", */
920 /*           (long)R->User,RdZ80(R->PC.W-1),R->PC.W-2 */
921 /*         ); */
922 	system_flags |= F_UNIMPL;
923 	break;
924   }
925 #undef XX
926 }
927 
CodesFD(register Z80 * R)928 static void CodesFD(register Z80 *R)
929 {
930   register byte I;
931   register pair J;
932 
933 #define XX IY
934   I=OpZ80(R);
935   R->ICount-=z80_CyclesXX[I];
936   switch(I)
937   {
938 #include "mz80opc5.h"
939     case PFX_FD:
940     case PFX_DD:
941       R->PC.W--;mz80_cache_ip(R);break;
942     case PFX_CB:
943       CodesFDCB(R);break;
944     case HALT:
945       R->PC.W--;R->IFF|=0x80;R->ICount=0;mz80_cache_ip(R);break;
946     default:
947 /*         printf */
948 /*         ( */
949 /*           "Unrecognized instruction: FD %02X at PC=%04X\n", */
950 /*           RdZ80(R->PC.W-1),R->PC.W-2 */
951 /*         ); */
952 	system_flags |= F_UNIMPL;
953   }
954 #undef XX
955 }
956 
957 /** ResetZ80() ***********************************************/
958 /** This function can be used to reset the register struct  **/
959 /** before starting execution with Z80(). It sets the       **/
960 /** registers to their supposed initial values.             **/
961 /*************************************************************/
ResetZ80(Z80 * R)962 void ResetZ80(Z80 *R)
963 {
964   R->PC.W=0x0000;R->SP.W=0xF000;
965   R->AF.W=R->BC.W=R->DE.W=R->HL.W=0x0000;
966   R->AF1.W=R->BC1.W=R->DE1.W=R->HL1.W=0x0000;
967   R->IX.W=R->IY.W=0x0000;
968   R->I=0x00;R->IFF=0x00;
969   R->ICount=R->IPeriod;
970   R->IRequest=INT_NONE;
971 
972   mz80_cache_ip(R);
973 }
974 
975 /** IntZ80() *************************************************/
976 /** This function will generate interrupt of given vector.  **/
977 /*************************************************************/
IntZ80(Z80 * R,word Vector)978 void IntZ80(Z80 *R,word Vector)
979 {
980   if((R->IFF&0x01)||(Vector==INT_NMI))
981   {
982     /* Experimental V Shouldn't disable all interrupts? */
983     R->IFF=(R->IFF&0x9E)|((R->IFF&0x01)<<6);
984     if(R->IFF&0x80) { R->PC.W++;R->IFF&=0x7F; }
985     M_PUSH(PC);
986 
987     if(Vector==INT_NMI) R->PC.W=INT_NMI;
988     else
989       if(R->IFF&0x04)
990       {
991         Vector=(Vector&0xFF)|((word)(R->I)<<8);
992         R->PC.B.l=RdZ80(Vector++);
993         R->PC.B.h=RdZ80(Vector);
994       }
995       else
996         if(R->IFF&0x02) R->PC.W=INT_IRQ;
997         else R->PC.W=Vector;
998   }
999   mz80_cache_ip(R);
1000 }
1001 
1002 /** RunZ80() *************************************************/
1003 /** This function will run Z80 code until an LoopZ80() call **/
1004 /** returns INT_QUIT. It will return the PC at which        **/
1005 /** emulation stopped, and current register values in R.    **/
1006 /*************************************************************/
RunZ80(Z80 * R)1007 word RunZ80(Z80 *R)
1008 {
1009     register byte I;
1010     register pair J;
1011 
1012     R->ICount += R->IPeriod;
1013 
1014     while ((R->ICount > 0) || (R->IFF&0x20)) {
1015 	J.W = R->IRequest;
1016 	R->IRequest = INT_NONE;
1017 
1018 	/* If we have come after EI, get address from IRequest */
1019 	/* Otherwise, get it from the loop handler             */
1020 	if(R->IFF&0x20) {
1021 	    R->ICount+=R->IBackup-1; /* Restore the ICount       */
1022 	    R->IFF&=0xDF;            /* Done with AfterEI state  */
1023 	}
1024 
1025 	if(J.W==INT_QUIT) return(R->PC.W); /* Exit if INT_QUIT */
1026 	if(J.W!=INT_NONE) IntZ80(R,J.W);   /* Int-pt if needed */
1027 
1028 	I=OpZ80(R);
1029 	R->ICount-=z80_Cycles[I];
1030 	switch(I) {
1031 #include "mz80opc1.h"
1032 	case PFX_CB: CodesCB(R);break;
1033 	case PFX_ED: CodesED(R);break;
1034 	case PFX_FD: CodesFD(R);break;
1035 	case PFX_DD: CodesDD(R);break;
1036 	}
1037     }
1038 
1039     /* Execution stopped */
1040     return(R->PC.W);
1041 }
1042 
1043 /*
1044  * CAL interface functions
1045  */
1046 
cal_maratz80_reset(cal_cpu cpu)1047 void cal_maratz80_reset(cal_cpu cpu)
1048 {
1049     ResetZ80(cpu->data.d_maratz80);
1050 }
1051 
cal_maratz80_run(cal_cpu cpu)1052 void cal_maratz80_run(cal_cpu cpu)
1053 {
1054     RunZ80(cpu->data.d_maratz80);
1055 }
1056 
cal_maratz80_runfor(cal_cpu cpu,int cycles)1057 void cal_maratz80_runfor(cal_cpu cpu, int cycles)
1058 {
1059     cpu->data.d_maratz80->IPeriod = cycles;
1060 }
1061 
cal_maratz80_irq(cal_cpu cpu,int irqno)1062 void cal_maratz80_irq(cal_cpu cpu, int irqno)
1063 {
1064     cpu->data.d_maratz80->IRequest = INT_IRQ;
1065 }
1066 
cal_maratz80_nmi(cal_cpu cpu)1067 void cal_maratz80_nmi(cal_cpu cpu)
1068 {
1069     cpu->data.d_maratz80->IRequest = INT_NMI;
1070 }
1071 
cal_maratz80_setzpage(cal_cpu cpu,void * page0)1072 void cal_maratz80_setzpage(cal_cpu cpu, void *page0)
1073 {
1074 }
1075 
cal_maratz80_timeleft(cal_cpu cpu)1076 int cal_maratz80_timeleft(cal_cpu cpu)
1077 {
1078     return cpu->data.d_maratz80->ICount;
1079 }
1080 
cal_maratz80_setmmu0(cal_cpu cpu,ranged_mmu * mmu)1081 void cal_maratz80_setmmu0(cal_cpu cpu, ranged_mmu *mmu)
1082 {
1083     cpu->data.d_maratz80->mmu = mmu;
1084 }
1085 
cal_maratz80_setmmu8(cal_cpu cpu,int shift,int mask,memread8_t * rtbl,memwrite8_t * wtbl)1086 void cal_maratz80_setmmu8(cal_cpu cpu, int shift, int mask, memread8_t *rtbl, memwrite8_t *wtbl)
1087 {
1088 /*     cpu->data.d_maratz80->memshift = shift; */
1089 /*     cpu->data.d_maratz80->memmask = mask; */
1090 /*     cpu->data.d_maratz80->readtable = rtbl; */
1091 /*     cpu->data.d_maratz80->writetable = wtbl; */
1092     cpu->data.d_maratz80->readfunc = *rtbl;
1093     cpu->data.d_maratz80->writefunc = *wtbl;
1094 }
1095 
cal_maratz80_setiou(cal_cpu cpu,memread8_t ioread,memwrite8_t iowrite)1096 void cal_maratz80_setiou(cal_cpu cpu, memread8_t ioread, memwrite8_t iowrite)
1097 {
1098     cpu->data.d_maratz80->io_read = ioread;
1099     cpu->data.d_maratz80->io_write = iowrite;
1100 }
1101 
cal_maratz80_init(cal_cpu * cpu)1102 void cal_maratz80_init(cal_cpu *cpu)
1103 {
1104     (*cpu)->data.d_maratz80 = calloc(1, sizeof(Z80));
1105     if (!(*cpu)->data.d_maratz80) {
1106 	deb_printf("Insufficient memory to create CPU.\n");
1107 	free(*cpu);
1108 	*cpu = NULL;
1109 	return;
1110     }
1111     (*cpu)->reset = cal_maratz80_reset;
1112     (*cpu)->run = cal_maratz80_run;
1113     (*cpu)->runfor = cal_maratz80_runfor;
1114     (*cpu)->irq = cal_maratz80_irq;
1115     (*cpu)->nmi = cal_maratz80_nmi;
1116     (*cpu)->setzpage = cal_maratz80_setzpage;
1117     (*cpu)->timeleft = cal_maratz80_timeleft;
1118     (*cpu)->setmmu0 = cal_maratz80_setmmu0;
1119     (*cpu)->setmmu8 = cal_maratz80_setmmu8;
1120     (*cpu)->setiou = cal_maratz80_setiou;
1121     (*cpu)->data.d_maratz80->User = *cpu;
1122 }
1123 
1124 /*
1125  * $Log: mz80.c,v $
1126  * Revision 1.7  2001/02/25 21:47:47  nyef
1127  * moved mz80 CAL interface code in from cal.c
1128  *
1129  * Revision 1.6  2000/08/02 03:04:55  nyef
1130  * removed an outdated warning comment
1131  *
1132  * Revision 1.5  1999/11/25 16:23:17  nyef
1133  * fixed a couple spots that were missed when adding ranged MMU
1134  *
1135  * Revision 1.4  1999/11/08 01:33:44  nyef
1136  * added preliminary implementation of ranged mmu
1137  *
1138  * Revision 1.3  1999/06/06 17:45:18  nyef
1139  * changed memory access to be non SMS-specific
1140  *
1141  * Revision 1.2  1999/05/01 23:57:59  nyef
1142  * added stuff to directly access sms memory
1143  *
1144  * Revision 1.1  1999/01/03 02:23:22  nyef
1145  * Initial revision
1146  *
1147  */
1148