summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/sharc/sharc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/sharc/sharc.cpp')
-rw-r--r--src/devices/cpu/sharc/sharc.cpp191
1 files changed, 115 insertions, 76 deletions
diff --git a/src/devices/cpu/sharc/sharc.cpp b/src/devices/cpu/sharc/sharc.cpp
index db6ed397374..f03dd5bbfc4 100644
--- a/src/devices/cpu/sharc/sharc.cpp
+++ b/src/devices/cpu/sharc/sharc.cpp
@@ -10,8 +10,6 @@
#include "sharcfe.h"
#include "sharcdsm.h"
-#include "debugger.h"
-
#define DISABLE_FAST_REGISTERS 1
@@ -85,10 +83,32 @@ adsp21062_device::adsp21062_device(const machine_config &mconfig, const char *ta
, m_cache(CACHE_SIZE + sizeof(sharc_internal_state))
, m_drcuml(nullptr)
, m_drcfe(nullptr)
+ , m_entry(nullptr)
+ , m_nocode(nullptr)
+ , m_out_of_cycles(nullptr)
+ , m_pm_read48(nullptr)
+ , m_pm_write48(nullptr)
+ , m_pm_read32(nullptr)
+ , m_pm_write32(nullptr)
+ , m_dm_read32(nullptr)
+ , m_dm_write32(nullptr)
+ , m_push_pc(nullptr)
+ , m_pop_pc(nullptr)
+ , m_push_loop(nullptr)
+ , m_pop_loop(nullptr)
+ , m_push_status(nullptr)
+ , m_pop_status(nullptr)
+ , m_swap_dag1_0_3(nullptr)
+ , m_swap_dag1_4_7(nullptr)
+ , m_swap_dag2_0_3(nullptr)
+ , m_swap_dag2_4_7(nullptr)
+ , m_swap_r0_7(nullptr)
+ , m_swap_r8_15(nullptr)
, m_block0(*this, "block0")
, m_block1(*this, "block1")
, m_enable_drc(false)
{
+ std::fill(std::begin(m_exception), std::end(m_exception), nullptr);
}
adsp21062_device::~adsp21062_device()
@@ -172,7 +192,7 @@ void adsp21062_device::sharc_iop_delayed_w(uint32_t reg, uint32_t data, int cycl
// 3 ab9 5h 5l 4l
// 4 cde 6h 6l 7h
-READ64_MEMBER( adsp21062_device::pm0_r)
+uint64_t adsp21062_device::pm0_r(offs_t offset)
{
offs_t slot = offset >> 12;
offs_t base = (offset & 0xfff) + (slot >> 1) * (3<<12);
@@ -182,7 +202,7 @@ READ64_MEMBER( adsp21062_device::pm0_r)
return (uint64_t(m_block0[base ]) << 16) | (m_block0[base + 0x1000] >> 16);
}
-WRITE64_MEMBER(adsp21062_device::pm0_w)
+void adsp21062_device::pm0_w(offs_t offset, uint64_t data, uint64_t mem_mask)
{
offs_t slot = offset >> 12;
offs_t base = (offset & 0xfff) + (slot >> 1) * (3<<12);
@@ -197,7 +217,7 @@ WRITE64_MEMBER(adsp21062_device::pm0_w)
}
}
-READ64_MEMBER( adsp21062_device::pm1_r)
+uint64_t adsp21062_device::pm1_r(offs_t offset)
{
offs_t slot = offset >> 12;
offs_t base = (offset & 0xfff) + (slot >> 1) * (3<<12);
@@ -207,7 +227,7 @@ READ64_MEMBER( adsp21062_device::pm1_r)
return (uint64_t(m_block1[base ]) << 16) | (m_block1[base + 0x1000] >> 16);
}
-WRITE64_MEMBER(adsp21062_device::pm1_w)
+void adsp21062_device::pm1_w(offs_t offset, uint64_t data, uint64_t mem_mask)
{
offs_t slot = offset >> 12;
offs_t base = (offset & 0xfff) + (slot >> 1) * (3<<12);
@@ -222,7 +242,7 @@ WRITE64_MEMBER(adsp21062_device::pm1_w)
}
}
-READ32_MEMBER( adsp21062_device::dmw0_r)
+uint32_t adsp21062_device::dmw0_r(offs_t offset)
{
if(offset & 1)
return m_block0[offset >> 1] >> 16;
@@ -230,7 +250,7 @@ READ32_MEMBER( adsp21062_device::dmw0_r)
return m_block0[offset >> 1] & 0xffff;
}
-WRITE32_MEMBER(adsp21062_device::dmw0_w)
+void adsp21062_device::dmw0_w(offs_t offset, uint32_t data)
{
if(offset & 1)
m_block0[offset >> 1] = (m_block0[offset >> 1] & 0xffff) | (data << 16);
@@ -238,7 +258,7 @@ WRITE32_MEMBER(adsp21062_device::dmw0_w)
m_block0[offset >> 1] = (m_block0[offset >> 1] & 0xffff0000) | (data & 0xffff);
}
-READ32_MEMBER( adsp21062_device::dmw1_r)
+uint32_t adsp21062_device::dmw1_r(offs_t offset)
{
if(offset & 1)
return m_block1[offset >> 1] >> 16;
@@ -246,7 +266,7 @@ READ32_MEMBER( adsp21062_device::dmw1_r)
return m_block1[offset >> 1] & 0xffff;
}
-WRITE32_MEMBER(adsp21062_device::dmw1_w)
+void adsp21062_device::dmw1_w(offs_t offset, uint32_t data)
{
if(offset & 1)
m_block1[offset >> 1] = (m_block1[offset >> 1] & 0xffff) | (data << 16);
@@ -255,7 +275,7 @@ WRITE32_MEMBER(adsp21062_device::dmw1_w)
}
/* IOP registers */
-READ32_MEMBER( adsp21062_device::iop_r)
+uint32_t adsp21062_device::iop_r(offs_t offset)
{
switch (offset)
{
@@ -273,7 +293,7 @@ READ32_MEMBER( adsp21062_device::iop_r)
}
}
-WRITE32_MEMBER(adsp21062_device::iop_w)
+void adsp21062_device::iop_w(offs_t offset, uint32_t data)
{
switch (offset)
{
@@ -321,7 +341,10 @@ WRITE32_MEMBER(adsp21062_device::iop_w)
case 0x1c:
{
m_core->dma[6].control = data;
- sharc_iop_delayed_w(0x1c, data, 1);
+ if (data & 0x1)
+ {
+ sharc_iop_delayed_w(0x1c, data, 1);
+ }
break;
}
@@ -340,7 +363,10 @@ WRITE32_MEMBER(adsp21062_device::iop_w)
case 0x1d:
{
m_core->dma[7].control = data;
- sharc_iop_delayed_w(0x1d, data, 30);
+ if (data & 0x1)
+ {
+ sharc_iop_delayed_w(0x1d, data, 30);
+ }
break;
}
@@ -448,8 +474,6 @@ void adsp21062_device::external_dma_write(uint32_t address, uint64_t data)
void adsp21062_device::device_start()
{
- int saveindex;
-
m_core = (sharc_internal_state *)m_cache.alloc_near(sizeof(sharc_internal_state));
memset(m_core, 0, sizeof(sharc_internal_state));
@@ -466,34 +490,22 @@ void adsp21062_device::device_start()
m_drcuml->symbol_add(&m_core->pc, sizeof(m_core->pc), "pc");
m_drcuml->symbol_add(&m_core->icount, sizeof(m_core->icount), "icount");
- for (int i=0; i < 16; i++)
+ for (int i = 0; i < 16; i++)
{
char buf[10];
- sprintf(buf, "r%d", i);
+
+ snprintf(buf, std::size(buf), "r%d", i);
m_drcuml->symbol_add(&m_core->r[i], sizeof(m_core->r[i]), buf);
- if (i < 8)
- {
- sprintf(buf, "dag_i%d", i);
- m_drcuml->symbol_add(&m_core->dag1.i[i & 7], sizeof(m_core->dag1.i[i & 7]), buf);
- sprintf(buf, "dag_m%d", i);
- m_drcuml->symbol_add(&m_core->dag1.m[i & 7], sizeof(m_core->dag1.m[i & 7]), buf);
- sprintf(buf, "dag_l%d", i);
- m_drcuml->symbol_add(&m_core->dag1.l[i & 7], sizeof(m_core->dag1.l[i & 7]), buf);
- sprintf(buf, "dag_b%d", i);
- m_drcuml->symbol_add(&m_core->dag1.b[i & 7], sizeof(m_core->dag1.b[i & 7]), buf);
- }
- else
- {
- sprintf(buf, "dag_i%d", i);
- m_drcuml->symbol_add(&m_core->dag2.i[i & 7], sizeof(m_core->dag2.i[i & 7]), buf);
- sprintf(buf, "dag_m%d", i);
- m_drcuml->symbol_add(&m_core->dag2.m[i & 7], sizeof(m_core->dag2.m[i & 7]), buf);
- sprintf(buf, "dag_l%d", i);
- m_drcuml->symbol_add(&m_core->dag2.l[i & 7], sizeof(m_core->dag2.l[i & 7]), buf);
- sprintf(buf, "dag_b%d", i);
- m_drcuml->symbol_add(&m_core->dag2.b[i & 7], sizeof(m_core->dag2.b[i & 7]), buf);
- }
+ SHARC_DAG &dag((i < 8) ? m_core->dag1 : m_core->dag2);
+ snprintf(buf, std::size(buf), "dag_i%d", i);
+ m_drcuml->symbol_add(&dag.i[i & 7], sizeof(dag.i[i & 7]), buf);
+ snprintf(buf, std::size(buf), "dag_m%d", i);
+ m_drcuml->symbol_add(&dag.m[i & 7], sizeof(dag.m[i & 7]), buf);
+ snprintf(buf, std::size(buf), "dag_l%d", i);
+ m_drcuml->symbol_add(&dag.l[i & 7], sizeof(dag.l[i & 7]), buf);
+ snprintf(buf, std::size(buf), "dag_b%d", i);
+ m_drcuml->symbol_add(&dag.b[i & 7], sizeof(dag.b[i & 7]), buf);
}
m_drcuml->symbol_add(&m_core->astat, sizeof(m_core->astat), "astat");
@@ -556,7 +568,7 @@ void adsp21062_device::device_start()
m_core->cache_dirty = 1;
- m_core->delayed_iop_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(adsp21062_device::sharc_iop_delayed_write_callback), this));
+ m_core->delayed_iop_timer = timer_alloc(FUNC(adsp21062_device::sharc_iop_delayed_write_callback), this);
for (auto & elem : m_core->dma_op)
{
@@ -570,7 +582,7 @@ void adsp21062_device::device_start()
elem.pmode = 0;
elem.chained_direction = 0;
elem.active = false;
- elem.timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(adsp21062_device::sharc_dma_callback), this));
+ elem.timer = timer_alloc(FUNC(adsp21062_device::sharc_dma_callback), this);
}
for (int i=0; i < 16; i++)
@@ -650,8 +662,8 @@ void adsp21062_device::device_start()
m_core->fp1 = 1.0f;
save_item(NAME(m_core->pc));
- save_pointer(NAME(&m_core->r[0].r), ARRAY_LENGTH(m_core->r));
- save_pointer(NAME(&m_core->reg_alt[0].r), ARRAY_LENGTH(m_core->reg_alt));
+ save_pointer(NAME(&m_core->r[0].r), std::size(m_core->r));
+ save_pointer(NAME(&m_core->reg_alt[0].r), std::size(m_core->reg_alt));
save_item(NAME(m_core->mrf));
save_item(NAME(m_core->mrb));
@@ -687,18 +699,15 @@ void adsp21062_device::device_start()
save_item(NAME(m_core->dag2_alt.b));
save_item(NAME(m_core->dag2_alt.l));
- for (saveindex = 0; saveindex < ARRAY_LENGTH(m_core->dma); saveindex++)
- {
- save_item(NAME(m_core->dma[saveindex].control), saveindex);
- save_item(NAME(m_core->dma[saveindex].int_index), saveindex);
- save_item(NAME(m_core->dma[saveindex].int_modifier), saveindex);
- save_item(NAME(m_core->dma[saveindex].int_count), saveindex);
- save_item(NAME(m_core->dma[saveindex].chain_ptr), saveindex);
- save_item(NAME(m_core->dma[saveindex].gen_purpose), saveindex);
- save_item(NAME(m_core->dma[saveindex].ext_index), saveindex);
- save_item(NAME(m_core->dma[saveindex].ext_modifier), saveindex);
- save_item(NAME(m_core->dma[saveindex].ext_count), saveindex);
- }
+ save_item(STRUCT_MEMBER(m_core->dma, control));
+ save_item(STRUCT_MEMBER(m_core->dma, int_index));
+ save_item(STRUCT_MEMBER(m_core->dma, int_modifier));
+ save_item(STRUCT_MEMBER(m_core->dma, int_count));
+ save_item(STRUCT_MEMBER(m_core->dma, chain_ptr));
+ save_item(STRUCT_MEMBER(m_core->dma, gen_purpose));
+ save_item(STRUCT_MEMBER(m_core->dma, ext_index));
+ save_item(STRUCT_MEMBER(m_core->dma, ext_modifier));
+ save_item(STRUCT_MEMBER(m_core->dma, ext_count));
save_item(NAME(m_core->mode1));
save_item(NAME(m_core->mode2));
@@ -715,11 +724,8 @@ void adsp21062_device::device_start()
save_item(NAME(m_core->syscon));
save_item(NAME(m_core->sysstat));
- for (saveindex = 0; saveindex < ARRAY_LENGTH(m_core->status_stack); saveindex++)
- {
- save_item(NAME(m_core->status_stack[saveindex].mode1), saveindex);
- save_item(NAME(m_core->status_stack[saveindex].astat), saveindex);
- }
+ save_item(STRUCT_MEMBER(m_core->status_stack, mode1));
+ save_item(STRUCT_MEMBER(m_core->status_stack, astat));
save_item(NAME(m_core->status_stkp));
save_item(NAME(m_core->px));
@@ -732,19 +738,16 @@ void adsp21062_device::device_start()
save_item(NAME(m_core->irq_pending));
save_item(NAME(m_core->active_irq_num));
- for (saveindex = 0; saveindex < ARRAY_LENGTH(m_core->dma_op); saveindex++)
- {
- save_item(NAME(m_core->dma_op[saveindex].src), saveindex);
- save_item(NAME(m_core->dma_op[saveindex].dst), saveindex);
- save_item(NAME(m_core->dma_op[saveindex].chain_ptr), saveindex);
- save_item(NAME(m_core->dma_op[saveindex].src_modifier), saveindex);
- save_item(NAME(m_core->dma_op[saveindex].dst_modifier), saveindex);
- save_item(NAME(m_core->dma_op[saveindex].src_count), saveindex);
- save_item(NAME(m_core->dma_op[saveindex].dst_count), saveindex);
- save_item(NAME(m_core->dma_op[saveindex].pmode), saveindex);
- save_item(NAME(m_core->dma_op[saveindex].chained_direction), saveindex);
- save_item(NAME(m_core->dma_op[saveindex].active), saveindex);
- }
+ save_item(STRUCT_MEMBER(m_core->dma_op, src));
+ save_item(STRUCT_MEMBER(m_core->dma_op, dst));
+ save_item(STRUCT_MEMBER(m_core->dma_op, chain_ptr));
+ save_item(STRUCT_MEMBER(m_core->dma_op, src_modifier));
+ save_item(STRUCT_MEMBER(m_core->dma_op, dst_modifier));
+ save_item(STRUCT_MEMBER(m_core->dma_op, src_count));
+ save_item(STRUCT_MEMBER(m_core->dma_op, dst_count));
+ save_item(STRUCT_MEMBER(m_core->dma_op, pmode));
+ save_item(STRUCT_MEMBER(m_core->dma_op, chained_direction));
+ save_item(STRUCT_MEMBER(m_core->dma_op, active));
save_item(NAME(m_core->dma_status));
@@ -961,6 +964,19 @@ void adsp21062_device::set_flag_input(int flag_num, int state)
}
}
+void adsp21062_device::write_stall(int state)
+{
+ m_core->write_stalled = (state == 0) ? false : true;
+
+ if (m_enable_drc)
+ {
+ if (m_core->write_stalled)
+ spin_until_trigger(45757);
+ else
+ machine().scheduler().trigger(45757);
+ }
+}
+
void adsp21062_device::check_interrupts()
{
int i;
@@ -1017,10 +1033,27 @@ void adsp21062_device::execute_run()
}
else
{
+ if (m_core->write_stalled)
+ eat_cycles(m_core->icount);
+
if (m_core->idle && m_core->irq_pending == 0)
{
+ debugger_wait_hook();
+
+ int dma_count = m_core->icount;
+
+ // run active DMAs even while idling
+ while (dma_count > 0 && m_core->dma_status & ((1 << 6) | (1 << 7)))
+ {
+ if (!m_core->write_stalled)
+ {
+ dma_run_cycle(6);
+ dma_run_cycle(7);
+ }
+ dma_count--;
+ }
+
m_core->icount = 0;
- debugger_instruction_hook(m_core->daddr);
}
if (m_core->irq_pending != 0)
{
@@ -1028,7 +1061,7 @@ void adsp21062_device::execute_run()
m_core->idle = 0;
}
- while (m_core->icount > 0 && !m_core->idle)
+ while (m_core->icount > 0 && !m_core->idle && !m_core->write_stalled)
{
m_core->pc = m_core->daddr;
m_core->daddr = m_core->faddr;
@@ -1115,6 +1148,12 @@ void adsp21062_device::execute_run()
}
}
+ if (!m_core->write_stalled)
+ {
+ dma_run_cycle(6);
+ dma_run_cycle(7);
+ }
+
--m_core->icount;
};
}