merge of latest MSP430X code for mspsim

This commit is contained in:
Joakim Eriksson 2012-01-31 06:42:21 +01:00
parent a7deb906e7
commit 1b3aa68fba
6 changed files with 794 additions and 116 deletions

View File

@ -42,24 +42,24 @@
package se.sics.mspsim.core;
import se.sics.mspsim.util.Utils;
public class BasicClockModule extends IOUnit {
public class BasicClockModule extends ClockSystem {
public static final int DCOCTL = 0x56; // 0x60
public static final int BCSCTL1 = 0x57; // 0x84
public static final int BCSCTL2 = 0x58;
private static final int DCOCTL = 0x56; // 0x60
private static final int BCSCTL1 = 0x57; // 0x84
private static final int BCSCTL2 = 0x58;
public static final int ACLK_FRQ = 32768;
private static final int ACLK_FRQ = 32768;
// DCO_FRQ what default frq is the DCO running at???
public static final int DCO_FRQ = 2500000;
private static final int DCO_FRQ = 2500000;
// What frequency steps to take for the DCO?
// We have 8 bits + 3 => 11 bits => 2048 combinations...
// => What is lowest frq??? (zero)
// Max speed is 8Mhz (CPU limits it) - is max DCO 8Mhz?
// Based on the scatterweb code it looks like less than
// 5Mhz is more correct...
public static final int MAX_DCO_FRQ = 4915200;
public static final int MIN_DCO_FRQ = 1000;
public static final int DCO_FACTOR = (MAX_DCO_FRQ - MIN_DCO_FRQ) / 2048;
private static final int MAX_DCO_FRQ = 4915200;
private static final int MIN_DCO_FRQ = 1000;
private static final int DCO_FACTOR = (MAX_DCO_FRQ - MIN_DCO_FRQ) / 2048;
private MSP430Core core;
@ -87,7 +87,19 @@ public class BasicClockModule extends IOUnit {
super("BasicClockModule", memory, offset);
this.core = core;
this.timers = timers;
reset(0);
// reset(0);
}
public int getMaxDCOFrequency() {
return MAX_DCO_FRQ;
}
public int getAddressRangeMin() {
return DCOCTL;
}
public int getAddressRangeMax() {
return BCSCTL2;
}
public void reset(int type) {

View File

@ -0,0 +1,54 @@
/**
* Copyright (c) 2011, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of MSPSim.
*
* $Id$
*
* -----------------------------------------------------------------
*
* ClockSystem
*
* Author : Joakim Eriksson
* Created : Sun Oct 21 22:00:00 2007
* Updated : $Date$
* $Revision$
*/
package se.sics.mspsim.core;
public abstract class ClockSystem extends IOUnit {
public abstract int getMaxDCOFrequency();
public abstract int getAddressRangeMin();
public abstract int getAddressRangeMax();
public ClockSystem(String type, int[] memory, int offset) {
super(type, memory, offset);
}
}

View File

@ -27,12 +27,16 @@
*
* This file is part of MSPSim.
*
* $Id$
*
* -----------------------------------------------------------------
*
* MSP430Core
*
* Author : Joakim Eriksson
* Created : Sun Oct 21 22:00:00 2007
* Updated : $Date$
* $Revision$
*/
package se.sics.mspsim.core;
@ -132,7 +136,9 @@ public class MSP430Core extends Chip implements MSP430Constants {
private Flash flash;
boolean isFlashBusy;
ClockSystem bcs;
public void setIO(int adr, IOUnit io, boolean word) {
memOut[adr] = io;
memIn[adr] = io;
@ -224,13 +230,19 @@ public class MSP430Core extends Chip implements MSP430Constants {
timers[i] = t;
}
BasicClockModule bcs = new BasicClockModule(this, memory, 0, timers);
for (int i = 0x56, n = 0x59; i < n; i++) {
// XXX this should be handled by the config, but we do it here to
// avoid changing too much of the mspsim architecture for now
if (MSP430XArch) {
bcs = new UnifiedClockSystem(this, memory, 0, timers);
} else {
bcs = new BasicClockModule(this, memory, 0, timers);
}
for (int i = bcs.getAddressRangeMin(), n = bcs.getAddressRangeMax();
i <= n; i++) {
memOut[i] = bcs;
memIn[i] = bcs;
}
// SFR and Basic clock system.
ioUnits.add(sfr);
ioUnits.add(bcs);
@ -247,6 +259,8 @@ public class MSP430Core extends Chip implements MSP430Constants {
memIn[config.watchdogOffset] = watchdog;
ioUnits.add(watchdog);
bcs.reset(0);
}
public Profiler getProfiler() {
@ -349,7 +363,7 @@ public class MSP430Core extends Chip implements MSP430Constants {
@Deprecated
public boolean hasBreakPoint(int address) {
return watchPoints[address] != null;
return watchPoints[address] != null;
}
@Deprecated
@ -470,7 +484,7 @@ public class MSP430Core extends Chip implements MSP430Constants {
public int incRegister(int r, int value) {
CPUMonitor rm = regReadMonitors[r];
if (rm != null) {
rm.cpuAction(CPUMonitor.REGISTER_READ, r, reg[r]);
rm.cpuAction(CPUMonitor.REGISTER_READ, r, reg[r]);
}
rm = regWriteMonitors[r];
if (rm != null) {
@ -491,11 +505,11 @@ public class MSP430Core extends Chip implements MSP430Constants {
lastVTime = getTime();
lastCyclesTime = cycles;
lastMicrosDelta = 0;
currentDCOFactor = 1.0 * BasicClockModule.MAX_DCO_FRQ / frequency;
// System.out.println("*** DCO: MAX:" + BasicClockModule.MAX_DCO_FRQ +
// " current: " + frequency + " DCO_FAC = " + currentDCOFactor);
currentDCOFactor = 1.0 * bcs.getMaxDCOFrequency() / frequency;
/* System.out.println("*** DCO: MAX:" + bcs.getMaxDCOFrequency() +
" current: " + frequency + " DCO_FAC = " + currentDCOFactor);*/
if (DEBUG)
log("Set smclkFrq: " + smclkFrq);
dcoReset();
@ -521,7 +535,7 @@ public class MSP430Core extends Chip implements MSP430Constants {
// get elapsed time in seconds
public double getTimeMillis() {
return 1000.0 * getTime() / BasicClockModule.MAX_DCO_FRQ;
return 1000.0 * getTime() / bcs.getMaxDCOFrequency();
}
private void executeEvents() {
@ -610,7 +624,8 @@ public class MSP430Core extends Chip implements MSP430Constants {
* @param time
*/
public long scheduleTimeEventMillis(TimeEvent event, double msec) {
long time = (long) (getTime() + msec / 1000 * BasicClockModule.MAX_DCO_FRQ);
/* System.out.println("MAX_DCO " + bcs.getMaxDCOFrequency());*/
long time = (long) (getTime() + msec / 1000 * bcs.getMaxDCOFrequency());
// System.out.println("Scheduling at: " + time + " (" + msec + ") getTime: " + getTime());
scheduleTimeEvent(event, time);
return time;
@ -786,7 +801,7 @@ public class MSP430Core extends Chip implements MSP430Constants {
dstAddress %= MAX_MEM;
}
CPUMonitor wp = watchPoints[dstAddress];
CPUMonitor wp = watchPoints[dstAddress];
if (wp != null) {
wp.cpuAction(CPUMonitor.MEMORY_WRITE, dstAddress, dst);
}
@ -824,7 +839,6 @@ public class MSP430Core extends Chip implements MSP430Constants {
if (wp != null) {
wp.cpuAction(CPUMonitor.MEMORY_WRITE, dstAddress, dst);
}
}
void profileCall(int dst, int pc) {
@ -981,7 +995,7 @@ public class MSP430Core extends Chip implements MSP430Constants {
CPUMonitor wp = watchPoints[pc];
if (wp != null) {
if (breakpointActive) {
wp.cpuAction(CPUMonitor.EXECUTE, pc, 0);
wp.cpuAction(CPUMonitor.EXECUTE, pc, 0);
breakpointActive = false;
return -1;
}
@ -992,15 +1006,33 @@ public class MSP430Core extends Chip implements MSP430Constants {
if (wp != null) {
wp.cpuAction(CPUMonitor.EXECUTE, pc, 0);
}
int pcBefore = pc;
instruction = read(pc, MODE_WORD);
int ext3_0 = 0;
boolean repeatsInDstReg = false;
boolean wordx20 = false;
/* check for extension words */
if ((instruction & 0xf800) == 0x1800) {
extWord = instruction;
ext3_0 = instruction & 0xf; /* bit 3 - 0 - either repeat count or dest 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
// the bit is 0, ext3_0 contains the number of repeats. If the
// bit is 1, ext3_0 contains the register number that holds
// the number of repeats.
if ((instruction & 0x80) == 0x80) {
repeatsInDstReg = true;
}
// Bit 6 indicates whether or not the data length mode should
// be 20 bits. A one means traditional MSP430 mode; a zero
// indicates 20 bit mode. (XXX: there is a reserved data
// length mode if this bit is zero and the MSP430 instruction
// that follows the extension word also has a zero bit data
// length mode.)
wordx20 = (instruction & 0x40) == 0;
instruction = read(pc, MODE_WORD);
// System.out.println("*** Extension word!!! " + Utils.hex16(extWord) +
// " read the instruction too: " + Utils.hex16(instruction) + " at " + Utils.hex16(pc - 2));
@ -1016,6 +1048,7 @@ public class MSP430Core extends Chip implements MSP430Constants {
boolean zeroCarry = false; /* msp430X can zero carry in repeats */
boolean word = (instruction & 0x40) == 0;
// Destination vars
int dstRegister = 0;
int dstAddress = -1;
@ -1040,25 +1073,14 @@ public class MSP430Core extends Chip implements MSP430Constants {
int srcData = (instruction & 0x0f00) >> 8;
int dstData = (instruction & 0x000f);
boolean rrword = true;
switch(op) {
// 20 bit register write
case MOVA_IMM2REG:
src = read(pc, MODE_WORD);
writeRegister(PC, pc += 2);
dst = src + (srcData << 16);
// System.out.println("*** Writing $" + getAddressAsString(dst) + " to reg: " + dstData);
writeRegister(dstData, dst);
updateStatus = false;
break;
case MOVA_ABS2REG:
src = read(pc, MODE_WORD);
writeRegister(PC, pc += 2);
dst = src + (srcData << 16);
//System.out.println(Utils.hex20(pc) + " MOVA &ABS Reading from $" + getAddressAsString(dst) + " to reg: " + dstData);
dst = read(dst, MODE_WORD20);
//System.out.println(" => $" + getAddressAsString(dst));
writeRegister(dstData, dst);
case MOVA_IND:
/* Read from address in src register, move to destination register. */
writeRegister(dstData, readRegister(srcData));
updateStatus = false;
cycles += 3;
break;
case MOVA_IND_AUTOINC:
if (profiler != null && instruction == 0x0110) {
@ -1075,52 +1097,203 @@ public class MSP430Core extends Chip implements MSP430Constants {
// System.out.println("*** Writing $" + getAddressAsString(dst) + " to reg: " + dstData);
writeRegister(dstData, dst);
updateStatus = false;
cycles += 3;
break;
// case CMPA_IMM:
// break;
// case CMPA_REG:
// break;
// case ADDA_IMM - TODO - make both ADDA use the same code.
case ADDA_REG:
src = readRegister(srcData);
dst = readRegister(dstData);
int tmp = (src ^ dst) & 0x80000;
dst = src + dst;
int nxtCarry = (dst & 0x100000) > 0 ? CARRY : 0; /* bit 20 */
dst &= 0xfffff;
case MOVA_ABS2REG:
src = read(pc, MODE_WORD);
writeRegister(PC, pc += 2);
dst = src + (srcData << 16);
//System.out.println(Utils.hex20(pc) + " MOVA &ABS Reading from $" + getAddressAsString(dst) + " to reg: " + dstData);
dst = read(dst, MODE_WORD20);
//System.out.println(" => $" + getAddressAsString(dst));
writeRegister(dstData, dst);
sr = readRegister(SR);
sr = sr & ~(NEGATIVE | OVERFLOW | CARRY | ZERO);
// If tmp == 0 and currenly not the same sign for src & dst
if (tmp == 0 && ((src ^ dst) & 0x80000) != 0) {
sr |= OVERFLOW;
// System.out.println("OVERFLOW - ADD/SUB " + Utils.hex16(src)
// + " + " + Utils.hex16(tmpDst));
}
sr = sr | nxtCarry | (dst == 0 ? ZERO : 0) | ((dst & 0x80000) > 0 ? NEGATIVE : 0);
writeRegister(SR, sr);
updateStatus = false;
cycles += 4;
break;
case MOVA_INDX2REG:
/* Read data from address in memory, indexed by source
* register, and place into destination register. */
int index = read(pc, MODE_WORD);
int indexModifier = readRegister(srcData);
if(index > 0x8000) {
index = -(0x10000 - index);
}
if(indexModifier > 0x8000) {
indexModifier = -(0x10000 - indexModifier);
}
writeRegister(dstData, read(indexModifier + index, MODE_WORD20));
writeRegister(PC, pc += 2);
updateStatus = false;
cycles += 4;
break;
case MOVA_REG2ABS:
dst = read(pc, MODE_WORD);
writeRegister(PC, pc += 2);
write(dst + (dstData << 16), readRegister(srcData), MODE_WORD20);
updateStatus = false;
cycles += 4;
break;
case MOVA_REG2INDX:
/* Read data from register, write to address in memory,
* indexed by source register. */
index = read(pc, MODE_WORD);
indexModifier = readRegister(dstData);
if(index > 0x8000) {
index = -(0x10000 - index);
}
if(indexModifier > 0x8000) {
indexModifier = -(0x10000 - indexModifier);
}
write(indexModifier + index, readRegister(srcData), MODE_WORD20);
writeRegister(PC, pc += 2);
updateStatus = false;
cycles += 4;
break;
case MOVA_IMM2REG:
src = read(pc, MODE_WORD);
writeRegister(PC, pc += 2);
dst = src + (srcData << 16);
// System.out.println("*** Writing $" + getAddressAsString(dst) + " to reg: " + dstData);
writeRegister(dstData, dst);
updateStatus = false;
cycles += 2;
break;
case ADDA_IMM:
// For all immediate instructions, the data low 16 bits of
// the data is stored in the following word (PC + 2) and
// the high 4 bits in the instruction word, which we have
// masked out as srcData.
int immData = read(pc, MODE_WORD) + (srcData << 16);
writeRegister(PC, pc += 2);
dst = readRegister(dstData) + immData;
writeRegister(dstData, dst);
cycles += 3;
break;
case CMPA_IMM:
/* Status Bits N: Set if result is negative (src > dst), reset if positive (src dst)
Z: Set if result is zero (src = dst), reset otherwise (src dst)
C: Set if there is a carry from the MSB, reset otherwise
V: Set if the subtraction of a negative source operand from a positive destination
operand delivers a negative result, or if the subtraction of a positive source
operand from a negative destination operand delivers a positive result, reset
otherwise (no overflow) */
immData = read(pc, MODE_WORD) + (srcData << 16);
writeRegister(PC, pc += 2);
sr = readRegister(SR);
sr &= ~(NEGATIVE | ZERO | CARRY | OVERFLOW);
if (readRegister(dstData) >= immData) {
sr |= CARRY;
}
if (readRegister(dstData) < immData) {
sr |= NEGATIVE;
}
if (readRegister(dstData) == immData) {
sr |= ZERO;
}
int cmpTmp = readRegister(dstData) - immData;
int b = 0x80000; // CMPA always use 20 bit data length
if (((readRegister(dstData) ^ cmpTmp) & b) == 0 &&
(((readRegister(dstData) ^ immData) & b) != 0)) {
sr |= OVERFLOW;
}
writeRegister(SR, sr);
updateStatus = false;
cycles += 3;
break;
case SUBA_IMM:
immData = read(pc, MODE_WORD) + (srcData << 16);
writeRegister(PC, pc += 2);
dst = readRegister(dstData) - immData;
writeRegister(dstData, dst);
cycles += 3;
break;
case MOVA_REG:
cycles += 1;
writeRegister(dstData, readRegister(srcData));
break;
case CMPA_REG:
sr = readRegister(SR);
sr &= ~(NEGATIVE | ZERO | CARRY | OVERFLOW);
if (readRegister(dstData) >= readRegister(srcData)) {
sr |= CARRY;
}
if (readRegister(dstData) < readRegister(srcData)) {
sr |= NEGATIVE;
}
if (readRegister(dstData) == readRegister(srcData)) {
sr |= ZERO;
}
cmpTmp = readRegister(dstData) - readRegister(srcData);
b = 0x80000; // CMPA always use 20 bit data length
if (((readRegister(dstData) ^ cmpTmp) & b) == 0 &&
(((readRegister(dstData) ^ readRegister(srcData)) & b) != 0)) {
sr |= OVERFLOW;
}
writeRegister(SR, sr);
updateStatus = false;
cycles += 1;
break;
case ADDA_REG:
dst = readRegister(dstData) + readRegister(srcData);
writeRegister(dstData, dst);
cycles += 1;
break;
case SUBA_REG:
dst = readRegister(dstData) - readRegister(srcData);
writeRegister(dstData, dst);
cycles += 1;
break;
case RRXX_ADDR:
rrword = false;
case RRXX_WORD:
int count = 1 + (instruction >> 10)& 0x03;
int count = ((instruction >> 10) & 0x03) + 1;
dst = readRegister(dstData);
nxtCarry = 0;
int nxtCarry = 0;
int carry = (readRegister(SR) & CARRY) > 0? 1: 0;
if (rrword) {
dst = dst & 0xffff;
}
cycles += 1 + count;
switch(instruction & RRMASK) {
/* if word zero anything above */
case RRCM:
System.out.println("*** RRCM!!! not implemented");
throw new EmulationException("**** RRCM!! not implemented");
// break;
/* if (rrword): Rotate right through carry the 16-bit CPU register content
if (!rrword): Rotate right through carry the 20-bit CPU register content */
/* Pull the (count) lowest bits from dst - those will
* be placed in the (count) high bits of dst after the
* instruction is complete. */
int dst_low = dst & ((1 << count) - 1);
/* Grab the bit that wlil be in the carry flag when instruction completes. */
nxtCarry = (dst & (1 << (count + 1))) > 0? CARRY: 0;
/* Rotate dst. */
dst = dst >> (count);
/* Rotate the high bits, insert into dst. */
if (rrword) {
dst |= (dst_low << (17 - count)) | (carry << (16 - count));
} else {
dst |= (dst_low << (21 - count)) | (carry << (20 - count));
}
break;
case RRAM:
// System.out.println("RRAM executing");
/* roll in MSB from above */
@ -1134,12 +1307,14 @@ public class MSP430Core extends Chip implements MSP430Constants {
dst = dst >> 1;
break;
case RLAM:
// System.out.println("RLAM executing at " + pc);
/* just roll in "zeroes" from left */
dst = dst << (count - 1);
nxtCarry = (dst & (rrword ? 0x8000 : 0x80000)) > 0 ? CARRY : 0;
dst = dst << 1;
break;
case RRUM:
//System.out.println("RRUM executing");
/* just roll in "zeroes" from right */
dst = dst >> (count - 1);
nxtCarry = (dst & 1) > 0 ? CARRY : 0;
@ -1152,9 +1327,12 @@ public class MSP430Core extends Chip implements MSP430Constants {
writeRegister(dstData, dst);
break;
default:
System.out.println("MSP430X instructions not yet supported: " +
Utils.hex16(instruction));
throw new EmulationException("MSP430X instructions not yet supported...");
System.out.println("MSP430X instruction not yet supported: " +
Utils.hex16(instruction) +
" op " + Utils.hex16(op));
throw new EmulationException("Found unsupported MSP430X instruction " +
Utils.hex16(instruction) +
" op " + Utils.hex16(op));
}
break;
@ -1177,14 +1355,14 @@ public class MSP430Core extends Chip implements MSP430Constants {
case CALLA_IMM:
dst = (dstRegister << 16) | read(pc, MODE_WORD);
pc += 2;
cycles += 4;
cycles += 5;
break;
case CALLA_ABS:
/* read the address of where the address to call is */
dst = (dstRegister << 16) | read(pc, MODE_WORD);
dst = read(dst, MODE_WORD20);
pc += 2;
cycles += 4;
cycles += 7;
break;
default:
int type = MODE_WORD;
@ -1195,6 +1373,7 @@ public class MSP430Core extends Chip implements MSP430Constants {
case PUSHM_A:
type = MODE_WORD20;
size = 4;
cycles += 2;
case PUSHM_W:
int n = 1 + ((instruction >> 4) & 0x0f);
int regNo = instruction & 0x0f;
@ -1205,6 +1384,7 @@ public class MSP430Core extends Chip implements MSP430Constants {
/* decrease stack pointer and write n times */
for(int i = 0; i < n; i++) {
sp -= size;
cycles += 2;
write(sp, this.reg[regNo--], type);
// System.out.println("Saved reg: " + (regNo + 1) + " was " + reg[regNo + 1]);
@ -1216,6 +1396,7 @@ public class MSP430Core extends Chip implements MSP430Constants {
case POPM_A:
type = MODE_WORD20;
size = 4;
cycles += 2;
case POPM_W:
n = 1 + ((instruction >> 4) & 0x0f);
regNo = instruction & 0x0f;
@ -1224,6 +1405,7 @@ public class MSP430Core extends Chip implements MSP430Constants {
/* read and increase stack pointer n times */
for(int i = 0; i < n; i++) {
cycles += 2;
this.reg[regNo++] = read(sp, type);
// System.out.println("Restored reg: " + (regNo - 1) + " to " + reg[regNo - 1]);
sp += size;
@ -1305,7 +1487,7 @@ public class MSP430Core extends Chip implements MSP430Constants {
break;
// Bugfix suggested by Matt Thompson
case AM_IND_AUTOINC:
if(dstRegister == PC) {
if (dstRegister == PC) {
dstAddress = readRegister(PC);
pc += 2;
writeRegister(PC, pc);
@ -1322,15 +1504,19 @@ public class MSP430Core extends Chip implements MSP430Constants {
if (dstRegMode) {
dst = readRegisterCG(dstRegister, ad);
if (!word) {
if (word) {
dst &= 0xffff;
} else if (wordx20) {
dst &= 0xfffff;
} else {
dst &= 0xff;
}
/* set the repeat here! */
if ((extWord & EXTWORD_REPEAT) > 0) {
repeats = 1 + readRegister(ext3_0) & 0xf;
} else {
repeats = 1 + ext3_0;
}
if (repeatsInDstReg) {
repeats = 1 + readRegister(ext3_0);
} else {
repeats = 1 + ext3_0;
}
zeroCarry = (extWord & EXTWORD_ZC) > 0;
// if (repeats > 1) {
@ -1357,9 +1543,12 @@ public class MSP430Core extends Chip implements MSP430Constants {
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;
}
// Indicate write to memory!!
write = true;
// Set the next carry!
@ -1374,6 +1563,8 @@ public class MSP430Core extends Chip implements MSP430Constants {
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);
}
@ -1382,7 +1573,7 @@ public class MSP430Core extends Chip implements MSP430Constants {
break;
case SXT:
// Extend Sign (bit 8-15 => same as bit 7)
dst = (dst & 0x80) > 0 ? dst | 0xff00 : dst & 0x7f;
dst = (dst & 0x80) > 0 ? dst | 0xfff00 : dst & 0x7f;
write = true;
sr = sr & ~(CARRY | OVERFLOW);
if (dst != 0) {
@ -1461,10 +1652,12 @@ public class MSP430Core extends Chip implements MSP430Constants {
Utils.hex16(instruction));
}
if (repeats > 0) {
if (!word) {
dst &= 0xff;
if (word) {
dst &= 0xffff;
} else if (wordx20) {
dst &= 0xfffff;
} else {
dst &= 0xffff;
dst &= 0xff;
}
}
}
@ -1534,7 +1727,11 @@ 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) {
if (word) {
src &= 0xffff;
} else if (wordx20) {
src &= 0xfffff;
} else {
src &= 0xff;
}
cycles += dstRegMode ? 1 : 4;
@ -1544,8 +1741,12 @@ public class MSP430Core extends Chip implements MSP430Constants {
case AM_REG:
// CG handled above!
src = readRegister(srcRegister);
if (!word) {
src &= 0xff;
if (word) {
src &= 0xffff;
} else if (wordx20) {
src &= 0xfffff;
} else {
src &= 0xff;
}
cycles += dstRegMode ? 1 : 4;
/* add cycle if destination register = PC */
@ -1554,11 +1755,12 @@ public class MSP430Core extends Chip implements MSP430Constants {
if (dstRegMode) {
/* possible to have repeat, etc... */
/* TODO: decode the # also */
if ((extWord & EXTWORD_REPEAT) > 0) {
repeats = 1 + readRegister(ext3_0) & 0xf;
} else {
repeats = 1 + ext3_0;
}
if (repeatsInDstReg) {
repeats = 1 + readRegister(ext3_0);
} else {
repeats = 1 + ext3_0;
}
zeroCarry = (extWord & EXTWORD_ZC) > 0;
}
@ -1602,9 +1804,13 @@ public class MSP430Core extends Chip implements MSP430Constants {
if (dstRegMode) {
if (op != MOV) {
dst = readRegister(dstRegister);
if (!word) {
dst &= 0xff;
}
if (word) {
dst &= 0xffff;
} else if (wordx20) {
dst &= 0xfffff;
} else {
dst &= 0xff;
}
}
} else {
// PC Could have changed above!
@ -1689,17 +1895,17 @@ public class MSP430Core extends Chip implements MSP430Constants {
case ADD: // ADD
// Tmp gives zero if same sign! if sign is different after -> overf.
sr &= ~(OVERFLOW | CARRY);
tmp = (src ^ dst) & (word ? 0x8000 : 0x80);
int b = word ? 0x8000 : (wordx20 ? 0x80000 : 0x80);
tmp = (src ^ dst) & b;
// Includes carry if carry should be added...
dst = dst + src + tmpAdd;
if (dst > (word ? 0xffff : 0xff)) {
int b2 = word ? 0xffff : (wordx20 ? 0xfffff : 0xff);
if (dst > b2) {
sr |= CARRY;
}
// If tmp == 0 and currenly not the same sign for src & dst
if (tmp == 0 && ((src ^ dst) & (word ? 0x8000 : 0x80)) != 0) {
if (tmp == 0 && ((src ^ dst) & b) != 0) {
sr |= OVERFLOW;
// System.out.println("OVERFLOW - ADD/SUB " + Utils.hex16(src)
// + " + " + Utils.hex16(tmpDst));
@ -1712,7 +1918,7 @@ public class MSP430Core extends Chip implements MSP430Constants {
break;
case CMP: // CMP
// Set CARRY if A >= B, and it's clear if A < B
int b = word ? 0x8000 : 0x80;
b = word ? 0x8000 : (wordx20 ? 0x80000 : 0x80);
sr = (sr & ~(CARRY | OVERFLOW)) | (dst >= src ? CARRY : 0);
tmp = (dst - src);
@ -1760,7 +1966,8 @@ public class MSP430Core extends Chip implements MSP430Constants {
break;
case XOR: // XOR
sr = sr & ~(CARRY | OVERFLOW);
if ((src & (word ? 0x8000 : 0x80)) != 0 && (dst & (word ? 0x8000 : 0x80)) != 0) {
b = word ? 0x8000 : (wordx20 ? 0x80000 : 0x80);
if ((src & b) != 0 && (dst & b) != 0) {
sr |= OVERFLOW;
}
dst = src ^ dst;
@ -1790,12 +1997,14 @@ public class MSP430Core extends Chip implements MSP430Constants {
/* If we have the same register as dst and src then copy here to get input
* in next loop
*/
if(repeats > 0 && srcRegister == dstRegister) {
if (repeats > 0 && srcRegister == dstRegister) {
src = dst;
if (!word) {
src &= 0xff;
if (word) {
src &= 0xffff;
} else if (wordx20) {
src &= 0xfffff;
} else {
src &= 0xffff;
src &= 0xff;
}
}
}
@ -1804,6 +2013,8 @@ public class MSP430Core extends Chip implements MSP430Constants {
/* Processing after each instruction */
if (word) {
dst &= 0xffff;
} else if (wordx20) {
dst &= 0xfffff;
} else {
dst &= 0xff;
}
@ -1822,7 +2033,8 @@ public class MSP430Core extends Chip implements MSP430Constants {
sr = (sr & ~(ZERO | NEGATIVE)) |
((dst == 0) ? ZERO : 0) |
(word ? ((dst & 0x8000) > 0 ? NEGATIVE : 0) :
((dst & 0x80) > 0 ? NEGATIVE : 0));
(wordx20 ? ((dst & 0x80000) > 0 ? NEGATIVE : 0) :
((dst & 0x80) > 0 ? NEGATIVE : 0)));
writeRegister(SR, sr);
}

View File

@ -0,0 +1,396 @@
/**
* Copyright (c) 2007, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of MSPSim.
*
* $Id$
*
* -----------------------------------------------------------------
*
* UnifiedClockSystem
*
* Author : Joakim Eriksson
* Author : Adam Dunkels
* Created : Sun Oct 21 22:00:00 2007
* Updated : $Date$
* $Revision$
*/
package se.sics.mspsim.core;
import se.sics.mspsim.util.Utils;
public class UnifiedClockSystem extends ClockSystem {
private static final int UCSCTL0 = 0x0160;
private static final int UCSCTL1 = 0x0162;
private static final int UCSCTL2 = 0x0164;
private static final int UCSCTL3 = 0x0166;
private static final int UCSCTL4 = 0x0168;
private static final int UCSCTL5 = 0x016a;
private static final int UCSCTL6 = 0x016c;
private static final int UCSCTL7 = 0x016e;
private static final int UCSCTL8 = 0x0170;
/* UCSCTL0 Control Bits */
// private static final int RESERVED = 0x0001; /* RESERVED */
// private static final int RESERVED = 0x0002; /* RESERVED */
// private static final int RESERVED = 0x0004; /* RESERVED */
private static final int MOD_BITPOS = 3;
private static final int MOD_BITWIDTH = 5;
private static final int MOD0 = 0x0008; /* Modulation Bit Counter Bit : 0 */
private static final int MOD1 = 0x0010; /* Modulation Bit Counter Bit : 1 */
private static final int MOD2 = 0x0020; /* Modulation Bit Counter Bit : 2 */
private static final int MOD3 = 0x0040; /* Modulation Bit Counter Bit : 3 */
private static final int MOD4 = 0x0080; /* Modulation Bit Counter Bit : 4 */
private static final int DCO_BITPOS = 8;
private static final int DCO_BITWIDTH = 5;
private static final int DCO0 = 0x0100; /* DCO TAP Bit : 0 */
private static final int DCO1 = 0x0200; /* DCO TAP Bit : 1 */
private static final int DCO2 = 0x0400; /* DCO TAP Bit : 2 */
private static final int DCO3 = 0x0800; /* DCO TAP Bit : 3 */
private static final int DCO4 = 0x1000; /* DCO TAP Bit : 4 */
// private static final int RESERVED = 0x2000; /* RESERVED */
// private static final int RESERVED = 0x4000; /* RESERVED */
// private static final int RESERVED = 0x8000; /* RESERVED */
/* UCSCTL1 Control Bits */
private static final int DISMOD = 0x0001; /* Disable Modulation */
// private static final int RESERVED = 0x0002; /* RESERVED */
// private static final int RESERVED = 0x0004; /* RESERVED */
// private static final int RESERVED = 0x0008; /* RESERVED */
private static final int DCORSEL_BITPOS = 4;
private static final int DCORSEL_BITWIDTH = 3;
private static final int DCORSEL0 = 0x0010; /* DCO Freq. Range Select Bit : 0 */
private static final int DCORSEL1 = 0x0020; /* DCO Freq. Range Select Bit : 1 */
private static final int DCORSEL2 = 0x0040; /* DCO Freq. Range Select Bit : 2 */
// private static final int RESERVED = 0x0080; /* RESERVED */
// private static final int RESERVED = 0x0100; /* RESERVED */
// private static final int RESERVED = 0x0200; /* RESERVED */
// private static final int RESERVED = 0x0400; /* RESERVED */
// private static final int RESERVED = 0x0800; /* RESERVED */
// private static final int RESERVED = 0x1000; /* RESERVED */
// private static final int RESERVED = 0x2000; /* RESERVED */
// private static final int RESERVED = 0x4000; /* RESERVED */
// private static final int RESERVED = 0x8000; /* RESERVED */
/* UCSCTL2 Control Bits */
private static final int FLLN_BITPOS = 0;
private static final int FLLN_BITWIDTH = 10;
private static final int FLLN0 = 0x0001; /* FLL Multipier Bit : 0 */
private static final int FLLN1 = 0x0002; /* FLL Multipier Bit : 1 */
private static final int FLLN2 = 0x0004; /* FLL Multipier Bit : 2 */
private static final int FLLN3 = 0x0008; /* FLL Multipier Bit : 3 */
private static final int FLLN4 = 0x0010; /* FLL Multipier Bit : 4 */
private static final int FLLN5 = 0x0020; /* FLL Multipier Bit : 5 */
private static final int FLLN6 = 0x0040; /* FLL Multipier Bit : 6 */
private static final int FLLN7 = 0x0080; /* FLL Multipier Bit : 7 */
private static final int FLLN8 = 0x0100; /* FLL Multipier Bit : 8 */
private static final int FLLN9 = 0x0200; /* FLL Multipier Bit : 9 */
// private static final int RESERVED = 0x0400; /* RESERVED */
// private static final int RESERVED = 0x0800; /* RESERVED */
private static final int FLLD_BITPOS = 12;
private static final int FLLD_BITWIDTH = 3;
private static final int FLLD0 = 0x1000; /* Loop Divider Bit : 0 */
private static final int FLLD1 = 0x2000; /* Loop Divider Bit : 1 */
private static final int FLLD2 = 0x4000; /* Loop Divider Bit : 1 */
// private static final int RESERVED = 0x8000; /* RESERVED */
/* UCSCTL3 Control Bits */
private static final int FLLREFDIV_BITPOS = 0;
private static final int FLLREFDIV_BITWIDTH = 3;
private static final int FLLREFDIV0 = 0x0001; /* Reference Divider Bit : 0 */
private static final int FLLREFDIV1 = 0x0002; /* Reference Divider Bit : 1 */
private static final int FLLREFDIV2 = 0x0004; /* Reference Divider Bit : 2 */
// private static final int RESERVED = 0x0008; /* RESERVED */
private static final int SELREF_BITPOS = 4;
private static final int SELREF_BITWIDTH = 3;
private static final int SELREF0 = 0x0010; /* FLL Reference Clock Select Bit : 0 */
private static final int SELREF1 = 0x0020; /* FLL Reference Clock Select Bit : 1 */
private static final int SELREF2 = 0x0040; /* FLL Reference Clock Select Bit : 2 */
// private static final int RESERVED = 0x0080; /* RESERVED */
// private static final int RESERVED = 0x0100; /* RESERVED */
// private static final int RESERVED = 0x0200; /* RESERVED */
// private static final int RESERVED = 0x0400; /* RESERVED */
// private static final int RESERVED = 0x0800; /* RESERVED */
// private static final int RESERVED = 0x1000; /* RESERVED */
// private static final int RESERVED = 0x2000; /* RESERVED */
// private static final int RESERVED = 0x4000; /* RESERVED */
// private static final int RESERVED = 0x8000; /* RESERVED */
/* UCSCTL3 Control Bits */
private static final int FLLREFDIV_0 = 0x0000; /* Reference Divider: f(LFCLK);/1 */
private static final int FLLREFDIV_1 = 0x0001; /* Reference Divider: f(LFCLK);/2 */
private static final int FLLREFDIV_2 = 0x0002; /* Reference Divider: f(LFCLK);/4 */
private static final int FLLREFDIV_3 = 0x0003; /* Reference Divider: f(LFCLK);/8 */
private static final int FLLREFDIV_4 = 0x0004; /* Reference Divider: f(LFCLK);/12 */
private static final int FLLREFDIV_5 = 0x0005; /* Reference Divider: f(LFCLK);/16 */
private static final int FLLREFDIV_6 = 0x0006; /* Reference Divider: f(LFCLK);/16 */
private static final int FLLREFDIV_7 = 0x0007; /* Reference Divider: f(LFCLK);/16 */
private static final int FLLREFDIV__1 = 0x0000; /* Reference Divider: f(LFCLK);/1 */
private static final int FLLREFDIV__2 = 0x0001; /* Reference Divider: f(LFCLK);/2 */
private static final int FLLREFDIV__4 = 0x0002; /* Reference Divider: f(LFCLK);/4 */
private static final int FLLREFDIV__8 = 0x0003; /* Reference Divider: f(LFCLK);/8 */
private static final int FLLREFDIV__12 = 0x0004; /* Reference Divider: f(LFCLK);/12 */
private static final int FLLREFDIV__16 = 0x0005; /* Reference Divider: f(LFCLK);/16 */
private static final int SELREF_0 = 0x0000; /* FLL Reference Clock Select 0 */
private static final int SELREF_1 = 0x0010; /* FLL Reference Clock Select 1 */
private static final int SELREF_2 = 0x0020; /* FLL Reference Clock Select 2 */
private static final int SELREF_3 = 0x0030; /* FLL Reference Clock Select 3 */
private static final int SELREF_4 = 0x0040; /* FLL Reference Clock Select 4 */
private static final int SELREF_5 = 0x0050; /* FLL Reference Clock Select 5 */
private static final int SELREF_6 = 0x0060; /* FLL Reference Clock Select 6 */
private static final int SELREF_7 = 0x0070; /* FLL Reference Clock Select 7 */
private static final int SELREF__XT1CLK = 0x0000; /* Multiply Selected Loop Freq. By XT1CLK */
private static final int SELREF__REFOCLK = 0x0020; /* Multiply Selected Loop Freq. By REFOCLK */
private static final int SELREF__XT2CLK = 0x0050; /* Multiply Selected Loop Freq. By XT2CLK */
/* UCSCTL4 Control Bits */
private static final int SELM0 = 0x0001; /* MCLK Source Select Bit: 0 */
private static final int SELM1 = 0x0002; /* MCLK Source Select Bit: 1 */
private static final int SELM2 = 0x0004; /* MCLK Source Select Bit: 2 */
// private static final int RESERVED = 0x0008; /* RESERVED */
private static final int SELS0 = 0x0010; /* SMCLK Source Select Bit: 0 */
private static final int SELS1 = 0x0020; /* SMCLK Source Select Bit: 1 */
private static final int SELS2 = 0x0040; /* SMCLK Source Select Bit: 2 */
// private static final int RESERVED = 0x0080; /* RESERVED */
private static final int SELA0 = 0x0100; /* ACLK Source Select Bit: 0 */
private static final int SELA1 = 0x0200; /* ACLK Source Select Bit: 1 */
private static final int SELA2 = 0x0400; /* ACLK Source Select Bit: 2 */
// private static final int RESERVED = 0x0800; /* RESERVED */
// private static final int RESERVED = 0x1000; /* RESERVED */
// private static final int RESERVED = 0x2000; /* RESERVED */
// private static final int RESERVED = 0x4000; /* RESERVED */
// private static final int RESERVED = 0x8000; /* RESERVED */
/* UCSCTL4 Control Bits */
private static final int SELM__XT1CLK = 0x0000; /* MCLK Source Select XT1CLK */
private static final int SELM__VLOCLK = 0x0001; /* MCLK Source Select VLOCLK */
private static final int SELM__REFOCLK = 0x0002; /* MCLK Source Select REFOCLK */
private static final int SELM__DCOCLK = 0x0003; /* MCLK Source Select DCOCLK */
private static final int SELM__DCOCLKDIV = 0x0004; /* MCLK Source Select DCOCLKDIV */
private static final int SELM__XT2CLK = 0x0005; /* MCLK Source Select XT2CLK */
private static final int SELS__XT1CLK = 0x0000; /* SMCLK Source Select XT1CLK */
private static final int SELS__VLOCLK = 0x0010; /* SMCLK Source Select VLOCLK */
private static final int SELS__REFOCLK = 0x0020; /* SMCLK Source Select REFOCLK */
private static final int SELS__DCOCLK = 0x0030; /* SMCLK Source Select DCOCLK */
private static final int SELS__DCOCLKDIV = 0x0040; /* SMCLK Source Select DCOCLKDIV */
private static final int SELS__XT2CLK = 0x0050; /* SMCLK Source Select XT2CLK */
private static final int SELA__XT1CLK = 0x0000; /* ACLK Source Select XT1CLK */
private static final int SELA__VLOCLK = 0x0100; /* ACLK Source Select VLOCLK */
private static final int SELA__REFOCLK = 0x0200; /* ACLK Source Select REFOCLK */
private static final int SELA__DCOCLK = 0x0300; /* ACLK Source Select DCOCLK */
private static final int SELA__DCOCLKDIV = 0x0400; /* ACLK Source Select DCOCLKDIV */
private static final int SELA__XT2CLK = 0x0500; /* ACLK Source Select XT2CLK */
/* UCSCTL5 Control Bits */
private static final int DIVM0 = 0x0001; /* MCLK Divider Bit: 0 */
private static final int DIVM1 = 0x0002; /* MCLK Divider Bit: 1 */
private static final int DIVM2 = 0x0004; /* MCLK Divider Bit: 2 */
// private static final int RESERVED = 0x0008; /* RESERVED */
private static final int DIVS_BITPOS = 4;
private static final int DIVS_BITWIDTH = 3;
private static final int DIVS0 = 0x0010; /* SMCLK Divider Bit: 0 */
private static final int DIVS1 = 0x0020; /* SMCLK Divider Bit: 1 */
private static final int DIVS2 = 0x0040; /* SMCLK Divider Bit: 2 */
// private static final int RESERVED = 0x0080; /* RESERVED */
private static final int DIVA0 = 0x0100; /* ACLK Divider Bit: 0 */
private static final int DIVA1 = 0x0200; /* ACLK Divider Bit: 1 */
private static final int DIVA2 = 0x0400; /* ACLK Divider Bit: 2 */
// private static final int RESERVED = 0x0800; /* RESERVED */
private static final int DIVPA0 = 0x1000; /* ACLK from Pin Divider Bit: 0 */
private static final int DIVPA1 = 0x2000; /* ACLK from Pin Divider Bit: 1 */
private static final int DIVPA2 = 0x4000; /* ACLK from Pin Divider Bit: 2 */
// private static final int RESERVED = 0x8000; /* RESERVED */
/* UCSCTL6 Control Bits */
private static final int XT1OFF = 0x0001; /* High Frequency Oscillator 1 (XT1); disable */
private static final int SMCLKOFF = 0x0002; /* SMCLK Off */
private static final int XCAP0 = 0x0004; /* XIN/XOUT Cap Bit: 0 */
private static final int XCAP1 = 0x0008; /* XIN/XOUT Cap Bit: 1 */
private static final int XT1BYPASS = 0x0010; /* XT1 bypass mode : 0: internal 1:sourced from external pin */
private static final int XTS = 0x0020; /* 1: Selects high-freq. oscillator */
private static final int XT1DRIVE0 = 0x0040; /* XT1 Drive Level mode Bit 0 */
private static final int XT1DRIVE1 = 0x0080; /* XT1 Drive Level mode Bit 1 */
private static final int XT2OFF = 0x0100; /* High Frequency Oscillator 2 (XT2); disable */
// private static final int RESERVED = 0x0200; /* RESERVED */
// private static final int RESERVED = 0x0400; /* RESERVED */
// private static final int RESERVED = 0x0800; /* RESERVED */
private static final int XT2BYPASS = 0x1000; /* XT2 bypass mode : 0: internal 1:sourced from external pin */
// private static final int RESERVED = 0x2000; /* RESERVED */
private static final int XT2DRIVE0 = 0x4000; /* XT2 Drive Level mode Bit 0 */
private static final int XT2DRIVE1 = 0x8000; /* XT2 Drive Level mode Bit 1 */
/* UCSCTL7 Control Bits */
private static final int DCOFFG = 0x0001; /* DCO Fault Flag */
private static final int XT1LFOFFG = 0x0002; /* XT1 Low Frequency Oscillator Fault Flag */
private static final int XT1HFOFFG = 0x0004; /* XT1 High Frequency Oscillator 1 Fault Flag */
private static final int XT2OFFG = 0x0008; /* High Frequency Oscillator 2 Fault Flag */
// private static final int RESERVED = 0x0010; /* RESERVED */
// private static final int RESERVED = 0x0020; /* RESERVED */
// private static final int RESERVED = 0x0040; /* RESERVED */
// private static final int RESERVED = 0x0080; /* RESERVED */
// private static final int RESERVED = 0x0100; /* RESERVED */
// private static final int RESERVED = 0x0200; /* RESERVED */
// private static final int RESERVED = 0x0400; /* RESERVED */
// private static final int RESERVED = 0x0800; /* RESERVED */
// private static final int RESERVED = 0x1000; /* RESERVED */
// private static final int RESERVED = 0x2000; /* RESERVED */
// private static final int RESERVED = 0x4000; /* RESERVED */
// private static final int RESERVED = 0x8000; /* RESERVED */
/* UCSCTL8 Control Bits */
private static final int ACLKREQEN = 0x0001; /* ACLK Clock Request Enable */
private static final int MCLKREQEN = 0x0002; /* MCLK Clock Request Enable */
private static final int SMCLKREQEN = 0x0004; /* SMCLK Clock Request Enable */
private static final int MODOSCREQEN = 0x0008; /* MODOSC Clock Request Enable */
// private static final int RESERVED = 0x0010; /* RESERVED */
// private static final int RESERVED = 0x0020; /* RESERVED */
// private static final int RESERVED = 0x0040; /* RESERVED */
// private static final int RESERVED = 0x0080; /* RESERVED */
// private static final int RESERVED = 0x0100; /* RESERVED */
// private static final int RESERVED = 0x0200; /* RESERVED */
// private static final int RESERVED = 0x0400; /* RESERVED */
// private static final int RESERVED = 0x0800; /* RESERVED */
// private static final int RESERVED = 0x1000; /* RESERVED */
// private static final int RESERVED = 0x2000; /* RESERVED */
// private static final int RESERVED = 0x4000; /* RESERVED */
// private static final int RESERVED = 0x8000; /* RESERVED */
private static final int ACLK_FRQ = 32768;
private static final int MAX_DCO_FRQ = 16000000;
private MSP430Core core;
private Timer[] timers;
private int currentDcoFrequency;
/**
* Creates a new <code>UnifiedClockSystem</code> instance.
*
*/
public UnifiedClockSystem(MSP430Core core, int[] memory, int offset, Timer[] timers) {
super("UnifiedClockSystem", memory, offset);
this.core = core;
this.timers = timers;
}
public int getMaxDCOFrequency() {
return MAX_DCO_FRQ;
}
public int getAddressRangeMin() {
return UCSCTL0;
}
public int getAddressRangeMax() {
return UCSCTL8;
}
public void reset(int type) {
// Set the reset states, according to the SLAU208h data sheet.
write(UCSCTL0, 0x0000, true, core.cycles);
write(UCSCTL1, 0x0020, true, core.cycles);
write(UCSCTL2, 0x101f, true, core.cycles);
write(UCSCTL3, 0x0000, true, core.cycles);
write(UCSCTL4, 0x0044, true, core.cycles);
write(UCSCTL5, 0x0000, true, core.cycles);
write(UCSCTL6, 0xc1cd, true, core.cycles);
write(UCSCTL7, 0x0703, true, core.cycles);
write(UCSCTL8, 0x0707, true, core.cycles);
}
// do nothing?
public int read(int address, boolean word, long cycles) {
int val = memory[address];
if (word) {
val |= memory[(address + 1) & 0xffff] << 8;
}
return val;
}
public void write(int address, int data, boolean word, long cycles) {
// Currently ignores the word flag...
if (DEBUG) log("Write to UnifiedClockSystem: " +
Utils.hex16(address) + " => " + Utils.hex16(data));
memory[address] = data & 0xff;
if (word) memory[address + 1] = (data >> 8) & 0xff;
setConfiguration(cycles);
}
public void interruptServiced(int vector) {
}
private void setConfiguration(long cycles) {
// Read a configuration from the UCSCTL* registers and compute the timer setup
// Read Modulation counter and DCO TAP from UCSCTL0 (currently unused)
int modulationBitCounter = ((read(UCSCTL0, true, cycles) >> MOD_BITPOS) & ((1 << MOD_BITWIDTH) - 1));
int dcoTap = ((read(UCSCTL0, true, cycles) >> DCO_BITPOS) & ((1 << DCO_BITWIDTH) - 1));
// Read modulation disable bit (currently unused)
int disableModulation = ((read(UCSCTL1, true, cycles) & DISMOD));
// Read DCO range selection from UCSCTL1 register
int dcoRange = ((read(UCSCTL1, true, cycles) >> DCORSEL_BITPOS) & ((1 << DCORSEL_BITWIDTH) - 1));
// Read DCO FLL multiplier and loop divider from the UCSCTL2 register
int dcoFLLMultiplier = (read(UCSCTL2, true, cycles) >> FLLN_BITPOS) & ((1 << FLLN_BITWIDTH) - 1);
int dcoLoopDivider = (read(UCSCTL2, true, cycles) >> FLLD_BITPOS) & ((1 << FLLD_BITWIDTH) - 1);
// FLL reference clock divider and selection from UCSCTL3 (currently unused)
int fllRefDiv = (read(UCSCTL3, true, cycles) >> FLLREFDIV_BITPOS) & ((1 << FLLREFDIV_BITWIDTH) - 1);
int selRef = (read(UCSCTL3, true, cycles) >> SELREF_BITPOS) & ((1 << SELREF_BITWIDTH) - 1);
// SMCLK divisor
int divSMclk = (read(UCSCTL5, true, cycles) >> DIVS_BITPOS) & ((1 << DIVS_BITWIDTH) - 1);
int newDcoFrequency = (dcoFLLMultiplier + 1) * ACLK_FRQ;
if (newDcoFrequency != currentDcoFrequency) {
currentDcoFrequency = newDcoFrequency;
core.setDCOFrq(currentDcoFrequency, currentDcoFrequency / (1 << divSMclk));
if (timers != null) {
for(int i = 0; i < timers.length; i++) {
timers[i].resetCounter(cycles);
}
}
}
}
}

View File

@ -27,12 +27,16 @@
*
* This file is part of MSPSim.
*
* $Id$
*
* -----------------------------------------------------------------
*
* MapTable
*
* Author : Joakim Eriksson
* Created : Sun Oct 21 22:00:00 2007
* Updated : $Date$
* $Revision$
*/
package se.sics.mspsim.util;
@ -261,7 +265,7 @@ public class MapTable {
int totsize = 0;
int totdata = map.dataFill, totbss = map.bssFill;
int totmemory = totdata + totbss;
System.out.printf("%7s %7s %7s %4s %s\n",
System.out.printf("%6s %6s %6s %4s %s\n",
"text", "data", "bss", "addr", "name");
for (int i = 0; i < map.modules.size(); i++) {
MapEntry module = map.modules.get(i);

View File

@ -47,7 +47,7 @@ public class StackMonitor implements CPUMonitor {
public StackMonitor(MSP430 cpu) {
this.cpu = cpu;
this.cpu.addRegisterWriteMonitor(MSP430.SP, this);
this.cpu.setRegisterWriteMonitor(MSP430.SP, this);
Object p = cpu.getRegistry().getComponent("profiler");
if (p instanceof SimpleProfiler) {
((SimpleProfiler) p).setStackMonitor(this);