summaryrefslogtreecommitdiffstatshomepage
path: root/src/mess/machine/sega8_slot.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mess/machine/sega8_slot.c')
-rw-r--r--src/mess/machine/sega8_slot.c122
1 files changed, 61 insertions, 61 deletions
diff --git a/src/mess/machine/sega8_slot.c b/src/mess/machine/sega8_slot.c
index 31d8245d966..5b4f53bb810 100644
--- a/src/mess/machine/sega8_slot.c
+++ b/src/mess/machine/sega8_slot.c
@@ -1,13 +1,13 @@
/***********************************************************************************************************
-
-
+
+
Sega 8-bit cart emulation
(through slot devices)
Master System (Mark III) and Game Gear memory map can access 3 x 16K banks of ROM in
- 0x0000-0xbfff memory range. These banks can however point to different ROM or RAM area
+ 0x0000-0xbfff memory range. These banks can however point to different ROM or RAM area
of the cart (or to BIOS banks, but these are handled directly in SMS emulation).
-
+
Hence, carts can interface with the main system through the following handlers
* read_cart : to read from ROM/RAM in memory range [0000-bfff]
* write_cart : to write to ROM/RAM in memory range [0000-bfff]
@@ -17,10 +17,10 @@
Note about Sega Card / MyCard: the data contained in these matches the data in carts, it's only
the connector to be different. We emulate this with a variant of the slot having different media
switch and different interface (the latter not implemented yet)
-
+
TODO:
- investigate SG-1000 carts so to reduce duplicated code and to add full .sg support to sg1000m3
-
+
***********************************************************************************************************/
@@ -81,8 +81,8 @@ void device_sega8_cart_interface::rom_alloc(running_machine &machine, UINT32 siz
m_rom = auto_alloc_array_clear(machine, UINT8, size);
m_rom_size = size;
m_rom_page_count = size / 0x4000;
- if (!m_rom_page_count)
- m_rom_page_count = 1; // we compute rom pages through (XXX % m_rom_page_count)!
+ if (!m_rom_page_count)
+ m_rom_page_count = 1; // we compute rom pages through (XXX % m_rom_page_count)!
late_bank_setup();
}
}
@@ -221,14 +221,14 @@ static const char *sega8_get_slot(int type)
int sega8_cart_slot_device::verify_cart( UINT8 *magic, int size )
{
int retval = IMAGE_VERIFY_FAIL;
-
+
// Verify the file is a valid image - check $7ff0 for "TMR SEGA"
if (size >= 0x8000)
{
if (!strncmp((char*)&magic[0x7ff0], "TMR SEGA", 8))
- retval = IMAGE_VERIFY_PASS;
+ retval = IMAGE_VERIFY_PASS;
}
-
+
return retval;
}
@@ -256,19 +256,19 @@ void sega8_cart_slot_device::set_lphaser_xoffset( UINT8 *rom, int size )
{
if (!memcmp(&rom[0x7ff0], signatures[0], 16) || !memcmp(&rom[0x7ff0], signatures[1], 16))
xoff = 41;
-
+
if (!memcmp(&rom[0x7ff0], signatures[2], 16))
xoff = 50;
-
+
if (!memcmp(&rom[0x7ff0], signatures[3], 16))
xoff = 48;
-
+
if (!memcmp(&rom[0x7ff0], signatures[4], 16))
xoff = 45;
-
+
if (!memcmp(&rom[0x7ff0], signatures[5], 16))
xoff = 54;
-
+
}
m_cart->set_lphaser_xoffs(xoff);
@@ -313,11 +313,11 @@ void sega8_cart_slot_device::setup_ram()
// Codemasters cart can have 64KB of RAM (Ernie Els Golf? or 8KB?) and no battery
m_cart->ram_alloc(machine(), 0x10000);
m_cart->set_has_battery(FALSE);
- }
+ }
else
{
- // for generic carts loaded from fullpath we have no way to know exactly if there was RAM,
- // how much RAM was in the cart and if there was a battery so we always alloc 32KB and
+ // for generic carts loaded from fullpath we have no way to know exactly if there was RAM,
+ // how much RAM was in the cart and if there was a battery so we always alloc 32KB and
// we save its content only if the game enable the RAM
m_cart->set_late_battery(TRUE);
m_cart->ram_alloc(machine(), 0x08000);
@@ -328,13 +328,13 @@ void sega8_cart_slot_device::setup_ram()
// from softlist we rely on the xml to only allocate the correct amount of RAM and to save it only if a battery was present
const char *battery = get_feature("battery");
m_cart->set_late_battery(FALSE);
-
+
if (get_software_region_length("ram"))
m_cart->ram_alloc(machine(), get_software_region_length("ram"));
if (battery && !strcmp(battery, "yes"))
m_cart->set_has_battery(TRUE);
- }
+ }
}
bool sega8_cart_slot_device::call_load()
@@ -350,21 +350,21 @@ bool sega8_cart_slot_device::call_load()
seterror(IMAGE_ERROR_UNSPECIFIED, "Attempted loading a card larger than 32KB");
return IMAGE_INIT_FAIL;
}
-
+
// check for header
if ((len % 0x4000) == 512)
{
offset = 512;
len -= 512;
}
-
+
// make sure that we only get complete (0x4000) rom banks
if (len & 0x3fff)
len = ((len >> 14) + 1) << 14;
-
+
m_cart->rom_alloc(machine(), len);
ROM = m_cart->get_rom_base();
-
+
if (software_entry() == NULL)
{
fseek(offset, SEEK_SET);
@@ -372,7 +372,7 @@ bool sega8_cart_slot_device::call_load()
}
else
memcpy(ROM, get_software_region("rom") + offset, len);
-
+
/* check the image */
if (verify_cart(ROM, len) == IMAGE_VERIFY_FAIL)
logerror("Warning loading image: verify_cart failed\n");
@@ -381,11 +381,11 @@ bool sega8_cart_slot_device::call_load()
m_type = sega8_get_pcb_id(get_feature("slot") ? get_feature("slot") : "rom");
else
m_type = get_cart_type(ROM, len);
-
+
set_lphaser_xoffset(ROM, len);
setup_ram();
-
+
// Check for gamegear cartridges with PIN 42 set to SMS mode
if (software_entry() != NULL)
{
@@ -398,11 +398,11 @@ bool sega8_cart_slot_device::call_load()
// we attempt to load a battery because the game might have it!
if (m_cart->get_ram_size() && (m_cart->get_has_battery() || m_cart->get_late_battery()))
battery_load(m_cart->get_ram_base(), m_cart->get_ram_size(), 0x00);
-
+
//printf("Type: %s\n", sega8_get_slot(type));
-
+
internal_header_logging(ROM + offset, len, m_cart->get_ram_size());
-
+
return IMAGE_INIT_PASS;
}
@@ -452,19 +452,19 @@ bool sega8_cart_slot_device::call_softlist_load(char *swlist, char *swname, rom_
- gamegear Pete Sampras Tennis
- gamegear S.S. Lucifer
- 95 - gamegear Micro Machines 2 - Turbo Tournament
-
+
The Korean game Jang Pung II also seems to use a codemasters style mapper.
*/
int sms_state::detect_codemasters_mapper( UINT8 *rom )
{
static const UINT8 jang_pung2[16] = { 0x00, 0xba, 0x38, 0x0d, 0x00, 0xb8, 0x38, 0x0c, 0x00, 0xb6, 0x38, 0x0b, 0x00, 0xb4, 0x38, 0x0a };
-
+
if (((rom[0x7fe0] & 0x0f ) <= 9) && (rom[0x7fe3] == 0x93 || rom[0x7fe3] == 0x94 || rom[0x7fe3] == 0x95) && rom[0x7fef] == 0x00)
return 1;
-
+
if (!memcmp(&rom[0x7ff0], jang_pung2, 16))
return 1;
-
+
return 0;
}
@@ -477,7 +477,7 @@ int sms_state::detect_korean_mapper( UINT8 *rom )
{ 0x41, 0x48, 0x37, 0x37, 0x44, 0x37, 0x4e, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20 }, /* Sangokushi 3 */
};
int i;
-
+
for (i = 0; i < 2; i++)
{
if (!memcmp(&rom[0x7ff0], signatures[i], 16))
@@ -518,9 +518,9 @@ int sega8_cart_slot_device::get_cart_type(UINT8 *ROM, UINT32 len)
{ i += 2; _6000++; continue; }
}
}
-
+
LOG(("Mapper test: _0002 = %d, _8000 = %d, _a000 = %d, _ffff = %d\n", _0002, _8000, _a000, _ffff));
-
+
// 2 is a security measure, although tests on existing ROM showed it was not needed
if (_0002 > _ffff + 2 || (_0002 > 0 && _ffff == 0))
{
@@ -545,13 +545,13 @@ int sega8_cart_slot_device::get_cart_type(UINT8 *ROM, UINT32 len)
if (len >= 0x8000)
{
int x2000_3000 = 0, xd000_e000_f000 = 0, x2000_ff = 0;
-
+
for (int i = 0; i < 0x8000; i++)
{
if (ROM[i] == 0x32)
{
UINT16 addr = ROM[i + 1] | (ROM[i + 2] << 8);
-
+
switch (addr & 0xf000)
{
case 0x2000:
@@ -559,7 +559,7 @@ int sega8_cart_slot_device::get_cart_type(UINT8 *ROM, UINT32 len)
i += 2;
x2000_3000++;
break;
-
+
case 0xd000:
case 0xe000:
case 0xf000:
@@ -582,7 +582,7 @@ int sega8_cart_slot_device::get_cart_type(UINT8 *ROM, UINT32 len)
type = SEGA8_DAHJEE_TYPEA;
}
}
-
+
// Terebi Oekaki (TV Draw)
if (!strncmp((const char *)&ROM[0x13b3], "annakmn", 7))
type = SEGA8_TEREBIOEKAKI;
@@ -590,16 +590,16 @@ int sega8_cart_slot_device::get_cart_type(UINT8 *ROM, UINT32 len)
// The Castle (ROM+RAM)
if (!strncmp((const char *)&ROM[0x1cc3], "ASCII 1986", 10))
type = SEGA8_CASTLE;
-
+
// BASIC Level 3
if (!strncmp((const char *)&ROM[0x6a20], "SC-3000 BASIC Level 3 ver 1.0", 29))
type = SEGA8_BASIC_L3;
-
+
// Music Editor
if (!strncmp((const char *)&ROM[0x0841], "PIANO", 5) || !strncmp((const char *)&ROM[0x0841], "music", 5))
type = SEGA8_MUSIC_EDITOR;
-
-
+
+
return type;
}
/*-------------------------------------------------
@@ -724,12 +724,12 @@ void sega8_cart_slot_device::internal_header_logging(UINT8 *ROM, UINT32 len, UIN
0x10000,
0x20000,
};
-
+
char reserved[10];
UINT8 version, csum_size, region, serial[3];
UINT16 checksum, csum = 0;
UINT32 csum_end = 0;
-
+
// LOG FILE DETAILS
logerror("FILE DETAILS\n" );
logerror("============\n" );
@@ -741,30 +741,30 @@ void sega8_cart_slot_device::internal_header_logging(UINT8 *ROM, UINT32 len, UIN
if (nvram_len)
logerror("RAM (Allocated) Size: 0x%X - Battery: %s\n", nvram_len, m_cart->get_has_battery() ? "Yes" : "No");
logerror("\n" );
-
-
+
+
// LOG HEADER DETAILS
if (len < 0x8000)
return;
for (int i = 0; i < 10; i++)
reserved[i] = ROM[0x7ff0 + i];
-
+
checksum = ROM[0x7ffa] | (ROM[0x7ffb] << 8);
-
+
for (int i = 0; i < 3; i++)
serial[i] = ROM[0x7ffc + i];
serial[2] &= 0x0f;
-
+
version = (ROM[0x7ffe] & 0xf0) >> 4;
-
+
csum_size = ROM[0x7fff] & 0x0f;
csum_end = csum_length[csum_size];
if (!csum_end || csum_end > len)
csum_end = len;
-
+
region = (ROM[0x7fff] & 0xf0) >> 4;
-
+
// compute cart checksum to compare with expected one
for (int i = 0; i < csum_end; i++)
{
@@ -772,9 +772,9 @@ void sega8_cart_slot_device::internal_header_logging(UINT8 *ROM, UINT32 len, UIN
{
csum += ROM[i];
csum &= 0xffff;
- }
+ }
}
-
+
logerror("INTERNAL HEADER\n" );
logerror("===============\n" );
logerror("Reserved String: %.10s\n", reserved);
@@ -785,12 +785,12 @@ void sega8_cart_slot_device::internal_header_logging(UINT8 *ROM, UINT32 len, UIN
logerror("Software Revision: %x\n", version);
logerror("\n" );
-
+
if (m_type == SEGA8_CODEMASTERS)
{
UINT8 day, month, year, hour, minute;
csum = 0;
-
+
day = ROM[0x7fe1];
month = ROM[0x7fe2];
year = ROM[0x7fe3];
@@ -808,7 +808,7 @@ void sega8_cart_slot_device::internal_header_logging(UINT8 *ROM, UINT32 len, UIN
csum &= 0xffff;
}
}
-
+
logerror("CODEMASTERS HEADER\n" );
logerror("==================\n" );
logerror("Build date & time: %x/%x/%x %.2x:%.2x\n", day, month, year, hour, minute);