mirror of https://github.com/contiki-ng/mspsim
Moved IO unit memory map into the IO memory segments
This commit is contained in:
parent
231714ecdc
commit
fcae849403
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,33 +76,22 @@ public class MSP430f2617Config extends MSP430Config {
|
|||
public int setup(MSP430Core cpu, ArrayList<IOUnit> 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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -103,18 +103,13 @@ public class MSP430f5437Config extends MSP430Config {
|
|||
public int setup(MSP430Core cpu, ArrayList<IOUnit> 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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 <code>IOPort</code> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<IOUnit> ioUnits;
|
||||
private SFR sfr;
|
||||
private Watchdog watchdog;
|
||||
private final ArrayList<IOUnit> 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<Chip> chips = new ArrayList<Chip>();
|
||||
|
||||
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<IOUnit>();
|
||||
|
||||
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<IOUnit>();
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue