From 0aa63fce1212a63c39beeea0795699c4c3042ae6 Mon Sep 17 00:00:00 2001 From: kub Date: Wed, 22 Feb 2023 23:22:45 +0000 Subject: [PATCH] core, revisit Sega 8 bit hardware handling --- pico/cart.c | 8 +++--- pico/draw.c | 4 +-- pico/media.c | 18 ++++++------- pico/mode4.c | 18 ++++++------- pico/pico.h | 3 +++ pico/pico_int.h | 3 --- pico/sms.c | 59 +++++++++++++++++++++++-------------------- platform/common/emu.c | 6 ++--- platform/psp/emu.c | 2 +- 9 files changed, 63 insertions(+), 58 deletions(-) diff --git a/pico/cart.c b/pico/cart.c index dad850b5..86cab1d7 100644 --- a/pico/cart.c +++ b/pico/cart.c @@ -847,7 +847,7 @@ int PicoCartInsert(unsigned char *rom, unsigned int romsize, const char *carthw_ } pdb_cleanup(); - PicoIn.AHW &= PAHW_MCD|PAHW_SMS|PAHW_PICO; + PicoIn.AHW &= ~(PAHW_32X|PAHW_SVP); PicoCartMemSetup = NULL; PicoDmaHook = NULL; @@ -866,7 +866,7 @@ int PicoCartInsert(unsigned char *rom, unsigned int romsize, const char *carthw_ PicoInitPico(); // setup correct memory map for loaded ROM - switch (PicoIn.AHW) { + switch (PicoIn.AHW & ~(PAHW_GG|PAHW_SG|PAHW_SC)) { default: elprintf(EL_STATUS|EL_ANOMALY, "starting in unknown hw configuration: %x", PicoIn.AHW); case 0: @@ -1353,7 +1353,7 @@ static void PicoCartDetect(const char *carthw_cfg) for (i = 0; i < Pico.romsize; i += 4) { unsigned v = CPU_BE2(*(u32 *) (Pico.rom + i)); if (a && v == a + 0x400) { // patch if 2 pointers with offset 0x400 are found - printf("auto-patching @%06x: %08x->%08x\n", i, v, v - 0x100); + elprintf(EL_STATUS, "auto-patching @%06x: %08x->%08x\n", i, v, v - 0x100); *(u32 *) (Pico.rom + i) = CPU_BE2(v - 0x100); } // detect a pointer into the incriminating area @@ -1374,7 +1374,7 @@ static void PicoCartDetect(const char *carthw_cfg) for (i = 0; i < Pico.romsize; i += 4) { unsigned v = CPU_BE2(*(u32 *) (Pico.rom + i)); if (a == 0xffffff8c && v == 0x5ee1) { // patch if 4-long xfer written to CHCR - printf("auto-patching @%06x: %08x->%08x\n", i, v, v & ~0x800); + elprintf(EL_STATUS, "auto-patching @%06x: %08x->%08x\n", i, v, v & ~0x800); *(u32 *) (Pico.rom + i) = CPU_BE2(v & ~0x800); // change to half-sized xfer } a = v; diff --git a/pico/draw.c b/pico/draw.c index 38820e8f..c1e8c4d3 100644 --- a/pico/draw.c +++ b/pico/draw.c @@ -1647,7 +1647,7 @@ void FinalizeLine555(int sh, int line, struct PicoEState *est) PicoDrawUpdateHighPal(); len = 256; - if ((PicoIn.AHW & PAHW_SMS) && (Pico.m.hardware & (PMS_HW_GG|PMS_HW_LCD)) == (PMS_HW_GG|PMS_HW_LCD)) + if ((PicoIn.AHW & PAHW_GG) && (Pico.m.hardware & PMS_HW_LCD)) len = 160; else if (!(PicoIn.AHW & PAHW_SMS) && (Pico.video.reg[12]&1)) len = 320; @@ -1711,7 +1711,7 @@ void FinalizeLine8bit(int sh, int line, struct PicoEState *est) } len = 256; - if ((PicoIn.AHW & PAHW_SMS) && (Pico.m.hardware & (PMS_HW_GG|PMS_HW_LCD)) == (PMS_HW_GG|PMS_HW_LCD)) + if ((PicoIn.AHW & PAHW_GG) && (Pico.m.hardware & PMS_HW_LCD)) len = 160; else if (!(PicoIn.AHW & PAHW_SMS) && (Pico.video.reg[12]&1)) len = 320; diff --git a/pico/media.c b/pico/media.c index 7e1dd692..ce0c24e8 100644 --- a/pico/media.c +++ b/pico/media.c @@ -345,12 +345,6 @@ enum media_type_e PicoLoadMedia(const char *filename, 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; @@ -363,18 +357,24 @@ enum media_type_e PicoLoadMedia(const char *filename, } } 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) { diff --git a/pico/mode4.c b/pico/mode4.c index ff54c144..9c1cff96 100644 --- a/pico/mode4.c +++ b/pico/mode4.c @@ -162,7 +162,7 @@ static void ParseSpritesM4(int scanline) 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); @@ -237,7 +237,7 @@ static void DrawStripM4(const u16 *nametab, int cells_dx, int tilex_ty) 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; @@ -294,7 +294,7 @@ static void DrawDisplayM4(int scanline) 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; @@ -302,7 +302,7 @@ static void DrawDisplayM4(int scanline) // 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) { @@ -318,7 +318,7 @@ static void DrawDisplayM4(int scanline) 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; @@ -742,7 +742,7 @@ void PicoFrameStartSMS(void) // 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)) { @@ -750,7 +750,7 @@ void PicoFrameStartSMS(void) 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; @@ -811,7 +811,7 @@ void PicoLineSMS(int line) 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) @@ -878,7 +878,7 @@ void PicoDoHighPal555SMS(void) * 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) diff --git a/pico/pico.h b/pico/pico.h index db92f304..a15a01a0 100644 --- a/pico/pico.h +++ b/pico/pico.h @@ -83,6 +83,9 @@ extern void *p32x_bios_g, *p32x_bios_m, *p32x_bios_s; #define PAHW_SVP (1<<2) #define PAHW_PICO (1<<3) #define PAHW_SMS (1<<4) +#define PAHW_GG (1<<5) +#define PAHW_SG (1<<6) +#define PAHW_SC (1<<7) #define PHWS_AUTO 0 #define PHWS_GG 1 diff --git a/pico/pico_int.h b/pico/pico_int.h index 11313766..1bb7b258 100644 --- a/pico/pico_int.h +++ b/pico/pico_int.h @@ -342,11 +342,8 @@ struct PicoMisc unsigned int frame_count; // 1c for movies and idle det }; -#define PMS_HW_GG 0x1 // Game Gear #define PMS_HW_LCD 0x2 // GG LCD #define PMS_HW_JAP 0x4 // japanese system -#define PMS_HW_SG 0x8 // SG-1000 -#define PMS_HW_SC 0x10 // SC-3000 #define PMS_MAP_AUTO 0 #define PMS_MAP_SEGA 1 diff --git a/pico/sms.c b/pico/sms.c index df99e926..f102cf44 100644 --- a/pico/sms.c +++ b/pico/sms.c @@ -57,7 +57,7 @@ static void vdp_data_write(unsigned char d) 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; @@ -160,7 +160,7 @@ static unsigned char z80_sms_in(unsigned short a) { 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; @@ -189,14 +189,14 @@ static unsigned char z80_sms_in(unsigned short a) 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 @@ -238,11 +238,11 @@ static void z80_sms_out(unsigned short a, unsigned char d) 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 @@ -267,7 +267,7 @@ static void z80_sms_out(unsigned short a, unsigned char d) 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 } } @@ -535,9 +535,11 @@ char *mappers[] = { // 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; @@ -556,9 +558,9 @@ static void xwrite(unsigned int a, unsigned char d) // 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); @@ -595,11 +597,11 @@ void PicoResetMS(void) // 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; @@ -614,9 +616,9 @@ void PicoResetMS(void) 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; @@ -655,7 +657,7 @@ void PicoResetMS(void) 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)); } @@ -666,7 +668,6 @@ void PicoPowerMS(void) 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. @@ -686,16 +687,20 @@ void PicoPowerMS(void) 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< 0x1e000) @@ -800,7 +805,7 @@ void PicoFrameMS(void) // 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; diff --git a/platform/common/emu.c b/platform/common/emu.c index a2dbf4ad..e0803cee 100644 --- a/platform/common/emu.c +++ b/platform/common/emu.c @@ -332,11 +332,11 @@ static void system_announce(void) if (PicoIn.AHW & PAHW_SMS) { sys_name = "Master System"; - if (Pico.m.hardware & PMS_HW_GG) + if (PicoIn.AHW & PAHW_GG) sys_name = "Game Gear"; - else if (Pico.m.hardware & PMS_HW_SG) + else if (PicoIn.AHW & PAHW_SG) sys_name = "SG-1000"; - else if (Pico.m.hardware & PMS_HW_SC) + else if (PicoIn.AHW & PAHW_SC) sys_name = "SC-3000"; else if (Pico.m.hardware & PMS_HW_JAP) sys_name = "Mark III"; diff --git a/platform/psp/emu.c b/platform/psp/emu.c index 24b39c6e..18eb388b 100644 --- a/platform/psp/emu.c +++ b/platform/psp/emu.c @@ -217,7 +217,7 @@ static void do_pal_update_sms(void) 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 { -- 2.39.2