}\r
pdb_cleanup();\r
\r
- PicoIn.AHW &= PAHW_MCD|PAHW_SMS|PAHW_PICO;\r
+ PicoIn.AHW &= ~(PAHW_32X|PAHW_SVP);\r
\r
PicoCartMemSetup = NULL;\r
PicoDmaHook = NULL;\r
PicoInitPico();\r
\r
// setup correct memory map for loaded ROM\r
- switch (PicoIn.AHW) {\r
+ switch (PicoIn.AHW & ~(PAHW_GG|PAHW_SG|PAHW_SC)) {\r
default:\r
elprintf(EL_STATUS|EL_ANOMALY, "starting in unknown hw configuration: %x", PicoIn.AHW);\r
case 0:\r
for (i = 0; i < Pico.romsize; i += 4) {\r
unsigned v = CPU_BE2(*(u32 *) (Pico.rom + i));\r
if (a && v == a + 0x400) { // patch if 2 pointers with offset 0x400 are found\r
- printf("auto-patching @%06x: %08x->%08x\n", i, v, v - 0x100);\r
+ elprintf(EL_STATUS, "auto-patching @%06x: %08x->%08x\n", i, v, v - 0x100);\r
*(u32 *) (Pico.rom + i) = CPU_BE2(v - 0x100);\r
}\r
// detect a pointer into the incriminating area\r
for (i = 0; i < Pico.romsize; i += 4) {\r
unsigned v = CPU_BE2(*(u32 *) (Pico.rom + i));\r
if (a == 0xffffff8c && v == 0x5ee1) { // patch if 4-long xfer written to CHCR\r
- printf("auto-patching @%06x: %08x->%08x\n", i, v, v & ~0x800);\r
+ elprintf(EL_STATUS, "auto-patching @%06x: %08x->%08x\n", i, v, v & ~0x800);\r
*(u32 *) (Pico.rom + i) = CPU_BE2(v & ~0x800); // change to half-sized xfer\r
}\r
a = v;\r
PicoDrawUpdateHighPal();\r
\r
len = 256;\r
- if ((PicoIn.AHW & PAHW_SMS) && (Pico.m.hardware & (PMS_HW_GG|PMS_HW_LCD)) == (PMS_HW_GG|PMS_HW_LCD))\r
+ if ((PicoIn.AHW & PAHW_GG) && (Pico.m.hardware & PMS_HW_LCD))\r
len = 160;\r
else if (!(PicoIn.AHW & PAHW_SMS) && (Pico.video.reg[12]&1))\r
len = 320;\r
}\r
\r
len = 256;\r
- if ((PicoIn.AHW & PAHW_SMS) && (Pico.m.hardware & (PMS_HW_GG|PMS_HW_LCD)) == (PMS_HW_GG|PMS_HW_LCD))\r
+ if ((PicoIn.AHW & PAHW_GG) && (Pico.m.hardware & PMS_HW_LCD))\r
len = 160;\r
else if (!(PicoIn.AHW & PAHW_SMS) && (Pico.video.reg[12]&1))\r
len = 320;\r
do_region_override(filename);
}
- if (PicoCartInsert(rom_data, rom_size, carthw_cfg_fname)) {
- media_type = PM_ERROR;
- goto out;
- }
- rom_data = NULL; // now belongs to PicoCart
-
// simple test for GG. Do this here since m.hardware is nulled in Insert
if ((PicoIn.AHW & PAHW_SMS) && !PicoIn.hwSelect) {
const char *ext = NULL;
}
}
if (ext && !strcmp(ext,"gg") && !PicoIn.hwSelect) {
- Pico.m.hardware |= PMS_HW_GG;
+ PicoIn.AHW |= PAHW_GG;
lprintf("detected GG ROM\n");
} else if (ext && !strcmp(ext,"sg")) {
- Pico.m.hardware |= PMS_HW_SG;
+ PicoIn.AHW |= PAHW_SG;
lprintf("detected SG-1000 ROM\n");
} else if (ext && !strcmp(ext,"sc")) {
- Pico.m.hardware |= PMS_HW_SC;
+ PicoIn.AHW |= PAHW_SC;
lprintf("detected SC-3000 ROM\n");
} else
lprintf("detected SMS ROM\n");
}
+ if (PicoCartInsert(rom_data, rom_size, carthw_cfg_fname)) {
+ media_type = PM_ERROR;
+ goto out;
+ }
+ rom_data = NULL; // now belongs to PicoCart
+
// insert CD if it was detected
Pico.m.ncart_in = 0;
if (cd_img_type != CT_UNKNOWN) {
if (pv->reg[0] & 8)
xoff -= 8; // sprite shift
- if ((Pico.m.hardware & (PMS_HW_GG|PMS_HW_LCD)) == (PMS_HW_GG|PMS_HW_LCD))
+ if (Pico.m.hardware & PMS_HW_LCD)
xoff -= 48; // GG LCD, adjust to center 160 px
sat = (u8 *)PicoMem.vram + ((pv->reg[5] & 0x7e) << 7);
int addr = 0, pal = 0;
// Draw tiles across screen:
- for (; cells_dx > 0; cells_dx += 8, tilex_ty++, cells_dx -= 0x10000)
+ for (; cells_dx >= 0; cells_dx += 8, tilex_ty++, cells_dx -= 0x10000)
{
unsigned int pack;
unsigned code;
tilex = (32 - (dx >> 3) + cellskip) & 0x1f;
ty = (line & 7) << 1; // Y-Offset into tile
- cells = maxcells - cellskip;
+ cells = maxcells - cellskip - 1;
dx = (dx & 7);
dx += cellskip << 3;
// tiles
if (!(pv->debug_p & PVD_KILL_B)) {
- if ((Pico.m.hardware & (PMS_HW_GG|PMS_HW_LCD)) == (PMS_HW_GG|PMS_HW_LCD)) {
+ if (Pico.m.hardware & PMS_HW_LCD) {
// on GG render only the center 160 px, but mind hscroll
DrawStripM4(nametab , (dx-8) | ((cells-11)<< 16),(tilex+5) | (ty << 16));
} else if (pv->reg[0] & 0x80) {
if (!(pv->debug_p & PVD_KILL_S_LO))
DrawSpritesM4();
- if ((pv->reg[0] & 0x20) && (Pico.m.hardware & (PMS_HW_GG|PMS_HW_LCD)) != (PMS_HW_GG|PMS_HW_LCD)) {
+ if ((pv->reg[0] & 0x20) && !(Pico.m.hardware & PMS_HW_LCD)) {
// first column masked with background, caculate offset to start of line
dx = line_offset / 4;
ty = ((pv->reg[7]&0x0f)|0x10) * 0x01010101;
// Copy LCD enable flag for easier handling
Pico.m.hardware &= ~PMS_HW_LCD;
- if ((PicoIn.opt & POPT_EN_GG_LCD) && (Pico.m.hardware & PMS_HW_GG))
+ if ((PicoIn.opt & POPT_EN_GG_LCD) && (PicoIn.AHW & PAHW_GG))
Pico.m.hardware |= PMS_HW_LCD;
if (!(Pico.m.hardware & PMS_HW_LCD) && (mode & 4) && (Pico.video.reg[0] & 0x20)) {
columns = 248;
Pico.est.rendstatus |= PDRAW_SMS_BLANK_1;
}
- if ((Pico.m.hardware & (PMS_HW_GG|PMS_HW_LCD)) == (PMS_HW_GG|PMS_HW_LCD)) {
+ if (Pico.m.hardware & PMS_HW_LCD) {
// GG LCD always has 160x144 regardless of settings
screen_offset = 24; // nonetheless the vdp timing has 224 lines
loffs = 48;
unsigned bgcolor;
// GG LCD, render only visible part of screen
- if ((Pico.m.hardware & (PMS_HW_GG|PMS_HW_LCD)) == (PMS_HW_GG|PMS_HW_LCD) && (line < 24 || line >= 24+144))
+ if ((Pico.m.hardware & PMS_HW_LCD) && (line < 24 || line >= 24+144))
goto norender;
if (PicoScanBegin != NULL && skip == 0)
* hence GG/SMS/TMS can all be handled the same here */
for (j = cnt; j > 0; j--) {
if (!(Pico.video.reg[0] & 0x4)) // fixed palette in TMS modes
- spal = (u32 *)tmspal + (Pico.m.hardware & (PMS_HW_SG|PMS_HW_SC) ? 16/2:0);
+ spal = (u32 *)tmspal + (PicoIn.AHW & (PAHW_SG|PAHW_SC) ? 16/2:0);
for (i = 0x20/2; i > 0; i--, spal++, dpal++) {
t = *spal;
#if defined(USE_BGR555)
#define PAHW_SVP (1<<2)\r
#define PAHW_PICO (1<<3)\r
#define PAHW_SMS (1<<4)\r
+#define PAHW_GG (1<<5)\r
+#define PAHW_SG (1<<6)\r
+#define PAHW_SC (1<<7)\r
\r
#define PHWS_AUTO 0\r
#define PHWS_GG 1\r
unsigned int frame_count; // 1c for movies and idle det\r
};\r
\r
-#define PMS_HW_GG 0x1 // Game Gear\r
#define PMS_HW_LCD 0x2 // GG LCD\r
#define PMS_HW_JAP 0x4 // japanese system\r
-#define PMS_HW_SG 0x8 // SG-1000\r
-#define PMS_HW_SC 0x10 // SC-3000\r
\r
#define PMS_MAP_AUTO 0\r
#define PMS_MAP_SEGA 1\r
if (pv->type == 3) {
// cram. 32 on SMS, but 64 on MD. Fill 2nd half of cram for prio bit mirror
- if (Pico.m.hardware & PMS_HW_GG) { // GG, same layout as MD
+ if (PicoIn.AHW & PAHW_GG) { // GG, same layout as MD
unsigned a = pv->addr & 0x3f;
if (a & 0x1) { // write complete color on high byte write
u16 c = ((d&0x0f) << 8) | Pico.ms.vdp_buffer;
{
case 0x00:
case 0x01:
- if ((Pico.m.hardware & PMS_HW_GG) && a < 0x8) { // GG I/O area
+ if ((PicoIn.AHW & PAHW_GG) && a < 0x8) { // GG I/O area
switch (a) {
case 0: d = 0xff & ~(PicoIn.pad[0] & 0x80); break;
case 1: d = Pico.ms.io_gg[1] | (Pico.ms.io_gg[2] & 0x7f); break;
break;
case 0xc0: /* I/O port A and B */
- if (! (Pico.m.hardware & PMS_HW_SC) || (Pico.ms.io_sg & 7) == 7)
+ if (! (PicoIn.AHW & PAHW_SC) || (Pico.ms.io_sg & 7) == 7)
d = ~((PicoIn.pad[0] & 0x3f) | (PicoIn.pad[1] << 6));
else
; // read kbd 8 bits
break;
case 0xc1: /* I/O port B and miscellaneous */
- if (! (Pico.m.hardware & PMS_HW_SC) || (Pico.ms.io_sg & 7) == 7) {
+ if (! (PicoIn.AHW & PAHW_SC) || (Pico.ms.io_sg & 7) == 7) {
d = (Pico.ms.io_ctl & 0x80) | ((Pico.ms.io_ctl << 1) & 0x40) | 0x30;
d |= ~(PicoIn.pad[1] >> 2) & 0x0f;
if (Pico.ms.io_ctl & 0x08) d |= 0x80; // TH as input is unconnected
switch (a & 0xc1)
{
case 0x00:
- if ((Pico.m.hardware & PMS_HW_GG) && a < 0x8) // GG I/O area
+ if ((PicoIn.AHW & PAHW_GG) && a < 0x8) // GG I/O area
Pico.ms.io_gg[a] = d;
break;
case 0x01:
- if ((Pico.m.hardware & PMS_HW_GG) && a < 0x8) { // GG I/O area
+ if ((PicoIn.AHW & PAHW_GG) && a < 0x8) { // GG I/O area
Pico.ms.io_gg[a] = d;
} else {
// pad. latch hcounter if one of the TH lines is switched to 1
break;
case 0xc0:
- if ((Pico.m.hardware & PMS_HW_SC) && (a & 0x2))
+ if ((PicoIn.AHW & PAHW_SC) && (a & 0x2))
Pico.ms.io_sg = d; // 0xc2 = kbd/pad select
}
}
// Before adding more mappers this should be revised.
static void xwrite(unsigned int a, unsigned char d)
{
+ int sz = (PicoIn.AHW & (PAHW_SG|PAHW_SC) ? 2 : 8) * 1024;
+
elprintf(EL_IO, "z80 write [%04x] %02x", a, d);
if (a >= 0xc000)
- PicoMem.zram[a & 0x1fff] = d;
+ PicoMem.zram[a & (sz-1)] = d;
switch (Pico.ms.mapper) { // via config, or auto detected
case PMS_MAP_SEGA: write_bank_sega(a, d); break;
// disable autodetection after some time
if ((a >= 0xc000 && a < 0xfff8) || Pico.ms.mapcnt > 20) break;
// NB the sequence of mappers is crucial for the auto detection
- if (Pico.m.hardware & PMS_HW_SC) {
+ if (PicoIn.AHW & PAHW_SC) {
write_bank_x32k(a,d);
- } else if (Pico.m.hardware & PMS_HW_SG) {
+ } else if (PicoIn.AHW & PAHW_SG) {
write_bank_x8k(a, d);
} else {
write_bank_n32k(a, d);
// set preselected hw/mapper from config
if (PicoIn.hwSelect) {
- Pico.m.hardware &= ~(PMS_HW_GG|PMS_HW_SG|PMS_HW_SC);
+ PicoIn.AHW &= ~(PAHW_GG|PAHW_SG|PAHW_SC);
switch (PicoIn.hwSelect) {
- case PHWS_GG: Pico.m.hardware |= PMS_HW_GG; break;
- case PHWS_SG: Pico.m.hardware |= PMS_HW_SG; break;
- case PHWS_SC: Pico.m.hardware |= PMS_HW_SC; break;
+ case PHWS_GG: PicoIn.AHW |= PAHW_GG; break;
+ case PHWS_SG: PicoIn.AHW |= PAHW_SG; break;
+ case PHWS_SC: PicoIn.AHW |= PAHW_SC; break;
}
}
Pico.ms.mapcnt = Pico.ms.mapper = 0;
if (!memcmp(Pico.rom + tmr-16, "TMR SEGA", 8)) {
hw = Pico.rom[tmr-1] >> 4;
if (!PicoIn.hwSelect) {
- Pico.m.hardware &= ~(PMS_HW_GG|PMS_HW_SG|PMS_HW_SC);
+ PicoIn.AHW &= ~(PAHW_GG|PAHW_SG|PAHW_SC);
if (hw >= 0x5 && hw < 0x8)
- Pico.m.hardware |= PMS_HW_GG; // GG cartridge detected
+ PicoIn.AHW |= PAHW_GG; // GG cartridge detected
}
if (!PicoIn.regionOverride) {
Pico.m.hardware &= ~PMS_HW_JAP;
Pico.video.reg[10] = 0xff;
// BIOS, clear zram (unitialized on Mark-III, cf src/mame/drivers/sms.cpp)
- i = (Pico.m.hardware & (PMS_HW_JAP|PMS_HW_GG)) == PMS_HW_JAP ? 0xf0 : 0x00;
+ i = !(PicoIn.AHW & PAHW_GG) && (Pico.m.hardware & PMS_HW_JAP) ? 0xf0 : 0x00;
memset(PicoMem.zram, i, sizeof(PicoMem.zram));
}
memset(&PicoMem,0,sizeof(PicoMem));
memset(&Pico.video,0,sizeof(Pico.video));
memset(&Pico.m,0,sizeof(Pico.m));
- Pico.m.pal = 0;
// calculate a mask for bank writes.
// ROM loader has aligned the size for us, so this is safe.
void PicoMemSetupMS(void)
{
u8 mapper = Pico.ms.mapper;
+ int sz = (PicoIn.AHW & (PAHW_SG|PAHW_SC) ? 2 : 8) * 1024;
+ u32 a;
- z80_map_set(z80_read_map, 0x0000, 0xbfff, Pico.rom, 0);
-
- z80_map_set(z80_read_map, 0xc000, 0xdfff, PicoMem.zram, 0);
- z80_map_set(z80_read_map, 0xe000, 0xffff, PicoMem.zram, 0);
- z80_map_set(z80_write_map, 0xc000, 0xdfff, PicoMem.zram, 0);
- z80_map_set(z80_write_map, 0xe000, 0xffff, PicoMem.zram, 0);
+ // RAM and its mirrors
+ for (a = 0xc000; a < 0x10000; a += sz) {
+ z80_map_set(z80_read_map, a, a + sz-1, PicoMem.zram, 0);
+ z80_map_set(z80_write_map, a, a + sz-1, PicoMem.zram, 0);
+ }
+ a = 0x10000 - (1<<Z80_MEM_SHIFT);
+ z80_map_set(z80_write_map, a, 0xffff, xwrite, 1); // mapper detection
- z80_map_set(z80_write_map, 0x0000, 0xbfff, xwrite, 1);
- z80_map_set(z80_write_map, 0xfc00, 0xffff, xwrite, 1);
+ // ROM
+ z80_map_set(z80_read_map, 0x0000, 0xbfff, Pico.rom, 0);
+ z80_map_set(z80_write_map, 0x0000, 0xbfff, xwrite, 1); // mapper detection
// Nemesis mapper maps last 8KB rom bank #15 to adress 0
if (mapper == PMS_MAP_NEMESIS && Pico.romsize > 0x1e000)
// for SMS the pause button generates an NMI, for GG ths is not the case
nmi = (PicoIn.pad[0] >> 7) & 1;
- if (!(Pico.m.hardware & PMS_HW_GG) && !Pico.ms.nmi_state && nmi)
+ if (!(PicoIn.AHW & PAHW_GG) && !Pico.ms.nmi_state && nmi)
z80_nmi();
Pico.ms.nmi_state = nmi;
\r
if (PicoIn.AHW & PAHW_SMS) {\r
sys_name = "Master System";\r
- if (Pico.m.hardware & PMS_HW_GG)\r
+ if (PicoIn.AHW & PAHW_GG)\r
sys_name = "Game Gear";\r
- else if (Pico.m.hardware & PMS_HW_SG)\r
+ else if (PicoIn.AHW & PAHW_SG)\r
sys_name = "SG-1000";\r
- else if (Pico.m.hardware & PMS_HW_SC)\r
+ else if (PicoIn.AHW & PAHW_SC)\r
sys_name = "SC-3000";\r
else if (Pico.m.hardware & PMS_HW_JAP)\r
sys_name = "Mark III";\r
int i;
if (!(Pico.video.reg[0] & 0x4)) {
- int sg = !!(Pico.m.hardware & (PMS_HW_SG|PMS_HW_SC));
+ int sg = !!(PicoIn.AHW & (PAHW_SG|PAHW_SC));
for (i = Pico.est.SonicPalCount; i >= 0; i--)
do_pal_convert(localPal+i*0x40, tmspal+sg*0x10, currentConfig.gamma, currentConfig.gamma2);
} else {