mirror of
https://github.com/holub/mame
synced 2025-07-04 09:28:51 +03:00
dp8344: Add preliminary execution core
This commit is contained in:
parent
0553965fe5
commit
edbc9a763b
@ -54,6 +54,8 @@ DEFINE_DEVICE_TYPE(DP8344, dp8344_device, "dp8344", "DP8344 BCP")
|
|||||||
// DEVICE CONSTRUCTION AND INITIALIZATION
|
// DEVICE CONSTRUCTION AND INITIALIZATION
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
|
|
||||||
|
ALLOW_SAVE_TYPE(dp8344_device::inst_state);
|
||||||
|
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
// dp8344_device - constructor
|
// dp8344_device - constructor
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
@ -72,6 +74,9 @@ dp8344_device::dp8344_device(const machine_config &mconfig, const char *tag, dev
|
|||||||
, m_pc(0)
|
, m_pc(0)
|
||||||
, m_icount(0)
|
, m_icount(0)
|
||||||
, m_nmi_pending(false)
|
, m_nmi_pending(false)
|
||||||
|
, m_wait_states(0)
|
||||||
|
, m_source_data(0)
|
||||||
|
, m_data_address(0)
|
||||||
, m_ccr(0)
|
, m_ccr(0)
|
||||||
, m_ncf(0)
|
, m_ncf(0)
|
||||||
, m_icr(0)
|
, m_icr(0)
|
||||||
@ -86,7 +91,7 @@ dp8344_device::dp8344_device(const machine_config &mconfig, const char *tag, dev
|
|||||||
, m_tmr(0)
|
, m_tmr(0)
|
||||||
, m_gp_main{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
, m_gp_main{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||||
, m_gp_alt{0, 0, 0, 0}
|
, m_gp_alt{0, 0, 0, 0}
|
||||||
, m_ir{{0}, {0}, {0}, {0}}
|
, m_ir{0, 0, 0, 0}
|
||||||
, m_tr(0)
|
, m_tr(0)
|
||||||
, m_as{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
, m_as{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||||
, m_ds{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
, m_ds{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||||
@ -151,10 +156,10 @@ void dp8344_device::device_start()
|
|||||||
set_icountptr(m_icount);
|
set_icountptr(m_icount);
|
||||||
|
|
||||||
// debug state registration
|
// debug state registration
|
||||||
state_add(BCP_PC, "PC", m_pc);
|
state_add<u16>(BCP_PC, "PC", [this]() { return m_pc; }, [this](u16 data) { m_pc = m_ppc = data; prefetch_instruction(); });
|
||||||
state_add(STATE_GENPC, "GENPC", m_pc).noshow();
|
state_add(STATE_GENPC, "GENPC", m_pc).noshow();
|
||||||
state_add(STATE_GENPCBASE, "GENPCBASE", m_pc).noshow();
|
state_add(STATE_GENPCBASE, "GENPCBASE", m_pc).noshow();
|
||||||
state_add(STATE_GENFLAGS, "GENFLAGS", m_ccr).noshow();
|
state_add(STATE_GENFLAGS, "GENFLAGS", m_ccr).formatstr("%09s").noshow();
|
||||||
state_add(BCP_BA, "BA", m_ba);
|
state_add(BCP_BA, "BA", m_ba);
|
||||||
state_add(BCP_BB, "BB", m_bb);
|
state_add(BCP_BB, "BB", m_bb);
|
||||||
state_add(BCP_CCR, "CCR", m_ccr);
|
state_add(BCP_CCR, "CCR", m_ccr);
|
||||||
@ -175,9 +180,13 @@ void dp8344_device::device_start()
|
|||||||
state_add(BCP_GP4_ALT + i, string_format("GP%da", 4 + i).c_str(), m_gp_alt[i]);
|
state_add(BCP_GP4_ALT + i, string_format("GP%da", 4 + i).c_str(), m_gp_alt[i]);
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
state_add(BCP_IW + i, string_format("I%c", 'W' + i).c_str(), m_ir[i].w);
|
state_add(BCP_IW + i, string_format("I%c", 'W' + i).c_str(), m_ir[i]);
|
||||||
state_add(BCP_IWLO + i, string_format("I%cLO", 'W' + i).c_str(), m_ir[i].b.l).noshow();
|
state_add<u8>(BCP_IWLO + i, string_format("I%cLO", 'W' + i).c_str(),
|
||||||
state_add(BCP_IWHI + i, string_format("I%cHI", 'W' + i).c_str(), m_ir[i].b.h).noshow();
|
[this, i]() -> u8 { return m_ir[i] & 0x00ff; },
|
||||||
|
[this, i](u8 data) { m_ir[i] = (m_ir[i] & 0xff00) | data; }).noshow();
|
||||||
|
state_add<u8>(BCP_IWHI + i, string_format("I%cHI", 'W' + i).c_str(),
|
||||||
|
[this, i]() -> u8 { return (m_ir[i] & 0xff00) >> 8; },
|
||||||
|
[this, i](u8 data) { m_ir[i] = (m_ir[i] & 0x00ff) | u16(data) << 8; }).noshow();
|
||||||
}
|
}
|
||||||
for (int i = 8; i < 16; i++)
|
for (int i = 8; i < 16; i++)
|
||||||
state_add(BCP_GP8 + i - 8, string_format("GP%d", i).c_str(), m_gp_main[i]);
|
state_add(BCP_GP8 + i - 8, string_format("GP%d", i).c_str(), m_gp_main[i]);
|
||||||
@ -187,6 +196,7 @@ void dp8344_device::device_start()
|
|||||||
|
|
||||||
// save states
|
// save states
|
||||||
save_item(NAME(m_pc));
|
save_item(NAME(m_pc));
|
||||||
|
save_item(NAME(m_ppc));
|
||||||
save_item(NAME(m_nmi_state));
|
save_item(NAME(m_nmi_state));
|
||||||
save_item(NAME(m_ccr));
|
save_item(NAME(m_ccr));
|
||||||
save_item(NAME(m_ncf));
|
save_item(NAME(m_ncf));
|
||||||
@ -202,8 +212,7 @@ void dp8344_device::device_start()
|
|||||||
save_item(NAME(m_tmr));
|
save_item(NAME(m_tmr));
|
||||||
save_item(NAME(m_gp_main));
|
save_item(NAME(m_gp_main));
|
||||||
save_item(NAME(m_gp_alt));
|
save_item(NAME(m_gp_alt));
|
||||||
for (int i = 0; i < 4; i++)
|
save_item(NAME(m_ir));
|
||||||
save_item(NAME(m_ir[i].w), i);
|
|
||||||
save_item(NAME(m_tr));
|
save_item(NAME(m_tr));
|
||||||
save_item(NAME(m_asp));
|
save_item(NAME(m_asp));
|
||||||
save_item(NAME(m_dsp));
|
save_item(NAME(m_dsp));
|
||||||
@ -215,6 +224,10 @@ void dp8344_device::device_start()
|
|||||||
save_item(NAME(m_hib));
|
save_item(NAME(m_hib));
|
||||||
save_item(NAME(m_latched_instr));
|
save_item(NAME(m_latched_instr));
|
||||||
save_item(NAME(m_nmi_pending));
|
save_item(NAME(m_nmi_pending));
|
||||||
|
save_item(NAME(m_inst_state));
|
||||||
|
save_item(NAME(m_wait_states));
|
||||||
|
save_item(NAME(m_source_data));
|
||||||
|
save_item(NAME(m_data_address));
|
||||||
save_item(NAME(m_rfifo)); // 3-frame Receive FIFO
|
save_item(NAME(m_rfifo)); // 3-frame Receive FIFO
|
||||||
save_item(NAME(m_tfifo)); // 3-frame Transmit FIFO
|
save_item(NAME(m_tfifo)); // 3-frame Transmit FIFO
|
||||||
save_item(NAME(m_rfifo_head));
|
save_item(NAME(m_rfifo_head));
|
||||||
@ -229,7 +242,7 @@ void dp8344_device::device_start()
|
|||||||
void dp8344_device::device_reset()
|
void dp8344_device::device_reset()
|
||||||
{
|
{
|
||||||
// Reset Program Counter
|
// Reset Program Counter
|
||||||
m_pc = 0x0000;
|
m_pc = m_ppc = 0x0000;
|
||||||
|
|
||||||
// Reset Condition Code Register
|
// Reset Condition Code Register
|
||||||
m_ccr &= 0x10;
|
m_ccr &= 0x10;
|
||||||
@ -265,7 +278,9 @@ void dp8344_device::device_reset()
|
|||||||
m_ric = m_auto_start ? 0x03 : 0x01;
|
m_ric = m_auto_start ? 0x03 : 0x01;
|
||||||
m_hib = false;
|
m_hib = false;
|
||||||
|
|
||||||
|
// Reset execution state
|
||||||
m_nmi_pending = false;
|
m_nmi_pending = false;
|
||||||
|
m_inst_state = T1_START;
|
||||||
|
|
||||||
transceiver_reset();
|
transceiver_reset();
|
||||||
|
|
||||||
@ -274,49 +289,21 @@ void dp8344_device::device_reset()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//**************************************************************************
|
|
||||||
// CONTROL REGISTERS AND CONDITION CODES
|
|
||||||
//**************************************************************************
|
|
||||||
|
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
// get_flag - retrieve condition from CCR or TSR
|
// create_disassembler - factory method for
|
||||||
|
// disassembling program code
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
bool dp8344_device::get_flag(unsigned f) const
|
std::unique_ptr<util::disasm_interface> dp8344_device::create_disassembler()
|
||||||
{
|
{
|
||||||
switch (f)
|
return std::make_unique<dp8344_disassembler>();
|
||||||
{
|
|
||||||
case 0: // Zero/Equal
|
|
||||||
return BIT(m_ccr, 0);
|
|
||||||
|
|
||||||
case 1: // Carry
|
|
||||||
return BIT(m_ccr, 1);
|
|
||||||
|
|
||||||
case 2: // Overflow
|
|
||||||
return BIT(m_ccr, 2);
|
|
||||||
|
|
||||||
case 3: // Negative (or else Positive)
|
|
||||||
return BIT(m_ccr, 3);
|
|
||||||
|
|
||||||
case 4: // Receiver Active
|
|
||||||
return BIT(m_tsr, 4);
|
|
||||||
|
|
||||||
case 5: // Receiver Error
|
|
||||||
return BIT(m_tsr, 5);
|
|
||||||
|
|
||||||
case 6: // Data Available
|
|
||||||
return BIT(m_tsr, 3); // FIXME: differs from numeric value!
|
|
||||||
|
|
||||||
case 7: // Transmitter FIFO Full (or else Not Full)
|
|
||||||
return BIT(m_tsr, 7);
|
|
||||||
|
|
||||||
default:
|
|
||||||
logerror("Unknown flag %d\n", f);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
// INTERRUPTS AND CONTROL REGISTERS
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
// set_receiver_interrupt - update receiver
|
// set_receiver_interrupt - update receiver
|
||||||
// interrupt request status
|
// interrupt request status
|
||||||
@ -405,6 +392,10 @@ void dp8344_device::set_condition_code(u8 data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// set_interrupt_control - write to ICR
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
void dp8344_device::set_interrupt_control(u8 data)
|
void dp8344_device::set_interrupt_control(u8 data)
|
||||||
{
|
{
|
||||||
// IM0: Receiver
|
// IM0: Receiver
|
||||||
@ -469,6 +460,169 @@ void dp8344_device::set_auxiliary_control(u8 data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// interrupt_active - determine if any of the
|
||||||
|
// five maskable interrupts is active
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
bool dp8344_device::interrupt_active() const
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// get_interrupt_vector - return the vector for
|
||||||
|
// the highest priority maskable interrupt
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
u8 dp8344_device::get_interrupt_vector() const
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
// CONDITION CODES AND ALU HELPERS
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// get_flag - retrieve condition from CCR or TSR
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
bool dp8344_device::get_flag(unsigned f) const
|
||||||
|
{
|
||||||
|
switch (f)
|
||||||
|
{
|
||||||
|
case 0: // Zero/Equal
|
||||||
|
return BIT(m_ccr, 0);
|
||||||
|
|
||||||
|
case 1: // Carry
|
||||||
|
return BIT(m_ccr, 1);
|
||||||
|
|
||||||
|
case 2: // Overflow
|
||||||
|
return BIT(m_ccr, 2);
|
||||||
|
|
||||||
|
case 3: // Negative (or else Positive)
|
||||||
|
return BIT(m_ccr, 3);
|
||||||
|
|
||||||
|
case 4: // Receiver Active
|
||||||
|
return BIT(m_tsr, 4);
|
||||||
|
|
||||||
|
case 5: // Receiver Error
|
||||||
|
return BIT(m_tsr, 5);
|
||||||
|
|
||||||
|
case 6: // Data Available
|
||||||
|
return BIT(m_tsr, 3); // FIXME: differs from numeric value!
|
||||||
|
|
||||||
|
case 7: // Transmitter FIFO Full (or else Not Full)
|
||||||
|
return BIT(m_tsr, 7);
|
||||||
|
|
||||||
|
default:
|
||||||
|
logerror("Unknown flag %d\n", f);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// set_nz - set the N and Z flags based on the
|
||||||
|
// result of an ALU operation
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void dp8344_device::set_nz(u8 result)
|
||||||
|
{
|
||||||
|
m_ccr &= 0xf6;
|
||||||
|
if (result == 0)
|
||||||
|
m_ccr |= 0x01;
|
||||||
|
else if (BIT(result, 7))
|
||||||
|
m_ccr |= 0x08;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// set_carry - set or clear the C flag
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void dp8344_device::set_carry(bool state)
|
||||||
|
{
|
||||||
|
if (state)
|
||||||
|
m_ccr |= 0x02;
|
||||||
|
else
|
||||||
|
m_ccr &= 0xfd;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// rotate_right - perform right rotation for ROT
|
||||||
|
// and JRMK instructions
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
u8 dp8344_device::rotate_right(u8 data, u8 b)
|
||||||
|
{
|
||||||
|
return (data >> b) | (data << (8 - b));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// add_nzcv - add and set N, Z, C, V flags for
|
||||||
|
// ADCA, ADD and ADDA instructions
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
u8 dp8344_device::add_nzcv(u8 s1, u8 s2, bool carry_in)
|
||||||
|
{
|
||||||
|
s16 result = s8(s1) + s8(s2) + (carry_in ? 1 : 0);
|
||||||
|
if (result >= 128 && result < -128)
|
||||||
|
m_ccr |= 0x04;
|
||||||
|
else
|
||||||
|
m_ccr &= 0xfb;
|
||||||
|
|
||||||
|
set_carry(s1 + s2 + (carry_in ? 1 : 0) >= 0x100);
|
||||||
|
set_nz(u8(result));
|
||||||
|
return u8(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// sub_nzcv - add and set N, Z, C, V flags for
|
||||||
|
// CMP, SBCA, SUB and SUBA instructions
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
u8 dp8344_device::sub_nzcv(u8 s1, u8 s2, bool carry_in)
|
||||||
|
{
|
||||||
|
s16 result = s8(s1) - s8(s2) - (carry_in ? 1 : 0);
|
||||||
|
if (result >= 128 && result < -128)
|
||||||
|
m_ccr |= 0x04;
|
||||||
|
else
|
||||||
|
m_ccr &= 0xfb;
|
||||||
|
|
||||||
|
set_carry(s1 < s2 + (carry_in ? 1 : 0));
|
||||||
|
set_nz(u8(result));
|
||||||
|
return u8(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void dp8344_device::state_string_export(const device_state_entry &entry, std::string &str) const
|
||||||
|
{
|
||||||
|
switch (entry.index())
|
||||||
|
{
|
||||||
|
case STATE_GENFLAGS:
|
||||||
|
str = string_format("%c%c%c%c %c%c%c%c",
|
||||||
|
BIT(m_ccr, 7) ? 'T' : '.', // TO
|
||||||
|
BIT(m_ccr, 6) ? 'R' : '.', // RR
|
||||||
|
BIT(m_ccr, 5) ? 'W' : '.', // RW
|
||||||
|
BIT(m_ccr, 4) ? 'B' : '.', // BIRQ
|
||||||
|
BIT(m_ccr, 3) ? 'N' : '.',
|
||||||
|
BIT(m_ccr, 2) ? 'V' : '.',
|
||||||
|
BIT(m_ccr, 1) ? 'C' : '.',
|
||||||
|
BIT(m_ccr, 0) ? 'Z' : '.');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
// 16-BIT TIMER
|
// 16-BIT TIMER
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
@ -498,8 +652,8 @@ void dp8344_device::address_stack_push()
|
|||||||
{
|
{
|
||||||
m_as[m_asp++] = u32(m_pc)
|
m_as[m_asp++] = u32(m_pc)
|
||||||
| (u32(m_ccr & 0x0f) << 16)
|
| (u32(m_ccr & 0x0f) << 16)
|
||||||
| (m_ba << 20)
|
| (m_ba << 21)
|
||||||
| (m_bb << 21)
|
| (m_bb << 20)
|
||||||
| (u32(m_acr & 0x01) << 22);
|
| (u32(m_acr & 0x01) << 22);
|
||||||
if (m_asp >= 12)
|
if (m_asp >= 12)
|
||||||
m_asp = 0;
|
m_asp = 0;
|
||||||
@ -511,23 +665,23 @@ void dp8344_device::address_stack_push()
|
|||||||
// executing a RET or RETF instruction
|
// executing a RET or RETF instruction
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
void dp8344_device::address_stack_pop(u8 grf)
|
void dp8344_device::address_stack_pop(u8 g, bool rf)
|
||||||
{
|
{
|
||||||
m_asp = (m_asp == 0) ? 11 : m_asp - 1;
|
m_asp = (m_asp == 0) ? 11 : m_asp - 1;
|
||||||
m_pc = m_as[m_asp] & 0xffff;
|
m_pc = m_as[m_asp] & 0xffff;
|
||||||
|
|
||||||
// Optionally restore, set or clear GIE
|
// Optionally restore, set or clear GIE
|
||||||
if (BIT(grf, 6))
|
if (BIT(g, 1))
|
||||||
set_gie(BIT(grf, 5));
|
set_gie(BIT(g, 0));
|
||||||
else if (BIT(grf, 5))
|
else if (BIT(g, 0))
|
||||||
set_gie(BIT(m_as[m_asp], 22));
|
set_gie(BIT(m_as[m_asp], 22));
|
||||||
|
|
||||||
// Optionally restore ALU flags and register banks
|
// Optionally restore ALU flags and register banks
|
||||||
if (BIT(grf, 4))
|
if (rf)
|
||||||
{
|
{
|
||||||
m_ccr = (m_ccr & 0xf0) | (m_as[m_asp] & 0xf0000) >> 20;
|
m_ccr = (m_ccr & 0xf0) | (m_as[m_asp] & 0xf0000) >> 16;
|
||||||
m_ba = BIT(m_as[m_asp], 20);
|
m_ba = BIT(m_as[m_asp], 21);
|
||||||
m_bb = BIT(m_as[m_asp], 21);
|
m_bb = BIT(m_as[m_asp], 20);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -928,28 +1082,28 @@ u8 dp8344_device::read_register(unsigned reg)
|
|||||||
return m_gp_main[7];
|
return m_gp_main[7];
|
||||||
|
|
||||||
case 12: // IW (low byte)
|
case 12: // IW (low byte)
|
||||||
return m_ir[0].b.l;
|
return m_ir[0] & 0x00ff;
|
||||||
|
|
||||||
case 13: // IW (high byte)
|
case 13: // IW (high byte)
|
||||||
return m_ir[0].b.h;
|
return (m_ir[0] & 0xff00) >> 8;
|
||||||
|
|
||||||
case 14: // IX (low byte)
|
case 14: // IX (low byte)
|
||||||
return m_ir[1].b.l;
|
return m_ir[1] & 0x00ff;
|
||||||
|
|
||||||
case 15: // IX (high byte)
|
case 15: // IX (high byte)
|
||||||
return m_ir[1].b.h;
|
return (m_ir[1] & 0xff00) >> 8;
|
||||||
|
|
||||||
case 16: // IY (low byte)
|
case 16: // IY (low byte)
|
||||||
return m_ir[2].b.l;
|
return m_ir[2] & 0x00ff;
|
||||||
|
|
||||||
case 17: // IY (high byte)
|
case 17: // IY (high byte)
|
||||||
return m_ir[2].b.h;
|
return (m_ir[2] & 0xff00) >> 8;
|
||||||
|
|
||||||
case 18: // IZ (low byte)
|
case 18: // IZ (low byte)
|
||||||
return m_ir[3].b.l;
|
return m_ir[3] & 0x00ff;
|
||||||
|
|
||||||
case 19: // IZ (high byte)
|
case 19: // IZ (high byte)
|
||||||
return m_ir[3].b.h;
|
return (m_ir[3] & 0xff00) >> 8;
|
||||||
|
|
||||||
case 20: // GP8
|
case 20: // GP8
|
||||||
return m_gp_main[8];
|
return m_gp_main[8];
|
||||||
@ -1097,35 +1251,35 @@ void dp8344_device::write_register(unsigned reg, u8 data)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 12: // IW (low byte)
|
case 12: // IW (low byte)
|
||||||
m_ir[0].b.l = data;
|
m_ir[0] = (m_ir[0] & 0xff00) | data;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 13: // IW (high byte)
|
case 13: // IW (high byte)
|
||||||
m_ir[0].b.h = data;
|
m_ir[0] = (m_ir[0] & 0x00ff) | u16(data) << 8;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 14: // IX (low byte)
|
case 14: // IX (low byte)
|
||||||
m_ir[1].b.l = data;
|
m_ir[1] = (m_ir[1] & 0xff00) | data;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 15: // IX (high byte)
|
case 15: // IX (high byte)
|
||||||
m_ir[1].b.h = data;
|
m_ir[1] = (m_ir[1] & 0x00ff) | u16(data) << 8;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 16: // IY (low byte)
|
case 16: // IY (low byte)
|
||||||
m_ir[2].b.l = data;
|
m_ir[2] = (m_ir[2] & 0xff00) | data;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 17: // IY (high byte)
|
case 17: // IY (high byte)
|
||||||
m_ir[2].b.h = data;
|
m_ir[2] = (m_ir[2] & 0x00ff) | u16(data) << 8;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 18: // IZ (low byte)
|
case 18: // IZ (low byte)
|
||||||
m_ir[3].b.l = data;
|
m_ir[3] = (m_ir[3] & 0xff00) | data;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 19: // IZ (high byte)
|
case 19: // IZ (high byte)
|
||||||
m_ir[3].b.h = data;
|
m_ir[3] = (m_ir[3] & 0x00ff) | u16(data) << 8;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 20: // GP8
|
case 20: // GP8
|
||||||
@ -1220,12 +1374,371 @@ void dp8344_device::execute_set_input(int irqline, int state)
|
|||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
|
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
// create_disassembler -
|
// prefetch_instruction - fetch the next
|
||||||
|
// instruction word from program memory
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
std::unique_ptr<util::disasm_interface> dp8344_device::create_disassembler()
|
void dp8344_device::prefetch_instruction()
|
||||||
{
|
{
|
||||||
return std::make_unique<dp8344_disassembler>();
|
m_latched_instr = m_inst_cache->read_word(m_pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// latch_address - handle ALE cycle and set T2
|
||||||
|
// wait states for instructions referencing data
|
||||||
|
// memory
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void dp8344_device::latch_address(bool rw)
|
||||||
|
{
|
||||||
|
//logerror("Latching data memory address %04Xh for %sing (PC = %04Xh)\n", m_data_address, rw ? "read" : "writ", m_pc);
|
||||||
|
if ((m_dcr & 0x18) == 0)
|
||||||
|
m_wait_states = m_dcr & 0x07;
|
||||||
|
else
|
||||||
|
m_wait_states = std::max(m_dcr & 0x07, ((m_dcr & 0x18) >> 3) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// instruction_wait - set T2 wait states for
|
||||||
|
// non-memory instructions
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void dp8344_device::instruction_wait()
|
||||||
|
{
|
||||||
|
m_wait_states = (m_dcr & 0x18) >> 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// decode_instruction - begin execution of an
|
||||||
|
// opcode
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
dp8344_device::inst_state dp8344_device::decode_instruction()
|
||||||
|
{
|
||||||
|
if (m_latched_instr < 0x8000)
|
||||||
|
{
|
||||||
|
m_source_data = read_register(m_latched_instr & 0x000f);
|
||||||
|
if ((m_latched_instr & 0xf000) == 0x1000)
|
||||||
|
{
|
||||||
|
// MOVE to indexed data memory
|
||||||
|
m_data_address = m_ir[3] + ((m_latched_instr & 0x0ff0) >> 4);
|
||||||
|
return TX_WRITE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
instruction_wait();
|
||||||
|
return T2_STORE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((m_latched_instr & 0xf800) == 0x8000)
|
||||||
|
{
|
||||||
|
// JRMK
|
||||||
|
m_source_data = read_register(m_latched_instr & 0x001f);
|
||||||
|
return TX1_JRMK;
|
||||||
|
}
|
||||||
|
else if ((m_latched_instr & 0xfc00) == 0x8800)
|
||||||
|
{
|
||||||
|
// MOVE immediate to data memory
|
||||||
|
m_source_data = (m_latched_instr & 0x0380) >> 2 | (m_latched_instr & 0x001f);
|
||||||
|
m_data_address = m_ir[(m_latched_instr & 0x0060) >> 5];
|
||||||
|
return TX_WRITE;
|
||||||
|
}
|
||||||
|
else if ((m_latched_instr & 0xfc00) == 0x8c00)
|
||||||
|
{
|
||||||
|
// LJMP or LCALL, conditional
|
||||||
|
m_source_data = read_register(m_latched_instr & 0x001f);
|
||||||
|
instruction_wait();
|
||||||
|
return T2_ABSOLUTE;
|
||||||
|
}
|
||||||
|
else if ((m_latched_instr & 0xf000) == 0x9000)
|
||||||
|
{
|
||||||
|
// MOVE from indexed data memory
|
||||||
|
m_data_address = m_ir[3] + ((m_latched_instr & 0x0ff0) >> 4);
|
||||||
|
return TX_READ;
|
||||||
|
}
|
||||||
|
else if ((m_latched_instr >= 0xa000 && m_latched_instr < 0xae00) || (m_latched_instr & 0xfc00) == 0xc000)
|
||||||
|
{
|
||||||
|
if ((m_latched_instr & 0xfe00) != 0xc000)
|
||||||
|
m_source_data = read_register(m_latched_instr & 0x001f);
|
||||||
|
switch (m_latched_instr & 0x0180)
|
||||||
|
{
|
||||||
|
case 0x0000:
|
||||||
|
m_data_address = m_ir[(m_latched_instr & 0x0060) >> 5]--;
|
||||||
|
break;
|
||||||
|
case 0x0080:
|
||||||
|
m_data_address = m_ir[(m_latched_instr & 0x0060) >> 5];
|
||||||
|
break;
|
||||||
|
case 0x0100:
|
||||||
|
m_data_address = m_ir[(m_latched_instr & 0x0060) >> 5]++;
|
||||||
|
break;
|
||||||
|
case 0x0180:
|
||||||
|
m_data_address = ++m_ir[(m_latched_instr & 0x0060) >> 5];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return (m_latched_instr & 0xfe00) == 0xc000 ? TX_READ : TX_WRITE;
|
||||||
|
}
|
||||||
|
else if ((m_latched_instr & 0xff80) == 0xae80)
|
||||||
|
{
|
||||||
|
// EXX
|
||||||
|
m_ba = BIT(m_latched_instr, 4);
|
||||||
|
m_bb = BIT(m_latched_instr, 3);
|
||||||
|
if (BIT(m_latched_instr, 6))
|
||||||
|
set_gie(BIT(m_latched_instr, 5));
|
||||||
|
instruction_wait();
|
||||||
|
return T2_NEXT;
|
||||||
|
}
|
||||||
|
else if ((m_latched_instr & 0xff00) == 0xaf00)
|
||||||
|
{
|
||||||
|
// RET or RETF
|
||||||
|
if (BIT(m_latched_instr, 7) || get_flag(m_latched_instr & 0x0007) == BIT(m_latched_instr, 3))
|
||||||
|
return TX_RET;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
instruction_wait();
|
||||||
|
return T2_NEXT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((m_latched_instr & 0xf000) == 0xb000)
|
||||||
|
{
|
||||||
|
// MOVE immediate to register
|
||||||
|
instruction_wait();
|
||||||
|
return T2_STORE;
|
||||||
|
}
|
||||||
|
else if ((m_latched_instr & 0xfc00) == 0xc400)
|
||||||
|
{
|
||||||
|
// MOVE to or from accumulator-indexed data memory
|
||||||
|
if (BIT(m_latched_instr, 7))
|
||||||
|
m_source_data = read_register(m_latched_instr & 0x001f);
|
||||||
|
m_data_address = m_ir[(m_latched_instr & 0x0060) >> 5] + read_accumulator();
|
||||||
|
return BIT(m_latched_instr, 7) ? TX_WRITE : TX_READ;
|
||||||
|
}
|
||||||
|
else if ((m_latched_instr & 0xff00) == 0xcb00)
|
||||||
|
{
|
||||||
|
// JMP to relative destination
|
||||||
|
m_source_data = m_latched_instr & 0x00ff;
|
||||||
|
return TX2_JMP;
|
||||||
|
}
|
||||||
|
else if ((m_latched_instr & 0xff00) == 0xcc00)
|
||||||
|
{
|
||||||
|
// CALL to relative destination
|
||||||
|
m_source_data = m_latched_instr & 0x00ff;
|
||||||
|
return TX_CALL;
|
||||||
|
}
|
||||||
|
else if ((m_latched_instr & 0xff80) == 0xcd00)
|
||||||
|
{
|
||||||
|
// LJMP to index register
|
||||||
|
m_pc = m_ir[(m_latched_instr & 0x0060) >> 5];
|
||||||
|
instruction_wait();
|
||||||
|
return T2_NEXT;
|
||||||
|
}
|
||||||
|
else if ((m_latched_instr & 0xff80) == 0xcd80)
|
||||||
|
{
|
||||||
|
// JMP, register-based
|
||||||
|
m_source_data = read_register(m_latched_instr & 0x001f);
|
||||||
|
return TX1_JMP;
|
||||||
|
}
|
||||||
|
else if ((m_latched_instr & 0xff00) == 0xce00)
|
||||||
|
{
|
||||||
|
// LJMP or LCALL, unconditional
|
||||||
|
instruction_wait();
|
||||||
|
return T2_ABSOLUTE;
|
||||||
|
}
|
||||||
|
else if ((m_latched_instr & 0xff80) == 0xcf80)
|
||||||
|
{
|
||||||
|
// TRAP or interrupt
|
||||||
|
address_stack_push();
|
||||||
|
m_pc = u16(m_ibr) << 8 | (m_latched_instr & 0x003f);
|
||||||
|
if (BIT(m_latched_instr, 6))
|
||||||
|
set_gie(false);
|
||||||
|
instruction_wait();
|
||||||
|
return T2_NEXT;
|
||||||
|
}
|
||||||
|
else if ((m_latched_instr & 0xf000) == 0xd000)
|
||||||
|
{
|
||||||
|
// JMP, conditional
|
||||||
|
m_source_data = m_latched_instr & 0x00ff;
|
||||||
|
if (get_flag((m_latched_instr & 0x0700) >> 8) == BIT(m_latched_instr, 11))
|
||||||
|
return TX2_JMP;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
instruction_wait();
|
||||||
|
return T2_NEXT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_source_data = read_register(m_latched_instr & 0x001f);
|
||||||
|
instruction_wait();
|
||||||
|
return T2_STORE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// store_result - calculate and store the result
|
||||||
|
// of a register operation
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void dp8344_device::store_result()
|
||||||
|
{
|
||||||
|
switch (m_latched_instr & 0xf000)
|
||||||
|
{
|
||||||
|
case 0x0000:
|
||||||
|
m_source_data = add_nzcv(m_source_data, (m_latched_instr & 0x0ff0) >> 4, false);
|
||||||
|
write_register(m_latched_instr & 0x000f, m_source_data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x2000:
|
||||||
|
m_source_data = sub_nzcv(m_source_data, (m_latched_instr & 0x0ff0) >> 4, false);
|
||||||
|
write_register(m_latched_instr & 0x000f, m_source_data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x3000:
|
||||||
|
(void)sub_nzcv(m_source_data, (m_latched_instr & 0x0ff0) >> 4, false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x4000:
|
||||||
|
m_source_data &= (m_latched_instr & 0x0ff0) >> 4;
|
||||||
|
set_nz(m_source_data);
|
||||||
|
write_register(m_latched_instr & 0x000f, m_source_data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x5000:
|
||||||
|
m_source_data |= (m_latched_instr & 0x0ff0) >> 4;
|
||||||
|
set_nz(m_source_data);
|
||||||
|
write_register(m_latched_instr & 0x000f, m_source_data + ((m_latched_instr & 0x0ff0) >> 4));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x6000:
|
||||||
|
m_source_data ^= (m_latched_instr & 0x0ff0) >> 4;
|
||||||
|
set_nz(m_source_data);
|
||||||
|
write_register(m_latched_instr & 0x000f, m_source_data + ((m_latched_instr & 0x0ff0) >> 4));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x7000:
|
||||||
|
m_source_data &= (m_latched_instr & 0x0ff0) >> 4;
|
||||||
|
set_nz(m_source_data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0xa000:
|
||||||
|
assert((m_latched_instr & 0x0f80) == 0x0e00);
|
||||||
|
m_source_data ^= 0xff;
|
||||||
|
set_nz(m_source_data);
|
||||||
|
write_register(m_latched_instr & 0x001f, m_source_data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0xb000:
|
||||||
|
write_register(m_latched_instr & 0x000f, (m_latched_instr & 0x0ff0) >> 4);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0xc000:
|
||||||
|
switch (m_latched_instr & 0x0f00)
|
||||||
|
{
|
||||||
|
case 0x800:
|
||||||
|
set_carry(BIT(u16(m_source_data) << 1, (m_latched_instr & 0x00e0) >> 5));
|
||||||
|
m_source_data >>= (m_latched_instr & 0x00e0) >> 5;
|
||||||
|
set_nz(m_source_data);
|
||||||
|
write_register(m_latched_instr & 0x001f, m_source_data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x900:
|
||||||
|
set_carry(BIT(m_source_data, (m_latched_instr & 0x00e0) >> 5));
|
||||||
|
m_source_data <<= 8 - ((m_latched_instr & 0x00e0) >> 5);
|
||||||
|
set_nz(m_source_data);
|
||||||
|
write_register(m_latched_instr & 0x001f, m_source_data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0xa00:
|
||||||
|
set_carry(BIT(u16(m_source_data) << 1, (m_latched_instr & 0x00e0) >> 5));
|
||||||
|
m_source_data = rotate_right(m_source_data, (m_latched_instr & 0x00e0) >> 5);
|
||||||
|
set_nz(m_source_data);
|
||||||
|
write_register(m_latched_instr & 0x001f, m_source_data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 0xe000:
|
||||||
|
if (BIT(m_latched_instr, 11))
|
||||||
|
m_source_data = sub_nzcv(m_source_data, read_accumulator(), BIT(m_latched_instr, 10) && BIT(m_ccr, 1));
|
||||||
|
else
|
||||||
|
m_source_data = add_nzcv(m_source_data, read_accumulator(), BIT(m_latched_instr, 10) && BIT(m_ccr, 1));
|
||||||
|
write_register((m_latched_instr & 0x03e0) >> 5, m_source_data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0xf000:
|
||||||
|
switch (m_latched_instr & 0x0c00)
|
||||||
|
{
|
||||||
|
case 0x000:
|
||||||
|
m_source_data &= read_accumulator();
|
||||||
|
set_nz(m_source_data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x400:
|
||||||
|
m_source_data |= read_accumulator();
|
||||||
|
set_nz(m_source_data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x800:
|
||||||
|
m_source_data ^= read_accumulator();
|
||||||
|
set_nz(m_source_data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0xc00:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
write_register((m_latched_instr & 0x03e0) >> 5, m_source_data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// data_write - write one byte to data memory to
|
||||||
|
// finish instruction
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void dp8344_device::data_write()
|
||||||
|
{
|
||||||
|
switch (m_latched_instr & 0xfe00)
|
||||||
|
{
|
||||||
|
case 0xa000: case 0xa200:
|
||||||
|
m_source_data = add_nzcv(m_source_data, read_accumulator(), BIT(m_latched_instr, 9) && BIT(m_ccr, 1));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0xa400: case 0xa600:
|
||||||
|
m_source_data = sub_nzcv(m_source_data, read_accumulator(), BIT(m_latched_instr, 9) && BIT(m_ccr, 1));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0xa800:
|
||||||
|
m_source_data &= read_accumulator();
|
||||||
|
set_nz(m_source_data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0xaa00:
|
||||||
|
m_source_data |= read_accumulator();
|
||||||
|
set_nz(m_source_data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0xac00:
|
||||||
|
m_source_data ^= read_accumulator();
|
||||||
|
set_nz(m_source_data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_data_space->write_byte(m_data_address, m_source_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// data_read - read one byte from data memory
|
||||||
|
// into register to finish instruction
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void dp8344_device::data_read()
|
||||||
|
{
|
||||||
|
write_register(m_latched_instr & ((m_latched_instr & 0xf000) == 0x9000 ? 0x000f : 0x001f), m_data_space->read_byte(m_data_address));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1235,10 +1748,159 @@ std::unique_ptr<util::disasm_interface> dp8344_device::create_disassembler()
|
|||||||
|
|
||||||
void dp8344_device::execute_run()
|
void dp8344_device::execute_run()
|
||||||
{
|
{
|
||||||
debugger_instruction_hook(m_pc);
|
while (m_icount > 0)
|
||||||
|
{
|
||||||
|
switch (m_inst_state)
|
||||||
|
{
|
||||||
|
case T1_DECODE:
|
||||||
|
m_ppc = m_pc;
|
||||||
|
debugger_instruction_hook(m_pc);
|
||||||
|
|
||||||
// TODO: everything
|
if (m_nmi_pending)
|
||||||
m_icount = 0;
|
{
|
||||||
|
m_nmi_pending = false;
|
||||||
|
|
||||||
|
// TRAP to interrupt vector
|
||||||
|
m_latched_instr = 0xcfdc;
|
||||||
|
}
|
||||||
|
else if (BIT(m_acr, 0) && interrupt_active())
|
||||||
|
{
|
||||||
|
// TRAP to interrupt vector
|
||||||
|
m_latched_instr = 0xcfc0 | get_interrupt_vector();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_pc++;
|
||||||
|
|
||||||
|
m_inst_state = decode_instruction();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case T1_START:
|
||||||
|
instruction_wait();
|
||||||
|
m_inst_state = T2_NEXT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case T1_SKIP:
|
||||||
|
m_pc++;
|
||||||
|
instruction_wait();
|
||||||
|
m_inst_state = T2_NEXT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case T1_LJMP:
|
||||||
|
m_pc = m_latched_instr;
|
||||||
|
instruction_wait();
|
||||||
|
m_inst_state = T2_NEXT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case T1_LCALL:
|
||||||
|
address_stack_push();
|
||||||
|
m_pc = m_latched_instr;
|
||||||
|
instruction_wait();
|
||||||
|
m_inst_state = T2_NEXT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TX_READ:
|
||||||
|
latch_address(true);
|
||||||
|
m_inst_state = T2_READ;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TX_WRITE:
|
||||||
|
latch_address(false);
|
||||||
|
m_inst_state = T2_WRITE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TX1_JRMK:
|
||||||
|
m_source_data = rotate_right(m_source_data, (m_latched_instr & 0x00e0) >> 5);
|
||||||
|
m_source_data &= (0xff >> ((m_latched_instr & 0x0700) >> 8)) & 0xfe;
|
||||||
|
m_inst_state = TX2_JMP;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TX1_JMP:
|
||||||
|
m_inst_state = TX2_JMP;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TX2_JMP:
|
||||||
|
m_pc += s8(m_source_data);
|
||||||
|
instruction_wait();
|
||||||
|
m_inst_state = T2_NEXT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TX_CALL:
|
||||||
|
address_stack_push();
|
||||||
|
m_pc += s8(m_source_data);
|
||||||
|
instruction_wait();
|
||||||
|
m_inst_state = T2_NEXT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TX_RET:
|
||||||
|
address_stack_pop((m_latched_instr & 0x0060) >> 5, BIT(m_latched_instr, 4));
|
||||||
|
instruction_wait();
|
||||||
|
m_inst_state = T2_NEXT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case T2_NEXT:
|
||||||
|
if (m_wait_states != 0)
|
||||||
|
m_wait_states--;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
prefetch_instruction();
|
||||||
|
m_inst_state = T1_DECODE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case T2_STORE:
|
||||||
|
if (m_wait_states != 0)
|
||||||
|
m_wait_states--;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
store_result();
|
||||||
|
prefetch_instruction();
|
||||||
|
m_inst_state = T1_DECODE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case T2_READ:
|
||||||
|
if (m_wait_states != 0)
|
||||||
|
m_wait_states--;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data_read();
|
||||||
|
prefetch_instruction();
|
||||||
|
m_inst_state = T1_DECODE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case T2_WRITE:
|
||||||
|
if (m_wait_states != 0)
|
||||||
|
m_wait_states--;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data_write();
|
||||||
|
prefetch_instruction();
|
||||||
|
m_inst_state = T1_DECODE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case T2_ABSOLUTE:
|
||||||
|
if (m_wait_states != 0)
|
||||||
|
m_wait_states--;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((m_latched_instr & 0xfc00) == 0x8c00)
|
||||||
|
{
|
||||||
|
if (BIT(m_source_data, (m_latched_instr & 0x00e0) >> 5) == BIT(m_latched_instr, 8))
|
||||||
|
m_inst_state = BIT(m_latched_instr, 9) ? T1_LCALL : T1_LJMP;
|
||||||
|
else
|
||||||
|
m_inst_state = T1_SKIP;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_inst_state = BIT(m_latched_instr, 7) ? T1_LCALL : T1_LJMP;
|
||||||
|
prefetch_instruction();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_icount--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -82,9 +82,18 @@ protected:
|
|||||||
// device_memory_interface overrides
|
// device_memory_interface overrides
|
||||||
virtual space_config_vector memory_space_config() const override;
|
virtual space_config_vector memory_space_config() const override;
|
||||||
|
|
||||||
|
// device_state_interface overrides
|
||||||
|
virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
enum inst_state : u8 {
|
||||||
|
T1_DECODE, T1_START, T1_SKIP, T1_LJMP, T1_LCALL,
|
||||||
|
TX_READ, TX_WRITE,
|
||||||
|
TX1_JRMK, TX1_JMP, TX2_JMP, TX_CALL, TX_RET,
|
||||||
|
T2_NEXT, T2_STORE, T2_READ, T2_WRITE, T2_ABSOLUTE
|
||||||
|
};
|
||||||
|
|
||||||
// internal functions
|
// internal functions
|
||||||
bool get_flag(unsigned f) const;
|
|
||||||
void set_receiver_interrupt(bool state);
|
void set_receiver_interrupt(bool state);
|
||||||
void set_transmitter_interrupt(bool state);
|
void set_transmitter_interrupt(bool state);
|
||||||
void set_line_turn_around_interrupt(bool state);
|
void set_line_turn_around_interrupt(bool state);
|
||||||
@ -94,9 +103,17 @@ private:
|
|||||||
void set_condition_code(u8 data);
|
void set_condition_code(u8 data);
|
||||||
void set_interrupt_control(u8 data);
|
void set_interrupt_control(u8 data);
|
||||||
void set_auxiliary_control(u8 data);
|
void set_auxiliary_control(u8 data);
|
||||||
|
bool interrupt_active() const;
|
||||||
|
u8 get_interrupt_vector() const;
|
||||||
|
bool get_flag(unsigned f) const;
|
||||||
|
void set_nz(u8 result);
|
||||||
|
void set_carry(bool state);
|
||||||
|
static u8 rotate_right(u8 data, u8 b);
|
||||||
|
u8 add_nzcv(u8 s1, u8 s2, bool carry_in);
|
||||||
|
u8 sub_nzcv(u8 s1, u8 s2, bool carry_in);
|
||||||
u16 get_timer_count();
|
u16 get_timer_count();
|
||||||
void address_stack_push();
|
void address_stack_push();
|
||||||
void address_stack_pop(u8 grf);
|
void address_stack_pop(u8 g, bool rf);
|
||||||
void set_stack_pointer(u8 data);
|
void set_stack_pointer(u8 data);
|
||||||
void data_stack_push(u8 data);
|
void data_stack_push(u8 data);
|
||||||
u8 data_stack_pop();
|
u8 data_stack_pop();
|
||||||
@ -114,6 +131,13 @@ private:
|
|||||||
u8 read_register(unsigned reg);
|
u8 read_register(unsigned reg);
|
||||||
u8 read_accumulator() const;
|
u8 read_accumulator() const;
|
||||||
void write_register(unsigned reg, u8 data);
|
void write_register(unsigned reg, u8 data);
|
||||||
|
void prefetch_instruction();
|
||||||
|
void latch_address(bool rw);
|
||||||
|
void instruction_wait();
|
||||||
|
inst_state decode_instruction();
|
||||||
|
void store_result();
|
||||||
|
void data_write();
|
||||||
|
void data_read();
|
||||||
|
|
||||||
// address spaces
|
// address spaces
|
||||||
const address_space_config m_inst_config;
|
const address_space_config m_inst_config;
|
||||||
@ -130,8 +154,13 @@ private:
|
|||||||
|
|
||||||
// execution state
|
// execution state
|
||||||
u16 m_pc;
|
u16 m_pc;
|
||||||
|
u16 m_ppc;
|
||||||
s32 m_icount;
|
s32 m_icount;
|
||||||
bool m_nmi_pending;
|
bool m_nmi_pending;
|
||||||
|
inst_state m_inst_state;
|
||||||
|
u8 m_wait_states;
|
||||||
|
u8 m_source_data;
|
||||||
|
u16 m_data_address;
|
||||||
|
|
||||||
// control registers
|
// control registers
|
||||||
u8 m_ccr;
|
u8 m_ccr;
|
||||||
@ -152,7 +181,7 @@ private:
|
|||||||
u8 m_gp_alt[4];
|
u8 m_gp_alt[4];
|
||||||
|
|
||||||
// index registers
|
// index registers
|
||||||
PAIR16 m_ir[4];
|
u16 m_ir[4];
|
||||||
|
|
||||||
// timer registers
|
// timer registers
|
||||||
u16 m_tr;
|
u16 m_tr;
|
||||||
|
Loading…
Reference in New Issue
Block a user