mirror of
https://github.com/holub/mame
synced 2025-10-06 09:00:04 +03:00
8x300: Cleanup and expansion
- Latch at most one IV input per instruction - Fix output behavior of some opcodes that selected the wrong IV bank or wrong value to write - Add 8X305 type - Emulate additional 8X305 registers - Add address latching callback
This commit is contained in:
parent
4c444b2a00
commit
a8d25fb2c6
@ -34,17 +34,29 @@
|
||||
// for XEC intruction, which sets the AR, but not PC, so that after the instruction at the relative address is done, execution
|
||||
// returns back to next instruction after XEC, unless a JMP or successful NZT is there.
|
||||
#define SET_AR(x) do { m_AR = (x); m_increment_pc = false; } while (0)
|
||||
#define SRC_LATCH do { if(SRC_IS_RIGHT_BANK) m_right_IV = READPORT(m_IVR+0x100); else m_left_IV = READPORT(m_IVL); } while (0)
|
||||
#define DST_LATCH do { if(DST_IS_RIGHT_BANK) m_right_IV = READPORT(m_IVR+0x100); else m_left_IV = READPORT(m_IVL); } while (0)
|
||||
#define SRC_LATCH do { if(SRC_IS_RIGHT_BANK) m_IV_latch = READPORT(m_IVR+0x100); else m_IV_latch = READPORT(m_IVL); } while (0)
|
||||
#define DST_LATCH do { if(DST_IS_RIGHT_BANK) m_IV_latch = READPORT(m_IVR+0x100); else m_IV_latch = READPORT(m_IVL); } while (0)
|
||||
#define SET_OVF do { if(result & 0xff00) m_OVF = 1; else m_OVF = 0; } while (0)
|
||||
|
||||
DEFINE_DEVICE_TYPE(N8X300, n8x300_cpu_device, "8x300", "Signetics 8X300")
|
||||
DEFINE_DEVICE_TYPE(N8X305, n8x305_cpu_device, "8x305", "Signetics 8X305")
|
||||
|
||||
|
||||
n8x300_cpu_device::n8x300_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: cpu_device(mconfig, N8X300, tag, owner, clock)
|
||||
n8x300_cpu_device::n8x300_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
|
||||
: cpu_device(mconfig, type, tag, owner, clock)
|
||||
, m_program_config("program", ENDIANNESS_BIG, 16, 14, 0)
|
||||
, m_io_config("io", ENDIANNESS_BIG, 8, 9, 0)
|
||||
, m_sc_callback(*this)
|
||||
{
|
||||
}
|
||||
|
||||
n8x300_cpu_device::n8x300_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: n8x300_cpu_device(mconfig, N8X300, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
n8x305_cpu_device::n8x305_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: n8x300_cpu_device(mconfig, N8X305, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
@ -56,9 +68,21 @@ device_memory_interface::space_config_vector n8x300_cpu_device::memory_space_con
|
||||
};
|
||||
}
|
||||
|
||||
void n8x300_cpu_device::set_reg(uint8_t reg, uint8_t val)
|
||||
void n8x300_cpu_device::xmit_lb(uint8_t dst, uint8_t mask)
|
||||
{
|
||||
switch(reg)
|
||||
m_IV_latch = (m_IV_latch & ~mask) | (dst & mask);
|
||||
WRITEPORT(m_IVL, dst);
|
||||
}
|
||||
|
||||
void n8x300_cpu_device::xmit_rb(uint8_t dst, uint8_t mask)
|
||||
{
|
||||
m_IV_latch = (m_IV_latch & ~mask) | (dst & mask);
|
||||
WRITEPORT(m_IVR + 0x100, dst);
|
||||
}
|
||||
|
||||
void n8x300_cpu_device::set_reg(uint8_t reg, uint8_t val, bool xmit)
|
||||
{
|
||||
switch (reg)
|
||||
{
|
||||
case 0x00: m_AUX = val; break;
|
||||
case 0x01: m_R1 = val; break;
|
||||
@ -67,17 +91,30 @@ void n8x300_cpu_device::set_reg(uint8_t reg, uint8_t val)
|
||||
case 0x04: m_R4 = val; break;
|
||||
case 0x05: m_R5 = val; break;
|
||||
case 0x06: m_R6 = val; break;
|
||||
case 0x07: m_IVL = val; break;
|
||||
case 0x07: m_IVL = val; m_sc_callback(0, val); break;
|
||||
// OVF is read-only
|
||||
case 0x09: m_R11 = val; break;
|
||||
case 0x0f: m_IVR = val; break;
|
||||
case 0x0f: m_IVR = val; m_sc_callback(1, val); break;
|
||||
default: logerror("8X300: Invalid register %02x written to.\n",reg); break;
|
||||
}
|
||||
}
|
||||
|
||||
void n8x305_cpu_device::set_reg(uint8_t reg, uint8_t val, bool xmit)
|
||||
{
|
||||
switch (reg)
|
||||
{
|
||||
case 0x0a: if (xmit) xmit_lb(val, 0xff); else m_R12 = val; break;
|
||||
case 0x0b: if (xmit) xmit_rb(val, 0xff); else m_R13 = val; break;
|
||||
case 0x0c: m_R14 = val; break;
|
||||
case 0x0d: m_R15 = val; break;
|
||||
case 0x0e: m_R16 = val; break;
|
||||
default: n8x300_cpu_device::set_reg(reg, val, xmit); break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t n8x300_cpu_device::get_reg(uint8_t reg)
|
||||
{
|
||||
switch(reg)
|
||||
switch (reg)
|
||||
{
|
||||
case 0x00: return m_AUX;
|
||||
case 0x01: return m_R1;
|
||||
@ -86,14 +123,34 @@ uint8_t n8x300_cpu_device::get_reg(uint8_t reg)
|
||||
case 0x04: return m_R4;
|
||||
case 0x05: return m_R5;
|
||||
case 0x06: return m_R6;
|
||||
// IVL is write-only
|
||||
// IVL is write-only on the 8X300
|
||||
case 0x08: return m_OVF;
|
||||
case 0x09: return m_R11;
|
||||
// IVR is write-only
|
||||
// IVR is write-only on the 8X300
|
||||
default: logerror("8X300: Invalid register %02x read.\n",reg); return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t n8x305_cpu_device::get_reg(uint8_t reg)
|
||||
{
|
||||
switch (reg)
|
||||
{
|
||||
case 0x07: return m_IVL;
|
||||
case 0x0a: return m_R12;
|
||||
case 0x0b: return m_R13;
|
||||
case 0x0c: return m_R14;
|
||||
case 0x0d: return m_R15;
|
||||
case 0x0e: return m_R16;
|
||||
case 0x0f: return m_IVR;
|
||||
default: return n8x300_cpu_device::get_reg(reg);
|
||||
}
|
||||
}
|
||||
|
||||
void n8x300_cpu_device::device_resolve_objects()
|
||||
{
|
||||
m_sc_callback.resolve_safe();
|
||||
}
|
||||
|
||||
void n8x300_cpu_device::device_start()
|
||||
{
|
||||
m_program = &space(AS_PROGRAM);
|
||||
@ -110,12 +167,19 @@ void n8x300_cpu_device::device_start()
|
||||
save_item(NAME(m_R5));
|
||||
save_item(NAME(m_R6));
|
||||
save_item(NAME(m_R11));
|
||||
if (type() == N8X305)
|
||||
{
|
||||
save_item(NAME(m_R12));
|
||||
save_item(NAME(m_R13));
|
||||
save_item(NAME(m_R14));
|
||||
save_item(NAME(m_R15));
|
||||
save_item(NAME(m_R16));
|
||||
}
|
||||
save_item(NAME(m_AUX));
|
||||
save_item(NAME(m_IVL));
|
||||
save_item(NAME(m_IVR));
|
||||
save_item(NAME(m_OVF));
|
||||
save_item(NAME(m_left_IV));
|
||||
save_item(NAME(m_right_IV));
|
||||
save_item(NAME(m_IV_latch));
|
||||
save_item(NAME(m_genPC));
|
||||
save_item(NAME(m_increment_pc));
|
||||
|
||||
@ -127,6 +191,14 @@ void n8x300_cpu_device::device_start()
|
||||
m_R5 = 0;
|
||||
m_R6 = 0;
|
||||
m_R11 = 0;
|
||||
if (type() == N8X305)
|
||||
{
|
||||
m_R12 = 0;
|
||||
m_R13 = 0;
|
||||
m_R14 = 0;
|
||||
m_R15 = 0;
|
||||
m_R16 = 0;
|
||||
}
|
||||
m_IVL = 0;
|
||||
m_IVR = 0;
|
||||
m_AUX = 0;
|
||||
@ -146,6 +218,14 @@ void n8x300_cpu_device::device_start()
|
||||
state_add( _8X300_R5, "R5", m_R5).mask(0xff).formatstr("%02X");
|
||||
state_add( _8X300_R6, "R6", m_R6).mask(0xff).formatstr("%02X");
|
||||
state_add( _8X300_R11, "R11", m_R11).mask(0xff).formatstr("%02X");
|
||||
if (type() == N8X305)
|
||||
{
|
||||
state_add( _8X300_R12, "R12", m_R12).mask(0xff).formatstr("%02X");
|
||||
state_add( _8X300_R13, "R13", m_R13).mask(0xff).formatstr("%02X");
|
||||
state_add( _8X300_R14, "R14", m_R14).mask(0xff).formatstr("%02X");
|
||||
state_add( _8X300_R15, "R15", m_R15).mask(0xff).formatstr("%02X");
|
||||
state_add( _8X300_R16, "R16", m_R16).mask(0xff).formatstr("%02X");
|
||||
}
|
||||
state_add( _8X300_OVF, "OVF", m_OVF).mask(0x01).formatstr("%01X");
|
||||
state_add( _8X300_IVL, "IVL", m_IVL).mask(0xff).formatstr("%02X");
|
||||
state_add( _8X300_IVR, "IVR", m_IVR).mask(0xff).formatstr("%02X");
|
||||
@ -202,7 +282,6 @@ void n8x300_cpu_device::execute_run()
|
||||
uint8_t dst;
|
||||
uint8_t rotlen; // rotate amount or I/O field length
|
||||
uint8_t mask;
|
||||
uint16_t result;
|
||||
|
||||
/* fetch the opcode */
|
||||
m_genPC = m_AR << 1;
|
||||
@ -230,7 +309,7 @@ void n8x300_cpu_device::execute_run()
|
||||
{
|
||||
src = get_reg(SRC);
|
||||
dst = rotate(src,rotlen);
|
||||
set_reg(DST,dst);
|
||||
set_reg(DST,dst,false);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -243,62 +322,42 @@ void n8x300_cpu_device::execute_run()
|
||||
src = (get_reg(SRC)) << (7-DST_LSB);
|
||||
mask <<= (7-DST_LSB);
|
||||
if(DST_IS_RIGHT_BANK)
|
||||
{
|
||||
dst = (m_right_IV & ~mask) | (src & mask);
|
||||
m_right_IV = dst;
|
||||
WRITEPORT(m_IVR+0x100,m_right_IV);
|
||||
}
|
||||
xmit_rb(src, mask);
|
||||
else
|
||||
{
|
||||
dst = (m_left_IV & ~mask) | (src & mask);
|
||||
m_left_IV = dst;
|
||||
WRITEPORT(m_IVL,m_left_IV);
|
||||
}
|
||||
xmit_lb(src, mask);
|
||||
}
|
||||
else if(!(is_src_reg(opcode)) && is_dst_reg(opcode))
|
||||
{ // MOVE IV,reg
|
||||
SRC_LATCH;
|
||||
if(SRC_IS_RIGHT_BANK)
|
||||
src = rotate(m_right_IV,7-SRC_LSB);
|
||||
else
|
||||
src = rotate(m_left_IV,7-SRC_LSB);
|
||||
src = rotate(m_IV_latch,7-SRC_LSB);
|
||||
mask = ((1 << rotlen)-1);
|
||||
dst = src & mask;
|
||||
set_reg(DST,dst);
|
||||
set_reg(DST,dst,false);
|
||||
}
|
||||
else if(!(is_src_reg(opcode)) && !(is_dst_reg(opcode)))
|
||||
{ // MOVE IV,IV
|
||||
SRC_LATCH;
|
||||
if(SRC_IS_RIGHT_BANK)
|
||||
src = rotate(m_right_IV,7-SRC_LSB);
|
||||
else
|
||||
src = rotate(m_left_IV,7-SRC_LSB);
|
||||
src = rotate(m_IV_latch,7-SRC_LSB);
|
||||
mask = ((1 << rotlen)-1);
|
||||
dst = src & mask;
|
||||
dst <<= (7-DST_LSB);
|
||||
mask <<= (7-DST_LSB);
|
||||
if(SRC_IS_RIGHT_BANK) // untouched source IV bits are preserved and sent to destination IV
|
||||
{
|
||||
dst = (m_right_IV & ~mask) | (dst & mask);
|
||||
m_right_IV = dst;
|
||||
WRITEPORT(m_IVR+0x100,m_right_IV);
|
||||
}
|
||||
if(DST_IS_RIGHT_BANK) // untouched source IV bits are preserved and sent to destination IV
|
||||
xmit_rb(dst, mask);
|
||||
else
|
||||
{
|
||||
dst = (m_left_IV & ~mask) | (dst & mask);
|
||||
m_left_IV = dst;
|
||||
WRITEPORT(m_IVL,m_left_IV);
|
||||
}
|
||||
xmit_lb(dst, mask);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x01: // ADD
|
||||
{
|
||||
uint16_t result;
|
||||
rotlen = ROTLEN;
|
||||
if(is_rot(opcode))
|
||||
{ // ADD reg,reg
|
||||
src = rotate(get_reg(SRC),rotlen);
|
||||
result = src + m_AUX;
|
||||
set_reg(DST,result & 0xff);
|
||||
set_reg(DST,result & 0xff,false);
|
||||
SET_OVF;
|
||||
}
|
||||
else
|
||||
@ -314,65 +373,43 @@ void n8x300_cpu_device::execute_run()
|
||||
mask <<= DST_LSB;
|
||||
SET_OVF;
|
||||
if(DST_IS_RIGHT_BANK)
|
||||
{
|
||||
dst = (m_right_IV & ~mask) | (dst & mask);
|
||||
m_right_IV = dst;
|
||||
WRITEPORT(m_IVR+0x100,m_right_IV);
|
||||
}
|
||||
xmit_rb(dst, mask);
|
||||
else
|
||||
{
|
||||
dst = (m_left_IV & ~mask) | (dst & mask);
|
||||
m_left_IV = dst;
|
||||
WRITEPORT(m_IVL,m_left_IV);
|
||||
}
|
||||
xmit_lb(dst, mask);
|
||||
}
|
||||
else if(!(is_src_reg(opcode)) && is_dst_reg(opcode))
|
||||
{ // ADD IV,reg
|
||||
SRC_LATCH;
|
||||
mask = ((1 << rotlen)-1);
|
||||
if(SRC_IS_RIGHT_BANK)
|
||||
src = rotate(m_right_IV,7-SRC_LSB) & mask;
|
||||
else
|
||||
src = rotate(m_left_IV,7-SRC_LSB) & mask;
|
||||
src = rotate(m_IV_latch,7-SRC_LSB) & mask;
|
||||
result = src + m_AUX;
|
||||
SET_OVF;
|
||||
set_reg(DST,result & 0xff);
|
||||
set_reg(DST,result & 0xff,false);
|
||||
}
|
||||
else if(!(is_src_reg(opcode)) && !(is_dst_reg(opcode)))
|
||||
{ // ADD IV,IV
|
||||
SRC_LATCH;
|
||||
DST_LATCH;
|
||||
mask = ((1 << rotlen)-1);
|
||||
if(SRC_IS_RIGHT_BANK)
|
||||
src = rotate(m_right_IV,7-SRC_LSB) & mask;
|
||||
else
|
||||
src = rotate(m_left_IV,7-SRC_LSB) & mask;
|
||||
src = rotate(m_IV_latch,7-SRC_LSB) & mask;
|
||||
result = src + m_AUX;
|
||||
SET_OVF;
|
||||
dst = (result << (7-DST_LSB)) & 0xff;
|
||||
mask <<= (7-DST_LSB);
|
||||
if(SRC_IS_RIGHT_BANK) // unused destination IV data is not preserved, is merged with input IV data
|
||||
{
|
||||
dst = (m_right_IV & ~mask) | (dst & mask);
|
||||
m_right_IV = dst;
|
||||
WRITEPORT(m_IVR+0x100,m_right_IV);
|
||||
}
|
||||
if(DST_IS_RIGHT_BANK) // unused destination IV data is not preserved, is merged with input IV data
|
||||
xmit_rb(dst, mask);
|
||||
else
|
||||
{
|
||||
dst = (m_left_IV & ~mask) | (dst & mask);
|
||||
m_left_IV = dst;
|
||||
WRITEPORT(m_IVL,m_left_IV);
|
||||
}
|
||||
xmit_lb(dst, mask);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x02: // AND
|
||||
rotlen = ROTLEN;
|
||||
if(is_rot(opcode))
|
||||
{ // AND reg,reg
|
||||
src = rotate(get_reg(SRC),rotlen);
|
||||
dst = src & m_AUX;
|
||||
set_reg(DST,dst);
|
||||
set_reg(DST,dst,false);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -381,60 +418,36 @@ void n8x300_cpu_device::execute_run()
|
||||
if(is_src_reg(opcode) && !(is_dst_reg(opcode)))
|
||||
{ // AND reg,IV
|
||||
DST_LATCH;
|
||||
src = get_reg(SRC) & m_AUX;
|
||||
src = get_reg(SRC);
|
||||
dst = src & m_AUX;
|
||||
mask = ((1 << rotlen)-1);
|
||||
src <<= (7-DST_LSB);
|
||||
dst <<= (7-DST_LSB);
|
||||
mask <<= (7-DST_LSB);
|
||||
if(DST_IS_RIGHT_BANK)
|
||||
{
|
||||
dst = (m_right_IV & ~mask) | (src & mask);
|
||||
m_right_IV = dst;
|
||||
WRITEPORT(m_IVR+0x100,m_right_IV);
|
||||
}
|
||||
xmit_rb(dst, mask);
|
||||
else
|
||||
{
|
||||
dst = (m_left_IV & ~mask) | (src & mask);
|
||||
m_left_IV = dst;
|
||||
WRITEPORT(m_IVL,m_left_IV);
|
||||
}
|
||||
xmit_lb(dst, mask);
|
||||
}
|
||||
else if(!(is_src_reg(opcode)) && is_dst_reg(opcode))
|
||||
{ // AND IV,reg
|
||||
SRC_LATCH;
|
||||
mask = ((1 << rotlen)-1);
|
||||
if(SRC_IS_RIGHT_BANK)
|
||||
src = rotate(m_right_IV,7-SRC_LSB) & mask;
|
||||
else
|
||||
src = rotate(m_left_IV,7-SRC_LSB) & mask;
|
||||
src &= mask;
|
||||
src = rotate(m_IV_latch,7-SRC_LSB) & mask;
|
||||
dst = src & m_AUX;
|
||||
set_reg(DST,dst);
|
||||
set_reg(DST,dst,false);
|
||||
}
|
||||
else if(!(is_src_reg(opcode)) && !(is_dst_reg(opcode)))
|
||||
{ // AND IV,IV
|
||||
SRC_LATCH;
|
||||
DST_LATCH;
|
||||
mask = ((1 << rotlen)-1);
|
||||
if(SRC_IS_RIGHT_BANK)
|
||||
src = rotate(m_right_IV,7-SRC_LSB) & mask;
|
||||
else
|
||||
src = rotate(m_left_IV,7-SRC_LSB) & mask;
|
||||
src &= mask;
|
||||
src = rotate(m_IV_latch,7-SRC_LSB) & mask;
|
||||
dst = src & m_AUX;
|
||||
dst <<= (7-DST_LSB);
|
||||
mask <<= (7-DST_LSB);
|
||||
if(SRC_IS_RIGHT_BANK)
|
||||
{
|
||||
dst = (m_right_IV & ~mask) | (src & mask);
|
||||
m_right_IV = dst;
|
||||
WRITEPORT(m_IVR+0x100,m_right_IV);
|
||||
}
|
||||
if(DST_IS_RIGHT_BANK)
|
||||
xmit_rb(dst, mask);
|
||||
else
|
||||
{
|
||||
dst = (m_left_IV & ~mask) | (src & mask);
|
||||
m_left_IV = dst;
|
||||
WRITEPORT(m_IVL,m_left_IV);
|
||||
}
|
||||
xmit_lb(dst, mask);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -444,69 +457,45 @@ void n8x300_cpu_device::execute_run()
|
||||
{ // AND reg,reg
|
||||
src = rotate(get_reg(SRC),rotlen);
|
||||
dst = src ^ m_AUX;
|
||||
set_reg(DST,dst);
|
||||
set_reg(DST,dst,false);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(rotlen == 0)
|
||||
rotlen = 8; // 0 = 8-bit I/O field length
|
||||
if(is_src_reg(opcode) && !(is_dst_reg(opcode)))
|
||||
{ // AND reg,IV
|
||||
{ // XOR reg,IV
|
||||
DST_LATCH;
|
||||
src = get_reg(SRC) ^ m_AUX;
|
||||
src = get_reg(SRC);
|
||||
dst = src ^ m_AUX;
|
||||
mask = ((1 << rotlen)-1);
|
||||
src <<= (7-DST_LSB);
|
||||
dst <<= (7-DST_LSB);
|
||||
mask <<= (7-DST_LSB);
|
||||
if(DST_IS_RIGHT_BANK)
|
||||
{
|
||||
dst = (m_right_IV & ~mask) | (src & mask);
|
||||
m_right_IV = dst;
|
||||
WRITEPORT(m_IVR+0x100,m_right_IV);
|
||||
}
|
||||
xmit_rb(dst, mask);
|
||||
else
|
||||
{
|
||||
dst = (m_left_IV & ~mask) | (src & mask);
|
||||
m_left_IV = dst;
|
||||
WRITEPORT(m_IVL,m_left_IV);
|
||||
}
|
||||
xmit_lb(dst, mask);
|
||||
}
|
||||
else if(!(is_src_reg(opcode)) && is_dst_reg(opcode))
|
||||
{ // AND IV,reg
|
||||
{ // XOR IV,reg
|
||||
SRC_LATCH;
|
||||
mask = ((1 << rotlen)-1);
|
||||
if(SRC_IS_RIGHT_BANK)
|
||||
src = rotate(m_right_IV,7-SRC_LSB) & mask;
|
||||
else
|
||||
src = rotate(m_left_IV,7-SRC_LSB) & mask;
|
||||
src &= mask;
|
||||
src = rotate(m_IV_latch,7-SRC_LSB) & mask;
|
||||
dst = src ^ m_AUX;
|
||||
set_reg(DST,dst);
|
||||
set_reg(DST,dst,false);
|
||||
}
|
||||
else if(!(is_src_reg(opcode)) && !(is_dst_reg(opcode)))
|
||||
{ // AND IV,IV
|
||||
{ // XOR IV,IV
|
||||
SRC_LATCH;
|
||||
DST_LATCH;
|
||||
mask = ((1 << rotlen)-1);
|
||||
if(SRC_IS_RIGHT_BANK)
|
||||
src = rotate(m_right_IV,7-SRC_LSB) & mask;
|
||||
else
|
||||
src = rotate(m_left_IV,7-SRC_LSB) & mask;
|
||||
src &= mask;
|
||||
src = rotate(m_IV_latch,7-SRC_LSB) & mask;
|
||||
dst = src ^ m_AUX;
|
||||
dst <<= (7-DST_LSB);
|
||||
mask <<= (7-DST_LSB);
|
||||
if(SRC_IS_RIGHT_BANK)
|
||||
{
|
||||
dst = (m_right_IV & ~mask) | (src & mask);
|
||||
m_right_IV = dst;
|
||||
WRITEPORT(m_IVR+0x100,m_right_IV);
|
||||
}
|
||||
if(DST_IS_RIGHT_BANK)
|
||||
xmit_rb(dst, mask);
|
||||
else
|
||||
{
|
||||
dst = (m_left_IV & ~mask) | (src & mask);
|
||||
m_left_IV = dst;
|
||||
WRITEPORT(m_IVL,m_left_IV);
|
||||
}
|
||||
xmit_lb(dst, mask);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -524,10 +513,7 @@ void n8x300_cpu_device::execute_run()
|
||||
if(rotlen == 0)
|
||||
rotlen = 8; // 0 = 8-bit I/O field length
|
||||
mask = ((1 << rotlen)-1);
|
||||
if(SRC_IS_RIGHT_BANK)
|
||||
src = rotate(m_right_IV,7-SRC_LSB);
|
||||
else
|
||||
src = rotate(m_left_IV,7-SRC_LSB);
|
||||
src = rotate(m_IV_latch,7-SRC_LSB);
|
||||
src &= mask;
|
||||
src += IMM5;
|
||||
SET_AR((m_AR & 0x1fe0) | (src & 0x1f));
|
||||
@ -547,11 +533,7 @@ void n8x300_cpu_device::execute_run()
|
||||
if(rotlen == 0)
|
||||
rotlen = 8; // 0 = 8-bit I/O field length
|
||||
mask = ((1 << rotlen)-1);
|
||||
if(SRC_IS_RIGHT_BANK)
|
||||
src = rotate(m_right_IV,7-SRC_LSB);
|
||||
else
|
||||
src = rotate(m_left_IV,7-SRC_LSB);
|
||||
rotate(src,SRC_LSB);
|
||||
src = rotate(m_IV_latch,7-SRC_LSB);
|
||||
src &= mask;
|
||||
if(src != 0)
|
||||
SET_PC((m_PC & 0x1fe0) | IMM5);
|
||||
@ -560,7 +542,7 @@ void n8x300_cpu_device::execute_run()
|
||||
case 0x06: // XMIT (Transmit)
|
||||
// the source is actually the destination for this instruction
|
||||
if(is_src_reg(opcode))
|
||||
set_reg(SRC,IMM8);
|
||||
set_reg(SRC,IMM8,true);
|
||||
else
|
||||
{
|
||||
SRC_LATCH;
|
||||
@ -572,15 +554,9 @@ void n8x300_cpu_device::execute_run()
|
||||
mask <<= (7-SRC_LSB);
|
||||
dst <<= (7-SRC_LSB);
|
||||
if(SRC_IS_RIGHT_BANK)
|
||||
{
|
||||
m_right_IV = (m_right_IV & ~mask) | (dst & mask);
|
||||
WRITEPORT(m_IVR+0x100,m_right_IV);
|
||||
}
|
||||
xmit_rb(dst, mask);
|
||||
else
|
||||
{
|
||||
m_left_IV = (m_left_IV & ~mask) | (dst & mask);
|
||||
WRITEPORT(m_IVL,m_left_IV);
|
||||
}
|
||||
xmit_lb(dst, mask);
|
||||
}
|
||||
break;
|
||||
case 0x07: // JMP
|
||||
|
@ -28,11 +28,11 @@ enum
|
||||
_8X300_IVL,
|
||||
_8X300_OVF,
|
||||
_8X300_R11,
|
||||
_8X300_UNUSED12,
|
||||
_8X300_UNUSED13,
|
||||
_8X300_UNUSED14,
|
||||
_8X300_UNUSED15,
|
||||
_8X300_UNUSED16,
|
||||
_8X300_R12,
|
||||
_8X300_R13,
|
||||
_8X300_R14,
|
||||
_8X300_R15,
|
||||
_8X300_R16,
|
||||
_8X300_IVR,
|
||||
_8X300_LIV,
|
||||
_8X300_RIV,
|
||||
@ -45,8 +45,13 @@ public:
|
||||
// construction/destruction
|
||||
n8x300_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
auto sc_callback() { return m_sc_callback.bind(); }
|
||||
|
||||
protected:
|
||||
n8x300_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_resolve_objects() override;
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
@ -65,6 +70,12 @@ protected:
|
||||
// device_disasm_interface overrides
|
||||
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
|
||||
|
||||
virtual void set_reg(uint8_t reg, uint8_t val, bool xmit);
|
||||
virtual uint8_t get_reg(uint8_t reg);
|
||||
|
||||
void xmit_lb(uint8_t dst, uint8_t mask);
|
||||
void xmit_rb(uint8_t dst, uint8_t mask);
|
||||
|
||||
address_space_config m_program_config;
|
||||
address_space_config m_io_config;
|
||||
|
||||
@ -75,6 +86,8 @@ protected:
|
||||
memory_access_cache<1, 0, ENDIANNESS_BIG> *m_cache;
|
||||
address_space *m_io;
|
||||
|
||||
devcb_write8 m_sc_callback; // Select Command (address latch)
|
||||
|
||||
uint16_t m_PC; // Program Counter
|
||||
uint16_t m_AR; // Address Register
|
||||
uint16_t m_IR; // Instruction Register
|
||||
@ -86,13 +99,17 @@ protected:
|
||||
uint8_t m_R5;
|
||||
uint8_t m_R6;
|
||||
uint8_t m_R11;
|
||||
uint8_t m_R12;
|
||||
uint8_t m_R13;
|
||||
uint8_t m_R14;
|
||||
uint8_t m_R15;
|
||||
uint8_t m_R16;
|
||||
uint8_t m_IVL; // Interface vector (I/O) left bank (write-only)
|
||||
uint8_t m_IVR; // Interface vector (I/O) right bank (write-only)
|
||||
uint8_t m_OVF; // Overflow register (read-only)
|
||||
uint16_t m_genPC;
|
||||
|
||||
uint8_t m_left_IV; // IV bank contents, these are latched when IVL or IVR are set
|
||||
uint8_t m_right_IV;
|
||||
uint8_t m_IV_latch; // IV bank contents, these are latched when IVL or IVR are set
|
||||
|
||||
private:
|
||||
inline bool is_rot(uint16_t opcode)
|
||||
@ -120,10 +137,20 @@ private:
|
||||
{
|
||||
return ((s & ((uint8_t)0xff << n)) >> n) | ((s & ((uint8_t)0xff >> (8-n))) << (8-n));
|
||||
}
|
||||
void set_reg(uint8_t reg,uint8_t val);
|
||||
uint8_t get_reg(uint8_t reg);
|
||||
};
|
||||
|
||||
class n8x305_cpu_device : public n8x300_cpu_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
n8x305_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
protected:
|
||||
virtual void set_reg(uint8_t reg, uint8_t val, bool xmit) override;
|
||||
virtual uint8_t get_reg(uint8_t reg) override;
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(N8X300, n8x300_cpu_device)
|
||||
DECLARE_DEVICE_TYPE(N8X305, n8x305_cpu_device)
|
||||
|
||||
#endif // MAME_CPU_8X300_8X300_H
|
||||
|
@ -297,7 +297,7 @@ void fs3216_state::fs3216(machine_config &config)
|
||||
screen.set_raw(14.58_MHz_XTAL, 900, 0, 720, 270, 0, 250);
|
||||
screen.set_screen_update("crtc", FUNC(mc6845_device::screen_update));
|
||||
|
||||
n8x300_cpu_device &wdcpu(N8X300(config, "wdcpu", 20_MHz_XTAL / 2)); // N8X305I
|
||||
n8x305_cpu_device &wdcpu(N8X305(config, "wdcpu", 8_MHz_XTAL)); // N8X305I
|
||||
wdcpu.set_addrmap(AS_PROGRAM, &fs3216_state::wdcpu_prog_map);
|
||||
wdcpu.set_addrmap(AS_IO, &fs3216_state::wdcpu_bank_map);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user