home *** CD-ROM | disk | FTP | other *** search
- /*
- * UAE - The Un*x Amiga Emulator
- *
- * BeBox port specific stuff
- *
- * (c) 1996 Christian Bauer
- */
-
- #include <AppKit.h>
- #include <InterfaceKit.h>
- #include <KernelKit.h>
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #define __STDC__ 1
- #define __GNU_LIBRARY__
- #include <getopt.h>
- #undef __GNU_LIBRARY__
- #undef __STDC__
-
- #ifndef __bebox__
- #error Compiling bebox.cpp, but __bebox__ unset.
- #endif
-
- extern "C" {
- #include "sysconfig.h"
- #include "sysdeps.h"
- #include "config.h"
- #include "options.h"
- #include "memory.h"
- #include "custom.h"
- #include "newcpu.h"
- #include "disk.h"
- #include "debug.h"
- #include "xwin.h"
- #include "os.h"
- #include "filesys.h"
- #include "keybuf.h"
- #include "keyboard.h"
- }
-
-
- class UAEWindow;
- class BitmapView;
- class Emulator;
-
-
- /*
- * The BeOS application object
- */
-
- class UAE : public BApplication {
- public:
- UAE();
- virtual void ArgvReceived(int argc, char **argv);
- virtual void ReadyToRun(void);
- virtual bool QuitRequested(void);
- virtual void AboutRequested(void);
-
- private:
- BBitmap *the_bitmap;
- UAEWindow *main_window;
- Emulator *the_emulator;
- };
-
-
- /*
- * The window in which the Amiga graphics are displayed, handles I/O
- */
-
- class UAEWindow : public BWindow {
- public:
- UAEWindow(BRect frame, BBitmap *bitmap);
- virtual bool QuitRequested(void);
- virtual void WindowActivated(bool active);
-
- private:
- BitmapView *main_view;
- };
-
-
- /*
- * A simple view class for blitting a bitmap on the screen
- */
-
- class BitmapView : public BView {
- public:
- BitmapView(BRect frame, BBitmap *bitmap);
- virtual void Draw(BRect update);
- void Draw(BRect from, BRect to);
-
- private:
- BBitmap *the_bitmap;
- };
-
-
- /*
- * For running the emulation in its own thread
- */
-
- class Emulator {
- public:
- Emulator() {thread_running = FALSE;}
- void Run(void);
- void Quit(void);
-
- private:
- static long thread_invoc(Emulator *obj);
- void thread_func(void);
-
- thread_id the_thread;
- bool thread_running;
- };
-
-
- // Keyboard and mouse
- int buttonstate[3];
- int newmousecounters;
- int lastmx, lastmy;
-
- key_info old_key_info;
- bool inwindow;
- bool window_open;
-
- // Color map and bitmap
- xcolnr xcolors[4096];
- struct vidbuf_description gfxvidinfo;
-
- int vsize, hsize, hpixels;
-
- BitmapView *bitmap_view;
- UAEWindow *bitmap_window;
-
-
- // Array for converting Be keycodes to Amiga keycodes
- int keycode2amiga[128] = {
- -1, AK_ESC, AK_F1, AK_F2, AK_F3, AK_F4, AK_F5, AK_F6,
- AK_F7, AK_F8, AK_F9, AK_F10, AK_LALT, AK_mousestuff, AK_RALT, -1,
-
- -1, AK_BACKQUOTE, AK_1, AK_2, AK_3, AK_4, AK_5, AK_6,
- AK_7, AK_8, AK_9, AK_0, AK_MINUS, AK_EQUAL, AK_BS, AK_HELP,
-
- AK_NPLPAREN, AK_RAMI, AK_NPLPAREN, AK_NPDIV, AK_NPMUL, AK_NPSUB, AK_TAB, AK_Q,
- AK_W, AK_E, AK_R, AK_T, AK_Y, AK_U, AK_I, AK_O,
-
- AK_P, AK_LBRACKET, AK_RBRACKET, AK_BACKSLASH, AK_DEL, AK_NPRPAREN, AK_LAMI, AK_NP7,
- AK_NP8, AK_NP9, AK_NPADD, AK_CAPSLOCK, AK_A, AK_S, AK_D, AK_F,
-
- AK_G, AK_H, AK_J, AK_K, AK_L, AK_SEMICOLON, AK_QUOTE, AK_RET,
- AK_NP4, AK_NP5, AK_NP6, AK_LSH, AK_Z, AK_X, AK_C, AK_V,
-
- AK_B, AK_N, AK_M, AK_COMMA, AK_PERIOD, AK_SLASH, AK_RSH, AK_UP,
- AK_NP1, AK_NP2, AK_NP3, AK_ENT, AK_CTRL, AK_LAMI, AK_SPC, AK_RAMI,
-
- AK_RALT, AK_LF, AK_DN, AK_RT, AK_NP0, AK_NPDEL, AK_LALT, AK_RALT,
- AK_LTGT, -1, -1, -1, -1, -1, -1, -1,
-
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1
- };
-
-
- /*
- * Create application object and start it
- */
-
- main()
- {
- UAE *the_app;
-
- the_app = new UAE();
- the_app->Run();
- delete the_app;
-
- return 0;
- }
-
-
- /*
- * UAE Constructor: Initialize member variables
- */
-
- UAE::UAE() : BApplication('UAEm')
- {
- the_bitmap = NULL;
- the_emulator = NULL;
- main_window = NULL;
- window_open = FALSE;
- }
-
-
- /*
- * Parse command line options
- */
-
- void usage(void)
- {
- printf("UAE - The Un*x Amiga emulator\n");
- printf("Summary of command-line options:\n");
- printf(" -h : Print help\n");
- printf(" -m VOLNAME:mount_point : mount file system at <mount point> as AmigaDOS\n"
- " volume VOLNAME:\n");
- printf(" -M VOLNAME:mount_point : like -m, but mount read-only\n");
- printf(" -a : Don't mount the harddisk file automatically.\n"
- " Useful only for testing.\n");
- printf(" -s : Emulate 1MB slow memory at 0xC00000\n");
- printf(" -F n : Emulate n MB fast memory at 0x200000\n");
- printf(" -f n : Set the frame rate to 1/n\n");
- printf(" -d : Draw the screen with the right aspect\n");
- printf(" -D : Start up the built-in debugger\n");
- printf(" -[0123] file : Use file instead of df[0123].adf as disk image file\n");
- printf(" -r file : Use file as ROM image instead of kick.rom\n");
- printf(" -p filename : Use filename to save printer output (may be LPT1: ?)\n");
- printf(" -J : Fake joystick emulation with the numeric pad.\n");
- printf(" -g : Turn on gfx-lib replacement.\n");
- printf(" -d mode : Select resolution with the mode parameter.\n");
- printf(" -H mode : Set the number of colors with the mode parameter.\n");
- printf("\n");
- printf("Valid resolutions: 0 (320x200); 1 (320x240); 2 (320x400); 3 (800x600);\n"
- " 4 (800x600, correct aspect)\n"
- "Valid color modes: 0 (256 colors); 1 (32768 colors); 2 (65536 colors)\n"
- "UAE may choose to ignore the color mode/resolution setting.\n");
- }
-
- void UAE::ArgvReceived(int argc, char **argv)
- {
- int c;
-
- while(((c = getopt(argc, argv, "Df:gd:hF:asJm:M:0:1:2:3:r:H:p:")) != EOF)) switch(c) {
- case 'h': usage(); exit(0);
-
- case '0': strncpy(df0, optarg, 255); df0[255] = 0; break;
- case '1': strncpy(df1, optarg, 255); df1[255] = 0; break;
- case '2': strncpy(df2, optarg, 255); df2[255] = 0; break;
- case '3': strncpy(df3, optarg, 255); df3[255] = 0; break;
- case 'r': strncpy(romfile, optarg, 255); romfile[255] = 0; break;
- case 'p': strncpy(prtname, optarg, 255); prtname[255] = 0; break;
- case 'm':
- case 'M':
- {
- /* mount file system (repeatable)
- * syntax: [-m | -M] VOLNAME:/mount_point
- * example: -M CDROM:/cdrom -m UNIXFS:./disk
- */
- static int mount_seen = 0;
- char buf[256];
- char *s2;
- int readonly = (c == 'M');
-
- if (mount_seen)
- fprintf(stderr, "warning: multiple mounts confuse Kickstart 1.3\n");
- mount_seen = 1;
- strncpy(buf, optarg, 255); buf[255] = 0;
- s2 = strchr(buf, ':');
- if(s2) {
- *s2++ = '\0';
- add_filesys_unit(buf, s2, readonly);
- } else {
- fprintf(stderr, "Usage: [-m | -M] VOLNAME:/mount_point\n");
- }
- }
- break;
-
- case 'f': framerate = atoi(optarg); break;
- case 'D': use_debugger = 1; break;
- case 'J': fake_joystick = 1; break;
- case 'a': automount_uaedev = 0; break;
- case 's': use_slow_mem = 1; break;
- case 'g': use_gfxlib = 1; break;
-
- case 'F':
- fastmem_size = atoi(optarg) * 0x100000;
- if (fastmem_size != 0x100000 && fastmem_size != 0x200000
- && fastmem_size != 0x400000 && fastmem_size != 0x800000)
- {
- fastmem_size = 0;
- fprintf(stderr, "Unsupported fastmem size!\n");
- }
-
- break;
-
- case 'd':
- screen_res = atoi(optarg);
- if (screen_res >= 0 && screen_res <= 4) {
- } else {
- fprintf(stderr, "Bad video mode selected. Using default.\n");
- screen_res = 3;
- }
- dont_want_aspect = screen_res != 4;
- use_lores = screen_res < 3;
- break;
-
- case 'H':
- color_mode = atoi(optarg);
- if (color_mode < 0 || color_mode > 2) {
- fprintf(stderr, "Bad color mode selected. Using default.\n");
- color_mode = 0;
- }
- break;
- }
- }
-
-
- /*
- * Arguments processed, create and start emulation
- */
-
- void UAE::ReadyToRun(void)
- {
- vsize = dont_want_aspect ? numscrlines : numscrlines*2;
- hsize = use_lores ? 400 : 800;
- hpixels = use_lores ? 320 : 796;
-
- // Allocate bitmap
- the_bitmap = new BBitmap(BRect(0, 0, hsize-1, vsize-1), B_COLOR_8_BIT);
-
- // Set up vidinfo
- gfxvidinfo.bufmem = (char *)the_bitmap->Bits();
- gfxvidinfo.rowbytes = the_bitmap->BytesPerRow();
- gfxvidinfo.pixbytes = 1;
- gfxvidinfo.maxblocklines = 100;
- gfxvidinfo.maxlinetoscr = 0;
- gfxvidinfo.x_adjust = 0;
- gfxvidinfo.maxline = 100000; /* ??? */
-
- // Open window
- main_window = new UAEWindow(BRect(0, 0, hpixels-1, vsize-1), the_bitmap);
-
- // Initialize mouse and keyboard variables
- buttonstate[0] = buttonstate[1] = buttonstate[2] = FALSE;
- lastmx = lastmy = 0;
- newmousecounters = FALSE;
- inwindow = TRUE;
-
- // Start emulation
- the_emulator = new Emulator;
- the_emulator->Run();
- }
-
-
- /*
- * Quit requested (either by menu or by closing the window)
- */
-
- bool UAE::QuitRequested(void)
- {
- if (BApplication::QuitRequested()) {
-
- // Stop emulation
- if (the_emulator) {
- the_emulator->Quit();
- delete the_emulator;
- }
-
- // Deallocate bitmap
- if (the_bitmap)
- delete the_bitmap;
-
- return TRUE;
- }
- return FALSE;
- }
-
-
- /*
- * Display "about" window
- */
-
- void UAE::AboutRequested(void)
- {
- char str[256];
-
- sprintf(str, "UAE V0.5.3 by Bernd Schmidt\nBeBox port by Christian Bauer");
- BAlert *the_alert = new BAlert("", str, "OK");
- the_alert->Go();
- }
-
-
- /*
- * UAE Window constructor
- */
-
- UAEWindow::UAEWindow(BRect frame, BBitmap *bitmap) : BWindow(frame, "UAE", B_TITLED_WINDOW, B_NOT_RESIZABLE)
- {
- int r, g, b, i;
-
- // Move window to right position
- MoveTo(80, 60);
-
- // Create bitmap view
- Lock();
- main_view = new BitmapView(frame, bitmap);
- AddChild(main_view);
- main_view->GetKeys(&old_key_info, FALSE);
- Unlock();
-
- bitmap_view = main_view;
- bitmap_window = this;
-
- // Initialize xcolors
- i = 0;
- for (r=0; r<16; r++) {
- for (g=0; g<16; g++) {
- for (b=0; b<16; b++)
- xcolors[i++] = index_for_color(r<<4 | r, g<<4 | g, b<<4 | b);
- }
- }
-
- // Show window
- Show();
- window_open = TRUE;
- }
-
-
- /*
- * Closing the window quits UAE
- */
-
- bool UAEWindow::QuitRequested(void)
- {
- window_open = FALSE;
- be_app->PostMessage(B_QUIT_REQUESTED);
- return TRUE;
- }
-
-
- /*
- * Window was (de)activated
- */
-
- void UAEWindow::WindowActivated(bool active)
- {
- inwindow = active;
- }
-
-
- /*
- * Bitmap view constructor
- */
-
- BitmapView::BitmapView(BRect frame, BBitmap *bitmap) : BView(frame, "", B_FOLLOW_NONE, B_WILL_DRAW)
- {
- the_bitmap = bitmap;
- }
-
-
- /*
- * Blit the bitmap
- */
-
- void BitmapView::Draw(BRect update)
- {
- DrawBitmap(the_bitmap, update, update);
- }
-
- void BitmapView::Draw(BRect from, BRect to)
- {
- DrawBitmap(the_bitmap, from, to);
- }
-
-
- /*
- * Start main emulation thread
- */
-
- void Emulator::Run(void)
- {
- // Initialize everything
- produce_sound = FALSE;
- init_joystick();
- keybuf_init ();
- memory_init();
- custom_init();
- DISK_init();
- init_m68k();
- MC68000_reset();
-
- // Start the emulation thread
- the_thread = spawn_thread(thread_invoc, "UAE 68000", B_NORMAL_PRIORITY, this);
- resume_thread(the_thread);
- thread_running = TRUE;
- }
-
-
- /*
- * Stop main emulation thread
- */
-
- void Emulator::Quit(void)
- {
- // Kill the thread if it is running
- if (thread_running) {
- kill_thread(the_thread);
- thread_running = FALSE;
- }
-
- close_joystick();
- }
-
-
- /*
- * The thread's main function
- */
-
- long Emulator::thread_invoc(Emulator *obj)
- {
- obj->thread_func();
- return 0;
- }
-
- void Emulator::thread_func(void)
- {
- // This jumps to MC68000_run() and executes the main loop
- debug();
- thread_running = FALSE;
- }
-
-
- /*
- * Redraw a line
- */
-
- void flush_line(int y)
- {
- if (window_open) {
- bitmap_window->Lock();
- bitmap_view->Draw(BRect(0, y, hpixels-1, y));
- bitmap_window->Unlock();
- }
- }
-
-
- /*
- * Redraw a block
- */
-
- void flush_block(int ystart, int ystop)
- {
- int xs = use_lores ? prev_max_diwstop - 328 : 0;
-
- if (window_open) {
- bitmap_window->Lock();
- bitmap_view->Draw(BRect(xs, ystart, hpixels+xs-1, ystop), BRect(0, ystart, hpixels-1, ystop));
- bitmap_window->Unlock();
- }
- }
-
-
- /*
- * Redraw the screen
- */
-
- void flush_screen(int ystart, int ystop)
- {
- }
-
-
- /*
- * Poll mouse and keyboard
- */
-
- void handle_events(void)
- {
- key_info the_key_info;
- int be_code, be_byte, be_bit, amiga_code;
- BPoint mouse_point;
- ulong mouse_buttons;
-
- // Keyboard
- if (window_open && inwindow) {
- bitmap_window->Lock();
- bitmap_view->GetKeys(&the_key_info, FALSE);
- bitmap_window->Unlock();
-
- for (be_code=0; be_code<0x80; be_code++) {
- be_byte = be_code >> 3;
- be_bit = 1 << (~be_code & 7);
-
- // Key state changed?
- if ((the_key_info.key_states[be_byte] & be_bit)
- != (old_key_info.key_states[be_byte] & be_bit)) {
-
- amiga_code = keycode2amiga[be_code];
- if (the_key_info.key_states[be_byte] & be_bit) {
-
- // Key pressed
- if (amiga_code == AK_mousestuff)
- togglemouse();
- else
- record_key(amiga_code << 1);
- } else {
-
- // Key released
- record_key((amiga_code << 1) | 1);
- }
- }
- }
- old_key_info = the_key_info;
-
- // "Affengriff"
- if ((the_key_info.key_states[0x5c >> 3] & (1 << (~0x5c & 7)))
- && (the_key_info.key_states[0x5d >> 3] & (1 << (~0x5d & 7)))
- && (the_key_info.key_states[0x5f >> 3] & (1 << (~0x5f & 7))))
- MC68000_reset();
-
- // Scroll lock toggles inhibit_frame
- inhibit_frame = the_key_info.key_states[0x0f >> 3] & (1 << (~0x0f & 7));
- }
-
- // Mouse
- if (window_open && inwindow) {
- bitmap_window->Lock();
- bitmap_view->GetMouse(&mouse_point, &mouse_buttons, FALSE);
- bitmap_window->Unlock();
- lastmx = mouse_point.x;
- lastmy = mouse_point.y;
-
- buttonstate[0] = mouse_buttons & B_PRIMARY_MOUSE_BUTTON;
- buttonstate[1] = mouse_buttons & B_TERTIARY_MOUSE_BUTTON;
- buttonstate[2] = mouse_buttons & B_SECONDARY_MOUSE_BUTTON;
- }
- }
-
-
- int debuggable(void)
- {
- return TRUE;
- }
-
- int needmousehack(void)
- {
- return TRUE;
- }
-
- void LED(int on)
- {
- }
-
- void calc_adjustment(void)
- {
- gfxvidinfo.x_adjust = 0;
- }
-
- void target_specific_usage(void)
- {
- }
-