diff --git a/scripts/src/cpu.lua b/scripts/src/cpu.lua index 5f8ddbf8f64..273dc7b5597 100644 --- a/scripts/src/cpu.lua +++ b/scripts/src/cpu.lua @@ -853,32 +853,36 @@ end if CPUS["SH"] then files { + MAME_DIR .. "src/devices/cpu/sh/sh_fe.cpp", MAME_DIR .. "src/devices/cpu/sh/sh.cpp", MAME_DIR .. "src/devices/cpu/sh/sh.h", MAME_DIR .. "src/devices/cpu/sh/sh2.cpp", MAME_DIR .. "src/devices/cpu/sh/sh2.h", - MAME_DIR .. "src/devices/cpu/sh/sh2comn.cpp", - MAME_DIR .. "src/devices/cpu/sh/sh2comn.h", - MAME_DIR .. "src/devices/cpu/sh/sh_fe.cpp", MAME_DIR .. "src/devices/cpu/sh/sh2fe.cpp", + MAME_DIR .. "src/devices/cpu/sh/sh3comn.cpp", + MAME_DIR .. "src/devices/cpu/sh/sh3comn.h", + MAME_DIR .. "src/devices/cpu/sh/sh4.cpp", + MAME_DIR .. "src/devices/cpu/sh/sh4.h", + MAME_DIR .. "src/devices/cpu/sh/sh4comn.cpp", + MAME_DIR .. "src/devices/cpu/sh/sh4comn.h", + MAME_DIR .. "src/devices/cpu/sh/sh4dmac.cpp", + MAME_DIR .. "src/devices/cpu/sh/sh4dmac.h", MAME_DIR .. "src/devices/cpu/sh/sh4fe.cpp", + MAME_DIR .. "src/devices/cpu/sh/sh4regs.h", + MAME_DIR .. "src/devices/cpu/sh/sh4tmu.cpp", + MAME_DIR .. "src/devices/cpu/sh/sh4tmu.h", + MAME_DIR .. "src/devices/cpu/sh/sh7021.cpp", + MAME_DIR .. "src/devices/cpu/sh/sh7021.h", + MAME_DIR .. "src/devices/cpu/sh/sh7032.cpp", + MAME_DIR .. "src/devices/cpu/sh/sh7032.h", MAME_DIR .. "src/devices/cpu/sh/sh7604_bus.cpp", MAME_DIR .. "src/devices/cpu/sh/sh7604_bus.h", MAME_DIR .. "src/devices/cpu/sh/sh7604_sci.cpp", MAME_DIR .. "src/devices/cpu/sh/sh7604_sci.h", MAME_DIR .. "src/devices/cpu/sh/sh7604_wdt.cpp", MAME_DIR .. "src/devices/cpu/sh/sh7604_wdt.h", - MAME_DIR .. "src/devices/cpu/sh/sh4.cpp", - MAME_DIR .. "src/devices/cpu/sh/sh4.h", - MAME_DIR .. "src/devices/cpu/sh/sh4comn.cpp", - MAME_DIR .. "src/devices/cpu/sh/sh4comn.h", - MAME_DIR .. "src/devices/cpu/sh/sh3comn.cpp", - MAME_DIR .. "src/devices/cpu/sh/sh3comn.h", - MAME_DIR .. "src/devices/cpu/sh/sh4tmu.cpp", - MAME_DIR .. "src/devices/cpu/sh/sh4tmu.h", - MAME_DIR .. "src/devices/cpu/sh/sh4dmac.cpp", - MAME_DIR .. "src/devices/cpu/sh/sh4dmac.h", - MAME_DIR .. "src/devices/cpu/sh/sh4regs.h", + MAME_DIR .. "src/devices/cpu/sh/sh7604.cpp", + MAME_DIR .. "src/devices/cpu/sh/sh7604.h", } end diff --git a/src/devices/cpu/sh/sh.h b/src/devices/cpu/sh/sh.h index d87c1e9742d..33b7583cd1e 100644 --- a/src/devices/cpu/sh/sh.h +++ b/src/devices/cpu/sh/sh.h @@ -506,4 +506,4 @@ protected: sh_common_execution *m_sh; }; -#endif // MAME_CPU_SH2_SH2_H +#endif // MAME_CPU_SH_SH_H diff --git a/src/devices/cpu/sh/sh2.cpp b/src/devices/cpu/sh/sh2.cpp index 5da515fe422..72576a67b2d 100644 --- a/src/devices/cpu/sh/sh2.cpp +++ b/src/devices/cpu/sh/sh2.cpp @@ -1,5 +1,5 @@ // license:BSD-3-Clause -// copyright-holders:Juergen Buchmueller +// copyright-holders:Juergen Buchmueller, R. Belmont /***************************************************************************** * * sh2.c @@ -12,269 +12,109 @@ * *****************************************************************************/ -/***************************************************************************** - Changes - 20130129 Angelo Salese - - added illegal opcode exception handling, side effect of some Saturn games - on loading like Feda or Falcom Classics Vol. 1 - (i.e. Master CPU Incautiously transfers memory from CD to work RAM H, and - wipes out Slave CPU program code too while at it). - - 20051129 Mariusz Wojcieszek - - introduced memory_decrypted_read_word() for opcode fetching - - 20050813 Mariusz Wojcieszek - - fixed 64 bit / 32 bit division in division unit - - 20031015 O. Galibert - - dma fixes, thanks to sthief - - 20031013 O. Galibert, A. Giles - - timer fixes - - multi-cpu simplifications - - 20030915 O. Galibert - - fix DMA1 irq vector - - ignore writes to DRCRx - - fix cpu number issues - - fix slave/master recognition - - fix wrong-cpu-in-context problem with the timers - - 20021020 O. Galibert - - DMA implementation, lightly tested - - delay slot in debugger fixed - - add divide box mirrors - - Nicola-ify the indentation - - Uncrapify sh2_internal_* - - Put back nmi support that had been lost somehow - - 20020914 R. Belmont - - Initial SH2 internal timers implementation, based on code by O. Galibert. - Makes music work in galspanic4/s/s2, panic street, cyvern, other SKNS games. - - Fix to external division, thanks to "spice" on the E2J board. - Corrects behavior of s1945ii turret boss. - - 20020302 Olivier Galibert (galibert@mame.net) - - Fixed interrupt in delay slot - - Fixed rotcr - - Fixed div1 - - Fixed mulu - - Fixed negc - - 20020301 R. Belmont - - Fixed external division - - 20020225 Olivier Galibert (galibert@mame.net) - - Fixed interrupt handling - - 20010207 Sylvain Glaize (mokona@puupuu.org) - - - Bug fix in void MOVBM(uint32_t m, uint32_t n) (see comment) - - Support of full 32 bit addressing (RB, RW, RL and WB, WW, WL functions) - reason : when the two high bits of the address are set, access is - done directly in the cache data array. The SUPER KANEKO NOVA SYSTEM - sets the stack pointer here, using these addresses as usual RAM access. - - No real cache support has been added. - - Read/Write memory format correction (_bew to _bedw) (see also SH2 - definition in cpuintrf.c and DasmSH2(..) in sh2dasm.c ) - - 20010623 James Forshaw (TyRaNiD@totalise.net) - - - Modified operation of sh2_exception. Done cause mame irq system is stupid, and - doesnt really seem designed for any more than 8 interrupt lines. - - 20010701 James Forshaw (TyRaNiD@totalise.net) - - - Fixed DIV1 operation. Q bit now correctly generated - - 20020218 Added save states (mokona@puupuu.org) - - *****************************************************************************/ #include "emu.h" #include "sh2.h" -#include "sh2comn.h" #include "sh_dasm.h" +#include "cpu/drcumlsh.h" //#define VERBOSE 1 #include "logmacro.h" +constexpr int SH2_INT_15 = 15; + +#define CHECK_PENDING_IRQ(message) \ +do { \ + int irq = -1; \ + if (m_sh2_state->pending_irq & (1 << 0)) irq = 0; \ + if (m_sh2_state->pending_irq & (1 << 1)) irq = 1; \ + if (m_sh2_state->pending_irq & (1 << 2)) irq = 2; \ + if (m_sh2_state->pending_irq & (1 << 3)) irq = 3; \ + if (m_sh2_state->pending_irq & (1 << 4)) irq = 4; \ + if (m_sh2_state->pending_irq & (1 << 5)) irq = 5; \ + if (m_sh2_state->pending_irq & (1 << 6)) irq = 6; \ + if (m_sh2_state->pending_irq & (1 << 7)) irq = 7; \ + if (m_sh2_state->pending_irq & (1 << 8)) irq = 8; \ + if (m_sh2_state->pending_irq & (1 << 9)) irq = 9; \ + if (m_sh2_state->pending_irq & (1 << 10)) irq = 10; \ + if (m_sh2_state->pending_irq & (1 << 11)) irq = 11; \ + if (m_sh2_state->pending_irq & (1 << 12)) irq = 12; \ + if (m_sh2_state->pending_irq & (1 << 13)) irq = 13; \ + if (m_sh2_state->pending_irq & (1 << 14)) irq = 14; \ + if (m_sh2_state->pending_irq & (1 << 15)) irq = 15; \ + if ((m_sh2_state->internal_irq_level != -1) && (m_sh2_state->internal_irq_level > irq)) irq = m_sh2_state->internal_irq_level; \ + if (irq >= 0) \ + sh2_exception(message,irq); \ +} while(0) - -DEFINE_DEVICE_TYPE(SH1, sh1_device, "sh1", "Hitachi SH-1") -DEFINE_DEVICE_TYPE(SH2, sh2_device, "sh2", "Hitachi SH-2") -DEFINE_DEVICE_TYPE(SH2A, sh2a_device, "sh21", "Hitachi SH-2A") - -/*------------------------------------------------- - sh2_internal_a5 - read handler for - SH2 internal map --------------------------------------------------*/ - -uint32_t sh2_device::sh2_internal_a5() -{ - return 0xa5a5a5a5; -} - - -/*------------------------------------------------- - sh2_internal_map - maps SH2 built-ins --------------------------------------------------*/ - - -void sh2_device::sh7604_map(address_map &map) -{ - map(0x40000000, 0xbfffffff).r(FUNC(sh2_device::sh2_internal_a5)); - -// TODO: cps3boot breaks with this enabled. Needs callback -// map(0xc0000000, 0xc0000fff).ram(); // cache data array - -// map(0xe0000000, 0xe00001ff).mirror(0x1ffffe00).rw(FUNC(sh2_device::sh7604_r), FUNC(sh2_device::sh7604_w)); - // TODO: internal map takes way too much resources if mirrored with 0x1ffffe00 - // we eventually internalize again via trampoline & sh7604_device - // Also area 0xffff8000-0xffffbfff is for synchronous DRAM mode, - // so this isn't actually a full mirror - // SCI - map(0xfffffe00, 0xfffffe00).rw(FUNC(sh2_device::smr_r), FUNC(sh2_device::smr_w)); - map(0xfffffe01, 0xfffffe01).rw(FUNC(sh2_device::brr_r), FUNC(sh2_device::brr_w)); - map(0xfffffe02, 0xfffffe02).rw(FUNC(sh2_device::scr_r), FUNC(sh2_device::scr_w)); - map(0xfffffe03, 0xfffffe03).rw(FUNC(sh2_device::tdr_r), FUNC(sh2_device::tdr_w)); - map(0xfffffe04, 0xfffffe04).rw(FUNC(sh2_device::ssr_r), FUNC(sh2_device::ssr_w)); - map(0xfffffe05, 0xfffffe05).r(FUNC(sh2_device::rdr_r)); - - // FRC - map(0xfffffe10, 0xfffffe10).rw(FUNC(sh2_device::tier_r), FUNC(sh2_device::tier_w)); - map(0xfffffe11, 0xfffffe11).rw(FUNC(sh2_device::ftcsr_r), FUNC(sh2_device::ftcsr_w)); - map(0xfffffe12, 0xfffffe13).rw(FUNC(sh2_device::frc_r), FUNC(sh2_device::frc_w)); - map(0xfffffe14, 0xfffffe15).rw(FUNC(sh2_device::ocra_b_r), FUNC(sh2_device::ocra_b_w)); - map(0xfffffe16, 0xfffffe16).rw(FUNC(sh2_device::frc_tcr_r), FUNC(sh2_device::frc_tcr_w)); - map(0xfffffe17, 0xfffffe17).rw(FUNC(sh2_device::tocr_r), FUNC(sh2_device::tocr_w)); - map(0xfffffe18, 0xfffffe19).r(FUNC(sh2_device::frc_icr_r)); - - // INTC - map(0xfffffe60, 0xfffffe61).rw(FUNC(sh2_device::iprb_r), FUNC(sh2_device::iprb_w)); - map(0xfffffe62, 0xfffffe63).rw(FUNC(sh2_device::vcra_r), FUNC(sh2_device::vcra_w)); - map(0xfffffe64, 0xfffffe65).rw(FUNC(sh2_device::vcrb_r), FUNC(sh2_device::vcrb_w)); - map(0xfffffe66, 0xfffffe67).rw(FUNC(sh2_device::vcrc_r), FUNC(sh2_device::vcrc_w)); - map(0xfffffe68, 0xfffffe69).rw(FUNC(sh2_device::vcrd_r), FUNC(sh2_device::vcrd_w)); - - map(0xfffffe71, 0xfffffe71).rw(FUNC(sh2_device::drcr_r<0>), FUNC(sh2_device::drcr_w<0>)); - map(0xfffffe72, 0xfffffe72).rw(FUNC(sh2_device::drcr_r<1>), FUNC(sh2_device::drcr_w<1>)); - - // WTC - map(0xfffffe80, 0xfffffe81).rw(FUNC(sh2_device::wtcnt_r), FUNC(sh2_device::wtcnt_w)); - map(0xfffffe82, 0xfffffe83).rw(FUNC(sh2_device::rstcsr_r), FUNC(sh2_device::rstcsr_w)); - - // standby and cache control - map(0xfffffe90, 0xfffffe91).rw(FUNC(sh2_device::fmr_sbycr_r), FUNC(sh2_device::fmr_sbycr_w)); - map(0xfffffe92, 0xfffffe92).rw(FUNC(sh2_device::ccr_r), FUNC(sh2_device::ccr_w)); - - // INTC second section - map(0xfffffee0, 0xfffffee1).rw(FUNC(sh2_device::intc_icr_r), FUNC(sh2_device::intc_icr_w)); - map(0xfffffee2, 0xfffffee3).rw(FUNC(sh2_device::ipra_r), FUNC(sh2_device::ipra_w)); - map(0xfffffee4, 0xfffffee5).rw(FUNC(sh2_device::vcrwdt_r), FUNC(sh2_device::vcrwdt_w)); - - // DIVU - map(0xffffff00, 0xffffff03).rw(FUNC(sh2_device::dvsr_r), FUNC(sh2_device::dvsr_w)); - map(0xffffff04, 0xffffff07).rw(FUNC(sh2_device::dvdnt_r), FUNC(sh2_device::dvdnt_w)); - map(0xffffff08, 0xffffff0b).rw(FUNC(sh2_device::dvcr_r), FUNC(sh2_device::dvcr_w)); - // INTC third section - map(0xffffff0c, 0xffffff0f).rw(FUNC(sh2_device::vcrdiv_r), FUNC(sh2_device::vcrdiv_w)); - // DIVU continued (64-bit plus mirrors) - map(0xffffff10, 0xffffff13).rw(FUNC(sh2_device::dvdnth_r), FUNC(sh2_device::dvdnth_w)); - map(0xffffff14, 0xffffff17).rw(FUNC(sh2_device::dvdntl_r), FUNC(sh2_device::dvdntl_w)); - map(0xffffff18, 0xffffff1b).r(FUNC(sh2_device::dvdnth_r)); - map(0xffffff1c, 0xffffff1f).r(FUNC(sh2_device::dvdntl_r)); - - // DMAC - map(0xffffff80, 0xffffff83).rw(FUNC(sh2_device::sar_r<0>), FUNC(sh2_device::sar_w<0>)); - map(0xffffff84, 0xffffff87).rw(FUNC(sh2_device::dar_r<0>), FUNC(sh2_device::dar_w<0>)); - map(0xffffff88, 0xffffff8b).rw(FUNC(sh2_device::dmac_tcr_r<0>), FUNC(sh2_device::dmac_tcr_w<0>)); - map(0xffffff8c, 0xffffff8f).rw(FUNC(sh2_device::chcr_r<0>), FUNC(sh2_device::chcr_w<0>)); - - map(0xffffff90, 0xffffff93).rw(FUNC(sh2_device::sar_r<1>), FUNC(sh2_device::sar_w<1>)); - map(0xffffff94, 0xffffff97).rw(FUNC(sh2_device::dar_r<1>), FUNC(sh2_device::dar_w<1>)); - map(0xffffff98, 0xffffff9b).rw(FUNC(sh2_device::dmac_tcr_r<1>), FUNC(sh2_device::dmac_tcr_w<1>)); - map(0xffffff9c, 0xffffff9f).rw(FUNC(sh2_device::chcr_r<1>), FUNC(sh2_device::chcr_w<1>)); - - map(0xffffffa0, 0xffffffa3).rw(FUNC(sh2_device::vcrdma_r<0>), FUNC(sh2_device::vcrdma_w<0>)); - map(0xffffffa8, 0xffffffab).rw(FUNC(sh2_device::vcrdma_r<1>), FUNC(sh2_device::vcrdma_w<1>)); - map(0xffffffb0, 0xffffffb3).rw(FUNC(sh2_device::dmaor_r), FUNC(sh2_device::dmaor_w)); - - // BSC - map(0xffffffe0, 0xffffffe3).rw(FUNC(sh2_device::bcr1_r), FUNC(sh2_device::bcr1_w)); - map(0xffffffe4, 0xffffffe7).rw(FUNC(sh2_device::bcr2_r), FUNC(sh2_device::bcr2_w)); - map(0xffffffe8, 0xffffffeb).rw(FUNC(sh2_device::wcr_r), FUNC(sh2_device::wcr_w)); - map(0xffffffec, 0xffffffef).rw(FUNC(sh2_device::mcr_r), FUNC(sh2_device::mcr_w)); - map(0xfffffff0, 0xfffffff3).rw(FUNC(sh2_device::rtcsr_r), FUNC(sh2_device::rtcsr_w)); - map(0xfffffff4, 0xfffffff7).rw(FUNC(sh2_device::rtcnt_r), FUNC(sh2_device::rtcnt_w)); - map(0xfffffff8, 0xfffffffb).rw(FUNC(sh2_device::rtcor_r), FUNC(sh2_device::rtcor_w)); -} - -void sh2a_device::sh7021_map(address_map &map) -{ -// fall-back - map(0x05fffe00, 0x05ffffff).rw(FUNC(sh2a_device::sh7021_r), FUNC(sh2a_device::sh7021_w)); // SH-7032H internal i/o -// overrides - map(0x05ffff40, 0x05ffff43).rw(FUNC(sh2a_device::dma_sar0_r), FUNC(sh2a_device::dma_sar0_w)); - map(0x05ffff44, 0x05ffff47).rw(FUNC(sh2a_device::dma_dar0_r), FUNC(sh2a_device::dma_dar0_w)); - map(0x05ffff48, 0x05ffff49).rw(FUNC(sh2a_device::dmaor_r), FUNC(sh2a_device::dmaor_w)); - map(0x05ffff4a, 0x05ffff4b).rw(FUNC(sh2a_device::dma_tcr0_r), FUNC(sh2a_device::dma_tcr0_w)); - map(0x05ffff4e, 0x05ffff4f).rw(FUNC(sh2a_device::dma_chcr0_r), FUNC(sh2a_device::dma_chcr0_w)); -// map(0x07000000, 0x070003ff).ram().share("oram"); // on-chip RAM, actually at 0xf000000 (1 kb) -// map(0x0f000000, 0x0f0003ff).ram().share("oram"); // on-chip RAM, actually at 0xf000000 (1 kb) -} - -void sh1_device::sh7032_map(address_map &map) -{ -// fall-back - map(0x05fffe00, 0x05ffffff).rw(FUNC(sh1_device::sh7032_r), FUNC(sh1_device::sh7032_w)); // SH-7032H internal i/o -} - -sh2_device::sh2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : sh2_device(mconfig, SH2, tag, owner, clock, CPU_TYPE_SH2, address_map_constructor(FUNC(sh2_device::sh7604_map), this), 32) -{ -} - -sh2_device::~sh2_device() -{ -} - - -void sh2_device::device_stop() -{ -} - - - - -sh2_device::sh2_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int cpu_type, address_map_constructor internal_map, int addrlines) +sh2_device::sh2_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int cpu_type, address_map_constructor internal_map, int addrlines, uint32_t address_mask) : sh_common_execution(mconfig, type, tag, owner, clock, ENDIANNESS_BIG, internal_map) + , m_am(address_mask) , m_program_config("program", ENDIANNESS_BIG, 32, addrlines, 0, internal_map) , m_decrypted_program_config("decrypted_opcodes", ENDIANNESS_BIG, 32, addrlines, 0) - , m_is_slave(0) - , m_dma_kludge_cb(*this) - , m_dma_fifo_data_available_cb(*this) - , m_ftcsr_read_cb(*this) , m_drcfe(nullptr) - , m_debugger_temp(0) { m_cpu_type = cpu_type; - m_am = SH12_AM; m_isdrc = allow_drc(); } -sh2a_device::sh2a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : sh2_device(mconfig, SH2A, tag, owner, clock, CPU_TYPE_SH2, address_map_constructor(FUNC(sh2a_device::sh7021_map), this), 28) +void sh2_device::device_start() { - std::fill(std::begin(m_sh7021_regs), std::end(m_sh7021_regs), 0); + sh_common_execution::device_start(); + + m_decrypted_program = has_space(AS_OPCODES) ? &space(AS_OPCODES) : &space(AS_PROGRAM); + m_decrypted_program->cache(m_cache32); + m_pr16 = [this](offs_t address) -> u16 { return m_cache32.read_word(address); }; + if (m_decrypted_program->endianness() != ENDIANNESS_NATIVE) + m_prptr = [this](offs_t address) -> const void * { + const u16 *ptr = reinterpret_cast(m_cache32.read_ptr(address & ~3)); + if(!(address & 2)) + ptr++; + return ptr; + }; + else + m_prptr = [this](offs_t address) -> const void * { + const u16 *ptr = reinterpret_cast(m_cache32.read_ptr(address & ~3)); + if(address & 2) + ptr++; + return ptr; + }; + + // internals + save_item(NAME(m_cpu_off)); + save_item(NAME(m_test_irq)); + save_item(NAME(m_irq_line_state)); + save_item(NAME(m_nmi_line_state)); + save_item(NAME(m_internal_irq_vector)); + + state_add( STATE_GENPC, "PC", m_sh2_state->pc).mask(m_am).callimport(); + state_add( STATE_GENPCBASE, "CURPC", m_sh2_state->pc ).callimport().noshow(); + + m_nmi_line_state = 0; + + drc_start(); } -sh1_device::sh1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : sh2_device(mconfig, SH1, tag, owner, clock, CPU_TYPE_SH1, address_map_constructor(FUNC(sh1_device::sh7032_map), this), 28) +void sh2_device::device_reset() { - std::fill(std::begin(m_sh7032_regs), std::end(m_sh7032_regs), 0); + std::fill(std::begin(m_sh2_state->r), std::end(m_sh2_state->r), 0); + std::fill(std::begin(m_irq_line_state), std::end(m_irq_line_state), 0); + + m_sh2_state->pc = m_sh2_state->pr = m_sh2_state->sr = m_sh2_state->gbr = m_sh2_state->vbr = m_sh2_state->mach = m_sh2_state->macl = 0; + m_sh2_state->evec = m_sh2_state->irqsr = 0; + m_sh2_state->ea = m_sh2_state->m_delay = 0; + m_sh2_state->pending_irq = 0; + m_sh2_state->sleep_mode = 0; + m_sh2_state->internal_irq_level = -1; + m_sh2_state->sr = SH_I; + m_sh2_state->pc = RL(0); + m_sh2_state->r[15] = RL(4); + + m_test_irq = 0; + m_cpu_off = 0; + m_internal_irq_vector = 0; + m_cache_dirty = true; } device_memory_interface::space_config_vector sh2_device::memory_space_config() const @@ -298,7 +138,7 @@ std::unique_ptr sh2_device::create_disassembler() uint8_t sh2_device::RB(offs_t A) { if((A & 0xf0000000) == 0 || (A & 0xf0000000) == 0x20000000) - return m_program->read_byte(A & SH12_AM); + return m_program->read_byte(A & m_am); return m_program->read_byte(A); } @@ -306,7 +146,7 @@ uint8_t sh2_device::RB(offs_t A) uint16_t sh2_device::RW(offs_t A) { if((A & 0xf0000000) == 0 || (A & 0xf0000000) == 0x20000000) - return m_program->read_word(A & SH12_AM); + return m_program->read_word(A & m_am); return m_program->read_word(A); } @@ -316,7 +156,7 @@ uint32_t sh2_device::RL(offs_t A) /* 0x20000000 no Cache */ /* 0x00000000 read thru Cache if CE bit is 1 */ if((A & 0xf0000000) == 0 || (A & 0xf0000000) == 0x20000000) - return m_program->read_dword(A & SH12_AM); + return m_program->read_dword(A & m_am); return m_program->read_dword(A); } @@ -325,7 +165,7 @@ void sh2_device::WB(offs_t A, uint8_t V) { if((A & 0xf0000000) == 0 || (A & 0xf0000000) == 0x20000000) { - m_program->write_byte(A & SH12_AM,V); + m_program->write_byte(A & m_am,V); return; } @@ -336,7 +176,7 @@ void sh2_device::WW(offs_t A, uint16_t V) { if((A & 0xf0000000) == 0 || (A & 0xf0000000) == 0x20000000) { - m_program->write_word(A & SH12_AM,V); + m_program->write_word(A & m_am,V); return; } @@ -347,7 +187,7 @@ void sh2_device::WL(offs_t A, uint32_t V) { if((A & 0xf0000000) == 0 || (A & 0xf0000000) == 0x20000000) { - m_program->write_dword(A & SH12_AM,V); + m_program->write_dword(A & m_am,V); return; } @@ -426,48 +266,11 @@ inline void sh2_device::ILLEGAL() m_sh2_state->icount -= 5; } -/***************************************************************************** - * OPCODE DISPATCHERS - *****************************************************************************/ - - void sh2_device::execute_one_f000(uint16_t opcode) { ILLEGAL(); } -/***************************************************************************** - * MAME CPU INTERFACE - *****************************************************************************/ - -void sh2_device::device_reset() -{ - m_sh2_state->pc = m_sh2_state->pr = m_sh2_state->sr = m_sh2_state->gbr = m_sh2_state->vbr = m_sh2_state->mach = m_sh2_state->macl = 0; - m_sh2_state->evec = m_sh2_state->irqsr = 0; - memset(&m_sh2_state->r[0], 0, sizeof(m_sh2_state->r[0])*16); - m_sh2_state->ea = m_sh2_state->m_delay = m_cpu_off = 0; - //m_dvsr = m_dvdnth = m_dvdntl = m_dvcr = 0; - m_sh2_state->pending_irq = m_test_irq = 0; - //memset(&m_irq_queue[0], 0, sizeof(m_irq_queue[0])*16); - memset(&m_irq_line_state[0], 0, sizeof(m_irq_line_state[0])*17); - m_frc = m_ocra = m_ocrb = m_frc_icr = 0; - m_frc_base = 0; - m_frt_input = m_sh2_state->internal_irq_level = m_internal_irq_vector = 0; - m_dma_timer_active[0] = m_dma_timer_active[1] = 0; - m_dma_irq[0] = m_dma_irq[1] = 0; - - m_sh2_state->pc = RL(0); - m_sh2_state->r[15] = RL(4); - m_sh2_state->sr = SH_I; - m_sh2_state->sleep_mode = 0; - - m_sh2_state->internal_irq_level = -1; - - m_cache_dirty = true; -} - - -/* Execute cycles - returns number of cycles actually run */ void sh2_device::execute_run() { if ( m_isdrc ) @@ -486,7 +289,7 @@ void sh2_device::execute_run() { debugger_instruction_hook(m_sh2_state->pc); - const uint16_t opcode = m_decrypted_program->read_word(m_sh2_state->pc >= 0x40000000 ? m_sh2_state->pc : m_sh2_state->pc & SH12_AM); + const uint16_t opcode = m_decrypted_program->read_word(m_sh2_state->pc >= 0x40000000 ? m_sh2_state->pc : m_sh2_state->pc & m_am); if (m_sh2_state->m_delay) { @@ -507,197 +310,11 @@ void sh2_device::execute_run() } while( m_sh2_state->icount > 0 ); } - void sh2_device::init_drc_frontend() { m_drcfe = std::make_unique(this, COMPILE_BACKWARDS_BYTES, COMPILE_FORWARDS_BYTES, SINGLE_INSTRUCTION_MODE ? 1 : COMPILE_MAX_SEQUENCE); } -void sh2_device::device_start() -{ - sh_common_execution::device_start(); - - m_timer = timer_alloc(FUNC(sh2_device::sh2_timer_callback), this); - m_timer->adjust(attotime::never); - m_wdtimer = timer_alloc(FUNC(sh2_device::sh2_wdtimer_callback), this); - m_wdtimer->adjust(attotime::never); - - m_dma_current_active_timer[0] = timer_alloc(FUNC(sh2_device::sh2_dma_current_active_callback), this); - m_dma_current_active_timer[0]->adjust(attotime::never); - - m_dma_current_active_timer[1] = timer_alloc(FUNC(sh2_device::sh2_dma_current_active_callback), this); - m_dma_current_active_timer[1]->adjust(attotime::never); - - /* resolve callbacks */ - m_dma_kludge_cb.resolve(); - m_dma_fifo_data_available_cb.resolve(); - m_ftcsr_read_cb.resolve(); - - m_decrypted_program = has_space(AS_OPCODES) ? &space(AS_OPCODES) : &space(AS_PROGRAM); - m_decrypted_program->cache(m_cache32); - m_pr16 = [this](offs_t address) -> u16 { return m_cache32.read_word(address); }; - if (m_decrypted_program->endianness() != ENDIANNESS_NATIVE) - m_prptr = [this](offs_t address) -> const void * { - const u16 *ptr = static_cast(m_cache32.read_ptr(address & ~3)); - if(!(address & 2)) - ptr++; - return ptr; - }; - else - m_prptr = [this](offs_t address) -> const void * { - const u16 *ptr = static_cast(m_cache32.read_ptr(address & ~3)); - if(address & 2) - ptr++; - return ptr; - }; - - m_internal = &space(AS_PROGRAM); - - // SCI - save_item(NAME(m_smr)); - save_item(NAME(m_brr)); - save_item(NAME(m_scr)); - save_item(NAME(m_tdr)); - save_item(NAME(m_ssr)); - - // FRT / FRC - save_item(NAME(m_tier)); - save_item(NAME(m_ftcsr)); - save_item(NAME(m_frc_tcr)); - save_item(NAME(m_tocr)); - save_item(NAME(m_frc)); - save_item(NAME(m_ocra)); - save_item(NAME(m_ocrb)); - save_item(NAME(m_frc_icr)); - save_item(NAME(m_frc_base)); - save_item(NAME(m_frt_input)); - - // INTC - save_item(NAME(m_irq_level.frc)); - save_item(NAME(m_irq_level.sci)); - save_item(NAME(m_irq_level.divu)); - save_item(NAME(m_irq_level.dmac)); - save_item(NAME(m_irq_level.wdt)); - save_item(NAME(m_irq_vector.fic)); - save_item(NAME(m_irq_vector.foc)); - save_item(NAME(m_irq_vector.fov)); - save_item(NAME(m_irq_vector.divu)); - save_item(NAME(m_irq_vector.dmac[0])); - save_item(NAME(m_irq_vector.dmac[1])); - - save_item(NAME(m_ipra)); - save_item(NAME(m_iprb)); - save_item(NAME(m_vcra)); - save_item(NAME(m_vcrb)); - save_item(NAME(m_vcrc)); - save_item(NAME(m_vcrd)); - save_item(NAME(m_vcrwdt)); - save_item(NAME(m_vcrdiv)); - save_item(NAME(m_intc_icr)); - save_item(NAME(m_vcrdma[0])); - save_item(NAME(m_vcrdma[1])); - - save_item(NAME(m_vecmd)); - save_item(NAME(m_nmie)); - - // DIVU - save_item(NAME(m_divu_ovf)); - save_item(NAME(m_divu_ovfie)); - save_item(NAME(m_dvsr)); - save_item(NAME(m_dvdntl)); - save_item(NAME(m_dvdnth)); - - // WTC - save_item(NAME(m_wtcnt)); - save_item(NAME(m_wtcsr)); - save_item(NAME(m_rstcsr)); - save_item(NAME(m_wtcw[0])); - save_item(NAME(m_wtcw[1])); - - // DMAC - save_item(NAME(m_dmaor)); - save_item(NAME(m_dmac[0].drcr)); - save_item(NAME(m_dmac[1].drcr)); - save_item(NAME(m_dmac[0].sar)); - save_item(NAME(m_dmac[1].sar)); - save_item(NAME(m_dmac[0].dar)); - save_item(NAME(m_dmac[1].dar)); - save_item(NAME(m_dmac[0].tcr)); - save_item(NAME(m_dmac[1].tcr)); - save_item(NAME(m_dmac[0].chcr)); - save_item(NAME(m_dmac[1].chcr)); - - // misc - save_item(NAME(m_sbycr)); - save_item(NAME(m_ccr)); - - // BSC - save_item(NAME(m_bcr1)); - save_item(NAME(m_bcr2)); - save_item(NAME(m_wcr)); - save_item(NAME(m_mcr)); - save_item(NAME(m_rtcsr)); - save_item(NAME(m_rtcor)); - save_item(NAME(m_rtcnt)); - - /* - for (int i = 0; i < 16; ++i) - { - save_item(NAME(m_irq_queue[i].irq_vector), i); - save_item(NAME(m_irq_queue[i].irq_priority), i); - } - */ - - // internals - save_item(NAME(m_cpu_off)); - save_item(NAME(m_test_irq)); - save_item(NAME(m_irq_line_state)); - save_item(NAME(m_nmi_line_state)); - save_item(NAME(m_internal_irq_vector)); - save_item(NAME(m_dma_timer_active)); - save_item(NAME(m_dma_irq)); - - state_add( STATE_GENPC, "PC", m_sh2_state->pc).mask(SH12_AM).callimport(); - state_add( STATE_GENPCBASE, "CURPC", m_sh2_state->pc ).callimport().noshow(); - - // Clear state - m_cpu_off = 0; - //m_dvsr = 0; - //m_dvdnth = 0; - //m_dvdntl = 0; - //m_dvcr = 0; - m_test_irq = 0; - - memset(m_irq_line_state, 0, sizeof(m_irq_line_state)); - - m_nmi_line_state = 0; - m_frc = 0; - m_ocra = 0; - m_ocrb = 0; - m_frc_icr = 0; - m_frc_base = 0; - m_frt_input = 0; - m_internal_irq_vector = 0; - - for ( int i = 0; i < 2; i++ ) - { - m_dma_timer_active[i] = 0; - m_dma_irq[i] = 0; - m_active_dma_incs[i] = 0; - m_active_dma_incd[i] = 0; - m_active_dma_size[i] = 0; - m_active_dma_steal[i] = 0; - m_active_dma_src[i] = 0; - m_active_dma_dst[i] = 0; - m_active_dma_count[i] = 0; - } - m_wtcnt = 0; - m_wtcsr = 0; - - drc_start(); -} - - void sh2_device::state_string_export(const device_state_entry &entry, std::string &str) const { switch (entry.index()) @@ -713,7 +330,6 @@ void sh2_device::state_string_export(const device_state_entry &entry, std::strin } } - void sh2_device::state_import(const device_state_entry &entry) { switch (entry.index()) @@ -729,7 +345,6 @@ void sh2_device::state_import(const device_state_entry &entry) } } - void sh2_device::execute_set_input(int irqline, int state) { if (irqline == INPUT_LINE_NMI) @@ -782,6 +397,7 @@ void sh2_device::execute_set_input(int irqline, int state) void sh2_device::sh2_exception(const char *message, int irqline) { + // override this at the individual CPU level when special logic is required int vector; if (irqline != 16) @@ -799,17 +415,9 @@ void sh2_device::sh2_exception(const char *message, int irqline) } else { - if(m_vecmd == true) - { - vector = standard_irq_callback(irqline, m_sh2_state->pc); - LOG("SH-2 exception #%d (external vector: $%x) after [%s]\n", irqline, vector, message); - } - else - { - standard_irq_callback(irqline, m_sh2_state->pc); - vector = 64 + irqline/2; - LOG("SH-2 exception #%d (autovector: $%x) after [%s]\n", irqline, vector, message); - } + standard_irq_callback(irqline, m_sh2_state->pc); + vector = 64 + irqline/2; + LOG("SH-2 exception #%d (autovector: $%x) after [%s]\n", irqline, vector, message); } } else @@ -817,12 +425,18 @@ void sh2_device::sh2_exception(const char *message, int irqline) vector = 11; LOG("SH-2 nmi exception (autovector: $%x) after [%s]\n", vector, message); } + + sh2_exception_internal(message, irqline, vector); +} + +void sh2_device::sh2_exception_internal(const char *message, int irqline, int vector) +{ debugger_exception_hook(vector); if (m_isdrc) { m_sh2_state->evec = RL( m_sh2_state->vbr + vector * 4 ); - m_sh2_state->evec &= SH12_AM; + m_sh2_state->evec &= m_am; m_sh2_state->irqsr = m_sh2_state->sr; /* set I flags in SR */ @@ -851,39 +465,25 @@ void sh2_device::sh2_exception(const char *message, int irqline) if(m_sh2_state->sleep_mode == 1) { m_sh2_state->sleep_mode = 2; } } -// license:BSD-3-Clause -// copyright-holders:R. Belmont -/*************************************************************************** - - sh2drc.c - Universal machine language-based SH-2 emulator. - -***************************************************************************/ - -#include "emu.h" -#include "sh2.h" -#include "sh2comn.h" -#include "cpu/drcumlsh.h" - +///////// +// DRC const opcode_desc* sh2_device::get_desclist(offs_t pc) { return m_drcfe->describe_code(pc); } - - -/*------------------------------------------------- - static_generate_entry_point - generate a - static entry point --------------------------------------------------*/ - void sh2_device::func_fastirq() { sh2_exception("fastirq",m_sh2_state->irqline); } static void cfunc_fastirq(void *param) { ((sh2_device *)param)->func_fastirq(); }; +/*------------------------------------------------- + static_generate_entry_point - generate a + static entry point +-------------------------------------------------*/ + void sh2_device::static_generate_entry_point() { uml::code_label const skip = 1; @@ -1063,7 +663,7 @@ void sh2_device::static_generate_memory_accessor(int size, int iswrite, const ch UML_CMP(block, I0, 0x40000000); // cmp #0x40000000, r0 UML_JMPc(block, COND_AE, label); // bae label - UML_AND(block, I0, I0, SH12_AM); // and r0, r0, #AM (0xc7ffffff) + UML_AND(block, I0, I0, m_am); // and r0, r0, #AM (0xc7ffffff) UML_LABEL(block, label++); // label: @@ -1167,5 +767,3 @@ void sh2_device::static_generate_memory_accessor(int size, int iswrite, const ch block.end(); } - - diff --git a/src/devices/cpu/sh/sh2.h b/src/devices/cpu/sh/sh2.h index c0ba7340d8b..2acd63094a9 100644 --- a/src/devices/cpu/sh/sh2.h +++ b/src/devices/cpu/sh/sh2.h @@ -12,37 +12,13 @@ * *****************************************************************************/ -#ifndef MAME_CPU_SH2_SH2_H -#define MAME_CPU_SH2_SH2_H +#ifndef MAME_CPU_SH_SH2_H +#define MAME_CPU_SH_SH2_H #pragma once - #include "sh.h" -#define SH2_INT_NONE -1 -#define SH2_INT_VBLIN 0 -#define SH2_INT_VBLOUT 1 -#define SH2_INT_HBLIN 2 -#define SH2_INT_TIMER0 3 -#define SH2_INT_TIMER1 4 -#define SH2_INT_DSP 5 -#define SH2_INT_SOUND 6 -#define SH2_INT_SMPC 7 -#define SH2_INT_PAD 8 -#define SH2_INT_DMA2 9 -#define SH2_INT_DMA1 10 -#define SH2_INT_DMA0 11 -#define SH2_INT_DMAILL 12 -#define SH2_INT_SPRITE 13 -#define SH2_INT_14 14 -#define SH2_INT_15 15 -#define SH2_INT_ABUS 16 - -#define SH2_DMA_KLUDGE_CB(name) int name(uint32_t src, uint32_t dst, uint32_t data, int size) -#define SH2_DMA_FIFO_DATA_AVAILABLE_CB(name) int name(uint32_t src, uint32_t dst, uint32_t data, int size) -#define SH2_FTCSR_READ_CB(name) void name(uint32_t data) - class sh2_frontend; class sh2_device : public sh_common_execution @@ -50,169 +26,16 @@ class sh2_device : public sh_common_execution friend class sh2_frontend; public: - typedef device_delegate dma_kludge_delegate; - typedef device_delegate dma_fifo_data_available_delegate; - typedef device_delegate ftcsr_read_delegate; + void set_frt_input(int state) override {} // not every CPU needs this, let the ones that do override it - // construction/destruction - sh2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - virtual ~sh2_device() override; + void func_fastirq(); // required for DRC, needs to be public to be accessible through non-classed static trampoline function - void set_is_slave(int slave) { m_is_slave = slave; } - - template void set_dma_kludge_callback(T &&... args) { m_dma_kludge_cb.set(std::forward(args)...); } - - template void set_dma_fifo_data_available_callback(T &&... args) { m_dma_fifo_data_available_cb.set(std::forward(args)...); } - - template void set_ftcsr_read_callback(T &&... args) { m_ftcsr_read_cb.set(std::forward(args)...); } - - uint32_t sh2_internal_a5(); - - // SCI - uint8_t smr_r(); - void smr_w(uint8_t data); - uint8_t brr_r(); - void brr_w(uint8_t data); - uint8_t scr_r(); - void scr_w(uint8_t data); - uint8_t tdr_r(); - void tdr_w(uint8_t data); - uint8_t ssr_r(); - void ssr_w(uint8_t data); - uint8_t rdr_r(); - - // FRT / FRC - uint8_t tier_r(); - void tier_w(uint8_t data); - uint16_t frc_r(); - void frc_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - uint8_t ftcsr_r(); - void ftcsr_w(uint8_t data); - uint16_t ocra_b_r(); - void ocra_b_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - uint8_t frc_tcr_r(); - void frc_tcr_w(uint8_t data); - uint8_t tocr_r(); - void tocr_w(uint8_t data); - uint16_t frc_icr_r(); - - // INTC - uint16_t ipra_r(); - void ipra_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - uint16_t iprb_r(); - void iprb_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - uint16_t vcra_r(); - void vcra_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - uint16_t vcrb_r(); - void vcrb_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - uint16_t vcrc_r(); - void vcrc_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - uint16_t vcrd_r(); - void vcrd_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - uint16_t vcrwdt_r(); - void vcrwdt_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - uint32_t vcrdiv_r(); - void vcrdiv_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); - uint16_t intc_icr_r(); - void intc_icr_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - - // DIVU - uint32_t dvsr_r(); - void dvsr_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); - uint32_t dvdnt_r(); - void dvdnt_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); - uint32_t dvdnth_r(); - void dvdnth_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); - uint32_t dvdntl_r(); - void dvdntl_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); - - uint32_t dvcr_r(); - void dvcr_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); - - // DMAC - template uint32_t vcrdma_r() - { - return m_vcrdma[Channel] & 0x7f; - } - - template void vcrdma_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0) - { - COMBINE_DATA(&m_vcrdma[Channel]); - m_irq_vector.dmac[Channel] = m_vcrdma[Channel] & 0x7f; - sh2_recalc_irq(); - } - - template uint8_t drcr_r() { return m_dmac[Channel].drcr & 3; } - template void drcr_w(uint8_t data) { m_dmac[Channel].drcr = data & 3; sh2_recalc_irq(); } - template uint32_t sar_r() { return m_dmac[Channel].sar; } - template void sar_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0) { COMBINE_DATA(&m_dmac[Channel].sar); } - template uint32_t dar_r() { return m_dmac[Channel].dar; } - template void dar_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0) { COMBINE_DATA(&m_dmac[Channel].dar); } - template uint32_t dmac_tcr_r() { return m_dmac[Channel].tcr; } - template void dmac_tcr_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0) { COMBINE_DATA(&m_dmac[Channel].tcr); m_dmac[Channel].tcr &= 0xffffff; } - template uint32_t chcr_r() { return m_dmac[Channel].chcr; } - template void chcr_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0) - { - uint32_t old; - old = m_dmac[Channel].chcr; - COMBINE_DATA(&m_dmac[Channel].chcr); - m_dmac[Channel].chcr = (data & ~2) | (old & m_dmac[Channel].chcr & 2); - sh2_dmac_check(Channel); - } - uint32_t dmaor_r() { return m_dmaor & 0xf; } - void dmaor_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0) - { - if(ACCESSING_BITS_0_7) - { - uint8_t old; - old = m_dmaor & 0xf; - m_dmaor = (data & ~6) | (old & m_dmaor & 6); - sh2_dmac_check(0); - sh2_dmac_check(1); - } - } - - // WTC - uint16_t wtcnt_r(); - void wtcnt_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - uint16_t rstcsr_r(); - void rstcsr_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - - // misc - uint16_t fmr_sbycr_r(); - void fmr_sbycr_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - uint8_t ccr_r(); - void ccr_w(uint8_t data); - - // BSC - uint32_t bcr1_r(); - void bcr1_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); - uint32_t bcr2_r(); - void bcr2_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); - uint32_t wcr_r(); - void wcr_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); - uint32_t mcr_r(); - void mcr_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); - uint32_t rtcsr_r(); - void rtcsr_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); - uint32_t rtcor_r(); - void rtcor_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); - uint32_t rtcnt_r(); - void rtcnt_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); - - - virtual void set_frt_input(int state) override; - void sh2_notify_dma_data_available(); - void func_fastirq(); - - void sh7604_map(address_map &map); protected: - sh2_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int cpu_type,address_map_constructor internal_map, int addrlines); + sh2_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int cpu_type, address_map_constructor internal_map, int addrlines, uint32_t address_mask); // device-level overrides virtual void device_start() override; virtual void device_reset() override; - virtual void device_stop() override; // device_execute_interface overrides virtual uint32_t execute_min_cycles() const noexcept override { return 1; } @@ -233,99 +56,17 @@ protected: // device_disasm_interface overrides virtual std::unique_ptr create_disassembler() override; + virtual void sh2_exception(const char *message, int irqline) override; + virtual void sh2_exception_internal(const char *message, int irqline, int vector); + address_space *m_decrypted_program; + const uint32_t m_am; + + uint32_t m_test_irq; + int32_t m_internal_irq_vector; + int8_t m_nmi_line_state; private: - address_space_config m_program_config, m_decrypted_program_config; - - uint32_t m_cpu_off = 0; - uint32_t m_test_irq = 0; - - int8_t m_irq_line_state[17]; - - address_space *m_internal; - - - // SCI - uint8_t m_smr = 0, m_brr = 0, m_scr = 0, m_tdr = 0, m_ssr = 0; - // FRT / FRC - uint8_t m_tier = 0, m_ftcsr = 0, m_frc_tcr = 0, m_tocr = 0; - uint16_t m_frc = 0; - uint16_t m_ocra = 0, m_ocrb = 0, m_frc_icr = 0; - // INTC - struct { - uint8_t frc = 0; - uint8_t sci = 0; - uint8_t divu = 0; - uint8_t dmac = 0; - uint8_t wdt = 0; - } m_irq_level; - struct { - uint8_t fic = 0; - uint8_t foc = 0; - uint8_t fov = 0; - uint8_t divu = 0; - uint8_t dmac[2] = { 0, 0 }; - } m_irq_vector; - uint16_t m_ipra = 0, m_iprb = 0; - uint16_t m_vcra = 0, m_vcrb = 0, m_vcrc = 0, m_vcrd = 0, m_vcrwdt = 0, m_vcrdiv = 0, m_intc_icr = 0, m_vcrdma[2] = { 0, 0, }; - bool m_vecmd = false, m_nmie = false; - - // DIVU - bool m_divu_ovf = false, m_divu_ovfie = false; - uint32_t m_dvsr = 0, m_dvdntl = 0, m_dvdnth = 0; - - // WTC - uint8_t m_wtcnt = 0, m_wtcsr = 0; - uint8_t m_rstcsr = 0; - uint16_t m_wtcw[2] = { 0, 0 }; - - // DMAC - struct { - uint8_t drcr = 0; - uint32_t sar = 0; - uint32_t dar = 0; - uint32_t tcr = 0; - uint32_t chcr = 0; - } m_dmac[2]; - uint8_t m_dmaor = 0; - - // misc - uint8_t m_sbycr = 0, m_ccr = 0; - - // BSC - uint32_t m_bcr1 = 0, m_bcr2 = 0, m_wcr = 0, m_mcr = 0, m_rtcsr = 0, m_rtcor = 0, m_rtcnt = 0; - - int8_t m_nmi_line_state = 0; - - uint64_t m_frc_base = 0; - - int m_frt_input = 0; - int m_internal_irq_vector = 0; - - emu_timer *m_timer = nullptr; - emu_timer *m_wdtimer = nullptr; - emu_timer *m_dma_current_active_timer[2] { nullptr, nullptr }; - int m_dma_timer_active[2] = { 0, 0 }; - uint8_t m_dma_irq[2] = { 0, 0 }; - - int m_active_dma_incs[2] = { 0, 0 }; - int m_active_dma_incd[2] = { 0, 0 }; - int m_active_dma_size[2] = { 0, 0 }; - int m_active_dma_steal[2] = { 0, 0 }; - uint32_t m_active_dma_src[2] = { 0, 0 }; - uint32_t m_active_dma_dst[2] = { 0, 0 }; - uint32_t m_active_dma_count[2] = { 0, 0 }; - - int m_is_slave = 0; - dma_kludge_delegate m_dma_kludge_cb; - dma_fifo_data_available_delegate m_dma_fifo_data_available_cb; - ftcsr_read_delegate m_ftcsr_read_cb; - - std::unique_ptr m_drcfe; /* pointer to the DRC front-end state */ - - uint32_t m_debugger_temp = 0; - virtual uint8_t RB(offs_t A) override; virtual uint16_t RW(offs_t A) override; virtual uint32_t RL(offs_t A) override; @@ -341,18 +82,6 @@ private: virtual void execute_one_f000(uint16_t opcode) override; - TIMER_CALLBACK_MEMBER( sh2_timer_callback ); - TIMER_CALLBACK_MEMBER( sh2_wdtimer_callback ); - TIMER_CALLBACK_MEMBER( sh2_dma_current_active_callback ); - void sh2_timer_resync(); - void sh2_timer_activate(); - void sh2_wtcnt_recalc(); - void sh2_wdt_activate(); - void sh2_do_dma(int dmach); - virtual void sh2_exception(const char *message, int irqline) override; - void sh2_dmac_check(int dma); - void sh2_recalc_irq(); - virtual void init_drc_frontend() override; virtual const opcode_desc* get_desclist(offs_t pc) override; @@ -360,53 +89,12 @@ private: virtual void static_generate_entry_point() override; virtual void static_generate_memory_accessor(int size, int iswrite, const char *name, uml::code_handle *&handleptr) override; -}; + address_space_config m_program_config, m_decrypted_program_config; -class sh2a_device : public sh2_device -{ -public: - // construction/destruction - sh2a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + std::unique_ptr m_drcfe; /* pointer to the DRC front-end state */ - uint32_t dma_sar0_r(); - void dma_sar0_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); - uint32_t dma_dar0_r(); - void dma_dar0_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); - uint16_t dmaor_r(); - void dmaor_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - uint16_t dma_tcr0_r(); - void dma_tcr0_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - uint16_t dma_chcr0_r(); - void dma_chcr0_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - uint16_t sh7021_r(offs_t offset); - void sh7021_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - void sh7032_dma_exec(int ch); - - void sh7021_map(address_map &map); -private: - uint16_t m_sh7021_regs[0x200]; - struct - { - uint32_t sar = 0; /**< Source Address Register */ - uint32_t dar = 0; /**< Destination Address Register */ - uint16_t tcr = 0; /**< Transfer Count Register */ - uint16_t chcr = 0; /**< Channel Control Register */ - } m_dma[4]; - uint16_t m_dmaor = 0; /**< DMA Operation Register (status flags) */ - -}; - -class sh1_device : public sh2_device -{ -public: - // construction/destruction - sh1_device(const machine_config &mconfig, const char *_tag, device_t *_owner, uint32_t _clock); - - uint16_t sh7032_r(offs_t offset); - void sh7032_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - void sh7032_map(address_map &map); -private: - uint16_t m_sh7032_regs[0x200]; + uint32_t m_cpu_off; + int8_t m_irq_line_state[17]; }; @@ -421,8 +109,4 @@ private: virtual bool describe_group_15(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode) override; }; -DECLARE_DEVICE_TYPE(SH1, sh1_device) -DECLARE_DEVICE_TYPE(SH2, sh2_device) -DECLARE_DEVICE_TYPE(SH2A, sh2a_device) - -#endif // MAME_CPU_SH2_SH2_H +#endif // MAME_CPU_SH_SH2_H diff --git a/src/devices/cpu/sh/sh2comn.cpp b/src/devices/cpu/sh/sh2comn.cpp deleted file mode 100644 index 89f37d54635..00000000000 --- a/src/devices/cpu/sh/sh2comn.cpp +++ /dev/null @@ -1,1253 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:R. Belmont -/***************************************************************************** - * - * sh2common.c - * - * SH-2 non-specific components - * - *****************************************************************************/ - -#include "emu.h" -#include "sh2.h" -#include "sh2comn.h" - -//#define VERBOSE 1 -#include "logmacro.h" - -static const int div_tab[4] = { 3, 5, 7, 0 }; -static const int wdtclk_tab[8] = { 1, 6, 7, 8, 9, 10, 12, 13 }; - - -void sh2_device::sh2_timer_resync() -{ - // TODO: setting 3 is "External clock: count on rising edge" - int divider = div_tab[m_frc_tcr & 3]; - uint64_t cur_time = total_cycles(); - uint64_t add = (cur_time - m_frc_base) >> divider; - - if (add > 0) - { - if(divider) - m_frc += add; - - m_frc_base = cur_time; - } -} - -void sh2_device::sh2_timer_activate() -{ - int max_delta = 0xfffff; - uint16_t frc; - - m_timer->adjust(attotime::never); - - frc = m_frc; - if(!(m_ftcsr & OCFA)) { - uint16_t delta = m_ocra - frc; - if(delta < max_delta) - max_delta = delta; - } - - if(!(m_ftcsr & OCFB) && (m_ocra <= m_ocrb || !(m_ftcsr & CCLRA))) { - uint16_t delta = m_ocrb - frc; - if(delta < max_delta) - max_delta = delta; - } - - if(!(m_ftcsr & OVF) && !(m_ftcsr & CCLRA)) { - int delta = 0x10000 - frc; - if(delta < max_delta) - max_delta = delta; - } - - if(max_delta != 0xfffff) { - int divider = div_tab[m_frc_tcr & 3]; - if(divider) { - max_delta <<= divider; - m_frc_base = total_cycles(); - m_timer->adjust(cycles_to_attotime(max_delta)); - } else { - logerror("SH2.%s: Timer event in %d cycles of external clock", tag(), max_delta); - } - } -} - -TIMER_CALLBACK_MEMBER( sh2_device::sh2_timer_callback ) -{ - uint16_t frc; - - sh2_timer_resync(); - - frc = m_frc; - - if(frc == m_ocrb) - m_ftcsr |= OCFB; - - if(frc == 0x0000) - m_ftcsr |= OVF; - - if(frc == m_ocra) - { - m_ftcsr |= OCFA; - - if(m_ftcsr & CCLRA) - m_frc = 0; - } - - sh2_recalc_irq(); - sh2_timer_activate(); -} - -void sh2_device::sh2_wtcnt_recalc() -{ - if (m_wdtimer->expire() != attotime::never) - m_wtcnt = 0x100 - (attotime_to_cycles(m_wdtimer->remaining()) >> wdtclk_tab[m_wtcsr & 7]); -} - -void sh2_device::sh2_wdt_activate() -{ - m_wdtimer->adjust(cycles_to_attotime((0x100 - m_wtcnt) << wdtclk_tab[m_wtcsr & 7])); -} - -TIMER_CALLBACK_MEMBER(sh2_device::sh2_wdtimer_callback) -{ - m_wtcnt = 0; - if (!(m_wtcsr & 0x40)) // timer mode - { - m_wtcsr |= 0x80; - sh2_recalc_irq(); - sh2_wdt_activate(); - } - else // watchdog mode - { - m_rstcsr |= 0x80; - // TODO reset and /WDTOVF out - } -} - -/* - We have to do DMA on a timer (or at least, in chunks) due to the way some systems use it. - The 32x is a difficult case, they set the SOURCE of the DMA to a FIFO buffer, which at most - can have 8 words in it. Attempting to do an 'instant DMA' in this scenario is impossible - because the game is expecting the 68k of the system to feed data into the FIFO at the same - time as the SH2 is transfering it out via DMA - - There are two ways we can do this - - a) with a high frequency timer (more accurate, but a large performance hit) - - or - - b) in the CPU_EXECUTE loop - - - we're currently doing a) - - b) causes problems with ST-V games - -*/ - - - -void sh2_device::sh2_notify_dma_data_available() -{ - //printf("call notify\n"); - - for (int dmach=0;dmach<2;dmach++) - { - //printf("m_dma_timer_active[dmach] %04x\n",m_dma_timer_active[dmach]); - - if (m_dma_timer_active[dmach]==2) // 2 = stalled - { - // printf("resuming stalled dma\n"); - m_dma_timer_active[dmach]=1; - m_dma_current_active_timer[dmach]->adjust(attotime::zero, dmach); - } - } - -} - -void sh2_device::sh2_do_dma(int dmach) -{ - uint32_t dmadata; - - uint32_t tempsrc, tempdst; - - if (m_active_dma_count[dmach] > 0) - { - // process current DMA - switch(m_active_dma_size[dmach]) - { - case 0: - { - // we need to know the src / dest ahead of time without changing them - // to allow for the callback to check if we can process the DMA at this - // time (we need to know where we're reading / writing to/from) - - if(m_active_dma_incs[dmach] == 2) - tempsrc = m_active_dma_src[dmach] - 1; - else - tempsrc = m_active_dma_src[dmach]; - - if(m_active_dma_incd[dmach] == 2) - tempdst = m_active_dma_dst[dmach] - 1; - else - tempdst = m_active_dma_dst[dmach]; - - if (!m_dma_fifo_data_available_cb.isnull()) - { - int available = m_dma_fifo_data_available_cb(tempsrc, tempdst, 0, m_active_dma_size[dmach]); - - if (!available) - { - //printf("dma stalled\n"); - m_dma_timer_active[dmach]=2;// mark as stalled - return; - } - } - - //schedule next DMA callback - m_dma_current_active_timer[dmach]->adjust(cycles_to_attotime(2), dmach); - - dmadata = m_program->read_byte(tempsrc); - if (!m_dma_kludge_cb.isnull()) dmadata = m_dma_kludge_cb(tempsrc, tempdst, dmadata, m_active_dma_size[dmach]); - m_program->write_byte(tempdst, dmadata); - - if(m_active_dma_incs[dmach] == 2) - m_active_dma_src[dmach] --; - if(m_active_dma_incd[dmach] == 2) - m_active_dma_dst[dmach] --; - - - if(m_active_dma_incs[dmach] == 1) - m_active_dma_src[dmach] ++; - if(m_active_dma_incd[dmach] == 1) - m_active_dma_dst[dmach] ++; - - m_active_dma_count[dmach] --; - } - break; - case 1: - { - if(m_active_dma_incs[dmach] == 2) - tempsrc = m_active_dma_src[dmach] - 2; - else - tempsrc = m_active_dma_src[dmach]; - - if(m_active_dma_incd[dmach] == 2) - tempdst = m_active_dma_dst[dmach] - 2; - else - tempdst = m_active_dma_dst[dmach]; - - if (!m_dma_fifo_data_available_cb.isnull()) - { - int available = m_dma_fifo_data_available_cb(tempsrc, tempdst, 0, m_active_dma_size[dmach]); - - if (!available) - { - //printf("dma stalled\n"); - m_dma_timer_active[dmach]=2;// mark as stalled - return; - } - } - - //schedule next DMA callback - m_dma_current_active_timer[dmach]->adjust(cycles_to_attotime(2), dmach); - - // check: should this really be using read_word_32 / write_word_32? - dmadata = m_program->read_word(tempsrc); - if (!m_dma_kludge_cb.isnull()) dmadata = m_dma_kludge_cb(tempsrc, tempdst, dmadata, m_active_dma_size[dmach]); - m_program->write_word(tempdst, dmadata); - - if(m_active_dma_incs[dmach] == 2) - m_active_dma_src[dmach] -= 2; - if(m_active_dma_incd[dmach] == 2) - m_active_dma_dst[dmach] -= 2; - - if(m_active_dma_incs[dmach] == 1) - m_active_dma_src[dmach] += 2; - if(m_active_dma_incd[dmach] == 1) - m_active_dma_dst[dmach] += 2; - - m_active_dma_count[dmach] --; - } - break; - case 2: - { - if(m_active_dma_incs[dmach] == 2) - tempsrc = m_active_dma_src[dmach] - 4; - else - tempsrc = m_active_dma_src[dmach]; - - if(m_active_dma_incd[dmach] == 2) - tempdst = m_active_dma_dst[dmach] - 4; - else - tempdst = m_active_dma_dst[dmach]; - - if (!m_dma_fifo_data_available_cb.isnull()) - { - int available = m_dma_fifo_data_available_cb(tempsrc, tempdst, 0, m_active_dma_size[dmach]); - - if (!available) - { - //printf("dma stalled\n"); - m_dma_timer_active[dmach]=2;// mark as stalled - return; - } - } - - //schedule next DMA callback - m_dma_current_active_timer[dmach]->adjust(cycles_to_attotime(2), dmach); - - dmadata = m_program->read_dword(tempsrc); - if (!m_dma_kludge_cb.isnull()) dmadata = m_dma_kludge_cb(tempsrc, tempdst, dmadata, m_active_dma_size[dmach]); - m_program->write_dword(tempdst, dmadata); - - if(m_active_dma_incs[dmach] == 2) - m_active_dma_src[dmach] -= 4; - if(m_active_dma_incd[dmach] == 2) - m_active_dma_dst[dmach] -= 4; - - if(m_active_dma_incs[dmach] == 1) - m_active_dma_src[dmach] += 4; - if(m_active_dma_incd[dmach] == 1) - m_active_dma_dst[dmach] += 4; - - m_active_dma_count[dmach] --; - } - break; - case 3: - { - // shouldn't this really be 4 calls here instead? - - tempsrc = m_active_dma_src[dmach]; - - if(m_active_dma_incd[dmach] == 2) - tempdst = m_active_dma_dst[dmach] - 16; - else - tempdst = m_active_dma_dst[dmach]; - - if (!m_dma_fifo_data_available_cb.isnull()) - { - int available = m_dma_fifo_data_available_cb(tempsrc, tempdst, 0, m_active_dma_size[dmach]); - - if (!available) - { - //printf("dma stalled\n"); - m_dma_timer_active[dmach]=2;// mark as stalled - fatalerror("SH2 dma_callback_fifo_data_available == 0 in unsupported mode\n"); - } - } - - //schedule next DMA callback - m_dma_current_active_timer[dmach]->adjust(cycles_to_attotime(2), dmach); - - dmadata = m_program->read_dword(tempsrc); - if (!m_dma_kludge_cb.isnull()) dmadata = m_dma_kludge_cb(tempsrc, tempdst, dmadata, m_active_dma_size[dmach]); - m_program->write_dword(tempdst, dmadata); - - dmadata = m_program->read_dword(tempsrc+4); - if (!m_dma_kludge_cb.isnull()) dmadata = m_dma_kludge_cb(tempsrc, tempdst, dmadata, m_active_dma_size[dmach]); - m_program->write_dword(tempdst+4, dmadata); - - dmadata = m_program->read_dword(tempsrc+8); - if (!m_dma_kludge_cb.isnull()) dmadata = m_dma_kludge_cb(tempsrc, tempdst, dmadata, m_active_dma_size[dmach]); - m_program->write_dword(tempdst+8, dmadata); - - dmadata = m_program->read_dword(tempsrc+12); - if (!m_dma_kludge_cb.isnull()) dmadata = m_dma_kludge_cb(tempsrc, tempdst, dmadata, m_active_dma_size[dmach]); - m_program->write_dword(tempdst+12, dmadata); - - if(m_active_dma_incd[dmach] == 2) - m_active_dma_dst[dmach] -= 16; - - m_active_dma_src[dmach] += 16; - if(m_active_dma_incd[dmach] == 1) - m_active_dma_dst[dmach] += 16; - - m_active_dma_count[dmach]-=4; - } - break; - } - } - else // the dma is complete - { - // int dma = param & 1; - - // fever soccer uses cycle-stealing mode, resume the CPU now DMA has finished - if (m_active_dma_steal[dmach]) - { - resume(SUSPEND_REASON_HALT ); - } - - - LOG("SH2: DMA %d complete\n", dmach); - m_dmac[dmach].tcr = 0; - m_dmac[dmach].chcr |= 2; - m_dma_timer_active[dmach] = 0; - m_dma_irq[dmach] |= 1; - sh2_recalc_irq(); - - } -} - -TIMER_CALLBACK_MEMBER( sh2_device::sh2_dma_current_active_callback ) -{ - int dma = param & 1; - - sh2_do_dma(dma); -} - - -void sh2_device::sh2_dmac_check(int dmach) -{ - if(m_dmac[dmach].chcr & m_dmaor & 1) - { - if(!m_dma_timer_active[dmach] && !(m_dmac[dmach].chcr & 2)) - { - m_active_dma_incd[dmach] = (m_dmac[dmach].chcr >> 14) & 3; - m_active_dma_incs[dmach] = (m_dmac[dmach].chcr >> 12) & 3; - m_active_dma_size[dmach] = (m_dmac[dmach].chcr >> 10) & 3; - m_active_dma_steal[dmach] = (m_dmac[dmach].chcr & 0x10); - - if(m_active_dma_incd[dmach] == 3 || m_active_dma_incs[dmach] == 3) - { - logerror("SH2: DMA: bad increment values (%d, %d, %d, %04x)\n", m_active_dma_incd[dmach], m_active_dma_incs[dmach], m_active_dma_size[dmach], m_dmac[dmach].chcr); - return; - } - m_active_dma_src[dmach] = m_dmac[dmach].sar; - m_active_dma_dst[dmach] = m_dmac[dmach].dar; - m_active_dma_count[dmach] = m_dmac[dmach].tcr; - if(!m_active_dma_count[dmach]) - m_active_dma_count[dmach] = 0x1000000; - - LOG("SH2: DMA %d start %x, %x, %x, %04x, %d, %d, %d\n", dmach, m_active_dma_src[dmach], m_active_dma_dst[dmach], m_active_dma_count[dmach], m_dmac[dmach].chcr, m_active_dma_incs[dmach], m_active_dma_incd[dmach], m_active_dma_size[dmach]); - - m_dma_timer_active[dmach] = 1; - - m_active_dma_src[dmach] &= SH12_AM; - m_active_dma_dst[dmach] &= SH12_AM; - - switch(m_active_dma_size[dmach]) - { - case 0: - break; - case 1: - m_active_dma_src[dmach] &= ~1; - m_active_dma_dst[dmach] &= ~1; - break; - case 2: - m_active_dma_src[dmach] &= ~3; - m_active_dma_dst[dmach] &= ~3; - break; - case 3: - m_active_dma_src[dmach] &= ~3; - m_active_dma_dst[dmach] &= ~3; - m_active_dma_count[dmach] &= ~3; - break; - } - - // start DMA timer - - // fever soccer uses cycle-stealing mode, requiring the CPU to be halted - if (m_active_dma_steal[dmach]) - { - //printf("cycle stealing DMA\n"); - suspend(SUSPEND_REASON_HALT, 1 ); - } - - m_dma_current_active_timer[dmach]->adjust(cycles_to_attotime(2), dmach); - } - } - else - { - if(m_dma_timer_active[dmach]) - { - logerror("SH2: DMA %d cancelled in-flight\n", dmach); - //m_dma_complete_timer[dmach]->adjust(attotime::never); - m_dma_current_active_timer[dmach]->adjust(attotime::never, dmach); - - m_dma_timer_active[dmach] = 0; - } - } -} - -/* - * SCI - */ -// TODO: identical to H8 counterpart - -uint8_t sh2_device::smr_r() -{ - return m_smr; -} - -void sh2_device::smr_w(uint8_t data) -{ - m_smr = data; -} - -uint8_t sh2_device::brr_r() -{ - return m_brr; -} - -void sh2_device::brr_w(uint8_t data) -{ - m_brr = data; -} - -uint8_t sh2_device::scr_r() -{ - return m_scr; -} - -void sh2_device::scr_w(uint8_t data) -{ - m_scr = data; -} - -uint8_t sh2_device::tdr_r() -{ - return m_tdr; -} - -void sh2_device::tdr_w(uint8_t data) -{ - m_tdr = data; - // printf("%c",data & 0xff); -} - -uint8_t sh2_device::ssr_r() -{ - // 0x84 is needed by EGWord on Saturn to make it to boot for some reason. - return m_ssr | 0x84; -} - -void sh2_device::ssr_w(uint8_t data) -{ - m_ssr = data; -} - -uint8_t sh2_device::rdr_r() -{ - return 0; -} - -/* - * FRC - */ - -uint8_t sh2_device::tier_r() -{ - return m_tier; -} - -void sh2_device::tier_w(uint8_t data) -{ - sh2_timer_resync(); - m_tier = data; - sh2_timer_activate(); - sh2_recalc_irq(); -} - -uint8_t sh2_device::ftcsr_r() -{ - // TODO: to be tested - if (!m_ftcsr_read_cb.isnull()) - m_ftcsr_read_cb((((m_tier<<24) | (m_ftcsr<<16)) & 0xffff0000) | m_frc); - - return m_ftcsr; -} - -void sh2_device::ftcsr_w(uint8_t data) -{ - uint8_t old; - old = m_ftcsr; - - m_ftcsr = data; - sh2_timer_resync(); - m_ftcsr = (m_ftcsr & ~(ICF|OCFA|OCFB|OVF)) | (old & m_ftcsr & (ICF|OCFA|OCFB|OVF)); - sh2_timer_activate(); - sh2_recalc_irq(); -} - -uint16_t sh2_device::frc_r() -{ - sh2_timer_resync(); - return m_frc; -} - -void sh2_device::frc_w(offs_t offset, uint16_t data, uint16_t mem_mask) -{ - sh2_timer_resync(); - COMBINE_DATA(&m_frc); - sh2_timer_activate(); - sh2_recalc_irq(); -} - -uint16_t sh2_device::ocra_b_r() -{ - return (m_tocr & 0x10) ? m_ocrb : m_ocra; -} - -void sh2_device::ocra_b_w(offs_t offset, uint16_t data, uint16_t mem_mask) -{ - sh2_timer_resync(); - if(m_tocr & 0x10) - m_ocrb = (m_ocrb & (~mem_mask)) | (data & mem_mask); - else - m_ocra = (m_ocra & (~mem_mask)) | (data & mem_mask); - sh2_timer_activate(); - sh2_recalc_irq(); -} - -uint8_t sh2_device::frc_tcr_r() -{ - return m_frc_tcr & 0x83; -} - -void sh2_device::frc_tcr_w(uint8_t data) -{ - sh2_timer_resync(); - m_frc_tcr = data & 0x83; - sh2_timer_activate(); - sh2_recalc_irq(); -} - -uint8_t sh2_device::tocr_r() -{ - return (m_tocr & 0x13) | 0xe0; -} - -void sh2_device::tocr_w(uint8_t data) -{ - sh2_timer_resync(); - // TODO: output levels A/B (bits 1-0) - m_tocr = data & 0x13; - sh2_timer_activate(); - sh2_recalc_irq(); -} - -uint16_t sh2_device::frc_icr_r() -{ - return m_frc_icr; -} - -/* - * INTC - */ - -uint16_t sh2_device::intc_icr_r() -{ - // TODO: flip meaning based off NMI edge select bit (NMIE) - uint16_t nmilv = m_nmi_line_state == ASSERT_LINE ? 0 : 0x8000; - return (nmilv) | (m_intc_icr & 0x0101); -} - -void sh2_device::intc_icr_w(offs_t offset, uint16_t data, uint16_t mem_mask) -{ - COMBINE_DATA(&m_intc_icr); - m_nmie = bool(BIT(m_intc_icr, 8)); - m_vecmd = bool(BIT(m_intc_icr, 0)); -} - -uint16_t sh2_device::ipra_r() -{ - return m_ipra & 0xfff0; -} - -void sh2_device::ipra_w(offs_t offset, uint16_t data, uint16_t mem_mask) -{ - COMBINE_DATA(&m_ipra); - m_irq_level.divu = (m_ipra >> 12) & 0xf; - m_irq_level.dmac = (m_ipra >> 8) & 0xf; - m_irq_level.wdt = (m_ipra >> 4) & 0xf; - sh2_recalc_irq(); -} - -uint16_t sh2_device::iprb_r() -{ - return m_iprb & 0xff00; -} - -void sh2_device::iprb_w(offs_t offset, uint16_t data, uint16_t mem_mask) -{ - COMBINE_DATA(&m_iprb); - m_irq_level.sci = (m_iprb >> 12) & 0xf; - m_irq_level.frc = (m_iprb >> 8) & 0xf; - sh2_recalc_irq(); -} - -uint16_t sh2_device::vcra_r() -{ - return m_vcra & 0x7f7f; -} - -void sh2_device::vcra_w(offs_t offset, uint16_t data, uint16_t mem_mask) -{ - COMBINE_DATA(&m_vcra); - // ... - sh2_recalc_irq(); -} - -uint16_t sh2_device::vcrb_r() -{ - return m_vcrb; -} - -void sh2_device::vcrb_w(offs_t offset, uint16_t data, uint16_t mem_mask) -{ - COMBINE_DATA(&m_vcrb); - // ... - sh2_recalc_irq(); -} - -uint16_t sh2_device::vcrc_r() -{ - return m_vcrc & 0x7f7f; -} - -void sh2_device::vcrc_w(offs_t offset, uint16_t data, uint16_t mem_mask) -{ - COMBINE_DATA(&m_vcrc); - m_irq_vector.fic = (m_vcrc >> 8) & 0x7f; - m_irq_vector.foc = (m_vcrc >> 0) & 0x7f; - sh2_recalc_irq(); -} - -uint16_t sh2_device::vcrd_r() -{ - return m_vcrd & 0x7f00; -} - -void sh2_device::vcrd_w(offs_t offset, uint16_t data, uint16_t mem_mask) -{ - COMBINE_DATA(&m_vcrd); - m_irq_vector.fov = (m_vcrc >> 8) & 0x7f; - sh2_recalc_irq(); -} - -uint16_t sh2_device::vcrwdt_r() -{ - return m_vcrwdt & 0x7f7f; -} - -void sh2_device::vcrwdt_w(offs_t offset, uint16_t data, uint16_t mem_mask) -{ - COMBINE_DATA(&m_vcrwdt); - // ... - sh2_recalc_irq(); -} - -uint32_t sh2_device::vcrdiv_r() -{ - return m_vcrdiv & 0x7f; -} - -void sh2_device::vcrdiv_w(offs_t offset, uint32_t data, uint32_t mem_mask) -{ - COMBINE_DATA(&m_vcrdiv); - // TODO: unemulated, level is seemingly not documented/settable? - m_irq_vector.divu = data & 0x7f; - sh2_recalc_irq(); -} - -/* - * DIVU - */ - -uint32_t sh2_device::dvcr_r() -{ - return (m_divu_ovfie == true ? 2 : 0) | (m_divu_ovf == true ? 1 : 0); -} - -void sh2_device::dvcr_w(offs_t offset, uint32_t data, uint32_t mem_mask) -{ - if(ACCESSING_BITS_0_7) - { - if (data & 1) - m_divu_ovf = false; - if (data & 2) - { - m_divu_ovfie = bool(BIT(data, 1)); - if (m_divu_ovfie == true) - logerror("SH2: unemulated DIVU OVF interrupt enable\n"); - } - sh2_recalc_irq(); - } -} - -uint32_t sh2_device::dvsr_r() -{ - return m_dvsr; -} - -void sh2_device::dvsr_w(offs_t offset, uint32_t data, uint32_t mem_mask) -{ - COMBINE_DATA(&m_dvsr); -} - -uint32_t sh2_device::dvdnt_r() -{ - return m_dvdntl; -} - -void sh2_device::dvdnt_w(offs_t offset, uint32_t data, uint32_t mem_mask) -{ - COMBINE_DATA(&m_dvdntl); - int32_t a = m_dvdntl; - int32_t b = m_dvsr; - LOG("SH2 div32+mod %d/%d\n", a, b); - if (b) - { - m_dvdntl = a / b; - m_dvdnth = a % b; - } - else - { - m_divu_ovf = true; - m_dvdntl = 0x7fffffff; - m_dvdnth = 0x7fffffff; - sh2_recalc_irq(); - } -} - -uint32_t sh2_device::dvdnth_r() -{ - return m_dvdnth; -} - -uint32_t sh2_device::dvdntl_r() -{ - return m_dvdntl; -} - -void sh2_device::dvdnth_w(offs_t offset, uint32_t data, uint32_t mem_mask) -{ - COMBINE_DATA(&m_dvdnth); -} - -void sh2_device::dvdntl_w(offs_t offset, uint32_t data, uint32_t mem_mask) -{ - COMBINE_DATA(&m_dvdntl); - int64_t a = m_dvdntl | ((uint64_t)(m_dvdnth) << 32); - int64_t b = (int32_t)m_dvsr; - LOG("SH2 div64+mod %d/%d\n", a, b); - if (b) - { - int64_t q = a / b; - if (q != (int32_t)q) - { - m_divu_ovf = true; - m_dvdntl = 0x7fffffff; - m_dvdnth = 0x7fffffff; - sh2_recalc_irq(); - } - else - { - m_dvdntl = q; - m_dvdnth = a % b; - } - } - else - { - m_divu_ovf = true; - m_dvdntl = 0x7fffffff; - m_dvdnth = 0x7fffffff; - sh2_recalc_irq(); - } -} - -/* - * WTC - */ - -uint16_t sh2_device::wtcnt_r() -{ - sh2_wtcnt_recalc(); - return ((m_wtcsr | 0x18) << 8) | (m_wtcnt & 0xff); -} - -uint16_t sh2_device::rstcsr_r() -{ - return (m_rstcsr & 0xe0) | 0x1f; -} - -void sh2_device::wtcnt_w(offs_t offset, uint16_t data, uint16_t mem_mask) -{ - COMBINE_DATA(&m_wtcw[0]); - switch (m_wtcw[0] & 0xff00) - { - case 0x5a00: - m_wtcnt = m_wtcw[0] & 0xff; - if (m_wtcsr & 0x20) - sh2_wdt_activate(); - break; - case 0xa500: - /* - WTCSR - x--- ---- Overflow in IT mode - -x-- ---- Timer mode (0: IT 1: watchdog) - --x- ---- Timer enable - ---1 1--- - ---- -xxx Clock select - */ - sh2_wtcnt_recalc(); - m_wtcsr &= m_wtcw[0] & 0x80; - m_wtcsr |= m_wtcw[0] & 0x7f; - if (m_wtcsr & 0x20) - sh2_wdt_activate(); - else - { - m_wtcnt = 0; - m_wdtimer->adjust(attotime::never); - } - sh2_recalc_irq(); - break; - } -} - -void sh2_device::rstcsr_w(offs_t offset, uint16_t data, uint16_t mem_mask) -{ - COMBINE_DATA(&m_wtcw[1]); - switch (m_wtcw[1] & 0xff00) - { - case 0xa500: - // clear WOVF flag - if ((m_wtcw[1] & 0x80) == 0) - m_rstcsr &= 0x7f; - break; - case 0x5a00: - m_rstcsr = (m_rstcsr & 0x80) | (m_wtcw[1] & 0x60); - break; - } -} - -uint16_t sh2_device::fmr_sbycr_r() -{ - return m_sbycr; -} - -void sh2_device::fmr_sbycr_w(offs_t offset, uint16_t data, uint16_t mem_mask) -{ - switch (mem_mask) - { - case 0xff00: // FMR 8bit - logerror("SH2 set clock multiplier x%d\n", 1 << ((data >> 8) & 3)); - break; - case 0xffff: // FMR 16bit - // SH7604 docs says FMR register must be set using 8-bit write, however at practice 16-bit works too. - // has been verified for CPS3 custom SH2, SH7604 and SH7095 (clock multiplier feature is not officially documented for SH7095). - logerror("SH2 set clock multiplier x%d\n", 1 << (data & 3)); - break; - case 0x00ff: // SBYCR - m_sbycr = data; - if (data & 0x1f) - logerror("SH2 module stop selected %02x\n", data); - break; - } -} - -uint8_t sh2_device::ccr_r() -{ - return m_ccr & ~0x30; -} - -void sh2_device::ccr_w(uint8_t data) -{ - /* - xx-- ---- Way 0/1 - ---x ---- Cache Purge (CP), write only - ---- x--- Two-Way Mode (TW) - ---- -x-- Data Replacement Disable (OD) - ---- --x- Instruction Replacement Disable (ID) - ---- ---x Cache Enable (CE) - */ - m_ccr = data; -} - -uint32_t sh2_device::bcr1_r() -{ - return (m_bcr1 & ~0xe008) | (m_is_slave ? 0x8000 : 0); -} - -void sh2_device::bcr1_w(offs_t offset, uint32_t data, uint32_t mem_mask) -{ - COMBINE_DATA(&m_bcr1); -} - -uint32_t sh2_device::bcr2_r() -{ - return m_bcr2; -} - -void sh2_device::bcr2_w(offs_t offset, uint32_t data, uint32_t mem_mask) -{ - COMBINE_DATA(&m_bcr2); -} - -uint32_t sh2_device::wcr_r() -{ - return m_wcr; -} - -void sh2_device::wcr_w(offs_t offset, uint32_t data, uint32_t mem_mask) -{ - COMBINE_DATA(&m_wcr); -} - -uint32_t sh2_device::mcr_r() -{ - return m_mcr & ~0x103; -} - -void sh2_device::mcr_w(offs_t offset, uint32_t data, uint32_t mem_mask) -{ - COMBINE_DATA(&m_mcr); -} - -uint32_t sh2_device::rtcsr_r() -{ - return m_rtcsr & 0xf8; -} - -void sh2_device::rtcsr_w(offs_t offset, uint32_t data, uint32_t mem_mask) -{ - COMBINE_DATA(&m_rtcsr); -} - -uint32_t sh2_device::rtcnt_r() -{ - return m_rtcnt & 0xff; -} - -void sh2_device::rtcnt_w(offs_t offset, uint32_t data, uint32_t mem_mask) -{ - COMBINE_DATA(&m_rtcnt); - m_rtcnt &= 0xff; -} - -uint32_t sh2_device::rtcor_r() -{ - return m_rtcor & 0xff; -} - -void sh2_device::rtcor_w(offs_t offset, uint32_t data, uint32_t mem_mask) -{ - COMBINE_DATA(&m_rtcor); - m_rtcor &= 0xff; -} - -void sh2_device::set_frt_input(int state) -{ - if(m_frt_input == state) { - return; - } - - m_frt_input = state; - - if(m_frc_tcr & 0x80) { - if(state == CLEAR_LINE) { - return; - } - } else { - if(state == ASSERT_LINE) { - return; - } - } - - sh2_timer_resync(); - m_frc_icr = m_frc; - m_ftcsr |= ICF; - //logerror("SH2.%s: ICF activated (%x)\n", tag(), m_sh2_state->pc & AM); - sh2_recalc_irq(); -} - -void sh2_device::sh2_recalc_irq() -{ - int irq = 0, vector = -1; - int level; - - // Timer irqs - if (m_tier & m_ftcsr & (ICF|OCFA|OCFB|OVF)) - { - level = (m_irq_level.frc & 15); - if (level > irq) - { - int mask = m_tier & m_ftcsr; - irq = level; - if(mask & ICF) - vector = m_irq_vector.fic & 0x7f; - else if(mask & (OCFA|OCFB)) - vector = m_irq_vector.foc & 0x7f; - else - vector = m_irq_vector.fov & 0x7f; - } - } - - // WDT irqs - if (m_wtcsr & 0x80) - { - level = m_irq_level.wdt & 15; - if (level > irq) - { - irq = level; - vector = (m_vcrwdt >> 8) & 0x7f; - } - } - - // DMA irqs - if((m_dmac[0].chcr & 6) == 6 && m_dma_irq[0]) { - level = m_irq_level.dmac & 15; - if(level > irq) { - irq = level; - m_dma_irq[0] &= ~1; - vector = m_irq_vector.dmac[0] & 0x7f; - } - } - else if((m_dmac[1].chcr & 6) == 6 && m_dma_irq[1]) { - level = m_irq_level.dmac & 15; - if(level > irq) { - irq = level; - m_dma_irq[1] &= ~1; - vector = m_irq_vector.dmac[1] & 0x7f; - } - } - - m_sh2_state->internal_irq_level = irq; - m_internal_irq_vector = vector; - m_test_irq = 1; -} - -/* - SH-7021 on-chip device - */ - -void sh2a_device::sh7032_dma_exec(int ch) -{ - const short dma_word_size[4] = { 0, +1, -1, 0 }; - uint8_t rs = (m_dma[ch].chcr >> 8) & 0xf; /**< Resource Select bits */ - if(rs != 0xc) // Auto-Request - { - logerror("Warning: SH7032 DMA enables non auto-request transfer\n"); - return; - } - - // channel enable & master enable - if((m_dma[ch].chcr & 1) == 0 || (m_dmaor & 1) == 0) - return; - - printf("%08x %08x %04x\n",m_dma[ch].sar,m_dma[ch].dar,m_dma[ch].chcr); - uint8_t dm = (m_dma[ch].chcr >> 14) & 3; /**< Destination Address Mode bits */ - uint8_t sm = (m_dma[ch].chcr >> 12) & 3; /**< Source Address Mode bits */ - bool ts = (m_dma[ch].chcr & 8); /**< Transfer Size bit */ - int src_word_size = dma_word_size[sm] * ((ts == true) ? 2 : 1); - int dst_word_size = dma_word_size[dm] * ((ts == true) ? 2 : 1); - uint32_t src_addr = m_dma[ch].sar; - uint32_t dst_addr = m_dma[ch].dar; - uint32_t size_index = m_dma[ch].tcr; - if(size_index == 0) - size_index = 0x10000; - - if(ts == false) - logerror("SH7032: DMA byte mode check\n"); - - for(int index = size_index;index>-1;index--) - { - if(ts == true) - m_program->write_word(dst_addr,m_program->read_word(src_addr)); - else - m_program->write_byte(dst_addr,m_program->read_byte(src_addr)); - - src_addr += src_word_size; - dst_addr += dst_word_size; - } - - m_dma[ch].chcr &= ~1; /**< @todo non-instant DMA */ - printf("%02x %02x %02x %1d\n",sm,dm,rs,ts); -} - -uint32_t sh2a_device::dma_sar0_r() -{ - return m_dma[0].sar; -} - -void sh2a_device::dma_sar0_w(offs_t offset, uint32_t data, uint32_t mem_mask) -{ - COMBINE_DATA(&m_dma[0].sar); -} - -uint32_t sh2a_device::dma_dar0_r() -{ - return m_dma[0].dar; -} - -void sh2a_device::dma_dar0_w(offs_t offset, uint32_t data, uint32_t mem_mask) -{ - COMBINE_DATA(&m_dma[0].dar); -} - -uint16_t sh2a_device::dma_tcr0_r() -{ - return m_dma[0].tcr; -} - -void sh2a_device::dma_tcr0_w(offs_t offset, uint16_t data, uint16_t mem_mask) -{ - //printf("%04x\n",data); - COMBINE_DATA(&m_dma[0].tcr); -} - -uint16_t sh2a_device::dma_chcr0_r() -{ - return m_dma[0].chcr; -} - -void sh2a_device::dma_chcr0_w(offs_t offset, uint16_t data, uint16_t mem_mask) -{ - //printf("%04x CHCR0\n",data); - COMBINE_DATA(&m_dma[0].chcr); - sh7032_dma_exec(0); -} - -uint16_t sh2a_device::dmaor_r() -{ - return m_dmaor; -} - -void sh2a_device::dmaor_w(offs_t offset, uint16_t data, uint16_t mem_mask) -{ - COMBINE_DATA(&m_dmaor); - sh7032_dma_exec(0); -} - -/*! - @brief Dummy debug interface - */ -uint16_t sh1_device::sh7032_r(offs_t offset) -{ - return m_sh7032_regs[offset]; -} - -/*! - @brief Dummy debug interface - */ -void sh1_device::sh7032_w(offs_t offset, uint16_t data, uint16_t mem_mask) -{ - COMBINE_DATA(&m_sh7032_regs[offset]); -} - -uint16_t sh2a_device::sh7021_r(offs_t offset) -{ - return m_sh7021_regs[offset]; -} - -/*! - @brief Dummy debug interface - */ -void sh2a_device::sh7021_w(offs_t offset, uint16_t data, uint16_t mem_mask) -{ - COMBINE_DATA(&m_sh7021_regs[offset]); -} diff --git a/src/devices/cpu/sh/sh2comn.h b/src/devices/cpu/sh/sh2comn.h deleted file mode 100644 index 53f5e04d2e6..00000000000 --- a/src/devices/cpu/sh/sh2comn.h +++ /dev/null @@ -1,52 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:R. Belmont -/***************************************************************************** - * - * sh2common.h - * - * SH-2 non-specific components - * - *****************************************************************************/ - -#ifndef MAME_CPU_SH2_SH2COMN_H -#define MAME_CPU_SH2_SH2COMN_H - -#pragma once - -enum -{ - ICF = 0x80, - OCFA = 0x08, - OCFB = 0x04, - OVF = 0x02, - CCLRA = 0x01 -}; - -#define SH12_AM 0xc7ffffff - -#define CHECK_PENDING_IRQ(message) \ -do { \ - int irq = -1; \ - if (m_sh2_state->pending_irq & (1 << 0)) irq = 0; \ - if (m_sh2_state->pending_irq & (1 << 1)) irq = 1; \ - if (m_sh2_state->pending_irq & (1 << 2)) irq = 2; \ - if (m_sh2_state->pending_irq & (1 << 3)) irq = 3; \ - if (m_sh2_state->pending_irq & (1 << 4)) irq = 4; \ - if (m_sh2_state->pending_irq & (1 << 5)) irq = 5; \ - if (m_sh2_state->pending_irq & (1 << 6)) irq = 6; \ - if (m_sh2_state->pending_irq & (1 << 7)) irq = 7; \ - if (m_sh2_state->pending_irq & (1 << 8)) irq = 8; \ - if (m_sh2_state->pending_irq & (1 << 9)) irq = 9; \ - if (m_sh2_state->pending_irq & (1 << 10)) irq = 10; \ - if (m_sh2_state->pending_irq & (1 << 11)) irq = 11; \ - if (m_sh2_state->pending_irq & (1 << 12)) irq = 12; \ - if (m_sh2_state->pending_irq & (1 << 13)) irq = 13; \ - if (m_sh2_state->pending_irq & (1 << 14)) irq = 14; \ - if (m_sh2_state->pending_irq & (1 << 15)) irq = 15; \ - if ((m_sh2_state->internal_irq_level != -1) && (m_sh2_state->internal_irq_level > irq)) irq = m_sh2_state->internal_irq_level; \ - if (irq >= 0) \ - sh2_exception(message,irq); \ -} while(0) - - -#endif // MAME_CPU_SH2_SH2COMN_H diff --git a/src/devices/cpu/sh/sh2fe.cpp b/src/devices/cpu/sh/sh2fe.cpp index 3019dc02ab7..8db408b4bd3 100644 --- a/src/devices/cpu/sh/sh2fe.cpp +++ b/src/devices/cpu/sh/sh2fe.cpp @@ -10,7 +10,6 @@ #include "emu.h" #include "sh2.h" -#include "sh2comn.h" #include "cpu/drcfe.h" diff --git a/src/devices/cpu/sh/sh7021.cpp b/src/devices/cpu/sh/sh7021.cpp new file mode 100644 index 00000000000..18aa0c1574d --- /dev/null +++ b/src/devices/cpu/sh/sh7021.cpp @@ -0,0 +1,163 @@ +// license:BSD-3-Clause +// copyright-holders:Angelo Salese + +#include "sh7021.h" + +DEFINE_DEVICE_TYPE(SH2A_SH7021, sh2a_sh7021_device, "sh2a_sh7021", "Hitachi SH-2A (SH7021)") + + +sh2a_sh7021_device::sh2a_sh7021_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : sh2_device(mconfig, SH2A_SH7021, tag, owner, clock, CPU_TYPE_SH2, address_map_constructor(FUNC(sh2a_sh7021_device::sh7021_map), this), 28, 0xc7ffffff) +{ +} + +void sh2a_sh7021_device::device_start() +{ + sh2_device::device_start(); + + save_item(NAME(m_sh7021_regs)); + save_item(NAME(m_dmaor)); + save_item(STRUCT_MEMBER(m_dma, sar)); + save_item(STRUCT_MEMBER(m_dma, dar)); + save_item(STRUCT_MEMBER(m_dma, tcr)); + save_item(STRUCT_MEMBER(m_dma, chcr)); +} + +void sh2a_sh7021_device::device_reset() +{ + sh2_device::device_reset(); + + std::fill(std::begin(m_sh7021_regs), std::end(m_sh7021_regs), 0); + + m_dmaor = 0; + + for(int i = 0; i < 4; i++) + { + m_dma[i].sar = 0; + m_dma[i].dar = 0; + m_dma[i].tcr = 0; + m_dma[i].chcr = 0; + } +} + +void sh2a_sh7021_device::sh7021_map(address_map &map) +{ +// fall-back + map(0x05fffe00, 0x05ffffff).rw(FUNC(sh2a_sh7021_device::sh7021_r), FUNC(sh2a_sh7021_device::sh7021_w)); // SH-7032H internal i/o +// overrides + map(0x05ffff40, 0x05ffff43).rw(FUNC(sh2a_sh7021_device::dma_sar0_r), FUNC(sh2a_sh7021_device::dma_sar0_w)); + map(0x05ffff44, 0x05ffff47).rw(FUNC(sh2a_sh7021_device::dma_dar0_r), FUNC(sh2a_sh7021_device::dma_dar0_w)); + map(0x05ffff48, 0x05ffff49).rw(FUNC(sh2a_sh7021_device::dmaor_r), FUNC(sh2a_sh7021_device::dmaor_w)); + map(0x05ffff4a, 0x05ffff4b).rw(FUNC(sh2a_sh7021_device::dma_tcr0_r), FUNC(sh2a_sh7021_device::dma_tcr0_w)); + map(0x05ffff4e, 0x05ffff4f).rw(FUNC(sh2a_sh7021_device::dma_chcr0_r), FUNC(sh2a_sh7021_device::dma_chcr0_w)); +// map(0x07000000, 0x070003ff).ram().share("oram"); // on-chip RAM, actually at 0xf000000 (1 kb) +// map(0x0f000000, 0x0f0003ff).ram().share("oram"); // on-chip RAM, actually at 0xf000000 (1 kb) +} + +void sh2a_sh7021_device::sh7021_dma_exec(int ch) +{ + const short dma_word_size[4] = { 0, +1, -1, 0 }; + uint8_t rs = (m_dma[ch].chcr >> 8) & 0xf; /**< Resource Select bits */ + if(rs != 0xc) // Auto-Request + { + logerror("Warning: SH7021 DMA enables non auto-request transfer\n"); + return; + } + + // channel enable & master enable + if((m_dma[ch].chcr & 1) == 0 || (m_dmaor & 1) == 0) + return; + + // printf("%08x %08x %04x\n",m_dma[ch].sar,m_dma[ch].dar,m_dma[ch].chcr); + uint8_t dm = (m_dma[ch].chcr >> 14) & 3; /**< Destination Address Mode bits */ + uint8_t sm = (m_dma[ch].chcr >> 12) & 3; /**< Source Address Mode bits */ + bool ts = (m_dma[ch].chcr & 8); /**< Transfer Size bit */ + int src_word_size = dma_word_size[sm] * ((ts == true) ? 2 : 1); + int dst_word_size = dma_word_size[dm] * ((ts == true) ? 2 : 1); + uint32_t src_addr = m_dma[ch].sar; + uint32_t dst_addr = m_dma[ch].dar; + uint32_t size_index = m_dma[ch].tcr; + if(size_index == 0) + size_index = 0x10000; + + if(ts == false) + logerror("SH7021: DMA byte mode check\n"); + + for(int index = size_index;index>-1;index--) + { + if(ts == true) + m_program->write_word(dst_addr,m_program->read_word(src_addr)); + else + m_program->write_byte(dst_addr,m_program->read_byte(src_addr)); + + src_addr += src_word_size; + dst_addr += dst_word_size; + } + + m_dma[ch].chcr &= ~1; /**< @todo non-instant DMA */ + // printf("%02x %02x %02x %1d\n",sm,dm,rs,ts); +} + +uint32_t sh2a_sh7021_device::dma_sar0_r() +{ + return m_dma[0].sar; +} + +void sh2a_sh7021_device::dma_sar0_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + COMBINE_DATA(&m_dma[0].sar); +} + +uint32_t sh2a_sh7021_device::dma_dar0_r() +{ + return m_dma[0].dar; +} + +void sh2a_sh7021_device::dma_dar0_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + COMBINE_DATA(&m_dma[0].dar); +} + +uint16_t sh2a_sh7021_device::dma_tcr0_r() +{ + return m_dma[0].tcr; +} + +void sh2a_sh7021_device::dma_tcr0_w(offs_t offset, uint16_t data, uint16_t mem_mask) +{ + //printf("%04x\n",data); + COMBINE_DATA(&m_dma[0].tcr); +} + +uint16_t sh2a_sh7021_device::dma_chcr0_r() +{ + return m_dma[0].chcr; +} + +void sh2a_sh7021_device::dma_chcr0_w(offs_t offset, uint16_t data, uint16_t mem_mask) +{ + //printf("%04x CHCR0\n",data); + COMBINE_DATA(&m_dma[0].chcr); + sh7021_dma_exec(0); +} + +uint16_t sh2a_sh7021_device::dmaor_r() +{ + return m_dmaor; +} + +void sh2a_sh7021_device::dmaor_w(offs_t offset, uint16_t data, uint16_t mem_mask) +{ + COMBINE_DATA(&m_dmaor); + sh7021_dma_exec(0); +} + +uint16_t sh2a_sh7021_device::sh7021_r(offs_t offset) +{ + return m_sh7021_regs[offset]; +} + +void sh2a_sh7021_device::sh7021_w(offs_t offset, uint16_t data, uint16_t mem_mask) +{ + COMBINE_DATA(&m_sh7021_regs[offset]); +} diff --git a/src/devices/cpu/sh/sh7021.h b/src/devices/cpu/sh/sh7021.h new file mode 100644 index 00000000000..dff35e72eab --- /dev/null +++ b/src/devices/cpu/sh/sh7021.h @@ -0,0 +1,52 @@ +// license:BSD-3-Clause +// copyright-holders:Angelo Salese + +#ifndef MAME_CPU_SH_SH7021_H +#define MAME_CPU_SH_SH7021_H + +#pragma once + +#include "sh2.h" + +class sh2a_sh7021_device : public sh2_device +{ +public: + sh2a_sh7021_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + virtual void device_start() override; + virtual void device_reset() override; + +private: + void sh7021_map(address_map &map); + + uint32_t dma_sar0_r(); + void dma_sar0_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); + uint32_t dma_dar0_r(); + void dma_dar0_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); + uint16_t dmaor_r(); + void dmaor_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + uint16_t dma_tcr0_r(); + void dma_tcr0_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + uint16_t dma_chcr0_r(); + void dma_chcr0_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + uint16_t sh7021_r(offs_t offset); + void sh7021_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + + void sh7021_dma_exec(int ch); + + uint16_t m_sh7021_regs[0x200]; + struct + { + uint32_t sar; /**< Source Address Register */ + uint32_t dar; /**< Destination Address Register */ + uint16_t tcr; /**< Transfer Count Register */ + uint16_t chcr; /**< Channel Control Register */ + } m_dma[4]; + + uint16_t m_dmaor; /**< DMA Operation Register (status flags) */ +}; + +DECLARE_DEVICE_TYPE(SH2A_SH7021, sh2a_sh7021_device) + +#endif // MAME_CPU_SH_SH7021_H diff --git a/src/devices/cpu/sh/sh7032.cpp b/src/devices/cpu/sh/sh7032.cpp new file mode 100644 index 00000000000..775e7e72f23 --- /dev/null +++ b/src/devices/cpu/sh/sh7032.cpp @@ -0,0 +1,42 @@ +// license:BSD-3-Clause +// copyright-holders:Angelo Salese + +#include "sh7032.h" + +DEFINE_DEVICE_TYPE(SH1_SH7032, sh1_sh7032_device, "sh1_sh7032", "Hitachi SH-1 (SH7032)") + + +sh1_sh7032_device::sh1_sh7032_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : sh2_device(mconfig, SH1_SH7032, tag, owner, clock, CPU_TYPE_SH1, address_map_constructor(FUNC(sh1_sh7032_device::sh7032_map), this), 28, 0xc7ffffff) +{ +} + +void sh1_sh7032_device::device_start() +{ + sh2_device::device_start(); + + save_item(NAME(m_sh7032_regs)); +} + +void sh1_sh7032_device::device_reset() +{ + sh2_device::device_reset(); + + std::fill(std::begin(m_sh7032_regs), std::end(m_sh7032_regs), 0); +} + +void sh1_sh7032_device::sh7032_map(address_map &map) +{ +// fall-back + map(0x05fffe00, 0x05ffffff).rw(FUNC(sh1_sh7032_device::sh7032_r), FUNC(sh1_sh7032_device::sh7032_w)); // SH-7032H internal i/o +} + +uint16_t sh1_sh7032_device::sh7032_r(offs_t offset) +{ + return m_sh7032_regs[offset]; +} + +void sh1_sh7032_device::sh7032_w(offs_t offset, uint16_t data, uint16_t mem_mask) +{ + COMBINE_DATA(&m_sh7032_regs[offset]); +} diff --git a/src/devices/cpu/sh/sh7032.h b/src/devices/cpu/sh/sh7032.h new file mode 100644 index 00000000000..37d528263bc --- /dev/null +++ b/src/devices/cpu/sh/sh7032.h @@ -0,0 +1,31 @@ +// license:BSD-3-Clause +// copyright-holders:Angelo Salese + +#ifndef MAME_CPU_SH_SH7032_H +#define MAME_CPU_SH_SH7032_H + +#pragma once + +#include "sh2.h" + +class sh1_sh7032_device : public sh2_device +{ +public: + sh1_sh7032_device(const machine_config &mconfig, const char *_tag, device_t *_owner, uint32_t _clock); + +protected: + virtual void device_start() override; + virtual void device_reset() override; + +private: + void sh7032_map(address_map &map); + + uint16_t sh7032_r(offs_t offset); + void sh7032_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + + uint16_t m_sh7032_regs[0x200]; +}; + +DECLARE_DEVICE_TYPE(SH1_SH7032, sh1_sh7032_device) + +#endif // MAME_CPU_SH_SH7032_H diff --git a/src/devices/cpu/sh/sh7604.cpp b/src/devices/cpu/sh/sh7604.cpp new file mode 100644 index 00000000000..af017bc14fa --- /dev/null +++ b/src/devices/cpu/sh/sh7604.cpp @@ -0,0 +1,1538 @@ +// license:BSD-3-Clause +// copyright-holders:Juergen Buchmueller, R. Belmont +/***************************************************************************** + * + * sh2.c + * Portable Hitachi SH-2 (SH7600 family) emulator + * + * This work is based on C/C++ implementation of + * the SH-2 CPU core and was adapted to the MAME CPU core requirements. + * Thanks also go to Chuck Mason and Olivier Galibert + * for letting me peek into their SEMU code :-) + * + *****************************************************************************/ +/* +TODO: Test and use sh7604_wdt_device, sh7604_sci_device, and sh7604_bus_device as appropriate +*/ + + +#include "emu.h" + +#include "sh7604.h" + +//#define VERBOSE 1 +#include "logmacro.h" + + +static constexpr int div_tab[4] = { 3, 5, 7, 0 }; +static constexpr int wdtclk_tab[8] = { 1, 6, 7, 8, 9, 10, 12, 13 }; + + +DEFINE_DEVICE_TYPE(SH2_SH7604, sh2_sh7604_device, "sh2_7604", "Hitachi SH-2 (SH7604)") + + +sh2_sh7604_device::sh2_sh7604_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : sh2_device(mconfig, SH2_SH7604, tag, owner, clock, CPU_TYPE_SH2, address_map_constructor(FUNC(sh2_sh7604_device::sh7604_map), this), 32, 0xc7ffffff) + , m_test_irq(0), m_internal_irq_vector(0) + , m_smr(0), m_brr(0), m_scr(0), m_tdr(0), m_ssr(0) + , m_tier(0), m_ftcsr(0), m_frc_tcr(0), m_tocr(0), m_frc(0), m_ocra(0), m_ocrb(0), m_frc_icr(0) + , m_ipra(0), m_iprb(0), m_vcra(0), m_vcrb(0), m_vcrc(0), m_vcrd(0), m_vcrwdt(0), m_vcrdiv(0), m_intc_icr(0), m_vecmd(false), m_nmie(false) + , m_divu_ovf(false), m_divu_ovfie(false), m_dvsr(0), m_dvdntl(0), m_dvdnth(0) + , m_wtcnt(0), m_wtcsr(0), m_rstcsr(0) + , m_dmaor(0) + , m_sbycr(0), m_ccr(0) + , m_bcr1(0), m_bcr2(0), m_wcr(0), m_mcr(0), m_rtcsr(0), m_rtcor(0), m_rtcnt(0) + , m_frc_base(0), m_frt_input(0) + , m_timer(nullptr), m_wdtimer(nullptr) + , m_is_slave(0) + , m_dma_kludge_cb(*this) + , m_dma_fifo_data_available_cb(*this) + , m_ftcsr_read_cb(*this) +{ + std::fill(std::begin(m_vcrdma), std::end(m_vcrdma), 0); + std::fill(std::begin(m_dma_timer_active), std::end(m_dma_timer_active), 0); + std::fill(std::begin(m_dma_irq), std::end(m_dma_irq), 0); + std::fill(std::begin(m_active_dma_incs), std::end(m_active_dma_incs), 0); + std::fill(std::begin(m_active_dma_incd), std::end(m_active_dma_incd), 0); + std::fill(std::begin(m_active_dma_size), std::end(m_active_dma_size), 0); + std::fill(std::begin(m_active_dma_steal), std::end(m_active_dma_steal), 0); + std::fill(std::begin(m_active_dma_src), std::end(m_active_dma_src), 0); + std::fill(std::begin(m_active_dma_dst), std::end(m_active_dma_dst), 0); + std::fill(std::begin(m_active_dma_count), std::end(m_active_dma_count), 0); + std::fill(std::begin(m_wtcw), std::end(m_wtcw), 0); + std::fill(std::begin(m_dma_current_active_timer), std::end(m_dma_current_active_timer), nullptr); + + m_irq_vector.fic = m_irq_vector.foc = m_irq_vector.fov = m_irq_vector.divu = 0; + std::fill(std::begin(m_irq_vector.dmac), std::end(m_irq_vector.dmac), 0); + + m_irq_level.frc = m_irq_level.sci = m_irq_level.divu = m_irq_level.dmac = m_irq_level.wdt = 0; + + for(int i = 0; i < 2; i++) + m_dmac[i].drcr = m_dmac[i].sar = m_dmac[i].dar = m_dmac[i].tcr = m_dmac[i].chcr = 0; +} + +void sh2_sh7604_device::device_start() +{ + sh2_device::device_start(); + + m_timer = timer_alloc(FUNC(sh2_sh7604_device::sh2_timer_callback), this); + m_timer->adjust(attotime::never); + m_wdtimer = timer_alloc(FUNC(sh2_sh7604_device::sh2_wdtimer_callback), this); + m_wdtimer->adjust(attotime::never); + + m_dma_current_active_timer[0] = timer_alloc(FUNC(sh2_sh7604_device::sh2_dma_current_active_callback), this); + m_dma_current_active_timer[0]->adjust(attotime::never); + + m_dma_current_active_timer[1] = timer_alloc(FUNC(sh2_sh7604_device::sh2_dma_current_active_callback), this); + m_dma_current_active_timer[1]->adjust(attotime::never); + + /* resolve callbacks */ + m_dma_kludge_cb.resolve(); + m_dma_fifo_data_available_cb.resolve(); + m_ftcsr_read_cb.resolve(); + + // SCI + save_item(NAME(m_smr)); + save_item(NAME(m_brr)); + save_item(NAME(m_scr)); + save_item(NAME(m_tdr)); + save_item(NAME(m_ssr)); + + // FRT / FRC + save_item(NAME(m_tier)); + save_item(NAME(m_ftcsr)); + save_item(NAME(m_frc_tcr)); + save_item(NAME(m_tocr)); + save_item(NAME(m_frc)); + save_item(NAME(m_ocra)); + save_item(NAME(m_ocrb)); + save_item(NAME(m_frc_icr)); + save_item(NAME(m_frc_base)); + save_item(NAME(m_frt_input)); + + // INTC + save_item(NAME(m_irq_level.frc)); + save_item(NAME(m_irq_level.sci)); + save_item(NAME(m_irq_level.divu)); + save_item(NAME(m_irq_level.dmac)); + save_item(NAME(m_irq_level.wdt)); + save_item(NAME(m_irq_vector.fic)); + save_item(NAME(m_irq_vector.foc)); + save_item(NAME(m_irq_vector.fov)); + save_item(NAME(m_irq_vector.divu)); + save_item(NAME(m_irq_vector.dmac)); + + save_item(NAME(m_ipra)); + save_item(NAME(m_iprb)); + save_item(NAME(m_vcra)); + save_item(NAME(m_vcrb)); + save_item(NAME(m_vcrc)); + save_item(NAME(m_vcrd)); + save_item(NAME(m_vcrwdt)); + save_item(NAME(m_vcrdiv)); + save_item(NAME(m_intc_icr)); + save_item(NAME(m_vcrdma)); + + save_item(NAME(m_vecmd)); + save_item(NAME(m_nmie)); + + // DIVU + save_item(NAME(m_divu_ovf)); + save_item(NAME(m_divu_ovfie)); + save_item(NAME(m_dvsr)); + save_item(NAME(m_dvdntl)); + save_item(NAME(m_dvdnth)); + + // WTC + save_item(NAME(m_wtcnt)); + save_item(NAME(m_wtcsr)); + save_item(NAME(m_rstcsr)); + save_item(NAME(m_wtcw)); + + // DMAC + save_item(NAME(m_dmaor)); + save_item(STRUCT_MEMBER(m_dmac, drcr)); + save_item(STRUCT_MEMBER(m_dmac, sar)); + save_item(STRUCT_MEMBER(m_dmac, dar)); + save_item(STRUCT_MEMBER(m_dmac, tcr)); + save_item(STRUCT_MEMBER(m_dmac, chcr)); + + // misc + save_item(NAME(m_sbycr)); + save_item(NAME(m_ccr)); + + // BSC + save_item(NAME(m_bcr1)); + save_item(NAME(m_bcr2)); + save_item(NAME(m_wcr)); + save_item(NAME(m_mcr)); + save_item(NAME(m_rtcsr)); + save_item(NAME(m_rtcor)); + save_item(NAME(m_rtcnt)); +} + +void sh2_sh7604_device::device_reset() +{ + sh2_device::device_reset(); + + m_frc = 0; + m_ocra = 0; + m_ocrb = 0; + m_frc_icr = 0; + m_frc_base = 0; + m_frt_input = 0; + + for ( int i = 0; i < 2; i++ ) + { + m_dma_timer_active[i] = 0; + m_dma_irq[i] = 0; + m_active_dma_incs[i] = 0; + m_active_dma_incd[i] = 0; + m_active_dma_size[i] = 0; + m_active_dma_steal[i] = 0; + m_active_dma_src[i] = 0; + m_active_dma_dst[i] = 0; + m_active_dma_count[i] = 0; + } + + m_wtcnt = 0; + m_wtcsr = 0; +} + +void sh2_sh7604_device::sh7604_map(address_map &map) +{ + map(0x40000000, 0xbfffffff).r(FUNC(sh2_sh7604_device::sh2_internal_a5)); + +// TODO: cps3boot breaks with this enabled. Needs callback +// map(0xc0000000, 0xc0000fff).ram(); // cache data array + +// map(0xe0000000, 0xe00001ff).mirror(0x1ffffe00).rw(FUNC(sh2_sh7604_device::sh7604_r), FUNC(sh2_sh7604_device::sh7604_w)); + // TODO: internal map takes way too much resources if mirrored with 0x1ffffe00 + // we eventually internalize again via trampoline & sh7604_device + // Also area 0xffff8000-0xffffbfff is for synchronous DRAM mode, + // so this isn't actually a full mirror + // SCI + map(0xfffffe00, 0xfffffe00).rw(FUNC(sh2_sh7604_device::smr_r), FUNC(sh2_sh7604_device::smr_w)); + map(0xfffffe01, 0xfffffe01).rw(FUNC(sh2_sh7604_device::brr_r), FUNC(sh2_sh7604_device::brr_w)); + map(0xfffffe02, 0xfffffe02).rw(FUNC(sh2_sh7604_device::scr_r), FUNC(sh2_sh7604_device::scr_w)); + map(0xfffffe03, 0xfffffe03).rw(FUNC(sh2_sh7604_device::tdr_r), FUNC(sh2_sh7604_device::tdr_w)); + map(0xfffffe04, 0xfffffe04).rw(FUNC(sh2_sh7604_device::ssr_r), FUNC(sh2_sh7604_device::ssr_w)); + map(0xfffffe05, 0xfffffe05).r(FUNC(sh2_sh7604_device::rdr_r)); + + // FRC + map(0xfffffe10, 0xfffffe10).rw(FUNC(sh2_sh7604_device::tier_r), FUNC(sh2_sh7604_device::tier_w)); + map(0xfffffe11, 0xfffffe11).rw(FUNC(sh2_sh7604_device::ftcsr_r), FUNC(sh2_sh7604_device::ftcsr_w)); + map(0xfffffe12, 0xfffffe13).rw(FUNC(sh2_sh7604_device::frc_r), FUNC(sh2_sh7604_device::frc_w)); + map(0xfffffe14, 0xfffffe15).rw(FUNC(sh2_sh7604_device::ocra_b_r), FUNC(sh2_sh7604_device::ocra_b_w)); + map(0xfffffe16, 0xfffffe16).rw(FUNC(sh2_sh7604_device::frc_tcr_r), FUNC(sh2_sh7604_device::frc_tcr_w)); + map(0xfffffe17, 0xfffffe17).rw(FUNC(sh2_sh7604_device::tocr_r), FUNC(sh2_sh7604_device::tocr_w)); + map(0xfffffe18, 0xfffffe19).r(FUNC(sh2_sh7604_device::frc_icr_r)); + + // INTC + map(0xfffffe60, 0xfffffe61).rw(FUNC(sh2_sh7604_device::iprb_r), FUNC(sh2_sh7604_device::iprb_w)); + map(0xfffffe62, 0xfffffe63).rw(FUNC(sh2_sh7604_device::vcra_r), FUNC(sh2_sh7604_device::vcra_w)); + map(0xfffffe64, 0xfffffe65).rw(FUNC(sh2_sh7604_device::vcrb_r), FUNC(sh2_sh7604_device::vcrb_w)); + map(0xfffffe66, 0xfffffe67).rw(FUNC(sh2_sh7604_device::vcrc_r), FUNC(sh2_sh7604_device::vcrc_w)); + map(0xfffffe68, 0xfffffe69).rw(FUNC(sh2_sh7604_device::vcrd_r), FUNC(sh2_sh7604_device::vcrd_w)); + + map(0xfffffe71, 0xfffffe71).rw(FUNC(sh2_sh7604_device::drcr_r<0>), FUNC(sh2_sh7604_device::drcr_w<0>)); + map(0xfffffe72, 0xfffffe72).rw(FUNC(sh2_sh7604_device::drcr_r<1>), FUNC(sh2_sh7604_device::drcr_w<1>)); + + // WTC + map(0xfffffe80, 0xfffffe81).rw(FUNC(sh2_sh7604_device::wtcnt_r), FUNC(sh2_sh7604_device::wtcnt_w)); + map(0xfffffe82, 0xfffffe83).rw(FUNC(sh2_sh7604_device::rstcsr_r), FUNC(sh2_sh7604_device::rstcsr_w)); + + // standby and cache control + map(0xfffffe90, 0xfffffe91).rw(FUNC(sh2_sh7604_device::fmr_sbycr_r), FUNC(sh2_sh7604_device::fmr_sbycr_w)); + map(0xfffffe92, 0xfffffe92).rw(FUNC(sh2_sh7604_device::ccr_r), FUNC(sh2_sh7604_device::ccr_w)); + + // INTC second section + map(0xfffffee0, 0xfffffee1).rw(FUNC(sh2_sh7604_device::intc_icr_r), FUNC(sh2_sh7604_device::intc_icr_w)); + map(0xfffffee2, 0xfffffee3).rw(FUNC(sh2_sh7604_device::ipra_r), FUNC(sh2_sh7604_device::ipra_w)); + map(0xfffffee4, 0xfffffee5).rw(FUNC(sh2_sh7604_device::vcrwdt_r), FUNC(sh2_sh7604_device::vcrwdt_w)); + + // DIVU + map(0xffffff00, 0xffffff03).rw(FUNC(sh2_sh7604_device::dvsr_r), FUNC(sh2_sh7604_device::dvsr_w)); + map(0xffffff04, 0xffffff07).rw(FUNC(sh2_sh7604_device::dvdnt_r), FUNC(sh2_sh7604_device::dvdnt_w)); + map(0xffffff08, 0xffffff0b).rw(FUNC(sh2_sh7604_device::dvcr_r), FUNC(sh2_sh7604_device::dvcr_w)); + // INTC third section + map(0xffffff0c, 0xffffff0f).rw(FUNC(sh2_sh7604_device::vcrdiv_r), FUNC(sh2_sh7604_device::vcrdiv_w)); + // DIVU continued (64-bit plus mirrors) + map(0xffffff10, 0xffffff13).rw(FUNC(sh2_sh7604_device::dvdnth_r), FUNC(sh2_sh7604_device::dvdnth_w)); + map(0xffffff14, 0xffffff17).rw(FUNC(sh2_sh7604_device::dvdntl_r), FUNC(sh2_sh7604_device::dvdntl_w)); + map(0xffffff18, 0xffffff1b).r(FUNC(sh2_sh7604_device::dvdnth_r)); + map(0xffffff1c, 0xffffff1f).r(FUNC(sh2_sh7604_device::dvdntl_r)); + + // DMAC + map(0xffffff80, 0xffffff83).rw(FUNC(sh2_sh7604_device::sar_r<0>), FUNC(sh2_sh7604_device::sar_w<0>)); + map(0xffffff84, 0xffffff87).rw(FUNC(sh2_sh7604_device::dar_r<0>), FUNC(sh2_sh7604_device::dar_w<0>)); + map(0xffffff88, 0xffffff8b).rw(FUNC(sh2_sh7604_device::dmac_tcr_r<0>), FUNC(sh2_sh7604_device::dmac_tcr_w<0>)); + map(0xffffff8c, 0xffffff8f).rw(FUNC(sh2_sh7604_device::chcr_r<0>), FUNC(sh2_sh7604_device::chcr_w<0>)); + + map(0xffffff90, 0xffffff93).rw(FUNC(sh2_sh7604_device::sar_r<1>), FUNC(sh2_sh7604_device::sar_w<1>)); + map(0xffffff94, 0xffffff97).rw(FUNC(sh2_sh7604_device::dar_r<1>), FUNC(sh2_sh7604_device::dar_w<1>)); + map(0xffffff98, 0xffffff9b).rw(FUNC(sh2_sh7604_device::dmac_tcr_r<1>), FUNC(sh2_sh7604_device::dmac_tcr_w<1>)); + map(0xffffff9c, 0xffffff9f).rw(FUNC(sh2_sh7604_device::chcr_r<1>), FUNC(sh2_sh7604_device::chcr_w<1>)); + + map(0xffffffa0, 0xffffffa3).rw(FUNC(sh2_sh7604_device::vcrdma_r<0>), FUNC(sh2_sh7604_device::vcrdma_w<0>)); + map(0xffffffa8, 0xffffffab).rw(FUNC(sh2_sh7604_device::vcrdma_r<1>), FUNC(sh2_sh7604_device::vcrdma_w<1>)); + map(0xffffffb0, 0xffffffb3).rw(FUNC(sh2_sh7604_device::dmaor_r), FUNC(sh2_sh7604_device::dmaor_w)); + + // BSC + map(0xffffffe0, 0xffffffe3).rw(FUNC(sh2_sh7604_device::bcr1_r), FUNC(sh2_sh7604_device::bcr1_w)); + map(0xffffffe4, 0xffffffe7).rw(FUNC(sh2_sh7604_device::bcr2_r), FUNC(sh2_sh7604_device::bcr2_w)); + map(0xffffffe8, 0xffffffeb).rw(FUNC(sh2_sh7604_device::wcr_r), FUNC(sh2_sh7604_device::wcr_w)); + map(0xffffffec, 0xffffffef).rw(FUNC(sh2_sh7604_device::mcr_r), FUNC(sh2_sh7604_device::mcr_w)); + map(0xfffffff0, 0xfffffff3).rw(FUNC(sh2_sh7604_device::rtcsr_r), FUNC(sh2_sh7604_device::rtcsr_w)); + map(0xfffffff4, 0xfffffff7).rw(FUNC(sh2_sh7604_device::rtcnt_r), FUNC(sh2_sh7604_device::rtcnt_w)); + map(0xfffffff8, 0xfffffffb).rw(FUNC(sh2_sh7604_device::rtcor_r), FUNC(sh2_sh7604_device::rtcor_w)); +} + + +void sh2_sh7604_device::sh2_exception(const char *message, int irqline) +{ + int vector; + + if (irqline != 16) + { + if (irqline <= ((m_sh2_state->sr >> 4) & 15)) /* If the cpu forbids this interrupt */ + return; + + // if this is an sh2 internal irq, use its vector + if (m_sh2_state->internal_irq_level == irqline) + { + vector = m_internal_irq_vector; + /* avoid spurious irqs with this (TODO: needs a better fix) */ + m_sh2_state->internal_irq_level = -1; + LOG("SH-2 exception #%d (internal vector: $%x) after [%s]\n", irqline, vector, message); + } + else + { + if(m_vecmd == true) + { + vector = standard_irq_callback(irqline, m_sh2_state->pc); + LOG("SH-2 exception #%d (external vector: $%x) after [%s]\n", irqline, vector, message); + } + else + { + standard_irq_callback(irqline, m_sh2_state->pc); + vector = 64 + irqline/2; + LOG("SH-2 exception #%d (autovector: $%x) after [%s]\n", irqline, vector, message); + } + } + } + else + { + vector = 11; + LOG("SH-2 nmi exception (autovector: $%x) after [%s]\n", vector, message); + } + + sh2_exception_internal(message, irqline, vector); +} + +uint32_t sh2_sh7604_device::sh2_internal_a5() +{ + return 0xa5a5a5a5; +} + +void sh2_sh7604_device::sh2_timer_resync() +{ + // TODO: setting 3 is "External clock: count on rising edge" + int divider = div_tab[m_frc_tcr & 3]; + uint64_t cur_time = total_cycles(); + uint64_t add = (cur_time - m_frc_base) >> divider; + + if (add > 0) + { + if(divider) + m_frc += add; + + m_frc_base = cur_time; + } +} + +void sh2_sh7604_device::sh2_timer_activate() +{ + int max_delta = 0xfffff; + uint16_t frc; + + m_timer->adjust(attotime::never); + + frc = m_frc; + if(!(m_ftcsr & OCFA)) { + uint16_t delta = m_ocra - frc; + if(delta < max_delta) + max_delta = delta; + } + + if(!(m_ftcsr & OCFB) && (m_ocra <= m_ocrb || !(m_ftcsr & CCLRA))) { + uint16_t delta = m_ocrb - frc; + if(delta < max_delta) + max_delta = delta; + } + + if(!(m_ftcsr & OVF) && !(m_ftcsr & CCLRA)) { + int delta = 0x10000 - frc; + if(delta < max_delta) + max_delta = delta; + } + + if(max_delta != 0xfffff) { + int divider = div_tab[m_frc_tcr & 3]; + if(divider) { + max_delta <<= divider; + m_frc_base = total_cycles(); + m_timer->adjust(cycles_to_attotime(max_delta)); + } else { + logerror("SH2.%s: Timer event in %d cycles of external clock", tag(), max_delta); + } + } +} + +TIMER_CALLBACK_MEMBER( sh2_sh7604_device::sh2_timer_callback ) +{ + uint16_t frc; + + sh2_timer_resync(); + + frc = m_frc; + + if(frc == m_ocrb) + m_ftcsr |= OCFB; + + if(frc == 0x0000) + m_ftcsr |= OVF; + + if(frc == m_ocra) + { + m_ftcsr |= OCFA; + + if(m_ftcsr & CCLRA) + m_frc = 0; + } + + sh2_recalc_irq(); + sh2_timer_activate(); +} + +void sh2_sh7604_device::sh2_wtcnt_recalc() +{ + if (m_wdtimer->expire() != attotime::never) + m_wtcnt = 0x100 - (attotime_to_cycles(m_wdtimer->remaining()) >> wdtclk_tab[m_wtcsr & 7]); +} + +void sh2_sh7604_device::sh2_wdt_activate() +{ + m_wdtimer->adjust(cycles_to_attotime((0x100 - m_wtcnt) << wdtclk_tab[m_wtcsr & 7])); +} + +TIMER_CALLBACK_MEMBER(sh2_sh7604_device::sh2_wdtimer_callback) +{ + m_wtcnt = 0; + if (!(m_wtcsr & 0x40)) // timer mode + { + m_wtcsr |= 0x80; + sh2_recalc_irq(); + sh2_wdt_activate(); + } + else // watchdog mode + { + m_rstcsr |= 0x80; + // TODO reset and /WDTOVF out + } +} + +/* + We have to do DMA on a timer (or at least, in chunks) due to the way some systems use it. + The 32x is a difficult case, they set the SOURCE of the DMA to a FIFO buffer, which at most + can have 8 words in it. Attempting to do an 'instant DMA' in this scenario is impossible + because the game is expecting the 68k of the system to feed data into the FIFO at the same + time as the SH2 is transfering it out via DMA + + There are two ways we can do this + + a) with a high frequency timer (more accurate, but a large performance hit) + + or + + b) in the CPU_EXECUTE loop + + + we're currently doing a) + + b) causes problems with ST-V games + +*/ + + + +void sh2_sh7604_device::sh2_notify_dma_data_available() +{ + //printf("call notify\n"); + + for (int dmach=0;dmach<2;dmach++) + { + //printf("m_dma_timer_active[dmach] %04x\n",m_dma_timer_active[dmach]); + + if (m_dma_timer_active[dmach]==2) // 2 = stalled + { + // printf("resuming stalled dma\n"); + m_dma_timer_active[dmach]=1; + m_dma_current_active_timer[dmach]->adjust(attotime::zero, dmach); + } + } + +} + +void sh2_sh7604_device::sh2_do_dma(int dmach) +{ + uint32_t dmadata; + + uint32_t tempsrc, tempdst; + + if (m_active_dma_count[dmach] > 0) + { + // process current DMA + switch(m_active_dma_size[dmach]) + { + case 0: + { + // we need to know the src / dest ahead of time without changing them + // to allow for the callback to check if we can process the DMA at this + // time (we need to know where we're reading / writing to/from) + + if(m_active_dma_incs[dmach] == 2) + tempsrc = m_active_dma_src[dmach] - 1; + else + tempsrc = m_active_dma_src[dmach]; + + if(m_active_dma_incd[dmach] == 2) + tempdst = m_active_dma_dst[dmach] - 1; + else + tempdst = m_active_dma_dst[dmach]; + + if (!m_dma_fifo_data_available_cb.isnull()) + { + int available = m_dma_fifo_data_available_cb(tempsrc, tempdst, 0, m_active_dma_size[dmach]); + + if (!available) + { + //printf("dma stalled\n"); + m_dma_timer_active[dmach]=2;// mark as stalled + return; + } + } + + //schedule next DMA callback + m_dma_current_active_timer[dmach]->adjust(cycles_to_attotime(2), dmach); + + dmadata = m_program->read_byte(tempsrc); + if (!m_dma_kludge_cb.isnull()) dmadata = m_dma_kludge_cb(tempsrc, tempdst, dmadata, m_active_dma_size[dmach]); + m_program->write_byte(tempdst, dmadata); + + if(m_active_dma_incs[dmach] == 2) + m_active_dma_src[dmach] --; + if(m_active_dma_incd[dmach] == 2) + m_active_dma_dst[dmach] --; + + + if(m_active_dma_incs[dmach] == 1) + m_active_dma_src[dmach] ++; + if(m_active_dma_incd[dmach] == 1) + m_active_dma_dst[dmach] ++; + + m_active_dma_count[dmach] --; + } + break; + case 1: + { + if(m_active_dma_incs[dmach] == 2) + tempsrc = m_active_dma_src[dmach] - 2; + else + tempsrc = m_active_dma_src[dmach]; + + if(m_active_dma_incd[dmach] == 2) + tempdst = m_active_dma_dst[dmach] - 2; + else + tempdst = m_active_dma_dst[dmach]; + + if (!m_dma_fifo_data_available_cb.isnull()) + { + int available = m_dma_fifo_data_available_cb(tempsrc, tempdst, 0, m_active_dma_size[dmach]); + + if (!available) + { + //printf("dma stalled\n"); + m_dma_timer_active[dmach]=2;// mark as stalled + return; + } + } + + //schedule next DMA callback + m_dma_current_active_timer[dmach]->adjust(cycles_to_attotime(2), dmach); + + // check: should this really be using read_word_32 / write_word_32? + dmadata = m_program->read_word(tempsrc); + if (!m_dma_kludge_cb.isnull()) dmadata = m_dma_kludge_cb(tempsrc, tempdst, dmadata, m_active_dma_size[dmach]); + m_program->write_word(tempdst, dmadata); + + if(m_active_dma_incs[dmach] == 2) + m_active_dma_src[dmach] -= 2; + if(m_active_dma_incd[dmach] == 2) + m_active_dma_dst[dmach] -= 2; + + if(m_active_dma_incs[dmach] == 1) + m_active_dma_src[dmach] += 2; + if(m_active_dma_incd[dmach] == 1) + m_active_dma_dst[dmach] += 2; + + m_active_dma_count[dmach] --; + } + break; + case 2: + { + if(m_active_dma_incs[dmach] == 2) + tempsrc = m_active_dma_src[dmach] - 4; + else + tempsrc = m_active_dma_src[dmach]; + + if(m_active_dma_incd[dmach] == 2) + tempdst = m_active_dma_dst[dmach] - 4; + else + tempdst = m_active_dma_dst[dmach]; + + if (!m_dma_fifo_data_available_cb.isnull()) + { + int available = m_dma_fifo_data_available_cb(tempsrc, tempdst, 0, m_active_dma_size[dmach]); + + if (!available) + { + //printf("dma stalled\n"); + m_dma_timer_active[dmach]=2;// mark as stalled + return; + } + } + + //schedule next DMA callback + m_dma_current_active_timer[dmach]->adjust(cycles_to_attotime(2), dmach); + + dmadata = m_program->read_dword(tempsrc); + if (!m_dma_kludge_cb.isnull()) dmadata = m_dma_kludge_cb(tempsrc, tempdst, dmadata, m_active_dma_size[dmach]); + m_program->write_dword(tempdst, dmadata); + + if(m_active_dma_incs[dmach] == 2) + m_active_dma_src[dmach] -= 4; + if(m_active_dma_incd[dmach] == 2) + m_active_dma_dst[dmach] -= 4; + + if(m_active_dma_incs[dmach] == 1) + m_active_dma_src[dmach] += 4; + if(m_active_dma_incd[dmach] == 1) + m_active_dma_dst[dmach] += 4; + + m_active_dma_count[dmach] --; + } + break; + case 3: + { + // shouldn't this really be 4 calls here instead? + + tempsrc = m_active_dma_src[dmach]; + + if(m_active_dma_incd[dmach] == 2) + tempdst = m_active_dma_dst[dmach] - 16; + else + tempdst = m_active_dma_dst[dmach]; + + if (!m_dma_fifo_data_available_cb.isnull()) + { + int available = m_dma_fifo_data_available_cb(tempsrc, tempdst, 0, m_active_dma_size[dmach]); + + if (!available) + { + //printf("dma stalled\n"); + m_dma_timer_active[dmach]=2;// mark as stalled + fatalerror("SH2 dma_callback_fifo_data_available == 0 in unsupported mode\n"); + } + } + + //schedule next DMA callback + m_dma_current_active_timer[dmach]->adjust(cycles_to_attotime(2), dmach); + + dmadata = m_program->read_dword(tempsrc); + if (!m_dma_kludge_cb.isnull()) dmadata = m_dma_kludge_cb(tempsrc, tempdst, dmadata, m_active_dma_size[dmach]); + m_program->write_dword(tempdst, dmadata); + + dmadata = m_program->read_dword(tempsrc+4); + if (!m_dma_kludge_cb.isnull()) dmadata = m_dma_kludge_cb(tempsrc, tempdst, dmadata, m_active_dma_size[dmach]); + m_program->write_dword(tempdst+4, dmadata); + + dmadata = m_program->read_dword(tempsrc+8); + if (!m_dma_kludge_cb.isnull()) dmadata = m_dma_kludge_cb(tempsrc, tempdst, dmadata, m_active_dma_size[dmach]); + m_program->write_dword(tempdst+8, dmadata); + + dmadata = m_program->read_dword(tempsrc+12); + if (!m_dma_kludge_cb.isnull()) dmadata = m_dma_kludge_cb(tempsrc, tempdst, dmadata, m_active_dma_size[dmach]); + m_program->write_dword(tempdst+12, dmadata); + + if(m_active_dma_incd[dmach] == 2) + m_active_dma_dst[dmach] -= 16; + + m_active_dma_src[dmach] += 16; + if(m_active_dma_incd[dmach] == 1) + m_active_dma_dst[dmach] += 16; + + m_active_dma_count[dmach]-=4; + } + break; + } + } + else // the dma is complete + { + // int dma = param & 1; + + // fever soccer uses cycle-stealing mode, resume the CPU now DMA has finished + if (m_active_dma_steal[dmach]) + { + resume(SUSPEND_REASON_HALT ); + } + + + LOG("SH2: DMA %d complete\n", dmach); + m_dmac[dmach].tcr = 0; + m_dmac[dmach].chcr |= 2; + m_dma_timer_active[dmach] = 0; + m_dma_irq[dmach] |= 1; + sh2_recalc_irq(); + + } +} + +TIMER_CALLBACK_MEMBER( sh2_sh7604_device::sh2_dma_current_active_callback ) +{ + int dma = param & 1; + + sh2_do_dma(dma); +} + + +void sh2_sh7604_device::sh2_dmac_check(int dmach) +{ + if(m_dmac[dmach].chcr & m_dmaor & 1) + { + if(!m_dma_timer_active[dmach] && !(m_dmac[dmach].chcr & 2)) + { + m_active_dma_incd[dmach] = (m_dmac[dmach].chcr >> 14) & 3; + m_active_dma_incs[dmach] = (m_dmac[dmach].chcr >> 12) & 3; + m_active_dma_size[dmach] = (m_dmac[dmach].chcr >> 10) & 3; + m_active_dma_steal[dmach] = (m_dmac[dmach].chcr & 0x10); + + if(m_active_dma_incd[dmach] == 3 || m_active_dma_incs[dmach] == 3) + { + logerror("SH2: DMA: bad increment values (%d, %d, %d, %04x)\n", m_active_dma_incd[dmach], m_active_dma_incs[dmach], m_active_dma_size[dmach], m_dmac[dmach].chcr); + return; + } + m_active_dma_src[dmach] = m_dmac[dmach].sar; + m_active_dma_dst[dmach] = m_dmac[dmach].dar; + m_active_dma_count[dmach] = m_dmac[dmach].tcr; + if(!m_active_dma_count[dmach]) + m_active_dma_count[dmach] = 0x1000000; + + LOG("SH2: DMA %d start %x, %x, %x, %04x, %d, %d, %d\n", dmach, m_active_dma_src[dmach], m_active_dma_dst[dmach], m_active_dma_count[dmach], m_dmac[dmach].chcr, m_active_dma_incs[dmach], m_active_dma_incd[dmach], m_active_dma_size[dmach]); + + m_dma_timer_active[dmach] = 1; + + m_active_dma_src[dmach] &= m_am; + m_active_dma_dst[dmach] &= m_am; + + switch(m_active_dma_size[dmach]) + { + case 0: + break; + case 1: + m_active_dma_src[dmach] &= ~1; + m_active_dma_dst[dmach] &= ~1; + break; + case 2: + m_active_dma_src[dmach] &= ~3; + m_active_dma_dst[dmach] &= ~3; + break; + case 3: + m_active_dma_src[dmach] &= ~3; + m_active_dma_dst[dmach] &= ~3; + m_active_dma_count[dmach] &= ~3; + break; + } + + // start DMA timer + + // fever soccer uses cycle-stealing mode, requiring the CPU to be halted + if (m_active_dma_steal[dmach]) + { + //printf("cycle stealing DMA\n"); + suspend(SUSPEND_REASON_HALT, 1 ); + } + + m_dma_current_active_timer[dmach]->adjust(cycles_to_attotime(2), dmach); + } + } + else + { + if(m_dma_timer_active[dmach]) + { + logerror("SH2: DMA %d cancelled in-flight\n", dmach); + //m_dma_complete_timer[dmach]->adjust(attotime::never); + m_dma_current_active_timer[dmach]->adjust(attotime::never, dmach); + + m_dma_timer_active[dmach] = 0; + } + } +} + +/* + * SCI + */ +// TODO: identical to H8 counterpart + +uint8_t sh2_sh7604_device::smr_r() +{ + return m_smr; +} + +void sh2_sh7604_device::smr_w(uint8_t data) +{ + m_smr = data; +} + +uint8_t sh2_sh7604_device::brr_r() +{ + return m_brr; +} + +void sh2_sh7604_device::brr_w(uint8_t data) +{ + m_brr = data; +} + +uint8_t sh2_sh7604_device::scr_r() +{ + return m_scr; +} + +void sh2_sh7604_device::scr_w(uint8_t data) +{ + m_scr = data; +} + +uint8_t sh2_sh7604_device::tdr_r() +{ + return m_tdr; +} + +void sh2_sh7604_device::tdr_w(uint8_t data) +{ + m_tdr = data; + // printf("%c",data & 0xff); +} + +uint8_t sh2_sh7604_device::ssr_r() +{ + // 0x84 is needed by EGWord on Saturn to make it to boot for some reason. + return m_ssr | 0x84; +} + +void sh2_sh7604_device::ssr_w(uint8_t data) +{ + m_ssr = data; +} + +uint8_t sh2_sh7604_device::rdr_r() +{ + return 0; +} + +/* + * FRC + */ + +uint8_t sh2_sh7604_device::tier_r() +{ + return m_tier; +} + +void sh2_sh7604_device::tier_w(uint8_t data) +{ + sh2_timer_resync(); + m_tier = data; + sh2_timer_activate(); + sh2_recalc_irq(); +} + +uint8_t sh2_sh7604_device::ftcsr_r() +{ + // TODO: to be tested + if (!m_ftcsr_read_cb.isnull()) + m_ftcsr_read_cb((((m_tier<<24) | (m_ftcsr<<16)) & 0xffff0000) | m_frc); + + return m_ftcsr; +} + +void sh2_sh7604_device::ftcsr_w(uint8_t data) +{ + uint8_t old; + old = m_ftcsr; + + m_ftcsr = data; + sh2_timer_resync(); + m_ftcsr = (m_ftcsr & ~(ICF|OCFA|OCFB|OVF)) | (old & m_ftcsr & (ICF|OCFA|OCFB|OVF)); + sh2_timer_activate(); + sh2_recalc_irq(); +} + +uint16_t sh2_sh7604_device::frc_r() +{ + sh2_timer_resync(); + return m_frc; +} + +void sh2_sh7604_device::frc_w(offs_t offset, uint16_t data, uint16_t mem_mask) +{ + sh2_timer_resync(); + COMBINE_DATA(&m_frc); + sh2_timer_activate(); + sh2_recalc_irq(); +} + +uint16_t sh2_sh7604_device::ocra_b_r() +{ + return (m_tocr & 0x10) ? m_ocrb : m_ocra; +} + +void sh2_sh7604_device::ocra_b_w(offs_t offset, uint16_t data, uint16_t mem_mask) +{ + sh2_timer_resync(); + if(m_tocr & 0x10) + m_ocrb = (m_ocrb & (~mem_mask)) | (data & mem_mask); + else + m_ocra = (m_ocra & (~mem_mask)) | (data & mem_mask); + sh2_timer_activate(); + sh2_recalc_irq(); +} + +uint8_t sh2_sh7604_device::frc_tcr_r() +{ + return m_frc_tcr & 0x83; +} + +void sh2_sh7604_device::frc_tcr_w(uint8_t data) +{ + sh2_timer_resync(); + m_frc_tcr = data & 0x83; + sh2_timer_activate(); + sh2_recalc_irq(); +} + +uint8_t sh2_sh7604_device::tocr_r() +{ + return (m_tocr & 0x13) | 0xe0; +} + +void sh2_sh7604_device::tocr_w(uint8_t data) +{ + sh2_timer_resync(); + // TODO: output levels A/B (bits 1-0) + m_tocr = data & 0x13; + sh2_timer_activate(); + sh2_recalc_irq(); +} + +uint16_t sh2_sh7604_device::frc_icr_r() +{ + return m_frc_icr; +} + +/* + * INTC + */ + +uint16_t sh2_sh7604_device::intc_icr_r() +{ + // TODO: flip meaning based off NMI edge select bit (NMIE) + uint16_t nmilv = m_nmi_line_state == ASSERT_LINE ? 0 : 0x8000; + return (nmilv) | (m_intc_icr & 0x0101); +} + +void sh2_sh7604_device::intc_icr_w(offs_t offset, uint16_t data, uint16_t mem_mask) +{ + COMBINE_DATA(&m_intc_icr); + m_nmie = bool(BIT(m_intc_icr, 8)); + m_vecmd = bool(BIT(m_intc_icr, 0)); +} + +uint16_t sh2_sh7604_device::ipra_r() +{ + return m_ipra & 0xfff0; +} + +void sh2_sh7604_device::ipra_w(offs_t offset, uint16_t data, uint16_t mem_mask) +{ + COMBINE_DATA(&m_ipra); + m_irq_level.divu = (m_ipra >> 12) & 0xf; + m_irq_level.dmac = (m_ipra >> 8) & 0xf; + m_irq_level.wdt = (m_ipra >> 4) & 0xf; + sh2_recalc_irq(); +} + +uint16_t sh2_sh7604_device::iprb_r() +{ + return m_iprb & 0xff00; +} + +void sh2_sh7604_device::iprb_w(offs_t offset, uint16_t data, uint16_t mem_mask) +{ + COMBINE_DATA(&m_iprb); + m_irq_level.sci = (m_iprb >> 12) & 0xf; + m_irq_level.frc = (m_iprb >> 8) & 0xf; + sh2_recalc_irq(); +} + +uint16_t sh2_sh7604_device::vcra_r() +{ + return m_vcra & 0x7f7f; +} + +void sh2_sh7604_device::vcra_w(offs_t offset, uint16_t data, uint16_t mem_mask) +{ + COMBINE_DATA(&m_vcra); + // ... + sh2_recalc_irq(); +} + +uint16_t sh2_sh7604_device::vcrb_r() +{ + return m_vcrb; +} + +void sh2_sh7604_device::vcrb_w(offs_t offset, uint16_t data, uint16_t mem_mask) +{ + COMBINE_DATA(&m_vcrb); + // ... + sh2_recalc_irq(); +} + +uint16_t sh2_sh7604_device::vcrc_r() +{ + return m_vcrc & 0x7f7f; +} + +void sh2_sh7604_device::vcrc_w(offs_t offset, uint16_t data, uint16_t mem_mask) +{ + COMBINE_DATA(&m_vcrc); + m_irq_vector.fic = (m_vcrc >> 8) & 0x7f; + m_irq_vector.foc = (m_vcrc >> 0) & 0x7f; + sh2_recalc_irq(); +} + +uint16_t sh2_sh7604_device::vcrd_r() +{ + return m_vcrd & 0x7f00; +} + +void sh2_sh7604_device::vcrd_w(offs_t offset, uint16_t data, uint16_t mem_mask) +{ + COMBINE_DATA(&m_vcrd); + m_irq_vector.fov = (m_vcrc >> 8) & 0x7f; + sh2_recalc_irq(); +} + +uint16_t sh2_sh7604_device::vcrwdt_r() +{ + return m_vcrwdt & 0x7f7f; +} + +void sh2_sh7604_device::vcrwdt_w(offs_t offset, uint16_t data, uint16_t mem_mask) +{ + COMBINE_DATA(&m_vcrwdt); + // ... + sh2_recalc_irq(); +} + +uint32_t sh2_sh7604_device::vcrdiv_r() +{ + return m_vcrdiv & 0x7f; +} + +void sh2_sh7604_device::vcrdiv_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + COMBINE_DATA(&m_vcrdiv); + // TODO: unemulated, level is seemingly not documented/settable? + m_irq_vector.divu = data & 0x7f; + sh2_recalc_irq(); +} + +/* + * DIVU + */ + +uint32_t sh2_sh7604_device::dvcr_r() +{ + return (m_divu_ovfie == true ? 2 : 0) | (m_divu_ovf == true ? 1 : 0); +} + +void sh2_sh7604_device::dvcr_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + if(ACCESSING_BITS_0_7) + { + if (data & 1) + m_divu_ovf = false; + if (data & 2) + { + m_divu_ovfie = bool(BIT(data, 1)); + if (m_divu_ovfie == true) + logerror("SH2: unemulated DIVU OVF interrupt enable\n"); + } + sh2_recalc_irq(); + } +} + +uint32_t sh2_sh7604_device::dvsr_r() +{ + return m_dvsr; +} + +void sh2_sh7604_device::dvsr_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + COMBINE_DATA(&m_dvsr); +} + +uint32_t sh2_sh7604_device::dvdnt_r() +{ + return m_dvdntl; +} + +void sh2_sh7604_device::dvdnt_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + COMBINE_DATA(&m_dvdntl); + int32_t a = m_dvdntl; + int32_t b = m_dvsr; + LOG("SH2 div32+mod %d/%d\n", a, b); + if (b) + { + m_dvdntl = a / b; + m_dvdnth = a % b; + } + else + { + m_divu_ovf = true; + m_dvdntl = 0x7fffffff; + m_dvdnth = 0x7fffffff; + sh2_recalc_irq(); + } +} + +uint32_t sh2_sh7604_device::dvdnth_r() +{ + return m_dvdnth; +} + +uint32_t sh2_sh7604_device::dvdntl_r() +{ + return m_dvdntl; +} + +void sh2_sh7604_device::dvdnth_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + COMBINE_DATA(&m_dvdnth); +} + +void sh2_sh7604_device::dvdntl_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + COMBINE_DATA(&m_dvdntl); + int64_t a = m_dvdntl | ((uint64_t)(m_dvdnth) << 32); + int64_t b = (int32_t)m_dvsr; + LOG("SH2 div64+mod %d/%d\n", a, b); + if (b) + { + int64_t q = a / b; + if (q != (int32_t)q) + { + m_divu_ovf = true; + m_dvdntl = 0x7fffffff; + m_dvdnth = 0x7fffffff; + sh2_recalc_irq(); + } + else + { + m_dvdntl = q; + m_dvdnth = a % b; + } + } + else + { + m_divu_ovf = true; + m_dvdntl = 0x7fffffff; + m_dvdnth = 0x7fffffff; + sh2_recalc_irq(); + } +} + +/* + * WTC + */ + +uint16_t sh2_sh7604_device::wtcnt_r() +{ + sh2_wtcnt_recalc(); + return ((m_wtcsr | 0x18) << 8) | (m_wtcnt & 0xff); +} + +uint16_t sh2_sh7604_device::rstcsr_r() +{ + return (m_rstcsr & 0xe0) | 0x1f; +} + +void sh2_sh7604_device::wtcnt_w(offs_t offset, uint16_t data, uint16_t mem_mask) +{ + COMBINE_DATA(&m_wtcw[0]); + switch (m_wtcw[0] & 0xff00) + { + case 0x5a00: + m_wtcnt = m_wtcw[0] & 0xff; + if (m_wtcsr & 0x20) + sh2_wdt_activate(); + break; + case 0xa500: + /* + WTCSR + x--- ---- Overflow in IT mode + -x-- ---- Timer mode (0: IT 1: watchdog) + --x- ---- Timer enable + ---1 1--- + ---- -xxx Clock select + */ + sh2_wtcnt_recalc(); + m_wtcsr &= m_wtcw[0] & 0x80; + m_wtcsr |= m_wtcw[0] & 0x7f; + if (m_wtcsr & 0x20) + sh2_wdt_activate(); + else + { + m_wtcnt = 0; + m_wdtimer->adjust(attotime::never); + } + sh2_recalc_irq(); + break; + } +} + +void sh2_sh7604_device::rstcsr_w(offs_t offset, uint16_t data, uint16_t mem_mask) +{ + COMBINE_DATA(&m_wtcw[1]); + switch (m_wtcw[1] & 0xff00) + { + case 0xa500: + // clear WOVF flag + if ((m_wtcw[1] & 0x80) == 0) + m_rstcsr &= 0x7f; + break; + case 0x5a00: + m_rstcsr = (m_rstcsr & 0x80) | (m_wtcw[1] & 0x60); + break; + } +} + +uint16_t sh2_sh7604_device::fmr_sbycr_r() +{ + return m_sbycr; +} + +void sh2_sh7604_device::fmr_sbycr_w(offs_t offset, uint16_t data, uint16_t mem_mask) +{ + switch (mem_mask) + { + case 0xff00: // FMR 8bit + logerror("SH2 set clock multiplier x%d\n", 1 << ((data >> 8) & 3)); + break; + case 0xffff: // FMR 16bit + // SH7604 docs says FMR register must be set using 8-bit write, however at practice 16-bit works too. + // has been verified for CPS3 custom SH2, SH7604 and SH7095 (clock multiplier feature is not officially documented for SH7095). + logerror("SH2 set clock multiplier x%d\n", 1 << (data & 3)); + break; + case 0x00ff: // SBYCR + m_sbycr = data; + if (data & 0x1f) + logerror("SH2 module stop selected %02x\n", data); + break; + } +} + +uint8_t sh2_sh7604_device::ccr_r() +{ + return m_ccr & ~0x30; +} + +void sh2_sh7604_device::ccr_w(uint8_t data) +{ + /* + xx-- ---- Way 0/1 + ---x ---- Cache Purge (CP), write only + ---- x--- Two-Way Mode (TW) + ---- -x-- Data Replacement Disable (OD) + ---- --x- Instruction Replacement Disable (ID) + ---- ---x Cache Enable (CE) + */ + m_ccr = data; +} + +uint32_t sh2_sh7604_device::bcr1_r() +{ + return (m_bcr1 & ~0xe008) | (m_is_slave ? 0x8000 : 0); +} + +void sh2_sh7604_device::bcr1_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + COMBINE_DATA(&m_bcr1); +} + +uint32_t sh2_sh7604_device::bcr2_r() +{ + return m_bcr2; +} + +void sh2_sh7604_device::bcr2_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + COMBINE_DATA(&m_bcr2); +} + +uint32_t sh2_sh7604_device::wcr_r() +{ + return m_wcr; +} + +void sh2_sh7604_device::wcr_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + COMBINE_DATA(&m_wcr); +} + +uint32_t sh2_sh7604_device::mcr_r() +{ + return m_mcr & ~0x103; +} + +void sh2_sh7604_device::mcr_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + COMBINE_DATA(&m_mcr); +} + +uint32_t sh2_sh7604_device::rtcsr_r() +{ + return m_rtcsr & 0xf8; +} + +void sh2_sh7604_device::rtcsr_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + COMBINE_DATA(&m_rtcsr); +} + +uint32_t sh2_sh7604_device::rtcnt_r() +{ + return m_rtcnt & 0xff; +} + +void sh2_sh7604_device::rtcnt_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + COMBINE_DATA(&m_rtcnt); + m_rtcnt &= 0xff; +} + +uint32_t sh2_sh7604_device::rtcor_r() +{ + return m_rtcor & 0xff; +} + +void sh2_sh7604_device::rtcor_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + COMBINE_DATA(&m_rtcor); + m_rtcor &= 0xff; +} + +void sh2_sh7604_device::set_frt_input(int state) +{ + if(m_frt_input == state) { + return; + } + + m_frt_input = state; + + if(m_frc_tcr & 0x80) { + if(state == CLEAR_LINE) { + return; + } + } else { + if(state == ASSERT_LINE) { + return; + } + } + + sh2_timer_resync(); + m_frc_icr = m_frc; + m_ftcsr |= ICF; + //logerror("SH2.%s: ICF activated (%x)\n", tag(), m_sh2_state->pc & AM); + sh2_recalc_irq(); +} + +void sh2_sh7604_device::sh2_recalc_irq() +{ + int irq = 0, vector = -1; + int level; + + // Timer irqs + if (m_tier & m_ftcsr & (ICF|OCFA|OCFB|OVF)) + { + level = (m_irq_level.frc & 15); + if (level > irq) + { + int mask = m_tier & m_ftcsr; + irq = level; + if(mask & ICF) + vector = m_irq_vector.fic & 0x7f; + else if(mask & (OCFA|OCFB)) + vector = m_irq_vector.foc & 0x7f; + else + vector = m_irq_vector.fov & 0x7f; + } + } + + // WDT irqs + if (m_wtcsr & 0x80) + { + level = m_irq_level.wdt & 15; + if (level > irq) + { + irq = level; + vector = (m_vcrwdt >> 8) & 0x7f; + } + } + + // DMA irqs + if((m_dmac[0].chcr & 6) == 6 && m_dma_irq[0]) { + level = m_irq_level.dmac & 15; + if(level > irq) { + irq = level; + m_dma_irq[0] &= ~1; + vector = m_irq_vector.dmac[0] & 0x7f; + } + } + else if((m_dmac[1].chcr & 6) == 6 && m_dma_irq[1]) { + level = m_irq_level.dmac & 15; + if(level > irq) { + irq = level; + m_dma_irq[1] &= ~1; + vector = m_irq_vector.dmac[1] & 0x7f; + } + } + + m_sh2_state->internal_irq_level = irq; + m_internal_irq_vector = vector; + m_test_irq = 1; +} + +/* + * DMAC + */ + +template +uint32_t sh2_sh7604_device::vcrdma_r() +{ + return m_vcrdma[Channel] & 0x7f; +} + +template +void sh2_sh7604_device::vcrdma_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + COMBINE_DATA(&m_vcrdma[Channel]); + m_irq_vector.dmac[Channel] = m_vcrdma[Channel] & 0x7f; + sh2_recalc_irq(); +} + +template +uint8_t sh2_sh7604_device::drcr_r() { + return m_dmac[Channel].drcr & 3; +} + +template +void sh2_sh7604_device::drcr_w(uint8_t data) +{ + m_dmac[Channel].drcr = data & 3; + sh2_recalc_irq(); +} + +template +uint32_t sh2_sh7604_device::sar_r() +{ + return m_dmac[Channel].sar; +} + +template +void sh2_sh7604_device::sar_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + COMBINE_DATA(&m_dmac[Channel].sar); +} + +template +uint32_t sh2_sh7604_device::dar_r() +{ + return m_dmac[Channel].dar; +} + +template +void sh2_sh7604_device::dar_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + COMBINE_DATA(&m_dmac[Channel].dar); +} + +template +uint32_t sh2_sh7604_device::dmac_tcr_r() +{ + return m_dmac[Channel].tcr; +} + +template +void sh2_sh7604_device::dmac_tcr_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + COMBINE_DATA(&m_dmac[Channel].tcr); + m_dmac[Channel].tcr &= 0xffffff; +} + +template +uint32_t sh2_sh7604_device::chcr_r() +{ + return m_dmac[Channel].chcr; +} + +template +void sh2_sh7604_device::chcr_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + uint32_t old; + old = m_dmac[Channel].chcr; + COMBINE_DATA(&m_dmac[Channel].chcr); + m_dmac[Channel].chcr = (data & ~2) | (old & m_dmac[Channel].chcr & 2); + sh2_dmac_check(Channel); +} + +uint32_t sh2_sh7604_device::dmaor_r() +{ + return m_dmaor & 0xf; +} + +void sh2_sh7604_device::dmaor_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + if(ACCESSING_BITS_0_7) + { + uint8_t old; + old = m_dmaor & 0xf; + m_dmaor = (data & ~6) | (old & m_dmaor & 6); // TODO: should this be old & data & 6? bug? + sh2_dmac_check(0); + sh2_dmac_check(1); + } +} diff --git a/src/devices/cpu/sh/sh7604.h b/src/devices/cpu/sh/sh7604.h new file mode 100644 index 00000000000..deb47dfd24f --- /dev/null +++ b/src/devices/cpu/sh/sh7604.h @@ -0,0 +1,259 @@ +// license:BSD-3-Clause +// copyright-holders:Juergen Buchmueller, R. Belmont + +#ifndef MAME_CPU_SH_SH7604_H +#define MAME_CPU_SH_SH7604_H + +#pragma once + +#include "sh2.h" + +#define SH2_DMA_KLUDGE_CB(name) int name(uint32_t src, uint32_t dst, uint32_t data, int size) +#define SH2_DMA_FIFO_DATA_AVAILABLE_CB(name) int name(uint32_t src, uint32_t dst, uint32_t data, int size) +#define SH2_FTCSR_READ_CB(name) void name(uint32_t data) + + +class sh2_sh7604_device : public sh2_device +{ +public: + typedef device_delegate dma_kludge_delegate; + typedef device_delegate dma_fifo_data_available_delegate; + typedef device_delegate ftcsr_read_delegate; + + sh2_sh7604_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + void set_is_slave(int slave) { m_is_slave = slave; } + + template void set_dma_kludge_callback(T &&... args) { m_dma_kludge_cb.set(std::forward(args)...); } + + template void set_dma_fifo_data_available_callback(T &&... args) { m_dma_fifo_data_available_cb.set(std::forward(args)...); } + + template void set_ftcsr_read_callback(T &&... args) { m_ftcsr_read_cb.set(std::forward(args)...); } + + void sh2_notify_dma_data_available(); + +protected: + sh2_sh7604_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int cpu_type,address_map_constructor internal_map, int addrlines); + + virtual void device_start() override; + virtual void device_reset() override; + + virtual void sh2_exception(const char *message, int irqline) override; + + uint32_t m_test_irq; + int m_internal_irq_vector; + +private: + enum + { + ICF = 0x80, + OCFA = 0x08, + OCFB = 0x04, + OVF = 0x02, + CCLRA = 0x01 + }; + + void sh7604_map(address_map &map); + + uint32_t sh2_internal_a5(); + + // SCI + uint8_t smr_r(); + void smr_w(uint8_t data); + uint8_t brr_r(); + void brr_w(uint8_t data); + uint8_t scr_r(); + void scr_w(uint8_t data); + uint8_t tdr_r(); + void tdr_w(uint8_t data); + uint8_t ssr_r(); + void ssr_w(uint8_t data); + uint8_t rdr_r(); + + // FRT / FRC + uint8_t tier_r(); + void tier_w(uint8_t data); + uint16_t frc_r(); + void frc_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + uint8_t ftcsr_r(); + void ftcsr_w(uint8_t data); + uint16_t ocra_b_r(); + void ocra_b_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + uint8_t frc_tcr_r(); + void frc_tcr_w(uint8_t data); + uint8_t tocr_r(); + void tocr_w(uint8_t data); + uint16_t frc_icr_r(); + + // INTC + uint16_t ipra_r(); + void ipra_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + uint16_t iprb_r(); + void iprb_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + uint16_t vcra_r(); + void vcra_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + uint16_t vcrb_r(); + void vcrb_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + uint16_t vcrc_r(); + void vcrc_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + uint16_t vcrd_r(); + void vcrd_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + uint16_t vcrwdt_r(); + void vcrwdt_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + uint32_t vcrdiv_r(); + void vcrdiv_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); + uint16_t intc_icr_r(); + void intc_icr_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + + // DIVU + uint32_t dvsr_r(); + void dvsr_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); + uint32_t dvdnt_r(); + void dvdnt_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); + uint32_t dvdnth_r(); + void dvdnth_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); + uint32_t dvdntl_r(); + void dvdntl_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); + + uint32_t dvcr_r(); + void dvcr_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); + + // DMAC + template uint32_t vcrdma_r(); + template void vcrdma_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); + template uint8_t drcr_r(); + template void drcr_w(uint8_t data); + template uint32_t sar_r(); + template void sar_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); + template uint32_t dar_r(); + template void dar_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); + template uint32_t dmac_tcr_r(); + template void dmac_tcr_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); + template uint32_t chcr_r(); + template void chcr_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); + uint32_t dmaor_r(); + void dmaor_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); + + // WTC + uint16_t wtcnt_r(); + void wtcnt_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + uint16_t rstcsr_r(); + void rstcsr_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + + // misc + uint16_t fmr_sbycr_r(); + void fmr_sbycr_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + uint8_t ccr_r(); + void ccr_w(uint8_t data); + + // BSC + uint32_t bcr1_r(); + void bcr1_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); + uint32_t bcr2_r(); + void bcr2_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); + uint32_t wcr_r(); + void wcr_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); + uint32_t mcr_r(); + void mcr_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); + uint32_t rtcsr_r(); + void rtcsr_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); + uint32_t rtcor_r(); + void rtcor_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); + uint32_t rtcnt_r(); + void rtcnt_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); + + virtual void set_frt_input(int state) override; + + // SCI + uint8_t m_smr, m_brr, m_scr, m_tdr, m_ssr; + + // FRT / FRC + uint8_t m_tier, m_ftcsr, m_frc_tcr, m_tocr; + uint16_t m_frc; + uint16_t m_ocra, m_ocrb, m_frc_icr; + + // INTC + struct { + uint8_t frc; + uint8_t sci; + uint8_t divu; + uint8_t dmac; + uint8_t wdt; + } m_irq_level; + + struct { + uint8_t fic; + uint8_t foc; + uint8_t fov; + uint8_t divu; + uint8_t dmac[2]; + } m_irq_vector; + + uint16_t m_ipra, m_iprb; + uint16_t m_vcra, m_vcrb, m_vcrc, m_vcrd, m_vcrwdt, m_vcrdiv, m_intc_icr, m_vcrdma[2]; + bool m_vecmd, m_nmie; + + // DIVU + bool m_divu_ovf, m_divu_ovfie; + uint32_t m_dvsr, m_dvdntl, m_dvdnth; + + // WTC + uint8_t m_wtcnt, m_wtcsr; + uint8_t m_rstcsr; + uint16_t m_wtcw[2]; + + // DMAC + struct { + uint8_t drcr; + uint32_t sar; + uint32_t dar; + uint32_t tcr; + uint32_t chcr; + } m_dmac[2]; + uint8_t m_dmaor; + + // misc + uint8_t m_sbycr, m_ccr; + + // BSC + uint32_t m_bcr1, m_bcr2, m_wcr, m_mcr, m_rtcsr, m_rtcor, m_rtcnt; + + uint64_t m_frc_base; + + int m_frt_input; + + emu_timer *m_timer; + emu_timer *m_wdtimer; + emu_timer *m_dma_current_active_timer[2]; + int m_dma_timer_active[2]; + uint8_t m_dma_irq[2]; + + int m_active_dma_incs[2]; + int m_active_dma_incd[2]; + int m_active_dma_size[2]; + int m_active_dma_steal[2]; + uint32_t m_active_dma_src[2]; + uint32_t m_active_dma_dst[2]; + uint32_t m_active_dma_count[2]; + + int m_is_slave; + + dma_kludge_delegate m_dma_kludge_cb; + dma_fifo_data_available_delegate m_dma_fifo_data_available_cb; + ftcsr_read_delegate m_ftcsr_read_cb; + + TIMER_CALLBACK_MEMBER( sh2_timer_callback ); + TIMER_CALLBACK_MEMBER( sh2_wdtimer_callback ); + TIMER_CALLBACK_MEMBER( sh2_dma_current_active_callback ); + void sh2_timer_resync(); + void sh2_timer_activate(); + void sh2_wtcnt_recalc(); + void sh2_wdt_activate(); + void sh2_do_dma(int dmach); + void sh2_dmac_check(int dma); + void sh2_recalc_irq(); +}; + +DECLARE_DEVICE_TYPE(SH2_SH7604, sh2_sh7604_device) + +#endif // MAME_CPU_SH_SH7604_H diff --git a/src/devices/cpu/sh/sh7604_bus.h b/src/devices/cpu/sh/sh7604_bus.h index 9d2915b6b6b..8189e6d2bf0 100644 --- a/src/devices/cpu/sh/sh7604_bus.h +++ b/src/devices/cpu/sh/sh7604_bus.h @@ -6,8 +6,8 @@ ***************************************************************************/ -#ifndef MAME_CPU_SH2_SH7604_BUS_H -#define MAME_CPU_SH2_SH7604_BUS_H +#ifndef MAME_CPU_SH_SH7604_BUS_H +#define MAME_CPU_SH_SH7604_BUS_H #pragma once @@ -67,4 +67,4 @@ private: // device type definition DECLARE_DEVICE_TYPE(SH7604_BUS, sh7604_bus_device) -#endif // MAME_CPU_SH2_SH7604_BUS_H +#endif // MAME_CPU_SH_SH7604_BUS_H diff --git a/src/devices/cpu/sh/sh7604_sci.h b/src/devices/cpu/sh/sh7604_sci.h index b77630db074..ae4e0155acb 100644 --- a/src/devices/cpu/sh/sh7604_sci.h +++ b/src/devices/cpu/sh/sh7604_sci.h @@ -6,8 +6,8 @@ ***************************************************************************/ -#ifndef MAME_CPU_SH2_SH7604_SCI_H -#define MAME_CPU_SH2_SH7604_SCI_H +#ifndef MAME_CPU_SH_SH7604_SCI_H +#define MAME_CPU_SH_SH7604_SCI_H #pragma once @@ -73,4 +73,4 @@ private: // device type definition DECLARE_DEVICE_TYPE(SH7604_SCI, sh7604_sci_device) -#endif // MAME_CPU_SH2_SH7604_SCI_H +#endif // MAME_CPU_SH_SH7604_SCI_H diff --git a/src/devices/cpu/sh/sh_fe.cpp b/src/devices/cpu/sh/sh_fe.cpp index 6a808429200..761cd79d342 100644 --- a/src/devices/cpu/sh/sh_fe.cpp +++ b/src/devices/cpu/sh/sh_fe.cpp @@ -10,7 +10,6 @@ #include "emu.h" #include "sh2.h" -#include "sh2comn.h" #include "cpu/drcfe.h" diff --git a/src/devices/machine/sega_scu.h b/src/devices/machine/sega_scu.h index 23662bb898b..ec09ef263fa 100644 --- a/src/devices/machine/sega_scu.h +++ b/src/devices/machine/sega_scu.h @@ -11,7 +11,7 @@ #pragma once -#include "cpu/sh/sh2.h" +#include "cpu/sh/sh7604.h" #include "cpu/scudsp/scudsp.h" #define IRQ_VBLANK_IN 1 << 0 @@ -84,7 +84,7 @@ private: bool m_t1md; bool m_tenb; - required_device m_hostcpu; + required_device m_hostcpu; address_space *m_hostspace; void test_pending_irqs(); diff --git a/src/mame/capcom/cps3.cpp b/src/mame/capcom/cps3.cpp index 26d7bdba071..feddaa2d0cf 100644 --- a/src/mame/capcom/cps3.cpp +++ b/src/mame/capcom/cps3.cpp @@ -582,8 +582,6 @@ Hardware registers info #include "emu.h" #include "cdrom.h" -#include "cpu/sh/sh2.h" -#include "machine/intelfsh.h" #include "machine/nvram.h" #include "cps3.h" #include "bus/nscsi/cd.h" @@ -2491,7 +2489,7 @@ void cps3_state::simm6_128mbit(machine_config &config) void cps3_state::cps3(machine_config &config) { /* basic machine hardware */ - SH2(config, m_maincpu, 6250000*4); // external clock is 6.25 Mhz, it sets the internal multiplier to 4x (this should probably be handled in the core..) + SH2_SH7604(config, m_maincpu, 6250000*4); // external clock is 6.25 Mhz, it sets the internal multiplier to 4x (this should probably be handled in the core..) m_maincpu->set_addrmap(AS_PROGRAM, &cps3_state::cps3_map); m_maincpu->set_addrmap(AS_OPCODES, &cps3_state::decrypted_opcodes_map); m_maincpu->set_dma_kludge_callback(FUNC(cps3_state::dma_callback)); diff --git a/src/mame/capcom/cps3.h b/src/mame/capcom/cps3.h index 51d4ccc7e16..b8818ea063f 100644 --- a/src/mame/capcom/cps3.h +++ b/src/mame/capcom/cps3.h @@ -12,7 +12,7 @@ ****************************************************************************/ #include "machine/intelfsh.h" -#include "cpu/sh/sh2.h" +#include "cpu/sh/sh7604.h" #include "cps3_a.h" #include "machine/timer.h" #include "emupal.h" @@ -82,7 +82,7 @@ protected: void copy_from_nvram(); u32 m_current_table_address; - required_device m_maincpu; + required_device m_maincpu; required_device m_gfxdecode; required_device m_palette; required_device m_cps3sound; diff --git a/src/mame/casio/casloopy.cpp b/src/mame/casio/casloopy.cpp index 15dfd48a50d..1e39f0bf3ac 100644 --- a/src/mame/casio/casloopy.cpp +++ b/src/mame/casio/casloopy.cpp @@ -149,7 +149,7 @@ PCB 'Z545-1 A240570-1' ******************************************************************************/ #include "emu.h" -#include "cpu/sh/sh2.h" +#include "cpu/sh/sh7021.h" #include "bus/generic/slot.h" #include "bus/generic/carts.h" #include "emupal.h" @@ -512,7 +512,7 @@ DEVICE_IMAGE_LOAD_MEMBER( casloopy_state::cart_load ) void casloopy_state::casloopy(machine_config &config) { /* basic machine hardware */ - SH2A(config, m_maincpu, 8000000); + SH2A_SH7021(config, m_maincpu, 8000000); m_maincpu->set_addrmap(AS_PROGRAM, &casloopy_state::casloopy_map); // v60_device &subcpu(V60(config, "subcpu", 8000000)); diff --git a/src/mame/dataeast/deco_mlc.cpp b/src/mame/dataeast/deco_mlc.cpp index 49a588583d7..b7a08db687e 100644 --- a/src/mame/dataeast/deco_mlc.cpp +++ b/src/mame/dataeast/deco_mlc.cpp @@ -113,7 +113,7 @@ #include "deco156_m.h" #include "machine/eepromser.h" #include "cpu/arm/arm.h" -#include "cpu/sh/sh2.h" +#include "cpu/sh/sh7604.h" #include "speaker.h" #include @@ -539,7 +539,7 @@ void deco_mlc_state::machine_reset() void deco_mlc_state::avengrgs(machine_config &config) { // basic machine hardware - SH2(config, m_maincpu, 42000000/2); // 21 MHz clock confirmed on real board + SH2_SH7604(config, m_maincpu, 42000000/2); // 21 MHz clock confirmed on real board m_maincpu->set_addrmap(AS_PROGRAM, &deco_mlc_state::avengrgs_map); EEPROM_93C46_16BIT(config, m_eeprom); // Actually 93c45 @@ -1014,16 +1014,16 @@ u32 deco_mlc_state::avengrgs_speedup_r() void deco_mlc_state::init_avengrgs() { // init options - dynamic_cast(m_maincpu.target())->sh2drc_set_options(SH2DRC_FASTEST_OPTIONS); + dynamic_cast(m_maincpu.target())->sh2drc_set_options(SH2DRC_FASTEST_OPTIONS); // set up speed cheat - dynamic_cast(m_maincpu.target())->sh2drc_add_pcflush(0x3234); - dynamic_cast(m_maincpu.target())->sh2drc_add_pcflush(0x32dc); + dynamic_cast(m_maincpu.target())->sh2drc_add_pcflush(0x3234); + dynamic_cast(m_maincpu.target())->sh2drc_add_pcflush(0x32dc); - dynamic_cast(m_maincpu.target())->sh2drc_add_fastram(0x0100000, 0x01088ff, 0, &m_mainram[0]); - dynamic_cast(m_maincpu.target())->sh2drc_add_fastram(0x0108a00, 0x011ffff, 0, &m_mainram[0x8a00 / 4]); - dynamic_cast(m_maincpu.target())->sh2drc_add_fastram(0x0200080, 0x02000ff, 0, &m_clip_ram[0]); - dynamic_cast(m_maincpu.target())->sh2drc_add_fastram(0x0280000, 0x029ffff, 0, &m_vram[0]); + dynamic_cast(m_maincpu.target())->sh2drc_add_fastram(0x0100000, 0x01088ff, 0, &m_mainram[0]); + dynamic_cast(m_maincpu.target())->sh2drc_add_fastram(0x0108a00, 0x011ffff, 0, &m_mainram[0x8a00 / 4]); + dynamic_cast(m_maincpu.target())->sh2drc_add_fastram(0x0200080, 0x02000ff, 0, &m_clip_ram[0]); + dynamic_cast(m_maincpu.target())->sh2drc_add_fastram(0x0280000, 0x029ffff, 0, &m_vram[0]); m_irqLevel = 1; m_maincpu->space(AS_PROGRAM).install_read_handler(0x01089a0, 0x01089a3, read32smo_delegate(*this, FUNC(deco_mlc_state::avengrgs_speedup_r))); diff --git a/src/mame/kaneko/suprnova.cpp b/src/mame/kaneko/suprnova.cpp index d44d2763dec..1b8ab507bac 100644 --- a/src/mame/kaneko/suprnova.cpp +++ b/src/mame/kaneko/suprnova.cpp @@ -149,7 +149,6 @@ NEP-16 #include "emu.h" #include "suprnova.h" -#include "cpu/sh/sh2.h" #include "machine/msm6242.h" #include "machine/nvram.h" #include "sound/ymz280b.h" @@ -764,7 +763,7 @@ GFXDECODE_END // XTALs : 28.636MHz, 33.3333MHz, 21.504MHz void skns_state::skns(machine_config &config) { - SH2(config, m_maincpu, XTAL(28'636'000)); + SH2_SH7604(config, m_maincpu, XTAL(28'636'000)); m_maincpu->set_addrmap(AS_PROGRAM, &skns_state::skns_map); TIMER(config, "scantimer").configure_scanline(FUNC(skns_state::irq), "screen", 0, 1); diff --git a/src/mame/kaneko/suprnova.h b/src/mame/kaneko/suprnova.h index fd41508bf51..8756f420be8 100644 --- a/src/mame/kaneko/suprnova.h +++ b/src/mame/kaneko/suprnova.h @@ -7,7 +7,7 @@ #include "sknsspr.h" -#include "cpu/sh/sh2.h" +#include "cpu/sh/sh7604.h" #include "machine/timer.h" #include "emupal.h" @@ -84,7 +84,7 @@ private: uint8_t disconnect = 0; }; - required_device m_maincpu; + required_device m_maincpu; required_device m_spritegen; required_device m_gfxdecode; required_device m_palette; diff --git a/src/mame/misc/hideseek.cpp b/src/mame/misc/hideseek.cpp index f8012e54546..8c90acd6532 100644 --- a/src/mame/misc/hideseek.cpp +++ b/src/mame/misc/hideseek.cpp @@ -27,7 +27,7 @@ Other stuff: NEC D4992 (RTC?) and xtal possibly 32.768kHz, 3V coin battery, 93L4 #include "emu.h" -#include "cpu/sh/sh2.h" +#include "cpu/sh/sh7604.h" #include "emupal.h" #include "screen.h" #include "speaker.h" @@ -108,7 +108,7 @@ void hideseek_state::hideseek_palette(palette_device &palette) const void hideseek_state::hideseek(machine_config &config) { /* basic machine hardware */ - SH2(config, m_maincpu, 7372800 * 4); + SH2_SH7604(config, m_maincpu, 7372800 * 4); m_maincpu->set_addrmap(AS_PROGRAM, &hideseek_state::mem_map); // TIMER(config, "scantimer").configure_scanline(FUNC(hideseek_state::hideseek_scanline), "screen", 0, 1); diff --git a/src/mame/namco/namcos23.cpp b/src/mame/namco/namcos23.cpp index e8a5a7db2df..01efbf959a2 100644 --- a/src/mame/namco/namcos23.cpp +++ b/src/mame/namco/namcos23.cpp @@ -1451,7 +1451,7 @@ It can also be used with Final Furlong when wired correctly. #include "cpu/h8/h83002.h" #include "cpu/h8/h83337.h" #include "cpu/mips/mips3.h" -#include "cpu/sh/sh2.h" +#include "cpu/sh/sh7604.h" #include "namco_settings.h" #include "machine/nvram.h" #include "machine/rtc4543.h" @@ -1764,7 +1764,7 @@ private: required_shared_ptr m_charram; required_shared_ptr m_textram; optional_shared_ptr m_czattr; - optional_device m_gmen_sh2; + optional_device m_gmen_sh2; optional_shared_ptr m_gmen_sh2_shared; required_device m_gfxdecode; optional_ioport m_lightx; @@ -3982,7 +3982,7 @@ void namcos23_state::gmen(machine_config &config) /* basic machine hardware */ m_maincpu->set_addrmap(AS_PROGRAM, &namcos23_state::gmen_mips_map); - SH2(config, m_gmen_sh2, XTAL(28'700'000)); + SH2_SH7604(config, m_gmen_sh2, XTAL(28'700'000)); m_gmen_sh2->set_addrmap(AS_PROGRAM, &namcos23_state::gmen_sh2_map); MCFG_MACHINE_RESET_OVERRIDE(namcos23_state,gmen) diff --git a/src/mame/psikyo/psikyo4.cpp b/src/mame/psikyo/psikyo4.cpp index 66c417603f2..90db575a8a7 100644 --- a/src/mame/psikyo/psikyo4.cpp +++ b/src/mame/psikyo/psikyo4.cpp @@ -605,7 +605,7 @@ void psikyo4_state::machine_reset() void psikyo4_state::ps4big(machine_config &config) { /* basic machine hardware */ - SH2(config, m_maincpu, 57272700/2); + SH2_SH7604(config, m_maincpu, 57272700/2); m_maincpu->set_addrmap(AS_PROGRAM, &psikyo4_state::ps4_map); m_maincpu->set_vblank_int("lscreen", FUNC(psikyo4_state::interrupt)); diff --git a/src/mame/psikyo/psikyo4.h b/src/mame/psikyo/psikyo4.h index de8eff7b0fa..a3bf964c86e 100644 --- a/src/mame/psikyo/psikyo4.h +++ b/src/mame/psikyo/psikyo4.h @@ -6,7 +6,7 @@ *************************************************************************/ -#include "cpu/sh/sh2.h" +#include "cpu/sh/sh7604.h" #include "sound/ymopl.h" #include "machine/eepromser.h" #include "emupal.h" @@ -57,7 +57,7 @@ private: double m_oldbrt[2]{}; /* devices */ - required_device m_maincpu; + required_device m_maincpu; required_device m_eeprom; required_device m_gfxdecode; required_device_array m_palette; diff --git a/src/mame/psikyo/psikyosh.cpp b/src/mame/psikyo/psikyosh.cpp index 926781c0ab9..a0f14379db9 100644 --- a/src/mame/psikyo/psikyosh.cpp +++ b/src/mame/psikyo/psikyosh.cpp @@ -335,7 +335,6 @@ ROM Usage #include "emu.h" #include "psikyosh.h" -#include "cpu/sh/sh2.h" #include "machine/eepromser.h" #include "machine/watchdog.h" #include "sound/ymopl.h" @@ -838,7 +837,7 @@ void psikyosh_state::machine_start() void psikyosh_state::psikyo3v1(machine_config &config) { /* basic machine hardware */ - SH2(config, m_maincpu, MASTER_CLOCK/2); + SH2_SH7604(config, m_maincpu, MASTER_CLOCK/2); m_maincpu->set_addrmap(AS_PROGRAM, &psikyosh_state::ps3v1_map); m_maincpu->set_vblank_int("screen", FUNC(psikyosh_state::interrupt)); diff --git a/src/mame/psikyo/psikyosh.h b/src/mame/psikyo/psikyosh.h index afa44509e52..542d2de493a 100644 --- a/src/mame/psikyo/psikyosh.h +++ b/src/mame/psikyo/psikyosh.h @@ -6,7 +6,7 @@ #pragma once #include "machine/eepromser.h" -#include "cpu/sh/sh2.h" +#include "cpu/sh/sh7604.h" #include "emupal.h" #include "screen.h" @@ -88,7 +88,7 @@ private: const struct sprite_t *m_sprite_end; /* devices */ - required_device m_maincpu; + required_device m_maincpu; required_device m_eeprom; required_device m_gfxdecode; required_device m_screen; diff --git a/src/mame/sega/coolridr.cpp b/src/mame/sega/coolridr.cpp index a393076a53e..64c579fc130 100644 --- a/src/mame/sega/coolridr.cpp +++ b/src/mame/sega/coolridr.cpp @@ -283,7 +283,8 @@ to the same bank as defined through A20. #include "emu.h" #include "cpu/m68000/m68000.h" -#include "cpu/sh/sh2.h" +#include "cpu/sh/sh7032.h" +#include "cpu/sh/sh7604.h" #include "machine/nvram.h" #include "machine/timer.h" #include "315_5649.h" @@ -350,8 +351,8 @@ public: uint32_t m_clipvals[2][3]; uint8_t m_clipblitterMode[2]; // hack - required_device m_maincpu; - required_device m_subcpu; + required_device m_maincpu; + required_device m_subcpu; required_device m_soundcpu; //required_device m_dmac; @@ -3227,14 +3228,14 @@ void coolridr_state::scsp2_to_sh1_irq(int state) void coolridr_state::coolridr(machine_config &config) { - SH2(config, m_maincpu, XTAL(28'000'000)); // 28 MHz + SH2_SH7604(config, m_maincpu, XTAL(28'000'000)); // 28 MHz m_maincpu->set_addrmap(AS_PROGRAM, &coolridr_state::coolridr_h1_map); TIMER(config, "scantimer").configure_scanline(FUNC(coolridr_state::interrupt_main), "screen", 0, 1); M68000(config, m_soundcpu, XTAL(32'000'000)/2); // 16 MHz m_soundcpu->set_addrmap(AS_PROGRAM, &coolridr_state::system_h1_sound_map); - SH1(config, m_subcpu, XTAL(32'000'000)/2); // SH7032 HD6417032F20!! 16 MHz + SH1_SH7032(config, m_subcpu, XTAL(32'000'000)/2); // SH7032 HD6417032F20!! 16 MHz m_subcpu->set_addrmap(AS_PROGRAM, &coolridr_state::coolridr_submap); TIMER(config, "scantimer2").configure_scanline(FUNC(coolridr_state::interrupt_sub), "screen", 0, 1); diff --git a/src/mame/sega/saturn.cpp b/src/mame/sega/saturn.cpp index 7a68640a4fe..e5ff9e78c8c 100644 --- a/src/mame/sega/saturn.cpp +++ b/src/mame/sega/saturn.cpp @@ -427,7 +427,6 @@ test1f diagnostic hacks: #include "cpu/m68000/m68000.h" #include "cpu/scudsp/scudsp.h" -#include "cpu/sh/sh2.h" #include "machine/nvram.h" #include "machine/smpc.h" #include "machine/stvcd.h" @@ -812,12 +811,12 @@ uint8_t sat_console_state::smpc_direct_mode(uint16_t in_value,bool which) void sat_console_state::saturn(machine_config &config) { /* basic machine hardware */ - SH2(config, m_maincpu, MASTER_CLOCK_352/2); // 28.6364 MHz + SH2_SH7604(config, m_maincpu, MASTER_CLOCK_352/2); // 28.6364 MHz m_maincpu->set_addrmap(AS_PROGRAM, &sat_console_state::saturn_mem); m_maincpu->set_is_slave(0); TIMER(config, "scantimer").configure_scanline(FUNC(sat_console_state::saturn_scanline), "screen", 0, 1); - SH2(config, m_slave, MASTER_CLOCK_352/2); // 28.6364 MHz + SH2_SH7604(config, m_slave, MASTER_CLOCK_352/2); // 28.6364 MHz m_slave->set_addrmap(AS_PROGRAM, &sat_console_state::saturn_mem); m_slave->set_is_slave(1); TIMER(config, "slave_scantimer").configure_scanline(FUNC(sat_console_state::saturn_slave_scanline), "screen", 0, 1); diff --git a/src/mame/sega/saturn.h b/src/mame/sega/saturn.h index 89f9760d216..ecf541e82fd 100644 --- a/src/mame/sega/saturn.h +++ b/src/mame/sega/saturn.h @@ -9,7 +9,7 @@ #include "bus/generic/carts.h" #include "cpu/m68000/m68000.h" -#include "cpu/sh/sh2.h" +#include "cpu/sh/sh7604.h" #include "315-5881_crypt.h" #include "315-5838_317-0229_comp.h" @@ -119,8 +119,8 @@ protected: int old_tvmd = 0; }m_vdp2; - required_device m_maincpu; - required_device m_slave; + required_device m_maincpu; + required_device m_slave; required_device m_audiocpu; required_device m_scsp; required_device m_smpc_hle; diff --git a/src/mame/sega/saturn_cdb.cpp b/src/mame/sega/saturn_cdb.cpp index 4163e36d78f..3ae572b30de 100644 --- a/src/mame/sega/saturn_cdb.cpp +++ b/src/mame/sega/saturn_cdb.cpp @@ -30,7 +30,7 @@ void saturn_cdb_device::saturn_cdb_map(address_map &map) void saturn_cdb_device::device_add_mconfig(machine_config &config) { - sh1_device &cdbcpu(SH1(config, "cdbcpu", DERIVED_CLOCK(1, 1))); + sh1_sh7032_device &cdbcpu(SH1_SH7032(config, "cdbcpu", DERIVED_CLOCK(1, 1))); cdbcpu.set_addrmap(AS_PROGRAM, &saturn_cdb_device::saturn_cdb_map); cdbcpu.set_disable(); // we're not actually using the CD Block ROM for now } diff --git a/src/mame/sega/saturn_cdb.h b/src/mame/sega/saturn_cdb.h index 667a5e03b12..73e9ceb9c1e 100644 --- a/src/mame/sega/saturn_cdb.h +++ b/src/mame/sega/saturn_cdb.h @@ -6,7 +6,7 @@ #pragma once -#include "cpu/sh/sh2.h" +#include "cpu/sh/sh7032.h" DECLARE_DEVICE_TYPE(SATURN_CDB, saturn_cdb_device) diff --git a/src/mame/sega/saturn_m.cpp b/src/mame/sega/saturn_m.cpp index 7ea5d31230b..b9b72cf03da 100644 --- a/src/mame/sega/saturn_m.cpp +++ b/src/mame/sega/saturn_m.cpp @@ -45,7 +45,6 @@ #include "emu.h" #include "saturn.h" -#include "cpu/sh/sh2.h" #include "cpu/scudsp/scudsp.h" diff --git a/src/mame/sega/stv.cpp b/src/mame/sega/stv.cpp index 3c8cd26f940..bcdb4faa5ad 100644 --- a/src/mame/sega/stv.cpp +++ b/src/mame/sega/stv.cpp @@ -45,7 +45,7 @@ #include "cpu/m68000/m68000.h" #include "cpu/scudsp/scudsp.h" -#include "cpu/sh/sh2.h" +#include "cpu/sh/sh7604.h" #include "machine/smpc.h" #include "machine/stvcd.h" #include "sound/scsp.h" @@ -1113,12 +1113,12 @@ void stv_state::pdr2_output_w(uint8_t data) void stv_state::stv(machine_config &config) { /* basic machine hardware */ - SH2(config, m_maincpu, MASTER_CLOCK_352/2); // 28.6364 MHz + SH2_SH7604(config, m_maincpu, MASTER_CLOCK_352/2); // 28.6364 MHz m_maincpu->set_addrmap(AS_PROGRAM, &stv_state::stv_mem); m_maincpu->set_is_slave(0); TIMER(config, "scantimer").configure_scanline(FUNC(stv_state::saturn_scanline), "screen", 0, 1); - SH2(config, m_slave, MASTER_CLOCK_352/2); // 28.6364 MHz + SH2_SH7604(config, m_slave, MASTER_CLOCK_352/2); // 28.6364 MHz m_slave->set_addrmap(AS_PROGRAM, &stv_state::stv_mem); m_slave->set_is_slave(1); TIMER(config, "slave_scantimer").configure_scanline(FUNC(stv_state::saturn_slave_scanline), "screen", 0, 1); diff --git a/src/mame/seibu/feversoc.cpp b/src/mame/seibu/feversoc.cpp index 6159d52b530..c29e6b48e9c 100644 --- a/src/mame/seibu/feversoc.cpp +++ b/src/mame/seibu/feversoc.cpp @@ -72,7 +72,7 @@ U089 MAX232 Dual EIA Driver/Receiver *******************************************************************************************/ #include "emu.h" -#include "cpu/sh/sh2.h" +#include "cpu/sh/sh7604.h" #include "seibuspi_m.h" #include "sound/okim6295.h" #include "machine/eepromser.h" @@ -126,7 +126,7 @@ private: required_ioport_array<2> m_in; output_finder<7> m_lamps; - required_device m_maincpu; + required_device m_maincpu; required_device m_oki; required_device m_eeprom; required_device m_rtc; @@ -297,7 +297,7 @@ void feversoc_state::machine_start() void feversoc_state::feversoc(machine_config &config) { /* basic machine hardware */ - SH2(config, m_maincpu, MASTER_CLOCK); + SH2_SH7604(config, m_maincpu, MASTER_CLOCK); m_maincpu->set_addrmap(AS_PROGRAM, &feversoc_state::feversoc_map); /* video hardware */ diff --git a/src/mame/shared/mega32x.cpp b/src/mame/shared/mega32x.cpp index 4fac35aa490..18f17083b93 100644 --- a/src/mame/shared/mega32x.cpp +++ b/src/mame/shared/mega32x.cpp @@ -1681,17 +1681,17 @@ const rom_entry *sega_32x_device::device_rom_region() const void sega_32x_device::device_add_mconfig(machine_config &config) { #ifndef _32X_SWAP_MASTER_SLAVE_HACK - SH2(config, m_master_cpu, DERIVED_CLOCK(1, 1)); + SH2_SH7604(config, m_master_cpu, DERIVED_CLOCK(1, 1)); m_master_cpu->set_is_slave(0); m_master_cpu->set_dma_fifo_data_available_callback(FUNC(sega_32x_device::_32x_fifo_available_callback)); #endif - SH2(config, m_slave_cpu, DERIVED_CLOCK(1, 1)); + SH2_SH7604(config, m_slave_cpu, DERIVED_CLOCK(1, 1)); m_slave_cpu->set_is_slave(1); m_slave_cpu->set_dma_fifo_data_available_callback(FUNC(sega_32x_device::_32x_fifo_available_callback)); #ifdef _32X_SWAP_MASTER_SLAVE_HACK - SH2(config, m_master_cpu, DERIVED_CLOCK(1, 1)); + SH2_SH7604(config, m_master_cpu, DERIVED_CLOCK(1, 1)); m_master_cpu->set_is_slave(0); m_master_cpu->set_dma_fifo_data_available_callback(FUNC(sega_32x_device::_32x_fifo_available_callback)); #endif diff --git a/src/mame/shared/mega32x.h b/src/mame/shared/mega32x.h index 14c2b0b6a13..927c5d82996 100644 --- a/src/mame/shared/mega32x.h +++ b/src/mame/shared/mega32x.h @@ -7,8 +7,7 @@ #pragma once #include "cpu/m68000/m68000.h" -#include "cpu/sh/sh2.h" -#include "cpu/sh/sh2comn.h" +#include "cpu/sh/sh7604.h" #include "machine/timer.h" #include "sound/dac.h" #include "emupal.h" @@ -116,8 +115,8 @@ protected: /* our main vblank handler resets this */ required_device m_main_cpu; - required_device m_master_cpu; - required_device m_slave_cpu; + required_device m_master_cpu; + required_device m_slave_cpu; required_device m_ldac; required_device m_rdac; required_device m_scan_timer; diff --git a/src/mame/virtual/vgmplay.cpp b/src/mame/virtual/vgmplay.cpp index 24ace147747..cfcf5d84e7f 100644 --- a/src/mame/virtual/vgmplay.cpp +++ b/src/mame/virtual/vgmplay.cpp @@ -13,7 +13,6 @@ #include "cpu/h6280/h6280.h" #include "cpu/m6502/rp2a03.h" #include "cpu/m68000/m68000.h" -#include "cpu/sh/sh2.h" #include "sound/ay8910.h" #include "sound/c140.h" #include "sound/c352.h"