📄 jopsim.java
字号:
/*** JopSim.java** Simulation of JOP JVM.** difference between JOP and JopSim:* loadBc (and invokestatic)** 2001-12-03 I don't need a fp!?*/package com.jopdesign.tools;import java.io.*;// uncomment for usage of the PCs com port//import javax.comm.CommPortIdentifier;//import javax.comm.SerialPort;//import javax.comm.UnsupportedCommOperationException;import com.jopdesign.sys.*;public class JopSim { static final int MAX_MEM = 1024*1024/4; static final int MAX_STACK = 256; // with internal memory static final int MIN_WB_ADDRESS = -128; static final int SYS_INT = 0xf0; int[] mem_load = new int[MAX_MEM]; int[] mem = new int[MAX_MEM]; int[] stack = new int[MAX_STACK]; Cache cache; int pc, cp, vp, sp, mp; int heap; int jjp; int jjhp; int moncnt; int empty_heap; static boolean log = false; static boolean useHandle = false; // // simulate timer interrupt // static int nextTimerInt; static boolean intPend; static boolean interrupt; static boolean intEna; // find JVM exit static String exitStr = "JVM exit!"; static char[] exitBuf = new char[exitStr.length()]; static boolean exit = false; static boolean stopped = false; // // only for statistics // int ioCnt; int[] bcStat = new int[256]; int rdMemCnt; int wrMemCnt; int maxInstr; int instrCnt; int maxSp; JopSim(String fn, int max) { maxInstr = max; init(fn); } JopSim(String fn) { this(fn, 0); } void init(String fn) { heap = 0; moncnt = 1; try { StreamTokenizer in = new StreamTokenizer(new FileReader(fn)); in.wordChars( '_', '_' ); in.wordChars( ':', ':' ); in.eolIsSignificant(true); in.slashStarComments(true); in.slashSlashComments(true); in.lowerCaseMode(true); while (in.nextToken()!=StreamTokenizer.TT_EOF) { if (in.ttype == StreamTokenizer.TT_NUMBER) { mem_load[heap++] = (int) in.nval; } } } catch (IOException e) { System.out.println(e.getMessage()); System.exit(-1); } int instr = mem_load[0]; System.out.println("Program: "+fn); System.out.println(instr + " instruction word ("+(instr*4/1024)+" KB)"); System.out.println(heap + " words mem read ("+(heap*4/1024)+" KB)"); empty_heap = heap; cache = new Cache(mem, this); } void start() { ioCnt = 0; rdMemCnt = 0; wrMemCnt = 0; instrCnt = 0; maxSp = 0; for (int i=0; i<256; ++i) bcStat[i] = 0; heap = empty_heap; for (int i=0; i<heap; ++i) mem[i] = mem_load[i]; moncnt = 1; nextTimerInt = 0; intPend = false; interrupt = false; intEna = false; pc = vp = 0; sp = 128; int ptr = readMem(1); jjp = readMem(ptr+1); jjhp = readMem(ptr+2); invokestatic(ptr); // load main() }/*** 'debug' functions.*/ void noim(int instr) { invoke(jjp+(instr<<1));/* System.out.println("byte code "+JopInstr.name(instr)+" ("+instr+") not implemented");System.out.println(mp+" "+pc); System.exit(-1);*/ }/*** call function in JVM.java with constant on stack*/ void jjvmConst(int instr) { int idx = readOpd16u(); int val = readMem(cp+idx); // read constant// System.out.println("jjvmConst: "+instr+" "+(cp+idx)+" "+val); stack[++sp] = val; // push on stack invoke(jjp+(instr<<1)); } void dump() { System.out.print("cp="+cp+" vp="+vp+" sp="+sp+" pc="+pc); System.out.println(" Stack=[..., "+stack[sp-2]+", "+stack[sp-1]+", "+stack[sp]+"]"); }/*** helper functions.*/ int readInstrMem(int addr) {// System.out.println(addr+" "+mem[addr]); ioCnt += 12; if (addr>MAX_MEM || addr<0) { System.out.println("readInstrMem: wrong address: "+addr); System.exit(-1); } return mem[addr]; } int readMem(int addr) {// System.out.println(addr+" "+mem[addr]); rdMemCnt++; ioCnt += 12; if (addr>MAX_MEM || addr<MIN_WB_ADDRESS) { System.out.println("readMem: wrong address: "+addr); System.exit(-1); } if (addr<0) { return 0; // no Simulation of the Wishbone devices } return mem[addr]; } void writeMem(int addr, int data) { wrMemCnt++; ioCnt += 12; if (addr>MAX_MEM || addr<MIN_WB_ADDRESS) { System.out.println("writeMem: wrong address: "+addr); System.exit(-1); } if (addr<0) { return; // no Simulation of the Wishbone devices } mem[addr] = data; } int readOpd16u() { int idx = ((cache.bc(pc)<<8) | (cache.bc(pc+1)&0x0ff)) & 0x0ffff; pc += 2; return idx; } int readOpd16s() { int i = readOpd16u(); if ((i&0x8000) != 0) { i |= 0xffff0000; } return i; } int readOpd8s() { return cache.bc(pc++); } int readOpd8u() { return cache.bc(pc++)&0x0ff; } int usCnt() { return ((int) System.currentTimeMillis())*1000; } // // Mapping of the second serial line to the PCs // com port. See ejip.MainSlipUart2 for an example. // Uncommented as javax.comm is NOT part of the standard // JDK - Blame Sun! // private String portName;// private CommPortIdentifier portId;// private InputStream is = null;// private OutputStream os = null;// private SerialPort serialPort;//// private void openSerialPort() {// try {// if (portId!=null) {// try {// is.close();// os.close();// is = null;// os = null;// } catch (Exception e1) {// }// serialPort.close();// }// portId = CommPortIdentifier.getPortIdentifier(portName);// serialPort = (SerialPort) portId.open(getClass().toString(), 2000);// serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_RTSCTS_OUT// | SerialPort.FLOWCONTROL_RTSCTS_IN);// serialPort.setSerialPortParams(115200,// SerialPort.DATABITS_8,// SerialPort.STOPBITS_1,// SerialPort.PARITY_NONE);// is = serialPort.getInputStream();// os = serialPort.getOutputStream();//System.out.println("open"+portName);// } catch (Exception e) {// is = null;// os = null;// System.out.println("Problem with serial port "+portName);// System.out.println(e.getMessage());// // System.exit(-1);// }// } void sysRd() { int addr = stack[sp]; int i; try { switch (addr) { case Const.IO_STATUS: stack[sp] = Const.MSK_UA_TDRE; if (System.in.available()!=0) { stack[sp] |= Const.MSK_UA_RDRF; } break; case Const.IO_STATUS2: i = 0;// if (is!=null) {// try {// if (is.available()!=0) {// i |= Const.MSK_UA_RDRF;// }// } catch (IOException e1) {// e1.printStackTrace();// } // rdrf// }// i |= Const.MSK_UA_TDRE; // tdre is alwais true on OutputStream stack[sp] = i; break; case Const.IO_UART: if (System.in.available()!=0) { stack[sp] = System.in.read(); } else { stack[sp] = '_'; } break; case Const.IO_UART2: i=0;// try {// i = is.read();// } catch (IOException e) {// e.printStackTrace();// } stack[sp] = i; break; case Const.IO_CNT: stack[sp] = ioCnt; break; case Const.IO_US_CNT: stack[sp] = usCnt(); break; case 1234: // trigger cache debug output// cache.rawData();// cache.resetCnt(); break; default: stack[sp] = 0; } } catch (Exception e) { System.out.println(e); } } void sysWr() { int addr = stack[sp--]; int val = stack[sp--]; switch (addr) { case Const.IO_UART: if (log) System.out.print("\t->"); System.out.print((char) val); if (log) System.out.println("<-"); // check the output for JVM exit! for (int i=0; i<exitStr.length()-1; ++i) { exitBuf[i] = exitBuf[i+1]; } exitBuf[exitBuf.length-1] = (char) val; if (new String(exitBuf).equals(exitStr)) { exit = true; } break; case Const.IO_UART2:// if (os==null) return;// try {// os.write(val&0xff);// } catch (IOException e) {// e.printStackTrace();// } break; case Const.IO_STATUS2:// if (serialPort!=null) {// serialPort.setDTR(val==1);// try {// if ((val&0x04)==0) {// serialPort.setSerialPortParams(2400,// SerialPort.DATABITS_8,// SerialPort.STOPBITS_1,// SerialPort.PARITY_NONE);// } else {// serialPort.setSerialPortParams(115200,// SerialPort.DATABITS_8,// SerialPort.STOPBITS_1,// SerialPort.PARITY_NONE);// }// if ((val&0x02)==0) {// serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);// } else {// serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_RTSCTS_OUT// | SerialPort.FLOWCONTROL_RTSCTS_IN);// }// } catch (UnsupportedCommOperationException e1) {// e1.printStackTrace();// }// } break; case Const.IO_INT_ENA: intEna = (val==0) ? false : true; break; case Const.IO_TIMER: intPend = false; // reset pending interrupt interrupt = false; // for shure ??? nextTimerInt = val; break; case Const.IO_SWINT: if (!intPend) { interrupt = true; intPend = true; } break; default: } }//// start of JVM :-)// void invokespecial() { invokestatic(); // what's the difference? } void invokevirtual() { int idx = readOpd16u(); int off = readMem(cp+idx); // index in vt and arg count (-1) int args = off & 0xff; // this is args count without obj-ref off >>>= 8; int ref = stack[sp-args]; if (useHandle) { // handle needs indirection ref = readMem(ref); } int vt = readMem(ref-1);// System.out.println("invvirt: off: "+off+" args: "+args+" ref: "+ref+" vt: "+vt+" addr: "+(vt+off)); invoke(vt+off); } void invokeinterface() { int idx = readOpd16u(); readOpd16u(); // read historical argument count and 0 int off = readMem(cp+idx); // index in interface table int args = off & 0xff; // this is args count without obj-ref off >>>= 8; int ref = stack[sp-args]; if (useHandle) { // handle needs indirection ref = readMem(ref); } int vt = readMem(ref-1); // pointer to virtual table in obj-1 int it = readMem(vt-1); // pointer to interface table one befor vt int mp = readMem(it+off);// System.out.println("invint: off: "+off+" args: "+args+" ref: "+ref+" vt: "+vt+" mp: "+(mp)); invoke(mp); }/*** invokestatic wie es in der JVM sein soll!!!*/ void invokestatic() { int idx = readOpd16u(); invokestatic(cp+idx); } void invokestatic(int ptr) { invoke(readMem(ptr)); }/*** do the real invoke. called with a pointer to method struct.*/ void invoke(int new_mp) { if (log) { System.out.println("addr. of meth.struct="+new_mp); } int old_vp = vp; int old_cp = cp; int old_mp = mp; mp = new_mp; int start = readMem(mp); int len = start & 0x03ff; start >>>= 10; cp = readMem(mp+1); int locals = (cp>>>5) & 0x01f; int args = cp & 0x01f; cp >>>= 10; int old_sp = sp-args; vp = old_sp+1; sp += locals;// System.out.println("inv: start: "+start+" len: "+len+" locals: "+locals+" args: "+args+" cp: "+cp); stack[++sp] = old_sp; stack[++sp] = cache.corrPc(pc); stack[++sp] = old_vp; stack[++sp] = old_cp; stack[++sp] = old_mp; pc = cache.invoke(start, len); }/*** return wie es sein sollte (oder doch nicht?)*/ void vreturn() { mp = stack[sp--]; cp = stack[sp--]; vp = stack[sp--]; pc = stack[sp--]; sp = stack[sp--]; int start = readMem(mp); int len = start & 0x03ff; start >>>= 10; // cp = readMem(mp+1)>>>10; pc = cache.ret(start, len, pc); } void ireturn() { int val = stack[sp--]; vreturn(); stack[++sp] = val; } void lreturn() { int val1 = stack[sp--]; int val2 = stack[sp--]; vreturn(); stack[++sp] = val2; stack[++sp] = val1; } void putstatic() { int idx = readOpd16u(); int addr = readMem(cp+idx); writeMem(addr, stack[sp--]); } void getstatic() { int idx = readOpd16u(); int addr = readMem(cp+idx); stack[++sp] = readMem(addr); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -