home *** CD-ROM | disk | FTP | other *** search
- /*
- * UAE - The Un*x Amiga Emulator
- *
- * SVGAlib interface.
- *
- * (c) 1995 Bernd Schmidt
- */
-
- #include "sysconfig.h"
- #include "sysdeps.h"
-
- #include <assert.h>
- #include <signal.h>
- #include <vga.h>
- #include <vgamouse.h>
- #include <vgakeyboard.h>
-
- #include "config.h"
- #include "options.h"
- #include "memory.h"
- #include "custom.h"
- #include "newcpu.h"
- #include "keyboard.h"
- #include "xwin.h"
- #include "keybuf.h"
-
- #define SCODE_CURSORBLOCKUP 103 /* Cursor key block. */
- #define SCODE_CURSORBLOCKLEFT 105
- #define SCODE_CURSORBLOCKRIGHT 106
- #define SCODE_CURSORBLOCKDOWN 108
-
- #define SCODE_INSERT 110
- #define SCODE_HOME 102
- #define SCODE_PGUP 104
- #define SCODE_DELETE 111
- #define SCODE_END 107
- #define SCODE_PGDN 109
-
- #define SCODE_KEYPAD0 82
- #define SCODE_KEYPAD1 79
- #define SCODE_KEYPAD2 80
- #define SCODE_KEYPAD3 81
- #define SCODE_KEYPAD4 75
- #define SCODE_KEYPAD5 76
- #define SCODE_KEYPAD6 77
- #define SCODE_KEYPAD7 71
- #define SCODE_KEYPAD8 72
- #define SCODE_KEYPAD9 73
- #define SCODE_KEYPADENTER 96
- #define SCODE_KEYPADPLUS 78
- #define SCODE_KEYPADMINUS 74
-
- #define SCODE_Q 16
- #define SCODE_W 17
- #define SCODE_E 18
- #define SCODE_R 19
- #define SCODE_T 20
- #define SCODE_Y 21
- #define SCODE_U 22
- #define SCODE_I 23
- #define SCODE_O 24
- #define SCODE_P 25
-
- #define SCODE_A 30
- #define SCODE_S 31
- #define SCODE_D 32
- #define SCODE_F 33
- #define SCODE_G 34
- #define SCODE_H 35
- #define SCODE_J 36
- #define SCODE_K 37
- #define SCODE_L 38
-
- #define SCODE_Z 44
- #define SCODE_X 45
- #define SCODE_C 46
- #define SCODE_V 47
- #define SCODE_B 48
- #define SCODE_N 49
- #define SCODE_M 50
-
- #define SCODE_ESCAPE 1
- #define SCODE_ENTER 28
- #define SCODE_RIGHTCONTROL 97
- #define SCODE_CONTROL 97
- #define SCODE_RIGHTALT 100
- #define SCODE_LEFTCONTROL 29
- #define SCODE_LEFTALT 56
- #define SCODE_SPACE 57
-
- #define SCODE_F1 59
- #define SCODE_F2 60
- #define SCODE_F3 61
- #define SCODE_F4 62
- #define SCODE_F5 63
- #define SCODE_F6 64
- #define SCODE_F7 65
- #define SCODE_F8 66
- #define SCODE_F9 67
- #define SCODE_F10 68
-
- #define SCODE_0 11
- #define SCODE_1 2
- #define SCODE_2 3
- #define SCODE_3 4
- #define SCODE_4 5
- #define SCODE_5 6
- #define SCODE_6 7
- #define SCODE_7 8
- #define SCODE_8 9
- #define SCODE_9 10
-
- #define SCODE_LEFTSHIFT 42
- #define SCODE_RIGHTSHIFT 54
- #define SCODE_TAB 15
-
- #define SCODE_F11 87
- #define SCODE_F12 88
- #define SCODE_NEXT 81
- #define SCODE_PRIOR 73
- #define SCODE_BS 14
- /*
- #define SCODE_asciicircum 1
- */
- #define SCODE_bracketleft 26
- #define SCODE_bracketright 27
- #define SCODE_comma 51
- #define SCODE_period 52
- #define SCODE_slash 53
- #define SCODE_semicolon 39
- #define SCODE_grave 40
- #define SCODE_minus 12
- #define SCODE_equal 13
- #define SCODE_numbersign 41
- #define SCODE_ltgt 43
- #define SCODE_scrolllock 70
-
- #define SCODE_LWIN95 125
- #define SCODE_RWIN95 126
- #define SCODE_MWIN95 127
-
- static int vsize, bitdepth, bit_unit, using_linear;
- static vga_modeinfo modeinfo;
- static char *linear_mem = NULL;
- static int need_dither;
- static int x_size = 0, vidmode_linewidth;
-
- static UBYTE dither_buf[1000]; /* I hate having to think about array bounds */
-
- xcolnr xcolors[4096];
-
- struct vidbuf_description gfxvidinfo;
-
- static int x_size_table[MAX_SCREEN_MODES+1] = { 320, 320, 320, 640, 800 };
-
- static int vga_mode_table[MAX_SCREEN_MODES+1][MAX_COLOR_MODES+1] =
- { { G320x200x256, G320x200x32K, G320x200x64K, G320x200x256, G320x200x16, G320x200x16M32 },
- { G320x240x256, -1, -1, G320x240x256, -1, -1 },
- { G320x400x256, -1, -1, G320x400x256, -1, -1 },
- { G640x480x256, G640x480x32K, G640x480x64K, G640x480x256, G640x480x16, G640x480x16M32 },
- { G800x600x256, G800x600x32K, G800x600x64K, G800x600x256, G800x600x16, G800x600x16M32 } };
-
- static int mode_bitdepth[MAX_COLOR_MODES+1][3] =
- { { 8, 8, 0 }, { 15, 16, 0 }, { 16, 16, 0 }, { 8, 8, 1 }, { 4, 8, 1 }, { 24, 32, 0 } };
-
- void flush_line(int y)
- {
- int target_y = y;
-
- if (screen_res < 2)
- target_y -= 8;
- if (linear_mem == NULL) {
- char *addr = gfxvidinfo.bufmem + y*gfxvidinfo.rowbytes;
- if (target_y < modeinfo.height && target_y >= 0) {
- if (need_dither) {
- DitherLine(dither_buf, (UWORD *)addr, 0, y, x_size, bit_unit);
- addr = dither_buf;
- }
- vga_drawscanline(target_y, addr);
- }
- } else {
- if (need_dither && target_y >= 0) {
- char *addr = gfxvidinfo.bufmem + y*gfxvidinfo.rowbytes;
- DitherLine(linear_mem + vidmode_linewidth * target_y, (UWORD *)addr, 0, y, x_size, bit_unit);
- }
- }
- }
-
- void flush_block(int a, int b)
- {
- abort();
- }
-
- void flush_screen(int a, int b)
- {
- }
-
- void calc_adjustment(void)
- {
- switch (screen_res) {
- case 0: case 1: case 2: /* LoRes, 320xfoo */
- gfxvidinfo.x_adjust = prev_max_diwstop - 320;
- break;
-
- case 3: /* 640xbar */
- gfxvidinfo.x_adjust = prev_max_diwstop - 640;
- break;
- default:
- gfxvidinfo.x_adjust = 0;
- break;
- }
- }
-
- static int colors_allocated;
-
- static int get_color(int r, int g, int b, xcolnr *cnp)
- {
- if (colors_allocated == 256)
- return -1;
- *cnp = colors_allocated;
- vga_setpalette(colors_allocated, doMask(r, 6, 0), doMask(g, 6, 0), doMask(b, 6, 0));
- colors_allocated++;
- return 1;
- }
-
- static void init_colors(void)
- {
- if (need_dither) {
- setup_dither(bitdepth, get_color);
- } else {
- int rw = 5, gw = 5, bw = 5;
- colors_allocated = 0;
- if (color_mode == 2) gw = 6;
-
- switch (gfxvidinfo.pixbytes) {
- case 4:
- alloc_colors64k(8, 8, 8, 16, 8, 0);
- break;
- case 2:
- alloc_colors64k(rw, gw, bw, gw+bw, bw, 0);
- break;
- case 1:
- alloc_colors256(get_color);
- break;
- default:
- abort();
- }
- }
- }
-
- int buttonstate[3] = { 0, 0, 0 };
- int lastmx, lastmy;
- int newmousecounters = 0;
-
- static int keystate[256];
-
- static int scancode2amiga(int scancode)
- {
- switch(scancode) {
- case SCODE_A: return AK_A;
- case SCODE_B: return AK_B;
- case SCODE_C: return AK_C;
- case SCODE_D: return AK_D;
- case SCODE_E: return AK_E;
- case SCODE_F: return AK_F;
- case SCODE_G: return AK_G;
- case SCODE_H: return AK_H;
- case SCODE_I: return AK_I;
- case SCODE_J: return AK_J;
- case SCODE_K: return AK_K;
- case SCODE_L: return AK_L;
- case SCODE_M: return AK_M;
- case SCODE_N: return AK_N;
- case SCODE_O: return AK_O;
- case SCODE_P: return AK_P;
- case SCODE_Q: return AK_Q;
- case SCODE_R: return AK_R;
- case SCODE_S: return AK_S;
- case SCODE_T: return AK_T;
- case SCODE_U: return AK_U;
- case SCODE_V: return AK_V;
- case SCODE_W: return AK_W;
- case SCODE_X: return AK_X;
- case SCODE_Y: return AK_Y;
- case SCODE_Z: return AK_Z;
-
- case SCODE_0: return AK_0;
- case SCODE_1: return AK_1;
- case SCODE_2: return AK_2;
- case SCODE_3: return AK_3;
- case SCODE_4: return AK_4;
- case SCODE_5: return AK_5;
- case SCODE_6: return AK_6;
- case SCODE_7: return AK_7;
- case SCODE_8: return AK_8;
- case SCODE_9: return AK_9;
-
- case SCODE_KEYPAD0: return AK_NP0;
- case SCODE_KEYPAD1: return AK_NP1;
- case SCODE_KEYPAD2: return AK_NP2;
- case SCODE_KEYPAD3: return AK_NP3;
- case SCODE_KEYPAD4: return AK_NP4;
- case SCODE_KEYPAD5: return AK_NP5;
- case SCODE_KEYPAD6: return AK_NP6;
- case SCODE_KEYPAD7: return AK_NP7;
- case SCODE_KEYPAD8: return AK_NP8;
- case SCODE_KEYPAD9: return AK_NP9;
-
- case SCODE_F1: return AK_F1;
- case SCODE_F2: return AK_F2;
- case SCODE_F3: return AK_F3;
- case SCODE_F4: return AK_F4;
- case SCODE_F5: return AK_F5;
- case SCODE_F6: return AK_F6;
- case SCODE_F7: return AK_F7;
- case SCODE_F8: return AK_F8;
- case SCODE_F9: return AK_F9;
- case SCODE_F10: return AK_F10;
-
- case SCODE_BS: return AK_BS;
- case SCODE_LEFTCONTROL: return AK_CTRL;
- case SCODE_RIGHTCONTROL: return AK_CTRL;
- case SCODE_TAB: return AK_TAB;
- case SCODE_LEFTALT: return AK_LALT;
- case SCODE_RIGHTALT: return AK_RALT;
- case SCODE_ENTER: return AK_RET;
- case SCODE_SPACE: return AK_SPC;
- case SCODE_LEFTSHIFT: return AK_LSH;
- case SCODE_RIGHTSHIFT: return AK_RSH;
- case SCODE_ESCAPE: return AK_ESC;
-
- case SCODE_INSERT:
- case SCODE_END:
- case SCODE_HOME: break;
-
- case SCODE_DELETE: return AK_DEL;
- case SCODE_CURSORBLOCKUP: return AK_UP;
- case SCODE_CURSORBLOCKDOWN: return AK_DN;
- case SCODE_CURSORBLOCKLEFT: return AK_LF;
- case SCODE_CURSORBLOCKRIGHT: return AK_RT;
-
- case SCODE_F11: return AK_BACKSLASH;
- /*
- case SCODE_asciicircum: return AK_00;
- */
- case SCODE_bracketleft: return AK_LBRACKET;
- case SCODE_bracketright: return AK_RBRACKET;
- case SCODE_comma: return AK_COMMA;
- case SCODE_period: return AK_PERIOD;
- case SCODE_slash: return AK_SLASH;
- case SCODE_semicolon: return AK_SEMICOLON;
- case SCODE_grave: return AK_QUOTE;
- case SCODE_minus: return AK_MINUS;
- case SCODE_equal: return AK_EQUAL;
-
- /* This one turns off screen updates. */
- case SCODE_scrolllock: return AK_inhibit;
-
- case SCODE_PGUP: case SCODE_RWIN95: return AK_RAMI;
- case SCODE_PGDN: case SCODE_LWIN95: return AK_LAMI;
-
- /*#ifdef KBD_LANG_DE*/
- case SCODE_numbersign: return AK_NUMBERSIGN;
- case SCODE_ltgt: return AK_LTGT;
- /*#endif*/
- }
- return -1;
- }
-
- static void my_kbd_handler(int scancode, int newstate)
- {
- int akey = scancode2amiga(scancode);
-
- assert(scancode >= 0 && scancode < 0x100);
- if (scancode == SCODE_F12)
- specialflags |= SPCFLAG_BRK;
- if (keystate[scancode] == newstate)
- return;
- keystate[scancode] = newstate;
-
- if (akey == -1)
- return;
-
- if (newstate == KEY_EVENTPRESS) {
- if (akey == AK_inhibit)
- inhibit_frame ^= 1;
- else
- record_key (akey << 1);
- } else
- record_key ((akey << 1) | 1);
-
- /* "Affengriff" */
- if(keystate[AK_CTRL] && keystate[AK_LAMI] && keystate[AK_RAMI])
- MC68000_reset();
- }
-
- int graphics_init(void)
- {
- int i;
- int vgamode;
-
- need_dither = 0;
- using_linear = 0;
-
- vgamode = vga_mode_table[screen_res][color_mode];
- if (vgamode == -1) {
- fprintf(stderr, "Sorry, this combination of color and video mode is not supported.\n");
- return 0;
- }
-
- bitdepth = mode_bitdepth[color_mode][0];
- bit_unit = mode_bitdepth[color_mode][1];
- need_dither = mode_bitdepth[color_mode][2];
- x_size = x_size_table[screen_res];
-
- vga_init();
- modeinfo = *vga_getmodeinfo (vgamode);
-
- vidmode_linewidth = modeinfo.linewidth;
- gfxvidinfo.pixbytes = modeinfo.bytesperpixel;
- if (!need_dither) {
- if (modeinfo.bytesperpixel == 0) {
- printf("Got a bogus value from SVGAlib... %s.\n",
- screen_res == 1 || screen_res == 2 ? "trying to fix it" : "giving up");
- if (screen_res != 1 && screen_res != 2)
- return 0;
- gfxvidinfo.pixbytes = 1;
- }
- } else {
- gfxvidinfo.pixbytes = 2;
- }
-
- if (vga_setmode(vgamode) < 0) {
- sleep(1);
- vga_setmode(TEXT);
- fprintf(stderr, "SVGAlib doesn't like my video mode. Giving up.\n");
- return 0;
- }
-
- if ((modeinfo.flags & CAPABLE_LINEAR) && !use_xhair) {
- if (vga_setlinearaddressing() != -1) {
- linear_mem = (char *)vga_getgraphmem();
- printf("Using linear addressing: %p.\n", linear_mem);
- using_linear = !need_dither;
- }
- }
-
- vsize = correct_aspect ? 2*numscrlines : numscrlines;
- gfxvidinfo.maxblocklines = 0;
-
- if (using_linear) {
- gfxvidinfo.bufmem = linear_mem;
- gfxvidinfo.rowbytes = modeinfo.linewidth;
- } else {
- gfxvidinfo.rowbytes = x_size * gfxvidinfo.pixbytes;
- gfxvidinfo.bufmem = malloc(gfxvidinfo.rowbytes * vsize);
- memset(gfxvidinfo.bufmem, 0, gfxvidinfo.rowbytes * vsize);
- }
-
- gfxvidinfo.maxlinetoscr = x_size < 800 ? x_size : 0;
- gfxvidinfo.x_adjust = 0;
- gfxvidinfo.maxline = modeinfo.height;
-
- init_colors();
- vga_setmousesupport(1);
- mouse_init("/dev/mouse",vga_getmousetype(),10);
- if (keyboard_init() != 0)
- abort();
- keyboard_seteventhandler(my_kbd_handler);
- keyboard_translatekeys(DONT_CATCH_CTRLC);
-
- buttonstate[0] = buttonstate[1] = buttonstate[2] = 0;
- for(i = 0; i < 256; i++)
- keystate[i] = 0;
-
- lastmx = lastmy = 0;
- newmousecounters = 0;
-
- mouse_setxrange(-1000,1000);
- mouse_setyrange(-1000,1000);
- mouse_setposition(0,0);
-
- return 1;
- }
-
- void graphics_leave(void)
- {
- sleep(1); /* Maybe this will fix the "screen full of garbage" problem */
- vga_setmode(TEXT);
- keyboard_close();
- }
-
- void handle_events(void)
- {
- int button = mouse_getbutton();
-
- keyboard_update();
- mouse_update();
- lastmx += mouse_getx();
- lastmy += mouse_gety();
- mouse_setposition(0,0);
-
- buttonstate[0] = button & 4;
- buttonstate[1] = button & 2;
- buttonstate[2] = button & 1;
- }
-
- int debuggable(void)
- {
- return 0;
- }
-
- int needmousehack(void)
- {
- return 0;
- }
-
- void LED(int on)
- {
- }
-
- void target_specific_usage(void)
- {
- printf(" -S : Turn off sound support (if it is configured)\n");
- printf(" -x : Don't use SVGAlib linear framebuffer, even if available.\n");
- printf(" -p command : Use command to pipe printer output to.\n");
-
- }
-