changeset 1610:c206a422d466

Added J-Cart support
author Michael Pavone <pavone@retrodev.com>
date Tue, 14 Aug 2018 00:07:21 -0700
parents 9c8f58740450
children dafe2a8769fd
files Makefile genesis.c io.c io.h jcart.c jcart.h rom.db romdb.c romdb.h
diffstat 9 files changed, 186 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Fri Aug 10 19:10:20 2018 -0700
+++ b/Makefile	Tue Aug 14 00:07:21 2018 -0700
@@ -145,7 +145,7 @@
 
 MAINOBJS=blastem.o system.o genesis.o debug.o gdb_remote.o vdp.o $(RENDEROBJS) io.o romdb.o hash.o menu.o xband.o \
 	realtec.o i2c.o nor.o sega_mapper.o multi_game.o megawifi.o $(NET) serialize.o $(TERMINAL) $(CONFIGOBJS) gst.o \
-	$(M68KOBJS) $(TRANSOBJS) $(AUDIOOBJS) saves.o zip.o bindings.o
+	$(M68KOBJS) $(TRANSOBJS) $(AUDIOOBJS) saves.o zip.o bindings.o jcart.o
 	
 ifdef NONUKLEAR
 CFLAGS+= -DDISABLE_NUKLEAR
--- a/genesis.c	Fri Aug 10 19:10:20 2018 -0700
+++ b/genesis.c	Tue Aug 14 00:07:21 2018 -0700
@@ -17,6 +17,7 @@
 #include "gdb_remote.h"
 #include "saves.h"
 #include "bindings.h"
+#include "jcart.h"
 #define MCLKS_NTSC 53693175
 #define MCLKS_PAL  53203395
 
@@ -330,6 +331,9 @@
 			io_adjust_cycles(gen->io.ports, context->current_cycle, deduction);
 			io_adjust_cycles(gen->io.ports+1, context->current_cycle, deduction);
 			io_adjust_cycles(gen->io.ports+2, context->current_cycle, deduction);
+			if (gen->mapper_type == MAPPER_JCART) {
+				jcart_adjust_cycles(gen, deduction);
+			}
 			context->current_cycle -= deduction;
 			z80_adjust_cycles(z_context, deduction);
 			gen->ym->current_cycle -= deduction;
@@ -1208,12 +1212,18 @@
 {
 	genesis_context *gen = (genesis_context *)system;
 	io_gamepad_down(&gen->io, gamepad_num, button);
+	if (gen->mapper_type == MAPPER_JCART) {
+		jcart_gamepad_down(gen, gamepad_num, button);
+	}
 }
 
 static void gamepad_up(system_header *system, uint8_t gamepad_num, uint8_t button)
 {
 	genesis_context *gen = (genesis_context *)system;
 	io_gamepad_up(&gen->io, gamepad_num, button);
+	if (gen->mapper_type == MAPPER_JCART) {
+		jcart_gamepad_up(gen, gamepad_num, button);
+	}
 }
 
 static void mouse_down(system_header *system, uint8_t mouse_num, uint8_t button)
--- a/io.c	Fri Aug 10 19:10:20 2018 -0700
+++ b/io.c	Tue Aug 14 00:07:21 2018 -0700
@@ -114,15 +114,29 @@
 	return NULL;
 }
 
+void io_port_gamepad_down(io_port *port, uint8_t button)
+{
+	gp_button_def *def = button_defs + button;
+	port->input[def->states[0]] |= def->value;
+	if (def->states[1] != GAMEPAD_NONE) {
+		port->input[def->states[1]] |= def->value;
+	}
+}
+
+void io_port_gamepad_up(io_port *port, uint8_t button)
+{
+	gp_button_def *def = button_defs + button;
+	port->input[def->states[0]] &= ~def->value;
+	if (def->states[1] != GAMEPAD_NONE) {
+		port->input[def->states[1]] &= ~def->value;
+	}
+}
+
 void io_gamepad_down(sega_io *io, uint8_t gamepad_num, uint8_t button)
 {
 	io_port *port = find_gamepad(io, gamepad_num);
 	if (port) {
-		gp_button_def *def = button_defs + button;
-		port->input[def->states[0]] |= def->value;
-		if (def->states[1] != GAMEPAD_NONE) {
-			port->input[def->states[1]] |= def->value;
-		}
+		io_port_gamepad_down(port, button);
 	}
 }
 
