summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices')
-rw-r--r--src/devices/cpu/rsp/rsp.cpp282
-rw-r--r--src/devices/cpu/rsp/rsp.h46
-rw-r--r--src/devices/cpu/z80/nsc800.cpp12
-rw-r--r--src/devices/cpu/z80/z80.cpp33
-rw-r--r--src/devices/cpu/z80/z80.h15
-rw-r--r--src/devices/cpu/z80/z80.lst110
-rw-r--r--src/devices/cpu/z80/z80make.py28
-rw-r--r--src/devices/cpu/z80/z80n.h2
-rw-r--r--src/devices/machine/netlist.cpp13
9 files changed, 301 insertions, 240 deletions
diff --git a/src/devices/cpu/rsp/rsp.cpp b/src/devices/cpu/rsp/rsp.cpp
index f39d79b21bb..b58b7169e80 100644
--- a/src/devices/cpu/rsp/rsp.cpp
+++ b/src/devices/cpu/rsp/rsp.cpp
@@ -62,11 +62,6 @@ DEFINE_DEVICE_TYPE(RSP, rsp_device, "rsp", "Nintendo & SGI Reality Signal Proces
#define ZERO 3
#define CLIP2 4
-#define SLICE_H 3
-#define SLICE_M 2
-#define SLICE_L 1
-#define SLICE_LL 0
-
#define WRITEBACK_RESULT() memcpy(m_v[VDREG].s, vres, sizeof(uint16_t) * 8);
static const int vector_elements_2[16][8] =
@@ -265,7 +260,7 @@ void rsp_device::device_start()
for (int regIdx = 0; regIdx < 32; regIdx++)
m_r[regIdx] = 0;
- for(auto & elem : m_v)
+ for (auto & elem : m_v)
{
elem.d[0] = 0;
elem.d[1] = 0;
@@ -284,7 +279,7 @@ void rsp_device::device_start()
m_vector_busy = false;
m_paired_busy = false;
- for(auto & elem : m_accum)
+ for (auto & elem : m_accum)
{
elem.q = 0;
}
@@ -294,6 +289,35 @@ void rsp_device::device_start()
m_sr = RSP_STATUS_HALT;
m_step_count = 0;
+ // register for savestates
+ save_item(NAME(m_pc));
+ save_item(NAME(m_r));
+ save_item(NAME(m_ideduct));
+ save_item(NAME(m_scalar_busy));
+ save_item(NAME(m_vector_busy));
+ save_item(NAME(m_paired_busy));
+
+ save_item(NAME(m_sr));
+ save_item(NAME(m_step_count));
+ save_item(NAME(m_ppc));
+ save_item(NAME(m_nextpc));
+
+ save_item(NAME(m_vres));
+ save_item(NAME(m_accum));
+ save_item(NAME(m_vcarry));
+ save_item(NAME(m_vcompare));
+ save_item(NAME(m_vclip1));
+ save_item(NAME(m_vzero));
+ save_item(NAME(m_vclip2));
+
+ for (int i = 0; i < std::size(m_v); i++)
+ save_item(NAME(m_v[i].d), i);
+
+ save_item(NAME(m_reciprocal_res));
+ save_item(NAME(m_reciprocal_high));
+ save_item(NAME(m_dp_allowed));
+
+ // register state for debugger
state_add( RSP_PC, "PC", m_pc).callimport().callexport().formatstr("%08X");
state_add( RSP_R0, "R0", m_r[0]).formatstr("%08X");
state_add( RSP_R1, "R1", m_r[1]).formatstr("%08X");
@@ -528,15 +552,15 @@ void rsp_device::device_reset()
uint16_t rsp_device::SATURATE_ACCUM(int accum, int slice, uint16_t negative, uint16_t positive)
{
- if ((int16_t)m_accum[accum].w[SLICE_H] < 0)
+ if ((int16_t)m_accum[accum].w.h3 < 0)
{
- if ((uint16_t)m_accum[accum].w[SLICE_H] != 0xffff)
+ if ((uint16_t)m_accum[accum].w.h3 != 0xffff)
{
return negative;
}
else
{
- if ((int16_t)m_accum[accum].w[SLICE_M] >= 0)
+ if ((int16_t)m_accum[accum].w.h2 >= 0)
{
return negative;
}
@@ -544,24 +568,24 @@ uint16_t rsp_device::SATURATE_ACCUM(int accum, int slice, uint16_t negative, uin
{
if (slice == 0)
{
- return m_accum[accum].w[SLICE_L];
+ return m_accum[accum].w.h;
}
else if (slice == 1)
{
- return m_accum[accum].w[SLICE_M];
+ return m_accum[accum].w.h2;
}
}
}
}
else
{
- if ((uint16_t)m_accum[accum].w[SLICE_H] != 0)
+ if ((uint16_t)m_accum[accum].w.h3 != 0)
{
return positive;
}
else
{
- if ((int16_t)m_accum[accum].w[SLICE_M] < 0)
+ if ((int16_t)m_accum[accum].w.h2 < 0)
{
return positive;
}
@@ -569,11 +593,11 @@ uint16_t rsp_device::SATURATE_ACCUM(int accum, int slice, uint16_t negative, uin
{
if (slice == 0)
{
- return m_accum[accum].w[SLICE_L];
+ return m_accum[accum].w.h;
}
else
{
- return m_accum[accum].w[SLICE_M];
+ return m_accum[accum].w.h2;
}
}
}
@@ -610,19 +634,19 @@ void rsp_device::handle_vector_ops(uint32_t op)
if (s1 == -32768 && s2 == -32768)
{
// overflow
- m_accum[i].w[SLICE_H] = 0;
- m_accum[i].w[SLICE_M] = -32768;
- m_accum[i].w[SLICE_L] = -32768;
+ m_accum[i].w.h3 = 0;
+ m_accum[i].w.h2 = -32768;
+ m_accum[i].w.h = -32768;
vres[i] = 0x7fff;
}
else
{
int64_t r = s1 * s2 * 2;
r += 0x8000; // rounding ?
- m_accum[i].w[SLICE_H] = (r < 0) ? 0xffff : 0; // Sign-extend to 48-bit
- m_accum[i].w[SLICE_M] = (int16_t)(r >> 16);
- m_accum[i].w[SLICE_L] = (uint16_t)r;
- vres[i] = m_accum[i].w[SLICE_M];
+ m_accum[i].w.h3 = (r < 0) ? 0xffff : 0; // Sign-extend to 48-bit
+ m_accum[i].w.h2 = (int16_t)(r >> 16);
+ m_accum[i].w.h = (uint16_t)r;
+ vres[i] = m_accum[i].w.h2;
}
}
WRITEBACK_RESULT();
@@ -645,21 +669,21 @@ void rsp_device::handle_vector_ops(uint32_t op)
int64_t r = s1 * s2 * 2;
r += 0x8000; // rounding ?
- m_accum[i].w[SLICE_H] = (uint16_t)(r >> 32);
- m_accum[i].w[SLICE_M] = (uint16_t)(r >> 16);
- m_accum[i].w[SLICE_L] = (uint16_t)r;
+ m_accum[i].w.h3 = (uint16_t)(r >> 32);
+ m_accum[i].w.h2 = (uint16_t)(r >> 16);
+ m_accum[i].w.h = (uint16_t)r;
if (r < 0)
{
vres[i] = 0;
}
- else if (((int16_t)m_accum[i].w[SLICE_H] ^ (int16_t)m_accum[i].w[SLICE_M]) < 0)
+ else if (((int16_t)m_accum[i].w.h3 ^ (int16_t)m_accum[i].w.h2) < 0)
{
vres[i] = -1;
}
else
{
- vres[i] = m_accum[i].w[SLICE_M];
+ vres[i] = m_accum[i].w.h2;
}
}
WRITEBACK_RESULT();
@@ -683,11 +707,11 @@ void rsp_device::handle_vector_ops(uint32_t op)
uint32_t s2 = m_v[VS2REG].w[VEC_EL_2(EL, i)];
uint32_t r = s1 * s2;
- m_accum[i].w[SLICE_H] = 0;
- m_accum[i].w[SLICE_M] = 0;
- m_accum[i].w[SLICE_L] = (uint16_t)(r >> 16);
+ m_accum[i].w.h3 = 0;
+ m_accum[i].w.h2 = 0;
+ m_accum[i].w.h = (uint16_t)(r >> 16);
- vres[i] = m_accum[i].w[SLICE_L];
+ vres[i] = m_accum[i].w.h;
}
WRITEBACK_RESULT();
break;
@@ -710,11 +734,11 @@ void rsp_device::handle_vector_ops(uint32_t op)
int32_t s2 = m_v[VS2REG].w[VEC_EL_2(EL, i)]; // not sign-extended
int32_t r = s1 * s2;
- m_accum[i].w[SLICE_H] = (r < 0) ? 0xffff : 0; // sign-extend to 48-bit
- m_accum[i].w[SLICE_M] = (int16_t)(r >> 16);
- m_accum[i].w[SLICE_L] = (uint16_t)r;
+ m_accum[i].w.h3 = (r < 0) ? 0xffff : 0; // sign-extend to 48-bit
+ m_accum[i].w.h2 = (int16_t)(r >> 16);
+ m_accum[i].w.h = (uint16_t)r;
- vres[i] = m_accum[i].w[SLICE_M];
+ vres[i] = m_accum[i].w.h2;
}
WRITEBACK_RESULT();
break;
@@ -737,11 +761,11 @@ void rsp_device::handle_vector_ops(uint32_t op)
int32_t s2 = m_v[VS2REG].s[VEC_EL_2(EL, i)];
int32_t r = s1 * s2;
- m_accum[i].w[SLICE_H] = (r < 0) ? 0xffff : 0; // sign-extend to 48-bit
- m_accum[i].w[SLICE_M] = (int16_t)(r >> 16);
- m_accum[i].w[SLICE_L] = (uint16_t)(r);
+ m_accum[i].w.h3 = (r < 0) ? 0xffff : 0; // sign-extend to 48-bit
+ m_accum[i].w.h2 = (int16_t)(r >> 16);
+ m_accum[i].w.h = (uint16_t)(r);
- vres[i] = m_accum[i].w[SLICE_L];
+ vres[i] = m_accum[i].w.h;
}
WRITEBACK_RESULT();
break;
@@ -764,9 +788,9 @@ void rsp_device::handle_vector_ops(uint32_t op)
int32_t s2 = m_v[VS2REG].s[VEC_EL_2(EL, i)];
int32_t r = s1 * s2;
- m_accum[i].w[SLICE_H] = (int16_t)(r >> 16);
- m_accum[i].w[SLICE_M] = (uint16_t)(r);
- m_accum[i].w[SLICE_L] = 0;
+ m_accum[i].w.h3 = (int16_t)(r >> 16);
+ m_accum[i].w.h2 = (uint16_t)(r);
+ m_accum[i].w.h = 0;
if (r < -32768) r = -32768;
if (r > 32767) r = 32767;
@@ -792,17 +816,17 @@ void rsp_device::handle_vector_ops(uint32_t op)
int32_t s2 = m_v[VS2REG].s[VEC_EL_2(EL, i)];
int32_t r = s1 * s2;
- uint64_t q = (uint64_t)(uint16_t)m_accum[i].w[SLICE_LL];
- q |= (((uint64_t)(uint16_t)m_accum[i].w[SLICE_L]) << 16);
- q |= (((uint64_t)(uint16_t)m_accum[i].w[SLICE_M]) << 32);
- q |= (((uint64_t)(uint16_t)m_accum[i].w[SLICE_H]) << 48);
+ uint64_t q = (uint64_t)(uint16_t)m_accum[i].w.l;
+ q |= (((uint64_t)(uint16_t)m_accum[i].w.h) << 16);
+ q |= (((uint64_t)(uint16_t)m_accum[i].w.h2) << 32);
+ q |= (((uint64_t)(uint16_t)m_accum[i].w.h3) << 48);
q += (int64_t)(r) << 17;
- m_accum[i].w[SLICE_LL] = (uint16_t)q;
- m_accum[i].w[SLICE_L] = (uint16_t)(q >> 16);
- m_accum[i].w[SLICE_M] = (uint16_t)(q >> 32);
- m_accum[i].w[SLICE_H] = (uint16_t)(q >> 48);
+ m_accum[i].w.l = (uint16_t)q;
+ m_accum[i].w.h = (uint16_t)(q >> 16);
+ m_accum[i].w.h2 = (uint16_t)(q >> 32);
+ m_accum[i].w.h3 = (uint16_t)(q >> 48);
vres[i] = SATURATE_ACCUM(i, 1, 0x8000, 0x7fff);
}
@@ -823,32 +847,32 @@ void rsp_device::handle_vector_ops(uint32_t op)
int32_t s1 = m_v[VS1REG].s[i];
int32_t s2 = m_v[VS2REG].s[VEC_EL_2(EL, i)];
int32_t r1 = s1 * s2;
- uint32_t r2 = m_accum[i].w[SLICE_L] + ((uint16_t)r1 * 2);
- uint32_t r3 = m_accum[i].w[SLICE_M] + (uint16_t)((r1 >> 16) * 2) + (uint16_t)(r2 >> 16);
+ uint32_t r2 = m_accum[i].w.h + ((uint16_t)r1 * 2);
+ uint32_t r3 = m_accum[i].w.h2 + (uint16_t)((r1 >> 16) * 2) + (uint16_t)(r2 >> 16);
- m_accum[i].w[SLICE_L] = (uint16_t)r2;
- m_accum[i].w[SLICE_M] = (uint16_t)r3;
- m_accum[i].w[SLICE_H] += (uint16_t)(r3 >> 16) + (uint16_t)(r1 >> 31);
+ m_accum[i].w.h = (uint16_t)r2;
+ m_accum[i].w.h2 = (uint16_t)r3;
+ m_accum[i].w.h3 += (uint16_t)(r3 >> 16) + (uint16_t)(r1 >> 31);
- if ((int16_t)m_accum[i].w[SLICE_H] < 0)
+ if ((int16_t)m_accum[i].w.h3 < 0)
{
vres[i] = 0;
}
else
{
- if (m_accum[i].w[SLICE_H] != 0)
+ if (m_accum[i].w.h3 != 0)
{
vres[i] = 0xffff;
}
else
{
- if ((int16_t)m_accum[i].w[SLICE_M] < 0)
+ if ((int16_t)m_accum[i].w.h2 < 0)
{
vres[i] = 0xffff;
}
else
{
- vres[i] = m_accum[i].w[SLICE_M];
+ vres[i] = m_accum[i].w.h2;
}
}
}
@@ -873,12 +897,12 @@ void rsp_device::handle_vector_ops(uint32_t op)
uint32_t s1 = m_v[VS1REG].w[i];
uint32_t s2 = m_v[VS2REG].w[VEC_EL_2(EL, i)];
uint32_t r1 = s1 * s2;
- uint32_t r2 = m_accum[i].w[SLICE_L] + (r1 >> 16);
- uint32_t r3 = m_accum[i].w[SLICE_M] + (r2 >> 16);
+ uint32_t r2 = m_accum[i].w.h + (r1 >> 16);
+ uint32_t r3 = m_accum[i].w.h2 + (r2 >> 16);
- m_accum[i].w[SLICE_L] = (uint16_t)r2;
- m_accum[i].w[SLICE_M] = (uint16_t)r3;
- m_accum[i].w[SLICE_H] += (int16_t)(r3 >> 16);
+ m_accum[i].w.h = (uint16_t)r2;
+ m_accum[i].w.h2 = (uint16_t)r3;
+ m_accum[i].w.h3 += (int16_t)(r3 >> 16);
vres[i] = SATURATE_ACCUM(i, 0, 0x0000, 0xffff);
}
@@ -902,14 +926,14 @@ void rsp_device::handle_vector_ops(uint32_t op)
uint32_t s1 = m_v[VS1REG].s[i];
uint32_t s2 = m_v[VS2REG].w[VEC_EL_2(EL, i)]; // not sign-extended
uint32_t r1 = s1 * s2;
- uint32_t r2 = (uint16_t)m_accum[i].w[SLICE_L] + (uint16_t)(r1);
- uint32_t r3 = (uint16_t)m_accum[i].w[SLICE_M] + (r1 >> 16) + (r2 >> 16);
+ uint32_t r2 = (uint16_t)m_accum[i].w.h + (uint16_t)(r1);
+ uint32_t r3 = (uint16_t)m_accum[i].w.h2 + (r1 >> 16) + (r2 >> 16);
- m_accum[i].w[SLICE_L] = (uint16_t)r2;
- m_accum[i].w[SLICE_M] = (uint16_t)r3;
- m_accum[i].w[SLICE_H] += (uint16_t)(r3 >> 16);
+ m_accum[i].w.h = (uint16_t)r2;
+ m_accum[i].w.h2 = (uint16_t)r3;
+ m_accum[i].w.h3 += (uint16_t)(r3 >> 16);
if ((int32_t)r1 < 0)
- m_accum[i].w[SLICE_H] -= 1;
+ m_accum[i].w.h3 -= 1;
vres[i] = SATURATE_ACCUM(i, 1, 0x8000, 0x7fff);
}
@@ -933,16 +957,16 @@ void rsp_device::handle_vector_ops(uint32_t op)
int32_t s1 = m_v[VS1REG].w[i]; // not sign-extended
int32_t s2 = m_v[VS2REG].s[VEC_EL_2(EL, i)];
- uint64_t q = (uint64_t)m_accum[i].w[SLICE_LL];
- q |= (((uint64_t)m_accum[i].w[SLICE_L]) << 16);
- q |= (((uint64_t)m_accum[i].w[SLICE_M]) << 32);
- q |= (((uint64_t)m_accum[i].w[SLICE_H]) << 48);
+ uint64_t q = (uint64_t)m_accum[i].w.l;
+ q |= (((uint64_t)m_accum[i].w.h) << 16);
+ q |= (((uint64_t)m_accum[i].w.h2) << 32);
+ q |= (((uint64_t)m_accum[i].w.h3) << 48);
q += (int64_t)(s1*s2) << 16;
- m_accum[i].w[SLICE_LL] = (uint16_t)q;
- m_accum[i].w[SLICE_L] = (uint16_t)(q >> 16);
- m_accum[i].w[SLICE_M] = (uint16_t)(q >> 32);
- m_accum[i].w[SLICE_H] = (uint16_t)(q >> 48);
+ m_accum[i].w.l = (uint16_t)q;
+ m_accum[i].w.h = (uint16_t)(q >> 16);
+ m_accum[i].w.h2 = (uint16_t)(q >> 32);
+ m_accum[i].w.h3 = (uint16_t)(q >> 48);
vres[i] = SATURATE_ACCUM(i, 0, 0x0000, 0xffff);
}
@@ -967,12 +991,12 @@ void rsp_device::handle_vector_ops(uint32_t op)
int32_t s1 = m_v[VS1REG].s[i];
int32_t s2 = m_v[VS2REG].s[VEC_EL_2(EL, i)];
- int32_t accum = (uint32_t)(uint16_t)m_accum[i].w[SLICE_M];
- accum |= ((uint32_t)((uint16_t)m_accum[i].w[SLICE_H])) << 16;
+ int32_t accum = (uint32_t)(uint16_t)m_accum[i].w.h2;
+ accum |= ((uint32_t)((uint16_t)m_accum[i].w.h3)) << 16;
accum += s1 * s2;
- m_accum[i].w[SLICE_H] = (uint16_t)(accum >> 16);
- m_accum[i].w[SLICE_M] = (uint16_t)accum;
+ m_accum[i].w.h3 = (uint16_t)(accum >> 16);
+ m_accum[i].w.h2 = (uint16_t)accum;
vres[i] = SATURATE_ACCUM(i, 1, 0x8000, 0x7fff);
}
@@ -997,7 +1021,7 @@ void rsp_device::handle_vector_ops(uint32_t op)
int32_t s2 = m_v[VS2REG].s[VEC_EL_2(EL, i)];
int32_t r = s1 + s2 + BIT(m_vcarry, i);
- m_accum[i].w[SLICE_L] = (int16_t)r;
+ m_accum[i].w.h = (int16_t)r;
if (r > 32767) r = 32767;
if (r < -32768) r = -32768;
@@ -1026,7 +1050,7 @@ void rsp_device::handle_vector_ops(uint32_t op)
int32_t s2 = m_v[VS2REG].s[VEC_EL_2(EL, i)];
int32_t r = s1 - s2 - BIT(m_vcarry, i);
- m_accum[i].w[SLICE_L] = (int16_t)r;
+ m_accum[i].w.h = (int16_t)r;
if (r > 32767) r = 32767;
if (r < -32768) r = -32768;
@@ -1074,7 +1098,7 @@ void rsp_device::handle_vector_ops(uint32_t op)
vres[i] = 0;
}
- m_accum[i].w[SLICE_L] = vres[i];
+ m_accum[i].w.h = vres[i];
}
WRITEBACK_RESULT();
break;
@@ -1101,7 +1125,7 @@ void rsp_device::handle_vector_ops(uint32_t op)
int32_t r = s1 + s2;
vres[i] = (int16_t)r;
- m_accum[i].w[SLICE_L] = (int16_t)r;
+ m_accum[i].w.h = (int16_t)r;
if (r & 0xffff0000)
{
@@ -1133,7 +1157,7 @@ void rsp_device::handle_vector_ops(uint32_t op)
int32_t r = s1 - s2;
vres[i] = (int16_t)(r);
- m_accum[i].w[SLICE_L] = (uint16_t)r;
+ m_accum[i].w.h = (uint16_t)r;
if ((uint16_t)r != 0)
{
@@ -1163,7 +1187,7 @@ void rsp_device::handle_vector_ops(uint32_t op)
{
for (int i = 0; i < 8; i++)
{
- m_v[VDREG].w[i] = m_accum[i].w[SLICE_H];
+ m_v[VDREG].w[i] = m_accum[i].w.h3;
}
break;
}
@@ -1171,7 +1195,7 @@ void rsp_device::handle_vector_ops(uint32_t op)
{
for (int i = 0; i < 8; i++)
{
- m_v[VDREG].w[i] = m_accum[i].w[SLICE_M];
+ m_v[VDREG].w[i] = m_accum[i].w.h2;
}
break;
}
@@ -1179,7 +1203,7 @@ void rsp_device::handle_vector_ops(uint32_t op)
{
for (int i = 0; i < 8; i++)
{
- m_v[VDREG].w[i] = m_accum[i].w[SLICE_L];
+ m_v[VDREG].w[i] = m_accum[i].w.h;
}
break;
}
@@ -1228,7 +1252,7 @@ void rsp_device::handle_vector_ops(uint32_t op)
vres[i] = s2;
}
- m_accum[i].w[SLICE_L] = vres[i];
+ m_accum[i].w.h = vres[i];
}
m_vzero = 0;
@@ -1264,7 +1288,7 @@ void rsp_device::handle_vector_ops(uint32_t op)
{
vres[i] = s2;
}
- m_accum[i].w[SLICE_L] = vres[i];
+ m_accum[i].w.h = vres[i];
}
m_vzero = 0;
@@ -1301,7 +1325,7 @@ void rsp_device::handle_vector_ops(uint32_t op)
vres[i] = s2;
}
- m_accum[i].w[SLICE_L] = vres[i];
+ m_accum[i].w.h = vres[i];
}
m_vzero = 0;
@@ -1338,7 +1362,7 @@ void rsp_device::handle_vector_ops(uint32_t op)
vres[i] = s2;
}
- m_accum[i].w[SLICE_L] = vres[i];
+ m_accum[i].w.h = vres[i];
}
m_vzero = 0;
@@ -1367,11 +1391,11 @@ void rsp_device::handle_vector_ops(uint32_t op)
{
if (BIT(m_vcompare, i)) // vcc_lo
{
- m_accum[i].w[SLICE_L] = -(uint16_t)s2;
+ m_accum[i].w.h = -(uint16_t)s2;
}
else
{
- m_accum[i].w[SLICE_L] = s1;
+ m_accum[i].w.h = s1;
}
}
else
@@ -1380,12 +1404,12 @@ void rsp_device::handle_vector_ops(uint32_t op)
{
if (((uint32_t)(uint16_t)(s1) + (uint32_t)(uint16_t)(s2)) > 0x10000)
{
- m_accum[i].w[SLICE_L] = s1;
+ m_accum[i].w.h = s1;
m_vcompare &= ~(1 << i);
}
else
{
- m_accum[i].w[SLICE_L] = -(uint16_t)s2;
+ m_accum[i].w.h = -(uint16_t)s2;
m_vcompare |= 1 << i;
}
}
@@ -1393,12 +1417,12 @@ void rsp_device::handle_vector_ops(uint32_t op)
{
if (((uint32_t)(uint16_t)(s1) + (uint32_t)(uint16_t)(s2)) != 0)
{
- m_accum[i].w[SLICE_L] = s1;
+ m_accum[i].w.h = s1;
m_vcompare &= ~(1 << i);
}
else
{
- m_accum[i].w[SLICE_L] = -(uint16_t)s2;
+ m_accum[i].w.h = -(uint16_t)s2;
m_vcompare |= 1 << i;
}
}
@@ -1410,29 +1434,29 @@ void rsp_device::handle_vector_ops(uint32_t op)
{
if (BIT(m_vclip2, i)) // vcc_hi
{
- m_accum[i].w[SLICE_L] = s2;
+ m_accum[i].w.h = s2;
}
else
{
- m_accum[i].w[SLICE_L] = s1;
+ m_accum[i].w.h = s1;
}
}
else
{
if (((int32_t)(uint16_t)s1 - (int32_t)(uint16_t)s2) >= 0)
{
- m_accum[i].w[SLICE_L] = s2;
+ m_accum[i].w.h = s2;
m_vclip2 |= 1 << i;
}
else
{
- m_accum[i].w[SLICE_L] = s1;
+ m_accum[i].w.h = s1;
m_vclip2 &= ~(1 << i);
}
}
}
- vres[i] = m_accum[i].w[SLICE_L];
+ vres[i] = m_accum[i].w.h;
}
m_vzero = 0;
@@ -1521,7 +1545,7 @@ void rsp_device::handle_vector_ops(uint32_t op)
m_vclip1 |= 1 << i;
}
- m_accum[i].w[SLICE_L] = vres[i];
+ m_accum[i].w.h = vres[i];
}
WRITEBACK_RESULT();
break;
@@ -1555,12 +1579,12 @@ void rsp_device::handle_vector_ops(uint32_t op)
}
if ((s1 + s2) <= 0)
{
- m_accum[i].w[SLICE_L] = ~(uint16_t)s2;
+ m_accum[i].w.h = ~(uint16_t)s2;
m_vcompare |= 1 << i;
}
else
{
- m_accum[i].w[SLICE_L] = s1;
+ m_accum[i].w.h = s1;
}
}
else
@@ -1571,16 +1595,16 @@ void rsp_device::handle_vector_ops(uint32_t op)
}
if ((s1 - s2) >= 0)
{
- m_accum[i].w[SLICE_L] = s2;
+ m_accum[i].w.h = s2;
m_vclip2 |= 1 << i;
}
else
{
- m_accum[i].w[SLICE_L] = s1;
+ m_accum[i].w.h = s1;
}
}
- vres[i] = m_accum[i].w[SLICE_L];
+ vres[i] = m_accum[i].w.h;
}
WRITEBACK_RESULT();
break;
@@ -1606,7 +1630,7 @@ void rsp_device::handle_vector_ops(uint32_t op)
vres[i] = m_v[VS2REG].s[VEC_EL_2(EL, i)];
}
- m_accum[i].w[SLICE_L] = vres[i];
+ m_accum[i].w.h = vres[i];
}
WRITEBACK_RESULT();
break;
@@ -1624,7 +1648,7 @@ void rsp_device::handle_vector_ops(uint32_t op)
for (int i = 0; i < 8; i++)
{
vres[i] = m_v[VS1REG].w[i] & m_v[VS2REG].w[VEC_EL_2(EL, i)];
- m_accum[i].w[SLICE_L] = vres[i];
+ m_accum[i].w.h = vres[i];
}
WRITEBACK_RESULT();
break;
@@ -1642,7 +1666,7 @@ void rsp_device::handle_vector_ops(uint32_t op)
for (int i = 0; i < 8; i++)
{
vres[i] = ~(m_v[VS1REG].w[i] & m_v[VS2REG].w[VEC_EL_2(EL, i)]);
- m_accum[i].w[SLICE_L] = vres[i];
+ m_accum[i].w.h = vres[i];
}
WRITEBACK_RESULT();
break;
@@ -1660,7 +1684,7 @@ void rsp_device::handle_vector_ops(uint32_t op)
for (int i = 0; i < 8; i++)
{
vres[i] = m_v[VS1REG].w[i] | m_v[VS2REG].w[VEC_EL_2(EL, i)];
- m_accum[i].w[SLICE_L] = vres[i];
+ m_accum[i].w.h = vres[i];
}
WRITEBACK_RESULT();
break;
@@ -1678,7 +1702,7 @@ void rsp_device::handle_vector_ops(uint32_t op)
for (int i = 0; i < 8; i++)
{
vres[i] = ~(m_v[VS1REG].w[i] | m_v[VS2REG].w[VEC_EL_2(EL, i)]);
- m_accum[i].w[SLICE_L] = vres[i];
+ m_accum[i].w.h = vres[i];
}
WRITEBACK_RESULT();
break;
@@ -1696,7 +1720,7 @@ void rsp_device::handle_vector_ops(uint32_t op)
for (int i = 0; i < 8; i++)
{
vres[i] = m_v[VS1REG].w[i] ^ m_v[VS2REG].w[VEC_EL_2(EL, i)];
- m_accum[i].w[SLICE_L] = vres[i];
+ m_accum[i].w.h = vres[i];
}
WRITEBACK_RESULT();
break;
@@ -1714,7 +1738,7 @@ void rsp_device::handle_vector_ops(uint32_t op)
for (int i = 0; i < 8; i++)
{
vres[i] = ~(m_v[VS1REG].w[i] ^ m_v[VS2REG].w[VEC_EL_2(EL, i)]);
- m_accum[i].w[SLICE_L] = vres[i];
+ m_accum[i].w.h = vres[i];
}
WRITEBACK_RESULT();
break;
@@ -1737,7 +1761,7 @@ void rsp_device::handle_vector_ops(uint32_t op)
vres[i] = 0;
uint16_t e1 = m_v[VS1REG].w[i];
uint16_t e2 = m_v[VS2REG].w[VEC_EL_2(EL, i)];
- m_accum[i].w[SLICE_L] = e1 + e2;
+ m_accum[i].w.h = e1 + e2;
}
WRITEBACK_RESULT();
break;
@@ -1796,7 +1820,7 @@ void rsp_device::handle_vector_ops(uint32_t op)
for (int i = 0; i < 8; i++)
{
- m_accum[i].w[SLICE_L] = m_v[VS2REG].w[VEC_EL_2(EL, i)];
+ m_accum[i].w.h = m_v[VS2REG].w[VEC_EL_2(EL, i)];
}
break;
}
@@ -1871,7 +1895,7 @@ void rsp_device::handle_vector_ops(uint32_t op)
for (int i = 0; i < 8; i++)
{
- m_accum[i].w[SLICE_L] = m_v[VS2REG].w[VEC_EL_2(EL, i)];
+ m_accum[i].w.h = m_v[VS2REG].w[VEC_EL_2(EL, i)];
}
break;
}
@@ -1890,7 +1914,7 @@ void rsp_device::handle_vector_ops(uint32_t op)
for (int i = 0; i < 8; i++)
{
- m_accum[i].w[SLICE_L] = m_v[VS2REG].w[VEC_EL_2(EL, i)];
+ m_accum[i].w.h = m_v[VS2REG].w[VEC_EL_2(EL, i)];
}
m_v[VDREG].s[VS1REG & 7] = (int16_t)(m_reciprocal_res >> 16);
@@ -1909,7 +1933,7 @@ void rsp_device::handle_vector_ops(uint32_t op)
m_v[VDREG].w[VS1REG & 7] = m_v[VS2REG].w[VEC_EL_2(EL, VS1REG & 7)];
for (int i = 0; i < 8; i++)
{
- m_accum[i].w[SLICE_L] = m_v[VS2REG].w[i];
+ m_accum[i].w.h = m_v[VS2REG].w[i];
}
break;
}
@@ -1969,7 +1993,7 @@ void rsp_device::handle_vector_ops(uint32_t op)
for (int i = 0; i < 8; i++)
{
- m_accum[i].w[SLICE_L] = m_v[VS2REG].w[VEC_EL_2(EL, i)];
+ m_accum[i].w.h = m_v[VS2REG].w[VEC_EL_2(EL, i)];
}
break;
@@ -2048,7 +2072,7 @@ void rsp_device::handle_vector_ops(uint32_t op)
for (int i = 0; i < 8; i++)
{
- m_accum[i].w[SLICE_L] = m_v[VS2REG].w[VEC_EL_2(EL, i)];
+ m_accum[i].w.h = m_v[VS2REG].w[VEC_EL_2(EL, i)];
}
break;
@@ -2068,7 +2092,7 @@ void rsp_device::handle_vector_ops(uint32_t op)
for (int i = 0; i < 8; i++)
{
- m_accum[i].w[SLICE_L] = m_v[VS2REG].w[VEC_EL_2(EL, i)];
+ m_accum[i].w.h = m_v[VS2REG].w[VEC_EL_2(EL, i)];
}
m_v[VDREG].s[VS1REG & 7] = (int16_t)(m_reciprocal_res >> 16); // store high part
@@ -2103,7 +2127,7 @@ void rsp_device::handle_vector_ops(uint32_t op)
vres[i] = 0;
uint16_t e1 = m_v[VS1REG].w[i];
uint16_t e2 = m_v[VS2REG].w[VEC_EL_2(EL, i)];
- m_accum[i].w[SLICE_L] = e1 + e2;
+ m_accum[i].w.h = e1 + e2;
}
WRITEBACK_RESULT();
break;
@@ -2123,7 +2147,7 @@ void rsp_device::handle_vector_ops(uint32_t op)
for (int i = 0; i < 8; i++)
{
vres[i] = m_v[VS1REG].w[i];
- m_accum[i].w[SLICE_L] = 0;
+ m_accum[i].w.h = 0;
}
WRITEBACK_RESULT();
break;
diff --git a/src/devices/cpu/rsp/rsp.h b/src/devices/cpu/rsp/rsp.h
index 0007e96714c..4e7378af089 100644
--- a/src/devices/cpu/rsp/rsp.h
+++ b/src/devices/cpu/rsp/rsp.h
@@ -148,7 +148,7 @@ protected:
memory_access<12, 2, 0, ENDIANNESS_BIG>::specific m_dmem;
private:
- union VECTOR_REG
+ union VECTOR_REG // PAIR128
{
uint64_t d[2];
uint32_t l[4];
@@ -157,13 +157,6 @@ private:
uint8_t b[16];
};
- union ACCUMULATOR_REG
- {
- uint64_t q;
- uint32_t l[2];
- uint16_t w[4];
- };
-
uint32_t m_debugger_temp;
uint16_t m_pc_temp;
uint16_t m_ppc_temp;
@@ -188,26 +181,23 @@ private:
// COP2 (vectors)
uint16_t SATURATE_ACCUM(int accum, int slice, uint16_t negative, uint16_t positive);
- uint16_t m_vres[8];
- VECTOR_REG m_v[32];
- ACCUMULATOR_REG m_accum[8];
- uint8_t m_vcarry;
- uint8_t m_vcompare;
- uint8_t m_vclip1;
- uint8_t m_vzero;
- uint8_t m_vclip2;
-
- int32_t m_reciprocal_res;
- uint32_t m_reciprocal_high;
- int32_t m_dp_allowed;
-
- void handle_cop2(uint32_t op);
- void handle_lwc2(uint32_t op);
- void handle_swc2(uint32_t op);
- void handle_vector_ops(uint32_t op);
-
- uint32_t m_div_in;
- uint32_t m_div_out;
+ uint16_t m_vres[8];
+ VECTOR_REG m_v[32];
+ PAIR64 m_accum[8];
+ uint8_t m_vcarry;
+ uint8_t m_vcompare;
+ uint8_t m_vclip1;
+ uint8_t m_vzero;
+ uint8_t m_vclip2;
+
+ int32_t m_reciprocal_res;
+ uint32_t m_reciprocal_high;
+ int32_t m_dp_allowed;
+
+ void handle_cop2(uint32_t op);
+ void handle_lwc2(uint32_t op);
+ void handle_swc2(uint32_t op);
+ void handle_vector_ops(uint32_t op);
};
DECLARE_DEVICE_TYPE(RSP, rsp_device)
diff --git a/src/devices/cpu/z80/nsc800.cpp b/src/devices/cpu/z80/nsc800.cpp
index d7af9a67fe2..e2c0bfd0087 100644
--- a/src/devices/cpu/z80/nsc800.cpp
+++ b/src/devices/cpu/z80/nsc800.cpp
@@ -54,17 +54,21 @@ void nsc800_device::execute_run()
void nsc800_device::execute_set_input(int inputnum, int state)
{
+ bool update_irq_attention = false;
switch (inputnum)
{
case NSC800_RSTA:
+ update_irq_attention = true;
m_nsc800_irq_state[0] = state;
break;
case NSC800_RSTB:
+ update_irq_attention = true;
m_nsc800_irq_state[1] = state;
break;
case NSC800_RSTC:
+ update_irq_attention = true;
m_nsc800_irq_state[2] = state;
break;
@@ -72,4 +76,12 @@ void nsc800_device::execute_set_input(int inputnum, int state)
z80_device::execute_set_input(inputnum, state);
break;
}
+
+ if (update_irq_attention)
+ {
+ if (m_nsc800_irq_state[0] != CLEAR_LINE || m_nsc800_irq_state[1] != CLEAR_LINE || m_nsc800_irq_state[2] != CLEAR_LINE)
+ set_service_attention<SA_NSC800_IRQ_ON, 1>();
+ else
+ set_service_attention<SA_NSC800_IRQ_ON, 0>();
+ }
}
diff --git a/src/devices/cpu/z80/z80.cpp b/src/devices/cpu/z80/z80.cpp
index ab4d79d5120..c95474999d5 100644
--- a/src/devices/cpu/z80/z80.cpp
+++ b/src/devices/cpu/z80/z80.cpp
@@ -50,6 +50,7 @@ void z80_device::halt()
if (!m_halt)
{
m_halt = 1;
+ set_service_attention<SA_HALT, 1>();
m_halt_cb(1);
}
}
@@ -62,6 +63,7 @@ void z80_device::leave_halt()
if (m_halt)
{
m_halt = 0;
+ set_service_attention<SA_HALT, 0>();
m_halt_cb(0);
}
}
@@ -468,7 +470,7 @@ void z80_device::block_io_interrupted_flags()
void z80_device::ei()
{
m_iff1 = m_iff2 = 1;
- m_after_ei = true;
+ set_service_attention<SA_AFTER_EI, 1>();
}
void z80_device::set_f(u8 f)
@@ -562,14 +564,12 @@ void z80_device::device_start()
save_item(NAME(m_im));
save_item(NAME(m_i));
save_item(NAME(m_nmi_state));
- save_item(NAME(m_nmi_pending));
save_item(NAME(m_irq_state));
save_item(NAME(m_wait_state));
save_item(NAME(m_busrq_state));
save_item(NAME(m_busack_state));
- save_item(NAME(m_after_ei));
- save_item(NAME(m_after_ldair));
save_item(NAME(m_ea));
+ save_item(NAME(m_service_attention));
save_item(NAME(m_tmp_irq_vector));
save_item(NAME(m_shared_addr.w));
save_item(NAME(m_shared_data.w));
@@ -602,14 +602,12 @@ void z80_device::device_start()
m_im = 0;
m_i = 0;
m_nmi_state = 0;
- m_nmi_pending = false;
m_irq_state = 0;
m_wait_state = 0;
m_busrq_state = 0;
m_busack_state = 0;
- m_after_ei = false;
- m_after_ldair = false;
m_ea = 0;
+ m_service_attention = 0;
m_rtemp = 0;
space(AS_PROGRAM).cache(m_args);
@@ -667,11 +665,9 @@ void z80_device::device_reset()
m_i = 0;
m_r = 0;
m_r2 = 0;
- m_nmi_pending = false;
- m_after_ei = false;
- m_after_ldair = false;
m_iff1 = 0;
m_iff2 = 0;
+ m_service_attention = 0;
}
/****************************************************************************
@@ -688,12 +684,18 @@ void z80_device::execute_set_input(int inputnum, int state)
{
case Z80_INPUT_LINE_BUSRQ:
m_busrq_state = state;
+ if (state != CLEAR_LINE)
+ set_service_attention<SA_BUSRQ, 1>();
+ else
+ set_service_attention<SA_BUSRQ, 0>();
break;
case INPUT_LINE_NMI:
// mark an NMI pending on the rising edge
if (m_nmi_state == CLEAR_LINE && state != CLEAR_LINE)
- m_nmi_pending = true;
+ {
+ set_service_attention<SA_NMI_PENDING, 1>();
+ }
m_nmi_state = state;
break;
@@ -702,6 +704,10 @@ void z80_device::execute_set_input(int inputnum, int state)
m_irq_state = state;
if (daisy_chain_present())
m_irq_state = (daisy_update_irq_state() == ASSERT_LINE) ? ASSERT_LINE : m_irq_state;
+ if (state != CLEAR_LINE)
+ set_service_attention<SA_IRQ_ON, 1>();
+ else
+ set_service_attention<SA_IRQ_ON, 0>();
// the main execute loop will take the interrupt
break;
@@ -728,8 +734,9 @@ void z80_device::state_import(const device_state_entry &entry)
case STATE_GENPC:
m_prvpc = m_pc;
m_ref = 0xffff00;
- m_after_ei = false;
- m_after_ldair = false;
+ set_service_attention<SA_AFTER_EI, 0>();
+ if (HAS_LDAIR_QUIRK)
+ set_service_attention<SA_AFTER_LDAIR, 0>();
break;
case Z80_R:
diff --git a/src/devices/cpu/z80/z80.h b/src/devices/cpu/z80/z80.h
index ec111c3cd32..b40e697d81f 100644
--- a/src/devices/cpu/z80/z80.h
+++ b/src/devices/cpu/z80/z80.h
@@ -78,6 +78,8 @@ protected:
void illegal_1();
void illegal_2();
u8 flags_szyxc(u16 value);
+ template <u8 Bit, bool State> void set_service_attention() { static_assert(Bit < 8, "out of range bit index"); if (State) m_service_attention |= (1 << Bit); else m_service_attention &= ~(1 << Bit); };
+ template <u8 Bit> bool get_service_attention() { static_assert(Bit < 8, "out of range bit index"); return m_service_attention & (1 << Bit); };
void halt();
void leave_halt();
@@ -137,6 +139,16 @@ protected:
devcb_write_line m_halt_cb;
devcb_write_line m_busack_cb;
+ static constexpr u8 SA_BUSRQ = 0;
+ static constexpr u8 SA_BUSACK = 1;
+ static constexpr u8 SA_NMI_PENDING = 2;
+ static constexpr u8 SA_IRQ_ON = 3;
+ static constexpr u8 SA_HALT = 4;
+ static constexpr u8 SA_AFTER_EI = 5;
+ static constexpr u8 SA_AFTER_LDAIR = 6;
+ static constexpr u8 SA_NSC800_IRQ_ON = 7;
+ u8 m_service_attention; // bitmap for required handling in service step
+
PAIR16 m_prvpc;
PAIR16 m_pc;
PAIR16 m_sp;
@@ -161,13 +173,10 @@ protected:
u8 m_im;
u8 m_i;
u8 m_nmi_state; // nmi pin state
- bool m_nmi_pending; // nmi pending
u8 m_irq_state; // irq pin state
int m_wait_state; // wait pin state
int m_busrq_state; // bus request pin state
u8 m_busack_state; // bus acknowledge pin state
- bool m_after_ei; // are we in the EI shadow?
- bool m_after_ldair; // same, but for LD A,I or LD A,R
u16 m_ea;
int m_icount;
diff --git a/src/devices/cpu/z80/z80.lst b/src/devices/cpu/z80/z80.lst
index 12bd39360ba..a31e651748b 100644
--- a/src/devices/cpu/z80/z80.lst
+++ b/src/devices/cpu/z80/z80.lst
@@ -206,10 +206,14 @@ macro r800:ld_r_a
macro ld_a_r
call nomreq_ir 1
- A = (m_r & 0x7f) | m_r2; set_f((F & CF) | SZ[A] | (m_iff2 << 2)); m_after_ldair = true;
+ A = (m_r & 0x7f) | m_r2; set_f((F & CF) | SZ[A] | (m_iff2 << 2));
+ if (HAS_LDAIR_QUIRK)
+ set_service_attention<SA_AFTER_LDAIR, 1>();
macro r800:ld_a_r
- A = (m_r & 0x7f) | m_r2; set_f((F & CF) | SZ[A] | (m_iff2 << 2)); m_after_ldair = true;
+ A = (m_r & 0x7f) | m_r2; set_f((F & CF) | SZ[A] | (m_iff2 << 2));
+ if (HAS_LDAIR_QUIRK)
+ set_service_attention<SA_AFTER_LDAIR, 1>();
macro ld_i_a
call nomreq_ir 1
@@ -220,10 +224,14 @@ macro r800:ld_i_a
macro ld_a_i
call nomreq_ir 1
- A = m_i; set_f((F & CF) | SZ[A] | (m_iff2 << 2)); m_after_ldair = true;
+ A = m_i; set_f((F & CF) | SZ[A] | (m_iff2 << 2));
+ if (HAS_LDAIR_QUIRK)
+ set_service_attention<SA_AFTER_LDAIR, 1>();
macro r800:ld_a_i
- A = m_i; set_f((F & CF) | SZ[A] | (m_iff2 << 2)); m_after_ldair = true;
+ A = m_i; set_f((F & CF) | SZ[A] | (m_iff2 << 2));
+ if (HAS_LDAIR_QUIRK)
+ set_service_attention<SA_AFTER_LDAIR, 1>();
macro rst addr
TDAT = PC;
@@ -531,8 +539,8 @@ macro r800:otdr
PC -= 2; block_io_interrupted_flags();
}
-macro jump %opcode
- m_ref = 0x%opcode00;
+macro jump %po
+ m_ref = 0x%po00;
goto process;
macro jump_prefixed %prefix
@@ -542,10 +550,9 @@ macro jump_prefixed %prefix
macro take_nmi
// Check if processor was halted
leave_halt();
- #if HAS_LDAIR_QUIRK
+ if (HAS_LDAIR_QUIRK)
// reset parity flag after LD A,I or LD A,R
- if (m_after_ldair) F &= ~PF;
- #endif
+ if (get_service_attention<SA_AFTER_LDAIR>()) F &= ~PF;
m_iff1 = 0;
m_r++;
+ 5
@@ -553,7 +560,7 @@ macro take_nmi
call wm16_sp
PC = 0x0066;
WZ = PC;
- m_nmi_pending = false;
+ set_service_attention<SA_NMI_PENDING, 0>();
macro irqfetch
{
@@ -640,27 +647,26 @@ macro take_interrupt
}
}
WZ = PC;
- #if HAS_LDAIR_QUIRK
+ if (HAS_LDAIR_QUIRK)
// reset parity flag after LD A,I or LD A,R
- if (m_after_ldair) F &= ~PF;
- #endif
+ if (get_service_attention<SA_AFTER_LDAIR>()) F &= ~PF;
macro check_interrupts
- if (m_nmi_pending) {
+ if (get_service_attention<SA_NMI_PENDING>()) {
call take_nmi
- } else if (m_irq_state != CLEAR_LINE && m_iff1 && !m_after_ei) {
+ } else if (m_irq_state != CLEAR_LINE && m_iff1 && !get_service_attention<SA_AFTER_EI>()) { // SA_IRQ_ON
call take_interrupt
}
macro z80n:check_interrupts
- if (m_nmi_pending) {
+ if (get_service_attention<SA_NMI_PENDING>()) {
if (m_stackless) {
// on take_nmi
m_out_nextreg_cb(0xc2, m_pc.b.l);
m_out_nextreg_cb(0xc3, m_pc.b.h);
}
call take_nmi
- } else if (m_irq_state != CLEAR_LINE && m_iff1 && !m_after_ei) {
+ } else if (m_irq_state != CLEAR_LINE && m_iff1 && !get_service_attention<SA_AFTER_EI>()) {
call take_interrupt
}
@@ -688,17 +694,16 @@ macro nsc800_take_interrupt
;
}
WZ = PC;
- #if HAS_LDAIR_QUIRK
+ if (HAS_LDAIR_QUIRK)
// reset parity flag after LD A,I or LD A,R
- if (m_after_ldair) F &= ~PF;
- #endif
+ if (get_service_attention<SA_AFTER_LDAIR>()) F &= ~PF;
macro nsc800:check_interrupts
- if (m_nmi_pending) {
+ if (get_service_attention<SA_NMI_PENDING>()) {
call take_nmi
- } else if ((m_nsc800_irq_state[0] != CLEAR_LINE || m_nsc800_irq_state[1] != CLEAR_LINE || m_nsc800_irq_state[2] != CLEAR_LINE) && m_iff1 && !m_after_ei) {
+ } else if (get_service_attention<SA_NSC800_IRQ_ON>() && m_iff1 && !get_service_attention<SA_AFTER_EI>()) {
call nsc800_take_interrupt
- } else if (m_irq_state != CLEAR_LINE && m_iff1 && !m_after_ei) {
+ } else if (m_irq_state != CLEAR_LINE && m_iff1 && !get_service_attention<SA_AFTER_EI>()) { // SA_IRQ_ON
call take_interrupt
}
@@ -707,35 +712,42 @@ macro nsc800:check_interrupts
# ROP
##########################################################
ffff
- m_ref = 0xffff00;
- if (m_icount <= 0) return;
- if (m_busrq_state) {
- if (!m_busack_state) {
- m_busack_state = 1;
- m_busack_cb(1);
- }
- if (m_icount > 0)
- m_icount = 0;
+ if (m_icount <= 0) {
+ m_ref = 0xffff00;
return;
- } else if (m_busack_state) {
- m_busack_state = 0;
- m_busack_cb(0);
}
- call check_interrupts
- m_after_ei = false;
- m_after_ldair = false;
- if (m_halt) {
- debugger_wait_hook();
- call rop
- PC--;
- continue;
- } else {
- PRVPC = PC;
- debugger_instruction_hook(PC);
- call rop
- m_ref = (0x00 << 16) | (TDAT8 << 8);
- goto process;
+ if (m_service_attention) {
+ if (m_busrq_state) { // SA_BUSRQ
+ if (!m_busack_state) {
+ m_busack_state = 1;
+ set_service_attention<SA_BUSACK, 1>();
+ m_busack_cb(1);
+ }
+ if (m_icount > 0)
+ m_icount = 0;
+ m_ref = 0xffff00;
+ return;
+ } else if (m_busack_state) { // SA_BUSACK
+ m_busack_state = 0;
+ set_service_attention<SA_BUSACK, 0>();
+ m_busack_cb(0);
+ }
+ call check_interrupts
+ set_service_attention<SA_AFTER_EI, 0>(); // SA_AFTER_EI
+ if (HAS_LDAIR_QUIRK)
+ set_service_attention<SA_AFTER_LDAIR, 0>(); // SA_AFTER_LDAIR
+ if (m_halt) { // SA_HALT
+ debugger_wait_hook();
+ call rop
+ PC--;
+ continue;
+ }
}
+ PRVPC = PC;
+ debugger_instruction_hook(PC);
+ call rop
+ m_ref = (0x00 << 16) | (TDAT8 << 8);
+ goto process;
##########################################################
diff --git a/src/devices/cpu/z80/z80make.py b/src/devices/cpu/z80/z80make.py
index 0aa7ee1a55e..023cdfd29ba 100644
--- a/src/devices/cpu/z80/z80make.py
+++ b/src/devices/cpu/z80/z80make.py
@@ -31,6 +31,10 @@ class IndStr:
def has_indent(self):
return self.indent != ''
+ def strip_indent(self, n):
+ if self.indent != '':
+ self.indent = self.indent[n:]
+
def replace(self, new):
self.str = new
@@ -77,7 +81,7 @@ class Opcode:
for i in range(0, len(self.source)):
il = self.source[i]
if not has_steps or not step_switch:
- il.indent = ""
+ il.strip_indent(1)
line = il.line()
tokens = line.split()
last_line = i + 1 == len(self.source)
@@ -240,7 +244,7 @@ class OpcodeList:
name = line_toc[1]
arg = None
if len(line_toc) > 2:
- arg = line_toc[2]
+ arg = " ".join(line_toc[2:])
if name in self.macros:
macro = self.macros[name]
([out.extend(self.pre_process(il)) for il in macro.apply(arg)])
@@ -260,21 +264,22 @@ class OpcodeList:
for prefix in sorted(prefixes):
is_rop = prefix == 'ff'
+ opc_switch = not is_rop
if prefix_switch:
print("case 0x%s:" % (prefix), file=f)
print("{", file=f)
- if not is_rop:
+ if opc_switch:
print("\tswitch (u8(m_ref >> 8)) // opcode", file=f)
print("\t{", file=f)
for opc in self.opcode_info[prefix]:
# reenter loop only process steps > 0
if not reenter or opc.with_steps():
- if not is_rop:
+ if opc_switch:
print("\tcase 0x%s:" % (opc.code), file=f)
opc.save_dasm(step_switch=reenter, f=f)
print("\t\tcontinue;", file=f)
print("", file=f)
- if not is_rop:
+ if opc_switch:
print("\t}", file=f)
if prefix_switch:
@@ -295,6 +300,7 @@ class OpcodeList:
print("", file=f)
print("bool interrupted = true;", file=f)
print("while (u8(m_ref) != 0x00) {", file=f)
+ print("// slow re-enter", file=f)
print("\t// workaround to simulate main loop behavior where continue statement relays on having it set after", file=f)
print("\tif (!interrupted) {", file=f)
print("\t\tm_ref = 0xffff00;", file=f)
@@ -305,19 +311,17 @@ class OpcodeList:
self.switch_prefix(self.opcode_info.keys(), reenter=True, f=f)
print("", file=f)
print('assert((void("switch statement above must cover all possible cases!"), false));', file=f)
- print("}", file=f)
- print("", file=f)
+ print("} // end: slow", file=f)
print("if (m_ref != 0xffff00) goto process;", file=f)
print("", file=f)
- print("while (true) {", file=f)
- print("", file=f)
- print("\t\t// unwrapped ff prefix", file=f)
+ print("while (true) { // fast process", file=f)
+ print("\t\t// rop: unwrapped ff prefix", file=f)
self.switch_prefix(['ff'], reenter=False, f=f)
print("", file=f)
print("process:", file=f)
self.switch_prefix(self.opcode_info.keys() - ['ff'], reenter=False, f=f)
- print("", file=f)
- print("} // while (true)", file=f)
+ print("} // end: fast", file=f)
+ print('assert((void("unreachable!"), false));', file=f)
def main(argv):
if len(argv) != 3 and len(argv) != 4:
diff --git a/src/devices/cpu/z80/z80n.h b/src/devices/cpu/z80/z80n.h
index 8198412074c..d4d452955fd 100644
--- a/src/devices/cpu/z80/z80n.h
+++ b/src/devices/cpu/z80/z80n.h
@@ -20,7 +20,7 @@ public:
bool nmi_stackless_r() { return m_stackless; }
void nmi_stackless_w(bool data) { m_stackless = data; }
- void nmi() { m_nmi_pending = true; }
+ void nmi() { set_service_attention<SA_NMI_PENDING, 1>(); }
protected:
virtual void device_start() override ATTR_COLD;
diff --git a/src/devices/machine/netlist.cpp b/src/devices/machine/netlist.cpp
index c9d91704cce..8d4d6cedf4d 100644
--- a/src/devices/machine/netlist.cpp
+++ b/src/devices/machine/netlist.cpp
@@ -33,7 +33,6 @@
#define LOG_TIMING (1U << 3)
//#define LOG_MASK (LOG_GENERAL | LOG_DEV_CALLS | LOG_DEBUG)
-//#define LOG_MASK (LOG_TIMING)
#define LOG_MASK (0)
#define LOGDEVCALLS(...) LOGMASKED(LOG_DEV_CALLS, __VA_ARGS__)
@@ -815,11 +814,15 @@ void netlist_mame_stream_output_device::device_reset()
void netlist_mame_stream_output_device::sound_update_fill(sound_stream &stream, int output)
{
- if (stream.samples() < m_buffer.size())
- osd_printf_warning("sound %s: samples %d less bufsize %d\n", name(), stream.samples(), m_buffer.size());
+ int samples = m_buffer.size();
+ if (stream.samples() < samples)
+ {
+ osd_printf_warning("sound %s: samples %d less bufsize %d\n", name(), stream.samples(), samples);
+ samples = stream.samples();
+ }
int sampindex;
- for (sampindex = 0; sampindex < m_buffer.size(); sampindex++)
+ for (sampindex = 0; sampindex < samples; sampindex++)
stream.put(output, sampindex, m_buffer[sampindex]);
if (sampindex < stream.samples())
stream.fill(output, m_cur, sampindex);
@@ -858,7 +861,7 @@ void netlist_mame_stream_output_device::process(netlist::netlist_time_ext tim, n
int pos = (tim - m_last_buffer_time) / m_sample_time;
//if (pos > m_bufsize)
// throw emu_fatalerror("sound %s: pos %d exceeded bufsize %d\n", name().c_str(), pos, m_bufsize);
- while (m_buffer.size() < pos )
+ while (m_buffer.size() < pos)
{
m_buffer.push_back(static_cast<sound_stream::sample_t>(m_cur));
}