View Javadoc

1   package com.tapina.robe.swi.clib;
2   
3   import com.tapina.robe.runtime.*;
4   import com.tapina.robe.runtime.instruction.SWI;
5   import com.tapina.robe.swi.OS;
6   
7   import java.io.IOException;
8   
9   /***
10   * Class to hold the kernel stubs.
11   */
12  public class Kernel {
13      private final static Kernel ourInstance = new Kernel();
14      static final int STACK_SIZE = 65536;
15  
16      public static Kernel getInstance() {
17          return ourInstance;
18      }
19  
20      private Kernel() {
21      }
22  
23      public final Stub dummy(final int stubId) {
24          return new Stub() {
25              public void executeStub(Environment environment) {
26                  log.warning("Attempt to call unknown kernel shared library stub &" + Integer.toHexString(stubId));
27                  throw new UnknownSharedLibraryCall(1, stubId);
28              }
29          };
30      }
31  
32      public final Stub init() {
33          return new Stub() {
34              /***
35               * This taken from riscose:
36               * <pre>
37               *        WORD *kernel_init = (WORD*) MEM_TOHOST(ARM_R0);
38               * //WORD image_base   = kernel_init[0];
39               * WORD c = 0, limit = kernel_init[2] - kernel_init[1];
40               * WORD *language_description = (WORD*) MEM_TOHOST(kernel_init[1]);
41               * ARM_SET_R10(MMAP_USRSTACK_BASE+768);
42               * ARM_SET_R11(0);
43               * ARM_SET_R12(0);
44               * ARM_SET_R13(MMAP_USRSTACK_BASE+ MMAP_USRSTACK_SIZE);
45               * while (c != limit)
46               * {
47               *    if (language_description[c + 4] != 0) {
48               *        arm_run_routine(language_description[c + 4]);
49               *        arm_set_pc(ARM_R0);
50               *        return SWIH_EXIT_HANDLED; // BODGE!
51               *    }
52               *    c += language_description[c] >> 2;
53               *    printf("%li\n", c);
54               * }
55               * </pre>
56               */
57              public void execute(Environment environment) {
58                  // R0 points to (image base, language description base, language description top)
59                  // Set R10 to the base of the stack + 768
60                  // Set R11 to 0
61                  // Set R12 to 0
62                  // Set R13 to the top of the stack
63                  final MemoryMap memoryMap = environment.getMemoryMap();
64                  final int[] R = environment.getCpu().R;
65                  int imageBase = memoryMap.getWord(R[0]);
66                  int c = 0;
67                  int languageDescription = memoryMap.getWord(R[0] + 4);
68                  int limit = memoryMap.getWord(R[0] + 8) - languageDescription;
69  
70                  RawDataBlock stack = memoryMap.createSystemDataBlock(STACK_SIZE);
71                  R[10] = stack.getAddress() + 768;
72                  R[11] = R[12] = 0;
73                  R[13] = stack.getAddress() + stack.getSize();
74                  while (c != limit) {
75                      final int routineAddress = memoryMap.getWord(languageDescription + (c + 4) * 4);
76                      if (routineAddress != 0) {
77                          CodeBlock codeBlock = memoryMap.addEntryPoint(routineAddress);
78                          executeSubroutine(environment, codeBlock);
79                          environment.getCpu().setPC(R[0]);
80                          return;
81                      }
82                      c += memoryMap.getWord(languageDescription + c * 4) >> 2;
83                  }
84                  unwind(environment);
85              }
86  
87              public void executeStub(Environment environment) {
88              }
89          };
90      }
91  
92      public final Stub exit() {
93          return new Stub() {
94              public void executeStub(Environment environment) {
95                  System.exit(environment.getCpu().R[0]);
96              }
97          };
98      }
99  
100     public final Stub setreturncode() {
101         return new Stub() {
102             public void executeStub(Environment environment) {
103                 log.warning("setreturncode() not implemented");
104             }
105         };
106     }
107 
108     public Stub commandString() {
109         return new Stub() {
110             public void executeStub(Environment environment) {
111                 OS.getInstance().GetEnv(environment); // Corrupts R1 and R2 as well
112             }
113         };
114     }
115 
116     public Stub swi() {
117         return new Stub() {
118             public void executeStub(Environment environment) {
119                 final int[] R = environment.getCpu().R;
120                 final int swiNumber = R[0];
121                 final int[] R4to9save = new int[6];
122                 final int[] R0to9in = environment.getMemoryMap().getWords(R[1], 10);
123                 final int[] R0to9out = new int[10];
124                 final int outAddress = R[2];
125                 System.arraycopy(R, 4, R4to9save, 0, 6);
126                 System.arraycopy(R0to9in, 0, R, 0, 10);
127                 try {
128                     SWI swi = new SWI(Condition.AL, swiNumber);
129                     swi.checkAndExecute(environment);
130                     System.arraycopy(R, 0, R0to9out, 0, 10);
131                     environment.getMemoryMap().storeWords(outAddress, R0to9out);
132                     R[0] = 0;
133                 } catch (UnknownSWIException e) {
134                     environment.returnError(e);
135                 } finally {
136                     System.arraycopy(R4to9save, 0, R, 4,6);
137                 }
138             }
139         };
140     }
141 
142     public Stub os_get() {
143         return new Stub() {
144             public void executeStub(Environment environment) {
145                 try {
146                     environment.getCpu().R[0] = System.in.read();
147                 } catch (IOException e) {
148                     environment.getCpu().R[0] = 256;
149                 }
150             }
151         };
152     }
153 
154     /***
155      * This function calls the OS_Byte SWI with the register R0 set to the value passed in a1, and registers R1 and R2
156      * set to the values pointed to by a2 and a3.
157      * The int returned contains R1 in its bottom byte, R2 in the second byte, and 1 in the third byte if the carry
158      * flag is set.
159      * Returns: Values returned, or error as follows: (-1) Carry flag is set (call failed), (-2) OS error occurs.
160      * @return Stub implementing desired functionality
161      */
162     public Stub osbyte() {
163         return new Stub() {
164             public void executeStub(Environment environment) {
165                 final int[] R = environment.getCpu().R;
166                 try {
167                     final int[] result = OS.getInstance().osByte(R[0], R[1], R[2]);
168                     R[0] = result[0] | (result[1] << 8);
169                 } catch (Exception e) {
170                     R[0] = -2;
171                 }
172             }
173         };
174     }
175 
176     /***
177      * This function tests for the presence of either the floating point co-processor or the floating point emulator
178      * module (FPE).
179      * Returns: 0 if floating point is not available.
180      * @return Stub implementing desired functionality
181      */
182     public Stub fpavailable() {
183         return new Stub() {
184             public void executeStub(Environment environment) {
185                 environment.getCpu().R[0] = 0;
186                 log.warning("_kernel_fpavailable() returns 0, which is a lie");
187             }
188         };
189     }
190 }