mirror of
https://github.com/holub/mame
synced 2025-04-26 18:23:08 +03:00
sm500: added jump opcodes (nw)
This commit is contained in:
parent
4d63d9d31e
commit
f1c043d18c
@ -85,11 +85,16 @@ protected:
|
|||||||
int m_o_mask; // number of 4-bit O pins minus 1
|
int m_o_mask; // number of 4-bit O pins minus 1
|
||||||
u8 m_ox[9]; // W' latch, max 9
|
u8 m_ox[9]; // W' latch, max 9
|
||||||
u8 m_o[9]; // W latch(O outputs)
|
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_mx; // m'(digit DP select)
|
||||||
|
u8 m_cb; // CB(PC high bit buffer)
|
||||||
|
bool m_rsub; // R(in subroutine)
|
||||||
|
|
||||||
void shift_w();
|
void shift_w();
|
||||||
u8 get_digit();
|
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
|
// opcode handlers
|
||||||
virtual void op_lb() override;
|
virtual void op_lb() override;
|
||||||
@ -98,7 +103,9 @@ protected:
|
|||||||
virtual void op_rbm();
|
virtual void op_rbm();
|
||||||
|
|
||||||
virtual void op_comcb();
|
virtual void op_comcb();
|
||||||
|
virtual void op_rtn0() override;
|
||||||
virtual void op_ssr();
|
virtual void op_ssr();
|
||||||
|
virtual void op_tr();
|
||||||
virtual void op_trs();
|
virtual void op_trs();
|
||||||
|
|
||||||
virtual void op_atbp() override;
|
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 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 void execute_one() override;
|
||||||
|
virtual int get_trs_field() override { return 1; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class sm5l_device : public sm5a_device
|
class sm5l_device : public sm5a_device
|
||||||
|
@ -78,7 +78,7 @@ void sm500_device::execute_one()
|
|||||||
case 0x70: op_ssr(); break;
|
case 0x70: op_ssr(); break;
|
||||||
|
|
||||||
case 0x80: case 0x90: case 0xa0: case 0xb0:
|
case 0x80: case 0x90: case 0xa0: case 0xb0:
|
||||||
op_t(); break; // aka tr
|
op_tr(); break;
|
||||||
case 0xc0: case 0xd0: case 0xe0: case 0xf0:
|
case 0xc0: case 0xd0: case 0xe0: case 0xf0:
|
||||||
op_trs(); break;
|
op_trs(); break;
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ void sm500_device::op_lb()
|
|||||||
|
|
||||||
void sm500_device::op_incb()
|
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();
|
sm510_base_device::op_incb();
|
||||||
m_skip = (m_bl == 8);
|
m_skip = (m_bl == 8);
|
||||||
}
|
}
|
||||||
@ -66,14 +66,47 @@ void sm500_device::op_rbm()
|
|||||||
|
|
||||||
void sm500_device::op_comcb()
|
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()
|
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()
|
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()
|
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();
|
sm510_base_device::op_atbp();
|
||||||
m_cn = m_acc >> 3 & 1;
|
m_cn = m_acc >> 3 & 1;
|
||||||
}
|
}
|
||||||
@ -164,6 +197,6 @@ void sm500_device::op_smf()
|
|||||||
|
|
||||||
void sm500_device::op_comcn()
|
void sm500_device::op_comcn()
|
||||||
{
|
{
|
||||||
// COMCN: complement Cn flag
|
// COMCN: complement CN flag
|
||||||
m_cn ^= 1;
|
m_cn ^= 1;
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ static ADDRESS_MAP_START(data_5x13x4, AS_DATA, 8, sm510_base_device)
|
|||||||
AM_RANGE(0x10, 0x1c) AM_RAM
|
AM_RANGE(0x10, 0x1c) AM_RAM
|
||||||
AM_RANGE(0x20, 0x2c) AM_RAM
|
AM_RANGE(0x20, 0x2c) AM_RAM
|
||||||
AM_RANGE(0x30, 0x3c) 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
|
ADDRESS_MAP_END
|
||||||
|
|
||||||
|
|
||||||
@ -77,7 +77,7 @@ void sm5a_device::execute_one()
|
|||||||
case 0x70: op_ssr(); break; // LP
|
case 0x70: op_ssr(); break; // LP
|
||||||
|
|
||||||
case 0x80: case 0x90: case 0xa0: case 0xb0:
|
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:
|
case 0xc0: case 0xd0: case 0xe0: case 0xf0:
|
||||||
op_trs(); break; // CBR/CZP (LP+this=CAL)
|
op_trs(); break; // CBR/CZP (LP+this=CAL)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user