X-Git-Url: https://mograsim.net/gitweb/?a=blobdiff_plain;f=net.mograsim.machine%2Fsrc%2Fnet%2Fmograsim%2Fmachine%2Fstandard%2Fmemory%2FWordAddressableMemory.java;h=2e209f1c172f0515e9ca279e4925b6574cc041b5;hb=153f81323a215691a0477af3fd1dd4a9d5b02958;hp=719c993eccb075a3dd6f67e152077e4c2f8085d9;hpb=de4ce44622b2a40c2ff4030467de8f56db917329;p=Mograsim.git diff --git a/net.mograsim.machine/src/net/mograsim/machine/standard/memory/WordAddressableMemory.java b/net.mograsim.machine/src/net/mograsim/machine/standard/memory/WordAddressableMemory.java index 719c993e..2e209f1c 100644 --- a/net.mograsim.machine/src/net/mograsim/machine/standard/memory/WordAddressableMemory.java +++ b/net.mograsim.machine/src/net/mograsim/machine/standard/memory/WordAddressableMemory.java @@ -1,50 +1,97 @@ package net.mograsim.machine.standard.memory; +import java.math.BigInteger; import java.util.Arrays; import java.util.HashMap; import net.mograsim.logic.core.types.Bit; import net.mograsim.logic.core.types.BitVector; +import net.mograsim.machine.MainMemory; +import net.mograsim.machine.MainMemoryDefinition; -public class WordAddressableMemory +public class WordAddressableMemory implements MainMemory { private final int cellWidth; private final long minimalAddress, maximalAddress; + private final MainMemoryDefinition definition; private final int pageSize = 64; private HashMap pages; - public WordAddressableMemory(int cellWidth, long minimalAddress, long maximalAddress) + public WordAddressableMemory(MainMemoryDefinition definition) { super(); - this.cellWidth = cellWidth; - this.minimalAddress = minimalAddress; - this.maximalAddress = maximalAddress; + this.cellWidth = definition.getCellWidth(); + this.minimalAddress = definition.getMinimalAddress(); + this.maximalAddress = definition.getMaximalAddress(); + this.definition = definition; this.pages = new HashMap<>(); } - - public void setCell(long address, BitVector b) + + private void inBoundsCheck(long address) { if (address < minimalAddress || address > maximalAddress) throw new IndexOutOfBoundsException(String.format("Memory address out of bounds! Minimum: %d Maximum: %d Actual: %d", minimalAddress, maximalAddress, address)); - long page = address / pageSize; - int offset = (int) (address % pageSize); + } + + private long page(long address) + { + return address / pageSize; + } + + private int offset(long address) + { + return (int) (address % pageSize); + } + + @Override + public void setCell(long address, BitVector b) + { + inBoundsCheck(address); + long page = page(address); + int offset = offset(address); Page p = pages.get(Long.valueOf(page)); if (p == null) pages.put(page, p = new Page()); p.setCell(offset, b); } + @Override public BitVector getCell(long address) { - long page = address / pageSize; - int offset = (int) (address % pageSize); + inBoundsCheck(address); + long page = page(address); + int offset = offset(address); Page p = pages.get(Long.valueOf(page)); if (p == null) - return BitVector.of(Bit.U, cellWidth); + return BitVector.of(Bit.ZERO, cellWidth); return p.getCell(offset); } + + @Override + public BigInteger getCellAsBigInteger(long address) + { + inBoundsCheck(address); + long page = page(address); + int offset = offset(address); + Page p = pages.get(Long.valueOf(page)); + if (p == null) + return BigInteger.valueOf(0L); + return p.getCellAsBigInteger(offset); + } + + @Override + public void setCellAsBigInteger(long address, BigInteger word) + { + inBoundsCheck(address); + long page = page(address); + int offset = offset(address); + Page p = pages.get(Long.valueOf(page)); + if (p == null) + pages.put(page, p = new Page()); + p.setCellAsBigInteger(offset, word); + } private class Page { @@ -59,22 +106,44 @@ public class WordAddressableMemory { BitVector b = memory[index]; if (b == null) - return BitVector.of(Bit.U, cellWidth); + return BitVector.of(Bit.ZERO, cellWidth); return memory[index]; } public void setCell(int index, BitVector bits) { - if (bits.length() != cellWidth) + if (bits.width() != cellWidth) throw new IllegalArgumentException(String.format( - "BitVector to be saved in memory cell has unexpected length. Expected: %d Actual: %d", cellWidth, bits.length())); + "BitVector to be saved in memory cell has unexpected width. Expected: %d Actual: %d", cellWidth, bits.width())); memory[index] = bits; } + public void setCellAsBigInteger(int index, BigInteger bits) + { + setCell(index, BitVector.from(bits, cellWidth)); + } + + public BigInteger getCellAsBigInteger(int index) + { + try { + return getCell(index).getUnsignedValue(); + } + catch(NumberFormatException e) + { + throw new MemoryException(e); + } + } + @Override public String toString() { return Arrays.deepToString(memory); } } + + @Override + public MainMemoryDefinition getDefinition() + { + return definition; + } }