mirror of
https://github.com/holub/mame
synced 2025-04-22 16:31:49 +03:00
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.
This commit is contained in:
parent
26ba4a362e
commit
8afcaaec3d
@ -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);
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -38,12 +38,6 @@
|
||||
#include "machine/z80daisy.h"
|
||||
#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;
|
||||
|
Loading…
Reference in New Issue
Block a user