trunk/src/emu/cpu/hmcs40/hmcs40.c
| r244932 | r244933 | |
| 184 | 184 | m_prgmask = (1 << m_prgwidth) - 1; |
| 185 | 185 | m_datamask = (1 << m_datawidth) - 1; |
| 186 | 186 | m_pcmask = (1 << m_pcwidth) - 1; |
| 187 | |
| 188 | m_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(hmcs40_cpu_device::simple_timer_cb), this)); |
| 189 | reset_prescaler(); |
| 187 | 190 | |
| 188 | 191 | m_read_r0.resolve_safe(0); |
| 189 | 192 | m_read_r1.resolve_safe(0); |
| r244932 | r244933 | |
| 210 | 213 | memset(m_stack, 0, sizeof(m_stack)); |
| 211 | 214 | m_op = 0; |
| 212 | 215 | m_prev_op = 0; |
| 216 | m_i = 0; |
| 217 | m_eint_line = 0; |
| 213 | 218 | m_pc = 0; |
| 214 | 219 | m_prev_pc = 0; |
| 215 | 220 | m_page = 0; |
| r244932 | r244933 | |
| 221 | 226 | m_spy = 0; |
| 222 | 227 | m_s = 1; |
| 223 | 228 | m_c = 0; |
| 229 | m_tc = 0; |
| 230 | m_cf = 0; |
| 231 | m_ie = 0; |
| 232 | m_iri = m_irt = 0; |
| 233 | memset(m_if, 0, sizeof(m_if)); |
| 234 | m_tf = 0; |
| 235 | memset(m_int, 0, sizeof(m_int)); |
| 224 | 236 | memset(m_r, 0, sizeof(m_r)); |
| 225 | 237 | m_d = 0; |
| 226 | 238 | |
| r244932 | r244933 | |
| 228 | 240 | save_item(NAME(m_stack)); |
| 229 | 241 | save_item(NAME(m_op)); |
| 230 | 242 | save_item(NAME(m_prev_op)); |
| 243 | save_item(NAME(m_i)); |
| 244 | save_item(NAME(m_eint_line)); |
| 231 | 245 | save_item(NAME(m_pc)); |
| 232 | 246 | save_item(NAME(m_prev_pc)); |
| 233 | 247 | save_item(NAME(m_page)); |
| r244932 | r244933 | |
| 239 | 253 | save_item(NAME(m_spy)); |
| 240 | 254 | save_item(NAME(m_s)); |
| 241 | 255 | save_item(NAME(m_c)); |
| 256 | save_item(NAME(m_tc)); |
| 257 | save_item(NAME(m_cf)); |
| 258 | save_item(NAME(m_ie)); |
| 259 | save_item(NAME(m_iri)); |
| 260 | save_item(NAME(m_irt)); |
| 261 | save_item(NAME(m_if)); |
| 262 | save_item(NAME(m_tf)); |
| 263 | save_item(NAME(m_int)); |
| 264 | |
| 242 | 265 | save_item(NAME(m_r)); |
| 243 | 266 | save_item(NAME(m_d)); |
| 244 | 267 | |
| r244932 | r244933 | |
| 275 | 298 | |
| 276 | 299 | for (int i = 0; i < 8; i++) |
| 277 | 300 | hmcs40_cpu_device::write_r(i, 0); |
| 301 | |
| 302 | // clear interrupts |
| 303 | m_cf = 0; |
| 304 | m_ie = 0; |
| 305 | m_iri = m_irt = 0; |
| 306 | m_if[0] = m_if[1] = m_tf = 1; |
| 278 | 307 | } |
| 279 | 308 | |
| 280 | 309 | |
| r244932 | r244933 | |
| 347 | 376 | index &= 7; |
| 348 | 377 | |
| 349 | 378 | if (index >= 2) |
| 350 | | logerror("%s read from %s port R%d at $%04X\n", tag(), (index >= 4) ? "unknown" : "output", index, m_prev_pc << 1); |
| 379 | logerror("%s read from %s port R%d at $%04X\n", tag(), (index >= 4) ? "unknown" : "output", index, m_prev_pc); |
| 351 | 380 | |
| 352 | 381 | return hmcs40_cpu_device::read_r(index); |
| 353 | 382 | } |
| r244932 | r244933 | |
| 359 | 388 | if (index != 0 && index < 4) |
| 360 | 389 | hmcs40_cpu_device::write_r(index, data); |
| 361 | 390 | else |
| 362 | | logerror("%s ineffective write to port R%d = $%X at $%04X\n", tag(), index, data & 0xf, m_prev_pc << 1); |
| 391 | logerror("%s ineffective write to port R%d = $%X at $%04X\n", tag(), index, data & 0xf, m_prev_pc); |
| 363 | 392 | } |
| 364 | 393 | |
| 365 | 394 | int hmcs43_cpu_device::read_d(int index) |
| r244932 | r244933 | |
| 367 | 396 | index &= 15; |
| 368 | 397 | |
| 369 | 398 | if (index >= 4) |
| 370 | | logerror("%s read from output pin D%d at $%04X\n", tag(), index, m_prev_pc << 1); |
| 399 | logerror("%s read from output pin D%d at $%04X\n", tag(), index, m_prev_pc); |
| 371 | 400 | |
| 372 | 401 | return hmcs40_cpu_device::read_d(index); |
| 373 | 402 | } |
| r244932 | r244933 | |
| 381 | 410 | index &= 7; |
| 382 | 411 | |
| 383 | 412 | if (index >= 6) |
| 384 | | logerror("%s read from unknown port R%d at $%04X\n", tag(), index, m_prev_pc << 1); |
| 413 | logerror("%s read from unknown port R%d at $%04X\n", tag(), index, m_prev_pc); |
| 385 | 414 | |
| 386 | 415 | return hmcs40_cpu_device::read_r(index); |
| 387 | 416 | } |
| r244932 | r244933 | |
| 393 | 422 | if (index < 6) |
| 394 | 423 | hmcs40_cpu_device::write_r(index, data); |
| 395 | 424 | else |
| 396 | | logerror("%s ineffective write to port R%d = $%X at $%04X\n", tag(), index, data & 0xf, m_prev_pc << 1); |
| 425 | logerror("%s ineffective write to port R%d = $%X at $%04X\n", tag(), index, data & 0xf, m_prev_pc); |
| 397 | 426 | } |
| 398 | 427 | |
| 399 | 428 | // HMCS45: |
| r244932 | r244933 | |
| 405 | 434 | index &= 7; |
| 406 | 435 | |
| 407 | 436 | if (index >= 6) |
| 408 | | logerror("%s read from %s port R%d at $%04X\n", tag(), (index == 7) ? "unknown" : "output", index, m_prev_pc << 1); |
| 437 | logerror("%s read from %s port R%d at $%04X\n", tag(), (index == 7) ? "unknown" : "output", index, m_prev_pc); |
| 409 | 438 | |
| 410 | 439 | return hmcs40_cpu_device::read_r(index); |
| 411 | 440 | } |
| r244932 | r244933 | |
| 417 | 446 | if (index != 7) |
| 418 | 447 | hmcs40_cpu_device::write_r(index, data); |
| 419 | 448 | else |
| 420 | | logerror("%s ineffective write to port R%d = $%X at $%04X\n", tag(), index, data & 0xf, m_prev_pc << 1); |
| 449 | logerror("%s ineffective write to port R%d = $%X at $%04X\n", tag(), index, data & 0xf, m_prev_pc); |
| 421 | 450 | } |
| 422 | 451 | |
| 423 | 452 | |
| 424 | 453 | |
| 425 | 454 | //------------------------------------------------- |
| 455 | // interrupt/timer handling |
| 456 | //------------------------------------------------- |
| 457 | |
| 458 | void hmcs40_cpu_device::do_interrupt() |
| 459 | { |
| 460 | m_icount--; |
| 461 | push_stack(); |
| 462 | |
| 463 | // line 0/1 for external interrupt, let's use 2 for t/c interrupt |
| 464 | int line = (m_iri) ? m_eint_line : 2; |
| 465 | |
| 466 | // vector $3f, on page 0(timer/counter), or page 1(external) |
| 467 | // external interrupt has priority over t/c interrupt |
| 468 | m_pc = 0x3f | (m_iri ? 0x40 : 0); |
| 469 | m_iri = m_irt = 0; |
| 470 | m_ie = 0; |
| 471 | |
| 472 | standard_irq_callback(line); |
| 473 | } |
| 474 | |
| 475 | void hmcs40_cpu_device::execute_set_input(int line, int state) |
| 476 | { |
| 477 | if (line != 0 && line != 1) |
| 478 | return; |
| 479 | state = (state) ? 1 : 0; |
| 480 | |
| 481 | // external interrupt request on rising edge |
| 482 | if (state && !m_int[line]) |
| 483 | { |
| 484 | if (!m_if[line]) |
| 485 | { |
| 486 | m_eint_line = line; |
| 487 | m_iri = 1; |
| 488 | m_if[line] = 1; |
| 489 | } |
| 490 | |
| 491 | // clock tc if it is in counter mode |
| 492 | if (m_cf && line == 1) |
| 493 | increment_tc(); |
| 494 | } |
| 495 | |
| 496 | m_int[line] = state; |
| 497 | } |
| 498 | |
| 499 | void hmcs40_cpu_device::reset_prescaler() |
| 500 | { |
| 501 | // reset 6-bit timer prescaler |
| 502 | attotime base = attotime::from_hz(unscaled_clock() / 4 / 64); |
| 503 | m_timer->adjust(base); |
| 504 | } |
| 505 | |
| 506 | TIMER_CALLBACK_MEMBER( hmcs40_cpu_device::simple_timer_cb ) |
| 507 | { |
| 508 | // timer prescaler overflow |
| 509 | if (!m_cf) |
| 510 | increment_tc(); |
| 511 | |
| 512 | reset_prescaler(); |
| 513 | } |
| 514 | |
| 515 | void hmcs40_cpu_device::increment_tc() |
| 516 | { |
| 517 | // increment timer/counter |
| 518 | m_tc = (m_tc + 1) & 0xf; |
| 519 | |
| 520 | // timer interrupt request on overflow |
| 521 | if (m_tc == 0 && !m_tf) |
| 522 | { |
| 523 | m_irt = 1; |
| 524 | m_tf = 1; |
| 525 | } |
| 526 | } |
| 527 | |
| 528 | |
| 529 | |
| 530 | //------------------------------------------------- |
| 426 | 531 | // execute |
| 427 | 532 | //------------------------------------------------- |
| 428 | 533 | |
| r244932 | r244933 | |
| 451 | 556 | if ((m_prev_op & 0x3e0) == 0x340) |
| 452 | 557 | m_pc = ((m_page << 6) | (m_pc & 0x3f)) & m_pcmask; |
| 453 | 558 | |
| 559 | // check/handle interrupt |
| 560 | else if (m_ie && (m_iri || m_irt)) |
| 561 | do_interrupt(); |
| 562 | |
| 454 | 563 | // remember previous state |
| 455 | 564 | m_prev_op = m_op; |
| 456 | 565 | m_prev_pc = m_pc; |
| r244932 | r244933 | |
| 458 | 567 | // fetch next opcode |
| 459 | 568 | debugger_instruction_hook(this, m_pc); |
| 460 | 569 | m_op = m_program->read_word(m_pc << 1) & 0x3ff; |
| 570 | m_i = BITSWAP8(m_op,7,6,5,4,0,1,2,3) & 0xf; // reversed bit-order for immediate param |
| 461 | 571 | increment_pc(); |
| 462 | 572 | |
| 573 | /* |
| 574 | |
| 575 | op_ayy(); - |
| 576 | op_syy(); - |
| 577 | op_am(); - 34 234 4c |
| 578 | op_sm()???:- 234 |
| 579 | op_daa(); - 46 |
| 580 | op_das(); - 45 |
| 581 | op_nega(); - |
| 582 | op_anem(); - 324 124 |
| 583 | op_bnem(); - 267 024 |
| 584 | op_alem(); - 324 124 |
| 585 | op_blem(); - 267 024 |
| 586 | op_lay(); - 118 |
| 587 | |
| 588 | */ |
| 589 | |
| 463 | 590 | // handle opcode |
| 464 | 591 | switch (m_op) |
| 465 | 592 | { |
| 593 | case 0x118: |
| 594 | op_lay(); // probably lay |
| 595 | break; |
| 596 | case 0x267: |
| 597 | op_blem(); break; // bnem or blem |
| 598 | case 0x124: |
| 599 | op_alem(); // alem or anem |
| 600 | break; |
| 601 | case 0x324: |
| 602 | op_anem(); break; // " |
| 603 | case 0x024: |
| 604 | //op_nega(); |
| 605 | //op_am(); |
| 606 | op_illegal(); |
| 607 | break; |
| 608 | case 0x234: |
| 609 | // sm? |
| 610 | #if 0 |
| 611 | m_a = ram_r() - m_a; |
| 612 | m_s = ~m_a >> 4 & 1; |
| 613 | m_a &= 0xf; |
| 614 | #else |
| 615 | op_am(); |
| 616 | #endif |
| 617 | break; |
| 618 | case 0x04c: |
| 619 | op_illegal(); |
| 620 | //m_c ^= 1; |
| 621 | //op_lat(); |
| 622 | break; |
| 623 | |
| 624 | |
| 625 | |
| 626 | |
| 466 | 627 | /* 0x000 */ |
| 467 | 628 | |
| 468 | 629 | case 0x000: case 0x001: case 0x002: case 0x003: |
| 469 | | op_xsp(); break; |
| 630 | /* ok */ op_xsp(); break; |
| 470 | 631 | case 0x004: case 0x005: case 0x006: case 0x007: |
| 471 | 632 | op_sem(); break; |
| 472 | 633 | case 0x008: case 0x009: case 0x00a: case 0x00b: |
| r244932 | r244933 | |
| 490 | 651 | case 0x050: |
| 491 | 652 | op_lya(); break; |
| 492 | 653 | case 0x054: |
| 493 | | op_iy(); break; |
| 654 | /* ok */ op_iy(); break; |
| 494 | 655 | case 0x060: |
| 495 | 656 | op_lba(); break; |
| 496 | 657 | case 0x064: |
| r244932 | r244933 | |
| 513 | 674 | case 0x0a2: |
| 514 | 675 | op_seif0(); break; |
| 515 | 676 | case 0x0a4: |
| 516 | | op_seie(); break; |
| 677 | /* ok */ op_seie(); break; |
| 517 | 678 | case 0x0a5: |
| 518 | 679 | op_setf(); break; |
| 519 | 680 | |
| r244932 | r244933 | |
| 526 | 687 | op_lbr(); break; |
| 527 | 688 | case 0x0f0: case 0x0f1: case 0x0f2: case 0x0f3: case 0x0f4: case 0x0f5: case 0x0f6: case 0x0f7: |
| 528 | 689 | case 0x0f8: case 0x0f9: case 0x0fa: case 0x0fb: case 0x0fc: case 0x0fd: case 0x0fe: case 0x0ff: |
| 529 | | op_xamr(); break; |
| 690 | /* ok */ op_xamr(); break; |
| 530 | 691 | |
| 531 | 692 | |
| 532 | 693 | /* 0x100 */ |
| 533 | 694 | |
| 534 | | case 0x110: case 0x111: |
| 695 | /* ok */ case 0x110: case 0x111: |
| 535 | 696 | op_lmaiy(); break; |
| 536 | | case 0x114: case 0x115: |
| 697 | /* ok */ case 0x114: case 0x115: |
| 537 | 698 | op_lmady(); break; |
| 538 | 699 | case 0x120: |
| 539 | 700 | op_or(); break; |
| r244932 | r244933 | |
| 549 | 710 | /* ok */ op_lbi(); break; |
| 550 | 711 | case 0x170: case 0x171: case 0x172: case 0x173: case 0x174: case 0x175: case 0x176: case 0x177: |
| 551 | 712 | case 0x178: case 0x179: case 0x17a: case 0x17b: case 0x17c: case 0x17d: case 0x17e: case 0x17f: |
| 552 | | op_lti(); break; |
| 713 | /* ok */ op_lti(); break; |
| 553 | 714 | |
| 554 | 715 | case 0x1a0: |
| 555 | 716 | op_tif1(); break; |
| r244932 | r244933 | |
| 580 | 741 | case 0x204: case 0x205: case 0x206: case 0x207: |
| 581 | 742 | op_rem(); break; |
| 582 | 743 | case 0x208: case 0x209: case 0x20a: case 0x20b: |
| 583 | | op_xma(); break; |
| 744 | /* ok */ op_xma(); break; |
| 584 | 745 | case 0x210: case 0x211: case 0x212: case 0x213: case 0x214: case 0x215: case 0x216: case 0x217: |
| 585 | 746 | case 0x218: case 0x219: case 0x21a: case 0x21b: case 0x21c: case 0x21d: case 0x21e: case 0x21f: |
| 586 | 747 | op_mnei(); break; |
| 587 | 748 | case 0x220: case 0x221: case 0x222: case 0x223: |
| 588 | 749 | /* ok */ op_xmb(); break; |
| 589 | 750 | case 0x224: |
| 590 | | op_rotr(); break; |
| 751 | /* ok */ op_rotr(); break; |
| 591 | 752 | case 0x225: |
| 592 | | op_rotl(); break; |
| 753 | /* ok */ op_rotl(); break; |
| 593 | 754 | case 0x230: |
| 594 | 755 | op_smc(); break; |
| 595 | 756 | case 0x23c: |
| 596 | 757 | op_lat(); break; |
| 597 | 758 | |
| 598 | 759 | case 0x240: |
| 599 | | op_laspx(); break; |
| 760 | /* ok */ op_laspx(); break; |
| 600 | 761 | case 0x24f: |
| 601 | 762 | op_tc(); break; |
| 602 | 763 | case 0x250: |
| 603 | | op_laspy(); break; |
| 764 | /* ok */ op_laspy(); break; |
| 604 | 765 | case 0x254: |
| 605 | 766 | op_dy(); break; |
| 606 | 767 | case 0x260: |
| 607 | | op_lab(); break; |
| 768 | /* ok */ op_lab(); break; |
| 608 | 769 | case 0x264: |
| 609 | 770 | op_db(); break; |
| 610 | 771 | case 0x270: case 0x271: case 0x272: case 0x273: case 0x274: case 0x275: case 0x276: case 0x277: |
| 611 | 772 | case 0x278: case 0x279: case 0x27a: case 0x27b: case 0x27c: case 0x27d: case 0x27e: case 0x27f: |
| 612 | | op_alei(); break; |
| 773 | /* ok */ op_alei(); break; |
| 613 | 774 | |
| 614 | 775 | case 0x280: case 0x281: case 0x282: case 0x283: case 0x284: case 0x285: case 0x286: case 0x287: |
| 615 | 776 | case 0x288: case 0x289: case 0x28a: case 0x28b: case 0x28c: case 0x28d: case 0x28e: case 0x28f: |
| 616 | | op_ynei(); break; |
| 777 | /* ok */ op_ynei(); break; |
| 617 | 778 | case 0x290: |
| 618 | 779 | /* ok */ op_red(); break; |
| 619 | 780 | case 0x2a0: |
| r244932 | r244933 | |
| 625 | 786 | case 0x2a4: |
| 626 | 787 | op_reie(); break; |
| 627 | 788 | case 0x2a5: |
| 628 | | op_retf(); break; |
| 789 | /* ok */ op_retf(); break; |
| 629 | 790 | |
| 630 | 791 | case 0x2c0: case 0x2c1: case 0x2c2: case 0x2c3: case 0x2c4: case 0x2c5: case 0x2c6: case 0x2c7: |
| 631 | 792 | /* ok */ op_lra(); break; |
| r244932 | r244933 | |
| 651 | 812 | /* ok */ op_p(); break; |
| 652 | 813 | |
| 653 | 814 | case 0x3a4: |
| 654 | | op_rtni(); break; |
| 815 | /* ok */ op_rtni(); break; |
| 655 | 816 | case 0x3a7: |
| 656 | 817 | /* ok */ op_rtn(); break; |
| 657 | 818 | |
trunk/src/emu/cpu/hmcs40/hmcs40.h
| r244932 | r244933 | |
| 78 | 78 | // device_execute_interface overrides |
| 79 | 79 | virtual UINT32 execute_min_cycles() const { return 1; } |
| 80 | 80 | virtual UINT32 execute_max_cycles() const { return 2; } |
| 81 | | virtual UINT32 execute_input_lines() const { return 1; } |
| 81 | virtual UINT32 execute_input_lines() const { return 2+1; } // 3rd one is internal |
| 82 | virtual void execute_set_input(int line, int state); |
| 82 | 83 | virtual void execute_run(); |
| 83 | 84 | |
| 84 | 85 | // device_memory_interface overrides |
| r244932 | r244933 | |
| 86 | 87 | |
| 87 | 88 | // device_disasm_interface overrides |
| 88 | 89 | virtual UINT32 disasm_min_opcode_bytes() const { return 2; } |
| 89 | | virtual UINT32 disasm_max_opcode_bytes() const { return 2+1; } |
| 90 | virtual UINT32 disasm_max_opcode_bytes() const { return 2; } |
| 90 | 91 | virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options); |
| 91 | 92 | void state_string_export(const device_state_entry &entry, astring &string); |
| 92 | 93 | |
| r244932 | r244933 | |
| 107 | 108 | UINT16 m_stack[4]; // max 4 |
| 108 | 109 | UINT16 m_op; // current opcode |
| 109 | 110 | UINT16 m_prev_op; |
| 111 | UINT8 m_i; // 4-bit immediate opcode param |
| 112 | int m_eint_line; // which input_line caused an interrupt |
| 113 | emu_timer *m_timer; |
| 110 | 114 | int m_icount; |
| 111 | 115 | |
| 112 | 116 | UINT16 m_pc; // Program Counter |
| r244932 | r244933 | |
| 118 | 122 | UINT8 m_spx; // 1/3/4-bit SPX register |
| 119 | 123 | UINT8 m_y; // 4-bit Y register |
| 120 | 124 | UINT8 m_spy; // 4-bit SPY register |
| 121 | | UINT8 m_s; // Status F/F |
| 125 | UINT8 m_s; // Status F/F (F/F = flip-flop) |
| 122 | 126 | UINT8 m_c; // Carry F/F |
| 127 | UINT8 m_tc; // Timer/Counter |
| 128 | UINT8 m_cf; // CF F/F (timer mode or counter mode) |
| 129 | UINT8 m_ie; // I/E(Interrupt Enable) F/F |
| 130 | UINT8 m_iri; // external interrupt pending I/RI F/F |
| 131 | UINT8 m_irt; // timer interrupt pending I/RT F/F |
| 132 | UINT8 m_if[2]; // external interrupt mask IF0,1 F/F |
| 133 | UINT8 m_tf; // timer interrupt mask TF F/F |
| 134 | UINT8 m_int[2]; // INT0/1 pins state |
| 123 | 135 | UINT8 m_r[8]; // R outputs state |
| 124 | 136 | UINT16 m_d; // D pins state |
| 125 | 137 | |
| r244932 | r244933 | |
| 142 | 154 | virtual int read_d(int index); |
| 143 | 155 | virtual void write_d(int index, int state); |
| 144 | 156 | |
| 157 | void reset_prescaler(); |
| 158 | TIMER_CALLBACK_MEMBER( simple_timer_cb ); |
| 159 | void increment_tc(); |
| 160 | void do_interrupt(); |
| 161 | |
| 145 | 162 | // opcode handlers |
| 146 | 163 | void op_illegal(); |
| 147 | 164 | |
trunk/src/emu/cpu/hmcs40/hmcs40d.c
| r244932 | r244933 | |
| 3 | 3 | /* |
| 4 | 4 | |
| 5 | 5 | Hitachi HMCS40 MCU family disassembler |
| 6 | |
| 7 | NOTE: start offset(basepc) is $3F, not 0 |
| 6 | 8 | |
| 7 | 9 | */ |
| 8 | 10 | |
| r244932 | r244933 | |
| 41 | 43 | "NOP", "?" |
| 42 | 44 | }; |
| 43 | 45 | |
| 44 | | // number of bits per opcode parameter, -3 means (XY) parameter |
| 46 | // number of bits per opcode parameter, 99 means (XY) parameter, negative means reversed bit-order |
| 45 | 47 | static const INT8 s_bits[] = |
| 46 | 48 | { |
| 47 | 49 | 0, 0, 0, 0, 0, 4, |
| 48 | | 0, 0, 4, 4, 0, 0, 0, 0, -3, |
| 49 | | -3, -3, -3, -3, -3, -3, |
| 50 | | 4, 4, 4, |
| 51 | | 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 52 | | 4, 4, 0, 0, 4, 0, 0, |
| 50 | 0, 0, -4, -4, 0, 0, 0, 0, 99, |
| 51 | 99, 99, 99, 99, 99, 99, |
| 52 | -4, -4, -4, |
| 53 | -4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 54 | -4, -4, 0, 0, -4, 0, 0, |
| 53 | 55 | 2, 2, 2, |
| 54 | 56 | 6, 6, 5, 3, 0, |
| 55 | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, |
| 56 | | 0, 0, 0, 4, 4, 3, 3, 3, 3, 3, |
| 57 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -4, 0, 0, 0, |
| 58 | 0, 0, 0, -4, -4, 3, 3, 3, 3, 3, |
| 57 | 59 | 0, 0 |
| 58 | 60 | }; |
| 59 | 61 | |
| r244932 | r244933 | |
| 186 | 188 | INT8 bits = s_bits[instr]; |
| 187 | 189 | |
| 188 | 190 | // special case for (XY) opcode |
| 189 | | if (bits == -3) |
| 191 | if (bits == 99) |
| 190 | 192 | { |
| 191 | 193 | dst += sprintf(dst, "%s", s_mnemonics[instr]); |
| 192 | 194 | |
| r244932 | r244933 | |
| 196 | 198 | dst += sprintf(dst, "Y"); |
| 197 | 199 | } |
| 198 | 200 | else |
| 201 | { |
| 199 | 202 | dst += sprintf(dst, "%-6s ", s_mnemonics[instr]); |
| 200 | 203 | |
| 201 | | // opcode parameter |
| 202 | | if (bits > 0) |
| 203 | | { |
| 204 | | UINT8 param = op & ((1 << bits) - 1); |
| 205 | | |
| 206 | | if (bits > 5) |
| 207 | | dst += sprintf(dst, "$%02X", param); |
| 208 | | else |
| 209 | | dst += sprintf(dst, "%d", param); |
| 204 | // opcode parameter |
| 205 | if (bits != 0) |
| 206 | { |
| 207 | UINT8 param = op; |
| 208 | |
| 209 | // reverse bits |
| 210 | if (bits < 0) |
| 211 | { |
| 212 | param = BITSWAP8(param,0,1,2,3,4,5,6,7); |
| 213 | param >>= (8 + bits); |
| 214 | bits = -bits; |
| 215 | } |
| 216 | |
| 217 | param &= ((1 << bits) - 1); |
| 218 | |
| 219 | if (bits > 5) |
| 220 | dst += sprintf(dst, "$%02X", param); |
| 221 | else |
| 222 | dst += sprintf(dst, "%d", param); |
| 223 | } |
| 210 | 224 | } |
| 211 | 225 | |
| 212 | 226 | int pos = s_next_pc[pc & 0x3f] & DASMFLAG_LENGTHMASK; |
trunk/src/emu/cpu/hmcs40/hmcs40op.inc
| r244932 | r244933 | |
| 34 | 34 | |
| 35 | 35 | void hmcs40_cpu_device::op_illegal() |
| 36 | 36 | { |
| 37 | | logerror("%s unknown opcode $%03X at $%04X\n", tag(), m_op, m_prev_pc << 1); |
| 37 | logerror("%s unknown opcode $%03X at $%04X\n", tag(), m_op, m_prev_pc); |
| 38 | 38 | } |
| 39 | 39 | |
| 40 | 40 | |
| r244932 | r244933 | |
| 110 | 110 | void hmcs40_cpu_device::op_lxi() |
| 111 | 111 | { |
| 112 | 112 | // LXI i: Load X from Immediate |
| 113 | | m_x = m_op & 0xf; |
| 113 | m_x = m_i; |
| 114 | 114 | } |
| 115 | 115 | |
| 116 | 116 | void hmcs40_cpu_device::op_lyi() |
| 117 | 117 | { |
| 118 | 118 | // LYI i: Load Y from Immediate |
| 119 | | m_y = m_op & 0xf; |
| 119 | m_y = m_i; |
| 120 | 120 | } |
| 121 | 121 | |
| 122 | 122 | void hmcs40_cpu_device::op_iy() |
| r244932 | r244933 | |
| 223 | 223 | void hmcs40_cpu_device::op_lmiiy() |
| 224 | 224 | { |
| 225 | 225 | // LMIIY i: Load Memory from Immediate, Increment Y |
| 226 | | ram_w(m_op & 0xf); |
| 226 | ram_w(m_i); |
| 227 | 227 | op_iy(); |
| 228 | 228 | } |
| 229 | 229 | |
| 230 | 230 | void hmcs40_cpu_device::op_lai() |
| 231 | 231 | { |
| 232 | 232 | // LAI i: Load A from Immediate |
| 233 | | m_a = m_op & 0xf; |
| 233 | m_a = m_i; |
| 234 | 234 | } |
| 235 | 235 | |
| 236 | 236 | void hmcs40_cpu_device::op_lbi() |
| 237 | 237 | { |
| 238 | 238 | // LBI i: Load B from Immediate |
| 239 | | m_b = m_op & 0xf; |
| 239 | m_b = m_i; |
| 240 | 240 | } |
| 241 | 241 | |
| 242 | 242 | |
| r244932 | r244933 | |
| 245 | 245 | void hmcs40_cpu_device::op_ai() |
| 246 | 246 | { |
| 247 | 247 | // AI i: Add Immediate to A |
| 248 | | m_a += (m_op & 0xf); |
| 248 | m_a += (m_i); |
| 249 | 249 | m_s = m_a >> 4 & 1; |
| 250 | 250 | m_a &= 0xf; |
| 251 | 251 | } |
| r244932 | r244933 | |
| 368 | 368 | void hmcs40_cpu_device::op_mnei() |
| 369 | 369 | { |
| 370 | 370 | // MNEI i: Memory Not Equal to Immediate |
| 371 | | m_s = (ram_r() != (m_op & 0xf)); |
| 371 | m_s = (ram_r() != (m_i)); |
| 372 | 372 | } |
| 373 | 373 | |
| 374 | 374 | void hmcs40_cpu_device::op_ynei() |
| 375 | 375 | { |
| 376 | 376 | // YNEI i: Y Not Equal to Immediate |
| 377 | | m_s = (m_y != (m_op & 0xf)); |
| 377 | m_s = (m_y != (m_i)); |
| 378 | 378 | } |
| 379 | 379 | |
| 380 | 380 | void hmcs40_cpu_device::op_anem() |
| r244932 | r244933 | |
| 392 | 392 | void hmcs40_cpu_device::op_alei() |
| 393 | 393 | { |
| 394 | 394 | // ALEI i: A Less or Equal to Immediate |
| 395 | | m_s = (m_a <= (m_op & 0xf)); |
| 395 | m_s = (m_a <= (m_i)); |
| 396 | 396 | } |
| 397 | 397 | |
| 398 | 398 | void hmcs40_cpu_device::op_alem() |
| r244932 | r244933 | |
| 458 | 458 | if (m_s) |
| 459 | 459 | m_page = m_op & 0x1f; |
| 460 | 460 | else |
| 461 | | m_op = 0; |
| 461 | m_op = 0; // fake nop |
| 462 | 462 | } |
| 463 | 463 | |
| 464 | 464 | void hmcs40_cpu_device::op_tbr() |
| r244932 | r244933 | |
| 480 | 480 | void hmcs40_cpu_device::op_seie() |
| 481 | 481 | { |
| 482 | 482 | // SEIE: Set I/E |
| 483 | | op_illegal(); |
| 483 | m_ie = 1; |
| 484 | 484 | } |
| 485 | 485 | |
| 486 | 486 | void hmcs40_cpu_device::op_seif0() |
| 487 | 487 | { |
| 488 | 488 | // SEIF0: Set IF0 |
| 489 | | op_illegal(); |
| 489 | m_if[0] = 1; |
| 490 | 490 | } |
| 491 | 491 | |
| 492 | 492 | void hmcs40_cpu_device::op_seif1() |
| 493 | 493 | { |
| 494 | 494 | // SEIF1: Set IF1 |
| 495 | | op_illegal(); |
| 495 | m_if[1] = 1; |
| 496 | 496 | } |
| 497 | 497 | |
| 498 | 498 | void hmcs40_cpu_device::op_setf() |
| 499 | 499 | { |
| 500 | 500 | // SETF: Set TF |
| 501 | | op_illegal(); |
| 501 | m_tf = 1; |
| 502 | 502 | } |
| 503 | 503 | |
| 504 | 504 | void hmcs40_cpu_device::op_secf() |
| 505 | 505 | { |
| 506 | 506 | // SECF: Set CF |
| 507 | | op_illegal(); |
| 507 | m_cf = 1; |
| 508 | 508 | } |
| 509 | 509 | |
| 510 | 510 | void hmcs40_cpu_device::op_reie() |
| 511 | 511 | { |
| 512 | 512 | // REIE: Reset I/E |
| 513 | | op_illegal(); |
| 513 | m_ie = 0; |
| 514 | 514 | } |
| 515 | 515 | |
| 516 | 516 | void hmcs40_cpu_device::op_reif0() |
| 517 | 517 | { |
| 518 | 518 | // REIF0: Reset IF0 |
| 519 | | op_illegal(); |
| 519 | m_if[0] = 0; |
| 520 | 520 | } |
| 521 | 521 | |
| 522 | 522 | void hmcs40_cpu_device::op_reif1() |
| 523 | 523 | { |
| 524 | 524 | // REIF1: Reset IF1 |
| 525 | | op_illegal(); |
| 525 | m_if[1] = 0; |
| 526 | 526 | } |
| 527 | 527 | |
| 528 | 528 | void hmcs40_cpu_device::op_retf() |
| 529 | 529 | { |
| 530 | 530 | // RETF: Reset TF |
| 531 | | op_illegal(); |
| 531 | m_tf = 0; |
| 532 | 532 | } |
| 533 | 533 | |
| 534 | 534 | void hmcs40_cpu_device::op_recf() |
| 535 | 535 | { |
| 536 | 536 | // RECF: Reset CF |
| 537 | | op_illegal(); |
| 537 | m_cf = 0; |
| 538 | 538 | } |
| 539 | 539 | |
| 540 | 540 | void hmcs40_cpu_device::op_ti0() |
| 541 | 541 | { |
| 542 | 542 | // TI0: Test INT0 |
| 543 | | op_illegal(); |
| 543 | m_s = m_int[0]; |
| 544 | 544 | } |
| 545 | 545 | |
| 546 | 546 | void hmcs40_cpu_device::op_ti1() |
| 547 | 547 | { |
| 548 | 548 | // TI1: Test INT1 |
| 549 | | op_illegal(); |
| 549 | m_s = m_int[1]; |
| 550 | 550 | } |
| 551 | 551 | |
| 552 | 552 | void hmcs40_cpu_device::op_tif0() |
| 553 | 553 | { |
| 554 | 554 | // TIF0: Test IF0 |
| 555 | | op_illegal(); |
| 555 | m_s = m_if[0]; |
| 556 | 556 | } |
| 557 | 557 | |
| 558 | 558 | void hmcs40_cpu_device::op_tif1() |
| 559 | 559 | { |
| 560 | 560 | // TIF1: Test IF1 |
| 561 | | op_illegal(); |
| 561 | m_s = m_if[1]; |
| 562 | 562 | } |
| 563 | 563 | |
| 564 | 564 | void hmcs40_cpu_device::op_ttf() |
| 565 | 565 | { |
| 566 | 566 | // TTF: Test TF |
| 567 | | op_illegal(); |
| 567 | m_s = m_tf; |
| 568 | 568 | } |
| 569 | 569 | |
| 570 | 570 | void hmcs40_cpu_device::op_lti() |
| 571 | 571 | { |
| 572 | 572 | // LTI i: Load Timer/Counter from Immediate |
| 573 | | op_illegal(); |
| 573 | m_tc = m_i; |
| 574 | reset_prescaler(); |
| 574 | 575 | } |
| 575 | 576 | |
| 576 | 577 | void hmcs40_cpu_device::op_lta() |
| 577 | 578 | { |
| 578 | 579 | // LTA: Load Timer/Counter from A |
| 579 | | op_illegal(); |
| 580 | m_tc = m_a; |
| 581 | reset_prescaler(); |
| 580 | 582 | } |
| 581 | 583 | |
| 582 | 584 | void hmcs40_cpu_device::op_lat() |
| 583 | 585 | { |
| 584 | 586 | // LAT: Load A from Timer/Counter |
| 585 | | op_illegal(); |
| 587 | m_a = m_tc; |
| 586 | 588 | } |
| 587 | 589 | |
| 588 | 590 | void hmcs40_cpu_device::op_rtni() |
| 589 | 591 | { |
| 590 | 592 | // RTNI: Return from Interrupt |
| 591 | | op_illegal(); |
| 593 | op_seie(); |
| 594 | op_rtn(); |
| 592 | 595 | } |
| 593 | 596 | |
| 594 | 597 | |
| r244932 | r244933 | |
| 615 | 618 | void hmcs40_cpu_device::op_sedd() |
| 616 | 619 | { |
| 617 | 620 | // SEDD n: Set Discrete I/O Latch Direct |
| 618 | | write_d(m_op & 0xf, 1); |
| 621 | write_d(m_i, 1); |
| 619 | 622 | } |
| 620 | 623 | |
| 621 | 624 | void hmcs40_cpu_device::op_redd() |
| 622 | 625 | { |
| 623 | 626 | // REDD n: Reset Discrete I/O Latch Direct |
| 624 | | write_d(m_op & 0xf, 0); |
| 627 | write_d(m_i, 0); |
| 625 | 628 | } |
| 626 | 629 | |
| 627 | 630 | void hmcs40_cpu_device::op_lar() |