1 /*****************************************************************************
2  *
3  *	 i8085.c
4  *	 Portable I8085A emulator V1.2
5  *
6  *	 Copyright (c) 1999 Juergen Buchmueller, all rights reserved.
7  *	 Partially based on information out of Z80Em by Marcel De Kogel
8  *
9  * changes in V1.3
10  *   - Added undocumented opcodes for the 8085A, based on a german
11  *     book about microcomputers: "Mikrocomputertechnik mit dem
12  *     Prozessor 8085A".
13  *   - This book also suggest that INX/DCX should modify the X flag bit
14  *     for a LSB to MSB carry and
15  *   - that jumps take 10 T-states only when they're executed, 7 when
16  *     they're skipped.
17  *     Thanks for the info and a copy of the tables go to Timo Sachsenberg
18  *     <timo.sachsenberg@student.uni-tuebingen.de>
19  * changes in V1.2
20  *	 - corrected cycle counts for these classes of opcodes
21  *	   Thanks go to Jim Battle <frustum@pacbell.bet>
22  *
23  *					808x	 Z80
24  *	   DEC A		   5	   4	\
25  *	   INC A		   5	   4	 \
26  *	   LD A,B		   5	   4	  >-- Z80 is faster
27  *	   JP (HL)		   5	   4	 /
28  *	   CALL cc,nnnn: 11/17	 10/17	/
29  *
30  *	   INC HL		   5	   6	\
31  *	   DEC HL		   5	   6	 \
32  *	   LD SP,HL 	   5	   6	  \
33  *	   ADD HL,BC	  10	  11	   \
34  *	   INC (HL) 	  10	  11		>-- 8080 is faster
35  *	   DEC (HL) 	  10	  11	   /
36  *	   IN A,(#) 	  10	  11	  /
37  *	   OUT (#),A	  10	  11	 /
38  *	   EX (SP),HL	  18	  19	/
39  *
40  *	 - This source code is released as freeware for non-commercial purposes.
41  *	 - You are free to use and redistribute this code in modified or
42  *	   unmodified form, provided you list me in the credits.
43  *	 - If you modify this source code, you must add a notice to each modified
44  *	   source file that it has been changed.  If you're a nice person, you
45  *	   will clearly mark each change too.  :)
46  *	 - If you wish to use this for commercial purposes, please contact me at
47  *	   pullmoll@t-online.de
48  *	 - The author of this copywritten work reserves the right to change the
49  *	   terms of its usage and license at any time, including retroactively
50  *	 - This entire notice must remain in the source code.
51  *
52  *
53  * Revisions:
54  *
55  * xx-xx-2002 Acho A. Tang
56  *
57  * - 8085 emulation was in fact never used. It's been treated as a plain 8080.
58  * - protected IRQ0 vector from being overwritten
59  * - modified interrupt handler to properly process 8085-specific IRQ's
60  * - corrected interrupt masking, RIM and SIM behaviors according to Intel's documentation
61  *
62  * 20-Jul-2002 Krzysztof Strzecha
63  *
64  * - SBB r instructions should affect parity flag.
65  *   Fixed only for non x86 asm version (#define i8080_EXACT 1).
66  *   There are probably more opcodes which should affect this flag, but don't.
67  * - JPO nnnn and JPE nnnn opcodes in disassembler were misplaced. Fixed.
68  * - Undocumented i8080 opcodes added:
69  *   08h, 10h, 18h, 20h, 28h, 30h, 38h  -  NOP
70  *   0CBh                               -  JMP
71  *   0D9h                               -  RET
72  *   0DDh, 0EDh, 0FDh                   -  CALL
73  *   Thanks for the info go to Anton V. Ignatichev.
74  *
75  * 08-Dec-2002 Krzysztof Strzecha
76  *
77  * - ADC r instructions should affect parity flag.
78  *   Fixed only for non x86 asm version (#define i8080_EXACT 1).
79  *   There are probably more opcodes which should affect this flag, but don't.
80  *
81  * 05-Sep-2003 Krzysztof Strzecha
82  *
83  * - INR r, DCR r, ADD r, SUB r, CMP r instructions should affect parity flag.
84  *   Fixed only for non x86 asm version (#define i8080_EXACT 1).
85  *
86  *****************************************************************************/
87 
88 /*int survival_prot = 0; */
89 
90 #include "driver.h"
91 #include "state.h"
92 #include "osd_cpu.h"
93 #include "mamedbg.h"
94 #include "i8085.h"
95 #include "i8085cpu.h"
96 #include "i8085daa.h"
97 
98 #include "log.h"
99 
100 #define I8085_INTR      0xff
101 
102 /* Layout of the registers in the debugger */
103 static UINT8 i8085_reg_layout[] = {
104 	I8085_PC,I8085_SP,I8085_AF,I8085_BC,I8085_DE,I8085_HL, -1,
105 	I8085_HALT,I8085_IM,I8085_IREQ,I8085_ISRV,I8085_VECTOR, -1,
106 	I8085_TRAP_STATE,I8085_INTR_STATE,I8085_RST55_STATE,I8085_RST65_STATE,I8085_RST75_STATE,
107 	0 };
108 
109 /* Layout of the debugger windows x,y,w,h */
110 static UINT8 i8085_win_layout[] = {
111 	25, 0,55, 3,	/* register window (top, right rows) */
112 	 0, 0,24,22,	/* disassembler window (left colums) */
113 	25, 4,55, 9,	/* memory #1 window (right, upper middle) */
114 	25,14,55, 8,	/* memory #2 window (right, lower middle) */
115 	 0,23,80, 1,	/* command line window (bottom rows) */
116 };
117 
118 
119 typedef struct {
120 	int 	cputype;	/* 0 8080, 1 8085A */
121 	PAIR	PC,SP,AF,BC,DE,HL,XX;
122 	UINT8	HALT;
123 	UINT8	IM; 		/* interrupt mask */
124 	UINT8	IREQ;		/* requested interrupts */
125 	UINT8	ISRV;		/* serviced interrupt */
126 	UINT32	INTR;		/* vector for INTR */
127 	UINT32	IRQ2;		/* scheduled interrupt address */
128 	UINT32	IRQ1;		/* executed interrupt address */
129 	INT8	nmi_state;
130 	INT8	irq_state[4];
131 	INT8	filler; /* align on dword boundary */
132 	int 	(*irq_callback)(int);
133 	void	(*sod_callback)(int state);
134 }	i8085_Regs;
135 
136 int i8085_ICount = 0;
137 
138 static i8085_Regs I;
139 static UINT8 ZS[256];
140 static UINT8 ZSP[256];
141 static UINT8 RIM_IEN = 0; /*AT: IEN status latch used by the RIM instruction*/
ROP(void)142 static UINT8 ROP(void)
143 {
144 	return cpu_readop(I.PC.w.l++);
145 }
146 
ARG(void)147 static UINT8 ARG(void)
148 {
149 	return cpu_readop_arg(I.PC.w.l++);
150 }
151 
ARG16(void)152 static UINT16 ARG16(void)
153 {
154 	UINT16 w;
155 	w  = cpu_readop_arg(I.PC.d);
156 	I.PC.w.l++;
157 	w += cpu_readop_arg(I.PC.d) << 8;
158 	I.PC.w.l++;
159 	return w;
160 }
161 
RM(UINT32 a)162 static UINT8 RM(UINT32 a)
163 {
164 	return cpu_readmem16(a);
165 }
166 
WM(UINT32 a,UINT8 v)167 static void WM(UINT32 a, UINT8 v)
168 {
169 	cpu_writemem16(a, v);
170 }
171 
illegal(void)172 static	void illegal(void)
173 {
174 	UINT16 pc = I.PC.w.l - 1;
175 	log_cb(RETRO_LOG_DEBUG, LOGPRE "i8085 illegal instruction %04X $%02X\n", pc, cpu_readop(pc));
176 }
177 
execute_one(int opcode)178 static INLINE void execute_one(int opcode)
179 {
180 	switch (opcode)
181 	{
182 		case 0x00: i8085_ICount -= 4;	/* NOP	*/
183 			/* no op */
184 			break;
185 		case 0x01: i8085_ICount -= 10;	/* LXI	B,nnnn */
186 			I.BC.w.l = ARG16();
187 			break;
188 		case 0x02: i8085_ICount -= 7;	/* STAX B */
189 			WM(I.BC.d, I.AF.b.h);
190 			break;
191 		case 0x03: i8085_ICount -= 5;	/* INX	B */
192 			I.BC.w.l++;
193 			if (I.BC.b.l == 0x00) I.AF.b.l |= XF; else I.AF.b.l &= ~XF;
194 			break;
195 		case 0x04: i8085_ICount -= 5;	/* INR	B */
196 			M_INR(I.BC.b.h);
197 			break;
198 		case 0x05: i8085_ICount -= 5;	/* DCR	B */
199 			M_DCR(I.BC.b.h);
200 			break;
201 		case 0x06: i8085_ICount -= 7;	/* MVI	B,nn */
202 			M_MVI(I.BC.b.h);
203 			break;
204 		case 0x07: i8085_ICount -= 4;	/* RLC	*/
205 			M_RLC;
206 			break;
207 
208 		case 0x08:
209 			if( I.cputype ) {
210 				i8085_ICount -= 10;		/* DSUB */
211 				M_DSUB();
212 			} else {
213 				i8085_ICount -= 4;		/* NOP undocumented */
214 			}
215 			break;
216 		case 0x09: i8085_ICount -= 10;	/* DAD	B */
217 			M_DAD(BC);
218 			break;
219 		case 0x0a: i8085_ICount -= 7;	/* LDAX B */
220 			I.AF.b.h = RM(I.BC.d);
221 			break;
222 		case 0x0b: i8085_ICount -= 5;	/* DCX	B */
223 			I.BC.w.l--;
224 			if (I.BC.b.l == 0xff) I.AF.b.l |= XF; else I.AF.b.l &= ~XF;
225 			break;
226 		case 0x0c: i8085_ICount -= 5;	/* INR	C */
227 			M_INR(I.BC.b.l);
228 			break;
229 		case 0x0d: i8085_ICount -= 5;	/* DCR	C */
230 			M_DCR(I.BC.b.l);
231 			break;
232 		case 0x0e: i8085_ICount -= 7;	/* MVI	C,nn */
233 			M_MVI(I.BC.b.l);
234 			break;
235 		case 0x0f: i8085_ICount -= 4;	/* RRC	*/
236 			M_RRC;
237 			break;
238 
239 		case 0x10:
240 			if( I.cputype ) {
241 				i8085_ICount -= 7;		/* ASRH */
242 				I.AF.b.l = (I.AF.b.l & ~CF) | (I.HL.b.l & CF);
243 				I.HL.w.l = (I.HL.w.l >> 1);
244 			} else {
245 				i8085_ICount -= 4;		/* NOP undocumented */
246 			}
247 			break;
248 		case 0x11: i8085_ICount -= 10;	/* LXI	D,nnnn */
249 			I.DE.w.l = ARG16();
250 			break;
251 		case 0x12: i8085_ICount -= 7;	/* STAX D */
252 			WM(I.DE.d, I.AF.b.h);
253 			break;
254 		case 0x13: i8085_ICount -= 5;	/* INX	D */
255 			I.DE.w.l++;
256 			if (I.DE.b.l == 0x00) I.AF.b.l |= XF; else I.AF.b.l &= ~XF;
257 			break;
258 		case 0x14: i8085_ICount -= 5;	/* INR	D */
259 			M_INR(I.DE.b.h);
260 			break;
261 		case 0x15: i8085_ICount -= 5;	/* DCR	D */
262 			M_DCR(I.DE.b.h);
263 			break;
264 		case 0x16: i8085_ICount -= 7;	/* MVI	D,nn */
265 			M_MVI(I.DE.b.h);
266 			break;
267 		case 0x17: i8085_ICount -= 4;	/* RAL	*/
268 			M_RAL;
269 			break;
270 
271 		case 0x18:
272 			if( I.cputype ) {
273 				i8085_ICount -= 10;		/* RLDE */
274 				I.AF.b.l = (I.AF.b.l & ~(CF | VF)) | (I.DE.b.h >> 7);
275 				I.DE.w.l = (I.DE.w.l << 1) | (I.DE.w.l >> 15);
276 				if (0 != (((I.DE.w.l >> 15) ^ I.AF.b.l) & CF))
277 					I.AF.b.l |= VF;
278 			} else {
279 				i8085_ICount -= 4;		/* NOP undocumented */
280 			}
281 			break;
282 		case 0x19: i8085_ICount -= 10;	/* DAD	D */
283 			M_DAD(DE);
284 			break;
285 		case 0x1a: i8085_ICount -= 7;	/* LDAX D */
286 			I.AF.b.h = RM(I.DE.d);
287 			break;
288 		case 0x1b: i8085_ICount -= 5;	/* DCX	D */
289 			I.DE.w.l--;
290 			if (I.DE.b.l == 0xff) I.AF.b.l |= XF; else I.AF.b.l &= ~XF;
291 			break;
292 		case 0x1c: i8085_ICount -= 5;	/* INR	E */
293 			M_INR(I.DE.b.l);
294 			break;
295 		case 0x1d: i8085_ICount -= 5;	/* DCR	E */
296 			M_DCR(I.DE.b.l);
297 			break;
298 		case 0x1e: i8085_ICount -= 7;	/* MVI	E,nn */
299 			M_MVI(I.DE.b.l);
300 			break;
301 		case 0x1f: i8085_ICount -= 4;	/* RAR	*/
302 			M_RAR;
303 			break;
304 
305 		case 0x20:
306 			if( I.cputype ) {
307 				i8085_ICount -= 7;		/* RIM	*/
308 				I.AF.b.h = I.IM;
309 				I.AF.b.h |= RIM_IEN; RIM_IEN = 0; /*AT: read and clear IEN status latch*/
310 /*				survival_prot ^= 0x01; */
311 			} else {
312 				i8085_ICount -= 4;		/* NOP undocumented */
313 			}
314 			break;
315 		case 0x21: i8085_ICount -= 10;	/* LXI	H,nnnn */
316 			I.HL.w.l = ARG16();
317 			break;
318 		case 0x22: i8085_ICount -= 16;	/* SHLD nnnn */
319 			I.XX.w.l = ARG16();
320 			WM(I.XX.d, I.HL.b.l);
321 			I.XX.w.l++;
322 			WM(I.XX.d, I.HL.b.h);
323 			break;
324 		case 0x23: i8085_ICount -= 5;	/* INX	H */
325 			I.HL.w.l++;
326 			if (I.HL.b.l == 0x00) I.AF.b.l |= XF; else I.AF.b.l &= ~XF;
327 			break;
328 		case 0x24: i8085_ICount -= 5;	/* INR	H */
329 			M_INR(I.HL.b.h);
330 			break;
331 		case 0x25: i8085_ICount -= 5;	/* DCR	H */
332 			M_DCR(I.HL.b.h);
333 			break;
334 		case 0x26: i8085_ICount -= 7;	/* MVI	H,nn */
335 			M_MVI(I.HL.b.h);
336 			break;
337 		case 0x27: i8085_ICount -= 4;	/* DAA	*/
338 			I.XX.d = I.AF.b.h;
339 			if (I.AF.b.l & CF) I.XX.d |= 0x100;
340 			if (I.AF.b.l & HF) I.XX.d |= 0x200;
341 			if (I.AF.b.l & NF) I.XX.d |= 0x400;
342 			I.AF.w.l = DAA[I.XX.d];
343 			break;
344 
345 		case 0x28:
346 			if( I.cputype ) {
347 				i8085_ICount -= 10;		/* LDEH nn */
348 				I.XX.d = ARG();
349 				I.DE.d = (I.HL.d + I.XX.d) & 0xffff;
350 			} else {
351 				i8085_ICount -= 4;		/* NOP undocumented */
352 			}
353 			break;
354 		case 0x29: i8085_ICount -= 10;	/* DAD	H */
355 			M_DAD(HL);
356 			break;
357 		case 0x2a: i8085_ICount -= 16;	/* LHLD nnnn */
358 			I.XX.d = ARG16();
359 			I.HL.b.l = RM(I.XX.d);
360 			I.XX.w.l++;
361 			I.HL.b.h = RM(I.XX.d);
362 			break;
363 		case 0x2b: i8085_ICount -= 5;	/* DCX	H */
364 			I.HL.w.l--;
365 			if (I.HL.b.l == 0xff) I.AF.b.l |= XF; else I.AF.b.l &= ~XF;
366 			break;
367 		case 0x2c: i8085_ICount -= 5;	/* INR	L */
368 			M_INR(I.HL.b.l);
369 			break;
370 		case 0x2d: i8085_ICount -= 5;	/* DCR	L */
371 			M_DCR(I.HL.b.l);
372 			break;
373 		case 0x2e: i8085_ICount -= 7;	/* MVI	L,nn */
374 			M_MVI(I.HL.b.l);
375 			break;
376 		case 0x2f: i8085_ICount -= 4;	/* CMA	*/
377 			I.AF.b.h ^= 0xff;
378 			I.AF.b.l |= HF + NF;
379 			break;
380 
381 		case 0x30:
382 			if( I.cputype ) {
383 				i8085_ICount -= 7;		/* SIM	*/
384 				if ((I.IM ^ I.AF.b.h) & 0x80)
385 					if (I.sod_callback) (*I.sod_callback)(I.AF.b.h >> 7);
386 /*AT*/
387 				/*I.IM &= (IM_SID + IM_IEN + IM_TRAP);*/
388 				/*I.IM |= (I.AF.b.h & ~(IM_SID + IM_SOD + IM_IEN + IM_TRAP));*/
389 
390 				/* overwrite RST5.5-7.5 interrupt masks only when bit 0x08 of the accumulator is set*/
391 				if (I.AF.b.h & 0x08)
392 					I.IM = (I.IM & ~(IM_RST55+IM_RST65+IM_RST75)) | (I.AF.b.h & (IM_RST55+IM_RST65+IM_RST75));
393 /*ZT*/
394 				if (I.AF.b.h & 0x80) I.IM |= IM_SOD;
395 			} else {
396 				i8085_ICount -= 4;		/* NOP undocumented */
397 			}
398 			break;
399 		case 0x31: i8085_ICount -= 10;	/* LXI SP,nnnn */
400 			I.SP.w.l = ARG16();
401 			break;
402 		case 0x32: i8085_ICount -= 13;	/* STAX nnnn */
403 			I.XX.d = ARG16();
404 			WM(I.XX.d, I.AF.b.h);
405 			break;
406 		case 0x33: i8085_ICount -= 5;	/* INX	SP */
407 			I.SP.w.l++;
408 			if (I.SP.b.l == 0x00) I.AF.b.l |= XF; else I.AF.b.l &= ~XF;
409 			break;
410 		case 0x34: i8085_ICount -= 10;	/* INR	M */
411 			I.XX.b.l = RM(I.HL.d);
412 			M_INR(I.XX.b.l);
413 			WM(I.HL.d, I.XX.b.l);
414 			break;
415 		case 0x35: i8085_ICount -= 10;	/* DCR	M */
416 			I.XX.b.l = RM(I.HL.d);
417 			M_DCR(I.XX.b.l);
418 			WM(I.HL.d, I.XX.b.l);
419 			break;
420 		case 0x36: i8085_ICount -= 10;	/* MVI	M,nn */
421 			I.XX.b.l = ARG();
422 			WM(I.HL.d, I.XX.b.l);
423 			break;
424 		case 0x37: i8085_ICount -= 4;	/* STC	*/
425 			I.AF.b.l = (I.AF.b.l & ~(HF + NF)) | CF;
426 			break;
427 
428 		case 0x38:
429 			if( I.cputype ) {
430 				i8085_ICount -= 10;		/* LDES nn */
431 				I.XX.d = ARG();
432 				I.DE.d = (I.SP.d + I.XX.d) & 0xffff;
433 			} else {
434 				i8085_ICount -= 4;		/* NOP undocumented */
435 			}
436 			break;
437 		case 0x39: i8085_ICount -= 10;	/* DAD SP */
438 			M_DAD(SP);
439 			break;
440 		case 0x3a: i8085_ICount -= 13;	/* LDAX nnnn */
441 			I.XX.d = ARG16();
442 			I.AF.b.h = RM(I.XX.d);
443 			break;
444 		case 0x3b: i8085_ICount -= 5;	/* DCX	SP */
445 			I.SP.w.l--;
446 			if (I.SP.b.l == 0xff) I.AF.b.l |= XF; else I.AF.b.l &= ~XF;
447 			break;
448 		case 0x3c: i8085_ICount -= 5;	/* INR	A */
449 			M_INR(I.AF.b.h);
450 			break;
451 		case 0x3d: i8085_ICount -= 5;	/* DCR	A */
452 			M_DCR(I.AF.b.h);
453 			break;
454 		case 0x3e: i8085_ICount -= 7;	/* MVI	A,nn */
455 			M_MVI(I.AF.b.h);
456 			break;
457 		case 0x3f: i8085_ICount -= 4;	/* CMF	*/
458 			I.AF.b.l = ((I.AF.b.l & ~(HF + NF)) |
459 					   ((I.AF.b.l & CF) << 4)) ^ CF;
460 			break;
461 
462 		case 0x40: i8085_ICount -= 5;	/* MOV	B,B */
463 			/* no op */
464 			break;
465 		case 0x41: i8085_ICount -= 5;	/* MOV	B,C */
466 			I.BC.b.h = I.BC.b.l;
467 			break;
468 		case 0x42: i8085_ICount -= 5;	/* MOV	B,D */
469 			I.BC.b.h = I.DE.b.h;
470 			break;
471 		case 0x43: i8085_ICount -= 5;	/* MOV	B,E */
472 			I.BC.b.h = I.DE.b.l;
473 			break;
474 		case 0x44: i8085_ICount -= 5;	/* MOV	B,H */
475 			I.BC.b.h = I.HL.b.h;
476 			break;
477 		case 0x45: i8085_ICount -= 5;	/* MOV	B,L */
478 			I.BC.b.h = I.HL.b.l;
479 			break;
480 		case 0x46: i8085_ICount -= 7;	/* MOV	B,M */
481 			I.BC.b.h = RM(I.HL.d);
482 			break;
483 		case 0x47: i8085_ICount -= 5;	/* MOV	B,A */
484 			I.BC.b.h = I.AF.b.h;
485 			break;
486 
487 		case 0x48: i8085_ICount -= 5;	/* MOV	C,B */
488 			I.BC.b.l = I.BC.b.h;
489 			break;
490 		case 0x49: i8085_ICount -= 5;	/* MOV	C,C */
491 			/* no op */
492 			break;
493 		case 0x4a: i8085_ICount -= 5;	/* MOV	C,D */
494 			I.BC.b.l = I.DE.b.h;
495 			break;
496 		case 0x4b: i8085_ICount -= 5;	/* MOV	C,E */
497 			I.BC.b.l = I.DE.b.l;
498 			break;
499 		case 0x4c: i8085_ICount -= 5;	/* MOV	C,H */
500 			I.BC.b.l = I.HL.b.h;
501 			break;
502 		case 0x4d: i8085_ICount -= 5;	/* MOV	C,L */
503 			I.BC.b.l = I.HL.b.l;
504 			break;
505 		case 0x4e: i8085_ICount -= 7;	/* MOV	C,M */
506 			I.BC.b.l = RM(I.HL.d);
507 			break;
508 		case 0x4f: i8085_ICount -= 5;	/* MOV	C,A */
509 			I.BC.b.l = I.AF.b.h;
510 			break;
511 
512 		case 0x50: i8085_ICount -= 5;	/* MOV	D,B */
513 			I.DE.b.h = I.BC.b.h;
514 			break;
515 		case 0x51: i8085_ICount -= 5;	/* MOV	D,C */
516 			I.DE.b.h = I.BC.b.l;
517 			break;
518 		case 0x52: i8085_ICount -= 5;	/* MOV	D,D */
519 			/* no op */
520 			break;
521 		case 0x53: i8085_ICount -= 5;	/* MOV	D,E */
522 			I.DE.b.h = I.DE.b.l;
523 			break;
524 		case 0x54: i8085_ICount -= 5;	/* MOV	D,H */
525 			I.DE.b.h = I.HL.b.h;
526 			break;
527 		case 0x55: i8085_ICount -= 5;	/* MOV	D,L */
528 			I.DE.b.h = I.HL.b.l;
529 			break;
530 		case 0x56: i8085_ICount -= 7;	/* MOV	D,M */
531 			I.DE.b.h = RM(I.HL.d);
532 			break;
533 		case 0x57: i8085_ICount -= 5;	/* MOV	D,A */
534 			I.DE.b.h = I.AF.b.h;
535 			break;
536 
537 		case 0x58: i8085_ICount -= 5;	/* MOV	E,B */
538 			I.DE.b.l = I.BC.b.h;
539 			break;
540 		case 0x59: i8085_ICount -= 5;	/* MOV	E,C */
541 			I.DE.b.l = I.BC.b.l;
542 			break;
543 		case 0x5a: i8085_ICount -= 5;	/* MOV	E,D */
544 			I.DE.b.l = I.DE.b.h;
545 			break;
546 		case 0x5b: i8085_ICount -= 5;	/* MOV	E,E */
547 			/* no op */
548 			break;
549 		case 0x5c: i8085_ICount -= 5;	/* MOV	E,H */
550 			I.DE.b.l = I.HL.b.h;
551 			break;
552 		case 0x5d: i8085_ICount -= 5;	/* MOV	E,L */
553 			I.DE.b.l = I.HL.b.l;
554 			break;
555 		case 0x5e: i8085_ICount -= 7;	/* MOV	E,M */
556 			I.DE.b.l = RM(I.HL.d);
557 			break;
558 		case 0x5f: i8085_ICount -= 5;	/* MOV	E,A */
559 			I.DE.b.l = I.AF.b.h;
560 			break;
561 
562 		case 0x60: i8085_ICount -= 5;	/* MOV	H,B */
563 			I.HL.b.h = I.BC.b.h;
564 			break;
565 		case 0x61: i8085_ICount -= 5;	/* MOV	H,C */
566 			I.HL.b.h = I.BC.b.l;
567 			break;
568 		case 0x62: i8085_ICount -= 5;	/* MOV	H,D */
569 			I.HL.b.h = I.DE.b.h;
570 			break;
571 		case 0x63: i8085_ICount -= 5;	/* MOV	H,E */
572 			I.HL.b.h = I.DE.b.l;
573 			break;
574 		case 0x64: i8085_ICount -= 5;	/* MOV	H,H */
575 			/* no op */
576 			break;
577 		case 0x65: i8085_ICount -= 5;	/* MOV	H,L */
578 			I.HL.b.h = I.HL.b.l;
579 			break;
580 		case 0x66: i8085_ICount -= 7;	/* MOV	H,M */
581 			I.HL.b.h = RM(I.HL.d);
582 			break;
583 		case 0x67: i8085_ICount -= 5;	/* MOV	H,A */
584 			I.HL.b.h = I.AF.b.h;
585 			break;
586 
587 		case 0x68: i8085_ICount -= 5;	/* MOV	L,B */
588 			I.HL.b.l = I.BC.b.h;
589 			break;
590 		case 0x69: i8085_ICount -= 5;	/* MOV	L,C */
591 			I.HL.b.l = I.BC.b.l;
592 			break;
593 		case 0x6a: i8085_ICount -= 5;	/* MOV	L,D */
594 			I.HL.b.l = I.DE.b.h;
595 			break;
596 		case 0x6b: i8085_ICount -= 5;	/* MOV	L,E */
597 			I.HL.b.l = I.DE.b.l;
598 			break;
599 		case 0x6c: i8085_ICount -= 5;	/* MOV	L,H */
600 			I.HL.b.l = I.HL.b.h;
601 			break;
602 		case 0x6d: i8085_ICount -= 5;	/* MOV	L,L */
603 			/* no op */
604 			break;
605 		case 0x6e: i8085_ICount -= 7;	/* MOV	L,M */
606 			I.HL.b.l = RM(I.HL.d);
607 			break;
608 		case 0x6f: i8085_ICount -= 5;	/* MOV	L,A */
609 			I.HL.b.l = I.AF.b.h;
610 			break;
611 
612 		case 0x70: i8085_ICount -= 7;	/* MOV	M,B */
613 			WM(I.HL.d, I.BC.b.h);
614 			break;
615 		case 0x71: i8085_ICount -= 7;	/* MOV	M,C */
616 			WM(I.HL.d, I.BC.b.l);
617 			break;
618 		case 0x72: i8085_ICount -= 7;	/* MOV	M,D */
619 			WM(I.HL.d, I.DE.b.h);
620 			break;
621 		case 0x73: i8085_ICount -= 7;	/* MOV	M,E */
622 			WM(I.HL.d, I.DE.b.l);
623 			break;
624 		case 0x74: i8085_ICount -= 7;	/* MOV	M,H */
625 			WM(I.HL.d, I.HL.b.h);
626 			break;
627 		case 0x75: i8085_ICount -= 7;	/* MOV	M,L */
628 			WM(I.HL.d, I.HL.b.l);
629 			break;
630 		case 0x76: i8085_ICount -= 4;	/* HALT */
631 			I.PC.w.l--;
632 			I.HALT = 1;
633 			if (i8085_ICount > 0) i8085_ICount = 0;
634 			break;
635 		case 0x77: i8085_ICount -= 7;	/* MOV	M,A */
636 			WM(I.HL.d, I.AF.b.h);
637 			break;
638 
639 		case 0x78: i8085_ICount -= 5;	/* MOV	A,B */
640 			I.AF.b.h = I.BC.b.h;
641 			break;
642 		case 0x79: i8085_ICount -= 5;	/* MOV	A,C */
643 			I.AF.b.h = I.BC.b.l;
644 			break;
645 		case 0x7a: i8085_ICount -= 5;	/* MOV	A,D */
646 			I.AF.b.h = I.DE.b.h;
647 			break;
648 		case 0x7b: i8085_ICount -= 5;	/* MOV	A,E */
649 			I.AF.b.h = I.DE.b.l;
650 			break;
651 		case 0x7c: i8085_ICount -= 5;	/* MOV	A,H */
652 			I.AF.b.h = I.HL.b.h;
653 			break;
654 		case 0x7d: i8085_ICount -= 5;	/* MOV	A,L */
655 			I.AF.b.h = I.HL.b.l;
656 			break;
657 		case 0x7e: i8085_ICount -= 7;	/* MOV	A,M */
658 			I.AF.b.h = RM(I.HL.d);
659 			break;
660 		case 0x7f: i8085_ICount -= 5;	/* MOV	A,A */
661 			/* no op */
662 			break;
663 
664 		case 0x80: i8085_ICount -= 4;	/* ADD	B */
665 			M_ADD(I.BC.b.h);
666 			break;
667 		case 0x81: i8085_ICount -= 4;	/* ADD	C */
668 			M_ADD(I.BC.b.l);
669 			break;
670 		case 0x82: i8085_ICount -= 4;	/* ADD	D */
671 			M_ADD(I.DE.b.h);
672 			break;
673 		case 0x83: i8085_ICount -= 4;	/* ADD	E */
674 			M_ADD(I.DE.b.l);
675 			break;
676 		case 0x84: i8085_ICount -= 4;	/* ADD	H */
677 			M_ADD(I.HL.b.h);
678 			break;
679 		case 0x85: i8085_ICount -= 4;	/* ADD	L */
680 			M_ADD(I.HL.b.l);
681 			break;
682 		case 0x86: i8085_ICount -= 7;	/* ADD	M */
683 			M_ADD(RM(I.HL.d));
684 			break;
685 		case 0x87: i8085_ICount -= 4;	/* ADD	A */
686 			M_ADD(I.AF.b.h);
687 			break;
688 
689 		case 0x88: i8085_ICount -= 4;	/* ADC	B */
690 			M_ADC(I.BC.b.h);
691 			break;
692 		case 0x89: i8085_ICount -= 4;	/* ADC	C */
693 			M_ADC(I.BC.b.l);
694 			break;
695 		case 0x8a: i8085_ICount -= 4;	/* ADC	D */
696 			M_ADC(I.DE.b.h);
697 			break;
698 		case 0x8b: i8085_ICount -= 4;	/* ADC	E */
699 			M_ADC(I.DE.b.l);
700 			break;
701 		case 0x8c: i8085_ICount -= 4;	/* ADC	H */
702 			M_ADC(I.HL.b.h);
703 			break;
704 		case 0x8d: i8085_ICount -= 4;	/* ADC	L */
705 			M_ADC(I.HL.b.l);
706 			break;
707 		case 0x8e: i8085_ICount -= 7;	/* ADC	M */
708 			M_ADC(RM(I.HL.d));
709 			break;
710 		case 0x8f: i8085_ICount -= 4;	/* ADC	A */
711 			M_ADC(I.AF.b.h);
712 			break;
713 
714 		case 0x90: i8085_ICount -= 4;	/* SUB	B */
715 			M_SUB(I.BC.b.h);
716 			break;
717 		case 0x91: i8085_ICount -= 4;	/* SUB	C */
718 			M_SUB(I.BC.b.l);
719 			break;
720 		case 0x92: i8085_ICount -= 4;	/* SUB	D */
721 			M_SUB(I.DE.b.h);
722 			break;
723 		case 0x93: i8085_ICount -= 4;	/* SUB	E */
724 			M_SUB(I.DE.b.l);
725 			break;
726 		case 0x94: i8085_ICount -= 4;	/* SUB	H */
727 			M_SUB(I.HL.b.h);
728 			break;
729 		case 0x95: i8085_ICount -= 4;	/* SUB	L */
730 			M_SUB(I.HL.b.l);
731 			break;
732 		case 0x96: i8085_ICount -= 7;	/* SUB	M */
733 			M_SUB(RM(I.HL.d));
734 			break;
735 		case 0x97: i8085_ICount -= 4;	/* SUB	A */
736 			M_SUB(I.AF.b.h);
737 			break;
738 
739 		case 0x98: i8085_ICount -= 4;	/* SBB	B */
740 			M_SBB(I.BC.b.h);
741 			break;
742 		case 0x99: i8085_ICount -= 4;	/* SBB	C */
743 			M_SBB(I.BC.b.l);
744 			break;
745 		case 0x9a: i8085_ICount -= 4;	/* SBB	D */
746 			M_SBB(I.DE.b.h);
747 			break;
748 		case 0x9b: i8085_ICount -= 4;	/* SBB	E */
749 			M_SBB(I.DE.b.l);
750 			break;
751 		case 0x9c: i8085_ICount -= 4;	/* SBB	H */
752 			M_SBB(I.HL.b.h);
753 			break;
754 		case 0x9d: i8085_ICount -= 4;	/* SBB	L */
755 			M_SBB(I.HL.b.l);
756 			break;
757 		case 0x9e: i8085_ICount -= 7;	/* SBB	M */
758 			M_SBB(RM(I.HL.d));
759 			break;
760 		case 0x9f: i8085_ICount -= 4;	/* SBB	A */
761 			M_SBB(I.AF.b.h);
762 			break;
763 
764 		case 0xa0: i8085_ICount -= 4;	/* ANA	B */
765 			M_ANA(I.BC.b.h);
766 			break;
767 		case 0xa1: i8085_ICount -= 4;	/* ANA	C */
768 			M_ANA(I.BC.b.l);
769 			break;
770 		case 0xa2: i8085_ICount -= 4;	/* ANA	D */
771 			M_ANA(I.DE.b.h);
772 			break;
773 		case 0xa3: i8085_ICount -= 4;	/* ANA	E */
774 			M_ANA(I.DE.b.l);
775 			break;
776 		case 0xa4: i8085_ICount -= 4;	/* ANA	H */
777 			M_ANA(I.HL.b.h);
778 			break;
779 		case 0xa5: i8085_ICount -= 4;	/* ANA	L */
780 			M_ANA(I.HL.b.l);
781 			break;
782 		case 0xa6: i8085_ICount -= 7;	/* ANA	M */
783 			M_ANA(RM(I.HL.d));
784 			break;
785 		case 0xa7: i8085_ICount -= 4;	/* ANA	A */
786 			M_ANA(I.AF.b.h);
787 			break;
788 
789 		case 0xa8: i8085_ICount -= 4;	/* XRA	B */
790 			M_XRA(I.BC.b.h);
791 			break;
792 		case 0xa9: i8085_ICount -= 4;	/* XRA	C */
793 			M_XRA(I.BC.b.l);
794 			break;
795 		case 0xaa: i8085_ICount -= 4;	/* XRA	D */
796 			M_XRA(I.DE.b.h);
797 			break;
798 		case 0xab: i8085_ICount -= 4;	/* XRA	E */
799 			M_XRA(I.DE.b.l);
800 			break;
801 		case 0xac: i8085_ICount -= 4;	/* XRA	H */
802 			M_XRA(I.HL.b.h);
803 			break;
804 		case 0xad: i8085_ICount -= 4;	/* XRA	L */
805 			M_XRA(I.HL.b.l);
806 			break;
807 		case 0xae: i8085_ICount -= 7;	/* XRA	M */
808 			M_XRA(RM(I.HL.d));
809 			break;
810 		case 0xaf: i8085_ICount -= 4;	/* XRA	A */
811 			M_XRA(I.AF.b.h);
812 			break;
813 
814 		case 0xb0: i8085_ICount -= 4;	/* ORA	B */
815 			M_ORA(I.BC.b.h);
816 			break;
817 		case 0xb1: i8085_ICount -= 4;	/* ORA	C */
818 			M_ORA(I.BC.b.l);
819 			break;
820 		case 0xb2: i8085_ICount -= 4;	/* ORA	D */
821 			M_ORA(I.DE.b.h);
822 			break;
823 		case 0xb3: i8085_ICount -= 4;	/* ORA	E */
824 			M_ORA(I.DE.b.l);
825 			break;
826 		case 0xb4: i8085_ICount -= 4;	/* ORA	H */
827 			M_ORA(I.HL.b.h);
828 			break;
829 		case 0xb5: i8085_ICount -= 4;	/* ORA	L */
830 			M_ORA(I.HL.b.l);
831 			break;
832 		case 0xb6: i8085_ICount -= 7;	/* ORA	M */
833 			M_ORA(RM(I.HL.d));
834 			break;
835 		case 0xb7: i8085_ICount -= 4;	/* ORA	A */
836 			M_ORA(I.AF.b.h);
837 			break;
838 
839 		case 0xb8: i8085_ICount -= 4;	/* CMP	B */
840 			M_CMP(I.BC.b.h);
841 			break;
842 		case 0xb9: i8085_ICount -= 4;	/* CMP	C */
843 			M_CMP(I.BC.b.l);
844 			break;
845 		case 0xba: i8085_ICount -= 4;	/* CMP	D */
846 			M_CMP(I.DE.b.h);
847 			break;
848 		case 0xbb: i8085_ICount -= 4;	/* CMP	E */
849 			M_CMP(I.DE.b.l);
850 			break;
851 		case 0xbc: i8085_ICount -= 4;	/* CMP	H */
852 			M_CMP(I.HL.b.h);
853 			break;
854 		case 0xbd: i8085_ICount -= 4;	/* CMP	L */
855 			M_CMP(I.HL.b.l);
856 			break;
857 		case 0xbe: i8085_ICount -= 7;	/* CMP	M */
858 			M_CMP(RM(I.HL.d));
859 			break;
860 		case 0xbf: i8085_ICount -= 4;	/* CMP	A */
861 			M_CMP(I.AF.b.h);
862 			break;
863 
864 		case 0xc0: i8085_ICount -= 5;	/* RNZ	*/
865 			M_RET( !(I.AF.b.l & ZF) );
866 			break;
867 		case 0xc1: i8085_ICount -= 10;	/* POP	B */
868 			M_POP(BC);
869 			break;
870 		case 0xc2: i8085_ICount -= 7;	/* JNZ	nnnn */
871 			M_JMP( !(I.AF.b.l & ZF) );
872 			break;
873 		case 0xc3: i8085_ICount -= 7;	/* JMP	nnnn */
874 			M_JMP(1);
875 			break;
876 		case 0xc4: i8085_ICount -= 11;	/* CNZ	nnnn */
877 			M_CALL( !(I.AF.b.l & ZF) );
878 			break;
879 		case 0xc5: i8085_ICount -= 11;	/* PUSH B */
880 			M_PUSH(BC);
881 			break;
882 		case 0xc6: i8085_ICount -= 7;	/* ADI	nn */
883 			I.XX.b.l = ARG();
884 			M_ADD(I.XX.b.l);
885 				break;
886 		case 0xc7: i8085_ICount -= 11;	/* RST	0 */
887 			M_RST(0);
888 			break;
889 
890 		case 0xc8: i8085_ICount -= 5;	/* RZ	*/
891 			M_RET( I.AF.b.l & ZF );
892 			break;
893 		case 0xc9: i8085_ICount -= 4;	/* RET	*/
894 			M_RET(1);
895 			break;
896 		case 0xca: i8085_ICount -= 7;	/* JZ	nnnn */
897 			M_JMP( I.AF.b.l & ZF );
898 			break;
899 		case 0xcb:
900 			if( I.cputype ) {
901 				if (I.AF.b.l & VF) {
902 					i8085_ICount -= 12;
903 					M_RST(8);			/* call 0x40 */
904 				} else {
905 					i8085_ICount -= 6;	/* RST  V */
906 				}
907 			} else {
908 				i8085_ICount -= 7;	/* JMP	nnnn undocumented*/
909 				M_JMP(1);
910 			}
911 			break;
912 		case 0xcc: i8085_ICount -= 11;	/* CZ	nnnn */
913 			M_CALL( I.AF.b.l & ZF );
914 			break;
915 		case 0xcd: i8085_ICount -= 11;	/* CALL nnnn */
916 			M_CALL(1);
917 			break;
918 		case 0xce: i8085_ICount -= 7;	/* ACI	nn */
919 			I.XX.b.l = ARG();
920 			M_ADC(I.XX.b.l);
921 			break;
922 		case 0xcf: i8085_ICount -= 11;	/* RST	1 */
923 			M_RST(1);
924 			break;
925 
926 		case 0xd0: i8085_ICount -= 5;	/* RNC	*/
927 			M_RET( !(I.AF.b.l & CF) );
928 			break;
929 		case 0xd1: i8085_ICount -= 10;	/* POP	D */
930 			M_POP(DE);
931 			break;
932 		case 0xd2: i8085_ICount -= 7;	/* JNC	nnnn */
933 			M_JMP( !(I.AF.b.l & CF) );
934 			break;
935 		case 0xd3: i8085_ICount -= 10;	/* OUT	nn */
936 			M_OUT;
937 			break;
938 		case 0xd4: i8085_ICount -= 11;	/* CNC	nnnn */
939 			M_CALL( !(I.AF.b.l & CF) );
940 			break;
941 		case 0xd5: i8085_ICount -= 11;	/* PUSH D */
942 			M_PUSH(DE);
943 			break;
944 		case 0xd6: i8085_ICount -= 7;	/* SUI	nn */
945 			I.XX.b.l = ARG();
946 			M_SUB(I.XX.b.l);
947 			break;
948 		case 0xd7: i8085_ICount -= 11;	/* RST	2 */
949 			M_RST(2);
950 			break;
951 
952 		case 0xd8: i8085_ICount -= 5;	/* RC	*/
953 			M_RET( I.AF.b.l & CF );
954 			break;
955 		case 0xd9:
956 			if( I.cputype ) {
957 				i8085_ICount -= 10;		/* SHLX */
958 				I.XX.w.l = I.DE.w.l;
959 				WM(I.XX.d, I.HL.b.l);
960 				I.XX.w.l++;
961 				WM(I.XX.d, I.HL.b.h);
962 			} else {
963 				i8085_ICount -= 4;	/* RET undocumented */
964 				M_RET(1);
965 			}
966 			break;
967 		case 0xda: i8085_ICount -= 7;	/* JC	nnnn */
968 			M_JMP( I.AF.b.l & CF );
969 			break;
970 		case 0xdb: i8085_ICount -= 10;	/* IN	nn */
971 			M_IN;
972 			break;
973 		case 0xdc: i8085_ICount -= 11;	/* CC	nnnn */
974 			M_CALL( I.AF.b.l & CF );
975 			break;
976 		case 0xdd:
977 			if( I.cputype ) {
978 				i8085_ICount -= 7;		/* JNX  nnnn */
979 				M_JMP( !(I.AF.b.l & XF) );
980 			} else {
981 				i8085_ICount -= 11;	/* CALL nnnn undocumented */
982 				M_CALL(1);
983 			}
984 			break;
985 		case 0xde: i8085_ICount -= 7;	/* SBI	nn */
986 			I.XX.b.l = ARG();
987 			M_SBB(I.XX.b.l);
988 			break;
989 		case 0xdf: i8085_ICount -= 11;	/* RST	3 */
990 			M_RST(3);
991 			break;
992 
993 		case 0xe0: i8085_ICount -= 5;	/* RPE	  */
994 			M_RET( !(I.AF.b.l & VF) );
995 			break;
996 		case 0xe1: i8085_ICount -= 10;	/* POP	H */
997 			M_POP(HL);
998 			break;
999 		case 0xe2: i8085_ICount -= 7;	/* JPO	nnnn */
1000 			M_JMP( !(I.AF.b.l & VF) );
1001 			break;
1002 		case 0xe3: i8085_ICount -= 18;	/* XTHL */
1003 			M_POP(XX);
1004 			M_PUSH(HL);
1005 			I.HL.d = I.XX.d;
1006 			break;
1007 		case 0xe4: i8085_ICount -= 11;	/* CPE	nnnn */
1008 			M_CALL( !(I.AF.b.l & VF) );
1009 			break;
1010 		case 0xe5: i8085_ICount -= 11;	/* PUSH H */
1011 			M_PUSH(HL);
1012 			break;
1013 		case 0xe6: i8085_ICount -= 7;	/* ANI	nn */
1014 			I.XX.b.l = ARG();
1015 			M_ANA(I.XX.b.l);
1016 			break;
1017 		case 0xe7: i8085_ICount -= 11;	/* RST	4 */
1018 			M_RST(4);
1019 			break;
1020 
1021 		case 0xe8: i8085_ICount -= 5;	/* RPO	*/
1022 			M_RET( I.AF.b.l & VF );
1023 			break;
1024 		case 0xe9: i8085_ICount -= 5;	/* PCHL */
1025 			I.PC.d = I.HL.w.l;
1026 			change_pc16(I.PC.d);
1027 			break;
1028 		case 0xea: i8085_ICount -= 7;	/* JPE	nnnn */
1029 			M_JMP( I.AF.b.l & VF );
1030 			break;
1031 		case 0xeb: i8085_ICount -= 4;	/* XCHG */
1032 			I.XX.d = I.DE.d;
1033 			I.DE.d = I.HL.d;
1034 			I.HL.d = I.XX.d;
1035 			break;
1036 		case 0xec: i8085_ICount -= 11;	/* CPO	nnnn */
1037 			M_CALL( I.AF.b.l & VF );
1038 			break;
1039 		case 0xed:
1040 			if( I.cputype ) {
1041 				i8085_ICount -= 10;		/* LHLX */
1042 				I.XX.w.l = I.DE.w.l;
1043 				I.HL.b.l = RM(I.XX.d);
1044 				I.XX.w.l++;
1045 				I.HL.b.h = RM(I.XX.d);
1046 			} else {
1047 				i8085_ICount -= 11;	/* CALL nnnn undocumented */
1048 				M_CALL(1);
1049 			}
1050 			break;
1051 		case 0xee: i8085_ICount -= 7;	/* XRI	nn */
1052 			I.XX.b.l = ARG();
1053 			M_XRA(I.XX.b.l);
1054 			break;
1055 		case 0xef: i8085_ICount -= 11;	/* RST	5 */
1056 			M_RST(5);
1057 			break;
1058 
1059 		case 0xf0: i8085_ICount -= 5;	/* RP	*/
1060 			M_RET( !(I.AF.b.l&SF) );
1061 			break;
1062 		case 0xf1: i8085_ICount -= 10;	/* POP	A */
1063 			M_POP(AF);
1064 			break;
1065 		case 0xf2: i8085_ICount -= 7;	/* JP	nnnn */
1066 			M_JMP( !(I.AF.b.l & SF) );
1067 			break;
1068 		case 0xf3: i8085_ICount -= 4;	/* DI	*/
1069 			/* remove interrupt enable */
1070 			I.IM &= ~IM_IEN;
1071 			break;
1072 		case 0xf4: i8085_ICount -= 11;	/* CP	nnnn */
1073 			M_CALL( !(I.AF.b.l & SF) );
1074 			break;
1075 		case 0xf5: i8085_ICount -= 11;	/* PUSH A */
1076 			M_PUSH(AF);
1077 			break;
1078 		case 0xf6: i8085_ICount -= 7;	/* ORI	nn */
1079 			I.XX.b.l = ARG();
1080 			M_ORA(I.XX.b.l);
1081 			break;
1082 		case 0xf7: i8085_ICount -= 11;	/* RST	6 */
1083 			M_RST(6);
1084 			break;
1085 
1086 		case 0xf8: i8085_ICount -= 5;	/* RM	*/
1087 			M_RET( I.AF.b.l & SF );
1088 			break;
1089 		case 0xf9: i8085_ICount -= 5;	/* SPHL */
1090 			I.SP.d = I.HL.d;
1091 			break;
1092 		case 0xfa: i8085_ICount -= 7;	/* JM	nnnn */
1093 			M_JMP( I.AF.b.l & SF );
1094 			break;
1095 		case 0xfb: i8085_ICount -= 4;	/* EI */
1096 			/* set interrupt enable */
1097 			I.IM |= IM_IEN;
1098 			/* remove serviced IRQ flag */
1099 			I.IREQ &= ~I.ISRV;
1100 			/* reset serviced IRQ */
1101 			I.ISRV = 0;
1102 			if( I.irq_state[0] != CLEAR_LINE ) {
1103 				log_cb(RETRO_LOG_DEBUG, LOGPRE "i8085 EI sets INTR\n");
1104 				I.IREQ |= IM_INTR;
1105 				I.INTR = I8085_INTR;
1106 			}
1107 			if( I.cputype ) {
1108 				if( I.irq_state[1] != CLEAR_LINE ) {
1109 					log_cb(RETRO_LOG_DEBUG, LOGPRE "i8085 EI sets RST5.5\n");
1110 					I.IREQ |= IM_RST55;
1111 				}
1112 				if( I.irq_state[2] != CLEAR_LINE ) {
1113 					log_cb(RETRO_LOG_DEBUG, LOGPRE "i8085 EI sets RST6.5\n");
1114 					I.IREQ |= IM_RST65;
1115 				}
1116 				if( I.irq_state[3] != CLEAR_LINE ) {
1117 					log_cb(RETRO_LOG_DEBUG, LOGPRE "i8085 EI sets RST7.5\n");
1118 					I.IREQ |= IM_RST75;
1119 				}
1120 				/* find highest priority IREQ flag with
1121 				   IM enabled and schedule for execution */
1122 				if( !(I.IM & IM_RST75) && (I.IREQ & IM_RST75) ) {
1123 					I.ISRV = IM_RST75;
1124 					I.IRQ2 = ADDR_RST75;
1125 				}
1126 				else
1127 				if( !(I.IM & IM_RST65) && (I.IREQ & IM_RST65) ) {
1128 					I.ISRV = IM_RST65;
1129 					I.IRQ2 = ADDR_RST65;
1130 				} else if( !(I.IM & IM_RST55) && (I.IREQ & IM_RST55) ) {
1131 					I.ISRV = IM_RST55;
1132 					I.IRQ2 = ADDR_RST55;
1133 				} else if( !(I.IM & IM_INTR) && (I.IREQ & IM_INTR) ) {
1134 					I.ISRV = IM_INTR;
1135 					I.IRQ2 = I.INTR;
1136 				}
1137 			} else {
1138 				if( !(I.IM & IM_INTR) && (I.IREQ & IM_INTR) ) {
1139 					I.ISRV = IM_INTR;
1140 					I.IRQ2 = I.INTR;
1141 				}
1142 			}
1143 			break;
1144 		case 0xfc: i8085_ICount -= 11;	/* CM	nnnn */
1145 			M_CALL( I.AF.b.l & SF );
1146 			break;
1147 		case 0xfd:
1148 			if( I.cputype ) {
1149 				i8085_ICount -= 7;		/* JX   nnnn */
1150 				M_JMP( I.AF.b.l & XF );
1151 			} else {
1152 				i8085_ICount -= 11;	/* CALL nnnn undocumented */
1153 				M_CALL(1);
1154 			}
1155 			break;
1156 		case 0xfe: i8085_ICount -= 7;	/* CPI	nn */
1157 			I.XX.b.l = ARG();
1158 			M_CMP(I.XX.b.l);
1159 			break;
1160 		case 0xff: i8085_ICount -= 11;	/* RST	7 */
1161 			M_RST(7);
1162 			break;
1163 	}
1164 }
1165 
Interrupt(void)1166 static void Interrupt(void)
1167 {
1168 
1169 	if( I.HALT )		/* if the CPU was halted */
1170 	{
1171 		I.PC.w.l++; 	/* skip HALT instr */
1172 		I.HALT = 0;
1173 	}
1174 /*AT*/
1175 	I.IREQ &= ~I.ISRV; /* remove serviced IRQ flag*/
1176 	RIM_IEN = (I.ISRV==IM_TRAP) ? I.IM & IM_IEN : 0; /* latch general interrupt enable bit on TRAP or NMI*/
1177 /*ZT*/
1178 	I.IM &= ~IM_IEN;		/* remove general interrupt enable bit */
1179 
1180 	if( I.ISRV == IM_INTR )
1181 	{
1182 		log_cb(RETRO_LOG_DEBUG, LOGPRE "Interrupt get INTR vector\n");
1183 		I.IRQ1 = (I.irq_callback)(0);
1184 	}
1185 
1186 	if( I.cputype )
1187 	{
1188 		if( I.ISRV == IM_RST55 )
1189 		{
1190 			log_cb(RETRO_LOG_DEBUG, LOGPRE "Interrupt get RST5.5 vector\n");
1191 			/*I.IRQ1 = (I.irq_callback)(1);*/
1192 			I.irq_state[I8085_RST55_LINE] = CLEAR_LINE; /*AT: processing RST5.5, reset interrupt line*/
1193 		}
1194 
1195 		if( I.ISRV == IM_RST65	)
1196 		{
1197 			log_cb(RETRO_LOG_DEBUG, LOGPRE "Interrupt get RST6.5 vector\n");
1198 			/*I.IRQ1 = (I.irq_callback)(2);*/
1199 			I.irq_state[I8085_RST65_LINE] = CLEAR_LINE; /*AT: processing RST6.5, reset interrupt line*/
1200 		}
1201 
1202 		if( I.ISRV == IM_RST75 )
1203 		{
1204 			log_cb(RETRO_LOG_DEBUG, LOGPRE "Interrupt get RST7.5 vector\n");
1205 			/*I.IRQ1 = (I.irq_callback)(3);*/
1206 			I.irq_state[I8085_RST75_LINE] = CLEAR_LINE; /*AT: processing RST7.5, reset interrupt line*/
1207 		}
1208 	}
1209 
1210 	switch( I.IRQ1 & 0xff0000 )
1211 	{
1212 		case 0xcd0000:	/* CALL nnnn */
1213 			i8085_ICount -= 7;
1214 			M_PUSH(PC);
1215 		case 0xc30000:	/* JMP	nnnn */
1216 			i8085_ICount -= 10;
1217 			I.PC.d = I.IRQ1 & 0xffff;
1218 			change_pc16(I.PC.d);
1219 			break;
1220 		default:
1221 			switch( I.ISRV )
1222 			{
1223 				case IM_TRAP:
1224 				case IM_RST75:
1225 				case IM_RST65:
1226 				case IM_RST55:
1227 					M_PUSH(PC);
1228 					if (I.IRQ1 != (1 << I8085_RST75_LINE))
1229 						I.PC.d = I.IRQ1;
1230 					else
1231 						I.PC.d = 0x3c;
1232 					change_pc16(I.PC.d);
1233 					break;
1234 				default:
1235 					log_cb(RETRO_LOG_DEBUG, LOGPRE "i8085 take int $%02x\n", I.IRQ1);
1236 					execute_one(I.IRQ1 & 0xff);
1237 			}
1238 	}
1239 }
1240 
i8085_execute(int cycles)1241 int i8085_execute(int cycles)
1242 {
1243 
1244 	i8085_ICount = cycles;
1245 	do
1246 	{
1247 		CALL_MAME_DEBUG;
1248 		/* interrupts enabled or TRAP pending ? */
1249 		if ( (I.IM & IM_IEN) || (I.IREQ & IM_TRAP) )
1250 		{
1251 			/* copy scheduled to executed interrupt request */
1252 			I.IRQ1 = I.IRQ2;
1253 			/* reset scheduled interrupt request */
1254 			I.IRQ2 = 0;
1255 			/* interrupt now ? */
1256 			if (I.IRQ1) Interrupt();
1257 		}
1258 
1259 		/* here we go... */
1260 		execute_one(ROP());
1261 
1262 	} while (i8085_ICount > 0);
1263 
1264 	return cycles - i8085_ICount;
1265 }
1266 
1267 /****************************************************************************
1268  * Initialise the various lookup tables used by the emulation code
1269  ****************************************************************************/
init_tables(void)1270 static void init_tables (void)
1271 {
1272 	UINT8 zs;
1273 	int i, p;
1274 	for (i = 0; i < 256; i++)
1275 	{
1276 		zs = 0;
1277 		if (i==0) zs |= ZF;
1278 		if (i&128) zs |= SF;
1279 		p = 0;
1280 		if (i&1) ++p;
1281 		if (i&2) ++p;
1282 		if (i&4) ++p;
1283 		if (i&8) ++p;
1284 		if (i&16) ++p;
1285 		if (i&32) ++p;
1286 		if (i&64) ++p;
1287 		if (i&128) ++p;
1288 		ZS[i] = zs;
1289 		ZSP[i] = zs | ((p&1) ? 0 : VF);
1290 	}
1291 }
1292 
1293 /****************************************************************************
1294  * Init the 8085 emulation
1295  ****************************************************************************/
i8085_init(void)1296 void i8085_init(void)
1297 {
1298 	int cpu = cpu_getactivecpu();
1299 	init_tables();
1300 	I.cputype = 1;
1301 
1302 	state_save_register_UINT16("i8085", cpu, "AF", &I.AF.w.l, 1);
1303 	state_save_register_UINT16("i8085", cpu, "BC", &I.BC.w.l, 1);
1304 	state_save_register_UINT16("i8085", cpu, "DE", &I.DE.w.l, 1);
1305 	state_save_register_UINT16("i8085", cpu, "HL", &I.HL.w.l, 1);
1306 	state_save_register_UINT16("i8085", cpu, "SP", &I.SP.w.l, 1);
1307 	state_save_register_UINT16("i8085", cpu, "PC", &I.PC.w.l, 1);
1308 	state_save_register_UINT8("i8085", cpu, "HALT", &I.HALT, 1);
1309 	state_save_register_UINT8("i8085", cpu, "IM", &I.IM, 1);
1310 	state_save_register_UINT8("i8085", cpu, "IREQ", &I.IREQ, 1);
1311 	state_save_register_UINT8("i8085", cpu, "ISRV", &I.ISRV, 1);
1312 	state_save_register_UINT32("i8085", cpu, "INTR", &I.INTR, 1);
1313 	state_save_register_UINT32("i8085", cpu, "IRQ2", &I.IRQ2, 1);
1314 	state_save_register_UINT32("i8085", cpu, "IRQ1", &I.IRQ1, 1);
1315 	state_save_register_INT8("i8085", cpu, "NMI_STATE", &I.nmi_state, 1);
1316 	state_save_register_INT8("i8085", cpu, "IRQ_STATE", I.irq_state, 4);
1317 }
1318 
1319 /****************************************************************************
1320  * Reset the 8085 emulation
1321  ****************************************************************************/
i8085_reset(void * param)1322 void i8085_reset(void *param)
1323 {
1324 	int cputype_bak = I.cputype; /*AT: backup cputype(0=8080, 1=8085)*/
1325 
1326 	init_tables();
1327 	memset(&I, 0, sizeof(i8085_Regs)); /*AT: this also resets I.cputype so 8085 features were never ever used!*/
1328 	change_pc16(I.PC.d);
1329 
1330 	I.cputype = cputype_bak; /*AT: restore cputype*/
1331 }
1332 
1333 /****************************************************************************
1334  * Shut down the CPU emulation
1335  ****************************************************************************/
i8085_exit(void)1336 void i8085_exit(void)
1337 {
1338 	/* nothing to do */
1339 }
1340 
1341 /****************************************************************************
1342  * Get the current 8085 context
1343  ****************************************************************************/
i8085_get_context(void * dst)1344 unsigned i8085_get_context(void *dst)
1345 {
1346 	if( dst )
1347 		*(i8085_Regs*)dst = I;
1348 	return sizeof(i8085_Regs);
1349 }
1350 
1351 /****************************************************************************
1352  * Set the current 8085 context
1353  ****************************************************************************/
i8085_set_context(void * src)1354 void i8085_set_context(void *src)
1355 {
1356 	if( src )
1357 	{
1358 		I = *(i8085_Regs*)src;
1359 		change_pc16(I.PC.d);
1360 	}
1361 }
1362 
1363 /****************************************************************************
1364  * Get a specific register
1365  ****************************************************************************/
i8085_get_reg(int regnum)1366 unsigned i8085_get_reg(int regnum)
1367 {
1368 	switch( regnum )
1369 	{
1370 		case REG_PC: return I.PC.d;
1371 		case I8085_PC: return I.PC.w.l;
1372 		case REG_SP: return I.SP.d;
1373 		case I8085_SP: return I.SP.w.l;
1374 		case I8085_AF: return I.AF.w.l;
1375 		case I8085_BC: return I.BC.w.l;
1376 		case I8085_DE: return I.DE.w.l;
1377 		case I8085_HL: return I.HL.w.l;
1378 		case I8085_IM: return I.IM;
1379 		case I8085_HALT: return I.HALT;
1380 		case I8085_IREQ: return I.IREQ;
1381 		case I8085_ISRV: return I.ISRV;
1382 		case I8085_VECTOR: return I.INTR;
1383 		case I8085_TRAP_STATE: return I.nmi_state;
1384 		case I8085_INTR_STATE: return I.irq_state[I8085_INTR_LINE];
1385 		case I8085_RST55_STATE: return I.irq_state[I8085_RST55_LINE];
1386 		case I8085_RST65_STATE: return I.irq_state[I8085_RST65_LINE];
1387 		case I8085_RST75_STATE: return I.irq_state[I8085_RST75_LINE];
1388 		case REG_PREVIOUSPC: return 0; /* previous pc not supported */
1389 		default:
1390 			if( regnum <= REG_SP_CONTENTS )
1391 			{
1392 				unsigned offset = I.SP.w.l + 2 * (REG_SP_CONTENTS - regnum);
1393 				if( offset < 0xffff )
1394 					return RM( offset ) + ( RM( offset+1 ) << 8 );
1395 			}
1396 	}
1397 	return 0;
1398 }
1399 
1400 /****************************************************************************
1401  * Set a specific register
1402  ****************************************************************************/
i8085_set_reg(int regnum,unsigned val)1403 void i8085_set_reg(int regnum, unsigned val)
1404 {
1405 	switch( regnum )
1406 	{
1407 		case REG_PC: I.PC.w.l = val; change_pc16(I.PC.d); break;
1408 		case I8085_PC: I.PC.w.l = val; break;
1409 		case REG_SP: I.SP.w.l = val; break;
1410 		case I8085_SP: I.SP.w.l = val; break;
1411 		case I8085_AF: I.AF.w.l = val; break;
1412 		case I8085_BC: I.BC.w.l = val; break;
1413 		case I8085_DE: I.DE.w.l = val; break;
1414 		case I8085_HL: I.HL.w.l = val; break;
1415 		case I8085_IM: I.IM = val; break;
1416 		case I8085_HALT: I.HALT = val; break;
1417 		case I8085_IREQ: I.IREQ = val; break;
1418 		case I8085_ISRV: I.ISRV = val; break;
1419 		case I8085_VECTOR: I.INTR = val; break;
1420 		case I8085_TRAP_STATE: I.nmi_state = val; break;
1421 		case I8085_INTR_STATE: I.irq_state[I8085_INTR_LINE] = val; break;
1422 		case I8085_RST55_STATE: I.irq_state[I8085_RST55_LINE] = val; break;
1423 		case I8085_RST65_STATE: I.irq_state[I8085_RST65_LINE] = val; break;
1424 		case I8085_RST75_STATE: I.irq_state[I8085_RST75_LINE] = val; break;
1425 		default:
1426 			if( regnum <= REG_SP_CONTENTS )
1427 			{
1428 				unsigned offset = I.SP.w.l + 2 * (REG_SP_CONTENTS - regnum);
1429 				if( offset < 0xffff )
1430 				{
1431 					WM( offset, val&0xff );
1432 					WM( offset+1, (val>>8)&0xff );
1433 				}
1434 			}
1435 	}
1436 }
1437 
1438 /****************************************************************************/
1439 /* Set the 8085 SID input signal state										*/
1440 /****************************************************************************/
i8085_set_SID(int state)1441 void i8085_set_SID(int state)
1442 {
1443 	log_cb(RETRO_LOG_DEBUG, LOGPRE "i8085: SID %d\n", state);
1444 	if (state)
1445 		I.IM |= IM_SID;
1446 	else
1447 		I.IM &= ~IM_SID;
1448 }
1449 
1450 /****************************************************************************/
1451 /* Set a callback to be called at SOD output change 						*/
1452 /****************************************************************************/
i8085_set_sod_callback(void (* callback)(int state))1453 void i8085_set_sod_callback(void (*callback)(int state))
1454 {
1455 	I.sod_callback = callback;
1456 }
1457 
1458 /****************************************************************************/
1459 /* Set TRAP signal state													*/
1460 /****************************************************************************/
i8085_set_TRAP(int state)1461 void i8085_set_TRAP(int state)
1462 {
1463 	log_cb(RETRO_LOG_DEBUG, LOGPRE "i8085: TRAP %d\n", state);
1464 	if (state)
1465 	{
1466 		I.IREQ |= IM_TRAP;
1467 		if( I.ISRV & IM_TRAP ) return;	/* already servicing TRAP ? */
1468 		I.ISRV = IM_TRAP;				/* service TRAP */
1469 		I.IRQ2 = ADDR_TRAP;
1470 	}
1471 	else
1472 	{
1473 		I.IREQ &= ~IM_TRAP; 			/* remove request for TRAP */
1474 	}
1475 }
1476 
1477 /****************************************************************************/
1478 /* Set RST7.5 signal state													*/
1479 /****************************************************************************/
i8085_set_RST75(int state)1480 void i8085_set_RST75(int state)
1481 {
1482 	log_cb(RETRO_LOG_DEBUG, LOGPRE "i8085: RST7.5 %d\n", state);
1483 	if( state )
1484 	{
1485 
1486 		I.IREQ |= IM_RST75; 			/* request RST7.5 */
1487 		if( I.IM & IM_RST75 ) return;	/* if masked, ignore it for now */
1488 		if( !I.ISRV )					/* if no higher priority IREQ is serviced */
1489 		{
1490 			I.ISRV = IM_RST75;			/* service RST7.5 */
1491 			I.IRQ2 = ADDR_RST75;
1492 		}
1493 	}
1494 	/* RST7.5 is reset only by SIM or end of service routine ! */
1495 }
1496 
1497 /****************************************************************************/
1498 /* Set RST6.5 signal state													*/
1499 /****************************************************************************/
i8085_set_RST65(int state)1500 void i8085_set_RST65(int state)
1501 {
1502 	log_cb(RETRO_LOG_DEBUG, LOGPRE "i8085: RST6.5 %d\n", state);
1503 	if( state )
1504 	{
1505 		I.IREQ |= IM_RST65; 			/* request RST6.5 */
1506 		if( I.IM & IM_RST65 ) return;	/* if masked, ignore it for now */
1507 		if( !I.ISRV )					/* if no higher priority IREQ is serviced */
1508 		{
1509 			I.ISRV = IM_RST65;			/* service RST6.5 */
1510 			I.IRQ2 = ADDR_RST65;
1511 		}
1512 	}
1513 	else
1514 	{
1515 		I.IREQ &= ~IM_RST65;			/* remove request for RST6.5 */
1516 	}
1517 }
1518 
1519 /****************************************************************************/
1520 /* Set RST5.5 signal state													*/
1521 /****************************************************************************/
i8085_set_RST55(int state)1522 void i8085_set_RST55(int state)
1523 {
1524 	log_cb(RETRO_LOG_DEBUG, LOGPRE "i8085: RST5.5 %d\n", state);
1525 	if( state )
1526 	{
1527 		I.IREQ |= IM_RST55; 			/* request RST5.5 */
1528 		if( I.IM & IM_RST55 ) return;	/* if masked, ignore it for now */
1529 		if( !I.ISRV )					/* if no higher priority IREQ is serviced */
1530 		{
1531 			I.ISRV = IM_RST55;			/* service RST5.5 */
1532 			I.IRQ2 = ADDR_RST55;
1533 		}
1534 	}
1535 	else
1536 	{
1537 		I.IREQ &= ~IM_RST55;			/* remove request for RST5.5 */
1538 	}
1539 }
1540 
1541 /****************************************************************************/
1542 /* Set INTR signal															*/
1543 /****************************************************************************/
i8085_set_INTR(int state)1544 void i8085_set_INTR(int state)
1545 {
1546 	log_cb(RETRO_LOG_DEBUG, LOGPRE "i8085: INTR %d\n", state);
1547 	if( state )
1548 	{
1549 		I.IREQ |= IM_INTR;				/* request INTR */
1550 		/*I.INTR = state;*/
1551 		I.INTR = I8085_INTR; /*AT: I.INTR is supposed to hold IRQ0 vector(0x38) (0xff in this implementation)*/
1552 		if( I.IM & IM_INTR ) return;	/* if masked, ignore it for now */
1553 		if( !I.ISRV )					/* if no higher priority IREQ is serviced */
1554 		{
1555 			I.ISRV = IM_INTR;			/* service INTR */
1556 			I.IRQ2 = I.INTR;
1557 		}
1558 	}
1559 	else
1560 	{
1561 		I.IREQ &= ~IM_INTR; 			/* remove request for INTR */
1562 	}
1563 }
1564 
i8085_set_irq_line(int irqline,int state)1565 void i8085_set_irq_line(int irqline, int state)
1566 {
1567 	if (irqline == IRQ_LINE_NMI)
1568 	{
1569 		I.nmi_state = state;
1570 		if( state != CLEAR_LINE )
1571 			i8085_set_TRAP(1);
1572 	}
1573 	else if (irqline < 4)
1574 	{
1575 		I.irq_state[irqline] = state;
1576 		if (state == CLEAR_LINE)
1577 		{
1578 			if( !(I.IM & IM_IEN) )
1579 			{
1580 				switch (irqline)
1581 				{
1582 					case I8085_INTR_LINE: i8085_set_INTR(0); break;
1583 					case I8085_RST55_LINE: i8085_set_RST55(0); break;
1584 					case I8085_RST65_LINE: i8085_set_RST65(0); break;
1585 					case I8085_RST75_LINE: i8085_set_RST75(0); break;
1586 				}
1587 			}
1588 		}
1589 		else
1590 		{
1591 			if( I.IM & IM_IEN )
1592 			{
1593 				switch( irqline )
1594 				{
1595 					case I8085_INTR_LINE: i8085_set_INTR(1); break;
1596 					case I8085_RST55_LINE: i8085_set_RST55(1); break;
1597 					case I8085_RST65_LINE: i8085_set_RST65(1); break;
1598 					case I8085_RST75_LINE: i8085_set_RST75(1); break;
1599 				}
1600 			}
1601 		}
1602 	}
1603 }
1604 
i8085_set_irq_callback(int (* callback)(int))1605 void i8085_set_irq_callback(int (*callback)(int))
1606 {
1607 	I.irq_callback = callback;
1608 }
1609 
1610 /****************************************************************************
1611  * Return a formatted string for a register
1612  ****************************************************************************/
i8085_info(void * context,int regnum)1613 const char *i8085_info(void *context, int regnum)
1614 {
1615 	static char buffer[16][47+1];
1616 	static int which = 0;
1617 	i8085_Regs *r = context;
1618 
1619 	which = (which+1) % 16;
1620 	buffer[which][0] = '\0';
1621 	if( !context )
1622 		r = &I;
1623 
1624 	switch( regnum )
1625 	{
1626 		case CPU_INFO_REG+I8085_AF: sprintf(buffer[which], "AF:%04X", r->AF.w.l); break;
1627 		case CPU_INFO_REG+I8085_BC: sprintf(buffer[which], "BC:%04X", r->BC.w.l); break;
1628 		case CPU_INFO_REG+I8085_DE: sprintf(buffer[which], "DE:%04X", r->DE.w.l); break;
1629 		case CPU_INFO_REG+I8085_HL: sprintf(buffer[which], "HL:%04X", r->HL.w.l); break;
1630 		case CPU_INFO_REG+I8085_SP: sprintf(buffer[which], "SP:%04X", r->SP.w.l); break;
1631 		case CPU_INFO_REG+I8085_PC: sprintf(buffer[which], "PC:%04X", r->PC.w.l); break;
1632 		case CPU_INFO_REG+I8085_IM: sprintf(buffer[which], "IM:%02X", r->IM); break;
1633 		case CPU_INFO_REG+I8085_HALT: sprintf(buffer[which], "HALT:%d", r->HALT); break;
1634 		case CPU_INFO_REG+I8085_IREQ: sprintf(buffer[which], "IREQ:%02X", I.IREQ); break;
1635 		case CPU_INFO_REG+I8085_ISRV: sprintf(buffer[which], "ISRV:%02X", I.ISRV); break;
1636 		case CPU_INFO_REG+I8085_VECTOR: sprintf(buffer[which], "VEC:%02X", I.INTR); break;
1637 		case CPU_INFO_REG+I8085_TRAP_STATE: sprintf(buffer[which], "TRAP:%X", I.nmi_state); break;
1638 		case CPU_INFO_REG+I8085_INTR_STATE: sprintf(buffer[which], "INTR:%X", I.irq_state[I8085_INTR_LINE]); break;
1639 		case CPU_INFO_REG+I8085_RST55_STATE: sprintf(buffer[which], "RST55:%X", I.irq_state[I8085_RST55_LINE]); break;
1640 		case CPU_INFO_REG+I8085_RST65_STATE: sprintf(buffer[which], "RST65:%X", I.irq_state[I8085_RST65_LINE]); break;
1641 		case CPU_INFO_REG+I8085_RST75_STATE: sprintf(buffer[which], "RST75:%X", I.irq_state[I8085_RST75_LINE]); break;
1642 		case CPU_INFO_FLAGS:
1643 			sprintf(buffer[which], "%c%c%c%c%c%c%c%c",
1644 				r->AF.b.l & 0x80 ? 'S':'.',
1645 				r->AF.b.l & 0x40 ? 'Z':'.',
1646 				r->AF.b.l & 0x20 ? '?':'.',
1647 				r->AF.b.l & 0x10 ? 'H':'.',
1648 				r->AF.b.l & 0x08 ? '?':'.',
1649 				r->AF.b.l & 0x04 ? 'P':'.',
1650 				r->AF.b.l & 0x02 ? 'N':'.',
1651 				r->AF.b.l & 0x01 ? 'C':'.');
1652 			break;
1653 		case CPU_INFO_NAME: return "8085A";
1654 		case CPU_INFO_FAMILY: return "Intel 8080";
1655 		case CPU_INFO_VERSION: return "1.1";
1656 		case CPU_INFO_FILE: return __FILE__;
1657 		case CPU_INFO_CREDITS: return "Copyright (c) 1999 Juergen Buchmueller, all rights reserved.";
1658 		case CPU_INFO_REG_LAYOUT: return (const char *)i8085_reg_layout;
1659 		case CPU_INFO_WIN_LAYOUT: return (const char *)i8085_win_layout;
1660 	}
1661 	return buffer[which];
1662 }
1663 
i8085_dasm(char * buffer,unsigned pc)1664 unsigned i8085_dasm(char *buffer, unsigned pc)
1665 {
1666 #ifdef MAME_DEBUG
1667 	return Dasm8085(buffer,pc);
1668 #else
1669 	sprintf( buffer, "$%02X", cpu_readop(pc) );
1670 	return 1;
1671 #endif
1672 }
1673 
1674 
1675 /**************************************************************************
1676  * 8080 section
1677  **************************************************************************/
1678 #if (HAS_8080)
1679 /* Layout of the registers in the debugger */
1680 static UINT8 i8080_reg_layout[] = {
1681 	I8080_AF, I8080_BC, I8080_DE, I8080_HL, I8080_SP, I8080_PC, -1,
1682 	I8080_HALT, I8080_IREQ, I8080_ISRV, I8080_VECTOR, I8080_TRAP_STATE, I8080_INTR_STATE,
1683 	0 };
1684 
1685 /* Layout of the debugger windows x,y,w,h */
1686 static UINT8 i8080_win_layout[] = {
1687 	25, 0,55, 2,	/* register window (top, right rows) */
1688 	 0, 0,24,22,	/* disassembler window (left colums) */
1689 	25, 3,55,10,	/* memory #1 window (right, upper middle) */
1690 	25,14,55, 8,	/* memory #2 window (right, lower middle) */
1691 	 0,23,80, 1,	/* command line window (bottom rows) */
1692 };
1693 
i8080_init(void)1694 void i8080_init(void)
1695 {
1696 	int cpu = cpu_getactivecpu();
1697 	init_tables();
1698 	I.cputype = 0;
1699 
1700 	state_save_register_UINT16("i8080", cpu, "AF", &I.AF.w.l, 1);
1701 	state_save_register_UINT16("i8080", cpu, "BC", &I.BC.w.l, 1);
1702 	state_save_register_UINT16("i8080", cpu, "DE", &I.DE.w.l, 1);
1703 	state_save_register_UINT16("i8080", cpu, "HL", &I.HL.w.l, 1);
1704 	state_save_register_UINT16("i8080", cpu, "SP", &I.SP.w.l, 1);
1705 	state_save_register_UINT16("i8080", cpu, "PC", &I.PC.w.l, 1);
1706 	state_save_register_UINT8("i8080", cpu, "HALT", &I.HALT, 1);
1707 	state_save_register_UINT8("i8080", cpu, "IREQ", &I.IREQ, 1);
1708 	state_save_register_UINT8("i8080", cpu, "ISRV", &I.ISRV, 1);
1709 	state_save_register_UINT32("i8080", cpu, "INTR", &I.INTR, 1);
1710 	state_save_register_UINT32("i8080", cpu, "IRQ2", &I.IRQ2, 1);
1711 	state_save_register_UINT32("i8080", cpu, "IRQ1", &I.IRQ1, 1);
1712 	state_save_register_INT8("i8080", cpu, "nmi_state", &I.nmi_state, 1);
1713 	state_save_register_INT8("i8080", cpu, "irq_state", I.irq_state, 1);
1714 }
1715 
i8080_reset(void * param)1716 void i8080_reset(void *param) { i8085_reset(param); }
i8080_exit(void)1717 void i8080_exit(void) { i8085_exit(); }
i8080_execute(int cycles)1718 int i8080_execute(int cycles) { return i8085_execute(cycles); }
i8080_get_context(void * dst)1719 unsigned i8080_get_context(void *dst) { return i8085_get_context(dst); }
i8080_set_context(void * src)1720 void i8080_set_context(void *src) { i8085_set_context(src); }
i8080_get_reg(int regnum)1721 unsigned i8080_get_reg(int regnum) { return i8085_get_reg(regnum); }
i8080_set_reg(int regnum,unsigned val)1722 void i8080_set_reg(int regnum, unsigned val)  { i8085_set_reg(regnum,val); }
i8080_set_irq_line(int irqline,int state)1723 void i8080_set_irq_line(int irqline, int state)
1724 {
1725 	if (irqline == IRQ_LINE_NMI)
1726 	{
1727 		i8085_set_irq_line(irqline, state);
1728 	}
1729 	else
1730 	{
1731 		I.irq_state[irqline] = state;
1732 		if (state == CLEAR_LINE)
1733 		{
1734 			if (!(I.IM & IM_IEN))
1735 				i8085_set_INTR(0);
1736 		}
1737 		else
1738 		{
1739 			if (I.IM & IM_IEN)
1740 				i8085_set_INTR(1);
1741 		}
1742 	}
1743 }
i8080_set_irq_callback(int (* callback)(int irqline))1744 void i8080_set_irq_callback(int (*callback)(int irqline)) { i8085_set_irq_callback(callback); }
i8080_info(void * context,int regnum)1745 const char *i8080_info(void *context, int regnum)
1746 {
1747 	switch( regnum )
1748 	{
1749 		case CPU_INFO_NAME: return "8080";
1750 		case CPU_INFO_VERSION: return "1.2";
1751 		case CPU_INFO_REG_LAYOUT: return (const char *)i8080_reg_layout;
1752 		case CPU_INFO_WIN_LAYOUT: return (const char *)i8080_win_layout;
1753 	}
1754 	return i8085_info(context,regnum);
1755 }
1756 
i8080_dasm(char * buffer,unsigned pc)1757 unsigned i8080_dasm(char *buffer, unsigned pc)
1758 {
1759 #ifdef MAME_DEBUG
1760 	return Dasm8085(buffer,pc);
1761 #else
1762 	sprintf( buffer, "$%02X", cpu_readop(pc) );
1763 	return 1;
1764 #endif
1765 }
1766 #endif
1767