+++ /dev/null
-// Copyright 2003 Brian Alliet
-// Based on org.xwt.imp.MIPS by Adam Megacz
-// Portions Copyright 2003 Adam Megacz
-package org.xwt.mips;
-
-import java.io.*;
-
-public class Interpreter extends Runtime {
- // Registers
- private int[] registers = new int[32];
- private int hi,lo;
-
- // Floating Point Registers
- private int[] fpregs = new int[32];
- // 24-31 - unused
- // 23 - conditional bit
- // 18-22 - unused
- // 12-17 - cause bits (unimplemented)
- // 7-11 - enables bits (unimplemented)
- // 2-6 - flags (unimplemented)
- // 0-1 - rounding mode (only implemented for fixed point conversions)
- private int fcsr;
-
- private int nextPC;
-
- // Register Operations
- private final void setFC(boolean b) { fcsr = (fcsr&~0x800000) | (b ? 0x800000 : 0x000000); }
- private final int roundingMode() { return fcsr & 3; /* bits 0-1 */ }
- private final double getDouble(int r) {
- return Double.longBitsToDouble(((fpregs[r+1]&0xffffffffL) << 32) | (fpregs[r]&0xffffffffL));
- }
- private final void setDouble(int r, double d) {
- long l = Double.doubleToLongBits(d);
- fpregs[r+1] = (int)(l >>> 32); fpregs[r] = (int)l;
- }
- private final float getFloat(int r) { return Float.intBitsToFloat(fpregs[r]); }
- private final void setFloat(int r, float f) { fpregs[r] = Float.floatToRawIntBits(f); }
-
- protected void _execute() throws ExecutionException { runSome(); }
-
- // Main interpretor
- // the return value is meaningless, its just to catch people typing "return" by accident
- private final int runSome() throws FaultException,ExecutionException {
- int[] r = registers;
- int[] f = fpregs;
- int pc = nextPC;
- int nextPC = pc + 4;
- try {
- OUTER: for(;;) {
- int insn;
- try {
- insn = readPages[pc>>>PAGE_SHIFT][(pc>>>2)&PAGE_WORDS-1];
- } catch (RuntimeException e) {
- insn = memRead(pc);
- }
-
- int op = (insn >>> 26) & 0xff; // bits 26-31
- int rs = (insn >>> 21) & 0x1f; // bits 21-25
- int rt = (insn >>> 16) & 0x1f; // bits 16-20
- int ft = (insn >>> 16) & 0x1f;
- int rd = (insn >>> 11) & 0x1f; // bits 11-15
- int fs = (insn >>> 11) & 0x1f;
- int shamt = (insn >>> 6) & 0x1f; // bits 6-10
- int fd = (insn >>> 6) & 0x1f;
- int subcode = insn & 0x3f; // bits 0-5
-
- int jumpTarget = (insn & 0x03ffffff); // bits 0-25
- int unsignedImmediate = insn & 0xffff;
- int signedImmediate = (insn << 16) >> 16;
- int branchTarget = signedImmediate;
-
- int tmp, addr; // temporaries
-
- r[ZERO] = 0;
-
- switch(op) {
- case 0: {
- switch(subcode) {
- case 0: // SLL
- if(insn == 0) break;
- r[rd] = r[rt] << shamt;
- break;
- case 2: // SRL
- r[rd] = r[rt] >>> shamt;
- break;
- case 3: // SRA
- r[rd] = r[rt] >> shamt;
- break;
- case 4: // SLLV
- r[rd] = r[rt] << (r[rs]&0x1f);
- break;
- case 6: // SRLV
- r[rd] = r[rt] >>> (r[rs]&0x1f);
- break;
- case 7: // SRAV
- r[rd] = r[rt] >> (r[rs]&0x1f);
- break;
- case 8: // JR
- tmp = r[rs]; pc += 4; nextPC = tmp;
- continue OUTER;
- case 9: // JALR
- tmp = r[rs]; pc += 4; r[rd] = pc+4; nextPC = tmp;
- continue OUTER;
- case 12: // SYSCALL
- r[V0] = syscall(r[V0],r[A0],r[A1],r[A2],r[A3]);
- if(state != RUNNING) {
- this.nextPC = nextPC;
- break OUTER;
- }
- break;
- case 13: // BREAK
- throw new ExecutionException("Break");
- case 16: // MFHI
- r[rd] = hi;
- break;
- case 17: // MTHI
- hi = r[rs];
- break;
- case 18: // MFLO
- r[rd] = lo;
- break;
- case 19: // MTLO
- lo = r[rs];
- break;
- case 24: { // MULT
- long hilo = (long)(r[rs]) * ((long)r[rt]);
- hi = (int) (hilo >>> 32);
- lo = (int) hilo;
- break;
- }
- case 25: { // MULTU
- long hilo = (r[rs] & 0xffffffffL) * (r[rt] & 0xffffffffL);
- hi = (int) (hilo >>> 32);
- lo = (int) hilo;
- break;
- }
- case 26: // DIV
- hi = r[rs]%r[rt];
- lo = r[rs]/r[rt];
- break;
- case 27: // DIVU
- hi = (int)((r[rs] & 0xffffffffL) % (r[rt] & 0xffffffffL));
- lo = (int)((r[rs] & 0xffffffffL) / (r[rt] & 0xffffffffL));
- break;
- case 32: // ADD
- throw new ExecutionException("ADD (add with oveflow trap) not suported");
- /*This must trap on overflow
- r[rd] = r[rs] + r[rt];
- break;*/
- case 33: // ADDU
- r[rd] = r[rs] + r[rt];
- break;
- case 34: // SUB
- throw new ExecutionException("SUB (sub with oveflow trap) not suported");
- /*This must trap on overflow
- r[rd] = r[rs] - r[rt];
- break;*/
- case 35: // SUBU
- r[rd] = r[rs] - r[rt];
- break;
- case 36: // AND
- r[rd] = r[rs] & r[rt];
- break;
- case 37: // OR
- r[rd] = r[rs] | r[rt];
- break;
- case 38: // XOR
- r[rd] = r[rs] ^ r[rt];
- break;
- case 39: // NOR
- r[rd] = ~(r[rs] | r[rt]);
- break;
- case 42: // SLT
- r[rd] = r[rs] < r[rt] ? 1 : 0;
- break;
- case 43: // SLTU
- r[rd] = ((r[rs] & 0xffffffffL) < (r[rt] & 0xffffffffL)) ? 1 : 0;
- break;
- default:
- throw new ExecutionException("Illegal instruction 0/" + subcode);
- }
- break;
- }
- case 1: {
- switch(rt) {
- case 0: // BLTZ
- if(r[rs] < 0) {
- pc += 4; tmp = pc + branchTarget*4; nextPC = tmp;
- continue OUTER;
- }
- break;
- case 1: // BGEZ
- if(r[rs] >= 0) {
- pc += 4; tmp = pc + branchTarget*4; nextPC = tmp;
- continue OUTER;
- }
- break;
- case 16: // BLTZAL
- if(r[rs] < 0) {
- pc += 4; r[RA] = pc+4; tmp = pc + branchTarget*4; nextPC = tmp;
- continue OUTER;
- }
- break;
- case 17: // BGEZAL
- if(r[rs] >= 0) {
- pc += 4; r[RA] = pc+4; tmp = pc + branchTarget*4; nextPC = tmp;
- continue OUTER;
- }
- break;
- default:
- throw new ExecutionException("Illegal Instruction");
- }
- break;
- }
- case 2: { // J
- tmp = (pc&0xf0000000) | (jumpTarget << 2);
- pc+=4; nextPC = tmp;
- continue OUTER;
- }
- case 3: { // JAL
- tmp = (pc&0xf0000000) | (jumpTarget << 2);
- pc+=4; r[RA] = pc+4; nextPC = tmp;
- continue OUTER;
- }
- case 4: // BEQ
- if(r[rs] == r[rt]) {
- pc += 4; tmp = pc + branchTarget*4; nextPC = tmp;
- continue OUTER;
- }
- break;
- case 5: // BNE
- if(r[rs] != r[rt]) {
- pc += 4; tmp = pc + branchTarget*4; nextPC = tmp;
- continue OUTER;
- }
- break;
- case 6: //BLEZ
- if(r[rs] <= 0) {
- pc += 4; tmp = pc + branchTarget*4; nextPC = tmp;
- continue OUTER;
- }
- break;
- case 7: //BGTZ
- if(r[rs] > 0) {
- pc += 4; tmp = pc + branchTarget*4; nextPC = tmp;
- continue OUTER;
- }
- break;
- case 8: // ADDI
- r[rt] = r[rs] + signedImmediate;
- break;
- case 9: // ADDIU
- r[rt] = r[rs] + signedImmediate;
- break;
- case 10: // SLTI
- r[rt] = r[rs] < signedImmediate ? 1 : 0;
- break;
- case 11: // SLTIU
- r[rt] = (r[rs]&0xffffffffL) < (unsignedImmediate&0xffffffffL) ? 1 : 0;
- break;
- case 12: // ANDI
- r[rt] = r[rs] & unsignedImmediate;
- break;
- case 13: // ORI
- r[rt] = r[rs] | unsignedImmediate;
- break;
- case 14: // XORI
- r[rt] = r[rs] ^ unsignedImmediate;
- break;
- case 15: // LUI
- r[rt] = unsignedImmediate << 16;
- break;
- case 16:
- throw new ExecutionException("TLB/Exception support not implemented");
- case 17: { // FPU
- boolean debug = false;
- String line = "";
- boolean debugon = debug && (line.indexOf("dtoa.c:51") >= 0 || line.indexOf("dtoa.c:52") >= 0 || line.indexOf("test.c") >= 0);
- if(rs > 8 && debugon)
- System.out.println(" FP Op: " + op + "/" + rs + "/" + subcode + " " + line);
- // FEATURE: This could probably be removed. I don't think gcc will ever generate code that does this
- if(roundingMode() != 0 && rs != 6 /*CTC.1*/ && !((rs==16 || rs==17) && subcode == 36 /* CVT.W.Z */))
- throw new ExecutionException("Non-cvt.w.z operation attempted with roundingMode != round to nearest");
- switch(rs) {
- case 0: // MFC.1
- r[rt] = f[rd];
- break;
- case 2: // CFC.1
- if(fs != 31) throw new ExecutionException("FCR " + fs + " unavailable");
- r[rt] = fcsr;
- break;
- case 4: // MTC.1
- f[rd] = r[rt];
- break;
- case 6: // CTC.1
- if(fs != 31) throw new ExecutionException("FCR " + fs + " unavailable");
- fcsr = r[rt];
- break;
- case 8: // BC1F, BC1T
- if(((fcsr&0x800000)!=0) == (((insn>>>16)&1)!=0)) {
- pc += 4; tmp = pc + branchTarget*4; nextPC = tmp;
- continue OUTER;
- }
- break;
- case 16: { // Single
- switch(subcode) {
- case 0: // ADD.S
- setFloat(fd,getFloat(fs)+getFloat(ft));
- break;
- case 1: // SUB.S
- setFloat(fd,getFloat(fs)-getFloat(ft));
- break;
- case 2: // MUL.S
- setFloat(fd,getFloat(fs)*getFloat(ft));
- break;
- case 3: // DIV.S
- setFloat(fd,getFloat(fs)/getFloat(ft));
- break;
- case 5: // ABS.S
- setFloat(fd,Math.abs(getFloat(fs)));
- break;
- case 6: // MOV.S
- f[fd] = f[fs];
- break;
- case 7: // NEG.S
- setFloat(fd,-getFloat(fs)); // FEATURE: just flip the sign bit
- break;
- case 33: // CVT.D.S
- setDouble(fd,getFloat(fs));
- break;
- case 36: // CVT.W.S
- switch(roundingMode()) {
- case 0: f[fd] = (int)Math.floor(getFloat(fs)+0.5f); break; // Round to nearest
- case 1: f[fd] = (int)getFloat(fs); break; // Round towards zero
- case 2: f[fd] = (int)Math.ceil(getFloat(fs)); break; // Round towards plus infinity
- case 3: f[fd] = (int)Math.floor(getFloat(fs)); break; // Round towards minus infinity
- }
- break;
- case -50: // C.EQ.S
- setFC(getFloat(fs) == getFloat(ft)); // FEATURE: just compare the ints, be sure things are normalized
- break;
- case 60: // C.LT.S
- setFC(getFloat(fs) < getFloat(ft));
- break;
- default: throw new ExecutionException("Invalid Instruction 17/" + rs + "/" + subcode);
- }
- break;
- }
- case 17: { // Double
- switch(subcode) {
- case 0: // ADD.D
- setDouble(fd,getDouble(fs)+getDouble(ft));
- break;
- case 1: // SUB.D
- if(debugon) System.out.println("f" + fd + " = f" + fs + " (" + getDouble(fs) + ") - f" + ft + " (" + getDouble(ft) + ")");
- setDouble(fd,getDouble(fs)-getDouble(ft));
- break;
- case 2: // MUL.D
- if(debugon) System.out.println("f" + fd + " = f" + fs + " (" + getDouble(fs) + ") * f" + ft + " (" + getDouble(ft) + ")");
- setDouble(fd,getDouble(fs)*getDouble(ft));
- if(debugon) System.out.println("f" + fd + " = " + getDouble(fd));
- break;
- case 3: // DIV.D
- setDouble(fd,getDouble(fs)/getDouble(ft));
- break;
- case 5: // ABS.D
- setDouble(fd,Math.abs(getDouble(fs)));
- break;
- case 6: // MOV.D
- f[fd] = f[fs];
- f[fd+1] = f[fs+1];
- break;
- case 7: // NEG.D
- setDouble(fd,-getDouble(fs)); // FEATURE: just flip the sign bit
- break;
- case 32: // CVT.S.D
- setFloat(fd,(float)getDouble(fs));
- break;
- case 36: // CVT.W.D
- if(debugon) System.out.println("CVT.W.D rm: " + roundingMode() + " f" + fs + ":" + getDouble(fs));
- switch(roundingMode()) {
- case 0: f[fd] = (int)Math.floor(getDouble(fs)+0.5); break; // Round to nearest
- case 1: f[fd] = (int)getDouble(fs); break; // Round towards zero
- case 2: f[fd] = (int)Math.ceil(getDouble(fs)); break; // Round towards plus infinity
- case 3: f[fd] = (int)Math.floor(getDouble(fs)); break; // Round towards minus infinity
- }
- if(debugon) System.out.println("CVT.W.D: f" + fd + ":" + f[fd]);
- break;
- case 50: // C.EQ.D
- setFC(getDouble(fs) == getDouble(ft)); // FEATURE: just compare the ints, be sure things are normalized
- break;
- case 60: // C.LT.D
- setFC(getDouble(fs) < getDouble(ft));
- break;
- case 62: // C.LE.D
- setFC(getDouble(fs) <= getDouble(ft));
- break;
- default: throw new ExecutionException("Invalid Instruction 17/" + rs + "/" + subcode);
- }
- break;
- }
- case 20: { // Integer
- switch(subcode) {
- case 33: // CVT.D.W
- setDouble(fd,(double)f[fs]);
- break;
- default: throw new ExecutionException("Invalid Instruction 17/" + rs + "/" + subcode);
- }
- break;
- }
- default:
- throw new ExecutionException("Invalid Instruction 17/" + rs);
- }
- break;
- }
- case 18: case 19:
- throw new ExecutionException("No coprocessor installed");
- case 32: { // LB
- addr = r[rs] + signedImmediate;
- try {
- tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)];
- } catch(RuntimeException e) {
- tmp = memRead(addr&~3);
- }
- switch(addr&3) {
- case 0: tmp = (tmp>>>24)&0xff; break;
- case 1: tmp = (tmp>>>16)&0xff; break;
- case 2: tmp = (tmp>>> 8)&0xff; break;
- case 3: tmp = (tmp>>> 0)&0xff; break;
- }
- if((tmp&0x80)!=0) tmp |= 0xffffff00; // sign extend
- r[rt] = tmp;
- break;
- }
- case 33: { // LH
- addr = r[rs] + signedImmediate;
- try {
- tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)];
- } catch(RuntimeException e) {
- tmp = memRead(addr&~3);
- }
- switch(addr&2) {
- case 0: tmp = (tmp>>>16)&0xffff; break;
- case 2: tmp = (tmp>>> 0)&0xffff; break;
- }
- if((tmp&0x8000)!=0) tmp |= 0xffff0000; // sign extend
- r[rt] = tmp;
- break;
- }
- case 34: { // LWL;
- addr = r[rs] + signedImmediate;
- try {
- tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)];
- } catch(RuntimeException e) {
- tmp = memRead(addr&~3);
- }
- switch(addr&3) {
- case 0: r[rt] = (r[rt]&0x00000000)|(tmp<< 0); break;
- case 1: r[rt] = (r[rt]&0x000000ff)|(tmp<< 8); break;
- case 2: r[rt] = (r[rt]&0x0000ffff)|(tmp<<16); break;
- case 3: r[rt] = (r[rt]&0x00ffffff)|(tmp<<24); break;
- }
- break;
- }
- case 35: // LW
- addr = r[rs] + signedImmediate;
- try {
- r[rt] = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)];
- } catch(RuntimeException e) {
- r[rt] = memRead(addr);
- }
- break;
- case 36: { // LBU
- addr = r[rs] + signedImmediate;
- try {
- tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)];
- } catch(RuntimeException e) {
- tmp = memRead(addr);
- }
- switch(addr&3) {
- case 0: r[rt] = (tmp>>>24)&0xff; break;
- case 1: r[rt] = (tmp>>>16)&0xff; break;
- case 2: r[rt] = (tmp>>> 8)&0xff; break;
- case 3: r[rt] = (tmp>>> 0)&0xff; break;
- }
- break;
- }
- case 37: { // LHU
- addr = r[rs] + signedImmediate;
- try {
- tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)];
- } catch(RuntimeException e) {
- tmp = memRead(addr&~3);
- }
- switch(addr&2) {
- case 0: r[rt] = (tmp>>>16)&0xffff; break;
- case 2: r[rt] = (tmp>>> 0)&0xffff; break;
- }
- break;
- }
- case 38: { // LWR
- addr = r[rs] + signedImmediate;
- try {
- tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)];
- } catch(RuntimeException e) {
- tmp = memRead(addr&~3);
- }
- switch(addr&3) {
- case 0: r[rt] = (r[rt]&0xffffff00)|(tmp>>>24); break;
- case 1: r[rt] = (r[rt]&0xffff0000)|(tmp>>>16); break;
- case 2: r[rt] = (r[rt]&0xff000000)|(tmp>>> 8); break;
- case 3: r[rt] = (r[rt]&0x00000000)|(tmp>>> 0); break;
- }
- break;
- }
- case 40: { // SB
- addr = r[rs] + signedImmediate;
- try {
- tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)];
- } catch(RuntimeException e) {
- tmp = memRead(addr&~3);
- }
- switch(addr&3) {
- case 0: tmp = (tmp&0x00ffffff) | ((r[rt]&0xff)<<24); break;
- case 1: tmp = (tmp&0xff00ffff) | ((r[rt]&0xff)<<16); break;
- case 2: tmp = (tmp&0xffff00ff) | ((r[rt]&0xff)<< 8); break;
- case 3: tmp = (tmp&0xffffff00) | ((r[rt]&0xff)<< 0); break;
- }
- try {
- writePages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)] = tmp;
- } catch(RuntimeException e) {
- memWrite(addr&~3,tmp);
- }
- break;
- }
- case 41: { // SH
- addr = r[rs] + signedImmediate;
- try {
- tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)];
- } catch(RuntimeException e) {
- tmp = memRead(addr&~3);
- }
- switch(addr&2) {
- case 0: tmp = (tmp&0x0000ffff) | ((r[rt]&0xffff)<<16); break;
- case 2: tmp = (tmp&0xffff0000) | ((r[rt]&0xffff)<< 0); break;
- }
- try {
- writePages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)] = tmp;
- } catch(RuntimeException e) {
- memWrite(addr&~3,tmp);
- }
- break;
- }
- case 42: { // SWL
- addr = r[rs] + signedImmediate;
- tmp = memRead(addr&~3);
- switch(addr&3) {
- case 0: tmp=(tmp&0x00000000)|(r[rt]>>> 0); break;
- case 1: tmp=(tmp&0xff000000)|(r[rt]>>> 8); break;
- case 2: tmp=(tmp&0xffff0000)|(r[rt]>>>16); break;
- case 3: tmp=(tmp&0xffffff00)|(r[rt]>>>24); break;
- }
- try {
- writePages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)] = tmp;
- } catch(RuntimeException e) {
- memWrite(addr&~3,tmp);
- }
- break;
- }
- case 43: // SW
- addr = r[rs] + signedImmediate;
- try {
- writePages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)] = r[rt];
- } catch(RuntimeException e) {
- memWrite(addr&~3,r[rt]);
- }
- break;
- case 46: { // SWR
- addr = r[rs] + signedImmediate;
- tmp = memRead(addr&~3);
- switch(addr&3) {
- case 0: tmp=(tmp&0x00ffffff)|(r[rt]<<24); break;
- case 1: tmp=(tmp&0x0000ffff)|(r[rt]<<16); break;
- case 2: tmp=(tmp&0x000000ff)|(r[rt]<< 8); break;
- case 3: tmp=(tmp&0x00000000)|(r[rt]<< 0); break;
- }
- memWrite(addr&~3,tmp);
- break;
- }
- case 49: // LWC1
- f[rt] = memRead(r[rs] + signedImmediate);
- break;
- case 57: // SWC1
- memWrite(r[rs] + signedImmediate,f[rt]);
- break;
- default:
- throw new ExecutionException("Invalid Instruction: " + op);
- }
- pc = nextPC;
- nextPC = pc + 4;
- } // for(;;)
- } catch(ExecutionException e) {
- this.nextPC = pc;
- throw e;
- }
- return 0;
- }
-
- // Image loading function
- void loadImage(Object file) throws IOException {
- ELF elf = new ELF(file);
- if(elf.header.type != ELF.ELFHeader.ET_EXEC)
- throw new IOException("Binary is not an executable");
- if(elf.header.machine != ELF.ELFHeader.EM_MIPS)
- throw new IOException("Binary is not for the MIPS I Architecture");
- entryPoint = elf.header.entry;
- ELF.PHeader[] pheaders = elf.pheaders;
- brk = 0;
- for(int i=0;i<pheaders.length;i++) {
- ELF.PHeader ph = pheaders[i];
- if(ph.type != ELF.PHeader.PT_LOAD) continue;
- int memsize = ph.memsz;
- int filesize = ph.filesz;
- if(memsize == 0) continue;
- if(memsize < 0) throw new IOException("pheader size too large");
- int addr = ph.vaddr;
- if(addr == 0x0) throw new IOException("pheader vaddr == 0x0");
- if(addr+memsize >= (brk<<PAGE_SHIFT)) brk = (addr+memsize+PAGE_SIZE-1) >> PAGE_SHIFT;
-
- for(int j=0;j<memsize+PAGE_SIZE-1;j+=PAGE_SIZE) {
- int page = (j+addr) >>> PAGE_SHIFT;
- if(readPages[page] == null)
- readPages[page] = new int[PAGE_WORDS];
- if(ph.writable()) writePages[page] = readPages[page];
- }
- if(filesize != 0) {
- filesize = filesize & ~3;
- DataInputStream dis = new DataInputStream(ph.getInputStream());
- do {
- readPages[addr >>> PAGE_SHIFT][(addr >>> 2)&(PAGE_WORDS-1)] = dis.readInt();
- addr+=4;
- filesize-=4;
- } while(filesize > 0);
- dis.close();
- }
- }
- state = INITIALIZED;
- }
-
- protected void _start(int pc) {
- registers[K0] = STUFF_BASE;
- registers[K1] = PAGE_SIZE;
- registers[SP] = INITIAL_SP;
- registers[RA] = 0xdeadbeef;
- nextPC = pc;
- }
- public Interpreter() { super(true); /* allow empty pages */ }
- public Interpreter(String filename) throws IOException { loadImage(filename); }
- public Interpreter(byte[] bytes) throws IOException { loadImage(bytes); }
-
- public class DebugShutdownHook implements Runnable {
- public void run() {
- int pc = nextPC;
- if(getState() == RUNNING)
- System.err.print("\nCPU Executing " + toHex(pc) + "\n");
- }
- }
-
- public static void main(String[] argv) throws Exception {
- String image = argv[0];
- Interpreter emu = new Interpreter();
- emu.loadImage(image);
- java.lang.Runtime.getRuntime().addShutdownHook(new Thread(emu.new DebugShutdownHook()));
- // User data
- int addr = emu.sbrk(PAGE_SIZE);
- for(int i=0;i<10;i++) {
- String s = "User Info item: " + (i+1) + "\0";
- byte[] b = s.getBytes("US-ASCII");
- emu.copyout(b,addr,b.length);
- emu.setUserInfo(i,addr);
- addr += b.length;
- }
- // End user data
- int status = emu.run(argv);
- System.err.println("Exit status: " + status);
- System.exit(status);
- }
-}