mirror of
https://github.com/holub/mame
synced 2025-07-04 17:38:08 +03:00
mn1400: add most opcodes
This commit is contained in:
parent
3226714fff
commit
ce807c207f
@ -56,6 +56,10 @@ protected:
|
|||||||
virtual bool op_has_param(u8 op) override;
|
virtual bool op_has_param(u8 op) override;
|
||||||
|
|
||||||
// opcode helpers
|
// opcode helpers
|
||||||
|
u8 ram_r();
|
||||||
|
void ram_w(u8 data);
|
||||||
|
void set_z(u8 data);
|
||||||
|
void set_cz(u8 data);
|
||||||
void op_illegal();
|
void op_illegal();
|
||||||
|
|
||||||
// opcode handlers
|
// opcode handlers
|
||||||
|
@ -59,12 +59,17 @@ void mn1400_base_device::device_start()
|
|||||||
m_op = 0;
|
m_op = 0;
|
||||||
m_prev_op = 0;
|
m_prev_op = 0;
|
||||||
m_param = 0;
|
m_param = 0;
|
||||||
|
m_ram_address = 0;
|
||||||
|
memset(m_stack, 0, sizeof(m_stack));
|
||||||
|
m_sp = 0;
|
||||||
|
|
||||||
m_a = 0;
|
m_a = 0;
|
||||||
m_x = 0;
|
m_x = 0;
|
||||||
m_y = 0;
|
m_y = 0;
|
||||||
m_status = 0;
|
m_status = 0;
|
||||||
|
m_c = 0;
|
||||||
m_counter = 0;
|
m_counter = 0;
|
||||||
|
m_ec = false;
|
||||||
|
|
||||||
// register for savestates
|
// register for savestates
|
||||||
save_item(NAME(m_pc));
|
save_item(NAME(m_pc));
|
||||||
@ -72,12 +77,17 @@ void mn1400_base_device::device_start()
|
|||||||
save_item(NAME(m_op));
|
save_item(NAME(m_op));
|
||||||
save_item(NAME(m_prev_op));
|
save_item(NAME(m_prev_op));
|
||||||
save_item(NAME(m_param));
|
save_item(NAME(m_param));
|
||||||
|
save_item(NAME(m_ram_address));
|
||||||
|
save_item(NAME(m_stack));
|
||||||
|
save_item(NAME(m_sp));
|
||||||
|
|
||||||
save_item(NAME(m_a));
|
save_item(NAME(m_a));
|
||||||
save_item(NAME(m_x));
|
save_item(NAME(m_x));
|
||||||
save_item(NAME(m_y));
|
save_item(NAME(m_y));
|
||||||
save_item(NAME(m_status));
|
save_item(NAME(m_status));
|
||||||
|
save_item(NAME(m_c));
|
||||||
save_item(NAME(m_counter));
|
save_item(NAME(m_counter));
|
||||||
|
save_item(NAME(m_ec));
|
||||||
|
|
||||||
// register state for debugger
|
// register state for debugger
|
||||||
state_add(STATE_GENPC, "GENPC", m_pc).formatstr("%03X").noshow();
|
state_add(STATE_GENPC, "GENPC", m_pc).formatstr("%03X").noshow();
|
||||||
@ -89,7 +99,7 @@ void mn1400_base_device::device_start()
|
|||||||
state_add(++m_state_count, "A", m_a).formatstr("%01X"); // 2
|
state_add(++m_state_count, "A", m_a).formatstr("%01X"); // 2
|
||||||
state_add(++m_state_count, "X", m_x).formatstr("%01X"); // 3
|
state_add(++m_state_count, "X", m_x).formatstr("%01X"); // 3
|
||||||
state_add(++m_state_count, "Y", m_y).formatstr("%01X"); // 4
|
state_add(++m_state_count, "Y", m_y).formatstr("%01X"); // 4
|
||||||
state_add(++m_state_count, "CNT", m_y).formatstr("%02X"); // 5
|
state_add(++m_state_count, "CNT", m_counter).formatstr("%02X"); // 5
|
||||||
|
|
||||||
set_icountptr(m_icount);
|
set_icountptr(m_icount);
|
||||||
}
|
}
|
||||||
@ -125,7 +135,10 @@ void mn1400_base_device::device_reset()
|
|||||||
{
|
{
|
||||||
m_pc = m_prev_pc = 0;
|
m_pc = m_prev_pc = 0;
|
||||||
m_op = m_prev_op = 0;
|
m_op = m_prev_op = 0;
|
||||||
m_param = 0;
|
m_status = 0;
|
||||||
|
|
||||||
|
// clear output ports
|
||||||
|
m_c = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -190,6 +203,7 @@ void mn1400_base_device::execute_run()
|
|||||||
cycle();
|
cycle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_ram_address = (m_x << 4 | m_y) & m_datamask;
|
||||||
execute_one();
|
execute_one();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,14 +70,19 @@ protected:
|
|||||||
u8 m_op;
|
u8 m_op;
|
||||||
u8 m_prev_op;
|
u8 m_prev_op;
|
||||||
u8 m_param;
|
u8 m_param;
|
||||||
|
u8 m_ram_address;
|
||||||
|
u16 m_stack[2];
|
||||||
|
u8 m_sp;
|
||||||
|
|
||||||
u8 m_a;
|
u8 m_a;
|
||||||
u8 m_x;
|
u8 m_x;
|
||||||
u8 m_y;
|
u8 m_y;
|
||||||
u8 m_status;
|
u8 m_status;
|
||||||
|
u16 m_c;
|
||||||
u8 m_counter;
|
u8 m_counter;
|
||||||
|
bool m_ec;
|
||||||
|
|
||||||
enum
|
enum : u8
|
||||||
{
|
{
|
||||||
FLAG_Z = 1,
|
FLAG_Z = 1,
|
||||||
FLAG_C = 2,
|
FLAG_C = 2,
|
||||||
|
@ -9,6 +9,34 @@
|
|||||||
|
|
||||||
// internal helpers
|
// internal helpers
|
||||||
|
|
||||||
|
u8 mn1400_cpu_device::ram_r()
|
||||||
|
{
|
||||||
|
return m_data->read_byte(m_ram_address) & 0xf;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mn1400_cpu_device::ram_w(u8 data)
|
||||||
|
{
|
||||||
|
m_data->write_byte(m_ram_address, data & 0xf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mn1400_cpu_device::set_z(u8 data)
|
||||||
|
{
|
||||||
|
if ((data & 0xf) == 0)
|
||||||
|
m_status |= FLAG_Z;
|
||||||
|
else
|
||||||
|
m_status &= ~FLAG_Z;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mn1400_cpu_device::set_cz(u8 data)
|
||||||
|
{
|
||||||
|
set_z(data);
|
||||||
|
|
||||||
|
if (data & 0x10)
|
||||||
|
m_status |= FLAG_C;
|
||||||
|
else
|
||||||
|
m_status &= ~FLAG_C;
|
||||||
|
}
|
||||||
|
|
||||||
void mn1400_cpu_device::op_illegal()
|
void mn1400_cpu_device::op_illegal()
|
||||||
{
|
{
|
||||||
logerror("unknown opcode $%02X at $%03X\n", m_op, m_prev_pc);
|
logerror("unknown opcode $%02X at $%03X\n", m_op, m_prev_pc);
|
||||||
@ -22,91 +50,124 @@ void mn1400_cpu_device::op_illegal()
|
|||||||
void mn1400_cpu_device::op_l()
|
void mn1400_cpu_device::op_l()
|
||||||
{
|
{
|
||||||
// L: load A from memory
|
// L: load A from memory
|
||||||
|
m_a = ram_r();
|
||||||
|
set_z(m_a);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mn1400_cpu_device::op_ld()
|
void mn1400_cpu_device::op_ld()
|
||||||
{
|
{
|
||||||
// LD: load A direct from memory
|
// LD: load A direct from memory
|
||||||
|
m_ram_address = m_op & 3;
|
||||||
|
op_l();
|
||||||
}
|
}
|
||||||
|
|
||||||
void mn1400_cpu_device::op_li()
|
void mn1400_cpu_device::op_li()
|
||||||
{
|
{
|
||||||
// LI: load A immediate
|
// LI: load A immediate
|
||||||
|
m_a = m_op & 0xf;
|
||||||
|
set_z(m_a);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mn1400_cpu_device::op_lic()
|
void mn1400_cpu_device::op_lic()
|
||||||
{
|
{
|
||||||
// LIC: L + increment Y
|
// LIC: L + increment Y
|
||||||
|
cycle();
|
||||||
|
op_l();
|
||||||
|
op_icy();
|
||||||
}
|
}
|
||||||
|
|
||||||
void mn1400_cpu_device::op_ldc()
|
void mn1400_cpu_device::op_ldc()
|
||||||
{
|
{
|
||||||
// LDC: L + decrement Y
|
// LDC: L + decrement Y
|
||||||
|
cycle();
|
||||||
|
op_l();
|
||||||
|
op_dcy();
|
||||||
}
|
}
|
||||||
|
|
||||||
void mn1400_cpu_device::op_st()
|
void mn1400_cpu_device::op_st()
|
||||||
{
|
{
|
||||||
// S: store A into memory
|
// S: store A into memory
|
||||||
|
ram_w(m_a);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mn1400_cpu_device::op_std()
|
void mn1400_cpu_device::op_std()
|
||||||
{
|
{
|
||||||
// STD: store A direct into memory
|
// STD: store A direct into memory
|
||||||
|
m_ram_address = m_op & 3;
|
||||||
|
op_st();
|
||||||
}
|
}
|
||||||
|
|
||||||
void mn1400_cpu_device::op_stic()
|
void mn1400_cpu_device::op_stic()
|
||||||
{
|
{
|
||||||
// STIC: S + increment Y
|
// STIC: ST + increment Y
|
||||||
|
cycle();
|
||||||
|
op_st();
|
||||||
|
op_icy();
|
||||||
}
|
}
|
||||||
|
|
||||||
void mn1400_cpu_device::op_stdc()
|
void mn1400_cpu_device::op_stdc()
|
||||||
{
|
{
|
||||||
// STDC: S + decrement Y
|
// STDC: ST + decrement Y
|
||||||
|
cycle();
|
||||||
|
op_st();
|
||||||
|
op_dcy();
|
||||||
}
|
}
|
||||||
|
|
||||||
void mn1400_cpu_device::op_lx()
|
void mn1400_cpu_device::op_lx()
|
||||||
{
|
{
|
||||||
// LX: load X immediate
|
// LX: load X immediate
|
||||||
|
m_x = m_op & 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mn1400_cpu_device::op_ly()
|
void mn1400_cpu_device::op_ly()
|
||||||
{
|
{
|
||||||
// LY: load Y immediate
|
// LY: load Y immediate
|
||||||
|
m_y = m_op & 0xf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mn1400_cpu_device::op_tax()
|
void mn1400_cpu_device::op_tax()
|
||||||
{
|
{
|
||||||
// TAX: transfer A to X
|
// TAX: transfer A to X
|
||||||
|
m_x = m_a;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mn1400_cpu_device::op_tay()
|
void mn1400_cpu_device::op_tay()
|
||||||
{
|
{
|
||||||
// TAY: transfer A to Y
|
// TAY: transfer A to Y
|
||||||
|
m_y = m_a;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mn1400_cpu_device::op_tya()
|
void mn1400_cpu_device::op_tya()
|
||||||
{
|
{
|
||||||
// TYA: transfer Y to A
|
// TYA: transfer Y to A
|
||||||
|
m_a = m_y;
|
||||||
|
set_z(m_a);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mn1400_cpu_device::op_tacu()
|
void mn1400_cpu_device::op_tacu()
|
||||||
{
|
{
|
||||||
// TACU: transfer A to counter upper
|
// TACU: transfer A to counter upper
|
||||||
|
m_counter = (m_counter & 0xf) | (m_a << 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mn1400_cpu_device::op_tacl()
|
void mn1400_cpu_device::op_tacl()
|
||||||
{
|
{
|
||||||
// TACL: transfer A to counter lower
|
// TACL: transfer A to counter lower
|
||||||
|
m_counter = (m_counter & 0xf0) | m_a;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mn1400_cpu_device::op_tcau()
|
void mn1400_cpu_device::op_tcau()
|
||||||
{
|
{
|
||||||
// TCAU: transfer counter upper to A
|
// TCAU: transfer counter upper to A
|
||||||
|
m_a = m_counter >> 4;
|
||||||
|
set_z(m_a);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mn1400_cpu_device::op_tcal()
|
void mn1400_cpu_device::op_tcal()
|
||||||
{
|
{
|
||||||
// TCAL: transfer counter lower to A
|
// TCAL: transfer counter lower to A
|
||||||
|
m_a = m_counter & 0xf;
|
||||||
|
set_z(m_a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -120,91 +181,131 @@ void mn1400_cpu_device::op_nop()
|
|||||||
void mn1400_cpu_device::op_and()
|
void mn1400_cpu_device::op_and()
|
||||||
{
|
{
|
||||||
// AND: AND A with memory
|
// AND: AND A with memory
|
||||||
|
m_a &= ram_r();
|
||||||
|
set_z(m_a);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mn1400_cpu_device::op_andi()
|
void mn1400_cpu_device::op_andi()
|
||||||
{
|
{
|
||||||
// ANDI: AND A with immediate
|
// ANDI: AND A with immediate
|
||||||
|
m_a &= (m_op & 0xf);
|
||||||
|
set_z(m_a);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mn1400_cpu_device::op_or()
|
void mn1400_cpu_device::op_or()
|
||||||
{
|
{
|
||||||
// OR: OR A with memory
|
// OR: OR A with memory
|
||||||
|
m_a |= ram_r();
|
||||||
|
set_z(m_a);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mn1400_cpu_device::op_xor()
|
void mn1400_cpu_device::op_xor()
|
||||||
{
|
{
|
||||||
// XOR: XOR A with memory
|
// XOR: XOR A with memory
|
||||||
|
m_a ^= ram_r();
|
||||||
|
set_z(m_a);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mn1400_cpu_device::op_a()
|
void mn1400_cpu_device::op_a()
|
||||||
{
|
{
|
||||||
// A: add memory + carry to A
|
// A: add memory + carry to A
|
||||||
|
u8 c = (m_status & FLAG_C) ? 1 : 0;
|
||||||
|
m_a += ram_r() + c;
|
||||||
|
set_cz(m_a);
|
||||||
|
m_a &= 0xf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mn1400_cpu_device::op_ai()
|
void mn1400_cpu_device::op_ai()
|
||||||
{
|
{
|
||||||
// AI: add immediate to A
|
// AI: add immediate to A
|
||||||
|
m_a += m_op & 0xf;
|
||||||
|
set_cz(m_a);
|
||||||
|
m_a &= 0xf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mn1400_cpu_device::op_cpl()
|
void mn1400_cpu_device::op_cpl()
|
||||||
{
|
{
|
||||||
// CPL: complement A
|
// CPL: complement A
|
||||||
|
m_a ^= 0xf;
|
||||||
|
set_z(m_a);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mn1400_cpu_device::op_c()
|
void mn1400_cpu_device::op_c()
|
||||||
{
|
{
|
||||||
// C: compare A to memory
|
// C: compare A with memory
|
||||||
|
set_cz((m_a ^ 0xf) + ram_r() + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mn1400_cpu_device::op_ci()
|
void mn1400_cpu_device::op_ci()
|
||||||
{
|
{
|
||||||
// CI: compare A to immediate
|
// CI: compare A with immediate
|
||||||
|
set_cz(m_a + (~m_op & 0xf) + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mn1400_cpu_device::op_cy()
|
void mn1400_cpu_device::op_cy()
|
||||||
{
|
{
|
||||||
// CY: compare A to Y
|
// CY: compare A with Y
|
||||||
|
set_z(m_y ^ (m_op & 0xf));
|
||||||
}
|
}
|
||||||
|
|
||||||
void mn1400_cpu_device::op_sl()
|
void mn1400_cpu_device::op_sl()
|
||||||
{
|
{
|
||||||
// SL: shift left A
|
// SL: shift left A
|
||||||
|
m_a += m_a;
|
||||||
|
set_cz(m_a);
|
||||||
|
m_a &= 0xf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mn1400_cpu_device::op_icy()
|
void mn1400_cpu_device::op_icy()
|
||||||
{
|
{
|
||||||
// ICY: increment Y
|
// ICY: increment Y
|
||||||
|
m_y = (m_y + 1) & 0xf;
|
||||||
|
set_z(m_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mn1400_cpu_device::op_dcy()
|
void mn1400_cpu_device::op_dcy()
|
||||||
{
|
{
|
||||||
// DCY: decrement Y
|
// DCY: decrement Y
|
||||||
|
m_y = (m_y - 1) & 0xf;
|
||||||
|
set_z(m_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mn1400_cpu_device::op_icm()
|
void mn1400_cpu_device::op_icm()
|
||||||
{
|
{
|
||||||
// ICM: increment memory
|
// ICM: increment memory
|
||||||
|
cycle();
|
||||||
|
u8 temp = ram_r() + 1;
|
||||||
|
ram_w(temp);
|
||||||
|
set_cz(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mn1400_cpu_device::op_dcm()
|
void mn1400_cpu_device::op_dcm()
|
||||||
{
|
{
|
||||||
// DCM: decrement memory
|
// DCM: decrement memory
|
||||||
|
cycle();
|
||||||
|
u8 temp = ram_r() - 1;
|
||||||
|
ram_w(temp);
|
||||||
|
set_cz(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mn1400_cpu_device::op_sm()
|
void mn1400_cpu_device::op_sm()
|
||||||
{
|
{
|
||||||
// SM: set memory bits
|
// SM: set memory bits
|
||||||
|
cycle();
|
||||||
|
ram_w(ram_r() | (m_op & 0xf));
|
||||||
}
|
}
|
||||||
|
|
||||||
void mn1400_cpu_device::op_rm()
|
void mn1400_cpu_device::op_rm()
|
||||||
{
|
{
|
||||||
// RM: reset memory bits
|
// RM: reset memory bits
|
||||||
|
cycle();
|
||||||
|
ram_w(ram_r() & (~m_op & 0xf));
|
||||||
}
|
}
|
||||||
|
|
||||||
void mn1400_cpu_device::op_tb()
|
void mn1400_cpu_device::op_tb()
|
||||||
{
|
{
|
||||||
// TB: test A bits
|
// TB: test A bits
|
||||||
|
set_z(m_a & (m_op & 0xf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -261,21 +362,25 @@ void mn1400_cpu_device::op_cco()
|
|||||||
void mn1400_cpu_device::op_rc()
|
void mn1400_cpu_device::op_rc()
|
||||||
{
|
{
|
||||||
// RC: reset CF
|
// RC: reset CF
|
||||||
|
m_status &= ~FLAG_C;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mn1400_cpu_device::op_rp()
|
void mn1400_cpu_device::op_rp()
|
||||||
{
|
{
|
||||||
// RP: reset PS
|
// RP: reset PS
|
||||||
|
m_status &= ~FLAG_P;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mn1400_cpu_device::op_sc()
|
void mn1400_cpu_device::op_sc()
|
||||||
{
|
{
|
||||||
// SC: set CF
|
// SC: set CF
|
||||||
|
m_status |= FLAG_C;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mn1400_cpu_device::op_sp()
|
void mn1400_cpu_device::op_sp()
|
||||||
{
|
{
|
||||||
// SP: set PS
|
// SP: set PS
|
||||||
|
m_status |= FLAG_P;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mn1400_cpu_device::op_bs01()
|
void mn1400_cpu_device::op_bs01()
|
||||||
@ -286,29 +391,40 @@ void mn1400_cpu_device::op_bs01()
|
|||||||
void mn1400_cpu_device::op_bpcz()
|
void mn1400_cpu_device::op_bpcz()
|
||||||
{
|
{
|
||||||
// B(N)P/C/Z: branch on status
|
// B(N)P/C/Z: branch on status
|
||||||
|
u8 mask = m_status & (m_op >> 1 & 7);
|
||||||
|
if (bool(m_op & 1) == bool(mask))
|
||||||
|
m_pc = (m_prev_pc & ~0xff) | m_param;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mn1400_cpu_device::op_jmp()
|
void mn1400_cpu_device::op_jmp()
|
||||||
{
|
{
|
||||||
// JMP: jump
|
// JMP: jump
|
||||||
|
m_pc = ((m_op & 0xf) << 8 | m_param) & m_prgmask;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mn1400_cpu_device::op_cal()
|
void mn1400_cpu_device::op_cal()
|
||||||
{
|
{
|
||||||
// CAL: call subroutine
|
// CAL: call subroutine
|
||||||
|
m_stack[m_sp] = m_pc;
|
||||||
|
m_sp = (m_sp + 1) % m_stack_levels;
|
||||||
|
op_jmp();
|
||||||
}
|
}
|
||||||
|
|
||||||
void mn1400_cpu_device::op_ret()
|
void mn1400_cpu_device::op_ret()
|
||||||
{
|
{
|
||||||
// RET: return from subroutine
|
// RET: return from subroutine
|
||||||
|
m_sp = (m_stack_levels + m_sp - 1) % m_stack_levels;
|
||||||
|
m_pc = m_stack[m_sp] & m_prgmask;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mn1400_cpu_device::op_ec()
|
void mn1400_cpu_device::op_ec()
|
||||||
{
|
{
|
||||||
// EC: enable counter
|
// EC: enable counter
|
||||||
|
m_ec = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mn1400_cpu_device::op_dc()
|
void mn1400_cpu_device::op_dc()
|
||||||
{
|
{
|
||||||
// DC: disable counter
|
// DC: disable counter
|
||||||
|
m_ec = false;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user