Merge pull request #3060 from Allofich/io

Make floppy disk I/O configurable
This commit is contained in:
Jonathan Campbell
2021-11-14 14:59:45 +00:00
committed by GitHub
6 changed files with 80 additions and 17 deletions

View File

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

View File

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

View File

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

View File

@@ -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<Section_prop*>(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;

View File

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

View File

@@ -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;i<reg_al;i++) {
last_status = imageDiskList[drivenum]->Read_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), &sectbuf[0]);
if(last_status != 0x00) {
@@ -1117,7 +1123,10 @@ static Bitu INT13_DiskHandler(void) {
for(i=0;i<dap.num;i++) {
last_status = imageDiskList[drivenum]->Read_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, &sectbuf[0]);
if(last_status != 0x00) {