summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Angelo Salese <lordkale4@gmail.com>2019-06-21 20:54:43 +0200
committer Angelo Salese <lordkale4@gmail.com>2019-06-21 20:55:05 +0200
commitd6b22fa2c0a78087794bf1df2bea62a7e34ca3cb (patch)
treef844754ded297c39919a603c499aab445291fde8
parentfb500438569eaa327d1accd5d467c03a49d6b1ba (diff)
sh2.cpp: first pass over SH7604 SoC refactoring [Angelo Salese]
* Fixed division unit overflow flag clearance;
-rw-r--r--src/devices/cpu/sh/sh2.cpp207
-rw-r--r--src/devices/cpu/sh/sh2.h192
-rw-r--r--src/devices/cpu/sh/sh2comn.cpp1023
-rw-r--r--src/devices/cpu/sh/sh2comn.h9
4 files changed, 1012 insertions, 419 deletions
diff --git a/src/devices/cpu/sh/sh2.cpp b/src/devices/cpu/sh/sh2.cpp
index d3660a52209..d38d8dcc6a8 100644
--- a/src/devices/cpu/sh/sh2.cpp
+++ b/src/devices/cpu/sh/sh2.cpp
@@ -123,15 +123,94 @@ READ32_MEMBER(sh2_device::sh2_internal_a5)
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 customization ...
- */
+
+// TODO: cps3boot breaks with this enabled. Needs callback
// AM_RANGE(0xc0000000, 0xc0000fff) AM_RAM // cache data array
-// AM_RANGE(0xffffff88, 0xffffff8b) AM_READWRITE(dma_dtcr0_r,dma_dtcr0_w)
- map(0xe0000000, 0xe00001ff).mirror(0x1ffffe00).rw(FUNC(sh2_device::sh7604_r), FUNC(sh2_device::sh7604_w));
+
+// 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
+ // additionally SH7604 doc mentions that there's a DRAM located at 0xffff8000,
+ // so this is not a full mirror? (needs confirmation)
+ // 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(0xfffffe91, 0xfffffe91).rw(FUNC(sh2_device::sbycr_r), FUNC(sh2_device::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)
@@ -364,14 +443,12 @@ void sh2_device::device_reset()
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_icr = 0;
+ 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;
- memset(m_m, 0, 0x200);
-
m_sh2_state->pc = RL(0);
m_sh2_state->r[15] = RL(4);
m_sh2_state->sr = SH_I;
@@ -467,13 +544,93 @@ void sh2_device::device_start()
m_internal = &space(AS_PROGRAM);
- save_item(NAME(m_cpu_off));
- //save_item(NAME(m_dvsr));
- //save_item(NAME(m_dvdnth));
- //save_item(NAME(m_dvdntl));
- //save_item(NAME(m_dvcr));
- save_item(NAME(m_test_irq));
+ // 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)
{
@@ -482,22 +639,15 @@ void sh2_device::device_start()
}
*/
-
+ // internals
+ save_item(NAME(m_cpu_off));
+ save_item(NAME(m_test_irq));
save_item(NAME(m_irq_line_state));
- save_item(NAME(m_m));
save_item(NAME(m_nmi_line_state));
- save_item(NAME(m_frc));
- save_item(NAME(m_ocra));
- save_item(NAME(m_ocrb));
- save_item(NAME(m_icr));
- save_item(NAME(m_frc_base));
- save_item(NAME(m_frt_input));
save_item(NAME(m_internal_irq_vector));
save_item(NAME(m_dma_timer_active));
save_item(NAME(m_dma_irq));
- save_item(NAME(m_wtcnt));
- save_item(NAME(m_wtcsr));
-
+
state_add( STATE_GENPC, "PC", m_sh2_state->pc).mask(SH12_AM).callimport();
state_add( STATE_GENPCBASE, "CURPC", m_sh2_state->pc ).callimport().noshow();
@@ -509,14 +659,13 @@ void sh2_device::device_start()
//m_dvcr = 0;
m_test_irq = 0;
-
memset(m_irq_line_state, 0, sizeof(m_irq_line_state));
- memset(m_m, 0, sizeof(m_m));
+
m_nmi_line_state = 0;
m_frc = 0;
m_ocra = 0;
m_ocrb = 0;
- m_icr = 0;
+ m_frc_icr = 0;
m_frc_base = 0;
m_frt_input = 0;
m_internal_irq_vector = 0;
@@ -641,7 +790,7 @@ void sh2_device::sh2_exception(const char *message, int irqline)
}
else
{
- if(m_m[0x38] & 0x00010000)
+ if(m_vecmd == true)
{
vector = standard_irq_callback(irqline);
LOG("SH-2 exception #%d (external vector: $%x) after [%s]\n", irqline, vector, message);
diff --git a/src/devices/cpu/sh/sh2.h b/src/devices/cpu/sh/sh2.h
index 206cecbab6d..e119d6bc098 100644
--- a/src/devices/cpu/sh/sh2.h
+++ b/src/devices/cpu/sh/sh2.h
@@ -81,10 +81,141 @@ public:
}
- DECLARE_WRITE32_MEMBER( sh7604_w );
- DECLARE_READ32_MEMBER( sh7604_r );
DECLARE_READ32_MEMBER(sh2_internal_a5);
+ // SCI
+ DECLARE_READ8_MEMBER( smr_r );
+ DECLARE_WRITE8_MEMBER( smr_w );
+ DECLARE_READ8_MEMBER( brr_r );
+ DECLARE_WRITE8_MEMBER( brr_w );
+ DECLARE_READ8_MEMBER( scr_r );
+ DECLARE_WRITE8_MEMBER( scr_w );
+ DECLARE_READ8_MEMBER( tdr_r );
+ DECLARE_WRITE8_MEMBER( tdr_w );
+ DECLARE_READ8_MEMBER( ssr_r );
+ DECLARE_WRITE8_MEMBER( ssr_w );
+ DECLARE_READ8_MEMBER( rdr_r );
+
+ // FRT / FRC
+ DECLARE_READ8_MEMBER( tier_r );
+ DECLARE_WRITE8_MEMBER( tier_w );
+ DECLARE_READ16_MEMBER( frc_r );
+ DECLARE_WRITE16_MEMBER( frc_w );
+ DECLARE_READ8_MEMBER( ftcsr_r );
+ DECLARE_WRITE8_MEMBER( ftcsr_w );
+ DECLARE_READ16_MEMBER( ocra_b_r );
+ DECLARE_WRITE16_MEMBER( ocra_b_w );
+ DECLARE_READ8_MEMBER( frc_tcr_r );
+ DECLARE_WRITE8_MEMBER( frc_tcr_w );
+ DECLARE_READ8_MEMBER( tocr_r );
+ DECLARE_WRITE8_MEMBER( tocr_w );
+ DECLARE_READ16_MEMBER( frc_icr_r );
+
+ // INTC
+ DECLARE_READ16_MEMBER( ipra_r );
+ DECLARE_WRITE16_MEMBER( ipra_w );
+ DECLARE_READ16_MEMBER( iprb_r );
+ DECLARE_WRITE16_MEMBER( iprb_w );
+ DECLARE_READ16_MEMBER( vcra_r );
+ DECLARE_WRITE16_MEMBER( vcra_w );
+ DECLARE_READ16_MEMBER( vcrb_r );
+ DECLARE_WRITE16_MEMBER( vcrb_w );
+ DECLARE_READ16_MEMBER( vcrc_r );
+ DECLARE_WRITE16_MEMBER( vcrc_w );
+ DECLARE_READ16_MEMBER( vcrd_r );
+ DECLARE_WRITE16_MEMBER( vcrd_w );
+ DECLARE_READ16_MEMBER( vcrwdt_r );
+ DECLARE_WRITE16_MEMBER( vcrwdt_w );
+ DECLARE_READ32_MEMBER( vcrdiv_r );
+ DECLARE_WRITE32_MEMBER( vcrdiv_w );
+ DECLARE_READ16_MEMBER( intc_icr_r );
+ DECLARE_WRITE16_MEMBER( intc_icr_w );
+
+ // DIVU
+ DECLARE_READ32_MEMBER( dvsr_r );
+ DECLARE_WRITE32_MEMBER( dvsr_w );
+ DECLARE_READ32_MEMBER( dvdnt_r );
+ DECLARE_WRITE32_MEMBER( dvdnt_w );
+ DECLARE_READ32_MEMBER( dvdnth_r );
+ DECLARE_WRITE32_MEMBER( dvdnth_w );
+ DECLARE_READ32_MEMBER( dvdntl_r );
+ DECLARE_WRITE32_MEMBER( dvdntl_w );
+
+ DECLARE_READ32_MEMBER( dvcr_r );
+ DECLARE_WRITE32_MEMBER( dvcr_w );
+
+ // DMAC
+ template <int Channel> READ32_MEMBER(vcrdma_r)
+ {
+ return m_vcrdma[Channel] & 0x7f;
+ }
+
+ template <int Channel> WRITE32_MEMBER(vcrdma_w)
+ {
+ COMBINE_DATA(&m_vcrdma[Channel]);
+ m_irq_vector.dmac[Channel] = m_vcrdma[Channel] & 0x7f;
+ sh2_recalc_irq();
+ }
+
+ template <int Channel> READ8_MEMBER(drcr_r) { return m_dmac[Channel].drcr & 3; }
+ template <int Channel> WRITE8_MEMBER(drcr_w) { m_dmac[Channel].drcr = data & 3; sh2_recalc_irq(); }
+ template <int Channel> READ32_MEMBER(sar_r) { return m_dmac[Channel].sar; }
+ template <int Channel> WRITE32_MEMBER(sar_w) { COMBINE_DATA(&m_dmac[Channel].sar); }
+ template <int Channel> READ32_MEMBER(dar_r) { return m_dmac[Channel].dar; }
+ template <int Channel> WRITE32_MEMBER(dar_w) { COMBINE_DATA(&m_dmac[Channel].dar); }
+ template <int Channel> READ32_MEMBER(dmac_tcr_r) { return m_dmac[Channel].tcr; }
+ template <int Channel> WRITE32_MEMBER(dmac_tcr_w) { COMBINE_DATA(&m_dmac[Channel].tcr); m_dmac[Channel].tcr &= 0xffffff; }
+ template <int Channel> READ32_MEMBER(chcr_r) { return m_dmac[Channel].chcr; }
+ template <int Channel> WRITE32_MEMBER(chcr_w)
+ {
+ 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);
+ }
+ READ32_MEMBER( dmaor_r ) { return m_dmaor & 0xf; }
+ WRITE32_MEMBER( dmaor_w )
+ {
+ 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
+ DECLARE_READ16_MEMBER( wtcnt_r );
+ DECLARE_WRITE16_MEMBER( wtcnt_w );
+ DECLARE_READ16_MEMBER( rstcsr_r );
+ DECLARE_WRITE16_MEMBER( rstcsr_w );
+
+ // misc
+ DECLARE_READ8_MEMBER( sbycr_r );
+ DECLARE_WRITE8_MEMBER( sbycr_w );
+ DECLARE_READ8_MEMBER( ccr_r );
+ DECLARE_WRITE8_MEMBER( ccr_w );
+
+ // BSC
+ DECLARE_READ32_MEMBER( bcr1_r );
+ DECLARE_WRITE32_MEMBER( bcr1_w );
+ DECLARE_READ32_MEMBER( bcr2_r );
+ DECLARE_WRITE32_MEMBER( bcr2_w );
+ DECLARE_READ32_MEMBER( wcr_r );
+ DECLARE_WRITE32_MEMBER( wcr_w );
+ DECLARE_READ32_MEMBER( mcr_r );
+ DECLARE_WRITE32_MEMBER( mcr_w );
+ DECLARE_READ32_MEMBER( rtcsr_r );
+ DECLARE_WRITE32_MEMBER( rtcsr_w );
+ DECLARE_READ32_MEMBER( rtcor_r );
+ DECLARE_WRITE32_MEMBER( rtcor_w );
+ DECLARE_READ32_MEMBER( rtcnt_r );
+ DECLARE_WRITE32_MEMBER( rtcnt_w );
+
+
virtual void set_frt_input(int state) override;
void sh2_notify_dma_data_available();
void func_fastirq();
@@ -128,11 +259,58 @@ private:
int8_t m_irq_line_state[17];
address_space *m_internal;
- uint32_t m_m[0x200/4];
+ // 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;
+
int8_t m_nmi_line_state;
- uint16_t m_frc;
- uint16_t m_ocra, m_ocrb, m_icr;
uint64_t m_frc_base;
int m_frt_input;
@@ -150,8 +328,6 @@ private:
uint32_t m_active_dma_src[2];
uint32_t m_active_dma_dst[2];
uint32_t m_active_dma_count[2];
- uint16_t m_wtcnt;
- uint8_t m_wtcsr;
int m_is_slave;
dma_kludge_delegate m_dma_kludge_cb;
@@ -181,7 +357,7 @@ private:
TIMER_CALLBACK_MEMBER( sh2_dma_current_active_callback );
void sh2_timer_resync();
void sh2_timer_activate();
- void sh2_do_dma(int dma);
+ 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();
diff --git a/src/devices/cpu/sh/sh2comn.cpp b/src/devices/cpu/sh/sh2comn.cpp
index 8accaaf8ebb..e9503099fc2 100644
--- a/src/devices/cpu/sh/sh2comn.cpp
+++ b/src/devices/cpu/sh/sh2comn.cpp
@@ -22,7 +22,8 @@ static const int div_tab[4] = { 3, 5, 7, 0 };
void sh2_device::sh2_timer_resync()
{
- int divider = div_tab[(m_m[5] >> 8) & 3];
+ // 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;
@@ -43,26 +44,26 @@ void sh2_device::sh2_timer_activate()
m_timer->adjust(attotime::never);
frc = m_frc;
- if(!(m_m[4] & OCFA)) {
+ if(!(m_ftcsr & OCFA)) {
uint16_t delta = m_ocra - frc;
if(delta < max_delta)
max_delta = delta;
}
- if(!(m_m[4] & OCFB) && (m_ocra <= m_ocrb || !(m_m[4] & 0x010000))) {
+ 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_m[4] & OVF) && !(m_m[4] & 0x010000)) {
+ 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_m[5] >> 8) & 3];
+ int divider = div_tab[m_frc_tcr & 3];
if(divider) {
max_delta <<= divider;
m_frc_base = total_cycles();
@@ -82,16 +83,16 @@ TIMER_CALLBACK_MEMBER( sh2_device::sh2_timer_callback )
frc = m_frc;
if(frc == m_ocrb)
- m_m[4] |= OCFB;
+ m_ftcsr |= OCFB;
if(frc == 0x0000)
- m_m[4] |= OVF;
+ m_ftcsr |= OVF;
if(frc == m_ocra)
{
- m_m[4] |= OCFA;
+ m_ftcsr |= OCFA;
- if(m_m[4] & 0x010000)
+ if(m_ftcsr & CCLRA)
m_frc = 0;
}
@@ -128,30 +129,30 @@ void sh2_device::sh2_notify_dma_data_available()
{
//printf("call notify\n");
- for (int dma=0;dma<2;dma++)
+ for (int dmach=0;dmach<2;dmach++)
{
- //printf("m_dma_timer_active[dma] %04x\n",m_dma_timer_active[dma]);
+ //printf("m_dma_timer_active[dmach] %04x\n",m_dma_timer_active[dmach]);
- if (m_dma_timer_active[dma]==2) // 2 = stalled
+ if (m_dma_timer_active[dmach]==2) // 2 = stalled
{
// printf("resuming stalled dma\n");
- m_dma_timer_active[dma]=1;
- m_dma_current_active_timer[dma]->adjust(attotime::zero, dma);
+ m_dma_timer_active[dmach]=1;
+ m_dma_current_active_timer[dmach]->adjust(attotime::zero, dmach);
}
}
}
-void sh2_device::sh2_do_dma(int dma)
+void sh2_device::sh2_do_dma(int dmach)
{
uint32_t dmadata;
uint32_t tempsrc, tempdst;
- if (m_active_dma_count[dma] > 0)
+ if (m_active_dma_count[dmach] > 0)
{
// process current DMA
- switch(m_active_dma_size[dma])
+ switch(m_active_dma_size[dmach])
{
case 0:
{
@@ -159,188 +160,188 @@ void sh2_device::sh2_do_dma(int dma)
// 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[dma] == 2)
- tempsrc = m_active_dma_src[dma] - 1;
+ if(m_active_dma_incs[dmach] == 2)
+ tempsrc = m_active_dma_src[dmach] - 1;
else
- tempsrc = m_active_dma_src[dma];
+ tempsrc = m_active_dma_src[dmach];
- if(m_active_dma_incd[dma] == 2)
- tempdst = m_active_dma_dst[dma] - 1;
+ if(m_active_dma_incd[dmach] == 2)
+ tempdst = m_active_dma_dst[dmach] - 1;
else
- tempdst = m_active_dma_dst[dma];
+ 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[dma]);
+ 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[dma]=2;// mark as stalled
+ m_dma_timer_active[dmach]=2;// mark as stalled
return;
}
}
//schedule next DMA callback
- m_dma_current_active_timer[dma]->adjust(cycles_to_attotime(2), dma);
+ 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[dma]);
+ 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[dma] == 2)
- m_active_dma_src[dma] --;
- if(m_active_dma_incd[dma] == 2)
- m_active_dma_dst[dma] --;
+ 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[dma] == 1)
- m_active_dma_src[dma] ++;
- if(m_active_dma_incd[dma] == 1)
- m_active_dma_dst[dma] ++;
+ 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[dma] --;
+ m_active_dma_count[dmach] --;
}
break;
case 1:
{
- if(m_active_dma_incs[dma] == 2)
- tempsrc = m_active_dma_src[dma] - 2;
+ if(m_active_dma_incs[dmach] == 2)
+ tempsrc = m_active_dma_src[dmach] - 2;
else
- tempsrc = m_active_dma_src[dma];
+ tempsrc = m_active_dma_src[dmach];
- if(m_active_dma_incd[dma] == 2)
- tempdst = m_active_dma_dst[dma] - 2;
+ if(m_active_dma_incd[dmach] == 2)
+ tempdst = m_active_dma_dst[dmach] - 2;
else
- tempdst = m_active_dma_dst[dma];
+ 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[dma]);
+ 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[dma]=2;// mark as stalled
+ m_dma_timer_active[dmach]=2;// mark as stalled
return;
}
}
//schedule next DMA callback
- m_dma_current_active_timer[dma]->adjust(cycles_to_attotime(2), dma);
+ 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[dma]);
+ 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[dma] == 2)
- m_active_dma_src[dma] -= 2;
- if(m_active_dma_incd[dma] == 2)
- m_active_dma_dst[dma] -= 2;
+ 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[dma] == 1)
- m_active_dma_src[dma] += 2;
- if(m_active_dma_incd[dma] == 1)
- m_active_dma_dst[dma] += 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[dma] --;
+ m_active_dma_count[dmach] --;
}
break;
case 2:
{
- if(m_active_dma_incs[dma] == 2)
- tempsrc = m_active_dma_src[dma] - 4;
+ if(m_active_dma_incs[dmach] == 2)
+ tempsrc = m_active_dma_src[dmach] - 4;
else
- tempsrc = m_active_dma_src[dma];
+ tempsrc = m_active_dma_src[dmach];
- if(m_active_dma_incd[dma] == 2)
- tempdst = m_active_dma_dst[dma] - 4;
+ if(m_active_dma_incd[dmach] == 2)
+ tempdst = m_active_dma_dst[dmach] - 4;
else
- tempdst = m_active_dma_dst[dma];
+ 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[dma]);
+ 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[dma]=2;// mark as stalled
+ m_dma_timer_active[dmach]=2;// mark as stalled
return;
}
}
//schedule next DMA callback
- m_dma_current_active_timer[dma]->adjust(cycles_to_attotime(2), dma);
+ 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[dma]);
+ 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[dma] == 2)
- m_active_dma_src[dma] -= 4;
- if(m_active_dma_incd[dma] == 2)
- m_active_dma_dst[dma] -= 4;
+ 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[dma] == 1)
- m_active_dma_src[dma] += 4;
- if(m_active_dma_incd[dma] == 1)
- m_active_dma_dst[dma] += 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[dma] --;
+ m_active_dma_count[dmach] --;
}
break;
case 3:
{
// shouldn't this really be 4 calls here instead?
- tempsrc = m_active_dma_src[dma];
+ tempsrc = m_active_dma_src[dmach];
- if(m_active_dma_incd[dma] == 2)
- tempdst = m_active_dma_dst[dma] - 16;
+ if(m_active_dma_incd[dmach] == 2)
+ tempdst = m_active_dma_dst[dmach] - 16;
else
- tempdst = m_active_dma_dst[dma];
+ 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[dma]);
+ 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[dma]=2;// mark as stalled
+ 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[dma]->adjust(cycles_to_attotime(2), dma);
+ 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[dma]);
+ 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[dma]);
+ 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[dma]);
+ 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[dma]);
+ 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[dma] == 2)
- m_active_dma_dst[dma] -= 16;
+ if(m_active_dma_incd[dmach] == 2)
+ m_active_dma_dst[dmach] -= 16;
- m_active_dma_src[dma] += 16;
- if(m_active_dma_incd[dma] == 1)
- m_active_dma_dst[dma] += 16;
+ m_active_dma_src[dmach] += 16;
+ if(m_active_dma_incd[dmach] == 1)
+ m_active_dma_dst[dmach] += 16;
- m_active_dma_count[dma]-=4;
+ m_active_dma_count[dmach]-=4;
}
break;
}
@@ -350,17 +351,17 @@ void sh2_device::sh2_do_dma(int dma)
// int dma = param & 1;
// fever soccer uses cycle-stealing mode, resume the CPU now DMA has finished
- if (m_active_dma_steal[dma])
+ if (m_active_dma_steal[dmach])
{
resume(SUSPEND_REASON_HALT );
}
- LOG("SH2: DMA %d complete\n", dma);
- m_m[0x62+4*dma] = 0;
- m_m[0x63+4*dma] |= 2;
- m_dma_timer_active[dma] = 0;
- m_dma_irq[dma] |= 1;
+ 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();
}
@@ -374,146 +375,489 @@ TIMER_CALLBACK_MEMBER( sh2_device::sh2_dma_current_active_callback )
}
-void sh2_device::sh2_dmac_check(int dma)
+void sh2_device::sh2_dmac_check(int dmach)
{
- if(m_m[0x63+4*dma] & m_m[0x6c] & 1)
+ if(m_dmac[dmach].chcr & m_dmaor & 1)
{
- if(!m_dma_timer_active[dma] && !(m_m[0x63+4*dma] & 2))
+ if(!m_dma_timer_active[dmach] && !(m_dmac[dmach].chcr & 2))
{
- m_active_dma_incd[dma] = (m_m[0x63+4*dma] >> 14) & 3;
- m_active_dma_incs[dma] = (m_m[0x63+4*dma] >> 12) & 3;
- m_active_dma_size[dma] = (m_m[0x63+4*dma] >> 10) & 3;
- m_active_dma_steal[dma] = (m_m[0x63+4*dma] &0x10);
+ 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[dma] == 3 || m_active_dma_incs[dma] == 3)
+ 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[dma], m_active_dma_incs[dma], m_active_dma_size[dma], m_m[0x63+4*dma]);
+ 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[dma] = m_m[0x60+4*dma];
- m_active_dma_dst[dma] = m_m[0x61+4*dma];
- m_active_dma_count[dma] = m_m[0x62+4*dma];
- if(!m_active_dma_count[dma])
- m_active_dma_count[dma] = 0x1000000;
+ 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", dma, m_active_dma_src[dma], m_active_dma_dst[dma], m_active_dma_count[dma], m_m[0x63+4*dma], m_active_dma_incs[dma], m_active_dma_incd[dma], m_active_dma_size[dma]);
+ 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[dma] = 1;
+ m_dma_timer_active[dmach] = 1;
- m_active_dma_src[dma] &= SH12_AM;
- m_active_dma_dst[dma] &= SH12_AM;
+ m_active_dma_src[dmach] &= SH12_AM;
+ m_active_dma_dst[dmach] &= SH12_AM;
- switch(m_active_dma_size[dma])
+ switch(m_active_dma_size[dmach])
{
case 0:
break;
case 1:
- m_active_dma_src[dma] &= ~1;
- m_active_dma_dst[dma] &= ~1;
+ m_active_dma_src[dmach] &= ~1;
+ m_active_dma_dst[dmach] &= ~1;
break;
case 2:
- m_active_dma_src[dma] &= ~3;
- m_active_dma_dst[dma] &= ~3;
+ m_active_dma_src[dmach] &= ~3;
+ m_active_dma_dst[dmach] &= ~3;
break;
case 3:
- m_active_dma_src[dma] &= ~3;
- m_active_dma_dst[dma] &= ~3;
- m_active_dma_count[dma] &= ~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[dma])
+ if (m_active_dma_steal[dmach])
{
//printf("cycle stealing DMA\n");
suspend(SUSPEND_REASON_HALT, 1 );
}
- m_dma_current_active_timer[dma]->adjust(cycles_to_attotime(2), dma);
+ m_dma_current_active_timer[dmach]->adjust(cycles_to_attotime(2), dmach);
}
}
else
{
- if(m_dma_timer_active[dma])
+ if(m_dma_timer_active[dmach])
{
- logerror("SH2: DMA %d cancelled in-flight\n", dma);
- //m_dma_complete_timer[dma]->adjust(attotime::never);
- m_dma_current_active_timer[dma]->adjust(attotime::never);
+ 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[dma] = 0;
+ m_dma_timer_active[dmach] = 0;
}
}
}
+/*
+ * SCI
+ */
+// TODO: identical to H8 counterpart
+
+READ8_MEMBER( sh2_device::smr_r )
+{
+ return m_smr;
+}
+
+WRITE8_MEMBER( sh2_device::smr_w )
+{
+ m_smr = data;
+}
+
+READ8_MEMBER( sh2_device::brr_r )
+{
+ return m_brr;
+}
+
+WRITE8_MEMBER( sh2_device::brr_w )
+{
+ m_brr = data;
+}
+
+READ8_MEMBER( sh2_device::scr_r )
+{
+ return m_scr;
+}
+
+WRITE8_MEMBER( sh2_device::scr_w )
+{
+ m_scr = data;
+}
+
+READ8_MEMBER( sh2_device::tdr_r )
+{
+ return m_tdr;
+}
+
+WRITE8_MEMBER( sh2_device::tdr_w )
+{
+ m_tdr = data;
+ // printf("%c",data & 0xff);
+}
+
+READ8_MEMBER( sh2_device::ssr_r )
+{
+ // 0x84 is needed by EGWord on Saturn to make it to boot for some reason.
+ return m_ssr | 0x84;
+}
+
+WRITE8_MEMBER( sh2_device::ssr_w )
+{
+ m_ssr = data;
+}
+
+READ8_MEMBER( sh2_device::rdr_r )
+{
+ return 0;
+}
+
+/*
+ * FRC
+ */
+
+READ8_MEMBER( sh2_device::tier_r )
+{
+ return m_tier;
+}
+
+WRITE8_MEMBER( sh2_device::tier_w )
+{
+ sh2_timer_resync();
+ m_tier = data;
+ sh2_timer_activate();
+ sh2_recalc_irq();
+}
+
+READ8_MEMBER( 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;
+}
+
+WRITE8_MEMBER( sh2_device::ftcsr_w )
+{
+ 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();
+}
+
+READ16_MEMBER( sh2_device::frc_r )
+{
+ sh2_timer_resync();
+ return m_frc;
+}
+
+WRITE16_MEMBER( sh2_device::frc_w )
+{
+ sh2_timer_resync();
+ COMBINE_DATA(&m_frc);
+ sh2_timer_activate();
+ sh2_recalc_irq();
+}
+
+READ16_MEMBER( sh2_device::ocra_b_r )
+{
+ return (m_tocr & 0x10) ? m_ocrb : m_ocra;
+}
+
+WRITE16_MEMBER( sh2_device::ocra_b_w )
+{
+ 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();
+}
+
+READ8_MEMBER( sh2_device::frc_tcr_r )
+{
+ return m_frc_tcr & 0x83;
+}
+
+WRITE8_MEMBER( sh2_device::frc_tcr_w )
+{
+ sh2_timer_resync();
+ m_frc_tcr = data & 0x83;
+ sh2_timer_activate();
+ sh2_recalc_irq();
+}
+
+READ8_MEMBER( sh2_device::tocr_r )
+{
+ return (m_tocr & 0x13) | 0xe0;
+}
+
+WRITE8_MEMBER( sh2_device::tocr_w )
+{
+ sh2_timer_resync();
+ // TODO: output levels A/B (bits 1-0)
+ m_tocr = data & 0x13;
+ sh2_timer_activate();
+ sh2_recalc_irq();
+}
+
+READ16_MEMBER( sh2_device::frc_icr_r )
+{
+ return m_frc_icr;
+}
+
+/*
+ * INTC
+ */
+
+READ16_MEMBER( 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);
+}
+
+WRITE16_MEMBER( sh2_device::intc_icr_w )
+{
+ COMBINE_DATA(&m_intc_icr);
+ m_nmie = bool(BIT(m_intc_icr, 8));
+ m_vecmd = bool(BIT(m_intc_icr, 0));
+}
+
+READ16_MEMBER( sh2_device::ipra_r )
+{
+ return m_ipra & 0xfff0;
+}
+
+WRITE16_MEMBER( sh2_device::ipra_w )
+{
+ 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();
+}
+
+READ16_MEMBER( sh2_device::iprb_r )
+{
+ return m_iprb & 0xff00;
+}
+
+WRITE16_MEMBER( sh2_device::iprb_w )
+{
+ COMBINE_DATA(&m_iprb);
+ m_irq_level.sci = (m_iprb >> 12) & 0xf;
+ m_irq_level.frc = (m_iprb >> 8) & 0xf;
+ sh2_recalc_irq();
+}
+
+READ16_MEMBER( sh2_device::vcra_r )
+{
+ return m_vcra & 0x7f7f;
+}
+
+WRITE16_MEMBER( sh2_device::vcra_w )
+{
+ COMBINE_DATA(&m_vcra);
+ // ...
+ sh2_recalc_irq();
+}
+
+READ16_MEMBER( sh2_device::vcrb_r )
+{
+ return m_vcrb;
+}
+
+WRITE16_MEMBER( sh2_device::vcrb_w )
+{
+ COMBINE_DATA(&m_vcrb);
+ // ...
+ sh2_recalc_irq();
+}
+
+READ16_MEMBER( sh2_device::vcrc_r )
+{
+ return m_vcrc & 0x7f7f;
+}
+
+WRITE16_MEMBER( sh2_device::vcrc_w )
+{
+ COMBINE_DATA(&m_vcrc);
+ m_irq_vector.fic = (m_vcrc >> 8) & 0x7f;
+ m_irq_vector.foc = (m_vcrc >> 0) & 0x7f;
+ sh2_recalc_irq();
+}
+
+READ16_MEMBER( sh2_device::vcrd_r )
+{
+ return m_vcrd & 0x7f00;
+}
+
+WRITE16_MEMBER( sh2_device::vcrd_w )
+{
+ COMBINE_DATA(&m_vcrd);
+ m_irq_vector.fov = (m_vcrc >> 8) & 0x7f;
+ sh2_recalc_irq();
+}
+
+READ16_MEMBER( sh2_device::vcrwdt_r )
+{
+ return m_vcrwdt & 0x7f7f;
+}
-WRITE32_MEMBER( sh2_device::sh7604_w )
+WRITE16_MEMBER( sh2_device::vcrwdt_w )
{
- uint32_t old;
+ COMBINE_DATA(&m_vcrwdt);
+ // ...
+ sh2_recalc_irq();
+}
- old = m_m[offset];
- COMBINE_DATA(m_m+offset);
+READ32_MEMBER( sh2_device::vcrdiv_r )
+{
+ return m_vcrdiv & 0x7f;
+}
- // if(offset != 0x20)
- // logerror("sh2_internal_w: Write %08x (%x), %08x @ %08x\n", 0xfffffe00+offset*4, offset, data, mem_mask);
+WRITE32_MEMBER( sh2_device::vcrdiv_w )
+{
+ COMBINE_DATA(&m_vcrdiv);
+ // TODO: unemulated, level is seemingly not documented/settable?
+ m_irq_vector.divu = data & 0x7f;
+ sh2_recalc_irq();
+}
-// if(offset != 0x20)
-// printf("sh2_internal_w: Write %08x (%x), %08x @ %08x (PC %x)\n", 0xfffffe00+offset*4, offset, data, mem_mask, pc());
+READ32_MEMBER( sh2_device::dvcr_r )
+{
+ return (m_divu_ovfie == true ? 2 : 0) | (m_divu_ovf == true ? 1 : 0);
+}
- switch( offset )
+WRITE32_MEMBER( sh2_device::dvcr_w )
+{
+ if(ACCESSING_BITS_0_7)
{
- case 0x00:
- //if(mem_mask == 0xff)
- // printf("%c",data & 0xff);
- break;
- case 0x01:
- //printf("%08x %02x %02x\n",mem_mask,offset,data);
- break;
- // Timers
- case 0x04: // TIER, FTCSR, FRC
- if((mem_mask & 0x00ffffff) != 0)
+ if (data & 1)
+ m_divu_ovf = false;
+ if (data & 2)
{
- sh2_timer_resync();
+ m_divu_ovfie = bool(BIT(data, 1));
+ if (m_divu_ovfie == true)
+ LOG("SH2: unemulated DIVU OVF interrupt enable\n");
}
-// printf("SH2.%s: TIER write %04x @ %04x\n", m_device->tag(), data >> 16, mem_mask>>16);
- m_m[4] = (m_m[4] & ~(ICF|OCFA|OCFB|OVF)) | (old & m_m[4] & (ICF|OCFA|OCFB|OVF));
- COMBINE_DATA(&m_frc);
- if((mem_mask & 0x00ffffff) != 0)
- sh2_timer_activate();
sh2_recalc_irq();
- break;
- case 0x05: // OCRx, TCR, TOCR
-// printf("SH2.%s: TCR write %08x @ %08x\n", m_device->tag(), data, mem_mask);
- sh2_timer_resync();
- if(m_m[5] & 0x10)
- m_ocrb = (m_ocrb & (~mem_mask >> 16)) | ((data & mem_mask) >> 16);
- else
- m_ocra = (m_ocra & (~mem_mask >> 16)) | ((data & mem_mask) >> 16);
- sh2_timer_activate();
- break;
+ }
+}
+
+/*
+ * DMAC
+ */
- case 0x06: // ICR
- break;
+READ32_MEMBER( sh2_device::dvsr_r )
+{
+ return m_dvsr;
+}
- // Interrupt vectors
- case 0x18: // IPRB, VCRA
- case 0x19: // VCRB, VCRC
- case 0x1a: // VCRD
+WRITE32_MEMBER( sh2_device::dvsr_w )
+{
+ COMBINE_DATA(&m_dvsr);
+}
+
+READ32_MEMBER( sh2_device::dvdnt_r )
+{
+ return m_dvdntl;
+}
+
+WRITE32_MEMBER( sh2_device::dvdnt_w )
+{
+ 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();
- break;
+ }
+}
- // DMA
- case 0x1c: // DRCR0, DRCR1
- break;
+READ32_MEMBER( sh2_device::dvdnth_r )
+{
+ return m_dvdnth;
+}
- // Watchdog
- case 0x20: // WTCNT, RSTCSR
- if((m_m[0x20] & 0xff000000) == 0x5a000000)
- m_wtcnt = (m_m[0x20] >> 16) & 0xff;
+READ32_MEMBER( sh2_device::dvdntl_r )
+{
+ return m_dvdntl;
+}
- if((m_m[0x20] & 0xff000000) == 0xa5000000)
+WRITE32_MEMBER( sh2_device::dvdnth_w )
+{
+ COMBINE_DATA(&m_dvdnth);
+}
+
+WRITE32_MEMBER( sh2_device::dvdntl_w )
+{
+ 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
+ */
+
+READ16_MEMBER( sh2_device::wtcnt_r )
+{
+ return ((m_wtcsr | 0x18) << 8) | (m_wtcnt & 0xff);
+}
+
+READ16_MEMBER( sh2_device::rstcsr_r )
+{
+ return (m_rstcsr & 0xe0) | 0x1f;
+}
+
+WRITE16_MEMBER( sh2_device::wtcnt_w )
+{
+ COMBINE_DATA(&m_wtcw[0]);
+ switch (m_wtcw[0] & 0xff00)
+ {
+ case 0x5a00:
+ m_wtcnt = m_wtcw[0] & 0xff;
+ break;
+ case 0xa500:
/*
WTCSR
x--- ---- Overflow in IT mode
@@ -522,204 +866,127 @@ WRITE32_MEMBER( sh2_device::sh7604_w )
---1 1---
---- -xxx Clock select
*/
+ m_wtcsr = m_wtcw[0] & 0xff;
+ break;
+ }
+}
- m_wtcsr = (m_m[0x20] >> 16) & 0xff;
- }
+WRITE16_MEMBER( sh2_device::rstcsr_w )
+{
+ 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;
+ }
+}
- if((m_m[0x20] & 0x0000ff00) == 0x00005a00)
- {
- // -x-- ---- RSTE (1: resets wtcnt when overflows 0: no reset)
- // --x- ---- RSTS (0: power-on reset 1: Manual reset)
- // ...
- }
+READ8_MEMBER( sh2_device::sbycr_r )
+{
+ return m_sbycr;
+}
- if((m_m[0x20] & 0x0000ff00) == 0x0000a500)
- {
- // clear WOVF
- // ...
- }
+WRITE8_MEMBER( sh2_device::sbycr_w )
+{
+ m_sbycr = data;
+ if (data & 0x1f)
+ logerror("SH2 module stop selected %02x\n",data);
+}
+READ8_MEMBER( sh2_device::ccr_r )
+{
+ return m_ccr & ~0x30;
+}
+WRITE8_MEMBER( sh2_device::ccr_w )
+{
+ /*
+ 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;
+}
- break;
-
- // Standby and cache
- case 0x24: // SBYCR, CCR
- /*
- CCR
- xx-- ---- ---- ---- Way 0/1
- ---x ---- ---- ---- Cache Purge (CP)
- ---- x--- ---- ---- Two-Way Mode (TW)
- ---- -x-- ---- ---- Data Replacement Disable (OD)
- ---- --x- ---- ---- Instruction Replacement Disable (ID)
- ---- ---x ---- ---- Cache Enable (CE)
- */
- break;
-
- // Interrupt vectors cont.
- case 0x38: // ICR, IRPA
- break;
- case 0x39: // VCRWDT
- break;
-
- // Division box
- case 0x40: // DVSR
- break;
- case 0x41: // DVDNT
- {
- int32_t a = m_m[0x41];
- int32_t b = m_m[0x40];
- LOG("SH2 div+mod %d/%d\n", a, b);
- if (b)
- {
- m_m[0x45] = a / b;
- m_m[0x44] = a % b;
- }
- else
- {
- m_m[0x42] |= 0x00010000;
- m_m[0x45] = 0x7fffffff;
- m_m[0x44] = 0x7fffffff;
- sh2_recalc_irq();
- }
- break;
- }
- case 0x42: // DVCR
- m_m[0x42] = (m_m[0x42] & ~0x00001000) | (old & m_m[0x42] & 0x00010000);
- sh2_recalc_irq();
- break;
- case 0x43: // VCRDIV
- sh2_recalc_irq();
- break;
- case 0x44: // DVDNTH
- break;
- case 0x45: // DVDNTL
- {
- int64_t a = m_m[0x45] | ((uint64_t)(m_m[0x44]) << 32);
- int64_t b = (int32_t)m_m[0x40];
- LOG("SH2 div+mod %d/%d\n", a, b);
- if (b)
- {
- int64_t q = a / b;
- if (q != (int32_t)q)
- {
- m_m[0x42] |= 0x00010000;
- m_m[0x45] = 0x7fffffff;
- m_m[0x44] = 0x7fffffff;
- sh2_recalc_irq();
- }
- else
- {
- m_m[0x45] = q;
- m_m[0x44] = a % b;
- }
- }
- else
- {
- m_m[0x42] |= 0x00010000;
- m_m[0x45] = 0x7fffffff;
- m_m[0x44] = 0x7fffffff;
- sh2_recalc_irq();
- }
- break;
- }
+READ32_MEMBER( sh2_device::bcr1_r )
+{
+ return (m_bcr1 & ~0xe008) | (m_is_slave ? 0x8000 : 0);
+}
- // DMA controller
- case 0x60: // SAR0
- case 0x61: // DAR0
- break;
- case 0x62: // DTCR0
- m_m[0x62] &= 0xffffff;
- break;
- case 0x63: // CHCR0
- m_m[0x63] = (m_m[0x63] & ~2) | (old & m_m[0x63] & 2);
- sh2_dmac_check(0);
- break;
- case 0x64: // SAR1
- case 0x65: // DAR1
- break;
- case 0x66: // DTCR1
- m_m[0x66] &= 0xffffff;
- break;
- case 0x67: // CHCR1
- m_m[0x67] = (m_m[0x67] & ~2) | (old & m_m[0x67] & 2);
- sh2_dmac_check(1);
- break;
- case 0x68: // VCRDMA0
- case 0x6a: // VCRDMA1
- sh2_recalc_irq();
- break;
- case 0x6c: // DMAOR
- m_m[0x6c] = (m_m[0x6c] & ~6) | (old & m_m[0x6c] & 6);
- sh2_dmac_check(0);
- sh2_dmac_check(1);
- break;
-
- // Bus controller
- case 0x78: // BCR1
- case 0x79: // BCR2
- case 0x7a: // WCR
- case 0x7b: // MCR
- case 0x7c: // RTCSR
- case 0x7d: // RTCNT
- case 0x7e: // RTCOR
- break;
-
- default:
- logerror("sh2_internal_w: Unmapped write %08x, %08x @ %08x\n", 0xfffffe00+offset*4, data, mem_mask);
- break;
- }
+WRITE32_MEMBER( sh2_device::bcr1_w )
+{
+ COMBINE_DATA(&m_bcr1);
}
-READ32_MEMBER( sh2_device::sh7604_r )
+READ32_MEMBER( sh2_device::bcr2_r )
{
-// logerror("sh2_internal_r: Read %08x (%x) @ %08x\n", 0xfffffe00+offset*4, offset, mem_mask);
- switch( offset )
- {
- case 0x00:
- break;
- case 0x01:
-// return m_m[1] | 0; // bit31 is TDRE: Trasmit Data Register Empty. Forcing it to be '1' breaks Saturn ...
- return m_m[1] | (0x84 << 24); // ... but this is actually needed to make EGWord on SS to boot?
-
- case 0x04: // TIER, FTCSR, FRC
- if ( mem_mask == 0x00ff0000 )
- {
- if (!m_ftcsr_read_cb.isnull())
- {
- m_ftcsr_read_cb((m_m[4] & 0xffff0000) | m_frc);
- }
- }
- sh2_timer_resync();
- return (m_m[4] & 0xffff0000) | m_frc;
- case 0x05: // OCRx, TCR, TOCR
- if(m_m[5] & 0x10)
- return (m_ocrb << 16) | (m_m[5] & 0xffff);
- else
- return (m_ocra << 16) | (m_m[5] & 0xffff);
- case 0x06: // ICR
- return m_icr << 16;
+ return m_bcr2;
+}
+
+WRITE32_MEMBER( sh2_device::bcr2_w )
+{
+ COMBINE_DATA(&m_bcr2);
+}
+
+READ32_MEMBER( sh2_device::wcr_r )
+{
+ return m_wcr;
+}
+
+WRITE32_MEMBER( sh2_device::wcr_w )
+{
+ COMBINE_DATA(&m_wcr);
+}
- case 0x20:
- return (((m_wtcsr | 0x18) & 0xff) << 24) | ((m_wtcnt & 0xff) << 16);
+READ32_MEMBER( sh2_device::mcr_r )
+{
+ return m_mcr & ~0x103;
+}
+
+WRITE32_MEMBER( sh2_device::mcr_w )
+{
+ COMBINE_DATA(&m_mcr);
+}
- case 0x24: // SBYCR, CCR
- return m_m[0x24] & ~0x3000; /* bit 4-5 of CCR are always zero */
+READ32_MEMBER( sh2_device::rtcsr_r )
+{
+ return m_rtcsr & 0xf8;
+}
+
+WRITE32_MEMBER( sh2_device::rtcsr_w )
+{
+ COMBINE_DATA(&m_rtcsr);
+}
- case 0x38: // ICR, IPRA
- return (m_m[0x38] & 0x7fffffff) | (m_nmi_line_state == ASSERT_LINE ? 0 : 0x80000000);
+READ32_MEMBER( sh2_device::rtcnt_r )
+{
+ return m_rtcnt & 0xff;
+}
- case 0x78: // BCR1
- return (m_is_slave ? 0x00008000 : 0) | (m_m[0x78] & 0x7fff);
+WRITE32_MEMBER( sh2_device::rtcnt_w )
+{
+ COMBINE_DATA(&m_rtcnt);
+ m_rtcnt &= 0xff;
+}
- case 0x41: // dvdntl mirrors
- case 0x47:
- return m_m[0x45];
+READ32_MEMBER( sh2_device::rtcor_r )
+{
+ return m_rtcor & 0xff;
+}
- case 0x46: // dvdnth mirror
- return m_m[0x44];
- }
- return m_m[offset];
+WRITE32_MEMBER( sh2_device::rtcor_w )
+{
+ COMBINE_DATA(&m_rtcor);
+ m_rtcor &= 0xff;
}
void sh2_device::set_frt_input(int state)
@@ -730,7 +997,7 @@ void sh2_device::set_frt_input(int state)
m_frt_input = state;
- if(m_m[5] & 0x8000) {
+ if(m_frc_tcr & 0x80) {
if(state == CLEAR_LINE) {
return;
}
@@ -741,8 +1008,8 @@ void sh2_device::set_frt_input(int state)
}
sh2_timer_resync();
- m_icr = m_frc;
- m_m[4] |= ICF;
+ m_frc_icr = m_frc;
+ m_ftcsr |= ICF;
//logerror("SH2.%s: ICF activated (%x)\n", tag(), m_sh2_state->pc & AM);
sh2_recalc_irq();
}
@@ -753,37 +1020,37 @@ void sh2_device::sh2_recalc_irq()
int level;
// Timer irqs
- if((m_m[4]>>8) & m_m[4] & (ICF|OCFA|OCFB|OVF))
+ if (m_tier & m_ftcsr & (ICF|OCFA|OCFB|OVF))
{
- level = (m_m[0x18] >> 24) & 15;
- if(level > irq)
+ level = (m_irq_level.frc & 15);
+ if (level > irq)
{
- int mask = (m_m[4]>>8) & m_m[4];
+ int mask = m_tier & m_ftcsr;
irq = level;
if(mask & ICF)
- vector = (m_m[0x19] >> 8) & 0x7f;
+ vector = m_irq_vector.fic & 0x7f;
else if(mask & (OCFA|OCFB))
- vector = m_m[0x19] & 0x7f;
+ vector = m_irq_vector.foc & 0x7f;
else
- vector = (m_m[0x1a] >> 24) & 0x7f;
+ vector = m_irq_vector.fov & 0x7f;
}
}
// DMA irqs
- if((m_m[0x63] & 6) == 6 && m_dma_irq[0]) {
- level = (m_m[0x38] >> 8) & 15;
+ 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_m[0x68]) & 0x7f;
+ vector = m_irq_vector.dmac[0] & 0x7f;
}
}
- else if((m_m[0x67] & 6) == 6 && m_dma_irq[1]) {
- level = (m_m[0x38] >> 8) & 15;
+ 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_m[0x6a]) & 0x7f;
+ vector = m_irq_vector.dmac[1] & 0x7f;
}
}
diff --git a/src/devices/cpu/sh/sh2comn.h b/src/devices/cpu/sh/sh2comn.h
index fb1e63eac19..53f5e04d2e6 100644
--- a/src/devices/cpu/sh/sh2comn.h
+++ b/src/devices/cpu/sh/sh2comn.h
@@ -15,10 +15,11 @@
enum
{
- ICF = 0x00800000,
- OCFA = 0x00080000,
- OCFB = 0x00040000,
- OVF = 0x00020000
+ ICF = 0x80,
+ OCFA = 0x08,
+ OCFB = 0x04,
+ OVF = 0x02,
+ CCLRA = 0x01
};
#define SH12_AM 0xc7ffffff