|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
4: * SVGAlib interface.
5: *
6: * (c) 1995 Bernd Schmidt
7: */
8:
9: #include "sysconfig.h"
10: #include "sysdeps.h"
11:
12: #include <assert.h>
13: #include <ctype.h>
14: #include <signal.h>
15: #include <vga.h>
16: #include <vgamouse.h>
17: #include <vgakeyboard.h>
18:
19: #include "config.h"
20: #include "options.h"
21: #include "memory.h"
22: #include "custom.h"
1.1.1.2 ! root 23: #include "readcpu.h"
1.1 root 24: #include "newcpu.h"
25: #include "keyboard.h"
26: #include "xwin.h"
27: #include "keybuf.h"
28: #include "gui.h"
29:
30: #define SCODE_CURSORBLOCKUP 103 /* Cursor key block. */
31: #define SCODE_CURSORBLOCKLEFT 105
32: #define SCODE_CURSORBLOCKRIGHT 106
33: #define SCODE_CURSORBLOCKDOWN 108
34:
35: #define SCODE_INSERT 110
36: #define SCODE_HOME 102
37: #define SCODE_PGUP 104
38: #define SCODE_DELETE 111
39: #define SCODE_END 107
40: #define SCODE_PGDN 109
41:
42: #define SCODE_KEYPAD0 82
43: #define SCODE_KEYPAD1 79
44: #define SCODE_KEYPAD2 80
45: #define SCODE_KEYPAD3 81
46: #define SCODE_KEYPAD4 75
47: #define SCODE_KEYPAD5 76
48: #define SCODE_KEYPAD6 77
49: #define SCODE_KEYPAD7 71
50: #define SCODE_KEYPAD8 72
51: #define SCODE_KEYPAD9 73
52: #define SCODE_KEYPADENTER 96
53: #define SCODE_KEYPADPLUS 78
54: #define SCODE_KEYPADMINUS 74
55:
56: #define SCODE_Q 16
57: #define SCODE_W 17
58: #define SCODE_E 18
59: #define SCODE_R 19
60: #define SCODE_T 20
61: #define SCODE_Y 21
62: #define SCODE_U 22
63: #define SCODE_I 23
64: #define SCODE_O 24
65: #define SCODE_P 25
66:
67: #define SCODE_A 30
68: #define SCODE_S 31
69: #define SCODE_D 32
70: #define SCODE_F 33
71: #define SCODE_G 34
72: #define SCODE_H 35
73: #define SCODE_J 36
74: #define SCODE_K 37
75: #define SCODE_L 38
76:
77: #define SCODE_Z 44
78: #define SCODE_X 45
79: #define SCODE_C 46
80: #define SCODE_V 47
81: #define SCODE_B 48
82: #define SCODE_N 49
83: #define SCODE_M 50
84:
85: #define SCODE_ESCAPE 1
86: #define SCODE_ENTER 28
87: #define SCODE_RIGHTCONTROL 97
88: #define SCODE_CONTROL 97
89: #define SCODE_RIGHTALT 100
90: #define SCODE_LEFTCONTROL 29
91: #define SCODE_LEFTALT 56
92: #define SCODE_SPACE 57
93:
94: #define SCODE_F1 59
95: #define SCODE_F2 60
96: #define SCODE_F3 61
97: #define SCODE_F4 62
98: #define SCODE_F5 63
99: #define SCODE_F6 64
100: #define SCODE_F7 65
101: #define SCODE_F8 66
102: #define SCODE_F9 67
103: #define SCODE_F10 68
104:
105: #define SCODE_0 11
106: #define SCODE_1 2
107: #define SCODE_2 3
108: #define SCODE_3 4
109: #define SCODE_4 5
110: #define SCODE_5 6
111: #define SCODE_6 7
112: #define SCODE_7 8
113: #define SCODE_8 9
114: #define SCODE_9 10
115:
116: #define SCODE_LEFTSHIFT 42
117: #define SCODE_RIGHTSHIFT 54
118: #define SCODE_TAB 15
119:
120: #define SCODE_F11 87
121: #define SCODE_F12 88
122: #define SCODE_NEXT 81
123: #define SCODE_PRIOR 73
124: #define SCODE_BS 14
1.1.1.2 ! root 125:
! 126: #define SCODE_asciicircum 41
! 127:
1.1 root 128: #define SCODE_bracketleft 26
129: #define SCODE_bracketright 27
130: #define SCODE_comma 51
131: #define SCODE_period 52
132: #define SCODE_slash 53
133: #define SCODE_semicolon 39
134: #define SCODE_grave 40
135: #define SCODE_minus 12
136: #define SCODE_equal 13
137: #define SCODE_numbersign 43
138: #define SCODE_ltgt 86
139: #define SCODE_scrolllock 70
140:
141: #define SCODE_LWIN95 125
142: #define SCODE_RWIN95 126
143: #define SCODE_MWIN95 127
144:
145: void setup_brkhandler(void)
146: {
147: }
148:
1.1.1.2 ! root 149: static int bitdepth, bit_unit, using_linear;
1.1 root 150: static vga_modeinfo modeinfo;
151: static char *linear_mem = NULL;
152: static int need_dither;
153:
154: static UBYTE dither_buf[1000]; /* I hate having to think about array bounds */
155:
156: xcolnr xcolors[4096];
157:
158: struct vidbuf_description gfxvidinfo;
1.1.1.2 ! root 159: #define MAX_SCREEN_MODES 6
1.1 root 160:
1.1.1.2 ! root 161: static int x_size_table[MAX_SCREEN_MODES] = { 320, 320, 320, 640, 640, 800 };
! 162: static int y_size_table[MAX_SCREEN_MODES] = { 200, 240, 400, 350, 480, 600 };
1.1 root 163:
1.1.1.2 ! root 164: static int vga_mode_table[MAX_SCREEN_MODES][MAX_COLOR_MODES+1] =
1.1 root 165: { { G320x200x256, G320x200x32K, G320x200x64K, G320x200x256, G320x200x16, G320x200x16M32 },
166: { G320x240x256, -1, -1, G320x240x256, -1, -1 },
167: { G320x400x256, -1, -1, G320x400x256, -1, -1 },
1.1.1.2 ! root 168: { -1, -1, -1, -1, G640x350x16, -1 },
1.1 root 169: { G640x480x256, G640x480x32K, G640x480x64K, G640x480x256, G640x480x16, G640x480x16M32 },
170: { G800x600x256, G800x600x32K, G800x600x64K, G800x600x256, G800x600x16, G800x600x16M32 } };
171:
172: static int mode_bitdepth[MAX_COLOR_MODES+1][3] =
173: { { 8, 8, 0 }, { 15, 16, 0 }, { 16, 16, 0 }, { 8, 8, 1 }, { 4, 8, 1 }, { 24, 32, 0 } };
174:
175: void flush_line(int y)
176: {
177: int target_y = y;
178:
179: if (linear_mem == NULL) {
180: char *addr = gfxvidinfo.bufmem + y*gfxvidinfo.rowbytes;
181: if (target_y < modeinfo.height && target_y >= 0) {
182: if (need_dither) {
1.1.1.2 ! root 183: DitherLine(dither_buf, (UWORD *)addr, 0, y, gfxvidinfo.maxlinetoscr, bit_unit);
1.1 root 184: addr = dither_buf;
185: }
186: vga_drawscanline(target_y, addr);
187: }
188: } else {
189: if (need_dither && target_y >= 0) {
190: char *addr = gfxvidinfo.bufmem + y*gfxvidinfo.rowbytes;
1.1.1.2 ! root 191: DitherLine(linear_mem + modeinfo.linewidth * target_y, (UWORD *)addr, 0, y,
! 192: gfxvidinfo.maxlinetoscr, bit_unit);
1.1 root 193: }
194: }
195: }
196:
197: void flush_block(int a, int b)
198: {
199: abort();
200: }
201:
202: void flush_screen(int a, int b)
203: {
204: }
205:
206: static int colors_allocated;
207:
208: static int get_color(int r, int g, int b, xcolnr *cnp)
209: {
210: if (colors_allocated == 256)
211: return -1;
212: *cnp = colors_allocated;
213: vga_setpalette(colors_allocated, doMask(r, 6, 0), doMask(g, 6, 0), doMask(b, 6, 0));
214: colors_allocated++;
215: return 1;
216: }
217:
218: static void init_colors(void)
219: {
220: if (need_dither) {
221: setup_dither(bitdepth, get_color);
222: } else {
223: int rw = 5, gw = 5, bw = 5;
224: colors_allocated = 0;
225: if (color_mode == 2) gw = 6;
226:
227: switch (gfxvidinfo.pixbytes) {
228: case 4:
229: alloc_colors64k(8, 8, 8, 16, 8, 0);
230: break;
231: case 2:
232: alloc_colors64k(rw, gw, bw, gw+bw, bw, 0);
233: break;
234: case 1:
235: alloc_colors256(get_color);
236: break;
237: default:
238: abort();
239: }
240: }
241: }
242:
243: int buttonstate[3] = { 0, 0, 0 };
244: int lastmx, lastmy;
245: int newmousecounters = 0;
246:
247: static int keystate[256];
248:
249: static int scancode2amiga(int scancode)
250: {
251: switch(scancode) {
252: case SCODE_A: return AK_A;
253: case SCODE_B: return AK_B;
254: case SCODE_C: return AK_C;
255: case SCODE_D: return AK_D;
256: case SCODE_E: return AK_E;
257: case SCODE_F: return AK_F;
258: case SCODE_G: return AK_G;
259: case SCODE_H: return AK_H;
260: case SCODE_I: return AK_I;
261: case SCODE_J: return AK_J;
262: case SCODE_K: return AK_K;
263: case SCODE_L: return AK_L;
264: case SCODE_M: return AK_M;
265: case SCODE_N: return AK_N;
266: case SCODE_O: return AK_O;
267: case SCODE_P: return AK_P;
268: case SCODE_Q: return AK_Q;
269: case SCODE_R: return AK_R;
270: case SCODE_S: return AK_S;
271: case SCODE_T: return AK_T;
272: case SCODE_U: return AK_U;
273: case SCODE_V: return AK_V;
274: case SCODE_W: return AK_W;
275: case SCODE_X: return AK_X;
276: case SCODE_Y: return AK_Y;
277: case SCODE_Z: return AK_Z;
278:
279: case SCODE_0: return AK_0;
280: case SCODE_1: return AK_1;
281: case SCODE_2: return AK_2;
282: case SCODE_3: return AK_3;
283: case SCODE_4: return AK_4;
284: case SCODE_5: return AK_5;
285: case SCODE_6: return AK_6;
286: case SCODE_7: return AK_7;
287: case SCODE_8: return AK_8;
288: case SCODE_9: return AK_9;
289:
290: case SCODE_KEYPAD0: return AK_NP0;
291: case SCODE_KEYPAD1: return AK_NP1;
292: case SCODE_KEYPAD2: return AK_NP2;
293: case SCODE_KEYPAD3: return AK_NP3;
294: case SCODE_KEYPAD4: return AK_NP4;
295: case SCODE_KEYPAD5: return AK_NP5;
296: case SCODE_KEYPAD6: return AK_NP6;
297: case SCODE_KEYPAD7: return AK_NP7;
298: case SCODE_KEYPAD8: return AK_NP8;
299: case SCODE_KEYPAD9: return AK_NP9;
300:
301: case SCODE_F1: return AK_F1;
302: case SCODE_F2: return AK_F2;
303: case SCODE_F3: return AK_F3;
304: case SCODE_F4: return AK_F4;
305: case SCODE_F5: return AK_F5;
306: case SCODE_F6: return AK_F6;
307: case SCODE_F7: return AK_F7;
308: case SCODE_F8: return AK_F8;
309: case SCODE_F9: return AK_F9;
310: case SCODE_F10: return AK_F10;
311:
312: case SCODE_BS: return AK_BS;
313: case SCODE_LEFTCONTROL: return AK_CTRL;
314: case SCODE_RIGHTCONTROL: return AK_CTRL;
315: case SCODE_TAB: return AK_TAB;
316: case SCODE_LEFTALT: return AK_LALT;
317: case SCODE_RIGHTALT: return AK_RALT;
318: case SCODE_ENTER: return AK_RET;
319: case SCODE_SPACE: return AK_SPC;
320: case SCODE_LEFTSHIFT: return AK_LSH;
321: case SCODE_RIGHTSHIFT: return AK_RSH;
322: case SCODE_ESCAPE: return AK_ESC;
323:
324: case SCODE_INSERT:
325: case SCODE_END:
326: case SCODE_HOME: break;
327:
328: case SCODE_DELETE: return AK_DEL;
329: case SCODE_CURSORBLOCKUP: return AK_UP;
330: case SCODE_CURSORBLOCKDOWN: return AK_DN;
331: case SCODE_CURSORBLOCKLEFT: return AK_LF;
332: case SCODE_CURSORBLOCKRIGHT: return AK_RT;
333:
334: case SCODE_F11: return AK_BACKSLASH;
335: case SCODE_asciicircum: return AK_00;
336: case SCODE_bracketleft: return AK_LBRACKET;
337: case SCODE_bracketright: return AK_RBRACKET;
338: case SCODE_comma: return AK_COMMA;
339: case SCODE_period: return AK_PERIOD;
340: case SCODE_slash: return AK_SLASH;
341: case SCODE_semicolon: return AK_SEMICOLON;
342: case SCODE_grave: return AK_QUOTE;
343: case SCODE_minus: return AK_MINUS;
344: case SCODE_equal: return AK_EQUAL;
345:
346: /* This one turns off screen updates. */
347: case SCODE_scrolllock: return AK_inhibit;
348:
349: case SCODE_PGUP: case SCODE_RWIN95: return AK_RAMI;
350: case SCODE_PGDN: case SCODE_LWIN95: return AK_LAMI;
351:
352: /*#ifdef KBD_LANG_DE*/
353: case SCODE_numbersign: return AK_NUMBERSIGN;
354: case SCODE_ltgt: return AK_LTGT;
355: /*#endif*/
356: }
357: return -1;
358: }
359:
360: static void my_kbd_handler(int scancode, int newstate)
361: {
362: int akey = scancode2amiga(scancode);
363:
364: assert(scancode >= 0 && scancode < 0x100);
365: if (scancode == SCODE_F12) {
366: regs.spcflags |= SPCFLAG_BRK;
367: quit_program = 1;
368: }
369: if (keystate[scancode] == newstate)
370: return;
371: keystate[scancode] = newstate;
372:
373: if (akey == -1) {
374: return;
375: }
376:
377: if (newstate == KEY_EVENTPRESS) {
378: if (akey == AK_inhibit)
379: inhibit_frame ^= 1;
380: else
381: record_key (akey << 1);
382: } else
383: record_key ((akey << 1) | 1);
384:
385: /* "Affengriff" */
386: if(keystate[AK_CTRL] && keystate[AK_LAMI] && keystate[AK_RAMI])
387: m68k_reset();
388: }
389:
390: int graphics_init(void)
391: {
392: int i;
393: int vgamode;
1.1.1.2 ! root 394: int mode_nr0, mode_nr;
1.1 root 395: need_dither = 0;
396: using_linear = 0;
397:
1.1.1.2 ! root 398: fprintf (stderr, "Initializing SVGAlib.\n");
! 399: mode_nr0 = 0;
! 400: for (i = 1; i < MAX_SCREEN_MODES; i++) {
! 401: if (x_size_table[mode_nr0] >= gfx_requested_width)
! 402: break;
! 403: if (x_size_table[i-1] != x_size_table[i])
! 404: mode_nr0 = i;
! 405: }
! 406: mode_nr = -1;
! 407: for (i = mode_nr0; i < MAX_SCREEN_MODES && x_size_table[i] == x_size_table[mode_nr0]; i++) {
! 408: if ((y_size_table[i] >= gfx_requested_height
! 409: || i + 1 == MAX_SCREEN_MODES
! 410: || x_size_table[i+1] != x_size_table[mode_nr0])
! 411: && vga_mode_table[i][color_mode] != -1)
! 412: {
! 413: mode_nr = i;
! 414: break;
! 415: }
! 416: }
! 417: if (mode_nr == -1) {
1.1 root 418: fprintf(stderr, "Sorry, this combination of color and video mode is not supported.\n");
419: return 0;
420: }
1.1.1.2 ! root 421: vgamode = vga_mode_table[mode_nr][color_mode];
! 422: if (vgamode == -1) {
! 423: fprintf(stderr, "Bug!\n");
! 424: abort();
! 425: }
! 426: fprintf(stderr, "Desired resolution: %dx%d, using: %dx%d\n",
! 427: gfx_requested_width, gfx_requested_height,
! 428: x_size_table[mode_nr], y_size_table[mode_nr]);
1.1 root 429:
1.1.1.2 ! root 430: gfx_requested_width = x_size_table[mode_nr];
! 431: gfx_requested_height = y_size_table[mode_nr];
! 432:
1.1 root 433: bitdepth = mode_bitdepth[color_mode][0];
434: bit_unit = mode_bitdepth[color_mode][1];
435: need_dither = mode_bitdepth[color_mode][2];
436:
437: vga_init();
438: modeinfo = *vga_getmodeinfo (vgamode);
439:
440: gfxvidinfo.pixbytes = modeinfo.bytesperpixel;
441: if (!need_dither) {
442: if (modeinfo.bytesperpixel == 0) {
1.1.1.2 ! root 443: printf("Got a bogus value from SVGAlib...\n");
1.1 root 444: gfxvidinfo.pixbytes = 1;
445: }
446: } else {
447: gfxvidinfo.pixbytes = 2;
448: }
449:
450: if (vga_setmode(vgamode) < 0) {
451: sleep(1);
452: vga_setmode(TEXT);
453: fprintf(stderr, "SVGAlib doesn't like my video mode. Giving up.\n");
454: return 0;
455: }
456:
457: if ((modeinfo.flags & CAPABLE_LINEAR) && !no_xhair) {
458: if (vga_setlinearaddressing() != -1) {
459: linear_mem = (char *)vga_getgraphmem();
460: printf("Using linear addressing: %p.\n", linear_mem);
461: using_linear = !need_dither;
462: }
463: }
1.1.1.2 ! root 464:
1.1 root 465: gfxvidinfo.maxblocklines = 0;
466:
1.1.1.2 ! root 467: gfxvidinfo.maxlinetoscr = modeinfo.width;
! 468: gfxvidinfo.maxline = modeinfo.height;
! 469:
1.1 root 470: if (using_linear) {
471: gfxvidinfo.bufmem = linear_mem;
472: gfxvidinfo.rowbytes = modeinfo.linewidth;
473: } else {
1.1.1.2 ! root 474: gfxvidinfo.rowbytes = (modeinfo.width * gfxvidinfo.pixbytes + 3) & ~3;
! 475: gfxvidinfo.bufmem = malloc(gfxvidinfo.rowbytes * modeinfo.height);
! 476: memset(gfxvidinfo.bufmem, 0, gfxvidinfo.rowbytes * modeinfo.height);
1.1 root 477: }
478:
479: init_colors();
480: vga_setmousesupport(1);
1.1.1.2 ! root 481: mouse_init("/dev/mouse", vga_getmousetype(), 10);
1.1 root 482: if (keyboard_init() != 0)
483: abort();
484: keyboard_seteventhandler(my_kbd_handler);
485: keyboard_translatekeys(DONT_CATCH_CTRLC);
486:
487: buttonstate[0] = buttonstate[1] = buttonstate[2] = 0;
488: for(i = 0; i < 256; i++)
489: keystate[i] = 0;
490:
491: lastmx = lastmy = 0;
492: newmousecounters = 0;
493:
494: mouse_setxrange(-1000,1000);
495: mouse_setyrange(-1000,1000);
496: mouse_setposition(0,0);
497:
498: return 1;
499: }
500:
501: void graphics_leave(void)
502: {
503: sleep(1); /* Maybe this will fix the "screen full of garbage" problem */
504: vga_setmode(TEXT);
505: keyboard_close();
506: dumpcustom();
507: }
508:
509: void handle_events(void)
510: {
511: int button = mouse_getbutton();
512:
513: keyboard_update();
514: mouse_update();
515: lastmx += mouse_getx();
516: lastmy += mouse_gety();
517: mouse_setposition(0,0);
518:
519: buttonstate[0] = button & 4;
520: buttonstate[1] = button & 2;
521: buttonstate[2] = button & 1;
522: }
523:
524: int debuggable(void)
525: {
526: return 0;
527: }
528:
529: int needmousehack(void)
530: {
531: return 0;
532: }
533:
534: void LED(int on)
535: {
536: }
537:
538: void target_specific_usage(void)
539: {
1.1.1.2 ! root 540: printf(" -S n : Sound emulation accuracy (n = 0, 1, 2 or 3)\n"
! 541: " For sound emulation, n = 2 is recommended\n");
! 542: printf(" -b n : Use n bits for sound output (8 or 16)\n");
! 543: printf(" -R n : Use n Hz to output sound. Common values are\n"
! 544: " 22050 Hz or 44100 Hz\n");
! 545: printf(" -B n : Use a sound buffer of n bytes (use small\n"
! 546: " values on fast machines)\n");
! 547: printf(" -x : Don't use SVGAlib linear framebuffer, even if available.\n");
! 548: printf(" -p command : Use command to pipe printer output to.\n");
! 549: printf(" -I device : Name of the used serial device (i.e. /dev/ttyS1\n");
1.1 root 550: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.