1 /*
2  * Z80SIM  -  a Z80-CPU simulator
3  *
4  * Copyright (C) 1987-2021 by Udo Munk
5  *
6  * History:
7  * 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3
8  * 11-JAN-89 Release 1.1
9  * 08-FEB-89 Release 1.2
10  * 13-MAR-89 Release 1.3
11  * 09-FEB-90 Release 1.4  Ported to TARGON/31 M10/30
12  * 20-DEC-90 Release 1.5  Ported to COHERENT 3.0
13  * 10-JUN-92 Release 1.6  long casting problem solved with COHERENT 3.2
14  *			  and some optimisation
15  * 25-JUN-92 Release 1.7  comments in english and ported to COHERENT 4.0
16  * 02-OCT-06 Release 1.8  modified to compile on modern POSIX OS's
17  * 18-NOV-06 Release 1.9  modified to work with CP/M sources
18  * 08-DEC-06 Release 1.10 modified MMU for working with CP/NET
19  * 17-DEC-06 Release 1.11 TCP/IP sockets for CP/NET
20  * 25-DEC-06 Release 1.12 CPU speed option
21  * 19-FEB-07 Release 1.13 various improvements
22  * 06-OCT-07 Release 1.14 bug fixes and improvements
23  * 06-AUG-08 Release 1.15 many improvements and Windows support via Cygwin
24  * 25-AUG-08 Release 1.16 console status I/O loop detection and line discipline
25  * 20-OCT-08 Release 1.17 frontpanel integrated and Altair/IMSAI emulations
26  * 24-JAN-14 Release 1.18 bug fixes and improvements
27  * 02-MAR-14 Release 1.19 source cleanup and improvements
28  * 14-MAR-14 Release 1.20 added Tarbell SD FDC and printer port to Altair
29  * 29-MAR-14 Release 1.21 many improvements
30  * 29-MAY-14 Release 1.22 improved networking and bugfixes
31  * 04-JUN-14 Release 1.23 added 8080 emulation
32  * 06-SEP-14 Release 1.24 bugfixes and improvements
33  * 18-FEB-15 Release 1.25 bugfixes, improvements, added Cromemco Z-1
34  * 18-APR-15 Release 1.26 bugfixes and improvements
35  * 18-JAN-16 Release 1.27 bugfixes and improvements
36  * 05-MAY-16 Release 1.28 improved usability
37  * 20-NOV-16 Release 1.29 bugfixes and improvements
38  * 15-DEC-16 Release 1.30 improved memory management, machine cycle correct CPUs
39  * 28-DEC-16 Release 1.31 improved memory management, reimplemented MMUs
40  * 12-JAN-17 Release 1.32 improved configurations, front panel, added IMSAI VIO
41  * 07-FEB-17 Release 1.33 bugfixes, improvements, better front panels
42  * 16-MAR-17 Release 1.34 improvements, added ProcTec VDM-1
43  * 03-AUG-17 Release 1.35 added UNIX sockets, bugfixes, improvements
44  * 21-DEC-17 Release 1.36 bugfixes and improvements
45  * 06-JAN-21 Release 1.37 bugfixes and improvements
46  */
47 
48 /*
49  *	Like the function "cpu_z80()" this one emulates multi byte opcodes
50  *	starting with 0xdd
51  */
52 
53 #include "sim.h"
54 #include "simglb.h"
55 #include "config.h"
56 #ifdef FRONTPANEL
57 #include "../../frontpanel/frontpanel.h"
58 #endif
59 #include "memory.h"
60 
61 #ifdef Z80_UNDOC
62 	#define UNDOC(f) f
63 #else
64 	#define UNDOC(f) trap_dd
65 #endif
66 
67 static int trap_dd(void);
68 static int op_popix(void), op_pusix(void);
69 static int op_jpix(void);
70 static int op_exspx(void);
71 static int op_ldspx(void);
72 static int op_ldixnn(void), op_ldixinn(void), op_ldinx(void);
73 static int op_adaxd(void), op_acaxd(void), op_suaxd(void), op_scaxd(void);
74 static int op_andxd(void), op_xorxd(void), op_orxd(void), op_cpxd(void);
75 static int op_decxd(void), op_incxd(void);
76 static int op_addxb(void), op_addxd(void), op_addxs(void), op_addxx(void);
77 static int op_incix(void), op_decix(void);
78 static int op_ldaxd(void), op_ldbxd(void), op_ldcxd(void);
79 static int op_lddxd(void), op_ldexd(void);
80 static int op_ldhxd(void), op_ldlxd(void);
81 static int op_ldxda(void), op_ldxdb(void), op_ldxdc(void);
82 static int op_ldxdd(void), op_ldxde(void);
83 static int op_ldxdh(void), op_ldxdl(void), op_ldxdn(void);
84 extern int op_ddcb_handel(void);
85 
86 #ifdef Z80_UNDOC
87 static int op_undoc_ldaixl(void), op_undoc_ldaixh(void);
88 static int op_undoc_ldbixl(void), op_undoc_ldbixh(void);
89 static int op_undoc_ldcixl(void), op_undoc_ldcixh(void);
90 static int op_undoc_lddixl(void), op_undoc_lddixh(void);
91 static int op_undoc_ldeixl(void), op_undoc_ldeixh(void);
92 static int op_undoc_ldixha(void), op_undoc_ldixla(void);
93 static int op_undoc_ldixhb(void), op_undoc_ldixlb(void);
94 static int op_undoc_ldixhc(void), op_undoc_ldixlc(void);
95 static int op_undoc_ldixhd(void), op_undoc_ldixld(void);
96 static int op_undoc_ldixhe(void), op_undoc_ldixle(void);
97 static int op_undoc_ldixhixh(void), op_undoc_ldixlixh(void);
98 static int op_undoc_ldixhixl(void), op_undoc_ldixlixl(void);
99 static int op_undoc_ldixhn(void), op_undoc_ldixln(void);
100 static int op_undoc_cpixl(void);
101 static int op_undoc_acaixl(void), op_undoc_acaixh(void);
102 static int op_undoc_scaixl(void), op_undoc_scaixh(void);
103 static int op_undoc_oraixl(void), op_undoc_oraixh(void);
104 static int op_undoc_andixl(void), op_undoc_andixh(void);
105 static int op_undoc_incixl(void), op_undoc_incixh(void);
106 static int op_undoc_decixl(void), op_undoc_decixh(void);
107 #endif
108 
op_dd_handel(void)109 long op_dd_handel(void)
110 {
111 	register int t;
112 
113 	static int (*op_dd[256]) (void) = {
114 		trap_dd,			/* 0x00 */
115 		trap_dd,			/* 0x01 */
116 		trap_dd,			/* 0x02 */
117 		trap_dd,			/* 0x03 */
118 		trap_dd,			/* 0x04 */
119 		trap_dd,			/* 0x05 */
120 		trap_dd,			/* 0x06 */
121 		trap_dd,			/* 0x07 */
122 		trap_dd,			/* 0x08 */
123 		op_addxb,			/* 0x09 */
124 		trap_dd,			/* 0x0a */
125 		trap_dd,			/* 0x0b */
126 		trap_dd,			/* 0x0c */
127 		trap_dd,			/* 0x0d */
128 		trap_dd,			/* 0x0e */
129 		trap_dd,			/* 0x0f */
130 		trap_dd,			/* 0x10 */
131 		trap_dd,			/* 0x11 */
132 		trap_dd,			/* 0x12 */
133 		trap_dd,			/* 0x13 */
134 		trap_dd,			/* 0x14 */
135 		trap_dd,			/* 0x15 */
136 		trap_dd,			/* 0x16 */
137 		trap_dd,			/* 0x17 */
138 		trap_dd,			/* 0x18 */
139 		op_addxd,			/* 0x19 */
140 		trap_dd,			/* 0x1a */
141 		trap_dd,			/* 0x1b */
142 		trap_dd,			/* 0x1c */
143 		trap_dd,			/* 0x1d */
144 		trap_dd,			/* 0x1e */
145 		trap_dd,			/* 0x1f */
146 		trap_dd,			/* 0x20 */
147 		op_ldixnn,			/* 0x21 */
148 		op_ldinx,			/* 0x22 */
149 		op_incix,			/* 0x23 */
150 		UNDOC(op_undoc_incixh),		/* 0x24 */
151 		UNDOC(op_undoc_decixh),		/* 0x25 */
152 		UNDOC(op_undoc_ldixhn),		/* 0x26 */
153 		trap_dd,			/* 0x27 */
154 		trap_dd,			/* 0x28 */
155 		op_addxx,			/* 0x29 */
156 		op_ldixinn,			/* 0x2a */
157 		op_decix,			/* 0x2b */
158 		UNDOC(op_undoc_incixl),		/* 0x2c */
159 		UNDOC(op_undoc_decixl),		/* 0x2d */
160 		UNDOC(op_undoc_ldixln),		/* 0x2e */
161 		trap_dd,			/* 0x2f */
162 		trap_dd,			/* 0x30 */
163 		trap_dd,			/* 0x31 */
164 		trap_dd,			/* 0x32 */
165 		trap_dd,			/* 0x33 */
166 		op_incxd,			/* 0x34 */
167 		op_decxd,			/* 0x35 */
168 		op_ldxdn,			/* 0x36 */
169 		trap_dd,			/* 0x37 */
170 		trap_dd,			/* 0x38 */
171 		op_addxs,			/* 0x39 */
172 		trap_dd,			/* 0x3a */
173 		trap_dd,			/* 0x3b */
174 		trap_dd,			/* 0x3c */
175 		trap_dd,			/* 0x3d */
176 		trap_dd,			/* 0x3e */
177 		trap_dd,			/* 0x3f */
178 		trap_dd,			/* 0x40 */
179 		trap_dd,			/* 0x41 */
180 		trap_dd,			/* 0x42 */
181 		trap_dd,			/* 0x43 */
182 		UNDOC(op_undoc_ldbixh),		/* 0x44 */
183 		UNDOC(op_undoc_ldbixl),		/* 0x45 */
184 		op_ldbxd,			/* 0x46 */
185 		trap_dd,			/* 0x47 */
186 		trap_dd,			/* 0x48 */
187 		trap_dd,			/* 0x49 */
188 		trap_dd,			/* 0x4a */
189 		trap_dd,			/* 0x4b */
190 		UNDOC(op_undoc_ldcixh),		/* 0x4c */
191 		UNDOC(op_undoc_ldcixl),		/* 0x4d */
192 		op_ldcxd,			/* 0x4e */
193 		trap_dd,			/* 0x4f */
194 		trap_dd,			/* 0x50 */
195 		trap_dd,			/* 0x51 */
196 		trap_dd,			/* 0x52 */
197 		trap_dd,			/* 0x53 */
198 		UNDOC(op_undoc_lddixh),		/* 0x54 */
199 		UNDOC(op_undoc_lddixl),		/* 0x55 */
200 		op_lddxd,			/* 0x56 */
201 		trap_dd,			/* 0x57 */
202 		trap_dd,			/* 0x58 */
203 		trap_dd,			/* 0x59 */
204 		trap_dd,			/* 0x5a */
205 		trap_dd,			/* 0x5b */
206 		UNDOC(op_undoc_ldeixh),		/* 0x5c */
207 		UNDOC(op_undoc_ldeixl),		/* 0x5d */
208 		op_ldexd,			/* 0x5e */
209 		trap_dd,			/* 0x5f */
210 		UNDOC(op_undoc_ldixhb),		/* 0x60 */
211 		UNDOC(op_undoc_ldixhc),		/* 0x61 */
212 		UNDOC(op_undoc_ldixhd),		/* 0x62 */
213 		UNDOC(op_undoc_ldixhe),		/* 0x63 */
214 		UNDOC(op_undoc_ldixhixh),	/* 0x64 */
215 		UNDOC(op_undoc_ldixhixl),	/* 0x65 */
216 		op_ldhxd,			/* 0x66 */
217 		UNDOC(op_undoc_ldixha),		/* 0x67 */
218 		UNDOC(op_undoc_ldixlb),		/* 0x68 */
219 		UNDOC(op_undoc_ldixlc),		/* 0x69 */
220 		UNDOC(op_undoc_ldixld),		/* 0x6a */
221 		UNDOC(op_undoc_ldixle),		/* 0x6b */
222 		UNDOC(op_undoc_ldixlixh),	/* 0x6c */
223 		UNDOC(op_undoc_ldixlixl),	/* 0x6d */
224 		op_ldlxd,			/* 0x6e */
225 		UNDOC(op_undoc_ldixla),		/* 0x6f */
226 		op_ldxdb,			/* 0x70 */
227 		op_ldxdc,			/* 0x71 */
228 		op_ldxdd,			/* 0x72 */
229 		op_ldxde,			/* 0x73 */
230 		op_ldxdh,			/* 0x74 */
231 		op_ldxdl,			/* 0x75 */
232 		trap_dd,			/* 0x76 */
233 		op_ldxda,			/* 0x77 */
234 		trap_dd,			/* 0x78 */
235 		trap_dd,			/* 0x79 */
236 		trap_dd,			/* 0x7a */
237 		trap_dd,			/* 0x7b */
238 		UNDOC(op_undoc_ldaixh),		/* 0x7c */
239 		UNDOC(op_undoc_ldaixl),		/* 0x7d */
240 		op_ldaxd,			/* 0x7e */
241 		trap_dd,			/* 0x7f */
242 		trap_dd,			/* 0x80 */
243 		trap_dd,			/* 0x81 */
244 		trap_dd,			/* 0x82 */
245 		trap_dd,			/* 0x83 */
246 		trap_dd,			/* 0x84 */
247 		trap_dd,			/* 0x85 */
248 		op_adaxd,			/* 0x86 */
249 		trap_dd,			/* 0x87 */
250 		trap_dd,			/* 0x88 */
251 		trap_dd,			/* 0x89 */
252 		trap_dd,			/* 0x8a */
253 		trap_dd,			/* 0x8b */
254 		UNDOC(op_undoc_acaixh),		/* 0x8c */
255 		UNDOC(op_undoc_acaixl),		/* 0x8d */
256 		op_acaxd,			/* 0x8e */
257 		trap_dd,			/* 0x8f */
258 		trap_dd,			/* 0x90 */
259 		trap_dd,			/* 0x91 */
260 		trap_dd,			/* 0x92 */
261 		trap_dd,			/* 0x93 */
262 		trap_dd,			/* 0x94 */
263 		trap_dd,			/* 0x95 */
264 		op_suaxd,			/* 0x96 */
265 		trap_dd,			/* 0x97 */
266 		trap_dd,			/* 0x98 */
267 		trap_dd,			/* 0x99 */
268 		trap_dd,			/* 0x9a */
269 		trap_dd,			/* 0x9b */
270 		UNDOC(op_undoc_scaixh),		/* 0x9c */
271 		UNDOC(op_undoc_scaixl),		/* 0x9d */
272 		op_scaxd,			/* 0x9e */
273 		trap_dd,			/* 0x9f */
274 		trap_dd,			/* 0xa0 */
275 		trap_dd,			/* 0xa1 */
276 		trap_dd,			/* 0xa2 */
277 		trap_dd,			/* 0xa3 */
278 		UNDOC(op_undoc_andixh),		/* 0xa4 */
279 		UNDOC(op_undoc_andixl),		/* 0xa5 */
280 		op_andxd,			/* 0xa6 */
281 		trap_dd,			/* 0xa7 */
282 		trap_dd,			/* 0xa8 */
283 		trap_dd,			/* 0xa9 */
284 		trap_dd,			/* 0xaa */
285 		trap_dd,			/* 0xab */
286 		trap_dd,			/* 0xac */
287 		trap_dd,			/* 0xad */
288 		op_xorxd,			/* 0xae */
289 		trap_dd,			/* 0xaf */
290 		trap_dd,			/* 0xb0 */
291 		trap_dd,			/* 0xb1 */
292 		trap_dd,			/* 0xb2 */
293 		trap_dd,			/* 0xb3 */
294 		UNDOC(op_undoc_oraixh),		/* 0xb4 */
295 		UNDOC(op_undoc_oraixl),		/* 0xb5 */
296 		op_orxd,			/* 0xb6 */
297 		trap_dd,			/* 0xb7 */
298 		trap_dd,			/* 0xb8 */
299 		trap_dd,			/* 0xb9 */
300 		trap_dd,			/* 0xba */
301 		trap_dd,			/* 0xbb */
302 		trap_dd,			/* 0xbc */
303 		UNDOC(op_undoc_cpixl),		/* 0xbd */
304 		op_cpxd,			/* 0xbe */
305 		trap_dd,			/* 0xbf */
306 		trap_dd,			/* 0xc0 */
307 		trap_dd,			/* 0xc1 */
308 		trap_dd,			/* 0xc2 */
309 		trap_dd,			/* 0xc3 */
310 		trap_dd,			/* 0xc4 */
311 		trap_dd,			/* 0xc5 */
312 		trap_dd,			/* 0xc6 */
313 		trap_dd,			/* 0xc7 */
314 		trap_dd,			/* 0xc8 */
315 		trap_dd,			/* 0xc9 */
316 		trap_dd,			/* 0xca */
317 		op_ddcb_handel,			/* 0xcb */
318 		trap_dd,			/* 0xcc */
319 		trap_dd,			/* 0xcd */
320 		trap_dd,			/* 0xce */
321 		trap_dd,			/* 0xcf */
322 		trap_dd,			/* 0xd0 */
323 		trap_dd,			/* 0xd1 */
324 		trap_dd,			/* 0xd2 */
325 		trap_dd,			/* 0xd3 */
326 		trap_dd,			/* 0xd4 */
327 		trap_dd,			/* 0xd5 */
328 		trap_dd,			/* 0xd6 */
329 		trap_dd,			/* 0xd7 */
330 		trap_dd,			/* 0xd8 */
331 		trap_dd,			/* 0xd9 */
332 		trap_dd,			/* 0xda */
333 		trap_dd,			/* 0xdb */
334 		trap_dd,			/* 0xdc */
335 		trap_dd,			/* 0xdd */
336 		trap_dd,			/* 0xde */
337 		trap_dd,			/* 0xdf */
338 		trap_dd,			/* 0xe0 */
339 		op_popix,			/* 0xe1 */
340 		trap_dd,			/* 0xe2 */
341 		op_exspx,			/* 0xe3 */
342 		trap_dd,			/* 0xe4 */
343 		op_pusix,			/* 0xe5 */
344 		trap_dd,			/* 0xe6 */
345 		trap_dd,			/* 0xe7 */
346 		trap_dd,			/* 0xe8 */
347 		op_jpix,			/* 0xe9 */
348 		trap_dd,			/* 0xea */
349 		trap_dd,			/* 0xeb */
350 		trap_dd,			/* 0xec */
351 		trap_dd,			/* 0xed */
352 		trap_dd,			/* 0xee */
353 		trap_dd,			/* 0xef */
354 		trap_dd,			/* 0xf0 */
355 		trap_dd,			/* 0xf1 */
356 		trap_dd,			/* 0xf2 */
357 		trap_dd,			/* 0xf3 */
358 		trap_dd,			/* 0xf4 */
359 		trap_dd,			/* 0xf5 */
360 		trap_dd,			/* 0xf6 */
361 		trap_dd,			/* 0xf7 */
362 		trap_dd,			/* 0xf8 */
363 		op_ldspx,			/* 0xf9 */
364 		trap_dd,			/* 0xfa */
365 		trap_dd,			/* 0xfb */
366 		trap_dd,			/* 0xfc */
367 		trap_dd,			/* 0xfd */
368 		trap_dd,			/* 0xfe */
369 		trap_dd				/* 0xff */
370 	};
371 
372 #ifdef BUS_8080
373 	/* M1 opcode fetch */
374 	cpu_bus = CPU_WO | CPU_M1 | CPU_MEMR;
375 	m1_step = 1;
376 #endif
377 #ifdef FRONTPANEL
378 	/* update frontpanel */
379 	fp_clock++;
380 	fp_sampleLightGroup(0, 0);
381 #endif
382 
383 	t = (*op_dd[memrdr(PC++)]) ();	/* execute next opcode */
384 
385 	return(t);
386 }
387 
388 /*
389  *	This function traps undocumented opcodes following the
390  *	initial 0xdd of a multi byte opcode.
391  */
trap_dd(void)392 static int trap_dd(void)
393 {
394 	cpu_error = OPTRAP2;
395 	cpu_state = STOPPED;
396 	return(0);
397 }
398 
op_popix(void)399 static int op_popix(void)		/* POP IX */
400 {
401 	IX = memrdr(SP++);
402 	IX += memrdr(SP++) << 8;
403 	return(14);
404 }
405 
op_pusix(void)406 static int op_pusix(void)		/* PUSH IX */
407 {
408 	memwrt(--SP, IX >> 8);
409 	memwrt(--SP, IX);
410 	return(15);
411 }
412 
op_jpix(void)413 static int op_jpix(void)		/* JP (IX) */
414 {
415 	PC = IX;
416 	return(8);
417 }
418 
op_exspx(void)419 static int op_exspx(void)		/* EX (SP),IX */
420 {
421 	register WORD i;
422 
423 	i = memrdr(SP) + (memrdr(SP + 1) << 8);
424 	memwrt(SP, IX);
425 	memwrt(SP + 1, IX >> 8);
426 	IX = i;
427 	return(23);
428 }
429 
op_ldspx(void)430 static int op_ldspx(void)		/* LD SP,IX */
431 {
432 	SP = IX;
433 	return(10);
434 }
435 
op_ldixnn(void)436 static int op_ldixnn(void)		/* LD IX,nn */
437 {
438 	IX = memrdr(PC++);
439 	IX += memrdr(PC++) << 8;
440 	return(14);
441 }
442 
op_ldixinn(void)443 static int op_ldixinn(void)		/* LD IX,(nn) */
444 {
445 	register WORD i;
446 
447 	i = memrdr(PC++);
448 	i += memrdr(PC++) << 8;
449 	IX = memrdr(i);
450 	IX += memrdr(i + 1) << 8;
451 	return(20);
452 }
453 
op_ldinx(void)454 static int op_ldinx(void)		/* LD (nn),IX */
455 {
456 	register WORD i;
457 
458 	i = memrdr(PC++);
459 	i += memrdr(PC++) << 8;
460 	memwrt(i, IX);
461 	memwrt(i + 1, IX >> 8);
462 	return(20);
463 }
464 
op_adaxd(void)465 static int op_adaxd(void)		/* ADD A,(IX+d) */
466 {
467 	register int i;
468 	register BYTE P;
469 
470 	P = memrdr(IX + (signed char) memrdr(PC++));
471 	((A & 0xf) + (P	& 0xf) > 0xf) ?	(F |= H_FLAG) : (F &= ~H_FLAG);
472 	(A + P > 255) ?	(F |= C_FLAG) : (F &= ~C_FLAG);
473 	A = i = (signed char) A + (signed char) P;
474 	(i < -128 || i > 127) ?	(F |= P_FLAG) : (F &= ~P_FLAG);
475 	(i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
476 	(A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
477 	F &= ~N_FLAG;
478 	return(19);
479 }
480 
op_acaxd(void)481 static int op_acaxd(void)		/* ADC A,(IX+d) */
482 {
483 	register int i, carry;
484 	register BYTE P;
485 
486 	carry = (F & C_FLAG) ? 1 : 0;
487 	P = memrdr(IX + (signed char) memrdr(PC++));
488 	((A & 0xf) + (P	& 0xf) + carry > 0xf) ?	(F |= H_FLAG) : (F &= ~H_FLAG);
489 	(A + P + carry > 255) ?	(F |= C_FLAG) : (F &= ~C_FLAG);
490 	A = i = (signed char) A + (signed char) P + carry;
491 	(i < -128 || i > 127) ?	(F |= P_FLAG) : (F &= ~P_FLAG);
492 	(i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
493 	(A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
494 	F &= ~N_FLAG;
495 	return(19);
496 }
497 
op_suaxd(void)498 static int op_suaxd(void)		/* SUB A,(IX+d) */
499 {
500 	register int i;
501 	register BYTE P;
502 
503 	P = memrdr(IX + (signed char) memrdr(PC++));
504 	((P & 0xf) > (A	& 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
505 	(P > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
506 	A = i = (signed char) A - (signed char) P;
507 	(i < -128 || i > 127) ?	(F |= P_FLAG) : (F &= ~P_FLAG);
508 	(i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
509 	(A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
510 	F |= N_FLAG;
511 	return(19);
512 }
513 
op_scaxd(void)514 static int op_scaxd(void)		/* SBC A,(IX+d) */
515 {
516 	register int i, carry;
517 	register BYTE P;
518 
519 	carry = (F & C_FLAG) ? 1 : 0;
520 	P = memrdr(IX + (signed char) memrdr(PC++));
521 	((P & 0xf) + carry > (A	& 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
522 	(P + carry > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
523 	A = i = (signed char) A - (signed char) P - carry;
524 	(i < -128 || i > 127) ?	(F |= P_FLAG) : (F &= ~P_FLAG);
525 	(i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
526 	(A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
527 	F |= N_FLAG;
528 	return(19);
529 }
530 
op_andxd(void)531 static int op_andxd(void)		/* AND (IX+d) */
532 {
533 	A &= memrdr(IX + (signed char) memrdr(PC++));
534 	(A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
535 	(A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
536 	F |= H_FLAG;
537 	(parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
538 	F &= ~(N_FLAG | C_FLAG);
539 	return(19);
540 }
541 
op_xorxd(void)542 static int op_xorxd(void)		/* XOR (IX+d) */
543 {
544 	A ^= memrdr(IX + (signed char) memrdr(PC++));
545 	(A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
546 	(A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
547 	(parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
548 	F &= ~(H_FLAG | N_FLAG | C_FLAG);
549 	return(19);
550 }
551 
op_orxd(void)552 static int op_orxd(void)		/* OR (IX+d) */
553 {
554 	A |= memrdr(IX + (signed char) memrdr(PC++));
555 	(A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
556 	(A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
557 	(parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
558 	F &= ~(H_FLAG | N_FLAG | C_FLAG);
559 	return(19);
560 }
561 
op_cpxd(void)562 static int op_cpxd(void)		/* CP (IX+d) */
563 {
564 	register int i;
565 	register BYTE P;
566 
567 	P = memrdr(IX + (signed char) memrdr(PC++));
568 	((P & 0xf) > (A	& 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
569 	(P > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
570 	i = (signed char) A - (signed char) P;
571 	(i < -128 || i > 127) ?	(F |= P_FLAG) : (F &= ~P_FLAG);
572 	(i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
573 	(i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
574 	F |= N_FLAG;
575 	return(19);
576 }
577 
op_incxd(void)578 static int op_incxd(void)		/* INC (IX+d) */
579 {
580 	register BYTE P;
581 	WORD addr;
582 
583 	addr = IX + (signed char) memrdr(PC++);
584 	P = memrdr(addr);
585 	P++;
586 	memwrt(addr, P);
587 	((P & 0xf) == 0) ? (F |= H_FLAG) : (F &= ~H_FLAG);
588 	(P == 128) ? (F |= P_FLAG) : (F &= ~P_FLAG);
589 	(P & 128) ? (F	|= S_FLAG) : (F	&= ~S_FLAG);
590 	(P) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
591 	F &= ~N_FLAG;
592 	return(23);
593 }
594 
op_decxd(void)595 static int op_decxd(void)		/* DEC (IX+d) */
596 {
597 	register BYTE P;
598 	WORD addr;
599 
600 	addr = IX + (signed char) memrdr(PC++);
601 	P = memrdr(addr);
602 	P--;
603 	memwrt(addr, P);
604 	((P & 0xf) == 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
605 	(P == 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
606 	(P & 128) ? (F |= S_FLAG) : (F	&= ~S_FLAG);
607 	(P) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
608 	F |= N_FLAG;
609 	return(23);
610 }
611 
op_addxb(void)612 static int op_addxb(void)		/* ADD IX,BC */
613 {
614 	register int carry;
615 	BYTE ixl = IX & 0xff;
616 	BYTE ixh = IX >> 8;
617 
618 	carry = (ixl + C > 255) ? 1 : 0;
619 	ixl += C;
620 	((ixh & 0xf) + (B & 0xf) + carry > 0xf) ? (F |= H_FLAG)
621 						: (F &= ~H_FLAG);
622 	(ixh + B + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
623 	ixh += B + carry;
624 	IX = (ixh << 8) + ixl;
625 	F &= ~N_FLAG;
626 	return(15);
627 }
628 
op_addxd(void)629 static int op_addxd(void)		/* ADD IX,DE */
630 {
631 	register int carry;
632 	BYTE ixl = IX & 0xff;
633 	BYTE ixh = IX >> 8;
634 
635 	carry = (ixl + E > 255) ? 1 : 0;
636 	ixl += E;
637 	((ixh & 0xf) + (D & 0xf) + carry > 0xf) ? (F |= H_FLAG)
638 						: (F &= ~H_FLAG);
639 	(ixh + D + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
640 	ixh += D + carry;
641 	IX = (ixh << 8) + ixl;
642 	F &= ~N_FLAG;
643 	return(15);
644 }
645 
op_addxs(void)646 static int op_addxs(void)		/* ADD IX,SP */
647 {
648 	register int carry;
649 	BYTE ixl = IX & 0xff;
650 	BYTE ixh = IX >> 8;
651 	BYTE spl = SP & 0xff;
652 	BYTE sph = SP >> 8;
653 
654 	carry = (ixl + spl > 255) ? 1 : 0;
655 	ixl += spl;
656 	((ixh & 0xf) + (sph & 0xf) + carry > 0xf) ? (F |= H_FLAG)
657 						  : (F &= ~H_FLAG);
658 	(ixh + sph + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
659 	ixh += sph + carry;
660 	IX = (ixh << 8) + ixl;
661 	F &= ~N_FLAG;
662 	return(15);
663 }
664 
op_addxx(void)665 static int op_addxx(void)		/* ADD IX,IX */
666 {
667 	register int carry;
668 	BYTE ixl = IX & 0xff;
669 	BYTE ixh = IX >> 8;
670 
671 	carry = (ixl << 1 > 255) ? 1 : 0;
672 	ixl <<= 1;
673 	((ixh & 0xf) + (ixh & 0xf) + carry > 0xf) ? (F |= H_FLAG)
674 						  : (F &= ~H_FLAG);
675 	(ixh + ixh + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
676 	ixh += ixh + carry;
677 	IX = (ixh << 8) + ixl;
678 	F &= ~N_FLAG;
679 	return(15);
680 }
681 
op_incix(void)682 static int op_incix(void)		/* INC IX */
683 {
684 	IX++;
685 	return(10);
686 }
687 
op_decix(void)688 static int op_decix(void)		/* DEC IX */
689 {
690 	IX--;
691 	return(10);
692 }
693 
op_ldaxd(void)694 static int op_ldaxd(void)		/* LD A,(IX+d) */
695 {
696 	A = memrdr(IX + (signed char) memrdr(PC++));
697 	return(19);
698 }
699 
op_ldbxd(void)700 static int op_ldbxd(void)		/* LD B,(IX+d) */
701 {
702 	B = memrdr(IX + (signed char) memrdr(PC++));
703 	return(19);
704 }
705 
op_ldcxd(void)706 static int op_ldcxd(void)		/* LD C,(IX+d) */
707 {
708 	C = memrdr(IX + (signed char) memrdr(PC++));
709 	return(19);
710 }
711 
op_lddxd(void)712 static int op_lddxd(void)		/* LD D,(IX+d) */
713 {
714 	D = memrdr(IX + (signed char) memrdr(PC++));
715 	return(19);
716 }
717 
op_ldexd(void)718 static int op_ldexd(void)		/* LD E,(IX+d) */
719 {
720 	E = memrdr(IX + (signed char) memrdr(PC++));
721 	return(19);
722 }
723 
op_ldhxd(void)724 static int op_ldhxd(void)		/* LD H,(IX+d) */
725 {
726 	H = memrdr(IX + (signed char) memrdr(PC++));
727 	return(19);
728 }
729 
op_ldlxd(void)730 static int op_ldlxd(void)		/* LD L,(IX+d) */
731 {
732 	L = memrdr(IX + (signed char) memrdr(PC++));
733 	return(19);
734 }
735 
op_ldxda(void)736 static int op_ldxda(void)		/* LD (IX+d),A */
737 {
738 	memwrt(IX + (signed char) memrdr(PC++), A);
739 	return(19);
740 }
741 
op_ldxdb(void)742 static int op_ldxdb(void)		/* LD (IX+d),B */
743 {
744 	memwrt(IX + (signed char) memrdr(PC++), B);
745 	return(19);
746 }
747 
op_ldxdc(void)748 static int op_ldxdc(void)		/* LD (IX+d),C */
749 {
750 	memwrt(IX + (signed char) memrdr(PC++), C);
751 	return(19);
752 }
753 
op_ldxdd(void)754 static int op_ldxdd(void)		/* LD (IX+d),D */
755 {
756 	memwrt(IX + (signed char) memrdr(PC++), D);
757 	return(19);
758 }
759 
op_ldxde(void)760 static int op_ldxde(void)		/* LD (IX+d),E */
761 {
762 	memwrt(IX + (signed char) memrdr(PC++), E);
763 	return(19);
764 }
765 
op_ldxdh(void)766 static int op_ldxdh(void)		/* LD (IX+d),H */
767 {
768 	memwrt(IX + (signed char) memrdr(PC++), H);
769 	return(19);
770 }
771 
op_ldxdl(void)772 static int op_ldxdl(void)		/* LD (IX+d),L */
773 {
774 	memwrt(IX + (signed char) memrdr(PC++), L);
775 	return(19);
776 }
777 
op_ldxdn(void)778 static int op_ldxdn(void)		/* LD (IX+d),n */
779 {
780 	register signed char d;
781 
782 	d = memrdr(PC++);
783 	memwrt(IX + d, memrdr(PC++));
784 	return(19);
785 }
786 
787 /**********************************************************************/
788 /**********************************************************************/
789 /*********       UNDOCUMENTED Z80 INSTRUCTIONS, BEWARE!      **********/
790 /**********************************************************************/
791 /**********************************************************************/
792 
793 #ifdef Z80_UNDOC
794 
op_undoc_ldaixl(void)795 static int op_undoc_ldaixl(void)	/* LD A,IXL */
796 {
797 	if (u_flag) {
798 		trap_dd();
799 		return(0);
800 	}
801 
802 	A = IX & 0xff;
803 	return(8);
804 }
805 
op_undoc_ldaixh(void)806 static int op_undoc_ldaixh(void)	/* LD A,IXH */
807 {
808 	if (u_flag) {
809 		trap_dd();
810 		return(0);
811 	}
812 
813 	A = IX >> 8;
814 	return(8);
815 }
816 
op_undoc_ldbixl(void)817 static int op_undoc_ldbixl(void)	/* LD B,IXL */
818 {
819 	if (u_flag) {
820 		trap_dd();
821 		return(0);
822 	}
823 
824 	B = IX & 0xff;
825 	return(8);
826 }
827 
op_undoc_ldbixh(void)828 static int op_undoc_ldbixh(void)	/* LD B,IXH */
829 {
830 	if (u_flag) {
831 		trap_dd();
832 		return(0);
833 	}
834 
835 	B = IX >> 8;
836 	return(8);
837 }
838 
op_undoc_ldcixl(void)839 static int op_undoc_ldcixl(void)	/* LD C,IXL */
840 {
841 	if (u_flag) {
842 		trap_dd();
843 		return(0);
844 	}
845 
846 	C = IX & 0xff;
847 	return(8);
848 }
849 
op_undoc_ldcixh(void)850 static int op_undoc_ldcixh(void)	/* LD C,IXH */
851 {
852 	if (u_flag) {
853 		trap_dd();
854 		return(0);
855 	}
856 
857 	C = IX >> 8;
858 	return(8);
859 }
860 
op_undoc_lddixl(void)861 static int op_undoc_lddixl(void)	/* LD D,IXL */
862 {
863 	if (u_flag) {
864 		trap_dd();
865 		return(0);
866 	}
867 
868 	D = IX & 0xff;
869 	return(8);
870 }
871 
op_undoc_lddixh(void)872 static int op_undoc_lddixh(void)	/* LD D,IXH */
873 {
874 	if (u_flag) {
875 		trap_dd();
876 		return(0);
877 	}
878 
879 	D = IX >> 8;
880 	return(8);
881 }
882 
op_undoc_ldeixl(void)883 static int op_undoc_ldeixl(void)	/* LD E,IXL */
884 {
885 	if (u_flag) {
886 		trap_dd();
887 		return(0);
888 	}
889 
890 	E = IX & 0xff;
891 	return(8);
892 }
893 
op_undoc_ldeixh(void)894 static int op_undoc_ldeixh(void)	/* LD E,IXH */
895 {
896 	if (u_flag) {
897 		trap_dd();
898 		return(0);
899 	}
900 
901 	E = IX >> 8;
902 	return(8);
903 }
904 
op_undoc_ldixla(void)905 static int op_undoc_ldixla(void)	/* LD IXL,A */
906 {
907 	if (u_flag) {
908 		trap_dd();
909 		return(0);
910 	}
911 
912 	IX = (IX & 0xff00) | A;
913 	return(8);
914 }
915 
op_undoc_ldixha(void)916 static int op_undoc_ldixha(void)	/* LD IXH,A */
917 {
918 	if (u_flag) {
919 		trap_dd();
920 		return(0);
921 	}
922 
923 	IX = (IX & 0x00ff) | (A << 8);
924 	return(8);
925 }
926 
op_undoc_ldixlb(void)927 static int op_undoc_ldixlb(void)	/* LD IXL,B */
928 {
929 	if (u_flag) {
930 		trap_dd();
931 		return(0);
932 	}
933 
934 	IX = (IX & 0xff00) | B;
935 	return(8);
936 }
937 
op_undoc_ldixhb(void)938 static int op_undoc_ldixhb(void)	/* LD IXH,B */
939 {
940 	if (u_flag) {
941 		trap_dd();
942 		return(0);
943 	}
944 
945 	IX = (IX & 0x00ff) | (B << 8);
946 	return(8);
947 }
948 
op_undoc_ldixlc(void)949 static int op_undoc_ldixlc(void)	/* LD IXL,C */
950 {
951 	if (u_flag) {
952 		trap_dd();
953 		return(0);
954 	}
955 
956 	IX = (IX & 0xff00) | C;
957 	return(8);
958 }
959 
op_undoc_ldixhc(void)960 static int op_undoc_ldixhc(void)	/* LD IXH,C */
961 {
962 	if (u_flag) {
963 		trap_dd();
964 		return(0);
965 	}
966 
967 	IX = (IX & 0x00ff) | (C << 8);
968 	return(8);
969 }
970 
op_undoc_ldixld(void)971 static int op_undoc_ldixld(void)	/* LD IXL,D */
972 {
973 	if (u_flag) {
974 		trap_dd();
975 		return(0);
976 	}
977 
978 	IX = (IX & 0xff00) | D;
979 	return(8);
980 }
981 
op_undoc_ldixhd(void)982 static int op_undoc_ldixhd(void)	/* LD IXH,D */
983 {
984 	if (u_flag) {
985 		trap_dd();
986 		return(0);
987 	}
988 
989 	IX = (IX & 0x00ff) | (D << 8);
990 	return(8);
991 }
992 
op_undoc_ldixle(void)993 static int op_undoc_ldixle(void)	/* LD IXL,E */
994 {
995 	if (u_flag) {
996 		trap_dd();
997 		return(0);
998 	}
999 
1000 	IX = (IX & 0xff00) | E;
1001 	return(8);
1002 }
1003 
op_undoc_ldixhe(void)1004 static int op_undoc_ldixhe(void)	/* LD IXH,E */
1005 {
1006 	if (u_flag) {
1007 		trap_dd();
1008 		return(0);
1009 	}
1010 
1011 	IX = (IX & 0x00ff) | (E << 8);
1012 	return(8);
1013 }
1014 
op_undoc_ldixlixh(void)1015 static int op_undoc_ldixlixh(void)	/* LD IXL,IXH */
1016 {
1017 	if (u_flag) {
1018 		trap_dd();
1019 		return(0);
1020 	}
1021 
1022 	IX = (IX & 0xff00) | (IX >> 8);
1023 	return(8);
1024 }
1025 
op_undoc_ldixhixh(void)1026 static int op_undoc_ldixhixh(void)	/* LD IXH,IXH */
1027 {
1028 	if (u_flag) {
1029 		trap_dd();
1030 		return(0);
1031 	}
1032 
1033 	return(8);
1034 }
1035 
op_undoc_ldixlixl(void)1036 static int op_undoc_ldixlixl(void)	/* LD IXL,IXL */
1037 {
1038 	if (u_flag) {
1039 		trap_dd();
1040 		return(0);
1041 	}
1042 
1043 	return(8);
1044 }
1045 
op_undoc_ldixhixl(void)1046 static int op_undoc_ldixhixl(void)	/* LD IXH,IXL */
1047 {
1048 	if (u_flag) {
1049 		trap_dd();
1050 		return(0);
1051 	}
1052 
1053 	IX = (IX & 0x00ff) | (IX << 8);
1054 	return(8);
1055 }
1056 
op_undoc_ldixhn(void)1057 static int op_undoc_ldixhn(void)	/* LD IXH,n */
1058 {
1059 	if (u_flag) {
1060 		trap_dd();
1061 		return(0);
1062 	}
1063 
1064 	IX = (IX & 0x00ff) | (memrdr(PC++) << 8);
1065 	return(11);
1066 }
1067 
op_undoc_ldixln(void)1068 static int op_undoc_ldixln(void)	/* LD IXL,n */
1069 {
1070 	if (u_flag) {
1071 		trap_dd();
1072 		return(0);
1073 	}
1074 
1075 	IX = (IX & 0xff00) | memrdr(PC++);
1076 	return(11);
1077 }
1078 
op_undoc_cpixl(void)1079 static int op_undoc_cpixl(void)		/* CP IXL */
1080 {
1081 	register int i;
1082 	register BYTE P;
1083 
1084 	if (u_flag) {
1085 		trap_dd();
1086 		return(0);
1087 	}
1088 
1089 	P = IX & 0xff;
1090 	((P & 0xf) > (A	& 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
1091 	(P > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
1092 	i = (signed char) A - (signed char) P;
1093 	(i < -128 || i > 127) ?	(F |= P_FLAG) : (F &= ~P_FLAG);
1094 	(i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
1095 	(i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
1096 	F |= N_FLAG;
1097 	return(8);
1098 }
1099 
op_undoc_acaixl(void)1100 static int op_undoc_acaixl(void)	/* ADC A,IXL */
1101 {
1102 	register int i, carry;
1103 	register BYTE P;
1104 
1105 	if (u_flag) {
1106 		trap_dd();
1107 		return(0);
1108 	}
1109 
1110 	carry = (F & C_FLAG) ? 1 : 0;
1111 	P = IX & 0xff;
1112 	((A & 0xf) + (P	& 0xf) + carry > 0xf) ?	(F |= H_FLAG) : (F &= ~H_FLAG);
1113 	(A + P + carry > 255) ?	(F |= C_FLAG) : (F &= ~C_FLAG);
1114 	A = i = (signed char) A + (signed char) P + carry;
1115 	(i < -128 || i > 127) ?	(F |= P_FLAG) : (F &= ~P_FLAG);
1116 	(i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
1117 	(A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
1118 	F &= ~N_FLAG;
1119 	return(8);
1120 }
1121 
op_undoc_acaixh(void)1122 static int op_undoc_acaixh(void)	/* ADC A,IXH */
1123 {
1124 	register int i, carry;
1125 	register BYTE P;
1126 
1127 	if (u_flag) {
1128 		trap_dd();
1129 		return(0);
1130 	}
1131 
1132 	carry = (F & C_FLAG) ? 1 : 0;
1133 	P = IX >> 8;
1134 	((A & 0xf) + (P	& 0xf) + carry > 0xf) ?	(F |= H_FLAG) : (F &= ~H_FLAG);
1135 	(A + P + carry > 255) ?	(F |= C_FLAG) : (F &= ~C_FLAG);
1136 	A = i = (signed char) A + (signed char) P + carry;
1137 	(i < -128 || i > 127) ?	(F |= P_FLAG) : (F &= ~P_FLAG);
1138 	(i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
1139 	(A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
1140 	F &= ~N_FLAG;
1141 	return(8);
1142 }
1143 
op_undoc_scaixl(void)1144 static int op_undoc_scaixl(void)	/* SBC A,IXL */
1145 {
1146 	register int i, carry;
1147 	register BYTE P;
1148 
1149 	if (u_flag) {
1150 		trap_dd();
1151 		return(0);
1152 	}
1153 
1154 	carry = (F & C_FLAG) ? 1 : 0;
1155 	P = IX & 0xff;
1156 	((P & 0xf) + carry > (A	& 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
1157 	(P + carry > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
1158 	A = i = (signed char) A - (signed char) P - carry;
1159 	(i < -128 || i > 127) ?	(F |= P_FLAG) : (F &= ~P_FLAG);
1160 	(i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
1161 	(A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
1162 	F |= N_FLAG;
1163 	return(8);
1164 }
1165 
op_undoc_scaixh(void)1166 static int op_undoc_scaixh(void)	/* SBC A,IXH */
1167 {
1168 	register int i, carry;
1169 	register BYTE P;
1170 
1171 	if (u_flag) {
1172 		trap_dd();
1173 		return(0);
1174 	}
1175 
1176 	carry = (F & C_FLAG) ? 1 : 0;
1177 	P = IX >> 8;
1178 	((P & 0xf) + carry > (A	& 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
1179 	(P + carry > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
1180 	A = i = (signed char) A - (signed char) P - carry;
1181 	(i < -128 || i > 127) ?	(F |= P_FLAG) : (F &= ~P_FLAG);
1182 	(i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
1183 	(A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
1184 	F |= N_FLAG;
1185 	return(8);
1186 }
1187 
op_undoc_oraixl(void)1188 static int op_undoc_oraixl(void)	/* OR IXL */
1189 {
1190 	if (u_flag) {
1191 		trap_dd();
1192 		return(0);
1193 	}
1194 
1195 	A |= IX & 0xff;
1196 	(A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
1197 	(A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
1198 	(parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
1199 	F &= ~(H_FLAG | N_FLAG | C_FLAG);
1200 	return(8);
1201 }
1202 
op_undoc_oraixh(void)1203 static int op_undoc_oraixh(void)	/* OR IXH */
1204 {
1205 	if (u_flag) {
1206 		trap_dd();
1207 		return(0);
1208 	}
1209 
1210 	A |= IX >> 8;
1211 	(A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
1212 	(A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
1213 	(parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
1214 	F &= ~(H_FLAG | N_FLAG | C_FLAG);
1215 	return(8);
1216 }
1217 
op_undoc_andixl(void)1218 static int op_undoc_andixl(void)	/* AND IXL */
1219 {
1220 	if (u_flag) {
1221 		trap_dd();
1222 		return(0);
1223 	}
1224 
1225 	A &= IX & 0xff;
1226 	(A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
1227 	(A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
1228 	F |= H_FLAG;
1229 	(parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
1230 	F &= ~(N_FLAG | C_FLAG);
1231 	return(8);
1232 }
1233 
op_undoc_andixh(void)1234 static int op_undoc_andixh(void)	/* AND IXH */
1235 {
1236 	if (u_flag) {
1237 		trap_dd();
1238 		return(0);
1239 	}
1240 
1241 	A &= IX >> 8;
1242 	(A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
1243 	(A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
1244 	F |= H_FLAG;
1245 	(parity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
1246 	F &= ~(N_FLAG | C_FLAG);
1247 	return(8);
1248 }
1249 
op_undoc_incixl(void)1250 static int op_undoc_incixl(void)	/* INC IXL */
1251 {
1252 	register BYTE P;
1253 
1254 	if (u_flag) {
1255 		trap_dd();
1256 		return(0);
1257 	}
1258 
1259 	P = IX & 0xff;
1260 	P++;
1261 	IX = (IX & 0xff00) | P;
1262 	((P & 0xf) == 0) ? (F |= H_FLAG) : (F &= ~H_FLAG);
1263 	(P == 128) ? (F |= P_FLAG) : (F &= ~P_FLAG);
1264 	(P & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
1265 	(P) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
1266 	F &= ~N_FLAG;
1267 	return(8);
1268 }
1269 
op_undoc_incixh(void)1270 static int op_undoc_incixh(void)	/* INC IXH */
1271 {
1272 	register BYTE P;
1273 
1274 	if (u_flag) {
1275 		trap_dd();
1276 		return(0);
1277 	}
1278 
1279 	P = IX >> 8;
1280 	P++;
1281 	IX = (IX & 0x00ff) | (P << 8);
1282 	((P & 0xf) == 0) ? (F |= H_FLAG) : (F &= ~H_FLAG);
1283 	(P == 128) ? (F |= P_FLAG) : (F &= ~P_FLAG);
1284 	(P & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
1285 	(P) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
1286 	F &= ~N_FLAG;
1287 	return(8);
1288 }
1289 
op_undoc_decixl(void)1290 static int op_undoc_decixl(void)	/* DEC IXL */
1291 {
1292 	register BYTE P;
1293 
1294 	if (u_flag) {
1295 		trap_dd();
1296 		return(0);
1297 	}
1298 
1299 	P = IX & 0xff;
1300 	P--;
1301 	IX = (IX & 0xff00) | P;
1302 	((P & 0xf) == 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
1303 	(P == 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
1304 	(P & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
1305 	(P) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
1306 	F |= N_FLAG;
1307 	return(8);
1308 }
1309 
op_undoc_decixh(void)1310 static int op_undoc_decixh(void)	/* DEC IXH */
1311 {
1312 	register BYTE P;
1313 
1314 	if (u_flag) {
1315 		trap_dd();
1316 		return(0);
1317 	}
1318 
1319 	P = IX >> 8;
1320 	P--;
1321 	IX = (IX & 0x00ff) | (P << 8);
1322 	((P & 0xf) == 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
1323 	(P == 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
1324 	(P & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
1325 	(P) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
1326 	F |= N_FLAG;
1327 	return(8);
1328 }
1329 
1330 #endif
1331