From e6adf90e297e3d055bb78d25ccde9334d432a1de Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 1 Jun 2017 01:47:54 +0200 Subject: [PATCH] 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. --- src/CPU/808x.c | 6 +++ src/Makefile.mingw | 2 +- src/SOUND/sound.c | 4 +- src/WIN/win.c | 19 +++---- src/cdrom.c | 7 +++ src/cdrom_dosbox.cpp | 51 +++++++++++-------- src/cdrom_dosbox.h | 15 +++--- src/cdrom_image.cc | 15 ------ src/cdrom_ioctl.c | 117 ++++++++++++++++++++++++++++++------------- src/config.c | 42 +++++++++++++--- src/config.h | 2 +- src/pc.c | 30 +++++------ 12 files changed, 193 insertions(+), 117 deletions(-) diff --git a/src/CPU/808x.c b/src/CPU/808x.c index c0e6dfa15..32a52e955 100644 --- a/src/CPU/808x.c +++ b/src/CPU/808x.c @@ -61,12 +61,14 @@ void writememll(uint32_t seg, uint32_t addr, uint32_t val); uint8_t readmemb(uint32_t a) { if (a!=(cs+cpu_state.pc)) memcycs+=4; + if (readlookup2 == NULL) return readmembl(a); if (readlookup2[(a)>>12]==-1) return readmembl(a); else return *(uint8_t *)(readlookup2[(a) >> 12] + (a)); } uint8_t readmembf(uint32_t a) { + if (readlookup2 == NULL) return readmembl(a); if (readlookup2[(a)>>12]==-1) return readmembl(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) { 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); 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) { memcycs+=4; + if (writelookup2 == NULL) writemembl(a,v); if (writelookup2[(a)>>12]==-1) writemembl(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) { memcycs+=(8>>is8086); + if (writelookup2 == NULL) 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; } void writememll(uint32_t seg, uint32_t addr, uint32_t val); 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); else *(uint32_t *)(writelookup2[(s + a) >> 12] + s + a) = v; } diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 21b5bc92c..d443739c1 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -40,7 +40,7 @@ ifndef DEBUG DEBUG = n endif ifndef OPTIM -OPTIM = y +OPTIM = n endif ifndef X64 X64 = n diff --git a/src/SOUND/sound.c b/src/SOUND/sound.c index 6a6deafc7..fb0237ac9 100644 --- a/src/SOUND/sound.c +++ b/src/SOUND/sound.c @@ -246,7 +246,7 @@ void sound_init() 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++; } @@ -335,7 +335,7 @@ void sound_cd_thread_reset() 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++; } diff --git a/src/WIN/win.c b/src/WIN/win.c index 0be43d165..7d742beb3 100644 --- a/src/WIN/win.c +++ b/src/WIN/win.c @@ -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 (!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; } @@ -1189,20 +1189,17 @@ void update_status_bar_panes(HWND hwnds) case SB_CDROM: /* CD-ROM */ 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 { - if (cdrom_drives[id].host_drive == 0x200) - { - sb_icon_flags[i] = (wcslen(cdrom_image[id].image_path) == 0) ? 256 : 0; - } - else - { - sb_icon_flags[i] = 0; - } + sb_icon_flags[i] = 256; } if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) { diff --git a/src/cdrom.c b/src/cdrom.c index 2bac1e2e3..21eba3ae0 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -2111,6 +2111,12 @@ int cdrom_pre_execution_check(uint8_t id, uint8_t *cdb) 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)) { /* 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); +skip_ready_check: if (!ready && cdrom[id].unit_attention) { /* If the drive is not ready, there is no reason to keep the diff --git a/src/cdrom_dosbox.cpp b/src/cdrom_dosbox.cpp index 906f7b0c8..be632fd38 100644 --- a/src/cdrom_dosbox.cpp +++ b/src/cdrom_dosbox.cpp @@ -51,27 +51,38 @@ using namespace std; CDROM_Interface_Image::BinaryFile::BinaryFile(const char *filename, bool &error) { - file = fopen64(filename, "rb"); - error = (file == NULL); + // file = fopen64(filename, "rb"); + // error = (file == NULL); + memset(fn, 0, sizeof(fn)); + strcpy(fn, filename); + error = false; } 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) { uint64_t offs = 0; + file = fopen64(fn, "rb"); fseeko64(file, seek, SEEK_SET); 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 ret = 0; + file = fopen64(fn, "rb"); fseeko64(file, 0, SEEK_END); - return ftello64(file); + ret = ftello64(file); + fclose(file); + return ret; } CDROM_Interface_Image::CDROM_Interface_Image() @@ -184,9 +195,9 @@ bool CDROM_Interface_Image::ReadSector(Bit8u *buffer, bool raw, unsigned long se { int track = GetTrack(sector) - 1; if (track < 0) return false; - - uint64_t seek = tracks[track].skip + (sector - tracks[track].start); - seek *= (uint64_t) tracks[track].sectorSize; + + uint64_t s = (uint64_t) sector; + uint64_t seek = tracks[track].skip + ((s - tracks[track].start) * tracks[track].sectorSize); 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 && !tracks[track].mode2 && !raw) seek += 16; @@ -259,10 +270,10 @@ bool CDROM_Interface_Image::LoadIsoFile(char* filename) 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]; - 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 (mode2) seek += 24; 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}; tracks.clear(); uint64_t shift = 0; - int currPregap = 0; - int totalPregap = 0; - int prestart = 0; + uint64_t currPregap = 0; + uint64_t totalPregap = 0; + uint64_t prestart = 0; bool success; bool canAddTrack = false; char tmp[MAX_FILENAME_LENGTH]; // dirname can change its argument @@ -353,9 +364,9 @@ bool CDROM_Interface_Image::LoadCueSheet(char *cuefile) canAddTrack = true; } else if (command == "INDEX") { - int index; + uint64_t index; line >> index; - int frame; + uint64_t frame; success = GetCueFrame(frame, line); if (index == 1) track.start = frame; @@ -410,10 +421,10 @@ bool CDROM_Interface_Image::LoadCueSheet(char *cuefile) 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 - int skip; + uint64_t skip; if (prestart > 0) { if (prestart > curr.start) return false; 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 if (prev.file == curr.file) { curr.start += shift; - prev.length = curr.start + ((uint64_t) totalPregap) - prev.start - ((uint64_t) skip); - curr.skip += prev.skip + prev.length * prev.sectorSize + skip * curr.sectorSize; + prev.length = curr.start + totalPregap - prev.start - skip; + curr.skip += prev.skip + (prev.length * prev.sectorSize) + (skip * curr.sectorSize); totalPregap += currPregap; curr.start += totalPregap; // 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; } -bool CDROM_Interface_Image::GetCueFrame(int &frames, istream &in) +bool CDROM_Interface_Image::GetCueFrame(uint64_t &frames, istream &in) { string msf; in >> msf; diff --git a/src/cdrom_dosbox.h b/src/cdrom_dosbox.h index f8fd704a7..243723fe4 100644 --- a/src/cdrom_dosbox.h +++ b/src/cdrom_dosbox.h @@ -116,6 +116,7 @@ private: uint64_t getLength(); private: BinaryFile(); + char fn[260]; FILE *file; }; @@ -123,10 +124,10 @@ private: int number; int track_number; int attr; - int start; - int length; - int skip; - int sectorSize; + uint64_t start; + uint64_t length; + uint64_t skip; + uint64_t sectorSize; bool mode2; TrackFile *file; }; @@ -156,14 +157,14 @@ static void CDAudioCallBack(Bitu len); void ClearTracks(); bool LoadIsoFile(char *filename); - bool CanReadPVD(TrackFile *file, int sectorSize, bool mode2); + bool CanReadPVD(TrackFile *file, uint64_t sectorSize, bool mode2); // cue sheet processing bool LoadCueSheet(char *cuefile); bool GetRealFileName(std::string& filename, std::string& pathname); 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 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 tracks; typedef std::vector::iterator track_it; diff --git a/src/cdrom_image.cc b/src/cdrom_image.cc index 07566b7ef..ae4ef727c 100644 --- a/src/cdrom_image.cc +++ b/src/cdrom_image.cc @@ -779,7 +779,6 @@ static int image_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, break; 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++] = attr; 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[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; } diff --git a/src/cdrom_ioctl.c b/src/cdrom_ioctl.c index b5f827fa7..5422c25b5 100644 --- a/src/cdrom_ioctl.c +++ b/src/cdrom_ioctl.c @@ -9,7 +9,7 @@ * Implementation of the CD-ROM host drive IOCTL interface for * 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, * Miran Grca, @@ -35,6 +35,7 @@ typedef struct { HANDLE hIOCTL; CDROM_TOC toc; + int is_playing; } cdrom_ioctl_windows_t; cdrom_ioctl_windows_t cdrom_ioctl_windows[CDROM_NUM]; @@ -62,6 +63,8 @@ void cdrom_ioctl_log(const char *format, ...) #endif } +static int ioctl_hopen(uint8_t id); + void ioctl_audio_callback(uint8_t id, int16_t *output, int len) { 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.SectorCount = 1; 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)) { 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_buflen = len; } @@ -96,11 +100,12 @@ void ioctl_audio_callback(uint8_t id, int16_t *output, int len) cdrom[id].seek_pos++; cdrom_ioctl[id].cd_buflen += (2352 / 2); } - ioctl_close(id); } else { 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_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) { + cdrom_ioctl_windows[id].is_playing = 0; + ioctl_close(id); 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. */ 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; } @@ -265,6 +277,11 @@ static void ioctl_stop(uint8_t id) { 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; } @@ -277,9 +294,16 @@ static int ioctl_ready(uint8_t id) { return 0; } - ioctl_open(id, 0); - temp = DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc, sizeof(ltoc), &size, NULL); - ioctl_close(id); + if (cdrom_ioctl_windows[id].hIOCTL == NULL) + { + ioctl_hopen(id); + temp = DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc, sizeof(ltoc), &size, NULL); + ioctl_close(id); + } + else + { + temp = DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc, sizeof(ltoc), &size, NULL); + } if (!temp) { return 0; @@ -310,7 +334,7 @@ static int ioctl_get_last_block(uint8_t id, unsigned char starttrack, int msf, i return 0; } 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); ioctl_close(id); 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; } +static void ioctl_read_capacity(uint8_t id, uint8_t *b); + static int ioctl_medium_changed(uint8_t id) { 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. */ } - ioctl_open(id, 0); + ioctl_hopen(id); temp = DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc,sizeof(ltoc), &size, NULL); ioctl_close(id); 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; } + 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); return 1; } @@ -363,6 +393,10 @@ static int ioctl_medium_changed(uint8_t id) cdrom_ioctl[id].cd_state = CD_STOPPED; cdrom_ioctl_log("Setting TOC...\n"); 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); return 1; /* TOC mismatches. */ } @@ -390,7 +424,7 @@ static uint8_t ioctl_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) else { 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); ioctl_close(id); memset(cdrom_ioctl[id].sub_q_data_format, 0, 16); @@ -485,8 +519,13 @@ static void ioctl_eject(uint8_t id) { 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; - ioctl_open(id, 0); + ioctl_hopen(id); DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_STORAGE_EJECT_MEDIA,NULL,0,NULL,0,&size,NULL); ioctl_close(id); } @@ -498,9 +537,16 @@ static void ioctl_load(uint8_t id) { 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; - ioctl_open(id, 0); + ioctl_hopen(id); 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); 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) { - int sector_type = 0; - int temp_len = 0; + int sector_type = 0; + int temp_len = 0; - if (no_length_check) + if (no_length_check) { switch (cdb[0]) { @@ -753,8 +799,6 @@ static void ioctl_read_capacity(uint8_t id, uint8_t *b) if (!cdrom_ioctl[id].capacity_read) { - ioctl_open(id, 0); - SCSICommand(id, cdb, buf, &len, 1); 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); } - - ioctl_close(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[2] = cdrom_asc; - ioctl_open(id, 0); + ioctl_hopen(id); 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[5] = cdb_msf[8] = (sector & 0xff); - ioctl_open(id, 0); + ioctl_hopen(id); if (ioctl_is_track_audio(id, sector, ismsf)) { @@ -901,7 +943,7 @@ static void ioctl_validate_toc(uint8_t id) return; } cdrom_ioctl[id].cd_state = CD_STOPPED; - ioctl_open(id, 0); + ioctl_hopen(id); 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); 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_open(id, 0); + ioctl_hopen(id); memcpy((void *) cdb, in_cdb, 12); @@ -1046,7 +1088,7 @@ void ioctl_reset(uint8_t id) return; } - ioctl_open(id, 0); + ioctl_hopen(id); DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc, sizeof(ltoc), &size, NULL); ioctl_close(id); @@ -1054,28 +1096,30 @@ void ioctl_reset(uint8_t id) 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) { - 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_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. */ - ioctl_read_capacity(id, NULL); - CloseHandle(cdrom_ioctl_windows[id].hIOCTL); - cdrom_ioctl_windows[id].hIOCTL = NULL; - } + 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; return 0; } void ioctl_close(uint8_t id) { + if (cdrom_ioctl_windows[id].is_playing) return; if (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) { + cdrom_ioctl_windows[id].is_playing = 0; ioctl_stop(id); cdrom_ioctl[id].ioctl_inited=0; cdrom_ioctl[id].tocvalid=0; diff --git a/src/config.c b/src/config.c index a524e27be..4ba9517d8 100644 --- a/src/config.c +++ b/src/config.c @@ -138,7 +138,7 @@ static wchar_t cfgbuffer[1024]; static char sname[256]; static char ename[256]; -void config_load(wchar_t *fn) +int config_load(wchar_t *fn) { section_t *current_section; section_t *new_section; @@ -153,7 +153,7 @@ void config_load(wchar_t *fn) f = _wfopen(fn, L"rt, ccs=UNICODE"); #endif if (!f) - return; + return 0; current_section = malloc(sizeof(section_t)); memset(current_section, 0x00, sizeof(section_t)); @@ -230,6 +230,8 @@ void config_load(wchar_t *fn) fclose(f); config_dump(); + + return 1; } @@ -793,7 +795,7 @@ static void loadconfig_general(void) config_delete_var(cat, "vid_api"); 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); scale = config_get_int(cat, "scale", 1); @@ -1570,7 +1572,12 @@ static void loadconfig_removable_devices(void) wp = config_get_wstring(cat, temps, L""); 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; } @@ -1602,9 +1609,32 @@ static void loadconfig_removable_devices(void) void loadconfig(wchar_t *fn) { + int i = 0; + if (fn == NULL) 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 */ loadconfig_general(); @@ -1692,7 +1722,7 @@ static void saveconfig_general(void) 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"); } diff --git a/src/config.h b/src/config.h index c2b08da0b..9efe0edd4 100644 --- a/src/config.h +++ b/src/config.h @@ -33,7 +33,7 @@ extern char *get_extension(char *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_dump(void); diff --git a/src/pc.c b/src/pc.c index dc7b3a5de..b85f401a1 100644 --- a/src/pc.c +++ b/src/pc.c @@ -435,16 +435,13 @@ void initmodules(void) 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); - } - else if ((cdrom_drives[i].host_drive >= 'A') && (cdrom_drives[i].host_drive <= 'Z')) - { - ioctl_reset(i); - } + image_reset(i); + } + else if ((cdrom_drives[i].host_drive >= 'A') && (cdrom_drives[i].host_drive <= 'Z')) + { + ioctl_reset(i); } } } @@ -547,16 +544,13 @@ void resetpchard(void) 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); - } - else if ((cdrom_drives[i].host_drive >= 'A') && (cdrom_drives[i].host_drive <= 'Z')) - { - ioctl_reset(i); - } + image_reset(i); + } + else if ((cdrom_drives[i].host_drive >= 'A') && (cdrom_drives[i].host_drive <= 'Z')) + { + ioctl_reset(i); } }