Annotation of uae/bebox.cpp, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.