changeset 2037:b0b0c31338c3

Implement TMSS VDP lock
author Michael Pavone <pavone@retrodev.com>
date Sun, 07 Mar 2021 22:44:33 -0800
parents 45c4b74e7676
children 5b51f03b2227
files genesis.c genesis.h
diffstat 2 files changed, 18 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/genesis.c	Sun Mar 07 22:43:51 2021 -0800
+++ b/genesis.c	Sun Mar 07 22:44:33 2021 -0800
@@ -519,6 +519,10 @@
 	if (vdp_port & 0x2700E0) {
 		fatal_error("machine freeze due to write to address %X\n", 0xC00000 | vdp_port);
 	}
+	genesis_context * gen = context->system;
+	if (!gen->vdp_unlocked) {
+		fatal_error("machine freeze due to VDP write to %X without TMSS unlock\n", 0xC00000 | vdp_port);
+	}
 	vdp_port &= 0x1F;
 	//printf("vdp_port write: %X, value: %X, cycle: %d\n", vdp_port, value, context->current_cycle);
 #ifdef REFRESH_EMULATION
@@ -529,7 +533,6 @@
 	last_sync_cycle = context->current_cycle;
 #endif
 	sync_components(context, 0);
-	genesis_context * gen = context->system;
 	vdp_context *v_context = gen->vdp;
 	uint32_t before_cycle = v_context->cycles;
 	if (vdp_port < 0x10) {
@@ -658,6 +661,10 @@
 	if (vdp_port & 0x2700E0) {
 		fatal_error("machine freeze due to read from address %X\n", 0xC00000 | vdp_port);
 	}
+	genesis_context *gen = context->system;
+	if (!gen->vdp_unlocked) {
+		fatal_error("machine freeze due to VDP read from %X without TMSS unlock\n", 0xC00000 | vdp_port);
+	}
 	vdp_port &= 0x1F;
 	uint16_t value;
 #ifdef REFRESH_EMULATION
@@ -668,7 +675,6 @@
 	last_sync_cycle = context->current_cycle;
 #endif
 	sync_components(context, 0);
-	genesis_context *gen = context->system;
 	vdp_context * v_context = gen->vdp;
 	uint32_t before_cycle = v_context->cycles;
 	if (vdp_port < 0x10) {
@@ -1168,6 +1174,11 @@
 	}
 }
 
+static void check_tmss_lock(genesis_context *gen)
+{
+	gen->vdp_unlocked = gen->tmss_lock[0] == 'SE' && gen->tmss_lock[1] == 'GA';
+}
+
 static void *unused_write(uint32_t location, void *vcontext, uint16_t value)
 {
 	m68k_context *context = vcontext;
@@ -1175,6 +1186,7 @@
 	uint8_t has_tmss = gen->version_reg & 0xF;
 	if (has_tmss && (location == 0xA14000 || location == 0xA14002)) {
 		gen->tmss_lock[location >> 1 & 1] = value;
+		check_tmss_lock(gen);
 	} else if (has_tmss && location == 0xA14100) {
 		value &= 1;
 		if (gen->tmss != value) {
@@ -1209,6 +1221,7 @@
 			gen->tmss_lock[offset] &= 0xFF;
 			gen->tmss_lock[offset] |= value << 8;
 		}
+		check_tmss_lock(gen);
 	} else if (has_tmss && (location == 0xA14100 || location == 0xA14101)) {
 		if (location & 1) {
 			value &= 1;
@@ -1737,6 +1750,8 @@
 	uint8_t tmss = !strcmp(tern_find_ptr_default(model, "tmss", "off"), "on");
 	if (tmss) {
 		gen->version_reg |= 1;
+	} else {
+		gen->vdp_unlocked = 1;
 	}
 
 	uint8_t max_vsram = !strcmp(tern_find_ptr_default(model, "vsram", "40"), "64");
--- a/genesis.h	Sun Mar 07 22:43:51 2021 -0800
+++ b/genesis.h	Sun Mar 07 22:44:33 2021 -0800
@@ -72,6 +72,7 @@
 	uint8_t         bus_busy;
 	uint8_t         reset_requested;
 	uint8_t         tmss;
+	uint8_t         vdp_unlocked;
 	eeprom_state    eeprom;
 	nor_state       nor;
 };