summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile12
-rw-r--r--blastem.c2
-rw-r--r--gen.h2
-rw-r--r--gen_x86.h2
-rw-r--r--m68k_core.c280
-rw-r--r--m68k_core.h2
-rw-r--r--m68k_core_x86.c (renamed from m68k_to_x86.c)271
-rw-r--r--m68k_internal.h28
-rw-r--r--trans.c2
9 files changed, 327 insertions, 274 deletions
diff --git a/Makefile b/Makefile
index b90e432..f26dbe8 100644
--- a/Makefile
+++ b/Makefile
@@ -5,9 +5,9 @@ LIBS=sdl glew gl
endif
LDFLAGS:=-lm $(shell pkg-config --libs $(LIBS))
ifdef DEBUG
-CFLAGS:=-ggdb -std=gnu99 $(shell pkg-config --cflags-only-I $(LIBS)) -Wreturn-type -Werror=return-type
+CFLAGS:=-ggdb -std=gnu99 $(shell pkg-config --cflags-only-I $(LIBS)) -Wreturn-type -Werror=return-type -Werror=implicit-function-declaration
else
-CFLAGS:=-O2 -std=gnu99 $(shell pkg-config --cflags-only-I $(LIBS)) -Wreturn-type -Werror=return-type
+CFLAGS:=-O2 -std=gnu99 $(shell pkg-config --cflags-only-I $(LIBS)) -Wreturn-type -Werror=return-type -Werror=implicit-function-declaration
endif
ifdef PROFILE
@@ -25,13 +25,13 @@ endif
TRANSOBJS=gen.o backend.o mem.o
-M68KOBJS=68kinst.o m68k_to_x86.o
+M68KOBJS=68kinst.o m68k_core.o
ifeq ($(CPU),x86_64)
-M68KOBJS+= runtime.o
+M68KOBJS+= runtime.o m68k_core_x86.o
TRANSOBJS+= gen_x86.o backend_x86.o
else
ifeq ($(CPU),i686)
-M68KOBJS+= runtime_32.o
+M68KOBJS+= runtime_32.o m68k_core_x86.o
TRANSOBJS+= gen_x86.o backend_x86.o
NOZ80:=1
endif
@@ -102,7 +102,7 @@ test_arm : test_arm.o gen_arm.o mem.o gen.o
gen_fib : gen_fib.o gen_x86.o mem.o
$(CC) -o gen_fib gen_fib.o gen_x86.o mem.o
-offsets : offsets.c z80_to_x86.h m68k_to_x86.h
+offsets : offsets.c z80_to_x86.h m68k_core.h
$(CC) -o offsets offsets.c
%.o : %.S
diff --git a/blastem.c b/blastem.c
index 78ee5f0..7d31540 100644
--- a/blastem.c
+++ b/blastem.c
@@ -963,7 +963,7 @@ void init_run_cpu(genesis_context * gen, FILE * address_log, char * statefile, u
}
atexit(save_sram);
}
- init_x86_68k_opts(&opts, memmap, num_chunks);
+ init_m68k_opts(&opts, memmap, num_chunks);
opts.address_log = address_log;
init_68k_context(&context, opts.gen.native_code_map, &opts);
diff --git a/gen.h b/gen.h
index cd6933e..a2d835c 100644
--- a/gen.h
+++ b/gen.h
@@ -18,5 +18,7 @@ typedef struct {
} code_info;
void init_code_info(code_info *code);
+void call(code_info *code, code_ptr fun);
+void jmp(code_info *code, code_ptr dest);
#endif //GEN_H_
diff --git a/gen_x86.h b/gen_x86.h
index a55a8d7..20fb908 100644
--- a/gen_x86.h
+++ b/gen_x86.h
@@ -207,9 +207,7 @@ void btc_rrdisp(code_info *code, uint8_t src, uint8_t dst_base, int32_t dst_disp
void btc_ir(code_info *code, uint8_t val, uint8_t dst, uint8_t size);
void btc_irdisp(code_info *code, uint8_t val, uint8_t dst_base, int32_t dst_disp, uint8_t size);
void jcc(code_info *code, uint8_t cc, code_ptr dest);
-void jmp(code_info *code, code_ptr dest);
void jmp_r(code_info *code, uint8_t dst);
-void call(code_info *code, code_ptr fun);
void call_r(code_info *code, uint8_t dst);
void retn(code_info *code);
void cdq(code_info *code);
diff --git a/m68k_core.c b/m68k_core.c
new file mode 100644
index 0000000..e8038f1
--- /dev/null
+++ b/m68k_core.c
@@ -0,0 +1,280 @@
+/*
+ Copyright 2014 Michael Pavone
+ This file is part of BlastEm.
+ BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text.
+*/
+#include "m68k_core.h"
+#include "m68k_internal.h"
+#include "68kinst.h"
+#include "backend.h"
+#include "gen.h"
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+int8_t native_reg(m68k_op_info * op, m68k_options * opts)
+{
+ if (op->addr_mode == MODE_REG) {
+ return opts->dregs[op->params.regs.pri];
+ }
+ if (op->addr_mode == MODE_AREG) {
+ return opts->aregs[op->params.regs.pri];
+ }
+ return -1;
+}
+
+//must be called with an m68k_op_info that uses a register
+size_t reg_offset(m68k_op_info *op)
+{
+ if (op->addr_mode == MODE_REG) {
+ return offsetof(m68k_context, dregs) + sizeof(uint32_t) * op->params.regs.pri;
+ }
+ return offsetof(m68k_context, aregs) + sizeof(uint32_t) * op->params.regs.pri;
+}
+
+void print_regs_exit(m68k_context * context)
+{
+ printf("XNZVC\n%d%d%d%d%d\n", context->flags[0], context->flags[1], context->flags[2], context->flags[3], context->flags[4]);
+ for (int i = 0; i < 8; i++) {
+ printf("d%d: %X\n", i, context->dregs[i]);
+ }
+ for (int i = 0; i < 8; i++) {
+ printf("a%d: %X\n", i, context->aregs[i]);
+ }
+ exit(0);
+}
+
+void m68k_read_size(m68k_options *opts, uint8_t size)
+{
+ switch (size)
+ {
+ case OPSIZE_BYTE:
+ call(&opts->gen.code, opts->read_8);
+ break;
+ case OPSIZE_WORD:
+ call(&opts->gen.code, opts->read_16);
+ break;
+ case OPSIZE_LONG:
+ call(&opts->gen.code, opts->read_32);
+ break;
+ }
+}
+
+void m68k_write_size(m68k_options *opts, uint8_t size)
+{
+ switch (size)
+ {
+ case OPSIZE_BYTE:
+ call(&opts->gen.code, opts->write_8);
+ break;
+ case OPSIZE_WORD:
+ call(&opts->gen.code, opts->write_16);
+ break;
+ case OPSIZE_LONG:
+ call(&opts->gen.code, opts->write_32_highfirst);
+ break;
+ }
+}
+
+code_ptr get_native_address(native_map_slot * native_code_map, uint32_t address)
+{
+ address &= 0xFFFFFF;
+ address /= 2;
+ uint32_t chunk = address / NATIVE_CHUNK_SIZE;
+ if (!native_code_map[chunk].base) {
+ return NULL;
+ }
+ uint32_t offset = address % NATIVE_CHUNK_SIZE;
+ if (native_code_map[chunk].offsets[offset] == INVALID_OFFSET || native_code_map[chunk].offsets[offset] == EXTENSION_WORD) {
+ return NULL;
+ }
+ return native_code_map[chunk].base + native_code_map[chunk].offsets[offset];
+}
+
+code_ptr get_native_from_context(m68k_context * context, uint32_t address)
+{
+ return get_native_address(context->native_code_map, address);
+}
+
+uint32_t get_instruction_start(native_map_slot * native_code_map, uint32_t address)
+{
+ address &= 0xFFFFFF;
+ address /= 2;
+ uint32_t chunk = address / NATIVE_CHUNK_SIZE;
+ if (!native_code_map[chunk].base) {
+ return 0;
+ }
+ uint32_t offset = address % NATIVE_CHUNK_SIZE;
+ if (native_code_map[chunk].offsets[offset] == INVALID_OFFSET) {
+ return 0;
+ }
+ while (native_code_map[chunk].offsets[offset] == EXTENSION_WORD) {
+ --address;
+ chunk = address / NATIVE_CHUNK_SIZE;
+ offset = address % NATIVE_CHUNK_SIZE;
+ }
+ return address*2;
+}
+
+void map_native_address(m68k_context * context, uint32_t address, code_ptr native_addr, uint8_t size, uint8_t native_size)
+{
+ native_map_slot * native_code_map = context->native_code_map;
+ m68k_options * opts = context->options;
+ address &= 0xFFFFFF;
+ if (address > 0xE00000) {
+ context->ram_code_flags[(address & 0xC000) >> 14] |= 1 << ((address & 0x3800) >> 11);
+ if (((address & 0x3FFF) + size) & 0xC000) {
+ context->ram_code_flags[((address+size) & 0xC000) >> 14] |= 1 << (((address+size) & 0x3800) >> 11);
+ }
+ uint32_t slot = (address & 0xFFFF)/1024;
+ if (!opts->gen.ram_inst_sizes[slot]) {
+ opts->gen.ram_inst_sizes[slot] = malloc(sizeof(uint8_t) * 512);
+ }
+ opts->gen.ram_inst_sizes[slot][((address & 0xFFFF)/2)%512] = native_size;
+ }
+ address/= 2;
+ uint32_t chunk = address / NATIVE_CHUNK_SIZE;
+ if (!native_code_map[chunk].base) {
+ native_code_map[chunk].base = native_addr;
+ native_code_map[chunk].offsets = malloc(sizeof(int32_t) * NATIVE_CHUNK_SIZE);
+ memset(native_code_map[chunk].offsets, 0xFF, sizeof(int32_t) * NATIVE_CHUNK_SIZE);
+ }
+ uint32_t offset = address % NATIVE_CHUNK_SIZE;
+ native_code_map[chunk].offsets[offset] = native_addr-native_code_map[chunk].base;
+ for(address++,size-=2; size; address++,size-=2) {
+ chunk = address / NATIVE_CHUNK_SIZE;
+ offset = address % NATIVE_CHUNK_SIZE;
+ if (!native_code_map[chunk].base) {
+ native_code_map[chunk].base = native_addr;
+ native_code_map[chunk].offsets = malloc(sizeof(int32_t) * NATIVE_CHUNK_SIZE);
+ memset(native_code_map[chunk].offsets, 0xFF, sizeof(int32_t) * NATIVE_CHUNK_SIZE);
+ }
+ native_code_map[chunk].offsets[offset] = EXTENSION_WORD;
+ }
+}
+
+uint8_t get_native_inst_size(m68k_options * opts, uint32_t address)
+{
+ if (address < 0xE00000) {
+ return 0;
+ }
+ uint32_t slot = (address & 0xFFFF)/1024;
+ return opts->gen.ram_inst_sizes[slot][((address & 0xFFFF)/2)%512];
+}
+
+uint8_t m68k_is_terminal(m68kinst * inst)
+{
+ return inst->op == M68K_RTS || inst->op == M68K_RTE || inst->op == M68K_RTR || inst->op == M68K_JMP
+ || inst->op == M68K_TRAP || inst->op == M68K_ILLEGAL || inst->op == M68K_INVALID || inst->op == M68K_RESET
+ || (inst->op == M68K_BCC && inst->extra.cond == COND_TRUE);
+}
+
+void m68k_handle_deferred(m68k_context * context)
+{
+ m68k_options * opts = context->options;
+ process_deferred(&opts->gen.deferred, context, (native_addr_func)get_native_from_context);
+ if (opts->gen.deferred) {
+ translate_m68k_stream(opts->gen.deferred->address, context);
+ }
+}
+
+void translate_m68k_stream(uint32_t address, m68k_context * context)
+{
+ m68kinst instbuf;
+ m68k_options * opts = context->options;
+ code_info *code = &opts->gen.code;
+ address &= 0xFFFFFF;
+ if(get_native_address(opts->gen.native_code_map, address)) {
+ return;
+ }
+ char disbuf[1024];
+ 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 {
+ if (opts->address_log) {
+ fprintf(opts->address_log, "%X\n", address);
+ }
+ do {
+ if (address >= 0x400000 && address < 0xE00000) {
+ translate_out_of_bounds(code);
+ break;
+ }
+ code_ptr existing = get_native_address(opts->gen.native_code_map, address);
+ if (existing) {
+ jmp(code, existing);
+ break;
+ }
+ next = m68k_decode(encoded, &instbuf, address);
+ if (instbuf.op == M68K_INVALID) {
+ instbuf.src.params.immed = *encoded;
+ }
+ uint16_t m68k_size = (next-encoded)*2;
+ address += m68k_size;
+ encoded = next;
+ //m68k_disasm(&instbuf, disbuf);
+ //printf("%X: %s\n", instbuf.address, disbuf);
+
+ //make sure the beginning of the code for an instruction is contiguous
+ check_code_prologue(code);
+ code_ptr start = code->cur;
+ translate_m68k(opts, &instbuf);
+ code_ptr after = code->cur;
+ map_native_address(context, instbuf.address, start, m68k_size, after-start);
+ } while(!m68k_is_terminal(&instbuf));
+ process_deferred(&opts->gen.deferred, context, (native_addr_func)get_native_from_context);
+ if (opts->gen.deferred) {
+ address = opts->gen.deferred->address;
+ 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);
+ }
+ } else {
+ encoded = NULL;
+ }
+ } while(encoded != NULL);
+}
+
+code_ptr get_native_address_trans(m68k_context * context, uint32_t address)
+{
+ address &= 0xFFFFFF;
+ code_ptr 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 remove_breakpoint(m68k_context * context, uint32_t address)
+{
+ code_ptr native = get_native_address(context->native_code_map, address);
+ check_cycles_int(context->options, address);
+}
+
+void start_68k_context(m68k_context * context, uint32_t address)
+{
+ code_ptr addr = get_native_address_trans(context, address);
+ m68k_options * options = context->options;
+ options->start_context(addr, context);
+}
+
+void m68k_reset(m68k_context * context)
+{
+ //TODO: Make this actually use the normal read functions
+ context->aregs[7] = context->mem_pointers[0][0] << 16 | context->mem_pointers[0][1];
+ uint32_t address = context->mem_pointers[0][2] << 16 | context->mem_pointers[0][3];
+ start_68k_context(context, address);
+}
+
diff --git a/m68k_core.h b/m68k_core.h
index 224312f..370aa1e 100644
--- a/m68k_core.h
+++ b/m68k_core.h
@@ -67,7 +67,7 @@ typedef struct {
void translate_m68k(m68k_options * opts, struct m68kinst * inst);
void translate_m68k_stream(uint32_t address, m68k_context * context);
void start_68k_context(m68k_context * context, uint32_t address);
-void init_x86_68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chunks);
+void init_m68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chunks);
void init_68k_context(m68k_context * context, native_map_slot * native_code_map, void * opts);
void m68k_reset(m68k_context * context);
void insert_breakpoint(m68k_context * context, uint32_t address, uint8_t * bp_handler);
diff --git a/m68k_to_x86.c b/m68k_core_x86.c
index 295ff8e..f0f2f84 100644
--- a/m68k_to_x86.c
+++ b/m68k_core_x86.c
@@ -5,6 +5,7 @@
*/
#include "gen_x86.h"
#include "m68k_core.h"
+#include "m68k_internal.h"
#include "68kinst.h"
#include "mem.h"
#include "backend.h"
@@ -180,70 +181,6 @@ void cmp_flags(m68k_options *opts, uint8_t flag1, uint8_t flag2)
}
}
-int8_t native_reg(m68k_op_info * op, m68k_options * opts)
-{
- if (op->addr_mode == MODE_REG) {
- return opts->dregs[op->params.regs.pri];
- }
- if (op->addr_mode == MODE_AREG) {
- return opts->aregs[op->params.regs.pri];
- }
- return -1;
-}
-
-//must be called with an m68k_op_info that uses a register
-size_t reg_offset(m68k_op_info *op)
-{
- if (op->addr_mode == MODE_REG) {
- return offsetof(m68k_context, dregs) + sizeof(uint32_t) * op->params.regs.pri;
- }
- return offsetof(m68k_context, aregs) + sizeof(uint32_t) * op->params.regs.pri;
-}
-
-void print_regs_exit(m68k_context * context)
-{
- printf("XNZVC\n%d%d%d%d%d\n", context->flags[0], context->flags[1], context->flags[2], context->flags[3], context->flags[4]);
- for (int i = 0; i < 8; i++) {
- printf("d%d: %X\n", i, context->dregs[i]);
- }
- for (int i = 0; i < 8; i++) {
- printf("a%d: %X\n", i, context->aregs[i]);
- }
- exit(0);
-}
-
-void m68k_read_size(m68k_options *opts, uint8_t size)
-{
- switch (size)
- {
- case OPSIZE_BYTE:
- call(&opts->gen.code, opts->read_8);
- break;
- case OPSIZE_WORD:
- call(&opts->gen.code, opts->read_16);
- break;
- case OPSIZE_LONG:
- call(&opts->gen.code, opts->read_32);
- break;
- }
-}
-
-void m68k_write_size(m68k_options *opts, uint8_t size)
-{
- switch (size)
- {
- case OPSIZE_BYTE:
- call(&opts->gen.code, opts->write_8);
- break;
- case OPSIZE_WORD:
- call(&opts->gen.code, opts->write_16);
- break;
- case OPSIZE_LONG:
- call(&opts->gen.code, opts->write_32_highfirst);
- break;
- }
-}
-
void translate_m68k_src(m68kinst * inst, x86_ea * ea, m68k_options * opts)
{
code_info *code = &opts->gen.code;
@@ -693,92 +630,6 @@ void m68k_save_result(m68kinst * inst, m68k_options * opts)
}
}
-code_ptr get_native_address(native_map_slot * native_code_map, uint32_t address)
-{
- address &= 0xFFFFFF;
- address /= 2;
- uint32_t chunk = address / NATIVE_CHUNK_SIZE;
- if (!native_code_map[chunk].base) {
- return NULL;
- }
- uint32_t offset = address % NATIVE_CHUNK_SIZE;
- if (native_code_map[chunk].offsets[offset] == INVALID_OFFSET || native_code_map[chunk].offsets[offset] == EXTENSION_WORD) {
- return NULL;
- }
- return native_code_map[chunk].base + native_code_map[chunk].offsets[offset];
-}
-
-code_ptr get_native_from_context(m68k_context * context, uint32_t address)
-{
- return get_native_address(context->native_code_map, address);
-}
-
-uint32_t get_instruction_start(native_map_slot * native_code_map, uint32_t address)
-{
- address &= 0xFFFFFF;
- address /= 2;
- uint32_t chunk = address / NATIVE_CHUNK_SIZE;
- if (!native_code_map[chunk].base) {
- return 0;
- }
- uint32_t offset = address % NATIVE_CHUNK_SIZE;
- if (native_code_map[chunk].offsets[offset] == INVALID_OFFSET) {
- return 0;
- }
- while (native_code_map[chunk].offsets[offset] == EXTENSION_WORD) {
- --address;
- chunk = address / NATIVE_CHUNK_SIZE;
- offset = address % NATIVE_CHUNK_SIZE;
- }
- return address*2;
-}
-
-void map_native_address(m68k_context * context, uint32_t address, code_ptr native_addr, uint8_t size, uint8_t native_size)
-{
- native_map_slot * native_code_map = context->native_code_map;
- m68k_options * opts = context->options;
- address &= 0xFFFFFF;
- if (address > 0xE00000) {
- context->ram_code_flags[(address & 0xC000) >> 14] |= 1 << ((address & 0x3800) >> 11);
- if (((address & 0x3FFF) + size) & 0xC000) {
- context->ram_code_flags[((address+size) & 0xC000) >> 14] |= 1 << (((address+size) & 0x3800) >> 11);
- }
- uint32_t slot = (address & 0xFFFF)/1024;
- if (!opts->gen.ram_inst_sizes[slot]) {
- opts->gen.ram_inst_sizes[slot] = malloc(sizeof(uint8_t) * 512);
- }
- opts->gen.ram_inst_sizes[slot][((address & 0xFFFF)/2)%512] = native_size;
- }
- address/= 2;
- uint32_t chunk = address / NATIVE_CHUNK_SIZE;
- if (!native_code_map[chunk].base) {
- native_code_map[chunk].base = native_addr;
- native_code_map[chunk].offsets = malloc(sizeof(int32_t) * NATIVE_CHUNK_SIZE);
- memset(native_code_map[chunk].offsets, 0xFF, sizeof(int32_t) * NATIVE_CHUNK_SIZE);
- }
- uint32_t offset = address % NATIVE_CHUNK_SIZE;
- native_code_map[chunk].offsets[offset] = native_addr-native_code_map[chunk].base;
- for(address++,size-=2; size; address++,size-=2) {
- chunk = address / NATIVE_CHUNK_SIZE;
- offset = address % NATIVE_CHUNK_SIZE;
- if (!native_code_map[chunk].base) {
- native_code_map[chunk].base = native_addr;
- native_code_map[chunk].offsets = malloc(sizeof(int32_t) * NATIVE_CHUNK_SIZE);
- memset(native_code_map[chunk].offsets, 0xFF, sizeof(int32_t) * NATIVE_CHUNK_SIZE);
- }
- native_code_map[chunk].offsets[offset] = EXTENSION_WORD;
- }
-}
-
-uint8_t get_native_inst_size(m68k_options * opts, uint32_t address)
-{
- if (address < 0xE00000) {
- return 0;
- }
- uint32_t slot = (address & 0xFFFF)/1024;
- return opts->gen.ram_inst_sizes[slot][((address & 0xFFFF)/2)%512];
-}
-
void translate_m68k_move(m68k_options * opts, m68kinst * inst)
{
code_info *code = &opts->gen.code;
@@ -3665,103 +3516,18 @@ void translate_m68k(m68k_options * opts, m68kinst * inst)
}
}
-uint8_t m68k_is_terminal(m68kinst * inst)
+void translate_out_of_bounds(code_info *code)
{
- return inst->op == M68K_RTS || inst->op == M68K_RTE || inst->op == M68K_RTR || inst->op == M68K_JMP
- || inst->op == M68K_TRAP || inst->op == M68K_ILLEGAL || inst->op == M68K_INVALID || inst->op == M68K_RESET
- || (inst->op == M68K_BCC && inst->extra.cond == COND_TRUE);
-}
-
-void m68k_handle_deferred(m68k_context * context)
-{
- m68k_options * opts = context->options;
- process_deferred(&opts->gen.deferred, context, (native_addr_func)get_native_from_context);
- if (opts->gen.deferred) {
- translate_m68k_stream(opts->gen.deferred->address, context);
- }
-}
-
-void translate_m68k_stream(uint32_t address, m68k_context * context)
-{
- m68kinst instbuf;
- m68k_options * opts = context->options;
- code_info *code = &opts->gen.code;
- address &= 0xFFFFFF;
- if(get_native_address(opts->gen.native_code_map, address)) {
- return;
- }
- char disbuf[1024];
- 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 {
- if (opts->address_log) {
- fprintf(opts->address_log, "%X\n", address);
- }
- do {
- if (address >= 0x400000 && address < 0xE00000) {
- xor_rr(code, RDI, RDI, SZ_D);
+ xor_rr(code, RDI, RDI, SZ_D);
#ifdef X86_32
- push_r(code, RDI);
+ push_r(code, RDI);
#endif
- call(code, (code_ptr)exit);
- break;
- }
- code_ptr existing = get_native_address(opts->gen.native_code_map, address);
- if (existing) {
- jmp(code, existing);
- break;
- }
- next = m68k_decode(encoded, &instbuf, address);
- if (instbuf.op == M68K_INVALID) {
- instbuf.src.params.immed = *encoded;
- }
- uint16_t m68k_size = (next-encoded)*2;
- address += m68k_size;
- encoded = next;
- //m68k_disasm(&instbuf, disbuf);
- //printf("%X: %s\n", instbuf.address, disbuf);
-
- //make sure the beginning of the code for an instruction is contiguous
- check_alloc_code(code, MAX_INST_LEN*4);
- code_ptr start = code->cur;
- translate_m68k(opts, &instbuf);
- code_ptr after = code->cur;
- map_native_address(context, instbuf.address, start, m68k_size, after-start);
- after;
- } while(!m68k_is_terminal(&instbuf));
- process_deferred(&opts->gen.deferred, context, (native_addr_func)get_native_from_context);
- if (opts->gen.deferred) {
- address = opts->gen.deferred->address;
- 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);
- }
- } else {
- encoded = NULL;
- }
- } while(encoded != NULL);
+ call(code, (code_ptr)exit);
}
-code_ptr get_native_address_trans(m68k_context * context, uint32_t address)
+void check_code_prologue(code_info *code)
{
- address &= 0xFFFFFF;
- code_ptr 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;
+ check_alloc_code(code, MAX_INST_LEN*4);
}
void * m68k_retranslate_inst(uint32_t address, m68k_context * context)
@@ -3937,27 +3703,6 @@ void insert_breakpoint(m68k_context * context, uint32_t address, code_ptr bp_han
}
}
-void remove_breakpoint(m68k_context * context, uint32_t address)
-{
- code_ptr native = get_native_address(context->native_code_map, address);
- check_cycles_int(context->options, address);
-}
-
-void start_68k_context(m68k_context * context, uint32_t address)
-{
- code_ptr addr = get_native_address_trans(context, address);
- m68k_options * options = context->options;
- options->start_context(addr, context);
-}
-
-void m68k_reset(m68k_context * context)
-{
- //TODO: Make this actually use the normal read functions
- context->aregs[7] = context->mem_pointers[0][0] << 16 | context->mem_pointers[0][1];
- uint32_t address = context->mem_pointers[0][2] << 16 | context->mem_pointers[0][3];
- start_68k_context(context, address);
-}
-
code_ptr gen_mem_fun(cpu_options * opts, memmap_chunk * memmap, uint32_t num_chunks, ftype fun_type)
{
code_info *code = &opts->code;
@@ -4197,7 +3942,7 @@ code_ptr gen_mem_fun(cpu_options * opts, memmap_chunk * memmap, uint32_t num_chu
return start;
}
-void init_x86_68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chunks)
+void init_m68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chunks)
{
memset(opts, 0, sizeof(*opts));
for (int i = 0; i < 8; i++)
diff --git a/m68k_internal.h b/m68k_internal.h
new file mode 100644
index 0000000..f73db3f
--- /dev/null
+++ b/m68k_internal.h
@@ -0,0 +1,28 @@
+/*
+ Copyright 2014 Michael Pavone
+ This file is part of BlastEm.
+ BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text.
+*/
+#ifndef M68K_INTERNAL_H_
+#define M68K_INTERNAL_H_
+
+#include "68kinst.h"
+
+//functions implemented in host CPU specfic file
+void translate_out_of_bounds(code_info *code);
+void check_code_prologue(code_info *code);
+
+//functions implemented in m68k_core.c
+int8_t native_reg(m68k_op_info * op, m68k_options * opts);
+size_t reg_offset(m68k_op_info *op);
+void print_regs_exit(m68k_context * context);
+void m68k_read_size(m68k_options *opts, uint8_t size);
+void m68k_write_size(m68k_options *opts, uint8_t size);
+code_ptr get_native_address(native_map_slot * native_code_map, uint32_t address);
+void map_native_address(m68k_context * context, uint32_t address, code_ptr native_addr, uint8_t size, uint8_t native_size);
+uint8_t get_native_inst_size(m68k_options * opts, uint32_t address);
+uint8_t m68k_is_terminal(m68kinst * inst);
+void m68k_handle_deferred(m68k_context * context);
+code_ptr get_native_address_trans(m68k_context * context, uint32_t address);
+
+#endif //M68K_INTERNAL_H_
diff --git a/trans.c b/trans.c
index e897d37..d73ebc5 100644
--- a/trans.c
+++ b/trans.c
@@ -49,7 +49,7 @@ int main(int argc, char ** argv)
memmap[1].mask = 0xFFFF;
memmap[1].flags = MMAP_READ | MMAP_WRITE | MMAP_CODE;
memmap[1].buffer = malloc(64 * 1024);
- init_x86_68k_opts(&opts, memmap, 2);
+ init_m68k_opts(&opts, memmap, 2);
init_68k_context(&context, opts.gen.native_code_map, &opts);
context.mem_pointers[0] = memmap[0].buffer;
context.mem_pointers[1] = memmap[1].buffer;