diff --git a/src/mame/machine/snes.c b/src/mame/machine/snes.c index b11a2ef57d8..645c2e618c0 100644 --- a/src/mame/machine/snes.c +++ b/src/mame/machine/snes.c @@ -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) - value = snes_ram[0x306000 + (offset & 0x1fff)]; + { + 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) - value = snes_ram[0x306000 + (offset & 0x1fff)]; + { + 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,12 +1736,12 @@ 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 */ } } else if (snes_cart.mode & 0x0a) /* Mode 21 & 25 */ - value = snes_ram[0x600000 + offset]; + value = snes_ram[0x600000 + offset]; return value; } @@ -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) { - snes_ram[0x306000 + (offset & 0x1fff)] = data; + 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,14 +1898,15 @@ 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) { - snes_ram[0x306000 + (offset & 0x1fff)] = data; + 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; diff --git a/src/mame/machine/snes7110.c b/src/mame/machine/snes7110.c index 54c1db6df1e..589c8f9d93c 100644 --- a/src/mame/machine/snes7110.c +++ b/src/mame/machine/snes7110.c @@ -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"); @@ -967,11 +1064,11 @@ static UINT8 spc7110_mmio_read(running_machine *machine, UINT32 addr) switch(addr) { - //================== - //decompression unit - //================== + //================== + //decompression unit + //================== - case 0x4800: + case 0x4800: { UINT16 counter = (snes_spc7110.r4809 + (snes_spc7110.r480a << 8)); counter--; @@ -979,29 +1076,29 @@ static UINT8 spc7110_mmio_read(running_machine *machine, UINT32 addr) snes_spc7110.r480a = counter >> 8; return SPC7110Decomp_read(snes_spc7110.decomp); } - case 0x4801: return snes_spc7110.r4801; - case 0x4802: return snes_spc7110.r4802; - case 0x4803: return snes_spc7110.r4803; - case 0x4804: return snes_spc7110.r4804; - case 0x4805: return snes_spc7110.r4805; - case 0x4806: return snes_spc7110.r4806; - case 0x4807: return snes_spc7110.r4807; - case 0x4808: return snes_spc7110.r4808; - case 0x4809: return snes_spc7110.r4809; - case 0x480a: return snes_spc7110.r480a; - case 0x480b: return snes_spc7110.r480b; - case 0x480c: + case 0x4801: return snes_spc7110.r4801; + case 0x4802: return snes_spc7110.r4802; + case 0x4803: return snes_spc7110.r4803; + case 0x4804: return snes_spc7110.r4804; + case 0x4805: return snes_spc7110.r4805; + case 0x4806: return snes_spc7110.r4806; + case 0x4807: return snes_spc7110.r4807; + case 0x4808: return snes_spc7110.r4808; + case 0x4809: return snes_spc7110.r4809; + case 0x480a: return snes_spc7110.r480a; + case 0x480b: return snes_spc7110.r480b; + case 0x480c: { UINT8 status = snes_spc7110.r480c; snes_spc7110.r480c &= 0x7f; return status; } - //============== - //data port unit - //============== + //============== + //data port unit + //============== - case 0x4810: + case 0x4810: { UINT8 data; UINT32 address, adjust, adjustaddr; @@ -1043,15 +1140,15 @@ static UINT8 spc7110_mmio_read(running_machine *machine, UINT32 addr) return data; } - case 0x4811: return snes_spc7110.r4811; - case 0x4812: return snes_spc7110.r4812; - case 0x4813: return snes_spc7110.r4813; - case 0x4814: return snes_spc7110.r4814; - case 0x4815: return snes_spc7110.r4815; - case 0x4816: return snes_spc7110.r4816; - case 0x4817: return snes_spc7110.r4817; - case 0x4818: return snes_spc7110.r4818; - case 0x481a: + case 0x4811: return snes_spc7110.r4811; + case 0x4812: return snes_spc7110.r4812; + case 0x4813: return snes_spc7110.r4813; + case 0x4814: return snes_spc7110.r4814; + case 0x4815: return snes_spc7110.r4815; + case 0x4816: return snes_spc7110.r4816; + case 0x4817: return snes_spc7110.r4817; + case 0x4818: return snes_spc7110.r4818; + case 0x481a: { UINT8 data; UINT32 address, adjust; @@ -1083,42 +1180,63 @@ static UINT8 spc7110_mmio_read(running_machine *machine, UINT32 addr) return data; } - //========= - //math unit - //========= + //========= + //math unit + //========= - case 0x4820: return snes_spc7110.r4820; - case 0x4821: return snes_spc7110.r4821; - case 0x4822: return snes_spc7110.r4822; - case 0x4823: return snes_spc7110.r4823; - case 0x4824: return snes_spc7110.r4824; - case 0x4825: return snes_spc7110.r4825; - case 0x4826: return snes_spc7110.r4826; - case 0x4827: return snes_spc7110.r4827; - case 0x4828: return snes_spc7110.r4828; - case 0x4829: return snes_spc7110.r4829; - case 0x482a: return snes_spc7110.r482a; - case 0x482b: return snes_spc7110.r482b; - case 0x482c: return snes_spc7110.r482c; - case 0x482d: return snes_spc7110.r482d; - case 0x482e: return snes_spc7110.r482e; - case 0x482f: - { + case 0x4820: return snes_spc7110.r4820; + case 0x4821: return snes_spc7110.r4821; + case 0x4822: return snes_spc7110.r4822; + case 0x4823: return snes_spc7110.r4823; + case 0x4824: return snes_spc7110.r4824; + case 0x4825: return snes_spc7110.r4825; + case 0x4826: return snes_spc7110.r4826; + case 0x4827: return snes_spc7110.r4827; + case 0x4828: return snes_spc7110.r4828; + case 0x4829: return snes_spc7110.r4829; + case 0x482a: return snes_spc7110.r482a; + case 0x482b: return snes_spc7110.r482b; + case 0x482c: return snes_spc7110.r482c; + case 0x482d: return snes_spc7110.r482d; + case 0x482e: return snes_spc7110.r482e; + case 0x482f: + { UINT8 status = snes_spc7110.r482f; snes_spc7110.r482f &= 0x7f; return status; } - //=================== - //memory mapping unit - //=================== + //=================== + //memory mapping unit + //=================== - case 0x4830: return snes_spc7110.r4830; - case 0x4831: return snes_spc7110.r4831; - case 0x4832: return snes_spc7110.r4832; - case 0x4833: return snes_spc7110.r4833; - case 0x4834: return snes_spc7110.r4834; + case 0x4830: return snes_spc7110.r4830; + case 0x4831: return snes_spc7110.r4831; + case 0x4832: return snes_spc7110.r4832; + 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; @@ -1132,16 +1250,16 @@ static void spc7110_mmio_write(running_machine *machine, UINT32 addr, UINT8 data switch(addr) { - //================== - //decompression unit - //================== + //================== + //decompression unit + //================== - case 0x4801: snes_spc7110.r4801 = data; break; - case 0x4802: snes_spc7110.r4802 = data; break; - case 0x4803: snes_spc7110.r4803 = data; break; - case 0x4804: snes_spc7110.r4804 = data; break; - case 0x4805: snes_spc7110.r4805 = data; break; - case 0x4806: + case 0x4801: snes_spc7110.r4801 = data; break; + case 0x4802: snes_spc7110.r4802 = data; break; + case 0x4803: snes_spc7110.r4803 = data; break; + case 0x4804: snes_spc7110.r4804 = data; break; + case 0x4805: snes_spc7110.r4805 = data; break; + case 0x4806: { UINT32 table, index, length, address, mode, offset; snes_spc7110.r4806 = data; @@ -1157,22 +1275,23 @@ 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; - case 0x4809: snes_spc7110.r4809 = data; break; - case 0x480a: snes_spc7110.r480a = data; break; - case 0x480b: snes_spc7110.r480b = data; break; + case 0x4807: snes_spc7110.r4807 = data; break; + case 0x4808: snes_spc7110.r4808 = data; break; + case 0x4809: snes_spc7110.r4809 = data; break; + case 0x480a: snes_spc7110.r480a = data; break; + case 0x480b: snes_spc7110.r480b = data; break; - //============== - //data port unit - //============== + //============== + //data port unit + //============== - case 0x4811: snes_spc7110.r4811 = data; snes_spc7110.r481x |= 0x01; break; - case 0x4812: snes_spc7110.r4812 = data; snes_spc7110.r481x |= 0x02; break; - case 0x4813: snes_spc7110.r4813 = data; snes_spc7110.r481x |= 0x04; break; - case 0x4814: + case 0x4811: snes_spc7110.r4811 = data; snes_spc7110.r481x |= 0x01; break; + case 0x4812: snes_spc7110.r4812 = data; snes_spc7110.r481x |= 0x02; break; + case 0x4813: snes_spc7110.r4813 = data; snes_spc7110.r481x |= 0x04; break; + case 0x4814: { snes_spc7110.r4814 = data; snes_spc7110.r4814_latch = 1; @@ -1210,7 +1329,7 @@ static void spc7110_mmio_write(running_machine *machine, UINT32 addr, UINT8 data break; } - case 0x4815: + case 0x4815: { snes_spc7110.r4815 = data; snes_spc7110.r4815_latch = 1; @@ -1248,58 +1367,62 @@ static void spc7110_mmio_write(running_machine *machine, UINT32 addr, UINT8 data break; } - case 0x4816: snes_spc7110.r4816 = data; break; - case 0x4817: snes_spc7110.r4817 = data; break; - case 0x4818: + case 0x4816: snes_spc7110.r4816 = data; break; + 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; - break; - } + snes_spc7110.r4818 = data; + snes_spc7110.r4814_latch = snes_spc7110.r4815_latch = 0; + break; + } - //========= - //math unit - //========= + //========= + //math unit + //========= - case 0x4820: snes_spc7110.r4820 = data; break; - case 0x4821: snes_spc7110.r4821 = data; break; - case 0x4822: snes_spc7110.r4822 = data; break; - case 0x4823: snes_spc7110.r4823 = data; break; - case 0x4824: snes_spc7110.r4824 = data; break; - case 0x4825: + case 0x4820: snes_spc7110.r4820 = data; break; + case 0x4821: snes_spc7110.r4821 = data; break; + case 0x4822: snes_spc7110.r4822 = data; break; + case 0x4823: snes_spc7110.r4823 = data; break; + case 0x4824: snes_spc7110.r4824 = data; break; + case 0x4825: { - snes_spc7110.r4825 = data; + snes_spc7110.r4825 = data; - 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)); + 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)); - INT32 result = r0 * r1; - snes_spc7110.r4828 = result; - snes_spc7110.r4829 = result >> 8; - snes_spc7110.r482a = result >> 16; - snes_spc7110.r482b = result >> 24; - } 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)); + INT32 result = r0 * r1; + snes_spc7110.r4828 = result; + snes_spc7110.r4829 = result >> 8; + snes_spc7110.r482a = result >> 16; + snes_spc7110.r482b = result >> 24; + } + 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)); - UINT32 result = r0 * r1; - snes_spc7110.r4828 = result; - snes_spc7110.r4829 = result >> 8; - snes_spc7110.r482a = result >> 16; - snes_spc7110.r482b = result >> 24; + UINT32 result = r0 * r1; + snes_spc7110.r4828 = result; + snes_spc7110.r4829 = result >> 8; + snes_spc7110.r482a = result >> 16; + snes_spc7110.r482b = result >> 24; } snes_spc7110.r482f = 0x80; break; } - case 0x4826: snes_spc7110.r4826 = data; break; - case 0x4827: + case 0x4826: snes_spc7110.r4826 = data; break; + case 0x4827: { snes_spc7110.r4827 = data; @@ -1366,7 +1489,7 @@ static void spc7110_mmio_write(running_machine *machine, UINT32 addr, UINT8 data break; } - case 0x482e: + case 0x482e: { //reset math unit snes_spc7110.r4820 = snes_spc7110.r4821 = snes_spc7110.r4822 = snes_spc7110.r4823 = 0; @@ -1378,33 +1501,148 @@ static void spc7110_mmio_write(running_machine *machine, UINT32 addr, UINT8 data break; } - //=================== - //memory mapping unit - //=================== + //=================== + //memory mapping unit + //=================== - case 0x4830: snes_spc7110.r4830 = data; break; + case 0x4830: snes_spc7110.r4830 = data; break; - case 0x4831: + 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: + 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: + 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; + 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; +} diff --git a/src/mame/machine/snesdsp2.c b/src/mame/machine/snesdsp2.c index bbdce8179e3..bb58a259438 100644 --- a/src/mame/machine/snesdsp2.c +++ b/src/mame/machine/snesdsp2.c @@ -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); diff --git a/src/mame/machine/snesrtc.c b/src/mame/machine/snesrtc.c index c69d4d56fd6..8c8cd94320e 100644 --- a/src/mame/machine/snesrtc.c +++ b/src/mame/machine/snesrtc.c @@ -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; }