mirror of https://github.com/contiki-ng/mspsim
cleaned up MSP430X byte/word/addressword handling and added support for additional instructions
This commit is contained in:
parent
13eb76ff7e
commit
47321ce616
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue