Added active instruction preview to LogicUIPart
[Mograsim.git] / plugins / net.mograsim.machine / src / net / mograsim / machine / mi / StandardMicroInstructionMemory.java
1 package net.mograsim.machine.mi;
2
3 import java.util.HashSet;
4 import java.util.Set;
5
6 import net.mograsim.machine.standard.memory.MemoryException;
7
8 public class StandardMicroInstructionMemory implements MicroInstructionMemory
9 {
10         private MicroInstruction[] data;
11         private MicroInstructionMemoryDefinition definition;
12         private HashSet<MemoryCellModifiedListener> observers = new HashSet<>();
13         private Set<ActiveMicroInstructionChangedListener> activeInstructionListeners = new HashSet<>();
14         private long activeInstruction = -1;
15
16         public StandardMicroInstructionMemory(MicroInstructionMemoryDefinition definition)
17         {
18                 if (definition.size() > Integer.MAX_VALUE)
19                         throw new MemoryException("Size of MicroInstructionMemory must be an int, not a long");
20                 this.definition = definition;
21                 data = new MicroInstruction[(int) definition.size()];
22         }
23
24         private int translate(long address)
25         {
26                 return (int) (address - definition.getMinimalAddress());
27         }
28
29         @Override
30         public MicroInstruction getCell(long address)
31         {
32                 int translatedAddress = translate(address);
33                 MicroInstruction actual = data[translatedAddress];
34                 if (actual == null)
35                         actual = data[translatedAddress] = definition.getMicroInstructionDefinition().createDefaultInstruction();
36                 return actual;
37         }
38
39         @Override
40         public void setCell(long address, MicroInstruction data)
41         {
42                 this.data[translate(address)] = data;
43                 notifyMemoryChanged(address);
44         }
45
46         @Override
47         public void registerCellModifiedListener(MemoryCellModifiedListener ob)
48         {
49                 observers.add(ob);
50         }
51
52         @Override
53         public void deregisterCellModifiedListener(MemoryCellModifiedListener ob)
54         {
55                 observers.remove(ob);
56         }
57
58         @Override
59         public void registerActiveMicroInstructionChangedListener(ActiveMicroInstructionChangedListener ob)
60         {
61                 activeInstructionListeners.add(ob);
62         }
63
64         @Override
65         public void deregisterActiveMicroInstructionChangedListener(ActiveMicroInstructionChangedListener ob)
66         {
67                 activeInstructionListeners.remove(ob);
68         }
69
70         private void notifyMemoryChanged(long address)
71         {
72                 observers.forEach(ob -> ob.update(address));
73         }
74
75         private void notifyActiveInstructionChanged(long address)
76         {
77                 activeInstructionListeners.forEach(o -> o.activeMicroInstructionChanged(address));
78         }
79
80         @Override
81         public MicroInstructionMemoryDefinition getDefinition()
82         {
83                 return definition;
84         }
85
86         @Override
87         public void setActiveInstruction(long address)
88         {
89                 if (address != activeInstruction)
90                 {
91                         activeInstruction = address;
92                         notifyActiveInstructionChanged(address);
93                 }
94         }
95
96 }