summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backend.c25
-rw-r--r--backend.h2
-rw-r--r--backend_x86.c8
-rw-r--r--blastem.c29
-rw-r--r--m68k_core.c67
-rw-r--r--m68k_core.h4
-rw-r--r--m68k_core_x86.c8
7 files changed, 106 insertions, 37 deletions
diff --git a/backend.c b/backend.c
index 8f65f25..1f9e718 100644
--- a/backend.c
+++ b/backend.c
@@ -72,3 +72,28 @@ void * get_native_pointer(uint32_t address, void ** mem_pointers, cpu_options *
}
return NULL;
}
+
+uint32_t chunk_size(cpu_options *opts, memmap_chunk const *chunk)
+{
+ if (chunk->mask == opts->address_mask) {
+ return chunk->end - chunk->start;
+ } else {
+ return chunk->mask + 1;
+ }
+}
+
+uint32_t ram_size(cpu_options *opts)
+{
+ uint32_t size = 0;
+ for (int i = 0; i < opts->memmap_chunks; i++)
+ {
+ if ((opts->memmap[i].flags & (MMAP_WRITE | MMAP_CODE)) == (MMAP_WRITE | MMAP_CODE)) {
+ if (opts->memmap[i].mask == opts->address_mask) {
+ size += opts->memmap[i].end - opts->memmap[i].start;
+ } else {
+ size += opts->memmap[i].mask + 1;
+ }
+ }
+ }
+ return size;
+}
diff --git a/backend.h b/backend.h
index c3ae875..2b95d06 100644
--- a/backend.h
+++ b/backend.h
@@ -116,6 +116,8 @@ void check_code_prologue(code_info *code);
code_ptr gen_mem_fun(cpu_options * opts, memmap_chunk const * memmap, uint32_t num_chunks, ftype fun_type, code_ptr *after_inc);
void * get_native_pointer(uint32_t address, void ** mem_pointers, cpu_options * opts);
+uint32_t chunk_size(cpu_options *opts, memmap_chunk const *chunk);
+uint32_t ram_size(cpu_options *opts);
#endif //BACKEND_H_
diff --git a/backend_x86.c b/backend_x86.c
index 7c289de..5a1f5d5 100644
--- a/backend_x86.c
+++ b/backend_x86.c
@@ -50,6 +50,7 @@ code_ptr gen_mem_fun(cpu_options * opts, memmap_chunk const * memmap, uint32_t n
uint8_t adr_reg = is_write ? opts->scratch2 : opts->scratch1;
uint16_t access_flag = is_write ? MMAP_WRITE : MMAP_READ;
uint8_t size = (fun_type == READ_16 || fun_type == WRITE_16) ? SZ_W : SZ_B;
+ uint32_t ram_flags_off = opts->ram_flags_off;
for (uint32_t chunk = 0; chunk < num_chunks; chunk++)
{
if (memmap[chunk].start > 0) {
@@ -173,7 +174,12 @@ code_ptr gen_mem_fun(cpu_options * opts, memmap_chunk const * memmap, uint32_t n
if (is_write && (memmap[chunk].flags & MMAP_CODE)) {
mov_rr(code, opts->scratch2, opts->scratch1, opts->address_size);
shr_ir(code, opts->ram_flags_shift, opts->scratch1, opts->address_size);
- bt_rrdisp(code, opts->scratch1, opts->context_reg, opts->ram_flags_off, opts->address_size);
+ bt_rrdisp(code, opts->scratch1, opts->context_reg, ram_flags_off, opts->address_size);
+ if (memmap[chunk].mask == opts->address_mask) {
+ ram_flags_off += memmap[chunk].end - memmap[chunk].start;
+ } else {
+ ram_flags_off += memmap[chunk].mask + 1;
+ }
code_ptr not_code = code->cur + 1;
jcc(code, CC_NC, code->cur + 2);
call(code, opts->save_context);
diff --git a/blastem.c b/blastem.c
index 684f644..27b9d07 100644
--- a/blastem.c
+++ b/blastem.c
@@ -901,9 +901,7 @@ void save_sram()
void init_run_cpu(genesis_context * gen, FILE * address_log, char * statefile, uint8_t * debugger)
{
- m68k_context context;
m68k_options opts;
- gen->m68k = &context;
memmap_chunk memmap[MAX_MAP_CHUNKS];
uint32_t num_chunks;
void * initial_mapped = NULL;
@@ -998,21 +996,22 @@ void init_run_cpu(genesis_context * gen, FILE * address_log, char * statefile, u
}
init_m68k_opts(&opts, memmap, num_chunks, MCLKS_PER_68K);
opts.address_log = address_log;
- init_68k_context(&context, opts.gen.native_code_map, &opts);
+ m68k_context *context = init_68k_context(&opts);
+ gen->m68k = context;
- context.video_context = gen->vdp;
- context.system = gen;
+ context->video_context = gen->vdp;
+ context->system = gen;
//cartridge ROM
- context.mem_pointers[0] = cart;
- context.target_cycle = context.sync_cycle = mclk_target;
+ context->mem_pointers[0] = cart;
+ context->target_cycle = context->sync_cycle = mclk_target;
//work RAM
- context.mem_pointers[1] = ram;
+ context->mem_pointers[1] = ram;
//save RAM/map
- context.mem_pointers[2] = initial_mapped;
- context.mem_pointers[3] = (uint16_t *)gen->save_ram;
+ context->mem_pointers[2] = initial_mapped;
+ context->mem_pointers[3] = (uint16_t *)gen->save_ram;
uint32_t address;
address = cart[2] << 16 | cart[3];
- translate_m68k_stream(address, &context);
+ translate_m68k_stream(address, context);
if (statefile) {
uint32_t pc = load_gst(gen, statefile);
if (!pc) {
@@ -1021,15 +1020,15 @@ void init_run_cpu(genesis_context * gen, FILE * address_log, char * statefile, u
}
printf("Loaded %s\n", statefile);
if (debugger) {
- insert_breakpoint(&context, pc, debugger);
+ insert_breakpoint(context, pc, debugger);
}
adjust_int_cycle(gen->m68k, gen->vdp);
- start_68k_context(&context, pc);
+ start_68k_context(context, pc);
} else {
if (debugger) {
- insert_breakpoint(&context, address, debugger);
+ insert_breakpoint(context, address, debugger);
}
- m68k_reset(&context);
+ m68k_reset(context);
}
}
diff --git a/m68k_core.c b/m68k_core.c
index 63133a1..ff6278c 100644
--- a/m68k_core.c
+++ b/m68k_core.c
@@ -553,6 +553,7 @@ void translate_m68k_rte(m68k_options *opts, m68kinst *inst)
code_ptr get_native_address(native_map_slot * native_code_map, uint32_t address)
{
+ //FIXME: Use opts->gen.address_mask
address &= 0xFFFFFF;
address /= 2;
uint32_t chunk = address / NATIVE_CHUNK_SIZE;
@@ -573,6 +574,7 @@ code_ptr get_native_from_context(m68k_context * context, uint32_t address)
uint32_t get_instruction_start(native_map_slot * native_code_map, uint32_t address)
{
+ //FIXME: Use opts->gen.address_mask
address &= 0xFFFFFF;
address /= 2;
uint32_t chunk = address / NATIVE_CHUNK_SIZE;
@@ -595,17 +597,34 @@ void map_native_address(m68k_context * context, uint32_t address, code_ptr nativ
{
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);
+ address &= opts->gen.address_mask;
+ uint32_t meta_off = 0;
+ //TODO: Refactor part of this loop into some kind of get_ram_chunk function
+ for (int i = 0; i < opts->gen.memmap_chunks; i++) {
+ if (address >= opts->gen.memmap[i].start && address < opts->gen.memmap[i].end) {
+ if ((opts->gen.memmap[i].flags & (MMAP_WRITE | MMAP_CODE)) == (MMAP_WRITE | MMAP_CODE)) {
+ uint32_t masked = (address & opts->gen.memmap[i].mask);
+ uint32_t final_off = masked + meta_off;
+ uint32_t ram_flags_off = final_off >> (opts->gen.ram_flags_shift + 3);
+ context->ram_code_flags[ram_flags_off] |= 1 << ((final_off >> opts->gen.ram_flags_shift) & 3);
+
+ uint32_t slot = final_off / 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][(final_off/2) & 511] = native_size;
+
+ //TODO: Deal with case in which end of instruction is in a different memory chunk
+ masked = (address + size - 1) & opts->gen.memmap[i].mask;
+ final_off = masked + meta_off;
+ ram_flags_off = final_off >> (opts->gen.ram_flags_shift + 3);
+ context->ram_code_flags[ram_flags_off] |= 1 << ((final_off >> opts->gen.ram_flags_shift) & 3);
+ }
+ break;
+ } else if ((opts->gen.memmap[i].flags & (MMAP_WRITE | MMAP_CODE)) == (MMAP_WRITE | MMAP_CODE)) {
+ uint32_t size = chunk_size(&opts->gen, opts->gen.memmap + i);
+ meta_off += size;
}
- opts->gen.ram_inst_sizes[slot][((address & 0xFFFF)/2)%512] = native_size;
}
address/= 2;
uint32_t chunk = address / NATIVE_CHUNK_SIZE;
@@ -630,11 +649,22 @@ void map_native_address(m68k_context * context, uint32_t address, code_ptr nativ
uint8_t get_native_inst_size(m68k_options * opts, uint32_t address)
{
- if (address < 0xE00000) {
- return 0;
+ address &= opts->gen.address_mask;
+ uint32_t meta_off = 0;
+ for (int i = 0; i < opts->gen.memmap_chunks; i++) {
+ if (address >= opts->gen.memmap[i].start && address < opts->gen.memmap[i].end) {
+ if ((opts->gen.memmap[i].flags & (MMAP_WRITE | MMAP_CODE)) != (MMAP_WRITE | MMAP_CODE)) {
+ return 0;
+ }
+ meta_off += address & opts->gen.memmap[i].mask;
+ break;
+ } else if ((opts->gen.memmap[i].flags & (MMAP_WRITE | MMAP_CODE)) == (MMAP_WRITE | MMAP_CODE)) {
+ uint32_t size = chunk_size(&opts->gen, opts->gen.memmap + i);
+ meta_off += size;
+ }
}
- uint32_t slot = (address & 0xFFFF)/1024;
- return opts->gen.ram_inst_sizes[slot][((address & 0xFFFF)/2)%512];
+ uint32_t slot = meta_off/1024;
+ return opts->gen.ram_inst_sizes[slot][(meta_off/2)%512];
}
uint8_t m68k_is_terminal(m68kinst * inst)
@@ -926,6 +956,7 @@ void * m68k_retranslate_inst(uint32_t address, m68k_context * context)
code_ptr get_native_address_trans(m68k_context * context, uint32_t address)
{
+ //FIXME: Use opts->gen.address_mask
address &= 0xFFFFFF;
code_ptr ret = get_native_address(context->native_code_map, address);
if (!ret) {
@@ -962,11 +993,13 @@ void m68k_reset(m68k_context * context)
}
-void init_68k_context(m68k_context * context, native_map_slot * native_code_map, void * opts)
+m68k_context * init_68k_context(m68k_options * opts)
{
+ m68k_context * context = malloc(sizeof(m68k_context) + ram_size(&opts->gen) / (1 << opts->gen.ram_flags_shift) / 8);
memset(context, 0, sizeof(m68k_context));
- context->native_code_map = native_code_map;
+ context->native_code_map = opts->gen.native_code_map;
context->options = opts;
- context->int_cycle = 0xFFFFFFFF;
+ context->int_cycle = CYCLE_NEVER;
context->status = 0x27;
+ return context;
}
diff --git a/m68k_core.h b/m68k_core.h
index cf43864..2635a09 100644
--- a/m68k_core.h
+++ b/m68k_core.h
@@ -60,15 +60,15 @@ typedef struct {
native_map_slot *native_code_map;
m68k_options *options;
- uint8_t ram_code_flags[32/8];
void *system;
+ uint8_t ram_code_flags[];
} m68k_context;
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_m68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chunks, uint32_t clock_divider);
-void init_68k_context(m68k_context * context, native_map_slot * native_code_map, void * opts);
+m68k_context * init_68k_context(m68k_options * opts);
void m68k_reset(m68k_context * context);
void insert_breakpoint(m68k_context * context, uint32_t address, uint8_t * bp_handler);
void remove_breakpoint(m68k_context * context, uint32_t address);
diff --git a/m68k_core_x86.c b/m68k_core_x86.c
index 9787b9c..167c740 100644
--- a/m68k_core_x86.c
+++ b/m68k_core_x86.c
@@ -2202,8 +2202,10 @@ void init_m68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chu
opts->gen.native_code_map = malloc(sizeof(native_map_slot) * NATIVE_MAP_CHUNKS);
memset(opts->gen.native_code_map, 0, sizeof(native_map_slot) * NATIVE_MAP_CHUNKS);
opts->gen.deferred = NULL;
- opts->gen.ram_inst_sizes = malloc(sizeof(uint8_t *) * 64);
- memset(opts->gen.ram_inst_sizes, 0, sizeof(uint8_t *) * 64);
+
+ uint32_t inst_size_size = sizeof(uint8_t *) * ram_size(&opts->gen) / 1024;
+ opts->gen.ram_inst_sizes = malloc(inst_size_size);
+ memset(opts->gen.ram_inst_sizes, 0, inst_size_size);
code_info *code = &opts->gen.code;
init_code_info(code);
@@ -2227,9 +2229,11 @@ void init_m68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chu
opts->gen.load_context = code->cur;
for (int i = 0; i < 5; i++)
+ {
if (opts->flag_regs[i] >= 0) {
mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, flags) + i, opts->flag_regs[i], SZ_B);
}
+ }
for (int i = 0; i < 8; i++)
{
if (opts->dregs[i] >= 0) {