From 47321ce6164a56d2ca478d0719dec4f3ee1437ec Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Fri, 5 Oct 2012 20:18:11 +0200 Subject: [PATCH] cleaned up MSP430X byte/word/addressword handling and added support for additional instructions --- se/sics/mspsim/core/DbgInstruction.java | 12 ++ se/sics/mspsim/core/DisAsm.java | 31 ++++ se/sics/mspsim/core/MSP430Constants.java | 1 + se/sics/mspsim/core/MSP430Core.java | 181 +++++++++++++---------- se/sics/mspsim/core/Memory.java | 4 +- 5 files changed, 153 insertions(+), 76 deletions(-) diff --git a/se/sics/mspsim/core/DbgInstruction.java b/se/sics/mspsim/core/DbgInstruction.java index 9b059c3..5092ff0 100644 --- a/se/sics/mspsim/core/DbgInstruction.java +++ b/se/sics/mspsim/core/DbgInstruction.java @@ -50,9 +50,16 @@ public class DbgInstruction { private int size; private int pos; + private boolean extWord = false; + public DbgInstruction() { } + + public boolean isExtensionWord() { + return extWord; + } + public void setPos(int p) { pos = p; } @@ -103,4 +110,9 @@ public class DbgInstruction { return getASMLine(); } + + public void setExtWord(boolean b) { + extWord = b; + } + } diff --git a/se/sics/mspsim/core/DisAsm.java b/se/sics/mspsim/core/DisAsm.java index e0e64a8..dda6689 100644 --- a/se/sics/mspsim/core/DisAsm.java +++ b/se/sics/mspsim/core/DisAsm.java @@ -79,6 +79,15 @@ public class DisAsm implements MSP430Constants { System.out.println("//// " + fkn); } System.out.println(dbg.getASMLine()); + + /* Hack for printing the instruction after the ext word... */ + if (dbg.isExtensionWord()) { + pc = pc + 2; + dbg = disassemble(pc, memory, reg, new DbgInstruction(), + interrupt); + System.out.println(dbg.getASMLine()); + } + return dbg; } @@ -128,6 +137,7 @@ public class DisAsm implements MSP430Constants { int srcdata = (instruction & 0x0f00) >> 8; int dst = instruction & 0x000f; int nextData = memory[pc] + (memory[pc + 1] << 8); + boolean rrword = true; switch(op) { case MOVA_IND: @@ -180,6 +190,26 @@ public class DisAsm implements MSP430Constants { case SUBA_REG: opstr = "SUBA R" + srcdata + ",R" + dst; break; + case RRXX_ADDR: + rrword = false; + case RRXX_WORD: + String rrwordStr = rrword ? ".W" : ".A"; + int count = ((instruction >> 10) & 0x03) + 1; // shift amount + switch (instruction & RRMASK) { + case RRCM: + opstr = "RRCM" + rrwordStr + " #" + count + ",R" + dst; + break; + case RRAM: + opstr = "RRAM" + rrwordStr + " #" + count + ",R" + dst; + break; + case RLAM: + opstr = "RLAM" + rrwordStr + " #" + count + ",R" + dst; + break; + case RRUM: + opstr = "RRUM" + rrwordStr + " #" + count + ",R" + dst; + break; + } + break; } output += dumpMem(startPC, size, memory); @@ -311,6 +341,7 @@ public class DisAsm implements MSP430Constants { int dhi = (instruction & EXTWORD_DST); opstr = "ExtWord " + Utils.hex16(instruction) + ":ZC:" + zc + " #:" + rp + " A/L:" + al + " src:" + shi + " dst:" + dhi; + dbg.setExtWord(true); } else { System.out.println("Not implemented instruction: $" + Utils.hex16(instruction) + " at " + Utils.hex16(startPC)); diff --git a/se/sics/mspsim/core/MSP430Constants.java b/se/sics/mspsim/core/MSP430Constants.java index 8097c26..5f30467 100644 --- a/se/sics/mspsim/core/MSP430Constants.java +++ b/se/sics/mspsim/core/MSP430Constants.java @@ -148,6 +148,7 @@ public interface MSP430Constants { public static final int CALLA_MASK = 0xfff0; public static final int CALLA_REG = 0x1340; + public static final int CALLA_INDEX = 0x1350; public static final int CALLA_IND = 0x1360; public static final int CALLA_IND_AUTOINC = 0x1370; public static final int CALLA_ABS = 0x1380; diff --git a/se/sics/mspsim/core/MSP430Core.java b/se/sics/mspsim/core/MSP430Core.java index b0c2c86..c09d87e 100644 --- a/se/sics/mspsim/core/MSP430Core.java +++ b/se/sics/mspsim/core/MSP430Core.java @@ -972,6 +972,7 @@ public class MSP430Core extends Chip implements MSP430Constants { return -2; } int ext3_0 = 0; + int ext10_7 = 0; boolean repeatsInDstReg = false; boolean wordx20 = false; @@ -979,6 +980,7 @@ public class MSP430Core extends Chip implements MSP430Constants { if ((instruction & 0xf800) == 0x1800) { extWord = instruction; ext3_0 = instruction & 0xf; /* bit 3 - 0 - either repeat count or dest 19-16 */ + ext10_7 = (instruction >> 7) & 0xf; /* bit 10 - 7 - src 19-16 */ pc += 2; // Bit 7 in the extension word indicates that the number of // repeats is found in the register pointed to by ext3_0. If @@ -1010,6 +1012,10 @@ public class MSP430Core extends Chip implements MSP430Constants { boolean zeroCarry = false; /* msp430X can zero carry in repeats */ boolean word = (instruction & 0x40) == 0; + /* NOTE: there is a mode when wordx20 = true & word = true that is resereved */ + AccessMode mode = wordx20 ? AccessMode.WORD20 : (word ? AccessMode.WORD : AccessMode.BYTE); + + if (mode == AccessMode.WORD20) System.out.println("WORD20 not really supported..."); // Destination vars int dstRegister = 0; @@ -1041,8 +1047,8 @@ public class MSP430Core extends Chip implements MSP430Constants { switch(op) { // 20 bit register write case MOVA_IND: - /* Read from address in src register, move to destination register. */ - writeRegister(dstData, readRegister(srcData)); + /* Read from address in src register (20-bit?), move to destination register (=20 bit). */ + writeRegister(dstData, currentSegment.read(readRegister(srcData), AccessMode.WORD20, AccessType.READ)); updateStatus = false; cycles += 3; break; @@ -1327,6 +1333,19 @@ public class MSP430Core extends Chip implements MSP430Constants { System.out.println("CALLA REG => " + Utils.hex20(dst)); cycles += 5; break; + case CALLA_INDEX: + /* CALLA X(REG) => REG + X is the address*/ + System.out.println("CALLA INDX: R" + dstRegister); + dst = readRegister(dstRegister); + /* what happens if wrapping here??? */ + System.out.println("CALLA INDX: Reg = " + Utils.hex20(dst) + " Mem: " + + currentSegment.read(pc, AccessMode.WORD, AccessType.READ)); + dst += currentSegment.read(pc, AccessMode.WORD, AccessType.READ); + System.out.println("CALLA INDX => " + Utils.hex20(dst)); + cycles += 5; + pc += 2; +// System.exit(0); + break; case CALLA_IMM: dst = (dstRegister << 16) | currentSegment.read(pc, AccessMode.WORD, AccessType.READ); pc += 2; @@ -1467,7 +1486,7 @@ public class MSP430Core extends Chip implements MSP430Constants { writeRegister(PC, pc); } else { dstAddress = readRegister(dstRegister); - writeRegister(dstRegister, dstAddress + (word ? 2 : 1)); + writeRegister(dstRegister, dstAddress + mode.bytes); // XXX (word ? 2 : 1)); } cycles += 3; break; @@ -1478,13 +1497,16 @@ public class MSP430Core extends Chip implements MSP430Constants { if (dstRegMode) { dst = readRegisterCG(dstRegister, ad); - if (word) { - dst &= 0xffff; - } else if (wordx20) { - dst &= 0xfffff; - } else { - dst &= 0xff; - } +//XXX if (word) { +// dst &= 0xffff; +// } else if (wordx20) { +// dst &= 0xfffff; +// } else { +// dst &= 0xff; +// } + + dst &= mode.mask; + /* set the repeat here! */ if (repeatsInDstReg) { repeats = 1 + readRegister(ext3_0); @@ -1515,13 +1537,14 @@ public class MSP430Core extends Chip implements MSP430Constants { case RRC: nxtCarry = (dst & 1) > 0 ? CARRY : 0; dst = dst >> 1; - if (word) { - dst |= (sr & CARRY) > 0 ? 0x8000 : 0; - } else if (wordx20) { - dst |= (sr & CARRY) > 0 ? 0x80000 : 0; - } else { - dst |= (sr & CARRY) > 0 ? 0x80 : 0; - } + dst |= (sr & CARRY) > 0 ? mode.msb : 0; +//XXX if (word) { +// dst |= (sr & CARRY) > 0 ? 0x8000 : 0; +// } else if (wordx20) { +// dst |= (sr & CARRY) > 0 ? 0x80000 : 0; +// } else { +// dst |= (sr & CARRY) > 0 ? 0x80 : 0; +// } // Indicate write to memory!! write = true; @@ -1535,13 +1558,14 @@ public class MSP430Core extends Chip implements MSP430Constants { break; case RRA: nxtCarry = (dst & 1) > 0 ? CARRY : 0; - if (word) { - dst = (dst & 0x8000) | (dst >> 1); - } else if (wordx20) { - dst = (dst & 0x80000) | (dst >> 1); - } else { - dst = (dst & 0x80) | (dst >> 1); - } + dst = (dst & mode.msb) | dst >> 1; +//XXX if (word) { +// dst = (dst & 0x8000) | (dst >> 1); +// } else if (wordx20) { +// dst = (dst & 0x80000) | (dst >> 1); +// } else { +// dst = (dst & 0x80) | (dst >> 1); +// } write = true; writeRegister(SR, (sr & ~(CARRY | OVERFLOW)) | nxtCarry); break; @@ -1626,13 +1650,14 @@ public class MSP430Core extends Chip implements MSP430Constants { Utils.hex16(instruction)); } if (repeats > 0) { - if (word) { - dst &= 0xffff; - } else if (wordx20) { - dst &= 0xfffff; - } else { - dst &= 0xff; - } +//XXX if (word) { +// dst &= 0xffff; +// } else if (wordx20) { +// dst &= 0xfffff; +// } else { +// dst &= 0xff; +// } + dst &= mode.mask; } } } @@ -1701,13 +1726,14 @@ public class MSP430Core extends Chip implements MSP430Constants { // Some CGs should be handled as registry reads only... if ((srcRegister == CG1 && as > AM_INDEX) || srcRegister == CG2) { src = CREG_VALUES[srcRegister - 2][as]; - if (word) { - src &= 0xffff; - } else if (wordx20) { - src &= 0xfffff; - } else { - src &= 0xff; - } + src &= mode.mask; +//XXX if (word) { +// src &= 0xffff; +// } else if (wordx20) { +// src &= 0xfffff; +// } else { +// src &= 0xff; +// } cycles += dstRegMode ? 1 : 4; } else { switch(as) { @@ -1715,13 +1741,14 @@ public class MSP430Core extends Chip implements MSP430Constants { case AM_REG: // CG handled above! src = readRegister(srcRegister); - if (word) { - src &= 0xffff; - } else if (wordx20) { - src &= 0xfffff; - } else { - src &= 0xff; - } + src &= mode.mask; +//XXX if (word) { +// src &= 0xffff; +// } else if (wordx20) { +// src &= 0xfffff; +// } else { +// src &= 0xff; +// } cycles += dstRegMode ? 1 : 4; /* add cycle if destination register = PC */ if (dstRegister == PC) cycles++; @@ -1776,7 +1803,7 @@ public class MSP430Core extends Chip implements MSP430Constants { cycles += dstRegMode ? 2 : 5; } else { srcAddress = readRegister(srcRegister); - incRegister(srcRegister, word ? 2 : 1); + incRegister(srcRegister, mode.bytes);//XXX word ? 2 : 1); cycles += dstRegMode ? 2 : 5; } /* If destination register is PC another cycle is consumed */ @@ -1791,13 +1818,14 @@ public class MSP430Core extends Chip implements MSP430Constants { if (dstRegMode) { if (op != MOV) { dst = readRegister(dstRegister); - if (word) { - dst &= 0xffff; - } else if (wordx20) { - dst &= 0xfffff; - } else { - dst &= 0xff; - } + dst &= mode.mask; +//XXX if (word) { +// dst &= 0xffff; +// } else if (wordx20) { +// dst &= 0xfffff; +// } else { +// dst &= 0xff; +// } } } else { // PC Could have changed above! @@ -1836,8 +1864,9 @@ public class MSP430Core extends Chip implements MSP430Constants { // System.out.println("SrcAddress is: " + Utils.hex20(srcAddress)); // } // srcAddress = srcAddress & 0xffff; + src = currentSegment.read(srcAddress, mode, AccessType.READ); - src = currentSegment.read(srcAddress, word ? AccessMode.WORD : AccessMode.BYTE, AccessType.READ); +// src = currentSegment.read(srcAddress, word ? AccessMode.WORD : AccessMode.BYTE, AccessType.READ); // if (debug) { // System.out.println("Reading from " + getAddressAsString(srcAddress) + @@ -1906,7 +1935,7 @@ public class MSP430Core extends Chip implements MSP430Constants { break; case CMP: // CMP // Set CARRY if A >= B, and it's clear if A < B - b = word ? 0x8000 : (wordx20 ? 0x80000 : 0x80); + b = mode.msb; sr = (sr & ~(CARRY | OVERFLOW)) | (dst >= src ? CARRY : 0); tmp = (dst - src); @@ -1954,7 +1983,7 @@ public class MSP430Core extends Chip implements MSP430Constants { break; case XOR: // XOR sr = sr & ~(CARRY | OVERFLOW); - b = word ? 0x8000 : (wordx20 ? 0x80000 : 0x80); + b = mode.msb; //word ? 0x8000 : (wordx20 ? 0x80000 : 0x80); if ((src & b) != 0 && (dst & b) != 0) { sr |= OVERFLOW; } @@ -1988,31 +2017,33 @@ public class MSP430Core extends Chip implements MSP430Constants { */ if (repeats > 0 && srcRegister == dstRegister) { src = dst; - if (word) { - src &= 0xffff; - } else if (wordx20) { - src &= 0xfffff; - } else { - src &= 0xff; - } + src &= mode.mask; +//XXX if (word) { +// src &= 0xffff; +// } else if (wordx20) { +// src &= 0xfffff; +// } else { +// src &= 0xff; +// } } } } /* Processing after each instruction */ - if (word) { - dst &= 0xffff; - } else if (wordx20) { - dst &= 0xfffff; - } else { - dst &= 0xff; - } + dst &= mode.mask; +//XXX if (word) { +// dst &= 0xffff; +// } else if (wordx20) { +// dst &= 0xfffff; +// } else { +// dst &= 0xff; +// } if (write) { if (dstRegMode) { writeRegister(dstRegister, dst); } else { dstAddress &= 0xffff; - currentSegment.write(dstAddress, dst, word ? AccessMode.WORD : AccessMode.BYTE); + currentSegment.write(dstAddress, dst, mode); } } if (updateStatus) { @@ -2020,10 +2051,10 @@ public class MSP430Core extends Chip implements MSP430Constants { // Carry and overflow must be set separately! sr = readRegister(SR); sr = (sr & ~(ZERO | NEGATIVE)) | - ((dst == 0) ? ZERO : 0) | - (word ? ((dst & 0x8000) > 0 ? NEGATIVE : 0) : - (wordx20 ? ((dst & 0x80000) > 0 ? NEGATIVE : 0) : - ((dst & 0x80) > 0 ? NEGATIVE : 0))); + ((dst == 0) ? ZERO : 0) | ((dst & mode.msb) > 0 ? NEGATIVE : 0); +//XXX (word ? ((dst & 0x8000) > 0 ? NEGATIVE : 0) : +// (wordx20 ? ((dst & 0x80000) > 0 ? NEGATIVE : 0) : +// ((dst & 0x80) > 0 ? NEGATIVE : 0))); writeRegister(SR, sr); } diff --git a/se/sics/mspsim/core/Memory.java b/se/sics/mspsim/core/Memory.java index ea19683..37ed95d 100644 --- a/se/sics/mspsim/core/Memory.java +++ b/se/sics/mspsim/core/Memory.java @@ -54,12 +54,14 @@ public interface Memory { public final int bytes; public final int bitSize; - public final int mask; + public final int mask; + public final int msb; AccessMode(int bytes, int bitSize, int mask) { this.bytes = bytes; this.bitSize = bitSize; this.mask = mask; + this.msb = 1 << (bitSize - 1); } };