mirror of
https://github.com/holub/mame
synced 2025-04-16 21:44:32 +03:00
cpu/e132xs: Emulate more exceptions, more recompiler optimisation.
Emulate pointer error exception on load/store and range error exception on store signed byte/half-word. Further optimised code generation for MOV and MOVI. These are very hot, so this alone gains a further 2% performance or so in the dgPIX games. Also some other miscellaneous cleanup.
This commit is contained in:
parent
2fb28016e5
commit
eed05ed158
@ -31,8 +31,7 @@
|
||||
- GMS30C2232
|
||||
|
||||
TODO:
|
||||
- Pointer error exception on zero address register for interpreter
|
||||
- Range error exception on store signed byte/half-word
|
||||
- All instructions should clear the H flag (not just MOV/MOVI)
|
||||
- Fix behaviour of exceptions in delay slots
|
||||
- Fix behaviour of branches in delay slots
|
||||
- Many wrong cycle counts
|
||||
|
@ -465,7 +465,7 @@ private:
|
||||
uint32_t generate_get_pcrel(const opcode_desc *desc);
|
||||
std::pair<uint16_t, uint32_t> generate_get_d_code_dis(const opcode_desc *opcode);
|
||||
|
||||
void generate_get_global_register(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc);
|
||||
void generate_get_global_register_high(drcuml_block &block, compiler_state &compiler, uint32_t code, uml::parameter dst);
|
||||
void generate_set_global_register(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint32_t dst_code);
|
||||
void generate_set_global_register_low(drcuml_block &block, compiler_state &compiler, uint32_t dst_code, uml::parameter src);
|
||||
void generate_set_global_register_high(drcuml_block &block, compiler_state &compiler, uint32_t dst_code, uml::parameter src);
|
||||
|
@ -26,6 +26,9 @@ public:
|
||||
compiler_state &operator=(compiler_state const &) = delete;
|
||||
|
||||
uint8_t mode() const { return m_mode; }
|
||||
bool user_mode() const { return !BIT(m_mode, 0); }
|
||||
bool supervisor_mode() const { return BIT(m_mode, 0); }
|
||||
bool trace_mode() const { return BIT(m_mode, 1); }
|
||||
|
||||
auto next_label() { return m_labelnum++; }
|
||||
|
||||
@ -828,7 +831,7 @@ void hyperstone_device::generate_sequence_instruction(drcuml_block &block, compi
|
||||
--compiler.m_check_delay;
|
||||
}
|
||||
|
||||
if (BIT(compiler.mode(), 1) && !desc->delayslots)
|
||||
if (compiler.trace_mode() && !desc->delayslots)
|
||||
UML_EXHc(block, uml::COND_Z, *m_exception, TRAPNO_TRACE_EXCEPTION);
|
||||
}
|
||||
else
|
||||
|
@ -127,6 +127,29 @@ inline void hyperstone_device::generate_add_dis(drcuml_block &block, compiler_st
|
||||
}
|
||||
|
||||
|
||||
void hyperstone_device::generate_get_global_register_high(drcuml_block &block, compiler_state &compiler, uint32_t code, uml::parameter dst)
|
||||
{
|
||||
// Expects cycles in I7 (cleared after use)
|
||||
code |= 0x10;
|
||||
if (code == TR_REGISTER)
|
||||
{
|
||||
UML_SUB(block, mem(&m_core->icount), mem(&m_core->icount), I7);
|
||||
UML_MOV(block, I7, 0);
|
||||
|
||||
UML_SHR(block, dst, mem(&m_core->tr_clocks_per_tick), 1);
|
||||
UML_CMP(block, mem(&m_core->icount), dst);
|
||||
UML_MOVc(block, uml::COND_BE, dst, 0);
|
||||
UML_SUB(block, mem(&m_core->icount), mem(&m_core->icount), dst);
|
||||
|
||||
UML_CALLC(block, &c_funcs::compute_tr, this);
|
||||
UML_MOV(block, dst, mem(&m_core->tr_result));
|
||||
}
|
||||
else
|
||||
{
|
||||
UML_MOV(block, dst, mem(&m_core->global_regs[code]));
|
||||
}
|
||||
}
|
||||
|
||||
void hyperstone_device::generate_set_global_register(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint32_t dst_code)
|
||||
{
|
||||
// TODO: this function should be refactored away
|
||||
@ -231,7 +254,7 @@ void hyperstone_device::generate_set_global_register_low(drcuml_block &block, co
|
||||
else if (dst_code == SR_REGISTER)
|
||||
{
|
||||
UML_MOV(block, I4, DRC_SR);
|
||||
if (BIT(compiler.mode(), 0) || (src.is_immediate() && !(src.immediate() & L_MASK)))
|
||||
if (compiler.supervisor_mode() || (src.is_immediate() && !(src.immediate() & L_MASK)))
|
||||
{
|
||||
UML_ROLINS(block, I4, src, 0, 0x0000ffff);
|
||||
UML_AND(block, I4, I4, ~0x40); // keep reserved bit clear
|
||||
@ -923,7 +946,7 @@ void hyperstone_device::generate_movd(drcuml_block &block, compiler_state &compi
|
||||
UML_AND(block, I0, I0, ~uint32_t(1));
|
||||
UML_MOV(block, DRC_PC, I0);
|
||||
|
||||
if (!BIT(compiler.mode(), 0))
|
||||
if (compiler.user_mode())
|
||||
{
|
||||
// privilege exception on setting S or L
|
||||
UML_XOR(block, I3, I3, ~uint32_t(0));
|
||||
@ -1288,38 +1311,6 @@ void hyperstone_device::generate_cmp(drcuml_block &block, compiler_state &compil
|
||||
UML_MOV(block, DRC_SR, I2);
|
||||
}
|
||||
|
||||
void hyperstone_device::generate_get_global_register(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc)
|
||||
{
|
||||
const uint16_t op = desc->opptr.w[0];
|
||||
const uint32_t src_code = op & 0xf;
|
||||
|
||||
int regular_load = compiler.next_label();
|
||||
int done = compiler.next_label();
|
||||
UML_TEST(block, DRC_SR, H_MASK);
|
||||
UML_MOVc(block, uml::COND_NZ, I1, 16 + src_code);
|
||||
UML_MOVc(block, uml::COND_Z, I1, src_code);
|
||||
UML_CMP(block, I1, TR_REGISTER);
|
||||
UML_JMPc(block, uml::COND_NE, regular_load);
|
||||
|
||||
UML_SHR(block, I2, mem(&m_core->tr_clocks_per_tick), 1);
|
||||
UML_SUB(block, mem(&m_core->icount), mem(&m_core->icount), I7);
|
||||
UML_MOV(block, I7, 0);
|
||||
UML_CMP(block, mem(&m_core->icount), I2);
|
||||
UML_MOVc(block, uml::COND_BE, I2, 0);
|
||||
UML_SUB(block, mem(&m_core->icount), mem(&m_core->icount), I2);
|
||||
UML_CALLC(block, &c_funcs::compute_tr, this);
|
||||
UML_MOV(block, I5, mem(&m_core->tr_result));
|
||||
UML_JMP(block, done);
|
||||
|
||||
UML_LABEL(block, regular_load);
|
||||
UML_LOAD(block, I5, (void *)m_core->global_regs, I1, SIZE_DWORD, SCALE_x4);
|
||||
UML_SHL(block, I2, 1, I1);
|
||||
UML_TEST(block, I2, WRITE_ONLY_REGMASK);
|
||||
UML_MOVc(block, uml::COND_NZ, I5, 0);
|
||||
|
||||
UML_LABEL(block, done);
|
||||
}
|
||||
|
||||
template <hyperstone_device::reg_bank DstGlobal, hyperstone_device::reg_bank SrcGlobal>
|
||||
void hyperstone_device::generate_mov(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc)
|
||||
{
|
||||
@ -1329,68 +1320,108 @@ void hyperstone_device::generate_mov(drcuml_block &block, compiler_state &compil
|
||||
const uint32_t src_code = op & 0xf;
|
||||
const uint32_t dst_code = (op & 0xf0) >> 4;
|
||||
|
||||
int done;
|
||||
if (DstGlobal)
|
||||
UML_AND(block, I2, DRC_SR, ~(Z_MASK | N_MASK));
|
||||
if (!SrcGlobal || !DstGlobal)
|
||||
UML_ROLAND(block, I3, I2, 32 - FP_SHIFT, 0x7f);
|
||||
|
||||
if (DstGlobal && compiler.user_mode())
|
||||
{
|
||||
done = compiler.next_label();
|
||||
if (!BIT(compiler.mode(), 0))
|
||||
{
|
||||
const int no_exception = compiler.next_label();
|
||||
UML_TEST(block, DRC_SR, H_MASK);
|
||||
UML_JMPc(block, uml::COND_Z, no_exception);
|
||||
UML_EXH(block, *m_exception, TRAPNO_PRIVILEGE_ERROR);
|
||||
UML_JMP(block, done);
|
||||
UML_LABEL(block, no_exception);
|
||||
}
|
||||
UML_TEST(block, I2, H_MASK);
|
||||
UML_EXHc(block, uml::COND_NZ, *m_exception, TRAPNO_PRIVILEGE_ERROR);
|
||||
}
|
||||
|
||||
if (SrcGlobal)
|
||||
{
|
||||
generate_get_global_register(block, compiler, desc);
|
||||
if (!DstGlobal)
|
||||
UML_ROLAND(block, I1, DRC_SR, 32 - FP_SHIFT, 0x7f);
|
||||
if (!DstGlobal || compiler.supervisor_mode())
|
||||
{
|
||||
const int highglobal = compiler.next_label();
|
||||
const int done = compiler.next_label();
|
||||
|
||||
UML_TEST(block, I2, H_MASK);
|
||||
UML_JMPc(block, uml::COND_NZ, highglobal);
|
||||
|
||||
UML_MOV(block, I0, mem(&m_core->global_regs[src_code]));
|
||||
UML_JMP(block, done);
|
||||
|
||||
UML_LABEL(block, highglobal);
|
||||
generate_get_global_register_high(block, compiler, src_code, uml::I0);
|
||||
|
||||
UML_LABEL(block, done);
|
||||
}
|
||||
else
|
||||
{
|
||||
UML_MOV(block, I0, mem(&m_core->global_regs[src_code]));
|
||||
}
|
||||
}
|
||||
else if (DstGlobal || (src_code == dst_code))
|
||||
{
|
||||
UML_ADD(block, I3, I3, src_code);
|
||||
UML_AND(block, I3, I3, 0x3f);
|
||||
UML_LOAD(block, I0, (void *)m_core->local_regs, I3, SIZE_DWORD, SCALE_x4);
|
||||
}
|
||||
else
|
||||
{
|
||||
UML_ROLAND(block, I1, DRC_SR, 32 - FP_SHIFT, 0x7f);
|
||||
UML_ADD(block, I2, I1, src_code);
|
||||
UML_AND(block, I2, I2, 0x3f);
|
||||
UML_LOAD(block, I5, (void *)m_core->local_regs, I2, SIZE_DWORD, SCALE_x4);
|
||||
UML_ADD(block, I0, I3, src_code);
|
||||
UML_AND(block, I0, I0, 0x3f);
|
||||
UML_LOAD(block, I0, (void *)m_core->local_regs, I0, SIZE_DWORD, SCALE_x4);
|
||||
}
|
||||
|
||||
UML_AND(block, DRC_SR, DRC_SR, ~(Z_MASK | N_MASK));
|
||||
UML_TEST(block, I5, ~0);
|
||||
UML_SETc(block, uml::COND_Z, I2);
|
||||
UML_ROLINS(block, DRC_SR, I2, Z_SHIFT, Z_MASK);
|
||||
UML_ROLINS(block, DRC_SR, I5, N_SHIFT + 1, N_MASK);
|
||||
UML_TEST(block, I0, ~uint32_t(0));
|
||||
generate_update_nz(block, compiler, uml::I2);
|
||||
|
||||
if (DstGlobal)
|
||||
{
|
||||
const int highglobal = compiler.next_label();
|
||||
|
||||
UML_TEST(block, DRC_SR, H_MASK);
|
||||
UML_JMPc(block, uml::COND_NZ, highglobal);
|
||||
generate_set_global_register_low(block, compiler, dst_code, uml::I5);
|
||||
if (dst_code == PC_REGISTER)
|
||||
if (compiler.supervisor_mode())
|
||||
{
|
||||
UML_AND(block, DRC_SR, DRC_SR, ~M_MASK);
|
||||
UML_AND(block, I5, I5, ~uint32_t(1));
|
||||
generate_branch(block, compiler, compiler.mode(), uml::I5, desc);
|
||||
const int highglobal = compiler.next_label();
|
||||
const int done = compiler.next_label();
|
||||
|
||||
UML_TEST(block, I2, H_MASK);
|
||||
UML_JMPc(block, uml::COND_NZ, highglobal);
|
||||
|
||||
UML_MOV(block, DRC_SR, I2);
|
||||
generate_set_global_register_low(block, compiler, dst_code, uml::I0);
|
||||
if (dst_code == PC_REGISTER)
|
||||
{
|
||||
UML_AND(block, DRC_SR, DRC_SR, ~M_MASK);
|
||||
UML_AND(block, I0, I0, ~uint32_t(1));
|
||||
generate_branch(block, compiler, compiler.mode(), uml::I0, desc);
|
||||
}
|
||||
else
|
||||
{
|
||||
UML_JMP(block, done);
|
||||
}
|
||||
|
||||
UML_LABEL(block, highglobal);
|
||||
UML_AND(block, I2, I2, ~H_MASK);
|
||||
UML_MOV(block, DRC_SR, I2);
|
||||
generate_set_global_register_high(block, compiler, dst_code, uml::I0);
|
||||
|
||||
UML_LABEL(block, done);
|
||||
}
|
||||
else
|
||||
{
|
||||
UML_MOV(block, DRC_SR, I2);
|
||||
generate_set_global_register_low(block, compiler, dst_code, uml::I0);
|
||||
if (dst_code == PC_REGISTER)
|
||||
{
|
||||
UML_AND(block, DRC_SR, DRC_SR, ~M_MASK);
|
||||
UML_AND(block, I0, I0, ~uint32_t(1));
|
||||
generate_branch(block, compiler, compiler.mode(), uml::I0, desc);
|
||||
}
|
||||
}
|
||||
UML_JMP(block, done);
|
||||
|
||||
UML_LABEL(block, highglobal);
|
||||
UML_AND(block, DRC_SR, DRC_SR, ~H_MASK);
|
||||
generate_set_global_register_high(block, compiler, dst_code, uml::I5);
|
||||
|
||||
UML_LABEL(block, done);
|
||||
}
|
||||
else
|
||||
{
|
||||
UML_AND(block, DRC_SR, DRC_SR, ~H_MASK);
|
||||
UML_ADD(block, I2, I1, dst_code);
|
||||
UML_AND(block, I2, I2, 0x3f);
|
||||
UML_STORE(block, (void *)m_core->local_regs, I2, I5, SIZE_DWORD, SCALE_x4);
|
||||
UML_AND(block, I2, I2, ~H_MASK);
|
||||
UML_MOV(block, DRC_SR, I2);
|
||||
|
||||
if (SrcGlobal || (src_code != dst_code))
|
||||
{
|
||||
UML_ADD(block, I3, I3, dst_code);
|
||||
UML_AND(block, I3, I3, 0x3f);
|
||||
UML_STORE(block, (void *)m_core->local_regs, I3, I0, SIZE_DWORD, SCALE_x4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1799,6 +1830,13 @@ void hyperstone_device::generate_movi(drcuml_block &block, compiler_state &compi
|
||||
src = op & 0x0f;
|
||||
|
||||
UML_AND(block, I2, DRC_SR, ~(Z_MASK | N_MASK));
|
||||
|
||||
if (DstGlobal && compiler.user_mode())
|
||||
{
|
||||
UML_TEST(block, I2, H_MASK);
|
||||
UML_EXHc(block, uml::COND_NZ, *m_exception, TRAPNO_PRIVILEGE_ERROR);
|
||||
}
|
||||
|
||||
if (!src)
|
||||
UML_OR(block, I2, I2, Z_MASK);
|
||||
else if (src & 0x80000000)
|
||||
@ -1807,48 +1845,55 @@ void hyperstone_device::generate_movi(drcuml_block &block, compiler_state &compi
|
||||
UML_AND(block, I2, I2, ~V_MASK);
|
||||
#endif
|
||||
|
||||
if (DstGlobal && !BIT(compiler.mode(), 0))
|
||||
{
|
||||
const int no_exception = compiler.next_label();
|
||||
UML_TEST(block, I2, H_MASK);
|
||||
UML_JMPc(block, uml::COND_Z, no_exception);
|
||||
UML_EXH(block, *m_exception, TRAPNO_PRIVILEGE_ERROR);
|
||||
UML_LABEL(block, no_exception);
|
||||
}
|
||||
|
||||
UML_MOV(block, DRC_SR, I2);
|
||||
|
||||
if (DstGlobal)
|
||||
{
|
||||
const int highglobal = compiler.next_label();
|
||||
const int done = compiler.next_label();
|
||||
|
||||
UML_TEST(block, I2, H_MASK);
|
||||
UML_JMPc(block, uml::COND_NZ, highglobal);
|
||||
generate_set_global_register_low(block, compiler, dst_code, src);
|
||||
if (dst_code == PC_REGISTER)
|
||||
if (compiler.supervisor_mode())
|
||||
{
|
||||
UML_AND(block, DRC_SR, DRC_SR, ~M_MASK);
|
||||
generate_branch(block, compiler, compiler.mode(), src & ~uint32_t(1), desc);
|
||||
const int highglobal = compiler.next_label();
|
||||
const int done = compiler.next_label();
|
||||
|
||||
UML_TEST(block, I2, H_MASK);
|
||||
UML_JMPc(block, uml::COND_NZ, highglobal);
|
||||
|
||||
UML_MOV(block, DRC_SR, I2);
|
||||
generate_set_global_register_low(block, compiler, dst_code, src);
|
||||
if (dst_code == PC_REGISTER)
|
||||
{
|
||||
UML_AND(block, DRC_SR, DRC_SR, ~M_MASK);
|
||||
generate_branch(block, compiler, compiler.mode(), src & ~uint32_t(1), desc);
|
||||
}
|
||||
else
|
||||
{
|
||||
UML_JMP(block, done);
|
||||
}
|
||||
|
||||
UML_LABEL(block, highglobal);
|
||||
UML_AND(block, I2, I2, ~H_MASK);
|
||||
UML_MOV(block, DRC_SR, I2);
|
||||
generate_set_global_register_high(block, compiler, dst_code, src);
|
||||
|
||||
UML_LABEL(block, done);
|
||||
}
|
||||
else
|
||||
{
|
||||
UML_JMP(block, done);
|
||||
UML_MOV(block, DRC_SR, I2);
|
||||
generate_set_global_register_low(block, compiler, dst_code, src);
|
||||
if (dst_code == PC_REGISTER)
|
||||
{
|
||||
UML_AND(block, DRC_SR, DRC_SR, ~M_MASK);
|
||||
generate_branch(block, compiler, compiler.mode(), src & ~uint32_t(1), desc);
|
||||
}
|
||||
}
|
||||
|
||||
UML_LABEL(block, highglobal);
|
||||
UML_AND(block, DRC_SR, DRC_SR, ~H_MASK);
|
||||
generate_set_global_register_high(block, compiler, dst_code, src);
|
||||
|
||||
UML_LABEL(block, done);
|
||||
}
|
||||
else
|
||||
{
|
||||
UML_AND(block, DRC_SR, DRC_SR, ~H_MASK);
|
||||
UML_ROLAND(block, I2, DRC_SR, 32 - FP_SHIFT, 0x7f);
|
||||
UML_ADD(block, I0, I2, dst_code);
|
||||
UML_AND(block, I0, I0, 0x3f);
|
||||
UML_STORE(block, (void *)m_core->local_regs, I0, src, SIZE_DWORD, SCALE_x4);
|
||||
UML_AND(block, I2, I2, ~H_MASK);
|
||||
UML_MOV(block, DRC_SR, I2);
|
||||
|
||||
UML_ROLAND(block, I2, I2, 32 - FP_SHIFT, 0x7f);
|
||||
UML_ADD(block, I2, I2, dst_code);
|
||||
UML_AND(block, I2, I2, 0x3f);
|
||||
UML_STORE(block, (void *)m_core->local_regs, I2, src, SIZE_DWORD, SCALE_x4);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2967,17 +3012,29 @@ void hyperstone_device::generate_stxx1(drcuml_block &block, compiler_state &comp
|
||||
{
|
||||
case 0: // STBS.D/A
|
||||
case 1: // STBU.D/A
|
||||
// TODO: missing trap on range error for STBS.D/A
|
||||
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
|
||||
generate_add_dis(block, compiler, uml::I0, dstp, extra_s, 1);
|
||||
UML_CALLH(block, *m_mem_write8);
|
||||
|
||||
if (sub_type == 0)
|
||||
{
|
||||
UML_SEXT(block, I0, I1, SIZE_BYTE);
|
||||
UML_CMP(block, I0, I1);
|
||||
UML_EXHc(block, uml::COND_NZ, *m_exception, TRAPNO_RANGE_ERROR);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: // STHS.D/A, STHU.D/A
|
||||
// TODO: missing trap on range error with STHS.D/A
|
||||
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
|
||||
generate_add_dis(block, compiler, uml::I0, dstp, extra_s, 2);
|
||||
UML_CALLH(block, *m_mem_write16);
|
||||
|
||||
if (extra_s & 1)
|
||||
{
|
||||
UML_SEXT(block, I0, I1, SIZE_WORD);
|
||||
UML_CMP(block, I0, I1);
|
||||
UML_EXHc(block, uml::COND_NZ, *m_exception, TRAPNO_RANGE_ERROR);
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
@ -3072,38 +3129,52 @@ void hyperstone_device::generate_stxx2(drcuml_block &block, compiler_state &comp
|
||||
}
|
||||
else
|
||||
{
|
||||
UML_ADD(block, I2, I3, src_code);
|
||||
UML_AND(block, I5, I2, 0x3f);
|
||||
UML_LOAD(block, I1, (void *)m_core->local_regs, I5, SIZE_DWORD, SCALE_x4);
|
||||
UML_ADD(block, I1, I3, src_code);
|
||||
UML_AND(block, I1, I1, 0x3f);
|
||||
UML_LOAD(block, I1, (void *)m_core->local_regs, I1, SIZE_DWORD, SCALE_x4);
|
||||
}
|
||||
|
||||
switch (sub_type)
|
||||
{
|
||||
case 0: // STBS.N
|
||||
case 1: // STBU.N
|
||||
// TODO: missing trap on range error with STBS.N
|
||||
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
|
||||
UML_CALLH(block, *m_mem_write8);
|
||||
UML_ADD(block, I0, I0, extra_s);
|
||||
|
||||
UML_ADD(block, I0, I0, extra_s);
|
||||
if (DstGlobal)
|
||||
UML_MOV(block, mem(&m_core->global_regs[dst_code]), I0);
|
||||
else
|
||||
UML_STORE(block, (void *)m_core->local_regs, I6, I0, SIZE_DWORD, SCALE_x4);
|
||||
|
||||
if (sub_type == 0)
|
||||
{
|
||||
UML_SEXT(block, I0, I1, SIZE_BYTE);
|
||||
UML_CMP(block, I0, I1);
|
||||
UML_EXHc(block, uml::COND_NZ, *m_exception, TRAPNO_RANGE_ERROR);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: // STHS.N, STHU.N
|
||||
// TODO: missing trap on range error with STHS.N
|
||||
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
|
||||
UML_MOV(block, I5, I0);
|
||||
UML_MOV(block, I4, I0);
|
||||
UML_AND(block, I0, I0, ~1);
|
||||
UML_CALLH(block, *m_mem_write16);
|
||||
UML_ADD(block, I5, I5, extra_s & ~1);
|
||||
|
||||
UML_ADD(block, I4, I4, extra_s & ~1);
|
||||
if (DstGlobal)
|
||||
UML_MOV(block, mem(&m_core->global_regs[dst_code]), I5);
|
||||
UML_MOV(block, mem(&m_core->global_regs[dst_code]), I4);
|
||||
else
|
||||
UML_STORE(block, (void *)m_core->local_regs, I6, I5, SIZE_DWORD, SCALE_x4);
|
||||
UML_STORE(block, (void *)m_core->local_regs, I6, I4, SIZE_DWORD, SCALE_x4);
|
||||
|
||||
if (extra_s & 1)
|
||||
{
|
||||
UML_SEXT(block, I0, I1, SIZE_WORD);
|
||||
UML_CMP(block, I0, I1);
|
||||
UML_EXHc(block, uml::COND_NZ, *m_exception, TRAPNO_RANGE_ERROR);
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
switch (extra_s & 3)
|
||||
{
|
||||
@ -3119,6 +3190,7 @@ void hyperstone_device::generate_stxx2(drcuml_block &block, compiler_state &comp
|
||||
else
|
||||
UML_STORE(block, (void *)m_core->local_regs, I6, I5, SIZE_DWORD, SCALE_x4);
|
||||
break;
|
||||
|
||||
case 1: // STD.N
|
||||
UML_MOV(block, I7, mem(&m_core->clock_cycles_2));
|
||||
UML_MOV(block, I5, I0);
|
||||
@ -3136,9 +3208,11 @@ void hyperstone_device::generate_stxx2(drcuml_block &block, compiler_state &comp
|
||||
UML_ADD(block, I0, I0, 4);
|
||||
UML_CALLH(block, *m_mem_write32);
|
||||
break;
|
||||
|
||||
case 2: // Reserved
|
||||
osd_printf_error("Executed Reserved instruction in hyperstone_stxx2. PC = %08X\n", desc->pc);
|
||||
break;
|
||||
|
||||
case 3: // STW.S
|
||||
{
|
||||
UML_MOV(block, I7, mem(&m_core->clock_cycles_3));
|
||||
|
@ -1553,6 +1553,12 @@ void hyperstone_device::hyperstone_ldxx1()
|
||||
const uint32_t dst_code = DstGlobal ? DST_CODE : ((DST_CODE + fp) & 0x3f);
|
||||
const uint32_t dreg = ((DstGlobal && dst_code == SR_REGISTER) ? 0 : (DstGlobal ? m_core->global_regs : m_core->local_regs)[dst_code]);
|
||||
|
||||
if ((!DstGlobal || (dst_code != SR_REGISTER)) && !dreg)
|
||||
{
|
||||
execute_exception(TRAPNO_POINTER_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (sub_type)
|
||||
{
|
||||
case 0: // LDBS.D
|
||||
@ -1667,18 +1673,36 @@ void hyperstone_device::hyperstone_ldxx2()
|
||||
check_delay_PC();
|
||||
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t src_code = SrcGlobal ? SRC_CODE : (SRC_CODE + fp) & 0x3f;
|
||||
const uint32_t srcf_code = SrcGlobal ? (src_code + 1) : ((src_code + 1) & 0x3f);
|
||||
const uint32_t dst_code = DstGlobal ? DST_CODE : (DST_CODE + fp) & 0x3f;
|
||||
const uint32_t dreg = (DstGlobal ? m_core->global_regs : m_core->local_regs)[dst_code];
|
||||
|
||||
if (DstGlobal && dst_code < 2)
|
||||
if (DstGlobal && (dst_code <= SR_REGISTER))
|
||||
{
|
||||
m_core->icount -= m_core->clock_cycles_1;
|
||||
LOG("Denoted PC or SR in hyperstone_ldxx2. PC = %08X\n", PC);
|
||||
return;
|
||||
}
|
||||
|
||||
const uint32_t src_code = SrcGlobal ? SRC_CODE : (SRC_CODE + fp) & 0x3f;
|
||||
const uint32_t srcf_code = SrcGlobal ? (src_code + 1) : ((src_code + 1) & 0x3f);
|
||||
const uint32_t dreg = (DstGlobal ? m_core->global_regs : m_core->local_regs)[dst_code];
|
||||
if (!dreg)
|
||||
{
|
||||
switch (sub_type)
|
||||
{
|
||||
case 0: // LDBS.N
|
||||
case 1: // LDBU.N
|
||||
(DstGlobal ? m_core->global_regs : m_core->local_regs)[dst_code] += extra_s;
|
||||
break;
|
||||
case 2: // LDHS.N, LDHU.N
|
||||
(DstGlobal ? m_core->global_regs : m_core->local_regs)[dst_code] += extra_s & ~1;
|
||||
break;
|
||||
case 3: // LDW.N, LDD.N, LDW.S
|
||||
(DstGlobal ? m_core->global_regs : m_core->local_regs)[dst_code] += extra_s & ~3;
|
||||
break;
|
||||
}
|
||||
execute_exception(TRAPNO_POINTER_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (sub_type)
|
||||
{
|
||||
@ -1716,7 +1740,7 @@ void hyperstone_device::hyperstone_ldxx2()
|
||||
m_core->local_regs[src_code] = READ_HW(dreg);
|
||||
}
|
||||
|
||||
if(DstGlobal != SrcGlobal || src_code != dst_code)
|
||||
if (DstGlobal != SrcGlobal || src_code != dst_code)
|
||||
(DstGlobal ? m_core->global_regs : m_core->local_regs)[dst_code] += (extra_s & ~1);
|
||||
break;
|
||||
|
||||
@ -1817,11 +1841,18 @@ void hyperstone_device::hyperstone_stxx1()
|
||||
const uint32_t dreg = ((DstGlobal && dst_code == SR_REGISTER) ? 0 : (DstGlobal ? m_core->global_regs : m_core->local_regs)[dst_code]);
|
||||
const uint32_t sreg = ((SrcGlobal && src_code == SR_REGISTER) ? 0 : (SrcGlobal ? m_core->global_regs : m_core->local_regs)[src_code]);
|
||||
|
||||
if ((!DstGlobal || (dst_code != SR_REGISTER)) && !dreg)
|
||||
{
|
||||
execute_exception(TRAPNO_POINTER_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (sub_type)
|
||||
{
|
||||
case 0: // STBS.D
|
||||
// TODO: missing trap on range error
|
||||
WRITE_B(dreg + extra_s, (uint8_t)sreg);
|
||||
WRITE_B(dreg + extra_s, uint8_t(sreg));
|
||||
if (int8_t(uint8_t(sreg)) != int32_t(sreg))
|
||||
execute_exception(TRAPNO_RANGE_ERROR);
|
||||
break;
|
||||
|
||||
case 1: // STBU.D
|
||||
@ -1829,8 +1860,9 @@ void hyperstone_device::hyperstone_stxx1()
|
||||
break;
|
||||
|
||||
case 2: // STHS.D, STHU.D
|
||||
WRITE_HW(dreg + (extra_s & ~1), (uint16_t)sreg);
|
||||
// TODO: missing trap on range error with STHS.D
|
||||
WRITE_HW(dreg + (extra_s & ~1), uint16_t(sreg));
|
||||
if ((extra_s & 1) && (int16_t(uint16_t(sreg)) != int32_t(sreg)))
|
||||
execute_exception(TRAPNO_RANGE_ERROR);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
@ -1907,18 +1939,40 @@ void hyperstone_device::hyperstone_stxx2()
|
||||
const uint32_t dst_code = DstGlobal ? DST_CODE : ((DST_CODE + fp) & 0x3f);
|
||||
const uint32_t dreg = (DstGlobal ? m_core->global_regs : m_core->local_regs)[dst_code];
|
||||
|
||||
if (DstGlobal && dst_code < 2)
|
||||
if (DstGlobal && (dst_code <= SR_REGISTER))
|
||||
{
|
||||
m_core->icount -= m_core->clock_cycles_1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!dreg)
|
||||
{
|
||||
switch (sub_type)
|
||||
{
|
||||
case 0: // LDBS.N
|
||||
case 1: // LDBU.N
|
||||
(DstGlobal ? m_core->global_regs : m_core->local_regs)[dst_code] += extra_s;
|
||||
break;
|
||||
case 2: // LDHS.N, LDHU.N
|
||||
(DstGlobal ? m_core->global_regs : m_core->local_regs)[dst_code] += extra_s & ~1;
|
||||
break;
|
||||
case 3: // LDW.N, LDD.N, LDW.S
|
||||
(DstGlobal ? m_core->global_regs : m_core->local_regs)[dst_code] += extra_s & ~3;
|
||||
break;
|
||||
}
|
||||
execute_exception(TRAPNO_POINTER_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
bool range_error;
|
||||
switch (sub_type)
|
||||
{
|
||||
case 0: // STBS.N
|
||||
// TODO: missing trap on range error
|
||||
WRITE_B(dreg, (uint8_t)sreg);
|
||||
range_error = int8_t(uint8_t(sreg)) != int32_t(sreg);
|
||||
(DstGlobal ? m_core->global_regs : m_core->local_regs)[dst_code] += extra_s;
|
||||
if (range_error)
|
||||
execute_exception(TRAPNO_RANGE_ERROR);
|
||||
break;
|
||||
|
||||
case 1: // STBU.N
|
||||
@ -1928,8 +1982,10 @@ void hyperstone_device::hyperstone_stxx2()
|
||||
|
||||
case 2: // STHS.N, STHU.N
|
||||
WRITE_HW(dreg, (uint16_t)sreg);
|
||||
range_error = (extra_s & 1) && (int16_t(uint16_t(sreg)) != int32_t(sreg));
|
||||
(DstGlobal ? m_core->global_regs : m_core->local_regs)[dst_code] += extra_s & ~1;
|
||||
// TODO: missing trap on range error with STHS.N
|
||||
if (range_error)
|
||||
execute_exception(TRAPNO_RANGE_ERROR);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
@ -2316,11 +2372,20 @@ template <hyperstone_device::reg_bank SrcGlobal>
|
||||
void hyperstone_device::hyperstone_ldwr()
|
||||
{
|
||||
check_delay_PC();
|
||||
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t dreg = m_core->local_regs[(DST_CODE + fp) & 0x3f];
|
||||
|
||||
if (!dreg)
|
||||
{
|
||||
execute_exception(TRAPNO_POINTER_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (SrcGlobal)
|
||||
set_global_register(SRC_CODE, READ_W(m_core->local_regs[(DST_CODE + fp) & 0x3f]));
|
||||
set_global_register(SRC_CODE, READ_W(dreg));
|
||||
else
|
||||
m_core->local_regs[(SRC_CODE + fp) & 0x3f] = READ_W(m_core->local_regs[(DST_CODE + fp) & 0x3f]);
|
||||
m_core->local_regs[(SRC_CODE + fp) & 0x3f] = READ_W(dreg);
|
||||
m_core->icount -= m_core->clock_cycles_1;
|
||||
}
|
||||
|
||||
@ -2333,6 +2398,12 @@ void hyperstone_device::hyperstone_lddr()
|
||||
const uint32_t src_code = SrcGlobal ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
|
||||
const uint32_t dreg = m_core->local_regs[(DST_CODE + fp) & 0x3f];
|
||||
|
||||
if (!dreg)
|
||||
{
|
||||
execute_exception(TRAPNO_POINTER_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (SrcGlobal)
|
||||
{
|
||||
set_global_register(src_code, READ_W(dreg));
|
||||
@ -2354,20 +2425,28 @@ void hyperstone_device::hyperstone_ldwp()
|
||||
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t dst_code = (DST_CODE + fp) & 0x3f;
|
||||
const uint32_t dreg = m_core->local_regs[dst_code];
|
||||
|
||||
if (!dreg)
|
||||
{
|
||||
m_core->local_regs[dst_code] = dreg + 4;
|
||||
execute_exception(TRAPNO_POINTER_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (SrcGlobal)
|
||||
{
|
||||
set_global_register(SRC_CODE, READ_W(m_core->local_regs[dst_code]));
|
||||
m_core->local_regs[dst_code] += 4;
|
||||
set_global_register(SRC_CODE, READ_W(dreg));
|
||||
m_core->local_regs[dst_code] = dreg + 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
const uint32_t src_code = (SRC_CODE + fp) & 0x3f;
|
||||
m_core->local_regs[src_code] = READ_W(m_core->local_regs[dst_code]);
|
||||
m_core->local_regs[src_code] = READ_W(dreg);
|
||||
// post increment the destination register if it's different from the source one
|
||||
// (needed by Hidden Catch)
|
||||
if (src_code != dst_code)
|
||||
m_core->local_regs[dst_code] += 4;
|
||||
m_core->local_regs[dst_code] = dreg + 4;
|
||||
}
|
||||
|
||||
m_core->icount -= m_core->clock_cycles_1;
|
||||
@ -2383,11 +2462,18 @@ void hyperstone_device::hyperstone_lddp()
|
||||
const uint32_t dst_code = (DST_CODE + fp) & 0x3f;
|
||||
const uint32_t dreg = m_core->local_regs[dst_code];
|
||||
|
||||
if (!dreg)
|
||||
{
|
||||
m_core->local_regs[dst_code] = dreg + 8;
|
||||
execute_exception(TRAPNO_POINTER_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (SrcGlobal)
|
||||
{
|
||||
set_global_register(src_code, READ_W(dreg));
|
||||
set_global_register(src_code + 1, READ_W(dreg + 4));
|
||||
m_core->local_regs[dst_code] += 8;
|
||||
m_core->local_regs[dst_code] = dreg + 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2398,7 +2484,7 @@ void hyperstone_device::hyperstone_lddp()
|
||||
// post increment the destination register if it's different from the source one
|
||||
// and from the "next source" one
|
||||
if (src_code != dst_code && srcf_code != dst_code)
|
||||
m_core->local_regs[dst_code] += 8;
|
||||
m_core->local_regs[dst_code] = dreg + 8;
|
||||
}
|
||||
|
||||
m_core->icount -= m_core->clock_cycles_2;
|
||||
@ -2412,7 +2498,15 @@ void hyperstone_device::hyperstone_stwr()
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t src_code = SrcGlobal ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
|
||||
const uint32_t sreg = (SrcGlobal && src_code == SR_REGISTER) ? 0 : (SrcGlobal ? m_core->global_regs : m_core->local_regs)[src_code];
|
||||
WRITE_W(m_core->local_regs[(DST_CODE + fp) & 0x3f], sreg);
|
||||
const uint32_t dreg = m_core->local_regs[(DST_CODE + fp) & 0x3f];
|
||||
|
||||
if (!dreg)
|
||||
{
|
||||
execute_exception(TRAPNO_POINTER_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
WRITE_W(dreg, sreg);
|
||||
|
||||
m_core->icount -= m_core->clock_cycles_1;
|
||||
}
|
||||
@ -2427,9 +2521,14 @@ void hyperstone_device::hyperstone_stdr()
|
||||
const uint32_t srcf_code = SrcGlobal ? (SRC_CODE + 1) : ((src_code + 1) & 0x3f);
|
||||
const uint32_t sreg = (SrcGlobal && src_code == SR_REGISTER) ? 0 : (SrcGlobal ? m_core->global_regs : m_core->local_regs)[src_code];
|
||||
const uint32_t sregf = (SrcGlobal && src_code == SR_REGISTER) ? 0 : (SrcGlobal ? m_core->global_regs : m_core->local_regs)[srcf_code];
|
||||
|
||||
const uint32_t dreg = m_core->local_regs[(DST_CODE + GET_FP) & 0x3f];
|
||||
|
||||
if (!dreg)
|
||||
{
|
||||
execute_exception(TRAPNO_POINTER_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
WRITE_W(dreg, sreg);
|
||||
WRITE_W(dreg + 4, sregf);
|
||||
|
||||
@ -2444,12 +2543,18 @@ void hyperstone_device::hyperstone_stwp()
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t src_code = SrcGlobal ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
|
||||
const uint32_t sreg = (SrcGlobal && src_code == SR_REGISTER) ? 0 : (SrcGlobal ? m_core->global_regs : m_core->local_regs)[src_code];
|
||||
|
||||
const uint32_t dst_code = (DST_CODE + fp) & 0x3f;
|
||||
const uint32_t dreg = m_core->local_regs[dst_code];
|
||||
|
||||
m_core->local_regs[dst_code] = dreg + 4;
|
||||
|
||||
if (!dreg)
|
||||
{
|
||||
execute_exception(TRAPNO_POINTER_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
WRITE_W(dreg, sreg);
|
||||
m_core->local_regs[dst_code] += 4;
|
||||
|
||||
m_core->icount -= m_core->clock_cycles_1;
|
||||
}
|
||||
@ -2463,13 +2568,18 @@ void hyperstone_device::hyperstone_stdp()
|
||||
const uint32_t src_code = SrcGlobal ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
|
||||
const uint32_t srcf_code = SrcGlobal ? (src_code + 1) : ((src_code + 1) & 0x3f);
|
||||
const uint32_t sreg = (SrcGlobal && src_code == SR_REGISTER) ? 0 : (SrcGlobal ? m_core->global_regs : m_core->local_regs)[src_code];
|
||||
|
||||
const uint32_t dst_code = (DST_CODE + fp) & 0x3f;
|
||||
const uint32_t dreg = m_core->local_regs[dst_code];
|
||||
|
||||
WRITE_W(dreg, sreg);
|
||||
m_core->local_regs[dst_code] = dreg + 8;
|
||||
|
||||
m_core->local_regs[dst_code] += 8;
|
||||
if (!dreg)
|
||||
{
|
||||
execute_exception(TRAPNO_POINTER_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
WRITE_W(dreg, sreg);
|
||||
|
||||
const uint32_t sregf = (SrcGlobal && src_code == SR_REGISTER) ? 0 : (SrcGlobal ? m_core->global_regs : m_core->local_regs)[srcf_code];
|
||||
|
||||
|
@ -73,10 +73,10 @@ uint32_t v60_device::opCVTSW()
|
||||
val = u2f(m_op1);
|
||||
switch (TKCW & 7)
|
||||
{
|
||||
case 0: m_modwritevalw = (uint32_t)(int64_t)round(val); break;
|
||||
case 1: m_modwritevalw = (uint32_t)(int64_t)floor(val); break;
|
||||
case 2: m_modwritevalw = (uint32_t)(int64_t)ceil(val); break;
|
||||
default: m_modwritevalw = (uint32_t)(int64_t)trunc(val); break;
|
||||
case 0: m_modwritevalw = (uint32_t)llroundf(val); break;
|
||||
case 1: m_modwritevalw = (uint32_t)(int64_t)floorf(val); break;
|
||||
case 2: m_modwritevalw = (uint32_t)(int64_t)ceilf(val); break;
|
||||
default: m_modwritevalw = (uint32_t)(int64_t)truncf(val); break;
|
||||
}
|
||||
|
||||
_S = ((m_modwritevalw & 0x80000000) != 0);
|
||||
|
@ -48,17 +48,19 @@ Official test program from pages 4 to 8 of the operator's manual:
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
#include "cpu/i8085/i8085.h"
|
||||
#include "machine/i8251.h"
|
||||
#include "machine/clock.h"
|
||||
#include "machine/timer.h"
|
||||
#include "bus/heathzenith/intr_cntrl/intr_cntrl.h"
|
||||
#include "bus/rs232/rs232.h"
|
||||
#include "cpu/i8085/i8085.h"
|
||||
#include "imagedev/cassette.h"
|
||||
#include "machine/clock.h"
|
||||
#include "machine/i8251.h"
|
||||
#include "machine/timer.h"
|
||||
#include "sound/beep.h"
|
||||
|
||||
#include "speaker.h"
|
||||
|
||||
#include "bus/heathzenith/intr_cntrl/intr_cntrl.h"
|
||||
#include "formats/h8_cas.h"
|
||||
|
||||
#include "h8.lh"
|
||||
|
||||
namespace {
|
||||
|
@ -25,28 +25,28 @@ tzbx15_device::tzbx15_device(const machine_config &mconfig, device_type type, co
|
||||
{
|
||||
}
|
||||
|
||||
tzbx15_device::tzbx15_device(const machine_config& mconfig, device_type type, const char* tag, device_t* owner, u32 clock, u32 clut_size)
|
||||
tzbx15_device::tzbx15_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u32 clut_size)
|
||||
: tzbx15_device(mconfig, type, tag, owner, clock)
|
||||
{
|
||||
m_rom_clut_size = clut_size;
|
||||
}
|
||||
|
||||
tzb215_device::tzb215_device(const machine_config& mconfig, const char* tag, device_t* owner, u32 clock, u32 clut_size)
|
||||
tzb215_device::tzb215_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock, u32 clut_size)
|
||||
: tzbx15_device(mconfig, TZB215_SPRITES, tag, owner, clock, clut_size)
|
||||
{
|
||||
}
|
||||
|
||||
tzb215_device::tzb215_device(const machine_config& mconfig, const char* tag, device_t* owner, u32 clock)
|
||||
tzb215_device::tzb215_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||
: tzbx15_device(mconfig, TZB215_SPRITES, tag, owner, clock, 0)
|
||||
{
|
||||
}
|
||||
|
||||
tzb315_device::tzb315_device(const machine_config& mconfig, const char* tag, device_t* owner, u32 clock, u32 clut_size)
|
||||
tzb315_device::tzb315_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock, u32 clut_size)
|
||||
: tzbx15_device(mconfig, TZB315_SPRITES, tag, owner, clock, clut_size)
|
||||
{
|
||||
}
|
||||
|
||||
tzb315_device::tzb315_device(const machine_config& mconfig, const char* tag, device_t* owner, u32 clock)
|
||||
tzb315_device::tzb315_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||
: tzbx15_device(mconfig, TZB315_SPRITES, tag, owner, clock, 0)
|
||||
{
|
||||
}
|
||||
@ -54,14 +54,6 @@ tzb315_device::tzb315_device(const machine_config& mconfig, const char* tag, dev
|
||||
|
||||
|
||||
|
||||
void tzbx15_device::common_init()
|
||||
{
|
||||
m_rom_clut_offset = memregion("sprites_l")->bytes() - m_rom_clut_size;
|
||||
|
||||
m_shadow_pen_array = make_unique_clear<uint8_t[]>(m_rom_clut_size * 2);
|
||||
m_temp_bitmap.allocate(512, 512);
|
||||
}
|
||||
|
||||
static const gfx_layout spritelayout =
|
||||
{
|
||||
8,8,
|
||||
@ -80,7 +72,11 @@ GFXDECODE_END
|
||||
|
||||
void tzbx15_device::device_start()
|
||||
{
|
||||
common_init();
|
||||
m_rom_clut_offset = memregion("sprites_l")->bytes() - m_rom_clut_size;
|
||||
|
||||
m_shadow_pen_array = make_unique_clear<uint8_t[]>(m_rom_clut_size * 2);
|
||||
m_temp_bitmap.allocate(512, 512);
|
||||
|
||||
decode_gfx(gfxinfo);
|
||||
gfx(0)->set_colors(m_rom_clut_size / 8);
|
||||
gfx(1)->set_colors(m_rom_clut_size / 8);
|
||||
@ -130,7 +126,7 @@ void tzbx15_device::mycopyrozbitmap_core(bitmap_rgb32 &bitmap, const bitmap_rgb3
|
||||
int x = sx;
|
||||
uint32_t cx = startx;
|
||||
uint32_t cy = starty;
|
||||
uint32_t* dest = &bitmap.pix(sy, sx);
|
||||
uint32_t *dest = &bitmap.pix(sy, sx);
|
||||
|
||||
while (x <= ex)
|
||||
{
|
||||
@ -155,9 +151,12 @@ void tzbx15_device::mycopyrozbitmap_core(bitmap_rgb32 &bitmap, const bitmap_rgb3
|
||||
}
|
||||
|
||||
template<class BitmapClass>
|
||||
void tzbx15_device::roundupt_drawgfxzoomrotate( BitmapClass &dest_bmp, const rectangle &clip,
|
||||
gfx_element *gfx, uint32_t code,uint32_t color,int flipx,int flipy,uint32_t ssx,uint32_t ssy,
|
||||
int scalex, int scaley, int rotate, int write_priority_only )
|
||||
void tzbx15_device::roundupt_drawgfxzoomrotate(
|
||||
BitmapClass &dest_bmp, const rectangle &clip,
|
||||
gfx_element *gfx, uint32_t code, uint32_t color,
|
||||
int flipx, int flipy, uint32_t ssx, uint32_t ssy,
|
||||
int scalex, int scaley, int rotate,
|
||||
int write_priority_only)
|
||||
{
|
||||
if (!scalex || !scaley) return;
|
||||
|
||||
@ -172,7 +171,7 @@ void tzbx15_device::roundupt_drawgfxzoomrotate( BitmapClass &dest_bmp, const rec
|
||||
rectangle myclip = clip;
|
||||
myclip &= dest_bmp.cliprect();
|
||||
|
||||
if( gfx )
|
||||
if (gfx)
|
||||
{
|
||||
const pen_t *pal = &m_palette_clut->pen(gfx->colorbase() + gfx->granularity() * (color % gfx->colors()));
|
||||
const uint8_t *shadow_pens = m_shadow_pen_array.get() + (gfx->granularity() * (color % gfx->colors()));
|
||||
@ -417,23 +416,27 @@ void tzbx15_device::draw_sprites_main(BitmapClass &bitmap, const rectangle &clip
|
||||
src1 += 4;
|
||||
int h = 0;
|
||||
|
||||
while (lines > 0) {
|
||||
while (lines > 0)
|
||||
{
|
||||
int base, x_offs, x_width, x_pos, draw_this_line = 1;
|
||||
int this_extent = 0;
|
||||
|
||||
/* Odd and even lines come from different banks */
|
||||
if (h & 1) {
|
||||
if (h & 1)
|
||||
{
|
||||
x_width = src1[0] + 1;
|
||||
x_offs = src1[1] * scale * 8;
|
||||
base = src1[2] | (src1[3] << 8);
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
x_width = src2[0] + 1;
|
||||
x_offs = src2[1] * scale * 8;
|
||||
base = src2[2] | (src2[3] << 8);
|
||||
}
|
||||
|
||||
if (draw_this_line) {
|
||||
if (draw_this_line)
|
||||
{
|
||||
base *= 2;
|
||||
|
||||
if (!rotate)
|
||||
@ -446,7 +449,8 @@ void tzbx15_device::draw_sprites_main(BitmapClass &bitmap, const rectangle &clip
|
||||
else
|
||||
x_pos = x_offs;
|
||||
|
||||
for (int w = 0; w < x_width; w++) {
|
||||
for (int w = 0; w < x_width; w++)
|
||||
{
|
||||
if (rotate)
|
||||
roundupt_drawgfxzoomrotate(
|
||||
m_temp_bitmap,cliprect,gfx(0 + (base & 1)),
|
||||
|
@ -15,8 +15,8 @@ public:
|
||||
template <typename T> void set_basepalette(T &&tag) { m_palette_base.set_tag(std::forward<T>(tag)); }
|
||||
template <typename T> void set_spriteram(T &&tag) { m_spriteram.set_tag(std::forward<T>(tag)); }
|
||||
|
||||
void draw_sprites(bitmap_rgb32& bitmap, const rectangle& cliprect, int write_priority_only, int rambank);
|
||||
void draw_sprites(bitmap_ind8& bitmap, const rectangle& cliprect, int write_priority_only, int rambank);
|
||||
void draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect, int write_priority_only, int rambank);
|
||||
void draw_sprites(bitmap_ind8 &bitmap, const rectangle &cliprect, int write_priority_only, int rambank);
|
||||
|
||||
void update_cluts();
|
||||
|
||||
@ -31,8 +31,6 @@ private:
|
||||
virtual void device_start() override ATTR_COLD;
|
||||
virtual void device_reset() override ATTR_COLD;
|
||||
|
||||
void common_init() ATTR_COLD;
|
||||
|
||||
void mycopyrozbitmap_core(bitmap_ind8 &bitmap, const bitmap_rgb32 &srcbitmap,
|
||||
int dstx, int dsty, int srcwidth, int srcheight, int incxx, int incxy, int incyx, int incyy,
|
||||
const rectangle &clip, int transparent_color);
|
||||
@ -41,9 +39,12 @@ private:
|
||||
const rectangle &clip, int transparent_color);
|
||||
|
||||
template<class BitmapClass> void draw_sprites_main(BitmapClass &bitmap, const rectangle &cliprect, int write_priority_only, int rambank);
|
||||
template<class BitmapClass> inline void roundupt_drawgfxzoomrotate( BitmapClass &dest_bmp, const rectangle &clip,
|
||||
gfx_element *gfx, uint32_t code,uint32_t color,int flipx,int flipy,uint32_t ssx,uint32_t ssy,
|
||||
int scalex, int scaley, int rotate, int write_priority_only );
|
||||
template<class BitmapClass> void roundupt_drawgfxzoomrotate(
|
||||
BitmapClass &dest_bmp, const rectangle &clip,
|
||||
gfx_element *gfx, uint32_t code, uint32_t color,
|
||||
int flipx, int flipy, uint32_t ssx, uint32_t ssy,
|
||||
int scalex, int scaley, int rotate,
|
||||
int write_priority_only);
|
||||
|
||||
DECLARE_GFXDECODE_MEMBER(gfxinfo);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user