fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation

8080: Support Z80 interrupt modes

+189 -10
+128 -1
src/cpu/e8080/e8080.c
··· 37 37 38 38 c->flags = 0; 39 39 40 + c->int_val = 0; 41 + c->nmi_val = 0; 42 + c->int_req = 0; 43 + 44 + c->int_cnt = 0; 45 + c->int_pc = 0; 46 + 40 47 c->mem_rd_ext = NULL; 41 48 c->mem_wr_ext = NULL; 42 49 ··· 219 226 c->hook_rst = fct; 220 227 } 221 228 229 + void e8080_rst (e8080_t *c, unsigned val) 230 + { 231 + e8080_set_clk (c, 0, 11); 232 + 233 + e8080_set_sp (c, e8080_get_sp (c) - 2); 234 + e8080_set_mem16 (c, e8080_get_sp (c), e8080_get_pc (c)); 235 + e8080_set_pc (c, val); 236 + } 237 + 238 + void e8080_set_int (e8080_t *c, unsigned char val) 239 + { 240 + c->int_val = (val != 0); 241 + 242 + if (c->int_val && c->iff) { 243 + c->int_req = 1; 244 + } 245 + 246 + } 247 + 222 248 unsigned char e8080_get_port8 (e8080_t *c, unsigned addr) 223 249 { 224 250 if (c->get_port8 != NULL) { ··· 301 327 *val = e8080_get_sp (c); 302 328 return (0); 303 329 } 330 + else if (strcmp (reg, "i") == 0) { 331 + *val = e8080_get_i (c); 332 + return (0); 333 + } 334 + else if (strcmp (reg, "icnt") == 0) { 335 + *val = e8080_get_int_cnt (c); 336 + return (0); 337 + } 338 + else if (strcmp (reg, "iff") == 0) { 339 + *val = e8080_get_iff1 (c); 340 + return (0); 341 + } 342 + else if (strcmp (reg, "iff2") == 0) { 343 + *val = e8080_get_iff2 (c); 344 + return (0); 345 + } 346 + else if (strcmp (reg, "im") == 0) { 347 + *val = e8080_get_im (c); 348 + return (0); 349 + } 350 + else if (strcmp (reg, "ipc") == 0) { 351 + *val = e8080_get_int_pc (c); 352 + return (0); 353 + } 304 354 else if (strcmp (reg, "r") == 0) { 305 355 *val = e8080_get_r (c); 306 356 return (0); ··· 375 425 e8080_set_sp (c, val); 376 426 return (0); 377 427 } 428 + else if (strcmp (reg, "i") == 0) { 429 + e8080_set_i (c, val); 430 + return (0); 431 + } 432 + else if (strcmp (reg, "icnt") == 0) { 433 + e8080_set_int_cnt (c, val); 434 + return (0); 435 + } 436 + else if (strcmp (reg, "iff") == 0) { 437 + e8080_set_iff1 (c, val); 438 + return (0); 439 + } 440 + else if (strcmp (reg, "iff2") == 0) { 441 + e8080_set_iff2 (c, val); 442 + return (0); 443 + } 444 + else if (strcmp (reg, "im") == 0) { 445 + e8080_set_im (c, val); 446 + return (0); 447 + } 448 + else if (strcmp (reg, "ipc") == 0) { 449 + e8080_set_int_pc (c, val); 450 + return (0); 451 + } 378 452 else if (strcmp (reg, "r") == 0) { 379 453 e8080_set_r (c, val); 380 454 return (0); ··· 449 523 c->iff = 0; 450 524 c->iff2 = 0; 451 525 526 + c->int_req = 0; 527 + c->int_pc = 0; 528 + c->im = 0; 529 + 452 530 c->halt = 0; 453 531 } 454 532 533 + void e8080_interrupt (e8080_t *c) 534 + { 535 + unsigned addr; 536 + 537 + e8080_inc_r (c); 538 + c->inscnt += 1; 539 + 540 + if (c->halt) { 541 + c->halt = 0; 542 + e8080_set_pc (c, e8080_get_pc (c) + 1); 543 + } 544 + 545 + c->int_cnt += 1; 546 + c->int_pc = e8080_get_pc (c); 547 + 548 + c->int_req = 0; 549 + 550 + if (c->im == 1) { 551 + e8080_rst (c, 0x38); 552 + 553 + c->iff = 0; 554 + c->iff2 = 0; 555 + } 556 + else if (c->im == 2) { 557 + addr = (e8080_get_i (c) << 8) | 0xff; 558 + addr = e8080_get_mem16 (c, addr); 559 + 560 + e8080_rst (c, addr); 561 + 562 + c->iff = 0; 563 + c->iff2 = 0; 564 + } 565 + else { 566 + fprintf (stderr, "8080: interrupt mode %u\n", c->im); 567 + } 568 + } 569 + 455 570 void e8080_execute (e8080_t *c) 456 571 { 457 572 unsigned short pc; 573 + unsigned char iff; 458 574 459 575 if (c->halt) { 460 - c->delay = 4; 576 + if (c->int_req && c->iff) { 577 + e8080_interrupt (c); 578 + } 579 + else { 580 + c->delay += 1; 581 + } 461 582 return; 462 583 } 463 584 ··· 475 596 } 476 597 #endif 477 598 599 + iff = c->iff; 600 + 478 601 c->op[c->inst[0]] (c); 479 602 480 603 c->inscnt += 1; 604 + 605 + if (c->int_req && iff && c->iff) { 606 + e8080_interrupt (c); 607 + } 481 608 } 482 609 483 610 void e8080_clock (e8080_t *c, unsigned n)
+27
src/cpu/e8080/e8080.h
··· 64 64 unsigned char iff; 65 65 unsigned char iff2; 66 66 67 + unsigned char im; 68 + 67 69 unsigned char halt; 70 + 71 + unsigned char int_val; 72 + unsigned char nmi_val; 73 + unsigned char int_req; 74 + 75 + unsigned int_cnt; 76 + unsigned short int_pc; 68 77 69 78 void *mem_rd_ext; 70 79 void *mem_wr_ext; ··· 128 137 #define e8080_get_l2(c) ((c)->reg2[5]); 129 138 #define e8080_get_psw2(c) ((c)->psw2) 130 139 140 + #define e8080_get_halt(c) ((c)->halt) 141 + #define e8080_get_iff1(c) ((c)->iff) 142 + #define e8080_get_iff2(c) ((c)->iff2) 143 + #define e8080_get_im(c) ((c)->im) 144 + #define e8080_get_int_cnt(c) ((c)->int_cnt) 145 + #define e8080_get_int_pc(c) ((c)->int_pc) 146 + 131 147 #define e8080_set_a(c, v) do { (c)->reg[7] = (v) & 0xff; } while (0) 132 148 #define e8080_set_b(c, v) do { (c)->reg[0] = (v) & 0xff; } while (0) 133 149 #define e8080_set_c(c, v) do { (c)->reg[1] = (v) & 0xff; } while (0) ··· 159 175 #define e8080_set_h2(c, v) do { (c)->reg2[4] = (v) & 0xff; } while (0) 160 176 #define e8080_set_l2(c, v) do { (c)->reg2[5] = (v) & 0xff; } while (0) 161 177 #define e8080_set_psw2(c, v) do { (c)->psw2 = (v) & 0xff; } while (0) 178 + 179 + #define e8080_set_halt(c, v) do { (c)->halt = ((v) != 0); } while (0) 180 + #define e8080_set_iff1(c, v) do { (c)->iff = ((v) != 0); } while (0) 181 + #define e8080_set_iff2(c, v) do { (c)->iff2 = ((v) != 0); } while (0) 182 + #define e8080_set_im(c, v) do { (c)->im = (v); } while (0) 183 + #define e8080_set_int_cnt(c, v) do { (c)->int_cnt = (v); } while (0) 184 + #define e8080_set_int_pc(c, v) do { (c)->int_pc = (v) & 0xffff; } while (0) 162 185 163 186 #define e8080_get_cf(c) (((c)->psw & E8080_FLG_C) != 0) 164 187 #define e8080_get_nf(c) (((c)->psw & E8080_FLG_N) != 0) ··· 285 308 void e8080_set_hook_all_fct (e8080_t *c, void *ext, void *fct); 286 309 void e8080_set_hook_undef_fct (e8080_t *c, void *ext, void *fct); 287 310 void e8080_set_hook_rst_fct (e8080_t *c, void *ext, void *fct); 311 + 312 + void e8080_rst (e8080_t *c, unsigned val); 313 + 314 + void e8080_set_int (e8080_t *c, unsigned char val); 288 315 289 316 unsigned char e8080_get_port8 (e8080_t *c, unsigned addr); 290 317 void e8080_set_port8 (e8080_t *c, unsigned addr, unsigned char val);
+28 -3
src/cpu/e8080/op_ed.c
··· 99 99 /* OP ED 45: RETN */ 100 100 static void op_ed_45 (e8080_t *c) 101 101 { 102 + e8080_set_iff1 (c, e8080_get_iff2 (c)); 102 103 e8080_set_pc (c, e8080_get_mem16 (c, e8080_get_sp (c))); 103 104 e8080_set_sp (c, e8080_get_sp (c) + 2); 104 105 e8080_set_clk (c, 0, 14); 106 + } 107 + 108 + /* OP ED 46: IM 0 */ 109 + static void op_ed_46 (e8080_t *c) 110 + { 111 + c->im = 0; 112 + 113 + e8080_set_clk (c, 2, 8); 105 114 } 106 115 107 116 /* OP ED 47: LD I, A */ ··· 174 183 e8080_set_clk (c, 4, 20); 175 184 } 176 185 186 + /* OP ED 56: IM 1 */ 187 + static void op_ed_56 (e8080_t *c) 188 + { 189 + c->im = 1; 190 + 191 + e8080_set_clk (c, 2, 8); 192 + } 193 + 177 194 /* OP ED 57: LD A, I */ 178 195 static void op_ed_57 (e8080_t *c) 179 196 { ··· 208 225 adr = e8080_uint16 (c->inst[2], c->inst[3]); 209 226 e8080_set_de (c, e8080_get_mem16 (c, adr)); 210 227 e8080_set_clk (c, 4, 20); 228 + } 229 + 230 + /* OP ED 5E: IM 2 */ 231 + static void op_ed_5e (e8080_t *c) 232 + { 233 + c->im = 2; 234 + 235 + e8080_set_clk (c, 2, 8); 211 236 } 212 237 213 238 /* OP ED 5F: LD A, R */ ··· 682 707 op_ed_ud, op_ed_ud, op_ed_ud, op_ed_ud, op_ed_ud, op_ed_ud, op_ed_ud, op_ed_ud, 683 708 op_ed_ud, op_ed_ud, op_ed_ud, op_ed_ud, op_ed_ud, op_ed_ud, op_ed_ud, op_ed_ud, /* 30 */ 684 709 op_ed_ud, op_ed_ud, op_ed_ud, op_ed_ud, op_ed_ud, op_ed_ud, op_ed_ud, op_ed_ud, 685 - op_ed_40, op_ed_41, op_ed_42, op_ed_43, op_ed_44, op_ed_45, op_ed_ud, op_ed_47, /* 40 */ 710 + op_ed_40, op_ed_41, op_ed_42, op_ed_43, op_ed_44, op_ed_45, op_ed_46, op_ed_47, /* 40 */ 686 711 op_ed_40, op_ed_41, op_ed_4a, op_ed_4b, op_ed_ud, op_ed_4d, op_ed_ud, op_ed_4f, 687 - op_ed_40, op_ed_41, op_ed_52, op_ed_53, op_ed_ud, op_ed_45, op_ed_ud, op_ed_57, /* 50 */ 688 - op_ed_40, op_ed_41, op_ed_5a, op_ed_5b, op_ed_ud, op_ed_45, op_ed_ud, op_ed_5f, 712 + op_ed_40, op_ed_41, op_ed_52, op_ed_53, op_ed_ud, op_ed_45, op_ed_56, op_ed_57, /* 50 */ 713 + op_ed_40, op_ed_41, op_ed_5a, op_ed_5b, op_ed_ud, op_ed_45, op_ed_5e, op_ed_5f, 689 714 op_ed_40, op_ed_41, op_ed_62, op_ed_63, op_ed_ud, op_ed_45, op_ed_ud, op_ed_67, /* 60 */ 690 715 op_ed_40, op_ed_41, op_ed_6a, op_ed_6b, op_ed_ud, op_ed_45, op_ed_ud, op_ed_6f, 691 716 op_ed_70, op_ed_71, op_ed_72, op_ed_73, op_ed_ud, op_ed_45, op_ed_ud, op_ed_ud, /* 70 */
+1 -1
src/cpu/e8080/op_z80.c
··· 530 530 static void op_76 (e8080_t *c) 531 531 { 532 532 c->halt = 1; 533 - e8080_set_clk (c, 1, 7); 533 + e8080_set_clk (c, 0, 7); 534 534 } 535 535 536 536 /* OP 80: ADD A, r */
+5 -5
src/cpu/e8080/opcodes.c
··· 571 571 static void op_76 (e8080_t *c) 572 572 { 573 573 c->halt = 1; 574 - e8080_set_clk (c, 1, 7); 574 + e8080_set_clk (c, 0, 7); 575 575 } 576 576 577 577 /* OP 80: ADD R */ ··· 1296 1296 /* OP F3: DI */ 1297 1297 static void op_f3 (e8080_t *c) 1298 1298 { 1299 - c->iff = 0; 1300 - c->iff2 = 0; 1299 + e8080_set_iff1 (c, 0); 1300 + e8080_set_iff2 (c, 0); 1301 1301 e8080_set_clk (c, 1, 4); 1302 1302 } 1303 1303 ··· 1376 1376 /* OP FB: EI */ 1377 1377 static void op_fb (e8080_t *c) 1378 1378 { 1379 - c->iff = 1; 1380 - c->iff2 = 1; 1379 + e8080_set_iff1 (c, 1); 1380 + e8080_set_iff2 (c, 1); 1381 1381 e8080_set_clk (c, 1, 4); 1382 1382 } 1383 1383