- 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
This commit is contained in:
cebix 2001-07-01 14:38:03 +00:00
parent 73912e732e
commit af35353cf0
8 changed files with 366 additions and 366 deletions

View File

@ -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

View File

@ -19,6 +19,7 @@
*/
#include "sysdeps.h"
#include "video.h"
#include <stdio.h>
#include <stdlib.h>
@ -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

View File

@ -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 ?

View File

@ -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; i<num; i++) {
int c = (i * 256) / num;
palette[i].red = c * 0x0101;
palette[i].green = c * 0x0101;
palette[i].blue = c * 0x0101;
if (vis->c_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<num; i++) {
int c = (i * 256) / num;
palette[i].pixel = ((c >> 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<num; i++) {
int c = (i * 256) / num;
palette[i].red = c * 0x0101;
palette[i].green = c * 0x0101;
palette[i].blue = c * 0x0101;
if (color_class == PseudoColor)
palette[i].pixel = i;
palette[i].flags = DoRed | DoGreen | DoBlue;
palette[i].pixel = ((c >> 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<video_mode>::const_iterator i = VideoModes.begin(), end = VideoModes.end();
while (i != end) {
if (i->x == default_width && i->y == default_height)
std::vector<video_mode>::const_iterator i, end = VideoModes.end();
for (i = VideoModes.begin(); i != end; ++i) {
if (i->x == default_width && i->y == default_height && i->depth == default_depth)
return video_open(*i);
++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++;

View File

@ -29,6 +29,11 @@
*/
#include <string.h>
#include <vector>
#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<cdrom_drive_info> 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) {

View File

@ -27,6 +27,11 @@
*/
#include <string.h>
#include <vector>
#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<disk_drive_info> 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

View File

@ -29,6 +29,11 @@
*/
#include <string.h>
#include <vector>
#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<sony_drive_info> 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;

View File

@ -67,11 +67,10 @@ struct {
static bool has_resolution(uint32 id)
{
vector<video_mode>::const_iterator i = VideoModes.begin(), end = VideoModes.end();
while (i != end) {
vector<video_mode>::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<video_mode>::const_iterator find_mode(uint16 mode, uint32 id)
{
vector<video_mode>::const_iterator i = VideoModes.begin(), end = VideoModes.end();
while (i != end) {
vector<video_mode>::const_iterator i, end = VideoModes.end();
for (i = VideoModes.begin(); i != end; ++i) {
if (i->resolution_id == id && DepthToAppleMode(i->depth) == mode)
return i;
++i;
}
return i;
}
@ -100,11 +98,10 @@ static vector<video_mode>::const_iterator find_mode(uint16 mode, uint32 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) {
vector<video_mode>::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<video_mode>::const_iterator i = VideoModes.begin(), end = VideoModes.end();
while (i != end) {
vector<video_mode>::const_iterator i, end = VideoModes.end();
for (i = VideoModes.begin(); i != end; ++i) {
if (i->resolution_id == id) {
x = i->x;
y = i->y;
return;
}
++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<video_mode>::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<video_mode>::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<video_mode>::const_iterator i = VideoModes.begin(), end = VideoModes.end();
while (i != end) {
vector<video_mode>::const_iterator i, end = VideoModes.end();
for (i = VideoModes.begin(); i != end; ++i) {
if (DepthToAppleMode(i->depth) == mode && i->resolution_id == id) {
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
}