sms, autodetection for sg-1000 ram extension

This commit is contained in:
kub 2022-02-27 09:40:04 +00:00
parent 171fb8cc14
commit 3611781e65
4 changed files with 40 additions and 26 deletions

View file

@ -831,14 +831,16 @@ norender:
/* Palette for TMS9918 mode, see https://www.smspower.org/Development/Palette */ /* Palette for TMS9918 mode, see https://www.smspower.org/Development/Palette */
// RGB values: #000000 #000000 #21c842 #5edc78 #5455ed #7d76fc #d4524d #42ebf5 // RGB values: #000000 #000000 #21c842 #5edc78 #5455ed #7d76fc #d4524d #42ebf5
// #fc5554 #ff7978 #d4c154 #e6ce80 #21b03b #c95b5a #cccccc #ffffff // #fc5554 #ff7978 #d4c154 #e6ce80 #21b03b #c95bba #cccccc #ffffff
// 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff
// 0007 0818 1929 2a3a 3b4b 4c5c 5d6d 6e7e 7f8f 90a0 a1b1 b2c2 c3d3 d4e4 e5f5 f6
static u16 tmspal[32] = { static u16 tmspal[32] = {
// SMS palette // SMS palette
// 0x0000, 0x0000, 0x00a0, 0x00f0, 0x0a00, 0x0f00, 0x0005, 0x0ff0, // 0x0000, 0x0000, 0x00a0, 0x00f0, 0x0a00, 0x0f00, 0x0005, 0x0ff0,
// 0x000a, 0x000f, 0x0055, 0x00ff, 0x0050, 0x0f0f, 0x0555, 0x0fff, // 0x000a, 0x000f, 0x0055, 0x00ff, 0x0050, 0x0f0f, 0x0555, 0x0fff,
// GG palette // GG palette
0x0000, 0x0000, 0x04c2, 0x07d5, 0x0e55, 0x0f77, 0x045d, 0x0fe4, 0x0000, 0x0000, 0x04c2, 0x07d6, 0x0e55, 0x0f77, 0x055d, 0x0ee4,
0x055f, 0x077f, 0x05cd, 0x08ce, 0x03b2, 0x0b5c, 0x0ccc, 0x0fff, 0x055f, 0x077f, 0x05bd, 0x08ce, 0x04a2, 0x0b5c, 0x0ccc, 0x0fff,
}; };
void PicoDoHighPal555SMS(void) void PicoDoHighPal555SMS(void)

View file

@ -77,15 +77,16 @@ extern void *p32x_bios_g, *p32x_bios_m, *p32x_bios_s;
#define POPT_DIS_FM_SSGEG (1<<23) #define POPT_DIS_FM_SSGEG (1<<23)
#define POPT_EN_FM_DAC (1<<24) //x00 0000 #define POPT_EN_FM_DAC (1<<24) //x00 0000
#define PAHW_MCD (1<<0) #define PAHW_MCD (1<<0)
#define PAHW_32X (1<<1) #define PAHW_32X (1<<1)
#define PAHW_SVP (1<<2) #define PAHW_SVP (1<<2)
#define PAHW_PICO (1<<3) #define PAHW_PICO (1<<3)
#define PAHW_SMS (1<<4) #define PAHW_SMS (1<<4)
#define PHWS_AUTO 0 #define PHWS_AUTO 0
#define PHWS_GG 1 #define PHWS_GG 1
#define PHWS_SMS 2 #define PHWS_SMS 2
#define PHWS_SG1000 3
#define PQUIRK_FORCE_6BTN (1<<0) #define PQUIRK_FORCE_6BTN (1<<0)

View file

@ -342,6 +342,11 @@ struct PicoMisc
unsigned int frame_count; // 1c for movies and idle det 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_MAP_AUTO 0 #define PMS_MAP_AUTO 0
#define PMS_MAP_SEGA 1 #define PMS_MAP_SEGA 1
#define PMS_MAP_CODEM 2 #define PMS_MAP_CODEM 2

View file

