This commit is contained in:
roy77 2015-09-04 13:19:57 +00:00
commit ed6a521038
37 changed files with 2841 additions and 775 deletions

View File

@ -62,6 +62,7 @@ Z1FIRMWARE = firmware/z1/blink.z1
WISMOTEFIRMWARE = firmware/wismote/blink.wismote
TYNDALLFIRMWARE = firmware/tyndall/blink.tyndall
EXP5438FIRMWARE = firmware/exp5438/testcase-bits.exp5438
MSPEXP430F5438FIRMWARE = firmware/mspexp430f5438/LCDflat.out
else
ESBFIRMWARE = ${FIRMWAREFILE}
SKYFIRMWARE = ${FIRMWAREFILE}
@ -69,6 +70,7 @@ Z1FIRMWARE = ${FIRMWAREFILE}
WISMOTEFIRMWARE = ${FIRMWAREFILE}
TYNDALLFIRMWARE = ${FIRMWAREFILE}
EXP5438FIRMWARE = ${FIRMWAREFILE}
MSPEXP430F5438FIRMWARE = ${FIRMWAREFILE}
endif
ifdef MAPFILE
@ -81,7 +83,7 @@ TIMERTEST := tests/timertest.firmware
SCRIPTS := ${addprefix scripts/,autorun.sc duty.sc}
BINARY := README.txt license.txt CHANGE_LOG.txt images/*.jpg images/*.png firmware/*/*.firmware ${SCRIPTS}
PACKAGES := se/sics/mspsim ${addprefix se/sics/mspsim/,core chip cli config debug platform ${addprefix platform/,esb sky jcreate sentillausb z1 tyndall ti wismote} plugin profiler emulink net ui util extutil/highlight extutil/jfreechart}
PACKAGES := se/sics/mspsim ${addprefix se/sics/mspsim/,core chip cli config debug platform ${addprefix platform/,esb sky jcreate sentillausb z1 tyndall ti MSPEXP430F5438 wismote} plugin profiler emulink net ui util extutil/highlight extutil/jfreechart}
SOURCES := ${wildcard *.java $(addsuffix /*.java,$(PACKAGES))}
@ -122,6 +124,10 @@ $(JARFILE): $(OBJECTS)
%.exp5438: jar
java -jar $(JARFILE) -platform=exp5438 $@ $(ARGS)
%.mspexp5438: jar
java -jar $(JARFILE) -platform=exp5438 $@ $(ARGS)
%.tyndall: jar
java -jar $(JARFILE) -platform=tyndall $@ $(ARGS)
@ -154,6 +160,8 @@ runwismote: compile
runexp5438: compile
$(JAVA) $(JAVAARGS) se.sics.mspsim.platform.ti.Exp5438Node $(EXP5438FIRMWARE) $(MAPARGS) $(ARGS)
runmspexp5438: compile
$(JAVA) $(JAVAARGS) se.sics.mspsim.platform.MSPEXP430F5438.Exp5438Node $(MSPEXP430F5438FIRMWARE) $(MAPARGS) $(ARGS)
test: cputest

Binary file not shown.

BIN
images/MSP-EXP430F5438.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

View File

@ -75,6 +75,9 @@ public class Main {
if ("exp5438".equals(platform)) {
return "se.sics.mspsim.platform.ti.Exp5438Node";
}
if ("mspexp430f5438".equals(platform)) {
return "se.sics.mspsim.platform.MSPEXP430F5438.Exp5438Node";
}
// Try to guess the node type.
return "se.sics.mspsim.platform." + platform + '.'
+ Character.toUpperCase(platform.charAt(0))

View File

@ -31,38 +31,82 @@
package se.sics.mspsim.chip;
import se.sics.mspsim.core.Chip;
import se.sics.mspsim.core.IOPort;
import se.sics.mspsim.core.IOPort.PortReg;
import se.sics.mspsim.core.MSP430Core;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* @author Niclas Finne
*
*/
public class Button extends Chip {
public class Button extends Chip implements ActionListener {
public enum Btn_Typ {
HighOpen, NoOpen
}
private final IOPort port;
private final int pin;
private final boolean polarity;
private boolean isPressed;
private Btn_Typ btnTyp = Btn_Typ.NoOpen;
private javax.swing.Timer waittimer;
public Button(String id, MSP430Core cpu, IOPort port, int pin, boolean polarity) {
super(id, cpu);
this.port = port;
this.pin = pin;
this.polarity = polarity;
this.isPressed = false;
if (this.polarity == false) {
SetState();
}
}
public Button(String id, MSP430Core cpu, IOPort port, int pin,
boolean polarity, Btn_Typ btnTyp) {
this(id,cpu,port,pin,polarity);
this.btnTyp = btnTyp;
waittimer = new javax.swing.Timer(3000, this);
waittimer.stop();
waittimer.setRepeats(false);
}
public boolean isPressed() {
return isPressed;
}
public void setPressed(boolean isPressed) {
if (this.isPressed != isPressed) {
this.isPressed = isPressed;
stateChanged(isPressed ? 1 : 0);
if (DEBUG) log(isPressed ? "pressed" : "released");
port.setPinState(pin, isPressed == polarity ? IOPort.PinState.HI : IOPort.PinState.LOW);
if (this.isPressed != isPressed) {
this.isPressed = isPressed;
boolean isHigh = isPressed ^ (!polarity);
boolean Ren = ((this.port.getRegister(PortReg.REN) & (1 << this.pin)) != 0);
boolean Up_Down = ((this.port.getRegister(PortReg.OUT) & (1 << this.pin)) != 0);
boolean PullUp = Up_Down & Ren;
// if potential open, then wait 3 seconds to change
if (isHigh && (btnTyp == Btn_Typ.HighOpen) && !PullUp) {
waittimer.restart();
} else {
waittimer.stop();
SetState();
}
}
}
public void actionPerformed(ActionEvent e) {
waittimer.stop();
SetState();
}
public void SetState() {
boolean isHigh = this.isPressed ^ (!this.polarity);
stateChanged(this.isPressed ? 1 : 0);
if (DEBUG)
log(this.isPressed ? "pressed" : "released");
port.setPinState(pin, isHigh ? IOPort.PinState.HI : IOPort.PinState.LOW);
}
@Override
public int getConfiguration(int parameter) {
@ -78,4 +122,9 @@ public class Button extends Chip {
public String info() {
return " Button is " + (isPressed ? "pressed" : "not pressed");
}
@Override
public void notifyReset() {
SetState();
}
}

View File

@ -0,0 +1,257 @@
/**
* Copyright (c) 2013, DHBW Cooperative State University Mannheim
* 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.
*
* Author: Rüdiger Heintz <ruediger.heintz@dhbw-mannheim.de>
*/
package se.sics.mspsim.chip;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
import se.sics.mspsim.core.IOPort;
import se.sics.mspsim.core.MSP430;
import se.sics.mspsim.core.PortListener;
import se.sics.mspsim.core.USARTListener;
import se.sics.mspsim.core.USARTSource;
import se.sics.mspsim.core.GenericUSCI;
public class HD66753 implements USARTListener, PortListener, ActionListener {
int[] MacroReadBlockAddress = { 0x74, 0x00, 0x12, 0x77, 0x00, 0x00 };
int[] MacroDrawBlockAdress = { 0x74, 0x00, 0x11, 0x76 };
int[] MacroDrawBlockValue = { 0x74, 0x00, 0x12, 0x76 };
private List<Integer> dataCom = new ArrayList<Integer>();
private MSP430 cpu;
public BufferedImage DisplayImage;
int w = 256;
int h = 110;
int LED_Port;
int LED_Bit;
Rectangle out;
private javax.swing.Timer waittimer;
private HD66753Listener Listen = null;
public HD66753(MSP430 cpu, String USARTUnit, int LED_Port, int LED_Bit,
Rectangle out) {
DisplayImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
int[] initVal = new int[4 * w * h];
for (int i = 0; i < initVal.length; i++) {
initVal[i] = 255 << 24;// Transparent
}
DisplayImage.getRaster().setPixels(0, 0, 256, 110, initVal);
this.cpu = cpu;
this.LED_Port = LED_Port;
this.LED_Bit = LED_Bit;
this.out = out;
GenericUSCI usart = cpu.getIOUnit(GenericUSCI.class, USARTUnit);
usart.addUSARTListener(this);
IOPort port8 = cpu.getIOUnit(IOPort.class, "P" + LED_Port);
port8.addPortListener(this);
waittimer = new javax.swing.Timer(3000, this);
waittimer.stop();
waittimer.setRepeats(false);
}
public synchronized void addListener(HD66753Listener newListener) {
Listen = HD66753ListenerProxy.addListener(Listen, newListener);
}
public synchronized void removeListener(HD66753Listener oldListener) {
Listen = HD66753ListenerProxy.removeListener(Listen, oldListener);
}
public void printCommand(String info, List<Integer> Values) {
StringBuffer buf = new StringBuffer();
for (Integer val : Values) {
buf.append(Integer.toHexString(val));
buf.append(" ");
}
System.out.println(info + ">" + buf.toString());
}
public boolean compareList(int[] Macro, List<Integer> Values) {
if (Values.size() < Macro.length)
return false;
for (int i = 0; i < Macro.length; i++) {
if (Values.get(i) != Macro[i])
return false;
}
return true;
}
public void dataReceived(USARTSource source, int data) {
if (data == 0x74) {
analyseCommand();
dataCom.clear();
}
dataCom.add(data);
}
int Adress = 0;
public void analyseCommand() {
if (compareList(MacroDrawBlockAdress, dataCom)) {
Adress = dataCom.get(4) * 256 + dataCom.get(5);
} else if (compareList(MacroDrawBlockValue, dataCom)) {
int x = (Adress % 32) * 8;
int y = Adress / 32;
for (int i = 4; i < dataCom.size(); i += 2) {
x = x + 8;
int Value = dataCom.get(i) * 256 + dataCom.get(i + 1);
SetPixel(y, x, Value);
}
Listen.displayChanged();
} else {
// printCommand("", dataCom);
}
}
private static int SetInt(byte gray) {
return (((gray == -1) ? 0 : 255) << 24) | 0 | 0 | 0;
}
private void SetPixel(int y, int x, int Value) {
int[] iArray = new int[8];
iArray[0] = SetInt((byte) (255 - ((Value & 0x0003) << 6)));
iArray[1] = SetInt((byte) (255 - ((Value & 0x000C) << 4)));
iArray[2] = SetInt((byte) (255 - ((Value & 0x0030) << 2)));
iArray[3] = SetInt((byte) (255 - ((Value & 0x00C0))));
iArray[4] = SetInt((byte) (255 - ((Value & 0x0300) >> 2)));
iArray[5] = SetInt((byte) (255 - ((Value & 0x0C00) >> 4)));
iArray[6] = SetInt((byte) (255 - ((Value & 0x3000) >> 6)));
iArray[7] = SetInt((byte) (255 - ((Value & 0xC000) >> 8)));
DisplayImage.setRGB(x, y, 8, 1, iArray, 0, 8);
// DisplayImage.getRaster().setPixels(x, y, 2, 1, iArray);
}
void SavetoImage() {
File outputfile = new File("/root/saved.png");
try {
ImageIO.write(DisplayImage, "png", outputfile);
} catch (IOException e) {
e.printStackTrace();
}
}
long old = 0;
long ti = Long.MAX_VALUE / 2;
long tp = Long.MAX_VALUE / 2;
int value = 0;
public void portWrite(IOPort source, int data) {
int curvalue = ((data >> LED_Bit) & 1);
if ((source.getPort() == LED_Port) && (curvalue != value)) {
waittimer.restart();
value = ((data >> LED_Bit) & 1);
if (value == 0) {
ti = cpu.cycles - old;
} else {
tp = cpu.cycles - old;
}
// System.out.println(tp+" "+ti);
old = cpu.cycles;
Listen.displayChanged();
}
}
public void actionPerformed(ActionEvent e) {
waittimer.stop();
if (value == 0) {
ti = 0;
tp = Long.MAX_VALUE;
} else {
ti = Long.MAX_VALUE;
tp = 0;
}
if (Listen != null)
Listen.displayChanged();
}
private double getFrequenz() {
return 1000000.0 / (double) (ti + tp);// 1Mhz Takt
}
private String getText() {
double frequenz = getFrequenz();
String[] Unit = new String[] { "Hz", "kHz", "MHz", "Ghz" };
int i = 0;
if (frequenz == Double.POSITIVE_INFINITY)
return "INFINITY";
while (frequenz > 1000.0) {
frequenz = frequenz / 1000.0;
i++;
}
return String.format("State: %d ti/T=%.2f %.1f" + Unit[i], value, ti
/ (double) (ti + tp), frequenz);
}
public void drawDisplay(Graphics g) {
int background;
if (getFrequenz() < 5) {
background = value * 255;
} else {
background = (int) Math.min(
(double) (255 * 1.1 * ti / (double) (ti + tp)), 255);
}
g.setColor(new Color(background, background, background, 0xff));
g.fillRect(out.x, out.y, out.width, out.height);
g.drawImage(DisplayImage, out.x, out.y, out.x + out.width, out.y
+ out.height, 8, 0, 138 + 8, 110, null);
String txt = getText();
Rectangle2D rectText = g.getFont().getStringBounds(txt,
g.getFontMetrics().getFontRenderContext());
g.setColor(new Color(255, 0, 0, 0xff));
g.drawString(txt, (int) (out.x + out.width - rectText.getWidth()), out.y
+ out.height);
}
}

View File

@ -0,0 +1,36 @@
/**
* Copyright (c) 2013, DHBW Cooperative State University Mannheim
* 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.
*
* Author: Rüdiger Heintz <ruediger.heintz@dhbw-mannheim.de>
*/
package se.sics.mspsim.chip;
public interface HD66753Listener {
public void displayChanged();
}

View File

@ -0,0 +1,92 @@
/**
* Copyright (c) 2013, DHBW Cooperative State University Mannheim
* 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.
*
* Author: Rüdiger Heintz <ruediger.heintz@dhbw-mannheim.de>
*/
package se.sics.mspsim.chip;
import se.sics.mspsim.util.ArrayUtils;
public class HD66753ListenerProxy implements HD66753Listener {
private HD66753Listener[] HD66753Listeners;
public HD66753ListenerProxy(HD66753Listener listen1, HD66753Listener listen2) {
HD66753Listeners = new HD66753Listener[] { listen1, listen2 };
}
public static HD66753Listener addListener(HD66753Listener portListener,
HD66753Listener listener) {
if (portListener == null) {
return listener;
}
if (portListener instanceof HD66753ListenerProxy) {
return ((HD66753ListenerProxy) portListener).add(listener);
}
return new HD66753ListenerProxy(portListener, listener);
}
public static HD66753Listener removeListener(HD66753Listener portListener,
HD66753Listener listener) {
if (portListener == listener) {
return null;
}
if (portListener instanceof HD66753ListenerProxy) {
return ((HD66753ListenerProxy) portListener).remove(listener);
}
return portListener;
}
public HD66753Listener add(HD66753Listener mon) {
HD66753Listeners = ArrayUtils.add(HD66753Listener.class, HD66753Listeners,
mon);
return this;
}
public HD66753Listener remove(HD66753Listener listener) {
HD66753Listener[] listeners = ArrayUtils.remove(HD66753Listeners, listener);
if (listeners == null) {
return null;
}
if (listeners.length == 1) {
return listeners[0];
}
HD66753Listeners = listeners;
return this;
}
@Override
public void displayChanged() {
HD66753Listener[] listeners = this.HD66753Listeners;
for (HD66753Listener l : listeners) {
l.displayChanged();
}
}
}

View File

@ -600,7 +600,7 @@ public class DebugCommands implements CommandBundle {
} else {
int port = context.getArgumentAsInt(0);
stubs = new GDBStubs();
stubs.setupServer(cpu, port);
stubs.setupServer(node,cpu, port,getELF());
}
return 0;
}

View File

@ -0,0 +1,188 @@
/**
* Copyright (c) 2013, DHBW Cooperative State University Mannheim
* 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.
*
* Author: Rüdiger Heintz <ruediger.heintz@dhbw-mannheim.de>
*/
package se.sics.mspsim.config;
import java.util.ArrayList;
import se.sics.mspsim.core.ADC12Plus;
import se.sics.mspsim.core.ClockSystem;
import se.sics.mspsim.core.GenericUSCI;
import se.sics.mspsim.core.IOPort;
import se.sics.mspsim.core.IOUnit;
import se.sics.mspsim.core.MSP430Config;
import se.sics.mspsim.core.MSP430Core;
import se.sics.mspsim.core.Multiplier32;
import se.sics.mspsim.core.PMM;
import se.sics.mspsim.core.SysReg;
import se.sics.mspsim.core.Timer;
import se.sics.mspsim.core.UnifiedClockSystem;
import se.sics.mspsim.core.MSP430Config.MUXConfig;
import se.sics.mspsim.util.Utils;
public class MSP430f5438Config extends MSP430Config {
// NOTE: this MCU also needs to configure
// - positions of all timers (A0, A1, B)
// - memory configuration
// -
private static final String portConfig[] = {
"P1=200,IN 00,OUT 02,DIR 04,REN 06,DS 08,SEL 0A,IV_L 0E,IV_H 0F,IES 18,IE 1A,IFG 1C",
"P2=200,IN 01,OUT 03,DIR 05,REN 07,DS 09,SEL 0B,IV_L 1E,IV_H 1F,IES 19,IE 1B,IFG 1D",
"P3=220,IN 00,OUT 02,DIR 04,REN 06,DS 08,SEL 0A",
"P4=220,IN 01,OUT 03,DIR 05,REN 07,DS 09,SEL 0B",
"P5=240,IN 00,OUT 02,DIR 04,REN 06,DS 08,SEL 0A",
"P6=240,IN 01,OUT 03,DIR 05,REN 07,DS 09,SEL 0B",
"P7=260,IN 00,OUT 02,DIR 04,REN 06,DS 08,SEL 0A",
"P8=260,IN 01,OUT 03,DIR 05,REN 07,DS 09,SEL 0B",
"P9=280,IN 00,OUT 02,DIR 04,REN 06,DS 08,SEL 0A",
"PA=280,IN 01,OUT 03,DIR 05,REN 07,DS 09,SEL 0B",
"PB=2A0,IN 0,OUT 02,DIR 04,REN 06,DS 08,SEL 0A", };
public MSP430f5438Config() {
/* 64 vectors for the MSP430f54xx series */
maxInterruptVector = 63;
MSP430XArch = true;
flashControllerOffset = 0x140;
sfrOffset = 0x100;
MUXConfig[] muxConfigA0= new MUXConfig[] {
new MUXConfig(0, 8, 0, 0),
new MUXConfig(0, 8, 1, 1),
new MUXConfig(0, 8, 2, 2),
new MUXConfig(0, 8, 3, 3),
new MUXConfig(0, 8, 4, 4),
new MUXConfig(0, 1, 1, 0),
new MUXConfig(0, 1, 2, 1),
new MUXConfig(0, 1, 3, 2),
new MUXConfig(0, 1, 4, 3),
new MUXConfig(0, 1, 5, 4)
};
MUXConfig[] muxConfigA1= new MUXConfig[] {
new MUXConfig(0, 8, 5, 0),
new MUXConfig(0, 8, 6, 1),
new MUXConfig(0, 7, 3, 2),
new MUXConfig(0, 2, 1, 0),
new MUXConfig(0, 2, 2, 1),
new MUXConfig(0, 2, 3, 2)
};
MUXConfig[] muxConfigB0= new MUXConfig[] {
new MUXConfig(0, 4, 0, 0),
new MUXConfig(0, 4, 1, 1),
new MUXConfig(0, 4, 2, 2),
new MUXConfig(0, 4, 3, 3),
new MUXConfig(0, 4, 4, 4),
new MUXConfig(0, 4, 5, 5),
new MUXConfig(0, 4, 6, 6)
};
/* configuration for the timers - need to set-up new source maps!!! */
TimerConfig timerA0 = new TimerConfig(54, 53, 5, 0x340, Timer.TIMER_Bx149, TimerType.Standard,
"TimerA0", 0x340 + 0x2e, muxConfigA0);
TimerConfig timerA1 = new TimerConfig(49, 48, 3, 0x380, Timer.TIMER_Ax149, TimerType.Standard,
"TimerA1", 0x380 + 0x2e, muxConfigA1);
TimerConfig timerB0 = new TimerConfig(60, 59, 7, 0x3C0, Timer.TIMER_Bx149, TimerType.TimerEndEdit,
"TimerB0", 0x3C0 + 0x2e, muxConfigB0);
timerConfig = new TimerConfig[] { timerA0, timerA1, timerB0 };
uartConfig = new UARTConfig[] { new UARTConfig("USCI A0", 57, 0x5c0),
new UARTConfig("USCI B0", 56, 0x5e0),
new UARTConfig("USCI A1", 46, 0x600),
new UARTConfig("USCI B1", 45, 0x620),
new UARTConfig("USCI A2", 52, 0x640),
new UARTConfig("USCI B2", 51, 0x660),
new UARTConfig("USCI A3", 44, 0x680),
new UARTConfig("USCI B3", 43, 0x6a0) };
/* configure memory */
infoMemConfig(0x1800, 128 * 4);
mainFlashConfig(0x5c00, 256 * 1024);
ramConfig(0x1c00, 16 * 1024);
ioMemSize(0x800); /* 2 KB of IO Memory */
watchdogOffset = 0x15c;
watchdogVersion = 1;
// bsl, IO, etc at a later stage...
}
public int setup(MSP430Core cpu, ArrayList<IOUnit> ioUnits) {
Multiplier32 mp = new Multiplier32(cpu, cpu.memory, 0x4c0);
cpu.setIORange(0x4c0, 0x2e, mp);
/* this code should be slightly more generic... and be somewhere else... */
for (int i = 0, n = uartConfig.length; i < n; i++) {
GenericUSCI usci = new GenericUSCI(cpu, i, cpu.memory, this);
/* setup 0 - 1f as IO addresses */
cpu.setIORange(uartConfig[i].offset, 0x20, usci);
// System.out.println("Adding IOUnit USCI: " + usci.getName());
ioUnits.add(usci);
}
IOPort last = null;
ioUnits.add(last = IOPort.parseIOPort(cpu, 47, portConfig[0], last));
ioUnits.add(last = IOPort.parseIOPort(cpu, 42, portConfig[1], last));
for (int i = 2; i < portConfig.length; i++) {
ioUnits.add(last = IOPort.parseIOPort(cpu, 0, portConfig[i], last));
}
/* XXX: Stub IO units: Sysreg and PMM */
SysReg sysreg = new SysReg(cpu, cpu.memory);
cpu.setIORange(SysReg.ADDRESS, SysReg.SIZE, sysreg);
ioUnits.add(sysreg);
PMM pmm = new PMM(cpu, cpu.memory, 0x120);
cpu.setIORange(0x120, PMM.SIZE, pmm);
ioUnits.add(pmm);
ADC12Plus adc12 = new ADC12Plus(cpu, ADC12Plus.OFFSET, 55);// 56?
cpu.setIORange(ADC12Plus.OFFSET, ADC12Plus.SIZE, adc12);
ioUnits.add(adc12);
return portConfig.length + uartConfig.length;
}
@Override
public String getAddressAsString(int addr) {
return Utils.hex20(addr);
}
@Override
public ClockSystem createClockSystem(MSP430Core cpu, int[] memory,
Timer[] timers) {
return new UnifiedClockSystem(cpu, memory, 0, timers);
}
}

View File

@ -42,6 +42,15 @@ import se.sics.mspsim.core.EmulationLogger.WarningType;
import se.sics.mspsim.core.Memory.AccessMode;
import se.sics.mspsim.util.Utils;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Flash extends IOUnit {
private static final int FCTL1 = 0x00;
@ -120,6 +129,8 @@ public class Flash extends IOUnit {
private WriteMode currentWriteMode;
private int blockwriteCount;
private String flashSaveFileName = "";
/**
* Infomem Configurations
*/
@ -353,6 +364,7 @@ public class Flash extends IOUnit {
waitFlashProcess(wait_time);
break;
}
writeFile();
}
public void notifyRead(int address) {
@ -620,4 +632,77 @@ public class Flash extends IOUnit {
locked = true;
currentWriteMode = WriteMode.NONE;
}
public void setFile(String FileName) {
flashSaveFileName = FileName;
readFile();
}
public void readFile() {
if (flashSaveFileName.length() > 0) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
try {
File file = new File(flashSaveFileName);
FileInputStream fis = new FileInputStream(file);
for (int readNum; (readNum = fis.read(buf)) != -1;) {
bos.write(buf, 0, readNum);
}
fis.close();
} catch (Exception ex) {
System.out.println("No file "+flashSaveFileName+ " found. Write a new file");
writeFile();
return;
}
byte[] bytes = bos.toByteArray();
int j = 0;
// for (int i = main_range.start; i < main_range.end; i++) {
// memory[i] = bytes[j++] << 24 | (bytes[j++] & 0xFF) << 16
// | (bytes[j++] & 0xFF) << 8 | (bytes[j++] & 0xFF);
// }
for (int i = info_range.start; i < info_range.end; i++) {
memory[i] = bytes[j++] << 24 | (bytes[j++] & 0xFF) << 16
| (bytes[j++] & 0xFF) << 8 | (bytes[j++] & 0xFF);
}
}
}
public void writeFile() {
if (flashSaveFileName.length() > 0) {
File someFile = new File(flashSaveFileName);
FileOutputStream fos;
try {
fos = new FileOutputStream(someFile);
} catch (Exception e) {
return;
}
int size = info_range.end - info_range.start;//+main_range.end - main_range.start;
byte[] All = new byte[size * 4];
int j = 0;
// for (int i = main_range.start; i < main_range.end; i++) {
// All[j++] = (byte) (memory[i] >> 24);
// All[j++] = (byte) (memory[i] >> 16);
// All[j++] = (byte) (memory[i] >> 8);
// All[j++] = (byte) memory[i];
// }
for (int i = info_range.start; i < info_range.end; i++) {
All[j++] = (byte) (memory[i] >> 24);
All[j++] = (byte) (memory[i] >> 16);
All[j++] = (byte) (memory[i] >> 8);
All[j++] = (byte) memory[i];
}
try {
fos.write(All);
fos.flush();
fos.close();
} catch (Exception e) {
return;
}
}
}
}

View File

@ -2,6 +2,8 @@ package se.sics.mspsim.core;
import java.util.ArrayDeque;
import javax.swing.tree.DefaultMutableTreeNode;
import se.sics.mspsim.chip.I2CUnit.I2CData;
@ -469,4 +471,17 @@ public class GenericUSCI extends IOUnit implements DMATrigger, USARTSource {
}
}
public DefaultMutableTreeNode getNode(){ //Collects information and converts them into tree nodes
DefaultMutableTreeNode node = new DefaultMutableTreeNode(getName()); //
DefaultMutableTreeNode UTXIE = new DefaultMutableTreeNode("UTXIE: " + isIEBitsSet(TXIFG)); //
DefaultMutableTreeNode URXIE = new DefaultMutableTreeNode("URXIE: " + isIEBitsSet(RXIFG)); //
DefaultMutableTreeNode UTXIFG = new DefaultMutableTreeNode("UTXIFG: " + ((getIFG() & TXIFG) > 0)); //
DefaultMutableTreeNode URXIFG = new DefaultMutableTreeNode("URXIFG: " + ((getIFG() & RXIFG) > 0)); //
node.add(UTXIE); //
node.add(URXIE); //
node.add(UTXIFG); //
node.add(URXIFG); //
return node; //Returns main nodes
}
}

View File

@ -38,6 +38,8 @@
package se.sics.mspsim.core;
import java.util.Arrays;
import javax.swing.tree.DefaultMutableTreeNode;
import se.sics.mspsim.core.EmulationLogger.WarningType;
import se.sics.mspsim.util.Utils;
@ -76,6 +78,11 @@ public class IOPort extends IOUnit {
private int ren;
private int ds;
private int selValue; /* this value is used for output when sel=1 and sel2=0*/
private int selValue2; /* this value is used for output when sel=1 and sel2=1 */
private int oldPortOut;
private int iv; /* low / high */
private Timer[] timerCapture = new Timer[8];
@ -100,6 +107,9 @@ public class IOPort extends IOUnit {
this.ie = 0;
this.ifg = 0;
this.portMap = portMap;
this.selValue = 0;
this.selValue2 = 0;
this.oldPortOut=CalcPortOut();
// System.out.println("Port " + port + " interrupt vector: " + interrupt);
/* register all the registers from the port-map */
@ -264,15 +274,53 @@ public class IOPort extends IOUnit {
/* default is zero ??? */
return 0;
}
public boolean readPortSel(int Sel, int Pin) {
if (Sel==0)
return ((selValue & (1 << Pin)) != 0);
else
return ((selValue2 & (1 << Pin)) != 0);
}
//Set SelValue and
public void writePortSel(int Sel, int Pin, boolean Value) {
if(Sel==0){
if (!Value) //set or clear bit
selValue = selValue & ~(1 << Pin);
else
selValue = selValue | (1 << Pin);
} else {
if (!Value) //set or clear bit
selValue2 = selValue2 & ~(1 << Pin);
else
selValue2 = selValue2 | (1 << Pin);
}
listenerwrite();
}
private void listenerwrite(){
PortListener listener = portListener;
if (listener != null) {
int newPortOut=CalcPortOut();
if(newPortOut!=oldPortOut){
oldPortOut=newPortOut;
listener.portWrite(this, newPortOut);
}
}
}
private int CalcPortOut(){
int selactive= sel ^ sel2;
int selValCombine= ((sel & selValue) | (sel2 & selValue2 )) & selactive;
int outVal=(~selactive & out);
return (selValCombine | outVal | ~dir ) & 0xff;
}
private void writePort(PortReg function, int data, long cycles) {
switch(function) {
case OUT: {
out = data;
PortListener listener = portListener;
if (listener != null) {
listener.portWrite(this, out | (~dir) & 0xff);
}
listenerwrite();
break;
}
case IN:
@ -283,10 +331,7 @@ public class IOPort extends IOUnit {
dir = data;
PortListener listener = portListener;
if (listener != null) {
// Any output configured pin (pin-bit = 0) should have 1 here?!
// if (name.equals("1"))
// System.out.println(getName() + " write to IOPort via DIR reg: " + Utils.hex8(data));
listener.portWrite(this, out | (~dir) & 0xff);
listenerwrite();
}
break;
}
@ -312,9 +357,11 @@ public class IOPort extends IOUnit {
break;
case SEL:
sel = data;
listenerwrite();
break;
case SEL2:
sel2 = data;
listenerwrite();
break;
case DS:
ds = data;
@ -417,22 +464,17 @@ public class IOPort extends IOUnit {
}
public void reset(int type) {
int oldValue = out | (~dir) & 0xff;
Arrays.fill(pinState, PinState.LOW);
in = 0;
//Arrays.fill(pinState, PinState.LOW);
//in = 0;
dir = 0;
ren = 0;
ifg = 0;
ie = 0;
iv = 0;
sel = 0;
sel2 = 0;
cpu.flagInterrupt(interrupt, this, (ifg & ie) > 0);
PortListener listener = portListener;
int newValue = out | (~dir) & 0xff;
if (oldValue != newValue && listener != null) {
listener.portWrite(this, newValue);
}
listenerwrite();
}
public String info() {
@ -448,4 +490,16 @@ public class IOPort extends IOUnit {
return sb.toString();
}
public DefaultMutableTreeNode getNode(){ //Collects information and converts them into tree nodes
DefaultMutableTreeNode node = new DefaultMutableTreeNode(getName()); //
for (int i = 0, n = portMap.length; i < n; i++){ //
PortReg reg = portMap[i]; //
if (reg != null) { //
DefaultMutableTreeNode child = new DefaultMutableTreeNode(reg+": " + Utils.hex(getRegister(reg), 2)); //
node.add(child); //
} //
} //
return node; //Returns main nodes
}
}

View File

@ -36,6 +36,8 @@
*/
package se.sics.mspsim.core;
import javax.swing.tree.DefaultMutableTreeNode;
import se.sics.mspsim.core.EmulationLogger.WarningType;
public abstract class IOUnit implements InterruptHandler, Loggable {
@ -133,4 +135,8 @@ public abstract class IOUnit implements InterruptHandler, Loggable {
public String info() {
return "* no info";
}
public DefaultMutableTreeNode getNode(){ //Default function returns null, if there are no collectible information
return null; //
} //
}

View File

@ -52,7 +52,7 @@ public class MSP430 extends MSP430Core {
private boolean debug = false;
private boolean running = false;
private boolean isBreaking = false;
private double rate = 2.0;
private double rate = 1.0;
// Debug time - measure cycles
private long lastCycles = 0;
@ -131,12 +131,12 @@ public class MSP430 extends MSP430Core {
/* Just a test to see if it gets down to a reasonable speed */
if (cycles > nextSleep) {
try {
Thread.sleep(100);
Thread.sleep(5);
} catch (Exception e) {
}
// Frequency = 100 * cycles ratio
// Ratio = Frq / 100
nextSleep = cycles + (long)(rate * dcoFrq / 10);
nextSleep = cycles + (long)(rate * dcoFrq / (10*20));
}
// if ((instruction & 0xff80) == CALL) {
@ -156,10 +156,12 @@ public class MSP430 extends MSP430Core {
throw new IllegalStateException("step not possible when CPU is running");
}
setRunning(true);
int trys=0;
try {
while (count > 0 && !isStopping) {
while (count > 0 && !isStopping) {
int pc = emulateOP(-1);
if (pc >= 0) {
trys=0;
count--;
if (execCounter != null) {
execCounter[pc]++;
@ -182,6 +184,10 @@ public class MSP430 extends MSP430Core {
}
}
}
else{
trys++;
if(trys==1000) break;
}
}
} finally {
setRunning(false);

View File

@ -5,7 +5,11 @@ import java.util.ArrayList;
import se.sics.mspsim.util.Utils;
public abstract class MSP430Config {
public enum TimerType {
Standard, TimerEndEdit
}
public static class TimerConfig {
public final int ccr0Vector;
public final int ccrXVector;
@ -14,6 +18,8 @@ public abstract class MSP430Config {
public final String name;
public final int[] srcMap;
public final int timerIVAddr;
public MUXConfig[] muxConfig;
public TimerType typ;
public TimerConfig(int ccr0Vec, int ccrXVec, int ccrCount, int offset,
int[] srcMap, String name, int tiv) {
@ -25,8 +31,34 @@ public abstract class MSP430Config {
this.srcMap = srcMap;
this.timerIVAddr = tiv;
}
public TimerConfig(int ccr0Vec, int ccrXVec, int ccrCount, int offset,
int[] srcMap, TimerType typ, String name, int tiv, MUXConfig[] muxConfig) {
this(ccr0Vec,ccrXVec,ccrCount,offset,srcMap,name,tiv);
this.muxConfig=muxConfig;
this.typ = typ;
}
public TimerConfig(int ccr0Vec, int ccrXVec, int ccrCount, int offset,
int[] srcMap, String name, int tiv, MUXConfig[] muxConfig) {
this(ccr0Vec,ccrXVec,ccrCount,offset,srcMap,name,tiv);
this.muxConfig=muxConfig;
}
}
public static class MUXConfig {
public final int Port;
public final int Pin;
public final int Sel;
public final int CCUnitIndex;
public MUXConfig(int sel, int port, int pin, int cCUnitIndex) {
this.Port = port;
this.Pin = pin;
this.Sel = sel;
this.CCUnitIndex = cCUnitIndex;
}
}
public static class UARTConfig {
private static final int USCI_2 = 1;
private static final int USCI_5 = 2;
@ -98,6 +130,7 @@ public abstract class MSP430Config {
public int sfrOffset = 0;
public int watchdogOffset = 0x120;
public int watchdogVersion = 0;
public abstract int setup(MSP430Core cpu, ArrayList<IOUnit> ioUnits);

View File

@ -245,14 +245,14 @@ public class MSP430Core extends Chip implements MSP430Constants {
ioSegment.setIORange(config.flashControllerOffset, Flash.SIZE, flash);
/* Setup special function registers */
sfr = new SFR(this, memory);
sfr = new SFR(this, memory,config.sfrOffset);
ioSegment.setIORange(config.sfrOffset, 0x10, sfr);
// first step towards making core configurable
Timer[] timers = new Timer[config.timerConfig.length];
for (int i = 0; i < config.timerConfig.length; i++) {
Timer t = new Timer(this, memory, config.timerConfig[i]);
ioSegment.setIORange(config.timerConfig[i].offset, 0x20, t);
ioSegment.setIORange(config.timerConfig[i].offset, 0x22, t);
ioSegment.setIORange(config.timerConfig[i].timerIVAddr, 1, t);
timers[i] = t;
}
@ -271,13 +271,17 @@ public class MSP430Core extends Chip implements MSP430Constants {
ioUnits.add(timers[i]);
}
watchdog = new Watchdog(this, config.watchdogOffset);
watchdog = new Watchdog(this, config.watchdogOffset,config.watchdogVersion);
ioSegment.setIORange(config.watchdogOffset, 1, watchdog);
ioUnits.add(watchdog);
bcs.reset(0);
}
public void setFlashFile(String FileName) {
flash.setFile(FileName);
}
public void setIORange(int address, int range, IOUnit io) {
if (address + range > MAX_MEM_IO) {
@ -721,6 +725,10 @@ public class MSP430Core extends Chip implements MSP430Constants {
vTimeEventQueue.print(out);
}
public Object[] getIOUnits(){
return ioUnits.toArray();
}
// Should also return active units...
public IOUnit getIOUnit(String name) {
for (IOUnit ioUnit : ioUnits) {
@ -966,7 +974,7 @@ public class MSP430Core extends Chip implements MSP430Constants {
// -------------------------------------------------------------------
// Interrupt processing [after the last instruction was executed]
// -------------------------------------------------------------------
if (interruptsEnabled && servicedInterrupt == -1 && interruptMax >= 0) {
if (interruptsEnabled && (servicedInterrupt == -1) && (interruptMax >= 0)) {
pc = serviceInterrupt(pc);
}
@ -1001,6 +1009,7 @@ public class MSP430Core extends Chip implements MSP430Constants {
int pcBefore = pc;
instruction = currentSegment.read(pc, AccessMode.WORD, AccessType.EXECUTE);
if (isStopping) {
// Signaled to stop the execution before performing the instruction
return -2;

View File

@ -67,8 +67,8 @@ public class SFR extends IOUnit {
private boolean[] autoclear = new boolean[64];
private int[] irqTriggeredPos = new int[64];
public SFR(MSP430Core cpu, int[] memory) {
super("SFR", "Special Function Register", cpu, memory, 0);
public SFR(MSP430Core cpu, int[] memory,int offset) {
super("SFR", "Special Function Register", cpu, memory, offset);
reset(0);
}
@ -100,28 +100,30 @@ public class SFR extends IOUnit {
// write a value to the IO unit
public void write(int address, int value, boolean word,
long cycles) {
if (DEBUG) log("write to: " + address + " = " + value);
switch (address) {
int addressRel=address-offset;
if (DEBUG) log("write to: " + addressRel + " = " + value);
switch (addressRel) {
case IE1:
case IE2:
updateIE(address - IE1, value);
updateIE(addressRel - IE1, value);
break;
case IFG1:
case IFG2:
updateIFG(address - IFG1, value);
updateIFG(addressRel - IFG1, value);
break;
case ME1:
case ME2:
updateME(address - ME1, value);
updateME(addressRel - ME1, value);
}
memory[address] = value;
memory[addressRel] = value;
}
// read
// read a value from the IO unit
public int read(int address, boolean word, long cycles) {
if (DEBUG) log("read from: " + address);
switch (address) {
int addressRel=address-offset;
if (DEBUG) log("read from: " + addressRel);
switch (addressRel) {
case IE1:
return ie1;
case IE2:
@ -135,7 +137,7 @@ public class SFR extends IOUnit {
case ME2:
return me2;
default:
return memory[address];
return memory[addressRel];
}
}

File diff suppressed because it is too large Load Diff

View File

@ -52,15 +52,15 @@ public class Watchdog extends IOUnit implements SFRModule {
private static final int WDTHOLD = 0x80;
private static final int WDTCNTCL = 0x08;
private static final int WDTMSEL = 0x10;
private static final int WDTSSEL = 0x04;
private static final int WDTISx = 0x03;
private static int WDTSSEL = 0x04;
private static int WDTISx = 0x03;
private static final int WATCHDOG_VECTOR = 10;
private static int WATCHDOG_VECTOR = 10;
private static final int WATCHDOG_INTERRUPT_BIT = 0;
private static final int WATCHDOG_INTERRUPT_VALUE = 1 << WATCHDOG_INTERRUPT_BIT;
private static final int[] DELAY = {
32768, 8192, 512, 64
2*1024*1024*1024,128*1024*1024,8*1024*1024,512*1024,32768, 8192, 512, 64
};
private int resetVector = 15;
@ -88,13 +88,21 @@ public class Watchdog extends IOUnit implements SFRModule {
}
};
public Watchdog(MSP430Core cpu, int address) {
public Watchdog(MSP430Core cpu, int address, int version) {
super("Watchdog", cpu, cpu.memory, address);
if (version!=0){
WDTSSEL = 0x20;
WDTISx = 0x07;
WATCHDOG_VECTOR = 58;
}
resetVector = cpu.MAX_INTERRUPT;
this.offset = address;
cpu.getSFR().registerSFDModule(0, WATCHDOG_INTERRUPT_BIT, this, WATCHDOG_VECTOR);
}
public void interruptServiced(int vector) {
@ -112,8 +120,8 @@ public class Watchdog extends IOUnit implements SFRModule {
SFR sfr = cpu.getSFR();
sfr.setBitIFG(0, WATCHDOG_INTERRUPT_VALUE);
scheduleTimer();
System.out.println("WDT trigger - will set interrupt flag (no reset)");
cpu.generateTrace(System.out);
//System.out.println("WDT trigger - will set interrupt flag (no reset)");
//cpu.generateTrace(System.out);
} else {
System.out.println("WDT trigger - will reset node!");
cpu.generateTrace(System.out);
@ -135,10 +143,12 @@ public class Watchdog extends IOUnit implements SFRModule {
wdtOn = (value & 0x80) == 0;
// boolean lastACLK = sourceACLK;
sourceACLK = (value & WDTSSEL) != 0;
if ((value & WDTCNTCL) != 0) {
//scheduleTimer should use the current delay, so update delay each time
//issue: if WDTCNTCL is not active the timer should be recalculated but an new timer is scheduled
//if ((value & WDTCNTCL) != 0) {
// Clear timer => reset the delay
delay = DELAY[value & WDTISx];
}
delay = DELAY[value & WDTISx];
//}
timerMode = (value & WDTMSEL) != 0;
// Start it if it should be started!
if (wdtOn) {

View File

@ -437,6 +437,28 @@ public class DwarfReader implements ELFDebug {
} while (pos < sec.getSize());
}
public int getPC(String FileName,int line) {
for (int i = 0; i < lineInfo.size(); i++) {
LineData data = lineInfo.get(i);
int start = data.lineEntries[0].address;
/* XXX ignore all line entries starting on address 0 */
if (start == 0) continue;
for (int j = 0; j < data.lineEntries.length; j++) {
LineEntry lineEntry = data.lineEntries[j];
if(lineEntry.line==line){
String FileName2=data.sourceFiles[lineEntry.file-1];
if(FileName2.equals(FileName)){
return lineEntry.address;
}
}
}
}
return -1;
}
/* Access methods for data... */
public DebugInfo getDebugInfo(int address) {
for (int i = 0; i < lineInfo.size(); i++) {

View File

@ -118,6 +118,9 @@ public class StabDebug implements ELFDebug {
return files.toArray(new StabFile[files.size()]);
}
public int getPC(String FileName,int line) {
return -1;
}
/* Just pick up file + some other things */
public DebugInfo getDebugInfo(int address) {

View File

@ -41,10 +41,13 @@
package se.sics.mspsim.extutil.highlight;
import java.awt.Color;
import java.awt.Container;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
@ -52,22 +55,32 @@ import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import se.sics.mspsim.core.MSP430;
import se.sics.mspsim.core.MemoryMonitor;
import se.sics.mspsim.core.Memory.AccessMode;
import se.sics.mspsim.core.Memory.AccessType;
import se.sics.mspsim.ui.SourceViewer;
import se.sics.mspsim.ui.WindowUtils;
import se.sics.mspsim.util.ELF;
/**
*
*/
public class HighlightSourceViewer implements SourceViewer {
private ELF elfData;
private MSP430 cpu;
private MemoryMonitor monitor;
private JFrame window;
private SyntaxHighlighter highlighter;
private String currentFile;
private ArrayList<File> path = null;
private JFileChooser fileChooser;
public HighlightSourceViewer() {
//
public HighlightSourceViewer(MSP430 cpu,ELF elfData) {
this.elfData=elfData;
this.cpu=cpu;
}
private void setup() {
@ -77,9 +90,10 @@ public class HighlightSourceViewer implements SourceViewer {
LineNumberedBorder border = new LineNumberedBorder(LineNumberedBorder.LEFT_SIDE, LineNumberedBorder.RIGHT_JUSTIFY);
border.setSeparatorColor(Color.lightGray);
Scanner scanner = new CScanner();
highlighter = new SyntaxHighlighter(24, 120, scanner);
highlighter = new SyntaxHighlighter(24, 200, scanner);
highlighter.setEditable(false);
highlighter.setBorder(border);
JScrollPane scroller = new JScrollPane(highlighter);
@ -97,9 +111,63 @@ public class HighlightSourceViewer implements SourceViewer {
if (searchPath != null) {
addEnvPath(searchPath);
}
setMonitor();
MouseAdapter mouseListener = new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
int sourceLine=highlighter.getLine(highlighter.viewToModel(e.getPoint()))+1;
int asmLine=elfData.getPC(currentFile, sourceLine);
if(asmLine!=-1)editBreakpoint(asmLine);
setBreakpointList();
}
}
};
highlighter.addMouseListener(mouseListener);
}
}
private void setMonitor(){
monitor = new MemoryMonitor.Adapter() {
private long lastCycles = -1;
@Override
public void notifyReadBefore(int address, AccessMode mode, AccessType type) {
if (type == AccessType.EXECUTE && cpu.cycles != lastCycles) {
cpu.triggBreakpoint();
lastCycles = cpu.cycles;
}
}
};
}
public void setBreakpointList(){
List<Integer> BreakList = new ArrayList<Integer>();
for(int i=0;i<highlighter.getLineCount();i++){
int asmLine=elfData.getPC(currentFile, i+1);
if(asmLine>0){
if(cpu.hasWatchPoint(asmLine)){
BreakList.add(i);
}
}
}
Integer[] result = new Integer[BreakList.size()];
result=BreakList.toArray(result);
highlighter.setBreakpointList(result);
}
private void editBreakpoint(int pos){
if (cpu.hasWatchPoint(pos)) {
cpu.removeWatchPoint(pos, monitor);
}else{
cpu.addWatchPoint(pos, monitor);
}
}
private void addEnvPath(String searchPath) {
String[] p = searchPath.split(File.pathSeparator);
if (p != null) {
@ -117,21 +185,21 @@ public class HighlightSourceViewer implements SourceViewer {
setup();
window.setVisible(isVisible);
}
public void viewFile(final String path, final String filename) {
public void viewFile(final String path, final String filename,final boolean useChooser) {
if (filename.equals(currentFile)) {
// Already showing this file
return;
}
currentFile = filename;
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
setup();
File file = findSourceFile(path, filename);
File file = findSourceFile(path, filename,useChooser);
if (file != null) {
currentFile = filename;
setup();
FileReader reader = new FileReader(file);
try {
highlighter.read(reader, null);
@ -159,9 +227,11 @@ public class HighlightSourceViewer implements SourceViewer {
if (highlighter != null) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
highlighter.viewLine(line - 1);
if (!window.isVisible()) {
window.setVisible(true);
if (highlighter.getDocument().getLength()>0){
highlighter.viewLine(line - 1);
if (!window.isVisible()) {
window.setVisible(true);
}
}
}
});
@ -181,7 +251,7 @@ public class HighlightSourceViewer implements SourceViewer {
}
}
private File findSourceFile(String fPath, String filename) {
private File findSourceFile(String fPath, String filename, boolean useChooser) {
File fp = new File(fPath, filename);
if (fp.exists()) {
return fp;
@ -207,22 +277,24 @@ public class HighlightSourceViewer implements SourceViewer {
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
fileChooser.setDialogTitle("Select compilation directory");
}
if (!window.isVisible()) {
window.setVisible(true);
}
if (useChooser){
if (!window.isVisible()) {
window.setVisible(true);
}
if (fileChooser.showOpenDialog(window) == JFileChooser.APPROVE_OPTION) {
File d = fileChooser.getSelectedFile();
if (d != null) {
path.add(d);
return findSourceFile(fPath, filename);
return findSourceFile(fPath, filename, useChooser);
}
}
}
return null;
}
public static void main(String[] args) {
HighlightSourceViewer sv = new HighlightSourceViewer();
sv.setVisible(true);
sv.viewFile(".", args[0]);
// HighlightSourceViewer sv = new HighlightSourceViewer();
// sv.setVisible(true);
// sv.viewFile(".", args[0]);
}
}

View File

@ -22,7 +22,9 @@ public class SyntaxHighlighter extends JTextPane implements DocumentListener, To
private Scanner scanner;
private int rows, columns;
private int currentY, currentHeight = -1;
private int currentY_Select, currentHeight = -1;
private int currentY_PC=-1;
private Integer [] BreakPointList=null;
/**
* Create a graphics component which displays text with syntax highlighting.
@ -48,14 +50,14 @@ public class SyntaxHighlighter extends JTextPane implements DocumentListener, To
try {
Rectangle r = getUI().modelToView(SyntaxHighlighter.this, caret);
if (currentHeight > 0) {
repaint(0, currentY, getWidth(), currentHeight);
repaint(0, currentY_Select, getWidth(), currentHeight);
}
if (r != null && r.height > 0) {
currentY = r.y;
currentHeight = r.height;
currentY_Select = r.y;
//currentHeight = r.height;
repaint(0, r.y, getWidth(), r.height);
} else {
currentHeight = -1;
//currentHeight = -1;
}
} catch (BadLocationException e1) {
@ -90,6 +92,7 @@ public class SyntaxHighlighter extends JTextPane implements DocumentListener, To
Dimension size = new Dimension(paneWidth, paneHeight);
setMinimumSize(size);
setPreferredSize(size);
currentHeight=metrics.getHeight();
invalidate();
}
@ -181,6 +184,17 @@ public class SyntaxHighlighter extends JTextPane implements DocumentListener, To
}
return root.getElement(line).getStartOffset();
}
public int getLine(int Offset) {
Element root = getDocument().getDefaultRootElement();
for(int i=0;i<getLineCount();i++){
if( (root.getElement(i).getStartOffset()<=Offset)&
(root.getElement(i).getEndOffset()>=Offset)){
return i;
}
}
return getLineCount();
}
public int getLineEndOffset(int line) {
Element root = getDocument().getDefaultRootElement();
@ -189,7 +203,11 @@ public class SyntaxHighlighter extends JTextPane implements DocumentListener, To
}
return root.getElement(line).getEndOffset();
}
public void setBreakpointList(Integer [] List){
BreakPointList=List;
repaint();
}
/**
* <font style='color:gray;'>Ignore this method. Responds to the underlying
@ -230,18 +248,29 @@ public class SyntaxHighlighter extends JTextPane implements DocumentListener, To
private int smallAmount = 100;
private Color highlightColor = new Color(0, 240, 0, 255);
private Color highlightColorSelect = new Color(0, 240, 0, 255);
private Color highlightColorBreakpoint = new Color(0, 0, 240, 255);
private Color highlightColorPC = new Color(240, 0, 0, 255);
/**
* <font style='color:gray;'>Ignore this method. Carries out a small amount of
* re-highlighting for each call to <code>repaint</code>.</font>
*/
protected void paintComponent(Graphics g) {
if (currentHeight > 0) {
g.setColor(highlightColor);
g.fillRect(0, currentY, getWidth(), currentHeight);
}
// g.setColor(highlightColorSelect);
// g.fillRect(0, currentY_Select, getWidth(), currentHeight);
if(BreakPointList!=null){
for( int k: BreakPointList ){
g.setColor(highlightColorBreakpoint);
g.fillRect(0, k*currentHeight, getWidth(), currentHeight);
}
}
if(currentY_PC>0){
g.setColor(highlightColorPC);
g.fillRect(0, currentY_PC*currentHeight, getWidth(), currentHeight);
}
super.paintComponent(g);
@ -281,7 +310,11 @@ public class SyntaxHighlighter extends JTextPane implements DocumentListener, To
}
public void viewLine(int line) {
if (line >= 0 && line < getLineCount()) {
if(line<0){
currentY_PC=-1;
repaint();
}
else if (line < getLineCount()) {
try {
int pos = getLineStartOffset(line);
@ -295,8 +328,10 @@ public class SyntaxHighlighter extends JTextPane implements DocumentListener, To
}
scrollRectToVisible(vr);
}
setCaretPosition(pos);
currentY_PC=line;
repaint();
//setCaretPosition(pos);
} catch (BadLocationException e1) {
// Ignore
}

View File

@ -132,6 +132,8 @@ public abstract class AbstractNodeGUI extends JComponent implements ServiceCompo
status = Status.STARTED;
window.setVisible(true);
window.setAlwaysOnTop(true);
window.setExitOnClose();
}
private URL getImageURL(String image) {

View File

@ -162,7 +162,7 @@ public abstract class GenericNode extends Chip implements Runnable {
ControlUI control = new ControlUI();
registry.registerComponent("controlgui", control);
registry.registerComponent("stackchart", new StackUI(cpu));
HighlightSourceViewer sourceViewer = new HighlightSourceViewer();
HighlightSourceViewer sourceViewer = new HighlightSourceViewer(cpu,elf);
// Add the firmware location to the search path
File fp = new File(firmwareFile).getParentFile();
if (fp != null) {

View File

@ -0,0 +1,172 @@
/**
* Copyright (c) 2013, DHBW Cooperative State University Mannheim
* 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.
*
* Author: Rüdiger Heintz <ruediger.heintz@dhbw-mannheim.de>
*/
package se.sics.mspsim.platform.MSPEXP430F5438;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import se.sics.mspsim.core.StateChangeListener;
import se.sics.mspsim.platform.AbstractNodeGUI;
public class Exp5438Gui extends AbstractNodeGUI {
private static final long serialVersionUID = 7753659717805292786L;
public static final Point Button1_Pos = new Point(400, 463);
public static final Point Button2_Pos = new Point(500, 463);
public static final Point ButtonR_Pos = new Point(325, 84);
public static final Point JoyL_Pos = new Point(103, 441);
public static final Point JoyM_Pos = new Point(123, 441);
public static final Point JoyR_Pos = new Point(143, 441);
public static final Point JoyT_Pos = new Point(123, 421);
public static final Point JoyB_Pos = new Point(123, 461);
public static Boolean ButtonR_Pressed = false;
public static int ButtonSize=10;
public static final int LEDR_X = 238;
public static final int LEDR_Y = 462;
public static final int LEDO_X = 294;
public static final int LEDO_Y = 462;
public static final Color LEDR_TRANS = new Color(0x80, 0x80, 0xff, 0xff);
public static final Color LEDO_TRANS = new Color(0x80, 0x80, 0xff, 0xff);
public static final Color LEDO_C = new Color(0xff, 0x8C, 0x00, 0xff);
public static final Color LEDR_C = new Color(0xf0, 0x10, 0x10, 0xff);
private final Exp5438Node node;
private final StateChangeListener ledsListener = new StateChangeListener() {
public void stateChanged(Object source, int oldState, int newState) {
repaint();
}
};
public Exp5438Gui(Exp5438Node node) {
super("MSPSIM fork by Prof. Rüdiger Heintz 0.4.13", "images/MSP-EXP430F5438.jpg");
this.node = node;
}
protected boolean isIn(Point mouse, Point btn) {
if (mouse.y > (btn.y - ButtonSize) && mouse.y < (btn.y + ButtonSize)) {
if (mouse.x > (btn.x - ButtonSize) && mouse.x < (btn.x + ButtonSize)) {
return true;
}
}
return false;
}
protected void startGUI() {
MouseAdapter mouseHandler = new MouseAdapter() {
public void mousePressed(MouseEvent e) {
if (isIn(e.getPoint(), Button1_Pos)) {
Exp5438Gui.this.node.button1.setPressed(true);
} else if (isIn(e.getPoint(), Button2_Pos)) {
Exp5438Gui.this.node.button2.setPressed(true);
} else if (isIn(e.getPoint(), JoyL_Pos)) {
Exp5438Gui.this.node.joyl.setPressed(true);
} else if (isIn(e.getPoint(), JoyM_Pos)) {
Exp5438Gui.this.node.joym.setPressed(true);
} else if (isIn(e.getPoint(), JoyR_Pos)) {
Exp5438Gui.this.node.joyr.setPressed(true);
} else if (isIn(e.getPoint(), JoyT_Pos)) {
Exp5438Gui.this.node.joyt.setPressed(true);
} else if (isIn(e.getPoint(), JoyB_Pos)) {
Exp5438Gui.this.node.joyb.setPressed(true);
} else if (isIn(e.getPoint(), ButtonR_Pos)) {
ButtonR_Pressed=true;
}
repaint();
}
public void mouseReleased(MouseEvent e) {
Exp5438Gui.this.node.button1.setPressed(false);
Exp5438Gui.this.node.button2.setPressed(false);
Exp5438Gui.this.node.joyl.setPressed(false);
Exp5438Gui.this.node.joym.setPressed(false);
Exp5438Gui.this.node.joyr.setPressed(false);
Exp5438Gui.this.node.joyt.setPressed(false);
Exp5438Gui.this.node.joyb.setPressed(false);
ButtonR_Pressed=false;
if (isIn(e.getPoint(), ButtonR_Pos)) {
Exp5438Gui.this.node.getCPU().reset();
}
repaint();
}
};
this.addMouseListener(mouseHandler);
node.leds.addStateChangeListener(ledsListener);
}
protected void paintComponent(Graphics g) {
Color old = g.getColor();
super.paintComponent(g);
g.setColor(new Color(0,0,0,128));
if(this.node.button1.isPressed()) g.fillRect(Button1_Pos.x-ButtonSize, Button1_Pos.y-ButtonSize, 2*ButtonSize, 2*ButtonSize);
if(this.node.button2.isPressed()) g.fillRect(Button2_Pos.x-ButtonSize, Button2_Pos.y-ButtonSize, 2*ButtonSize, 2*ButtonSize);
if(this.node.joyl.isPressed()) g.fillRect(JoyL_Pos.x-ButtonSize, JoyL_Pos.y-ButtonSize, 2*ButtonSize, 2*ButtonSize);
if(this.node.joym.isPressed()) g.fillRect(JoyM_Pos.x-ButtonSize, JoyM_Pos.y-ButtonSize, 2*ButtonSize, 2*ButtonSize);
if(this.node.joyr.isPressed()) g.fillRect(JoyR_Pos.x-ButtonSize, JoyR_Pos.y-ButtonSize, 2*ButtonSize, 2*ButtonSize);
if(this.node.joyt.isPressed()) g.fillRect(JoyT_Pos.x-ButtonSize, JoyT_Pos.y-ButtonSize, 2*ButtonSize, 2*ButtonSize);
if(this.node.joyb.isPressed()) g.fillRect(JoyB_Pos.x-ButtonSize, JoyB_Pos.y-ButtonSize, 2*ButtonSize, 2*ButtonSize);
if(ButtonR_Pressed) g.fillRect(ButtonR_Pos.x-ButtonSize, ButtonR_Pos.y-ButtonSize, 2*ButtonSize, 2*ButtonSize);
// Display all active leds
if (node.LEDR) {
g.setColor(LEDR_TRANS);
g.fillOval(LEDR_X - 7, LEDR_Y - 2, 13, 9);
g.setColor(LEDR_C);
g.fillOval(LEDR_X - 5, LEDR_Y - 1, 9, 7);
}
if (node.LEDO) {
g.setColor(LEDO_TRANS);
g.fillOval(LEDO_X - 7, LEDO_Y - 2, 13, 9);
g.setColor(LEDO_C);
g.fillOval(LEDO_X - 5, LEDO_Y - 1, 9, 7);
}
this.node.lcd.drawDisplay(g);
g.setColor(old);
}
protected void stopGUI() {
node.leds.removeStateChangeListener(ledsListener);
}
}

View File

@ -0,0 +1,168 @@
/**
* Copyright (c) 2013, DHBW Cooperative State University Mannheim
* 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.
*
* Author: Rüdiger Heintz <ruediger.heintz@dhbw-mannheim.de>
*/
package se.sics.mspsim.platform.MSPEXP430F5438;
import java.awt.Rectangle;
import java.io.IOException;
import se.sics.mspsim.chip.Button;
import se.sics.mspsim.chip.HD66753Listener;
import se.sics.mspsim.chip.Leds;
import se.sics.mspsim.config.MSP430f5438Config;
import se.sics.mspsim.core.IOPort;
import se.sics.mspsim.core.MSP430;
import se.sics.mspsim.core.PortListener;
import se.sics.mspsim.core.USART;
import se.sics.mspsim.extutil.jfreechart.DataChart;
import se.sics.mspsim.extutil.jfreechart.DataSourceSampler;
import se.sics.mspsim.platform.GenericNode;
import se.sics.mspsim.ui.SerialMon;
import se.sics.mspsim.util.ArgumentManager;
import se.sics.mspsim.util.OperatingModeStatistics;
import se.sics.mspsim.chip.HD66753;
public class Exp5438Node extends GenericNode implements PortListener,HD66753Listener {
public static final int MODE_LEDS_OFF = 0;
public static final int MODE_MAX = 2;
private static final int[] LEDSCOLOR = { 0xff2020, 0x40ff40 };
public static final int LEDO_BIT = 0x02;
public static final int LEDR_BIT = 0x01;
public boolean LEDR;
public boolean LEDO;
public Leds leds;
public Button button1;
public Button button2;
public Button joyl;
public Button joyr;
public Button joym;
public Button joyt;
public Button joyb;
public HD66753 lcd;
public Exp5438Gui gui;
public Exp5438Node() {
super("Exp5438", new MSP430f5438Config());
setMode(MODE_LEDS_OFF);
}
public void setupNodePorts() {
IOPort port1 = cpu.getIOUnit(IOPort.class, "P1");
port1.addPortListener(this);
IOPort port2 = cpu.getIOUnit(IOPort.class, "P2");
leds = new Leds(cpu, LEDSCOLOR);
button1 = new Button("Button", cpu, port2, 6, false,Button.Btn_Typ.HighOpen);
button2 = new Button("Button", cpu, port2, 7, false,Button.Btn_Typ.HighOpen);
joyl = new Button("Button", cpu, port2, 1, false,Button.Btn_Typ.HighOpen);
joyr = new Button("Button", cpu, port2, 2, false,Button.Btn_Typ.HighOpen);
joym = new Button("Button", cpu, port2, 3, false,Button.Btn_Typ.HighOpen);
joyt = new Button("Button", cpu, port2, 4, false,Button.Btn_Typ.HighOpen);
joyb = new Button("Button", cpu, port2, 5, false,Button.Btn_Typ.HighOpen);
lcd=new HD66753(cpu,"USCI B2",8,3,new Rectangle(368, 189, 179, 138));
lcd.addListener(this);
}
public void setupGUI() {
if (gui == null) {
gui = new Exp5438Gui(this);
registry.registerComponent("nodegui", gui);
}
}
public void portWrite(IOPort source, int data) {
if (source.getPort() == 1) {
LEDR = (data & LEDR_BIT) != 0;
LEDO = (data & LEDO_BIT) != 0;
leds.setLeds((LEDR ? 1 : 0) + (LEDO ? 2 : 0));
int newMode = (LEDR ? 1 : 0) + (LEDO ? 1 : 0);
setMode(newMode);
gui.repaint();
}
}
public void displayChanged(){
gui.repaint();
}
public void setupNode() {
setupNodePorts();
cpu.setFlashFile("flash.dat");
if (stats != null) {
stats.addMonitor(this);
stats.addMonitor(cpu);
}
if (!config.getPropertyAsBoolean("nogui", true)) {
setupGUI();
IOPort port1 = cpu.getIOUnit(IOPort.class, "P1");
// Add some windows for listening to serial output
USART usart = cpu.getIOUnit(USART.class, "USART1");
if (usart != null) {
SerialMon serial = new SerialMon(usart, "USART1 Port Output");
registry.registerComponent("serialgui", serial);
}
if (stats != null) {
DataChart dataChart = new DataChart(registry, "Duty Cycle","Duty Cycle");
registry.registerComponent("dutychart", dataChart);
DataSourceSampler dss = dataChart.setupChipFrame(cpu);
dataChart.addDataSource(dss, "LEDS", stats.getDataSource(
getID(), 0, OperatingModeStatistics.OP_INVERT));
dataChart.addDataSource(dss, "CPU",
stats.getDataSource(cpu.getID(), MSP430.MODE_ACTIVE));
}
}
}
public int getModeMax() {
return MODE_MAX;
}
public static void main(String[] args) throws IOException {
Exp5438Node node = new Exp5438Node();
ArgumentManager config = new ArgumentManager();
config.handleArguments(args);
node.setupArgs(config);
}
}

View File

@ -46,14 +46,20 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import se.sics.mspsim.cli.CommandContext;
import se.sics.mspsim.core.MSP430;
import se.sics.mspsim.core.MemoryMonitor;
import se.sics.mspsim.core.SimEvent;
import se.sics.mspsim.core.SimEventListener;
import se.sics.mspsim.core.Memory.AccessMode;
import se.sics.mspsim.core.Memory.AccessType;
import se.sics.mspsim.platform.GenericNode;
import se.sics.mspsim.util.ComponentRegistry;
import se.sics.mspsim.util.DebugInfo;
@ -81,6 +87,8 @@ public class ControlUI extends JPanel implements ActionListener, SimEventListene
private Status status = Status.STOPPED;
private String name;
private TreeView tv = null;
public ControlUI() {
super(new GridLayout(0, 1));
@ -98,8 +106,9 @@ public class ControlUI extends JPanel implements ActionListener, SimEventListene
jp.setLayout(new BorderLayout());
jp.add(this, BorderLayout.WEST);
jp.add(dui = new DebugUI(cpu), BorderLayout.CENTER);
jp.add(dui = new DebugUI(cpu,elfData), BorderLayout.CENTER);
window.add(jp);
window.setSize(800, 500);
createButton("Debug On");
controlButton = createButton(cpu.isRunning() ? "Stop" : "Run");
@ -124,7 +133,7 @@ public class ControlUI extends JPanel implements ActionListener, SimEventListene
" => " + dbg.getFile() + ':' +
dbg.getLine());
}
sourceViewer.viewFile(dbg.getPath(), dbg.getFile());
sourceViewer.viewFile(dbg.getPath(), dbg.getFile(),false);
sourceViewer.viewLine(dbg.getLine());
}
}
@ -142,6 +151,7 @@ public class ControlUI extends JPanel implements ActionListener, SimEventListene
createButton("Show Source");
}
createButton("Profile Dump");
createButton("Component View");
// Setup standard actions
stepButton.getInputMap(WHEN_IN_FOCUSED_WINDOW)
@ -168,6 +178,9 @@ public class ControlUI extends JPanel implements ActionListener, SimEventListene
private void updateCPUPercent() {
window.setTitle(TITLE + " CPU On: " + cpu.getCPUPercent() + "%");
}
public void actionPerformed(ActionEvent ae) {
String cmd = ae.getActionCommand();
@ -182,42 +195,60 @@ public class ControlUI extends JPanel implements ActionListener, SimEventListene
} else if ("Run".equals(cmd)) {
node.start();
} else if ("Stop".equals(cmd)) {
node.stop();
UpdateSourceView(false);
} else if ("Profile Dump".equals(cmd)) {
if (cpu.getProfiler() != null) {
cpu.getProfiler().printProfile(System.out);
cpu.getProfiler().printProfile(System.out);
} else {
System.out.println("*** No profiler available");
System.out.println("*** No profiler available");
}
// } else if ("Single Step".equals(cmd)) {
// cpu.step();
// dui.repaint();
// } else if ("Single Step".equals(cmd)) {
// cpu.step();
// dui.repaint();
} else if ("Show Source".equals(cmd)) {
int pc = cpu.getPC();
if (elfData != null) {
DebugInfo dbg = elfData.getDebugInfo(pc);
if (dbg != null) {
if (cpu.getDebug()) {
System.out.println("looking up $" + Integer.toString(pc, 16) +
" => " + dbg.getFile() + ':' + dbg.getLine());
}
if (sourceViewer != null) {
sourceViewer.viewFile(dbg.getPath(), dbg.getFile());
sourceViewer.viewLine(dbg.getLine());
} else {
System.out.println("File: " + dbg.getFile());
System.out.println("LineNr: " + dbg.getLine());
}
}
}
UpdateSourceView(true);
} else if ("Stack Trace".equals(cmd)) {
cpu.getProfiler().printStackTrace(System.out);
}
else if ("Component View".equals(cmd)){ //
if(tv==null) //Initializes the tree view frame
tv = new TreeView(cpu); //Button does nothing, if tree is created and visible
//
else{ //
tv.ReOpen(); //If tree is not visible, but already built, makes it visible
} //
} //
dui.updateRegs();
}
public void UpdateSourceView(boolean useChooser){
int pc = cpu.getPC();
if (elfData != null) {
DebugInfo dbg = elfData.getDebugInfo(pc);
if (dbg != null) {
if (cpu.getDebug()) {
System.out.println("looking up $" + Integer.toString(pc, 16)
+ " => " + dbg.getFile() + ':' + dbg.getLine());
}
if (sourceViewer != null) {
sourceViewer.viewFile(dbg.getPath(), dbg.getFile(),useChooser);
if(cpu.isRunning())
sourceViewer.viewLine(-1);
else
sourceViewer.viewLine(dbg.getLine());
} else {
System.out.println("File: " + dbg.getFile());
System.out.println("LineNr: " + dbg.getLine());
}
}
}
}
public void simChanged(SimEvent event) {
switch (event.getType()) {
@ -232,7 +263,10 @@ public class ControlUI extends JPanel implements ActionListener, SimEventListene
} else {
controlButton.setText("Run");
stepAction.setEnabled(true);
dui.updateRegs();
dui.repaint();
}
UpdateSourceView(false);
}
});

View File

@ -42,14 +42,28 @@ import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.AbstractListModel;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListCellRenderer;
import se.sics.mspsim.cli.CommandContext;
import se.sics.mspsim.core.DbgInstruction;
import se.sics.mspsim.core.DisAsm;
import se.sics.mspsim.core.MSP430;
import se.sics.mspsim.core.MemoryMonitor;
import se.sics.mspsim.core.Memory.AccessMode;
import se.sics.mspsim.core.Memory.AccessType;
import se.sics.mspsim.util.DebugInfo;
import se.sics.mspsim.util.ELF;
import se.sics.mspsim.util.Utils;
public class DebugUI extends JPanel {
@ -63,26 +77,60 @@ public class DebugUI extends JPanel {
private DisAsm disAsm;
private MemoryMonitor monitor;
/**
* Creates a new <code>DebugUI</code> instance.
*
*/
public DebugUI(MSP430 cpu) {
this(cpu, true);
public DebugUI(MSP430 cpu,ELF elfData) {
this(cpu, elfData, true);
}
private void setMonitor(){
monitor = new MemoryMonitor.Adapter() {
private long lastCycles = -1;
@Override
public void notifyReadBefore(int address, AccessMode mode, AccessType type) {
if (type == AccessType.EXECUTE && cpu.cycles != lastCycles) {
cpu.triggBreakpoint();
lastCycles = cpu.cycles;
}
}
};
}
public DebugUI(MSP430 cpu, boolean showRegs) {
public DebugUI(MSP430 cpu,ELF elfData, boolean showRegs) {
super(new BorderLayout());
this.cpu = cpu;
disAsm = cpu.getDisAsm();
disAsm = cpu.getDisAsm();
setMonitor();
listModel = new DbgListModel();
disList = new JList<DbgInstruction>(listModel);
disList.setFont(new Font("courier", 0, 12));
disList.setCellRenderer(new MyCellRenderer());
disList.setPreferredSize(new Dimension(500, 350));
add(disList, BorderLayout.CENTER);
disList.setCellRenderer(new MyCellRenderer(elfData));
disList.setPreferredSize(new Dimension(500, 2000));
JScrollPane scrollPane = new JScrollPane();
scrollPane.setViewportView(disList);
add(scrollPane, BorderLayout.CENTER);
MouseAdapter mouseListener = new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
int pos=disList.getSelectedValue().getPos();
editBreakpoint(pos);
}
disList.updateUI();
}
};
disList.addMouseListener(mouseListener);
if (showRegs) {
JPanel regs = new JPanel(new GridLayout(2,8,4,0));
regsLabel = new JLabel[16];
@ -102,13 +150,23 @@ public class DebugUI extends JPanel {
}
repaint();
}
private void editBreakpoint(int pos){
if (cpu.hasWatchPoint(pos)) {
cpu.removeWatchPoint(pos, monitor);
}else{
cpu.addWatchPoint(pos, monitor);
}
}
private class DbgListModel extends AbstractListModel<DbgInstruction> {
private static final long serialVersionUID = -2856626511548201481L;
int startPos = -1;
int endPos = -1;
final int size = 21;
final int size = 101;
DbgInstruction[] instructions = new DbgInstruction[size];
@ -160,8 +218,10 @@ public class DebugUI extends JPanel {
class MyCellRenderer extends JLabel implements ListCellRenderer<DbgInstruction> {
private static final long serialVersionUID = -2633138712695105181L;
private ELF elfData;
public MyCellRenderer() {
public MyCellRenderer(ELF elfData) {
this.elfData=elfData;
setOpaque(true);
}
@ -189,6 +249,16 @@ public class DebugUI extends JPanel {
s += "; " + instruction.getFunction();
}
}
s=String.format("%1$-" + 60 + "s", s);
try{
String s2= elfData.getDebugInfo(pos).toString();
s2=s2.replace("(function: * not available)", "");
s2=s2.replace("in file: ", "");
s2=s2.replace(".//../", "");
s += ","+s2;
}catch(Exception e){}
setText(s);
if (pos == cpu.getPC()) {
setBackground(Color.green);

View File

@ -4,6 +4,9 @@ import java.awt.Component;
import javax.swing.JFrame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class JFrameWindowManager implements WindowManager {
public ManagedWindow createWindow(final String name) {
@ -14,6 +17,8 @@ public class JFrameWindowManager implements WindowManager {
public void setSize(int width, int height) {
window.setSize(width, height);
}
public void setBounds(int x, int y, int width, int height) {
window.setBounds(x, y, width, height);
@ -34,6 +39,19 @@ public class JFrameWindowManager implements WindowManager {
public void removeAll() {
window.removeAll();
}
public void setAlwaysOnTop(boolean val) {
window.setAlwaysOnTop( val);
}
public void setExitOnClose(){
window.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0);//cierra aplicacion
}
});
}
public boolean isVisible() {
return window.isVisible();

View File

@ -7,9 +7,12 @@ public interface ManagedWindow {
public void setSize(int width, int height);
public void setBounds(int x, int y, int width, int height);
public void pack();
public void setAlwaysOnTop(boolean val);
public void add(Component component);
public void removeAll();
public void setExitOnClose();
public boolean isVisible();

View File

@ -44,7 +44,7 @@ package se.sics.mspsim.ui;
public interface SourceViewer {
public boolean isVisible();
public void viewFile(String path, String file);
public void viewFile(String path, String file, boolean UseChooser);
public void viewLine(int line);
}

View File

@ -0,0 +1,113 @@
package se.sics.mspsim.ui;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import se.sics.mspsim.core.IOUnit;
import se.sics.mspsim.core.MSP430;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultTreeModel;
public class TreeView
{
private MSP430 cpu;
private DefaultMutableTreeNode root=null;
private JScrollPane scroller;
private JPanel view;
public javax.swing.Timer rtimer;
public JFrame tf = null;
public TreeView(MSP430 cpu) //Create tree in JFrame, set size and other parameters
{
rtimer = new javax.swing.Timer(300, new ActionListener() { //Refresh-Timer
public void actionPerformed(ActionEvent evt) { //
Refresh(); //Calls Refresh-function periodically to ensure correct information
if (!tf.isVisible()) { //Displayed in the frame
rtimer.stop(); //Stops the timer in case of not-visible window to ensure performance
} //
} //
}); //
this.cpu = cpu; //
root = CreateRoot(); //Fills root with information which are stored in tree nodes
DefaultTreeModel model = new DefaultTreeModel(root); //
JTree tree = new JTree(model); //
tf = new JFrame("Components"); //Names frame
tf.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); //Sets parameters
tf.add(tree); //Adds tree to frame
tf.setSize(210,450); //Set parameters
tf.setLocation(750,400); //Set parameters
tf.setVisible(true); //Makes it visible
tree.setRootVisible(false); //Makes root invisible
view = new JPanel(new GridBagLayout());
view.add(tree,GetConstraints());
scroller = new JScrollPane(view); //Creates scroll bar
tf.add(scroller); //Adds scroller to frame
rtimer.start(); //Refresh timer runs from the beginning
}
private DefaultMutableTreeNode CreateRoot() { //Calls function, which collects data from components and adds those data to the tree
DefaultMutableTreeNode root=new DefaultMutableTreeNode("Components");//
for(Object uni: cpu.getIOUnits()){ //This loop enables direct access to each component and tries to gather information about them
IOUnit ele=(IOUnit)uni; //
DefaultMutableTreeNode node=ele.getNode(); //
if(node!=null) //Only components with collectible information are displayed
root.add(node); //
} //
return root; //Returns root
} //
private void Refresh(){ //Refreshes tree
int position = scroller.getVerticalScrollBar().getValue(); //Stores scroll bar position
DefaultTreeModel model = new DefaultTreeModel(CreateRoot());
JTree tree = new JTree(model);
tree.setRootVisible(false);
for(int count = 0; count < tree.getRowCount(); count++) //This loop prompts which rows are expanded in the obsolete tree.
if(((JTree)view.getComponent(0)).isExpanded(count)) //
tree.expandRow(count); //Expands those rows in new tree
view.removeAll();
view.add(tree,GetConstraints());
view.revalidate();
view.repaint();
scroller.getVerticalScrollBar().setValue(position); //Sets the scroll bar to the previous position
}
private static GridBagConstraints GetConstraints(){
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.VERTICAL;
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1;
return gbc;
}
public void ReOpen(){
tf.setVisible(true); //
rtimer.restart(); //Makes frame visible, if it's already built
} //restarts timer
} //

View File

@ -333,21 +333,30 @@ public class ELF {
for (int i = 0, n = len; i < n; i++) {
memory[addr++] = elfData[offset++] & 0xff;
}
if (fill > len) {
int n = fill - len;
if (n + addr > memory.length) {
n = memory.length - addr;
}
for (int i = 0; i < n; i++) {
memory[addr++] = 0;
}
}
// Flash is overridden but I want to define the values in the flash class
// if (fill > len) {
// int n = fill - len;
// if (n + addr > memory.length) {
// n = memory.length - addr;
// }
// for (int i = 0; i < n; i++) {
// memory[addr++] = 0;
// }
// }
}
public ELFDebug getDebug() {
return debug;
}
public int getPC(String FileName,int line) {
if (debug != null) {
return debug.getPC(FileName, line);
}
return -1;
}
public DebugInfo getDebugInfo(int adr) {
if (debug != null) {
return debug.getDebugInfo(adr);

View File

@ -47,5 +47,7 @@ public interface ELFDebug {
public ArrayList<Integer> getExecutableAddresses();
public String[] getSourceFiles();
public int getPC(String FileName,int line);
} // ELFDebug

550
se/sics/mspsim/util/GDBStubs.java Normal file → Executable file
View File

@ -45,210 +45,388 @@ import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import javax.xml.soap.Node;
import se.sics.mspsim.core.EmulationException;
import se.sics.mspsim.core.MSP430Core;
import se.sics.mspsim.core.MSP430;
import se.sics.mspsim.core.Memory;
import se.sics.mspsim.core.MemoryMonitor;
import se.sics.mspsim.core.Memory.AccessMode;
import se.sics.mspsim.core.Memory.AccessType;
import se.sics.mspsim.platform.GenericNode;
public class GDBStubs implements Runnable {
private final static String OK = "OK";
private static final int SIGTRAP = 5; // Trace/breakpoint trap.
private static final int SIGCONT = 25; // Continue stopped process
ServerSocket serverSocket;
OutputStream output;
MSP430Core cpu;
private final static String OK = "OK";
public void setupServer(MSP430Core cpu, int port) {
this.cpu = cpu;
try {
serverSocket = new ServerSocket(port);
System.out.println("GDBStubs open server socket port: " + port);
new Thread(this).start();
} catch (IOException e) {
private MemoryMonitor monitor;
ServerSocket serverSocket;
OutputStream output;
MSP430 cpu;
GenericNode node;
ELF elf;
public void setupServer(GenericNode node, MSP430 cpu, int port, ELF elf) {
this.cpu = cpu;
this.node = node;
this.elf = elf;
try {
serverSocket = new ServerSocket(port);
System.out.println("GDBStubs open server socket port: " + port);
setMonitor();
new Thread(this).start();
} catch (IOException e) {
e.printStackTrace();
}
}
List<Integer> buffer = new ArrayList<Integer>();
Socket s;
public void run() {
while (true) {
try {
s = serverSocket.accept();
node.stop();
cpu.reset();
DataInputStream input = new DataInputStream(s.getInputStream());
output = s.getOutputStream();
String cmd = "";
boolean readCmd = false;
int c;
while (s != null && ((c = input.read()) != -1)) {
// System.out.print((char)c);
if (readCmd) {
if (c == '#') {
readCmd = false;
output.write('+');
handleCmd(cmd, (Integer [])buffer.toArray(new Integer[buffer.size()]), buffer.size());
cmd = "";
buffer.clear();
} else {
cmd += (char) c;
buffer.add(c & 0xff);
if (c == '$') {
System.out
.println("GDBStubs: server send start $ without end #");
}
}
} else {
if (c == '$') {
readCmd = true;
} else if (c == '-') {
System.out.println("GDBStubs: server send - (NAK) ");
} else if (c == 3) {
output.write('+');
handleCmd("3", new Integer [0], 0);
}
}
}
} catch (IOException e) {
System.out.println(e.getMessage());
e.printStackTrace();
} catch (EmulationException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
private void stepSource() {
node.stop();
node.step(1);
/*
* List<Integer> listPC = new ArrayList<Integer>(); DebugInfo dbg =
* elf.getDebugInfo(cpu.getPC()); String File=dbg.getFile(); int
* Line=dbg.getLine(); String Path=dbg.getPath();
*
* do{ listPC.add(cpu.getPC()); node.step(1); dbg =
* elf.getDebugInfo(cpu.getPC());
* }while((Path==dbg.getPath())&&(Line==dbg.getLine
* ())&&(File==dbg.getFile())&&!listPC.contains(cpu.getPC()));
*/}
/**
* @param cmd
* @param cmdBytes
* @param cmdLen
* @throws IOException
* @throws EmulationException
*/
/**
* @param cmd
* @param cmdBytes
* @param cmdLen
* @throws IOException
* @throws EmulationException
*/
private void handleCmd(String cmd, Integer[] cmdBytes, int cmdLen)
throws IOException, EmulationException {
System.out.println("cmd: " + cmd);
char c = cmd.charAt(0);
String parts[];
switch (c) {
case 'H':
sendResponse("", "command unknown");
break;
case 'v':
if ("vCont?".equals(cmd)) {
sendResponse("", "vCont not supported (only needed for multithreading)");
} else {
sendResponse("", "command unknown");
}
break;
case 'q':
if ("qC".equals(cmd)) {
sendResponse("", "command unknown");
} else if ("qOffsets".equals(cmd)) {
sendResponse("", "command unknown");
} else if ("qfThreadInfo".equals(cmd)) {
sendResponse("<?xml version\"1.0\"?><threads></threads>");
} else if ("qsThreadInfo".equals(cmd)) {
sendResponse("l");
} else if ("qAttached".equals(cmd)) {
sendResponse("", "command unknown");
} else if ("qSymbol::".equals(cmd)) {
sendResponse("", "command unknown");
} else if ("qTStatus".equals(cmd)) {
sendResponse("", "command unknown");
} else if (cmd.contains("qRcmd,")) {
String Text = hexTostring(cmd.substring(6));
if (Text.equals("erase all")) {
sendResponse(stringToHex("Erasing..."), "Erasing...");
} else if (Text == "reset") {
cpu.reset();
sendResponse(stringToHex("Resetting..."), "Resetting...");
}
} else if ("qSupported:qRelocInsn+".equals(cmd)) {
sendResponse("PacketSize=4000", "packet size 4000 bytes");
} else {
sendResponse("", "command unknown");
}
break;
case '?':
if(cpu.isRunning()){
sendRegisters2(SIGCONT);
} else {
sendRegisters2(SIGTRAP);
}
break;
case 'g':
sendRegisters();
break;
case 'P': // write Register
parts = cmd.split("=");
if (parts.length == 2) {
String Val = parts[1].substring(2, 4) + parts[1].substring(0, 2);
cpu.writeRegister(Integer.parseInt(parts[0].substring(1)),
Integer.parseInt(Val, 16));
sendResponse(OK, "register written");
}
break;
case 'k': // kill
sendResponse(OK, "kill task");
s.close();
s = null;
System.exit(0);
break;
case '3': // Pause
case 's':
case 'S':
node.stop();
stepSource();
sendRegisters2(SIGTRAP);
break;
case 'c':
case 'C':
node.start();
break;
case 'Z':
parts = cmd.split(",");
setBreakpoint(Integer.parseInt(parts[1], 16));
sendResponse(OK, "set breakpoint at 0x" + parts[1]);
break;
case 'z':
parts = cmd.split(",");
removeBreakpoint(Integer.parseInt(parts[1], 16));
sendResponse(OK, "remove breakpoint at 0x" + parts[1]);
break;
case 'm':
case 'M':
case 'X':
String cmd2 = cmd.substring(1);
String wdata[] = cmd2.split(":");
int cPos = cmd.indexOf(':');
if (cPos > 0) {
/* only until length in first part */
cmd2 = wdata[0];
}
parts = cmd2.split(",");
int addr = Integer.decode("0x" + parts[0]);
int len = Integer.decode("0x" + parts[1]);
String data = "";
Memory mem = cpu.getMemory();
if (c == 'm') {
System.out.println("Returning memory from: 0x" + Integer.toHexString(addr) + " len = " + len);
/* This might be wrong - which is the correct byte order? */
for (int i = 0; i < len; i+=2) {
String data2 = Utils.hex16(mem.get(addr, Memory.AccessMode.WORD));
data+=data2.substring(2);
data+=data2.substring(0, 2);
addr+=2;
}
sendResponse(data);
} else {
// List<String> supplierNames = new ArrayList<String>();
// for (int i = 0; i < len; i++) {
// String Val= Integer.toHexString(mem.get(addr+2*i,
// Memory.AccessMode.WORD));
// supplierNames.add(Val+" "+Integer.toHexString(addr+2*i));
// }
System.out.println("Writing to memory at: " + Integer.toHexString(addr) + " len = " + len + " with: "
+ ((wdata.length > 1) ? wdata[1] : ""));
cPos++;
for (int i = 0; i < len; i+=2) {
mem.set(addr, cmdBytes[cPos++]+cmdBytes[cPos++]*256, Memory.AccessMode.WORD);
addr+=2;
// cpu.memory[addr+i]=cmdBytes[cPos++];
}
// for (int i = 0; i < len; i++) {
// String Val= Integer.toHexString(mem.get(addr+2*i,
// Memory.AccessMode.WORD));
// System.out.println(Val+" "+Integer.toHexString(addr+2*i)+" old:"+supplierNames.get(i));
// }
sendResponse(OK);
}
break;
default:
sendResponse("", "Command unknown");
}
}
private static String hexTostring(String hexValue) {
StringBuilder output = new StringBuilder("");
for (int i = 0; i < hexValue.length(); i += 2) {
String str = hexValue.substring(i, i + 2);
output.append((char) Integer.parseInt(str, 16));
}
return output.toString();
}
private void setBreakpoint(int pos) {
if (!cpu.hasWatchPoint(pos)) {
cpu.addWatchPoint(pos, monitor);
}
}
private void removeBreakpoint(int pos) {
if (cpu.hasWatchPoint(pos)) {
cpu.removeWatchPoint(pos, monitor);
}
}
private void setMonitor() {
monitor = new MemoryMonitor.Adapter() {
private long lastCycles = -1;
@Override
public void notifyReadBefore(int address, AccessMode mode, AccessType type) {
if (type == AccessType.EXECUTE && cpu.cycles != lastCycles) {
cpu.triggBreakpoint();
lastCycles = cpu.cycles;
try {
sendRegisters2(SIGTRAP);
} catch (IOException e) {
e.printStackTrace();
}
}
}
};
}
private void sendRegisters() throws IOException {
String regs = "";
for (int i = 0; i < 16; i++) {
regs += Utils.hex8(cpu.reg[i] & 0xff) + Utils.hex8(cpu.reg[i] >> 8);
}
sendResponse(regs);
}
int[] buffer = new int[256];
int len;
public void run() {
while (true) {
try {
Socket s = serverSocket.accept();
DataInputStream input = new DataInputStream(s.getInputStream());
output = s.getOutputStream();
String cmd = "";
boolean readCmd = false;
int c;
while (s != null && ((c = input.read()) != -1)) {
System.out.println("GDBStubs: Read " + c + " => "
+ (char) c);
if (c == '#') {
readCmd = false;
/* ack the message */
output.write('+');
handleCmd(cmd, buffer, len);
cmd = "";
len = 0;
}
if (readCmd) {
cmd += (char) c;
buffer[len++] = (c & 0xff);
}
if (c == '$') {
readCmd = true;
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (EmulationException e) {
e.printStackTrace();
}
}
// synchronized because of asynchron breakpoint call
private synchronized void sendRegisters2(int Signal) throws IOException {
String regs = "T" + String.format("%02d", Signal);
for (int i = 0; i < 16; i++) {
regs += Utils.hex8(i) + ":" + Utils.hex8(cpu.reg[i] & 0xff)
+ Utils.hex8(cpu.reg[i] >> 8) + ";";
}
sendResponse(regs);
}
private void handleCmd(String cmd, int[] cmdBytes, int cmdLen)
throws IOException, EmulationException {
System.out.println("cmd: " + cmd);
char c = cmd.charAt(0);
switch (c) {
case 'H':
sendResponse(OK);
break;
case 'q':
if ("qC".equals(cmd)) {
sendResponse("QC1");
} else if ("qOffsets".equals(cmd)) {
sendResponse("Text=0;Data=0;Bss=0");
} else if ("qfThreadInfo".equals(cmd)){
sendResponse("m 01");
} else if ("qsThreadInfo".equals(cmd)){
sendResponse("l");
} else if ("qSymbol::".equals(cmd)){
sendResponse(OK);
//} else if ("qThreadExtraInfo,1".equals(cmd)){
// sendResponse(stringToHex("Stoped"));
} else {
System.out.println("Command unknown");
sendResponse("");
}
break;
case '?':
sendResponse("S01");
break;
case 'g':
readRegisters();
break;
case 'k': // kill
sendResponse(OK);
break;
case 'm':
case 'M':
case 'X':
String cmd2 = cmd.substring(1);
String wdata[] = cmd2.split(":");
int cPos = cmd.indexOf(':');
if (cPos > 0) {
/* only until length in first part */
cmd2 = wdata[0];
}
String parts[] = cmd2.split(",");
int addr = Integer.decode("0x" + parts[0]);
int len = Integer.decode("0x" + parts[1]);
String data = "";
Memory mem = cpu.getMemory();
if (c == 'm') {
System.out.println("Returning memory from: " + addr + " len = "
+ len);
/* This might be wrong - which is the correct byte order? */
for (int i = 0; i < len; i++) {
data += Utils.hex8(mem.get(addr++, Memory.AccessMode.BYTE));
}
sendResponse(data);
} else {
System.out.println("Writing to memory at: " + addr + " len = "
+ len + " with: "
+ ((wdata.length > 1) ? wdata[1] : ""));
cPos++;
for (int i = 0; i < len; i++) {
System.out.println("Writing: " + cmdBytes[cPos] + " to "
+ addr + " cpos=" + cPos);
mem.set(addr++, cmdBytes[cPos++], Memory.AccessMode.BYTE);
}
sendResponse(OK);
}
break;
case 'C':
sendResponse("S01");
break;
default:
System.out.println("Command unknown");
sendResponse("");
}
private static String stringToHex(String asciiValue) {
char[] chars = asciiValue.toCharArray();
StringBuffer hex = new StringBuffer();
for (int i = 0; i < chars.length; i++) {
hex.append(Integer.toHexString((int) chars[i]));
}
return hex.toString();
}
private void readRegisters() throws IOException {
String regs = "";
for (int i = 0; i < 16; i++) {
regs += Utils.hex8(cpu.reg[i] & 0xff) + Utils.hex8(cpu.reg[i] >> 8);
}
sendResponse(regs);
public void sendResponse(String resp) throws IOException {
sendResponse(resp, "");
}
public void sendResponse(String resp, String info) throws IOException {
System.out.print("ans: ");
String a = "";
a += '$';
int cs = 0;
if (resp != null) {
for (int i = 0; i < resp.length(); i++) {
a += resp.charAt(i);
System.out.print(resp.charAt(i));
cs += resp.charAt(i);
}
}
public static String stringToHex(String base)
{
StringBuffer buffer = new StringBuffer();
int intValue;
for(int x = 0; x < base.length(); x++)
{
int cursor = 0;
intValue = base.charAt(x);
String binaryChar = new String(Integer.toBinaryString(base.charAt(x)));
for(int i = 0; i < binaryChar.length(); i++) {
if(binaryChar.charAt(i) == '1') {
cursor += 1;
}
}
if((cursor % 2) > 0) {
intValue += 128;
}
buffer.append(Integer.toHexString(intValue));
}
return buffer.toString();
a += '#';
int c = (cs & 0xff) >> 4;
if (c < 10) {
c = c + '0';
} else {
c = c - 10 + 'a';
}
a += (char) c;
public void sendResponse(String resp) throws IOException {
output.write('$');
int cs = 0;
if (resp != null) {
for (int i = 0; i < resp.length(); i++) {
output.write(resp.charAt(i));
System.out.print(resp.charAt(i));
cs += resp.charAt(i);
}
}
output.write('#');
System.out.print('#');
int c = (cs & 0xff) >> 4;
if (c < 10) {
c = c + '0';
} else {
c = c - 10 + 'a';
}
output.write((char) c);
System.out.print((char) c);
c = cs & 15;
if (c < 10) {
c = c + '0';
} else {
c = c - 10 + 'a';
}
output.write((char) c);
System.out.println((char) c);
c = cs & 15;
if (c < 10) {
c = c + '0';
} else {
c = c - 10 + 'a';
}
a += (char) c;
if (info == "") {
System.out.println("");
} else {
System.out.println(" (" + info + ")");
}
output.write(a.getBytes());
}
}