home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / Emulation / BasiliskII / src / video.cpp < prev    next >
C/C++ Source or Header  |  1999-10-19  |  8KB  |  262 lines

  1. /*
  2.  *  video.cpp - Video/graphics emulation
  3.  *
  4.  *  Basilisk II (C) 1997-1999 Christian Bauer
  5.  *  Portions (C) 1997-1999 Marc Hellwig
  6.  *
  7.  *  This program is free software; you can redistribute it and/or modify
  8.  *  it under the terms of the GNU General Public License as published by
  9.  *  the Free Software Foundation; either version 2 of the License, or
  10.  *  (at your option) any later version.
  11.  *
  12.  *  This program is distributed in the hope that it will be useful,
  13.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  *  GNU General Public License for more details.
  16.  *
  17.  *  You should have received a copy of the GNU General Public License
  18.  *  along with this program; if not, write to the Free Software
  19.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  20.  */
  21.  
  22. /*
  23.  *  SEE ALSO
  24.  *    Inside Macintosh: Devices, chapter 1 "Device Manager"
  25.  *    Designing Cards and Drivers for the Macintosh Family, Second Edition
  26.  */
  27.  
  28. #include <stdio.h>
  29.  
  30. #include "sysdeps.h"
  31. #include "cpu_emulation.h"
  32. #include "main.h"
  33. #include "macos_util.h"
  34. #include "video.h"
  35. #include "video_defs.h"
  36.  
  37. #define DEBUG 0
  38. #include "debug.h"
  39.  
  40.  
  41. // Description of the main monitor
  42. video_desc VideoMonitor;
  43.  
  44. // Local variables (per monitor)
  45. struct {
  46.     video_desc *desc;            // Pointer to monitor description
  47.     uint8 palette[256 * 3];        // Color palette, 256 entries, RGB
  48.     bool luminance_mapping;        // Luminance mapping on/off
  49.     bool interrupts_enabled;    // VBL interrupts on/off
  50. } VidLocal;
  51.  
  52.  
  53. /*
  54.  *  Driver Open() routine
  55.  */
  56.  
  57. int16 VideoDriverOpen(uint32 pb, uint32 dce)
  58. {
  59.     D(bug("VideoDriverOpen\n"));
  60.  
  61.     // Init local variables
  62.     VidLocal.desc = &VideoMonitor;
  63.     VidLocal.luminance_mapping = false;
  64.     VidLocal.interrupts_enabled = false;
  65.  
  66.     // Init color palette (solid gray)
  67.     if (!IsDirectMode(VidLocal.desc->mode)) {
  68.         for (int i=0; i<256; i++) {
  69.             VidLocal.palette[i * 3 + 0] = 127;
  70.             VidLocal.palette[i * 3 + 1] = 127;
  71.             VidLocal.palette[i * 3 + 2] = 127;
  72.         }
  73.         video_set_palette(VidLocal.palette);
  74.     }
  75.     return noErr;
  76. }
  77.  
  78.  
  79. /*
  80.  *  Driver Control() routine
  81.  */
  82.  
  83. int16 VideoDriverControl(uint32 pb, uint32 dce)
  84. {
  85.     uint16 code = ReadMacInt16(pb + csCode);
  86.     uint32 param = ReadMacInt32(pb + csParam);
  87.     D(bug("VideoDriverControl %d\n", code));
  88.     switch (code) {
  89.  
  90.         case cscSetMode:        // Set color depth
  91.             D(bug(" SetMode %04x\n", ReadMacInt16(param + csMode)));
  92.             WriteMacInt32(param + csBaseAddr, VidLocal.desc->mac_frame_base);
  93.             return noErr;
  94.  
  95.         case cscSetEntries: {    // Set palette
  96.             D(bug(" SetEntries table %08lx, count %d, start %d\n", ReadMacInt32(param + csTable), ReadMacInt16(param + csCount), ReadMacInt16(param + csStart)));
  97.             if (IsDirectMode(VidLocal.desc->mode))
  98.                 return controlErr;
  99.  
  100.             uint32 s_pal = ReadMacInt32(param + csTable);    // Source palette
  101.             uint8 *d_pal;                                    // Destination palette
  102.             uint16 count = ReadMacInt16(param + csCount);
  103.             if (!s_pal || count > 255)
  104.                 return paramErr;
  105.  
  106.             if (ReadMacInt16(param + csStart) == 0xffff) {    // Indexed
  107.                 for (uint32 i=0; i<=count; i++) {
  108.                     d_pal = VidLocal.palette + ReadMacInt16(s_pal) * 3;
  109.                     uint8 red = (uint16)ReadMacInt16(s_pal + 2) >> 8;
  110.                     uint8 green = (uint16)ReadMacInt16(s_pal + 4) >> 8;
  111.                     uint8 blue = (uint16)ReadMacInt16(s_pal + 6) >> 8;
  112.                     if (VidLocal.luminance_mapping)
  113.                         red = green = blue = (red * 0x4ccc + green * 0x970a + blue * 0x1c29) >> 16;
  114.                     *d_pal++ = red;
  115.                     *d_pal++ = green;
  116.                     *d_pal++ = blue;
  117.                     s_pal += 8;
  118.                 }
  119.             } else {                                        // Sequential
  120.                 d_pal = VidLocal.palette + ReadMacInt16(param + csStart) * 3;
  121.                 for (uint32 i=0; i<=count; i++) {
  122.                     uint8 red = (uint16)ReadMacInt16(s_pal + 2) >> 8;
  123.                     uint8 green = (uint16)ReadMacInt16(s_pal + 4) >> 8;
  124.                     uint8 blue = (uint16)ReadMacInt16(s_pal + 6) >> 8;
  125.                     if (VidLocal.luminance_mapping)
  126.                         red = green = blue = (red * 0x4ccc + green * 0x970a + blue * 0x1c29) >> 16;
  127.                     *d_pal++ = red;
  128.                     *d_pal++ = green;
  129.                     *d_pal++ = blue;
  130.                     s_pal += 8;
  131.                 }
  132.             }
  133.             video_set_palette(VidLocal.palette);
  134.             return noErr;
  135.         }
  136.  
  137.         case cscSetGamma:        // Set gamma table
  138.             D(bug(" SetGamma\n"));
  139.             return noErr;
  140.  
  141.         case cscGrayPage: {        // Fill page with dithered gray pattern
  142.             D(bug(" GrayPage %d\n", ReadMacInt16(param + csPage)));
  143.             if (ReadMacInt16(param + csPage))
  144.                 return paramErr;
  145.  
  146.             uint32 pattern[6] = {
  147.                 0xaaaaaaaa,        // 1 bpp
  148.                 0xcccccccc,        // 2 bpp
  149.                 0xf0f0f0f0,        // 4 bpp
  150.                 0xff00ff00,        // 8 bpp
  151.                 0xffff0000,        // 16 bpp
  152.                 0xffffffff        // 32 bpp
  153.             };
  154.             uint32 p = VidLocal.desc->mac_frame_base;
  155.             uint32 pat = pattern[VidLocal.desc->mode];
  156.             for (uint32 y=0; y<VidLocal.desc->y; y++) {
  157.                 uint32 p2 = p;
  158.                 for (uint32 x=0; x<VidLocal.desc->bytes_per_row / 4; x++) {
  159.                     WriteMacInt32(p2, pat);
  160.                     p2 += 4;
  161.                     if (VidLocal.desc->mode == VMODE_32BIT)
  162.                         pat = ~pat;
  163.                 }
  164.                 p += VidLocal.desc->bytes_per_row;
  165.                 pat = ~pat;
  166.             }
  167.             return noErr;
  168.         }
  169.  
  170.         case cscSetGray:        // Enable/disable luminance mapping
  171.             D(bug(" SetGray %02x\n", ReadMacInt8(param + csMode)));
  172.             VidLocal.luminance_mapping = ReadMacInt8(param + csMode);
  173.             return noErr;
  174.  
  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.  
  180.         case cscSetInterrupt:    // Enable/disable VBL
  181.             D(bug(" SetInterrupt %02x\n", ReadMacInt8(param + csMode)));
  182.             VidLocal.interrupts_enabled = (ReadMacInt8(param + csMode) == 0);
  183.             return noErr;
  184.  
  185.         default:
  186.             printf("WARNING: Unknown VideoDriverControl(%d)\n", code);
  187.             return controlErr;
  188.     }
  189. }
  190.  
  191.  
  192. /*
  193.  *  Driver Status() routine
  194.  */
  195.  
  196. int16 VideoDriverStatus(uint32 pb, uint32 dce)
  197. {
  198.     uint16 code = ReadMacInt16(pb + csCode);
  199.     uint32 param = ReadMacInt32(pb + csParam);
  200.     D(bug("VideoDriverStatus %d\n", code));
  201.     switch (code) {
  202.  
  203.         case cscGetPageCnt:            // Get number of pages
  204.             D(bug(" GetPageCnt\n"));
  205.             WriteMacInt16(param + csPage, 1);
  206.             return noErr;
  207.  
  208.         case cscGetPageBase:        // Get page base address
  209.             D(bug(" GetPageBase\n"));
  210.             WriteMacInt32(param + csBaseAddr, VidLocal.desc->mac_frame_base);
  211.             return noErr;
  212.  
  213.         case cscGetGray:            // Get luminance mapping flag
  214.             D(bug(" GetGray\n"));
  215.             WriteMacInt8(param + csMode, VidLocal.luminance_mapping ? 1 : 0);
  216.             return noErr;
  217.  
  218.         case cscGetInterrupt:        // Get interrupt disable flag
  219.             D(bug(" GetInterrupt\n"));
  220.             WriteMacInt8(param + csMode, VidLocal.interrupts_enabled ? 0 : 1);
  221.             return noErr;
  222.  
  223.         case cscGetDefaultMode:        // Get default video mode
  224.             D(bug(" GetDefaultMode\n"));
  225.             WriteMacInt8(param + csMode, 0x80);
  226.             return noErr;
  227.  
  228.         case cscGetCurMode:            // Get current video mode
  229.             D(bug(" GetCurMode\n"));
  230.             WriteMacInt16(param + csMode, 0x80);
  231.             WriteMacInt32(param + csData, 0x80);
  232.             WriteMacInt16(param + csPage, 0);
  233.             WriteMacInt32(param + csBaseAddr, VidLocal.desc->mac_frame_base);
  234.             return noErr;
  235.  
  236.         case cscGetConnection:        // Get monitor information
  237.             D(bug(" GetConnection\n"));
  238.             WriteMacInt16(param + csDisplayType, 6);        // 21" Multiscan
  239.             WriteMacInt8(param + csConnectTaggedType, 6);
  240.             WriteMacInt8(param + csConnectTaggedData, 0x23);
  241.             WriteMacInt32(param + csConnectFlags, 0x03);    // All modes valid and safe
  242.             WriteMacInt32(param + csDisplayComponent, 0);
  243.             return noErr;
  244.  
  245.         case cscGetModeTiming:        // Get video timing for mode
  246.             D(bug(" GetModeTiming mode %08lx\n", ReadMacInt32(param + csTimingMode)));
  247.             WriteMacInt32(param + csTimingFormat, 'decl');
  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.  
  252.         case cscGetModeBaseAddress:    // Get frame buffer base address
  253.             D(bug(" GetModeBaseAddress\n"));
  254.             WriteMacInt32(param + csBaseAddr, VidLocal.desc->mac_frame_base);
  255.             return noErr;
  256.  
  257.         default:
  258.             printf("WARNING: Unknown VideoDriverStatus(%d)\n", code);
  259.             return statusErr;
  260.     }
  261. }
  262.