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;
|
||||
}
|
||||
|
||||
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++)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
cdrom_ioctl[id].last_track_pos = pos;
|
||||
cdrom_ioctl[id].last_track_nr = 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;
|
||||
SUB_Q_CHANNEL_DATA sub;
|
||||
unsigned long size;
|
||||
int pos=0;
|
||||
int pos = 0, track;
|
||||
uint32_t cdpos, track_address, dat;
|
||||
|
||||
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;
|
||||
ioctl_open(id, 0);
|
||||
DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_Q_CHANNEL,&insub,sizeof(insub),&sub,sizeof(sub),&size,NULL);
|
||||
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)
|
||||
{
|
||||
uint32_t cdpos = cdrom[id].seek_pos;
|
||||
int track = get_track_nr(id, cdpos);
|
||||
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);
|
||||
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);
|
||||
|
||||
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)
|
||||
{
|
||||
uint32_t dat = cdpos;
|
||||
dat = cdpos;
|
||||
b[pos + 3] = (uint8_t)(dat % 75); dat /= 75;
|
||||
b[pos + 2] = (uint8_t)(dat % 60); dat /= 60;
|
||||
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 };
|
||||
UCHAR buf[16];
|
||||
|
||||
if (!cdrom_ioctl[id].capacity_read)
|
||||
{
|
||||
ioctl_open(id, 0);
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -1016,10 +1048,12 @@ int ioctl_open(uint8_t id, char d)
|
||||
if (!cdrom_ioctl[id].ioctl_inited)
|
||||
{
|
||||
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);
|
||||
cdrom_ioctl_windows[id].hIOCTL = NULL;
|
||||
}
|
||||
update_status_bar_icon_state(0x10 | id, 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -2953,7 +2953,11 @@ void cdrom_command(uint8_t id, uint8_t *cdb)
|
||||
alloc_length = 24;
|
||||
break;
|
||||
}
|
||||
if (alloc_length < len)
|
||||
if (!(cdb[2] & 0x40) || (cdb[3] == 0))
|
||||
{
|
||||
len = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
len = alloc_length;
|
||||
}
|
||||
|
||||
@@ -199,6 +199,13 @@ typedef struct
|
||||
int16_t cd_buffer[BUF_SIZE];
|
||||
int cd_buflen;
|
||||
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;
|
||||
|
||||
void ioctl_close(uint8_t id);
|
||||
|
||||
@@ -2156,6 +2156,12 @@ aha_cmd_cb(void *priv)
|
||||
} else if (AHA_InOperation == 1) {
|
||||
pclog("BusLogic Callback: Process CD-ROM request\n");
|
||||
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) {
|
||||
pclog("BusLogic Callback: Send incoming mailbox\n");
|
||||
aha_mbi(dev);
|
||||
|
||||
@@ -1970,6 +1970,12 @@ BuslogicCommandCallback(void *p)
|
||||
} else if (BuslogicInOperation == 1) {
|
||||
pclog("BusLogic Callback: Process CD-ROM request\n");
|
||||
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) {
|
||||
pclog("BusLogic Callback: Send incoming mailbox\n");
|
||||
BuslogicMailboxIn(bl);
|
||||
|
||||
73
src/win.c
73
src/win.c
@@ -617,7 +617,7 @@ HANDLE hinstAcc;
|
||||
|
||||
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)
|
||||
@@ -722,9 +722,7 @@ void update_status_bar_icon(int tag, int active)
|
||||
sb_part_icons[found] &= ~257;
|
||||
sb_part_icons[found] |= sb_icon_flags[found];
|
||||
|
||||
DestroyIcon(hIcon[found]);
|
||||
hIcon[found] = LoadIconEx((PCTSTR) sb_part_icons[found]);
|
||||
SendMessage(hwndStatus, SB_SETICON, found, (LPARAM) hIcon[found]);
|
||||
SendMessage(hwndStatus, SB_SETICON, found, (LPARAM) hIcon[sb_part_icons[found]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -751,29 +749,13 @@ void update_status_bar_icon_state(int tag, int state)
|
||||
|
||||
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] |= state ? 256 : 0;
|
||||
|
||||
sb_part_icons[found] &= ~257;
|
||||
sb_part_icons[found] |= sb_icon_flags[found];
|
||||
|
||||
DestroyIcon(hIcon[found]);
|
||||
hIcon[found] = LoadIconEx((PCTSTR) sb_part_icons[found]);
|
||||
SendMessage(hwndStatus, SB_SETICON, found, (LPARAM) hIcon[found]);
|
||||
SendMessage(hwndStatus, SB_SETICON, found, (LPARAM) hIcon[sb_part_icons[found]]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1052,9 +1034,7 @@ void update_status_bar_panes(HWND hwnds)
|
||||
if (sb_part_icons[i] != -1)
|
||||
{
|
||||
SendMessage(hwnds, SB_SETTEXT, i | SBT_NOBORDERS, (LPARAM) "");
|
||||
DestroyIcon(hIcon[i]);
|
||||
hIcon[i] = LoadIconEx((PCTSTR) sb_part_icons[i]);
|
||||
SendMessage(hwnds, SB_SETICON, i, (LPARAM) hIcon[i]);
|
||||
SendMessage(hwnds, SB_SETICON, i, (LPARAM) hIcon[sb_part_icons[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]); */
|
||||
}
|
||||
@@ -1072,6 +1052,51 @@ HWND EmulatorStatusBar(HWND hwndParent, int idStatus, HINSTANCE hinst)
|
||||
RECT rectDialog;
|
||||
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);
|
||||
dw = rectDialog.right - rectDialog.left;
|
||||
dh = rectDialog.bottom - rectDialog.top;
|
||||
|
||||
Reference in New Issue
Block a user