added an interrupt multiplexer for DMA and later DAC

git-svn-id: https://mspsim.svn.sourceforge.net/svnroot/mspsim/mspsim@783 23d1a52b-0c3c-0410-b72d-8f29ab48fe35
This commit is contained in:
joxe 2011-02-04 17:55:45 +00:00
parent 910881840f
commit 2ea5f90c8f
3 changed files with 74 additions and 9 deletions

View File

@ -29,9 +29,13 @@ public class DMA extends IOUnit {
public static final int UTXIFG1 = 10; /* UART 1 */
public static final int MULTIPLIER = 11;
public static final int IFG_MASK = 0x08;
private static final int[] INCR = {0,0,-1,1};
class Channel {
private InterruptMultiplexer interruptMultiplexer;
class Channel implements InterruptHandler {
int channelNo;
/* public registers */
@ -52,8 +56,12 @@ public class DMA extends IOUnit {
DMATrigger trigger;
int triggerIndex;
int transferMode = 0;
boolean enable = false;
boolean dmaLevel = false; /* edge or level sensitive trigger */
boolean dmaIE = false;
boolean dmaIFG = false;
public Channel(int i) {
channelNo = i;
@ -69,15 +77,22 @@ public class DMA extends IOUnit {
switch(address) {
case 0:
ctl = data;
transferMode = (data >> 12) & 7;
dstIncr = INCR[(data >> 10) & 3];
srcIncr = INCR[(data >> 8) & 3];
dstByteMode = (data & 0x80) > 0; /* bit 7 */
srcByteMode = (data & 0x40) > 0; /* bit 6 */
dmaLevel = (data & 0x20) > 0; /* bit 5 */
boolean enabling = !enable && (data & 0x10) > 0;
enable = (data & 0x10) > 0; /* bit 4 */
dmaIFG = (data & IFG_MASK) > 0; /* bit 3 */
dmaIE = (data & 0x04) > 0; /* bit 2 */
System.out.println("DMA Ch." + channelNo + ": config srcIncr: " + srcIncr + " dstIncr:" + dstIncr
+ " en: " + enable + " srcB:" + srcByteMode + " dstB:" + dstByteMode);
+ " en: " + enable + " srcB:" + srcByteMode + " dstB:" + dstByteMode + " level: " + dmaLevel +
" transferMode: " + transferMode + " ie:" + dmaIE);
/* this might be wrong ? */
if (enabling) trigger(trigger, triggerIndex);
interruptMultiplexer.updateInterrupt(dmaIFG & dmaIE, channelNo);
break;
case 2:
sourceAddress = data;
@ -97,13 +112,15 @@ public class DMA extends IOUnit {
public int read(int address) {
switch(address) {
case 0:
return ctl;
/* set the IFG */
ctl = (ctl & ~IFG_MASK) | (dmaIFG ? IFG_MASK : 0);
return ctl;
case 2:
return sourceAddress;
return sourceAddress;
case 4:
return destinationAddress;
return destinationAddress;
case 6:
return size;
return size;
}
System.out.println("Illegal read of DMA Channel register");
return 0;
@ -127,10 +144,22 @@ public class DMA extends IOUnit {
currentSourceAddress = sourceAddress;
currentDestinationAddress = destinationAddress;
size = storedSize;
/* flag interrupt!!!! */
if ((transferMode & 0x04) == 0) {
enable = false;
}
/* flag interrupt and update interrupt vector */
dmaIFG = true;
interruptMultiplexer.updateInterrupt(dmaIFG & dmaIE, channelNo);
}
}
}
public void interruptServiced(int vector) {
}
public String getName() {
return "DMA Channel " + channelNo;
}
}
private Channel channels[] = new Channel[3];
@ -151,6 +180,10 @@ public class DMA extends IOUnit {
this.cpu = msp430Core;
}
public void setInterruptMultiplexer(InterruptMultiplexer interruptMultiplexer) {
this.interruptMultiplexer = interruptMultiplexer;
}
public void setDMATrigger(int totindex, DMATrigger trigger, int tIndex) {
dmaTrigger[totindex] = trigger;
dmaTriggerIndex[totindex] = tIndex;

View File

@ -0,0 +1,30 @@
package se.sics.mspsim.core;
public class InterruptMultiplexer implements InterruptHandler {
int interruptBits;
MSP430Core cpu;
int vector;
public InterruptMultiplexer(MSP430Core cpu, int vector) {
this.cpu = cpu;
this.vector = vector;
}
public void updateInterrupt(boolean value, int bit) {
if (value) interruptBits |= 1 << bit;
else interruptBits &= ~(1 << bit);
cpu.flagInterrupt(vector, this, interruptBits > 0);
}
public void interruptServiced(int vector) {
/* do nothing??? */
}
public String getName() {
return "InterruptMultiplexer vector " + vector + " bits: " + interruptBits;
}
}

View File

@ -94,7 +94,7 @@ public class MSP430Core extends Chip implements MSP430Constants {
private Watchdog watchdog;
// From the possible interrupt sources - to be able to indicate is serviced.
private InterruptHandler interruptSource[] = new IOUnit[16];
private InterruptHandler interruptSource[] = new InterruptHandler[16];
protected int interruptMax = -1;
// Op/instruction represents the last executed OP / instruction
@ -277,6 +277,8 @@ public class MSP430Core extends Chip implements MSP430Constants {
dma.setDMATrigger(DMA.UTXIFG0, usart0, 1);
dma.setDMATrigger(DMA.URXIFG1, usart1, 0);
dma.setDMATrigger(DMA.UTXIFG1, usart1, 1);
dma.setInterruptMultiplexer(new InterruptMultiplexer(this, 0));
ioUnits[passIO++] = dma;