sm500: added jump opcodes (nw)

This commit is contained in:
hap 2017-06-24 01:30:20 +02:00
parent 4d63d9d31e
commit f1c043d18c
4 changed files with 48 additions and 7 deletions

View File

@ -85,11 +85,16 @@ protected:
int m_o_mask; // number of 4-bit O pins minus 1
u8 m_ox[9]; // W' latch, max 9
u8 m_o[9]; // W latch(O outputs)
u8 m_cn; // Cn(digit select)
u8 m_cn; // CN(digit select)
u8 m_mx; // m'(digit DP select)
u8 m_cb; // CB(PC high bit buffer)
bool m_rsub; // R(in subroutine)
void shift_w();
u8 get_digit();
void set_su(u8 su) { m_stack[0] = (m_stack[0] & ~0x3c0) | (su << 6); }
u8 get_su() { return m_stack[0] >> 6 & 0xf; }
virtual int get_trs_field() { return 0; }
// opcode handlers
virtual void op_lb() override;
@ -98,7 +103,9 @@ protected:
virtual void op_rbm();
virtual void op_comcb();
virtual void op_rtn0() override;
virtual void op_ssr();
virtual void op_tr();
virtual void op_trs();
virtual void op_atbp() override;
@ -129,6 +136,7 @@ protected:
virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) override;
virtual void execute_one() override;
virtual int get_trs_field() override { return 1; }
};
class sm5l_device : public sm5a_device

View File

@ -78,7 +78,7 @@ void sm500_device::execute_one()
case 0x70: op_ssr(); break;
case 0x80: case 0x90: case 0xa0: case 0xb0:
op_t(); break; // aka tr
op_tr(); break;
case 0xc0: case 0xd0: case 0xe0: case 0xf0:
op_trs(); break;

View File

@ -44,7 +44,7 @@ void sm500_device::op_lb()
void sm500_device::op_incb()
{
// INCB: same as SM510, but overflow on 3rd bit!
// INCB: increment BL, but overflow on 3rd bit!
sm510_base_device::op_incb();
m_skip = (m_bl == 8);
}
@ -66,14 +66,47 @@ void sm500_device::op_rbm()
void sm500_device::op_comcb()
{
// COMCB: complement CB
m_cb ^= 1;
}
void sm500_device::op_rtn0()
{
// RTN0(RTN): return from subroutine
sm510_base_device::op_rtn0();
m_rsub = false;
}
void sm500_device::op_ssr()
{
// SSR x: set stack upper bits, also sets E flag for next opcode
set_su(m_op & 0xf);
}
void sm500_device::op_tr()
{
// TR x: jump (long or short)
m_pc = (m_pc & ~0x3f) | (m_op & 0x3f);
if (!m_rsub)
do_branch(m_cb, get_su(), m_pc & 0x3f);
}
void sm500_device::op_trs()
{
// TRS x: call subroutine
if (!m_rsub)
{
m_rsub = true;
u8 su = get_su();
push_stack();
do_branch(get_trs_field(), 0, m_op & 0x3f);
// E flag was set?
if ((m_prev_op & 0xf0) == 0x70)
do_branch(m_cb, su, m_pc & 0x3f);
}
else
m_pc = (m_pc & ~0xff) | (m_op << 2 & 0xc0) | (m_op & 0xf);
}
@ -81,7 +114,7 @@ void sm500_device::op_trs()
void sm500_device::op_atbp()
{
// ATBP: same as SM510, and set Cn with ACC3
// ATBP: same as SM510, and set CN with ACC3
sm510_base_device::op_atbp();
m_cn = m_acc >> 3 & 1;
}
@ -164,6 +197,6 @@ void sm500_device::op_smf()
void sm500_device::op_comcn()
{
// COMCN: complement Cn flag
// COMCN: complement CN flag
m_cn ^= 1;
}

View File

@ -28,7 +28,7 @@ static ADDRESS_MAP_START(data_5x13x4, AS_DATA, 8, sm510_base_device)
AM_RANGE(0x10, 0x1c) AM_RAM
AM_RANGE(0x20, 0x2c) AM_RAM
AM_RANGE(0x30, 0x3c) AM_RAM
AM_RANGE(0x40, 0x4c) AM_RAM
AM_RANGE(0x40, 0x4c) AM_MIRROR(0x30) AM_RAM
ADDRESS_MAP_END
@ -77,7 +77,7 @@ void sm5a_device::execute_one()
case 0x70: op_ssr(); break; // LP
case 0x80: case 0x90: case 0xa0: case 0xb0:
op_t(); break; // BR (LP+this=JMP)
op_tr(); break; // BR (LP+this=JMP)
case 0xc0: case 0xd0: case 0xe0: case 0xf0:
op_trs(); break; // CBR/CZP (LP+this=CAL)