|
|
1.1 ! root 1: /* ! 2: * UAE - The Un*x Amiga Emulator ! 3: * ! 4: * BeBox port specific stuff ! 5: * ! 6: * (c) 1996 Christian Bauer ! 7: */ ! 8: ! 9: #include <AppKit.h> ! 10: #include <InterfaceKit.h> ! 11: #include <KernelKit.h> ! 12: ! 13: #include <stdio.h> ! 14: #include <stdlib.h> ! 15: #include <string.h> ! 16: #define __STDC__ 1 ! 17: #define __GNU_LIBRARY__ ! 18: #include <getopt.h> ! 19: #undef __GNU_LIBRARY__ ! 20: #undef __STDC__ ! 21: ! 22: #ifndef __bebox__ ! 23: #error Compiling bebox.cpp, but __bebox__ unset. ! 24: #endif ! 25: ! 26: extern "C" { ! 27: #include "sysconfig.h" ! 28: #include "sysdeps.h" ! 29: #include "config.h" ! 30: #include "options.h" ! 31: #include "memory.h" ! 32: #include "custom.h" ! 33: #include "newcpu.h" ! 34: #include "disk.h" ! 35: #include "debug.h" ! 36: #include "xwin.h" ! 37: #include "os.h" ! 38: #include "filesys.h" ! 39: #include "keybuf.h" ! 40: #include "keyboard.h" ! 41: } ! 42: ! 43: ! 44: class UAEWindow; ! 45: class BitmapView; ! 46: class Emulator; ! 47: ! 48: ! 49: /* ! 50: * The BeOS application object ! 51: */ ! 52: ! 53: class UAE : public BApplication { ! 54: public: ! 55: UAE(); ! 56: virtual void ArgvReceived(int argc, char **argv); ! 57: virtual void ReadyToRun(void); ! 58: virtual bool QuitRequested(void); ! 59: virtual void AboutRequested(void); ! 60: ! 61: private: ! 62: BBitmap *the_bitmap; ! 63: UAEWindow *main_window; ! 64: Emulator *the_emulator; ! 65: }; ! 66: ! 67: ! 68: /* ! 69: * The window in which the Amiga graphics are displayed, handles I/O ! 70: */ ! 71: ! 72: class UAEWindow : public BWindow { ! 73: public: ! 74: UAEWindow(BRect frame, BBitmap *bitmap); ! 75: virtual bool QuitRequested(void); ! 76: virtual void WindowActivated(bool active); ! 77: ! 78: private: ! 79: BitmapView *main_view; ! 80: }; ! 81: ! 82: ! 83: /* ! 84: * A simple view class for blitting a bitmap on the screen ! 85: */ ! 86: ! 87: class BitmapView : public BView { ! 88: public: ! 89: BitmapView(BRect frame, BBitmap *bitmap); ! 90: virtual void Draw(BRect update); ! 91: void Draw(BRect from, BRect to); ! 92: ! 93: private: ! 94: BBitmap *the_bitmap; ! 95: }; ! 96: ! 97: ! 98: /* ! 99: * For running the emulation in its own thread ! 100: */ ! 101: ! 102: class Emulator { ! 103: public: ! 104: Emulator() {thread_running = FALSE;} ! 105: void Run(void); ! 106: void Quit(void); ! 107: ! 108: private: ! 109: static long thread_invoc(Emulator *obj); ! 110: void thread_func(void); ! 111: ! 112: thread_id the_thread; ! 113: bool thread_running; ! 114: }; ! 115: ! 116: ! 117: // Keyboard and mouse ! 118: int buttonstate[3]; ! 119: int newmousecounters; ! 120: int lastmx, lastmy; ! 121: ! 122: key_info old_key_info; ! 123: bool inwindow; ! 124: bool window_open; ! 125: ! 126: // Color map and bitmap ! 127: xcolnr xcolors[4096]; ! 128: struct vidbuf_description gfxvidinfo; ! 129: ! 130: int vsize, hsize, hpixels; ! 131: ! 132: BitmapView *bitmap_view; ! 133: UAEWindow *bitmap_window; ! 134: ! 135: ! 136: // Array for converting Be keycodes to Amiga keycodes ! 137: int keycode2amiga[128] = { ! 138: -1, AK_ESC, AK_F1, AK_F2, AK_F3, AK_F4, AK_F5, AK_F6, ! 139: AK_F7, AK_F8, AK_F9, AK_F10, AK_LALT, AK_mousestuff, AK_RALT, -1, ! 140: ! 141: -1, AK_BACKQUOTE, AK_1, AK_2, AK_3, AK_4, AK_5, AK_6, ! 142: AK_7, AK_8, AK_9, AK_0, AK_MINUS, AK_EQUAL, AK_BS, AK_HELP, ! 143: ! 144: AK_NPLPAREN, AK_RAMI, AK_NPLPAREN, AK_NPDIV, AK_NPMUL, AK_NPSUB, AK_TAB, AK_Q, ! 145: AK_W, AK_E, AK_R, AK_T, AK_Y, AK_U, AK_I, AK_O, ! 146: ! 147: AK_P, AK_LBRACKET, AK_RBRACKET, AK_BACKSLASH, AK_DEL, AK_NPRPAREN, AK_LAMI, AK_NP7, ! 148: AK_NP8, AK_NP9, AK_NPADD, AK_CAPSLOCK, AK_A, AK_S, AK_D, AK_F, ! 149: ! 150: AK_G, AK_H, AK_J, AK_K, AK_L, AK_SEMICOLON, AK_QUOTE, AK_RET, ! 151: AK_NP4, AK_NP5, AK_NP6, AK_LSH, AK_Z, AK_X, AK_C, AK_V, ! 152: ! 153: AK_B, AK_N, AK_M, AK_COMMA, AK_PERIOD, AK_SLASH, AK_RSH, AK_UP, ! 154: AK_NP1, AK_NP2, AK_NP3, AK_ENT, AK_CTRL, AK_LAMI, AK_SPC, AK_RAMI, ! 155: ! 156: AK_RALT, AK_LF, AK_DN, AK_RT, AK_NP0, AK_NPDEL, AK_LALT, AK_RALT, ! 157: AK_LTGT, -1, -1, -1, -1, -1, -1, -1, ! 158: ! 159: -1, -1, -1, -1, -1, -1, -1, -1, ! 160: -1, -1, -1, -1, -1, -1, -1, -1 ! 161: }; ! 162: ! 163: ! 164: /* ! 165: * Create application object and start it ! 166: */ ! 167: ! 168: main() ! 169: { ! 170: UAE *the_app; ! 171: ! 172: the_app = new UAE(); ! 173: the_app->Run(); ! 174: delete the_app; ! 175: ! 176: return 0; ! 177: } ! 178: ! 179: ! 180: /* ! 181: * UAE Constructor: Initialize member variables ! 182: */ ! 183: ! 184: UAE::UAE() : BApplication('UAEm') ! 185: { ! 186: the_bitmap = NULL; ! 187: the_emulator = NULL; ! 188: main_window = NULL; ! 189: window_open = FALSE; ! 190: } ! 191: ! 192: ! 193: /* ! 194: * Parse command line options ! 195: */ ! 196: ! 197: void usage(void) ! 198: { ! 199: printf("UAE - The Un*x Amiga emulator\n"); ! 200: printf("Summary of command-line options:\n"); ! 201: printf(" -h : Print help\n"); ! 202: printf(" -m VOLNAME:mount_point : mount file system at <mount point> as AmigaDOS\n" ! 203: " volume VOLNAME:\n"); ! 204: printf(" -M VOLNAME:mount_point : like -m, but mount read-only\n"); ! 205: printf(" -a : Don't mount the harddisk file automatically.\n" ! 206: " Useful only for testing.\n"); ! 207: printf(" -s : Emulate 1MB slow memory at 0xC00000\n"); ! 208: printf(" -F n : Emulate n MB fast memory at 0x200000\n"); ! 209: printf(" -f n : Set the frame rate to 1/n\n"); ! 210: printf(" -d : Draw the screen with the right aspect\n"); ! 211: printf(" -D : Start up the built-in debugger\n"); ! 212: printf(" -[0123] file : Use file instead of df[0123].adf as disk image file\n"); ! 213: printf(" -r file : Use file as ROM image instead of kick.rom\n"); ! 214: printf(" -p filename : Use filename to save printer output (may be LPT1: ?)\n"); ! 215: printf(" -J : Fake joystick emulation with the numeric pad.\n"); ! 216: printf(" -g : Turn on gfx-lib replacement.\n"); ! 217: printf(" -d mode : Select resolution with the mode parameter.\n"); ! 218: printf(" -H mode : Set the number of colors with the mode parameter.\n"); ! 219: printf("\n"); ! 220: printf("Valid resolutions: 0 (320x200); 1 (320x240); 2 (320x400); 3 (800x600);\n" ! 221: " 4 (800x600, correct aspect)\n" ! 222: "Valid color modes: 0 (256 colors); 1 (32768 colors); 2 (65536 colors)\n" ! 223: "UAE may choose to ignore the color mode/resolution setting.\n"); ! 224: } ! 225: ! 226: void UAE::ArgvReceived(int argc, char **argv) ! 227: { ! 228: int c; ! 229: ! 230: while(((c = getopt(argc, argv, "Df:gd:hF:asJm:M:0:1:2:3:r:H:p:")) != EOF)) switch(c) { ! 231: case 'h': usage(); exit(0); ! 232: ! 233: case '0': strncpy(df0, optarg, 255); df0[255] = 0; break; ! 234: case '1': strncpy(df1, optarg, 255); df1[255] = 0; break; ! 235: case '2': strncpy(df2, optarg, 255); df2[255] = 0; break; ! 236: case '3': strncpy(df3, optarg, 255); df3[255] = 0; break; ! 237: case 'r': strncpy(romfile, optarg, 255); romfile[255] = 0; break; ! 238: case 'p': strncpy(prtname, optarg, 255); prtname[255] = 0; break; ! 239: case 'm': ! 240: case 'M': ! 241: { ! 242: /* mount file system (repeatable) ! 243: * syntax: [-m | -M] VOLNAME:/mount_point ! 244: * example: -M CDROM:/cdrom -m UNIXFS:./disk ! 245: */ ! 246: static int mount_seen = 0; ! 247: char buf[256]; ! 248: char *s2; ! 249: int readonly = (c == 'M'); ! 250: ! 251: if (mount_seen) ! 252: fprintf(stderr, "warning: multiple mounts confuse Kickstart 1.3\n"); ! 253: mount_seen = 1; ! 254: strncpy(buf, optarg, 255); buf[255] = 0; ! 255: s2 = strchr(buf, ':'); ! 256: if(s2) { ! 257: *s2++ = '\0'; ! 258: add_filesys_unit(buf, s2, readonly); ! 259: } else { ! 260: fprintf(stderr, "Usage: [-m | -M] VOLNAME:/mount_point\n"); ! 261: } ! 262: } ! 263: break; ! 264: ! 265: case 'f': framerate = atoi(optarg); break; ! 266: case 'D': use_debugger = 1; break; ! 267: case 'J': fake_joystick = 1; break; ! 268: case 'a': automount_uaedev = 0; break; ! 269: case 's': use_slow_mem = 1; break; ! 270: case 'g': use_gfxlib = 1; break; ! 271: ! 272: case 'F': ! 273: fastmem_size = atoi(optarg) * 0x100000; ! 274: if (fastmem_size != 0x100000 && fastmem_size != 0x200000 ! 275: && fastmem_size != 0x400000 && fastmem_size != 0x800000) ! 276: { ! 277: fastmem_size = 0; ! 278: fprintf(stderr, "Unsupported fastmem size!\n"); ! 279: } ! 280: ! 281: break; ! 282: ! 283: case 'd': ! 284: screen_res = atoi(optarg); ! 285: if (screen_res >= 0 && screen_res <= 4) { ! 286: } else { ! 287: fprintf(stderr, "Bad video mode selected. Using default.\n"); ! 288: screen_res = 3; ! 289: } ! 290: dont_want_aspect = screen_res != 4; ! 291: use_lores = screen_res < 3; ! 292: break; ! 293: ! 294: case 'H': ! 295: color_mode = atoi(optarg); ! 296: if (color_mode < 0 || color_mode > 2) { ! 297: fprintf(stderr, "Bad color mode selected. Using default.\n"); ! 298: color_mode = 0; ! 299: } ! 300: break; ! 301: } ! 302: } ! 303: ! 304: ! 305: /* ! 306: * Arguments processed, create and start emulation ! 307: */ ! 308: ! 309: void UAE::ReadyToRun(void) ! 310: { ! 311: vsize = dont_want_aspect ? numscrlines : numscrlines*2; ! 312: hsize = use_lores ? 400 : 800; ! 313: hpixels = use_lores ? 320 : 796; ! 314: ! 315: // Allocate bitmap ! 316: the_bitmap = new BBitmap(BRect(0, 0, hsize-1, vsize-1), B_COLOR_8_BIT); ! 317: ! 318: // Set up vidinfo ! 319: gfxvidinfo.bufmem = (char *)the_bitmap->Bits(); ! 320: gfxvidinfo.rowbytes = the_bitmap->BytesPerRow(); ! 321: gfxvidinfo.pixbytes = 1; ! 322: gfxvidinfo.maxblocklines = 100; ! 323: ! 324: // Open window ! 325: main_window = new UAEWindow(BRect(0, 0, hpixels-1, vsize-1), the_bitmap); ! 326: ! 327: // Initialize mouse and keyboard variables ! 328: buttonstate[0] = buttonstate[1] = buttonstate[2] = FALSE; ! 329: lastmx = lastmy = 0; ! 330: newmousecounters = FALSE; ! 331: inwindow = TRUE; ! 332: ! 333: // Start emulation ! 334: the_emulator = new Emulator; ! 335: the_emulator->Run(); ! 336: } ! 337: ! 338: ! 339: /* ! 340: * Quit requested (either by menu or by closing the window) ! 341: */ ! 342: ! 343: bool UAE::QuitRequested(void) ! 344: { ! 345: if (BApplication::QuitRequested()) { ! 346: ! 347: // Stop emulation ! 348: if (the_emulator) { ! 349: the_emulator->Quit(); ! 350: delete the_emulator; ! 351: } ! 352: ! 353: // Deallocate bitmap ! 354: if (the_bitmap) ! 355: delete the_bitmap; ! 356: ! 357: return TRUE; ! 358: } ! 359: return FALSE; ! 360: } ! 361: ! 362: ! 363: /* ! 364: * Display "about" window ! 365: */ ! 366: ! 367: void UAE::AboutRequested(void) ! 368: { ! 369: char str[256]; ! 370: ! 371: sprintf(str, "UAE V0.5.3 by Bernd Schmidt\nBeBox port by Christian Bauer"); ! 372: BAlert *the_alert = new BAlert("", str, "OK"); ! 373: the_alert->Go(); ! 374: } ! 375: ! 376: ! 377: /* ! 378: * UAE Window constructor ! 379: */ ! 380: ! 381: UAEWindow::UAEWindow(BRect frame, BBitmap *bitmap) : BWindow(frame, "UAE", B_TITLED_WINDOW, B_NOT_RESIZABLE) ! 382: { ! 383: int r, g, b, i; ! 384: ! 385: // Move window to right position ! 386: MoveTo(80, 60); ! 387: ! 388: // Create bitmap view ! 389: Lock(); ! 390: main_view = new BitmapView(frame, bitmap); ! 391: AddChild(main_view); ! 392: main_view->GetKeys(&old_key_info, FALSE); ! 393: Unlock(); ! 394: ! 395: bitmap_view = main_view; ! 396: bitmap_window = this; ! 397: ! 398: // Initialize xcolors ! 399: i = 0; ! 400: for (r=0; r<16; r++) { ! 401: for (g=0; g<16; g++) { ! 402: for (b=0; b<16; b++) ! 403: xcolors[i++] = index_for_color(r<<4 | r, g<<4 | g, b<<4 | b); ! 404: } ! 405: } ! 406: ! 407: // Show window ! 408: Show(); ! 409: window_open = TRUE; ! 410: } ! 411: ! 412: ! 413: /* ! 414: * Closing the window quits UAE ! 415: */ ! 416: ! 417: bool UAEWindow::QuitRequested(void) ! 418: { ! 419: window_open = FALSE; ! 420: be_app->PostMessage(B_QUIT_REQUESTED); ! 421: return TRUE; ! 422: } ! 423: ! 424: ! 425: /* ! 426: * Window was (de)activated ! 427: */ ! 428: ! 429: void UAEWindow::WindowActivated(bool active) ! 430: { ! 431: inwindow = active; ! 432: } ! 433: ! 434: ! 435: /* ! 436: * Bitmap view constructor ! 437: */ ! 438: ! 439: BitmapView::BitmapView(BRect frame, BBitmap *bitmap) : BView(frame, "", B_FOLLOW_NONE, B_WILL_DRAW) ! 440: { ! 441: the_bitmap = bitmap; ! 442: } ! 443: ! 444: ! 445: /* ! 446: * Blit the bitmap ! 447: */ ! 448: ! 449: void BitmapView::Draw(BRect update) ! 450: { ! 451: DrawBitmap(the_bitmap, update, update); ! 452: } ! 453: ! 454: void BitmapView::Draw(BRect from, BRect to) ! 455: { ! 456: DrawBitmap(the_bitmap, from, to); ! 457: } ! 458: ! 459: ! 460: /* ! 461: * Start main emulation thread ! 462: */ ! 463: ! 464: void Emulator::Run(void) ! 465: { ! 466: // Initialize everything ! 467: produce_sound = FALSE; ! 468: init_joystick(); ! 469: keybuf_init (); ! 470: memory_init(); ! 471: custom_init(); ! 472: DISK_init(); ! 473: init_m68k(); ! 474: MC68000_reset(); ! 475: ! 476: // Start the emulation thread ! 477: the_thread = spawn_thread(thread_invoc, "UAE 68000", B_NORMAL_PRIORITY, this); ! 478: resume_thread(the_thread); ! 479: thread_running = TRUE; ! 480: } ! 481: ! 482: ! 483: /* ! 484: * Stop main emulation thread ! 485: */ ! 486: ! 487: void Emulator::Quit(void) ! 488: { ! 489: // Kill the thread if it is running ! 490: if (thread_running) { ! 491: kill_thread(the_thread); ! 492: thread_running = FALSE; ! 493: } ! 494: ! 495: close_joystick(); ! 496: } ! 497: ! 498: ! 499: /* ! 500: * The thread's main function ! 501: */ ! 502: ! 503: long Emulator::thread_invoc(Emulator *obj) ! 504: { ! 505: obj->thread_func(); ! 506: return 0; ! 507: } ! 508: ! 509: void Emulator::thread_func(void) ! 510: { ! 511: // This jumps to MC68000_run() and executes the main loop ! 512: debug(); ! 513: thread_running = FALSE; ! 514: } ! 515: ! 516: ! 517: /* ! 518: * Redraw a line ! 519: */ ! 520: ! 521: void flush_line(int y) ! 522: { ! 523: if (window_open) { ! 524: bitmap_window->Lock(); ! 525: bitmap_view->Draw(BRect(0, y, hpixels-1, y)); ! 526: bitmap_window->Unlock(); ! 527: } ! 528: } ! 529: ! 530: ! 531: /* ! 532: * Redraw a block ! 533: */ ! 534: ! 535: void flush_block(int ystart, int ystop) ! 536: { ! 537: int xs = use_lores ? prev_max_diwstop - 328 : 0; ! 538: ! 539: if (window_open) { ! 540: bitmap_window->Lock(); ! 541: bitmap_view->Draw(BRect(xs, ystart, hpixels+xs-1, ystop), BRect(0, ystart, hpixels-1, ystop)); ! 542: bitmap_window->Unlock(); ! 543: } ! 544: } ! 545: ! 546: ! 547: /* ! 548: * Redraw the screen ! 549: */ ! 550: ! 551: void flush_screen(int ystart, int ystop) ! 552: { ! 553: } ! 554: ! 555: ! 556: /* ! 557: * Poll mouse and keyboard ! 558: */ ! 559: ! 560: void handle_events(void) ! 561: { ! 562: key_info the_key_info; ! 563: int be_code, be_byte, be_bit, amiga_code; ! 564: BPoint mouse_point; ! 565: ulong mouse_buttons; ! 566: ! 567: // Keyboard ! 568: if (window_open && inwindow) { ! 569: bitmap_window->Lock(); ! 570: bitmap_view->GetKeys(&the_key_info, FALSE); ! 571: bitmap_window->Unlock(); ! 572: ! 573: for (be_code=0; be_code<0x80; be_code++) { ! 574: be_byte = be_code >> 3; ! 575: be_bit = 1 << (~be_code & 7); ! 576: ! 577: // Key state changed? ! 578: if ((the_key_info.key_states[be_byte] & be_bit) ! 579: != (old_key_info.key_states[be_byte] & be_bit)) { ! 580: ! 581: amiga_code = keycode2amiga[be_code]; ! 582: if (the_key_info.key_states[be_byte] & be_bit) { ! 583: ! 584: // Key pressed ! 585: if (amiga_code == AK_mousestuff) ! 586: togglemouse(); ! 587: else ! 588: record_key(amiga_code << 1); ! 589: } else { ! 590: ! 591: // Key released ! 592: record_key((amiga_code << 1) | 1); ! 593: } ! 594: } ! 595: } ! 596: old_key_info = the_key_info; ! 597: ! 598: // "Affengriff" ! 599: if ((the_key_info.key_states[0x5c >> 3] & (1 << (~0x5c & 7))) ! 600: && (the_key_info.key_states[0x5d >> 3] & (1 << (~0x5d & 7))) ! 601: && (the_key_info.key_states[0x5f >> 3] & (1 << (~0x5f & 7)))) ! 602: MC68000_reset(); ! 603: ! 604: // Scroll lock toggles inhibit_frame ! 605: inhibit_frame = the_key_info.key_states[0x0f >> 3] & (1 << (~0x0f & 7)); ! 606: } ! 607: ! 608: // Mouse ! 609: if (window_open && inwindow) { ! 610: bitmap_window->Lock(); ! 611: bitmap_view->GetMouse(&mouse_point, &mouse_buttons, FALSE); ! 612: bitmap_window->Unlock(); ! 613: lastmx = mouse_point.x; ! 614: lastmy = mouse_point.y; ! 615: ! 616: buttonstate[0] = mouse_buttons & B_PRIMARY_MOUSE_BUTTON; ! 617: buttonstate[1] = mouse_buttons & B_TERTIARY_MOUSE_BUTTON; ! 618: buttonstate[2] = mouse_buttons & B_SECONDARY_MOUSE_BUTTON; ! 619: } ! 620: } ! 621: ! 622: ! 623: int debuggable(void) ! 624: { ! 625: return TRUE; ! 626: } ! 627: ! 628: int needmousehack(void) ! 629: { ! 630: return TRUE; ! 631: } ! 632: ! 633: void LED(int on) ! 634: { ! 635: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.