@@ -130,11 +144,7 @@
 {
 	io_port *port = find_gamepad(io, gamepad_num);
 	if (port) {
-		gp_button_def *def = button_defs + button;
-		port->input[def->states[0]] &= ~def->value;
-		if (def->states[1] != GAMEPAD_NONE) {
-			port->input[def->states[1]] &= ~def->value;
-		}
+		io_port_gamepad_up(port, button);
 	}
 }
 
--- a/io.h	Fri Aug 10 19:10:20 2018 -0700
+++ b/io.h	Tue Aug 14 00:07:21 2018 -0700
@@ -112,6 +112,8 @@
 void io_serialize(io_port *port, serialize_buffer *buf);
 void io_deserialize(deserialize_buffer *buf, void *vport);
 
+void io_port_gamepad_down(io_port *port, uint8_t button);
+void io_port_gamepad_up(io_port *port, uint8_t button);
 void io_gamepad_down(sega_io *io, uint8_t gamepad_num, uint8_t button);
 void io_gamepad_up(sega_io *io, uint8_t gamepad_num, uint8_t button);
 void io_mouse_down(sega_io *io, uint8_t mouse_num, uint8_t button);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jcart.c	Tue Aug 14 00:07:21 2018 -0700
@@ -0,0 +1,87 @@
+#include "genesis.h"
+
+static io_port *get_ports(m68k_context *m68k)
+{
+	genesis_context *gen = m68k->system;
+	if (!gen->extra) {
+		io_port *ports = calloc(2, sizeof(io_port));
+		ports[0].device_type = IO_GAMEPAD3;
+		ports[0].device.pad.gamepad_num = 3;
+		ports[1].device_type = IO_GAMEPAD3;
+		ports[1].device.pad.gamepad_num = 4;
+		io_control_write(ports, 0x40, 0);
+		io_control_write(ports + 1, 0x40, 0);
+		gen->extra = ports;
+	}
+		
+	return gen->extra;
+}
+
+void *jcart_write_w(uint32_t address, void *context, uint16_t value)
+{
+	m68k_context *m68k= context;
+	io_port *ports = get_ports(m68k);
+	value = value << 6 & 0x40;
+	io_data_write(ports, value, m68k->current_cycle);
+	io_data_write(ports + 1, value, m68k->current_cycle);
+	return context;
+}
+
+void *jcart_write_b(uint32_t address, void *context, uint8_t value)
+{
+	if (address & 1) {
+		return jcart_write_w(address, context, value);
+	}
+	return context;
+}
+
+uint16_t jcart_read_w(uint32_t address, void *context)
+{
+	m68k_context *m68k= context;
+	io_port *ports = get_ports(m68k);
+	//according to Eke, bit 14 is forced low, at least on the Micro Machines 2 cart
+	//TODO: Test behavior of actual cart
+	uint16_t value = io_data_read(ports, m68k->current_cycle) << 8/;
+	value |= io_data_read(ports + 1, m68k->current_cycle);
+	return value;
+}
+
+uint8_t jcart_read_b(uint32_t address, void *context)
+{
+	m68k_context *m68k= context;
+	io_port *ports = get_ports(m68k);
+	return io_data_read(ports + (address & 1), m68k->current_cycle);
+}
+
+void jcart_adjust_cycles(genesis_context *context, uint32_t deduction)
+{
+	io_port *ports = get_ports(context->m68k);
+	io_adjust_cycles(ports, context->m68k->current_cycle, deduction);
+	io_adjust_cycles(ports + 1, context->m68k->current_cycle, deduction);
+}
+
+void jcart_gamepad_down(genesis_context *context, uint8_t gamepad_num, uint8_t button)
+{
+	io_port *ports = get_ports(context->m68k);
+	if (gamepad_num == ports[1].device.pad.gamepad_num) {
+		ports++;
+	} else if (gamepad_num != ports[0].device.pad.gamepad_num) {
+		ports = NULL;
+	}
+	if (ports) {
+		io_port_gamepad_down(ports, button);
+	}
+}
+
+void jcart_gamepad_up(genesis_context *context, uint8_t gamepad_num, uint8_t button)
+{
+	io_port *ports = get_ports(context->m68k);
+	if (gamepad_num == ports[1].device.pad.gamepad_num) {
+		ports++;
+	} else if (gamepad_num != ports[0].device.pad.gamepad_num) {
+		ports = NULL;
+	}
+	if (ports) {
+		io_port_gamepad_up(ports, button);
+	}
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jcart.h	Tue Aug 14 00:07:21 2018 -0700
@@ -0,0 +1,12 @@
+#ifndef JCART_H_
+#define JCART_H_
+
+void *jcart_write_w(uint32_t address, void *context, uint16_t value);
+void *jcart_write_b(uint32_t address, void *context, uint8_t value);
+uint16_t jcart_read_w(uint32_t address, void *context);
+uint8_t jcart_read_b(uint32_t address, void *context);
+void jcart_adjust_cycles(genesis_context *context, uint32_t deduction);
+void jcart_gamepad_down(genesis_context *context, uint8_t gamepad_num, uint8_t button);
+void jcart_gamepad_up(genesis_context *context, uint8_t gamepad_num, uint8_t button);
+
+#endif //JCART_H_
--- a/rom.db	Fri Aug 10 19:10:20 2018 -0700
+++ b/rom.db	Tue Aug 14 00:07:21 2018 -0700
@@ -565,11 +565,15 @@
 		}
 		380000 {
 			device EEPROM
-			last 3FFFFF
+			last 387FFF
 			bits_read {
 				7 sda
 			}
 		}
