From: <jo...@us...> - 2007-10-24 10:44:57
|
Revision: 4 http://mspsim.svn.sourceforge.net/mspsim/?rev=4&view=rev Author: joxe Date: 2007-10-24 03:44:41 -0700 (Wed, 24 Oct 2007) Log Message: ----------- initial add of mspsim Added Paths: ----------- mspsim/se/ mspsim/se/sics/ mspsim/se/sics/mspsim/ mspsim/se/sics/mspsim/chip/ mspsim/se/sics/mspsim/chip/Beeper.java mspsim/se/sics/mspsim/chip/CC2420.java mspsim/se/sics/mspsim/core/ mspsim/se/sics/mspsim/core/BasicClockModule.java mspsim/se/sics/mspsim/core/CPUMonitor.java mspsim/se/sics/mspsim/core/DbgInstruction.java mspsim/se/sics/mspsim/core/DisAsm.java mspsim/se/sics/mspsim/core/IOPort.java mspsim/se/sics/mspsim/core/IOUnit.java mspsim/se/sics/mspsim/core/MSP430.java mspsim/se/sics/mspsim/core/MSP430Constants.java mspsim/se/sics/mspsim/core/MSP430Core.java mspsim/se/sics/mspsim/core/MapTable.java mspsim/se/sics/mspsim/core/Multiplier.java mspsim/se/sics/mspsim/core/PortListener.java mspsim/se/sics/mspsim/core/SFR.java mspsim/se/sics/mspsim/core/Timer.java mspsim/se/sics/mspsim/core/USART.java mspsim/se/sics/mspsim/core/USARTListener.java mspsim/se/sics/mspsim/platform/ mspsim/se/sics/mspsim/platform/esb/ mspsim/se/sics/mspsim/platform/esb/CVS/ mspsim/se/sics/mspsim/platform/esb/CVS/Entries mspsim/se/sics/mspsim/platform/esb/CVS/Repository mspsim/se/sics/mspsim/platform/esb/CVS/Root mspsim/se/sics/mspsim/platform/esb/ESBGui.java mspsim/se/sics/mspsim/platform/esb/ESBNode.java mspsim/se/sics/mspsim/platform/sky/ mspsim/se/sics/mspsim/platform/sky/CVS/ mspsim/se/sics/mspsim/platform/sky/CVS/Entries mspsim/se/sics/mspsim/platform/sky/CVS/Repository mspsim/se/sics/mspsim/platform/sky/CVS/Root mspsim/se/sics/mspsim/platform/sky/ExtFlash.java mspsim/se/sics/mspsim/platform/sky/SkyGui.java mspsim/se/sics/mspsim/platform/sky/SkyNode.java mspsim/se/sics/mspsim/util/ mspsim/se/sics/mspsim/util/ControlUI.java mspsim/se/sics/mspsim/util/DebugUI.java mspsim/se/sics/mspsim/util/DotDiagram.java mspsim/se/sics/mspsim/util/ELF.java mspsim/se/sics/mspsim/util/ELFProgram.java mspsim/se/sics/mspsim/util/ELFSection.java mspsim/se/sics/mspsim/util/IHexReader.java mspsim/se/sics/mspsim/util/SerialMon.java mspsim/se/sics/mspsim/util/StackUI.java mspsim/se/sics/mspsim/util/Test.java mspsim/se/sics/mspsim/util/Utils.java mspsim/se/sics/mspsim/util/WindowUtils.java Added: mspsim/se/sics/mspsim/chip/Beeper.java =================================================================== --- mspsim/se/sics/mspsim/chip/Beeper.java (rev 0) +++ mspsim/se/sics/mspsim/chip/Beeper.java 2007-10-24 10:44:41 UTC (rev 4) @@ -0,0 +1,148 @@ +/** + * Copyright (c) 2007, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of MSPSim. + * + * $Id: Beeper.java,v 1.3 2007/10/21 21:17:33 nfi Exp $ + * + * ----------------------------------------------------------------- + * + * Beeper + * + * Author : Joakim Eriksson + * Created : Sun Oct 21 22:00:00 2007 + * Updated : $Date: 2007/10/21 21:17:33 $ + * $Revision: 1.3 $ + */ + +package se.sics.mspsim.chip; +import javax.sound.sampled.*; +import se.sics.mspsim.core.*; + +/** + * Beeper for the esb... + */ +public class Beeper extends IOUnit { + + private SourceDataLine dataLine; + private FloatControl volume; + + public static final int SAMPLE_RATE = 44000; + + public static final int FRQ_1 = 2200; + + public static final int WAVE_LEN = (SAMPLE_RATE / FRQ_1); + + // One second of the sound in buffer + byte[] buffer = new byte[WAVE_LEN]; + byte[] quiet = new byte[WAVE_LEN]; + + int beepCtr = 0; + + public Beeper() { + super(null, 0); + AudioFormat af = new AudioFormat(SAMPLE_RATE, 8, 1, true, false); + DataLine.Info dli = + new DataLine.Info(SourceDataLine.class, af, 16384); + try { + dataLine = (SourceDataLine) AudioSystem.getLine(dli); + if (dataLine == null) { + System.out.println("DataLine: not existing..."); + } else { + dataLine.open(dataLine.getFormat(), 16384); + volume = (FloatControl) dataLine.getControl(FloatControl.Type.MASTER_GAIN); + } + } catch (Exception e) { + System.out.println("Problem while getting data line " + e); + } + double f1 = 0; + for (int i = 0, n = WAVE_LEN; i < n; i++) { + f1 = Math.sin(i * 3.141592 * 2 / WAVE_LEN) * 40; + f1 += Math.sin(i * 3.141592 * 4 / WAVE_LEN) * 30; + buffer[i] = (byte) (f1); + } + + if (dataLine != null) { + dataLine.start(); + } + } + + public void setVolue(int vol) { + volume.setValue(vol); + } + + public void beepOn(boolean beep) { + if (beep) { + beepCtr = 7; + } + } + + public long ioTick(long cycles) { + // Avoid blocking using timer... + if (dataLine != null) { + if (dataLine.available() > WAVE_LEN * 2) { + if (beepCtr > 0) { + dataLine.write(buffer, 0, WAVE_LEN); + beepCtr--; + } else { + dataLine.write(quiet, 0, WAVE_LEN); + } + } + } + return cycles + 1000; + } + + + public int read(int address, boolean word, long cycler) { + return 0; + } + + public void write(int address, int data, boolean word, long cycler) { + } + + public String getName() { + return "Beeper"; + } + + // Nothing for interrupts... + public void interruptServiced() { + } + + public static void main(String[] args) { + Beeper beep = new Beeper(); + while (true) { + beep.beepOn(true); + for (int i = 0, n = 1000; i < n; i++) { + beep.ioTick(0); + } + beep.beepOn(false); + for (int i = 0, n = 10000; i < n; i++) { + beep.ioTick(0); + } + } + } +} Added: mspsim/se/sics/mspsim/chip/CC2420.java =================================================================== --- mspsim/se/sics/mspsim/chip/CC2420.java (rev 0) +++ mspsim/se/sics/mspsim/chip/CC2420.java 2007-10-24 10:44:41 UTC (rev 4) @@ -0,0 +1,345 @@ +/** + * Copyright (c) 2007, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of MSPSim. + * + * $Id: CC2420.java,v 1.4 2007/10/22 18:03:41 joakime Exp $ + * + * ----------------------------------------------------------------- + * + * CC2420 + * + * Author : Joakim Eriksson + * Created : Sun Oct 21 22:00:00 2007 + * Updated : $Date: 2007/10/22 18:03:41 $ + * $Revision: 1.4 $ + */ + +package se.sics.mspsim.chip; +import se.sics.mspsim.core.*; +import se.sics.mspsim.util.Utils; + +public class CC2420 implements USARTListener { + + public static final boolean DEBUG = true; + + public static final int REG_SNOP = 0x00; + public static final int REG_SXOSCON = 0x01; + public static final int REG_STXCAL = 0x02; + public static final int REG_SRXON = 0x03; + public static final int REG_STXON = 0x04; + public static final int REG_STXONCCA = 0x05; + public static final int REG_SRFOFF = 0x06; + public static final int REG_SXOSCOFF = 0x07; + public static final int REG_SFLUSHRX = 0x08; + public static final int REG_SFLUSHTX = 0x09; + public static final int REG_SACK = 0x0A; + public static final int REG_SACKPEND = 0x0B; + public static final int REG_SRXDEC = 0x0C; + public static final int REG_STXENC = 0x0D; + public static final int REG_SAES = 0x0E; + public static final int REG_foo = 0x0F; + public static final int REG_MAIN = 0x10; + public static final int REG_MDMCTRL0 = 0x11; + public static final int REG_MDMCTRL1 = 0x12; + public static final int REG_RSSI = 0x13; + public static final int REG_SYNCWORD = 0x14; + public static final int REG_TXCTRL = 0x15; + public static final int REG_RXCTRL0 = 0x16; + public static final int REG_RXCTRL1 = 0x17; + public static final int REG_FSCTRL = 0x18; + public static final int REG_SECCTRL0 = 0x19; + public static final int REG_SECCTRL1 = 0x1A; + public static final int REG_BATTMON = 0x1B; + public static final int REG_IOCFG0 = 0x1C; + public static final int REG_IOCFG1 = 0x1D; + public static final int REG_MANFIDL = 0x1E; + public static final int REG_MANFIDH = 0x1F; + public static final int REG_FSMTC = 0x20; + public static final int REG_MANAND = 0x21; + public static final int REG_MANOR = 0x22; + public static final int REG_AGCCTRL = 0x23; + public static final int REG_AGCTST0 = 0x24; + public static final int REG_AGCTST1 = 0x25; + public static final int REG_AGCTST2 = 0x26; + public static final int REG_FSTST0 = 0x27; + public static final int REG_FSTST1 = 0x28; + public static final int REG_FSTST2 = 0x29; + public static final int REG_FSTST3 = 0x2A; + public static final int REG_RXBPFTST = 0x2B; + public static final int REG_FSMSTATE = 0x2C; + public static final int REG_ADCTST = 0x2D; + public static final int REG_DACTST = 0x2E; + public static final int REG_TOPTST = 0x2F; + public static final int REG_RESERVED = 0x30; + /* 0x31 - 0x3D not used */ + public static final int REG_TXFIFO = 0x3E; + public static final int REG_RXFIFO = 0x3F; + + public static final int ST_XOSC16M_STABLE = 1 << 6; + public static final int ST_TX_UNDERFLOW = 1 << 5; + public static final int ST_ENC_BUSY = 1 << 4; + public static final int ST_TX_ACTIVE = 1 << 3; + public static final int ST_LOCK = 1 << 2; + public static final int ST_RSSI_VALID = 1 << 1; + + // RAM Addresses + public static final int RAM_TXFIFO = 0x000; + public static final int RAM_RXFIFO = 0x080; + public static final int RAM_KEY0 = 0x100; + public static final int RAM_RXNONCE = 0x110; + public static final int RAM_SABUF = 0x120; + public static final int RAM_KEY1 = 0x130; + public static final int RAM_TXNONCE = 0x140; + public static final int RAM_CBCSTATE = 0x150; + public static final int RAM_IEEEADDR = 0x160; + public static final int RAM_PANID = 0x168; + public static final int RAM_SHORTADDR = 0x16A; + + // when reading registrers this flag is set! + public static final int FLAG_READ = 0x40; + + public static final int FLAG_RAM = 0x80; + // When accessing RAM the second byte of the address comtains + // a flag indicating read/write + public static final int FLAG_RAM_READ = 0x20; + + + public static final int WAITING = 0; + public static final int WRITE_REGISTER = 1; + public static final int READ_REGISTER = 2; + public static final int RAM_ACCESS = 3; + + public static final int READ_RXFIFO = 4; + public static final int WRITE_TXFIFO = 5; + + private int state = WAITING; + private int pos; + private int address; + private boolean ramRead = false; + + private int status = ST_XOSC16M_STABLE; + + private int[] registers = new int[64]; + // More than needed... + private int[] memory = new int[512]; + + private boolean chipSelect; + + private IOPort ccaPort = null; + private int ccaPin; + + private IOPort fifopPort = null; + private int fifopPin; + + private IOPort fifoPort = null; + private int fifoPin; + + private boolean rxPacket; + private int rxCursor; + private int rxLen; + + public CC2420() { + registers[REG_SNOP] = 0; + } + + public void dataReceived(USART source, int data) { + if (chipSelect) { + System.out.println("CC2420 byte received: " + Utils.hex8(data) + + '\'' + (char) data + '\'' + + " CS: " + chipSelect + " state: " + state); + switch(state) { + case WAITING: + state = WRITE_REGISTER; + if ((data & FLAG_READ) != 0) { + state = READ_REGISTER; + } + if ((data & FLAG_RAM) != 0) { + state = RAM_ACCESS; + address = data & 0x7f; + } else { + // The register address + address = data & 0x3f; + + if (address == REG_RXFIFO) { + // check read/write??? + System.out.println("CC2420: Reading RXFIFO!!!"); + state = READ_RXFIFO; + } else if (address == REG_TXFIFO) { + state = WRITE_TXFIFO; + } + } + if (data < 0x0f) { + strobe(data); + } + pos = 0; + // Assuming that the status always is sent back??? + source.byteReceived(status); + break; + case WRITE_REGISTER: + if (pos == 0) { + source.byteReceived(registers[address] >> 8); + // set the high bits + registers[address] = registers[address] & 0xff | (data << 8); + } else { + source.byteReceived(registers[address] & 0xff); + // set the low bits + registers[address] = registers[address] & 0xff00 | data; + System.out.println("CC2420: wrote to " + Utils.hex8(address) + " = " + + registers[address]); + } + break; + case READ_REGISTER: + if (pos == 0) { + source.byteReceived(registers[address] >> 8); + } else { + source.byteReceived(registers[address] & 0xff); + System.out.println("CC2420: read from " + Utils.hex8(address) + " = " + + registers[address]); + } + break; + case READ_RXFIFO: + System.out.println("CC2420: RXFIFO READ => " + + memory[RAM_RXFIFO + rxCursor]); + source.byteReceived(memory[RAM_RXFIFO + rxCursor++]); + // What if wrap cursor??? + if (rxCursor >= 128) rxCursor = 0; + // When is this set to "false" - when is interrupt de-triggered? + if (rxPacket) { + rxPacket = false; + updateFifopPin(); + } + break; + case RAM_ACCESS: + if (pos == 0) { + address = address | (data << 1) & 0x180; + ramRead = (data & 0x20) != 0; + System.out.println("CC2420: Address: " + Utils.hex16(address) + + " read: " + ramRead); + pos++; + } else { + if (!ramRead) { + memory[address++] = data; + if (address == RAM_PANID + 2) { + System.out.println("CC2420: Pan ID set to: 0x" + + Utils.hex8(memory[RAM_PANID]) + + Utils.hex8(memory[RAM_PANID + 1])); + } + } + } + break; + } + } + } + + // Needs to get information about when it is possible to write + // next data... + + private void strobe(int data) { + // Resets, on/off of different things... + System.out.println("CC2420: Strobe on: " + Utils.hex8(data)); + + switch (data) { + case REG_SRXON: + System.out.println("CC2420: Strobe RX-ON!!!"); + break; + case REG_SFLUSHRX: + flushRX(); + break; + } + } + + + public void setChipSelect(boolean select) { + chipSelect = select; + if (!chipSelect) + state = WAITING; + System.out.println("CC2420: chipSelect: " + chipSelect); + } + + public void setCCAPort(IOPort port, int pin) { + ccaPort = port; + ccaPin = pin; + } + + public void setFIFOPPort(IOPort port, int pin) { + fifopPort = port; + fifopPin = pin; + } + + public void setFIFOPort(IOPort port, int pin) { + fifoPort = port; + fifoPin = pin; + } + + + // ------------------------------------------------------------------- + // Methods for accessing and writing to registers, etc from outside + // ------------------------------------------------------------------- + + public int getRegister(int register) { + return registers[register]; + } + + public void setRegister(int register, int data) { + registers[register] = data; + } + + public void setIncomingPacket(int[] packet) { + int adr = RAM_RXFIFO; + memory[adr++] = packet.length + 2; + for (int i = 0, n = packet.length; i < n; i++) { + memory[adr++] = packet[i] & 0xff; + } + // Should take a RSSI value as input or use a set-RSSI value... + memory[adr++] = (202) & 0xff; + // Set CRC ok and add a correlation + memory[adr++] = (37) | 0x80; + rxPacket = true; + rxCursor = 0; + rxLen = adr; + updateFifopPin(); + } + + private void flushRX() { + if (DEBUG) System.out.println("Flushing RX! was: " + rxPacket + " len = " + + rxLen); + rxPacket = false; + rxCursor = 0; + rxLen = 0; + updateFifopPin(); + } + + private void updateFifopPin() { + fifopPort.setPinState(fifopPin, rxPacket ? 1 : 0); + } + + public void setCCA(boolean cca) { + ccaPort.setPinState(ccaPin, cca ? 1 : 0); + } + +} // CC2420 Added: mspsim/se/sics/mspsim/core/BasicClockModule.java =================================================================== --- mspsim/se/sics/mspsim/core/BasicClockModule.java (rev 0) +++ mspsim/se/sics/mspsim/core/BasicClockModule.java 2007-10-24 10:44:41 UTC (rev 4) @@ -0,0 +1,165 @@ +/** + * Copyright (c) 2007, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of MSPSim. + * + * $Id: BasicClockModule.java,v 1.3 2007/10/21 21:17:34 nfi Exp $ + * + * ----------------------------------------------------------------- + * + * BasicClockModule + * + * Author : Joakim Eriksson + * Created : Sun Oct 21 22:00:00 2007 + * Updated : $Date: 2007/10/21 21:17:34 $ + * $Revision: 1.3 $ + */ + +package se.sics.mspsim.core; +import se.sics.mspsim.util.Utils; + +public class BasicClockModule extends IOUnit { + + public static final int DCOCTL = 0x56; + public static final int BCSCTL1 = 0x57; + public static final int BCSCTL2 = 0x58; + + public static final int ACLK_FRQ = 32768; + // DCO_FRQ what default frq is the DCO running at??? + public static final int DCO_FRQ = 2500000; + // What frequency steps to take for the DCO? + // We have 8 bits + 3 => 11 bits => 2048 combinations... + // => What is lowest frq??? (zero) + // Max speed is 8Mhz (CPU limits it) - is max DCO 8Mhz? + // Based on the scatterweb code it looks like less than + // 5Mhz is more correct... + public static final int MAX_DCO_FRQ = 4915200; + public static final int DCO_FACTOR = MAX_DCO_FRQ / 2048; + + + private MSP430Core core; + + private int dcoFrequency; + private int dcoModulator; + private int resistorSel; + // These will give => + private int calcDCOFrq; + private int divAclk = 1; + private int lfxt1Mode; + private int xt2Off; + private int mclkSel; + private int divMclk = 1; + private int smclSel; + private int divSMclk = 1; + private int dcoResitorSel; + + /** + * Creates a new <code>BasicClockModule</code> instance. + * + */ + public BasicClockModule(MSP430Core core, int[] memory, int offset) { + super(memory, offset); + this.core = core; + init(); + } + + public void init() { + // What should be initial values? + memory[DCOCTL] = 0; + } + + // Should return the cycle it wants the next tick... + public long ioTick(long cycles) { + return cycles + 4711; + } + + // do nothing? + public int read(int address, boolean word, long cycles) { + int val = memory[address]; + if (word) { + val |= memory[(address + 1) & 0xffff] << 8; + } + return val; + } + + public void write(int address, int data, boolean word, long cycles) { + // Currently ignores the word flag... + System.out.println("Write to BasicClockModule: " + + Utils.hex16(address) + " => " + Utils.hex16(data)); + + memory[address] = data & 0xff; + if (word) memory[address + 1] = (data >> 8) & 0xff; + + + switch (address) { + case DCOCTL: + dcoFrequency = (data >> 5) & 0x7; + dcoModulator = data & 0x1f; + System.out.println("Write: BCM DCOCTL0: DCO Frq:" + dcoFrequency + + " dcoMod:" + dcoModulator); + break; + case BCSCTL1: + resistorSel = data & 0x7; + divAclk = 1 << ((data >> 4) & 3); + lfxt1Mode = (data >> 6) & 1; + xt2Off = (data >> 7) & 1; + System.out.println("Write: BCM BCSCTL1: RSel:" + resistorSel + + " DivACLK:" + divAclk + " ACLKFrq: " + + ACLK_FRQ / divAclk); + core.setACLKFrq(ACLK_FRQ / divAclk); + break; + case BCSCTL2: + mclkSel = (data >> 6) & 3; + divMclk = 1 << ((data >> 4) & 3); + smclSel = (data >> 3) & 1; + divSMclk = 1 << ((data >> 2) & 3); + dcoResitorSel = data & 1; + System.out.println("Write: BCM BCSCTL2: SMCLKDIV: " + + divSMclk + " SMCLK_SEL: " + + smclSel + " MCLKSel: " + mclkSel + " divMclk: " + + divMclk + " DCOResitorSel: " + dcoResitorSel); + core.setDCOFrq(calcDCOFrq, calcDCOFrq / divSMclk); + break; + } + + + int newcalcDCOFrq = ((dcoFrequency << 5) + dcoModulator + + (resistorSel << 8)) * DCO_FACTOR; + if (newcalcDCOFrq != calcDCOFrq) { + calcDCOFrq = newcalcDCOFrq; + System.out.println("BCM DCO_Speed: " + calcDCOFrq); + core.setDCOFrq(calcDCOFrq, calcDCOFrq / divSMclk); + } + } + + public String getName() { + return "BasicClockModule"; + } + + public void interruptServiced() { + } +} Added: mspsim/se/sics/mspsim/core/CPUMonitor.java =================================================================== --- mspsim/se/sics/mspsim/core/CPUMonitor.java (rev 0) +++ mspsim/se/sics/mspsim/core/CPUMonitor.java 2007-10-24 10:44:41 UTC (rev 4) @@ -0,0 +1,54 @@ +/** + * Copyright (c) 2007, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of MSPSim. + * + * $Id: CPUMonitor.java,v 1.3 2007/10/21 21:17:34 nfi Exp $ + * + * ----------------------------------------------------------------- + * + * CPUMonitor + * + * Author : Joakim Eriksson + * Created : Sun Oct 21 22:00:00 2007 + * Updated : $Date: 2007/10/21 21:17:34 $ + * $Revision: 1.3 $ + */ + +package se.sics.mspsim.core; + +public interface CPUMonitor { + + public static final int MEMORY_READ = 1; + public static final int MEMORY_WRITE = 2; + public static final int REGISTER_READ = 3; + public static final int REGISTER_WRITE = 4; + public static final int BREAK = 5; + + public void cpuAction(int type, int adr, int data); + +} Added: mspsim/se/sics/mspsim/core/DbgInstruction.java =================================================================== --- mspsim/se/sics/mspsim/core/DbgInstruction.java (rev 0) +++ mspsim/se/sics/mspsim/core/DbgInstruction.java 2007-10-24 10:44:41 UTC (rev 4) @@ -0,0 +1,106 @@ +/** + * Copyright (c) 2007, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of MSPSim. + * + * $Id: DbgInstruction.java,v 1.3 2007/10/21 21:17:34 nfi Exp $ + * + * ----------------------------------------------------------------- + * + * DbgInstruction + * + * Author : Joakim Eriksson + * Created : Sun Oct 21 22:00:00 2007 + * Updated : $Date: 2007/10/21 21:17:34 $ + * $Revision: 1.3 $ + */ + +package se.sics.mspsim.core; + +public class DbgInstruction { + + private String asmLine; + private String regs; + private String function; + private int instruction; + private int size; + private int pos; + + public DbgInstruction() { + } + + public void setPos(int p) { + pos = p; + } + + public int getPos() { + return pos; + } + + public void setASMLine(String line) { + asmLine = line; + } + + public void setRegs(String regs) { + this.regs = regs; + } + + public void setInstruction(int instruction, int size) { + this.instruction = instruction; + this.size = size; + } + + public int getSize() { + return size; + } + + public int getInstruction() { + return instruction; + } + + public String getASMLine(boolean showregs) { + if (showregs) return getASMLine(); + return asmLine; + } + + public String getASMLine() { + return asmLine + "\t" + regs; + } + + public void setFunction(String fkn) { + function = fkn; + } + + public String getFunction() { + return function; + } + + public String toString() { + return getASMLine(); + } + +} Added: mspsim/se/sics/mspsim/core/DisAsm.java =================================================================== --- mspsim/se/sics/mspsim/core/DisAsm.java (rev 0) +++ mspsim/se/sics/mspsim/core/DisAsm.java 2007-10-24 10:44:41 UTC (rev 4) @@ -0,0 +1,457 @@ +/** + * Copyright (c) 2007, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of MSPSim. + * + * $Id: DisAsm.java,v 1.3 2007/10/21 21:17:34 nfi Exp $ + * + * ----------------------------------------------------------------- + * + * DisAsm + * + * Author : Joakim Eriksson + * Created : Sun Oct 21 22:00:00 2007 + * Updated : $Date: 2007/10/21 21:17:34 $ + * $Revision: 1.3 $ + */ + +package se.sics.mspsim.core; +import java.io.BufferedReader; +import java.io.InputStreamReader; + +import se.sics.mspsim.util.Utils; + +public class DisAsm implements MSP430Constants { + + private boolean step = true; //false; + + private MapTable map; + + // Idiots solution to single stepping... + private BufferedReader input = + new BufferedReader(new InputStreamReader(System.in)); + + public void setMap(MapTable m) { + map = m; + } + + public MapTable getMap() { + return map; + } + + public DbgInstruction disassemble(int pc, int[] memory, int[] reg) { + return disassemble(pc, memory, reg, 0); + } + + public DbgInstruction disassemble(int pc, int[] memory, int[] reg, + int interrupt) { + DbgInstruction dbg = disassemble(pc, memory, reg, new DbgInstruction(), + interrupt); + String fkn; + if ((fkn = dbg.getFunction()) != null) { + System.out.println("//// " + fkn); + } + System.out.println(dbg.getASMLine()); + return dbg; + } + + public DbgInstruction getDbgInstruction(int pc, MSP430 cpu) { + return disassemble(pc, cpu.memory, cpu.reg, new DbgInstruction(), + cpu.servicedInterrupt); + } + + public DbgInstruction disassemble(int pc, int[] memory, int[] reg, + DbgInstruction dbg, int interrupt) { + int startPC = pc; + int size = 0; + int instruction = memory[pc] + (memory[pc + 1] << 8); + int op = instruction >> 12; + boolean word = (instruction & 0x40) == 0; + + String output = " "; + if (interrupt > 0) { + output = "I:" + Integer.toString(interrupt) + ' '; + } + + String regs = ""; + + + if (pc < 0x0010) { + output += "000" + Integer.toString(pc, 16); + } else if (pc < 0x0100) { + output += "00" + Integer.toString(pc, 16); + } else if (pc < 0x1000) { + output += "0" + Integer.toString(pc, 16); + } else { + output += Integer.toString(pc, 16); + } + + + output += ":\t"; + + pc += 2; + size += 2; + + switch (op) { + case 1: // Single operand instructions + { + // Register + int register = instruction & 0xf; + // Adress mode of destination... + int ad = (instruction >> 4) & 3; + // Pick up the destination address based on ad more and regs... + int dstAddress = 0; + String adr = ""; + String opstr = ""; + switch(ad) { + // Operand in register! + case AM_REG: + adr = "R" + register; + break; + case AM_INDEX: + dstAddress = memory[pc] + (memory[pc + 1] << 8); + adr = "R" + register + "(" + dstAddress + ")"; + dstAddress = (register == CG1 ? 0 : reg[register]) + dstAddress; + pc += 2; + size += 2; + break; + // Indirect register + case AM_IND_REG: + adr = "@(R" + register + ")"; + dstAddress = reg[register]; + break; + case AM_IND_AUTOINC: + if (register == 0) { + // Can this be PC and be incremented only one byte? + adr = "#" + Utils.hex16(memory[pc] + (memory[pc + 1] << 8)); + size += 2; + } else { + adr = "@(R" + register + "+)"; + dstAddress = reg[register]; + } + break; + } + + switch(instruction & 0xff80) { + case RRC: + opstr = "RRC" + (word ? ".W" : ".B"); + break; + case SWPB: + opstr = "SWPB" + (word ? ".W" : ".B"); + break; + case RRA: + opstr = "RRA" + (word ? ".W" : ".B"); + break; + case SXT: + opstr = "RRA" + (word ? ".W" : ".B"); + break; + case PUSH: + opstr = "PUSH" + (word ? ".W" : ".B"); + break; + case CALL: + opstr = "CALL"; + break; + case RETI: + opstr = "RETI"; + break; + default: + System.out.println("Not implemented instruction: " + instruction); + } + output += dumpMem(startPC, size, memory); + output += opstr + " " + adr; + regs = "R" + register + "=" + Utils.hex16(reg[register]); + regs += " SP=" + Utils.hex16(reg[SP]); + } + break; + // Jump instructions + case 2: + case 3: + // 10 bits for address for these => 0x00fc => remove 2 bits + int jmpOffset = instruction & 0x3ff; + jmpOffset = (jmpOffset & 0x200) == 0 ? + 2 * jmpOffset : -(2 * (0x200 - (jmpOffset & 0x1ff))); + boolean jump = false; + String opstr = ""; + switch(instruction & 0xfc00) { + case JNE: + opstr = "JNE"; + break; + case JEQ: + opstr = "JEQ"; + break; + case JNC: + opstr = "JNC"; + break; + case JC: + opstr = "JC"; + break; + case JN: + opstr = "JN"; + break; + case JGE: + opstr = "JGE"; + break; + case JL: + opstr = "JL"; + break; + case JMP: + opstr = "JMP"; + break; + default: + System.out.println("Not implemented instruction: " + + Utils.binary16(instruction)); + } + output += dumpMem(startPC, size, memory); + output += opstr + " " + Integer.toString(jmpOffset, 16); + regs = "\tSR=" + dumpSR(reg[SR]); + break; + default: + // --------------------------------------------------------------- + // Double operand instructions! + // --------------------------------------------------------------- + int dstRegister = (instruction & 0xf); + int srcRegister = (instruction >> 8) & 0xf; + int as = (instruction >> 4) & 3; + + // AD: 0 => register direct, 1 => register index, e.g. X(Rn) + boolean dstRegMode = ((instruction >> 7) & 1) == 0; + int dstAddress = 0; + int srcAddress = 0; + int src = 0; + int dst = 0; + boolean write = false; + boolean updateStatus = true; + String srcadr = ""; + String dstadr = ""; + switch(as) { + // Operand in register! + case AM_REG: + if (srcRegister == CG2) { + srcadr = "#0"; + } else if (srcRegister == CG1) { + srcadr = "#0"; + } else { + srcadr = getRegName(srcRegister); + } + break; + case AM_INDEX: + // Indexed if reg != PC & CG1/CG2 - will PC be incremented? + if (srcRegister == CG1) { + srcAddress = memory[pc] + (memory[pc + 1] << 8); + srcadr = "&" + Utils.hex16(srcAddress); + size += 2; + } else if (srcRegister == CG2) { + srcadr = "#1"; + } else { + srcAddress = reg[srcRegister] + memory[pc] + (memory[pc + 1] << 8); + srcadr = "(R" + srcRegister + ")"; + } + break; + // Indirect register + case AM_IND_REG: + if (srcRegister == CG2) { + srcadr = "#2"; + } else if (srcRegister == CG1) { + srcadr = "#4"; + } else { + srcadr = "@" + getRegName(srcRegister); + } + break; + case AM_IND_AUTOINC: + if (srcRegister == CG2) { + srcadr = "#$ffff"; + } else if (srcRegister == CG1) { + srcadr = "#8"; + } else if (srcRegister == PC) { + srcadr = "#" + Utils.hex16(memory[pc] + (memory[pc + 1] << 8)); + pc += 2; + size += 2; + } else if (srcRegister == CG2) { + srcadr = "#ffff"; + } else { + srcadr = "@" + getRegName(srcRegister) + "+"; + srcAddress = reg[srcRegister]; + } + break; + } + + if (dstRegMode) { + dstadr = getRegName(dstRegister); + } else { + dstAddress = memory[pc] + (memory[pc + 1] << 8); + if (dstRegister == 2) { + dstadr = "&" + Utils.hex16(dstAddress); + } else { + dstadr = Utils.hex16(dstAddress) + "(R" + dstRegister + ")"; + } + pc += 2; + size += 2; + } + + // If byte mode the source will not contain the full word... + if (!word) { + src = src & 0xff; + dst = dst & 0xff; + } + opstr = ""; + switch (op) { + case MOV: // MOV + if (instruction == 0x3041) { + opstr = "RET /emulated: MOV.W "; + } else { + opstr = "MOV" + (word ? ".W" : ".B"); + } + break; + case ADD: // ADD + opstr = "ADD" + (word ? ".W" : ".B"); + break; + case ADDC: // ADDC + opstr = "ADDC" + (word ? ".W" : ".B"); + break; + case SUBC: // SUBC + opstr = "SUBC" + (word ? ".W" : ".B"); + break; + case SUB: // SUB + opstr = "SUB" + (word ? ".W" : ".B"); + break; + case CMP: // CMP + opstr = "CMP" + (word ? ".W" : ".B"); + break; + case DADD: // DADD + opstr = "DADD" + (word ? ".W" : ".B"); + break; + case BIT: // BIT + opstr = "BIT" + (word ? ".W" : ".B"); + break; + case BIC: // BIC + opstr = "BIC" + (word ? ".W" : ".B"); + break; + case BIS: // BIS + opstr = "BIS" + (word ? ".W" : ".B"); + break; + case XOR: // XOR + opstr = "XOR" + (word ? ".W" : ".B"); + break; + case AND: // AND + opstr = "AND" + (word ? ".W" : ".B"); + break; + default: + System.out.println(output + " DoubleOperand not implemented: " + + op + " instruction: " + + Utils.binary16(instruction) + " = " + + Utils.hex16(instruction)); + } + + + output += dumpMem(startPC, size, memory); + output += opstr + " " + srcadr + ", " + dstadr; + + regs = "R" + dstRegister + "=" + Utils.hex16(reg[dstRegister]) + + " R" + srcRegister + "=" + Utils.hex16(reg[srcRegister]); + regs += " SR=" + dumpSR(reg[SR]); + regs += " SP=" + Utils.hex16(reg[SP]); + regs += "; as = " + as; + srcAddress &= 0xffff; + if (srcAddress != -1) { + srcAddress &= 0xffff; + regs += " sMem:" + Utils.hex16(memory[srcAddress] + + (memory[(srcAddress + 1) % 0xffff] + << 8)); + } + } + + dbg.setASMLine(output); + dbg.setRegs(regs); + dbg.setInstruction(instruction, size); + if (map != null) { + dbg.setFunction(map.getFunction(startPC)); + } + + if (!step) { + String line = ""; + try {line = input.readLine();}catch(Exception e){} + if (line != null && line.length() > 0 && line.charAt(0) == 'r') { + System.out.println("Registers:"); + for (int i = 0, n = 16; i < n; i++) { + System.out.print("R" + i + "=" + Utils.hex16(reg[i]) + " "); + if (i % 7 == 0 && i != 0) System.out.println(); + } + System.out.println(); + } + } + return dbg; + } + + private String getRegName(int index) { + if (index == 0) return "PC"; + if (index == 1) return "SP"; + if (index == 2) return "SR"; + return "R" + index; + } + + public static String getSingleOPStr(int instruction) { + boolean word = (instruction & 0x40) == 0; + switch(instruction & 0xff80) { + case RRC: + return "RRC" + (word ? ".W" : ".B"); + case SWPB: + return "SWPB" + (word ? ".W" : ".B"); + case RRA: + return "RRA" + (word ? ".W" : ".B"); + case SXT: + return "RRA" + (word ? ".W" : ".B"); + case PUSH: + return "PUSH" + (word ? ".W" : ".B"); + case CALL: + return "CALL"; + case RETI: + return "RETI"; + default: + return "-"; + } + } + + private static String dumpSR(int sr) { + return "" + + (((sr & OVERFLOW) != 0) ? 'V' : '-') + + (((sr & NEGATIVE) != 0) ? 'N' : '-') + + (((sr & ZERO) != 0) ? 'Z' : '-') + + (((sr & CARRY) != 0) ? 'C' : '-'); + } + + private static String dumpMem(int pc, int size, int[] memory) { + String output = ""; + for (int i = 0, n = 4; i < n; i++) { + if (size > i) { + output += Utils.hex8(memory[pc + i]) + " "; + } else { + output += " "; + } + } + return output; + } +} Added: mspsim/se/sics/mspsim/core/IOPort.java =================================================================== --- mspsim/se/sics/mspsim/core/IOPort.java (rev 0) +++ mspsim/se/sics/mspsim/core/IOPort.java 2007-10-24 10:44:41 UTC (rev 4) @@ -0,0 +1,199 @@ +/** + * Copyright (c) 2007, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of MSPSim. + * + * $Id: IOPort.java,v 1.3 2007/10/21 21:17:34 nfi Exp $ + * + * ----------------------------------------------------------------- + * + * IOPort + * + * Author : Joakim Eriksson + * Created : Sun Oct 21 22:00:00 2007 + * Updated : $Date: 2007/10/21 21:17:34 $ + * $Revision: 1.3 $ + */ + +package se.sics.mspsim.core; +import se.sics.mspsim.util.Utils; + +public class IOPort extends IOUnit { + + public static final int PIN_LOW = 0; + public static final int PIN_HI = 1; + + public static final boolean DEBUG = false; + + public static final String[] iNames = { + "P_IN","P_OUT", "P_DIR", "P_IFG", "P_IES", "P_IE", "P_SEL" }; + public static final String[] names = { + "P_IN", "P_OUT", "P_DIR", "P_SEL" }; + + private String name; + private int interrupt; + private int interruptFlag; + private MSP430Core cpu; + + // External pin state! + private int pinState[] = new int[8]; + + public static final int IN = 0; + public static final int OUT = 1; + public static final int DIR = 2; + public static final int SEL = 3; + public static final int IFG = 3; + public static final int IES = 4; + public static final int IE = 5; + public static final int ISEL = 6; + + // One listener per port maximum (now at leat) + private PortListener listener; + + /** + * Creates a new <code>IOPort</code> instance. + * + */ + public IOPort(MSP430Core cpu, String portName, + int interrupt, int[] memory, int offset) { + super(memory, offset); + name = portName; + this.interrupt = interrupt; + this.cpu = cpu; + } + + public void setPortListener(PortListener listener) { + this.listener = listener; + } + + public int read(int address, boolean word, long cycles) { + if (DEBUG) { + System.out.println("Notify read: " + address); + } + + int val = memory[address]; + if (word) { + val |= memory[(address + 1) & 0xffff] << 8; + } + return val; + } + + public void write(int address, int data, boolean word, long cycles) { + memory[address] = data & 0xff; + if (word) memory[address + 1] = (data >> 8) & 0xff; + + // This does not handle word writes yet... + int iAddress = address - offset; + + if (DEBUG) { + try { + System.out.println("Writing to " + getName() + ":" + + (interrupt > 0? iNames[iAddress] : names[iAddress]) + + " " + Utils.hex8(address) + + " => " + Utils.hex8(data) + "=#" + + Utils.binary8(data) + " word: " + word); + } catch (Exception e) { + e.printStackTrace(); + } + } + + switch (iAddress) { + case IN: + break; + case OUT: + if (listener != null) { + listener.portWrite(this, data); + } + break; + case DIR: + break; + // SEL & IFG is the same but behaviour differs between p1,p2 and rest... + case SEL: + // case IFG: + if (interrupt > 0) { + // IFG - writing a zero => clear the flag! + System.out.println(getName() + " Clearing IFlag: " + data); + interruptFlag &= data; + memory[offset + IFG] = interruptFlag; + cpu.flagInterrupt(interrupt, this, interruptFlag > 0); + } else { + // Samel as ISEL!!! + } + break; + case IES: + break; + case IE: + break; + case ISEL: + } + } + + public String getName() { + return "Port " + name; + } + + public void interruptServiced() { + } + + // for HW to set hi/low on the pins... + public void setPinState(int pin, int state) { + if (interrupt > 0) { + if (pinState[pin] != state) { + pinState[pin] = state; + int bit = 1 << pin; + if ((memory[offset + IES] & bit) == 0) { + // LO/HI transition + if (state == PIN_HI) { + interruptFlag |= bit; + System.out.println(getName() + " Flagging interrupt (HI): " + bit); + } + } else { + // HI/LO transition + if (state == PIN_LOW) { + interruptFlag |= bit; + System.out.println(getName() + " Flagging interrupt (LOW): " + + bit); + } + } + } + } + memory[offset + IFG] = interruptFlag; + + // Maybe this is not the only place where we should flag int? + cpu.flagInterrupt(interrupt, this, interruptFlag > 0); + } + + + public void reset() { + for (int i = 0, n = 8; i < n; i++) { + pinState[i] = PIN_LOW; + } + interruptFlag = 0; + cpu.flagInterrupt(interrupt, this, interruptFlag > 0); + } + +} Added: mspsim/se/sics/mspsim/core/IOUnit.java =================================================================== --- mspsim/se/sics/mspsim/core/IOUnit.java (rev 0) +++ mspsim/se/sics/mspsim/core/IOUnit.java 2007-10-24 10:44:41 UTC (rev 4) @@ -0,0 +1,100 @@ +/** + * Copyright (c) 2007, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of MSPSim. + * + * $Id: IOUnit.java,v 1.3 2007/10/21 21:17:34 nfi Exp $ + * + * ----------------------------------------------------------------- + * + * IOUnit + * + * Author : Joakim Eriksson + * Created : Sun Oct 21 22:00:00 2007 + * Updated : $Date: 2007/10/21 21:17:34 $ + * $Revision: 1.3 $ + */ + +package se.sics.mspsim.core; + +public abstract class IOUnit { + + int[] memory; + int offset; + + public IOUnit(int[] memory, int offset) { + this.memory = memory; + this.offset = offset; + } + + public void reset() { + } + + public boolean needsTick() { + return true; + } + + // Default implementation assums notify write and read on all + // addresses (should be optimized for each unit) + public boolean needsWrite(int address) { + return true; + } + + public boolean needsRead(int address) { + return true; + } + + // Should return the cycle it wants the next tick... + public long ioTick(long cycles) { + return cycles + 1000000; + } + + // write + // write a value to the IO unit + public abstract void write(int address, int value, boolean word, + long cycles); + + // read + // read a value from the IO unit + public abstract int read(int address, boolean word, long cycles); + + public abstract String getName(); + + // We should add "Interrupt serviced..." to indicate that its latest + // Interrupt was serviced... + public abstract void interruptServiced(); + + // Utility function for converting 16 bits data to correct return + // value depending on address alignment and word/byte mode + public static int return16(int address, int data, boolean word) { + if (word) return data; + // First byte => low byte + if ((address & 1) == 0) return data & 0xff; + // Second byte => hi byte + return (data >> 8) & 0xff; + } +} Added: mspsim/se/sics/mspsim/core/MSP430.java =================================================================== --- mspsim/se/sics/mspsim/core/MSP430.java (rev 0) +++ mspsim/se/sics/mspsim/core/MSP430.java 2007-10-24 10:44:41 UTC (rev 4) @@ -0,0 +1,281 @@ +/** + * Copyright (c) 2007, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of MSPSim. + * + * $Id: MSP430.java,v 1.4 2007/10/21 22:02:22 nfi Exp $ + * + * ----------------------------------------------------------------- + * + * MSP430 + * + * Author : Joakim Eriksson + * Created : Sun Oct 21 22:00:00 2007 + * Updated : $Date: 2007/10/21 22:02:22 $ + * $Revision: 1.4 $ + */ + +package se.sics.mspsim.core; +import java.util.Arrays; +import java.util.Hashtable; + +import se.sics.mspsim.util.Utils; + +public class MSP430 extends MSP430Core { + + public static final int RETURN = 0x4130; + + private int[] execCounter; + + private boolean debug = false; + private boolean running = false; + + // Debug time - measure cycles + private long lastCycles = 0; + private long time; + + private long instCtr = 0; + + private DisAsm disAsm; + + private MapTable map; + private Hashtable<String,CallEntry> profileData; + private CallEntry[] callStack; + private int cSP = 0; + + /** + * Creates a new <code>MSP430</code> instance. + * + */ + public MSP430(int type) { + super(type); + disAsm = new DisAsm(); + } + + public DisAsm getDisAsm() { + return disAsm; + } + + public void cpuloop() { + if (running) { + throw new IllegalStateException("already running"); + } + running = true; + // ??? - power-up reset should be executed?! + time = System.currentTimeMillis(); + run(); + } + + private void run() { + while (running) { + // ------------------------------------------------------------------- + // Debug information + // ------------------------------------------------------------------- + if (debug) { + if (servicedInterrupt >= 0) { + disAsm.disassemble(reg[PC], memory, reg, servicedInterrupt); + } else { + disAsm.disassemble(reg[PC], memory, reg); + } + } + + instCtr++; + if ((instCtr % 10000007) == 0 && !debug) { + printCPUSpeed(reg[PC]); + } + + if (execCounter != null) { + execCounter[reg[PC]]++; + } + + emulateOP(); + +// if ((instruction & 0xff80) == CALL) { +// System.out.println("Call to PC = " + reg[PC]); +// } + + if (map != null) { + if ((instruction & 0xff80) == CALL) { + profileCall(map.getFunction(reg[PC]), cycles); + // System.out.println("Call," + map.getFunction(reg[PC]) + "," + + // cycles); + } else if (instruction == RETURN) { + profileReturn(cycles); + //System.out.println("Return," + cycles); + } + } + } + } + + private void profileCall(String function, long cycles) { +// System.out.println("Call at: " + Utils.hex16(reg[PC])); + if (callStack[cSP] == null) { + callStack[cSP] = new CallEntry(); + } + if (function == null) { + function = "fkn at $" + Utils.hex16(reg[PC]); + } + callStack[cSP].function = function; + callStack[cSP++].cycles = cycles; + } + + private void profileReturn(long cycles) { + String fkn = callStack[--cSP].function; +// System.out.println("Profiler: return / call stack: " + cSP + ", " + fkn); + + long elapsed = cycles - callStack[cSP].cycles; + CallEntry ce = profileData.get(fkn); + if (ce == null) { + profileData.put(fkn, ce = new CallEntry()); + ce.function = fkn; + ce.cycles = elapsed; + } else { + ce.cycles += elapsed; + } + } + + public void printProfile() { + CallEntry[] entries = + profileData.values().toArray(new CallEntry[0]); + Arrays.sort(entries); + for (int i = 0, n = entries.length; i < n; i++) { + printFkn(entries[i].function); + System.out.println(" " + entries[i].cycles); + } + } + + public void printFkn(String f) { + System.out.print(f); + int len = f.length(); + if (len < 40) + len = 40 - len; + else + len = 0; + for (int i = 0, n = len; i < n; i++) { + System.out.print(" "); + } + } + + public long step() { + if (running) { + throw new IllegalStateException("step not possible when CPU is running"); + } + + // ------------------------------------------------------------------- + // Debug information + // ------------------------------------------------------------------- + if (debug) { + if (servicedInterrupt >= 0) { + disAsm.disassemble(reg[PC], memory, reg, servicedInterrupt); + } else { + disAsm.disassemble(reg[PC], memory, reg); + } + } + + instCtr++; + if ((instCtr % 10000007) == 0 && !debug) { + printCPUSpeed(reg[PC]); + } + + if (e... [truncated message content] |