• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Commit MetaInfo

Revisióneefe55010f308d5c8a0604f069e2c96864339927 (tree)
Tiempo2014-05-29 02:29:20
Autorhikarupsp <hikarupsp@user...>
Commiterhikarupsp

Log Message

osecpu106a

Cambiar Resumen

Diferencia incremental

--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@
22 a.out
33 make_vm.bat
44 osecpu-test.exe
5+osecpu-test.bin
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,7 @@
11 CC = cc
2-SRCS = extend.c float.c integer.c osecpu-vm.c pointer.c test.c
2+SRCS = api.c driver.c extend.c float.c \
3+ integer.c osecpu-vm.c other.c pointer.c \
4+ test.c
35 BINNAME = osecpu-test.bin
46
57 $(BINNAME): $(SRCS)
--- /dev/null
+++ b/api.c
@@ -0,0 +1,76 @@
1+#include "osecpu-vm.h"
2+#include <setjmp.h>
3+
4+const Int32 *apiEntry(OsecpuVm *vm);
5+
6+/* driver.c */
7+void *mallocRWE(int bytes); // 実行権付きメモリのmalloc.
8+void drv_openWin(int x, int y, unsigned char *buf, char *winClosed);
9+void drv_flshWin(int sx, int sy, int x0, int y0);
10+void drv_sleep(int msec);
11+
12+void apiInit(OsecpuVm *vm)
13+{
14+ vm->p[0x28].typ = PTR_TYP_NATIVECODE;
15+ vm->p[0x28].p = (void *) &apiEntry;
16+ return;
17+}
18+
19+Int32 apiGetRxx(OsecpuVm *vm, int r, int bit);
20+
21+void api0001_putString(OsecpuVm *vm);
22+void api0002_drawPoint(OsecpuVm *vm);
23+void api0003_drawLine(OsecpuVm *vm);
24+void api0004_rect(OsecpuVm *vm);
25+void api0005_oval(OsecpuVm *vm);
26+void api0006_drawString(OsecpuVm *vm);
27+void api0008_exit(OsecpuVm *vm);
28+void api0009_sleep(OsecpuVm *vm);
29+
30+const Int32 *apiEntry(OsecpuVm *vm)
31+// VMの再開地点を返す.
32+{
33+ int func = apiGetRxx(vm, 0x30, 16);
34+ if (vm->errorCode != 0) goto fin;
35+ if (func == 0x0001) { api0001_putString(vm); goto fin; }
36+ if (func == 0x0002) { api0002_drawPoint(vm); goto fin; }
37+ if (func == 0x0003) { api0003_drawLine(vm); goto fin; }
38+ if (func == 0x0004) { api0004_rect(vm); goto fin; }
39+ if (func == 0x0005) { api0005_oval(vm); goto fin; }
40+ if (func == 0x0006) { api0006_drawString(vm); goto fin; }
41+ if (func == 0x0008) { api0008_exit(vm); goto fin; }
42+ if (func == 0x0009) { api0009_sleep(vm); goto fin; }
43+ jitcSetRetCode(&vm->errorCode, EXEC_API_ERROR);
44+fin: ;
45+ const Int32 *retcode = NULL;
46+ execStep_checkMemAccess(vm, 0x30, PTR_TYP_CODE, EXEC_CMA_FLAG_EXEC); // 主にliveSignのチェック.
47+ if (vm->errorCode == 0)
48+ retcode = (const Int32 *) vm->p[0x30].p;
49+ return retcode;
50+}
51+
52+Int32 apiGetRxx(OsecpuVm *vm, int r, int bit)
53+{
54+ Int32 i, value = vm->r[r];
55+ if (vm->bit[r] != BIT_DISABLE_REG && vm->bit[r] < bit)
56+ jitcSetRetCode(&vm->errorCode, EXEC_BAD_BITS);
57+ i = (-1) << bit;
58+ if ((value & (1 << (bit - 1))) == 0) {
59+ // 符号ビットが0だった.
60+ value &= ~i;
61+ } else {
62+ // 符号ビットが1だった.
63+ value |= i;
64+ }
65+ return value;
66+}
67+
68+void api0001_putString(OsecpuVm *vm) { }
69+void api0002_drawPoint(OsecpuVm *vm) { }
70+void api0003_drawLine(OsecpuVm *vm) { }
71+void api0004_rect(OsecpuVm *vm) { puts("api0004_rect"); }
72+void api0005_oval(OsecpuVm *vm) { }
73+void api0006_drawString(OsecpuVm *vm) { }
74+void api0008_exit(OsecpuVm *vm) { }
75+void api0009_sleep(OsecpuVm *vm) { }
76+
--- /dev/null
+++ b/bitmemo.txt
@@ -0,0 +1,56 @@
1+bit[]に関するメモ
2+
3+#1. 目的
4+整数演算に関するbitは、多倍長演算において、どの精度まで行えば結果が変わらないのかをVMに教えるための手段である。
5+したがって、bit=32であってもVMは64ビット演算をするかもしれないし、256ビット演算をするかもしれない。
6+しかしそれによって、最終的な結果が少しでも変わることは許さない。
7+この情報があればVM(特にJITコンパイラ)は、処理を高速化できる。
8+
9+#2. 注意すべき点
10+レジスタやメモリのbitの情報は、高速モードでは一切生成されない。参照もされない。
11+あるタスクがあって、それは最初安全モードで動作していたとする。それが一度高速モードに切り替わって、また安全モードに
12+戻ったとしても、結果は正しく得られなければならない。高速モード中に情報が失われているので、チェック能力が下がるのは
13+かまわない。
14+つまりbitに依存した動作をすることは許されない。
15+
16+#3. タスクセーブに関すること
17+タスクセーブでは、不定ビットは全て0か1に初期化される。と思ったが、これは必要ないかもしれない。
18+なぜなら高速モードではbitがないので、この不定ビットつぶしができない。つまり他のタスクからの情報が流出しうる。
19+となれば、やはり消すのは別のところでやるべきだ。malloc時に重要であると明示させるのがよさそう。
20+そうすればVMもしくはOSは、free時にゼロクリアできる。
21+同じ問題はレジスタでも起こり得る。だから重要な値を持つレジスタは明示的にデータを消さなければいけない。
22+その際には必要なビット幅でLIMMをするべき。その後にbit=0のLIMMをしてもしなくてもいい。
23+これは2度手間だけど、使用頻度を考えれば妥当。
24+
25+#4. VMは安全モードの場合は、不定ビットをレジスタ内に残さず、常に符号拡張した状態で処理する。
26+これは値の範囲チェックをするため。高速モードでは、不定ビットを残していてもよい。
27+タスクセーブ時には、不定ビットは殺してしまう。
28+しかしこの方法では、高速モードから安全モードに移行した際に問題にならないか?
29+高速モードではどこまでビットをつぶすべきか分かっていないのだから。
30+さてこまった。となると、高速モードから安全モードに戻せないとしたほうがいいのかもしれない。
31+もしくはbitに不明という状態を許すか?不明の間は、しょうがないのでチェックができない。
32+分かったらすぐにチェックをする。まあこれもありかもしれない。・・・よしこれにしよう。
33+
34+#5. LMEM
35+
36+
37+
38+#6. SMEM
39+(1)SINT32のメモリに対して、bit=16のデータを書き込むことは許される。
40+ その場合、メモリのbitは16になる。書いた値が読み出せるかどうかのチェックはない。
41+(2)UINT32のメモリに対して、bit=16のデータを書き込むことは許される。
42+ その場合、メモリのbitは16になる。書いた値が読み出せるかどうかのチェックは少しある。
43+ それはデータが負ではないこと。負はどうやっても読み出せないから。
44+dat.bit=min(reg.bit, SMEM.bit)
45+(3)typ.bit >= dat.bit は原則OK。ただし、符号のチェックはある。
46+ unsignedなtypで、reg<0ならダメ。
47+(4)typ.bit < dat.bit の場合は、値の範囲が妥当なら問題ない。範囲がまずければやはりエラーになる。
48+(5)2F-0がある場合は、ダメな場合でもメモリのbitが0になるだけで、アプリは例外を起こさずに続行できる。
49+ しかしそれでも符号のチェックはある。
50+(6)2F-0でUINT系を全部エラーにしてしまえばいいかとも思ったけど、レジスタの用法はわからないので、
51+ 将来のアプリに配慮した。
52+
53+#7. LMEM, SMEMのプリフィクス
54+2F-0: マスクリード、マスクライト。
55+2F-1: レジスタ退避用のリードライト。
56+2F-2: メモリのbitを0にする。
--- /dev/null
+++ b/driver.c
@@ -0,0 +1,526 @@
1+/* OS依存関数 */
2+void *mallocRWE(int bytes); // 実行権付きメモリのmalloc.
3+void drv_openWin(int x, int y, unsigned char *buf, char *winClosed);
4+void drv_flshWin(int sx, int sy, int x0, int y0);
5+void drv_sleep(int msec);
6+
7+#if (!defined(JITC_OSNUM))
8+ #if (defined(_WIN32))
9+ #define JITC_OSNUM 0x0001
10+ #endif
11+ #if (defined(__APPLE__))
12+ #define JITC_OSNUM 0x0002
13+ #endif
14+ #if (defined(__linux__))
15+ #define JITC_OSNUM 0x0003
16+ #endif
17+ /* 0001: win32-x86-32bit */
18+ /* 0002: MacOS-x86-32bit */
19+ /* 0003: linux-x86-32bit */
20+#endif
21+
22+/* OS依存部 */
23+
24+#if (DRV_OSNUM == 0x0001)
25+
26+#include <windows.h>
27+#include <setjmp.h>
28+
29+#define TIMER_ID 1
30+#define TIMER_INTERVAL 10
31+
32+struct BLD_WORK {
33+ HINSTANCE hi;
34+ HWND hw;
35+ BITMAPINFO bmi;
36+ int tmcount1, tmcount2, flags, smp; /* bit0: 終了 */
37+ HANDLE mtx;
38+ char *winClosed;
39+};
40+
41+struct BLD_WORK bld_work;
42+
43+struct BL_WIN {
44+ int xsiz, ysiz, *buf;
45+};
46+
47+struct BL_WORK {
48+ struct BL_WIN win;
49+ jmp_buf jb;
50+ int csiz_x, csiz_y, cx, cy, col0, col1, tabsiz, slctwin;
51+ int tmcount, tmcount0, mod, rand_seed;
52+ int *cbuf;
53+ unsigned char *ftyp;
54+ unsigned char **fptn;
55+ int *ccol, *cbak;
56+ int *kbuf, kbuf_rp, kbuf_wp, kbuf_c;
57+};
58+
59+struct BL_WORK bl_work;
60+
61+#define BL_SIZ_KBUF 8192
62+
63+#define BL_WAITKEYF 0x00000001
64+#define BL_WAITKEYNF 0x00000002
65+#define BL_WAITKEY 0x00000003
66+#define BL_GETKEY 0x00000004
67+#define BL_CLEARREP 0x00000008
68+#define BL_DELFFF 0x00000010
69+
70+#define BL_KEYMODE 0x00000000 // 作りかけ, make/remake/breakが見えるかどうか
71+
72+#define w bl_work
73+#define dw bld_work
74+
75+void bld_openWin(int x, int y, char *winClosed);
76+void bld_flshWin(int sx, int sy, int x0, int y0);
77+LRESULT CALLBACK WndProc(HWND hw, unsigned int msg, WPARAM wp, LPARAM lp);
78+void bl_cls();
79+int bl_iCol(int i);
80+void bl_readyWin(int n);
81+
82+static HANDLE threadhandle;
83+
84+int main(int argc, const UCHAR **argv)
85+{
86+ return OsecpuMain(argc, argv);
87+}
88+
89+void *mallocRWE(int bytes)
90+{
91+ void *p = malloc(bytes);
92+ DWORD dmy;
93+ VirtualProtect(p, bytes, PAGE_EXECUTE_READWRITE, &dmy);
94+ return p;
95+}
96+
97+static int winthread(void *dmy)
98+{
99+ WNDCLASSEX wc;
100+ RECT r;
101+ unsigned char *p, *p0, *p00;
102+ int i, x, y;
103+ MSG msg;
104+
105+ x = dw.bmi.bmiHeader.biWidth;
106+ y = - dw.bmi.bmiHeader.biHeight;
107+
108+ wc.cbSize = sizeof (WNDCLASSEX);
109+ wc.style = CS_HREDRAW | CS_VREDRAW;
110+ wc.lpfnWndProc = WndProc;
111+ wc.cbClsExtra = 0;
112+ wc.cbWndExtra = 0;
113+ wc.hInstance = dw.hi;
114+ wc.hIcon = (HICON) LoadImage(NULL, MAKEINTRESOURCE(IDI_APPLICATION),
115+ IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
116+ wc.hIconSm = wc.hIcon;
117+ wc.hCursor = (HCURSOR)LoadImage(NULL, MAKEINTRESOURCE(IDC_ARROW),
118+ IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
119+ wc.hbrBackground = (HBRUSH) COLOR_APPWORKSPACE;
120+ wc.lpszMenuName = NULL;
121+ wc.lpszClassName = "WinClass";
122+ if (RegisterClassEx(&wc) == 0)
123+ return 1;
124+ r.left = 0;
125+ r.top = 0;
126+ r.right = x;
127+ r.bottom = y;
128+ AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW, FALSE);
129+ x = r.right - r.left;
130+ y = r.bottom - r.top;
131+
132+#if 0
133+ static unsigned char t[32];
134+ p00 = p0 = p = GetCommandLineA();
135+ if (*p == 0x22) {
136+ p00 = p0 = ++p;
137+ while (*p != '\0' && *p != 0x22) {
138+ if (*p == '\\')
139+ p0 = p + 1;
140+ p++;
141+ }
142+ } else {
143+ while (*p > ' ') {
144+ if (*p == '\\')
145+ p0 = p + 1;
146+ p++;
147+ }
148+ }
149+ if (p - p0 > 4 && p[-4] == '.' && p[-3] == 'e' && p[-2] == 'x' && p[-1] == 'e')
150+ p -= 4;
151+ for (i = 0; i < 32 - 1; i++) {
152+ if (p <= &p0[i])
153+ break;
154+ t[i] = p0[i];
155+ }
156+ t[i] = '\0';
157+#endif
158+ char *t = "osecpu";
159+
160+ dw.hw = CreateWindowA(wc.lpszClassName, t, WS_OVERLAPPEDWINDOW,
161+ CW_USEDEFAULT, CW_USEDEFAULT, x, y, NULL, NULL, dw.hi, NULL);
162+ if (dw.hw == NULL)
163+ return 1;
164+ ShowWindow(dw.hw, SW_SHOW);
165+ UpdateWindow(dw.hw);
166+ SetTimer(dw.hw, TIMER_ID, TIMER_INTERVAL, NULL);
167+ SetTimer(dw.hw, TIMER_ID + 1, TIMER_INTERVAL * 10, NULL);
168+ SetTimer(dw.hw, TIMER_ID + 2, TIMER_INTERVAL * 100, NULL);
169+ dw.flags |= 2 | 4;
170+
171+ for (;;) {
172+ i = GetMessage(&msg, NULL, 0, 0);
173+ if (i == 0 || i == -1) /* エラーもしくは終了メッセージ */
174+ break;
175+ /* そのほかはとりあえずデフォルト処理で */
176+ TranslateMessage(&msg);
177+ DispatchMessage(&msg);
178+ }
179+// PostQuitMessage(0);
180+ dw.flags |= 1; /* 終了, bld_waitNF()が見つける */
181+ if (dw.winClosed != NULL)
182+ *dw.winClosed = 1;
183+ return 0;
184+}
185+
186+void bld_openWin(int sx, int sy, char *winClosed)
187+{
188+ static int i;
189+
190+ dw.bmi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
191+ dw.bmi.bmiHeader.biWidth = sx;
192+ dw.bmi.bmiHeader.biHeight = - sy;
193+ dw.bmi.bmiHeader.biPlanes = 1;
194+ dw.bmi.bmiHeader.biBitCount = 32;
195+ dw.bmi.bmiHeader.biCompression = BI_RGB;
196+ dw.winClosed = winClosed;
197+
198+ threadhandle = CreateThread(NULL, 0, (void *) &winthread, NULL, 0, (void *) &i);
199+
200+ return;
201+}
202+
203+void drv_flshWin(int sx, int sy, int x0, int y0)
204+{
205+ InvalidateRect(dw.hw, NULL, FALSE);
206+ UpdateWindow(dw.hw);
207+ return;
208+}
209+
210+LRESULT CALLBACK WndProc(HWND hw, unsigned int msg, WPARAM wp, LPARAM lp)
211+{
212+ int i, j;
213+ if (msg == WM_PAINT) {
214+ PAINTSTRUCT ps;
215+ HDC hdc = BeginPaint(dw.hw, &ps);
216+ SetDIBitsToDevice(hdc, 0, 0, w.win.xsiz, w.win.ysiz,
217+ 0, 0, 0, w.win.ysiz, w.win.buf, &dw.bmi, DIB_RGB_COLORS);
218+ EndPaint(dw.hw, &ps);
219+ }
220+ if (msg == WM_DESTROY) {
221+ PostQuitMessage(0);
222+ return 0;
223+ }
224+ if (msg == WM_TIMER && wp == TIMER_ID) {
225+ w.tmcount += TIMER_INTERVAL;
226+ return 0;
227+ }
228+ if (msg == WM_TIMER && wp == TIMER_ID + 1) {
229+ dw.tmcount1 += TIMER_INTERVAL * 10;
230+ w.tmcount = dw.tmcount1;
231+ return 0;
232+ }
233+ if (msg == WM_TIMER && wp == TIMER_ID + 2) {
234+ dw.tmcount2 += TIMER_INTERVAL * 100;
235+ w.tmcount = dw.tmcount1 = dw.tmcount2;
236+ return 0;
237+ }
238+ if (msg == WM_KEYDOWN || msg == WM_SYSKEYDOWN) {
239+ i = -1;
240+#if 0
241+ int s_sht = GetKeyState(VK_SHIFT);
242+ int s_ctl = GetKeyState(VK_CONTROL);
243+ int s_cap = GetKeyState(VK_CAPITAL);
244+ int s_num = GetKeyState(VK_NUMLOCK);
245+ if ('A' <= wp && wp <= 'Z') {
246+ i = wp;
247+ if (((s_sht < 0) ^ (s_cap & 1)) == 0)
248+ i += 'a' - 'A';
249+ }
250+ if (wp == VK_SPACE) i = ' ';
251+#endif
252+ if (wp == VK_RETURN) i = KEY_ENTER;
253+ if (wp == VK_ESCAPE) i = KEY_ESC;
254+ if (wp == VK_BACK) i = KEY_BACKSPACE;
255+ if (wp == VK_TAB) i = KEY_TAB;
256+ if (wp == VK_PRIOR) i = KEY_PAGEUP;
257+ if (wp == VK_NEXT) i = KEY_PAGEDWN;
258+ if (wp == VK_END) i = KEY_END;
259+ if (wp == VK_HOME) i = KEY_HOME;
260+ if (wp == VK_LEFT) i = KEY_LEFT;
261+ if (wp == VK_RIGHT) i = KEY_RIGHT;
262+ if (wp == VK_UP) i = KEY_UP;
263+ if (wp == VK_DOWN) i = KEY_DOWN;
264+ if (wp == VK_INSERT) i = KEY_INS;
265+ if (wp == VK_DELETE) i = KEY_DEL;
266+ j &= 0;
267+ if ((GetKeyState(VK_LCONTROL) & (1 << 15)) != 0) j |= 1 << 17;
268+ if ((GetKeyState(VK_LMENU) & (1 << 15)) != 0) j |= 1 << 18;
269+ if ((GetKeyState(VK_RCONTROL) & (1 << 15)) != 0) j |= 1 << 25;
270+ if ((GetKeyState(VK_RMENU) & (1 << 15)) != 0) j |= 1 << 26;
271+ if ((GetKeyState(VK_RSHIFT) & (1 << 15)) != 0) i |= 1 << 24;
272+ if ((GetKeyState(VK_LSHIFT) & (1 << 15)) != 0) i |= 1 << 16;
273+ if ((GetKeyState(VK_NUMLOCK) & (1 << 0)) != 0) i |= 1 << 22;
274+ if ((GetKeyState(VK_CAPITAL) & (1 << 0)) != 0) i |= 1 << 23;
275+ if (j != 0) {
276+ if ('A' <= wp && wp <= 'Z') i = wp;
277+ }
278+ if (i != -1) {
279+ putKeybuf(i | j);
280+// bl_putKeyB(1, &i);
281+ return 0;
282+ }
283+ }
284+ if (msg == WM_KEYUP) {
285+ i = 0xfff;
286+// bl_putKeyB(1, &i);
287+ }
288+ if (msg == WM_CHAR) {
289+ i = 0;
290+ if (' ' <= wp && wp <= 0x7e) {
291+ i = wp;
292+ j &= 0;
293+ if ((GetKeyState(VK_LCONTROL) & (1 << 15)) != 0) j |= 1 << 17;
294+ if ((GetKeyState(VK_LMENU) & (1 << 15)) != 0) j |= 1 << 18;
295+ if ((GetKeyState(VK_RCONTROL) & (1 << 15)) != 0) j |= 1 << 25;
296+ if ((GetKeyState(VK_RMENU) & (1 << 15)) != 0) j |= 1 << 26;
297+ if ((GetKeyState(VK_RSHIFT) & (1 << 15)) != 0) i |= 1 << 24;
298+ if ((GetKeyState(VK_LSHIFT) & (1 << 15)) != 0) i |= 1 << 16;
299+ if ((GetKeyState(VK_NUMLOCK) & (1 << 0)) != 0) i |= 1 << 22;
300+ if ((GetKeyState(VK_CAPITAL) & (1 << 0)) != 0) i |= 1 << 23;
301+ if (('A' <= wp && wp <= 'Z') || ('a' <= wp && wp <= 'z')) {
302+ if (j != 0) {
303+ i |= j;
304+ i &= ~0x20;
305+ }
306+ }
307+ putKeybuf(i);
308+// bl_putKeyB(1, &i);
309+ return 0;
310+ }
311+ }
312+ return DefWindowProc(hw, msg, wp, lp);
313+}
314+
315+void drv_openWin(int sx, int sy, UCHAR *buf, char *winClosed)
316+{
317+ int i, x, y;
318+// if (sx <= 0 || sy <= 0) return;
319+// if (sx < 160) return;
320+ w.win.buf = (int *) buf;
321+ w.win.xsiz = sx;
322+ w.win.ysiz = sy;
323+ bld_openWin(sx, sy, winClosed);
324+ return;
325+}
326+
327+void drv_sleep(int msec)
328+{
329+ Sleep(msec);
330+// MsgWaitForMultipleObjects(1, &threadhandle, FALSE, msec, QS_ALLINPUT);
331+ /* 勉強不足でまだ書き方が分かりません! */
332+ return;
333+}
334+
335+#endif
336+
337+#if (DRV_OSNUM == 0x0002)
338+
339+// by Liva, 2013.05.29-
340+
341+#include <mach/mach.h>
342+#include <Cocoa/Cocoa.h>
343+
344+void *mallocRWE(int bytes)
345+{
346+ void *p = malloc(bytes);
347+ vm_protect(mach_task_self(), (vm_address_t) p, bytes, FALSE, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE);
348+ return p;
349+}
350+
351+NSApplication* app;
352+
353+@interface OSECPUView : NSView {
354+ UCHAR *_buf;
355+ int _sx;
356+ int _sy;
357+ CGContextRef _context;
358+}
359+
360+- (id)initWithFrame:(NSRect)frameRect
361+ buf : (UCHAR *) buf
362+ sx : (int) sx
363+ sy : (int) sy;
364+
365+- (void)drawRect:(NSRect)rect;
366+@end
367+
368+@implementation OSECPUView
369+- (id)initWithFrame:(NSRect)frameRect
370+ buf : (UCHAR *) buf
371+ sx : (int) sx
372+ sy : (int) sy
373+{
374+ self = [super initWithFrame:frameRect];
375+ if (self) {
376+ _buf = buf;
377+ _sx = sx;
378+ _sy = sy;
379+ }
380+ return self;
381+}
382+
383+- (void)drawRect:(NSRect)rect {
384+ CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
385+ _context = CGBitmapContextCreate (_buf, _sx, _sy, 8, 4 * _sx, colorSpace, (kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst));
386+ CGImageRef image = CGBitmapContextCreateImage(_context);
387+ CGContextRef currentContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
388+ CGContextDrawImage(currentContext, NSRectToCGRect(rect), image);
389+}
390+
391+@end
392+
393+@interface Main : NSObject<NSWindowDelegate> {
394+ int argc;
395+ const UCHAR **argv;
396+ char *winClosed;
397+ OSECPUView *_view;
398+}
399+
400+- (void)runApp;
401+- (void)createThread : (int)_argc
402+args : (const UCHAR **)_argv;
403+- (BOOL)windowShouldClose:(id)sender;
404+- (void)openWin : (UCHAR *)buf
405+sx : (int) sx
406+sy : (int) sy
407+winClosed : (char *)_winClosed;
408+- (void)flushWin : (NSRect) rect;
409+@end
410+
411+@implementation Main
412+- (void)runApp
413+{
414+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
415+ OsecpuMain(argc,argv);
416+ [NSApp terminate:self];
417+ [pool release];
418+}
419+
420+- (void)createThread : (int)_argc
421+ args : (const UCHAR **)_argv
422+{
423+ argc = _argc;
424+ argv = _argv;
425+ NSThread *thread = [[[NSThread alloc] initWithTarget:self selector:@selector(runApp) object:nil] autorelease];
426+ [thread start];
427+}
428+
429+- (BOOL)windowShouldClose:(id)sender
430+{
431+ *winClosed = 1;
432+ return YES;
433+}
434+
435+- (void)openWin : (UCHAR *)buf
436+ sx : (int) sx
437+ sy : (int) sy
438+ winClosed : (char *)_winClosed
439+{
440+
441+ NSWindow* window = [[NSWindow alloc] initWithContentRect: NSMakeRect(0, 0, sx, sy) styleMask: NSTitledWindowMask | NSMiniaturizableWindowMask | NSClosableWindowMask backing: NSBackingStoreBuffered defer: NO];
442+ [window setTitle: @"osecpu"];
443+ [window center];
444+ [window makeKeyAndOrderFront:nil];
445+ [window setReleasedWhenClosed:YES];
446+ window.delegate = self;
447+ winClosed = _winClosed;
448+
449+ _view = [[OSECPUView alloc] initWithFrame:NSMakeRect(0,0,sx,sy) buf:buf sx:sx sy:sy];
450+ [window.contentView addSubview:_view];
451+}
452+
453+- (void)flushWin : (NSRect) rect
454+ {
455+ [_view drawRect:rect];
456+ }
457+
458+@end
459+
460+id objc_main;
461+
462+int main(int argc, const UCHAR **argv)
463+{
464+ objc_main = [[Main alloc] init];
465+
466+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
467+ app = [[NSApplication alloc] init];
468+ [objc_main createThread:argc args:argv];
469+ [app run];
470+ [pool release];
471+ return 0;
472+}
473+
474+void drv_openWin(int sx, int sy, UCHAR *buf, char *winClosed)
475+{
476+ [objc_main openWin:buf sx:sx sy:sy winClosed:winClosed];
477+}
478+
479+void drv_flshWin(int sx, int sy, int x0, int y0)
480+{
481+ [objc_main flushWin:NSMakeRect(x0,y0,sx,sy)];
482+}
483+
484+void drv_sleep(int msec)
485+{
486+ [NSThread sleepForTimeInterval:0.001*msec];
487+ return;
488+}
489+
490+#endif
491+
492+#if (DRV_OSNUM == 0x0003)
493+
494+// by takeutch-kemeco, 2013.07.25-
495+
496+// gcc -D__linux__ osecpu.c `pkg-config blike --cflags --libs` -o osecpu
497+
498+
499+void __bl_openWin_attach_vram(int, int, int*);
500+void *__bld_mallocRWE(unsigned int);
501+void bld_flshWin(int, int, int, int);
502+void bl_wait(int);
503+void __bld_set_callback_key_press(void (*f)(void*, const int));
504+void __bld_set_callback_key_release(void (*f)(void*, const int));
505+
506+extern int bl_argc;
507+extern const UCHAR** bl_argv;
508+
509+static void __drv_bld_callback_key_press(void* a, const int keyval) { if (keyval != -1) putKeybuf(keyval); }
510+static void __drv_bld_callback_key_release(void* a, const int keyval) { /* putKeybuf(0x0fff); */ }
511+
512+void *mallocRWE(int bytes) { return __bld_mallocRWE(bytes); }
513+void drv_openWin(int sx, int sy, UCHAR *buf, char *winClosed) { __bl_openWin_attach_vram(sx, sy, (int*) buf); }
514+void drv_flshWin(int sx, int sy, int x0, int y0) { bld_flshWin(sx, sy, x0, y0); }
515+void drv_sleep(int msec) { bl_wait(msec); }
516+
517+blMain()
518+{
519+ __bld_set_callback_key_press(__drv_bld_callback_key_press);
520+ __bld_set_callback_key_release(__drv_bld_callback_key_release);
521+ OsecpuMain(bl_argc, bl_argv);
522+}
523+
524+#endif /* (DRV_OSNUM == 0x0003) */
525+
526+
--- a/extend.c
+++ b/extend.c
@@ -12,9 +12,9 @@ int jitcStepExtend(OsecpuJitc *jitc)
1212 return -1;
1313 }
1414
15-void jitcAfterStepExtend(OsecpuJitc *jitc)
15+int jitcAfterStepExtend(OsecpuJitc *jitc)
1616 {
17- return;
17+ return 0;
1818 }
1919
2020 void execStepExtend(OsecpuVm *vm)
--- a/float.c
+++ b/float.c
@@ -95,6 +95,7 @@ int jitcStepFloat(OsecpuJitc *jitc)
9595 jitcStep_checkFxx(pRC, f);
9696 jitcStep_checkBits32(pRC, bit0);
9797 jitcStep_checkRxxNotR3F(pRC, r);
98+ jitc->prefix2f[0] = 0; // 2F-0.
9899 goto fin;
99100 }
100101 if (0x48 <= opecode && opecode <= 0x4d) {
@@ -125,9 +126,9 @@ fin1:
125126 return retcode;
126127 }
127128
128-void jitcAfterStepFloat(OsecpuJitc *jitc)
129+int jitcAfterStepFloat(OsecpuJitc *jitc)
129130 {
130- return;
131+ return 0;
131132 }
132133
133134 void execStepFloat(OsecpuVm *vm)
@@ -200,7 +201,7 @@ void execStepFloat(OsecpuVm *vm)
200201 }
201202 vm->r[r] = (Int32) vm->f[f];
202203 vm->bit[r] = bit0;
203- execStep_checkBitsRange(vm->r[r], bit0, vm);
204+ vm->r[r] = execStep_checkBitsRange(vm->r[r], bit0, vm, 0, 0);
204205 ip += 5;
205206 goto fin;
206207 }
--- a/integer.c
+++ b/integer.c
@@ -1,6 +1,37 @@
11 #include "osecpu-vm.h"
22
3-// 整数命令: 02, 10-16, 18-1B, 20-27, FD
3+// 整数命令: 02, 08-09, 10-16, 18-1B, 20-27, 2F, FD
4+
5+int getTypBitInteger(int typ)
6+{
7+ int retcode = 0;
8+ if (2 <= typ && typ <= 21) {
9+ static unsigned char table[10] = { 8, 16, 32, 4, 2, 1, 12, 20, 24, 28 };
10+ retcode = table[(typ - 2) / 2];
11+ }
12+ return retcode;
13+}
14+
15+void getTypInfoInteger(int typ, int *typSize0, int *typSize1, int *typSign)
16+// typSize0: 公式サイズ(ビット単位).
17+// typSize1: 内部サイズ(バイト単位).
18+// typSign: 符号の有無(0は符号なし).
19+{
20+ *typSize0 = *typSize1 = -1;
21+ if (2 <= typ && typ <= 21) {
22+ int bytes;
23+ if ((typ & 1) == 0)
24+ *typSign = -1; // typが偶数なら符号あり.
25+ else
26+ *typSign = 0; // typが奇数なら符号なし.
27+ *typSize0 = getTypBitInteger(typ);
28+ bytes = (*typSize0 + 7) / 8;
29+ if (bytes == 3) bytes = 4;
30+ *typSize1 = bytes;
31+ }
32+ return;
33+}
34+
435
536 void jitcInitInteger(OsecpuJitc *jitc)
637 {
@@ -12,13 +43,9 @@ int jitcStepInteger(OsecpuJitc *jitc)
1243 {
1344 Int32 *ip = jitc->hh4Buffer;
1445 Int32 opecode = ip[0], imm;
15- int bit, bit0, bit1, r, r0, r1, r2;
46+ int bit, bit0, bit1, r, r0, r1, r2, p, typ;
1647 int retcode = -1, *pRC = &retcode;
17- int i;
18- if (opecode == 0x00) { /* NOP */
19- jitcSetHh4BufferSimple(jitc, 1);
20- goto fin;
21- }
48+ int i, j;
2249 if (opecode == 0x02) { /* LIMM(imm, Rxx, bits); */
2350 ip[1] = hh4ReaderGetSigned(&jitc->hh4r);
2451 ip[2] = hh4ReaderGetUnsigned(&jitc->hh4r);
@@ -42,6 +69,43 @@ int jitcStepInteger(OsecpuJitc *jitc)
4269 jitc->ope04 = jitc->dst;
4370 goto fin;
4471 }
72+ if (opecode == 0x08) { /* LMEM(p, typ, 0, r, bit); */
73+ jitcSetHh4BufferSimple(jitc, 6);
74+ p = ip[1]; typ = ip[2]; i = ip[3]; r = ip[4]; bit = ip[5];
75+ if (i != 0) {
76+ jitcSetRetCode(pRC, JITC_UNSUPPORTED);
77+ goto fin;
78+ }
79+ jitcStep_checkPxx(pRC, p);
80+ jitcStep_checkRxxNotR3F(pRC, r);
81+ jitcStep_checkBits32(pRC, bit);
82+ if (jitc->prefix2f[0] != 0 && jitc->prefix2f[1] != 0)
83+ jitcSetRetCode(pRC, JITC_BAD_PREFIX); // 2F-n系プリフィクスは1個まで.
84+ jitc->prefix2f[0] = 0; // 2F-0.
85+ jitc->prefix2f[1] = 0; // 2F-1.
86+ goto fin;
87+ }
88+ if (opecode == 0x09) { /* SMEM(r, bit, p, typ, 0); */
89+ jitcSetHh4BufferSimple(jitc, 6);
90+ r = ip[1]; bit = ip[2]; p = ip[3]; typ = ip[4]; i = ip[5];
91+ if (i != 0) {
92+ jitcSetRetCode(pRC, JITC_UNSUPPORTED);
93+ goto fin;
94+ }
95+ jitcStep_checkPxx(pRC, p);
96+ jitcStep_checkRxxNotR3F(pRC, r);
97+ j = 0;
98+ for (i = 0; i < 3; i++) {
99+ if (jitc->prefix2f[i] != 0)
100+ j++;
101+ }
102+ if (j > 1)
103+ jitcSetRetCode(pRC, JITC_BAD_PREFIX); // 2F-n系プリフィクスは1個まで.
104+ jitc->prefix2f[0] = 0; // 2F-0.
105+ jitc->prefix2f[1] = 0; // 2F-1.
106+ jitc->prefix2f[2] = 0; // 2F-2.
107+ goto fin;
108+ }
45109 if (0x10 <= opecode && opecode <= 0x1b && opecode != 0x13 && opecode != 0x17) {
46110 jitcSetHh4BufferSimple(jitc, 5);
47111 r1 = ip[1]; r2 = ip[2]; r0 = ip[3]; bit = ip[4];
@@ -49,6 +113,7 @@ int jitcStepInteger(OsecpuJitc *jitc)
49113 jitcStep_checkRxx(pRC, r2);
50114 jitcStep_checkRxxNotR3F(pRC, r0);
51115 jitcStep_checkBits32(pRC, bit);
116+ jitc->prefix2f[0] = 0; // 2F-0.
52117 goto fin;
53118 }
54119 if (opecode == 0x13) { // SBX.
@@ -59,6 +124,7 @@ int jitcStepInteger(OsecpuJitc *jitc)
59124 if (r2 != 0x3f)
60125 jitcSetRetCode(pRC, JITC_BAD_RXX);
61126 jitcStep_checkBits32(pRC, bit);
127+ jitc->prefix2f[0] = 0; // 2F-0.
62128 goto fin;
63129 }
64130 if (0x20 <= opecode && opecode <= 0x27) {
@@ -71,13 +137,6 @@ int jitcStepInteger(OsecpuJitc *jitc)
71137 jitcStep_checkBits32(pRC, bit1);
72138 goto fin;
73139 }
74- if (opecode == 0xfd) {
75- jitcSetHh4BufferSimple(jitc, 3);
76- imm = ip[1]; r = ip[2];
77- if (0 <= r && r <= 3)
78- jitc->dr[r] = imm;
79- goto fin;
80- }
81140 goto fin1;
82141 fin:
83142 if (retcode == -1)
@@ -86,46 +145,120 @@ fin1:
86145 return retcode;
87146 }
88147
89-void jitcAfterStepInteger(OsecpuJitc *jitc)
148+int jitcAfterStepInteger(OsecpuJitc *jitc)
90149 {
150+ int i, retcode = 0;
91151 if (jitc->ope04 != NULL && jitc->dst != jitc->ope04) {
92152 // CND命令の直後の命令を検出.
93153 Int32 *dst04 = jitc->ope04;
94154 dst04[2] = jitc->instrLength; // 直後の命令の命令長.
95155 jitc->ope04 = NULL;
96156 }
97- return;
157+ return 0;
158+}
159+
160+Int32 execStep_checkBitsRange(Int32 value, int bit, OsecpuVm *vm, int bit1, int bit2)
161+{
162+ int max, min, i;
163+ if (bit1 != BIT_DISABLE_REG && bit2 != BIT_DISABLE_REG && vm->prefix2f[0] == 0) {
164+ max = 1 << (bit - 1); // 例: bits=8だとmax=128になる.
165+ max--; // 例: bits=8だとmax=127になる.
166+ min = - max - 1; // 例: bits=8だとmin=-128になる。
167+ if (!(min <= value && value <= max))
168+ jitcSetRetCode(&vm->errorCode, EXEC_BITS_RANGE_OVER);
169+ } else {
170+ vm->prefix2f[0] = 0;
171+ if (bit > 0) {
172+ i = (-1) << bit;
173+ if ((value & (1 << (bit - 1))) == 0) {
174+ // 符号ビットが0だった.
175+ value &= ~i;
176+ } else {
177+ // 符号ビットが1だった.
178+ value |= i;
179+ }
180+ } else
181+ value = 0;
182+ }
183+ return value;
98184 }
99185
100186 void execStepInteger(OsecpuVm *vm)
101187 {
102188 const Int32 *ip = vm->ip;
103189 Int32 opecode = ip[0], imm;
104- int bit, bit0, bit1, r, r0, r1, r2;
105- int i;
106- if (opecode == 0x00) { // NOP();
107- ip++;
108- goto fin;
109- }
190+ int bit, bit0, bit1, r, r0, r1, r2, p, typ, typSign, typSize0, typSize1;
191+ int i, mbit, tbit;
110192 if (opecode == 0x02) { // LIMM(imm, Rxx, bits);
111193 imm = ip[1]; r = ip[2]; bit = ip[3];
112194 vm->r[r] = imm;
113195 vm->bit[r] = bit;
114- execStep_checkBitsRange(vm->r[r], bit, vm);
196+ execStep_checkBitsRange(vm->r[r], bit, vm, 0, 0);
115197 ip += 4;
116198 goto fin;
117199 }
118200 if (opecode == 0x04) { /* CND(Rxx); */
119- r = ip[1];
120- i = ip[2];
201+ r = ip[1]; i = ip[2];
121202 ip += 3;
122203 if ((vm->r[r] & 1) == 0)
123204 ip += i;
124205 goto fin;
125206 }
207+ if (opecode == 0x08) { /* LMEM(p, typ, 0, r, bit); */
208+ p = ip[1]; typ = ip[2]; r = ip[4]; bit = ip[5];
209+ execStep_checkMemAccess(vm, p, typ, EXEC_CMA_FLAG_READ);
210+ if (vm->errorCode != 0) goto fin;
211+ mbit = *(vm->p[p].bit);
212+ tbit = getTypBitInteger(typ);
213+ if (mbit == BIT_DISABLE_MEM)
214+ tbit = mbit;
215+ getTypInfoInteger(typ, &typSize0, &typSize1, &typSign);
216+ if (typSize1 == 1 && typSign == 0) {
217+ unsigned char *puc = (unsigned char *) vm->p[p].p;
218+ vm->r[r] = *puc;
219+ }
220+ if (typSize1 == 1 && typSign != 0) {
221+ signed char *psc = (signed char *) vm->p[p].p;
222+ vm->r[r] = *psc;
223+ }
224+ if (typSize1 == 2 && typSign == 0) {
225+ unsigned short *pus = (unsigned short *) vm->p[p].p;
226+ vm->r[r] = *pus;
227+ }
228+ if (typSize1 == 2 && typSign != 0) {
229+ signed short *pss = (signed short *) vm->p[p].p;
230+ vm->r[r] = *pss;
231+ }
232+ if (typSize1 == 4 && typSign == 0) {
233+ unsigned int *pui = (unsigned int *) vm->p[p].p;
234+ vm->r[r] = *pui;
235+ }
236+ if (typSize1 == 4 && typSign != 0) {
237+ signed int *psi = (signed int *) vm->p[p].p;
238+ vm->r[r] = *psi;
239+ }
240+ if (vm->prefix2f[1] == 0) {
241+ if (mbit < tbit && mbit < bit)
242+ jitcSetRetCode(&vm->errorCode, EXEC_BAD_BITS); // 不確定ビットの参照がある場合.
243+ } else {
244+ if (bit > mbit)
245+ bit = mbit;
246+ vm->prefix2f[1] = 0;
247+ }
248+ vm->bit[r] = bit;
249+ if (tbit > bit)
250+ vm->r[r] = execStep_checkBitsRange(vm->r[r], bit, vm, 0, 0); // 部分リードの場合は、ゴミビットを消す.
251+ ip += 6;
252+ goto fin;
253+ }
254+
126255 if (0x10 <= opecode && opecode <= 0x16 && opecode != 0x13) {
127256 r1 = ip[1]; r2 = ip[2]; r0 = ip[3]; bit = ip[4];
128- if (bit > vm->bit[r1] || bit > vm->bit[r2]) {
257+ if (vm->bit[r1] != BIT_DISABLE_REG && bit > vm->bit[r1]) {
258+ jitcSetRetCode(&vm->errorCode, EXEC_BAD_BITS);
259+ goto fin;
260+ }
261+ if (vm->bit[r2] != BIT_DISABLE_REG && bit > vm->bit[r2]) {
129262 jitcSetRetCode(&vm->errorCode, EXEC_BAD_BITS);
130263 goto fin;
131264 }
@@ -136,13 +269,13 @@ void execStepInteger(OsecpuVm *vm)
136269 if (opecode == 0x15) vm->r[r0] = vm->r[r1] - vm->r[r2]; // SUB(r0, r1, r2, bits);
137270 if (opecode == 0x16) vm->r[r0] = vm->r[r1] * vm->r[r2]; // MUL(r0, r1, r2, bits);
138271 vm->bit[r0] = bit;
139- execStep_checkBitsRange(vm->r[r0], bit, vm);
272+ vm->r[r0] = execStep_checkBitsRange(vm->r[r0], bit, vm, vm->bit[r1], vm->bit[r2]);
140273 ip += 5;
141274 goto fin;
142275 }
143276 if (opecode == 0x13) { // SBX.
144277 r1 = ip[1]; r0 = ip[3]; bit = ip[4];
145- if (bit > vm->bit[r1]) {
278+ if (vm->bit[r1] != BIT_DISABLE_REG && bit > vm->bit[r1]) {
146279 jitcSetRetCode(&vm->errorCode, EXEC_BAD_BITS);
147280 goto fin;
148281 }
@@ -159,17 +292,17 @@ void execStepInteger(OsecpuVm *vm)
159292 vm->r[r0] = vm->r[r1] | i;
160293 }
161294 vm->bit[r0] = bit;
162- execStep_checkBitsRange(vm->r[r0], bit, vm);
295+ vm->r[r0] = execStep_checkBitsRange(vm->r[r0], bit, vm, vm->bit[r1], 0);
163296 ip += 5;
164297 goto fin;
165298 }
166299 if (0x18 <= opecode && opecode <= 0x19) {
167300 r1 = ip[1]; r2 = ip[2]; r0 = ip[3]; bit = ip[4];
168- if (bit > vm->bit[r1]) {
301+ if (vm->bit[r1] != BIT_DISABLE_REG && bit > vm->bit[r1]) {
169302 jitcSetRetCode(&vm->errorCode, EXEC_BAD_BITS);
170303 goto fin;
171304 }
172- if (bit <= vm->r[r2] || vm->r[r2] < 0) {
305+ if (vm->r[r2] < 0) {
173306 jitcSetRetCode(&vm->errorCode, EXEC_BAD_R2);
174307 goto fin;
175308 }
@@ -178,13 +311,17 @@ void execStepInteger(OsecpuVm *vm)
178311 else
179312 vm->r[r0] = vm->r[r1] >> vm->r[r2]; // SAR
180313 vm->bit[r0] = bit;
181- execStep_checkBitsRange(vm->r[r0], bit, vm);
314+ vm->r[r0] = execStep_checkBitsRange(vm->r[r0], bit, vm, vm->bit[r1], 0);
182315 ip += 5;
183316 goto fin;
184317 }
185318 if (0x1a <= opecode && opecode <= 0x1b) {
186319 r1 = ip[1]; r2 = ip[2]; r0 = ip[3]; bit = ip[4];
187- if (bit > vm->bit[r1] || bit > vm->bit[r2]) {
320+ if (vm->bit[r1] != BIT_DISABLE_REG && bit > vm->bit[r1]) {
321+ jitcSetRetCode(&vm->errorCode, EXEC_BAD_BITS);
322+ goto fin;
323+ }
324+ if (vm->bit[r2] != BIT_DISABLE_REG && bit > vm->bit[r2]) {
188325 jitcSetRetCode(&vm->errorCode, EXEC_BAD_BITS);
189326 goto fin;
190327 }
@@ -197,13 +334,17 @@ void execStepInteger(OsecpuVm *vm)
197334 else
198335 vm->r[r0] = vm->r[r1] % vm->r[r2];
199336 vm->bit[r0] = bit;
200- execStep_checkBitsRange(vm->r[r0], bit, vm);
337+ vm->r[r0] = execStep_checkBitsRange(vm->r[r0], bit, vm, vm->bit[r1], vm->bit[r2]);
201338 ip += 5;
202339 goto fin;
203340 }
204341 if (0x20 <= opecode && opecode <= 0x27) {
205342 r1 = ip[1]; r2 = ip[2]; bit1 = ip[3]; r0 = ip[4]; bit0 = ip[5];
206- if (bit1 > vm->bit[r1] || bit1 > vm->bit[r2]) {
343+ if (vm->bit[r1] != BIT_DISABLE_REG && bit > vm->bit[r1]) {
344+ jitcSetRetCode(&vm->errorCode, EXEC_BAD_BITS);
345+ goto fin;
346+ }
347+ if (vm->bit[r2] != BIT_DISABLE_REG && bit > vm->bit[r2]) {
207348 jitcSetRetCode(&vm->errorCode, EXEC_BAD_BITS);
208349 goto fin;
209350 }
@@ -230,8 +371,32 @@ void execStepInteger(OsecpuVm *vm)
230371 ip += 6;
231372 goto fin;
232373 }
374+
233375 fin:
234- vm->ip = ip;
376+ if (vm->errorCode <= 0)
377+ vm->ip = ip;
378+ return;
379+}
380+
381+void jitcStep_checkBits32(int *pRC, int bits)
382+{
383+ if (!(0 <= bits && bits <= 32))
384+ jitcSetRetCode(pRC, JITC_BAD_BITS);
235385 return;
236386 }
237387
388+void jitcStep_checkRxx(int *pRC, int rxx)
389+{
390+ if (!(0x00 <= rxx && rxx <= 0x3f))
391+ jitcSetRetCode(pRC, JITC_BAD_RXX);
392+ return;
393+}
394+
395+void jitcStep_checkRxxNotR3F(int *pRC, int rxx)
396+{
397+ if (!(0x00 <= rxx && rxx <= 0x3e))
398+ jitcSetRetCode(pRC, JITC_BAD_RXX);
399+ return;
400+}
401+
402+
--- a/memo.txt
+++ b/memo.txt
@@ -33,3 +33,59 @@
3333 data命令でも浮動小数点を使えるようになりたいからそれは後日がんばる。
3434 次はLMEMだなー。その次がPADD。
3535
36+2014.05.23金:
37+ プリフィクスについて:
38+ 解釈できるプリフィクスは、認識した後に0クリアすること。そうしなければエラーになる。
39+ 2Fプリフィクスは、フラグ的な指定なので、命令ごとに意味が異なる。
40+ LMEMに対する、2F-0プリフィクスについて:
41+ 2F-0プリフィクスがない場合:
42+ (1) mem.bit < typ.bit なら、セキュリティ例外になる。
43+ mem.bit: メモリのbit[]値
44+ typ.bit: そのメモリの型での最大のbit値
45+ reg.bit: LMEM命令内のbit値で、これは命令実行後にRxxのbit[]値になる
46+ 2F-0プリフィクスがある場合:
47+ (1) reg.bit = min(reg.bit, mem.bit) とする。結果が何であろうとセキュリティ例外にはならない。
48+ この場合、不定値をロードしてもレジスタが不定値なるだけで処理を続行できる。
49+ しかしこの値を使って演算しようとすると、エラーになる。
50+ SMEMに対する、2F-0プリフィクスについて:
51+ 2F-0プリフィクスがない場合:
52+ (1) typ.bit > reg.bit なら、セキュリティ例外になる。
53+ (2) typで指定されている型で表現可能な範囲にregがないのであれば、セキュリティ例外になる。
54+ (3) mem.bit = typ.bit になる。
55+ 2F-0プリフィクスがある場合:
56+ (1) typで指定されている型で表現可能な範囲にregがないのであれば、mem.bit = 0 になる。
57+ (2) そうでなければ mem.bit = reg.bit になる。
58+ つまり例外を起こさずに何とかする。
59+ この場合、unsignedな型は指定できない。
60+ SMEMに対する、2F-1プリフィクスについて:
61+ 2F-1プリフィクスがあると、Rxxフィールドは無視されて、メモリは無条件にbit[]値を0にされる。
62+ 明示的にメモリを不定値したい場合は、これが望ましい。適当なレジスタに不定値を代入して格納する方法だと
63+ 高速モード時に不要なSMEM命令が残ってしまうかもしれない。
64+ SMEMに対する、2F-2プリフィクスについて:
65+ 2F-2プリフィクスがある場合:
66+ (1) typ.bit > reg.bit なら、セキュリティ例外になる。
67+ (2) 実際に書き込まれるのは、typ.bitでマスクされた下位の値のみ。
68+ (3) mem.bit = typ.bit になる。
69+ (上記のメモは、もはや古い内容。メモだから残しているだけ。)
70+ data命令がpointer.cの中にあるのはうまくない!
71+
72+2014.05.27火:
73+ レンジチェックに関する諸問題:
74+ (1) 高速モードから安全モードへ切り替えることを想定すると、bit[]に「不明」を認めなければいけない。
75+ しかしそうなると、レンジチェックの手順はかなり複雑になる。
76+ ソースデータに「不明」がある場合、結果が出た後に結果を正規化する必要がある。
77+ (2) 安全モードだけでも、C=(A+B)&3;のような計算をするときに、A+Bの結果を2ビットの精度で演算できるべきでは
78+ ないか?・・・となると、A+Bの計算をするときに結果が2ビットで収まらなくても構わないということを認めなければ
79+ いけない。そのために2F-0プリフィクスを付ける。
80+ (3) まず論点としては、レンジチェックをやめてしまえばいいのではないかということがある。ごみデータが現れることは
81+ 高速モードじゃなくても十分に起こり得ることなのであって、そうなるとそれに気を使うのは面倒なだけではないか?
82+ しかしとりあえず、まだあきらめずにレンジチェックをやる方向で検討する。この(3)は思考過程を記録として残すために
83+ 書いた。
84+ (4) 2F-0プリフィクスがある場合、レンジチェックはしないで、むしろ結果がそのレンジに収まるように符号拡張をする。
85+ そうしないと以後のレンジチェックに障るかもしれないので。
86+ 例外検出に関する諸問題:
87+ 例外を検出した時に、正常系だった最後の値を保持する(おかしくなった原因命令を実行する直前の状態にする)のは
88+ 負担が大きいので、それはやらない。これについては、将来の逆再生機能に期待するべきだ。
89+ driver.cについて:
90+ 確かMacOS版にバグの修正があった気がするけど、まだそこまで手が回らない。落ち着いたら確認する。
91+
--- a/osecpu-vm.c
+++ b/osecpu-vm.c
@@ -155,8 +155,11 @@ void jitcInitDstLogSetPhase(OsecpuJitc *jitc, int phase)
155155 for (i = 0; i < JITC_DSTLOG_SIZE; i++)
156156 jitc->dstLog[i] = NULL;
157157 jitc->dstLogIndex = 0;
158+ for (i = 0; i < PREFIX2F_SIZE; i++)
159+ jitc->prefix2f[i] = 0;
158160 jitc->phase = phase;
159161 jitcInitInteger(jitc);
162+ jitcInitOther(jitc);
160163 jitcInitPointer(jitc);
161164 jitcInitFloat(jitc);
162165 jitcInitExtend(jitc);
@@ -184,6 +187,7 @@ int jitcStep(OsecpuJitc *jitc)
184187 int retcode = -1, *pRC = &retcode, i;
185188 jitc->hh4Buffer[0] = hh4ReaderGetUnsigned(&jitc->hh4r);
186189 retcode = jitcStepInteger(jitc); if (retcode >= 0) goto fin;
190+ retcode = jitcStepOther(jitc); if (retcode >= 0) goto fin;
187191 retcode = jitcStepPointer(jitc); if (retcode >= 0) goto fin;
188192 retcode = jitcStepFloat(jitc); if (retcode >= 0) goto fin;
189193 retcode = jitcStepExtend(jitc); if (retcode >= 0) goto fin;
@@ -197,10 +201,11 @@ fin:
197201 goto fin1;
198202 for (i = 0; i < jitc->instrLength; i++)
199203 jitc->dst[i] = jitc->hh4Buffer[i];
200- jitcAfterStepInteger(jitc);
201- jitcAfterStepPointer(jitc);
202- jitcAfterStepFloat(jitc);
203- jitcAfterStepExtend(jitc);
204+ retcode = jitcAfterStepInteger(jitc); if (retcode > 0) goto fin1;
205+ retcode = jitcAfterStepOther(jitc); if (retcode > 0) goto fin1;
206+ retcode = jitcAfterStepPointer(jitc); if (retcode > 0) goto fin1;
207+ retcode = jitcAfterStepFloat(jitc); if (retcode > 0) goto fin1;
208+ retcode = jitcAfterStepExtend(jitc); if (retcode > 0) goto fin1;
204209 i = jitc->dstLogIndex;
205210 jitc->dstLog[i] = jitc->dst; // エラーのなかった命令は記録する.
206211 jitc->dstLogIndex = (i + 1) % JITC_DSTLOG_SIZE;
@@ -236,27 +241,6 @@ fin:
236241 return jitc->errorCode;
237242 }
238243
239-void jitcStep_checkBits32(int *pRC, int bits)
240-{
241- if (!(0 <= bits && bits <= 32))
242- jitcSetRetCode(pRC, JITC_BAD_BITS);
243- return;
244-}
245-
246-void jitcStep_checkRxx(int *pRC, int rxx)
247-{
248- if (!(0x00 <= rxx && rxx <= 0x3f))
249- jitcSetRetCode(pRC, JITC_BAD_RXX);
250- return;
251-}
252-
253-void jitcStep_checkRxxNotR3F(int *pRC, int rxx)
254-{
255- if (!(0x00 <= rxx && rxx <= 0x3e))
256- jitcSetRetCode(pRC, JITC_BAD_RXX);
257- return;
258-}
259-
260244 // exec関係.
261245
262246 int execStep(OsecpuVm *vm)
@@ -264,6 +248,7 @@ int execStep(OsecpuVm *vm)
264248 const Int32 *ip = vm->ip;
265249 vm->errorCode = 0;
266250 execStepInteger(vm); if (ip != vm->ip || vm->errorCode != 0) goto fin;
251+ execStepOther(vm); if (ip != vm->ip || vm->errorCode != 0) goto fin;
267252 execStepPointer(vm); if (ip != vm->ip || vm->errorCode != 0) goto fin;
268253 execStepFloat(vm); if (ip != vm->ip || vm->errorCode != 0) goto fin;
269254 execStepExtend(vm); if (ip != vm->ip || vm->errorCode != 0) goto fin;
@@ -280,6 +265,9 @@ fin:
280265
281266 int execAll(OsecpuVm *vm)
282267 {
268+ int i;
269+ for (i = 0; i < PREFIX2F_SIZE; i++)
270+ vm->prefix2f[i] = 0;
283271 for (;;) {
284272 // 理想は適当な上限を決めて、休み休みでやるべきかもしれない.
285273 execStep(vm);
@@ -288,16 +276,6 @@ int execAll(OsecpuVm *vm)
288276 return vm->errorCode;
289277 }
290278
291-void execStep_checkBitsRange(Int32 value, int bits, OsecpuVm *vm)
292-{
293- int max, min;
294- max = 1 << (bits - 1); // 例: bits=8だとmax=128になる.
295- max--; // 例: bits=8だとmax=127になる.
296- min = - max - 1; // 例: bits=8だとmin=-128になる。
297- if (!(min <= value && value <= max))
298- jitcSetRetCode(&vm->errorCode, EXEC_BITS_RANGE_OVER);
299- return;
300-}
301279
302280 // 関連ツール関数.
303281
--- a/osecpu-vm.h
+++ b/osecpu-vm.h
@@ -48,6 +48,7 @@ typedef struct _BitReader {
4848 } BitReader;
4949
5050 #define JITC_DSTLOG_SIZE 16
51+#define PREFIX2F_SIZE 16
5152
5253 typedef struct _OsecpuJitc {
5354 int phase, dstLogIndex;
@@ -60,6 +61,7 @@ typedef struct _OsecpuJitc {
6061 int errorCode, instrLength;
6162 Int32 dr[4]; // Integer
6263 Int32 *ope04; // Integer
64+ unsigned char prefix2f[PREFIX2F_SIZE]; // Integer
6365 } OsecpuJitc;
6466
6567 typedef struct _OsecpuVm {
@@ -72,6 +74,7 @@ typedef struct _OsecpuVm {
7274 const Int32 *ip, *ip1; /* instruction-pointer, program-counter */
7375 const Defines *defines;
7476 int errorCode;
77+ unsigned char prefix2f[PREFIX2F_SIZE];
7578 } OsecpuVm;
7679
7780 // osecpu-vm.c
@@ -112,10 +115,8 @@ int jitcAll(OsecpuJitc *jitc);
112115 #define JITC_BAD_LABEL_TYPE 14
113116 #define JITC_LABEL_UNDEFINED 15
114117 #define JITC_BAD_TYPE 16
115-
116-void jitcStep_checkBits32(int *pRC, int bits);
117-void jitcStep_checkRxx(int *pRC, int rxx);
118-void jitcStep_checkRxxNotR3F(int *pRC, int rxx);
118+#define JITC_BAD_PREFIX 17
119+#define JITC_UNSUPPORTED 18
119120
120121 int execStep(OsecpuVm *r); // 検証済みのOSECPU命令を一つだけ実行する.
121122 int execAll(OsecpuVm *vm);
@@ -125,32 +126,62 @@ int execAll(OsecpuVm *vm);
125126 #define EXEC_BAD_R2 3 // SBX, SHL, SARのr2が不適切.
126127 #define EXEC_DIVISION_BY_ZERO 4
127128 #define EXEC_SRC_OVERRUN 5
129+#define EXEC_TYP_MISMATCH 6
130+#define EXEC_PTR_RANGE_OVER 7
131+#define EXEC_BAD_ACCESS 8
132+#define EXEC_API_ERROR 9
128133 #define EXEC_ABORT_OPECODE_M1 0xffff
129134
130-void execStep_checkBitsRange(Int32 value, int bits, OsecpuVm *vm);
135+#define EXEC_CMA_FLAG_SEEK 1
136+#define EXEC_CMA_FLAG_READ 2
137+#define EXEC_CMA_FLAG_WRITE 4
138+#define EXEC_CMA_FLAG_EXEC 8
139+
140+#define BIT_DISABLE_REG -1
141+#define BIT_DISABLE_MEM 255
142+
143+#define PTR_TYP_CODE -1
144+#define PTR_TYP_NATIVECODE -2
131145
132146 unsigned char *hh4StrToBin(unsigned char *src, unsigned char *src1, unsigned char *dst, unsigned char *dst1);
133147
134-// integer.c : 整数命令
148+// integer.c : 整数命令.
135149 void jitcInitInteger(OsecpuJitc *jitc);
136150 int jitcStepInteger(OsecpuJitc *jitc);
137-void jitcAfterStepInteger(OsecpuJitc *jitc);
151+int jitcAfterStepInteger(OsecpuJitc *jitc);
138152 void execStepInteger(OsecpuVm *vm);
139153
140-// pointer.c : ポインタ命令
154+int getTypBitInteger(int typ);
155+void getTypInfoInteger(int typ, int *typSize0, int *typSize1, int *typSign);
156+Int32 execStep_checkBitsRange(Int32 value, int bit, OsecpuVm *vm, int bit1, int bit2);
157+void jitcStep_checkBits32(int *pRC, int bits);
158+void jitcStep_checkRxx(int *pRC, int rxx);
159+void jitcStep_checkRxxNotR3F(int *pRC, int rxx);
160+
161+// pointer.c : ポインタ命令.
141162 void jitcInitPointer(OsecpuJitc *jitc);
142163 int jitcStepPointer(OsecpuJitc *jitc);
143-void jitcAfterStepPointer(OsecpuJitc *jitc);
164+int jitcAfterStepPointer(OsecpuJitc *jitc);
144165 void execStepPointer(OsecpuVm *vm);
145166
167+void getTypSize(int typ, int *typSize0, int *typSize1, int *typSign); // これは直すべき.
168+void jitcStep_checkPxx(int *pRC, int pxx);
169+void execStep_checkMemAccess(OsecpuVm *vm, int p, int typ, int flag);
170+
146171 // float.c : 浮動小数点命令
147172 void jitcInitFloat(OsecpuJitc *jitc);
148173 int jitcStepFloat(OsecpuJitc *jitc);
149-void jitcAfterStepFloat(OsecpuJitc *jitc);
174+int jitcAfterStepFloat(OsecpuJitc *jitc);
150175 void execStepFloat(OsecpuVm *vm);
151176
177+// other.c : 雑命令.
178+void jitcInitOther(OsecpuJitc *jitc);
179+int jitcStepOther(OsecpuJitc *jitc);
180+int jitcAfterStepOther(OsecpuJitc *jitc);
181+void execStepOther(OsecpuVm *vm);
182+
152183 // extend.c : 拡張命令関係.
153184 void jitcInitExtend(OsecpuJitc *jitc);
154185 int jitcStepExtend(OsecpuJitc *jitc);
155-void jitcAfterStepExtend(OsecpuJitc *jitc);
186+int jitcAfterStepExtend(OsecpuJitc *jitc);
156187 void execStepExtend(OsecpuVm *vm);
--- /dev/null
+++ b/other.c
@@ -0,0 +1,87 @@
1+#include "osecpu-vm.h"
2+
3+// その他の命令: 00, 2F, FD
4+
5+void jitcInitOther(OsecpuJitc *jitc)
6+{
7+ jitc->ope04 = NULL;
8+ return;
9+}
10+
11+int jitcStepOther(OsecpuJitc *jitc)
12+{
13+ Int32 *ip = jitc->hh4Buffer;
14+ Int32 opecode = ip[0], imm;
15+ int bit, bit0, bit1, r, r0, r1, r2, p, typ;
16+ int retcode = -1, *pRC = &retcode;
17+ int i, j;
18+ if (opecode == 0x00) { /* NOP */
19+ jitcSetHh4BufferSimple(jitc, 1);
20+ goto fin;
21+ }
22+ if (opecode == 0x2f) {
23+ jitcSetHh4BufferSimple(jitc, 2);
24+ i = ip[1];
25+ if (i < PREFIX2F_SIZE && jitc->prefix2f[i] == 0)
26+ jitc->prefix2f[i] = 1;
27+ else
28+ jitcSetRetCode(pRC, JITC_BAD_PREFIX);
29+ goto fin;
30+ }
31+ if (opecode == 0xfd) {
32+ jitcSetHh4BufferSimple(jitc, 3);
33+ imm = ip[1]; r = ip[2];
34+ if (0 <= r && r <= 3)
35+ jitc->dr[r] = imm;
36+ goto fin;
37+ }
38+ goto fin1;
39+fin:
40+ if (retcode == -1)
41+ retcode = 0;
42+fin1:
43+ return retcode;
44+}
45+
46+int jitcAfterStepOther(OsecpuJitc *jitc)
47+{
48+ int i, retcode = 0;
49+ if (jitc->hh4Buffer[0] != 0x2f) {
50+ // 未解釈の2Fプリフィクスが残っていないか調査.
51+ // 解釈したら0クリアするのが作法.
52+ for (i = 0; i < PREFIX2F_SIZE; i++) {
53+ if (jitc->prefix2f[i] != 0)
54+ retcode = JITC_BAD_PREFIX;
55+ }
56+ }
57+ return 0;
58+}
59+
60+void execStepOther(OsecpuVm *vm)
61+{
62+ const Int32 *ip = vm->ip;
63+ Int32 opecode = ip[0], imm;
64+ int bit, bit0, bit1, r, r0, r1, r2, p, typ, typSign, typSize0, typSize1;
65+ int i, mbit, tbit;
66+ if (opecode == 0x00) { // NOP();
67+ ip++;
68+ goto fin;
69+ }
70+ if (opecode == 0x2f) {
71+ i = ip[1];
72+ vm->prefix2f[i] = 1;
73+ ip += 2;
74+ goto fin;
75+ }
76+ if (opecode == 0xfd) {
77+ imm = ip[1]; r = ip[2];
78+ if (0 <= r && r <= 3)
79+ vm->dr[r] = imm;
80+ goto fin;
81+ }
82+fin:
83+ if (vm->errorCode <= 0)
84+ vm->ip = ip;
85+ return;
86+}
87+
--- a/pointer.c
+++ b/pointer.c
@@ -1,19 +1,12 @@
11 #include "osecpu-vm.h"
22
3-// ポインタ関連命令: 01, 03, 2E
3+// ポインタ関連命令: 01, 03, 0E, 1E, 2E
44
55 void jitcInitPointer(OsecpuJitc *jitc)
66 {
77 return;
88 }
99
10-void jitcStep_checkPxx(int *pRC, int pxx)
11-{
12- if (!(0x00 <= pxx && pxx <= 0x3f))
13- jitcSetRetCode(pRC, JITC_BAD_PXX);
14- return;
15-}
16-
1710 void getTypSize(int typ, int *typSize0, int *typSize1, int *typSign)
1811 // typSize0: 入力バイナリ内でのビット数.
1912 // typSize1: 出力バイナリ内でのバイト数.
@@ -39,7 +32,7 @@ int jitcStepPointer(OsecpuJitc *jitc)
3932 Int32 *ip = jitc->hh4Buffer;
4033 Int32 opecode = ip[0], imm;
4134 int retcode = -1, *pRC = &retcode;
42- int i, j, opt, p, typ, len, typSign, typSize0, typSize1;
35+ int i, j, opt, p, p0, p1, r, bit, typ, len, typSign, typSize0, typSize1;
4336 if (opecode == 0x01) { /* LB(opt, uimm); */
4437 jitcSetHh4BufferSimple(jitc, 3);
4538 i = ip[1]; opt = ip[2];
@@ -56,7 +49,7 @@ int jitcStepPointer(OsecpuJitc *jitc)
5649 jitcSetRetCode(pRC, JITC_BAD_LABEL_TYPE);
5750 goto fin;
5851 }
59- jitc->defines->label[i].typ = -1; // とりあえずコードラベルにする.
52+ jitc->defines->label[i].typ = PTR_TYP_CODE; // とりあえずコードラベルにする.
6053 jitc->defines->label[i].opt = opt;
6154 jitc->defines->label[i].dst = jitc->dst;
6255 goto fin;
@@ -74,11 +67,29 @@ int jitcStepPointer(OsecpuJitc *jitc)
7467 jitcSetRetCode(pRC, JITC_LABEL_UNDEFINED);
7568 if (p != 0x3f && jitc->defines->label[i].opt == 0)
7669 jitcSetRetCode(pRC, JITC_BAD_LABEL_TYPE);
77- if (p == 0x3f && jitc->defines->label[i].typ != -1)
70+ if (p == 0x3f && jitc->defines->label[i].typ != PTR_TYP_CODE)
7871 jitcSetRetCode(pRC, JITC_BAD_LABEL_TYPE); // P3Fにデータラベルを代入できない.
7972 goto fin;
8073 }
81- if (opecode == 0x2e) { // data
74+ if (opecode == 0x0e) { // PADD(r, bit, p1, typ, p0);
75+ jitcSetHh4BufferSimple(jitc, 6);
76+ r = ip[1]; bit = ip[2]; p1 = ip[3]; typ = ip[4]; p0 = ip[5];
77+ jitcStep_checkPxx(pRC, p0);
78+ jitcStep_checkPxx(pRC, p1);
79+ jitcStep_checkRxx(pRC, r);
80+ jitcStep_checkBits32(pRC, bit);
81+ goto fin;
82+ }
83+ if (opecode == 0x1e) { // PCP(p1, p0);
84+ jitcSetHh4BufferSimple(jitc, 3);
85+ p1 = ip[1]; p0 = ip[2];
86+ jitcStep_checkPxx(pRC, p0);
87+ jitcStep_checkPxx(pRC, p1);
88+ if (p1 == 0x3f)
89+ jitcSetRetCode(pRC, JITC_BAD_PXX);
90+ goto fin;
91+ }
92+ if (opecode == 0x2e) { // data...これはother.cへ移動させるべき
8293 BitReader br;
8394 typ = hh4ReaderGetUnsigned(&jitc->hh4r);
8495 len = hh4ReaderGetUnsigned(&jitc->hh4r);
@@ -88,7 +99,7 @@ int jitcStepPointer(OsecpuJitc *jitc)
8899 goto fin;
89100 }
90101 jitc->instrLength = 0; // 自前で処理するので、この値は0にする.
91- if (jitc->dst + 3 + (typSize1 * len + 3) / 4 > jitc->dst1) {
102+ if (jitc->dst + 3 + (typSize1 * len + 3) / 4 + (len + 3) / 4 > jitc->dst1) {
92103 jitcSetRetCode(pRC, JITC_DST_OVERRUN);
93104 goto fin;
94105 }
@@ -132,12 +143,14 @@ int jitcStepPointer(OsecpuJitc *jitc)
132143 }
133144 jitc->dst += (typSize1 * len + 3) / 4;
134145 unsigned char *puc = (unsigned char *) jitc->dst;
146+ int tbit = getTypBitInteger(typ);
135147 for (i = 0; i < len; i++)
136- puc[i] = 0xff; // bits=255.
148+ puc[i] = tbit;
137149 jitc->dst += (len + 3) / 4;
138150 }
139151 for (j = 0; j < JITC_DSTLOG_SIZE; j++) {
140- Int32 *dstLog = jitc->dstLog[jitc->dstLogIndex + JITC_DSTLOG_SIZE - 1 - j];
152+ Int32 *dstLog = jitc->dstLog[(jitc->dstLogIndex + JITC_DSTLOG_SIZE - 1 - j) % JITC_DSTLOG_SIZE];
153+ // 1つ前、2つ前、3つ前...の命令をチェックしている.
141154 if (dstLog == NULL) break;
142155 if (dstLog[0] != 0x01) break;
143156 i = dstLog[1];
@@ -155,16 +168,16 @@ fin1:
155168 return retcode;
156169 }
157170
158-void jitcAfterStepPointer(OsecpuJitc *jitc)
171+int jitcAfterStepPointer(OsecpuJitc *jitc)
159172 {
160- return;
173+ return 0;
161174 }
162175
163176 void execStepPointer(OsecpuVm *vm)
164177 {
165178 const Int32 *ip = vm->ip;
166179 Int32 opecode = ip[0];
167- int i, p, typ, len, typSign, typSize0, typSize1;
180+ int i, p, r, p0, p1, bit, typ, len, typSign, typSize0, typSize1;
168181 if (opecode == 0x01) { /* LB(opt, uimm); */
169182 ip += 3;
170183 goto fin;
@@ -175,17 +188,21 @@ void execStepPointer(OsecpuVm *vm)
175188 ip = (const Int32 *) vm->defines->label[i].dst;
176189 else {
177190 typ = vm->defines->label[i].typ;
178- vm->p[p].p = (unsigned char *) vm->defines->label[i].dst;
179191 vm->p[p].typ = typ;
180- vm->p[p].p0 = vm->p[p].p;
181192 if (typ >= 2) {
193+ vm->p[p].p = (unsigned char *) (vm->defines->label[i].dst + 3);
194+ vm->p[p].p0 = vm->p[p].p;
182195 len = vm->defines->label[i].dst[2]; // 2e(data)のlenフィールド値.
183- getTypSize(typ, NULL, &typSize1, NULL);
196+ getTypSize(typ, &typSize0, &typSize1, &typSign);
184197 vm->p[p].p1 = vm->p[p].p + typSize1 * len;
185198 vm->p[p].bit = vm->p[p].p + ((typSize1 * len + 3) / 4) * 4;
199+ vm->p[p].flags = 6; // over-seek:ok, read:ok, write:ok
186200 }
187- if (typ == -1) { // コードラベル.
201+ if (typ == PTR_TYP_CODE) { // コードラベル.
202+ vm->p[p].p = (unsigned char *) vm->defines->label[i].dst;
203+ vm->p[p].p0 = vm->p[p].p;
188204 vm->p[p].p1 = vm->p[p].p + 1;
205+ vm->p[p].flags = 0; // over-seek:ok, read:err, write:err
189206 }
190207 if (typ == 1) { // VPtr.
191208 }
@@ -193,6 +210,40 @@ void execStepPointer(OsecpuVm *vm)
193210 }
194211 goto fin;
195212 }
213+ if (opecode == 0x0e) { // PADD(r, bit, p1, typ, p0);
214+ r = ip[1]; bit = ip[2]; p1 = ip[3]; typ = ip[4]; p0 = ip[5];
215+ getTypSize(typ, &typSize0, &typSize1, &typSign);
216+ i = execStep_checkBitsRange(vm->r[r], bit, vm, 0, 0);
217+ vm->p[p0] = vm->p[p1];
218+ vm->p[p0].p += i * typSize1;
219+ vm->p[p0].bit += i;
220+ execStep_checkMemAccess(vm, p0, typ, EXEC_CMA_FLAG_SEEK);
221+ ip += 6;
222+ }
223+ if (opecode == 0x1e) { // PCP(p1, p0);
224+ p1 = ip[1]; p0 = ip[2];
225+ if (p0 == 0x3f) {
226+ if (vm->p[p1].typ == PTR_TYP_CODE) { // code
227+ execStep_checkMemAccess(vm, p1, PTR_TYP_CODE, EXEC_CMA_FLAG_EXEC); // 主にliveSignのチェック.
228+ if (vm->errorCode != 0) goto fin;
229+ ip = (const Int32 *) vm->p[p1].p;
230+ }
231+ if (vm->p[p1].typ == PTR_TYP_NATIVECODE) { // native-code (API)
232+ const Int32 *(*func)(OsecpuVm *);
233+ const Int32 *nextIp;
234+ func = (void *) vm->p[p1].p;
235+ nextIp = (*func)(vm);
236+ if (nextIp != NULL)
237+ ip = nextIp;
238+ else
239+ jitcSetRetCode(&vm->errorCode, EXEC_API_ERROR);
240+ }
241+ } else {
242+ vm->p[p0] = vm->p[p1];
243+ ip += 3;
244+ }
245+ goto fin;
246+ }
196247 if (opecode == 0x2e) { // data
197248 typ = ip[1]; len = ip[2];
198249 getTypSize(typ, &typSize0, &typSize1, &typSign);
@@ -204,3 +255,31 @@ fin:
204255 return;
205256 }
206257
258+void jitcStep_checkPxx(int *pRC, int pxx)
259+{
260+ if (!(0x00 <= pxx && pxx <= 0x3f))
261+ jitcSetRetCode(pRC, JITC_BAD_PXX);
262+ return;
263+}
264+
265+void execStep_checkMemAccess(OsecpuVm *vm, int p, int typ, int flag)
266+{
267+ if (vm->p[p].typ != typ)
268+ jitcSetRetCode(&vm->errorCode, EXEC_TYP_MISMATCH);
269+ if (vm->p[p].p < vm->p[p].p0 || vm->p[p].p1 <= vm->p[p].p) {
270+ if (flag != EXEC_CMA_FLAG_SEEK)
271+ jitcSetRetCode(&vm->errorCode, EXEC_PTR_RANGE_OVER);
272+ else {
273+ if ((vm->p[p].flags & 1) != 0)
274+ jitcSetRetCode(&vm->errorCode, EXEC_PTR_RANGE_OVER); // over-seek検出.
275+ }
276+ }
277+ if (flag == EXEC_CMA_FLAG_READ && (vm->p[p].flags & EXEC_CMA_FLAG_READ) == 0)
278+ jitcSetRetCode(&vm->errorCode, EXEC_BAD_ACCESS);
279+ if (flag == EXEC_CMA_FLAG_WRITE && (vm->p[p].flags & EXEC_CMA_FLAG_WRITE) == 0)
280+ jitcSetRetCode(&vm->errorCode, EXEC_BAD_ACCESS);
281+
282+ // ToDo: liveSignに対応する.
283+ return;
284+}
285+
--- a/test.c
+++ b/test.c
@@ -1,5 +1,7 @@
11 #include "osecpu-vm.h"
22
3+void apiInit(OsecpuVm *vm);
4+
35 #define BUFFER_SIZE 256
46
57 int main(int argc, const char **argv)
@@ -60,8 +62,15 @@ int main(int argc, const char **argv)
6062 "1 2 1" // LB1(2);
6163 "ae 2 84 01 23 45 67" // data(UINT8, 4, 0x01, 0x23, 0x45, 0x67);
6264 "3 2 1" // PLIMM(P01, 2);
63- "2 1 3 a0" // LIMM32(R03, 1);
65+ "2 84 3 a0" // LIMM32(R03, 4);
66+ "2 2 bf a0" // LIMM32(R3F, 2);
67+ "8e bf a0 1 2 1" // PADD32(P01, UINT8, P01, R3F);
68+ "88 1 2 0 3 a0" // LMEM32(P01, UINT8, 0, R03);
6469 #endif
70+ "2 84 b0 a0" // LIMM32(R30, 4);
71+ "3 3 b0" // PLIMM(P30, 3);
72+ "9e a8 bf" // PCP(P3F, P28);
73+ "1 3 1" // LB1(3);
6574
6675 , NULL, hh4src, &hh4src[BUFFER_SIZE]
6776 );
@@ -84,6 +93,7 @@ int main(int argc, const char **argv)
8493 vm.ip1 = jitc.dst;
8594 // この時点で、i32buf[]は破棄しても良い.
8695
96+ apiInit(&vm);
8797 // execAll()を使って、j32buf[]内の中間コードを実行する.
8898 printf("execAll()=%d\n", execAll(&vm)); // 65535なら成功(EXEC_ABORT_OPECODE_M1).
8999 printf("R00=%d\n", vm.r[0x00]);