diff --git a/source/cart_hw/cart_hw.c b/source/cart_hw/cart_hw.c index 61986fe..57d96a8 100644 --- a/source/cart_hw/cart_hw.c +++ b/source/cart_hw/cart_hw.c @@ -32,20 +32,7 @@ extern int emulate_address_error; /* Global Variables */ -T_CART_HW cart_hw; -uint8 j_cart; -uint8 *default_rom; -int old_system[2] = {-1,-1}; - -/* Function prototypes */ -void default_time_w(uint32 address, uint32 data); -void special_mapper_w(uint32 address, uint32 data); -void realtec_mapper_w(uint32 address, uint32 data); -void seganet_mapper_w(uint32 address, uint32 data); -uint32 radica_mapper_r(uint32 address); -void default_regs_w(uint32 address, uint32 data); -uint32 default_regs_r(uint32 address); -void special_regs_w(uint32 address, uint32 data); +T_CART cart; /* Cart database entry */ typedef struct @@ -57,64 +44,75 @@ typedef struct T_CART_HW cart_hw; /* hardware description */ } T_CART_ENTRY; +/* Function prototypes */ +static void sega_mapper_w(uint32 address, uint32 data); +static void special_mapper_w(uint32 address, uint32 data); +static void realtec_mapper_w(uint32 address, uint32 data); +static void seganet_mapper_w(uint32 address, uint32 data); +static uint32 radica_mapper_r(uint32 address); +static void default_time_w(uint32 address, uint32 data); +static void default_regs_w(uint32 address, uint32 data); +static uint32 default_regs_r(uint32 address); +static void special_regs_w(uint32 address, uint32 data); + /* Games that need extra hardware emulation: - copy protection device - custom ROM banking device */ static const T_CART_ENTRY rom_database[CART_CNT] = { -/* Game no Kanzume Otokuyou */ - {0x0000,0xf9d1,0,0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},0,0,0,seganet_mapper_w,0,0}}, -/* RADICA (Volume 1) (not byteswapped) */ - {0x0000,0x2326,0,0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},0,1,radica_mapper_r,0,0,0}}, -/* RADICA (Volume 2) */ - {0x4f10,0x0836,0,0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},0,1,radica_mapper_r,0,0,0}}, -/* RADICA (Volume 1) */ - {0xf424,0x9f82,0,0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},0,1,radica_mapper_r,0,0,0}}, /* Funny World & Balloon Boy */ - {0x0000,0x06ab,0x40,0x40,{{0,0,0,0},{0,0,0,0},{0,0,0,0},1,1,0,0,0,realtec_mapper_w}}, + {0x0000,0x06ab,0x40,0x40,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},1,0,1,NULL,NULL,NULL,realtec_mapper_w}}, /* Whac-a-Critter */ - {0xffff,0xf863,0x40,0x40,{{0,0,0,0},{0,0,0,0},{0,0,0,0},1,1,0,0,0,realtec_mapper_w}}, + {0xffff,0xf863,0x40,0x40,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},1,0,1,NULL,NULL,NULL,realtec_mapper_w}}, /* Earth Defense */ - {0xffff,0x44fb,0x40,0x40,{{0,0,0,0},{0,0,0,0},{0,0,0,0},1,1,0,0,0,realtec_mapper_w}}, -/* Super Mario 2 1998 */ - {0xffff,0x0474,0,0,{{0x0a,0,0,0},{0xffffff,0,0,0},{0xa13000,0,0,0},0,0,default_regs_r,0,0,0}}, -/* Super Mario 2 1998 */ - {0x2020,0xb4eb,0,0,{{0x1c,0,0,0},{0xffffff,0,0,0},{0xa13000,0,0,0},0,0,default_regs_r,0,0,0}}, -/* Supper Bubble Bobble */ - {0x0000,0x16cd,0x40,0x40,{{0x55,0x0f,0,0},{0xffffff,0xffffff,0,0},{0x400000,0x400002,0,0},0,0,0,0,default_regs_r,0}}, -/* Mahjong Lover */ - {0x0000,0x7037,0x40,0x40,{{0x90,0xd3,0,0},{0xffffff,0xffffff,0,0},{0x400000,0x401000,0,0},0,0,0,0,default_regs_r,0}}, -/* Lion King 2 */ - {0xffff,0x1d9b,0x40,0x40,{{0,0,0,0},{0xfffffd,0xfffffd,0,0},{0x400000,0x400004,0,0},0,0,0,0,default_regs_r,default_regs_w}}, -/* Squirell King */ - {0x0000,0x8ec8,0x40,0x40,{{0,0,0,0},{0xfffffd,0xfffffd,0,0},{0x400000,0x400004,0,0},0,0,0,0,default_regs_r,default_regs_w}}, -/* Rockman X3 */ - {0x0000,0x9d0e,0x40,0x40,{{0x0c,0x88,0,0},{0xffffff,0xffffff,0,0},{0xa13000,0x400004,0,0},0,0,default_regs_r,0,default_regs_r,0}}, -/* A Bug's Life */ - {0x7f7f,0x2aad,0,0,{{0x28,0x1f,0x01,0},{0xffffff,0xffffff,0xffffff,0},{0xa13000,0xa13002,0xa1303e,0},0,0,default_regs_r,0,0,0}}, -/* King of Fighter 99 */ - {0x0000,0x21e,0,0,{{0x00,0x01,0x1f,0},{0xffffff,0xffffff,0xffffff,0},{0xa13000,0xa13002,0xa1303e,0},0,0,default_regs_r,0,0,0}}, -/* Pocket Monster */ - {0xd6fc,0x1eb1,0,0,{{0x00,0x01,0x1f,0},{0xffffff,0xffffff,0xffffff,0},{0xa13000,0xa13002,0xa1303e,0},0,0,default_regs_r,0,0,0}}, + {0xffff,0x44fb,0x40,0x40,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},1,0,1,NULL,NULL,NULL,realtec_mapper_w}}, +/* RADICA (Volume 1) (not byteswapped) */ + {0x0000,0x2326,0x00,0x00,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},0,0,1,radica_mapper_r,NULL,NULL,NULL}}, +/* RADICA (Volume 2) */ + {0x4f10,0x0836,0x00,0x00,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},0,0,1,radica_mapper_r,NULL,NULL,NULL}}, +/* RADICA (Volume 1) */ + {0xf424,0x9f82,0x00,0x00,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},0,0,1,radica_mapper_r,NULL,NULL,NULL}}, /* Lion King 3 */ - {0x0000,0x507c,0x60,0x7f,{{0,0,0,0},{0xf0000e,0xf0000e,0xf0000e,0},{0x600000,0x600002,0x600004,0},0,1,0,0,default_regs_r,special_regs_w}}, + {0x0000,0x507c,0x60,0x7f,{{0x00,0x00,0x00,0x00},{0xf0000e,0xf0000e,0xf0000e,0x000000},{0x600000,0x600002,0x600004,0x000000},0,0,1,NULL,NULL,default_regs_r,special_regs_w}}, /* Super King Kong 99 */ - {0x0000,0x7d6e,0x60,0x7f,{{0,0,0,0},{0xf0000e,0xf0000e,0xf0000e,0},{0x600000,0x600002,0x600004,0},0,1,0,0,default_regs_r,special_regs_w}}, + {0x0000,0x7d6e,0x60,0x7f,{{0x00,0x00,0x00,0x00},{0xf0000e,0xf0000e,0xf0000e,0x000000},{0x600000,0x600002,0x600004,0x000000},0,0,1,NULL,NULL,default_regs_r,special_regs_w}}, /* Pokemon Stadium */ - {0x0000,0x843c,0x70,0x7f,{{0,0,0,0},{0,0,0,0},{0,0,0,0},0,1,0,0,0,special_regs_w}}, + {0x0000,0x843c,0x70,0x7f,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},0,0,1,NULL,NULL,default_regs_r,special_regs_w}}, +/* Lion King 2 */ + {0xffff,0x1d9b,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xfffffd,0xfffffd,0x000000,0x000000},{0x400000,0x400004,0x000000,0x000000},0,0,0,NULL,NULL,default_regs_r,default_regs_w}}, +/* Squirell King */ + {0x0000,0x8ec8,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xfffffd,0xfffffd,0x000000,0x000000},{0x400000,0x400004,0x000000,0x000000},0,0,0,NULL,NULL,default_regs_r,default_regs_w}}, +/* Supper Bubble Bobble */ + {0x0000,0x16cd,0x40,0x40,{{0x55,0x0f,0x00,0x00},{0xffffff,0xffffff,0x000000,0x000000},{0x400000,0x400002,0x000000,0x000000},0,0,0,NULL,NULL,default_regs_r,NULL}}, +/* Mahjong Lover */ + {0x0000,0x7037,0x40,0x40,{{0x90,0xd3,0x00,0x00},{0xffffff,0xffffff,0x000000,0x000000},{0x400000,0x401000,0x000000,0x000000},0,0,0,NULL,NULL,default_regs_r,NULL}}, /* Elf Wor */ - {0x0080,0x3dba,0x40,0x40,{{0x55,0x0f,0xc9,0x18},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,0,0,default_regs_r,0}}, + {0x0080,0x3dba,0x40,0x40,{{0x55,0x0f,0xc9,0x18},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,0,NULL,NULL,default_regs_r,NULL}}, /* Huan Le Tao Qi Shu - Smart Mouse */ - {0x0000,0x1a28,0x40,0x40,{{0x55,0x0f,0xaa,0xf0},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,0,0,default_regs_r,0}}, + {0x0000,0x1a28,0x40,0x40,{{0x55,0x0f,0xaa,0xf0},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,0,NULL,NULL,default_regs_r,NULL}}, /* Ya-Se Chuanshuo */ - {0xffff,0xd472,0x40,0x40,{{0x63,0x98,0xc9,0x18},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,0,0,default_regs_r,0}}, + {0xffff,0xd472,0x40,0x40,{{0x63,0x98,0xc9,0x18},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,0,NULL,NULL,default_regs_r,NULL}}, /* Soul Blade */ - {0x0000,0x0c5b,0x40,0x40,{{0x00,0x98,0xc9,0xF0},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,0,0,default_regs_r,0}}, + {0x0000,0x0c5b,0x40,0x40,{{0x00,0x98,0xc9,0xF0},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,0,NULL,NULL,default_regs_r,NULL}}, /* King of Fighter 98 */ - {0x0000,0xd0a0,0x48,0x4f,{{0xaa,0xa0,0xf0,0xa0},{0xfc0000,0xffffff,0xffffff,0xffffff},{0x480000,0x4c82c0,0x4cdda0,0x4f8820},0,0,0,0,default_regs_r,0}}, + {0x0000,0xd0a0,0x48,0x4f,{{0xaa,0xa0,0xf0,0xa0},{0xfc0000,0xffffff,0xffffff,0xffffff},{0x480000,0x4c82c0,0x4cdda0,0x4f8820},0,0,0,NULL,NULL,default_regs_r,NULL}}, /* Lian Huan Pao - Barver Battle Saga */ - {0x30b9,0x1c2a,0x40,0x40,{{0,0,0,0},{0,0,0,0},{0,0,0,0},0,0,0,0,default_regs_r,0}} + {0x30b9,0x1c2a,0x40,0x40,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},0,0,0,NULL,NULL,default_regs_r,NULL}}, +/* Rockman X3 */ + {0x0000,0x9d0e,0x40,0x40,{{0x0c,0x88,0x00,0x00},{0xffffff,0xffffff,0x000000,0x000000},{0xa13000,0x400004,0x000000,0x000000},0,0,0,default_regs_r,NULL,default_regs_r,NULL}}, +/* Super Mario 2 1998 */ + {0xffff,0x0474,0x00,0x00,{{0x0a,0x00,0x00,0x00},{0xffffff,0x000000,0x000000,0x000000},{0xa13000,0x000000,0x000000,0x000000},0,0,0,default_regs_r,NULL,NULL,NULL}}, +/* Super Mario 2 1998 */ + {0x2020,0xb4eb,0x00,0x00,{{0x1c,0x00,0x00,0x00},{0xffffff,0x000000,0x000000,0x000000},{0xa13000,0x000000,0x000000,0x000000},0,0,0,default_regs_r,NULL,NULL,NULL}}, +/* A Bug's Life */ + {0x7f7f,0x2aad,0x00,0x00,{{0x28,0x1f,0x01,0x00},{0xffffff,0xffffff,0xffffff,0x000000},{0xa13000,0xa13002,0xa1303e,0x000000},0,0,0,default_regs_r,NULL,NULL,NULL}}, +/* King of Fighter 99 */ + {0x0000,0x021e,0x00,0x00,{{0x00,0x01,0x1f,0x00},{0xffffff,0xffffff,0xffffff,0x000000},{0xa13000,0xa13002,0xa1303e,0x000000},0,0,0,default_regs_r,NULL,NULL,NULL}}, +/* Pocket Monster */ + {0xd6fc,0x1eb1,0x00,0x00,{{0x00,0x01,0x1f,0x00},{0xffffff,0xffffff,0xffffff,0x000000},{0xa13000,0xa13002,0xa1303e,0x000000},0,0,0,default_regs_r,NULL,NULL,NULL}}, +/* Game no Kanzume Otokuyou */ + {0x0000,0xf9d1,0x00,0x00,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},0,0,0,NULL,seganet_mapper_w,NULL,NULL}} }; /* temporary memory chunk */ @@ -125,64 +123,97 @@ static uint8 mem_chunk[0x10000]; Cart Hardware initialization *************************************************************/ -/* hardware that need to be reseted on power on */ -void cart_hw_reset() -{ - int i; - - /* reset bankshifting */ - if (cart_hw.bankshift) - { - for (i=0x00; i<0x40; i++) - m68k_memory_map[i].base = cart_rom + (i<<16); - } - - /* Realtec mapper */ - if (cart_hw.realtec & 1) - { - /* enable BOOTROM */ - for (i=0; i<0x40; i++) m68k_memory_map[i].base = mem_chunk; - for (i=0; i<8; i++) memcpy(mem_chunk + i*0x2000, cart_rom + 0x7e000, 0x2000); - cart_hw.realtec |= 2; - } - - /* SVP chip */ - if (svp) svp_reset(); - - /* Lock-ON */ - switch (config.lock_on) - { - case GAME_GENIE: - ggenie_reset(); - break; - - case ACTION_REPLAY: - datel_reset(); - break; - - case SONIC_KNUCKLES: - break; - - default: - break; - } - - /* save default cartridge slot mapping */ - default_rom = m68k_memory_map[0].base; -} - /* cart hardware detection */ void cart_hw_init() { - int i; + /*************************************************************************************************************** + CARTRIDGE ROM MIRRORING + *************************************************************************************************************** + + Cartridge area is mapped to $000000-$3fffff: + -> when accessing ROM, 68k address lines A1 to A21 are used by the internal cartridge hardware to decode the + full 4MB address range. + -> depending on the ROM total size, some address lines might be ignored, resulting in ROM mirroring. + + + Cartridges can use either 8-bits (x2) or 16-bits (x1, x2) Mask ROM chips, each chip size is a factor of 2 bytes: + + -> two 8-bits chips are equivalent to one 16-bits chip, no specific address decoding is required, needed + address lines are simply connected to each chip, upper address lines are ignored and data lines are + connected appropriately to each chip (D0-D7 to one chip, D8-D15 to the other one). + ROM is mirrored each N bytes where N=2^(k+1) is the total ROM size (ROM1+ROM2,ROM1+ROM2,...). + + -> one single 16-bits chip do not need specific address decoding, address lines are simply connected + depending on the ROM size, upper address lines being ignored. + ROM is mirrored each N bytes where N=2^k is the size of the ROM chip (ROM1,ROM1,ROM1,...). + + -> two 16-bits chips of the same size are equivalent to one chip of double size, address decoding generally + is the same except that specific hardware is used (one address line is generally used for chip selection, + lower ones being used to address the chips and upper ones being ignored). + ROM is mirrored continuously each N bytes where N=2^(k+1) is the total ROM size (ROM1,ROM2,ROM1,ROM2,...). + + -> two 16-bits chips with different size are mapped differently. Address decoding is done the same way as + above (one address line used for chip selection) but the ignored & required address lines differ from + one chip to another, which makes ROM mirroring different. + ROM2 size is generally half of ROM1 size and ROM are mirrored like that : ROM1,ROM2,ROM2,ROM1,ROM2,ROM2,... + + From the emulator point of view, we only need to distinguish 3 cases: + + 1/ total ROM size is a factor of 2: ROM is mirrored each 2^k bytes. + + 2/ total ROM size is not a factor of 2 and cartridge uses one or two chips of the same size (Type A): + ROM is padded up to 2^k and mirrored each 2^k bytes. + + 3/ total ROM size is not a factor of 2 and cartridge uses two chips of different sizes (Type B): + ROM is not padded and the first 2^(k-1) bytes are mirrored each 2^k bytes while the next 2^(k-2) bytes are + mirrored in the last 2^(k-2) bytes. + + ******************************************************************************************************************/ + + /* calculate nearest size with factor of 2 */ + int size = 0x10000; + while (cart.romsize > size) size <<= 1; + + /* total ROM size is not a factor of 2 */ + if ((size < MAXROMSIZE) && (cart.romsize < size)) + { + /* two chips with different size */ + if (config.romtype) + { + /* third ROM section is mirrored in the last section */ + memcpy(cart.rom + cart.romsize, cart.rom + 2*cart.romsize - size, size - cart.romsize); + } + else + { + /* ROM is padded up to 2^k bytes */ + memset(cart.rom + cart.romsize, 0xff, size - cart.romsize); + } + } + + /* special case: Sonic & Knuckles */ + /* $200000-$3fffff is mapped to external cartridge */ + if (strstr(rominfo.international,"SONIC & KNUCKLES") != NULL) + { + /* disable ROM mirroring */ + size = 0x400000; + } + + /* ROM is mirrored each 2^k bytes */ + int i = size; + while (i < 0x400000) + { + memcpy(cart.rom + i, cart.rom, size); + i += size; + } + /********************************************** DEFAULT CARTRIDGE MAPPING ***********************************************/ for (i=0; i<0x40; i++) { /* cartridge ROM */ - m68k_memory_map[i].base = cart_rom + (i<<16); + m68k_memory_map[i].base = cart.rom + (i<<16); m68k_memory_map[i].read8 = NULL; m68k_memory_map[i].read16 = NULL; m68k_memory_map[i].write8 = m68k_unused_8_w; @@ -194,7 +225,7 @@ void cart_hw_init() for (i=0x40; i<0x80; i++) { /* unused area */ - m68k_memory_map[i].base = cart_rom + (i<<16); + m68k_memory_map[i].base = cart.rom + (i<<16); m68k_memory_map[i].read8 = m68k_read_bus_8; m68k_memory_map[i].read16 = m68k_read_bus_16; m68k_memory_map[i].write8 = m68k_unused_8_w; @@ -203,10 +234,6 @@ void cart_hw_init() zbank_memory_map[i].write = zbank_unused_w; } - /* restore previous setting */ - if (old_system[0] != -1) input.system[0] = old_system[0]; - if (old_system[1] != -1) input.system[1] = old_system[1]; - /********************************************** EXTERNAL RAM ***********************************************/ @@ -240,26 +267,6 @@ void cart_hw_init() } } - /********************************************** - CARTRIDGE LOCK-ON - ***********************************************/ - switch (config.lock_on) - { - case GAME_GENIE: - ggenie_init(); - break; - - case ACTION_REPLAY: - datel_init(); - break; - - case SONIC_KNUCKLES: - break; - - default: - break; - } - /********************************************** SVP CHIP ***********************************************/ @@ -268,11 +275,11 @@ void cart_hw_init() { svp_init(); - m68k_memory_map[0x30].base = svp->dram; + m68k_memory_map[0x30].base = svp->dram; m68k_memory_map[0x30].read16 = NULL; m68k_memory_map[0x30].write16 = svp_write_dram; - m68k_memory_map[0x31].base = svp->dram + 0x10000; + m68k_memory_map[0x31].base = svp->dram + 0x10000; m68k_memory_map[0x31].read16 = NULL; m68k_memory_map[0x31].write16 = svp_write_dram; @@ -280,109 +287,89 @@ void cart_hw_init() m68k_memory_map[0x3a].read16 = svp_read_cell_2; } - - /* default GUN settings */ - input.x_offset = 0x00; - input.y_offset = 0x00; - - /********************************************** - SEGA MENACER - ***********************************************/ - if (strstr(rominfo.international,"MENACER") != NULL) - { - /* save current setting */ - if (old_system[0] == -1) old_system[0] = input.system[0]; - if (old_system[1] == -1) old_system[1] = input.system[1]; - - input.system[0] = NO_SYSTEM; - input.system[1] = SYSTEM_MENACER; - input.x_offset = 0x52; - input.y_offset = 0x00; - } - else if (strstr(rominfo.international,"T2 ; THE ARCADE GAME") != NULL) - { - /* save current setting */ - if (old_system[0] == -1) old_system[0] = input.system[0]; - if (old_system[1] == -1) old_system[1] = input.system[1]; - - input.system[0] = SYSTEM_GAMEPAD; - input.system[1] = SYSTEM_MENACER; - input.x_offset = 0x84; - input.y_offset = 0x08; - } - else if (strstr(rominfo.international,"BODY COUNT") != NULL) - { - /* save current setting */ - if (old_system[0] == -1) old_system[0] = input.system[0]; - if (old_system[1] == -1) old_system[1] = input.system[1]; - - input.system[0] = SYSTEM_MOUSE; - input.system[1] = SYSTEM_MENACER; - input.x_offset = 0x44; - input.y_offset = 0x18; - } - - /********************************************** - KONAMI JUSTIFIER - ***********************************************/ - else if (strstr(rominfo.international,"LETHAL ENFORCERSII") != NULL) - { - /* save current setting */ - if (old_system[0] == -1) old_system[0] = input.system[0]; - if (old_system[1] == -1) old_system[1] = input.system[1]; - - input.system[0] = SYSTEM_GAMEPAD; - input.system[1] = SYSTEM_JUSTIFIER; - input.x_offset = 0x18; - input.y_offset = 0x00; - } - else if (strstr(rominfo.international,"LETHAL ENFORCERS") != NULL) - { - /* save current setting */ - if (old_system[0] == -1) old_system[0] = input.system[0]; - if (old_system[1] == -1) old_system[1] = input.system[1]; - - input.system[0] = SYSTEM_GAMEPAD; - input.system[1] = SYSTEM_JUSTIFIER; - input.x_offset = 0x00; - input.y_offset = 0x00; - } - /********************************************** J-CART ***********************************************/ - j_cart = 0; - if (((strstr(rominfo.product,"00000000") != NULL) && (rominfo.checksum == 0x168b)) || /* Super Skidmarks, Micro Machines Military*/ - ((strstr(rominfo.product,"00000000") != NULL) && (rominfo.checksum == 0x165e)) || /* Pete Sampras Tennis (1991), Micro Machines 96 */ - ((strstr(rominfo.product,"00000000") != NULL) && (rominfo.checksum == 0xcee0)) || /* Micro Machines Military (bad) */ - ((strstr(rominfo.product,"00000000") != NULL) && (rominfo.checksum == 0x2c41)) || /* Micro Machines 96 (bad) */ - ((strstr(rominfo.product,"XXXXXXXX") != NULL) && (rominfo.checksum == 0xdf39)) || /* Sampras Tennis 96 */ - ((strstr(rominfo.product,"T-123456") != NULL) && (rominfo.checksum == 0x1eae)) || /* Sampras Tennis 96 */ - ((strstr(rominfo.product,"T-120066") != NULL) && (rominfo.checksum == 0x16a4)) || /* Pete Sampras Tennis (1994)*/ - (strstr(rominfo.product,"T-120096") != NULL)) /* Micro Machines 2 */ + cart.hw.jcart = 0; + if (((strstr(rominfo.product,"00000000") != NULL) && (rominfo.checksum == 0x168b)) || /* Super Skidmarks, Micro Machines Military*/ + ((strstr(rominfo.product,"00000000") != NULL) && (rominfo.checksum == 0x165e)) || /* Pete Sampras Tennis (1991), Micro Machines 96 */ + ((strstr(rominfo.product,"00000000") != NULL) && (rominfo.checksum == 0xcee0)) || /* Micro Machines Military (bad) */ + ((strstr(rominfo.product,"00000000") != NULL) && (rominfo.checksum == 0x2c41)) || /* Micro Machines 96 (bad) */ + ((strstr(rominfo.product,"XXXXXXXX") != NULL) && (rominfo.checksum == 0xdf39)) || /* Sampras Tennis 96 */ + ((strstr(rominfo.product,"T-123456") != NULL) && (rominfo.checksum == 0x1eae)) || /* Sampras Tennis 96 */ + ((strstr(rominfo.product,"T-120066") != NULL) && (rominfo.checksum == 0x16a4)) || /* Pete Sampras Tennis (1994)*/ + (strstr(rominfo.product,"T-120096") != NULL)) /* Micro Machines 2 */ { - if (genromsize <= 0x380000) /* just to be sure (checksum might not be enough) */ + if (cart.romsize <= 0x380000) /* just to be sure (checksum might not be enough) */ { - j_cart = 1; + cart.hw.jcart = 1; m68k_memory_map[0x38].read16 = jcart_read; m68k_memory_map[0x38].write16 = jcart_write; m68k_memory_map[0x3f].read16 = jcart_read; m68k_memory_map[0x3f].write16 = jcart_write; - - /* save current setting */ - if (old_system[0] == -1) old_system[0] = input.system[0]; - if (old_system[1] == -1) old_system[1] = input.system[1]; - - /* PORT B by default */ - input.system[0] = SYSTEM_GAMEPAD; - input.system[1] = SYSTEM_GAMEPAD; } } /********************************************** - Mappers & HW registers + LOCK-ON ***********************************************/ - memset(&cart_hw, 0, sizeof(cart_hw)); + cart.lock_on = 0; + switch (config.lock_on) + { + case TYPE_GG: + ggenie_init(); + break; + + case TYPE_AR: + datel_init(); + break; + + case TYPE_SK: + /* be sure we have enough place to copy everything */ + if (cart.romsize < 0x700000) + { + /* load Sonic & Knuckles ROM (2 MBytes) */ + FILE *f = fopen(SK_ROM,"r+b"); + if (!f) break; + fread(cart.rom+0x700000,1,0x200000,f); + fclose(f); + + /* load Sonic 2 UPMEM ROM (256 KBytes) */ + f = fopen(SK_UPMEM,"r+b"); + if (!f) break; + fread(cart.rom+0x900000,1,0x40000,f); + fclose(f); + + /* ROM is mirrored each 256K */ + memcpy(cart.rom+0x940000,cart.rom+0x900000,0x40000); + memcpy(cart.rom+0x980000,cart.rom+0x900000,0x40000); + memcpy(cart.rom+0x9C0000,cart.rom+0x900000,0x40000); + +#ifdef LSB_FIRST + /* Byteswap ROM */ + int i; + uint8 temp; + for(i = 0; i < 0x300000; i += 2) + { + temp = cart.rom[i+0x700000]; + cart.rom[i+0x700000] = cart.rom[i+1+0x700000]; + cart.rom[i+1+0x700000] = temp; + } +#endif + + cart.lock_on = 1; + + } + break; + + default: + break; + } + + /********************************************** + Cartridge Extra Hardware + ***********************************************/ + memset(&cart.hw, 0, sizeof(T_CART_HW)); /* search for game into database */ for (i=0; i < CART_CNT + 1; i++) @@ -392,23 +379,23 @@ void cart_hw_init() (realchecksum == rom_database[i].chk_2)) { /* retrieve hardware information */ - memcpy(&cart_hw, &(rom_database[i].cart_hw), sizeof(cart_hw)); + memcpy(&cart.hw, &(rom_database[i].cart_hw), sizeof(T_CART_HW)); /* initialize memory handlers for $400000-$7fffff region */ int j = rom_database[i].bank_start; while (j <= rom_database[i].bank_end) { - if (cart_hw.regs_r) + if (cart.hw.regs_r) { - m68k_memory_map[j].read8 = cart_hw.regs_r; - m68k_memory_map[j].read16 = cart_hw.regs_r; - zbank_memory_map[j].read = cart_hw.regs_r; + m68k_memory_map[j].read8 = cart.hw.regs_r; + m68k_memory_map[j].read16 = cart.hw.regs_r; + zbank_memory_map[j].read = cart.hw.regs_r; } - if (cart_hw.regs_w) + if (cart.hw.regs_w) { - m68k_memory_map[j].write8 = cart_hw.regs_w; - m68k_memory_map[j].write16 = cart_hw.regs_w; - zbank_memory_map[j].write = cart_hw.regs_w; + m68k_memory_map[j].write8 = cart.hw.regs_w; + m68k_memory_map[j].write16 = cart.hw.regs_w; + zbank_memory_map[j].write = cart.hw.regs_w; } j++; } @@ -424,12 +411,12 @@ void cart_hw_init() #endif /* detect ROM files larger than 4MB */ - if (genromsize > 0x800000) + if (cart.romsize > 0x800000) { /* Ultimate MK3 (hack) */ for (i=0x40; i<0xA0; i++) { - m68k_memory_map[i].base = cart_rom + (i<<16); + m68k_memory_map[i].base = cart.rom + (i<<16); m68k_memory_map[i].read8 = NULL; m68k_memory_map[i].read16 = NULL; zbank_memory_map[i].read = NULL; @@ -440,17 +427,77 @@ void cart_hw_init() emulate_address_error = 0; #endif } - else if (genromsize > 0x400000) + else if (cart.romsize > 0x400000) { /* assume SSF2 mapper */ - cart_hw.bankshift = 1; + cart.hw.bankshift = 1; + cart.hw.time_w = sega_mapper_w; } /* default write handler for !TIME signal */ /* TODO: handle Sonic & Knuckles + Sonic 2 case to prevent RAM activation */ - if (!cart_hw.time_w) cart_hw.time_w = default_time_w; + if (!cart.hw.time_w) + cart.hw.time_w = default_time_w; } +/* hardware that need to be reseted on power on */ +void cart_hw_reset() +{ + int i; + + /* reset bankshifting */ + if (cart.hw.bankshift) + { + for (i=0x00; i<0x40; i++) + m68k_memory_map[i].base = cart.rom + (i<<16); + } + + /* Realtec mapper */ + if (cart.hw.realtec & 1) + { + /* enable BOOTROM */ + for (i=0; i<0x40; i++) + m68k_memory_map[i].base = mem_chunk; + for (i=0; i<8; i++) + memcpy(mem_chunk + i*0x2000, cart.rom + 0x7e000, 0x2000); + cart.hw.realtec |= 2; + } + + /* SVP chip */ + if (svp) + svp_reset(); + + /* Lock-ON */ + switch (config.lock_on) + { + case TYPE_GG: + ggenie_reset(); + break; + + case TYPE_AR: + datel_reset(); + break; + + case TYPE_SK: + if (cart.lock_on) + { + /* reset memory map */ + for (i=0x00; i<0x20; i++) + m68k_memory_map[i].base = cart.rom + 0x700000 + (i<<16); + for (i=0x30; i<0x40; i++) + m68k_memory_map[i].base = cart.rom + (i<<16); + } + break; + + default: + break; + } + + /* save default cartridge slot mapping */ + cart.base = m68k_memory_map[0].base; +} + + /************************************************************ MAPPER handlers *************************************************************/ @@ -458,7 +505,7 @@ void cart_hw_init() /* "official" ROM/RAM switch */ -static inline void sega_mapper_w(uint32 address, uint32 data) +static void sega_mapper_w(uint32 address, uint32 data) { uint32 i,slot = (address >> 1) & 7; uint8 *src; @@ -486,21 +533,36 @@ static inline void sega_mapper_w(uint32 address, uint32 data) m68k_memory_map[0x20].write16 = NULL; zbank_memory_map[0x20].write = NULL; } + + if (cart.lock_on) + { + /* enable UPMEM chip at $300000-$3fffff */ + for (i=0x30; i<0x40; i++) + m68k_memory_map[i].base = cart.rom + 0x600000 + (i<<16); + } } else { /* ROM enabled */ - m68k_memory_map[0x20].base = cart_rom + 0x200000; + m68k_memory_map[0x20].base = cart.rom + 0x200000; + + if (cart.lock_on) + { + /* enable cartridge ROM at $300000-$3fffff */ + for (i=0x30; i<0x40; i++) + m68k_memory_map[i].base = cart.rom + (i<<16); + } } break; - + default: /* ROM Bankswitch (Super Street Fighter 2) documented by Bart Trzynadlowski (http://www.trzy.org/files/ssf2.txt) */ slot = slot << 3; /* 8 x 512k banks */ - src = cart_rom + (data << 19); - for (i=0; i<8; i++) m68k_memory_map[slot++].base = src + (i<<16); + src = cart.rom + (data << 19); + for (i=0; i<8; i++) + m68k_memory_map[slot++].base = src + (i<<16); break; } } @@ -508,35 +570,33 @@ static inline void sega_mapper_w(uint32 address, uint32 data) /* custom ROM Bankswitch used by pirate "Multi-in-1" carts */ -static inline void multi_mapper_w(uint32 address, uint32 data) +static void multi_mapper_w(uint32 address, uint32 data) { int i; - cart_hw.bankshift = 1; + cart.hw.bankshift = 1; /* 64 x 64k banks */ for (i=0; i<64; i++) - { - m68k_memory_map[i].base = &cart_rom[((address++) & 0x3f) << 16]; - } + m68k_memory_map[i].base = &cart.rom[((address++) & 0x3f) << 16]; } /* Special ROM Bankswitch used for copy protection Used by unlicensed cartridges (Lion King III, Super King Kong 99) */ -void special_mapper_w(uint32 address, uint32 data) +static void special_mapper_w(uint32 address, uint32 data) { /* 1 x 32k bank */ m68k_memory_map[0].base = mem_chunk; - memcpy(mem_chunk,&cart_rom[(data & 0x7f) << 15],0x8000); - memcpy(mem_chunk+0x8000,cart_rom + 0x8000,0x8000); + memcpy(mem_chunk,&cart.rom[(data & 0x7f) << 15],0x8000); + memcpy(mem_chunk+0x8000,cart.rom + 0x8000,0x8000); } /* Realtec ROM Bankswitch (Earth Defend, Balloon Boy & Funny World, Whac-A-Critter) */ -void realtec_mapper_w(uint32 address, uint32 data) +static void realtec_mapper_w(uint32 address, uint32 data) { int i; uint32 base; @@ -545,32 +605,32 @@ void realtec_mapper_w(uint32 address, uint32 data) switch (address) { case 0x404000: /* three lower bits of ROM base address */ - cart_hw.regs[0] = data & 7; - base = ((data & 7) | (cart_hw.regs[1] << 2)); - for (i=0; i<=cart_hw.regs[2]; i++) + cart.hw.regs[0] = data & 7; + base = ((data & 7) | (cart.hw.regs[1] << 2)); + for (i=0; i<=cart.hw.regs[2]; i++) { - m68k_memory_map[i*2].base = &cart_rom[((base + i)*2 & 0x3f) << 16]; - m68k_memory_map[i*2+1].base = &cart_rom[(((base + i)*2 + 1) & 0x3f) << 16]; + m68k_memory_map[i*2].base = &cart.rom[((base + i)*2 & 0x3f) << 16]; + m68k_memory_map[i*2+1].base = &cart.rom[(((base + i)*2 + 1) & 0x3f) << 16]; } return; case 0x400000: /* two higher bits of ROM base address */ - cart_hw.regs[1] = data & 6; - base = cart_hw.regs[0] | ((data & 6) << 2); - for (i=0; i<=cart_hw.regs[2]; i++) + cart.hw.regs[1] = data & 6; + base = cart.hw.regs[0] | ((data & 6) << 2); + for (i=0; i<=cart.hw.regs[2]; i++) { - m68k_memory_map[i*2].base = &cart_rom[((base + i)*2 & 0x3f) << 16]; - m68k_memory_map[i*2+1].base = &cart_rom[(((base + i)*2 + 1) & 0x3f) << 16]; + m68k_memory_map[i*2].base = &cart.rom[((base + i)*2 & 0x3f) << 16]; + m68k_memory_map[i*2+1].base = &cart.rom[(((base + i)*2 + 1) & 0x3f) << 16]; } return; case 0x402000: /* number of 128k blocks to map */ - cart_hw.regs[2] = data & 0x1f; - base = cart_hw.regs[0] | (cart_hw.regs[1] << 2); + cart.hw.regs[2] = data & 0x1f; + base = cart.hw.regs[0] | (cart.hw.regs[1] << 2); for (i=0; i<=(data & 0x1f); i++) { - m68k_memory_map[i*2].base = &cart_rom[((base + i)*2 & 0x3f) << 16]; - m68k_memory_map[i*2+1].base = &cart_rom[(((base + i)*2 + 1) & 0x3f) << 16]; + m68k_memory_map[i*2].base = &cart.rom[((base + i)*2 & 0x3f) << 16]; + m68k_memory_map[i*2+1].base = &cart.rom[(((base + i)*2 + 1) & 0x3f) << 16]; } return; @@ -578,7 +638,7 @@ void realtec_mapper_w(uint32 address, uint32 data) } /* Game no Kanzume Otokuyou ROM Mapper */ -void seganet_mapper_w(uint32 address, uint32 data) +static void seganet_mapper_w(uint32 address, uint32 data) { if ((address & 0xff) == 0xf1) { @@ -609,16 +669,15 @@ void seganet_mapper_w(uint32 address, uint32 data) /* RADICA ROM Bankswitch (use !TIME) */ -uint32 radica_mapper_r(uint32 address) +static uint32 radica_mapper_r(uint32 address) { int i = 0; address = (address >> 1); /* 64 x 64k banks */ for (i = 0; i < 64; i++) - { - m68k_memory_map[i].base = &cart_rom[((address++)& 0x3f)<< 16]; - } + m68k_memory_map[i].base = &cart.rom[((address++)& 0x3f)<< 16]; + return 0xff; } @@ -628,10 +687,13 @@ uint32 radica_mapper_r(uint32 address) *************************************************************/ /* default ROM bankswitch */ -void default_time_w(uint32 address, uint32 data) +static void default_time_w(uint32 address, uint32 data) { - if ((address & 0xf1) == 0xf1) sega_mapper_w(address, data); - else if (address < 0xa13040) multi_mapper_w(address, data); + if ((address & 0xf1) == 0xf1) + sega_mapper_w(address, data); + + else if (address < 0xa13040) + multi_mapper_w(address, data); } @@ -639,33 +701,31 @@ void default_time_w(uint32 address, uint32 data) Internal register handlers *************************************************************/ -uint32 default_regs_r(uint32 address) +static uint32 default_regs_r(uint32 address) { int i; for (i=0; i<4; i++) { - if ((address & cart_hw.mask[i]) == cart_hw.addr[i]) - return cart_hw.regs[i]; + if ((address & cart.hw.mask[i]) == cart.hw.addr[i]) + return cart.hw.regs[i]; } /* unused */ return 0xffff; } -void default_regs_w(uint32 address, uint32 data) +static void default_regs_w(uint32 address, uint32 data) { int i; for (i=0; i<4; i++) { - if ((address & cart_hw.mask[i]) == cart_hw.addr[i]) - { - cart_hw.regs[i] = data; - } + if ((address & cart.hw.mask[i]) == cart.hw.addr[i]) + cart.hw.regs[i] = data; } } /* special register behaviour (Lion King III, Super Donkey Kong 99) */ -void special_regs_w(uint32 address, uint32 data) +static void special_regs_w(uint32 address, uint32 data) { /* ROM bankswitch */ if ((address >> 16) > 0x6f) @@ -678,19 +738,19 @@ void special_regs_w(uint32 address, uint32 data) default_regs_w(address, data); /* bitswapping (documented by Haze) */ - uint32 temp = cart_hw.regs[0]; - switch (cart_hw.regs[1]) + uint32 temp = cart.hw.regs[0]; + switch (cart.hw.regs[1]) { case 1: - cart_hw.regs[2] = (temp >> 1); + cart.hw.regs[2] = (temp >> 1); return; case 2: - cart_hw.regs[2] = ((temp >> 4) | ((temp & 0x0F) << 4)); + cart.hw.regs[2] = ((temp >> 4) | ((temp & 0x0F) << 4)); return; default: - cart_hw.regs[2] = (((temp >> 7) & 0x01) | ((temp >> 5) & 0x02) | + cart.hw.regs[2] = (((temp >> 7) & 0x01) | ((temp >> 5) & 0x02) | ((temp >> 3) & 0x04) | ((temp >> 1) & 0x08) | ((temp << 1) & 0x10) | ((temp << 3) & 0x20) | ((temp << 5) & 0x40) | ((temp << 7) & 0x80)); diff --git a/source/cart_hw/cart_hw.h b/source/cart_hw/cart_hw.h index 90a8b0f..35629f8 100644 --- a/source/cart_hw/cart_hw.h +++ b/source/cart_hw/cart_hw.h @@ -27,34 +27,42 @@ #ifndef _CART_HW_H_ #define _CART_HW_H_ -/* Lock-ON cartridge devices */ -#define GAME_GENIE 1 -#define ACTION_REPLAY 2 -#define SONIC_KNUCKLES 3 +/* Lock-ON cartridge type */ +#define TYPE_GG 0x10 /* Game Genie */ +#define TYPE_AR 0x20 /* Action Replay (Pro) */ +#define TYPE_SK 0x40 /* Sonic & Knuckles */ -/* Hardware description */ +/* Cartridge extra hardware */ typedef struct { uint8 regs[4]; /* internal registers (R/W) */ uint32 mask[4]; /* registers address mask */ uint32 addr[4]; /* registers address */ uint32 realtec; /* bit 0: realtec mapper detected, bit 1: bootrom enabled */ - uint32 bankshift; /* cartridge with bankshift mecanism */ + uint16 jcart; /* cartridge with JCART port */ + uint16 bankshift; /* cartridge with bankshift mecanism */ unsigned int (*time_r)(unsigned int address); /* !TIME signal ($a130xx) read handler */ void (*time_w)(unsigned int address, unsigned int data); /* !TIME signal ($a130xx) write handler */ - unsigned int (*regs_r)(unsigned int address); /* cart hardware region ($400000-$7fffff) read handler */ - void (*regs_w)(unsigned int address, unsigned int data); /* cart hardware region ($400000-$7fffff) write handler */ + unsigned int (*regs_r)(unsigned int address); /* cart hardware registers read handler */ + void (*regs_w)(unsigned int address, unsigned int data); /* cart hardware registers write handler */ } T_CART_HW; +/* Cartridge type */ +typedef struct +{ + uint8 *rom; /* ROM data */ + uint8 *base; /* ROM area (slot 0) */ + uint32 lock_on; /* 1: Lock-On enabled */ + uint32 romsize; /* ROM size */ + T_CART_HW hw; /* Custom hardware */ +} T_CART; + /* global variables */ -extern T_CART_HW cart_hw; -extern uint8 j_cart; -extern uint8 *default_rom; -extern int old_system[2]; +extern T_CART cart; /* Function prototypes */ -extern void cart_hw_reset(); extern void cart_hw_init(); +extern void cart_hw_reset(); #endif diff --git a/source/cart_hw/datel.c b/source/cart_hw/datel.c index ed4f91c..8faab21 100644 --- a/source/cart_hw/datel.c +++ b/source/cart_hw/datel.c @@ -21,9 +21,9 @@ #include "shared.h" -#define TYPE_AR 1 -#define TYPE_PRO1 2 -#define TYPE_PRO2 3 +#define TYPE_AR 0x01 +#define TYPE_PRO1 0x02 +#define TYPE_PRO2 0x03 static struct { @@ -145,7 +145,7 @@ void datel_switch(uint8 enable) offset = action_replay.addr[i] >> 16; if (offset < 0x40) /* cartridge ROM */ - action_replay.old[i] = *(uint16 *)(cart_rom + action_replay.addr[i]); + action_replay.old[i] = *(uint16 *)(cart.rom + action_replay.addr[i]); else if (offset >= 0xe0) /* Work RAM */ action_replay.old[i] = *(uint16 *)(work_ram + (action_replay.addr[i]&0xffff)); } @@ -159,7 +159,7 @@ void datel_switch(uint8 enable) offset = action_replay.addr[i] >> 16; if (offset < 0x40) /* cartridge ROM */ - *(uint16 *)(cart_rom + action_replay.addr[i]) = action_replay.data[i]; + *(uint16 *)(cart.rom + action_replay.addr[i]) = action_replay.data[i]; else if (offset >= 0xe0) /* Work RAM */ *(uint16 *)(work_ram + (action_replay.addr[i]&0xffff)) = action_replay.data[i]; } @@ -180,7 +180,7 @@ void datel_switch(uint8 enable) if (action_replay.data[i]) { if (action_replay.addr[i] < 0x400000) - *(uint16 *)(cart_rom + action_replay.addr[i]) = action_replay.old[i]; + *(uint16 *)(cart.rom + action_replay.addr[i]) = action_replay.old[i]; else if (action_replay.addr[i] >= 0xe00000) *(uint16 *)(work_ram + (action_replay.addr[i]&0xffff)) = action_replay.old[i]; } @@ -253,6 +253,6 @@ static void ar_write_regs(uint32 address, uint32 data) /* reads are mapped to Cartridge ROM */ /* NOTE: codes should be disabled on startup */ - m68k_memory_map[0].base = cart_rom; + m68k_memory_map[0].base = cart.rom; } } diff --git a/source/cart_hw/eeprom.c b/source/cart_hw/eeprom.c index 68f61c1..1dfa816 100644 --- a/source/cart_hw/eeprom.c +++ b/source/cart_hw/eeprom.c @@ -27,7 +27,7 @@ T_EEPROM eeprom; typedef struct { - char game_id[14]; + char game_id[16]; uint16 chk; T_EEPROM_TYPE type; } T_GAME_ENTRY; diff --git a/source/cart_hw/ggenie.c b/source/cart_hw/ggenie.c index 39be8f4..2d62a10 100644 --- a/source/cart_hw/ggenie.c +++ b/source/cart_hw/ggenie.c @@ -117,8 +117,8 @@ void ggenie_switch(uint8 enable) /* save old value and patch ROM if enabled */ if (ggenie.regs[0] & (1 << i)) { - ggenie.old[i] = *(uint16 *)(cart_rom + ggenie.addr[i]); - *(uint16 *)(cart_rom + ggenie.addr[i]) = ggenie.data[i]; + ggenie.old[i] = *(uint16 *)(cart.rom + ggenie.addr[i]); + *(uint16 *)(cart.rom + ggenie.addr[i]) = ggenie.data[i]; } } } @@ -131,7 +131,7 @@ void ggenie_switch(uint8 enable) /* patch is enabled ? */ if (ggenie.regs[0] & (1 << i)) { - *(uint16 *)(cart_rom + ggenie.addr[i]) = ggenie.old[i]; + *(uint16 *)(cart.rom + ggenie.addr[i]) = ggenie.old[i]; } } } @@ -203,7 +203,7 @@ static void ggenie_write_regs(uint8 offset, uint32 data, uint8 type) if (data & 0x400) { /* $0000-$7ffff reads mapped to Cartridge ROM */ - m68k_memory_map[0].base = cart_rom; + m68k_memory_map[0].base = cart.rom; } else { @@ -249,6 +249,6 @@ static void ggenie_write_regs(uint8 offset, uint32 data, uint8 type) static uint32 ggenie_read_regs(uint32 address) { if (address < 0x40) return ggenie.regs[address >> 1]; - else return *(uint16 *)(cart_rom + address); /* is that correct ? */ + else return *(uint16 *)(cart.rom + address); /* is that correct ? */ } diff --git a/source/cart_hw/sram.c b/source/cart_hw/sram.c index fd641a6..5f50a72 100644 --- a/source/cart_hw/sram.c +++ b/source/cart_hw/sram.c @@ -45,12 +45,12 @@ void sram_init() memset (&sram.sram[0], 0xFF, 0x10000); sram.crc = crc32 (0, &sram.sram[0], 0x10000); - if ((READ_BYTE(cart_rom,0x1b0) == 0x52) && (READ_BYTE(cart_rom,0x1b1) == 0x41)) + if ((READ_BYTE(cart.rom,0x1b0) == 0x52) && (READ_BYTE(cart.rom,0x1b1) == 0x41)) { /* retrieve informations from headezr */ sram.detected = 1; - sram.start = READ_WORD_LONG(cart_rom, 0x1b4); - sram.end = READ_WORD_LONG(cart_rom, 0x1b8); + sram.start = READ_WORD_LONG(cart.rom, 0x1b4); + sram.end = READ_WORD_LONG(cart.rom, 0x1b8); /* fixe some bad header informations */ if ((sram.start > sram.end) || ((sram.end - sram.start) >= 0x10000)) @@ -66,7 +66,7 @@ void sram_init() } /* set SRAM ON by default when ROM is not mapped */ - if (genromsize <= sram.start) + if (cart.romsize <= sram.start) { sram.on = 1; sram.write = 1; diff --git a/source/cart_hw/svp/ssp16.c b/source/cart_hw/svp/ssp16.c index 71e29ba..349d636 100644 --- a/source/cart_hw/svp/ssp16.c +++ b/source/cart_hw/svp/ssp16.c @@ -262,7 +262,7 @@ // how is low word really affected by these? // nearly sure 'ld A' doesn't affect flags #define OP_LDA(x) \ - rA = x + rA = x #define OP_LDA32(x) \ rA32 = x @@ -326,16 +326,16 @@ UPD_ACC_ZN -#define OP_CHECK32(OP) { \ +#define OP_CHECK32(OP) { \ if ((op & 0x0f) == SSP_P) { /* A <- P */ \ - read_P(); /* update P */ \ - OP(rP.v); \ - break; \ - } \ - if ((op & 0x0f) == SSP_A) { /* A <- A */ \ - OP(rA32); \ - break; \ - } \ + read_P(); /* update P */ \ + OP(rP.v); \ + break; \ + } \ + if ((op & 0x0f) == SSP_A) { /* A <- A */ \ + OP(rA32); \ + break; \ + } \ } @@ -553,14 +553,14 @@ static u32 pm_io(int reg, int write, u32 d) { #ifdef LOG_SVP elprintf(EL_SVP, "ssp ROM r [%06x] %04x", CADDR, - ((unsigned short *)cart_rom)[addr|((mode&0xf)<<16)]); + ((unsigned short *)cart.rom)[addr|((mode&0xf)<<16)]); #endif /*if ((signed int)ssp->pmac_read[reg] >> 16 == -1) ssp->pmac_read[reg]++; ssp->pmac_read[reg] += 1<<16;*/ if ((signed int)(ssp->pmac_read[reg] & 0xffff) == -1) ssp->pmac_read[reg] += 1<<16; ssp->pmac_read[reg] ++; - d = ((unsigned short *)cart_rom)[addr|((mode&0xf)<<16)]; + d = ((unsigned short *)cart.rom)[addr|((mode&0xf)<<16)]; } else if ((mode & 0x47ff) == 0x0018) // DRAM { @@ -1106,7 +1106,7 @@ void ssp1601_run(int cycles) if (op == ((SSP_A<<4)|SSP_P)) { // A <- P // not sure. MAME claims that only hi word is transfered. read_P(); // update P - rA32 = rP.v; + rA32 = rP.v; } else { @@ -1194,7 +1194,7 @@ void ssp1601_run(int cycles) if (!(op&0x100)) elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME: no b bit @ %04x", GET_PPC_OFFS()); #endif read_P(); // update P - rA32 -= rP.v; // maybe only upper word? + rA32 -= rP.v; // maybe only upper word? UPD_ACC_ZN // there checking flags after this rX = ptr1_read_(op&3, 0, (op<<1)&0x18); // ri (maybe rj?) rY = ptr1_read_((op>>4)&3, 4, (op>>3)&0x18); // rj @@ -1206,7 +1206,7 @@ void ssp1601_run(int cycles) if (!(op&0x100)) elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME: no b bit @ %04x", GET_PPC_OFFS()); #endif read_P(); // update P - rA32 += rP.v; // confirmed to be 32bit + rA32 += rP.v; // confirmed to be 32bit UPD_ACC_ZN // ? rX = ptr1_read_(op&3, 0, (op<<1)&0x18); // ri (maybe rj?) rY = ptr1_read_((op>>4)&3, 4, (op>>3)&0x18); // rj diff --git a/source/cart_hw/svp/svp.c b/source/cart_hw/svp/svp.c index 3cb168e..b7864d0 100644 --- a/source/cart_hw/svp/svp.c +++ b/source/cart_hw/svp/svp.c @@ -17,13 +17,13 @@ int16 SVP_cycles = 850; void svp_init(void) { - svp = (void *) ((char *)cart_rom + 0x200000); + svp = (void *) ((char *)cart.rom + 0x200000); memset(svp, 0, sizeof(*svp)); } void svp_reset(void) { - memcpy(svp->iram_rom + 0x800, cart_rom + 0x800, 0x20000 - 0x800); + memcpy(svp->iram_rom + 0x800, cart.rom + 0x800, 0x20000 - 0x800); ssp1601_reset(&svp->ssp1601); } diff --git a/source/gen_input.c b/source/gen_input.c index d39e5f5..fb933a3 100644 --- a/source/gen_input.c +++ b/source/gen_input.c @@ -30,7 +30,7 @@ t_input input; * *****************************************************************************/ /* H counter values for a 256-pixel wide display (342 pixel max.) */ -static uint8 hc_256[171] = { +static const uint8 hc_256[171] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, @@ -46,7 +46,7 @@ static uint8 hc_256[171] = { }; /* H counter values for a 320-pixel wide display (420 pixels max.) */ -static uint8 hc_320[210] = { +static const uint8 hc_320[210] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, @@ -80,7 +80,7 @@ static inline void lightgun_update(int num) /* External Interrupt ? */ if (reg[11] & 0x08) irq_status = (irq_status & ~0x40) | 0x12; - /* HVC Latch: + /* Horizontal Counter Latch: 1) some games does not set HVC latch but instead use bigger X offset 2) for games using H40 mode, the gun routine scales up the Hcounter value, H-Counter range is approx. 292 pixel clocks @@ -136,7 +136,7 @@ uint32 justifier_read() * SEGA MOUSE specific functions * *****************************************************************************/ -struct mega_mouse +static struct mega_mouse { uint8 State; uint8 Counter; @@ -258,7 +258,7 @@ uint32 mouse_read() * GAMEPAD specific functions (2PLAYERS/4WAYPLAY) * *****************************************************************************/ -struct pad +static struct pad { uint8 State; uint8 Counter; @@ -387,22 +387,19 @@ static inline void gamepad_write(uint32 i, uint32 data) * TEAMPLAYER adapter * *****************************************************************************/ -struct teamplayer +static struct teamplayer { uint8 State; uint8 Counter; uint8 Table[12]; } teamplayer[2]; -static inline void teamplayer_reset(uint32 port) +static inline void teamplayer_init(uint32 port) { int i; int index = 0; int pad_input = 0; - teamplayer[port].State = 0x60; /* TH = 1, TR = 1 */ - teamplayer[port].Counter = 0; - /* this table determines which gamepad input should be returned during acquisition sequence index = teamplayer read table index: 0=1st read, 1=2nd read, ... pad_input = gamepad input 0-14: 0=P1_DIR, 1=P1_SABC, 2=P1_MXYZ, 4=P2_DIR, 5=P2_SABC, ... @@ -424,6 +421,12 @@ static inline void teamplayer_reset(uint32 port) } } +static inline void teamplayer_reset(uint32 port) +{ + teamplayer[port].State = 0x60; /* TH = 1, TR = 1 */ + teamplayer[port].Counter = 0; +} + /* SEGA teamplayer returns successively: - PAD1 inputs - PAD2 inputs @@ -603,7 +606,7 @@ void teamplayer_2_write (uint32 data) uint32 jcart_read(uint32 address) { - return (gamepad_read(5) | ((gamepad_read(6)&0x3f) << 8)); /* fixes Micro Machines 2 (is it correct ?) */ + return (gamepad_read(5) | ((gamepad_read(6)&0x3f) << 8)); /* fixes Micro Machines 2 */ } void jcart_write(uint32 address, uint32 data) @@ -617,12 +620,11 @@ void jcart_write(uint32 address, uint32 data) * Generic INPUTS Control * *****************************************************************************/ -void input_reset () +void input_init () { int i,j; input.max = 0; - input.current = 0; for (i=0; i TYPE_SK) config.lock_on = 0; + if (config.lock_on == TYPE_GG) sprintf (items[4].text, "Lock-On: GAME GENIE"); + else if (config.lock_on == TYPE_AR) sprintf (items[4].text, "Lock-On: ACTION REPLAY"); + else if (config.lock_on == TYPE_SK) sprintf (items[4].text, "Lock-On: SONIC & KNUCKLES"); else sprintf (items[4].text, "Lock-On: OFF"); - if (genromsize) + if (cart.romsize) { system_reset (); /* clear any patches first */ system_init (); @@ -1113,7 +1116,7 @@ static void ctrlmenu_raz(void) m->buttons[i+2].data = &button_player_data; m->buttons[i+2].state |= BUTTON_ACTIVE; sprintf(m->items[i+2].text,"%d",max + 1); - if (j_cart && (i > 4)) + if (cart.hw.jcart && (i > 4)) sprintf(m->items[i+2].comment,"Configure Player %d (J-CART) settings", max + 1); else sprintf(m->items[i+2].comment,"Configure Player %d settings", max + 1); @@ -1291,7 +1294,7 @@ static void ctrlmenu(void) switch (m->selected) { case 0: /* update port 1 system */ - if (j_cart) break; + if (cart.hw.jcart) break; if (input.system[0] == SYSTEM_MOUSE) input.system[0] +=3; /* lightguns are never used on Port 1 */ else input.system[0] ++; if ((input.system[0] == SYSTEM_MOUSE) && (input.system[1] == SYSTEM_MOUSE)) input.system[0] +=3; @@ -1339,7 +1342,7 @@ static void ctrlmenu(void) break; case 1: /* update port 2 system */ - if (j_cart) break; + if (cart.hw.jcart) break; input.system[1] ++; if ((input.system[0] == SYSTEM_MOUSE) && (input.system[1] == SYSTEM_MOUSE)) input.system[1] ++; if (input.system[1] == SYSTEM_WAYPLAY) input.system[0] = SYSTEM_WAYPLAY; @@ -1466,7 +1469,7 @@ static void ctrlmenu(void) GUI_DrawMenuFX(m, 20, 0); /* update title */ - if (j_cart && (player > 1)) + if (cart.hw.jcart && (player > 1)) sprintf(m->title,"Controller Settings (Player %d) (J-CART)",player+1); else sprintf(m->title,"Controller Settings (Player %d)",player+1); @@ -1911,7 +1914,7 @@ static int loadmenu () if (DVD_Open()) { GUI_DeleteMenu(m); - size = FileSelector(cart_rom,0); + size = FileSelector(cart.rom,0); if (size) return 1; GUI_InitMenu(m); } @@ -1922,7 +1925,7 @@ static int loadmenu () if (FAT_Open(ret)) { GUI_DeleteMenu(m); - size = FileSelector(cart_rom,1); + size = FileSelector(cart.rom,1); if (size) return 1; GUI_InitMenu(m); } @@ -2095,7 +2098,7 @@ void MainMenu (void) if (!rom_loaded) { /* check if a game is running */ - if (genromsize) + if (cart.romsize) { m->screenshot = 1; m->bg_images[0].state &= ~IMAGE_VISIBLE; @@ -2124,7 +2127,7 @@ void MainMenu (void) { case -1: /*** Return to Game ***/ case 6: - if (!genromsize) break; + if (!cart.romsize) break; GUI_DrawMenuFX(m,10,1); GUI_DeleteMenu(m); quit = 1; @@ -2178,7 +2181,7 @@ void MainMenu (void) break; case 3: /*** Memory Manager ***/ - if (!genromsize) break; + if (!cart.romsize) break; GUI_DeleteMenu(m); quit = filemenu (); if (quit) break; @@ -2186,7 +2189,7 @@ void MainMenu (void) break; case 4: /*** Emulator Reset ***/ - if (!genromsize) break; + if (!cart.romsize) break; GUI_DrawMenuFX(m,10,1); GUI_DeleteMenu(m); gxClearScreen ((GXColor)BLACK); @@ -2196,19 +2199,19 @@ void MainMenu (void) break; case 5: /*** Game Genie ***/ - if (!genromsize) break; + if (!cart.romsize) break; GUI_DeleteMenu(m); GetGGEntries(); GUI_InitMenu(m); break; case 7: /*** ROM Captrure ***/ - if (!genromsize) break; + if (!cart.romsize) break; gx_video_Capture(); break; case 8: /*** ROM Information ***/ - if (!genromsize) break; + if (!cart.romsize) break; GUI_DeleteMenu(m); showrominfo (); GUI_InitMenu(m); diff --git a/source/gx/gx_video.c b/source/gx/gx_video.c index 889fc6e..e0932ae 100644 --- a/source/gx/gx_video.c +++ b/source/gx/gx_video.c @@ -1442,11 +1442,11 @@ void gx_video_Init(void) */ int *romptr = (int *)0x80700000; StartARAM(); - genromsize = 0; + cart.romsize = 0; if (memcmp((char *)romptr,"GENPLUSR",8) == 0) { - genromsize = romptr[2]; - ARAMPut((char *) 0x80700000 + 0x20, (char *) 0x8000, genromsize); + cart.romsize = romptr[2]; + ARAMPut((char *) 0x80700000 + 0x20, (char *) 0x8000, cart.romsize); } /* Get the current VIDEO mode then : diff --git a/source/gx/main.c b/source/gx/main.c index 95a8cc2..b3e7669 100644 --- a/source/gx/main.c +++ b/source/gx/main.c @@ -79,8 +79,8 @@ static void load_bios(void) static void init_machine(void) { /* Allocate cart_rom here ( 10 MBytes ) */ - cart_rom = memalign(32, MAXROMSIZE); - if (!cart_rom) + cart.rom = memalign(32, MAXROMSIZE); + if (!cart.rom) { FONT_writeCenter("Failed to allocate ROM buffer... Rebooting",18,0,640,200,(GXColor)WHITE); gxSetScreen(); @@ -121,7 +121,7 @@ static void init_machine(void) ***************************************************/ void reloadrom (int size, char *name) { - genromsize = size; + cart.romsize = size; load_rom(name); /* Load ROM */ system_init (); /* Initialize System */ audio_init(48000); /* Audio System initialization */ @@ -138,7 +138,7 @@ void shutdown(void) memfile_autosave(-1,config.state_auto); system_shutdown(); audio_shutdown(); - free(cart_rom); + free(cart.rom); gx_audio_Shutdown(); gx_video_Shutdown(); #ifdef HW_RVL @@ -212,10 +212,10 @@ int main (int argc, char *argv[]) init_machine(); /* run any injected rom */ - if (genromsize) + if (cart.romsize) { - ARAMFetch((char *)cart_rom, (void *)0x8000, genromsize); - reloadrom (genromsize,"INJECT.bin"); + ARAMFetch((char *)cart.rom, (void *)0x8000, cart.romsize); + reloadrom (cart.romsize,"INJECT.bin"); gx_video_Start(); gx_audio_Start(); frameticker = 1; diff --git a/source/gx/osd.h b/source/gx/osd.h index 133ff08..b61cf46 100644 --- a/source/gx/osd.h +++ b/source/gx/osd.h @@ -29,11 +29,13 @@ #define GG_ROM "/genplus/ggenie.bin" #define AR_ROM "/genplus/areplay.bin" #define OS_ROM "/genplus/bios.bin" +#define SK_ROM "/genplus/sk.bin" +#define SK_UPMEM "/genplus/sk2chip.bin" #ifdef HW_RVL -#define VERSION "version 1.3.3W" +#define VERSION "version 1.4.0W" #else -#define VERSION "version 1.3.3G" +#define VERSION "version 1.4.0G" #endif /* globals */ diff --git a/source/loadrom.c b/source/loadrom.c index 2b1edca..2815687 100644 --- a/source/loadrom.c +++ b/source/loadrom.c @@ -225,7 +225,7 @@ static void getrominfo (char *romheader) memcpy (&rominfo.memo, romheader + ROMMEMO, 40); memcpy (&rominfo.country, romheader + ROMCOUNTRY, 16); - realchecksum = GetRealChecksum (((uint8 *) cart_rom) + 0x200, genromsize - 0x200); + realchecksum = GetRealChecksum (((uint8 *) cart.rom) + 0x200, cart.romsize - 0x200); #ifdef LSB_FIRST rominfo.checksum = (rominfo.checksum >> 8) | ((rominfo.checksum & 0xff) << 8); #endif @@ -256,49 +256,49 @@ int load_rom(char *filename) int i, size, offset = 0; #ifdef NGC - size = genromsize; + size = cart.romsize; sprintf(rom_filename,"%s",filename); rom_filename[strlen(rom_filename) - 4] = 0; #else uint8 *ptr; ptr = load_archive(filename, &size); if(!ptr) return (0); - memcpy(cart_rom, ptr + offset, size); + memcpy(cart.rom, ptr + offset, size); free(ptr); #endif /* detect interleaved roms (.smd format) */ - if (strncmp((char *)(cart_rom + 0x100),"SEGA", 4) && ((size / 512) & 1)) + if (strncmp((char *)(cart.rom + 0x100),"SEGA", 4) && ((size / 512) & 1)) { size -= 512; offset += 512; for (i = 0; i < (size / 0x4000); i += 1) { - deinterleave_block (cart_rom + offset + (i * 0x4000)); + deinterleave_block (cart.rom + offset + (i * 0x4000)); } - memcpy(cart_rom, cart_rom + offset, size); + memcpy(cart.rom, cart.rom + offset, size); } /* max. 10 MBytes supported */ if (size > MAXROMSIZE) size = MAXROMSIZE; - genromsize = size; + cart.romsize = size; /* clear unused ROM space */ - if (size < MAXROMSIZE) memset (cart_rom + size, 0x00, MAXROMSIZE - size); + memset (cart.rom + size, 0xff, MAXROMSIZE - size); - getrominfo((char *)cart_rom); /* get infos from ROM header */ + getrominfo((char *)cart.rom); /* get infos from ROM header */ set_region(); /* set game region (PAL/NTSC, JAP/USA/EUR) */ #ifdef LSB_FIRST /* Byteswap ROM */ uint8 temp; - for(i = 0; i < genromsize; i += 2) + for(i = 0; i < size; i += 2) { - temp = cart_rom[i]; - cart_rom[i] = cart_rom[i+1]; - cart_rom[i+1] = temp; + temp = cart.rom[i]; + cart.rom[i] = cart.rom[i+1]; + cart.rom[i+1] = temp; } #endif @@ -307,11 +307,11 @@ int load_rom(char *filename) ((strstr(rominfo.product,"-K0109") != NULL) && (rominfo.checksum == 0x4f10))) { uint8 temp; - for(i = 0; i < genromsize; i += 2) + for(i = 0; i < size; i += 2) { - temp = cart_rom[i]; - cart_rom[i] = cart_rom[i+1]; - cart_rom[i+1] = temp; + temp = cart.rom[i]; + cart.rom[i] = cart.rom[i+1]; + cart.rom[i+1] = temp; } } diff --git a/source/mem68k.c b/source/mem68k.c index ff2f4ce..82e183f 100644 --- a/source/mem68k.c +++ b/source/mem68k.c @@ -112,13 +112,13 @@ static int pico_page[7] = {0x00,0x01,0x03,0x07,0x0F,0x1F,0x3F}; uint32 eeprom_read_byte(uint32 address) { if (address == eeprom.type.sda_out_adr) return eeprom_read(address, 0); - else return READ_BYTE(cart_rom, address); + else return READ_BYTE(cart.rom, address); } uint32 eeprom_read_word(uint32 address) { if (address == (eeprom.type.sda_out_adr & 0xfffffe)) return eeprom_read(address, 1); - else return *(uint16 *)(cart_rom + address); + else return *(uint16 *)(cart.rom + address); } void eeprom_write_byte(uint32 address, uint32 data) @@ -270,7 +270,8 @@ uint32 ctrl_io_read_byte(uint32 address) else return ((m68k_read_pcrelative_8(REG_PC) & 0xfe) | zbusack); case 0x30: /* TIME */ - if (cart_hw.time_r) return cart_hw.time_r(address); + if (cart.hw.time_r) + return ((address & 1) ? (cart.hw.time_r(address) & 0xff) : (cart.hw.time_r(address) >> 8)); else return m68k_read_bus_8(address); case 0x10: /* MEMORY MODE */ @@ -302,7 +303,7 @@ uint32 ctrl_io_read_word(uint32 address) return ((m68k_read_pcrelative_16(REG_PC) & 0xfeff) | (zbusack << 8)); case 0x30: /* TIME */ - if (cart_hw.time_r) return cart_hw.time_r(address); + if (cart.hw.time_r) return cart.hw.time_r(address); else return m68k_read_bus_16(address); case 0x50: /* SVP */ @@ -351,20 +352,20 @@ void ctrl_io_write_byte(uint32 address, uint32 data) return; case 0x30: /* TIME */ - cart_hw.time_w(address, data); + cart.hw.time_w(address, data); return; case 0x41: /* BOOTROM */ if (address & 1) { - m68k_memory_map[0].base = (data & 1) ? default_rom : bios_rom; + m68k_memory_map[0].base = (data & 1) ? cart.base : bios_rom; /* autodetect BIOS ROM file */ if (!(config.bios_enabled & 2)) { config.bios_enabled |= 2; - memcpy(bios_rom, cart_rom, 0x800); - memset(cart_rom, 0, genromsize); + memcpy(bios_rom, cart.rom, 0x800); + memset(cart.rom, 0xff, cart.romsize); } } else m68k_unused_8_w (address, data); @@ -417,20 +418,20 @@ void ctrl_io_write_word(uint32 address, uint32 data) return; case 0x30: /* TIME */ - cart_hw.time_w(address & 0xfe, data >> 8); - cart_hw.time_w(address, data & 0xff); + cart.hw.time_w(address & 0xfe, data >> 8); + cart.hw.time_w(address, data & 0xff); return; case 0x41: /* BOOTROM */ - m68k_memory_map[0].base = (data & 1) ? default_rom : bios_rom; + m68k_memory_map[0].base = (data & 1) ? cart.base : bios_rom; /* autodetect BIOS ROM file */ if (!(config.bios_enabled & 2)) { config.bios_enabled |= 2; - memcpy(bios_rom, cart_rom, 0x800); - memset(cart_rom, 0, genromsize); + memcpy(bios_rom, cart.rom, 0x800); + memset(cart.rom, 0xff, cart.romsize); } return; diff --git a/source/membnk.c b/source/membnk.c index 2bd1478..417a578 100644 --- a/source/membnk.c +++ b/source/membnk.c @@ -73,7 +73,8 @@ uint32 zbank_read_ctrl_io(uint32 address) else return (0xfe | zbusack); case 0x30: /* TIME */ - if (cart_hw.time_r) return cart_hw.time_r(address); + if (cart.hw.time_r) + return ((address & 1) ? (cart.hw.time_r(address) & 0xff) : (cart.hw.time_r(address) >> 8)); else return zbank_unused_r(address); case 0x10: /* MEMORY MODE */ @@ -110,21 +111,20 @@ void zbank_write_ctrl_io(uint32 address, uint32 data) return; case 0x30: /* TIME */ - if (cart_hw.time_w) cart_hw.time_w(address, data); - else zbank_unused_w(address, data); + cart.hw.time_w(address, data); return; case 0x41: /* BOOTROM */ if (address & 1) { - m68k_memory_map[0].base = (data & 1) ? default_rom : bios_rom; + m68k_memory_map[0].base = (data & 1) ? cart.base : bios_rom; /* autodetect BIOS ROM file */ if (!(config.bios_enabled & 2)) { config.bios_enabled |= 2; - memcpy(bios_rom, cart_rom, 0x800); - memset(cart_rom, 0, genromsize); + memcpy(bios_rom, cart.rom, 0x800); + memset(cart.rom, 0xff, cart.romsize); } } else zbank_unused_w (address, data); diff --git a/source/state.c b/source/state.c index e2e11ac..104ce45 100644 --- a/source/state.c +++ b/source/state.c @@ -54,7 +54,7 @@ int state_load(unsigned char *buffer) /* reset system */ system_reset(); - m68k_memory_map[0].base = default_rom; + m68k_memory_map[0].base = cart.base; // GENESIS load_param(work_ram, sizeof(work_ram)); diff --git a/source/system.c b/source/system.c index 40d068f..040d21c 100644 --- a/source/system.c +++ b/source/system.c @@ -204,10 +204,14 @@ void audio_shutdown(void) ****************************************************************/ void system_init (void) { + /* Cartridge hardware (should be done first !) */ + cart_hw_init(); + + /* Genesis hardware */ gen_init (); vdp_init (); render_init (); - cart_hw_init(); + io_init(); } /**************************************************************** @@ -215,15 +219,14 @@ void system_init (void) ****************************************************************/ void system_reset (void) { - /* Cartridge Hardware (should be done first !) */ + /* Cartridge hardware (should be done first !) */ cart_hw_reset(); - /* Genesis Hardware */ + /* Genesis hardware */ gen_reset (1); vdp_reset (); render_reset (); io_reset(); - SN76489_Reset(); /* Clear Sound Buffers */ if (snd.psg.buffer) memset (snd.psg.buffer, 0, SND_SIZE); diff --git a/source/unused/dos/dos.c b/source/unused/dos/dos.c index 879c8e0..200572e 100644 --- a/source/unused/dos/dos.c +++ b/source/unused/dos/dos.c @@ -66,8 +66,8 @@ int main (int argc, char *argv[]) } error_init(); - cart_rom = malloc(0xA00000); - memset(cart_rom, 0, 0xA00000); + cart.rom = malloc(0xA00000); + memset(cart.rom, 0, 0xA00000); if(!load_rom(argv[1])) { @@ -146,7 +146,7 @@ int main (int argc, char *argv[]) trash_machine(); system_shutdown(); error_shutdown(); - free(cart_rom); + free(cart.rom); return (0); } diff --git a/source/unused/win/config.c b/source/unused/win/config.c index a038e25..bcff4d2 100644 --- a/source/unused/win/config.c +++ b/source/unused/win/config.c @@ -11,9 +11,11 @@ void set_config_defaults(void) /* sound options */ config.psg_preamp = 150; config.fm_preamp = 100; - config.hq_fm = 1; + config.hq_fm = 0; config.psgBoostNoise = 0; config.filter = 1; + config.low_freq = 200; + config.high_freq = 8000; config.lg = 1.0; config.mg = 1.0; config.hg = 1.0; @@ -21,11 +23,14 @@ void set_config_defaults(void) /* system options */ config.region_detect = 0; config.force_dtack = 0; + config.addr_error = 0; config.bios_enabled = 0; + config.lock_on = 0; + config.romtype = 0; /* display options */ config.overscan = 1; - config.render = 1; + config.render = 0; /* controllers options */ input.system[0] = SYSTEM_GAMEPAD; diff --git a/source/unused/win/config.h b/source/unused/win/config.h index 8b4dfd9..f91a2d4 100644 --- a/source/unused/win/config.h +++ b/source/unused/win/config.h @@ -18,12 +18,17 @@ typedef struct int32 psg_preamp; int32 fm_preamp; uint8 filter; + uint16 low_freq; + uint16 high_freq; float lg; float mg; float hg; uint8 region_detect; uint8 force_dtack; + uint8 addr_error; uint8 bios_enabled; + uint8 lock_on; + uint8 romtype; uint8 overscan; uint8 render; uint8 ntsc; diff --git a/source/unused/win/main.c b/source/unused/win/main.c index 089d4bd..c31aed3 100644 --- a/source/unused/win/main.c +++ b/source/unused/win/main.c @@ -133,7 +133,7 @@ Uint32 fps_callback(Uint32 interval) if (region_code == REGION_USA) sprintf(region,"USA"); else if (region_code == REGION_EUROPE) sprintf(region,"EUR"); else sprintf(region,"JAP"); - sprintf(caption, "Genesis Plus/SDL - %s (%s) - %d fps - xoffset = %d", rominfo.international, region, fps,input.x_offset); + sprintf(caption, "Genesis Plus/SDL - %s (%s) - %d fps - 0x%04X", rominfo.international, region, fps, realchecksum); SDL_WM_SetCaption(caption, NULL); frame_count = 0; @@ -177,8 +177,8 @@ int main (int argc, char **argv) set_config_defaults(); /* Load game */ - cart_rom = malloc(10*1024*1024); - memset(cart_rom, 0, 10*1024*1024); + cart.rom = malloc(10*1024*1024); + memset(cart.rom, 0, 10*1024*1024); if(!load_rom(argv[1])) { char caption[256]; @@ -221,7 +221,7 @@ int main (int argc, char **argv) /* load BIOS */ memset(bios_rom, 0, sizeof(bios_rom)); - FILE *f = fopen("./BIOS.bin", "rb"); + FILE *f = fopen(OS_ROM, "rb"); if (f!=NULL) { fread(&bios_rom, 0x800,1,f); @@ -436,8 +436,9 @@ int main (int argc, char **argv) SDL_FreeSurface(screen); SDL_Quit(); system_shutdown(); + audio_shutdown(); error_shutdown(); - free(cart_rom); + free(cart.rom); return 0; } diff --git a/source/unused/win/osd.h b/source/unused/win/osd.h index 572756b..f250a31 100644 --- a/source/unused/win/osd.h +++ b/source/unused/win/osd.h @@ -18,4 +18,10 @@ #include "unzip.h" #include "fileio.h" +#define GG_ROM "./ggenie.bin" +#define AR_ROM "./areplay.bin" +#define OS_ROM "./bios.bin" +#define SK_ROM "./sk.bin" +#define SK_UPMEM "./sk2chip.bin" + #endif /* _OSD_H_ */ diff --git a/source/vdp.c b/source/vdp.c index 322386b..7571233 100644 --- a/source/vdp.c +++ b/source/vdp.c @@ -76,21 +76,21 @@ uint8 fifo_latency; /* VDP write cycles latency */ uint8 odd_frame; /* 1: odd field, 0: even field */ uint8 im2_flag; /* 1= Interlace mode 2 is being used */ uint8 interlaced; /* 1: Interlaced mode 1 or 2 */ -uint8 vdp_pal = 0; /* 1: PAL , 0: NTSC (default) */ +uint8 vdp_pal; /* 1: PAL , 0: NTSC (default) */ uint8 vdp_rate; /* PAL: 50hz, NTSC: 60hz */ uint16 lines_per_frame; /* PAL: 313 lines, NTSC: 262 lines */ /* Tables that define the playfield layout */ -static const uint8 shift_table[] = { 6, 7, 0, 8 }; -static const uint8 col_mask_table[] = { 0x0F, 0x1F, 0x0F, 0x3F }; -static const uint16 row_mask_table[] = { 0x0FF, 0x1FF, 0x2FF, 0x3FF }; -static const uint32 y_mask_table[] = { 0x1FC0, 0x1F80, 0x1FC0, 0x1F00 }; +static const uint8 shift_table[] = { 6, 7, 0, 8 }; +static const uint8 col_mask_table[] = { 0x0F, 0x1F, 0x0F, 0x3F }; +static const uint16 row_mask_table[] = { 0x0FF, 0x1FF, 0x2FF, 0x3FF }; +static const uint32 y_mask_table[] = { 0x1FC0, 0x1F80, 0x1FC0, 0x1F00 }; -static uint16 sat_base_mask; /* Base bits of SAT */ -static uint16 sat_addr_mask; /* Index bits of SAT */ -static uint32 dma_endCycles; /* 68k cycles to DMA end */ -static uint8 dma_type; /* Type of DMA */ +static uint16 sat_base_mask; /* Base bits of SAT */ +static uint16 sat_addr_mask; /* Index bits of SAT */ +static uint32 dma_endCycles; /* 68k cycles to DMA end */ +static uint8 dma_type; /* DMA mode */ /* DMA Timings @@ -159,8 +159,8 @@ void vdp_reset(void) code = 0; pending = 0; - status = 0x200; /* fifo empty */ - status |= vdp_pal; + status = 0x200; /* fifo empty */ + status |= vdp_pal; /* PAL/NTSC flag */ ntab = 0; ntbb = 0;