mirror of
https://github.com/kanjitalk755/macemu.git
synced 2025-03-05 03:29:35 +00:00
- added infrastructure for multi-monitor support; only video_x.cpp is
converted for the new scheme; not actually tested with a mult-monitor setup yet but at least single-monitor display doesn't seem to be broken (UAE banked addressing would definitely require some extensions to handle multiple frame buffers) - struct video_mode has an extra field that is free for use by platform- specific code
This commit is contained in:
parent
665c64b4aa
commit
8871da753d
BasiliskII/src
@ -163,8 +163,10 @@ static uint32 page_extend(uint32 size)
|
||||
|
||||
static bool screen_fault_handler(sigsegv_address_t fault_address, sigsegv_address_t fault_instruction);
|
||||
|
||||
static bool video_vosf_init(void)
|
||||
static bool video_vosf_init(X11_monitor_desc &monitor)
|
||||
{
|
||||
const video_mode &mode = monitor.get_current_mode();
|
||||
|
||||
const uintptr page_size = getpagesize();
|
||||
const uintptr page_mask = page_size - 1;
|
||||
|
||||
@ -196,13 +198,13 @@ static bool video_vosf_init(void)
|
||||
|
||||
uint32 a = 0;
|
||||
for (unsigned i = 0; i < mainBuffer.pageCount; i++) {
|
||||
unsigned y1 = a / VideoMonitor.mode.bytes_per_row;
|
||||
if (y1 >= VideoMonitor.mode.y)
|
||||
y1 = VideoMonitor.mode.y - 1;
|
||||
unsigned y1 = a / mode.bytes_per_row;
|
||||
if (y1 >= mode.y)
|
||||
y1 = mode.y - 1;
|
||||
|
||||
unsigned y2 = (a + mainBuffer.pageSize) / VideoMonitor.mode.bytes_per_row;
|
||||
if (y2 >= VideoMonitor.mode.y)
|
||||
y2 = VideoMonitor.mode.y - 1;
|
||||
unsigned y2 = (a + mainBuffer.pageSize) / mode.bytes_per_row;
|
||||
if (y2 >= mode.y)
|
||||
y2 = mode.y - 1;
|
||||
|
||||
mainBuffer.pageInfo[i].top = y1;
|
||||
mainBuffer.pageInfo[i].bottom = y2;
|
||||
@ -330,6 +332,8 @@ There are two cases to check:
|
||||
|
||||
static inline void update_display_window_vosf(driver_window *drv)
|
||||
{
|
||||
const video_mode &mode = drv->monitor.get_current_mode();
|
||||
|
||||
int page = 0;
|
||||
for (;;) {
|
||||
const unsigned first_page = find_next_page_set(page);
|
||||
@ -349,15 +353,15 @@ static inline void update_display_window_vosf(driver_window *drv)
|
||||
const int y2 = mainBuffer.pageInfo[page - 1].bottom;
|
||||
const int height = y2 - y1 + 1;
|
||||
|
||||
if (VideoMonitor.mode.depth < VDEPTH_8BIT) {
|
||||
if (mode.depth < VDEPTH_8BIT) {
|
||||
|
||||
// Update the_host_buffer and copy of the_buffer
|
||||
const int src_bytes_per_row = VideoMonitor.mode.bytes_per_row;
|
||||
const int src_bytes_per_row = mode.bytes_per_row;
|
||||
const int dst_bytes_per_row = drv->img->bytes_per_line;
|
||||
const int pixels_per_byte = VideoMonitor.mode.x / src_bytes_per_row;
|
||||
const int pixels_per_byte = mode.x / src_bytes_per_row;
|
||||
int i1 = y1 * src_bytes_per_row, i2 = y1 * dst_bytes_per_row, j;
|
||||
for (j = y1; j <= y2; j++) {
|
||||
Screen_blit(the_host_buffer + i2, the_buffer + i1, VideoMonitor.mode.x / pixels_per_byte);
|
||||
Screen_blit(the_host_buffer + i2, the_buffer + i1, mode.x / pixels_per_byte);
|
||||
i1 += src_bytes_per_row;
|
||||
i2 += dst_bytes_per_row;
|
||||
}
|
||||
@ -365,21 +369,21 @@ static inline void update_display_window_vosf(driver_window *drv)
|
||||
} else {
|
||||
|
||||
// Update the_host_buffer and copy of the_buffer
|
||||
const int src_bytes_per_row = VideoMonitor.mode.bytes_per_row;
|
||||
const int src_bytes_per_row = mode.bytes_per_row;
|
||||
const int dst_bytes_per_row = drv->img->bytes_per_line;
|
||||
const int bytes_per_pixel = src_bytes_per_row / VideoMonitor.mode.x;
|
||||
const int bytes_per_pixel = src_bytes_per_row / mode.x;
|
||||
int i1 = y1 * src_bytes_per_row, i2 = y1 * dst_bytes_per_row, j;
|
||||
for (j = y1; j <= y2; j++) {
|
||||
Screen_blit(the_host_buffer + i2, the_buffer + i1, bytes_per_pixel * VideoMonitor.mode.x);
|
||||
Screen_blit(the_host_buffer + i2, the_buffer + i1, bytes_per_pixel * mode.x);
|
||||
i1 += src_bytes_per_row;
|
||||
i2 += dst_bytes_per_row;
|
||||
}
|
||||
}
|
||||
|
||||
if (drv->have_shm)
|
||||
XShmPutImage(x_display, drv->w, drv->gc, drv->img, 0, y1, 0, y1, VideoMonitor.mode.x, height, 0);
|
||||
XShmPutImage(x_display, drv->w, drv->gc, drv->img, 0, y1, 0, y1, mode.x, height, 0);
|
||||
else
|
||||
XPutImage(x_display, drv->w, drv->gc, drv->img, 0, y1, 0, y1, VideoMonitor.mode.x, height);
|
||||
XPutImage(x_display, drv->w, drv->gc, drv->img, 0, y1, 0, y1, mode.x, height);
|
||||
}
|
||||
mainBuffer.dirty = false;
|
||||
}
|
||||
@ -393,6 +397,8 @@ static inline void update_display_window_vosf(driver_window *drv)
|
||||
#if REAL_ADDRESSING || DIRECT_ADDRESSING
|
||||
static inline void update_display_dga_vosf(void)
|
||||
{
|
||||
const video_mode &mode = drv->monitor.get_current_mode();
|
||||
|
||||
int page = 0;
|
||||
for (;;) {
|
||||
const unsigned first_page = find_next_page_set(page);
|
||||
@ -411,13 +417,13 @@ static inline void update_display_dga_vosf(void)
|
||||
const int y1 = mainBuffer.pageInfo[first_page].top;
|
||||
const int y2 = mainBuffer.pageInfo[page - 1].bottom;
|
||||
|
||||
const int bytes_per_row = VideoMonitor.mode.bytes_per_row;
|
||||
const int bytes_per_pixel = VideoMonitor.mode.bytes_per_row / VideoMonitor.mode.x;
|
||||
const int bytes_per_row = mode.bytes_per_row;
|
||||
const int bytes_per_pixel = mode.bytes_per_row / mode.x;
|
||||
int i, j;
|
||||
|
||||
// Check for first column from left and first column
|
||||
// from right that have changed
|
||||
int x1 = VideoMonitor.mode.x * bytes_per_pixel - 1;
|
||||
int x1 = mode.x * bytes_per_pixel - 1;
|
||||
for (j = y1; j <= y2; j++) {
|
||||
uint8 * const p1 = &the_buffer[j * bytes_per_row];
|
||||
uint8 * const p2 = &the_buffer_copy[j * bytes_per_row];
|
||||
@ -434,7 +440,7 @@ static inline void update_display_dga_vosf(void)
|
||||
for (j = y2; j >= y1; j--) {
|
||||
uint8 * const p1 = &the_buffer[j * bytes_per_row];
|
||||
uint8 * const p2 = &the_buffer_copy[j * bytes_per_row];
|
||||
for (i = VideoMonitor.mode.x * bytes_per_pixel - 1; i > x2; i--) {
|
||||
for (i = mode.x * bytes_per_pixel - 1; i > x2; i--) {
|
||||
if (p1[i] != p2[i]) {
|
||||
x2 = i;
|
||||
break;
|
||||
|
@ -39,10 +39,6 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#ifndef NO_STD_NAMESPACE
|
||||
using std::sort;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PTHREADS
|
||||
# include <pthread.h>
|
||||
#endif
|
||||
@ -71,6 +67,9 @@ using std::sort;
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
// Supported video modes
|
||||
static vector<video_mode> VideoModes;
|
||||
|
||||
// Display types
|
||||
enum {
|
||||
DISPLAY_WINDOW, // X11 window, using MIT SHM extensions if possible
|
||||
@ -140,8 +139,8 @@ static int rshift, rloss, gshift, gloss, bshift, bloss; // Pixel format of Direc
|
||||
|
||||
static Colormap cmap[2] = {0, 0}; // Colormaps for indexed modes (DGA needs two of them)
|
||||
|
||||
static XColor palette[256]; // Color palette to be used as CLUT and gamma table
|
||||
static bool palette_changed = false; // Flag: Palette changed, redraw thread must set new colors
|
||||
static XColor x_palette[256]; // Color palette to be used as CLUT and gamma table
|
||||
static bool x_palette_changed = false; // Flag: Palette changed, redraw thread must set new colors
|
||||
|
||||
#ifdef ENABLE_FBDEV_DGA
|
||||
static int fbdev_fd = -1;
|
||||
@ -154,9 +153,9 @@ static int num_x_video_modes;
|
||||
|
||||
// Mutex to protect palette
|
||||
#ifdef HAVE_PTHREADS
|
||||
static pthread_mutex_t palette_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
#define LOCK_PALETTE pthread_mutex_lock(&palette_lock)
|
||||
#define UNLOCK_PALETTE pthread_mutex_unlock(&palette_lock)
|
||||
static pthread_mutex_t x_palette_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
#define LOCK_PALETTE pthread_mutex_lock(&x_palette_lock)
|
||||
#define UNLOCK_PALETTE pthread_mutex_unlock(&x_palette_lock)
|
||||
#else
|
||||
#define LOCK_PALETTE
|
||||
#define UNLOCK_PALETTE
|
||||
@ -194,6 +193,23 @@ extern Display *x_display;
|
||||
extern void SysMountFirstFloppy(void);
|
||||
|
||||
|
||||
/*
|
||||
* monitor_desc subclass for X11 display
|
||||
*/
|
||||
|
||||
class X11_monitor_desc : public monitor_desc {
|
||||
public:
|
||||
X11_monitor_desc(const vector<video_mode> &available_modes, video_depth default_depth, uint32 default_id) : monitor_desc(available_modes, default_depth, default_id) {}
|
||||
~X11_monitor_desc() {}
|
||||
|
||||
virtual void switch_to_current_mode(void);
|
||||
virtual void set_palette(uint8 *pal, int num);
|
||||
|
||||
bool video_open(void);
|
||||
void video_close(void);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Utility functions
|
||||
*/
|
||||
@ -332,7 +348,7 @@ static void add_window_modes(video_depth depth)
|
||||
}
|
||||
|
||||
// Set Mac frame layout and base address (uses the_buffer/MacFrameBaseMac)
|
||||
static void set_mac_frame_buffer(video_depth depth, bool native_byte_order)
|
||||
static void set_mac_frame_buffer(X11_monitor_desc &monitor, video_depth depth, bool native_byte_order)
|
||||
{
|
||||
#if !REAL_ADDRESSING && !DIRECT_ADDRESSING
|
||||
int layout = FLAYOUT_DIRECT;
|
||||
@ -344,16 +360,17 @@ static void set_mac_frame_buffer(video_depth depth, bool native_byte_order)
|
||||
MacFrameLayout = layout;
|
||||
else
|
||||
MacFrameLayout = FLAYOUT_DIRECT;
|
||||
VideoMonitor.mac_frame_base = MacFrameBaseMac;
|
||||
monitor.set_mac_frame_base(MacFrameBaseMac);
|
||||
|
||||
// Set variables used by UAE memory banking
|
||||
const video_mode &mode = monitor.get_current_mode();
|
||||
MacFrameBaseHost = the_buffer;
|
||||
MacFrameSize = VideoMonitor.mode.bytes_per_row * VideoMonitor.mode.y;
|
||||
MacFrameSize = mode.bytes_per_row * mode.y;
|
||||
InitFrameBufferMapping();
|
||||
#else
|
||||
VideoMonitor.mac_frame_base = Host2MacAddr(the_buffer);
|
||||
monitor.set_mac_frame_base(Host2MacAddr(the_buffer));
|
||||
#endif
|
||||
D(bug("VideoMonitor.mac_frame_base = %08x\n", VideoMonitor.mac_frame_base));
|
||||
D(bug("monitor.mac_frame_base = %08x\n", monitor.get_mac_frame_base()));
|
||||
}
|
||||
|
||||
// Set window name and class
|
||||
@ -431,7 +448,7 @@ static int error_handler(Display *d, XErrorEvent *e)
|
||||
|
||||
class driver_base {
|
||||
public:
|
||||
driver_base();
|
||||
driver_base(X11_monitor_desc &m);
|
||||
virtual ~driver_base();
|
||||
|
||||
virtual void update_palette(void);
|
||||
@ -447,6 +464,9 @@ public:
|
||||
virtual void ungrab_mouse(void) {}
|
||||
|
||||
public:
|
||||
X11_monitor_desc &monitor; // Associated video monitor
|
||||
const video_mode &mode; // Video mode handled by the driver
|
||||
|
||||
bool init_ok; // Initialization succeeded (we can't use exceptions because of -fomit-frame-pointer)
|
||||
Window w; // The window we draw into
|
||||
|
||||
@ -464,7 +484,7 @@ class driver_window : public driver_base {
|
||||
friend void update_display_static(driver_window *drv);
|
||||
|
||||
public:
|
||||
driver_window(const video_mode &mode);
|
||||
driver_window(X11_monitor_desc &monitor);
|
||||
~driver_window();
|
||||
|
||||
void toggle_mouse_grab(void);
|
||||
@ -489,8 +509,8 @@ static driver_base *drv = NULL; // Pointer to currently used driver object
|
||||
# include "video_vosf.h"
|
||||
#endif
|
||||
|
||||
driver_base::driver_base()
|
||||
: init_ok(false), w(0)
|
||||
driver_base::driver_base(X11_monitor_desc &m)
|
||||
: monitor(m), mode(m.get_current_mode()), init_ok(false), w(0)
|
||||
{
|
||||
the_buffer = NULL;
|
||||
the_buffer_copy = NULL;
|
||||
@ -549,10 +569,10 @@ void driver_base::update_palette(void)
|
||||
{
|
||||
if (color_class == PseudoColor || color_class == DirectColor) {
|
||||
int num = vis->map_entries;
|
||||
if (!IsDirectMode(VideoMonitor.mode) && color_class == DirectColor)
|
||||
if (!IsDirectMode(monitor.get_current_mode()) && color_class == DirectColor)
|
||||
return; // Indexed mode on true color screen, don't set CLUT
|
||||
XStoreColors(x_display, cmap[0], palette, num);
|
||||
XStoreColors(x_display, cmap[1], palette, num);
|
||||
XStoreColors(x_display, cmap[0], x_palette, num);
|
||||
XStoreColors(x_display, cmap[1], x_palette, num);
|
||||
}
|
||||
XSync(x_display, false);
|
||||
}
|
||||
@ -575,8 +595,8 @@ void driver_base::restore_mouse_accel(void)
|
||||
*/
|
||||
|
||||
// Open display
|
||||
driver_window::driver_window(const video_mode &mode)
|
||||
: gc(0), img(NULL), have_shm(false), mac_cursor(0), mouse_grabbed(false)
|
||||
driver_window::driver_window(X11_monitor_desc &m)
|
||||
: driver_base(m), gc(0), img(NULL), have_shm(false), mac_cursor(0), mouse_grabbed(false)
|
||||
{
|
||||
int width = mode.x, height = mode.y;
|
||||
int aligned_width = (width + 15) & ~15;
|
||||
@ -708,9 +728,8 @@ driver_window::driver_window(const video_mode &mode)
|
||||
Screen_blitter_init(&visualInfo, native_byte_order, mode.depth);
|
||||
#endif
|
||||
|
||||
// Set VideoMonitor
|
||||
VideoMonitor.mode = mode;
|
||||
set_mac_frame_buffer(mode.depth, native_byte_order);
|
||||
// Set frame buffer base
|
||||
set_mac_frame_buffer(monitor, mode.depth, native_byte_order);
|
||||
|
||||
// Everything went well
|
||||
init_ok = true;
|
||||
@ -790,7 +809,7 @@ void driver_window::mouse_moved(int x, int y)
|
||||
// Warped mouse motion (this code is taken from SDL)
|
||||
|
||||
// Post first mouse event
|
||||
int width = VideoMonitor.mode.x, height = VideoMonitor.mode.y;
|
||||
int width = monitor.get_current_mode().x, height = monitor.get_current_mode().y;
|
||||
int delta_x = x - mouse_last_x, delta_y = y - mouse_last_y;
|
||||
mouse_last_x = x; mouse_last_y = y;
|
||||
ADBMouseMoved(delta_x, delta_y);
|
||||
@ -827,7 +846,7 @@ void driver_window::mouse_moved(int x, int y)
|
||||
|
||||
class driver_dga : public driver_base {
|
||||
public:
|
||||
driver_dga();
|
||||
driver_dga(X11_monitor_desc &monitor);
|
||||
~driver_dga();
|
||||
|
||||
void suspend(void);
|
||||
@ -838,8 +857,8 @@ private:
|
||||
void *fb_save; // Saved frame buffer for suspend/resume
|
||||
};
|
||||
|
||||
driver_dga::driver_dga()
|
||||
: suspend_win(0), fb_save(NULL)
|
||||
driver_dga::driver_dga(X11_monitor_desc &m)
|
||||
: driver_base(m), suspend_win(0), fb_save(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
@ -860,9 +879,9 @@ void driver_dga::suspend(void)
|
||||
LOCK_FRAME_BUFFER;
|
||||
|
||||
// Save frame buffer
|
||||
fb_save = malloc(VideoMonitor.mode.y * VideoMonitor.mode.bytes_per_row);
|
||||
fb_save = malloc(mode.y * mode.bytes_per_row);
|
||||
if (fb_save)
|
||||
memcpy(fb_save, the_buffer, VideoMonitor.mode.y * VideoMonitor.mode.bytes_per_row);
|
||||
memcpy(fb_save, the_buffer, mode.y * mode.bytes_per_row);
|
||||
|
||||
// Close full screen display
|
||||
#ifdef ENABLE_XF86_DGA
|
||||
@ -915,7 +934,7 @@ void driver_dga::resume(void)
|
||||
LOCK_VOSF;
|
||||
PFLAG_SET_ALL;
|
||||
UNLOCK_VOSF;
|
||||
memset(the_buffer_copy, 0, VideoMonitor.mode.bytes_per_row * VideoMonitor.mode.y);
|
||||
memset(the_buffer_copy, 0, mode.bytes_per_row * mode.y);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -925,7 +944,7 @@ void driver_dga::resume(void)
|
||||
// Don't copy fb_save to the temporary frame buffer in VOSF mode
|
||||
if (!use_vosf)
|
||||
#endif
|
||||
memcpy(the_buffer, fb_save, VideoMonitor.mode.y * VideoMonitor.mode.bytes_per_row);
|
||||
memcpy(the_buffer, fb_save, mode.y * mode.bytes_per_row);
|
||||
free(fb_save);
|
||||
fb_save = NULL;
|
||||
}
|
||||
@ -947,12 +966,12 @@ const char FBDEVICE_FILE_NAME[] = "/dev/fb";
|
||||
|
||||
class driver_fbdev : public driver_dga {
|
||||
public:
|
||||
driver_fbdev(const video_mode &mode);
|
||||
driver_fbdev(X11_monitor_desc &monitor);
|
||||
~driver_fbdev();
|
||||
};
|
||||
|
||||
// Open display
|
||||
driver_fbdev::driver_fbdev(const video_mode &mode)
|
||||
driver_fbdev::driver_fbdev(X11_monitor_desc &m) : driver_dga(m)
|
||||
{
|
||||
int width = mode.x, height = mode.y;
|
||||
|
||||
@ -1081,10 +1100,9 @@ driver_fbdev::driver_fbdev(const video_mode &mode)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Set VideoMonitor
|
||||
VideoModes[0].bytes_per_row = bytes_per_row;
|
||||
VideoModes[0].depth = DepthModeForPixelDepth(fb_depth);
|
||||
VideoMonitor.mode = mode;
|
||||
// Set frame buffer base
|
||||
const_cast<video_mode *>(&mode)->bytes_per_row = bytes_per_row;
|
||||
const_cast<video_mode *>(&mode)->depth = DepthModeForPixelDepth(fb_depth);
|
||||
set_mac_frame_buffer(mode.depth, true);
|
||||
|
||||
// Everything went well
|
||||
@ -1121,7 +1139,7 @@ driver_fbdev::~driver_fbdev()
|
||||
|
||||
class driver_xf86dga : public driver_dga {
|
||||
public:
|
||||
driver_xf86dga(const video_mode &mode);
|
||||
driver_xf86dga(X11_monitor_desc &monitor);
|
||||
~driver_xf86dga();
|
||||
|
||||
void update_palette(void);
|
||||
@ -1132,8 +1150,8 @@ private:
|
||||
};
|
||||
|
||||
// Open display
|
||||
driver_xf86dga::driver_xf86dga(const video_mode &mode)
|
||||
: current_dga_cmap(0)
|
||||
driver_xf86dga::driver_xf86dga(X11_monitor_desc &m)
|
||||
: driver_dga(m), current_dga_cmap(0)
|
||||
{
|
||||
int width = mode.x, height = mode.y;
|
||||
|
||||
@ -1214,10 +1232,9 @@ driver_xf86dga::driver_xf86dga(const video_mode &mode)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Set VideoMonitor
|
||||
// Set frame buffer base
|
||||
const_cast<video_mode *>(&mode)->bytes_per_row = bytes_per_row;
|
||||
VideoMonitor.mode = mode;
|
||||
set_mac_frame_buffer(mode.depth, true);
|
||||
set_mac_frame_buffer(monitor, mode.depth, true);
|
||||
|
||||
// Everything went well
|
||||
init_ok = true;
|
||||
@ -1248,7 +1265,7 @@ void driver_xf86dga::update_palette(void)
|
||||
{
|
||||
driver_dga::update_palette();
|
||||
current_dga_cmap ^= 1;
|
||||
if (!IsDirectMode(VideoMonitor.mode) && cmap[current_dga_cmap])
|
||||
if (!IsDirectMode(monitor.get_current_mode()) && cmap[current_dga_cmap])
|
||||
XF86DGAInstallColormap(x_display, screen, cmap[current_dga_cmap]);
|
||||
}
|
||||
|
||||
@ -1256,7 +1273,7 @@ void driver_xf86dga::update_palette(void)
|
||||
void driver_xf86dga::resume(void)
|
||||
{
|
||||
driver_dga::resume();
|
||||
if (!IsDirectMode(VideoMonitor.mode))
|
||||
if (!IsDirectMode(monitor.get_current_mode()))
|
||||
XF86DGAInstallColormap(x_display, screen, cmap[current_dga_cmap]);
|
||||
}
|
||||
#endif
|
||||
@ -1331,10 +1348,11 @@ static void keycode_init(void)
|
||||
}
|
||||
}
|
||||
|
||||
// Open display for specified mode
|
||||
static bool video_open(const video_mode &mode)
|
||||
// Open display for current mode
|
||||
bool X11_monitor_desc::video_open(void)
|
||||
{
|
||||
D(bug("video_open()\n"));
|
||||
const video_mode &mode = get_current_mode();
|
||||
|
||||
// Find best available X visual
|
||||
if (!find_visual_for_depth(mode.depth)) {
|
||||
@ -1375,13 +1393,13 @@ static bool video_open(const video_mode &mode)
|
||||
int num = vis->map_entries;
|
||||
for (int i=0; i<num; i++) {
|
||||
int c = (i * 256) / num;
|
||||
palette[i].pixel = map_rgb(c, c, c);
|
||||
palette[i].flags = DoRed | DoGreen | DoBlue;
|
||||
x_palette[i].pixel = map_rgb(c, c, c);
|
||||
x_palette[i].flags = DoRed | DoGreen | DoBlue;
|
||||
}
|
||||
} else if (color_class == PseudoColor) {
|
||||
for (int i=0; i<256; i++) {
|
||||
palette[i].pixel = i;
|
||||
palette[i].flags = DoRed | DoGreen | DoBlue;
|
||||
x_palette[i].pixel = i;
|
||||
x_palette[i].flags = DoRed | DoGreen | DoBlue;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1389,13 +1407,13 @@ static bool video_open(const video_mode &mode)
|
||||
int num = (color_class == DirectColor ? vis->map_entries : 256);
|
||||
for (int i=0; i<num; i++) {
|
||||
int c = (i * 256) / num;
|
||||
palette[i].red = c * 0x0101;
|
||||
palette[i].green = c * 0x0101;
|
||||
palette[i].blue = c * 0x0101;
|
||||
x_palette[i].red = c * 0x0101;
|
||||
x_palette[i].green = c * 0x0101;
|
||||
x_palette[i].blue = c * 0x0101;
|
||||
}
|
||||
if (color_class == PseudoColor || color_class == DirectColor) {
|
||||
XStoreColors(x_display, cmap[0], palette, num);
|
||||
XStoreColors(x_display, cmap[1], palette, num);
|
||||
XStoreColors(x_display, cmap[0], x_palette, num);
|
||||
XStoreColors(x_display, cmap[1], x_palette, num);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_VOSF
|
||||
@ -1408,16 +1426,16 @@ static bool video_open(const video_mode &mode)
|
||||
// Create display driver object of requested type
|
||||
switch (display_type) {
|
||||
case DISPLAY_WINDOW:
|
||||
drv = new driver_window(mode);
|
||||
drv = new driver_window(*this);
|
||||
break;
|
||||
#ifdef ENABLE_FBDEV_DGA
|
||||
case DISPLAY_DGA:
|
||||
drv = new driver_fbdev(mode);
|
||||
drv = new driver_fbdev(*this);
|
||||
break;
|
||||
#endif
|
||||
#ifdef ENABLE_XF86_DGA
|
||||
case DISPLAY_DGA:
|
||||
drv = new driver_xf86dga(mode);
|
||||
drv = new driver_xf86dga(*this);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
@ -1432,7 +1450,7 @@ static bool video_open(const video_mode &mode)
|
||||
#ifdef ENABLE_VOSF
|
||||
if (use_vosf) {
|
||||
// Initialize the VOSF system
|
||||
if (!video_vosf_init()) {
|
||||
if (!video_vosf_init(*this)) {
|
||||
ErrorAlert(STR_VOSF_INIT_ERR);
|
||||
return false;
|
||||
}
|
||||
@ -1494,7 +1512,7 @@ bool VideoInit(bool classic)
|
||||
ErrorAlert(STR_UNSUPP_DEPTH_ERR);
|
||||
return false;
|
||||
}
|
||||
sort(avail_depths, avail_depths + num_depths);
|
||||
std::sort(avail_depths, avail_depths + num_depths);
|
||||
|
||||
#ifdef ENABLE_FBDEV_DGA
|
||||
// Frame buffer name
|
||||
@ -1597,34 +1615,39 @@ bool VideoInit(bool classic)
|
||||
ErrorAlert(STR_NO_XVISUAL_ERR);
|
||||
return false;
|
||||
}
|
||||
video_init_depth_list();
|
||||
|
||||
// Find requested default mode with specified dimensions
|
||||
uint32 default_id;
|
||||
std::vector<video_mode>::const_iterator i, end = VideoModes.end();
|
||||
for (i = VideoModes.begin(); i != end; ++i) {
|
||||
if (i->x == default_width && i->y == default_height && i->depth == default_depth) {
|
||||
default_id = i->resolution_id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == end) { // not found, use first available mode
|
||||
default_depth = VideoModes[0].depth;
|
||||
default_id = VideoModes[0].resolution_id;
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
D(bug("Available video modes:\n"));
|
||||
vector<video_mode>::const_iterator i = VideoModes.begin(), end = VideoModes.end();
|
||||
while (i != end) {
|
||||
for (i = VideoModes.begin(); i != end; ++i) {
|
||||
int bits = 1 << i->depth;
|
||||
if (bits == 16)
|
||||
bits = 15;
|
||||
else if (bits == 32)
|
||||
bits = 24;
|
||||
D(bug(" %dx%d (ID %02x), %d colors\n", i->x, i->y, i->resolution_id, 1 << bits));
|
||||
++i;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Find requested default mode and open display
|
||||
if (VideoModes.size() == 1)
|
||||
return video_open(VideoModes[0]);
|
||||
else {
|
||||
// Find mode with specified dimensions
|
||||
std::vector<video_mode>::const_iterator i, end = VideoModes.end();
|
||||
for (i = VideoModes.begin(); i != end; ++i) {
|
||||
if (i->x == default_width && i->y == default_height && i->depth == default_depth)
|
||||
return video_open(*i);
|
||||
}
|
||||
return video_open(VideoModes[0]);
|
||||
}
|
||||
// Create X11_monitor_desc for this (the only) display
|
||||
X11_monitor_desc *monitor = new X11_monitor_desc(VideoModes, default_depth, default_id);
|
||||
VideoMonitors.push_back(monitor);
|
||||
|
||||
// Open display
|
||||
return monitor->video_open();
|
||||
}
|
||||
|
||||
|
||||
@ -1633,7 +1656,7 @@ bool VideoInit(bool classic)
|
||||
*/
|
||||
|
||||
// Close display
|
||||
static void video_close(void)
|
||||
void X11_monitor_desc::video_close(void)
|
||||
{
|
||||
D(bug("video_close()\n"));
|
||||
|
||||
@ -1678,8 +1701,10 @@ static void video_close(void)
|
||||
|
||||
void VideoExit(void)
|
||||
{
|
||||
// Close display
|
||||
video_close();
|
||||
// Close displays
|
||||
vector<monitor_desc *>::iterator i, end = VideoMonitors.end();
|
||||
for (i = VideoMonitors.begin(); i != end; ++i)
|
||||
dynamic_cast<X11_monitor_desc *>(*i)->video_close();
|
||||
|
||||
#ifdef ENABLE_XF86_VIDMODE
|
||||
// Free video mode list
|
||||
@ -1737,19 +1762,21 @@ void VideoInterrupt(void)
|
||||
* Set palette
|
||||
*/
|
||||
|
||||
void video_set_palette(uint8 *pal, int num_in)
|
||||
void X11_monitor_desc::set_palette(uint8 *pal, int num_in)
|
||||
{
|
||||
const video_mode &mode = get_current_mode();
|
||||
|
||||
LOCK_PALETTE;
|
||||
|
||||
// Convert colors to XColor array
|
||||
int num_out = 256;
|
||||
bool stretch = false;
|
||||
if (IsDirectMode(VideoMonitor.mode)) {
|
||||
if (IsDirectMode(mode)) {
|
||||
// If X is in 565 mode we have to stretch the gamma table from 32 to 64 entries
|
||||
num_out = vis->map_entries;
|
||||
stretch = true;
|
||||
}
|
||||
XColor *p = palette;
|
||||
XColor *p = x_palette;
|
||||
for (int i=0; i<num_out; i++) {
|
||||
int c = (stretch ? (i * num_in) / num_out : i);
|
||||
p->red = pal[c*3 + 0] * 0x0101;
|
||||
@ -1760,7 +1787,7 @@ void video_set_palette(uint8 *pal, int num_in)
|
||||
|
||||
#ifdef ENABLE_VOSF
|
||||
// Recalculate pixel color expansion map
|
||||
if (!IsDirectMode(VideoMonitor.mode) && xdepth > 8) {
|
||||
if (!IsDirectMode(mode) && xdepth > 8) {
|
||||
for (int i=0; i<256; i++) {
|
||||
int c = i & (num_in-1); // If there are less than 256 colors, we repeat the first entries (this makes color expansion easier)
|
||||
ExpandMap[i] = map_rgb(pal[c*3+0], pal[c*3+1], pal[c*3+2]);
|
||||
@ -1770,12 +1797,12 @@ void video_set_palette(uint8 *pal, int num_in)
|
||||
LOCK_VOSF;
|
||||
PFLAG_SET_ALL;
|
||||
UNLOCK_VOSF;
|
||||
memset(the_buffer_copy, 0, VideoMonitor.mode.bytes_per_row * VideoMonitor.mode.y);
|
||||
memset(the_buffer_copy, 0, mode.bytes_per_row * mode.y);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Tell redraw thread to change palette
|
||||
palette_changed = true;
|
||||
x_palette_changed = true;
|
||||
|
||||
UNLOCK_PALETTE;
|
||||
}
|
||||
@ -1785,11 +1812,11 @@ void video_set_palette(uint8 *pal, int num_in)
|
||||
* Switch video mode
|
||||
*/
|
||||
|
||||
void video_switch_to_mode(const video_mode &mode)
|
||||
void X11_monitor_desc::switch_to_current_mode(void)
|
||||
{
|
||||
// Close and reopen display
|
||||
video_close();
|
||||
video_open(mode);
|
||||
video_open();
|
||||
|
||||
if (drv == NULL) {
|
||||
ErrorAlert(STR_OPEN_WINDOW_ERR);
|
||||
@ -2059,12 +2086,13 @@ static void handle_events(void)
|
||||
// Hidden parts exposed, force complete refresh of window
|
||||
case Expose:
|
||||
if (display_type == DISPLAY_WINDOW) {
|
||||
const video_mode &mode = VideoMonitors[0]->get_current_mode();
|
||||
#ifdef ENABLE_VOSF
|
||||
if (use_vosf) { // VOSF refresh
|
||||
LOCK_VOSF;
|
||||
PFLAG_SET_ALL;
|
||||
UNLOCK_VOSF;
|
||||
memset(the_buffer_copy, 0, VideoMonitor.mode.bytes_per_row * VideoMonitor.mode.y);
|
||||
memset(the_buffer_copy, 0, mode.bytes_per_row * mode.y);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
@ -2075,7 +2103,7 @@ static void handle_events(void)
|
||||
updt_box[x1][y1] = true;
|
||||
nr_boxes = 16 * 16;
|
||||
} else // Static refresh
|
||||
memset(the_buffer_copy, 0, VideoMonitor.mode.bytes_per_row * VideoMonitor.mode.y);
|
||||
memset(the_buffer_copy, 0, mode.bytes_per_row * mode.y);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -2101,10 +2129,11 @@ static void update_display_dynamic(int ticker, driver_window *drv)
|
||||
int y1, y2, y2s, y2a, i, x1, xm, xmo, ymo, yo, yi, yil, xi;
|
||||
int xil = 0;
|
||||
int rxm = 0, rxmo = 0;
|
||||
int bytes_per_row = VideoMonitor.mode.bytes_per_row;
|
||||
int bytes_per_pixel = VideoMonitor.mode.bytes_per_row / VideoMonitor.mode.x;
|
||||
int rx = VideoMonitor.mode.bytes_per_row / 16;
|
||||
int ry = VideoMonitor.mode.y / 16;
|
||||
const video_mode &mode = drv->monitor.get_current_mode();
|
||||
int bytes_per_row = mode.bytes_per_row;
|
||||
int bytes_per_pixel = mode.bytes_per_row / mode.x;
|
||||
int rx = mode.bytes_per_row / 16;
|
||||
int ry = mode.y / 16;
|
||||
int max_box;
|
||||
|
||||
y2s = sm_uptd[ticker % 8];
|
||||
@ -2158,7 +2187,7 @@ static void update_display_dynamic(int ticker, driver_window *drv)
|
||||
i = (yi * bytes_per_row) + xi;
|
||||
for (y2=0; y2 < yil; y2++, i += bytes_per_row)
|
||||
memcpy(&the_buffer_copy[i], &the_buffer[i], xil);
|
||||
if (VideoMonitor.mode.depth == VDEPTH_1BIT) {
|
||||
if (mode.depth == VDEPTH_1BIT) {
|
||||
if (drv->have_shm)
|
||||
XShmPutImage(x_display, drv->w, drv->gc, drv->img, xi * 8, yi, xi * 8, yi, xil * 8, yil, 0);
|
||||
else
|
||||
@ -2190,20 +2219,21 @@ static void update_display_static(driver_window *drv)
|
||||
{
|
||||
// Incremental update code
|
||||
unsigned wide = 0, high = 0, x1, x2, y1, y2, i, j;
|
||||
int bytes_per_row = VideoMonitor.mode.bytes_per_row;
|
||||
int bytes_per_pixel = VideoMonitor.mode.bytes_per_row / VideoMonitor.mode.x;
|
||||
const video_mode &mode = drv->monitor.get_current_mode();
|
||||
int bytes_per_row = mode.bytes_per_row;
|
||||
int bytes_per_pixel = mode.bytes_per_row / mode.x;
|
||||
uint8 *p, *p2;
|
||||
|
||||
// Check for first line from top and first line from bottom that have changed
|
||||
y1 = 0;
|
||||
for (j=0; j<VideoMonitor.mode.y; j++) {
|
||||
for (j=0; j<mode.y; j++) {
|
||||
if (memcmp(&the_buffer[j * bytes_per_row], &the_buffer_copy[j * bytes_per_row], bytes_per_row)) {
|
||||
y1 = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
y2 = y1 - 1;
|
||||
for (j=VideoMonitor.mode.y-1; j>=y1; j--) {
|
||||
for (j=mode.y-1; j>=y1; j--) {
|
||||
if (memcmp(&the_buffer[j * bytes_per_row], &the_buffer_copy[j * bytes_per_row], bytes_per_row)) {
|
||||
y2 = j;
|
||||
break;
|
||||
@ -2213,8 +2243,8 @@ static void update_display_static(driver_window *drv)
|
||||
|
||||
// Check for first column from left and first column from right that have changed
|
||||
if (high) {
|
||||
if (VideoMonitor.mode.depth == VDEPTH_1BIT) {
|
||||
x1 = VideoMonitor.mode.x - 1;
|
||||
if (mode.depth == VDEPTH_1BIT) {
|
||||
x1 = mode.x - 1;
|
||||
for (j=y1; j<=y2; j++) {
|
||||
p = &the_buffer[j * bytes_per_row];
|
||||
p2 = &the_buffer_copy[j * bytes_per_row];
|
||||
@ -2232,7 +2262,7 @@ static void update_display_static(driver_window *drv)
|
||||
p2 = &the_buffer_copy[j * bytes_per_row];
|
||||
p += bytes_per_row;
|
||||
p2 += bytes_per_row;
|
||||
for (i=(VideoMonitor.mode.x>>3); i>(x2>>3); i--) {
|
||||
for (i=(mode.x>>3); i>(x2>>3); i--) {
|
||||
p--; p2--;
|
||||
if (*p != *p2) {
|
||||
x2 = (i << 3) + 7;
|
||||
@ -2251,7 +2281,7 @@ static void update_display_static(driver_window *drv)
|
||||
}
|
||||
|
||||
} else {
|
||||
x1 = VideoMonitor.mode.x;
|
||||
x1 = mode.x;
|
||||
for (j=y1; j<=y2; j++) {
|
||||
p = &the_buffer[j * bytes_per_row];
|
||||
p2 = &the_buffer_copy[j * bytes_per_row];
|
||||
@ -2269,7 +2299,7 @@ static void update_display_static(driver_window *drv)
|
||||
p2 = &the_buffer_copy[j * bytes_per_row];
|
||||
p += bytes_per_row;
|
||||
p2 += bytes_per_row;
|
||||
for (i=VideoMonitor.mode.x*bytes_per_pixel; i>x2*bytes_per_pixel; i--) {
|
||||
for (i=mode.x*bytes_per_pixel; i>x2*bytes_per_pixel; i--) {
|
||||
p--;
|
||||
p2--;
|
||||
if (*p != *p2) {
|
||||
@ -2336,8 +2366,8 @@ static inline void handle_palette_changes(void)
|
||||
{
|
||||
LOCK_PALETTE;
|
||||
|
||||
if (palette_changed) {
|
||||
palette_changed = false;
|
||||
if (x_palette_changed) {
|
||||
x_palette_changed = false;
|
||||
drv->update_palette();
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
||||
using std::vector;
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
Some of the terminology here is completely frelled. In Basilisk II, a
|
||||
"video mode" refers to a combination of resolution and color depth, and
|
||||
@ -55,19 +56,7 @@ enum video_depth {
|
||||
VDEPTH_32BIT // "Millions"
|
||||
};
|
||||
|
||||
// For compatibility reasons with older (pre-Display Manager) versions of
|
||||
// MacOS, the Apple modes must start at 0x80 and be contiguous. Therefore
|
||||
// we construct an array to map the depth codes to the corresponding Apple
|
||||
// mode. This array is initialized by video_init_depth_list() which must
|
||||
// be called by the platform-dependant VideoInit() routine after filling
|
||||
// the VideoModes array.
|
||||
extern uint16 apple_mode_for_depth[6];
|
||||
|
||||
inline uint16 DepthToAppleMode(video_depth depth)
|
||||
{
|
||||
return apple_mode_for_depth[depth];
|
||||
}
|
||||
|
||||
// 1, 2, 4 and 8 bit depths use a color palette
|
||||
inline bool IsDirectMode(video_depth depth)
|
||||
{
|
||||
return depth == VDEPTH_16BIT || depth == VDEPTH_32BIT;
|
||||
@ -101,6 +90,7 @@ inline uint32 TrivialBytesPerRow(uint32 width, video_depth depth)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
You are not completely free in your selection of depth/resolution
|
||||
combinations:
|
||||
@ -134,8 +124,9 @@ struct video_mode {
|
||||
uint32 x; // X size of screen (pixels)
|
||||
uint32 y; // Y size of screen (pixels)
|
||||
uint32 resolution_id; // Resolution ID (should be >= 0x80 and uniquely identify the sets of modes with the same X/Y size)
|
||||
uint32 bytes_per_row; // Bytes per row of frame buffer
|
||||
video_depth depth; // Color depth (see definitions above)
|
||||
uint32 bytes_per_row; // Bytes per row of frame buffer
|
||||
uint32 user_data; // Free for use by platform-specific code
|
||||
};
|
||||
|
||||
inline bool IsDirectMode(const video_mode &mode)
|
||||
@ -143,22 +134,132 @@ inline bool IsDirectMode(const video_mode &mode)
|
||||
return IsDirectMode(mode.depth);
|
||||
}
|
||||
|
||||
// List of all supported video modes
|
||||
extern vector<video_mode> VideoModes;
|
||||
|
||||
// Description for one (possibly virtual) monitor
|
||||
struct monitor_desc {
|
||||
uint32 mac_frame_base; // Mac frame buffer address
|
||||
video_mode mode; // Currently selected video mode description
|
||||
// Mac video driver per-display private variables (opaque)
|
||||
struct video_locals;
|
||||
|
||||
|
||||
// Abstract base class representing one (possibly virtual) monitor
|
||||
// ("monitor" = rectangular display with a contiguous frame buffer)
|
||||
class monitor_desc {
|
||||
public:
|
||||
monitor_desc(const vector<video_mode> &available_modes, video_depth default_depth, uint32 default_id);
|
||||
virtual ~monitor_desc() {}
|
||||
|
||||
// Get Mac slot ID number
|
||||
uint8 get_slot_id(void) const {return slot_id;}
|
||||
|
||||
// Get current Mac frame buffer base address
|
||||
uint32 get_mac_frame_base(void) const {return mac_frame_base;}
|
||||
|
||||
// Set Mac frame buffer base address (called from switch_to_mode())
|
||||
void set_mac_frame_base(uint32 base) {mac_frame_base = base;}
|
||||
|
||||
// Get current video mode
|
||||
const video_mode &get_current_mode(void) const {return *current_mode;}
|
||||
|
||||
// Get Apple mode id for given depth
|
||||
uint16 depth_to_apple_mode(video_depth depth) const {return apple_mode_for_depth[depth];}
|
||||
|
||||
// Get current color depth
|
||||
uint16 get_apple_mode(void) const {return depth_to_apple_mode(current_mode->depth);}
|
||||
|
||||
// Get bytes-per-row value for specified resolution/depth
|
||||
// (if the mode isn't supported, make a good guess)
|
||||
uint32 get_bytes_per_row(video_depth depth, uint32 id) const;
|
||||
|
||||
// Check whether a mode with the specified depth exists on this display
|
||||
bool has_depth(video_depth depth) const;
|
||||
|
||||
// Mac video driver functions
|
||||
int16 driver_open(void);
|
||||
int16 driver_control(uint16 code, uint32 param, uint32 dce);
|
||||
int16 driver_status(uint16 code, uint32 param);
|
||||
|
||||
protected:
|
||||
vector<video_mode> modes; // List of supported video modes
|
||||
vector<video_mode>::const_iterator current_mode; // Currently selected video mode
|
||||
|
||||
uint32 mac_frame_base; // Mac frame buffer address for current mode
|
||||
|
||||
// Mac video driver per-display private variables/functions
|
||||
private:
|
||||
// Check whether the specified resolution ID is one of the supported resolutions
|
||||
bool has_resolution(uint32 id) const;
|
||||
|
||||
// Return iterator signifying "invalid mode"
|
||||
vector<video_mode>::const_iterator invalid_mode(void) const {return modes.end();}
|
||||
|
||||
// Find specified mode (depth/resolution) (or invalid_mode() if not found)
|
||||
vector<video_mode>::const_iterator find_mode(uint16 apple_mode, uint32 id) const;
|
||||
|
||||
// Find maximum supported depth for given resolution ID
|
||||
video_depth max_depth_of_resolution(uint32 id) const;
|
||||
|
||||
// Get X/Y size of specified resolution
|
||||
void get_size_of_resolution(uint32 id, uint32 &x, uint32 &y) const;
|
||||
|
||||
// Set palette to 50% gray
|
||||
void set_gray_palette(void);
|
||||
|
||||
// Load gamma-corrected black-to-white ramp to palette for direct-color mode
|
||||
void load_ramp_palette(void);
|
||||
|
||||
// Allocate gamma table of specified size
|
||||
bool allocate_gamma_table(int size);
|
||||
|
||||
// Set gamma table (0 = build linear ramp)
|
||||
bool set_gamma_table(uint32 user_table);
|
||||
|
||||
// Switch video mode
|
||||
void switch_mode(vector<video_mode>::const_iterator it, uint32 param, uint32 dce);
|
||||
|
||||
uint8 slot_id; // NuBus slot ID number
|
||||
static uint8 next_slot_id; // Next available slot ID
|
||||
|
||||
uint8 palette[256 * 3]; // Color palette, 256 entries, RGB
|
||||
|
||||
bool luminance_mapping; // Luminance mapping on/off
|
||||
bool interrupts_enabled; // VBL interrupts on/off
|
||||
bool dm_present; // We received a GetVideoParameters call, so the Display Manager seems to be present
|
||||
|
||||
uint32 gamma_table; // Mac address of gamma table
|
||||
int alloc_gamma_table_size; // Allocated size of gamma table
|
||||
|
||||
uint16 current_apple_mode; // Currently selected depth/resolution
|
||||
uint32 current_id;
|
||||
uint16 preferred_apple_mode; // Preferred depth/resolution
|
||||
uint32 preferred_id;
|
||||
|
||||
uint32 slot_param; // Mac address of Slot Manager parameter block
|
||||
|
||||
// For compatibility reasons with older (pre-Display Manager) versions of
|
||||
// MacOS, the Apple modes must start at 0x80 and be contiguous. Therefore
|
||||
// we maintain an array to map the depth codes to the corresponding Apple
|
||||
// mode.
|
||||
uint16 apple_mode_for_depth[6];
|
||||
|
||||
// The following functions are implemented by platform-specific code
|
||||
public:
|
||||
|
||||
// Called by the video driver to switch the video mode on this display
|
||||
// (must call set_mac_frame_base())
|
||||
virtual void switch_to_current_mode(void) = 0;
|
||||
|
||||
// Called by the video driver to set the color palette (in indexed modes)
|
||||
// or the gamma table (in direct modes)
|
||||
virtual void set_palette(uint8 *pal, int num) = 0;
|
||||
};
|
||||
|
||||
// Description of the main (and currently the only) monitor, set by VideoInit()
|
||||
extern monitor_desc VideoMonitor;
|
||||
// Vector of pointers to available monitor descriptions, filled by VideoInit()
|
||||
extern vector<monitor_desc *> VideoMonitors;
|
||||
|
||||
|
||||
extern int16 VideoDriverOpen(uint32 pb, uint32 dce);
|
||||
extern int16 VideoDriverControl(uint32 pb, uint32 dce);
|
||||
extern int16 VideoDriverStatus(uint32 pb, uint32 dce);
|
||||
|
||||
|
||||
// System specific and internal functions/data
|
||||
extern bool VideoInit(bool classic);
|
||||
extern void VideoExit(void);
|
||||
@ -168,20 +269,4 @@ extern void VideoQuitFullScreen(void);
|
||||
extern void VideoInterrupt(void);
|
||||
extern void VideoRefresh(void);
|
||||
|
||||
// Called by the video driver to switch the video mode
|
||||
extern void video_switch_to_mode(const video_mode &mode);
|
||||
|
||||
// Called by the video driver to set the color palette (in indexed modes)
|
||||
// or gamma table (in direct modes)
|
||||
extern void video_set_palette(uint8 *pal, int num);
|
||||
|
||||
// Check whether a mode with the specified depth exists
|
||||
extern bool video_has_depth(video_depth depth);
|
||||
|
||||
// Get bytes-per-row value for specified resolution/depth
|
||||
extern uint32 video_bytes_per_row(video_depth depth, uint32 id);
|
||||
|
||||
// Initialize apple_mode_for_depth[] array from VideoModes list
|
||||
extern void video_init_depth_list(void);
|
||||
|
||||
#endif
|
||||
|
@ -176,7 +176,8 @@ bool InitAll(void)
|
||||
// Set default video mode in XPRAM
|
||||
XPRAM[0x56] = 0x42; // 'B'
|
||||
XPRAM[0x57] = 0x32; // '2'
|
||||
XPRAM[0x58] = DepthToAppleMode(VideoMonitor.mode.depth);
|
||||
const monitor_desc &main_monitor = *VideoMonitors[0];
|
||||
XPRAM[0x58] = main_monitor.depth_to_apple_mode(main_monitor.get_current_mode().depth);
|
||||
XPRAM[0x59] = 0;
|
||||
|
||||
#if EMULATED_68K
|
||||
|
@ -105,12 +105,14 @@ static void PString(char *str)
|
||||
srom[p++] = 0;
|
||||
}
|
||||
|
||||
static uint32 VModeParms(const video_mode &mode, video_depth depth)
|
||||
static uint32 VModeParms(const monitor_desc &m, video_depth depth)
|
||||
{
|
||||
const video_mode &mode = m.get_current_mode();
|
||||
|
||||
uint32 ret = p;
|
||||
Long(50); // Length
|
||||
Long(0); // Base offset
|
||||
Word(video_bytes_per_row(depth, mode.resolution_id));
|
||||
Word(m.get_bytes_per_row(depth, mode.resolution_id));
|
||||
Word(0); // Bounds
|
||||
Word(0);
|
||||
Word(mode.y);
|
||||
@ -173,15 +175,64 @@ static uint32 VModeDesc(uint32 params, bool direct)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint32 VMonitor(const monitor_desc &m, uint32 videoType, uint32 videoName, uint32 vidDrvrDir, uint32 gammaDir)
|
||||
{
|
||||
uint32 minorBase, minorLength;
|
||||
uint32 vidModeParms1, vidModeParms2, vidModeParms4, vidModeParms8, vidModeParms16, vidModeParms32;
|
||||
uint32 vidMode1, vidMode2, vidMode4, vidMode8, vidMode16, vidMode32;
|
||||
uint32 ret;
|
||||
|
||||
minorBase = p;
|
||||
Long(m.get_mac_frame_base()); // Frame buffer base
|
||||
minorLength = p;
|
||||
Long(0); // Frame buffer size (unspecified)
|
||||
|
||||
vidModeParms1 = VModeParms(m, VDEPTH_1BIT);
|
||||
vidModeParms2 = VModeParms(m, VDEPTH_2BIT);
|
||||
vidModeParms4 = VModeParms(m, VDEPTH_4BIT);
|
||||
vidModeParms8 = VModeParms(m, VDEPTH_8BIT);
|
||||
vidModeParms16 = VModeParms(m, VDEPTH_16BIT);
|
||||
vidModeParms32 = VModeParms(m, VDEPTH_32BIT);
|
||||
|
||||
vidMode1 = VModeDesc(vidModeParms1, false);
|
||||
vidMode2 = VModeDesc(vidModeParms2, false);
|
||||
vidMode4 = VModeDesc(vidModeParms4, false);
|
||||
vidMode8 = VModeDesc(vidModeParms8, false);
|
||||
vidMode16 = VModeDesc(vidModeParms16, true);
|
||||
vidMode32 = VModeDesc(vidModeParms32, true);
|
||||
|
||||
ret = p;
|
||||
Offs(0x01, videoType); // Video type descriptor
|
||||
Offs(0x02, videoName); // Driver name
|
||||
Offs(0x04, vidDrvrDir); // Driver directory
|
||||
Rsrc(0x08, 0x4232); // Hardware device ID ('B2')
|
||||
Offs(0x0a, minorBase); // Frame buffer base
|
||||
Offs(0x0b, minorLength); // Frame buffer length
|
||||
Offs(0x40, gammaDir); // Gamma directory
|
||||
Rsrc(0x7d, 6); // Video attributes: Default to color, built-in
|
||||
if (m.has_depth(VDEPTH_1BIT))
|
||||
Offs(m.depth_to_apple_mode(VDEPTH_1BIT), vidMode1); // Video mode parameters for 1 bit
|
||||
if (m.has_depth(VDEPTH_2BIT))
|
||||
Offs(m.depth_to_apple_mode(VDEPTH_2BIT), vidMode2); // Video mode parameters for 2 bit
|
||||
if (m.has_depth(VDEPTH_4BIT))
|
||||
Offs(m.depth_to_apple_mode(VDEPTH_4BIT), vidMode4); // Video mode parameters for 4 bit
|
||||
if (m.has_depth(VDEPTH_8BIT))
|
||||
Offs(m.depth_to_apple_mode(VDEPTH_8BIT), vidMode8); // Video mode parameters for 8 bit
|
||||
if (m.has_depth(VDEPTH_16BIT))
|
||||
Offs(m.depth_to_apple_mode(VDEPTH_16BIT), vidMode16); // Video mode parameters for 16 bit
|
||||
if (m.has_depth(VDEPTH_32BIT))
|
||||
Offs(m.depth_to_apple_mode(VDEPTH_32BIT), vidMode32); // Video mode parameters for 32 bit
|
||||
EndOfList();
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool InstallSlotROM(void)
|
||||
{
|
||||
uint32 boardType, boardName, vendorID, revLevel, partNum, date;
|
||||
uint32 vendorInfo, sRsrcBoard;
|
||||
|
||||
uint32 videoType, videoName, minorBase, minorLength, videoDrvr, vidDrvrDir;
|
||||
uint32 defaultGamma, gammaDir, sRsrcVideo;
|
||||
uint32 vidModeParms1, vidModeParms2, vidModeParms4, vidModeParms8, vidModeParms16, vidModeParms32;
|
||||
uint32 vidMode1, vidMode2, vidMode4, vidMode8, vidMode16, vidMode32;
|
||||
uint32 videoType, videoName, videoDrvr, vidDrvrDir;
|
||||
uint32 defaultGamma, gammaDir;
|
||||
|
||||
uint32 cpuType, cpuName, cpuMajor, cpuMinor, sRsrcCPU;
|
||||
|
||||
@ -189,7 +240,11 @@ bool InstallSlotROM(void)
|
||||
|
||||
uint32 sRsrcDir;
|
||||
|
||||
vector<monitor_desc *>::const_iterator m, mend = VideoMonitors.end();
|
||||
vector<uint32> sRsrcVideo;
|
||||
|
||||
char str[256];
|
||||
int i;
|
||||
p = 0;
|
||||
|
||||
// Board sResource
|
||||
@ -221,15 +276,10 @@ bool InstallSlotROM(void)
|
||||
Offs(0x24, vendorInfo); // Vendor Info
|
||||
EndOfList();
|
||||
|
||||
// Video sResource for default mode
|
||||
videoType = p; // Literals
|
||||
videoType = p;
|
||||
Word(3); Word(1); Word(1); Word(0x4232); // Display Video Apple 'B2'
|
||||
videoName = p;
|
||||
String("Display_Video_Apple_Basilisk");
|
||||
minorBase = p;
|
||||
Long(VideoMonitor.mac_frame_base); // Frame buffer base
|
||||
minorLength = p;
|
||||
Long(0); // Frame buffer size (unspecified)
|
||||
|
||||
videoDrvr = p; // Video driver
|
||||
Long(0x72); // Length
|
||||
@ -302,42 +352,8 @@ bool InstallSlotROM(void)
|
||||
Offs(0x80, defaultGamma);
|
||||
EndOfList();
|
||||
|
||||
vidModeParms1 = VModeParms(VideoMonitor.mode, VDEPTH_1BIT);
|
||||
vidModeParms2 = VModeParms(VideoMonitor.mode, VDEPTH_2BIT);
|
||||
vidModeParms4 = VModeParms(VideoMonitor.mode, VDEPTH_4BIT);
|
||||
vidModeParms8 = VModeParms(VideoMonitor.mode, VDEPTH_8BIT);
|
||||
vidModeParms16 = VModeParms(VideoMonitor.mode, VDEPTH_16BIT);
|
||||
vidModeParms32 = VModeParms(VideoMonitor.mode, VDEPTH_32BIT);
|
||||
|
||||
vidMode1 = VModeDesc(vidModeParms1, false);
|
||||
vidMode2 = VModeDesc(vidModeParms2, false);
|
||||
vidMode4 = VModeDesc(vidModeParms4, false);
|
||||
vidMode8 = VModeDesc(vidModeParms8, false);
|
||||
vidMode16 = VModeDesc(vidModeParms16, true);
|
||||
vidMode32 = VModeDesc(vidModeParms32, true);
|
||||
|
||||
sRsrcVideo = p;
|
||||
Offs(0x01, videoType); // Video type descriptor
|
||||
Offs(0x02, videoName); // Driver name
|
||||
Offs(0x04, vidDrvrDir); // Driver directory
|
||||
Rsrc(0x08, 0x4232); // Hardware device ID ('B2')
|
||||
Offs(0x0a, minorBase); // Frame buffer base
|
||||
Offs(0x0b, minorLength); // Frame buffer length
|
||||
Offs(0x40, gammaDir); // Gamma directory
|
||||
Rsrc(0x7d, 6); // Video attributes: Default to color, built-in
|
||||
if (video_has_depth(VDEPTH_1BIT))
|
||||
Offs(DepthToAppleMode(VDEPTH_1BIT), vidMode1); // Video mode parameters for 1 bit
|
||||
if (video_has_depth(VDEPTH_2BIT))
|
||||
Offs(DepthToAppleMode(VDEPTH_2BIT), vidMode2); // Video mode parameters for 2 bit
|
||||
if (video_has_depth(VDEPTH_4BIT))
|
||||
Offs(DepthToAppleMode(VDEPTH_4BIT), vidMode4); // Video mode parameters for 4 bit
|
||||
if (video_has_depth(VDEPTH_8BIT))
|
||||
Offs(DepthToAppleMode(VDEPTH_8BIT), vidMode8); // Video mode parameters for 8 bit
|
||||
if (video_has_depth(VDEPTH_16BIT))
|
||||
Offs(DepthToAppleMode(VDEPTH_16BIT), vidMode16); // Video mode parameters for 16 bit
|
||||
if (video_has_depth(VDEPTH_32BIT))
|
||||
Offs(DepthToAppleMode(VDEPTH_32BIT), vidMode32); // Video mode parameters for 32 bit
|
||||
EndOfList();
|
||||
for (m = VideoMonitors.begin(); m != mend; ++m)
|
||||
sRsrcVideo.push_back(VMonitor(**m, videoType, videoName, vidDrvrDir, gammaDir));
|
||||
|
||||
// CPU sResource
|
||||
cpuType = p; // Literals
|
||||
@ -415,7 +431,8 @@ bool InstallSlotROM(void)
|
||||
// sResource directory
|
||||
sRsrcDir = p;
|
||||
Offs(0x01, sRsrcBoard);
|
||||
Offs(0x80, sRsrcVideo);
|
||||
for (m = VideoMonitors.begin(), i = 0; m != mend; ++m, ++i)
|
||||
Offs((*m)->get_slot_id(), sRsrcVideo[i]);
|
||||
Offs(0xf0, sRsrcCPU);
|
||||
Offs(0xf1, sRsrcEther);
|
||||
EndOfList();
|
||||
|
@ -41,143 +41,11 @@
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
// List of supported video modes
|
||||
vector<video_mode> VideoModes;
|
||||
// Next available NuBus slot ID
|
||||
uint8 monitor_desc::next_slot_id = 0x80;
|
||||
|
||||
// Description of the main monitor
|
||||
monitor_desc VideoMonitor;
|
||||
|
||||
// Depth code -> Apple mode mapping
|
||||
uint16 apple_mode_for_depth[6];
|
||||
|
||||
// Local variables (per monitor)
|
||||
struct {
|
||||
monitor_desc *desc; // Pointer to description of monitor handled by this instance of the driver
|
||||
uint8 palette[256 * 3]; // Color palette, 256 entries, RGB
|
||||
bool luminance_mapping; // Luminance mapping on/off
|
||||
bool interrupts_enabled; // VBL interrupts on/off
|
||||
bool dm_present; // We received a GetVideoParameters call, so the Display Manager seems to be present
|
||||
uint32 gamma_table; // Mac address of gamma table
|
||||
int alloc_gamma_table_size; // Allocated size of gamma table
|
||||
uint16 current_mode; // Currently selected depth/resolution
|
||||
uint32 current_id;
|
||||
uint16 preferred_mode; // Preferred depth/resolution
|
||||
uint32 preferred_id;
|
||||
uint32 slot_param; // Mac address of Slot Manager parameter block
|
||||
} VidLocal;
|
||||
|
||||
|
||||
/*
|
||||
* Initialize apple_mode_for_depth[] array from VideoModes list
|
||||
*/
|
||||
|
||||
void video_init_depth_list(void)
|
||||
{
|
||||
uint16 mode = 0x80;
|
||||
for (int depth = VDEPTH_1BIT; depth <= VDEPTH_32BIT; depth++) {
|
||||
if (video_has_depth(video_depth(depth)))
|
||||
apple_mode_for_depth[depth] = mode++;
|
||||
else
|
||||
apple_mode_for_depth[depth] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Check whether a mode with the specified depth exists
|
||||
*/
|
||||
|
||||
bool video_has_depth(video_depth depth)
|
||||
{
|
||||
vector<video_mode>::const_iterator i = VideoModes.begin(), end = VideoModes.end();
|
||||
while (i != end) {
|
||||
if (i->depth == depth)
|
||||
return true;
|
||||
++i;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Check whether specified resolution ID is one of the supported resolutions
|
||||
*/
|
||||
|
||||
static bool has_resolution(uint32 id)
|
||||
{
|
||||
vector<video_mode>::const_iterator i, end = VideoModes.end();
|
||||
for (i = VideoModes.begin(); i != end; ++i) {
|
||||
if (i->resolution_id == id)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Find specified mode (depth/resolution) (or VideoModes.end() if not found)
|
||||
*/
|
||||
|
||||
static vector<video_mode>::const_iterator find_mode(uint16 mode, uint32 id)
|
||||
{
|
||||
vector<video_mode>::const_iterator i, end = VideoModes.end();
|
||||
for (i = VideoModes.begin(); i != end; ++i) {
|
||||
if (i->resolution_id == id && DepthToAppleMode(i->depth) == mode)
|
||||
return i;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Find maximum supported depth for given resolution ID
|
||||
*/
|
||||
|
||||
static video_depth max_depth_of_resolution(uint32 id)
|
||||
{
|
||||
video_depth m = VDEPTH_1BIT;
|
||||
vector<video_mode>::const_iterator i, end = VideoModes.end();
|
||||
for (i = VideoModes.begin(); i != end; ++i) {
|
||||
if (i->depth > m)
|
||||
m = i->depth;
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get X/Y size of specified resolution
|
||||
*/
|
||||
|
||||
static void get_size_of_resolution(uint32 id, uint32 &x, uint32 &y)
|
||||
{
|
||||
vector<video_mode>::const_iterator i, end = VideoModes.end();
|
||||
for (i = VideoModes.begin(); i != end; ++i) {
|
||||
if (i->resolution_id == id) {
|
||||
x = i->x;
|
||||
y = i->y;
|
||||
return;
|
||||
}
|
||||
}
|
||||
x = y = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get bytes-per-row value for specified resolution/depth
|
||||
*/
|
||||
|
||||
uint32 video_bytes_per_row(video_depth depth, uint32 id)
|
||||
{
|
||||
vector<video_mode>::const_iterator i, end = VideoModes.end();
|
||||
for (i = VideoModes.begin(); i != end; ++i) {
|
||||
if (i->depth == depth && i->resolution_id == id)
|
||||
return i->bytes_per_row;
|
||||
}
|
||||
uint32 x, y;
|
||||
get_size_of_resolution(id, x, y);
|
||||
return TrivialBytesPerRow(x, depth);
|
||||
}
|
||||
// Vector of pointers to available monitor descriptions, filled by VideoInit()
|
||||
vector<monitor_desc *> VideoMonitors;
|
||||
|
||||
|
||||
/*
|
||||
@ -198,18 +66,154 @@ static int palette_size(video_depth depth)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Find pointer to monitor_desc for given slot ID (or NULL if not found)
|
||||
*/
|
||||
|
||||
static monitor_desc *find_monitor(uint8 id)
|
||||
{
|
||||
vector<monitor_desc *>::const_iterator i, end = VideoMonitors.end();
|
||||
for (i = VideoMonitors.begin(); i != end; ++i) {
|
||||
if ((*i)->get_slot_id() == id)
|
||||
return *i;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* monitor_desc constructor
|
||||
*/
|
||||
|
||||
monitor_desc::monitor_desc(const vector<video_mode> &available_modes, video_depth default_depth, uint32 default_id) : modes(available_modes)
|
||||
{
|
||||
// Assign the next slot ID on construction
|
||||
slot_id = next_slot_id++;
|
||||
|
||||
// Initialize Apple mode list
|
||||
uint16 mode = 0x80;
|
||||
for (int depth = VDEPTH_1BIT; depth <= VDEPTH_32BIT; depth++) {
|
||||
if (has_depth(video_depth(depth)))
|
||||
apple_mode_for_depth[depth] = mode++;
|
||||
else
|
||||
apple_mode_for_depth[depth] = 0;
|
||||
}
|
||||
|
||||
// Set default mode
|
||||
current_mode = find_mode(depth_to_apple_mode(default_depth), default_id);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get bytes-per-row value for specified resolution/depth
|
||||
* (if the mode isn't supported, make a good guess)
|
||||
*/
|
||||
|
||||
uint32 monitor_desc::get_bytes_per_row(video_depth depth, uint32 id) const
|
||||
{
|
||||
vector<video_mode>::const_iterator i, end = modes.end();
|
||||
for (i = modes.begin(); i != end; ++i) {
|
||||
if (i->depth == depth && i->resolution_id == id)
|
||||
return i->bytes_per_row;
|
||||
}
|
||||
uint32 x, y;
|
||||
get_size_of_resolution(id, x, y);
|
||||
return TrivialBytesPerRow(x, depth);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Check whether a mode with the specified depth exists on this display
|
||||
*/
|
||||
|
||||
bool monitor_desc::has_depth(video_depth depth) const
|
||||
{
|
||||
vector<video_mode>::const_iterator i = modes.begin(), end = modes.end();
|
||||
while (i != end) {
|
||||
if (i->depth == depth)
|
||||
return true;
|
||||
++i;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Check whether the specified resolution ID is one of the supported resolutions
|
||||
*/
|
||||
|
||||
bool monitor_desc::has_resolution(uint32 id) const
|
||||
{
|
||||
vector<video_mode>::const_iterator i, end = modes.end();
|
||||
for (i = modes.begin(); i != end; ++i) {
|
||||
if (i->resolution_id == id)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Find specified mode (depth/resolution) (or invalid_mode() if not found)
|
||||
*/
|
||||
|
||||
vector<video_mode>::const_iterator monitor_desc::find_mode(uint16 apple_mode, uint32 id) const
|
||||
{
|
||||
vector<video_mode>::const_iterator i, end = modes.end();
|
||||
for (i = modes.begin(); i != end; ++i) {
|
||||
if (i->resolution_id == id && depth_to_apple_mode(i->depth) == apple_mode)
|
||||
return i;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Find maximum supported depth for given resolution ID
|
||||
*/
|
||||
|
||||
video_depth monitor_desc::max_depth_of_resolution(uint32 id) const
|
||||
{
|
||||
video_depth m = VDEPTH_1BIT;
|
||||
vector<video_mode>::const_iterator i, end = modes.end();
|
||||
for (i = modes.begin(); i != end; ++i) {
|
||||
if (i->depth > m)
|
||||
m = i->depth;
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get X/Y size of specified resolution
|
||||
*/
|
||||
|
||||
void monitor_desc::get_size_of_resolution(uint32 id, uint32 &x, uint32 &y) const
|
||||
{
|
||||
vector<video_mode>::const_iterator i, end = modes.end();
|
||||
for (i = modes.begin(); i != end; ++i) {
|
||||
if (i->resolution_id == id) {
|
||||
x = i->x;
|
||||
y = i->y;
|
||||
return;
|
||||
}
|
||||
}
|
||||
x = y = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set palette to 50% gray
|
||||
*/
|
||||
|
||||
static void set_gray_palette(void)
|
||||
void monitor_desc::set_gray_palette(void)
|
||||
{
|
||||
for (int i=0; i<256; i++) {
|
||||
VidLocal.palette[i * 3 + 0] = 127;
|
||||
VidLocal.palette[i * 3 + 1] = 127;
|
||||
VidLocal.palette[i * 3 + 2] = 127;
|
||||
palette[i * 3 + 0] = 127;
|
||||
palette[i * 3 + 1] = 127;
|
||||
palette[i * 3 + 2] = 127;
|
||||
}
|
||||
video_set_palette(VidLocal.palette, 256);
|
||||
set_palette(palette, 256);
|
||||
}
|
||||
|
||||
|
||||
@ -217,14 +221,14 @@ static void set_gray_palette(void)
|
||||
* Load gamma-corrected black-to-white ramp to palette for direct-color mode
|
||||
*/
|
||||
|
||||
static void load_ramp_palette(void)
|
||||
void monitor_desc::load_ramp_palette(void)
|
||||
{
|
||||
// Find tables for gamma correction
|
||||
uint8 *red_gamma = NULL, *green_gamma = NULL, *blue_gamma = NULL;
|
||||
bool have_gamma = false;
|
||||
int data_width = 0;
|
||||
if (VidLocal.gamma_table) {
|
||||
uint32 table = VidLocal.gamma_table;
|
||||
if (gamma_table) {
|
||||
uint32 table = gamma_table;
|
||||
red_gamma = Mac2HostAddr(table + gFormulaData + ReadMacInt16(table + gFormulaSize));
|
||||
int chan_cnt = ReadMacInt16(table + gChanCnt);
|
||||
if (chan_cnt == 1)
|
||||
@ -238,8 +242,8 @@ static void load_ramp_palette(void)
|
||||
have_gamma = true;
|
||||
}
|
||||
|
||||
int num = (VidLocal.desc->mode.depth == VDEPTH_16BIT ? 32 : 256);
|
||||
uint8 *p = VidLocal.palette;
|
||||
int num = (current_mode->depth == VDEPTH_16BIT ? 32 : 256);
|
||||
uint8 *p = palette;
|
||||
for (int i=0; i<num; i++) {
|
||||
uint8 red = (i * 256 / num), green = red, blue = red;
|
||||
if (have_gamma) {
|
||||
@ -252,7 +256,7 @@ static void load_ramp_palette(void)
|
||||
*p++ = blue;
|
||||
}
|
||||
|
||||
video_set_palette(VidLocal.palette, num);
|
||||
set_palette(palette, num);
|
||||
}
|
||||
|
||||
|
||||
@ -260,23 +264,23 @@ static void load_ramp_palette(void)
|
||||
* Allocate gamma table of specified size
|
||||
*/
|
||||
|
||||
static bool allocate_gamma_table(int size)
|
||||
bool monitor_desc::allocate_gamma_table(int size)
|
||||
{
|
||||
M68kRegisters r;
|
||||
|
||||
if (size > VidLocal.alloc_gamma_table_size) {
|
||||
if (VidLocal.gamma_table) {
|
||||
r.a[0] = VidLocal.gamma_table;
|
||||
if (size > alloc_gamma_table_size) {
|
||||
if (gamma_table) {
|
||||
r.a[0] = gamma_table;
|
||||
Execute68kTrap(0xa01f, &r); // DisposePtr()
|
||||
VidLocal.gamma_table = 0;
|
||||
VidLocal.alloc_gamma_table_size = 0;
|
||||
gamma_table = 0;
|
||||
alloc_gamma_table_size = 0;
|
||||
}
|
||||
r.d[0] = size;
|
||||
Execute68kTrap(0xa71e, &r); // NewPtrSysClear()
|
||||
if (r.a[0] == 0)
|
||||
return false;
|
||||
VidLocal.gamma_table = r.a[0];
|
||||
VidLocal.alloc_gamma_table_size = size;
|
||||
gamma_table = r.a[0];
|
||||
alloc_gamma_table_size = size;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -286,25 +290,24 @@ static bool allocate_gamma_table(int size)
|
||||
* Set gamma table (0 = build linear ramp)
|
||||
*/
|
||||
|
||||
static bool set_gamma_table(uint32 user_table)
|
||||
bool monitor_desc::set_gamma_table(uint32 user_table)
|
||||
{
|
||||
if (user_table == 0) { // Build linear ramp, 256 entries
|
||||
|
||||
// Allocate new table, if necessary
|
||||
if (!allocate_gamma_table(SIZEOF_GammaTbl + 256))
|
||||
return memFullErr;
|
||||
uint32 table = VidLocal.gamma_table;
|
||||
|
||||
// Initialize header
|
||||
WriteMacInt16(table + gVersion, 0);
|
||||
WriteMacInt16(table + gType, 0);
|
||||
WriteMacInt16(table + gFormulaSize, 0);
|
||||
WriteMacInt16(table + gChanCnt, 1);
|
||||
WriteMacInt16(table + gDataCnt, 256);
|
||||
WriteMacInt16(table + gDataWidth, 8);
|
||||
WriteMacInt16(gamma_table + gVersion, 0);
|
||||
WriteMacInt16(gamma_table + gType, 0);
|
||||
WriteMacInt16(gamma_table + gFormulaSize, 0);
|
||||
WriteMacInt16(gamma_table + gChanCnt, 1);
|
||||
WriteMacInt16(gamma_table + gDataCnt, 256);
|
||||
WriteMacInt16(gamma_table + gDataWidth, 8);
|
||||
|
||||
// Build ramp
|
||||
uint32 p = table + gFormulaData;
|
||||
uint32 p = gamma_table + gFormulaData;
|
||||
for (int i=0; i<256; i++)
|
||||
WriteMacInt8(p + i, i);
|
||||
|
||||
@ -329,13 +332,12 @@ static bool set_gamma_table(uint32 user_table)
|
||||
int size = SIZEOF_GammaTbl + ReadMacInt16(user_table + gFormulaSize) + chan_cnt * data_cnt;
|
||||
if (!allocate_gamma_table(size))
|
||||
return memFullErr;
|
||||
uint32 table = VidLocal.gamma_table;
|
||||
|
||||
// Copy table
|
||||
Mac2Mac_memcpy(table, user_table, size);
|
||||
Mac2Mac_memcpy(gamma_table, user_table, size);
|
||||
}
|
||||
|
||||
if (IsDirectMode(VidLocal.desc->mode))
|
||||
if (IsDirectMode(*current_mode))
|
||||
load_ramp_palette();
|
||||
|
||||
return true;
|
||||
@ -346,49 +348,49 @@ static bool set_gamma_table(uint32 user_table)
|
||||
* Switch video mode
|
||||
*/
|
||||
|
||||
static void switch_mode(const video_mode &mode, uint32 param, uint32 dce)
|
||||
void monitor_desc::switch_mode(vector<video_mode>::const_iterator it, uint32 param, uint32 dce)
|
||||
{
|
||||
const video_mode &mode = *it;
|
||||
|
||||
// Switch mode
|
||||
set_gray_palette();
|
||||
video_switch_to_mode(mode);
|
||||
current_mode = it;
|
||||
switch_to_current_mode();
|
||||
|
||||
// Update VidLocal
|
||||
VidLocal.current_mode = DepthToAppleMode(mode.depth);
|
||||
VidLocal.current_id = mode.resolution_id;
|
||||
|
||||
uint32 frame_base = VidLocal.desc->mac_frame_base;
|
||||
// Update variables
|
||||
current_apple_mode = depth_to_apple_mode(mode.depth);
|
||||
current_id = mode.resolution_id;
|
||||
|
||||
M68kRegisters r;
|
||||
uint32 sp = VidLocal.slot_param;
|
||||
r.a[0] = sp;
|
||||
r.a[0] = slot_param;
|
||||
|
||||
// Find functional sResource for this display
|
||||
WriteMacInt8(sp + spSlot, ReadMacInt8(dce + dCtlSlot));
|
||||
WriteMacInt8(sp + spID, ReadMacInt8(dce + dCtlSlotId));
|
||||
WriteMacInt8(sp + spExtDev, 0);
|
||||
WriteMacInt8(slot_param + spSlot, ReadMacInt8(dce + dCtlSlot));
|
||||
WriteMacInt8(slot_param + spID, ReadMacInt8(dce + dCtlSlotId));
|
||||
WriteMacInt8(slot_param + spExtDev, 0);
|
||||
r.d[0] = 0x0016;
|
||||
Execute68kTrap(0xa06e, &r); // SRsrcInfo()
|
||||
uint32 rsrc = ReadMacInt32(sp + spPointer);
|
||||
uint32 rsrc = ReadMacInt32(slot_param + spPointer);
|
||||
|
||||
// Patch minorBase (otherwise rebooting won't work)
|
||||
WriteMacInt8(sp + spID, 0x0a); // minorBase
|
||||
WriteMacInt8(slot_param + spID, 0x0a); // minorBase
|
||||
r.d[0] = 0x0006;
|
||||
Execute68kTrap(0xa06e, &r); // SFindStruct()
|
||||
uint32 minor_base = ReadMacInt32(sp + spPointer) - ROMBaseMac;
|
||||
ROMBaseHost[minor_base + 0] = frame_base >> 24;
|
||||
ROMBaseHost[minor_base + 1] = frame_base >> 16;
|
||||
ROMBaseHost[minor_base + 2] = frame_base >> 8;
|
||||
ROMBaseHost[minor_base + 3] = frame_base;
|
||||
uint32 minor_base = ReadMacInt32(slot_param + spPointer) - ROMBaseMac;
|
||||
ROMBaseHost[minor_base + 0] = mac_frame_base >> 24;
|
||||
ROMBaseHost[minor_base + 1] = mac_frame_base >> 16;
|
||||
ROMBaseHost[minor_base + 2] = mac_frame_base >> 8;
|
||||
ROMBaseHost[minor_base + 3] = mac_frame_base;
|
||||
|
||||
// Patch video mode parameter table
|
||||
WriteMacInt32(sp + spPointer, rsrc);
|
||||
WriteMacInt8(sp + spID, DepthToAppleMode(mode.depth));
|
||||
WriteMacInt32(slot_param + spPointer, rsrc);
|
||||
WriteMacInt8(slot_param + spID, depth_to_apple_mode(mode.depth));
|
||||
r.d[0] = 0x0006;
|
||||
Execute68kTrap(0xa06e, &r); // SFindStruct()
|
||||
WriteMacInt8(sp + spID, 0x01);
|
||||
WriteMacInt8(slot_param + spID, 0x01);
|
||||
r.d[0] = 0x0006;
|
||||
Execute68kTrap(0xa06e, &r); // SFindStruct()
|
||||
uint32 p = ReadMacInt32(sp + spPointer) - ROMBaseMac;
|
||||
uint32 p = ReadMacInt32(slot_param + spPointer) - ROMBaseMac;
|
||||
ROMBaseHost[p + 8] = mode.bytes_per_row >> 8;
|
||||
ROMBaseHost[p + 9] = mode.bytes_per_row;
|
||||
ROMBaseHost[p + 14] = mode.y >> 8;
|
||||
@ -400,23 +402,24 @@ static void switch_mode(const video_mode &mode, uint32 param, uint32 dce)
|
||||
ChecksumSlotROM();
|
||||
|
||||
// Update sResource
|
||||
WriteMacInt8(sp + spID, ReadMacInt8(dce + dCtlSlotId));
|
||||
WriteMacInt8(slot_param + spID, ReadMacInt8(dce + dCtlSlotId));
|
||||
r.d[0] = 0x002b;
|
||||
Execute68kTrap(0xa06e, &r); // SUpdateSRT()
|
||||
|
||||
// Update frame buffer base in DCE and param block
|
||||
WriteMacInt32(dce + dCtlDevBase, frame_base);
|
||||
WriteMacInt32(param + csBaseAddr, frame_base);
|
||||
WriteMacInt32(dce + dCtlDevBase, mac_frame_base);
|
||||
WriteMacInt32(param + csBaseAddr, mac_frame_base);
|
||||
|
||||
// Patch frame buffer base address for MacOS versions <7.6
|
||||
if (!VidLocal.dm_present) { // Only do this when no Display Manager seems to be present; otherwise, the screen will not get redrawn
|
||||
WriteMacInt32(0x824, frame_base); // ScrnBase
|
||||
WriteMacInt32(0x898, frame_base); // CrsrBase
|
||||
if (!dm_present) { // Only do this when no Display Manager seems to be present; otherwise, the screen will not get redrawn
|
||||
D(bug("No Display Manager, patching frame buffer base\n"));
|
||||
WriteMacInt32(0x824, mac_frame_base); // ScrnBase
|
||||
WriteMacInt32(0x898, mac_frame_base); // CrsrBase
|
||||
uint32 gdev = ReadMacInt32(0x8a4); // MainDevice
|
||||
gdev = ReadMacInt32(gdev);
|
||||
uint32 pmap = ReadMacInt32(gdev + 0x16); // gdPMap
|
||||
pmap = ReadMacInt32(pmap);
|
||||
WriteMacInt32(pmap, frame_base); // baseAddr
|
||||
WriteMacInt32(pmap, mac_frame_base); // baseAddr
|
||||
}
|
||||
}
|
||||
|
||||
@ -425,23 +428,18 @@ static void switch_mode(const video_mode &mode, uint32 param, uint32 dce)
|
||||
* Driver Open() routine
|
||||
*/
|
||||
|
||||
int16 VideoDriverOpen(uint32 pb, uint32 dce)
|
||||
int16 monitor_desc::driver_open(void)
|
||||
{
|
||||
D(bug("VideoDriverOpen\n"));
|
||||
|
||||
// This shouldn't happen unless the platform-specific video code is broken
|
||||
if (VideoModes.empty())
|
||||
if (modes.empty())
|
||||
fprintf(stderr, "No valid video modes found (broken video driver?)\n");
|
||||
|
||||
// Init local variables
|
||||
VidLocal.desc = &VideoMonitor;
|
||||
VidLocal.luminance_mapping = false;
|
||||
VidLocal.interrupts_enabled = false;
|
||||
VidLocal.current_mode = DepthToAppleMode(VidLocal.desc->mode.depth);
|
||||
VidLocal.current_id = VidLocal.desc->mode.resolution_id;
|
||||
VidLocal.preferred_mode = VidLocal.current_mode;
|
||||
VidLocal.preferred_id = VidLocal.current_id;
|
||||
VidLocal.dm_present = false;
|
||||
luminance_mapping = false;
|
||||
interrupts_enabled = false;
|
||||
current_apple_mode = preferred_apple_mode = depth_to_apple_mode(current_mode->depth);
|
||||
current_id = preferred_id = current_mode->resolution_id;
|
||||
dm_present = false;
|
||||
|
||||
// Allocate Slot Manager parameter block in Mac RAM
|
||||
M68kRegisters r;
|
||||
@ -449,12 +447,12 @@ int16 VideoDriverOpen(uint32 pb, uint32 dce)
|
||||
Execute68kTrap(0xa71e, &r); // NewPtrSysClear()
|
||||
if (r.a[0] == 0)
|
||||
return memFullErr;
|
||||
VidLocal.slot_param = r.a[0];
|
||||
D(bug("SPBlock at %08x\n", VidLocal.slot_param));
|
||||
slot_param = r.a[0];
|
||||
D(bug("SPBlock at %08x\n", slot_param));
|
||||
|
||||
// Find and set default gamma table
|
||||
VidLocal.gamma_table = 0;
|
||||
VidLocal.alloc_gamma_table_size = 0;
|
||||
gamma_table = 0;
|
||||
alloc_gamma_table_size = 0;
|
||||
set_gamma_table(0);
|
||||
|
||||
// Init color palette (solid gray)
|
||||
@ -462,16 +460,25 @@ int16 VideoDriverOpen(uint32 pb, uint32 dce)
|
||||
return noErr;
|
||||
}
|
||||
|
||||
int16 VideoDriverOpen(uint32 pb, uint32 dce)
|
||||
{
|
||||
uint8 slot_id = ReadMacInt8(dce + dCtlSlotId);
|
||||
D(bug("VideoDriverOpen slot %02x\n", slot_id));
|
||||
|
||||
monitor_desc *m = find_monitor(slot_id);
|
||||
if (m)
|
||||
return m->driver_open();
|
||||
else
|
||||
return nsDrvErr;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Driver Control() routine
|
||||
*/
|
||||
|
||||
int16 VideoDriverControl(uint32 pb, uint32 dce)
|
||||
int16 monitor_desc::driver_control(uint16 code, uint32 param, uint32 dce)
|
||||
{
|
||||
uint16 code = ReadMacInt16(pb + csCode);
|
||||
uint32 param = ReadMacInt32(pb + csParam);
|
||||
D(bug("VideoDriverControl %d\n", code));
|
||||
switch (code) {
|
||||
|
||||
case cscSetMode: { // Set color depth
|
||||
@ -479,25 +486,25 @@ int16 VideoDriverControl(uint32 pb, uint32 dce)
|
||||
D(bug(" SetMode %04x\n", mode));
|
||||
|
||||
// Set old base address in case the switch fails
|
||||
WriteMacInt32(param + csBaseAddr, VidLocal.desc->mac_frame_base);
|
||||
WriteMacInt32(param + csBaseAddr, mac_frame_base);
|
||||
|
||||
if (ReadMacInt16(param + csPage))
|
||||
return paramErr;
|
||||
|
||||
if (mode != VidLocal.current_mode) {
|
||||
vector<video_mode>::const_iterator i = find_mode(mode, VidLocal.current_id);
|
||||
if (i == VideoModes.end())
|
||||
if (mode != current_apple_mode) {
|
||||
vector<video_mode>::const_iterator i = find_mode(mode, current_id);
|
||||
if (i == invalid_mode())
|
||||
return paramErr;
|
||||
switch_mode(*i, param, dce);
|
||||
switch_mode(i, param, dce);
|
||||
}
|
||||
D(bug(" base %08x\n", VidLocal.desc->mac_frame_base));
|
||||
D(bug(" base %08x\n", mac_frame_base));
|
||||
return noErr;
|
||||
}
|
||||
|
||||
case cscSetEntries: // Set palette
|
||||
case cscDirectSetEntries: {
|
||||
D(bug(" (Direct)SetEntries table %08x, count %d, start %d\n", ReadMacInt32(param + csTable), ReadMacInt16(param + csCount), ReadMacInt16(param + csStart)));
|
||||
bool is_direct = IsDirectMode(VidLocal.desc->mode);
|
||||
bool is_direct = IsDirectMode(*current_mode);
|
||||
if (code == cscSetEntries && is_direct)
|
||||
return controlErr;
|
||||
if (code == cscDirectSetEntries && !is_direct)
|
||||
@ -514,29 +521,28 @@ int16 VideoDriverControl(uint32 pb, uint32 dce)
|
||||
uint8 *red_gamma = NULL, *green_gamma = NULL, *blue_gamma = NULL;
|
||||
bool have_gamma = false;
|
||||
int data_width = 0;
|
||||
if (VidLocal.gamma_table) {
|
||||
uint32 table = VidLocal.gamma_table;
|
||||
red_gamma = Mac2HostAddr(table + gFormulaData + ReadMacInt16(table + gFormulaSize));
|
||||
int chan_cnt = ReadMacInt16(table + gChanCnt);
|
||||
if (gamma_table) {
|
||||
red_gamma = Mac2HostAddr(gamma_table + gFormulaData + ReadMacInt16(gamma_table + gFormulaSize));
|
||||
int chan_cnt = ReadMacInt16(gamma_table + gChanCnt);
|
||||
if (chan_cnt == 1)
|
||||
green_gamma = blue_gamma = red_gamma;
|
||||
else {
|
||||
int ofs = ReadMacInt16(table + gDataCnt);
|
||||
int ofs = ReadMacInt16(gamma_table + gDataCnt);
|
||||
green_gamma = red_gamma + ofs;
|
||||
blue_gamma = green_gamma + ofs;
|
||||
}
|
||||
data_width = ReadMacInt16(table + gDataWidth);
|
||||
data_width = ReadMacInt16(gamma_table + gDataWidth);
|
||||
have_gamma = true;
|
||||
}
|
||||
|
||||
// Convert palette
|
||||
if (start == 0xffff) { // Indexed
|
||||
for (uint32 i=0; i<=count; i++) {
|
||||
d_pal = VidLocal.palette + (ReadMacInt16(s_pal) & 0xff) * 3;
|
||||
d_pal = palette + (ReadMacInt16(s_pal) & 0xff) * 3;
|
||||
uint8 red = (uint16)ReadMacInt16(s_pal + 2) >> 8;
|
||||
uint8 green = (uint16)ReadMacInt16(s_pal + 4) >> 8;
|
||||
uint8 blue = (uint16)ReadMacInt16(s_pal + 6) >> 8;
|
||||
if (VidLocal.luminance_mapping && !is_direct)
|
||||
if (luminance_mapping && !is_direct)
|
||||
red = green = blue = (red * 0x4ccc + green * 0x970a + blue * 0x1c29) >> 16;
|
||||
if (have_gamma) {
|
||||
red = red_gamma[red >> (8 - data_width)];
|
||||
@ -551,12 +557,12 @@ int16 VideoDriverControl(uint32 pb, uint32 dce)
|
||||
} else { // Sequential
|
||||
if (start + count > 255)
|
||||
return paramErr;
|
||||
d_pal = VidLocal.palette + start * 3;
|
||||
d_pal = palette + start * 3;
|
||||
for (uint32 i=0; i<=count; i++) {
|
||||
uint8 red = (uint16)ReadMacInt16(s_pal + 2) >> 8;
|
||||
uint8 green = (uint16)ReadMacInt16(s_pal + 4) >> 8;
|
||||
uint8 blue = (uint16)ReadMacInt16(s_pal + 6) >> 8;
|
||||
if (VidLocal.luminance_mapping && !is_direct)
|
||||
if (luminance_mapping && !is_direct)
|
||||
red = green = blue = (red * 0x4ccc + green * 0x970a + blue * 0x1c29) >> 16;
|
||||
if (have_gamma) {
|
||||
red = red_gamma[red >> (8 - data_width)];
|
||||
@ -569,7 +575,7 @@ int16 VideoDriverControl(uint32 pb, uint32 dce)
|
||||
s_pal += 8;
|
||||
}
|
||||
}
|
||||
video_set_palette(VidLocal.palette, palette_size(VidLocal.desc->mode.depth));
|
||||
set_palette(palette, palette_size(current_mode->depth));
|
||||
return noErr;
|
||||
}
|
||||
|
||||
@ -592,20 +598,20 @@ int16 VideoDriverControl(uint32 pb, uint32 dce)
|
||||
0xffff0000, // 16 bpp
|
||||
0xffffffff // 32 bpp
|
||||
};
|
||||
uint32 frame_base = VidLocal.desc->mac_frame_base;
|
||||
uint32 pat = pattern[VidLocal.desc->mode.depth];
|
||||
bool invert = (VidLocal.desc->mode.depth == VDEPTH_32BIT);
|
||||
for (uint32 y=0; y<VidLocal.desc->mode.y; y++) {
|
||||
for (uint32 x=0; x<VidLocal.desc->mode.bytes_per_row; x+=4) {
|
||||
WriteMacInt32(frame_base + x, pat);
|
||||
uint32 p = mac_frame_base;
|
||||
uint32 pat = pattern[current_mode->depth];
|
||||
bool invert = (current_mode->depth == VDEPTH_32BIT);
|
||||
for (uint32 y=0; y<current_mode->y; y++) {
|
||||
for (uint32 x=0; x<current_mode->bytes_per_row; x+=4) {
|
||||
WriteMacInt32(p + x, pat);
|
||||
if (invert)
|
||||
pat = ~pat;
|
||||
}
|
||||
frame_base += VidLocal.desc->mode.bytes_per_row;
|
||||
p += current_mode->bytes_per_row;
|
||||
pat = ~pat;
|
||||
}
|
||||
|
||||
if (IsDirectMode(VidLocal.desc->mode))
|
||||
if (IsDirectMode(*current_mode))
|
||||
load_ramp_palette();
|
||||
|
||||
return noErr;
|
||||
@ -613,18 +619,18 @@ int16 VideoDriverControl(uint32 pb, uint32 dce)
|
||||
|
||||
case cscSetGray: // Enable/disable luminance mapping
|
||||
D(bug(" SetGray %02x\n", ReadMacInt8(param + csMode)));
|
||||
VidLocal.luminance_mapping = ReadMacInt8(param + csMode);
|
||||
luminance_mapping = ReadMacInt8(param + csMode);
|
||||
return noErr;
|
||||
|
||||
case cscSetInterrupt: // Enable/disable VBL
|
||||
D(bug(" SetInterrupt %02x\n", ReadMacInt8(param + csMode)));
|
||||
VidLocal.interrupts_enabled = (ReadMacInt8(param + csMode) == 0);
|
||||
interrupts_enabled = (ReadMacInt8(param + csMode) == 0);
|
||||
return noErr;
|
||||
|
||||
case cscSetDefaultMode: { // Set default color depth
|
||||
uint16 mode = ReadMacInt8(param + csMode);
|
||||
D(bug(" SetDefaultMode %02x\n", mode));
|
||||
VidLocal.preferred_mode = mode;
|
||||
preferred_apple_mode = mode;
|
||||
return noErr;
|
||||
}
|
||||
|
||||
@ -634,18 +640,18 @@ int16 VideoDriverControl(uint32 pb, uint32 dce)
|
||||
D(bug(" SwitchMode %04x, %08x\n", mode, id));
|
||||
|
||||
// Set old base address in case the switch fails
|
||||
WriteMacInt32(param + csBaseAddr, VidLocal.desc->mac_frame_base);
|
||||
WriteMacInt32(param + csBaseAddr, mac_frame_base);
|
||||
|
||||
if (ReadMacInt16(param + csPage))
|
||||
return paramErr;
|
||||
|
||||
if (mode != VidLocal.current_mode || id != VidLocal.current_id) {
|
||||
if (mode != current_apple_mode || id != current_id) {
|
||||
vector<video_mode>::const_iterator i = find_mode(mode, id);
|
||||
if (i == VideoModes.end())
|
||||
if (i == invalid_mode())
|
||||
return paramErr;
|
||||
switch_mode(*i, param, dce);
|
||||
switch_mode(i, param, dce);
|
||||
}
|
||||
D(bug(" base %08x\n", VidLocal.desc->mac_frame_base));
|
||||
D(bug(" base %08x\n", mac_frame_base));
|
||||
return noErr;
|
||||
}
|
||||
|
||||
@ -653,8 +659,8 @@ int16 VideoDriverControl(uint32 pb, uint32 dce)
|
||||
uint16 mode = ReadMacInt16(param + csMode);
|
||||
uint32 id = ReadMacInt32(param + csData);
|
||||
D(bug(" SavePreferredConfiguration %04x, %08x\n", mode, id));
|
||||
VidLocal.preferred_mode = mode;
|
||||
VidLocal.preferred_id = id;
|
||||
preferred_apple_mode = mode;
|
||||
preferred_id = id;
|
||||
return noErr;
|
||||
}
|
||||
|
||||
@ -664,23 +670,34 @@ int16 VideoDriverControl(uint32 pb, uint32 dce)
|
||||
}
|
||||
}
|
||||
|
||||
int16 VideoDriverControl(uint32 pb, uint32 dce)
|
||||
{
|
||||
uint8 slot_id = ReadMacInt8(dce + dCtlSlotId);
|
||||
uint16 code = ReadMacInt16(pb + csCode);
|
||||
uint32 param = ReadMacInt32(pb + csParam);
|
||||
D(bug("VideoDriverControl slot %02x, code %d\n", slot_id, code));
|
||||
|
||||
monitor_desc *m = find_monitor(slot_id);
|
||||
if (m)
|
||||
return m->driver_control(code, param, dce);
|
||||
else
|
||||
return nsDrvErr;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Driver Status() routine
|
||||
*/
|
||||
|
||||
int16 VideoDriverStatus(uint32 pb, uint32 dce)
|
||||
int16 monitor_desc::driver_status(uint16 code, uint32 param)
|
||||
{
|
||||
uint16 code = ReadMacInt16(pb + csCode);
|
||||
uint32 param = ReadMacInt32(pb + csParam);
|
||||
D(bug("VideoDriverStatus %d\n", code));
|
||||
switch (code) {
|
||||
|
||||
case cscGetMode: // Get current color depth
|
||||
D(bug(" GetMode -> %04x, base %08x\n", VidLocal.current_mode, VidLocal.desc->mac_frame_base));
|
||||
WriteMacInt16(param + csMode, VidLocal.current_mode);
|
||||
D(bug(" GetMode -> %04x, base %08x\n", current_apple_mode, mac_frame_base));
|
||||
WriteMacInt16(param + csMode, current_apple_mode);
|
||||
WriteMacInt16(param + csPage, 0);
|
||||
WriteMacInt32(param + csBaseAddr, VidLocal.desc->mac_frame_base);
|
||||
WriteMacInt32(param + csBaseAddr, mac_frame_base);
|
||||
return noErr;
|
||||
|
||||
case cscGetEntries: { // Read palette
|
||||
@ -695,7 +712,7 @@ int16 VideoDriverStatus(uint32 pb, uint32 dce)
|
||||
|
||||
if (start == 0xffff) { // Indexed
|
||||
for (uint32 i=0; i<=count; i++) {
|
||||
s_pal = VidLocal.palette + (ReadMacInt16(d_pal) & 0xff) * 3;
|
||||
s_pal = palette + (ReadMacInt16(d_pal) & 0xff) * 3;
|
||||
uint8 red = *s_pal++;
|
||||
uint8 green = *s_pal++;
|
||||
uint8 blue = *s_pal++;
|
||||
@ -707,7 +724,7 @@ int16 VideoDriverStatus(uint32 pb, uint32 dce)
|
||||
} else { // Sequential
|
||||
if (start + count > 255)
|
||||
return paramErr;
|
||||
s_pal = VidLocal.palette + start * 3;
|
||||
s_pal = palette + start * 3;
|
||||
for (uint32 i=0; i<=count; i++) {
|
||||
uint8 red = *s_pal++;
|
||||
uint8 green = *s_pal++;
|
||||
@ -727,39 +744,39 @@ int16 VideoDriverStatus(uint32 pb, uint32 dce)
|
||||
return noErr;
|
||||
|
||||
case cscGetBaseAddress: // Get page base address
|
||||
D(bug(" GetBaseAddress -> %08x\n", VidLocal.desc->mac_frame_base));
|
||||
WriteMacInt32(param + csBaseAddr, VidLocal.desc->mac_frame_base);
|
||||
D(bug(" GetBaseAddress -> %08x\n", mac_frame_base));
|
||||
WriteMacInt32(param + csBaseAddr, mac_frame_base);
|
||||
if (ReadMacInt16(param + csPage))
|
||||
return paramErr;
|
||||
else
|
||||
return noErr;
|
||||
|
||||
case cscGetGray: // Get luminance mapping flag
|
||||
D(bug(" GetGray -> %d\n", VidLocal.luminance_mapping));
|
||||
WriteMacInt8(param, VidLocal.luminance_mapping ? 1 : 0);
|
||||
D(bug(" GetGray -> %d\n", luminance_mapping));
|
||||
WriteMacInt8(param, luminance_mapping ? 1 : 0);
|
||||
return noErr;
|
||||
|
||||
case cscGetInterrupt: // Get interrupt disable flag
|
||||
D(bug(" GetInterrupt -> %d\n", VidLocal.interrupts_enabled));
|
||||
WriteMacInt8(param, VidLocal.interrupts_enabled ? 0 : 1);
|
||||
D(bug(" GetInterrupt -> %d\n", interrupts_enabled));
|
||||
WriteMacInt8(param, interrupts_enabled ? 0 : 1);
|
||||
return noErr;
|
||||
|
||||
case cscGetGamma:
|
||||
D(bug(" GetGamma -> %08x\n", VidLocal.gamma_table));
|
||||
WriteMacInt32(param + csGTable, VidLocal.gamma_table);
|
||||
D(bug(" GetGamma -> %08x\n", gamma_table));
|
||||
WriteMacInt32(param + csGTable, gamma_table);
|
||||
return noErr;
|
||||
|
||||
case cscGetDefaultMode: // Get default color depth
|
||||
D(bug(" GetDefaultMode -> %02x\n", VidLocal.preferred_mode));
|
||||
WriteMacInt8(param + csMode, VidLocal.preferred_mode);
|
||||
D(bug(" GetDefaultMode -> %02x\n", preferred_apple_mode));
|
||||
WriteMacInt8(param + csMode, preferred_apple_mode);
|
||||
return noErr;
|
||||
|
||||
case cscGetCurrentMode: // Get current video mode (depth and resolution)
|
||||
D(bug(" GetCurMode -> %04x/%08x, base %08x\n", VidLocal.current_mode, VidLocal.current_id, VidLocal.desc->mac_frame_base));
|
||||
WriteMacInt16(param + csMode, VidLocal.current_mode);
|
||||
WriteMacInt32(param + csData, VidLocal.current_id);
|
||||
D(bug(" GetCurMode -> %04x/%08x, base %08x\n", current_apple_mode, current_id, mac_frame_base));
|
||||
WriteMacInt16(param + csMode, current_apple_mode);
|
||||
WriteMacInt32(param + csData, current_id);
|
||||
WriteMacInt16(param + csPage, 0);
|
||||
WriteMacInt32(param + csBaseAddr, VidLocal.desc->mac_frame_base);
|
||||
WriteMacInt32(param + csBaseAddr, mac_frame_base);
|
||||
return noErr;
|
||||
|
||||
case cscGetConnection: // Get monitor information
|
||||
@ -780,21 +797,21 @@ int16 VideoDriverStatus(uint32 pb, uint32 dce)
|
||||
WriteMacInt32(param + csTimingFormat, FOURCC('d', 'e', 'c', 'l'));
|
||||
WriteMacInt32(param + csTimingData, 0); // unknown
|
||||
uint32 flags = 0xb; // mode valid, safe and shown in Monitors panel
|
||||
if (id == VidLocal.preferred_id)
|
||||
if (id == preferred_id)
|
||||
flags |= 4; // default mode
|
||||
WriteMacInt32(param + csTimingFlags, flags);
|
||||
return noErr;
|
||||
}
|
||||
|
||||
case cscGetModeBaseAddress: // Get frame buffer base address
|
||||
D(bug(" GetModeBaseAddress -> base %08x\n", VidLocal.desc->mac_frame_base));
|
||||
WriteMacInt32(param + csBaseAddr, VidLocal.desc->mac_frame_base);
|
||||
D(bug(" GetModeBaseAddress -> base %08x\n", mac_frame_base));
|
||||
WriteMacInt32(param + csBaseAddr, mac_frame_base);
|
||||
return noErr;
|
||||
|
||||
case cscGetPreferredConfiguration: // Get default video mode (depth and resolution)
|
||||
D(bug(" GetPreferredConfiguration -> %04x/%08x\n", VidLocal.preferred_mode, VidLocal.preferred_id));
|
||||
WriteMacInt16(param + csMode, VidLocal.preferred_mode);
|
||||
WriteMacInt32(param + csData, VidLocal.preferred_id);
|
||||
D(bug(" GetPreferredConfiguration -> %04x/%08x\n", preferred_apple_mode, preferred_id));
|
||||
WriteMacInt16(param + csMode, preferred_apple_mode);
|
||||
WriteMacInt32(param + csData, preferred_id);
|
||||
return noErr;
|
||||
|
||||
case cscGetNextResolution: { // Called iteratively to obtain a list of all supported resolutions
|
||||
@ -804,7 +821,7 @@ int16 VideoDriverStatus(uint32 pb, uint32 dce)
|
||||
switch (id) {
|
||||
case 0:
|
||||
// Return current resolution
|
||||
id = VidLocal.current_id;
|
||||
id = current_id;
|
||||
break;
|
||||
|
||||
case 0xfffffffe:
|
||||
@ -834,7 +851,7 @@ int16 VideoDriverStatus(uint32 pb, uint32 dce)
|
||||
WriteMacInt32(param + csHorizontalPixels, x);
|
||||
WriteMacInt32(param + csVerticalLines, y);
|
||||
WriteMacInt32(param + csRefreshRate, 75 << 16);
|
||||
WriteMacInt16(param + csMaxDepthMode, DepthToAppleMode(max_depth_of_resolution(id)));
|
||||
WriteMacInt16(param + csMaxDepthMode, depth_to_apple_mode(max_depth_of_resolution(id)));
|
||||
WriteMacInt32(param + csResolutionFlags, 0);
|
||||
return noErr;
|
||||
}
|
||||
@ -843,11 +860,12 @@ int16 VideoDriverStatus(uint32 pb, uint32 dce)
|
||||
uint32 id = ReadMacInt32(param + csDisplayModeID);
|
||||
uint16 mode = ReadMacInt16(param + csDepthMode);
|
||||
D(bug(" GetVideoParameters %04x/%08x\n", mode, id));
|
||||
VidLocal.dm_present = true; // Display Manager seems to be present
|
||||
dm_present = true; // Display Manager seems to be present
|
||||
D(bug(" Display Manager detected\n"));
|
||||
|
||||
vector<video_mode>::const_iterator i, end = VideoModes.end();
|
||||
for (i = VideoModes.begin(); i != end; ++i) {
|
||||
if (DepthToAppleMode(i->depth) == mode && i->resolution_id == id) {
|
||||
vector<video_mode>::const_iterator i, end = modes.end();
|
||||
for (i = modes.begin(); i != end; ++i) {
|
||||
if (depth_to_apple_mode(i->depth) == mode && i->resolution_id == id) {
|
||||
uint32 vp = ReadMacInt32(param + csVPBlockPtr);
|
||||
WriteMacInt32(vp + vpBaseOffset, 0);
|
||||
WriteMacInt16(vp + vpRowBytes, i->bytes_per_row);
|
||||
@ -912,3 +930,17 @@ int16 VideoDriverStatus(uint32 pb, uint32 dce)
|
||||
return statusErr;
|
||||
}
|
||||
}
|
||||
|
||||
int16 VideoDriverStatus(uint32 pb, uint32 dce)
|
||||
{
|
||||
uint8 slot_id = ReadMacInt8(dce + dCtlSlotId);
|
||||
uint16 code = ReadMacInt16(pb + csCode);
|
||||
uint32 param = ReadMacInt32(pb + csParam);
|
||||
D(bug("VideoDriverStatus slot %02x, code %d\n", slot_id, code));
|
||||
|
||||
monitor_desc *m = find_monitor(slot_id);
|
||||
if (m)
|
||||
return m->driver_status(code, param);
|
||||
else
|
||||
return nsDrvErr;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user