diff --git a/README b/README index 4f43a978..8e0e5fd6 100644 --- a/README +++ b/README @@ -72,6 +72,7 @@ A: You have to make your directories available as drives in DOSBox by using To change to the drive mounted like above, type "C:". If everything went fine, DOSBox will display the prompt "C:\>". + Q: How do I change to fullscreen ? A: Press alt-enter. Alternatively: Edit the configuration file of DOSBox and change the option fullscreen=false to fullscreen=true. If fullscreen looks @@ -486,9 +487,11 @@ IMGMOUNT -size [sectorsbytesize, sectorsperhead, heads, cylinders] imagefile - Location of the image files to mount in DOSBox. The location is on a - mounted drive inside DOSBox. CD-ROM images can be mounted - directly as well. They don't have to be on a mounted drive. + Location of the image files to mount in DOSBox. The location can + be on a mounted drive inside DOSBox, or on your real disk. It is + possible to mount CD-ROM images (ISOs or CUE/BIN) as well, if you + need CD swapping capabilities specify all images in succession. + The CDs can be swapped with CTRL-F4 at any time. -t The following are valid image types: @@ -532,11 +535,11 @@ BOOT Boot will start floppy images or hard disk images independent of the operating system emulation offered by DOSBox. This will allow you to play booter floppies or boot other operating systems inside DOSBox. - If the target emulated system is PCJr (machine=pcjr) the boot command - can be used to load PCJr cartridges (.jrc). + If the target emulated system is PCjr (machine=pcjr) the boot command + can be used to load PCjr cartridges (.jrc). BOOT [diskimg1.img diskimg2.img .. diskimgN.img] [-l driveletter] - BOOT [cart.jrc] (PCJr only) + BOOT [cart.jrc] (PCjr only) diskimgN.img This can be any number of floppy disk images one wants mounted after @@ -551,8 +554,8 @@ BOOT a hard drive image mounted as master by specifying "-l C" without the quotes, or the drive as slave by specifying "-l D" - cart.jrc (PCJr only) - When emulation of a PCJr is enabled, cartridges can be loaded with + cart.jrc (PCjr only) + When emulation of a PCjr is enabled, cartridges can be loaded with the BOOT command. Support is still limited. diff --git a/include/dos_system.h b/include/dos_system.h index 47c9a43e..8b30d5e3 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_system.h,v 1.38 2007-01-08 19:45:37 qbix79 Exp $ */ +/* $Id: dos_system.h,v 1.39 2007-01-21 16:21:22 c2woody Exp $ */ #ifndef DOSBOX_DOS_SYSTEM_H #define DOSBOX_DOS_SYSTEM_H @@ -242,6 +242,9 @@ public: virtual char const * GetLabel(){return dirCache.GetLabel();}; DOS_Drive_Cache dirCache; + + // disk cycling functionality (request resources) + virtual void Activate(void) {}; }; enum { OPEN_READ=0,OPEN_WRITE=1,OPEN_READWRITE=2, DOS_NOT_INHERIT=128}; diff --git a/src/dos/cdrom_image.cpp b/src/dos/cdrom_image.cpp index 6b1e5652..1cae4927 100644 --- a/src/dos/cdrom_image.cpp +++ b/src/dos/cdrom_image.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_image.cpp,v 1.13 2007-01-08 19:45:39 qbix79 Exp $ */ +/* $Id: cdrom_image.cpp,v 1.14 2007-01-21 16:21:22 c2woody Exp $ */ #include #include @@ -136,9 +136,6 @@ CDROM_Interface_Image::CDROM_Interface_Image(Bit8u subUnit) { images[subUnit] = this; if (refCount == 0) { -#if defined(C_SDL_SOUND) - Sound_Init(); -#endif player.mutex = SDL_CreateMutex(); if (!player.channel) { player.channel = MIXER_AddChannel(&CDAudioCallBack, 44100, "CDAUDIO"); @@ -154,9 +151,6 @@ CDROM_Interface_Image::~CDROM_Interface_Image() if (player.cd == this) player.cd = NULL; ClearTracks(); if (refCount == 0) { -#if defined(C_SDL_SOUND) - Sound_Quit(); -#endif SDL_DestroyMutex(player.mutex); player.channel->Enable(false); } @@ -663,3 +657,16 @@ void CDROM_Interface_Image::ClearTracks() } tracks.clear(); } + +void CDROM_Image_Destroy(Section*) { +#if defined(C_SDL_SOUND) + Sound_Quit(); +#endif +} + +void CDROM_Image_Init(Section* section) { +#if defined(C_SDL_SOUND) + Sound_Init(); + section->AddDestroyFunction(CDROM_Image_Destroy, false); +#endif +} diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index ca749200..3753337a 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_mscdex.cpp,v 1.44 2007-01-08 19:45:39 qbix79 Exp $ */ +/* $Id: dos_mscdex.cpp,v 1.45 2007-01-21 16:21:22 c2woody Exp $ */ #include #include @@ -109,6 +109,8 @@ public: int RemoveDrive (Bit16u _drive); int AddDrive (Bit16u _drive, char* physicalPath, Bit8u& subUnit); + bool HasDrive (Bit16u drive); + void ReplaceDrive (CDROM_Interface* newCdrom, Bit8u subUnit); void GetDrives (PhysPt data); void GetDriverInfo (PhysPt data); bool GetVolumeName (Bit8u subUnit, char* name); @@ -382,6 +384,16 @@ int CMscdex::AddDrive(Bit16u _drive, char* physicalPath, Bit8u& subUnit) return result; }; +bool CMscdex::HasDrive(Bit16u drive) { + return (GetSubUnit(drive) != 0xff); +} + +void CMscdex::ReplaceDrive(CDROM_Interface* newCdrom, Bit8u subUnit) { + delete cdrom[subUnit]; + cdrom[subUnit] = newCdrom; + StopAudio(subUnit); +} + PhysPt CMscdex::GetDefaultBuffer(void) { if (defaultBufSeg==0) { @@ -1205,6 +1217,16 @@ int MSCDEX_RemoveDrive(char driveLetter) return mscdex->RemoveDrive(driveLetter-'A'); }; +bool MSCDEX_HasDrive(char driveLetter) +{ + return mscdex->HasDrive(driveLetter-'A'); +}; + +void MSCDEX_ReplaceDrive(CDROM_Interface* cdrom, Bit8u subUnit) +{ + mscdex->ReplaceDrive(cdrom, subUnit); +}; + bool MSCDEX_GetVolumeName(Bit8u subUnit, char* name) { return mscdex->GetVolumeName(subUnit,name); diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 285c5baf..41cce0fb 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,11 +16,13 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.65 2007-01-14 18:44:01 c2woody Exp $ */ +/* $Id: dos_programs.cpp,v 1.66 2007-01-21 16:21:22 c2woody Exp $ */ #include #include #include +#include +#include #include "programs.h" #include "support.h" #include "drives.h" @@ -57,7 +59,7 @@ public: umount[0] = toupper(umount[0]); int i_drive = umount[0]-'A'; if(i_drive < DOS_DRIVES && Drives[i_drive]) { - switch (Drives[i_drive]->UnMount()) { + switch (DriveManager::UnmountDrive(i_drive)) { case 0: Drives[i_drive] = 0; if(i_drive == DOS_GetDefaultDrive()) @@ -822,13 +824,14 @@ public: Bit32u imagesize; char drive; std::string label; + std::vector paths; std::string umount; /* Check for unmounting */ if (cmd->FindString("-u",umount,false)) { umount[0] = toupper(umount[0]); int i_drive = umount[0]-'A'; if (i_drive < DOS_DRIVES && Drives[i_drive]) { - switch (Drives[i_drive]->UnMount()) { + switch (DriveManager::UnmountDrive(i_drive)) { case 0: Drives[i_drive] = 0; if (i_drive == DOS_GetDefaultDrive()) @@ -912,40 +915,47 @@ public: WriteOut(MSG_Get("PROGRAM_IMGMOUNT_FORMAT_UNSUPPORTED")); return; } - - if (!cmd->FindCommand(2,temp_line)) { - WriteOut(MSG_Get("PROGRAM_IMGMOUNT_SPECIFY_FILE")); - return; - } - if (!temp_line.size()) { - WriteOut(MSG_Get("PROGRAM_IMGMOUNT_SPECIFY_FILE")); - return; - } - struct stat test; - if (stat(temp_line.c_str(),&test)) { - // convert dosbox filename to system filename - char fullname[CROSS_LEN]; - char tmp[CROSS_LEN]; - safe_strncpy(tmp, temp_line.c_str(), CROSS_LEN); - - Bit8u dummy; - if (!DOS_MakeName(tmp, fullname, &dummy) || strncmp(Drives[dummy]->GetInfo(),"local directory",15)) { - WriteOut(MSG_Get("PROGRAM_IMGMOUNT_FILE_NOT_FOUND")); - return; - } - - localDrive *ldp = (localDrive*)Drives[dummy]; - ldp->GetSystemFilename(tmp, fullname); - temp_line = tmp; - - if (stat(temp_line.c_str(),&test)) { - WriteOut(MSG_Get("PROGRAM_IMGMOUNT_FILE_NOT_FOUND")); - return; - } - } - if ((test.st_mode & S_IFDIR)) { - WriteOut(MSG_Get("PROGRAM_IMGMOUNT_MOUNT")); + // find all file parameters, assuming that all option parameters have been removed + while(cmd->FindCommand(paths.size() + 2, temp_line) && temp_line.size()) { + + struct stat test; + if (stat(temp_line.c_str(),&test)) { + // convert dosbox filename to system filename + char fullname[CROSS_LEN]; + char tmp[CROSS_LEN]; + safe_strncpy(tmp, temp_line.c_str(), CROSS_LEN); + + Bit8u dummy; + if (!DOS_MakeName(tmp, fullname, &dummy) || strncmp(Drives[dummy]->GetInfo(),"local directory",15)) { + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_NON_LOCAL_DRIVE")); + return; + } + + localDrive *ldp = (localDrive*)Drives[dummy]; + ldp->GetSystemFilename(tmp, fullname); + temp_line = tmp; + + if (stat(temp_line.c_str(),&test)) { + WriteOut(MSG_Get("PROGRAM_IMGMOUNG_FILE_NOT_FOUND")); + return; + } + + if ((test.st_mode & S_IFDIR)) { + WriteOut(MSG_Get("PROGRAM_IMGMOUNG_MOUNT")); + return; + } + } + paths.push_back(temp_line); + } + if (paths.size() == 0) { + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_SPECIFY_FILE")); + return; + } + if (paths.size() == 1) + temp_line = paths[0]; + if (paths.size() > 1 && fstype != "iso") { + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_MULTIPLE_NON_CUEISO_FILES")); return; } @@ -956,22 +966,6 @@ public: newdrive = 0; } } else if (fstype=="iso") { - int error; - MSCDEX_SetCDInterface(CDROM_USE_SDL, -1); - newdrive = new isoDrive(drive, temp_line.c_str(), mediaid, error); - switch (error) { - case 0 : WriteOut(MSG_Get("MSCDEX_SUCCESS")); break; - case 1 : WriteOut(MSG_Get("MSCDEX_ERROR_MULTIPLE_CDROMS")); break; - case 2 : WriteOut(MSG_Get("MSCDEX_ERROR_NOT_SUPPORTED")); break; - case 3 : WriteOut(MSG_Get("MSCDEX_ERROR_PATH")); break; - case 4 : WriteOut(MSG_Get("MSCDEX_TOO_MANY_DRIVES")); break; - case 5 : WriteOut(MSG_Get("MSCDEX_LIMITED_SUPPORT")); break; - default : WriteOut(MSG_Get("MSCDEX_UNKNOWN_ERROR")); break; - }; - if (error && error!=5) { - delete newdrive; - return; - } } else { FILE *newDisk = fopen(temp_line.c_str(), "rb+"); fseek(newDisk,0L, SEEK_END); @@ -1014,14 +1008,50 @@ public: } else if (fstype=="iso") { if (Drives[drive-'A']) { WriteOut(MSG_Get("PROGRAM_IMGMOUNT_ALREADY_MOUNTED")); - if (newdrive) delete newdrive; return; } - if (!newdrive) WriteOut(MSG_Get("PROGRAM_IMGMOUNT_CANT_CREATE")); - Drives[drive-'A']=newdrive; + MSCDEX_SetCDInterface(CDROM_USE_SDL, -1); + // create new drives for all images + std::vector isoDisks; + for (int i = 0; i < paths.size(); i++) { + int error = -1; + DOS_Drive* newDrive = new isoDrive(drive, paths[i].c_str(), mediaid, error); + isoDisks.push_back(newDrive); + switch (error) { + case 0 : break; + case 1 : WriteOut(MSG_Get("MSCDEX_ERROR_MULTIPLE_CDROMS")); break; + case 2 : WriteOut(MSG_Get("MSCDEX_ERROR_NOT_SUPPORTED")); break; + case 3 : WriteOut(MSG_Get("MSCDEX_ERROR_PATH")); break; + case 4 : WriteOut(MSG_Get("MSCDEX_TOO_MANY_DRIVES")); break; + case 5 : WriteOut(MSG_Get("MSCDEX_LIMITED_SUPPORT")); break; + case 6 : WriteOut(MSG_Get("MSCDEX_INVALID_FILEFORMAT")); break; + default : WriteOut(MSG_Get("MSCDEX_UNKNOWN_ERROR")); break; + } + // error: clean up and leave + if (error) { + for(int i = 0; i < isoDisks.size(); i++) { + delete isoDisks[i]; + } + return; + } + } + // Update DriveManager + for(int i = 0; i < isoDisks.size(); i++) { + DriveManager::AppendDisk(drive - 'A', isoDisks[i]); + } + DriveManager::InitializeDrive(drive - 'A'); + // Set the correct media byte in the table - mem_writeb(Real2Phys(dos.tables.mediaid)+(drive-'A')*2,mediaid); - WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_2"),drive,temp_line.c_str()); + mem_writeb(Real2Phys(dos.tables.mediaid) + (drive - 'A') * 2, mediaid); + + // Print status message (success) + WriteOut(MSG_Get("MSCDEX_SUCCESS")); + std::string tmp(paths[0]); + for (int i = 1; i < paths.size(); i++) { + tmp += "; " + paths[i]; + } + WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_2"), drive, tmp.c_str()); + } else if (fstype=="none") { if(imageDiskList[drive-'0'] != NULL) delete imageDiskList[drive-'0']; imageDiskList[drive-'0'] = newImage; @@ -1137,6 +1167,7 @@ void DOS_SetupPrograms(void) { MSG_Add("MSCDEX_ERROR_PATH","MSCDEX: Failure: Path not valid.\n"); MSG_Add("MSCDEX_TOO_MANY_DRIVES","MSCDEX: Failure: Too many CDRom-drives (max: 5). MSCDEX Installation failed.\n"); MSG_Add("MSCDEX_LIMITED_SUPPORT","MSCDEX: Mounted subdirectory: limited support.\n"); + MSG_Add("MSCDEX_INVALID_FILEFORMAT","MSCDEX: Failure: File is either no iso/cue image or contains errors.\n"); MSG_Add("MSCDEX_UNKNOWN_ERROR","MSCDEX: Failure: Unknown error.\n"); MSG_Add("PROGRAM_RESCAN_SUCCESS","Drive cache cleared.\n"); @@ -1238,7 +1269,7 @@ void DOS_SetupPrograms(void) { ); MSG_Add("PROGRAM_BOOT_NOT_EXIST","Bootdisk file does not exist. Failing.\n"); MSG_Add("PROGRAM_BOOT_NOT_OPEN","Cannot open bootdisk file. Failing.\n"); - MSG_Add("PROGRAM_BOOT_PRINT_ERROR","This command boots DosBox from either a floppy or hard disk image.\n\n" + MSG_Add("PROGRAM_BOOT_PRINT_ERROR","This command boots DOSBox from either a floppy or hard disk image.\n\n" "For this command, one can specify a succession of floppy disks swappable\n" "by pressing Ctrl-F4, and -l specifies the mounted drive to boot from. If\n" "no drive letter is specified, this defaults to booting from the A drive.\n" @@ -1252,17 +1283,18 @@ void DOS_SetupPrograms(void) { MSG_Add("PROGRAM_BOOT_IMAGE_OPEN","Opening image file: %s\n"); MSG_Add("PROGRAM_BOOT_IMAGE_NOT_OPEN","Cannot open %s"); MSG_Add("PROGRAM_BOOT_BOOT","Booting from drive %c...\n"); - MSG_Add("PROGRAM_BOOT_CART_WO_PCJR","PCJr cartridge found, but machine is not PCJr"); - MSG_Add("PROGRAM_BOOT_CART_LIST_CMDS","Available PCJr cartridge commandos:%s"); - MSG_Add("PROGRAM_BOOT_CART_NO_CMDS","No PCJr cartridge commandos found"); + MSG_Add("PROGRAM_BOOT_CART_WO_PCJR","PCjr cartridge found, but machine is not PCjr"); + MSG_Add("PROGRAM_BOOT_CART_LIST_CMDS","Available PCjr cartridge commandos:%s"); + MSG_Add("PROGRAM_BOOT_CART_NO_CMDS","No PCjr cartridge commandos found"); MSG_Add("PROGRAM_IMGMOUNT_SPECIFY_DRIVE","Must specify drive letter to mount image at.\n"); MSG_Add("PROGRAM_IMGMOUNT_SPECIFY2","Must specify drive number (0 or 3) to mount image at (0,1=fda,fdb;2,3=hda,hdb).\n"); MSG_Add("PROGRAM_IMGMOUNT_SPECIFY_GEOMETRY", - "For \033[33mCD-ROM\033[0m images: \033[34;1mimgmount Drive-Letter location-of-image -t iso\033[0m\n" + "For \033[33mCD-ROM\033[0m images: \033[34;1mIMGMOUNT drive-letter location-of-image -t iso\033[0m\n" "\n" "For \033[33mhardrive\033[0m images: Must specify drive geometry for hard drives:\n" - "bytes_per_sector, sectors_per_cylinder, heads_per_cylinder, cylinder_count.\n"); + "bytes_per_sector, sectors_per_cylinder, heads_per_cylinder, cylinder_count.\n" + "\033[34;1mIMGMOUNT drive-letter location-of-image -size bps,spc,hpc,cyl\033[0m\n"); MSG_Add("PROGRAM_IMGMOUNT_TYPE_UNSUPPORTED","Type \"%s\" is unsupported. Specify \"hdd\" or \"floppy\" or\"iso\".\n"); MSG_Add("PROGRAM_IMGMOUNT_FORMAT_UNSUPPORTED","Format \"%s\" is unsupported. Specify \"fat\" or \"iso\" or \"none\".\n"); MSG_Add("PROGRAM_IMGMOUNT_SPECIFY_FILE","Must specify file-image to mount.\n"); @@ -1271,6 +1303,8 @@ void DOS_SetupPrograms(void) { MSG_Add("PROGRAM_IMGMOUNT_ALREADY_MOUNTED","Drive already mounted at that letter.\n"); MSG_Add("PROGRAM_IMGMOUNT_CANT_CREATE","Can't create drive from file.\n"); MSG_Add("PROGRAM_IMGMOUNT_MOUNT_NUMBER","Drive number %d mounted as %s\n"); + MSG_Add("PROGRAM_IMGMOUNT_NON_LOCAL_DRIVE", "The image must be on a host or local drive.\n"); + MSG_Add("PROGRAM_IMGMOUNT_MULTIPLE_NON_CUEISO_FILES", "Using multiple files is only supported for cue/iso images.\n"); MSG_Add("PROGRAM_KEYB_INFO","Codepage %i has been loaded\n"); MSG_Add("PROGRAM_KEYB_SHOWHELP", diff --git a/src/dos/drive_iso.cpp b/src/dos/drive_iso.cpp index 710764e4..dd5ec85b 100644 --- a/src/dos/drive_iso.cpp +++ b/src/dos/drive_iso.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drive_iso.cpp,v 1.16 2007-01-10 10:47:08 qbix79 Exp $ */ +/* $Id: drive_iso.cpp,v 1.17 2007-01-21 16:21:22 c2woody Exp $ */ #include #include @@ -140,7 +140,8 @@ Bit16u isoFile::GetInformation(void) int MSCDEX_RemoveDrive(char driveLetter); int MSCDEX_AddDrive(char driveLetter, const char* physicalPath, Bit8u& subUnit); -bool MSCDEX_HasMediaChanged(Bit8u subUnit); +void MSCDEX_ReplaceDrive(CDROM_Interface* cdrom, Bit8u subUnit); +bool MSCDEX_HasDrive(char driveLetter); bool MSCDEX_GetVolumeName(Bit8u subUnit, char* name); isoDrive::isoDrive(char driveLetter, const char *fileName, Bit8u mediaid, int &error) @@ -150,7 +151,8 @@ isoDrive::isoDrive(char driveLetter, const char *fileName, Bit8u mediaid, int &e memset(sectorHashEntries, 0, sizeof(sectorHashEntries)); memset(&rootEntry, 0, sizeof(isoDirEntry)); - error = MSCDEX_AddDrive(driveLetter, fileName, subUnit); + safe_strncpy(this->fileName, fileName, CROSS_LEN); + error = UpdateMscdex(driveLetter, fileName, subUnit); if (!error) { if (loadImage()) { @@ -187,6 +189,28 @@ isoDrive::isoDrive(char driveLetter, const char *fileName, Bit8u mediaid, int &e isoDrive::~isoDrive() { } +int isoDrive::UpdateMscdex(char driveLetter, const char* path, Bit8u& subUnit) { + if (MSCDEX_HasDrive(driveLetter)) { + CDROM_Interface_Image* oldCdrom = CDROM_Interface_Image::images[subUnit]; + CDROM_Interface* cdrom = new CDROM_Interface_Image(subUnit); + char pathCopy[CROSS_LEN]; + safe_strncpy(pathCopy, path, CROSS_LEN); + if (!cdrom->SetDevice(pathCopy, 0)) { + CDROM_Interface_Image::images[subUnit] = oldCdrom; + delete cdrom; + return 3; + } + MSCDEX_ReplaceDrive(cdrom, subUnit); + return 0; + } else { + return MSCDEX_AddDrive(driveLetter, path, subUnit); + } +} + +void isoDrive::Activate(void) { + UpdateMscdex(driveLetter, fileName, subUnit); +} + bool isoDrive::FileOpen(DOS_File **file, char *name, Bit32u flags) { if (flags == OPEN_WRITE) { diff --git a/src/dos/drives.cpp b/src/dos/drives.cpp index 9720ff33..fa5f50fc 100644 --- a/src/dos/drives.cpp +++ b/src/dos/drives.cpp @@ -19,6 +19,7 @@ #include "dosbox.h" #include "dos_system.h" #include "drives.h" +#include "mapper.h" #include "support.h" bool WildFileCmp(const char * file, const char * wild) @@ -82,3 +83,113 @@ DOS_Drive::DOS_Drive() { char * DOS_Drive::GetInfo(void) { return info; } + +// static members variables +int DriveManager::currentDrive; +DriveManager::DriveInfo DriveManager::driveInfos[26]; + +void DriveManager::AppendDisk(int drive, DOS_Drive* disk) { + driveInfos[drive].disks.push_back(disk); +} + +void DriveManager::InitializeDrive(int drive) { + currentDrive = drive; + DriveInfo& driveInfo = driveInfos[currentDrive]; + if (driveInfo.disks.size() > 0) { + driveInfo.currentDisk = 0; + DOS_Drive* disk = driveInfo.disks[driveInfo.currentDisk]; + Drives[currentDrive] = disk; + disk->Activate(); + } +} + +/* +void DriveManager::CycleDrive(bool pressed) { + if (!pressed) return; + + // do one round through all drives or stop at the next drive with multiple disks + int oldDrive = currentDrive; + do { + currentDrive = (currentDrive + 1) % DOS_DRIVES; + int numDisks = driveInfos[currentDrive].disks.size(); + if (numDisks > 1) break; + } while (currentDrive != oldDrive); +} + +void DriveManager::CycleDisk(bool pressed) { + if (!pressed) return; + + int numDisks = driveInfos[currentDrive].disks.size(); + if (numDisks > 1) { + // cycle disk + int currentDisk = driveInfos[currentDrive].currentDisk; + DOS_Drive* oldDisk = driveInfos[currentDrive].disks[currentDisk]; + currentDisk = (currentDisk + 1) % numDisks; + DOS_Drive* newDisk = driveInfos[currentDrive].disks[currentDisk]; + driveInfos[currentDrive].currentDisk = currentDisk; + + // copy working directory, acquire system resources and finally switch to next drive + strcpy(newDisk->curdir, oldDisk->curdir); + newDisk->Activate(); + Drives[currentDrive] = newDisk; + } +} +*/ + +void DriveManager::CycleAllDisks(void) { + for (int idrive=0; idrive 1) { + // cycle disk + int currentDisk = driveInfos[idrive].currentDisk; + DOS_Drive* oldDisk = driveInfos[idrive].disks[currentDisk]; + currentDisk = (currentDisk + 1) % numDisks; + DOS_Drive* newDisk = driveInfos[idrive].disks[currentDisk]; + driveInfos[idrive].currentDisk = currentDisk; + + // copy working directory, acquire system resources and finally switch to next drive + strcpy(newDisk->curdir, oldDisk->curdir); + newDisk->Activate(); + Drives[idrive] = newDisk; + LOG_MSG("Drive %c: disk %d of %d now active", 'A'+idrive, currentDisk+1, numDisks); + } + } +} + +int DriveManager::UnmountDrive(int drive) { + int result = 0; + // unmanaged drive + if (driveInfos[drive].disks.size() == 0) { + result = Drives[drive]->UnMount(); + } else { + // managed drive + int currentDisk = driveInfos[drive].currentDisk; + result = driveInfos[drive].disks[currentDisk]->UnMount(); + // only delete on success, current disk set to NULL because of UnMount + if (result == 0) { + driveInfos[drive].disks[currentDisk] = NULL; + for (int i = 0; i < (int)driveInfos[drive].disks.size(); i++) { + delete driveInfos[drive].disks[i]; + } + driveInfos[drive].disks.clear(); + } + } + + return result; +} + +void DriveManager::Init(Section* /* sec */) { + + // setup driveInfos structure + currentDrive = 0; + for(int i = 0; i < DOS_DRIVES; i++) { + driveInfos[i].currentDisk = 0; + } + +// MAPPER_AddHandler(&CycleDisk, MK_f3, MMOD1, "cycledisk", "Cycle Disk"); +// MAPPER_AddHandler(&CycleDrive, MK_f3, MMOD2, "cycledrive", "Cycle Drv"); +} + +void DRIVES_Init(Section* sec) { + DriveManager::Init(sec); +} diff --git a/src/dos/drives.h b/src/dos/drives.h index 052b618c..51d618fd 100644 --- a/src/dos/drives.h +++ b/src/dos/drives.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: drives.h,v 1.35 2007-01-08 19:45:39 qbix79 Exp $ */ +/* $Id: drives.h,v 1.36 2007-01-21 16:21:22 c2woody Exp $ */ #ifndef _DRIVES_H__ #define _DRIVES_H__ @@ -29,6 +29,25 @@ bool WildFileCmp(const char * file, const char * wild); +class DriveManager { +public: + static void AppendDisk(int drive, DOS_Drive* disk); + static void InitializeDrive(int drive); + static int UnmountDrive(int drive); +// static void CycleDrive(bool pressed); +// static void CycleDisk(bool pressed); + static void CycleAllDisks(void); + static void Init(Section* sec); + +private: + static struct DriveInfo { + std::vector disks; + Bit32u currentDisk; + } driveInfos[DOS_DRIVES]; + + static int currentDrive; +}; + class localDrive : public DOS_Drive { public: localDrive(const char * startdir,Bit16u _bytes_sector,Bit8u _sectors_cluster,Bit16u _total_clusters,Bit16u _free_clusters,Bit8u _mediaid); @@ -311,12 +330,13 @@ public: virtual Bits UnMount(void); bool readSector(Bit8u *buffer, Bit32u sector); virtual char const* GetLabel(void) {return discLabel;}; + virtual void Activate(void); private: int readDirEntry(isoDirEntry *de, Bit8u *data); bool loadImage(); bool lookupSingle(isoDirEntry *de, const char *name, Bit32u sectorStart, Bit32u length); bool lookup(isoDirEntry *de, const char *path); - + int UpdateMscdex(char driveLetter, const char* physicalPath, Bit8u& subUnit); int GetDirIterator(const isoDirEntry* de); bool GetNextDirEntry(const int dirIterator, isoDirEntry* de); void FreeDirIterator(const int dirIterator); @@ -339,6 +359,7 @@ private: isoDirEntry rootEntry; Bit8u mediaid; + char fileName[CROSS_LEN]; Bit8u subUnit; char driveLetter; char discLabel[32]; diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 23433d71..0bd3b423 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.111 2007-01-13 08:35:49 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.112 2007-01-21 16:21:22 c2woody Exp $ */ #include #include @@ -96,6 +96,8 @@ void DEBUG_Init(Section*); void CMOS_Init(Section*); void MSCDEX_Init(Section*); +void DRIVES_Init(Section*); +void CDROM_Image_Init(Section*); /* Dos Internal mostly */ void EMS_Init(Section*); @@ -456,6 +458,8 @@ void DOSBOX_Init(void) { ); // Mscdex secprop->AddInitFunction(&MSCDEX_Init); + secprop->AddInitFunction(&DRIVES_Init); + secprop->AddInitFunction(&CDROM_Image_Init); #if C_IPX secprop=control->AddSection_prop("ipx",&IPX_Init,true); secprop->Add_bool("ipx", false); diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index 34c03ea3..48e4196e 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios_disk.cpp,v 1.32 2007-01-14 18:44:01 c2woody Exp $ */ +/* $Id: bios_disk.cpp,v 1.33 2007-01-21 16:21:22 c2woody Exp $ */ #include "dosbox.h" #include "callback.h" @@ -24,6 +24,7 @@ #include "regs.h" #include "mem.h" #include "dos_inc.h" /* for Drives[] */ +#include "../dos/drives.h" #include "mapper.h" #define MAX_DISK_IMAGES 4 @@ -124,6 +125,7 @@ void swapInNextDisk(bool pressed) { if (!pressed) return; /* Hack/feature: rescan all disks as well */ + DriveManager::CycleAllDisks(); for(Bitu i=0;iEmptyCache(); } @@ -396,6 +398,7 @@ static Bitu INT13_DiskHandler(void) { return CBRET_NONE; } } + reg_ah = 0x00; CALLBACK_SCF(false); break; case 0x04: /* Verify sectors */