From a39a82cc9773c8336eaa48379f2d2fe3615f178c Mon Sep 17 00:00:00 2001 From: Mike Pavone Date: Tue, 17 Jun 2014 01:50:29 -0400 Subject: blastem builds and almost works on OS X now --- Makefile | 13 ++++++++++++- blastem.c | 3 +++ m68k_to_x86.c | 17 +++++++++++++---- runtime.S | 12 ------------ util.c | 2 +- z80_to_x86.c | 31 ++++++++++++++++--------------- z80_to_x86.h | 6 +++--- zruntime.S | 6 +++--- 8 files changed, 51 insertions(+), 39 deletions(-) diff --git a/Makefile b/Makefile index a20ae8f..0eb57cd 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,17 @@ +ifndef OS +OS:=$(shell uname -s) +endif + ifdef NOGL LIBS=sdl else +ifeq ($(OS),Darwin) +LIBS=sdl glew +else LIBS=sdl glew gl endif +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 @@ -22,7 +31,9 @@ ifndef CPU CPU:=$(shell uname -m) endif - +ifeq ($(OS),Darwin) +LDFLAGS+= -framework OpenGL +endif TRANSOBJS=gen_x86.o backend.o mem.o M68KOBJS=68kinst.o m68k_to_x86.o diff --git a/blastem.c b/blastem.c index 52de892..962ea9b 100644 --- a/blastem.c +++ b/blastem.c @@ -383,6 +383,7 @@ m68k_context * vdp_port_write_b(uint32_t vdp_port, m68k_context * context, uint8 return vdp_port_write(vdp_port, context, vdp_port < 0x10 ? value | value << 8 : ((vdp_port & 1) ? value : 0)); } +z80_context * z80_vdp_port_write(uint16_t vdp_port, z80_context * context, uint8_t value) asm("z80_vdp_port_write"); z80_context * z80_vdp_port_write(uint16_t vdp_port, z80_context * context, uint8_t value) { genesis_context * gen = context->system; @@ -674,6 +675,7 @@ uint16_t io_read_w(uint32_t location, m68k_context * context) return value; } +extern z80_context * z80_write_ym(uint16_t location, z80_context * context, uint8_t value) asm("z80_write_ym"); z80_context * z80_write_ym(uint16_t location, z80_context * context, uint8_t value) { genesis_context * gen = context->system; @@ -688,6 +690,7 @@ z80_context * z80_write_ym(uint16_t location, z80_context * context, uint8_t val return context; } +extern uint8_t z80_read_ym(uint16_t location, z80_context * context) asm("z80_read_ym"); uint8_t z80_read_ym(uint16_t location, z80_context * context) { genesis_context * gen = context->system; diff --git a/m68k_to_x86.c b/m68k_to_x86.c index 34a631f..959d62b 100644 --- a/m68k_to_x86.c +++ b/m68k_to_x86.c @@ -39,9 +39,14 @@ char disasm_buf[1024]; m68k_context * sync_components(m68k_context * context, uint32_t address); -void m68k_invalid(); -void bcd_add(); -void bcd_sub(); +extern void bcd_add() asm("bcd_add"); +extern void bcd_sub() asm("bcd_sub"); + +void m68k_invalid(uint32_t address, m68k_context * context) +{ + printf("Invalid instruction at %X\n", address); + exit(1); +} code_ptr cycles(code_ptr dst, uint32_t num) { @@ -2864,7 +2869,11 @@ code_ptr translate_m68k(code_ptr dst, m68kinst * inst, x86_68k_options * opts) if (inst->src.params.immed == 0x7100) { return retn(dst); } - dst = mov_ir(dst, inst->address, SCRATCH1, SZ_D); + dst = mov_ir(dst, inst->address, SCRATCH2, SZ_D); +#ifdef X86_32 + dst = push_r(dst, CONTEXT); + dst = push_r(dst, SCRATCH2); +#endif return call(dst, (code_ptr)m68k_invalid); } else if(inst->op == M68K_CMP) { return translate_m68k_cmp(dst, inst, opts); diff --git a/runtime.S b/runtime.S index e66b158..caac541 100644 --- a/runtime.S +++ b/runtime.S @@ -1,17 +1,5 @@ -invalid_msg: - .asciz "Invalid instruction at %X\n" - - .global m68k_invalid -m68k_invalid: - lea invalid_msg(%rip), %rdi - mov %ecx, %esi - xor %rax, %rax - call printf - mov $1, %rdi - call exit - .global bcd_add bcd_add: xchg %rax, %rdi diff --git a/util.c b/util.c index 2bc3109..5367cd5 100644 --- a/util.c +++ b/util.c @@ -92,7 +92,7 @@ char * readlink_alloc(char * path) if (linksize == -1) { perror("readlink"); free(linktext); - linktext = NULL; + return NULL; } } while ((linksize+1) > cursize); linktext[linksize] = 0; diff --git a/z80_to_x86.c b/z80_to_x86.c index 2cab1c9..34263ad 100644 --- a/z80_to_x86.c +++ b/z80_to_x86.c @@ -28,21 +28,21 @@ #define dprintf #endif -void z80_read_byte(); -void z80_read_word(); -void z80_write_byte(); -void z80_write_word_highfirst(); -void z80_write_word_lowfirst(); -void z80_save_context(); -void z80_native_addr(); -void z80_do_sync(); -void z80_handle_cycle_limit_int(); -void z80_retrans_stub(); -void z80_io_read(); -void z80_io_write(); -void z80_halt(); -void z80_save_context(); -void z80_load_context(); +extern void z80_read_byte() asm("z80_read_byte"); +extern void z80_read_word() asm("z80_read_word"); +extern void z80_write_byte() asm("z80_write_byte"); +extern void z80_write_word_highfirst() asm("z80_write_word_highfirst"); +extern void z80_write_word_lowfirst() asm("z80_write_word_lowfirst"); +extern void z80_save_context() asm("z80_save_context"); +extern void z80_native_addr() asm("z80_native_addr"); +extern void z80_do_sync() asm("z80_do_sync"); +extern void z80_handle_cycle_limit_int() asm("z80_handle_cycle_limit_int"); +extern void z80_retrans_stub() asm("z80_retrans_stub"); +extern void z80_io_read() asm("z80_io_read"); +extern void z80_io_write() asm("z80_io_write"); +extern void z80_halt() asm("z80_halt"); +extern void z80_save_context() asm("z80_save_context"); +extern void z80_load_context() asm("z80_load_context"); uint8_t z80_size(z80inst * inst) { @@ -1780,6 +1780,7 @@ void z80_handle_deferred(z80_context * context) } } +extern void * z80_retranslate_inst(uint32_t address, z80_context * context, uint8_t * orig_start) asm("z80_retranslate_inst"); void * z80_retranslate_inst(uint32_t address, z80_context * context, uint8_t * orig_start) { char disbuf[80]; diff --git a/z80_to_x86.h b/z80_to_x86.h index ab2c846..48cc942 100644 --- a/z80_to_x86.h +++ b/z80_to_x86.h @@ -62,9 +62,9 @@ void translate_z80_stream(z80_context * context, uint32_t address); void init_x86_z80_opts(x86_z80_options * options); void init_z80_context(z80_context * context, x86_z80_options * options); uint8_t * z80_get_native_address(z80_context * context, uint32_t address); -uint8_t * z80_get_native_address_trans(z80_context * context, uint32_t address); -z80_context * z80_handle_code_write(uint32_t address, z80_context * context); -void z80_run(z80_context * context); +extern uint8_t * z80_get_native_address_trans(z80_context * context, uint32_t address) asm("z80_get_native_address_trans"); +z80_context * z80_handle_code_write(uint32_t address, z80_context * context) asm("z80_handle_code_write"); +extern void z80_run(z80_context * context) asm("z80_run"); void z80_reset(z80_context * context); void zinsert_breakpoint(z80_context * context, uint16_t address, uint8_t * bp_handler); void zremove_breakpoint(z80_context * context, uint16_t address); diff --git a/zruntime.S b/zruntime.S index 4445842..1883239 100644 --- a/zruntime.S +++ b/zruntime.S @@ -125,7 +125,7 @@ z80_read_bank: add $3, %ebp push %rsi mov 144(%rsi), %rsi /* get system context pointer */ - cmp $0, 120(%rsi) /* check bus busy flag */ + cmpb $0, 120(%rsi) /* check bus busy flag */ pop %rsi jne bus_busy z80_read_bank_cont: @@ -243,7 +243,7 @@ z80_read_bank_word: add $3, %ebp /* first read typically has 3 wait states */ push %rsi mov 144(%rsi), %rsi /* get system context pointer */ - cmp $0, 120(%rsi) /* check bus busy flag */ + cmpb $0, 120(%rsi) /* check bus busy flag */ pop %rsi jne bus_busy_word z80_read_bank_word_cont: @@ -256,7 +256,7 @@ z80_read_bank_word_cont: add $4, %ebp /* second read typically has 4 wait states */ push %rsi mov 144(%rsi), %rsi /* get system context pointer */ - cmp $0, 120(%rsi) /* check bus busy flag */ + cmpb $0, 120(%rsi) /* check bus busy flag */ pop %rsi jne bus_busy_word2 z80_read_bank_word_cont2: -- cgit v1.2.3 From 85cfa2bb7834854e587f466cb877b4bf5ed7966e Mon Sep 17 00:00:00 2001 From: Mike Pavone Date: Mon, 23 Jun 2014 11:05:55 -0400 Subject: Fix x86_rrindex_sizedir. Pass the correct scale to mov_rindexr in gen_mem_fun. BlastEm now sort of works on OS X. Runs reliably from lldb, but only intermittently from the shell --- gen_x86.c | 10 ++++------ m68k_to_x86.c | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/gen_x86.c b/gen_x86.c index c062ac8..2ec4c00 100644 --- a/gen_x86.c +++ b/gen_x86.c @@ -359,13 +359,11 @@ uint8_t * x86_rrindex_sizedir(uint8_t * out, uint8_t opcode, uint8_t reg, uint8_ opcode |= BIT_SIZE; } *(out++) = opcode | dir; - *(out++) = MODE_REG_INDIRECT | base | (RSP << 3); - if (base == RSP) { - if (scale == 4) { - scale = 3; - } - *(out++) = scale << 6 | (index << 3) | base; + *(out++) = MODE_REG_INDIRECT | RSP | (reg << 3); + if (scale == 4) { + scale = 3; } + *(out++) = scale << 6 | (index << 3) | base; return out; } diff --git a/m68k_to_x86.c b/m68k_to_x86.c index 959d62b..886cc08 100644 --- a/m68k_to_x86.c +++ b/m68k_to_x86.c @@ -4499,7 +4499,7 @@ code_ptr gen_mem_fun(cpu_options * opts, memmap_chunk * memmap, uint32_t num_chu dst = mov_rrind(dst, SCRATCH1, SCRATCH2, tmp_size); } else { dst = mov_ir(dst, (intptr_t)memmap[chunk].buffer, SCRATCH2, SZ_PTR); - dst = mov_rindexr(dst, SCRATCH2, SCRATCH1, 1, SCRATCH1, tmp_size); + dst = mov_rindexr(dst, SCRATCH2, SCRATCH1, 0, SCRATCH1, tmp_size); } } if (size != tmp_size && !is_write) { -- cgit v1.2.3 From f1a97be9f7d1a939b3b1920c1764bf872edef10f Mon Sep 17 00:00:00 2001 From: Mike Pavone Date: Mon, 23 Jun 2014 11:46:56 -0400 Subject: Save and restore guest address in the write function for a code memory chunk in the "slow" path for inconvenient host addresses. This fixes an intermittent crash on OSX in the code that checks whether the memory written may contain code --- m68k_to_x86.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/m68k_to_x86.c b/m68k_to_x86.c index 886cc08..b46a5c3 100644 --- a/m68k_to_x86.c +++ b/m68k_to_x86.c @@ -4492,11 +4492,17 @@ code_ptr gen_mem_fun(cpu_options * opts, memmap_chunk * memmap, uint32_t num_chu } } else { if (is_write) { + if (memmap[chunk].flags & MMAP_CODE) { + dst = push_r(dst, SCRATCH2); + } dst = push_r(dst, SCRATCH1); dst = mov_ir(dst, (intptr_t)memmap[chunk].buffer, SCRATCH1, SZ_PTR); dst = add_rr(dst, SCRATCH1, SCRATCH2, SZ_PTR); dst = pop_r(dst, SCRATCH1); dst = mov_rrind(dst, SCRATCH1, SCRATCH2, tmp_size); + if (memmap[chunk].flags & MMAP_CODE) { + dst = pop_r(dst, SCRATCH2); + } } else { dst = mov_ir(dst, (intptr_t)memmap[chunk].buffer, SCRATCH2, SZ_PTR); dst = mov_rindexr(dst, SCRATCH2, SCRATCH1, 0, SCRATCH1, tmp_size); -- cgit v1.2.3 From 8a7f8bc09c88e9446d475127a82df23a1dcb0c75 Mon Sep 17 00:00:00 2001 From: Mike Pavone Date: Mon, 23 Jun 2014 13:12:04 -0400 Subject: Ensure proper stack alignment when the Z80 calls into C code. This fixes a crash in optimized builds on OSX --- zruntime.S | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/zruntime.S b/zruntime.S index 1883239..a7bac3f 100644 --- a/zruntime.S +++ b/zruntime.S @@ -150,7 +150,15 @@ z80_read_ym2612: call z80_save_context mov %r13w, %di push %rsi + test $8, %rsp + jnz 0f call z80_read_ym + jmp 1f +0: + sub $8, %rsp + call z80_read_ym + add $8, %rsp +1: pop %rsi mov %al, %r13b call z80_load_context @@ -196,7 +204,15 @@ z80_write_ym2612: call z80_save_context mov %r14w, %di mov %r13b, %dl + test $8, %rsp + jnz 0f + call z80_write_ym + jmp 1f +0: + sub $8, %rsp call z80_write_ym + add $8, %rsp +1: mov %rax, %rsi jmp z80_load_context z80_write_bank_reg: @@ -219,7 +235,15 @@ z80_write_vdp: call z80_save_context mov %r14w, %di mov %r13b, %dl + test $8, %rsp + jnz 0f + call z80_vdp_port_write + jmp 1f +0: + sub $8, %rsp call z80_vdp_port_write + add $8, %rsp +1: mov %rax, %rsi jmp z80_load_context -- cgit v1.2.3