Exemplo n.º 1
0
offs_t cop420_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer &params)
{
	uint8_t opcode = opcodes.r8(pc);
	uint8_t next_opcode = opcodes.r8(pc+1);
	uint16_t address;
	uint32_t flags = 0;
	int bytes = 1;

	if ((opcode >= 0x80 && opcode <= 0xBE) || (opcode >= 0xC0 && opcode <= 0xFE))
	{
		int page = pc >> 6;

		if (page == 2 || page == 3) //JP pages 2,3
		{
			address = (uint16_t)((pc & 0x380) | (opcode & 0x7F));
			util::stream_format(stream, "JP %03X", address);
		}
		else
		{
			if ((opcode & 0xC0) == 0xC0) //JP other pages
			{
				address = (uint16_t)((pc & 0x3C0) | (opcode & 0x3F));
				util::stream_format(stream, "JP %03X", address);
			}
			else                    //JSRP
			{
				address = (uint16_t)(0x80 | (opcode & 0x3F));
				util::stream_format(stream, "JSRP %03X", address);
				flags = STEP_OVER;
			}
		}
	}
Exemplo n.º 2
0
offs_t capricorn_disassembler::param_dr_lit(std::ostream &stream, offs_t pc, const data_buffer &opcodes)
{
	stream << "DR,=";
	// Here we assume that multi-byte instructions operate on 2 bytes because we
	// have no way of knowing how many they are (the actual number of bytes is
	// dynamically determined by the value of DRP register at run-time)
	unsigned bytes = BIT(opcodes.r8(pc), 0) ? 2 : 1;

	for (unsigned i = 1; i <= bytes; i++) {
		util::stream_format(stream, "$%02x ", opcodes.r8(pc+i));
	}

	return bytes;
}
Exemplo n.º 3
0
offs_t capricorn_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer &params)
{
	const dis_entry_t *p;
	uint8_t opcode = opcodes.r8(pc);

	for (p = dis_table; p->m_op_mask; p++) {
		if ((opcode & p->m_op_mask) == p->m_opcode) {
			offs_t res = 1 | p->m_dasm_flags | SUPPORTED;
			stream << p->m_mnemonic;
			if (p->m_has_mb) {
				stream << (BIT(opcode, 0) ? 'M' : 'B');
			}
			if (p->m_addr_mode != '\0') {
				stream << p->m_addr_mode;
			}
			if (p->m_param_fn != nullptr) {
				stream << " ";
				res += (this->*(p->m_param_fn))(stream, pc, opcodes);
			}
			return res;
		}
	}

	// Unknown opcode
	stream << "???";
	return 1 | SUPPORTED;
}
Exemplo n.º 4
0
offs_t capricorn_disassembler::param_jmp_off(std::ostream &stream, offs_t pc, const data_buffer &opcodes)
{
	uint16_t off = opcodes.r8(pc+1);
	if (BIT(off, 7)) {
		off -= 0x100;
	}
	util::stream_format(stream, "$%04x", (pc + 2 + off) & 0xffff);
	return 1;
}
Exemplo n.º 5
0
offs_t capricorn_disassembler::param_dr_id_ar(std::ostream &stream, offs_t pc, const data_buffer &opcodes)
{
	stream << "DR," << (BIT(opcodes.r8(pc), 1) ? '-' : '+') << "AR";
	return 0;
}
Exemplo n.º 6
0
offs_t capricorn_disassembler::param_arp_drp(std::ostream &stream, offs_t pc, const data_buffer &opcodes)
{
	stream << "R";
	util::stream_format(stream, "%02o", opcodes.r8(pc) & 0x3f);
	return 0;
}
Exemplo n.º 7
0
offs_t saturn_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer &params)
{
	int adr=0;

	int cont=1; // operation still not complete disassembled
	char bin[10]; int binsize=0; // protocollizing fetched nibbles
	char number[17];
	const OPCODE *level=opcs[0]; //pointer to current digit
	int op; // currently fetched nibble
	offs_t pos = pc;

	int i,c,v;

	int mnemonics_bank = m_config->get_nonstandard_mnemonics_mode() ? 1 : 0;

	while (cont)
	{
		op = opcodes.r8(pos++) & 0xf;
		level+=op;
		switch (level->sel) {
		case Illegal:
			cont=0;
			bin[binsize++]=number_2_hex[op];
			bin[binsize]=0;
			util::stream_format(stream, "???%s",bin);
			break;
		default:
			bin[binsize++]=number_2_hex[op];
			switch (level->adr) {
			case AdrNone: break;
			case AdrA:
				adr=field_adr_a[op];
				break;
			case AdrAF:
				adr=field_adr_af[op];
				break;
			case AdrB:
				adr=field_adr_b[op&7];
				break;
			default:
				cont = 0;
				bin[binsize++]=number_2_hex[op];
				bin[binsize]=0;
				util::stream_format(stream, "???%s",bin);
				break;
			}
			break;
		case Complete:
			cont=0;
			switch (level->adr==AdrNone?adr:level->adr) {
			case AdrNone:
				stream << mnemonics[level->mnemonic][mnemonics_bank];
				break;
			case Imm:
				util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], opcodes.r8(pos++));
				break;
			case ImmCount:
				util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], opcodes.r8(pos++)+1);
				break;
			case AdrImmCount:
				util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], field_2_string(adr), opcodes.r8(pos++)+1);
				break;
			case AdrCount: // mnemonics have string %s for address field
				snprintf(number,sizeof(number),"%x",opcodes.r8(pos++)+1);
				util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], number);
				break;
			case Imm2:
				v=opcodes.r8(pos++);
				v|=opcodes.r8(pos++)<<4;
				util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], v);
				break;
			case Imm4:
				v=opcodes.r8(pos++);
				v|=opcodes.r8(pos++)<<4;
				v|=opcodes.r8(pos++)<<8;
				v|=opcodes.r8(pos++)<<12;
				util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], v);
				break;
			case Imm5:
				v=opcodes.r8(pos++);
				v|=opcodes.r8(pos++)<<4;
				v|=opcodes.r8(pos++)<<8;
				v|=opcodes.r8(pos++)<<12;
				v|=opcodes.r8(pos++)<<16;
				util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], v);
				break;
			case ImmCload:
				c=i=opcodes.r8(pos++) & 0xf;
				number[i+1]=0;
				for (;i>=0; i--) number[i]=number_2_hex[opcodes.r8(pos++) & 0xf];
				util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], c+1, number);
				break;
			case Dis3:
				SATURN_PEEKOP_DIS12(v);
				c=(pc+pos-3+v)&0xfffff;
				util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], c );
				break;
			case Dis3Call:
				SATURN_PEEKOP_DIS12(v);
				c=(pc+pos+v)&0xfffff;
				util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], c );
				break;
			case Dis4:
				SATURN_PEEKOP_DIS16(v);
				c=(pc+pos-4+v)&0xfffff;
				util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], c );
				break;
			case Dis4Call:
				SATURN_PEEKOP_DIS16(v);
				c=(pc+pos+v)&0xfffff;
				util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], c );
				break;
			case Abs:
				SATURN_PEEKOP_ADR(v);
				util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], v );
				break;
			case BranchReturn:
				SATURN_PEEKOP_DIS8(v);
				if (v==0) {
					stream << mnemonics[level->mnemonic+1][mnemonics_bank];
				} else {
					c=(pc+pos-2+v)&0xfffff;
					util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], c);
				}
				break;
			case ABranchReturn:
				SATURN_PEEKOP_DIS8(v);
				if (v==0) {
					util::stream_format(stream, mnemonics[level->mnemonic+1][mnemonics_bank], A);
				} else {
					c=(pc+pos-2+v)&0xfffff;
					util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], A, c);
				}
				break;
			case xBranchReturn:
				SATURN_PEEKOP_DIS8(v);
				if (v==0) {
					util::stream_format(stream, mnemonics[level->mnemonic+1][mnemonics_bank], field_2_string(adr));
				} else {
					c=(pc+pos-2+v)&0xfffff;
					util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], field_2_string(adr), c);
				}
				break;
			case TestBranchRet:
				i=opcodes.r8(pos++);
				SATURN_PEEKOP_DIS8(v);
				if (v==0) {
					util::stream_format(stream, mnemonics[level->mnemonic+1][mnemonics_bank], i);
				} else {
					c=(pc+pos-2+v)&0xfffff;
					util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], i, c);
				}
				break;
			case ImmBranch:
				i=opcodes.r8(pos++);
				SATURN_PEEKOP_DIS8(v);
				c=(pc+pos-2+v)&0xfffff;
				util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], i, c);
				break;
			case FieldP:
				util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], P );
				break;
			case FieldWP:
				util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], WP );
				break;
			case FieldXS:
				util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], XS );
				break;
			case FieldX:
				util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], X );
				break;
			case FieldS:
				util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], S );
				break;
			case FieldM:
				util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], M );
				break;
			case FieldB:
				util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], B );
				break;
			case FieldA:
				util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], A );
				break;
			case FieldW:
				util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], W );
				break;
			case AdrA:
				util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], adr_a[opcodes.r8(pos++) & 0x7] );
				break;
			case AdrAF:
				util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], adr_af[opcodes.r8(pos++) & 0xf] );
				break;
			case AdrB:
				util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], adr_b[opcodes.r8(pos++) & 0x7] );
				break;
			}
			break;
		}
		level = opcs[level->sel];
	}

	return pos - pc;
}