• R/O
  • HTTP
  • SSH
  • HTTPS

HeavyOSECPU: Commit


Commit MetaInfo

Revisión1e67a042b88d3bfebb9335dddacc5e2b71df2846 (tree)
Tiempo2014-03-12 23:46:43
Autorttwilb <ttwilb@user...>
Commiterttwilb

Log Message

syslibのエラーは出なくなったがアプリは動かない(pack error)

Cambiar Resumen

Diferencia incremental

--- a/comlib.c
+++ b/comlib.c
@@ -1,76 +1,76 @@
1-#include "osecpu.h"
2-
3-struct ComLib_Str {
4- const unsigned char *p;
5- int bitBuf, bitBufLen;
6- int tmp;
7-};
8-
9-int ComLib_getBit(struct ComLib_Str *s)
10-{
11- //ビットを一つずつ取り出す
12- if (s->bitBufLen == 0) {
13- s->bitBuf = s->p[0] | s->p[1] << 8;
14- s->p += 2;
15- s->bitBufLen = 16;
16- }
17- s->bitBufLen--;
18- return (s->bitBuf >> s->bitBufLen) & 1;
19-}
20-
21-int ComLib_getTmpBit(struct ComLib_Str *s)
22-{
23- //次のビットをtmpの一番下のビットに押し込んで、その次のビットを返す
24- s->tmp = (s->tmp << 1 | ComLib_getBit(s)) & 0xffff;
25- return ComLib_getBit(s);
26-}
27-
28-unsigned char *ComLib_main(const unsigned char *p, unsigned char *q)
29-{
30- //hh4デコーダー?
31- struct ComLib_Str s;
32- int i, dis = 0;
33- dis |= -1;
34- s.p = p;
35- s.bitBufLen = 0;
36- goto l1;
37-l0:
38- *q++ = *s.p++;
39-l1:
40- i = ComLib_getBit(&s);
41- if (i != 0){
42- //4bit?
43- goto l0;
44- }
45- s.tmp = 1;
46- do {
47- i = ComLib_getTmpBit(&s);
48- if (s.tmp == 0){
49- goto fin;
50- }
51- } while (i == 0);
52- if (s.tmp >= 3){
53- dis = ~((s.tmp - 3) << 8 | *s.p++);
54- }
55- s.tmp &= 0;
56- i = ComLib_getTmpBit(&s);
57- s.tmp = s.tmp << 1 | i;
58- if (s.tmp == 0) {
59- s.tmp |= 1;
60- do {
61- i = ComLib_getTmpBit(&s);
62- } while (i == 0);
63- s.tmp += 2;
64- }
65- s.tmp++;
66- if (dis < -0xd00){
67- s.tmp++;
68- }
69- for (i = 0; i < s.tmp; i++){
70- q[i] = q[i + dis];
71- }
72- q += s.tmp;
73- goto l1;
74-fin:
75- return q;
76-}
\ No newline at end of file
1+#include "osecpu.h"
2+
3+struct ComLib_Str {
4+ const unsigned char *p;
5+ int bitBuf, bitBufLen;
6+ int tmp;
7+};
8+
9+int ComLib_getBit(struct ComLib_Str *s)
10+{
11+ //ビットを一つずつ取り出す
12+ if (s->bitBufLen == 0) {
13+ s->bitBuf = s->p[0] | s->p[1] << 8;
14+ s->p += 2;
15+ s->bitBufLen = 16;
16+ }
17+ s->bitBufLen--;
18+ return (s->bitBuf >> s->bitBufLen) & 1;
19+}
20+
21+int ComLib_getTmpBit(struct ComLib_Str *s)
22+{
23+ //次のビットをtmpの一番下のビットに押し込んで、その次のビットを返す
24+ s->tmp = (s->tmp << 1 | ComLib_getBit(s)) & 0xffff;
25+ return ComLib_getBit(s);
26+}
27+
28+unsigned char *ComLib_main(const unsigned char *p, unsigned char *q)
29+{
30+ //hh4デコーダー?
31+ struct ComLib_Str s;
32+ int i, dis = 0;
33+ dis |= -1;
34+ s.p = p;
35+ s.bitBufLen = 0;
36+ goto l1;
37+l0:
38+ *q++ = *s.p++;
39+l1:
40+ i = ComLib_getBit(&s);
41+ if (i != 0){
42+ //4bit?
43+ goto l0;
44+ }
45+ s.tmp = 1;
46+ do {
47+ i = ComLib_getTmpBit(&s);
48+ if (s.tmp == 0){
49+ goto fin;
50+ }
51+ } while (i == 0);
52+ if (s.tmp >= 3){
53+ dis = ~((s.tmp - 3) << 8 | *s.p++);
54+ }
55+ s.tmp &= 0;
56+ i = ComLib_getTmpBit(&s);
57+ s.tmp = s.tmp << 1 | i;
58+ if (s.tmp == 0) {
59+ s.tmp |= 1;
60+ do {
61+ i = ComLib_getTmpBit(&s);
62+ } while (i == 0);
63+ s.tmp += 2;
64+ }
65+ s.tmp++;
66+ if (dis < -0xd00){
67+ s.tmp++;
68+ }
69+ for (i = 0; i < s.tmp; i++){
70+ q[i] = q[i + dis];
71+ }
72+ q += s.tmp;
73+ goto l1;
74+fin:
75+ return q;
76+}
--- a/dpndenv.c
+++ b/dpndenv.c
@@ -1,428 +1,428 @@
1-#include "osecpu.h"
2-
3-
4-#if (DRV_OSNUM == 0x0002)
5-//
6-// for Mac OSX 32-bit
7-//
8-#include <mach/mach.h>
9-#include <Cocoa/Cocoa.h>
10-
11-void *mallocRWE(int bytes)
12-{
13- void *p = malloc(bytes);
14- vm_protect(mach_task_self(), (vm_address_t) p, bytes, FALSE, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE);
15- return p;
16-}
17-
18-NSApplication* app;
19-
20-@interface OSECPUView : NSView
21-{
22- unsigned char *_buf;
23- int _sx;
24- int _sy;
25- CGContextRef _context;
26-}
27-
28-- (id)initWithFrame:(NSRect)frameRect buf:(unsigned char *)buf sx:(int)sx sy:(int)sy;
29-- (void)drawRect:(NSRect)rect;
30-@end
31-
32-@implementation OSECPUView
33-- (id)initWithFrame:(NSRect)frameRect buf:(unsigned char *)buf sx:(int)sx sy:(int)sy
34-{
35- self = [super initWithFrame:frameRect];
36- if (self) {
37- _buf = buf;
38- _sx = sx;
39- _sy = sy;
40- }
41- return self;
42-}
43-
44-- (void)drawRect:(NSRect)rect {
45- CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
46- _context = CGBitmapContextCreate (_buf, _sx, _sy, 8, 4 * _sx, colorSpace, (kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst));
47- CGImageRef image = CGBitmapContextCreateImage(_context);
48- CGContextRef currentContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
49- CGContextDrawImage(currentContext, NSRectToCGRect(rect), image);
50-
51- CFRelease(colorSpace);
52- CFRelease(image);
53-}
54-
55-@end
56-
57-@interface Main : NSObject<NSWindowDelegate>
58-{
59- int argc;
60- const unsigned char **argv;
61- char *winClosed;
62- OSECPUView *_view;
63-}
64-
65-- (void)runApp;
66-- (void)createThread:(int)_argc args:(const unsigned char **)_argv;
67-- (BOOL)windowShouldClose:(id)sender;
68-- (void)openWin:(unsigned char *)buf sx:(int)sx sy:(int)sy winClosed:(char *)_winClosed;
69-- (void)flushWin:(NSRect)rect;
70-@end
71-
72-@implementation Main
73-- (void)runApp
74-{
75- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
76- HeavyOSECPUMain(argc, (char **)argv);
77- [NSApp terminate:self];
78- [pool release];
79-}
80-
81-- (void)createThread : (int)_argc args:(const unsigned char **)_argv
82-{
83- argc = _argc;
84- argv = _argv;
85- NSThread *thread = [[[NSThread alloc] initWithTarget:self selector:@selector(runApp) object:nil] autorelease];
86- [thread start];
87-}
88-
89-- (BOOL)windowShouldClose:(id)sender
90-{
91- *winClosed = 1;
92- return YES;
93-}
94-
95-- (void)openWin:(unsigned char *)buf sx:(int)sx sy:(int) sy winClosed:(char *)_winClosed
96-{
97-
98- NSWindow* window = [[NSWindow alloc] initWithContentRect: NSMakeRect(0, 0, sx, sy) styleMask: NSTitledWindowMask | NSMiniaturizableWindowMask | NSClosableWindowMask backing: NSBackingStoreBuffered defer: NO];
99- [window setTitle: @"osecpu"];
100- [window center];
101- [window makeKeyAndOrderFront:nil];
102- [window setReleasedWhenClosed:YES];
103- window.delegate = self;
104- winClosed = _winClosed;
105-
106- _view = [[OSECPUView alloc] initWithFrame:NSMakeRect(0,0,sx,sy) buf:buf sx:sx sy:sy];
107- [window.contentView addSubview:_view];
108-}
109-
110-- (void)flushWin : (NSRect)rect
111-{
112- [_view drawRect:rect];
113-}
114-
115-@end
116-
117-id objc_main;
118-
119-int main(int argc, char **argv)
120-{
121- objc_main = [[Main alloc] init];
122-
123- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
124- app = [[NSApplication alloc] init];
125- [objc_main createThread:argc args:(const unsigned char **)argv];
126- [app run];
127- [pool release];
128- return 0;
129-}
130-
131-void drv_openWin(int sx, int sy, unsigned char *buf, char *winClosed)
132-{
133- [objc_main openWin:buf sx:sx sy:sy winClosed:winClosed];
134-}
135-
136-void drv_flshWin(int sx, int sy, int x0, int y0)
137-{
138- [objc_main flushWin:NSMakeRect(x0,y0,sx,sy)];
139-}
140-
141-void drv_sleep(int msec)
142-{
143- [NSThread sleepForTimeInterval:0.001*msec];
144- return;
145-}
146-
147-
148-#elif (DRV_OSNUM == 0x0003)
149-
150-#error "Your OS is not supported."
151-
152-#elif (DRV_OSNUM == 0x0001)
153-//
154-// for Windows 32-bit
155-//
156-#include <windows.h>
157-
158-#define TIMER_ID 1
159-#define TIMER_INTERVAL 10
160-
161-struct BLD_WORK {
162- HINSTANCE hi;
163- HWND hw;
164- BITMAPINFO bmi;
165- int tmcount1, tmcount2, flags, smp; /* bit0: 終了 */
166- HANDLE mtx;
167- char *winClosed;
168-};
169-
170-struct BLD_WORK bld_work;
171-
172-struct BL_WIN {
173- int xsiz, ysiz, *buf;
174-};
175-
176-struct BL_WORK {
177- struct BL_WIN win;
178- jmp_buf jb;
179- int csiz_x, csiz_y, cx, cy, col0, col1, tabsiz, slctwin;
180- int tmcount, tmcount0, mod, rand_seed;
181- int *cbuf;
182- unsigned char *ftyp;
183- unsigned char **fptn;
184- int *ccol, *cbak;
185- int *kbuf, kbuf_rp, kbuf_wp, kbuf_c;
186-};
187-
188-struct BL_WORK bl_work;
189-
190-#define BL_SIZ_KBUF 8192
191-
192-#define BL_WAITKEYF 0x00000001
193-#define BL_WAITKEYNF 0x00000002
194-#define BL_WAITKEY 0x00000003
195-#define BL_GETKEY 0x00000004
196-#define BL_CLEARREP 0x00000008
197-#define BL_DELFFF 0x00000010
198-
199-#define BL_KEYMODE 0x00000000 // 作りかけ, make/remake/breakが見えるかどうか
200-
201-#define w bl_work
202-#define dw bld_work
203-
204-void bld_openWin(int x, int y, char *winClosed);
205-void bld_flshWin(int sx, int sy, int x0, int y0);
206-LRESULT CALLBACK WndProc(HWND hw, unsigned int msg, WPARAM wp, LPARAM lp);
207-void bl_cls();
208-int bl_iCol(int i);
209-void bl_readyWin(int n);
210-
211-static HANDLE threadhandle;
212-
213-int main(int argc, char **argv)
214-{
215- // Program entry point
216- return HeavyOSECPUMain(argc, argv);
217-}
218-
219-void *mallocRWE(int bytes)
220-{
221- void *p = malloc(bytes);
222- DWORD dmy;
223- VirtualProtect(p, bytes, PAGE_EXECUTE_READWRITE, &dmy);
224- return p;
225-}
226-
227-static int winthread(void *dmy)
228-{
229- WNDCLASSEX wc;
230- RECT r;
231- int i, x, y;
232- MSG msg;
233-
234- x = dw.bmi.bmiHeader.biWidth;
235- y = -dw.bmi.bmiHeader.biHeight;
236-
237- wc.cbSize = sizeof (WNDCLASSEX);
238- wc.style = CS_HREDRAW | CS_VREDRAW;
239- wc.lpfnWndProc = WndProc;
240- wc.cbClsExtra = 0;
241- wc.cbWndExtra = 0;
242- wc.hInstance = dw.hi;
243- wc.hIcon = (HICON)LoadImage(NULL, MAKEINTRESOURCE(IDI_APPLICATION),
244- IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
245- wc.hIconSm = wc.hIcon;
246- wc.hCursor = (HCURSOR)LoadImage(NULL, MAKEINTRESOURCE(IDC_ARROW),
247- IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
248- wc.hbrBackground = (HBRUSH)COLOR_APPWORKSPACE;
249- wc.lpszMenuName = NULL;
250- wc.lpszClassName = L"WinClass";
251- if (RegisterClassEx(&wc) == 0)
252- return 1;
253- r.left = 0;
254- r.top = 0;
255- r.right = x;
256- r.bottom = y;
257- AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW, FALSE);
258- x = r.right - r.left;
259- y = r.bottom - r.top;
260-
261- char *t = "osecpu";
262-
263- dw.hw = CreateWindowA("WinClass", t, WS_OVERLAPPEDWINDOW,
264- CW_USEDEFAULT, CW_USEDEFAULT, x, y, NULL, NULL, dw.hi, NULL);
265- if (dw.hw == NULL)
266- return 1;
267- ShowWindow(dw.hw, SW_SHOW);
268- UpdateWindow(dw.hw);
269- SetTimer(dw.hw, TIMER_ID, TIMER_INTERVAL, NULL);
270- SetTimer(dw.hw, TIMER_ID + 1, TIMER_INTERVAL * 10, NULL);
271- SetTimer(dw.hw, TIMER_ID + 2, TIMER_INTERVAL * 100, NULL);
272- dw.flags |= 2 | 4;
273-
274- for (;;) {
275- i = GetMessage(&msg, NULL, 0, 0);
276- if (i == 0 || i == -1) /* エラーもしくは終了メッセージ */
277- break;
278- /* そのほかはとりあえずデフォルト処理で */
279- TranslateMessage(&msg);
280- DispatchMessage(&msg);
281- }
282- // PostQuitMessage(0);
283- dw.flags |= 1; /* 終了, bld_waitNF()が見つける */
284- if (dw.winClosed != NULL)
285- *dw.winClosed = 1;
286- return 0;
287-}
288-
289-void bld_openWin(int sx, int sy, char *winClosed)
290-{
291- static int i;
292-
293- dw.bmi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
294- dw.bmi.bmiHeader.biWidth = sx;
295- dw.bmi.bmiHeader.biHeight = -sy;
296- dw.bmi.bmiHeader.biPlanes = 1;
297- dw.bmi.bmiHeader.biBitCount = 32;
298- dw.bmi.bmiHeader.biCompression = BI_RGB;
299- dw.winClosed = winClosed;
300-
301- threadhandle = CreateThread(NULL, 0, (void *)&winthread, NULL, 0, (void *)&i);
302-
303- return;
304-}
305-
306-void drv_flshWin(int sx, int sy, int x0, int y0)
307-{
308- InvalidateRect(dw.hw, NULL, FALSE);
309- UpdateWindow(dw.hw);
310- return;
311-}
312-
313-LRESULT CALLBACK WndProc(HWND hw, unsigned int msg, WPARAM wp, LPARAM lp)
314-{
315- int i, j;
316- if (msg == WM_PAINT) {
317- PAINTSTRUCT ps;
318- HDC hdc = BeginPaint(dw.hw, &ps);
319- SetDIBitsToDevice(hdc, 0, 0, w.win.xsiz, w.win.ysiz,
320- 0, 0, 0, w.win.ysiz, w.win.buf, &dw.bmi, DIB_RGB_COLORS);
321- EndPaint(dw.hw, &ps);
322- }
323- if (msg == WM_DESTROY) {
324- PostQuitMessage(0);
325- return 0;
326- }
327- if (msg == WM_TIMER && wp == TIMER_ID) {
328- w.tmcount += TIMER_INTERVAL;
329- return 0;
330- }
331- if (msg == WM_TIMER && wp == TIMER_ID + 1) {
332- dw.tmcount1 += TIMER_INTERVAL * 10;
333- w.tmcount = dw.tmcount1;
334- return 0;
335- }
336- if (msg == WM_TIMER && wp == TIMER_ID + 2) {
337- dw.tmcount2 += TIMER_INTERVAL * 100;
338- w.tmcount = dw.tmcount1 = dw.tmcount2;
339- return 0;
340- }
341- if (msg == WM_KEYDOWN || msg == WM_SYSKEYDOWN) {
342- i = -1;
343-
344- if (wp == VK_RETURN) i = KEY_ENTER;
345- if (wp == VK_ESCAPE) i = KEY_ESC;
346- if (wp == VK_BACK) i = KEY_BACKSPACE;
347- if (wp == VK_TAB) i = KEY_TAB;
348- if (wp == VK_PRIOR) i = KEY_PAGEUP;
349- if (wp == VK_NEXT) i = KEY_PAGEDWN;
350- if (wp == VK_END) i = KEY_END;
351- if (wp == VK_HOME) i = KEY_HOME;
352- if (wp == VK_LEFT) i = KEY_LEFT;
353- if (wp == VK_RIGHT) i = KEY_RIGHT;
354- if (wp == VK_UP) i = KEY_UP;
355- if (wp == VK_DOWN) i = KEY_DOWN;
356- if (wp == VK_INSERT) i = KEY_INS;
357- if (wp == VK_DELETE) i = KEY_DEL;
358- j &= 0;
359- if ((GetKeyState(VK_LCONTROL) & (1 << 15)) != 0) j |= 1 << 17;
360- if ((GetKeyState(VK_LMENU) & (1 << 15)) != 0) j |= 1 << 18;
361- if ((GetKeyState(VK_RCONTROL) & (1 << 15)) != 0) j |= 1 << 25;
362- if ((GetKeyState(VK_RMENU) & (1 << 15)) != 0) j |= 1 << 26;
363- if ((GetKeyState(VK_RSHIFT) & (1 << 15)) != 0) i |= 1 << 24;
364- if ((GetKeyState(VK_LSHIFT) & (1 << 15)) != 0) i |= 1 << 16;
365- if ((GetKeyState(VK_NUMLOCK) & (1 << 0)) != 0) i |= 1 << 22;
366- if ((GetKeyState(VK_CAPITAL) & (1 << 0)) != 0) i |= 1 << 23;
367- if (j != 0) {
368- if ('A' <= wp && wp <= 'Z') i = wp;
369- }
370- if (i != -1) {
371- putKeybuf(i | j);
372- // bl_putKeyB(1, &i);
373- return 0;
374- }
375- }
376- if (msg == WM_KEYUP) {
377- i = 0xfff;
378- // bl_putKeyB(1, &i);
379- }
380- if (msg == WM_CHAR) {
381- i = 0;
382- if (' ' <= wp && wp <= 0x7e) {
383- i = wp;
384- j &= 0;
385- if ((GetKeyState(VK_LCONTROL) & (1 << 15)) != 0) j |= 1 << 17;
386- if ((GetKeyState(VK_LMENU) & (1 << 15)) != 0) j |= 1 << 18;
387- if ((GetKeyState(VK_RCONTROL) & (1 << 15)) != 0) j |= 1 << 25;
388- if ((GetKeyState(VK_RMENU) & (1 << 15)) != 0) j |= 1 << 26;
389- if ((GetKeyState(VK_RSHIFT) & (1 << 15)) != 0) i |= 1 << 24;
390- if ((GetKeyState(VK_LSHIFT) & (1 << 15)) != 0) i |= 1 << 16;
391- if ((GetKeyState(VK_NUMLOCK) & (1 << 0)) != 0) i |= 1 << 22;
392- if ((GetKeyState(VK_CAPITAL) & (1 << 0)) != 0) i |= 1 << 23;
393- if (('A' <= wp && wp <= 'Z') || ('a' <= wp && wp <= 'z')) {
394- if (j != 0) {
395- i |= j;
396- i &= ~0x20;
397- }
398- }
399- putKeybuf(i);
400- // bl_putKeyB(1, &i);
401- return 0;
402- }
403- }
404- return DefWindowProc(hw, msg, wp, lp);
405-}
406-
407-void drv_openWin(int sx, int sy, UCHAR *buf, char *winClosed)
408-{
409- w.win.buf = (int *)buf;
410- w.win.xsiz = sx;
411- w.win.ysiz = sy;
412- bld_openWin(sx, sy, winClosed);
413- return;
414-}
415-
416-void drv_sleep(int msec)
417-{
418- Sleep(msec);
419- // MsgWaitForMultipleObjects(1, &threadhandle, FALSE, msec, QS_ALLINPUT);
420- /* 勉強不足でまだ書き方が分かりません! */
421- return;
422-}
423-
424-#else
425-
426-#error "Illegal OS type. Edit osecpu.h and look at DRV_OSNUM"
427-
1+#include "osecpu.h"
2+
3+
4+#if (DRV_OSNUM == 0x0002)
5+//
6+// for Mac OSX 32-bit
7+//
8+#include <mach/mach.h>
9+#include <Cocoa/Cocoa.h>
10+
11+void *mallocRWE(int bytes)
12+{
13+ void *p = malloc(bytes);
14+ vm_protect(mach_task_self(), (vm_address_t) p, bytes, FALSE, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE);
15+ return p;
16+}
17+
18+NSApplication* app;
19+
20+@interface OSECPUView : NSView
21+{
22+ unsigned char *_buf;
23+ int _sx;
24+ int _sy;
25+ CGContextRef _context;
26+}
27+
28+- (id)initWithFrame:(NSRect)frameRect buf:(unsigned char *)buf sx:(int)sx sy:(int)sy;
29+- (void)drawRect:(NSRect)rect;
30+@end
31+
32+@implementation OSECPUView
33+- (id)initWithFrame:(NSRect)frameRect buf:(unsigned char *)buf sx:(int)sx sy:(int)sy
34+{
35+ self = [super initWithFrame:frameRect];
36+ if (self) {
37+ _buf = buf;
38+ _sx = sx;
39+ _sy = sy;
40+ }
41+ return self;
42+}
43+
44+- (void)drawRect:(NSRect)rect {
45+ CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
46+ _context = CGBitmapContextCreate (_buf, _sx, _sy, 8, 4 * _sx, colorSpace, (kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst));
47+ CGImageRef image = CGBitmapContextCreateImage(_context);
48+ CGContextRef currentContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
49+ CGContextDrawImage(currentContext, NSRectToCGRect(rect), image);
50+
51+ CFRelease(colorSpace);
52+ CFRelease(image);
53+}
54+
55+@end
56+
57+@interface Main : NSObject<NSWindowDelegate>
58+{
59+ int argc;
60+ const unsigned char **argv;
61+ char *winClosed;
62+ OSECPUView *_view;
63+}
64+
65+- (void)runApp;
66+- (void)createThread:(int)_argc args:(const unsigned char **)_argv;
67+- (BOOL)windowShouldClose:(id)sender;
68+- (void)openWin:(unsigned char *)buf sx:(int)sx sy:(int)sy winClosed:(char *)_winClosed;
69+- (void)flushWin:(NSRect)rect;
70+@end
71+
72+@implementation Main
73+- (void)runApp
74+{
75+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
76+ HeavyOSECPUMain(argc, (char **)argv);
77+ [NSApp terminate:self];
78+ [pool release];
79+}
80+
81+- (void)createThread : (int)_argc args:(const unsigned char **)_argv
82+{
83+ argc = _argc;
84+ argv = _argv;
85+ NSThread *thread = [[[NSThread alloc] initWithTarget:self selector:@selector(runApp) object:nil] autorelease];
86+ [thread start];
87+}
88+
89+- (BOOL)windowShouldClose:(id)sender
90+{
91+ *winClosed = 1;
92+ return YES;
93+}
94+
95+- (void)openWin:(unsigned char *)buf sx:(int)sx sy:(int) sy winClosed:(char *)_winClosed
96+{
97+
98+ NSWindow* window = [[NSWindow alloc] initWithContentRect: NSMakeRect(0, 0, sx, sy) styleMask: NSTitledWindowMask | NSMiniaturizableWindowMask | NSClosableWindowMask backing: NSBackingStoreBuffered defer: NO];
99+ [window setTitle: @"osecpu"];
100+ [window center];
101+ [window makeKeyAndOrderFront:nil];
102+ [window setReleasedWhenClosed:YES];
103+ window.delegate = self;
104+ winClosed = _winClosed;
105+
106+ _view = [[OSECPUView alloc] initWithFrame:NSMakeRect(0,0,sx,sy) buf:buf sx:sx sy:sy];
107+ [window.contentView addSubview:_view];
108+}
109+
110+- (void)flushWin : (NSRect)rect
111+{
112+ [_view drawRect:rect];
113+}
114+
115+@end
116+
117+id objc_main;
118+
119+int main(int argc, char **argv)
120+{
121+ objc_main = [[Main alloc] init];
122+
123+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
124+ app = [[NSApplication alloc] init];
125+ [objc_main createThread:argc args:(const unsigned char **)argv];
126+ [app run];
127+ [pool release];
128+ return 0;
129+}
130+
131+void drv_openWin(int sx, int sy, unsigned char *buf, char *winClosed)
132+{
133+ [objc_main openWin:buf sx:sx sy:sy winClosed:winClosed];
134+}
135+
136+void drv_flshWin(int sx, int sy, int x0, int y0)
137+{
138+ [objc_main flushWin:NSMakeRect(x0,y0,sx,sy)];
139+}
140+
141+void drv_sleep(int msec)
142+{
143+ [NSThread sleepForTimeInterval:0.001*msec];
144+ return;
145+}
146+
147+
148+#elif (DRV_OSNUM == 0x0003)
149+
150+#error "Your OS is not supported."
151+
152+#elif (DRV_OSNUM == 0x0001)
153+//
154+// for Windows 32-bit
155+//
156+#include <windows.h>
157+
158+#define TIMER_ID 1
159+#define TIMER_INTERVAL 10
160+
161+struct BLD_WORK {
162+ HINSTANCE hi;
163+ HWND hw;
164+ BITMAPINFO bmi;
165+ int tmcount1, tmcount2, flags, smp; /* bit0: 終了 */
166+ HANDLE mtx;
167+ char *winClosed;
168+};
169+
170+struct BLD_WORK bld_work;
171+
172+struct BL_WIN {
173+ int xsiz, ysiz, *buf;
174+};
175+
176+struct BL_WORK {
177+ struct BL_WIN win;
178+ jmp_buf jb;
179+ int csiz_x, csiz_y, cx, cy, col0, col1, tabsiz, slctwin;
180+ int tmcount, tmcount0, mod, rand_seed;
181+ int *cbuf;
182+ unsigned char *ftyp;
183+ unsigned char **fptn;
184+ int *ccol, *cbak;
185+ int *kbuf, kbuf_rp, kbuf_wp, kbuf_c;
186+};
187+
188+struct BL_WORK bl_work;
189+
190+#define BL_SIZ_KBUF 8192
191+
192+#define BL_WAITKEYF 0x00000001
193+#define BL_WAITKEYNF 0x00000002
194+#define BL_WAITKEY 0x00000003
195+#define BL_GETKEY 0x00000004
196+#define BL_CLEARREP 0x00000008
197+#define BL_DELFFF 0x00000010
198+
199+#define BL_KEYMODE 0x00000000 // 作りかけ, make/remake/breakが見えるかどうか
200+
201+#define w bl_work
202+#define dw bld_work
203+
204+void bld_openWin(int x, int y, char *winClosed);
205+void bld_flshWin(int sx, int sy, int x0, int y0);
206+LRESULT CALLBACK WndProc(HWND hw, unsigned int msg, WPARAM wp, LPARAM lp);
207+void bl_cls();
208+int bl_iCol(int i);
209+void bl_readyWin(int n);
210+
211+static HANDLE threadhandle;
212+
213+int main(int argc, char **argv)
214+{
215+ // Program entry point
216+ return HeavyOSECPUMain(argc, argv);
217+}
218+
219+void *mallocRWE(int bytes)
220+{
221+ void *p = malloc(bytes);
222+ DWORD dmy;
223+ VirtualProtect(p, bytes, PAGE_EXECUTE_READWRITE, &dmy);
224+ return p;
225+}
226+
227+static int winthread(void *dmy)
228+{
229+ WNDCLASSEX wc;
230+ RECT r;
231+ int i, x, y;
232+ MSG msg;
233+
234+ x = dw.bmi.bmiHeader.biWidth;
235+ y = -dw.bmi.bmiHeader.biHeight;
236+
237+ wc.cbSize = sizeof (WNDCLASSEX);
238+ wc.style = CS_HREDRAW | CS_VREDRAW;
239+ wc.lpfnWndProc = WndProc;
240+ wc.cbClsExtra = 0;
241+ wc.cbWndExtra = 0;
242+ wc.hInstance = dw.hi;
243+ wc.hIcon = (HICON)LoadImage(NULL, MAKEINTRESOURCE(IDI_APPLICATION),
244+ IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
245+ wc.hIconSm = wc.hIcon;
246+ wc.hCursor = (HCURSOR)LoadImage(NULL, MAKEINTRESOURCE(IDC_ARROW),
247+ IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
248+ wc.hbrBackground = (HBRUSH)COLOR_APPWORKSPACE;
249+ wc.lpszMenuName = NULL;
250+ wc.lpszClassName = "WinClass";
251+ if (RegisterClassEx(&wc) == 0)
252+ return 1;
253+ r.left = 0;
254+ r.top = 0;
255+ r.right = x;
256+ r.bottom = y;
257+ AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW, FALSE);
258+ x = r.right - r.left;
259+ y = r.bottom - r.top;
260+
261+ char *t = "osecpu";
262+
263+ dw.hw = CreateWindowA("WinClass", t, WS_OVERLAPPEDWINDOW,
264+ CW_USEDEFAULT, CW_USEDEFAULT, x, y, NULL, NULL, dw.hi, NULL);
265+ if (dw.hw == NULL)
266+ return 1;
267+ ShowWindow(dw.hw, SW_SHOW);
268+ UpdateWindow(dw.hw);
269+ SetTimer(dw.hw, TIMER_ID, TIMER_INTERVAL, NULL);
270+ SetTimer(dw.hw, TIMER_ID + 1, TIMER_INTERVAL * 10, NULL);
271+ SetTimer(dw.hw, TIMER_ID + 2, TIMER_INTERVAL * 100, NULL);
272+ dw.flags |= 2 | 4;
273+
274+ for (;;) {
275+ i = GetMessage(&msg, NULL, 0, 0);
276+ if (i == 0 || i == -1) /* エラーもしくは終了メッセージ */
277+ break;
278+ /* そのほかはとりあえずデフォルト処理で */
279+ TranslateMessage(&msg);
280+ DispatchMessage(&msg);
281+ }
282+ // PostQuitMessage(0);
283+ dw.flags |= 1; /* 終了, bld_waitNF()が見つける */
284+ if (dw.winClosed != NULL)
285+ *dw.winClosed = 1;
286+ return 0;
287+}
288+
289+void bld_openWin(int sx, int sy, char *winClosed)
290+{
291+ static int i;
292+
293+ dw.bmi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
294+ dw.bmi.bmiHeader.biWidth = sx;
295+ dw.bmi.bmiHeader.biHeight = -sy;
296+ dw.bmi.bmiHeader.biPlanes = 1;
297+ dw.bmi.bmiHeader.biBitCount = 32;
298+ dw.bmi.bmiHeader.biCompression = BI_RGB;
299+ dw.winClosed = winClosed;
300+
301+ threadhandle = CreateThread(NULL, 0, (void *)&winthread, NULL, 0, (void *)&i);
302+
303+ return;
304+}
305+
306+void drv_flshWin(int sx, int sy, int x0, int y0)
307+{
308+ InvalidateRect(dw.hw, NULL, FALSE);
309+ UpdateWindow(dw.hw);
310+ return;
311+}
312+
313+LRESULT CALLBACK WndProc(HWND hw, unsigned int msg, WPARAM wp, LPARAM lp)
314+{
315+ int i, j;
316+ if (msg == WM_PAINT) {
317+ PAINTSTRUCT ps;
318+ HDC hdc = BeginPaint(dw.hw, &ps);
319+ SetDIBitsToDevice(hdc, 0, 0, w.win.xsiz, w.win.ysiz,
320+ 0, 0, 0, w.win.ysiz, w.win.buf, &dw.bmi, DIB_RGB_COLORS);
321+ EndPaint(dw.hw, &ps);
322+ }
323+ if (msg == WM_DESTROY) {
324+ PostQuitMessage(0);
325+ return 0;
326+ }
327+ if (msg == WM_TIMER && wp == TIMER_ID) {
328+ w.tmcount += TIMER_INTERVAL;
329+ return 0;
330+ }
331+ if (msg == WM_TIMER && wp == TIMER_ID + 1) {
332+ dw.tmcount1 += TIMER_INTERVAL * 10;
333+ w.tmcount = dw.tmcount1;
334+ return 0;
335+ }
336+ if (msg == WM_TIMER && wp == TIMER_ID + 2) {
337+ dw.tmcount2 += TIMER_INTERVAL * 100;
338+ w.tmcount = dw.tmcount1 = dw.tmcount2;
339+ return 0;
340+ }
341+ if (msg == WM_KEYDOWN || msg == WM_SYSKEYDOWN) {
342+ i = -1;
343+
344+ if (wp == VK_RETURN) i = KEY_ENTER;
345+ if (wp == VK_ESCAPE) i = KEY_ESC;
346+ if (wp == VK_BACK) i = KEY_BACKSPACE;
347+ if (wp == VK_TAB) i = KEY_TAB;
348+ if (wp == VK_PRIOR) i = KEY_PAGEUP;
349+ if (wp == VK_NEXT) i = KEY_PAGEDWN;
350+ if (wp == VK_END) i = KEY_END;
351+ if (wp == VK_HOME) i = KEY_HOME;
352+ if (wp == VK_LEFT) i = KEY_LEFT;
353+ if (wp == VK_RIGHT) i = KEY_RIGHT;
354+ if (wp == VK_UP) i = KEY_UP;
355+ if (wp == VK_DOWN) i = KEY_DOWN;
356+ if (wp == VK_INSERT) i = KEY_INS;
357+ if (wp == VK_DELETE) i = KEY_DEL;
358+ j &= 0;
359+ if ((GetKeyState(VK_LCONTROL) & (1 << 15)) != 0) j |= 1 << 17;
360+ if ((GetKeyState(VK_LMENU) & (1 << 15)) != 0) j |= 1 << 18;
361+ if ((GetKeyState(VK_RCONTROL) & (1 << 15)) != 0) j |= 1 << 25;
362+ if ((GetKeyState(VK_RMENU) & (1 << 15)) != 0) j |= 1 << 26;
363+ if ((GetKeyState(VK_RSHIFT) & (1 << 15)) != 0) i |= 1 << 24;
364+ if ((GetKeyState(VK_LSHIFT) & (1 << 15)) != 0) i |= 1 << 16;
365+ if ((GetKeyState(VK_NUMLOCK) & (1 << 0)) != 0) i |= 1 << 22;
366+ if ((GetKeyState(VK_CAPITAL) & (1 << 0)) != 0) i |= 1 << 23;
367+ if (j != 0) {
368+ if ('A' <= wp && wp <= 'Z') i = wp;
369+ }
370+ if (i != -1) {
371+ putKeybuf(i | j);
372+ // bl_putKeyB(1, &i);
373+ return 0;
374+ }
375+ }
376+ if (msg == WM_KEYUP) {
377+ i = 0xfff;
378+ // bl_putKeyB(1, &i);
379+ }
380+ if (msg == WM_CHAR) {
381+ i = 0;
382+ if (' ' <= wp && wp <= 0x7e) {
383+ i = wp;
384+ j &= 0;
385+ if ((GetKeyState(VK_LCONTROL) & (1 << 15)) != 0) j |= 1 << 17;
386+ if ((GetKeyState(VK_LMENU) & (1 << 15)) != 0) j |= 1 << 18;
387+ if ((GetKeyState(VK_RCONTROL) & (1 << 15)) != 0) j |= 1 << 25;
388+ if ((GetKeyState(VK_RMENU) & (1 << 15)) != 0) j |= 1 << 26;
389+ if ((GetKeyState(VK_RSHIFT) & (1 << 15)) != 0) i |= 1 << 24;
390+ if ((GetKeyState(VK_LSHIFT) & (1 << 15)) != 0) i |= 1 << 16;
391+ if ((GetKeyState(VK_NUMLOCK) & (1 << 0)) != 0) i |= 1 << 22;
392+ if ((GetKeyState(VK_CAPITAL) & (1 << 0)) != 0) i |= 1 << 23;
393+ if (('A' <= wp && wp <= 'Z') || ('a' <= wp && wp <= 'z')) {
394+ if (j != 0) {
395+ i |= j;
396+ i &= ~0x20;
397+ }
398+ }
399+ putKeybuf(i);
400+ // bl_putKeyB(1, &i);
401+ return 0;
402+ }
403+ }
404+ return DefWindowProc(hw, msg, wp, lp);
405+}
406+
407+void drv_openWin(int sx, int sy, UCHAR *buf, char *winClosed)
408+{
409+ w.win.buf = (int *)buf;
410+ w.win.xsiz = sx;
411+ w.win.ysiz = sy;
412+ bld_openWin(sx, sy, winClosed);
413+ return;
414+}
415+
416+void drv_sleep(int msec)
417+{
418+ Sleep(msec);
419+ // MsgWaitForMultipleObjects(1, &threadhandle, FALSE, msec, QS_ALLINPUT);
420+ /* 勉強不足でまだ書き方が分かりません! */
421+ return;
422+}
423+
424+#else
425+
426+#error "Illegal OS type. Edit osecpu.h and look at DRV_OSNUM"
427+
428428 #endif
\ No newline at end of file
--- a/fontdata.c
+++ b/fontdata.c
@@ -1,99 +1,99 @@
1-
2-unsigned char fontdata[] = {
3- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4- 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,
5- 0x28, 0x28, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6- 0x00, 0x44, 0x44, 0x44, 0xfe, 0x44, 0x44, 0x44, 0x44, 0x44, 0xfe, 0x44, 0x44, 0x44, 0x00, 0x00,
7- 0x10, 0x3a, 0x56, 0x92, 0x92, 0x90, 0x50, 0x38, 0x14, 0x12, 0x92, 0x92, 0xd4, 0xb8, 0x10, 0x10,
8- 0x62, 0x92, 0x94, 0x94, 0x68, 0x08, 0x10, 0x10, 0x20, 0x2c, 0x52, 0x52, 0x92, 0x8c, 0x00, 0x00,
9- 0x00, 0x70, 0x88, 0x88, 0x88, 0x90, 0x60, 0x47, 0xa2, 0x92, 0x8a, 0x84, 0x46, 0x39, 0x00, 0x00,
10- 0x04, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11- 0x02, 0x04, 0x08, 0x08, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x04, 0x02, 0x00,
12- 0x80, 0x40, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x40, 0x80, 0x00,
13- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x92, 0x54, 0x38, 0x54, 0x92, 0x10, 0x00, 0x00, 0x00, 0x00,
14- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0xfe, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
15- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x08, 0x08, 0x10,
16- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
17- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
18- 0x02, 0x02, 0x04, 0x04, 0x08, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x40, 0x80, 0x80,
19- 0x00, 0x18, 0x24, 0x24, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x24, 0x24, 0x18, 0x00, 0x00,
20- 0x00, 0x08, 0x18, 0x28, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00,
21- 0x00, 0x18, 0x24, 0x42, 0x42, 0x02, 0x04, 0x08, 0x10, 0x20, 0x20, 0x40, 0x40, 0x7e, 0x00, 0x00,
22- 0x00, 0x18, 0x24, 0x42, 0x02, 0x02, 0x04, 0x18, 0x04, 0x02, 0x02, 0x42, 0x24, 0x18, 0x00, 0x00,
23- 0x00, 0x0c, 0x0c, 0x0c, 0x14, 0x14, 0x14, 0x24, 0x24, 0x44, 0x7e, 0x04, 0x04, 0x1e, 0x00, 0x00,
24- 0x00, 0x7c, 0x40, 0x40, 0x40, 0x58, 0x64, 0x02, 0x02, 0x02, 0x02, 0x42, 0x24, 0x18, 0x00, 0x00,
25- 0x00, 0x18, 0x24, 0x42, 0x40, 0x58, 0x64, 0x42, 0x42, 0x42, 0x42, 0x42, 0x24, 0x18, 0x00, 0x00,
26- 0x00, 0x7e, 0x42, 0x42, 0x04, 0x04, 0x08, 0x08, 0x08, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00,
27- 0x00, 0x18, 0x24, 0x42, 0x42, 0x42, 0x24, 0x18, 0x24, 0x42, 0x42, 0x42, 0x24, 0x18, 0x00, 0x00,
28- 0x00, 0x18, 0x24, 0x42, 0x42, 0x42, 0x42, 0x42, 0x26, 0x1a, 0x02, 0x42, 0x24, 0x18, 0x00, 0x00,
29- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
30- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x08, 0x08, 0x10,
31- 0x00, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x00,
32- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
33- 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00,
34- 0x00, 0x38, 0x44, 0x82, 0x82, 0x82, 0x04, 0x08, 0x10, 0x10, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
35- 0x00, 0x38, 0x44, 0x82, 0x9a, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x9c, 0x80, 0x46, 0x38, 0x00, 0x00,
36- 0x00, 0x18, 0x18, 0x18, 0x18, 0x24, 0x24, 0x24, 0x24, 0x7e, 0x42, 0x42, 0x42, 0xe7, 0x00, 0x00,
37- 0x00, 0xf0, 0x48, 0x44, 0x44, 0x44, 0x48, 0x78, 0x44, 0x42, 0x42, 0x42, 0x44, 0xf8, 0x00, 0x00,
38- 0x00, 0x3a, 0x46, 0x42, 0x82, 0x80, 0x80, 0x80, 0x80, 0x80, 0x82, 0x42, 0x44, 0x38, 0x00, 0x00,
39- 0x00, 0xf8, 0x44, 0x44, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x44, 0x44, 0xf8, 0x00, 0x00,
40- 0x00, 0xfe, 0x42, 0x42, 0x40, 0x40, 0x44, 0x7c, 0x44, 0x40, 0x40, 0x42, 0x42, 0xfe, 0x00, 0x00,
41- 0x00, 0xfe, 0x42, 0x42, 0x40, 0x40, 0x44, 0x7c, 0x44, 0x44, 0x40, 0x40, 0x40, 0xf0, 0x00, 0x00,
42- 0x00, 0x3a, 0x46, 0x42, 0x82, 0x80, 0x80, 0x9e, 0x82, 0x82, 0x82, 0x42, 0x46, 0x38, 0x00, 0x00,
43- 0x00, 0xe7, 0x42, 0x42, 0x42, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x42, 0xe7, 0x00, 0x00,
44- 0x00, 0x7c, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x7c, 0x00, 0x00,
45- 0x00, 0x1f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x84, 0x48, 0x30, 0x00,
46- 0x00, 0xe7, 0x42, 0x44, 0x48, 0x50, 0x50, 0x60, 0x50, 0x50, 0x48, 0x44, 0x42, 0xe7, 0x00, 0x00,
47- 0x00, 0xf0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x42, 0x42, 0xfe, 0x00, 0x00,
48- 0x00, 0xc3, 0x42, 0x66, 0x66, 0x66, 0x5a, 0x5a, 0x5a, 0x42, 0x42, 0x42, 0x42, 0xe7, 0x00, 0x00,
49- 0x00, 0xc7, 0x42, 0x62, 0x62, 0x52, 0x52, 0x52, 0x4a, 0x4a, 0x4a, 0x46, 0x46, 0xe2, 0x00, 0x00,
50- 0x00, 0x38, 0x44, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x44, 0x38, 0x00, 0x00,
51- 0x00, 0xf8, 0x44, 0x42, 0x42, 0x42, 0x44, 0x78, 0x40, 0x40, 0x40, 0x40, 0x40, 0xf0, 0x00, 0x00,
52- 0x00, 0x38, 0x44, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x92, 0x8a, 0x44, 0x3a, 0x00, 0x00,
53- 0x00, 0xfc, 0x42, 0x42, 0x42, 0x42, 0x7c, 0x44, 0x42, 0x42, 0x42, 0x42, 0x42, 0xe7, 0x00, 0x00,
54- 0x00, 0x3a, 0x46, 0x82, 0x82, 0x80, 0x40, 0x38, 0x04, 0x02, 0x82, 0x82, 0xc4, 0xb8, 0x00, 0x00,
55- 0x00, 0xfe, 0x92, 0x92, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x7c, 0x00, 0x00,
56- 0x00, 0xe7, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x24, 0x3c, 0x00, 0x00,
57- 0x00, 0xe7, 0x42, 0x42, 0x42, 0x42, 0x24, 0x24, 0x24, 0x24, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00,
58- 0x00, 0xe7, 0x42, 0x42, 0x42, 0x5a, 0x5a, 0x5a, 0x5a, 0x24, 0x24, 0x24, 0x24, 0x24, 0x00, 0x00,
59- 0x00, 0xe7, 0x42, 0x42, 0x24, 0x24, 0x24, 0x18, 0x24, 0x24, 0x24, 0x42, 0x42, 0xe7, 0x00, 0x00,
60- 0x00, 0xee, 0x44, 0x44, 0x44, 0x28, 0x28, 0x28, 0x10, 0x10, 0x10, 0x10, 0x10, 0x7c, 0x00, 0x00,
61- 0x00, 0xfe, 0x84, 0x84, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x42, 0x82, 0xfe, 0x00, 0x00,
62- 0x00, 0x3e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3e, 0x00,
63- 0x80, 0x80, 0x40, 0x40, 0x20, 0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x04, 0x04, 0x02, 0x02,
64- 0x00, 0x7c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x7c, 0x00,
65- 0x00, 0x10, 0x28, 0x44, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
66- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00,
67- 0x10, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68- 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x08, 0x04, 0x3c, 0x44, 0x84, 0x84, 0x8c, 0x76, 0x00, 0x00,
69- 0xc0, 0x40, 0x40, 0x40, 0x40, 0x58, 0x64, 0x42, 0x42, 0x42, 0x42, 0x42, 0x64, 0x58, 0x00, 0x00,
70- 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x4c, 0x84, 0x84, 0x80, 0x80, 0x82, 0x44, 0x38, 0x00, 0x00,
71- 0x0c, 0x04, 0x04, 0x04, 0x04, 0x34, 0x4c, 0x84, 0x84, 0x84, 0x84, 0x84, 0x4c, 0x36, 0x00, 0x00,
72- 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x82, 0x82, 0xfc, 0x80, 0x82, 0x42, 0x3c, 0x00, 0x00,
73- 0x0e, 0x10, 0x10, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x7c, 0x00, 0x00,
74- 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x4c, 0x84, 0x84, 0x84, 0x84, 0x4c, 0x34, 0x04, 0x04, 0x78,
75- 0xc0, 0x40, 0x40, 0x40, 0x40, 0x58, 0x64, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0xe3, 0x00, 0x00,
76- 0x00, 0x10, 0x10, 0x00, 0x00, 0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00,
77- 0x00, 0x04, 0x04, 0x00, 0x00, 0x0c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x08, 0x30,
78- 0xc0, 0x40, 0x40, 0x40, 0x40, 0x4e, 0x44, 0x48, 0x50, 0x60, 0x50, 0x48, 0x44, 0xe6, 0x00, 0x00,
79- 0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00,
80- 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0xdb, 0x00, 0x00,
81- 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x64, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0xe3, 0x00, 0x00,
82- 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x82, 0x82, 0x82, 0x82, 0x82, 0x44, 0x38, 0x00, 0x00,
83- 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x64, 0x42, 0x42, 0x42, 0x42, 0x42, 0x64, 0x58, 0x40, 0xe0,
84- 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x4c, 0x84, 0x84, 0x84, 0x84, 0x84, 0x4c, 0x34, 0x04, 0x0e,
85- 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x62, 0x42, 0x40, 0x40, 0x40, 0x40, 0x40, 0xe0, 0x00, 0x00,
86- 0x00, 0x00, 0x00, 0x00, 0x00, 0x7a, 0x86, 0x82, 0xc0, 0x38, 0x06, 0x82, 0xc2, 0xbc, 0x00, 0x00,
87- 0x00, 0x00, 0x10, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0e, 0x00, 0x00,
88- 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x46, 0x3b, 0x00, 0x00,
89- 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x42, 0x42, 0x42, 0x24, 0x24, 0x24, 0x18, 0x18, 0x00, 0x00,
90- 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x42, 0x42, 0x5a, 0x5a, 0x5a, 0x24, 0x24, 0x24, 0x00, 0x00,
91- 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x44, 0x28, 0x28, 0x10, 0x28, 0x28, 0x44, 0xc6, 0x00, 0x00,
92- 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x42, 0x42, 0x24, 0x24, 0x24, 0x18, 0x18, 0x10, 0x10, 0x60,
93- 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x82, 0x84, 0x08, 0x10, 0x20, 0x42, 0x82, 0xfe, 0x00, 0x00,
94- 0x00, 0x06, 0x08, 0x10, 0x10, 0x10, 0x10, 0x60, 0x10, 0x10, 0x10, 0x10, 0x08, 0x06, 0x00, 0x00,
95- 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
96- 0x00, 0x60, 0x10, 0x08, 0x08, 0x08, 0x08, 0x06, 0x08, 0x08, 0x08, 0x08, 0x10, 0x60, 0x00, 0x00,
97- 0x00, 0x72, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
98- 0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0x44, 0x82, 0xfe, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00
99-};
1+
2+unsigned char fontdata[] = {
3+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4+ 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,
5+ 0x28, 0x28, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6+ 0x00, 0x44, 0x44, 0x44, 0xfe, 0x44, 0x44, 0x44, 0x44, 0x44, 0xfe, 0x44, 0x44, 0x44, 0x00, 0x00,
7+ 0x10, 0x3a, 0x56, 0x92, 0x92, 0x90, 0x50, 0x38, 0x14, 0x12, 0x92, 0x92, 0xd4, 0xb8, 0x10, 0x10,
8+ 0x62, 0x92, 0x94, 0x94, 0x68, 0x08, 0x10, 0x10, 0x20, 0x2c, 0x52, 0x52, 0x92, 0x8c, 0x00, 0x00,
9+ 0x00, 0x70, 0x88, 0x88, 0x88, 0x90, 0x60, 0x47, 0xa2, 0x92, 0x8a, 0x84, 0x46, 0x39, 0x00, 0x00,
10+ 0x04, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11+ 0x02, 0x04, 0x08, 0x08, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x04, 0x02, 0x00,
12+ 0x80, 0x40, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x40, 0x80, 0x00,
13+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x92, 0x54, 0x38, 0x54, 0x92, 0x10, 0x00, 0x00, 0x00, 0x00,
14+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0xfe, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
15+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x08, 0x08, 0x10,
16+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
17+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
18+ 0x02, 0x02, 0x04, 0x04, 0x08, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x40, 0x80, 0x80,
19+ 0x00, 0x18, 0x24, 0x24, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x24, 0x24, 0x18, 0x00, 0x00,
20+ 0x00, 0x08, 0x18, 0x28, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00,
21+ 0x00, 0x18, 0x24, 0x42, 0x42, 0x02, 0x04, 0x08, 0x10, 0x20, 0x20, 0x40, 0x40, 0x7e, 0x00, 0x00,
22+ 0x00, 0x18, 0x24, 0x42, 0x02, 0x02, 0x04, 0x18, 0x04, 0x02, 0x02, 0x42, 0x24, 0x18, 0x00, 0x00,
23+ 0x00, 0x0c, 0x0c, 0x0c, 0x14, 0x14, 0x14, 0x24, 0x24, 0x44, 0x7e, 0x04, 0x04, 0x1e, 0x00, 0x00,
24+ 0x00, 0x7c, 0x40, 0x40, 0x40, 0x58, 0x64, 0x02, 0x02, 0x02, 0x02, 0x42, 0x24, 0x18, 0x00, 0x00,
25+ 0x00, 0x18, 0x24, 0x42, 0x40, 0x58, 0x64, 0x42, 0x42, 0x42, 0x42, 0x42, 0x24, 0x18, 0x00, 0x00,
26+ 0x00, 0x7e, 0x42, 0x42, 0x04, 0x04, 0x08, 0x08, 0x08, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00,
27+ 0x00, 0x18, 0x24, 0x42, 0x42, 0x42, 0x24, 0x18, 0x24, 0x42, 0x42, 0x42, 0x24, 0x18, 0x00, 0x00,
28+ 0x00, 0x18, 0x24, 0x42, 0x42, 0x42, 0x42, 0x42, 0x26, 0x1a, 0x02, 0x42, 0x24, 0x18, 0x00, 0x00,
29+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
30+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x08, 0x08, 0x10,
31+ 0x00, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x00,
32+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
33+ 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00,
34+ 0x00, 0x38, 0x44, 0x82, 0x82, 0x82, 0x04, 0x08, 0x10, 0x10, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
35+ 0x00, 0x38, 0x44, 0x82, 0x9a, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x9c, 0x80, 0x46, 0x38, 0x00, 0x00,
36+ 0x00, 0x18, 0x18, 0x18, 0x18, 0x24, 0x24, 0x24, 0x24, 0x7e, 0x42, 0x42, 0x42, 0xe7, 0x00, 0x00,
37+ 0x00, 0xf0, 0x48, 0x44, 0x44, 0x44, 0x48, 0x78, 0x44, 0x42, 0x42, 0x42, 0x44, 0xf8, 0x00, 0x00,
38+ 0x00, 0x3a, 0x46, 0x42, 0x82, 0x80, 0x80, 0x80, 0x80, 0x80, 0x82, 0x42, 0x44, 0x38, 0x00, 0x00,
39+ 0x00, 0xf8, 0x44, 0x44, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x44, 0x44, 0xf8, 0x00, 0x00,
40+ 0x00, 0xfe, 0x42, 0x42, 0x40, 0x40, 0x44, 0x7c, 0x44, 0x40, 0x40, 0x42, 0x42, 0xfe, 0x00, 0x00,
41+ 0x00, 0xfe, 0x42, 0x42, 0x40, 0x40, 0x44, 0x7c, 0x44, 0x44, 0x40, 0x40, 0x40, 0xf0, 0x00, 0x00,
42+ 0x00, 0x3a, 0x46, 0x42, 0x82, 0x80, 0x80, 0x9e, 0x82, 0x82, 0x82, 0x42, 0x46, 0x38, 0x00, 0x00,
43+ 0x00, 0xe7, 0x42, 0x42, 0x42, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x42, 0xe7, 0x00, 0x00,
44+ 0x00, 0x7c, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x7c, 0x00, 0x00,
45+ 0x00, 0x1f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x84, 0x48, 0x30, 0x00,
46+ 0x00, 0xe7, 0x42, 0x44, 0x48, 0x50, 0x50, 0x60, 0x50, 0x50, 0x48, 0x44, 0x42, 0xe7, 0x00, 0x00,
47+ 0x00, 0xf0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x42, 0x42, 0xfe, 0x00, 0x00,
48+ 0x00, 0xc3, 0x42, 0x66, 0x66, 0x66, 0x5a, 0x5a, 0x5a, 0x42, 0x42, 0x42, 0x42, 0xe7, 0x00, 0x00,
49+ 0x00, 0xc7, 0x42, 0x62, 0x62, 0x52, 0x52, 0x52, 0x4a, 0x4a, 0x4a, 0x46, 0x46, 0xe2, 0x00, 0x00,
50+ 0x00, 0x38, 0x44, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x44, 0x38, 0x00, 0x00,
51+ 0x00, 0xf8, 0x44, 0x42, 0x42, 0x42, 0x44, 0x78, 0x40, 0x40, 0x40, 0x40, 0x40, 0xf0, 0x00, 0x00,
52+ 0x00, 0x38, 0x44, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x92, 0x8a, 0x44, 0x3a, 0x00, 0x00,
53+ 0x00, 0xfc, 0x42, 0x42, 0x42, 0x42, 0x7c, 0x44, 0x42, 0x42, 0x42, 0x42, 0x42, 0xe7, 0x00, 0x00,
54+ 0x00, 0x3a, 0x46, 0x82, 0x82, 0x80, 0x40, 0x38, 0x04, 0x02, 0x82, 0x82, 0xc4, 0xb8, 0x00, 0x00,
55+ 0x00, 0xfe, 0x92, 0x92, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x7c, 0x00, 0x00,
56+ 0x00, 0xe7, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x24, 0x3c, 0x00, 0x00,
57+ 0x00, 0xe7, 0x42, 0x42, 0x42, 0x42, 0x24, 0x24, 0x24, 0x24, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00,
58+ 0x00, 0xe7, 0x42, 0x42, 0x42, 0x5a, 0x5a, 0x5a, 0x5a, 0x24, 0x24, 0x24, 0x24, 0x24, 0x00, 0x00,
59+ 0x00, 0xe7, 0x42, 0x42, 0x24, 0x24, 0x24, 0x18, 0x24, 0x24, 0x24, 0x42, 0x42, 0xe7, 0x00, 0x00,
60+ 0x00, 0xee, 0x44, 0x44, 0x44, 0x28, 0x28, 0x28, 0x10, 0x10, 0x10, 0x10, 0x10, 0x7c, 0x00, 0x00,
61+ 0x00, 0xfe, 0x84, 0x84, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x42, 0x82, 0xfe, 0x00, 0x00,
62+ 0x00, 0x3e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3e, 0x00,
63+ 0x80, 0x80, 0x40, 0x40, 0x20, 0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x04, 0x04, 0x02, 0x02,
64+ 0x00, 0x7c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x7c, 0x00,
65+ 0x00, 0x10, 0x28, 0x44, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
66+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00,
67+ 0x10, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x08, 0x04, 0x3c, 0x44, 0x84, 0x84, 0x8c, 0x76, 0x00, 0x00,
69+ 0xc0, 0x40, 0x40, 0x40, 0x40, 0x58, 0x64, 0x42, 0x42, 0x42, 0x42, 0x42, 0x64, 0x58, 0x00, 0x00,
70+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x4c, 0x84, 0x84, 0x80, 0x80, 0x82, 0x44, 0x38, 0x00, 0x00,
71+ 0x0c, 0x04, 0x04, 0x04, 0x04, 0x34, 0x4c, 0x84, 0x84, 0x84, 0x84, 0x84, 0x4c, 0x36, 0x00, 0x00,
72+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x82, 0x82, 0xfc, 0x80, 0x82, 0x42, 0x3c, 0x00, 0x00,
73+ 0x0e, 0x10, 0x10, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x7c, 0x00, 0x00,
74+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x4c, 0x84, 0x84, 0x84, 0x84, 0x4c, 0x34, 0x04, 0x04, 0x78,
75+ 0xc0, 0x40, 0x40, 0x40, 0x40, 0x58, 0x64, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0xe3, 0x00, 0x00,
76+ 0x00, 0x10, 0x10, 0x00, 0x00, 0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00,
77+ 0x00, 0x04, 0x04, 0x00, 0x00, 0x0c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x08, 0x30,
78+ 0xc0, 0x40, 0x40, 0x40, 0x40, 0x4e, 0x44, 0x48, 0x50, 0x60, 0x50, 0x48, 0x44, 0xe6, 0x00, 0x00,
79+ 0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00,
80+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0xdb, 0x00, 0x00,
81+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x64, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0xe3, 0x00, 0x00,
82+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x82, 0x82, 0x82, 0x82, 0x82, 0x44, 0x38, 0x00, 0x00,
83+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x64, 0x42, 0x42, 0x42, 0x42, 0x42, 0x64, 0x58, 0x40, 0xe0,
84+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x4c, 0x84, 0x84, 0x84, 0x84, 0x84, 0x4c, 0x34, 0x04, 0x0e,
85+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x62, 0x42, 0x40, 0x40, 0x40, 0x40, 0x40, 0xe0, 0x00, 0x00,
86+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7a, 0x86, 0x82, 0xc0, 0x38, 0x06, 0x82, 0xc2, 0xbc, 0x00, 0x00,
87+ 0x00, 0x00, 0x10, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0e, 0x00, 0x00,
88+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x46, 0x3b, 0x00, 0x00,
89+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x42, 0x42, 0x42, 0x24, 0x24, 0x24, 0x18, 0x18, 0x00, 0x00,
90+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x42, 0x42, 0x5a, 0x5a, 0x5a, 0x24, 0x24, 0x24, 0x00, 0x00,
91+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x44, 0x28, 0x28, 0x10, 0x28, 0x28, 0x44, 0xc6, 0x00, 0x00,
92+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x42, 0x42, 0x24, 0x24, 0x24, 0x18, 0x18, 0x10, 0x10, 0x60,
93+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x82, 0x84, 0x08, 0x10, 0x20, 0x42, 0x82, 0xfe, 0x00, 0x00,
94+ 0x00, 0x06, 0x08, 0x10, 0x10, 0x10, 0x10, 0x60, 0x10, 0x10, 0x10, 0x10, 0x08, 0x06, 0x00, 0x00,
95+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
96+ 0x00, 0x60, 0x10, 0x08, 0x08, 0x08, 0x08, 0x06, 0x08, 0x08, 0x08, 0x08, 0x10, 0x60, 0x00, 0x00,
97+ 0x00, 0x72, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
98+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0x44, 0x82, 0xfe, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00
99+};
--- a/function.c
+++ b/function.c
@@ -1,717 +1,717 @@
1-#include "osecpu.h"
2-
3-extern unsigned char fontdata[]; // @fontdata.c
4-
5-const char *searchArg(int argc, const char **argv, const char *tag, int i)
6-{
7- int j, l;
8- const char *r = NULL;
9- if (tag != NULL) {
10- l = (int)strlen(tag);
11- for (j = 1; j < argc; j++) {
12- if (strncmp(argv[j], tag, l) == 0) {
13- r = argv[j] + l;
14- if (i == 0){
15- break;
16- }
17- i--;
18- }
19- }
20- }
21- else {
22- for (j = 1; j < argc; j++) {
23- if (strchr(argv[j], ':') == NULL) {
24- r = argv[j];
25- if (i == 0){
26- break;
27- }
28- i--;
29- }
30- }
31- }
32- if (i != 0){
33- r = NULL;
34- }
35- return r;
36-}
37-
38-void devFunc0001(int len, unsigned char *puc, HOSECPU_RuntimeEnvironment *r)
39-{
40- while (len > 0) {
41- putOsaskChar(*puc++, r);
42- len--;
43- }
44- return;
45-}
46-
47-void devFunc0006(int mod, int sx, int sy, int x, int y, int c, int len, unsigned char *puc, HOSECPU_RuntimeEnvironment *r)
48-{
49- int xx;
50- int yy;
51- int i, ddx, ddy, j, ch, dx, dy;
52-
53- if (sy == 0){
54- sy = sx;
55- }
56- xx = x + sx * 8;
57- yy = y + sy * 16;
58- if (xx <= 0 || xx > mainWindow.xsize || yy <= 0 || yy > mainWindow.ysize){
59- (*(r->errHndl))(r);
60- }
61- if (x < 0 || x >= mainWindow.xsize || y < 0 || y >= mainWindow.ysize){
62- (*(r->errHndl))(r);
63- }
64-
65-
66- if ((mod & 3) == 0 && sx == 1 && sy == 1) {
67- // メジャーケースを高速化.
68- for (i = 0; i < len; i++) {
69- ch = puc[i];
70- if (0x10 <= ch && ch <= 0x1f)
71- ch = "0123456789ABCDEF"[ch & 0x0f];
72- for (dy = 0; dy < 16; dy++) {
73- j = fontdata[(ch - ' ') * 16 + dy];
74- for (dx = 0; dx < 8; dx++) {
75- if ((j & (0x80 >> dx)) != 0){
76- mainWindow.vram[(x + dx) + (y + dy) * mainWindow.xsize] = c;
77- }
78- }
79- }
80- x += 8;
81- }
82- return;
83- }
84- for (i = 0; i < len; i++) {
85- ch = puc[i];
86- if (0x10 <= ch && ch <= 0x1f)
87- ch = "0123456789ABCDEF"[ch & 0x0f];
88- for (dy = 0; dy < 16; dy++) {
89- j = fontdata[(ch - ' ') * 16 + dy];
90- for (ddy = 0; ddy < sy; ddy++) {
91- for (dx = 0; dx < 8; dx++) {
92- if ((j & (0x80 >> dx)) != 0) {
93- for (ddx = 0; ddx < sx; ddx++) {
94- switch (mod & 3) {
95- case 0:
96- mainWindow.vram[x + y * mainWindow.xsize] = c;
97- break;
98- case 1:
99- mainWindow.vram[x + y * mainWindow.xsize] |= c;
100- break;
101- case 2:
102- mainWindow.vram[x + y * mainWindow.xsize] ^= c;
103- break;
104- case 3:
105- mainWindow.vram[x + y * mainWindow.xsize] &= c;
106- break;
107- }
108- x++;
109- }
110- } else{
111- x += sx;
112- }
113- }
114- x -= sx * 8;
115- y++;
116- }
117- }
118- x += sx * 8;
119- y -= sy * 16;
120- }
121- return;
122-}
123-
124-void devFunc0004(int mod, int x0, int y0, int x1, int y1, int c)
125-{
126- int x, y;
127- if (mod == 0) {
128- for (y = y0; y <= y1; y++) {
129- for (x = x0; x <= x1; x++) {
130- mainWindow.vram[x + y * mainWindow.xsize] = c;
131- }
132- }
133- }
134- else {
135- for (y = y0; y <= y1; y++) {
136- for (x = x0; x <= x1; x++) {
137- switch (mod) {
138- case 1:
139- mainWindow.vram[x + y * mainWindow.xsize] |= c;
140- break;
141- case 2:
142- mainWindow.vram[x + y * mainWindow.xsize] ^= c;
143- break;
144- case 3:
145- mainWindow.vram[x + y * mainWindow.xsize] &= c;
146- break;
147- }
148- }
149- }
150- }
151- return;
152-}
153-
154-int devFunc0016(int buflen, unsigned char *buf, int plen, unsigned char *p, int qlen, int *q, HOSECPU_RuntimeEnvironment *r)
155-{
156- int i = 0, base, j, k;
157- char sign;
158-
159- while (plen > 0) {
160- if (i >= buflen){
161- (*(r->errHndl))(r);
162- }
163- if (*p != 0x01) {
164- buf[i++] = *p++;
165- plen--;
166- continue;
167- }
168- p++;
169- plen--;
170- if (qlen < 4){
171- (*(r->errHndl))(r);
172- }
173- base = q[0];
174- sign = 0;
175- if (base == 0){
176- base = 16;
177- }
178-#if (REVISION == 1)
179- if (base == -3){
180- base = 10;
181- }
182-#endif
183- if (base == -1){
184- base = 10;
185- }
186- if (base < 0 || base > 16){
187- (*(r->errHndl))(r);
188- }
189- if (q[1] + i > buflen){
190- (*(r->errHndl))(r);
191- }
192- j = q[3];
193- if ((q[2] & 4) == 0) {
194- // jは符号付き整数.
195- if ((q[2] & 8) != 0 && j > 0){
196- sign = '+';
197- }
198- if (j < 0) {
199- sign = '-'; j *= -1;
200- }
201- } else{
202- // jは符号無し整数.
203- if ((q[2] & 8) != 0 && j != 0){
204- sign = '+';
205- }
206- }
207- for (k = q[1] - 1; k >= 0; k--) {
208- buf[i + k] = (j % base) + 0x10;
209- j = ((unsigned)j) / base;
210- }
211- k = 0;
212- if ((q[2] & 2) == 0 && j == 0) {
213- for (k = 0; k < q[1] - 1; k++) {
214- if (buf[i + k] != 0x10){
215- break;
216- }
217- buf[i + k] = ' ';
218- }
219- }
220- if (sign != 0) {
221- if (k > 0){
222- k--;
223- }
224- buf[i + k] = sign;
225- }
226- if ((q[2] & 1) != 0 && buf[i] == ' ') {
227- for (j = 0; k < q[1]; k++, j++){
228- buf[i + j] = buf[i + k];
229- }
230- i += j;
231- } else{
232- i += q[1];
233- }
234- qlen -= 4;
235- q += 4;
236- }
237- return i;
238-}
239-
240-void devFunc(HOSECPU_RuntimeEnvironment *r)
241-{
242- FILE *fp;
243- int i, c;
244- int x, y, len, dx, dy;
245- unsigned char *puc;
246- unsigned char pucbuf[256];
247-
248- //サイズを節約するためにEBPを128バイトずらしているのを元に戻す
249- r = (HOSECPU_RuntimeEnvironment *) (((char *)r) - 128);
250-
251- if (r->winClosed != 0){
252- longjmp(*(r->setjmpEnv), 1);
253- }
254- if (0xff44 <= r->ireg[0x30] && r->ireg[0x30] <= 0xff48) {
255- if (mainWindow.vram == NULL) {
256- mainWindow.xsize = 640;
257- mainWindow.ysize = 480;
258- mainWindow.vram = malloc(640 * 480 * 4);
259- drv_openWin(640, 480, (void *)mainWindow.vram, &r->winClosed);
260- r->autoSleep = 1;
261- for (i = 640 * 480 - 1; i >= 0; i--){
262- mainWindow.vram[i] = 0;
263- }
264- }
265- }
266-
267- switch (r->ireg[0x30]){
268- case 0xff00:
269- printf("R31=%d(dec)\n", r->ireg[0x31]);
270- break;
271-
272- case 0xff01:
273- /* return: R30, P31 */
274- if (r->buf0 == NULL){
275- r->buf0 = malloc(1024 * 1024);
276- }
277- if (r->mainArgc <= r->ireg[0x31]) {
278- fprintf(stderr, "devFunc: error: R30=ff01: argc error: R31=%08X\n", r->ireg[0x31]);
279- exit(1);
280- }
281- fp = fopen(r->mainArgv[r->ireg[0x31]], "rb");
282- if (fp == NULL) {
283- fprintf(stderr, "devFunc: error: R30=ff01: fopen error: '%s'\n", r->mainArgv[r->ireg[0x31]]);
284- exit(1);
285- }
286- i = (int)fread(r->buf0, 1, 1024 * 1024 - 4, fp);
287- if (i >= 1024 * 1024 - 4 || i < 0) {
288- fprintf(stderr, "devFunc: error: R30=ff01: fread error: '%s'\n", r->mainArgv[r->ireg[0x31]]);
289- exit(1);
290- }
291- fclose(fp);
292- r->preg[0x31].p = r->buf0;
293- r->preg[0x31].p0 = r->buf0;
294- r->preg[0x31].p1 = r->buf0 + i;
295- r->preg[0x31].typ = 3; // T_UINT8
296- r->ireg[0x30] = i;
297- break;
298-
299- case 0xff02:
300- /* return: none */
301- if (r->mainArgc <= r->ireg[0x31]) {
302- fprintf(stderr, "devFunc: error: R30=ff02: argc error: R31=%08X\n", r->ireg[0x31]);
303- exit(1);
304- }
305- fp = fopen(r->mainArgv[r->ireg[0x31]], "wb");
306- if (fp == NULL) {
307- fprintf(stderr, "devFunc: error: R30=ff02: fopen error: '%s'\n", r->mainArgv[r->ireg[0x31]]);
308- exit(1);
309- }
310- if (r->ireg[0x32] >= 1024 * 1024 || r->ireg[0x32] < 0){
311- fprintf(stderr, "devFunc: error: R30=ff02: fwrite error: R02=%08X\n", r->ireg[0x32]);
312- exit(1);
313- }
314- fwrite(r->preg[0x31].p, 1, r->ireg[0x32], fp);
315- fclose(fp);
316- break;
317-
318- case 0xff03:
319- /* return: P31 */
320- if (r->buf1 == NULL){
321- r->buf1 = malloc(1024 * 1024);
322- }
323- r->preg[0x31].p = r->buf1;
324- r->preg[0x31].p0 = r->buf1;
325- r->preg[0x31].p1 = r->buf1 + 1024 * 1024;
326- break;
327-
328- case 0xff04:
329- printf("P31.(p-p0)=%d(dec)\n", (int)(r->preg[0x31].p - r->preg[0x31].p0));
330- break;
331-
332- case 0xff05:
333- fwrite(r->preg[0x31].p, 1, r->ireg[0x31], stdout);
334- break;
335-
336- case 0xff06:
337- // R31はリターンコード.
338- // これを反映すべきだが、現状は手抜きでいつも正常終了.
339- longjmp(*(r->setjmpEnv), 1);
340- break;
341-
342- case 0xff07:
343- // マシになった文字列表示.OSASK文字列に対応.offにすれば通常の文字列処理もできる.現状はonのみサポート.
344- checkString(r, 0x31, 0x31);
345- devFunc0001(r->ireg[0x31], r->preg[0x31].p, r);
346- break;
347-
348- case 0xff08:
349- // JITC on JITC
350- // R31: 言語(back-end, front-end, ...
351- // R32: level
352- // R33: debugInfo1
353- checkString(r, 0x34, 0x31);
354- if (r->ireg[0x33] < 0 || r->ireg[0x33] > 15 || r->debugInfo1 > 15){
355- (*(r->errHndl))(r);
356- }
357- for (i = 0; i < r->maxLabels; i++){
358- r->label[i].opt = 0;
359- }
360- puc = r->preg[0x31].p;
361- i = jitCompiler(r->jitbuf, r->jitbuf1, puc, puc + r->ireg[0x34], puc, r->label, r->maxLabels, r->ireg[0x32], di1_serial, JITC_NOSTARTUP + 0);
362- if (i == 0) {
363- i = jitCompiler(r->jitbuf, r->jitbuf1, puc, puc + r->ireg[0x34], puc, r->label, r->maxLabels, r->ireg[0x32], di1_serial, JITC_NOSTARTUP + JITC_PHASE1 + 0);
364- if (i >= 0) {
365- r->mapDi1s[r->debugInfo1][r->ireg[0x33]] = di1_serial;
366- di1_serial++;
367- r->ireg[0x30] = 0;
368- r->preg[0x31].p = r->jitbuf;
369- r->preg[0x31].typ = 0; // TYP_CODE
370- r->preg[0x31].p0 = r->jitbuf;
371- r->preg[0x31].p1 = r->jitbuf + 1;
372- //int j; for (j = 0; j < i; j++) printf("%02X ", r->jitbuf[j]); putchar('\n');
373- r->jitbuf += i;
374- static unsigned char ff08_ret[3] = { 0x1e, 0x3f, 0x30 };
375- i = jitCompiler(r->jitbuf, r->jitbuf1, ff08_ret, ff08_ret + 3, puc, r->label, r->maxLabels, r->ireg[0x32], -1, JITC_NOSTARTUP + JITC_PHASE1 + 0);
376- r->jitbuf += i;
377- break;
378- }
379- }
380- r->ireg[0x30] = -1;
381- break;
382-
383- case 0xff09:
384- // たぶんbit7を使ったテキストはうまく処理できない(これはもはや仕様にしても問題ないかも).
385- checkString(r, 0x31, 0x31);
386- len = devFunc0016(sizeof pucbuf, pucbuf, r->ireg[0x31], r->preg[0x31].p, r->ireg[0x32], (int *)r->preg[0x32].p, r);
387- devFunc0001(len, pucbuf, r);
388- break;
389-
390- case 0xff40:
391- /* R31とR32でサイズを指定 */
392- mainWindow.xsize = r->ireg[0x31];
393- mainWindow.ysize = r->ireg[0x32];
394- if (mainWindow.xsize <= 0 || mainWindow.ysize <= 0){
395- (*(r->errHndl))(r);
396- }
397- r->preg[0x31].p = (void *)(mainWindow.vram = malloc(mainWindow.xsize * mainWindow.ysize * 4));
398- r->preg[0x31].p0 = r->preg[0x31].p;
399- r->preg[0x31].p1 = r->preg[0x31].p + mainWindow.xsize * mainWindow.ysize * 4;
400- drv_openWin(r->ireg[0x31], r->ireg[0x32], r->preg[0x31].p, &r->winClosed);
401- // drv_flshWin(r->ireg[1], r->ireg[2], 0, 0);
402- r->autoSleep = 1;
403- for (i = mainWindow.xsize * mainWindow.ysize - 1; i >= 0; i--){
404- mainWindow.vram[i] = 0;
405- }
406- break;
407-
408- case 0xff41:
409- /* R31とR32でサイズを指定、R33とR34でx0,y0指定 */
410- if (r->ireg[0x31] == -1) {
411- r->ireg[0x31] = mainWindow.xsize; r->ireg[0x33] &= 0;
412- }
413- if (r->ireg[0x32] == -1) {
414- r->ireg[0x32] = mainWindow.ysize; r->ireg[0x34] &= 0;
415- }
416- checkRect(r, 0x31);
417- drv_flshWin(r->ireg[0x31], r->ireg[0x32], r->ireg[0x33], r->ireg[0x34]);
418- break;
419-
420- case 0xff42:
421- if (r->ireg[0x32] == -1) {
422- r->autoSleep = 1;
423- longjmp(*(r->setjmpEnv), 1);
424- }
425- if (r->ireg[0x32] < 0){
426- (*(r->errHndl))(r);
427- }
428- r->autoSleep = 0;
429- if ((r->ireg[0x31] & 1) == 0 && mainWindow.vram != NULL){
430- drv_flshWin(mainWindow.xsize, mainWindow.ysize, 0, 0);
431- }
432- for (;;) {
433- if (r->winClosed != 0){
434- longjmp(*(r->setjmpEnv), 1);
435- }
436- drv_sleep(r->ireg[0x32]);
437- if ((r->ireg[0x31] & 2) != 0 && keybuf_c <= 0){
438- continue;
439- }
440- break;
441- }
442- break;
443-
444- case 0xff43:
445- // 1:peek
446- // 2:stdin
447- // 4,8: ソース指定.
448- // 16: shift, lock系を有効化.
449- // 32: 左右のshift系を区別する.
450- if (r->ireg[0x31] == 2) { // なぜ3にしなかったのか...
451- r->ireg[0x30] = fgetc(stdin);
452- if (r->ireg[0x30] == EOF){
453- r->ireg[0x30] = -1;
454- }
455- break;
456- }
457- r->ireg[0x30] |= -1;
458- if (keybuf_c > 0) {
459- r->ireg[0x30] = keybuf[keybuf_r];
460- if ((r->ireg[0x31] & 16) == 0){
461- r->ireg[0x30] &= 0x3e3effff;
462- }
463- if ((r->ireg[0x31] & 32) == 0){
464- r->ireg[0x30] |= (r->ireg[0x30] >> 8) & 0xff0000;
465- }
466- if ((r->ireg[0x31] & 1) != 0) {
467- keybuf_c--;
468- keybuf_r = (keybuf_r + 1) & (KEYBUFSIZ - 1);
469- }
470- }
471- r->ireg[0x32] = r->ireg[0x33] = 0;
472- if (r->ireg[0x30] == 4132) r->ireg[0x32]--;
473- if (r->ireg[0x30] == 4133) r->ireg[0x33]--;
474- if (r->ireg[0x30] == 4134) r->ireg[0x32]++;
475- if (r->ireg[0x30] == 4135) r->ireg[0x33]++;
476- break;
477-
478- case 0xff44:
479- c = loadColor(r, 0x34);
480- if (r->ireg[0x32] < 0 || r->ireg[0x32] >= mainWindow.xsize ||
481- r->ireg[0x33] < 0 || r->ireg[0x33] >= mainWindow.ysize){
482- (*(r->errHndl))(r);
483- }
484-
485- switch ((r->ireg[0x31] & 3)) {
486- case 0:
487- mainWindow.vram[r->ireg[0x32] + r->ireg[0x33] * mainWindow.xsize] = c;
488- break;
489- case 1:
490- mainWindow.vram[r->ireg[0x32] + r->ireg[0x33] * mainWindow.xsize] |= c;
491- break;
492- case 2:
493- mainWindow.vram[r->ireg[0x32] + r->ireg[0x33] * mainWindow.xsize] ^= c;
494- break;
495- case 3:
496- mainWindow.vram[r->ireg[0x32] + r->ireg[0x33] * mainWindow.xsize] &= c;
497- break;
498- }
499- break;
500-
501- case 0xff45:
502- //drawLine
503- c = loadColor(r, 0x36);
504- if (r->ireg[0x32] < 0 || r->ireg[0x32] >= mainWindow.xsize ||
505- r->ireg[0x33] < 0 || r->ireg[0x33] >= mainWindow.ysize){
506- (*(r->errHndl))(r);
507- }
508- if (r->ireg[0x34] < 0 || r->ireg[0x34] >= mainWindow.xsize ||
509- r->ireg[0x35] < 0 || r->ireg[0x35] >= mainWindow.ysize){
510- (*(r->errHndl))(r);
511- }
512- dx = r->ireg[0x34] - r->ireg[0x32];
513- dy = r->ireg[0x35] - r->ireg[0x33];
514- x = r->ireg[0x32] << 10;
515- y = r->ireg[0x33] << 10;
516- if (dx < 0){
517- dx = -dx;
518- }
519- if (dy < 0){
520- dy = -dy;
521- }
522- if (dx >= dy) {
523- len = dx + 1; dx = 1024;
524- if (r->ireg[0x32] > r->ireg[0x34]){
525- dx *= -1;
526- }
527- if (r->ireg[0x33] > r->ireg[0x35]){
528- dy *= -1;
529- }
530- dy = (dy << 10) / len;
531- } else {
532- len = dy + 1; dy = 1024;
533- if (r->ireg[0x33] > r->ireg[0x35]){
534- dy *= -1;
535- }
536- if (r->ireg[0x32] > r->ireg[0x34]){
537- dx *= -1;
538- }
539- dx = (dx << 10) / len;
540- }
541- if ((r->ireg[0x31] & 3) == 0) {
542- for (i = 0; i < len; i++) {
543- mainWindow.vram[(x >> 10) + (y >> 10) * mainWindow.xsize] = c;
544- x += dx;
545- y += dy;
546- }
547- break;
548- }
549- for (i = 0; i < len; i++) {
550- // if ((r->ireg[0x31] & 3) == 0) vram[(x >> 10) + (y >> 10) * v_xsiz] = c;
551- switch ((r->ireg[0x31] & 3)) {
552- case 1:
553- mainWindow.vram[(x >> 10) + (y >> 10) * mainWindow.xsize] |= c;
554- break;
555- case 2:
556- mainWindow.vram[(x >> 10) + (y >> 10) * mainWindow.xsize] ^= c;
557- break;
558- case 3:
559- mainWindow.vram[(x >> 10) + (y >> 10) * mainWindow.xsize] &= c;
560- break;
561- default:
562- break;
563- }
564- x += dx;
565- y += dy;
566- }
567- break;
568-
569- case 0xff46: // fillRect(opt:R31, xsiz:R32, ysiz:R33, x0:R34, y0:R35, c:R36)
570- c = loadColor(r, 0x36);
571- if (r->ireg[0x32] == -1) { r->ireg[0x32] = mainWindow.xsize; r->ireg[0x34] &= 0; }
572- if (r->ireg[0x33] == -1) { r->ireg[0x33] = mainWindow.ysize; r->ireg[0x35] &= 0; }
573- checkRect(r, 0x32);
574- int mod3 = r->ireg[0x31] & 3, x0 = r->ireg[0x34], y0 = r->ireg[0x35], x1 = r->ireg[0x34] + r->ireg[0x32] - 1, y1 = r->ireg[0x35] + r->ireg[0x33] - 1;
575- if ((r->ireg[0x31] & 0x20) == 0) {
576- devFunc0004(mod3, x0, y0, x1, y1, c);
577- } else { // drawRect
578- devFunc0004(mod3, x0, y0, x1, y0, c);
579- devFunc0004(mod3, x0, y1, x1, y1, c);
580- devFunc0004(mod3, x0, y0, x0, y1, c);
581- devFunc0004(mod3, x1, y0, x1, y1, c);
582- }
583- break;
584-
585- case 0xff47: // fillOval(opt:R31, xsiz:R32, ysiz:R33, x0:R34, y0:R35, c:R36)
586- // これの計算精度はアーキテクチャに依存する.
587- c = loadColor(r, 0x36);
588- if (r->ireg[0x32] == -1) {
589- r->ireg[0x32] = mainWindow.xsize; r->ireg[0x34] &= 0;
590- }
591- if (r->ireg[0x33] == -1) {
592- r->ireg[0x33] = mainWindow.ysize; r->ireg[0x35] &= 0;
593- }
594- checkRect(r, 0x32);
595- double dcx = 0.5 * (r->ireg[0x32] - 1);
596- double dcy = 0.5 * (r->ireg[0x33] - 1);
597- double dcxy = (dcx + 0.5) * (dcy + 0.5) - 0.1;
598- dcxy *= dcxy;
599- mod3 = r->ireg[0x31] & 3;
600- x1 = r->ireg[0x32];
601- y1 = r->ireg[0x33];
602- if (mod3 == 0 && (r->ireg[0x31] & 0x20) == 0) {
603- for (y = 0; y < y1; y++) {
604- double dty = (y - dcy) * dcx;
605- for (x = 0; x < x1; x++) {
606- double dtx = (x - dcx) * dcy;
607- if (dtx * dtx + dty * dty > dcxy){
608- continue;
609- }
610- mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] = c;
611- }
612- }
613- } else {
614-#define DRAWOVALPARAM 1
615- double dcx1 = 0.5 * (r->ireg[0x32] - (1 + DRAWOVALPARAM * 2));
616- double dcy1 = 0.5 * (r->ireg[0x33] - (1 + DRAWOVALPARAM * 2));
617- double dcxy1 = (dcx1 + 0.5) * (dcy1 + 0.5) - 0.1;
618- dcxy1 *= dcxy1;
619- for (y = 0; y < y1; y++) {
620- double dty = (y - dcy) * dcx;
621- double dty1 = (y - dcy) * dcx1;
622- for (x = 0; x < x1; x++) {
623- double dtx = (x - dcx) * dcy;
624- double dtx1 = (x - dcx) * dcy1;
625- if (dtx * dtx + dty * dty > dcxy){
626- continue;
627- }
628- if (DRAWOVALPARAM <= x && x < x1 - DRAWOVALPARAM && DRAWOVALPARAM <= y && y < y1 - DRAWOVALPARAM) {
629- if (dtx1 * dtx1 + dty1 * dty1 < dcxy1){
630- continue;
631- }
632- }
633- switch (mod3) {
634- case 0:
635- mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] = c;
636- break;
637- case 1:
638- mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] |= c;
639- break;
640- case 2:
641- mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] ^= c;
642- break;
643- case 3:
644- mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] &= c;
645- break;
646- }
647- }
648- }
649- }
650- break;
651-
652- case 0xff48: // drawString(opt:R31, xsiz:R32, ysiz:R33, x0:R34, y0:R35, c:R36, s.len:R37, s.p:P31)
653- checkString(r, 0x37, 0x31);
654- devFunc0006(r->ireg[0x31], r->ireg[0x32], r->ireg[0x33], r->ireg[0x34], r->ireg[0x35], loadColor(r, 0x36), r->ireg[0x37], r->preg[0x31].p, r);
655- break;
656-
657- case 0xff49:
658- // **** junkApi_rand(i, max) ****
659- // 0 <= i <= maxとなるiを返す。
660- // max==0のとき、iはSINT32全体を範囲とする乱数となる。
661- r->ireg[0x30] = randGetNextUInt32();
662- if (r->ireg[0x31] > 0){
663- r->ireg[0x30] = (r->ireg[0x30] & 0x7fffffff) % (r->ireg[0x31] + 1);
664- }
665- break;
666-
667- case 0xff4a: /* seedの指定 */
668- randStatInit(r->ireg[0x31]);
669- break;
670-
671- case 0xff4b: /* 適当なseedを提供 */
672- r->ireg[0x30] = (int)(time(NULL) ^ (long)0x55555555);
673- break;
674-
675- case 0xff4c:
676- checkString(r, 0x37, 0x31);
677- len = devFunc0016(sizeof pucbuf, pucbuf, r->ireg[0x37], r->preg[0x31].p, r->ireg[0x38], (int *)r->preg[0x32].p, r);
678- devFunc0006(r->ireg[0x31], r->ireg[0x32], r->ireg[0x33], r->ireg[0x34], r->ireg[0x35], loadColor(r, 0x36), len, pucbuf, r);
679- break;
680-
681- case 0xff4d:
682- // bitblt(mod, xsiz, ysiz, xscale, yscale, x0, y0, lineskip, inv, p_buf, typ0, p_table, typ1);
683- // mod: 0x20:use_table, 0x40:inv_is_visible & typ1_is_color
684- puc = r->preg[0x31].p;
685- mod3 = r->ireg[0x31] & 3;
686- dx = r->ireg[0x34];
687- dy = r->ireg[0x35];
688- if (dy == 0){
689- dy = dx;
690- }
691- if (r->ireg[0x32] == -1) {
692- r->ireg[0x32] = mainWindow.xsize / dx; r->ireg[0x36] &= 0;
693- }
694- if (r->ireg[0x33] == -1) {
695- r->ireg[0x33] = mainWindow.ysize / dy; r->ireg[0x37] &= 0;
696- }
697- for (y = 0; y < r->ireg[0x33]; y++) {
698- y0 = y * dy + r->ireg[0x37];
699- for (x = 0; x < r->ireg[0x32]; x++) {
700- x0 = x * dx + r->ireg[0x36];
701- c = iColor1[*puc++];
702- devFunc0004(mod3, x0, y0, x0 + dx, y0 + dy, c);
703- }
704- puc += r->ireg[0x38];
705- }
706- break;
707-
708- default:
709- printf("devFunc: error: R30=%08X\n", r->ireg[0x30]);
710- exit(EXIT_FAILURE);
711-
712- }
713- return;
714-}
715-
716-
717-
1+#include "osecpu.h"
2+
3+extern unsigned char fontdata[]; // @fontdata.c
4+
5+const char *searchArg(int argc, const char **argv, const char *tag, int i)
6+{
7+ int j, l;
8+ const char *r = NULL;
9+ if (tag != NULL) {
10+ l = (int)strlen(tag);
11+ for (j = 1; j < argc; j++) {
12+ if (strncmp(argv[j], tag, l) == 0) {
13+ r = argv[j] + l;
14+ if (i == 0){
15+ break;
16+ }
17+ i--;
18+ }
19+ }
20+ }
21+ else {
22+ for (j = 1; j < argc; j++) {
23+ if (strchr(argv[j], ':') == NULL) {
24+ r = argv[j];
25+ if (i == 0){
26+ break;
27+ }
28+ i--;
29+ }
30+ }
31+ }
32+ if (i != 0){
33+ r = NULL;
34+ }
35+ return r;
36+}
37+
38+void devFunc0001(int len, unsigned char *puc, HOSECPU_RuntimeEnvironment *r)
39+{
40+ while (len > 0) {
41+ putOsaskChar(*puc++, r);
42+ len--;
43+ }
44+ return;
45+}
46+
47+void devFunc0006(int mod, int sx, int sy, int x, int y, int c, int len, unsigned char *puc, HOSECPU_RuntimeEnvironment *r)
48+{
49+ int xx;
50+ int yy;
51+ int i, ddx, ddy, j, ch, dx, dy;
52+
53+ if (sy == 0){
54+ sy = sx;
55+ }
56+ xx = x + sx * 8;
57+ yy = y + sy * 16;
58+ if (xx <= 0 || xx > mainWindow.xsize || yy <= 0 || yy > mainWindow.ysize){
59+ (*(r->errHndl))(r);
60+ }
61+ if (x < 0 || x >= mainWindow.xsize || y < 0 || y >= mainWindow.ysize){
62+ (*(r->errHndl))(r);
63+ }
64+
65+
66+ if ((mod & 3) == 0 && sx == 1 && sy == 1) {
67+ // メジャーケースを高速化.
68+ for (i = 0; i < len; i++) {
69+ ch = puc[i];
70+ if (0x10 <= ch && ch <= 0x1f)
71+ ch = "0123456789ABCDEF"[ch & 0x0f];
72+ for (dy = 0; dy < 16; dy++) {
73+ j = fontdata[(ch - ' ') * 16 + dy];
74+ for (dx = 0; dx < 8; dx++) {
75+ if ((j & (0x80 >> dx)) != 0){
76+ mainWindow.vram[(x + dx) + (y + dy) * mainWindow.xsize] = c;
77+ }
78+ }
79+ }
80+ x += 8;
81+ }
82+ return;
83+ }
84+ for (i = 0; i < len; i++) {
85+ ch = puc[i];
86+ if (0x10 <= ch && ch <= 0x1f)
87+ ch = "0123456789ABCDEF"[ch & 0x0f];
88+ for (dy = 0; dy < 16; dy++) {
89+ j = fontdata[(ch - ' ') * 16 + dy];
90+ for (ddy = 0; ddy < sy; ddy++) {
91+ for (dx = 0; dx < 8; dx++) {
92+ if ((j & (0x80 >> dx)) != 0) {
93+ for (ddx = 0; ddx < sx; ddx++) {
94+ switch (mod & 3) {
95+ case 0:
96+ mainWindow.vram[x + y * mainWindow.xsize] = c;
97+ break;
98+ case 1:
99+ mainWindow.vram[x + y * mainWindow.xsize] |= c;
100+ break;
101+ case 2:
102+ mainWindow.vram[x + y * mainWindow.xsize] ^= c;
103+ break;
104+ case 3:
105+ mainWindow.vram[x + y * mainWindow.xsize] &= c;
106+ break;
107+ }
108+ x++;
109+ }
110+ } else{
111+ x += sx;
112+ }
113+ }
114+ x -= sx * 8;
115+ y++;
116+ }
117+ }
118+ x += sx * 8;
119+ y -= sy * 16;
120+ }
121+ return;
122+}
123+
124+void devFunc0004(int mod, int x0, int y0, int x1, int y1, int c)
125+{
126+ int x, y;
127+ if (mod == 0) {
128+ for (y = y0; y <= y1; y++) {
129+ for (x = x0; x <= x1; x++) {
130+ mainWindow.vram[x + y * mainWindow.xsize] = c;
131+ }
132+ }
133+ }
134+ else {
135+ for (y = y0; y <= y1; y++) {
136+ for (x = x0; x <= x1; x++) {
137+ switch (mod) {
138+ case 1:
139+ mainWindow.vram[x + y * mainWindow.xsize] |= c;
140+ break;
141+ case 2:
142+ mainWindow.vram[x + y * mainWindow.xsize] ^= c;
143+ break;
144+ case 3:
145+ mainWindow.vram[x + y * mainWindow.xsize] &= c;
146+ break;
147+ }
148+ }
149+ }
150+ }
151+ return;
152+}
153+
154+int devFunc0016(int buflen, unsigned char *buf, int plen, unsigned char *p, int qlen, int *q, HOSECPU_RuntimeEnvironment *r)
155+{
156+ int i = 0, base, j, k;
157+ char sign;
158+
159+ while (plen > 0) {
160+ if (i >= buflen){
161+ (*(r->errHndl))(r);
162+ }
163+ if (*p != 0x01) {
164+ buf[i++] = *p++;
165+ plen--;
166+ continue;
167+ }
168+ p++;
169+ plen--;
170+ if (qlen < 4){
171+ (*(r->errHndl))(r);
172+ }
173+ base = q[0];
174+ sign = 0;
175+ if (base == 0){
176+ base = 16;
177+ }
178+#if (REVISION == 1)
179+ if (base == -3){
180+ base = 10;
181+ }
182+#endif
183+ if (base == -1){
184+ base = 10;
185+ }
186+ if (base < 0 || base > 16){
187+ (*(r->errHndl))(r);
188+ }
189+ if (q[1] + i > buflen){
190+ (*(r->errHndl))(r);
191+ }
192+ j = q[3];
193+ if ((q[2] & 4) == 0) {
194+ // jは符号付き整数.
195+ if ((q[2] & 8) != 0 && j > 0){
196+ sign = '+';
197+ }
198+ if (j < 0) {
199+ sign = '-'; j *= -1;
200+ }
201+ } else{
202+ // jは符号無し整数.
203+ if ((q[2] & 8) != 0 && j != 0){
204+ sign = '+';
205+ }
206+ }
207+ for (k = q[1] - 1; k >= 0; k--) {
208+ buf[i + k] = (j % base) + 0x10;
209+ j = ((unsigned)j) / base;
210+ }
211+ k = 0;
212+ if ((q[2] & 2) == 0 && j == 0) {
213+ for (k = 0; k < q[1] - 1; k++) {
214+ if (buf[i + k] != 0x10){
215+ break;
216+ }
217+ buf[i + k] = ' ';
218+ }
219+ }
220+ if (sign != 0) {
221+ if (k > 0){
222+ k--;
223+ }
224+ buf[i + k] = sign;
225+ }
226+ if ((q[2] & 1) != 0 && buf[i] == ' ') {
227+ for (j = 0; k < q[1]; k++, j++){
228+ buf[i + j] = buf[i + k];
229+ }
230+ i += j;
231+ } else{
232+ i += q[1];
233+ }
234+ qlen -= 4;
235+ q += 4;
236+ }
237+ return i;
238+}
239+
240+void devFunc(HOSECPU_RuntimeEnvironment *r)
241+{
242+ FILE *fp;
243+ int i, c;
244+ int x, y, len, dx, dy;
245+ unsigned char *puc;
246+ unsigned char pucbuf[256];
247+
248+ //サイズを節約するためにEBPを128バイトずらしているのを元に戻す
249+ r = (HOSECPU_RuntimeEnvironment *) (((char *)r) - 128);
250+
251+ if (r->winClosed != 0){
252+ longjmp(*(r->setjmpEnv), 1);
253+ }
254+ if (0xff44 <= r->ireg[0x30] && r->ireg[0x30] <= 0xff48) {
255+ if (mainWindow.vram == NULL) {
256+ mainWindow.xsize = 640;
257+ mainWindow.ysize = 480;
258+ mainWindow.vram = malloc(640 * 480 * 4);
259+ drv_openWin(640, 480, (void *)mainWindow.vram, &r->winClosed);
260+ r->autoSleep = 1;
261+ for (i = 640 * 480 - 1; i >= 0; i--){
262+ mainWindow.vram[i] = 0;
263+ }
264+ }
265+ }
266+
267+ switch (r->ireg[0x30]){
268+ case 0xff00:
269+ printf("R31=%d(dec)\n", r->ireg[0x31]);
270+ break;
271+
272+ case 0xff01:
273+ /* return: R30, P31 */
274+ if (r->buf0 == NULL){
275+ r->buf0 = malloc(1024 * 1024);
276+ }
277+ if (r->mainArgc <= r->ireg[0x31]) {
278+ fprintf(stderr, "devFunc: error: R30=ff01: argc error: R31=%08X\n", r->ireg[0x31]);
279+ exit(1);
280+ }
281+ fp = fopen(r->mainArgv[r->ireg[0x31]], "rb");
282+ if (fp == NULL) {
283+ fprintf(stderr, "devFunc: error: R30=ff01: fopen error: '%s'\n", r->mainArgv[r->ireg[0x31]]);
284+ exit(1);
285+ }
286+ i = (int)fread(r->buf0, 1, 1024 * 1024 - 4, fp);
287+ if (i >= 1024 * 1024 - 4 || i < 0) {
288+ fprintf(stderr, "devFunc: error: R30=ff01: fread error: '%s'\n", r->mainArgv[r->ireg[0x31]]);
289+ exit(1);
290+ }
291+ fclose(fp);
292+ r->preg[0x31].p = r->buf0;
293+ r->preg[0x31].p0 = r->buf0;
294+ r->preg[0x31].p1 = r->buf0 + i;
295+ r->preg[0x31].typ = 3; // T_UINT8
296+ r->ireg[0x30] = i;
297+ break;
298+
299+ case 0xff02:
300+ /* return: none */
301+ if (r->mainArgc <= r->ireg[0x31]) {
302+ fprintf(stderr, "devFunc: error: R30=ff02: argc error: R31=%08X\n", r->ireg[0x31]);
303+ exit(1);
304+ }
305+ fp = fopen(r->mainArgv[r->ireg[0x31]], "wb");
306+ if (fp == NULL) {
307+ fprintf(stderr, "devFunc: error: R30=ff02: fopen error: '%s'\n", r->mainArgv[r->ireg[0x31]]);
308+ exit(1);
309+ }
310+ if (r->ireg[0x32] >= 1024 * 1024 || r->ireg[0x32] < 0){
311+ fprintf(stderr, "devFunc: error: R30=ff02: fwrite error: R02=%08X\n", r->ireg[0x32]);
312+ exit(1);
313+ }
314+ fwrite(r->preg[0x31].p, 1, r->ireg[0x32], fp);
315+ fclose(fp);
316+ break;
317+
318+ case 0xff03:
319+ /* return: P31 */
320+ if (r->buf1 == NULL){
321+ r->buf1 = malloc(1024 * 1024);
322+ }
323+ r->preg[0x31].p = r->buf1;
324+ r->preg[0x31].p0 = r->buf1;
325+ r->preg[0x31].p1 = r->buf1 + 1024 * 1024;
326+ break;
327+
328+ case 0xff04:
329+ printf("P31.(p-p0)=%d(dec)\n", (int)(r->preg[0x31].p - r->preg[0x31].p0));
330+ break;
331+
332+ case 0xff05:
333+ fwrite(r->preg[0x31].p, 1, r->ireg[0x31], stdout);
334+ break;
335+
336+ case 0xff06:
337+ // R31はリターンコード.
338+ // これを反映すべきだが、現状は手抜きでいつも正常終了.
339+ longjmp(*(r->setjmpEnv), 1);
340+ break;
341+
342+ case 0xff07:
343+ // マシになった文字列表示.OSASK文字列に対応.offにすれば通常の文字列処理もできる.現状はonのみサポート.
344+ checkString(r, 0x31, 0x31);
345+ devFunc0001(r->ireg[0x31], r->preg[0x31].p, r);
346+ break;
347+
348+ case 0xff08:
349+ // JITC on JITC
350+ // R31: 言語(back-end, front-end, ...
351+ // R32: level
352+ // R33: debugInfo1
353+ checkString(r, 0x34, 0x31);
354+ if (r->ireg[0x33] < 0 || r->ireg[0x33] > 15 || r->debugInfo1 > 15){
355+ (*(r->errHndl))(r);
356+ }
357+ for (i = 0; i < r->maxLabels; i++){
358+ r->label[i].opt = 0;
359+ }
360+ puc = r->preg[0x31].p;
361+ i = jitCompiler(r->jitbuf, r->jitbuf1, puc, puc + r->ireg[0x34], puc, r->label, r->maxLabels, r->ireg[0x32], di1_serial, JITC_NOSTARTUP + 0);
362+ if (i == 0) {
363+ i = jitCompiler(r->jitbuf, r->jitbuf1, puc, puc + r->ireg[0x34], puc, r->label, r->maxLabels, r->ireg[0x32], di1_serial, JITC_NOSTARTUP + JITC_PHASE1 + 0);
364+ if (i >= 0) {
365+ r->mapDi1s[r->debugInfo1][r->ireg[0x33]] = di1_serial;
366+ di1_serial++;
367+ r->ireg[0x30] = 0;
368+ r->preg[0x31].p = r->jitbuf;
369+ r->preg[0x31].typ = 0; // TYP_CODE
370+ r->preg[0x31].p0 = r->jitbuf;
371+ r->preg[0x31].p1 = r->jitbuf + 1;
372+ //int j; for (j = 0; j < i; j++) printf("%02X ", r->jitbuf[j]); putchar('\n');
373+ r->jitbuf += i;
374+ static unsigned char ff08_ret[3] = { 0x1e, 0x3f, 0x30 };
375+ i = jitCompiler(r->jitbuf, r->jitbuf1, ff08_ret, ff08_ret + 3, puc, r->label, r->maxLabels, r->ireg[0x32], -1, JITC_NOSTARTUP + JITC_PHASE1 + 0);
376+ r->jitbuf += i;
377+ break;
378+ }
379+ }
380+ r->ireg[0x30] = -1;
381+ break;
382+
383+ case 0xff09:
384+ // たぶんbit7を使ったテキストはうまく処理できない(これはもはや仕様にしても問題ないかも).
385+ checkString(r, 0x31, 0x31);
386+ len = devFunc0016(sizeof pucbuf, pucbuf, r->ireg[0x31], r->preg[0x31].p, r->ireg[0x32], (int *)r->preg[0x32].p, r);
387+ devFunc0001(len, pucbuf, r);
388+ break;
389+
390+ case 0xff40:
391+ /* R31とR32でサイズを指定 */
392+ mainWindow.xsize = r->ireg[0x31];
393+ mainWindow.ysize = r->ireg[0x32];
394+ if (mainWindow.xsize <= 0 || mainWindow.ysize <= 0){
395+ (*(r->errHndl))(r);
396+ }
397+ r->preg[0x31].p = (void *)(mainWindow.vram = malloc(mainWindow.xsize * mainWindow.ysize * 4));
398+ r->preg[0x31].p0 = r->preg[0x31].p;
399+ r->preg[0x31].p1 = r->preg[0x31].p + mainWindow.xsize * mainWindow.ysize * 4;
400+ drv_openWin(r->ireg[0x31], r->ireg[0x32], r->preg[0x31].p, &r->winClosed);
401+ // drv_flshWin(r->ireg[1], r->ireg[2], 0, 0);
402+ r->autoSleep = 1;
403+ for (i = mainWindow.xsize * mainWindow.ysize - 1; i >= 0; i--){
404+ mainWindow.vram[i] = 0;
405+ }
406+ break;
407+
408+ case 0xff41:
409+ /* R31とR32でサイズを指定、R33とR34でx0,y0指定 */
410+ if (r->ireg[0x31] == -1) {
411+ r->ireg[0x31] = mainWindow.xsize; r->ireg[0x33] &= 0;
412+ }
413+ if (r->ireg[0x32] == -1) {
414+ r->ireg[0x32] = mainWindow.ysize; r->ireg[0x34] &= 0;
415+ }
416+ checkRect(r, 0x31);
417+ drv_flshWin(r->ireg[0x31], r->ireg[0x32], r->ireg[0x33], r->ireg[0x34]);
418+ break;
419+
420+ case 0xff42:
421+ if (r->ireg[0x32] == -1) {
422+ r->autoSleep = 1;
423+ longjmp(*(r->setjmpEnv), 1);
424+ }
425+ if (r->ireg[0x32] < 0){
426+ (*(r->errHndl))(r);
427+ }
428+ r->autoSleep = 0;
429+ if ((r->ireg[0x31] & 1) == 0 && mainWindow.vram != NULL){
430+ drv_flshWin(mainWindow.xsize, mainWindow.ysize, 0, 0);
431+ }
432+ for (;;) {
433+ if (r->winClosed != 0){
434+ longjmp(*(r->setjmpEnv), 1);
435+ }
436+ drv_sleep(r->ireg[0x32]);
437+ if ((r->ireg[0x31] & 2) != 0 && keybuf_c <= 0){
438+ continue;
439+ }
440+ break;
441+ }
442+ break;
443+
444+ case 0xff43:
445+ // 1:peek
446+ // 2:stdin
447+ // 4,8: ソース指定.
448+ // 16: shift, lock系を有効化.
449+ // 32: 左右のshift系を区別する.
450+ if (r->ireg[0x31] == 2) { // なぜ3にしなかったのか...
451+ r->ireg[0x30] = fgetc(stdin);
452+ if (r->ireg[0x30] == EOF){
453+ r->ireg[0x30] = -1;
454+ }
455+ break;
456+ }
457+ r->ireg[0x30] |= -1;
458+ if (keybuf_c > 0) {
459+ r->ireg[0x30] = keybuf[keybuf_r];
460+ if ((r->ireg[0x31] & 16) == 0){
461+ r->ireg[0x30] &= 0x3e3effff;
462+ }
463+ if ((r->ireg[0x31] & 32) == 0){
464+ r->ireg[0x30] |= (r->ireg[0x30] >> 8) & 0xff0000;
465+ }
466+ if ((r->ireg[0x31] & 1) != 0) {
467+ keybuf_c--;
468+ keybuf_r = (keybuf_r + 1) & (KEYBUFSIZ - 1);
469+ }
470+ }
471+ r->ireg[0x32] = r->ireg[0x33] = 0;
472+ if (r->ireg[0x30] == 4132) r->ireg[0x32]--;
473+ if (r->ireg[0x30] == 4133) r->ireg[0x33]--;
474+ if (r->ireg[0x30] == 4134) r->ireg[0x32]++;
475+ if (r->ireg[0x30] == 4135) r->ireg[0x33]++;
476+ break;
477+
478+ case 0xff44:
479+ c = loadColor(r, 0x34);
480+ if (r->ireg[0x32] < 0 || r->ireg[0x32] >= mainWindow.xsize ||
481+ r->ireg[0x33] < 0 || r->ireg[0x33] >= mainWindow.ysize){
482+ (*(r->errHndl))(r);
483+ }
484+
485+ switch ((r->ireg[0x31] & 3)) {
486+ case 0:
487+ mainWindow.vram[r->ireg[0x32] + r->ireg[0x33] * mainWindow.xsize] = c;
488+ break;
489+ case 1:
490+ mainWindow.vram[r->ireg[0x32] + r->ireg[0x33] * mainWindow.xsize] |= c;
491+ break;
492+ case 2:
493+ mainWindow.vram[r->ireg[0x32] + r->ireg[0x33] * mainWindow.xsize] ^= c;
494+ break;
495+ case 3:
496+ mainWindow.vram[r->ireg[0x32] + r->ireg[0x33] * mainWindow.xsize] &= c;
497+ break;
498+ }
499+ break;
500+
501+ case 0xff45:
502+ //drawLine
503+ c = loadColor(r, 0x36);
504+ if (r->ireg[0x32] < 0 || r->ireg[0x32] >= mainWindow.xsize ||
505+ r->ireg[0x33] < 0 || r->ireg[0x33] >= mainWindow.ysize){
506+ (*(r->errHndl))(r);
507+ }
508+ if (r->ireg[0x34] < 0 || r->ireg[0x34] >= mainWindow.xsize ||
509+ r->ireg[0x35] < 0 || r->ireg[0x35] >= mainWindow.ysize){
510+ (*(r->errHndl))(r);
511+ }
512+ dx = r->ireg[0x34] - r->ireg[0x32];
513+ dy = r->ireg[0x35] - r->ireg[0x33];
514+ x = r->ireg[0x32] << 10;
515+ y = r->ireg[0x33] << 10;
516+ if (dx < 0){
517+ dx = -dx;
518+ }
519+ if (dy < 0){
520+ dy = -dy;
521+ }
522+ if (dx >= dy) {
523+ len = dx + 1; dx = 1024;
524+ if (r->ireg[0x32] > r->ireg[0x34]){
525+ dx *= -1;
526+ }
527+ if (r->ireg[0x33] > r->ireg[0x35]){
528+ dy *= -1;
529+ }
530+ dy = (dy << 10) / len;
531+ } else {
532+ len = dy + 1; dy = 1024;
533+ if (r->ireg[0x33] > r->ireg[0x35]){
534+ dy *= -1;
535+ }
536+ if (r->ireg[0x32] > r->ireg[0x34]){
537+ dx *= -1;
538+ }
539+ dx = (dx << 10) / len;
540+ }
541+ if ((r->ireg[0x31] & 3) == 0) {
542+ for (i = 0; i < len; i++) {
543+ mainWindow.vram[(x >> 10) + (y >> 10) * mainWindow.xsize] = c;
544+ x += dx;
545+ y += dy;
546+ }
547+ break;
548+ }
549+ for (i = 0; i < len; i++) {
550+ // if ((r->ireg[0x31] & 3) == 0) vram[(x >> 10) + (y >> 10) * v_xsiz] = c;
551+ switch ((r->ireg[0x31] & 3)) {
552+ case 1:
553+ mainWindow.vram[(x >> 10) + (y >> 10) * mainWindow.xsize] |= c;
554+ break;
555+ case 2:
556+ mainWindow.vram[(x >> 10) + (y >> 10) * mainWindow.xsize] ^= c;
557+ break;
558+ case 3:
559+ mainWindow.vram[(x >> 10) + (y >> 10) * mainWindow.xsize] &= c;
560+ break;
561+ default:
562+ break;
563+ }
564+ x += dx;
565+ y += dy;
566+ }
567+ break;
568+
569+ case 0xff46: // fillRect(opt:R31, xsiz:R32, ysiz:R33, x0:R34, y0:R35, c:R36)
570+ c = loadColor(r, 0x36);
571+ if (r->ireg[0x32] == -1) { r->ireg[0x32] = mainWindow.xsize; r->ireg[0x34] &= 0; }
572+ if (r->ireg[0x33] == -1) { r->ireg[0x33] = mainWindow.ysize; r->ireg[0x35] &= 0; }
573+ checkRect(r, 0x32);
574+ int mod3 = r->ireg[0x31] & 3, x0 = r->ireg[0x34], y0 = r->ireg[0x35], x1 = r->ireg[0x34] + r->ireg[0x32] - 1, y1 = r->ireg[0x35] + r->ireg[0x33] - 1;
575+ if ((r->ireg[0x31] & 0x20) == 0) {
576+ devFunc0004(mod3, x0, y0, x1, y1, c);
577+ } else { // drawRect
578+ devFunc0004(mod3, x0, y0, x1, y0, c);
579+ devFunc0004(mod3, x0, y1, x1, y1, c);
580+ devFunc0004(mod3, x0, y0, x0, y1, c);
581+ devFunc0004(mod3, x1, y0, x1, y1, c);
582+ }
583+ break;
584+
585+ case 0xff47: // fillOval(opt:R31, xsiz:R32, ysiz:R33, x0:R34, y0:R35, c:R36)
586+ // これの計算精度はアーキテクチャに依存する.
587+ c = loadColor(r, 0x36);
588+ if (r->ireg[0x32] == -1) {
589+ r->ireg[0x32] = mainWindow.xsize; r->ireg[0x34] &= 0;
590+ }
591+ if (r->ireg[0x33] == -1) {
592+ r->ireg[0x33] = mainWindow.ysize; r->ireg[0x35] &= 0;
593+ }
594+ checkRect(r, 0x32);
595+ double dcx = 0.5 * (r->ireg[0x32] - 1);
596+ double dcy = 0.5 * (r->ireg[0x33] - 1);
597+ double dcxy = (dcx + 0.5) * (dcy + 0.5) - 0.1;
598+ dcxy *= dcxy;
599+ mod3 = r->ireg[0x31] & 3;
600+ x1 = r->ireg[0x32];
601+ y1 = r->ireg[0x33];
602+ if (mod3 == 0 && (r->ireg[0x31] & 0x20) == 0) {
603+ for (y = 0; y < y1; y++) {
604+ double dty = (y - dcy) * dcx;
605+ for (x = 0; x < x1; x++) {
606+ double dtx = (x - dcx) * dcy;
607+ if (dtx * dtx + dty * dty > dcxy){
608+ continue;
609+ }
610+ mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] = c;
611+ }
612+ }
613+ } else {
614+#define DRAWOVALPARAM 1
615+ double dcx1 = 0.5 * (r->ireg[0x32] - (1 + DRAWOVALPARAM * 2));
616+ double dcy1 = 0.5 * (r->ireg[0x33] - (1 + DRAWOVALPARAM * 2));
617+ double dcxy1 = (dcx1 + 0.5) * (dcy1 + 0.5) - 0.1;
618+ dcxy1 *= dcxy1;
619+ for (y = 0; y < y1; y++) {
620+ double dty = (y - dcy) * dcx;
621+ double dty1 = (y - dcy) * dcx1;
622+ for (x = 0; x < x1; x++) {
623+ double dtx = (x - dcx) * dcy;
624+ double dtx1 = (x - dcx) * dcy1;
625+ if (dtx * dtx + dty * dty > dcxy){
626+ continue;
627+ }
628+ if (DRAWOVALPARAM <= x && x < x1 - DRAWOVALPARAM && DRAWOVALPARAM <= y && y < y1 - DRAWOVALPARAM) {
629+ if (dtx1 * dtx1 + dty1 * dty1 < dcxy1){
630+ continue;
631+ }
632+ }
633+ switch (mod3) {
634+ case 0:
635+ mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] = c;
636+ break;
637+ case 1:
638+ mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] |= c;
639+ break;
640+ case 2:
641+ mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] ^= c;
642+ break;
643+ case 3:
644+ mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] &= c;
645+ break;
646+ }
647+ }
648+ }
649+ }
650+ break;
651+
652+ case 0xff48: // drawString(opt:R31, xsiz:R32, ysiz:R33, x0:R34, y0:R35, c:R36, s.len:R37, s.p:P31)
653+ checkString(r, 0x37, 0x31);
654+ devFunc0006(r->ireg[0x31], r->ireg[0x32], r->ireg[0x33], r->ireg[0x34], r->ireg[0x35], loadColor(r, 0x36), r->ireg[0x37], r->preg[0x31].p, r);
655+ break;
656+
657+ case 0xff49:
658+ // **** junkApi_rand(i, max) ****
659+ // 0 <= i <= maxとなるiを返す。
660+ // max==0のとき、iはSINT32全体を範囲とする乱数となる。
661+ r->ireg[0x30] = randGetNextUInt32();
662+ if (r->ireg[0x31] > 0){
663+ r->ireg[0x30] = (r->ireg[0x30] & 0x7fffffff) % (r->ireg[0x31] + 1);
664+ }
665+ break;
666+
667+ case 0xff4a: /* seedの指定 */
668+ randStatInit(r->ireg[0x31]);
669+ break;
670+
671+ case 0xff4b: /* 適当なseedを提供 */
672+ r->ireg[0x30] = (int)(time(NULL) ^ (long)0x55555555);
673+ break;
674+
675+ case 0xff4c:
676+ checkString(r, 0x37, 0x31);
677+ len = devFunc0016(sizeof pucbuf, pucbuf, r->ireg[0x37], r->preg[0x31].p, r->ireg[0x38], (int *)r->preg[0x32].p, r);
678+ devFunc0006(r->ireg[0x31], r->ireg[0x32], r->ireg[0x33], r->ireg[0x34], r->ireg[0x35], loadColor(r, 0x36), len, pucbuf, r);
679+ break;
680+
681+ case 0xff4d:
682+ // bitblt(mod, xsiz, ysiz, xscale, yscale, x0, y0, lineskip, inv, p_buf, typ0, p_table, typ1);
683+ // mod: 0x20:use_table, 0x40:inv_is_visible & typ1_is_color
684+ puc = r->preg[0x31].p;
685+ mod3 = r->ireg[0x31] & 3;
686+ dx = r->ireg[0x34];
687+ dy = r->ireg[0x35];
688+ if (dy == 0){
689+ dy = dx;
690+ }
691+ if (r->ireg[0x32] == -1) {
692+ r->ireg[0x32] = mainWindow.xsize / dx; r->ireg[0x36] &= 0;
693+ }
694+ if (r->ireg[0x33] == -1) {
695+ r->ireg[0x33] = mainWindow.ysize / dy; r->ireg[0x37] &= 0;
696+ }
697+ for (y = 0; y < r->ireg[0x33]; y++) {
698+ y0 = y * dy + r->ireg[0x37];
699+ for (x = 0; x < r->ireg[0x32]; x++) {
700+ x0 = x * dx + r->ireg[0x36];
701+ c = iColor1[*puc++];
702+ devFunc0004(mod3, x0, y0, x0 + dx, y0 + dy, c);
703+ }
704+ puc += r->ireg[0x38];
705+ }
706+ break;
707+
708+ default:
709+ printf("devFunc: error: R30=%08X\n", r->ireg[0x30]);
710+ exit(EXIT_FAILURE);
711+
712+ }
713+ return;
714+}
715+
716+
717+
--- a/jitc.c
+++ b/jitc.c
@@ -1,69 +1,69 @@
1-#include "osecpu.h"
2-#include "jitc.h"
3-
4-//
5-// JITC common functions (architecture not dependent)
6-//
7-
8-void errorHandler(HOSECPU_RuntimeEnvironment *r)
9-{
10- puts("security error! abort...");
11- printf("debugInfo0=%d, debugInfo1=%d\n", r->debugInfo0, r->debugInfo1);
12-#if (USE_DEBUGGER != 0)
13- dbgrMain(r);
14-#endif
15- exit(1);
16-}
17-
18-int jitCompCmdLen(const unsigned char *src)
19-{
20- //BCode命令長を取得する
21- int i = 1;
22-
23- if (0x01 <= *src && *src < 0x04){
24- // LB, LIMM, PLIMM
25- i = 6;
26- } else if (*src == 0x04){
27- // CND
28- i = 2;
29- } else if (0x08 <= *src && *src < 0x0d){
30- // LMEM, SMEM, ??, ??, ??
31- i = 8 + src[7] * 4;
32- } else if (0x0e <= *src && *src < 0x10){
33- // PADD, PDIF
34- i = 8;
35- } else if (0x10 <= *src && *src < 0x1c){
36- // CP/OR, XOR, AND, ADD, SUB, MUL, SHL, SAR, DIV, MOD,
37- i = 4;
38- } else if (0x1c <= *src && *src < 0x1f){
39- // ??, ??, PCP
40- i = 3;
41- } else if (*src == 0x1f){
42- // ??
43- i = 11;
44- } else if(0x20 <= *src && *src < 0x2e){
45- // CMPE, CMPNE, CMPL, CMPGE, CMPLE, CMPG, TSTZ, TSTNZ,
46- // PCMPE, PCMPNE, PCMPL, PCMPGE, PCMPLE, PCMPG,
47- i = 4;
48- } else if (*src == 0x2f){
49- // ??
50- i = 4 + src[1];
51- } else if (0x30 <= *src && *src < 0x34){
52- // ??, ??, MALLOC, ??
53- i = 4;
54- } else if (0x3c <= *src && *src < 0x3e){
55- // ??, ??
56- i = 7;
57- } else if (*src == 0xfe){
58- // REMARK
59- i = 2 + src[1];
60- }
61-
62- return i;
63-}
64-
65-
66-
67-
68-
69-
1+#include "osecpu.h"
2+#include "jitc.h"
3+
4+//
5+// JITC common functions (architecture not dependent)
6+//
7+
8+void errorHandler(HOSECPU_RuntimeEnvironment *r)
9+{
10+ puts("security error! abort...");
11+ printf("debugInfo0=%d, debugInfo1=%d\n", r->debugInfo0, r->debugInfo1);
12+#if (USE_DEBUGGER != 0)
13+ dbgrMain(r);
14+#endif
15+ exit(1);
16+}
17+
18+int jitCompCmdLen(const unsigned char *src)
19+{
20+ //BCode命令長を取得する
21+ int i = 1;
22+
23+ if (0x01 <= *src && *src < 0x04){
24+ // LB, LIMM, PLIMM
25+ i = 6;
26+ } else if (*src == 0x04){
27+ // CND
28+ i = 2;
29+ } else if (0x08 <= *src && *src < 0x0d){
30+ // LMEM, SMEM, ??, ??, ??
31+ i = 8 + src[7] * 4;
32+ } else if (0x0e <= *src && *src < 0x10){
33+ // PADD, PDIF
34+ i = 8;
35+ } else if (0x10 <= *src && *src < 0x1c){
36+ // CP/OR, XOR, AND, ADD, SUB, MUL, SHL, SAR, DIV, MOD,
37+ i = 4;
38+ } else if (0x1c <= *src && *src < 0x1f){
39+ // ??, ??, PCP
40+ i = 3;
41+ } else if (*src == 0x1f){
42+ // ??
43+ i = 11;
44+ } else if(0x20 <= *src && *src < 0x2e){
45+ // CMPE, CMPNE, CMPL, CMPGE, CMPLE, CMPG, TSTZ, TSTNZ,
46+ // PCMPE, PCMPNE, PCMPL, PCMPGE, PCMPLE, PCMPG,
47+ i = 4;
48+ } else if (*src == 0x2f){
49+ // ??
50+ i = 4 + src[1];
51+ } else if (0x30 <= *src && *src < 0x34){
52+ // ??, ??, MALLOC, ??
53+ i = 4;
54+ } else if (0x3c <= *src && *src < 0x3e){
55+ // ??, ??
56+ i = 7;
57+ } else if (*src == 0xfe){
58+ // REMARK
59+ i = 2 + src[1];
60+ }
61+
62+ return i;
63+}
64+
65+
66+
67+
68+
69+
--- a/jitc.h
+++ b/jitc.h
@@ -1,118 +1,118 @@
1-
2-#ifndef HeavyOSECPU_jitc_h
3-#define HeavyOSECPU_jitc_h
4-
5-// Error flags
6-#define JITC_ERR_MASK 255
7-#define JITC_ERR_PHASE0ONLY 256
8-#define JITC_ERR_REGNUM (1 | JITC_ERR_PHASE0ONLY)
9-#define JITC_ERR_DST1 (2 | JITC_ERR_PHASE0ONLY)
10-#define JITC_ERR_OPECODE (3 | JITC_ERR_PHASE0ONLY)
11-#define JITC_ERR_LABELNUM (4 | JITC_ERR_PHASE0ONLY)
12-#define JITC_ERR_LABELREDEF (5 | JITC_ERR_PHASE0ONLY)
13-#define JITC_ERR_PREFIX (6 | JITC_ERR_PHASE0ONLY)
14-#define JITC_ERR_LABELNODEF 7
15-#define JITC_ERR_LABELTYP 8
16-#define JITC_ERR_IDIOM 9
17-#define JITC_ERR_PREGNUM (10 | JITC_ERR_PHASE0ONLY)
18-#define JITC_ERR_SRC1 (11 | JITC_ERR_PHASE0ONLY)
19-#define JITC_ERR_BADTYPE (12 | JITC_ERR_PHASE0ONLY)
20-#define JITC_ERR_PREFIXFAR (13 | JITC_ERR_PHASE0ONLY)
21-#define JITC_ERR_INTERNAL 99
22-
23-// Byte operations
24-#define jitCompPutByte1(p, c0) *p++ = c0
25-#define jitCompPutByte2(p, c0, c1) *p++ = c0; *p++ = c1
26-#define jitCompPutByte3(p, c0, c1, c2) *p++ = c0; *p++ = c1; *p++ = c2
27-#define jitCompPutByte4(p, c0, c1, c2, c3) *p++ = c0; *p++ = c1; *p++ = c2; *p++ = c3
28-
29-//
30-// functions (jitc internal)
31-//
32-
33-// @jitc.c
34-void errorHandler(HOSECPU_RuntimeEnvironment *r);
35-int jitCompCmdLen(const unsigned char *src);
36-
37-// @jitcx86.c
38-#if (JITC_ARCNUM == 0x0001)
39-//
40-// for x86-32bit
41-//
42-
43-// 他のCPUへ移植する人へ:
44-// 以下の定数は最適化のためのものなので、すべて0として簡単に移植しても問題ありません
45-#define jitCompA0001_USE_R3F_CMPJMP 1*1
46-#define jitCompA0001_USE_R3F_IMM32 1*1
47-#define jitCompA0001_USE_R3F_IMM8 1*1
48-#define jitCompA0001_USE_R3F_INCDEC 1*1
49-#define jitCompA0001_OPTIMIZE_JMP 1*1
50-#define jitCompA0001_OPTIMIZE_MOV 1*1 /* 1にすると速度低下する? */
51-#define jitCompA0001_OPTIMIZE_CMP 1*1
52-#define jitCompA0001_OPTIMIZE_ALIGN 4*1 /* 0-8を想定 */
53-#define jitCompA0001_EBP128 128*1
54-
55-struct JitCompWork {
56- unsigned char *dst, *dst0;
57- int err, maxLabels;
58-#if (jitCompA0001_USE_R3F_IMM32 != 0)
59- int r3f;
60-#endif
61- char prefix; //CND命令の値を記録(初期値=0)
62-};
63-
64-void jitCompPutImm32(struct JitCompWork *w, int i);
65-int jitCompGetImm32(const unsigned char *src);
66-int jitCompGetLabelNum(struct JitCompWork *w, const unsigned char *src);
67-void jitCompA0001_85DispN(struct JitCompWork *w, int disp, int n);
68-void jitCompA0001_movEbpDispReg32(struct JitCompWork *w, int disp, int reg32);
69-void jitCompA0001_movReg32EbpDisp(struct JitCompWork *w, int reg32, int disp);
70-void jitCompA0001_movEaxRxx(struct JitCompWork *w, int rxx);
71-void jitCompA0001_movRxxEax(struct JitCompWork *w, int rxx);
72-void jitCompA0001_fixPrefix(struct JitCompWork *w);
73-void jitCompA0001_checkCompPtr(struct JitCompWork *w, int p0, int p1);
74-void jitCompA000_loadRegCacheAll(struct JitCompWork *w);
75-void jitCompA000_storeRegCacheAll(struct JitCompWork *w);
76-void jitCompA000_loadRegCacheEcx(struct JitCompWork *w);
77-void jitCompA000_storeRegCacheEcx(struct JitCompWork *w);
78-void jitCompA000_loadRegCacheEdx(struct JitCompWork *w);
79-void jitCompA000_storeRegCacheEdx(struct JitCompWork *w);
80-int jitCompA000_selectRegCache(int rxx, int reg);
81-void jitCompA000_loadPRegCacheAll(struct JitCompWork *w);
82-void jitCompA000_storePRegCacheAll(struct JitCompWork *w);
83-int jitCompA000_selectPRegCache(int pxx, int reg);
84-int jitCompA000_convTyp(int t);
85-int jitCompA000_dataWidth(int t);
86-void jitCompA0001_checkType0(struct JitCompWork *w, int pxx, int typ, int ac);
87-void jitCompA0001_checkType(struct JitCompWork *w, int pxx, int typ, int ac);
88-void jitCompA0001_checkLimit(struct JitCompWork *w, int reg, int pxx);
89-int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *src, const unsigned char *src1, const unsigned char *src0, HOSECPU_LabelListTag *label, int maxLabels, int level, int debugInfo1, int flags);
90-unsigned char *jitCompCallFunc(unsigned char *dst, void *func);
91-unsigned char *jitCompInit(unsigned char *dst);
92-void func3c(char *ebp, int opt, int r1, int p1, int lenR, int lenP, int r0, int p0);
93-void func3d(char *ebp, int opt, int r1, int p1, int lenR, int lenP, int r0, int p0);
94-void funcf4(char *ebp, int pxx, int typ, int len);
95-void funcf5(char *ebp, int pxx, int typ, int len);
96-void funcf6(char *ebp, int pxx, int typ, int len);
97-void funcf7(char *ebp, int pxx, int typ, int len);
98-void errHndl(HOSECPU_RuntimeEnvironment *r);
99-int jitc0(unsigned char **qq, unsigned char *q1, const unsigned char *p0, const unsigned char *p1, int level, HOSECPU_LabelListTag *label);
100-#if (USE_DEBUGGER != 0)
101-int dbgrGetRegNum(const char *p);
102-void dbgrMain(HOSECPU_RuntimeEnvironment *r);
103-#endif
104-
105-
106-
107-
108-
109-
110-
111-
112-
113-
114-
115-
116-#endif
117-
118-#endif
1+
2+#ifndef HeavyOSECPU_jitc_h
3+#define HeavyOSECPU_jitc_h
4+
5+// Error flags
6+#define JITC_ERR_MASK 255
7+#define JITC_ERR_PHASE0ONLY 256
8+#define JITC_ERR_REGNUM (1 | JITC_ERR_PHASE0ONLY)
9+#define JITC_ERR_DST1 (2 | JITC_ERR_PHASE0ONLY)
10+#define JITC_ERR_OPECODE (3 | JITC_ERR_PHASE0ONLY)
11+#define JITC_ERR_LABELNUM (4 | JITC_ERR_PHASE0ONLY)
12+#define JITC_ERR_LABELREDEF (5 | JITC_ERR_PHASE0ONLY)
13+#define JITC_ERR_PREFIX (6 | JITC_ERR_PHASE0ONLY)
14+#define JITC_ERR_LABELNODEF 7
15+#define JITC_ERR_LABELTYP 8
16+#define JITC_ERR_IDIOM 9
17+#define JITC_ERR_PREGNUM (10 | JITC_ERR_PHASE0ONLY)
18+#define JITC_ERR_SRC1 (11 | JITC_ERR_PHASE0ONLY)
19+#define JITC_ERR_BADTYPE (12 | JITC_ERR_PHASE0ONLY)
20+#define JITC_ERR_PREFIXFAR (13 | JITC_ERR_PHASE0ONLY)
21+#define JITC_ERR_INTERNAL 99
22+
23+// Byte operations
24+#define jitCompPutByte1(p, c0) *p++ = c0
25+#define jitCompPutByte2(p, c0, c1) *p++ = c0; *p++ = c1
26+#define jitCompPutByte3(p, c0, c1, c2) *p++ = c0; *p++ = c1; *p++ = c2
27+#define jitCompPutByte4(p, c0, c1, c2, c3) *p++ = c0; *p++ = c1; *p++ = c2; *p++ = c3
28+
29+//
30+// functions (jitc internal)
31+//
32+
33+// @jitc.c
34+void errorHandler(HOSECPU_RuntimeEnvironment *r);
35+int jitCompCmdLen(const unsigned char *src);
36+
37+// @jitcx86.c
38+#if (JITC_ARCNUM == 0x0001)
39+//
40+// for x86-32bit
41+//
42+
43+// 他のCPUへ移植する人へ:
44+// 以下の定数は最適化のためのものなので、すべて0として簡単に移植しても問題ありません
45+#define jitCompA0001_USE_R3F_CMPJMP 1*1
46+#define jitCompA0001_USE_R3F_IMM32 1*1
47+#define jitCompA0001_USE_R3F_IMM8 1*1
48+#define jitCompA0001_USE_R3F_INCDEC 1*1
49+#define jitCompA0001_OPTIMIZE_JMP 1*1
50+#define jitCompA0001_OPTIMIZE_MOV 1*1 /* 1にすると速度低下する? */
51+#define jitCompA0001_OPTIMIZE_CMP 1*1
52+#define jitCompA0001_OPTIMIZE_ALIGN 4*1 /* 0-8を想定 */
53+#define jitCompA0001_EBP128 128*1
54+
55+struct JitCompWork {
56+ unsigned char *dst, *dst0;
57+ int err, maxLabels;
58+#if (jitCompA0001_USE_R3F_IMM32 != 0)
59+ int r3f;
60+#endif
61+ char prefix; //CND命令の値を記録(初期値=0)
62+};
63+
64+void jitCompPutImm32(struct JitCompWork *w, int i);
65+int jitCompGetImm32(const unsigned char *src);
66+int jitCompGetLabelNum(struct JitCompWork *w, const unsigned char *src);
67+void jitCompA0001_85DispN(struct JitCompWork *w, int disp, int n);
68+void jitCompA0001_movEbpDispReg32(struct JitCompWork *w, int disp, int reg32);
69+void jitCompA0001_movReg32EbpDisp(struct JitCompWork *w, int reg32, int disp);
70+void jitCompA0001_movEaxRxx(struct JitCompWork *w, int rxx);
71+void jitCompA0001_movRxxEax(struct JitCompWork *w, int rxx);
72+void jitCompA0001_fixPrefix(struct JitCompWork *w);
73+void jitCompA0001_checkCompPtr(struct JitCompWork *w, int p0, int p1);
74+void jitCompA000_loadRegCacheAll(struct JitCompWork *w);
75+void jitCompA000_storeRegCacheAll(struct JitCompWork *w);
76+void jitCompA000_loadRegCacheEcx(struct JitCompWork *w);
77+void jitCompA000_storeRegCacheEcx(struct JitCompWork *w);
78+void jitCompA000_loadRegCacheEdx(struct JitCompWork *w);
79+void jitCompA000_storeRegCacheEdx(struct JitCompWork *w);
80+int jitCompA000_selectRegCache(int rxx, int reg);
81+void jitCompA000_loadPRegCacheAll(struct JitCompWork *w);
82+void jitCompA000_storePRegCacheAll(struct JitCompWork *w);
83+int jitCompA000_selectPRegCache(int pxx, int reg);
84+int jitCompA000_convTyp(int t);
85+int jitCompA000_dataWidth(int t);
86+void jitCompA0001_checkType0(struct JitCompWork *w, int pxx, int typ, int ac);
87+void jitCompA0001_checkType(struct JitCompWork *w, int pxx, int typ, int ac);
88+void jitCompA0001_checkLimit(struct JitCompWork *w, int reg, int pxx);
89+int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *src, const unsigned char *src1, const unsigned char *src0, HOSECPU_LabelListTag *label, int maxLabels, int level, int debugInfo1, int flags);
90+unsigned char *jitCompCallFunc(unsigned char *dst, void *func);
91+unsigned char *jitCompInit(unsigned char *dst);
92+void func3c(char *ebp, int opt, int r1, int p1, int lenR, int lenP, int r0, int p0);
93+void func3d(char *ebp, int opt, int r1, int p1, int lenR, int lenP, int r0, int p0);
94+void funcf4(char *ebp, int pxx, int typ, int len);
95+void funcf5(char *ebp, int pxx, int typ, int len);
96+void funcf6(char *ebp, int pxx, int typ, int len);
97+void funcf7(char *ebp, int pxx, int typ, int len);
98+void errHndl(HOSECPU_RuntimeEnvironment *r);
99+int jitc0(unsigned char **qq, unsigned char *q1, const unsigned char *p0, const unsigned char *p1, int level, HOSECPU_LabelListTag *label);
100+#if (USE_DEBUGGER != 0)
101+int dbgrGetRegNum(const char *p);
102+void dbgrMain(HOSECPU_RuntimeEnvironment *r);
103+#endif
104+
105+
106+
107+
108+
109+
110+
111+
112+
113+
114+
115+
116+#endif
117+
118+#endif
--- a/jitcx86.c
+++ b/jitcx86.c
@@ -1,1711 +1,1711 @@
1-#include "osecpu.h"
2-#include "jitc.h"
3-
4-#if (JITC_ARCNUM == 0x0001)
5-//
6-// for x86-32bit
7-//
8-
9-void jitCompPutImm32(struct JitCompWork *w, int i)
10-{
11- jitCompPutByte1(w->dst, i & 0xff);
12- jitCompPutByte1(w->dst, (i >> 8) & 0xff);
13- jitCompPutByte1(w->dst, (i >> 16) & 0xff);
14- jitCompPutByte1(w->dst, (i >> 24) & 0xff);
15- return;
16-}
17-
18-int jitCompGetImm32(const unsigned char *src)
19-{
20- return (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
21-}
22-
23-int jitCompGetLabelNum(struct JitCompWork *w, const unsigned char *src)
24-{
25- int i = jitCompGetImm32(src);
26- if (i < 0 || i >= w->maxLabels) {
27- w->err = JITC_ERR_LABELNUM;
28- i = 0;
29- }
30- return i;
31-}
32-
33-void jitCompA0001_85DispN(struct JitCompWork *w, int disp, int n)
34-{
35- disp -= jitCompA0001_EBP128;
36- if (-128 <= disp && disp <= 127) {
37- jitCompPutByte2(w->dst, 0x45 | (n << 3), disp & 0xff);
38- } else {
39- jitCompPutByte1(w->dst, 0x85 | (n << 3));
40- jitCompPutImm32(w, disp);
41- }
42- return;
43-}
44-
45-void jitCompA0001_movEbpDispReg32(struct JitCompWork *w, int disp, int reg32)
46-{
47- jitCompPutByte1(w->dst, 0x89); /* MOV(mem, reg32); */
48- jitCompA0001_85DispN(w, disp, reg32);
49- return;
50-}
51-
52-void jitCompA0001_movReg32EbpDisp(struct JitCompWork *w, int reg32, int disp)
53-{
54- jitCompPutByte1(w->dst, 0x8b); /* MOV(reg32, mem); */
55- jitCompA0001_85DispN(w, disp, reg32);
56- return;
57-}
58-
59-void jitCompA0001_movEaxRxx(struct JitCompWork *w, int rxx)
60-{
61-#if (jitCompA0001_USE_R3F_IMM32 != 0)
62- if (rxx == 0x3f) {
63- jitCompPutByte1(w->dst, 0xb8); /* MOV(EAX, ?); */
64- jitCompPutImm32(w, w->r3f);
65- return;
66- }
67-#endif
68- if (rxx >= 0x40 || rxx < 0){
69- w->err = JITC_ERR_REGNUM;
70- }
71- jitCompA0001_movReg32EbpDisp(w, 0 /* EAX */, rxx * 4); /* MOV(EAX, [EBP+?]); */
72- return;
73-}
74-
75-void jitCompA0001_movRxxEax(struct JitCompWork *w, int rxx)
76-{
77- if (rxx >= 0x40 || rxx < 0){
78- w->err = JITC_ERR_REGNUM;
79- }
80- jitCompA0001_movEbpDispReg32(w, rxx * 4, 0 /* EAX */); /* MOV([EBP+?], EAX); */
81- return;
82-}
83-
84-void jitCompA0001_fixPrefix(struct JitCompWork *w)
85-{
86- if (w->prefix != 0) {
87- if (w->dst - w->dst0 > 127){
88- w->err = JITC_ERR_REGNUM;
89- }
90- w->dst0[-1] = (unsigned char)((w->dst - w->dst0) & 0xff);
91- }
92- return;
93-}
94-
95-void jitCompA0001_checkCompPtr(struct JitCompWork *w, int p0, int p1)
96-{
97- if (p0 >= 0x3f || p0 < 0){
98- w->err = JITC_ERR_PREGNUM;
99- }
100- if (p1 >= 0x3f || p1 < 0){
101- w->err = JITC_ERR_PREGNUM;
102- }
103- /* 比較可能可能なのかのチェックのコードを出力 */ /* 未完成 */
104- return;
105-}
106-
107-void jitCompA000_loadRegCacheAll(struct JitCompWork *w)
108-{
109- jitCompA0001_movReg32EbpDisp(w, 3 /* EBX */, 0 * 4); /* EBX = R00; */
110- jitCompA0001_movReg32EbpDisp(w, 1 /* ECX */, 1 * 4); /* ECX = R01; */
111- jitCompA0001_movReg32EbpDisp(w, 2 /* EDX */, 2 * 4); /* EDX = R02; */
112- return;
113-}
114-
115-void jitCompA000_storeRegCacheAll(struct JitCompWork *w)
116-{
117- jitCompA0001_movEbpDispReg32(w, 0 * 4, 3 /* EBX */); /* R00 = EBX; */
118- jitCompA0001_movEbpDispReg32(w, 1 * 4, 1 /* ECX */); /* R01 = ECX; */
119- jitCompA0001_movEbpDispReg32(w, 2 * 4, 2 /* EDX */); /* R02 = EDX; */
120- return;
121-}
122-
123-void jitCompA000_loadRegCacheEcx(struct JitCompWork *w)
124-{
125- jitCompA0001_movReg32EbpDisp(w, 1 /* ECX */, 1 * 4); /* ECX = R01; */
126- return;
127-}
128-
129-void jitCompA000_storeRegCacheEcx(struct JitCompWork *w)
130-{
131- jitCompA0001_movEbpDispReg32(w, 1 * 4, 1 /* ECX */); /* R01 = ECX; */
132- return;
133-}
134-
135-void jitCompA000_loadRegCacheEdx(struct JitCompWork *w)
136-{
137- jitCompA0001_movReg32EbpDisp(w, 2 /* EDX */, 2 * 4); /* EDX = R02; */
138- return;
139-}
140-
141-void jitCompA000_storeRegCacheEdx(struct JitCompWork *w)
142-{
143- jitCompA0001_movEbpDispReg32(w, 2 * 4, 2 /* EDX */); /* R02 = EDX; */
144- return;
145-}
146-
147-int jitCompA000_selectRegCache(int rxx, int reg)
148-{
149- switch (rxx) {
150- case 0:
151- //EBX
152- reg = 3;
153- break;
154- case 1:
155- //ECX
156- reg = 1;
157- break;
158- case 2:
159- //EDX
160- reg = 2;
161- break;
162- }
163- return reg;
164-}
165-
166-void jitCompA000_loadPRegCacheAll(struct JitCompWork *w)
167-{
168- // jitCompA0001_movReg32EbpDisp(w, 5 /* EBP */, 256 + 0 * 32 + 0); /* EBP = P00; */
169- jitCompA0001_movReg32EbpDisp(w, 6 /* ESI */, 256 + 1 * 32 + 0); /* ESI = P01; */
170- jitCompA0001_movReg32EbpDisp(w, 7 /* EDI */, 256 + 2 * 32 + 0); /* EDI = P02; */
171- return;
172-}
173-
174-void jitCompA000_storePRegCacheAll(struct JitCompWork *w)
175-{
176- // jitCompA0001_movEbpDispReg32(w, 256 + 0 * 32 + 0, 5 /* EBP */); /* P00 = EBP; */
177- jitCompA0001_movEbpDispReg32(w, 256 + 1 * 32 + 0, 6 /* ESI */); /* P01 = ESI; */
178- jitCompA0001_movEbpDispReg32(w, 256 + 2 * 32 + 0, 7 /* EDI */); /* P02 = EDI; */
179- return;
180-}
181-
182-int jitCompA000_selectPRegCache(int pxx, int reg)
183-{
184- // if (pxx == 0) reg = 5; /* EBP */
185- switch (pxx) {
186- case 1:
187- //ESI
188- reg = 6;
189- break;
190-
191- case 2:
192- //EDI
193- reg = 7;
194- break;
195- }
196- return reg;
197-}
198-
199-int jitCompA000_convTyp(int t)
200-{
201- int r = -1;
202-
203- if (1 <= t && t <= 7){
204- r = t;
205- } else if (8 <= t && t <= 13){
206- r = 2 | (t & 1);
207- } else if (14 <= t && t <= 15){
208- r = 4 | (t & 1);
209- } else if (16 <= t && t <= 21){
210- r = 6 | (t & 1);
211- }
212- return r;
213-}
214-
215-int jitCompA000_dataWidth(int t)
216-{
217- int r = -1;
218- if (t == 0x0001) r = 256;
219- t >>= 1;
220- if (t == 0x0002 / 2) r = 8;
221- if (t == 0x0004 / 2) r = 16;
222- if (t == 0x0006 / 2) r = 32;
223- if (t == 0x0008 / 2) r = 4;
224- if (t == 0x000a / 2) r = 2;
225- if (t == 0x000c / 2) r = 1;
226- if (t == 0x000e / 2) r = 12;
227- if (t == 0x0010 / 2) r = 20;
228- if (t == 0x0012 / 2) r = 24;
229- if (t == 0x0014 / 2) r = 28;
230- return r;
231-}
232-
233-static unsigned char *errfnc;
234-
235-void jitCompA0001_checkType0(struct JitCompWork *w, int pxx, int typ, int ac)
236-{
237- if (typ <= 0) { w->err = JITC_ERR_BADTYPE; }
238- if (typ > 0x7f) { w->err = JITC_ERR_INTERNAL; }
239- jitCompA0001_movReg32EbpDisp(w, 0 /* EAX */, 256 + pxx * 32 + 4); /* MOV(EAX, [EBP+?]); */ /* typ */
240- jitCompPutByte3(w->dst, 0x83, 0xf8, typ & 0x7f); /* CMP(EAX, ?); */
241- jitCompPutByte2(w->dst, 0x0f, 0x85); /* JNE */
242- jitCompPutImm32(w, errfnc - (w->dst + 4));
243- return;
244-}
245-
246-void jitCompA0001_checkType(struct JitCompWork *w, int pxx, int typ, int ac)
247-// data用.
248-// 将来的にはaliveやアクセス権チェックも入れる
249-{
250- jitCompA0001_checkType0(w, pxx, typ, ac);
251- return;
252-}
253-
254-void jitCompA0001_checkLimit(struct JitCompWork *w, int reg, int pxx)
255-{
256- jitCompPutByte1(w->dst, 0x3b); /* CMP(reg, [EBP+?]); */
257- jitCompA0001_85DispN(w, 256 + pxx * 32 + 8, reg); /* p0 */
258- jitCompPutByte2(w->dst, 0x0f, 0x82); /* JB */
259- jitCompPutImm32(w, errfnc - (w->dst + 4));
260- jitCompPutByte1(w->dst, 0x3b); /* CMP(reg, [EBP+?]); */
261- jitCompA0001_85DispN(w, 256 + pxx * 32 + 12, reg); /* p1 */
262- jitCompPutByte2(w->dst, 0x0f, 0x83); /* JAE */
263- jitCompPutImm32(w, errfnc - (w->dst + 4));
264- return;
265-}
266-
267-// F5の場合、decoderが対応するalloc-freeを結びつけるのが簡単で、typやlenを指定必須にしてもフロントエンドコードに影響はない.
268-int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *src, const unsigned char *src1, const unsigned char *src0, HOSECPU_LabelListTag *label, int maxLabels, int level, int debugInfo1, int flags)
269-{
270- // For IA-32 (x86, 32-bit)
271- // 本来ならこのレイヤでは文法チェックしない
272- //
273- // dst : 現在の書き込みアドレス。
274- // dst1 : 書き込みアドレスの最大値
275- // src : 現在の読み込みアドレス(ヘッダ部は飛ばしてある
276- // src1 : 読み込みアドレスの最大値
277- // src0 : 読み込みバイナリのアドレス
278- struct JitCompWork w;
279- unsigned char *dst00 = dst, *enter0 = NULL, *tmp_ucp;
280- char *errmsg = "";
281- const unsigned char *oldsrc;
282- int timecount = 0, i, j = 0, lastlabel = -1, debugInfo0 = -1;
283- int reg0, reg1, reg2, cmp0reg = -1, cmp0lev = 0;
284- w.dst = w.dst0 = dst;
285- w.err = 0;
286- w.maxLabels = maxLabels;
287-
288- if ((flags & JITC_NOSTARTUP) == 0) {
289- jitCompPutByte1(w.dst, 0x60); /* PUSHAD(); */
290- jitCompA000_loadRegCacheAll(&w); /* start-up */
291- jitCompA000_loadPRegCacheAll(&w);
292- }
293- if (level <= JITC_LV_SLOWER) {
294- jitCompPutByte2(w.dst, 0x31, 0xc0); /* XOR(EAX, EAX); */
295- jitCompA0001_movEbpDispReg32(&w, 2304 + 0, 0 /* EAX */); /* MOV(debugInfo0, EAX); */
296- jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */
297- jitCompPutImm32(&w, debugInfo1);
298- jitCompA0001_movEbpDispReg32(&w, 2304 + 4, 0 /* EAX */); /* MOV(debugInfo1, EAX); */
299- }
300- while (src < src1) {
301- w.prefix = 0; //0x04 CND 命令で変更される
302- if (w.dst + 256 > dst1) { w.err = JITC_ERR_DST1; goto err_w; } // 書き込み領域が残り256バイト未満ならエラー
303- timecount++;
304- if (timecount >= 64) {
305- timecount -= 64;
306- /* 未完成(timeoutチェックコードを入れる) */
307- }
308- prefix_continue: // CND命令実行後ここに戻る
309- switch (*src) {
310-
311- case 0x00: /* NOP */
312- if (w.prefix != 0) { w.err = JITC_ERR_PREFIX; goto err_w; } // 「条件付きでNOPを実行」するなんて、矛盾している!
313- break;
314-
315- case 0x01: /* LB */
316-
317- /*
318- * LB : ラベル設置命令。(6byte)
319- * ・prefex = 1にする
320- * ・timecount++し、timecountのチェックをする。
321- * ・ラベル位置を登録する。
322- * ・割り込みがある場合、このタイミングで割り込みを発生させる。
323- *
324- * 1 2 3 456
325- * LB 01 opt imm32
326- *
327- */
328-
329- if (enter0 == NULL && (src[6] == 0x3c /* 多数のレジスタをスタックに退避 */ || (src[6] == 0xfe/* REMARK */ && src[7] == 0x01 && src[9] == 0x3c))) { //beginFunc()中のLB
330- // LB命令の後に0x3C命令・・・beginFunc()
331- jitCompPutByte1(w.dst, 0xe9); // (x86) JMP rel32 : 次の命令との相対オフセットだけ相対ニアジャンプする
332- enter0 = w.dst;
333- jitCompPutImm32(&w, 0); // 飛び相対座標が0 ・・・パイプラインのフラッシュ??
334- }
335- if (src[6] == 0x34) { // LBの次の命令がDATA ・・・DAT_SA0(label, typ32, length) ・・・メモリ確保命令
336- tmp_ucp = w.dst;
337- jitCompPutByte1(w.dst, 0xe9); // (x86) JMP rel32 : 次の命令との相対オフセットだけ相対ニアジャンプする
338- i = jitCompGetImm32(&src[7]); // type32 を取得
339- j = 32;
340- if (i != 1) {
341- i = jitCompA000_convTyp(i);
342- j = 0;
343- if (i == 2 || i == 3) { j = 1; }
344- if (i == 4 || i == 5) { j = 2; }
345- if (i == 6 || i == 7) { j = 4; }
346- }
347- j *= jitCompGetImm32(&src[11]);
348- if (j <= 0) w.err = JITC_ERR_BADTYPE;
349- jitCompPutImm32(&w, j);
350-#if (jitCompA0001_OPTIMIZE_JMP != 0)
351- if (j <= 127 - jitCompA0001_OPTIMIZE_ALIGN) {
352- w.dst -= 5;
353- jitCompPutByte2(w.dst, 0xeb, j);
354- }
355-#endif
356- }
357-#if (jitCompA0001_OPTIMIZE_ALIGN != 0)
358- for (;;) {
359- i = ((int)w.dst) & (jitCompA0001_OPTIMIZE_ALIGN - 1); /* ALIGNで割ったあまりを計算 */
360- if (i == 0) break;
361- i = jitCompA0001_OPTIMIZE_ALIGN - i;
362- if (i == 1) { jitCompPutByte1(w.dst, 0x90); j += i; } /* NOP(); */
363- if (i == 2) { jitCompPutByte2(w.dst, 0x89, 0xc0); j += i; } /* MOV(EAX, EAX); */
364- if (i == 3) { jitCompPutByte3(w.dst, 0x8d, 0x76, 0x00); j += i; } /* LEA(ESI, [ESI+0]); */
365- if (i == 4) { jitCompPutByte4(w.dst, 0x8d, 0x74, 0x26, 0x00); j += i; } /* LEA(ESI, [ESI*1+0]); */
366- if (i == 5) { jitCompPutByte1(w.dst, 0x0d); jitCompPutImm32(&w, 0); j += i; } /* OR(EAX, 0); */
367- if (i == 6) { jitCompPutByte2(w.dst, 0x8d, 0xb6); jitCompPutImm32(&w, 0); j += i; } /* LEA(ESI, [ESI+0]); */
368- if (i >= 7) { jitCompPutByte3(w.dst, 0x8d, 0xb4, 0x26); jitCompPutImm32(&w, 0); j += 7; } /* LEA(ESI, [ESI*1+0]); */
369- }
370-#endif
371- if (src[6] == 0x34) {
372- tmp_ucp[1] = j & 0xff;
373- if (*tmp_ucp == 0xe9) {
374- tmp_ucp[2] = (j >> 8) & 0xff;
375- tmp_ucp[3] = (j >> 16) & 0xff;
376- tmp_ucp[4] = (j >> 24) & 0xff;
377- }
378- }
379- if ((flags & JITC_PHASE1) == 0) {
380- i = jitCompGetLabelNum(&w, src + 2);
381- //printf("i=%06X %06X\n", i, src-src0);
382- if (label[i].opt != 0 && w.err == 0) { w.err = JITC_ERR_LABELREDEF; goto err_w; }
383- if (w.prefix != 0) { w.err = JITC_ERR_PREFIX; goto err_w; }
384- label[i].opt = src[1] + 1;
385- label[i].typ = 0; /* TYP_CODE */
386- label[i].p = w.dst;
387- label[i].p1 = w.dst + 1;
388- lastlabel = i;
389- }
390- cmp0reg = -1;
391- timecount = 0;
392- /* 未完成(timeoutチェックコードを入れる) */
393- break;
394-
395- case 0x02: /* LIMM */
396-
397- /*
398- * LIMM : 定数即値代入命令(6byte)
399- *
400- * 1 2 3456
401- * 02 reg0R imm32
402- *
403- * ・reg3F は条件比較慣用句指定用&演算命令即値慣用句指定用。よってCND命令の直後では使用できない。
404- */
405-
406- if (src[1] == 0x3f && w.prefix != 0) w.err = JITC_ERR_PREFIX; // CND命令の直後でR3Fを書き換えるなんて変だよね
407-
408-#if (jitCompA0001_USE_R3F_IMM32 != 0)
409- if (src[1] == 0x3f) { // R3Fへの代入は例外敵に、 w.r3f を使用
410- w.r3f = jitCompGetImm32(src + 2);
411- break;
412- }
413-#endif
414- i = jitCompGetImm32(src + 2); // 与えられた即値(第二引数)を取得
415-
416- /* R00-R02 なら EBX, ECX, EDX 、それ以外なら EAX のレジスタIDを reg0 に代入 */
417- reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */);
418-
419-#if (jitCompA0001_OPTIMIZE_MOV != 0)
420- if (i == 0) {
421- jitCompPutByte2(w.dst, 0x31, 0xc0 | reg0 << 3 | reg0); /* XOR(reg0, reg0); */
422- jitCompA0001_movRxxEax(&w, src[1]);
423- break;
424- }
425-#endif
426-
427- /* reg0 のレジスタに対応したMOV命令を発行 */
428- jitCompPutByte1(w.dst, 0xb8 | reg0); /* MOV(reg0, ?); == 10111000b+wr imm32 */
429- jitCompPutImm32(&w, i);
430-
431- if (reg0 == 0) // R03以降の、レジスタの内容をメモリ上に格納してエミュレートする場合
432-
433- jitCompA0001_movRxxEax(&w, src[1]);
434- break;
435-
436- case 0x03: /* PLIMM */ /* 未完成(plsまで対応) */
437-
438- /*
439- * PLIMM : ラベル番号代入命令(6byte)
440- *
441- * 1 2 3456
442- * 03 PXX imm32
443- *
444- * ・P28 はAPI用
445- * ・P30 はリターンアドレス
446- * ・P3F はプログラムカウンタ
447- */
448-
449- i = jitCompGetLabelNum(&w, src + 2); // Pxxに代入するラベルの番号(第二引数)
450- if ((flags & JITC_PHASE1) != 0 && w.err == 0) { // Phase 1であるならば
451- if (label[i].opt == 0) { w.err = JITC_ERR_LABELNODEF; goto err_w; } // 指定されたラベル番号は存在しない
452- if (src[1] != 0x3f && label[i].opt != 2) { w.err = JITC_ERR_LABELTYP; goto err_w; } //
453- if (src[1] == 0x3f && label[i].typ != 0) { w.err = JITC_ERR_LABELTYP; goto err_w; } // プログラムカウンタに TYP_CODEでない値は代入できない
454- }
455- if (src[1] == 0x3f) { // プログラムカウンタへの代入なら
456- if (w.prefix == 0) { // CND命令による条件付きでなければ、即座に移動
457- jitCompPutByte1(w.dst, 0xe9); /* JMP(?); */
458- }
459- else { // 直前はCND命令。
460-
461- /*
462- * CND命令
463- * 1 2
464- * 04 reg0R
465- *
466- * いま、dstの末端はJZ命令になっている。 0x0F 0x84 cd
467- */
468-
469- // JZのとび先アドレスの書き換え?
470- w.dst[-1] = w.dst[-2] ^ 0xf1; /* 74->85, 75->84 */
471- w.dst[-2] = 0x0f;
472-
473- w.prefix = 0;
474- }
475- j = 0;
476- if ((flags & JITC_PHASE1) != 0 || (((flags & JITC_PHASE1) == 0) && label[i].opt != 0)) // label番号iが確保されていれば (このif文は意味をなさない)
477- j = label[i].p - (w.dst + 4); // j はとび先の相対番地
478- jitCompPutImm32(&w, j); // JMP もしくは JZ 命令のアドレス部を記述
479-#if (jitCompA0001_OPTIMIZE_JMP != 0)
480- if (-128 - 3 <= j && j < 0) {
481- if (w.dst[-5] == 0xe9) {
482- j += 3;
483- w.dst -= 5;
484- jitCompPutByte1(w.dst, 0xeb); /* JMP(?); */
485- }
486- else {
487- j += 4;
488- w.dst -= 6;
489- jitCompPutByte1(w.dst, w.dst[1] ^ 0xf0);
490- }
491- jitCompPutByte1(w.dst, j & 0xff);
492- }
493-#endif
494- }
495- else { // プログラムカウンタ以外への代入
496-
497- // 代入先が P01, P02なら ESI, EDI,それ以外ならEAXを指定
498- reg0 = jitCompA000_selectPRegCache(src[1], 0 /* EAX */);
499- jitCompPutByte1(w.dst, 0xb8 | reg0); /* MOV(reg0, ?); */
500- jitCompPutImm32(&w, (int)label[i].p); // ラベルのパスを各レジスタに代入
501-
502- // レジスタへの代入をメモリでエミュレーションする場合は、スタックに積む。
503- if (reg0 == 0)
504- jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32, 0); /* MOV([EBP+?], EAX); */
505-
506- if (level < JITC_LV_FASTEST) {
507- jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 8, reg0); /* MOV([EBP+?], reg0); */ /* p0 */
508- jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */
509- jitCompPutImm32(&w, label[i].typ);
510- jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 4, 0); /* MOV([EBP+?], EAX); */ /* typ */
511- jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */
512- jitCompPutImm32(&w, (int)label[i].p1);
513- jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 12, 0); /* MOV([EBP+?], EAX); */ /* p1 */
514- jitCompPutByte2(w.dst, 0x31, 0xc0); /* XOR(EAX, EAX); */
515- jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 16, 0); /* MOV([EBP+?], EAX); */ /* liveSign */
516- jitCompA0001_movReg32EbpDisp(&w, 0, 2320); /* MOV(EAX, ptrCtrl); */
517- jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 20, 0); /* MOV([EBP+?], EAX); */ /* pls */
518- }
519- }
520- break;
521-
522- case 0x04: /* CND (prefix) */
523-
524- /*
525- * CND命令
526- * 与えられたRxxの最下位ビットが1であれば後続の命令を実行、そうでなければ飛ばす。
527- */
528-
529- if (src[1] >= 0x40) w.err = JITC_ERR_REGNUM; // R00-R3F 以外のレジスタは比較対象にできない
530-
531- // 比較対象のレジスタがメモリ上にあれば-1, それ以外なら適切なレジスタ番号を返す
532- reg0 = jitCompA000_selectRegCache(src[1], -1 /* mem */);
533-
534- /* TEST命令を発行 */
535- if (reg0 < 0) { //比較対象のレジスタはメモリ上にある
536- jitCompPutByte1(w.dst, 0xf7); /* TEST([EBP+?],1); */
537- jitCompA0001_85DispN(&w, src[1] * 4, 0);
538- }
539- else {
540- jitCompPutByte2(w.dst, 0xf7, 0xc0 | reg0); /* TEST(reg0,1); */
541- }
542- jitCompPutImm32(&w, 1);
543-
544- /* JZ命令を発行 */
545- jitCompPutByte2(w.dst, 0x74, 0x00); /* JZ($+2) */
546- cmp0reg = -1;
547- if (w.err != 0) goto err_w;
548- src += 2;
549- w.prefix = 1; // プリフィックスをセット
550- w.dst0 = w.dst;
551- goto prefix_continue;
552-
553- case 0x08: /* LMEM */ /* 完成 */
554- i = jitCompGetImm32(src + 2);
555- if (i == 0x0001) w.err = JITC_ERR_BADTYPE;
556- if (level < JITC_LV_FASTER) {
557- jitCompA0001_checkType(&w, src[6], i, 0); // read
558- cmp0reg = -1;
559- }
560- reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */);
561- reg1 = jitCompA000_selectPRegCache(src[6], 2 /* EDX */);
562- if (reg0 != 0 /* EAX */ && reg1 == 2 /* EDX */)
563- reg1 = 0; /* EAX */
564- if (reg1 == 2 /* EDX */)
565- jitCompA000_storeRegCacheEdx(&w);
566- if (reg1 <= 3 /* EAX, EDX */)
567- jitCompA0001_movReg32EbpDisp(&w, reg1, 256 + src[6] * 32 + 0); /* MOV(reg1, [EBP+?]); */
568- if (level < JITC_LV_FASTER)
569- jitCompA0001_checkLimit(&w, reg1, src[6]);
570- i = jitCompA000_convTyp(jitCompGetImm32(src + 2));
571- switch (i) {
572- case 0x0002:
573- jitCompPutByte3(w.dst, 0x0f, 0xbe, reg0 << 3 | reg1); /* MOVSX(reg0,BYTE [reg1]); */
574- break;
575- case 0x0003:
576- jitCompPutByte3(w.dst, 0x0f, 0xb6, reg0 << 3 | reg1); /* MOVZX(reg0,BYTE [reg1]); */
577- break;
578- case 0x0004:
579- jitCompPutByte3(w.dst, 0x0f, 0xbf, reg0 << 3 | reg1); /* MOVSX(reg0,WORD [reg1]); */
580- break;
581- case 0x0005:
582- jitCompPutByte3(w.dst, 0x0f, 0xb7, reg0 << 3 | reg1); /* MOVZX(reg0,WORD [reg1]); */
583- break;
584- case 0x0006:
585- case 0x0007:
586- jitCompPutByte2(w.dst, 0x8b, reg0 << 3 | reg1); /* MOV(reg0, [reg1]); */
587- break;
588- default:
589- w.err = JITC_ERR_BADTYPE;
590- }
591- if (reg0 == 0 /* EAX */)
592- jitCompA0001_movRxxEax(&w, src[1]);
593- if (reg1 == 2 /* EDX */)
594- jitCompA000_loadRegCacheEdx(&w);
595- break;
596-
597- case 0x09: /* SMEM */ /* 完成 */
598- i = jitCompGetImm32(src + 2);
599- if (i == 0x0001) w.err = JITC_ERR_BADTYPE;
600- if (level < JITC_LV_FASTER) {
601- jitCompA0001_checkType(&w, src[6], i, 1); // write
602- cmp0reg = -1;
603- }
604- reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */);
605- reg1 = jitCompA000_selectPRegCache(src[6], 2 /* EDX */);
606- if (reg0 != 0 /* EAX */ && reg1 == 2 /* EDX */)
607- reg1 = 0; /* EAX */
608- if (reg1 == 2 /* EDX */)
609- jitCompA000_storeRegCacheEdx(&w);
610- if (reg1 <= 3 /* EAX, EDX */)
611- jitCompA0001_movReg32EbpDisp(&w, reg1, 256 + src[6] * 32 + 0); /* MOV(reg1, [EBP+?]); */
612- if (level < JITC_LV_FASTER)
613- jitCompA0001_checkLimit(&w, reg1, src[6]);
614- if (reg0 == 0 /* EAX */)
615- jitCompA0001_movEaxRxx(&w, src[1]);
616- /* 値の範囲チェック */
617- i = jitCompA000_convTyp(jitCompGetImm32(src + 2));
618- switch (i) {
619- case 0x0002:
620- case 0x0003:
621- jitCompPutByte2(w.dst, 0x88, reg0 << 3 | reg1); /* MOV([reg1], BYTE(reg0)); */
622- break;
623- case 0x0004:
624- case 0x0005:
625- jitCompPutByte3(w.dst, 0x66, 0x89, reg0 << 3 | reg1); /* MOV([reg1], WORD(reg0)); */
626- break;
627- case 0x0006:
628- case 0x0007:
629- jitCompPutByte2(w.dst, 0x89, reg0 << 3 | reg1); /* MOV([reg1], reg0); */
630- break;
631- default:
632- w.err = JITC_ERR_BADTYPE;
633- }
634- if (reg1 == 2 /* EDX */)
635- jitCompA000_loadRegCacheEdx(&w);
636- break;
637-
638- case 0x0a: /* PLMEM */ /* 完成 */
639- i = jitCompGetImm32(src + 2);
640- if (i != 0x0001) w.err = JITC_ERR_BADTYPE;
641- if (level < JITC_LV_FASTER) {
642- jitCompA0001_checkType(&w, src[6], i, 0); // read
643- cmp0reg = -1;
644- }
645- reg0 = jitCompA000_selectPRegCache(src[1], 0 /* EAX */);
646- reg1 = jitCompA000_selectPRegCache(src[6], 2 /* EDX */);
647- // if (reg0 != 0 /* EAX */ && reg1 == 2 /* EDX */) /* これをやってはいけない!(by K, 2013.08.02) */
648- // reg1 = 0; /* EAX */
649- if (reg0 == reg1 && reg0 != 0) { // bugfix: hinted by yao, 2013.09.14. thanks!
650- jitCompA000_storePRegCacheAll(&w);
651- reg1 = 2; /* EDX */
652- }
653- if (reg1 == 2 /* EDX */)
654- jitCompA000_storeRegCacheEdx(&w);
655- if (reg1 <= 3 /* EAX, EDX */)
656- jitCompA0001_movReg32EbpDisp(&w, reg1, 256 + src[6] * 32 + 0); /* MOV(reg1, [EBP+?]); */
657- if (level < JITC_LV_FASTER)
658- jitCompA0001_checkLimit(&w, reg1, src[6]);
659- jitCompPutByte2(w.dst, 0x8b, reg0 << 3 | reg1); /* MOV(reg0, [reg1]); */
660- if (reg0 == 0 /* EAX */)
661- jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 0, 0); /* MOV([EBP+?], EAX); */
662- for (i = 4; i < 32; i += 4) {
663- jitCompPutByte3(w.dst, 0x8b, 0x40 | reg1, i); /* MOV(EAX, [reg1+?]); */
664- jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + i, 0 /* EAX */); /* MOV([EBP+?], EAX); */
665- }
666- if (reg1 == 2 /* EDX */)
667- jitCompA000_loadRegCacheEdx(&w);
668- break;
669-
670- case 0x0b: /* PSMEM */ /* 完成 */
671- i = jitCompGetImm32(src + 2);
672- if (i != 0x0001) w.err = JITC_ERR_BADTYPE;
673- if (level < JITC_LV_FASTER) {
674- jitCompA0001_checkType(&w, src[6], i, 1); // write
675- cmp0reg = -1;
676- }
677- reg0 = jitCompA000_selectPRegCache(src[1], 0 /* EAX */);
678- reg1 = jitCompA000_selectPRegCache(src[6], 2 /* EDX */);
679- // if (reg0 != 0 /* EAX */ && reg1 == 2 /* EDX */) /* これをやってはいけない!(by K, 2013.08.02) */
680- // reg1 = 0; /* EAX */
681- if (reg1 == 2 /* EDX */)
682- jitCompA000_storeRegCacheEdx(&w);
683- if (reg1 <= 3 /* EAX, EDX */)
684- jitCompA0001_movReg32EbpDisp(&w, reg1, 256 + src[6] * 32 + 0); /* MOV(reg1, [EBP+?]); */
685- if (level < JITC_LV_FASTER)
686- jitCompA0001_checkLimit(&w, reg1, src[6]);
687- if (reg0 == 0 /* EAX */)
688- jitCompA0001_movReg32EbpDisp(&w, reg0, 256 + src[1] * 32 + 0); /* MOV(reg0, [EBP+?]); */
689- jitCompPutByte2(w.dst, 0x89, reg0 << 3 | reg1); /* MOV([reg1], reg0); */
690- for (i = 4; i < 32; i += 4) {
691- jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[1] * 32 + i); /* MOV(EAX, [EBP+?]); */
692- jitCompPutByte3(w.dst, 0x89, 0x40 | reg1, i); /* MOV([reg1+?], EAX); */
693- }
694- if (reg1 == 2 /* EDX */)
695- jitCompA000_loadRegCacheEdx(&w);
696- break;
697-
698- case 0x0e: /* PADD */ /* 完成 */
699- if (level < JITC_LV_FASTER) {
700- jitCompA0001_checkType0(&w, src[6], jitCompGetImm32(src + 2), 2); // other, aliveテストはとりあえずしない.
701- cmp0reg = -1;
702- }
703- reg0 = jitCompA000_selectPRegCache(src[1], 0 /* EAX */);
704- reg1 = jitCompA000_selectPRegCache(src[6], -1 /* mem */);
705- if (reg1 < 0 /* mem */)
706- jitCompA0001_movReg32EbpDisp(&w, reg0, 256 + src[6] * 32 + 0); /* MOV(reg0, [EBP+?]); */
707- if (reg1 >= 0 && reg0 != reg1) {
708- jitCompPutByte2(w.dst, 0x89, 0xc0 | reg1 << 3 | reg0); /* MOV(reg0, reg1); */
709- }
710- i = jitCompGetImm32(src + 2);
711- j = -1;
712- if (i == 1)
713- j = 5; /* 32 */
714- else {
715- i = jitCompA000_convTyp(i);
716- if (0x0002 <= i && i <= 0x0007)
717- j = (i - 0x0002) >> 1;
718- }
719- if (j < 0) { w.err = JITC_ERR_BADTYPE; goto err_w; }
720-#if (jitCompA0001_USE_R3F_IMM32 != 0)
721- if (src[7] == 0x3f) {
722- j = w.r3f << j;
723-#if (jitCompA0001_USE_R3F_IMM8 != 0)
724- if (-0x80 <= j && j <= 0x7f) {
725-#if (jitCompA0001_USE_R3F_INCDEC != 0)
726- if (j == 1) { jitCompPutByte1(w.dst, 0x40 | reg0); goto padd1; } /* INC */
727- if (j == -1) { jitCompPutByte1(w.dst, 0x48 | reg0); goto padd1; } /* DEC */
728-#endif
729- jitCompPutByte3(w.dst, 0x83, 0xc0 | reg0, j & 0xff); /* ADD(reg0, im8); */
730- goto padd1;
731- }
732-#endif
733- if (reg0 == 0) {
734- jitCompPutByte1(w.dst, 0x05); /* ADD(reg0, ?); */
735- }
736- else {
737- jitCompPutByte2(w.dst, 0x81, 0xc0 | reg0); /* ADD(reg0, ?); */
738- }
739- jitCompPutImm32(&w, j);
740- goto padd1;
741- }
742-#endif
743- if (src[7] >= 0x40) w.err = JITC_ERR_REGNUM;
744- if (j == 0) {
745- reg1 = jitCompA000_selectRegCache(src[7], -1 /* mem */);
746- if (reg1 >= 0) {
747- jitCompPutByte2(w.dst, 0x01, 0xc0 | reg1 << 3 | reg0); /* ADD(reg0, reg1); */
748- }
749- else {
750- jitCompPutByte1(w.dst, 0x03); /* ADD(reg0, [EBP+?]); */
751- jitCompA0001_85DispN(&w, src[7] * 4, reg0);
752- }
753- }
754- else {
755- reg1 = jitCompA000_selectRegCache(src[7], -1 /* mem */);
756- reg2 = 2; /* EDX */
757- jitCompA000_storeRegCacheEdx(&w);
758- if (reg1 < 0)
759- jitCompA0001_movReg32EbpDisp(&w, reg2, src[7] * 4); /* MOV(reg2, [EBP+?]); */
760- if (reg1 >= 0 && reg1 != reg2) {
761- jitCompPutByte2(w.dst, 0x89, 0xc0 | reg1 << 3 | reg2); /* MOV(reg2, reg1); */
762- }
763- jitCompPutByte3(w.dst, 0xc1, 0xe0 | reg2, j); /* SHL(reg2, ?); */
764- jitCompPutByte2(w.dst, 0x01, 0xc0 | reg2 << 3 | reg0); /* ADD(reg0, reg2); */
765- jitCompA000_loadRegCacheEdx(&w);
766- }
767-#if (jitCompA0001_USE_R3F_IMM32 != 0)
768- padd1:
769-#endif
770- if (reg0 == 0 /* EAX */)
771- jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 0, reg0); /* MOV([EBP+?], reg0); */
772- if (src[1] != src[6]) {
773- for (i = 4; i < 32; i += 4) {
774- jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[6] * 32 + i); /* MOV(EAX, [EBP+?]); */
775- jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + i, 0 /* EAX */); /* MOV([EBP+?], EAX); */
776- }
777- }
778- cmp0reg = -1;
779- break;
780-
781- case 0x0f: /* PDIF */ /* 未完成 */
782- reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */);
783- jitCompA000_storePRegCacheAll(&w); // 手抜き.
784- jitCompA0001_checkCompPtr(&w, src[6], src[7]);
785- jitCompA0001_movReg32EbpDisp(&w, reg0, 256 + src[6] * 32 + 0); /* MOV(reg0, [EBP+?]); */
786- jitCompPutByte1(w.dst, 0x2b); /* SUB(EAX, [EBP+?]); */
787- jitCompA0001_85DispN(&w, 256 + src[7] * 32 + 0, reg0);
788- i = jitCompA000_convTyp(jitCompGetImm32(src + 2));
789- j = -1;
790- if (0x0002 <= i && i <= 0x0007)
791- j = (i - 0x0002) >> 1;
792- if (j < 0) { w.err = JITC_ERR_BADTYPE; goto err_w; }
793- if (j > 0) {
794- jitCompPutByte3(w.dst, 0xc1, 0xf8 | reg0, j); /* SAR(reg0,?); */
795- }
796- if (reg0 == 0 /* EAX */)
797- jitCompA0001_movRxxEax(&w, src[1]);
798- cmp0reg = src[1]; cmp0lev = 1;
799- break;
800-
801- case 0x10: /* OR */
802- case 0x11: /* XOR */
803- case 0x12: /* AND */
804- case 0x14: /* ADD */
805- case 0x15: /* SUB */
806- case 0x16: /* MUL */
807- if (src[1] >= 0x3f) w.err = JITC_ERR_REGNUM;
808- reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */);
809- reg1 = jitCompA000_selectRegCache(src[2], -1 /* mem */);
810-#if (jitCompA0001_USE_R3F_IMM32 != 0)
811- if (src[2] == 0x3f) { // SUBのみ該当.
812- if (*src != 0x15) w.err = JITC_ERR_REGNUM;
813- reg2 = jitCompA000_selectRegCache(src[3], -1 /* mem */);
814- if (reg2 >= 0)
815- jitCompA000_storeRegCacheAll(&w);
816- jitCompPutByte1(w.dst, 0xb8 | reg0); /* MOV(reg0, ?); */
817- jitCompPutImm32(&w, w.r3f);
818- jitCompPutByte1(w.dst, 0x2b);
819- jitCompA0001_85DispN(&w, src[3] * 4, reg0);
820- if (reg0 == 0)
821- jitCompA0001_movRxxEax(&w, src[1]);
822- break;
823- }
824-#endif
825- if (reg1 < 0) {
826- jitCompA0001_movReg32EbpDisp(&w, reg0, src[2] * 4); /* MOV(reg0, [EBP+?]); */
827- }
828- if (reg1 >= 0 && reg0 != reg1) {
829- jitCompPutByte2(w.dst, 0x89, 0xc0 | reg1 << 3 | reg0); /* MOV(reg0, reg1); */
830- }
831- if (!(src[0] == 0x10 && src[3] == 0xff)) { // bugfix: hinted by Iris, 2013.06.26. thanks!
832- cmp0reg = src[1];
833- cmp0lev = 1;
834- if (src[0] < 0x14)
835- cmp0lev = 2;
836- if (src[0] == 0x16)
837- cmp0reg = -1;
838- }
839- if (!(src[0] == 0x10 && src[3] == 0xff)) {
840-#if (jitCompA0001_USE_R3F_IMM32 != 0)
841- if (src[3] == 0x3f) {
842- if (*src == 0x16 && w.r3f == -1) {
843- jitCompPutByte2(w.dst, 0xf7, 0xd8 | reg0); /* NEG(reg0); */
844- if (reg0 == 0)
845- jitCompA0001_movRxxEax(&w, src[1]);
846- break;
847- }
848-#if (jitCompA0001_USE_R3F_INCDEC != 0)
849- if ((*src == 0x14 && w.r3f == 1) || (*src == 0x15 && w.r3f == -1)) {
850- jitCompPutByte1(w.dst, 0x40 | reg0); /* INC(reg0); */
851- if (reg0 == 0)
852- jitCompA0001_movRxxEax(&w, src[1]);
853- break;
854- }
855- if ((*src == 0x15 && w.r3f == 1) || (*src == 0x14 && w.r3f == -1)) {
856- jitCompPutByte1(w.dst, 0x48 | reg0); /* DEC(reg0); */
857- if (reg0 == 0)
858- jitCompA0001_movRxxEax(&w, src[1]);
859- break;
860- }
861-#endif
862-#if (jitCompA0001_USE_R3F_IMM8 != 0)
863- if (-0x80 <= w.r3f && w.r3f <= 0x7f) {
864- if (*src != 0x16) {
865- static unsigned char basic_op_table_im8[] = { 0xc8, 0xf0, 0xe0, 0, 0xc0, 0xe8 };
866- jitCompPutByte3(w.dst, 0x83, basic_op_table_im8[*src - 0x10] | reg0, w.r3f & 0xff);
867- }
868- else {
869- jitCompPutByte3(w.dst, 0x6b, 0xc0 | reg0 << 3 | reg0, w.r3f & 0xff);
870- }
871- if (reg0 == 0)
872- jitCompA0001_movRxxEax(&w, src[1]);
873- break;
874- }
875-#endif
876- if (reg0 == 0 /* EAX */) {
877- static unsigned char basic_op_table_im32_eax[] = { 0x0d, 0x35, 0x25, 0, 0x05, 0x2d, 0xc0 };
878- if (*src == 0x16) { jitCompPutByte1(w.dst, 0x69); }
879- jitCompPutByte1(w.dst, basic_op_table_im32_eax[*src - 0x10]);
880- }
881- else {
882- if (*src != 0x16) {
883- static unsigned char basic_op_table_im32_reg[] = { 0xc8, 0xf0, 0xe0, 0, 0xc0, 0xe8 };
884- jitCompPutByte2(w.dst, 0x81, basic_op_table_im32_reg[*src - 0x10] | reg0);
885- }
886- else {
887- jitCompPutByte2(w.dst, 0x69, 0xc0 | reg0 << 3 | reg0);
888- }
889- }
890- jitCompPutImm32(&w, w.r3f);
891- if (reg0 == 0)
892- jitCompA0001_movRxxEax(&w, src[1]);
893- break;
894- }
895-#endif
896- reg1 = jitCompA000_selectRegCache(src[3], -1 /* mem */);
897- if (src[3] >= 0x40) w.err = JITC_ERR_REGNUM;
898- if (*src != 0x16) {
899- if (reg1 >= 0) {
900- static unsigned char basic_op_table_rr[] = { 0x09, 0x31, 0x21, 0, 0x01, 0x29 }; /* op(reg,reg); */
901- jitCompPutByte2(w.dst, basic_op_table_rr[*src - 0x10], 0xc0 | reg1 << 3 | reg0);
902- }
903- else {
904- static unsigned char basic_op_table_rm[] = { 0x0b, 0x33, 0x23, 0, 0x03, 0x2b, 0xaf }; /* op(reg,mem); */
905- jitCompPutByte1(w.dst, basic_op_table_rm[*src - 0x10]);
906- jitCompA0001_85DispN(&w, src[3] * 4, reg0);
907- }
908- }
909- else {
910- if (reg1 >= 0) {
911- jitCompPutByte3(w.dst, 0x0f, 0xaf, 0xc0 | reg0 << 3 | reg1);
912- }
913- else {
914- jitCompPutByte2(w.dst, 0x0f, 0xaf);
915- jitCompA0001_85DispN(&w, src[3] * 4, reg0);
916- }
917- }
918- }
919- if (reg0 == 0)
920- jitCompA0001_movRxxEax(&w, src[1]);
921- break;
922-
923- case 0x18: /* SHL */
924- case 0x19: /* SAR */
925- if (src[1] >= 0x3f) w.err = JITC_ERR_REGNUM;
926- if (src[3] >= 0x40) w.err = JITC_ERR_REGNUM;
927-#if (jitCompA0001_USE_R3F_IMM32 != 0)
928- if (src[3] == 0x3f) {
929- reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */);
930- reg1 = jitCompA000_selectRegCache(src[2], -1 /* mem */);
931- if (src[1] >= 0x3f) w.err = JITC_ERR_REGNUM;
932- if (reg1 == -1)
933- jitCompA0001_movReg32EbpDisp(&w, reg0, src[2] * 4); /* MOV(reg1, [EBP+?]); */
934- else {
935- if (reg0 != reg1) {
936- jitCompPutByte2(w.dst, 0x89, 0xc0 | reg1 << 3 | reg0); /* MOV(reg0, reg1); */
937- }
938- }
939- if (*src == 0x18) { jitCompPutByte3(w.dst, 0xc1, 0xe0 | reg0, w.r3f); } /* SHL(reg0, im8); */
940- if (*src == 0x19) { jitCompPutByte3(w.dst, 0xc1, 0xf8 | reg0, w.r3f); } /* SAR(reg0, im8); */
941- if (reg0 == 0 /* EAX */)
942- jitCompA0001_movRxxEax(&w, src[1]);
943- cmp0reg = src[1];
944- cmp0lev = 1;
945- break;
946- }
947-#endif
948- jitCompA000_storeRegCacheAll(&w); // 手抜き.
949- jitCompA0001_movReg32EbpDisp(&w, 1 /* ECX */, src[3] * 4); /* MOV(ECX, [EBP+?]); */
950-#if (jitCompA0001_USE_R3F_IMM32 != 0)
951- if (src[2] == 0x3f) {
952- jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */
953- jitCompPutImm32(&w, w.r3f);
954- }
955- else {
956- jitCompA0001_movEaxRxx(&w, src[2]);
957- }
958-#else
959- jitCompA0001_movEaxRxx(&w, src[2]);
960-#endif
961- if (*src == 0x18) { jitCompPutByte2(w.dst, 0xd3, 0xe0); } /* SHL(EAX, CL); */
962- if (*src == 0x19) { jitCompPutByte2(w.dst, 0xd3, 0xf8); } /* SAR(EAX, CL); */
963- jitCompA0001_movRxxEax(&w, src[1]);
964- jitCompA000_loadRegCacheAll(&w); // 手抜き.
965- cmp0reg = src[1];
966- cmp0lev = 1;
967- break;
968-
969- case 0x1a: /* DIV */
970- case 0x1b: /* MOD */
971- if (src[1] >= 0x3f) w.err = JITC_ERR_REGNUM;
972- if (src[2] >= 0x40) w.err = JITC_ERR_REGNUM;
973- if (src[3] >= 0x40) w.err = JITC_ERR_REGNUM;
974- jitCompA000_storeRegCacheAll(&w); // 手抜き.
975-#if (jitCompA0001_USE_R3F_IMM32 != 0)
976- if (src[3] == 0x3f) {
977- jitCompPutByte1(w.dst, 0xb8 | 1); /* MOV(ECX, ?); */
978- jitCompPutImm32(&w, w.r3f);
979- }
980- else {
981- jitCompA0001_movReg32EbpDisp(&w, 1 /* ECX */, src[3] * 4); /* MOV(ECX, [EBP+?]); */
982- }
983- if (src[2] == 0x3f) {
984- jitCompPutByte1(w.dst, 0xb8 | 0); /* MOV(EAX, ?); */
985- jitCompPutImm32(&w, w.r3f);
986- }
987- else {
988- jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, src[2] * 4); /* MOV(EAX, [EBP+?]); */
989- }
990-#else
991- jitCompA0001_movReg32EbpDisp(&w, 1 /* ECX */, src[3] * 4); /* MOV(ECX, [EBP+?]); */
992- jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, src[2] * 4); /* MOV(EAX, [EBP+?]); */
993-#endif
994- jitCompPutByte1(w.dst, 0x99); /* CDQ(); */
995- /* ECXがゼロではないことを確認すべき */
996- jitCompPutByte2(w.dst, 0xf7, 0xf9); /* IDIV(ECX); */
997- if (*src == 0x1a) { jitCompA0001_movEbpDispReg32(&w, src[1] * 4, 0 /* EAX */); }
998- if (*src == 0x1b) { jitCompA0001_movEbpDispReg32(&w, src[1] * 4, 2 /* EDX */); }
999- jitCompA000_loadRegCacheAll(&w); // 手抜き.
1000- cmp0reg = -1;
1001- break;
1002-
1003- case 0x1c: /* PLMT0 */
1004- case 0x1d: /* PLMT1 */
1005- if (src[1] >= 0x40 || src[2] >= 0x40) w.err = JITC_ERR_PREGNUM;
1006- if (level < JITC_LV_FASTEST) {
1007- cmp0reg = -1;
1008- if (level < JITC_LV_FASTER) {
1009- // typ が一致していることを確認.
1010- // plsとliveSignが一致していることを確認.
1011-
1012- // preg1はp0 <= p <= p1 を満たしているか?.
1013- // 新しいp0/p1は古いp0〜p1に適合しているか?.
1014-
1015- }
1016- }
1017-
1018- case 0x1e: /* PCP */ /* 未完成(p1まで完成) */
1019- if (src[1] >= 0x40 || src[2] >= 0x40) w.err = JITC_ERR_PREGNUM;
1020- if (src[2] == 0x3f) w.err = JITC_ERR_PREGNUM;
1021- if (src[1] != 0x3f) {
1022- /* src[2] == 0xff の場合に対応できてない */
1023- jitCompA000_storePRegCacheAll(&w); // 手抜き.
1024- for (i = 0; i < 32; i += 4) {
1025- jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[2] * 32 + i); /* MOV(EAX, [EBP+?]); */
1026- jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + i, 0 /* EAX */); /* MOV([EBP+?], EAX); */
1027- }
1028- jitCompA000_loadPRegCacheAll(&w); // 手抜き.
1029- }
1030- else {
1031- if (level < JITC_LV_FASTER) {
1032- jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[2] * 32 + 4); /* MOV(EAX, [EBP+?]); */ /* typ */
1033- jitCompPutByte3(w.dst, 0x83, 0xf8, 0); /* CMP(EAX, 0); */
1034- jitCompPutByte2(w.dst, 0x0f, 0x85); /* JNE */
1035- jitCompPutImm32(&w, errfnc - (w.dst + 4));
1036- /* セキュリティチェックが足りてない!(aliveとか) */
1037- }
1038- reg0 = 0; /* EAX */
1039- jitCompA000_storePRegCacheAll(&w); // 手抜き.
1040- jitCompA0001_movReg32EbpDisp(&w, reg0, 256 + src[2] * 32 + 0); /* MOV(EAX, [EBP+?]); */
1041- if (level < JITC_LV_FASTER) {
1042- jitCompPutByte1(w.dst, 0x3b); /* CMP(reg0, [EBP+?]); */
1043- jitCompA0001_85DispN(&w, 256 + src[2] * 32 + 8, reg0); /* p0 */
1044- jitCompPutByte2(w.dst, 0x0f, 0x85); /* JNE */
1045- jitCompPutImm32(&w, errfnc - (w.dst + 4));
1046- }
1047- jitCompPutByte2(w.dst, 0xff, 0xe0); /* JMP(EAX); */
1048- }
1049- break;
1050-
1051- case 0x1f: /* PCST */
1052- if (jitCompGetImm32(src + 2) == 0) {
1053- if (level < JITC_LV_FASTER)
1054- jitCompA0001_checkType0(&w, src[6], jitCompGetImm32(src + 7), 2);
1055- jitCompA000_storePRegCacheAll(&w); // 手抜き.
1056- for (i = 0; i < 32 - 4; i += 4) {
1057- jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[6] * 32 + i); /* MOV(EAX, [EBP+?]); */
1058- if (i == 4) {
1059- jitCompPutByte1(w.dst, 0x0d); /* OR(EAX, ?); */
1060- jitCompPutImm32(&w, 0x80000000);
1061- }
1062- jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + i, 0 /* EAX */); /* MOV([EBP+?], EAX); */
1063- }
1064- jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */
1065- jitCompPutImm32(&w, debugInfo1);
1066- jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 28, 0 /* EAX */); /* MOV([EBP+?], EAX); */
1067- jitCompA000_loadPRegCacheAll(&w); // 手抜き.
1068- cmp0reg = -1;
1069- break;
1070- }
1071- if (jitCompGetImm32(src + 7) == 0) {
1072- jitCompA000_storePRegCacheAll(&w); // 手抜き.
1073- for (i = 0; i < 32 - 4; i += 4) {
1074- jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[6] * 32 + i); /* MOV(EAX, [EBP+?]); */
1075- if (i == 4) {
1076- jitCompPutByte1(w.dst, 0x25); /* AND(EAX, ?); */
1077- jitCompPutImm32(&w, 0x7fffffff);
1078- }
1079- jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + i, 0 /* EAX */); /* MOV([EBP+?], EAX); */
1080- }
1081- if (level < JITC_LV_FASTER) {
1082- jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[6] * 32 + 28); /* MOV(EAX, [EBP+?]); */
1083- jitCompPutByte1(w.dst, 0x3d); /* CMP(EAX, ?); */
1084- jitCompPutImm32(&w, debugInfo1);
1085- jitCompPutByte2(w.dst, 0x74, 8); /* JE */
1086- jitCompPutByte2(w.dst, 0x31, 0xc0); /* XOR(EAX, EAX); (2) */
1087- jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 0, 0 /* EAX */); /* MOV([EBP+?], EAX); (1+1+4) */
1088- }
1089- jitCompA000_loadPRegCacheAll(&w); // 手抜き.
1090- cmp0reg = -1;
1091- break;
1092- }
1093- w.err = JITC_ERR_OPECODE;
1094- goto err_w;
1095-
1096- case 0x20: /* CMPE */
1097- case 0x21: /* CMPNE */
1098- case 0x22: /* CMPL */
1099- case 0x23: /* CMPGE */
1100- case 0x24: /* CMPLE */
1101- case 0x25: /* CMPG */
1102- case 0x26: /* TSTZ */
1103- case 0x27: /* TSTNZ */
1104- reg0 = jitCompA000_selectRegCache(src[2], 0 /* EAX */);
1105- reg1 = jitCompA000_selectRegCache(src[3], -1 /* mem */);
1106- if (src[1] == 0x3f) {
1107- /* 特殊構文チェック */
1108- if (w.prefix != 0) { w.err = JITC_ERR_PREFIX; goto err_w; }
1109- if (src[4] != 0x04 || src[5] != 0x3f || src[6] != 0x03 || src[7] != 0x3f) {
1110- w.err = JITC_ERR_IDIOM; goto err_w;
1111- }
1112- }
1113- if (reg0 == 0)
1114- jitCompA0001_movEaxRxx(&w, src[2]);
1115-#if (jitCompA0001_USE_R3F_IMM32 != 0)
1116- if (src[3] == 0x3f) {
1117-#if (jitCompA0001_OPTIMIZE_CMP != 0)
1118- if ((*src <= 0x25 && w.r3f == 0) || (*src >= 0x26 && w.r3f == -1)) {
1119- i = 0;
1120- if (cmp0reg == src[2]) {
1121- if (cmp0lev >= 1 && (src[0] == 0x20 || src[0] == 0x21 || src[0] == 0x26 || src[0] == 0x27))
1122- i = 1;
1123- if (cmp0lev >= 2 && (src[0] == 0x22 || src[0] == 0x23 || src[0] == 0x24 || src[0] == 0x25))
1124- i = 1;
1125- }
1126- if (i == 0) {
1127- jitCompPutByte2(w.dst, 0x85, 0xc0 | reg0 << 3 | reg0); /* TEST(reg0, reg0); */
1128- }
1129- cmp0reg = src[2];
1130- cmp0lev = 2;
1131- goto cmpcc1;
1132- }
1133-#endif
1134-#if (jitCompA0001_USE_R3F_IMM8 != 0)
1135- if (-0x80 <= w.r3f && w.r3f <= 0x7f && *src <= 0x25) {
1136- jitCompPutByte3(w.dst, 0x83, 0xf8 | reg0, w.r3f);
1137- goto cmpcc1;
1138- }
1139-#endif
1140- if (reg0 == 0) {
1141- if (*src <= 0x25) { jitCompPutByte1(w.dst, 0x3d); }
1142- if (*src >= 0x26) { jitCompPutByte1(w.dst, 0xa9); }
1143- }
1144- else {
1145- if (*src <= 0x25) { jitCompPutByte2(w.dst, 0x81, 0xf8 | reg0); }
1146- if (*src >= 0x26) { jitCompPutByte2(w.dst, 0xf7, 0xc0 | reg0); }
1147- }
1148- jitCompPutImm32(&w, w.r3f);
1149- goto cmpcc1;
1150- }
1151-#endif
1152- if (src[3] >= 0x40) w.err = JITC_ERR_PREGNUM;
1153- if (reg1 >= 0) {
1154- if (*src <= 0x25) { jitCompPutByte2(w.dst, 0x39, 0xc0 | reg1 << 3 | reg0); }
1155- if (*src >= 0x26) { jitCompPutByte2(w.dst, 0x85, 0xc0 | reg1 << 3 | reg0); }
1156- }
1157- else {
1158- if (*src <= 0x25) { jitCompPutByte1(w.dst, 0x3b); }
1159- if (*src >= 0x26) { jitCompPutByte1(w.dst, 0x85); }
1160- jitCompA0001_85DispN(&w, src[3] * 4, reg0);
1161- }
1162- cmpcc1:
1163- if (w.err != 0) goto err_w;
1164- static unsigned char cmpcc_table0[] = {
1165- 0x04, 0x05, 0x0c, 0x0d, 0x0e, 0x0f, 0x04, 0x05, /* CMPcc, TSTcc */
1166- 0x04, 0x05, 0x02, 0x03, 0x06, 0x07 /* PCMPcc */
1167- };
1168-#if (jitCompA0001_USE_R3F_CMPJMP != 0)
1169- if (src[1] == 0x3f) {
1170- /* 特殊構文を利用した最適化 */
1171- jitCompPutByte2(w.dst, 0x0f, 0x80 | cmpcc_table0[*src - 0x20]);
1172- src += 6;
1173- i = jitCompGetLabelNum(&w, src + 2);
1174- if ((flags & JITC_PHASE1) != 0 && w.err != 0) {
1175- if (label[i].opt == 0) { w.err = JITC_ERR_LABELNODEF; goto err_w; }
1176- // if (label[i].typ != 1) { w.err = JITC_ERR_LABELTYP; goto err_w; }
1177- }
1178- j = 0;
1179- if ((flags & JITC_PHASE1) != 0 || (((flags & JITC_PHASE1) == 0) && label[i].opt != 0))
1180- j = label[i].p - (w.dst + 4);
1181- jitCompPutImm32(&w, j);
1182-#if (jitCompA0001_OPTIMIZE_JMP != 0)
1183- if (-128 - 4 <= j && j < 0) {
1184- j += 4;
1185- w.dst -= 6;
1186- jitCompPutByte2(w.dst, w.dst[1] ^ 0xf0, j & 0xff);
1187- }
1188-#endif
1189- src += 6;
1190- if (w.err != 0) goto err_w;
1191- continue;
1192- }
1193-#endif
1194- /* 一般的なJITC */
1195- reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */);
1196- jitCompPutByte3(w.dst, 0x0f, 0x90 | cmpcc_table0[*src - 0x20], 0xc0 | reg0); /* SETcc(BYTE(reg0)); */
1197- jitCompPutByte3(w.dst, 0x0f, 0xb6, 0xc0 | reg0 << 3 | reg0); /* MOVZX(reg0, BYTE(reg0)); */
1198- jitCompPutByte2(w.dst, 0xf7, 0xd8 | reg0); /* NEG(reg0); */
1199- if (reg0 == 0)
1200- jitCompA0001_movRxxEax(&w, src[1]);
1201- cmp0reg = src[2];
1202- cmp0lev = 1;
1203- break;
1204-
1205- case 0x28: /* PCMPE */
1206- case 0x29: /* PCMPNE */
1207- case 0x2a: /* PCMPL */
1208- case 0x2b: /* PCMPGE */
1209- case 0x2c: /* PCMPLE */
1210- case 0x2d: /* PCMPG */
1211- if (src[1] == 0x3f) {
1212- /* 特殊構文チェック */
1213- if (w.prefix != 0) { w.err = JITC_ERR_PREFIX; goto err_w; }
1214- if (src[4] != 0x04 || src[5] != 0x3f || src[6] != 0x03 || src[7] != 0x3f) {
1215- w.err = JITC_ERR_IDIOM; goto err_w;
1216- }
1217- }
1218- if (src[2] >= 0x40) w.err = JITC_ERR_PREGNUM;
1219- jitCompA000_storePRegCacheAll(&w); // 手抜き.
1220- if (src[3] != 0xff)
1221- jitCompA0001_checkCompPtr(&w, src[2], src[3]);
1222- jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[2] * 32 + 0); /* MOV(EAX, [EBP+?]); */
1223- if (src[3] != 0xff) {
1224- jitCompPutByte1(w.dst, 0x3b); /* CMP(EAX, [EBP+?]); */
1225- jitCompA0001_85DispN(&w, 256 + src[3] * 32 + 0, 0);
1226- }
1227- else {
1228- /* ヌルポインタとの比較はこれでいいのか?たぶんよくない */
1229- jitCompPutByte3(w.dst, 0x83, 0xf8, 0x00); /* CMP(EAX, 0); */
1230- }
1231- cmp0reg = -1;
1232- goto cmpcc1;
1233-
1234- case 0x30: /* talloc(old:F4) */
1235- case 0x31: /* tfree(old:F5) */
1236- case 0x32: /* malloc(old:F6) */
1237- case 0x33: /* mfree(old:F7) */
1238- jitCompA000_storeRegCacheAll(&w); // 手抜き.
1239- jitCompA000_storePRegCacheAll(&w); // 手抜き.
1240- jitCompPutByte2(w.dst, 0x6a, src[3]); /* PUSH(?); */
1241- jitCompPutByte2(w.dst, 0x6a, src[2]); /* PUSH(?); */
1242- jitCompPutByte2(w.dst, 0x6a, src[1]); /* PUSH(?); */
1243- jitCompPutByte1(w.dst, 0x55); /* PUSH(EBP); */
1244- jitCompPutByte1(w.dst, 0xe8);
1245- if (*src == 0x30) j = ((unsigned char *)&funcf4) - (w.dst + 4);
1246- if (*src == 0x31) j = ((unsigned char *)&funcf5) - (w.dst + 4);
1247- if (*src == 0x32) j = ((unsigned char *)&funcf6) - (w.dst + 4);
1248- if (*src == 0x33) j = ((unsigned char *)&funcf7) - (w.dst + 4);
1249- jitCompPutImm32(&w, j);
1250- jitCompPutByte3(w.dst, 0x83, 0xc4, 0x10); /* ADD(ESP,16); */
1251- jitCompA000_loadRegCacheAll(&w); // 手抜き.
1252- jitCompA000_loadPRegCacheAll(&w); // 手抜き.
1253- cmp0reg = -1;
1254- break;
1255-
1256- case 0x34: /* data (暫定) */
1257- cmp0reg = -1;
1258- if (w.prefix != 0) { w.err = JITC_ERR_PREFIX; goto err_w; }
1259- int k = jitCompGetImm32(&src[1]), tmpData, bitCount, dataWidth = jitCompA000_dataWidth(k);
1260- if (lastlabel >= 0 && label[lastlabel].typ == 0)
1261- label[lastlabel].typ = k;
1262- if (k != 1) {
1263- i = jitCompA000_convTyp(k);
1264- if (i < 2 || i > 7) { w.err = JITC_ERR_BADTYPE; goto err_w; }
1265- }
1266- j = jitCompGetImm32(&src[5]);
1267- oldsrc = src;
1268- src += 9;
1269- if (k != 1) {
1270- bitCount = 7;
1271- while (j > 0) {
1272- if (src >= src1) { w.err = JITC_ERR_SRC1; src = oldsrc; goto err_w; }
1273- if (w.dst + 256 > dst1) { w.err = JITC_ERR_DST1; src = oldsrc; goto err_w; }
1274- tmpData = 0;
1275- for (k = 0; k < dataWidth; k++) {
1276- tmpData = tmpData << 1 | ((*src >> bitCount) & 1);
1277- bitCount--;
1278- if (bitCount < 0) {
1279- bitCount = 7;
1280- src++;
1281- }
1282- }
1283- if ((i & 1) == 0 && dataWidth <= 31 && (tmpData >> (dataWidth - 1)) != 0) {
1284- tmpData -= 1 << dataWidth;
1285- }
1286- if (i == 2 || i == 3) { jitCompPutByte1(w.dst, tmpData & 0xff); }
1287- if (i == 4 || i == 5) { jitCompPutByte2(w.dst, tmpData & 0xff, (tmpData >> 8) & 0xff); }
1288- if (i == 6 || i == 7) { jitCompPutByte4(w.dst, tmpData & 0xff, (tmpData >> 8) & 0xff, (tmpData >> 16) & 0xff, (tmpData >> 24) & 0xff); }
1289- j--;
1290- }
1291- }
1292- else {
1293- while (j > 0) {
1294- if (src >= src1) { w.err = JITC_ERR_SRC1; src = oldsrc; goto err_w; }
1295- if (w.dst + 256 > dst1) { w.err = JITC_ERR_DST1; src = oldsrc; goto err_w; }
1296- i = jitCompGetImm32(src);
1297- src += 4;
1298- if ((flags & JITC_PHASE1) != 0 && w.err == 0) {
1299- if (label[i].opt == 0) { w.err = JITC_ERR_LABELNODEF; goto err_w; }
1300- }
1301- jitCompPutImm32(&w, (int)label[i].p);
1302- jitCompPutImm32(&w, label[i].typ);
1303- jitCompPutImm32(&w, (int)label[i].p);
1304- jitCompPutImm32(&w, (int)label[i].p1);
1305- jitCompPutImm32(&w, 0); /* liveSign */
1306- jitCompPutImm32(&w, 2320); /* pls */
1307- jitCompPutImm32(&w, 0);
1308- jitCompPutImm32(&w, 0);
1309- j--;
1310- }
1311- }
1312- if (lastlabel >= 0 && label[lastlabel].p1 < w.dst)
1313- label[lastlabel].p1 = w.dst;
1314- continue;
1315-
1316- case 0x3c: /* ENTER */
1317- jitCompA000_storeRegCacheAll(&w); // 手抜き.
1318- jitCompA000_storePRegCacheAll(&w); // 手抜き.
1319- jitCompPutByte2(w.dst, 0x6a, src[6]); /* PUSH(?); */
1320- jitCompPutByte2(w.dst, 0x6a, src[5]); /* PUSH(?); */
1321- jitCompPutByte2(w.dst, 0x6a, src[4] & 0x0f); /* PUSH(?); */
1322- jitCompPutByte2(w.dst, 0x6a, (src[4] >> 4) & 0x0f); /* PUSH(?); */
1323- jitCompPutByte2(w.dst, 0x6a, src[3]); /* PUSH(?); */
1324- jitCompPutByte2(w.dst, 0x6a, src[2]); /* PUSH(?); */
1325- jitCompPutByte2(w.dst, 0x6a, src[1]); /* PUSH(?); */
1326- jitCompPutByte1(w.dst, 0x55); /* PUSH(EBP); */
1327- jitCompPutByte1(w.dst, 0xe8);
1328- j = ((unsigned char *)&func3c) - (w.dst + 4);
1329- jitCompPutImm32(&w, j);
1330- jitCompPutByte3(w.dst, 0x83, 0xc4, 0x20); /* ADD(ESP,32); */
1331- jitCompA000_loadRegCacheAll(&w); // 手抜き.
1332- jitCompA000_loadPRegCacheAll(&w); // 手抜き.
1333- cmp0reg = -1;
1334- break;
1335-
1336- case 0x3d: /* LEAVE */
1337- jitCompA000_storeRegCacheAll(&w); // 手抜き.
1338- jitCompA000_storePRegCacheAll(&w); // 手抜き.
1339- jitCompPutByte2(w.dst, 0x6a, src[6]); /* PUSH(?); */
1340- jitCompPutByte2(w.dst, 0x6a, src[5]); /* PUSH(?); */
1341- jitCompPutByte2(w.dst, 0x6a, src[4] & 0x0f); /* PUSH(?); */
1342- jitCompPutByte2(w.dst, 0x6a, (src[4] >> 4) & 0x0f); /* PUSH(?); */
1343- jitCompPutByte2(w.dst, 0x6a, src[3]); /* PUSH(?); */
1344- jitCompPutByte2(w.dst, 0x6a, src[2]); /* PUSH(?); */
1345- jitCompPutByte2(w.dst, 0x6a, src[1]); /* PUSH(?); */
1346- jitCompPutByte1(w.dst, 0x55); /* PUSH(EBP); */
1347- jitCompPutByte1(w.dst, 0xe8);
1348- j = ((unsigned char *)&func3d) - (w.dst + 4);
1349- jitCompPutImm32(&w, j);
1350- jitCompPutByte3(w.dst, 0x83, 0xc4, 0x20); /* ADD(ESP,32); */
1351- jitCompA000_loadRegCacheAll(&w); // 手抜き.
1352- jitCompA000_loadPRegCacheAll(&w); // 手抜き.
1353- cmp0reg = -1;
1354- break;
1355-
1356- case 0xfe: /* remark */
1357- if (src[1] == 0x01 && src[2] == 0x00) { // DBGINFO1
1358- if (level <= JITC_LV_SLOWER) {
1359- jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */
1360- jitCompPutImm32(&w, debugInfo1);
1361- jitCompA0001_movEbpDispReg32(&w, 2304 + 4, 0 /* EAX */); /* MOV(debugInfo1, EAX); */
1362- }
1363- }
1364- if (src[1] == 0x01 && src[2] == 0x03) { // DBGINFO1CLR
1365- if (level <= JITC_LV_SLOWER) {
1366- jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */
1367- jitCompPutImm32(&w, -1);
1368- jitCompA0001_movEbpDispReg32(&w, 2304 + 4, 0 /* EAX */); /* MOV(debugInfo1, EAX); */
1369- }
1370- }
1371- if (src[1] == 0x05 && src[2] == 0x00) { // DBGINFO0
1372- if (level <= JITC_LV_SLOWEST) {
1373- debugInfo0 = jitCompGetImm32(src + 3);
1374- // jitCompPutByte1(w.dst, 0xbf); /* MOV(EDI, ?); */
1375- // jitCompPutImm32(&w, debugInfo0);
1376- jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */
1377- jitCompPutImm32(&w, debugInfo0);
1378- jitCompA0001_movEbpDispReg32(&w, 2304 + 0, 0 /* EAX */); /* MOV(debugInfo0, EAX); */
1379- }
1380- }
1381- break;
1382-
1383- default:
1384- w.err = JITC_ERR_OPECODE;
1385- goto err_w;
1386- }
1387- if (w.err != 0) goto err_w;
1388- jitCompA0001_fixPrefix(&w);
1389- if (w.err != 0) goto err_w;
1390- src += jitCompCmdLen(src);
1391- }
1392- if (enter0 != NULL) {
1393- j = w.dst - (enter0 + 4);
1394- enter0[0] = j & 0xff;
1395- enter0[1] = (j >> 8) & 0xff;
1396- enter0[2] = (j >> 16) & 0xff;
1397- enter0[3] = (j >> 24) & 0xff;
1398- }
1399- if ((flags & JITC_NOSTARTUP) == 0) {
1400- jitCompA000_storeRegCacheAll(&w);
1401- jitCompA000_storePRegCacheAll(&w);
1402- jitCompPutByte1(w.dst, 0x61); /* POPAD(); */
1403- }
1404- if ((flags & JITC_PHASE1) != 0)
1405- return w.dst - dst00;
1406- return 0;
1407-
1408-err_w:
1409- if ((w.err & JITC_ERR_PHASE0ONLY) != 0) {
1410- if ((flags & JITC_PHASE1) == 0)
1411- w.err &= ~JITC_ERR_PHASE0ONLY;
1412- }
1413- if (w.err == (JITC_ERR_MASK & JITC_ERR_REGNUM)) errmsg = "reg-number error";
1414- if (w.err == (JITC_ERR_MASK & JITC_ERR_DST1)) errmsg = "dst1 error";
1415- if (w.err == (JITC_ERR_MASK & JITC_ERR_OPECODE)) errmsg = "opecode error";
1416- if (w.err == (JITC_ERR_MASK & JITC_ERR_LABELNUM)) errmsg = "label number too large";
1417- if (w.err == (JITC_ERR_MASK & JITC_ERR_LABELREDEF)) errmsg = "label redefine";
1418- if (w.err == (JITC_ERR_MASK & JITC_ERR_PREFIX)) { errmsg = "prefix redefine"; w.dst -= 2; }
1419- if (w.err == (JITC_ERR_MASK & JITC_ERR_LABELNODEF)) errmsg = "label not defined";
1420- if (w.err == (JITC_ERR_MASK & JITC_ERR_LABELTYP)) errmsg = "label type error";
1421- if (w.err == (JITC_ERR_MASK & JITC_ERR_IDIOM)) errmsg = "idiom error";
1422- if (w.err == (JITC_ERR_MASK & JITC_ERR_PREGNUM)) errmsg = "preg-number error";
1423- if (w.err == (JITC_ERR_MASK & JITC_ERR_SRC1)) errmsg = "src1 error";
1424- if (w.err == (JITC_ERR_MASK & JITC_ERR_BADTYPE)) errmsg = "bad type code";
1425- if (w.err == (JITC_ERR_MASK & JITC_ERR_PREFIXFAR)) errmsg = "prefix internal error";
1426- if (w.err == (JITC_ERR_MASK & JITC_ERR_INTERNAL)) errmsg = "general internal error";
1427- if (*errmsg != '\0') {
1428- fprintf(stderr, "JITC: %s at %06X (debugInfo0=%d)\n ", errmsg, src - src0, debugInfo0);
1429- for (i = 0; i < 16; i++)
1430- fprintf(stderr, "%02X ", src[i]);
1431- static char *table[0x30] = {
1432- "NOP", "LB", "LIMM", "PLIMM", "CND", "??", "??", "??",
1433- "LMEM", "SMEM", "PLMEM", "PSMEM", "LEA", "??", "PADD", "PDIF",
1434- "CP/OR", "XOR", "AND", "??", "ADD", "SUB", "MUL", "??",
1435- "SHL", "SAR", "DIV", "MOD", "PLMT0", "PLMT1", "PCP", "PCST",
1436- "CMPE", "CMPNE", "CMPL", "CMPGE", "CMPLE", "CMPG", "TSTZ", "TSTNZ",
1437- "PCMPE", "PCMPNE", "PCMPL", "PCMPGE", "PCMPLE", "PCMPG", "??", "EXT" };
1438- errmsg = "??";
1439- if (*src < 0x30) errmsg = table[*src];
1440- fprintf(stderr, "(%s)\n", errmsg);
1441- }
1442- return -1;
1443-}
1444-
1445-unsigned char *jitCompCallFunc(unsigned char *dst, void *func)
1446-{
1447- struct JitCompWork w;
1448- w.dst = dst;
1449- jitCompA000_storeRegCacheAll(&w);
1450- jitCompA000_storePRegCacheAll(&w);
1451- jitCompPutByte1(w.dst, 0x60); /* PUSHAD(); */
1452- jitCompPutByte1(w.dst, 0x50); /* PUSH(EAX); */ /* for 16byte-align(win32では不要なのだけど、MacOSには必要らしい) */
1453- jitCompPutByte1(w.dst, 0x55); /* PUSH(EBP); */
1454- jitCompPutByte1(w.dst, 0xe8); /* CALL(func); */
1455- int j = ((unsigned char *)func) - (w.dst + 4);
1456-
1457- //この関数の中では結局w->dstしか参照していない
1458- jitCompPutImm32(&w, j);
1459-
1460- jitCompPutByte1(w.dst, 0x58); /* POP(EAX); */ /* (win32では不要なのだけど、MacOSには必要らしい) */
1461- jitCompPutByte1(w.dst, 0x58); /* POP(EAX); */
1462- jitCompPutByte1(w.dst, 0x61); /* POPAD(); */
1463- jitCompA000_loadRegCacheAll(&w);
1464- jitCompA000_loadPRegCacheAll(&w);
1465- jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + 0x30 * 32 + 0); /* MOV(EAX, [EBP+?]); */
1466- jitCompPutByte2(w.dst, 0xff, 0xe0); /* JMP(EAX); */
1467- return w.dst;
1468-}
1469-
1470-unsigned char *jitCompInit(unsigned char *dst)
1471-{
1472- errfnc = dst;
1473- return jitCompCallFunc(dst, &errHndl);
1474-}
1475-
1476-void func3c(char *ebp, int opt, int r1, int p1, int lenR, int lenP, int r0, int p0)
1477-{
1478- HOSECPU_RuntimeEnvironment *r = (HOSECPU_RuntimeEnvironment *) (ebp - jitCompA0001_EBP128);
1479- int i, *pi;
1480- HOSECPU_PointerRegisterEntry *pp;
1481- if (r->junkStack + 2048 > r->junkStack1) (*(r->errHndl))(r);
1482- pi = (void *)r->junkStack; r->junkStack += r1 * 4;
1483- for (i = 0; i < r1; i++)
1484- pi[i] = r->ireg[i];
1485- pp = (void *)r->junkStack; r->junkStack += p1 * 32;
1486- for (i = 0; i < p1; i++)
1487- pp[i] = r->preg[i];
1488- pp = (void *)r->junkStack; r->junkStack += 32;
1489- *pp = r->preg[0x30];
1490- pi = (void *)r->junkStack; r->junkStack += 4;
1491- *pi = opt << 16 | r1 << 8 | p1;
1492- for (i = 0; i < lenR; i++)
1493- r->ireg[r0 + i] = r->ireg[0x30 + i];
1494- for (i = 0; i < lenP; i++)
1495- r->preg[p0 + i] = r->preg[0x31 + i];
1496- return;
1497-}
1498-
1499-void func3d(char *ebp, int opt, int r1, int p1, int lenR, int lenP, int r0, int p0)
1500-{
1501- HOSECPU_RuntimeEnvironment *r = (HOSECPU_RuntimeEnvironment *) (ebp - jitCompA0001_EBP128);
1502- int i;
1503- r->junkStack -= 4;
1504- r->junkStack -= 32;
1505- HOSECPU_PointerRegisterEntry *pp = (void *)r->junkStack;
1506- r->preg[0x30] = *pp;
1507- r->junkStack -= p1 * 32; pp = (void *)r->junkStack;
1508- for (i = 0; i < p1; i++)
1509- r->preg[i] = pp[i];
1510- r->junkStack -= r1 * 4; int *pi = (void *)r->junkStack;
1511- for (i = 0; i < r1; i++)
1512- r->ireg[i] = pi[i];
1513- return;
1514-}
1515-
1516-void funcf4(char *ebp, int pxx, int typ, int len)
1517-{
1518- HOSECPU_RuntimeEnvironment *r = (HOSECPU_RuntimeEnvironment *) (ebp - jitCompA0001_EBP128);
1519- int width = jitCompA000_dataWidth(jitCompA000_convTyp(r->ireg[typ])) >> 3;
1520- if (width < 0 || r->ireg[len] < 0)
1521- (*(r->errHndl))(r);
1522- void *p = r->junkStack;
1523- if (r->junkStack + width * r->ireg[len] + 256 > r->junkStack1) (*(r->errHndl))(r);
1524- r->junkStack += width * r->ireg[len];
1525- r->preg[pxx].p = p;
1526- r->preg[pxx].typ = r->ireg[typ];
1527- r->preg[pxx].p0 = p;
1528- r->preg[pxx].p1 = (void *)r->junkStack;
1529- int *pi = (int *)r->junkStack;
1530- *pi = width * r->ireg[len];
1531- r->junkStack += sizeof (int);
1532- if (r->ireg[typ] == 1) {
1533- int i, i1 = (width * r->ireg[len]) >> 2;
1534- pi = p;
1535- for (i = 0; i < i1; i++)
1536- pi[i] = 0;
1537- }
1538- return;
1539-}
1540-
1541-void funcf5(char *ebp, int pxx, int typ, int len)
1542-{
1543- // pxxはダミーで参照されない
1544- HOSECPU_RuntimeEnvironment *r = (HOSECPU_RuntimeEnvironment *) (ebp - jitCompA0001_EBP128);
1545- r->junkStack -= sizeof (int);
1546- int *pi = (int *)r->junkStack;
1547- r->junkStack -= *pi;
1548-#if 0
1549- int width = jitCompA000_dataWidth(r->ireg[typ]);
1550- void *p = r->junkStack;
1551- r->junkStack -= width * r->ireg[len];
1552-#endif
1553- return;
1554-}
1555-
1556-void funcf6(char *ebp, int pxx, int typ, int len)
1557-{
1558- HOSECPU_RuntimeEnvironment *r = (HOSECPU_RuntimeEnvironment *) (ebp - jitCompA0001_EBP128);
1559- int width = jitCompA000_dataWidth(jitCompA000_convTyp(r->ireg[typ])) >> 3;
1560- if (width < 0 || r->ireg[len] < 0)
1561- (*(r->errHndl))(r);
1562- void *p = malloc(width * r->ireg[len]);
1563- r->preg[pxx].p = p;
1564- r->preg[pxx].typ = r->ireg[typ];
1565- r->preg[pxx].p0 = p;
1566- r->preg[pxx].p1 = (unsigned char *)p + width * r->ireg[len];
1567- if (r->ireg[typ] == 1) {
1568- int i, i1 = (width * r->ireg[len]) >> 2, *pi;
1569- pi = p;
1570- for (i = 0; i < i1; i++)
1571- pi[i] = 0;
1572- for (i = 1; i < i1; i += 8)
1573- pi[i] |= -1;
1574- }
1575- return;
1576-}
1577-
1578-void funcf7(char *ebp, int pxx, int typ, int len)
1579-{
1580- // typとlenはダミーで参照されない
1581- HOSECPU_RuntimeEnvironment *r = (HOSECPU_RuntimeEnvironment *) (ebp - jitCompA0001_EBP128);
1582- free(r->preg[pxx].p);
1583- return;
1584-}
1585-
1586-void errHndl(HOSECPU_RuntimeEnvironment *r)
1587-{
1588- r = (HOSECPU_RuntimeEnvironment *) (((char *)r) - jitCompA0001_EBP128);
1589- (*(r->errHndl))(r);
1590- // ここに帰ってきてはいけない.
1591-}
1592-
1593-/*
1594- * jitcの出力コードをひとまとめにする関数を作成しその中身をjitCompile()で生成
1595- *
1596- * qq : 出力バイナリの書き込み位置のアドレスへの参照(書き込み位置を呼び出しに反映させるため参照渡しにする)
1597- * q1 : 出力バイナリの書き込み位置のアドレスの最大値
1598- * p0 : (*.ose)バイナリの読み込み位置のアドレス(ヘッダ部除去済)
1599- * p1 : (*.ose)バイナリの読み込み位置の取りうる最大値
1600- * (ただし、「確保したメモリ」の最大値なのでこれより手前にゴミデータが入っているかもしれない)
1601- * ret=1 : ヘッダのエラー
1602- * ret=2 : jitコンパイルエラー
1603- */
1604-int jitc0(unsigned char **qq, unsigned char *q1, const unsigned char *p0, const unsigned char *p1, int level, HOSECPU_LabelListTag *label)
1605-{
1606- unsigned char *q = *qq;
1607- if (p0[0] != 0x05 || p0[1] != SIGN1) // OSECPUのヘッダ (05E1) を確認
1608- return 1;
1609-
1610- *q++ = 0x55; /* PUSH(EBP); */
1611- *q++ = 0x8b; *q++ = 0x6c; *q++ = 0x24; *q++ = 0x08; /* MOV(EBP,[ESP+8]); */
1612-
1613- int i;
1614- for (i = 0; i < JITC_MAXLABELS; i++)
1615- label[i].opt = 0;
1616-
1617- // 以下のjitCompile()呼び出しでは第二引数をq1-2にした方がよいのではないか?
1618- i = jitCompiler(q, q1, p0 + 2, p1, p0, label, JITC_MAXLABELS, level, di1_serial, 0);
1619- if (i != 0) return 2;
1620- i = jitCompiler(q, q1, p0 + 2, p1, p0, label, JITC_MAXLABELS, level, di1_serial, JITC_PHASE1 + 0);
1621- if (i < 0) return 2;
1622- q += i;
1623-
1624- *q++ = 0x5d; /* POP(EBP); */
1625- *q++ = 0xc3; /* RET(); */
1626-
1627- *qq = q;
1628- return 0;
1629-}
1630-
1631-#if (USE_DEBUGGER != 0)
1632-
1633-int dbgrGetRegNum(const char *p)
1634-{
1635- int i, j, r = -1;
1636- if (p[2] <= ' ') {
1637- i = p[0] - '0';
1638- j = p[1] - '0';
1639- if (i > 9) i -= 'A' - '0' - 10;
1640- if (j > 9) j -= 'A' - '0' - 10;
1641- if (0 <= i && i <= 15 && 0 <= j && j <= 15)
1642- r = i << 4 | j;
1643- }
1644- return r;
1645-}
1646-
1647-void dbgrMain(HOSECPU_RuntimeEnvironment *r)
1648-{
1649- if (r->dbgr == 0) return;
1650- for (;;) {
1651- char cmd[64], *p;
1652- int i, j, k;
1653- printf("\ndbgr>");
1654- p = fgets(cmd, 64, stdin);
1655- if (p == NULL) break;
1656- if (cmd[0] == '\0') continue;
1657- if (cmd[0] == 'q' && cmd[1] <= ' ') break;
1658- if (cmd[0] == 'p' && cmd[1] <= ' ' && cmd[1] != '\0') {
1659- p = &cmd[2];
1660- while (*p <= ' ' && *p != '\0') p++;
1661- if (*p == 'R') {
1662- i = dbgrGetRegNum(p + 1);
1663- if (0 <= i && i <= 0x3f) {
1664- printf("R%02X = 0x%08X = %d\n", i, r->ireg[i], r->ireg[i]);
1665- }
1666- else
1667- puts("register name error");
1668- continue;
1669- }
1670- if (*p == 'P') {
1671- i = dbgrGetRegNum(p + 1);
1672- if (0 <= i && i <= 0x3f) {
1673- p = "invalid";
1674- if (0 <= r->preg[i].typ && r->preg[i].typ <= 0x15) {
1675- static char *typName[] = {
1676- "T_CODE", "T_VPTR", "T_SINT8", "T_UINT8",
1677- "T_SINT16", "T_UINT16", "T_SINT32", "T_UINT32",
1678- "T_SINT4", "T_UINT4", "T_SINT2", "T_UINT2",
1679- "T_SINT1", "T_UINT1", "T_SINT12", "T_UINT12",
1680- "T_SINT20", "T_UINT20", "T_SINT24", "T_UINT24",
1681- "T_SINT28", "T_UINT28"
1682- };
1683- p = typName[r->preg[i].typ];
1684- }
1685- printf("P%02X:\n type = %s(%04X), (origin-ptr) = 0x%08X\n", i, p, r->preg[i].typ, (unsigned int)(r->preg[i].p0));
1686- if (r->preg[i].p != NULL && r->preg[i].p0 != NULL) {
1687- j = jitCompA000_dataWidth(jitCompA000_convTyp(r->preg[i].typ)) >> 3;
1688- if (j <= 0) j = 1;
1689- k = (r->preg[i].p1 - r->preg[i].p0) / j;
1690- printf(" size = 0x%08X = %d\n", k, k);
1691- k = (r->preg[i].p - r->preg[i].p0) / j;
1692- printf(" pos = 0x%08X = %d\n", k, k);
1693- }
1694- else {
1695- puts(" null pointer");
1696- }
1697- }
1698- else
1699- puts("register name error");
1700- continue;
1701- }
1702- }
1703- puts("command error");
1704- }
1705- return;
1706-}
1707-
1708-#endif
1709-
1710-
1+#include "osecpu.h"
2+#include "jitc.h"
3+
4+#if (JITC_ARCNUM == 0x0001)
5+//
6+// for x86-32bit
7+//
8+
9+void jitCompPutImm32(struct JitCompWork *w, int i)
10+{
11+ jitCompPutByte1(w->dst, i & 0xff);
12+ jitCompPutByte1(w->dst, (i >> 8) & 0xff);
13+ jitCompPutByte1(w->dst, (i >> 16) & 0xff);
14+ jitCompPutByte1(w->dst, (i >> 24) & 0xff);
15+ return;
16+}
17+
18+int jitCompGetImm32(const unsigned char *src)
19+{
20+ return (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
21+}
22+
23+int jitCompGetLabelNum(struct JitCompWork *w, const unsigned char *src)
24+{
25+ int i = jitCompGetImm32(src);
26+ if (i < 0 || i >= w->maxLabels) {
27+ w->err = JITC_ERR_LABELNUM;
28+ i = 0;
29+ }
30+ return i;
31+}
32+
33+void jitCompA0001_85DispN(struct JitCompWork *w, int disp, int n)
34+{
35+ disp -= jitCompA0001_EBP128;
36+ if (-128 <= disp && disp <= 127) {
37+ jitCompPutByte2(w->dst, 0x45 | (n << 3), disp & 0xff);
38+ } else {
39+ jitCompPutByte1(w->dst, 0x85 | (n << 3));
40+ jitCompPutImm32(w, disp);
41+ }
42+ return;
43+}
44+
45+void jitCompA0001_movEbpDispReg32(struct JitCompWork *w, int disp, int reg32)
46+{
47+ jitCompPutByte1(w->dst, 0x89); /* MOV(mem, reg32); */
48+ jitCompA0001_85DispN(w, disp, reg32);
49+ return;
50+}
51+
52+void jitCompA0001_movReg32EbpDisp(struct JitCompWork *w, int reg32, int disp)
53+{
54+ jitCompPutByte1(w->dst, 0x8b); /* MOV(reg32, mem); */
55+ jitCompA0001_85DispN(w, disp, reg32);
56+ return;
57+}
58+
59+void jitCompA0001_movEaxRxx(struct JitCompWork *w, int rxx)
60+{
61+#if (jitCompA0001_USE_R3F_IMM32 != 0)
62+ if (rxx == 0x3f) {
63+ jitCompPutByte1(w->dst, 0xb8); /* MOV(EAX, ?); */
64+ jitCompPutImm32(w, w->r3f);
65+ return;
66+ }
67+#endif
68+ if (rxx >= 0x40 || rxx < 0){
69+ w->err = JITC_ERR_REGNUM;
70+ }
71+ jitCompA0001_movReg32EbpDisp(w, 0 /* EAX */, rxx * 4); /* MOV(EAX, [EBP+?]); */
72+ return;
73+}
74+
75+void jitCompA0001_movRxxEax(struct JitCompWork *w, int rxx)
76+{
77+ if (rxx >= 0x40 || rxx < 0){
78+ w->err = JITC_ERR_REGNUM;
79+ }
80+ jitCompA0001_movEbpDispReg32(w, rxx * 4, 0 /* EAX */); /* MOV([EBP+?], EAX); */
81+ return;
82+}
83+
84+void jitCompA0001_fixPrefix(struct JitCompWork *w)
85+{
86+ if (w->prefix != 0) {
87+ if (w->dst - w->dst0 > 127){
88+ w->err = JITC_ERR_REGNUM;
89+ }
90+ w->dst0[-1] = (unsigned char)((w->dst - w->dst0) & 0xff);
91+ }
92+ return;
93+}
94+
95+void jitCompA0001_checkCompPtr(struct JitCompWork *w, int p0, int p1)
96+{
97+ if (p0 >= 0x3f || p0 < 0){
98+ w->err = JITC_ERR_PREGNUM;
99+ }
100+ if (p1 >= 0x3f || p1 < 0){
101+ w->err = JITC_ERR_PREGNUM;
102+ }
103+ /* 比較可能可能なのかのチェックのコードを出力 */ /* 未完成 */
104+ return;
105+}
106+
107+void jitCompA000_loadRegCacheAll(struct JitCompWork *w)
108+{
109+ jitCompA0001_movReg32EbpDisp(w, 3 /* EBX */, 0 * 4); /* EBX = R00; */
110+ jitCompA0001_movReg32EbpDisp(w, 1 /* ECX */, 1 * 4); /* ECX = R01; */
111+ jitCompA0001_movReg32EbpDisp(w, 2 /* EDX */, 2 * 4); /* EDX = R02; */
112+ return;
113+}
114+
115+void jitCompA000_storeRegCacheAll(struct JitCompWork *w)
116+{
117+ jitCompA0001_movEbpDispReg32(w, 0 * 4, 3 /* EBX */); /* R00 = EBX; */
118+ jitCompA0001_movEbpDispReg32(w, 1 * 4, 1 /* ECX */); /* R01 = ECX; */
119+ jitCompA0001_movEbpDispReg32(w, 2 * 4, 2 /* EDX */); /* R02 = EDX; */
120+ return;
121+}
122+
123+void jitCompA000_loadRegCacheEcx(struct JitCompWork *w)
124+{
125+ jitCompA0001_movReg32EbpDisp(w, 1 /* ECX */, 1 * 4); /* ECX = R01; */
126+ return;
127+}
128+
129+void jitCompA000_storeRegCacheEcx(struct JitCompWork *w)
130+{
131+ jitCompA0001_movEbpDispReg32(w, 1 * 4, 1 /* ECX */); /* R01 = ECX; */
132+ return;
133+}
134+
135+void jitCompA000_loadRegCacheEdx(struct JitCompWork *w)
136+{
137+ jitCompA0001_movReg32EbpDisp(w, 2 /* EDX */, 2 * 4); /* EDX = R02; */
138+ return;
139+}
140+
141+void jitCompA000_storeRegCacheEdx(struct JitCompWork *w)
142+{
143+ jitCompA0001_movEbpDispReg32(w, 2 * 4, 2 /* EDX */); /* R02 = EDX; */
144+ return;
145+}
146+
147+int jitCompA000_selectRegCache(int rxx, int reg)
148+{
149+ switch (rxx) {
150+ case 0:
151+ //EBX
152+ reg = 3;
153+ break;
154+ case 1:
155+ //ECX
156+ reg = 1;
157+ break;
158+ case 2:
159+ //EDX
160+ reg = 2;
161+ break;
162+ }
163+ return reg;
164+}
165+
166+void jitCompA000_loadPRegCacheAll(struct JitCompWork *w)
167+{
168+ // jitCompA0001_movReg32EbpDisp(w, 5 /* EBP */, 256 + 0 * 32 + 0); /* EBP = P00; */
169+ jitCompA0001_movReg32EbpDisp(w, 6 /* ESI */, 256 + 1 * 32 + 0); /* ESI = P01; */
170+ jitCompA0001_movReg32EbpDisp(w, 7 /* EDI */, 256 + 2 * 32 + 0); /* EDI = P02; */
171+ return;
172+}
173+
174+void jitCompA000_storePRegCacheAll(struct JitCompWork *w)
175+{
176+ // jitCompA0001_movEbpDispReg32(w, 256 + 0 * 32 + 0, 5 /* EBP */); /* P00 = EBP; */
177+ jitCompA0001_movEbpDispReg32(w, 256 + 1 * 32 + 0, 6 /* ESI */); /* P01 = ESI; */
178+ jitCompA0001_movEbpDispReg32(w, 256 + 2 * 32 + 0, 7 /* EDI */); /* P02 = EDI; */
179+ return;
180+}
181+
182+int jitCompA000_selectPRegCache(int pxx, int reg)
183+{
184+ // if (pxx == 0) reg = 5; /* EBP */
185+ switch (pxx) {
186+ case 1:
187+ //ESI
188+ reg = 6;
189+ break;
190+
191+ case 2:
192+ //EDI
193+ reg = 7;
194+ break;
195+ }
196+ return reg;
197+}
198+
199+int jitCompA000_convTyp(int t)
200+{
201+ int r = -1;
202+
203+ if (1 <= t && t <= 7){
204+ r = t;
205+ } else if (8 <= t && t <= 13){
206+ r = 2 | (t & 1);
207+ } else if (14 <= t && t <= 15){
208+ r = 4 | (t & 1);
209+ } else if (16 <= t && t <= 21){
210+ r = 6 | (t & 1);
211+ }
212+ return r;
213+}
214+
215+int jitCompA000_dataWidth(int t)
216+{
217+ int r = -1;
218+ if (t == 0x0001) r = 256;
219+ t >>= 1;
220+ if (t == 0x0002 / 2) r = 8;
221+ if (t == 0x0004 / 2) r = 16;
222+ if (t == 0x0006 / 2) r = 32;
223+ if (t == 0x0008 / 2) r = 4;
224+ if (t == 0x000a / 2) r = 2;
225+ if (t == 0x000c / 2) r = 1;
226+ if (t == 0x000e / 2) r = 12;
227+ if (t == 0x0010 / 2) r = 20;
228+ if (t == 0x0012 / 2) r = 24;
229+ if (t == 0x0014 / 2) r = 28;
230+ return r;
231+}
232+
233+static unsigned char *errfnc;
234+
235+void jitCompA0001_checkType0(struct JitCompWork *w, int pxx, int typ, int ac)
236+{
237+ if (typ <= 0) { w->err = JITC_ERR_BADTYPE; }
238+ if (typ > 0x7f) { w->err = JITC_ERR_INTERNAL; }
239+ jitCompA0001_movReg32EbpDisp(w, 0 /* EAX */, 256 + pxx * 32 + 4); /* MOV(EAX, [EBP+?]); */ /* typ */
240+ jitCompPutByte3(w->dst, 0x83, 0xf8, typ & 0x7f); /* CMP(EAX, ?); */
241+ jitCompPutByte2(w->dst, 0x0f, 0x85); /* JNE */
242+ jitCompPutImm32(w, errfnc - (w->dst + 4));
243+ return;
244+}
245+
246+void jitCompA0001_checkType(struct JitCompWork *w, int pxx, int typ, int ac)
247+// data用.
248+// 将来的にはaliveやアクセス権チェックも入れる
249+{
250+ jitCompA0001_checkType0(w, pxx, typ, ac);
251+ return;
252+}
253+
254+void jitCompA0001_checkLimit(struct JitCompWork *w, int reg, int pxx)
255+{
256+ jitCompPutByte1(w->dst, 0x3b); /* CMP(reg, [EBP+?]); */
257+ jitCompA0001_85DispN(w, 256 + pxx * 32 + 8, reg); /* p0 */
258+ jitCompPutByte2(w->dst, 0x0f, 0x82); /* JB */
259+ jitCompPutImm32(w, errfnc - (w->dst + 4));
260+ jitCompPutByte1(w->dst, 0x3b); /* CMP(reg, [EBP+?]); */
261+ jitCompA0001_85DispN(w, 256 + pxx * 32 + 12, reg); /* p1 */
262+ jitCompPutByte2(w->dst, 0x0f, 0x83); /* JAE */
263+ jitCompPutImm32(w, errfnc - (w->dst + 4));
264+ return;
265+}
266+
267+// F5の場合、decoderが対応するalloc-freeを結びつけるのが簡単で、typやlenを指定必須にしてもフロントエンドコードに影響はない.
268+int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *src, const unsigned char *src1, const unsigned char *src0, HOSECPU_LabelListTag *label, int maxLabels, int level, int debugInfo1, int flags)
269+{
270+ // For IA-32 (x86, 32-bit)
271+ // 本来ならこのレイヤでは文法チェックしない
272+ //
273+ // dst : 現在の書き込みアドレス。
274+ // dst1 : 書き込みアドレスの最大値
275+ // src : 現在の読み込みアドレス(ヘッダ部は飛ばしてある
276+ // src1 : 読み込みアドレスの最大値
277+ // src0 : 読み込みバイナリのアドレス
278+ struct JitCompWork w;
279+ unsigned char *dst00 = dst, *enter0 = NULL, *tmp_ucp;
280+ char *errmsg = "";
281+ const unsigned char *oldsrc;
282+ int timecount = 0, i, j = 0, lastlabel = -1, debugInfo0 = -1;
283+ int reg0, reg1, reg2, cmp0reg = -1, cmp0lev = 0;
284+ w.dst = w.dst0 = dst;
285+ w.err = 0;
286+ w.maxLabels = maxLabels;
287+
288+ if ((flags & JITC_NOSTARTUP) == 0) {
289+ jitCompPutByte1(w.dst, 0x60); /* PUSHAD(); */
290+ jitCompA000_loadRegCacheAll(&w); /* start-up */
291+ jitCompA000_loadPRegCacheAll(&w);
292+ }
293+ if (level <= JITC_LV_SLOWER) {
294+ jitCompPutByte2(w.dst, 0x31, 0xc0); /* XOR(EAX, EAX); */
295+ jitCompA0001_movEbpDispReg32(&w, 2304 + 0, 0 /* EAX */); /* MOV(debugInfo0, EAX); */
296+ jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */
297+ jitCompPutImm32(&w, debugInfo1);
298+ jitCompA0001_movEbpDispReg32(&w, 2304 + 4, 0 /* EAX */); /* MOV(debugInfo1, EAX); */
299+ }
300+ while (src < src1) {
301+ w.prefix = 0; //0x04 CND 命令で変更される
302+ if (w.dst + 256 > dst1) { w.err = JITC_ERR_DST1; goto err_w; } // 書き込み領域が残り256バイト未満ならエラー
303+ timecount++;
304+ if (timecount >= 64) {
305+ timecount -= 64;
306+ /* 未完成(timeoutチェックコードを入れる) */
307+ }
308+ prefix_continue: // CND命令実行後ここに戻る
309+ switch (*src) {
310+
311+ case 0x00: /* NOP */
312+ if (w.prefix != 0) { w.err = JITC_ERR_PREFIX; goto err_w; } // 「条件付きでNOPを実行」するなんて、矛盾している!
313+ break;
314+
315+ case 0x01: /* LB */
316+
317+ /*
318+ * LB : ラベル設置命令。(6byte)
319+ * ・prefex = 1にする
320+ * ・timecount++し、timecountのチェックをする。
321+ * ・ラベル位置を登録する。
322+ * ・割り込みがある場合、このタイミングで割り込みを発生させる。
323+ *
324+ * 1 2 3 456
325+ * LB 01 opt imm32
326+ *
327+ */
328+
329+ if (enter0 == NULL && (src[6] == 0x3c /* 多数のレジスタをスタックに退避 */ || (src[6] == 0xfe/* REMARK */ && src[7] == 0x01 && src[9] == 0x3c))) { //beginFunc()中のLB
330+ // LB命令の後に0x3C命令・・・beginFunc()
331+ jitCompPutByte1(w.dst, 0xe9); // (x86) JMP rel32 : 次の命令との相対オフセットだけ相対ニアジャンプする
332+ enter0 = w.dst;
333+ jitCompPutImm32(&w, 0); // 飛び相対座標が0 ・・・パイプラインのフラッシュ??
334+ }
335+ if (src[6] == 0x34) { // LBの次の命令がDATA ・・・DAT_SA0(label, typ32, length) ・・・メモリ確保命令
336+ tmp_ucp = w.dst;
337+ jitCompPutByte1(w.dst, 0xe9); // (x86) JMP rel32 : 次の命令との相対オフセットだけ相対ニアジャンプする
338+ i = jitCompGetImm32(&src[7]); // type32 を取得
339+ j = 32;
340+ if (i != 1) {
341+ i = jitCompA000_convTyp(i);
342+ j = 0;
343+ if (i == 2 || i == 3) { j = 1; }
344+ if (i == 4 || i == 5) { j = 2; }
345+ if (i == 6 || i == 7) { j = 4; }
346+ }
347+ j *= jitCompGetImm32(&src[11]);
348+ if (j <= 0) w.err = JITC_ERR_BADTYPE;
349+ jitCompPutImm32(&w, j);
350+#if (jitCompA0001_OPTIMIZE_JMP != 0)
351+ if (j <= 127 - jitCompA0001_OPTIMIZE_ALIGN) {
352+ w.dst -= 5;
353+ jitCompPutByte2(w.dst, 0xeb, j);
354+ }
355+#endif
356+ }
357+#if (jitCompA0001_OPTIMIZE_ALIGN != 0)
358+ for (;;) {
359+ i = ((int)w.dst) & (jitCompA0001_OPTIMIZE_ALIGN - 1); /* ALIGNで割ったあまりを計算 */
360+ if (i == 0) break;
361+ i = jitCompA0001_OPTIMIZE_ALIGN - i;
362+ if (i == 1) { jitCompPutByte1(w.dst, 0x90); j += i; } /* NOP(); */
363+ if (i == 2) { jitCompPutByte2(w.dst, 0x89, 0xc0); j += i; } /* MOV(EAX, EAX); */
364+ if (i == 3) { jitCompPutByte3(w.dst, 0x8d, 0x76, 0x00); j += i; } /* LEA(ESI, [ESI+0]); */
365+ if (i == 4) { jitCompPutByte4(w.dst, 0x8d, 0x74, 0x26, 0x00); j += i; } /* LEA(ESI, [ESI*1+0]); */
366+ if (i == 5) { jitCompPutByte1(w.dst, 0x0d); jitCompPutImm32(&w, 0); j += i; } /* OR(EAX, 0); */
367+ if (i == 6) { jitCompPutByte2(w.dst, 0x8d, 0xb6); jitCompPutImm32(&w, 0); j += i; } /* LEA(ESI, [ESI+0]); */
368+ if (i >= 7) { jitCompPutByte3(w.dst, 0x8d, 0xb4, 0x26); jitCompPutImm32(&w, 0); j += 7; } /* LEA(ESI, [ESI*1+0]); */
369+ }
370+#endif
371+ if (src[6] == 0x34) {
372+ tmp_ucp[1] = j & 0xff;
373+ if (*tmp_ucp == 0xe9) {
374+ tmp_ucp[2] = (j >> 8) & 0xff;
375+ tmp_ucp[3] = (j >> 16) & 0xff;
376+ tmp_ucp[4] = (j >> 24) & 0xff;
377+ }
378+ }
379+ if ((flags & JITC_PHASE1) == 0) {
380+ i = jitCompGetLabelNum(&w, src + 2);
381+ //printf("i=%06X %06X\n", i, src-src0);
382+ if (label[i].opt != 0 && w.err == 0) { w.err = JITC_ERR_LABELREDEF; goto err_w; }
383+ if (w.prefix != 0) { w.err = JITC_ERR_PREFIX; goto err_w; }
384+ label[i].opt = src[1] + 1;
385+ label[i].typ = 0; /* TYP_CODE */
386+ label[i].p = w.dst;
387+ label[i].p1 = w.dst + 1;
388+ lastlabel = i;
389+ }
390+ cmp0reg = -1;
391+ timecount = 0;
392+ /* 未完成(timeoutチェックコードを入れる) */
393+ break;
394+
395+ case 0x02: /* LIMM */
396+
397+ /*
398+ * LIMM : 定数即値代入命令(6byte)
399+ *
400+ * 1 2 3456
401+ * 02 reg0R imm32
402+ *
403+ * ・reg3F は条件比較慣用句指定用&演算命令即値慣用句指定用。よってCND命令の直後では使用できない。
404+ */
405+
406+ if (src[1] == 0x3f && w.prefix != 0) w.err = JITC_ERR_PREFIX; // CND命令の直後でR3Fを書き換えるなんて変だよね
407+
408+#if (jitCompA0001_USE_R3F_IMM32 != 0)
409+ if (src[1] == 0x3f) { // R3Fへの代入は例外敵に、 w.r3f を使用
410+ w.r3f = jitCompGetImm32(src + 2);
411+ break;
412+ }
413+#endif
414+ i = jitCompGetImm32(src + 2); // 与えられた即値(第二引数)を取得
415+
416+ /* R00-R02 なら EBX, ECX, EDX 、それ以外なら EAX のレジスタIDを reg0 に代入 */
417+ reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */);
418+
419+#if (jitCompA0001_OPTIMIZE_MOV != 0)
420+ if (i == 0) {
421+ jitCompPutByte2(w.dst, 0x31, 0xc0 | reg0 << 3 | reg0); /* XOR(reg0, reg0); */
422+ jitCompA0001_movRxxEax(&w, src[1]);
423+ break;
424+ }
425+#endif
426+
427+ /* reg0 のレジスタに対応したMOV命令を発行 */
428+ jitCompPutByte1(w.dst, 0xb8 | reg0); /* MOV(reg0, ?); == 10111000b+wr imm32 */
429+ jitCompPutImm32(&w, i);
430+
431+ if (reg0 == 0) // R03以降の、レジスタの内容をメモリ上に格納してエミュレートする場合
432+
433+ jitCompA0001_movRxxEax(&w, src[1]);
434+ break;
435+
436+ case 0x03: /* PLIMM */ /* 未完成(plsまで対応) */
437+
438+ /*
439+ * PLIMM : ラベル番号代入命令(6byte)
440+ *
441+ * 1 2 3456
442+ * 03 PXX imm32
443+ *
444+ * ・P28 はAPI用
445+ * ・P30 はリターンアドレス
446+ * ・P3F はプログラムカウンタ
447+ */
448+
449+ i = jitCompGetLabelNum(&w, src + 2); // Pxxに代入するラベルの番号(第二引数)
450+ if ((flags & JITC_PHASE1) != 0 && w.err == 0) { // Phase 1であるならば
451+ if (label[i].opt == 0) { w.err = JITC_ERR_LABELNODEF; goto err_w; } // 指定されたラベル番号は存在しない
452+ if (src[1] != 0x3f && label[i].opt != 2) { w.err = JITC_ERR_LABELTYP; goto err_w; } //
453+ if (src[1] == 0x3f && label[i].typ != 0) { w.err = JITC_ERR_LABELTYP; goto err_w; } // プログラムカウンタに TYP_CODEでない値は代入できない
454+ }
455+ if (src[1] == 0x3f) { // プログラムカウンタへの代入なら
456+ if (w.prefix == 0) { // CND命令による条件付きでなければ、即座に移動
457+ jitCompPutByte1(w.dst, 0xe9); /* JMP(?); */
458+ }
459+ else { // 直前はCND命令。
460+
461+ /*
462+ * CND命令
463+ * 1 2
464+ * 04 reg0R
465+ *
466+ * いま、dstの末端はJZ命令になっている。 0x0F 0x84 cd
467+ */
468+
469+ // JZのとび先アドレスの書き換え?
470+ w.dst[-1] = w.dst[-2] ^ 0xf1; /* 74->85, 75->84 */
471+ w.dst[-2] = 0x0f;
472+
473+ w.prefix = 0;
474+ }
475+ j = 0;
476+ if ((flags & JITC_PHASE1) != 0 || (((flags & JITC_PHASE1) == 0) && label[i].opt != 0)) // label番号iが確保されていれば (このif文は意味をなさない)
477+ j = label[i].p - (w.dst + 4); // j はとび先の相対番地
478+ jitCompPutImm32(&w, j); // JMP もしくは JZ 命令のアドレス部を記述
479+#if (jitCompA0001_OPTIMIZE_JMP != 0)
480+ if (-128 - 3 <= j && j < 0) {
481+ if (w.dst[-5] == 0xe9) {
482+ j += 3;
483+ w.dst -= 5;
484+ jitCompPutByte1(w.dst, 0xeb); /* JMP(?); */
485+ }
486+ else {
487+ j += 4;
488+ w.dst -= 6;
489+ jitCompPutByte1(w.dst, w.dst[1] ^ 0xf0);
490+ }
491+ jitCompPutByte1(w.dst, j & 0xff);
492+ }
493+#endif
494+ }
495+ else { // プログラムカウンタ以外への代入
496+
497+ // 代入先が P01, P02なら ESI, EDI,それ以外ならEAXを指定
498+ reg0 = jitCompA000_selectPRegCache(src[1], 0 /* EAX */);
499+ jitCompPutByte1(w.dst, 0xb8 | reg0); /* MOV(reg0, ?); */
500+ jitCompPutImm32(&w, (int)label[i].p); // ラベルのパスを各レジスタに代入
501+
502+ // レジスタへの代入をメモリでエミュレーションする場合は、スタックに積む。
503+ if (reg0 == 0)
504+ jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32, 0); /* MOV([EBP+?], EAX); */
505+
506+ if (level < JITC_LV_FASTEST) {
507+ jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 8, reg0); /* MOV([EBP+?], reg0); */ /* p0 */
508+ jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */
509+ jitCompPutImm32(&w, label[i].typ);
510+ jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 4, 0); /* MOV([EBP+?], EAX); */ /* typ */
511+ jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */
512+ jitCompPutImm32(&w, (int)label[i].p1);
513+ jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 12, 0); /* MOV([EBP+?], EAX); */ /* p1 */
514+ jitCompPutByte2(w.dst, 0x31, 0xc0); /* XOR(EAX, EAX); */
515+ jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 16, 0); /* MOV([EBP+?], EAX); */ /* liveSign */
516+ jitCompA0001_movReg32EbpDisp(&w, 0, 2320); /* MOV(EAX, ptrCtrl); */
517+ jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 20, 0); /* MOV([EBP+?], EAX); */ /* pls */
518+ }
519+ }
520+ break;
521+
522+ case 0x04: /* CND (prefix) */
523+
524+ /*
525+ * CND命令
526+ * 与えられたRxxの最下位ビットが1であれば後続の命令を実行、そうでなければ飛ばす。
527+ */
528+
529+ if (src[1] >= 0x40) w.err = JITC_ERR_REGNUM; // R00-R3F 以外のレジスタは比較対象にできない
530+
531+ // 比較対象のレジスタがメモリ上にあれば-1, それ以外なら適切なレジスタ番号を返す
532+ reg0 = jitCompA000_selectRegCache(src[1], -1 /* mem */);
533+
534+ /* TEST命令を発行 */
535+ if (reg0 < 0) { //比較対象のレジスタはメモリ上にある
536+ jitCompPutByte1(w.dst, 0xf7); /* TEST([EBP+?],1); */
537+ jitCompA0001_85DispN(&w, src[1] * 4, 0);
538+ }
539+ else {
540+ jitCompPutByte2(w.dst, 0xf7, 0xc0 | reg0); /* TEST(reg0,1); */
541+ }
542+ jitCompPutImm32(&w, 1);
543+
544+ /* JZ命令を発行 */
545+ jitCompPutByte2(w.dst, 0x74, 0x00); /* JZ($+2) */
546+ cmp0reg = -1;
547+ if (w.err != 0) goto err_w;
548+ src += 2;
549+ w.prefix = 1; // プリフィックスをセット
550+ w.dst0 = w.dst;
551+ goto prefix_continue;
552+
553+ case 0x08: /* LMEM */ /* 完成 */
554+ i = jitCompGetImm32(src + 2);
555+ if (i == 0x0001) w.err = JITC_ERR_BADTYPE;
556+ if (level < JITC_LV_FASTER) {
557+ jitCompA0001_checkType(&w, src[6], i, 0); // read
558+ cmp0reg = -1;
559+ }
560+ reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */);
561+ reg1 = jitCompA000_selectPRegCache(src[6], 2 /* EDX */);
562+ if (reg0 != 0 /* EAX */ && reg1 == 2 /* EDX */)
563+ reg1 = 0; /* EAX */
564+ if (reg1 == 2 /* EDX */)
565+ jitCompA000_storeRegCacheEdx(&w);
566+ if (reg1 <= 3 /* EAX, EDX */)
567+ jitCompA0001_movReg32EbpDisp(&w, reg1, 256 + src[6] * 32 + 0); /* MOV(reg1, [EBP+?]); */
568+ if (level < JITC_LV_FASTER)
569+ jitCompA0001_checkLimit(&w, reg1, src[6]);
570+ i = jitCompA000_convTyp(jitCompGetImm32(src + 2));
571+ switch (i) {
572+ case 0x0002:
573+ jitCompPutByte3(w.dst, 0x0f, 0xbe, reg0 << 3 | reg1); /* MOVSX(reg0,BYTE [reg1]); */
574+ break;
575+ case 0x0003:
576+ jitCompPutByte3(w.dst, 0x0f, 0xb6, reg0 << 3 | reg1); /* MOVZX(reg0,BYTE [reg1]); */
577+ break;
578+ case 0x0004:
579+ jitCompPutByte3(w.dst, 0x0f, 0xbf, reg0 << 3 | reg1); /* MOVSX(reg0,WORD [reg1]); */
580+ break;
581+ case 0x0005:
582+ jitCompPutByte3(w.dst, 0x0f, 0xb7, reg0 << 3 | reg1); /* MOVZX(reg0,WORD [reg1]); */
583+ break;
584+ case 0x0006:
585+ case 0x0007:
586+ jitCompPutByte2(w.dst, 0x8b, reg0 << 3 | reg1); /* MOV(reg0, [reg1]); */
587+ break;
588+ default:
589+ w.err = JITC_ERR_BADTYPE;
590+ }
591+ if (reg0 == 0 /* EAX */)
592+ jitCompA0001_movRxxEax(&w, src[1]);
593+ if (reg1 == 2 /* EDX */)
594+ jitCompA000_loadRegCacheEdx(&w);
595+ break;
596+
597+ case 0x09: /* SMEM */ /* 完成 */
598+ i = jitCompGetImm32(src + 2);
599+ if (i == 0x0001) w.err = JITC_ERR_BADTYPE;
600+ if (level < JITC_LV_FASTER) {
601+ jitCompA0001_checkType(&w, src[6], i, 1); // write
602+ cmp0reg = -1;
603+ }
604+ reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */);
605+ reg1 = jitCompA000_selectPRegCache(src[6], 2 /* EDX */);
606+ if (reg0 != 0 /* EAX */ && reg1 == 2 /* EDX */)
607+ reg1 = 0; /* EAX */
608+ if (reg1 == 2 /* EDX */)
609+ jitCompA000_storeRegCacheEdx(&w);
610+ if (reg1 <= 3 /* EAX, EDX */)
611+ jitCompA0001_movReg32EbpDisp(&w, reg1, 256 + src[6] * 32 + 0); /* MOV(reg1, [EBP+?]); */
612+ if (level < JITC_LV_FASTER)
613+ jitCompA0001_checkLimit(&w, reg1, src[6]);
614+ if (reg0 == 0 /* EAX */)
615+ jitCompA0001_movEaxRxx(&w, src[1]);
616+ /* 値の範囲チェック */
617+ i = jitCompA000_convTyp(jitCompGetImm32(src + 2));
618+ switch (i) {
619+ case 0x0002:
620+ case 0x0003:
621+ jitCompPutByte2(w.dst, 0x88, reg0 << 3 | reg1); /* MOV([reg1], BYTE(reg0)); */
622+ break;
623+ case 0x0004:
624+ case 0x0005:
625+ jitCompPutByte3(w.dst, 0x66, 0x89, reg0 << 3 | reg1); /* MOV([reg1], WORD(reg0)); */
626+ break;
627+ case 0x0006:
628+ case 0x0007:
629+ jitCompPutByte2(w.dst, 0x89, reg0 << 3 | reg1); /* MOV([reg1], reg0); */
630+ break;
631+ default:
632+ w.err = JITC_ERR_BADTYPE;
633+ }
634+ if (reg1 == 2 /* EDX */)
635+ jitCompA000_loadRegCacheEdx(&w);
636+ break;
637+
638+ case 0x0a: /* PLMEM */ /* 完成 */
639+ i = jitCompGetImm32(src + 2);
640+ if (i != 0x0001) w.err = JITC_ERR_BADTYPE;
641+ if (level < JITC_LV_FASTER) {
642+ jitCompA0001_checkType(&w, src[6], i, 0); // read
643+ cmp0reg = -1;
644+ }
645+ reg0 = jitCompA000_selectPRegCache(src[1], 0 /* EAX */);
646+ reg1 = jitCompA000_selectPRegCache(src[6], 2 /* EDX */);
647+ // if (reg0 != 0 /* EAX */ && reg1 == 2 /* EDX */) /* これをやってはいけない!(by K, 2013.08.02) */
648+ // reg1 = 0; /* EAX */
649+ if (reg0 == reg1 && reg0 != 0) { // bugfix: hinted by yao, 2013.09.14. thanks!
650+ jitCompA000_storePRegCacheAll(&w);
651+ reg1 = 2; /* EDX */
652+ }
653+ if (reg1 == 2 /* EDX */)
654+ jitCompA000_storeRegCacheEdx(&w);
655+ if (reg1 <= 3 /* EAX, EDX */)
656+ jitCompA0001_movReg32EbpDisp(&w, reg1, 256 + src[6] * 32 + 0); /* MOV(reg1, [EBP+?]); */
657+ if (level < JITC_LV_FASTER)
658+ jitCompA0001_checkLimit(&w, reg1, src[6]);
659+ jitCompPutByte2(w.dst, 0x8b, reg0 << 3 | reg1); /* MOV(reg0, [reg1]); */
660+ if (reg0 == 0 /* EAX */)
661+ jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 0, 0); /* MOV([EBP+?], EAX); */
662+ for (i = 4; i < 32; i += 4) {
663+ jitCompPutByte3(w.dst, 0x8b, 0x40 | reg1, i); /* MOV(EAX, [reg1+?]); */
664+ jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + i, 0 /* EAX */); /* MOV([EBP+?], EAX); */
665+ }
666+ if (reg1 == 2 /* EDX */)
667+ jitCompA000_loadRegCacheEdx(&w);
668+ break;
669+
670+ case 0x0b: /* PSMEM */ /* 完成 */
671+ i = jitCompGetImm32(src + 2);
672+ if (i != 0x0001) w.err = JITC_ERR_BADTYPE;
673+ if (level < JITC_LV_FASTER) {
674+ jitCompA0001_checkType(&w, src[6], i, 1); // write
675+ cmp0reg = -1;
676+ }
677+ reg0 = jitCompA000_selectPRegCache(src[1], 0 /* EAX */);
678+ reg1 = jitCompA000_selectPRegCache(src[6], 2 /* EDX */);
679+ // if (reg0 != 0 /* EAX */ && reg1 == 2 /* EDX */) /* これをやってはいけない!(by K, 2013.08.02) */
680+ // reg1 = 0; /* EAX */
681+ if (reg1 == 2 /* EDX */)
682+ jitCompA000_storeRegCacheEdx(&w);
683+ if (reg1 <= 3 /* EAX, EDX */)
684+ jitCompA0001_movReg32EbpDisp(&w, reg1, 256 + src[6] * 32 + 0); /* MOV(reg1, [EBP+?]); */
685+ if (level < JITC_LV_FASTER)
686+ jitCompA0001_checkLimit(&w, reg1, src[6]);
687+ if (reg0 == 0 /* EAX */)
688+ jitCompA0001_movReg32EbpDisp(&w, reg0, 256 + src[1] * 32 + 0); /* MOV(reg0, [EBP+?]); */
689+ jitCompPutByte2(w.dst, 0x89, reg0 << 3 | reg1); /* MOV([reg1], reg0); */
690+ for (i = 4; i < 32; i += 4) {
691+ jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[1] * 32 + i); /* MOV(EAX, [EBP+?]); */
692+ jitCompPutByte3(w.dst, 0x89, 0x40 | reg1, i); /* MOV([reg1+?], EAX); */
693+ }
694+ if (reg1 == 2 /* EDX */)
695+ jitCompA000_loadRegCacheEdx(&w);
696+ break;
697+
698+ case 0x0e: /* PADD */ /* 完成 */
699+ if (level < JITC_LV_FASTER) {
700+ jitCompA0001_checkType0(&w, src[6], jitCompGetImm32(src + 2), 2); // other, aliveテストはとりあえずしない.
701+ cmp0reg = -1;
702+ }
703+ reg0 = jitCompA000_selectPRegCache(src[1], 0 /* EAX */);
704+ reg1 = jitCompA000_selectPRegCache(src[6], -1 /* mem */);
705+ if (reg1 < 0 /* mem */)
706+ jitCompA0001_movReg32EbpDisp(&w, reg0, 256 + src[6] * 32 + 0); /* MOV(reg0, [EBP+?]); */
707+ if (reg1 >= 0 && reg0 != reg1) {
708+ jitCompPutByte2(w.dst, 0x89, 0xc0 | reg1 << 3 | reg0); /* MOV(reg0, reg1); */
709+ }
710+ i = jitCompGetImm32(src + 2);
711+ j = -1;
712+ if (i == 1)
713+ j = 5; /* 32 */
714+ else {
715+ i = jitCompA000_convTyp(i);
716+ if (0x0002 <= i && i <= 0x0007)
717+ j = (i - 0x0002) >> 1;
718+ }
719+ if (j < 0) { w.err = JITC_ERR_BADTYPE; goto err_w; }
720+#if (jitCompA0001_USE_R3F_IMM32 != 0)
721+ if (src[7] == 0x3f) {
722+ j = w.r3f << j;
723+#if (jitCompA0001_USE_R3F_IMM8 != 0)
724+ if (-0x80 <= j && j <= 0x7f) {
725+#if (jitCompA0001_USE_R3F_INCDEC != 0)
726+ if (j == 1) { jitCompPutByte1(w.dst, 0x40 | reg0); goto padd1; } /* INC */
727+ if (j == -1) { jitCompPutByte1(w.dst, 0x48 | reg0); goto padd1; } /* DEC */
728+#endif
729+ jitCompPutByte3(w.dst, 0x83, 0xc0 | reg0, j & 0xff); /* ADD(reg0, im8); */
730+ goto padd1;
731+ }
732+#endif
733+ if (reg0 == 0) {
734+ jitCompPutByte1(w.dst, 0x05); /* ADD(reg0, ?); */
735+ }
736+ else {
737+ jitCompPutByte2(w.dst, 0x81, 0xc0 | reg0); /* ADD(reg0, ?); */
738+ }
739+ jitCompPutImm32(&w, j);
740+ goto padd1;
741+ }
742+#endif
743+ if (src[7] >= 0x40) w.err = JITC_ERR_REGNUM;
744+ if (j == 0) {
745+ reg1 = jitCompA000_selectRegCache(src[7], -1 /* mem */);
746+ if (reg1 >= 0) {
747+ jitCompPutByte2(w.dst, 0x01, 0xc0 | reg1 << 3 | reg0); /* ADD(reg0, reg1); */
748+ }
749+ else {
750+ jitCompPutByte1(w.dst, 0x03); /* ADD(reg0, [EBP+?]); */
751+ jitCompA0001_85DispN(&w, src[7] * 4, reg0);
752+ }
753+ }
754+ else {
755+ reg1 = jitCompA000_selectRegCache(src[7], -1 /* mem */);
756+ reg2 = 2; /* EDX */
757+ jitCompA000_storeRegCacheEdx(&w);
758+ if (reg1 < 0)
759+ jitCompA0001_movReg32EbpDisp(&w, reg2, src[7] * 4); /* MOV(reg2, [EBP+?]); */
760+ if (reg1 >= 0 && reg1 != reg2) {
761+ jitCompPutByte2(w.dst, 0x89, 0xc0 | reg1 << 3 | reg2); /* MOV(reg2, reg1); */
762+ }
763+ jitCompPutByte3(w.dst, 0xc1, 0xe0 | reg2, j); /* SHL(reg2, ?); */
764+ jitCompPutByte2(w.dst, 0x01, 0xc0 | reg2 << 3 | reg0); /* ADD(reg0, reg2); */
765+ jitCompA000_loadRegCacheEdx(&w);
766+ }
767+#if (jitCompA0001_USE_R3F_IMM32 != 0)
768+ padd1:
769+#endif
770+ if (reg0 == 0 /* EAX */)
771+ jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 0, reg0); /* MOV([EBP+?], reg0); */
772+ if (src[1] != src[6]) {
773+ for (i = 4; i < 32; i += 4) {
774+ jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[6] * 32 + i); /* MOV(EAX, [EBP+?]); */
775+ jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + i, 0 /* EAX */); /* MOV([EBP+?], EAX); */
776+ }
777+ }
778+ cmp0reg = -1;
779+ break;
780+
781+ case 0x0f: /* PDIF */ /* 未完成 */
782+ reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */);
783+ jitCompA000_storePRegCacheAll(&w); // 手抜き.
784+ jitCompA0001_checkCompPtr(&w, src[6], src[7]);
785+ jitCompA0001_movReg32EbpDisp(&w, reg0, 256 + src[6] * 32 + 0); /* MOV(reg0, [EBP+?]); */
786+ jitCompPutByte1(w.dst, 0x2b); /* SUB(EAX, [EBP+?]); */
787+ jitCompA0001_85DispN(&w, 256 + src[7] * 32 + 0, reg0);
788+ i = jitCompA000_convTyp(jitCompGetImm32(src + 2));
789+ j = -1;
790+ if (0x0002 <= i && i <= 0x0007)
791+ j = (i - 0x0002) >> 1;
792+ if (j < 0) { w.err = JITC_ERR_BADTYPE; goto err_w; }
793+ if (j > 0) {
794+ jitCompPutByte3(w.dst, 0xc1, 0xf8 | reg0, j); /* SAR(reg0,?); */
795+ }
796+ if (reg0 == 0 /* EAX */)
797+ jitCompA0001_movRxxEax(&w, src[1]);
798+ cmp0reg = src[1]; cmp0lev = 1;
799+ break;
800+
801+ case 0x10: /* OR */
802+ case 0x11: /* XOR */
803+ case 0x12: /* AND */
804+ case 0x14: /* ADD */
805+ case 0x15: /* SUB */
806+ case 0x16: /* MUL */
807+ if (src[1] >= 0x3f) w.err = JITC_ERR_REGNUM;
808+ reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */);
809+ reg1 = jitCompA000_selectRegCache(src[2], -1 /* mem */);
810+#if (jitCompA0001_USE_R3F_IMM32 != 0)
811+ if (src[2] == 0x3f) { // SUBのみ該当.
812+ if (*src != 0x15) w.err = JITC_ERR_REGNUM;
813+ reg2 = jitCompA000_selectRegCache(src[3], -1 /* mem */);
814+ if (reg2 >= 0)
815+ jitCompA000_storeRegCacheAll(&w);
816+ jitCompPutByte1(w.dst, 0xb8 | reg0); /* MOV(reg0, ?); */
817+ jitCompPutImm32(&w, w.r3f);
818+ jitCompPutByte1(w.dst, 0x2b);
819+ jitCompA0001_85DispN(&w, src[3] * 4, reg0);
820+ if (reg0 == 0)
821+ jitCompA0001_movRxxEax(&w, src[1]);
822+ break;
823+ }
824+#endif
825+ if (reg1 < 0) {
826+ jitCompA0001_movReg32EbpDisp(&w, reg0, src[2] * 4); /* MOV(reg0, [EBP+?]); */
827+ }
828+ if (reg1 >= 0 && reg0 != reg1) {
829+ jitCompPutByte2(w.dst, 0x89, 0xc0 | reg1 << 3 | reg0); /* MOV(reg0, reg1); */
830+ }
831+ if (!(src[0] == 0x10 && src[3] == 0xff)) { // bugfix: hinted by Iris, 2013.06.26. thanks!
832+ cmp0reg = src[1];
833+ cmp0lev = 1;
834+ if (src[0] < 0x14)
835+ cmp0lev = 2;
836+ if (src[0] == 0x16)
837+ cmp0reg = -1;
838+ }
839+ if (!(src[0] == 0x10 && src[3] == 0xff)) {
840+#if (jitCompA0001_USE_R3F_IMM32 != 0)
841+ if (src[3] == 0x3f) {
842+ if (*src == 0x16 && w.r3f == -1) {
843+ jitCompPutByte2(w.dst, 0xf7, 0xd8 | reg0); /* NEG(reg0); */
844+ if (reg0 == 0)
845+ jitCompA0001_movRxxEax(&w, src[1]);
846+ break;
847+ }
848+#if (jitCompA0001_USE_R3F_INCDEC != 0)
849+ if ((*src == 0x14 && w.r3f == 1) || (*src == 0x15 && w.r3f == -1)) {
850+ jitCompPutByte1(w.dst, 0x40 | reg0); /* INC(reg0); */
851+ if (reg0 == 0)
852+ jitCompA0001_movRxxEax(&w, src[1]);
853+ break;
854+ }
855+ if ((*src == 0x15 && w.r3f == 1) || (*src == 0x14 && w.r3f == -1)) {
856+ jitCompPutByte1(w.dst, 0x48 | reg0); /* DEC(reg0); */
857+ if (reg0 == 0)
858+ jitCompA0001_movRxxEax(&w, src[1]);
859+ break;
860+ }
861+#endif
862+#if (jitCompA0001_USE_R3F_IMM8 != 0)
863+ if (-0x80 <= w.r3f && w.r3f <= 0x7f) {
864+ if (*src != 0x16) {
865+ static unsigned char basic_op_table_im8[] = { 0xc8, 0xf0, 0xe0, 0, 0xc0, 0xe8 };
866+ jitCompPutByte3(w.dst, 0x83, basic_op_table_im8[*src - 0x10] | reg0, w.r3f & 0xff);
867+ }
868+ else {
869+ jitCompPutByte3(w.dst, 0x6b, 0xc0 | reg0 << 3 | reg0, w.r3f & 0xff);
870+ }
871+ if (reg0 == 0)
872+ jitCompA0001_movRxxEax(&w, src[1]);
873+ break;
874+ }
875+#endif
876+ if (reg0 == 0 /* EAX */) {
877+ static unsigned char basic_op_table_im32_eax[] = { 0x0d, 0x35, 0x25, 0, 0x05, 0x2d, 0xc0 };
878+ if (*src == 0x16) { jitCompPutByte1(w.dst, 0x69); }
879+ jitCompPutByte1(w.dst, basic_op_table_im32_eax[*src - 0x10]);
880+ }
881+ else {
882+ if (*src != 0x16) {
883+ static unsigned char basic_op_table_im32_reg[] = { 0xc8, 0xf0, 0xe0, 0, 0xc0, 0xe8 };
884+ jitCompPutByte2(w.dst, 0x81, basic_op_table_im32_reg[*src - 0x10] | reg0);
885+ }
886+ else {
887+ jitCompPutByte2(w.dst, 0x69, 0xc0 | reg0 << 3 | reg0);
888+ }
889+ }
890+ jitCompPutImm32(&w, w.r3f);
891+ if (reg0 == 0)
892+ jitCompA0001_movRxxEax(&w, src[1]);
893+ break;
894+ }
895+#endif
896+ reg1 = jitCompA000_selectRegCache(src[3], -1 /* mem */);
897+ if (src[3] >= 0x40) w.err = JITC_ERR_REGNUM;
898+ if (*src != 0x16) {
899+ if (reg1 >= 0) {
900+ static unsigned char basic_op_table_rr[] = { 0x09, 0x31, 0x21, 0, 0x01, 0x29 }; /* op(reg,reg); */
901+ jitCompPutByte2(w.dst, basic_op_table_rr[*src - 0x10], 0xc0 | reg1 << 3 | reg0);
902+ }
903+ else {
904+ static unsigned char basic_op_table_rm[] = { 0x0b, 0x33, 0x23, 0, 0x03, 0x2b, 0xaf }; /* op(reg,mem); */
905+ jitCompPutByte1(w.dst, basic_op_table_rm[*src - 0x10]);
906+ jitCompA0001_85DispN(&w, src[3] * 4, reg0);
907+ }
908+ }
909+ else {
910+ if (reg1 >= 0) {
911+ jitCompPutByte3(w.dst, 0x0f, 0xaf, 0xc0 | reg0 << 3 | reg1);
912+ }
913+ else {
914+ jitCompPutByte2(w.dst, 0x0f, 0xaf);
915+ jitCompA0001_85DispN(&w, src[3] * 4, reg0);
916+ }
917+ }
918+ }
919+ if (reg0 == 0)
920+ jitCompA0001_movRxxEax(&w, src[1]);
921+ break;
922+
923+ case 0x18: /* SHL */
924+ case 0x19: /* SAR */
925+ if (src[1] >= 0x3f) w.err = JITC_ERR_REGNUM;
926+ if (src[3] >= 0x40) w.err = JITC_ERR_REGNUM;
927+#if (jitCompA0001_USE_R3F_IMM32 != 0)
928+ if (src[3] == 0x3f) {
929+ reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */);
930+ reg1 = jitCompA000_selectRegCache(src[2], -1 /* mem */);
931+ if (src[1] >= 0x3f) w.err = JITC_ERR_REGNUM;
932+ if (reg1 == -1)
933+ jitCompA0001_movReg32EbpDisp(&w, reg0, src[2] * 4); /* MOV(reg1, [EBP+?]); */
934+ else {
935+ if (reg0 != reg1) {
936+ jitCompPutByte2(w.dst, 0x89, 0xc0 | reg1 << 3 | reg0); /* MOV(reg0, reg1); */
937+ }
938+ }
939+ if (*src == 0x18) { jitCompPutByte3(w.dst, 0xc1, 0xe0 | reg0, w.r3f); } /* SHL(reg0, im8); */
940+ if (*src == 0x19) { jitCompPutByte3(w.dst, 0xc1, 0xf8 | reg0, w.r3f); } /* SAR(reg0, im8); */
941+ if (reg0 == 0 /* EAX */)
942+ jitCompA0001_movRxxEax(&w, src[1]);
943+ cmp0reg = src[1];
944+ cmp0lev = 1;
945+ break;
946+ }
947+#endif
948+ jitCompA000_storeRegCacheAll(&w); // 手抜き.
949+ jitCompA0001_movReg32EbpDisp(&w, 1 /* ECX */, src[3] * 4); /* MOV(ECX, [EBP+?]); */
950+#if (jitCompA0001_USE_R3F_IMM32 != 0)
951+ if (src[2] == 0x3f) {
952+ jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */
953+ jitCompPutImm32(&w, w.r3f);
954+ }
955+ else {
956+ jitCompA0001_movEaxRxx(&w, src[2]);
957+ }
958+#else
959+ jitCompA0001_movEaxRxx(&w, src[2]);
960+#endif
961+ if (*src == 0x18) { jitCompPutByte2(w.dst, 0xd3, 0xe0); } /* SHL(EAX, CL); */
962+ if (*src == 0x19) { jitCompPutByte2(w.dst, 0xd3, 0xf8); } /* SAR(EAX, CL); */
963+ jitCompA0001_movRxxEax(&w, src[1]);
964+ jitCompA000_loadRegCacheAll(&w); // 手抜き.
965+ cmp0reg = src[1];
966+ cmp0lev = 1;
967+ break;
968+
969+ case 0x1a: /* DIV */
970+ case 0x1b: /* MOD */
971+ if (src[1] >= 0x3f) w.err = JITC_ERR_REGNUM;
972+ if (src[2] >= 0x40) w.err = JITC_ERR_REGNUM;
973+ if (src[3] >= 0x40) w.err = JITC_ERR_REGNUM;
974+ jitCompA000_storeRegCacheAll(&w); // 手抜き.
975+#if (jitCompA0001_USE_R3F_IMM32 != 0)
976+ if (src[3] == 0x3f) {
977+ jitCompPutByte1(w.dst, 0xb8 | 1); /* MOV(ECX, ?); */
978+ jitCompPutImm32(&w, w.r3f);
979+ }
980+ else {
981+ jitCompA0001_movReg32EbpDisp(&w, 1 /* ECX */, src[3] * 4); /* MOV(ECX, [EBP+?]); */
982+ }
983+ if (src[2] == 0x3f) {
984+ jitCompPutByte1(w.dst, 0xb8 | 0); /* MOV(EAX, ?); */
985+ jitCompPutImm32(&w, w.r3f);
986+ }
987+ else {
988+ jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, src[2] * 4); /* MOV(EAX, [EBP+?]); */
989+ }
990+#else
991+ jitCompA0001_movReg32EbpDisp(&w, 1 /* ECX */, src[3] * 4); /* MOV(ECX, [EBP+?]); */
992+ jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, src[2] * 4); /* MOV(EAX, [EBP+?]); */
993+#endif
994+ jitCompPutByte1(w.dst, 0x99); /* CDQ(); */
995+ /* ECXがゼロではないことを確認すべき */
996+ jitCompPutByte2(w.dst, 0xf7, 0xf9); /* IDIV(ECX); */
997+ if (*src == 0x1a) { jitCompA0001_movEbpDispReg32(&w, src[1] * 4, 0 /* EAX */); }
998+ if (*src == 0x1b) { jitCompA0001_movEbpDispReg32(&w, src[1] * 4, 2 /* EDX */); }
999+ jitCompA000_loadRegCacheAll(&w); // 手抜き.
1000+ cmp0reg = -1;
1001+ break;
1002+
1003+ case 0x1c: /* PLMT0 */
1004+ case 0x1d: /* PLMT1 */
1005+ if (src[1] >= 0x40 || src[2] >= 0x40) w.err = JITC_ERR_PREGNUM;
1006+ if (level < JITC_LV_FASTEST) {
1007+ cmp0reg = -1;
1008+ if (level < JITC_LV_FASTER) {
1009+ // typ が一致していることを確認.
1010+ // plsとliveSignが一致していることを確認.
1011+
1012+ // preg1はp0 <= p <= p1 を満たしているか?.
1013+ // 新しいp0/p1は古いp0〜p1に適合しているか?.
1014+
1015+ }
1016+ }
1017+
1018+ case 0x1e: /* PCP */ /* 未完成(p1まで完成) */
1019+ if (src[1] >= 0x40 || src[2] >= 0x40) w.err = JITC_ERR_PREGNUM;
1020+ if (src[2] == 0x3f) w.err = JITC_ERR_PREGNUM;
1021+ if (src[1] != 0x3f) {
1022+ /* src[2] == 0xff の場合に対応できてない */
1023+ jitCompA000_storePRegCacheAll(&w); // 手抜き.
1024+ for (i = 0; i < 32; i += 4) {
1025+ jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[2] * 32 + i); /* MOV(EAX, [EBP+?]); */
1026+ jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + i, 0 /* EAX */); /* MOV([EBP+?], EAX); */
1027+ }
1028+ jitCompA000_loadPRegCacheAll(&w); // 手抜き.
1029+ }
1030+ else {
1031+ if (level < JITC_LV_FASTER) {
1032+ jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[2] * 32 + 4); /* MOV(EAX, [EBP+?]); */ /* typ */
1033+ jitCompPutByte3(w.dst, 0x83, 0xf8, 0); /* CMP(EAX, 0); */
1034+ jitCompPutByte2(w.dst, 0x0f, 0x85); /* JNE */
1035+ jitCompPutImm32(&w, errfnc - (w.dst + 4));
1036+ /* セキュリティチェックが足りてない!(aliveとか) */
1037+ }
1038+ reg0 = 0; /* EAX */
1039+ jitCompA000_storePRegCacheAll(&w); // 手抜き.
1040+ jitCompA0001_movReg32EbpDisp(&w, reg0, 256 + src[2] * 32 + 0); /* MOV(EAX, [EBP+?]); */
1041+ if (level < JITC_LV_FASTER) {
1042+ jitCompPutByte1(w.dst, 0x3b); /* CMP(reg0, [EBP+?]); */
1043+ jitCompA0001_85DispN(&w, 256 + src[2] * 32 + 8, reg0); /* p0 */
1044+ jitCompPutByte2(w.dst, 0x0f, 0x85); /* JNE */
1045+ jitCompPutImm32(&w, errfnc - (w.dst + 4));
1046+ }
1047+ jitCompPutByte2(w.dst, 0xff, 0xe0); /* JMP(EAX); */
1048+ }
1049+ break;
1050+
1051+ case 0x1f: /* PCST */
1052+ if (jitCompGetImm32(src + 2) == 0) {
1053+ if (level < JITC_LV_FASTER)
1054+ jitCompA0001_checkType0(&w, src[6], jitCompGetImm32(src + 7), 2);
1055+ jitCompA000_storePRegCacheAll(&w); // 手抜き.
1056+ for (i = 0; i < 32 - 4; i += 4) {
1057+ jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[6] * 32 + i); /* MOV(EAX, [EBP+?]); */
1058+ if (i == 4) {
1059+ jitCompPutByte1(w.dst, 0x0d); /* OR(EAX, ?); */
1060+ jitCompPutImm32(&w, 0x80000000);
1061+ }
1062+ jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + i, 0 /* EAX */); /* MOV([EBP+?], EAX); */
1063+ }
1064+ jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */
1065+ jitCompPutImm32(&w, debugInfo1);
1066+ jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 28, 0 /* EAX */); /* MOV([EBP+?], EAX); */
1067+ jitCompA000_loadPRegCacheAll(&w); // 手抜き.
1068+ cmp0reg = -1;
1069+ break;
1070+ }
1071+ if (jitCompGetImm32(src + 7) == 0) {
1072+ jitCompA000_storePRegCacheAll(&w); // 手抜き.
1073+ for (i = 0; i < 32 - 4; i += 4) {
1074+ jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[6] * 32 + i); /* MOV(EAX, [EBP+?]); */
1075+ if (i == 4) {
1076+ jitCompPutByte1(w.dst, 0x25); /* AND(EAX, ?); */
1077+ jitCompPutImm32(&w, 0x7fffffff);
1078+ }
1079+ jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + i, 0 /* EAX */); /* MOV([EBP+?], EAX); */
1080+ }
1081+ if (level < JITC_LV_FASTER) {
1082+ jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[6] * 32 + 28); /* MOV(EAX, [EBP+?]); */
1083+ jitCompPutByte1(w.dst, 0x3d); /* CMP(EAX, ?); */
1084+ jitCompPutImm32(&w, debugInfo1);
1085+ jitCompPutByte2(w.dst, 0x74, 8); /* JE */
1086+ jitCompPutByte2(w.dst, 0x31, 0xc0); /* XOR(EAX, EAX); (2) */
1087+ jitCompA0001_movEbpDispReg32(&w, 256 + src[1] * 32 + 0, 0 /* EAX */); /* MOV([EBP+?], EAX); (1+1+4) */
1088+ }
1089+ jitCompA000_loadPRegCacheAll(&w); // 手抜き.
1090+ cmp0reg = -1;
1091+ break;
1092+ }
1093+ w.err = JITC_ERR_OPECODE;
1094+ goto err_w;
1095+
1096+ case 0x20: /* CMPE */
1097+ case 0x21: /* CMPNE */
1098+ case 0x22: /* CMPL */
1099+ case 0x23: /* CMPGE */
1100+ case 0x24: /* CMPLE */
1101+ case 0x25: /* CMPG */
1102+ case 0x26: /* TSTZ */
1103+ case 0x27: /* TSTNZ */
1104+ reg0 = jitCompA000_selectRegCache(src[2], 0 /* EAX */);
1105+ reg1 = jitCompA000_selectRegCache(src[3], -1 /* mem */);
1106+ if (src[1] == 0x3f) {
1107+ /* 特殊構文チェック */
1108+ if (w.prefix != 0) { w.err = JITC_ERR_PREFIX; goto err_w; }
1109+ if (src[4] != 0x04 || src[5] != 0x3f || src[6] != 0x03 || src[7] != 0x3f) {
1110+ w.err = JITC_ERR_IDIOM; goto err_w;
1111+ }
1112+ }
1113+ if (reg0 == 0)
1114+ jitCompA0001_movEaxRxx(&w, src[2]);
1115+#if (jitCompA0001_USE_R3F_IMM32 != 0)
1116+ if (src[3] == 0x3f) {
1117+#if (jitCompA0001_OPTIMIZE_CMP != 0)
1118+ if ((*src <= 0x25 && w.r3f == 0) || (*src >= 0x26 && w.r3f == -1)) {
1119+ i = 0;
1120+ if (cmp0reg == src[2]) {
1121+ if (cmp0lev >= 1 && (src[0] == 0x20 || src[0] == 0x21 || src[0] == 0x26 || src[0] == 0x27))
1122+ i = 1;
1123+ if (cmp0lev >= 2 && (src[0] == 0x22 || src[0] == 0x23 || src[0] == 0x24 || src[0] == 0x25))
1124+ i = 1;
1125+ }
1126+ if (i == 0) {
1127+ jitCompPutByte2(w.dst, 0x85, 0xc0 | reg0 << 3 | reg0); /* TEST(reg0, reg0); */
1128+ }
1129+ cmp0reg = src[2];
1130+ cmp0lev = 2;
1131+ goto cmpcc1;
1132+ }
1133+#endif
1134+#if (jitCompA0001_USE_R3F_IMM8 != 0)
1135+ if (-0x80 <= w.r3f && w.r3f <= 0x7f && *src <= 0x25) {
1136+ jitCompPutByte3(w.dst, 0x83, 0xf8 | reg0, w.r3f);
1137+ goto cmpcc1;
1138+ }
1139+#endif
1140+ if (reg0 == 0) {
1141+ if (*src <= 0x25) { jitCompPutByte1(w.dst, 0x3d); }
1142+ if (*src >= 0x26) { jitCompPutByte1(w.dst, 0xa9); }
1143+ }
1144+ else {
1145+ if (*src <= 0x25) { jitCompPutByte2(w.dst, 0x81, 0xf8 | reg0); }
1146+ if (*src >= 0x26) { jitCompPutByte2(w.dst, 0xf7, 0xc0 | reg0); }
1147+ }
1148+ jitCompPutImm32(&w, w.r3f);
1149+ goto cmpcc1;
1150+ }
1151+#endif
1152+ if (src[3] >= 0x40) w.err = JITC_ERR_PREGNUM;
1153+ if (reg1 >= 0) {
1154+ if (*src <= 0x25) { jitCompPutByte2(w.dst, 0x39, 0xc0 | reg1 << 3 | reg0); }
1155+ if (*src >= 0x26) { jitCompPutByte2(w.dst, 0x85, 0xc0 | reg1 << 3 | reg0); }
1156+ }
1157+ else {
1158+ if (*src <= 0x25) { jitCompPutByte1(w.dst, 0x3b); }
1159+ if (*src >= 0x26) { jitCompPutByte1(w.dst, 0x85); }
1160+ jitCompA0001_85DispN(&w, src[3] * 4, reg0);
1161+ }
1162+ cmpcc1:
1163+ if (w.err != 0) goto err_w;
1164+ static unsigned char cmpcc_table0[] = {
1165+ 0x04, 0x05, 0x0c, 0x0d, 0x0e, 0x0f, 0x04, 0x05, /* CMPcc, TSTcc */
1166+ 0x04, 0x05, 0x02, 0x03, 0x06, 0x07 /* PCMPcc */
1167+ };
1168+#if (jitCompA0001_USE_R3F_CMPJMP != 0)
1169+ if (src[1] == 0x3f) {
1170+ /* 特殊構文を利用した最適化 */
1171+ jitCompPutByte2(w.dst, 0x0f, 0x80 | cmpcc_table0[*src - 0x20]);
1172+ src += 6;
1173+ i = jitCompGetLabelNum(&w, src + 2);
1174+ if ((flags & JITC_PHASE1) != 0 && w.err != 0) {
1175+ if (label[i].opt == 0) { w.err = JITC_ERR_LABELNODEF; goto err_w; }
1176+ // if (label[i].typ != 1) { w.err = JITC_ERR_LABELTYP; goto err_w; }
1177+ }
1178+ j = 0;
1179+ if ((flags & JITC_PHASE1) != 0 || (((flags & JITC_PHASE1) == 0) && label[i].opt != 0))
1180+ j = label[i].p - (w.dst + 4);
1181+ jitCompPutImm32(&w, j);
1182+#if (jitCompA0001_OPTIMIZE_JMP != 0)
1183+ if (-128 - 4 <= j && j < 0) {
1184+ j += 4;
1185+ w.dst -= 6;
1186+ jitCompPutByte2(w.dst, w.dst[1] ^ 0xf0, j & 0xff);
1187+ }
1188+#endif
1189+ src += 6;
1190+ if (w.err != 0) goto err_w;
1191+ continue;
1192+ }
1193+#endif
1194+ /* 一般的なJITC */
1195+ reg0 = jitCompA000_selectRegCache(src[1], 0 /* EAX */);
1196+ jitCompPutByte3(w.dst, 0x0f, 0x90 | cmpcc_table0[*src - 0x20], 0xc0 | reg0); /* SETcc(BYTE(reg0)); */
1197+ jitCompPutByte3(w.dst, 0x0f, 0xb6, 0xc0 | reg0 << 3 | reg0); /* MOVZX(reg0, BYTE(reg0)); */
1198+ jitCompPutByte2(w.dst, 0xf7, 0xd8 | reg0); /* NEG(reg0); */
1199+ if (reg0 == 0)
1200+ jitCompA0001_movRxxEax(&w, src[1]);
1201+ cmp0reg = src[2];
1202+ cmp0lev = 1;
1203+ break;
1204+
1205+ case 0x28: /* PCMPE */
1206+ case 0x29: /* PCMPNE */
1207+ case 0x2a: /* PCMPL */
1208+ case 0x2b: /* PCMPGE */
1209+ case 0x2c: /* PCMPLE */
1210+ case 0x2d: /* PCMPG */
1211+ if (src[1] == 0x3f) {
1212+ /* 特殊構文チェック */
1213+ if (w.prefix != 0) { w.err = JITC_ERR_PREFIX; goto err_w; }
1214+ if (src[4] != 0x04 || src[5] != 0x3f || src[6] != 0x03 || src[7] != 0x3f) {
1215+ w.err = JITC_ERR_IDIOM; goto err_w;
1216+ }
1217+ }
1218+ if (src[2] >= 0x40) w.err = JITC_ERR_PREGNUM;
1219+ jitCompA000_storePRegCacheAll(&w); // 手抜き.
1220+ if (src[3] != 0xff)
1221+ jitCompA0001_checkCompPtr(&w, src[2], src[3]);
1222+ jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + src[2] * 32 + 0); /* MOV(EAX, [EBP+?]); */
1223+ if (src[3] != 0xff) {
1224+ jitCompPutByte1(w.dst, 0x3b); /* CMP(EAX, [EBP+?]); */
1225+ jitCompA0001_85DispN(&w, 256 + src[3] * 32 + 0, 0);
1226+ }
1227+ else {
1228+ /* ヌルポインタとの比較はこれでいいのか?たぶんよくない */
1229+ jitCompPutByte3(w.dst, 0x83, 0xf8, 0x00); /* CMP(EAX, 0); */
1230+ }
1231+ cmp0reg = -1;
1232+ goto cmpcc1;
1233+
1234+ case 0x30: /* talloc(old:F4) */
1235+ case 0x31: /* tfree(old:F5) */
1236+ case 0x32: /* malloc(old:F6) */
1237+ case 0x33: /* mfree(old:F7) */
1238+ jitCompA000_storeRegCacheAll(&w); // 手抜き.
1239+ jitCompA000_storePRegCacheAll(&w); // 手抜き.
1240+ jitCompPutByte2(w.dst, 0x6a, src[3]); /* PUSH(?); */
1241+ jitCompPutByte2(w.dst, 0x6a, src[2]); /* PUSH(?); */
1242+ jitCompPutByte2(w.dst, 0x6a, src[1]); /* PUSH(?); */
1243+ jitCompPutByte1(w.dst, 0x55); /* PUSH(EBP); */
1244+ jitCompPutByte1(w.dst, 0xe8);
1245+ if (*src == 0x30) j = ((unsigned char *)&funcf4) - (w.dst + 4);
1246+ if (*src == 0x31) j = ((unsigned char *)&funcf5) - (w.dst + 4);
1247+ if (*src == 0x32) j = ((unsigned char *)&funcf6) - (w.dst + 4);
1248+ if (*src == 0x33) j = ((unsigned char *)&funcf7) - (w.dst + 4);
1249+ jitCompPutImm32(&w, j);
1250+ jitCompPutByte3(w.dst, 0x83, 0xc4, 0x10); /* ADD(ESP,16); */
1251+ jitCompA000_loadRegCacheAll(&w); // 手抜き.
1252+ jitCompA000_loadPRegCacheAll(&w); // 手抜き.
1253+ cmp0reg = -1;
1254+ break;
1255+
1256+ case 0x34: /* data (暫定) */
1257+ cmp0reg = -1;
1258+ if (w.prefix != 0) { w.err = JITC_ERR_PREFIX; goto err_w; }
1259+ int k = jitCompGetImm32(&src[1]), tmpData, bitCount, dataWidth = jitCompA000_dataWidth(k);
1260+ if (lastlabel >= 0 && label[lastlabel].typ == 0)
1261+ label[lastlabel].typ = k;
1262+ if (k != 1) {
1263+ i = jitCompA000_convTyp(k);
1264+ if (i < 2 || i > 7) { w.err = JITC_ERR_BADTYPE; goto err_w; }
1265+ }
1266+ j = jitCompGetImm32(&src[5]);
1267+ oldsrc = src;
1268+ src += 9;
1269+ if (k != 1) {
1270+ bitCount = 7;
1271+ while (j > 0) {
1272+ if (src >= src1) { w.err = JITC_ERR_SRC1; src = oldsrc; goto err_w; }
1273+ if (w.dst + 256 > dst1) { w.err = JITC_ERR_DST1; src = oldsrc; goto err_w; }
1274+ tmpData = 0;
1275+ for (k = 0; k < dataWidth; k++) {
1276+ tmpData = tmpData << 1 | ((*src >> bitCount) & 1);
1277+ bitCount--;
1278+ if (bitCount < 0) {
1279+ bitCount = 7;
1280+ src++;
1281+ }
1282+ }
1283+ if ((i & 1) == 0 && dataWidth <= 31 && (tmpData >> (dataWidth - 1)) != 0) {
1284+ tmpData -= 1 << dataWidth;
1285+ }
1286+ if (i == 2 || i == 3) { jitCompPutByte1(w.dst, tmpData & 0xff); }
1287+ if (i == 4 || i == 5) { jitCompPutByte2(w.dst, tmpData & 0xff, (tmpData >> 8) & 0xff); }
1288+ if (i == 6 || i == 7) { jitCompPutByte4(w.dst, tmpData & 0xff, (tmpData >> 8) & 0xff, (tmpData >> 16) & 0xff, (tmpData >> 24) & 0xff); }
1289+ j--;
1290+ }
1291+ }
1292+ else {
1293+ while (j > 0) {
1294+ if (src >= src1) { w.err = JITC_ERR_SRC1; src = oldsrc; goto err_w; }
1295+ if (w.dst + 256 > dst1) { w.err = JITC_ERR_DST1; src = oldsrc; goto err_w; }
1296+ i = jitCompGetImm32(src);
1297+ src += 4;
1298+ if ((flags & JITC_PHASE1) != 0 && w.err == 0) {
1299+ if (label[i].opt == 0) { w.err = JITC_ERR_LABELNODEF; goto err_w; }
1300+ }
1301+ jitCompPutImm32(&w, (int)label[i].p);
1302+ jitCompPutImm32(&w, label[i].typ);
1303+ jitCompPutImm32(&w, (int)label[i].p);
1304+ jitCompPutImm32(&w, (int)label[i].p1);
1305+ jitCompPutImm32(&w, 0); /* liveSign */
1306+ jitCompPutImm32(&w, 2320); /* pls */
1307+ jitCompPutImm32(&w, 0);
1308+ jitCompPutImm32(&w, 0);
1309+ j--;
1310+ }
1311+ }
1312+ if (lastlabel >= 0 && label[lastlabel].p1 < w.dst)
1313+ label[lastlabel].p1 = w.dst;
1314+ continue;
1315+
1316+ case 0x3c: /* ENTER */
1317+ jitCompA000_storeRegCacheAll(&w); // 手抜き.
1318+ jitCompA000_storePRegCacheAll(&w); // 手抜き.
1319+ jitCompPutByte2(w.dst, 0x6a, src[6]); /* PUSH(?); */
1320+ jitCompPutByte2(w.dst, 0x6a, src[5]); /* PUSH(?); */
1321+ jitCompPutByte2(w.dst, 0x6a, src[4] & 0x0f); /* PUSH(?); */
1322+ jitCompPutByte2(w.dst, 0x6a, (src[4] >> 4) & 0x0f); /* PUSH(?); */
1323+ jitCompPutByte2(w.dst, 0x6a, src[3]); /* PUSH(?); */
1324+ jitCompPutByte2(w.dst, 0x6a, src[2]); /* PUSH(?); */
1325+ jitCompPutByte2(w.dst, 0x6a, src[1]); /* PUSH(?); */
1326+ jitCompPutByte1(w.dst, 0x55); /* PUSH(EBP); */
1327+ jitCompPutByte1(w.dst, 0xe8);
1328+ j = ((unsigned char *)&func3c) - (w.dst + 4);
1329+ jitCompPutImm32(&w, j);
1330+ jitCompPutByte3(w.dst, 0x83, 0xc4, 0x20); /* ADD(ESP,32); */
1331+ jitCompA000_loadRegCacheAll(&w); // 手抜き.
1332+ jitCompA000_loadPRegCacheAll(&w); // 手抜き.
1333+ cmp0reg = -1;
1334+ break;
1335+
1336+ case 0x3d: /* LEAVE */
1337+ jitCompA000_storeRegCacheAll(&w); // 手抜き.
1338+ jitCompA000_storePRegCacheAll(&w); // 手抜き.
1339+ jitCompPutByte2(w.dst, 0x6a, src[6]); /* PUSH(?); */
1340+ jitCompPutByte2(w.dst, 0x6a, src[5]); /* PUSH(?); */
1341+ jitCompPutByte2(w.dst, 0x6a, src[4] & 0x0f); /* PUSH(?); */
1342+ jitCompPutByte2(w.dst, 0x6a, (src[4] >> 4) & 0x0f); /* PUSH(?); */
1343+ jitCompPutByte2(w.dst, 0x6a, src[3]); /* PUSH(?); */
1344+ jitCompPutByte2(w.dst, 0x6a, src[2]); /* PUSH(?); */
1345+ jitCompPutByte2(w.dst, 0x6a, src[1]); /* PUSH(?); */
1346+ jitCompPutByte1(w.dst, 0x55); /* PUSH(EBP); */
1347+ jitCompPutByte1(w.dst, 0xe8);
1348+ j = ((unsigned char *)&func3d) - (w.dst + 4);
1349+ jitCompPutImm32(&w, j);
1350+ jitCompPutByte3(w.dst, 0x83, 0xc4, 0x20); /* ADD(ESP,32); */
1351+ jitCompA000_loadRegCacheAll(&w); // 手抜き.
1352+ jitCompA000_loadPRegCacheAll(&w); // 手抜き.
1353+ cmp0reg = -1;
1354+ break;
1355+
1356+ case 0xfe: /* remark */
1357+ if (src[1] == 0x01 && src[2] == 0x00) { // DBGINFO1
1358+ if (level <= JITC_LV_SLOWER) {
1359+ jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */
1360+ jitCompPutImm32(&w, debugInfo1);
1361+ jitCompA0001_movEbpDispReg32(&w, 2304 + 4, 0 /* EAX */); /* MOV(debugInfo1, EAX); */
1362+ }
1363+ }
1364+ if (src[1] == 0x01 && src[2] == 0x03) { // DBGINFO1CLR
1365+ if (level <= JITC_LV_SLOWER) {
1366+ jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */
1367+ jitCompPutImm32(&w, -1);
1368+ jitCompA0001_movEbpDispReg32(&w, 2304 + 4, 0 /* EAX */); /* MOV(debugInfo1, EAX); */
1369+ }
1370+ }
1371+ if (src[1] == 0x05 && src[2] == 0x00) { // DBGINFO0
1372+ if (level <= JITC_LV_SLOWEST) {
1373+ debugInfo0 = jitCompGetImm32(src + 3);
1374+ // jitCompPutByte1(w.dst, 0xbf); /* MOV(EDI, ?); */
1375+ // jitCompPutImm32(&w, debugInfo0);
1376+ jitCompPutByte1(w.dst, 0xb8); /* MOV(EAX, ?); */
1377+ jitCompPutImm32(&w, debugInfo0);
1378+ jitCompA0001_movEbpDispReg32(&w, 2304 + 0, 0 /* EAX */); /* MOV(debugInfo0, EAX); */
1379+ }
1380+ }
1381+ break;
1382+
1383+ default:
1384+ w.err = JITC_ERR_OPECODE;
1385+ goto err_w;
1386+ }
1387+ if (w.err != 0) goto err_w;
1388+ jitCompA0001_fixPrefix(&w);
1389+ if (w.err != 0) goto err_w;
1390+ src += jitCompCmdLen(src);
1391+ }
1392+ if (enter0 != NULL) {
1393+ j = w.dst - (enter0 + 4);
1394+ enter0[0] = j & 0xff;
1395+ enter0[1] = (j >> 8) & 0xff;
1396+ enter0[2] = (j >> 16) & 0xff;
1397+ enter0[3] = (j >> 24) & 0xff;
1398+ }
1399+ if ((flags & JITC_NOSTARTUP) == 0) {
1400+ jitCompA000_storeRegCacheAll(&w);
1401+ jitCompA000_storePRegCacheAll(&w);
1402+ jitCompPutByte1(w.dst, 0x61); /* POPAD(); */
1403+ }
1404+ if ((flags & JITC_PHASE1) != 0)
1405+ return w.dst - dst00;
1406+ return 0;
1407+
1408+err_w:
1409+ if ((w.err & JITC_ERR_PHASE0ONLY) != 0) {
1410+ if ((flags & JITC_PHASE1) == 0)
1411+ w.err &= ~JITC_ERR_PHASE0ONLY;
1412+ }
1413+ if (w.err == (JITC_ERR_MASK & JITC_ERR_REGNUM)) errmsg = "reg-number error";
1414+ if (w.err == (JITC_ERR_MASK & JITC_ERR_DST1)) errmsg = "dst1 error";
1415+ if (w.err == (JITC_ERR_MASK & JITC_ERR_OPECODE)) errmsg = "opecode error";
1416+ if (w.err == (JITC_ERR_MASK & JITC_ERR_LABELNUM)) errmsg = "label number too large";
1417+ if (w.err == (JITC_ERR_MASK & JITC_ERR_LABELREDEF)) errmsg = "label redefine";
1418+ if (w.err == (JITC_ERR_MASK & JITC_ERR_PREFIX)) { errmsg = "prefix redefine"; w.dst -= 2; }
1419+ if (w.err == (JITC_ERR_MASK & JITC_ERR_LABELNODEF)) errmsg = "label not defined";
1420+ if (w.err == (JITC_ERR_MASK & JITC_ERR_LABELTYP)) errmsg = "label type error";
1421+ if (w.err == (JITC_ERR_MASK & JITC_ERR_IDIOM)) errmsg = "idiom error";
1422+ if (w.err == (JITC_ERR_MASK & JITC_ERR_PREGNUM)) errmsg = "preg-number error";
1423+ if (w.err == (JITC_ERR_MASK & JITC_ERR_SRC1)) errmsg = "src1 error";
1424+ if (w.err == (JITC_ERR_MASK & JITC_ERR_BADTYPE)) errmsg = "bad type code";
1425+ if (w.err == (JITC_ERR_MASK & JITC_ERR_PREFIXFAR)) errmsg = "prefix internal error";
1426+ if (w.err == (JITC_ERR_MASK & JITC_ERR_INTERNAL)) errmsg = "general internal error";
1427+ if (*errmsg != '\0') {
1428+ fprintf(stderr, "JITC: %s at %06X (debugInfo0=%d)\n ", errmsg, src - src0, debugInfo0);
1429+ for (i = 0; i < 16; i++)
1430+ fprintf(stderr, "%02X ", src[i]);
1431+ static char *table[0x30] = {
1432+ "NOP", "LB", "LIMM", "PLIMM", "CND", "??", "??", "??",
1433+ "LMEM", "SMEM", "PLMEM", "PSMEM", "LEA", "??", "PADD", "PDIF",
1434+ "CP/OR", "XOR", "AND", "??", "ADD", "SUB", "MUL", "??",
1435+ "SHL", "SAR", "DIV", "MOD", "PLMT0", "PLMT1", "PCP", "PCST",
1436+ "CMPE", "CMPNE", "CMPL", "CMPGE", "CMPLE", "CMPG", "TSTZ", "TSTNZ",
1437+ "PCMPE", "PCMPNE", "PCMPL", "PCMPGE", "PCMPLE", "PCMPG", "??", "EXT" };
1438+ errmsg = "??";
1439+ if (*src < 0x30) errmsg = table[*src];
1440+ fprintf(stderr, "(%s)\n", errmsg);
1441+ }
1442+ return -1;
1443+}
1444+
1445+unsigned char *jitCompCallFunc(unsigned char *dst, void *func)
1446+{
1447+ struct JitCompWork w;
1448+ w.dst = dst;
1449+ jitCompA000_storeRegCacheAll(&w);
1450+ jitCompA000_storePRegCacheAll(&w);
1451+ jitCompPutByte1(w.dst, 0x60); /* PUSHAD(); */
1452+ jitCompPutByte1(w.dst, 0x50); /* PUSH(EAX); */ /* for 16byte-align(win32では不要なのだけど、MacOSには必要らしい) */
1453+ jitCompPutByte1(w.dst, 0x55); /* PUSH(EBP); */
1454+ jitCompPutByte1(w.dst, 0xe8); /* CALL(func); */
1455+ int j = ((unsigned char *)func) - (w.dst + 4);
1456+
1457+ //この関数の中では結局w->dstしか参照していない
1458+ jitCompPutImm32(&w, j);
1459+
1460+ jitCompPutByte1(w.dst, 0x58); /* POP(EAX); */ /* (win32では不要なのだけど、MacOSには必要らしい) */
1461+ jitCompPutByte1(w.dst, 0x58); /* POP(EAX); */
1462+ jitCompPutByte1(w.dst, 0x61); /* POPAD(); */
1463+ jitCompA000_loadRegCacheAll(&w);
1464+ jitCompA000_loadPRegCacheAll(&w);
1465+ jitCompA0001_movReg32EbpDisp(&w, 0 /* EAX */, 256 + 0x30 * 32 + 0); /* MOV(EAX, [EBP+?]); */
1466+ jitCompPutByte2(w.dst, 0xff, 0xe0); /* JMP(EAX); */
1467+ return w.dst;
1468+}
1469+
1470+unsigned char *jitCompInit(unsigned char *dst)
1471+{
1472+ errfnc = dst;
1473+ return jitCompCallFunc(dst, &errHndl);
1474+}
1475+
1476+void func3c(char *ebp, int opt, int r1, int p1, int lenR, int lenP, int r0, int p0)
1477+{
1478+ HOSECPU_RuntimeEnvironment *r = (HOSECPU_RuntimeEnvironment *) (ebp - jitCompA0001_EBP128);
1479+ int i, *pi;
1480+ HOSECPU_PointerRegisterEntry *pp;
1481+ if (r->junkStack + 2048 > r->junkStack1) (*(r->errHndl))(r);
1482+ pi = (void *)r->junkStack; r->junkStack += r1 * 4;
1483+ for (i = 0; i < r1; i++)
1484+ pi[i] = r->ireg[i];
1485+ pp = (void *)r->junkStack; r->junkStack += p1 * 32;
1486+ for (i = 0; i < p1; i++)
1487+ pp[i] = r->preg[i];
1488+ pp = (void *)r->junkStack; r->junkStack += 32;
1489+ *pp = r->preg[0x30];
1490+ pi = (void *)r->junkStack; r->junkStack += 4;
1491+ *pi = opt << 16 | r1 << 8 | p1;
1492+ for (i = 0; i < lenR; i++)
1493+ r->ireg[r0 + i] = r->ireg[0x30 + i];
1494+ for (i = 0; i < lenP; i++)
1495+ r->preg[p0 + i] = r->preg[0x31 + i];
1496+ return;
1497+}
1498+
1499+void func3d(char *ebp, int opt, int r1, int p1, int lenR, int lenP, int r0, int p0)
1500+{
1501+ HOSECPU_RuntimeEnvironment *r = (HOSECPU_RuntimeEnvironment *) (ebp - jitCompA0001_EBP128);
1502+ int i;
1503+ r->junkStack -= 4;
1504+ r->junkStack -= 32;
1505+ HOSECPU_PointerRegisterEntry *pp = (void *)r->junkStack;
1506+ r->preg[0x30] = *pp;
1507+ r->junkStack -= p1 * 32; pp = (void *)r->junkStack;
1508+ for (i = 0; i < p1; i++)
1509+ r->preg[i] = pp[i];
1510+ r->junkStack -= r1 * 4; int *pi = (void *)r->junkStack;
1511+ for (i = 0; i < r1; i++)
1512+ r->ireg[i] = pi[i];
1513+ return;
1514+}
1515+
1516+void funcf4(char *ebp, int pxx, int typ, int len)
1517+{
1518+ HOSECPU_RuntimeEnvironment *r = (HOSECPU_RuntimeEnvironment *) (ebp - jitCompA0001_EBP128);
1519+ int width = jitCompA000_dataWidth(jitCompA000_convTyp(r->ireg[typ])) >> 3;
1520+ if (width < 0 || r->ireg[len] < 0)
1521+ (*(r->errHndl))(r);
1522+ void *p = r->junkStack;
1523+ if (r->junkStack + width * r->ireg[len] + 256 > r->junkStack1) (*(r->errHndl))(r);
1524+ r->junkStack += width * r->ireg[len];
1525+ r->preg[pxx].p = p;
1526+ r->preg[pxx].typ = r->ireg[typ];
1527+ r->preg[pxx].p0 = p;
1528+ r->preg[pxx].p1 = (void *)r->junkStack;
1529+ int *pi = (int *)r->junkStack;
1530+ *pi = width * r->ireg[len];
1531+ r->junkStack += sizeof (int);
1532+ if (r->ireg[typ] == 1) {
1533+ int i, i1 = (width * r->ireg[len]) >> 2;
1534+ pi = p;
1535+ for (i = 0; i < i1; i++)
1536+ pi[i] = 0;
1537+ }
1538+ return;
1539+}
1540+
1541+void funcf5(char *ebp, int pxx, int typ, int len)
1542+{
1543+ // pxxはダミーで参照されない
1544+ HOSECPU_RuntimeEnvironment *r = (HOSECPU_RuntimeEnvironment *) (ebp - jitCompA0001_EBP128);
1545+ r->junkStack -= sizeof (int);
1546+ int *pi = (int *)r->junkStack;
1547+ r->junkStack -= *pi;
1548+#if 0
1549+ int width = jitCompA000_dataWidth(r->ireg[typ]);
1550+ void *p = r->junkStack;
1551+ r->junkStack -= width * r->ireg[len];
1552+#endif
1553+ return;
1554+}
1555+
1556+void funcf6(char *ebp, int pxx, int typ, int len)
1557+{
1558+ HOSECPU_RuntimeEnvironment *r = (HOSECPU_RuntimeEnvironment *) (ebp - jitCompA0001_EBP128);
1559+ int width = jitCompA000_dataWidth(jitCompA000_convTyp(r->ireg[typ])) >> 3;
1560+ if (width < 0 || r->ireg[len] < 0)
1561+ (*(r->errHndl))(r);
1562+ void *p = malloc(width * r->ireg[len]);
1563+ r->preg[pxx].p = p;
1564+ r->preg[pxx].typ = r->ireg[typ];
1565+ r->preg[pxx].p0 = p;
1566+ r->preg[pxx].p1 = (unsigned char *)p + width * r->ireg[len];
1567+ if (r->ireg[typ] == 1) {
1568+ int i, i1 = (width * r->ireg[len]) >> 2, *pi;
1569+ pi = p;
1570+ for (i = 0; i < i1; i++)
1571+ pi[i] = 0;
1572+ for (i = 1; i < i1; i += 8)
1573+ pi[i] |= -1;
1574+ }
1575+ return;
1576+}
1577+
1578+void funcf7(char *ebp, int pxx, int typ, int len)
1579+{
1580+ // typとlenはダミーで参照されない
1581+ HOSECPU_RuntimeEnvironment *r = (HOSECPU_RuntimeEnvironment *) (ebp - jitCompA0001_EBP128);
1582+ free(r->preg[pxx].p);
1583+ return;
1584+}
1585+
1586+void errHndl(HOSECPU_RuntimeEnvironment *r)
1587+{
1588+ r = (HOSECPU_RuntimeEnvironment *) (((char *)r) - jitCompA0001_EBP128);
1589+ (*(r->errHndl))(r);
1590+ // ここに帰ってきてはいけない.
1591+}
1592+
1593+/*
1594+ * jitcの出力コードをひとまとめにする関数を作成しその中身をjitCompile()で生成
1595+ *
1596+ * qq : 出力バイナリの書き込み位置のアドレスへの参照(書き込み位置を呼び出しに反映させるため参照渡しにする)
1597+ * q1 : 出力バイナリの書き込み位置のアドレスの最大値
1598+ * p0 : (*.ose)バイナリの読み込み位置のアドレス(ヘッダ部除去済)
1599+ * p1 : (*.ose)バイナリの読み込み位置の取りうる最大値
1600+ * (ただし、「確保したメモリ」の最大値なのでこれより手前にゴミデータが入っているかもしれない)
1601+ * ret=1 : ヘッダのエラー
1602+ * ret=2 : jitコンパイルエラー
1603+ */
1604+int jitc0(unsigned char **qq, unsigned char *q1, const unsigned char *p0, const unsigned char *p1, int level, HOSECPU_LabelListTag *label)
1605+{
1606+ unsigned char *q = *qq;
1607+ if (p0[0] != 0x05 || p0[1] != SIGN1) // OSECPUのヘッダ (05E1) を確認
1608+ return 1;
1609+
1610+ *q++ = 0x55; /* PUSH(EBP); */
1611+ *q++ = 0x8b; *q++ = 0x6c; *q++ = 0x24; *q++ = 0x08; /* MOV(EBP,[ESP+8]); */
1612+
1613+ int i;
1614+ for (i = 0; i < JITC_MAXLABELS; i++)
1615+ label[i].opt = 0;
1616+
1617+ // 以下のjitCompile()呼び出しでは第二引数をq1-2にした方がよいのではないか?
1618+ i = jitCompiler(q, q1, p0 + 2, p1, p0, label, JITC_MAXLABELS, level, di1_serial, 0);
1619+ if (i != 0) return 2;
1620+ i = jitCompiler(q, q1, p0 + 2, p1, p0, label, JITC_MAXLABELS, level, di1_serial, JITC_PHASE1 + 0);
1621+ if (i < 0) return 2;
1622+ q += i;
1623+
1624+ *q++ = 0x5d; /* POP(EBP); */
1625+ *q++ = 0xc3; /* RET(); */
1626+
1627+ *qq = q;
1628+ return 0;
1629+}
1630+
1631+#if (USE_DEBUGGER != 0)
1632+
1633+int dbgrGetRegNum(const char *p)
1634+{
1635+ int i, j, r = -1;
1636+ if (p[2] <= ' ') {
1637+ i = p[0] - '0';
1638+ j = p[1] - '0';
1639+ if (i > 9) i -= 'A' - '0' - 10;
1640+ if (j > 9) j -= 'A' - '0' - 10;
1641+ if (0 <= i && i <= 15 && 0 <= j && j <= 15)
1642+ r = i << 4 | j;
1643+ }
1644+ return r;
1645+}
1646+
1647+void dbgrMain(HOSECPU_RuntimeEnvironment *r)
1648+{
1649+ if (r->dbgr == 0) return;
1650+ for (;;) {
1651+ char cmd[64], *p;
1652+ int i, j, k;
1653+ printf("\ndbgr>");
1654+ p = fgets(cmd, 64, stdin);
1655+ if (p == NULL) break;
1656+ if (cmd[0] == '\0') continue;
1657+ if (cmd[0] == 'q' && cmd[1] <= ' ') break;
1658+ if (cmd[0] == 'p' && cmd[1] <= ' ' && cmd[1] != '\0') {
1659+ p = &cmd[2];
1660+ while (*p <= ' ' && *p != '\0') p++;
1661+ if (*p == 'R') {
1662+ i = dbgrGetRegNum(p + 1);
1663+ if (0 <= i && i <= 0x3f) {
1664+ printf("R%02X = 0x%08X = %d\n", i, r->ireg[i], r->ireg[i]);
1665+ }
1666+ else
1667+ puts("register name error");
1668+ continue;
1669+ }
1670+ if (*p == 'P') {
1671+ i = dbgrGetRegNum(p + 1);
1672+ if (0 <= i && i <= 0x3f) {
1673+ p = "invalid";
1674+ if (0 <= r->preg[i].typ && r->preg[i].typ <= 0x15) {
1675+ static char *typName[] = {
1676+ "T_CODE", "T_VPTR", "T_SINT8", "T_UINT8",
1677+ "T_SINT16", "T_UINT16", "T_SINT32", "T_UINT32",
1678+ "T_SINT4", "T_UINT4", "T_SINT2", "T_UINT2",
1679+ "T_SINT1", "T_UINT1", "T_SINT12", "T_UINT12",
1680+ "T_SINT20", "T_UINT20", "T_SINT24", "T_UINT24",
1681+ "T_SINT28", "T_UINT28"
1682+ };
1683+ p = typName[r->preg[i].typ];
1684+ }
1685+ printf("P%02X:\n type = %s(%04X), (origin-ptr) = 0x%08X\n", i, p, r->preg[i].typ, (unsigned int)(r->preg[i].p0));
1686+ if (r->preg[i].p != NULL && r->preg[i].p0 != NULL) {
1687+ j = jitCompA000_dataWidth(jitCompA000_convTyp(r->preg[i].typ)) >> 3;
1688+ if (j <= 0) j = 1;
1689+ k = (r->preg[i].p1 - r->preg[i].p0) / j;
1690+ printf(" size = 0x%08X = %d\n", k, k);
1691+ k = (r->preg[i].p - r->preg[i].p0) / j;
1692+ printf(" pos = 0x%08X = %d\n", k, k);
1693+ }
1694+ else {
1695+ puts(" null pointer");
1696+ }
1697+ }
1698+ else
1699+ puts("register name error");
1700+ continue;
1701+ }
1702+ }
1703+ puts("command error");
1704+ }
1705+ return;
1706+}
1707+
1708+#endif
1709+
1710+
17111711 #endif
\ No newline at end of file
--- a/main.c
+++ b/main.c
@@ -1,338 +1,338 @@
1-#include "osecpu.h"
2-
3-int *keybuf, keybuf_r, keybuf_w, keybuf_c;
4-HOSECPU_Device_Window mainWindow;
5-//デバッグ用。プログラム中の随所で加算される変数
6-int di1_serial;
7-
8-
9-
10-unsigned char *Init_LoadSysLib(char argv0[], unsigned char *tmpWorkMemory);
11-void LoadAppBin(HOSECPU_RuntimeEnvironment *env);
12-
13-void putKeybuf(int i)
14-{
15- if (keybuf_c < KEYBUFSIZ) {
16- keybuf[keybuf_w] = i;
17- keybuf_c++;
18- keybuf_w = (keybuf_w + 1) & (KEYBUFSIZ - 1);
19- }
20- return;
21-}
22-
23-int HeavyOSECPUMain(int argc, char **argv)
24-{
25- FILE *fp;
26- unsigned char *jitbuf, *sysjit00, *sysjit;
27- unsigned char *systmp0, *systmp1, *systmp2;
28- unsigned char *opTbl;
29- HOSECPU_LabelListTag *label;
30- int tmpsiz, i;
31- jmp_buf setjmpEnv;
32- double tm0, tm1, tm2;
33- HOSECPU_PointerControlTag *ptrCtrl;
34- unsigned char *syslib;
35- int argDebug = 0, stacksiz = 1;
36- const char *cp;
37- HOSECPU_RuntimeEnvironment env;
38- void(*jitfunc)(char *);
39- unsigned char *jp;
40-
41- //Initialize mainWindow
42- mainWindow.vram = NULL;
43- mainWindow.xsize = 0;
44- mainWindow.ysize = 0;
45- di1_serial = 0;
46-
47- //実行環境初期化
48- env.mainArgc = argc;
49- env.mainArgv = (const char **)argv;
50- env.appBin = malloc(APPSIZ1);
51- env.executionLevel = JITC_LV_SLOWEST;
52- jitbuf = mallocRWE(1024 * 1024); /* とりあえず1MBで */
53- //unsigned char *sysjit0 = mallocRWE(SJITSIZ1), *sysjit1 = sysjit0, *sysjit00 = sysjit0;
54- // syslib.oseのjitc結果を格納する領域を確保。
55- sysjit00 = mallocRWE(SJITSIZ1);
56- sysjit = sysjit00;
57- // 現在の、jitc結果を格納するメモリへの書き込み位置のアドレス
58- // sysjit: 現在のjitc書き込み位置
59- // sysjit00: jitc結果の先頭
60- //ワークメモリを三つくらいもらう
61- systmp0 = malloc(SYSTMP0SIZ); /* syslibのjitc用 */
62- systmp1 = malloc(SYSTMP1SIZ);
63- systmp2 = malloc(1024 * 1024);
64-
65- opTbl = malloc(256);
66- label = malloc(JITC_MAXLABELS * sizeof (HOSECPU_LabelListTag));
67- keybuf = malloc(KEYBUFSIZ * sizeof (int));
68- keybuf_r = keybuf_w = keybuf_c = 0;
69- ptrCtrl = malloc(PTRCTRLSIZ * sizeof (HOSECPU_PointerControlTag));
70-
71- randStatInit((unsigned int)time(NULL));
72- for (i = 0; i < PTRCTRLSIZ; i++) {
73- ptrCtrl[i].liveSign = 0;
74- ptrCtrl[i].size = -1;
75- }
76- ptrCtrl[0].size = -2;
77-
78- /* syslibの読み込み */
79- syslib = Init_LoadSysLib(argv[0], systmp0);
80-
81- sysjit = jitCompInit(sysjit);
82- sysjit00 = sysjit;
83- // labelはjitc0()内で初期化される。
84- i = jitc0(&sysjit, sysjit00 + SJITSIZ1, syslib + 32, syslib + SYSLIBSIZ1, JITC_LV_SLOWEST+9, label);
85- if (i != 0){
86- fputs("syslib-file JITC error.\n", stderr);
87- return 1;
88- }
89-
90- // エラー時にデバッグ用に表示する変数を加算
91- di1_serial++;
92-
93- /* アプリバイナリの読み込み */
94- LoadAppBin(&env);
95-
96- /* クロック初期化 */
97- tm0 = clock() / (double)CLOCKS_PER_SEC;
98-
99- if (env.appBin[2] == 0xf0) {
100- // tek5圧縮がかかっている
101-#if (USE_TEK5 != 0)
102- env.appSize1 = tek5Decomp(env.appBin + 2, env.appBin + env.appSize0, systmp0) + 2;
103-#else
104- env.appSize1 = -9;
105-#endif
106- if (env.appSize1 < 0) {
107- fputs("unsupported-format(tek5)\n", stderr);
108- return 1;
109- }
110- }
111- //デバッグモード指定
112- cp = searchArg(argc, (const char **)argv, "debug:", 0);
113- if (cp != NULL){
114- argDebug = *cp - '0';
115- }
116- //スタックサイズ指定(MiB単位)
117- cp = searchArg(argc, (const char **)argv, "stack:", 0);
118- if (cp != NULL){
119- stacksiz = strtol(cp, NULL, 0);
120- }
121- jp = jitbuf; /* JIT-pointer */
122-
123- /* フロントエンドコードをバックエンドコードに変換する */
124- if ((env.appBin[2] & 0xf0) != 0) {
125- systmp0[0] = env.appBin[0];
126- systmp0[1] = env.appBin[1];
127- env.preg[2].p = systmp0 + 2;
128- env.preg[3].p = systmp0 + SYSTMP0SIZ;
129- env.preg[4].p = env.appBin + 2;
130- env.preg[5].p = env.appBin + env.appSize1;
131- env.preg[6].p = systmp1;
132- env.preg[7].p = systmp1 + SYSTMP1SIZ;
133- env.preg[10].p = systmp2;
134- int pxxFlag[64], typLabel[4096];
135- env.preg[0x0b].p = (void *)pxxFlag;
136- env.preg[0x0c].p = (void *)typLabel;
137- env.preg[0x0d].p = opTbl;
138- jitfunc = (void *)sysjit00;
139- (*jitfunc)(((char *)&env) + 128); /* サイズを節約するためにEBPを128バイトずらす */
140- if (env.ireg[0] != 0) {
141- jp = env.preg[2].p - 1;
142- fprintf(stderr, "unpack error: %02X (at %06X) (R00=%d)\n", *jp, jp - systmp0, env.ireg[0]);
143- if ((argDebug & 2) != 0) {
144- fp = fopen("debug2.bin", "wb");
145- fwrite(systmp0, 1, jp - systmp0 + 16, fp);
146- fclose(fp);
147- }
148- exit(1);
149- }
150- tmpsiz = env.preg[2].p - systmp0;
151- } else{
152- memcpy(systmp0, env.appBin, env.appSize1);
153- tmpsiz = env.appSize1;
154- }
155-
156- if ((argDebug & 2) != 0) {
157- /*変換後のバックエンドコードをファイルへ保存*/
158- fp = fopen("debug2.bin", "wb");
159- fwrite(systmp0, 1, tmpsiz, fp);
160- fclose(fp);
161- }
162-
163- //JITコンパイル
164- i = jitc0(&jp, jitbuf + 1024 * 1024, systmp0, systmp0 + tmpsiz, env.executionLevel, label);
165- if (i == 1){
166- fputs("app-file header error.\n", stderr);
167- return 1;
168- }
169- if (i != 0){
170- return 1;
171- }
172- di1_serial++;
173-
174- int appsiz2 = jp - jitbuf;
175-
176- unsigned char *p28 = jp;
177- jp = jitCompCallFunc(jp, &devFunc);
178-
179- tm1 = clock() / (double)CLOCKS_PER_SEC;
180-
181- /* レジスタ初期化 */
182- for (i = 0; i < 64; i++){
183- env.ireg[i] = 0;
184- }
185- for (i = 0; i < 64; i++) {
186- env.preg[i].p = NULL;
187- env.preg[i].typ = -1;
188- env.preg[i].p0 = NULL;
189- env.preg[i].p1 = NULL;
190- }
191-
192- env.buf0 = env.buf1 = NULL;
193- env.preg[0x28].p = p28;
194- env.preg[0x28].typ = 0; // TYP_CODE
195- env.preg[0x28].p0 = p28;
196- env.preg[0x28].p1 = p28 + 1;
197- //env.preg[0x00].p = malloc(1024 * 1024) + (1024 * 1024 - 32);
198- env.junkStack = malloc(stacksiz << 20);
199- env.junkStack1 = env.junkStack + (stacksiz << 20);
200- env.winClosed = 0;
201- env.autoSleep = 0;
202- env.setjmpEnv = &setjmpEnv;
203- env.lastConsoleChar = '\n';
204-
205- env.label = label;
206- env.maxLabels = JITC_MAXLABELS;
207- env.jitbuf = jp;
208- env.jitbuf1 = jitbuf + 1024 * 1024;
209- env.errHndl = &errorHandler;
210-
211- env.dbgr = 0;
212- if (searchArg(argc, (const char **)argv, "dbgr:1", 0) != NULL){
213- env.dbgr = 1;
214- }
215-
216- if ((argDebug & 1) != 0) {
217- fp = fopen("debug1.bin", "wb");
218- fwrite(jitbuf, 1, jp - jitbuf, fp);
219- fclose(fp);
220- }
221-
222- /* JITコード実行 */
223- jitfunc = (void *)jitbuf;
224- if (setjmp(setjmpEnv) == 0){
225- (*jitfunc)(((char *)&env) + 128); /* サイズを節約するためにEBPを128バイトずらす */
226- }
227- if (env.autoSleep != 0) {
228- if (mainWindow.vram != NULL){
229- drv_flshWin(mainWindow.xsize, mainWindow.ysize, 0, 0);
230- }
231- while (env.winClosed == 0){
232- drv_sleep(100);
233- }
234- }
235- if (env.lastConsoleChar != '\n'){
236- putchar('\n');
237- }
238-
239- tm2 = clock() / (double)CLOCKS_PER_SEC;
240-
241- /* 実行結果確認のためのレジスタダンプ */
242- if (searchArg(argc, (const char **)argv, "verbose:1", 0) != NULL) {
243- printf("time: JITC=%.3f[sec], exec=%.3f[sec]\n", tm1 - tm0, tm2 - tm1);
244- printf("size: OSECPU=%d, decomp=%d, tmp=%d, native=%d\n", env.appSize0, env.appSize1, tmpsiz, appsiz2);
245- printf("result:\n");
246- printf("R00:0x%08X R01:0x%08X R02:0x%08X R03:0x%08X\n", env.ireg[0], env.ireg[1], env.ireg[2], env.ireg[3]);
247- }
248-#if (USE_DEBUGGER != 0)
249- dbgrMain(&env);
250-#endif
251- return 0;
252-}
253-
254-unsigned char *Init_LoadSysLib(char argv0[], unsigned char *tmpWorkMemory)
255-{
256- unsigned char *syslib;
257- FILE *fp;
258- unsigned char *up;
259- int appsize;
260-
261- /* syslibの読み込み */
262- syslib = malloc(SYSLIBSIZ1);
263- fp = fopen(SYSLIB_OSE, "rb");
264- if (fp == NULL) {
265- syslib[0] = '/';
266- strcpy((char *)syslib + 1, argv0);
267- up = syslib + 1;
268- while (*up != '\0'){
269- up++;
270- }
271- while (*up != '/' && *up != 0x5c){
272- up--;
273- }
274- up++;
275- strcpy((char *)up, SYSLIB_OSE);
276- fp = fopen((char *)syslib + 1, "rb");
277- }
278- if (fp == NULL) {
279- fputs("syslib-file fopen error.\n", stderr);
280- exit(EXIT_FAILURE);
281- }
282- appsize = fread(syslib, 1, SYSLIBSIZ1 - 4, fp);
283- fclose(fp);
284- if (appsize >= SYSLIBSIZ1 - 4) {
285- fputs("syslib-file too large.\n", stderr);
286- exit(EXIT_FAILURE);
287- }
288- if (syslib[0] == 0x05 && syslib[1] == 0xc1) {
289- // maklib のライブラリ形式である。
290- memcpy(tmpWorkMemory, syslib, appsize);
291- ComLib_main(tmpWorkMemory + 2, syslib + 2);
292- syslib[0] = 0x05;
293- syslib[1] = 0x1b;
294- }
295-
296- fp = fopen("syslib_dbg.ose", "wb");
297- fwrite(syslib, 1, SYSLIBSIZ1, fp);
298- fclose(fp);
299- return syslib;
300-}
301-
302-void LoadAppBin(HOSECPU_RuntimeEnvironment *env)
303-{
304- FILE *fp;
305- const char *fileName;
306- /* アプリバイナリの読み込み */
307- if (env->mainArgc <= 1) {
308- //アプリ名未指定なので何事もなく終了
309- exit(EXIT_SUCCESS);
310- }
311- fileName = env->mainArgv[1];
312- //アプリ名先頭に:n:をつけることでレベルnでの実行が可能?
313- if (fileName[0] == ':' && fileName[2] == ':') {
314- env->executionLevel = fileName[1] - '0';
315- if (env->executionLevel < 0 || env->executionLevel > 9){
316- env->executionLevel = JITC_LV_SLOWEST;
317- }
318- fileName += 3;
319- }
320-
321- fp = fopen(fileName, "rb");
322- if (fp == NULL) {
323- fputs("app-file load error.\n", stderr);
324- exit(EXIT_FAILURE);
325- }
326- env->appSize0 = fread(env->appBin, 1, APPSIZ1 - 4, fp);
327- env->appSize1 = env->appSize0;
328- fclose(fp);
329-
330- if (env->appSize0 >= APPSIZ1 - 4) {
331- fputs("app-file too large.\n", stderr);
332- exit(EXIT_FAILURE);
333- }
334- if (env->appSize0 < 3) {
335- fputs("app-file header error.\n", stderr);
336- exit(EXIT_FAILURE);
337- }
338-}
1+#include "osecpu.h"
2+
3+int *keybuf, keybuf_r, keybuf_w, keybuf_c;
4+HOSECPU_Device_Window mainWindow;
5+//デバッグ用。プログラム中の随所で加算される変数
6+int di1_serial;
7+
8+
9+
10+unsigned char *Init_LoadSysLib(char argv0[], unsigned char *tmpWorkMemory);
11+void LoadAppBin(HOSECPU_RuntimeEnvironment *env);
12+
13+void putKeybuf(int i)
14+{
15+ if (keybuf_c < KEYBUFSIZ) {
16+ keybuf[keybuf_w] = i;
17+ keybuf_c++;
18+ keybuf_w = (keybuf_w + 1) & (KEYBUFSIZ - 1);
19+ }
20+ return;
21+}
22+
23+int HeavyOSECPUMain(int argc, char **argv)
24+{
25+ FILE *fp;
26+ unsigned char *jitbuf, *sysjit00, *sysjit;
27+ unsigned char *systmp0, *systmp1, *systmp2;
28+ unsigned char *opTbl;
29+ HOSECPU_LabelListTag *label;
30+ int tmpsiz, i;
31+ jmp_buf setjmpEnv;
32+ double tm0, tm1, tm2;
33+ HOSECPU_PointerControlTag *ptrCtrl;
34+ unsigned char *syslib;
35+ int argDebug = 0, stacksiz = 1;
36+ const char *cp;
37+ HOSECPU_RuntimeEnvironment env;
38+ void(*jitfunc)(char *);
39+ unsigned char *jp;
40+
41+ //Initialize mainWindow
42+ mainWindow.vram = NULL;
43+ mainWindow.xsize = 0;
44+ mainWindow.ysize = 0;
45+ di1_serial = 0;
46+
47+ //実行環境初期化
48+ env.mainArgc = argc;
49+ env.mainArgv = (const char **)argv;
50+ env.appBin = malloc(APPSIZ1);
51+ env.executionLevel = JITC_LV_SLOWEST;
52+ jitbuf = mallocRWE(1024 * 1024); /* とりあえず1MBで */
53+ //unsigned char *sysjit0 = mallocRWE(SJITSIZ1), *sysjit1 = sysjit0, *sysjit00 = sysjit0;
54+ // syslib.oseのjitc結果を格納する領域を確保。
55+ sysjit00 = mallocRWE(SJITSIZ1);
56+ sysjit = sysjit00;
57+ // 現在の、jitc結果を格納するメモリへの書き込み位置のアドレス
58+ // sysjit: 現在のjitc書き込み位置
59+ // sysjit00: jitc結果の先頭
60+ //ワークメモリを三つくらいもらう
61+ systmp0 = malloc(SYSTMP0SIZ); /* syslibのjitc用 */
62+ systmp1 = malloc(SYSTMP1SIZ);
63+ systmp2 = malloc(1024 * 1024);
64+
65+ opTbl = malloc(256);
66+ label = malloc(JITC_MAXLABELS * sizeof (HOSECPU_LabelListTag));
67+ keybuf = malloc(KEYBUFSIZ * sizeof (int));
68+ keybuf_r = keybuf_w = keybuf_c = 0;
69+ ptrCtrl = malloc(PTRCTRLSIZ * sizeof (HOSECPU_PointerControlTag));
70+
71+ randStatInit((unsigned int)time(NULL));
72+ for (i = 0; i < PTRCTRLSIZ; i++) {
73+ ptrCtrl[i].liveSign = 0;
74+ ptrCtrl[i].size = -1;
75+ }
76+ ptrCtrl[0].size = -2;
77+
78+ /* syslibの読み込み */
79+ syslib = Init_LoadSysLib(argv[0], systmp0);
80+
81+ sysjit = jitCompInit(sysjit);
82+ sysjit00 = sysjit;
83+ // labelはjitc0()内で初期化される。
84+ i = jitc0(&sysjit, sysjit00 + SJITSIZ1, syslib + 32, syslib + SYSLIBSIZ1, JITC_LV_SLOWEST+9, label);
85+ if (i != 0){
86+ fputs("syslib-file JITC error.\n", stderr);
87+ return 1;
88+ }
89+
90+ // エラー時にデバッグ用に表示する変数を加算
91+ di1_serial++;
92+
93+ /* アプリバイナリの読み込み */
94+ LoadAppBin(&env);
95+
96+ /* クロック初期化 */
97+ tm0 = clock() / (double)CLOCKS_PER_SEC;
98+
99+ if (env.appBin[2] == 0xf0) {
100+ // tek5圧縮がかかっている
101+#if (USE_TEK5 != 0)
102+ env.appSize1 = tek5Decomp(env.appBin + 2, env.appBin + env.appSize0, systmp0) + 2;
103+#else
104+ env.appSize1 = -9;
105+#endif
106+ if (env.appSize1 < 0) {
107+ fputs("unsupported-format(tek5)\n", stderr);
108+ return 1;
109+ }
110+ }
111+ //デバッグモード指定
112+ cp = searchArg(argc, (const char **)argv, "debug:", 0);
113+ if (cp != NULL){
114+ argDebug = *cp - '0';
115+ }
116+ //スタックサイズ指定(MiB単位)
117+ cp = searchArg(argc, (const char **)argv, "stack:", 0);
118+ if (cp != NULL){
119+ stacksiz = strtol(cp, NULL, 0);
120+ }
121+ jp = jitbuf; /* JIT-pointer */
122+
123+ /* フロントエンドコードをバックエンドコードに変換する */
124+ if ((env.appBin[2] & 0xf0) != 0) {
125+ systmp0[0] = env.appBin[0];
126+ systmp0[1] = env.appBin[1];
127+ env.preg[2].p = systmp0 + 2;
128+ env.preg[3].p = systmp0 + SYSTMP0SIZ;
129+ env.preg[4].p = env.appBin + 2;
130+ env.preg[5].p = env.appBin + env.appSize1;
131+ env.preg[6].p = systmp1;
132+ env.preg[7].p = systmp1 + SYSTMP1SIZ;
133+ env.preg[10].p = systmp2;
134+ int pxxFlag[64], typLabel[4096];
135+ env.preg[0x0b].p = (void *)pxxFlag;
136+ env.preg[0x0c].p = (void *)typLabel;
137+ env.preg[0x0d].p = opTbl;
138+ jitfunc = (void *)sysjit00;
139+ (*jitfunc)(((char *)&env) + 128); /* サイズを節約するためにEBPを128バイトずらす */
140+ if (env.ireg[0] != 0) {
141+ jp = env.preg[2].p - 1;
142+ fprintf(stderr, "unpack error: %02X (at %06X) (R00=%d)\n", *jp, jp - systmp0, env.ireg[0]);
143+ if ((argDebug & 2) != 0) {
144+ fp = fopen("debug2.bin", "wb");
145+ fwrite(systmp0, 1, jp - systmp0 + 16, fp);
146+ fclose(fp);
147+ }
148+ exit(1);
149+ }
150+ tmpsiz = env.preg[2].p - systmp0;
151+ } else{
152+ memcpy(systmp0, env.appBin, env.appSize1);
153+ tmpsiz = env.appSize1;
154+ }
155+
156+ if ((argDebug & 2) != 0) {
157+ /*変換後のバックエンドコードをファイルへ保存*/
158+ fp = fopen("debug2.bin", "wb");
159+ fwrite(systmp0, 1, tmpsiz, fp);
160+ fclose(fp);
161+ }
162+
163+ //JITコンパイル
164+ i = jitc0(&jp, jitbuf + 1024 * 1024, systmp0, systmp0 + tmpsiz, env.executionLevel, label);
165+ if (i == 1){
166+ fputs("app-file header error.\n", stderr);
167+ return 1;
168+ }
169+ if (i != 0){
170+ return 1;
171+ }
172+ di1_serial++;
173+
174+ int appsiz2 = jp - jitbuf;
175+
176+ unsigned char *p28 = jp;
177+ jp = jitCompCallFunc(jp, &devFunc);
178+
179+ tm1 = clock() / (double)CLOCKS_PER_SEC;
180+
181+ /* レジスタ初期化 */
182+ for (i = 0; i < 64; i++){
183+ env.ireg[i] = 0;
184+ }
185+ for (i = 0; i < 64; i++) {
186+ env.preg[i].p = NULL;
187+ env.preg[i].typ = -1;
188+ env.preg[i].p0 = NULL;
189+ env.preg[i].p1 = NULL;
190+ }
191+
192+ env.buf0 = env.buf1 = NULL;
193+ env.preg[0x28].p = p28;
194+ env.preg[0x28].typ = 0; // TYP_CODE
195+ env.preg[0x28].p0 = p28;
196+ env.preg[0x28].p1 = p28 + 1;
197+ //env.preg[0x00].p = malloc(1024 * 1024) + (1024 * 1024 - 32);
198+ env.junkStack = malloc(stacksiz << 20);
199+ env.junkStack1 = env.junkStack + (stacksiz << 20);
200+ env.winClosed = 0;
201+ env.autoSleep = 0;
202+ env.setjmpEnv = &setjmpEnv;
203+ env.lastConsoleChar = '\n';
204+
205+ env.label = label;
206+ env.maxLabels = JITC_MAXLABELS;
207+ env.jitbuf = jp;
208+ env.jitbuf1 = jitbuf + 1024 * 1024;
209+ env.errHndl = &errorHandler;
210+
211+ env.dbgr = 0;
212+ if (searchArg(argc, (const char **)argv, "dbgr:1", 0) != NULL){
213+ env.dbgr = 1;
214+ }
215+
216+ if ((argDebug & 1) != 0) {
217+ fp = fopen("debug1.bin", "wb");
218+ fwrite(jitbuf, 1, jp - jitbuf, fp);
219+ fclose(fp);
220+ }
221+
222+ /* JITコード実行 */
223+ jitfunc = (void *)jitbuf;
224+ if (setjmp(setjmpEnv) == 0){
225+ (*jitfunc)(((char *)&env) + 128); /* サイズを節約するためにEBPを128バイトずらす */
226+ }
227+ if (env.autoSleep != 0) {
228+ if (mainWindow.vram != NULL){
229+ drv_flshWin(mainWindow.xsize, mainWindow.ysize, 0, 0);
230+ }
231+ while (env.winClosed == 0){
232+ drv_sleep(100);
233+ }
234+ }
235+ if (env.lastConsoleChar != '\n'){
236+ putchar('\n');
237+ }
238+
239+ tm2 = clock() / (double)CLOCKS_PER_SEC;
240+
241+ /* 実行結果確認のためのレジスタダンプ */
242+ if (searchArg(argc, (const char **)argv, "verbose:1", 0) != NULL) {
243+ printf("time: JITC=%.3f[sec], exec=%.3f[sec]\n", tm1 - tm0, tm2 - tm1);
244+ printf("size: OSECPU=%d, decomp=%d, tmp=%d, native=%d\n", env.appSize0, env.appSize1, tmpsiz, appsiz2);
245+ printf("result:\n");
246+ printf("R00:0x%08X R01:0x%08X R02:0x%08X R03:0x%08X\n", env.ireg[0], env.ireg[1], env.ireg[2], env.ireg[3]);
247+ }
248+#if (USE_DEBUGGER != 0)
249+ dbgrMain(&env);
250+#endif
251+ return 0;
252+}
253+
254+unsigned char *Init_LoadSysLib(char argv0[], unsigned char *tmpWorkMemory)
255+{
256+ unsigned char *syslib;
257+ FILE *fp;
258+ unsigned char *up;
259+ int appsize;
260+
261+ /* syslibの読み込み */
262+ syslib = malloc(SYSLIBSIZ1);
263+ fp = fopen(SYSLIB_OSE, "rb");
264+ if (fp == NULL) {
265+ syslib[0] = '/';
266+ strcpy((char *)syslib + 1, argv0);
267+ up = syslib + 1;
268+ while (*up != '\0'){
269+ up++;
270+ }
271+ while (*up != '/' && *up != 0x5c){
272+ up--;
273+ }
274+ up++;
275+ strcpy((char *)up, SYSLIB_OSE);
276+ fp = fopen((char *)syslib + 1, "rb");
277+ }
278+ if (fp == NULL) {
279+ fputs("syslib-file fopen error.\n", stderr);
280+ exit(EXIT_FAILURE);
281+ }
282+ appsize = fread(syslib, 1, SYSLIBSIZ1 - 4, fp);
283+ fclose(fp);
284+ if (appsize >= SYSLIBSIZ1 - 4) {
285+ fputs("syslib-file too large.\n", stderr);
286+ exit(EXIT_FAILURE);
287+ }
288+ if (syslib[0] == 0x05 && syslib[1] == 0xc1) {
289+ // maklib のライブラリ形式である。
290+ memcpy(tmpWorkMemory, syslib, appsize);
291+ ComLib_main(tmpWorkMemory + 2, syslib + 2);
292+ syslib[0] = 0x05;
293+ syslib[1] = 0x1b;
294+ }
295+
296+ fp = fopen("syslib_dbg.ose", "wb");
297+ fwrite(syslib, 1, SYSLIBSIZ1, fp);
298+ fclose(fp);
299+ return syslib;
300+}
301+
302+void LoadAppBin(HOSECPU_RuntimeEnvironment *env)
303+{
304+ FILE *fp;
305+ const char *fileName;
306+ /* アプリバイナリの読み込み */
307+ if (env->mainArgc <= 1) {
308+ //アプリ名未指定なので何事もなく終了
309+ exit(EXIT_SUCCESS);
310+ }
311+ fileName = env->mainArgv[1];
312+ //アプリ名先頭に:n:をつけることでレベルnでの実行が可能?
313+ if (fileName[0] == ':' && fileName[2] == ':') {
314+ env->executionLevel = fileName[1] - '0';
315+ if (env->executionLevel < 0 || env->executionLevel > 9){
316+ env->executionLevel = JITC_LV_SLOWEST;
317+ }
318+ fileName += 3;
319+ }
320+
321+ fp = fopen(fileName, "rb");
322+ if (fp == NULL) {
323+ fputs("app-file load error.\n", stderr);
324+ exit(EXIT_FAILURE);
325+ }
326+ env->appSize0 = fread(env->appBin, 1, APPSIZ1 - 4, fp);
327+ env->appSize1 = env->appSize0;
328+ fclose(fp);
329+
330+ if (env->appSize0 >= APPSIZ1 - 4) {
331+ fputs("app-file too large.\n", stderr);
332+ exit(EXIT_FAILURE);
333+ }
334+ if (env->appSize0 < 3) {
335+ fputs("app-file header error.\n", stderr);
336+ exit(EXIT_FAILURE);
337+ }
338+}
--- a/osecpu.h
+++ b/osecpu.h
@@ -1,224 +1,224 @@
1-#ifndef _HDLOAD_OSECPU
2-#define _HDLOAD_OSECPU 1
3-
4-/* Visual Studio で fopen()やsprintf() などの古い関数を使用する時に出る警告を抑止する*/
5-#define _CRT_SECURE_NO_WARNINGS 1
6-
7-//
8-// Including stdc headers
9-//
10-
11-#include <stdio.h>
12-#include <string.h>
13-#include <limits.h>
14-#include <time.h>
15-#include <setjmp.h>
16-#include <stdlib.h>
17-
18-
19-//
20-// Compile options
21-//
22-
23-// Target architecture
24-// 1 : i386
25-#define JITC_ARCNUM 0x0001
26-
27-// Target operating system
28-// 1 : Windows 32bit
29-// 2 : Mac OSX 32bit
30-// 3 : blike for Linux
31-#ifdef _WIN32
32-#define DRV_OSNUM 0x0001
33-#endif
34-#ifdef __APPLE__
35-#define DRV_OSNUM 0x0002
36-#endif
37-#ifdef __linux__
38-#define DRV_OSNUM 0x0003
39-#endif
40-//#define DRV_OSNUM 0x0002
41-
42-// Decoder (syslib.ose) setting
43-// syslib.ose is necessary to work OSECPU
44-#define SYSLIB_OSE "syslib.ose"
45-
46-//
47-// Define constant values
48-//
49-
50-// SIGN1: The 2nd signature of OSECPU Format(05 e1)
51-// It will be changed in OSECPU Rev.2 to "e2" (no adaptation in their binary layers)
52-#define SIGN1 0xe1
53-
54-#define USE_DEBUGGER 1
55-#define USE_TEK5 0 //元々は1
56-
57-/* JITC mode flags */
58-#define JITC_LV_SLOWEST 0 /* デバッグ支援は何でもやる */
59-#define JITC_LV_SLOWER 1 /* エラーモジュールはレポートできるが、行番号は分からない、テストは過剰 */
60-#define JITC_LV_SAFE 2 /* とにかく止まる、場所は不明、テストは必要最小限 */
61-#define JITC_LV_FASTER 4 /* 情報は生成するがチェックをしない */
62-#define JITC_LV_FASTEST 5 /* 情報すら生成しない */
63-#define JITC_PHASE1 0x0001
64-#define JITC_SKIPCHECK 0x0002 /* セキュリティチェックを省略する(高速危険モード) */
65-#define JITC_NOSTARTUP 0x0004
66-#define JITC_MAXLABELS 4096
67-#define PTRCTRLSIZ 4096
68-
69-#define APPSIZ1 1 * 1024 * 1024 /* 1MB for now */
70-#define JITSIZ1 1 * 1024 * 1024 /* 1MB for now */
71-#define SJITSIZ1 1 * 1024 * 1024 /* 1MB for now */
72-#define SYSLIBSIZ1 1 * 1024 * 1024 /* 1MB for now */
73-#define SYSTMP0SIZ 1 * 1024 * 1024 /* 1MB for now */
74-#define SYSTMP1SIZ 2 * 1024 * 1024 /* 1MB for now */
75-
76-#define KEYBUFSIZ 4096
77-
78-#define KEY_ENTER '\n'
79-#define KEY_ESC 27
80-#define KEY_BACKSPACE 8
81-#define KEY_TAB 9
82-#define KEY_PAGEUP 0x1020
83-#define KEY_PAGEDWN 0x1021
84-#define KEY_END 0x1022
85-#define KEY_HOME 0x1023
86-#define KEY_LEFT 0x1024
87-#define KEY_UP 0x1025
88-#define KEY_RIGHT 0x1026
89-#define KEY_DOWN 0x1027
90-#define KEY_INS 0x1028
91-#define KEY_DEL 0x1029
92-
93-//
94-// HOSECPU structures
95-//
96-typedef struct PtrCtrl HOSECPU_PointerControlTag;
97-struct PtrCtrl {
98- int liveSign;
99- int size, typ;
100- unsigned char *p0;
101-};
102-
103-typedef struct Ptr HOSECPU_PointerRegisterEntry;
104-struct Ptr { /* 32バイト(=256bit!) */
105- unsigned char *p;
106- int typ;
107- unsigned char *p0, *p1;
108- int liveSign;
109- HOSECPU_PointerControlTag *pls;
110- int flags, dummy; /* read/writeなど */
111-};
112-
113-typedef struct LabelTable HOSECPU_LabelListTag;
114-struct LabelTable {
115- unsigned char *p, *p1;
116- int opt;
117- /*
118- * default = -1
119- * TYP_CODE = 0
120- * T_UINT8 = 3
121- *
122- * 将来的には UInt8, SInt32, Flt64, UInt8, VPtr が使えるようになる http://osecpu.osask.jp/wiki/?page0053
123- */
124- int typ;
125-};
126-
127-typedef struct Device_Window HOSECPU_Device_Window;
128-struct Device_Window {
129- int *vram;
130- int xsize, ysize;
131-};
132-
133-typedef struct Regs HOSECPU_RuntimeEnvironment;
134-struct Regs {
135- int ireg[64]; /* 32bit整数レジスタ */
136- HOSECPU_PointerRegisterEntry preg[64]; /* ポインタレジスタ */
137- //
138- int debugInfo0, debugInfo1, dmy[2]; /* 2304 */
139- HOSECPU_PointerControlTag *ptrCtrl; /* 2320 */
140- char winClosed, autoSleep;
141- jmp_buf *setjmpEnv;
142-
143- /* Main environment */
144- int mainArgc; // HOSECPU起動引数の個数
145- const char **mainArgv; // HOSECPU起動引数リスト
146- unsigned char *appBin; // 実行するアプリのバイナリ
147- int appSize0;
148- int appSize1;
149- int executionLevel;
150-
151- /* for-junkApi */
152- unsigned char *buf0, *buf1, *junkStack, lastConsoleChar, *junkStack1;
153-
154- HOSECPU_LabelListTag *label;
155- int maxLabels;
156- unsigned char *jitbuf, *jitbuf1;
157- void(*errHndl)(HOSECPU_RuntimeEnvironment *);
158- char dbgr;
159- int mapDi1s[16][16];
160-};
161-
162-//
163-// Grobal values
164-//
165-
166-extern int *keybuf, keybuf_r, keybuf_w, keybuf_c;
167-extern HOSECPU_Device_Window mainWindow;
168-// di1_serial: デバッグ用。プログラム中の随所で加算される変数
169-extern int di1_serial;
170-
171-//
172-// Functions
173-//
174-
175-// @main.c
176-void putKeybuf(int i);
177-int HeavyOSECPUMain(int argc, char **argv);
178-
179-// @comlib.c
180-unsigned char *ComLib_main(const unsigned char *p, unsigned char *q);
181-// @dpndenv.c
182-// OSに依存する関数群を定義する。
183-void *mallocRWE(int bytes); // 実行権付きメモリのmalloc.
184-void drv_openWin(int x, int y, unsigned char *buf, char *winClosed);
185-void drv_flshWin(int sx, int sy, int x0, int y0);
186-void drv_sleep(int msec);
187-
188-// @function.c
189-void dbgrMain(HOSECPU_RuntimeEnvironment *r);
190-const char *searchArg(int argc, const char **argv, const char *tag, int i); // コマンドライン引数処理.
191-void devFunc(HOSECPU_RuntimeEnvironment *r); // junkApiを処理する関数
192-
193-// @jitc.c
194-int jitc0(unsigned char **qq, unsigned char *q1, const unsigned char *p0, const unsigned char *p1, int level, HOSECPU_LabelListTag *label);
195-int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *src, const unsigned char *src1, const unsigned char *src0, HOSECPU_LabelListTag *label, int maxLabels, int level, int debugInfo1, int flags);
196-unsigned char *jitCompCallFunc(unsigned char *dst, void *func);
197-unsigned char *jitCompInit(unsigned char *dst);
198-void errorHandler(HOSECPU_RuntimeEnvironment *r);
199-
200-// @randmt.c
201-void randStatInit(unsigned int seed);
202-void randStatNext();
203-unsigned int randGetNextUInt32(void);
204-
205-// @screen.c
206-static int iColor1[] = {
207- 0x000000, 0xff0000, 0x00ff00, 0xffff00,
208- 0x0000ff, 0xff00ff, 0x00ffff, 0xffffff
209-};
210-void putOsaskChar(int c, HOSECPU_RuntimeEnvironment *r);
211-void checkString(HOSECPU_RuntimeEnvironment *r, int rxx, int pxx);
212-void checkRect(HOSECPU_RuntimeEnvironment *r, int rxx);
213-int loadColor(HOSECPU_RuntimeEnvironment *r, int rxx);
214-
215-#if (USE_TEK5 != 0)
216-/* tek.cを移植するのは大変だと思ったので、断念 */
217-#error "tek is not supported. edit switch.h and set USE_TEK5=0"
218-// #include "tek.c"
219-// int tek5Decomp(unsigned char *buf, unsigned char *buf1, unsigned char *tmp);
220-#endif
221-
222-
223-#endif
224-
1+#ifndef _HDLOAD_OSECPU
2+#define _HDLOAD_OSECPU 1
3+
4+/* Visual Studio で fopen()やsprintf() などの古い関数を使用する時に出る警告を抑止する*/
5+#define _CRT_SECURE_NO_WARNINGS 1
6+
7+//
8+// Including stdc headers
9+//
10+
11+#include <stdio.h>
12+#include <string.h>
13+#include <limits.h>
14+#include <time.h>
15+#include <setjmp.h>
16+#include <stdlib.h>
17+
18+
19+//
20+// Compile options
21+//
22+
23+// Target architecture
24+// 1 : i386
25+#define JITC_ARCNUM 0x0001
26+
27+// Target operating system
28+// 1 : Windows 32bit
29+// 2 : Mac OSX 32bit
30+// 3 : blike for Linux
31+#ifdef _WIN32
32+#define DRV_OSNUM 0x0001
33+#endif
34+#ifdef __APPLE__
35+#define DRV_OSNUM 0x0002
36+#endif
37+#ifdef __linux__
38+#define DRV_OSNUM 0x0003
39+#endif
40+//#define DRV_OSNUM 0x0002
41+
42+// Decoder (syslib.ose) setting
43+// syslib.ose is necessary to work OSECPU
44+#define SYSLIB_OSE "syslib.ose"
45+
46+//
47+// Define constant values
48+//
49+
50+// SIGN1: The 2nd signature of OSECPU Format(05 e1)
51+// It will be changed in OSECPU Rev.2 to "e2" (no adaptation in their binary layers)
52+#define SIGN1 0xe1
53+
54+#define USE_DEBUGGER 1
55+#define USE_TEK5 0 //元々は1
56+
57+/* JITC mode flags */
58+#define JITC_LV_SLOWEST 0 /* デバッグ支援は何でもやる */
59+#define JITC_LV_SLOWER 1 /* エラーモジュールはレポートできるが、行番号は分からない、テストは過剰 */
60+#define JITC_LV_SAFE 2 /* とにかく止まる、場所は不明、テストは必要最小限 */
61+#define JITC_LV_FASTER 4 /* 情報は生成するがチェックをしない */
62+#define JITC_LV_FASTEST 5 /* 情報すら生成しない */
63+#define JITC_PHASE1 0x0001
64+#define JITC_SKIPCHECK 0x0002 /* セキュリティチェックを省略する(高速危険モード) */
65+#define JITC_NOSTARTUP 0x0004
66+#define JITC_MAXLABELS 4096
67+#define PTRCTRLSIZ 4096
68+
69+#define APPSIZ1 1 * 1024 * 1024 /* 1MB for now */
70+#define JITSIZ1 1 * 1024 * 1024 /* 1MB for now */
71+#define SJITSIZ1 1 * 1024 * 1024 /* 1MB for now */
72+#define SYSLIBSIZ1 1 * 1024 * 1024 /* 1MB for now */
73+#define SYSTMP0SIZ 1 * 1024 * 1024 /* 1MB for now */
74+#define SYSTMP1SIZ 2 * 1024 * 1024 /* 1MB for now */
75+
76+#define KEYBUFSIZ 4096
77+
78+#define KEY_ENTER '\n'
79+#define KEY_ESC 27
80+#define KEY_BACKSPACE 8
81+#define KEY_TAB 9
82+#define KEY_PAGEUP 0x1020
83+#define KEY_PAGEDWN 0x1021
84+#define KEY_END 0x1022
85+#define KEY_HOME 0x1023
86+#define KEY_LEFT 0x1024
87+#define KEY_UP 0x1025
88+#define KEY_RIGHT 0x1026
89+#define KEY_DOWN 0x1027
90+#define KEY_INS 0x1028
91+#define KEY_DEL 0x1029
92+
93+//
94+// HOSECPU structures
95+//
96+typedef struct PtrCtrl HOSECPU_PointerControlTag;
97+struct PtrCtrl {
98+ int liveSign;
99+ int size, typ;
100+ unsigned char *p0;
101+};
102+
103+typedef struct Ptr HOSECPU_PointerRegisterEntry;
104+struct Ptr { /* 32バイト(=256bit!) */
105+ unsigned char *p;
106+ int typ;
107+ unsigned char *p0, *p1;
108+ int liveSign;
109+ HOSECPU_PointerControlTag *pls;
110+ int flags, dummy; /* read/writeなど */
111+};
112+
113+typedef struct LabelTable HOSECPU_LabelListTag;
114+struct LabelTable {
115+ unsigned char *p, *p1;
116+ int opt;
117+ /*
118+ * default = -1
119+ * TYP_CODE = 0
120+ * T_UINT8 = 3
121+ *
122+ * 将来的には UInt8, SInt32, Flt64, UInt8, VPtr が使えるようになる http://osecpu.osask.jp/wiki/?page0053
123+ */
124+ int typ;
125+};
126+
127+typedef struct Device_Window HOSECPU_Device_Window;
128+struct Device_Window {
129+ int *vram;
130+ int xsize, ysize;
131+};
132+
133+typedef struct Regs HOSECPU_RuntimeEnvironment;
134+struct Regs {
135+ int ireg[64]; /* 32bit整数レジスタ */
136+ HOSECPU_PointerRegisterEntry preg[64]; /* ポインタレジスタ */
137+ //
138+ int debugInfo0, debugInfo1, dmy[2]; /* 2304 */
139+ HOSECPU_PointerControlTag *ptrCtrl; /* 2320 */
140+ char winClosed, autoSleep;
141+ jmp_buf *setjmpEnv;
142+
143+ /* Main environment */
144+ int mainArgc; // HOSECPU起動引数の個数
145+ const char **mainArgv; // HOSECPU起動引数リスト
146+ unsigned char *appBin; // 実行するアプリのバイナリ
147+ int appSize0;
148+ int appSize1;
149+ int executionLevel;
150+
151+ /* for-junkApi */
152+ unsigned char *buf0, *buf1, *junkStack, lastConsoleChar, *junkStack1;
153+
154+ HOSECPU_LabelListTag *label;
155+ int maxLabels;
156+ unsigned char *jitbuf, *jitbuf1;
157+ void(*errHndl)(HOSECPU_RuntimeEnvironment *);
158+ char dbgr;
159+ int mapDi1s[16][16];
160+};
161+
162+//
163+// Grobal values
164+//
165+
166+extern int *keybuf, keybuf_r, keybuf_w, keybuf_c;
167+extern HOSECPU_Device_Window mainWindow;
168+// di1_serial: デバッグ用。プログラム中の随所で加算される変数
169+extern int di1_serial;
170+
171+//
172+// Functions
173+//
174+
175+// @main.c
176+void putKeybuf(int i);
177+int HeavyOSECPUMain(int argc, char **argv);
178+
179+// @comlib.c
180+unsigned char *ComLib_main(const unsigned char *p, unsigned char *q);
181+// @dpndenv.c
182+// OSに依存する関数群を定義する。
183+void *mallocRWE(int bytes); // 実行権付きメモリのmalloc.
184+void drv_openWin(int x, int y, unsigned char *buf, char *winClosed);
185+void drv_flshWin(int sx, int sy, int x0, int y0);
186+void drv_sleep(int msec);
187+
188+// @function.c
189+void dbgrMain(HOSECPU_RuntimeEnvironment *r);
190+const char *searchArg(int argc, const char **argv, const char *tag, int i); // コマンドライン引数処理.
191+void devFunc(HOSECPU_RuntimeEnvironment *r); // junkApiを処理する関数
192+
193+// @jitc.c
194+int jitc0(unsigned char **qq, unsigned char *q1, const unsigned char *p0, const unsigned char *p1, int level, HOSECPU_LabelListTag *label);
195+int jitCompiler(unsigned char *dst, unsigned char *dst1, const unsigned char *src, const unsigned char *src1, const unsigned char *src0, HOSECPU_LabelListTag *label, int maxLabels, int level, int debugInfo1, int flags);
196+unsigned char *jitCompCallFunc(unsigned char *dst, void *func);
197+unsigned char *jitCompInit(unsigned char *dst);
198+void errorHandler(HOSECPU_RuntimeEnvironment *r);
199+
200+// @randmt.c
201+void randStatInit(unsigned int seed);
202+void randStatNext();
203+unsigned int randGetNextUInt32(void);
204+
205+// @screen.c
206+static int iColor1[] = {
207+ 0x000000, 0xff0000, 0x00ff00, 0xffff00,
208+ 0x0000ff, 0xff00ff, 0x00ffff, 0xffffff
209+};
210+void putOsaskChar(int c, HOSECPU_RuntimeEnvironment *r);
211+void checkString(HOSECPU_RuntimeEnvironment *r, int rxx, int pxx);
212+void checkRect(HOSECPU_RuntimeEnvironment *r, int rxx);
213+int loadColor(HOSECPU_RuntimeEnvironment *r, int rxx);
214+
215+#if (USE_TEK5 != 0)
216+/* tek.cを移植するのは大変だと思ったので、断念 */
217+#error "tek is not supported. edit switch.h and set USE_TEK5=0"
218+// #include "tek.c"
219+// int tek5Decomp(unsigned char *buf, unsigned char *buf1, unsigned char *tmp);
220+#endif
221+
222+
223+#endif
224+
--- a/randmt.c
+++ b/randmt.c
@@ -1,46 +1,46 @@
1-
2-#include "osecpu.h"
3-
4-static struct {
5- unsigned stat[4], mat1, mat2, tmat;
6-} randStat;
7-
8-// tinyMTの32bit版のアルゴリズムを使っています : http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/TINYMT/index-jp.html
9-void randStatNext()
10-{
11- unsigned x, y;
12- x = (randStat.stat[0] & 0x7fffffff) ^ randStat.stat[1] ^ randStat.stat[2];
13- y = randStat.stat[3];
14- x ^= x << 1;
15- y ^= (y >> 1) ^ x;
16- randStat.stat[1] = randStat.stat[2] ^ (-((int)(y & 1)) & randStat.mat1);
17- randStat.stat[2] = x ^ (y << 10) ^ (-((int)(y & 1)) & randStat.mat2);
18- randStat.stat[3] = y;
19- return;
20-}
21-
22-void randStatInit(unsigned seed)
23-{
24- int i;
25- randStat.stat[0] = seed;
26- randStat.stat[1] = randStat.mat1 = 0x8f7011ee;
27- randStat.stat[2] = randStat.mat2 = 0xfc78ff1f;
28- randStat.stat[3] = randStat.tmat = 0x3793fdff;
29- for (i = 1; i < 8; i++){
30- randStat.stat[i & 3] ^= i + ((unsigned)1812433253) * (randStat.stat[(i - 1) & 3] ^ (randStat.stat[(i - 1) & 3] >> 30));
31- }
32- for (i = 0; i < 8; i++){
33- randStatNext();
34- }
35- return;
36-}
37-
38-unsigned int randGetNextUInt32(void)
39-{
40- //次の乱数を取得する。
41- unsigned int u32t;
42-
43- randStatNext();
44- u32t = randStat.stat[0] + (randStat.stat[2] >> 8);
45- return (randStat.stat[3] ^ u32t ^ (-((int)(u32t & 1)) & randStat.tmat));
46-}
1+
2+#include "osecpu.h"
3+
4+static struct {
5+ unsigned stat[4], mat1, mat2, tmat;
6+} randStat;
7+
8+// tinyMTの32bit版のアルゴリズムを使っています : http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/TINYMT/index-jp.html
9+void randStatNext()
10+{
11+ unsigned x, y;
12+ x = (randStat.stat[0] & 0x7fffffff) ^ randStat.stat[1] ^ randStat.stat[2];
13+ y = randStat.stat[3];
14+ x ^= x << 1;
15+ y ^= (y >> 1) ^ x;
16+ randStat.stat[1] = randStat.stat[2] ^ (-((int)(y & 1)) & randStat.mat1);
17+ randStat.stat[2] = x ^ (y << 10) ^ (-((int)(y & 1)) & randStat.mat2);
18+ randStat.stat[3] = y;
19+ return;
20+}
21+
22+void randStatInit(unsigned seed)
23+{
24+ int i;
25+ randStat.stat[0] = seed;
26+ randStat.stat[1] = randStat.mat1 = 0x8f7011ee;
27+ randStat.stat[2] = randStat.mat2 = 0xfc78ff1f;
28+ randStat.stat[3] = randStat.tmat = 0x3793fdff;
29+ for (i = 1; i < 8; i++){
30+ randStat.stat[i & 3] ^= i + ((unsigned)1812433253) * (randStat.stat[(i - 1) & 3] ^ (randStat.stat[(i - 1) & 3] >> 30));
31+ }
32+ for (i = 0; i < 8; i++){
33+ randStatNext();
34+ }
35+ return;
36+}
37+
38+unsigned int randGetNextUInt32(void)
39+{
40+ //次の乱数を取得する。
41+ unsigned int u32t;
42+
43+ randStatNext();
44+ u32t = randStat.stat[0] + (randStat.stat[2] >> 8);
45+ return (randStat.stat[3] ^ u32t ^ (-((int)(u32t & 1)) & randStat.tmat));
46+}
--- a/readme.txt
+++ b/readme.txt
@@ -1,19 +1,19 @@
1-HeavyOSECPU
2-
3-OSECPUを学習する人向けにソースコードを幾つかのファイルに分割し、多少は読みやすくなったかもしれない非公式OSECPUソースコードのパッケージ。ソースコードの内容はほとんど本家のOSECPUと同じです。
4-今のところまともに動作しないので実用目的で使用することはできません。
5-名前の由来: 本家よりもファイルサイズが「重く」なることから。
6-
7-プロジェクトページ
8-https://sourceforge.jp/projects/heavyosecpu/
9-
10-OSECPUの概要
11-http://osecpu.osask.jp/wiki/
12-
13-
14-■ Visual Studioでの開き方
15-
16-Visual Studio を起動し、ファイル->新規作成->既存のコードからプロジェクトを作成
17-を選択して、このディレクトリを指定しプロジェクトを生成してください。
18-
19-ビルドした後、実行するためには、実行ファイルの存在するディレクトリにsyslib.oseをコピーする必要があります。Visual Studioによって作成されたDebugディレクトリに同梱のsyslib.oseをコピーしてください。
1+HeavyOSECPU
2+
3+OSECPUを学習する人向けにソースコードを幾つかのファイルに分割し、多少は読みやすくなったかもしれない非公式OSECPUソースコードのパッケージ。ソースコードの内容はほとんど本家のOSECPUと同じです。
4+今のところまともに動作しないので実用目的で使用することはできません。
5+名前の由来: 本家よりもファイルサイズが「重く」なることから。
6+
7+プロジェクトページ
8+https://sourceforge.jp/projects/heavyosecpu/
9+
10+OSECPUの概要
11+http://osecpu.osask.jp/wiki/
12+
13+
14+■ Visual Studioでの開き方
15+
16+Visual Studio を起動し、ファイル->新規作成->既存のコードからプロジェクトを作成
17+を選択して、このディレクトリを指定しプロジェクトを生成してください。
18+
19+ビルドした後、実行するためには、実行ファイルの存在するディレクトリにsyslib.oseをコピーする必要があります。Visual Studioによって作成されたDebugディレクトリに同梱のsyslib.oseをコピーしてください。
--- a/screen.c
+++ b/screen.c
@@ -1,105 +1,105 @@
1-#include "osecpu.h"
2-
3-void putOsaskChar(int c, HOSECPU_RuntimeEnvironment *r)
4-{
5- if (0x10 <= c && c <= 0x1f){
6- c = "0123456789ABCDEF"[c & 0x0f];
7- }
8- putchar(c);
9- r->lastConsoleChar = c;
10- return;
11-}
12-
13-void checkString(HOSECPU_RuntimeEnvironment *r, int rxx, int pxx)
14-{
15- char c = 0;
16- if (r->preg[pxx].typ != 0x03){
17- c = 1;
18- }
19- if (r->preg[pxx].p < r->preg[pxx].p0){
20- c = 1;
21- }
22- if (r->ireg[rxx] < 0){
23- c = 1;
24- }
25- if (r->preg[pxx].p + r->ireg[rxx] > r->preg[pxx].p1){
26- c = 1;
27- }
28- if (c != 0){
29- (*(r->errHndl))(r);
30- }
31- return;
32-}
33-
34-int loadColor(HOSECPU_RuntimeEnvironment *r, int rxx)
35-{
36- int c, m, rr, gg, bb;
37- c = r->ireg[rxx];
38- m = r->ireg[0x31] & 0x0c;
39- if (m == 0x04) {
40- if (c < -1 || c > 7){
41- (*(r->errHndl))(r);
42- }
43- c = iColor1[c & 0x07];
44- }
45- if (m == 0x08) {
46- // 00, 24, 48, 6d, 91, b6, da, ff
47- if (c < 0 || c >= (1 << 9)){
48- (*(r->errHndl))(r);
49- }
50- rr = (c >> 6) & 0x07;
51- gg = (c >> 3) & 0x07;
52- bb = c & 0x07;
53- rr = (rr * 255) / 7;
54- gg = (gg * 255) / 7;
55- bb = (bb * 255) / 7;
56- c = rr << 16 | gg << 8 | bb;
57- }
58- if (m == 0x0c) {
59- // 00, 08, 10, 18, 20, 29, 31, 39,
60- // 41, 4a, 52, 5a, 62, 6a, 73, 7b,
61- // 83, 8b, 94, 9c, a4, ac, b4, bd,
62- // c5, cd, d5, de, e6, ee, f6, ff
63- if (c < 0 || c >= (1 << 15)){
64- (*(r->errHndl))(r);
65- }
66- rr = (c >> 10) & 0x1f;
67- gg = (c >> 5) & 0x1f;
68- bb = c & 0x1f;
69- rr = (rr * 255) / 31;
70- gg = (gg * 255) / 31;
71- bb = (bb * 255) / 31;
72- c = rr << 16 | gg << 8 | bb;
73- }
74- return c;
75-}
76-
77-void checkRect(HOSECPU_RuntimeEnvironment *r, int rxx)
78-{
79- char c = 0;
80- int i;
81- if (r->ireg[rxx + 0] <= 0 || r->ireg[rxx + 0] > mainWindow.xsize){
82- c = 1;
83- }
84- if (r->ireg[rxx + 1] <= 0 || r->ireg[rxx + 1] > mainWindow.ysize){
85- c = 1;
86- }
87- if (r->ireg[rxx + 2] < 0 || r->ireg[rxx + 2] >= mainWindow.xsize){
88- c = 1;
89- }
90- if (r->ireg[rxx + 3] < 0 || r->ireg[rxx + 3] >= mainWindow.ysize){
91- c = 1;
92- }
93- i = r->ireg[rxx + 2] + r->ireg[rxx + 0];
94- if (i <= 0 || i > mainWindow.xsize){
95- c = 1;
96- }
97- i = r->ireg[rxx + 1] + r->ireg[rxx + 3];
98- if (i <= 0 || i > mainWindow.ysize){
99- c = 1;
100- }
101- if (c != 0){
102- (*(r->errHndl))(r);
103- }
104- return;
1+#include "osecpu.h"
2+
3+void putOsaskChar(int c, HOSECPU_RuntimeEnvironment *r)
4+{
5+ if (0x10 <= c && c <= 0x1f){
6+ c = "0123456789ABCDEF"[c & 0x0f];
7+ }
8+ putchar(c);
9+ r->lastConsoleChar = c;
10+ return;
11+}
12+
13+void checkString(HOSECPU_RuntimeEnvironment *r, int rxx, int pxx)
14+{
15+ char c = 0;
16+ if (r->preg[pxx].typ != 0x03){
17+ c = 1;
18+ }
19+ if (r->preg[pxx].p < r->preg[pxx].p0){
20+ c = 1;
21+ }
22+ if (r->ireg[rxx] < 0){
23+ c = 1;
24+ }
25+ if (r->preg[pxx].p + r->ireg[rxx] > r->preg[pxx].p1){
26+ c = 1;
27+ }
28+ if (c != 0){
29+ (*(r->errHndl))(r);
30+ }
31+ return;
32+}
33+
34+int loadColor(HOSECPU_RuntimeEnvironment *r, int rxx)
35+{
36+ int c, m, rr, gg, bb;
37+ c = r->ireg[rxx];
38+ m = r->ireg[0x31] & 0x0c;
39+ if (m == 0x04) {
40+ if (c < -1 || c > 7){
41+ (*(r->errHndl))(r);
42+ }
43+ c = iColor1[c & 0x07];
44+ }
45+ if (m == 0x08) {
46+ // 00, 24, 48, 6d, 91, b6, da, ff
47+ if (c < 0 || c >= (1 << 9)){
48+ (*(r->errHndl))(r);
49+ }
50+ rr = (c >> 6) & 0x07;
51+ gg = (c >> 3) & 0x07;
52+ bb = c & 0x07;
53+ rr = (rr * 255) / 7;
54+ gg = (gg * 255) / 7;
55+ bb = (bb * 255) / 7;
56+ c = rr << 16 | gg << 8 | bb;
57+ }
58+ if (m == 0x0c) {
59+ // 00, 08, 10, 18, 20, 29, 31, 39,
60+ // 41, 4a, 52, 5a, 62, 6a, 73, 7b,
61+ // 83, 8b, 94, 9c, a4, ac, b4, bd,
62+ // c5, cd, d5, de, e6, ee, f6, ff
63+ if (c < 0 || c >= (1 << 15)){
64+ (*(r->errHndl))(r);
65+ }
66+ rr = (c >> 10) & 0x1f;
67+ gg = (c >> 5) & 0x1f;
68+ bb = c & 0x1f;
69+ rr = (rr * 255) / 31;
70+ gg = (gg * 255) / 31;
71+ bb = (bb * 255) / 31;
72+ c = rr << 16 | gg << 8 | bb;
73+ }
74+ return c;
75+}
76+
77+void checkRect(HOSECPU_RuntimeEnvironment *r, int rxx)
78+{
79+ char c = 0;
80+ int i;
81+ if (r->ireg[rxx + 0] <= 0 || r->ireg[rxx + 0] > mainWindow.xsize){
82+ c = 1;
83+ }
84+ if (r->ireg[rxx + 1] <= 0 || r->ireg[rxx + 1] > mainWindow.ysize){
85+ c = 1;
86+ }
87+ if (r->ireg[rxx + 2] < 0 || r->ireg[rxx + 2] >= mainWindow.xsize){
88+ c = 1;
89+ }
90+ if (r->ireg[rxx + 3] < 0 || r->ireg[rxx + 3] >= mainWindow.ysize){
91+ c = 1;
92+ }
93+ i = r->ireg[rxx + 2] + r->ireg[rxx + 0];
94+ if (i <= 0 || i > mainWindow.xsize){
95+ c = 1;
96+ }
97+ i = r->ireg[rxx + 1] + r->ireg[rxx + 3];
98+ if (i <= 0 || i > mainWindow.ysize){
99+ c = 1;
100+ }
101+ if (c != 0){
102+ (*(r->errHndl))(r);
103+ }
104+ return;
105105 }
\ No newline at end of file
Show on old repository browser