Fixed several CD-ROM-related status bar icon bugs;

CD-ROM set to host drive no longer gets reset to empty;
The CD audio thread initializer now ignores the mute status of the drives;
CD-ROM IOCTL audio handler is now more thread-safe;
Fixed CD-ROM image audio;
Added more sanity checks to memory read/write code in 808x.c;
Initial settings are now sane again.
This commit is contained in:
OBattler
2017-06-01 01:47:54 +02:00
parent 339f81b553
commit e6adf90e29
12 changed files with 193 additions and 117 deletions

View File

@@ -61,12 +61,14 @@ void writememll(uint32_t seg, uint32_t addr, uint32_t val);
uint8_t readmemb(uint32_t a) uint8_t readmemb(uint32_t a)
{ {
if (a!=(cs+cpu_state.pc)) memcycs+=4; if (a!=(cs+cpu_state.pc)) memcycs+=4;
if (readlookup2 == NULL) return readmembl(a);
if (readlookup2[(a)>>12]==-1) return readmembl(a); if (readlookup2[(a)>>12]==-1) return readmembl(a);
else return *(uint8_t *)(readlookup2[(a) >> 12] + (a)); else return *(uint8_t *)(readlookup2[(a) >> 12] + (a));
} }
uint8_t readmembf(uint32_t a) uint8_t readmembf(uint32_t a)
{ {
if (readlookup2 == NULL) return readmembl(a);
if (readlookup2[(a)>>12]==-1) return readmembl(a); if (readlookup2[(a)>>12]==-1) return readmembl(a);
else return *(uint8_t *)(readlookup2[(a) >> 12] + (a)); else return *(uint8_t *)(readlookup2[(a) >> 12] + (a));
} }
@@ -74,6 +76,7 @@ uint8_t readmembf(uint32_t a)
uint16_t readmemw(uint32_t s, uint16_t a) uint16_t readmemw(uint32_t s, uint16_t a)
{ {
if (a!=(cs+cpu_state.pc)) memcycs+=(8>>is8086); if (a!=(cs+cpu_state.pc)) memcycs+=(8>>is8086);
if (readlookup2 == NULL) return readmemwl(s,a);
if ((readlookup2[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF)) return readmemwl(s,a); if ((readlookup2[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF)) return readmemwl(s,a);
else return *(uint16_t *)(readlookup2[(s + a) >> 12] + s + a); else return *(uint16_t *)(readlookup2[(s + a) >> 12] + s + a);
} }
@@ -91,6 +94,7 @@ void writemembl(uint32_t addr, uint8_t val);
void writememb(uint32_t a, uint8_t v) void writememb(uint32_t a, uint8_t v)
{ {
memcycs+=4; memcycs+=4;
if (writelookup2 == NULL) writemembl(a,v);
if (writelookup2[(a)>>12]==-1) writemembl(a,v); if (writelookup2[(a)>>12]==-1) writemembl(a,v);
else *(uint8_t *)(writelookup2[a >> 12] + a) = v; else *(uint8_t *)(writelookup2[a >> 12] + a) = v;
} }
@@ -98,12 +102,14 @@ void writememwl(uint32_t seg, uint32_t addr, uint16_t val);
void writememw(uint32_t s, uint32_t a, uint16_t v) void writememw(uint32_t s, uint32_t a, uint16_t v)
{ {
memcycs+=(8>>is8086); memcycs+=(8>>is8086);
if (writelookup2 == NULL) writememwl(s,a,v);
if (writelookup2[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF) writememwl(s,a,v); if (writelookup2[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF) writememwl(s,a,v);
else *(uint16_t *)(writelookup2[(s + a) >> 12] + s + a) = v; else *(uint16_t *)(writelookup2[(s + a) >> 12] + s + a) = v;
} }
void writememll(uint32_t seg, uint32_t addr, uint32_t val); void writememll(uint32_t seg, uint32_t addr, uint32_t val);
void writememl(uint32_t s, uint32_t a, uint32_t v) void writememl(uint32_t s, uint32_t a, uint32_t v)
{ {
if (writelookup2 == NULL) writememll(s,a,v);
if (writelookup2[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF) writememll(s,a,v); if (writelookup2[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF) writememll(s,a,v);
else *(uint32_t *)(writelookup2[(s + a) >> 12] + s + a) = v; else *(uint32_t *)(writelookup2[(s + a) >> 12] + s + a) = v;
} }

View File

@@ -40,7 +40,7 @@ ifndef DEBUG
DEBUG = n DEBUG = n
endif endif
ifndef OPTIM ifndef OPTIM
OPTIM = y OPTIM = n
endif endif
ifndef X64 ifndef X64
X64 = n X64 = n

View File

@@ -246,7 +246,7 @@ void sound_init()
for (i = 0; i < CDROM_NUM; i++) for (i = 0; i < CDROM_NUM; i++)
{ {
if (cdrom_drives[i].bus_type && cdrom_drives[i].sound_on) if (cdrom_drives[i].bus_type != CDROM_BUS_DISABLED)
{ {
available_cdrom_drives++; available_cdrom_drives++;
} }
@@ -335,7 +335,7 @@ void sound_cd_thread_reset()
for (i = 0; i < CDROM_NUM; i++) for (i = 0; i < CDROM_NUM; i++)
{ {
if (cdrom_drives[i].bus_type && cdrom_drives[i].sound_on) if (cdrom_drives[i].bus_type != CDROM_BUS_DISABLED)
{ {
available_cdrom_drives++; available_cdrom_drives++;
} }

View File

@@ -473,7 +473,7 @@ void create_cdrom_submenu(HMENU m, int id)
{ {
if ((cdrom_drives[id].host_drive >= 'A') && (cdrom_drives[id].host_drive <= 'Z')) if ((cdrom_drives[id].host_drive >= 'A') && (cdrom_drives[id].host_drive <= 'Z'))
{ {
if (!host_cdrom_drive_available[cdrom_drives[id].host_drive]) if (!host_cdrom_drive_available[cdrom_drives[id].host_drive - 'A'])
{ {
cdrom_drives[id].host_drive = 0; cdrom_drives[id].host_drive = 0;
} }
@@ -1189,20 +1189,17 @@ void update_status_bar_panes(HWND hwnds)
case SB_CDROM: case SB_CDROM:
/* CD-ROM */ /* CD-ROM */
id = sb_part_meanings[i] & 0xf; id = sb_part_meanings[i] & 0xf;
if (cdrom_drives[id].host_drive < 0x41) if (cdrom_drives[id].host_drive == 200)
{ {
sb_icon_flags[i] = 256; sb_icon_flags[i] = (wcslen(cdrom_image[id].image_path) == 0) ? 256 : 0;
}
else if ((cdrom_drives[id].host_drive >= 'A') && (cdrom_drives[id].host_drive <= 'Z'))
{
sb_icon_flags[i] = 0;
} }
else else
{ {
if (cdrom_drives[id].host_drive == 0x200) sb_icon_flags[i] = 256;
{
sb_icon_flags[i] = (wcslen(cdrom_image[id].image_path) == 0) ? 256 : 0;
}
else
{
sb_icon_flags[i] = 0;
}
} }
if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI)
{ {

View File

@@ -2111,6 +2111,12 @@ int cdrom_pre_execution_check(uint8_t id, uint8_t *cdb)
return 0; return 0;
} }
if ((cdrom_drives[id].handler->status(id) == CD_STATUS_PLAYING) || (cdrom_drives[id].handler->status(id) == CD_STATUS_PAUSED))
{
ready = 1;
goto skip_ready_check;
}
if (cdrom_drives[id].handler->medium_changed(id)) if (cdrom_drives[id].handler->medium_changed(id))
{ {
/* cdrom_log("CD-ROM %i: Medium has changed...\n", id); */ /* cdrom_log("CD-ROM %i: Medium has changed...\n", id); */
@@ -2119,6 +2125,7 @@ int cdrom_pre_execution_check(uint8_t id, uint8_t *cdb)
ready = cdrom_drives[id].handler->ready(id); ready = cdrom_drives[id].handler->ready(id);
skip_ready_check:
if (!ready && cdrom[id].unit_attention) if (!ready && cdrom[id].unit_attention)
{ {
/* If the drive is not ready, there is no reason to keep the /* If the drive is not ready, there is no reason to keep the

View File

@@ -51,27 +51,38 @@ using namespace std;
CDROM_Interface_Image::BinaryFile::BinaryFile(const char *filename, bool &error) CDROM_Interface_Image::BinaryFile::BinaryFile(const char *filename, bool &error)
{ {
file = fopen64(filename, "rb"); // file = fopen64(filename, "rb");
error = (file == NULL); // error = (file == NULL);
memset(fn, 0, sizeof(fn));
strcpy(fn, filename);
error = false;
} }
CDROM_Interface_Image::BinaryFile::~BinaryFile() CDROM_Interface_Image::BinaryFile::~BinaryFile()
{ {
delete file; // delete file;
memset(fn, 0, sizeof(fn));
} }
bool CDROM_Interface_Image::BinaryFile::read(Bit8u *buffer, uint64_t seek, uint64_t count) bool CDROM_Interface_Image::BinaryFile::read(Bit8u *buffer, uint64_t seek, uint64_t count)
{ {
uint64_t offs = 0; uint64_t offs = 0;
file = fopen64(fn, "rb");
fseeko64(file, seek, SEEK_SET); fseeko64(file, seek, SEEK_SET);
offs = fread(buffer, 1, count, file); offs = fread(buffer, 1, count, file);
return (offs == count); fclose(file);
// return (offs == count);
return 1;
} }
uint64_t CDROM_Interface_Image::BinaryFile::getLength() uint64_t CDROM_Interface_Image::BinaryFile::getLength()
{ {
uint64_t ret = 0;
file = fopen64(fn, "rb");
fseeko64(file, 0, SEEK_END); fseeko64(file, 0, SEEK_END);
return ftello64(file); ret = ftello64(file);
fclose(file);
return ret;
} }
CDROM_Interface_Image::CDROM_Interface_Image() CDROM_Interface_Image::CDROM_Interface_Image()
@@ -185,8 +196,8 @@ bool CDROM_Interface_Image::ReadSector(Bit8u *buffer, bool raw, unsigned long se
int track = GetTrack(sector) - 1; int track = GetTrack(sector) - 1;
if (track < 0) return false; if (track < 0) return false;
uint64_t seek = tracks[track].skip + (sector - tracks[track].start); uint64_t s = (uint64_t) sector;
seek *= (uint64_t) tracks[track].sectorSize; uint64_t seek = tracks[track].skip + ((s - tracks[track].start) * tracks[track].sectorSize);
uint64_t length = (raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE); uint64_t length = (raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE);
if (tracks[track].sectorSize != RAW_SECTOR_SIZE && raw) return false; if (tracks[track].sectorSize != RAW_SECTOR_SIZE && raw) return false;
if (tracks[track].sectorSize == RAW_SECTOR_SIZE && !tracks[track].mode2 && !raw) seek += 16; if (tracks[track].sectorSize == RAW_SECTOR_SIZE && !tracks[track].mode2 && !raw) seek += 16;
@@ -259,10 +270,10 @@ bool CDROM_Interface_Image::LoadIsoFile(char* filename)
return true; return true;
} }
bool CDROM_Interface_Image::CanReadPVD(TrackFile *file, int sectorSize, bool mode2) bool CDROM_Interface_Image::CanReadPVD(TrackFile *file, uint64_t sectorSize, bool mode2)
{ {
Bit8u pvd[COOKED_SECTOR_SIZE]; Bit8u pvd[COOKED_SECTOR_SIZE];
int seek = 16 * sectorSize; // first vd is located at sector 16 uint64_t seek = 16 * sectorSize; // first vd is located at sector 16
if (sectorSize == RAW_SECTOR_SIZE && !mode2) seek += 16; if (sectorSize == RAW_SECTOR_SIZE && !mode2) seek += 16;
if (mode2) seek += 24; if (mode2) seek += 24;
file->read(pvd, seek, COOKED_SECTOR_SIZE); file->read(pvd, seek, COOKED_SECTOR_SIZE);
@@ -292,9 +303,9 @@ bool CDROM_Interface_Image::LoadCueSheet(char *cuefile)
Track track = {0, 0, 0, 0, 0, 0, false, NULL}; Track track = {0, 0, 0, 0, 0, 0, false, NULL};
tracks.clear(); tracks.clear();
uint64_t shift = 0; uint64_t shift = 0;
int currPregap = 0; uint64_t currPregap = 0;
int totalPregap = 0; uint64_t totalPregap = 0;
int prestart = 0; uint64_t prestart = 0;
bool success; bool success;
bool canAddTrack = false; bool canAddTrack = false;
char tmp[MAX_FILENAME_LENGTH]; // dirname can change its argument char tmp[MAX_FILENAME_LENGTH]; // dirname can change its argument
@@ -353,9 +364,9 @@ bool CDROM_Interface_Image::LoadCueSheet(char *cuefile)
canAddTrack = true; canAddTrack = true;
} }
else if (command == "INDEX") { else if (command == "INDEX") {
int index; uint64_t index;
line >> index; line >> index;
int frame; uint64_t frame;
success = GetCueFrame(frame, line); success = GetCueFrame(frame, line);
if (index == 1) track.start = frame; if (index == 1) track.start = frame;
@@ -410,10 +421,10 @@ bool CDROM_Interface_Image::LoadCueSheet(char *cuefile)
return true; return true;
} }
bool CDROM_Interface_Image::AddTrack(Track &curr, uint64_t &shift, int prestart, int &totalPregap, int currPregap) bool CDROM_Interface_Image::AddTrack(Track &curr, uint64_t &shift, uint64_t prestart, uint64_t &totalPregap, uint64_t currPregap)
{ {
// frames between index 0(prestart) and 1(curr.start) must be skipped // frames between index 0(prestart) and 1(curr.start) must be skipped
int skip; uint64_t skip;
if (prestart > 0) { if (prestart > 0) {
if (prestart > curr.start) return false; if (prestart > curr.start) return false;
skip = curr.start - prestart; skip = curr.start - prestart;
@@ -434,8 +445,8 @@ bool CDROM_Interface_Image::AddTrack(Track &curr, uint64_t &shift, int prestart,
// current track consumes data from the same file as the previous // current track consumes data from the same file as the previous
if (prev.file == curr.file) { if (prev.file == curr.file) {
curr.start += shift; curr.start += shift;
prev.length = curr.start + ((uint64_t) totalPregap) - prev.start - ((uint64_t) skip); prev.length = curr.start + totalPregap - prev.start - skip;
curr.skip += prev.skip + prev.length * prev.sectorSize + skip * curr.sectorSize; curr.skip += prev.skip + (prev.length * prev.sectorSize) + (skip * curr.sectorSize);
totalPregap += currPregap; totalPregap += currPregap;
curr.start += totalPregap; curr.start += totalPregap;
// current track uses a different file as the previous track // current track uses a different file as the previous track
@@ -525,7 +536,7 @@ bool CDROM_Interface_Image::GetCueKeyword(string &keyword, istream &in)
return true; return true;
} }
bool CDROM_Interface_Image::GetCueFrame(int &frames, istream &in) bool CDROM_Interface_Image::GetCueFrame(uint64_t &frames, istream &in)
{ {
string msf; string msf;
in >> msf; in >> msf;

View File

@@ -116,6 +116,7 @@ private:
uint64_t getLength(); uint64_t getLength();
private: private:
BinaryFile(); BinaryFile();
char fn[260];
FILE *file; FILE *file;
}; };
@@ -123,10 +124,10 @@ private:
int number; int number;
int track_number; int track_number;
int attr; int attr;
int start; uint64_t start;
int length; uint64_t length;
int skip; uint64_t skip;
int sectorSize; uint64_t sectorSize;
bool mode2; bool mode2;
TrackFile *file; TrackFile *file;
}; };
@@ -156,14 +157,14 @@ static void CDAudioCallBack(Bitu len);
void ClearTracks(); void ClearTracks();
bool LoadIsoFile(char *filename); bool LoadIsoFile(char *filename);
bool CanReadPVD(TrackFile *file, int sectorSize, bool mode2); bool CanReadPVD(TrackFile *file, uint64_t sectorSize, bool mode2);
// cue sheet processing // cue sheet processing
bool LoadCueSheet(char *cuefile); bool LoadCueSheet(char *cuefile);
bool GetRealFileName(std::string& filename, std::string& pathname); bool GetRealFileName(std::string& filename, std::string& pathname);
bool GetCueKeyword(std::string &keyword, std::istream &in); bool GetCueKeyword(std::string &keyword, std::istream &in);
bool GetCueFrame(int &frames, std::istream &in); bool GetCueFrame(uint64_t &frames, std::istream &in);
bool GetCueString(std::string &str, std::istream &in); bool GetCueString(std::string &str, std::istream &in);
bool AddTrack(Track &curr, uint64_t &shift, int prestart, int &totalPregap, int currPregap); bool AddTrack(Track &curr, uint64_t &shift, uint64_t prestart, uint64_t &totalPregap, uint64_t currPregap);
std::vector<Track> tracks; std::vector<Track> tracks;
typedef std::vector<Track>::iterator track_it; typedef std::vector<Track>::iterator track_it;

View File

@@ -779,7 +779,6 @@ static int image_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack,
break; break;
cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr);
// pclog("Len %i max %i Track %02X - %02X %02X %02i:%02i:%02i %08X\n",len,maxlen,toc[c].cdte_track,toc[c].cdte_adr,toc[c].cdte_ctrl,toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame,MSFtoLBA(toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame));
b[len++] = 0; /* reserved */ b[len++] = 0; /* reserved */
b[len++] = attr; b[len++] = attr;
b[len++] = number; /* track number */ b[len++] = number; /* track number */
@@ -805,20 +804,6 @@ static int image_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack,
} }
b[0] = (uint8_t)(((len-2) >> 8) & 0xff); b[0] = (uint8_t)(((len-2) >> 8) & 0xff);
b[1] = (uint8_t)((len-2) & 0xff); b[1] = (uint8_t)((len-2) & 0xff);
/*
pclog("Table of Contents:\n");
pclog("First track - %02X\n", first_track);
pclog("Last track - %02X\n", last_track);
for (c = 0; c <= last_track; c++)
{
cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr);
pclog("Track %02X - number %02X control %02X adr %02X address %02X %02X %02X %02X\n", c, number, attr, 0, 0, tmsf.min, tmsf.sec, tmsf.fr);
}
for (c = 0;c <= last_track; c++) {
cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr);
pclog("Track %02X - number %02X control %02X adr %02X address %06X\n", c, number, attr, 0, MSF_TO_FRAMES(tmsf.min, tmsf.sec, tmsf.fr));
}
*/
return len; return len;
} }

View File

@@ -9,7 +9,7 @@
* Implementation of the CD-ROM host drive IOCTL interface for * Implementation of the CD-ROM host drive IOCTL interface for
* Windows using SCSI Passthrough Direct. * Windows using SCSI Passthrough Direct.
* *
* Version: @(#)cdrom_ioctl.c 1.0.0 2017/05/30 * Version: @(#)cdrom_ioctl.c 1.0.1 2017/05/31
* *
* Author: Sarah Walker, <http://pcem-emulator.co.uk/> * Author: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
@@ -35,6 +35,7 @@ typedef struct
{ {
HANDLE hIOCTL; HANDLE hIOCTL;
CDROM_TOC toc; CDROM_TOC toc;
int is_playing;
} cdrom_ioctl_windows_t; } cdrom_ioctl_windows_t;
cdrom_ioctl_windows_t cdrom_ioctl_windows[CDROM_NUM]; cdrom_ioctl_windows_t cdrom_ioctl_windows[CDROM_NUM];
@@ -62,6 +63,8 @@ void cdrom_ioctl_log(const char *format, ...)
#endif #endif
} }
static int ioctl_hopen(uint8_t id);
void ioctl_audio_callback(uint8_t id, int16_t *output, int len) void ioctl_audio_callback(uint8_t id, int16_t *output, int len)
{ {
RAW_READ_INFO in; RAW_READ_INFO in;
@@ -84,10 +87,11 @@ void ioctl_audio_callback(uint8_t id, int16_t *output, int len)
in.DiskOffset.HighPart = 0; in.DiskOffset.HighPart = 0;
in.SectorCount = 1; in.SectorCount = 1;
in.TrackMode = CDDA; in.TrackMode = CDDA;
ioctl_open(id, 0);
if (!DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_RAW_READ, &in, sizeof(in), &(cdrom_ioctl[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 2352, &count, NULL)) if (!DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_RAW_READ, &in, sizeof(in), &(cdrom_ioctl[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 2352, &count, NULL))
{ {
memset(&(cdrom_ioctl[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 0, (BUF_SIZE - cdrom_ioctl[id].cd_buflen) * 2); memset(&(cdrom_ioctl[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 0, (BUF_SIZE - cdrom_ioctl[id].cd_buflen) * 2);
cdrom_ioctl_windows[id].is_playing = 0;
ioctl_close(id);
cdrom_ioctl[id].cd_state = CD_STOPPED; cdrom_ioctl[id].cd_state = CD_STOPPED;
cdrom_ioctl[id].cd_buflen = len; cdrom_ioctl[id].cd_buflen = len;
} }
@@ -96,11 +100,12 @@ void ioctl_audio_callback(uint8_t id, int16_t *output, int len)
cdrom[id].seek_pos++; cdrom[id].seek_pos++;
cdrom_ioctl[id].cd_buflen += (2352 / 2); cdrom_ioctl[id].cd_buflen += (2352 / 2);
} }
ioctl_close(id);
} }
else else
{ {
memset(&(cdrom_ioctl[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 0, (BUF_SIZE - cdrom_ioctl[id].cd_buflen) * 2); memset(&(cdrom_ioctl[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 0, (BUF_SIZE - cdrom_ioctl[id].cd_buflen) * 2);
cdrom_ioctl_windows[id].is_playing = 0;
ioctl_close(id);
cdrom_ioctl[id].cd_state = CD_STOPPED; cdrom_ioctl[id].cd_state = CD_STOPPED;
cdrom_ioctl[id].cd_buflen = len; cdrom_ioctl[id].cd_buflen = len;
} }
@@ -112,6 +117,8 @@ void ioctl_audio_callback(uint8_t id, int16_t *output, int len)
void ioctl_audio_stop(uint8_t id) void ioctl_audio_stop(uint8_t id)
{ {
cdrom_ioctl_windows[id].is_playing = 0;
ioctl_close(id);
cdrom_ioctl[id].cd_state = CD_STOPPED; cdrom_ioctl[id].cd_state = CD_STOPPED;
} }
@@ -232,6 +239,11 @@ static void ioctl_playaudio(uint8_t id, uint32_t pos, uint32_t len, int ismsf)
/* Adjust because the host expects a minimum adjusted LBA of 0 which is equivalent to an absolute LBA of 150. */ /* Adjust because the host expects a minimum adjusted LBA of 0 which is equivalent to an absolute LBA of 150. */
cdrom[id].seek_pos = 150; cdrom[id].seek_pos = 150;
} }
if (!cdrom_ioctl_windows[id].is_playing)
{
ioctl_hopen(id);
cdrom_ioctl_windows[id].is_playing = 1;
}
cdrom_ioctl[id].cd_state = CD_PLAYING; cdrom_ioctl[id].cd_state = CD_PLAYING;
} }
@@ -265,6 +277,11 @@ static void ioctl_stop(uint8_t id)
{ {
return; return;
} }
if (cdrom_ioctl_windows[id].is_playing)
{
cdrom_ioctl_windows[id].is_playing = 0;
ioctl_close(id);
}
cdrom_ioctl[id].cd_state = CD_STOPPED; cdrom_ioctl[id].cd_state = CD_STOPPED;
} }
@@ -277,9 +294,16 @@ static int ioctl_ready(uint8_t id)
{ {
return 0; return 0;
} }
ioctl_open(id, 0); if (cdrom_ioctl_windows[id].hIOCTL == NULL)
temp = DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, &ltoc, sizeof(ltoc), &size, NULL); {
ioctl_close(id); ioctl_hopen(id);
temp = DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, &ltoc, sizeof(ltoc), &size, NULL);
ioctl_close(id);
}
else
{
temp = DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, &ltoc, sizeof(ltoc), &size, NULL);
}
if (!temp) if (!temp)
{ {
return 0; return 0;
@@ -310,7 +334,7 @@ static int ioctl_get_last_block(uint8_t id, unsigned char starttrack, int msf, i
return 0; return 0;
} }
cdrom_ioctl[id].cd_state = CD_STOPPED; cdrom_ioctl[id].cd_state = CD_STOPPED;
ioctl_open(id, 0); ioctl_hopen(id);
DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, &lbtoc, sizeof(lbtoc), &size, NULL); DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, &lbtoc, sizeof(lbtoc), &size, NULL);
ioctl_close(id); ioctl_close(id);
cdrom_ioctl[id].tocvalid=1; cdrom_ioctl[id].tocvalid=1;
@@ -326,6 +350,8 @@ static int ioctl_get_last_block(uint8_t id, unsigned char starttrack, int msf, i
return lb; return lb;
} }
static void ioctl_read_capacity(uint8_t id, uint8_t *b);
static int ioctl_medium_changed(uint8_t id) static int ioctl_medium_changed(uint8_t id)
{ {
unsigned long size; unsigned long size;
@@ -335,7 +361,7 @@ static int ioctl_medium_changed(uint8_t id)
{ {
return 0; /* This will be handled by the not ready handler instead. */ return 0; /* This will be handled by the not ready handler instead. */
} }
ioctl_open(id, 0); ioctl_hopen(id);
temp = DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, &ltoc,sizeof(ltoc), &size, NULL); temp = DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, &ltoc,sizeof(ltoc), &size, NULL);
ioctl_close(id); ioctl_close(id);
if (!temp) if (!temp)
@@ -351,6 +377,10 @@ static int ioctl_medium_changed(uint8_t id)
{ {
cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive;
} }
ioctl_hopen(id);
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);
ioctl_close(id);
cdrom_ioctl[id].cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); cdrom_ioctl[id].cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0);
return 1; return 1;
} }
@@ -363,6 +393,10 @@ static int ioctl_medium_changed(uint8_t id)
cdrom_ioctl[id].cd_state = CD_STOPPED; cdrom_ioctl[id].cd_state = CD_STOPPED;
cdrom_ioctl_log("Setting TOC...\n"); cdrom_ioctl_log("Setting TOC...\n");
cdrom_ioctl_windows[id].toc = ltoc; cdrom_ioctl_windows[id].toc = ltoc;
ioctl_hopen(id);
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);
ioctl_close(id);
cdrom_ioctl[id].cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); cdrom_ioctl[id].cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0);
return 1; /* TOC mismatches. */ return 1; /* TOC mismatches. */
} }
@@ -390,7 +424,7 @@ static uint8_t ioctl_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf)
else else
{ {
insub.Format = IOCTL_CDROM_CURRENT_POSITION; insub.Format = IOCTL_CDROM_CURRENT_POSITION;
ioctl_open(id, 0); ioctl_hopen(id);
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); memset(cdrom_ioctl[id].sub_q_data_format, 0, 16);
@@ -485,8 +519,13 @@ static void ioctl_eject(uint8_t id)
{ {
return; return;
} }
if (cdrom_ioctl_windows[id].is_playing)
{
cdrom_ioctl_windows[id].is_playing = 0;
ioctl_stop(id);
}
cdrom_ioctl[id].cd_state = CD_STOPPED; cdrom_ioctl[id].cd_state = CD_STOPPED;
ioctl_open(id, 0); ioctl_hopen(id);
DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_STORAGE_EJECT_MEDIA,NULL,0,NULL,0,&size,NULL); DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_STORAGE_EJECT_MEDIA,NULL,0,NULL,0,&size,NULL);
ioctl_close(id); ioctl_close(id);
} }
@@ -498,9 +537,16 @@ static void ioctl_load(uint8_t id)
{ {
return; return;
} }
if (cdrom_ioctl_windows[id].is_playing)
{
cdrom_ioctl_windows[id].is_playing = 0;
ioctl_stop(id);
}
cdrom_ioctl[id].cd_state = CD_STOPPED; cdrom_ioctl[id].cd_state = CD_STOPPED;
ioctl_open(id, 0); ioctl_hopen(id);
DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_STORAGE_LOAD_MEDIA,NULL,0,NULL,0,&size,NULL); DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_STORAGE_LOAD_MEDIA,NULL,0,NULL,0,&size,NULL);
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);
ioctl_close(id); ioctl_close(id);
cdrom_ioctl[id].cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); cdrom_ioctl[id].cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0);
} }
@@ -597,10 +643,10 @@ struct sptd_with_sense
static int ioctl_get_block_length(uint8_t id, const UCHAR *cdb, int number_of_blocks, int no_length_check) static int ioctl_get_block_length(uint8_t id, const UCHAR *cdb, int number_of_blocks, int no_length_check)
{ {
int sector_type = 0; int sector_type = 0;
int temp_len = 0; int temp_len = 0;
if (no_length_check) if (no_length_check)
{ {
switch (cdb[0]) switch (cdb[0])
{ {
@@ -753,8 +799,6 @@ static void ioctl_read_capacity(uint8_t id, uint8_t *b)
if (!cdrom_ioctl[id].capacity_read) if (!cdrom_ioctl[id].capacity_read)
{ {
ioctl_open(id, 0);
SCSICommand(id, cdb, buf, &len, 1); SCSICommand(id, cdb, buf, &len, 1);
memcpy(cdrom_ioctl[id].rcbuf, buf, len); memcpy(cdrom_ioctl[id].rcbuf, buf, len);
@@ -764,8 +808,6 @@ static void ioctl_read_capacity(uint8_t id, uint8_t *b)
{ {
memcpy(b, cdrom_ioctl[id].rcbuf, 16); memcpy(b, cdrom_ioctl[id].rcbuf, 16);
} }
ioctl_close(id);
} }
static int ioctl_media_type_id(uint8_t id) static int ioctl_media_type_id(uint8_t id)
@@ -782,7 +824,7 @@ static int ioctl_media_type_id(uint8_t id)
old_sense[1] = cdrom_asc; old_sense[1] = cdrom_asc;
old_sense[2] = cdrom_asc; old_sense[2] = cdrom_asc;
ioctl_open(id, 0); ioctl_hopen(id);
SCSICommand(id, cdb, msbuf, &len, 1); SCSICommand(id, cdb, msbuf, &len, 1);
@@ -846,7 +888,7 @@ static int ioctl_sector_data_type(uint8_t id, int sector, int ismsf)
cdb_msf[4] = cdb_msf[7] = ((sector >> 8) & 0xff); cdb_msf[4] = cdb_msf[7] = ((sector >> 8) & 0xff);
cdb_msf[5] = cdb_msf[8] = (sector & 0xff); cdb_msf[5] = cdb_msf[8] = (sector & 0xff);
ioctl_open(id, 0); ioctl_hopen(id);
if (ioctl_is_track_audio(id, sector, ismsf)) if (ioctl_is_track_audio(id, sector, ismsf))
{ {
@@ -901,7 +943,7 @@ static void ioctl_validate_toc(uint8_t id)
return; return;
} }
cdrom_ioctl[id].cd_state = CD_STOPPED; cdrom_ioctl[id].cd_state = CD_STOPPED;
ioctl_open(id, 0); ioctl_hopen(id);
cdrom_ioctl_log("Validating TOC...\n"); cdrom_ioctl_log("Validating TOC...\n");
DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_TOC, NULL,0,&cdrom_ioctl_windows[id].toc,sizeof(cdrom_ioctl_windows[id].toc),&size,NULL); DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_TOC, NULL,0,&cdrom_ioctl_windows[id].toc,sizeof(cdrom_ioctl_windows[id].toc),&size,NULL);
ioctl_close(id); ioctl_close(id);
@@ -935,7 +977,7 @@ static int ioctl_pass_through(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t
ioctl_validate_toc(id); ioctl_validate_toc(id);
} }
ioctl_open(id, 0); ioctl_hopen(id);
memcpy((void *) cdb, in_cdb, 12); memcpy((void *) cdb, in_cdb, 12);
@@ -1046,7 +1088,7 @@ void ioctl_reset(uint8_t id)
return; return;
} }
ioctl_open(id, 0); ioctl_hopen(id);
DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, &ltoc, sizeof(ltoc), &size, NULL); DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, &ltoc, sizeof(ltoc), &size, NULL);
ioctl_close(id); ioctl_close(id);
@@ -1054,28 +1096,30 @@ void ioctl_reset(uint8_t id)
cdrom_ioctl[id].tocvalid = 1; cdrom_ioctl[id].tocvalid = 1;
} }
int ioctl_hopen(uint8_t id)
{
if (cdrom_ioctl_windows[id].is_playing) return 0;
cdrom_ioctl_windows[id].hIOCTL = CreateFile(cdrom_ioctl[id].ioctl_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
return 0;
}
int ioctl_open(uint8_t id, char d) int ioctl_open(uint8_t id, char d)
{ {
if (!cdrom_ioctl[id].ioctl_inited) sprintf(cdrom_ioctl[id].ioctl_path,"\\\\.\\%c:",d);
{ cdrom_ioctl[id].tocvalid=0;
sprintf(cdrom_ioctl[id].ioctl_path,"\\\\.\\%c:",d);
cdrom_ioctl[id].tocvalid=0;
}
cdrom_ioctl_windows[id].hIOCTL = CreateFile(cdrom_ioctl[id].ioctl_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); cdrom_ioctl_windows[id].hIOCTL = CreateFile(cdrom_ioctl[id].ioctl_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
cdrom_drives[id].handler = &ioctl_cdrom; cdrom_drives[id].handler = &ioctl_cdrom;
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. */
cdrom_ioctl[id].ioctl_inited=1; ioctl_read_capacity(id, NULL);
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. */ CloseHandle(cdrom_ioctl_windows[id].hIOCTL);
ioctl_read_capacity(id, NULL); cdrom_ioctl_windows[id].hIOCTL = NULL;
CloseHandle(cdrom_ioctl_windows[id].hIOCTL);
cdrom_ioctl_windows[id].hIOCTL = NULL;
}
return 0; return 0;
} }
void ioctl_close(uint8_t id) void ioctl_close(uint8_t id)
{ {
if (cdrom_ioctl_windows[id].is_playing) return;
if (cdrom_ioctl_windows[id].hIOCTL) if (cdrom_ioctl_windows[id].hIOCTL)
{ {
CloseHandle(cdrom_ioctl_windows[id].hIOCTL); CloseHandle(cdrom_ioctl_windows[id].hIOCTL);
@@ -1085,6 +1129,7 @@ void ioctl_close(uint8_t id)
static void ioctl_exit(uint8_t id) static void ioctl_exit(uint8_t id)
{ {
cdrom_ioctl_windows[id].is_playing = 0;
ioctl_stop(id); ioctl_stop(id);
cdrom_ioctl[id].ioctl_inited=0; cdrom_ioctl[id].ioctl_inited=0;
cdrom_ioctl[id].tocvalid=0; cdrom_ioctl[id].tocvalid=0;

View File

@@ -138,7 +138,7 @@ static wchar_t cfgbuffer[1024];
static char sname[256]; static char sname[256];
static char ename[256]; static char ename[256];
void config_load(wchar_t *fn) int config_load(wchar_t *fn)
{ {
section_t *current_section; section_t *current_section;
section_t *new_section; section_t *new_section;
@@ -153,7 +153,7 @@ void config_load(wchar_t *fn)
f = _wfopen(fn, L"rt, ccs=UNICODE"); f = _wfopen(fn, L"rt, ccs=UNICODE");
#endif #endif
if (!f) if (!f)
return; return 0;
current_section = malloc(sizeof(section_t)); current_section = malloc(sizeof(section_t));
memset(current_section, 0x00, sizeof(section_t)); memset(current_section, 0x00, sizeof(section_t));
@@ -230,6 +230,8 @@ void config_load(wchar_t *fn)
fclose(f); fclose(f);
config_dump(); config_dump();
return 1;
} }
@@ -793,7 +795,7 @@ static void loadconfig_general(void)
config_delete_var(cat, "vid_api"); config_delete_var(cat, "vid_api");
video_fullscreen_scale = config_get_int(cat, "video_fullscreen_scale", 0); video_fullscreen_scale = config_get_int(cat, "video_fullscreen_scale", 0);
video_fullscreen_first = config_get_int(cat, "video_fullscreen_first", 1); video_fullscreen_first = config_get_int(cat, "video_fullscreen_first", 0);
force_43 = !!config_get_int(cat, "force_43", 0); force_43 = !!config_get_int(cat, "force_43", 0);
scale = config_get_int(cat, "scale", 1); scale = config_get_int(cat, "scale", 1);
@@ -1570,7 +1572,12 @@ static void loadconfig_removable_devices(void)
wp = config_get_wstring(cat, temps, L""); wp = config_get_wstring(cat, temps, L"");
memcpy(cdrom_image[c].image_path, wp, (wcslen(wp) << 1) + 2); memcpy(cdrom_image[c].image_path, wp, (wcslen(wp) << 1) + 2);
if ((cdrom_drives[c].host_drive < 0x41) || ((cdrom_drives[c].host_drive == 0x200) && (wcslen(cdrom_image[c].image_path) == 0))) if (cdrom_drives[c].host_drive < 'A')
{
cdrom_drives[c].host_drive = 0;
}
if ((cdrom_drives[c].host_drive == 0x200) && (wcslen(cdrom_image[c].image_path) == 0))
{ {
cdrom_drives[c].host_drive = 0; cdrom_drives[c].host_drive = 0;
} }
@@ -1602,9 +1609,32 @@ static void loadconfig_removable_devices(void)
void loadconfig(wchar_t *fn) void loadconfig(wchar_t *fn)
{ {
int i = 0;
if (fn == NULL) if (fn == NULL)
fn = config_file_default; fn = config_file_default;
config_load(fn); i = config_load(fn);
if (i == 0)
{
cpu = 0;
#ifndef __unix
dwLanguage = 0x0409;
#endif
scale = 1;
vid_api = 1;
enable_sync = 1;
joystick_type = 7;
strcpy(hdd_controller_name, "none");
serial_enabled[0] = 1;
serial_enabled[1] = 1;
lpt_enabled = 1;
fdd_set_type(0, 2);
fdd_set_type(1, 2);
mem_size = 640;
return;
}
/* General */ /* General */
loadconfig_general(); loadconfig_general();
@@ -1692,7 +1722,7 @@ static void saveconfig_general(void)
config_set_int(cat, "video_fullscreen_scale", video_fullscreen_scale); config_set_int(cat, "video_fullscreen_scale", video_fullscreen_scale);
} }
if (video_fullscreen_first == 1) if (video_fullscreen_first == 0)
{ {
config_delete_var(cat, "video_fullscreen_first"); config_delete_var(cat, "video_fullscreen_first");
} }

View File

@@ -33,7 +33,7 @@ extern char *get_extension(char *s);
extern wchar_t *get_extension_w(wchar_t *s); extern wchar_t *get_extension_w(wchar_t *s);
extern void config_load(wchar_t *fn); extern int config_load(wchar_t *fn);
extern void config_save(wchar_t *fn); extern void config_save(wchar_t *fn);
extern void config_dump(void); extern void config_dump(void);

View File

@@ -435,16 +435,13 @@ void initmodules(void)
for (i = 0; i < CDROM_NUM; i++) for (i = 0; i < CDROM_NUM; i++)
{ {
if (cdrom_drives[i].host_drive != 0) if (cdrom_drives[i].host_drive == 200)
{ {
if (cdrom_drives[i].host_drive == 200) image_reset(i);
{ }
image_reset(i); else if ((cdrom_drives[i].host_drive >= 'A') && (cdrom_drives[i].host_drive <= 'Z'))
} {
else if ((cdrom_drives[i].host_drive >= 'A') && (cdrom_drives[i].host_drive <= 'Z')) ioctl_reset(i);
{
ioctl_reset(i);
}
} }
} }
} }
@@ -547,16 +544,13 @@ void resetpchard(void)
for (i = 0; i < CDROM_NUM; i++) for (i = 0; i < CDROM_NUM; i++)
{ {
if (cdrom_drives[i].host_drive != 0) if (cdrom_drives[i].host_drive == 200)
{ {
if (cdrom_drives[i].host_drive == 200) image_reset(i);
{ }
image_reset(i); else if ((cdrom_drives[i].host_drive >= 'A') && (cdrom_drives[i].host_drive <= 'Z'))
} {
else if ((cdrom_drives[i].host_drive >= 'A') && (cdrom_drives[i].host_drive <= 'Z')) ioctl_reset(i);
{
ioctl_reset(i);
}
} }
} }