mirror of
https://github.com/holub/mame
synced 2025-04-22 16:31:49 +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);
|
||||
|
||||
int op_offset = 0;
|
||||
/* process condition codes for this instruction */
|
||||
if ((insn >> INSN_COND_SHIFT) != COND_AL)
|
||||
{
|
||||
@ -717,13 +718,17 @@ void arm7_cpu_device::execute_run()
|
||||
{ UNEXECUTED(); goto skip_exec; }
|
||||
break;
|
||||
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 */
|
||||
/*******************************************************************/
|
||||
(this->*ops_handler[((insn & 0xF000000) >> 24)])(insn);
|
||||
(this->*ops_handler[((insn & 0xF000000) >> 24) + op_offset])(insn);
|
||||
}
|
||||
|
||||
skip_exec:
|
||||
|
@ -126,7 +126,7 @@ protected:
|
||||
void HandleCoProcDO(uint32_t insn);
|
||||
void HandleCoProcRT(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 HandleHalfWordDT(uint32_t insn);
|
||||
void HandleSwap(uint32_t insn);
|
||||
@ -136,6 +136,7 @@ protected:
|
||||
void HandleSMulLong(uint32_t insn);
|
||||
void HandleUMulLong(uint32_t insn);
|
||||
void HandleMemBlock(uint32_t insn);
|
||||
|
||||
void arm7ops_0123(uint32_t insn);
|
||||
void arm7ops_4567(uint32_t insn);
|
||||
void arm7ops_89(uint32_t insn);
|
||||
@ -143,6 +144,15 @@ protected:
|
||||
void arm7ops_cd(uint32_t insn);
|
||||
void arm7ops_e(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);
|
||||
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 );
|
||||
@ -268,7 +278,7 @@ protected:
|
||||
static const arm7thumb_ophandler thumb_handler[0x40*0x10];
|
||||
|
||||
typedef void ( arm7_cpu_device::*arm7ops_ophandler )(uint32_t);
|
||||
static const arm7ops_ophandler ops_handler[0x10];
|
||||
static const arm7ops_ophandler ops_handler[0x20];
|
||||
|
||||
//
|
||||
// DRC
|
||||
|
@ -172,14 +172,19 @@ static void WriteRegisterOperand1( std::ostream &stream, uint32_t opcode )
|
||||
} /* 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;
|
||||
if( opcode&0x00800000 )
|
||||
opcode <<= 2;
|
||||
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 );
|
||||
} /* WriteBranchAddress */
|
||||
|
||||
@ -205,7 +210,18 @@ static uint32_t arm7_disasm( std::ostream &stream, uint32_t pc, uint32_t opcode
|
||||
|
||||
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) */
|
||||
util::stream_format( stream, "B");
|
||||
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);
|
||||
|
||||
WriteBranchAddress( stream, pc, opcode );
|
||||
WriteBranchAddress( stream, pc, opcode, false );
|
||||
}
|
||||
else if( (opcode&0x0e000000)==0x0c000000 ) //bits 27-25 == 110
|
||||
{
|
||||
|
@ -378,9 +378,14 @@ void arm7_cpu_device::HandleCoProcDT(uint32_t insn)
|
||||
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;
|
||||
if (h_bit)
|
||||
{
|
||||
// H goes to bit1
|
||||
off |= (insn & 0x01000000) >> 23;
|
||||
}
|
||||
|
||||
/* Save PC into LR if this is a branch with link */
|
||||
if (insn & INSN_BL)
|
||||
@ -1519,14 +1524,95 @@ void arm7_cpu_device::HandleMemBlock(uint32_t insn)
|
||||
} /* 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_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_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)
|
||||
{
|
||||
//case 0:
|
||||
@ -1824,7 +1910,7 @@ void arm7_cpu_device::arm7ops_ab(uint32_t insn) /* Branch or Branch & Link */
|
||||
{
|
||||
//case 0xa:
|
||||
//case 0xb:
|
||||
HandleBranch(insn);
|
||||
HandleBranch(insn, false);
|
||||
// break;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user