summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author hap <happppp@users.noreply.github.com>2015-01-30 19:28:31 +0100
committer hap <happppp@users.noreply.github.com>2015-01-30 19:28:31 +0100
commit409448ef65d64986a662734195666f18385faf25 (patch)
treecf3e91190cf15ee457cbd9114cb998592d26eca4
parente94979bac5dc7faac032f0b7fe975b9ef527921b (diff)
added most straightforward opcodes
-rw-r--r--src/emu/cpu/amis2000/amis2000.c18
-rw-r--r--src/emu/cpu/amis2000/amis2000.h10
-rw-r--r--src/emu/cpu/amis2000/amis2000op.inc120
3 files changed, 109 insertions, 39 deletions
diff --git a/src/emu/cpu/amis2000/amis2000.c b/src/emu/cpu/amis2000/amis2000.c
index 1d0f923a59e..b194cdbad15 100644
--- a/src/emu/cpu/amis2000/amis2000.c
+++ b/src/emu/cpu/amis2000/amis2000.c
@@ -114,7 +114,7 @@ offs_t amis2000_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8
enum
{
S2000_PC=1, S2000_BL, S2000_BU,
- S2000_ACC, S2000_E
+ S2000_ACC, S2000_E, S2000_CARRY
};
void amis2000_device::device_start()
@@ -134,22 +134,30 @@ void amis2000_device::device_start()
// zerofill
memset(m_callstack, 0, sizeof(m_callstack));
m_pc = 0;
+ m_skip = false;
m_op = 0;
m_f = 0;
+ m_carry = 0;
m_bl = 0;
m_bu = 0;
m_acc = 0;
m_e = 0;
+ m_i = 0;
+ m_k = 0;
// register for savestates
save_item(NAME(m_callstack));
save_item(NAME(m_pc));
+ save_item(NAME(m_skip));
save_item(NAME(m_op));
save_item(NAME(m_f));
+ save_item(NAME(m_carry));
save_item(NAME(m_bl));
save_item(NAME(m_bu));
save_item(NAME(m_acc));
save_item(NAME(m_e));
+ save_item(NAME(m_i));
+ save_item(NAME(m_k));
// register state for debugger
state_add(S2000_PC, "PC", m_pc ).formatstr("%04X");
@@ -157,6 +165,7 @@ void amis2000_device::device_start()
state_add(S2000_BU, "BU", m_bu ).formatstr("%01X");
state_add(S2000_ACC, "ACC", m_acc ).formatstr("%01X");
state_add(S2000_E, "E", m_e ).formatstr("%01X");
+ state_add(S2000_CARRY, "CARRY", m_carry ).formatstr("%01X");
state_add(STATE_GENPC, "curpc", m_pc).formatstr("%04X").noshow();
state_add(STATE_GENFLAGS, "GENFLAGS", m_f).formatstr("%6s").noshow();
@@ -192,6 +201,13 @@ void amis2000_device::execute_run()
debugger_instruction_hook(this, m_pc);
m_op = m_program->read_byte(m_pc);
m_pc = (m_pc + 1) & 0x1fff;
+
+ if (m_skip)
+ {
+ // always skip over PP prefix
+ m_skip = ((m_op & 0xf0) == 0x60);
+ continue;
+ }
switch (m_op & 0xf0)
{
diff --git a/src/emu/cpu/amis2000/amis2000.h b/src/emu/cpu/amis2000/amis2000.h
index 5cf7761c27e..7e34ed560d0 100644
--- a/src/emu/cpu/amis2000/amis2000.h
+++ b/src/emu/cpu/amis2000/amis2000.h
@@ -78,12 +78,16 @@ protected:
UINT16 m_callstack[5]; // max 5
UINT16 m_pc;
+ bool m_skip;
UINT8 m_op;
UINT8 m_f; // generic flags: 2 on 2000/2150, 6 on 2200/2400
+ UINT8 m_carry; // carry flag
UINT8 m_bl; // 4-bit ram index x
UINT8 m_bu; // 2/3-bit ram index y
- UINT8 m_acc;
- UINT8 m_e;
+ UINT8 m_acc; // 4-bit accumulator
+ UINT8 m_e; // 4-bit generic register
+ UINT8 m_i; // 4-bit i-pins latch
+ UINT8 m_k; // 4-bit k-pins latch
devcb_read8 m_read_k;
devcb_read8 m_read_i;
@@ -93,6 +97,8 @@ protected:
int m_icount;
+ UINT8 ram_r();
+ void ram_w(UINT8 data);
void op_illegal();
void op_lai();
diff --git a/src/emu/cpu/amis2000/amis2000op.inc b/src/emu/cpu/amis2000/amis2000op.inc
index a0b219dbd72..173f0531ae1 100644
--- a/src/emu/cpu/amis2000/amis2000op.inc
+++ b/src/emu/cpu/amis2000/amis2000op.inc
@@ -2,6 +2,18 @@
// internal helpers
+UINT8 amis2000_device::ram_r()
+{
+ UINT16 address = m_bu << m_bu_bits | m_bl;
+ return m_data->read_byte(address) & 0xf;
+}
+
+void amis2000_device::ram_w(UINT8 data)
+{
+ UINT16 address = m_bu << m_bu_bits | m_bl;
+ m_data->write_byte(address, data & 0xf);
+}
+
void amis2000_device::op_illegal()
{
logerror("%s unknown opcode $%02X at $%04X\n", tag(), m_op, m_pc);
@@ -13,61 +25,78 @@ void amis2000_device::op_illegal()
void amis2000_device::op_lai()
{
// LAI X: load ACC with X, select I and K inputs
- op_illegal();
+ UINT8 param = m_op & 0x0f;
+ m_acc = param;
+ m_i = m_read_i(0, 0xff) & param;
+ m_k = m_read_k(0, 0xff) & param;
}
void amis2000_device::op_lab()
{
// LAB: load ACC with BL
- op_illegal();
+ m_acc = m_bl;
}
void amis2000_device::op_lae()
{
// LAE: load ACC with E
- op_illegal();
+ m_acc = m_e;
}
void amis2000_device::op_xab()
{
// XAB: exchange ACC with BL
- op_illegal();
+ UINT8 old_acc = m_acc;
+ m_acc = m_bl;
+ m_bl = old_acc;
}
void amis2000_device::op_xabu()
{
// XABU: exchange ACC with BU
- op_illegal();
+ UINT8 old_acc = m_acc;
+ m_acc = (m_acc & ~m_bu_mask) | (m_bu & m_bu_mask);
+ m_bu = old_acc & m_bu_mask;
}
void amis2000_device::op_xae()
{
// XAE: exchange ACC with E
- op_illegal();
+ UINT8 old_acc = m_acc;
+ m_acc = m_e;
+ m_e = old_acc;
}
void amis2000_device::op_lbe()
{
// LBE Y: load BU with Y, load BL with E
- op_illegal();
+ UINT8 param = m_op & 0x03;
+ m_bu = param & m_bu_mask;
+ m_bl = m_e;
}
void amis2000_device::op_lbep()
{
// LBEP Y: load BU with Y, load BL with E+1
- op_illegal();
+ UINT8 param = m_op & 0x03;
+ m_bu = param & m_bu_mask;
+ m_bl = m_e + 1;
}
void amis2000_device::op_lbz()
{
// LBZ Y: load BU with Y, load BL with 0
- op_illegal();
+ UINT8 param = m_op & 0x03;
+ m_bu = param & m_bu_mask;
+ m_bl = 0;
}
void amis2000_device::op_lbf()
{
// LBF Y: load BU with Y, load BL with 15
- op_illegal();
+ UINT8 param = m_op & 0x03;
+ m_bu = param & m_bu_mask;
+ m_bl = 0xf;
}
@@ -76,37 +105,49 @@ void amis2000_device::op_lbf()
void amis2000_device::op_lam()
{
// LAM _Y: load ACC with RAM, xor BU with _Y
- op_illegal();
+ m_acc = ram_r();
+ UINT8 param = ~m_op & 0x03;
+ m_bu ^= param & m_bu_mask;
}
void amis2000_device::op_xc()
{
// XC _Y: exchange ACC with RAM, xor BU with _Y
- op_illegal();
+ UINT8 old_acc = m_acc;
+ m_acc = ram_r();
+ ram_w(old_acc);
+ UINT8 param = ~m_op & 0x03;
+ m_bu ^= param & m_bu_mask;
}
void amis2000_device::op_xci()
{
// XCI _Y: exchange ACC with RAM, increment BL(skip next on carry), xor BU with _Y
- op_illegal();
+ op_xc();
+ m_bl = (m_bl + 1) & 0xf;
+ m_skip = (m_bl == 0);
}
void amis2000_device::op_xcd()
{
// XCD _Y: exchange ACC with RAM, decrement BL(skip next on carry), xor BU with _Y
- op_illegal();
+ op_xc();
+ m_bl = (m_bl - 1) & 0xf;
+ m_skip = (m_bl == 0xf);
}
void amis2000_device::op_stm()
{
// STM Z: set RAM bit Z
- op_illegal();
+ UINT8 param = 1 << (m_op & 0x03);
+ ram_w(ram_r() | param);
}
void amis2000_device::op_rsm()
{
// RSM Z: reset RAM bit Z
- op_illegal();
+ UINT8 param = 1 << (m_op & 0x03);
+ ram_w(ram_r() & ~param);
}
@@ -204,37 +245,38 @@ void amis2000_device::op_nop()
void amis2000_device::op_szc()
{
// SZC: skip next on zero(no) carry
- op_illegal();
+ m_skip = !m_carry;
}
void amis2000_device::op_szm()
{
// SZM Z: skip next on zero RAM bit Z
- op_illegal();
+ UINT8 param = 1 << (m_op & 0x03);
+ m_skip = !(ram_r() & param);
}
void amis2000_device::op_szi()
{
// SZI: skip next on zero I pin(s)
- op_illegal();
+ m_skip = !m_i;
}
void amis2000_device::op_szk()
{
// SZK: skip next on zero K pin(s)
- op_illegal();
+ m_skip = !m_k;
}
void amis2000_device::op_sbe()
{
// SBE: skip next on BL equ E
- op_illegal();
+ m_skip = (m_bl == m_e);
}
void amis2000_device::op_sam()
{
// SAM: skip next on ACC equ RAM
- op_illegal();
+ m_skip = (m_acc == ram_r());
}
void amis2000_device::op_sos()
@@ -246,13 +288,13 @@ void amis2000_device::op_sos()
void amis2000_device::op_tf1()
{
// TF1: skip next on flag 1
- op_illegal();
+ m_skip = (m_f & 0x01);
}
void amis2000_device::op_tf2()
{
// TF2: skip next on flag 2
- op_illegal();
+ m_skip = (m_f & 0x02);
}
@@ -261,71 +303,77 @@ void amis2000_device::op_tf2()
void amis2000_device::op_adcs()
{
// ADCS: add RAM to ACC+carry, skip next on no carry
- op_illegal();
+ m_acc += ram_r() + m_carry;
+ m_carry = m_acc >> 4 & 1;
+ m_skip = !m_carry;
+ m_acc &= 0xf;
}
void amis2000_device::op_adis()
{
// ADIS X: add X to ACC, skip next on no carry
- op_illegal();
+ UINT8 param = m_op & 0x0f;
+ m_acc += param;
+ m_skip = !(m_acc >> 4 & 1);
+ m_acc &= 0xf;
}
void amis2000_device::op_add()
{
// ADD: add RAM to ACC
- op_illegal();
+ m_acc = (m_acc + ram_r()) & 0xf;
}
void amis2000_device::op_and()
{
// AND: and ACC with RAM
- op_illegal();
+ m_acc &= ram_r();
}
void amis2000_device::op_xor()
{
// XOR: xor ACC with RAM
- op_illegal();
+ m_acc ^= ram_r();
}
void amis2000_device::op_stc()
{
// STC: set carry
- op_illegal();
+ m_carry = 1;
}
void amis2000_device::op_rsc()
{
// RSC: reset carry
- op_illegal();
+ m_carry = 0;
}
void amis2000_device::op_cma()
{
// CMA: complement ACC
- op_illegal();
+ m_acc ^= 0xf;
}
void amis2000_device::op_sf1()
{
// SF1: set flag 1
- op_illegal();
+ m_f |= 0x01;
}
void amis2000_device::op_rf1()
{
// RF1: reset flag 1
- op_illegal();
+ m_f &= ~0x01;
}
void amis2000_device::op_sf2()
{
// SF2: set flag 2
- op_illegal();
+ m_f |= 0x02;
}
void amis2000_device::op_rf2()
{
// RF2: reset flag 2
- op_illegal();
+ m_f &= ~0x02;
}