changeset 594:086de8692932

Add in missing generated Z80 helper functions. Fix a small bug in Z80_HALT. Fix generation of save and load context for Z80
author Michael Pavone <pavone@retrodev.com>
date Fri, 26 Dec 2014 12:34:41 -0800
parents 5ef3fe516da9
children 68f86ca4bb32
files gen_x86.h z80_to_x86.c z80_to_x86.h
diffstat 3 files changed, 64 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/gen_x86.h	Mon Dec 22 20:55:10 2014 -0800
+++ b/gen_x86.h	Fri Dec 26 12:34:41 2014 -0800
@@ -38,6 +38,7 @@
 	CC_C,
 	CC_B = CC_C,
 	CC_NC,
+	CC_NB = CC_NC,
 	CC_Z,
 	CC_NZ,
 	CC_BE,
--- a/z80_to_x86.c	Mon Dec 22 20:55:10 2014 -0800
+++ b/z80_to_x86.c	Fri Dec 26 12:34:41 2014 -0800
@@ -870,7 +870,7 @@
 		add_rr(code, opts->gen.scratch2, opts->gen.cycles, SZ_D);
 		cmp_rr(code, opts->gen.limit, opts->gen.cycles, SZ_D);
 		code_ptr skip_last = code->cur+1;
-		jcc(code, CC_B, opts->gen.handle_cycle_limit_int);
+		jcc(code, CC_NB, code->cur+2);
 		cycles(&opts->gen, 4);
 		*skip_last = code->cur - (skip_last+1);
 		call(code, opts->gen.handle_cycle_limit_int);
@@ -1953,10 +1953,8 @@
 		int reg;
 		uint8_t size;
 		if (i < Z80_I) {
-			reg = i /2 + Z80_BC;
+			reg = i /2 + Z80_BC + (i > Z80_H ? 2 : 0);
 			size = SZ_W;
-			i++;
-
 		} else {
 			reg = i;
 			size = SZ_B;
@@ -1964,6 +1962,9 @@
 		if (options->regs[reg] >= 0) {
 			mov_rrdisp(code, options->regs[reg], options->gen.context_reg, offsetof(z80_context, regs) + i, size);
 		}
+		if (size == SZ_W) {
+			i++;
+		}
 	}
 	if (options->regs[Z80_SP] >= 0) {
 		mov_rrdisp(code, options->regs[Z80_SP], options->gen.context_reg, offsetof(z80_context, sp), SZ_W);
@@ -1983,9 +1984,8 @@
 		int reg;
 		uint8_t size;
 		if (i < Z80_I) {
-			int reg = i /2 + Z80_BC;
+			reg = i /2 + Z80_BC + (i > Z80_H ? 2 : 0);
 			size = SZ_W;
-
 		} else {
 			reg = i;
 			size = SZ_B;
@@ -1993,6 +1993,9 @@
 		if (options->regs[reg] >= 0) {
 			mov_rdispr(code, options->gen.context_reg, offsetof(z80_context, regs) + i, options->regs[reg], size);
 		}
+		if (size == SZ_W) {
+			i++;
+		}
 	}
 	if (options->regs[Z80_SP] >= 0) {
 		mov_rdispr(code, options->gen.context_reg, offsetof(z80_context, sp), options->regs[Z80_SP], SZ_W);
@@ -2035,8 +2038,10 @@
 	*no_sync = code->cur - no_sync;
 	//return to caller of z80_run
 	retn(code);
+	
+	options->gen.handle_code_write = (code_ptr)z80_handle_code_write;
 
-	options->read_8 = gen_mem_fun(&options->gen, chunks, num_chunks, READ_8, NULL);
+	options->read_8 = gen_mem_fun(&options->gen, chunks, num_chunks, READ_8, &options->read_8_noinc);
 	options->write_8 = gen_mem_fun(&options->gen, chunks, num_chunks, WRITE_8, &options->write_8_noinc);
 
 	options->gen.handle_cycle_limit_int = code->cur;
@@ -2105,6 +2110,55 @@
 	check_cycles(&options->gen);
 	cycles(&options->gen, 4);
 	retn(code);
+	
+	options->read_16 = code->cur;
+	cycles(&options->gen, 3);
+	check_cycles(&options->gen);
+	//TODO: figure out how to handle the extra wait state for word reads to bank area
+	//may also need special handling to avoid too much stack depth when acces is blocked
+	push_r(code, options->gen.scratch1);
+	call(code, options->read_8_noinc);
+	mov_rr(code, options->gen.scratch1, options->gen.scratch2, SZ_B);
+	pop_r(code, options->gen.scratch1);
+	add_ir(code, 1, options->gen.scratch1, SZ_W);
+	cycles(&options->gen, 3);
+	check_cycles(&options->gen);
+	call(code, options->read_8_noinc);
+	shl_ir(code, 8, options->gen.scratch1, SZ_W);
+	mov_rr(code, options->gen.scratch2, options->gen.scratch1, SZ_B);
+	retn(code);
+	
+	options->write_16_highfirst = code->cur;
+	cycles(&options->gen, 3);
+	check_cycles(&options->gen);
+	push_r(code, options->gen.scratch2);
+	push_r(code, options->gen.scratch1);
+	add_ir(code, 1, options->gen.scratch2, SZ_W);
+	shr_ir(code, 8, options->gen.scratch1, SZ_W);
+	call(code, options->write_8_noinc);
+	pop_r(code, options->gen.scratch1);
+	pop_r(code, options->gen.scratch2);
+	cycles(&options->gen, 3);
+	check_cycles(&options->gen);
+	//TODO: Check if we can get away with TCO here
+	call(code, options->write_8_noinc);
+	retn(code);
+	
+	options->write_16_lowfirst = code->cur;
+	cycles(&options->gen, 3);
+	check_cycles(&options->gen);
+	push_r(code, options->gen.scratch2);
+	push_r(code, options->gen.scratch1);
+	call(code, options->write_8_noinc);
+	pop_r(code, options->gen.scratch1);
+	pop_r(code, options->gen.scratch2);
+	add_ir(code, 1, options->gen.scratch2, SZ_W);
+	shr_ir(code, 8, options->gen.scratch1, SZ_W);
+	cycles(&options->gen, 3);
+	check_cycles(&options->gen);
+	//TODO: Check if we can get away with TCO here
+	call(code, options->write_8_noinc);
+	retn(code);
 
 	options->retrans_stub = code->cur;
 	//pop return address
@@ -2130,6 +2184,7 @@
 	push_r(code, R14);
 	push_r(code, R15);
 	mov_rr(code, RDI, options->gen.context_reg, SZ_PTR);
+	call(code, options->load_context_scratch);
 	cmp_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, extra_pc), SZ_PTR);
 	code_ptr no_extra = code->cur+1;
 	jcc(code, CC_Z, no_extra);
--- a/z80_to_x86.h	Mon Dec 22 20:55:10 2014 -0800
+++ b/z80_to_x86.h	Fri Dec 26 12:34:41 2014 -0800
@@ -32,6 +32,7 @@
 	code_ptr        do_sync;
 	code_ptr        read_8;
 	code_ptr        write_8;
+	code_ptr        read_8_noinc;
 	code_ptr        write_8_noinc;
 	code_ptr        read_16;
 	code_ptr        write_16_highfirst;