/******************************************************************************* * openDLX - A DLX/MIPS processor simulator. * Copyright (C) 2013 The openDLX project, University of Augsburg, Germany * Project URL: <https://sourceforge.net/projects/opendlx> * Development branch: <https://github.com/smetzlaff/openDLX> * * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program, see <LICENSE>. If not, see * <http://www.gnu.org/licenses/>. ******************************************************************************/ package openDLX.util; import openDLX.datatypes.uint32; import openDLX.exception.MemoryException; import org.apache.log4j.Logger; public class PagedMemory { private static Logger logger = Logger.getLogger("PagedMem"); private Page[] pages; private int page_addr_bits; private int page_count; public PagedMemory() { // allocate array of 2^(32-13) 16k pages page_addr_bits = 32 - ((int) (Math.log(Page.page_size)/Math.log(2))); page_count = (int) Math.pow(2, page_addr_bits); pages = new Page[page_count]; logger.debug("Reserving " + page_count + " pages, using the upper " + page_addr_bits + " bits for page addressing"); } public void writeByte(uint32 address, byte data) throws MemoryException { writeByte(address.getValue(), data); } public void writeByte(int address, byte data) throws MemoryException { // determine the page by the upper 18 bit int page_number = address >>> (32-page_addr_bits); //logger.trace("Accessing page: " + page_number + " 0x" + Integer.toHexString(page_number)); if(page_number >= page_count) { throw new MemoryException("Page number out of bounds: " + page_number + "/" + page_count); } // allocate page if not already allocated if(pages[page_number] == null) { pages[page_number] = new Page(); } // determine the lower 13 bit for addressing within the 16k pages // and write data to page pages[page_number].writeByte((address&(Page.page_size-1)), data); } public byte readByte(uint32 address) throws MemoryException { return readByte(address.getValue()); } public byte readByte(int address) throws MemoryException { // determine the page by the upper 18 bit int page_number = address >>> (32-page_addr_bits); //logger.trace("Accessing page: " + page_number + " 0x" + Integer.toHexString(page_number)); if(page_number >= page_count) { throw new MemoryException("Page number out of bounds: " + page_number + "/" + page_count); } // allocate page if not already allocated if(pages[page_number] == null) { logger.warn("Reading from unallocated page!"); pages[page_number] = new Page(); } // determine the lower 13 bit for addressing within the 16k pages // and write data to page return pages[page_number].readByte((address&(Page.page_size-1))); } public String readByteAsString(uint32 address) throws MemoryException { return readByteAsString(address.getValue()); } public String readByteAsString(int address) throws MemoryException { byte value = readByte(address); String s = Integer.toHexString((byte)value); int diff = 2 - s.length(); if(diff > 0) { for(;diff > 0; diff--) s = "0"+s; } else if(diff < 0) { s = s.substring(s.length()-2, s.length()); } return "0x"+s; } /** * TODO .. * @throws MemoryException */ public int readByteDump(int address) throws MemoryException { // determine the page by the upper 18 bit int page_number = address >>> (32-page_addr_bits); if(page_number >= page_count) { throw new MemoryException("Page number out of bounds: " + page_number + "/" + page_count); } // check if page was not allocated if(pages[page_number] == null) { // do not allocate page here, since only a memory dump is created // show non allocated pages in a memory dump with values of 0x0 return 0; } else { // determine the lower 13 bit for addressing within the 16k pages // and write data to page return pages[page_number].readByte((address&(Page.page_size-1))); } } }