1 package net.mograsim.machine;
3 import java.util.Arrays;
4 import java.util.HashMap;
5 import java.util.HashSet;
8 public abstract class GenericMemory<T> implements Memory<T>
10 private final long minimalAddress, maximalAddress;
11 private final MemoryDefinition definition;
12 private final int pageSize = 64;
13 private Set<MemoryCellModifiedListener> observers = new HashSet<>();
15 private HashMap<Long, Page> pages;
17 public GenericMemory(MemoryDefinition definition)
20 this.definition = definition;
21 this.minimalAddress = definition.getMinimalAddress();
22 this.maximalAddress = definition.getMaximalAddress();
23 this.pages = new HashMap<>();
26 private void inBoundsCheck(long address)
28 if (address < minimalAddress || address > maximalAddress)
29 throw new IndexOutOfBoundsException(String.format("Memory address out of bounds! Minimum: %d Maximum: %d Actual: %d",
30 minimalAddress, maximalAddress, address));
33 private long page(long address)
35 return address / pageSize;
38 private int offset(long address)
40 return (int) (address % pageSize);
44 public void setCell(long address, T data)
46 inBoundsCheck(address);
47 long page = page(address);
48 int offset = offset(address);
49 Page p = pages.get(Long.valueOf(page));
51 pages.put(page, p = new Page());
52 p.setCell(offset, data);
53 notifyObservers(address);
57 public T getCell(long address)
59 inBoundsCheck(address);
60 long page = page(address);
61 int offset = offset(address);
62 Page p = pages.get(Long.valueOf(page));
65 return p.getCell(offset);
70 private Object[] memory;
74 memory = new Object[pageSize];
77 public T getCell(int index)
79 @SuppressWarnings("unchecked")
80 T data = (T) memory[index];
84 public void setCell(int index, T data)
90 public String toString()
92 return Arrays.deepToString(memory);
97 public void registerCellModifiedListener(MemoryCellModifiedListener ob)
103 public void deregisterCellModifiedListener(MemoryCellModifiedListener ob)
105 observers.remove(ob);
108 protected void notifyObservers(long address)
110 observers.forEach(ob -> ob.update(address));
114 public MemoryDefinition getDefinition()