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