1 package com.tapina.robe.runtime;
2
3 import java.lang.reflect.Method;
4 import java.lang.reflect.InvocationTargetException;
5 import java.util.Map;
6 import java.util.HashMap;
7
8 import com.tapina.robe.swi.SWIHandler;
9 import com.tapina.robe.swi.SWIError;
10
11 /***
12 * Created by IntelliJ IDEA.
13 * User: gareth
14 * Date: Aug 21, 2003
15 * Time: 8:00:28 AM
16 */
17 public final class Environment {
18 private final CPU cpu;
19 private final MemoryMap memoryMap;
20
21 public Environment(int loadAddress, byte[] image) {
22 cpu = new CPU();
23 memoryMap = new MemoryMap(loadAddress, image);
24 }
25
26 public final CPU getCpu() {
27 return cpu;
28 }
29
30 public final MemoryMap getMemoryMap() {
31 return memoryMap;
32 }
33
34 private final Map swiHandlers = new HashMap(20);
35
36 private static final Class[] EMPTY_PARAM_TYPE = new Class[0];
37 private static final Object[] EMPTY_PARAM_LIST = new Object[0];
38
39 public final void dispatchSwi(Method method, boolean generateErrors) {
40 try {
41 final Class swiHandlerClass = method.getDeclaringClass();
42 SWIHandler swiHandler = (SWIHandler) swiHandlers.get(swiHandlerClass);
43 if (swiHandler == null) {
44 Method getInstanceMethod = swiHandlerClass.getMethod("getInstance", EMPTY_PARAM_TYPE);
45 swiHandler = (SWIHandler) getInstanceMethod.invoke(null, EMPTY_PARAM_LIST);
46 swiHandlers.put(swiHandlerClass, swiHandler);
47 }
48 method.invoke(swiHandler, new Object[] { this });
49 cpu.clearV();
50 } catch (InvocationTargetException e) {
51 final Throwable targetException = e.getTargetException();
52 if (generateErrors || !(targetException instanceof SWIError)) {
53 throw new RuntimeException(targetException);
54 } else {
55 if (((SWIError) targetException).getErrorBlock() != 0) {
56 cpu.R[0] = ((SWIError) targetException).getErrorBlock();
57 } else {
58 returnError(targetException);
59 }
60 cpu.setV();
61 }
62 } catch (RuntimeException e) {
63 throw e;
64 } catch (Exception e) {
65 throw new RuntimeException(e);
66 }
67 }
68
69 /***
70 * Turn the exception given into an error block and return it in R[0].
71 * @param targetException
72 */
73 public void returnError(final Throwable targetException) {
74 final String message = targetException.getMessage();
75 RawDataBlock errorBlock = memoryMap.createErrorBlock(4 + message.length() + 1);
76 if (targetException instanceof SWIError) {
77 ByteArrayUtils.putInt(errorBlock.getBytes(), 0, ((SWIError) targetException).getErrorNumber());
78 } else {
79 ByteArrayUtils.putInt(errorBlock.getBytes(), 0, 0);
80 }
81 ByteArrayUtils.putString0(errorBlock.getBytes(), 4, message);
82 cpu.R[0] = errorBlock.getAddress();
83 }
84 }