changeset 152:79958b95526f

Implement TRAP (untested)
author Mike Pavone <pavone@retrodev.com>
date Thu, 03 Jan 2013 22:49:21 -0800
parents 6b593ea0ed90
children 42c031184e8a
files m68k_to_x86.c runtime.S
diffstat 2 files changed, 42 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/m68k_to_x86.c	Thu Jan 03 22:07:40 2013 -0800
+++ b/m68k_to_x86.c	Thu Jan 03 22:49:21 2013 -0800
@@ -41,6 +41,7 @@
 void m68k_modified_ret_addr();
 void m68k_native_addr();
 void m68k_native_addr_and_sync();
+void m68k_trap();
 void set_sr();
 void set_ccr();
 void get_sr();
@@ -2967,9 +2968,13 @@
 		dst = setcc_r(dst, CC_S, FLAG_N);
 		dst = mov_ir(dst, 0, FLAG_V, SZ_B);
 		break;
-	/*case M68K_TAS:
+	//case M68K_TAS:
 	case M68K_TRAP:
-	case M68K_TRAPV:*/
+		dst = mov_ir(dst, src_op.disp, SCRATCH2, SZ_D);
+		dst = mov_ir(dst, inst->address, SCRATCH1, SZ_D);
+		dst = jmp(dst, (uint8_t *)m68k_trap);
+		break;
+	//case M68K_TRAPV:
 	case M68K_TST:
 		dst = cycles(dst, BUS);
 		if (src_op.mode == MODE_REG_DIRECT) {
@@ -3047,7 +3052,7 @@
 			//m68k_disasm(&instbuf, disbuf);
 			//printf("%X: %s\n", instbuf.address, disbuf);
 			dst = translate_m68k(dst, &instbuf, opts);
-		} while(instbuf.op != M68K_ILLEGAL && instbuf.op != M68K_RTS && instbuf.op != M68K_RTE && !(instbuf.op == M68K_BCC && instbuf.extra.cond == COND_TRUE) && instbuf.op != M68K_JMP);
+		} while(instbuf.op != M68K_ILLEGAL && instbuf.op != M68K_TRAP && instbuf.op != M68K_RTS && instbuf.op != M68K_RTE && !(instbuf.op == M68K_BCC && instbuf.extra.cond == COND_TRUE) && instbuf.op != M68K_JMP);
 		process_deferred(opts);
 		if (opts->deferred) {
 			address = opts->deferred->address;
--- a/runtime.S	Thu Jan 03 22:07:40 2013 -0800
+++ b/runtime.S	Thu Jan 03 22:49:21 2013 -0800
@@ -57,7 +57,40 @@
 	jnb do_sync
 	ret
 	
-	.global do_sync
+	.global m68k_trap
+m68k_trap:
+	push %rdi
+	push %rcx
+	/* swap USP and SSP if not already in supervisor mode */
+	bt $5, 5(%rsi)
+	jc already_supervisor_trap
+	mov 72(%rsi), %edi
+	mov %r15d, 72(%rsi)
+	mov %edi, %r15d
+already_supervisor_trap:
+	/* save status register on stack */
+	sub $2, %r15d
+	mov %r15d, %edi
+	call get_sr
+	call m68k_write_word
+	/* update status register */
+	andb $0xF8, 5(%rsi)
+	mov 92(%rsi), %cl
+	or $0x20, %cl
+	or %cl, 5(%rsi)
+	/* save PC */
+	sub $4, %r15d
+	mov %r15d, %edi
+	pop %rcx
+	call m68k_write_long_lowfirst
+	/* 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
+	jmp *%rcx
 	
 int_dbg_msg:
 	.asciz "Executing Interrupt!"