From c19693980dcaa2dee811608bc5eb5728c0d952cb Mon Sep 17 00:00:00 2001 From: hikarupsp Date: Thu, 20 Mar 2014 17:44:57 +0900 Subject: [PATCH] =?utf8?q?MacOSX=E3=81=A7=E3=81=AE=E3=82=AD=E3=83=BC?= =?utf8?q?=E3=83=9C=E3=83=BC=E3=83=89=E5=85=A5=E5=8A=9B=E5=AF=BE=E5=BF=9C!?= =?utf8?q?=20=E4=BF=AE=E9=A3=BE=E3=82=AD=E3=83=BC=E3=81=AF=E6=9C=AA?= =?utf8?q?=E5=AE=9F=E8=A3=85=E3=80=82=20=E3=82=AD=E3=83=BC=E3=83=9C?= =?utf8?q?=E3=83=BC=E3=83=89=E9=96=A2=E9=80=A3=E3=81=AE=E5=AE=9A=E6=95=B0?= =?utf8?q?=E5=8C=96=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- dpndenv.c | 946 ++++++++++++++++++++----------------- function.c | 1544 ++++++++++++++++++++++++++++++------------------------------ main.c | 693 +++++++++++++-------------- osecpu.h | 495 +++++++++---------- 4 files changed, 1892 insertions(+), 1786 deletions(-) diff --git a/dpndenv.c b/dpndenv.c index 855795d..9ad5cbd 100644 --- a/dpndenv.c +++ b/dpndenv.c @@ -1,439 +1,509 @@ -#include "osecpu.h" - - -#if (DRV_OSNUM == 0x0002) -// -// for Mac OSX 32-bit -// -#include -#include - -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 -{ - 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 - -#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" + + +#if (DRV_OSNUM == 0x0002) +// +// for Mac OSX 32-bit +// +#include +#include + +@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; + CGImageRef image; + CGContextRef currentContext; + + currentContext = [[NSGraphicsContext currentContext] graphicsPort]; + colorSpace= CGColorSpaceCreateDeviceRGB(); + + // ビットマップコンテキストにvramイメージを生成 + _context = CGBitmapContextCreate (_buf, _sx, _sy, 8, 4 * _sx, colorSpace, (kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst)); + image = CGBitmapContextCreateImage(_context); + + // 生成したvramイメージをViewに描画 + CGContextDrawImage(currentContext, NSRectToCGRect(rect), image); + + // メモリ解放 + CFRelease(colorSpace); + CFRelease(image); +} + +- (void)keyDown:(NSEvent *)theEvent +{ + int i, j; + unichar kc; + + if([[theEvent characters] length] != 1){ + return; + } + + kc = [[theEvent characters] characterAtIndex:0]; + + // 通常キー + i = KEY_EMPTY; + if (kc == '\r') i = KEY_ENTER; + if (kc == 0x1b) i = KEY_ESC; + if (kc == 0x7F) i = KEY_BACKSPACE; + if (kc == '\t') i = KEY_TAB; + if (kc == NSPageUpFunctionKey) i = KEY_PAGEUP; + if (kc == NSPageDownFunctionKey) i = KEY_PAGEDWN; + if (kc == NSEndFunctionKey) i = KEY_END; + if (kc == NSHomeFunctionKey) i = KEY_HOME; + if (kc == NSLeftArrowFunctionKey) i = KEY_LEFT; + if (kc == NSRightArrowFunctionKey) i = KEY_RIGHT; + if (kc == NSUpArrowFunctionKey) i = KEY_UP; + if (kc == NSDownArrowFunctionKey) i = KEY_DOWN; + if (kc == NSInsertFunctionKey) i = KEY_INS; + if (kc == NSDeleteFunctionKey) i = KEY_DEL; + // 修飾キー + // TODO : 下の方の右辺、iとjが混ざっているのは修正すべき? + j = 0; + /* + if ((GetKeyState(VK_LCONTROL) & (1 << 15)) != 0) j |= KEY_MODIFIER_CONTROL_L; + if ((GetKeyState(VK_LMENU) & (1 << 15)) != 0) j |= KEY_MODIFIER_MENU_L; + if ((GetKeyState(VK_RCONTROL) & (1 << 15)) != 0) j |= KEY_MODIFIER_CONTROL_R; + if ((GetKeyState(VK_RMENU) & (1 << 15)) != 0) j |= KEY_MODIFIER_MENU_R; + if ((GetKeyState(VK_RSHIFT) & (1 << 15)) != 0) i |= KEY_MODIFIER_SHIFT_R; + if ((GetKeyState(VK_LSHIFT) & (1 << 15)) != 0) i |= KEY_MODIFIER_SHIFT_L; + if ((GetKeyState(VK_NUMLOCK) & (1 << 0)) != 0) i |= KEY_MODIFIER_NUMLOCK; + if ((GetKeyState(VK_CAPITAL) & (1 << 0)) != 0) i |= KEY_MODIFIER_CAPITAL; + */ + + NSLog(@"%X", kc); + if (isascii(kc)){ + i = kc; + } + + if (i != -1) { + putKeybuf(i | j); + } +} +/* +- (void)keyUp:(NSEvent *)theEvent +{ + NSLog(@"kUp"); +} + */ +@end + +@interface Main : NSObject +{ + int argc; + const unsigned char **argv; + char *winClosed; + OSECPUView *_view; + NSWindow *mainWindow; + NSMenu *mainMenu; +} + +- (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 +{ + // Sub thread + 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)windowDidBecomeKey:(NSNotification *)notification +{ + [mainWindow makeFirstResponder:_view]; +} + +- (void)openWin:(unsigned char *)buf sx:(int)sx sy:(int) sy winClosed:(char *)_winClosed +{ + mainWindow = [[NSWindow alloc] initWithContentRect: NSMakeRect(0, 0, sx, sy) styleMask: NSTitledWindowMask | NSMiniaturizableWindowMask | NSClosableWindowMask backing: NSBackingStoreBuffered defer: NO]; + mainWindow.delegate = self; + [mainWindow setTitle: @"osecpu"]; + [mainWindow center]; + [mainWindow makeKeyAndOrderFront:self]; + [mainWindow setReleasedWhenClosed:YES]; + + winClosed = _winClosed; + + _view = [[OSECPUView alloc] initWithFrame:NSMakeRect(0,0,sx,sy) buf:buf sx:sx sy:sy]; + [mainWindow.contentView addSubview:_view]; +} + +- (void)flushWin : (NSRect)rect +{ + [_view setNeedsDisplayInRect:rect]; +} + +@end + +id objc_main; + +int main(int argc, char **argv) +{ + // Main thread + NSAutoreleasePool* pool; + ProcessSerialNumber psn = {0, kCurrentProcess}; + + // ForegroundApplicationになれるように設定(こうしないとキーイベントが取得できない) + TransformProcessType(&psn, kProcessTransformToForegroundApplication); + + objc_main = [[Main alloc] init]; + NSApp = [NSApplication sharedApplication]; + + pool = [[NSAutoreleasePool alloc] init]; + [objc_main createThread:argc args:(const unsigned char **)argv]; + [NSApp run]; + [pool release]; + return 0; +} + +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; +} + +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 + +#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 = KEY_EMPTY; + 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; + // 修飾キー + // TODO : 下の方の右辺、iとjが混ざっているのは修正すべき? + j = 0; + if ((GetKeyState(VK_LCONTROL) & (1 << 15)) != 0) j |= KEY_MODIFIER_CONTROL_L; + if ((GetKeyState(VK_LMENU) & (1 << 15)) != 0) j |= KEY_MODIFIER_MENU_L; + if ((GetKeyState(VK_RCONTROL) & (1 << 15)) != 0) j |= KEY_MODIFIER_CONTROL_R; + if ((GetKeyState(VK_RMENU) & (1 << 15)) != 0) j |= KEY_MODIFIER_MENU_R; + if ((GetKeyState(VK_RSHIFT) & (1 << 15)) != 0) i |= KEY_MODIFIER_SHIFT_R; + if ((GetKeyState(VK_LSHIFT) & (1 << 15)) != 0) i |= KEY_MODIFIER_SHIFT_L; + if ((GetKeyState(VK_NUMLOCK) & (1 << 0)) != 0) i |= KEY_MODIFIER_NUMLOCK; + if ((GetKeyState(VK_CAPITAL) & (1 << 0)) != 0) i |= KEY_MODIFIER_CAPITAL; + if (j != 0) { + if ('A' <= wp && wp <= 'Z'){ + i = wp; + } + } + if (i != -1) { + putKeybuf(i | j); + return 0; + } + } + if (msg == WM_KEYUP) { + i = 0xfff; + } + 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); + 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" + #endif \ No newline at end of file diff --git a/function.c b/function.c index 5d10137..2a5765e 100644 --- a/function.c +++ b/function.c @@ -1,760 +1,784 @@ -#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" +#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 + // opt: + // 1 = ついでにウィンドウを更新する + // 2 = キー入力されるまでずっと待つ + if (r->ireg[0x32] == -1) { + // sleep forever (事実上実行は終了) + 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){ + // opt1:ついでにウィンドウを更新する + 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){ + // opt2:キー入力があったので戻る + continue; + } + // 時間指定ならここに来て終了 + break; + } + break; + + case 0xff43: + // junkApi_inkey(_i, mod) R31=mod; _i=R30 + // 1:peek(キーを「のぞき見る」だけで、バッファは進めない) + // 2:stdin + // 4,8: ソース指定. + // 16: shift, lock系を有効化. + // 32: 左右のshift系を区別する. + // カーソルキーの左右でR32は減少,増加する。 + // カーソルキーの上下でR33は減少,増加する。 + if (r->ireg[0x31] == 2) { + // 標準入力から + r->ireg[0x30] = fgetc(stdin); + if (r->ireg[0x30] == EOF){ + r->ireg[0x30] = KEY_EMPTY; + } + break; + } + r->ireg[0x30] |= -1; + if (keybuf_c > 0) { + // 入力された文字がある + r->ireg[0x30] = keybuf[keybuf_r]; + if ((r->ireg[0x31] & 16) == 0){ + // shift, lockキー([C]マークのあるキー)の無効化 + r->ireg[0x30] &= 0x3e3effff; + } + if ((r->ireg[0x31] & 32) == 0){ + // 左右の区別を無効化 + r->ireg[0x30] |= (r->ireg[0x30] >> 8) & 0xff0000; + } + if ((r->ireg[0x31] & 1) != 0) { + // peekでないならバッファを進める + keybuf_c--; + keybuf_r = (keybuf_r + 1) & (KEYBUFSIZ - 1); + } + } + r->ireg[0x32] = r->ireg[0x33] = 0; + if (r->ireg[0x30] == KEY_LEFT){ + r->ireg[0x32]--; + } + if (r->ireg[0x30] == KEY_UP){ + r->ireg[0x33]--; + } + if (r->ireg[0x30] == KEY_RIGHT){ + r->ireg[0x32]++; + } + if (r->ireg[0x30] == KEY_DOWN){ + 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; +} + + + diff --git a/main.c b/main.c index 9cc56e6..f24bb70 100644 --- a/main.c +++ b/main.c @@ -1,346 +1,347 @@ -#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" + +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) +{ + // TODO : あふれた場合のことを考慮すべき + 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); + } +} diff --git a/osecpu.h b/osecpu.h index abcfd5f..62b4f22 100644 --- a/osecpu.h +++ b/osecpu.h @@ -1,242 +1,253 @@ -#ifndef _HDLOAD_OSECPU -#define _HDLOAD_OSECPU 1 - -/* Visual Studio で fopen()やsprintf() などの古い関数を使用する時に出る警告を抑止する*/ -#define _CRT_SECURE_NO_WARNINGS 1 - -// -// Including stdc headers -// - -#include -#include -#include -#include -#include -#include - - -// -// 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 +#define _HDLOAD_OSECPU 1 + +/* Visual Studio で fopen()やsprintf() などの古い関数を使用する時に出る警告を抑止する*/ +#define _CRT_SECURE_NO_WARNINGS 1 + +// +// Including stdc headers +// + +#include +#include +#include +#include +#include +#include + + +// +// 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_EMPTY -1 +#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 + +#define KEY_MODIFIER_SHIFT_L (1 << 16) // [C] +#define KEY_MODIFIER_CONTROL_L (1 << 17) +#define KEY_MODIFIER_MENU_L (1 << 18) +#define KEY_MODIFIER_NUMLOCK (1 << 22) // [C] +#define KEY_MODIFIER_CAPITAL (1 << 23) // [C] +#define KEY_MODIFIER_SHIFT_R (1 << 24) // [C] +#define KEY_MODIFIER_CONTROL_R (1 << 25) +#define KEY_MODIFIER_MENU_R (1 << 26) + + +// +// 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 -- 2.11.0