[Core/MS] improved emulation of Japanese Master System I/O chip (315-5297)

This commit is contained in:
EkeEke 2014-11-23 20:30:27 +01:00
parent 4946d73a47
commit d08b903a11
5 changed files with 59 additions and 53 deletions

View File

@ -412,12 +412,10 @@ unsigned int io_68k_read(unsigned int offset)
void io_z80_write(unsigned int offset, unsigned int data, unsigned int cycles)
{
/* I/O Control register */
if (offset)
{
/* I/O Control register */
if (region_code & REGION_USA)
{
/*
/*
Bit Function
--------------
D7 : Port B TH pin output level (1=high, 0=low)
@ -428,36 +426,33 @@ void io_z80_write(unsigned int offset, unsigned int data, unsigned int cycles)
D2 : Port B TR pin direction (1=input, 0=output)
D1 : Port A TH pin direction (1=input, 0=output)
D0 : Port A TR pin direction (1=input, 0=output)
*/
*/
/* Send TR/TH state to connected peripherals */
port[0].data_w((data << 1) & 0x60, (~io_reg[0x0F] << 5) & 0x60);
port[1].data_w((data >> 1) & 0x60, (~io_reg[0x0F] << 3) & 0x60);
/* Send TR/TH state to connected peripherals */
port[0].data_w((data << 1) & 0x60, (~data << 5) & 0x60);
port[1].data_w((data >> 1) & 0x60, (~data << 3) & 0x60);
/* Check for TH low-to-high transitions on both ports */
if ((!(io_reg[0x0F] & 0x80) && (data & 0x80)) ||
(!(io_reg[0x0F] & 0x20) && (data & 0x20)))
{
/* Latch new HVC */
hvc_latch = hctab[cycles % MCYCLES_PER_LINE] | 0x10000;
}
/* Update I/O Control register */
io_reg[0x0F] = data;
}
else
/* Japanese model specific */
if (region_code == REGION_JAPAN_NTSC)
{
/* TH output is fixed to 0 & TR is always an input on japanese hardware */
io_reg[0x0F] = (data | 0x05) & 0x5F;
/* Port $DD bits D4-D5 return D0-D2 (cf. http://www2.odn.ne.jp/~haf09260/Sms/EnrSms.htm) */
io_reg[0x0D] = ((data & 0x01) << 4) | ((data & 0x04) << 3);
/* Reading TH & TR pins always return 0 when set as output */
data &= 0x0F;
}
/* Check for TH low-to-high transitions on both ports */
if ((!(io_reg[0x0F] & 0x80) && (data & 0x80)) ||
(!(io_reg[0x0F] & 0x20) && (data & 0x20)))
{
/* Latch new HVC */
hvc_latch = hctab[cycles % MCYCLES_PER_LINE] | 0x10000;
}
/* Update I/O Control register */
io_reg[0x0F] = data;
}
else
{
/* Update Memory Control register */
/* Memory Control register */
io_reg[0x0E] = data;
/* Switch cartridge & BIOS ROM */

View File

@ -251,9 +251,10 @@ void z80_md_port_w(unsigned int port, unsigned char data)
{
port &= 0xFF;
/* write FM chip if enabled */
if ((port >= 0xF0) && (config.ym2413 & 1))
{
fm_write(Z80.cycles, port&3, data);
fm_write(Z80.cycles, port, data);
return;
}
@ -299,7 +300,7 @@ unsigned char z80_md_port_r(unsigned int port)
/* read FM chip if enabled */
if ((port >= 0xF0) && (config.ym2413 & 1))
{
return YM2413Read(port & 3);
return YM2413Read();
}
return z80_unused_port_r(port);
@ -329,7 +330,7 @@ void z80_gg_port_w(unsigned int port, unsigned char data)
return;
}
z80_unused_port_w(port & 0xFF, data);
z80_unused_port_w(port, data);
return;
}
@ -431,13 +432,13 @@ void z80_ms_port_w(unsigned int port, unsigned char data)
case 0x01:
{
/* full address range is decoded by 315-5297 I/O chip (fixes Super Tetris / Power Boggle Boggle) */
if ((region_code == REGION_JAPAN_NTSC) && ((port & 0xFE) != 0x3E))
if ((region_code != REGION_JAPAN_NTSC) || ((port & 0xFE) == 0x3E))
{
z80_unused_port_w(port & 0xFF, data);
io_z80_write(port & 1, data, Z80.cycles + SMS_CYCLE_OFFSET);
return;
}
io_z80_write(port & 1, data, Z80.cycles + SMS_CYCLE_OFFSET);
z80_unused_port_w(port & 0xFF, data);
return;
}
@ -462,9 +463,17 @@ void z80_ms_port_w(unsigned int port, unsigned char data)
default:
{
/* write FM chip if enabled */
if (!(port & 4) && (config.ym2413 & 1))
{
fm_write(Z80.cycles, port & 3, data);
fm_write(Z80.cycles, port, data);
/* 315-5297 I/O chip decodes bit 1 to enable/disable PSG output */
if (region_code == REGION_JAPAN_NTSC)
{
io_reg[6] = (data & 2) ? 0xFF : 0x00;
SN76489_Config(Z80.cycles, config.psg_preamp, config.psgBoostNoise, io_reg[6]);
}
return;
}
@ -506,27 +515,27 @@ unsigned char z80_ms_port_r(unsigned int port)
default:
{
uint8 data = 0xFF;
/* read FM chip if enabled */
if (!(port & 4) && (config.ym2413 & 1))
{
/* check if I/O ports are disabled */
if (io_reg[0x0E] & 0x04)
data = YM2413Read();
/* 315-5297 I/O chip decodes full address range */
if (region_code == REGION_JAPAN_NTSC)
{
return YM2413Read(port & 3);
}
else
{
return YM2413Read(port & 3) & io_z80_read(port & 1);
return data;
}
}
/* check if I/O ports are enabled */
/* read I/O ports if enabled */
if (!(io_reg[0x0E] & 0x04))
{
return io_z80_read(port & 1);
data &= io_z80_read(port & 1);
}
return z80_unused_port_r(port & 0xFF);
return data;
}
}
}
@ -543,7 +552,7 @@ void z80_m3_port_w(unsigned int port, unsigned char data)
case 0x00:
case 0x01:
{
z80_unused_port_w(port, data);
z80_unused_port_w(port & 0xFF, data);
return;
}
@ -568,9 +577,10 @@ void z80_m3_port_w(unsigned int port, unsigned char data)
default:
{
/* write FM chip if enabled */
if (!(port & 4) && (config.ym2413 & 1))
{
fm_write(Z80.cycles, port & 3, data);
fm_write(Z80.cycles, port, data);
return;
}
@ -615,8 +625,8 @@ unsigned char z80_m3_port_r(unsigned int port)
/* read FM chip if enabled */
if (!(port & 4) && (config.ym2413 & 1))
{
/* I/O ports are automatically disabled */
return YM2413Read(port & 3);
/* I/O ports are automatically disabled by hardware */
return YM2413Read();
}
/* read I/O ports */
@ -683,7 +693,7 @@ unsigned char z80_sg_port_r(unsigned int port)
default:
{
return z80_unused_port_r(port);
return z80_unused_port_r(port & 0xFF);
}
}
}

