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", "", "", "",
42 "", "", "", "", "", "", "", "",
43 "", "", "", "", "", "", "", "",
44 "", "", "", "", "", "", "", "",
45 "", "", "", "", "", "", "", "",
46 "", "", "", "", "", "", "", "",
47 "", "", "", "", "", "", "", "",
48 "", "", "", "", "", "", "", ""
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
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
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);
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 }