more opcodes added

This commit is contained in:
hap 2015-07-03 18:33:41 +02:00
parent 927ad9c16e
commit d19922bd32
4 changed files with 69 additions and 57 deletions

View File

@ -47,23 +47,6 @@ sm510_device::sm510_device(const machine_config &mconfig, const char *tag, devic
// disasm
void sm510_base_device::state_string_export(const device_state_entry &entry, std::string &str)
{
#if 0
switch (entry.index())
{
case STATE_GENFLAGS:
strprintf(str, "%c%c",
m_c ? 'C':'c',
m_s ? 'S':'s'
);
break;
default: break;
}
#endif
}
offs_t sm510_base_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
{
extern CPU_DISASSEMBLE(sm510);
@ -124,7 +107,7 @@ void sm510_base_device::device_start()
state_add(SM510_BM, "BM", m_bm).formatstr("%01X");
state_add(STATE_GENPC, "curpc", m_pc).formatstr("%04X").noshow();
state_add(STATE_GENFLAGS, "GENFLAGS", m_pc).formatstr("%2s").noshow();
state_add(STATE_GENFLAGS, "GENFLAGS", m_c).formatstr("%1s").noshow();
m_icountptr = &m_icount;
}
@ -137,7 +120,10 @@ void sm510_base_device::device_start()
void sm510_base_device::device_reset()
{
m_pc = 0x37 << 6;
m_skip = false;
m_op = m_prev_op = 0;
do_branch(3, 7, 0);
m_prev_pc = m_pc;
}
@ -156,10 +142,10 @@ inline void sm510_base_device::increment_pc()
void sm510_base_device::get_opcode_param()
{
// LBL, TL, TML, TM opcodes are 2 bytes
if (m_op == 0x5f || (m_op & 0xf0) == 0x70 || m_op >= 0xc0)
// LBL, TL, TML opcodes are 2 bytes
if (m_op == 0x5f || (m_op & 0xf0) == 0x70)
{
m_icount -= 2; // guessed
m_icount--;
m_param = m_program->read_byte(m_pc);
increment_pc();
}
@ -175,12 +161,19 @@ void sm510_base_device::execute_run()
// fetch next opcode
debugger_instruction_hook(this, m_pc);
m_icount -= 2; // 61us typical
m_icount--;
m_op = m_program->read_byte(m_pc);
increment_pc();
get_opcode_param();
// handle opcode
// handle opcode if it's not skipped
if (m_skip)
{
m_skip = false;
m_op = 0; // fake nop
}
else //execute_one();
switch (m_op & 0xf0)
{
case 0x20: op_lax(); break;

View File

@ -42,6 +42,8 @@ protected:
virtual void device_reset();
// device_execute_interface overrides
virtual UINT64 execute_clocks_to_cycles(UINT64 clocks) const { return (clocks + 2 - 1) / 2; } // default 2 cycles per machine cycle
virtual UINT64 execute_cycles_to_clocks(UINT64 cycles) const { return (cycles * 2); } // "
virtual UINT32 execute_min_cycles() const { return 1; }
virtual UINT32 execute_max_cycles() const { return 2; }
virtual UINT32 execute_input_lines() const { return 1; }
@ -55,7 +57,6 @@ protected:
virtual UINT32 disasm_min_opcode_bytes() const { return 1; }
virtual UINT32 disasm_max_opcode_bytes() const { return 2; }
virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);
void state_string_export(const device_state_entry &entry, std::string &str);
address_space_config m_program_config;
address_space_config m_data_config;
@ -93,6 +94,8 @@ protected:
void ram_w(UINT8 data);
void pop_stack();
void push_stack();
void do_branch(UINT8 pu, UINT8 pm, UINT8 pl);
UINT8 bitmask(UINT8 param);
// opcode handlers
void op_lb();

View File

@ -40,7 +40,7 @@ static const UINT8 s_bits[] =
{
0,
4, 8, 0, 0, 0, 0,
0, 0, 0, 4+8, 2+8, 6+8, 6,
0, 0, 0, 4+8, 2+8, 6, 6,
2, 0, 2, 2, 2, 4, 0, 0,
0, 0, 0, 0, 0,
0, 0, 4, 0, 0, 0, 0,
@ -133,15 +133,11 @@ CPU_DISASSEMBLE(sm510)
{
dst += sprintf(dst, "$%02X", param);
}
else if (instr == mTL || instr == mTML)
else
{
UINT16 address = (param << 4 & 0xc00) | (mask << 6 & 0x3c0) | (param & 0x3f);
UINT16 address = (param << 4 & 0xc00) | (mask << 6 & 0x3c0) | (param & 0x03f);
dst += sprintf(dst, "$%03X", address);
}
else if (instr == mTM)
{
//todo
}
}
return len | s_flags[instr] | DASMFLAG_SUPPORTED;

View File

@ -7,13 +7,15 @@
inline UINT8 sm510_base_device::ram_r()
{
UINT8 address = (m_bm << 4 | m_bl) & m_datamask;
int bmh = (m_prev_op == 0x02) ? (1 << (m_datawidth-1)) : 0; // from SBM
UINT8 address = (bmh | m_bm << 4 | m_bl) & m_datamask;
return m_data->read_byte(address) & 0xf;
}
inline void sm510_base_device::ram_w(UINT8 data)
{
UINT8 address = (m_bm << 4 | m_bl) & m_datamask;
int bmh = (m_prev_op == 0x02) ? (1 << (m_datawidth-1)) : 0; // from SBM
UINT8 address = (bmh | m_bm << 4 | m_bl) & m_datamask;
m_data->write_byte(address, data & 0xf);
}
@ -31,6 +33,18 @@ void sm510_base_device::push_stack()
m_stack[0] = m_pc;
}
inline void sm510_base_device::do_branch(UINT8 pu, UINT8 pm, UINT8 pl)
{
// set new PC(Pu/Pm/Pl)
m_pc = ((pu << 10 & 0xc00) | (pm << 6 & 0x3c0) | (pl & 0x03f)) & m_prgmask;
}
inline UINT8 sm510_base_device::bitmask(UINT8 param)
{
// bitmask from immediate opcode param
return 1 << (param & 3);
}
// instruction set
@ -46,13 +60,14 @@ void sm510_base_device::op_lb()
void sm510_base_device::op_lbl()
{
// LBL xy: load BM/BL with 8-bit immediate value
op_illegal();
m_bl = m_param & 0xf;
m_bm = (m_param & m_datamask) >> 4;
}
void sm510_base_device::op_sbm()
{
// SBM: set BM high bit for next opcode
op_illegal();
// SBM: set BM high bit for next opcode - handled in ram_r/w
assert(m_op == 0x02);
}
void sm510_base_device::op_exbla()
@ -82,7 +97,7 @@ void sm510_base_device::op_decb()
void sm510_base_device::op_atpl()
{
// ATPL: load PC low bits with ACC
// ATPL: load Pl(PC low bits) with ACC
m_pc = (m_pc & ~0xf) | m_acc;
}
@ -99,29 +114,34 @@ void sm510_base_device::op_rtn1()
m_skip = true;
}
void sm510_base_device::op_t()
{
// T xy: jump(transfer) within current page
m_pc = (m_pc & ~0x3f) | (m_op & 0x3f);
}
void sm510_base_device::op_tl()
{
// TL xyz: longjump
op_illegal();
// TL xyz: long jump
do_branch(m_param >> 6 & 3, m_op & 0xf, m_param & 0x3f);
}
void sm510_base_device::op_tml()
{
// TML xyz: x
op_illegal();
// TML xyz: long call
push_stack();
do_branch(m_param >> 6 & 3, m_op & 3, m_param & 0x3f);
}
void sm510_base_device::op_tm()
{
// TM xyz: x
op_illegal();
// TM x: indirect subroutine call, pointers(IDX) are in page 0
m_icount--;
push_stack();
UINT8 idx = m_program->read_byte(m_op & 0x3f);
do_branch(idx >> 6 & 3, 4, idx & 0x3f);
}
void sm510_base_device::op_t()
{
// T xy: jump within current page
m_pc = (m_pc & ~0x3f) | (m_op & 0x3f);
}
// Data transfer instructions
@ -236,7 +256,7 @@ void sm510_base_device::op_adx()
{
// ADX x: add immediate value to ACC, skip next on carry
m_acc += (m_op & 0xf);
m_skip = (m_acc & 0x10) ? true : false;
m_skip = ((m_acc & 0x10) != 0);
m_acc &= 0xf;
}
@ -248,10 +268,10 @@ void sm510_base_device::op_coma()
void sm510_base_device::op_rot()
{
// ROT: rotate ACC left through carry
m_acc = m_acc << 1 | m_c;
m_c = m_acc >> 4 & 1;
m_acc &= 0xf;
// ROT: rotate ACC right through carry
UINT8 c = m_acc & 1;
m_acc = m_acc >> 1 | m_c << 3;
m_c = c;
}
void sm510_base_device::op_rc()
@ -290,7 +310,7 @@ void sm510_base_device::op_tam()
void sm510_base_device::op_tmi()
{
// TMI x: skip next if RAM bit is set
m_skip = (ram_r() & 1 << (m_op & 3)) ? true : false;
m_skip = ((ram_r() & bitmask(m_op)) != 0);
}
void sm510_base_device::op_ta0()
@ -335,13 +355,13 @@ void sm510_base_device::op_tf4()
void sm510_base_device::op_rm()
{
// RM x: reset RAM bit
ram_w(ram_r() & ~(1 << (m_op & 3)));
ram_w(ram_r() & ~bitmask(m_op));
}
void sm510_base_device::op_sm()
{
// SM x: set RAM bit
ram_w(ram_r() | (1 << (m_op & 3)));
ram_w(ram_r() | bitmask(m_op));
}