From: kub Date: Sat, 18 Feb 2023 20:57:16 +0000 (+0000) Subject: core, preparations for sc-3000 support X-Git-Tag: v2.00~252 X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cab84f29e5ab9fff0e73f5548cba58daa9f0d767;p=picodrive.git core, preparations for sc-3000 support --- diff --git a/pico/media.c b/pico/media.c index d1bec342..7e1dd692 100644 --- a/pico/media.c +++ b/pico/media.c @@ -368,6 +368,9 @@ enum media_type_e PicoLoadMedia(const char *filename, } else if (ext && !strcmp(ext,"sg")) { Pico.m.hardware |= PMS_HW_SG; lprintf("detected SG-1000 ROM\n"); + } else if (ext && !strcmp(ext,"sc")) { + Pico.m.hardware |= PMS_HW_SC; + lprintf("detected SC-3000 ROM\n"); } else lprintf("detected SMS ROM\n"); } diff --git a/pico/mode4.c b/pico/mode4.c index 9cdf1c94..ff54c144 100644 --- a/pico/mode4.c +++ b/pico/mode4.c @@ -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 ? 16/2 : 0); + spal = (u32 *)tmspal + (Pico.m.hardware & (PMS_HW_SG|PMS_HW_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 6882faa5..db92f304 100644 --- a/pico/pico.h +++ b/pico/pico.h @@ -88,6 +88,7 @@ extern void *p32x_bios_g, *p32x_bios_m, *p32x_bios_s; #define PHWS_GG 1 #define PHWS_SMS 2 #define PHWS_SG 3 +#define PHWS_SC 4 #define PQUIRK_FORCE_6BTN (1<<0) #define PQUIRK_BLACKTHORNE_HACK (1<<1) diff --git a/pico/pico_int.h b/pico/pico_int.h index 55fb5ae6..11313766 100644 --- a/pico/pico_int.h +++ b/pico/pico_int.h @@ -346,6 +346,7 @@ struct PicoMisc #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 @@ -358,6 +359,7 @@ struct PicoMisc #define PMS_MAP_NEMESIS 8 #define PMS_MAP_8KBRAM 9 #define PMS_MAP_XOR 10 +#define PMS_MAP_32KBRAM 11 struct PicoMS { @@ -370,7 +372,8 @@ struct PicoMS unsigned char vdp_hlatch; unsigned char io_gg[0x08]; unsigned char mapcnt; - unsigned char pad[0x41]; + unsigned char io_sg; + unsigned char pad[0x40]; }; // emu state and data for the asm code diff --git a/pico/sms.c b/pico/sms.c index 91d61e5d..df99e926 100644 --- a/pico/sms.c +++ b/pico/sms.c @@ -189,14 +189,20 @@ static unsigned char z80_sms_in(unsigned short a) break; case 0xc0: /* I/O port A and B */ - d = ~((PicoIn.pad[0] & 0x3f) | (PicoIn.pad[1] << 6)); + if (! (Pico.m.hardware & PMS_HW_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 */ - 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 - if (Pico.ms.io_ctl & 0x02) d |= 0x40; + if (! (Pico.m.hardware & PMS_HW_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 + if (Pico.ms.io_ctl & 0x02) d |= 0x40; + } else + ; // read kbd 4 bits break; } } @@ -209,7 +215,7 @@ static void z80_sms_out(unsigned short a, unsigned char d) elprintf(EL_IO, "z80 port %04x write %02x", a, d); a &= 0xff; - if(a >= 0xf0){ + if (a >= 0xf0){ if (PicoIn.opt & POPT_EN_YM2413){ switch(a) { @@ -228,7 +234,7 @@ static void z80_sms_out(unsigned short a, unsigned char d) } } } - else{ + else { switch (a & 0xc1) { case 0x00: @@ -259,6 +265,10 @@ static void z80_sms_out(unsigned short a, unsigned char d) case 0x81: vdp_ctl_write(d); break; + + case 0xc0: + if ((Pico.m.hardware & PMS_HW_SC) && (a & 0x2)) + Pico.ms.io_sg = d; // 0xc2 = kbd/pad select } } } @@ -488,6 +498,25 @@ static void write_bank_x8k(unsigned short a, unsigned char d) z80_map_set(z80_write_map, a, a+0x1fff, PicoMem.vram+0x4000, 0); } +// SC-3000 32KB RAM mapper for BASIC level IIIB. 32KB RAM at address 0x8000 +static void write_bank_x32k(unsigned short a, unsigned char d) +{ + // 32KB address range @ 0x8000 + if ((a&0xc000) != 0x8000) return; + if (Pico.ms.mapper != PMS_MAP_32KBRAM && + (Pico.ms.mapper || Pico.romsize > 0x8000)) return; + + elprintf(EL_Z80BNK, "bank x32k %04x %02x @ %04x", a, d, z80_pc()); + ((unsigned char *)(PicoMem.vram+0x4000))[a&0x7fff] = d; + Pico.ms.mapper = PMS_MAP_32KBRAM; + + a &= 0xc000; + Pico.ms.carthw[0] = a >> 12; + // NB this deactivates internal RAM and all mapper detection + z80_map_set(z80_read_map, a, a+0x7fff, PicoMem.vram+0x4000, 0); + z80_map_set(z80_write_map, a, a+0x7fff, PicoMem.vram+0x4000, 0); +} + char *mappers[] = { [PMS_MAP_SEGA] = "Sega", [PMS_MAP_CODEM] = "Codemasters", @@ -499,6 +528,7 @@ char *mappers[] = { [PMS_MAP_NEMESIS] = "Korea Nemesis", [PMS_MAP_8KBRAM] = "Taiwan 8K RAM", [PMS_MAP_XOR] = "Korea XOR", + [PMS_MAP_32KBRAM] = "Sega 32K RAM", }; // TODO auto-selecting is not really reliable. @@ -519,15 +549,18 @@ static void xwrite(unsigned int a, unsigned char d) case PMS_MAP_JANGGUN: write_bank_jang(a, d); break; case PMS_MAP_NEMESIS: write_bank_msxn(a, d); break; case PMS_MAP_8KBRAM: write_bank_x8k(a, d); break; + case PMS_MAP_32KBRAM: write_bank_x32k(a, d); break; case PMS_MAP_XOR: write_bank_xor(a, d); break; case PMS_MAP_AUTO: // 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_SG) + if (Pico.m.hardware & PMS_HW_SC) { + write_bank_x32k(a,d); + } else if (Pico.m.hardware & PMS_HW_SG) { write_bank_x8k(a, d); - else { + } else { write_bank_n32k(a, d); write_bank_sega(a, d); write_bank_msx(a, d); @@ -562,10 +595,11 @@ void PicoResetMS(void) // set preselected hw/mapper from config if (PicoIn.hwSelect) { - Pico.m.hardware &= ~(PMS_HW_GG|PMS_HW_SG); + Pico.m.hardware &= ~(PMS_HW_GG|PMS_HW_SG|PMS_HW_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; } } Pico.ms.mapcnt = Pico.ms.mapper = 0; @@ -580,7 +614,7 @@ 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); + Pico.m.hardware &= ~(PMS_HW_GG|PMS_HW_SG|PMS_HW_SC); if (hw >= 0x5 && hw < 0x8) Pico.m.hardware |= PMS_HW_GG; // GG cartridge detected } @@ -654,12 +688,14 @@ void PicoMemSetupMS(void) u8 mapper = Pico.ms.mapper; 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); z80_map_set(z80_write_map, 0x0000, 0xbfff, xwrite, 1); - z80_map_set(z80_write_map, 0xc000, 0xdfff, PicoMem.zram, 0); - z80_map_set(z80_write_map, 0xe000, 0xffff, xwrite, 1); + z80_map_set(z80_write_map, 0xfc00, 0xffff, xwrite, 1); // Nemesis mapper maps last 8KB rom bank #15 to adress 0 if (mapper == PMS_MAP_NEMESIS && Pico.romsize > 0x1e000) @@ -712,7 +748,7 @@ void PicoMemSetupMS(void) void PicoStateLoadedMS(void) { u8 mapper = Pico.ms.mapper; - if (mapper == PMS_MAP_8KBRAM) { + if (mapper == PMS_MAP_8KBRAM || mapper == PMS_MAP_32KBRAM) { u16 a = Pico.ms.carthw[0] << 12; xwrite(a, *(unsigned char *)(PicoMem.vram+0x4000)); } else if (mapper == PMS_MAP_MSX || mapper == PMS_MAP_NEMESIS) { diff --git a/platform/common/emu.c b/platform/common/emu.c index f44aa5d3..a2dbf4ad 100644 --- a/platform/common/emu.c +++ b/platform/common/emu.c @@ -336,6 +336,8 @@ static void system_announce(void) sys_name = "Game Gear"; else if (Pico.m.hardware & PMS_HW_SG) sys_name = "SG-1000"; + else if (Pico.m.hardware & PMS_HW_SC) + sys_name = "SC-3000"; else if (Pico.m.hardware & PMS_HW_JAP) sys_name = "Mark III"; #ifdef NO_SMS diff --git a/platform/common/menu_pico.c b/platform/common/menu_pico.c index 0994b31e..f90fa276 100644 --- a/platform/common/menu_pico.c +++ b/platform/common/menu_pico.c @@ -572,7 +572,7 @@ static int menu_loop_32x_options(int id, int keys) #ifndef NO_SMS -static const char *sms_hardwares[] = { "auto", "Game Gear", "Master System", "SG-1000", NULL }; +static const char *sms_hardwares[] = { "auto", "Game Gear", "Master System", "SG-1000", "SC-3000", NULL }; static const char *gg_ghosting_opts[] = { "OFF", "weak", "normal", NULL }; static const char *sms_mappers[] = { "auto", "Sega", "Codemasters", "Korea", "Korea MSX", "Korea X-in-1", "Korea 4-Pak", "Korea Janggun", "Korea Nemesis", "Taiwan 8K RAM", "Korea XOR", NULL }; static const char h_smsfm[] = "FM sound is only supported by few games\nOther games may crash with FM enabled"; diff --git a/platform/libretro/libretro.c b/platform/libretro/libretro.c index a0d36d4e..2ebf31b7 100644 --- a/platform/libretro/libretro.c +++ b/platform/libretro/libretro.c @@ -1789,6 +1789,8 @@ static void update_variables(bool first_run) PicoIn.hwSelect = PHWS_GG; else if (strcmp(var.value, "SG-1000") == 0) PicoIn.hwSelect = PHWS_SG; + else if (strcmp(var.value, "SC-3000") == 0) + PicoIn.hwSelect = PHWS_SC; else PicoIn.hwSelect = PHWS_SMS; } diff --git a/platform/libretro/libretro_core_options.h b/platform/libretro/libretro_core_options.h index d3aab08a..4498b469 100644 --- a/platform/libretro/libretro_core_options.h +++ b/platform/libretro/libretro_core_options.h @@ -118,6 +118,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { { "Game Gear", NULL }, { "Master System", NULL }, { "SG-1000" , NULL }, + { "SC-3000" , NULL }, { NULL, NULL }, }, "Auto" diff --git a/platform/psp/emu.c b/platform/psp/emu.c index 3e9e66ef..24b39c6e 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); + int sg = !!(Pico.m.hardware & (PMS_HW_SG|PMS_HW_SC)); for (i = Pico.est.SonicPalCount; i >= 0; i--) do_pal_convert(localPal+i*0x40, tmspal+sg*0x10, currentConfig.gamma, currentConfig.gamma2); } else {