/* * Copyright 2010 Georgios Migdos <cyberpython@gmail.com>. * * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * under the License. */ package bmach.logic.machine; import bmach.logic.machine.parser.IInstructionParser; import bmach.logic.machine.parser.InstructionParser; import bmach.logic.machine.parser.MalformedInstructionException; import bmach.logic.memory.IMainMemory; import bmach.logic.memory.IMemoryAddress; import bmach.logic.memory.MainMemory; import bmach.logic.memory.MemoryAddress; import bmach.logic.processor.IProcessor; import bmach.logic.processor.MalformedProcessorInstructionException; import bmach.logic.processor.Processor; import bmach.logic.processor.ProcessorNotificationData; import bmach.logic.processor.ProcessorUtils; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.InputStream; import java.io.Reader; import util.binary.bitpattern.BitPattern; import util.binary.bitpattern.BitPatternOverflowException; import util.binary.bitpattern.IBitPattern; import util.patterns.observer.IObserver; /** * * @author Georgios Migdos <cyberpython@gmail.com> */ public class Machine implements IMachine { private final static long DEFAULT_SLEEP_TIME; public final static int STATUS_OK; public final static int STATUS_UNKNOWN_INSTRUCTION; public final static int STATUS_UNKNOWN_ERROR; static { DEFAULT_SLEEP_TIME = 500; STATUS_OK = 0; STATUS_UNKNOWN_INSTRUCTION = 1; STATUS_UNKNOWN_ERROR = 2; } private IProcessor processor; private IMainMemory memory; private boolean stop; private long sleepTime; private int statusCode; private String statusMsg; private boolean stepByStep; public Machine() { processor = new Processor(); memory = new MainMemory(); stop = false; sleepTime = DEFAULT_SLEEP_TIME; statusCode = STATUS_OK; statusMsg = ""; stepByStep = false; } public IMainMemory getMemory() { return memory; } public IProcessor getProcessor() { return processor; } public void loadInstructions(InputStream is) throws MalformedInstructionException { load(is); } public void loadInstructions(Reader r) throws MalformedInstructionException { load(r); } public void reset() { processor.init(this); memory.clear(); } public void setStepByStep(boolean stepByStep) { this.stepByStep = stepByStep; } public boolean getStepByStep() { return stepByStep; } public void nextStep() { proceed(); } private void load(Object o) throws MalformedInstructionException { int i = 0; IInstructionParser p; if (o instanceof InputStream) { p = new InstructionParser((InputStream) o); } else if (o instanceof Reader) { p = new InstructionParser((Reader) o); } else { return; } String inst; while ((inst = p.parseNextInstruction()) != null) { IMemoryAddress address1 = new MemoryAddress("0x" + Integer.toHexString(i++)); IMemoryAddress address2 = new MemoryAddress("0x" + Integer.toHexString(i++)); memory.get(address1).setContentValue(inst.substring(0, 8)); memory.get(address2).setContentValue(inst.substring(8, 16)); } } public void halt() { stop = true; } public int getStatusCode() { return statusCode; } public String getStatusMsg() { return statusMsg; } public long getSleepTime() { return sleepTime; } public void setSleepTime(long sleepTime) { this.sleepTime = sleepTime; } public void run() { stop = false; statusCode = STATUS_OK; statusMsg = ""; processor.init(this); proceed(); while ((!stop) && (!processor.hasReachedEnd())) { consumeTime(1000); } } public void notifyObserver(Object notificationData) { if(!stepByStep){ if (notificationData instanceof ProcessorNotificationData) { Object data = ((ProcessorNotificationData) notificationData).getData(); if ((data instanceof IBitPattern) && (!stop) && (!processor.hasReachedEnd())) { consumeTime(sleepTime); proceed(); } } } } private void proceed() { try { processor.execNext(); } catch (MalformedProcessorInstructionException mpie) { stop = true; statusCode = STATUS_UNKNOWN_INSTRUCTION; statusMsg = mpie.getMessage(); } catch(BitPatternOverflowException boe) { stop = true; statusCode = STATUS_UNKNOWN_INSTRUCTION; statusMsg = boe.getMessage(); } } private void consumeTime(long millis) { try { Thread.sleep(millis); } catch (InterruptedException ie) { } } public static void main(String[] args) { IMachine machine = new Machine(); IProcessor p = machine.getProcessor(); p.addObserver(new IObserver() { public void notifyObserver(Object notificationData) { if (notificationData instanceof ProcessorNotificationData) { Object data = ((ProcessorNotificationData) notificationData).getData(); if (data instanceof IBitPattern) { //System.out.println("Command executed: " + ((IBitPattern) data).toHexString()); try { IBitPattern inst = new BitPattern(16,((IBitPattern) data).toBinaryString().substring(8)); System.out.println("Command executed: " + ProcessorUtils.instructionToString(inst)); } catch (MalformedProcessorInstructionException mpie) { } } } } }); try { machine.loadInstructions(new FileReader("/home/cyberpython/Desktop/test2.bma")); Thread t = new Thread(machine); t.start(); try { t.join(); } catch (InterruptedException ie) { } System.out.println(); p.printRegistersHex(System.out); System.out.println(); machine.getMemory().printHex(System.out); } catch (FileNotFoundException fnfe) { fnfe.printStackTrace(); } catch (MalformedInstructionException mie) { mie.printStackTrace(); } } }