cleaned up MSP430X byte/word/addressword handling and added support for additional instructions

This commit is contained in:
Joakim Eriksson 2012-10-05 20:18:11 +02:00
parent 13eb76ff7e
commit 47321ce616
5 changed files with 153 additions and 76 deletions

View File

@ -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;
}
}

View File

@ -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));

View File

@ -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;

View File

@ -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);
}

View File

@ -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);
}
};