From 49166bd5c8b976a30e4e001b0513f18618eb1f5e Mon Sep 17 00:00:00 2001 From: hap Date: Thu, 20 Apr 2023 19:28:57 +0200 Subject: smc1102: added timer --- src/devices/cpu/tms1000/smc1102.cpp | 61 +++++++++++++++++++++++++++++++--- src/devices/cpu/tms1000/smc1102.h | 6 ++++ src/devices/cpu/tms1000/tms1k_base.cpp | 10 +++--- src/devices/cpu/tms1000/tms1k_base.h | 2 +- src/mame/layout/starwlb.lay | 4 +-- 5 files changed, 70 insertions(+), 13 deletions(-) diff --git a/src/devices/cpu/tms1000/smc1102.cpp b/src/devices/cpu/tms1000/smc1102.cpp index 00551ec27da..6e6b84ac7ec 100644 --- a/src/devices/cpu/tms1000/smc1102.cpp +++ b/src/devices/cpu/tms1000/smc1102.cpp @@ -19,10 +19,8 @@ SMC1112 die notes (SMC1102 is assumed to be the same): - no output PLA TODO: -- each opcode is 4 cycles instead of 6 - LCD refresh timing is unknown - add (micro)instructions PLA if it turns out it can be customized -- add timer - add halt opcode */ @@ -72,6 +70,11 @@ void smc1102_cpu_device::device_start() m_selin = 0; m_k_line = false; + m_div = 0; + m_timer = 0; + m_timeout = false; + m_tmset = 0; + memset(m_stack, 0, sizeof(m_stack)); m_sp = 0; m_pb_stack = 0; @@ -87,6 +90,11 @@ void smc1102_cpu_device::device_start() save_item(NAME(m_selin)); save_item(NAME(m_k_line)); + save_item(NAME(m_div)); + save_item(NAME(m_timer)); + save_item(NAME(m_timeout)); + save_item(NAME(m_tmset)); + save_item(NAME(m_stack)); save_item(NAME(m_sp)); save_item(NAME(m_pb_stack)); @@ -102,6 +110,7 @@ void smc1102_cpu_device::device_reset() m_inten = false; m_selin = 0; + m_timeout = false; // changed/added fixed instructions (mostly handled in op_extra) m_fixed_decode[0x0a] = F_EXTRA; @@ -186,11 +195,12 @@ void smc1102_cpu_device::read_opcode() } // check interrupts (blocked after INTEN) - if (m_inten && m_opcode != 0x74) + if (m_opcode != 0x74) { - bool taken = (m_selin & 2) ? false : m_k_line; + const bool taken = (m_selin & 2) ? m_timeout : m_k_line; + m_timeout = false; - if (taken) + if (m_inten && taken) { interrupt(); return; @@ -223,6 +233,46 @@ void smc1102_cpu_device::interrupt() m_inten = false; } +void smc1102_cpu_device::execute_run() +{ + while (m_icount > 0) + { + m_icount--; + + // decrement timer + m_div = (m_div + 1) & 0x1fff; + const u16 tmask = (m_selin & 1) ? 0x1ff : 0x1fff; + if ((m_div & tmask) == 0) + { + m_timer = (m_timer - 1) & 0xf; + if (m_timer == 0) + { + m_timer = m_tmset; + m_timeout = true; + } + } + + // 4 cycles per opcode instead of 6 + switch (m_subcycle) + { + case 2: + execute_one(2); + execute_one(3); + break; + + case 3: + execute_one(4); + execute_one(5); + break; + + default: + execute_one(m_subcycle); + break; + } + m_subcycle = (m_subcycle + 1) & 3; + } +} + // opcode deviations void smc1102_cpu_device::op_call() @@ -283,6 +333,7 @@ void smc1102_cpu_device::op_selin() void smc1102_cpu_device::op_tmset() { // TMSET: transfer A to timer latch + m_tmset = m_a; } void smc1102_cpu_device::op_halt() diff --git a/src/devices/cpu/tms1000/smc1102.h b/src/devices/cpu/tms1000/smc1102.h index 1727e6a32b8..648d637544d 100644 --- a/src/devices/cpu/tms1000/smc1102.h +++ b/src/devices/cpu/tms1000/smc1102.h @@ -62,6 +62,7 @@ protected: virtual std::unique_ptr create_disassembler() override; virtual u32 decode_micro(offs_t offset) override; + virtual void execute_run() override; virtual void read_opcode() override; void interrupt(); @@ -92,6 +93,11 @@ protected: u8 m_selin; bool m_k_line; + u16 m_div; + u8 m_timer; + bool m_timeout; + u8 m_tmset; + // stack u16 m_stack[4]; u8 m_sp; diff --git a/src/devices/cpu/tms1000/tms1k_base.cpp b/src/devices/cpu/tms1000/tms1k_base.cpp index e6eac330f48..28ef3121199 100644 --- a/src/devices/cpu/tms1000/tms1k_base.cpp +++ b/src/devices/cpu/tms1000/tms1k_base.cpp @@ -598,9 +598,9 @@ void tms1k_base_device::op_tpc() // execute //------------------------------------------------- -void tms1k_base_device::execute_one() +void tms1k_base_device::execute_one(int subcycle) { - switch (m_subcycle) + switch (subcycle) { case 0: // fetch: rom address 1/2 @@ -735,8 +735,6 @@ void tms1k_base_device::execute_one() // execute: br/call 1/2 break; } - - m_subcycle = (m_subcycle + 1) % 6; } void tms1k_base_device::execute_run() @@ -744,6 +742,8 @@ void tms1k_base_device::execute_run() while (m_icount > 0) { m_icount--; - execute_one(); + + execute_one(m_subcycle); + m_subcycle = (m_subcycle + 1) % 6; } } diff --git a/src/devices/cpu/tms1000/tms1k_base.h b/src/devices/cpu/tms1000/tms1k_base.h index fa86a0dd86a..01437ba9d4d 100644 --- a/src/devices/cpu/tms1000/tms1k_base.h +++ b/src/devices/cpu/tms1000/tms1k_base.h @@ -62,7 +62,7 @@ protected: virtual u32 execute_min_cycles() const noexcept override { return 1; } virtual u32 execute_max_cycles() const noexcept override { return 1; } virtual void execute_run() override; - virtual void execute_one(); + virtual void execute_one(int subcycle); // device_memory_interface overrides virtual space_config_vector memory_space_config() const override; diff --git a/src/mame/layout/starwlb.lay b/src/mame/layout/starwlb.lay index ffc7f50180c..9e401479434 100644 --- a/src/mame/layout/starwlb.lay +++ b/src/mame/layout/starwlb.lay @@ -26,8 +26,8 @@ license:CC0-1.0 - - + + -- cgit v1.2.3