changeset 1753:33ec5df77fac

Integration of new Z80 core is sort of working now
author Michael Pavone <pavone@retrodev.com>
date Tue, 12 Feb 2019 09:58:04 -0800
parents d6d4c006a7b3
children 043cf458704c
files backend.c backend.h cpu_dsl.py genesis.c z80.cpu z80_util.c
diffstat 6 files changed, 148 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/backend.c	Sun Feb 10 11:58:23 2019 -0800
+++ b/backend.c	Tue Feb 12 09:58:04 2019 -0800
@@ -93,6 +93,31 @@
 	return NULL;
 }
 
+void * get_native_write_pointer(uint32_t address, void ** mem_pointers, cpu_options * opts)
+{
+	memmap_chunk const * memmap = opts->memmap;
+	address &= opts->address_mask;
+	for (uint32_t chunk = 0; chunk < opts->memmap_chunks; chunk++)
+	{
+		if (address >= memmap[chunk].start && address < memmap[chunk].end) {
+			if (!(memmap[chunk].flags & (MMAP_WRITE))) {
+				return NULL;
+			}
+			uint8_t * base = memmap[chunk].flags & MMAP_PTR_IDX
+				? mem_pointers[memmap[chunk].ptr_index]
+				: memmap[chunk].buffer;
+			if (!base) {
+				if (memmap[chunk].flags & MMAP_AUX_BUFF) {
+					return memmap[chunk].buffer + (address & memmap[chunk].aux_mask);
+				}
+				return NULL;
+			}
+			return base + (address & memmap[chunk].mask);
+		}
+	}
+	return NULL;
+}
+
 uint16_t read_word(uint32_t address, void **mem_pointers, cpu_options *opts, void *context)
 {
 	memmap_chunk const *chunk = find_map_chunk(address, opts, 0, NULL);
--- a/backend.h	Sun Feb 10 11:58:23 2019 -0800
+++ b/backend.h	Tue Feb 12 09:58:04 2019 -0800
@@ -95,6 +95,7 @@
 
 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);
+void * get_native_write_pointer(uint32_t address, void ** mem_pointers, cpu_options * opts);
 uint16_t read_word(uint32_t address, void **mem_pointers, cpu_options *opts, void *context);
 uint8_t read_byte(uint32_t address, void **mem_pointers, cpu_options *opts, void *context);
 void write_byte(uint32_t address, uint8_t value, void **mem_pointers, cpu_options *opts, void *context);
--- a/cpu_dsl.py	Sun Feb 10 11:58:23 2019 -0800
+++ b/cpu_dsl.py	Tue Feb 12 09:58:04 2019 -0800
@@ -696,7 +696,7 @@
 	'sext': Op(_sext).addImplementation('c', 2, _sextCImpl),
 	'ocall': Op().addImplementation('c', None, lambda prog, params: '\n\t{pre}{fun}({args});'.format(
 		pre = prog.prefix, fun = params[0], args = ', '.join(['context'] + [str(p) for p in params[1:]])
-	)),
+	) + _updateSyncCImpl(prog, params)),
 	'cycles': Op().addImplementation('c', None,
 		lambda prog, params: '\n\tcontext->cycles += context->opts->gen.clock_divider * {0};'.format(
 			params[0]
--- a/genesis.c	Sun Feb 10 11:58:23 2019 -0800
+++ b/genesis.c	Tue Feb 12 09:58:04 2019 -0800
@@ -155,6 +155,7 @@
 	} else {
 		gen->z80->mem_pointers[1] = NULL;
 	}
+	z80_invalidate_code_range(gen->z80, 0x8000, 0xFFFF);
 }
 
 static void bus_arbiter_deserialize(deserialize_buffer *buf, void *vgen)
@@ -293,20 +294,27 @@
 #define dputs
 #endif
 
