static CPU_EXECUTE( tms0980 ) { tms0980_state *cpustate = get_safe_token( device ); cpustate->icount = cycles; do { // debugger_instruction_hook( device, ( ( cpustate->pa << cpustate->pc_size ) | cpustate->pc ) << 1 ); cpustate->icount--; switch( cpustate->subcycle ) { case 0: /* fetch: rom address 0 */ /* execute: read ram, alu input, execute br/call, k input valid */ tms0980_set_cki_bus( device ); cpustate->ram_data = memory_read_byte_8le( cpustate->data, cpustate->ram_address ); cpustate->status = 1; cpustate->p = 0; cpustate->n = 0; cpustate->carry_in = 0; break; case 1: /* fetch: rom address 1 */ if ( cpustate->pc_size == 6 ) cpustate->rom_address = ( cpustate->pa << 6 ) | tms1000_pc_decode[ cpustate->pc ]; else cpustate->rom_address = ( cpustate->pa << 7 ) | cpustate->pc; /* execute: k input valid */ if ( cpustate->decode & MICRO_MASK ) { /* Check N inputs */ if ( cpustate->decode & ( M_15TN | M_ATN | M_CKN | M_MTN | M_NATN ) ) { cpustate->n = 0; if ( cpustate->decode & M_15TN ) { cpustate->n |= 0x0F; } if ( cpustate->decode & M_ATN ) { cpustate->n |= cpustate->a; } if ( cpustate->decode & M_CKN ) { cpustate->n |= cpustate->cki_bus; } if ( cpustate->decode & M_MTN ) { cpustate->n |= cpustate->ram_data; } if ( cpustate->decode & M_NATN ) { cpustate->n |= ( ( ~cpustate->a ) & 0x0F ); } } /* Check P inputs */ if ( cpustate->decode & ( M_CKP | M_DMTP | M_MTP | M_NDMTP | M_YTP ) ) { cpustate->p = 0; if ( cpustate->decode & M_CKP ) { cpustate->p |= cpustate->cki_bus; } if ( cpustate->decode & M_DMTP ) { cpustate->p |= cpustate->dam; } if ( cpustate->decode & M_MTP ) { cpustate->p |= cpustate->ram_data; } if ( cpustate->decode & M_NDMTP ) { cpustate->p |= ( ( ~cpustate->dam ) & 0x0F ); } if ( cpustate->decode & M_YTP ) { cpustate->p |= cpustate->y; } } /* Carry In input */ if ( cpustate->decode & M_CIN ) { cpustate->carry_in = 1; } } break; case 2: /* fetch: nothing */ /* execute: write ram */ /* perform adder logic */ cpustate->adder_result = cpustate->p + cpustate->n + cpustate->carry_in; if ( cpustate->decode & MICRO_MASK ) { if ( cpustate->decode & M_NE ) { if ( cpustate->n == cpustate->p ) { cpustate->status = 0; } } if ( cpustate->decode & M_C8 ) { cpustate->status = cpustate->adder_result >> 4; } if ( cpustate->decode & M_STO ) { memory_write_byte_8le( cpustate->data, cpustate->ram_address, cpustate->a ); } if ( cpustate->decode & M_CKM ) { memory_write_byte_8le( cpustate->data, cpustate->ram_address, cpustate->cki_bus ); } } else { if ( cpustate->decode & F_SBIT ) { memory_write_byte_8le( cpustate->data, cpustate->ram_address, cpustate->ram_data | tms0980_bit_value[ cpustate->opcode & 0x03 ] ); } if ( cpustate->decode & F_RBIT ) { memory_write_byte_8le( cpustate->data, cpustate->ram_address, cpustate->ram_data & tms0980_nbit_value[ cpustate->opcode & 0x03 ] ); } if ( cpustate->decode & F_SETR ) { cpustate->r = cpustate->r | ( 1 << cpustate->y ); if ( cpustate->config->write_r ) { cpustate->config->write_r( device, 0, cpustate->r & cpustate->r_mask, 0xffff ); } } if ( cpustate->decode & F_RSTR ) { cpustate->r = cpustate->r & ( ~( 1 << cpustate->y ) ); if ( cpustate->config->write_r ) { cpustate->config->write_r( device, 0, cpustate->r & cpustate->r_mask, 0xffff ); } } if ( cpustate->decode & F_TDO ) { int i = 0; /* Calculate O-outputs based on status latch, A, and the output PLA configuration */ cpustate->o = 0; for ( i = 0; i < 20; i++ ) { if ( ( ( cpustate->status_latch << 4 ) | cpustate->a ) == cpustate->config->o_pla[i].value ) { cpustate->o = cpustate->config->o_pla[i].output; } } if ( cpustate->config->write_o ) { cpustate->config->write_o( device, 0, cpustate->o & cpustate->o_mask, 0xffff ); } } if ( cpustate->decode & F_CLO ) { cpustate->o = 0; if ( cpustate->config->write_o ) { cpustate->config->write_o( device, 0, cpustate->o & cpustate->o_mask, 0xffff ); } } if ( cpustate->decode & F_LDX ) { cpustate->x = tms0980_c2_value[ cpustate->opcode & 0x03 ]; } if ( cpustate->decode & F_COMX ) { cpustate->x = cpustate->x ^ 0x03; } if ( cpustate->decode & F_COMC ) { cpustate->cb = cpustate->cb ^ 0x01; } if ( cpustate->decode & F_LDP ) { cpustate->pb = tms0980_c4_value[ cpustate->opcode & 0x0F ]; } if ( cpustate->decode & F_REAC ) { cpustate->special_status = 0; } if ( cpustate->decode & F_SEAC ) { cpustate->special_status = 1; } if ( cpustate->decode == F_SAL ) { cpustate->add_latch = 1; } if ( cpustate->decode == F_SBL ) { cpustate->branch_latch = 1; } } break; case 3: /* fetch: fetch, update pc, ram address */ /* execute: register store */ break; case 4: /* execute: register store */ if ( cpustate->decode & MICRO_MASK ) { if ( cpustate->decode & M_AUTA ) { cpustate->a = cpustate->adder_result & 0x0F; } if ( cpustate->decode & M_AUTY ) { cpustate->y = cpustate->adder_result & 0x0F; } if ( cpustate->decode & M_STSL ) { cpustate->status_latch = cpustate->status; } } /* fetch: fetch, update pc, ram address */ if ( cpustate->byte_size > 8 ) { debugger_instruction_hook( device, cpustate->rom_address << 1 ); cpustate->opcode = memory_read_word_16be( cpustate->program, cpustate->rom_address << 1 ) & 0x1FF; } else { debugger_instruction_hook( device, cpustate->rom_address ); cpustate->opcode = memory_read_word_8le( cpustate->program, cpustate->rom_address ) & 0xFF; } tms0980_next_pc( cpustate ); if (LOG) logerror( "tms0980: read opcode %04x from %04x. Set pc to %04x\n", cpustate->opcode, cpustate->rom_address, cpustate->pc ); /* ram address */ cpustate->ram_address = ( cpustate->x << 4 ) | cpustate->y; break; case 5: /* fetch: instruction decode */ cpustate->decode = cpustate->decode_table[ cpustate->opcode ]; /* execute: execute br/call */ if ( cpustate->status ) { if ( cpustate->decode == F_BR ) { if ( cpustate->call_latch == 0 ) { cpustate->pa = cpustate->pb; } cpustate->pc = cpustate->opcode & ( ( 1 << cpustate->pc_size ) - 1 ); } if ( cpustate->decode == F_CALL ) { UINT8 t = cpustate->pa; if ( cpustate->call_latch == 0 ) { cpustate->sr = cpustate->pc; cpustate->call_latch = 1; cpustate->pa = cpustate->pb; } cpustate->pb = t; cpustate->pc = cpustate->opcode & ( ( 1 << cpustate->pc_size ) - 1 ); } } if ( cpustate->decode == F_RETN ) { if ( cpustate->call_latch == 1 ) { cpustate->pc = cpustate->sr; cpustate->call_latch = 0; } cpustate->add_latch = 0; cpustate->pa = cpustate->pb; } else { cpustate->branch_latch = 0; } break; }
static CPU_EXECUTE( tms0980 ) { tms0980_state *cpustate = get_safe_token( device ); do { // debugger_instruction_hook( device, ( ( cpustate->m_pa << cpustate->m_pc_size ) | cpustate->m_pc ) << 1 ); cpustate->m_icount--; switch( cpustate->m_subcycle ) { case 0: /* fetch: rom address 0 */ /* execute: read ram, alu input, execute br/call, k input valid */ tms0980_set_cki_bus( device ); cpustate->m_ram_data = cpustate->m_data->read_byte( cpustate->m_ram_address ); cpustate->m_status = 1; cpustate->m_p = 0; cpustate->m_n = 0; cpustate->m_carry_in = 0; break; case 1: /* fetch: rom address 1 */ cpustate->m_rom_address = ( cpustate->m_ca << ( cpustate->m_pc_size + 4 ) ) | ( cpustate->m_pa << cpustate->m_pc_size ) | cpustate->m_pc; /* execute: k input valid */ if ( cpustate->m_decode & MICRO_MASK ) { /* Check N inputs */ if ( cpustate->m_decode & ( M_15TN | M_ATN | M_CKN | M_MTN | M_NATN ) ) { cpustate->m_n = 0; if ( cpustate->m_decode & M_15TN ) { cpustate->m_n |= 0x0F; } if ( cpustate->m_decode & M_ATN ) { cpustate->m_n |= cpustate->m_a; } if ( cpustate->m_decode & M_CKN ) { cpustate->m_n |= cpustate->m_cki_bus; } if ( cpustate->m_decode & M_MTN ) { cpustate->m_n |= cpustate->m_ram_data; } if ( cpustate->m_decode & M_NATN ) { cpustate->m_n |= ( ( ~cpustate->m_a ) & 0x0F ); } } /* Check P inputs */ if ( cpustate->m_decode & ( M_CKP | M_DMTP | M_MTP | M_NDMTP | M_YTP ) ) { cpustate->m_p = 0; if ( cpustate->m_decode & M_CKP ) { cpustate->m_p |= cpustate->m_cki_bus; } if ( cpustate->m_decode & M_DMTP ) { cpustate->m_p |= cpustate->m_dam; } if ( cpustate->m_decode & M_MTP ) { cpustate->m_p |= cpustate->m_ram_data; } if ( cpustate->m_decode & M_NDMTP ) { cpustate->m_p |= ( ( ~cpustate->m_dam ) & 0x0F ); } if ( cpustate->m_decode & M_YTP ) { cpustate->m_p |= cpustate->m_y; } } /* Carry In input */ if ( cpustate->m_decode & M_CIN ) { cpustate->m_carry_in = 1; } } break; case 2: /* fetch: nothing */ /* execute: write ram */ /* perform adder logic */ cpustate->m_adder_result = cpustate->m_p + cpustate->m_n + cpustate->m_carry_in; if ( cpustate->m_decode & MICRO_MASK ) { if ( cpustate->m_decode & M_NE ) { if ( cpustate->m_n == cpustate->m_p ) { cpustate->m_status = 0; } } if ( cpustate->m_decode & M_C8 ) { cpustate->m_status = cpustate->m_adder_result >> 4; } if ( cpustate->m_decode & M_STO ) { //printf("write ram %02x data %01x\n", cpustate->m_ram_address, cpustate->m_a ); cpustate->m_data->write_byte( cpustate->m_ram_address, cpustate->m_a ); } if ( cpustate->m_decode & M_CKM ) { //printf("write ram %02x data %01x\n", cpustate->m_ram_address, cpustate->m_cki_bus ); cpustate->m_data->write_byte( cpustate->m_ram_address, cpustate->m_cki_bus ); } } else { if ( cpustate->m_decode & F_SBIT ) { //printf("write ram %02x data %01x\n", cpustate->m_ram_address, cpustate->m_ram_data | tms0980_bit_value[ cpustate->m_opcode & 0x03 ] ); cpustate->m_data->write_byte( cpustate->m_ram_address, cpustate->m_ram_data | tms0980_bit_value[ cpustate->m_opcode & 0x03 ] ); } if ( cpustate->m_decode & F_RBIT ) { //printf("write ram %02x data %01x\n", cpustate->m_ram_address, cpustate->m_ram_data & tms0980_nbit_value[ cpustate->m_opcode & 0x03 ] ); cpustate->m_data->write_byte( cpustate->m_ram_address, cpustate->m_ram_data & tms0980_nbit_value[ cpustate->m_opcode & 0x03 ] ); } if ( cpustate->m_decode & F_SETR ) { cpustate->m_r = cpustate->m_r | ( 1 << cpustate->m_y ); if ( !cpustate->m_write_r.isnull() ) { cpustate->m_write_r( 0, cpustate->m_r & cpustate->m_r_mask, 0xffff ); } } if ( cpustate->m_decode & F_RSTR ) { cpustate->m_r = cpustate->m_r & ( ~( 1 << cpustate->m_y ) ); if ( !cpustate->m_write_r.isnull() ) { cpustate->m_write_r( 0, cpustate->m_r & cpustate->m_r_mask, 0xffff ); } } if ( cpustate->m_decode & F_TDO ) { /* Calculate O-outputs based on status latch, A, and the output PLA configuration */ //printf("o output m_status_latch = %X, m_a = %X\n", cpustate->m_status_latch, cpustate->m_a); cpustate->m_o = cpustate->config->o_pla[ ( cpustate->m_status_latch << 4 ) | cpustate->m_a ]; //if ( cpustate->m_o == 0 ) //printf("****** o output m_status_latch = %X, m_a = %X\n", cpustate->m_status_latch, cpustate->m_a); //else //printf("o output m_status_latch = %X, m_a = %X\n", cpustate->m_status_latch, cpustate->m_a); if ( !cpustate->m_write_o.isnull() ) { cpustate->m_write_o( 0, cpustate->m_o & cpustate->m_o_mask, 0xffff ); } } if ( cpustate->m_decode & F_CLO ) { cpustate->m_o = 0; if ( !cpustate->m_write_o.isnull() ) { cpustate->m_write_o( 0, cpustate->m_o & cpustate->m_o_mask, 0xffff ); } } if ( cpustate->m_decode & F_LDX ) { switch( cpustate->m_x_bits ) { case 2: cpustate->m_x = tms0980_c2_value[ cpustate->m_opcode & 0x03 ]; break; case 3: cpustate->m_x = tms0980_c3_value[ cpustate->m_opcode & 0x07 ]; break; case 4: cpustate->m_x = tms0980_c4_value[ cpustate->m_opcode & 0x0f ]; break; } } if ( cpustate->m_decode & F_COMX ) { switch ( cpustate->m_x_bits ) { case 2: cpustate->m_x = cpustate->m_x ^ 0x03; break; case 3: cpustate->m_x = cpustate->m_x ^ 0x07; break; case 4: cpustate->m_x = cpustate->m_x ^ 0x0f; break; } } if ( cpustate->m_decode & F_COMC ) { cpustate->m_cb = cpustate->m_cb ^ 0x01; } if ( cpustate->m_decode & F_LDP ) { cpustate->m_pb = tms0980_c4_value[ cpustate->m_opcode & 0x0F ]; } if ( cpustate->m_decode & F_REAC ) { cpustate->m_special_status = 0; } if ( cpustate->m_decode & F_SEAC ) { cpustate->m_special_status = 1; } if ( cpustate->m_decode == F_SAL ) { cpustate->m_add_latch = 1; } if ( cpustate->m_decode == F_SBL ) { cpustate->m_branch_latch = 1; } } break; case 3: /* fetch: fetch, update pc, ram address */ /* execute: register store */ break; case 4: /* execute: register store */ if ( cpustate->m_decode & MICRO_MASK ) { if ( cpustate->m_decode & M_AUTA ) { cpustate->m_a = cpustate->m_adder_result & 0x0F; } if ( cpustate->m_decode & M_AUTY ) { cpustate->m_y = cpustate->m_adder_result & 0x0F; } if ( cpustate->m_decode & M_STSL ) { cpustate->m_status_latch = cpustate->m_status; } } /* fetch: fetch, update pc, ram address */ if ( cpustate->m_byte_size > 8 ) { debugger_instruction_hook( device, cpustate->m_rom_address << 1 ); cpustate->m_opcode = cpustate->m_program->read_word( cpustate->m_rom_address << 1 ) & 0x1FF; } else { debugger_instruction_hook( device, cpustate->m_rom_address ); cpustate->m_opcode = cpustate->m_program->read_byte( cpustate->m_rom_address ); } tms0980_next_pc( cpustate ); if (LOG) logerror( "tms0980: read opcode %04x from %04x. Set pc to %04x\n", cpustate->m_opcode, cpustate->m_rom_address, cpustate->m_pc ); /* ram address */ cpustate->m_ram_address = ( cpustate->m_x << 4 ) | cpustate->m_y; break; case 5: /* fetch: instruction decode */ cpustate->m_decode = cpustate->m_decode_table[ cpustate->m_opcode ]; /* execute: execute br/call */ if ( cpustate->m_status ) { if ( cpustate->m_decode == F_BR ) { cpustate->m_ca = cpustate->m_cb; if ( cpustate->m_call_latch == 0 ) { cpustate->m_pa = cpustate->m_pb; } cpustate->m_pc = cpustate->m_opcode & ( ( 1 << cpustate->m_pc_size ) - 1 ); } if ( cpustate->m_decode == F_CALL ) { UINT8 t = cpustate->m_pa; if ( cpustate->m_call_latch == 0 ) { cpustate->m_sr = cpustate->m_pc; cpustate->m_call_latch = 1; cpustate->m_pa = cpustate->m_pb; cpustate->m_cs = cpustate->m_ca; } cpustate->m_ca = cpustate->m_cb; cpustate->m_pb = t; cpustate->m_pc = cpustate->m_opcode & ( ( 1 << cpustate->m_pc_size ) - 1 ); } } if ( cpustate->m_decode == F_RETN ) { if ( cpustate->m_call_latch == 1 ) { cpustate->m_pc = cpustate->m_sr; cpustate->m_call_latch = 0; cpustate->m_ca = cpustate->m_cs; } cpustate->m_add_latch = 0; cpustate->m_pa = cpustate->m_pb; } else { cpustate->m_branch_latch = 0; } break; }