OSDN Git Service

MacOSXでのキーボード入力対応!
authorhikarupsp <hikarupsp@users.sourceforge.jp>
Thu, 20 Mar 2014 08:44:57 +0000 (17:44 +0900)
committerhikarupsp <hikarupsp@users.sourceforge.jp>
Thu, 20 Mar 2014 08:44:57 +0000 (17:44 +0900)
修飾キーは未実装。
キーボード関連の定数化。

dpndenv.c
function.c
main.c
osecpu.h

index 855795d..9ad5cbd 100644 (file)
--- a/dpndenv.c
+++ b/dpndenv.c
-#include "osecpu.h"
-
-
-#if (DRV_OSNUM == 0x0002)
-//
-// for Mac OSX 32-bit
-//
-#include <mach/mach.h>
-#include <Cocoa/Cocoa.h>
-
-void *mallocRWE(int bytes)
-{
-       void *p = malloc(bytes);
-       vm_protect(mach_task_self(), (vm_address_t) p, bytes, FALSE, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE);
-       return p;
-}
-
-NSApplication* app;
-
-@interface OSECPUView : NSView
-{
-       unsigned char *_buf;
-       int _sx;
-       int _sy;
-       CGContextRef _context;
-}
-
-- (id)initWithFrame:(NSRect)frameRect buf:(unsigned char *)buf sx:(int)sx sy:(int)sy;
-- (void)drawRect:(NSRect)rect;
-@end
-
-@implementation OSECPUView
-- (id)initWithFrame:(NSRect)frameRect buf:(unsigned char *)buf sx:(int)sx sy:(int)sy
-{
-       self = [super initWithFrame:frameRect];
-       if (self) {
-               _buf = buf;
-               _sx = sx;
-               _sy = sy;
-       }
-       return self;
-}
-
-- (void)drawRect:(NSRect)rect {
-       CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
-       _context = CGBitmapContextCreate (_buf, _sx, _sy, 8, 4 * _sx, colorSpace, (kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst));
-       CGImageRef image = CGBitmapContextCreateImage(_context);
-       CGContextRef currentContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
-       CGContextDrawImage(currentContext, NSRectToCGRect(rect), image);
-       CFRelease(colorSpace);
-       CFRelease(image);
-}
-
-- (void)keyDown:(NSEvent *)theEvent
-{
-
-}
-
-- (void)keyUp:(NSEvent *)theEvent
-{
-
-}
-
-@end
-
-@interface Main : NSObject<NSWindowDelegate>
-{
-       int argc;
-       const unsigned char **argv;
-       char *winClosed;
-       OSECPUView *_view;
-}
-
-- (void)runApp;
-- (void)createThread:(int)_argc args:(const unsigned char **)_argv;
-- (BOOL)windowShouldClose:(id)sender;
-- (void)openWin:(unsigned char *)buf sx:(int)sx sy:(int)sy winClosed:(char *)_winClosed;
-- (void)flushWin:(NSRect)rect;
-@end
-
-@implementation Main
-- (void)runApp
-{
-       NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
-       int retv;
-       retv = HeavyOSECPUMain(argc, (char **)argv);
-       [NSApp terminate:self];
-       [pool release];
-       exit(retv);
-}
-
-- (void)createThread : (int)_argc args:(const unsigned char **)_argv
-{
-       argc = _argc;
-       argv = _argv;
-       NSThread *thread = [[[NSThread alloc] initWithTarget:self selector:@selector(runApp) object:nil] autorelease];
-       [thread start];
-}
-
-- (BOOL)windowShouldClose:(id)sender
-{
-       *winClosed = 1;
-       return YES;
-}
-
-- (void)openWin:(unsigned char *)buf sx:(int)sx sy:(int) sy winClosed:(char *)_winClosed
-{
-       
-       NSWindow* window = [[NSWindow alloc] initWithContentRect: NSMakeRect(0, 0, sx, sy) styleMask: NSTitledWindowMask | NSMiniaturizableWindowMask | NSClosableWindowMask backing: NSBackingStoreBuffered defer: NO];
-       [window setTitle: @"osecpu"];
-       [window center];
-       [window makeKeyAndOrderFront:nil];
-       [window setReleasedWhenClosed:YES];
-       window.delegate = self;
-       winClosed = _winClosed;
-       
-       _view = [[OSECPUView alloc] initWithFrame:NSMakeRect(0,0,sx,sy) buf:buf sx:sx sy:sy];
-       [window.contentView addSubview:_view];
-}
-
-- (void)flushWin : (NSRect)rect
-{
-       [_view setNeedsDisplayInRect:rect];
-}
-
-@end
-
-id objc_main;
-
-int main(int argc, char **argv)
-{
-       objc_main = [[Main alloc] init];
-       
-       NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
-       app = [[NSApplication alloc] init];
-       [objc_main createThread:argc args:(const unsigned char **)argv];
-       [app run];
-       [pool release];
-       return 0;
-}
-
-void drv_openWin(int sx, int sy, unsigned char *buf, char *winClosed)
-{
-       [objc_main openWin:buf sx:sx sy:sy winClosed:winClosed];
-}
-
-void drv_flshWin(int sx, int sy, int x0, int y0)
-{
-       [objc_main flushWin:NSMakeRect(x0,y0,sx,sy)];
-}
-
-void drv_sleep(int msec)
-{
-       [NSThread sleepForTimeInterval:0.001*msec];
-       return;
-}
-
-
-#elif (DRV_OSNUM == 0x0003)
-
-#error "Your OS is not supported."
-
-#elif (DRV_OSNUM == 0x0001)
-//
-// for Windows 32-bit
-//
-#include <windows.h>
-
-#define TIMER_ID                        1
-#define TIMER_INTERVAL         10
-
-struct BLD_WORK {
-       HINSTANCE hi;
-       HWND hw;
-       BITMAPINFO bmi;
-       int tmcount1, tmcount2, flags, smp; /* bit0: 終了 */
-       HANDLE mtx;
-       char *winClosed;
-};
-
-struct BLD_WORK bld_work;
-
-struct BL_WIN {
-       int xsiz, ysiz, *buf;
-};
-
-struct BL_WORK {
-       struct BL_WIN win;
-       jmp_buf jb;
-       int csiz_x, csiz_y, cx, cy, col0, col1, tabsiz, slctwin;
-       int tmcount, tmcount0, mod, rand_seed;
-       int *cbuf;
-       unsigned char *ftyp;
-       unsigned char **fptn;
-       int *ccol, *cbak;
-       int *kbuf, kbuf_rp, kbuf_wp, kbuf_c;
-};
-
-struct BL_WORK bl_work;
-
-#define BL_SIZ_KBUF                    8192
-
-#define BL_WAITKEYF            0x00000001
-#define BL_WAITKEYNF   0x00000002
-#define BL_WAITKEY             0x00000003
-#define BL_GETKEY              0x00000004
-#define BL_CLEARREP            0x00000008
-#define BL_DELFFF              0x00000010
-
-#define        BL_KEYMODE              0x00000000      // 作りかけ, make/remake/breakが見えるかどうか
-
-#define w      bl_work
-#define dw     bld_work
-
-void bld_openWin(int x, int y, char *winClosed);
-void bld_flshWin(int sx, int sy, int x0, int y0);
-LRESULT CALLBACK WndProc(HWND hw, unsigned int msg, WPARAM wp, LPARAM lp);
-void bl_cls();
-int bl_iCol(int i);
-void bl_readyWin(int n);
-
-static HANDLE threadhandle;
-
-int main(int argc, char **argv)
-{
-       // Program entry point
-       return HeavyOSECPUMain(argc, argv);
-}
-
-void *mallocRWE(int bytes)
-{
-       void *p = malloc(bytes);
-       DWORD dmy;
-       VirtualProtect(p, bytes, PAGE_EXECUTE_READWRITE, &dmy);
-       return p;
-}
-
-static int winthread(void *dmy)
-{
-       WNDCLASSEX wc;
-       RECT r;
-       int i, x, y;
-       MSG msg;
-       
-       x = dw.bmi.bmiHeader.biWidth;
-       y = -dw.bmi.bmiHeader.biHeight;
-       
-       wc.cbSize = sizeof (WNDCLASSEX);
-       wc.style = CS_HREDRAW | CS_VREDRAW;
-       wc.lpfnWndProc = WndProc;
-       wc.cbClsExtra = 0;
-       wc.cbWndExtra = 0;
-       wc.hInstance = dw.hi;
-       wc.hIcon = (HICON)LoadImage(NULL, MAKEINTRESOURCE(IDI_APPLICATION),
-                                                               IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
-       wc.hIconSm = wc.hIcon;
-       wc.hCursor = (HCURSOR)LoadImage(NULL, MAKEINTRESOURCE(IDC_ARROW),
-                                                                       IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
-       wc.hbrBackground = (HBRUSH)COLOR_APPWORKSPACE;
-       wc.lpszMenuName = NULL;
-       wc.lpszClassName = "WinClass";
-       if (RegisterClassEx(&wc) == 0)
-               return 1;
-       r.left = 0;
-       r.top = 0;
-       r.right = x;
-       r.bottom = y;
-       AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW, FALSE);
-       x = r.right - r.left;
-       y = r.bottom - r.top;
-       
-       char *t = "osecpu";
-       
-       dw.hw = CreateWindowA("WinClass", t, WS_OVERLAPPEDWINDOW,
-                                                 CW_USEDEFAULT, CW_USEDEFAULT, x, y, NULL, NULL, dw.hi, NULL);
-       if (dw.hw == NULL)
-               return 1;
-       ShowWindow(dw.hw, SW_SHOW);
-       UpdateWindow(dw.hw);
-       SetTimer(dw.hw, TIMER_ID, TIMER_INTERVAL, NULL);
-       SetTimer(dw.hw, TIMER_ID + 1, TIMER_INTERVAL * 10, NULL);
-       SetTimer(dw.hw, TIMER_ID + 2, TIMER_INTERVAL * 100, NULL);
-       dw.flags |= 2 | 4;
-       
-       for (;;) {
-               i = GetMessage(&msg, NULL, 0, 0);
-               if (i == 0 || i == -1)  /* エラーもしくは終了メッセージ */
-                       break;
-               /* そのほかはとりあえずデフォルト処理で */
-               TranslateMessage(&msg);
-               DispatchMessage(&msg);
-       }
-       //      PostQuitMessage(0);
-       dw.flags |= 1; /* 終了, bld_waitNF()が見つける */
-       if (dw.winClosed != NULL)
-               *dw.winClosed = 1;
-       return 0;
-}
-
-void bld_openWin(int sx, int sy, char *winClosed)
-{
-       static int i;
-       
-       dw.bmi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
-       dw.bmi.bmiHeader.biWidth = sx;
-       dw.bmi.bmiHeader.biHeight = -sy;
-       dw.bmi.bmiHeader.biPlanes = 1;
-       dw.bmi.bmiHeader.biBitCount = 32;
-       dw.bmi.bmiHeader.biCompression = BI_RGB;
-       dw.winClosed = winClosed;
-       
-       threadhandle = CreateThread(NULL, 0, (void *)&winthread, NULL, 0, (void *)&i);
-       
-       return;
-}
-
-void drv_flshWin(int sx, int sy, int x0, int y0)
-{
-       InvalidateRect(dw.hw, NULL, FALSE);
-       UpdateWindow(dw.hw);
-       return;
-}
-
-LRESULT CALLBACK WndProc(HWND hw, unsigned int msg, WPARAM wp, LPARAM lp)
-{
-       int i, j;
-       if (msg == WM_PAINT) {
-               PAINTSTRUCT ps;
-               HDC hdc = BeginPaint(dw.hw, &ps);
-               SetDIBitsToDevice(hdc, 0, 0, w.win.xsiz, w.win.ysiz,
-                                                 0, 0, 0, w.win.ysiz, w.win.buf, &dw.bmi, DIB_RGB_COLORS);
-               EndPaint(dw.hw, &ps);
-       }
-       if (msg == WM_DESTROY) {
-               PostQuitMessage(0);
-               return 0;
-       }
-       if (msg == WM_TIMER && wp == TIMER_ID) {
-               w.tmcount += TIMER_INTERVAL;
-               return 0;
-       }
-       if (msg == WM_TIMER && wp == TIMER_ID + 1) {
-               dw.tmcount1 += TIMER_INTERVAL * 10;
-               w.tmcount = dw.tmcount1;
-               return 0;
-       }
-       if (msg == WM_TIMER && wp == TIMER_ID + 2) {
-               dw.tmcount2 += TIMER_INTERVAL * 100;
-               w.tmcount = dw.tmcount1 = dw.tmcount2;
-               return 0;
-       }
-       if (msg == WM_KEYDOWN || msg == WM_SYSKEYDOWN) {
-               i = -1;
-               
-               if (wp == VK_RETURN)    i = KEY_ENTER;
-               if (wp == VK_ESCAPE)    i = KEY_ESC;
-               if (wp == VK_BACK)              i = KEY_BACKSPACE;
-               if (wp == VK_TAB)               i = KEY_TAB;
-               if (wp == VK_PRIOR)             i = KEY_PAGEUP;
-               if (wp == VK_NEXT)              i = KEY_PAGEDWN;
-               if (wp == VK_END)               i = KEY_END;
-               if (wp == VK_HOME)              i = KEY_HOME;
-               if (wp == VK_LEFT)              i = KEY_LEFT;
-               if (wp == VK_RIGHT)             i = KEY_RIGHT;
-               if (wp == VK_UP)                i = KEY_UP;
-               if (wp == VK_DOWN)              i = KEY_DOWN;
-               if (wp == VK_INSERT)    i = KEY_INS;
-               if (wp == VK_DELETE)    i = KEY_DEL;
-               j &= 0;
-               if ((GetKeyState(VK_LCONTROL) & (1 << 15)) != 0) j |= 1 << 17;
-               if ((GetKeyState(VK_LMENU)    & (1 << 15)) != 0) j |= 1 << 18;
-               if ((GetKeyState(VK_RCONTROL) & (1 << 15)) != 0) j |= 1 << 25;
-               if ((GetKeyState(VK_RMENU)    & (1 << 15)) != 0) j |= 1 << 26;
-               if ((GetKeyState(VK_RSHIFT)   & (1 << 15)) != 0) i |= 1 << 24;
-               if ((GetKeyState(VK_LSHIFT)   & (1 << 15)) != 0) i |= 1 << 16;
-               if ((GetKeyState(VK_NUMLOCK)  & (1 << 0)) != 0) i |= 1 << 22;
-               if ((GetKeyState(VK_CAPITAL)  & (1 << 0)) != 0) i |= 1 << 23;
-               if (j != 0) {
-                       if ('A' <= wp && wp <= 'Z') i = wp;
-               }
-               if (i != -1) {
-                       putKeybuf(i | j);
-                       //                      bl_putKeyB(1, &i);
-                       return 0;
-               }
-       }
-       if (msg == WM_KEYUP) {
-               i = 0xfff;
-               //              bl_putKeyB(1, &i);
-       }
-       if (msg == WM_CHAR) {
-               i = 0;
-               if (' ' <= wp && wp <= 0x7e) {
-                       i = wp;
-                       j &= 0;
-                       if ((GetKeyState(VK_LCONTROL) & (1 << 15)) != 0) j |= 1 << 17;
-                       if ((GetKeyState(VK_LMENU)    & (1 << 15)) != 0) j |= 1 << 18;
-                       if ((GetKeyState(VK_RCONTROL) & (1 << 15)) != 0) j |= 1 << 25;
-                       if ((GetKeyState(VK_RMENU)    & (1 << 15)) != 0) j |= 1 << 26;
-                       if ((GetKeyState(VK_RSHIFT)   & (1 << 15)) != 0) i |= 1 << 24;
-                       if ((GetKeyState(VK_LSHIFT)   & (1 << 15)) != 0) i |= 1 << 16;
-                       if ((GetKeyState(VK_NUMLOCK)  & (1 << 0)) != 0) i |= 1 << 22;
-                       if ((GetKeyState(VK_CAPITAL)  & (1 << 0)) != 0) i |= 1 << 23;
-                       if (('A' <= wp && wp <= 'Z') || ('a' <= wp && wp <= 'z')) {
-                               if (j != 0) {
-                                       i |= j;
-                                       i &= ~0x20;
-                               }
-                       }
-                       putKeybuf(i);
-                       //                      bl_putKeyB(1, &i);
-                       return 0;
-               }
-       }
-       return DefWindowProc(hw, msg, wp, lp);
-}
-
-void drv_openWin(int sx, int sy, UCHAR *buf, char *winClosed)
-{
-       w.win.buf = (int *)buf;
-       w.win.xsiz = sx;
-       w.win.ysiz = sy;
-       bld_openWin(sx, sy, winClosed);
-       return;
-}
-
-void drv_sleep(int msec)
-{
-       Sleep(msec);
-       //      MsgWaitForMultipleObjects(1, &threadhandle, FALSE, msec, QS_ALLINPUT);
-       /* 勉強不足でまだ書き方が分かりません! */
-       return;
-}
-
-#else
-
-#error "Illegal OS type. Edit osecpu.h and look at DRV_OSNUM"
-
+#include "osecpu.h"\r
+\r
+\r
+#if (DRV_OSNUM == 0x0002)\r
+//\r
+// for Mac OSX 32-bit\r
+//\r
+#include <mach/mach.h>\r
+#include <Cocoa/Cocoa.h>\r
+\r
+@interface OSECPUView : NSView\r
+{\r
+       unsigned char *_buf;\r
+       int _sx;\r
+       int _sy;\r
+       CGContextRef _context;\r
+}\r
+\r
+- (id)initWithFrame:(NSRect)frameRect buf:(unsigned char *)buf sx:(int)sx sy:(int)sy;\r
+- (void)drawRect:(NSRect)rect;\r
+@end\r
+\r
+@implementation OSECPUView\r
+- (id)initWithFrame:(NSRect)frameRect buf:(unsigned char *)buf sx:(int)sx sy:(int)sy\r
+{\r
+       self = [super initWithFrame:frameRect];\r
+       if (self) {\r
+               _buf = buf;\r
+               _sx = sx;\r
+               _sy = sy;\r
+       }\r
+       return self;\r
+}\r
+\r
+- (void)drawRect:(NSRect)rect {\r
+       CGColorSpaceRef colorSpace;\r
+       CGImageRef image;\r
+       CGContextRef currentContext;\r
+       \r
+       currentContext = [[NSGraphicsContext currentContext] graphicsPort];\r
+       colorSpace= CGColorSpaceCreateDeviceRGB();\r
+       \r
+       // ビットマップコンテキストにvramイメージを生成\r
+       _context = CGBitmapContextCreate (_buf, _sx, _sy, 8, 4 * _sx, colorSpace, (kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst));\r
+       image = CGBitmapContextCreateImage(_context);\r
+       \r
+       // 生成したvramイメージをViewに描画\r
+       CGContextDrawImage(currentContext, NSRectToCGRect(rect), image);\r
+       \r
+       // メモリ解放\r
+       CFRelease(colorSpace);\r
+       CFRelease(image);\r
+}\r
+\r
+- (void)keyDown:(NSEvent *)theEvent\r
+{\r
+       int i, j;\r
+       unichar kc;\r
+       \r
+       if([[theEvent characters] length] != 1){\r
+               return;\r
+       }\r
+       \r
+       kc = [[theEvent characters] characterAtIndex:0];\r
+       \r
+       // 通常キー\r
+       i = KEY_EMPTY;\r
+       if (kc == '\r') i = KEY_ENTER;\r
+       if (kc == 0x1b) i = KEY_ESC;\r
+       if (kc == 0x7F)         i = KEY_BACKSPACE;\r
+       if (kc == '\t')         i = KEY_TAB;\r
+       if (kc == NSPageUpFunctionKey)          i = KEY_PAGEUP;\r
+       if (kc == NSPageDownFunctionKey)                i = KEY_PAGEDWN;\r
+       if (kc == NSEndFunctionKey)             i = KEY_END;\r
+       if (kc == NSHomeFunctionKey)            i = KEY_HOME;\r
+       if (kc == NSLeftArrowFunctionKey)               i = KEY_LEFT;\r
+       if (kc == NSRightArrowFunctionKey)              i = KEY_RIGHT;\r
+       if (kc == NSUpArrowFunctionKey)         i = KEY_UP;\r
+       if (kc == NSDownArrowFunctionKey)               i = KEY_DOWN;\r
+       if (kc == NSInsertFunctionKey)  i = KEY_INS;\r
+       if (kc == NSDeleteFunctionKey)  i = KEY_DEL;\r
+       // 修飾キー\r
+       // TODO : 下の方の右辺、iとjが混ざっているのは修正すべき?\r
+       j = 0;\r
+       /*\r
+       if ((GetKeyState(VK_LCONTROL) & (1 << 15)) != 0) j |= KEY_MODIFIER_CONTROL_L;\r
+       if ((GetKeyState(VK_LMENU)    & (1 << 15)) != 0) j |= KEY_MODIFIER_MENU_L;\r
+       if ((GetKeyState(VK_RCONTROL) & (1 << 15)) != 0) j |= KEY_MODIFIER_CONTROL_R;\r
+       if ((GetKeyState(VK_RMENU)    & (1 << 15)) != 0) j |= KEY_MODIFIER_MENU_R;\r
+       if ((GetKeyState(VK_RSHIFT)   & (1 << 15)) != 0) i |= KEY_MODIFIER_SHIFT_R;\r
+       if ((GetKeyState(VK_LSHIFT)   & (1 << 15)) != 0) i |= KEY_MODIFIER_SHIFT_L;\r
+       if ((GetKeyState(VK_NUMLOCK)  & (1 << 0)) != 0) i |= KEY_MODIFIER_NUMLOCK;\r
+       if ((GetKeyState(VK_CAPITAL)  & (1 << 0)) != 0) i |= KEY_MODIFIER_CAPITAL;\r
+        */\r
+       \r
+       NSLog(@"%X", kc);\r
+       if (isascii(kc)){\r
+               i = kc;\r
+       }\r
+\r
+       if (i != -1) {\r
+               putKeybuf(i | j);\r
+       }\r
+}\r
+/*\r
+- (void)keyUp:(NSEvent *)theEvent\r
+{\r
+       NSLog(@"kUp");\r
+}\r
+ */\r
+@end\r
+\r
+@interface Main : NSObject<NSWindowDelegate>\r
+{\r
+       int argc;\r
+       const unsigned char **argv;\r
+       char *winClosed;\r
+       OSECPUView *_view;\r
+       NSWindow *mainWindow;\r
+       NSMenu *mainMenu;\r
+}\r
+\r
+- (void)runApp;\r
+- (void)createThread:(int)_argc args:(const unsigned char **)_argv;\r
+- (BOOL)windowShouldClose:(id)sender;\r
+- (void)openWin:(unsigned char *)buf sx:(int)sx sy:(int)sy winClosed:(char *)_winClosed;\r
+- (void)flushWin:(NSRect)rect;\r
+@end\r
+\r
+@implementation Main\r
+- (void)runApp\r
+{\r
+       // Sub thread\r
+       NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];\r
+       int retv;\r
+       retv = HeavyOSECPUMain(argc, (char **)argv);\r
+       [NSApp terminate:self];\r
+       [pool release];\r
+       exit(retv);\r
+}\r
+\r
+- (void)createThread : (int)_argc args:(const unsigned char **)_argv\r
+{\r
+       argc = _argc;\r
+       argv = _argv;\r
+       NSThread *thread = [[[NSThread alloc] initWithTarget:self selector:@selector(runApp) object:nil] autorelease];\r
+       [thread start];\r
+}\r
+\r
+- (BOOL)windowShouldClose:(id)sender\r
+{\r
+       *winClosed = 1;\r
+       return YES;\r
+}\r
+\r
+- (void)windowDidBecomeKey:(NSNotification *)notification\r
+{\r
+       [mainWindow makeFirstResponder:_view];\r
+}\r
+\r
+- (void)openWin:(unsigned char *)buf sx:(int)sx sy:(int) sy winClosed:(char *)_winClosed\r
+{\r
+       mainWindow = [[NSWindow alloc] initWithContentRect: NSMakeRect(0, 0, sx, sy) styleMask: NSTitledWindowMask | NSMiniaturizableWindowMask | NSClosableWindowMask backing: NSBackingStoreBuffered defer: NO];\r
+       mainWindow.delegate = self;\r
+       [mainWindow setTitle: @"osecpu"];\r
+       [mainWindow center];\r
+       [mainWindow makeKeyAndOrderFront:self];\r
+       [mainWindow setReleasedWhenClosed:YES];\r
+       \r
+       winClosed = _winClosed;\r
+       \r
+       _view = [[OSECPUView alloc] initWithFrame:NSMakeRect(0,0,sx,sy) buf:buf sx:sx sy:sy];\r
+       [mainWindow.contentView addSubview:_view];\r
+}\r
+\r
+- (void)flushWin : (NSRect)rect\r
+{\r
+       [_view setNeedsDisplayInRect:rect];\r
+}\r
+\r
+@end\r
+\r
+id objc_main;\r
+\r
+int main(int argc, char **argv)\r
+{\r
+       // Main thread\r
+       NSAutoreleasePool* pool;\r
+       ProcessSerialNumber psn = {0, kCurrentProcess};\r
+       \r
+       // ForegroundApplicationになれるように設定(こうしないとキーイベントが取得できない)\r
+       TransformProcessType(&psn, kProcessTransformToForegroundApplication);\r
+               \r
+       objc_main = [[Main alloc] init];\r
+       NSApp = [NSApplication sharedApplication];\r
+       \r
+       pool = [[NSAutoreleasePool alloc] init];\r
+       [objc_main createThread:argc args:(const unsigned char **)argv];\r
+       [NSApp run];\r
+       [pool release];\r
+       return 0;\r
+}\r
+\r
+void *mallocRWE(int bytes)\r
+{\r
+       void *p = malloc(bytes);\r
+       vm_protect(mach_task_self(), (vm_address_t) p, bytes, FALSE, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE);\r
+       return p;\r
+}\r
+\r
+void drv_openWin(int sx, int sy, unsigned char *buf, char *winClosed)\r
+{\r
+       [objc_main openWin:buf sx:sx sy:sy winClosed:winClosed];\r
+}\r
+\r
+void drv_flshWin(int sx, int sy, int x0, int y0)\r
+{\r
+       [objc_main flushWin:NSMakeRect(x0,y0,sx,sy)];\r
+}\r
+\r
+void drv_sleep(int msec)\r
+{\r
+       [NSThread sleepForTimeInterval:0.001*msec];\r
+       return;\r
+}\r
+\r
+\r
+#elif (DRV_OSNUM == 0x0003)\r
+\r
+#error "Your OS is not supported."\r
+\r
+#elif (DRV_OSNUM == 0x0001)\r
+//\r
+// for Windows 32-bit\r
+//\r
+#include <windows.h>\r
+\r
+#define TIMER_ID                        1\r
+#define TIMER_INTERVAL         10\r
+\r
+struct BLD_WORK {\r
+       HINSTANCE hi;\r
+       HWND hw;\r
+       BITMAPINFO bmi;\r
+       int tmcount1, tmcount2, flags, smp; /* bit0: 終了 */\r
+       HANDLE mtx;\r
+       char *winClosed;\r
+};\r
+\r
+struct BLD_WORK bld_work;\r
+\r
+struct BL_WIN {\r
+       int xsiz, ysiz, *buf;\r
+};\r
+\r
+struct BL_WORK {\r
+       struct BL_WIN win;\r
+       jmp_buf jb;\r
+       int csiz_x, csiz_y, cx, cy, col0, col1, tabsiz, slctwin;\r
+       int tmcount, tmcount0, mod, rand_seed;\r
+       int *cbuf;\r
+       unsigned char *ftyp;\r
+       unsigned char **fptn;\r
+       int *ccol, *cbak;\r
+       int *kbuf, kbuf_rp, kbuf_wp, kbuf_c;\r
+};\r
+\r
+struct BL_WORK bl_work;\r
+\r
+#define BL_SIZ_KBUF                    8192\r
+\r
+#define BL_WAITKEYF            0x00000001\r
+#define BL_WAITKEYNF   0x00000002\r
+#define BL_WAITKEY             0x00000003\r
+#define BL_GETKEY              0x00000004\r
+#define BL_CLEARREP            0x00000008\r
+#define BL_DELFFF              0x00000010\r
+\r
+#define        BL_KEYMODE              0x00000000      // 作りかけ, make/remake/breakが見えるかどうか\r
+\r
+#define w      bl_work\r
+#define dw     bld_work\r
+\r
+void bld_openWin(int x, int y, char *winClosed);\r
+void bld_flshWin(int sx, int sy, int x0, int y0);\r
+LRESULT CALLBACK WndProc(HWND hw, unsigned int msg, WPARAM wp, LPARAM lp);\r
+void bl_cls();\r
+int bl_iCol(int i);\r
+void bl_readyWin(int n);\r
+\r
+static HANDLE threadhandle;\r
+\r
+int main(int argc, char **argv)\r
+{\r
+       // Program entry point\r
+       return HeavyOSECPUMain(argc, argv);\r
+}\r
+\r
+void *mallocRWE(int bytes)\r
+{\r
+       void *p = malloc(bytes);\r
+       DWORD dmy;\r
+       VirtualProtect(p, bytes, PAGE_EXECUTE_READWRITE, &dmy);\r
+       return p;\r
+}\r
+\r
+static int winthread(void *dmy)\r
+{\r
+       WNDCLASSEX wc;\r
+       RECT r;\r
+       int i, x, y;\r
+       MSG msg;\r
+       \r
+       x = dw.bmi.bmiHeader.biWidth;\r
+       y = -dw.bmi.bmiHeader.biHeight;\r
+       \r
+       wc.cbSize = sizeof (WNDCLASSEX);\r
+       wc.style = CS_HREDRAW | CS_VREDRAW;\r
+       wc.lpfnWndProc = WndProc;\r
+       wc.cbClsExtra = 0;\r
+       wc.cbWndExtra = 0;\r
+       wc.hInstance = dw.hi;\r
+       wc.hIcon = (HICON)LoadImage(NULL, MAKEINTRESOURCE(IDI_APPLICATION),\r
+                                                               IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED);\r
+       wc.hIconSm = wc.hIcon;\r
+       wc.hCursor = (HCURSOR)LoadImage(NULL, MAKEINTRESOURCE(IDC_ARROW),\r
+                                                                       IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED);\r
+       wc.hbrBackground = (HBRUSH)COLOR_APPWORKSPACE;\r
+       wc.lpszMenuName = NULL;\r
+       wc.lpszClassName = "WinClass";\r
+       if (RegisterClassEx(&wc) == 0)\r
+               return 1;\r
+       r.left = 0;\r
+       r.top = 0;\r
+       r.right = x;\r
+       r.bottom = y;\r
+       AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW, FALSE);\r
+       x = r.right - r.left;\r
+       y = r.bottom - r.top;\r
+       \r
+       char *t = "osecpu";\r
+       \r
+       dw.hw = CreateWindowA("WinClass", t, WS_OVERLAPPEDWINDOW,\r
+                                                 CW_USEDEFAULT, CW_USEDEFAULT, x, y, NULL, NULL, dw.hi, NULL);\r
+       if (dw.hw == NULL)\r
+               return 1;\r
+       ShowWindow(dw.hw, SW_SHOW);\r
+       UpdateWindow(dw.hw);\r
+       SetTimer(dw.hw, TIMER_ID, TIMER_INTERVAL, NULL);\r
+       SetTimer(dw.hw, TIMER_ID + 1, TIMER_INTERVAL * 10, NULL);\r
+       SetTimer(dw.hw, TIMER_ID + 2, TIMER_INTERVAL * 100, NULL);\r
+       dw.flags |= 2 | 4;\r
+       \r
+       for (;;) {\r
+               i = GetMessage(&msg, NULL, 0, 0);\r
+               if (i == 0 || i == -1)  /* エラーもしくは終了メッセージ */\r
+                       break;\r
+               /* そのほかはとりあえずデフォルト処理で */\r
+               TranslateMessage(&msg);\r
+               DispatchMessage(&msg);\r
+       }\r
+       //      PostQuitMessage(0);\r
+       dw.flags |= 1; /* 終了, bld_waitNF()が見つける */\r
+       if (dw.winClosed != NULL)\r
+               *dw.winClosed = 1;\r
+       return 0;\r
+}\r
+\r
+void bld_openWin(int sx, int sy, char *winClosed)\r
+{\r
+       static int i;\r
+       \r
+       dw.bmi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);\r
+       dw.bmi.bmiHeader.biWidth = sx;\r
+       dw.bmi.bmiHeader.biHeight = -sy;\r
+       dw.bmi.bmiHeader.biPlanes = 1;\r
+       dw.bmi.bmiHeader.biBitCount = 32;\r
+       dw.bmi.bmiHeader.biCompression = BI_RGB;\r
+       dw.winClosed = winClosed;\r
+       \r
+       threadhandle = CreateThread(NULL, 0, (void *)&winthread, NULL, 0, (void *)&i);\r
+       \r
+       return;\r
+}\r
+\r
+void drv_flshWin(int sx, int sy, int x0, int y0)\r
+{\r
+       InvalidateRect(dw.hw, NULL, FALSE);\r
+       UpdateWindow(dw.hw);\r
+       return;\r
+}\r
+\r
+LRESULT CALLBACK WndProc(HWND hw, unsigned int msg, WPARAM wp, LPARAM lp)\r
+{\r
+       int i, j;\r
+       if (msg == WM_PAINT) {\r
+               PAINTSTRUCT ps;\r
+               HDC hdc = BeginPaint(dw.hw, &ps);\r
+               SetDIBitsToDevice(hdc, 0, 0, w.win.xsiz, w.win.ysiz,\r
+                                                 0, 0, 0, w.win.ysiz, w.win.buf, &dw.bmi, DIB_RGB_COLORS);\r
+               EndPaint(dw.hw, &ps);\r
+       }\r
+       if (msg == WM_DESTROY) {\r
+               PostQuitMessage(0);\r
+               return 0;\r
+       }\r
+       if (msg == WM_TIMER && wp == TIMER_ID) {\r
+               w.tmcount += TIMER_INTERVAL;\r
+               return 0;\r
+       }\r
+       if (msg == WM_TIMER && wp == TIMER_ID + 1) {\r
+               dw.tmcount1 += TIMER_INTERVAL * 10;\r
+               w.tmcount = dw.tmcount1;\r
+               return 0;\r
+       }\r
+       if (msg == WM_TIMER && wp == TIMER_ID + 2) {\r
+               dw.tmcount2 += TIMER_INTERVAL * 100;\r
+               w.tmcount = dw.tmcount1 = dw.tmcount2;\r
+               return 0;\r
+       }\r
+       if (msg == WM_KEYDOWN || msg == WM_SYSKEYDOWN) {\r
+               // 通常キー\r
+               i = KEY_EMPTY;\r
+               if (wp == VK_RETURN)    i = KEY_ENTER;\r
+               if (wp == VK_ESCAPE)    i = KEY_ESC;\r
+               if (wp == VK_BACK)              i = KEY_BACKSPACE;\r
+               if (wp == VK_TAB)               i = KEY_TAB;\r
+               if (wp == VK_PRIOR)             i = KEY_PAGEUP;\r
+               if (wp == VK_NEXT)              i = KEY_PAGEDWN;\r
+               if (wp == VK_END)               i = KEY_END;\r
+               if (wp == VK_HOME)              i = KEY_HOME;\r
+               if (wp == VK_LEFT)              i = KEY_LEFT;\r
+               if (wp == VK_RIGHT)             i = KEY_RIGHT;\r
+               if (wp == VK_UP)                i = KEY_UP;\r
+               if (wp == VK_DOWN)              i = KEY_DOWN;\r
+               if (wp == VK_INSERT)    i = KEY_INS;\r
+               if (wp == VK_DELETE)    i = KEY_DEL;\r
+               // 修飾キー\r
+               // TODO : 下の方の右辺、iとjが混ざっているのは修正すべき?\r
+               j = 0;\r
+               if ((GetKeyState(VK_LCONTROL) & (1 << 15)) != 0) j |= KEY_MODIFIER_CONTROL_L;\r
+               if ((GetKeyState(VK_LMENU)    & (1 << 15)) != 0) j |= KEY_MODIFIER_MENU_L;\r
+               if ((GetKeyState(VK_RCONTROL) & (1 << 15)) != 0) j |= KEY_MODIFIER_CONTROL_R;\r
+               if ((GetKeyState(VK_RMENU)    & (1 << 15)) != 0) j |= KEY_MODIFIER_MENU_R;\r
+               if ((GetKeyState(VK_RSHIFT)   & (1 << 15)) != 0) i |= KEY_MODIFIER_SHIFT_R;\r
+               if ((GetKeyState(VK_LSHIFT)   & (1 << 15)) != 0) i |= KEY_MODIFIER_SHIFT_L;\r
+               if ((GetKeyState(VK_NUMLOCK)  & (1 << 0)) != 0) i |= KEY_MODIFIER_NUMLOCK;\r
+               if ((GetKeyState(VK_CAPITAL)  & (1 << 0)) != 0) i |= KEY_MODIFIER_CAPITAL;\r
+               if (j != 0) {\r
+                       if ('A' <= wp && wp <= 'Z'){\r
+                               i = wp;\r
+                       }\r
+               }\r
+               if (i != -1) {\r
+                       putKeybuf(i | j);\r
+                       return 0;\r
+               }\r
+       }\r
+       if (msg == WM_KEYUP) {\r
+               i = 0xfff;\r
+       }\r
+       if (msg == WM_CHAR) {\r
+               i = 0;\r
+               if (' ' <= wp && wp <= 0x7e) {\r
+                       i = wp;\r
+                       j &= 0;\r
+                       if ((GetKeyState(VK_LCONTROL) & (1 << 15)) != 0) j |= 1 << 17;\r
+                       if ((GetKeyState(VK_LMENU)    & (1 << 15)) != 0) j |= 1 << 18;\r
+                       if ((GetKeyState(VK_RCONTROL) & (1 << 15)) != 0) j |= 1 << 25;\r
+                       if ((GetKeyState(VK_RMENU)    & (1 << 15)) != 0) j |= 1 << 26;\r
+                       if ((GetKeyState(VK_RSHIFT)   & (1 << 15)) != 0) i |= 1 << 24;\r
+                       if ((GetKeyState(VK_LSHIFT)   & (1 << 15)) != 0) i |= 1 << 16;\r
+                       if ((GetKeyState(VK_NUMLOCK)  & (1 << 0)) != 0) i |= 1 << 22;\r
+                       if ((GetKeyState(VK_CAPITAL)  & (1 << 0)) != 0) i |= 1 << 23;\r
+                       if (('A' <= wp && wp <= 'Z') || ('a' <= wp && wp <= 'z')) {\r
+                               if (j != 0) {\r
+                                       i |= j;\r
+                                       i &= ~0x20;\r
+                               }\r
+                       }\r
+                       putKeybuf(i);\r
+                       return 0;\r
+               }\r
+       }\r
+       return DefWindowProc(hw, msg, wp, lp);\r
+}\r
+\r
+void drv_openWin(int sx, int sy, UCHAR *buf, char *winClosed)\r
+{\r
+       w.win.buf = (int *)buf;\r
+       w.win.xsiz = sx;\r
+       w.win.ysiz = sy;\r
+       bld_openWin(sx, sy, winClosed);\r
+       return;\r
+}\r
+\r
+void drv_sleep(int msec)\r
+{\r
+       Sleep(msec);\r
+       //      MsgWaitForMultipleObjects(1, &threadhandle, FALSE, msec, QS_ALLINPUT);\r
+       /* 勉強不足でまだ書き方が分かりません! */\r
+       return;\r
+}\r
+\r
+#else\r
+\r
+#error "Illegal OS type. Edit osecpu.h and look at DRV_OSNUM"\r
+\r
 #endif
