diff options
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 |
commit | 475cf95575c36a7bb0980f966131ebf97ecae1de (patch) | |
tree | bef26270d97bfbaa5b7d86b4f379feacd89e0bba | |
parent | 4854fdf2c6e73ed0ab78e3e9e4b5d1d7039e10b1 (diff) |
arm7: fix unaligned 16-bit loads
-rw-r--r-- | src/devices/cpu/arm7/arm7.cpp | 12 | ||||
-rw-r--r-- | src/devices/cpu/arm7/arm7.h | 4 | ||||
-rw-r--r-- | src/devices/cpu/arm7/arm7ops.cpp | 10 |
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 { |