Package com.cburch.logisim.std.memory

Source Code of com.cburch.logisim.std.memory.Rom$ContentsCell

/* 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.Window;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.NoSuchElementException;
import java.util.StringTokenizer;
import java.util.WeakHashMap;

import javax.swing.JLabel;

import com.cburch.logisim.circuit.CircuitState;
import com.cburch.logisim.data.Attribute;
import com.cburch.logisim.data.AttributeSet;
import com.cburch.logisim.data.BitWidth;
import com.cburch.logisim.data.Value;
import com.cburch.logisim.gui.hex.HexFile;
import com.cburch.logisim.gui.hex.HexFrame;
import com.cburch.logisim.gui.main.Frame;
import com.cburch.logisim.instance.Instance;
import com.cburch.logisim.instance.InstanceState;
import com.cburch.logisim.instance.Port;
import com.cburch.logisim.proj.Project;
import static com.cburch.logisim.util.LocaleString.*;

public class Rom extends Mem {
    public static Attribute<MemContents> CONTENTS_ATTR = new ContentsAttribute();

    // The following is so that instance's MemListeners aren't freed by the
    // garbage collector until the instance itself is ready to be freed.
    private WeakHashMap<Instance,MemListener> memListeners;

    public Rom() {
        super("ROM", getFromLocale("romComponent"), 0);
        setIconName("rom.svg");
        memListeners = new WeakHashMap<Instance,MemListener>();
    }

    @Override
    void configurePorts(Instance instance) {
        Port[] ps = new Port[MEM_INPUTS];
        configureStandardPorts(instance, ps);
        instance.setPorts(ps);
    }

    @Override
    public AttributeSet createAttributeSet() {
        return new RomAttributes();
    }

    @Override
    MemState getState(Instance instance, CircuitState state) {
        MemState ret = (MemState) instance.getData(state);
        if (ret == null) {
            MemContents contents = getMemContents(instance);
            ret = new MemState(contents);
            instance.setData(state, ret);
        }
        return ret;
    }

    @Override
    MemState getState(InstanceState state) {
        MemState ret = (MemState) state.getData();
        if (ret == null) {
            MemContents contents = getMemContents(state.getInstance());
            ret = new MemState(contents);
            state.setData(ret);
        }
        return ret;
    }

    @Override
    HexFrame getHexFrame(Project proj, Instance instance, CircuitState state) {
        return RomAttributes.getHexFrame(getMemContents(instance), proj);
    }

    // TODO - maybe delete this method?
    MemContents getMemContents(Instance instance) {
        return instance.getAttributeValue(CONTENTS_ATTR);
    }

    @Override
    public void propagate(InstanceState state) {
        MemState myState = getState(state);
        BitWidth dataBits = state.getAttributeValue(DATA_ATTR);

        Value addrValue = state.getPort(ADDR);
        boolean chipSelect = state.getPort(CS) != Value.FALSE;

        if (!chipSelect) {
            myState.setCurrent(-1);
            state.setPort(DATA, Value.createUnknown(dataBits), DELAY);
            return;
        }

        int addr = addrValue.toIntValue();
        if (!addrValue.isFullyDefined() || addr < 0)
            return;
        if (addr != myState.getCurrent()) {
            myState.setCurrent(addr);
            myState.scrollToShow(addr);
        }

        int val = myState.getContents().get(addr);
        state.setPort(DATA, Value.createKnown(dataBits, val), DELAY);
    }

    @Override
    protected void configureNewInstance(Instance instance) {
        super.configureNewInstance(instance);
        MemContents contents = getMemContents(instance);
        MemListener listener = new MemListener(instance);
        memListeners.put(instance, listener);
        contents.addHexModelListener(listener);
    }

    private static class ContentsAttribute extends Attribute<MemContents> {
        public ContentsAttribute() {
            super("contents", getFromLocale("romContentsAttr"));
        }

        @Override
        public java.awt.Component getCellEditor(Window source, MemContents value) {
            if (source instanceof Frame) {
                Project proj = ((Frame) source).getProject();
                RomAttributes.register(value, proj);
            }
            ContentsCell ret = new ContentsCell(source, value);
            ret.mouseClicked(null);
            return ret;
        }

        @Override
        public String toDisplayString(MemContents value) {
            return getFromLocale("romContentsValue");
        }

        @Override
        public String toStandardString(MemContents state) {
            int addr = state.getLogLength();
            int data = state.getWidth();
            StringWriter ret = new StringWriter();
            ret.write("addr/data: " + addr + " " + data + "\n");
            try {
                HexFile.save(ret, state);
            } catch (IOException e) { }
            return ret.toString();
        }

        @Override
        public MemContents parse(String value) {
            int lineBreak = value.indexOf('\n');
            String first = lineBreak < 0 ? value : value.substring(0, lineBreak);
            String rest = lineBreak < 0 ? "" : value.substring(lineBreak + 1);
            StringTokenizer toks = new StringTokenizer(first);
            try {
                String header = toks.nextToken();
                if (!header.equals("addr/data:")) {
                    return null;
                }

                int addr = Integer.parseInt(toks.nextToken());
                int data = Integer.parseInt(toks.nextToken());
                MemContents ret = MemContents.create(addr, data);
                HexFile.open(ret, new StringReader(rest));
                return ret;
            } catch (IOException e) {
                return null;
            } catch (NumberFormatException e) {
                return null;
            } catch (NoSuchElementException e) {
                return null;
            }
        }
    }

  @SuppressWarnings("serial")
    private static class ContentsCell extends JLabel
            implements MouseListener {
        Window source;
        MemContents contents;

        ContentsCell(Window source, MemContents contents) {
            super(getFromLocale("romContentsValue"));
            this.source = source;
            this.contents = contents;
            addMouseListener(this);
        }

        @Override
        public void mouseClicked(MouseEvent e) {
            if (contents == null) {
                return;
            }

            Project proj = source instanceof Frame ? ((Frame) source).getProject() : null;
            HexFrame frame = RomAttributes.getHexFrame(contents, proj);
            frame.setVisible(true);
            frame.toFront();
        }

        @Override
        public void mousePressed(MouseEvent e) { }

        @Override
        public void mouseReleased(MouseEvent e) { }

        @Override
        public void mouseEntered(MouseEvent e) { }

        @Override
        public void mouseExited(MouseEvent e) { }
    }
}
TOP

Related Classes of com.cburch.logisim.std.memory.Rom$ContentsCell

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.