added simple opcodes

This commit is contained in:
hap 2015-05-20 13:24:04 +02:00
parent 817d131dfd
commit bb70541c18
2 changed files with 109 additions and 26 deletions

View File

@ -61,6 +61,24 @@ protected:
UINT16 m_prev_pc; UINT16 m_prev_pc;
UINT16 m_op; UINT16 m_op;
// registers (unless specified, each is 4-bit)
UINT8 m_a; // accumulator
UINT8 m_b; // generic
UINT8 m_y, m_y2; // RAM index Y, Y' (Z.XX.YYYY is DP aka Data Pointer)
UINT8 m_x, m_x2; // RAM index X, X', 2-bit
UINT8 m_z, m_z2; // RAM index Z, Z', 1-bit, optional
UINT8 m_cy, m_cy2; // carry flag(s)
UINT8 m_e; // 8-bit register, hold data for S output
UINT8 m_cps; // DP,CY or DP',CY' selected
bool m_skip;
// misc internal helpers
UINT8 ram_r();
void ram_w(UINT8 data);
void pop_pc();
void push_pc();
// opcode handlers // opcode handlers
void op_tab(); void op_tab();
void op_tba(); void op_tba();

View File

@ -3,6 +3,27 @@
// MELPS 4 opcode handlers // MELPS 4 opcode handlers
// internal helpers
inline UINT8 melps4_cpu_device::ram_r()
{
UINT8 address = (m_z << 5 | m_x << 4 | m_y) & m_datamask;
return m_data->read_byte(address) & 0xf;
}
inline void melps4_cpu_device::ram_w(UINT8 data)
{
UINT8 address = (m_z << 5 | m_x << 4 | m_y) & m_datamask;
m_data->write_byte(address, data & 0xf);
}
void melps4_cpu_device::pop_pc()
{
}
void melps4_cpu_device::push_pc()
{
}
// Register-to-register transfers // Register-to-register transfers
@ -10,31 +31,31 @@
void melps4_cpu_device::op_tab() void melps4_cpu_device::op_tab()
{ {
// TAB: transfer B to A // TAB: transfer B to A
op_illegal(); m_a = m_b;
} }
void melps4_cpu_device::op_tba() void melps4_cpu_device::op_tba()
{ {
// TBA: transfer A to B // TBA: transfer A to B
op_illegal(); m_b = m_a;
} }
void melps4_cpu_device::op_tay() void melps4_cpu_device::op_tay()
{ {
// TAY: transfer Y to A // TAY: transfer Y to A
op_illegal(); m_a = m_y;
} }
void melps4_cpu_device::op_tya() void melps4_cpu_device::op_tya()
{ {
// TYA: transfer A to Y // TYA: transfer A to Y
op_illegal(); m_y = m_a;
} }
void melps4_cpu_device::op_teab() void melps4_cpu_device::op_teab()
{ {
// TEAB: transfer A and B to E // TEAB: transfer A and B to E
op_illegal(); m_e = m_b << 4 | m_a;
} }
void melps4_cpu_device::op_tepa() void melps4_cpu_device::op_tepa()
@ -61,31 +82,56 @@ void melps4_cpu_device::op_tax()
void melps4_cpu_device::op_lxy() void melps4_cpu_device::op_lxy()
{ {
// LXY x,y: load immediate into X,Y, skip any next LXY // LXY x,y: load immediate into X,Y, skip any next LXY
m_x = m_op >> 4 & 3;
m_y = m_op & 0xf;
op_illegal(); op_illegal();
} }
void melps4_cpu_device::op_lz() void melps4_cpu_device::op_lz()
{ {
// LZ z: load immediate into Z // LZ z: load immediate into Z
op_illegal(); m_z = m_op & 1;
} }
void melps4_cpu_device::op_iny() void melps4_cpu_device::op_iny()
{ {
// INY: increment Y, skip next on overflow // INY: increment Y, skip next on overflow
op_illegal(); m_y = (m_y + 1) & 0xf;
m_skip = (m_y == 0);
} }
void melps4_cpu_device::op_dey() void melps4_cpu_device::op_dey()
{ {
// DEY: decrement Y, skip next on overflow // DEY: decrement Y, skip next on overflow
op_illegal(); m_y = (m_y - 1) & 0xf;
m_skip = (m_y == 0xf);
} }
void melps4_cpu_device::op_lcps() void melps4_cpu_device::op_lcps()
{ {
// LCPS i: choose active DP,CY or DP',CY' // LCPS i: choose active DP,CY or DP',CY'
op_illegal(); if ((m_op & 1) != m_cps)
{
m_cps = m_op & 1;
// swap registers
UINT8 x, y, z, cy;
x = m_x;
y = m_y;
z = m_z;
cy = m_cy;
m_x = m_x2;
m_y = m_y2;
m_z = m_z2;
m_cy = m_cy2;
m_x2 = x;
m_y2 = y;
m_z2 = z;
m_cy2 = cy;
}
} }
void melps4_cpu_device::op_sadr() void melps4_cpu_device::op_sadr()
@ -100,24 +146,32 @@ void melps4_cpu_device::op_sadr()
void melps4_cpu_device::op_tam() void melps4_cpu_device::op_tam()
{ {
// TAM j: transfer RAM to A, xor X with j // TAM j: transfer RAM to A, xor X with j
op_illegal(); m_a = ram_r();
m_x ^= m_op & 3;
} }
void melps4_cpu_device::op_xam() void melps4_cpu_device::op_xam()
{ {
// XAM j: exchange RAM with A, xor X with j // XAM j: exchange RAM with A, xor X with j
op_illegal(); UINT8 a = m_a;
m_a = ram_r();
ram_w(a);
m_x ^= m_op & 3;
} }
void melps4_cpu_device::op_xamd() void melps4_cpu_device::op_xamd()
{ {
// XAMD j: XAM J, DEY // XAMD j: XAM J, DEY
op_illegal(); op_xam();
op_dey();
} }
void melps4_cpu_device::op_xami() void melps4_cpu_device::op_xami()
{ {
// XAMI j: XAM J, increment Y, skip next on Y=mask(default 0) // XAMI j: XAM J, INY, skip next on Y=mask(default 0)
op_xam();
op_iny();
op_illegal(); op_illegal();
} }
@ -127,55 +181,63 @@ void melps4_cpu_device::op_xami()
void melps4_cpu_device::op_la() void melps4_cpu_device::op_la()
{ {
// LA n: load immediate into A, skip any next LA // LA n: load immediate into A, skip any next LA
m_a = m_op & 0xf;
op_illegal(); op_illegal();
} }
void melps4_cpu_device::op_am() void melps4_cpu_device::op_am()
{ {
// AM: add RAM to A // AM: add RAM to A
op_illegal(); m_a = (m_a + ram_r()) & 0xf;
} }
void melps4_cpu_device::op_amc() void melps4_cpu_device::op_amc()
{ {
// AMC: add RAM+CY to A and CY // AMC: add RAM+CY to A and CY
op_illegal(); m_a += ram_r() + m_cy;
m_cy = m_a >> 4 & 1;
m_a &= 0xf;
} }
void melps4_cpu_device::op_amcs() void melps4_cpu_device::op_amcs()
{ {
// AMCS: AMC, skip next on carry // AMCS: AMC, skip next on carry
op_illegal(); op_amc();
m_skip = (m_cy != 0);
} }
void melps4_cpu_device::op_a() void melps4_cpu_device::op_a()
{ {
// A n: add immediate to A, skip next on no carry (except when n=6) // A n: add immediate to A, skip next on no carry (except when n=6)
op_illegal(); UINT8 n = m_op & 0xf;
m_a += n;
m_skip = !(m_a & 0x10 || n == 6);
m_a &= 0xf;
} }
void melps4_cpu_device::op_sc() void melps4_cpu_device::op_sc()
{ {
// SC: set carry // SC: set carry
op_illegal(); m_cy = 1;
} }
void melps4_cpu_device::op_rc() void melps4_cpu_device::op_rc()
{ {
// RC: reset carry // RC: reset carry
op_illegal(); m_cy = 0;
} }
void melps4_cpu_device::op_szc() void melps4_cpu_device::op_szc()
{ {
// SZC: skip next on no carry // SZC: skip next on no carry
op_illegal(); m_skip = !m_cy;
} }
void melps4_cpu_device::op_cma() void melps4_cpu_device::op_cma()
{ {
// CMA: complement A // CMA: complement A
op_illegal(); m_a ^= 0xf;
} }
@ -184,19 +246,22 @@ void melps4_cpu_device::op_cma()
void melps4_cpu_device::op_sb() void melps4_cpu_device::op_sb()
{ {
// SB j: set RAM bit // SB j: set RAM bit
op_illegal(); UINT8 mask = 1 << (m_op & 3);
ram_w(ram_r() | mask);
} }
void melps4_cpu_device::op_rb() void melps4_cpu_device::op_rb()
{ {
// RB j: reset RAM bit // RB j: reset RAM bit
op_illegal(); UINT8 mask = 1 << (m_op & 3);
ram_w(ram_r() & ~mask);
} }
void melps4_cpu_device::op_szb() void melps4_cpu_device::op_szb()
{ {
// SZB j: skip next if RAM bit is reset // SZB j: skip next if RAM bit is reset
op_illegal(); UINT8 mask = 1 << (m_op & 3);
m_skip = !(ram_r() & mask);
} }
@ -205,13 +270,13 @@ void melps4_cpu_device::op_szb()
void melps4_cpu_device::op_seam() void melps4_cpu_device::op_seam()
{ {
// SEAM: skip next if A equals RAM // SEAM: skip next if A equals RAM
op_illegal(); m_skip = (m_a == ram_r());
} }
void melps4_cpu_device::op_sey() void melps4_cpu_device::op_sey()
{ {
// SEY y: skip next if Y equals immediate // SEY y: skip next if Y equals immediate
op_illegal(); m_skip = (m_y == (m_op & 0xf));
} }