summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2017-11-30 19:58:51 +1100
committer Vas Crabb <vas@vastheman.com>2017-11-30 19:58:51 +1100
commit475cf95575c36a7bb0980f966131ebf97ecae1de (patch)
treebef26270d97bfbaa5b7d86b4f379feacd89e0bba
parent4854fdf2c6e73ed0ab78e3e9e4b5d1d7039e10b1 (diff)
arm7: fix unaligned 16-bit loads
-rw-r--r--src/devices/cpu/arm7/arm7.cpp12
-rw-r--r--src/devices/cpu/arm7/arm7.h4
-rw-r--r--src/devices/cpu/arm7/arm7ops.cpp10
3 files changed, 13 insertions, 13 deletions
diff --git a/src/devices/cpu/arm7/arm7.cpp b/src/devices/cpu/arm7/arm7.cpp
index 6538e573935..7a3a7ba30db 100644
--- a/src/devices/cpu/arm7/arm7.cpp
+++ b/src/devices/cpu/arm7/arm7.cpp
@@ -1417,9 +1417,9 @@ uint32_t arm946es_cpu_device::arm7_cpu_read32(uint32_t addr)
return result;
}
-uint16_t arm946es_cpu_device::arm7_cpu_read16(uint32_t addr)
+uint32_t arm946es_cpu_device::arm7_cpu_read16(uint32_t addr)
{
- uint16_t result;
+ uint32_t result;
if ((addr >= cp15_itcm_base) && (addr <= cp15_itcm_end))
{
@@ -1438,7 +1438,7 @@ uint16_t arm946es_cpu_device::arm7_cpu_read16(uint32_t addr)
if (addr & 1)
{
- result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
+ result = ((result >> 8) & 0xff) | ((result & 0xff) << 24);
}
return result;
@@ -1567,9 +1567,9 @@ uint32_t arm7_cpu_device::arm7_cpu_read32(uint32_t addr)
return result;
}
-uint16_t arm7_cpu_device::arm7_cpu_read16(uint32_t addr)
+uint32_t arm7_cpu_device::arm7_cpu_read16(uint32_t addr)
{
- uint16_t result;
+ uint32_t result;
if( COPRO_CTRL & COPRO_CTRL_MMU_EN )
{
@@ -1583,7 +1583,7 @@ uint16_t arm7_cpu_device::arm7_cpu_read16(uint32_t addr)
if (addr & 1)
{
- result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
+ result = ((result >> 8) & 0xff) | ((result & 0xff) << 24);
}
return result;
diff --git a/src/devices/cpu/arm7/arm7.h b/src/devices/cpu/arm7/arm7.h
index 2fde4b1805a..f6eecc4e4e1 100644
--- a/src/devices/cpu/arm7/arm7.h
+++ b/src/devices/cpu/arm7/arm7.h
@@ -236,7 +236,7 @@ protected:
virtual void arm7_cpu_write16(uint32_t addr, uint16_t data);
virtual void arm7_cpu_write8(uint32_t addr, uint8_t data);
virtual uint32_t arm7_cpu_read32(uint32_t addr);
- virtual uint16_t arm7_cpu_read16(uint32_t addr);
+ virtual uint32_t arm7_cpu_read16(uint32_t addr);
virtual uint8_t arm7_cpu_read8(uint32_t addr);
// Coprocessor support
@@ -623,7 +623,7 @@ public:
virtual void arm7_cpu_write16(uint32_t addr, uint16_t data) override;
virtual void arm7_cpu_write8(uint32_t addr, uint8_t data) override;
virtual uint32_t arm7_cpu_read32(uint32_t addr) override;
- virtual uint16_t arm7_cpu_read16(uint32_t addr) override;
+ virtual uint32_t arm7_cpu_read16(uint32_t addr) override;
virtual uint8_t arm7_cpu_read8(uint32_t addr) override;
private:
diff --git a/src/devices/cpu/arm7/arm7ops.cpp b/src/devices/cpu/arm7/arm7ops.cpp
index 084634a77c0..3e0b9a599c2 100644
--- a/src/devices/cpu/arm7/arm7ops.cpp
+++ b/src/devices/cpu/arm7/arm7ops.cpp
@@ -492,7 +492,7 @@ void arm7_cpu_device::HandleMemSingle(uint32_t insn)
R15 = data - 4;
else
R15 = (R15 & ~0x03FFFFFC) /* N Z C V I F M1 M0 */ | ((data - 4) & 0x03FFFFFC);
- // LDR, PC takes 2S + 2N + 1I (5 total cycles)
+ // LDR, PC takes 2S + 2N + 1I (5 total cycles)
ARM7_ICOUNT -= 2;
if ((data & 1) && m_archRev >= 5)
{
@@ -648,10 +648,10 @@ void arm7_cpu_device::HandleHalfWordDT(uint32_t insn)
// Signed Half Word?
if (insn & 0x20) {
- uint16_t signbyte, databyte;
- databyte = READ16(rnv) & 0xFFFF;
- signbyte = (databyte & 0x8000) ? 0xffff : 0;
- newval = (uint32_t)(signbyte << 16)|databyte;
+ uint32_t databyte = READ16(rnv);
+ uint32_t mask = 0x0000ffff;
+ mask >>= (rnv & 1) ? 8 : 0;
+ newval = databyte | ((databyte & ((mask + 1) >> 1)) ? ~mask : 0);
}
// Signed Byte
else {