diff options
author | Mike Pavone <pavone@retrodev.com> | 2013-01-03 22:49:21 -0800 |
---|---|---|
committer | Mike Pavone <pavone@retrodev.com> | 2013-01-03 22:49:21 -0800 |
commit | eae20aa44a669c6a871d89b58b1ae3fe3208c97a (patch) | |
tree | 23a1c1cdefe715f761b5c740cec6368bf8626c9a | |
parent | c245888b71b6cb8eb85af2e1e5caebc792b5c858 (diff) |
Implement TRAP (untested)
-rw-r--r-- | m68k_to_x86.c | 11 | ||||
-rw-r--r-- | runtime.S | 35 |
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; @@ -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!" |