mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +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;
|
||||
|
||||
// opcode helpers
|
||||
u8 ram_r();
|
||||
void ram_w(u8 data);
|
||||
void set_z(u8 data);
|
||||
void set_cz(u8 data);
|
||||
void op_illegal();
|
||||
|
||||
// opcode handlers
|
||||
|
@ -59,12 +59,17 @@ void mn1400_base_device::device_start()
|
||||
m_op = 0;
|
||||
m_prev_op = 0;
|
||||
m_param = 0;
|
||||
m_ram_address = 0;
|
||||
memset(m_stack, 0, sizeof(m_stack));
|
||||
m_sp = 0;
|
||||
|
||||
m_a = 0;
|
||||
m_x = 0;
|
||||
m_y = 0;
|
||||
m_status = 0;
|
||||
m_c = 0;
|
||||
m_counter = 0;
|
||||
m_ec = false;
|
||||
|
||||
// register for savestates
|
||||
save_item(NAME(m_pc));
|
||||
@ -72,12 +77,17 @@ void mn1400_base_device::device_start()
|
||||
save_item(NAME(m_op));
|
||||
save_item(NAME(m_prev_op));
|
||||
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_x));
|
||||
save_item(NAME(m_y));
|
||||
save_item(NAME(m_status));
|
||||
save_item(NAME(m_c));
|
||||
save_item(NAME(m_counter));
|
||||
save_item(NAME(m_ec));
|
||||
|
||||
// register state for debugger
|
||||
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, "X", m_x).formatstr("%01X"); // 3
|
||||
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);
|
||||
}
|
||||
@ -125,7 +135,10 @@ void mn1400_base_device::device_reset()
|
||||
{
|
||||
m_pc = m_prev_pc = 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();
|
||||
}
|
||||
|
||||
m_ram_address = (m_x << 4 | m_y) & m_datamask;
|
||||
execute_one();
|
||||
}
|
||||
}
|
||||
|
@ -70,14 +70,19 @@ protected:
|
||||
u8 m_op;
|
||||
u8 m_prev_op;
|
||||
u8 m_param;
|
||||
u8 m_ram_address;
|
||||
u16 m_stack[2];
|
||||
u8 m_sp;
|
||||
|
||||
u8 m_a;
|
||||
u8 m_x;
|
||||
u8 m_y;
|
||||
u8 m_status;
|
||||
u16 m_c;
|
||||
u8 m_counter;
|
||||
bool m_ec;
|
||||
|
||||
enum
|
||||
enum : u8
|
||||
{
|
||||
FLAG_Z = 1,
|
||||
FLAG_C = 2,
|
||||
|
@ -9,6 +9,34 @@
|
||||
|
||||
// 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()
|
||||
{
|
||||
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()
|
||||
{
|
||||
// L: load A from memory
|
||||
m_a = ram_r();
|
||||
set_z(m_a);
|
||||
}
|
||||
|
||||
void mn1400_cpu_device::op_ld()
|
||||
{
|
||||
// LD: load A direct from memory
|
||||
m_ram_address = m_op & 3;
|
||||
op_l();
|
||||
}
|
||||
|
||||
void mn1400_cpu_device::op_li()
|
||||
{
|
||||
// LI: load A immediate
|
||||
m_a = m_op & 0xf;
|
||||
set_z(m_a);
|
||||
}
|
||||
|
||||
void mn1400_cpu_device::op_lic()
|
||||
{
|
||||
// LIC: L + increment Y
|
||||
cycle();
|
||||
op_l();
|
||||
op_icy();
|
||||
}
|
||||
|
||||
void mn1400_cpu_device::op_ldc()
|
||||
{
|
||||
// LDC: L + decrement Y
|
||||
cycle();
|
||||
op_l();
|
||||
op_dcy();
|
||||
}
|
||||
|
||||
void mn1400_cpu_device::op_st()
|
||||
{
|
||||
// S: store A into memory
|
||||
ram_w(m_a);
|
||||
}
|
||||
|
||||
void mn1400_cpu_device::op_std()
|
||||
{
|
||||
// STD: store A direct into memory
|
||||
m_ram_address = m_op & 3;
|
||||
op_st();
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
// STDC: S + decrement Y
|
||||
// STDC: ST + decrement Y
|
||||
cycle();
|
||||
op_st();
|
||||
op_dcy();
|
||||
}
|
||||
|
||||
void mn1400_cpu_device::op_lx()
|
||||
{
|
||||
// LX: load X immediate
|
||||
m_x = m_op & 7;
|
||||
}
|
||||
|
||||
void mn1400_cpu_device::op_ly()
|
||||
{
|
||||
// LY: load Y immediate
|
||||
m_y = m_op & 0xf;
|
||||
}
|
||||
|
||||
void mn1400_cpu_device::op_tax()
|
||||
{
|
||||
// TAX: transfer A to X
|
||||
m_x = m_a;
|
||||
}
|
||||
|
||||
void mn1400_cpu_device::op_tay()
|
||||
{
|
||||
// TAY: transfer A to Y
|
||||
m_y = m_a;
|
||||
}
|
||||
|
||||
void mn1400_cpu_device::op_tya()
|
||||
{
|
||||
// TYA: transfer Y to A
|
||||
m_a = m_y;
|
||||
set_z(m_a);
|
||||
}
|
||||
|
||||
void mn1400_cpu_device::op_tacu()
|
||||
{
|
||||
// TACU: transfer A to counter upper
|
||||
m_counter = (m_counter & 0xf) | (m_a << 4);
|
||||
}
|
||||
|
||||
void mn1400_cpu_device::op_tacl()
|
||||
{
|
||||
// TACL: transfer A to counter lower
|
||||
m_counter = (m_counter & 0xf0) | m_a;
|
||||
}
|
||||
|
||||
void mn1400_cpu_device::op_tcau()
|
||||
{
|
||||
// TCAU: transfer counter upper to A
|
||||
m_a = m_counter >> 4;
|
||||
set_z(m_a);
|
||||
}
|
||||
|
||||
void mn1400_cpu_device::op_tcal()
|
||||
{
|
||||
// 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()
|
||||
{
|
||||
// AND: AND A with memory
|
||||
m_a &= ram_r();
|
||||
set_z(m_a);
|
||||
}
|
||||
|
||||
void mn1400_cpu_device::op_andi()
|
||||
{
|
||||
// ANDI: AND A with immediate
|
||||
m_a &= (m_op & 0xf);
|
||||
set_z(m_a);
|
||||
}
|
||||
|
||||
void mn1400_cpu_device::op_or()
|
||||
{
|
||||
// OR: OR A with memory
|
||||
m_a |= ram_r();
|
||||
set_z(m_a);
|
||||
}
|
||||
|
||||
void mn1400_cpu_device::op_xor()
|
||||
{
|
||||
// XOR: XOR A with memory
|
||||
m_a ^= ram_r();
|
||||
set_z(m_a);
|
||||
}
|
||||
|
||||
void mn1400_cpu_device::op_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()
|
||||
{
|
||||
// AI: add immediate to A
|
||||
m_a += m_op & 0xf;
|
||||
set_cz(m_a);
|
||||
m_a &= 0xf;
|
||||
}
|
||||
|
||||
void mn1400_cpu_device::op_cpl()
|
||||
{
|
||||
// CPL: complement A
|
||||
m_a ^= 0xf;
|
||||
set_z(m_a);
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
// CI: compare A to immediate
|
||||
// CI: compare A with immediate
|
||||
set_cz(m_a + (~m_op & 0xf) + 1);
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
// SL: shift left A
|
||||
m_a += m_a;
|
||||
set_cz(m_a);
|
||||
m_a &= 0xf;
|
||||
}
|
||||
|
||||
void mn1400_cpu_device::op_icy()
|
||||
{
|
||||
// ICY: increment Y
|
||||
m_y = (m_y + 1) & 0xf;
|
||||
set_z(m_y);
|
||||
}
|
||||
|
||||
void mn1400_cpu_device::op_dcy()
|
||||
{
|
||||
// DCY: decrement Y
|
||||
m_y = (m_y - 1) & 0xf;
|
||||
set_z(m_y);
|
||||
}
|
||||
|
||||
void mn1400_cpu_device::op_icm()
|
||||
{
|
||||
// ICM: increment memory
|
||||
cycle();
|
||||
u8 temp = ram_r() + 1;
|
||||
ram_w(temp);
|
||||
set_cz(temp);
|
||||
}
|
||||
|
||||
void mn1400_cpu_device::op_dcm()
|
||||
{
|
||||
// DCM: decrement memory
|
||||
cycle();
|
||||
u8 temp = ram_r() - 1;
|
||||
ram_w(temp);
|
||||
set_cz(temp);
|
||||
}
|
||||
|
||||
void mn1400_cpu_device::op_sm()
|
||||
{
|
||||
// SM: set memory bits
|
||||
cycle();
|
||||
ram_w(ram_r() | (m_op & 0xf));
|
||||
}
|
||||
|
||||
void mn1400_cpu_device::op_rm()
|
||||
{
|
||||
// RM: reset memory bits
|
||||
cycle();
|
||||
ram_w(ram_r() & (~m_op & 0xf));
|
||||
}
|
||||
|
||||
void mn1400_cpu_device::op_tb()
|
||||
{
|
||||
// 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()
|
||||
{
|
||||
// RC: reset CF
|
||||
m_status &= ~FLAG_C;
|
||||
}
|
||||
|
||||
void mn1400_cpu_device::op_rp()
|
||||
{
|
||||
// RP: reset PS
|
||||
m_status &= ~FLAG_P;
|
||||
}
|
||||
|
||||
void mn1400_cpu_device::op_sc()
|
||||
{
|
||||
// SC: set CF
|
||||
m_status |= FLAG_C;
|
||||
}
|
||||
|
||||
void mn1400_cpu_device::op_sp()
|
||||
{
|
||||
// SP: set PS
|
||||
m_status |= FLAG_P;
|
||||
}
|
||||
|
||||
void mn1400_cpu_device::op_bs01()
|
||||
@ -286,29 +391,40 @@ void mn1400_cpu_device::op_bs01()
|
||||
void mn1400_cpu_device::op_bpcz()
|
||||
{
|
||||
// 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()
|
||||
{
|
||||
// JMP: jump
|
||||
m_pc = ((m_op & 0xf) << 8 | m_param) & m_prgmask;
|
||||
}
|
||||
|
||||
void mn1400_cpu_device::op_cal()
|
||||
{
|
||||
// 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()
|
||||
{
|
||||
// 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()
|
||||
{
|
||||
// EC: enable counter
|
||||
m_ec = true;
|
||||
}
|
||||
|
||||
void mn1400_cpu_device::op_dc()
|
||||
{
|
||||
// DC: disable counter
|
||||
m_ec = false;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user