added infrastructure for resolution/depth switching (currently, all video

drivers only support one mode, the one selected by the user)
This commit is contained in:
cebix 2001-06-27 19:03:38 +00:00
parent dae4fb627c
commit 1be8a821a8
8 changed files with 636 additions and 233 deletions

View File

@ -95,6 +95,45 @@ static void periodic_func(void);
* Initialization
*/
// Add resolution to list of supported modes and set VideoMonitor
static void set_video_monitor(uint32 width, uint32 height, uint32 bytes_per_row, int depth)
{
video_mode mode;
mode.x = width;
mode.y = height;
mode.resolution_id = 0x80;
mode.bytes_per_row = bytes_per_row;
switch (depth) {
case 1:
mode.depth = VDEPTH_1BIT;
break;
case 2:
mode.depth = VDEPTH_2BIT;
break;
case 4:
mode.depth = VDEPTH_4BIT;
break;
case 8:
mode.depth = VDEPTH_8BIT;
break;
case 15:
mode.depth = VDEPTH_16BIT;
break;
case 16:
mode.depth = VDEPTH_16BIT;
break;
case 24:
case 32:
mode.depth = VDEPTH_32BIT;
break;
}
VideoModes.push_back(mode);
VideoMonitor.mode = mode;
}
// Open window
static bool init_window(int width, int height)
{
@ -128,12 +167,9 @@ static bool init_window(int width, int height)
return false;
}
// Set VideoMonitor
// Add resolution and set VideoMonitor
set_video_monitor(width, height, the_bitmap->BytesPerRow, 1);
VideoMonitor.mac_frame_base = (uint32)the_bitmap->Planes[0];
VideoMonitor.bytes_per_row = the_bitmap->BytesPerRow;
VideoMonitor.x = width;
VideoMonitor.y = height;
VideoMonitor.mode = VMODE_1BIT;
// Set FgPen and BgPen
black_pen = ObtainBestPenA(the_win->WScreen->ViewPort.ColorMap, 0, 0, 0, NULL);
@ -179,12 +215,9 @@ static bool init_pip(int width, int height)
// Find bitmap
p96PIP_GetTags(the_win, P96PIP_SourceBitMap, (ULONG)&the_bitmap, TAG_END);
// Set VideoMonitor
// Add resolution and set VideoMonitor
set_video_monitor(width, height, p96GetBitMapAttr(the_bitmap, P96BMA_BYTESPERROW), 16);
VideoMonitor.mac_frame_base = p96GetBitMapAttr(the_bitmap, P96BMA_MEMORY);
VideoMonitor.bytes_per_row = p96GetBitMapAttr(the_bitmap, P96BMA_BYTESPERROW);
VideoMonitor.x = width;
VideoMonitor.y = height;
VideoMonitor.mode = VMODE_16BIT;
return true;
}
@ -200,7 +233,6 @@ static bool init_screen_p96(ULONG mode_id)
switch (depth) {
case 8:
VideoMonitor.mode = VMODE_8BIT;
break;
case 15:
case 16:
@ -208,7 +240,6 @@ static bool init_screen_p96(ULONG mode_id)
ErrorAlert(GetString(STR_WRONG_SCREEN_FORMAT_ERR));
return false;
}
VideoMonitor.mode = VMODE_16BIT;
break;
case 24:
case 32:
@ -216,7 +247,6 @@ static bool init_screen_p96(ULONG mode_id)
ErrorAlert(GetString(STR_WRONG_SCREEN_FORMAT_ERR));
return false;
}
VideoMonitor.mode = VMODE_32BIT;
break;
default:
ErrorAlert(GetString(STR_WRONG_SCREEN_DEPTH_ERR));
@ -227,9 +257,6 @@ static bool init_screen_p96(ULONG mode_id)
uint32 width = p96GetModeIDAttr(mode_id, P96IDA_WIDTH);
uint32 height = p96GetModeIDAttr(mode_id, P96IDA_HEIGHT);
VideoMonitor.x = width;
VideoMonitor.y = height;
// Open screen
the_screen = p96OpenScreenTags(
P96SA_DisplayID, mode_id,
@ -262,10 +289,11 @@ static bool init_screen_p96(ULONG mode_id)
return false;
}
// Set VideoMonitor
ScreenToFront(the_screen);
// Add resolution and set VideoMonitor
set_video_monitor(width, height, p96GetBitMapAttr(the_screen->RastPort.BitMap, P96BMA_BYTESPERROW), depth);
VideoMonitor.mac_frame_base = p96GetBitMapAttr(the_screen->RastPort.BitMap, P96BMA_MEMORY);
VideoMonitor.bytes_per_row = p96GetBitMapAttr(the_screen->RastPort.BitMap, P96BMA_BYTESPERROW);
return true;
}
@ -281,7 +309,6 @@ static bool init_screen_cgfx(ULONG mode_id)
switch (depth) {
case 8:
VideoMonitor.mode = VMODE_8BIT;
break;
case 15:
case 16:
@ -290,7 +317,6 @@ static bool init_screen_cgfx(ULONG mode_id)
ErrorAlert(GetString(STR_WRONG_SCREEN_FORMAT_ERR));
return false;
}
VideoMonitor.mode = VMODE_16BIT;
break;
case 24:
case 32:
@ -298,7 +324,6 @@ static bool init_screen_cgfx(ULONG mode_id)
ErrorAlert(GetString(STR_WRONG_SCREEN_FORMAT_ERR));
return false;
}
VideoMonitor.mode = VMODE_32BIT;
break;
default:
ErrorAlert(GetString(STR_WRONG_SCREEN_DEPTH_ERR));
@ -309,9 +334,6 @@ static bool init_screen_cgfx(ULONG mode_id)
uint32 width = GetCyberIDAttr(CYBRIDATTR_WIDTH, mode_id);
uint32 height = GetCyberIDAttr(CYBRIDATTR_HEIGHT, mode_id);
VideoMonitor.x = width;
VideoMonitor.y = height;
// Open screen
the_screen = OpenScreenTags(NULL,
SA_DisplayID, mode_id,
@ -342,15 +364,19 @@ static bool init_screen_cgfx(ULONG mode_id)
return false;
}
// Set VideoMonitor
ScreenToFront(the_screen);
static UWORD ptr[] = { 0, 0, 0, 0 };
SetPointer(the_win, ptr, 0, 0, 0, 0); // Hide mouse pointer
// Set VideoMonitor
ULONG frame_base;
APTR handle = LockBitMapTags(the_screen->RastPort.BitMap,
LBMI_BASEADDRESS, (ULONG)&VideoMonitor.mac_frame_base,
TAG_END);
LBMI_BASEADDRESS, (ULONG)&frame_base,
TAG_END
);
UnLockBitMap(handle);
VideoMonitor.bytes_per_row = GetCyberMapAttr(the_screen->RastPort.BitMap, CYBRMATTR_XMOD);
set_video_monitor(width, height, GetCyberMapAttr(the_screen->RastPort.BitMap, CYBRMATTR_XMOD), depth);
VideoMonitor.mac_frame_base = frame_base;
return true;
}
@ -590,7 +616,7 @@ static __saveds void periodic_func(void)
// Timer tick, update display
BltTemplate(the_bitmap->Planes[0], 0, the_bitmap->BytesPerRow, the_win->RPort,
the_win->BorderLeft, the_win->BorderTop, VideoMonitor.x, VideoMonitor.y);
the_win->BorderLeft, the_win->BorderTop, VideoMonitor.mode.x, VideoMonitor.mode.y);
// Restart timer
timer_io->tr_node.io_Command = TR_ADDREQUEST;
@ -621,8 +647,8 @@ static __saveds void periodic_func(void)
ADBMouseMoved(mx - the_win->BorderLeft, my - the_win->BorderTop);
if (mx < the_win->BorderLeft
|| my < the_win->BorderTop
|| mx >= the_win->BorderLeft + VideoMonitor.x
|| my >= the_win->BorderTop + VideoMonitor.y) {
|| mx >= the_win->BorderLeft + VideoMonitor.mode.x
|| my >= the_win->BorderTop + VideoMonitor.mode.y) {
if (current_pointer) {
ClearPointer(the_win);
current_pointer = NULL;

View File

@ -154,6 +154,7 @@ private:
uint8 *frame_backup; // Frame buffer backup when switching from/to different workspace
bool quitting; // Flag for ScreenConnected: We are quitting, don't pause emulator thread
bool screen_active;
bool first_time;
};
@ -169,6 +170,46 @@ static uint8 MacCursor[68] = {16, 1}; // Mac cursor image
* Initialization
*/
// Add resolution to list of supported modes and set VideoMonitor
static void set_video_monitor(uint32 width, uint32 height, uint32 bytes_per_row, int depth)
{
video_mode mode;
mode.x = width;
mode.y = height;
mode.resolution_id = 0x80;
mode.bytes_per_row = bytes_per_row;
switch (depth) {
case 1:
mode.depth = VDEPTH_1BIT;
break;
case 2:
mode.depth = VDEPTH_2BIT;
break;
case 4:
mode.depth = VDEPTH_4BIT;
break;
case 8:
mode.depth = VDEPTH_8BIT;
break;
case 15:
mode.depth = VDEPTH_16BIT;
break;
case 16:
mode.depth = VDEPTH_16BIT;
break;
case 24:
case 32:
mode.depth = VDEPTH_32BIT;
break;
}
VideoModes.push_back(mode);
VideoMonitor.mode = mode;
}
bool VideoInit(bool classic)
{
// Create semaphore
@ -424,21 +465,18 @@ MacWindow::MacWindow(BRect frame) : BDirectWindow(frame, GetString(STR_WINDOW_TI
the_bitmap = new BBitmap(frame, B_COLOR_8_BIT);
the_buffer = new uint8[x * (y + 2)]; // "y + 2" for safety
// Set VideoMonitor
// Add resolution and set VideoMonitor
set_video_monitor(x, y, x, 8);
#if REAL_ADDRESSING
VideoMonitor.mac_frame_base = (uint32)the_buffer;
#else
VideoMonitor.mac_frame_base = MacFrameBaseMac;
#endif
VideoMonitor.bytes_per_row = x;
VideoMonitor.x = x;
VideoMonitor.y = y;
VideoMonitor.mode = VMODE_8BIT;
#if !REAL_ADDRESSING
// Set variables for UAE memory mapping
MacFrameBaseHost = the_buffer;
MacFrameSize = VideoMonitor.bytes_per_row * VideoMonitor.y;
MacFrameSize = x * y;
MacFrameLayout = FLAYOUT_DIRECT;
#endif
@ -610,10 +648,10 @@ void MacWindow::MessageReceived(BMessage *msg)
// Convert Mac screen buffer to BeOS palette and blit
uint8 *source = the_buffer - 1;
uint8 *dest = (uint8 *)the_bitmap->Bits() - 1;
uint32 length = VideoMonitor.bytes_per_row * VideoMonitor.y;
uint32 length = VideoMonitor.mode.bytes_per_row * VideoMonitor.mode.y;
for (int i=0; i<length; i++)
*++dest = remap_mac_be[*++source];
BRect update_rect = BRect(0, 0, VideoMonitor.x-1, VideoMonitor.y-1);
BRect update_rect = BRect(0, 0, VideoMonitor.mode.x-1, VideoMonitor.mode.y-1);
main_view->DrawBitmapAsync(the_bitmap, update_rect, update_rect);
break;
}
@ -733,8 +771,8 @@ status_t MacWindow::tick_func(void *arg)
uint8 *source = obj->the_buffer - 1;
uint8 *dest = (uint8 *)obj->bits;
uint32 bytes_per_row = obj->bytes_per_row;
int xsize = VideoMonitor.x;
int ysize = VideoMonitor.y;
int xsize = VideoMonitor.mode.x;
int ysize = VideoMonitor.mode.y;
for (int y=0; y<ysize; y++) {
uint32 *p = (uint32 *)dest - 1;
for (int x=0; x<xsize/4; x++) {
@ -795,6 +833,7 @@ MacScreen::MacScreen(const char *name, int mode_bit, status_t *error) : BWindowS
frame_backup = NULL;
palette_changed = false;
screen_active = false;
first_time = true;
quitting = false;
// Set relative mouse mode
@ -856,35 +895,23 @@ void MacScreen::ScreenConnected(bool active)
if (active == true) {
// Add resolution and set VideoMonitor
if (first_time) {
set_video_monitor(info->width, info->height, info->bytes_per_row, info->bits_per_pixel);
first_time = false;
}
// Set VideoMonitor
#if REAL_ADDRESSING
VideoMonitor.mac_frame_base = (uint32)info->frame_buffer;
#else
VideoMonitor.mac_frame_base = MacFrameBaseMac;
#endif
VideoMonitor.bytes_per_row = info->bytes_per_row;
VideoMonitor.x = info->width;
VideoMonitor.y = info->height;
switch (info->bits_per_pixel) {
case 8:
VideoMonitor.mode = VMODE_8BIT;
break;
case 15:
case 16:
VideoMonitor.mode = VMODE_16BIT;
break;
case 32:
VideoMonitor.mode = VMODE_32BIT;
break;
default:
VideoMonitor.mode = VMODE_8BIT;
break;
}
#if !REAL_ADDRESSING
// Set variables for UAE memory mapping
MacFrameBaseHost = (uint8 *)info->frame_buffer;
MacFrameSize = VideoMonitor.bytes_per_row * VideoMonitor.y;
MacFrameSize = VideoMonitor.mode.bytes_per_row * VideoMonitor.mode.y;
switch (info->bits_per_pixel) {
case 15:
MacFrameLayout = FLAYOUT_HOST_555;
@ -903,13 +930,13 @@ void MacScreen::ScreenConnected(bool active)
// Copy from backup store to frame buffer
if (frame_backup != NULL) {
memcpy(info->frame_buffer, frame_backup, VideoMonitor.bytes_per_row * VideoMonitor.y);
memcpy(info->frame_buffer, frame_backup, VideoMonitor.bytes_per_row * VideoMonitor.mode.y);
delete[] frame_backup;
frame_backup = NULL;
}
// Restore palette
if (VideoMonitor.mode == VMODE_8BIT)
if (VideoMonitor.depth == VDEPTH_8BIT)
SetColorList(palette);
// Restart/signal emulator thread
@ -923,8 +950,8 @@ void MacScreen::ScreenConnected(bool active)
acquire_sem(mac_os_lock);
// Create backup store and save frame buffer
frame_backup = new uint8[VideoMonitor.bytes_per_row * VideoMonitor.y];
memcpy(frame_backup, info->frame_buffer, VideoMonitor.bytes_per_row * VideoMonitor.y);
frame_backup = new uint8[VideoMonitor.mode.bytes_per_row * VideoMonitor.mode.y];
memcpy(frame_backup, info->frame_buffer, VideoMonitor.mode.bytes_per_row * VideoMonitor.mode.y);
}
}
}

View File

@ -127,15 +127,15 @@ static inline void update_display_window_vosf(void)
const int y2 = mainBuffer.pageInfo[page - 1].bottom;
const int height = y2 - y1 + 1;
const int bytes_per_row = VideoMonitor.bytes_per_row;
const int bytes_per_pixel = VideoMonitor.bytes_per_row / VideoMonitor.x;
const int bytes_per_row = VideoMonitor.mode.bytes_per_row;
const int bytes_per_pixel = VideoMonitor.mode.bytes_per_row / VideoMonitor.mode.x;
int i = y1 * bytes_per_row, j;
if (depth == 1) {
// Update the_host_buffer and copy of the_buffer
for (j = y1; j <= y2; j++) {
Screen_blit(the_host_buffer + i, the_buffer + i, VideoMonitor.x >> 3);
Screen_blit(the_host_buffer + i, the_buffer + i, VideoMonitor.mode.x >> 3);
i += bytes_per_row;
}
@ -143,15 +143,15 @@ static inline void update_display_window_vosf(void)
// Update the_host_buffer and copy of the_buffer
for (j = y1; j <= y2; j++) {
Screen_blit(the_host_buffer + i, the_buffer + i, bytes_per_pixel * VideoMonitor.x);
Screen_blit(the_host_buffer + i, the_buffer + i, bytes_per_pixel * VideoMonitor.mode.x);
i += bytes_per_row;
}
}
if (have_shm)
XShmPutImage(x_display, the_win, the_gc, img, 0, y1, 0, y1, VideoMonitor.x, height, 0);
XShmPutImage(x_display, the_win, the_gc, img, 0, y1, 0, y1, VideoMonitor.mode.x, height, 0);
else
XPutImage(x_display, the_win, the_gc, img, 0, y1, 0, y1, VideoMonitor.x, height);
XPutImage(x_display, the_win, the_gc, img, 0, y1, 0, y1, VideoMonitor.mode.x, height);
}
mainBuffer.dirty = false;
@ -184,13 +184,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.bytes_per_row;
const int bytes_per_pixel = VideoMonitor.bytes_per_row / VideoMonitor.x;
const int bytes_per_row = VideoMonitor.mode.bytes_per_row;
const int bytes_per_pixel = VideoMonitor.mode.bytes_per_row / VideoMonitor.mode.x;
int i, j;
// Check for first column from left and first column
// from right that have changed
int x1 = VideoMonitor.x * bytes_per_pixel - 1;
int x1 = VideoMonitor.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];
@ -207,7 +207,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.x * bytes_per_pixel - 1; i > x2; i--) {
for (i = VideoMonitor.mode.x * bytes_per_pixel - 1; i > x2; i--) {
if (p1[i] != p2[i]) {
x2 = i;
break;

View File

@ -325,9 +325,10 @@ extern void SysMountFirstFloppy(void);
* Initialization
*/
// Set VideoMonitor according to video mode
void set_video_monitor(int width, int height, int bytes_per_row, bool native_byte_order)
// Add resolution to list of supported modes and set VideoMonitor
static void set_video_monitor(uint32 width, uint32 height, uint32 bytes_per_row, bool native_byte_order)
{
video_mode mode;
#if !REAL_ADDRESSING && !DIRECT_ADDRESSING
int layout = FLAYOUT_DIRECT;
switch (depth) {
@ -353,27 +354,39 @@ void set_video_monitor(int width, int height, int bytes_per_row, bool native_byt
else
MacFrameLayout = FLAYOUT_DIRECT;
#endif
mode.x = width;
mode.y = height;
mode.resolution_id = 0x80;
mode.bytes_per_row = bytes_per_row;
switch (depth) {
case 1:
VideoMonitor.mode = VMODE_1BIT;
mode.depth = VDEPTH_1BIT;
break;
case 2:
mode.depth = VDEPTH_2BIT;
break;
case 4:
mode.depth = VDEPTH_4BIT;
break;
case 8:
VideoMonitor.mode = VMODE_8BIT;
mode.depth = VDEPTH_8BIT;
break;
case 15:
VideoMonitor.mode = VMODE_16BIT;
mode.depth = VDEPTH_16BIT;
break;
case 16:
VideoMonitor.mode = VMODE_16BIT;
mode.depth = VDEPTH_16BIT;
break;
case 24:
case 32:
VideoMonitor.mode = VMODE_32BIT;
mode.depth = VDEPTH_32BIT;
break;
}
VideoMonitor.x = width;
VideoMonitor.y = height;
VideoMonitor.bytes_per_row = bytes_per_row;
VideoModes.push_back(mode);
VideoMonitor.mode = mode;
}
// Set window name and class
@ -566,7 +579,7 @@ static bool init_window(int width, int height)
&black, &white, 0, 0);
XDefineCursor(x_display, the_win, mac_cursor);
// Set VideoMonitor
// Add resolution and set VideoMonitor
bool native_byte_order;
#ifdef WORDS_BIGENDIAN
native_byte_order = (XImageByteOrder(x_display) == MSBFirst);
@ -955,13 +968,13 @@ bool VideoInitBuffer()
uint32 a = 0;
for (int i = 0; i < mainBuffer.pageCount; i++) {
int y1 = a / VideoMonitor.bytes_per_row;
if (y1 >= VideoMonitor.y)
y1 = VideoMonitor.y - 1;
int y1 = a / VideoMonitor.mode.bytes_per_row;
if (y1 >= VideoMonitor.mode.y)
y1 = VideoMonitor.mode.y - 1;
int y2 = (a + mainBuffer.pageSize) / VideoMonitor.bytes_per_row;
if (y2 >= VideoMonitor.y)
y2 = VideoMonitor.y - 1;
int y2 = (a + mainBuffer.pageSize) / VideoMonitor.mode.bytes_per_row;
if (y2 >= VideoMonitor.mode.y)
y2 = VideoMonitor.mode.y - 1;
mainBuffer.pageInfo[i].top = y1;
mainBuffer.pageInfo[i].bottom = y2;
@ -1148,7 +1161,7 @@ bool VideoInit(bool classic)
#if !REAL_ADDRESSING && !DIRECT_ADDRESSING
// Set variables for UAE memory mapping
MacFrameBaseHost = the_buffer;
MacFrameSize = VideoMonitor.bytes_per_row * VideoMonitor.y;
MacFrameSize = VideoMonitor.mode.bytes_per_row * VideoMonitor.mode.y;
// No special frame buffer in Classic mode (frame buffer is in Mac RAM)
if (classic)
@ -1359,9 +1372,9 @@ static void suspend_emul(void)
LOCK_FRAME_BUFFER;
// Save frame buffer
fb_save = malloc(VideoMonitor.y * VideoMonitor.bytes_per_row);
fb_save = malloc(VideoMonitor.mode.y * VideoMonitor.mode.bytes_per_row);
if (fb_save)
memcpy(fb_save, the_buffer, VideoMonitor.y * VideoMonitor.bytes_per_row);
memcpy(fb_save, the_buffer, VideoMonitor.mode.y * VideoMonitor.mode.bytes_per_row);
// Close full screen display
#ifdef ENABLE_XF86_DGA
@ -1412,7 +1425,7 @@ static void resume_emul(void)
LOCK_VOSF;
PFLAG_SET_ALL;
UNLOCK_VOSF;
memset(the_buffer_copy, 0, VideoMonitor.bytes_per_row * VideoMonitor.y);
memset(the_buffer_copy, 0, VideoMonitor.mode.bytes_per_row * VideoMonitor.mode.y);
}
#endif
@ -1422,7 +1435,7 @@ static void resume_emul(void)
// Don't copy fb_save to the temporary frame buffer in VOSF mode
if (!use_vosf)
#endif
memcpy(the_buffer, fb_save, VideoMonitor.y * VideoMonitor.bytes_per_row);
memcpy(the_buffer, fb_save, VideoMonitor.mode.y * VideoMonitor.mode.bytes_per_row);
free(fb_save);
fb_save = NULL;
}
@ -1703,7 +1716,7 @@ static void handle_events(void)
LOCK_VOSF;
PFLAG_SET_ALL;
UNLOCK_VOSF;
memset(the_buffer_copy, 0, VideoMonitor.bytes_per_row * VideoMonitor.y);
memset(the_buffer_copy, 0, VideoMonitor.mode.bytes_per_row * VideoMonitor.mode.y);
}
else
#endif
@ -1714,7 +1727,7 @@ static void handle_events(void)
updt_box[x1][y1] = true;
nr_boxes = 16 * 16;
} else // Static refresh
memset(the_buffer_copy, 0, VideoMonitor.bytes_per_row * VideoMonitor.y);
memset(the_buffer_copy, 0, VideoMonitor.mode.bytes_per_row * VideoMonitor.mode.y);
}
break;
@ -1740,10 +1753,10 @@ static void update_display_dynamic(int ticker)
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.bytes_per_row;
int bytes_per_pixel = VideoMonitor.bytes_per_row / VideoMonitor.x;
int rx = VideoMonitor.bytes_per_row / 16;
int ry = VideoMonitor.y / 16;
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;
int max_box;
y2s = sm_uptd[ticker % 8];
@ -1829,20 +1842,20 @@ static void update_display_static(void)
{
// Incremental update code
int wide = 0, high = 0, x1, x2, y1, y2, i, j;
int bytes_per_row = VideoMonitor.bytes_per_row;
int bytes_per_pixel = VideoMonitor.bytes_per_row / VideoMonitor.x;
int bytes_per_row = VideoMonitor.mode.bytes_per_row;
int bytes_per_pixel = VideoMonitor.mode.bytes_per_row / VideoMonitor.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.y; j++) {
for (j=0; j<VideoMonitor.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.y-1; j>=y1; j--) {
for (j=VideoMonitor.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;
@ -1853,7 +1866,7 @@ static void update_display_static(void)
// Check for first column from left and first column from right that have changed
if (high) {
if (depth == 1) {
x1 = VideoMonitor.x - 1;
x1 = VideoMonitor.mode.x - 1;
for (j=y1; j<=y2; j++) {
p = &the_buffer[j * bytes_per_row];
p2 = &the_buffer_copy[j * bytes_per_row];
@ -1871,7 +1884,7 @@ static void update_display_static(void)
p2 = &the_buffer_copy[j * bytes_per_row];
p += bytes_per_row;
p2 += bytes_per_row;
for (i=(VideoMonitor.x>>3); i>(x2>>3); i--) {
for (i=(VideoMonitor.mode.x>>3); i>(x2>>3); i--) {
p--; p2--;
if (*p != *p2) {
x2 = (i << 3) + 7;
@ -1890,7 +1903,7 @@ static void update_display_static(void)
}
} else {
x1 = VideoMonitor.x;
x1 = VideoMonitor.mode.x;
for (j=y1; j<=y2; j++) {
p = &the_buffer[j * bytes_per_row];
p2 = &the_buffer_copy[j * bytes_per_row];
@ -1908,7 +1921,7 @@ static void update_display_static(void)
p2 = &the_buffer_copy[j * bytes_per_row];
p += bytes_per_row;
p2 += bytes_per_row;
for (i=VideoMonitor.x*bytes_per_pixel; i>x2*bytes_per_pixel; i--) {
for (i=VideoMonitor.mode.x*bytes_per_pixel; i>x2*bytes_per_pixel; i--) {
p--;
p2--;
if (*p != *p2) {

View File

@ -21,27 +21,57 @@
#ifndef VIDEO_H
#define VIDEO_H
// Description for one (possibly virtual) monitor
enum {
VMODE_1BIT,
VMODE_2BIT,
VMODE_4BIT,
VMODE_8BIT,
VMODE_16BIT,
VMODE_32BIT
#include <vector>
// Color depth codes
enum video_depth {
VDEPTH_1BIT, // 2 colors
VDEPTH_2BIT, // 4 colors
VDEPTH_4BIT, // 16 colors
VDEPTH_8BIT, // 256 colors
VDEPTH_16BIT, // "Thousands"
VDEPTH_32BIT // "Millions"
};
#define IsDirectMode(x) ((x) == VMODE_16BIT || (x) == VMODE_32BIT)
inline bool IsDirectMode(video_depth depth)
{
return depth == VDEPTH_16BIT || depth == VDEPTH_32BIT;
}
struct video_desc {
uint32 mac_frame_base; // Mac frame buffer address
uint32 bytes_per_row; // Bytes per row
inline uint16 DepthToAppleMode(video_depth depth)
{
return depth + 0x80;
}
inline video_depth AppleModeToDepth(uint16 mode)
{
return video_depth(mode - 0x80);
}
// Description of one video mode
struct video_mode {
uint32 x; // X size of screen (pixels)
uint32 y; // Y size of screen (pixels)
int mode; // Video mode
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)
};
extern struct video_desc VideoMonitor; // Description of the main monitor, set by VideoInit()
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
};
extern monitor_desc VideoMonitor; // Description of the main monitor, set by VideoInit()
extern int16 VideoDriverOpen(uint32 pb, uint32 dce);
extern int16 VideoDriverControl(uint32 pb, uint32 dce);

View File

@ -108,12 +108,38 @@ enum { // VDTimingInfo struct
csTimingFlags = 16
};
enum { // VDPageInfo struct
csPageMode = 0,
csPageData = 2,
csPagePage = 6,
csPageBaseAddr = 8
enum { // VDResolutionInfo struct
csPreviousDisplayModeID = 0,
csRIDisplayModeID = 4,
csHorizontalPixels = 8,
csVerticalLines = 12,
csRefreshRate = 16,
csMaxDepthMode = 20,
csResolutionFlags = 22
};
enum { // VDVideoParametersInfo struct
csDisplayModeID = 0,
csDepthMode = 4,
csVPBlockPtr = 6,
csPageCount = 10,
csDeviceType = 14
};
enum { // VPBlock struct
vpBaseOffset = 0,
vpRowBytes = 4,
vpBounds = 6,
vpVersion = 14,
vpPackType = 16,
vpPackSize = 18,
vpHRes = 22,
vpVRes = 26,
vpPixelType = 30,
vpPixelSize = 32,
vpCmpCount = 34,
vpCmpSize = 36,
vpPlaneBytes = 38
};
#endif

View File

@ -102,13 +102,83 @@ static void PString(char *str)
srom[p++] = 0;
}
static uint32 VModeParms(uint32 width, uint32 height, uint32 bytes_per_row, video_depth depth)
{
uint32 ret = p;
Long(50); // Length
Long(0); // Base offset
Word(bytes_per_row); // Row bytes
Word(0); // Bounds
Word(0);
Word(height);
Word(width);
Word(0); // Version
Word(0); // Pack type
Long(0); // Pack size
Long(0x00480000); // HRes
Long(0x00480000); // VRes
switch (depth) {
case VDEPTH_1BIT:
Word(0); // Pixel type (indirect)
Word(1); // Pixel size
Word(1); // CmpCount
Word(1); // CmpSize
break;
case VDEPTH_2BIT:
Word(0); // Pixel type (indirect)
Word(2); // Pixel size
Word(1); // CmpCount
Word(2); // CmpSize
break;
case VDEPTH_4BIT:
Word(0); // Pixel type (indirect)
Word(4); // Pixel size
Word(1); // CmpCount
Word(4); // CmpSize
break;
case VDEPTH_8BIT:
Word(0); // Pixel type (indirect)
Word(8); // Pixel size
Word(1); // CmpCount
Word(8); // CmpSize
break;
case VDEPTH_16BIT:
Word(16); // Pixel type (direct)
Word(16); // Pixel size
Word(3); // CmpCount
Word(5); // CmpSize
break;
case VDEPTH_32BIT:
Word(16); // Pixel type (direct)
Word(32); // Pixel size
Word(3); // CmpCount
Word(8); // CmpSize
break;
}
Long(0); // Plane size
Long(0); // Reserved
return ret;
}
static uint32 VModeDesc(uint32 params, bool direct)
{
uint32 ret = p;
Offs(0x01, params); // Video parameters
Rsrc(0x03, 1); // Page count
Rsrc(0x04, direct ? 2 : 0); // Device type
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, vidModeParms, vidMode, sRsrcVideo;
uint32 defaultGamma, gammaDir, sRsrcVideo;
uint32 vidModeParms1, vidModeParms2, vidModeParms4, vidModeParms8, vidModeParms16, vidModeParms32;
uint32 vidMode1, vidMode2, vidMode4, vidMode8, vidMode16, vidMode32;
uint32 cpuType, cpuName, cpuMajor, cpuMinor, sRsrcCPU;
@ -148,7 +218,7 @@ bool InstallSlotROM(void)
Offs(0x24, vendorInfo); // Vendor Info
EndOfList();
// Video sResource
// Video sResource for default mode
videoType = p; // Literals
Word(3); Word(1); Word(1); Word(0x4232); // Display Video Apple 'B2'
videoName = p;
@ -156,7 +226,7 @@ bool InstallSlotROM(void)
minorBase = p;
Long(VideoMonitor.mac_frame_base); // Frame buffer base
minorLength = p;
Long(VideoMonitor.bytes_per_row * VideoMonitor.y); // Frame buffer size
Long(VideoMonitor.mode.bytes_per_row * VideoMonitor.mode.y); // Frame buffer size
videoDrvr = p; // Video driver
Long(0x72); // Length
@ -229,65 +299,19 @@ bool InstallSlotROM(void)
Offs(0x80, defaultGamma);
EndOfList();
vidModeParms = p; // Video mode parameters
Long(50); // Length
Long(0); // Base offset
Word(VideoMonitor.bytes_per_row); // Row bytes
Word(0); // Bounds
Word(0);
Word(VideoMonitor.y);
Word(VideoMonitor.x);
Word(0); // Version
Word(0); // Pack type
Long(0); // Pack size
Long(0x00480000); // HRes
Long(0x00480000); // VRes
switch (VideoMonitor.mode) {
case VMODE_1BIT:
Word(0); // Pixel type (indirect)
Word(1); // Pixel size
Word(1); // CmpCount
Word(1); // CmpSize
break;
case VMODE_2BIT:
Word(0); // Pixel type (indirect)
Word(2); // Pixel size
Word(1); // CmpCount
Word(2); // CmpSize
break;
case VMODE_4BIT:
Word(0); // Pixel type (indirect)
Word(4); // Pixel size
Word(1); // CmpCount
Word(4); // CmpSize
break;
case VMODE_8BIT:
Word(0); // Pixel type (indirect)
Word(8); // Pixel size
Word(1); // CmpCount
Word(8); // CmpSize
break;
case VMODE_16BIT:
Word(16); // Pixel type (direct)
Word(16); // Pixel size
Word(3); // CmpCount
Word(5); // CmpSize
break;
case VMODE_32BIT:
Word(16); // Pixel type (direct)
Word(32); // Pixel size
Word(3); // CmpCount
Word(8); // CmpSize
break;
}
Long(0); // Plane size
Long(0); // Reserved
vidModeParms1 = VModeParms(VideoMonitor.mode.x, VideoMonitor.mode.y, VideoMonitor.mode.bytes_per_row, VDEPTH_1BIT);
vidModeParms2 = VModeParms(VideoMonitor.mode.x, VideoMonitor.mode.y, VideoMonitor.mode.bytes_per_row, VDEPTH_2BIT);
vidModeParms4 = VModeParms(VideoMonitor.mode.x, VideoMonitor.mode.y, VideoMonitor.mode.bytes_per_row, VDEPTH_4BIT);
vidModeParms8 = VModeParms(VideoMonitor.mode.x, VideoMonitor.mode.y, VideoMonitor.mode.bytes_per_row, VDEPTH_8BIT);
vidModeParms16 = VModeParms(VideoMonitor.mode.x, VideoMonitor.mode.y, VideoMonitor.mode.bytes_per_row, VDEPTH_16BIT);
vidModeParms32 = VModeParms(VideoMonitor.mode.x, VideoMonitor.mode.y, VideoMonitor.mode.bytes_per_row, VDEPTH_32BIT);
vidMode = p; // Video mode description
Offs(0x01, vidModeParms); // Video parameters
Rsrc(0x03, 1); // Page count
Rsrc(0x04, IsDirectMode(VideoMonitor.mode) ? 2 :0); // Device type
EndOfList();
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
@ -298,7 +322,35 @@ bool InstallSlotROM(void)
Offs(0x0b, minorLength); // Frame buffer length
Offs(0x40, gammaDir); // Gamma directory
Rsrc(0x7d, 6); // Video attributes: Default to color, built-in
Offs(0x80, vidMode); // Video mode parameters
#if 0
Offs(0x80, vidMode1); // Video mode parameters for 1 bit
Offs(0x81, vidMode2); // Video mode parameters for 2 bit
Offs(0x82, vidMode4); // Video mode parameters for 4 bit
Offs(0x83, vidMode8); // Video mode parameters for 8 bit
Offs(0x84, vidMode16); // Video mode parameters for 16 bit
Offs(0x85, vidMode32); // Video mode parameters for 32 bit
#else
switch (VideoMonitor.mode.depth) {
case VDEPTH_1BIT:
Offs(0x80, vidMode1); // Video mode parameters
break;
case VDEPTH_2BIT:
Offs(0x80, vidMode2); // Video mode parameters
break;
case VDEPTH_4BIT:
Offs(0x80, vidMode4); // Video mode parameters
break;
case VDEPTH_8BIT:
Offs(0x80, vidMode8); // Video mode parameters
break;
case VDEPTH_16BIT:
Offs(0x80, vidMode16); // Video mode parameters
break;
case VDEPTH_32BIT:
Offs(0x80, vidMode32); // Video mode parameters
break;
}
#endif
EndOfList();
// CPU sResource

View File

@ -38,18 +38,76 @@
#include "debug.h"
// List of supported video modes
vector<video_mode> VideoModes;
// Description of the main monitor
video_desc VideoMonitor;
monitor_desc VideoMonitor;
// Local variables (per monitor)
struct {
video_desc *desc; // Pointer to monitor description
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
uint16 current_mode; // Currently selected depth/resolution
uint32 current_id;
uint16 preferred_mode; // Preferred depth/resolution
uint32 preferred_id;
} VidLocal;
/*
* Check whether specified resolution ID is one of the supported resolutions
*/
static bool has_resolution(uint32 id)
{
vector<video_mode>::const_iterator i = VideoModes.begin(), end = VideoModes.end();
while (i != end) {
if (i->resolution_id == id)
return true;
++i;
}
return false;
}
/*
* 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 = VideoModes.begin(), end = VideoModes.end();
while (i != end) {
if (i->depth > m)
m = i->depth;
++i;
}
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 = VideoModes.begin(), end = VideoModes.end();
while (i != end) {
if (i->resolution_id == id) {
x = i->x;
y = i->y;
return;
}
++i;
}
}
/*
* Driver Open() routine
*/
@ -58,10 +116,18 @@ int16 VideoDriverOpen(uint32 pb, uint32 dce)
{
D(bug("VideoDriverOpen\n"));
// This shouldn't happen unless the platform-specific video code is broken
if (VideoModes.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;
// Init color palette (solid gray)
if (!IsDirectMode(VidLocal.desc->mode)) {
@ -87,10 +153,17 @@ int16 VideoDriverControl(uint32 pb, uint32 dce)
D(bug("VideoDriverControl %d\n", code));
switch (code) {
case cscSetMode: // Set color depth
D(bug(" SetMode %04x\n", ReadMacInt16(param + csMode)));
case cscSetMode: { // Set color depth
uint16 mode = ReadMacInt16(param + csMode);
D(bug(" SetMode %04x\n", mode));
//!! switch mode
WriteMacInt32(param + csBaseAddr, VidLocal.desc->mac_frame_base);
return noErr;
//!! VidLocal.current_mode = mode;
if (mode != VidLocal.current_mode)
return paramErr;
else
return noErr;
}
case cscSetEntries: { // Set palette
D(bug(" SetEntries table %08lx, count %d, start %d\n", ReadMacInt32(param + csTable), ReadMacInt16(param + csCount), ReadMacInt16(param + csStart)));
@ -136,6 +209,7 @@ int16 VideoDriverControl(uint32 pb, uint32 dce)
case cscSetGamma: // Set gamma table
D(bug(" SetGamma\n"));
//!!
return noErr;
case cscGrayPage: { // Fill page with dithered gray pattern
@ -152,14 +226,14 @@ int16 VideoDriverControl(uint32 pb, uint32 dce)
0xffffffff // 32 bpp
};
uint32 p = VidLocal.desc->mac_frame_base;
uint32 pat = pattern[VidLocal.desc->mode];
for (uint32 y=0; y<VidLocal.desc->y; y++) {
for (uint32 x=0; x<VidLocal.desc->bytes_per_row; x+=4) {
uint32 pat = pattern[VidLocal.desc->mode.depth];
for (uint32 y=0; y<VidLocal.desc->mode.y; y++) {
for (uint32 x=0; x<VidLocal.desc->mode.bytes_per_row; x+=4) {
WriteMacInt32(p + x, pat);
if (VidLocal.desc->mode == VMODE_32BIT)
if (VidLocal.desc->mode.depth == VDEPTH_32BIT)
pat = ~pat;
}
p += VidLocal.desc->bytes_per_row;
p += VidLocal.desc->mode.bytes_per_row;
pat = ~pat;
}
return noErr;
@ -170,16 +244,43 @@ int16 VideoDriverControl(uint32 pb, uint32 dce)
VidLocal.luminance_mapping = ReadMacInt8(param + csMode);
return noErr;
case cscSwitchMode: // Switch video mode
D(bug(" SwitchMode %04x, %08lx\n", ReadMacInt16(param + csMode), ReadMacInt32(param + csData)));
WriteMacInt32(param + csBaseAddr, VidLocal.desc->mac_frame_base);
return noErr;
case cscSetInterrupt: // Enable/disable VBL
D(bug(" SetInterrupt %02x\n", ReadMacInt8(param + csMode)));
VidLocal.interrupts_enabled = (ReadMacInt8(param + csMode) == 0);
return noErr;
// case cscDirectSetEntries:
case cscSetDefaultMode: { // Set default color depth
uint16 mode = ReadMacInt16(param + csMode);
D(bug(" SetDefaultMode %04x\n", mode));
VidLocal.preferred_mode = mode;
return noErr;
}
case cscSwitchMode: { // Switch video mode (depth and resolution)
uint16 mode = ReadMacInt16(param + csMode);
uint32 id = ReadMacInt32(param + csData);
D(bug(" SwitchMode %04x, %08x\n", mode, id));
//!! switch mode
WriteMacInt32(param + csBaseAddr, VidLocal.desc->mac_frame_base);
//!! VidLocal.current_mode = mode;
//!! VidLocal.current_id = id;
if (mode != VidLocal.current_mode || id != VidLocal.current_id)
return paramErr;
else
return noErr;
}
case cscSavePreferredConfiguration: {
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;
return noErr;
}
default:
printf("WARNING: Unknown VideoDriverControl(%d)\n", code);
return controlErr;
@ -198,35 +299,46 @@ int16 VideoDriverStatus(uint32 pb, uint32 dce)
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);
WriteMacInt16(param + csPage, 0);
WriteMacInt32(param + csBaseAddr, VidLocal.desc->mac_frame_base);
return noErr;
// case cscGetEntries:
case cscGetPageCnt: // Get number of pages
D(bug(" GetPageCnt\n"));
D(bug(" GetPageCnt -> 1\n"));
WriteMacInt16(param + csPage, 1);
return noErr;
case cscGetPageBase: // Get page base address
D(bug(" GetPageBase\n"));
D(bug(" GetPageBase -> %08x\n", VidLocal.desc->mac_frame_base));
WriteMacInt32(param + csBaseAddr, VidLocal.desc->mac_frame_base);
return noErr;
case cscGetGray: // Get luminance mapping flag
D(bug(" GetGray\n"));
WriteMacInt8(param + csMode, VidLocal.luminance_mapping ? 1 : 0);
D(bug(" GetGray -> %d\n", VidLocal.luminance_mapping));
WriteMacInt8(param, VidLocal.luminance_mapping ? 1 : 0);
return noErr;
case cscGetInterrupt: // Get interrupt disable flag
D(bug(" GetInterrupt\n"));
WriteMacInt8(param + csMode, VidLocal.interrupts_enabled ? 0 : 1);
D(bug(" GetInterrupt -> %d\n", VidLocal.interrupts_enabled));
WriteMacInt8(param, VidLocal.interrupts_enabled ? 0 : 1);
return noErr;
case cscGetDefaultMode: // Get default video mode
D(bug(" GetDefaultMode\n"));
WriteMacInt8(param + csMode, 0x80);
// case cscGetGamma:
case cscGetDefaultMode: // Get default color depth
D(bug(" GetDefaultMode -> %04x\n", VidLocal.preferred_mode));
WriteMacInt16(param + csMode, VidLocal.preferred_mode);
return noErr;
case cscGetCurMode: // Get current video mode
D(bug(" GetCurMode\n"));
WriteMacInt16(param + csMode, 0x80);
WriteMacInt32(param + csData, 0x80);
case cscGetCurMode: // Get current video mode (depth and resolution)
D(bug(" GetCurMode -> %04x/%08x\n", VidLocal.current_mode, VidLocal.current_id));
WriteMacInt16(param + csMode, VidLocal.current_mode);
WriteMacInt32(param + csData, VidLocal.current_id);
WriteMacInt16(param + csPage, 0);
WriteMacInt32(param + csBaseAddr, VidLocal.desc->mac_frame_base);
return noErr;
@ -240,26 +352,143 @@ int16 VideoDriverStatus(uint32 pb, uint32 dce)
WriteMacInt32(param + csDisplayComponent, 0);
return noErr;
case cscGetModeTiming: // Get video timing for mode
D(bug(" GetModeTiming mode %08lx\n", ReadMacInt32(param + csTimingMode)));
WriteMacInt32(param + csTimingFormat, FOURCC('d', 'e', 'c', 'l'));
WriteMacInt32(param + csTimingData, 220); // 21" Multiscan
WriteMacInt32(param + csTimingFlags, 0x0f); // Mode valid, safe, default and shown in Monitors panel
return noErr;
case cscGetModeBaseAddress: // Get frame buffer base address
D(bug(" GetModeBaseAddress\n"));
D(bug(" GetModeBaseAddress -> %08x\n", VidLocal.desc->mac_frame_base));
WriteMacInt32(param + csBaseAddr, VidLocal.desc->mac_frame_base); // Base address of video RAM for the current DisplayModeID and relative bit depth
return noErr;
case cscGetMode: // REQUIRED for MacsBug
D(bug(" GetMode\n"));
WriteMacInt16(param + csPageMode, 0x80);
WriteMacInt32(param + csPageData, 0x80); // Unused
WriteMacInt16(param + csPagePage, 0); // Current display page
WriteMacInt32(param + csPageBaseAddr, VidLocal.desc->mac_frame_base);
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);
return noErr;
case cscGetNextResolution: { // Called iteratively to obtain a list of all supported resolutions
uint32 id = ReadMacInt32(param + csPreviousDisplayModeID);
D(bug(" GetNextResolution %08x\n", id));
switch (id) {
case 0:
// Return current resolution
id = VidLocal.current_id;
break;
case 0xfffffffe:
// Return first supported resolution
id = 0x80;
while (!has_resolution(id))
id++;
break;
default:
// Get next resolution
if (!has_resolution(id))
return paramErr;
id++;
while (!has_resolution(id) && id < 0x100)
id++;
if (id == 0x100) { // No more resolutions
WriteMacInt32(param + csRIDisplayModeID, 0xfffffffd);
return noErr;
}
break;
}
WriteMacInt32(param + csRIDisplayModeID, id);
uint32 x, y;
get_size_of_resolution(id, x, y);
WriteMacInt32(param + csHorizontalPixels, x);
WriteMacInt32(param + csVerticalLines, y);
WriteMacInt32(param + csRefreshRate, 75 << 16);
WriteMacInt16(param + csMaxDepthMode, DepthToAppleMode(max_depth_of_resolution(id)));
uint32 flags = 0xb; // mode valid, safe and shown in Monitors panel
if (id == VidLocal.preferred_id)
flags |= 4; // default mode
WriteMacInt32(param + csResolutionFlags, flags);
return noErr;
}
case cscGetVideoParameters: { // Get information about specified resolution/depth
uint32 id = ReadMacInt32(param + csDisplayModeID);
uint16 mode = ReadMacInt16(param + csDepthMode);
D(bug(" GetVideoParameters %04x/%08x\n", mode, id));
vector<video_mode>::const_iterator i = VideoModes.begin(), end = VideoModes.end();
while (i != end) {
if (DepthToAppleMode(i->depth) == mode && i->resolution_id == id) {
uint32 vp = ReadMacInt32(param + csVPBlockPtr);
WriteMacInt32(vp + vpBaseOffset, 0);
WriteMacInt16(vp + vpRowBytes, i->bytes_per_row);
WriteMacInt16(vp + vpBounds, 0);
WriteMacInt16(vp + vpBounds + 2, 0);
WriteMacInt16(vp + vpBounds + 4, i->y);
WriteMacInt16(vp + vpBounds + 6, i->x);
WriteMacInt16(vp + vpVersion, 0);
WriteMacInt16(vp + vpPackType, 0);
WriteMacInt32(vp + vpPackSize, 0);
WriteMacInt32(vp + vpHRes, 0x00480000);
WriteMacInt32(vp + vpVRes, 0x00480000);
uint32 pix_type, pix_size, cmp_count, cmp_size, dev_type;
switch (i->depth) {
case VDEPTH_1BIT:
pix_type = 0; pix_size = 1;
cmp_count = 1; cmp_size = 1;
dev_type = 0; // CLUT
break;
case VDEPTH_2BIT:
pix_type = 0; pix_size = 2;
cmp_count = 1; cmp_size = 2;
dev_type = 0; // CLUT
break;
case VDEPTH_4BIT:
pix_type = 0; pix_size = 4;
cmp_count = 1; cmp_size = 4;
dev_type = 0; // CLUT
break;
case VDEPTH_8BIT:
pix_type = 0; pix_size = 8;
cmp_count = 1; cmp_size = 8;
dev_type = 0; // CLUT
break;
case VDEPTH_16BIT:
pix_type = 0x10; pix_size = 16;
cmp_count = 3; cmp_size = 5;
dev_type = 2; // direct
break;
case VDEPTH_32BIT:
pix_type = 0x10; pix_size = 32;
cmp_count = 3; cmp_size = 8;
dev_type = 2; // direct
break;
}
WriteMacInt16(vp + vpPixelType, pix_type);
WriteMacInt16(vp + vpPixelSize, pix_size);
WriteMacInt16(vp + vpCmpCount, cmp_count);
WriteMacInt16(vp + vpCmpSize, cmp_size);
WriteMacInt32(param + csPageCount, 1);
WriteMacInt32(param + csDeviceType, dev_type);
return noErr;
}
++i;
}
return paramErr; // specified resolution/depth not supported
}
case cscGetModeTiming: { // Get video timing for specified resolution
uint32 id = ReadMacInt32(param + csTimingMode);
D(bug(" GetModeTiming %08x\n", id));
if (!has_resolution(id))
return paramErr;
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)
flags |= 4; // default mode
WriteMacInt32(param + csTimingFlags, flags);
return noErr;
}
default:
printf("WARNING: Unknown VideoDriverStatus(%d)\n", code);
return statusErr;