1 /***
2 * Created by IntelliJ IDEA.
3 * User: gareth
4 * Date: Sep 10, 2003
5 * Time: 10:58:14 AM
6 */
7 package com.tapina.robe.swi;
8
9 import com.tapina.robe.runtime.*;
10 import com.tapina.robe.runtime.instruction.SWI;
11 import com.tapina.robe.swi.os.Handler;
12 import com.tapina.robe.swi.os.MemMapInfo;
13 import com.tapina.robe.swi.os.PlatformFeatures;
14 import sun.misc.CRC16;
15
16 import java.lang.reflect.Method;
17 import java.util.Date;
18
19 public final class OSExt extends SWIHandler {
20 private static OSExt ourInstance;
21
22 public synchronized static OSExt getInstance() {
23 if (ourInstance == null) {
24 ourInstance = new OSExt();
25 }
26 return ourInstance;
27 }
28
29 private OSExt() {
30 }
31
32 public static int getBase() {
33 return 0x40;
34 }
35
36 private static final String[] methodNames = new String[] {
37 "ChangeEnvironment", "", "ReadMonotonicTime", "", "", "", "", "",
38 "WriteEnv", "", "", "", "", "", "", "",
39 "", "ReadMemMapInfo", "", "", "", "", "", "",
40 "", "", "", "CRC", "", "", "", "",
41 "", "", "", "", "", "ScreenMode", "DynamicArea", "",
42 "", "", "", "", "", "PlatformFeatures", "", "",
43 "", "CallASWIR12", "", "", "", "", "", "",
44 "", "", "", "", "", "", "", ""
45 };
46
47 public static Method getMethod(Integer offset) throws NoSuchMethodException {
48 return getMethod(methodNames[offset.intValue()]);
49 }
50
51 private static final Method getMethod(String name) throws NoSuchMethodException {
52 return OSExt.class.getMethod(name, METHOD_PARAMETERS);
53 }
54
55 public final void ChangeEnvironment(Environment env) {
56 final int R[] = env.getCpu().R;
57 Handler oldHandler = getEnvironmentHandler(R[0]);
58 if (R[1] != 0 || R[3] != 0) {
59 log.warning("We do not support changing the environment in OS.ChangeEnvironment");
60 }
61 R[1] = oldHandler.getAddress();
62 R[2] = oldHandler.getR12();
63 R[3] = oldHandler.getBuffer();
64 }
65
66 static final Handler DEFAULT_APPSPACE_HANDLER = new Handler(OS.DEFAULT_RAM_LIMIT, 0, 0);
67
68 public final Handler getEnvironmentHandler(int handlerNumber) {
69 switch (handlerNumber) {
70 case 14:
71 return DEFAULT_APPSPACE_HANDLER;
72 default:
73 throw new SWIError(0, "Unknown OS.ChangeEnvironment " + handlerNumber);
74 }
75 }
76
77 /***
78 * Number of centi-seconds since last hard reset.
79 * @param env OUT: R0 = Number of centi-seconds since last hard reset.
80 */
81 public final void ReadMonotonicTime(Environment env) {
82 env.getCpu().R[0] = readMonotonicTime();
83 }
84
85 /***
86 * Number of centi-seconds since program start.
87 * @return Number of centi-seconds since program start.
88 */
89 public final int readMonotonicTime() {
90 return (int) ((System.currentTimeMillis() - OS.DEFAULT_APP_ENVIRONMENT.getStartTime().getTime()) / 10);
91 }
92
93 public final void WriteEnv(Environment env) {
94 final int R[] = env.getCpu().R;
95 String commandLine = env.getMemoryMap().getString0(R[0]);
96 long fiveByteTime = env.getMemoryMap().getWord(R[1]);
97 fiveByteTime |= ((long) env.getMemoryMap().getByte(R[1] + 4)) << 32;
98 Date startTime = OS.convertToDate(fiveByteTime);
99 writeEnv(commandLine, startTime);
100 }
101
102 public final void writeEnv(String commandLine, Date startTime) {
103 OS.DEFAULT_APP_ENVIRONMENT.setCommandLine(commandLine);
104 OS.DEFAULT_APP_ENVIRONMENT.setStartTime(startTime);
105 }
106
107 private final static MemMapInfo DEFAULT_MEM_MAP_INFO = new MemMapInfo(4096, 4096);
108
109 public final void ReadMemMapInfo(Environment env) {
110 final int[] R = env.getCpu().R;
111 MemMapInfo memMapInfo = readMemMapInfo();
112 R[0] = memMapInfo.getPageSize();
113 R[1] = memMapInfo.getNumberOfPages();
114 }
115
116 public final MemMapInfo readMemMapInfo() {
117 return DEFAULT_MEM_MAP_INFO;
118 }
119
120 public final void CRC(Environment env) {
121 final int[] R = env.getCpu().R;
122 final ByteArray data = env.getMemoryMap().getByteArray(R[1], R[2] - R[1], false);
123 if ((R[2] - R[1]) % R[3] != 0) {
124 throw new SWIError(0, "End address never reached using specified increment");
125 }
126 R[0] = crc((short) R[0], data, R[3]);
127 }
128
129 public final short crc(short crc, ByteArray data, int increment) {
130 CRC16 crc16 = new CRC16();
131 crc16.value = crc;
132 for (int i = 0; i < data.getLength(); i += increment) {
133 byte b = data.getByte(i);
134 crc16.update(b);
135 }
136 return (short) crc16.value;
137 }
138
139 /***
140 * This call is used to change or read the screen mode.
141 * See also Wimp_SetMode.
142 * @param env IN: R0 = reason code, other registers dependant on call.
143 */
144 public final void ScreenMode(Environment env) {
145 final int[] R = env.getCpu().R;
146 final int reasonCode = R[0];
147 switch (reasonCode) {
148 case 1:
149 R[1] = getScreenMode();
150 break;
151 default:
152 throw new SWIError(0, "Unknown OS.ScreenMode " + reasonCode);
153 }
154 }
155
156 public final int getScreenMode() {
157 log.warning("Always returns screen mode as Mode 21");
158 return 21;
159 }
160
161 public final void DynamicArea(Environment env) {
162 final int[] R = env.getCpu().R;
163 final MemoryMap memoryMap = env.getMemoryMap();
164 switch (R[0]) {
165 case 0:
166 DynamicArea newArea = memoryMap.createDynamicArea(R[2], R[5], R[6], R[7], memoryMap.getString0(R[8]),
167 R[4] & 3, R[4] & (~3));
168 R[1] = newArea.getAreaNumber();
169 R[3] = newArea.getBase();
170 R[5] = newArea.getMaximumSize();
171 break;
172 case 2:
173 final int areaNumber = R[1];
174 DynamicArea area = memoryMap.findDynamicArea(areaNumber);
175 R[2] = area.getSize();
176 R[3] = area.getAddress();
177 R[4] = area.getFlags();
178 R[5] = area.getMaximumSize();
179 R[6] = area.getHandlerRoutine();
180 R[7] = area.getHandlerWorkspace();
181 final String name = area.getName();
182 final RawDataBlock nameBlock = memoryMap.createSystemDataBlock(name);
183 R[8] = nameBlock.getAddress();
184 break;
185 default:
186 throw new SWIError(0, "We do not support OS.DynamicArea " + R[0]);
187 }
188 }
189
190 private final static PlatformFeatures DEFAULT_PLATFORM_FEATURES = new PlatformFeatures(
191 PlatformFeatures.CODE_SYNCHRONISATION_REQUIRED |
192 PlatformFeatures.PC_PLUS_8_STORED
193 );
194
195 public final void PlatformFeatures(Environment env) {
196 final int[] R = env.getCpu().R;
197 R[0] = getPlatformFeatures().getCodeFeatures();
198 }
199
200 public final PlatformFeatures getPlatformFeatures() {
201 return DEFAULT_PLATFORM_FEATURES;
202 }
203
204 public final void CallASWIR12(Environment env) {
205 try {
206 new SWI(Condition.AL, env.getCpu().R[12]).checkAndExecute(env);
207 } catch (UnknownSWIException e) {
208 throw new SWIError(0, e);
209 }
210 }
211 }
212