\ No newline at end of file
index 5d10137..2a5765e 100644 (file)
-#include "osecpu.h"
-#include "jitc.h"
-
-extern unsigned char fontdata[];    // @fontdata.c
-
-const char *searchArg(int argc, const char **argv, const char *tag, int i)
-{
-       // 引数リストargvの中から、文字列tagが前方一致する引数のi番目を探し出し、
-       // その引数の文字列の、tagに続く部分の文字へのポインタを返す。
-       int j, l;
-       const char *r = NULL;
-       
-       if (tag != NULL) {
-               l = (int)strlen(tag);
-               for (j = 1; j < argc; j++) {
-                       if (strncmp(argv[j], tag, l) == 0) {
-                               r = argv[j] + l;
-                               if (i == 0){
-                                       break;
-                               }
-                               i--;
-                       }
-               }
-       }
-       /*
-        // 未使用
-       else {
-               for (j = 1; j < argc; j++) {
-                       if (strchr(argv[j], ':') == NULL) {
-                               r = argv[j];
-                               if (i == 0){
-                                       break;
-                               }
-                               i--;
-                       }
-               }
-       }
-        */
-       if (i != 0){
-               r = NULL;
-       }
-       return r;
-}
-
-void devFunc0001(int len, unsigned char *puc, HOSECPU_RuntimeEnvironment *r)
-{
-       // OSASK文字列の出力
-       while (len > 0) {
-               putOsaskChar(*puc++, r);
-               len--;
-       }
-       return;
-}
-
-void devFunc0006(int mod, int sx, int sy, int x, int y, int c, int len, unsigned char *puc, HOSECPU_RuntimeEnvironment *r)
-{
-       // drawString
-       int xx;
-       int yy;
-       int i, ddx, ddy, j, ch, dx, dy;
-       
-       if (sy == 0){
-               sy = sx;
-       }
-       xx = x + sx * 8;
-       yy = y + sy * 16;
-       if (xx <= 0 || xx > mainWindow.xsize || yy <= 0 || yy > mainWindow.ysize){
-               (*(r->errHndl))(r);
-       }
-       if (x < 0 || x >= mainWindow.xsize || y < 0 || y >= mainWindow.ysize){
-               (*(r->errHndl))(r);
-       }
-       
-       
-       if ((mod & 3) == 0 && sx == 1 && sy == 1) {
-               // メジャーケースを高速化.
-               for (i = 0; i < len; i++) {
-                       ch = puc[i];
-                       if (0x10 <= ch && ch <= 0x1f)
-                               ch = "0123456789ABCDEF"[ch & 0x0f];
-                       for (dy = 0; dy < 16; dy++) {
-                               j = fontdata[(ch - ' ') * 16 + dy];
-                               for (dx = 0; dx < 8; dx++) {
-                                       if ((j & (0x80 >> dx)) != 0){
-                                               mainWindow.vram[(x + dx) + (y + dy) * mainWindow.xsize] = c;
-                                       }
-                               }
-                       }
-                       x += 8;
-               }
-               return;
-       }
-       for (i = 0; i < len; i++) {
-               ch = puc[i];
-               if (0x10 <= ch && ch <= 0x1f)
-                       ch = "0123456789ABCDEF"[ch & 0x0f];
-               for (dy = 0; dy < 16; dy++) {
-                       j = fontdata[(ch - ' ') * 16 + dy];
-                       for (ddy = 0; ddy < sy; ddy++) {
-                               for (dx = 0; dx < 8; dx++) {
-                                       if ((j & (0x80 >> dx)) != 0) {
-                                               for (ddx = 0; ddx < sx; ddx++) {
-                                                       switch (mod & 3) {
-                                                               case 0:
-                                                                       mainWindow.vram[x + y * mainWindow.xsize] = c;
-                                                                       break;
-                                                               case 1:
-                                                                       mainWindow.vram[x + y * mainWindow.xsize] |= c;
-                                                                       break;
-                                                               case 2:
-                                                                       mainWindow.vram[x + y * mainWindow.xsize] ^= c;
-                                                                       break;
-                                                               case 3:
-                                                                       mainWindow.vram[x + y * mainWindow.xsize] &= c;
-                                                                       break;
-                                                       }
-                                                       x++;
-                                               }
-                                       } else{
-                                               x += sx;
-                                       }
-                               }
-                               x -= sx * 8;
-                               y++;
-                       }
-               }
-               x += sx * 8;
-               y -= sy * 16;
-       }
-       return;
-}
-
-void devFunc0004(int mod, int x0, int y0, int x1, int y1, int c)
-{
-       // FillRect
-       int x, y;
-       if (mod == 0) {
-               for (y = y0; y <= y1; y++) {
-                       for (x = x0; x <= x1; x++) {
-                               mainWindow.vram[x + y * mainWindow.xsize] = c;
-                       }
-               }
-       }
-       else {
-               for (y = y0; y <= y1; y++) {
-                       for (x = x0; x <= x1; x++) {
-                               switch (mod) {
-                                       case 1:
-                                               mainWindow.vram[x + y * mainWindow.xsize] |= c;
-                                               break;
-                                       case 2:
-                                               mainWindow.vram[x + y * mainWindow.xsize] ^= c;
-                                               break;
-                                       case 3:
-                                               mainWindow.vram[x + y * mainWindow.xsize] &= c;
-                                               break;
-                               }
-                       }
-               }
-       }
-       return;
-}
-
-int devFunc0016(int buflen, unsigned char *buf, int plen, unsigned char *p, int qlen, int *q, HOSECPU_RuntimeEnvironment *r)
-{
-       // OSASK文字列への変換?
-       int i = 0, base, j, k;
-       char sign;
-       
-       while (plen > 0) {
-               if (i >= buflen){
-                       (*(r->errHndl))(r);
-               }
-               if (*p != 0x01) {
-                       buf[i++] = *p++;
-                       plen--;
-                       continue;
-               }
-               p++;
-               plen--;
-               if (qlen < 4){
-                       (*(r->errHndl))(r);
-               }
-               base = q[0];
-               sign = 0;
-               if (base == 0){
-                       base = 16;
-               }
-#if (REVISION == 1)
-               if (base == -3){
-                       base = 10;
-               }
-#endif
-               if (base == -1){
-                       base = 10;
-               }
-               if (base < 0 || base > 16){
-                       (*(r->errHndl))(r);
-               }
-               if (q[1] + i > buflen){
-                       (*(r->errHndl))(r);
-               }
-               j = q[3];
-               if ((q[2] & 4) == 0) {
-                       // jは符号付き整数.
-                       if ((q[2] & 8) != 0 && j > 0){
-                               sign = '+';
-                       }
-                       if (j < 0) {
-                               sign = '-'; j *= -1;
-                       }
-               } else{
-                       // jは符号無し整数.
-                       if ((q[2] & 8) != 0 && j != 0){
-                               sign = '+';
-                       }
-               }
-               for (k = q[1] - 1; k >= 0; k--) {
-                       buf[i + k] = (j % base) + 0x10;
-                       j = ((unsigned)j) / base;
-               }
-               k = 0;
-               if ((q[2] & 2) == 0 && j == 0) {
-                       for (k = 0; k < q[1] - 1; k++) {
-                               if (buf[i + k] != 0x10){
-                                       break;
-                               }
-                               buf[i + k] = ' ';
-                       }
-               }
-               if (sign != 0) {
-                       if (k > 0){
-                               k--;
-                       }
-                       buf[i + k] = sign;
-               }
-               if ((q[2] & 1) != 0 && buf[i] == ' ') {
-                       for (j = 0; k < q[1]; k++, j++){
-                               buf[i + j] = buf[i + k];
-                       }
-                       i += j;
-               } else{
-                       i += q[1];
-               }
-               qlen -= 4;
-               q += 4;
-       }
-       return i;
-}
-
-void devFunc(HOSECPU_RuntimeEnvironment *r)
-{
-       FILE *fp;
-       int i, c;
-       int x, y, len, dx, dy;
-       unsigned char *puc;
-       unsigned char pucbuf[256];
-       
-       //サイズを節約するためにEBPを128バイトずらしているのを元に戻す
-       r = (HOSECPU_RuntimeEnvironment *) (((char *)r) - jitCompA0001_EBP128);
-       
-       if (r->winClosed != 0){
-               longjmp(r->setjmpEnv, 1);
-       }
-       if (0xff44 <= r->ireg[0x30] && r->ireg[0x30] <= 0xff48) {
-               if (mainWindow.vram == NULL) {
-                       mainWindow.xsize = 640;
-                       mainWindow.ysize = 480;
-                       mainWindow.vram = malloc(640 * 480 * 4);
-                       drv_openWin(640, 480, (void *)mainWindow.vram, &r->winClosed);
-                       r->autoSleep = 1;
-                       for (i = 640 * 480 - 1; i >= 0; i--){
-                               mainWindow.vram[i] = 0;
-                       }
-               }
-       }
-       
-       switch (r->ireg[0x30]){
-               case 0xff00:
-                       printf("R31=%d(dec)\n", r->ireg[0x31]);
-                       break;
-                       
-               case 0xff01:
-                       // junkApi_fopenRead(_filesize, _p, arg)
-                       // args: R31=arg, R30=_filesize, P31=_p
-                       // retv: R30, P31
-                       if (r->buf0 == NULL){
-                               r->buf0 = malloc(1024 * 1024);
-                       }
-                       if (r->mainArgc <= r->ireg[0x31]) {
-                               fprintf(stderr, "devFunc: error: R30=ff01: argc error: R31=%08X\n", r->ireg[0x31]);
-                               exit(1);
-                       }
-                       fp = fopen(r->mainArgv[r->ireg[0x31]], "rb");
-                       if (fp == NULL) {
-                               fprintf(stderr, "devFunc: error: R30=ff01: fopen error: '%s'\n", r->mainArgv[r->ireg[0x31]]);
-                               exit(1);
-                       }
-                       i = (int)fread(r->buf0, 1, 1024 * 1024 - 4, fp);
-                       if (i >= 1024 * 1024 - 4 || i < 0) {
-                               fprintf(stderr, "devFunc: error: R30=ff01: fread error: '%s'\n", r->mainArgv[r->ireg[0x31]]);
-                               exit(1);
-                       }
-                       fclose(fp);
-                       r->preg[0x31].p = r->buf0;
-                       r->preg[0x31].p0 = r->buf0;
-                       r->preg[0x31].p1 = r->buf0 + i;
-                       r->preg[0x31].typ = 3; // T_UINT8
-                       r->ireg[0x30] = i;
-                       break;
-                       
-               case 0xff02:
-                       // junkApi_fopenWrite(arg, filesize, p)
-                       // args: R31=arg, R32=filesize, P31=p
-                       // retv: (none)
-                       if (r->mainArgc <= r->ireg[0x31]) {
-                               fprintf(stderr, "devFunc: error: R30=ff02: argc error: R31=%08X\n", r->ireg[0x31]);
-                               exit(1);
-                       }
-                       fp = fopen(r->mainArgv[r->ireg[0x31]], "wb");
-                       if (fp == NULL) {
-                               fprintf(stderr, "devFunc: error: R30=ff02: fopen error: '%s'\n", r->mainArgv[r->ireg[0x31]]);
-                               exit(1);
-                       }
-                       if (r->ireg[0x32] >= 1024 * 1024 || r->ireg[0x32] < 0){
-                               fprintf(stderr, "devFunc: error: R30=ff02: fwrite error: R02=%08X\n", r->ireg[0x32]);
-                               exit(1);
-                       }
-                       fwrite(r->preg[0x31].p, 1, r->ireg[0x32], fp);
-                       fclose(fp);
-                       break;
-                       
-               case 0xff03:
-                       // junkApi_allocBuf(_p)
-                       // args: P31=_p
-                       // retv: P31
-                       if (r->buf1 == NULL){
-                               r->buf1 = malloc(1024 * 1024);
-                       }
-                       r->preg[0x31].p = r->buf1;
-                       r->preg[0x31].p0 = r->buf1;
-                       r->preg[0x31].p1 = r->buf1 + 1024 * 1024;
-                       break;
-                       
-               case 0xff04:
-                       printf("P31.(p-p0)=%d(dec)\n", (int)(r->preg[0x31].p - r->preg[0x31].p0));
-                       break;
-                       
-               case 0xff05:
-                       // junkApi_writeStdout(len, p)
-                       // args: R31=len, P31=p
-                       // retv: (none)
-                       fwrite(r->preg[0x31].p, 1, r->ireg[0x31], stdout);
-                       break;
-                       
-               case 0xff06:
-                       // junkApi_exit(i)
-                       // args: R31=i
-                       // retv: (none)
-                       r->appReturnCode = r->ireg[31];
-                       longjmp(r->setjmpEnv, 1);
-                       break;
-                       
-               case 0xff07:
-                       // junkApi_putConstString0(s)
-                       // DB(0xff,0x00,0x00); DB%(s,0x00);
-                       // マシになった文字列表示.
-                       // OSASK文字列に対応.offにすれば通常の文字列処理もできる.
-                       // 現状はonのみサポート.
-                       checkString(r, 0x31, 0x31);
-                       devFunc0001(r->ireg[0x31], r->preg[0x31].p, r);
-                       break;
-                       
-               case 0xff08:
-                       // junkApi_jitc2(_rc, _p, mod, lev, di1, len, s)
-                       // R31=mod; R32=lev; R33=di1; R34=len; P31=s; _rc=R30; _p=P31
-                       // JITC on JITC
-                       // R31: 言語(back-end, front-end, ...
-                       // R32: level
-                       // R33: debugInfo1
-                       checkString(r, 0x34, 0x31);
-                       if (r->ireg[0x33] < 0 || r->ireg[0x33] > 15 || r->debugInfo1 > 15){
-                               (*(r->errHndl))(r);
-                       }
-                       for (i = 0; i < r->maxLabels; i++){
-                               r->label[i].opt = 0;
-                       }
-                       puc = r->preg[0x31].p;
-                       i = jitCompiler(r->jitbuf, r->jitbuf1, puc, puc + r->ireg[0x34], puc, r->label, r->maxLabels, r->ireg[0x32], di1_serial, JITC_NOSTARTUP + 0);
-                       if (i == 0) {
-                               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);
-                               if (i >= 0) {
-                                       r->mapDi1s[r->debugInfo1][r->ireg[0x33]] = di1_serial;
-                                       di1_serial++;
-                                       r->ireg[0x30] = 0;
-                                       r->preg[0x31].p = r->jitbuf;
-                                       r->preg[0x31].typ = 0; // TYP_CODE
-                                       r->preg[0x31].p0 = r->jitbuf;
-                                       r->preg[0x31].p1 = r->jitbuf + 1;
-                                       //int j; for (j = 0; j < i; j++) printf("%02X ", r->jitbuf[j]); putchar('\n');
-                                       r->jitbuf += i;
-                                       static unsigned char ff08_ret[3] = { 0x1e, 0x3f, 0x30 };
-                                       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);
-                                       r->jitbuf += i;
-                                       break;
-                               }
-                       }
-                       r->ireg[0x30] = -1;
-                       break;
-                       
-               case 0xff09:
-                       //putStringDec
-                       // たぶんbit7を使ったテキストはうまく処理できない(これはもはや仕様にしても問題ないかも).
-                       checkString(r, 0x31, 0x31);
-                       len = devFunc0016(sizeof pucbuf, pucbuf, r->ireg[0x31], r->preg[0x31].p, r->ireg[0x32], (int *)r->preg[0x32].p, r);
-                       devFunc0001(len, pucbuf, r);
-                       break;
-                       
-               case 0xff40:
-                       // junkApi_openWin(xsiz, ysiz) R31=xsiz; R32=ysiz;
-                       /* R31とR32でサイズを指定 */
-                       mainWindow.xsize = r->ireg[0x31];
-                       mainWindow.ysize = r->ireg[0x32];
-                       if (mainWindow.xsize <= 0 || mainWindow.ysize <= 0){
-                               (*(r->errHndl))(r);
-                       }
-                       r->preg[0x31].p = (void *)(mainWindow.vram = malloc(mainWindow.xsize * mainWindow.ysize * 4));
-                       r->preg[0x31].p0 = r->preg[0x31].p;
-                       r->preg[0x31].p1 = r->preg[0x31].p + mainWindow.xsize * mainWindow.ysize * 4;
-                       drv_openWin(r->ireg[0x31], r->ireg[0x32], r->preg[0x31].p, &r->winClosed);
-                       //      drv_flshWin(r->ireg[1], r->ireg[2], 0, 0);
-                       r->autoSleep = 1;
-                       for (i = mainWindow.xsize * mainWindow.ysize - 1; i >= 0; i--){
-                               mainWindow.vram[i] = 0;
-                       }
-                       break;
-                       
-               case 0xff41:
-                       // junkApi_flushWin(xsiz, ysiz, x0, y0)
-                       // R31=xsiz; R32=ysiz; R33=x0; R34=y0
-                       /* R31とR32でサイズを指定、R33とR34でx0,y0指定 */
-                       if (r->ireg[0x31] == -1) {
-                               r->ireg[0x31] = mainWindow.xsize; r->ireg[0x33] &= 0;
-                       }
-                       if (r->ireg[0x32] == -1) {
-                               r->ireg[0x32] = mainWindow.ysize; r->ireg[0x34] &= 0;
-                       }
-                       checkRect(r, 0x31);
-                       drv_flshWin(r->ireg[0x31], r->ireg[0x32], r->ireg[0x33], r->ireg[0x34]);
-                       break;
-                       
-               case 0xff42:
-                       // junkApi_sleep(opt, msec) R31=opt; R32=msec
-                       if (r->ireg[0x32] == -1) {
-                               r->autoSleep = 1;
-                               longjmp(r->setjmpEnv, 1);
-                       }
-                       if (r->ireg[0x32] < 0){
-                               (*(r->errHndl))(r);
-                       }
-                       r->autoSleep = 0;
-                       if ((r->ireg[0x31] & 1) == 0 && mainWindow.vram != NULL){
-                               drv_flshWin(mainWindow.xsize, mainWindow.ysize, 0, 0);
-                       }
-                       for (;;) {
-                               if (r->winClosed != 0){
-                                       longjmp(r->setjmpEnv, 1);
-                               }
-                               drv_sleep(r->ireg[0x32]);
-                               if ((r->ireg[0x31] & 2) != 0 && keybuf_c <= 0){
-                                       continue;
-                               }
-                               break;
-                       }
-                       break;
-                       
-               case 0xff43:
-                       // junkApi_inkey(_i, mod) R31=mod; _i=R30
-                       //  1:peek
-                       //  2:stdin
-                       //      4,8: ソース指定.
-                       //      16: shift, lock系を有効化.
-                       //      32: 左右のshift系を区別する.
-                       if (r->ireg[0x31] == 2) {       // なぜ3にしなかったのか...
-                               r->ireg[0x30] = fgetc(stdin);
-                               if (r->ireg[0x30] == EOF){
-                                       r->ireg[0x30] = -1;
-                               }
-                               break;
-                       }
-                       r->ireg[0x30] |= -1;
-                       if (keybuf_c > 0) {
-                               r->ireg[0x30] = keybuf[keybuf_r];
-                               if ((r->ireg[0x31] & 16) == 0){
-                                       r->ireg[0x30] &= 0x3e3effff;
-                               }
-                               if ((r->ireg[0x31] & 32) == 0){
-                                       r->ireg[0x30] |= (r->ireg[0x30] >> 8) & 0xff0000;
-                               }
-                               if ((r->ireg[0x31] & 1) != 0) {
-                                       keybuf_c--;
-                                       keybuf_r = (keybuf_r + 1) & (KEYBUFSIZ - 1);
-                               }
-                       }
-                       r->ireg[0x32] = r->ireg[0x33] = 0;
-                       if (r->ireg[0x30] == 4132) r->ireg[0x32]--;
-                       if (r->ireg[0x30] == 4133) r->ireg[0x33]--;
-                       if (r->ireg[0x30] == 4134) r->ireg[0x32]++;
-                       if (r->ireg[0x30] == 4135) r->ireg[0x33]++;
-                       break;
-                       
-               case 0xff44:
-                       // junkApi_drawPoint(mod, x, y, c) R31=mod; R32=x; R33=y; R34=c
-                       c = loadColor(r, 0x34);
-                       if (r->ireg[0x32] < 0 || r->ireg[0x32] >= mainWindow.xsize ||
-                               r->ireg[0x33] < 0 || r->ireg[0x33] >= mainWindow.ysize){
-                               (*(r->errHndl))(r);
-                       }
-                       
-                       switch ((r->ireg[0x31] & 3)) {
-                               case 0:
-                                       mainWindow.vram[r->ireg[0x32] + r->ireg[0x33] * mainWindow.xsize] = c;
-                                       break;
-                               case 1:
-                                       mainWindow.vram[r->ireg[0x32] + r->ireg[0x33] * mainWindow.xsize] |= c;
-                                       break;
-                               case 2:
-                                       mainWindow.vram[r->ireg[0x32] + r->ireg[0x33] * mainWindow.xsize] ^= c;
-                                       break;
-                               case 3:
-                                       mainWindow.vram[r->ireg[0x32] + r->ireg[0x33] * mainWindow.xsize] &= c;
-                                       break;
-                       }
-                       break;
-                       
-               case 0xff45:
-                       // junkApi_drawLine(mod, x0, y0, x1, y1, c)     DB(0xfe,0x05,0x01); DDBE(0x0003); R30=0xff45; R31=mod; R32=x0; R33=y0; R34=x1; R35=y1; R36=c
-                       //drawLine
-                       c = loadColor(r, 0x36);
-                       if (r->ireg[0x32] < 0 || r->ireg[0x32] >= mainWindow.xsize ||
-                               r->ireg[0x33] < 0 || r->ireg[0x33] >= mainWindow.ysize){
-                               (*(r->errHndl))(r);
-                       }
-                       if (r->ireg[0x34] < 0 || r->ireg[0x34] >= mainWindow.xsize ||
-                               r->ireg[0x35] < 0 || r->ireg[0x35] >= mainWindow.ysize){
-                               (*(r->errHndl))(r);
-                       }
-                       dx = r->ireg[0x34] - r->ireg[0x32];
-                       dy = r->ireg[0x35] - r->ireg[0x33];
-                       x = r->ireg[0x32] << 10;
-                       y = r->ireg[0x33] << 10;
-                       if (dx < 0){
-                               dx = -dx;
-                       }
-                       if (dy < 0){
-                               dy = -dy;
-                       }
-                       if (dx >= dy) {
-                               len = dx + 1; dx = 1024;
-                               if (r->ireg[0x32] > r->ireg[0x34]){
-                                       dx *= -1;
-                               }
-                               if (r->ireg[0x33] > r->ireg[0x35]){
-                                       dy *= -1;
-                               }
-                               dy = (dy << 10) / len;
-                       } else {
-                               len = dy + 1; dy = 1024;
-                               if (r->ireg[0x33] > r->ireg[0x35]){
-                                       dy *= -1;
-                               }
-                               if (r->ireg[0x32] > r->ireg[0x34]){
-                                       dx *= -1;
-                               }
-                               dx = (dx << 10) / len;
-                       }
-                       if ((r->ireg[0x31] & 3) == 0) {
-                               for (i = 0; i < len; i++) {
-                                       mainWindow.vram[(x >> 10) + (y >> 10) * mainWindow.xsize] = c;
-                                       x += dx;
-                                       y += dy;
-                               }
-                               break;
-                       }
-                       for (i = 0; i < len; i++) {
-                               //      if ((r->ireg[0x31] & 3) == 0) vram[(x >> 10) + (y >> 10) * v_xsiz] =  c;
-                               switch ((r->ireg[0x31] & 3)) {
-                                       case 1:
-                                               mainWindow.vram[(x >> 10) + (y >> 10) * mainWindow.xsize] |= c;
-                                               break;
-                                       case 2:
-                                               mainWindow.vram[(x >> 10) + (y >> 10) * mainWindow.xsize] ^= c;
-                                               break;
-                                       case 3:
-                                               mainWindow.vram[(x >> 10) + (y >> 10) * mainWindow.xsize] &= c;
-                                               break;
-                                       default:
-                                               break;
-                               }
-                               x += dx;
-                               y += dy;
-                       }
-                       break;
-                       
-               case 0xff46:
-                       // fillRect(opt:R31, xsiz:R32, ysiz:R33, x0:R34, y0:R35, c:R36)
-                       c = loadColor(r, 0x36);
-                       if (r->ireg[0x32] == -1) { r->ireg[0x32] = mainWindow.xsize; r->ireg[0x34] &= 0; }
-                       if (r->ireg[0x33] == -1) { r->ireg[0x33] = mainWindow.ysize; r->ireg[0x35] &= 0; }
-                       checkRect(r, 0x32);
-                       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;
-                       if ((r->ireg[0x31] & 0x20) == 0) {
-                               devFunc0004(mod3, x0, y0, x1, y1, c);
-                       } else {        // drawRect
-                               devFunc0004(mod3, x0, y0, x1, y0, c);
-                               devFunc0004(mod3, x0, y1, x1, y1, c);
-                               devFunc0004(mod3, x0, y0, x0, y1, c);
-                               devFunc0004(mod3, x1, y0, x1, y1, c);
-                       }
-                       break;
-                       
-               case 0xff47:
-                       // fillOval(opt:R31, xsiz:R32, ysiz:R33, x0:R34, y0:R35, c:R36)
-                       // これの計算精度はアーキテクチャに依存する.
-                       c = loadColor(r, 0x36);
-                       if (r->ireg[0x32] == -1) {
-                               r->ireg[0x32] = mainWindow.xsize; r->ireg[0x34] &= 0;
-                       }
-                       if (r->ireg[0x33] == -1) {
-                               r->ireg[0x33] = mainWindow.ysize; r->ireg[0x35] &= 0;
-                       }
-                       checkRect(r, 0x32);
-                       double dcx = 0.5 * (r->ireg[0x32] - 1);
-                       double dcy = 0.5 * (r->ireg[0x33] - 1);
-                       double dcxy = (dcx + 0.5) * (dcy + 0.5) - 0.1;
-                       dcxy *= dcxy;
-                       mod3 = r->ireg[0x31] & 3;
-                       x1 = r->ireg[0x32];
-                       y1 = r->ireg[0x33];
-                       if (mod3 == 0 && (r->ireg[0x31] & 0x20) == 0) {
-                               for (y = 0; y < y1; y++) {
-                                       double dty = (y - dcy) * dcx;
-                                       for (x = 0; x < x1; x++) {
-                                               double dtx = (x - dcx) * dcy;
-                                               if (dtx * dtx + dty * dty > dcxy){
-                                                       continue;
-                                               }
-                                               mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] = c;
-                                       }
-                               }
-                       } else {
-#define DRAWOVALPARAM  1
-                               double dcx1 = 0.5 * (r->ireg[0x32] - (1 + DRAWOVALPARAM * 2));
-                               double dcy1 = 0.5 * (r->ireg[0x33] - (1 + DRAWOVALPARAM * 2));
-                               double dcxy1 = (dcx1 + 0.5) * (dcy1 + 0.5) - 0.1;
-                               dcxy1 *= dcxy1;
-                               for (y = 0; y < y1; y++) {
-                                       double dty = (y - dcy) * dcx;
-                                       double dty1 = (y - dcy) * dcx1;
-                                       for (x = 0; x < x1; x++) {
-                                               double dtx = (x - dcx) * dcy;
-                                               double dtx1 = (x - dcx) * dcy1;
-                                               if (dtx * dtx + dty * dty > dcxy){
-                                                       continue;
-                                               }
-                                               if (DRAWOVALPARAM <= x && x < x1 - DRAWOVALPARAM && DRAWOVALPARAM <= y && y < y1 - DRAWOVALPARAM) {
-                                                       if (dtx1 * dtx1 + dty1 * dty1 < dcxy1){
-                                                               continue;
-                                                       }
-                                               }
-                                               switch (mod3) {
-                                                       case 0:
-                                                               mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] = c;
-                                                               break;
-                                                       case 1:
-                                                               mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] |= c;
-                                                               break;
-                                                       case 2:
-                                                               mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] ^= c;
-                                                               break;
-                                                       case 3:
-                                                               mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] &= c;
-                                                               break;
-                                               }
-                                       }
-                               }
-                       }
-                       break;
-                       
-               case 0xff48:
-                       // drawString(opt:R31, xsiz:R32, ysiz:R33, x0:R34, y0:R35, c:R36, s.len:R37, s.p:P31)
-                       checkString(r, 0x37, 0x31);
-                       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);
-                       break;
-                       
-               case 0xff49:
-                       // junkApi_rand(_r, range) R31=range; _r=R30
-                       // **** junkApi_rand(i, max) ****
-                       // 0 <= i <= maxとなるiを返す。
-                       // max==0のとき、iはSINT32全体を範囲とする乱数となる。
-                       r->ireg[0x30] = randGetNextUInt32();
-                       if (r->ireg[0x31] > 0){
-                               r->ireg[0x30] = (r->ireg[0x30] & 0x7fffffff) % (r->ireg[0x31] + 1);
-                       }
-                       break;
-                       
-               case 0xff4a:
-                       // srand
-                       randStatInit(r->ireg[0x31]);
-                       break;
-                       
-               case 0xff4b:
-                       // srand(random)
-                       r->ireg[0x30] = (int)(time(NULL) ^ (long)0x55555555);
-                       break;
-                       
-               case 0xff4c:
-                       // drawStringDec
-                       checkString(r, 0x37, 0x31);
-                       len = devFunc0016(sizeof pucbuf, pucbuf, r->ireg[0x37], r->preg[0x31].p, r->ireg[0x38], (int *)r->preg[0x32].p, r);
-                       devFunc0006(r->ireg[0x31], r->ireg[0x32], r->ireg[0x33], r->ireg[0x34], r->ireg[0x35], loadColor(r, 0x36), len, pucbuf, r);
-                       break;
-                       
-               case 0xff4d:
-                       // bitblt(mod, xsiz, ysiz, xscale, yscale, x0, y0, lineskip, inv, p_buf, typ0, p_table, typ1); 
-                       // mod: 0x20:use_table, 0x40:inv_is_visible & typ1_is_color
-                       puc = r->preg[0x31].p;
-                       mod3 = r->ireg[0x31] & 3;
-                       dx = r->ireg[0x34];
-                       dy = r->ireg[0x35];
-                       if (dy == 0){
-                               dy = dx;
-                       }
-                       if (r->ireg[0x32] == -1) {
-                               r->ireg[0x32] = mainWindow.xsize / dx; r->ireg[0x36] &= 0;
-                       }
-                       if (r->ireg[0x33] == -1) {
-                               r->ireg[0x33] = mainWindow.ysize / dy; r->ireg[0x37] &= 0;
-                       }
-                       for (y = 0; y < r->ireg[0x33]; y++) {
-                               y0 = y * dy + r->ireg[0x37];
-                               for (x = 0; x < r->ireg[0x32]; x++) {
-                                       x0 = x * dx + r->ireg[0x36];
-                                       c = iColor1[*puc++];
-                                       devFunc0004(mod3, x0, y0, x0 + dx, y0 + dy, c);
-                               }
-                               puc += r->ireg[0x38];
-                       }
-                       break;
-                       
-               default:
-                       printf("devFunc: error: R30=%08X\n", r->ireg[0x30]);
-                       exit(EXIT_FAILURE);
-                       
-       }
-       return;
-}
-
-
-
+#include "osecpu.h"\r
+#include "jitc.h"\r
+\r
+extern unsigned char fontdata[];    // @fontdata.c\r
+\r
+const char *searchArg(int argc, const char **argv, const char *tag, int i)\r
+{\r
+       // 引数リストargvの中から、文字列tagが前方一致する引数のi番目を探し出し、\r
+       // その引数の文字列の、tagに続く部分の文字へのポインタを返す。\r
+       int j, l;\r
+       const char *r = NULL;\r
+       \r
+       if (tag != NULL) {\r
+               l = (int)strlen(tag);\r
+               for (j = 1; j < argc; j++) {\r
+                       if (strncmp(argv[j], tag, l) == 0) {\r
+                               r = argv[j] + l;\r
+                               if (i == 0){\r
+                                       break;\r
+                               }\r
+                               i--;\r
+                       }\r
+               }\r
+       }\r
+       /*\r
+        // 未使用\r
+       else {\r
+               for (j = 1; j < argc; j++) {\r
+                       if (strchr(argv[j], ':') == NULL) {\r
+                               r = argv[j];\r
+                               if (i == 0){\r
+                                       break;\r
+                               }\r
+                               i--;\r
+                       }\r
+               }\r
+       }\r
+        */\r
+       if (i != 0){\r
+               r = NULL;\r
+       }\r
+       return r;\r
+}\r
+\r
+void devFunc0001(int len, unsigned char *puc, HOSECPU_RuntimeEnvironment *r)\r
+{\r
+       // OSASK文字列の出力\r
+       while (len > 0) {\r
+               putOsaskChar(*puc++, r);\r
+               len--;\r
+       }\r
+       return;\r
+}\r
+\r
+void devFunc0006(int mod, int sx, int sy, int x, int y, int c, int len, unsigned char *puc, HOSECPU_RuntimeEnvironment *r)\r
+{\r
+       // drawString\r
+       int xx;\r
+       int yy;\r
+       int i, ddx, ddy, j, ch, dx, dy;\r
+       \r
+       if (sy == 0){\r
+               sy = sx;\r
+       }\r
+       xx = x + sx * 8;\r
+       yy = y + sy * 16;\r
+       if (xx <= 0 || xx > mainWindow.xsize || yy <= 0 || yy > mainWindow.ysize){\r
+               (*(r->errHndl))(r);\r
+       }\r
+       if (x < 0 || x >= mainWindow.xsize || y < 0 || y >= mainWindow.ysize){\r
+               (*(r->errHndl))(r);\r
+       }\r
+       \r
+       \r
+       if ((mod & 3) == 0 && sx == 1 && sy == 1) {\r
+               // メジャーケースを高速化.\r
+               for (i = 0; i < len; i++) {\r
+                       ch = puc[i];\r
+                       if (0x10 <= ch && ch <= 0x1f)\r
+                               ch = "0123456789ABCDEF"[ch & 0x0f];\r
+                       for (dy = 0; dy < 16; dy++) {\r
+                               j = fontdata[(ch - ' ') * 16 + dy];\r
+                               for (dx = 0; dx < 8; dx++) {\r
+                                       if ((j & (0x80 >> dx)) != 0){\r
+                                               mainWindow.vram[(x + dx) + (y + dy) * mainWindow.xsize] = c;\r
+                                       }\r
+                               }\r
+                       }\r
+                       x += 8;\r
+               }\r
+               return;\r
+       }\r
+       for (i = 0; i < len; i++) {\r
+               ch = puc[i];\r
+               if (0x10 <= ch && ch <= 0x1f)\r
+                       ch = "0123456789ABCDEF"[ch & 0x0f];\r
+               for (dy = 0; dy < 16; dy++) {\r
+                       j = fontdata[(ch - ' ') * 16 + dy];\r
+                       for (ddy = 0; ddy < sy; ddy++) {\r
+                               for (dx = 0; dx < 8; dx++) {\r
+                                       if ((j & (0x80 >> dx)) != 0) {\r
+                                               for (ddx = 0; ddx < sx; ddx++) {\r
+                                                       switch (mod & 3) {\r
+                                                               case 0:\r
+                                                                       mainWindow.vram[x + y * mainWindow.xsize] = c;\r
+                                                                       break;\r
+                                                               case 1:\r
+                                                                       mainWindow.vram[x + y * mainWindow.xsize] |= c;\r
+                                                                       break;\r
+                                                               case 2:\r
+                                                                       mainWindow.vram[x + y * mainWindow.xsize] ^= c;\r
+                                                                       break;\r
+                                                               case 3:\r
+                                                                       mainWindow.vram[x + y * mainWindow.xsize] &= c;\r
+                                                                       break;\r
+                                                       }\r
+                                                       x++;\r
+                                               }\r
+                                       } else{\r
+                                               x += sx;\r
+                                       }\r
+                               }\r
+                               x -= sx * 8;\r
+                               y++;\r
+                       }\r
+               }\r
+               x += sx * 8;\r
+               y -= sy * 16;\r
+       }\r
+       return;\r
+}\r
+\r
+void devFunc0004(int mod, int x0, int y0, int x1, int y1, int c)\r
+{\r
+       // FillRect\r
+       int x, y;\r
+       if (mod == 0) {\r
+               for (y = y0; y <= y1; y++) {\r
+                       for (x = x0; x <= x1; x++) {\r
+                               mainWindow.vram[x + y * mainWindow.xsize] = c;\r
+                       }\r
+               }\r
+       }\r
+       else {\r
+               for (y = y0; y <= y1; y++) {\r
+                       for (x = x0; x <= x1; x++) {\r
+                               switch (mod) {\r
+                                       case 1:\r
+                                               mainWindow.vram[x + y * mainWindow.xsize] |= c;\r
+                                               break;\r
+                                       case 2:\r
+                                               mainWindow.vram[x + y * mainWindow.xsize] ^= c;\r
+                                               break;\r
+                                       case 3:\r
+                                               mainWindow.vram[x + y * mainWindow.xsize] &= c;\r
+                                               break;\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+       return;\r
+}\r
+\r
+int devFunc0016(int buflen, unsigned char *buf, int plen, unsigned char *p, int qlen, int *q, HOSECPU_RuntimeEnvironment *r)\r
+{\r
+       // OSASK文字列への変換?\r
+       int i = 0, base, j, k;\r
+       char sign;\r
+       \r
+       while (plen > 0) {\r
+               if (i >= buflen){\r
+                       (*(r->errHndl))(r);\r
+               }\r
+               if (*p != 0x01) {\r
+                       buf[i++] = *p++;\r
+                       plen--;\r
+                       continue;\r
+               }\r
+               p++;\r
+               plen--;\r
+               if (qlen < 4){\r
+                       (*(r->errHndl))(r);\r
+               }\r
+               base = q[0];\r
+               sign = 0;\r
+               if (base == 0){\r
+                       base = 16;\r
+               }\r
+#if (REVISION == 1)\r
+               if (base == -3){\r
+                       base = 10;\r
+               }\r
+#endif\r
+               if (base == -1){\r
+                       base = 10;\r
+               }\r
+               if (base < 0 || base > 16){\r
+                       (*(r->errHndl))(r);\r
+               }\r
+               if (q[1] + i > buflen){\r
+                       (*(r->errHndl))(r);\r
+               }\r
+               j = q[3];\r
+               if ((q[2] & 4) == 0) {\r
+                       // jは符号付き整数.\r
+                       if ((q[2] & 8) != 0 && j > 0){\r
+                               sign = '+';\r
+                       }\r
+                       if (j < 0) {\r
+                               sign = '-'; j *= -1;\r
+                       }\r
+               } else{\r
+                       // jは符号無し整数.\r
+                       if ((q[2] & 8) != 0 && j != 0){\r
+                               sign = '+';\r
+                       }\r
+               }\r
+               for (k = q[1] - 1; k >= 0; k--) {\r
+                       buf[i + k] = (j % base) + 0x10;\r
+                       j = ((unsigned)j) / base;\r
+               }\r
+               k = 0;\r
+               if ((q[2] & 2) == 0 && j == 0) {\r
+                       for (k = 0; k < q[1] - 1; k++) {\r
+                               if (buf[i + k] != 0x10){\r
+                                       break;\r
+                               }\r
+                               buf[i + k] = ' ';\r
+                       }\r
+               }\r
+               if (sign != 0) {\r
+                       if (k > 0){\r
+                               k--;\r
+                       }\r
+                       buf[i + k] = sign;\r
+               }\r
+               if ((q[2] & 1) != 0 && buf[i] == ' ') {\r
+                       for (j = 0; k < q[1]; k++, j++){\r
+                               buf[i + j] = buf[i + k];\r
+                       }\r
+                       i += j;\r
+               } else{\r
+                       i += q[1];\r
+               }\r
+               qlen -= 4;\r
+               q += 4;\r
+       }\r
+       return i;\r
+}\r
+\r
+void devFunc(HOSECPU_RuntimeEnvironment *r)\r
+{\r
+       FILE *fp;\r
+       int i, c;\r
+       int x, y, len, dx, dy;\r
+       unsigned char *puc;\r
+       unsigned char pucbuf[256];\r
+       \r
+       //サイズを節約するためにEBPを128バイトずらしているのを元に戻す\r
+       r = (HOSECPU_RuntimeEnvironment *) (((char *)r) - jitCompA0001_EBP128);\r
+       \r
+       if (r->winClosed != 0){\r
+               longjmp(r->setjmpEnv, 1);\r
+       }\r
+       if (0xff44 <= r->ireg[0x30] && r->ireg[0x30] <= 0xff48) {\r
+               if (mainWindow.vram == NULL) {\r
+                       mainWindow.xsize = 640;\r
+                       mainWindow.ysize = 480;\r
+                       mainWindow.vram = malloc(640 * 480 * 4);\r
+                       drv_openWin(640, 480, (void *)mainWindow.vram, &r->winClosed);\r
+                       r->autoSleep = 1;\r
+                       for (i = 640 * 480 - 1; i >= 0; i--){\r
+                               mainWindow.vram[i] = 0;\r
+                       }\r
+               }\r
+       }\r
+       \r
+       switch (r->ireg[0x30]){\r
+               case 0xff00:\r
+                       printf("R31=%d(dec)\n", r->ireg[0x31]);\r
+                       break;\r
+                       \r
+               case 0xff01:\r
+                       // junkApi_fopenRead(_filesize, _p, arg)\r
+                       // args: R31=arg, R30=_filesize, P31=_p\r
+                       // retv: R30, P31\r
+                       if (r->buf0 == NULL){\r
+                               r->buf0 = malloc(1024 * 1024);\r
+                       }\r
+                       if (r->mainArgc <= r->ireg[0x31]) {\r
+                               fprintf(stderr, "devFunc: error: R30=ff01: argc error: R31=%08X\n", r->ireg[0x31]);\r
+                               exit(1);\r
+                       }\r
+                       fp = fopen(r->mainArgv[r->ireg[0x31]], "rb");\r
+                       if (fp == NULL) {\r
+                               fprintf(stderr, "devFunc: error: R30=ff01: fopen error: '%s'\n", r->mainArgv[r->ireg[0x31]]);\r
+                               exit(1);\r
+                       }\r
+                       i = (int)fread(r->buf0, 1, 1024 * 1024 - 4, fp);\r
+                       if (i >= 1024 * 1024 - 4 || i < 0) {\r
+                               fprintf(stderr, "devFunc: error: R30=ff01: fread error: '%s'\n", r->mainArgv[r->ireg[0x31]]);\r
+                               exit(1);\r
+                       }\r
+                       fclose(fp);\r
+                       r->preg[0x31].p = r->buf0;\r
+                       r->preg[0x31].p0 = r->buf0;\r
+                       r->preg[0x31].p1 = r->buf0 + i;\r
+                       r->preg[0x31].typ = 3; // T_UINT8\r
+                       r->ireg[0x30] = i;\r
+                       break;\r
+                       \r
+               case 0xff02:\r
+                       // junkApi_fopenWrite(arg, filesize, p)\r
+                       // args: R31=arg, R32=filesize, P31=p\r
+                       // retv: (none)\r
+                       if (r->mainArgc <= r->ireg[0x31]) {\r
+                               fprintf(stderr, "devFunc: error: R30=ff02: argc error: R31=%08X\n", r->ireg[0x31]);\r
+                               exit(1);\r
+                       }\r
+                       fp = fopen(r->mainArgv[r->ireg[0x31]], "wb");\r
+                       if (fp == NULL) {\r
+                               fprintf(stderr, "devFunc: error: R30=ff02: fopen error: '%s'\n", r->mainArgv[r->ireg[0x31]]);\r
+                               exit(1);\r
+                       }\r
+                       if (r->ireg[0x32] >= 1024 * 1024 || r->ireg[0x32] < 0){\r
+                               fprintf(stderr, "devFunc: error: R30=ff02: fwrite error: R02=%08X\n", r->ireg[0x32]);\r
+                               exit(1);\r
+                       }\r
+                       fwrite(r->preg[0x31].p, 1, r->ireg[0x32], fp);\r
+                       fclose(fp);\r
+                       break;\r
+                       \r
+               case 0xff03:\r
+                       // junkApi_allocBuf(_p)\r
+                       // args: P31=_p\r
+                       // retv: P31\r
+                       if (r->buf1 == NULL){\r
+                               r->buf1 = malloc(1024 * 1024);\r
+                       }\r
+                       r->preg[0x31].p = r->buf1;\r
+                       r->preg[0x31].p0 = r->buf1;\r
+                       r->preg[0x31].p1 = r->buf1 + 1024 * 1024;\r
+                       break;\r
+                       \r
+               case 0xff04:\r
+                       printf("P31.(p-p0)=%d(dec)\n", (int)(r->preg[0x31].p - r->preg[0x31].p0));\r
+                       break;\r
+                       \r
+               case 0xff05:\r
+                       // junkApi_writeStdout(len, p)\r
+                       // args: R31=len, P31=p\r
+                       // retv: (none)\r
+                       fwrite(r->preg[0x31].p, 1, r->ireg[0x31], stdout);\r
+                       break;\r
+                       \r
+               case 0xff06:\r
+                       // junkApi_exit(i)\r
+                       // args: R31=i\r
+                       // retv: (none)\r
+                       r->appReturnCode = r->ireg[31];\r
+                       longjmp(r->setjmpEnv, 1);\r
+                       break;\r
+                       \r
+               case 0xff07:\r
+                       // junkApi_putConstString0(s)\r
+                       // DB(0xff,0x00,0x00); DB%(s,0x00);\r
+                       // マシになった文字列表示.\r
+                       // OSASK文字列に対応.offにすれば通常の文字列処理もできる.\r
+                       // 現状はonのみサポート.\r
+                       checkString(r, 0x31, 0x31);\r
+                       devFunc0001(r->ireg[0x31], r->preg[0x31].p, r);\r
+                       break;\r
+                       \r
+               case 0xff08:\r
+                       // junkApi_jitc2(_rc, _p, mod, lev, di1, len, s)\r
+                       // R31=mod; R32=lev; R33=di1; R34=len; P31=s; _rc=R30; _p=P31\r
+                       // JITC on JITC\r
+                       // R31: 言語(back-end, front-end, ...\r
+                       // R32: level\r
+                       // R33: debugInfo1\r
+                       checkString(r, 0x34, 0x31);\r
+                       if (r->ireg[0x33] < 0 || r->ireg[0x33] > 15 || r->debugInfo1 > 15){\r
+                               (*(r->errHndl))(r);\r
+                       }\r
+                       for (i = 0; i < r->maxLabels; i++){\r
+                               r->label[i].opt = 0;\r
+                       }\r
+                       puc = r->preg[0x31].p;\r
+                       i = jitCompiler(r->jitbuf, r->jitbuf1, puc, puc + r->ireg[0x34], puc, r->label, r->maxLabels, r->ireg[0x32], di1_serial, JITC_NOSTARTUP + 0);\r
+                       if (i == 0) {\r
+                               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);\r
+                               if (i >= 0) {\r
+                                       r->mapDi1s[r->debugInfo1][r->ireg[0x33]] = di1_serial;\r
+                                       di1_serial++;\r
+                                       r->ireg[0x30] = 0;\r
+                                       r->preg[0x31].p = r->jitbuf;\r
+                                       r->preg[0x31].typ = 0; // TYP_CODE\r
+                                       r->preg[0x31].p0 = r->jitbuf;\r
+                                       r->preg[0x31].p1 = r->jitbuf + 1;\r
+                                       //int j; for (j = 0; j < i; j++) printf("%02X ", r->jitbuf[j]); putchar('\n');\r
+                                       r->jitbuf += i;\r
+                                       static unsigned char ff08_ret[3] = { 0x1e, 0x3f, 0x30 };\r
+                                       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);\r
+                                       r->jitbuf += i;\r
+                                       break;\r
+                               }\r
+                       }\r
+                       r->ireg[0x30] = -1;\r
+                       break;\r
+                       \r
+               case 0xff09:\r
+                       //putStringDec\r
+                       // たぶんbit7を使ったテキストはうまく処理できない(これはもはや仕様にしても問題ないかも).\r
+                       checkString(r, 0x31, 0x31);\r
+                       len = devFunc0016(sizeof pucbuf, pucbuf, r->ireg[0x31], r->preg[0x31].p, r->ireg[0x32], (int *)r->preg[0x32].p, r);\r
+                       devFunc0001(len, pucbuf, r);\r
+                       break;\r
+                       \r
+               case 0xff40:\r
+                       // junkApi_openWin(xsiz, ysiz) R31=xsiz; R32=ysiz;\r
+                       /* R31とR32でサイズを指定 */\r
+                       mainWindow.xsize = r->ireg[0x31];\r
+                       mainWindow.ysize = r->ireg[0x32];\r
+                       if (mainWindow.xsize <= 0 || mainWindow.ysize <= 0){\r
+                               (*(r->errHndl))(r);\r
+                       }\r
+                       r->preg[0x31].p = (void *)(mainWindow.vram = malloc(mainWindow.xsize * mainWindow.ysize * 4));\r
+                       r->preg[0x31].p0 = r->preg[0x31].p;\r
+                       r->preg[0x31].p1 = r->preg[0x31].p + mainWindow.xsize * mainWindow.ysize * 4;\r
+                       drv_openWin(r->ireg[0x31], r->ireg[0x32], r->preg[0x31].p, &r->winClosed);\r
+                       //      drv_flshWin(r->ireg[1], r->ireg[2], 0, 0);\r
+                       r->autoSleep = 1;\r
+                       for (i = mainWindow.xsize * mainWindow.ysize - 1; i >= 0; i--){\r
+                               mainWindow.vram[i] = 0;\r
+                       }\r
+                       break;\r
+                       \r
+               case 0xff41:\r
+                       // junkApi_flushWin(xsiz, ysiz, x0, y0)\r
+                       // R31=xsiz; R32=ysiz; R33=x0; R34=y0\r
+                       /* R31とR32でサイズを指定、R33とR34でx0,y0指定 */\r
+                       if (r->ireg[0x31] == -1) {\r
+                               r->ireg[0x31] = mainWindow.xsize; r->ireg[0x33] &= 0;\r
+                       }\r
+                       if (r->ireg[0x32] == -1) {\r
+                               r->ireg[0x32] = mainWindow.ysize; r->ireg[0x34] &= 0;\r
+                       }\r
+                       checkRect(r, 0x31);\r
+                       drv_flshWin(r->ireg[0x31], r->ireg[0x32], r->ireg[0x33], r->ireg[0x34]);\r
+                       break;\r
+                       \r
+               case 0xff42:\r
+                       // junkApi_sleep(opt, msec) R31=opt; R32=msec\r
+                       // opt:\r
+                       //              1 = ついでにウィンドウを更新する\r
+                       //              2 = キー入力されるまでずっと待つ\r
+                       if (r->ireg[0x32] == -1) {\r
+                               // sleep forever (事実上実行は終了)\r
+                               r->autoSleep = 1;\r
+                               longjmp(r->setjmpEnv, 1);\r
+                       }\r
+                       if (r->ireg[0x32] < 0){\r
+                               // マイナス秒スリープするなんておかしい\r
+                               (*(r->errHndl))(r);\r
+                       }\r
+                       //スリープしたので終了時の自動スリープ無効\r
+                       r->autoSleep = 0;\r
+                       if ((r->ireg[0x31] & 1) == 0 && mainWindow.vram != NULL){\r
+                               // opt1:ついでにウィンドウを更新する\r
+                               drv_flshWin(mainWindow.xsize, mainWindow.ysize, 0, 0);\r
+                       }\r
+                       for (;;) {\r
+                               if (r->winClosed != 0){\r
+                                       longjmp(r->setjmpEnv, 1);\r
+                               }\r
+                               drv_sleep(r->ireg[0x32]);\r
+                               if ((r->ireg[0x31] & 2) != 0 && keybuf_c <= 0){\r
+                                       // opt2:キー入力があったので戻る\r
+                                       continue;\r
+                               }\r
+                               // 時間指定ならここに来て終了\r
+                               break;\r
+                       }\r
+                       break;\r
+                       \r
+               case 0xff43:\r
+                       // junkApi_inkey(_i, mod) R31=mod; _i=R30\r
+                       //  1:peek(キーを「のぞき見る」だけで、バッファは進めない)\r
+                       //  2:stdin\r
+                       //      4,8: ソース指定.\r
+                       //      16: shift, lock系を有効化.\r
+                       //      32: 左右のshift系を区別する.\r
+                       // カーソルキーの左右でR32は減少,増加する。\r
+                       // カーソルキーの上下でR33は減少,増加する。\r
+                       if (r->ireg[0x31] == 2) {\r
+                               // 標準入力から\r
+                               r->ireg[0x30] = fgetc(stdin);\r
+                               if (r->ireg[0x30] == EOF){\r
+                                       r->ireg[0x30] = KEY_EMPTY;\r
+                               }\r
+                               break;\r
+                       }\r
+                       r->ireg[0x30] |= -1;\r
+                       if (keybuf_c > 0) {\r
+                               // 入力された文字がある\r
+                               r->ireg[0x30] = keybuf[keybuf_r];\r
+                               if ((r->ireg[0x31] & 16) == 0){\r
+                                       // shift, lockキー([C]マークのあるキー)の無効化\r
+                                       r->ireg[0x30] &= 0x3e3effff;\r
+                               }\r
+                               if ((r->ireg[0x31] & 32) == 0){\r
+                                       // 左右の区別を無効化\r
+                                       r->ireg[0x30] |= (r->ireg[0x30] >> 8) & 0xff0000;\r
+                               }\r
+                               if ((r->ireg[0x31] & 1) != 0) {\r
+                                       // peekでないならバッファを進める\r
+                                       keybuf_c--;\r
+                                       keybuf_r = (keybuf_r + 1) & (KEYBUFSIZ - 1);\r
+                               }\r
+                       }\r
+                       r->ireg[0x32] = r->ireg[0x33] = 0;\r
+                       if (r->ireg[0x30] == KEY_LEFT){\r
+                               r->ireg[0x32]--;\r
+                       }\r
+                       if (r->ireg[0x30] == KEY_UP){\r
+                               r->ireg[0x33]--;\r
+                       }\r
+                       if (r->ireg[0x30] == KEY_RIGHT){\r
+                               r->ireg[0x32]++;\r
+                       }\r
+                       if (r->ireg[0x30] == KEY_DOWN){\r
+                               r->ireg[0x33]++;\r
+                       }\r
+                       break;\r
+                       \r
+               case 0xff44:\r
+                       // junkApi_drawPoint(mod, x, y, c) R31=mod; R32=x; R33=y; R34=c\r
+                       c = loadColor(r, 0x34);\r
+                       if (r->ireg[0x32] < 0 || r->ireg[0x32] >= mainWindow.xsize ||\r
+                               r->ireg[0x33] < 0 || r->ireg[0x33] >= mainWindow.ysize){\r
+                               (*(r->errHndl))(r);\r
+                       }\r
+                       \r
+                       switch ((r->ireg[0x31] & 3)) {\r
+                               case 0:\r
+                                       mainWindow.vram[r->ireg[0x32] + r->ireg[0x33] * mainWindow.xsize] = c;\r
+                                       break;\r
+                               case 1:\r
+                                       mainWindow.vram[r->ireg[0x32] + r->ireg[0x33] * mainWindow.xsize] |= c;\r
+                                       break;\r
+                               case 2:\r
+                                       mainWindow.vram[r->ireg[0x32] + r->ireg[0x33] * mainWindow.xsize] ^= c;\r
+                                       break;\r
+                               case 3:\r
+                                       mainWindow.vram[r->ireg[0x32] + r->ireg[0x33] * mainWindow.xsize] &= c;\r
+                                       break;\r
+                       }\r
+                       break;\r
+                       \r
+               case 0xff45:\r
+                       // junkApi_drawLine(mod, x0, y0, x1, y1, c)     DB(0xfe,0x05,0x01); DDBE(0x0003); R30=0xff45; R31=mod; R32=x0; R33=y0; R34=x1; R35=y1; R36=c\r
+                       //drawLine\r
+                       c = loadColor(r, 0x36);\r
+                       if (r->ireg[0x32] < 0 || r->ireg[0x32] >= mainWindow.xsize ||\r
+                               r->ireg[0x33] < 0 || r->ireg[0x33] >= mainWindow.ysize){\r
+                               (*(r->errHndl))(r);\r
+                       }\r
+                       if (r->ireg[0x34] < 0 || r->ireg[0x34] >= mainWindow.xsize ||\r
+                               r->ireg[0x35] < 0 || r->ireg[0x35] >= mainWindow.ysize){\r
+                               (*(r->errHndl))(r);\r
+                       }\r
+                       dx = r->ireg[0x34] - r->ireg[0x32];\r
+                       dy = r->ireg[0x35] - r->ireg[0x33];\r
+                       x = r->ireg[0x32] << 10;\r
+                       y = r->ireg[0x33] << 10;\r
+                       if (dx < 0){\r
+                               dx = -dx;\r
+                       }\r
+                       if (dy < 0){\r
+                               dy = -dy;\r
+                       }\r
+                       if (dx >= dy) {\r
+                               len = dx + 1; dx = 1024;\r
+                               if (r->ireg[0x32] > r->ireg[0x34]){\r
+                                       dx *= -1;\r
+                               }\r
+                               if (r->ireg[0x33] > r->ireg[0x35]){\r
+                                       dy *= -1;\r
+                               }\r
+                               dy = (dy << 10) / len;\r
+                       } else {\r
+                               len = dy + 1; dy = 1024;\r
+                               if (r->ireg[0x33] > r->ireg[0x35]){\r
+                                       dy *= -1;\r
+                               }\r
+                               if (r->ireg[0x32] > r->ireg[0x34]){\r
+                                       dx *= -1;\r
+                               }\r
+                               dx = (dx << 10) / len;\r
+                       }\r
+                       if ((r->ireg[0x31] & 3) == 0) {\r
+                               for (i = 0; i < len; i++) {\r
+                                       mainWindow.vram[(x >> 10) + (y >> 10) * mainWindow.xsize] = c;\r
+                                       x += dx;\r
+                                       y += dy;\r
+                               }\r
+                               break;\r
+                       }\r
+                       for (i = 0; i < len; i++) {\r
+                               //      if ((r->ireg[0x31] & 3) == 0) vram[(x >> 10) + (y >> 10) * v_xsiz] =  c;\r
+                               switch ((r->ireg[0x31] & 3)) {\r
+                                       case 1:\r
+                                               mainWindow.vram[(x >> 10) + (y >> 10) * mainWindow.xsize] |= c;\r
+                                               break;\r
+                                       case 2:\r
+                                               mainWindow.vram[(x >> 10) + (y >> 10) * mainWindow.xsize] ^= c;\r
+                                               break;\r
+                                       case 3:\r
+                                               mainWindow.vram[(x >> 10) + (y >> 10) * mainWindow.xsize] &= c;\r
+                                               break;\r
+                                       default:\r
+                                               break;\r
+                               }\r
+                               x += dx;\r
+                               y += dy;\r
+                       }\r
+                       break;\r
+                       \r
+               case 0xff46:\r
+                       // fillRect(opt:R31, xsiz:R32, ysiz:R33, x0:R34, y0:R35, c:R36)\r
+                       c = loadColor(r, 0x36);\r
+                       if (r->ireg[0x32] == -1) { r->ireg[0x32] = mainWindow.xsize; r->ireg[0x34] &= 0; }\r
+                       if (r->ireg[0x33] == -1) { r->ireg[0x33] = mainWindow.ysize; r->ireg[0x35] &= 0; }\r
+                       checkRect(r, 0x32);\r
+                       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;\r
+                       if ((r->ireg[0x31] & 0x20) == 0) {\r
+                               devFunc0004(mod3, x0, y0, x1, y1, c);\r
+                       } else {        // drawRect\r
+                               devFunc0004(mod3, x0, y0, x1, y0, c);\r
+                               devFunc0004(mod3, x0, y1, x1, y1, c);\r
+                               devFunc0004(mod3, x0, y0, x0, y1, c);\r
+                               devFunc0004(mod3, x1, y0, x1, y1, c);\r
+                       }\r
+                       break;\r
+                       \r
+               case 0xff47:\r
+                       // fillOval(opt:R31, xsiz:R32, ysiz:R33, x0:R34, y0:R35, c:R36)\r
+                       // これの計算精度はアーキテクチャに依存する.\r
+                       c = loadColor(r, 0x36);\r
+                       if (r->ireg[0x32] == -1) {\r
+                               r->ireg[0x32] = mainWindow.xsize; r->ireg[0x34] &= 0;\r
+                       }\r
+                       if (r->ireg[0x33] == -1) {\r
+                               r->ireg[0x33] = mainWindow.ysize; r->ireg[0x35] &= 0;\r
+                       }\r
+                       checkRect(r, 0x32);\r
+                       double dcx = 0.5 * (r->ireg[0x32] - 1);\r
+                       double dcy = 0.5 * (r->ireg[0x33] - 1);\r
+                       double dcxy = (dcx + 0.5) * (dcy + 0.5) - 0.1;\r
+                       dcxy *= dcxy;\r
+                       mod3 = r->ireg[0x31] & 3;\r
+                       x1 = r->ireg[0x32];\r
+                       y1 = r->ireg[0x33];\r
+                       if (mod3 == 0 && (r->ireg[0x31] & 0x20) == 0) {\r
+                               for (y = 0; y < y1; y++) {\r
+                                       double dty = (y - dcy) * dcx;\r
+                                       for (x = 0; x < x1; x++) {\r
+                                               double dtx = (x - dcx) * dcy;\r
+                                               if (dtx * dtx + dty * dty > dcxy){\r
+                                                       continue;\r
+                                               }\r
+                                               mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] = c;\r
+                                       }\r
+                               }\r
+                       } else {\r
+#define DRAWOVALPARAM  1\r
+                               double dcx1 = 0.5 * (r->ireg[0x32] - (1 + DRAWOVALPARAM * 2));\r
+                               double dcy1 = 0.5 * (r->ireg[0x33] - (1 + DRAWOVALPARAM * 2));\r
+                               double dcxy1 = (dcx1 + 0.5) * (dcy1 + 0.5) - 0.1;\r
+                               dcxy1 *= dcxy1;\r
+                               for (y = 0; y < y1; y++) {\r
+                                       double dty = (y - dcy) * dcx;\r
+                                       double dty1 = (y - dcy) * dcx1;\r
+                                       for (x = 0; x < x1; x++) {\r
+                                               double dtx = (x - dcx) * dcy;\r
+                                               double dtx1 = (x - dcx) * dcy1;\r
+                                               if (dtx * dtx + dty * dty > dcxy){\r
+                                                       continue;\r
+                                               }\r
+                                               if (DRAWOVALPARAM <= x && x < x1 - DRAWOVALPARAM && DRAWOVALPARAM <= y && y < y1 - DRAWOVALPARAM) {\r
+                                                       if (dtx1 * dtx1 + dty1 * dty1 < dcxy1){\r
+                                                               continue;\r
+                                                       }\r
+                                               }\r
+                                               switch (mod3) {\r
+                                                       case 0:\r
+                                                               mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] = c;\r
+                                                               break;\r
+                                                       case 1:\r
+                                                               mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] |= c;\r
+                                                               break;\r
+                                                       case 2:\r
+                                                               mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] ^= c;\r
+                                                               break;\r
+                                                       case 3:\r
+                                                               mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] &= c;\r
+                                                               break;\r
+                                               }\r
+                                       }\r
+                               }\r
+                       }\r
+                       break;\r
+                       \r
+               case 0xff48:\r
+                       // drawString(opt:R31, xsiz:R32, ysiz:R33, x0:R34, y0:R35, c:R36, s.len:R37, s.p:P31)\r
+                       checkString(r, 0x37, 0x31);\r
+                       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);\r
+                       break;\r
+                       \r
+               case 0xff49:\r
+                       // junkApi_rand(_r, range) R31=range; _r=R30\r
+                       // **** junkApi_rand(i, max) ****\r
+                       // 0 <= i <= maxとなるiを返す。\r
+                       // max==0のとき、iはSINT32全体を範囲とする乱数となる。\r
+                       r->ireg[0x30] = randGetNextUInt32();\r
+                       if (r->ireg[0x31] > 0){\r
+                               r->ireg[0x30] = (r->ireg[0x30] & 0x7fffffff) % (r->ireg[0x31] + 1);\r
+                       }\r
+                       break;\r
+                       \r
+               case 0xff4a:\r
+                       // srand\r
+                       randStatInit(r->ireg[0x31]);\r
+                       break;\r
+                       \r
+               case 0xff4b:\r
+                       // srand(random)\r
+                       r->ireg[0x30] = (int)(time(NULL) ^ (long)0x55555555);\r
+                       break;\r
+                       \r
+               case 0xff4c:\r
+                       // drawStringDec\r
+                       checkString(r, 0x37, 0x31);\r
+                       len = devFunc0016(sizeof pucbuf, pucbuf, r->ireg[0x37], r->preg[0x31].p, r->ireg[0x38], (int *)r->preg[0x32].p, r);\r
+                       devFunc0006(r->ireg[0x31], r->ireg[0x32], r->ireg[0x33], r->ireg[0x34], r->ireg[0x35], loadColor(r, 0x36), len, pucbuf, r);\r
+                       break;\r
+                       \r
+               case 0xff4d:\r
+                       // bitblt(mod, xsiz, ysiz, xscale, yscale, x0, y0, lineskip, inv, p_buf, typ0, p_table, typ1); \r
+                       // mod: 0x20:use_table, 0x40:inv_is_visible & typ1_is_color\r
+                       puc = r->preg[0x31].p;\r
+                       mod3 = r->ireg[0x31] & 3;\r
+                       dx = r->ireg[0x34];\r
+                       dy = r->ireg[0x35];\r
+                       if (dy == 0){\r
+                               dy = dx;\r
+                       }\r
+                       if (r->ireg[0x32] == -1) {\r
+                               r->ireg[0x32] = mainWindow.xsize / dx; r->ireg[0x36] &= 0;\r
+                       }\r
+                       if (r->ireg[0x33] == -1) {\r
+                               r->ireg[0x33] = mainWindow.ysize / dy; r->ireg[0x37] &= 0;\r
+                       }\r
+                       for (y = 0; y < r->ireg[0x33]; y++) {\r
+                               y0 = y * dy + r->ireg[0x37];\r
+                               for (x = 0; x < r->ireg[0x32]; x++) {\r
+                                       x0 = x * dx + r->ireg[0x36];\r
+                                       c = iColor1[*puc++];\r
+                                       devFunc0004(mod3, x0, y0, x0 + dx, y0 + dy, c);\r
+                               }\r
+                               puc += r->ireg[0x38];\r
+                       }\r
+                       break;\r
+                       \r
+               default:\r
+                       printf("devFunc: error: R30=%08X\n", r->ireg[0x30]);\r
+                       exit(EXIT_FAILURE);\r
+                       \r
+       }\r
+       return;\r
+}\r
+\r
+\r
+\r
diff --git a/main.c b/main.c
index 9cc56e6..f24bb70 100644 (file)
--- a/main.c
+++ b/main.c
-#include "osecpu.h"
-
-int *keybuf, keybuf_r, keybuf_w, keybuf_c;
-HOSECPU_Device_Window mainWindow;
-//デバッグ用。プログラム中の随所で加算される変数
-int di1_serial;
-HOSECPU_RuntimeEnvironment *dbg_env;
-
-
-
-unsigned char *Init_LoadSysLib(char argv0[], unsigned char *tmpWorkMemory);
-void LoadAppBin(HOSECPU_RuntimeEnvironment *env);
-
-void putKeybuf(int i)
-{
-       if (keybuf_c < KEYBUFSIZ) {
-               keybuf[keybuf_w] = i;
-               keybuf_c++;
-               keybuf_w = (keybuf_w + 1) & (KEYBUFSIZ - 1);
-       }
-       return;
-}
-
-int HeavyOSECPUMain(int argc, char **argv)
-{
-       HOSECPU_RuntimeEnvironment env;
-       FILE *fp;
-       unsigned char *jitbuf, *sysjit00, *sysjit;
-       unsigned char *systmp0, *systmp1, *systmp2;
-       unsigned char *opTbl;
-       HOSECPU_LabelListTag *label;
-       int tmpsiz, i;
-       double tm0, tm1, tm2;
-       HOSECPU_PointerControlTag *ptrCtrl;
-       unsigned char *syslib;
-       int argDebug = 0, stacksiz = 1;
-       const  char *cp;
-       void(*jitfunc)(char *);
-       unsigned char *jp;
-       
-       // For debug
-       dbg_env = &env;
-       
-       // Initialize mainWindow
-       mainWindow.vram = NULL;
-       mainWindow.xsize = 0;
-       mainWindow.ysize = 0;
-       di1_serial = 0;
-       
-       // 実行環境初期化
-       env.mainArgc = argc;
-       env.mainArgv = (const char **)argv;
-       env.appBin = malloc(APPSIZ1);
-       env.executionLevel = JITC_LV_SLOWEST;
-       jitbuf = mallocRWE(APPJITSIZE); /* とりあえず1MBで */
-       // syslib.oseのjitc結果を格納する領域を確保。
-       sysjit00 = mallocRWE(SYSJITSIZ1);
-       sysjit = sysjit00;
-       // 現在の、jitc結果を格納するメモリへの書き込み位置のアドレス
-       // sysjit: 現在のjitc書き込み位置
-       // sysjit00: jitc結果の先頭
-       //ワークメモリを三つくらいもらう
-       systmp0 = malloc(SYSTMP0SIZ);   /* syslibのjitc用 */
-       systmp1 = malloc(SYSTMP1SIZ);
-       systmp2 = malloc(1024 * 1024);
-       
-       opTbl = malloc(256);
-       label = malloc(JITC_MAXLABELS * sizeof (HOSECPU_LabelListTag));
-       keybuf = malloc(KEYBUFSIZ * sizeof (int));
-       keybuf_r = keybuf_w = keybuf_c = 0;
-       ptrCtrl = malloc(PTRCTRLSIZ * sizeof (HOSECPU_PointerControlTag));
-       
-       randStatInit((unsigned int)time(NULL));
-       for (i = 0; i < PTRCTRLSIZ; i++) {
-               ptrCtrl[i].liveSign = 0;
-               ptrCtrl[i].size = -1;
-       }
-       ptrCtrl[0].size = -2;
-       
-       /* syslibの読み込み */
-       syslib = Init_LoadSysLib(argv[0], systmp0);
-       
-       sysjit = jitCompInit(sysjit);
-       sysjit00 = sysjit;
-       // labelはjitc0()内で初期化される。
-       i = jitc0(&sysjit, sysjit00 + SYSJITSIZ1, syslib + 32, syslib + SYSLIBSIZ1, JITC_LV_SLOWEST+9, label);
-       if (i != 0){
-               fputs("syslib-file JITC error.\n", stderr);
-               return 1;
-       }
-       
-       // エラー時にデバッグ用に表示する変数を加算
-       di1_serial++;
-       
-       /* アプリバイナリの読み込み */
-       LoadAppBin(&env);
-       
-       /* クロック初期化 */
-       tm0 = clock() / (double)CLOCKS_PER_SEC;
-       
-       if (env.appBin[2] == 0xf0) {
-               // tek5圧縮がかかっている
-#if (USE_TEK5 != 0)
-               env.appSize1 = tek5Decomp(env.appBin + 2, env.appBin + env.appSize0, systmp0);
-               env.appSize1 += 2;
-#else
-               env.appSize1 = -9;
-#endif
-               if (env.appSize1 < 0) {
-                       fputs("unsupported-format(tek5)\n", stderr);
-                       return 1;
-               }
-       }
-       //デバッグモード指定
-       cp = searchArg(argc, (const char **)argv, "debug:", 0);
-       if (cp != NULL){
-               argDebug = *cp - '0';
-       }
-       //スタックサイズ指定(MiB単位)
-       cp = searchArg(argc, (const char **)argv, "stack:", 0);
-       if (cp != NULL){
-               stacksiz = strtol(cp, NULL, 0);
-       }
-
-       // jitbufは先頭。 jpは現在位置
-       jp = jitbuf; /* JIT-pointer */
-       
-       /* フロントエンドコードをバックエンドコードに変換する */
-       if ((env.appBin[2] & 0xf0) != 0) {                              // 3バイト目が00なら処理しない
-               systmp0[0] = env.appBin[0];
-               systmp0[1] = env.appBin[1];
-               env.preg[2].p = systmp0 + 2;
-               env.preg[3].p = systmp0 + SYSTMP0SIZ;
-               env.preg[4].p = env.appBin + 2;
-               env.preg[5].p = env.appBin + env.appSize1;
-               env.preg[6].p = systmp1;
-               env.preg[7].p = systmp1 + SYSTMP1SIZ;
-               env.preg[10].p = systmp2;
-               int pxxFlag[64], typLabel[4096];
-               env.preg[0x0b].p = (void *)pxxFlag;
-               env.preg[0x0c].p = (void *)typLabel;
-               env.preg[0x0d].p = opTbl;
-               jitfunc = (void *)sysjit00;
-               jitcRunBinary(jitfunc, &env);
-               if (env.ireg[0] != 0) {
-                       jp = env.preg[2].p - 1;
-                       fprintf(stderr, "unpack error: %02X (at %06X) (R00=%d)\n", *jp, jp - systmp0, env.ireg[0]);
-                       if ((argDebug & 2) != 0) {
-                               fp = fopen("debug2.bin", "wb");
-                               fwrite(systmp0, 1, jp - systmp0 + 16, fp);
-                               fclose(fp);
-                       }
-                       exit(1);
-               }
-               tmpsiz = env.preg[2].p - systmp0;
-       } else{
-               memcpy(systmp0, env.appBin, env.appSize1);
-               tmpsiz = env.appSize1;
-       }
-       
-       if ((argDebug & 2) != 0) {
-               /*変換後のバックエンドコードをファイルへ保存*/
-               fp = fopen("debug2.bin", "wb");
-               fwrite(systmp0, 1, tmpsiz, fp);
-               fclose(fp);
-       }
-       
-       //JITコンパイル
-       i = jitc0(&jp, jitbuf + 1024 * 1024, systmp0, systmp0 + tmpsiz, env.executionLevel, label);
-       if (i == 1){
-               fputs("app-file header error.\n", stderr);
-               return 1;
-       }
-       if (i != 0){
-               return 1;
-       }
-       di1_serial++;
-       
-       int appsiz2 = jp - jitbuf;
-       
-       unsigned char *p28 = jp;
-       jp = jitCompCallFunc(jp, &devFunc);
-       
-       tm1 = clock() / (double)CLOCKS_PER_SEC;
-       
-       /* レジスタ初期化 */
-       for (i = 0; i < 64; i++){
-               env.ireg[i] = 0;
-       }
-       for (i = 0; i < 64; i++) {
-               env.preg[i].p = NULL;
-               env.preg[i].typ = -1;
-               env.preg[i].p0 = NULL;
-               env.preg[i].p1 = NULL;
-       }
-       
-       env.buf0 = env.buf1 = NULL;
-
-       // p28にapiをコールするアドレスを設定
-       env.preg[0x28].p = p28; // p28には、devFuncをコールするコードが書かれている
-       env.preg[0x28].typ = 0; // TYP_CODE
-       env.preg[0x28].p0 = p28;                // アドレス演算できる範囲を制限
-       env.preg[0x28].p1 = p28 + 1;    // アドレス演算できる範囲を制限
-
-       //env.preg[0x00].p = malloc(1024 * 1024) + (1024 * 1024 - 32);
-       env.junkStack = malloc(stacksiz << 20);
-       env.junkStack1 = env.junkStack + (stacksiz << 20);
-       env.winClosed = 0;
-       env.autoSleep = 0;
-       env.lastConsoleChar = '\n';
-       
-       env.label = label;
-       env.maxLabels = JITC_MAXLABELS;
-       env.jitbuf = jp;
-       env.jitbuf1 = jitbuf + 1024 * 1024;
-       env.errHndl = &errorHandler;
-       env.appReturnCode = 0;
-       
-       env.dbgr = 0;
-       if (searchArg(argc, (const char **)argv, "dbgr:1", 0) != NULL){
-               env.dbgr = 1;
-       }
-       
-       if ((argDebug & 1) != 0) {
-               fp = fopen("debug1.bin", "wb");
-               fwrite(jitbuf, 1, jp - jitbuf, fp);
-               fclose(fp);
-       }
-       
-       /* JITコード実行 */
-       jitfunc = (void *)jitbuf;
-       if (setjmp(env.setjmpEnv) == 0){
-               jitcRunBinary(jitfunc, &env);
-       }
-       if (env.autoSleep != 0) {
-               if (mainWindow.vram != NULL){
-                       drv_flshWin(mainWindow.xsize, mainWindow.ysize, 0, 0);
-               }
-               while (env.winClosed == 0){
-                       drv_sleep(100);
-               }
-       }
-       if (env.lastConsoleChar != '\n'){
-               putchar('\n');
-       }
-       
-       tm2 = clock() / (double)CLOCKS_PER_SEC;
-       
-       /* 実行結果確認のためのレジスタダンプ */
-       if (searchArg(argc, (const char **)argv, "verbose:1", 0) != NULL) {
-               printf("time: JITC=%.3f[sec], exec=%.3f[sec]\n", tm1 - tm0, tm2 - tm1);
-               printf("size: OSECPU=%d, decomp=%d, tmp=%d, native=%d\n", env.appSize0, env.appSize1, tmpsiz, appsiz2);
-               printf("result:\n");
-               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]);
-       }
-#if (USE_DEBUGGER != 0)
-       dbgrMain(&env);
-#endif
-       return env.appReturnCode;
-}
-
-unsigned char *Init_LoadSysLib(char argv0[], unsigned char *tmpWorkMemory)
-{
-       unsigned char *syslib;
-       FILE *fp;
-       unsigned char *up;
-       int appsize;
-       
-       /* syslibの読み込み */
-       syslib = malloc(SYSLIBSIZ1);
-       fp = fopen(SYSLIB_OSE, "rb");
-       if (fp == NULL) {
-               syslib[0] = '/';
-               strcpy((char *)syslib + 1, argv0);
-               up = syslib + 1;
-               while (*up != '\0'){
-                       up++;
-               }
-               while (*up != '/' && *up != 0x5c){
-                       up--;
-               }
-               up++;
-               strcpy((char *)up, SYSLIB_OSE);
-               fp = fopen((char *)syslib + 1, "rb");
-       }
-       if (fp == NULL) {
-               fputs("syslib-file fopen error.\n", stderr);
-               exit(EXIT_FAILURE);
-       }
-       appsize = fread(syslib, 1, SYSLIBSIZ1 - 4, fp);
-       fclose(fp);
-       if (appsize >= SYSLIBSIZ1 - 4) {
-               fputs("syslib-file too large.\n", stderr);
-               exit(EXIT_FAILURE);
-       }
-       if (syslib[0] == 0x05 && syslib[1] == 0xc1) {
-               // maklib のライブラリ形式である。
-               memcpy(tmpWorkMemory, syslib, appsize);
-               ComLib_main(tmpWorkMemory + 2, syslib + 2);
-               syslib[0] = 0x05;
-               syslib[1] = 0x1b;
-       }
-       
-       fp = fopen("syslib_dbg.ose", "wb");
-       fwrite(syslib, 1, SYSLIBSIZ1, fp);
-       fclose(fp);
-       return syslib;
-}
-
-void LoadAppBin(HOSECPU_RuntimeEnvironment *env)
-{
-       FILE *fp;
-       const char *fileName;
-       /* アプリバイナリの読み込み */
-       if (env->mainArgc <= 1) {
-               //アプリ名未指定なので何事もなく終了
-               exit(EXIT_SUCCESS);
-       }
-       fileName = env->mainArgv[1];
-       //アプリ名先頭に:n:をつけることでレベルnでの実行が可能?
-       if (fileName[0] == ':' && fileName[2] == ':') {
-               env->executionLevel = fileName[1] - '0';
-               if (env->executionLevel < 0 || env->executionLevel > 9){
-                       env->executionLevel = JITC_LV_SLOWEST;
-               }
-               fileName += 3;
-       }
-       
-       fp = fopen(fileName, "rb");
-       if (fp == NULL) {
-               fputs("app-file load error.\n", stderr);
-               exit(EXIT_FAILURE);
-       }
-       env->appSize0 = fread(env->appBin, 1, APPSIZ1 - 4, fp);
-       env->appSize1 = env->appSize0;
-       fclose(fp);
-       
-       if (env->appSize0 >= APPSIZ1 - 4) {
-               fputs("app-file too large.\n", stderr);
-               exit(EXIT_FAILURE);
-       }
-       if (env->appSize0 < 3) {
-               fputs("app-file header error.\n", stderr);
-               exit(EXIT_FAILURE);
-       }
-}
+#include "osecpu.h"\r
+\r
+int *keybuf, keybuf_r, keybuf_w, keybuf_c;\r
+HOSECPU_Device_Window mainWindow;\r
+//デバッグ用。プログラム中の随所で加算される変数\r
+int di1_serial;\r
+HOSECPU_RuntimeEnvironment *dbg_env;\r
+\r
+\r
+\r
+unsigned char *Init_LoadSysLib(char argv0[], unsigned char *tmpWorkMemory);\r
+void LoadAppBin(HOSECPU_RuntimeEnvironment *env);\r
+\r
+void putKeybuf(int i)\r
+{\r
+       // TODO : あふれた場合のことを考慮すべき\r
+       if (keybuf_c < KEYBUFSIZ) {\r
+               keybuf[keybuf_w] = i;\r
+               keybuf_c++;\r
+               keybuf_w = (keybuf_w + 1) & (KEYBUFSIZ - 1);\r
+       }\r
+       return;\r
+}\r
+\r
+int HeavyOSECPUMain(int argc, char **argv)\r
+{\r
+       HOSECPU_RuntimeEnvironment env;\r
+       FILE *fp;\r
+       unsigned char *jitbuf, *sysjit00, *sysjit;\r
+       unsigned char *systmp0, *systmp1, *systmp2;\r
+       unsigned char *opTbl;\r
+       HOSECPU_LabelListTag *label;\r
+       int tmpsiz, i;\r
+       double tm0, tm1, tm2;\r
+       HOSECPU_PointerControlTag *ptrCtrl;\r
+       unsigned char *syslib;\r
+       int argDebug = 0, stacksiz = 1;\r
+       const  char *cp;\r
+       void(*jitfunc)(char *);\r
+       unsigned char *jp;\r
+       \r
+       // For debug\r
+       dbg_env = &env;\r
+       \r
+       // Initialize mainWindow\r
+       mainWindow.vram = NULL;\r
+       mainWindow.xsize = 0;\r
+       mainWindow.ysize = 0;\r
+       di1_serial = 0;\r
+       \r
+       // 実行環境初期化\r
+       env.mainArgc = argc;\r
+       env.mainArgv = (const char **)argv;\r
+       env.appBin = malloc(APPSIZ1);\r
+       env.executionLevel = JITC_LV_SLOWEST;\r
+       jitbuf = mallocRWE(APPJITSIZE); /* とりあえず1MBで */\r
+       // syslib.oseのjitc結果を格納する領域を確保。\r
+       sysjit00 = mallocRWE(SYSJITSIZ1);\r
+       sysjit = sysjit00;\r
+       // 現在の、jitc結果を格納するメモリへの書き込み位置のアドレス\r
+       // sysjit: 現在のjitc書き込み位置\r
+       // sysjit00: jitc結果の先頭\r
+       //ワークメモリを三つくらいもらう\r
+       systmp0 = malloc(SYSTMP0SIZ);   /* syslibのjitc用 */\r
+       systmp1 = malloc(SYSTMP1SIZ);\r
+       systmp2 = malloc(1024 * 1024);\r
+       \r
+       opTbl = malloc(256);\r
+       label = malloc(JITC_MAXLABELS * sizeof (HOSECPU_LabelListTag));\r
+       keybuf = malloc(KEYBUFSIZ * sizeof (int));\r
+       keybuf_r = keybuf_w = keybuf_c = 0;\r
+       ptrCtrl = malloc(PTRCTRLSIZ * sizeof (HOSECPU_PointerControlTag));\r
+       \r
+       randStatInit((unsigned int)time(NULL));\r
+       for (i = 0; i < PTRCTRLSIZ; i++) {\r
+               ptrCtrl[i].liveSign = 0;\r
+               ptrCtrl[i].size = -1;\r
+       }\r
+       ptrCtrl[0].size = -2;\r
+       \r
+       /* syslibの読み込み */\r
+       syslib = Init_LoadSysLib(argv[0], systmp0);\r
+       \r
+       sysjit = jitCompInit(sysjit);\r
+       sysjit00 = sysjit;\r
+       // labelはjitc0()内で初期化される。\r
+       i = jitc0(&sysjit, sysjit00 + SYSJITSIZ1, syslib + 32, syslib + SYSLIBSIZ1, JITC_LV_SLOWEST+9, label);\r
+       if (i != 0){\r
+               fputs("syslib-file JITC error.\n", stderr);\r
+               return 1;\r
+       }\r
+       \r
+       // エラー時にデバッグ用に表示する変数を加算\r
+       di1_serial++;\r
+       \r
+       /* アプリバイナリの読み込み */\r
+       LoadAppBin(&env);\r
+       \r
+       /* クロック初期化 */\r
+       tm0 = clock() / (double)CLOCKS_PER_SEC;\r
+       \r
+       if (env.appBin[2] == 0xf0) {\r
+               // tek5圧縮がかかっている\r
+#if (USE_TEK5 != 0)\r
+               env.appSize1 = tek5Decomp(env.appBin + 2, env.appBin + env.appSize0, systmp0);\r
+               env.appSize1 += 2;\r
+#else\r
+               env.appSize1 = -9;\r
+#endif\r
+               if (env.appSize1 < 0) {\r
+                       fputs("unsupported-format(tek5)\n", stderr);\r
+                       return 1;\r
+               }\r
+       }\r
+       //デバッグモード指定\r
+       cp = searchArg(argc, (const char **)argv, "debug:", 0);\r
+       if (cp != NULL){\r
+               argDebug = *cp - '0';\r
+       }\r
+       //スタックサイズ指定(MiB単位)\r
+       cp = searchArg(argc, (const char **)argv, "stack:", 0);\r
+       if (cp != NULL){\r
+               stacksiz = strtol(cp, NULL, 0);\r
+       }\r
+\r
+       // jitbufは先頭。 jpは現在位置\r
+       jp = jitbuf; /* JIT-pointer */\r
+       \r
+       /* フロントエンドコードをバックエンドコードに変換する */\r
+       if ((env.appBin[2] & 0xf0) != 0) {                              // 3バイト目が00なら処理しない\r
+               systmp0[0] = env.appBin[0];\r
+               systmp0[1] = env.appBin[1];\r
+               env.preg[2].p = systmp0 + 2;\r
+               env.preg[3].p = systmp0 + SYSTMP0SIZ;\r
+               env.preg[4].p = env.appBin + 2;\r
+               env.preg[5].p = env.appBin + env.appSize1;\r
+               env.preg[6].p = systmp1;\r
+               env.preg[7].p = systmp1 + SYSTMP1SIZ;\r
+               env.preg[10].p = systmp2;\r
+               int pxxFlag[64], typLabel[4096];\r
+               env.preg[0x0b].p = (void *)pxxFlag;\r
+               env.preg[0x0c].p = (void *)typLabel;\r
+               env.preg[0x0d].p = opTbl;\r
+               jitfunc = (void *)sysjit00;\r
+               jitcRunBinary(jitfunc, &env);\r
+               if (env.ireg[0] != 0) {\r
+                       jp = env.preg[2].p - 1;\r
+                       fprintf(stderr, "unpack error: %02X (at %06X) (R00=%d)\n", *jp, jp - systmp0, env.ireg[0]);\r
+                       if ((argDebug & 2) != 0) {\r
+                               fp = fopen("debug2.bin", "wb");\r
+                               fwrite(systmp0, 1, jp - systmp0 + 16, fp);\r
+                               fclose(fp);\r
+                       }\r
+                       exit(1);\r
+               }\r
+               tmpsiz = env.preg[2].p - systmp0;\r
+       } else{\r
+               memcpy(systmp0, env.appBin, env.appSize1);\r
+               tmpsiz = env.appSize1;\r
+       }\r
+       \r
+       if ((argDebug & 2) != 0) {\r
+               /*変換後のバックエンドコードをファイルへ保存*/\r
+               fp = fopen("debug2.bin", "wb");\r
+               fwrite(systmp0, 1, tmpsiz, fp);\r
+               fclose(fp);\r
+       }\r
+       \r
+       //JITコンパイル\r
+       i = jitc0(&jp, jitbuf + 1024 * 1024, systmp0, systmp0 + tmpsiz, env.executionLevel, label);\r
+       if (i == 1){\r
+               fputs("app-file header error.\n", stderr);\r
+               return 1;\r
+       }\r
+       if (i != 0){\r
+               return 1;\r
+       }\r
+       di1_serial++;\r
+       \r
+       int appsiz2 = jp - jitbuf;\r
+       \r
+       unsigned char *p28 = jp;\r
+       jp = jitCompCallFunc(jp, &devFunc);\r
+       \r
+       tm1 = clock() / (double)CLOCKS_PER_SEC;\r
+       \r
+       /* レジスタ初期化 */\r
+       for (i = 0; i < 64; i++){\r
+               env.ireg[i] = 0;\r
+       }\r
+       for (i = 0; i < 64; i++) {\r
+               env.preg[i].p = NULL;\r
+               env.preg[i].typ = -1;\r
+               env.preg[i].p0 = NULL;\r
+               env.preg[i].p1 = NULL;\r
+       }\r
+       \r
+       env.buf0 = env.buf1 = NULL;\r
+\r
+       // p28にapiをコールするアドレスを設定\r
+       env.preg[0x28].p = p28; // p28には、devFuncをコールするコードが書かれている\r
+       env.preg[0x28].typ = 0; // TYP_CODE\r
+       env.preg[0x28].p0 = p28;                // アドレス演算できる範囲を制限\r
+       env.preg[0x28].p1 = p28 + 1;    // アドレス演算できる範囲を制限\r
+\r
+       //env.preg[0x00].p = malloc(1024 * 1024) + (1024 * 1024 - 32);\r
+       env.junkStack = malloc(stacksiz << 20);\r
+       env.junkStack1 = env.junkStack + (stacksiz << 20);\r
+       env.winClosed = 0;\r
+       env.autoSleep = 0;\r
+       env.lastConsoleChar = '\n';\r
+       \r
+       env.label = label;\r
+       env.maxLabels = JITC_MAXLABELS;\r
+       env.jitbuf = jp;\r
+       env.jitbuf1 = jitbuf + 1024 * 1024;\r
+       env.errHndl = &errorHandler;\r
+       env.appReturnCode = 0;\r
+       \r
+       env.dbgr = 0;\r
+       if (searchArg(argc, (const char **)argv, "dbgr:1", 0) != NULL){\r
+               env.dbgr = 1;\r
+       }\r
+       \r
+       if ((argDebug & 1) != 0) {\r
+               fp = fopen("debug1.bin", "wb");\r
+               fwrite(jitbuf, 1, jp - jitbuf, fp);\r
+               fclose(fp);\r
+       }\r
+       \r
+       /* JITコード実行 */\r
+       jitfunc = (void *)jitbuf;\r
+       if (setjmp(env.setjmpEnv) == 0){\r
+               jitcRunBinary(jitfunc, &env);\r
+       }\r
+       if (env.autoSleep != 0) {\r
+               if (mainWindow.vram != NULL){\r
+                       drv_flshWin(mainWindow.xsize, mainWindow.ysize, 0, 0);\r
+               }\r
+               while (env.winClosed == 0){\r
+                       drv_sleep(100);\r
+               }\r
+       }\r
+       if (env.lastConsoleChar != '\n'){\r
+               putchar('\n');\r
+       }\r
+       \r
+       tm2 = clock() / (double)CLOCKS_PER_SEC;\r
+       \r
+       /* 実行結果確認のためのレジスタダンプ */\r
+       if (searchArg(argc, (const char **)argv, "verbose:1", 0) != NULL) {\r
+               printf("time: JITC=%.3f[sec], exec=%.3f[sec]\n", tm1 - tm0, tm2 - tm1);\r
+               printf("size: OSECPU=%d, decomp=%d, tmp=%d, native=%d\n", env.appSize0, env.appSize1, tmpsiz, appsiz2);\r
+               printf("result:\n");\r
+               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]);\r
+       }\r
+#if (USE_DEBUGGER != 0)\r
+       dbgrMain(&env);\r
+#endif\r
+       return env.appReturnCode;\r
+}\r
+\r
+unsigned char *Init_LoadSysLib(char argv0[], unsigned char *tmpWorkMemory)\r
+{\r
+       unsigned char *syslib;\r
+       FILE *fp;\r
+       unsigned char *up;\r
+       int appsize;\r
+       \r
+       /* syslibの読み込み */\r
+       syslib = malloc(SYSLIBSIZ1);\r
+       fp = fopen(SYSLIB_OSE, "rb");\r
+       if (fp == NULL) {\r
+               syslib[0] = '/';\r
+               strcpy((char *)syslib + 1, argv0);\r
+               up = syslib + 1;\r
+               while (*up != '\0'){\r
+                       up++;\r
+               }\r
+               while (*up != '/' && *up != 0x5c){\r
+                       up--;\r
+               }\r
+               up++;\r
+               strcpy((char *)up, SYSLIB_OSE);\r
+               fp = fopen((char *)syslib + 1, "rb");\r
+       }\r
+       if (fp == NULL) {\r
+               fputs("syslib-file fopen error.\n", stderr);\r
+               exit(EXIT_FAILURE);\r
+       }\r
+       appsize = fread(syslib, 1, SYSLIBSIZ1 - 4, fp);\r
+       fclose(fp);\r
+       if (appsize >= SYSLIBSIZ1 - 4) {\r
+               fputs("syslib-file too large.\n", stderr);\r
+               exit(EXIT_FAILURE);\r
+       }\r
+       if (syslib[0] == 0x05 && syslib[1] == 0xc1) {\r
+               // maklib のライブラリ形式である。\r
+               memcpy(tmpWorkMemory, syslib, appsize);\r
+               ComLib_main(tmpWorkMemory + 2, syslib + 2);\r
+               syslib[0] = 0x05;\r
+               syslib[1] = 0x1b;\r
+       }\r
+       \r
+       fp = fopen("syslib_dbg.ose", "wb");\r
+       fwrite(syslib, 1, SYSLIBSIZ1, fp);\r
+       fclose(fp);\r
+       return syslib;\r
+}\r
+\r
+void LoadAppBin(HOSECPU_RuntimeEnvironment *env)\r
+{\r
+       FILE *fp;\r
+       const char *fileName;\r
+       /* アプリバイナリの読み込み */\r
+       if (env->mainArgc <= 1) {\r
+               //アプリ名未指定なので何事もなく終了\r
+               exit(EXIT_SUCCESS);\r
+       }\r
+       fileName = env->mainArgv[1];\r
+       //アプリ名先頭に:n:をつけることでレベルnでの実行が可能?\r
+       if (fileName[0] == ':' && fileName[2] == ':') {\r
+               env->executionLevel = fileName[1] - '0';\r
+               if (env->executionLevel < 0 || env->executionLevel > 9){\r
+                       env->executionLevel = JITC_LV_SLOWEST;\r
+               }\r
+               fileName += 3;\r
+       }\r
+       \r
+       fp = fopen(fileName, "rb");\r
+       if (fp == NULL) {\r
+               fputs("app-file load error.\n", stderr);\r
+               exit(EXIT_FAILURE);\r
+       }\r
+       env->appSize0 = fread(env->appBin, 1, APPSIZ1 - 4, fp);\r
+       env->appSize1 = env->appSize0;\r
+       fclose(fp);\r
+       \r
+       if (env->appSize0 >= APPSIZ1 - 4) {\r
+               fputs("app-file too large.\n", stderr);\r
+               exit(EXIT_FAILURE);\r
+       }\r
+       if (env->appSize0 < 3) {\r
+               fputs("app-file header error.\n", stderr);\r
+               exit(EXIT_FAILURE);\r
+       }\r
+}\r
index abcfd5f..62b4f22 100644 (file)
--- a/osecpu.h
+++ b/osecpu.h
-#ifndef _HDLOAD_OSECPU
-#define _HDLOAD_OSECPU 1
-
-/* Visual Studio で fopen()やsprintf() などの古い関数を使用する時に出る警告を抑止する*/
-#define _CRT_SECURE_NO_WARNINGS 1
-
-//
-// Including stdc headers
-//
-
-#include <stdio.h>
-#include <string.h>
-#include <limits.h>
-#include <time.h>
-#include <setjmp.h>
-#include <stdlib.h>
-
-
-//
-// Compile options
-//
-
-// Target architecture
-// 1 : i386
-#define JITC_ARCNUM 0x0001
-
-// Target operating system
-// 1 : Windows 32bit
-// 2 : Mac OSX 32bit
-// 3 : blike for Linux
-#ifdef _WIN32
-#define DRV_OSNUM                      0x0001
-#endif
-#ifdef __APPLE__
-#define DRV_OSNUM                      0x0002
-#endif
-#ifdef __linux__
-#define DRV_OSNUM                      0x0003
-#endif
-//#define DRV_OSNUM 0x0002
-
-// Decoder (syslib.ose) setting
-// syslib.ose is necessary to work OSECPU
-#define SYSLIB_OSE     "syslib.ose"
-
-//
-// Define constant values
-//
-
-// SIGN1: The 2nd signature of OSECPU Format(05 e1)
-// It will be changed in OSECPU Rev.2 to "e2" (no adaptation in their binary layers)
-#define SIGN1          0xe1
-
-#define USE_DEBUGGER   1
-#define USE_TEK5               1
-
-/* JITC mode flags */
-#define        JITC_LV_SLOWEST         0       /* デバッグ支援は何でもやる */
-#define        JITC_LV_SLOWER          1       /* エラーモジュールはレポートできるが、行番号は分からない、テストは過剰 */
-#define        JITC_LV_SAFE            2       /* とにかく止まる、場所は不明、テストは必要最小限 */
-#define        JITC_LV_FASTER          4       /* 情報は生成するがチェックをしない */
-#define        JITC_LV_FASTEST         5       /* 情報すら生成しない */
-#define JITC_PHASE1                    0x0001
-#define JITC_SKIPCHECK         0x0002  /* セキュリティチェックを省略する(高速危険モード) */
-#define JITC_NOSTARTUP         0x0004
-#define JITC_MAXLABELS         4096
-#define PTRCTRLSIZ                     4096
-
-#define        APPSIZ1         1 * 1024 * 1024 /* 1MB for now */
-#define APPJITSIZE  1 * 1024 * 1024 /* 1MB for now */
-#define        SYSJITSIZ1      2 * 1024 * 1024 /* 1MB for now */
-#define        SYSLIBSIZ1      1 * 1024 * 1024 /* 1MB for now */
-#define SYSTMP0SIZ     1 * 1024 * 1024 /* 1MB for now */
-#define SYSTMP1SIZ     2 * 1024 * 1024 /* 1MB for now */
-
-#define KEYBUFSIZ              4096
-
-#define KEY_ENTER              '\n'
-#define KEY_ESC                        27
-#define KEY_BACKSPACE  8
-#define KEY_TAB                        9
-#define KEY_PAGEUP             0x1020
-#define KEY_PAGEDWN            0x1021
-#define        KEY_END                 0x1022
-#define        KEY_HOME                0x1023
-#define KEY_LEFT               0x1024
-#define KEY_UP                 0x1025
-#define KEY_RIGHT              0x1026
-#define KEY_DOWN               0x1027
-#define KEY_INS                        0x1028
-#define KEY_DEL                        0x1029
-
-//
-// HOSECPU structures
-//
-typedef struct PtrCtrl HOSECPU_PointerControlTag;
-struct PtrCtrl {
-       int liveSign;
-       int size, typ;
-       unsigned char *p0;
-};
-
-typedef struct Ptr HOSECPU_PointerRegisterEntry;
-struct Ptr {
-       // 32バイト(=256bit!)
-       unsigned char *p;
-       
-       /* static char *typName[] = {
-               "T_CODE", "T_VPTR", "T_SINT8", "T_UINT8",
-               "T_SINT16", "T_UINT16", "T_SINT32", "T_UINT32",
-               "T_SINT4", "T_UINT4", "T_SINT2", "T_UINT2",
-               "T_SINT1", "T_UINT1", "T_SINT12", "T_UINT12",
-               "T_SINT20", "T_UINT20", "T_SINT24", "T_UINT24",
-               "T_SINT28", "T_UINT28"
-       } ; */
-       int typ;
-       unsigned char *p0, *p1;
-       int liveSign;
-       HOSECPU_PointerControlTag *pls;
-       int flags, dummy;       /* read/writeなど */
-};
-
-typedef struct LabelTable HOSECPU_LabelListTag;
-struct LabelTable {
-       unsigned char *p, *p1;
-       int opt;
-       /*
-        * default = -1
-        * TYP_CODE = 0
-        * T_UINT8 = 3
-        *
-        * 将来的には UInt8, SInt32, Flt64, UInt8, VPtr が使えるようになる http://osecpu.osask.jp/wiki/?page0053
-        */
-       int typ;
-};
-
-typedef struct Device_Window HOSECPU_Device_Window;
-struct Device_Window {
-    int *vram;
-    int xsize, ysize;
-};
-
-typedef struct Regs HOSECPU_RuntimeEnvironment;
-struct Regs {
-       int ireg[64];                                                           // 整数レジスタ (4 * 64) = 256
-       HOSECPU_PointerRegisterEntry preg[64];          // ポインタレジスタ (32 * 64) = 2048
-    //
-       int debugInfo0;                                                         // 2304
-       int debugInfo1;                                                         // 2308
-    int dbg_currentCode;                        // 2312
-       int dmy;                                                                        // 2316
-       //
-       HOSECPU_PointerControlTag *ptrCtrl;         // 2320
-       char winClosed, autoSleep;
-       jmp_buf setjmpEnv;
-    int appReturnCode;      // アプリ自体の終了コード
-    
-    /* Main environment */
-    int mainArgc;           // HOSECPU起動引数の個数
-    const char **mainArgv;  // HOSECPU起動引数リスト
-    unsigned char *appBin;  // 実行するアプリのバイナリ
-    int appSize0;
-    int appSize1;
-    int executionLevel;
-    
-       /* for-junkApi */
-       unsigned char *buf0, *buf1, *junkStack, lastConsoleChar, *junkStack1;
-    
-       HOSECPU_LabelListTag *label;
-       int maxLabels;
-       unsigned char *jitbuf, *jitbuf1;
-       void(*errHndl)(HOSECPU_RuntimeEnvironment *);
-       char dbgr;
-       int mapDi1s[16][16];
-};
-
-//
-// Grobal values
-//
-
-extern int *keybuf, keybuf_r, keybuf_w, keybuf_c;
-extern HOSECPU_Device_Window mainWindow;
-// di1_serial: デバッグ用。プログラム中の随所で加算される変数
-extern int di1_serial;
-
-//
-// Functions
-//
-
-// @main.c
-void putKeybuf(int i);
-int HeavyOSECPUMain(int argc, char **argv);
-
-// @comlib.c
-unsigned char *ComLib_main(const unsigned char *p, unsigned char *q);
-// @dpndenv.c
-// OSに依存する関数群を定義する。
-void *mallocRWE(int bytes); // 実行権付きメモリのmalloc.
-void drv_openWin(int x, int y, unsigned char *buf, char *winClosed);
-void drv_flshWin(int sx, int sy, int x0, int y0);
-void drv_sleep(int msec);
-
-// @function.c
-void dbgrMain(HOSECPU_RuntimeEnvironment *r);
-const char *searchArg(int argc, const char **argv, const char *tag, int i); // コマンドライン引数処理.
-void devFunc(HOSECPU_RuntimeEnvironment *r); // junkApiを処理する関数
-
-// @jitc.c
-void errorHandler(HOSECPU_RuntimeEnvironment *r);
-void PRegCopy(HOSECPU_PointerRegisterEntry *dst, HOSECPU_PointerRegisterEntry *src);
-// @jitcx86.c
-int jitc0(unsigned char **qq, unsigned char *q1, const unsigned char *p0, const unsigned char *p1, int level, HOSECPU_LabelListTag *label);
-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);
-unsigned char *jitCompCallFunc(unsigned char *dst, void *func);
-unsigned char *jitCompInit(unsigned char *dst);
-void jitcRunBinary(void (*bin)(char *), HOSECPU_RuntimeEnvironment *env);
-
-// @randmt.c
-void randStatInit(unsigned int seed);
-void randStatNext();
-unsigned int randGetNextUInt32(void);
-
-// @screen.c
-static int iColor1[] = {
-       0x000000, 0xff0000, 0x00ff00, 0xffff00,
-       0x0000ff, 0xff00ff, 0x00ffff, 0xffffff
-};
-void putOsaskChar(int c, HOSECPU_RuntimeEnvironment *r);
-void checkString(HOSECPU_RuntimeEnvironment *r, int rxx, int pxx);
-void checkRect(HOSECPU_RuntimeEnvironment *r, int rxx);
-int loadColor(HOSECPU_RuntimeEnvironment *r, int rxx);
-
-// @usetek.c
-#if (USE_TEK5 != 0)
-#include "tek.h"
-int appackSub2(const UCHAR **pp, char *pif);
-int appackSub3u(const UCHAR **pp, char *pif);
-int tek5Decomp(UCHAR *buf, UCHAR *buf1, UCHAR *tmp);
-#endif
-
-
-#endif
+#ifndef _HDLOAD_OSECPU\r
+#define _HDLOAD_OSECPU 1\r
+\r
+/* Visual Studio で fopen()やsprintf() などの古い関数を使用する時に出る警告を抑止する*/\r
+#define _CRT_SECURE_NO_WARNINGS 1\r
+\r
+//\r
+// Including stdc headers\r
+//\r
+\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include <limits.h>\r
+#include <time.h>\r
+#include <setjmp.h>\r
+#include <stdlib.h>\r
+\r
+\r
+//\r
+// Compile options\r
+//\r
+\r
+// Target architecture\r
+// 1 : i386\r
+#define JITC_ARCNUM 0x0001\r
+\r
+// Target operating system\r
+// 1 : Windows 32bit\r
+// 2 : Mac OSX 32bit\r
+// 3 : blike for Linux\r
+#ifdef _WIN32\r
+#define DRV_OSNUM                      0x0001\r
+#endif\r
+#ifdef __APPLE__\r
+#define DRV_OSNUM                      0x0002\r
+#endif\r
+#ifdef __linux__\r
+#define DRV_OSNUM                      0x0003\r
+#endif\r
+//#define DRV_OSNUM 0x0002\r
+\r
+// Decoder (syslib.ose) setting\r
+// syslib.ose is necessary to work OSECPU\r
+#define SYSLIB_OSE     "syslib.ose"\r
+\r
+//\r
+// Define constant values\r
+//\r
+\r
+// SIGN1: The 2nd signature of OSECPU Format(05 e1)\r
+// It will be changed in OSECPU Rev.2 to "e2" (no adaptation in their binary layers)\r
+#define SIGN1          0xe1\r
+\r
+#define USE_DEBUGGER   1\r
+#define USE_TEK5               1\r
+\r
+/* JITC mode flags */\r
+#define        JITC_LV_SLOWEST         0       /* デバッグ支援は何でもやる */\r
+#define        JITC_LV_SLOWER          1       /* エラーモジュールはレポートできるが、行番号は分からない、テストは過剰 */\r
+#define        JITC_LV_SAFE            2       /* とにかく止まる、場所は不明、テストは必要最小限 */\r
+#define        JITC_LV_FASTER          4       /* 情報は生成するがチェックをしない */\r
+#define        JITC_LV_FASTEST         5       /* 情報すら生成しない */\r
+#define JITC_PHASE1                    0x0001\r
+#define JITC_SKIPCHECK         0x0002  /* セキュリティチェックを省略する(高速危険モード) */\r
+#define JITC_NOSTARTUP         0x0004\r
+#define JITC_MAXLABELS         4096\r
+#define PTRCTRLSIZ                     4096\r
+\r
+#define        APPSIZ1         1 * 1024 * 1024 /* 1MB for now */\r
+#define APPJITSIZE  1 * 1024 * 1024 /* 1MB for now */\r
+#define        SYSJITSIZ1      2 * 1024 * 1024 /* 1MB for now */\r
+#define        SYSLIBSIZ1      1 * 1024 * 1024 /* 1MB for now */\r
+#define SYSTMP0SIZ     1 * 1024 * 1024 /* 1MB for now */\r
+#define SYSTMP1SIZ     2 * 1024 * 1024 /* 1MB for now */\r
+\r
+#define KEYBUFSIZ              4096\r
+\r
+#define KEY_EMPTY       -1\r
+#define KEY_ENTER              '\n'\r
+#define KEY_ESC                        27\r
+#define KEY_BACKSPACE  8\r
+#define KEY_TAB                        9\r
+#define KEY_PAGEUP             0x1020\r
+#define KEY_PAGEDWN            0x1021\r
+#define        KEY_END                 0x1022\r
+#define        KEY_HOME                0x1023\r
+#define KEY_LEFT               0x1024\r
+#define KEY_UP                 0x1025\r
+#define KEY_RIGHT              0x1026\r
+#define KEY_DOWN               0x1027\r
+#define KEY_INS                        0x1028\r
+#define KEY_DEL                        0x1029\r
+\r
+#define KEY_MODIFIER_SHIFT_L    (1 << 16)   // [C]\r
+#define KEY_MODIFIER_CONTROL_L  (1 << 17)\r
+#define KEY_MODIFIER_MENU_L     (1 << 18)\r
+#define KEY_MODIFIER_NUMLOCK    (1 << 22)   // [C]\r
+#define KEY_MODIFIER_CAPITAL    (1 << 23)   // [C]\r
+#define KEY_MODIFIER_SHIFT_R    (1 << 24)   // [C]\r
+#define KEY_MODIFIER_CONTROL_R  (1 << 25)\r
+#define KEY_MODIFIER_MENU_R     (1 << 26)\r
+\r
+\r
+//\r
+// HOSECPU structures\r
+//\r
+typedef struct PtrCtrl HOSECPU_PointerControlTag;\r
+struct PtrCtrl {\r
+       int liveSign;\r
+       int size, typ;\r
+       unsigned char *p0;\r
+};\r
+\r
+typedef struct Ptr HOSECPU_PointerRegisterEntry;\r
+struct Ptr {\r
+       // 32バイト(=256bit!)\r
+       unsigned char *p;\r
+       \r
+       /* static char *typName[] = {\r
+               "T_CODE", "T_VPTR", "T_SINT8", "T_UINT8",\r
+               "T_SINT16", "T_UINT16", "T_SINT32", "T_UINT32",\r
+               "T_SINT4", "T_UINT4", "T_SINT2", "T_UINT2",\r
+               "T_SINT1", "T_UINT1", "T_SINT12", "T_UINT12",\r
+               "T_SINT20", "T_UINT20", "T_SINT24", "T_UINT24",\r
+               "T_SINT28", "T_UINT28"\r
+       } ; */\r
+       int typ;\r
+       unsigned char *p0, *p1;\r
+       int liveSign;\r
+       HOSECPU_PointerControlTag *pls;\r
+       int flags, dummy;       /* read/writeなど */\r
+};\r
+\r
+typedef struct LabelTable HOSECPU_LabelListTag;\r
+struct LabelTable {\r
+       unsigned char *p, *p1;\r
+       int opt;\r
+       /*\r
+        * default = -1\r
+        * TYP_CODE = 0\r
+        * T_UINT8 = 3\r
+        *\r
+        * 将来的には UInt8, SInt32, Flt64, UInt8, VPtr が使えるようになる http://osecpu.osask.jp/wiki/?page0053\r
+        */\r
+       int typ;\r
+};\r
+\r
+typedef struct Device_Window HOSECPU_Device_Window;\r
+struct Device_Window {\r
+    int *vram;\r
+    int xsize, ysize;\r
+};\r
+\r
+typedef struct Regs HOSECPU_RuntimeEnvironment;\r
+struct Regs {\r
+       int ireg[64];                                                           // 整数レジスタ (4 * 64) = 256\r
+       HOSECPU_PointerRegisterEntry preg[64];          // ポインタレジスタ (32 * 64) = 2048\r
+    //\r
+       int debugInfo0;                                                         // 2304\r
+       int debugInfo1;                                                         // 2308\r
+    int dbg_currentCode;                        // 2312\r
+       int dmy;                                                                        // 2316\r
+       //\r
+       HOSECPU_PointerControlTag *ptrCtrl;         // 2320\r
+       char winClosed, autoSleep;\r
+       jmp_buf setjmpEnv;\r
+    int appReturnCode;      // アプリ自体の終了コード\r
+    \r
+    /* Main environment */\r
+    int mainArgc;           // HOSECPU起動引数の個数\r
+    const char **mainArgv;  // HOSECPU起動引数リスト\r
+    unsigned char *appBin;  // 実行するアプリのバイナリ\r
+    int appSize0;\r
+    int appSize1;\r
+    int executionLevel;\r
+    \r
+       /* for-junkApi */\r
+       unsigned char *buf0, *buf1, *junkStack, lastConsoleChar, *junkStack1;\r
+    \r
+       HOSECPU_LabelListTag *label;\r
+       int maxLabels;\r
+       unsigned char *jitbuf, *jitbuf1;\r
+       void(*errHndl)(HOSECPU_RuntimeEnvironment *);\r
+       char dbgr;\r
+       int mapDi1s[16][16];\r
+};\r
+\r
+//\r
+// Grobal values\r
+//\r
+\r
+extern int *keybuf, keybuf_r, keybuf_w, keybuf_c;\r
+extern HOSECPU_Device_Window mainWindow;\r
+// di1_serial: デバッグ用。プログラム中の随所で加算される変数\r
+extern int di1_serial;\r
+\r
+//\r
+// Functions\r
+//\r
+\r
+// @main.c\r
+void putKeybuf(int i);\r
+int HeavyOSECPUMain(int argc, char **argv);\r
+\r
+// @comlib.c\r
+unsigned char *ComLib_main(const unsigned char *p, unsigned char *q);\r
+// @dpndenv.c\r
+// OSに依存する関数群を定義する。\r
+void *mallocRWE(int bytes); // 実行権付きメモリのmalloc.\r
+void drv_openWin(int x, int y, unsigned char *buf, char *winClosed);\r
+void drv_flshWin(int sx, int sy, int x0, int y0);\r
+void drv_sleep(int msec);\r
+\r
+// @function.c\r
+void dbgrMain(HOSECPU_RuntimeEnvironment *r);\r
+const char *searchArg(int argc, const char **argv, const char *tag, int i); // コマンドライン引数処理.\r
+void devFunc(HOSECPU_RuntimeEnvironment *r); // junkApiを処理する関数\r
+\r
+// @jitc.c\r
+void errorHandler(HOSECPU_RuntimeEnvironment *r);\r
+void PRegCopy(HOSECPU_PointerRegisterEntry *dst, HOSECPU_PointerRegisterEntry *src);\r
+// @jitcx86.c\r
+int jitc0(unsigned char **qq, unsigned char *q1, const unsigned char *p0, const unsigned char *p1, int level, HOSECPU_LabelListTag *label);\r
+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);\r
+unsigned char *jitCompCallFunc(unsigned char *dst, void *func);\r
+unsigned char *jitCompInit(unsigned char *dst);\r
+void jitcRunBinary(void (*bin)(char *), HOSECPU_RuntimeEnvironment *env);\r
+\r
+// @randmt.c\r
+void randStatInit(unsigned int seed);\r
+void randStatNext();\r
+unsigned int randGetNextUInt32(void);\r
+\r
+// @screen.c\r
+static int iColor1[] = {\r
+       0x000000, 0xff0000, 0x00ff00, 0xffff00,\r
+       0x0000ff, 0xff00ff, 0x00ffff, 0xffffff\r
+};\r
+void putOsaskChar(int c, HOSECPU_RuntimeEnvironment *r);\r
+void checkString(HOSECPU_RuntimeEnvironment *r, int rxx, int pxx);\r
+void checkRect(HOSECPU_RuntimeEnvironment *r, int rxx);\r
+int loadColor(HOSECPU_RuntimeEnvironment *r, int rxx);\r
+\r
+// @usetek.c\r
+#if (USE_TEK5 != 0)\r
+#include "tek.h"\r
+int appackSub2(const UCHAR **pp, char *pif);\r
+int appackSub3u(const UCHAR **pp, char *pif);\r
+int tek5Decomp(UCHAR *buf, UCHAR *buf1, UCHAR *tmp);\r
+#endif\r
+\r
+\r
+#endif\r