changeset 347:b24556b45d1e

Generate handle_cycle_limit_int at runtime so it can refer to the runtime generated memory map functions
author Mike Pavone <pavone@retrodev.com>
date Tue, 21 May 2013 00:56:56 -0700
parents aff29d50afd5
children 3923dbc2dcc4
files m68k_to_x86.c m68k_to_x86.h runtime.S
diffstat 3 files changed, 61 insertions(+), 60 deletions(-) [+]
line wrap: on
line diff
--- a/m68k_to_x86.c	Sun May 19 18:40:34 2013 -0700
+++ b/m68k_to_x86.c	Tue May 21 00:56:56 2013 -0700
@@ -23,7 +23,8 @@
 
 char disasm_buf[1024];
 
-void handle_cycle_limit_int();
+m68k_context * sync_components(m68k_context * context, uint32_t address);
+
 void handle_cycle_limit();
 void m68k_save_context();
 void m68k_load_context();
@@ -48,13 +49,13 @@
 	return dst;
 }
 
-uint8_t * check_cycles_int(uint8_t * dst, uint32_t address)
+uint8_t * check_cycles_int(uint8_t * dst, uint32_t address, x86_68k_options * opts)
 {
 	dst = cmp_rr(dst, CYCLES, LIMIT, SZ_D);
 	uint8_t * jmp_off = dst+1;
 	dst = jcc(dst, CC_NC, dst + 7);
 	dst = mov_ir(dst, address, SCRATCH1, SZ_D);
-	dst = call(dst, (uint8_t *)handle_cycle_limit_int);
+	dst = call(dst, opts->handle_cycle_limit_int);
 	*jmp_off = dst - (jmp_off+1);
 	return dst;
 }
@@ -2746,7 +2747,7 @@
 {
 	uint8_t * end_off, *zero_off, *norm_off;
 	uint8_t dst_reg;
-	dst = check_cycles_int(dst, inst->address);
+	dst = check_cycles_int(dst, inst->address, opts);
 	if (inst->op == M68K_MOVE) {
 		return translate_m68k_move(dst, inst, opts);
 	} else if(inst->op == M68K_LEA) {
@@ -4089,7 +4090,7 @@
 		native = call(native, bp_stub);
 		
 		//Calculate length of prologue
-		dst = check_cycles_int(dst, address);
+		dst = check_cycles_int(dst, address, opts);
 		int check_int_size = dst-bp_stub;
 		dst = bp_stub;
 		
@@ -4107,7 +4108,7 @@
 		dst = cmp_rr(dst, CYCLES, LIMIT, SZ_D);
 		uint8_t * jmp_off = dst+1;
 		dst = jcc(dst, CC_NC, dst + 7);
-		dst = call(dst, (uint8_t *)handle_cycle_limit_int);
+		dst = call(dst, opts->handle_cycle_limit_int);
 		*jmp_off = dst - (jmp_off+1);
 		//jump back to body of translated instruction
 		dst = pop_r(dst, SCRATCH1);
@@ -4122,7 +4123,7 @@
 void remove_breakpoint(m68k_context * context, uint32_t address)
 {
 	uint8_t * native = get_native_address(context->native_code_map, address);
-	check_cycles_int(native, address);
+	check_cycles_int(native, address, context->options);
 }
 
 void start_68k_context(m68k_context * context, uint32_t address)
@@ -4468,6 +4469,58 @@
 	dst = add_ir(dst, 2, SCRATCH2, SZ_D);
 	dst = jmp(dst, opts->write_16);
 	
+	opts->handle_cycle_limit_int = dst;
+	dst = cmp_rdisp8r(dst, CONTEXT, offsetof(m68k_context, int_cycle), CYCLES, SZ_D);
+	uint8_t * do_int = dst+1;
+	dst = jcc(dst, CC_NC, dst+2);
+	dst = cmp_rdisp8r(dst, CONTEXT, offsetof(m68k_context, sync_cycle), CYCLES, SZ_D);
+	uint8_t * skip_sync = dst+1;
+	dst = jcc(dst, CC_C, dst+2);
+	dst = call(dst, (uint8_t *)m68k_save_context);
+	dst = mov_rr(dst, CONTEXT, RDI, SZ_Q);
+	dst = mov_rr(dst, SCRATCH1, RSI, SZ_D);
+	dst = call(dst, (uint8_t *)sync_components);
+	dst = mov_rr(dst, RAX, CONTEXT, SZ_Q);
+	dst = jmp(dst, (uint8_t *)m68k_load_context);
+	*skip_sync = dst - (skip_sync+1);
+	dst = retn(dst);
+	*do_int = dst - (do_int+1);
+	//set target cycle to sync cycle
+	dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, sync_cycle), LIMIT, SZ_D);
+	//swap USP and SSP if not already in supervisor mode
+	dst = bt_irdisp8(dst, 5, CONTEXT, offsetof(m68k_context, status), SZ_B);
+	uint8_t *already_supervisor = dst+1;
+	dst = jcc(dst, CC_C, dst+2);
+	dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SCRATCH2, SZ_D);
+	dst = mov_rrdisp8(dst, opts->aregs[7], CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_D);
+	dst = mov_rr(dst, SCRATCH2, opts->aregs[7], SZ_D);
+	*already_supervisor = dst - (already_supervisor+1);
+	//save PC
+	dst = sub_ir(dst, 4, opts->aregs[7], SZ_D);
+	dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
+	dst = call(dst, opts->write_32_lowfirst);
+	//save status register
+	dst = sub_ir(dst, 2, opts->aregs[7], SZ_D);
+	dst = call(dst, (uint8_t *)get_sr);
+	dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
+	dst = call(dst, opts->write_16);
+	//update status register
+	dst = and_irdisp8(dst, 0xF8, CONTEXT, offsetof(m68k_context, status), SZ_B);
+	dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, int_num), SCRATCH1, SZ_B);
+	dst = or_ir(dst, 0x20, SCRATCH1, SZ_B);
+	dst = or_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, status), SZ_B);
+	//calculate interrupt vector address
+	dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, int_num), SCRATCH1, SZ_D);
+	dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, int_ack), SZ_W);
+	dst = shl_ir(dst, 2, SCRATCH1, SZ_D);
+	dst = add_ir(dst, 0x60, SCRATCH1, SZ_D);
+	dst = call(dst, opts->read_32);
+	dst = call(dst, (uint8_t *)m68k_native_addr_and_sync);
+	dst = cycles(dst, 24);
+	//discard function return address
+	dst = pop_r(dst, SCRATCH2);
+	dst = jmp_r(dst, SCRATCH1);
+	
 	opts->cur_code = dst;
 }
 
