Am2900Machine now has registers
[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
5 import net.mograsim.machine.standard.memory.MemoryException;
6
7 public class StandardMicroInstructionMemory implements MicroInstructionMemory
8 {
9         private MicroInstruction[] data;
10         private MicroInstructionMemoryDefinition definition;
11         private HashSet<MemoryCellModifiedListener> observers = new HashSet<>();
12
13         public StandardMicroInstructionMemory(MicroInstructionMemoryDefinition definition)
14         {
15                 if (definition.size() > Integer.MAX_VALUE)
16                         throw new MemoryException("Size of MicroInstructionMemory must be an int, not a long");
17                 this.definition = definition;
18                 data = new MicroInstruction[(int) definition.size()];
19         }
20
21         private int translate(long address)
22         {
23                 return (int) (address - definition.getMinimalAddress());
24         }
25
26         @Override
27         public MicroInstruction getCell(long address)
28         {
29                 int translatedAddress = translate(address);
30                 MicroInstruction actual = data[translatedAddress];
31                 if (actual == null)
32                         actual = data[translatedAddress] = definition.getMicroInstructionDefinition().createDefaultInstruction();
33                 return actual;
34         }
35
36         @Override
37         public void setCell(long address, MicroInstruction data)
38         {
39                 this.data[translate(address)] = data;
40                 notifyMemoryChanged(address);
41         }
42
43         @Override
44         public void registerCellModifiedListener(MemoryCellModifiedListener ob)
45         {
46                 observers.add(ob);
47         }
48
49         @Override
50         public void deregisterCellModifiedListener(MemoryCellModifiedListener ob)
51         {
52                 observers.remove(ob);
53         }
54
55         private void notifyMemoryChanged(long address)
56         {
57                 observers.forEach(ob -> ob.update(address));
58         }
59
60         @Override
61         public MicroInstructionMemoryDefinition getDefinition()
62         {
63                 return definition;
64         }
65 }