View File

@ -111,6 +111,7 @@ void sound_reset(void)
/* reset sound chips */
YM_Reset();
SN76489_Reset();
SN76489_Config(0, config.psg_preamp, config.psgBoostNoise, 0xff);
/* reset FM buffer ouput */
fm_last[0] = fm_last[1] = 0;

View File

@ -1658,14 +1658,14 @@ void YM2413Write(unsigned int a, unsigned int v)
}
else
{
/* latched bit (Master System specific) */
/* bit 0 enable/disable FM output (Master System / Mark-III FM adapter specific) */
ym2413.status = v & 0x01;
}
}
unsigned int YM2413Read(unsigned int a)
unsigned int YM2413Read(void)
{
/* D0=latched bit, D1-D2 need to be zero (Master System specific) */
/* bit 0 returns latched FM enable status, bits 1-2 return zero (Master System / Mark-III FM adapter specific) */
return 0xF8 | ym2413.status;
}

View File

@ -16,7 +16,7 @@ extern void YM2413Init(void);
extern void YM2413ResetChip(void);
extern void YM2413Update(int *buffer, int length);
extern void YM2413Write(unsigned int a, unsigned int v);
extern unsigned int YM2413Read(unsigned int a);
extern unsigned int YM2413Read(void);
extern unsigned char *YM2413GetContextPtr(void);
extern unsigned int YM2413GetContextSize(void);