# HG changeset patch # User Michael Pavone # Date 1534230441 25200 # Node ID c206a422d46662bc5a0239607fd0f877af1963da # Parent 9c8f587404508390f743e6cc528d70452eb2b592 Added J-Cart support diff -r 9c8f58740450 -r c206a422d466 Makefile --- 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 diff -r 9c8f58740450 -r c206a422d466 genesis.c --- 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) diff -r 9c8f58740450 -r c206a422d466 io.c --- 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); } } diff -r 9c8f58740450 -r c206a422d466 io.h --- 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); diff -r 9c8f58740450 -r c206a422d466 jcart.c --- /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 diff -r 9c8f58740450 -r c206a422d466 jcart.h --- /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_ diff -r 9c8f58740450 -r c206a422d466 rom.db --- 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 + } + } +} diff -r 9c8f58740450 -r c206a422d466 romdb.c --- 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); } diff -r 9c8f58740450 -r c206a422d466 romdb.h --- 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 };