1
0
Fork 0

add imagedisk swapping capabilities (prompt, slightly modified sf patch #1505951); fix int13 write sectors return code

Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2778
This commit is contained in:
Sebastian Strohhäcker 2007-01-21 16:21:22 +00:00
parent 235c630cef
commit e608297aae
10 changed files with 319 additions and 87 deletions

19
README
View file

@ -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.

View file

@ -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};

View file

@ -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 <cctype>
#include <cmath>
@ -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
}

View file

@ -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 <string.h>
#include <ctype.h>
@ -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);

View file

@ -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 <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <string>
#include <vector>
#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<std::string> 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<DOS_Drive*> 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",

View file

@ -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 <cctype>
#include <cstring>
@ -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) {

View file

@ -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<DOS_DRIVES; idrive++) {
int numDisks = (int)driveInfos[idrive].disks.size();
if (numDisks > 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);
}

View file

@ -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<DOS_Drive*> 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];

View file

@ -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 <stdlib.h>
#include <stdarg.h>
@ -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);

View file

@ -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;i<DOS_DRIVES;i++) {
if (Drives[i]) Drives[i]->EmptyCache();
}
@ -396,6 +398,7 @@ static Bitu INT13_DiskHandler(void) {
return CBRET_NONE;
}
}
reg_ah = 0x00;
CALLBACK_SCF(false);
break;
case 0x04: /* Verify sectors */