mirror of
https://github.com/holub/mame
synced 2025-05-20 20:58:51 +03:00
further snes.c wip: [Fabio Priuli]
- Fixed a bug in SPC7110 handlers (now Tengai Makyou Zero test reaches RTC tests and fails them, instead of getting stuck at MUL/DIV tests) - Implemented very preliminary (and currently broken) SPC7110 RTC emulation - Updated DSP2 handlers to better reflect Overload's docs (problem and fix actually found by byuu) - Updated add-on chips handlers to reflect byuu's findings
This commit is contained in:
parent
7ec65cbc92
commit
957387880a
@ -623,7 +623,7 @@ READ8_HANDLER( snes_r_io )
|
||||
else if (snes_has_addon_chip == HAS_SPC7110 || snes_has_addon_chip == HAS_SPC7110_RTC)
|
||||
{
|
||||
UINT16 limit = (snes_has_addon_chip == HAS_SPC7110_RTC) ? 0x4842 : 0x483f;
|
||||
if (offset >= 0x4800 && offset < limit)
|
||||
if (offset >= 0x4800 && offset <= limit)
|
||||
{
|
||||
return spc7110_mmio_read(space->machine, offset);
|
||||
}
|
||||
@ -934,7 +934,7 @@ WRITE8_HANDLER( snes_w_io )
|
||||
else if (snes_has_addon_chip == HAS_SPC7110 || snes_has_addon_chip == HAS_SPC7110_RTC)
|
||||
{
|
||||
UINT16 limit = (snes_has_addon_chip == HAS_SPC7110_RTC) ? 0x4842 : 0x483f;
|
||||
if (offset >= 0x4800 && offset < limit)
|
||||
if (offset >= 0x4800 && offset <= limit)
|
||||
{
|
||||
spc7110_mmio_write(space->machine, (UINT32)offset, data);
|
||||
return;
|
||||
@ -1603,7 +1603,7 @@ address | | | | | | |
|
||||
/* 0x000000 - 0x2fffff */
|
||||
READ8_HANDLER( snes_r_bank1 )
|
||||
{
|
||||
UINT8 value;
|
||||
UINT8 value = 0xff;
|
||||
UINT16 address = offset & 0xffff;
|
||||
|
||||
if (address < 0x2000) /* Mirror of Low RAM */
|
||||
@ -1613,27 +1613,28 @@ READ8_HANDLER( snes_r_bank1 )
|
||||
else if (address < 0x8000)
|
||||
{
|
||||
if (snes_has_addon_chip == HAS_SUPERFX)
|
||||
value = snes_ram[0xf00000 + (address & 0x1fff)]; // here it should 0xe00000 but there are mirroring issues
|
||||
value = snes_ram[0xf00000 + (address & 0x1fff)]; // here it should be 0xe00000 but there are mirroring issues
|
||||
else if (snes_has_addon_chip == HAS_OBC1)
|
||||
value = obc1_read(space, offset);
|
||||
else if ((snes_has_addon_chip == HAS_DSP2) && (offset >= 0x200000))
|
||||
value = (address < 0x7000) ? dsp2_read() : 0x00;
|
||||
else if ((snes_cart.mode == SNES_MODE_21) && (snes_has_addon_chip == HAS_DSP1) && (offset < 0x100000))
|
||||
value = (address < 0x7000) ? dsp1_get_dr() : dsp1_get_sr();
|
||||
else if (snes_has_addon_chip == HAS_CX4)
|
||||
value = CX4_read(address - 0x6000);
|
||||
else if (snes_has_addon_chip == HAS_SPC7110 || snes_has_addon_chip == HAS_SPC7110_RTC)
|
||||
{
|
||||
if (offset < 0x10000)
|
||||
value = snes_ram[0x306000 + (offset & 0x1fff)];
|
||||
}
|
||||
else
|
||||
{
|
||||
logerror( "snes_r_bank1: Unmapped external chip read: %04x\n", address );
|
||||
logerror("snes_r_bank1: Unmapped external chip read: %04x\n", address);
|
||||
value = 0xff; /* Reserved */
|
||||
}
|
||||
}
|
||||
else if ((snes_cart.mode == SNES_MODE_20) && (snes_has_addon_chip == HAS_DSP1) && (offset >= 0x200000))
|
||||
value = (address < 0xc000) ? dsp1_get_dr() : dsp1_get_sr();
|
||||
else if ((snes_cart.mode == SNES_MODE_20) && (snes_has_addon_chip == HAS_DSP2) && (offset >= 0x200000))
|
||||
value = (address < 0xc000) ? dsp2_read() : 0x00;
|
||||
value = (address < 0xc000) ? dsp2_dr_read() : dsp2_sr_read();
|
||||
else if ((snes_has_addon_chip == HAS_DSP3) && (offset >= 0x200000))
|
||||
value = dsp3_read(address);
|
||||
else
|
||||
@ -1645,7 +1646,7 @@ READ8_HANDLER( snes_r_bank1 )
|
||||
/* 0x300000 - 0x3fffff */
|
||||
READ8_HANDLER( snes_r_bank2 )
|
||||
{
|
||||
UINT8 value;
|
||||
UINT8 value = 0xff;
|
||||
UINT16 address = offset & 0xffff;
|
||||
|
||||
if (address < 0x2000) /* Mirror of Low RAM */
|
||||
@ -1655,13 +1656,16 @@ READ8_HANDLER( snes_r_bank2 )
|
||||
else if (address < 0x8000) /* SRAM for mode_21, Reserved othewise */
|
||||
{
|
||||
if (snes_has_addon_chip == HAS_SUPERFX)
|
||||
value = snes_ram[0xf00000 + (address & 0x1fff)]; // here it should 0xe00000 but there are mirroring issues
|
||||
value = snes_ram[0xf00000 + (address & 0x1fff)]; // here it should be 0xe00000 but there are mirroring issues
|
||||
else if (snes_has_addon_chip == HAS_OBC1)
|
||||
value = obc1_read (space, offset);
|
||||
else if (snes_has_addon_chip == HAS_DSP2)
|
||||
value = (address < 0x7000) ? dsp2_read() : 0x00;
|
||||
else if (snes_has_addon_chip == HAS_CX4)
|
||||
value = CX4_read(address - 0x6000);
|
||||
else if (snes_has_addon_chip == HAS_SPC7110 || snes_has_addon_chip == HAS_SPC7110_RTC)
|
||||
{
|
||||
if (offset < 0x10000)
|
||||
value = snes_ram[0x306000 + (offset & 0x1fff)];
|
||||
}
|
||||
else if ((snes_cart.mode == SNES_MODE_21) && (snes_cart.sram > 0))
|
||||
{
|
||||
int mask = ((snes_cart.sram * 1024) - 1); /* Limit SRAM size to what's actually present */
|
||||
@ -1678,7 +1682,7 @@ READ8_HANDLER( snes_r_bank2 )
|
||||
else if ((snes_cart.mode == SNES_MODE_20) && (snes_has_addon_chip == HAS_DSP1))
|
||||
value = (address < 0xc000) ? dsp1_get_dr() : dsp1_get_sr();
|
||||
else if ((snes_cart.mode == SNES_MODE_20) && (snes_has_addon_chip == HAS_DSP2))
|
||||
value = (address < 0xc000) ? dsp2_read() : 0x00;
|
||||
value = (address < 0xc000) ? dsp2_dr_read() : dsp2_sr_read();
|
||||
else if (snes_has_addon_chip == HAS_DSP3)
|
||||
value = dsp3_read(address);
|
||||
else if (snes_has_addon_chip == HAS_DSP4)
|
||||
@ -1692,10 +1696,15 @@ READ8_HANDLER( snes_r_bank2 )
|
||||
/* 0x400000 - 0x5fffff */
|
||||
READ8_HANDLER( snes_r_bank3 )
|
||||
{
|
||||
UINT8 value;
|
||||
UINT8 value = 0xff;
|
||||
UINT16 address = offset & 0xffff;
|
||||
|
||||
if ((snes_cart.mode & 5) && !(snes_has_addon_chip == HAS_SUPERFX)) /* Mode 20 & 22 */
|
||||
if ((snes_has_addon_chip == HAS_SPC7110 || snes_has_addon_chip == HAS_SPC7110_RTC))
|
||||
{
|
||||
if (offset >= 0x100000 && offset < 0x110000)
|
||||
value = spc7110_mmio_read(space->machine, 0x4800);
|
||||
}
|
||||
else if ((snes_cart.mode & 5) && !(snes_has_addon_chip == HAS_SUPERFX)) /* Mode 20 & 22 */
|
||||
{
|
||||
if ((address < 0x8000) && (snes_cart.mode == SNES_MODE_20))
|
||||
value = 0xff; /* Reserved */
|
||||
@ -1727,7 +1736,7 @@ READ8_HANDLER( snes_r_bank4 )
|
||||
value = (address >= 0x4000) ? dsp1_get_sr() : dsp1_get_dr();
|
||||
else
|
||||
{
|
||||
logerror( "snes_r_bank4: Unmapped external chip read: %04x\n", address );
|
||||
logerror("snes_r_bank4: Unmapped external chip read: %04x\n", address);
|
||||
value = 0xff; /* Reserved */
|
||||
}
|
||||
}
|
||||
@ -1776,10 +1785,8 @@ READ8_HANDLER( snes_r_bank6 )
|
||||
{
|
||||
if (snes_cart.mode != SNES_MODE_25)
|
||||
value = memory_read_byte(space, offset);
|
||||
else if (snes_has_addon_chip == HAS_CX4)
|
||||
{
|
||||
//printf( "R: CX4 hit from 0x800000\n" );
|
||||
}
|
||||
else if ((snes_has_addon_chip == HAS_CX4) && (address >= 0x6000))
|
||||
value = CX4_read(address - 0x6000);
|
||||
else /* Mode 25 has SRAM not mirrored from lower banks */
|
||||
{
|
||||
if (address < 0x6000)
|
||||
@ -1800,7 +1807,7 @@ READ8_HANDLER( snes_r_bank6 )
|
||||
else if ((snes_cart.mode == SNES_MODE_20) && (snes_has_addon_chip == HAS_DSP1) && (offset >= 0x200000))
|
||||
value = (address < 0xc000) ? dsp1_get_dr() : dsp1_get_sr();
|
||||
else if ((snes_cart.mode == SNES_MODE_20) && (snes_has_addon_chip == HAS_DSP2) && (offset >= 0x200000))
|
||||
value = (address < 0xc000) ? dsp2_read() : 0x00;
|
||||
value = (address < 0xc000) ? dsp2_dr_read() : dsp2_sr_read();
|
||||
else if ((snes_has_addon_chip == HAS_DSP3) && (offset >= 0x200000))
|
||||
value = dsp3_read(address);
|
||||
else if ((snes_has_addon_chip == HAS_DSP4) && (offset >= 0x300000))
|
||||
@ -1817,7 +1824,9 @@ READ8_HANDLER( snes_r_bank7 )
|
||||
UINT8 value = 0;
|
||||
UINT16 address = offset & 0xffff;
|
||||
|
||||
if (snes_has_addon_chip == HAS_SDD1)
|
||||
if ((snes_has_addon_chip == HAS_SPC7110 || snes_has_addon_chip == HAS_SPC7110_RTC) && offset >= 0x100000)
|
||||
value = spc7110_bank7_read(space->machine, offset);
|
||||
else if (snes_has_addon_chip == HAS_SDD1)
|
||||
value = sdd1_read(space->machine, offset);
|
||||
else if (snes_has_addon_chip == HAS_ST010 && offset >= 0x280000 && offset < 0x300000 && address < 0x1000)
|
||||
value = st010_read(address);
|
||||
@ -1850,23 +1859,27 @@ WRITE8_HANDLER( snes_w_bank1 )
|
||||
snes_ram[0xf00000 + (address & 0x1fff)] = data; // here it should 0xe00000 but there are mirroring issues
|
||||
else if (snes_has_addon_chip == HAS_OBC1)
|
||||
obc1_write(space, offset, data);
|
||||
else if ((snes_has_addon_chip == HAS_DSP2) && (offset >= 0x200000))
|
||||
dsp2_write(data);
|
||||
else if ((snes_cart.mode == SNES_MODE_21) && (snes_has_addon_chip == HAS_DSP1) && (offset < 0x100000))
|
||||
dsp1_set_dr(data);
|
||||
else if (snes_has_addon_chip == HAS_CX4)
|
||||
CX4_write(space->machine, address - 0x6000, data);
|
||||
else if (snes_has_addon_chip == HAS_SPC7110 || snes_has_addon_chip == HAS_SPC7110_RTC)
|
||||
{
|
||||
if (offset < 0x10000)
|
||||
snes_ram[0x306000 + (offset & 0x1fff)] = data;
|
||||
}
|
||||
else
|
||||
logerror( "snes_w_bank1: Attempt to write to reserved address: %x = %02x\n", offset, data );
|
||||
logerror("snes_w_bank1: Attempt to write to reserved address: %x = %02x\n", offset, data);
|
||||
}
|
||||
else if ((snes_cart.mode == SNES_MODE_20) && (snes_has_addon_chip == HAS_DSP1) && (offset >= 0x200000))
|
||||
dsp1_set_dr(data);
|
||||
else if ((snes_cart.mode == SNES_MODE_20) && (snes_has_addon_chip == HAS_DSP2) && (offset >= 0x200000) && (address < 0xc000))
|
||||
dsp2_write(data);
|
||||
else if ((snes_cart.mode == SNES_MODE_20) && (snes_has_addon_chip == HAS_DSP2) && (offset >= 0x200000))
|
||||
{
|
||||
if (address < 0xc000)
|
||||
dsp2_dr_write(data);
|
||||
else
|
||||
dsp2_sr_write(data);
|
||||
}
|
||||
else if ((snes_has_addon_chip == HAS_DSP3) && (offset >= 0x200000))
|
||||
dsp3_write(address, data);
|
||||
else
|
||||
@ -1885,13 +1898,14 @@ WRITE8_HANDLER( snes_w_bank2 )
|
||||
else if (address < 0x8000) /* SRAM for mode_21, Reserved othewise */
|
||||
{
|
||||
if (snes_has_addon_chip == HAS_SUPERFX)
|
||||
snes_ram[0xf00000 + (address & 0x1fff)] = data; // here it should 0xe00000 but there are mirroring issues
|
||||
snes_ram[0xf00000 + (address & 0x1fff)] = data; // here it should be 0xe00000 but there are mirroring issues
|
||||
else if (snes_has_addon_chip == HAS_OBC1)
|
||||
obc1_write(space, offset, data);
|
||||
else if (snes_has_addon_chip == HAS_DSP2)
|
||||
dsp2_write(data);
|
||||
else if (snes_has_addon_chip == HAS_CX4)
|
||||
CX4_write(space->machine, address - 0x6000, data);
|
||||
else if (snes_has_addon_chip == HAS_SPC7110 || snes_has_addon_chip == HAS_SPC7110_RTC)
|
||||
{
|
||||
if (offset < 0x10000)
|
||||
snes_ram[0x306000 + (offset & 0x1fff)] = data;
|
||||
}
|
||||
else if ((snes_cart.mode == SNES_MODE_21) && (snes_cart.sram > 0))
|
||||
@ -1906,8 +1920,13 @@ WRITE8_HANDLER( snes_w_bank2 )
|
||||
/* some dsp1 games use these banks 0x30 to 0x3f at address 0x8000 */
|
||||
else if ((snes_cart.mode == SNES_MODE_20) && (snes_has_addon_chip == HAS_DSP1))
|
||||
dsp1_set_dr(data);
|
||||
else if ((snes_cart.mode == SNES_MODE_20) && (snes_has_addon_chip == HAS_DSP2) && (address < 0xc000))
|
||||
dsp2_write(data);
|
||||
else if ((snes_cart.mode == SNES_MODE_20) && (snes_has_addon_chip == HAS_DSP2))
|
||||
{
|
||||
if (address < 0xc000)
|
||||
dsp2_dr_write(data);
|
||||
else
|
||||
dsp2_sr_write(data);
|
||||
}
|
||||
else if (snes_has_addon_chip == HAS_DSP3)
|
||||
dsp3_write(address, data);
|
||||
else if ((snes_has_addon_chip == HAS_DSP4) && (address < 0xc000))
|
||||
@ -1969,11 +1988,9 @@ WRITE8_HANDLER( snes_w_bank6 )
|
||||
memory_write_byte(space, offset, data);
|
||||
else if (address < 0x8000)
|
||||
{
|
||||
if (snes_has_addon_chip == HAS_CX4)
|
||||
{
|
||||
//printf( "R: CX4 hit from 0x800000\n" );
|
||||
}
|
||||
if (snes_cart.mode != SNES_MODE_25)
|
||||
if ((snes_has_addon_chip == HAS_CX4) && (address >= 0x6000))
|
||||
CX4_write(space->machine, address - 0x6000, data);
|
||||
else if (snes_cart.mode != SNES_MODE_25)
|
||||
memory_write_byte(space, offset, data);
|
||||
else /* Mode 25 has SRAM not mirrored from lower banks */
|
||||
{
|
||||
@ -1991,8 +2008,13 @@ WRITE8_HANDLER( snes_w_bank6 )
|
||||
}
|
||||
else if ((snes_cart.mode == SNES_MODE_20) && (snes_has_addon_chip == HAS_DSP1) && (offset >= 0x200000))
|
||||
dsp1_set_dr(data);
|
||||
else if ((snes_cart.mode == SNES_MODE_20) && (snes_has_addon_chip == HAS_DSP2) && (offset >= 0x200000) && (address < 0xc000))
|
||||
dsp2_write(data);
|
||||
else if ((snes_cart.mode == SNES_MODE_20) && (snes_has_addon_chip == HAS_DSP2) && (offset >= 0x200000))
|
||||
{
|
||||
if (address < 0xc000)
|
||||
dsp2_dr_write(data);
|
||||
else
|
||||
dsp2_sr_write(data);
|
||||
}
|
||||
else if ((snes_has_addon_chip == HAS_DSP3) && (offset >= 0x200000))
|
||||
dsp3_write(address, data);
|
||||
else if ((snes_has_addon_chip == HAS_DSP4) && (offset >= 0x300000) && (address < 0xc000))
|
||||
@ -2289,9 +2311,11 @@ MACHINE_START( snes )
|
||||
sdd1_init(machine);
|
||||
break;
|
||||
case HAS_SPC7110:
|
||||
case HAS_SPC7110_RTC:
|
||||
spc7110_init(machine);
|
||||
break;
|
||||
case HAS_SPC7110_RTC:
|
||||
spc7110rtc_init(machine);
|
||||
break;
|
||||
case HAS_ST010:
|
||||
st010_init(machine);
|
||||
break;
|
||||
|
@ -764,6 +764,7 @@ static UINT32 SPC7110Decomp_morton_4x8(SPC7110Decomp *thisptr, UINT32 data)
|
||||
|
||||
static void spc7110_mmio_write(running_machine *machine, UINT32 addr, UINT8 data);
|
||||
static UINT8 spc7110_mmio_read(running_machine *machine, UINT32 addr);
|
||||
static void spc7110_update_time(running_machine *machine, UINT8 offset);
|
||||
|
||||
enum RTC_State
|
||||
{
|
||||
@ -859,6 +860,9 @@ typedef struct
|
||||
UINT32 rtc_mode;
|
||||
UINT32 rtc_index;
|
||||
|
||||
UINT64 rtc_offset;
|
||||
|
||||
UINT8 rtc_ram[16]; // 0-12 secs, min, hrs, etc.; 13-14-15 control registers
|
||||
} _snes_spc7110_t;
|
||||
|
||||
static _snes_spc7110_t snes_spc7110;
|
||||
@ -921,6 +925,19 @@ static void spc7110_init(running_machine* machine)
|
||||
snes_spc7110.decomp = SPC7110Decomp_ctor(machine);
|
||||
}
|
||||
|
||||
static void spc7110rtc_init(running_machine* machine)
|
||||
{
|
||||
spc7110_init(machine);
|
||||
|
||||
snes_spc7110.rtc_state = RTCS_Inactive;
|
||||
snes_spc7110.rtc_mode = RTCM_Linear;
|
||||
snes_spc7110.rtc_index = 0;
|
||||
|
||||
snes_spc7110.rtc_offset = 0;
|
||||
|
||||
spc7110_update_time(machine, 0);
|
||||
}
|
||||
|
||||
static UINT32 spc7110_datarom_addr(UINT32 addr)
|
||||
{
|
||||
UINT32 size = snes_rom_size - 0x100000;
|
||||
@ -959,6 +976,86 @@ static void spc7110_set_data_adjust(UINT32 addr)
|
||||
snes_spc7110.r4815 = addr >> 8;
|
||||
}
|
||||
|
||||
// FIXME: SPC7110 RTC is capable of rounding/adding/zero-ing seconds, so
|
||||
// we should probably keep track internally of the time rather than updating
|
||||
// to the system time at each call with a "offset" tracking as we do now...
|
||||
// (and indeed current code fails to pass Tengai Makyou Zero tests)
|
||||
static void spc7110_update_time(running_machine *machine, UINT8 offset)
|
||||
{
|
||||
mame_system_time curtime, *systime = &curtime;
|
||||
mame_get_current_datetime(machine, &curtime);
|
||||
int update = 1;
|
||||
|
||||
snes_spc7110.rtc_offset += offset;
|
||||
|
||||
// TEST: can we go beyond 24hrs of rounding?!? I doubt it will ever go beyond 3600, but I could be wrong...
|
||||
assert(snes_spc7110.rtc_offset < 86400);
|
||||
|
||||
/* do not update if CR0 or CR2 timer disable flags are set */
|
||||
if ((snes_spc7110.rtc_ram[13] & 0x01) || (snes_spc7110.rtc_ram[15] & 0x03))
|
||||
update = 0;
|
||||
|
||||
if (update)
|
||||
{
|
||||
/* update time with offset, assuming offset < 3600s */
|
||||
UINT8 second = systime->local_time.second;
|
||||
UINT8 minute = systime->local_time.minute;
|
||||
UINT8 hour = systime->local_time.hour;
|
||||
UINT8 mday = systime->local_time.mday;
|
||||
|
||||
while (snes_spc7110.rtc_offset >= 3600)
|
||||
{
|
||||
snes_spc7110.rtc_offset -= 3600;
|
||||
hour++;
|
||||
|
||||
if (hour == 24)
|
||||
{
|
||||
mday++;
|
||||
hour = 0;
|
||||
}
|
||||
}
|
||||
|
||||
while (snes_spc7110.rtc_offset >= 60)
|
||||
{
|
||||
snes_spc7110.rtc_offset -= 60;
|
||||
minute++;
|
||||
|
||||
if (minute == 60)
|
||||
{
|
||||
hour++;
|
||||
minute = 0;
|
||||
}
|
||||
}
|
||||
|
||||
while (snes_spc7110.rtc_offset)
|
||||
{
|
||||
snes_spc7110.rtc_offset -= 1;
|
||||
second++;
|
||||
|
||||
if (second == 60)
|
||||
{
|
||||
minute++;
|
||||
second = 0;
|
||||
}
|
||||
}
|
||||
|
||||
snes_spc7110.rtc_ram[0] = second % 10;
|
||||
snes_spc7110.rtc_ram[1] = second / 10;
|
||||
snes_spc7110.rtc_ram[2] = minute % 10;
|
||||
snes_spc7110.rtc_ram[3] = minute / 10;
|
||||
snes_spc7110.rtc_ram[4] = hour % 10;
|
||||
snes_spc7110.rtc_ram[5] = hour / 10;
|
||||
snes_spc7110.rtc_ram[6] = mday % 10;
|
||||
snes_spc7110.rtc_ram[7] = mday / 10;
|
||||
snes_spc7110.rtc_ram[8] = systime->local_time.month % 10;
|
||||
snes_spc7110.rtc_ram[9] = systime->local_time.month / 10;
|
||||
snes_spc7110.rtc_ram[8] = systime->local_time.month;
|
||||
snes_spc7110.rtc_ram[10] = (systime->local_time.year - 1900) % 10;
|
||||
snes_spc7110.rtc_ram[11] = ((systime->local_time.year - 1900) / 10) % 10;
|
||||
snes_spc7110.rtc_ram[12] = systime->local_time.weekday % 7;
|
||||
}
|
||||
}
|
||||
|
||||
static UINT8 spc7110_mmio_read(running_machine *machine, UINT32 addr)
|
||||
{
|
||||
UINT8 *ROM = memory_region(machine, "cart");
|
||||
@ -1119,6 +1216,27 @@ static UINT8 spc7110_mmio_read(running_machine *machine, UINT32 addr)
|
||||
case 0x4833: return snes_spc7110.r4833;
|
||||
case 0x4834: return snes_spc7110.r4834;
|
||||
|
||||
//====================
|
||||
//real-time clock unit
|
||||
//====================
|
||||
case 0x4840: return snes_spc7110.r4840;
|
||||
case 0x4841:
|
||||
{
|
||||
UINT8 data = 0;
|
||||
if (snes_spc7110.rtc_state == RTCS_Inactive || snes_spc7110.rtc_state == RTCS_ModeSelect)
|
||||
return 0x00;
|
||||
|
||||
snes_spc7110.r4842 = 0x80;
|
||||
data = snes_spc7110.rtc_ram[snes_spc7110.rtc_index];
|
||||
snes_spc7110.rtc_index = (snes_spc7110.rtc_index + 1) & 15;
|
||||
return data;
|
||||
}
|
||||
case 0x4842:
|
||||
{
|
||||
UINT8 status = snes_spc7110.r4842;
|
||||
snes_spc7110.r4842 &= 0x7f;
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
return 0xff;
|
||||
@ -1157,7 +1275,8 @@ static void spc7110_mmio_write(running_machine *machine, UINT32 addr, UINT8 data
|
||||
|
||||
SPC7110Decomp_init(snes_spc7110.decomp, machine, mode, offset, (snes_spc7110.r4805 + (snes_spc7110.r4806 << 8)) << mode);
|
||||
snes_spc7110.r480c = 0x80;
|
||||
} break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x4807: snes_spc7110.r4807 = data; break;
|
||||
case 0x4808: snes_spc7110.r4808 = data; break;
|
||||
@ -1252,7 +1371,8 @@ static void spc7110_mmio_write(running_machine *machine, UINT32 addr, UINT8 data
|
||||
case 0x4817: snes_spc7110.r4817 = data; break;
|
||||
case 0x4818:
|
||||
{
|
||||
if(snes_spc7110.r481x != 0x07) break;
|
||||
if(snes_spc7110.r481x != 0x07)
|
||||
break;
|
||||
|
||||
snes_spc7110.r4818 = data;
|
||||
snes_spc7110.r4814_latch = snes_spc7110.r4815_latch = 0;
|
||||
@ -1272,7 +1392,8 @@ static void spc7110_mmio_write(running_machine *machine, UINT32 addr, UINT8 data
|
||||
{
|
||||
snes_spc7110.r4825 = data;
|
||||
|
||||
if(snes_spc7110.r482e & 1) {
|
||||
if(snes_spc7110.r482e & 1)
|
||||
{
|
||||
//signed 16-bit x 16-bit multiplication
|
||||
INT16 r0 = (INT16)(snes_spc7110.r4824 + (snes_spc7110.r4825 << 8));
|
||||
INT16 r1 = (INT16)(snes_spc7110.r4820 + (snes_spc7110.r4821 << 8));
|
||||
@ -1282,7 +1403,9 @@ static void spc7110_mmio_write(running_machine *machine, UINT32 addr, UINT8 data
|
||||
snes_spc7110.r4829 = result >> 8;
|
||||
snes_spc7110.r482a = result >> 16;
|
||||
snes_spc7110.r482b = result >> 24;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
//unsigned 16-bit x 16-bit multiplication
|
||||
UINT16 r0 = (UINT16)(snes_spc7110.r4824 + (snes_spc7110.r4825 << 8));
|
||||
UINT16 r1 = (UINT16)(snes_spc7110.r4820 + (snes_spc7110.r4821 << 8));
|
||||
@ -1387,24 +1510,139 @@ static void spc7110_mmio_write(running_machine *machine, UINT32 addr, UINT8 data
|
||||
case 0x4831:
|
||||
{
|
||||
snes_spc7110.r4831 = data;
|
||||
snes_spc7110.dx_offset = spc7110_datarom_addr((data & 7) * 0x100000);
|
||||
snes_spc7110.dx_offset = spc7110_datarom_addr(data * 0x100000);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x4832:
|
||||
{
|
||||
snes_spc7110.r4832 = data;
|
||||
snes_spc7110.ex_offset = spc7110_datarom_addr((data & 7) * 0x100000);
|
||||
snes_spc7110.ex_offset = spc7110_datarom_addr(data * 0x100000);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x4833:
|
||||
{
|
||||
snes_spc7110.r4833 = data;
|
||||
snes_spc7110.fx_offset = spc7110_datarom_addr((data & 7) * 0x100000);
|
||||
snes_spc7110.fx_offset = spc7110_datarom_addr(data * 0x100000);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x4834: snes_spc7110.r4834 = data; break;
|
||||
|
||||
//====================
|
||||
//real-time clock unit
|
||||
//====================
|
||||
|
||||
case 0x4840:
|
||||
{
|
||||
snes_spc7110.r4840 = data;
|
||||
|
||||
if (!(snes_spc7110.r4840 & 1))
|
||||
{
|
||||
//disable RTC
|
||||
snes_spc7110.rtc_state = RTCS_Inactive;
|
||||
spc7110_update_time(machine, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
//enable RTC
|
||||
snes_spc7110.r4842 = 0x80;
|
||||
snes_spc7110.rtc_state = RTCS_ModeSelect;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x4841:
|
||||
{
|
||||
snes_spc7110.r4841 = data;
|
||||
|
||||
switch (snes_spc7110.rtc_state)
|
||||
{
|
||||
case RTCS_ModeSelect:
|
||||
if (data == RTCM_Linear || data == RTCM_Indexed)
|
||||
{
|
||||
snes_spc7110.r4842 = 0x80;
|
||||
snes_spc7110.rtc_state = RTCS_IndexSelect;
|
||||
snes_spc7110.rtc_mode = (RTC_Mode)data;
|
||||
snes_spc7110.rtc_index = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case RTCS_IndexSelect:
|
||||
snes_spc7110.r4842 = 0x80;
|
||||
snes_spc7110.rtc_index = data & 15;
|
||||
if (snes_spc7110.rtc_mode == RTCM_Linear)
|
||||
snes_spc7110.rtc_state = RTCS_Write;
|
||||
break;
|
||||
|
||||
case RTCS_Write:
|
||||
snes_spc7110.r4842 = 0x80;
|
||||
|
||||
//control register 0
|
||||
if (snes_spc7110.rtc_index == 13)
|
||||
{
|
||||
//increment second counter
|
||||
if (data & 2)
|
||||
spc7110_update_time(machine, 1);
|
||||
|
||||
//round minute counter
|
||||
if (data & 8)
|
||||
{
|
||||
spc7110_update_time(machine, 0);
|
||||
|
||||
UINT8 second = snes_spc7110.rtc_ram[0] + snes_spc7110.rtc_ram[1] * 10;
|
||||
//clear seconds
|
||||
snes_spc7110.rtc_ram[0] = 0;
|
||||
snes_spc7110.rtc_ram[1] = 0;
|
||||
|
||||
if (second >= 30)
|
||||
spc7110_update_time(machine, 60);
|
||||
}
|
||||
}
|
||||
|
||||
//control register 2
|
||||
if (snes_spc7110.rtc_index == 15)
|
||||
{
|
||||
//disable timer and clear second counter
|
||||
if ((data & 1) && !(snes_spc7110.rtc_ram[15] & 1))
|
||||
{
|
||||
spc7110_update_time(machine, 0);
|
||||
|
||||
//clear seconds
|
||||
snes_spc7110.rtc_ram[0] = 0;
|
||||
snes_spc7110.rtc_ram[1] = 0;
|
||||
}
|
||||
|
||||
//disable timer
|
||||
if((data & 2) && !(snes_spc7110.rtc_ram[15] & 2))
|
||||
spc7110_update_time(machine, 0);
|
||||
}
|
||||
|
||||
snes_spc7110.rtc_ram[snes_spc7110.rtc_index] = data & 15;
|
||||
snes_spc7110.rtc_index = (snes_spc7110.rtc_index + 1) & 15;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static UINT8 spc7110_bank7_read(running_machine *machine, UINT32 offset)
|
||||
{
|
||||
UINT8 *ROM = memory_region(machine, "cart");
|
||||
UINT32 addr = offset & 0x0fffff;
|
||||
|
||||
switch (offset & 0xf00000)
|
||||
{
|
||||
case 0x100000:
|
||||
return ROM[snes_spc7110.dx_offset + addr];
|
||||
case 0x200000:
|
||||
return ROM[snes_spc7110.ex_offset + addr];
|
||||
case 0x300000:
|
||||
return ROM[snes_spc7110.fx_offset + addr];
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0xff;
|
||||
}
|
||||
|
@ -254,7 +254,7 @@ static void dsp2_init( running_machine *machine )
|
||||
dsp2_register_save(machine);
|
||||
}
|
||||
|
||||
static UINT8 dsp2_read( void )
|
||||
static UINT8 dsp2_dr_read( void )
|
||||
{
|
||||
UINT8 r = 0xff;
|
||||
if (dsp2_state.out_count)
|
||||
@ -267,7 +267,7 @@ static UINT8 dsp2_read( void )
|
||||
return r;
|
||||
}
|
||||
|
||||
static void dsp2_write(UINT8 data)
|
||||
static void dsp2_dr_write(UINT8 data)
|
||||
{
|
||||
if (dsp2_state.waiting_for_command)
|
||||
{
|
||||
@ -377,6 +377,16 @@ static void dsp2_write(UINT8 data)
|
||||
}
|
||||
}
|
||||
|
||||
static UINT8 dsp2_sr_read( void )
|
||||
{
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
static void dsp2_sr_write( UINT8 data )
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
static void dsp2_register_save( running_machine *machine )
|
||||
{
|
||||
state_save_register_global(machine, dsp2_state.waiting_for_command);
|
||||
|
@ -52,9 +52,9 @@ static void srtc_update_time( running_machine *machine )
|
||||
rtc_state.ram[6] = systime->local_time.mday % 10;
|
||||
rtc_state.ram[7] = systime->local_time.mday / 10;
|
||||
rtc_state.ram[8] = systime->local_time.month;
|
||||
rtc_state.ram[9] = (systime->local_time.year - 1900) % 10;
|
||||
rtc_state.ram[10] = ((systime->local_time.year - 1900) / 10) % 10;
|
||||
rtc_state.ram[11] = (systime->local_time.year - 1900) / 100;
|
||||
rtc_state.ram[9] = (systime->local_time.year - 1000) % 10;
|
||||
rtc_state.ram[10] = ((systime->local_time.year - 1000) / 10) % 10;
|
||||
rtc_state.ram[11] = (systime->local_time.year - 1000) / 100;
|
||||
rtc_state.ram[12] = systime->local_time.weekday % 7;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user