From fcae84940391da9bca0b7129bf4a83f79d787e40 Mon Sep 17 00:00:00 2001 From: Niclas Finne Date: Fri, 25 May 2012 20:14:44 +0200 Subject: [PATCH] Moved IO unit memory map into the IO memory segments --- se/sics/mspsim/config/MSP430f1611Config.java | 84 ++------ se/sics/mspsim/config/MSP430f2617Config.java | 91 ++------- se/sics/mspsim/config/MSP430f5437Config.java | 11 +- se/sics/mspsim/core/IOPort.java | 28 ++- se/sics/mspsim/core/IOSegment.java | 47 ++++- se/sics/mspsim/core/MSP430Core.java | 194 ++++++++----------- 6 files changed, 170 insertions(+), 285 deletions(-) diff --git a/se/sics/mspsim/config/MSP430f1611Config.java b/se/sics/mspsim/config/MSP430f1611Config.java index fbb1804..410dfaa 100644 --- a/se/sics/mspsim/config/MSP430f1611Config.java +++ b/se/sics/mspsim/config/MSP430f1611Config.java @@ -72,36 +72,23 @@ public class MSP430f1611Config extends MSP430Config { USART usart0 = new USART(cpu, 0, cpu.memory, 0x70); USART usart1 = new USART(cpu, 1, cpu.memory, 0x78); - - for (int i = 0, n = 8; i < n; i++) { - cpu.memOut[0x70 + i] = usart0; - cpu.memIn[0x70 + i] = usart0; + cpu.setIORange(0x70, 8, usart0); + cpu.setIORange(0x78, 8, usart1); - cpu.memOut[0x78 + i] = usart1; - cpu.memIn[0x78 + i] = usart1; - } - Multiplier mp = new Multiplier(cpu, cpu.memory, 0); - // Only cares of writes! - for (int i = 0x130, n = 0x13f; i < n; i++) { - cpu.memOut[i] = mp; - cpu.memIn[i] = mp; - } - + cpu.setIORange(0x130, 0x0f, mp); + // Usarts ioUnits.add(usart0); ioUnits.add(usart1); DMA dma = new DMA("dma", cpu, cpu.memory, 0); - for (int i = 0, n = 24; i < n; i++) { - cpu.memOut[0x1E0 + i] = dma; - cpu.memIn[0x1E0 + i] = dma; - } + cpu.setIORange(0x1e0, 24, dma); /* DMA Ctl */ - cpu.memOut[0x122] = dma; - cpu.memIn[0x124] = dma; - + cpu.setIORange(0x122, 1, dma); + cpu.setIORange(0x124, 1, dma); + /* configure the DMA */ dma.setDMATrigger(DMA.URXIFG0, usart0, 0); dma.setDMATrigger(DMA.UTXIFG0, usart0, 1); @@ -112,60 +99,23 @@ public class MSP430f1611Config extends MSP430Config { ioUnits.add(dma); // Add port 1,2 with interrupt capability! - IOPort io1; - IOPort io2; - ioUnits.add(io1 = new IOPort(cpu, 1, 4, cpu.memory, 0x20)); - ioUnits.add(io2 = new IOPort(cpu, 2, 1, cpu.memory, 0x28)); - for (int i = 0, n = 8; i < n; i++) { - cpu.memOut[0x20 + i] = io1; - cpu.memOut[0x28 + i] = io2; - cpu.memIn[0x20 + i] = io1; - cpu.memIn[0x28 + i] = io2; - } + // IOPorts will add themselves to the CPU + ioUnits.add(new IOPort(cpu, 1, 4, cpu.memory, 0x20)); + ioUnits.add(new IOPort(cpu, 2, 1, cpu.memory, 0x28)); // Add port 3,4 & 5,6 for (int i = 0, n = 2; i < n; i++) { - IOPort p = new IOPort(cpu, (3 + i), 0, cpu.memory, 0x18 + i * 4); - ioUnits.add(p); - cpu.memOut[0x18 + i * 4] = p; - cpu.memOut[0x19 + i * 4] = p; - cpu.memOut[0x1a + i * 4] = p; - cpu.memOut[0x1b + i * 4] = p; - cpu.memIn[0x18 + i * 4] = p; - cpu.memIn[0x19 + i * 4] = p; - cpu.memIn[0x1a + i * 4] = p; - cpu.memIn[0x1b + i * 4] = p; + ioUnits.add(new IOPort(cpu, (3 + i), 0, cpu.memory, 0x18 + i * 4)); + ioUnits.add(new IOPort(cpu, (5 + i), 0, cpu.memory, 0x30 + i * 4)); } - for (int i = 0, n = 2; i < n; i++) { - IOPort p = new IOPort(cpu, (5 + i), 0, cpu.memory, 0x30 + i * 4); - ioUnits.add(p); - cpu.memOut[0x30 + i * 4] = p; - cpu.memOut[0x31 + i * 4] = p; - cpu.memOut[0x32 + i * 4] = p; - cpu.memOut[0x33 + i * 4] = p; - cpu.memIn[0x30 + i * 4] = p; - cpu.memIn[0x31 + i * 4] = p; - cpu.memIn[0x32 + i * 4] = p; - cpu.memIn[0x33 + i * 4] = p; - } - ADC12 adc12 = new ADC12(cpu); ioUnits.add(adc12); + cpu.setIORange(0x080, 16, adc12); + cpu.setIORange(0x140, 16, adc12); + cpu.setIORange(0x150, 16, adc12); + cpu.setIORange(0x1a0, 8, adc12); - for (int i = 0, n = 16; i < n; i++) { - cpu.memOut[0x80 + i] = adc12; - cpu.memIn[0x80 + i] = adc12; - cpu.memOut[0x140 + i] = adc12; - cpu.memIn[0x140 + i] = adc12; - cpu.memOut[0x150 + i] = adc12; - cpu.memIn[0x150 + i] = adc12; - } - for (int i = 0, n = 8; i < n; i++) { - cpu.memOut[0x1A0 + i] = adc12; - cpu.memIn[0x1A0 + i] = adc12; - } - return 3 + 6; } } diff --git a/se/sics/mspsim/config/MSP430f2617Config.java b/se/sics/mspsim/config/MSP430f2617Config.java index 3a9f0ff..bbf1fc3 100644 --- a/se/sics/mspsim/config/MSP430f2617Config.java +++ b/se/sics/mspsim/config/MSP430f2617Config.java @@ -76,33 +76,22 @@ public class MSP430f2617Config extends MSP430Config { public int setup(MSP430Core cpu, ArrayList ioUnits) { Multiplier mp = new Multiplier(cpu, cpu.memory, 0); - // Only cares of writes! - for (int i = 0x130, n = 0x13f; i < n; i++) { - cpu.memOut[i] = mp; - cpu.memIn[i] = mp; - } - + cpu.setIORange(0x130, 0x0f, mp); + USCI usciA0 = new USCI(cpu, 0, cpu.memory, this); USCI usciB0 = new USCI(cpu, 1, cpu.memory, this); USCI usciA1 = new USCI(cpu, 2, cpu.memory, this); USCI usciB1 = new USCI(cpu, 3, cpu.memory, this); - - for (int i = 0, n = 8; i < n; i++) { - cpu.memOut[0x60 + i] = usciA0; - cpu.memIn[0x60 + i] = usciA0; - cpu.memOut[0x68 + i] = usciB0; - cpu.memIn[0x68 + i] = usciB0; + cpu.setIORange(0x60, 8, usciA0); + cpu.setIORange(0x68, 8, usciB0); + cpu.setIORange(0xd0, 8, usciA1); + cpu.setIORange(0xd8, 8, usciB1); - cpu.memOut[0xd0 + i] = usciA1; - cpu.memIn[0xd0 + i] = usciA1; - cpu.memOut[0xd8 + i] = usciB1; - cpu.memIn[0xd8 + i] = usciB1; - } /* usciBx for i2c mode */ - cpu.setIO(0x118, usciB0, true); - cpu.setIO(0x11a, usciB0, true); - cpu.setIO(0x17c, usciB1, true); - cpu.setIO(0x17e, usciB1, true); + cpu.setIORange(0x118, 2, usciB0); + cpu.setIORange(0x11a, 2, usciB0); + cpu.setIORange(0x17c, 2, usciB1); + cpu.setIORange(0x17e, 2, usciB1); ioUnits.add(usciA0); ioUnits.add(usciB0); @@ -110,66 +99,26 @@ public class MSP430f2617Config extends MSP430Config { ioUnits.add(usciB1); /* usciA1 handles interrupts for both usciA1 and B1 */ - cpu.memOut[6] = usciA1; - cpu.memIn[6] = usciA1; - cpu.memOut[7] = usciA1; - cpu.memIn[7] = usciA1; + cpu.setIORange(0x06, 2, usciA1); // Add port 1,2 with interrupt capability! - IOPort io1; - IOPort io2; - ioUnits.add(io1 = new IOPort(cpu, 1, 4, cpu.memory, 0x20)); - ioUnits.add(io2 = new IOPort(cpu, 2, 1, cpu.memory, 0x28)); - for (int i = 0, n = 8; i < n; i++) { - cpu.memOut[0x20 + i] = io1; - cpu.memOut[0x28 + i] = io2; - cpu.memIn[0x20 + i] = io1; - cpu.memIn[0x28 + i] = io2; - } + // IOPorts will add themselves to the CPU + ioUnits.add(new IOPort(cpu, 1, 4, cpu.memory, 0x20)); + ioUnits.add(new IOPort(cpu, 2, 1, cpu.memory, 0x28)); // Add port 3,4 & 5,6 for (int i = 0, n = 2; i < n; i++) { - IOPort p = new IOPort(cpu, (3 + i), 0, cpu.memory, 0x18 + i * 4); - ioUnits.add(p); - cpu.memOut[0x18 + i * 4] = p; - cpu.memOut[0x19 + i * 4] = p; - cpu.memOut[0x1a + i * 4] = p; - cpu.memOut[0x1b + i * 4] = p; - cpu.memIn[0x18 + i * 4] = p; - cpu.memIn[0x19 + i * 4] = p; - cpu.memIn[0x1a + i * 4] = p; - cpu.memIn[0x1b + i * 4] = p; + ioUnits.add(new IOPort(cpu, (3 + i), 0, cpu.memory, 0x18 + i * 4)); + ioUnits.add(new IOPort(cpu, (5 + i), 0, cpu.memory, 0x30 + i * 4)); } - for (int i = 0, n = 2; i < n; i++) { - IOPort p = new IOPort(cpu, (5 + i), 0, cpu.memory, 0x30 + i * 4); - ioUnits.add(p); - cpu.memOut[0x30 + i * 4] = p; - cpu.memOut[0x31 + i * 4] = p; - cpu.memOut[0x32 + i * 4] = p; - cpu.memOut[0x33 + i * 4] = p; - cpu.memIn[0x30 + i * 4] = p; - cpu.memIn[0x31 + i * 4] = p; - cpu.memIn[0x32 + i * 4] = p; - cpu.memIn[0x33 + i * 4] = p; - } - ADC12 adc12 = new ADC12(cpu); ioUnits.add(adc12); + cpu.setIORange(0x080, 16, adc12); + cpu.setIORange(0x140, 16, adc12); + cpu.setIORange(0x150, 16, adc12); + cpu.setIORange(0x1a0, 8, adc12); - for (int i = 0, n = 16; i < n; i++) { - cpu.memOut[0x80 + i] = adc12; - cpu.memIn[0x80 + i] = adc12; - cpu.memOut[0x140 + i] = adc12; - cpu.memIn[0x140 + i] = adc12; - cpu.memOut[0x150 + i] = adc12; - cpu.memIn[0x150 + i] = adc12; - } - for (int i = 0, n = 8; i < n; i++) { - cpu.memOut[0x1A0 + i] = adc12; - cpu.memIn[0x1A0 + i] = adc12; - } - /* 4 usci units + 6 io port*/ return 4 + 6; } diff --git a/se/sics/mspsim/config/MSP430f5437Config.java b/se/sics/mspsim/config/MSP430f5437Config.java index 196f900..4b849b6 100644 --- a/se/sics/mspsim/config/MSP430f5437Config.java +++ b/se/sics/mspsim/config/MSP430f5437Config.java @@ -103,18 +103,13 @@ public class MSP430f5437Config extends MSP430Config { public int setup(MSP430Core cpu, ArrayList ioUnits) { Multiplier32 mp = new Multiplier32(cpu, cpu.memory, 0x4c0); - for (int i = 0x4c0, n = 0x4c0 + 0x2e; i < n; i++) { - cpu.memOut[i] = mp; - cpu.memIn[i] = mp; - } - + 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 */ - for (int a = 0; a < 0x20; a++) { - cpu.setIO(a + uartConfig[i].offset, usci, false); - } + cpu.setIORange(uartConfig[i].offset, 0x20, usci); // System.out.println("Adding IOUnit USCI: " + usci.getName()); ioUnits.add(usci); } diff --git a/se/sics/mspsim/core/IOPort.java b/se/sics/mspsim/core/IOPort.java index 9fe4251..f5331e1 100644 --- a/se/sics/mspsim/core/IOPort.java +++ b/se/sics/mspsim/core/IOPort.java @@ -84,7 +84,7 @@ public class IOPort extends IOUnit { private static final PortReg[] PORTMAP_NO_INTERRUPT = {PortReg.IN, PortReg.OUT, PortReg.DIR, PortReg.SEL}; - private PortReg[] portMap; + private final PortReg[] portMap; private PortListener portListener = null; // represents the direction register @@ -111,33 +111,27 @@ public class IOPort extends IOUnit { * Creates a new IOPort instance. * */ - public IOPort(MSP430Core cpu, int port, - int interrupt, int[] memory, int offset) { - super("P" + port, "Port " + port, cpu, memory, offset); - this.port = port; - this.interrupt = interrupt; - this.ie = 0; - this.ifg = 0; - - if (interrupt == 0) { - portMap = PORTMAP_NO_INTERRUPT; - } else { - portMap = PORTMAP_INTERRUPT; - } + public IOPort(MSP430Core cpu, int port, int interrupt, int[] memory, int offset) { + this(cpu, port, interrupt, memory, offset, + interrupt == 0 ? PORTMAP_NO_INTERRUPT : PORTMAP_INTERRUPT); } /* Create an IOPort with a special PortMap */ public IOPort(MSP430Core cpu, int port, int interrupt, int[] memory, int offset, PortReg[] portMap) { - this(cpu, port, interrupt, memory, offset); + super("P" + port, "Port " + port, cpu, memory, offset); + this.port = port; + this.interrupt = interrupt; + this.ie = 0; + this.ifg = 0; this.portMap = portMap; - + // System.out.println("Port " + port + " interrupt vector: " + interrupt); /* register all the registers from the port-map */ for (int i = 0; i < portMap.length; i++) { if (portMap[i] != null) { // System.out.println(" P" + port + portMap[i] + " at " + Utils.hex16(offset + i)); - cpu.setIO(offset + i, this, false); + cpu.setIORange(offset + i, 1, this); } } } diff --git a/se/sics/mspsim/core/IOSegment.java b/se/sics/mspsim/core/IOSegment.java index 8e21b0a..072bdb5 100644 --- a/se/sics/mspsim/core/IOSegment.java +++ b/se/sics/mspsim/core/IOSegment.java @@ -1,20 +1,41 @@ package se.sics.mspsim.core; +import java.util.Arrays; +import se.sics.mspsim.util.Utils; + public class IOSegment implements Memory { private final MSP430Core core; + private final IOUnit[] mem; + private final IOUnit voidIO; - IOSegment(MSP430Core core) { + IOSegment(MSP430Core core, int maxMemIO, IOUnit voidIO) { this.core = core; + this.voidIO = voidIO; + this.mem = new IOUnit[maxMemIO]; + Arrays.fill(mem, voidIO); + } + + void setIORange(int address, int range, IOUnit io) { + System.out.println("IO: 0x" + Utils.hex(address, 4) + "-" + + Utils.hex(address + range, 4) + ": " + io.id); + for (int i = 0; i < range; i++) { + if (mem[address + i] != voidIO) { + throw new IllegalStateException("IO unit already set: 0x" + + Utils.hex(address + i, 4) + + " (" + io.id + " => " + mem[address + i].id + ')'); + } + mem[address + i] = io; + } } @Override public int read(int address, AccessMode mode, AccessType type) throws EmulationException { boolean word = mode != AccessMode.BYTE; // Only word reads at 0x1fe which is highest address... - int val = core.memIn[address].read(address, word, core.cycles); + int val = mem[address].read(address, word, core.cycles); if (mode == AccessMode.WORD20) { - val |= core.memIn[address + 2].read(address, word, core.cycles) << 16; + val |= mem[address + 2].read(address, word, core.cycles) << 16; } return val; } @@ -24,9 +45,9 @@ public class IOSegment implements Memory { boolean word = mode != AccessMode.BYTE; if (!word) data &= 0xff; - core.memOut[dstAddress].write(dstAddress, data & 0xffff, word, core.cycles); + mem[dstAddress].write(dstAddress, data & 0xffff, word, core.cycles); if (mode == AccessMode.WORD20) { - core.memOut[dstAddress].write(dstAddress + 2, data >> 16, word, core.cycles); + mem[dstAddress].write(dstAddress + 2, data >> 16, word, core.cycles); } } @@ -40,4 +61,20 @@ public class IOSegment implements Memory { write(address, data, mode); } + public String info() { + StringBuilder sb = new StringBuilder(); + sb.append("IOSegment[0x0000-").append(Utils.hex(mem.length, 4)).append("]\n"); + + int start = 0; + for (int i = 1; i < mem.length; i++) { + if (mem[i] != mem[i - 1]) { + sb.append(" 0x").append(Utils.hex(start, 4)) + .append("-").append(Utils.hex(i - 1, 4)) + .append(": ").append(mem[i - 1].id).append(" (") + .append(mem[i - 1].name).append(")\n"); + start = i; + } + } + return sb.toString(); + } } diff --git a/se/sics/mspsim/core/MSP430Core.java b/se/sics/mspsim/core/MSP430Core.java index d013643..db3fde5 100644 --- a/se/sics/mspsim/core/MSP430Core.java +++ b/se/sics/mspsim/core/MSP430Core.java @@ -70,6 +70,9 @@ public class MSP430Core extends Chip implements MSP430Constants { boolean breakpointActive = true; public final int memory[]; + private final Flash flash; + boolean isFlashBusy; + boolean isStopping = false; private final Memory memorySegments[]; Memory currentSegment; @@ -80,15 +83,10 @@ public class MSP430Core extends Chip implements MSP430Constants { public final boolean MSP430XArch; public final MSP430Config config; - // Most HW needs only notify write and clocking, others need also read... - // For notify write... - public final IOUnit[] memOut; - // For notify read... -> which will happen before actual read! - public final IOUnit[] memIn; - - private ArrayList ioUnits; - private SFR sfr; - private Watchdog watchdog; + private final ArrayList ioUnits; + private final SFR sfr; + private final Watchdog watchdog; + private final ClockSystem bcs; // From the possible interrupt sources - to be able to indicate is serviced. // NOTE: 64 since more modern MSP430's have more than 16 vectors (5xxx has 64). @@ -129,43 +127,24 @@ public class MSP430Core extends Chip implements MSP430Constants { private ArrayList chips = new ArrayList(); - ComponentRegistry registry; + final ComponentRegistry registry; Profiler profiler; - private Flash flash; - boolean isFlashBusy; - boolean isStopping = false; - - ClockSystem bcs; - - public void setIO(int adr, IOUnit io, boolean word) { - memOut[adr] = io; - memIn[adr] = io; - if (word) { - memOut[adr + 1] = io; - memIn[adr + 1] = io; - } - } - - public void setIORange(int adr, int size, IOUnit io) { - for (int i = 0; i < size; i++) { - memOut[adr + i] = io; - memIn[adr + i] = io; - } - } - public MSP430Core(int type, ComponentRegistry registry, MSP430Config config) { super("MSP430", "MSP430 Core", null); MAX_INTERRUPT = config.maxInterruptVector; MAX_MEM_IO = config.maxMemIO; MAX_MEM = config.maxMem; - memOut = new IOUnit[MAX_MEM_IO]; - memIn = new IOUnit[MAX_MEM_IO]; MSP430XArch = config.MSP430XArch; memory = new int[MAX_MEM]; memorySegments = new Memory[MAX_MEM >> 8]; - + + flash = new Flash(this, memory, + new FlashRange(config.mainFlashStart, config.mainFlashStart + config.mainFlashSize, 512, 64), + new FlashRange(config.infoMemStart, config.infoMemStart + config.infoMemSize, 128, 64), + config.flashControllerOffset); + currentSegment = new Memory() { @Override public int read(int address, AccessMode mode, AccessType type) throws EmulationException { @@ -197,10 +176,10 @@ public class MSP430Core extends Chip implements MSP430Constants { } }; - System.out.println("Set up MSP430 Core with " + MAX_MEM + " bytes memory"); - +// System.out.println("Set up MSP430 Core with " + MAX_MEM + " bytes memory"); + /* this is for detecting writes/read to/from non-existing IO */ - IOUnit voidIO = new IOUnit(id, cpu, memory, 0) { + IOUnit voidIO = new IOUnit("void", cpu, memory, 0) { public void interruptServiced(int vector) { } public void write(int address, int value, boolean word, long cycles) { @@ -212,89 +191,11 @@ public class MSP430Core extends Chip implements MSP430Constants { } }; - /* fill with void IO */ - for (int i = 0; i < MAX_MEM_IO; i++) { - memOut[i] = voidIO; - memIn[i] = voidIO; - } - - this.registry = registry; - this.config = config; - // The CPU need to register itself as chip - addChip(this); - - // Ignore type for now... - setModeNames(MODE_NAMES); - // IOUnits should likely be placed in a hashtable? - // Maybe for debugging purposes... - ioUnits = new ArrayList(); - - flash = new Flash(this, memory, - new FlashRange(config.mainFlashStart, config.mainFlashStart + config.mainFlashSize, 512, 64), - new FlashRange(config.infoMemStart, config.infoMemStart + config.infoMemSize, 128, 64), - config.flashControllerOffset); - for (int i = 0; i < 8; i++) { - memOut[i + config.flashControllerOffset] = flash; - memIn[i + config.flashControllerOffset] = flash; - } - - /* Setup special function registers */ - sfr = new SFR(this, memory); - for (int i = 0, n = 0x10; i < n; i++) { - memOut[i + config.sfrOffset] = sfr; - memIn[i + config.sfrOffset] = 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]); - for (int a = 0, n = 0x20; a < n; a++) { - memOut[config.timerConfig[i].offset + a] = t; - memIn[config.timerConfig[i].offset + a] = t; - } - memIn[config.timerConfig[i].timerIVAddr] = t; - memOut[config.timerConfig[i].timerIVAddr] = t; - - timers[i] = t; - } - - // XXX this should be handled by the config, but we do it here to - // avoid changing too much of the mspsim architecture for now - if (MSP430XArch) { - bcs = new UnifiedClockSystem(this, memory, 0, timers); - } else { - bcs = new BasicClockModule(this, memory, 0, timers); - } - for (int i = bcs.getAddressRangeMin(), n = bcs.getAddressRangeMax(); - i <= n; i++) { - memOut[i] = bcs; - memIn[i] = bcs; - } - - // SFR and Basic clock system. - ioUnits.add(sfr); - ioUnits.add(bcs); - - config.setup(this, ioUnits); - - /* timers after ports ? */ - for (int i = 0; i < timers.length; i++) { - ioUnits.add(timers[i]); - } - - watchdog = new Watchdog(this); - memOut[config.watchdogOffset] = watchdog; - memIn[config.watchdogOffset] = watchdog; - - ioUnits.add(watchdog); - /* setup memory segments */ int maxSeg = MAX_MEM >> 8; Memory ramSegment = new RAMSegment(this); Memory flashSegment = new FlashSegment(this, flash); - Memory ioSegment = new IOSegment(this); + IOSegment ioSegment = new IOSegment(this, MAX_MEM_IO, voidIO); Memory noMemorySegment = new NoMemSegment(this); for (int i = 0; i < maxSeg; i++) { if (config.isRAM(i << 8)) { @@ -312,9 +213,68 @@ public class MSP430Core extends Chip implements MSP430Constants { } } + this.registry = registry; + this.config = config; + // The CPU need to register itself as chip + addChip(this); + + // Ignore type for now... + setModeNames(MODE_NAMES); + // IOUnits should likely be placed in a hashtable? + // Maybe for debugging purposes... + ioUnits = new ArrayList(); + + ioSegment.setIORange(config.flashControllerOffset, 6, flash); + + /* Setup special function registers */ + sfr = new SFR(this, memory); + 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].timerIVAddr, 1, t); + timers[i] = t; + } + + // XXX this should be handled by the config, but we do it here to + // avoid changing too much of the mspsim architecture for now + if (MSP430XArch) { + bcs = new UnifiedClockSystem(this, memory, 0, timers); + } else { + bcs = new BasicClockModule(this, memory, 0, timers); + } + ioSegment.setIORange(bcs.getAddressRangeMin(), bcs.getAddressRangeMax() - bcs.getAddressRangeMin() + 1, bcs); + + // SFR and Basic clock system. + ioUnits.add(sfr); + ioUnits.add(bcs); + + config.setup(this, ioUnits); + + /* timers after ports ? */ + for (int i = 0; i < timers.length; i++) { + ioUnits.add(timers[i]); + } + + watchdog = new Watchdog(this); + ioSegment.setIORange(config.watchdogOffset, 1, watchdog); + + ioUnits.add(watchdog); + bcs.reset(0); } + public void setIORange(int address, int range, IOUnit io) { + if (address + range > MAX_MEM_IO) { + throw new IllegalStateException("Outside IO memory: 0x" + Utils.hex(address, 4)); + } + IOSegment ioSegment = (IOSegment) memorySegments[address >> 8]; + ioSegment.setIORange(address, range, io); + } + public Profiler getProfiler() { return profiler; }