View Javadoc

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  }