Merge pull request #6 from nfi/PxIV

Bug fixes in the interrupt handling
This commit is contained in:
mspsim 2013-03-15 06:41:47 -07:00
commit b9c9fdd5e4
7 changed files with 84 additions and 78 deletions

View File

@ -76,6 +76,6 @@ public class Button extends Chip {
@Override
public String info() {
return id + ": " + (isPressed ? "pressed" : "released");
return " Button is " + (isPressed ? "pressed" : "not pressed");
}
}

View File

@ -69,9 +69,6 @@ public abstract class Chip implements Loggable, EventSource {
public Chip(String id, MSP430Core cpu) {
this(id, id, cpu);
if (cpu != null) {
logger = cpu.getLogger();
}
}
public Chip(String id, String name, MSP430Core cpu) {

View File

@ -116,9 +116,9 @@ public class IOPort extends IOUnit {
String[] specs = specification.split(",");
int port = specs[0].charAt(1) - '0';
int offset = Integer.parseInt(specs[0].substring(3), 16);
PortReg[] portMap = new PortReg[0x20]; /* Worst case port-map */
int highest = -1;
for (int i = 1; i < specs.length; i++) {
String[] preg = specs[i].split(" ");
PortReg pr = PortReg.valueOf(preg[0]);
@ -127,6 +127,12 @@ public class IOPort extends IOUnit {
portMap = Arrays.copyOf(portMap, offs + 1);
}
portMap[offs] = pr;
if (offs > highest) {
highest = offs;
}
}
if (highest + 1 < portMap.length) {
portMap = Arrays.copyOf(portMap, highest + 1);
}
IOPort newPort = new IOPort(cpu, port, interrupt, cpu.memory, offset, portMap);
if (last != null && offset == last.offset && offset > 0) {
@ -171,7 +177,7 @@ public class IOPort extends IOUnit {
timerCapture[pin] = timer;
}
public void updateIV() {
private void updateIV() {
int bitval = 0x01;
iv = 0;
int ie_ifg = ifg & ie;
@ -183,6 +189,7 @@ public class IOPort extends IOUnit {
bitval = bitval << 1;
}
//System.out.println("*** Setting IV to: " + iv + " ifg: " + ifg);
cpu.flagInterrupt(interrupt, this, (ifg & ie) > 0);
}
public int getRegister(PortReg register) {
@ -216,7 +223,7 @@ public class IOPort extends IOUnit {
}
/* only byte access!!! */
int read_port(PortReg function, long cycles) {
private int readPort(PortReg function, long cycles) {
switch(function) {
case OUT:
return out;
@ -238,18 +245,27 @@ public class IOPort extends IOUnit {
return sel2;
case DS:
return ds;
case IV_L:
return iv & 0xff;
case IV_H:
int v = iv >> 8;
updateIV();
case IV_L: {
int v = iv & 0xff;
// Clear highest interrupt
if (iv != 0) {
if (iv > 1 && iv < 17) {
ifg &= ~(1 << ((iv - 2) / 2));
}
updateIV();
}
return v;
}
case IV_H: {
int v = iv >> 8;
return v;
}
}
/* default is zero ??? */
return 0;
}
void write_port(PortReg function, int data, long cycles) {
private void writePort(PortReg function, int data, long cycles) {
switch(function) {
case OUT: {
out = data;
@ -279,11 +295,10 @@ public class IOPort extends IOUnit {
break;
case IFG:
if (DEBUG) {
log("Clearing IFlag: " + data);
log("Setting IFlag: " + data);
}
ifg &= data;
ifg = data;
updateIV();
cpu.flagInterrupt(interrupt, this, (ifg & ie) > 0);
break;
case IE:
ie = data;
@ -301,15 +316,21 @@ public class IOPort extends IOUnit {
case SEL2:
sel2 = data;
break;
/* Can IV be written ? */
case DS:
ds = data;
break;
case IV_L:
iv = (iv & 0xff00) | data;
// IV can not be written but highest interrupt should be cleared
// on access.
if (iv != 0) {
if (iv > 1 && iv < 17) {
ifg &= ~(1 << ((iv - 2) / 2));
}
updateIV();
}
break;
case IV_H:
iv = (iv & 0x00ff) | (data << 8);
// IV_H can not be written
break;
}
}
@ -319,22 +340,19 @@ public class IOPort extends IOUnit {
PortReg reg = portMap[address - offset];
/* only byte read allowed if not having an ioPair */
if (word && reg == PortReg.IV_L) {
/* Always read low first then high => update on high!!! */
return read_port(reg, cycles) | (read_port(PortReg.IV_H, cycles) << 8);
/* Read hi first then low => update on low!!! */
return (readPort(PortReg.IV_H, cycles) << 8) | readPort(reg, cycles);
} else if (word && ioPair != null) {
/* read same function from both */
return read_port(reg, cycles) | (ioPair.read_port(reg, cycles) << 8);
return readPort(reg, cycles) | (ioPair.readPort(reg, cycles) << 8);
}
/* NOTE: read of PIV might be wrong here - might be word access on IV? */
return read_port(reg, cycles);
return readPort(reg, cycles);
}
public void write(int address, int data, boolean word, long cycles) {
int iAddress = address - offset;
if (iAddress < 0 || iAddress >= portMap.length) {
throw new EmulationException("Writing to illegal IO port address at " + getID() + ": $" + Utils.hex(address, 4));
}
PortReg fun = portMap[iAddress];
if (DEBUG) {
log("Writing to " + getID() + fun +
@ -345,10 +363,10 @@ public class IOPort extends IOUnit {
/* only byte write - need to convert any word write here... */
if (word && ioPair != null) {
write_port(fun, data & 0xff, cycles);
ioPair.write_port(fun, data >> 8, cycles);
writePort(fun, data & 0xff, cycles);
ioPair.writePort(fun, data >> 8, cycles);
} else {
write_port(fun, data, cycles);
writePort(fun, data, cycles);
}
}
@ -370,23 +388,21 @@ public class IOPort extends IOUnit {
// LO/HI transition
if (state == PinState.HI) {
ifg |= bit;
updateIV();
if (DEBUG) {
log("Flagging interrupt (HI): " + bit);
}
updateIV();
}
} else {
// HI/LO transition
if (state == PinState.LOW) {
ifg |= bit;
updateIV();
if (DEBUG) {
log("Flagging interrupt (LOW): " + bit);
}
updateIV();
}
}
// Maybe this is not the only place where we should flag int?
cpu.flagInterrupt(interrupt, this, (ifg & ie) > 0);
}
if (timerCapture[pin] != null) {

View File

@ -36,9 +36,6 @@
*/
package se.sics.mspsim.core;
import java.io.PrintStream;
import se.sics.mspsim.core.EmulationLogger.WarningType;
public abstract class IOUnit implements InterruptHandler, Loggable {
@ -53,11 +50,10 @@ public abstract class IOUnit implements InterruptHandler, Loggable {
private StateChangeListener stateListener;
private int ioState;
protected int logLevel;
protected EmulationLogger logger;
private PrintStream log;
protected boolean DEBUG = false;
protected EmulationLogger logger;
public IOUnit(String id, MSP430Core cpu, int[] memory, int offset) {
this(id, id, cpu, memory, offset);
}
@ -79,8 +75,9 @@ public abstract class IOUnit implements InterruptHandler, Loggable {
@Override
public void setLogLevel(int l) {
logLevel = l;
DEBUG = logLevel == Loggable.DEBUG;
}
public void addStateChangeListener(StateChangeListener listener) {
stateListener = StateChangeListener.Proxy.INSTANCE.add(stateListener, listener);
}

View File

@ -67,8 +67,8 @@ public class WismoteNode extends GenericNode implements PortListener, USARTListe
/* P4.4 - Output: RESET_N to CC2520 */
public static final int CC2520_RESET = 1 << 4;
/* P2.7 - Button */
public static final int BUTTON_PIN = 7;
/* P1.4 - Button */
public static final int BUTTON_PIN = 4;
/* P8.6 - Red (left) led */
private static final int LEDS_CONF_RED2 = 1 << 6;
@ -173,7 +173,7 @@ public class WismoteNode extends GenericNode implements PortListener, USARTListe
throw new EmulationException("Could not setup wismote mote - missing USCI B0");
}
leds = new Leds(cpu, LEDS);
button = new Button("Button", cpu, port2, BUTTON_PIN, true);
button = new Button("Button", cpu, port1, BUTTON_PIN, true);
IOUnit usart = cpu.getIOUnit("USCI A1");
if (usart instanceof USARTSource) {

View File

@ -27,16 +27,12 @@
*
* This file is part of MSPSim.
*
* $Id$
*
* -----------------------------------------------------------------
*
* ELF
*
* Author : Joakim Eriksson
* Created : Sun Oct 21 22:00:00 2007
* Updated : $Date$
* $Revision$
*/
package se.sics.mspsim.util;
@ -54,7 +50,7 @@ import se.sics.mspsim.debug.StabDebug;
public class ELF {
private static final int EI_NIDENT = 16;
// private static final int EI_NIDENT = 16;
private static final int EI_ENCODING = 5;
private static final int[] MAGIC = new int[] {0x7f, 'E', 'L', 'F'};
@ -97,28 +93,22 @@ public class ELF {
/* check if the file exists and is an ELF file */
public static boolean isELF(File file) {
InputStream input = null;
try {
input = new BufferedInputStream(new FileInputStream(file));
InputStream input = new BufferedInputStream(new FileInputStream(file));
for (int i = 0; i < MAGIC.length; i++) {
if (MAGIC[i] != input.read()) {
input.close();
return false;
}
}
input.close();
return true;
} catch(IOException ioe) {
// ignore and return false - this is not an elf.
return false;
} finally {
if (input != null) {
try {
input.close();
} catch (Exception e) {
}
}
}
return true;
}
private void readHeader() throws ELFException {
for (int i = 0; i < MAGIC.length; i++) {
if (elfData[i] != (byte) (MAGIC[i] & 0xff)) {
@ -465,10 +455,10 @@ public class ELF {
addr += symTable.getEntrySize();
}
if (sAddrHighest > 0) {
System.out.printf("Warning: Unable to parse _end symbol. I'm guessing that heap starts at 0x%05x\n", sAddrHighest);
map.setHeapStart(sAddrHighest);
}
if (map.getHeapStart() <= 0 && sAddrHighest > 0) {
System.err.printf("Warning: Unable to parse _end symbol. I'm guessing that heap starts at 0x%05x\n", sAddrHighest);
map.setHeapStart(sAddrHighest);
}
return map;
}
@ -530,26 +520,24 @@ public class ELF {
}
}
public void setPos(int pos) {
this.pos = pos;
}
}
public int getPos() {
public int getPos() {
return pos;
}
}
private static class FileInfo {
public final String name;
public final int start;
public final int end;
class FileInfo {
String name;
int start;
int end;
FileInfo(String name, int start, int end) {
this.name = name;
this.start = start;
this.end = end;
}
FileInfo(String name, int start, int end) {
this.name = name;
this.start = start;
this.end = end;
}
}

View File

@ -248,10 +248,18 @@ public class MapTable {
return -1;
}
public int getStackStart() {
return stackStartAddress;
}
public void setStackStart(int start) {
stackStartAddress = start;
}
public int getHeapStart() {
return heapStartAddress;
}
public void setHeapStart(int start) {
heapStartAddress = start;
}