+		388000 {
+			device jcart
+			last 38FFFF
+		}
 	}
 }
 9f47fcc7bb2f5921cb1c3beb06b668ffb292cb08 {
@@ -623,11 +627,15 @@
 		}
 		380000 {
 			device EEPROM
-			last 3FFFFF
+			last 387FFF
 			bits_read {
 				7 sda
 			}
 		}
+		388000 {
+			device jcart
+			last 38FFFF
+		}
 	}
 }
 T-120096 {
@@ -652,11 +660,15 @@
 		}
 		380000 {
 			device EEPROM
-			last 3FFFFF
+			last 387FFF
 			bits_read {
 				7 sda
 			}
 		}
+		388000 {
+			device jcart
+			last 38FFFF
+		}
 	}
 }
 MK-12056 {
@@ -1321,3 +1333,32 @@
 		}
 	}
 }
+222a66cdb8865a7f89e5a72418413888bb400176 {
+	#I've personally confirmed this version had a J-Cart
+	#release, but unlike the other revision it runs without it
+	name Pete Sampras Tennis
+	map {
+		0 {
+			device ROM
+			last 1FFFFF
+		}
+		200000 {
+			device jcart
+			last 3FFFFF
+		}
+	}
+}
+4c830ace4590294bb374b4cab71ebebf44d9a07a {
+	#This version will not accept input if J-Cart hardware is missing
+	name Pete Sampras Tennis
+	map {
+		0 {
+			device ROM
+			last 1FFFFF
+		}
+		200000 {
+			device jcart
+			last 3FFFFF
+		}
+	}
+}
--- a/romdb.c	Fri Aug 10 19:10:20 2018 -0700
+++ b/romdb.c	Tue Aug 14 00:07:21 2018 -0700
@@ -12,6 +12,7 @@
 #include "sega_mapper.h"
 #include "multi_game.h"
 #include "megawifi.h"
+#include "jcart.h"
 #include "blastem.h"
 
 #define DOM_TITLE_START 0x120
@@ -819,6 +820,13 @@
 			warning("ROM uses MegaWiFi, but it is disabled\n");
 			return;
 		}
+	} else if (!strcmp(dtype, "jcart")) {
+		state->info->mapper_type = MAPPER_JCART;
+		map->write_16 = jcart_write_w;
+		map->write_8 = jcart_write_b;
+		map->read_16 = jcart_read_w;
+		map->read_8 = jcart_read_b;
+		map->mask = 0xFFFFFF;
 	} else {
 		fatal_error("Invalid device type %s for ROM DB map entry %d with address %s\n", dtype, state->index, key);
 	}
--- a/romdb.h	Fri Aug 10 19:10:20 2018 -0700
+++ b/romdb.h	Tue Aug 14 00:07:21 2018 -0700
@@ -45,7 +45,8 @@
 	MAPPER_SEGA,
 	MAPPER_REALTEC,
 	MAPPER_XBAND,
-	MAPPER_MULTI_GAME
+	MAPPER_MULTI_GAME,
+	MAPPER_JCART
 };