/* * $Id: Cpu.java 536 2008-02-19 06:03:27Z weiju $ * * Created on 2006/02/14 * Copyright 2005-2008 by Wei-ju Wu * This file is part of The Z-machine Preservation Project (ZMPP). * * ZMPP 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 * (at your option) any later version. * * ZMPP 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 ZMPP. If not, see <http://www.gnu.org/licenses/>. */ package org.zmpp.vm; import java.util.List; public interface Cpu { /** * The possible variable types. */ enum VariableType { STACK, LOCAL, GLOBAL } /** * Resets this object to initial state. */ void reset(); /** * Indicates if the virtual machine is running. * * @return true if the machine is running, false, otherwise */ boolean isRunning(); /** * Sets the running status. * * @param flag the running status */ void setRunning(boolean flag); /** * Halts the machine with the specified error message. * * @param errormsg the error message */ void halt(String errormsg); /** * Returns the next instruction. * * @return the next instruction */ Instruction nextStep(); /** * Translates a packed address into a byte address. * * @param packedAddress the packed address * @param isCall if true then this is a call address, if false, this is a * string address * @return the translated byte address */ int translatePackedAddress(int packedAddress, boolean isCall); /** * Computes a branch target from an offset. * * @return the resulting branch target */ int computeBranchTarget(short offset, int instructionLength); /** * Returns the current program counter. * * @return the current program counter */ int getProgramCounter(); /** * Sets the program counter to a new address. * * @param address the new address */ void setProgramCounter(int address); /** * Increments the program counter by the specified offset. * * @param offset the offset */ void incrementProgramCounter(int offset); // ******************************************************************** // ***** Stack operations // *************************************** /** * Returns the global stack pointer. Equals the stack size. * * @return the stack pointer */ int getStackPointer(); /** * Returns the value at the top of the stack without removing it. * * @return the stack top element */ short getStackTopElement(); /** * Sets the value of the element at the top of the stack without * incrementing the stack pointer. * * @param value the value to set */ void setStackTopElement(short value); /** * Returns the evaluation stack element at the specified index. * * @param index an index * @return the stack value at the specified index */ short getStackElement(int index); /** * Pushes the specified value on the user stack. * * @param userstackAddress the address of the user stack * @param value the value to push * @return true if operation was ok, false if overflow */ boolean pushUserStack(int userstackAddress, short value); /** * Pops the specified value from the user stack. * * @param userstackAddress the address of the user stack * @return the popped value */ short popUserStack(int userstackAddress); // ******************************************************************** // ***** Variable access // *************************************** /** * Returns the value of the specified variable. 0 is the stack pointer, * 0x01-0x0f are local variables, and 0x10-0xff are global variables. If the * stack pointer is read from, its top value will be popped off. * * @param variableNumber the variable number * @return the value of the variable * @throws IllegalStateException if a local variable is accessed without a * subroutine context or if a non-existent local variable is accessed */ short getVariable(int variableNumber); /** * Sets the value of the specified variable. If the stack pointer is written * to, the stack will contain one more value. * * @param variableNumber the variable number * @param value the value to write * @throws IllegalStateException if a local variable is accessed without a * subroutine context or if a non-existent local variable is accessed */ void setVariable(int variableNumber, short value); // ******************************************************************** // ***** Routine stack frames // *************************************** /** * Pushes a new routine context onto the routine context stack. * * @param routineContext the routine context object */ void pushRoutineContext(RoutineContext routineContext); /** * Pops the current routine context from the stack. It will also restore the * state before the invocation of the routine, i.e. it will restore the * program counter and the stack pointers and set the specfied return value * to the return variable. * * @param returnValue the return value * @throws IllegalStateException if no RoutineContext exists */ void popRoutineContext(short returnValue); /** * Returns the state of the current routine context stack as a non- * modifiable List. This is exposed to PortableGameState to take a machine * state snapshot. * * @return the list of routine contexts */ List<RoutineContext> getRoutineContexts(); /** * Copies the list of routine contexts into this machine's routine context * stack. This is a consequence of a restore operation. * * @param contexts a list of routine contexts */ void setRoutineContexts(List<RoutineContext> contexts); /** * Returns the current routine context without affecting the state of the * machine. * * @return the current routine context */ RoutineContext getCurrentRoutineContext(); /** * Performs a routine call. * * @param routineAddress the packed routine address * @param returnAddress the return address * @param args the argument list * @param returnVariable the return variable or DISCARD_RESULT * @return the routine context created */ RoutineContext call(int routineAddress, int returnAddress, short[] args, short returnVariable); // *********************************************************************** // **** Interrupt routines // ******************************** /** * Indicates if the last interrupt routine performed any output. * * @return true if the routine performed output, false otherwise */ boolean interruptDidOutput(); /** * Calls the specified interrupt routine. * * @param routineAddress the routine address * @return the return value */ short callInterrupt(int routineAddress); }