changeset 226:28a6697e847b

Implement CHK instruction (not fully tested).
author Mike Pavone <pavone@retrodev.com>
date Sun, 21 Apr 2013 13:00:34 -0700
parents 7348057e7a8c
children 42123feab62d
files 68kinst.h m68k_to_x86.c runtime.S
diffstat 3 files changed, 84 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/68kinst.h	Sun Apr 21 11:42:45 2013 -0700
+++ b/68kinst.h	Sun Apr 21 13:00:34 2013 -0700
@@ -182,6 +182,48 @@
 	m68k_op_info dst;
 } m68kinst;
 
+typedef enum {
+	VECTOR_RESET_STACK,
+	VECTOR_RESET_PC,
+	VECTOR_ACCESS_FAULT,
+	VECTOR_ADDRESS_ERROR,
+	VECTOR_ILLEGAL_INST,
+	VECTOR_INT_DIV_ZERO,
+	VECTOR_CHK,
+	VECTOR_TRAPV,
+	VECTOR_PRIV_VIOLATION,
+	VECTOR_TRACE,
+	VECTOR_LINE_1010,
+	VECTOR_LINE_1111,
+	VECTOR_COPROC_VIOLATION=13,
+	VECTOR_FORMAT_ERROR,
+	VECTOR_UNINIT_INTERRUPT,
+	VECTOR_SPURIOUS_INTERRUPT=24,
+	VECTOR_INT_1,
+	VECTOR_INT_2,
+	VECTOR_INT_3,
+	VECTOR_INT_4,
+	VECTOR_INT_5,
+	VECTOR_INT_6,
+	VECTOR_INT_7,
+	VECTOR_TRAP_0,
+	VECTOR_TRAP_1,
+	VECTOR_TRAP_2,
+	VECTOR_TRAP_3,
+	VECTOR_TRAP_4,
+	VECTOR_TRAP_5,
+	VECTOR_TRAP_6,
+	VECTOR_TRAP_7,
+	VECTOR_TRAP_8,
+	VECTOR_TRAP_9,
+	VECTOR_TRAP_10,
+	VECTOR_TRAP_11,
+	VECTOR_TRAP_12,
+	VECTOR_TRAP_13,
+	VECTOR_TRAP_14,
+	VECTOR_TRAP_15
+} m68k_vector;
+
 uint16_t * m68k_decode(uint16_t * istream, m68kinst * dst, uint32_t address);
 uint32_t m68k_cycles(m68kinst * inst);
 int m68k_disasm(m68kinst * decoded, char * dst);
--- a/m68k_to_x86.c	Sun Apr 21 11:42:45 2013 -0700
+++ b/m68k_to_x86.c	Sun Apr 21 13:00:34 2013 -0700
@@ -3084,8 +3084,46 @@
 			dst = m68k_save_result(inst, dst, opts);
 		}
 		break;
-	/*case M68K_CHK:
-		break;*/
+	case M68K_CHK:
+	{
+		dst = cycles(dst, 6);
+		if (dst_op.mode == MODE_REG_DIRECT) {
+			dst = cmp_ir(dst, 0, dst_op.base, inst->extra.size);
+		} else {
+			dst = cmp_irdisp8(dst, 0, dst_op.base, dst_op.disp, inst->extra.size);
+		}
+		uint8_t * passed = dst+1;			
+		dst = jcc(dst, CC_GE, dst+2);
+		dst = mov_ir(dst, 1, FLAG_N, SZ_B);
+		dst = mov_ir(dst, VECTOR_CHK, SCRATCH2, SZ_D);
+		dst = mov_ir(dst, inst->address+2, SCRATCH1, SZ_D);
+		dst = jmp(dst, (uint8_t *)m68k_trap);
+		*passed = dst - (passed+1);
+		if (dst_op.mode == MODE_REG_DIRECT) {
+			if (src_op.mode == MODE_REG_DIRECT) {
+				dst = cmp_rr(dst, src_op.base, dst_op.base, inst->extra.size);
+			} else if(src_op.mode == MODE_REG_DISPLACE8) {
+				dst = cmp_rdisp8r(dst, src_op.base, src_op.disp, dst_op.base, inst->extra.size);
+			} else {
+				dst = cmp_ir(dst, src_op.disp, dst_op.base, inst->extra.size);
+			}
+		} else if(dst_op.mode == MODE_REG_DISPLACE8) {
+			if (src_op.mode == MODE_REG_DIRECT) {
+				dst = cmp_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, inst->extra.size);
+			} else {
+				dst = cmp_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size);
+			}
+		}
+		passed = dst+1;
+		dst = jcc(dst, CC_LE, dst+2);
+		dst = mov_ir(dst, 0, FLAG_N, SZ_B);
+		dst = mov_ir(dst, VECTOR_CHK, SCRATCH2, SZ_D);
+		dst = mov_ir(dst, inst->address+2, SCRATCH1, SZ_D);
+		dst = jmp(dst, (uint8_t *)m68k_trap);
+		*passed = dst - (passed+1);
+		dst = cycles(dst, 4);
+		break;
+	}
 	case M68K_DIVS:
 	case M68K_DIVU:
 		//TODO: Trap on division by zero
@@ -3802,7 +3840,7 @@
 		break;
 	//case M68K_TAS:
 	case M68K_TRAP:
-		dst = mov_ir(dst, src_op.disp, SCRATCH2, SZ_D);
+		dst = mov_ir(dst, src_op.disp + VECTOR_TRAP_0, SCRATCH2, SZ_D);
 		dst = mov_ir(dst, inst->address+2, SCRATCH1, SZ_D);
 		dst = jmp(dst, (uint8_t *)m68k_trap);
 		break;
--- a/runtime.S	Sun Apr 21 11:42:45 2013 -0700
+++ b/runtime.S	Sun Apr 21 13:00:34 2013 -0700
@@ -91,10 +91,9 @@
 	/* calculate interrupt vector address */
 	pop %rcx
 	shl $2, %ecx
-	add $0x80, %ecx
 	call m68k_read_long_scratch1
 	call m68k_native_addr_and_sync
-	add $24, %eax
+	add $18, %eax
 	jmp *%rcx
 
 invalid_msg: