#include "operand_info.hpp"

void Operand::setup(opcode::AddressingMode target,
					opcode::AddressingMode instruction, unsigned parameter) 
{
	switch (target) {
	case opcode::REG_A: case opcode::REG_X: case opcode::REG_Y:
	case opcode::REG_SP: case opcode::REG_PS: case opcode::REG_PC:
	case opcode::PS_N: case opcode::PS_Z:
	case opcode::PS_C: case opcode::PS_V:
	case opcode::PS_I: case opcode::PS_D:
	case opcode::PS_NZ: case opcode::PS_NZC:
	case opcode::PS_NVZ: case opcode::PS_NVZC: 
		type = REGISTER;
		reg = target;
		return;
	case opcode::REL:
		type = MEMORY;
		value = parameter;
	case opcode::IMM:
		type = IMMEDIATE;
		value = parameter;
		return;
	case opcode::ZERO:
	case opcode::ABS:
	case opcode::IND:
		type = MEMORY;
		value = parameter;
		return;
	case opcode::ZERO_X:
	case opcode::ABS_X:
	case opcode::PRE_IND:
		type = INDEX;
		value = parameter;
		reg = opcode::REG_X;
		return;
	case opcode::ZERO_Y:
	case opcode::ABS_Y:
	case opcode::POST_IND:
		type = INDEX;
		value = parameter;
		reg = opcode::REG_Y;
		return;
	case opcode::AM_WILD:
		setup(instruction, opcode::AM_NONE, parameter);
		return;
	default:
		return;
	}
}

const opcode::OperationInfo*
OperationInfoServer::getInfoOf(opcode::Operation type)const
{
	const opcode::OperationInfo* infos = opcode::optype_infos;
	for (unsigned i=0; i < opcode::OPERATION_NUM; ++i) {
		if (infos[i].op == type) {
			return &infos[i];
		}
	}
	return &infos[0];
}
