mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-11-18 18:05:21 +00:00
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:
parent
dae4fb627c
commit
1be8a821a8
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user