/* WordMemoryArea.java (c) 2005-2015 Edward Swartz All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html */ package v9t9.engine.memory; import v9t9.common.memory.IMemoryDomain; import v9t9.common.memory.IMemoryEntry; /** * Word memory is accessed in 9900 byte order but accessed with usual * host endianness. * <p> * This area provides a basis for "traditional" memory which has a flat * array of bytes with read and/or write support. * @author ejs */ public class WordMemoryArea extends MemoryArea { public WordMemoryArea() { this(0); } public WordMemoryArea(int latency) { super(latency); } public WordMemoryArea(int latency, short[] memory, boolean isStored) { super(latency); if (memory != null && memory.length % IMemoryDomain.AREASIZE != 0) assert false : "memory area size not multiple of " + IMemoryDomain.AREASIZE; this.memory = memory; this.read = memory; if (isStored) this.write = memory; } public boolean bWordAccess = true; /* actual memory for area, except for empty mem */ public short[] memory; /* if non-NULL, we can statically read */ public short[] read; /* if non-NULL, we can statically write */ public short[] write; /* (non-Javadoc) * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { if (!(obj instanceof WordMemoryArea)) { return false; } WordMemoryArea area = (WordMemoryArea)obj; return area.bWordAccess == bWordAccess && area.memory == memory && area.read == read && area.write == write; } public static WordMemoryArea newDefaultArea() { WordMemoryArea area = new WordMemoryArea(); return area; } @Override public boolean hasWriteAccess() { return read != null && write != null; } @Override public boolean hasReadAccess() { return read != null; } @Override protected int getSize() { return memory != null ? memory.length*2 : 0; } @Override public void copyFromBytes(byte[] array) { if (memory == null) { memory = new short[array.length / 2]; read = memory; } int length = Math.min(array.length, memory.length*2); for (int i = 0; i < length; i+=2) { memory[i/2] = (short) (array[i]<<8 | array[i+1]&0xff); } } @Override public void copyToBytes(byte[] array) { int length = Math.min(array.length, memory.length*2); for (int i = 0; i < length; i+=2) { array[i] = (byte) (memory[i/2] >> 8); array[i+1] = (byte) (memory[i/2] & 0xff); } } @Override public short readWord(IMemoryEntry entry, int addr) { if (read != null) { int addr1 = addr - entry.getAddr(); /* * processor ignores word access on odd boundaries, and stores in * big-endian format */ addr1 &= 0xfffe; return read[addr1 >> 1]; } else { return 0; } } @Override public byte readByte(IMemoryEntry entry, int addr) { if (read != null) { int addr1 = addr - entry.getAddr(); /* * processor ignores word access on odd boundaries, and stores in * big-endian format */ addr1 &= 0xfffe; short word = read[addr1 >> 1]; if ((addr & 1) == 0) { return (byte)(word >> 8); } else { return (byte)word; } } else { return 0; } } @Override public void writeWord(IMemoryEntry entry, int addr, short val) { if (write != null) { int addr1 = addr - entry.getAddr(); /* * processor ignores word access on odd boundaries, and stores in * big-endian format */ addr1 &= 0xfffe; write[addr1 >> 1] = val; } } /* (non-Javadoc) * @see v9t9.engine.memory.MemoryArea#patchWord(v9t9.engine.memory.MemoryEntry, int, short) */ @Override public boolean patchWord(MemoryEntry entry, int addr, short value) { int addr1 = addr - entry.getAddr(); /* * processor ignores word access on odd boundaries, and stores in * big-endian format */ addr1 = (addr1 & 0xfffe) >> 1; if (memory[addr1] != value) { memory[addr1] = value; return true; } return false; } @Override public void writeByte(IMemoryEntry entry, int addr, byte val) { if (write != null) { int addr1 = addr - entry.getAddr(); /* * processor ignores word access on odd boundaries, and stores in * big-endian format */ addr1 &= 0xfffe; short word = write[addr1 >> 1]; if ((addr & 1) == 0) { word = (short) (val << 8 | word & 0xff); } else { word = (short) (word & 0xff00 | val & 0xff); } write[addr1 >> 1] = word; } } }