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.9 by cebix, 2001-06-27T19:03:35Z

# 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 38 | Line 38
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 +        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 maximum supported depth for given resolution ID
78 + */
79 +
80 + static video_depth max_depth_of_resolution(uint32 id)
81 + {
82 +        video_depth m = VDEPTH_1BIT;
83 +        vector<video_mode>::const_iterator i = VideoModes.begin(), end = VideoModes.end();
84 +        while (i != end) {
85 +                if (i->depth > m)
86 +                        m = i->depth;
87 +                ++i;
88 +        }
89 +        return m;
90 + }
91 +
92 +
93 + /*
94 + *  Get X/Y size of specified resolution
95 + */
96 +
97 + static void get_size_of_resolution(uint32 id, uint32 &x, uint32 &y)
98 + {
99 +        vector<video_mode>::const_iterator i = VideoModes.begin(), end = VideoModes.end();
100 +        while (i != end) {
101 +                if (i->resolution_id == id) {
102 +                        x = i->x;
103 +                        y = i->y;
104 +                        return;
105 +                }
106 +                ++i;
107 +        }
108 + }
109 +
110 +
111 + /*
112   *  Driver Open() routine
113   */
114  
# Line 58 | Line 116 | int16 VideoDriverOpen(uint32 pb, uint32
116   {
117          D(bug("VideoDriverOpen\n"));
118  
119 +        // This shouldn't happen unless the platform-specific video code is broken
120 +        if (VideoModes.empty())
121 +                fprintf(stderr, "No valid video modes found (broken video driver?)\n");
122 +
123          // Init local variables
124          VidLocal.desc = &VideoMonitor;
125          VidLocal.luminance_mapping = false;
126          VidLocal.interrupts_enabled = false;
127 +        VidLocal.current_mode = DepthToAppleMode(VidLocal.desc->mode.depth);
128 +        VidLocal.current_id = VidLocal.desc->mode.resolution_id;
129 +        VidLocal.preferred_mode = VidLocal.current_mode;
130 +        VidLocal.preferred_id = VidLocal.current_id;
131  
132          // Init color palette (solid gray)
133          if (!IsDirectMode(VidLocal.desc->mode)) {
# Line 87 | Line 153 | int16 VideoDriverControl(uint32 pb, uint
153          D(bug("VideoDriverControl %d\n", code));
154          switch (code) {
155  
156 <                case cscSetMode:                // Set color depth
157 <                        D(bug(" SetMode %04x\n", ReadMacInt16(param + csMode)));
156 >                case cscSetMode: {              // Set color depth
157 >                        uint16 mode = ReadMacInt16(param + csMode);
158 >                        D(bug(" SetMode %04x\n", mode));
159 >                        //!! switch mode
160                          WriteMacInt32(param + csBaseAddr, VidLocal.desc->mac_frame_base);
161 <                        return noErr;
161 >                        //!! VidLocal.current_mode = mode;
162 >                        if (mode != VidLocal.current_mode)
163 >                                return paramErr;
164 >                        else
165 >                                return noErr;
166 >                }
167  
168                  case cscSetEntries: {   // Set palette
169                          D(bug(" SetEntries table %08lx, count %d, start %d\n", ReadMacInt32(param + csTable), ReadMacInt16(param + csCount), ReadMacInt16(param + csStart)));
# Line 136 | Line 209 | int16 VideoDriverControl(uint32 pb, uint
209  
210                  case cscSetGamma:               // Set gamma table
211                          D(bug(" SetGamma\n"));
212 +                        //!!
213                          return noErr;
214  
215                  case cscGrayPage: {             // Fill page with dithered gray pattern
# Line 152 | Line 226 | int16 VideoDriverControl(uint32 pb, uint
226                                  0xffffffff              // 32 bpp
227                          };
228                          uint32 p = VidLocal.desc->mac_frame_base;
229 <                        uint32 pat = pattern[VidLocal.desc->mode];
230 <                        for (uint32 y=0; y<VidLocal.desc->y; y++) {
231 <                                uint32 p2 = p;
232 <                                for (uint32 x=0; x<VidLocal.desc->bytes_per_row / 4; x++) {
233 <                                        WriteMacInt32(p2, pat);
160 <                                        p2 += 4;
161 <                                        if (VidLocal.desc->mode == VMODE_32BIT)
229 >                        uint32 pat = pattern[VidLocal.desc->mode.depth];
230 >                        for (uint32 y=0; y<VidLocal.desc->mode.y; y++) {
231 >                                for (uint32 x=0; x<VidLocal.desc->mode.bytes_per_row; x+=4) {
232 >                                        WriteMacInt32(p + x, pat);
233 >                                        if (VidLocal.desc->mode.depth == VDEPTH_32BIT)
234                                                  pat = ~pat;
235                                  }
236 <                                p += VidLocal.desc->bytes_per_row;
236 >                                p += VidLocal.desc->mode.bytes_per_row;
237                                  pat = ~pat;
238                          }
239                          return noErr;
# Line 172 | Line 244 | int16 VideoDriverControl(uint32 pb, uint
244                          VidLocal.luminance_mapping = ReadMacInt8(param + csMode);
245                          return noErr;
246  
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
247                  case cscSetInterrupt:   // Enable/disable VBL
248                          D(bug(" SetInterrupt %02x\n", ReadMacInt8(param + csMode)));
249                          VidLocal.interrupts_enabled = (ReadMacInt8(param + csMode) == 0);
250                          return noErr;
251  
252 +                // case cscDirectSetEntries:
253 +
254 +                case cscSetDefaultMode: { // Set default color depth
255 +                        uint16 mode = ReadMacInt16(param + csMode);
256 +                        D(bug(" SetDefaultMode %04x\n", mode));
257 +                        VidLocal.preferred_mode = mode;
258 +                        return noErr;
259 +                }
260 +
261 +                case cscSwitchMode: {   // Switch video mode (depth and resolution)
262 +                        uint16 mode = ReadMacInt16(param + csMode);
263 +                        uint32 id = ReadMacInt32(param + csData);
264 +                        D(bug(" SwitchMode %04x, %08x\n", mode, id));
265 +                        //!! switch mode
266 +                        WriteMacInt32(param + csBaseAddr, VidLocal.desc->mac_frame_base);
267 +                        //!! VidLocal.current_mode = mode;
268 +                        //!! VidLocal.current_id = id;
269 +                        if (mode != VidLocal.current_mode || id != VidLocal.current_id)
270 +                                return paramErr;
271 +                        else
272 +                                return noErr;
273 +                }
274 +
275 +                case cscSavePreferredConfiguration: {
276 +                        uint16 mode = ReadMacInt16(param + csMode);
277 +                        uint32 id = ReadMacInt32(param + csData);
278 +                        D(bug(" SavePreferredConfiguration %04x, %08x\n", mode, id));
279 +                        VidLocal.preferred_mode = mode;
280 +                        VidLocal.preferred_id = id;
281 +                        return noErr;
282 +                }
283 +
284                  default:
285                          printf("WARNING: Unknown VideoDriverControl(%d)\n", code);
286                          return controlErr;
# Line 200 | Line 299 | int16 VideoDriverStatus(uint32 pb, uint3
299          D(bug("VideoDriverStatus %d\n", code));
300          switch (code) {
301  
302 +                case cscGetMode:                        // Get current color depth
303 +                        D(bug(" GetMode -> %04x, base %08x\n", VidLocal.current_mode, VidLocal.desc->mac_frame_base));
304 +                        WriteMacInt16(param + csMode, VidLocal.current_mode);
305 +                        WriteMacInt16(param + csPage, 0);
306 +                        WriteMacInt32(param + csBaseAddr, VidLocal.desc->mac_frame_base);
307 +                        return noErr;
308 +
309 +                // case cscGetEntries:
310 +
311                  case cscGetPageCnt:                     // Get number of pages
312 <                        D(bug(" GetPageCnt\n"));
312 >                        D(bug(" GetPageCnt -> 1\n"));
313                          WriteMacInt16(param + csPage, 1);
314                          return noErr;
315  
316                  case cscGetPageBase:            // Get page base address
317 <                        D(bug(" GetPageBase\n"));
317 >                        D(bug(" GetPageBase -> %08x\n", VidLocal.desc->mac_frame_base));
318                          WriteMacInt32(param + csBaseAddr, VidLocal.desc->mac_frame_base);
319                          return noErr;
320  
321                  case cscGetGray:                        // Get luminance mapping flag
322 <                        D(bug(" GetGray\n"));
323 <                        WriteMacInt8(param + csMode, VidLocal.luminance_mapping ? 1 : 0);
322 >                        D(bug(" GetGray -> %d\n", VidLocal.luminance_mapping));
323 >                        WriteMacInt8(param, VidLocal.luminance_mapping ? 1 : 0);
324                          return noErr;
325  
326                  case cscGetInterrupt:           // Get interrupt disable flag
327 <                        D(bug(" GetInterrupt\n"));
328 <                        WriteMacInt8(param + csMode, VidLocal.interrupts_enabled ? 0 : 1);
327 >                        D(bug(" GetInterrupt -> %d\n", VidLocal.interrupts_enabled));
328 >                        WriteMacInt8(param, VidLocal.interrupts_enabled ? 0 : 1);
329                          return noErr;
330  
331 <                case cscGetDefaultMode:         // Get default video mode
332 <                        D(bug(" GetDefaultMode\n"));
333 <                        WriteMacInt8(param + csMode, 0x80);
331 >                // case cscGetGamma:
332 >
333 >                case cscGetDefaultMode:         // Get default color depth
334 >                        D(bug(" GetDefaultMode -> %04x\n", VidLocal.preferred_mode));
335 >                        WriteMacInt16(param + csMode, VidLocal.preferred_mode);
336                          return noErr;
337  
338 <                case cscGetCurMode:                     // Get current video mode
339 <                        D(bug(" GetCurMode\n"));
340 <                        WriteMacInt16(param + csMode, 0x80);
341 <                        WriteMacInt32(param + csData, 0x80);
338 >                case cscGetCurMode:                     // Get current video mode (depth and resolution)
339 >                        D(bug(" GetCurMode -> %04x/%08x\n", VidLocal.current_mode, VidLocal.current_id));
340 >                        WriteMacInt16(param + csMode, VidLocal.current_mode);
341 >                        WriteMacInt32(param + csData, VidLocal.current_id);
342                          WriteMacInt16(param + csPage, 0);
343                          WriteMacInt32(param + csBaseAddr, VidLocal.desc->mac_frame_base);
344                          return noErr;
# Line 242 | Line 352 | int16 VideoDriverStatus(uint32 pb, uint3
352                          WriteMacInt32(param + csDisplayComponent, 0);
353                          return noErr;
354  
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
355                  case cscGetModeBaseAddress:     // Get frame buffer base address
356 <                        D(bug(" GetModeBaseAddress\n"));
356 >                        D(bug(" GetModeBaseAddress -> %08x\n", VidLocal.desc->mac_frame_base));
357                          WriteMacInt32(param + csBaseAddr, VidLocal.desc->mac_frame_base);       // Base address of video RAM for the current DisplayModeID and relative bit depth
358                          return noErr;
359  
360 <                case cscGetMode:                // REQUIRED for MacsBug
361 <                        D(bug(" GetMode\n"));
362 <                        WriteMacInt16(param + csPageMode, 0x80);
363 <                        WriteMacInt32(param + csPageData, 0x80);        // Unused
364 <                        WriteMacInt16(param + csPagePage, 0);   // Current display page
365 <                        WriteMacInt32(param + csPageBaseAddr, VidLocal.desc->mac_frame_base);
360 >                case cscGetPreferredConfiguration: // Get default video mode (depth and resolution)
361 >                        D(bug(" GetPreferredConfiguration -> %04x/%08x\n", VidLocal.preferred_mode, VidLocal.preferred_id));
362 >                        WriteMacInt16(param + csMode, VidLocal.preferred_mode);
363 >                        WriteMacInt32(param + csData, VidLocal.preferred_id);
364 >                        return noErr;
365 >
366 >                case cscGetNextResolution: {    // Called iteratively to obtain a list of all supported resolutions
367 >                        uint32 id = ReadMacInt32(param + csPreviousDisplayModeID);
368 >                        D(bug(" GetNextResolution %08x\n", id));
369 >
370 >                        switch (id) {
371 >                                case 0:
372 >                                        // Return current resolution
373 >                                        id = VidLocal.current_id;
374 >                                        break;
375 >
376 >                                case 0xfffffffe:
377 >                                        // Return first supported resolution
378 >                                        id = 0x80;
379 >                                        while (!has_resolution(id))
380 >                                                id++;
381 >                                        break;
382 >
383 >                                default:
384 >                                        // Get next resolution
385 >                                        if (!has_resolution(id))
386 >                                                return paramErr;
387 >                                        id++;
388 >                                        while (!has_resolution(id) && id < 0x100)
389 >                                                id++;
390 >                                        if (id == 0x100) { // No more resolutions
391 >                                                WriteMacInt32(param + csRIDisplayModeID, 0xfffffffd);
392 >                                                return noErr;
393 >                                        }
394 >                                        break;
395 >                        }
396 >
397 >                        WriteMacInt32(param + csRIDisplayModeID, id);
398 >                        uint32 x, y;
399 >                        get_size_of_resolution(id, x, y);
400 >                        WriteMacInt32(param + csHorizontalPixels, x);
401 >                        WriteMacInt32(param + csVerticalLines, y);
402 >                        WriteMacInt32(param + csRefreshRate, 75 << 16);
403 >                        WriteMacInt16(param + csMaxDepthMode, DepthToAppleMode(max_depth_of_resolution(id)));
404 >                        uint32 flags = 0xb; // mode valid, safe and shown in Monitors panel
405 >                        if (id == VidLocal.preferred_id)
406 >                                flags |= 4; // default mode
407 >                        WriteMacInt32(param + csResolutionFlags, flags);
408 >                        return noErr;
409 >                }
410 >
411 >                case cscGetVideoParameters: {   // Get information about specified resolution/depth
412 >                        uint32 id = ReadMacInt32(param + csDisplayModeID);
413 >                        uint16 mode = ReadMacInt16(param + csDepthMode);
414 >                        D(bug(" GetVideoParameters %04x/%08x\n", mode, id));
415 >
416 >                        vector<video_mode>::const_iterator i = VideoModes.begin(), end = VideoModes.end();
417 >                        while (i != end) {
418 >                                if (DepthToAppleMode(i->depth) == mode && i->resolution_id == id) {
419 >                                        uint32 vp = ReadMacInt32(param + csVPBlockPtr);
420 >                                        WriteMacInt32(vp + vpBaseOffset, 0);
421 >                                        WriteMacInt16(vp + vpRowBytes, i->bytes_per_row);
422 >                                        WriteMacInt16(vp + vpBounds, 0);
423 >                                        WriteMacInt16(vp + vpBounds + 2, 0);
424 >                                        WriteMacInt16(vp + vpBounds + 4, i->y);
425 >                                        WriteMacInt16(vp + vpBounds + 6, i->x);
426 >                                        WriteMacInt16(vp + vpVersion, 0);
427 >                                        WriteMacInt16(vp + vpPackType, 0);
428 >                                        WriteMacInt32(vp + vpPackSize, 0);
429 >                                        WriteMacInt32(vp + vpHRes, 0x00480000);
430 >                                        WriteMacInt32(vp + vpVRes, 0x00480000);
431 >                                        uint32 pix_type, pix_size, cmp_count, cmp_size, dev_type;
432 >                                        switch (i->depth) {
433 >                                                case VDEPTH_1BIT:
434 >                                                        pix_type = 0; pix_size = 1;
435 >                                                        cmp_count = 1; cmp_size = 1;
436 >                                                        dev_type = 0; // CLUT
437 >                                                        break;
438 >                                                case VDEPTH_2BIT:
439 >                                                        pix_type = 0; pix_size = 2;
440 >                                                        cmp_count = 1; cmp_size = 2;
441 >                                                        dev_type = 0; // CLUT
442 >                                                        break;
443 >                                                case VDEPTH_4BIT:
444 >                                                        pix_type = 0; pix_size = 4;
445 >                                                        cmp_count = 1; cmp_size = 4;
446 >                                                        dev_type = 0; // CLUT
447 >                                                        break;
448 >                                                case VDEPTH_8BIT:
449 >                                                        pix_type = 0; pix_size = 8;
450 >                                                        cmp_count = 1; cmp_size = 8;
451 >                                                        dev_type = 0; // CLUT
452 >                                                        break;
453 >                                                case VDEPTH_16BIT:
454 >                                                        pix_type = 0x10; pix_size = 16;
455 >                                                        cmp_count = 3; cmp_size = 5;
456 >                                                        dev_type = 2; // direct
457 >                                                        break;
458 >                                                case VDEPTH_32BIT:
459 >                                                        pix_type = 0x10; pix_size = 32;
460 >                                                        cmp_count = 3; cmp_size = 8;
461 >                                                        dev_type = 2; // direct
462 >                                                        break;
463 >                                        }
464 >                                        WriteMacInt16(vp + vpPixelType, pix_type);
465 >                                        WriteMacInt16(vp + vpPixelSize, pix_size);
466 >                                        WriteMacInt16(vp + vpCmpCount, cmp_count);
467 >                                        WriteMacInt16(vp + vpCmpSize, cmp_size);
468 >                                        WriteMacInt32(param + csPageCount, 1);
469 >                                        WriteMacInt32(param + csDeviceType, dev_type);
470 >                                        return noErr;
471 >                                }
472 >                                ++i;
473 >                        }
474 >                        return paramErr; // specified resolution/depth not supported
475 >                }
476 >
477 >                case cscGetModeTiming: {        // Get video timing for specified resolution
478 >                        uint32 id = ReadMacInt32(param + csTimingMode);
479 >                        D(bug(" GetModeTiming %08x\n", id));
480 >                        if (!has_resolution(id))
481 >                                return paramErr;
482 >
483 >                        WriteMacInt32(param + csTimingFormat, FOURCC('d', 'e', 'c', 'l'));
484 >                        WriteMacInt32(param + csTimingData, 0); // unknown
485 >                        uint32 flags = 0xb; // mode valid, safe and shown in Monitors panel
486 >                        if (id == VidLocal.preferred_id)
487 >                                flags |= 4; // default mode
488 >                        WriteMacInt32(param + csTimingFlags, flags);
489                          return noErr;
490 +                }
491  
492                  default:
493                          printf("WARNING: Unknown VideoDriverStatus(%d)\n", code);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines