[Core/SG] improved SG-1000 cartridge memory mapping (fixes Safari Hunting crash when accessing unmapped ROM area)

This commit is contained in:
EkeEke 2017-12-13 23:09:29 +01:00
parent 515e2ff0d1
commit 46f3e640e8

View File

@ -43,8 +43,9 @@
#define MAPPER_NONE (0x00) #define MAPPER_NONE (0x00)
#define MAPPER_TEREBI (0x01) #define MAPPER_TEREBI (0x01)
#define MAPPER_RAM_2K (0x02) #define MAPPER_RAM_2K (0x02)
#define MAPPER_RAM_8K_EXT1 (0x03) #define MAPPER_RAM_8K (0x03)
#define MAPPER_RAM_8K_EXT2 (0x04) #define MAPPER_RAM_8K_EXT1 (0x04)
#define MAPPER_RAM_8K_EXT2 (0x05)
#define MAPPER_SEGA (0x10) #define MAPPER_SEGA (0x10)
#define MAPPER_SEGA_X (0x11) #define MAPPER_SEGA_X (0x11)
#define MAPPER_93C46 (0x12) #define MAPPER_93C46 (0x12)
@ -146,11 +147,13 @@ static const rominfo_t game_list[] =
{0xDD4A661B, 0, 0, 0, MAPPER_TEREBI, SYSTEM_SG, REGION_JAPAN_NTSC}, /* Terebi Oekaki */ {0xDD4A661B, 0, 0, 0, MAPPER_TEREBI, SYSTEM_SG, REGION_JAPAN_NTSC}, /* Terebi Oekaki */
/* games using 2KB external RAM (volatile) */ /* games using 2KB external RAM (volatile) */
{0x092F29D6, 0, 0, 0, MAPPER_RAM_2K, SYSTEM_SG, REGION_JAPAN_NTSC}, /* The Castle (J) */
{0xAF4F14BC, 0, 0, 0, MAPPER_RAM_2K, SYSTEM_SG, REGION_JAPAN_NTSC}, /* Othello (J) */ {0xAF4F14BC, 0, 0, 0, MAPPER_RAM_2K, SYSTEM_SG, REGION_JAPAN_NTSC}, /* Othello (J) */
{0x1D1A0CA3, 0, 0, 0, MAPPER_RAM_2K, SYSTEM_SGII, REGION_JAPAN_NTSC}, /* Othello (TW) */ {0x1D1A0CA3, 0, 0, 0, MAPPER_RAM_2K, SYSTEM_SGII, REGION_JAPAN_NTSC}, /* Othello (TW) */
/* games requiring SG-1000 II 8K RAM extension adapter */ /* games using 8KB external RAM (volatile) */
{0x092F29D6, 0, 0, 0, MAPPER_RAM_8K, SYSTEM_SG, REGION_JAPAN_NTSC}, /* The Castle (J) */
/* games requiring SG-1000 II 8K RAM extension adapters */
{0xCE5648C3, 0, 0, 0, MAPPER_RAM_8K_EXT1, SYSTEM_SGII, REGION_JAPAN_NTSC}, /* Bomberman Special [DahJee] (TW) */ {0xCE5648C3, 0, 0, 0, MAPPER_RAM_8K_EXT1, SYSTEM_SGII, REGION_JAPAN_NTSC}, /* Bomberman Special [DahJee] (TW) */
{0x223397A1, 0, 0, 0, MAPPER_RAM_8K_EXT1, SYSTEM_SGII, REGION_JAPAN_NTSC}, /* King's Valley (TW) */ {0x223397A1, 0, 0, 0, MAPPER_RAM_8K_EXT1, SYSTEM_SGII, REGION_JAPAN_NTSC}, /* King's Valley (TW) */
{0x281D2888, 0, 0, 0, MAPPER_RAM_8K_EXT1, SYSTEM_SGII, REGION_JAPAN_NTSC}, /* Knightmare (TW) */ {0x281D2888, 0, 0, 0, MAPPER_RAM_8K_EXT1, SYSTEM_SGII, REGION_JAPAN_NTSC}, /* Knightmare (TW) */
@ -464,22 +467,22 @@ void sms_cart_init(void)
/* ROM paging */ /* ROM paging */
if (cart_rom.mapper < MAPPER_SEGA) if (cart_rom.mapper < MAPPER_SEGA)
{ {
/* 1k ROM banks */ /* 1KB ROM banks */
cart_rom.pages = (cart.romsize + (1 << 10) - 1) >> 10; cart_rom.pages = (cart.romsize + (1 << 10) - 1) >> 10;
} }
else if (cart_rom.mapper & MAPPER_KOREA_8K) else if (cart_rom.mapper & MAPPER_KOREA_8K)
{ {
/* 8k ROM banks */ /* 8KB ROM banks */
cart_rom.pages = (cart.romsize + (1 << 13) - 1) >> 13; cart_rom.pages = (cart.romsize + (1 << 13) - 1) >> 13;
} }
else if (cart_rom.mapper & MAPPER_MULTI_32K) else if (cart_rom.mapper & MAPPER_MULTI_32K)
{ {
/* 32k ROM banks */ /* 32KB ROM banks */
cart_rom.pages = (cart.romsize + (1 << 15) - 1) >> 15; cart_rom.pages = (cart.romsize + (1 << 15) - 1) >> 15;
} }
else else
{ {
/* 16k ROM banks */ /* 16KB ROM banks */
cart_rom.pages = (cart.romsize + (1 << 14) - 1) >> 14; cart_rom.pages = (cart.romsize + (1 << 14) - 1) >> 14;
} }
@ -519,7 +522,7 @@ void sms_cart_init(void)
if (bios_size > 0xC000) if (bios_size > 0xC000)
{ {
/* assume SEGA mapper if BIOS ROM is larger than 48k */ /* assume SEGA mapper if BIOS ROM is larger than 48KB */
bios_rom.mapper = MAPPER_SEGA; bios_rom.mapper = MAPPER_SEGA;
bios_rom.pages = bios_size >> 14; bios_rom.pages = bios_size >> 14;
} }
@ -582,7 +585,7 @@ void sms_cart_reset(void)
break; break;
} }
/* check if BIOS is larger than 1k */ /* check if BIOS is larger than 1KB */
if (bios_rom.pages > 1) if (bios_rom.pages > 1)
{ {
/* enable BIOS ROM */ /* enable BIOS ROM */
@ -612,7 +615,7 @@ void sms_cart_reset(void)
/* reset Z80 memory map */ /* reset Z80 memory map */
mapper_reset(); mapper_reset();
/* 1k BIOS special case (Majesco GG) */ /* 1KB BIOS special case (Majesco GG) */
if (bios_rom.pages == 1) if (bios_rom.pages == 1)
{ {
/* BIOS ROM is mapped to $0000-$03FF */ /* BIOS ROM is mapped to $0000-$03FF */
@ -643,7 +646,7 @@ void sms_cart_switch(uint8 mode)
/* BIOS ROM enabled ? */ /* BIOS ROM enabled ? */
if (mode & 0x08) if (mode & 0x08)
{ {
/* check if BIOS ROM is larger than 1K */ /* check if BIOS ROM is larger than 1KB */
if (bios_rom.pages > 1) if (bios_rom.pages > 1)
{ {
/* map BIOS ROM */ /* map BIOS ROM */
@ -683,7 +686,7 @@ void sms_cart_switch(uint8 mode)
/* reset Z80 memory map */ /* reset Z80 memory map */
mapper_reset(); mapper_reset();
/* 1k BIOS special case (Majesco GG) */ /* 1KB BIOS special case (Majesco GG) */
if ((bios_rom.pages == 1) && ((mode & 0x48) == 0x08)) if ((bios_rom.pages == 1) && ((mode & 0x48) == 0x08))
{ {
/* BIOS ROM is mapped to $0000-$03FF */ /* BIOS ROM is mapped to $0000-$03FF */
@ -746,10 +749,10 @@ static void mapper_reset(void)
/* reset $C000-$FFFF mapping */ /* reset $C000-$FFFF mapping */
if (cart_rom.mapper == MAPPER_RAM_8K_EXT2) if (cart_rom.mapper == MAPPER_RAM_8K_EXT2)
{ {
/* 8k RAM extension adapter (type B) */ /* 8KB RAM extension adapter (type B) */
for (i = 0x30; i < 0x40; i++) for (i = 0x30; i < 0x40; i++)
{ {
/* $C000-$FFFF mapped to 8k external RAM (mirrored) */ /* $C000-$FFFF mapped to 8KB external RAM (mirrored) */
z80_readmap[i] = z80_writemap[i] = &work_ram[(i & 0x07) << 10]; z80_readmap[i] = z80_writemap[i] = &work_ram[(i & 0x07) << 10];
} }
} }
@ -758,7 +761,7 @@ static void mapper_reset(void)
/* SG-1000 II clone hardware with 2KB internal RAM */ /* SG-1000 II clone hardware with 2KB internal RAM */
for (i = 0x30; i < 0x40; i++) for (i = 0x30; i < 0x40; i++)
{ {
/* $C000-$FFFF mapped to 2k internal RAM (mirrored) */ /* $C000-$FFFF mapped to 2KB internal RAM (mirrored) */
z80_readmap[i] = z80_writemap[i] = &work_ram[(i & 0x01) << 10]; z80_readmap[i] = z80_writemap[i] = &work_ram[(i & 0x01) << 10];
} }
} }
@ -767,7 +770,7 @@ static void mapper_reset(void)
/* default SG-1000 hardware has only 1KB internal RAM */ /* default SG-1000 hardware has only 1KB internal RAM */
for (i = 0x30; i < 0x40; i++) for (i = 0x30; i < 0x40; i++)
{ {
/* $C000-$FFFF mapped to 1k internal RAM (mirrored) */ /* $C000-$FFFF mapped to 1KB internal RAM (mirrored) */
z80_readmap[i] = z80_writemap[i] = &work_ram[0]; z80_readmap[i] = z80_writemap[i] = &work_ram[0];
} }
} }
@ -776,7 +779,7 @@ static void mapper_reset(void)
/* Mark III / Master System / Game Gear hardware */ /* Mark III / Master System / Game Gear hardware */
for (i = 0x30; i < 0x40; i++) for (i = 0x30; i < 0x40; i++)
{ {
/* $C000-$FFFF mapped to 8k internal RAM (mirrored) */ /* $C000-$FFFF mapped to 8KB internal RAM (mirrored) */
z80_readmap[i] = z80_writemap[i] = &work_ram[(i & 0x07) << 10]; z80_readmap[i] = z80_writemap[i] = &work_ram[(i & 0x07) << 10];
} }
} }
@ -797,39 +800,81 @@ static void mapper_reset(void)
return; return;
} }
/* reset $0000-$BFFF mapping */
for (i = 0x00; i < 0x30; i++)
{
/* by default, $0000-$BFFF is mapped to cartridge ROM (first 48k) */
z80_readmap[i] = &slot.rom[i << 10];
z80_writemap[i] = cart.rom + 0x510000; /* unused area */
}
/* reset cartridge hardware mapping */ /* reset cartridge hardware mapping */
if (slot.mapper == MAPPER_RAM_8K_EXT1) if (slot.mapper < MAPPER_SEGA)
{ {
/* 8k RAM extension adapter (type A) */ /* $0000-$7FFF mapping */
for (i = 0x08; i < 0x10; i++) for (i = 0x00; i < 0x20; i++)
{ {
/* $2000-$3FFF mapped to 8k external RAM */ /* by default, $0000-$7FFF mapped to cartridge ROM lower KB (mirrored if less than 32KB) */
z80_readmap[i] = z80_writemap[i] = &work_ram[0x2000 + ((i & 0x07) << 10)]; z80_readmap[i] = &slot.rom[(i % slot.pages) << 10];
z80_writemap[i] = cart.rom + 0x510000; /* unused area */
}
/* 8KB RAM extension adapter (type A) */
if (slot.mapper == MAPPER_RAM_8K_EXT1)
{
for (i = 0x08; i < 0x10; i++)
{
/* $2000-$3FFF mapped to 8KB external RAM */
z80_readmap[i] = z80_writemap[i] = &work_ram[0x2000 + ((i & 0x07) << 10)];
}
}
/* $8000-$BFFF mapping */
if (slot.mapper == MAPPER_RAM_8K)
{
/* 8KB on-board RAM (The Castle) */
for (i = 0x20; i < 0x30; i++)
{
/* $8000-$BFFF mapped to 8KB external RAM (mirrored) */
z80_readmap[i] = z80_writemap[i] = &work_ram[0x2000 + ((i & 0x07) << 10)];
}
}
else if (slot.mapper == MAPPER_RAM_2K)
{
/* 2KB on-board RAM (Othello) */
for (i = 0x20; i < 0x30; i++)
{
/* $8000-$BFFF mapped to 2KB external RAM (mirrored) */
z80_readmap[i] = z80_writemap[i] = &work_ram[0x2000 + ((i & 0x01) << 10)];
}
}
else if (slot.pages <= 0x20)
{
/* cartridge ROM lower than 32KB */
for (i = 0x20; i < 0x30; i++)
{
/* $8000-$BFFF mapped to unused area */
z80_writemap[i] = cart.rom + 0x510000;
z80_readmap[i] = cart.rom + 0x510400;
}
}
else
{
/* cartridge ROM up to 48KB */
for (i = 0x20; i < 0x30; i++)
{
/* $8000-$BFFF mapped to cartridge ROM upper KB (mirrored if less than 48KB) */
z80_readmap[i] = &slot.rom[(0x20 + (i % (slot.pages - 0x20))) << 10];
z80_writemap[i] = cart.rom + 0x510000; /* unused area */
}
} }
} }
else if (slot.mapper == MAPPER_RAM_2K) else
{ {
/* 2k on-board RAM (The Castle, Othello) */ /* reset $0000-$BFFF mapping */
for (i = 0x20; i < 0x30; i++) for (i = 0x00; i < 0x30; i++)
{ {
/* $8000-$BFFF mapped to 2k external RAM (mirrored) */ /* by default, $0000-$BFFF is mapped to cartridge ROM lower 48KB */
z80_readmap[i] = z80_writemap[i] = &work_ram[0x2000 + ((i & 0x07) << 10)]; z80_readmap[i] = &slot.rom[i << 10];
z80_writemap[i] = cart.rom + 0x510000; /* unused area */
} }
}
else if (slot.mapper >= MAPPER_SEGA)
{
/* reset ROM paging hardware */ /* reset ROM paging hardware */
if (slot.mapper & MAPPER_KOREA_8K) if (slot.mapper & MAPPER_KOREA_8K)
{ {
/* 8k pages */ /* 8KB pages */
mapper_8k_w(0,slot.fcr[0]); mapper_8k_w(0,slot.fcr[0]);
mapper_8k_w(1,slot.fcr[1]); mapper_8k_w(1,slot.fcr[1]);
mapper_8k_w(2,slot.fcr[2]); mapper_8k_w(2,slot.fcr[2]);
@ -838,7 +883,7 @@ static void mapper_reset(void)
/* "Nemesis" mapper specific */ /* "Nemesis" mapper specific */
if (slot.mapper == MAPPER_MSX_NEMESIS) if (slot.mapper == MAPPER_MSX_NEMESIS)
{ {
/* first 8k page is mapped to last 8k ROM bank */ /* first 8KB page is mapped to last 8KB ROM bank */
for (i = 0x00; i < 0x08; i++) for (i = 0x00; i < 0x08; i++)
{ {
z80_readmap[i] = &slot.rom[(0x0f << 13) | ((i & 0x07) << 10)]; z80_readmap[i] = &slot.rom[(0x0f << 13) | ((i & 0x07) << 10)];
@ -847,12 +892,12 @@ static void mapper_reset(void)
} }
else if (slot.mapper & MAPPER_MULTI_32K) else if (slot.mapper & MAPPER_MULTI_32K)
{ {
/* 32k pages */ /* 32KB pages */
mapper_32k_w(slot.fcr[0]); mapper_32k_w(slot.fcr[0]);
} }
else else
{ {
/* 16k pages */ /* 16KB pages */
mapper_16k_w(0,slot.fcr[0]); mapper_16k_w(0,slot.fcr[0]);
mapper_16k_w(1,slot.fcr[1]); mapper_16k_w(1,slot.fcr[1]);
mapper_16k_w(2,slot.fcr[2]); mapper_16k_w(2,slot.fcr[2]);
@ -863,12 +908,10 @@ static void mapper_reset(void)
/* reset Z80 memory handlers */ /* reset Z80 memory handlers */
switch (slot.mapper) switch (slot.mapper)
{ {
case MAPPER_NONE: case MAPPER_SEGA:
case MAPPER_RAM_2K: case MAPPER_SEGA_X:
case MAPPER_RAM_8K_EXT1:
case MAPPER_RAM_8K_EXT2:
z80_readmem = read_mapper_default; z80_readmem = read_mapper_default;
z80_writemem = write_mapper_none; z80_writemem = write_mapper_sega;
break; break;
case MAPPER_CODIES: case MAPPER_CODIES:
@ -919,7 +962,7 @@ static void mapper_reset(void)
default: default:
z80_readmem = read_mapper_default; z80_readmem = read_mapper_default;
z80_writemem = write_mapper_sega; z80_writemem = write_mapper_none;
break; break;
} }
} }
@ -928,16 +971,16 @@ static void mapper_8k_w(int offset, unsigned char data)
{ {
int i; int i;
/* cartridge ROM page (8k) */ /* cartridge ROM page (8KB) */
uint8 *page = &slot.rom[(data % slot.pages) << 13]; uint8 *page = &slot.rom[(data % slot.pages) << 13];
/* Save frame control register data */ /* Save frame control register data */
slot.fcr[offset] = data; slot.fcr[offset] = data;
/* 4 x 8k banks */ /* 4 x 8KB banks */
switch (offset & 3) switch (offset & 3)
{ {
case 0: /* cartridge ROM bank (8k) at $8000-$9FFF */ case 0: /* cartridge ROM bank (8KB) at $8000-$9FFF */
{ {
for (i = 0x20; i < 0x28; i++) for (i = 0x20; i < 0x28; i++)
{ {
@ -946,7 +989,7 @@ static void mapper_8k_w(int offset, unsigned char data)
break; break;
} }
case 1: /* cartridge ROM bank (8k) at $A000-$BFFF */ case 1: /* cartridge ROM bank (8KB) at $A000-$BFFF */
{ {
for (i = 0x28; i < 0x30; i++) for (i = 0x28; i < 0x30; i++)
{ {
@ -955,7 +998,7 @@ static void mapper_8k_w(int offset, unsigned char data)
break; break;
} }
case 2: /* cartridge ROM bank (8k) at $4000-$5FFF */ case 2: /* cartridge ROM bank (8KB) at $4000-$5FFF */
{ {
for (i = 0x10; i < 0x18; i++) for (i = 0x10; i < 0x18; i++)
{ {
@ -964,7 +1007,7 @@ static void mapper_8k_w(int offset, unsigned char data)
break; break;
} }
case 3: /* cartridge ROM bank (8k) at $6000-$7FFF */ case 3: /* cartridge ROM bank (8KB) at $6000-$7FFF */
{ {
for (i = 0x18; i < 0x20; i++) for (i = 0x18; i < 0x20; i++)
{ {
@ -984,7 +1027,7 @@ static void mapper_16k_w(int offset, unsigned char data)
{ {
int i; int i;
/* cartridge ROM page (16k) */ /* cartridge ROM page (16KB) */
uint8 page = data % slot.pages; uint8 page = data % slot.pages;
/* page index increment (SEGA mapper only) */ /* page index increment (SEGA mapper only) */
@ -1002,7 +1045,7 @@ static void mapper_16k_w(int offset, unsigned char data)
{ {
if (data & 0x08) if (data & 0x08)
{ {
/* external RAM (upper or lower 16K) mapped at $8000-$BFFF */ /* external RAM (upper or lower 16KB) mapped at $8000-$BFFF */
for (i = 0x20; i < 0x30; i++) for (i = 0x20; i < 0x30; i++)
{ {
z80_readmap[i] = z80_writemap[i] = &sram.sram[((data & 0x04) << 12) + ((i & 0x0F) << 10)]; z80_readmap[i] = z80_writemap[i] = &sram.sram[((data & 0x04) << 12) + ((i & 0x0F) << 10)];
@ -1010,7 +1053,7 @@ static void mapper_16k_w(int offset, unsigned char data)
} }
else else
{ {
/* cartridge ROM page (16k) */ /* cartridge ROM page (16KB) */
page = slot.fcr[3] % slot.pages; page = slot.fcr[3] % slot.pages;
/* page index increment (SEGA mapper) */ /* page index increment (SEGA mapper) */
@ -1029,7 +1072,7 @@ static void mapper_16k_w(int offset, unsigned char data)
if (data & 0x10) if (data & 0x10)
{ {
/* external RAM (lower 16K) mapped at $C000-$FFFF */ /* external RAM (lower 16KB) mapped at $C000-$FFFF */
for (i = 0x30; i < 0x40; i++) for (i = 0x30; i < 0x40; i++)
{ {
z80_readmap[i] = z80_writemap[i] = &sram.sram[(i & 0x0F) << 10]; z80_readmap[i] = z80_writemap[i] = &sram.sram[(i & 0x0F) << 10];
@ -1037,7 +1080,7 @@ static void mapper_16k_w(int offset, unsigned char data)
} }
else else
{ {
/* internal RAM (8K mirrorred) mapped at $C000-$FFFF */ /* internal RAM (8KB mirrored) mapped at $C000-$FFFF */
for (i = 0x30; i < 0x40; i++) for (i = 0x30; i < 0x40; i++)
{ {
z80_readmap[i] = z80_writemap[i] = &work_ram[(i & 0x07) << 10]; z80_readmap[i] = z80_writemap[i] = &work_ram[(i & 0x07) << 10];
@ -1046,9 +1089,9 @@ static void mapper_16k_w(int offset, unsigned char data)
break; break;
} }
case 1: /* cartridge ROM bank (16k) at $0000-$3FFF */ case 1: /* cartridge ROM bank (16KB) at $0000-$3FFF */
{ {
/* first 1k is not fixed (CODEMASTER or MULTI mappers only) */ /* first 1KB is not fixed (CODEMASTER or MULTI mappers only) */
if ((slot.mapper == MAPPER_CODIES) || (slot.mapper == MAPPER_MULTI_16K)) if ((slot.mapper == MAPPER_CODIES) || (slot.mapper == MAPPER_MULTI_16K))
{ {
z80_readmap[0] = &slot.rom[(page << 14)]; z80_readmap[0] = &slot.rom[(page << 14)];
@ -1061,7 +1104,7 @@ static void mapper_16k_w(int offset, unsigned char data)
break; break;
} }
case 2: /* cartridge ROM bank (16k) at $4000-$7FFF */ case 2: /* cartridge ROM bank (16KB) at $4000-$7FFF */
{ {
for (i = 0x10; i < 0x20; i++) for (i = 0x10; i < 0x20; i++)
{ {
@ -1073,7 +1116,7 @@ static void mapper_16k_w(int offset, unsigned char data)
{ {
if (data & 0x80) if (data & 0x80)
{ {
/* external RAM (8k) mapped at $A000-$BFFF */ /* external RAM (8KB) mapped at $A000-$BFFF */
for (i = 0x28; i < 0x30; i++) for (i = 0x28; i < 0x30; i++)
{ {
z80_readmap[i] = z80_writemap[i] = &sram.sram[(i & 0x0F) << 10]; z80_readmap[i] = z80_writemap[i] = &sram.sram[(i & 0x0F) << 10];
@ -1081,7 +1124,7 @@ static void mapper_16k_w(int offset, unsigned char data)
} }
else else
{ {
/* cartridge ROM page (16k) */ /* cartridge ROM page (16KB) */
page = slot.fcr[3] % slot.pages; page = slot.fcr[3] % slot.pages;
/* cartridge ROM mapped at $A000-$BFFF */ /* cartridge ROM mapped at $A000-$BFFF */
@ -1095,21 +1138,21 @@ static void mapper_16k_w(int offset, unsigned char data)
break; break;
} }
case 3: /* cartridge ROM bank (16k) at $8000-$BFFF */ case 3: /* cartridge ROM bank (16KB) at $8000-$BFFF */
{ {
/* check that external RAM (16k) is not mapped at $8000-$BFFF (SEGA mapper only) */ /* check that external RAM (16KB) is not mapped at $8000-$BFFF (SEGA mapper only) */
if ((slot.fcr[0] & 0x08)) break; if ((slot.fcr[0] & 0x08)) break;
/* first 8k */ /* first 8KB */
for (i = 0x20; i < 0x28; i++) for (i = 0x20; i < 0x28; i++)
{ {
z80_readmap[i] = &slot.rom[(page << 14) | ((i & 0x0F) << 10)]; z80_readmap[i] = &slot.rom[(page << 14) | ((i & 0x0F) << 10)];
} }
/* check that cartridge RAM (8k) is not mapped at $A000-$BFFF (CODEMASTER mapper only) */ /* check that cartridge RAM (8KB) is not mapped at $A000-$BFFF (CODEMASTER mapper only) */
if ((slot.mapper == MAPPER_CODIES) && (slot.fcr[2] & 0x80)) break; if ((slot.mapper == MAPPER_CODIES) && (slot.fcr[2] & 0x80)) break;
/* last 8k */ /* last 8KB */
for (i = 0x28; i < 0x30; i++) for (i = 0x28; i < 0x30; i++)
{ {
z80_readmap[i] = &slot.rom[(page << 14) | ((i & 0x0F) << 10)]; z80_readmap[i] = &slot.rom[(page << 14) | ((i & 0x0F) << 10)];
@ -1128,19 +1171,19 @@ static void mapper_32k_w(unsigned char data)
{ {
int i; int i;
/* cartridge ROM page (32k) */ /* cartridge ROM page (32KB) */
uint8 *page = &slot.rom[(data % slot.pages) << 15]; uint8 *page = &slot.rom[(data % slot.pages) << 15];
/* Save frame control register data */ /* Save frame control register data */
slot.fcr[0] = data; slot.fcr[0] = data;
/* selected page (32k) is mapped at $0000-$7FFF */ /* selected page (32KB) is mapped at $0000-$7FFF */
for (i = 0x00; i < 0x20; i++) for (i = 0x00; i < 0x20; i++)
{ {
z80_readmap[i] = &page[i << 10]; z80_readmap[i] = &page[i << 10];
} }
/* first 16K is mirrored at $8000-$BFFF */ /* first 16KB is mirrored at $8000-$BFFF */
for (i = 0x20; i < 0x30; i++) for (i = 0x20; i < 0x30; i++)
{ {
z80_readmap[i] = z80_readmap[i & 0x0F]; z80_readmap[i] = z80_readmap[i & 0x0F];
@ -1379,10 +1422,10 @@ static unsigned char read_mapper_korea_8k(unsigned int address)
{ {
unsigned char data = z80_readmap[address >> 10][address & 0x03FF]; unsigned char data = z80_readmap[address >> 10][address & 0x03FF];
/* 16k page */ /* 16KB page */
unsigned char page = address >> 14; unsigned char page = address >> 14;
/* $4000-$7FFFF and $8000-$BFFF area are protected */ /* $4000-$7FFF and $8000-$BFFF area are protected */
if (((page == 1) && (slot.fcr[2] & 0x80)) || ((page == 2) && (slot.fcr[0] & 0x80))) if (((page == 1) && (slot.fcr[2] & 0x80)) || ((page == 2) && (slot.fcr[0] & 0x80)))
{ {
/* bit-swapped value */ /* bit-swapped value */