Package Hack.CPUEmulator

Source Code of Hack.CPUEmulator.ROM$ROMLoadProgramTask

/********************************************************************************
* The contents of this file are subject to the GNU General Public License      *
* (GPL) Version 2 or later (the "License"); you may not use this file except   *
* in compliance with the License. You may obtain a copy of the License at      *
* http://www.gnu.org/copyleft/gpl.html                                         *
*                                                                              *
* Software distributed under the License is distributed on an "AS IS" basis,   *
* without warranty of any kind, either expressed or implied. See the License   *
* for the specific language governing rights and limitations under the         *
* License.                                                                     *
*                                                                              *
* This file was originally developed as part of the software suite that        *
* supports the book "The Elements of Computing Systems" by Nisan and Schocken, *
* MIT Press 2005. If you modify the contents of this file, please document and *
* mark your changes clearly, for the benefit of others.                        *
********************************************************************************/

package Hack.CPUEmulator;

import Hack.Assembler.AssemblerException;
import Hack.Assembler.HackAssemblerTranslator;
import Hack.ComputerParts.ComputerPartEvent;
import Hack.ComputerParts.PointedMemory;
import Hack.Controller.HackController;
import Hack.Controller.ProgramException;
import Hack.Events.ProgramEvent;
import Hack.Events.ProgramEventListener;
import Hack.Utilities.Definitions;
import java.util.Vector;

/**
* A Read Only Memory. Has methods for loading a machine language file (.hack) and for
* setting a pointer (a specific address in the ROM for GUI perposes).
*/
public class ROM extends PointedMemory implements ProgramEventListener
{
    /**
     * Decimal numeric format
     */
    public static final int DECIMAL_FORMAT = HackController.DECIMAL_FORMAT;

    /**
     * Hexadecimal numeric format
     */
    public static final int HEXA_FORMAT = HackController.HEXA_FORMAT;;

    /**
     * Binary numeric format
     */
    public static final int BINARY_FORMAT = HackController.BINARY_FORMAT;;

    /**
     * Assembler format
     */
    public static final int ASM_FORMAT = 4;

    // listeners to program changes
    private Vector listeners;

    /**
     * Constructs a new ROM with the given ROM GUI.
     */
    public ROM(ROMGUI gui) {
        super(Definitions.ROM_SIZE, gui);
        setNullValue(HackAssemblerTranslator.NOP, true);
        listeners = new Vector();

        if (hasGUI) {
          gui.addProgramListener( (ProgramEventListener)this);
          gui.setNumericFormat(ASM_FORMAT); // enable assembler
        }
    }

    /**
     * Loads the given program file (HACK or ASM) into the ROM.
     */
    public synchronized void loadProgram(String fileName) throws ProgramException {
        short[] program = null;

        if (displayChanges)
            ((ROMGUI)gui).showMessage("Loading...");

        try {
            program = HackAssemblerTranslator.loadProgram(fileName, Definitions.ROM_SIZE,
                                                          HackAssemblerTranslator.NOP);

            mem = program;

            if (displayChanges) {
                gui.setContents(mem);

                ((ROMGUI)gui).setProgram(fileName);

                ((ROMGUI)gui).hideMessage();
                gui.hideHighlight();
            }

            notifyProgramListeners(ProgramEvent.LOAD, fileName);

        } catch (AssemblerException ae) {
            if (displayChanges)
                ((ROMGUI)gui).hideMessage();
            throw new ProgramException(ae.getMessage());
        }

    }

    /**
     * Called when the ROM's current program is changed.
     * The event contains the source object, event type and the new program's file name (if any).
     */
    public void programChanged(ProgramEvent event) {
        switch (event.getType()) {
            case ProgramEvent.LOAD:
                ROMLoadProgramTask task = new ROMLoadProgramTask(event.getProgramFileName());
                Thread t = new Thread(task);
                t.start();
                break;
            case ProgramEvent.CLEAR:
                notifyProgramListeners(ProgramEvent.CLEAR, null);
        }
    }

    /**
     * Called when the contents of the memory are changed through the memory gui.
     */
    public void valueChanged(ComputerPartEvent event) {
        short newValue = event.getValue();
        int newAddress = event.getIndex();
        clearErrorListeners();
        try {
            HackAssemblerTranslator.getInstance().codeToText(newValue);
            setValueAt(newAddress, newValue, true);
        } catch (AssemblerException ae) {
            notifyErrorListeners("Illegal instruction");
            quietUpdateGUI(newAddress, mem[newAddress]);
        }
    }

    class ROMLoadProgramTask implements Runnable {

        private String programName;

        public ROMLoadProgramTask(String programName) {
            this.programName = programName;
        }

        public void run() {
            clearErrorListeners();
            try {
                loadProgram(programName);
            } catch (ProgramException pe) {
                notifyErrorListeners(pe.getMessage());
            }
        }
    }

    /**
     * Registers the given ProgramEventListener as a listener to this GUI.
     */
    public void addProgramListener(ProgramEventListener listener) {
        listeners.add(listener);
    }

    /**
     * Un-registers the given ProgramEventListener from being a listener to this GUI.
     */
    public void removeProgramListener(ProgramEventListener listener) {
        listeners.remove(listener);
    }

    /**
     * Notifies all the ProgramEventListeners on a change in the ROM's program by creating
     * a ProgramEvent (with the new event type and program's file name) and sending it using the
     * programChanged method to all the listeners.
     */
    protected void notifyProgramListeners(byte eventType, String programFileName) {
        ProgramEvent event = new ProgramEvent(this, eventType, programFileName);

        for (int i = 0; i < listeners.size(); i++) {
            ((ProgramEventListener)listeners.elementAt(i)).programChanged(event);
        }
    }
}
TOP

Related Classes of Hack.CPUEmulator.ROM$ROMLoadProgramTask

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.