Package com.cburch.logisim.std.memory

Source Code of com.cburch.logisim.std.memory.Mem

/* Copyright (c) 2010, Carl Burch. License information is located in the
* com.cburch.logisim.Main source code and at www.cburch.com/logisim/. */

package com.cburch.logisim.std.memory;

import java.awt.Color;
import java.awt.Graphics;
import java.io.File;
import java.io.IOException;
import java.util.WeakHashMap;

import com.cburch.hex.HexModel;
import com.cburch.hex.HexModelListener;
import com.cburch.logisim.circuit.CircuitState;
import com.cburch.logisim.data.Attribute;
import com.cburch.logisim.data.AttributeSet;
import com.cburch.logisim.data.Attributes;
import com.cburch.logisim.data.BitWidth;
import com.cburch.logisim.data.Bounds;
import com.cburch.logisim.data.Direction;
import com.cburch.logisim.gui.hex.HexFile;
import com.cburch.logisim.gui.hex.HexFrame;
import com.cburch.logisim.instance.Instance;
import com.cburch.logisim.instance.InstanceFactory;
import com.cburch.logisim.instance.InstancePainter;
import com.cburch.logisim.instance.InstanceState;
import com.cburch.logisim.instance.Port;
import com.cburch.logisim.proj.Project;
import com.cburch.logisim.tools.MenuExtender;
import com.cburch.logisim.tools.key.BitWidthConfigurator;
import com.cburch.logisim.tools.key.JoinedConfigurator;
import com.cburch.logisim.util.GraphicsUtil;
import com.cburch.logisim.util.StringGetter;
import com.cburch.logisim.util.StringUtil;

abstract class Mem extends InstanceFactory {
  // Note: The code is meant to be able to handle up to 32-bit addresses, but it
  // hasn't been debugged thoroughly. There are two definite changes I would
  // make if I were to extend the address bits: First, there would need to be some
  // modification to the memory's graphical representation, because there isn't
  // room in the box to include such long memory addresses with the current font
  // size. And second, I'd alter the MemContents class's PAGE_SIZE_BITS constant
  // to 14 so that its "page table" isn't quite so big.
  public static final Attribute<BitWidth> ADDR_ATTR = Attributes.forBitWidth(
      "addrWidth", Strings.getter("ramAddrWidthAttr"), 2, 24);
  public static final Attribute<BitWidth> DATA_ATTR = Attributes.forBitWidth(
      "dataWidth", Strings.getter("ramDataWidthAttr"));
 
  // port-related constants
  static final int DATA = 0;
  static final int ADDR = 1;
  static final int CS = 2;
  static final int MEM_INPUTS = 3;

  // other constants
  static final int DELAY = 10;

  private WeakHashMap<Instance,File> currentInstanceFiles;

  Mem(String name, StringGetter desc, int extraPorts) {
    super(name, desc);
    currentInstanceFiles = new WeakHashMap<Instance,File>();
    setInstancePoker(MemPoker.class);
    setKeyConfigurator(JoinedConfigurator.create(
        new BitWidthConfigurator(ADDR_ATTR, 2, 24, 0),
        new BitWidthConfigurator(DATA_ATTR)));

    setOffsetBounds(Bounds.create(-140, -40, 140, 80));
  }
 
  abstract void configurePorts(Instance instance);
  @Override
  public abstract AttributeSet createAttributeSet();
  abstract MemState getState(InstanceState state);
  abstract MemState getState(Instance instance, CircuitState state);
  abstract HexFrame getHexFrame(Project proj, Instance instance, CircuitState state);
  @Override
  public abstract void propagate(InstanceState state);

  @Override
  protected void configureNewInstance(Instance instance) {
    configurePorts(instance);
  }
 
  void configureStandardPorts(Instance instance, Port[] ps) {
    ps[DATA] = new Port(   00, Port.INOUT, DATA_ATTR);
    ps[ADDR] = new Port(-1400, Port.INPUT, ADDR_ATTR);
    ps[CS]   = new Port( -90, 40, Port.INPUT, 1);
    ps[DATA].setToolTip(Strings.getter("memDataTip"));
    ps[ADDR].setToolTip(Strings.getter("memAddrTip"));
    ps[CS].setToolTip(Strings.getter("memCSTip"));
  }

  @Override
  public void paintInstance(InstancePainter painter) {
    Graphics g = painter.getGraphics();
    Bounds bds = painter.getBounds();

    // draw boundary
    painter.drawBounds();

    // draw contents
    if (painter.getShowState()) {
      MemState state = getState(painter);
      state.paint(painter.getGraphics(), bds.getX(), bds.getY());
    } else {
      BitWidth addr = painter.getAttributeValue(ADDR_ATTR);
      int addrBits = addr.getWidth();
      int bytes = 1 << addrBits;
      String label;
      if (this instanceof Rom) {
        if (addrBits >= 30) {
          label = StringUtil.format(Strings.get("romGigabyteLabel"), ""
              + (bytes >>> 30));
        } else if (addrBits >= 20) {
          label = StringUtil.format(Strings.get("romMegabyteLabel"), ""
              + (bytes >> 20));
        } else if (addrBits >= 10) {
          label = StringUtil.format(Strings.get("romKilobyteLabel"), ""
              + (bytes >> 10));
        } else {
          label = StringUtil.format(Strings.get("romByteLabel"), ""
              + bytes);
        }
      } else {
        if (addrBits >= 30) {
          label = StringUtil.format(Strings.get("ramGigabyteLabel"), ""
              + (bytes >>> 30));
        } else if (addrBits >= 20) {
          label = StringUtil.format(Strings.get("ramMegabyteLabel"), ""
              + (bytes >> 20));
        } else if (addrBits >= 10) {
          label = StringUtil.format(Strings.get("ramKilobyteLabel"), ""
              + (bytes >> 10));
        } else {
          label = StringUtil.format(Strings.get("ramByteLabel"), ""
              + bytes);
        }
      }
      GraphicsUtil.drawCenteredText(g, label, bds.getX() + bds.getWidth()
          / 2, bds.getY() + bds.getHeight() / 2);
    }

    // draw input and output ports
    painter.drawPort(DATA, Strings.get("ramDataLabel"), Direction.WEST);
    painter.drawPort(ADDR, Strings.get("ramAddrLabel"), Direction.EAST);
    g.setColor(Color.GRAY);
    painter.drawPort(CS, Strings.get("ramCSLabel"), Direction.SOUTH);
  }
 
  File getCurrentImage(Instance instance) {
    return currentInstanceFiles.get(instance);
  }
 
  void setCurrentImage(Instance instance, File value) {
    currentInstanceFiles.put(instance, value);
  }
 
  public void loadImage(InstanceState instanceState, File imageFile)
      throws IOException {
    MemState s = this.getState(instanceState);
    HexFile.open(s.getContents(), imageFile);
    this.setCurrentImage(instanceState.getInstance(), imageFile);
  }

  @Override
  protected Object getInstanceFeature(Instance instance, Object key) {
    if (key == MenuExtender.class) return new MemMenu(this, instance);
    return super.getInstanceFeature(instance, key);
  }
 
  static class MemListener implements HexModelListener {
    Instance instance;
   
    MemListener(Instance instance) { this.instance = instance; }
   
    public void metainfoChanged(HexModel source) { }

    public void bytesChanged(HexModel source, long start,
        long numBytes, int[] values) {
      instance.fireInvalidated();
    }
  }
}
TOP

Related Classes of com.cburch.logisim.std.memory.Mem

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.