summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/sm510/sm500op.cpp
diff options
context:
space:
mode:
author hap <happppp@users.noreply.github.com>2017-06-23 21:14:02 +0200
committer hap <happppp@users.noreply.github.com>2017-06-23 21:14:24 +0200
commit1a82ca71ba5240e5eebc38723f343765ac2ea627 (patch)
tree0b4890f49cb959070dd0b3be85114364a41525f6 /src/devices/cpu/sm510/sm500op.cpp
parenta8bde85010426ea4fe6a7888178046a145914825 (diff)
sm500: added lcd opcodes (nw)
Diffstat (limited to 'src/devices/cpu/sm510/sm500op.cpp')
-rw-r--r--src/devices/cpu/sm510/sm500op.cpp78
1 files changed, 70 insertions, 8 deletions
diff --git a/src/devices/cpu/sm510/sm500op.cpp b/src/devices/cpu/sm510/sm500op.cpp
index 44ed43952ff..d3a31204fb0 100644
--- a/src/devices/cpu/sm510/sm500op.cpp
+++ b/src/devices/cpu/sm510/sm500op.cpp
@@ -7,6 +7,29 @@
#include "sm500.h"
+// internal helpers
+
+void sm500_device::shift_w()
+{
+ // shifts internal W' latches
+ for (int i = 0; i < m_o_mask; i++)
+ m_ox[i] = m_ox[i + 1];
+}
+
+u8 sm500_device::get_digit()
+{
+ // default digit segments PLA
+ static const u8 lut_digits[0x20] =
+ {
+ 0xe, 0x0, 0xc, 0x8, 0x2, 0xa, 0xe, 0x2, 0xe, 0xa, 0x0, 0x0, 0x2, 0xa, 0x2, 0x2,
+ 0xb, 0x9, 0x7, 0xf, 0xd, 0xe, 0xe, 0xb, 0xf, 0xf, 0x4, 0x0, 0xd, 0xe, 0x4, 0x0
+ };
+
+ return lut_digits[m_cn << 4 | m_acc] | (~m_cn & m_mx);
+}
+
+
+
// instruction set
// RAM address instructions
@@ -21,8 +44,8 @@ void sm500_device::op_lb()
void sm500_device::op_incb()
{
- // INCB: increment BL, skip next on overflow, of 3rd bit!
- m_bl = (m_bl + 1) & 0xf;
+ // INCB: same as SM510, but overflow on 3rd bit!
+ sm510_base_device::op_incb();
m_skip = (m_bl == 8);
}
@@ -54,21 +77,55 @@ void sm500_device::op_trs()
}
-// Arithmetic instructions
-
-
// Data transfer instructions
-void sm500_device::op_pdtw()
+void sm500_device::op_atbp()
+{
+ // ATBP: same as SM510, and set Cn with ACC3
+ sm510_base_device::op_atbp();
+ m_cn = m_acc >> 3 & 1;
+}
+
+void sm500_device::op_ptw()
{
+ // PTW: partial transfer W' to W
+ m_o[m_o_mask] = m_ox[m_o_mask];
+ m_o[m_o_mask-1] = m_ox[m_o_mask-1];
}
void sm500_device::op_tw()
{
+ // TW: transfer W' to W
+ for (int i = 0; i <= m_o_mask; i++)
+ m_o[i] = m_ox[i];
+}
+
+void sm500_device::op_pdtw()
+{
+ // PDTW: partial shift digit into W'
+ m_ox[m_o_mask-1] = m_ox[m_o_mask];
+ m_ox[m_o_mask] = get_digit();
}
void sm500_device::op_dtw()
{
+ // DTW: shift digit into W'
+ shift_w();
+ m_ox[m_o_mask] = get_digit();
+}
+
+void sm500_device::op_wr()
+{
+ // WR: shift ACC into W', reset last bit
+ shift_w();
+ m_ox[m_o_mask] = m_acc & 7;
+}
+
+void sm500_device::op_ws()
+{
+ // WR: shift ACC into W', set last bit
+ shift_w();
+ m_ox[m_o_mask] = m_acc | 8;
}
@@ -94,14 +151,19 @@ void sm500_device::op_exkfa()
void sm500_device::op_rmf()
{
+ // RMF: reset m' flag, also clears ACC
+ m_mx = 0;
+ m_acc = 0;
}
void sm500_device::op_smf()
{
+ // SMF: set m' flag
+ m_mx = 1;
}
void sm500_device::op_comcn()
{
+ // COMCN: complement Cn flag
+ m_cn ^= 1;
}
-
-// Test instructions