mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
smc1102: added timer
This commit is contained in:
parent
dd1fe09ce3
commit
49166bd5c8
@ -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()
|
||||
|
@ -62,6 +62,7 @@ protected:
|
||||
virtual std::unique_ptr<util::disasm_interface> 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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -26,8 +26,8 @@ license:CC0-1.0
|
||||
</element>
|
||||
|
||||
<element name="lamp" defstate="0">
|
||||
<disk state="1"><color red="1.0" green="1.0" blue="1.0" /></disk>
|
||||
<disk state="0"><color red="0.25" green="0.25" blue="0.25" /></disk>
|
||||
<disk state="1"><color red="1.0" green="0.97" blue="0.9" /></disk>
|
||||
<disk state="0"><color red="0.3" green="0.3" blue="0.3" /></disk>
|
||||
</element>
|
||||
|
||||
<element name="hl" defstate="0">
|
||||
|
Loading…
Reference in New Issue
Block a user