-#ifndef NEW_CORE
 static void z80_next_int_pulse(z80_context * z_context)
 {
 	genesis_context * gen = z_context->system;
+#ifdef NEW_CORE
+	z_context->int_cycle = vdp_next_vint_z80(gen->vdp);
+	z_context->int_end_cycle = z_context->int_cycle + Z80_INT_PULSE_MCLKS;
+	z_context->int_value = 0xFF;
+#else
 	z_context->int_pulse_start = vdp_next_vint_z80(gen->vdp);
 	z_context->int_pulse_end = z_context->int_pulse_start + Z80_INT_PULSE_MCLKS;
 	z_context->im2_vector = 0xFF;
+#endif
 }
-#endif
 
 static void sync_z80(z80_context * z_context, uint32_t mclks)
 {
 #ifndef NO_Z80
 	if (z80_enabled) {
+#ifdef NEW_CORE
+		z80_next_int_pulse(z_context);
+#endif
 		z80_run(z_context, mclks);
 	} else
 #endif
--- a/z80.cpu	Sun Feb 10 11:58:23 2019 -0800
+++ b/z80.cpu	Tue Feb 12 09:58:04 2019 -0800
@@ -54,10 +54,12 @@
 	io_chunks 32
 	io_mask 32
 	int_cycle 32
+	int_end_cycle 32
 	int_value 8
 	nmi_cycle 32
 	system ptrvoid
-	fastmem ptr8 64
+	fastread ptr8 64
+	fastwrite ptr8 64
 	mem_pointers ptr8 4
 	
 flags
@@ -81,6 +83,7 @@
 	add 1 pc pc
 	
 z80_run_op
+	#printf "Z80: %X @ %d\n" pc cycles
 	z80_op_fetch
 	dispatch scratch1
 
@@ -88,7 +91,6 @@
 	cmp int_cycle cycles
 	if >=U
 	
-	mov 0xFFFFFFFF int_cycle
 	mov 0 iff1
 	mov 0 iff2
 	cycles 6
@@ -1535,12 +1537,18 @@
 11110011 di
 	mov 0 iff1
 	mov 0 iff2
-	#TODO: update interrupt/sync cycle
+	update_sync
 
 11111011 ei
 	mov 1 iff1
 	mov 1 iff2
-	#TODO: update interrupt/sync cycle
+	update_sync
+	cmp int_cycle cycles
+	if >=U
+	
+	add 1 cycles int_cycle
+	
+	end
 
 ed 01D00110 im0
 	mov 0 imode
@@ -1654,6 +1662,25 @@
 	lsl pch 8 pch
 	or pch pc pc
 	
+ed 01001101 reti
+	local pch 16
+	cycles 1
+	meta high pch
+	meta low pc
+	z80_pop
+	lsl pch 8 pch
+	or pch pc pc
+	
+ed 01NN1101 retn
+	mov iff2 iff1
+	local pch 16
+	cycles 1
+	meta high pch
+	meta low pc
+	z80_pop
+	lsl pch 8 pch
+	or pch pc pc
+	
 11CCC000 ret_cond
 	local pch 16
 	cycles 1
@@ -1691,6 +1718,60 @@
 	mov main.R scratch1
 	ocall io_write8
 	
+z80_outi_outd
+	arg change 16
+	local tmp 8
+	cycles 1
+	z80_fetch_hl
+	
+	and 0x80 scratch1 nflag
+	
+	lsl h 8 scratch2
+	or l scratch2 scratch2
+	add change scratch2 scratch2
+	mov scratch2 l
+	lsr scratch2 8 h
+	
+	add l scratch1 tmp
+	update_flags C
+	and 7 tmp tmp
+	
+	lsl 8 b scratch2
+	or c scratch2 scratch2
+	ocall io_write8
+	
+	lsl 8 b wz
+	or c wz wz
+	
+	sub 1 b b
+	update_flags SZYX
+	xor b tmp tmp
+	update_flags P
+	lsr chflags 4 tmp
+	or tmp chflags chflags
+	
+ed 10100011 outi
+	z80_outi_outd 1
+
+ed 10110011 otir
+	z80_outi_outd 1
+	if zflag
+	else
+	sub 2 pc pc
+	cycles 5
+	end
+	
+ed 10101011 outd
+	z80_outi_outd -1
+	
+ed 10111011 otdr
+	z80_outi_outd -1
+	if zflag
+	else
+	sub 2 pc pc
+	cycles 5
+	end
+	
 00000111 rlca
 	rol a 1 a
 	update_flags YH0XN0C
--- a/z80_util.c	Sun Feb 10 11:58:23 2019 -0800
+++ b/z80_util.c	Tue Feb 12 09:58:04 2019 -0800
@@ -3,7 +3,7 @@
 void z80_read_8(z80_context *context)
 {
 	context->cycles += 3 * context->opts->gen.clock_divider;
-	uint8_t *fast = context->fastmem[context->scratch1 >> 10];
+	uint8_t *fast = context->fastread[context->scratch1 >> 10];
 	if (fast) {
 		context->scratch1 = fast[context->scratch1 & 0x3FF];
 	} else {
@@ -14,7 +14,7 @@
 void z80_write_8(z80_context *context)
 {
 	context->cycles += 3 * context->opts->gen.clock_divider;
-	uint8_t *fast = context->fastmem[context->scratch2 >> 10];
+	uint8_t *fast = context->fastwrite[context->scratch2 >> 10];
 	if (fast) {
 		fast[context->scratch2 & 0x3FF] = context->scratch1;
 	} else {
@@ -84,24 +84,19 @@
 	context->io_map = (memmap_chunk *)tmp_io_chunks;
 	context->io_chunks = tmp_num_io_chunks;
 	context->io_mask = tmp_io_mask;
-	context->int_cycle = context->nmi_cycle = 0xFFFFFFFFU;
-	for(uint32_t address = 0; address < 0x10000; address+=1024)
-	{
-		uint8_t *start = get_native_pointer(address, (void**)context->mem_pointers, &options->gen);
-		if (start) {
-			uint8_t *end = get_native_pointer(address + 1023, (void**)context->mem_pointers, &options->gen);
-			if (end && end - start == 1023) {
-				context->fastmem[address >> 10] = start;
-			}
-		}
-	}
+	context->int_cycle = context->int_end_cycle = context->nmi_cycle = 0xFFFFFFFFU;
+	z80_invalidate_code_range(context, 0, 0xFFFF);
 	return context;
 }
 
 uint32_t z80_sync_cycle(z80_context *context, uint32_t target_cycle)
 {
 	if (context->iff1 && context->int_cycle < target_cycle) {
-		target_cycle = context->int_cycle;
+		if (context->cycles > context->int_end_cycle) {
+			context->int_cycle = 0xFFFFFFFFU;
+		} else {
+			target_cycle = context->int_cycle;
+		}
 	};
 	if (context->nmi_cycle < target_cycle) {
 		target_cycle = context->nmi_cycle;
@@ -182,7 +177,7 @@
 
 void z80_invalidate_code_range(z80_context *context, uint32_t startA, uint32_t endA)
 {
-	for(startA &= ~0x3FF; startA += 1024; startA < endA)
+	for(startA &= ~0x3FF; startA < endA; startA += 1024)
 	{
 		uint8_t *start = get_native_pointer(startA, (void**)context->mem_pointers, &context->opts->gen);
 		if (start) {
@@ -191,7 +186,15 @@
 				start = NULL;
 			}
 		}
-		context->fastmem[startA >> 10] = start;
+		context->fastread[startA >> 10] = start;
+		start = get_native_write_pointer(startA, (void**)context->mem_pointers, &context->opts->gen);
+		if (start) {
+			uint8_t *end = get_native_write_pointer(startA + 1023, (void**)context->mem_pointers, &context->opts->gen);
+			if (!end || end - start != 1023) {
+				start = NULL;
+			}
+		}
+		context->fastwrite[startA >> 10] = start;
 	}
 }
 
@@ -205,6 +208,13 @@
 			context->int_cycle = 0;
 		}
 	}
+	if (context->int_end_cycle != 0xFFFFFFFFU) {
+		if (context->int_end_cycle > deduction) {
+			context->int_end_cycle -= deduction;
+		} else {
+			context->int_end_cycle = 0;
+		}
+	}
 	if (context->nmi_cycle != 0xFFFFFFFFU) {
 		if (context->nmi_cycle > deduction) {
 			context->nmi_cycle -= deduction;