From af35353cf077ebd65f4a633df5df1db3e0f61562 Mon Sep 17 00:00:00 2001 From: cebix <> Date: Sun, 1 Jul 2001 14:38:03 +0000 Subject: [PATCH] - sony.cpp/disk.cpp/cdrom.cpp use vector<> of drive_info objects instead of linked list - color depth switching updates slot ROM - video_x.cpp always supports 1-bit window modes - timer_create()/clock_gettime() are pulled from librt if present --- BasiliskII/src/Unix/configure.in | 1 + BasiliskII/src/Unix/video_blit.cpp | 87 +++++++++------- BasiliskII/src/Unix/video_vosf.h | 2 +- BasiliskII/src/Unix/video_x.cpp | 140 ++++++++++++++----------- BasiliskII/src/cdrom.cpp | 160 ++++++++++++++--------------- BasiliskII/src/disk.cpp | 97 ++++++++--------- BasiliskII/src/sony.cpp | 90 +++++++--------- BasiliskII/src/video.cpp | 155 ++++++++++++++-------------- 8 files changed, 366 insertions(+), 366 deletions(-) diff --git a/BasiliskII/src/Unix/configure.in b/BasiliskII/src/Unix/configure.in index 21367af8..716a7850 100644 --- a/BasiliskII/src/Unix/configure.in +++ b/BasiliskII/src/Unix/configure.in @@ -101,6 +101,7 @@ fi dnl Checks for libraries. AC_CHECK_LIB(posix4, sem_init) +AC_CHECK_LIB(rt, timer_create) dnl We need X11. AC_PATH_XTRA diff --git a/BasiliskII/src/Unix/video_blit.cpp b/BasiliskII/src/Unix/video_blit.cpp index e65ea84e..7e249ae4 100644 --- a/BasiliskII/src/Unix/video_blit.cpp +++ b/BasiliskII/src/Unix/video_blit.cpp @@ -19,6 +19,7 @@ */ #include "sysdeps.h" +#include "video.h" #include #include @@ -304,51 +305,59 @@ static Screen_blit_func_info Screen_blitters[] = { // Initialize the framebuffer update function // Returns FALSE, if the function was to be reduced to a simple memcpy() // --> In that case, VOSF is not necessary -bool Screen_blitter_init(XVisualInfo * visual_info, bool native_byte_order) +bool Screen_blitter_init(XVisualInfo * visual_info, bool native_byte_order, video_depth mac_depth) { #if REAL_ADDRESSING || DIRECT_ADDRESSING - visualFormat.depth = visual_info->depth; - visualFormat.Rmask = visual_info->red_mask; - visualFormat.Gmask = visual_info->green_mask; - visualFormat.Bmask = visual_info->blue_mask; + if (mac_depth == VDEPTH_1BIT) { + + // 1-bit mode uses a 1-bit X image, so there's no need for special blitting routines + Screen_blit = Blit_Copy_Raw; + + } else { + + visualFormat.depth = visual_info->depth; + visualFormat.Rmask = visual_info->red_mask; + visualFormat.Gmask = visual_info->green_mask; + visualFormat.Bmask = visual_info->blue_mask; - // Compute RGB shift values - visualFormat.Rshift = 0; - for (uint32 Rmask = visualFormat.Rmask; Rmask && ((Rmask & 1) != 1); Rmask >>= 1) - ++visualFormat.Rshift; - visualFormat.Gshift = 0; - for (uint32 Gmask = visualFormat.Gmask; Gmask && ((Gmask & 1) != 1); Gmask >>= 1) - ++visualFormat.Gshift; - visualFormat.Bshift = 0; - for (uint32 Bmask = visualFormat.Bmask; Bmask && ((Bmask & 1) != 1); Bmask >>= 1) - ++visualFormat.Bshift; + // Compute RGB shift values + visualFormat.Rshift = 0; + for (uint32 Rmask = visualFormat.Rmask; Rmask && ((Rmask & 1) != 1); Rmask >>= 1) + ++visualFormat.Rshift; + visualFormat.Gshift = 0; + for (uint32 Gmask = visualFormat.Gmask; Gmask && ((Gmask & 1) != 1); Gmask >>= 1) + ++visualFormat.Gshift; + visualFormat.Bshift = 0; + for (uint32 Bmask = visualFormat.Bmask; Bmask && ((Bmask & 1) != 1); Bmask >>= 1) + ++visualFormat.Bshift; - // Search for an adequate blit function - bool blitter_found = false; - const int blitters_count = sizeof(Screen_blitters)/sizeof(Screen_blitters[0]); - for (int i = 0; !blitter_found && (i < blitters_count); i++) { - if ( (visualFormat.depth == Screen_blitters[i].depth) - && (visualFormat.Rmask == Screen_blitters[i].Rmask) - && (visualFormat.Gmask == Screen_blitters[i].Gmask) - && (visualFormat.Bmask == Screen_blitters[i].Bmask) - ) - { - blitter_found = true; - Screen_blit = native_byte_order - ? Screen_blitters[i].handler_nbo - : Screen_blitters[i].handler_obo - ; + // Search for an adequate blit function + bool blitter_found = false; + const int blitters_count = sizeof(Screen_blitters)/sizeof(Screen_blitters[0]); + for (int i = 0; !blitter_found && (i < blitters_count); i++) { + if ( (visualFormat.depth == Screen_blitters[i].depth) + && (visualFormat.Rmask == Screen_blitters[i].Rmask) + && (visualFormat.Gmask == Screen_blitters[i].Gmask) + && (visualFormat.Bmask == Screen_blitters[i].Bmask) + ) + { + blitter_found = true; + Screen_blit = native_byte_order + ? Screen_blitters[i].handler_nbo + : Screen_blitters[i].handler_obo + ; + } } - } - // No appropriate blitter found, dump RGB mask values and abort() - if (!blitter_found) { - fprintf(stderr, "### No appropriate blitter found\n"); - fprintf(stderr, "\tR/G/B mask values : 0x%06x, 0x%06x, 0x%06x (depth = %d)\n", - visualFormat.Rmask, visualFormat.Gmask, visualFormat.Bmask, visualFormat.depth); - fprintf(stderr, "\tR/G/B shift values : %d/%d/%d\n", - visualFormat.Rshift, visualFormat.Gshift, visualFormat.Bshift); - abort(); + // No appropriate blitter found, dump RGB mask values and abort() + if (!blitter_found) { + fprintf(stderr, "### No appropriate blitter found\n"); + fprintf(stderr, "\tR/G/B mask values : 0x%06x, 0x%06x, 0x%06x (depth = %d)\n", + visualFormat.Rmask, visualFormat.Gmask, visualFormat.Bmask, visualFormat.depth); + fprintf(stderr, "\tR/G/B shift values : %d/%d/%d\n", + visualFormat.Rshift, visualFormat.Gshift, visualFormat.Bshift); + abort(); + } } #else // The UAE memory handlers will blit correctly diff --git a/BasiliskII/src/Unix/video_vosf.h b/BasiliskII/src/Unix/video_vosf.h index f894707a..91af9581 100644 --- a/BasiliskII/src/Unix/video_vosf.h +++ b/BasiliskII/src/Unix/video_vosf.h @@ -280,7 +280,7 @@ static bool screen_fault_handler(sigsegv_address_t fault_address, sigsegv_addres // From video_blit.cpp extern void (*Screen_blit)(uint8 * dest, const uint8 * source, uint32 length); -extern bool Screen_blitter_init(XVisualInfo * visual_info, bool native_byte_order); +extern bool Screen_blitter_init(XVisualInfo * visual_info, bool native_byte_order, video_depth mac_depth); /* How can we deal with array overrun conditions ? diff --git a/BasiliskII/src/Unix/video_x.cpp b/BasiliskII/src/Unix/video_x.cpp index e8826cf6..88d667fa 100644 --- a/BasiliskII/src/Unix/video_x.cpp +++ b/BasiliskII/src/Unix/video_x.cpp @@ -124,7 +124,9 @@ static XColor black, white; static unsigned long black_pixel, white_pixel; static int eventmask; -static XColor palette[256]; // Color palette for indexed modes +static int rshift, rloss, gshift, gloss, bshift, bloss; // Pixel format of DirectColor/TrueColor modes + +static XColor palette[256]; // Color palette to be used as CLUT and gamma table static bool palette_changed = false; // Flag: Palette changed, redraw thread must set new colors #ifdef ENABLE_FBDEV_DGA @@ -203,7 +205,7 @@ static void set_mac_frame_buffer(video_depth depth, bool native_byte_order) if (depth == VDEPTH_16BIT) layout = (xdepth == 15) ? FLAYOUT_HOST_555 : FLAYOUT_HOST_565; else if (depth == VDEPTH_32BIT) - layour = (xdepth == 24) ? FLAYOUT_HOST_888 : FLAYOUT_DIRECT; + layout = (xdepth == 24) ? FLAYOUT_HOST_888 : FLAYOUT_DIRECT; if (native_byte_order) MacFrameLayout = layout; else @@ -414,9 +416,9 @@ driver_window::driver_window(const video_mode &mode) XSetWindowAttributes wattr; wattr.event_mask = eventmask = win_eventmask; wattr.background_pixel = black_pixel; - wattr.colormap = cmap[0]; + wattr.colormap = (mode.depth == VDEPTH_1BIT && vis->c_class == PseudoColor ? DefaultColormap(x_display, screen) : cmap[0]); w = XCreateWindow(x_display, rootwin, 0, 0, width, height, 0, xdepth, - InputOutput, vis, CWEventMask | CWBackPixel | ((mode.depth == VDEPTH_1BIT || cmap[0] == 0) ? 0 : CWColormap), &wattr); + InputOutput, vis, CWEventMask | CWBackPixel | (vis->c_class == PseudoColor || vis->c_class == DirectColor ? CWColormap : 0), &wattr); // Set window name/class set_window_name(w, STR_WINDOW_TITLE); @@ -445,8 +447,12 @@ driver_window::driver_window(const video_mode &mode) XMapWindow(x_display, w); wait_mapped(w); + // 1-bit mode is big-endian; if the X server is little-endian, we can't + // use SHM because that doesn't allow changing the image byte order + bool need_msb_image = (mode.depth == VDEPTH_1BIT && XImageByteOrder(x_display) == LSBFirst); + // Try to create and attach SHM image - if (local_X11 && XShmQueryExtension(x_display)) { + if (local_X11 && !need_msb_image && XShmQueryExtension(x_display)) { // Create SHM image ("height + 2" for safety) img = XShmCreateImage(x_display, vis, mode.depth == VDEPTH_1BIT ? 1 : xdepth, mode.depth == VDEPTH_1BIT ? XYBitmap : ZPixmap, 0, &shminfo, width, height); @@ -478,8 +484,7 @@ driver_window::driver_window(const video_mode &mode) img = XCreateImage(x_display, vis, mode.depth == VDEPTH_1BIT ? 1 : xdepth, mode.depth == VDEPTH_1BIT ? XYBitmap : ZPixmap, 0, (char *)the_buffer_copy, aligned_width, aligned_height, 32, bytes_per_row); } - // 1-Bit mode is big-endian - if (mode.depth == VDEPTH_1BIT) { + if (need_msb_image) { img->byte_order = MSBFirst; img->bitmap_bit_order = MSBFirst; } @@ -514,7 +519,7 @@ driver_window::driver_window(const video_mode &mode) native_byte_order = (XImageByteOrder(x_display) == LSBFirst); #endif #ifdef ENABLE_VOSF - Screen_blitter_init(&visualInfo, native_byte_order); + Screen_blitter_init(&visualInfo, native_byte_order, mode.depth); #endif // Set VideoMonitor @@ -782,7 +787,7 @@ driver_fbdev::driver_fbdev(const video_mode &mode) #if REAL_ADDRESSING || DIRECT_ADDRESSING // Screen_blitter_init() returns TRUE if VOSF is mandatory // i.e. the framebuffer update function is not Blit_Copy_Raw - use_vosf = Screen_blitter_init(&visualInfo, true); + use_vosf = Screen_blitter_init(&visualInfo, true, mode.depth); if (use_vosf) { // Allocate memory for frame buffer (SIZE is extended to page-boundary) @@ -898,7 +903,7 @@ driver_xf86dga::driver_xf86dga(const video_mode &mode) #if REAL_ADDRESSING || DIRECT_ADDRESSING // Screen_blitter_init() returns TRUE if VOSF is mandatory // i.e. the framebuffer update function is not Blit_Copy_Raw - use_vosf = Screen_blitter_init(&visualInfo, true); + use_vosf = Screen_blitter_init(&visualInfo, true, mode.depth); if (use_vosf) { // Allocate memory for frame buffer (SIZE is extended to page-boundary) @@ -1022,6 +1027,22 @@ static void keycode_init(void) // Open display for specified mode static bool video_open(const video_mode &mode) { + // Load gray ramp to color map + int num = (vis->c_class == DirectColor ? vis->map_entries : 256); + for (int i=0; ic_class == PseudoColor) + palette[i].pixel = i; + palette[i].flags = DoRed | DoGreen | DoBlue; + } + if (cmap[0] && cmap[1]) { + XStoreColors(x_display, cmap[0], palette, num); + XStoreColors(x_display, cmap[1], palette, num); + } + // Create display driver object of requested type switch (display_type) { case DISPLAY_WINDOW: @@ -1186,46 +1207,34 @@ bool VideoInit(bool classic) if (color_class == PseudoColor || color_class == DirectColor) { cmap[0] = XCreateColormap(x_display, rootwin, vis, AllocAll); cmap[1] = XCreateColormap(x_display, rootwin, vis, AllocAll); + } - int num = 256; - if (color_class == DirectColor) { - num = vis->map_entries; + // Find pixel format of direct modes + if (color_class == DirectColor || color_class == TrueColor) { + rshift = gshift = bshift = 0; + rloss = gloss = bloss = 8; + uint32 mask; + for (mask=vis->red_mask; !(mask&1); mask>>=1) + ++rshift; + for (; mask&1; mask>>=1) + --rloss; + for (mask=vis->green_mask; !(mask&1); mask>>=1) + ++gshift; + for (; mask&1; mask>>=1) + --gloss; + for (mask=vis->blue_mask; !(mask&1); mask>>=1) + ++bshift; + for (; mask&1; mask>>=1) + --bloss; + } - // Preset pixel values for gamma table - uint32 rmask = vis->red_mask, gmask = vis->green_mask, bmask = vis->blue_mask; - uint32 mask; - int rloss = 8, rshift = 0; - for (mask=rmask; !(mask&1); mask>>=1) - ++rshift; - for (; mask&1; mask>>=1) - --rloss; - int gloss = 8, gshift = 0; - for (mask=gmask; !(mask&1); mask>>=1) - ++gshift; - for (; mask&1; mask>>=1) - --gloss; - int bloss = 8, bshift = 0; - for (mask=bmask; !(mask&1); mask>>=1) - ++bshift; - for (; mask&1; mask>>=1) - --bloss; - for (int i=0; i> rloss) << rshift) | ((c >> gloss) << gshift) | ((c >> bloss) << bshift); - } - } - - // Load gray ramp + // Preset palette pixel values for gamma table + if (color_class == DirectColor) { + int num = vis->map_entries; for (int i=0; i> rloss) << rshift) | ((c >> gloss) << gshift) | ((c >> bloss) << bshift); } - XStoreColors(x_display, cmap[0], palette, num); } // Get screen mode from preferences @@ -1261,34 +1270,45 @@ bool VideoInit(bool classic) else if (default_height > DisplayHeight(x_display, screen)) default_height = DisplayHeight(x_display, screen); - // Mac screen depth is always 1 bit in Classic mode, but follows X depth otherwise - int depth = (classic_mode ? 1 : xdepth); - video_depth depth_mode = DepthModeForPixelDepth(depth); + // Mac screen depth follows X depth + video_depth default_depth = DepthModeForPixelDepth(xdepth); // Construct list of supported modes if (display_type == DISPLAY_WINDOW) { if (classic) - add_mode(512, 342, 0x80, 64, depth_mode); + add_mode(512, 342, 0x80, 64, VDEPTH_1BIT); else { - add_mode(512, 384, 0x80, TrivialBytesPerRow(512, depth_mode), depth_mode); - add_mode(640, 480, 0x81, TrivialBytesPerRow(640, depth_mode), depth_mode); - add_mode(800, 600, 0x82, TrivialBytesPerRow(800, depth_mode), depth_mode); - add_mode(1024, 768, 0x83, TrivialBytesPerRow(1024, depth_mode), depth_mode); - add_mode(1280, 1024, 0x84, TrivialBytesPerRow(1280, depth_mode), depth_mode); + if (default_depth != VDEPTH_1BIT) { // 1-bit modes are always available + add_mode(512, 384, 0x80, TrivialBytesPerRow(512, VDEPTH_1BIT), VDEPTH_1BIT); + add_mode(640, 480, 0x81, TrivialBytesPerRow(640, VDEPTH_1BIT), VDEPTH_1BIT); + add_mode(800, 600, 0x82, TrivialBytesPerRow(800, VDEPTH_1BIT), VDEPTH_1BIT); + add_mode(832, 624, 0x83, TrivialBytesPerRow(832, VDEPTH_1BIT), VDEPTH_1BIT); + add_mode(1024, 768, 0x84, TrivialBytesPerRow(1024, VDEPTH_1BIT), VDEPTH_1BIT); + add_mode(1152, 870, 0x85, TrivialBytesPerRow(1152, VDEPTH_1BIT), VDEPTH_1BIT); + add_mode(1280, 1024, 0x86, TrivialBytesPerRow(1280, VDEPTH_1BIT), VDEPTH_1BIT); + add_mode(1600, 1200, 0x87, TrivialBytesPerRow(1600, VDEPTH_1BIT), VDEPTH_1BIT); + } + add_mode(512, 384, 0x80, TrivialBytesPerRow(512, default_depth), default_depth); + add_mode(640, 480, 0x81, TrivialBytesPerRow(640, default_depth), default_depth); + add_mode(800, 600, 0x82, TrivialBytesPerRow(800, default_depth), default_depth); + add_mode(832, 624, 0x83, TrivialBytesPerRow(832, default_depth), default_depth); + add_mode(1024, 768, 0x84, TrivialBytesPerRow(1024, default_depth), default_depth); + add_mode(1152, 870, 0x85, TrivialBytesPerRow(1152, default_depth), default_depth); + add_mode(1280, 1024, 0x86, TrivialBytesPerRow(1280, default_depth), default_depth); + add_mode(1600, 1200, 0x87, TrivialBytesPerRow(1600, default_depth), default_depth); } } else - add_mode(default_width, default_height, 0x80, TrivialBytesPerRow(default_width, depth_mode), depth_mode); + add_mode(default_width, default_height, 0x80, TrivialBytesPerRow(default_width, default_depth), default_depth); // Find requested default mode and open display if (VideoModes.size() == 1) return video_open(VideoModes[0]); else { // Find mode with specified dimensions - std::vector::const_iterator i = VideoModes.begin(), end = VideoModes.end(); - while (i != end) { - if (i->x == default_width && i->y == default_height) + std::vector::const_iterator i, end = VideoModes.end(); + for (i = VideoModes.begin(); i != end; ++i) { + if (i->x == default_width && i->y == default_height && i->depth == default_depth) return video_open(*i); - ++i; } return video_open(VideoModes[0]); } @@ -1420,7 +1440,7 @@ void video_set_palette(uint8 *pal) p->red = pal[c*3 + 0] * 0x0101; p->green = pal[c*3 + 1] * 0x0101; p->blue = pal[c*3 + 2] * 0x0101; - if (!IsDirectMode(VideoMonitor.mode)) + if (vis->c_class == PseudoColor) p->pixel = i; p->flags = DoRed | DoGreen | DoBlue; p++; diff --git a/BasiliskII/src/cdrom.cpp b/BasiliskII/src/cdrom.cpp index bb5eeab5..e2efa962 100644 --- a/BasiliskII/src/cdrom.cpp +++ b/BasiliskII/src/cdrom.cpp @@ -29,6 +29,11 @@ */ #include +#include + +#ifndef NO_STD_NAMESPACE +using std::vector; +#endif #include "sysdeps.h" #include "cpu_emulation.h" @@ -97,7 +102,7 @@ static const uint8 bin2bcd[256] = { }; static const uint8 bcd2bin[256] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, @@ -117,17 +122,12 @@ static const uint8 bcd2bin[256] = { // Struct for each drive -struct DriveInfo { - DriveInfo() - { - next = NULL; - num = 0; - fh = NULL; - start_byte = 0; - status = 0; - } +struct cdrom_drive_info { + cdrom_drive_info() : num(0), fh(NULL), start_byte(0), status(0) {} + cdrom_drive_info(void *fh_) : num(0), fh(fh_), start_byte(0), status(0) {} + + void close_fh(void) { SysAllowRemoval(fh); Sys_close(fh); } - DriveInfo *next; // Pointer to next DriveInfo (must be first in struct!) int num; // Drive number void *fh; // File handle int block_size; // CD-ROM block size @@ -145,8 +145,9 @@ struct DriveInfo { uint32 status; // Mac address of drive status record }; -// Linked list of DriveInfos -static DriveInfo *first_drive_info; +// List of drives handled by this driver +typedef vector drive_vec; +static drive_vec drives; // Icon address (Mac address space, set by PatchROM()) uint32 CDROMIconAddr; @@ -156,18 +157,17 @@ static bool acc_run_called = false; /* - * Get pointer to drive info, NULL = invalid drive number + * Get pointer to drive info or drives.end() if not found */ -static DriveInfo *get_drive_info(int num) +static drive_vec::iterator get_drive_info(int num) { - DriveInfo *info = first_drive_info; - while (info != NULL) { + drive_vec::iterator info, end = drives.end(); + for (info = drives.begin(); info != end; ++info) { if (info->num == num) return info; - info = info->next; } - return NULL; + return info; } @@ -175,14 +175,14 @@ static DriveInfo *get_drive_info(int num) * Find HFS partition, set info->start_byte (0 = no HFS partition) */ -static void find_hfs_partition(DriveInfo *info) +static void find_hfs_partition(cdrom_drive_info &info) { - info->start_byte = 0; + info.start_byte = 0; uint8 *map = new uint8[512]; // Search first 64 blocks for HFS partition for (int i=0; i<64; i++) { - if (Sys_read(info->fh, map, i * 512, 512) != 512) + if (Sys_read(info.fh, map, i * 512, 512) != 512) break; // Not a partition map block? Then look at next block @@ -192,8 +192,8 @@ static void find_hfs_partition(DriveInfo *info) // Partition map block found, Apple HFS partition? if (strcmp((char *)(map + 48), "Apple_HFS") == 0) { - info->start_byte = ntohl(((uint32 *)map)[2]) << 9; - D(bug(" HFS partition found at %d, %d blocks\n", info->start_byte, ntohl(((uint32 *)map)[3]))); + info.start_byte = ntohl(((uint32 *)map)[2]) << 9; + D(bug(" HFS partition found at %d, %d blocks\n", info.start_byte, ntohl(((uint32 *)map)[3]))); break; } } @@ -205,26 +205,26 @@ static void find_hfs_partition(DriveInfo *info) * Read TOC of disk and set lead_out */ -static void read_toc(DriveInfo *info) +static void read_toc(cdrom_drive_info &info) { // Read TOC - memset(&info->toc, 0, sizeof(info->toc)); - SysCDReadTOC(info->fh, info->toc); - D(bug(" TOC: %08lx %08lx\n", ntohl(((uint32 *)info->toc)[0]), ntohl(((uint32 *)info->toc)[1]))); + memset(info.toc, 0, sizeof(info.toc)); + SysCDReadTOC(info.fh, info.toc); + D(bug(" TOC: %08lx %08lx\n", ntohl(((uint32 *)info.toc)[0]), ntohl(((uint32 *)info.toc)[1]))); // Find lead-out track - info->lead_out[0] = 0; - info->lead_out[1] = 0; - info->lead_out[2] = 0; + info.lead_out[0] = 0; + info.lead_out[1] = 0; + info.lead_out[2] = 0; for (int i=4; i<804; i+=8) { - if (info->toc[i+2] == 0xaa) { - info->stop_at[0] = info->lead_out[0] = info->toc[i+5]; - info->stop_at[1] = info->lead_out[1] = info->toc[i+6]; - info->stop_at[2] = info->lead_out[2] = info->toc[i+7]; + if (info.toc[i+2] == 0xaa) { + info.stop_at[0] = info.lead_out[0] = info.toc[i+5]; + info.stop_at[1] = info.lead_out[1] = info.toc[i+6]; + info.stop_at[2] = info.lead_out[2] = info.toc[i+7]; break; } } - D(bug(" Lead-Out M %d S %d F %d\n", info->lead_out[0], info->lead_out[1], info->lead_out[2])); + D(bug(" Lead-Out M %d S %d F %d\n", info.lead_out[0], info.lead_out[1], info.lead_out[2])); } @@ -233,7 +233,7 @@ static void read_toc(DriveInfo *info) * Return: false = error */ -static bool position2msf(DriveInfo *info, uint16 postype, uint32 pos, bool stopping, uint8 &m, uint8 &s, uint8 &f) +static bool position2msf(const cdrom_drive_info &info, uint16 postype, uint32 pos, bool stopping, uint8 &m, uint8 &s, uint8 &f) { switch (postype) { case 0: @@ -251,10 +251,10 @@ static bool position2msf(DriveInfo *info, uint16 postype, uint32 pos, bool stopp if (stopping) track++; for (int i=4; i<804; i+=8) { - if (info->toc[i+2] == track || info->toc[i+2] == 0xaa) { - m = info->toc[i+5]; - s = info->toc[i+6]; - f = info->toc[i+7]; + if (info.toc[i+2] == track || info.toc[i+2] == 0xaa) { + m = info.toc[i+5]; + s = info.toc[i+6]; + f = info.toc[i+7]; return true; } } @@ -272,25 +272,17 @@ static bool position2msf(DriveInfo *info, uint16 postype, uint32 pos, bool stopp void CDROMInit(void) { - first_drive_info = NULL; - // No drives specified in prefs? Then add defaults if (PrefsFindString("cdrom", 0) == NULL) SysAddCDROMPrefs(); // Add drives specified in preferences - int32 index = 0; + int index = 0; const char *str; while ((str = PrefsFindString("cdrom", index++)) != NULL) { void *fh = Sys_open(str, true); - if (fh) { - DriveInfo *info = new DriveInfo; - info->fh = fh; - DriveInfo *p = (DriveInfo *)&first_drive_info; - while (p->next != NULL) - p = p->next; - p->next = info; - } + if (fh) + drives.push_back(cdrom_drive_info(fh)); } } @@ -301,14 +293,10 @@ void CDROMInit(void) void CDROMExit(void) { - DriveInfo *info = first_drive_info, *next; - while (info != NULL) { - SysAllowRemoval(info->fh); - Sys_close(info->fh); - next = info->next; - delete info; - info = next; - } + drive_vec::iterator info, end = drives.end(); + for (info = drives.begin(); info != end; ++info) + info->close_fh(); + drives.clear(); } @@ -318,14 +306,15 @@ void CDROMExit(void) bool CDROMMountVolume(void *fh) { - DriveInfo *info; - for (info = first_drive_info; info != NULL && info->fh != fh; info = info->next) ; - if (info) { + drive_vec::iterator info = drives.begin(), end = drives.end(); + while (info != end && info->fh != fh) + ++info; + if (info != end) { if (SysIsDiskInserted(info->fh)) { SysPreventRemoval(info->fh); WriteMacInt8(info->status + dsDiskInPlace, 1); - read_toc(info); - find_hfs_partition(info); + read_toc(*info); + find_hfs_partition(*info); if (info->start_byte != 0 || info->mount_non_hfs) info->to_be_mounted = true; } @@ -342,8 +331,8 @@ bool CDROMMountVolume(void *fh) static void mount_mountable_volumes(void) { - DriveInfo *info = first_drive_info; - while (info != NULL) { + drive_vec::iterator info, end = drives.end(); + for (info = drives.begin(); info != end; ++info) { // Disk in drive? if (ReadMacInt8(info->status + dsDiskInPlace) == 0) { @@ -362,8 +351,6 @@ static void mount_mountable_volumes(void) Execute68kTrap(0xa02f, &r); // PostEvent() info->to_be_mounted = false; } - - info = info->next; } } @@ -381,7 +368,8 @@ int16 CDROMOpen(uint32 pb, uint32 dce) acc_run_called = false; // Install drives - for (DriveInfo *info = first_drive_info; info; info = info->next) { + drive_vec::iterator info, end = drives.end(); + for (info = drives.begin(); info != end; ++info) { info->num = FindFreeDriveNumber(1); info->to_be_mounted = false; @@ -411,8 +399,8 @@ int16 CDROMOpen(uint32 pb, uint32 dce) if (SysIsDiskInserted(info->fh)) { SysPreventRemoval(info->fh); WriteMacInt8(info->status + dsDiskInPlace, 1); - read_toc(info); - find_hfs_partition(info); + read_toc(*info); + find_hfs_partition(*info); info->to_be_mounted = true; } @@ -436,8 +424,8 @@ int16 CDROMPrime(uint32 pb, uint32 dce) WriteMacInt32(pb + ioActCount, 0); // Drive valid and disk inserted? - DriveInfo *info; - if ((info = get_drive_info(ReadMacInt16(pb + ioVRefNum))) == NULL) + drive_vec::iterator info = get_drive_info(ReadMacInt16(pb + ioVRefNum)); + if (info == drives.end()) return nsDrvErr; if (ReadMacInt8(info->status + dsDiskInPlace) == 0) return offLinErr; @@ -503,12 +491,13 @@ int16 CDROMControl(uint32 pb, uint32 dce) } // Drive valid? - DriveInfo *info; - if ((info = get_drive_info(ReadMacInt16(pb + ioVRefNum))) == NULL) - if (first_drive_info == NULL) + drive_vec::iterator info = get_drive_info(ReadMacInt16(pb + ioVRefNum)); + if (info == drives.end()) { + if (drives.empty()) return nsDrvErr; else - info = first_drive_info; // This is needed for Apple's Audio CD program + info = drives.begin(); // This is needed for Apple's Audio CD program + } // Drive-specific codes switch (code) { @@ -535,7 +524,7 @@ int16 CDROMControl(uint32 pb, uint32 dce) WriteMacInt32(pb + csParam, CDROMIconAddr); return noErr; - case 23: // DriveInfo + case 23: // drive_info WriteMacInt32(pb + csParam, 0x00000b01); // Unspecified external removable SCSI disk return noErr; @@ -857,11 +846,11 @@ int16 CDROMControl(uint32 pb, uint32 dce) int16 CDROMStatus(uint32 pb, uint32 dce) { - DriveInfo *info = get_drive_info(ReadMacInt16(pb + ioVRefNum)); + drive_vec::iterator info = get_drive_info(ReadMacInt16(pb + ioVRefNum)); uint16 code = ReadMacInt16(pb + csCode); D(bug("CDROMStatus %d\n", code)); - // General codes + // General codes (we can get these even if the drive was invalid) switch (code) { case 43: { // DriverGestalt uint32 sel = ReadMacInt32(pb + csParam); @@ -880,7 +869,7 @@ int16 CDROMStatus(uint32 pb, uint32 dce) WriteMacInt32(pb + csParam + 4, 0x01000000); break; case FOURCC('b','o','o','t'): // Boot ID - if (info != NULL) + if (info != drives.end()) WriteMacInt16(pb + csParam + 4, info->num); else WriteMacInt16(pb + csParam + 4, 0); @@ -909,11 +898,12 @@ int16 CDROMStatus(uint32 pb, uint32 dce) } // Drive valid? - if (info == NULL) - if (first_drive_info == NULL) + if (info == drives.end()) { + if (drives.empty()) return nsDrvErr; else - info = first_drive_info; // This is needed for Apple's Audio CD program + info = drives.begin(); // This is needed for Apple's Audio CD program + } // Drive-specific codes switch (code) { diff --git a/BasiliskII/src/disk.cpp b/BasiliskII/src/disk.cpp index 959d54e3..80b6389a 100644 --- a/BasiliskII/src/disk.cpp +++ b/BasiliskII/src/disk.cpp @@ -27,6 +27,11 @@ */ #include +#include + +#ifndef NO_STD_NAMESPACE +using std::vector; +#endif #include "sysdeps.h" #include "cpu_emulation.h" @@ -65,17 +70,12 @@ const uint8 DiskIcon[258] = { // Struct for each drive -struct DriveInfo { - DriveInfo() - { - next = NULL; - num = 0; - fh = NULL; - read_only = false; - status = 0; - } +struct disk_drive_info { + disk_drive_info() : num(0), fh(NULL), read_only(false), status(0) {} + disk_drive_info(void *fh_, bool ro) : num(0), fh(fh_), read_only(ro), status(0) {} + + void close_fh(void) { Sys_close(fh); } - DriveInfo *next; // Pointer to next DriveInfo (must be first in struct!) int num; // Drive number void *fh; // File handle uint32 num_blocks; // Size in 512-byte blocks @@ -84,8 +84,9 @@ struct DriveInfo { uint32 status; // Mac address of drive status record }; -// Linked list of DriveInfos -static DriveInfo *first_drive_info; +// List of drives handled by this driver +typedef vector drive_vec; +static drive_vec drives; // Icon address (Mac address space, set by PatchROM()) uint32 DiskIconAddr; @@ -95,18 +96,17 @@ static bool acc_run_called = false; /* - * Get pointer to drive info, NULL = invalid drive number + * Get pointer to drive info or drives.end() if not found */ -static DriveInfo *get_drive_info(int num) +static drive_vec::iterator get_drive_info(int num) { - DriveInfo *info = first_drive_info; - while (info != NULL) { + drive_vec::iterator info, end = drives.end(); + for (info = drives.begin(); info != end; ++info) { if (info->num == num) return info; - info = info->next; } - return NULL; + return info; } @@ -116,14 +116,12 @@ static DriveInfo *get_drive_info(int num) void DiskInit(void) { - first_drive_info = NULL; - // No drives specified in prefs? Then add defaults if (PrefsFindString("disk", 0) == NULL) SysAddDiskPrefs(); // Add drives specified in preferences - int32 index = 0; + int index = 0; const char *str; while ((str = PrefsFindString("disk", index++)) != NULL) { bool read_only = false; @@ -132,16 +130,8 @@ void DiskInit(void) str++; } void *fh = Sys_open(str, read_only); - if (fh) { - D(bug(" adding drive '%s'\n", str)); - DriveInfo *info = new DriveInfo; - info->fh = fh; - info->read_only = SysIsReadOnly(fh); - DriveInfo *p = (DriveInfo *)&first_drive_info; - while (p->next != NULL) - p = p->next; - p->next = info; - } + if (fh) + drives.push_back(disk_drive_info(fh, SysIsReadOnly(fh))); } } @@ -152,13 +142,10 @@ void DiskInit(void) void DiskExit(void) { - DriveInfo *info = first_drive_info, *next; - while (info != NULL) { - Sys_close(info->fh); - next = info->next; - delete info; - info = next; - } + drive_vec::iterator info, end = drives.end(); + for (info = drives.begin(); info != end; ++info) + info->close_fh(); + drives.clear(); } @@ -168,9 +155,10 @@ void DiskExit(void) bool DiskMountVolume(void *fh) { - DriveInfo *info; - for (info = first_drive_info; info != NULL && info->fh != fh; info = info->next) ; - if (info) { + drive_vec::iterator info = drives.begin(), end = drives.end(); + while (info != end && info->fh != fh) + ++info; + if (info != end) { if (SysIsDiskInserted(info->fh)) { info->read_only = SysIsReadOnly(info->fh); WriteMacInt8(info->status + dsDiskInPlace, 1); // Inserted removable disk @@ -193,8 +181,8 @@ bool DiskMountVolume(void *fh) static void mount_mountable_volumes(void) { - DriveInfo *info = first_drive_info; - while (info != NULL) { + drive_vec::iterator info, end = drives.end(); + for (info = drives.begin(); info != end; ++info) { // Disk in drive? if (!ReadMacInt8(info->status + dsDiskInPlace)) { @@ -213,8 +201,6 @@ static void mount_mountable_volumes(void) Execute68kTrap(0xa02f, &r); // PostEvent() info->to_be_mounted = false; } - - info = info->next; } } @@ -232,7 +218,8 @@ int16 DiskOpen(uint32 pb, uint32 dce) acc_run_called = false; // Install drives - for (DriveInfo *info = first_drive_info; info; info = info->next) { + drive_vec::iterator info, end = drives.end(); + for (info = drives.begin(); info != end; ++info) { info->num = FindFreeDriveNumber(1); info->to_be_mounted = false; @@ -289,8 +276,8 @@ int16 DiskPrime(uint32 pb, uint32 dce) WriteMacInt32(pb + ioActCount, 0); // Drive valid and disk inserted? - DriveInfo *info; - if ((info = get_drive_info(ReadMacInt16(pb + ioVRefNum))) == NULL) + drive_vec::iterator info = get_drive_info(ReadMacInt16(pb + ioVRefNum)); + if (info == drives.end()) return nsDrvErr; if (!ReadMacInt8(info->status + dsDiskInPlace)) return offLinErr; @@ -352,8 +339,8 @@ int16 DiskControl(uint32 pb, uint32 dce) } // Drive valid? - DriveInfo *info; - if ((info = get_drive_info(ReadMacInt16(pb + ioVRefNum))) == NULL) + drive_vec::iterator info = get_drive_info(ReadMacInt16(pb + ioVRefNum)); + if (info == drives.end()) return nsDrvErr; // Drive-specific codes @@ -417,11 +404,11 @@ int16 DiskControl(uint32 pb, uint32 dce) int16 DiskStatus(uint32 pb, uint32 dce) { - DriveInfo *info = get_drive_info(ReadMacInt16(pb + ioVRefNum)); + drive_vec::iterator info = get_drive_info(ReadMacInt16(pb + ioVRefNum)); uint16 code = ReadMacInt16(pb + csCode); D(bug("DiskStatus %d\n", code)); - // General codes + // General codes (we can get these even if the drive was invalid) switch (code) { case 43: { // Driver gestalt uint32 sel = ReadMacInt32(pb + csParam); @@ -431,7 +418,7 @@ int16 DiskStatus(uint32 pb, uint32 dce) WriteMacInt32(pb + csParam + 4, 0x01008000); break; case FOURCC('d','e','v','t'): // Device type - if (info != NULL) { + if (info != drives.end()) { if (ReadMacInt8(info->status + dsDiskInPlace) == 8) WriteMacInt32(pb + csParam + 4, FOURCC('d','i','s','k')); else @@ -446,7 +433,7 @@ int16 DiskStatus(uint32 pb, uint32 dce) WriteMacInt32(pb + csParam + 4, 0x01000000); break; case FOURCC('b','o','o','t'): // Boot ID - if (info != NULL) + if (info != drives.end()) WriteMacInt16(pb + csParam + 4, info->num); else WriteMacInt16(pb + csParam + 4, 0); @@ -475,7 +462,7 @@ int16 DiskStatus(uint32 pb, uint32 dce) } // Drive valid? - if (info == NULL) + if (info == drives.end()) return nsDrvErr; // Drive-specific codes diff --git a/BasiliskII/src/sony.cpp b/BasiliskII/src/sony.cpp index 4ce82c0a..a348c42f 100644 --- a/BasiliskII/src/sony.cpp +++ b/BasiliskII/src/sony.cpp @@ -29,6 +29,11 @@ */ #include +#include + +#ifndef NO_STD_NAMESPACE +using std::vector; +#endif #include "sysdeps.h" #include "cpu_emulation.h" @@ -99,17 +104,12 @@ const uint8 SonyDriveIcon[258] = { // Struct for each drive -struct DriveInfo { - DriveInfo() - { - next = NULL; - num = 0; - fh = NULL; - read_only = false; - status = 0; - } +struct sony_drive_info { + sony_drive_info() : num(0), fh(NULL), read_only(false), status(0) {} + sony_drive_info(void *fh_, bool ro) : num(0), fh(fh_), read_only(ro), status(0) {} + + void close_fh(void) { Sys_close(fh); } - DriveInfo *next; // Pointer to next DriveInfo (must be first in struct!) int num; // Drive number void *fh; // Floppy driver file handle bool to_be_mounted; // Flag: drive must be mounted in accRun @@ -118,8 +118,9 @@ struct DriveInfo { uint32 status; // Mac address of drive status record }; -// Linked list of DriveInfos -static DriveInfo *first_drive_info; +// List of drives handled by this driver +typedef vector drive_vec; +static drive_vec drives; // Icon addresses (Mac address space, set by PatchROM()) uint32 SonyDiskIconAddr; @@ -130,18 +131,17 @@ static bool acc_run_called = false; /* - * Get pointer to drive info, NULL = invalid drive number + * Get reference to drive info or drives.end() if not found */ -static DriveInfo *get_drive_info(int num) +static drive_vec::iterator get_drive_info(int num) { - DriveInfo *info = first_drive_info; - while (info != NULL) { + drive_vec::iterator info, end = drives.end(); + for (info = drives.begin(); info != end; ++info) { if (info->num == num) return info; - info = info->next; } - return NULL; + return info; } @@ -151,14 +151,12 @@ static DriveInfo *get_drive_info(int num) void SonyInit(void) { - first_drive_info = NULL; - // No drives specified in prefs? Then add defaults if (PrefsFindString("floppy", 0) == NULL) SysAddFloppyPrefs(); // Add drives specified in preferences - int32 index = 0; + int index = 0; const char *str; while ((str = PrefsFindString("floppy", index++)) != NULL) { bool read_only = false; @@ -167,15 +165,8 @@ void SonyInit(void) str++; } void *fh = Sys_open(str, read_only); - if (fh) { - DriveInfo *info = new DriveInfo; - info->fh = fh; - info->read_only = SysIsReadOnly(fh); - DriveInfo *p = (DriveInfo *)&first_drive_info; - while (p->next != NULL) - p = p->next; - p->next = info; - } + if (fh) + drives.push_back(sony_drive_info(fh, SysIsReadOnly(fh))); } } @@ -186,13 +177,10 @@ void SonyInit(void) void SonyExit(void) { - DriveInfo *info = first_drive_info, *next; - while (info != NULL) { - Sys_close(info->fh); - next = info->next; - delete info; - info = next; - } + drive_vec::iterator info, end = drives.end(); + for (info = drives.begin(); info != end; ++info) + info->close_fh(); + drives.clear(); } @@ -202,9 +190,10 @@ void SonyExit(void) bool SonyMountVolume(void *fh) { - DriveInfo *info; - for (info = first_drive_info; info != NULL && info->fh != fh; info = info->next) ; - if (info) { + drive_vec::iterator info = drives.begin(), end = drives.end(); + while (info != end && info->fh != fh) + ++info; + if (info != end) { if (SysIsDiskInserted(info->fh)) { info->read_only = SysIsReadOnly(info->fh); WriteMacInt8(info->status + dsDiskInPlace, 1); // Inserted removable disk @@ -224,8 +213,8 @@ bool SonyMountVolume(void *fh) static void mount_mountable_volumes(void) { - DriveInfo *info = first_drive_info; - while (info != NULL) { + drive_vec::iterator info, end = drives.end(); + for (info = drives.begin(); info != end; ++info) { #if DISK_INSERT_CHECK // Disk in drive? @@ -246,8 +235,6 @@ static void mount_mountable_volumes(void) Execute68kTrap(0xa02f, &r); // PostEvent() info->to_be_mounted = false; } - - info = info->next; } } @@ -287,7 +274,8 @@ int16 SonyOpen(uint32 pb, uint32 dce) set_dsk_err(0); // Install drives - for (DriveInfo *info = first_drive_info; info; info = info->next) { + drive_vec::iterator info, end = drives.end(); + for (info = drives.begin(); info != end; ++info) { info->num = FindFreeDriveNumber(1); info->to_be_mounted = false; @@ -341,8 +329,8 @@ int16 SonyPrime(uint32 pb, uint32 dce) WriteMacInt32(pb + ioActCount, 0); // Drive valid and disk inserted? - DriveInfo *info; - if ((info = get_drive_info(ReadMacInt16(pb + ioVRefNum))) == NULL) + drive_vec::iterator info = get_drive_info(ReadMacInt16(pb + ioVRefNum)); + if (info == drives.end()) return set_dsk_err(nsDrvErr); if (!ReadMacInt8(info->status + dsDiskInPlace)) return set_dsk_err(offLinErr); @@ -411,8 +399,8 @@ int16 SonyControl(uint32 pb, uint32 dce) } // Drive valid? - DriveInfo *info; - if ((info = get_drive_info(ReadMacInt16(pb + ioVRefNum))) == NULL) + drive_vec::iterator info = get_drive_info(ReadMacInt16(pb + ioVRefNum)); + if (info == drives.end()) return set_dsk_err(nsDrvErr); // Drive-specific codes @@ -492,8 +480,8 @@ int16 SonyStatus(uint32 pb, uint32 dce) D(bug("SonyStatus %d\n", code)); // Drive valid? - DriveInfo *info; - if ((info = get_drive_info(ReadMacInt16(pb + ioVRefNum))) == NULL) + drive_vec::iterator info = get_drive_info(ReadMacInt16(pb + ioVRefNum)); + if (info == drives.end()) return set_dsk_err(nsDrvErr); int16 err = noErr; diff --git a/BasiliskII/src/video.cpp b/BasiliskII/src/video.cpp index 6be16221..d946e7f6 100644 --- a/BasiliskII/src/video.cpp +++ b/BasiliskII/src/video.cpp @@ -67,11 +67,10 @@ struct { static bool has_resolution(uint32 id) { - vector::const_iterator i = VideoModes.begin(), end = VideoModes.end(); - while (i != end) { + vector::const_iterator i, end = VideoModes.end(); + for (i = VideoModes.begin(); i != end; ++i) { if (i->resolution_id == id) return true; - ++i; } return false; } @@ -83,11 +82,10 @@ static bool has_resolution(uint32 id) static vector::const_iterator find_mode(uint16 mode, uint32 id) { - vector::const_iterator i = VideoModes.begin(), end = VideoModes.end(); - while (i != end) { + vector::const_iterator i, end = VideoModes.end(); + for (i = VideoModes.begin(); i != end; ++i) { if (i->resolution_id == id && DepthToAppleMode(i->depth) == mode) return i; - ++i; } return i; } @@ -100,11 +98,10 @@ static vector::const_iterator find_mode(uint16 mode, uint32 id) static video_depth max_depth_of_resolution(uint32 id) { video_depth m = VDEPTH_1BIT; - vector::const_iterator i = VideoModes.begin(), end = VideoModes.end(); - while (i != end) { + vector::const_iterator i, end = VideoModes.end(); + for (i = VideoModes.begin(); i != end; ++i) { if (i->depth > m) m = i->depth; - ++i; } return m; } @@ -116,14 +113,13 @@ static video_depth max_depth_of_resolution(uint32 id) static void get_size_of_resolution(uint32 id, uint32 &x, uint32 &y) { - vector::const_iterator i = VideoModes.begin(), end = VideoModes.end(); - while (i != end) { + vector::const_iterator i, end = VideoModes.end(); + for (i = VideoModes.begin(); i != end; ++i) { if (i->resolution_id == id) { x = i->x; y = i->y; return; } - ++i; } } @@ -272,6 +268,74 @@ static bool set_gamma_table(uint32 user_table) } +/* + * Switch video mode + */ + +static void switch_mode(const video_mode &mode, uint32 param, uint32 dce) +{ + // Switch mode + set_gray_palette(); + video_switch_to_mode(mode); + + // Update VidLocal + VidLocal.current_mode = DepthToAppleMode(mode.depth); + VidLocal.current_id = mode.resolution_id; + + uint32 frame_base = VidLocal.desc->mac_frame_base; + + M68kRegisters r; + uint32 sp = VidLocal.slot_param; + r.a[0] = sp; + + // Find functional sResource for this display + WriteMacInt8(sp + spSlot, ReadMacInt8(dce + dCtlSlot)); + WriteMacInt8(sp + spID, ReadMacInt8(dce + dCtlSlotId)); + WriteMacInt8(sp + spExtDev, 0); + r.d[0] = 0x0016; + Execute68kTrap(0xa06e, &r); // SRsrcInfo() + uint32 rsrc = ReadMacInt32(sp + spPointer); + + // Patch minorBase (otherwise rebooting won't work) + WriteMacInt8(sp + spID, 0x0a); // minorBase + r.d[0] = 0x0006; + Execute68kTrap(0xa06e, &r); // SFindStruct() + uint32 minor_base = ReadMacInt32(sp + spPointer) - ROMBaseMac; + ROMBaseHost[minor_base + 0] = frame_base >> 24; + ROMBaseHost[minor_base + 1] = frame_base >> 16; + ROMBaseHost[minor_base + 2] = frame_base >> 8; + ROMBaseHost[minor_base + 3] = frame_base; + + // Patch video mode parameter table + WriteMacInt32(sp + spPointer, rsrc); + WriteMacInt8(sp + spID, DepthToAppleMode(mode.depth)); + r.d[0] = 0x0006; + Execute68kTrap(0xa06e, &r); // SFindStruct() + WriteMacInt8(sp + spID, 0x01); + r.d[0] = 0x0006; + Execute68kTrap(0xa06e, &r); // SFindStruct() + uint32 p = ReadMacInt32(sp + spPointer) - ROMBaseMac; + ROMBaseHost[p + 8] = mode.bytes_per_row >> 8; + ROMBaseHost[p + 9] = mode.bytes_per_row; + ROMBaseHost[p + 14] = mode.y >> 8; + ROMBaseHost[p + 15] = mode.y; + ROMBaseHost[p + 16] = mode.x >> 8; + ROMBaseHost[p + 17] = mode.x; + + // Recalculate slot ROM checksum + ChecksumSlotROM(); + + // Update sResource + WriteMacInt8(sp + spID, ReadMacInt8(dce + dCtlSlotId)); + r.d[0] = 0x002b; + Execute68kTrap(0xa06e, &r); // SUpdateSRT() + + // Update frame buffer base in DCE and param block + WriteMacInt32(dce + dCtlDevBase, frame_base); + WriteMacInt32(param + csBaseAddr, frame_base); +} + + /* * Driver Open() routine */ @@ -338,11 +402,7 @@ int16 VideoDriverControl(uint32 pb, uint32 dce) vector::const_iterator i = find_mode(mode, VidLocal.current_id); if (i == VideoModes.end()) return paramErr; - set_gray_palette(); - video_switch_to_mode(*i); - VidLocal.current_mode = mode; - WriteMacInt32(param + csBaseAddr, VidLocal.desc->mac_frame_base); - WriteMacInt32(dce + dCtlDevBase, VidLocal.desc->mac_frame_base); + switch_mode(*i, param, dce); } D(bug(" base %08x\n", VidLocal.desc->mac_frame_base)); return noErr; @@ -497,61 +557,7 @@ int16 VideoDriverControl(uint32 pb, uint32 dce) vector::const_iterator i = find_mode(mode, id); if (i == VideoModes.end()) return paramErr; - set_gray_palette(); - video_switch_to_mode(*i); - VidLocal.current_mode = mode; - VidLocal.current_id = id; - uint32 frame_base = VidLocal.desc->mac_frame_base; - WriteMacInt32(param + csBaseAddr, frame_base); - - M68kRegisters r; - uint32 sp = VidLocal.slot_param; - r.a[0] = sp; - - // Find functional sResource for this display - WriteMacInt8(sp + spSlot, ReadMacInt8(dce + dCtlSlot)); - WriteMacInt8(sp + spID, ReadMacInt8(dce + dCtlSlotId)); - WriteMacInt8(sp + spExtDev, 0); - r.d[0] = 0x0016; - Execute68kTrap(0xa06e, &r); // SRsrcInfo() - uint32 rsrc = ReadMacInt32(sp + spPointer); - - // Patch minorBase (otherwise rebooting won't work) - WriteMacInt8(sp + spID, 0x0a); // minorBase - r.d[0] = 0x0006; - Execute68kTrap(0xa06e, &r); // SFindStruct() - uint32 minor_base = ReadMacInt32(sp + spPointer) - ROMBaseMac; - ROMBaseHost[minor_base + 0] = frame_base >> 24; - ROMBaseHost[minor_base + 1] = frame_base >> 16; - ROMBaseHost[minor_base + 2] = frame_base >> 8; - ROMBaseHost[minor_base + 3] = frame_base; - - // Patch video mode parameter table - WriteMacInt32(sp + spPointer, rsrc); - WriteMacInt8(sp + spID, mode); - r.d[0] = 0x0006; - Execute68kTrap(0xa06e, &r); // SFindStruct() - WriteMacInt8(sp + spID, 0x01); - r.d[0] = 0x0006; - Execute68kTrap(0xa06e, &r); // SFindStruct() - uint32 p = ReadMacInt32(sp + spPointer) - ROMBaseMac; - ROMBaseHost[p + 8] = i->bytes_per_row >> 8; - ROMBaseHost[p + 9] = i->bytes_per_row; - ROMBaseHost[p + 14] = i->y >> 8; - ROMBaseHost[p + 15] = i->y; - ROMBaseHost[p + 16] = i->x >> 8; - ROMBaseHost[p + 17] = i->x; - - // Recalculate slot ROM checksum - ChecksumSlotROM(); - - // Update sResource - WriteMacInt8(sp + spID, ReadMacInt8(dce + dCtlSlotId)); - r.d[0] = 0x002b; - Execute68kTrap(0xa06e, &r); // SUpdateSRT() - - // Update frame buffer base in DCE - WriteMacInt32(dce + dCtlDevBase, frame_base); + switch_mode(*i, param, dce); } D(bug(" base %08x\n", VidLocal.desc->mac_frame_base)); return noErr; @@ -751,8 +757,8 @@ int16 VideoDriverStatus(uint32 pb, uint32 dce) uint16 mode = ReadMacInt16(param + csDepthMode); D(bug(" GetVideoParameters %04x/%08x\n", mode, id)); - vector::const_iterator i = VideoModes.begin(), end = VideoModes.end(); - while (i != end) { + vector::const_iterator i, end = VideoModes.end(); + for (i = VideoModes.begin(); i != end; ++i) { if (DepthToAppleMode(i->depth) == mode && i->resolution_id == id) { uint32 vp = ReadMacInt32(param + csVPBlockPtr); WriteMacInt32(vp + vpBaseOffset, 0); @@ -807,7 +813,6 @@ int16 VideoDriverStatus(uint32 pb, uint32 dce) WriteMacInt32(param + csDeviceType, dev_type); return noErr; } - ++i; } return paramErr; // specified resolution/depth not supported }