summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author MooglyGuy <MooglyGuy@users.noreply.github.com>2022-04-26 14:53:54 +0200
committer Vas Crabb <vas@vastheman.com>2022-04-27 07:14:11 +1000
commit8afcaaec3daf4f9c51868da1d6bf38a86ea12773 (patch)
treeb7a50a6c4741ec9f6690ac06c7662372d355b1ab
parent26ba4a362e3ad433ad34b996d2b32d7cddc03e3c (diff)
Addressed performance loss from recent z80scc changes (#9629) [Ryan Holtz]
z80scc: Removed unused Z80SCC_USE_LOCAL_BRG and simplified WR15_ZEROCOUNT usage to reduce the likelihood of needless timer activation. mips3drc: Additional micro-optimizations to generate_checksum_block.
-rw-r--r--src/devices/cpu/mips/mips3drc.cpp25
-rw-r--r--src/devices/machine/z80scc.cpp99
-rw-r--r--src/devices/machine/z80scc.h17
3 files changed, 35 insertions, 106 deletions
diff --git a/src/devices/cpu/mips/mips3drc.cpp b/src/devices/cpu/mips/mips3drc.cpp
index db5faef8a97..9390c39cbc6 100644
--- a/src/devices/cpu/mips/mips3drc.cpp
+++ b/src/devices/cpu/mips/mips3drc.cpp
@@ -1164,14 +1164,15 @@ void mips3_device::generate_checksum_block(drcuml_block &block, compiler_state &
uint32_t sum = 0;
const void *base = m_prptr(seqhead->physpc);
const uint32_t data_bits_mask = (m_data_bits == 64 ? 4 : 0);
+ const uint32_t last_physpc = codelast->physpc;
uint32_t low_bits = (seqhead->physpc & data_bits_mask) ^ m_dword_xor;
UML_LOAD(block, I0, base, low_bits, SIZE_DWORD, SCALE_x1); // load i0,base,0,dword
sum += seqhead->opptr.l[0];
- if ((m_drcoptions & MIPS3DRC_EXTRA_INSTR_CHECK) && !(codelast->flags & OPFLAG_VIRTUAL_NOOP) && codelast->physpc != seqhead->physpc)
+ if ((m_drcoptions & MIPS3DRC_EXTRA_INSTR_CHECK) && !(codelast->flags & OPFLAG_VIRTUAL_NOOP) && last_physpc != seqhead->physpc)
{
- base = m_prptr(codelast->physpc);
+ base = m_prptr(last_physpc);
assert(base != nullptr);
- low_bits = (codelast->physpc & data_bits_mask) ^ m_dword_xor;
+ low_bits = (last_physpc & data_bits_mask) ^ m_dword_xor;
UML_LOAD(block, I1, base, low_bits, SIZE_DWORD, SCALE_x1); // load i1,base,dword
UML_ADD(block, I0, I0, I1); // add i0,i0,i1
sum += codelast->opptr.l[0];
@@ -1210,11 +1211,11 @@ void mips3_device::generate_checksum_block(drcuml_block &block, compiler_state &
if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP))
{
// Skip the last if it was already included above
- if (curdesc->physpc != codelast->physpc)
+ if (curdesc->physpc != last_physpc)
{
base = m_prptr(curdesc->physpc);
assert(base != nullptr);
- low_bits = (curdesc->physpc & (m_data_bits == 64 ? 4 : 0)) ^ m_dword_xor;
+ low_bits = (curdesc->physpc & data_bits_mask) ^ m_dword_xor;
UML_LOAD(block, I1, base, low_bits, SIZE_DWORD, SCALE_x1); // load i1,base,dword
UML_ADD(block, I0, I0, I1); // add i0,i0,i1
sum += curdesc->opptr.l[0];
@@ -1226,7 +1227,7 @@ void mips3_device::generate_checksum_block(drcuml_block &block, compiler_state &
{
base = m_prptr(curdesc->delay.first()->physpc);
assert(base != nullptr);
- low_bits = (curdesc->delay.first()->physpc & (m_data_bits == 64 ? 4 : 0)) ^ m_dword_xor;
+ low_bits = (curdesc->delay.first()->physpc & data_bits_mask) ^ m_dword_xor;
UML_LOAD(block, I1, base, low_bits, SIZE_DWORD, SCALE_x1); // load i1,base,dword
UML_ADD(block, I0, I0, I1); // add i0,i0,i1
sum += curdesc->delay.first()->opptr.l[0];
@@ -1243,11 +1244,11 @@ void mips3_device::generate_checksum_block(drcuml_block &block, compiler_state &
uml::code_label check_failed = compiler.labelnum++;
uml::code_label check_passed = compiler.labelnum++;
// Check the last instruction
- if (!(codelast->flags & OPFLAG_VIRTUAL_NOOP) && codelast->physpc != seqhead->physpc)
+ if (!(codelast->flags & OPFLAG_VIRTUAL_NOOP) && last_physpc != seqhead->physpc)
{
- base = m_prptr(codelast->physpc);
+ base = m_prptr(last_physpc);
assert(base != nullptr);
- low_bits = (codelast->physpc & (m_data_bits == 64 ? 4 : 0)) ^ m_dword_xor;
+ low_bits = (last_physpc & (m_data_bits == 64 ? 4 : 0)) ^ m_dword_xor;
UML_LOAD(block, I0, base, low_bits, SIZE_DWORD, SCALE_x1); // load i1,base,dword
sum = codelast->opptr.l[0];
UML_CMP(block, I0, sum); // cmp i0,sum
@@ -1255,7 +1256,7 @@ void mips3_device::generate_checksum_block(drcuml_block &block, compiler_state &
static const char text[] = "Last instr validation fail seq: %08X end: %08x\n";
UML_DMOV(block, mem(&m_core->format), (uintptr_t)text); // mov [format],text
UML_MOV(block, mem(&m_core->arg0), seqhead->pc);
- UML_MOV(block, mem(&m_core->arg1), codelast->physpc); // mov [arg0],desc->pc
+ UML_MOV(block, mem(&m_core->arg1), last_physpc); // mov [arg0],desc->pc
UML_CALLC(block, cfunc_printf_debug, this); // callc printf_debug
//UML_CALLC(block, cfunc_debug_break, this);
// Skip delay slot check
@@ -1263,7 +1264,7 @@ void mips3_device::generate_checksum_block(drcuml_block &block, compiler_state &
// Check the last instruction delay slot
UML_LABEL(block, check_second);
if (codelast->delay.first() != nullptr && !(codelast->delay.first()->flags & OPFLAG_VIRTUAL_NOOP)
- && codelast->physpc != seqhead->physpc)
+ && last_physpc != seqhead->physpc)
{
base = m_prptr(codelast->delay.first()->physpc);
assert(base != nullptr);
@@ -1275,7 +1276,7 @@ void mips3_device::generate_checksum_block(drcuml_block &block, compiler_state &
static const char text[] = "Last delay slot validation fail seq: %08X end: %08x\n";
UML_DMOV(block, mem(&m_core->format), (uintptr_t)text); // mov [format],text
UML_MOV(block, mem(&m_core->arg0), seqhead->pc);
- UML_MOV(block, mem(&m_core->arg1), codelast->physpc); // mov [arg0],desc->pc
+ UML_MOV(block, mem(&m_core->arg1), last_physpc); // mov [arg0],desc->pc
UML_CALLC(block, cfunc_printf_debug, this); // callc printf_debug
//UML_CALLC(block, cfunc_debug_break, this);
UML_JMP(block, check_failed);
diff --git a/src/devices/machine/z80scc.cpp b/src/devices/machine/z80scc.cpp
index c363357f551..d82ebd1bf91 100644
--- a/src/devices/machine/z80scc.cpp
+++ b/src/devices/machine/z80scc.cpp
@@ -136,14 +136,8 @@ baud rate:
#define FUNCNAME __PRETTY_FUNCTION__
#endif
-/* LOCAL _BRG is set in z80scc.h, local timer based BRG is not complete and will be removed if not needed for synchrounous mode */
-#if Z80SCC_USE_LOCAL_BRG
-#define START_BIT_HUNT 1
-#define START_BIT_ADJUST 1
-#else
#define START_BIT_HUNT 0
#define START_BIT_ADJUST 0
-#endif
#define CHANA_TAG "cha"
#define CHANB_TAG "chb"
@@ -1078,8 +1072,7 @@ void z80scc_channel::device_start()
m_rxc = 0x00;
m_txc = 0x00;
- // baudrate clocks and timers
- m_baudtimer = timer_alloc(TIMER_ID_BAUD);
+ m_baudtimer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(z80scc_channel::brg_tick), this));
// state saving
save_item(NAME(m_rr0));
@@ -1192,33 +1185,10 @@ void z80scc_channel::device_reset()
m_brg_counter = 0;
}
-void z80scc_channel::device_timer(emu_timer &timer, device_timer_id id, int param)
+TIMER_CALLBACK_MEMBER(z80scc_channel::brg_tick)
{
-// LOG("%s %d\n", FUNCNAME, id);
-
-
- switch(id)
- {
- case TIMER_ID_BAUD:
- {
- if (m_wr14 & WR14_BRG_ENABLE)
- {
-#if Z80SCC_USE_LOCAL_BRG
- txc_w(m_brg_counter & 1);
- rxc_w(m_brg_counter & 1);
-#endif
- m_brg_counter++; // Will just keep track of state in timer mode, not hardware counter value.
-
- if (m_wr15 & WR15_ZEROCOUNT)
- m_uart->trigger_interrupt(m_index, INT_EXTERNAL);
- }
- update_baudtimer();
- }
- break;
- default:
- logerror("Spurious timer %d event\n", id);
- break;
- }
+ // wr15 & WR15_ZEROCOUNT is implied by this timer being running at all
+ m_uart->trigger_interrupt(m_index, INT_EXTERNAL);
}
@@ -1619,14 +1589,6 @@ uint8_t z80scc_channel::do_sccreg_rr7()
return m_rr3;
}
-#if 0 // Short cutted in control_read()
-/* RR8 is the Receive Data register. */
-uint8_t z80scc_channel::do_sccreg_rr8()
-{
- return data_read():
-}
-#endif
-
/* (ESCC and 85C30 Only)
On the ESCC, Read Register 9 reflects the contents of Write Register 3 provided the Extended
Read option has been enabled. On the NMOS/CMOS version, a read to this location returns an image
@@ -2290,14 +2252,6 @@ void z80scc_channel::do_sccreg_wr14(uint8_t data)
{
brg_change = true;
LOG("%s: Misc Control Bits Baudrate generator enabled with %s source\n", FUNCNAME, (data & WR14_BRG_SOURCE) ? "PCLK" : "external clock");
- if (data & WR14_BRG_SOURCE) // Do we use the PCLK as baudrate source
- {
-#if Z80SCC_USE_LOCAL_BRG
-#if START_BIT_HUNT
- m_rcv_mode = RCV_SEEKING;
-#endif
-#endif
- }
}
else if ( (m_wr14 & WR14_BRG_ENABLE) && !(data & WR14_BRG_ENABLE) ) // baud rate generator being disabled?
{
@@ -2332,7 +2286,13 @@ void z80scc_channel::do_sccreg_wr15(uint8_t data)
LOG("CTS ints : %s\n", data & WR15_CTS ? WR15EN : "disabled");
LOG("Tx underr./EOM ints: %s\n", data & WR15_TX_EOM ? WR15NO : "disabled");
LOG("Break/Abort ints : %s\n", data & WR15_BREAK_ABORT ? WR15NO : "disabled");
+
+ const bool old_reg = m_wr15;
m_wr15 = data;
+ if ((old_reg & WR15_ZEROCOUNT) != (m_wr15 & WR15_ZEROCOUNT))
+ {
+ update_baudtimer();
+ }
}
void z80scc_channel::scc_register_write(uint8_t reg, uint8_t data)
@@ -2773,34 +2733,7 @@ void z80scc_channel::sync_w(int state)
//-------------------------------------------------
void z80scc_channel::rxc_w(int state)
{
-/* Support for external clock as source for BRG yet to be finished */
-#if 0
- //LOG("Receiver Clock Pulse\n");
- if ( ((m_wr3 & WR3_RX_ENABLE) | (m_wr5 & WR5_TX_ENABLE)) && m_wr14 & WR14_BRG_ENABLE)
- {
- if (!(m_wr14 & WR14_BRG_SOURCE)) // Is the Baud rate Generator driven by RTxC?
- {
- printf("x");
- if (!m_brg_counter) // Zero crossing?!
- {
- printf(".");
- m_brg_counter = m_wr13 << 8 | m_wr12; // Reload BRG counter
- if ((m_wr11 & WR11_TRACLK_SRC_MASK) == WR11_TRACLK_SRC_BR) // Is transmitt clock driven by BRG?
- {
- printf("+");
- txc_w(state);
- }
- }
- else
- {
- m_brg_counter--;
- if ((m_wr11 & WR11_RCVCLK_SRC_MASK) == WR11_RCVCLK_SRC_BR) // Is receive clock driven by BRG and not zero cross
- return;
- }
- }
- }
-#endif
-
+ /* Support for external clock as source for BRG has not been added */
if (m_wr3 & WR3_RX_ENABLE)
{
int clocks = get_clock_mode();
@@ -2904,7 +2837,15 @@ void z80scc_channel::update_baudtimer()
unsigned int source = (m_index == z80scc_device::CHANNEL_A) ? m_uart->m_rxca : m_uart->m_rxcb;
rate = source / (brg_const == 0 ? 1 : brg_const);
}
- m_baudtimer->adjust(attotime::from_hz(rate));
+
+ if (m_wr15 & WR15_ZEROCOUNT)
+ {
+ m_baudtimer->adjust(attotime::from_hz(rate), 0, attotime::from_hz(rate));
+ }
+ else
+ {
+ m_baudtimer->adjust(attotime::never);
+ }
}
else
{
diff --git a/src/devices/machine/z80scc.h b/src/devices/machine/z80scc.h
index 31a80aa69b7..a993d831ce0 100644
--- a/src/devices/machine/z80scc.h
+++ b/src/devices/machine/z80scc.h
@@ -39,12 +39,6 @@
#include "diserial.h"
//**************************************************************************
-// DEVICE CONFIGURATION MACROS
-//**************************************************************************
-
-#define Z80SCC_USE_LOCAL_BRG 0
-
-//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
@@ -64,7 +58,6 @@ public:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
- virtual void device_timer(emu_timer &timer, device_timer_id id, int param) override;
// device_serial_interface overrides
virtual void tra_callback() override;
@@ -129,6 +122,8 @@ public:
void txc_w(int state);
void sync_w(int state);
+ TIMER_CALLBACK_MEMBER(brg_tick);
+
int m_rxc;
int m_txc;
@@ -237,14 +232,6 @@ protected:
REG_WR15_EXT_ST_INT_CTRL= 15
};
- enum
- {
- TIMER_ID_BAUD,
- TIMER_ID_XTAL,
- TIMER_ID_RTXC,
- TIMER_ID_TRXC
- };
-
emu_timer *m_baudtimer;
uint16_t m_brg_counter;
unsigned int m_brg_rate;