mirror of
https://github.com/holub/mame
synced 2025-10-06 17:08:28 +03:00
ARMv5 additions to ARM7
This commit is contained in:
parent
4a7f62957b
commit
976647a292
@ -655,6 +655,7 @@ void arm7_cpu_device::execute_run()
|
|||||||
|
|
||||||
insn = m_direct->read_dword(raddr);
|
insn = m_direct->read_dword(raddr);
|
||||||
|
|
||||||
|
int op_offset = 0;
|
||||||
/* process condition codes for this instruction */
|
/* process condition codes for this instruction */
|
||||||
if ((insn >> INSN_COND_SHIFT) != COND_AL)
|
if ((insn >> INSN_COND_SHIFT) != COND_AL)
|
||||||
{
|
{
|
||||||
@ -717,13 +718,17 @@ void arm7_cpu_device::execute_run()
|
|||||||
{ UNEXECUTED(); goto skip_exec; }
|
{ UNEXECUTED(); goto skip_exec; }
|
||||||
break;
|
break;
|
||||||
case COND_NV:
|
case COND_NV:
|
||||||
{ UNEXECUTED(); goto skip_exec; }
|
if (m_archRev < 5)
|
||||||
|
{ UNEXECUTED(); goto skip_exec; }
|
||||||
|
else
|
||||||
|
op_offset = 0x10;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*******************************************************************/
|
/*******************************************************************/
|
||||||
/* If we got here - condition satisfied, so decode the instruction */
|
/* If we got here - condition satisfied, so decode the instruction */
|
||||||
/*******************************************************************/
|
/*******************************************************************/
|
||||||
(this->*ops_handler[((insn & 0xF000000) >> 24)])(insn);
|
(this->*ops_handler[((insn & 0xF000000) >> 24) + op_offset])(insn);
|
||||||
}
|
}
|
||||||
|
|
||||||
skip_exec:
|
skip_exec:
|
||||||
|
@ -126,7 +126,7 @@ protected:
|
|||||||
void HandleCoProcDO(uint32_t insn);
|
void HandleCoProcDO(uint32_t insn);
|
||||||
void HandleCoProcRT(uint32_t insn);
|
void HandleCoProcRT(uint32_t insn);
|
||||||
void HandleCoProcDT(uint32_t insn);
|
void HandleCoProcDT(uint32_t insn);
|
||||||
void HandleBranch(uint32_t insn);
|
void HandleBranch(uint32_t insn, bool h_bit);
|
||||||
void HandleMemSingle(uint32_t insn);
|
void HandleMemSingle(uint32_t insn);
|
||||||
void HandleHalfWordDT(uint32_t insn);
|
void HandleHalfWordDT(uint32_t insn);
|
||||||
void HandleSwap(uint32_t insn);
|
void HandleSwap(uint32_t insn);
|
||||||
@ -136,6 +136,7 @@ protected:
|
|||||||
void HandleSMulLong(uint32_t insn);
|
void HandleSMulLong(uint32_t insn);
|
||||||
void HandleUMulLong(uint32_t insn);
|
void HandleUMulLong(uint32_t insn);
|
||||||
void HandleMemBlock(uint32_t insn);
|
void HandleMemBlock(uint32_t insn);
|
||||||
|
|
||||||
void arm7ops_0123(uint32_t insn);
|
void arm7ops_0123(uint32_t insn);
|
||||||
void arm7ops_4567(uint32_t insn);
|
void arm7ops_4567(uint32_t insn);
|
||||||
void arm7ops_89(uint32_t insn);
|
void arm7ops_89(uint32_t insn);
|
||||||
@ -143,6 +144,15 @@ protected:
|
|||||||
void arm7ops_cd(uint32_t insn);
|
void arm7ops_cd(uint32_t insn);
|
||||||
void arm7ops_e(uint32_t insn);
|
void arm7ops_e(uint32_t insn);
|
||||||
void arm7ops_f(uint32_t insn);
|
void arm7ops_f(uint32_t insn);
|
||||||
|
|
||||||
|
void arm9ops_undef(uint32_t insn);
|
||||||
|
void arm9ops_1(uint32_t insn);
|
||||||
|
void arm9ops_57(uint32_t insn);
|
||||||
|
void arm9ops_89(uint32_t insn);
|
||||||
|
void arm9ops_ab(uint32_t insn);
|
||||||
|
void arm9ops_c(uint32_t insn);
|
||||||
|
void arm9ops_e(uint32_t insn);
|
||||||
|
|
||||||
void set_cpsr(uint32_t val);
|
void set_cpsr(uint32_t val);
|
||||||
bool arm7_tlb_translate(offs_t &addr, int flags);
|
bool arm7_tlb_translate(offs_t &addr, int flags);
|
||||||
uint32_t arm7_tlb_get_second_level_descriptor( uint32_t granularity, uint32_t first_desc, uint32_t vaddr );
|
uint32_t arm7_tlb_get_second_level_descriptor( uint32_t granularity, uint32_t first_desc, uint32_t vaddr );
|
||||||
@ -268,7 +278,7 @@ protected:
|
|||||||
static const arm7thumb_ophandler thumb_handler[0x40*0x10];
|
static const arm7thumb_ophandler thumb_handler[0x40*0x10];
|
||||||
|
|
||||||
typedef void ( arm7_cpu_device::*arm7ops_ophandler )(uint32_t);
|
typedef void ( arm7_cpu_device::*arm7ops_ophandler )(uint32_t);
|
||||||
static const arm7ops_ophandler ops_handler[0x10];
|
static const arm7ops_ophandler ops_handler[0x20];
|
||||||
|
|
||||||
//
|
//
|
||||||
// DRC
|
// DRC
|
||||||
|
@ -172,14 +172,19 @@ static void WriteRegisterOperand1( std::ostream &stream, uint32_t opcode )
|
|||||||
} /* WriteRegisterOperand */
|
} /* WriteRegisterOperand */
|
||||||
|
|
||||||
|
|
||||||
static void WriteBranchAddress( std::ostream &stream, uint32_t pc, uint32_t opcode )
|
static void WriteBranchAddress( std::ostream &stream, uint32_t pc, uint32_t opcode, bool h_bit )
|
||||||
{
|
{
|
||||||
opcode &= 0x00ffffff;
|
opcode <<= 2;
|
||||||
if( opcode&0x00800000 )
|
if (h_bit && (opcode & 0x04000000))
|
||||||
{
|
{
|
||||||
opcode |= 0xff000000; /* sign-extend */
|
opcode |= 2;
|
||||||
}
|
}
|
||||||
pc += 8+4*opcode;
|
opcode &= 0x03fffffe;
|
||||||
|
if( opcode & 0x02000000 )
|
||||||
|
{
|
||||||
|
opcode |= 0xfc000000; /* sign-extend */
|
||||||
|
}
|
||||||
|
pc += 8+opcode;
|
||||||
util::stream_format( stream, "$%x", pc );
|
util::stream_format( stream, "$%x", pc );
|
||||||
} /* WriteBranchAddress */
|
} /* WriteBranchAddress */
|
||||||
|
|
||||||
@ -205,7 +210,18 @@ static uint32_t arm7_disasm( std::ostream &stream, uint32_t pc, uint32_t opcode
|
|||||||
|
|
||||||
pConditionCode= pConditionCodeTable[opcode>>28];
|
pConditionCode= pConditionCodeTable[opcode>>28];
|
||||||
|
|
||||||
if( (opcode&0x0ffffff0)==0x012fff10 ) { //bits 27-4 == 000100101111111111110001
|
if( (opcode&0xfe000000)==0xfa000000 ) //bits 31-25 == 1111 101 (BLX - v5)
|
||||||
|
{
|
||||||
|
/* BLX */
|
||||||
|
util::stream_format( stream, "BLX" );
|
||||||
|
dasmflags = DASMFLAG_STEP_OVER;
|
||||||
|
|
||||||
|
WritePadding(stream, start_position);
|
||||||
|
|
||||||
|
WriteBranchAddress( stream, pc, opcode, true );
|
||||||
|
}
|
||||||
|
else if( (opcode&0x0ffffff0)==0x012fff10 ) //bits 27-4 == 000100101111111111110001
|
||||||
|
{
|
||||||
/* Branch and Exchange (BX) */
|
/* Branch and Exchange (BX) */
|
||||||
util::stream_format( stream, "B");
|
util::stream_format( stream, "B");
|
||||||
util::stream_format( stream, "%sX", pConditionCode );
|
util::stream_format( stream, "%sX", pConditionCode );
|
||||||
@ -636,7 +652,7 @@ static uint32_t arm7_disasm( std::ostream &stream, uint32_t pc, uint32_t opcode
|
|||||||
|
|
||||||
WritePadding(stream, start_position);
|
WritePadding(stream, start_position);
|
||||||
|
|
||||||
WriteBranchAddress( stream, pc, opcode );
|
WriteBranchAddress( stream, pc, opcode, false );
|
||||||
}
|
}
|
||||||
else if( (opcode&0x0e000000)==0x0c000000 ) //bits 27-25 == 110
|
else if( (opcode&0x0e000000)==0x0c000000 ) //bits 27-25 == 110
|
||||||
{
|
{
|
||||||
|
@ -378,9 +378,14 @@ void arm7_cpu_device::HandleCoProcDT(uint32_t insn)
|
|||||||
SetRegister(rn, ornv);
|
SetRegister(rn, ornv);
|
||||||
}
|
}
|
||||||
|
|
||||||
void arm7_cpu_device::HandleBranch(uint32_t insn)
|
void arm7_cpu_device::HandleBranch(uint32_t insn, bool h_bit)
|
||||||
{
|
{
|
||||||
uint32_t off = (insn & INSN_BRANCH) << 2;
|
uint32_t off = (insn & INSN_BRANCH) << 2;
|
||||||
|
if (h_bit)
|
||||||
|
{
|
||||||
|
// H goes to bit1
|
||||||
|
off |= (insn & 0x01000000) >> 23;
|
||||||
|
}
|
||||||
|
|
||||||
/* Save PC into LR if this is a branch with link */
|
/* Save PC into LR if this is a branch with link */
|
||||||
if (insn & INSN_BL)
|
if (insn & INSN_BL)
|
||||||
@ -1519,14 +1524,95 @@ void arm7_cpu_device::HandleMemBlock(uint32_t insn)
|
|||||||
} /* HandleMemBlock */
|
} /* HandleMemBlock */
|
||||||
|
|
||||||
|
|
||||||
const arm7_cpu_device::arm7ops_ophandler arm7_cpu_device::ops_handler[0x10] =
|
const arm7_cpu_device::arm7ops_ophandler arm7_cpu_device::ops_handler[0x20] =
|
||||||
{
|
{
|
||||||
&arm7_cpu_device::arm7ops_0123, &arm7_cpu_device::arm7ops_0123, &arm7_cpu_device::arm7ops_0123, &arm7_cpu_device::arm7ops_0123,
|
&arm7_cpu_device::arm7ops_0123, &arm7_cpu_device::arm7ops_0123, &arm7_cpu_device::arm7ops_0123, &arm7_cpu_device::arm7ops_0123,
|
||||||
&arm7_cpu_device::arm7ops_4567, &arm7_cpu_device::arm7ops_4567, &arm7_cpu_device::arm7ops_4567, &arm7_cpu_device::arm7ops_4567,
|
&arm7_cpu_device::arm7ops_4567, &arm7_cpu_device::arm7ops_4567, &arm7_cpu_device::arm7ops_4567, &arm7_cpu_device::arm7ops_4567,
|
||||||
&arm7_cpu_device::arm7ops_89, &arm7_cpu_device::arm7ops_89, &arm7_cpu_device::arm7ops_ab, &arm7_cpu_device::arm7ops_ab,
|
&arm7_cpu_device::arm7ops_89, &arm7_cpu_device::arm7ops_89, &arm7_cpu_device::arm7ops_ab, &arm7_cpu_device::arm7ops_ab,
|
||||||
&arm7_cpu_device::arm7ops_cd, &arm7_cpu_device::arm7ops_cd, &arm7_cpu_device::arm7ops_e, &arm7_cpu_device::arm7ops_f,
|
&arm7_cpu_device::arm7ops_cd, &arm7_cpu_device::arm7ops_cd, &arm7_cpu_device::arm7ops_e, &arm7_cpu_device::arm7ops_f,
|
||||||
|
&arm7_cpu_device::arm9ops_undef,&arm7_cpu_device::arm9ops_1, &arm7_cpu_device::arm9ops_undef,&arm7_cpu_device::arm9ops_undef,
|
||||||
|
&arm7_cpu_device::arm9ops_undef,&arm7_cpu_device::arm9ops_57, &arm7_cpu_device::arm9ops_undef,&arm7_cpu_device::arm9ops_57,
|
||||||
|
&arm7_cpu_device::arm9ops_89, &arm7_cpu_device::arm9ops_89, &arm7_cpu_device::arm9ops_ab, &arm7_cpu_device::arm9ops_ab,
|
||||||
|
&arm7_cpu_device::arm9ops_c, &arm7_cpu_device::arm9ops_undef,&arm7_cpu_device::arm9ops_e, &arm7_cpu_device::arm9ops_undef,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void arm7_cpu_device::arm9ops_undef(uint32_t insn)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void arm7_cpu_device::arm9ops_1(uint32_t insn)
|
||||||
|
{
|
||||||
|
/* Change processor state (CPS) */
|
||||||
|
if ((insn & 0x00f10020) == 0x00000000)
|
||||||
|
{
|
||||||
|
// unsupported (armv6 onwards only)
|
||||||
|
}
|
||||||
|
else if ((insn & 0x00ff00f0) == 0x00010000) /* set endianness (SETEND) */
|
||||||
|
{
|
||||||
|
// unsupported (armv6 onwards only)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
arm9ops_undef(insn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void arm7_cpu_device::arm9ops_57(uint32_t insn)
|
||||||
|
{
|
||||||
|
/* Cache Preload (PLD) */
|
||||||
|
if ((insn & 0x0070f000) == 0x0050f000)
|
||||||
|
{
|
||||||
|
// unsupported (armv6 onwards only)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
arm9ops_undef(insn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void arm7_cpu_device::arm9ops_89(uint32_t insn)
|
||||||
|
{
|
||||||
|
/* Save Return State (SRS) */
|
||||||
|
if ((insn & 0x005f0f00) == 0x004d0500)
|
||||||
|
{
|
||||||
|
// unsupported (armv6 onwards only)
|
||||||
|
}
|
||||||
|
else if ((insn & 0x00500f00) == 0x00100a00) /* Return From Exception (RFE) */
|
||||||
|
{
|
||||||
|
// unsupported (armv6 onwards only)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
arm9ops_undef(insn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void arm7_cpu_device::arm9ops_ab(uint32_t insn)
|
||||||
|
{
|
||||||
|
// blx
|
||||||
|
HandleBranch(insn, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void arm7_cpu_device::arm9ops_c(uint32_t insn)
|
||||||
|
{
|
||||||
|
/* Additional coprocessor double register transfer */
|
||||||
|
if ((insn & 0x00e00000) == 0x00400000)
|
||||||
|
{
|
||||||
|
// unsupported
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
arm9ops_undef(insn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void arm7_cpu_device::arm9ops_e(uint32_t insn)
|
||||||
|
{
|
||||||
|
/* Additional coprocessor register transfer */
|
||||||
|
// unsupported
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void arm7_cpu_device::arm7ops_0123(uint32_t insn)
|
void arm7_cpu_device::arm7ops_0123(uint32_t insn)
|
||||||
{
|
{
|
||||||
//case 0:
|
//case 0:
|
||||||
@ -1824,7 +1910,7 @@ void arm7_cpu_device::arm7ops_ab(uint32_t insn) /* Branch or Branch & Link */
|
|||||||
{
|
{
|
||||||
//case 0xa:
|
//case 0xa:
|
||||||
//case 0xb:
|
//case 0xb:
|
||||||
HandleBranch(insn);
|
HandleBranch(insn, false);
|
||||||
// break;
|
// break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user