Example #1
0
File: mc6809.c Project: jedie/XRoar
static uint16_t ea_indexed(struct MC6809 *cpu) {
	unsigned ea;
	unsigned postbyte;
	uint16_t *reg;
	postbyte = byte_immediate(cpu);
	switch ((postbyte >> 5) & 3) {
		case 0: reg = &REG_X; break;
		case 1: reg = &REG_Y; break;
		case 2: reg = &REG_U; break;
		case 3: reg = &REG_S; break;
		default: return 0;
	}
	if ((postbyte & 0x80) == 0) {
		peek_byte(cpu, REG_PC);
		NVMA_CYCLE;
		return *reg + sex5(postbyte & 0x1f);
	}
	switch (postbyte & 0x0f) {
		case 0x00: ea = *reg; *reg += 1; peek_byte(cpu, REG_PC); NVMA_CYCLE; NVMA_CYCLE; break;
		case 0x01: ea = *reg; *reg += 2; peek_byte(cpu, REG_PC); NVMA_CYCLE; NVMA_CYCLE; NVMA_CYCLE; break;
		case 0x02: *reg -= 1; ea = *reg; peek_byte(cpu, REG_PC); NVMA_CYCLE; NVMA_CYCLE; break;
		case 0x03: *reg -= 2; ea = *reg; peek_byte(cpu, REG_PC); NVMA_CYCLE; NVMA_CYCLE; NVMA_CYCLE; break;
		case 0x04: ea = *reg; peek_byte(cpu, REG_PC); break;
		case 0x05: ea = *reg + sex8(RREG_B); peek_byte(cpu, REG_PC); NVMA_CYCLE; break;
		case 0x07: // illegal
		case 0x06: ea = *reg + sex8(RREG_A); peek_byte(cpu, REG_PC); NVMA_CYCLE; break;
		case 0x08: ea = byte_immediate(cpu); ea = sex8(ea) + *reg; NVMA_CYCLE; break;
		case 0x09: ea = word_immediate(cpu); ea = ea + *reg; NVMA_CYCLE; NVMA_CYCLE; NVMA_CYCLE; break;
		case 0x0a: ea = REG_PC | 0xff; break;
		case 0x0b: ea = *reg + REG_D; peek_byte(cpu, REG_PC); peek_byte(cpu, REG_PC + 1); NVMA_CYCLE; NVMA_CYCLE; NVMA_CYCLE; break;
		case 0x0c: ea = byte_immediate(cpu); ea = sex8(ea) + REG_PC; NVMA_CYCLE; break;
		case 0x0d: ea = word_immediate(cpu); ea = ea + REG_PC; peek_byte(cpu, REG_PC); NVMA_CYCLE; NVMA_CYCLE; NVMA_CYCLE; break;
		case 0x0e: ea = 0xffff; break; // illegal
		case 0x0f: ea = word_immediate(cpu); NVMA_CYCLE; break;
		default: ea = 0; break;
	}
	if (postbyte & 0x10) {
		unsigned tmp_ea = fetch_byte(cpu, ea) << 8;
		ea = tmp_ea | fetch_byte(cpu, ea + 1);
		NVMA_CYCLE;
	}
	return ea;
}
Example #2
0
void m6809_trace_byte(unsigned int byte, unsigned int pc) {
	static int ins_type = PAGE0;
	static unsigned int byte_val = 0, word_val = 0;
	static int indexed_mode = 0;
	static const char *indexed_fmt;
	static unsigned int indexed_flags;

	byte &= 0xff;
	pc &= 0xffff;

	if (bytes_count == 0) {
		instr_pc = pc;
	}

	if (bytes_count < BYTES_BUF_SIZE && state != WANT_PRINT) {
		bytes_buf[bytes_count++] = byte;
	}

	switch (state) {
		default:
		case WANT_INSTRUCTION:
			mnemonic = instructions[page][byte].mnemonic;
			ins_type = instructions[page][byte].type;
			switch (ins_type) {
				case PAGE2: case PAGE3:
					page = ins_type;
					break;
				default: case ILLEGAL: case INHERENT:
					state = WANT_PRINT;
					break;
				case IMMEDIATE: case DIRECT: case RELATIVE:
				case STACKS: case STACKU: case REGISTER:
				case INDEXED:
					state = WANT_BYTE;
					break;
				case WORD_IMMEDIATE: case EXTENDED:
				case LONG_RELATIVE:
					state = WANT_WORD1;
					break;
			}
			break;
		case WANT_IRQVEC1:
			mnemonic = irq_names[irq_vector];
			ins_type = IRQVECTOR;
			state = WANT_IRQVEC2;
			break;
		case WANT_IRQVEC2:
			state = WANT_PRINT;
			break;
		case WANT_BYTE:
			if (ins_type == INDEXED && indexed_mode == 0) {
				indexed_mode = byte;
				if ((indexed_mode & 0x80) == 0) {
					state = WANT_PRINT;
					break;
				}
				indexed_fmt = indexed_modes[byte & 0x0f].fmt;
				indexed_flags = indexed_modes[byte & 0x0f].flags;
				if (indexed_flags & INDEXED_WANT_WORD) {
					state = WANT_WORD1;
				} else if (indexed_flags & INDEXED_WANT_BYTE) {
					state = WANT_BYTE;
				} else {
					state = WANT_PRINT;
				}
			} else {
				byte_val = byte;
				state = WANT_PRINT;
			}
			break;
		case WANT_WORD1:
			word_val = byte;
			state = WANT_WORD2;
			break;
		case WANT_WORD2:
			word_val = (word_val << 8) | byte;
			state = WANT_PRINT;
			break;
		case WANT_PRINT:
			/* Now waiting for a call to m6809_trace_print() */
			return;
	}

	/* If state got set to WANT_PRINT, create the operand text */
	if (state != WANT_PRINT)
	 	return;

	operand_text[0] = '\0';
	switch (ins_type) {
		case ILLEGAL: case INHERENT:
			break;

		case IMMEDIATE:
			snprintf(operand_text, sizeof(operand_text), "#$%02x", byte_val);
			break;

		case DIRECT:
			snprintf(operand_text, sizeof(operand_text), "<$%02x", byte_val);
			break;

		case WORD_IMMEDIATE:
			snprintf(operand_text, sizeof(operand_text), "#$%04x", word_val);
			break;

		case EXTENDED:
			snprintf(operand_text, sizeof(operand_text), "$%04x", word_val);
			break;

		case STACKS: {
			int not_first = 0;
			if (byte_val & 0x01) { STACK_PRINT("CC"); }
			if (byte_val & 0x02) { STACK_PRINT("A"); }
			if (byte_val & 0x04) { STACK_PRINT("B"); }
			if (byte_val & 0x08) { STACK_PRINT("DP"); }
			if (byte_val & 0x10) { STACK_PRINT("X"); }
			if (byte_val & 0x20) { STACK_PRINT("Y"); }
			if (byte_val & 0x40) { STACK_PRINT("U"); }
			if (byte_val & 0x80) { STACK_PRINT("PC"); }
		} break;

		case STACKU: {
			int not_first = 0;
			if (byte_val & 0x01) { STACK_PRINT("CC"); }
			if (byte_val & 0x02) { STACK_PRINT("A"); }
			if (byte_val & 0x04) { STACK_PRINT("B"); }
			if (byte_val & 0x08) { STACK_PRINT("DP"); }
			if (byte_val & 0x10) { STACK_PRINT("X"); }
			if (byte_val & 0x20) { STACK_PRINT("Y"); }
			if (byte_val & 0x40) { STACK_PRINT("S"); }
			if (byte_val & 0x80) { STACK_PRINT("PC"); }
		} break;

		case REGISTER:
			snprintf(operand_text, sizeof(operand_text), "%s,%s",
					tfr_regs[(byte_val&0xf0)>>4],
					tfr_regs[byte_val&0x0f]);
			break;

		case INDEXED: {
			const char *reg = indexed_regs[(indexed_mode>>5)&3];
			const char *pre = "";
			const char *post = "";
			int value = word_val;
			if (indexed_flags & INDEXED_WANT_BYTE) value = byte_val;
			if ((indexed_mode & 0x80) == 0) {
				value = sex5(indexed_mode & 0x1f);
				snprintf(operand_text, sizeof(operand_text), "%d,%s", value, reg);
				break;
			}
			if (indexed_mode & 0x10) {
				pre = "[";
				post = "]";
			}
			if (indexed_flags & (INDEXED_WANT_WORD | INDEXED_WANT_BYTE)) {
				if (indexed_flags & INDEXED_WANT_REG) {
					snprintf(operand_text, sizeof(operand_text), indexed_fmt, pre, value, reg, post);
				} else {
					snprintf(operand_text, sizeof(operand_text), indexed_fmt, pre, value, post);
				}
			} else {
				if (indexed_flags & INDEXED_WANT_REG) {
					snprintf(operand_text, sizeof(operand_text), indexed_fmt, pre, reg, post);
				} else {
					snprintf(operand_text, sizeof(operand_text), indexed_fmt, pre, post);
				}
			}
			} break;

		case RELATIVE:
			pc += (byte_val & 0x80) ? 0xff00 : 0;
			pc += 1 + byte_val;
			pc &= 0xffff;
			snprintf(operand_text, sizeof(operand_text), "$%04x", pc);
			break;

		case LONG_RELATIVE:
			pc += 1 + word_val;
			pc &= 0xffff;
			snprintf(operand_text, sizeof(operand_text), "$%04x", pc);
			break;

		case IRQVECTOR:
			trace_print_short();
			break;

		default:
			break;
	}
	indexed_mode = 0;
	byte_val = word_val = 0;
}