changeset 95:dd3c680c618c

Initial work on allowing dynamic branches and code in RAM plus a small fix to effective address decoding
author Mike Pavone <pavone@retrodev.com>
date Thu, 27 Dec 2012 21:19:58 -0800
parents a668a35a3463
children f894f85cf39d
files 68kinst.c blastem.c m68k_to_x86.c m68k_to_x86.h runtime.S
diffstat 5 files changed, 44 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/68kinst.c	Thu Dec 27 18:47:33 2012 -0800
+++ b/68kinst.c	Thu Dec 27 21:19:58 2012 -0800
@@ -63,6 +63,7 @@
 			dst->params.regs.sec = ext >> 11;//includes areg/dreg bit, reg num and word/long bit
 			dst->params.regs.displacement = sign_extend8(ext&0xFF);
 #endif
+			break;
 		case 2:
 			dst->addr_mode = MODE_PC_DISPLACE;
 			ext = *(++cur);
--- a/blastem.c	Thu Dec 27 18:47:33 2012 -0800
+++ b/blastem.c	Thu Dec 27 21:19:58 2012 -0800
@@ -472,8 +472,6 @@
 		}
 	}
 	render_init(width, height);
-	size_t size = 1024 * 1024;
-	uint8_t * transbuf = alloc_code(&size);
 	
 	x86_68k_options opts;
 	m68k_context context;
@@ -490,14 +488,13 @@
 	context.mem_pointers[1] = ram;
 	uint32_t address;
 	address = cart[0x68/2] << 16 | cart[0x6A/2];
-	uint8_t * end = transbuf + size;
-	transbuf = translate_m68k_stream(transbuf, end, address, &context);
+	translate_m68k_stream(address, &context);
 	address = cart[0x70/2] << 16 | cart[0x72/2];
-	transbuf = translate_m68k_stream(transbuf, end, address, &context);
+	translate_m68k_stream(address, &context);
 	address = cart[0x78/2] << 16 | cart[0x7A/2];
-	transbuf = translate_m68k_stream(transbuf, end, address, &context);
+	translate_m68k_stream(address, &context);
 	address = cart[2] << 16 | cart[3];
-	translate_m68k_stream(transbuf, end, address, &context);
+	translate_m68k_stream(address, &context);
 	m68k_reset(&context);
 	return 0;
 }
--- a/m68k_to_x86.c	Thu Dec 27 18:47:33 2012 -0800
+++ b/m68k_to_x86.c	Thu Dec 27 21:19:58 2012 -0800
@@ -1,5 +1,6 @@
 #include "gen_x86.h"
 #include "m68k_to_x86.h"
+#include "mem.h"
 #include <stdio.h>
 #include <stddef.h>
 #include <stdlib.h>
