mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-11-10 21:05:12 +01:00
[Core/MS] improved emulation of Japanese Master System I/O chip (315-5297)
This commit is contained in:
parent
4946d73a47
commit
d08b903a11
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user