예제 #1
0
파일: tms0980.c 프로젝트: nitrologic/emu
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;
		}
예제 #2
0
파일: tms0980.c 프로젝트: coinhelper/jsmess
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;
		}