diff --git a/se/sics/mspsim/core/IOPort.java b/se/sics/mspsim/core/IOPort.java index cad5255..fc28261 100644 --- a/se/sics/mspsim/core/IOPort.java +++ b/se/sics/mspsim/core/IOPort.java @@ -36,7 +36,6 @@ */ package se.sics.mspsim.core; -import se.sics.mspsim.util.ArrayUtils; import se.sics.mspsim.util.Utils; public class IOPort extends IOUnit { @@ -89,7 +88,7 @@ public class IOPort extends IOUnit { private PortReg[] portMap; - private PortListener[] listeners = new PortListener[0]; + private PortListener portListener = null; // represents the direction register /* Registers for Digital I/O */ @@ -102,7 +101,7 @@ public class IOPort extends IOUnit { private int ifg; private int ies; /* edge select */ private int ren; - private int ds; +// private int ds; private int iv; /* low / high */ @@ -184,9 +183,21 @@ public class IOPort extends IOUnit { return sel; } - public void setPortListener(PortListener listener) { - /* 2011-09-11: XXX should now be named addPortListener() */ - listeners = (PortListener[]) ArrayUtils.add(PortListener.class, listeners, listener); + public synchronized void addPortListener(PortListener newListener) { + portListener = PortListenerProxy.addPortListener(portListener, newListener); + } + + public synchronized void removePortListener(PortListener oldListener) { + portListener = PortListenerProxy.removePortListener(portListener, oldListener); + } + + @Deprecated + public synchronized void setPortListener(PortListener listener) { + if (listener != null) { + addPortListener(listener); + } else { + portListener = null; + } } public void setTimerCapture(Timer timer, int pin) { @@ -242,25 +253,29 @@ public class IOPort extends IOUnit { void write_port(PortReg function, int data, long cycles) { switch(function) { - case OUT: + case OUT: { out = data; - for (PortListener listener: listeners) { + PortListener listener = portListener; + if (listener != null) { listener.portWrite(this, out | (~dir) & 0xff); } break; + } case IN: logw("WARNING: writing to read-only " + getID() + "IN"); throw new EmulationException("Writing to read-only " + getID() + "IN"); // in = data; - case DIR: + case DIR: { dir = data; - for (PortListener listener: listeners) { + 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); + listener.portWrite(this, out | (~dir) & 0xff); } break; + } case REN: ren = data; break; diff --git a/se/sics/mspsim/core/PortListenerProxy.java b/se/sics/mspsim/core/PortListenerProxy.java new file mode 100644 index 0000000..5a6f6eb --- /dev/null +++ b/se/sics/mspsim/core/PortListenerProxy.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2011, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of MSPSim. + * + * ----------------------------------------------------------------- + * + * PortListenerProxy + * + * Author : Niclas Finne + * Created : Tue Dec 7 18:25:00 2011 + */ + +package se.sics.mspsim.core; +import se.sics.mspsim.util.ArrayUtils; + +public class PortListenerProxy implements PortListener { + + private PortListener[] portListeners; + + public PortListenerProxy(PortListener listen1, PortListener listen2) { + portListeners = new PortListener[] { listen1, listen2 }; + } + + public static PortListener addPortListener(PortListener portListener, PortListener listener) { + if (portListener == null) { + return listener; + } + if (portListener instanceof PortListenerProxy) { + return ((PortListenerProxy)portListener).add(listener); + } + return new PortListenerProxy(portListener, listener); + } + + public static PortListener removePortListener(PortListener portListener, PortListener listener) { + if (portListener == listener) { + return null; + } + if (portListener instanceof PortListenerProxy) { + return ((PortListenerProxy)portListener).remove(listener); + } + return portListener; + } + + public PortListener add(PortListener mon) { + portListeners = (PortListener[]) ArrayUtils.add(PortListener.class, portListeners, mon); + return this; + } + + public PortListener remove(PortListener listener) { + PortListener[] listeners = (PortListener[]) ArrayUtils.remove(portListeners, listener); + if (listeners == null) { + return null; + } + if (listeners.length == 1) { + return listeners[0]; + } + portListeners = listeners; + return this; + } + + @Override + public void portWrite(IOPort source, int data) { + PortListener[] listeners = this.portListeners; + for(PortListener l : listeners) { + l.portWrite(source, data); + } + } + +}