summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author hap <happppp@users.noreply.github.com>2015-07-07 21:49:49 +0200
committer hap <happppp@users.noreply.github.com>2015-07-07 21:49:49 +0200
commit5c036e09986d4d415f042631d73e1e7cd3a0c177 (patch)
treefcea35d640bac334a7cdd04d9841de7d739eb2af
parent37950bd90fdb299275d68aa9bed36c385b1aec76 (diff)
added internal timer
-rw-r--r--src/emu/cpu/sm510/sm510.c83
-rw-r--r--src/emu/cpu/sm510/sm510.h30
-rw-r--r--src/emu/cpu/sm510/sm510op.c35
3 files changed, 119 insertions, 29 deletions
diff --git a/src/emu/cpu/sm510/sm510.c b/src/emu/cpu/sm510/sm510.c
index 2968335b68a..b4208c4a9f1 100644
--- a/src/emu/cpu/sm510/sm510.c
+++ b/src/emu/cpu/sm510/sm510.c
@@ -36,8 +36,13 @@ void sm510_base_device::device_start()
m_prgmask = (1 << m_prgwidth) - 1;
m_datamask = (1 << m_datawidth) - 1;
+ m_div_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(sm510_base_device::div_timer_cb), this));
+ reset_divider();
+
// resolve callbacks
m_read_k.resolve_safe(0);
+ m_read_ba.resolve_safe(1);
+ m_read_b.resolve_safe(1);
m_write_s.resolve_safe();
// zerofill
@@ -53,9 +58,11 @@ void sm510_base_device::device_start()
m_c = 0;
m_skip = false;
m_w = 0;
- m_div = 0;
- m_bdc = false;
- m_cend = false;
+// m_div = 0;
+ m_1s = false;
+ m_bp = false;
+ m_bc = false;
+ m_halt = false;
// register for savestates
save_item(NAME(m_stack));
@@ -71,8 +78,10 @@ void sm510_base_device::device_start()
save_item(NAME(m_skip));
save_item(NAME(m_w));
save_item(NAME(m_div));
- save_item(NAME(m_bdc));
- save_item(NAME(m_cend));
+ save_item(NAME(m_1s));
+ save_item(NAME(m_bp));
+ save_item(NAME(m_bc));
+ save_item(NAME(m_halt));
// register state for debugger
state_add(SM510_PC, "PC", m_pc).formatstr("%04X");
@@ -97,11 +106,64 @@ void sm510_base_device::device_start()
void sm510_base_device::device_reset()
{
m_skip = false;
- m_bdc = false;
- m_cend = false;
+ m_halt = false;
m_op = m_prev_op = 0;
do_branch(3, 7, 0);
m_prev_pc = m_pc;
+
+ // lcd is on (Bp on, BC off)
+ m_bp = true;
+ m_bc = false;
+
+ // y=0(bs), r=0
+}
+
+
+
+//-------------------------------------------------
+// interrupt/timer
+//-------------------------------------------------
+
+void sm510_base_device::wake_me_up()
+{
+ // in halt mode, wake up after 1S signal or K input
+ if (m_halt)
+ {
+ m_halt = false;
+ do_branch(1, 0, 0);
+
+ // note: official doc warns that Bl/Bm and the stack are undefined
+ // after waking up, but we leave it unchanged
+ }
+}
+
+void sm510_base_device::execute_set_input(int line, int state)
+{
+ if (line != 0)
+ return;
+}
+
+TIMER_CALLBACK_MEMBER(sm510_base_device::div_timer_cb)
+{
+ // no need to increment it by 1 everytime, since only the
+ // highest bits are accessible
+ m_div = (m_div + 0x800) & 0x7fff;
+
+ // 1S signal on overflow(falling edge of f1)
+ if (m_div == 0)
+ {
+ m_1s = true;
+ wake_me_up();
+ }
+
+ // schedule next timeout
+ m_div_timer->adjust(attotime::from_ticks(0x800, unscaled_clock()));
+}
+
+void sm510_base_device::reset_divider()
+{
+ m_div = 0;
+ m_div_timer->adjust(attotime::from_ticks(0x800, unscaled_clock()));
}
@@ -120,6 +182,13 @@ void sm510_base_device::increment_pc()
void sm510_base_device::execute_run()
{
+ // nothing to do if in halt mode
+ if (m_halt)
+ {
+ m_icount = 0;
+ return;
+ }
+
while (m_icount > 0)
{
// remember previous state
diff --git a/src/emu/cpu/sm510/sm510.h b/src/emu/cpu/sm510/sm510.h
index 7af7f1a7542..e8d345d2389 100644
--- a/src/emu/cpu/sm510/sm510.h
+++ b/src/emu/cpu/sm510/sm510.h
@@ -14,10 +14,18 @@
// I/O ports setup
-// 4-bit K input port
+// 4-bit K input port (pull-down)
#define MCFG_SM510_READ_K_CB(_devcb) \
sm510_base_device::set_read_k_callback(*device, DEVCB_##_devcb);
+// 1-bit BA input pin (pull-up)
+#define MCFG_SM510_READ_BA_CB(_devcb) \
+ sm510_base_device::set_read_ba_callback(*device, DEVCB_##_devcb);
+
+// 1-bit B(beta) input pin (pull-up)
+#define MCFG_SM510_READ_B_CB(_devcb) \
+ sm510_base_device::set_read_b_callback(*device, DEVCB_##_devcb);
+
// 8-bit S strobe output port
#define MCFG_SM510_WRITE_S_CB(_devcb) \
sm510_base_device::set_write_s_callback(*device, DEVCB_##_devcb);
@@ -43,11 +51,15 @@ public:
, m_datawidth(datawidth)
, m_stack_levels(stack_levels)
, m_read_k(*this)
+ , m_read_ba(*this)
+ , m_read_b(*this)
, m_write_s(*this)
{ }
// static configuration helpers
template<class _Object> static devcb_base &set_read_k_callback(device_t &device, _Object object) { return downcast<sm510_base_device &>(device).m_read_k.set_callback(object); }
+ template<class _Object> static devcb_base &set_read_ba_callback(device_t &device, _Object object) { return downcast<sm510_base_device &>(device).m_read_ba.set_callback(object); }
+ template<class _Object> static devcb_base &set_read_b_callback(device_t &device, _Object object) { return downcast<sm510_base_device &>(device).m_read_b.set_callback(object); }
template<class _Object> static devcb_base &set_write_s_callback(device_t &device, _Object object) { return downcast<sm510_base_device &>(device).m_write_s.set_callback(object); }
protected:
@@ -61,7 +73,7 @@ protected:
virtual UINT32 execute_min_cycles() const { return 1; }
virtual UINT32 execute_max_cycles() const { return 2; }
virtual UINT32 execute_input_lines() const { return 1; }
- //virtual void execute_set_input(int line, int state);
+ virtual void execute_set_input(int line, int state);
virtual void execute_run();
virtual void execute_one() { } // -> child class
@@ -89,6 +101,7 @@ protected:
int m_stack_levels;
UINT16 m_stack[2];
int m_icount;
+ emu_timer *m_div_timer;
UINT8 m_acc;
UINT8 m_bl;
@@ -97,15 +110,22 @@ protected:
bool m_skip;
UINT8 m_w;
UINT16 m_div;
- bool m_bdc;
- bool m_cend;
+ bool m_1s;
+ bool m_bp;
+ bool m_bc;
+ bool m_halt;
// i/o handlers
- devcb_read16 m_read_k;
+ devcb_read8 m_read_k;
+ devcb_read_line m_read_ba;
+ devcb_read_line m_read_b;
devcb_write8 m_write_s;
// misc internal helpers
void increment_pc();
+ TIMER_CALLBACK_MEMBER(div_timer_cb);
+ void wake_me_up();
+ virtual void reset_divider();
virtual void get_opcode_param() { } // -> child class
UINT8 ram_r();
diff --git a/src/emu/cpu/sm510/sm510op.c b/src/emu/cpu/sm510/sm510op.c
index 0e3238e1739..b704d18880d 100644
--- a/src/emu/cpu/sm510/sm510op.c
+++ b/src/emu/cpu/sm510/sm510op.c
@@ -161,7 +161,7 @@ void sm510_base_device::op_exc()
void sm510_base_device::op_bdc()
{
// BDC: enable LCD bleeder current with C
- m_bdc = (m_c != 0);
+ m_bc = (m_c != 0);
}
void sm510_base_device::op_exci()
@@ -217,8 +217,8 @@ void sm510_base_device::op_kta()
void sm510_base_device::op_atbp()
{
- // ATBP: output ACC to BP
- op_illegal();
+ // ATBP: output ACC to BP(internal LCD backplate signal)
+ m_bp = ((m_acc & 1) != 0);
}
void sm510_base_device::op_atl()
@@ -296,8 +296,8 @@ void sm510_base_device::op_sc()
void sm510_base_device::op_tb()
{
- // TB: x
- op_illegal();
+ // TB: skip next if B(beta) pin is set
+ m_skip = (m_read_b() != 0);
}
void sm510_base_device::op_tc()
@@ -326,32 +326,33 @@ void sm510_base_device::op_ta0()
void sm510_base_device::op_tabl()
{
- // TABL: skip next of ACC equals BL
+ // TABL: skip next if ACC equals BL
m_skip = (m_acc == m_bl);
}
void sm510_base_device::op_tis()
{
- // TIS: x
- op_illegal();
+ // TIS: skip next if 1S(gamma flag) is clear, reset it after
+ m_skip = !m_1s;
+ m_1s = false;
}
void sm510_base_device::op_tal()
{
- // TAL: x
- op_illegal();
+ // TB: skip next if BA pin is set
+ m_skip = (m_read_ba() != 0);
}
void sm510_base_device::op_tf1()
{
- // TF1: x
- op_illegal();
+ // TF1: skip next if divider F1(d14) is set
+ m_skip = ((m_div & 0x4000) != 0);
}
void sm510_base_device::op_tf4()
{
- // TF4: x
- op_illegal();
+ // TF4: skip next if divider F4(d11) is set
+ m_skip = ((m_div & 0x0800) != 0);
}
@@ -379,14 +380,14 @@ void sm510_base_device::op_skip()
void sm510_base_device::op_cend()
{
- // CEND: stop clock
- m_cend = true;
+ // CEND: stop clock (halt the cpu and go into low-power mode)
+ m_halt = true;
}
void sm510_base_device::op_idiv()
{
// IDIV: reset divider
- m_div = 0;
+ reset_divider();
}
void sm510_base_device::op_illegal()