diff --git a/CHANGELOG b/CHANGELOG index b139a782d..486bf3a00 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -81,6 +81,10 @@ - Make memory B0000-B7FFF unmapped for the CGA emulation. Fixes "Backgammon 5.0" detecting that an MDA is also present when using CGA. (Allofich) + - Make floppy I/O delay separataly configurable from + hard drive delay, and make it slower than before + by default.(Allofich) + - Fixed possible crash with printing. (jamesbond3142) - Video emulation for PC-98 mode (for 400-line modes) is now 16:10 instead of 4:3. 480-line PC-98 modes are still 4:3. (joncampbell123) diff --git a/dosbox-x.reference.conf b/dosbox-x.reference.conf index 19890a799..221c145c5 100644 --- a/dosbox-x.reference.conf +++ b/dosbox-x.reference.conf @@ -968,6 +968,9 @@ timeout = 0 # hard drive data rate limit: Slow down (limit) hard disk throughput. This setting controls the limit in bytes/second. # Set to 0 to disable the limit, or -1 (default) to use a reasonable limit. # The disk I/O performance as in DOSBox SVN can be achieved by setting this to 0. +# floppy drive data rate limit: Slow down (limit) floppy disk throughput. This setting controls the limit in bytes/second. +# Set to 0 to disable the limit, or -1 (default) to use a reasonable limit. +# The disk I/O performance as in DOSBox SVN can be achieved by setting this to 0. # ansi.sys: If set (by default), ANSI.SYS emulation is on. If clear, ANSI.SYS is not emulated and will not appear to be installed. # NOTE: This option has no effect in PC-98 mode where MS-DOS systems integrate ANSI.SYS into the DOS kernel. # log console: If set, log DOS CON output to the log file. Setting to "quiet" will log DOS CON output only (no debugging output). diff --git a/dosbox-x.reference.full.conf b/dosbox-x.reference.full.conf index 1458ea21d..a60590a67 100644 --- a/dosbox-x.reference.full.conf +++ b/dosbox-x.reference.full.conf @@ -1928,6 +1928,9 @@ timeout = 0 # hard drive data rate limit: Slow down (limit) hard disk throughput. This setting controls the limit in bytes/second. # Set to 0 to disable the limit, or -1 (default) to use a reasonable limit. # The disk I/O performance as in DOSBox SVN can be achieved by setting this to 0. +# floppy drive data rate limit: Slow down (limit) floppy disk throughput. This setting controls the limit in bytes/second. +# Set to 0 to disable the limit, or -1 (default) to use a reasonable limit. +# The disk I/O performance as in DOSBox SVN can be achieved by setting this to 0. # drive z is remote: If set, DOS will report drive Z as remote. If not set, DOS will report drive Z as local. # If auto (default), DOS will report drive Z as remote or local depending on the program. # Set this option to true to prevent SCANDISK.EXE from attempting scan and repair drive Z: diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 355341e1b..8eab37a69 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -420,7 +420,7 @@ static void DOS_AddDays(uint8_t days) { #endif // TODO: Make this configurable. -// (This can be controlled with the setting "hard drive data rate limit") +// (This can be controlled with the settings "hard drive data rate limit" and "floppy drive data rate limit") // Additionally, allow this to vary per-drive so that // Drive D: can be as slow as a 2X IDE CD-ROM drive in PIO mode // Drive C: can be as slow as a IDE drive in PIO mode and @@ -429,11 +429,21 @@ static void DOS_AddDays(uint8_t days) { // This fixes MS-DOS games that crash or malfunction if the disk I/O is too fast. // This also fixes "380 volt" and prevents the "city animation" from loading too fast for it's music timing (and getting stuck) int disk_data_rate = 2100000; // 2.1MBytes/sec mid 1990s IDE PIO hard drive without SMARTDRV +int floppy_data_rate; -void diskio_delay(Bits value/*bytes*/) { - if (disk_data_rate != 0) { - double scalar = (double)value / disk_data_rate; - double endtime = PIC_FullIndex() + (scalar * 1000); +void diskio_delay(Bits value/*bytes*/, int type = -1) { + if ((type == 0 && floppy_data_rate != 0) || (type != 0 && disk_data_rate != 0)) { + double scalar; + double endtime; + + if(type == 0) { // Floppy + scalar = (double)value / floppy_data_rate; + endtime = PIC_FullIndex() + (scalar * 1000); + } + else { // Hard drive or CD-ROM + scalar = (double)value / disk_data_rate; + endtime = PIC_FullIndex() + (scalar * 1000); + } /* MS-DOS will most likely enable interrupts in the course of * performing disk I/O */ @@ -1701,7 +1711,10 @@ static Bitu DOS_21Handler(void) { reg_ax=dos.errorcode; CALLBACK_SCF(true); } - diskio_delay(2048); + if (DOS_GetDefaultDrive() < 2) + diskio_delay(2048,0); // Floppy + else + diskio_delay(2048); force_sfn = false; break; case 0x3d: /* OPEN Open existing file */ @@ -1767,7 +1780,10 @@ static Bitu DOS_21Handler(void) { reg_ax=dos.errorcode; CALLBACK_SCF(true); } - diskio_delay(1024); + if(DOS_GetDefaultDrive() < 2) + diskio_delay(1024,0); // Floppy + else + diskio_delay(1024); force_sfn = false; break; } @@ -1784,7 +1800,10 @@ static Bitu DOS_21Handler(void) { reg_ax=dos.errorcode; CALLBACK_SCF(true); } - diskio_delay(512); + if(DOS_GetDefaultDrive() < 2) + diskio_delay(512, 0); // Floppy + else + diskio_delay(512); break; case 0x3f: /* READ Read from file or device */ unmask_irq0 |= disk_io_unmask_irq0; @@ -1849,7 +1868,10 @@ static Bitu DOS_21Handler(void) { reg_ax=dos.errorcode; CALLBACK_SCF(true); } - diskio_delay(reg_ax); + if(DOS_GetDefaultDrive() < 2) + diskio_delay(reg_ax,0); // Floppy + else + diskio_delay(reg_ax); dos.echo=false; break; } @@ -1882,7 +1904,10 @@ static Bitu DOS_21Handler(void) { reg_ax=dos.errorcode; CALLBACK_SCF(true); } - diskio_delay(reg_ax); + if(DOS_GetDefaultDrive() < 2) + diskio_delay(reg_ax,0); // Floppy + else + diskio_delay(reg_ax); break; } case 0x41: /* UNLINK Delete file */ @@ -1896,7 +1921,10 @@ static Bitu DOS_21Handler(void) { CALLBACK_SCF(true); } force_sfn = false; - diskio_delay(1024); + if(DOS_GetDefaultDrive() < 2) + diskio_delay(1024,0); // Floppy + else + diskio_delay(1024); break; case 0x42: /* LSEEK Set current file position */ unmask_irq0 |= disk_io_unmask_irq0; @@ -1910,7 +1938,10 @@ static Bitu DOS_21Handler(void) { reg_ax=dos.errorcode; CALLBACK_SCF(true); } - diskio_delay(32); + if(DOS_GetDefaultDrive() < 2) + diskio_delay(32,0); // Floppy + else + diskio_delay(32); break; } case 0x43: /* Get/Set file attributes */ @@ -3623,6 +3654,7 @@ public: const Section_prop* section = static_cast(configuration); ::disk_data_rate = section->Get_int("hard drive data rate limit"); + ::floppy_data_rate = section->Get_int("floppy drive data rate limit"); if (::disk_data_rate < 0) { extern bool pcibus_enable; @@ -3630,6 +3662,9 @@ public: ::disk_data_rate = 8333333; /* Probably an average IDE data rate for mid 1990s PCI IDE controllers in PIO mode */ else ::disk_data_rate = 3500000; /* Probably an average IDE data rate for early 1990s ISA IDE controllers in PIO mode */ + } + if(::floppy_data_rate < 0) { + ::floppy_data_rate = 5000; // Slow enough so that PC Booter game title screens that depend on floppy drive speed will show for a few seconds } maxfcb=100; DOS_FILES=200; diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 6c19361be..8dbb2704c 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -3905,6 +3905,12 @@ void DOSBOX_SetupConfigSections(void) { "The disk I/O performance as in DOSBox SVN can be achieved by setting this to 0."); Pint->SetBasic(true); + Pint = secprop->Add_int("floppy drive data rate limit", Property::Changeable::WhenIdle, -1); + Pint->Set_help("Slow down (limit) floppy disk throughput. This setting controls the limit in bytes/second.\n" + "Set to 0 to disable the limit, or -1 (default) to use a reasonable limit.\n" + "The disk I/O performance as in DOSBox SVN can be achieved by setting this to 0."); + Pint->SetBasic(true); + Pstring = secprop->Add_string("drive z is remote",Property::Changeable::WhenIdle,"auto"); Pstring->Set_values(truefalseautoopt); Pstring->Set_help("If set, DOS will report drive Z as remote. If not set, DOS will report drive Z as local.\n" diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index 6bf3a4fe8..3a5771f7e 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -734,7 +734,7 @@ void IDE_ResetDiskByBIOS(unsigned char disk); void IDE_EmuINT13DiskReadByBIOS(unsigned char disk,unsigned int cyl,unsigned int head,unsigned sect); void IDE_EmuINT13DiskReadByBIOS_LBA(unsigned char disk,uint64_t lba); -void diskio_delay(Bits value/*bytes*/); +void diskio_delay(Bits value/*bytes*/, int type = -1); static Bitu INT13_DiskHandler(void) { uint16_t segat, bufptr; @@ -859,7 +859,10 @@ static Bitu INT13_DiskHandler(void) { for(i=0;iRead_Sector((uint32_t)reg_dh, (uint32_t)(reg_ch | ((reg_cl & 0xc0)<< 2)), (uint32_t)((reg_cl & 63)+i), sectbuf); - diskio_delay(512); + if (drivenum < 2) + diskio_delay(512, 0); // Floppy + else + diskio_delay(512); /* IDE emulation: simulate change of IDE state that would occur on a real machine after INT 13h */ IDE_EmuINT13DiskReadByBIOS(reg_dl, (uint32_t)(reg_ch | ((reg_cl & 0xc0)<< 2)), (uint32_t)reg_dh, (uint32_t)((reg_cl & 63)+i)); @@ -908,7 +911,10 @@ static Bitu INT13_DiskHandler(void) { bufptr++; } - diskio_delay(512); + if(drivenum < 2) + diskio_delay(512, 0); // Floppy + else + diskio_delay(512); last_status = imageDiskList[drivenum]->Write_Sector((uint32_t)reg_dh, (uint32_t)(reg_ch | ((reg_cl & 0xc0) << 2)), (uint32_t)((reg_cl & 63) + i), §buf[0]); if(last_status != 0x00) { @@ -1117,7 +1123,10 @@ static Bitu INT13_DiskHandler(void) { for(i=0;iRead_AbsoluteSector(dap.sector+i, sectbuf); - diskio_delay(512); + if(drivenum < 2) + diskio_delay(512, 0); // Floppy + else + diskio_delay(512); IDE_EmuINT13DiskReadByBIOS_LBA(reg_dl,dap.sector+i); @@ -1152,7 +1161,10 @@ static Bitu INT13_DiskHandler(void) { bufptr++; } - diskio_delay(512); + if(drivenum < 2) + diskio_delay(512, 0); // Floppy + else + diskio_delay(512); last_status = imageDiskList[drivenum]->Write_AbsoluteSector(dap.sector+i, §buf[0]); if(last_status != 0x00) {