summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--m68k_to_x86.c11
-rw-r--r--runtime.S35
2 files changed, 42 insertions, 4 deletions
diff --git a/m68k_to_x86.c b/m68k_to_x86.c
index 3481867..5ca76db 100644
--- a/m68k_to_x86.c
+++ b/m68k_to_x86.c
@@ -41,6 +41,7 @@ void m68k_save_context();
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 @@ uint8_t * translate_m68k(uint8_t * dst, m68kinst * inst, x86_68k_options * opts)
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 @@ uint8_t * translate_m68k_stream(uint32_t address, m68k_context * context)
//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;
diff --git a/runtime.S b/runtime.S
index 65e64be..fc3a90e 100644
--- a/runtime.S
+++ b/runtime.S
@@ -57,7 +57,40 @@ skip_int:
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!"