home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 25 / AACD 25.iso / AACD / Utilities / BasiliskII / src / video.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-05-31  |  8.2 KB  |  268 lines

  1. /*
  2.  *  video.cpp - Video/graphics emulation
  3.  *
  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
  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.                 for (uint32 x=0; x<VidLocal.desc->bytes_per_row; x+=4) {
  158.                     WriteMacInt32(p + x, pat);
  159.                     if (VidLocal.desc->mode == VMODE_32BIT)
  160.                         pat = ~pat;
  161.                 }
  162.                 p += VidLocal.desc->bytes_per_row;
  163.                 pat = ~pat;
  164.             }
  165.             return noErr;
  166.         }
  167.  
  168.         case cscSetGray:        // Enable/disable luminance mapping
  169.             D(bug(" SetGray %02x\n", ReadMacInt8(param + csMode)));
  170.             VidLocal.luminance_mapping = ReadMacInt8(param + csMode);
  171.             return noErr;
  172.  
  173.         case cscSwitchMode:        // Switch video mode
  174.             D(bug(" SwitchMode %04x, %08lx\n", ReadMacInt16(param + csMode), ReadMacInt32(param + csData)));
  175.             WriteMacInt32(param + csBaseAddr, VidLocal.desc->mac_frame_base);
  176.             return noErr;
  177.  
  178.         case cscSetInterrupt:    // Enable/disable VBL
  179.             D(bug(" SetInterrupt %02x\n", ReadMacInt8(param + csMode)));
  180.             VidLocal.interrupts_enabled = (ReadMacInt8(param + csMode) == 0);
  181.             return noErr;
  182.  
  183.         default:
  184.             printf("WARNING: Unknown VideoDriverControl(%d)\n", code);
  185.             return controlErr;
  186.     }
  187. }
  188.  
  189.  
  190. /*
  191.  *  Driver Status() routine
  192.  */
  193.  
  194. int16 VideoDriverStatus(uint32 pb, uint32 dce)
  195. {
  196.     uint16 code = ReadMacInt16(pb + csCode);
  197.     uint32 param = ReadMacInt32(pb + csParam);
  198.     D(bug("VideoDriverStatus %d\n", code));
  199.     switch (code) {
  200.  
  201.         case cscGetPageCnt:            // Get number of pages
  202.             D(bug(" GetPageCnt\n"));
  203.             WriteMacInt16(param + csPage, 1);
  204.             return noErr;
  205.  
  206.         case cscGetPageBase:        // Get page base address
  207.             D(bug(" GetPageBase\n"));
  208.             WriteMacInt32(param + csBaseAddr, VidLocal.desc->mac_frame_base);
  209.             return noErr;
  210.  
  211.         case cscGetGray:            // Get luminance mapping flag
  212.             D(bug(" GetGray\n"));
  213.             WriteMacInt8(param + csMode, VidLocal.luminance_mapping ? 1 : 0);
  214.             return noErr;
  215.  
  216.         case cscGetInterrupt:        // Get interrupt disable flag
  217.             D(bug(" GetInterrupt\n"));
  218.             WriteMacInt8(param + csMode, VidLocal.interrupts_enabled ? 0 : 1);
  219.             return noErr;
  220.  
  221.         case cscGetDefaultMode:        // Get default video mode
  222.             D(bug(" GetDefaultMode\n"));
  223.             WriteMacInt8(param + csMode, 0x80);
  224.             return noErr;
  225.  
  226.         case cscGetCurMode:            // Get current video mode
  227.             D(bug(" GetCurMode\n"));
  228.             WriteMacInt16(param + csMode, 0x80);
  229.             WriteMacInt32(param + csData, 0x80);
  230.             WriteMacInt16(param + csPage, 0);
  231.             WriteMacInt32(param + csBaseAddr, VidLocal.desc->mac_frame_base);
  232.             return noErr;
  233.  
  234.         case cscGetConnection:        // Get monitor information
  235.             D(bug(" GetConnection\n"));
  236.             WriteMacInt16(param + csDisplayType, 6);        // 21" Multiscan
  237.             WriteMacInt8(param + csConnectTaggedType, 6);
  238.             WriteMacInt8(param + csConnectTaggedData, 0x23);
  239.             WriteMacInt32(param + csConnectFlags, 0x03);    // All modes valid and safe
  240.             WriteMacInt32(param + csDisplayComponent, 0);
  241.             return noErr;
  242.  
  243.         case cscGetModeTiming:        // Get video timing for mode
  244.             D(bug(" GetModeTiming mode %08lx\n", ReadMacInt32(param + csTimingMode)));
  245.             WriteMacInt32(param + csTimingFormat, FOURCC('d', 'e', 'c', 'l'));
  246.             WriteMacInt32(param + csTimingData, 220);        // 21" Multiscan
  247.             WriteMacInt32(param + csTimingFlags, 0x0f);        // Mode valid, safe, default and shown in Monitors panel
  248.             return noErr;
  249.  
  250.         case cscGetModeBaseAddress:    // Get frame buffer base address
  251.             D(bug(" GetModeBaseAddress\n"));
  252.             WriteMacInt32(param + csBaseAddr, VidLocal.desc->mac_frame_base);    // Base address of video RAM for the current DisplayModeID and relative bit depth
  253.             return noErr;
  254.  
  255.         case cscGetMode:        // REQUIRED for MacsBug
  256.             D(bug(" GetMode\n"));
  257.             WriteMacInt16(param + csPageMode, 0x80);
  258.             WriteMacInt32(param + csPageData, 0x80);    // Unused
  259.             WriteMacInt16(param + csPagePage, 0);    // Current display page
  260.             WriteMacInt32(param + csPageBaseAddr, VidLocal.desc->mac_frame_base);
  261.             return noErr;
  262.  
  263.         default:
  264.             printf("WARNING: Unknown VideoDriverStatus(%d)\n", code);
  265.             return statusErr;
  266.     }
  267. }
  268.