@@ -486,9 +487,10 @@
 uint8_t * get_native_address(native_map_slot * native_code_map, uint32_t address)
 {
 	address &= 0xFFFFFF;
-	if (address > 0x400000) {
+	//if (address > 0x400000) {
 		printf("get_native_address: %X\n", address);
-	}
+	//}
+	address /= 2;
 	uint32_t chunk = address / NATIVE_CHUNK_SIZE;
 	if (!native_code_map[chunk].base) {
 		return NULL;
@@ -539,6 +541,7 @@
 void map_native_address(native_map_slot * native_code_map, uint32_t address, uint8_t * native_addr)
 {
 	address &= 0xFFFFFF;
+	address/= 2;
 	uint32_t chunk = address / NATIVE_CHUNK_SIZE;
 	if (!native_code_map[chunk].base) {
 		native_code_map[chunk].base = native_addr;
@@ -1880,15 +1883,25 @@
 	return dst;
 }
 
-uint8_t * translate_m68k_stream(uint8_t * dst, uint8_t * dst_end, uint32_t address, m68k_context * context)
+uint8_t * translate_m68k_stream(uint32_t address, m68k_context * context)
 {
 	m68kinst instbuf;
 	x86_68k_options * opts = context->options;
+	uint8_t * dst = opts->cur_code;
+	uint8_t * dst_end = opts->code_end; 
 	if(get_native_address(opts->native_code_map, address)) {
 		return dst;
 	}
 	char disbuf[1024];
-	uint16_t *encoded = context->mem_pointers[0] + address/2, *next;
+	uint16_t *encoded, *next;
+	if ((address & 0xFFFFFF) < 0x400000) {
+		encoded = context->mem_pointers[0] + (address & 0xFFFFFF)/2;
+	} else if ((address & 0xFFFFFF) > 0xE00000) {
+		encoded = context->mem_pointers[1] + (address  & 0xFFFF)/2;
+	} else {
+		printf("attempt to translate non-memory address: %X\n", address);
+		exit(1);
+	}
 	do {
 		do {
 			if (dst_end-dst < 128) {
@@ -1910,9 +1923,21 @@
 			encoded = NULL;
 		}
 	} while(encoded != NULL);
+	opts->cur_code = dst;
 	return dst;
 }
 
+uint8_t * get_native_address_trans(m68k_context * context, uint32_t address)
+{
+	address &= 0xFFFFFF;
+	uint8_t * ret = get_native_address(context->native_code_map, address);
+	if (!ret) {
+		translate_m68k_stream(address, context);
+		ret = get_native_address(context->native_code_map, address);
+	}
+	return ret;
+}
+
 void start_68k_context(m68k_context * context, uint32_t address)
 {
 	uint8_t * addr = get_native_address(context->native_code_map, address);
@@ -1941,6 +1966,9 @@
 	opts->native_code_map = malloc(sizeof(native_map_slot) * NATIVE_MAP_CHUNKS);
 	memset(opts->native_code_map, 0, sizeof(native_map_slot) * NATIVE_MAP_CHUNKS);
 	opts->deferred = NULL;
+	size_t size = 1024 * 1024;
+	opts->cur_code = alloc_code(&size);
+	opts->code_end = opts->cur_code + size;
 }
 
 void init_68k_context(m68k_context * context, native_map_slot * native_code_map, void * opts)
--- a/m68k_to_x86.h	Thu Dec 27 18:47:33 2012 -0800
+++ b/m68k_to_x86.h	Thu Dec 27 21:19:58 2012 -0800
@@ -23,7 +23,8 @@
 	int8_t          aregs[8];
 	native_map_slot *native_code_map;
 	deferred_addr   *deferred;
-	
+	uint8_t         *cur_code;
+	uint8_t         *code_end;
 } x86_68k_options;
 
 typedef struct {
@@ -46,7 +47,7 @@
 } m68k_context;
 
 uint8_t * translate_m68k(uint8_t * dst, m68kinst * inst, x86_68k_options * opts);
-uint8_t * translate_m68k_stream(uint8_t * dst, uint8_t * dst_end, uint32_t address, m68k_context * context);
+uint8_t * translate_m68k_stream(uint32_t address, m68k_context * context);
 void start_68k_context(m68k_context * context, uint32_t address);
 void init_x86_68k_opts(x86_68k_options * opts);
 void init_68k_context(m68k_context * context, native_map_slot * native_code_map, void * opts);
--- a/runtime.S	Thu Dec 27 18:47:33 2012 -0800
+++ b/runtime.S	Thu Dec 27 21:19:58 2012 -0800
@@ -413,8 +413,8 @@
 	call sync_components
 	pop %rsi
 	push %rax
-	mov 144(%rax), %rdi
-	call get_native_address
+	mov %rax, %rdi
+	call get_native_address_trans
 	mov %rax, %rcx
 	pop %rsi
 	call m68k_load_context
@@ -424,9 +424,9 @@
 m68k_native_addr:
 	call m68k_save_context
 	push %rsi
-	mov 144(%rsi), %rdi
+	mov %rsi, %rdi
 	mov %ecx, %esi
-	call get_native_address
+	call get_native_address_trans
 	mov %rax, %rcx
 	pop %rsi
 	call m68k_load_context