summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--blastem.c18
-rw-r--r--gen.h2
-rw-r--r--gen_x86.c13
-rw-r--r--m68k_core.c15
-rw-r--r--m68k_core.h6
-rw-r--r--m68k_core_x86.c27
-rw-r--r--m68k_internal.h4
-rw-r--r--trans.c10
8 files changed, 68 insertions, 27 deletions
diff --git a/blastem.c b/blastem.c
index 085dd8c..b91070a 100644
--- a/blastem.c
+++ b/blastem.c
@@ -875,11 +875,11 @@ void persist_save()
#ifndef NO_Z80
const memmap_chunk z80_map[] = {
- { 0x0000, 0x4000, 0x1FFF, 0, MMAP_READ | MMAP_WRITE | MMAP_CODE, z80_ram, NULL, NULL, NULL, NULL },
- { 0x8000, 0x10000, 0x7FFF, 0, 0, NULL, NULL, NULL, z80_read_bank, z80_write_bank},
- { 0x4000, 0x6000, 0x0003, 0, 0, NULL, NULL, NULL, z80_read_ym, z80_write_ym},
- { 0x6000, 0x6100, 0xFFFF, 0, 0, NULL, NULL, NULL, NULL, z80_write_bank_reg},
- { 0x7F00, 0x8000, 0x00FF, 0, 0, NULL, NULL, NULL, z80_vdp_port_read, z80_vdp_port_write}
+ { 0x0000, 0x4000, 0x1FFF, 0, 0, MMAP_READ | MMAP_WRITE | MMAP_CODE, z80_ram, NULL, NULL, NULL, NULL },
+ { 0x8000, 0x10000, 0x7FFF, 0, 0, 0, NULL, NULL, NULL, z80_read_bank, z80_write_bank},
+ { 0x4000, 0x6000, 0x0003, 0, 0, 0, NULL, NULL, NULL, z80_read_ym, z80_write_ym},
+ { 0x6000, 0x6100, 0xFFFF, 0, 0, 0, NULL, NULL, NULL, NULL, z80_write_bank_reg},
+ { 0x7F00, 0x8000, 0x00FF, 0, 0, 0, NULL, NULL, NULL, z80_vdp_port_read, z80_vdp_port_write}
};
#endif
@@ -939,7 +939,7 @@ genesis_context *alloc_init_genesis(rom_info *rom, int fps, uint32_t ym_opts)
init_m68k_opts(opts, rom->map, rom->map_chunks, MCLKS_PER_68K);
//TODO: make this configurable
opts->gen.flags |= M68K_OPT_BROKEN_READ_MODIFY;
- gen->m68k = init_68k_context(opts);
+ gen->m68k = init_68k_context(opts, NULL);
gen->m68k->system = gen;
for (int i = 0; i < rom->map_chunks; i++)
@@ -1213,12 +1213,12 @@ int main(int argc, char ** argv)
}
ram = malloc(RAM_WORDS * sizeof(uint16_t));
memmap_chunk base_map[] = {
- {0xE00000, 0x1000000, 0xFFFF, 0, MMAP_READ | MMAP_WRITE | MMAP_CODE, ram,
+ {0xE00000, 0x1000000, 0xFFFF, 0, 0, MMAP_READ | MMAP_WRITE | MMAP_CODE, ram,
NULL, NULL, NULL, NULL},
- {0xC00000, 0xE00000, 0x1FFFFF, 0, 0, NULL,
+ {0xC00000, 0xE00000, 0x1FFFFF, 0, 0, 0, NULL,
(read_16_fun)vdp_port_read, (write_16_fun)vdp_port_write,
(read_8_fun)vdp_port_read_b, (write_8_fun)vdp_port_write_b},
- {0xA00000, 0xA12000, 0x1FFFF, 0, 0, NULL,
+ {0xA00000, 0xA12000, 0x1FFFF, 0, 0, 0, NULL,
(read_16_fun)io_read_w, (write_16_fun)io_write_w,
(read_8_fun)io_read, (write_8_fun)io_write}
};
diff --git a/gen.h b/gen.h
index 16dcab8..7d9b373 100644
--- a/gen.h
+++ b/gen.h
@@ -26,6 +26,8 @@ void jmp(code_info *code, code_ptr dest);
void jmp_r(code_info *code, uint8_t dst);
//call a function and put the arguments in the appropriate place according to the host ABI
void call_args(code_info *code, code_ptr fun, uint32_t num_args, ...);
+//like the above, but call a function pointer stored in a register
+void call_args_r(code_info *code, uint8_t fun_reg, uint32_t num_args, ...);
//like the above, but follows other aspects of the ABI like stack alignment
//void call_args_abi(code_info *code, code_ptr fun, uint32_t num_args, ...);
#define call_args_abi call_args
diff --git a/gen_x86.c b/gen_x86.c
index 2f5689e..60ad90a 100644
--- a/gen_x86.c
+++ b/gen_x86.c
@@ -2138,6 +2138,19 @@ void call_args(code_info *code, code_ptr fun, uint32_t num_args, ...)
code->stack_off -= adjust;
}
}
+
+void call_args_r(code_info *code, uint8_t fun_reg, uint32_t num_args, ...)
+{
+ va_list args;
+ va_start(args, num_args);
+ uint32_t adjust = prep_args(code, num_args, args);
+ va_end(args);
+ call_r(code, fun_reg);
+ if (adjust) {
+ add_ir(code, adjust, RSP, SZ_PTR);
+ code->stack_off -= adjust;
+ }
+}
/*
void call_args_abi(code_info *code, code_ptr fun, uint32_t num_args, ...)
{
diff --git a/m68k_core.c b/m68k_core.c
index 812e00a..71a7310 100644
--- a/m68k_core.c
+++ b/m68k_core.c
@@ -43,7 +43,7 @@ size_t reg_offset(m68k_op_info *op)
return op->addr_mode == MODE_REG ? dreg_offset(op->params.regs.pri) : areg_offset(op->params.regs.pri);
}
-void print_regs_exit(m68k_context * context)
+void m68k_print_regs(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++) {
@@ -52,7 +52,6 @@ void print_regs_exit(m68k_context * context)
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)
@@ -538,13 +537,6 @@ void swap_ssp_usp(m68k_options * opts)
native_to_areg(opts, opts->gen.scratch2, 8);
}
-void translate_m68k_reset(m68k_options *opts, m68kinst *inst)
-{
- code_info *code = &opts->gen.code;
- call(code, opts->gen.save_context);
- call_args(code, (code_ptr)print_regs_exit, 1, opts->gen.context_reg);
-}
-
void translate_m68k_rte(m68k_options *opts, m68kinst *inst)
{
m68k_trap_if_not_supervisor(opts, inst);
@@ -907,7 +899,7 @@ void translate_m68k_stream(uint32_t address, m68k_context * context)
encoded = get_native_pointer(address, (void **)context->mem_pointers, &opts->gen);
if (!encoded) {
map_native_address(context, address, code->cur, 2, 1);
- translate_out_of_bounds(code);
+ translate_out_of_bounds(opts, address);
break;
}
code_ptr existing = get_native_address(opts, address);
@@ -1068,7 +1060,7 @@ void m68k_options_free(m68k_options *opts)
}
-m68k_context * init_68k_context(m68k_options * opts)
+m68k_context * init_68k_context(m68k_options * opts, m68k_reset_handler reset_handler)
{
size_t ctx_size = sizeof(m68k_context) + ram_size(&opts->gen) / (1 << opts->gen.ram_flags_shift) / 8;
m68k_context * context = malloc(ctx_size);
@@ -1077,5 +1069,6 @@ m68k_context * init_68k_context(m68k_options * opts)
context->options = opts;
context->int_cycle = CYCLE_NEVER;
context->status = 0x27;
+ context->reset_handler = (code_ptr)reset_handler;
return context;
}
diff --git a/m68k_core.h b/m68k_core.h
index bc434a9..f1e2cef 100644
--- a/m68k_core.h
+++ b/m68k_core.h
@@ -61,6 +61,7 @@ typedef struct {
uint32_t last_prefetch_address;
uint16_t *mem_pointers[NUM_MEM_AREAS];
code_ptr resume_pc;
+ code_ptr reset_handler;
native_map_slot *native_code_map;
m68k_options *options;
void *system;
@@ -69,12 +70,14 @@ typedef struct {
uint8_t ram_code_flags[];
} m68k_context;
+typedef m68k_context *(*m68k_reset_handler)(m68k_context *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 resume_68k(m68k_context *context);
void init_m68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chunks, uint32_t clock_divider);
-m68k_context * init_68k_context(m68k_options * opts);
+m68k_context * init_68k_context(m68k_options * opts, m68k_reset_handler reset_handler);
void m68k_reset(m68k_context * context);
void m68k_options_free(m68k_options *opts);
void insert_breakpoint(m68k_context * context, uint32_t address, uint8_t * bp_handler);
@@ -82,6 +85,7 @@ void remove_breakpoint(m68k_context * context, uint32_t address);
m68k_context * m68k_handle_code_write(uint32_t address, m68k_context * context);
uint32_t get_instruction_start(m68k_options *opts, native_map_slot * native_code_map, uint32_t address);
uint16_t m68k_get_ir(m68k_context *context);
+void m68k_print_regs(m68k_context * context);
#endif //M68K_CORE_H_
diff --git a/m68k_core_x86.c b/m68k_core_x86.c
index c07760b..6ad305d 100644
--- a/m68k_core_x86.c
+++ b/m68k_core_x86.c
@@ -1156,6 +1156,21 @@ void translate_shift(m68k_options * opts, m68kinst * inst, host_ea *src_op, host
}
}
+void translate_m68k_reset(m68k_options *opts, m68kinst *inst)
+{
+ code_info *code = &opts->gen.code;
+ cycles(&opts->gen, BUS);
+ mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, reset_handler), opts->gen.scratch1, SZ_PTR);
+ cmp_ir(code, 0, opts->gen.scratch1, SZ_PTR);
+ code_ptr no_reset_handler = code->cur + 1;
+ jcc(code, CC_Z, code->cur+2);
+ call(code, opts->gen.save_context);
+ call_args_r(code, opts->gen.scratch1, 1, opts->gen.context_reg);
+ mov_rr(code, RAX, opts->gen.context_reg, SZ_PTR);
+ call(code, opts->gen.load_context);
+ *no_reset_handler = code->cur - (no_reset_handler + 1);
+}
+
void op_ir(code_info *code, m68kinst *inst, int32_t val, uint8_t dst, uint8_t size)
{
switch (inst->op)
@@ -2220,10 +2235,16 @@ void translate_m68k_move_from_sr(m68k_options *opts, m68kinst *inst, host_ea *sr
m68k_save_result(inst, opts);
}
-void translate_out_of_bounds(code_info *code)
+void m68k_out_of_bounds_execution(uint32_t address)
+{
+ fatal_error("M68K attempted to execute code at unmapped or I/O address %X\n", address);
+}
+
+void translate_out_of_bounds(m68k_options *opts, uint32_t address)
{
- xor_rr(code, RDI, RDI, SZ_D);
- call_args(code, (code_ptr)exit, 1, RDI);
+ code_info *code = &opts->gen.code;
+ mov_ir(code, address, opts->gen.scratch1, SZ_D);
+ call_args(code, (code_ptr)m68k_out_of_bounds_execution, 1, opts->gen.scratch1);
}
void m68k_set_last_prefetch(m68k_options *opts, uint32_t address)
diff --git a/m68k_internal.h b/m68k_internal.h
index 4a3acf3..b472eb6 100644
--- a/m68k_internal.h
+++ b/m68k_internal.h
@@ -9,7 +9,7 @@
#include "68kinst.h"
//functions implemented in host CPU specfic file
-void translate_out_of_bounds(code_info *code);
+void translate_out_of_bounds(m68k_options *opts, uint32_t address);
void areg_to_native(m68k_options *opts, uint8_t reg, uint8_t native_reg);
void dreg_to_native(m68k_options *opts, uint8_t reg, uint8_t native_reg);
void areg_to_native_sx(m68k_options *opts, uint8_t reg, uint8_t native_reg);
@@ -42,7 +42,6 @@ size_t dreg_offset(uint8_t reg);
size_t areg_offset(uint8_t reg);
size_t reg_offset(m68k_op_info *op);
void translate_m68k_op(m68kinst * inst, host_ea * ea, m68k_options * opts, uint8_t dst);
-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, uint8_t lowfirst);
void m68k_save_result(m68kinst * inst, m68k_options * opts);
@@ -88,6 +87,7 @@ void translate_m68k_eori_ccr_sr(m68k_options *opts, m68kinst *inst);
void translate_m68k_move_ccr_sr(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op);
void translate_m68k_stop(m68k_options *opts, m68kinst *inst);
void translate_m68k_move_from_sr(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op);
+void translate_m68k_reset(m68k_options *opts, m68kinst *inst);
//flag update bits
#define X0 0x0001
diff --git a/trans.c b/trans.c
index 7dd21fd..bdde49c 100644
--- a/trans.c
+++ b/trans.c
@@ -27,6 +27,14 @@ m68k_context * sync_components(m68k_context * context, uint32_t address)
return context;
}
+m68k_context *reset_handler(m68k_context *context)
+{
+ m68k_print_regs(context);
+ exit(0);
+ //unreachable
+ return context;
+}
+
int main(int argc, char ** argv)
{
long filesize;
@@ -60,7 +68,7 @@ int main(int argc, char ** argv)
memmap[1].buffer = malloc(64 * 1024);
memset(memmap[1].buffer, 0, 64 * 1024);
init_m68k_opts(&opts, memmap, 2, 1);
- m68k_context * context = init_68k_context(&opts);
+ m68k_context * context = init_68k_context(&opts, reset_handler);
context->mem_pointers[0] = memmap[0].buffer;
context->mem_pointers[1] = memmap[1].buffer;
context->target_cycle = context->sync_cycle = 0x80000000;