mirror of
https://github.com/holub/mame
synced 2025-04-23 08:49:55 +03:00
-arm7: Performed some minor optimization. [Ryan Holtz]
This commit is contained in:
parent
66c56d1c9a
commit
12aa436b96
@ -125,9 +125,14 @@ sa1110_cpu_device::sa1110_cpu_device(const machine_config &mconfig, const char *
|
||||
{
|
||||
}
|
||||
|
||||
void arm7_cpu_device::update_reg_ptr()
|
||||
{
|
||||
m_reg_group = sRegisterTable[GET_MODE];
|
||||
}
|
||||
|
||||
void arm7_cpu_device::set_cpsr(UINT32 val)
|
||||
{
|
||||
UINT8 old_mode = GET_CPSR & MODE_FLAG;
|
||||
if (m_archFlags & eARM_ARCHFLAGS_MODE26)
|
||||
{
|
||||
if ((val & 0x10) != (m_r[eCPSR] & 0x10))
|
||||
@ -158,6 +163,10 @@ void arm7_cpu_device::set_cpsr(UINT32 val)
|
||||
val |= 0x10; // force valid mode
|
||||
}
|
||||
m_r[eCPSR] = val;
|
||||
if ((GET_CPSR & MODE_FLAG) != old_mode)
|
||||
{
|
||||
update_reg_ptr();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -179,13 +188,6 @@ enum
|
||||
};
|
||||
|
||||
|
||||
UINT32 arm7_cpu_device::arm7_tlb_get_first_level_descriptor( UINT32 vaddr )
|
||||
{
|
||||
UINT32 entry_paddr = ( m_tlbBase & COPRO_TLB_BASE_MASK ) | ( ( vaddr & COPRO_TLB_VADDR_FLTI_MASK ) >> COPRO_TLB_VADDR_FLTI_MASK_SHIFT );
|
||||
return m_program->read_dword( entry_paddr );
|
||||
}
|
||||
|
||||
|
||||
// COARSE, desc_level1, vaddr
|
||||
UINT32 arm7_cpu_device::arm7_tlb_get_second_level_descriptor( UINT32 granularity, UINT32 first_desc, UINT32 vaddr )
|
||||
{
|
||||
@ -209,9 +211,9 @@ UINT32 arm7_cpu_device::arm7_tlb_get_second_level_descriptor( UINT32 granularity
|
||||
}
|
||||
|
||||
|
||||
int arm7_cpu_device::detect_fault(int permission, int ap, int flags)
|
||||
int arm7_cpu_device::detect_fault(int desc_lvl1, int ap, int flags)
|
||||
{
|
||||
switch (permission)
|
||||
switch (m_decoded_access_control[(desc_lvl1 >> 5) & 0xf])
|
||||
{
|
||||
case 0 : // "No access - Any access generates a domain fault"
|
||||
{
|
||||
@ -219,62 +221,56 @@ int arm7_cpu_device::detect_fault(int permission, int ap, int flags)
|
||||
}
|
||||
case 1 : // "Client - Accesses are checked against the access permission bits in the section or page descriptor"
|
||||
{
|
||||
switch (ap)
|
||||
if ((ap & 3) == 3)
|
||||
{
|
||||
case 0 :
|
||||
return FAULT_NONE;
|
||||
}
|
||||
else if (ap & 2)
|
||||
{
|
||||
if (((m_r[eCPSR] & MODE_FLAG) == eARM7_MODE_USER) && (flags & ARM7_TLB_WRITE))
|
||||
{
|
||||
int s = (m_control & COPRO_CTRL_SYSTEM) ? 1 : 0;
|
||||
int r = (m_control & COPRO_CTRL_ROM) ? 1 : 0;
|
||||
if (s == 0)
|
||||
return FAULT_PERMISSION;
|
||||
}
|
||||
}
|
||||
else if (ap & 1)
|
||||
{
|
||||
if ((m_r[eCPSR] & MODE_FLAG) == eARM7_MODE_USER)
|
||||
{
|
||||
return FAULT_PERMISSION;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int s = (m_control & COPRO_CTRL_SYSTEM) ? 1 : 0;
|
||||
int r = (m_control & COPRO_CTRL_ROM) ? 1 : 0;
|
||||
if (s == 0)
|
||||
{
|
||||
if (r == 0) // "Any access generates a permission fault"
|
||||
{
|
||||
if (r == 0) // "Any access generates a permission fault"
|
||||
{
|
||||
return FAULT_PERMISSION;
|
||||
}
|
||||
else // "Any write generates a permission fault"
|
||||
{
|
||||
if (flags & ARM7_TLB_WRITE)
|
||||
{
|
||||
return FAULT_PERMISSION;
|
||||
}
|
||||
}
|
||||
return FAULT_PERMISSION;
|
||||
}
|
||||
else
|
||||
else // "Any write generates a permission fault"
|
||||
{
|
||||
if (r == 0) // "Only Supervisor read permitted"
|
||||
{
|
||||
if (((m_r[eCPSR] & MODE_FLAG) == eARM7_MODE_USER) || (flags & ARM7_TLB_WRITE))
|
||||
{
|
||||
return FAULT_PERMISSION;
|
||||
}
|
||||
}
|
||||
else // "Reserved" -> assume same behaviour as S=0/R=0 case
|
||||
if (flags & ARM7_TLB_WRITE)
|
||||
{
|
||||
return FAULT_PERMISSION;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1 : // "Access allowed only in Supervisor mode"
|
||||
else
|
||||
{
|
||||
if ((m_r[eCPSR] & MODE_FLAG) == eARM7_MODE_USER)
|
||||
if (r == 0) // "Only Supervisor read permitted"
|
||||
{
|
||||
if (((m_r[eCPSR] & MODE_FLAG) == eARM7_MODE_USER) || (flags & ARM7_TLB_WRITE))
|
||||
{
|
||||
return FAULT_PERMISSION;
|
||||
}
|
||||
}
|
||||
else // "Reserved" -> assume same behaviour as S=0/R=0 case
|
||||
{
|
||||
return FAULT_PERMISSION;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2 : // "Writes in User mode cause permission fault"
|
||||
{
|
||||
if (((m_r[eCPSR] & MODE_FLAG) == eARM7_MODE_USER) && (flags & ARM7_TLB_WRITE))
|
||||
{
|
||||
return FAULT_PERMISSION;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 3 : // "All access types permitted in both modes"
|
||||
{
|
||||
return FAULT_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -293,30 +289,17 @@ int arm7_cpu_device::detect_fault(int permission, int ap, int flags)
|
||||
|
||||
bool arm7_cpu_device::arm7_tlb_translate(offs_t &addr, int flags)
|
||||
{
|
||||
UINT32 desc_lvl1;
|
||||
UINT32 desc_lvl2 = 0;
|
||||
UINT32 paddr, vaddr = addr;
|
||||
UINT8 domain, permission;
|
||||
|
||||
if (vaddr < 32 * 1024 * 1024)
|
||||
if (addr < 0x2000000)
|
||||
{
|
||||
UINT32 pid = ((m_fcsePID >> 25) & 0x7F);
|
||||
if (pid > 0)
|
||||
{
|
||||
//LOG( ( "ARM7: FCSE PID vaddr %08X -> %08X\n", vaddr, vaddr + (pid * (32 * 1024 * 1024))) );
|
||||
vaddr = vaddr + (((m_fcsePID >> 25) & 0x7F) * (32 * 1024 * 1024));
|
||||
}
|
||||
addr += m_pid_offset;
|
||||
}
|
||||
|
||||
desc_lvl1 = arm7_tlb_get_first_level_descriptor( vaddr );
|
||||
|
||||
paddr = vaddr;
|
||||
UINT32 desc_lvl1 = m_program->read_dword(m_tlb_base_mask | ((addr & COPRO_TLB_VADDR_FLTI_MASK) >> COPRO_TLB_VADDR_FLTI_MASK_SHIFT));
|
||||
|
||||
#if ARM7_MMU_ENABLE_HACK
|
||||
if ((m_r[eR15] == (m_mmu_enable_addr + 4)) || (m_r[eR15] == (m_mmu_enable_addr + 8)))
|
||||
{
|
||||
LOG( ( "ARM7: fetch flat, PC = %08x, vaddr = %08x\n", m_r[eR15], vaddr ) );
|
||||
*addr = vaddr;
|
||||
LOG( ( "ARM7: fetch flat, PC = %08x, vaddr = %08x\n", m_r[eR15], addr ) );
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@ -325,132 +308,113 @@ bool arm7_cpu_device::arm7_tlb_translate(offs_t &addr, int flags)
|
||||
}
|
||||
#endif
|
||||
|
||||
domain = (desc_lvl1 >> 5) & 0xF;
|
||||
permission = (m_domainAccessControl >> (domain << 1)) & 3;
|
||||
|
||||
switch( desc_lvl1 & 3 )
|
||||
UINT8 tlb_type = desc_lvl1 & 3;
|
||||
if (tlb_type == COPRO_TLB_SECTION_TABLE)
|
||||
{
|
||||
case COPRO_TLB_UNMAPPED:
|
||||
// Unmapped, generate a translation fault
|
||||
// Entry is a section
|
||||
int fault = detect_fault(desc_lvl1, (desc_lvl1 >> 10) & 3, flags);
|
||||
if (fault == FAULT_NONE)
|
||||
{
|
||||
addr = ( desc_lvl1 & COPRO_TLB_SECTION_PAGE_MASK ) | ( addr & ~COPRO_TLB_SECTION_PAGE_MASK );
|
||||
}
|
||||
else
|
||||
{
|
||||
if (flags & ARM7_TLB_ABORT_D)
|
||||
{
|
||||
LOG( ( "ARM7: Translation fault on unmapped virtual address, PC = %08x, vaddr = %08x\n", m_r[eR15], vaddr ) );
|
||||
m_faultStatus[0] = (5 << 0); // 5 = section translation fault
|
||||
m_faultAddress = vaddr;
|
||||
m_pendingAbtD = 1;
|
||||
UINT8 domain = (desc_lvl1 >> 5) & 0xF;
|
||||
LOG( ( "ARM7: Section Table, Section %s fault on virtual address, vaddr = %08x, PC = %08x\n", (fault == FAULT_DOMAIN) ? "domain" : "permission", addr, m_r[eR15] ) );
|
||||
m_faultStatus[0] = ((fault == FAULT_DOMAIN) ? (9 << 0) : (13 << 0)) | (domain << 4); // 9 = section domain fault, 13 = section permission fault
|
||||
m_faultAddress = addr;
|
||||
m_pendingAbtD = true;
|
||||
LOG( ( "vaddr %08X desc_lvl1 %08X domain %d permission %d ap %d s %d r %d mode %d read %d write %d\n",
|
||||
addr, desc_lvl1, domain, (m_domainAccessControl >> ((desc_lvl1 >> 4) & 0x1e)) & 3, (desc_lvl1 >> 10) & 3, (m_control & COPRO_CTRL_SYSTEM) ? 1 : 0, (m_control & COPRO_CTRL_ROM) ? 1 : 0,
|
||||
m_r[eCPSR] & MODE_FLAG, flags & ARM7_TLB_READ ? 1 : 0, flags & ARM7_TLB_WRITE ? 1 : 0) );
|
||||
}
|
||||
else if (flags & ARM7_TLB_ABORT_P)
|
||||
{
|
||||
LOG( ( "ARM7: Translation fault on unmapped virtual address, PC = %08x, vaddr = %08x\n", m_r[eR15], vaddr ) );
|
||||
m_pendingAbtP = 1;
|
||||
LOG( ( "ARM7: Section Table, Section %s fault on virtual address, vaddr = %08x, PC = %08x\n", (fault == FAULT_DOMAIN) ? "domain" : "permission", addr, m_r[eR15] ) );
|
||||
m_pendingAbtP = true;
|
||||
}
|
||||
return FALSE;
|
||||
case COPRO_TLB_COARSE_TABLE:
|
||||
// Entry is the physical address of a coarse second-level table
|
||||
if ((permission == 1) || (permission == 3))
|
||||
{
|
||||
desc_lvl2 = arm7_tlb_get_second_level_descriptor( TLB_COARSE, desc_lvl1, vaddr );
|
||||
}
|
||||
else
|
||||
{
|
||||
fatalerror("ARM7: Not Yet Implemented: Coarse Table, Section Domain fault on virtual address, vaddr = %08x, domain = %08x, PC = %08x\n", vaddr, domain, m_r[eR15]);
|
||||
}
|
||||
break;
|
||||
case COPRO_TLB_SECTION_TABLE:
|
||||
{
|
||||
// Entry is a section
|
||||
UINT8 ap = (desc_lvl1 >> 10) & 3;
|
||||
int fault = detect_fault(permission, ap, flags);
|
||||
if (fault == FAULT_NONE)
|
||||
{
|
||||
paddr = ( desc_lvl1 & COPRO_TLB_SECTION_PAGE_MASK ) | ( vaddr & ~COPRO_TLB_SECTION_PAGE_MASK );
|
||||
}
|
||||
else
|
||||
{
|
||||
if (flags & ARM7_TLB_ABORT_D)
|
||||
{
|
||||
LOG( ( "ARM7: Section Table, Section %s fault on virtual address, vaddr = %08x, PC = %08x\n", (fault == FAULT_DOMAIN) ? "domain" : "permission", vaddr, m_r[eR15] ) );
|
||||
m_faultStatus[0] = ((fault == FAULT_DOMAIN) ? (9 << 0) : (13 << 0)) | (domain << 4); // 9 = section domain fault, 13 = section permission fault
|
||||
m_faultAddress = vaddr;
|
||||
m_pendingAbtD = 1;
|
||||
LOG( ( "vaddr %08X desc_lvl1 %08X domain %d permission %d ap %d s %d r %d mode %d read %d write %d\n",
|
||||
vaddr, desc_lvl1, domain, permission, ap, (m_control & COPRO_CTRL_SYSTEM) ? 1 : 0, (m_control & COPRO_CTRL_ROM) ? 1 : 0,
|
||||
m_r[eCPSR] & MODE_FLAG, flags & ARM7_TLB_READ ? 1 : 0, flags & ARM7_TLB_WRITE ? 1 : 0) );
|
||||
}
|
||||
else if (flags & ARM7_TLB_ABORT_P)
|
||||
{
|
||||
LOG( ( "ARM7: Section Table, Section %s fault on virtual address, vaddr = %08x, PC = %08x\n", (fault == FAULT_DOMAIN) ? "domain" : "permission", vaddr, m_r[eR15] ) );
|
||||
m_pendingAbtP = 1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case COPRO_TLB_FINE_TABLE:
|
||||
// Entry is the physical address of a coarse second-level table
|
||||
if ((permission == 1) || (permission == 3))
|
||||
{
|
||||
desc_lvl2 = arm7_tlb_get_second_level_descriptor( TLB_FINE, desc_lvl1, vaddr );
|
||||
}
|
||||
else
|
||||
{
|
||||
fatalerror("ARM7: Not Yet Implemented: Fine Table, Section Domain fault on virtual address, vaddr = %08x, domain = %08x, PC = %08x\n", vaddr, domain, m_r[eR15]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// Entry is the physical address of a three-legged termite-eaten table
|
||||
break;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if( ( desc_lvl1 & 3 ) == COPRO_TLB_COARSE_TABLE || ( desc_lvl1 & 3 ) == COPRO_TLB_FINE_TABLE )
|
||||
else if (tlb_type == COPRO_TLB_UNMAPPED)
|
||||
{
|
||||
// Unmapped, generate a translation fault
|
||||
if (flags & ARM7_TLB_ABORT_D)
|
||||
{
|
||||
LOG( ( "ARM7: Translation fault on unmapped virtual address, PC = %08x, vaddr = %08x\n", m_r[eR15], addr ) );
|
||||
m_faultStatus[0] = (5 << 0); // 5 = section translation fault
|
||||
m_faultAddress = addr;
|
||||
m_pendingAbtD = true;
|
||||
}
|
||||
else if (flags & ARM7_TLB_ABORT_P)
|
||||
{
|
||||
LOG( ( "ARM7: Translation fault on unmapped virtual address, PC = %08x, vaddr = %08x\n", m_r[eR15], addr ) );
|
||||
m_pendingAbtP = true;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Entry is the physical address of a coarse second-level table
|
||||
UINT8 permission = (m_domainAccessControl >> ((desc_lvl1 >> 4) & 0x1e)) & 3;
|
||||
UINT32 desc_lvl2 = arm7_tlb_get_second_level_descriptor( (desc_lvl1 & 3) == COPRO_TLB_COARSE_TABLE ? TLB_COARSE : TLB_FINE, desc_lvl1, addr );
|
||||
if ((permission != 1) && (permission != 3))
|
||||
{
|
||||
UINT8 domain = (desc_lvl1 >> 5) & 0xF;
|
||||
fatalerror("ARM7: Not Yet Implemented: Coarse Table, Section Domain fault on virtual address, vaddr = %08x, domain = %08x, PC = %08x\n", addr, domain, m_r[eR15]);
|
||||
}
|
||||
|
||||
switch( desc_lvl2 & 3 )
|
||||
{
|
||||
case COPRO_TLB_UNMAPPED:
|
||||
// Unmapped, generate a translation fault
|
||||
if (flags & ARM7_TLB_ABORT_D)
|
||||
{
|
||||
LOG( ( "ARM7: Translation fault on unmapped virtual address, vaddr = %08x, PC %08X\n", vaddr, m_r[eR15] ) );
|
||||
UINT8 domain = (desc_lvl1 >> 5) & 0xF;
|
||||
LOG( ( "ARM7: Translation fault on unmapped virtual address, vaddr = %08x, PC %08X\n", addr, m_r[eR15] ) );
|
||||
m_faultStatus[0] = (7 << 0) | (domain << 4); // 7 = page translation fault
|
||||
m_faultAddress = vaddr;
|
||||
m_pendingAbtD = 1;
|
||||
m_faultAddress = addr;
|
||||
m_pendingAbtD = true;
|
||||
}
|
||||
else if (flags & ARM7_TLB_ABORT_P)
|
||||
{
|
||||
LOG( ( "ARM7: Translation fault on unmapped virtual address, vaddr = %08x, PC %08X\n", vaddr, m_r[eR15] ) );
|
||||
m_pendingAbtP = 1;
|
||||
LOG( ( "ARM7: Translation fault on unmapped virtual address, vaddr = %08x, PC %08X\n", addr, m_r[eR15] ) );
|
||||
m_pendingAbtP = true;
|
||||
}
|
||||
return FALSE;
|
||||
case COPRO_TLB_LARGE_PAGE:
|
||||
// Large page descriptor
|
||||
paddr = ( desc_lvl2 & COPRO_TLB_LARGE_PAGE_MASK ) | ( vaddr & ~COPRO_TLB_LARGE_PAGE_MASK );
|
||||
addr = ( desc_lvl2 & COPRO_TLB_LARGE_PAGE_MASK ) | ( addr & ~COPRO_TLB_LARGE_PAGE_MASK );
|
||||
break;
|
||||
case COPRO_TLB_SMALL_PAGE:
|
||||
// Small page descriptor
|
||||
{
|
||||
UINT8 ap = ((((desc_lvl2 >> 4) & 0xFF) >> (((vaddr >> 10) & 3) << 1)) & 3);
|
||||
int fault = detect_fault(permission, ap, flags);
|
||||
UINT8 ap = ((((desc_lvl2 >> 4) & 0xFF) >> (((addr >> 10) & 3) << 1)) & 3);
|
||||
int fault = detect_fault(desc_lvl1, ap, flags);
|
||||
if (fault == FAULT_NONE)
|
||||
{
|
||||
paddr = ( desc_lvl2 & COPRO_TLB_SMALL_PAGE_MASK ) | ( vaddr & ~COPRO_TLB_SMALL_PAGE_MASK );
|
||||
addr = ( desc_lvl2 & COPRO_TLB_SMALL_PAGE_MASK ) | ( addr & ~COPRO_TLB_SMALL_PAGE_MASK );
|
||||
}
|
||||
else
|
||||
{
|
||||
if (flags & ARM7_TLB_ABORT_D)
|
||||
{
|
||||
UINT8 domain = (desc_lvl1 >> 5) & 0xF;
|
||||
// hapyfish expects a data abort when something tries to write to a read-only memory location from user mode
|
||||
LOG( ( "ARM7: Page Table, Section %s fault on virtual address, vaddr = %08x, PC = %08x\n", (fault == FAULT_DOMAIN) ? "domain" : "permission", vaddr, m_r[eR15] ) );
|
||||
LOG( ( "ARM7: Page Table, Section %s fault on virtual address, vaddr = %08x, PC = %08x\n", (fault == FAULT_DOMAIN) ? "domain" : "permission", addr, m_r[eR15] ) );
|
||||
m_faultStatus[0] = ((fault == FAULT_DOMAIN) ? (11 << 0) : (15 << 0)) | (domain << 4); // 11 = page domain fault, 15 = page permission fault
|
||||
m_faultAddress = vaddr;
|
||||
m_pendingAbtD = 1;
|
||||
m_faultAddress = addr;
|
||||
m_pendingAbtD = true;
|
||||
LOG( ( "vaddr %08X desc_lvl2 %08X domain %d permission %d ap %d s %d r %d mode %d read %d write %d\n",
|
||||
vaddr, desc_lvl2, domain, permission, ap, (m_control & COPRO_CTRL_SYSTEM) ? 1 : 0, (m_control & COPRO_CTRL_ROM) ? 1 : 0,
|
||||
addr, desc_lvl2, domain, permission, ap, (m_control & COPRO_CTRL_SYSTEM) ? 1 : 0, (m_control & COPRO_CTRL_ROM) ? 1 : 0,
|
||||
m_r[eCPSR] & MODE_FLAG, flags & ARM7_TLB_READ ? 1 : 0, flags & ARM7_TLB_WRITE ? 1 : 0) );
|
||||
}
|
||||
else if (flags & ARM7_TLB_ABORT_P)
|
||||
{
|
||||
LOG( ( "ARM7: Page Table, Section %s fault on virtual address, vaddr = %08x, PC = %08x\n", (fault == FAULT_DOMAIN) ? "domain" : "permission", vaddr, m_r[eR15] ) );
|
||||
m_pendingAbtP = 1;
|
||||
LOG( ( "ARM7: Page Table, Section %s fault on virtual address, vaddr = %08x, PC = %08x\n", (fault == FAULT_DOMAIN) ? "domain" : "permission", addr, m_r[eR15] ) );
|
||||
m_pendingAbtP = true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -460,13 +424,13 @@ bool arm7_cpu_device::arm7_tlb_translate(offs_t &addr, int flags)
|
||||
// Tiny page descriptor
|
||||
if( ( desc_lvl1 & 3 ) == 1 )
|
||||
{
|
||||
LOG( ( "ARM7: It would appear that we're looking up a tiny page from a coarse TLB lookup. This is bad. vaddr = %08x\n", vaddr ) );
|
||||
LOG( ( "ARM7: It would appear that we're looking up a tiny page from a coarse TLB lookup. This is bad. vaddr = %08x\n", addr ) );
|
||||
}
|
||||
paddr = ( desc_lvl2 & COPRO_TLB_TINY_PAGE_MASK ) | ( vaddr & ~COPRO_TLB_TINY_PAGE_MASK );
|
||||
addr = ( desc_lvl2 & COPRO_TLB_TINY_PAGE_MASK ) | ( addr & ~COPRO_TLB_TINY_PAGE_MASK );
|
||||
break;
|
||||
}
|
||||
}
|
||||
addr = paddr;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -501,6 +465,9 @@ void arm7_cpu_device::device_start()
|
||||
save_item(NAME(m_pendingAbtP));
|
||||
save_item(NAME(m_pendingUnd));
|
||||
save_item(NAME(m_pendingSwi));
|
||||
save_item(NAME(m_pending_interrupt));
|
||||
save_item(NAME(m_fcsePID));
|
||||
save_item(NAME(m_pid_offset));
|
||||
|
||||
m_icountptr = &m_icount;
|
||||
|
||||
@ -588,19 +555,23 @@ void arm7_cpu_device::state_string_export(const device_state_entry &entry, std::
|
||||
void arm7_cpu_device::device_reset()
|
||||
{
|
||||
memset(m_r, 0, sizeof(m_r));
|
||||
m_pendingIrq = 0;
|
||||
m_pendingFiq = 0;
|
||||
m_pendingAbtD = 0;
|
||||
m_pendingAbtP = 0;
|
||||
m_pendingUnd = 0;
|
||||
m_pendingSwi = 0;
|
||||
m_pendingIrq = false;
|
||||
m_pendingFiq = false;
|
||||
m_pendingAbtD = false;
|
||||
m_pendingAbtP = false;
|
||||
m_pendingUnd = false;
|
||||
m_pendingSwi = false;
|
||||
m_pending_interrupt = false;
|
||||
m_control = 0;
|
||||
m_tlbBase = 0;
|
||||
m_tlb_base_mask = 0;
|
||||
m_faultStatus[0] = 0;
|
||||
m_faultStatus[1] = 0;
|
||||
m_faultAddress = 0;
|
||||
m_fcsePID = 0;
|
||||
m_pid_offset = 0;
|
||||
m_domainAccessControl = 0;
|
||||
memset(m_decoded_access_control, 0, sizeof(UINT8) * 16);
|
||||
|
||||
/* start up in SVC mode with interrupts disabled. */
|
||||
m_r[eCPSR] = I_MASK | F_MASK | 0x10;
|
||||
@ -677,66 +648,69 @@ void arm7_cpu_device::execute_run()
|
||||
insn = m_direct->read_dword(raddr);
|
||||
|
||||
/* process condition codes for this instruction */
|
||||
switch (insn >> INSN_COND_SHIFT)
|
||||
if ((insn >> INSN_COND_SHIFT) != COND_AL)
|
||||
{
|
||||
case COND_EQ:
|
||||
if (Z_IS_CLEAR(m_r[eCPSR]))
|
||||
switch (insn >> INSN_COND_SHIFT)
|
||||
{
|
||||
case COND_EQ:
|
||||
if (Z_IS_CLEAR(m_r[eCPSR]))
|
||||
{ UNEXECUTED(); goto skip_exec; }
|
||||
break;
|
||||
case COND_NE:
|
||||
if (Z_IS_SET(m_r[eCPSR]))
|
||||
{ UNEXECUTED(); goto skip_exec; }
|
||||
break;
|
||||
case COND_CS:
|
||||
if (C_IS_CLEAR(m_r[eCPSR]))
|
||||
{ UNEXECUTED(); goto skip_exec; }
|
||||
break;
|
||||
case COND_CC:
|
||||
if (C_IS_SET(m_r[eCPSR]))
|
||||
{ UNEXECUTED(); goto skip_exec; }
|
||||
break;
|
||||
case COND_MI:
|
||||
if (N_IS_CLEAR(m_r[eCPSR]))
|
||||
{ UNEXECUTED(); goto skip_exec; }
|
||||
break;
|
||||
case COND_PL:
|
||||
if (N_IS_SET(m_r[eCPSR]))
|
||||
{ UNEXECUTED(); goto skip_exec; }
|
||||
break;
|
||||
case COND_VS:
|
||||
if (V_IS_CLEAR(m_r[eCPSR]))
|
||||
{ UNEXECUTED(); goto skip_exec; }
|
||||
break;
|
||||
case COND_VC:
|
||||
if (V_IS_SET(m_r[eCPSR]))
|
||||
{ UNEXECUTED(); goto skip_exec; }
|
||||
break;
|
||||
case COND_HI:
|
||||
if (C_IS_CLEAR(m_r[eCPSR]) || Z_IS_SET(m_r[eCPSR]))
|
||||
{ UNEXECUTED(); goto skip_exec; }
|
||||
break;
|
||||
case COND_LS:
|
||||
if (C_IS_SET(m_r[eCPSR]) && Z_IS_CLEAR(m_r[eCPSR]))
|
||||
{ UNEXECUTED(); goto skip_exec; }
|
||||
break;
|
||||
case COND_GE:
|
||||
if (!(m_r[eCPSR] & N_MASK) != !(m_r[eCPSR] & V_MASK)) /* Use x ^ (x >> ...) method */
|
||||
{ UNEXECUTED(); goto skip_exec; }
|
||||
break;
|
||||
case COND_LT:
|
||||
if (!(m_r[eCPSR] & N_MASK) == !(m_r[eCPSR] & V_MASK))
|
||||
{ UNEXECUTED(); goto skip_exec; }
|
||||
break;
|
||||
case COND_GT:
|
||||
if (Z_IS_SET(m_r[eCPSR]) || (!(m_r[eCPSR] & N_MASK) != !(m_r[eCPSR] & V_MASK)))
|
||||
{ UNEXECUTED(); goto skip_exec; }
|
||||
break;
|
||||
case COND_LE:
|
||||
if (Z_IS_CLEAR(m_r[eCPSR]) && (!(m_r[eCPSR] & N_MASK) == !(m_r[eCPSR] & V_MASK)))
|
||||
{ UNEXECUTED(); goto skip_exec; }
|
||||
break;
|
||||
case COND_NV:
|
||||
{ UNEXECUTED(); goto skip_exec; }
|
||||
break;
|
||||
case COND_NE:
|
||||
if (Z_IS_SET(m_r[eCPSR]))
|
||||
{ UNEXECUTED(); goto skip_exec; }
|
||||
break;
|
||||
case COND_CS:
|
||||
if (C_IS_CLEAR(m_r[eCPSR]))
|
||||
{ UNEXECUTED(); goto skip_exec; }
|
||||
break;
|
||||
case COND_CC:
|
||||
if (C_IS_SET(m_r[eCPSR]))
|
||||
{ UNEXECUTED(); goto skip_exec; }
|
||||
break;
|
||||
case COND_MI:
|
||||
if (N_IS_CLEAR(m_r[eCPSR]))
|
||||
{ UNEXECUTED(); goto skip_exec; }
|
||||
break;
|
||||
case COND_PL:
|
||||
if (N_IS_SET(m_r[eCPSR]))
|
||||
{ UNEXECUTED(); goto skip_exec; }
|
||||
break;
|
||||
case COND_VS:
|
||||
if (V_IS_CLEAR(m_r[eCPSR]))
|
||||
{ UNEXECUTED(); goto skip_exec; }
|
||||
break;
|
||||
case COND_VC:
|
||||
if (V_IS_SET(m_r[eCPSR]))
|
||||
{ UNEXECUTED(); goto skip_exec; }
|
||||
break;
|
||||
case COND_HI:
|
||||
if (C_IS_CLEAR(m_r[eCPSR]) || Z_IS_SET(m_r[eCPSR]))
|
||||
{ UNEXECUTED(); goto skip_exec; }
|
||||
break;
|
||||
case COND_LS:
|
||||
if (C_IS_SET(m_r[eCPSR]) && Z_IS_CLEAR(m_r[eCPSR]))
|
||||
{ UNEXECUTED(); goto skip_exec; }
|
||||
break;
|
||||
case COND_GE:
|
||||
if (!(m_r[eCPSR] & N_MASK) != !(m_r[eCPSR] & V_MASK)) /* Use x ^ (x >> ...) method */
|
||||
{ UNEXECUTED(); goto skip_exec; }
|
||||
break;
|
||||
case COND_LT:
|
||||
if (!(m_r[eCPSR] & N_MASK) == !(m_r[eCPSR] & V_MASK))
|
||||
{ UNEXECUTED(); goto skip_exec; }
|
||||
break;
|
||||
case COND_GT:
|
||||
if (Z_IS_SET(m_r[eCPSR]) || (!(m_r[eCPSR] & N_MASK) != !(m_r[eCPSR] & V_MASK)))
|
||||
{ UNEXECUTED(); goto skip_exec; }
|
||||
break;
|
||||
case COND_LE:
|
||||
if (Z_IS_CLEAR(m_r[eCPSR]) && (!(m_r[eCPSR] & N_MASK) == !(m_r[eCPSR] & V_MASK)))
|
||||
{ UNEXECUTED(); goto skip_exec; }
|
||||
break;
|
||||
case COND_NV:
|
||||
{ UNEXECUTED(); goto skip_exec; }
|
||||
}
|
||||
}
|
||||
/*******************************************************************/
|
||||
/* If we got here - condition satisfied, so decode the instruction */
|
||||
@ -758,25 +732,26 @@ void arm7_cpu_device::execute_set_input(int irqline, int state)
|
||||
{
|
||||
switch (irqline) {
|
||||
case ARM7_IRQ_LINE: /* IRQ */
|
||||
m_pendingIrq = state & 1;
|
||||
m_pendingIrq = state ? true : false;
|
||||
break;
|
||||
|
||||
case ARM7_FIRQ_LINE: /* FIRQ */
|
||||
m_pendingFiq = state & 1;
|
||||
m_pendingFiq = state ? true : false;
|
||||
break;
|
||||
|
||||
case ARM7_ABORT_EXCEPTION:
|
||||
m_pendingAbtD = state & 1;
|
||||
m_pendingAbtD = state ? true : false;
|
||||
break;
|
||||
case ARM7_ABORT_PREFETCH_EXCEPTION:
|
||||
m_pendingAbtP = state & 1;
|
||||
m_pendingAbtP = state ? true : false;
|
||||
break;
|
||||
|
||||
case ARM7_UNDEFINE_EXCEPTION:
|
||||
m_pendingUnd = state & 1;
|
||||
m_pendingUnd = state ? true : false;
|
||||
break;
|
||||
}
|
||||
|
||||
update_irq_state();
|
||||
arm7_check_irq_state();
|
||||
}
|
||||
|
||||
@ -809,7 +784,7 @@ offs_t arm7_cpu_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8
|
||||
|
||||
WRITE32_MEMBER( arm7_cpu_device::arm7_do_callback )
|
||||
{
|
||||
m_pendingUnd = 1;
|
||||
m_pendingUnd = true;
|
||||
}
|
||||
|
||||
READ32_MEMBER( arm7_cpu_device::arm7_rt_r_callback )
|
||||
@ -851,7 +826,7 @@ READ32_MEMBER( arm7_cpu_device::arm7_rt_r_callback )
|
||||
else
|
||||
{
|
||||
LOG( ("ARM7: Unhandled coprocessor %d (archFlags %x)\n", cpnum, m_archFlags) );
|
||||
m_pendingUnd = 1;
|
||||
m_pendingUnd = true;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -994,7 +969,7 @@ WRITE32_MEMBER( arm7_cpu_device::arm7_rt_w_callback )
|
||||
else
|
||||
{
|
||||
LOG( ("ARM7: Unhandled coprocessor %d\n", cpnum) );
|
||||
m_pendingUnd = 1;
|
||||
m_pendingUnd = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -1039,10 +1014,15 @@ WRITE32_MEMBER( arm7_cpu_device::arm7_rt_w_callback )
|
||||
case 2: // Translation Table Base
|
||||
LOG( ( "arm7_rt_w_callback TLB Base = %08x (%d) (%d)\n", data, op2, op3 ) );
|
||||
COPRO_TLB_BASE = data;
|
||||
m_tlb_base_mask = data & COPRO_TLB_BASE_MASK;
|
||||
break;
|
||||
case 3: // Domain Access Control
|
||||
LOG( ( "arm7_rt_w_callback Domain Access Control = %08x (%d) (%d)\n", data, op2, op3 ) );
|
||||
COPRO_DOMAIN_ACCESS_CONTROL = data;
|
||||
for (int i = 0; i < 32; i += 2)
|
||||
{
|
||||
m_decoded_access_control[i >> 1] = (COPRO_DOMAIN_ACCESS_CONTROL >> i) & 3;
|
||||
}
|
||||
break;
|
||||
case 5: // Fault Status
|
||||
LOG( ( "arm7_rt_w_callback Fault Status = %08x (%d) (%d)\n", data, op2, op3 ) );
|
||||
@ -1068,6 +1048,7 @@ WRITE32_MEMBER( arm7_cpu_device::arm7_rt_w_callback )
|
||||
case 13: // Write Process ID (PID)
|
||||
LOG( ( "arm7_rt_w_callback Write PID = %08x (%d) (%d)\n", data, op2, op3 ) );
|
||||
COPRO_FCSE_PID = data;
|
||||
m_pid_offset = (((COPRO_FCSE_PID >> 25) & 0x7F)) * 0x2000000;
|
||||
break;
|
||||
case 14: // Write Breakpoint
|
||||
LOG( ( "arm7_rt_w_callback Write Breakpoint = %08x (%d) (%d)\n", data, op2, op3 ) );
|
||||
@ -1088,7 +1069,7 @@ void arm7_cpu_device::arm7_dt_r_callback(UINT32 insn, UINT32 *prn)
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pendingUnd = 1;
|
||||
m_pendingUnd = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1102,7 +1083,7 @@ void arm7_cpu_device::arm7_dt_w_callback(UINT32 insn, UINT32 *prn)
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pendingUnd = 1;
|
||||
m_pendingUnd = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -81,12 +81,13 @@ protected:
|
||||
address_space_config m_program_config;
|
||||
|
||||
UINT32 m_r[/*NUM_REGS*/37];
|
||||
UINT32 m_pendingIrq;
|
||||
UINT32 m_pendingFiq;
|
||||
UINT32 m_pendingAbtD;
|
||||
UINT32 m_pendingAbtP;
|
||||
UINT32 m_pendingUnd;
|
||||
UINT32 m_pendingSwi;
|
||||
bool m_pendingIrq;
|
||||
bool m_pendingFiq;
|
||||
bool m_pendingAbtD;
|
||||
bool m_pendingAbtP;
|
||||
bool m_pendingUnd;
|
||||
bool m_pendingSwi;
|
||||
bool m_pending_interrupt;
|
||||
int m_icount;
|
||||
endianness_t m_endian;
|
||||
address_space *m_program;
|
||||
@ -95,10 +96,13 @@ protected:
|
||||
/* Coprocessor Registers */
|
||||
UINT32 m_control;
|
||||
UINT32 m_tlbBase;
|
||||
UINT32 m_tlb_base_mask;
|
||||
UINT32 m_faultStatus[2];
|
||||
UINT32 m_faultAddress;
|
||||
UINT32 m_fcsePID;
|
||||
UINT32 m_pid_offset;
|
||||
UINT32 m_domainAccessControl;
|
||||
UINT8 m_decoded_access_control[16];
|
||||
|
||||
UINT8 m_archRev; // ARM architecture revision (3, 4, and 5 are valid)
|
||||
UINT8 m_archFlags; // architecture flags
|
||||
@ -141,10 +145,10 @@ protected:
|
||||
void arm7ops_f(UINT32 insn);
|
||||
void set_cpsr(UINT32 val);
|
||||
bool arm7_tlb_translate(offs_t &addr, int flags);
|
||||
UINT32 arm7_tlb_get_first_level_descriptor( UINT32 vaddr );
|
||||
UINT32 arm7_tlb_get_second_level_descriptor( UINT32 granularity, UINT32 first_desc, UINT32 vaddr );
|
||||
int detect_fault(int permission, int ap, int flags);
|
||||
int detect_fault(int desc_lvl1, int ap, int flags);
|
||||
void arm7_check_irq_state();
|
||||
void update_irq_state();
|
||||
void arm7_cpu_write32(UINT32 addr, UINT32 data);
|
||||
void arm7_cpu_write16(UINT32 addr, UINT16 data);
|
||||
void arm7_cpu_write8(UINT32 addr, UINT8 data);
|
||||
@ -445,6 +449,8 @@ protected:
|
||||
void drctg0f_0(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
void drctg0f_1(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); /* BL */
|
||||
|
||||
void update_reg_ptr();
|
||||
const int* m_reg_group;
|
||||
void load_fast_iregs(drcuml_block *block);
|
||||
void save_fast_iregs(drcuml_block *block);
|
||||
void arm7_drc_init();
|
||||
|
@ -165,12 +165,13 @@ struct arm7imp_state;
|
||||
struct arm_state
|
||||
{
|
||||
UINT32 m_r[NUM_REGS];
|
||||
UINT32 m_pendingIrq;
|
||||
UINT32 m_pendingFiq;
|
||||
UINT32 m_pendingAbtD;
|
||||
UINT32 m_pendingAbtP;
|
||||
UINT32 m_pendingUnd;
|
||||
UINT32 m_pendingSwi;
|
||||
bool m_pendingIrq;
|
||||
bool m_pendingFiq;
|
||||
bool m_pendingAbtD;
|
||||
bool m_pendingAbtP;
|
||||
bool m_pendingUnd;
|
||||
bool m_pendingSwi;
|
||||
bool m_pending_interrupt;
|
||||
int m_icount;
|
||||
endianness_t m_endian;
|
||||
address_space *m_program;
|
||||
@ -179,10 +180,12 @@ struct arm_state
|
||||
/* Coprocessor Registers */
|
||||
UINT32 m_control;
|
||||
UINT32 m_tlbBase;
|
||||
UINT32 m_tlb_base_mask;
|
||||
UINT32 m_faultStatus[2];
|
||||
UINT32 m_faultAddress;
|
||||
UINT32 m_fcsePID;
|
||||
UINT32 m_domainAccessControl;
|
||||
UINT32 m_decoded_access_control[16];
|
||||
|
||||
UINT8 m_archRev; // ARM architecture revision (3, 4, and 5 are valid)
|
||||
UINT8 m_archFlags; // architecture flags
|
||||
@ -488,7 +491,6 @@ enum
|
||||
#define R15 m_r[eR15]
|
||||
#define SPSR 17 // SPSR is always the 18th register in our 0 based array sRegisterTable[][18]
|
||||
#define GET_CPSR m_r[eCPSR]
|
||||
#define SET_CPSR(v) set_cpsr(v)
|
||||
#define MODE_FLAG 0xF // Mode bits are 4:0 of CPSR, but we ignore bit 4.
|
||||
#define GET_MODE (GET_CPSR & MODE_FLAG)
|
||||
#define SIGN_BIT ((UINT32)(1 << 31))
|
||||
@ -508,14 +510,6 @@ enum
|
||||
#define ARM7_TLB_READ (1 << 2)
|
||||
#define ARM7_TLB_WRITE (1 << 3)
|
||||
|
||||
/* At one point I thought these needed to be cpu implementation specific, but they don't.. */
|
||||
#define GET_REGISTER(reg) GetRegister(reg)
|
||||
#define SET_REGISTER(reg, val) SetRegister(reg, val)
|
||||
#define GET_MODE_REGISTER(mode, reg) GetModeRegister(mode, reg)
|
||||
#define SET_MODE_REGISTER(mode, reg, val) SetModeRegister(mode, reg, val)
|
||||
#define ARM7_CHECKIRQ arm7_check_irq_state()
|
||||
|
||||
|
||||
/* ARM flavors */
|
||||
enum arm_flavor
|
||||
{
|
||||
|
@ -84,10 +84,18 @@ static const char *GetModeText(int cpsr)
|
||||
* Main CPU Funcs
|
||||
***************************************************************************/
|
||||
|
||||
void arm7_cpu_device::update_irq_state()
|
||||
{
|
||||
m_pending_interrupt = m_pendingAbtD || m_pendingAbtP || m_pendingUnd || m_pendingSwi || m_pendingFiq || m_pendingIrq;
|
||||
}
|
||||
|
||||
// CPU CHECK IRQ STATE
|
||||
// Note: couldn't find any exact cycle counts for most of these exceptions
|
||||
void arm7_cpu_device::arm7_check_irq_state()
|
||||
{
|
||||
if (!m_pending_interrupt)
|
||||
return;
|
||||
|
||||
UINT32 cpsr = m_r[eCPSR]; /* save current CPSR */
|
||||
UINT32 pc = m_r[eR15] + 4; /* save old pc (already incremented in pipeline) */;
|
||||
|
||||
@ -103,41 +111,45 @@ void arm7_cpu_device::arm7_check_irq_state()
|
||||
*/
|
||||
|
||||
// Data Abort
|
||||
if (m_pendingAbtD) {
|
||||
if (m_pendingAbtD)
|
||||
{
|
||||
if (MODE26) fatalerror( "pendingAbtD (todo)\n");
|
||||
SwitchMode(eARM7_MODE_ABT); /* Set ABT mode so PC is saved to correct R14 bank */
|
||||
SET_REGISTER(14, pc - 8 + 8); /* save PC to R14 */
|
||||
SET_REGISTER(SPSR, cpsr); /* Save current CPSR */
|
||||
SET_CPSR(GET_CPSR | I_MASK); /* Mask IRQ */
|
||||
SET_CPSR(GET_CPSR & ~T_MASK);
|
||||
SetRegister(14, pc - 8 + 8); /* save PC to R14 */
|
||||
SetRegister(SPSR, cpsr); /* Save current CPSR */
|
||||
set_cpsr(GET_CPSR | I_MASK); /* Mask IRQ */
|
||||
set_cpsr(GET_CPSR & ~T_MASK);
|
||||
R15 = 0x10; /* IRQ Vector address */
|
||||
if ((COPRO_CTRL & COPRO_CTRL_MMU_EN) && (COPRO_CTRL & COPRO_CTRL_INTVEC_ADJUST)) R15 |= 0xFFFF0000;
|
||||
m_pendingAbtD = 0;
|
||||
m_pendingAbtD = false;
|
||||
update_irq_state();
|
||||
return;
|
||||
}
|
||||
|
||||
// FIQ
|
||||
if (m_pendingFiq && (cpsr & F_MASK) == 0) {
|
||||
if (m_pendingFiq && (cpsr & F_MASK) == 0)
|
||||
{
|
||||
if (MODE26) fatalerror( "pendingFiq (todo)\n");
|
||||
SwitchMode(eARM7_MODE_FIQ); /* Set FIQ mode so PC is saved to correct R14 bank */
|
||||
SET_REGISTER(14, pc - 4 + 4); /* save PC to R14 */
|
||||
SET_REGISTER(SPSR, cpsr); /* Save current CPSR */
|
||||
SET_CPSR(GET_CPSR | I_MASK | F_MASK); /* Mask both IRQ & FIQ */
|
||||
SET_CPSR(GET_CPSR & ~T_MASK);
|
||||
SetRegister(14, pc - 4 + 4); /* save PC to R14 */
|
||||
SetRegister(SPSR, cpsr); /* Save current CPSR */
|
||||
set_cpsr(GET_CPSR | I_MASK | F_MASK); /* Mask both IRQ & FIQ */
|
||||
set_cpsr(GET_CPSR & ~T_MASK);
|
||||
R15 = 0x1c; /* IRQ Vector address */
|
||||
if ((COPRO_CTRL & COPRO_CTRL_MMU_EN) && (COPRO_CTRL & COPRO_CTRL_INTVEC_ADJUST)) R15 |= 0xFFFF0000;
|
||||
return;
|
||||
}
|
||||
|
||||
// IRQ
|
||||
if (m_pendingIrq && (cpsr & I_MASK) == 0) {
|
||||
if (m_pendingIrq && (cpsr & I_MASK) == 0)
|
||||
{
|
||||
SwitchMode(eARM7_MODE_IRQ); /* Set IRQ mode so PC is saved to correct R14 bank */
|
||||
SET_REGISTER(14, pc - 4 + 4); /* save PC to R14 */
|
||||
SetRegister(14, pc - 4 + 4); /* save PC to R14 */
|
||||
if (MODE32)
|
||||
{
|
||||
SET_REGISTER(SPSR, cpsr); /* Save current CPSR */
|
||||
SET_CPSR(GET_CPSR | I_MASK); /* Mask IRQ */
|
||||
SET_CPSR(GET_CPSR & ~T_MASK);
|
||||
SetRegister(SPSR, cpsr); /* Save current CPSR */
|
||||
set_cpsr(GET_CPSR | I_MASK); /* Mask IRQ */
|
||||
set_cpsr(GET_CPSR & ~T_MASK);
|
||||
R15 = 0x18; /* IRQ Vector address */
|
||||
}
|
||||
else
|
||||
@ -145,65 +157,70 @@ void arm7_cpu_device::arm7_check_irq_state()
|
||||
UINT32 temp;
|
||||
R15 = (pc & 0xF4000000) /* N Z C V F */ | 0x18 | 0x00000002 /* IRQ */ | 0x08000000 /* I */;
|
||||
temp = (GET_CPSR & 0x0FFFFF3F) /* N Z C V I F */ | (R15 & 0xF0000000) /* N Z C V */ | ((R15 & 0x0C000000) >> (26 - 6)) /* I F */;
|
||||
SET_CPSR(temp); /* Mask IRQ */
|
||||
set_cpsr(temp); /* Mask IRQ */
|
||||
}
|
||||
if ((COPRO_CTRL & COPRO_CTRL_MMU_EN) && (COPRO_CTRL & COPRO_CTRL_INTVEC_ADJUST)) R15 |= 0xFFFF0000;
|
||||
return;
|
||||
}
|
||||
|
||||
// Prefetch Abort
|
||||
if (m_pendingAbtP) {
|
||||
if (m_pendingAbtP)
|
||||
{
|
||||
if (MODE26) fatalerror( "pendingAbtP (todo)\n");
|
||||
SwitchMode(eARM7_MODE_ABT); /* Set ABT mode so PC is saved to correct R14 bank */
|
||||
SET_REGISTER(14, pc - 4 + 4); /* save PC to R14 */
|
||||
SET_REGISTER(SPSR, cpsr); /* Save current CPSR */
|
||||
SET_CPSR(GET_CPSR | I_MASK); /* Mask IRQ */
|
||||
SET_CPSR(GET_CPSR & ~T_MASK);
|
||||
SetRegister(14, pc - 4 + 4); /* save PC to R14 */
|
||||
SetRegister(SPSR, cpsr); /* Save current CPSR */
|
||||
set_cpsr(GET_CPSR | I_MASK); /* Mask IRQ */
|
||||
set_cpsr(GET_CPSR & ~T_MASK);
|
||||
R15 = 0x0c; /* IRQ Vector address */
|
||||
if ((COPRO_CTRL & COPRO_CTRL_MMU_EN) && (COPRO_CTRL & COPRO_CTRL_INTVEC_ADJUST)) R15 |= 0xFFFF0000;
|
||||
m_pendingAbtP = 0;
|
||||
m_pendingAbtP = false;
|
||||
update_irq_state();
|
||||
return;
|
||||
}
|
||||
|
||||
// Undefined instruction
|
||||
if (m_pendingUnd) {
|
||||
if (m_pendingUnd)
|
||||
{
|
||||
if (MODE26) fatalerror( "pendingUnd (todo)\n");
|
||||
SwitchMode(eARM7_MODE_UND); /* Set UND mode so PC is saved to correct R14 bank */
|
||||
// compensate for prefetch (should this also be done for normal IRQ?)
|
||||
if (T_IS_SET(GET_CPSR))
|
||||
{
|
||||
SET_REGISTER(14, pc - 4 + 2); /* save PC to R14 */
|
||||
SetRegister(14, pc - 4 + 2); /* save PC to R14 */
|
||||
}
|
||||
else
|
||||
{
|
||||
SET_REGISTER(14, pc - 4 + 4 - 4); /* save PC to R14 */
|
||||
SetRegister(14, pc - 4 + 4 - 4); /* save PC to R14 */
|
||||
}
|
||||
SET_REGISTER(SPSR, cpsr); /* Save current CPSR */
|
||||
SET_CPSR(GET_CPSR | I_MASK); /* Mask IRQ */
|
||||
SET_CPSR(GET_CPSR & ~T_MASK);
|
||||
SetRegister(SPSR, cpsr); /* Save current CPSR */
|
||||
set_cpsr(GET_CPSR | I_MASK); /* Mask IRQ */
|
||||
set_cpsr(GET_CPSR & ~T_MASK);
|
||||
R15 = 0x04; /* IRQ Vector address */
|
||||
if ((COPRO_CTRL & COPRO_CTRL_MMU_EN) && (COPRO_CTRL & COPRO_CTRL_INTVEC_ADJUST)) R15 |= 0xFFFF0000;
|
||||
m_pendingUnd = 0;
|
||||
m_pendingUnd = false;
|
||||
update_irq_state();
|
||||
return;
|
||||
}
|
||||
|
||||
// Software Interrupt
|
||||
if (m_pendingSwi) {
|
||||
if (m_pendingSwi)
|
||||
{
|
||||
SwitchMode(eARM7_MODE_SVC); /* Set SVC mode so PC is saved to correct R14 bank */
|
||||
// compensate for prefetch (should this also be done for normal IRQ?)
|
||||
if (T_IS_SET(GET_CPSR))
|
||||
{
|
||||
SET_REGISTER(14, pc - 4 + 2); /* save PC to R14 */
|
||||
SetRegister(14, pc - 4 + 2); /* save PC to R14 */
|
||||
}
|
||||
else
|
||||
{
|
||||
SET_REGISTER(14, pc - 4 + 4); /* save PC to R14 */
|
||||
SetRegister(14, pc - 4 + 4); /* save PC to R14 */
|
||||
}
|
||||
if (MODE32)
|
||||
{
|
||||
SET_REGISTER(SPSR, cpsr); /* Save current CPSR */
|
||||
SET_CPSR(GET_CPSR | I_MASK); /* Mask IRQ */
|
||||
SET_CPSR(GET_CPSR & ~T_MASK); /* Go to ARM mode */
|
||||
SetRegister(SPSR, cpsr); /* Save current CPSR */
|
||||
set_cpsr(GET_CPSR | I_MASK); /* Mask IRQ */
|
||||
set_cpsr(GET_CPSR & ~T_MASK); /* Go to ARM mode */
|
||||
R15 = 0x08; /* Jump to the SWI vector */
|
||||
}
|
||||
else
|
||||
@ -211,10 +228,11 @@ void arm7_cpu_device::arm7_check_irq_state()
|
||||
UINT32 temp;
|
||||
R15 = (pc & 0xF4000000) /* N Z C V F */ | 0x08 | 0x00000003 /* SVC */ | 0x08000000 /* I */;
|
||||
temp = (GET_CPSR & 0x0FFFFF3F) /* N Z C V I F */ | (R15 & 0xF0000000) /* N Z C V */ | ((R15 & 0x0C000000) >> (26 - 6)) /* I F */;
|
||||
SET_CPSR(temp); /* Mask IRQ */
|
||||
set_cpsr(temp); /* Mask IRQ */
|
||||
}
|
||||
if ((COPRO_CTRL & COPRO_CTRL_MMU_EN) && (COPRO_CTRL & COPRO_CTRL_INTVEC_ADJUST)) R15 |= 0xFFFF0000;
|
||||
m_pendingSwi = 0;
|
||||
m_pendingSwi = false;
|
||||
update_irq_state();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -547,8 +547,8 @@ void arm7_cpu_device::static_generate_check_irq()
|
||||
UML_JMPc(block, uml::COND_Z, nodabt = label++); // jmpz nodabt
|
||||
|
||||
UML_ROLINS(block, uml::mem(&GET_CPSR), eARM7_MODE_ABT, 0, MODE_FLAG); // rolins CPSR, eARM7_MODE_ABT, 0, MODE_FLAG
|
||||
UML_MOV(block, uml::mem(&GET_REGISTER(14)), uml::I0); // mov LR, i0
|
||||
UML_MOV(block, uml::mem(&GET_REGISTER(SPSR)), uml::mem(&GET_CPSR)); // mov SPSR, CPSR
|
||||
UML_MOV(block, uml::mem(&GetRegister(14)), uml::I0); // mov LR, i0
|
||||
UML_MOV(block, uml::mem(&GetRegister(SPSR)), uml::mem(&GET_CPSR)); // mov SPSR, CPSR
|
||||
UML_OR(block, uml::mem(&GET_CPSR), uml::mem(&GET_CPSR), I_MASK); // or CPSR, CPSR, I_MASK
|
||||
UML_ROLAND(block, uml::mem(&GET_CPSR), uml::mem(&GET_CPSR), 0, ~T_MASK); // roland CPSR, CPSR, 0, ~T_MASK
|
||||
UML_MOV(block, uml::mem(&R15), 0x00000010); // mov PC, 0x10 (Data Abort vector address)
|
||||
@ -563,8 +563,8 @@ void arm7_cpu_device::static_generate_check_irq()
|
||||
UML_TEST(block, uml::mem(&GET_CPSR), F_MASK); // test CPSR, F_MASK
|
||||
UML_JMPc(block, uml::COND_Z, nofiq); // jmpz nofiq
|
||||
|
||||
UML_MOV(block, uml::mem(&GET_REGISTER(14)), uml::I0); // mov LR, i0
|
||||
UML_MOV(block, uml::mem(&GET_REGISTER(SPSR)), uml::mem(&GET_CPSR)); // mov SPSR, CPSR
|
||||
UML_MOV(block, uml::mem(&GetRegister(14)), uml::I0); // mov LR, i0
|
||||
UML_MOV(block, uml::mem(&GetRegister(SPSR)), uml::mem(&GET_CPSR)); // mov SPSR, CPSR
|
||||
UML_OR(block, uml::mem(&GET_CPSR), uml::mem(&GET_CPSR), I_MASK | F_MASK); // or CPSR, CPSR, I_MASK | F_MASK
|
||||
UML_ROLAND(block, uml::mem(&GET_CPSR), uml::mem(&GET_CPSR), 0, ~T_MASK); // roland CPSR, CPSR, 0, ~T_MASK
|
||||
UML_MOV(block, uml::mem(&R15), 0x0000001c); // mov PC, 0x1c (FIQ vector address)
|
||||
@ -579,7 +579,7 @@ void arm7_cpu_device::static_generate_check_irq()
|
||||
UML_TEST(block, uml::mem(&GET_CPSR), I_MASK); // test CPSR, I_MASK
|
||||
UML_JMPc(block, uml::COND_Z, noirq); // jmpz noirq
|
||||
|
||||
UML_MOV(block, uml::mem(&GET_REGISTER(14)), uml::I0); // mov LR, i0
|
||||
UML_MOV(block, uml::mem(&GetRegister(14)), uml::I0); // mov LR, i0
|
||||
UML_TEST(block, uml::mem(&GET_CPSR), SR_MODE32); // test CPSR, MODE32
|
||||
UML_JMPc(block, uml::COND_NZ, irq32 = label++); // jmpnz irq32
|
||||
UML_AND(block, uml::I1, uml::I0, 0xf4000000); // and i1, i0, 0xf4000000
|
||||
@ -591,7 +591,7 @@ void arm7_cpu_device::static_generate_check_irq()
|
||||
UML_JMP(block, irqadjust); // jmp irqadjust
|
||||
|
||||
UML_LABEL(block, irq32); // irq32:
|
||||
UML_MOV(block, uml::mem(&GET_REGISTER(SPSR)), uml::mem(&GET_CPSR)); // mov SPSR, CPSR
|
||||
UML_MOV(block, uml::mem(&GetRegister(SPSR)), uml::mem(&GET_CPSR)); // mov SPSR, CPSR
|
||||
UML_OR(block, uml::mem(&GET_CPSR), uml::mem(&GET_CPSR), I_MASK); // or CPSR, CPSR, I_MASK
|
||||
UML_ROLAND(block, uml::mem(&GET_CPSR), uml::mem(&GET_CPSR), 0, ~T_MASK); // roland CPSR, CPSR, 0, ~T_MASK
|
||||
UML_MOV(block, uml::mem(&R15), 0x00000018); // mov PC, 0x18 (IRQ vector address)
|
||||
@ -605,8 +605,8 @@ void arm7_cpu_device::static_generate_check_irq()
|
||||
UML_JMPc(block, uml::COND_Z, nopabt = label++); // jmpz nopabt
|
||||
|
||||
UML_ROLINS(block, uml::mem(&GET_CPSR), eARM7_MODE_ABT, 0, MODE_FLAG); // rolins CPSR, eARM7_MODE_ABT, 0, MODE_FLAG
|
||||
UML_MOV(block, uml::mem(&GET_REGISTER(14)), uml::I0); // mov LR, i0
|
||||
UML_MOV(block, uml::mem(&GET_REGISTER(SPSR)), uml::mem(&GET_CPSR)); // mov SPSR, CPSR
|
||||
UML_MOV(block, uml::mem(&GetRegister(14)), uml::I0); // mov LR, i0
|
||||
UML_MOV(block, uml::mem(&GetRegister(SPSR)), uml::mem(&GET_CPSR)); // mov SPSR, CPSR
|
||||
UML_OR(block, uml::mem(&GET_CPSR), uml::mem(&GET_CPSR), I_MASK); // or CPSR, CPSR, I_MASK
|
||||
UML_ROLAND(block, uml::mem(&GET_CPSR), uml::mem(&GET_CPSR), 0, ~T_MASK); // roland CPSR, CPSR, 0, ~T_MASK
|
||||
UML_MOV(block, uml::mem(&R15), 0x0000000c); // mov PC, 0x0c (Prefetch Abort vector address)
|
||||
@ -623,8 +623,8 @@ void arm7_cpu_device::static_generate_check_irq()
|
||||
UML_MOV(block, uml::I1, (UINT64)-4); // mov i1, -4
|
||||
UML_TEST(block, uml::mem(&GET_CPSR), T_MASK); // test CPSR, T_MASK
|
||||
UML_MOVc(block, uml::COND_NZ, uml::I1, (UINT64)-2); // movnz i1, -2
|
||||
UML_ADD(block, uml::mem(&GET_REGISTER(14)), uml::I0, uml::I1); // add LR, i0, i1
|
||||
UML_MOV(block, uml::mem(&GET_REGISTER(SPSR)), uml::mem(&GET_CPSR)); // mov SPSR, CPSR
|
||||
UML_ADD(block, uml::mem(&GetRegister(14)), uml::I0, uml::I1); // add LR, i0, i1
|
||||
UML_MOV(block, uml::mem(&GetRegister(SPSR)), uml::mem(&GET_CPSR)); // mov SPSR, CPSR
|
||||
UML_OR(block, uml::mem(&GET_CPSR), uml::mem(&GET_CPSR), I_MASK); // or CPSR, CPSR, I_MASK
|
||||
UML_ROLAND(block, uml::mem(&GET_CPSR), uml::mem(&GET_CPSR), 0, ~T_MASK); // roland CPSR, CPSR, 0, ~T_MASK
|
||||
UML_MOV(block, uml::mem(&R15), 0x00000004); // mov PC, 0x0c (Undefined Insn vector address)
|
||||
@ -641,7 +641,7 @@ void arm7_cpu_device::static_generate_check_irq()
|
||||
UML_MOV(block, uml::I1, (UINT64)-4); // mov i1, -4
|
||||
UML_TEST(block, uml::mem(&GET_CPSR), T_MASK); // test CPSR, T_MASK
|
||||
UML_MOVc(block, uml::COND_NZ, uml::I1, (UINT64)-2); // movnz i1, -2
|
||||
UML_ADD(block, uml::mem(&GET_REGISTER(14)), uml::I0, uml::I1); // add LR, i0, i1
|
||||
UML_ADD(block, uml::mem(&GetRegister(14)), uml::I0, uml::I1); // add LR, i0, i1
|
||||
|
||||
UML_TEST(block, uml::mem(&GET_CPSR), SR_MODE32); // test CPSR, MODE32
|
||||
UML_JMPc(block, uml::COND_NZ, swi32 = label++); // jmpnz swi32
|
||||
@ -655,7 +655,7 @@ void arm7_cpu_device::static_generate_check_irq()
|
||||
UML_JMP(block, irqadjust); // jmp irqadjust
|
||||
|
||||
UML_LABEL(block, swi32); // irq32:
|
||||
UML_MOV(block, uml::mem(&GET_REGISTER(SPSR)), uml::mem(&GET_CPSR)); // mov SPSR, CPSR
|
||||
UML_MOV(block, uml::mem(&GetRegister(SPSR)), uml::mem(&GET_CPSR)); // mov SPSR, CPSR
|
||||
UML_OR(block, uml::mem(&GET_CPSR), uml::mem(&GET_CPSR), I_MASK); // or CPSR, CPSR, I_MASK
|
||||
UML_ROLAND(block, uml::mem(&GET_CPSR), uml::mem(&GET_CPSR), 0, ~T_MASK); // roland CPSR, CPSR, 0, ~T_MASK
|
||||
UML_MOV(block, uml::mem(&R15), 0x00000008); // mov PC, 0x08 (SWI vector address)
|
||||
@ -1508,8 +1508,8 @@ bool arm7_cpu_device::drcarm7ops_0123(drcuml_block *block, compiler_state *compi
|
||||
}
|
||||
else if ((insn & 0x0ff00090) == 0x01600080) // SMULxy - v5
|
||||
{
|
||||
INT32 src1 = GET_REGISTER(insn&0xf);
|
||||
INT32 src2 = GET_REGISTER((insn>>8)&0xf);
|
||||
INT32 src1 = GetRegister(insn&0xf);
|
||||
INT32 src2 = GetRegister((insn>>8)&0xf);
|
||||
INT32 res;
|
||||
|
||||
// select top and bottom halves of src1/src2 and sign extend if necessary
|
||||
@ -1536,13 +1536,13 @@ bool arm7_cpu_device::drcarm7ops_0123(drcuml_block *block, compiler_state *compi
|
||||
}
|
||||
|
||||
res = src1 * src2;
|
||||
SET_REGISTER((insn>>16)&0xf, res);
|
||||
SetRegister((insn>>16)&0xf, res);
|
||||
R15 += 4;
|
||||
}
|
||||
else if ((insn & 0x0ff000b0) == 0x012000a0) // SMULWy - v5
|
||||
{
|
||||
INT32 src1 = GET_REGISTER(insn&0xf);
|
||||
INT32 src2 = GET_REGISTER((insn>>8)&0xf);
|
||||
INT32 src1 = GetRegister(insn&0xf);
|
||||
INT32 src2 = GetRegister((insn>>8)&0xf);
|
||||
INT64 res;
|
||||
|
||||
if (insn & 0x40)
|
||||
@ -1560,13 +1560,13 @@ bool arm7_cpu_device::drcarm7ops_0123(drcuml_block *block, compiler_state *compi
|
||||
|
||||
res = (INT64)src1 * (INT64)src2;
|
||||
res >>= 16;
|
||||
SET_REGISTER((insn>>16)&0xf, (UINT32)res);
|
||||
SetRegister((insn>>16)&0xf, (UINT32)res);
|
||||
}
|
||||
else if ((insn & 0x0ff000b0) == 0x01200080) // SMLAWy - v5
|
||||
{
|
||||
INT32 src1 = GET_REGISTER(insn&0xf);
|
||||
INT32 src2 = GET_REGISTER((insn>>8)&0xf);
|
||||
INT32 src3 = GET_REGISTER((insn>>12)&0xf);
|
||||
INT32 src1 = GetRegister(insn&0xf);
|
||||
INT32 src2 = GetRegister((insn>>8)&0xf);
|
||||
INT32 src3 = GetRegister((insn>>12)&0xf);
|
||||
INT64 res;
|
||||
|
||||
if (insn & 0x40)
|
||||
@ -1592,7 +1592,7 @@ bool arm7_cpu_device::drcarm7ops_0123(drcuml_block *block, compiler_state *compi
|
||||
src3 += (INT32)res;
|
||||
|
||||
// write the result back
|
||||
SET_REGISTER((insn>>16)&0xf, (UINT32)res);
|
||||
SetRegister((insn>>16)&0xf, (UINT32)res);
|
||||
}
|
||||
else
|
||||
/* Multiply OR Swap OR Half Word Data Transfer */
|
||||
|
@ -29,14 +29,14 @@
|
||||
/* Set NZCV flags for ADDS / SUBS */
|
||||
#define HandleALUAddFlags(rd, rn, op2) \
|
||||
if (insn & INSN_S) \
|
||||
SET_CPSR(((GET_CPSR & ~(N_MASK | Z_MASK | V_MASK | C_MASK)) \
|
||||
set_cpsr(((GET_CPSR & ~(N_MASK | Z_MASK | V_MASK | C_MASK)) \
|
||||
| (((!SIGN_BITS_DIFFER(rn, op2)) && SIGN_BITS_DIFFER(rn, rd)) << V_BIT) \
|
||||
| (((IsNeg(rn) & IsNeg(op2)) | (IsNeg(rn) & IsPos(rd)) | (IsNeg(op2) & IsPos(rd))) ? C_MASK : 0) \
|
||||
| HandleALUNZFlags(rd))); \
|
||||
R15 += 4;
|
||||
|
||||
#define HandleThumbALUAddFlags(rd, rn, op2) \
|
||||
SET_CPSR(((GET_CPSR & ~(N_MASK | Z_MASK | V_MASK | C_MASK)) \
|
||||
set_cpsr(((GET_CPSR & ~(N_MASK | Z_MASK | V_MASK | C_MASK)) \
|
||||
| (((!THUMB_SIGN_BITS_DIFFER(rn, op2)) && THUMB_SIGN_BITS_DIFFER(rn, rd)) << V_BIT) \
|
||||
| (((~(rn)) < (op2)) << C_BIT) \
|
||||
| HandleALUNZFlags(rd))); \
|
||||
@ -62,14 +62,14 @@
|
||||
|
||||
#define HandleALUSubFlags(rd, rn, op2) \
|
||||
if (insn & INSN_S) \
|
||||
SET_CPSR(((GET_CPSR & ~(N_MASK | Z_MASK | V_MASK | C_MASK)) \
|
||||
set_cpsr(((GET_CPSR & ~(N_MASK | Z_MASK | V_MASK | C_MASK)) \
|
||||
| ((SIGN_BITS_DIFFER(rn, op2) && SIGN_BITS_DIFFER(rn, rd)) << V_BIT) \
|
||||
| (((IsNeg(rn) & IsPos(op2)) | (IsNeg(rn) & IsPos(rd)) | (IsPos(op2) & IsPos(rd))) ? C_MASK : 0) \
|
||||
| HandleALUNZFlags(rd))); \
|
||||
R15 += 4;
|
||||
|
||||
#define HandleThumbALUSubFlags(rd, rn, op2) \
|
||||
SET_CPSR(((GET_CPSR & ~(N_MASK | Z_MASK | V_MASK | C_MASK)) \
|
||||
set_cpsr(((GET_CPSR & ~(N_MASK | Z_MASK | V_MASK | C_MASK)) \
|
||||
| ((THUMB_SIGN_BITS_DIFFER(rn, op2) && THUMB_SIGN_BITS_DIFFER(rn, rd)) << V_BIT) \
|
||||
| (((IsNeg(rn) & IsPos(op2)) | (IsNeg(rn) & IsPos(rd)) | (IsPos(op2) & IsPos(rd))) ? C_MASK : 0) \
|
||||
| HandleALUNZFlags(rd))); \
|
||||
@ -122,13 +122,13 @@
|
||||
|
||||
#define HandleALULogicalFlags(rd, sc) \
|
||||
if (insn & INSN_S) \
|
||||
SET_CPSR(((GET_CPSR & ~(N_MASK | Z_MASK | C_MASK)) \
|
||||
set_cpsr(((GET_CPSR & ~(N_MASK | Z_MASK | C_MASK)) \
|
||||
| HandleALUNZFlags(rd) \
|
||||
| (((sc) != 0) << C_BIT))); \
|
||||
R15 += 4;
|
||||
|
||||
#define DRC_RD uml::mem(&GET_REGISTER(rd))
|
||||
#define DRC_RS uml::mem(&GET_REGISTER(rs))
|
||||
#define DRC_RD uml::mem(&GetRegister(rd))
|
||||
#define DRC_RS uml::mem(&GetRegister(rs))
|
||||
#define DRC_CPSR uml::mem(&GET_CPSR)
|
||||
#define DRC_PC uml::mem(&R15)
|
||||
#define DRC_REG(i) uml::mem(&m_r[(i)])
|
||||
@ -148,8 +148,8 @@
|
||||
|
||||
|
||||
// used to be functions, but no longer a need, so we'll use define for better speed.
|
||||
#define GetRegister(rIndex) m_r[sRegisterTable[GET_MODE][rIndex]]
|
||||
#define SetRegister(rIndex, value) m_r[sRegisterTable[GET_MODE][rIndex]] = value
|
||||
#define GetRegister(rIndex) m_r[m_reg_group[rIndex]]
|
||||
#define SetRegister(rIndex, value) m_r[m_reg_group[rIndex]] = value
|
||||
|
||||
#define GetModeRegister(mode, rIndex) m_r[sRegisterTable[mode][rIndex]]
|
||||
#define SetModeRegister(mode, rIndex, value) m_r[sRegisterTable[mode][rIndex]] = value
|
||||
|
@ -10,12 +10,12 @@ INT64 arm7_cpu_device::saturate_qbit_overflow(INT64 res)
|
||||
if (res > 2147483647) // INT32_MAX
|
||||
{ // overflow high? saturate and set Q
|
||||
res = 2147483647;
|
||||
SET_CPSR(GET_CPSR | Q_MASK);
|
||||
set_cpsr(GET_CPSR | Q_MASK);
|
||||
}
|
||||
else if (res < (-2147483647-1)) // INT32_MIN
|
||||
{ // overflow low? saturate and set Q
|
||||
res = (-2147483647-1);
|
||||
SET_CPSR(GET_CPSR | Q_MASK);
|
||||
set_cpsr(GET_CPSR | Q_MASK);
|
||||
}
|
||||
|
||||
return res;
|
||||
@ -50,7 +50,7 @@ void arm7_cpu_device::SwitchMode(UINT32 cpsr_mode_val)
|
||||
UINT32 arm7_cpu_device::decodeShift(UINT32 insn, UINT32 *pCarry)
|
||||
{
|
||||
UINT32 k = (insn & INSN_OP2_SHIFT) >> INSN_OP2_SHIFT_SHIFT; // Bits 11-7
|
||||
UINT32 rm = GET_REGISTER(insn & INSN_OP2_RM);
|
||||
UINT32 rm = GetRegister(insn & INSN_OP2_RM);
|
||||
UINT32 t = (insn & INSN_OP2_SHIFT_TYPE) >> INSN_OP2_SHIFT_TYPE_SHIFT;
|
||||
|
||||
if ((insn & INSN_OP2_RM) == 0xf) {
|
||||
@ -61,17 +61,17 @@ UINT32 arm7_cpu_device::decodeShift(UINT32 insn, UINT32 *pCarry)
|
||||
/* All shift types ending in 1 are Rk, not #k */
|
||||
if (t & 1)
|
||||
{
|
||||
// LOG(("%08x: RegShift %02x %02x\n", R15, k >> 1, GET_REGISTER(k >> 1)));
|
||||
// LOG(("%08x: RegShift %02x %02x\n", R15, k >> 1, GetRegister(k >> 1)));
|
||||
#if ARM7_DEBUG_CORE
|
||||
if ((insn & 0x80) == 0x80)
|
||||
LOG(("%08x: RegShift ERROR (p36)\n", R15));
|
||||
#endif
|
||||
|
||||
// see p35 for check on this
|
||||
//k = GET_REGISTER(k >> 1) & 0x1f;
|
||||
//k = GetRegister(k >> 1) & 0x1f;
|
||||
|
||||
// Keep only the bottom 8 bits for a Register Shift
|
||||
k = GET_REGISTER(k >> 1) & 0xff;
|
||||
k = GetRegister(k >> 1) & 0xff;
|
||||
|
||||
if (k == 0) /* Register shift by 0 is a no-op */
|
||||
{
|
||||
@ -176,21 +176,24 @@ int arm7_cpu_device::loadInc(UINT32 pat, UINT32 rbv, UINT32 s, int mode)
|
||||
{
|
||||
if ((pat >> i) & 1)
|
||||
{
|
||||
if (m_pendingAbtD == 0) // "Overwriting of registers stops when the abort happens."
|
||||
if (!m_pendingAbtD) // "Overwriting of registers stops when the abort happens."
|
||||
{
|
||||
data = READ32(rbv += 4);
|
||||
if (i == 15) {
|
||||
if (s) /* Pull full contents from stack */
|
||||
SET_MODE_REGISTER(mode, 15, data);
|
||||
else /* Pull only address, preserve mode & status flags */
|
||||
if (MODE32)
|
||||
SET_MODE_REGISTER(mode, 15, data);
|
||||
data = READ32(rbv += 4);
|
||||
if (i == 15)
|
||||
{
|
||||
if (s) /* Pull full contents from stack */
|
||||
SetModeRegister(mode, 15, data);
|
||||
else if (MODE32) /* Pull only address, preserve mode & status flags */
|
||||
SetModeRegister(mode, 15, data);
|
||||
else
|
||||
{
|
||||
SET_MODE_REGISTER(mode, 15, (GET_MODE_REGISTER(mode, 15) & ~0x03FFFFFC) | (data & 0x03FFFFFC));
|
||||
SetModeRegister(mode, 15, (GetModeRegister(mode, 15) & ~0x03FFFFFC) | (data & 0x03FFFFFC));
|
||||
}
|
||||
} else
|
||||
SET_MODE_REGISTER(mode, i, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetModeRegister(mode, i, data);
|
||||
}
|
||||
}
|
||||
result++;
|
||||
}
|
||||
@ -210,22 +213,24 @@ int arm7_cpu_device::loadDec(UINT32 pat, UINT32 rbv, UINT32 s, int mode)
|
||||
{
|
||||
if ((pat >> i) & 1)
|
||||
{
|
||||
if (m_pendingAbtD == 0) // "Overwriting of registers stops when the abort happens."
|
||||
if (!m_pendingAbtD) // "Overwriting of registers stops when the abort happens."
|
||||
{
|
||||
data = READ32(rbv -= 4);
|
||||
if (i == 15) {
|
||||
if (s) /* Pull full contents from stack */
|
||||
SET_MODE_REGISTER(mode, 15, data);
|
||||
else /* Pull only address, preserve mode & status flags */
|
||||
if (MODE32)
|
||||
SET_MODE_REGISTER(mode, 15, data);
|
||||
data = READ32(rbv -= 4);
|
||||
if (i == 15)
|
||||
{
|
||||
if (s) /* Pull full contents from stack */
|
||||
SetModeRegister(mode, 15, data);
|
||||
else if (MODE32) /* Pull only address, preserve mode & status flags */
|
||||
SetModeRegister(mode, 15, data);
|
||||
else
|
||||
{
|
||||
SET_MODE_REGISTER(mode, 15, (GET_MODE_REGISTER(mode, 15) & ~0x03FFFFFC) | (data & 0x03FFFFFC));
|
||||
SetModeRegister(mode, 15, (GetModeRegister(mode, 15) & ~0x03FFFFFC) | (data & 0x03FFFFFC));
|
||||
}
|
||||
}
|
||||
else
|
||||
SET_MODE_REGISTER(mode, i, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetModeRegister(mode, i, data);
|
||||
}
|
||||
}
|
||||
result++;
|
||||
}
|
||||
@ -247,7 +252,7 @@ int arm7_cpu_device::storeInc(UINT32 pat, UINT32 rbv, int mode)
|
||||
if (i == 15) /* R15 is plus 12 from address of STM */
|
||||
LOG(("%08x: StoreInc on R15\n", R15));
|
||||
#endif
|
||||
WRITE32(rbv += 4, GET_MODE_REGISTER(mode, i));
|
||||
WRITE32(rbv += 4, GetModeRegister(mode, i));
|
||||
result++;
|
||||
}
|
||||
}
|
||||
@ -280,7 +285,7 @@ int arm7_cpu_device::storeDec(UINT32 pat, UINT32 rbv, int mode)
|
||||
if (i == 15) /* R15 is plus 12 from address of STM */
|
||||
LOG(("%08x: StoreDec on R15\n", R15));
|
||||
#endif
|
||||
WRITE32(rbv + (cnt * 4), GET_MODE_REGISTER(mode, i));
|
||||
WRITE32(rbv + (cnt * 4), GetModeRegister(mode, i));
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
@ -308,15 +313,15 @@ void arm7_cpu_device::HandleCoProcRT(UINT32 insn)
|
||||
if (insn & 0x00100000) // Bit 20 = Load or Store
|
||||
{
|
||||
UINT32 res = arm7_rt_r_callback(*m_program, insn, 0); // RT Read handler must parse opcode & return appropriate result
|
||||
if (m_pendingUnd == 0)
|
||||
if (!m_pendingUnd)
|
||||
{
|
||||
SET_REGISTER((insn >> 12) & 0xf, res);
|
||||
SetRegister((insn >> 12) & 0xf, res);
|
||||
}
|
||||
}
|
||||
// Store (MCR) data from ARM7 to Co-Proc register
|
||||
else
|
||||
{
|
||||
arm7_rt_w_callback(*m_program, insn, GET_REGISTER((insn >> 12) & 0xf), 0);
|
||||
arm7_rt_w_callback(*m_program, insn, GetRegister((insn >> 12) & 0xf), 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -335,7 +340,7 @@ void arm7_cpu_device::HandleCoProcRT(UINT32 insn)
|
||||
void arm7_cpu_device::HandleCoProcDT(UINT32 insn)
|
||||
{
|
||||
UINT32 rn = (insn >> 16) & 0xf;
|
||||
UINT32 rnv = GET_REGISTER(rn); // Get Address Value stored from Rn
|
||||
UINT32 rnv = GetRegister(rn); // Get Address Value stored from Rn
|
||||
UINT32 ornv = rnv; // Keep value of Rn
|
||||
UINT32 off = (insn & 0xff) << 2; // Offset is << 2 according to manual
|
||||
UINT32 *prn = &ARM7REG(rn); // Pointer to our register, so it can be changed in the callback
|
||||
@ -370,7 +375,7 @@ void arm7_cpu_device::HandleCoProcDT(UINT32 insn)
|
||||
|
||||
// If writeback not used - ensure the original value of RN is restored in case co-proc callback changed value
|
||||
if ((insn & 0x200000) == 0)
|
||||
SET_REGISTER(rn, ornv);
|
||||
SetRegister(rn, ornv);
|
||||
}
|
||||
|
||||
void arm7_cpu_device::HandleBranch(UINT32 insn)
|
||||
@ -380,7 +385,7 @@ void arm7_cpu_device::HandleBranch(UINT32 insn)
|
||||
/* Save PC into LR if this is a branch with link */
|
||||
if (insn & INSN_BL)
|
||||
{
|
||||
SET_REGISTER(14, R15 + 4);
|
||||
SetRegister(14, R15 + 4);
|
||||
}
|
||||
|
||||
/* Sign-extend the 24-bit offset in our calculations */
|
||||
@ -425,22 +430,22 @@ void arm7_cpu_device::HandleMemSingle(UINT32 insn)
|
||||
if (insn & INSN_SDT_U)
|
||||
{
|
||||
if ((MODE32) || (rn != eR15))
|
||||
rnv = (GET_REGISTER(rn) + off);
|
||||
rnv = (GetRegister(rn) + off);
|
||||
else
|
||||
rnv = (GET_PC + off);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((MODE32) || (rn != eR15))
|
||||
rnv = (GET_REGISTER(rn) - off);
|
||||
rnv = (GetRegister(rn) - off);
|
||||
else
|
||||
rnv = (GET_PC - off);
|
||||
}
|
||||
|
||||
if (insn & INSN_SDT_W)
|
||||
{
|
||||
rnv_old = GET_REGISTER(rn);
|
||||
SET_REGISTER(rn, rnv);
|
||||
rnv_old = GetRegister(rn);
|
||||
SetRegister(rn, rnv);
|
||||
|
||||
// check writeback???
|
||||
}
|
||||
@ -461,7 +466,7 @@ void arm7_cpu_device::HandleMemSingle(UINT32 insn)
|
||||
}
|
||||
else
|
||||
{
|
||||
rnv = GET_REGISTER(rn);
|
||||
rnv = GetRegister(rn);
|
||||
}
|
||||
}
|
||||
|
||||
@ -473,15 +478,15 @@ void arm7_cpu_device::HandleMemSingle(UINT32 insn)
|
||||
if (insn & INSN_SDT_B)
|
||||
{
|
||||
UINT32 data = READ8(rnv);
|
||||
if (m_pendingAbtD == 0)
|
||||
if (!m_pendingAbtD)
|
||||
{
|
||||
SET_REGISTER(rd, data);
|
||||
SetRegister(rd, data);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT32 data = READ32(rnv);
|
||||
if (m_pendingAbtD == 0)
|
||||
if (!m_pendingAbtD)
|
||||
{
|
||||
if (rd == eR15)
|
||||
{
|
||||
@ -494,7 +499,7 @@ void arm7_cpu_device::HandleMemSingle(UINT32 insn)
|
||||
}
|
||||
else
|
||||
{
|
||||
SET_REGISTER(rd, data);
|
||||
SetRegister(rd, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -509,7 +514,7 @@ void arm7_cpu_device::HandleMemSingle(UINT32 insn)
|
||||
LOG(("Wrote R15 in byte mode\n"));
|
||||
#endif
|
||||
|
||||
WRITE8(rnv, (UINT8) GET_REGISTER(rd) & 0xffu);
|
||||
WRITE8(rnv, (UINT8) GetRegister(rd) & 0xffu);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -518,18 +523,18 @@ void arm7_cpu_device::HandleMemSingle(UINT32 insn)
|
||||
LOG(("Wrote R15 in 32bit mode\n"));
|
||||
#endif
|
||||
|
||||
//WRITE32(rnv, rd == eR15 ? R15 + 8 : GET_REGISTER(rd));
|
||||
WRITE32(rnv, rd == eR15 ? R15 + 8 + 4 : GET_REGISTER(rd)); // manual says STR rd = PC, +12
|
||||
//WRITE32(rnv, rd == eR15 ? R15 + 8 : GetRegister(rd));
|
||||
WRITE32(rnv, rd == eR15 ? R15 + 8 + 4 : GetRegister(rd)); // manual says STR rd = PC, +12
|
||||
}
|
||||
// Store takes only 2 N Cycles, so add + 1
|
||||
ARM7_ICOUNT += 1;
|
||||
}
|
||||
|
||||
if (m_pendingAbtD != 0)
|
||||
if (m_pendingAbtD)
|
||||
{
|
||||
if ((insn & INSN_SDT_P) && (insn & INSN_SDT_W))
|
||||
{
|
||||
SET_REGISTER(rn, rnv_old);
|
||||
SetRegister(rn, rnv_old);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -542,14 +547,14 @@ void arm7_cpu_device::HandleMemSingle(UINT32 insn)
|
||||
/* Writeback is applied in pipeline, before value is read from mem,
|
||||
so writeback is effectively ignored */
|
||||
if (rd == rn) {
|
||||
SET_REGISTER(rn, GET_REGISTER(rd));
|
||||
SetRegister(rn, GetRegister(rd));
|
||||
// todo: check for offs... ?
|
||||
}
|
||||
else {
|
||||
if ((insn & INSN_SDT_W) != 0)
|
||||
LOG(("%08x: RegisterWritebackIncrement %d %d %d\n", R15, (insn & INSN_SDT_P) != 0, (insn & INSN_SDT_W) != 0, (insn & INSN_SDT_U) != 0));
|
||||
|
||||
SET_REGISTER(rn, (rnv + off));
|
||||
SetRegister(rn, (rnv + off));
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -557,20 +562,19 @@ void arm7_cpu_device::HandleMemSingle(UINT32 insn)
|
||||
/* Writeback is applied in pipeline, before value is read from mem,
|
||||
so writeback is effectively ignored */
|
||||
if (rd == rn) {
|
||||
SET_REGISTER(rn, GET_REGISTER(rd));
|
||||
SetRegister(rn, GetRegister(rd));
|
||||
}
|
||||
else {
|
||||
SET_REGISTER(rn, (rnv - off));
|
||||
SetRegister(rn, (rnv - off));
|
||||
|
||||
if ((insn & INSN_SDT_W) != 0)
|
||||
LOG(("%08x: RegisterWritebackDecrement %d %d %d\n", R15, (insn & INSN_SDT_P) != 0, (insn & INSN_SDT_W) != 0, (insn & INSN_SDT_U) != 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ARM7_CHECKIRQ
|
||||
// arm7_check_irq_state();
|
||||
|
||||
} /* HandleMemSingle */
|
||||
|
||||
@ -585,7 +589,7 @@ void arm7_cpu_device::HandleHalfWordDT(UINT32 insn)
|
||||
}
|
||||
else {
|
||||
// register
|
||||
off = GET_REGISTER(insn & 0x0f);
|
||||
off = GetRegister(insn & 0x0f);
|
||||
}
|
||||
|
||||
/* Calculate Rn, accounting for PC */
|
||||
@ -596,17 +600,17 @@ void arm7_cpu_device::HandleHalfWordDT(UINT32 insn)
|
||||
/* Pre-indexed addressing */
|
||||
if (insn & INSN_SDT_U)
|
||||
{
|
||||
rnv = (GET_REGISTER(rn) + off);
|
||||
rnv = (GetRegister(rn) + off);
|
||||
}
|
||||
else
|
||||
{
|
||||
rnv = (GET_REGISTER(rn) - off);
|
||||
rnv = (GetRegister(rn) - off);
|
||||
}
|
||||
|
||||
if (insn & INSN_SDT_W)
|
||||
{
|
||||
rnv_old = GET_REGISTER(rn);
|
||||
SET_REGISTER(rn, rnv);
|
||||
rnv_old = GetRegister(rn);
|
||||
SetRegister(rn, rnv);
|
||||
|
||||
// check writeback???
|
||||
}
|
||||
@ -624,7 +628,7 @@ void arm7_cpu_device::HandleHalfWordDT(UINT32 insn)
|
||||
}
|
||||
else
|
||||
{
|
||||
rnv = GET_REGISTER(rn);
|
||||
rnv = GetRegister(rn);
|
||||
}
|
||||
}
|
||||
|
||||
@ -655,7 +659,7 @@ void arm7_cpu_device::HandleHalfWordDT(UINT32 insn)
|
||||
newval = (UINT32)(signbyte << 8)|databyte;
|
||||
}
|
||||
|
||||
if (m_pendingAbtD == 0)
|
||||
if (!m_pendingAbtD)
|
||||
{
|
||||
// PC?
|
||||
if (rd == eR15)
|
||||
@ -667,7 +671,7 @@ void arm7_cpu_device::HandleHalfWordDT(UINT32 insn)
|
||||
}
|
||||
else
|
||||
{
|
||||
SET_REGISTER(rd, newval);
|
||||
SetRegister(rd, newval);
|
||||
R15 += 4;
|
||||
}
|
||||
|
||||
@ -683,20 +687,19 @@ void arm7_cpu_device::HandleHalfWordDT(UINT32 insn)
|
||||
{
|
||||
UINT32 newval = READ16(rnv);
|
||||
|
||||
if (m_pendingAbtD == 0)
|
||||
if (!m_pendingAbtD)
|
||||
{
|
||||
if (rd == eR15)
|
||||
{
|
||||
R15 = newval + 8;
|
||||
// extra cycles for LDR(H,SH,SB) PC (5 total cycles)
|
||||
ARM7_ICOUNT -= 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
SET_REGISTER(rd, newval);
|
||||
R15 += 4;
|
||||
}
|
||||
|
||||
if (rd == eR15)
|
||||
{
|
||||
R15 = newval + 8;
|
||||
// extra cycles for LDR(H,SH,SB) PC (5 total cycles)
|
||||
ARM7_ICOUNT -= 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetRegister(rd, newval);
|
||||
R15 += 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -711,38 +714,38 @@ void arm7_cpu_device::HandleHalfWordDT(UINT32 insn)
|
||||
else
|
||||
{
|
||||
if ((insn & 0x60) == 0x40) // LDRD
|
||||
{
|
||||
SET_REGISTER(rd, READ32(rnv));
|
||||
SET_REGISTER(rd+1, READ32(rnv+4));
|
||||
{
|
||||
SetRegister(rd, READ32(rnv));
|
||||
SetRegister(rd+1, READ32(rnv+4));
|
||||
R15 += 4;
|
||||
}
|
||||
}
|
||||
else if ((insn & 0x60) == 0x60) // STRD
|
||||
{
|
||||
WRITE32(rnv, GET_REGISTER(rd));
|
||||
WRITE32(rnv+4, GET_REGISTER(rd+1));
|
||||
R15 += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
// WRITE16(rnv, rd == eR15 ? R15 + 8 : GET_REGISTER(rd));
|
||||
WRITE16(rnv, rd == eR15 ? R15 + 8 + 4 : GET_REGISTER(rd)); // manual says STR RD=PC, +12 of address
|
||||
{
|
||||
WRITE32(rnv, GetRegister(rd));
|
||||
WRITE32(rnv+4, GetRegister(rd+1));
|
||||
R15 += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
// WRITE16(rnv, rd == eR15 ? R15 + 8 : GetRegister(rd));
|
||||
WRITE16(rnv, rd == eR15 ? R15 + 8 + 4 : GetRegister(rd)); // manual says STR RD=PC, +12 of address
|
||||
|
||||
// if R15 is not increased then e.g. "STRH R10, [R15,#$10]" will be executed over and over again
|
||||
#if 0
|
||||
if (rn != eR15)
|
||||
#endif
|
||||
R15 += 4;
|
||||
R15 += 4;
|
||||
|
||||
// STRH takes 2 cycles, so we add + 1
|
||||
ARM7_ICOUNT += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_pendingAbtD != 0)
|
||||
if (m_pendingAbtD)
|
||||
{
|
||||
if ((insn & INSN_SDT_P) && (insn & INSN_SDT_W))
|
||||
{
|
||||
SET_REGISTER(rn, rnv_old);
|
||||
SetRegister(rn, rnv_old);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -757,14 +760,14 @@ void arm7_cpu_device::HandleHalfWordDT(UINT32 insn)
|
||||
/* Writeback is applied in pipeline, before value is read from mem,
|
||||
so writeback is effectively ignored */
|
||||
if (rd == rn) {
|
||||
SET_REGISTER(rn, GET_REGISTER(rd));
|
||||
SetRegister(rn, GetRegister(rd));
|
||||
// todo: check for offs... ?
|
||||
}
|
||||
else {
|
||||
if ((insn & INSN_SDT_W) != 0)
|
||||
LOG(("%08x: RegisterWritebackIncrement %d %d %d\n", R15, (insn & INSN_SDT_P) != 0, (insn & INSN_SDT_W) != 0, (insn & INSN_SDT_U) != 0));
|
||||
|
||||
SET_REGISTER(rn, (rnv + off));
|
||||
SetRegister(rn, (rnv + off));
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -772,10 +775,10 @@ void arm7_cpu_device::HandleHalfWordDT(UINT32 insn)
|
||||
/* Writeback is applied in pipeline, before value is read from mem,
|
||||
so writeback is effectively ignored */
|
||||
if (rd == rn) {
|
||||
SET_REGISTER(rn, GET_REGISTER(rd));
|
||||
SetRegister(rn, GetRegister(rd));
|
||||
}
|
||||
else {
|
||||
SET_REGISTER(rn, (rnv - off));
|
||||
SetRegister(rn, (rnv - off));
|
||||
|
||||
if ((insn & INSN_SDT_W) != 0)
|
||||
LOG(("%08x: RegisterWritebackDecrement %d %d %d\n", R15, (insn & INSN_SDT_P) != 0, (insn & INSN_SDT_W) != 0, (insn & INSN_SDT_U) != 0));
|
||||
@ -791,8 +794,8 @@ void arm7_cpu_device::HandleSwap(UINT32 insn)
|
||||
{
|
||||
UINT32 rn, rm, rd, tmp;
|
||||
|
||||
rn = GET_REGISTER((insn >> 16) & 0xf); // reg. w/read address
|
||||
rm = GET_REGISTER(insn & 0xf); // reg. w/write address
|
||||
rn = GetRegister((insn >> 16) & 0xf); // reg. w/read address
|
||||
rm = GetRegister(insn & 0xf); // reg. w/write address
|
||||
rd = (insn >> 12) & 0xf; // dest reg
|
||||
|
||||
#if ARM7_DEBUG_CORE
|
||||
@ -805,13 +808,13 @@ void arm7_cpu_device::HandleSwap(UINT32 insn)
|
||||
{
|
||||
tmp = READ8(rn);
|
||||
WRITE8(rn, rm);
|
||||
SET_REGISTER(rd, tmp);
|
||||
SetRegister(rd, tmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp = READ32(rn);
|
||||
WRITE32(rn, rm);
|
||||
SET_REGISTER(rd, tmp);
|
||||
SetRegister(rd, tmp);
|
||||
}
|
||||
|
||||
R15 += 4;
|
||||
@ -826,7 +829,7 @@ void arm7_cpu_device::HandlePSRTransfer(UINT32 insn)
|
||||
int oldmode = GET_CPSR & MODE_FLAG;
|
||||
|
||||
// get old value of CPSR/SPSR
|
||||
newval = GET_REGISTER(reg);
|
||||
newval = GetRegister(reg);
|
||||
|
||||
// MSR (bit 21 set) - Copy value to CPSR/SPSR
|
||||
if ((insn & 0x00200000))
|
||||
@ -843,7 +846,7 @@ void arm7_cpu_device::HandlePSRTransfer(UINT32 insn)
|
||||
// Value from Register
|
||||
else
|
||||
{
|
||||
val = GET_REGISTER(insn & 0x0f);
|
||||
val = GetRegister(insn & 0x0f);
|
||||
}
|
||||
|
||||
// apply field code bits
|
||||
@ -903,9 +906,11 @@ void arm7_cpu_device::HandlePSRTransfer(UINT32 insn)
|
||||
|
||||
// Update the Register
|
||||
if (reg == eCPSR)
|
||||
SET_CPSR(newval);
|
||||
{
|
||||
set_cpsr(newval);
|
||||
}
|
||||
else
|
||||
SET_REGISTER(reg, newval);
|
||||
SetRegister(reg, newval);
|
||||
|
||||
// Switch to new mode if changed
|
||||
if ((newval & MODE_FLAG) != oldmode)
|
||||
@ -915,7 +920,7 @@ void arm7_cpu_device::HandlePSRTransfer(UINT32 insn)
|
||||
// MRS (bit 21 clear) - Copy CPSR or SPSR to specified Register
|
||||
else
|
||||
{
|
||||
SET_REGISTER((insn >> 12)& 0x0f, GET_REGISTER(reg));
|
||||
SetRegister((insn >> 12)& 0x0f, GetRegister(reg));
|
||||
}
|
||||
}
|
||||
|
||||
@ -982,7 +987,7 @@ void arm7_cpu_device::HandleALU(UINT32 insn)
|
||||
}
|
||||
else
|
||||
{
|
||||
rn = GET_REGISTER(rn);
|
||||
rn = GetRegister(rn);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1078,7 +1083,7 @@ void arm7_cpu_device::HandleALU(UINT32 insn)
|
||||
if (GET_MODE != eARM7_MODE_USER)
|
||||
{
|
||||
// Update CPSR from SPSR
|
||||
SET_CPSR(GET_REGISTER(SPSR));
|
||||
set_cpsr(GetRegister(SPSR));
|
||||
SwitchMode(GET_MODE);
|
||||
}
|
||||
|
||||
@ -1090,7 +1095,7 @@ void arm7_cpu_device::HandleALU(UINT32 insn)
|
||||
UINT32 temp;
|
||||
R15 = rd; //(R15 & 0x03FFFFFC) | (rd & 0xFC000003);
|
||||
temp = (GET_CPSR & 0x0FFFFF20) | (rd & 0xF0000000) /* N Z C V */ | ((rd & 0x0C000000) >> (26 - 6)) /* I F */ | (rd & 0x00000003) /* M1 M0 */;
|
||||
SET_CPSR( temp);
|
||||
set_cpsr( temp);
|
||||
SwitchMode( temp & 3);
|
||||
}
|
||||
|
||||
@ -1098,11 +1103,11 @@ void arm7_cpu_device::HandleALU(UINT32 insn)
|
||||
ARM7_ICOUNT -= 2;
|
||||
|
||||
/* IRQ masks may have changed in this instruction */
|
||||
// ARM7_CHECKIRQ;
|
||||
// arm7_check_irq_state();
|
||||
}
|
||||
else
|
||||
/* S Flag is set - Write results to register & update CPSR (which was already handled using HandleALU flag macros) */
|
||||
SET_REGISTER(rdn, rd);
|
||||
SetRegister(rdn, rd);
|
||||
}
|
||||
}
|
||||
// SJE: Don't think this applies any more.. (see page 44 at bottom)
|
||||
@ -1120,12 +1125,12 @@ void arm7_cpu_device::HandleALU(UINT32 insn)
|
||||
UINT32 temp;
|
||||
R15 = (R15 & 0x03FFFFFC) | (rd & ~0x03FFFFFC);
|
||||
temp = (GET_CPSR & 0x0FFFFF20) | (rd & 0xF0000000) /* N Z C V */ | ((rd & 0x0C000000) >> (26 - 6)) /* I F */ | (rd & 0x00000003) /* M1 M0 */;
|
||||
SET_CPSR( temp);
|
||||
set_cpsr( temp);
|
||||
SwitchMode( temp & 3);
|
||||
}
|
||||
|
||||
/* IRQ masks may have changed in this instruction */
|
||||
// ARM7_CHECKIRQ;
|
||||
// arm7_check_irq_state();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1151,8 +1156,8 @@ void arm7_cpu_device::HandleMul(UINT32 insn)
|
||||
// multiply, which is controlled by the value of the multiplier operand
|
||||
// specified by Rs.
|
||||
|
||||
rm = GET_REGISTER(insn & INSN_MUL_RM);
|
||||
rs = GET_REGISTER((insn & INSN_MUL_RS) >> INSN_MUL_RS_SHIFT);
|
||||
rm = GetRegister(insn & INSN_MUL_RM);
|
||||
rs = GetRegister((insn & INSN_MUL_RS) >> INSN_MUL_RS_SHIFT);
|
||||
|
||||
/* Do the basic multiply of Rm and Rs */
|
||||
r = rm * rs;
|
||||
@ -1167,18 +1172,18 @@ void arm7_cpu_device::HandleMul(UINT32 insn)
|
||||
/* Add on Rn if this is a MLA */
|
||||
if (insn & INSN_MUL_A)
|
||||
{
|
||||
r += GET_REGISTER((insn & INSN_MUL_RN) >> INSN_MUL_RN_SHIFT);
|
||||
r += GetRegister((insn & INSN_MUL_RN) >> INSN_MUL_RN_SHIFT);
|
||||
// extra cycle for MLA
|
||||
ARM7_ICOUNT -= 1;
|
||||
}
|
||||
|
||||
/* Write the result */
|
||||
SET_REGISTER((insn & INSN_MUL_RD) >> INSN_MUL_RD_SHIFT, r);
|
||||
SetRegister((insn & INSN_MUL_RD) >> INSN_MUL_RD_SHIFT, r);
|
||||
|
||||
/* Set N and Z if asked */
|
||||
if (insn & INSN_S)
|
||||
{
|
||||
SET_CPSR((GET_CPSR & ~(N_MASK | Z_MASK)) | HandleALUNZFlags(r));
|
||||
set_cpsr((GET_CPSR & ~(N_MASK | Z_MASK)) | HandleALUNZFlags(r));
|
||||
}
|
||||
|
||||
if (rs & SIGN_BIT) rs = -rs;
|
||||
@ -1201,8 +1206,8 @@ void arm7_cpu_device::HandleSMulLong(UINT32 insn)
|
||||
// number of 8 bit multiplier array cycles required to complete the multiply, which is
|
||||
// controlled by the value of the multiplier operand specified by Rs.
|
||||
|
||||
rm = (INT32)GET_REGISTER(insn & 0xf);
|
||||
rs = (INT32)GET_REGISTER(((insn >> 8) & 0xf));
|
||||
rm = (INT32)GetRegister(insn & 0xf);
|
||||
rs = (INT32)GetRegister(((insn >> 8) & 0xf));
|
||||
rhi = (insn >> 16) & 0xf;
|
||||
rlo = (insn >> 12) & 0xf;
|
||||
|
||||
@ -1217,20 +1222,20 @@ void arm7_cpu_device::HandleSMulLong(UINT32 insn)
|
||||
/* Add on Rn if this is a MLA */
|
||||
if (insn & INSN_MUL_A)
|
||||
{
|
||||
INT64 acum = (INT64)((((INT64)(GET_REGISTER(rhi))) << 32) | GET_REGISTER(rlo));
|
||||
INT64 acum = (INT64)((((INT64)(GetRegister(rhi))) << 32) | GetRegister(rlo));
|
||||
res += acum;
|
||||
// extra cycle for MLA
|
||||
ARM7_ICOUNT -= 1;
|
||||
}
|
||||
|
||||
/* Write the result (upper dword goes to RHi, lower to RLo) */
|
||||
SET_REGISTER(rhi, res >> 32);
|
||||
SET_REGISTER(rlo, res & 0xFFFFFFFF);
|
||||
SetRegister(rhi, res >> 32);
|
||||
SetRegister(rlo, res & 0xFFFFFFFF);
|
||||
|
||||
/* Set N and Z if asked */
|
||||
if (insn & INSN_S)
|
||||
{
|
||||
SET_CPSR((GET_CPSR & ~(N_MASK | Z_MASK)) | HandleLongALUNZFlags(res));
|
||||
set_cpsr((GET_CPSR & ~(N_MASK | Z_MASK)) | HandleLongALUNZFlags(res));
|
||||
}
|
||||
|
||||
if (rs < 0) rs = -rs;
|
||||
@ -1253,8 +1258,8 @@ void arm7_cpu_device::HandleUMulLong(UINT32 insn)
|
||||
// number of 8 bit multiplier array cycles required to complete the multiply, which is
|
||||
// controlled by the value of the multiplier operand specified by Rs.
|
||||
|
||||
rm = (INT32)GET_REGISTER(insn & 0xf);
|
||||
rs = (INT32)GET_REGISTER(((insn >> 8) & 0xf));
|
||||
rm = (INT32)GetRegister(insn & 0xf);
|
||||
rs = (INT32)GetRegister(((insn >> 8) & 0xf));
|
||||
rhi = (insn >> 16) & 0xf;
|
||||
rlo = (insn >> 12) & 0xf;
|
||||
|
||||
@ -1269,20 +1274,20 @@ void arm7_cpu_device::HandleUMulLong(UINT32 insn)
|
||||
/* Add on Rn if this is a MLA */
|
||||
if (insn & INSN_MUL_A)
|
||||
{
|
||||
UINT64 acum = (UINT64)((((UINT64)(GET_REGISTER(rhi))) << 32) | GET_REGISTER(rlo));
|
||||
UINT64 acum = (UINT64)((((UINT64)(GetRegister(rhi))) << 32) | GetRegister(rlo));
|
||||
res += acum;
|
||||
// extra cycle for MLA
|
||||
ARM7_ICOUNT -= 1;
|
||||
}
|
||||
|
||||
/* Write the result (upper dword goes to RHi, lower to RLo) */
|
||||
SET_REGISTER(rhi, res >> 32);
|
||||
SET_REGISTER(rlo, res & 0xFFFFFFFF);
|
||||
SetRegister(rhi, res >> 32);
|
||||
SetRegister(rlo, res & 0xFFFFFFFF);
|
||||
|
||||
/* Set N and Z if asked */
|
||||
if (insn & INSN_S)
|
||||
{
|
||||
SET_CPSR((GET_CPSR & ~(N_MASK | Z_MASK)) | HandleLongALUNZFlags(res));
|
||||
set_cpsr((GET_CPSR & ~(N_MASK | Z_MASK)) | HandleLongALUNZFlags(res));
|
||||
}
|
||||
|
||||
if (rs < 0x00000100) ARM7_ICOUNT -= 1 + 1 + 1;
|
||||
@ -1296,7 +1301,7 @@ void arm7_cpu_device::HandleUMulLong(UINT32 insn)
|
||||
void arm7_cpu_device::HandleMemBlock(UINT32 insn)
|
||||
{
|
||||
UINT32 rb = (insn & INSN_RN) >> INSN_RN_SHIFT;
|
||||
UINT32 rbp = GET_REGISTER(rb);
|
||||
UINT32 rbp = GetRegister(rb);
|
||||
int result;
|
||||
|
||||
#if ARM7_DEBUG_CORE
|
||||
@ -1335,7 +1340,7 @@ void arm7_cpu_device::HandleMemBlock(UINT32 insn)
|
||||
else
|
||||
result = loadInc(insn & 0xffff, rbp, insn & INSN_BDT_S, GET_MODE);
|
||||
|
||||
if ((insn & INSN_BDT_W) && (m_pendingAbtD == 0))
|
||||
if ((insn & INSN_BDT_W) && !m_pendingAbtD)
|
||||
{
|
||||
#if ARM7_DEBUG_CORE
|
||||
if (rb == 15)
|
||||
@ -1345,19 +1350,20 @@ void arm7_cpu_device::HandleMemBlock(UINT32 insn)
|
||||
// GBA "V-Rally 3" expects R0 not to be overwritten with the updated base value [BP 8077B0C]
|
||||
if (((insn >> rb) & 1) == 0)
|
||||
{
|
||||
SET_REGISTER(rb, GET_REGISTER(rb) + result * 4);
|
||||
SetRegister(rb, GetRegister(rb) + result * 4);
|
||||
}
|
||||
}
|
||||
|
||||
// R15 included? (NOTE: CPSR restore must occur LAST otherwise wrong registers restored!)
|
||||
if ((insn & 0x8000) && (m_pendingAbtD == 0)) {
|
||||
if ((insn & 0x8000) && !m_pendingAbtD)
|
||||
{
|
||||
R15 -= 4; // SJE: I forget why i did this?
|
||||
// S - Flag Set? Signals transfer of current mode SPSR->CPSR
|
||||
if (insn & INSN_BDT_S)
|
||||
{
|
||||
if (MODE32)
|
||||
{
|
||||
SET_CPSR(GET_REGISTER(SPSR));
|
||||
set_cpsr(GetRegister(SPSR));
|
||||
SwitchMode(GET_MODE);
|
||||
}
|
||||
else
|
||||
@ -1365,7 +1371,7 @@ void arm7_cpu_device::HandleMemBlock(UINT32 insn)
|
||||
UINT32 temp;
|
||||
// LOG(("LDM + S | R15 %08X CPSR %08X\n", R15, GET_CPSR));
|
||||
temp = (GET_CPSR & 0x0FFFFF20) | (R15 & 0xF0000000) /* N Z C V */ | ((R15 & 0x0C000000) >> (26 - 6)) /* I F */ | (R15 & 0x00000003) /* M1 M0 */;
|
||||
SET_CPSR( temp);
|
||||
set_cpsr( temp);
|
||||
SwitchMode(temp & 3);
|
||||
}
|
||||
}
|
||||
@ -1395,26 +1401,26 @@ void arm7_cpu_device::HandleMemBlock(UINT32 insn)
|
||||
else
|
||||
result = loadDec(insn & 0xffff, rbp, insn & INSN_BDT_S, GET_MODE);
|
||||
|
||||
if ((insn & INSN_BDT_W) && (m_pendingAbtD == 0))
|
||||
if ((insn & INSN_BDT_W) && !m_pendingAbtD)
|
||||
{
|
||||
if (rb == 0xf)
|
||||
LOG(("%08x: Illegal LDRM writeback to r15\n", R15));
|
||||
// "A LDM will always overwrite the updated base if the base is in the list." (also for a user bank transfer?)
|
||||
if (((insn >> rb) & 1) == 0)
|
||||
{
|
||||
SET_REGISTER(rb, GET_REGISTER(rb) - result * 4);
|
||||
SetRegister(rb, GetRegister(rb) - result * 4);
|
||||
}
|
||||
}
|
||||
|
||||
// R15 included? (NOTE: CPSR restore must occur LAST otherwise wrong registers restored!)
|
||||
if ((insn & 0x8000) && (m_pendingAbtD == 0)) {
|
||||
if ((insn & 0x8000) && !m_pendingAbtD) {
|
||||
R15 -= 4; // SJE: I forget why i did this?
|
||||
// S - Flag Set? Signals transfer of current mode SPSR->CPSR
|
||||
if (insn & INSN_BDT_S)
|
||||
{
|
||||
if (MODE32)
|
||||
{
|
||||
SET_CPSR(GET_REGISTER(SPSR));
|
||||
set_cpsr(GetRegister(SPSR));
|
||||
SwitchMode(GET_MODE);
|
||||
}
|
||||
else
|
||||
@ -1422,7 +1428,7 @@ void arm7_cpu_device::HandleMemBlock(UINT32 insn)
|
||||
UINT32 temp;
|
||||
// LOG(("LDM + S | R15 %08X CPSR %08X\n", R15, GET_CPSR));
|
||||
temp = (GET_CPSR & 0x0FFFFF20) /* N Z C V I F M4 M3 M2 M1 M0 */ | (R15 & 0xF0000000) /* N Z C V */ | ((R15 & 0x0C000000) >> (26 - 6)) /* I F */ | (R15 & 0x00000003) /* M1 M0 */;
|
||||
SET_CPSR( temp);
|
||||
set_cpsr(temp);
|
||||
SwitchMode(temp & 3);
|
||||
}
|
||||
}
|
||||
@ -1468,9 +1474,9 @@ void arm7_cpu_device::HandleMemBlock(UINT32 insn)
|
||||
else
|
||||
result = storeInc(insn & 0xffff, rbp, GET_MODE);
|
||||
|
||||
if ((insn & INSN_BDT_W) && (m_pendingAbtD == 0))
|
||||
if ((insn & INSN_BDT_W) && !m_pendingAbtD)
|
||||
{
|
||||
SET_REGISTER(rb, GET_REGISTER(rb) + result * 4);
|
||||
SetRegister(rb, GetRegister(rb) + result * 4);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1495,9 +1501,9 @@ void arm7_cpu_device::HandleMemBlock(UINT32 insn)
|
||||
else
|
||||
result = storeDec(insn & 0xffff, rbp, GET_MODE);
|
||||
|
||||
if ((insn & INSN_BDT_W) && (m_pendingAbtD == 0))
|
||||
if ((insn & INSN_BDT_W) && !m_pendingAbtD)
|
||||
{
|
||||
SET_REGISTER(rb, GET_REGISTER(rb) - result * 4);
|
||||
SetRegister(rb, GetRegister(rb) - result * 4);
|
||||
}
|
||||
}
|
||||
if (insn & (1 << eR15))
|
||||
@ -1530,10 +1536,10 @@ void arm7_cpu_device::arm7ops_0123(UINT32 insn)
|
||||
/* Branch and Exchange (BX) */
|
||||
if ((insn & 0x0ffffff0) == 0x012fff10) // bits 27-4 == 000100101111111111110001
|
||||
{
|
||||
R15 = GET_REGISTER(insn & 0x0f);
|
||||
R15 = GetRegister(insn & 0x0f);
|
||||
// If new PC address has A0 set, switch to Thumb mode
|
||||
if (R15 & 1) {
|
||||
SET_CPSR(GET_CPSR|T_MASK);
|
||||
set_cpsr(GET_CPSR|T_MASK);
|
||||
R15--;
|
||||
}
|
||||
}
|
||||
@ -1542,25 +1548,25 @@ void arm7_cpu_device::arm7ops_0123(UINT32 insn)
|
||||
UINT32 rm = insn&0xf;
|
||||
UINT32 rd = (insn>>12)&0xf;
|
||||
|
||||
SET_REGISTER(rd, count_leading_zeros(GET_REGISTER(rm)));
|
||||
SetRegister(rd, count_leading_zeros(GetRegister(rm)));
|
||||
|
||||
R15 += 4;
|
||||
}
|
||||
else if ((insn & 0x0ff000f0) == 0x01000050) // QADD - v5
|
||||
{
|
||||
INT32 src1 = GET_REGISTER(insn&0xf);
|
||||
INT32 src2 = GET_REGISTER((insn>>16)&0xf);
|
||||
INT32 src1 = GetRegister(insn&0xf);
|
||||
INT32 src2 = GetRegister((insn>>16)&0xf);
|
||||
INT64 res;
|
||||
|
||||
res = saturate_qbit_overflow((INT64)src1 + (INT64)src2);
|
||||
|
||||
SET_REGISTER((insn>>12)&0xf, (INT32)res);
|
||||
SetRegister((insn>>12)&0xf, (INT32)res);
|
||||
R15 += 4;
|
||||
}
|
||||
else if ((insn & 0x0ff000f0) == 0x01400050) // QDADD - v5
|
||||
{
|
||||
INT32 src1 = GET_REGISTER(insn&0xf);
|
||||
INT32 src2 = GET_REGISTER((insn>>16)&0xf);
|
||||
INT32 src1 = GetRegister(insn&0xf);
|
||||
INT32 src2 = GetRegister((insn>>16)&0xf);
|
||||
INT64 res;
|
||||
|
||||
// check if doubling operation will overflow
|
||||
@ -1570,24 +1576,24 @@ void arm7_cpu_device::arm7ops_0123(UINT32 insn)
|
||||
src2 *= 2;
|
||||
res = saturate_qbit_overflow((INT64)src1 + (INT64)src2);
|
||||
|
||||
SET_REGISTER((insn>>12)&0xf, (INT32)res);
|
||||
SetRegister((insn>>12)&0xf, (INT32)res);
|
||||
R15 += 4;
|
||||
}
|
||||
else if ((insn & 0x0ff000f0) == 0x01200050) // QSUB - v5
|
||||
{
|
||||
INT32 src1 = GET_REGISTER(insn&0xf);
|
||||
INT32 src2 = GET_REGISTER((insn>>16)&0xf);
|
||||
INT32 src1 = GetRegister(insn&0xf);
|
||||
INT32 src2 = GetRegister((insn>>16)&0xf);
|
||||
INT64 res;
|
||||
|
||||
res = saturate_qbit_overflow((INT64)src1 - (INT64)src2);
|
||||
|
||||
SET_REGISTER((insn>>12)&0xf, (INT32)res);
|
||||
SetRegister((insn>>12)&0xf, (INT32)res);
|
||||
R15 += 4;
|
||||
}
|
||||
else if ((insn & 0x0ff000f0) == 0x01600050) // QDSUB - v5
|
||||
{
|
||||
INT32 src1 = GET_REGISTER(insn&0xf);
|
||||
INT32 src2 = GET_REGISTER((insn>>16)&0xf);
|
||||
INT32 src1 = GetRegister(insn&0xf);
|
||||
INT32 src2 = GetRegister((insn>>16)&0xf);
|
||||
INT64 res;
|
||||
|
||||
// check if doubling operation will overflow
|
||||
@ -1597,13 +1603,13 @@ void arm7_cpu_device::arm7ops_0123(UINT32 insn)
|
||||
src2 *= 2;
|
||||
res = saturate_qbit_overflow((INT64)src1 - (INT64)src2);
|
||||
|
||||
SET_REGISTER((insn>>12)&0xf, (INT32)res);
|
||||
SetRegister((insn>>12)&0xf, (INT32)res);
|
||||
R15 += 4;
|
||||
}
|
||||
else if ((insn & 0x0ff00090) == 0x01000080) // SMLAxy - v5
|
||||
{
|
||||
INT32 src1 = GET_REGISTER(insn&0xf);
|
||||
INT32 src2 = GET_REGISTER((insn>>8)&0xf);
|
||||
INT32 src1 = GetRegister(insn&0xf);
|
||||
INT32 src2 = GetRegister((insn>>8)&0xf);
|
||||
INT32 res1;
|
||||
|
||||
// select top and bottom halves of src1/src2 and sign extend if necessary
|
||||
@ -1632,32 +1638,32 @@ void arm7_cpu_device::arm7ops_0123(UINT32 insn)
|
||||
// do the signed multiply
|
||||
res1 = src1 * src2;
|
||||
// and the accumulate. NOTE: only the accumulate can cause an overflow, which is why we do it this way.
|
||||
saturate_qbit_overflow((INT64)res1 + (INT64)GET_REGISTER((insn>>12)&0xf));
|
||||
saturate_qbit_overflow((INT64)res1 + (INT64)GetRegister((insn>>12)&0xf));
|
||||
|
||||
SET_REGISTER((insn>>16)&0xf, res1 + GET_REGISTER((insn>>12)&0xf));
|
||||
SetRegister((insn>>16)&0xf, res1 + GetRegister((insn>>12)&0xf));
|
||||
R15 += 4;
|
||||
}
|
||||
else if ((insn & 0x0ff00090) == 0x01400080) // SMLALxy - v5
|
||||
{
|
||||
INT32 src1 = GET_REGISTER(insn&0xf);
|
||||
INT32 src2 = GET_REGISTER((insn>>8)&0xf);
|
||||
INT32 src1 = GetRegister(insn&0xf);
|
||||
INT32 src2 = GetRegister((insn>>8)&0xf);
|
||||
INT64 dst;
|
||||
|
||||
dst = (INT64)GET_REGISTER((insn>>12)&0xf);
|
||||
dst |= (INT64)GET_REGISTER((insn>>16)&0xf)<<32;
|
||||
dst = (INT64)GetRegister((insn>>12)&0xf);
|
||||
dst |= (INT64)GetRegister((insn>>16)&0xf)<<32;
|
||||
|
||||
// do the multiply and accumulate
|
||||
dst += (INT64)src1 * (INT64)src2;
|
||||
|
||||
// write back the result
|
||||
SET_REGISTER((insn>>12)&0xf, (UINT32)dst);
|
||||
SET_REGISTER((insn>>16)&0xf, (UINT32)(dst >> 32));
|
||||
SetRegister((insn>>12)&0xf, (UINT32)dst);
|
||||
SetRegister((insn>>16)&0xf, (UINT32)(dst >> 32));
|
||||
R15 += 4;
|
||||
}
|
||||
else if ((insn & 0x0ff00090) == 0x01600080) // SMULxy - v5
|
||||
{
|
||||
INT32 src1 = GET_REGISTER(insn&0xf);
|
||||
INT32 src2 = GET_REGISTER((insn>>8)&0xf);
|
||||
INT32 src1 = GetRegister(insn&0xf);
|
||||
INT32 src2 = GetRegister((insn>>8)&0xf);
|
||||
INT32 res;
|
||||
|
||||
// select top and bottom halves of src1/src2 and sign extend if necessary
|
||||
@ -1684,13 +1690,13 @@ void arm7_cpu_device::arm7ops_0123(UINT32 insn)
|
||||
}
|
||||
|
||||
res = src1 * src2;
|
||||
SET_REGISTER((insn>>16)&0xf, res);
|
||||
SetRegister((insn>>16)&0xf, res);
|
||||
R15 += 4;
|
||||
}
|
||||
else if ((insn & 0x0ff000b0) == 0x012000a0) // SMULWy - v5
|
||||
{
|
||||
INT32 src1 = GET_REGISTER(insn&0xf);
|
||||
INT32 src2 = GET_REGISTER((insn>>8)&0xf);
|
||||
INT32 src1 = GetRegister(insn&0xf);
|
||||
INT32 src2 = GetRegister((insn>>8)&0xf);
|
||||
INT64 res;
|
||||
|
||||
if (insn & 0x40)
|
||||
@ -1706,14 +1712,14 @@ void arm7_cpu_device::arm7ops_0123(UINT32 insn)
|
||||
|
||||
res = (INT64)src1 * (INT64)src2;
|
||||
res >>= 16;
|
||||
SET_REGISTER((insn>>16)&0xf, (UINT32)res);
|
||||
SetRegister((insn>>16)&0xf, (UINT32)res);
|
||||
R15 += 4;
|
||||
}
|
||||
else if ((insn & 0x0ff000b0) == 0x01200080) // SMLAWy - v5
|
||||
{
|
||||
INT32 src1 = GET_REGISTER(insn&0xf);
|
||||
INT32 src2 = GET_REGISTER((insn>>8)&0xf);
|
||||
INT32 src3 = GET_REGISTER((insn>>12)&0xf);
|
||||
INT32 src1 = GetRegister(insn&0xf);
|
||||
INT32 src2 = GetRegister((insn>>8)&0xf);
|
||||
INT32 src3 = GetRegister((insn>>12)&0xf);
|
||||
INT64 res;
|
||||
|
||||
if (insn & 0x40)
|
||||
@ -1737,7 +1743,7 @@ void arm7_cpu_device::arm7ops_0123(UINT32 insn)
|
||||
src3 += (INT32)res;
|
||||
|
||||
// write the result back
|
||||
SET_REGISTER((insn>>16)&0xf, (UINT32)res);
|
||||
SetRegister((insn>>16)&0xf, (UINT32)res);
|
||||
R15 += 4;
|
||||
}
|
||||
else
|
||||
@ -1844,8 +1850,9 @@ void arm7_cpu_device::arm7ops_e(UINT32 insn) /* Co-Processor Data Operation or R
|
||||
|
||||
void arm7_cpu_device::arm7ops_f(UINT32 insn) /* Software Interrupt */
|
||||
{
|
||||
m_pendingSwi = 1;
|
||||
ARM7_CHECKIRQ;
|
||||
m_pendingSwi = true;
|
||||
update_irq_state();
|
||||
arm7_check_irq_state();
|
||||
//couldn't find any cycle counts for SWI
|
||||
// break;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user