mirror of https://github.com/contiki-ng/mspsim
Merge 243797edc7 into 93a19ea91e
This commit is contained in:
commit
ed6a521038
10
Makefile
10
Makefile
|
|
@ -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.
Binary file not shown.
|
After Width: | Height: | Size: 82 KiB |
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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; //
|
||||
} //
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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++) {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
} //
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -47,5 +47,7 @@ public interface ELFDebug {
|
|||
public ArrayList<Integer> getExecutableAddresses();
|
||||
|
||||
public String[] getSourceFiles();
|
||||
|
||||
public int getPC(String FileName,int line);
|
||||
|
||||
} // ELFDebug
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue