@interface OSECPUView : NSView
{
- unsigned char *_buf;
- int _sx;
- int _sy;
+ unsigned char *_buf;
+ int _sx;
+ int _sy;
CGContextRef _context;
}
@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;
+ 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);
+ 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);
}
@end
@interface Main : NSObject<NSWindowDelegate>
{
- int argc;
- const unsigned char **argv;
- char *winClosed;
- OSECPUView *_view;
+ int argc;
+ const unsigned char **argv;
+ char *winClosed;
+ OSECPUView *_view;
}
- (void)runApp;
@implementation Main
- (void)runApp
{
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- HeavyOSECPUMain(argc, (char **)argv);
- [NSApp terminate:self];
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ HeavyOSECPUMain(argc, (char **)argv);
+ [NSApp terminate:self];
[pool release];
}
- (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];
+ 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;
+ *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 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 drawRect:rect];
+ [_view drawRect:rect];
}
@end
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];
+ 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;
+ return 0;
}
void drv_openWin(int sx, int sy, unsigned char *buf, char *winClosed)
{
- [objc_main openWin:buf sx:sx sy:sy winClosed: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)];
+ [objc_main flushWin:NSMakeRect(x0,y0,sx,sy)];
}
void drv_sleep(int msec)
{
- [NSThread sleepForTimeInterval:0.001*msec];
- return;
+ [NSThread sleepForTimeInterval:0.001*msec];
+ return;
}
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.cbWndExtra = 0;
wc.hInstance = dw.hi;
wc.hIcon = (HICON)LoadImage(NULL, MAKEINTRESOURCE(IDI_APPLICATION),
- IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
+ 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);
+ IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
wc.hbrBackground = (HBRUSH)COLOR_APPWORKSPACE;
wc.lpszMenuName = NULL;
wc.lpszClassName = L"WinClass";
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);
+ CW_USEDEFAULT, CW_USEDEFAULT, x, y, NULL, NULL, dw.hi, NULL);
if (dw.hw == NULL)
return 1;
ShowWindow(dw.hw, SW_SHOW);
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) /* エラーもしくは終了メッセージ */
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.biBitCount = 32;
dw.bmi.bmiHeader.biCompression = BI_RGB;
dw.winClosed = winClosed;
-
+
threadhandle = CreateThread(NULL, 0, (void *)&winthread, NULL, 0, (void *)&i);
-
+
return;
}
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);
+ 0, 0, 0, w.win.ysiz, w.win.buf, &dw.bmi, DIB_RGB_COLORS);
EndPaint(dw.hw, &ps);
}
if (msg == WM_DESTROY) {
}
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 (strncmp(argv[j], tag, l) == 0) {
r = argv[j] + l;
if (i == 0){
- break;
- }
+ break;
+ }
i--;
}
}
if (strchr(argv[j], ':') == NULL) {
r = argv[j];
if (i == 0){
- break;
- }
+ break;
+ }
i--;
}
}
}
if (i != 0){
- r = NULL;
- }
+ r = NULL;
+ }
return r;
}
void devFunc0006(int mod, int sx, int sy, int x, int y, int c, int len, unsigned char *puc, HOSECPU_RuntimeEnvironment *r)
{
- int xx;
- int yy;
- int i, ddx, ddy, j, ch, dx, dy;
-
+ int xx;
+ int yy;
+ int i, ddx, ddy, j, ch, dx, dy;
+
if (sy == 0){
- sy = sx;
- }
+ 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++) {
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;
- }
+ mainWindow.vram[(x + dx) + (y + dy) * mainWindow.xsize] = c;
+ }
}
}
x += 8;
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;
- }
+ 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++;
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;
- }
- }
+ 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 i = 0, base, j, k;
char sign;
-
+
while (plen > 0) {
if (i >= buflen){
(*(r->errHndl))(r);
- }
+ }
if (*p != 0x01) {
buf[i++] = *p++;
plen--;
plen--;
if (qlen < 4){
(*(r->errHndl))(r);
- }
+ }
base = q[0];
sign = 0;
if (base == 0){
- base = 16;
- }
+ base = 16;
+ }
#if (REVISION == 1)
if (base == -3){
- base = 10;
- }
+ base = 10;
+ }
#endif
if (base == -1){
- base = 10;
- }
+ 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 = '+';
- }
+ sign = '+';
+ }
if (j < 0) {
- sign = '-'; j *= -1;
- }
+ sign = '-'; j *= -1;
+ }
} else{
// jは符号無し整数.
if ((q[2] & 8) != 0 && j != 0){
- sign = '+';
- }
+ sign = '+';
+ }
}
for (k = q[1] - 1; k >= 0; k--) {
buf[i + k] = (j % base) + 0x10;
if ((q[2] & 2) == 0 && j == 0) {
for (k = 0; k < q[1] - 1; k++) {
if (buf[i + k] != 0x10){
- break;
- }
+ break;
+ }
buf[i + k] = ' ';
}
}
if (sign != 0) {
if (k > 0){
- k--;
- }
+ 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;
}
void devFunc(HOSECPU_RuntimeEnvironment *r)
{
FILE *fp;
- int i, c;
+ int i, c;
int x, y, len, dx, dy;
unsigned char *puc;
unsigned char pucbuf[256];
-
- //サイズを節約するためにEBPを128バイトずらしているのを元に戻す
+
+ //サイズを節約するためにEBPを128バイトずらしているのを元に戻す
r = (HOSECPU_RuntimeEnvironment *) (((char *)r) - 128);
if (r->winClosed != 0){
longjmp(*(r->setjmpEnv), 1);
- }
+ }
if (0xff44 <= r->ireg[0x30] && r->ireg[0x30] <= 0xff48) {
if (mainWindow.vram == NULL) {
mainWindow.xsize = 640;
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:
- /* return: 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:
- /* return: 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:
- /* return: 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:
- fwrite(r->preg[0x31].p, 1, r->ireg[0x31], stdout);
- break;
-
- case 0xff06:
- // R31はリターンコード.
- // これを反映すべきだが、現状は手抜きでいつも正常終了.
- longjmp(*(r->setjmpEnv), 1);
- break;
-
- case 0xff07:
- // マシになった文字列表示.OSASK文字列に対応.offにすれば通常の文字列処理もできる.現状はonのみサポート.
- checkString(r, 0x31, 0x31);
- devFunc0001(r->ireg[0x31], r->preg[0x31].p, r);
- break;
-
- case 0xff08:
- // 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:
- // たぶん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:
- /* 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:
- /* 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:
- 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:
- // 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:
- 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:
- //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 {
+ case 0xff00:
+ printf("R31=%d(dec)\n", r->ireg[0x31]);
+ break;
+
+ case 0xff01:
+ /* return: 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:
+ /* return: 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:
+ /* return: 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:
+ fwrite(r->preg[0x31].p, 1, r->ireg[0x31], stdout);
+ break;
+
+ case 0xff06:
+ // R31はリターンコード.
+ // これを反映すべきだが、現状は手抜きでいつも正常終了.
+ longjmp(*(r->setjmpEnv), 1);
+ break;
+
+ case 0xff07:
+ // マシになった文字列表示.OSASK文字列に対応.offにすれば通常の文字列処理もできる.現状はonのみサポート.
+ checkString(r, 0x31, 0x31);
+ devFunc0001(r->ireg[0x31], r->preg[0x31].p, r);
+ break;
+
+ case 0xff08:
+ // 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:
+ // たぶん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:
+ /* 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:
+ /* 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:
+ 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:
+ // 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:
+ 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:
+ //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(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: /* seedの指定 */
- randStatInit(r->ireg[0x31]);
- break;
-
- case 0xff4b: /* 適当なseedを提供 */
- r->ireg[0x30] = (int)(time(NULL) ^ (long)0x55555555);
- break;
-
- case 0xff4c:
- 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);
-
+ 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(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: /* seedの指定 */
+ randStatInit(r->ireg[0x31]);
+ break;
+
+ case 0xff4b: /* 適当なseedを提供 */
+ r->ireg[0x30] = (int)(time(NULL) ^ (long)0x55555555);
+ break;
+
+ case 0xff4c:
+ 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;
}
int HeavyOSECPUMain(int argc, char **argv)
{
- FILE *fp;
- unsigned char *jitbuf, *sysjit00, *sysjit;
- unsigned char *systmp0, *systmp1, *systmp2;
- unsigned char *opTbl;
- HOSECPU_LabelListTag *label;
- int tmpsiz, i;
- jmp_buf setjmpEnv;
+ FILE *fp;
+ unsigned char *jitbuf, *sysjit00, *sysjit;
+ unsigned char *systmp0, *systmp1, *systmp2;
+ unsigned char *opTbl;
+ HOSECPU_LabelListTag *label;
+ int tmpsiz, i;
+ jmp_buf setjmpEnv;
double tm0, tm1, tm2;
HOSECPU_PointerControlTag *ptrCtrl;
- unsigned char *syslib;
- int argDebug = 0, stacksiz = 1;
- const char *cp;
- HOSECPU_RuntimeEnvironment env;
+ unsigned char *syslib;
+ int argDebug = 0, stacksiz = 1;
+ const char *cp;
+ HOSECPU_RuntimeEnvironment env;
void(*jitfunc)(char *);
- unsigned char *jp;
-
- //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;
+ unsigned char *jp;
+
+ //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(1024 * 1024); /* とりあえず1MBで */
//unsigned char *sysjit0 = mallocRWE(SJITSIZ1), *sysjit1 = sysjit0, *sysjit00 = sysjit0;
// syslib.oseのjitc結果を格納する領域を確保。
sysjit00 = mallocRWE(SJITSIZ1);
- sysjit = sysjit00;
+ sysjit = sysjit00;
// 現在の、jitc結果を格納するメモリへの書き込み位置のアドレス
- // sysjit: 現在のjitc書き込み位置
- // sysjit00: jitc結果の先頭
- //ワークメモリを三つくらいもらう
+ // sysjit: 現在のjitc書き込み位置
+ // sysjit00: jitc結果の先頭
+ //ワークメモリを三つくらいもらう
systmp0 = malloc(SYSTMP0SIZ); /* syslibのjitc用 */
systmp1 = malloc(SYSTMP1SIZ);
systmp2 = malloc(1024 * 1024);
-
- opTbl = malloc(256);
+
+ 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;
+
+ /* syslibの読み込み */
+ syslib = Init_LoadSysLib(argv[0], systmp0);
+
+ sysjit = jitCompInit(sysjit);
+ sysjit00 = sysjit;
// labelはjitc0()内で初期化される。
i = jitc0(&sysjit, sysjit00 + SJITSIZ1, 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);
-
- /* クロック初期化 */
+
+ /* アプリバイナリの読み込み */
+ LoadAppBin(&env);
+
+ /* クロック初期化 */
tm0 = clock() / (double)CLOCKS_PER_SEC;
-
+
if (env.appBin[2] == 0xf0) {
- // tek5圧縮がかかっている
+ // tek5圧縮がかかっている
#if (USE_TEK5 != 0)
env.appSize1 = tek5Decomp(env.appBin + 2, env.appBin + env.appSize0, systmp0) + 2;
#else
return 1;
}
}
- //デバッグモード指定
+ //デバッグモード指定
cp = searchArg(argc, (const char **)argv, "debug:", 0);
if (cp != NULL){
- argDebug = *cp - '0';
- }
- //スタックサイズ指定(MiB単位)
+ argDebug = *cp - '0';
+ }
+ //スタックサイズ指定(MiB単位)
cp = searchArg(argc, (const char **)argv, "stack:", 0);
if (cp != NULL){
- stacksiz = strtol(cp, NULL, 0);
- }
+ stacksiz = strtol(cp, NULL, 0);
+ }
jp = jitbuf; /* JIT-pointer */
-
+
/* フロントエンドコードをバックエンドコードに変換する */
if ((env.appBin[2] & 0xf0) != 0) {
systmp0[0] = env.appBin[0];
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コンパイル
+
+ //JITコンパイル
i = jitc0(&jp, jitbuf + 1024 * 1024, systmp0, systmp0 + tmpsiz, env.executionLevel, label);
if (i == 1){
- fputs("app-file header error.\n", stderr);
+ fputs("app-file header error.\n", stderr);
return 1;
- }
+ }
if (i != 0){
- return 1;
- }
+ 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;
env.preg[0x28].p = p28;
env.preg[0x28].typ = 0; // TYP_CODE
env.autoSleep = 0;
env.setjmpEnv = &setjmpEnv;
env.lastConsoleChar = '\n';
-
+
env.label = label;
env.maxLabels = JITC_MAXLABELS;
env.jitbuf = jp;
env.jitbuf1 = jitbuf + 1024 * 1024;
env.errHndl = &errorHandler;
-
+
env.dbgr = 0;
if (searchArg(argc, (const char **)argv, "dbgr:1", 0) != NULL){
- env.dbgr = 1;
- }
-
+ 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(setjmpEnv) == 0){
(*jitfunc)(((char *)&env) + 128); /* サイズを節約するためにEBPを128バイトずらす */
- }
+ }
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);
unsigned char *Init_LoadSysLib(char argv0[], unsigned char *tmpWorkMemory)
{
- unsigned char *syslib;
- FILE *fp;
- unsigned char *up;
- int appsize;
-
- /* syslibの読み込み */
+ unsigned char *syslib;
+ FILE *fp;
+ unsigned char *up;
+ int appsize;
+
+ /* syslibの読み込み */
syslib = malloc(SYSLIBSIZ1);
fp = fopen(SYSLIB_OSE, "rb");
if (fp == NULL) {
strcpy((char *)syslib + 1, argv0);
up = syslib + 1;
while (*up != '\0'){
- up++;
- }
+ up++;
+ }
while (*up != '/' && *up != 0x5c){
- up--;
- }
+ 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);
+ exit(EXIT_FAILURE);
}
appsize = fread(syslib, 1, SYSLIBSIZ1 - 4, fp);
fclose(fp);
syslib[0] = 0x05;
syslib[1] = 0x1b;
}
-
+
fp = fopen("syslib_dbg.ose", "wb");
fwrite(syslib, 1, SYSLIBSIZ1, fp);
fclose(fp);
- return syslib;
+ return syslib;
}
void LoadAppBin(HOSECPU_RuntimeEnvironment *env)
{
- FILE *fp;
- const char *fileName;
+ FILE *fp;
+ const char *fileName;
/* アプリバイナリの読み込み */
if (env->mainArgc <= 1) {
- //アプリ名未指定なので何事もなく終了
- exit(EXIT_SUCCESS);
- }
+ //アプリ名未指定なので何事もなく終了
+ exit(EXIT_SUCCESS);
+ }
fileName = env->mainArgv[1];
- //アプリ名先頭に:n:をつけることでレベルnでの実行が可能?
+ //アプリ名先頭に: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;
+ env->appSize1 = env->appSize0;
fclose(fp);
-
+
if (env->appSize0 >= APPSIZ1 - 4) {
fputs("app-file too large.\n", stderr);
exit(EXIT_FAILURE);