ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/video.cpp
(Generate patch)

Comparing BasiliskII/src/video.cpp (file contents):
Revision 1.6 by cebix, 2000-08-22T12:44:29Z vs.
Revision 1.10 by cebix, 2001-06-27T20:05:23Z

# Line 1 | Line 1
1   /*
2   *  video.cpp - Video/graphics emulation
3   *
4 < *  Basilisk II (C) 1997-2000 Christian Bauer
4 > *  Basilisk II (C) 1997-2001 Christian Bauer
5   *  Portions (C) 1997-1999 Marc Hellwig
6   *
7   *  This program is free software; you can redistribute it and/or modify
# Line 34 | Line 34
34   #include "video.h"
35   #include "video_defs.h"
36  
37 < #define DEBUG 0
37 > #define DEBUG 1
38   #include "debug.h"
39  
40  
41 + // List of supported video modes
42 + vector<video_mode> VideoModes;
43 +
44   // Description of the main monitor
45 < video_desc VideoMonitor;
45 > monitor_desc VideoMonitor;
46  
47   // Local variables (per monitor)
48   struct {
49 <        video_desc *desc;                       // Pointer to monitor description
49 >        monitor_desc *desc;                     // Pointer to description of monitor handled by this instance of the driver
50          uint8 palette[256 * 3];         // Color palette, 256 entries, RGB
51          bool luminance_mapping;         // Luminance mapping on/off
52          bool interrupts_enabled;        // VBL interrupts on/off
53 +        uint16 current_mode;            // Currently selected depth/resolution
54 +        uint32 current_id;
55 +        uint16 preferred_mode;          // Preferred depth/resolution
56 +        uint32 preferred_id;
57   } VidLocal;
58  
59  
60   /*
61 + *  Check whether specified resolution ID is one of the supported resolutions
62 + */
63 +
64 + static bool has_resolution(uint32 id)
65 + {
66 +        std::vector<video_mode>::const_iterator i = VideoModes.begin(), end = VideoModes.end();
67 +        while (i != end) {
68 +                if (i->resolution_id == id)
69 +                        return true;
70 +                ++i;
71 +        }
72 +        return false;
73 + }
74 +
75 +
76 + /*
77 + *  Find specified mode (depth/resolution) (or VideoModes.end() if not found)
78 + */
79 +
80 + static std::vector<video_mode>::const_iterator find_mode(uint16 mode, uint32 id)
81 + {
82 +        std::vector<video_mode>::const_iterator i = VideoModes.begin(), end = VideoModes.end();
83 +        while (i != end) {
84 +                if (i->resolution_id == id && DepthToAppleMode(i->depth) == mode)
85 +                        return i;
86 +                ++i;
87 +        }
88 +        return i;
89 + }
90 +
91 +
92 + /*
93 + *  Find maximum supported depth for given resolution ID
94 + */
95 +
96 + static video_depth max_depth_of_resolution(uint32 id)
97 + {
98 +        video_depth m = VDEPTH_1BIT;
99 +        vector<video_mode>::const_iterator i = VideoModes.begin(), end = VideoModes.end();
100 +        while (i != end) {
101 +                if (i->depth > m)
102 +                        m = i->depth;
103 +                ++i;
104 +        }
105 +        return m;
106 + }
107 +
108 +
109 + /*
110 + *  Get X/Y size of specified resolution
111 + */
112 +
113 + static void get_size_of_resolution(uint32 id, uint32 &x, uint32 &y)
114 + {
115 +        vector<video_mode>::const_iterator i = VideoModes.begin(), end = VideoModes.end();
116 +        while (i != end) {
117 +                if (i->resolution_id == id) {
118 +                        x = i->x;
119 +                        y = i->y;
120 +                        return;
121 +                }
122 +                ++i;
123 +        }
124 + }
125 +
126 +
127 + /*
128   *  Driver Open() routine
129   */
130  
# Line 58 | Line 132 | int16 VideoDriverOpen(uint32 pb, uint32
132   {
133          D(bug("VideoDriverOpen\n"));
134  
135 +        // This shouldn't happen unless the platform-specific video code is broken
136 +        if (VideoModes.empty())
137 +                fprintf(stderr, "No valid video modes found (broken video driver?)\n");
138 +
139          // Init local variables
140          VidLocal.desc = &VideoMonitor;
141          VidLocal.luminance_mapping = false;
142          VidLocal.interrupts_enabled = false;
143 +        VidLocal.current_mode = DepthToAppleMode(VidLocal.desc->mode.depth);
144 +        VidLocal.current_id = VidLocal.desc->mode.resolution_id;
145 +        VidLocal.preferred_mode = VidLocal.current_mode;
146 +        VidLocal.preferred_id = VidLocal.current_id;
147  
148          // Init color palette (solid gray)
149          if (!IsDirectMode(VidLocal.desc->mode)) {
# Line 87 | Line 169 | int16 VideoDriverControl(uint32 pb, uint
169          D(bug("VideoDriverControl %d\n", code));
170          switch (code) {
171  
172 <                case cscSetMode:                // Set color depth
173 <                        D(bug(" SetMode %04x\n", ReadMacInt16(param + csMode)));
172 >                case cscSetMode: {              // Set color depth
173 >                        uint16 mode = ReadMacInt16(param + csMode);
174 >                        D(bug(" SetMode %04x\n", mode));
175 >
176 >                        if (mode != VidLocal.current_mode) {
177 >                                std::vector<video_mode>::const_iterator i = find_mode(mode, VidLocal.current_id);
178 >                                if (i == VideoModes.end()) {
179 >                                        WriteMacInt32(param + csBaseAddr, VidLocal.desc->mac_frame_base);
180 >                                        return paramErr;
181 >                                }
182 >                                video_switch_to_mode(*i);
183 >                                VidLocal.current_mode = mode;
184 >                        }
185                          WriteMacInt32(param + csBaseAddr, VidLocal.desc->mac_frame_base);
186                          return noErr;
187 +                }
188  
189                  case cscSetEntries: {   // Set palette
190                          D(bug(" SetEntries table %08lx, count %d, start %d\n", ReadMacInt32(param + csTable), ReadMacInt16(param + csCount), ReadMacInt16(param + csStart)));
# Line 136 | Line 230 | int16 VideoDriverControl(uint32 pb, uint
230  
231                  case cscSetGamma:               // Set gamma table
232                          D(bug(" SetGamma\n"));
233 +                        //!!
234                          return noErr;
235  
236                  case cscGrayPage: {             // Fill page with dithered gray pattern
# Line 152 | Line 247 | int16 VideoDriverControl(uint32 pb, uint
247                                  0xffffffff              // 32 bpp
248                          };
249                          uint32 p = VidLocal.desc->mac_frame_base;
250 <                        uint32 pat = pattern[VidLocal.desc->mode];
251 <                        for (uint32 y=0; y<VidLocal.desc->y; y++) {
252 <                                uint32 p2 = p;
253 <                                for (uint32 x=0; x<VidLocal.desc->bytes_per_row / 4; x++) {
254 <                                        WriteMacInt32(p2, pat);
160 <                                        p2 += 4;
161 <                                        if (VidLocal.desc->mode == VMODE_32BIT)
250 >                        uint32 pat = pattern[VidLocal.desc->mode.depth];
251 >                        for (uint32 y=0; y<VidLocal.desc->mode.y; y++) {
252 >                                for (uint32 x=0; x<VidLocal.desc->mode.bytes_per_row; x+=4) {
253 >                                        WriteMacInt32(p + x, pat);
254 >                                        if (VidLocal.desc->mode.depth == VDEPTH_32BIT)
255                                                  pat = ~pat;
256                                  }
257 <                                p += VidLocal.desc->bytes_per_row;
257 >                                p += VidLocal.desc->mode.bytes_per_row;
258                                  pat = ~pat;
259                          }
260                          return noErr;
# Line 172 | Line 265 | int16 VideoDriverControl(uint32 pb, uint
265                          VidLocal.luminance_mapping = ReadMacInt8(param + csMode);
266                          return noErr;
267  
175                case cscSwitchMode:             // Switch video mode
176                        D(bug(" SwitchMode %04x, %08lx\n", ReadMacInt16(param + csMode), ReadMacInt32(param + csData)));
177                        WriteMacInt32(param + csBaseAddr, VidLocal.desc->mac_frame_base);
178                        return noErr;
179
268                  case cscSetInterrupt:   // Enable/disable VBL
269                          D(bug(" SetInterrupt %02x\n", ReadMacInt8(param + csMode)));
270                          VidLocal.interrupts_enabled = (ReadMacInt8(param + csMode) == 0);
271                          return noErr;
272  
273 +                // case cscDirectSetEntries:
274 +
275 +                case cscSetDefaultMode: { // Set default color depth
276 +                        uint16 mode = ReadMacInt16(param + csMode);
277 +                        D(bug(" SetDefaultMode %04x\n", mode));
278 +                        VidLocal.preferred_mode = mode;
279 +                        return noErr;
280 +                }
281 +
282 +                case cscSwitchMode: {   // Switch video mode (depth and resolution)
283 +                        uint16 mode = ReadMacInt16(param + csMode);
284 +                        uint32 id = ReadMacInt32(param + csData);
285 +                        D(bug(" SwitchMode %04x, %08x\n", mode, id));
286 +
287 +                        if (mode != VidLocal.current_mode || id != VidLocal.current_id) {
288 +                                std::vector<video_mode>::const_iterator i = find_mode(mode, id);
289 +                                if (i == VideoModes.end()) {
290 +                                        WriteMacInt32(param + csBaseAddr, VidLocal.desc->mac_frame_base);
291 +                                        return paramErr;
292 +                                }
293 +                                video_switch_to_mode(*i);
294 +                                VidLocal.current_mode = mode;
295 +                                VidLocal.current_id = id;
296 +                        }
297 +                        WriteMacInt32(param + csBaseAddr, VidLocal.desc->mac_frame_base);
298 +                        return noErr;
299 +                }
300 +
301 +                case cscSavePreferredConfiguration: {
302 +                        uint16 mode = ReadMacInt16(param + csMode);
303 +                        uint32 id = ReadMacInt32(param + csData);
304 +                        D(bug(" SavePreferredConfiguration %04x, %08x\n", mode, id));
305 +                        VidLocal.preferred_mode = mode;
306 +                        VidLocal.preferred_id = id;
307 +                        return noErr;
308 +                }
309 +
310                  default:
311                          printf("WARNING: Unknown VideoDriverControl(%d)\n", code);
312                          return controlErr;
# Line 200 | Line 325 | int16 VideoDriverStatus(uint32 pb, uint3
325          D(bug("VideoDriverStatus %d\n", code));
326          switch (code) {
327  
328 +                case cscGetMode:                        // Get current color depth
329 +                        D(bug(" GetMode -> %04x, base %08x\n", VidLocal.current_mode, VidLocal.desc->mac_frame_base));
330 +                        WriteMacInt16(param + csMode, VidLocal.current_mode);
331 +                        WriteMacInt16(param + csPage, 0);
332 +                        WriteMacInt32(param + csBaseAddr, VidLocal.desc->mac_frame_base);
333 +                        return noErr;
334 +
335 +                // case cscGetEntries:
336 +
337                  case cscGetPageCnt:                     // Get number of pages
338 <                        D(bug(" GetPageCnt\n"));
338 >                        D(bug(" GetPageCnt -> 1\n"));
339                          WriteMacInt16(param + csPage, 1);
340                          return noErr;
341  
342                  case cscGetPageBase:            // Get page base address
343 <                        D(bug(" GetPageBase\n"));
343 >                        D(bug(" GetPageBase -> %08x\n", VidLocal.desc->mac_frame_base));
344                          WriteMacInt32(param + csBaseAddr, VidLocal.desc->mac_frame_base);
345                          return noErr;
346  
347                  case cscGetGray:                        // Get luminance mapping flag
348 <                        D(bug(" GetGray\n"));
349 <                        WriteMacInt8(param + csMode, VidLocal.luminance_mapping ? 1 : 0);
348 >                        D(bug(" GetGray -> %d\n", VidLocal.luminance_mapping));
349 >                        WriteMacInt8(param, VidLocal.luminance_mapping ? 1 : 0);
350                          return noErr;
351  
352                  case cscGetInterrupt:           // Get interrupt disable flag
353 <                        D(bug(" GetInterrupt\n"));
354 <                        WriteMacInt8(param + csMode, VidLocal.interrupts_enabled ? 0 : 1);
353 >                        D(bug(" GetInterrupt -> %d\n", VidLocal.interrupts_enabled));
354 >                        WriteMacInt8(param, VidLocal.interrupts_enabled ? 0 : 1);
355                          return noErr;
356  
357 <                case cscGetDefaultMode:         // Get default video mode
358 <                        D(bug(" GetDefaultMode\n"));
359 <                        WriteMacInt8(param + csMode, 0x80);
357 >                // case cscGetGamma:
358 >
359 >                case cscGetDefaultMode:         // Get default color depth
360 >                        D(bug(" GetDefaultMode -> %04x\n", VidLocal.preferred_mode));
361 >                        WriteMacInt16(param + csMode, VidLocal.preferred_mode);
362                          return noErr;
363  
364 <                case cscGetCurMode:                     // Get current video mode
365 <                        D(bug(" GetCurMode\n"));
366 <                        WriteMacInt16(param + csMode, 0x80);
367 <                        WriteMacInt32(param + csData, 0x80);
364 >                case cscGetCurMode:                     // Get current video mode (depth and resolution)
365 >                        D(bug(" GetCurMode -> %04x/%08x\n", VidLocal.current_mode, VidLocal.current_id));
366 >                        WriteMacInt16(param + csMode, VidLocal.current_mode);
367 >                        WriteMacInt32(param + csData, VidLocal.current_id);
368                          WriteMacInt16(param + csPage, 0);
369                          WriteMacInt32(param + csBaseAddr, VidLocal.desc->mac_frame_base);
370                          return noErr;
# Line 242 | Line 378 | int16 VideoDriverStatus(uint32 pb, uint3
378                          WriteMacInt32(param + csDisplayComponent, 0);
379                          return noErr;
380  
245                case cscGetModeTiming:          // Get video timing for mode
246                        D(bug(" GetModeTiming mode %08lx\n", ReadMacInt32(param + csTimingMode)));
247                        WriteMacInt32(param + csTimingFormat, FOURCC('d', 'e', 'c', 'l'));
248                        WriteMacInt32(param + csTimingData, 220);               // 21" Multiscan
249                        WriteMacInt32(param + csTimingFlags, 0x0f);             // Mode valid, safe, default and shown in Monitors panel
250                        return noErr;
251
381                  case cscGetModeBaseAddress:     // Get frame buffer base address
382 <                        D(bug(" GetModeBaseAddress\n"));
382 >                        D(bug(" GetModeBaseAddress -> %08x\n", VidLocal.desc->mac_frame_base));
383                          WriteMacInt32(param + csBaseAddr, VidLocal.desc->mac_frame_base);       // Base address of video RAM for the current DisplayModeID and relative bit depth
384                          return noErr;
385  
386 <                case cscGetMode:                // REQUIRED for MacsBug
387 <                        D(bug(" GetMode\n"));
388 <                        WriteMacInt16(param + csPageMode, 0x80);
389 <                        WriteMacInt32(param + csPageData, 0x80);        // Unused
390 <                        WriteMacInt16(param + csPagePage, 0);   // Current display page
391 <                        WriteMacInt32(param + csPageBaseAddr, VidLocal.desc->mac_frame_base);
386 >                case cscGetPreferredConfiguration: // Get default video mode (depth and resolution)
387 >                        D(bug(" GetPreferredConfiguration -> %04x/%08x\n", VidLocal.preferred_mode, VidLocal.preferred_id));
388 >                        WriteMacInt16(param + csMode, VidLocal.preferred_mode);
389 >                        WriteMacInt32(param + csData, VidLocal.preferred_id);
390 >                        return noErr;
391 >
392 >                case cscGetNextResolution: {    // Called iteratively to obtain a list of all supported resolutions
393 >                        uint32 id = ReadMacInt32(param + csPreviousDisplayModeID);
394 >                        D(bug(" GetNextResolution %08x\n", id));
395 >
396 >                        switch (id) {
397 >                                case 0:
398 >                                        // Return current resolution
399 >                                        id = VidLocal.current_id;
400 >                                        break;
401 >
402 >                                case 0xfffffffe:
403 >                                        // Return first supported resolution
404 >                                        id = 0x80;
405 >                                        while (!has_resolution(id))
406 >                                                id++;
407 >                                        break;
408 >
409 >                                default:
410 >                                        // Get next resolution
411 >                                        if (!has_resolution(id))
412 >                                                return paramErr;
413 >                                        id++;
414 >                                        while (!has_resolution(id) && id < 0x100)
415 >                                                id++;
416 >                                        if (id == 0x100) { // No more resolutions
417 >                                                WriteMacInt32(param + csRIDisplayModeID, 0xfffffffd);
418 >                                                return noErr;
419 >                                        }
420 >                                        break;
421 >                        }
422 >
423 >                        WriteMacInt32(param + csRIDisplayModeID, id);
424 >                        uint32 x, y;
425 >                        get_size_of_resolution(id, x, y);
426 >                        WriteMacInt32(param + csHorizontalPixels, x);
427 >                        WriteMacInt32(param + csVerticalLines, y);
428 >                        WriteMacInt32(param + csRefreshRate, 75 << 16);
429 >                        WriteMacInt16(param + csMaxDepthMode, DepthToAppleMode(max_depth_of_resolution(id)));
430 >                        uint32 flags = 0xb; // mode valid, safe and shown in Monitors panel
431 >                        if (id == VidLocal.preferred_id)
432 >                                flags |= 4; // default mode
433 >                        WriteMacInt32(param + csResolutionFlags, flags);
434                          return noErr;
435 +                }
436 +
437 +                case cscGetVideoParameters: {   // Get information about specified resolution/depth
438 +                        uint32 id = ReadMacInt32(param + csDisplayModeID);
439 +                        uint16 mode = ReadMacInt16(param + csDepthMode);
440 +                        D(bug(" GetVideoParameters %04x/%08x\n", mode, id));
441 +
442 +                        vector<video_mode>::const_iterator i = VideoModes.begin(), end = VideoModes.end();
443 +                        while (i != end) {
444 +                                if (DepthToAppleMode(i->depth) == mode && i->resolution_id == id) {
445 +                                        uint32 vp = ReadMacInt32(param + csVPBlockPtr);
446 +                                        WriteMacInt32(vp + vpBaseOffset, 0);
447 +                                        WriteMacInt16(vp + vpRowBytes, i->bytes_per_row);
448 +                                        WriteMacInt16(vp + vpBounds, 0);
449 +                                        WriteMacInt16(vp + vpBounds + 2, 0);
450 +                                        WriteMacInt16(vp + vpBounds + 4, i->y);
451 +                                        WriteMacInt16(vp + vpBounds + 6, i->x);
452 +                                        WriteMacInt16(vp + vpVersion, 0);
453 +                                        WriteMacInt16(vp + vpPackType, 0);
454 +                                        WriteMacInt32(vp + vpPackSize, 0);
455 +                                        WriteMacInt32(vp + vpHRes, 0x00480000);
456 +                                        WriteMacInt32(vp + vpVRes, 0x00480000);
457 +                                        uint32 pix_type, pix_size, cmp_count, cmp_size, dev_type;
458 +                                        switch (i->depth) {
459 +                                                case VDEPTH_1BIT:
460 +                                                        pix_type = 0; pix_size = 1;
461 +                                                        cmp_count = 1; cmp_size = 1;
462 +                                                        dev_type = 0; // CLUT
463 +                                                        break;
464 +                                                case VDEPTH_2BIT:
465 +                                                        pix_type = 0; pix_size = 2;
466 +                                                        cmp_count = 1; cmp_size = 2;
467 +                                                        dev_type = 0; // CLUT
468 +                                                        break;
469 +                                                case VDEPTH_4BIT:
470 +                                                        pix_type = 0; pix_size = 4;
471 +                                                        cmp_count = 1; cmp_size = 4;
472 +                                                        dev_type = 0; // CLUT
473 +                                                        break;
474 +                                                case VDEPTH_8BIT:
475 +                                                        pix_type = 0; pix_size = 8;
476 +                                                        cmp_count = 1; cmp_size = 8;
477 +                                                        dev_type = 0; // CLUT
478 +                                                        break;
479 +                                                case VDEPTH_16BIT:
480 +                                                        pix_type = 0x10; pix_size = 16;
481 +                                                        cmp_count = 3; cmp_size = 5;
482 +                                                        dev_type = 2; // direct
483 +                                                        break;
484 +                                                case VDEPTH_32BIT:
485 +                                                        pix_type = 0x10; pix_size = 32;
486 +                                                        cmp_count = 3; cmp_size = 8;
487 +                                                        dev_type = 2; // direct
488 +                                                        break;
489 +                                        }
490 +                                        WriteMacInt16(vp + vpPixelType, pix_type);
491 +                                        WriteMacInt16(vp + vpPixelSize, pix_size);
492 +                                        WriteMacInt16(vp + vpCmpCount, cmp_count);
493 +                                        WriteMacInt16(vp + vpCmpSize, cmp_size);
494 +                                        WriteMacInt32(param + csPageCount, 1);
495 +                                        WriteMacInt32(param + csDeviceType, dev_type);
496 +                                        return noErr;
497 +                                }
498 +                                ++i;
499 +                        }
500 +                        return paramErr; // specified resolution/depth not supported
501 +                }
502 +
503 +                case cscGetModeTiming: {        // Get video timing for specified resolution
504 +                        uint32 id = ReadMacInt32(param + csTimingMode);
505 +                        D(bug(" GetModeTiming %08x\n", id));
506 +                        if (!has_resolution(id))
507 +                                return paramErr;
508 +
509 +                        WriteMacInt32(param + csTimingFormat, FOURCC('d', 'e', 'c', 'l'));
510 +                        WriteMacInt32(param + csTimingData, 0); // unknown
511 +                        uint32 flags = 0xb; // mode valid, safe and shown in Monitors panel
512 +                        if (id == VidLocal.preferred_id)
513 +                                flags |= 4; // default mode
514 +                        WriteMacInt32(param + csTimingFlags, flags);
515 +                        return noErr;
516 +                }
517  
518                  default:
519                          printf("WARNING: Unknown VideoDriverStatus(%d)\n", code);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines