From f1c043d18c6882930b4c00877c5d1773c527f998 Mon Sep 17 00:00:00 2001 From: hap Date: Sat, 24 Jun 2017 01:30:20 +0200 Subject: [PATCH] sm500: added jump opcodes (nw) --- src/devices/cpu/sm510/sm500.h | 10 +++++++- src/devices/cpu/sm510/sm500core.cpp | 2 +- src/devices/cpu/sm510/sm500op.cpp | 39 ++++++++++++++++++++++++++--- src/devices/cpu/sm510/sm5acore.cpp | 4 +-- 4 files changed, 48 insertions(+), 7 deletions(-) diff --git a/src/devices/cpu/sm510/sm500.h b/src/devices/cpu/sm510/sm500.h index 122a779494a..57b89202c3b 100644 --- a/src/devices/cpu/sm510/sm500.h +++ b/src/devices/cpu/sm510/sm500.h @@ -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 diff --git a/src/devices/cpu/sm510/sm500core.cpp b/src/devices/cpu/sm510/sm500core.cpp index 5727e36e8ee..1df14d4d147 100644 --- a/src/devices/cpu/sm510/sm500core.cpp +++ b/src/devices/cpu/sm510/sm500core.cpp @@ -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; diff --git a/src/devices/cpu/sm510/sm500op.cpp b/src/devices/cpu/sm510/sm500op.cpp index d3a31204fb0..fc18e279894 100644 --- a/src/devices/cpu/sm510/sm500op.cpp +++ b/src/devices/cpu/sm510/sm500op.cpp @@ -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; } diff --git a/src/devices/cpu/sm510/sm5acore.cpp b/src/devices/cpu/sm510/sm5acore.cpp index 51ffdfceed6..ab402e535ba 100644 --- a/src/devices/cpu/sm510/sm5acore.cpp +++ b/src/devices/cpu/sm510/sm5acore.cpp @@ -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)