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