mirror of
https://github.com/holub/mame
synced 2025-04-17 22:13:04 +03:00
-cpu/e132xs: Log bus control and memory control setup.
-cpu/drcbearm64.cpp: Simplified logic for choosing optimal AND strategy.
This commit is contained in:
parent
4e80f6e0d9
commit
7efe37938f
@ -38100,7 +38100,7 @@ license:CC0-1.0
|
|||||||
<description>German Vocabulary Games (version 1.1) (4am crack)</description>
|
<description>German Vocabulary Games (version 1.1) (4am crack)</description>
|
||||||
<year>1984</year>
|
<year>1984</year>
|
||||||
<publisher>Intellectual Software</publisher>
|
<publisher>Intellectual Software</publisher>
|
||||||
<info name="programmer" value="Frank Flint " />
|
<info name="programmer" value="Frank Flint" />
|
||||||
<info name="usage" value="Requires an Apple ][+ or later." />
|
<info name="usage" value="Requires an Apple ][+ or later." />
|
||||||
<info name="version" value="1.1" />
|
<info name="version" value="1.1" />
|
||||||
<sharedfeat name="compatibility" value="A2P,A2E,A2EE,A2C,A2GS" />
|
<sharedfeat name="compatibility" value="A2P,A2E,A2EE,A2C,A2GS" />
|
||||||
|
@ -444,8 +444,8 @@ private:
|
|||||||
static be_parameter make_memory(void *base) { return be_parameter(PTYPE_MEMORY, reinterpret_cast<be_parameter_value>(base)); }
|
static be_parameter make_memory(void *base) { return be_parameter(PTYPE_MEMORY, reinterpret_cast<be_parameter_value>(base)); }
|
||||||
static be_parameter make_memory(const void *base) { return be_parameter(PTYPE_MEMORY, reinterpret_cast<be_parameter_value>(const_cast<void *>(base))); }
|
static be_parameter make_memory(const void *base) { return be_parameter(PTYPE_MEMORY, reinterpret_cast<be_parameter_value>(const_cast<void *>(base))); }
|
||||||
|
|
||||||
bool operator==(const be_parameter &rhs) const { return (m_type == rhs.m_type && m_value == rhs.m_value); }
|
bool operator==(const be_parameter &rhs) const { return (m_type == rhs.m_type) && (m_value == rhs.m_value); }
|
||||||
bool operator!=(const be_parameter &rhs) const { return (m_type != rhs.m_type || m_value != rhs.m_value); }
|
bool operator!=(const be_parameter &rhs) const { return (m_type != rhs.m_type) || (m_value != rhs.m_value); }
|
||||||
|
|
||||||
be_parameter_type type() const { return m_type; }
|
be_parameter_type type() const { return m_type; }
|
||||||
uint64_t immediate() const { assert(m_type == PTYPE_IMMEDIATE); return m_value; }
|
uint64_t immediate() const { assert(m_type == PTYPE_IMMEDIATE); return m_value; }
|
||||||
@ -4084,6 +4084,12 @@ void drcbe_arm64::op_and(a64::Assembler &a, const uml::instruction &inst)
|
|||||||
be_parameter src1p(*this, inst.param(1), PTYPE_MRI);
|
be_parameter src1p(*this, inst.param(1), PTYPE_MRI);
|
||||||
be_parameter src2p(*this, inst.param(2), PTYPE_MRI);
|
be_parameter src2p(*this, inst.param(2), PTYPE_MRI);
|
||||||
|
|
||||||
|
if (src1p.is_immediate() || (dstp.is_int_register() && (dstp == src2p)))
|
||||||
|
{
|
||||||
|
using std::swap;
|
||||||
|
swap(src1p, src2p);
|
||||||
|
}
|
||||||
|
|
||||||
const a64::Gp dst = dstp.select_register(TEMP_REG3, inst.size());
|
const a64::Gp dst = dstp.select_register(TEMP_REG3, inst.size());
|
||||||
|
|
||||||
if (src1p.is_immediate_value(0) || src2p.is_immediate_value(0))
|
if (src1p.is_immediate_value(0) || src2p.is_immediate_value(0))
|
||||||
@ -4100,13 +4106,6 @@ void drcbe_arm64::op_and(a64::Assembler &a, const uml::instruction &inst)
|
|||||||
if (inst.flags())
|
if (inst.flags())
|
||||||
a.tst(dst, dst);
|
a.tst(dst, dst);
|
||||||
}
|
}
|
||||||
else if (src1p.is_immediate() && is_valid_immediate_mask(src1p.immediate(), inst.size()))
|
|
||||||
{
|
|
||||||
const a64::Gp src2 = src2p.select_register(dst, inst.size());
|
|
||||||
mov_reg_param(a, inst.size(), src2, src2p);
|
|
||||||
|
|
||||||
a.emit(opcode, dst, src2, src1p.immediate());
|
|
||||||
}
|
|
||||||
else if (src2p.is_immediate() && is_valid_immediate_mask(src2p.immediate(), inst.size()))
|
else if (src2p.is_immediate() && is_valid_immediate_mask(src2p.immediate(), inst.size()))
|
||||||
{
|
{
|
||||||
const a64::Gp src1 = src1p.select_register(dst, inst.size());
|
const a64::Gp src1 = src1p.select_register(dst, inst.size());
|
||||||
@ -4114,13 +4113,6 @@ void drcbe_arm64::op_and(a64::Assembler &a, const uml::instruction &inst)
|
|||||||
|
|
||||||
a.emit(opcode, dst, src1, src2p.immediate());
|
a.emit(opcode, dst, src1, src2p.immediate());
|
||||||
}
|
}
|
||||||
else if ((inst.size() == 8) && src1p.is_immediate() && is_valid_immediate_mask(src1p.immediate(), 4) && (!inst.flags() || !BIT(src1p.immediate(), 31)))
|
|
||||||
{
|
|
||||||
const a64::Gp src2 = src2p.select_register(dst, inst.size());
|
|
||||||
mov_reg_param(a, inst.size(), src2, src2p);
|
|
||||||
|
|
||||||
a.emit(opcode, dst.w(), src2.w(), src1p.immediate());
|
|
||||||
}
|
|
||||||
else if ((inst.size() == 8) && src2p.is_immediate() && is_valid_immediate_mask(src2p.immediate(), 4) && (!inst.flags() || !BIT(src2p.immediate(), 31)))
|
else if ((inst.size() == 8) && src2p.is_immediate() && is_valid_immediate_mask(src2p.immediate(), 4) && (!inst.flags() || !BIT(src2p.immediate(), 31)))
|
||||||
{
|
{
|
||||||
const a64::Gp src1 = src1p.select_register(dst, inst.size());
|
const a64::Gp src1 = src1p.select_register(dst, inst.size());
|
||||||
|
@ -24,6 +24,7 @@ enum
|
|||||||
{
|
{
|
||||||
PC_REGISTER = 0,
|
PC_REGISTER = 0,
|
||||||
SR_REGISTER = 1,
|
SR_REGISTER = 1,
|
||||||
|
FER_REGISTER = 2,
|
||||||
SP_REGISTER = 18,
|
SP_REGISTER = 18,
|
||||||
UB_REGISTER = 19,
|
UB_REGISTER = 19,
|
||||||
BCR_REGISTER = 20,
|
BCR_REGISTER = 20,
|
||||||
|
@ -34,9 +34,11 @@
|
|||||||
- All instructions should clear the H flag (not just MOV/MOVI)
|
- All instructions should clear the H flag (not just MOV/MOVI)
|
||||||
- Fix behaviour of branches in delay slots
|
- Fix behaviour of branches in delay slots
|
||||||
- Many wrong cycle counts
|
- Many wrong cycle counts
|
||||||
|
- Prevent reading write-only BCR, TPR, FCR and MCR
|
||||||
|
- IRAM selection should happen before EA calculation
|
||||||
- No emulation of memory access latency and pipleline
|
- No emulation of memory access latency and pipleline
|
||||||
- Should a zero bit shift clear C or leave it unchanged?
|
- Should a zero bit shift clear C or leave it unchanged?
|
||||||
- What actually happens on trying to load memory to PC or SR?
|
- What actually happens on trying to load to PC, SR, G14 or G15?
|
||||||
- Verify register wrapping with sregf/dregf on hardware
|
- Verify register wrapping with sregf/dregf on hardware
|
||||||
- Tracing doesn't work properly
|
- Tracing doesn't work properly
|
||||||
DRC does not generate trace exceptions on branch or return
|
DRC does not generate trace exceptions on branch or return
|
||||||
@ -370,17 +372,16 @@ void hyperstone_device::adjust_timer_interrupt()
|
|||||||
if (cycles_until_next_clock == 0)
|
if (cycles_until_next_clock == 0)
|
||||||
cycles_until_next_clock = (uint64_t)(1 << m_core->clck_scale);
|
cycles_until_next_clock = (uint64_t)(1 << m_core->clck_scale);
|
||||||
|
|
||||||
/* special case: if we have a change pending, set a timer to fire then */
|
|
||||||
if (TPR & 0x80000000)
|
if (TPR & 0x80000000)
|
||||||
{
|
{
|
||||||
|
// special case: if we have a change pending, set a timer to fire then
|
||||||
uint64_t clocks_until_int = m_core->tr_clocks_per_tick - (clocks_since_base % m_core->tr_clocks_per_tick);
|
uint64_t clocks_until_int = m_core->tr_clocks_per_tick - (clocks_since_base % m_core->tr_clocks_per_tick);
|
||||||
uint64_t cycles_until_int = (clocks_until_int << m_core->clck_scale) + cycles_until_next_clock;
|
uint64_t cycles_until_int = (clocks_until_int << m_core->clck_scale) + cycles_until_next_clock;
|
||||||
m_timer->adjust(cycles_to_attotime(cycles_until_int + 1), 1);
|
m_timer->adjust(cycles_to_attotime(cycles_until_int + 1), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* else if the timer interrupt is enabled, configure it to fire at the appropriate time */
|
|
||||||
else if (!(FCR & 0x00800000))
|
else if (!(FCR & 0x00800000))
|
||||||
{
|
{
|
||||||
|
// else if the timer interrupt is enabled, configure it to fire at the appropriate time
|
||||||
uint32_t curtr = m_core->tr_base_value + (clocks_since_base / m_core->tr_clocks_per_tick);
|
uint32_t curtr = m_core->tr_base_value + (clocks_since_base / m_core->tr_clocks_per_tick);
|
||||||
uint32_t delta = TCR - curtr;
|
uint32_t delta = TCR - curtr;
|
||||||
if (delta > 0x80000000)
|
if (delta > 0x80000000)
|
||||||
@ -395,10 +396,108 @@ void hyperstone_device::adjust_timer_interrupt()
|
|||||||
m_timer->adjust(cycles_to_attotime(cycles_until_int));
|
m_timer->adjust(cycles_to_attotime(cycles_until_int));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* otherwise, disable the timer */
|
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
// otherwise, disable the timer
|
||||||
m_timer->adjust(attotime::never);
|
m_timer->adjust(attotime::never);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void hyperstone_device::update_bus_control()
|
||||||
|
{
|
||||||
|
const uint32_t val = m_core->global_regs[BCR_REGISTER];
|
||||||
|
|
||||||
|
LOG("%s: Set BCR = 0x%08x\n", machine().describe_context(), val);
|
||||||
|
if (BIT(m_core->global_regs[MCR_REGISTER], 21))
|
||||||
|
{
|
||||||
|
LOG("MEM0 access time %d cycles, hold time %d cycles, setup time %d cycles\n",
|
||||||
|
BIT(val, 16, 4) + 1,
|
||||||
|
BIT(val, 11, 3),
|
||||||
|
BIT(val, 14, 2));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char const *const refresh[8] = {
|
||||||
|
"every 256 prescaler time units",
|
||||||
|
"every 128 prescaler time units",
|
||||||
|
"every 64 prescaler time units",
|
||||||
|
"every 32 prescaler time units",
|
||||||
|
"every 16 prescaler time units",
|
||||||
|
"every 8 prescaler time units",
|
||||||
|
"every 4 prescaler time units",
|
||||||
|
"disabled" };
|
||||||
|
char const *const page[8] = { "64K", "32K", "16K", "8K", "4K", "2K", "1K", "512" };
|
||||||
|
LOG("MEM0 RAS precharge time %d cycles, RAS to CAS delay time %d cycles, CAS access time %d cycles, %s byte rows, refresh %s\n",
|
||||||
|
BIT(val, 18, 2) + 1 + (BIT(m_core->global_regs[MCR_REGISTER], 8) * 2),
|
||||||
|
BIT(val, 14, 2) + 1,
|
||||||
|
BIT(val, 16, 2) + 1 + (BIT(m_core->global_regs[MCR_REGISTER], 8) * 2),
|
||||||
|
page[BIT(val, 4, 3)],
|
||||||
|
refresh[BIT(val, 11, 3)]);
|
||||||
|
}
|
||||||
|
LOG("MEM1 access time %d cycles, hold time %d cycles\n",
|
||||||
|
BIT(val, 20, 3) + 1,
|
||||||
|
BIT(val, 22) + BIT(val, 23));
|
||||||
|
LOG("MEM2 access time %d cycles, hold time %d cycles, setup time %d cycles\n",
|
||||||
|
BIT(val, 24, 4) + 1,
|
||||||
|
BIT(val, 0, 3),
|
||||||
|
BIT(val, 3));
|
||||||
|
LOG("MEM3 access time %d cycles, hold time %d cycles, setup time %d cycles\n",
|
||||||
|
BIT(val, 28, 4) + 1,
|
||||||
|
BIT(val, 8, 3),
|
||||||
|
BIT(val, 7));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void hyperstone_device::update_memory_control()
|
||||||
|
{
|
||||||
|
const uint32_t val = m_core->global_regs[MCR_REGISTER];
|
||||||
|
|
||||||
|
static char const *const entrymap[8] = { "MEM0", "MEM1", "MEM2", "IRAM", "reserved", "reserved", "reserved", "MEM3" };
|
||||||
|
LOG("%s: Set MCR = 0x%08x entry map in %s\n",
|
||||||
|
machine().describe_context(),
|
||||||
|
val,
|
||||||
|
entrymap[BIT(val, 12, 3)]);
|
||||||
|
|
||||||
|
static char const *const size[4] = { "32 bit", "reserved", "16 bit", "8 bit" };
|
||||||
|
if (BIT(val, 21))
|
||||||
|
{
|
||||||
|
LOG("MEM0 %s, bus hold break %s, parity %s, byte %s\n",
|
||||||
|
size[BIT(val, 0, 2)], // MEM0 bus size
|
||||||
|
BIT(val, 8) ? "disabled" : "enabled", // MEM0 bus hold break
|
||||||
|
BIT(val, 28) ? "disabled" : "enabled", // MEM0 parity
|
||||||
|
BIT(val, 15) ? "strobe" : "enable"); // MEM0 byte mode
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
static char const *const dramtype[4] = { "S", "S", "EDO ", "fast page " };
|
||||||
|
LOG("MEM0 %s %sDRAM, hold time %s, parity %s\n",
|
||||||
|
size[BIT(val, 0, 2)], // MEM0 bus size
|
||||||
|
dramtype[bitswap<2>(val, 15, 22)], // MEM0 DRAM type
|
||||||
|
BIT(val, 8) ? "1 cycle" : "0 cycles", // MEM0 bus hold
|
||||||
|
BIT(val, 28) ? "disabled" : "enabled", // MEM0 parity
|
||||||
|
BIT(val, 15) ? "strobe" : "enable"); // MEM0 byte mode
|
||||||
|
}
|
||||||
|
LOG("MEM1 %s, bus hold break %s, parity %s, byte %s\n",
|
||||||
|
size[BIT(val, 2, 2)], // MEM1 bus size
|
||||||
|
BIT(val, 9) ? "disabled" : "enabled", // MEM1 bus hold break
|
||||||
|
BIT(val, 29) ? "disabled" : "enabled", // MEM1 parity
|
||||||
|
BIT(val, 19) ? "strobe" : "enable"); // MEM1 byte mode
|
||||||
|
LOG("MEM2 %s, bus hold break %s, parity %s, byte %s, wait %s\n",
|
||||||
|
size[BIT(val, 4, 2)], // MEM2 bus size
|
||||||
|
BIT(val, 10) ? "disabled" : "enabled", // MEM2 bus hold break
|
||||||
|
BIT(val, 30) ? "disabled" : "enabled", // MEM2 parity
|
||||||
|
BIT(val, 23) ? "strobe" : "enable", // MEM2 byte mode
|
||||||
|
BIT(val, 26) ? "disabled" : "enabled"); // MEM2 wait
|
||||||
|
LOG("MEM3 %s, bus hold break %s, parity %s\n",
|
||||||
|
size[BIT(val, 6, 2)], // MEM3 bus size
|
||||||
|
BIT(val, 11) ? "disabled" : "enabled", // MEM3 bus hold break
|
||||||
|
BIT(val, 31) ? "disabled" : "enabled"); // MEM3 parity
|
||||||
|
|
||||||
|
|
||||||
|
// bits 14..12 EntryTableMap
|
||||||
|
const int which = (val & 0x7000) >> 12;
|
||||||
|
assert(which < 4 || which == 7);
|
||||||
|
m_core->trap_entry = s_trap_entries[which];
|
||||||
}
|
}
|
||||||
|
|
||||||
TIMER_CALLBACK_MEMBER( hyperstone_device::timer_callback )
|
TIMER_CALLBACK_MEMBER( hyperstone_device::timer_callback )
|
||||||
@ -460,7 +559,7 @@ uint32_t hyperstone_device::get_global_register(uint8_t code)
|
|||||||
*/
|
*/
|
||||||
if (code == TR_REGISTER)
|
if (code == TR_REGISTER)
|
||||||
{
|
{
|
||||||
/* it is common to poll this in a loop */
|
// it is common to poll this in a loop
|
||||||
if (m_core->icount > m_core->tr_clocks_per_tick / 2)
|
if (m_core->icount > m_core->tr_clocks_per_tick / 2)
|
||||||
m_core->icount -= m_core->tr_clocks_per_tick / 2;
|
m_core->icount -= m_core->tr_clocks_per_tick / 2;
|
||||||
compute_tr();
|
compute_tr();
|
||||||
@ -517,6 +616,7 @@ void hyperstone_device::set_global_register(uint8_t code, uint32_t val)
|
|||||||
return;
|
return;
|
||||||
case BCR_REGISTER:
|
case BCR_REGISTER:
|
||||||
m_core->global_regs[code] = val;
|
m_core->global_regs[code] = val;
|
||||||
|
update_bus_control();
|
||||||
return;
|
return;
|
||||||
case TPR_REGISTER:
|
case TPR_REGISTER:
|
||||||
m_core->global_regs[code] = val;
|
m_core->global_regs[code] = val;
|
||||||
@ -551,14 +651,9 @@ void hyperstone_device::set_global_register(uint8_t code, uint32_t val)
|
|||||||
m_core->global_regs[code] = val;
|
m_core->global_regs[code] = val;
|
||||||
return;
|
return;
|
||||||
case MCR_REGISTER:
|
case MCR_REGISTER:
|
||||||
{
|
|
||||||
// bits 14..12 EntryTableMap
|
|
||||||
const int which = (val & 0x7000) >> 12;
|
|
||||||
assert(which < 4 || which == 7);
|
|
||||||
m_core->trap_entry = s_trap_entries[which];
|
|
||||||
m_core->global_regs[code] = val;
|
m_core->global_regs[code] = val;
|
||||||
|
update_memory_control();
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
case 28:
|
case 28:
|
||||||
case 29:
|
case 29:
|
||||||
case 30:
|
case 30:
|
||||||
@ -1014,19 +1109,20 @@ void hyperstone_device::device_start()
|
|||||||
const uint32_t umlflags = 0;
|
const uint32_t umlflags = 0;
|
||||||
m_drcuml = std::make_unique<drcuml_state>(*this, m_cache, umlflags, 4, 32, 1);
|
m_drcuml = std::make_unique<drcuml_state>(*this, m_cache, umlflags, 4, 32, 1);
|
||||||
|
|
||||||
// add UML symbols-
|
// add UML symbols
|
||||||
m_drcuml->symbol_add(&m_core->global_regs[PC_REGISTER], sizeof(m_core->global_regs[PC_REGISTER]), "pc");
|
m_drcuml->symbol_add(&m_core->global_regs[PC_REGISTER], sizeof(m_core->global_regs[PC_REGISTER]), "pc");
|
||||||
m_drcuml->symbol_add(&m_core->global_regs[SR_REGISTER], sizeof(m_core->global_regs[SR_REGISTER]), "sr");
|
m_drcuml->symbol_add(&m_core->global_regs[SR_REGISTER], sizeof(m_core->global_regs[SR_REGISTER]), "sr");
|
||||||
m_drcuml->symbol_add(&m_core->global_regs[SP_REGISTER], sizeof(m_core->global_regs[SP_REGISTER]), "sp");
|
m_drcuml->symbol_add(&m_core->global_regs[FER_REGISTER], sizeof(m_core->global_regs[FER_REGISTER]), "fer");
|
||||||
m_drcuml->symbol_add(&m_core->global_regs[UB_REGISTER], sizeof(m_core->global_regs[UB_REGISTER]), "ub");
|
m_drcuml->symbol_add(&m_core->global_regs[SP_REGISTER], sizeof(m_core->global_regs[SP_REGISTER]), "sp");
|
||||||
m_drcuml->symbol_add(&m_core->trap_entry, sizeof(m_core->trap_entry), "trap_entry");
|
m_drcuml->symbol_add(&m_core->global_regs[UB_REGISTER], sizeof(m_core->global_regs[UB_REGISTER]), "ub");
|
||||||
m_drcuml->symbol_add(&m_core->delay_pc, sizeof(m_core->delay_pc), "delay_pc");
|
m_drcuml->symbol_add(&m_core->trap_entry, sizeof(m_core->trap_entry), "trap_entry");
|
||||||
m_drcuml->symbol_add(&m_core->delay_slot, sizeof(m_core->delay_slot), "delay_slot");
|
m_drcuml->symbol_add(&m_core->delay_pc, sizeof(m_core->delay_pc), "delay_pc");
|
||||||
m_drcuml->symbol_add(&m_core->delay_slot_taken, sizeof(m_core->delay_slot_taken), "delay_slot_taken");
|
m_drcuml->symbol_add(&m_core->delay_slot, sizeof(m_core->delay_slot), "delay_slot");
|
||||||
m_drcuml->symbol_add(&m_core->intblock, sizeof(m_core->intblock), "intblock");
|
m_drcuml->symbol_add(&m_core->delay_slot_taken, sizeof(m_core->delay_slot_taken), "delay_slot_taken");
|
||||||
m_drcuml->symbol_add(&m_core->arg0, sizeof(m_core->arg0), "arg0");
|
m_drcuml->symbol_add(&m_core->intblock, sizeof(m_core->intblock), "intblock");
|
||||||
m_drcuml->symbol_add(&m_core->arg1, sizeof(m_core->arg1), "arg1");
|
m_drcuml->symbol_add(&m_core->arg0, sizeof(m_core->arg0), "arg0");
|
||||||
m_drcuml->symbol_add(&m_core->icount, sizeof(m_core->icount), "icount");
|
m_drcuml->symbol_add(&m_core->arg1, sizeof(m_core->arg1), "arg1");
|
||||||
|
m_drcuml->symbol_add(&m_core->icount, sizeof(m_core->icount), "icount");
|
||||||
|
|
||||||
char buf[4];
|
char buf[4];
|
||||||
buf[3] = '\0';
|
buf[3] = '\0';
|
||||||
@ -1227,9 +1323,9 @@ void hyperstone_device::device_reset()
|
|||||||
|
|
||||||
m_core->trap_entry = s_trap_entries[E132XS_ENTRY_MEM3]; // default entry point @ MEM3
|
m_core->trap_entry = s_trap_entries[E132XS_ENTRY_MEM3]; // default entry point @ MEM3
|
||||||
|
|
||||||
set_global_register(BCR_REGISTER, ~0);
|
set_global_register(BCR_REGISTER, ~uint32_t(0));
|
||||||
set_global_register(MCR_REGISTER, ~0);
|
set_global_register(MCR_REGISTER, ~uint32_t(0));
|
||||||
set_global_register(FCR_REGISTER, ~0);
|
set_global_register(FCR_REGISTER, ~uint32_t(0));
|
||||||
set_global_register(TPR_REGISTER, 0xc000000);
|
set_global_register(TPR_REGISTER, 0xc000000);
|
||||||
|
|
||||||
PC = get_trap_addr(TRAPNO_RESET);
|
PC = get_trap_addr(TRAPNO_RESET);
|
||||||
|
@ -258,6 +258,8 @@ protected:
|
|||||||
void update_timer_prescale();
|
void update_timer_prescale();
|
||||||
void compute_tr();
|
void compute_tr();
|
||||||
void adjust_timer_interrupt();
|
void adjust_timer_interrupt();
|
||||||
|
void update_bus_control();
|
||||||
|
void update_memory_control();
|
||||||
|
|
||||||
void e116_16k_iram_map(address_map &map) ATTR_COLD;
|
void e116_16k_iram_map(address_map &map) ATTR_COLD;
|
||||||
void e116_4k_iram_map(address_map &map) ATTR_COLD;
|
void e116_4k_iram_map(address_map &map) ATTR_COLD;
|
||||||
|
@ -86,6 +86,16 @@ struct hyperstone_device::c_funcs
|
|||||||
reinterpret_cast<hyperstone_device *>(param)->update_timer_prescale();
|
reinterpret_cast<hyperstone_device *>(param)->update_timer_prescale();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void update_bus_control(void *param)
|
||||||
|
{
|
||||||
|
reinterpret_cast<hyperstone_device *>(param)->update_bus_control();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void update_memory_control(void *param)
|
||||||
|
{
|
||||||
|
reinterpret_cast<hyperstone_device *>(param)->update_memory_control();
|
||||||
|
}
|
||||||
|
|
||||||
#if E132XS_LOG_DRC_REGS || E132XS_LOG_INTERPRETER_REGS
|
#if E132XS_LOG_DRC_REGS || E132XS_LOG_INTERPRETER_REGS
|
||||||
static void dump_registers(void *param)
|
static void dump_registers(void *param)
|
||||||
{
|
{
|
||||||
|
@ -212,7 +212,6 @@ void hyperstone_device::generate_set_global_register_high(drcuml_block &block, c
|
|||||||
{
|
{
|
||||||
case 16: // G16 reserved
|
case 16: // G16 reserved
|
||||||
case 17: // G17 reserved
|
case 17: // G17 reserved
|
||||||
case BCR_REGISTER: // G20 Bus Control Register
|
|
||||||
case WCR_REGISTER: // G24 Watchdog Compare Register
|
case WCR_REGISTER: // G24 Watchdog Compare Register
|
||||||
case 28: // G28 reserved
|
case 28: // G28 reserved
|
||||||
case 29: // G29 reserved
|
case 29: // G29 reserved
|
||||||
@ -221,9 +220,15 @@ void hyperstone_device::generate_set_global_register_high(drcuml_block &block, c
|
|||||||
UML_MOV(block, mem(&m_core->global_regs[dst_code]), src);
|
UML_MOV(block, mem(&m_core->global_regs[dst_code]), src);
|
||||||
break;
|
break;
|
||||||
case SP_REGISTER: // G18 Stack Pointer
|
case SP_REGISTER: // G18 Stack Pointer
|
||||||
|
UML_MOV(block, mem(&m_core->global_regs[dst_code]), src);
|
||||||
|
break;
|
||||||
case UB_REGISTER: // G19 Upper Stack Bound
|
case UB_REGISTER: // G19 Upper Stack Bound
|
||||||
UML_AND(block, mem(&m_core->global_regs[dst_code]), src, ~uint32_t(3));
|
UML_AND(block, mem(&m_core->global_regs[dst_code]), src, ~uint32_t(3));
|
||||||
break;
|
break;
|
||||||
|
case BCR_REGISTER: // G20 Bus Control Register
|
||||||
|
UML_MOV(block, mem(&m_core->global_regs[dst_code]), src);
|
||||||
|
UML_CALLC(block, &c_funcs::update_bus_control, this);
|
||||||
|
break;
|
||||||
case TPR_REGISTER: // G21 Timer Prescaler Register
|
case TPR_REGISTER: // G21 Timer Prescaler Register
|
||||||
{
|
{
|
||||||
const int skip_compute_tr = compiler.next_label();
|
const int skip_compute_tr = compiler.next_label();
|
||||||
@ -269,10 +274,8 @@ void hyperstone_device::generate_set_global_register_high(drcuml_block &block, c
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MCR_REGISTER: // G27 Memory Control Register
|
case MCR_REGISTER: // G27 Memory Control Register
|
||||||
UML_ROLAND(block, I6, src, 20, 0x7);
|
|
||||||
UML_LOAD(block, I6, (void *)s_trap_entries, I6, SIZE_DWORD, SCALE_x4);
|
|
||||||
UML_MOV(block, mem(&m_core->trap_entry), I6);
|
|
||||||
UML_MOV(block, mem(&m_core->global_regs[dst_code]), src);
|
UML_MOV(block, mem(&m_core->global_regs[dst_code]), src);
|
||||||
|
UML_CALLC(block, &c_funcs::update_memory_control, this);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw emu_fatalerror("%s: invalid high global register G%u\n", dst_code);
|
throw emu_fatalerror("%s: invalid high global register G%u\n", dst_code);
|
||||||
@ -951,8 +954,10 @@ void hyperstone_device::generate_movd(drcuml_block &block, compiler_state &compi
|
|||||||
}
|
}
|
||||||
else if (SrcGlobal && (src_code == SR_REGISTER)) // Rd doesn't denote PC and Rs denotes SR
|
else if (SrcGlobal && (src_code == SR_REGISTER)) // Rd doesn't denote PC and Rs denotes SR
|
||||||
{
|
{
|
||||||
UML_OR(block, DRC_SR, DRC_SR, Z_MASK);
|
UML_MOV(block, I2, DRC_SR);
|
||||||
UML_AND(block, DRC_SR, DRC_SR, ~N_MASK);
|
UML_OR(block, I2, I2, Z_MASK);
|
||||||
|
UML_AND(block, I2, I2, ~N_MASK);
|
||||||
|
UML_MOV(block, DRC_SR, I2);
|
||||||
if (DstGlobal)
|
if (DstGlobal)
|
||||||
{
|
{
|
||||||
generate_set_global_register_low(block, compiler, desc, dst_code, 0);
|
generate_set_global_register_low(block, compiler, desc, dst_code, 0);
|
||||||
@ -960,7 +965,7 @@ void hyperstone_device::generate_movd(drcuml_block &block, compiler_state &compi
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UML_ROLAND(block, I0, DRC_SR, 32 - FP_SHIFT, 0x7f);
|
UML_ROLAND(block, I0, I2, 32 - FP_SHIFT, 0x7f);
|
||||||
UML_ADD(block, I0, I0, dst_code);
|
UML_ADD(block, I0, I0, dst_code);
|
||||||
UML_AND(block, I0, I0, 0x3f);
|
UML_AND(block, I0, I0, 0x3f);
|
||||||
UML_STORE(block, (void *)m_core->local_regs, I0, 0, SIZE_DWORD, SCALE_x4);
|
UML_STORE(block, (void *)m_core->local_regs, I0, 0, SIZE_DWORD, SCALE_x4);
|
||||||
|
@ -594,8 +594,8 @@ void mcd212_device::process_vsr(uint32_t *pixels, bool *transparent)
|
|||||||
u += m_delta_uv_lut[byte];
|
u += m_delta_uv_lut[byte];
|
||||||
v += m_delta_uv_lut[byte1];
|
v += m_delta_uv_lut[byte1];
|
||||||
|
|
||||||
uint32_t* limit_rgb = m_dyuv_limit_lut + y2 + 0x100;
|
const uint32_t *limit_rgb = m_dyuv_limit_lut + y2 + 0x100;
|
||||||
uint32_t* limit_rgb2 = m_dyuv_limit_lut + y + 0x100;
|
const uint32_t *limit_rgb2 = m_dyuv_limit_lut + y + 0x100;
|
||||||
|
|
||||||
color0 = (limit_rgb[m_dyuv_v_to_r[v]] << 16) | (limit_rgb[m_dyuv_u_to_g[u] + m_dyuv_v_to_g[v]] << 8) | limit_rgb[m_dyuv_u_to_b[u]];
|
color0 = (limit_rgb[m_dyuv_v_to_r[v]] << 16) | (limit_rgb[m_dyuv_u_to_g[u] + m_dyuv_v_to_g[v]] << 8) | limit_rgb[m_dyuv_u_to_b[u]];
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user