v6m virtual machine
Import programemu812
mbed LPC812 emulator pre-alpha version
Import programemu1114
mbed LPC1114 emulator pre-alpha version
Diff: BaseV6M.cpp
- Revision:
- 3:fe333683e8f7
- Parent:
- 2:078d2e512ba4
- Child:
- 4:1c7b72bcfc4d
--- a/BaseV6M.cpp Wed Aug 19 16:50:07 2015 +0900 +++ b/BaseV6M.cpp Thu Aug 20 18:08:34 2015 +0900 @@ -1,4 +1,4 @@ -// BaseV6M.cpp 2015/8/19 +// BaseV6M.cpp 2015/8/20 #pragma Otime #include "BaseV6M.h" @@ -129,7 +129,7 @@ } void BaseV6M::jump(uint32_t addr) { - R[_PC] = addr; + R[_PC] = align16(addr); cache = false; } @@ -419,7 +419,7 @@ NZupdate(data); } -void BaseV6M::c_beq(uint32_t code) { // BEQ #0xd000-0xd0ff +void BaseV6M::c_beq(uint32_t code) { // BEQ 0xd000-0xd0ff uint32_t addr = R[_PC] + signed_immed(code, 8) * 2; if (Z() == 1) { jump(addr); @@ -435,7 +435,7 @@ V6M_INFO("I: BNE 0x%08x", addr); } -void BaseV6M::c_bcs(uint32_t code) { // BCS #0xd200-0xd2ff +void BaseV6M::c_bcs(uint32_t code) { // BCS 0xd200-0xd2ff uint32_t addr = R[_PC] + signed_immed(code, 8) * 2; if (C() == 1) { jump(addr); @@ -443,7 +443,7 @@ V6M_INFO("I: BCS 0x%08x", addr); } -void BaseV6M::c_bcc(uint32_t code) { // BCC #0xd300-0xd3ff +void BaseV6M::c_bcc(uint32_t code) { // BCC 0xd300-0xd3ff uint32_t addr = R[_PC] + signed_immed(code, 8) * 2; if (C() == 0) { jump(addr); @@ -715,7 +715,13 @@ void BaseV6M::c_add_hr(uint32_t code) { // ADD Rd,Rm (high reg) 0x4400-0x44ff d_D_M_Rm_Rd(code); *Rd = add32(*Rn, *Rm); - V6M_INFO("I: ADD %s,%s,%s", GetRegName(Rd), GetRegName(Rn), GetRegName(Rm)); + if (Rd == &R[_PC]) { + jump(R[_PC]); + V6M_INFO("I: ADD pc,pc,%s ; pc=0x%08x", GetRegName(Rn), R[_PC]); + exception_return(); + } else { + V6M_INFO("I: ADD %s,%s,%s", GetRegName(Rd), GetRegName(Rn), GetRegName(Rm)); + } } void BaseV6M::c_cmp_hr(uint32_t code) { // CMP Rd,Rm (high reg) 0x4500-0x45ff @@ -1026,12 +1032,13 @@ } void BaseV6M::fetch() { + V6M_ASSERT((R[_PC]&1) == 0); if (cache) { code = code2nd; - code2nd = peek16(align16(R[_PC])); + code2nd = peek16(R[_PC]); R[_PC] += 2; } else { - uint32_t d = peek32(align16(R[_PC])); + uint32_t d = peek32(R[_PC]); code = d & 0xffff; code2nd = d>>16; R[_PC] += 4; @@ -1117,7 +1124,7 @@ void BaseV6M::reset() { R[_SP] = peek32(0x00000000); R[_PC] = peek32(0x00000004); - cache = false; + jump(R[_PC]); } void BaseV6M::run(int step) {