Fixed a bug in Am2900; created dlatch8/80; relayouted some components
[Mograsim.git] / net.mograsim.machine / src / net / mograsim / machine / mi / StandardMicroInstructionMemory.java
1 package net.mograsim.machine.mi;
2
3 import java.util.HashSet;
4
5 import net.mograsim.machine.MemoryObserver;
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<MemoryObserver> observers = new HashSet<>();
13
14         public StandardMicroInstructionMemory(MicroInstructionMemoryDefinition definition)
15         {
16                 if (definition.size() > Integer.MAX_VALUE)
17                         throw new MemoryException("Size of MicroInstructionMemory must be an int, not a long");
18                 this.definition = definition;
19                 data = new MicroInstruction[(int) definition.size()];
20         }
21
22         private int translate(long address)
23         {
24                 return (int) (address - definition.getMinimalAddress());
25         }
26
27         @Override
28         public MicroInstruction getCell(long address)
29         {
30                 int translatedAddress = translate(address);
31                 MicroInstruction actual = data[translatedAddress];
32                 if (actual == null)
33                         actual = data[translatedAddress] = definition.getMicroInstructionDefinition()
34                                         .createDefaultInstruction(() -> notifyObservers(address));
35                 return actual;
36         }
37
38         @Override
39         public void setCell(long address, MicroInstruction data)
40         {
41                 this.data[translate(address)] = data;
42                 notifyObservers(address);
43         }
44
45         @Override
46         public void registerObserver(MemoryObserver ob)
47         {
48                 observers.add(ob);
49         }
50
51         @Override
52         public void deregisterObserver(MemoryObserver ob)
53         {
54                 observers.remove(ob);
55         }
56
57         @Override
58         public void notifyObservers(long address)
59         {
60                 observers.forEach(ob -> ob.update(address));
61         }
62
63         @Override
64         public MicroInstructionMemoryDefinition getDefinition()
65         {
66                 return definition;
67         }
68
69 }