mirror of
https://github.com/kanjitalk755/macemu.git
synced 2025-03-03 20:30:11 +00:00
- 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:
parent
73912e732e
commit
af35353cf0
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 ?
|
||||
|
||||
|
@ -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++;
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user