View Javadoc

1   package com.tapina.robe.swi;
2   
3   import com.tapina.robe.runtime.Environment;
4   import com.tapina.robe.runtime.MemoryMap;
5   import com.tapina.robe.swi.clib.CLibrary;
6   import com.tapina.robe.swi.clib.Kernel;
7   import com.tapina.robe.swi.clib.Stub;
8   import com.tapina.robe.swi.clib.setjmp.SetJmp;
9   import com.tapina.robe.swi.clib.roslib.SWIX;
10  import com.tapina.robe.swi.clib.roslib.SWI;
11  import com.tapina.robe.swi.clib.signal.Signal;
12  import com.tapina.robe.swi.clib.stdio.*;
13  import com.tapina.robe.swi.clib.stdlib.*;
14  import com.tapina.robe.swi.clib.string.*;
15  
16  import java.lang.reflect.Method;
17  
18  /***
19   * Floating point emulator SWIs.
20   * Currently there are no floating point instructions available.
21   */
22  public class SharedCLibrary extends SWIHandler {
23      public static final int FILE_DESCRIPTOR_SIZE = 0x28;
24      private static SharedCLibrary ourInstance;
25  
26      public synchronized static SharedCLibrary getInstance() {
27          if (ourInstance == null) {
28              ourInstance = new SharedCLibrary();
29          }
30          return ourInstance;
31      }
32  
33      private SharedCLibrary() {
34      }
35  
36      public static int getBase() {
37          return 0x80680;
38      }
39  
40      private static final String[] methodNames = new String[]{
41          "LibInitAPCS_A", "LibInitAPCS_R", "LibInitModule", "LibInitAPCS_32", "LibInitModuleAPCS_32", "", "", "", // 0x80680
42          "", "", "", "", "", "", "", "", // 0x80688
43          "", "", "", "", "", "", "", "", // 0x80690
44          "", "", "", "", "", "", "", "", // 0x80698
45          "", "", "", "", "", "", "", "", // 0x806a0
46          "", "", "", "", "", "", "", "", // 0x806a8
47          "", "", "", "", "", "", "", "", // 0x806b0
48          "", "", "", "", "", "", "", ""  // 0x806b8
49      };
50  
51      public static Method getMethod(Integer offset) throws NoSuchMethodException {
52          return getMethod(methodNames[offset.intValue()]);
53      }
54  
55      private static final Method getMethod(String name) throws NoSuchMethodException {
56          return SharedCLibrary.class.getMethod(name, METHOD_PARAMETERS);
57      }
58  
59      /***
60       * Initialise the Shared C Library stubs.
61       * @param env IN: R0 points to list of stub chunks; OUT: R0 = R2, R2 = R1 + (R6 >> 16), R6 = 6
62       * <pre>
63       *  0: Chunk ID (0 = kernel, 1 = C library, -1 = end of list)
64       *  4: Pointer to start of stub list
65       *  8: Pointer to end of stub list
66       *  12: Pointer to workspace for statics (C library only)
67       *  16: reserved
68       * </pre>
69       * The static workspace contains:
70       * <pre>
71       *  0x000: errno
72       *  0x004: stdin
73       *  0x02c: stdout
74       *  0x054: stderr
75       *  0x290: ctype
76       * </pre>
77       * A RISC OS file record looks like:
78       * <pre>
79       * {
80       *  WORD __ptr;
81       *  WORD __icnt;
82       *  WORD __ocnt;
83       *  WORD __flag;
84       *  WORD __base;
85       *  WORD __file;
86       *  WORD __pos;
87       *  WORD __bufsiz;
88       *  WORD __signature;
89       *  FILE *real;
90       * }
91       * </pre>
92       * The stub list is a set of instructions which implement the desired function.
93       */
94      public void LibInitAPCS_R(Environment env) {
95          final int[] R = env.getCpu().R;
96          final MemoryMap memoryMap = env.getMemoryMap();
97          for (int address = R[0]; ; address += 20) {
98              final int chunkId = memoryMap.getWord(address);
99              final int stubAddress = memoryMap.getWord(address + 4);
100             final int stubEndAddress = memoryMap.getWord(address + 8);
101             final int maxStubs = (stubEndAddress - stubAddress) / 4;
102             if (chunkId == -1) break;
103             final Stub[] stubs = libInitAPCS_R(chunkId);
104             for (int i = 0; i < stubs.length && i < maxStubs; i++) {
105                 Stub stub = stubs[i];
106                 stub.setAddress(stubAddress + (i * 4));
107                 memoryMap.addEntryPoint(stub);
108             }
109             // Add code for the unimplemented stubs and see what happens.
110             for (int i = stubs.length; i < maxStubs; i++) {
111                 Stub stub = chunkId == 1? kernel.dummy(i) : clib.dummy(i);
112                 stub.setAddress(stubAddress + (i * 4));
113                 memoryMap.addEntryPoint(stub);
114             }
115             if (chunkId == 2) {
116                 // Populate statics too
117                 final int staticAddress = memoryMap.getWord(address + 12);
118                 memoryMap.storeWord(staticAddress + 4, FilePointer.stdin.getHandle());
119                 memoryMap.storeWord(staticAddress + 4 + FILE_DESCRIPTOR_SIZE, FilePointer.stdout.getHandle());
120                 memoryMap.storeWord(staticAddress + 4 + (FILE_DESCRIPTOR_SIZE * 2), FilePointer.stderr.getHandle());
121             }
122         }
123         R[0] = R[2];
124         R[2] = R[1] + (R[6] >> 16); // Do not understand this one.
125         R[6] = 6;
126     }
127 
128     public final void LibInitAPCS_32(Environment env) {
129         LibInitAPCS_R(env);
130     }
131 
132     private final Kernel kernel = Kernel.getInstance();
133     private final CLibrary clib = CLibrary.getInstance();
134 
135     private final Stub[] KERNEL_STUBS = new Stub[] {
136         kernel.init(), kernel.exit(), kernel.setreturncode(), kernel.dummy(3), kernel.dummy(4),
137         kernel.dummy(5), kernel.dummy(6), kernel.commandString(), kernel.dummy(8), kernel.swi(),
138         kernel.osbyte(), kernel.os_get(), kernel.dummy(0x0c), kernel.dummy(0x0d), kernel.dummy(0x0e),
139         kernel.dummy(0x0f), kernel.dummy(0x10), kernel.dummy(0x11), kernel.dummy(0x12), kernel.dummy(0x13),
140         kernel.dummy(0x14), kernel.dummy(0x15), kernel.dummy(0x16), kernel.dummy(0x17), kernel.dummy(0x18),
141         kernel.dummy(0x19), kernel.dummy(0x1a), kernel.dummy(0x1b), kernel.dummy(0x1c), kernel.dummy(0x1d),
142         kernel.dummy(0x1e), kernel.dummy(0x1f), kernel.dummy(0x20), kernel.dummy(0x21), kernel.dummy(0x22),
143         kernel.dummy(0x23), kernel.dummy(0x24), kernel.fpavailable(), kernel.dummy(0x26), kernel.dummy(0x27),
144         kernel.dummy(0x28), kernel.dummy(0x29), kernel.dummy(0x2a), kernel.dummy(0x2b), kernel.dummy(0x2c),
145         kernel.dummy(0x2d), kernel.dummy(0x2e), kernel.dummy(0x2f)
146     };
147 
148     private final Stub[] CLIB_STUBS = new Stub[] {
149         clib.traphandler(), clib.dummy(1), clib.dummy(2), clib.dummy(3), clib.dummy(4), clib.dummy(5),
150         clib.xdudivide(), clib.xduremainder(), clib.xddivide(), clib.dummy(9), clib.xdremainder(), clib.dummy(0x0b),
151         clib.dummy(0x0c), clib.dummy(0x0d), clib.dummy(0x0e), clib.dummy(0x0f), clib.dummy(0x10), clib.dummy(0x11),
152         clib.main(), clib.dummy(0x13), clib.initialise(), clib.dummy(0x15), clib.dummy(0x16),
153         clib.dummy(0x17), clib.dummy(0x18), clib.dummy(0x19), new PrintF(), new FPrintF(), new SPrintF(),
154         clib.dummy(0x1d), clib.dummy(0x1e), clib.dummy(0x1f), clib.dummy(0x20), clib.dummy(0x21), clib.dummy(0x22),
155         clib.dummy(0x23), clib.dummy(0x24), clib.dummy(0x25), new MemCpy(), new MemMove(), new StrCpy(),
156         new StrNCpy(), new StrCat(), new StrNCat(), new MemCmp(), new StrCmp(), new StrNCmp(),
157         new MemChr(), new StrChr(), clib.dummy(0x31), clib.dummy(0x32), clib.dummy(0x33), clib.dummy(0x34),
158         clib.dummy(0x35), clib.dummy(0x36), new MemSet(), clib.dummy(0x38), new StrLen(), clib.dummy(0x3a),
159         new AToI(), clib.dummy(0x3c), clib.dummy(0x3d), clib.dummy(0x3e), clib.strtoul(), new Rand(clib.random),
160         new SRand(clib.random), new CAlloc(), new Free(), new Malloc(), new ReAlloc(), clib.dummy(0x46),
161         new AtExit(), new Exit(), new GetEnv(), clib.dummy(0x4a), clib.dummy(0x4b), new QSort(),
162         clib.dummy(0x4d), clib.dummy(0x4e), clib.dummy(0x4f), clib.dummy(0x50), new Remove(), clib.dummy(0x52),
163         clib.dummy(0x53), clib.dummy(0x54), new FClose(), new FFlush(), new FOpen(), clib.dummy(0x58),
164         clib.dummy(0x59), clib.dummy(0x5a), new PrintF(), new FPrintF(), new SPrintF(), clib.dummy(0x5e),
165         new FScanF(), new SScanF(), clib.dummy(0x61), clib.dummy(0x62), new VSPrintF(), clib.dummy(0x64),
166         new FGetC(), new FGetS(), new FPutC(), new FPutS(), clib.dummy(0x69), new GetC(),
167         clib.dummy(0x6b), clib.dummy(0x6c), new __FlsBuf(), new PutC(), new PutChar(), new PutS(),
168         clib.dummy(0x71), new FRead(), new FWrite(), clib.dummy(0x74), new FSeek(), clib.dummy(0x76),
169         new FTell(), new Rewind(), clib.dummy(0x79), new FEof(), clib.dummy(0x7b), clib.dummy(0x7c), clib.dummy(0x7d), clib.dummy(0x7e),
170         clib.dummy(0x7f), new Signal(), clib.dummy(0x81), new SetJmp(), clib.dummy(0x83), clib.dummy(0x84),
171         clib.dummy(0x85), clib.dummy(0x86), clib.dummy(0x87), clib.dummy(0x88), clib.dummy(0x89), clib.dummy(0x8a),
172         clib.dummy(0x8b), clib.dummy(0x8c), clib.dummy(0x8d), clib.dummy(0x8e), clib.dummy(0x8f), clib.dummy(0x90),
173         clib.dummy(0x91), clib.dummy(0x92), clib.dummy(0x93), clib.dummy(0x94), clib.dummy(0x95), clib.dummy(0x96),
174         clib.dummy(0x97), clib.dummy(0x98), clib.dummy(0x99), clib.dummy(0x9a), clib.dummy(0x9b), clib.dummy(0x9c),
175         clib.dummy(0x9d), clib.dummy(0x9e), clib.dummy(0x9f), clib.dummy(0xa0), clib.dummy(0xa1), clib.dummy(0xa2),
176         clib.dummy(0xa3), clib.dummy(0xa4), clib.dummy(0xa5), clib.dummy(0xa6), clib.dummy(0xa7), clib.dummy(0xa8),
177         clib.dummy(0xa9), clib.dummy(0xaa), clib.dummy(0xab), clib.dummy(0xac), clib.dummy(0xad), clib.dummy(0xae),
178         clib.dummy(0xaf), clib.dummy(0xb0), clib.dummy(0xb1), clib.dummy(0xb2), clib.dummy(0xb3), clib.dummy(0xb4),
179         clib.dummy(0xb5), new TmpNam(), new SWI(), new SWIX()
180     };
181 
182     private final Stub[][] STUB_CHUNKS = new Stub[][] {
183         KERNEL_STUBS, CLIB_STUBS
184     };
185 
186     public Stub[] libInitAPCS_R(int chunkId) {
187         return STUB_CHUNKS[chunkId - 1];
188     }
189 }