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 // 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) offs_t sm510_base_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
{ {
extern CPU_DISASSEMBLE(sm510); 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(SM510_BM, "BM", m_bm).formatstr("%01X");
state_add(STATE_GENPC, "curpc", m_pc).formatstr("%04X").noshow(); 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; m_icountptr = &m_icount;
} }
@ -137,7 +120,10 @@ void sm510_base_device::device_start()
void sm510_base_device::device_reset() 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() void sm510_base_device::get_opcode_param()
{ {
// LBL, TL, TML, TM opcodes are 2 bytes // LBL, TL, TML opcodes are 2 bytes
if (m_op == 0x5f || (m_op & 0xf0) == 0x70 || m_op >= 0xc0) if (m_op == 0x5f || (m_op & 0xf0) == 0x70)
{ {
m_icount -= 2; // guessed m_icount--;
m_param = m_program->read_byte(m_pc); m_param = m_program->read_byte(m_pc);
increment_pc(); increment_pc();
} }
@ -175,12 +161,19 @@ void sm510_base_device::execute_run()
// fetch next opcode // fetch next opcode
debugger_instruction_hook(this, m_pc); debugger_instruction_hook(this, m_pc);
m_icount -= 2; // 61us typical m_icount--;
m_op = m_program->read_byte(m_pc); m_op = m_program->read_byte(m_pc);
increment_pc(); increment_pc();
get_opcode_param(); 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) switch (m_op & 0xf0)
{ {
case 0x20: op_lax(); break; case 0x20: op_lax(); break;

View File

@ -42,6 +42,8 @@ protected:
virtual void device_reset(); virtual void device_reset();
// device_execute_interface overrides // 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_min_cycles() const { return 1; }
virtual UINT32 execute_max_cycles() const { return 2; } virtual UINT32 execute_max_cycles() const { return 2; }
virtual UINT32 execute_input_lines() const { return 1; } 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_min_opcode_bytes() const { return 1; }
virtual UINT32 disasm_max_opcode_bytes() const { return 2; } 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); 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_program_config;
address_space_config m_data_config; address_space_config m_data_config;
@ -93,6 +94,8 @@ protected:
void ram_w(UINT8 data); void ram_w(UINT8 data);
void pop_stack(); void pop_stack();
void push_stack(); void push_stack();
void do_branch(UINT8 pu, UINT8 pm, UINT8 pl);
UINT8 bitmask(UINT8 param);
// opcode handlers // opcode handlers
void op_lb(); void op_lb();

View File

@ -40,7 +40,7 @@ static const UINT8 s_bits[] =
{ {
0, 0,
4, 8, 0, 0, 0, 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, 2, 0, 2, 2, 2, 4, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 4, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0,
@ -133,15 +133,11 @@ CPU_DISASSEMBLE(sm510)
{ {
dst += sprintf(dst, "$%02X", param); 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); dst += sprintf(dst, "$%03X", address);
} }
else if (instr == mTM)
{
//todo
}
} }
return len | s_flags[instr] | DASMFLAG_SUPPORTED; return len | s_flags[instr] | DASMFLAG_SUPPORTED;

View File

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