diff --git a/src/emucore/CartELF.cxx b/src/emucore/CartELF.cxx index 303ec050e..be2311756 100644 --- a/src/emucore/CartELF.cxx +++ b/src/emucore/CartELF.cxx @@ -456,7 +456,7 @@ void CartridgeELF::jumpToMain() .setRegister(0, sp ) .setRegister(13, sp) .setRegister(14, RETURN_ADDR_MAIN) - .setRegister(15, myArmEntrypoint); + .setPc(myArmEntrypoint); } void CartridgeELF::runArm() diff --git a/src/emucore/CortexM0.cxx b/src/emucore/CortexM0.cxx index 702ffe081..63c5bac54 100644 --- a/src/emucore/CortexM0.cxx +++ b/src/emucore/CortexM0.cxx @@ -553,10 +553,6 @@ CortexM0& CortexM0::mapRegionCode(uInt32 pageBase, region.access.accessCode.backingStore = backingStore; region.access.accessCode.ops = static_cast(std::malloc((pageCount * PAGE_SIZE) >> 1)); - for (size_t i = 0; i < pageCount * PAGE_SIZE; i += 2) - region.access.accessCode.ops[i >> 1] = - decodeInstructionWord(READ16(backingStore, i)); - return *this; } @@ -583,9 +579,16 @@ CortexM0& CortexM0::reset() reg_norm.fill(0); znFlags = cFlag = vFlag = 0; + recompileCodeRegions(); + return *this; } +CortexM0& CortexM0::setPc(uInt32 pc) +{ + return setRegister(15, (pc & ~1) + 2); +} + CortexM0& CortexM0::setRegister(uInt8 regno, uInt32 value) { write_register(regno, value); @@ -610,7 +613,7 @@ CortexM0::err_t CortexM0::run(uInt32 maxCycles, uInt32& cycles) uInt16 inst; uInt8 op; - err_t err = fetch16(pc -2, inst, op); + err_t err = fetch16(pc - 2, inst, op); if (err) return err; @@ -650,6 +653,17 @@ CortexM0::MemoryRegion& CortexM0::setupMapping(uInt32 pageBase, uInt32 pageCount return region; } +void CortexM0::recompileCodeRegions() +{ + for (const auto& region: myRegions) { + if (region.type != MemoryRegionType::directCode) continue; + + for (size_t i = 0; i < region.size; i += 2) + region.access.accessCode.ops[i >> 1] = + decodeInstructionWord(READ16(region.access.accessCode.backingStore, i)); + } +} + CortexM0::err_t CortexM0::read32(uInt32 address, uInt32& value) { if (address & 0x03) return errIntrinsic(ERR_ACCESS_ALIGNMENT_FAULT, address); @@ -1176,7 +1190,7 @@ CortexM0::err_t CortexM0::execute(uInt16 inst, uInt8 op) } case Op::bkpt: - return errIntrinsic(ERR_BKPT, read_register(15) - 2); + return errIntrinsic(ERR_BKPT, read_register(15) - 4); //BL/BLX(1) variants // (bl, blx_thumb) @@ -1216,7 +1230,7 @@ CortexM0::err_t CortexM0::execute(uInt16 inst, uInt8 op) write_register(15, rc); return ERR_NONE; } - else return errIntrinsic(ERR_INVALID_OPERATING_MODE, read_register(15) - 2); + else return errIntrinsic(ERR_INVALID_OPERATING_MODE, read_register(15) - 4); } //BX @@ -1233,7 +1247,7 @@ CortexM0::err_t CortexM0::execute(uInt16 inst, uInt8 op) write_register(15, rc); return ERR_NONE; } - else return errIntrinsic(ERR_INVALID_OPERATING_MODE, read_register(15) - 2); + else return errIntrinsic(ERR_INVALID_OPERATING_MODE, read_register(15) - 4); } //CMN @@ -1864,11 +1878,6 @@ CortexM0::err_t CortexM0::execute(uInt16 inst, uInt8 op) rc = read_register(14); const err_t err = write32(rd, rc); if (err) return err; - - if((rc & 1) == 0) - { - return errIntrinsic(ERR_INVALID_OPERATING_MODE, read_register(15) - 2); - } } write_register(13, sp); return ERR_NONE; @@ -1966,7 +1975,7 @@ CortexM0::err_t CortexM0::execute(uInt16 inst, uInt8 op) #ifndef UNSAFE_OPTIMIZATIONS //SETEND case Op::setend: { - return errIntrinsic(ERR_UNIMPLEMENTED_INST, read_register(15) - 2); + return errIntrinsic(ERR_UNIMPLEMENTED_INST, read_register(15) - 4); } #endif @@ -2235,6 +2244,6 @@ CortexM0::err_t CortexM0::execute(uInt16 inst, uInt8 op) } default: - return errIntrinsic(ERR_UNDEFINED_INST, read_register(15) - 2); + return errIntrinsic(ERR_UNDEFINED_INST, read_register(15) - 4); } } diff --git a/src/emucore/CortexM0.hxx b/src/emucore/CortexM0.hxx index 81c271504..81224b70c 100644 --- a/src/emucore/CortexM0.hxx +++ b/src/emucore/CortexM0.hxx @@ -104,6 +104,7 @@ class CortexM0 CortexM0& mapDefault(BusTransactionDelegate* delegate); CortexM0& reset(); + CortexM0& setPc(uInt32 pc); CortexM0& setRegister(uInt8 regno, uInt32 value); uInt32 getRegister(uInt32 regno); @@ -168,6 +169,8 @@ class CortexM0 MemoryRegion& setupMapping(uInt32 pageBase, uInt32 pageCount, bool readOnly, MemoryRegionType type); + void recompileCodeRegions(); + err_t fetch16(uInt32 address, uInt16& value, uInt8& op); void do_cvflag(uInt32 a, uInt32 b, uInt32 c);