--- a/m68k_to_x86.h	Sun May 19 18:40:34 2013 -0700
+++ b/m68k_to_x86.h	Tue May 21 00:56:56 2013 -0700
@@ -30,6 +30,7 @@
 	uint8_t         *read_32;
 	uint8_t         *write_32_lowfirst;
 	uint8_t         *write_32_highfirst;
+	uint8_t         *handle_cycle_limit_int;
 } x86_68k_options;
 
 typedef struct {
--- a/runtime.S	Sun May 19 18:40:34 2013 -0700
+++ b/runtime.S	Tue May 21 00:56:56 2013 -0700
@@ -17,59 +17,6 @@
 	pop %rcx
 skip_sync:
 	ret
-
-	.global handle_cycle_limit_int
-handle_cycle_limit_int:
-	cmp 88(%rsi), %eax
-	jb skip_int
-	mov 84(%rsi), %ebp
-	/* swap USP and SSP if not already in supervisor mode */
-	bt $5, 5(%rsi)
-	jc already_supervisor
-	mov 72(%rsi), %edi
-	mov %r15d, 72(%rsi)
-	mov %edi, %r15d
-already_supervisor:
-	/* save PC */
-	sub $4, %r15d
-	mov %r15d, %edi
-	call m68k_write_long_lowfirst
-	/* 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)
-	/* calculate interrupt vector address */
-	mov 92(%rsi), %ecx
-	mov %cx, 6(%rsi) /* interrupt acknowlege */
-	shl $2, %ecx
-	add $0x60, %ecx
-	/* push %rcx
-	call debug_print_sr_int
-	pop %rcx */
-	call m68k_read_long_scratch1
-	call m68k_native_addr_and_sync
-	add $24, %eax
-	/* discard function return address */
-	pop %rdi
-	jmp *%rcx
-	ret
-skip_int:
-	cmp 84(%rsi), %eax
-	jb skip_sync_int
-	call m68k_save_context
-	mov %rsi, %rdi
-	mov %ecx, %esi
-	call sync_components
-	mov %rax, %rsi
-	call m68k_load_context
-skip_sync_int:
-	ret
 	
 sr_msg_int:
 	.asciz "SR set to $%X due to interrupt\n"