@ -57,7 +57,7 @@ static void vdp_data_write(unsigned char d)
if (pv->type == 3) { if (pv->type == 3) {
// cram. 32 on SMS, but 64 on MD. Fill 2nd half of cram for prio bit mirror // cram. 32 on SMS, but 64 on MD. Fill 2nd half of cram for prio bit mirror
if (Pico.m.hardware & 0x1) { // GG, same layout as MD if (Pico.m.hardware & PMS_HW_GG) { // GG, same layout as MD
unsigned a = pv->addr & 0x3f; unsigned a = pv->addr & 0x3f;
if (a & 0x1) { // write complete color on high byte write if (a & 0x1) { // write complete color on high byte write
u16 c = ((d&0x0f) << 8) | Pico.ms.vdp_buffer; 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 0x00:
case 0x01: case 0x01:
if ((Pico.m.hardware & 0x1) && a < 0x8) { // GG I/O area if ((Pico.m.hardware & PMS_HW_GG) && a < 0x8) { // GG I/O area
switch (a) { switch (a) {
case 0: d = 0xff & ~(PicoIn.pad[0] & 0x80); break; case 0: d = 0xff & ~(PicoIn.pad[0] & 0x80); break;
case 1: d = Pico.ms.io_gg[1] | (Pico.ms.io_gg[2] & 0x7f); break; case 1: d = Pico.ms.io_gg[1] | (Pico.ms.io_gg[2] & 0x7f); break;
@ -232,11 +232,11 @@ static void z80_sms_out(unsigned short a, unsigned char d)
switch (a & 0xc1) switch (a & 0xc1)
{ {
case 0x00: case 0x00:
if ((Pico.m.hardware & 0x1) && a < 0x8) // GG I/O area if ((Pico.m.hardware & PMS_HW_GG) && a < 0x8) // GG I/O area
Pico.ms.io_gg[a] = d; Pico.ms.io_gg[a] = d;
break; break;
case 0x01: case 0x01:
if ((Pico.m.hardware & 0x1) && a < 0x8) { // GG I/O area if ((Pico.m.hardware & PMS_HW_GG) && a < 0x8) { // GG I/O area
Pico.ms.io_gg[a] = d; Pico.ms.io_gg[a] = d;
} else { } else {
// pad. latch hcounter if one of the TH lines is switched to 1 // pad. latch hcounter if one of the TH lines is switched to 1
@ -454,13 +454,15 @@ static void write_bank_jang(unsigned short a, unsigned char d)
} }
} }
// SG-1000 8KB RAM Adaptor mapper. 8KB RAM at address 0x2000
static void write_bank_x8k(unsigned short a, unsigned char d) static void write_bank_x8k(unsigned short a, unsigned char d)
{ {
// 8KB address range @ 0x2000 // 8KB address range @ 0x2000
if ((a&0xe000) != 0x2000) return; if ((a&0xe000) != 0x2000) return;
// never autodetected, selectable only via config // this is only available on SG-1000
if (Pico.ms.mapper != PMS_MAP_8KBRAM) return; if (Pico.ms.mapper != PMS_MAP_8KBRAM && (Pico.ms.mapper || !(Pico.m.hardware & PMS_HW_SG))) return;
elprintf(EL_Z80BNK, "bank x8k %04x %02x @ %04x", a, d, z80_pc()); elprintf(EL_Z80BNK, "bank x8k %04x %02x @ %04x", a, d, z80_pc());
Pico.ms.mapper = PMS_MAP_8KBRAM;
((unsigned char *)PicoMem.vram)[a+0x6000] = d; ((unsigned char *)PicoMem.vram)[a+0x6000] = d;
z80_map_set(z80_read_map, 0x2000, 0x3fff, PicoMem.vram+0x4000, 0); z80_map_set(z80_read_map, 0x2000, 0x3fff, PicoMem.vram+0x4000, 0);
@ -488,6 +490,7 @@ static void xwrite(unsigned int a, unsigned char d)
case PMS_MAP_AUTO: case PMS_MAP_AUTO:
// NB the sequence of mappers is crucial for the auto detection // NB the sequence of mappers is crucial for the auto detection
write_bank_x8k(a, d);
write_bank_n32k(a, d); write_bank_n32k(a, d);
write_bank_sega(a, d); write_bank_sega(a, d);
write_bank_msx(a, d); write_bank_msx(a, d);
@ -517,27 +520,29 @@ void PicoResetMS(void)
// set preselected hw/mapper from config // set preselected hw/mapper from config
if (PicoIn.hwSelect) { if (PicoIn.hwSelect) {
switch (PicoIn.hwSelect) { switch (PicoIn.hwSelect) {
case PHWS_GG: Pico.m.hardware |= 0x1; break; case PHWS_GG: Pico.m.hardware |= PMS_HW_GG; break;
default: Pico.m.hardware &= ~0x1; break; default: Pico.m.hardware &= ~PMS_HW_GG; break;
} }
} }
if (PicoIn.mapper) if (PicoIn.mapper)
Pico.ms.mapper = PicoIn.mapper; Pico.ms.mapper = PicoIn.mapper;
Pico.m.hardware |= 0x4; // default region Japan if no TMR header Pico.m.hardware |= PMS_HW_JAP; // default region Japan if no TMR header
Pico.m.hardware |= PMS_HW_SG; // default to SG-1000 if no TMR header
// check if the ROM header contains more system information // check if the ROM header contains more system information
for (tmr = 0x2000; tmr < 0xbfff && tmr <= Pico.romsize; tmr *= 2) { for (tmr = 0x2000; tmr < 0xbfff && tmr <= Pico.romsize; tmr *= 2) {
if (!memcmp(Pico.rom + tmr-16, "TMR SEGA", 8)) { if (!memcmp(Pico.rom + tmr-16, "TMR SEGA", 8)) {
Pico.m.hardware &= ~PMS_HW_SG; // not SG-1000
hw = Pico.rom[tmr-1] >> 4; hw = Pico.rom[tmr-1] >> 4;
if (!PicoIn.hwSelect) { if (!PicoIn.hwSelect) {
Pico.m.hardware &= ~0x1; Pico.m.hardware &= ~PMS_HW_GG;
if (hw >= 0x5 && hw < 0x8) if (hw >= 0x5 && hw < 0x8)
Pico.m.hardware |= 0x1; // GG cartridge detected Pico.m.hardware |= PMS_HW_GG; // GG cartridge detected
} }
if (!PicoIn.regionOverride) { if (!PicoIn.regionOverride) {
Pico.m.hardware &= ~0x4; Pico.m.hardware &= ~PMS_HW_JAP;
if (hw == 0x5 || hw == 0x3) if (hw == 0x5 || hw == 0x3)
Pico.m.hardware |= 0x4; // region Japan Pico.m.hardware |= PMS_HW_JAP; // region Japan
} }
id = CPU_LE4(*(u32 *)&Pico.rom[tmr-4]) & 0xf0f0ffff; id = CPU_LE4(*(u32 *)&Pico.rom[tmr-4]) & 0xf0f0ffff;
for (i = 0; i < sizeof(region_pal)/sizeof(*region_pal); i++) for (i = 0; i < sizeof(region_pal)/sizeof(*region_pal); i++)
@ -571,7 +576,8 @@ void PicoResetMS(void)
Pico.video.reg[10] = 0xff; Pico.video.reg[10] = 0xff;
// BIOS, clear zram (unitialized on Mark-III, cf src/mame/drivers/sms.cpp) // BIOS, clear zram (unitialized on Mark-III, cf src/mame/drivers/sms.cpp)
memset(PicoMem.zram, (Pico.m.hardware&5) == 4 ? 0xf0:0, sizeof(PicoMem.zram)); i = (Pico.m.hardware & (PMS_HW_JAP|PMS_HW_GG)) == PMS_HW_JAP ? 0xf0 : 0x00;
memset(PicoMem.zram, i, sizeof(PicoMem.zram));
} }
void PicoPowerMS(void) void PicoPowerMS(void)
@ -698,7 +704,7 @@ void PicoFrameMS(void)
// for SMS the pause button generates an NMI, for GG ths is not the case // for SMS the pause button generates an NMI, for GG ths is not the case
nmi = (PicoIn.pad[0] >> 7) & 1; nmi = (PicoIn.pad[0] >> 7) & 1;
if (!(Pico.m.hardware & 0x1) && !Pico.ms.nmi_state && nmi) if (!(Pico.m.hardware & PMS_HW_GG) && !Pico.ms.nmi_state && nmi)
z80_nmi(); z80_nmi();
Pico.ms.nmi_state = nmi; Pico.ms.nmi_state = nmi;