diff options
author | Michael Pavone <pavone@retrodev.com> | 2018-08-14 00:07:21 -0700 |
---|---|---|
committer | Michael Pavone <pavone@retrodev.com> | 2018-08-14 00:07:21 -0700 |
commit | 7f914285b17c1b010c5a3f007f13e587126f6f4d (patch) | |
tree | c7caf557adee57425f19c5f70356fe79eed45924 | |
parent | 04063013139898718b3775dc10123a400b2c9173 (diff) |
Added J-Cart support
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | genesis.c | 10 | ||||
-rw-r--r-- | io.c | 30 | ||||
-rw-r--r-- | io.h | 2 | ||||
-rw-r--r-- | jcart.c | 87 | ||||
-rw-r--r-- | jcart.h | 12 | ||||
-rw-r--r-- | rom.db | 47 | ||||
-rw-r--r-- | romdb.c | 8 | ||||
-rw-r--r-- | romdb.h | 3 |
9 files changed, 186 insertions, 15 deletions
@@ -145,7 +145,7 @@ endif 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 @@ -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 @@ m68k_context * sync_components(m68k_context * context, uint32_t address) 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 @@ static void gamepad_down(system_header *system, uint8_t gamepad_num, uint8_t but { 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) @@ -114,15 +114,29 @@ static io_port *find_keyboard(sega_io *io) 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 @@ void io_gamepad_up(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_up(port, button); } } @@ -112,6 +112,8 @@ uint8_t io_data_read(io_port * pad, uint32_t current_cycle); 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); @@ -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 @@ -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_ @@ -565,11 +565,15 @@ e8ff759679a0df2b3f9ece37ef686f248d3cf37b { } 380000 { device EEPROM - last 3FFFFF + last 387FFF bits_read { 7 sda } } + 388000 { + device jcart + last 38FFFF + } } } 9f47fcc7bb2f5921cb1c3beb06b668ffb292cb08 { @@ -623,11 +627,15 @@ e8ff759679a0df2b3f9ece37ef686f248d3cf37b { } 380000 { device EEPROM - last 3FFFFF + last 387FFF bits_read { 7 sda } } + 388000 { + device jcart + last 38FFFF + } } } T-120096 { @@ -652,11 +660,15 @@ T-120096 { } 380000 { device EEPROM - last 3FFFFF + last 387FFF bits_read { 7 sda } } + 388000 { + device jcart + last 38FFFF + } } } MK-12056 { @@ -1321,3 +1333,32 @@ cda73e4caf53cbc8f0750b69e5e7f394ad3735d1 { } } } +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 + } + } +} @@ -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 @@ void map_iter_fun(char *key, tern_val val, uint8_t valtype, void *data) 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); } @@ -45,7 +45,8 @@ enum { MAPPER_SEGA, MAPPER_REALTEC, MAPPER_XBAND, - MAPPER_MULTI_GAME + MAPPER_MULTI_GAME, + MAPPER_JCART }; |