Both SCSI controllers now set the next callback to be issued after 1000 * TIMER_USEC instead of 50 * TIMER_USEC if the device is CD-ROM and the command is 0x42 (READ SUBCHANNEL);
A few CD-ROM IOCTL commands are cached now; CD Audio over IOCTL works again; The status bar icons are now only loaded once at emulator start, and subsequently just used on demand.
This commit is contained in:
@@ -107,6 +107,11 @@ static int get_track_nr(uint8_t id, uint32_t pos)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cdrom_ioctl[id].last_track_pos == pos)
|
||||||
|
{
|
||||||
|
return cdrom_ioctl[id].last_track_nr;
|
||||||
|
}
|
||||||
|
|
||||||
for (c = cdrom_ioctl_windows[id].toc.FirstTrack; c < cdrom_ioctl_windows[id].toc.LastTrack; c++)
|
for (c = cdrom_ioctl_windows[id].toc.FirstTrack; c < cdrom_ioctl_windows[id].toc.LastTrack; c++)
|
||||||
{
|
{
|
||||||
uint32_t track_address = cdrom_ioctl_windows[id].toc.TrackData[c].Address[3] +
|
uint32_t track_address = cdrom_ioctl_windows[id].toc.TrackData[c].Address[3] +
|
||||||
@@ -118,6 +123,9 @@ static int get_track_nr(uint8_t id, uint32_t pos)
|
|||||||
track = c;
|
track = c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
cdrom_ioctl[id].last_track_pos = pos;
|
||||||
|
cdrom_ioctl[id].last_track_nr = track;
|
||||||
|
|
||||||
return track;
|
return track;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -349,19 +357,35 @@ static uint8_t ioctl_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf)
|
|||||||
CDROM_SUB_Q_DATA_FORMAT insub;
|
CDROM_SUB_Q_DATA_FORMAT insub;
|
||||||
SUB_Q_CHANNEL_DATA sub;
|
SUB_Q_CHANNEL_DATA sub;
|
||||||
unsigned long size;
|
unsigned long size;
|
||||||
int pos=0;
|
int pos = 0, track;
|
||||||
|
uint32_t cdpos, track_address, dat;
|
||||||
|
|
||||||
if (!cdrom_drives[id].host_drive) return 0;
|
if (!cdrom_drives[id].host_drive) return 0;
|
||||||
|
|
||||||
|
cdpos = cdrom[id].seek_pos;
|
||||||
|
|
||||||
|
if (cdrom_ioctl[id].last_subchannel_pos == cdpos)
|
||||||
|
{
|
||||||
|
memcpy(&insub, cdrom_ioctl[id].sub_q_data_format, sizeof(insub));
|
||||||
|
memcpy(&sub, cdrom_ioctl[id].sub_q_channel_data, sizeof(sub));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
insub.Format = IOCTL_CDROM_CURRENT_POSITION;
|
insub.Format = IOCTL_CDROM_CURRENT_POSITION;
|
||||||
ioctl_open(id, 0);
|
ioctl_open(id, 0);
|
||||||
DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_Q_CHANNEL,&insub,sizeof(insub),&sub,sizeof(sub),&size,NULL);
|
DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_Q_CHANNEL,&insub,sizeof(insub),&sub,sizeof(sub),&size,NULL);
|
||||||
ioctl_close(id);
|
ioctl_close(id);
|
||||||
|
memset(cdrom_ioctl[id].sub_q_data_format, 0, 16);
|
||||||
|
memcpy(cdrom_ioctl[id].sub_q_data_format, &insub, sizeof(insub));
|
||||||
|
memset(cdrom_ioctl[id].sub_q_channel_data, 0, 256);
|
||||||
|
memcpy(cdrom_ioctl[id].sub_q_channel_data, &sub, sizeof(sub));
|
||||||
|
cdrom_ioctl[id].last_subchannel_pos = cdpos;
|
||||||
|
}
|
||||||
|
|
||||||
if (cdrom_ioctl[id].cd_state == CD_PLAYING || cdrom_ioctl[id].cd_state == CD_PAUSED)
|
if (cdrom_ioctl[id].cd_state == CD_PLAYING || cdrom_ioctl[id].cd_state == CD_PAUSED)
|
||||||
{
|
{
|
||||||
uint32_t cdpos = cdrom[id].seek_pos;
|
track = get_track_nr(id, cdpos);
|
||||||
int track = get_track_nr(id, cdpos);
|
track_address = cdrom_ioctl_windows[id].toc.TrackData[track].Address[3] + (cdrom_ioctl_windows[id].toc.TrackData[track].Address[2] * 75) + (cdrom_ioctl_windows[id].toc.TrackData[track].Address[1] * 75 * 60);
|
||||||
uint32_t track_address = cdrom_ioctl_windows[id].toc.TrackData[track].Address[3] + (cdrom_ioctl_windows[id].toc.TrackData[track].Address[2] * 75) + (cdrom_ioctl_windows[id].toc.TrackData[track].Address[1] * 75 * 60);
|
|
||||||
|
|
||||||
cdrom_ioctl_log("cdpos = %i, track = %i, track_address = %i\n", cdpos, track, track_address);
|
cdrom_ioctl_log("cdpos = %i, track = %i, track_address = %i\n", cdpos, track, track_address);
|
||||||
|
|
||||||
@@ -371,7 +395,7 @@ static uint8_t ioctl_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf)
|
|||||||
|
|
||||||
if (msf)
|
if (msf)
|
||||||
{
|
{
|
||||||
uint32_t dat = cdpos;
|
dat = cdpos;
|
||||||
b[pos + 3] = (uint8_t)(dat % 75); dat /= 75;
|
b[pos + 3] = (uint8_t)(dat % 75); dat /= 75;
|
||||||
b[pos + 2] = (uint8_t)(dat % 60); dat /= 60;
|
b[pos + 2] = (uint8_t)(dat % 60); dat /= 60;
|
||||||
b[pos + 1] = (uint8_t)dat;
|
b[pos + 1] = (uint8_t)dat;
|
||||||
@@ -709,11 +733,19 @@ static void ioctl_read_capacity(uint8_t id, uint8_t *b)
|
|||||||
const UCHAR cdb[] = { 0x25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
const UCHAR cdb[] = { 0x25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
UCHAR buf[16];
|
UCHAR buf[16];
|
||||||
|
|
||||||
|
if (!cdrom_ioctl[id].capacity_read)
|
||||||
|
{
|
||||||
ioctl_open(id, 0);
|
ioctl_open(id, 0);
|
||||||
|
|
||||||
SCSICommand(id, cdb, buf, &len, 1);
|
SCSICommand(id, cdb, buf, &len, 1);
|
||||||
|
|
||||||
memcpy(b, buf, len);
|
memcpy(cdrom_ioctl[id].rcbuf, buf, len);
|
||||||
|
cdrom_ioctl[id].capacity_read = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy(b, cdrom_ioctl[id].rcbuf, 16);
|
||||||
|
}
|
||||||
|
|
||||||
ioctl_close(id);
|
ioctl_close(id);
|
||||||
}
|
}
|
||||||
@@ -1016,10 +1048,12 @@ int ioctl_open(uint8_t id, char d)
|
|||||||
if (!cdrom_ioctl[id].ioctl_inited)
|
if (!cdrom_ioctl[id].ioctl_inited)
|
||||||
{
|
{
|
||||||
cdrom_ioctl[id].ioctl_inited=1;
|
cdrom_ioctl[id].ioctl_inited=1;
|
||||||
|
cdrom_ioctl[id].capacity_read=0; /* With this two lines, we read the READ CAPACITY command output from the host drive into our cache buffer. */
|
||||||
|
ioctl_read_capacity(id, NULL);
|
||||||
CloseHandle(cdrom_ioctl_windows[id].hIOCTL);
|
CloseHandle(cdrom_ioctl_windows[id].hIOCTL);
|
||||||
cdrom_ioctl_windows[id].hIOCTL = NULL;
|
cdrom_ioctl_windows[id].hIOCTL = NULL;
|
||||||
}
|
|
||||||
update_status_bar_icon_state(0x10 | id, 0);
|
update_status_bar_icon_state(0x10 | id, 0);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2953,7 +2953,11 @@ void cdrom_command(uint8_t id, uint8_t *cdb)
|
|||||||
alloc_length = 24;
|
alloc_length = 24;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (alloc_length < len)
|
if (!(cdb[2] & 0x40) || (cdb[3] == 0))
|
||||||
|
{
|
||||||
|
len = 4;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
len = alloc_length;
|
len = alloc_length;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -199,6 +199,13 @@ typedef struct
|
|||||||
int16_t cd_buffer[BUF_SIZE];
|
int16_t cd_buffer[BUF_SIZE];
|
||||||
int cd_buflen;
|
int cd_buflen;
|
||||||
int actual_requested_blocks;
|
int actual_requested_blocks;
|
||||||
|
int last_track_pos;
|
||||||
|
int last_track_nr;
|
||||||
|
int capacity_read;
|
||||||
|
uint8_t rcbuf[16];
|
||||||
|
uint8_t sub_q_data_format[16];
|
||||||
|
uint8_t sub_q_channel_data[256];
|
||||||
|
int last_subchannel_pos;
|
||||||
} cdrom_ioctl_t;
|
} cdrom_ioctl_t;
|
||||||
|
|
||||||
void ioctl_close(uint8_t id);
|
void ioctl_close(uint8_t id);
|
||||||
|
|||||||
@@ -2156,6 +2156,12 @@ aha_cmd_cb(void *priv)
|
|||||||
} else if (AHA_InOperation == 1) {
|
} else if (AHA_InOperation == 1) {
|
||||||
pclog("BusLogic Callback: Process CD-ROM request\n");
|
pclog("BusLogic Callback: Process CD-ROM request\n");
|
||||||
aha_cdrom_cmd(dev);
|
aha_cdrom_cmd(dev);
|
||||||
|
if (dev->Req.CmdBlock.common.Cdb[0] == 0x42)
|
||||||
|
{
|
||||||
|
/* This is needed since CD Audio inevitably means READ SUBCHANNEL spam. */
|
||||||
|
AHA_Callback += 1000 * SCSI_TIME;
|
||||||
|
return;
|
||||||
|
}
|
||||||
} else if (AHA_InOperation == 2) {
|
} else if (AHA_InOperation == 2) {
|
||||||
pclog("BusLogic Callback: Send incoming mailbox\n");
|
pclog("BusLogic Callback: Send incoming mailbox\n");
|
||||||
aha_mbi(dev);
|
aha_mbi(dev);
|
||||||
|
|||||||
@@ -1970,6 +1970,12 @@ BuslogicCommandCallback(void *p)
|
|||||||
} else if (BuslogicInOperation == 1) {
|
} else if (BuslogicInOperation == 1) {
|
||||||
pclog("BusLogic Callback: Process CD-ROM request\n");
|
pclog("BusLogic Callback: Process CD-ROM request\n");
|
||||||
BuslogicCDROMCommand(bl);
|
BuslogicCDROMCommand(bl);
|
||||||
|
if (bl->Req.CmdBlock.common.Cdb[0] == 0x42)
|
||||||
|
{
|
||||||
|
/* This is needed since CD Audio inevitably means READ SUBCHANNEL spam. */
|
||||||
|
BuslogicCallback += 1000 * SCSI_TIME;
|
||||||
|
return;
|
||||||
|
}
|
||||||
} else if (BuslogicInOperation == 2) {
|
} else if (BuslogicInOperation == 2) {
|
||||||
pclog("BusLogic Callback: Send incoming mailbox\n");
|
pclog("BusLogic Callback: Send incoming mailbox\n");
|
||||||
BuslogicMailboxIn(bl);
|
BuslogicMailboxIn(bl);
|
||||||
|
|||||||
73
src/win.c
73
src/win.c
@@ -617,7 +617,7 @@ HANDLE hinstAcc;
|
|||||||
|
|
||||||
HICON LoadIconEx(PCTSTR pszIconName)
|
HICON LoadIconEx(PCTSTR pszIconName)
|
||||||
{
|
{
|
||||||
return (HICON) LoadImage(hinstance, pszIconName, IMAGE_ICON, 16, 16, 0);
|
return (HICON) LoadImage(hinstance, pszIconName, IMAGE_ICON, 16, 16, LR_SHARED);
|
||||||
}
|
}
|
||||||
|
|
||||||
HICON LoadIconBig(PCTSTR pszIconName)
|
HICON LoadIconBig(PCTSTR pszIconName)
|
||||||
@@ -722,9 +722,7 @@ void update_status_bar_icon(int tag, int active)
|
|||||||
sb_part_icons[found] &= ~257;
|
sb_part_icons[found] &= ~257;
|
||||||
sb_part_icons[found] |= sb_icon_flags[found];
|
sb_part_icons[found] |= sb_icon_flags[found];
|
||||||
|
|
||||||
DestroyIcon(hIcon[found]);
|
SendMessage(hwndStatus, SB_SETICON, found, (LPARAM) hIcon[sb_part_icons[found]]);
|
||||||
hIcon[found] = LoadIconEx((PCTSTR) sb_part_icons[found]);
|
|
||||||
SendMessage(hwndStatus, SB_SETICON, found, (LPARAM) hIcon[found]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -751,29 +749,13 @@ void update_status_bar_icon_state(int tag, int state)
|
|||||||
|
|
||||||
if (found != -1)
|
if (found != -1)
|
||||||
{
|
{
|
||||||
if (state)
|
|
||||||
{
|
|
||||||
switch(tag & 0xf0)
|
|
||||||
{
|
|
||||||
case 0x00:
|
|
||||||
default:
|
|
||||||
discfns[tag & 0x0f][0] = L'\0';
|
|
||||||
break;
|
|
||||||
case 0x10:
|
|
||||||
cdrom_image[tag & 0x0f].image_path[0] = L'\0';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sb_icon_flags[found] &= ~256;
|
sb_icon_flags[found] &= ~256;
|
||||||
sb_icon_flags[found] |= state ? 256 : 0;
|
sb_icon_flags[found] |= state ? 256 : 0;
|
||||||
|
|
||||||
sb_part_icons[found] &= ~257;
|
sb_part_icons[found] &= ~257;
|
||||||
sb_part_icons[found] |= sb_icon_flags[found];
|
sb_part_icons[found] |= sb_icon_flags[found];
|
||||||
|
|
||||||
DestroyIcon(hIcon[found]);
|
SendMessage(hwndStatus, SB_SETICON, found, (LPARAM) hIcon[sb_part_icons[found]]);
|
||||||
hIcon[found] = LoadIconEx((PCTSTR) sb_part_icons[found]);
|
|
||||||
SendMessage(hwndStatus, SB_SETICON, found, (LPARAM) hIcon[found]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1052,9 +1034,7 @@ void update_status_bar_panes(HWND hwnds)
|
|||||||
if (sb_part_icons[i] != -1)
|
if (sb_part_icons[i] != -1)
|
||||||
{
|
{
|
||||||
SendMessage(hwnds, SB_SETTEXT, i | SBT_NOBORDERS, (LPARAM) "");
|
SendMessage(hwnds, SB_SETTEXT, i | SBT_NOBORDERS, (LPARAM) "");
|
||||||
DestroyIcon(hIcon[i]);
|
SendMessage(hwnds, SB_SETICON, i, (LPARAM) hIcon[sb_part_icons[i]]);
|
||||||
hIcon[i] = LoadIconEx((PCTSTR) sb_part_icons[i]);
|
|
||||||
SendMessage(hwnds, SB_SETICON, i, (LPARAM) hIcon[i]);
|
|
||||||
SendMessage(hwnds, SB_SETTIPTEXT, i, (LPARAM) sbTips[i]);
|
SendMessage(hwnds, SB_SETTIPTEXT, i, (LPARAM) sbTips[i]);
|
||||||
/* pclog("Status bar part found: %02X (%i)\n", sb_part_meanings[i], sb_part_icons[i]); */
|
/* pclog("Status bar part found: %02X (%i)\n", sb_part_meanings[i], sb_part_icons[i]); */
|
||||||
}
|
}
|
||||||
@@ -1072,6 +1052,51 @@ HWND EmulatorStatusBar(HWND hwndParent, int idStatus, HINSTANCE hinst)
|
|||||||
RECT rectDialog;
|
RECT rectDialog;
|
||||||
int dw, dh;
|
int dw, dh;
|
||||||
|
|
||||||
|
for (i = 128; i < 136; i++)
|
||||||
|
{
|
||||||
|
hIcon[i] = LoadIconEx((PCTSTR) i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 144; i < 148; i++)
|
||||||
|
{
|
||||||
|
hIcon[i] = LoadIconEx((PCTSTR) i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 150; i < 154; i++)
|
||||||
|
{
|
||||||
|
hIcon[i] = LoadIconEx((PCTSTR) i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 160; i < 166; i++)
|
||||||
|
{
|
||||||
|
hIcon[i] = LoadIconEx((PCTSTR) i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 176; i < 184; i++)
|
||||||
|
{
|
||||||
|
hIcon[i] = LoadIconEx((PCTSTR) i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 384; i < 392; i++)
|
||||||
|
{
|
||||||
|
hIcon[i] = LoadIconEx((PCTSTR) i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 400; i < 404; i++)
|
||||||
|
{
|
||||||
|
hIcon[i] = LoadIconEx((PCTSTR) i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 406; i < 410; i++)
|
||||||
|
{
|
||||||
|
hIcon[i] = LoadIconEx((PCTSTR) i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 416; i < 422; i++)
|
||||||
|
{
|
||||||
|
hIcon[i] = LoadIconEx((PCTSTR) i);
|
||||||
|
}
|
||||||
|
|
||||||
GetWindowRect(hwndParent, &rectDialog);
|
GetWindowRect(hwndParent, &rectDialog);
|
||||||
dw = rectDialog.right - rectDialog.left;
|
dw = rectDialog.right - rectDialog.left;
|
||||||
dh = rectDialog.bottom - rectDialog.top;
|
dh = rectDialog.bottom - rectDialog.top;
|
||||||
|
|||||||
Reference in New Issue
Block a user