mirror of
https://github.com/holub/mame
synced 2025-06-28 15:14:21 +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)
|
void arm7_cpu_device::set_cpsr(UINT32 val)
|
||||||
{
|
{
|
||||||
|
UINT8 old_mode = GET_CPSR & MODE_FLAG;
|
||||||
if (m_archFlags & eARM_ARCHFLAGS_MODE26)
|
if (m_archFlags & eARM_ARCHFLAGS_MODE26)
|
||||||
{
|
{
|
||||||
if ((val & 0x10) != (m_r[eCPSR] & 0x10))
|
if ((val & 0x10) != (m_r[eCPSR] & 0x10))
|
||||||
@ -158,6 +163,10 @@ void arm7_cpu_device::set_cpsr(UINT32 val)
|
|||||||
val |= 0x10; // force valid mode
|
val |= 0x10; // force valid mode
|
||||||
}
|
}
|
||||||
m_r[eCPSR] = val;
|
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
|
// COARSE, desc_level1, vaddr
|
||||||
UINT32 arm7_cpu_device::arm7_tlb_get_second_level_descriptor( UINT32 granularity, UINT32 first_desc, UINT32 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"
|
case 0 : // "No access - Any access generates a domain fault"
|
||||||
{
|
{
|
||||||
@ -219,9 +221,25 @@ 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"
|
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))
|
||||||
|
{
|
||||||
|
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 s = (m_control & COPRO_CTRL_SYSTEM) ? 1 : 0;
|
||||||
int r = (m_control & COPRO_CTRL_ROM) ? 1 : 0;
|
int r = (m_control & COPRO_CTRL_ROM) ? 1 : 0;
|
||||||
@ -254,28 +272,6 @@ int arm7_cpu_device::detect_fault(int permission, int ap, int flags)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case 1 : // "Access allowed only in Supervisor mode"
|
|
||||||
{
|
|
||||||
if ((m_r[eCPSR] & MODE_FLAG) == eARM7_MODE_USER)
|
|
||||||
{
|
|
||||||
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;
|
break;
|
||||||
case 2 : // "Reserved - Reserved. Currently behaves like the no access mode"
|
case 2 : // "Reserved - Reserved. Currently behaves like the no access mode"
|
||||||
@ -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)
|
bool arm7_cpu_device::arm7_tlb_translate(offs_t &addr, int flags)
|
||||||
{
|
{
|
||||||
UINT32 desc_lvl1;
|
if (addr < 0x2000000)
|
||||||
UINT32 desc_lvl2 = 0;
|
|
||||||
UINT32 paddr, vaddr = addr;
|
|
||||||
UINT8 domain, permission;
|
|
||||||
|
|
||||||
if (vaddr < 32 * 1024 * 1024)
|
|
||||||
{
|
{
|
||||||
UINT32 pid = ((m_fcsePID >> 25) & 0x7F);
|
addr += m_pid_offset;
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
desc_lvl1 = arm7_tlb_get_first_level_descriptor( vaddr );
|
UINT32 desc_lvl1 = m_program->read_dword(m_tlb_base_mask | ((addr & COPRO_TLB_VADDR_FLTI_MASK) >> COPRO_TLB_VADDR_FLTI_MASK_SHIFT));
|
||||||
|
|
||||||
paddr = vaddr;
|
|
||||||
|
|
||||||
#if ARM7_MMU_ENABLE_HACK
|
#if ARM7_MMU_ENABLE_HACK
|
||||||
if ((m_r[eR15] == (m_mmu_enable_addr + 4)) || (m_r[eR15] == (m_mmu_enable_addr + 8)))
|
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 ) );
|
LOG( ( "ARM7: fetch flat, PC = %08x, vaddr = %08x\n", m_r[eR15], addr ) );
|
||||||
*addr = vaddr;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -325,132 +308,113 @@ bool arm7_cpu_device::arm7_tlb_translate(offs_t &addr, int flags)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
domain = (desc_lvl1 >> 5) & 0xF;
|
UINT8 tlb_type = desc_lvl1 & 3;
|
||||||
permission = (m_domainAccessControl >> (domain << 1)) & 3;
|
if (tlb_type == COPRO_TLB_SECTION_TABLE)
|
||||||
|
|
||||||
switch( desc_lvl1 & 3 )
|
|
||||||
{
|
|
||||||
case 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], vaddr ) );
|
|
||||||
m_faultStatus[0] = (5 << 0); // 5 = section translation fault
|
|
||||||
m_faultAddress = vaddr;
|
|
||||||
m_pendingAbtD = 1;
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
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
|
// Entry is a section
|
||||||
UINT8 ap = (desc_lvl1 >> 10) & 3;
|
int fault = detect_fault(desc_lvl1, (desc_lvl1 >> 10) & 3, flags);
|
||||||
int fault = detect_fault(permission, ap, flags);
|
|
||||||
if (fault == FAULT_NONE)
|
if (fault == FAULT_NONE)
|
||||||
{
|
{
|
||||||
paddr = ( desc_lvl1 & COPRO_TLB_SECTION_PAGE_MASK ) | ( vaddr & ~COPRO_TLB_SECTION_PAGE_MASK );
|
addr = ( desc_lvl1 & COPRO_TLB_SECTION_PAGE_MASK ) | ( addr & ~COPRO_TLB_SECTION_PAGE_MASK );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (flags & ARM7_TLB_ABORT_D)
|
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] ) );
|
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_faultStatus[0] = ((fault == FAULT_DOMAIN) ? (9 << 0) : (13 << 0)) | (domain << 4); // 9 = section domain fault, 13 = section permission fault
|
||||||
m_faultAddress = vaddr;
|
m_faultAddress = addr;
|
||||||
m_pendingAbtD = 1;
|
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",
|
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,
|
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) );
|
m_r[eCPSR] & MODE_FLAG, flags & ARM7_TLB_READ ? 1 : 0, flags & ARM7_TLB_WRITE ? 1 : 0) );
|
||||||
}
|
}
|
||||||
else if (flags & ARM7_TLB_ABORT_P)
|
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] ) );
|
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 = 1;
|
m_pendingAbtP = true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
else if (tlb_type == COPRO_TLB_UNMAPPED)
|
||||||
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 );
|
// 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
|
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]);
|
// Entry is the physical address of a coarse second-level table
|
||||||
}
|
UINT8 permission = (m_domainAccessControl >> ((desc_lvl1 >> 4) & 0x1e)) & 3;
|
||||||
break;
|
UINT32 desc_lvl2 = arm7_tlb_get_second_level_descriptor( (desc_lvl1 & 3) == COPRO_TLB_COARSE_TABLE ? TLB_COARSE : TLB_FINE, desc_lvl1, addr );
|
||||||
default:
|
if ((permission != 1) && (permission != 3))
|
||||||
// Entry is the physical address of a three-legged termite-eaten table
|
{
|
||||||
break;
|
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]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ( desc_lvl1 & 3 ) == COPRO_TLB_COARSE_TABLE || ( desc_lvl1 & 3 ) == COPRO_TLB_FINE_TABLE )
|
|
||||||
{
|
|
||||||
switch( desc_lvl2 & 3 )
|
switch( desc_lvl2 & 3 )
|
||||||
{
|
{
|
||||||
case COPRO_TLB_UNMAPPED:
|
case COPRO_TLB_UNMAPPED:
|
||||||
// Unmapped, generate a translation fault
|
// Unmapped, generate a translation fault
|
||||||
if (flags & ARM7_TLB_ABORT_D)
|
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_faultStatus[0] = (7 << 0) | (domain << 4); // 7 = page translation fault
|
||||||
m_faultAddress = vaddr;
|
m_faultAddress = addr;
|
||||||
m_pendingAbtD = 1;
|
m_pendingAbtD = true;
|
||||||
}
|
}
|
||||||
else if (flags & ARM7_TLB_ABORT_P)
|
else if (flags & ARM7_TLB_ABORT_P)
|
||||||
{
|
{
|
||||||
LOG( ( "ARM7: Translation fault on unmapped virtual address, vaddr = %08x, PC %08X\n", vaddr, m_r[eR15] ) );
|
LOG( ( "ARM7: Translation fault on unmapped virtual address, vaddr = %08x, PC %08X\n", addr, m_r[eR15] ) );
|
||||||
m_pendingAbtP = 1;
|
m_pendingAbtP = true;
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
case COPRO_TLB_LARGE_PAGE:
|
case COPRO_TLB_LARGE_PAGE:
|
||||||
// Large page descriptor
|
// 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;
|
break;
|
||||||
case COPRO_TLB_SMALL_PAGE:
|
case COPRO_TLB_SMALL_PAGE:
|
||||||
// Small page descriptor
|
// Small page descriptor
|
||||||
{
|
{
|
||||||
UINT8 ap = ((((desc_lvl2 >> 4) & 0xFF) >> (((vaddr >> 10) & 3) << 1)) & 3);
|
UINT8 ap = ((((desc_lvl2 >> 4) & 0xFF) >> (((addr >> 10) & 3) << 1)) & 3);
|
||||||
int fault = detect_fault(permission, ap, flags);
|
int fault = detect_fault(desc_lvl1, ap, flags);
|
||||||
if (fault == FAULT_NONE)
|
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
|
else
|
||||||
{
|
{
|
||||||
if (flags & ARM7_TLB_ABORT_D)
|
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
|
// 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_faultStatus[0] = ((fault == FAULT_DOMAIN) ? (11 << 0) : (15 << 0)) | (domain << 4); // 11 = page domain fault, 15 = page permission fault
|
||||||
m_faultAddress = vaddr;
|
m_faultAddress = addr;
|
||||||
m_pendingAbtD = 1;
|
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",
|
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) );
|
m_r[eCPSR] & MODE_FLAG, flags & ARM7_TLB_READ ? 1 : 0, flags & ARM7_TLB_WRITE ? 1 : 0) );
|
||||||
}
|
}
|
||||||
else if (flags & ARM7_TLB_ABORT_P)
|
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] ) );
|
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 = 1;
|
m_pendingAbtP = true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -460,13 +424,13 @@ bool arm7_cpu_device::arm7_tlb_translate(offs_t &addr, int flags)
|
|||||||
// Tiny page descriptor
|
// Tiny page descriptor
|
||||||
if( ( desc_lvl1 & 3 ) == 1 )
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
addr = paddr;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -501,6 +465,9 @@ void arm7_cpu_device::device_start()
|
|||||||
save_item(NAME(m_pendingAbtP));
|
save_item(NAME(m_pendingAbtP));
|
||||||
save_item(NAME(m_pendingUnd));
|
save_item(NAME(m_pendingUnd));
|
||||||
save_item(NAME(m_pendingSwi));
|
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;
|
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()
|
void arm7_cpu_device::device_reset()
|
||||||
{
|
{
|
||||||
memset(m_r, 0, sizeof(m_r));
|
memset(m_r, 0, sizeof(m_r));
|
||||||
m_pendingIrq = 0;
|
m_pendingIrq = false;
|
||||||
m_pendingFiq = 0;
|
m_pendingFiq = false;
|
||||||
m_pendingAbtD = 0;
|
m_pendingAbtD = false;
|
||||||
m_pendingAbtP = 0;
|
m_pendingAbtP = false;
|
||||||
m_pendingUnd = 0;
|
m_pendingUnd = false;
|
||||||
m_pendingSwi = 0;
|
m_pendingSwi = false;
|
||||||
|
m_pending_interrupt = false;
|
||||||
m_control = 0;
|
m_control = 0;
|
||||||
m_tlbBase = 0;
|
m_tlbBase = 0;
|
||||||
|
m_tlb_base_mask = 0;
|
||||||
m_faultStatus[0] = 0;
|
m_faultStatus[0] = 0;
|
||||||
m_faultStatus[1] = 0;
|
m_faultStatus[1] = 0;
|
||||||
m_faultAddress = 0;
|
m_faultAddress = 0;
|
||||||
m_fcsePID = 0;
|
m_fcsePID = 0;
|
||||||
|
m_pid_offset = 0;
|
||||||
m_domainAccessControl = 0;
|
m_domainAccessControl = 0;
|
||||||
|
memset(m_decoded_access_control, 0, sizeof(UINT8) * 16);
|
||||||
|
|
||||||
/* start up in SVC mode with interrupts disabled. */
|
/* start up in SVC mode with interrupts disabled. */
|
||||||
m_r[eCPSR] = I_MASK | F_MASK | 0x10;
|
m_r[eCPSR] = I_MASK | F_MASK | 0x10;
|
||||||
@ -677,6 +648,8 @@ void arm7_cpu_device::execute_run()
|
|||||||
insn = m_direct->read_dword(raddr);
|
insn = m_direct->read_dword(raddr);
|
||||||
|
|
||||||
/* process condition codes for this instruction */
|
/* process condition codes for this instruction */
|
||||||
|
if ((insn >> INSN_COND_SHIFT) != COND_AL)
|
||||||
|
{
|
||||||
switch (insn >> INSN_COND_SHIFT)
|
switch (insn >> INSN_COND_SHIFT)
|
||||||
{
|
{
|
||||||
case COND_EQ:
|
case COND_EQ:
|
||||||
@ -738,6 +711,7 @@ void arm7_cpu_device::execute_run()
|
|||||||
case COND_NV:
|
case COND_NV:
|
||||||
{ UNEXECUTED(); goto skip_exec; }
|
{ UNEXECUTED(); goto skip_exec; }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/*******************************************************************/
|
/*******************************************************************/
|
||||||
/* If we got here - condition satisfied, so decode the instruction */
|
/* 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) {
|
switch (irqline) {
|
||||||
case ARM7_IRQ_LINE: /* IRQ */
|
case ARM7_IRQ_LINE: /* IRQ */
|
||||||
m_pendingIrq = state & 1;
|
m_pendingIrq = state ? true : false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ARM7_FIRQ_LINE: /* FIRQ */
|
case ARM7_FIRQ_LINE: /* FIRQ */
|
||||||
m_pendingFiq = state & 1;
|
m_pendingFiq = state ? true : false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ARM7_ABORT_EXCEPTION:
|
case ARM7_ABORT_EXCEPTION:
|
||||||
m_pendingAbtD = state & 1;
|
m_pendingAbtD = state ? true : false;
|
||||||
break;
|
break;
|
||||||
case ARM7_ABORT_PREFETCH_EXCEPTION:
|
case ARM7_ABORT_PREFETCH_EXCEPTION:
|
||||||
m_pendingAbtP = state & 1;
|
m_pendingAbtP = state ? true : false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ARM7_UNDEFINE_EXCEPTION:
|
case ARM7_UNDEFINE_EXCEPTION:
|
||||||
m_pendingUnd = state & 1;
|
m_pendingUnd = state ? true : false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
update_irq_state();
|
||||||
arm7_check_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 )
|
WRITE32_MEMBER( arm7_cpu_device::arm7_do_callback )
|
||||||
{
|
{
|
||||||
m_pendingUnd = 1;
|
m_pendingUnd = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
READ32_MEMBER( arm7_cpu_device::arm7_rt_r_callback )
|
READ32_MEMBER( arm7_cpu_device::arm7_rt_r_callback )
|
||||||
@ -851,7 +826,7 @@ READ32_MEMBER( arm7_cpu_device::arm7_rt_r_callback )
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG( ("ARM7: Unhandled coprocessor %d (archFlags %x)\n", cpnum, m_archFlags) );
|
LOG( ("ARM7: Unhandled coprocessor %d (archFlags %x)\n", cpnum, m_archFlags) );
|
||||||
m_pendingUnd = 1;
|
m_pendingUnd = true;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -994,7 +969,7 @@ WRITE32_MEMBER( arm7_cpu_device::arm7_rt_w_callback )
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG( ("ARM7: Unhandled coprocessor %d\n", cpnum) );
|
LOG( ("ARM7: Unhandled coprocessor %d\n", cpnum) );
|
||||||
m_pendingUnd = 1;
|
m_pendingUnd = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1039,10 +1014,15 @@ WRITE32_MEMBER( arm7_cpu_device::arm7_rt_w_callback )
|
|||||||
case 2: // Translation Table Base
|
case 2: // Translation Table Base
|
||||||
LOG( ( "arm7_rt_w_callback TLB Base = %08x (%d) (%d)\n", data, op2, op3 ) );
|
LOG( ( "arm7_rt_w_callback TLB Base = %08x (%d) (%d)\n", data, op2, op3 ) );
|
||||||
COPRO_TLB_BASE = data;
|
COPRO_TLB_BASE = data;
|
||||||
|
m_tlb_base_mask = data & COPRO_TLB_BASE_MASK;
|
||||||
break;
|
break;
|
||||||
case 3: // Domain Access Control
|
case 3: // Domain Access Control
|
||||||
LOG( ( "arm7_rt_w_callback Domain Access Control = %08x (%d) (%d)\n", data, op2, op3 ) );
|
LOG( ( "arm7_rt_w_callback Domain Access Control = %08x (%d) (%d)\n", data, op2, op3 ) );
|
||||||
COPRO_DOMAIN_ACCESS_CONTROL = data;
|
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;
|
break;
|
||||||
case 5: // Fault Status
|
case 5: // Fault Status
|
||||||
LOG( ( "arm7_rt_w_callback Fault Status = %08x (%d) (%d)\n", data, op2, op3 ) );
|
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)
|
case 13: // Write Process ID (PID)
|
||||||
LOG( ( "arm7_rt_w_callback Write PID = %08x (%d) (%d)\n", data, op2, op3 ) );
|
LOG( ( "arm7_rt_w_callback Write PID = %08x (%d) (%d)\n", data, op2, op3 ) );
|
||||||
COPRO_FCSE_PID = data;
|
COPRO_FCSE_PID = data;
|
||||||
|
m_pid_offset = (((COPRO_FCSE_PID >> 25) & 0x7F)) * 0x2000000;
|
||||||
break;
|
break;
|
||||||
case 14: // Write Breakpoint
|
case 14: // Write Breakpoint
|
||||||
LOG( ( "arm7_rt_w_callback Write Breakpoint = %08x (%d) (%d)\n", data, op2, op3 ) );
|
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
|
else
|
||||||
{
|
{
|
||||||
m_pendingUnd = 1;
|
m_pendingUnd = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1102,7 +1083,7 @@ void arm7_cpu_device::arm7_dt_w_callback(UINT32 insn, UINT32 *prn)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_pendingUnd = 1;
|
m_pendingUnd = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,12 +81,13 @@ protected:
|
|||||||
address_space_config m_program_config;
|
address_space_config m_program_config;
|
||||||
|
|
||||||
UINT32 m_r[/*NUM_REGS*/37];
|
UINT32 m_r[/*NUM_REGS*/37];
|
||||||
UINT32 m_pendingIrq;
|
bool m_pendingIrq;
|
||||||
UINT32 m_pendingFiq;
|
bool m_pendingFiq;
|
||||||
UINT32 m_pendingAbtD;
|
bool m_pendingAbtD;
|
||||||
UINT32 m_pendingAbtP;
|
bool m_pendingAbtP;
|
||||||
UINT32 m_pendingUnd;
|
bool m_pendingUnd;
|
||||||
UINT32 m_pendingSwi;
|
bool m_pendingSwi;
|
||||||
|
bool m_pending_interrupt;
|
||||||
int m_icount;
|
int m_icount;
|
||||||
endianness_t m_endian;
|
endianness_t m_endian;
|
||||||
address_space *m_program;
|
address_space *m_program;
|
||||||
@ -95,10 +96,13 @@ protected:
|
|||||||
/* Coprocessor Registers */
|
/* Coprocessor Registers */
|
||||||
UINT32 m_control;
|
UINT32 m_control;
|
||||||
UINT32 m_tlbBase;
|
UINT32 m_tlbBase;
|
||||||
|
UINT32 m_tlb_base_mask;
|
||||||
UINT32 m_faultStatus[2];
|
UINT32 m_faultStatus[2];
|
||||||
UINT32 m_faultAddress;
|
UINT32 m_faultAddress;
|
||||||
UINT32 m_fcsePID;
|
UINT32 m_fcsePID;
|
||||||
|
UINT32 m_pid_offset;
|
||||||
UINT32 m_domainAccessControl;
|
UINT32 m_domainAccessControl;
|
||||||
|
UINT8 m_decoded_access_control[16];
|
||||||
|
|
||||||
UINT8 m_archRev; // ARM architecture revision (3, 4, and 5 are valid)
|
UINT8 m_archRev; // ARM architecture revision (3, 4, and 5 are valid)
|
||||||
UINT8 m_archFlags; // architecture flags
|
UINT8 m_archFlags; // architecture flags
|
||||||
@ -141,10 +145,10 @@ protected:
|
|||||||
void arm7ops_f(UINT32 insn);
|
void arm7ops_f(UINT32 insn);
|
||||||
void set_cpsr(UINT32 val);
|
void set_cpsr(UINT32 val);
|
||||||
bool arm7_tlb_translate(offs_t &addr, int flags);
|
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 );
|
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 arm7_check_irq_state();
|
||||||
|
void update_irq_state();
|
||||||
void arm7_cpu_write32(UINT32 addr, UINT32 data);
|
void arm7_cpu_write32(UINT32 addr, UINT32 data);
|
||||||
void arm7_cpu_write16(UINT32 addr, UINT16 data);
|
void arm7_cpu_write16(UINT32 addr, UINT16 data);
|
||||||
void arm7_cpu_write8(UINT32 addr, UINT8 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_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 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 load_fast_iregs(drcuml_block *block);
|
||||||
void save_fast_iregs(drcuml_block *block);
|
void save_fast_iregs(drcuml_block *block);
|
||||||
void arm7_drc_init();
|
void arm7_drc_init();
|
||||||
|
@ -165,12 +165,13 @@ struct arm7imp_state;
|
|||||||
struct arm_state
|
struct arm_state
|
||||||
{
|
{
|
||||||
UINT32 m_r[NUM_REGS];
|
UINT32 m_r[NUM_REGS];
|
||||||
UINT32 m_pendingIrq;
|
bool m_pendingIrq;
|
||||||
UINT32 m_pendingFiq;
|
bool m_pendingFiq;
|
||||||
UINT32 m_pendingAbtD;
|
bool m_pendingAbtD;
|
||||||
UINT32 m_pendingAbtP;
|
bool m_pendingAbtP;
|
||||||
UINT32 m_pendingUnd;
|
bool m_pendingUnd;
|
||||||
UINT32 m_pendingSwi;
|
bool m_pendingSwi;
|
||||||
|
bool m_pending_interrupt;
|
||||||
int m_icount;
|
int m_icount;
|
||||||
endianness_t m_endian;
|
endianness_t m_endian;
|
||||||
address_space *m_program;
|
address_space *m_program;
|
||||||
@ -179,10 +180,12 @@ struct arm_state
|
|||||||
/* Coprocessor Registers */
|
/* Coprocessor Registers */
|
||||||
UINT32 m_control;
|
UINT32 m_control;
|
||||||
UINT32 m_tlbBase;
|
UINT32 m_tlbBase;
|
||||||
|
UINT32 m_tlb_base_mask;
|
||||||
UINT32 m_faultStatus[2];
|
UINT32 m_faultStatus[2];
|
||||||
UINT32 m_faultAddress;
|
UINT32 m_faultAddress;
|
||||||
UINT32 m_fcsePID;
|
UINT32 m_fcsePID;
|
||||||
UINT32 m_domainAccessControl;
|
UINT32 m_domainAccessControl;
|
||||||
|
UINT32 m_decoded_access_control[16];
|
||||||
|
|
||||||
UINT8 m_archRev; // ARM architecture revision (3, 4, and 5 are valid)
|
UINT8 m_archRev; // ARM architecture revision (3, 4, and 5 are valid)
|
||||||
UINT8 m_archFlags; // architecture flags
|
UINT8 m_archFlags; // architecture flags
|
||||||
@ -488,7 +491,6 @@ enum
|
|||||||
#define R15 m_r[eR15]
|
#define R15 m_r[eR15]
|
||||||
#define SPSR 17 // SPSR is always the 18th register in our 0 based array sRegisterTable[][18]
|
#define SPSR 17 // SPSR is always the 18th register in our 0 based array sRegisterTable[][18]
|
||||||
#define GET_CPSR m_r[eCPSR]
|
#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 MODE_FLAG 0xF // Mode bits are 4:0 of CPSR, but we ignore bit 4.
|
||||||
#define GET_MODE (GET_CPSR & MODE_FLAG)
|
#define GET_MODE (GET_CPSR & MODE_FLAG)
|
||||||
#define SIGN_BIT ((UINT32)(1 << 31))
|
#define SIGN_BIT ((UINT32)(1 << 31))
|
||||||
@ -508,14 +510,6 @@ enum
|
|||||||
#define ARM7_TLB_READ (1 << 2)
|
#define ARM7_TLB_READ (1 << 2)
|
||||||
#define ARM7_TLB_WRITE (1 << 3)
|
#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 */
|
/* ARM flavors */
|
||||||
enum arm_flavor
|
enum arm_flavor
|
||||||
{
|
{
|
||||||
|
@ -84,10 +84,18 @@ static const char *GetModeText(int cpsr)
|
|||||||
* Main CPU Funcs
|
* 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
|
// CPU CHECK IRQ STATE
|
||||||
// Note: couldn't find any exact cycle counts for most of these exceptions
|
// Note: couldn't find any exact cycle counts for most of these exceptions
|
||||||
void arm7_cpu_device::arm7_check_irq_state()
|
void arm7_cpu_device::arm7_check_irq_state()
|
||||||
{
|
{
|
||||||
|
if (!m_pending_interrupt)
|
||||||
|
return;
|
||||||
|
|
||||||
UINT32 cpsr = m_r[eCPSR]; /* save current CPSR */
|
UINT32 cpsr = m_r[eCPSR]; /* save current CPSR */
|
||||||
UINT32 pc = m_r[eR15] + 4; /* save old pc (already incremented in pipeline) */;
|
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
|
// Data Abort
|
||||||
if (m_pendingAbtD) {
|
if (m_pendingAbtD)
|
||||||
|
{
|
||||||
if (MODE26) fatalerror( "pendingAbtD (todo)\n");
|
if (MODE26) fatalerror( "pendingAbtD (todo)\n");
|
||||||
SwitchMode(eARM7_MODE_ABT); /* Set ABT mode so PC is saved to correct R14 bank */
|
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 */
|
SetRegister(14, pc - 8 + 8); /* save PC to R14 */
|
||||||
SET_REGISTER(SPSR, cpsr); /* Save current CPSR */
|
SetRegister(SPSR, cpsr); /* Save current CPSR */
|
||||||
SET_CPSR(GET_CPSR | I_MASK); /* Mask IRQ */
|
set_cpsr(GET_CPSR | I_MASK); /* Mask IRQ */
|
||||||
SET_CPSR(GET_CPSR & ~T_MASK);
|
set_cpsr(GET_CPSR & ~T_MASK);
|
||||||
R15 = 0x10; /* IRQ Vector address */
|
R15 = 0x10; /* IRQ Vector address */
|
||||||
if ((COPRO_CTRL & COPRO_CTRL_MMU_EN) && (COPRO_CTRL & COPRO_CTRL_INTVEC_ADJUST)) R15 |= 0xFFFF0000;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIQ
|
// FIQ
|
||||||
if (m_pendingFiq && (cpsr & F_MASK) == 0) {
|
if (m_pendingFiq && (cpsr & F_MASK) == 0)
|
||||||
|
{
|
||||||
if (MODE26) fatalerror( "pendingFiq (todo)\n");
|
if (MODE26) fatalerror( "pendingFiq (todo)\n");
|
||||||
SwitchMode(eARM7_MODE_FIQ); /* Set FIQ mode so PC is saved to correct R14 bank */
|
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 */
|
SetRegister(14, pc - 4 + 4); /* save PC to R14 */
|
||||||
SET_REGISTER(SPSR, cpsr); /* Save current CPSR */
|
SetRegister(SPSR, cpsr); /* Save current CPSR */
|
||||||
SET_CPSR(GET_CPSR | I_MASK | F_MASK); /* Mask both IRQ & FIQ */
|
set_cpsr(GET_CPSR | I_MASK | F_MASK); /* Mask both IRQ & FIQ */
|
||||||
SET_CPSR(GET_CPSR & ~T_MASK);
|
set_cpsr(GET_CPSR & ~T_MASK);
|
||||||
R15 = 0x1c; /* IRQ Vector address */
|
R15 = 0x1c; /* IRQ Vector address */
|
||||||
if ((COPRO_CTRL & COPRO_CTRL_MMU_EN) && (COPRO_CTRL & COPRO_CTRL_INTVEC_ADJUST)) R15 |= 0xFFFF0000;
|
if ((COPRO_CTRL & COPRO_CTRL_MMU_EN) && (COPRO_CTRL & COPRO_CTRL_INTVEC_ADJUST)) R15 |= 0xFFFF0000;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// IRQ
|
// 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 */
|
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)
|
if (MODE32)
|
||||||
{
|
{
|
||||||
SET_REGISTER(SPSR, cpsr); /* Save current CPSR */
|
SetRegister(SPSR, cpsr); /* Save current CPSR */
|
||||||
SET_CPSR(GET_CPSR | I_MASK); /* Mask IRQ */
|
set_cpsr(GET_CPSR | I_MASK); /* Mask IRQ */
|
||||||
SET_CPSR(GET_CPSR & ~T_MASK);
|
set_cpsr(GET_CPSR & ~T_MASK);
|
||||||
R15 = 0x18; /* IRQ Vector address */
|
R15 = 0x18; /* IRQ Vector address */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -145,65 +157,70 @@ void arm7_cpu_device::arm7_check_irq_state()
|
|||||||
UINT32 temp;
|
UINT32 temp;
|
||||||
R15 = (pc & 0xF4000000) /* N Z C V F */ | 0x18 | 0x00000002 /* IRQ */ | 0x08000000 /* I */;
|
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 */;
|
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;
|
if ((COPRO_CTRL & COPRO_CTRL_MMU_EN) && (COPRO_CTRL & COPRO_CTRL_INTVEC_ADJUST)) R15 |= 0xFFFF0000;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prefetch Abort
|
// Prefetch Abort
|
||||||
if (m_pendingAbtP) {
|
if (m_pendingAbtP)
|
||||||
|
{
|
||||||
if (MODE26) fatalerror( "pendingAbtP (todo)\n");
|
if (MODE26) fatalerror( "pendingAbtP (todo)\n");
|
||||||
SwitchMode(eARM7_MODE_ABT); /* Set ABT mode so PC is saved to correct R14 bank */
|
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 */
|
SetRegister(14, pc - 4 + 4); /* save PC to R14 */
|
||||||
SET_REGISTER(SPSR, cpsr); /* Save current CPSR */
|
SetRegister(SPSR, cpsr); /* Save current CPSR */
|
||||||
SET_CPSR(GET_CPSR | I_MASK); /* Mask IRQ */
|
set_cpsr(GET_CPSR | I_MASK); /* Mask IRQ */
|
||||||
SET_CPSR(GET_CPSR & ~T_MASK);
|
set_cpsr(GET_CPSR & ~T_MASK);
|
||||||
R15 = 0x0c; /* IRQ Vector address */
|
R15 = 0x0c; /* IRQ Vector address */
|
||||||
if ((COPRO_CTRL & COPRO_CTRL_MMU_EN) && (COPRO_CTRL & COPRO_CTRL_INTVEC_ADJUST)) R15 |= 0xFFFF0000;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Undefined instruction
|
// Undefined instruction
|
||||||
if (m_pendingUnd) {
|
if (m_pendingUnd)
|
||||||
|
{
|
||||||
if (MODE26) fatalerror( "pendingUnd (todo)\n");
|
if (MODE26) fatalerror( "pendingUnd (todo)\n");
|
||||||
SwitchMode(eARM7_MODE_UND); /* Set UND mode so PC is saved to correct R14 bank */
|
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?)
|
// compensate for prefetch (should this also be done for normal IRQ?)
|
||||||
if (T_IS_SET(GET_CPSR))
|
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
|
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 */
|
SetRegister(SPSR, cpsr); /* Save current CPSR */
|
||||||
SET_CPSR(GET_CPSR | I_MASK); /* Mask IRQ */
|
set_cpsr(GET_CPSR | I_MASK); /* Mask IRQ */
|
||||||
SET_CPSR(GET_CPSR & ~T_MASK);
|
set_cpsr(GET_CPSR & ~T_MASK);
|
||||||
R15 = 0x04; /* IRQ Vector address */
|
R15 = 0x04; /* IRQ Vector address */
|
||||||
if ((COPRO_CTRL & COPRO_CTRL_MMU_EN) && (COPRO_CTRL & COPRO_CTRL_INTVEC_ADJUST)) R15 |= 0xFFFF0000;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Software Interrupt
|
// Software Interrupt
|
||||||
if (m_pendingSwi) {
|
if (m_pendingSwi)
|
||||||
|
{
|
||||||
SwitchMode(eARM7_MODE_SVC); /* Set SVC mode so PC is saved to correct R14 bank */
|
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?)
|
// compensate for prefetch (should this also be done for normal IRQ?)
|
||||||
if (T_IS_SET(GET_CPSR))
|
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
|
else
|
||||||
{
|
{
|
||||||
SET_REGISTER(14, pc - 4 + 4); /* save PC to R14 */
|
SetRegister(14, pc - 4 + 4); /* save PC to R14 */
|
||||||
}
|
}
|
||||||
if (MODE32)
|
if (MODE32)
|
||||||
{
|
{
|
||||||
SET_REGISTER(SPSR, cpsr); /* Save current CPSR */
|
SetRegister(SPSR, cpsr); /* Save current CPSR */
|
||||||
SET_CPSR(GET_CPSR | I_MASK); /* Mask IRQ */
|
set_cpsr(GET_CPSR | I_MASK); /* Mask IRQ */
|
||||||
SET_CPSR(GET_CPSR & ~T_MASK); /* Go to ARM mode */
|
set_cpsr(GET_CPSR & ~T_MASK); /* Go to ARM mode */
|
||||||
R15 = 0x08; /* Jump to the SWI vector */
|
R15 = 0x08; /* Jump to the SWI vector */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -211,10 +228,11 @@ void arm7_cpu_device::arm7_check_irq_state()
|
|||||||
UINT32 temp;
|
UINT32 temp;
|
||||||
R15 = (pc & 0xF4000000) /* N Z C V F */ | 0x08 | 0x00000003 /* SVC */ | 0x08000000 /* I */;
|
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 */;
|
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;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -547,8 +547,8 @@ void arm7_cpu_device::static_generate_check_irq()
|
|||||||
UML_JMPc(block, uml::COND_Z, nodabt = label++); // jmpz nodabt
|
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_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(&GetRegister(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(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_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_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)
|
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_TEST(block, uml::mem(&GET_CPSR), F_MASK); // test CPSR, F_MASK
|
||||||
UML_JMPc(block, uml::COND_Z, nofiq); // jmpz nofiq
|
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(&GetRegister(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(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_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_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)
|
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_TEST(block, uml::mem(&GET_CPSR), I_MASK); // test CPSR, I_MASK
|
||||||
UML_JMPc(block, uml::COND_Z, noirq); // jmpz noirq
|
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_TEST(block, uml::mem(&GET_CPSR), SR_MODE32); // test CPSR, MODE32
|
||||||
UML_JMPc(block, uml::COND_NZ, irq32 = label++); // jmpnz irq32
|
UML_JMPc(block, uml::COND_NZ, irq32 = label++); // jmpnz irq32
|
||||||
UML_AND(block, uml::I1, uml::I0, 0xf4000000); // and i1, i0, 0xf4000000
|
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_JMP(block, irqadjust); // jmp irqadjust
|
||||||
|
|
||||||
UML_LABEL(block, irq32); // irq32:
|
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_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_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)
|
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_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_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(&GetRegister(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(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_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_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)
|
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_MOV(block, uml::I1, (UINT64)-4); // mov i1, -4
|
||||||
UML_TEST(block, uml::mem(&GET_CPSR), T_MASK); // test CPSR, T_MASK
|
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_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_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_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_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)
|
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_MOV(block, uml::I1, (UINT64)-4); // mov i1, -4
|
||||||
UML_TEST(block, uml::mem(&GET_CPSR), T_MASK); // test CPSR, T_MASK
|
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_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_TEST(block, uml::mem(&GET_CPSR), SR_MODE32); // test CPSR, MODE32
|
||||||
UML_JMPc(block, uml::COND_NZ, swi32 = label++); // jmpnz swi32
|
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_JMP(block, irqadjust); // jmp irqadjust
|
||||||
|
|
||||||
UML_LABEL(block, swi32); // irq32:
|
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_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_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)
|
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
|
else if ((insn & 0x0ff00090) == 0x01600080) // SMULxy - v5
|
||||||
{
|
{
|
||||||
INT32 src1 = GET_REGISTER(insn&0xf);
|
INT32 src1 = GetRegister(insn&0xf);
|
||||||
INT32 src2 = GET_REGISTER((insn>>8)&0xf);
|
INT32 src2 = GetRegister((insn>>8)&0xf);
|
||||||
INT32 res;
|
INT32 res;
|
||||||
|
|
||||||
// select top and bottom halves of src1/src2 and sign extend if necessary
|
// 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;
|
res = src1 * src2;
|
||||||
SET_REGISTER((insn>>16)&0xf, res);
|
SetRegister((insn>>16)&0xf, res);
|
||||||
R15 += 4;
|
R15 += 4;
|
||||||
}
|
}
|
||||||
else if ((insn & 0x0ff000b0) == 0x012000a0) // SMULWy - v5
|
else if ((insn & 0x0ff000b0) == 0x012000a0) // SMULWy - v5
|
||||||
{
|
{
|
||||||
INT32 src1 = GET_REGISTER(insn&0xf);
|
INT32 src1 = GetRegister(insn&0xf);
|
||||||
INT32 src2 = GET_REGISTER((insn>>8)&0xf);
|
INT32 src2 = GetRegister((insn>>8)&0xf);
|
||||||
INT64 res;
|
INT64 res;
|
||||||
|
|
||||||
if (insn & 0x40)
|
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 = (INT64)src1 * (INT64)src2;
|
||||||
res >>= 16;
|
res >>= 16;
|
||||||
SET_REGISTER((insn>>16)&0xf, (UINT32)res);
|
SetRegister((insn>>16)&0xf, (UINT32)res);
|
||||||
}
|
}
|
||||||
else if ((insn & 0x0ff000b0) == 0x01200080) // SMLAWy - v5
|
else if ((insn & 0x0ff000b0) == 0x01200080) // SMLAWy - v5
|
||||||
{
|
{
|
||||||
INT32 src1 = GET_REGISTER(insn&0xf);
|
INT32 src1 = GetRegister(insn&0xf);
|
||||||
INT32 src2 = GET_REGISTER((insn>>8)&0xf);
|
INT32 src2 = GetRegister((insn>>8)&0xf);
|
||||||
INT32 src3 = GET_REGISTER((insn>>12)&0xf);
|
INT32 src3 = GetRegister((insn>>12)&0xf);
|
||||||
INT64 res;
|
INT64 res;
|
||||||
|
|
||||||
if (insn & 0x40)
|
if (insn & 0x40)
|
||||||
@ -1592,7 +1592,7 @@ bool arm7_cpu_device::drcarm7ops_0123(drcuml_block *block, compiler_state *compi
|
|||||||
src3 += (INT32)res;
|
src3 += (INT32)res;
|
||||||
|
|
||||||
// write the result back
|
// write the result back
|
||||||
SET_REGISTER((insn>>16)&0xf, (UINT32)res);
|
SetRegister((insn>>16)&0xf, (UINT32)res);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* Multiply OR Swap OR Half Word Data Transfer */
|
/* Multiply OR Swap OR Half Word Data Transfer */
|
||||||
|
@ -29,14 +29,14 @@
|
|||||||
/* Set NZCV flags for ADDS / SUBS */
|
/* Set NZCV flags for ADDS / SUBS */
|
||||||
#define HandleALUAddFlags(rd, rn, op2) \
|
#define HandleALUAddFlags(rd, rn, op2) \
|
||||||
if (insn & INSN_S) \
|
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) \
|
| (((!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) \
|
| (((IsNeg(rn) & IsNeg(op2)) | (IsNeg(rn) & IsPos(rd)) | (IsNeg(op2) & IsPos(rd))) ? C_MASK : 0) \
|
||||||
| HandleALUNZFlags(rd))); \
|
| HandleALUNZFlags(rd))); \
|
||||||
R15 += 4;
|
R15 += 4;
|
||||||
|
|
||||||
#define HandleThumbALUAddFlags(rd, rn, op2) \
|
#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) \
|
| (((!THUMB_SIGN_BITS_DIFFER(rn, op2)) && THUMB_SIGN_BITS_DIFFER(rn, rd)) << V_BIT) \
|
||||||
| (((~(rn)) < (op2)) << C_BIT) \
|
| (((~(rn)) < (op2)) << C_BIT) \
|
||||||
| HandleALUNZFlags(rd))); \
|
| HandleALUNZFlags(rd))); \
|
||||||
@ -62,14 +62,14 @@
|
|||||||
|
|
||||||
#define HandleALUSubFlags(rd, rn, op2) \
|
#define HandleALUSubFlags(rd, rn, op2) \
|
||||||
if (insn & INSN_S) \
|
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) \
|
| ((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) \
|
| (((IsNeg(rn) & IsPos(op2)) | (IsNeg(rn) & IsPos(rd)) | (IsPos(op2) & IsPos(rd))) ? C_MASK : 0) \
|
||||||
| HandleALUNZFlags(rd))); \
|
| HandleALUNZFlags(rd))); \
|
||||||
R15 += 4;
|
R15 += 4;
|
||||||
|
|
||||||
#define HandleThumbALUSubFlags(rd, rn, op2) \
|
#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) \
|
| ((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) \
|
| (((IsNeg(rn) & IsPos(op2)) | (IsNeg(rn) & IsPos(rd)) | (IsPos(op2) & IsPos(rd))) ? C_MASK : 0) \
|
||||||
| HandleALUNZFlags(rd))); \
|
| HandleALUNZFlags(rd))); \
|
||||||
@ -122,13 +122,13 @@
|
|||||||
|
|
||||||
#define HandleALULogicalFlags(rd, sc) \
|
#define HandleALULogicalFlags(rd, sc) \
|
||||||
if (insn & INSN_S) \
|
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) \
|
| HandleALUNZFlags(rd) \
|
||||||
| (((sc) != 0) << C_BIT))); \
|
| (((sc) != 0) << C_BIT))); \
|
||||||
R15 += 4;
|
R15 += 4;
|
||||||
|
|
||||||
#define DRC_RD uml::mem(&GET_REGISTER(rd))
|
#define DRC_RD uml::mem(&GetRegister(rd))
|
||||||
#define DRC_RS uml::mem(&GET_REGISTER(rs))
|
#define DRC_RS uml::mem(&GetRegister(rs))
|
||||||
#define DRC_CPSR uml::mem(&GET_CPSR)
|
#define DRC_CPSR uml::mem(&GET_CPSR)
|
||||||
#define DRC_PC uml::mem(&R15)
|
#define DRC_PC uml::mem(&R15)
|
||||||
#define DRC_REG(i) uml::mem(&m_r[(i)])
|
#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.
|
// 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 GetRegister(rIndex) m_r[m_reg_group[rIndex]]
|
||||||
#define SetRegister(rIndex, value) m_r[sRegisterTable[GET_MODE][rIndex]] = value
|
#define SetRegister(rIndex, value) m_r[m_reg_group[rIndex]] = value
|
||||||
|
|
||||||
#define GetModeRegister(mode, rIndex) m_r[sRegisterTable[mode][rIndex]]
|
#define GetModeRegister(mode, rIndex) m_r[sRegisterTable[mode][rIndex]]
|
||||||
#define SetModeRegister(mode, rIndex, value) m_r[sRegisterTable[mode][rIndex]] = value
|
#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
|
if (res > 2147483647) // INT32_MAX
|
||||||
{ // overflow high? saturate and set Q
|
{ // overflow high? saturate and set Q
|
||||||
res = 2147483647;
|
res = 2147483647;
|
||||||
SET_CPSR(GET_CPSR | Q_MASK);
|
set_cpsr(GET_CPSR | Q_MASK);
|
||||||
}
|
}
|
||||||
else if (res < (-2147483647-1)) // INT32_MIN
|
else if (res < (-2147483647-1)) // INT32_MIN
|
||||||
{ // overflow low? saturate and set Q
|
{ // overflow low? saturate and set Q
|
||||||
res = (-2147483647-1);
|
res = (-2147483647-1);
|
||||||
SET_CPSR(GET_CPSR | Q_MASK);
|
set_cpsr(GET_CPSR | Q_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
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 arm7_cpu_device::decodeShift(UINT32 insn, UINT32 *pCarry)
|
||||||
{
|
{
|
||||||
UINT32 k = (insn & INSN_OP2_SHIFT) >> INSN_OP2_SHIFT_SHIFT; // Bits 11-7
|
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;
|
UINT32 t = (insn & INSN_OP2_SHIFT_TYPE) >> INSN_OP2_SHIFT_TYPE_SHIFT;
|
||||||
|
|
||||||
if ((insn & INSN_OP2_RM) == 0xf) {
|
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 */
|
/* All shift types ending in 1 are Rk, not #k */
|
||||||
if (t & 1)
|
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 ARM7_DEBUG_CORE
|
||||||
if ((insn & 0x80) == 0x80)
|
if ((insn & 0x80) == 0x80)
|
||||||
LOG(("%08x: RegShift ERROR (p36)\n", R15));
|
LOG(("%08x: RegShift ERROR (p36)\n", R15));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// see p35 for check on this
|
// 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
|
// 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 */
|
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 ((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);
|
data = READ32(rbv += 4);
|
||||||
if (i == 15) {
|
if (i == 15)
|
||||||
|
{
|
||||||
if (s) /* Pull full contents from stack */
|
if (s) /* Pull full contents from stack */
|
||||||
SET_MODE_REGISTER(mode, 15, data);
|
SetModeRegister(mode, 15, data);
|
||||||
else /* Pull only address, preserve mode & status flags */
|
else if (MODE32) /* Pull only address, preserve mode & status flags */
|
||||||
if (MODE32)
|
SetModeRegister(mode, 15, data);
|
||||||
SET_MODE_REGISTER(mode, 15, data);
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SET_MODE_REGISTER(mode, 15, (GET_MODE_REGISTER(mode, 15) & ~0x03FFFFFC) | (data & 0x03FFFFFC));
|
SetModeRegister(mode, 15, (GetModeRegister(mode, 15) & ~0x03FFFFFC) | (data & 0x03FFFFFC));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetModeRegister(mode, i, data);
|
||||||
}
|
}
|
||||||
} else
|
|
||||||
SET_MODE_REGISTER(mode, i, data);
|
|
||||||
}
|
}
|
||||||
result++;
|
result++;
|
||||||
}
|
}
|
||||||
@ -210,22 +213,24 @@ int arm7_cpu_device::loadDec(UINT32 pat, UINT32 rbv, UINT32 s, int mode)
|
|||||||
{
|
{
|
||||||
if ((pat >> i) & 1)
|
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);
|
data = READ32(rbv -= 4);
|
||||||
if (i == 15) {
|
if (i == 15)
|
||||||
|
{
|
||||||
if (s) /* Pull full contents from stack */
|
if (s) /* Pull full contents from stack */
|
||||||
SET_MODE_REGISTER(mode, 15, data);
|
SetModeRegister(mode, 15, data);
|
||||||
else /* Pull only address, preserve mode & status flags */
|
else if (MODE32) /* Pull only address, preserve mode & status flags */
|
||||||
if (MODE32)
|
SetModeRegister(mode, 15, data);
|
||||||
SET_MODE_REGISTER(mode, 15, data);
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SET_MODE_REGISTER(mode, 15, (GET_MODE_REGISTER(mode, 15) & ~0x03FFFFFC) | (data & 0x03FFFFFC));
|
SetModeRegister(mode, 15, (GetModeRegister(mode, 15) & ~0x03FFFFFC) | (data & 0x03FFFFFC));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
SET_MODE_REGISTER(mode, i, data);
|
{
|
||||||
|
SetModeRegister(mode, i, data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
result++;
|
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 */
|
if (i == 15) /* R15 is plus 12 from address of STM */
|
||||||
LOG(("%08x: StoreInc on R15\n", R15));
|
LOG(("%08x: StoreInc on R15\n", R15));
|
||||||
#endif
|
#endif
|
||||||
WRITE32(rbv += 4, GET_MODE_REGISTER(mode, i));
|
WRITE32(rbv += 4, GetModeRegister(mode, i));
|
||||||
result++;
|
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 */
|
if (i == 15) /* R15 is plus 12 from address of STM */
|
||||||
LOG(("%08x: StoreDec on R15\n", R15));
|
LOG(("%08x: StoreDec on R15\n", R15));
|
||||||
#endif
|
#endif
|
||||||
WRITE32(rbv + (cnt * 4), GET_MODE_REGISTER(mode, i));
|
WRITE32(rbv + (cnt * 4), GetModeRegister(mode, i));
|
||||||
cnt++;
|
cnt++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -308,15 +313,15 @@ void arm7_cpu_device::HandleCoProcRT(UINT32 insn)
|
|||||||
if (insn & 0x00100000) // Bit 20 = Load or Store
|
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
|
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
|
// Store (MCR) data from ARM7 to Co-Proc register
|
||||||
else
|
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)
|
void arm7_cpu_device::HandleCoProcDT(UINT32 insn)
|
||||||
{
|
{
|
||||||
UINT32 rn = (insn >> 16) & 0xf;
|
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 ornv = rnv; // Keep value of Rn
|
||||||
UINT32 off = (insn & 0xff) << 2; // Offset is << 2 according to manual
|
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
|
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 writeback not used - ensure the original value of RN is restored in case co-proc callback changed value
|
||||||
if ((insn & 0x200000) == 0)
|
if ((insn & 0x200000) == 0)
|
||||||
SET_REGISTER(rn, ornv);
|
SetRegister(rn, ornv);
|
||||||
}
|
}
|
||||||
|
|
||||||
void arm7_cpu_device::HandleBranch(UINT32 insn)
|
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 */
|
/* Save PC into LR if this is a branch with link */
|
||||||
if (insn & INSN_BL)
|
if (insn & INSN_BL)
|
||||||
{
|
{
|
||||||
SET_REGISTER(14, R15 + 4);
|
SetRegister(14, R15 + 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sign-extend the 24-bit offset in our calculations */
|
/* 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 (insn & INSN_SDT_U)
|
||||||
{
|
{
|
||||||
if ((MODE32) || (rn != eR15))
|
if ((MODE32) || (rn != eR15))
|
||||||
rnv = (GET_REGISTER(rn) + off);
|
rnv = (GetRegister(rn) + off);
|
||||||
else
|
else
|
||||||
rnv = (GET_PC + off);
|
rnv = (GET_PC + off);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((MODE32) || (rn != eR15))
|
if ((MODE32) || (rn != eR15))
|
||||||
rnv = (GET_REGISTER(rn) - off);
|
rnv = (GetRegister(rn) - off);
|
||||||
else
|
else
|
||||||
rnv = (GET_PC - off);
|
rnv = (GET_PC - off);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (insn & INSN_SDT_W)
|
if (insn & INSN_SDT_W)
|
||||||
{
|
{
|
||||||
rnv_old = GET_REGISTER(rn);
|
rnv_old = GetRegister(rn);
|
||||||
SET_REGISTER(rn, rnv);
|
SetRegister(rn, rnv);
|
||||||
|
|
||||||
// check writeback???
|
// check writeback???
|
||||||
}
|
}
|
||||||
@ -461,7 +466,7 @@ void arm7_cpu_device::HandleMemSingle(UINT32 insn)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rnv = GET_REGISTER(rn);
|
rnv = GetRegister(rn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -473,15 +478,15 @@ void arm7_cpu_device::HandleMemSingle(UINT32 insn)
|
|||||||
if (insn & INSN_SDT_B)
|
if (insn & INSN_SDT_B)
|
||||||
{
|
{
|
||||||
UINT32 data = READ8(rnv);
|
UINT32 data = READ8(rnv);
|
||||||
if (m_pendingAbtD == 0)
|
if (!m_pendingAbtD)
|
||||||
{
|
{
|
||||||
SET_REGISTER(rd, data);
|
SetRegister(rd, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UINT32 data = READ32(rnv);
|
UINT32 data = READ32(rnv);
|
||||||
if (m_pendingAbtD == 0)
|
if (!m_pendingAbtD)
|
||||||
{
|
{
|
||||||
if (rd == eR15)
|
if (rd == eR15)
|
||||||
{
|
{
|
||||||
@ -494,7 +499,7 @@ void arm7_cpu_device::HandleMemSingle(UINT32 insn)
|
|||||||
}
|
}
|
||||||
else
|
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"));
|
LOG(("Wrote R15 in byte mode\n"));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
WRITE8(rnv, (UINT8) GET_REGISTER(rd) & 0xffu);
|
WRITE8(rnv, (UINT8) GetRegister(rd) & 0xffu);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -518,18 +523,18 @@ void arm7_cpu_device::HandleMemSingle(UINT32 insn)
|
|||||||
LOG(("Wrote R15 in 32bit mode\n"));
|
LOG(("Wrote R15 in 32bit mode\n"));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//WRITE32(rnv, rd == eR15 ? R15 + 8 : GET_REGISTER(rd));
|
//WRITE32(rnv, rd == eR15 ? R15 + 8 : GetRegister(rd));
|
||||||
WRITE32(rnv, rd == eR15 ? R15 + 8 + 4 : GET_REGISTER(rd)); // manual says STR rd = PC, +12
|
WRITE32(rnv, rd == eR15 ? R15 + 8 + 4 : GetRegister(rd)); // manual says STR rd = PC, +12
|
||||||
}
|
}
|
||||||
// Store takes only 2 N Cycles, so add + 1
|
// Store takes only 2 N Cycles, so add + 1
|
||||||
ARM7_ICOUNT += 1;
|
ARM7_ICOUNT += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_pendingAbtD != 0)
|
if (m_pendingAbtD)
|
||||||
{
|
{
|
||||||
if ((insn & INSN_SDT_P) && (insn & INSN_SDT_W))
|
if ((insn & INSN_SDT_P) && (insn & INSN_SDT_W))
|
||||||
{
|
{
|
||||||
SET_REGISTER(rn, rnv_old);
|
SetRegister(rn, rnv_old);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -542,14 +547,14 @@ void arm7_cpu_device::HandleMemSingle(UINT32 insn)
|
|||||||
/* Writeback is applied in pipeline, before value is read from mem,
|
/* Writeback is applied in pipeline, before value is read from mem,
|
||||||
so writeback is effectively ignored */
|
so writeback is effectively ignored */
|
||||||
if (rd == rn) {
|
if (rd == rn) {
|
||||||
SET_REGISTER(rn, GET_REGISTER(rd));
|
SetRegister(rn, GetRegister(rd));
|
||||||
// todo: check for offs... ?
|
// todo: check for offs... ?
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if ((insn & INSN_SDT_W) != 0)
|
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));
|
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
|
else
|
||||||
@ -557,20 +562,19 @@ void arm7_cpu_device::HandleMemSingle(UINT32 insn)
|
|||||||
/* Writeback is applied in pipeline, before value is read from mem,
|
/* Writeback is applied in pipeline, before value is read from mem,
|
||||||
so writeback is effectively ignored */
|
so writeback is effectively ignored */
|
||||||
if (rd == rn) {
|
if (rd == rn) {
|
||||||
SET_REGISTER(rn, GET_REGISTER(rd));
|
SetRegister(rn, GetRegister(rd));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
SET_REGISTER(rn, (rnv - off));
|
SetRegister(rn, (rnv - off));
|
||||||
|
|
||||||
if ((insn & INSN_SDT_W) != 0)
|
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));
|
LOG(("%08x: RegisterWritebackDecrement %d %d %d\n", R15, (insn & INSN_SDT_P) != 0, (insn & INSN_SDT_W) != 0, (insn & INSN_SDT_U) != 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
// arm7_check_irq_state();
|
||||||
|
|
||||||
// ARM7_CHECKIRQ
|
|
||||||
|
|
||||||
} /* HandleMemSingle */
|
} /* HandleMemSingle */
|
||||||
|
|
||||||
@ -585,7 +589,7 @@ void arm7_cpu_device::HandleHalfWordDT(UINT32 insn)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// register
|
// register
|
||||||
off = GET_REGISTER(insn & 0x0f);
|
off = GetRegister(insn & 0x0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate Rn, accounting for PC */
|
/* Calculate Rn, accounting for PC */
|
||||||
@ -596,17 +600,17 @@ void arm7_cpu_device::HandleHalfWordDT(UINT32 insn)
|
|||||||
/* Pre-indexed addressing */
|
/* Pre-indexed addressing */
|
||||||
if (insn & INSN_SDT_U)
|
if (insn & INSN_SDT_U)
|
||||||
{
|
{
|
||||||
rnv = (GET_REGISTER(rn) + off);
|
rnv = (GetRegister(rn) + off);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rnv = (GET_REGISTER(rn) - off);
|
rnv = (GetRegister(rn) - off);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (insn & INSN_SDT_W)
|
if (insn & INSN_SDT_W)
|
||||||
{
|
{
|
||||||
rnv_old = GET_REGISTER(rn);
|
rnv_old = GetRegister(rn);
|
||||||
SET_REGISTER(rn, rnv);
|
SetRegister(rn, rnv);
|
||||||
|
|
||||||
// check writeback???
|
// check writeback???
|
||||||
}
|
}
|
||||||
@ -624,7 +628,7 @@ void arm7_cpu_device::HandleHalfWordDT(UINT32 insn)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rnv = GET_REGISTER(rn);
|
rnv = GetRegister(rn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -655,7 +659,7 @@ void arm7_cpu_device::HandleHalfWordDT(UINT32 insn)
|
|||||||
newval = (UINT32)(signbyte << 8)|databyte;
|
newval = (UINT32)(signbyte << 8)|databyte;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_pendingAbtD == 0)
|
if (!m_pendingAbtD)
|
||||||
{
|
{
|
||||||
// PC?
|
// PC?
|
||||||
if (rd == eR15)
|
if (rd == eR15)
|
||||||
@ -667,7 +671,7 @@ void arm7_cpu_device::HandleHalfWordDT(UINT32 insn)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SET_REGISTER(rd, newval);
|
SetRegister(rd, newval);
|
||||||
R15 += 4;
|
R15 += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -683,7 +687,7 @@ void arm7_cpu_device::HandleHalfWordDT(UINT32 insn)
|
|||||||
{
|
{
|
||||||
UINT32 newval = READ16(rnv);
|
UINT32 newval = READ16(rnv);
|
||||||
|
|
||||||
if (m_pendingAbtD == 0)
|
if (!m_pendingAbtD)
|
||||||
{
|
{
|
||||||
if (rd == eR15)
|
if (rd == eR15)
|
||||||
{
|
{
|
||||||
@ -693,10 +697,9 @@ void arm7_cpu_device::HandleHalfWordDT(UINT32 insn)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SET_REGISTER(rd, newval);
|
SetRegister(rd, newval);
|
||||||
R15 += 4;
|
R15 += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -712,20 +715,20 @@ void arm7_cpu_device::HandleHalfWordDT(UINT32 insn)
|
|||||||
{
|
{
|
||||||
if ((insn & 0x60) == 0x40) // LDRD
|
if ((insn & 0x60) == 0x40) // LDRD
|
||||||
{
|
{
|
||||||
SET_REGISTER(rd, READ32(rnv));
|
SetRegister(rd, READ32(rnv));
|
||||||
SET_REGISTER(rd+1, READ32(rnv+4));
|
SetRegister(rd+1, READ32(rnv+4));
|
||||||
R15 += 4;
|
R15 += 4;
|
||||||
}
|
}
|
||||||
else if ((insn & 0x60) == 0x60) // STRD
|
else if ((insn & 0x60) == 0x60) // STRD
|
||||||
{
|
{
|
||||||
WRITE32(rnv, GET_REGISTER(rd));
|
WRITE32(rnv, GetRegister(rd));
|
||||||
WRITE32(rnv+4, GET_REGISTER(rd+1));
|
WRITE32(rnv+4, GetRegister(rd+1));
|
||||||
R15 += 4;
|
R15 += 4;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// WRITE16(rnv, rd == eR15 ? R15 + 8 : GET_REGISTER(rd));
|
// WRITE16(rnv, rd == eR15 ? R15 + 8 : GetRegister(rd));
|
||||||
WRITE16(rnv, rd == eR15 ? R15 + 8 + 4 : GET_REGISTER(rd)); // manual says STR RD=PC, +12 of address
|
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 R15 is not increased then e.g. "STRH R10, [R15,#$10]" will be executed over and over again
|
||||||
#if 0
|
#if 0
|
||||||
@ -738,11 +741,11 @@ void arm7_cpu_device::HandleHalfWordDT(UINT32 insn)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_pendingAbtD != 0)
|
if (m_pendingAbtD)
|
||||||
{
|
{
|
||||||
if ((insn & INSN_SDT_P) && (insn & INSN_SDT_W))
|
if ((insn & INSN_SDT_P) && (insn & INSN_SDT_W))
|
||||||
{
|
{
|
||||||
SET_REGISTER(rn, rnv_old);
|
SetRegister(rn, rnv_old);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -757,14 +760,14 @@ void arm7_cpu_device::HandleHalfWordDT(UINT32 insn)
|
|||||||
/* Writeback is applied in pipeline, before value is read from mem,
|
/* Writeback is applied in pipeline, before value is read from mem,
|
||||||
so writeback is effectively ignored */
|
so writeback is effectively ignored */
|
||||||
if (rd == rn) {
|
if (rd == rn) {
|
||||||
SET_REGISTER(rn, GET_REGISTER(rd));
|
SetRegister(rn, GetRegister(rd));
|
||||||
// todo: check for offs... ?
|
// todo: check for offs... ?
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if ((insn & INSN_SDT_W) != 0)
|
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));
|
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
|
else
|
||||||
@ -772,10 +775,10 @@ void arm7_cpu_device::HandleHalfWordDT(UINT32 insn)
|
|||||||
/* Writeback is applied in pipeline, before value is read from mem,
|
/* Writeback is applied in pipeline, before value is read from mem,
|
||||||
so writeback is effectively ignored */
|
so writeback is effectively ignored */
|
||||||
if (rd == rn) {
|
if (rd == rn) {
|
||||||
SET_REGISTER(rn, GET_REGISTER(rd));
|
SetRegister(rn, GetRegister(rd));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
SET_REGISTER(rn, (rnv - off));
|
SetRegister(rn, (rnv - off));
|
||||||
|
|
||||||
if ((insn & INSN_SDT_W) != 0)
|
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));
|
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;
|
UINT32 rn, rm, rd, tmp;
|
||||||
|
|
||||||
rn = GET_REGISTER((insn >> 16) & 0xf); // reg. w/read address
|
rn = GetRegister((insn >> 16) & 0xf); // reg. w/read address
|
||||||
rm = GET_REGISTER(insn & 0xf); // reg. w/write address
|
rm = GetRegister(insn & 0xf); // reg. w/write address
|
||||||
rd = (insn >> 12) & 0xf; // dest reg
|
rd = (insn >> 12) & 0xf; // dest reg
|
||||||
|
|
||||||
#if ARM7_DEBUG_CORE
|
#if ARM7_DEBUG_CORE
|
||||||
@ -805,13 +808,13 @@ void arm7_cpu_device::HandleSwap(UINT32 insn)
|
|||||||
{
|
{
|
||||||
tmp = READ8(rn);
|
tmp = READ8(rn);
|
||||||
WRITE8(rn, rm);
|
WRITE8(rn, rm);
|
||||||
SET_REGISTER(rd, tmp);
|
SetRegister(rd, tmp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tmp = READ32(rn);
|
tmp = READ32(rn);
|
||||||
WRITE32(rn, rm);
|
WRITE32(rn, rm);
|
||||||
SET_REGISTER(rd, tmp);
|
SetRegister(rd, tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
R15 += 4;
|
R15 += 4;
|
||||||
@ -826,7 +829,7 @@ void arm7_cpu_device::HandlePSRTransfer(UINT32 insn)
|
|||||||
int oldmode = GET_CPSR & MODE_FLAG;
|
int oldmode = GET_CPSR & MODE_FLAG;
|
||||||
|
|
||||||
// get old value of CPSR/SPSR
|
// get old value of CPSR/SPSR
|
||||||
newval = GET_REGISTER(reg);
|
newval = GetRegister(reg);
|
||||||
|
|
||||||
// MSR (bit 21 set) - Copy value to CPSR/SPSR
|
// MSR (bit 21 set) - Copy value to CPSR/SPSR
|
||||||
if ((insn & 0x00200000))
|
if ((insn & 0x00200000))
|
||||||
@ -843,7 +846,7 @@ void arm7_cpu_device::HandlePSRTransfer(UINT32 insn)
|
|||||||
// Value from Register
|
// Value from Register
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
val = GET_REGISTER(insn & 0x0f);
|
val = GetRegister(insn & 0x0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// apply field code bits
|
// apply field code bits
|
||||||
@ -903,9 +906,11 @@ void arm7_cpu_device::HandlePSRTransfer(UINT32 insn)
|
|||||||
|
|
||||||
// Update the Register
|
// Update the Register
|
||||||
if (reg == eCPSR)
|
if (reg == eCPSR)
|
||||||
SET_CPSR(newval);
|
{
|
||||||
|
set_cpsr(newval);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
SET_REGISTER(reg, newval);
|
SetRegister(reg, newval);
|
||||||
|
|
||||||
// Switch to new mode if changed
|
// Switch to new mode if changed
|
||||||
if ((newval & MODE_FLAG) != oldmode)
|
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
|
// MRS (bit 21 clear) - Copy CPSR or SPSR to specified Register
|
||||||
else
|
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
|
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)
|
if (GET_MODE != eARM7_MODE_USER)
|
||||||
{
|
{
|
||||||
// Update CPSR from SPSR
|
// Update CPSR from SPSR
|
||||||
SET_CPSR(GET_REGISTER(SPSR));
|
set_cpsr(GetRegister(SPSR));
|
||||||
SwitchMode(GET_MODE);
|
SwitchMode(GET_MODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1090,7 +1095,7 @@ void arm7_cpu_device::HandleALU(UINT32 insn)
|
|||||||
UINT32 temp;
|
UINT32 temp;
|
||||||
R15 = rd; //(R15 & 0x03FFFFFC) | (rd & 0xFC000003);
|
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 */;
|
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);
|
SwitchMode( temp & 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1098,11 +1103,11 @@ void arm7_cpu_device::HandleALU(UINT32 insn)
|
|||||||
ARM7_ICOUNT -= 2;
|
ARM7_ICOUNT -= 2;
|
||||||
|
|
||||||
/* IRQ masks may have changed in this instruction */
|
/* IRQ masks may have changed in this instruction */
|
||||||
// ARM7_CHECKIRQ;
|
// arm7_check_irq_state();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* S Flag is set - Write results to register & update CPSR (which was already handled using HandleALU flag macros) */
|
/* 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)
|
// 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;
|
UINT32 temp;
|
||||||
R15 = (R15 & 0x03FFFFFC) | (rd & ~0x03FFFFFC);
|
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 */;
|
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);
|
SwitchMode( temp & 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* IRQ masks may have changed in this instruction */
|
/* IRQ masks may have changed in this instruction */
|
||||||
// ARM7_CHECKIRQ;
|
// arm7_check_irq_state();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1151,8 +1156,8 @@ void arm7_cpu_device::HandleMul(UINT32 insn)
|
|||||||
// multiply, which is controlled by the value of the multiplier operand
|
// multiply, which is controlled by the value of the multiplier operand
|
||||||
// specified by Rs.
|
// specified by Rs.
|
||||||
|
|
||||||
rm = GET_REGISTER(insn & INSN_MUL_RM);
|
rm = GetRegister(insn & INSN_MUL_RM);
|
||||||
rs = GET_REGISTER((insn & INSN_MUL_RS) >> INSN_MUL_RS_SHIFT);
|
rs = GetRegister((insn & INSN_MUL_RS) >> INSN_MUL_RS_SHIFT);
|
||||||
|
|
||||||
/* Do the basic multiply of Rm and Rs */
|
/* Do the basic multiply of Rm and Rs */
|
||||||
r = rm * rs;
|
r = rm * rs;
|
||||||
@ -1167,18 +1172,18 @@ void arm7_cpu_device::HandleMul(UINT32 insn)
|
|||||||
/* Add on Rn if this is a MLA */
|
/* Add on Rn if this is a MLA */
|
||||||
if (insn & INSN_MUL_A)
|
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
|
// extra cycle for MLA
|
||||||
ARM7_ICOUNT -= 1;
|
ARM7_ICOUNT -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write the result */
|
/* 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 */
|
/* Set N and Z if asked */
|
||||||
if (insn & INSN_S)
|
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;
|
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
|
// 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.
|
// controlled by the value of the multiplier operand specified by Rs.
|
||||||
|
|
||||||
rm = (INT32)GET_REGISTER(insn & 0xf);
|
rm = (INT32)GetRegister(insn & 0xf);
|
||||||
rs = (INT32)GET_REGISTER(((insn >> 8) & 0xf));
|
rs = (INT32)GetRegister(((insn >> 8) & 0xf));
|
||||||
rhi = (insn >> 16) & 0xf;
|
rhi = (insn >> 16) & 0xf;
|
||||||
rlo = (insn >> 12) & 0xf;
|
rlo = (insn >> 12) & 0xf;
|
||||||
|
|
||||||
@ -1217,20 +1222,20 @@ void arm7_cpu_device::HandleSMulLong(UINT32 insn)
|
|||||||
/* Add on Rn if this is a MLA */
|
/* Add on Rn if this is a MLA */
|
||||||
if (insn & INSN_MUL_A)
|
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;
|
res += acum;
|
||||||
// extra cycle for MLA
|
// extra cycle for MLA
|
||||||
ARM7_ICOUNT -= 1;
|
ARM7_ICOUNT -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write the result (upper dword goes to RHi, lower to RLo) */
|
/* Write the result (upper dword goes to RHi, lower to RLo) */
|
||||||
SET_REGISTER(rhi, res >> 32);
|
SetRegister(rhi, res >> 32);
|
||||||
SET_REGISTER(rlo, res & 0xFFFFFFFF);
|
SetRegister(rlo, res & 0xFFFFFFFF);
|
||||||
|
|
||||||
/* Set N and Z if asked */
|
/* Set N and Z if asked */
|
||||||
if (insn & INSN_S)
|
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;
|
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
|
// 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.
|
// controlled by the value of the multiplier operand specified by Rs.
|
||||||
|
|
||||||
rm = (INT32)GET_REGISTER(insn & 0xf);
|
rm = (INT32)GetRegister(insn & 0xf);
|
||||||
rs = (INT32)GET_REGISTER(((insn >> 8) & 0xf));
|
rs = (INT32)GetRegister(((insn >> 8) & 0xf));
|
||||||
rhi = (insn >> 16) & 0xf;
|
rhi = (insn >> 16) & 0xf;
|
||||||
rlo = (insn >> 12) & 0xf;
|
rlo = (insn >> 12) & 0xf;
|
||||||
|
|
||||||
@ -1269,20 +1274,20 @@ void arm7_cpu_device::HandleUMulLong(UINT32 insn)
|
|||||||
/* Add on Rn if this is a MLA */
|
/* Add on Rn if this is a MLA */
|
||||||
if (insn & INSN_MUL_A)
|
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;
|
res += acum;
|
||||||
// extra cycle for MLA
|
// extra cycle for MLA
|
||||||
ARM7_ICOUNT -= 1;
|
ARM7_ICOUNT -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write the result (upper dword goes to RHi, lower to RLo) */
|
/* Write the result (upper dword goes to RHi, lower to RLo) */
|
||||||
SET_REGISTER(rhi, res >> 32);
|
SetRegister(rhi, res >> 32);
|
||||||
SET_REGISTER(rlo, res & 0xFFFFFFFF);
|
SetRegister(rlo, res & 0xFFFFFFFF);
|
||||||
|
|
||||||
/* Set N and Z if asked */
|
/* Set N and Z if asked */
|
||||||
if (insn & INSN_S)
|
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;
|
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)
|
void arm7_cpu_device::HandleMemBlock(UINT32 insn)
|
||||||
{
|
{
|
||||||
UINT32 rb = (insn & INSN_RN) >> INSN_RN_SHIFT;
|
UINT32 rb = (insn & INSN_RN) >> INSN_RN_SHIFT;
|
||||||
UINT32 rbp = GET_REGISTER(rb);
|
UINT32 rbp = GetRegister(rb);
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
#if ARM7_DEBUG_CORE
|
#if ARM7_DEBUG_CORE
|
||||||
@ -1335,7 +1340,7 @@ void arm7_cpu_device::HandleMemBlock(UINT32 insn)
|
|||||||
else
|
else
|
||||||
result = loadInc(insn & 0xffff, rbp, insn & INSN_BDT_S, GET_MODE);
|
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 ARM7_DEBUG_CORE
|
||||||
if (rb == 15)
|
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]
|
// GBA "V-Rally 3" expects R0 not to be overwritten with the updated base value [BP 8077B0C]
|
||||||
if (((insn >> rb) & 1) == 0)
|
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!)
|
// 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?
|
R15 -= 4; // SJE: I forget why i did this?
|
||||||
// S - Flag Set? Signals transfer of current mode SPSR->CPSR
|
// S - Flag Set? Signals transfer of current mode SPSR->CPSR
|
||||||
if (insn & INSN_BDT_S)
|
if (insn & INSN_BDT_S)
|
||||||
{
|
{
|
||||||
if (MODE32)
|
if (MODE32)
|
||||||
{
|
{
|
||||||
SET_CPSR(GET_REGISTER(SPSR));
|
set_cpsr(GetRegister(SPSR));
|
||||||
SwitchMode(GET_MODE);
|
SwitchMode(GET_MODE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1365,7 +1371,7 @@ void arm7_cpu_device::HandleMemBlock(UINT32 insn)
|
|||||||
UINT32 temp;
|
UINT32 temp;
|
||||||
// LOG(("LDM + S | R15 %08X CPSR %08X\n", R15, GET_CPSR));
|
// 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 */;
|
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);
|
SwitchMode(temp & 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1395,26 +1401,26 @@ void arm7_cpu_device::HandleMemBlock(UINT32 insn)
|
|||||||
else
|
else
|
||||||
result = loadDec(insn & 0xffff, rbp, insn & INSN_BDT_S, GET_MODE);
|
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)
|
if (rb == 0xf)
|
||||||
LOG(("%08x: Illegal LDRM writeback to r15\n", R15));
|
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?)
|
// "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)
|
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!)
|
// 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?
|
R15 -= 4; // SJE: I forget why i did this?
|
||||||
// S - Flag Set? Signals transfer of current mode SPSR->CPSR
|
// S - Flag Set? Signals transfer of current mode SPSR->CPSR
|
||||||
if (insn & INSN_BDT_S)
|
if (insn & INSN_BDT_S)
|
||||||
{
|
{
|
||||||
if (MODE32)
|
if (MODE32)
|
||||||
{
|
{
|
||||||
SET_CPSR(GET_REGISTER(SPSR));
|
set_cpsr(GetRegister(SPSR));
|
||||||
SwitchMode(GET_MODE);
|
SwitchMode(GET_MODE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1422,7 +1428,7 @@ void arm7_cpu_device::HandleMemBlock(UINT32 insn)
|
|||||||
UINT32 temp;
|
UINT32 temp;
|
||||||
// LOG(("LDM + S | R15 %08X CPSR %08X\n", R15, GET_CPSR));
|
// 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 */;
|
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);
|
SwitchMode(temp & 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1468,9 +1474,9 @@ void arm7_cpu_device::HandleMemBlock(UINT32 insn)
|
|||||||
else
|
else
|
||||||
result = storeInc(insn & 0xffff, rbp, GET_MODE);
|
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
|
else
|
||||||
@ -1495,9 +1501,9 @@ void arm7_cpu_device::HandleMemBlock(UINT32 insn)
|
|||||||
else
|
else
|
||||||
result = storeDec(insn & 0xffff, rbp, GET_MODE);
|
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))
|
if (insn & (1 << eR15))
|
||||||
@ -1530,10 +1536,10 @@ void arm7_cpu_device::arm7ops_0123(UINT32 insn)
|
|||||||
/* Branch and Exchange (BX) */
|
/* Branch and Exchange (BX) */
|
||||||
if ((insn & 0x0ffffff0) == 0x012fff10) // bits 27-4 == 000100101111111111110001
|
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 new PC address has A0 set, switch to Thumb mode
|
||||||
if (R15 & 1) {
|
if (R15 & 1) {
|
||||||
SET_CPSR(GET_CPSR|T_MASK);
|
set_cpsr(GET_CPSR|T_MASK);
|
||||||
R15--;
|
R15--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1542,25 +1548,25 @@ void arm7_cpu_device::arm7ops_0123(UINT32 insn)
|
|||||||
UINT32 rm = insn&0xf;
|
UINT32 rm = insn&0xf;
|
||||||
UINT32 rd = (insn>>12)&0xf;
|
UINT32 rd = (insn>>12)&0xf;
|
||||||
|
|
||||||
SET_REGISTER(rd, count_leading_zeros(GET_REGISTER(rm)));
|
SetRegister(rd, count_leading_zeros(GetRegister(rm)));
|
||||||
|
|
||||||
R15 += 4;
|
R15 += 4;
|
||||||
}
|
}
|
||||||
else if ((insn & 0x0ff000f0) == 0x01000050) // QADD - v5
|
else if ((insn & 0x0ff000f0) == 0x01000050) // QADD - v5
|
||||||
{
|
{
|
||||||
INT32 src1 = GET_REGISTER(insn&0xf);
|
INT32 src1 = GetRegister(insn&0xf);
|
||||||
INT32 src2 = GET_REGISTER((insn>>16)&0xf);
|
INT32 src2 = GetRegister((insn>>16)&0xf);
|
||||||
INT64 res;
|
INT64 res;
|
||||||
|
|
||||||
res = saturate_qbit_overflow((INT64)src1 + (INT64)src2);
|
res = saturate_qbit_overflow((INT64)src1 + (INT64)src2);
|
||||||
|
|
||||||
SET_REGISTER((insn>>12)&0xf, (INT32)res);
|
SetRegister((insn>>12)&0xf, (INT32)res);
|
||||||
R15 += 4;
|
R15 += 4;
|
||||||
}
|
}
|
||||||
else if ((insn & 0x0ff000f0) == 0x01400050) // QDADD - v5
|
else if ((insn & 0x0ff000f0) == 0x01400050) // QDADD - v5
|
||||||
{
|
{
|
||||||
INT32 src1 = GET_REGISTER(insn&0xf);
|
INT32 src1 = GetRegister(insn&0xf);
|
||||||
INT32 src2 = GET_REGISTER((insn>>16)&0xf);
|
INT32 src2 = GetRegister((insn>>16)&0xf);
|
||||||
INT64 res;
|
INT64 res;
|
||||||
|
|
||||||
// check if doubling operation will overflow
|
// check if doubling operation will overflow
|
||||||
@ -1570,24 +1576,24 @@ void arm7_cpu_device::arm7ops_0123(UINT32 insn)
|
|||||||
src2 *= 2;
|
src2 *= 2;
|
||||||
res = saturate_qbit_overflow((INT64)src1 + (INT64)src2);
|
res = saturate_qbit_overflow((INT64)src1 + (INT64)src2);
|
||||||
|
|
||||||
SET_REGISTER((insn>>12)&0xf, (INT32)res);
|
SetRegister((insn>>12)&0xf, (INT32)res);
|
||||||
R15 += 4;
|
R15 += 4;
|
||||||
}
|
}
|
||||||
else if ((insn & 0x0ff000f0) == 0x01200050) // QSUB - v5
|
else if ((insn & 0x0ff000f0) == 0x01200050) // QSUB - v5
|
||||||
{
|
{
|
||||||
INT32 src1 = GET_REGISTER(insn&0xf);
|
INT32 src1 = GetRegister(insn&0xf);
|
||||||
INT32 src2 = GET_REGISTER((insn>>16)&0xf);
|
INT32 src2 = GetRegister((insn>>16)&0xf);
|
||||||
INT64 res;
|
INT64 res;
|
||||||
|
|
||||||
res = saturate_qbit_overflow((INT64)src1 - (INT64)src2);
|
res = saturate_qbit_overflow((INT64)src1 - (INT64)src2);
|
||||||
|
|
||||||
SET_REGISTER((insn>>12)&0xf, (INT32)res);
|
SetRegister((insn>>12)&0xf, (INT32)res);
|
||||||
R15 += 4;
|
R15 += 4;
|
||||||
}
|
}
|
||||||
else if ((insn & 0x0ff000f0) == 0x01600050) // QDSUB - v5
|
else if ((insn & 0x0ff000f0) == 0x01600050) // QDSUB - v5
|
||||||
{
|
{
|
||||||
INT32 src1 = GET_REGISTER(insn&0xf);
|
INT32 src1 = GetRegister(insn&0xf);
|
||||||
INT32 src2 = GET_REGISTER((insn>>16)&0xf);
|
INT32 src2 = GetRegister((insn>>16)&0xf);
|
||||||
INT64 res;
|
INT64 res;
|
||||||
|
|
||||||
// check if doubling operation will overflow
|
// check if doubling operation will overflow
|
||||||
@ -1597,13 +1603,13 @@ void arm7_cpu_device::arm7ops_0123(UINT32 insn)
|
|||||||
src2 *= 2;
|
src2 *= 2;
|
||||||
res = saturate_qbit_overflow((INT64)src1 - (INT64)src2);
|
res = saturate_qbit_overflow((INT64)src1 - (INT64)src2);
|
||||||
|
|
||||||
SET_REGISTER((insn>>12)&0xf, (INT32)res);
|
SetRegister((insn>>12)&0xf, (INT32)res);
|
||||||
R15 += 4;
|
R15 += 4;
|
||||||
}
|
}
|
||||||
else if ((insn & 0x0ff00090) == 0x01000080) // SMLAxy - v5
|
else if ((insn & 0x0ff00090) == 0x01000080) // SMLAxy - v5
|
||||||
{
|
{
|
||||||
INT32 src1 = GET_REGISTER(insn&0xf);
|
INT32 src1 = GetRegister(insn&0xf);
|
||||||
INT32 src2 = GET_REGISTER((insn>>8)&0xf);
|
INT32 src2 = GetRegister((insn>>8)&0xf);
|
||||||
INT32 res1;
|
INT32 res1;
|
||||||
|
|
||||||
// select top and bottom halves of src1/src2 and sign extend if necessary
|
// 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
|
// do the signed multiply
|
||||||
res1 = src1 * src2;
|
res1 = src1 * src2;
|
||||||
// and the accumulate. NOTE: only the accumulate can cause an overflow, which is why we do it this way.
|
// 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;
|
R15 += 4;
|
||||||
}
|
}
|
||||||
else if ((insn & 0x0ff00090) == 0x01400080) // SMLALxy - v5
|
else if ((insn & 0x0ff00090) == 0x01400080) // SMLALxy - v5
|
||||||
{
|
{
|
||||||
INT32 src1 = GET_REGISTER(insn&0xf);
|
INT32 src1 = GetRegister(insn&0xf);
|
||||||
INT32 src2 = GET_REGISTER((insn>>8)&0xf);
|
INT32 src2 = GetRegister((insn>>8)&0xf);
|
||||||
INT64 dst;
|
INT64 dst;
|
||||||
|
|
||||||
dst = (INT64)GET_REGISTER((insn>>12)&0xf);
|
dst = (INT64)GetRegister((insn>>12)&0xf);
|
||||||
dst |= (INT64)GET_REGISTER((insn>>16)&0xf)<<32;
|
dst |= (INT64)GetRegister((insn>>16)&0xf)<<32;
|
||||||
|
|
||||||
// do the multiply and accumulate
|
// do the multiply and accumulate
|
||||||
dst += (INT64)src1 * (INT64)src2;
|
dst += (INT64)src1 * (INT64)src2;
|
||||||
|
|
||||||
// write back the result
|
// write back the result
|
||||||
SET_REGISTER((insn>>12)&0xf, (UINT32)dst);
|
SetRegister((insn>>12)&0xf, (UINT32)dst);
|
||||||
SET_REGISTER((insn>>16)&0xf, (UINT32)(dst >> 32));
|
SetRegister((insn>>16)&0xf, (UINT32)(dst >> 32));
|
||||||
R15 += 4;
|
R15 += 4;
|
||||||
}
|
}
|
||||||
else if ((insn & 0x0ff00090) == 0x01600080) // SMULxy - v5
|
else if ((insn & 0x0ff00090) == 0x01600080) // SMULxy - v5
|
||||||
{
|
{
|
||||||
INT32 src1 = GET_REGISTER(insn&0xf);
|
INT32 src1 = GetRegister(insn&0xf);
|
||||||
INT32 src2 = GET_REGISTER((insn>>8)&0xf);
|
INT32 src2 = GetRegister((insn>>8)&0xf);
|
||||||
INT32 res;
|
INT32 res;
|
||||||
|
|
||||||
// select top and bottom halves of src1/src2 and sign extend if necessary
|
// 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;
|
res = src1 * src2;
|
||||||
SET_REGISTER((insn>>16)&0xf, res);
|
SetRegister((insn>>16)&0xf, res);
|
||||||
R15 += 4;
|
R15 += 4;
|
||||||
}
|
}
|
||||||
else if ((insn & 0x0ff000b0) == 0x012000a0) // SMULWy - v5
|
else if ((insn & 0x0ff000b0) == 0x012000a0) // SMULWy - v5
|
||||||
{
|
{
|
||||||
INT32 src1 = GET_REGISTER(insn&0xf);
|
INT32 src1 = GetRegister(insn&0xf);
|
||||||
INT32 src2 = GET_REGISTER((insn>>8)&0xf);
|
INT32 src2 = GetRegister((insn>>8)&0xf);
|
||||||
INT64 res;
|
INT64 res;
|
||||||
|
|
||||||
if (insn & 0x40)
|
if (insn & 0x40)
|
||||||
@ -1706,14 +1712,14 @@ void arm7_cpu_device::arm7ops_0123(UINT32 insn)
|
|||||||
|
|
||||||
res = (INT64)src1 * (INT64)src2;
|
res = (INT64)src1 * (INT64)src2;
|
||||||
res >>= 16;
|
res >>= 16;
|
||||||
SET_REGISTER((insn>>16)&0xf, (UINT32)res);
|
SetRegister((insn>>16)&0xf, (UINT32)res);
|
||||||
R15 += 4;
|
R15 += 4;
|
||||||
}
|
}
|
||||||
else if ((insn & 0x0ff000b0) == 0x01200080) // SMLAWy - v5
|
else if ((insn & 0x0ff000b0) == 0x01200080) // SMLAWy - v5
|
||||||
{
|
{
|
||||||
INT32 src1 = GET_REGISTER(insn&0xf);
|
INT32 src1 = GetRegister(insn&0xf);
|
||||||
INT32 src2 = GET_REGISTER((insn>>8)&0xf);
|
INT32 src2 = GetRegister((insn>>8)&0xf);
|
||||||
INT32 src3 = GET_REGISTER((insn>>12)&0xf);
|
INT32 src3 = GetRegister((insn>>12)&0xf);
|
||||||
INT64 res;
|
INT64 res;
|
||||||
|
|
||||||
if (insn & 0x40)
|
if (insn & 0x40)
|
||||||
@ -1737,7 +1743,7 @@ void arm7_cpu_device::arm7ops_0123(UINT32 insn)
|
|||||||
src3 += (INT32)res;
|
src3 += (INT32)res;
|
||||||
|
|
||||||
// write the result back
|
// write the result back
|
||||||
SET_REGISTER((insn>>16)&0xf, (UINT32)res);
|
SetRegister((insn>>16)&0xf, (UINT32)res);
|
||||||
R15 += 4;
|
R15 += 4;
|
||||||
}
|
}
|
||||||
else
|
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 */
|
void arm7_cpu_device::arm7ops_f(UINT32 insn) /* Software Interrupt */
|
||||||
{
|
{
|
||||||
m_pendingSwi = 1;
|
m_pendingSwi = true;
|
||||||
ARM7_CHECKIRQ;
|
update_irq_state();
|
||||||
|
arm7_check_irq_state();
|
||||||
//couldn't find any cycle counts for SWI
|
//couldn't find any cycle counts for SWI
|
||||||
// break;
|
// break;
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user