# HG changeset patch # User Mike Pavone # Date 1357282161 28800 # Node ID 79958b95526f77391d7d83d0db2b2ba249cf1b08 # Parent 6b593ea0ed905e098ae5268081739659fec916ef Implement TRAP (untested) diff -r 6b593ea0ed90 -r 79958b95526f m68k_to_x86.c --- 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; diff -r 6b593ea0ed90 -r 79958b95526f runtime.S --- 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!"