trunk/src/emu/cpu/tms0980/tms0980.c
| r18816 | r18817 | |
| 228 | 228 | |
| 229 | 229 | struct tms0980_state |
| 230 | 230 | { |
| 231 | | UINT8 prev_pc; /* previous program counter */ |
| 232 | | UINT8 prev_pa; /* previous page address register */ |
| 233 | | UINT8 pc; /* program counter is a 7 bit register on tms0980, 6 bit register on tms1000/1070/1200/1270/1100/1300 */ |
| 234 | | UINT8 pa; /* page address register is a 4 bit register */ |
| 235 | | UINT8 sr; /* subroutine return register is a 7 bit register */ |
| 236 | | UINT8 pb; /* page buffer register is a 4 bit register */ |
| 237 | | UINT8 a; /* Accumulator is a 4 bit register (?) */ |
| 238 | | UINT8 x; /* X-register is a 2, 3, or 4 bit register */ |
| 239 | | UINT8 y; /* Y-register is a 4 bit register */ |
| 240 | | UINT8 dam; /* DAM register is a 4 bit register */ |
| 241 | | UINT8 ca; /* Chapter address bit */ |
| 242 | | UINT8 cb; /* Chapter buffer bit */ |
| 243 | | UINT8 cs; /* Chapter subroutine bit */ |
| 244 | | UINT16 r; |
| 245 | | UINT8 o; |
| 246 | | UINT8 cki_bus; /* CKI bus */ |
| 247 | | UINT8 p; /* adder p-input */ |
| 248 | | UINT8 n; /* adder n-input */ |
| 249 | | UINT8 adder_result; /* adder result */ |
| 250 | | UINT8 carry_in; /* carry in */ |
| 251 | | UINT8 status; |
| 252 | | UINT8 status_latch; |
| 253 | | UINT8 special_status; |
| 254 | | UINT8 call_latch; |
| 255 | | UINT8 add_latch; |
| 256 | | UINT8 branch_latch; |
| 257 | | int subcycle; |
| 258 | | UINT8 ram_address; |
| 259 | | UINT16 ram_data; |
| 260 | | UINT16 rom_address; |
| 261 | | UINT16 opcode; |
| 262 | | UINT32 decode; |
| 263 | | int icount; |
| 264 | | UINT16 o_mask; /* mask to determine the number of O outputs */ |
| 265 | | UINT16 r_mask; /* mask to determine the number of R outputs */ |
| 266 | | UINT8 pc_size; /* how bits in the PC register */ |
| 267 | | UINT8 byte_size; /* 8 or 9 bit bytes */ |
| 231 | UINT8 m_prev_pc; /* previous program counter */ |
| 232 | UINT8 m_prev_pa; /* previous page address register */ |
| 233 | UINT8 m_pc; /* program counter is a 7 bit register on tms0980, 6 bit register on tms1000/1070/1200/1270/1100/1300 */ |
| 234 | UINT8 m_pa; /* page address register is a 4 bit register */ |
| 235 | UINT8 m_sr; /* subroutine return register is a 7 bit register */ |
| 236 | UINT8 m_pb; /* page buffer register is a 4 bit register */ |
| 237 | UINT8 m_a; /* Accumulator is a 4 bit register (?) */ |
| 238 | UINT8 m_x; /* X-register is a 2, 3, or 4 bit register */ |
| 239 | UINT8 m_y; /* Y-register is a 4 bit register */ |
| 240 | UINT8 m_dam; /* DAM register is a 4 bit register */ |
| 241 | UINT8 m_ca; /* Chapter address bit */ |
| 242 | UINT8 m_cb; /* Chapter buffer bit */ |
| 243 | UINT8 m_cs; /* Chapter subroutine bit */ |
| 244 | UINT16 m_r; |
| 245 | UINT8 m_o; |
| 246 | UINT8 m_cki_bus; /* CKI bus */ |
| 247 | UINT8 m_p; /* adder p-input */ |
| 248 | UINT8 m_n; /* adder n-input */ |
| 249 | UINT8 m_adder_result; /* adder result */ |
| 250 | UINT8 m_carry_in; /* carry in */ |
| 251 | UINT8 m_status; |
| 252 | UINT8 m_status_latch; |
| 253 | UINT8 m_special_status; |
| 254 | UINT8 m_call_latch; |
| 255 | UINT8 m_add_latch; |
| 256 | UINT8 m_branch_latch; |
| 257 | int m_subcycle; |
| 258 | UINT8 m_ram_address; |
| 259 | UINT16 m_ram_data; |
| 260 | UINT16 m_rom_address; |
| 261 | UINT16 m_opcode; |
| 262 | UINT32 m_decode; |
| 263 | int m_icount; |
| 264 | UINT16 m_o_mask; /* mask to determine the number of O outputs */ |
| 265 | UINT16 m_r_mask; /* mask to determine the number of R outputs */ |
| 266 | UINT8 m_pc_size; /* how bits in the PC register */ |
| 267 | UINT8 m_byte_size; /* 8 or 9 bit bytes */ |
| 268 | 268 | UINT8 m_x_bits; /* determine the number of bits in the X register */ |
| 269 | | const UINT32 *decode_table; |
| 269 | const UINT32 *m_decode_table; |
| 270 | 270 | const tms0980_config *config; |
| 271 | | address_space *program; |
| 272 | | address_space *data; |
| 271 | address_space *m_program; |
| 272 | address_space *m_data; |
| 273 | 273 | |
| 274 | 274 | devcb_resolved_read8 m_read_k; |
| 275 | 275 | devcb_resolved_write16 m_write_o; |
| r18816 | r18817 | |
| 506 | 506 | |
| 507 | 507 | assert( cpustate->config != NULL ); |
| 508 | 508 | |
| 509 | | cpustate->decode_table = decode_table; |
| 510 | | cpustate->o_mask = o_mask; |
| 511 | | cpustate->r_mask = r_mask; |
| 512 | | cpustate->pc_size = pc_size; |
| 513 | | cpustate->byte_size = byte_size; |
| 509 | cpustate->m_decode_table = decode_table; |
| 510 | cpustate->m_o_mask = o_mask; |
| 511 | cpustate->m_r_mask = r_mask; |
| 512 | cpustate->m_pc_size = pc_size; |
| 513 | cpustate->m_byte_size = byte_size; |
| 514 | 514 | cpustate->m_x_bits = x_bits; |
| 515 | 515 | |
| 516 | | cpustate->program = &device->space( AS_PROGRAM ); |
| 517 | | cpustate->data = &device->space( AS_DATA ); |
| 516 | cpustate->m_program = &device->space( AS_PROGRAM ); |
| 517 | cpustate->m_data = &device->space( AS_DATA ); |
| 518 | 518 | |
| 519 | 519 | cpustate->m_read_k.resolve(cpustate->config->read_k, *device); |
| 520 | 520 | cpustate->m_write_o.resolve(cpustate->config->write_o, *device); |
| 521 | 521 | cpustate->m_write_r.resolve(cpustate->config->write_r, *device); |
| 522 | 522 | |
| 523 | 523 | |
| 524 | | device->save_item( NAME(cpustate->prev_pc) ); |
| 525 | | device->save_item( NAME(cpustate->prev_pa) ); |
| 526 | | device->save_item( NAME(cpustate->pc) ); |
| 527 | | device->save_item( NAME(cpustate->pa) ); |
| 528 | | device->save_item( NAME(cpustate->sr) ); |
| 529 | | device->save_item( NAME(cpustate->pb) ); |
| 530 | | device->save_item( NAME(cpustate->a) ); |
| 531 | | device->save_item( NAME(cpustate->x) ); |
| 532 | | device->save_item( NAME(cpustate->y) ); |
| 533 | | device->save_item( NAME(cpustate->dam) ); |
| 534 | | device->save_item( NAME(cpustate->ca) ); |
| 535 | | device->save_item( NAME(cpustate->cb) ); |
| 536 | | device->save_item( NAME(cpustate->cs) ); |
| 537 | | device->save_item( NAME(cpustate->r) ); |
| 538 | | device->save_item( NAME(cpustate->o) ); |
| 539 | | device->save_item( NAME(cpustate->cki_bus) ); |
| 540 | | device->save_item( NAME(cpustate->p) ); |
| 541 | | device->save_item( NAME(cpustate->n) ); |
| 542 | | device->save_item( NAME(cpustate->adder_result) ); |
| 543 | | device->save_item( NAME(cpustate->carry_in) ); |
| 544 | | device->save_item( NAME(cpustate->status) ); |
| 545 | | device->save_item( NAME(cpustate->status_latch) ); |
| 546 | | device->save_item( NAME(cpustate->special_status) ); |
| 547 | | device->save_item( NAME(cpustate->call_latch) ); |
| 548 | | device->save_item( NAME(cpustate->add_latch) ); |
| 549 | | device->save_item( NAME(cpustate->branch_latch) ); |
| 550 | | device->save_item( NAME(cpustate->subcycle) ); |
| 551 | | device->save_item( NAME(cpustate->ram_address) ); |
| 552 | | device->save_item( NAME(cpustate->ram_data) ); |
| 553 | | device->save_item( NAME(cpustate->rom_address) ); |
| 554 | | device->save_item( NAME(cpustate->opcode) ); |
| 555 | | device->save_item( NAME(cpustate->decode) ); |
| 524 | device->save_item( NAME(cpustate->m_prev_pc) ); |
| 525 | device->save_item( NAME(cpustate->m_prev_pa) ); |
| 526 | device->save_item( NAME(cpustate->m_pc) ); |
| 527 | device->save_item( NAME(cpustate->m_pa) ); |
| 528 | device->save_item( NAME(cpustate->m_sr) ); |
| 529 | device->save_item( NAME(cpustate->m_pb) ); |
| 530 | device->save_item( NAME(cpustate->m_a) ); |
| 531 | device->save_item( NAME(cpustate->m_x) ); |
| 532 | device->save_item( NAME(cpustate->m_y) ); |
| 533 | device->save_item( NAME(cpustate->m_dam) ); |
| 534 | device->save_item( NAME(cpustate->m_ca) ); |
| 535 | device->save_item( NAME(cpustate->m_cb) ); |
| 536 | device->save_item( NAME(cpustate->m_cs) ); |
| 537 | device->save_item( NAME(cpustate->m_r) ); |
| 538 | device->save_item( NAME(cpustate->m_o) ); |
| 539 | device->save_item( NAME(cpustate->m_cki_bus) ); |
| 540 | device->save_item( NAME(cpustate->m_p) ); |
| 541 | device->save_item( NAME(cpustate->m_n) ); |
| 542 | device->save_item( NAME(cpustate->m_adder_result) ); |
| 543 | device->save_item( NAME(cpustate->m_carry_in) ); |
| 544 | device->save_item( NAME(cpustate->m_status) ); |
| 545 | device->save_item( NAME(cpustate->m_status_latch) ); |
| 546 | device->save_item( NAME(cpustate->m_special_status) ); |
| 547 | device->save_item( NAME(cpustate->m_call_latch) ); |
| 548 | device->save_item( NAME(cpustate->m_add_latch) ); |
| 549 | device->save_item( NAME(cpustate->m_branch_latch) ); |
| 550 | device->save_item( NAME(cpustate->m_subcycle) ); |
| 551 | device->save_item( NAME(cpustate->m_ram_address) ); |
| 552 | device->save_item( NAME(cpustate->m_ram_data) ); |
| 553 | device->save_item( NAME(cpustate->m_rom_address) ); |
| 554 | device->save_item( NAME(cpustate->m_opcode) ); |
| 555 | device->save_item( NAME(cpustate->m_decode) ); |
| 556 | 556 | } |
| 557 | 557 | |
| 558 | 558 | |
| r18816 | r18817 | |
| 602 | 602 | { |
| 603 | 603 | tms0980_state *cpustate = get_safe_token( device ); |
| 604 | 604 | |
| 605 | | cpustate->pa = 0x0F; |
| 606 | | cpustate->pb = 0x0F; |
| 607 | | cpustate->pc = 0; |
| 608 | | cpustate->dam = 0; |
| 609 | | cpustate->ca = 0; |
| 610 | | cpustate->cb = 0; |
| 611 | | cpustate->cs = 0; |
| 612 | | cpustate->subcycle = 0; |
| 613 | | cpustate->status = 1; |
| 614 | | cpustate->status_latch = 0; |
| 615 | | cpustate->call_latch = 0; |
| 616 | | cpustate->add_latch = 0; |
| 617 | | cpustate->branch_latch = 0; |
| 618 | | cpustate->r = 0; |
| 619 | | cpustate->o = 0; |
| 620 | | cpustate->ram_address = 0; |
| 621 | | cpustate->decode = F_ILL; |
| 622 | | cpustate->opcode = 0; |
| 605 | cpustate->m_pa = 0x0F; |
| 606 | cpustate->m_pb = 0x0F; |
| 607 | cpustate->m_pc = 0; |
| 608 | cpustate->m_dam = 0; |
| 609 | cpustate->m_ca = 0; |
| 610 | cpustate->m_cb = 0; |
| 611 | cpustate->m_cs = 0; |
| 612 | cpustate->m_subcycle = 0; |
| 613 | cpustate->m_status = 1; |
| 614 | cpustate->m_status_latch = 0; |
| 615 | cpustate->m_call_latch = 0; |
| 616 | cpustate->m_add_latch = 0; |
| 617 | cpustate->m_branch_latch = 0; |
| 618 | cpustate->m_r = 0; |
| 619 | cpustate->m_o = 0; |
| 620 | cpustate->m_ram_address = 0; |
| 621 | cpustate->m_decode = F_ILL; |
| 622 | cpustate->m_opcode = 0; |
| 623 | 623 | } |
| 624 | 624 | |
| 625 | 625 | |
| r18816 | r18817 | |
| 745 | 745 | */ |
| 746 | 746 | INLINE void tms0980_next_pc( tms0980_state *cpustate ) |
| 747 | 747 | { |
| 748 | | if ( cpustate->byte_size > 8 ) |
| 748 | if ( cpustate->m_byte_size > 8 ) |
| 749 | 749 | { |
| 750 | | UINT8 xorval = ( cpustate->pc & 0x3F ) == 0x3F ? 1 : 0; |
| 751 | | UINT8 new_bit = ( ( cpustate->pc ^ ( cpustate->pc << 1 ) ) & 0x40 ) ? xorval : 1 - xorval; |
| 750 | UINT8 xorval = ( cpustate->m_pc & 0x3F ) == 0x3F ? 1 : 0; |
| 751 | UINT8 new_bit = ( ( cpustate->m_pc ^ ( cpustate->m_pc << 1 ) ) & 0x40 ) ? xorval : 1 - xorval; |
| 752 | 752 | |
| 753 | | cpustate->pc = ( cpustate->pc << 1 ) | new_bit; |
| 753 | cpustate->m_pc = ( cpustate->m_pc << 1 ) | new_bit; |
| 754 | 754 | } |
| 755 | 755 | else |
| 756 | 756 | { |
| 757 | | cpustate->pc = tms1000_next_pc[ cpustate->pc & 0x3f ]; |
| 757 | cpustate->m_pc = tms1000_next_pc[ cpustate->m_pc & 0x3f ]; |
| 758 | 758 | } |
| 759 | 759 | } |
| 760 | 760 | |
| r18816 | r18817 | |
| 776 | 776 | { |
| 777 | 777 | tms0980_state *cpustate = get_safe_token( device ); |
| 778 | 778 | |
| 779 | | switch( cpustate->opcode & 0x1F8 ) |
| 779 | switch( cpustate->m_opcode & 0x1F8 ) |
| 780 | 780 | { |
| 781 | 781 | case 0x008: |
| 782 | 782 | if ( !cpustate->m_read_k.isnull() ) |
| 783 | 783 | { |
| 784 | | cpustate->cki_bus = cpustate->m_read_k( 0, 0xff ); |
| 784 | cpustate->m_cki_bus = cpustate->m_read_k( 0, 0xff ); |
| 785 | 785 | } |
| 786 | 786 | else |
| 787 | 787 | { |
| 788 | | cpustate->cki_bus = 0x0F; |
| 788 | cpustate->m_cki_bus = 0x0F; |
| 789 | 789 | } |
| 790 | 790 | break; |
| 791 | 791 | case 0x020: case 0x028: |
| 792 | | cpustate->cki_bus = 0; |
| 792 | cpustate->m_cki_bus = 0; |
| 793 | 793 | break; |
| 794 | 794 | case 0x030: case 0x038: |
| 795 | | cpustate->cki_bus = tms0980_nbit_value[ cpustate->opcode & 0x03 ]; |
| 795 | cpustate->m_cki_bus = tms0980_nbit_value[ cpustate->m_opcode & 0x03 ]; |
| 796 | 796 | break; |
| 797 | 797 | case 0x000: |
| 798 | 798 | case 0x040: case 0x048: |
| r18816 | r18817 | |
| 805 | 805 | case 0x0d0: case 0x0d8: |
| 806 | 806 | case 0x0e0: case 0x0e8: |
| 807 | 807 | case 0x0f0: case 0x0f8: |
| 808 | | cpustate->cki_bus = tms0980_c4_value[ cpustate->opcode & 0x0F ]; |
| 808 | cpustate->m_cki_bus = tms0980_c4_value[ cpustate->m_opcode & 0x0F ]; |
| 809 | 809 | break; |
| 810 | 810 | default: |
| 811 | | cpustate->cki_bus = 0x0F; |
| 811 | cpustate->m_cki_bus = 0x0F; |
| 812 | 812 | break; |
| 813 | 813 | } |
| 814 | 814 | } |
| r18816 | r18817 | |
| 820 | 820 | |
| 821 | 821 | do |
| 822 | 822 | { |
| 823 | | // debugger_instruction_hook( device, ( ( cpustate->pa << cpustate->pc_size ) | cpustate->pc ) << 1 ); |
| 824 | | cpustate->icount--; |
| 825 | | switch( cpustate->subcycle ) |
| 823 | // debugger_instruction_hook( device, ( ( cpustate->m_pa << cpustate->m_pc_size ) | cpustate->m_pc ) << 1 ); |
| 824 | cpustate->m_icount--; |
| 825 | switch( cpustate->m_subcycle ) |
| 826 | 826 | { |
| 827 | 827 | case 0: |
| 828 | 828 | /* fetch: rom address 0 */ |
| 829 | 829 | /* execute: read ram, alu input, execute br/call, k input valid */ |
| 830 | 830 | tms0980_set_cki_bus( device ); |
| 831 | | cpustate->ram_data = cpustate->data->read_byte( cpustate->ram_address ); |
| 832 | | cpustate->status = 1; |
| 833 | | cpustate->p = 0; |
| 834 | | cpustate->n = 0; |
| 835 | | cpustate->carry_in = 0; |
| 831 | cpustate->m_ram_data = cpustate->m_data->read_byte( cpustate->m_ram_address ); |
| 832 | cpustate->m_status = 1; |
| 833 | cpustate->m_p = 0; |
| 834 | cpustate->m_n = 0; |
| 835 | cpustate->m_carry_in = 0; |
| 836 | 836 | break; |
| 837 | 837 | case 1: |
| 838 | 838 | /* fetch: rom address 1 */ |
| 839 | | if ( cpustate->pc_size == 6 ) |
| 840 | | // cpustate->rom_address = ( cpustate->pa << 6 ) | tms1000_pc_decode[ cpustate->pc ]; |
| 841 | | cpustate->rom_address = ( cpustate->pa << 6 ) | cpustate->pc; |
| 842 | | else |
| 843 | | cpustate->rom_address = ( cpustate->pa << 7 ) | cpustate->pc; |
| 839 | cpustate->m_rom_address = ( cpustate->m_ca << ( cpustate->m_pc_size + 4 ) ) | ( cpustate->m_pa << cpustate->m_pc_size ) | cpustate->m_pc; |
| 844 | 840 | /* execute: k input valid */ |
| 845 | | if ( cpustate->decode & MICRO_MASK ) |
| 841 | if ( cpustate->m_decode & MICRO_MASK ) |
| 846 | 842 | { |
| 847 | 843 | /* Check N inputs */ |
| 848 | | if ( cpustate->decode & ( M_15TN | M_ATN | M_CKN | M_MTN | M_NATN ) ) |
| 844 | if ( cpustate->m_decode & ( M_15TN | M_ATN | M_CKN | M_MTN | M_NATN ) ) |
| 849 | 845 | { |
| 850 | | cpustate->n = 0; |
| 851 | | if ( cpustate->decode & M_15TN ) |
| 846 | cpustate->m_n = 0; |
| 847 | if ( cpustate->m_decode & M_15TN ) |
| 852 | 848 | { |
| 853 | | cpustate->n |= 0x0F; |
| 849 | cpustate->m_n |= 0x0F; |
| 854 | 850 | } |
| 855 | | if ( cpustate->decode & M_ATN ) |
| 851 | if ( cpustate->m_decode & M_ATN ) |
| 856 | 852 | { |
| 857 | | cpustate->n |= cpustate->a; |
| 853 | cpustate->m_n |= cpustate->m_a; |
| 858 | 854 | } |
| 859 | | if ( cpustate->decode & M_CKN ) |
| 855 | if ( cpustate->m_decode & M_CKN ) |
| 860 | 856 | { |
| 861 | | cpustate->n |= cpustate->cki_bus; |
| 857 | cpustate->m_n |= cpustate->m_cki_bus; |
| 862 | 858 | } |
| 863 | | if ( cpustate->decode & M_MTN ) |
| 859 | if ( cpustate->m_decode & M_MTN ) |
| 864 | 860 | { |
| 865 | | cpustate->n |= cpustate->ram_data; |
| 861 | cpustate->m_n |= cpustate->m_ram_data; |
| 866 | 862 | } |
| 867 | | if ( cpustate->decode & M_NATN ) |
| 863 | if ( cpustate->m_decode & M_NATN ) |
| 868 | 864 | { |
| 869 | | cpustate->n |= ( ( ~cpustate->a ) & 0x0F ); |
| 865 | cpustate->m_n |= ( ( ~cpustate->m_a ) & 0x0F ); |
| 870 | 866 | } |
| 871 | 867 | } |
| 872 | 868 | |
| 873 | 869 | |
| 874 | 870 | /* Check P inputs */ |
| 875 | | if ( cpustate->decode & ( M_CKP | M_DMTP | M_MTP | M_NDMTP | M_YTP ) ) |
| 871 | if ( cpustate->m_decode & ( M_CKP | M_DMTP | M_MTP | M_NDMTP | M_YTP ) ) |
| 876 | 872 | { |
| 877 | | cpustate->p = 0; |
| 878 | | if ( cpustate->decode & M_CKP ) |
| 873 | cpustate->m_p = 0; |
| 874 | if ( cpustate->m_decode & M_CKP ) |
| 879 | 875 | { |
| 880 | | cpustate->p |= cpustate->cki_bus; |
| 876 | cpustate->m_p |= cpustate->m_cki_bus; |
| 881 | 877 | } |
| 882 | | if ( cpustate->decode & M_DMTP ) |
| 878 | if ( cpustate->m_decode & M_DMTP ) |
| 883 | 879 | { |
| 884 | | cpustate->p |= cpustate->dam; |
| 880 | cpustate->m_p |= cpustate->m_dam; |
| 885 | 881 | } |
| 886 | | if ( cpustate->decode & M_MTP ) |
| 882 | if ( cpustate->m_decode & M_MTP ) |
| 887 | 883 | { |
| 888 | | cpustate->p |= cpustate->ram_data; |
| 884 | cpustate->m_p |= cpustate->m_ram_data; |
| 889 | 885 | } |
| 890 | | if ( cpustate->decode & M_NDMTP ) |
| 886 | if ( cpustate->m_decode & M_NDMTP ) |
| 891 | 887 | { |
| 892 | | cpustate->p |= ( ( ~cpustate->dam ) & 0x0F ); |
| 888 | cpustate->m_p |= ( ( ~cpustate->m_dam ) & 0x0F ); |
| 893 | 889 | } |
| 894 | | if ( cpustate->decode & M_YTP ) |
| 890 | if ( cpustate->m_decode & M_YTP ) |
| 895 | 891 | { |
| 896 | | cpustate->p |= cpustate->y; |
| 892 | cpustate->m_p |= cpustate->m_y; |
| 897 | 893 | } |
| 898 | 894 | } |
| 899 | 895 | |
| 900 | 896 | /* Carry In input */ |
| 901 | | if ( cpustate->decode & M_CIN ) |
| 897 | if ( cpustate->m_decode & M_CIN ) |
| 902 | 898 | { |
| 903 | | cpustate->carry_in = 1; |
| 899 | cpustate->m_carry_in = 1; |
| 904 | 900 | } |
| 905 | 901 | } |
| 906 | 902 | break; |
| r18816 | r18817 | |
| 908 | 904 | /* fetch: nothing */ |
| 909 | 905 | /* execute: write ram */ |
| 910 | 906 | /* perform adder logic */ |
| 911 | | cpustate->adder_result = cpustate->p + cpustate->n + cpustate->carry_in; |
| 912 | | if ( cpustate->decode & MICRO_MASK ) |
| 907 | cpustate->m_adder_result = cpustate->m_p + cpustate->m_n + cpustate->m_carry_in; |
| 908 | if ( cpustate->m_decode & MICRO_MASK ) |
| 913 | 909 | { |
| 914 | | if ( cpustate->decode & M_NE ) |
| 910 | if ( cpustate->m_decode & M_NE ) |
| 915 | 911 | { |
| 916 | | if ( cpustate->n == cpustate->p ) |
| 912 | if ( cpustate->m_n == cpustate->m_p ) |
| 917 | 913 | { |
| 918 | | cpustate->status = 0; |
| 914 | cpustate->m_status = 0; |
| 919 | 915 | } |
| 920 | 916 | } |
| 921 | | if ( cpustate->decode & M_C8 ) |
| 917 | if ( cpustate->m_decode & M_C8 ) |
| 922 | 918 | { |
| 923 | | cpustate->status = cpustate->adder_result >> 4; |
| 919 | cpustate->m_status = cpustate->m_adder_result >> 4; |
| 924 | 920 | } |
| 925 | | if ( cpustate->decode & M_STO ) |
| 921 | if ( cpustate->m_decode & M_STO ) |
| 926 | 922 | { |
| 927 | | cpustate->data->write_byte( cpustate->ram_address, cpustate->a ); |
| 923 | //printf("write ram %02x data %01x\n", cpustate->m_ram_address, cpustate->m_a ); |
| 924 | cpustate->m_data->write_byte( cpustate->m_ram_address, cpustate->m_a ); |
| 928 | 925 | } |
| 929 | | if ( cpustate->decode & M_CKM ) |
| 926 | if ( cpustate->m_decode & M_CKM ) |
| 930 | 927 | { |
| 931 | | cpustate->data->write_byte( cpustate->ram_address, cpustate->cki_bus ); |
| 928 | //printf("write ram %02x data %01x\n", cpustate->m_ram_address, cpustate->m_cki_bus ); |
| 929 | cpustate->m_data->write_byte( cpustate->m_ram_address, cpustate->m_cki_bus ); |
| 932 | 930 | } |
| 933 | 931 | } |
| 934 | 932 | else |
| 935 | 933 | { |
| 936 | | if ( cpustate->decode & F_SBIT ) |
| 934 | if ( cpustate->m_decode & F_SBIT ) |
| 937 | 935 | { |
| 938 | | cpustate->data->write_byte( cpustate->ram_address, cpustate->ram_data | tms0980_bit_value[ cpustate->opcode & 0x03 ] ); |
| 936 | //printf("write ram %02x data %01x\n", cpustate->m_ram_address, cpustate->m_ram_data | tms0980_bit_value[ cpustate->m_opcode & 0x03 ] ); |
| 937 | cpustate->m_data->write_byte( cpustate->m_ram_address, cpustate->m_ram_data | tms0980_bit_value[ cpustate->m_opcode & 0x03 ] ); |
| 939 | 938 | } |
| 940 | | if ( cpustate->decode & F_RBIT ) |
| 939 | if ( cpustate->m_decode & F_RBIT ) |
| 941 | 940 | { |
| 942 | | cpustate->data->write_byte( cpustate->ram_address, cpustate->ram_data & tms0980_nbit_value[ cpustate->opcode & 0x03 ] ); |
| 941 | //printf("write ram %02x data %01x\n", cpustate->m_ram_address, cpustate->m_ram_data & tms0980_nbit_value[ cpustate->m_opcode & 0x03 ] ); |
| 942 | cpustate->m_data->write_byte( cpustate->m_ram_address, cpustate->m_ram_data & tms0980_nbit_value[ cpustate->m_opcode & 0x03 ] ); |
| 943 | 943 | } |
| 944 | | if ( cpustate->decode & F_SETR ) |
| 944 | if ( cpustate->m_decode & F_SETR ) |
| 945 | 945 | { |
| 946 | | cpustate->r = cpustate->r | ( 1 << cpustate->y ); |
| 946 | cpustate->m_r = cpustate->m_r | ( 1 << cpustate->m_y ); |
| 947 | 947 | if ( !cpustate->m_write_r.isnull() ) |
| 948 | 948 | { |
| 949 | | cpustate->m_write_r( 0, cpustate->r & cpustate->r_mask, 0xffff ); |
| 949 | cpustate->m_write_r( 0, cpustate->m_r & cpustate->m_r_mask, 0xffff ); |
| 950 | 950 | } |
| 951 | 951 | } |
| 952 | | if ( cpustate->decode & F_RSTR ) |
| 952 | if ( cpustate->m_decode & F_RSTR ) |
| 953 | 953 | { |
| 954 | | cpustate->r = cpustate->r & ( ~( 1 << cpustate->y ) ); |
| 954 | cpustate->m_r = cpustate->m_r & ( ~( 1 << cpustate->m_y ) ); |
| 955 | 955 | if ( !cpustate->m_write_r.isnull() ) |
| 956 | 956 | { |
| 957 | | cpustate->m_write_r( 0, cpustate->r & cpustate->r_mask, 0xffff ); |
| 957 | cpustate->m_write_r( 0, cpustate->m_r & cpustate->m_r_mask, 0xffff ); |
| 958 | 958 | } |
| 959 | 959 | } |
| 960 | | if ( cpustate->decode & F_TDO ) |
| 960 | if ( cpustate->m_decode & F_TDO ) |
| 961 | 961 | { |
| 962 | | int i = 0; |
| 963 | | |
| 964 | 962 | /* Calculate O-outputs based on status latch, A, and the output PLA configuration */ |
| 965 | | cpustate->o = 0; |
| 966 | | for ( i = 0; i < 20; i++ ) |
| 967 | | { |
| 968 | | if ( ( ( cpustate->status_latch << 4 ) | cpustate->a ) == cpustate->config->o_pla[i].value ) |
| 969 | | { |
| 970 | | cpustate->o = cpustate->config->o_pla[i].output; |
| 971 | | } |
| 972 | | } |
| 963 | //printf("o output m_status_latch = %X, m_a = %X\n", cpustate->m_status_latch, cpustate->m_a); |
| 964 | cpustate->m_o = cpustate->config->o_pla[ ( cpustate->m_status_latch << 4 ) | cpustate->m_a ]; |
| 965 | //if ( cpustate->m_o == 0 ) |
| 966 | //printf("****** o output m_status_latch = %X, m_a = %X\n", cpustate->m_status_latch, cpustate->m_a); |
| 967 | //else |
| 968 | //printf("o output m_status_latch = %X, m_a = %X\n", cpustate->m_status_latch, cpustate->m_a); |
| 973 | 969 | |
| 974 | 970 | if ( !cpustate->m_write_o.isnull() ) |
| 975 | 971 | { |
| 976 | | cpustate->m_write_o( 0, cpustate->o & cpustate->o_mask, 0xffff ); |
| 972 | cpustate->m_write_o( 0, cpustate->m_o & cpustate->m_o_mask, 0xffff ); |
| 977 | 973 | } |
| 978 | 974 | } |
| 979 | | if ( cpustate->decode & F_CLO ) |
| 975 | if ( cpustate->m_decode & F_CLO ) |
| 980 | 976 | { |
| 981 | | cpustate->o = 0; |
| 977 | cpustate->m_o = 0; |
| 982 | 978 | if ( !cpustate->m_write_o.isnull() ) |
| 983 | 979 | { |
| 984 | | cpustate->m_write_o( 0, cpustate->o & cpustate->o_mask, 0xffff ); |
| 980 | cpustate->m_write_o( 0, cpustate->m_o & cpustate->m_o_mask, 0xffff ); |
| 985 | 981 | } |
| 986 | 982 | } |
| 987 | | if ( cpustate->decode & F_LDX ) |
| 983 | if ( cpustate->m_decode & F_LDX ) |
| 988 | 984 | { |
| 989 | 985 | switch( cpustate->m_x_bits ) |
| 990 | 986 | { |
| 991 | 987 | case 2: |
| 992 | | cpustate->x = tms0980_c2_value[ cpustate->opcode & 0x03 ]; |
| 988 | cpustate->m_x = tms0980_c2_value[ cpustate->m_opcode & 0x03 ]; |
| 993 | 989 | break; |
| 994 | 990 | case 3: |
| 995 | | cpustate->x = tms0980_c3_value[ cpustate->opcode & 0x07 ]; |
| 991 | cpustate->m_x = tms0980_c3_value[ cpustate->m_opcode & 0x07 ]; |
| 996 | 992 | break; |
| 997 | 993 | case 4: |
| 998 | | cpustate->x = tms0980_c4_value[ cpustate->opcode & 0x0f ]; |
| 994 | cpustate->m_x = tms0980_c4_value[ cpustate->m_opcode & 0x0f ]; |
| 999 | 995 | break; |
| 1000 | 996 | } |
| 1001 | 997 | } |
| 1002 | | if ( cpustate->decode & F_COMX ) |
| 998 | if ( cpustate->m_decode & F_COMX ) |
| 1003 | 999 | { |
| 1004 | | cpustate->x = cpustate->x ^ 0x03; |
| 1000 | switch ( cpustate->m_x_bits ) |
| 1001 | { |
| 1002 | case 2: |
| 1003 | cpustate->m_x = cpustate->m_x ^ 0x03; |
| 1004 | break; |
| 1005 | case 3: |
| 1006 | cpustate->m_x = cpustate->m_x ^ 0x07; |
| 1007 | break; |
| 1008 | case 4: |
| 1009 | cpustate->m_x = cpustate->m_x ^ 0x0f; |
| 1010 | break; |
| 1011 | } |
| 1005 | 1012 | } |
| 1006 | | if ( cpustate->decode & F_COMC ) |
| 1013 | if ( cpustate->m_decode & F_COMC ) |
| 1007 | 1014 | { |
| 1008 | | cpustate->cb = cpustate->cb ^ 0x01; |
| 1015 | cpustate->m_cb = cpustate->m_cb ^ 0x01; |
| 1009 | 1016 | } |
| 1010 | | if ( cpustate->decode & F_LDP ) |
| 1017 | if ( cpustate->m_decode & F_LDP ) |
| 1011 | 1018 | { |
| 1012 | | cpustate->pb = tms0980_c4_value[ cpustate->opcode & 0x0F ]; |
| 1019 | cpustate->m_pb = tms0980_c4_value[ cpustate->m_opcode & 0x0F ]; |
| 1013 | 1020 | } |
| 1014 | | if ( cpustate->decode & F_REAC ) |
| 1021 | if ( cpustate->m_decode & F_REAC ) |
| 1015 | 1022 | { |
| 1016 | | cpustate->special_status = 0; |
| 1023 | cpustate->m_special_status = 0; |
| 1017 | 1024 | } |
| 1018 | | if ( cpustate->decode & F_SEAC ) |
| 1025 | if ( cpustate->m_decode & F_SEAC ) |
| 1019 | 1026 | { |
| 1020 | | cpustate->special_status = 1; |
| 1027 | cpustate->m_special_status = 1; |
| 1021 | 1028 | } |
| 1022 | | if ( cpustate->decode == F_SAL ) |
| 1029 | if ( cpustate->m_decode == F_SAL ) |
| 1023 | 1030 | { |
| 1024 | | cpustate->add_latch = 1; |
| 1031 | cpustate->m_add_latch = 1; |
| 1025 | 1032 | } |
| 1026 | | if ( cpustate->decode == F_SBL ) |
| 1033 | if ( cpustate->m_decode == F_SBL ) |
| 1027 | 1034 | { |
| 1028 | | cpustate->branch_latch = 1; |
| 1035 | cpustate->m_branch_latch = 1; |
| 1029 | 1036 | } |
| 1030 | 1037 | } |
| 1031 | 1038 | break; |
| r18816 | r18817 | |
| 1035 | 1042 | break; |
| 1036 | 1043 | case 4: |
| 1037 | 1044 | /* execute: register store */ |
| 1038 | | if ( cpustate->decode & MICRO_MASK ) |
| 1045 | if ( cpustate->m_decode & MICRO_MASK ) |
| 1039 | 1046 | { |
| 1040 | | if ( cpustate->decode & M_AUTA ) |
| 1047 | if ( cpustate->m_decode & M_AUTA ) |
| 1041 | 1048 | { |
| 1042 | | cpustate->a = cpustate->adder_result & 0x0F; |
| 1049 | cpustate->m_a = cpustate->m_adder_result & 0x0F; |
| 1043 | 1050 | } |
| 1044 | | if ( cpustate->decode & M_AUTY ) |
| 1051 | if ( cpustate->m_decode & M_AUTY ) |
| 1045 | 1052 | { |
| 1046 | | cpustate->y = cpustate->adder_result & 0x0F; |
| 1053 | cpustate->m_y = cpustate->m_adder_result & 0x0F; |
| 1047 | 1054 | } |
| 1048 | | if ( cpustate->decode & M_STSL ) |
| 1055 | if ( cpustate->m_decode & M_STSL ) |
| 1049 | 1056 | { |
| 1050 | | cpustate->status_latch = cpustate->status; |
| 1057 | cpustate->m_status_latch = cpustate->m_status; |
| 1051 | 1058 | } |
| 1052 | 1059 | } |
| 1053 | 1060 | /* fetch: fetch, update pc, ram address */ |
| 1054 | | if ( cpustate->byte_size > 8 ) |
| 1061 | if ( cpustate->m_byte_size > 8 ) |
| 1055 | 1062 | { |
| 1056 | | debugger_instruction_hook( device, cpustate->rom_address << 1 ); |
| 1057 | | cpustate->opcode = cpustate->program->read_word( cpustate->rom_address << 1 ) & 0x1FF; |
| 1063 | debugger_instruction_hook( device, cpustate->m_rom_address << 1 ); |
| 1064 | cpustate->m_opcode = cpustate->m_program->read_word( cpustate->m_rom_address << 1 ) & 0x1FF; |
| 1058 | 1065 | } |
| 1059 | 1066 | else |
| 1060 | 1067 | { |
| 1061 | | debugger_instruction_hook( device, cpustate->rom_address ); |
| 1062 | | cpustate->opcode = cpustate->program->read_byte( cpustate->rom_address ); |
| 1068 | debugger_instruction_hook( device, cpustate->m_rom_address ); |
| 1069 | cpustate->m_opcode = cpustate->m_program->read_byte( cpustate->m_rom_address ); |
| 1063 | 1070 | } |
| 1064 | 1071 | tms0980_next_pc( cpustate ); |
| 1065 | 1072 | if (LOG) |
| 1066 | | logerror( "tms0980: read opcode %04x from %04x. Set pc to %04x\n", cpustate->opcode, cpustate->rom_address, cpustate->pc ); |
| 1073 | logerror( "tms0980: read opcode %04x from %04x. Set pc to %04x\n", cpustate->m_opcode, cpustate->m_rom_address, cpustate->m_pc ); |
| 1067 | 1074 | |
| 1068 | 1075 | /* ram address */ |
| 1069 | | cpustate->ram_address = ( cpustate->x << 4 ) | cpustate->y; |
| 1076 | cpustate->m_ram_address = ( cpustate->m_x << 4 ) | cpustate->m_y; |
| 1070 | 1077 | break; |
| 1071 | 1078 | case 5: |
| 1072 | 1079 | /* fetch: instruction decode */ |
| 1073 | | cpustate->decode = cpustate->decode_table[ cpustate->opcode ]; |
| 1080 | cpustate->m_decode = cpustate->m_decode_table[ cpustate->m_opcode ]; |
| 1074 | 1081 | /* execute: execute br/call */ |
| 1075 | | if ( cpustate->status ) |
| 1082 | if ( cpustate->m_status ) |
| 1076 | 1083 | { |
| 1077 | | if ( cpustate->decode == F_BR ) |
| 1084 | if ( cpustate->m_decode == F_BR ) |
| 1078 | 1085 | { |
| 1079 | | if ( cpustate->call_latch == 0 ) |
| 1086 | cpustate->m_ca = cpustate->m_cb; |
| 1087 | if ( cpustate->m_call_latch == 0 ) |
| 1080 | 1088 | { |
| 1081 | | cpustate->pa = cpustate->pb; |
| 1089 | cpustate->m_pa = cpustate->m_pb; |
| 1082 | 1090 | } |
| 1083 | | cpustate->pc = cpustate->opcode & ( ( 1 << cpustate->pc_size ) - 1 ); |
| 1091 | cpustate->m_pc = cpustate->m_opcode & ( ( 1 << cpustate->m_pc_size ) - 1 ); |
| 1084 | 1092 | } |
| 1085 | | if ( cpustate->decode == F_CALL ) |
| 1093 | if ( cpustate->m_decode == F_CALL ) |
| 1086 | 1094 | { |
| 1087 | | UINT8 t = cpustate->pa; |
| 1088 | | if ( cpustate->call_latch == 0 ) |
| 1095 | UINT8 t = cpustate->m_pa; |
| 1096 | if ( cpustate->m_call_latch == 0 ) |
| 1089 | 1097 | { |
| 1090 | | cpustate->sr = cpustate->pc; |
| 1091 | | cpustate->call_latch = 1; |
| 1092 | | cpustate->pa = cpustate->pb; |
| 1098 | cpustate->m_sr = cpustate->m_pc; |
| 1099 | cpustate->m_call_latch = 1; |
| 1100 | cpustate->m_pa = cpustate->m_pb; |
| 1101 | cpustate->m_cs = cpustate->m_ca; |
| 1093 | 1102 | } |
| 1094 | | cpustate->pb = t; |
| 1095 | | cpustate->pc = cpustate->opcode & ( ( 1 << cpustate->pc_size ) - 1 ); |
| 1103 | cpustate->m_ca = cpustate->m_cb; |
| 1104 | cpustate->m_pb = t; |
| 1105 | cpustate->m_pc = cpustate->m_opcode & ( ( 1 << cpustate->m_pc_size ) - 1 ); |
| 1096 | 1106 | } |
| 1097 | 1107 | } |
| 1098 | | if ( cpustate->decode == F_RETN ) |
| 1108 | if ( cpustate->m_decode == F_RETN ) |
| 1099 | 1109 | { |
| 1100 | | if ( cpustate->call_latch == 1 ) |
| 1110 | if ( cpustate->m_call_latch == 1 ) |
| 1101 | 1111 | { |
| 1102 | | cpustate->pc = cpustate->sr; |
| 1103 | | cpustate->call_latch = 0; |
| 1112 | cpustate->m_pc = cpustate->m_sr; |
| 1113 | cpustate->m_call_latch = 0; |
| 1114 | cpustate->m_ca = cpustate->m_cs; |
| 1104 | 1115 | } |
| 1105 | | cpustate->add_latch = 0; |
| 1106 | | cpustate->pa = cpustate->pb; |
| 1116 | cpustate->m_add_latch = 0; |
| 1117 | cpustate->m_pa = cpustate->m_pb; |
| 1107 | 1118 | } else { |
| 1108 | | cpustate->branch_latch = 0; |
| 1119 | cpustate->m_branch_latch = 0; |
| 1109 | 1120 | } |
| 1110 | 1121 | break; |
| 1111 | 1122 | } |
| 1112 | | cpustate->subcycle = ( cpustate->subcycle + 1 ) % 6; |
| 1113 | | } while( cpustate->icount > 0 ); |
| 1123 | cpustate->m_subcycle = ( cpustate->m_subcycle + 1 ) % 6; |
| 1124 | } while( cpustate->m_icount > 0 ); |
| 1114 | 1125 | } |
| 1115 | 1126 | |
| 1116 | 1127 | |
| r18816 | r18817 | |
| 1120 | 1131 | |
| 1121 | 1132 | switch( state ) |
| 1122 | 1133 | { |
| 1123 | | case CPUINFO_INT_PC: cpustate->pc = ( info->i >> 1 ) & 0x7f; cpustate->pa = info->i >> 8; break; |
| 1124 | | case CPUINFO_INT_REGISTER + TMS0980_PC: cpustate->pc = info->i; break; |
| 1125 | | case CPUINFO_INT_REGISTER + TMS0980_SR: cpustate->sr = info->i; break; |
| 1126 | | case CPUINFO_INT_REGISTER + TMS0980_PA: cpustate->pa = info->i; break; |
| 1127 | | case CPUINFO_INT_REGISTER + TMS0980_PB: cpustate->pb = info->i; break; |
| 1128 | | case CPUINFO_INT_REGISTER + TMS0980_A: cpustate->a = info->i; break; |
| 1129 | | case CPUINFO_INT_REGISTER + TMS0980_X: cpustate->x = info->i; break; |
| 1130 | | case CPUINFO_INT_REGISTER + TMS0980_Y: cpustate->y = info->i; break; |
| 1131 | | case CPUINFO_INT_REGISTER + TMS0980_STATUS: cpustate->status = info->i; break; |
| 1134 | case CPUINFO_INT_PC: cpustate->m_pc = ( info->i >> 1 ) & 0x7f; cpustate->m_pa = ( info->i >> 8 ) & 0x0F; cpustate->m_cb = ( info->i >> 12 ) & 0x01; break; |
| 1135 | case CPUINFO_INT_REGISTER + TMS0980_PC: cpustate->m_pc = info->i; break; |
| 1136 | case CPUINFO_INT_REGISTER + TMS0980_SR: cpustate->m_sr = info->i; break; |
| 1137 | case CPUINFO_INT_REGISTER + TMS0980_PA: cpustate->m_pa = info->i; break; |
| 1138 | case CPUINFO_INT_REGISTER + TMS0980_PB: cpustate->m_pb = info->i; break; |
| 1139 | case CPUINFO_INT_REGISTER + TMS0980_A: cpustate->m_a = info->i; break; |
| 1140 | case CPUINFO_INT_REGISTER + TMS0980_X: cpustate->m_x = info->i; break; |
| 1141 | case CPUINFO_INT_REGISTER + TMS0980_Y: cpustate->m_y = info->i; break; |
| 1142 | case CPUINFO_INT_REGISTER + TMS0980_STATUS: cpustate->m_status = info->i; break; |
| 1132 | 1143 | } |
| 1133 | 1144 | } |
| 1134 | 1145 | |
| r18816 | r18817 | |
| 1151 | 1162 | case CPUINFO_INT_DATABUS_WIDTH + AS_DATA: info->i = 8 /* 4 */; break; |
| 1152 | 1163 | case CPUINFO_INT_ADDRBUS_SHIFT + AS_DATA: info->i = 0; break; |
| 1153 | 1164 | |
| 1154 | | case CPUINFO_INT_PREVIOUSPC: info->i = ( ( cpustate->prev_pa << 7 ) | cpustate->prev_pc ) << 1; break; |
| 1155 | | case CPUINFO_INT_PC: info->i = ( ( cpustate->pa << 7 ) | cpustate->pc ) << 1; break; |
| 1165 | case CPUINFO_INT_PREVIOUSPC: info->i = ( ( cpustate->m_prev_pa << 7 ) | cpustate->m_prev_pc ) << 1; break; |
| 1166 | case CPUINFO_INT_PC: info->i = ( ( cpustate->m_pa << 7 ) | cpustate->m_pc ) << 1; break; |
| 1156 | 1167 | case CPUINFO_INT_SP: info->i = 0xFFFF; break; |
| 1157 | | case CPUINFO_INT_REGISTER + TMS0980_PC: info->i = cpustate->pc; break; |
| 1158 | | case CPUINFO_INT_REGISTER + TMS0980_SR: info->i = cpustate->sr; break; |
| 1159 | | case CPUINFO_INT_REGISTER + TMS0980_PA: info->i = cpustate->pa; break; |
| 1160 | | case CPUINFO_INT_REGISTER + TMS0980_PB: info->i = cpustate->pb; break; |
| 1161 | | case CPUINFO_INT_REGISTER + TMS0980_A: info->i = cpustate->a; break; |
| 1162 | | case CPUINFO_INT_REGISTER + TMS0980_X: info->i = cpustate->x; break; |
| 1163 | | case CPUINFO_INT_REGISTER + TMS0980_Y: info->i = cpustate->y; break; |
| 1164 | | case CPUINFO_INT_REGISTER + TMS0980_STATUS: info->i = cpustate->status; break; |
| 1168 | case CPUINFO_INT_REGISTER + TMS0980_PC: info->i = cpustate->m_pc; break; |
| 1169 | case CPUINFO_INT_REGISTER + TMS0980_SR: info->i = cpustate->m_sr; break; |
| 1170 | case CPUINFO_INT_REGISTER + TMS0980_PA: info->i = cpustate->m_pa; break; |
| 1171 | case CPUINFO_INT_REGISTER + TMS0980_PB: info->i = cpustate->m_pb; break; |
| 1172 | case CPUINFO_INT_REGISTER + TMS0980_A: info->i = cpustate->m_a; break; |
| 1173 | case CPUINFO_INT_REGISTER + TMS0980_X: info->i = cpustate->m_x; break; |
| 1174 | case CPUINFO_INT_REGISTER + TMS0980_Y: info->i = cpustate->m_y; break; |
| 1175 | case CPUINFO_INT_REGISTER + TMS0980_STATUS: info->i = cpustate->m_status; break; |
| 1165 | 1176 | |
| 1166 | 1177 | case CPUINFO_FCT_SET_INFO: info->setinfo = CPU_SET_INFO_NAME( tms0980 ); break; |
| 1167 | 1178 | case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME( tms0980 ); break; |
| 1168 | 1179 | case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME( tms0980 ); break; |
| 1169 | 1180 | case CPUINFO_FCT_EXECUTE: info->execute = CPU_EXECUTE_NAME( tms0980 ); break; |
| 1170 | | case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &cpustate->icount; break; |
| 1181 | case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &cpustate->m_icount; break; |
| 1171 | 1182 | |
| 1172 | 1183 | case CPUINFO_STR_FAMILY: strcpy( info->s, "Texas Instruments TMS0980/TMS1000" ); break; |
| 1173 | 1184 | case CPUINFO_STR_VERSION: strcpy( info->s, "0.2" ); break; |
| r18816 | r18817 | |
| 1176 | 1187 | |
| 1177 | 1188 | case CPUINFO_STR_FLAGS: strcpy( info->s, "N/A" ); break; |
| 1178 | 1189 | |
| 1179 | | case CPUINFO_STR_REGISTER + TMS0980_PC: sprintf( info->s, "PC:%02X", cpustate->pc ); break; |
| 1180 | | case CPUINFO_STR_REGISTER + TMS0980_SR: sprintf( info->s, "SR:%01X", cpustate->sr ); break; |
| 1181 | | case CPUINFO_STR_REGISTER + TMS0980_PA: sprintf( info->s, "PA:%01X", cpustate->pa ); break; |
| 1182 | | case CPUINFO_STR_REGISTER + TMS0980_PB: sprintf( info->s, "PB:%01X", cpustate->pb ); break; |
| 1183 | | case CPUINFO_STR_REGISTER + TMS0980_A: sprintf( info->s, "A:%01X", cpustate->a ); break; |
| 1184 | | case CPUINFO_STR_REGISTER + TMS0980_X: sprintf( info->s, "X:%01X", cpustate->x ); break; |
| 1185 | | case CPUINFO_STR_REGISTER + TMS0980_Y: sprintf( info->s, "Y:%01X", cpustate->y ); break; |
| 1186 | | case CPUINFO_STR_REGISTER + TMS0980_STATUS: sprintf( info->s, "STATUS:%01X", cpustate->status ); break; |
| 1190 | case CPUINFO_STR_REGISTER + TMS0980_PC: sprintf( info->s, "PC:%02X", cpustate->m_pc ); break; |
| 1191 | case CPUINFO_STR_REGISTER + TMS0980_SR: sprintf( info->s, "SR:%01X", cpustate->m_sr ); break; |
| 1192 | case CPUINFO_STR_REGISTER + TMS0980_PA: sprintf( info->s, "PA:%01X", cpustate->m_pa ); break; |
| 1193 | case CPUINFO_STR_REGISTER + TMS0980_PB: sprintf( info->s, "PB:%01X", cpustate->m_pb ); break; |
| 1194 | case CPUINFO_STR_REGISTER + TMS0980_A: sprintf( info->s, "A:%01X", cpustate->m_a ); break; |
| 1195 | case CPUINFO_STR_REGISTER + TMS0980_X: sprintf( info->s, "X:%01X", cpustate->m_x ); break; |
| 1196 | case CPUINFO_STR_REGISTER + TMS0980_Y: sprintf( info->s, "Y:%01X", cpustate->m_y ); break; |
| 1197 | case CPUINFO_STR_REGISTER + TMS0980_STATUS: sprintf( info->s, "STATUS:%01X", cpustate->m_status ); break; |
| 1187 | 1198 | |
| 1188 | 1199 | } |
| 1189 | 1200 | } |
| r18816 | r18817 | |
| 1200 | 1211 | case CPUINFO_INT_DATABUS_WIDTH + AS_PROGRAM: info->i = 16 /* 9 */; break; |
| 1201 | 1212 | case CPUINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 12; break; |
| 1202 | 1213 | case CPUINFO_INT_ADDRBUS_WIDTH + AS_DATA: info->i = 7; break; |
| 1203 | | case CPUINFO_INT_PREVIOUSPC: info->i = ( ( cpustate->prev_pa << 7 ) | cpustate->prev_pc ) << 1; break; |
| 1204 | | case CPUINFO_INT_PC: info->i = ( ( cpustate->pa << 7 ) | cpustate->pc ) << 1; break; |
| 1214 | case CPUINFO_INT_PREVIOUSPC: info->i = ( ( cpustate->m_prev_pa << 7 ) | cpustate->m_prev_pc ) << 1; break; |
| 1215 | case CPUINFO_INT_PC: info->i = ( ( cpustate->m_pa << 7 ) | cpustate->m_pc ) << 1; break; |
| 1205 | 1216 | case CPUINFO_PTR_INTERNAL_MEMORY_MAP + AS_PROGRAM: info->internal_map16 = ADDRESS_MAP_NAME( tms0980_internal_rom ); break; |
| 1206 | 1217 | case CPUINFO_PTR_INTERNAL_MEMORY_MAP + AS_DATA: info->internal_map8 = ADDRESS_MAP_NAME( tms0980_internal_ram ); break; |
| 1207 | 1218 | case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME( tms0980 ); break; |
| r18816 | r18817 | |
| 1223 | 1234 | case CPUINFO_INT_DATABUS_WIDTH + AS_PROGRAM: info->i = 8; break; |
| 1224 | 1235 | case CPUINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 10; break; |
| 1225 | 1236 | case CPUINFO_INT_ADDRBUS_WIDTH + AS_DATA: info->i = 6; break; |
| 1226 | | case CPUINFO_INT_PREVIOUSPC: info->i = ( cpustate->prev_pa << 6 ) | tms1000_pc_decode[ cpustate->prev_pc ]; break; |
| 1227 | | case CPUINFO_INT_PC: info->i = ( cpustate->pa << 6 ) | tms1000_pc_decode[ cpustate->pc ]; break; |
| 1237 | case CPUINFO_INT_PREVIOUSPC: info->i = ( cpustate->m_prev_pa << 6 ) | tms1000_pc_decode[ cpustate->m_prev_pc ]; break; |
| 1238 | case CPUINFO_INT_PC: info->i = ( cpustate->m_pa << 6 ) | tms1000_pc_decode[ cpustate->m_pc ]; break; |
| 1228 | 1239 | case CPUINFO_PTR_INTERNAL_MEMORY_MAP + AS_PROGRAM: info->internal_map8 = ADDRESS_MAP_NAME( program_10bit_8 ); break; |
| 1229 | 1240 | case CPUINFO_PTR_INTERNAL_MEMORY_MAP + AS_DATA: info->internal_map8 = ADDRESS_MAP_NAME( data_6bit ); break; |
| 1230 | 1241 | case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME( tms1000 ); break; |
| r18816 | r18817 | |
| 1280 | 1291 | case CPUINFO_INT_DATABUS_WIDTH + AS_PROGRAM: info->i = 8; break; |
| 1281 | 1292 | case CPUINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 11; break; |
| 1282 | 1293 | case CPUINFO_INT_ADDRBUS_WIDTH + AS_DATA: info->i = 7; break; |
| 1283 | | case CPUINFO_INT_PREVIOUSPC: info->i = ( cpustate->prev_pa << 6 ) | tms1000_pc_decode[ cpustate->prev_pc ]; break; |
| 1284 | | case CPUINFO_INT_PC: info->i = ( cpustate->pa << 6 ) | cpustate->pc; break; |
| 1294 | case CPUINFO_INT_PREVIOUSPC: info->i = ( cpustate->m_prev_pa << 6 ) | cpustate->m_prev_pc; break; |
| 1295 | case CPUINFO_INT_PC: info->i = ( cpustate->m_ca << 10 ) | ( cpustate->m_pa << 6 ) | cpustate->m_pc; break; |
| 1285 | 1296 | case CPUINFO_PTR_INTERNAL_MEMORY_MAP + AS_PROGRAM: info->internal_map8 = ADDRESS_MAP_NAME( program_11bit_8 ); break; |
| 1286 | 1297 | case CPUINFO_PTR_INTERNAL_MEMORY_MAP + AS_DATA: info->internal_map8 = ADDRESS_MAP_NAME( data_7bit ); break; |
| 1287 | 1298 | case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME( tms1100 ); break; |
trunk/src/mess/drivers/merlin.c
| r18816 | r18817 | |
| 1 | 1 | #include "emu.h" |
| 2 | 2 | #include "cpu/tms0980/tms0980.h" |
| 3 | #include "sound/speaker.h" |
| 3 | 4 | |
| 4 | 5 | /* Layout */ |
| 5 | 6 | #include "merlin.lh" |
| r18816 | r18817 | |
| 9 | 10 | { |
| 10 | 11 | public: |
| 11 | 12 | merlin_state(const machine_config &mconfig, device_type type, const char *tag) |
| 12 | | : driver_device(mconfig, type, tag) { } |
| 13 | : driver_device(mconfig, type, tag) |
| 14 | , m_speaker(*this, "speaker") |
| 15 | { } |
| 13 | 16 | |
| 17 | required_device<device_t> m_speaker; |
| 18 | |
| 14 | 19 | DECLARE_READ8_MEMBER(read_k); |
| 15 | 20 | DECLARE_WRITE16_MEMBER(write_o); |
| 16 | 21 | DECLARE_WRITE16_MEMBER(write_r); |
| 22 | |
| 23 | protected: |
| 24 | UINT16 m_o; |
| 25 | UINT16 m_r; |
| 17 | 26 | }; |
| 18 | 27 | |
| 19 | 28 | |
| 20 | 29 | |
| 21 | 30 | #define LOG 1 |
| 22 | 31 | |
| 32 | |
| 23 | 33 | static INPUT_PORTS_START( merlin ) |
| 34 | PORT_START("O0") |
| 35 | PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_NAME("R0") // R0 |
| 36 | PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_NAME("R4") // R4 |
| 37 | PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_NAME("R8") // R8 |
| 38 | PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_UNUSED) |
| 39 | |
| 40 | PORT_START("O1") |
| 41 | PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_NAME("R1") // R1 |
| 42 | PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_NAME("R5") // R5 |
| 43 | PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_NAME("R9") // R9 |
| 44 | PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_NAME("CT") // CT - comp turn |
| 45 | |
| 46 | PORT_START("O3") |
| 47 | PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_NAME("R2") // R2 |
| 48 | PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_NAME("R6") // R6 |
| 49 | PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_NAME("R10") // R10 |
| 50 | PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_NAME("NG") // NG - new game |
| 51 | |
| 52 | PORT_START("O2") |
| 53 | PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_NAME("R3") // R3 |
| 54 | PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_NAME("R7") // R7 |
| 55 | PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_NAME("SG") // SG - same game |
| 56 | PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_NAME("HM") // HM - hit me |
| 24 | 57 | INPUT_PORTS_END |
| 25 | 58 | |
| 26 | 59 | |
| 60 | /* |
| 61 | The keypad is a 4*4 matrix, connected like so: |
| 62 | |
| 63 | +----+ +----+ +----+ +----+ |
| 64 | K1 o---| R0 |--| R1 |--| R2 |--| R3 | |
| 65 | +----+ +----+ +----+ +----+ |
| 66 | | | | | |
| 67 | +----+ +----+ +----+ +----+ |
| 68 | K2 o---| R4 |--| R5 |--| R6 |--| R7 | |
| 69 | +----+ +----+ +----+ +----+ |
| 70 | | | | | |
| 71 | +----+ +----+ +----+ +----+ |
| 72 | K4 o---| R8 |--| R9 |--|R10 |--| SG | |
| 73 | +----+ +----+ +----+ +----+ |
| 74 | | | | | |
| 75 | | +----+ +----+ +----+ |
| 76 | K8 o------+----| CT |--| NG |--| HM | |
| 77 | | +----+ +----+ +----+ |
| 78 | | | | | |
| 79 | o o o o |
| 80 | O0 O1 O3 O2 |
| 81 | |
| 82 | SG = same game, CT = comp turn, NG = new game, HM = hit me |
| 83 | */ |
| 84 | |
| 27 | 85 | READ8_MEMBER(merlin_state::read_k) |
| 28 | 86 | { |
| 29 | | UINT8 data = 0xFF; |
| 87 | UINT8 data = 0; |
| 30 | 88 | |
| 31 | 89 | if (LOG) |
| 32 | 90 | logerror( "read_k\n" ); |
| 33 | 91 | |
| 92 | if ( m_o & 0x01 ) |
| 93 | { |
| 94 | data |= ioport("O0")->read(); |
| 95 | } |
| 96 | |
| 97 | if ( m_o & 0x02 ) |
| 98 | { |
| 99 | data |= ioport("O1")->read(); |
| 100 | } |
| 101 | |
| 102 | if ( m_o & 0x04 ) |
| 103 | { |
| 104 | data |= ioport("O2")->read(); |
| 105 | } |
| 106 | |
| 107 | if ( m_o & 0x08 ) |
| 108 | { |
| 109 | data |= ioport("O3")->read(); |
| 110 | } |
| 111 | |
| 34 | 112 | return data; |
| 35 | 113 | } |
| 36 | 114 | |
| 37 | 115 | |
| 116 | /* |
| 117 | The speaker is connected to O4 through O6. The 3 outputs are paralleled for |
| 118 | increased current driving capability. They are passed thru a 220 ohm resistor |
| 119 | and then to the speaker, which has the other side grounded. The software then |
| 120 | toggles these lines to make sounds and noises. (There is no audio generator |
| 121 | other than toggling it with a software delay between to make tones). |
| 122 | */ |
| 123 | |
| 38 | 124 | WRITE16_MEMBER(merlin_state::write_o) |
| 39 | 125 | { |
| 40 | 126 | if (LOG) |
| 41 | 127 | logerror( "write_o: write %02x\n", data ); |
| 128 | |
| 129 | m_o = data; |
| 130 | |
| 131 | speaker_level_w( m_speaker, m_o & 0x70 ); |
| 42 | 132 | } |
| 43 | 133 | |
| 44 | 134 | |
| 135 | /* |
| 136 | |
| 137 | LEDs: |
| 138 | |
| 139 | R0 |
| 140 | R1 R2 R3 |
| 141 | R4 R5 R6 |
| 142 | R7 R8 R9 |
| 143 | R10 |
| 144 | |
| 145 | When that particular R output is high, that LED is on. |
| 146 | */ |
| 147 | |
| 45 | 148 | WRITE16_MEMBER(merlin_state::write_r) |
| 46 | 149 | { |
| 47 | 150 | if (LOG) |
| 48 | 151 | logerror( "write_r: write %04x\n", data ); |
| 152 | |
| 153 | m_r = data; |
| 154 | |
| 155 | output_set_value( "led_0", BIT( m_r, 0 ) ); |
| 156 | output_set_value( "led_1", BIT( m_r, 1 ) ); |
| 157 | output_set_value( "led_2", BIT( m_r, 2 ) ); |
| 158 | output_set_value( "led_3", BIT( m_r, 3 ) ); |
| 159 | output_set_value( "led_4", BIT( m_r, 4 ) ); |
| 160 | output_set_value( "led_5", BIT( m_r, 5 ) ); |
| 161 | output_set_value( "led_6", BIT( m_r, 6 ) ); |
| 162 | output_set_value( "led_7", BIT( m_r, 7 ) ); |
| 163 | output_set_value( "led_8", BIT( m_r, 8 ) ); |
| 164 | output_set_value( "led_9", BIT( m_r, 9 ) ); |
| 165 | output_set_value( "led_10", BIT( m_r, 10 ) ); |
| 49 | 166 | } |
| 50 | 167 | |
| 51 | 168 | |
| r18816 | r18817 | |
| 53 | 170 | { |
| 54 | 171 | { |
| 55 | 172 | /* O output PLA configuration currently unknown */ |
| 56 | | { 0x01, 0x01 }, { 0x02, 0x02 }, { 0x03, 0x03 }, { 0x04, 0x04 }, |
| 57 | | { 0x05, 0x05 }, { 0x06, 0x06 }, { 0x07, 0x07 }, { 0x08, 0x08 }, |
| 58 | | { 0x09, 0x09 }, { 0x0a, 0x0a }, { 0x0b, 0x0b }, { 0x0c, 0x0c }, |
| 59 | | { 0x0d, 0x0d }, { 0x0e, 0x0e }, { 0x0f, 0x0f }, { 0x10, 0x10 }, |
| 60 | | { 0x11, 0x11 }, { 0x12, 0x12 }, { 0x13, 0x13 }, { 0x14, 0x14 } |
| 173 | 0x01, 0x10, 0x30, 0x70, 0x02, 0x12, 0x32, 0x72, |
| 174 | 0x04, 0x14, 0x34, 0x74, 0x08, 0x18, 0x38, 0x78, |
| 175 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 176 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
| 61 | 177 | }, |
| 62 | 178 | DEVCB_DRIVER_MEMBER(merlin_state, read_k), |
| 63 | 179 | DEVCB_DRIVER_MEMBER16(merlin_state, write_o), |
| r18816 | r18817 | |
| 66 | 182 | |
| 67 | 183 | |
| 68 | 184 | static MACHINE_CONFIG_START( merlin, merlin_state ) |
| 69 | | MCFG_CPU_ADD( "maincpu", TMS1100, 5000000 ) /* Clock is wrong */ |
| 185 | MCFG_CPU_ADD( "maincpu", TMS1100, 500000 ) /* Clock is wrong */ |
| 70 | 186 | MCFG_CPU_CONFIG( merlin_tms0980_config ) |
| 71 | 187 | |
| 72 | 188 | MCFG_DEFAULT_LAYOUT(layout_merlin) |
| 189 | |
| 190 | MCFG_SPEAKER_STANDARD_MONO("mono") |
| 191 | MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0) |
| 192 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) |
| 73 | 193 | MACHINE_CONFIG_END |
| 74 | 194 | |
| 195 | |
| 75 | 196 | ROM_START( merlin ) |
| 76 | 197 | ROM_REGION( 0x800, "maincpu", 0 ) |
| 77 | 198 | ROM_LOAD( "mp3404", 0x0000, 0x800, CRC(9362d9f9) SHA1(266d2a4a98cc33944a4fc7ed073ba9321bba8e05) ) |