mirror of https://github.com/bochs-emu/Bochs
- patch is checked in and there are no bugreports
This commit is contained in:
parent
26a2731a19
commit
c24eaf3e3c
|
@ -1,512 +0,0 @@
|
|||
----------------------------------------------------------------------
|
||||
Patch name: patch.floppy-volker
|
||||
Author: Volker.Ruppert@t-online.de
|
||||
Date: Don Dez 27 10:23:47 CET 2001
|
||||
|
||||
Detailed description:
|
||||
|
||||
This patch fixes the behaviour of some floppy commands (Windows 95 driver
|
||||
works now). The changes are checked in, so you can use this file to revert
|
||||
them if they cause trouble.
|
||||
|
||||
* diskette controller data register returns last result if no new data
|
||||
is available
|
||||
* reset will be activated when the reset bit is changed to normal operation
|
||||
* reset sets the error bits in status register 0
|
||||
* write access to port 0x3f4 will cause a BX_ERROR now
|
||||
* unsupported and invalid floppy commands are setting the error status bit
|
||||
'invalid command' - BX_PANIC not necessary
|
||||
* flag FS_MS_DIO is not set while a floppy command is pending
|
||||
* floppy command 'specify': cause a BX_ERROR when non-DMA mode is selected
|
||||
* floppy command 'sense interrupt status' returns an error if no interrupt
|
||||
is pending
|
||||
* floppy command 'read ID' sets the 'busy' flag and returns no data if the
|
||||
motor is not on
|
||||
* removed SIMX86 section (not defined in bochs)
|
||||
* define variable 'sTemp' for win32 only
|
||||
* removed commented BX_INFO statements
|
||||
|
||||
Patch was created with:
|
||||
diff -u
|
||||
Apply patch to what version:
|
||||
cvs checked out on DATE
|
||||
Instructions:
|
||||
To patch, go to main bochs directory.
|
||||
Type "patch -p0 < THIS_PATCH_FILE".
|
||||
----------------------------------------------------------------------
|
||||
--- ../bochs/iodev/floppy.h Wed Oct 3 15:10:38 2001
|
||||
+++ iodev/floppy.h Thu Dec 27 09:31:46 2001
|
||||
@@ -70,6 +70,8 @@
|
||||
Boolean command_complete;
|
||||
Bit8u pending_command;
|
||||
|
||||
+ Boolean pending_irq;
|
||||
+
|
||||
Bit8u result[10];
|
||||
Bit8u result_index;
|
||||
Bit8u result_size;
|
||||
--- ../bochs/iodev/floppy.cc Sun Oct 7 05:28:45 2001
|
||||
+++ iodev/floppy.cc Thu Dec 27 09:38:45 2001
|
||||
@@ -132,7 +132,7 @@
|
||||
cmos->s.reg[0x10] = (cmos->s.reg[0x10] & 0x0f) | 0x50;
|
||||
break;
|
||||
default:
|
||||
- BX_PANIC(( "unknown floppya type" ));
|
||||
+ BX_PANIC(("unknown floppya type"));
|
||||
}
|
||||
|
||||
if (bx_options.floppya.Otype->get () != BX_FLOPPY_NONE) {
|
||||
@@ -226,6 +226,8 @@
|
||||
BX_FD_THIS s.command_size = 0;
|
||||
BX_FD_THIS s.pending_command = 0;
|
||||
|
||||
+ BX_FD_THIS s.pending_irq = 0;
|
||||
+
|
||||
BX_FD_THIS s.result_index = 0;
|
||||
BX_FD_THIS s.result_size = 0;
|
||||
|
||||
@@ -307,13 +309,17 @@
|
||||
|
||||
case 0x3F5: /* diskette controller data */
|
||||
if (BX_FD_THIS s.result_size == 0) {
|
||||
- BX_PANIC(("diskette controller:port3f5: no results to read"));
|
||||
+ BX_ERROR(("port 0x3f5: no results to read"));
|
||||
+ BX_FD_THIS s.main_status_reg = 0;
|
||||
+ return BX_FD_THIS s.result[0];
|
||||
}
|
||||
|
||||
value = BX_FD_THIS s.result[BX_FD_THIS s.result_index++];
|
||||
+ BX_FD_THIS s.main_status_reg &= 0xF0;
|
||||
if (BX_FD_THIS s.result_index >= BX_FD_THIS s.result_size) {
|
||||
BX_FD_THIS s.result_size = 0;
|
||||
BX_FD_THIS s.result_index = 0;
|
||||
+ BX_FD_THIS s.result[0] = value;
|
||||
BX_FD_THIS s.main_status_reg = FD_MS_MRQ;
|
||||
}
|
||||
return(value);
|
||||
@@ -399,22 +405,14 @@
|
||||
|
||||
if (prev_normal_operation==0 && normal_operation) {
|
||||
// transition from RESET to NORMAL
|
||||
-#if 0
|
||||
-
|
||||
- BX_FD_THIS s.main_status_reg = FD_MS_BUSY;
|
||||
- BX_FD_THIS s.pending_command = 0xfe; // RESET pending
|
||||
-
|
||||
bx_pc_system.activate_timer( BX_FD_THIS s.floppy_timer_index,
|
||||
bx_options.Ofloppy_command_delay->get (), 0 );
|
||||
-#endif
|
||||
}
|
||||
else if (prev_normal_operation && normal_operation==0) {
|
||||
// transition from NORMAL to RESET
|
||||
BX_FD_THIS s.main_status_reg = FD_MS_BUSY;
|
||||
BX_FD_THIS s.pending_command = 0xfe; // RESET pending
|
||||
|
||||
- bx_pc_system.activate_timer( BX_FD_THIS s.floppy_timer_index,
|
||||
- bx_options.Ofloppy_command_delay->get (), 0 );
|
||||
}
|
||||
BX_DEBUG(("io_write: digital output register"));
|
||||
BX_DEBUG((" motor on, drive1 = %d", motor_on_drive1 > 0));
|
||||
@@ -431,7 +429,7 @@
|
||||
break;
|
||||
|
||||
case 0x3f4: /* diskette controller data rate select register */
|
||||
- BX_PANIC(("io_write: data rate select register"));
|
||||
+ BX_ERROR(("io_write: data rate select register unsupported"));
|
||||
break;
|
||||
|
||||
case 0x3F5: /* diskette controller data */
|
||||
@@ -457,8 +455,6 @@
|
||||
break;
|
||||
case 0x08: /* sense interrupt status */
|
||||
BX_FD_THIS s.command_size = 1;
|
||||
- floppy_command();
|
||||
- BX_FD_THIS s.command_complete = 1;
|
||||
break;
|
||||
case 0x0f: /* seek */
|
||||
BX_FD_THIS s.command_size = 3;
|
||||
@@ -483,29 +479,29 @@
|
||||
// These commands are not implemented on the standard
|
||||
// controller and return an error. They are available on
|
||||
// the enhanced controller.
|
||||
+ BX_DEBUG(("io_write: 0x3f5: unsupported floppy command 0x%02x",
|
||||
+ (unsigned) value));
|
||||
BX_FD_THIS s.command_size = 1;
|
||||
- BX_FD_THIS s.result[0] = 0x80;
|
||||
- BX_FD_THIS s.result_size = 1;
|
||||
- BX_FD_THIS s.result_index = 0;
|
||||
- BX_FD_THIS s.main_status_reg = FD_MS_MRQ | FD_MS_DIO | FD_MS_BUSY;
|
||||
- BX_FD_THIS s.command_complete = 1;
|
||||
+ BX_FD_THIS s.status_reg0 = 0x80; // status: invalid command
|
||||
break;
|
||||
|
||||
default:
|
||||
- BX_PANIC(("io write:3f5: unsupported case 0x%02x",
|
||||
+ BX_ERROR(("io_write: 0x3f5: invalid floppy command 0x%02x",
|
||||
(unsigned) value));
|
||||
+ BX_FD_THIS s.command_size = 1;
|
||||
+ BX_FD_THIS s.status_reg0 = 0x80; // status: invalid command
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
BX_FD_THIS s.command[BX_FD_THIS s.command_index++] =
|
||||
value;
|
||||
- if (BX_FD_THIS s.command_index ==
|
||||
- BX_FD_THIS s.command_size) {
|
||||
- /* read/write command not in progress any more */
|
||||
- floppy_command();
|
||||
- BX_FD_THIS s.command_complete = 1;
|
||||
- }
|
||||
+ }
|
||||
+ if (BX_FD_THIS s.command_index ==
|
||||
+ BX_FD_THIS s.command_size) {
|
||||
+ /* read/write command not in progress any more */
|
||||
+ floppy_command();
|
||||
+ BX_FD_THIS s.command_complete = 1;
|
||||
}
|
||||
BX_DEBUG(("io_write: diskette controller data"));
|
||||
return;
|
||||
@@ -568,12 +564,13 @@
|
||||
|
||||
switch (BX_FD_THIS s.command[0]) {
|
||||
case 0x03: // specify
|
||||
-//BX_INFO(("floppy_command specify"));
|
||||
// execution: specified parameters are loaded
|
||||
// result: no result bytes, no interrupt
|
||||
step_rate_time = BX_FD_THIS s.command[1] >> 4;
|
||||
head_unload_time = BX_FD_THIS s.command[1] & 0x0f;
|
||||
head_load_time = BX_FD_THIS s.command[2] >> 1;
|
||||
+ if (BX_FD_THIS s.command[2] & 0x01)
|
||||
+ BX_ERROR(("non DMA mode selected"));
|
||||
BX_FD_THIS s.main_status_reg = FD_MS_MRQ;
|
||||
return;
|
||||
break;
|
||||
@@ -589,7 +586,6 @@
|
||||
break;
|
||||
|
||||
case 0x07: // recalibrate
|
||||
-//BX_INFO(("floppy_command recalibrate"));
|
||||
drive = (BX_FD_THIS s.command[1] & 0x03);
|
||||
BX_FD_THIS s.DOR &= 0xfc;
|
||||
BX_FD_THIS s.DOR |= drive;
|
||||
@@ -616,13 +612,12 @@
|
||||
* seek end bit set to 1 in Status reg 0 regardless of outcome
|
||||
*/
|
||||
/* data reg not ready, controller busy */
|
||||
- BX_FD_THIS s.main_status_reg = FD_MS_DIO | FD_MS_BUSY;
|
||||
+ BX_FD_THIS s.main_status_reg = FD_MS_BUSY;
|
||||
BX_FD_THIS s.pending_command = 0x07; // recalibrate pending
|
||||
return;
|
||||
break;
|
||||
|
||||
case 0x08: /* sense interrupt status */
|
||||
-//BX_INFO(("floppy_command sense interrupt status"));
|
||||
/* execution:
|
||||
* get status
|
||||
* result:
|
||||
@@ -630,21 +625,27 @@
|
||||
* byte0 = status reg0
|
||||
* byte1 = current cylinder number (0 to 79)
|
||||
*/
|
||||
- /*BX_FD_THIS s.status_reg0 = ;*/
|
||||
drive = BX_FD_THIS s.DOR & 0x03;
|
||||
- BX_FD_THIS s.result[0] = 0x20 | drive;
|
||||
+ if (BX_FD_THIS s.pending_irq) {
|
||||
+ BX_FD_THIS s.pending_irq = 0;
|
||||
+ }
|
||||
+ else {
|
||||
+ BX_FD_THIS s.status_reg0 = 0x80;
|
||||
+ }
|
||||
+ BX_FD_THIS s.result[0] = BX_FD_THIS s.status_reg0;
|
||||
BX_FD_THIS s.result[1] = BX_FD_THIS s.cylinder[drive];
|
||||
BX_FD_THIS s.result_size = 2;
|
||||
BX_FD_THIS s.result_index = 0;
|
||||
+ BX_FD_THIS s.status_reg0 = 0;
|
||||
|
||||
/* read ready */
|
||||
- BX_FD_THIS s.main_status_reg = FD_MS_MRQ | FD_MS_DIO | FD_MS_BUSY;
|
||||
+ BX_FD_THIS s.main_status_reg &= 0x0f;
|
||||
+ BX_FD_THIS s.main_status_reg |= (FD_MS_MRQ | FD_MS_DIO | FD_MS_BUSY);
|
||||
BX_DEBUG(("sense interrupt status"));
|
||||
return;
|
||||
break;
|
||||
|
||||
case 0x0f: /* seek */
|
||||
-//BX_INFO(("floppy_command seek"));
|
||||
/* command:
|
||||
* byte0 = 0F
|
||||
* byte1 = drive & head select
|
||||
@@ -666,7 +667,7 @@
|
||||
bx_pc_system.activate_timer( BX_FD_THIS s.floppy_timer_index,
|
||||
bx_options.Ofloppy_command_delay->get (), 0 );
|
||||
/* data reg not ready, controller busy */
|
||||
- BX_FD_THIS s.main_status_reg = FD_MS_DIO | FD_MS_BUSY;
|
||||
+ BX_FD_THIS s.main_status_reg = FD_MS_BUSY;
|
||||
BX_FD_THIS s.pending_command = 0x0f; /* seek pending */
|
||||
return;
|
||||
break;
|
||||
@@ -682,38 +683,38 @@
|
||||
break;
|
||||
|
||||
case 0x4a: // read ID
|
||||
-//BX_INFO(("floppy_command read ID")); // ???
|
||||
drive = BX_FD_THIS s.command[1] & 0x03;
|
||||
BX_FD_THIS s.DOR &= 0xfc;
|
||||
BX_FD_THIS s.DOR |= drive;
|
||||
|
||||
motor_on = (BX_FD_THIS s.DOR>>(drive+4)) & 0x01;
|
||||
- if (motor_on == 0)
|
||||
- BX_PANIC(("floppy_command(): 4a: motor not on"));
|
||||
+ if (motor_on == 0) {
|
||||
+ BX_ERROR(("floppy_command(): 0x4a: motor not on"));
|
||||
+ BX_FD_THIS s.main_status_reg = FD_MS_BUSY;
|
||||
+ return;
|
||||
+ }
|
||||
if (drive > 1)
|
||||
BX_PANIC(("io: 4a: bad drive #"));
|
||||
BX_FD_THIS s.result_size = 7;
|
||||
BX_FD_THIS s.result_index = 0;
|
||||
- BX_FD_THIS s.result[0] = 0; /* ??? */
|
||||
- BX_FD_THIS s.result[1] = 0;
|
||||
- BX_FD_THIS s.result[2] = 0;
|
||||
+ // setting result[0] in timer handler
|
||||
+ BX_FD_THIS s.result[1] = BX_FD_THIS s.status_reg1;
|
||||
+ BX_FD_THIS s.result[2] = BX_FD_THIS s.status_reg2;
|
||||
BX_FD_THIS s.result[3] = BX_FD_THIS s.cylinder[drive];
|
||||
- BX_FD_THIS s.result[4] = 0; /* head */
|
||||
- BX_FD_THIS s.result[5] = 0; /* sector at completion */
|
||||
- BX_FD_THIS s.result[6] = 2;
|
||||
+ BX_FD_THIS s.result[4] = BX_FD_THIS s.head[drive];
|
||||
+ BX_FD_THIS s.result[5] = 1; /* sector at completion */
|
||||
+ BX_FD_THIS s.result[6] = 2; // sector size code
|
||||
bx_pc_system.activate_timer( BX_FD_THIS s.floppy_timer_index,
|
||||
bx_options.Ofloppy_command_delay->get (), 0 );
|
||||
/* data reg not ready, controller busy */
|
||||
- BX_FD_THIS s.main_status_reg = FD_MS_DIO | FD_MS_BUSY;
|
||||
+ BX_FD_THIS s.main_status_reg = FD_MS_BUSY;
|
||||
BX_FD_THIS s.pending_command = 0x4a; /* read ID pending */
|
||||
return;
|
||||
break;
|
||||
|
||||
|
||||
case 0xe6: // read normal data
|
||||
-//BX_INFO(("floppy_command read normal data"));
|
||||
case 0xc5: // write normal data
|
||||
-//BX_INFO(("floppy_command write normal data"));
|
||||
if ( (BX_FD_THIS s.DOR & 0x08) == 0 )
|
||||
BX_PANIC(("read/write command with DMA and int disabled"));
|
||||
drive = BX_FD_THIS s.command[1] & 0x03;
|
||||
@@ -749,7 +750,8 @@
|
||||
BX_ERROR(("head number in command[1] doesn't match head field"));
|
||||
BX_FD_THIS s.result_size = 7;
|
||||
BX_FD_THIS s.result_index = 0;
|
||||
- BX_FD_THIS s.result[0] = 0x40 | (BX_FD_THIS s.head[drive]<<2) | drive; // abnormal termination
|
||||
+ BX_FD_THIS s.status_reg0 = 0x40 | (BX_FD_THIS s.head[drive]<<2) | drive; // abnormal termination
|
||||
+ BX_FD_THIS s.result[0] = BX_FD_THIS s.status_reg0;
|
||||
BX_FD_THIS s.result[1] = 0x04; // 0000 0100
|
||||
BX_FD_THIS s.result[2] = 0x00; // 0000 0000
|
||||
BX_FD_THIS s.result[3] = BX_FD_THIS s.cylinder[drive];
|
||||
@@ -760,6 +762,7 @@
|
||||
BX_FD_THIS s.pending_command = 0;
|
||||
BX_FD_THIS s.main_status_reg = FD_MS_MRQ | FD_MS_DIO | FD_MS_BUSY;
|
||||
BX_FD_THIS devices->pic->trigger_irq(6);
|
||||
+ BX_FD_THIS s.pending_irq = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -771,7 +774,8 @@
|
||||
(unsigned) BX_FD_THIS s.media[drive].sectors_per_track));
|
||||
BX_FD_THIS s.result_size = 7;
|
||||
BX_FD_THIS s.result_index = 0;
|
||||
- BX_FD_THIS s.result[0] = 0x40 | (BX_FD_THIS s.head[drive]<<2) | drive; // abnormal termination
|
||||
+ BX_FD_THIS s.status_reg0 = 0x40 | (BX_FD_THIS s.head[drive]<<2) | drive; // abnormal termination
|
||||
+ BX_FD_THIS s.result[0] = BX_FD_THIS s.status_reg0;
|
||||
BX_FD_THIS s.result[1] = 0x25; // 0010 0101
|
||||
BX_FD_THIS s.result[2] = 0x31; // 0011 0001
|
||||
BX_FD_THIS s.result[3] = BX_FD_THIS s.cylinder[drive];
|
||||
@@ -782,6 +786,7 @@
|
||||
BX_FD_THIS s.pending_command = 0;
|
||||
BX_FD_THIS s.main_status_reg = FD_MS_MRQ | FD_MS_DIO | FD_MS_BUSY;
|
||||
BX_FD_THIS devices->pic->trigger_irq(6);
|
||||
+ BX_FD_THIS s.pending_irq = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -810,7 +815,8 @@
|
||||
|
||||
BX_FD_THIS s.result_index = 0;
|
||||
// 0100 0HDD abnormal termination
|
||||
- BX_FD_THIS s.result[0] = 0x40 | (BX_FD_THIS s.head[drive]<<2) | drive;
|
||||
+ BX_FD_THIS s.status_reg0 = 0x40 | (BX_FD_THIS s.head[drive]<<2) | drive;
|
||||
+ BX_FD_THIS s.result[0] = BX_FD_THIS s.status_reg0;
|
||||
// 1000 0101 end of cyl/NDAT/NID
|
||||
BX_FD_THIS s.result[1] = 0x86;
|
||||
// 0000 0000
|
||||
@@ -823,7 +829,7 @@
|
||||
bx_pc_system.activate_timer( BX_FD_THIS s.floppy_timer_index,
|
||||
bx_options.Ofloppy_command_delay->get (), 0 );
|
||||
/* data reg not ready, controller busy */
|
||||
- BX_FD_THIS s.main_status_reg = FD_MS_DIO | FD_MS_BUSY;
|
||||
+ BX_FD_THIS s.main_status_reg = FD_MS_BUSY;
|
||||
BX_FD_THIS s.pending_command = BX_FD_THIS s.command[0];
|
||||
return;
|
||||
}
|
||||
@@ -856,7 +862,7 @@
|
||||
bx_pc_system.set_DRQ(FLOPPY_DMA_CHAN, 1);
|
||||
|
||||
/* data reg not ready, controller busy */
|
||||
- BX_FD_THIS s.main_status_reg = FD_MS_MRQ | FD_MS_DIO | FD_MS_BUSY;
|
||||
+ BX_FD_THIS s.main_status_reg = FD_MS_BUSY;
|
||||
BX_FD_THIS s.pending_command = BX_FD_THIS s.command[0];
|
||||
return;
|
||||
}
|
||||
@@ -866,7 +872,7 @@
|
||||
bx_pc_system.set_DRQ(FLOPPY_DMA_CHAN, 1);
|
||||
|
||||
/* data reg not ready, controller busy */
|
||||
- BX_FD_THIS s.main_status_reg = FD_MS_MRQ | FD_MS_DIO | FD_MS_BUSY;
|
||||
+ BX_FD_THIS s.main_status_reg = FD_MS_BUSY;
|
||||
BX_FD_THIS s.pending_command = BX_FD_THIS s.command[0];
|
||||
return;
|
||||
}
|
||||
@@ -876,10 +882,13 @@
|
||||
return;
|
||||
break;
|
||||
|
||||
- default:
|
||||
- BX_PANIC(("floppy_command(): unknown function"));
|
||||
+ default: // invalid or unsupported command
|
||||
+ BX_FD_THIS s.result_size = 1;
|
||||
+ BX_FD_THIS s.result_index = 0;
|
||||
+ BX_FD_THIS s.result[0] = BX_FD_THIS s.status_reg0;
|
||||
+ BX_FD_THIS s.status_reg0 = 0;
|
||||
+ BX_FD_THIS s.main_status_reg = FD_MS_MRQ | FD_MS_DIO | FD_MS_BUSY;
|
||||
}
|
||||
- BX_PANIC(("floppy_command()"));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -949,9 +958,6 @@
|
||||
void
|
||||
bx_floppy_ctrl_c::timer_handler(void *this_ptr)
|
||||
{
|
||||
-#if defined(SIMX86)
|
||||
- printf("Floppy timer");
|
||||
-#endif
|
||||
|
||||
bx_floppy_ctrl_c *class_ptr = (bx_floppy_ctrl_c *) this_ptr;
|
||||
|
||||
@@ -961,38 +967,56 @@
|
||||
void
|
||||
bx_floppy_ctrl_c::timer()
|
||||
{
|
||||
+ Bit8u drive;
|
||||
+
|
||||
+ drive = BX_FD_THIS s.DOR & 0x03;
|
||||
switch ( BX_FD_THIS s.pending_command ) {
|
||||
case 0x07: // recal
|
||||
BX_FD_THIS s.pending_command = 0;
|
||||
/* write ready, not busy */
|
||||
- BX_FD_THIS s.main_status_reg = FD_MS_MRQ;
|
||||
+ BX_FD_THIS s.main_status_reg = FD_MS_MRQ | (1 << drive);
|
||||
+ BX_FD_THIS s.status_reg0 = 0x20 | drive;
|
||||
BX_FD_THIS devices->pic->trigger_irq(6);
|
||||
+ BX_FD_THIS s.pending_irq = 1;
|
||||
goto reset_changeline;
|
||||
break;
|
||||
|
||||
case 0x0f: // seek
|
||||
BX_FD_THIS s.pending_command = 0;
|
||||
/* write ready, not busy */
|
||||
- BX_FD_THIS s.main_status_reg = FD_MS_MRQ;
|
||||
+ BX_FD_THIS s.main_status_reg = FD_MS_MRQ | (1 << drive);
|
||||
+ BX_FD_THIS s.status_reg0 = 0x20 | drive;
|
||||
BX_FD_THIS devices->pic->trigger_irq(6);
|
||||
+ BX_FD_THIS s.pending_irq = 1;
|
||||
goto reset_changeline;
|
||||
break;
|
||||
|
||||
-
|
||||
case 0x4a: /* read ID */
|
||||
+ BX_FD_THIS s.pending_command = 0;
|
||||
+ /* read ready, busy */
|
||||
+ BX_FD_THIS s.main_status_reg = FD_MS_MRQ | FD_MS_DIO;
|
||||
+ BX_FD_THIS s.status_reg0 = 0x20 | drive;
|
||||
+ BX_FD_THIS s.result[0] = BX_FD_THIS s.status_reg0;
|
||||
+ BX_FD_THIS devices->pic->trigger_irq(6);
|
||||
+ BX_FD_THIS s.pending_irq = 1;
|
||||
+ break;
|
||||
+
|
||||
case 0xc5: // write normal data
|
||||
case 0xe6: // read normal data
|
||||
BX_FD_THIS s.pending_command = 0;
|
||||
/* read ready, busy */
|
||||
- BX_FD_THIS s.main_status_reg = FD_MS_MRQ | FD_MS_DIO;
|
||||
+ BX_FD_THIS s.main_status_reg = FD_MS_MRQ | FD_MS_DIO | (1 << drive);
|
||||
+ BX_FD_THIS s.status_reg0 = 0x20 | drive;
|
||||
BX_FD_THIS devices->pic->trigger_irq(6);
|
||||
+ BX_FD_THIS s.pending_irq = 1;
|
||||
break;
|
||||
|
||||
case 0xfe: // (contrived) RESET
|
||||
reset(BX_RESET_SOFTWARE);
|
||||
BX_FD_THIS s.pending_command = 0;
|
||||
- BX_FD_THIS s.main_status_reg = FD_MS_MRQ;
|
||||
+ BX_FD_THIS s.status_reg0 = 0xc0;
|
||||
BX_FD_THIS devices->pic->trigger_irq(6);
|
||||
+ BX_FD_THIS s.pending_irq = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -1002,7 +1026,6 @@
|
||||
return;
|
||||
|
||||
reset_changeline:
|
||||
- unsigned drive = BX_FD_THIS s.DOR & 0x3;
|
||||
if (drive > 1) return;
|
||||
if (BX_FD_THIS s.media_present[drive])
|
||||
BX_FD_THIS s.DIR &= ~0x80; // clear disk change line
|
||||
@@ -1026,10 +1049,11 @@
|
||||
BX_FD_THIS s.floppy_buffer_index = 0;
|
||||
if (bx_pc_system.TC) { // Terminal Count line, done
|
||||
BX_FD_THIS s.pending_command = 0;
|
||||
- BX_FD_THIS s.main_status_reg = FD_MS_MRQ | FD_MS_DIO | FD_MS_BUSY;
|
||||
+ BX_FD_THIS s.main_status_reg = FD_MS_MRQ | FD_MS_DIO | FD_MS_BUSY | (1 << drive);
|
||||
BX_FD_THIS s.result_size = 7;
|
||||
BX_FD_THIS s.result_index = 0;
|
||||
- BX_FD_THIS s.result[0] = (BX_FD_THIS s.head[drive] << 2) | drive;
|
||||
+ BX_FD_THIS s.status_reg0 = 0x20 | (BX_FD_THIS s.head[drive] << 2) | drive;
|
||||
+ BX_FD_THIS s.result[0] = BX_FD_THIS s.status_reg0;
|
||||
BX_FD_THIS s.result[1] = 0;
|
||||
BX_FD_THIS s.result[2] = 0;
|
||||
BX_FD_THIS s.result[3] = BX_FD_THIS s.cylinder[drive];
|
||||
@@ -1096,7 +1120,7 @@
|
||||
BX_FD_THIS s.result[6] = 2; // sector size = 512
|
||||
|
||||
BX_FD_THIS s.pending_command = 0;
|
||||
- BX_FD_THIS s.main_status_reg = FD_MS_MRQ | FD_MS_DIO | FD_MS_BUSY;
|
||||
+ BX_FD_THIS s.main_status_reg = FD_MS_MRQ | FD_MS_DIO | FD_MS_BUSY | (1 << drive);
|
||||
BX_FD_THIS devices->pic->trigger_irq(6);
|
||||
return;
|
||||
}
|
||||
@@ -1109,7 +1133,8 @@
|
||||
BX_FD_THIS s.main_status_reg = FD_MS_MRQ | FD_MS_DIO | FD_MS_BUSY;
|
||||
BX_FD_THIS s.result_size = 7;
|
||||
BX_FD_THIS s.result_index = 0;
|
||||
- BX_FD_THIS s.result[0] = (BX_FD_THIS s.head[drive] << 2) | drive;
|
||||
+ BX_FD_THIS s.status_reg0 = 0x20 | (BX_FD_THIS s.head[drive] << 2) | drive;
|
||||
+ BX_FD_THIS s.result[0] = BX_FD_THIS s.status_reg0;
|
||||
BX_FD_THIS s.result[1] = 0;
|
||||
BX_FD_THIS s.result[2] = 0;
|
||||
BX_FD_THIS s.result[3] = BX_FD_THIS s.cylinder[drive];
|
||||
@@ -1222,7 +1247,9 @@
|
||||
{
|
||||
struct stat stat_buf;
|
||||
int ret;
|
||||
+#if BX_WITH_WIN32
|
||||
char sTemp[1024];
|
||||
+#endif
|
||||
|
||||
if (type == BX_FLOPPY_NONE)
|
||||
return(0);
|
|
@ -1,286 +0,0 @@
|
|||
----------------------------------------------------------------------
|
||||
Patch name: patch.floppy-volker
|
||||
Author: Volker.Ruppert@t-online.de
|
||||
Date: Don Dez 28 17:29:00 CET 2001
|
||||
|
||||
Detailed description:
|
||||
|
||||
This patch contains the second set of changes to bochs floppy support.
|
||||
The changes are checked in, so you can use this file to revert them if
|
||||
they cause trouble.
|
||||
|
||||
* floppy command 'format track' implemented
|
||||
* read and write operations with MT=0 are working now
|
||||
(function 'increment_sector()' updated)
|
||||
* result code of floppy command 'get status' fixed
|
||||
* flag FS_MS_DIO is not set while the 'configure' floppy command is pending
|
||||
|
||||
Patch was created with:
|
||||
diff -u
|
||||
Apply patch to what version:
|
||||
cvs checked out on DATE
|
||||
Instructions:
|
||||
To patch, go to main bochs directory.
|
||||
Type "patch -p0 < THIS_PATCH_FILE".
|
||||
----------------------------------------------------------------------
|
||||
--- ../bochs/iodev/floppy.cc Thu Dec 27 10:30:31 2001
|
||||
+++ iodev/floppy.cc Fri Dec 28 17:06:26 2001
|
||||
@@ -462,9 +462,14 @@
|
||||
case 0x4a: /* read ID */
|
||||
BX_FD_THIS s.command_size = 2;
|
||||
break;
|
||||
+ case 0x4d: /* format track */
|
||||
+ BX_FD_THIS s.command_size = 6;
|
||||
+ break;
|
||||
+ case 0x45:
|
||||
case 0xc5: /* write normal data */
|
||||
BX_FD_THIS s.command_size = 9;
|
||||
break;
|
||||
+ case 0x66:
|
||||
case 0xe6: /* read normal data */
|
||||
BX_FD_THIS s.command_size = 9;
|
||||
break;
|
||||
@@ -577,8 +582,8 @@
|
||||
|
||||
case 0x04: // get status
|
||||
drive = (BX_FD_THIS s.command[1] & 0x03);
|
||||
- BX_FD_THIS s.result[0] =
|
||||
- BX_FD_THIS s.media[drive].write_protected ? 0x40 : 0x00;
|
||||
+ BX_FD_THIS s.result[0] = 0x28 | (BX_FD_THIS s.head[drive]<<2) | drive
|
||||
+ | (BX_FD_THIS s.media[drive].write_protected ? 0x40 : 0x00);
|
||||
BX_FD_THIS s.result_size = 1;
|
||||
BX_FD_THIS s.result_index = 0;
|
||||
BX_FD_THIS s.main_status_reg = FD_MS_MRQ | FD_MS_DIO | FD_MS_BUSY;
|
||||
@@ -678,7 +683,7 @@
|
||||
BX_FD_THIS s.result_size = 0;
|
||||
BX_FD_THIS s.result_index = 0;
|
||||
BX_FD_THIS s.pending_command = 0;
|
||||
- BX_FD_THIS s.main_status_reg = FD_MS_MRQ | FD_MS_DIO | FD_MS_BUSY;
|
||||
+ BX_FD_THIS s.main_status_reg = FD_MS_MRQ | FD_MS_BUSY;
|
||||
return;
|
||||
break;
|
||||
|
||||
@@ -712,9 +717,77 @@
|
||||
return;
|
||||
break;
|
||||
|
||||
+ case 0x4d: // format track
|
||||
+ drive = BX_FD_THIS s.command[1] & 0x03;
|
||||
+ BX_FD_THIS s.DOR &= 0xfc;
|
||||
+ BX_FD_THIS s.DOR |= drive;
|
||||
+
|
||||
+ motor_on = (BX_FD_THIS s.DOR>>(drive+4)) & 0x01;
|
||||
+ if (motor_on == 0)
|
||||
+ BX_PANIC(("floppy_command(): format track: motor not on"));
|
||||
+ BX_FD_THIS s.head[drive] = (BX_FD_THIS s.command[1] >> 2) & 0x01;
|
||||
+ sector_size = BX_FD_THIS s.command[2];
|
||||
+ BX_FD_THIS s.format_count = BX_FD_THIS s.command[3];
|
||||
+ BX_FD_THIS s.format_fillbyte = BX_FD_THIS s.command[5];
|
||||
+ if (drive > 1)
|
||||
+ BX_PANIC(("format track: bad drive #%d", drive));
|
||||
+
|
||||
+ if (sector_size != 0x02) { // 512 bytes
|
||||
+ BX_PANIC(("format track: sector_size not 512"));
|
||||
+ }
|
||||
+ if (BX_FD_THIS s.format_count != BX_FD_THIS s.media[drive].sectors_per_track) {
|
||||
+ BX_PANIC(("format track: wrong number of sectors/track"));
|
||||
+ }
|
||||
+ if ( BX_FD_THIS s.media_present[drive] == 0 ) {
|
||||
+ // media not in drive, return error
|
||||
+ BX_INFO(("attempt to format track with media not present"));
|
||||
+ BX_FD_THIS s.result_size = 7;
|
||||
+ BX_FD_THIS s.result_index = 0;
|
||||
+ BX_FD_THIS s.status_reg0 = 0x40 | (BX_FD_THIS s.head[drive]<<2) | drive; // abnormal termination
|
||||
+ BX_FD_THIS s.result[0] = BX_FD_THIS s.status_reg0;
|
||||
+ BX_FD_THIS s.result[1] = 0x25; // 0010 0101
|
||||
+ BX_FD_THIS s.result[2] = 0x31; // 0011 0001
|
||||
+ // 4 result bytes are unused
|
||||
+ BX_FD_THIS s.pending_command = 0;
|
||||
+ BX_FD_THIS s.main_status_reg = FD_MS_MRQ | FD_MS_DIO | FD_MS_BUSY;
|
||||
+ BX_FD_THIS devices->pic->trigger_irq(6);
|
||||
+ BX_FD_THIS s.pending_irq = 1;
|
||||
+ return;
|
||||
+ }
|
||||
+ if (BX_FD_THIS s.media[drive].write_protected) {
|
||||
+ // media write-protected, return error
|
||||
+ BX_INFO(("attempt to format track with media write-protected"));
|
||||
+ BX_FD_THIS s.result_size = 7;
|
||||
+ BX_FD_THIS s.result_index = 0;
|
||||
+ BX_FD_THIS s.status_reg0 = 0x40 | (BX_FD_THIS s.head[drive]<<2) | drive; // abnormal termination
|
||||
+ BX_FD_THIS s.result[0] = BX_FD_THIS s.status_reg0;
|
||||
+ BX_FD_THIS s.result[1] = 0x27; // 0010 0111
|
||||
+ BX_FD_THIS s.result[2] = 0x31; // 0011 0001
|
||||
+ // 4 result bytes are unused
|
||||
+ BX_FD_THIS s.pending_command = 0;
|
||||
+ BX_FD_THIS s.main_status_reg = FD_MS_MRQ | FD_MS_DIO | FD_MS_BUSY;
|
||||
+ BX_FD_THIS devices->pic->trigger_irq(6);
|
||||
+ BX_FD_THIS s.pending_irq = 1;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* 4 header bytes per sector are required */
|
||||
+ BX_FD_THIS s.format_count <<= 2;
|
||||
|
||||
- case 0xe6: // read normal data
|
||||
- case 0xc5: // write normal data
|
||||
+ bx_pc_system.set_DRQ(FLOPPY_DMA_CHAN, 1);
|
||||
+
|
||||
+ /* data reg not ready, controller busy */
|
||||
+ BX_FD_THIS s.main_status_reg = FD_MS_BUSY;
|
||||
+ BX_FD_THIS s.pending_command = 0x4d; /* format track pending */
|
||||
+ BX_DEBUG(("format track"));
|
||||
+ return;
|
||||
+ break;
|
||||
+
|
||||
+ case 0x66: // read normal data, MT=0
|
||||
+ case 0xe6: // read normal data, MT=1
|
||||
+ case 0x45: // write normal data, MT=0
|
||||
+ case 0xc5: // write normal data, MT=1
|
||||
+ BX_FD_THIS s.multi_track = (BX_FD_THIS s.command[0] >> 7);
|
||||
if ( (BX_FD_THIS s.DOR & 0x08) == 0 )
|
||||
BX_PANIC(("read/write command with DMA and int disabled"));
|
||||
drive = BX_FD_THIS s.command[1] & 0x03;
|
||||
@@ -744,7 +817,7 @@
|
||||
|
||||
// check that head number in command[1] bit two matches the head
|
||||
// reported in the head number field. Real floppy drives are
|
||||
- // picky about this, as reported in SF bug #439945, (Floppy drive
|
||||
+ // picky about this, as reported in SF bug #439945, (Floppy drive
|
||||
// read input error checking).
|
||||
if (head != (BX_FD_THIS s.command[1]>>2)&1) {
|
||||
BX_ERROR(("head number in command[1] doesn't match head field"));
|
||||
@@ -854,7 +927,7 @@
|
||||
BX_FD_THIS s.sector[drive] = sector;
|
||||
BX_FD_THIS s.head[drive] = head;
|
||||
|
||||
- if (BX_FD_THIS s.command[0] == 0xe6) { // read
|
||||
+ if ((BX_FD_THIS s.command[0] & 0x7f) == 0x66) { // read
|
||||
floppy_xfer(drive, logical_sector*512, BX_FD_THIS s.floppy_buffer,
|
||||
512, FROM_FLOPPY);
|
||||
BX_FD_THIS s.floppy_buffer_index = 0;
|
||||
@@ -866,7 +939,7 @@
|
||||
BX_FD_THIS s.pending_command = BX_FD_THIS s.command[0];
|
||||
return;
|
||||
}
|
||||
- else if (BX_FD_THIS s.command[0] == 0xc5) { // write
|
||||
+ else if ((BX_FD_THIS s.command[0] & 0x7f) == 0x45) { // write
|
||||
BX_FD_THIS s.floppy_buffer_index = 0;
|
||||
|
||||
bx_pc_system.set_DRQ(FLOPPY_DMA_CHAN, 1);
|
||||
@@ -1001,8 +1074,10 @@
|
||||
BX_FD_THIS s.pending_irq = 1;
|
||||
break;
|
||||
|
||||
- case 0xc5: // write normal data
|
||||
- case 0xe6: // read normal data
|
||||
+ case 0x66: // read normal data
|
||||
+ case 0xe6:
|
||||
+ case 0x45: // write normal data
|
||||
+ case 0xc5:
|
||||
BX_FD_THIS s.pending_command = 0;
|
||||
/* read ready, busy */
|
||||
BX_FD_THIS s.main_status_reg = FD_MS_MRQ | FD_MS_DIO | (1 << drive);
|
||||
@@ -1096,10 +1171,56 @@
|
||||
Bit8u drive;
|
||||
Bit32u logical_sector;
|
||||
|
||||
+ drive = BX_FD_THIS s.DOR & 0x03;
|
||||
+ if (BX_FD_THIS s.pending_command == 0x4d) { // format track in progress
|
||||
+ --BX_FD_THIS s.format_count;
|
||||
+ switch (3 - (BX_FD_THIS s.format_count & 0x03)) {
|
||||
+ case 0:
|
||||
+ BX_FD_THIS s.cylinder[drive] = *data_byte;
|
||||
+ break;
|
||||
+ case 1:
|
||||
+ if (*data_byte != BX_FD_THIS s.head[drive])
|
||||
+ BX_ERROR(("head number does not match head field"));
|
||||
+ break;
|
||||
+ case 2:
|
||||
+ BX_FD_THIS s.sector[drive] = *data_byte;
|
||||
+ break;
|
||||
+ case 3:
|
||||
+ if (*data_byte != 2) BX_ERROR(("sector size code not 2"));
|
||||
+ BX_DEBUG(("formatting cylinder %u head %u sector %u",
|
||||
+ BX_FD_THIS s.cylinder[drive], BX_FD_THIS s.head[drive],
|
||||
+ BX_FD_THIS s.sector[drive]));
|
||||
+ for (unsigned i = 0; i < 512; i++) {
|
||||
+ BX_FD_THIS s.floppy_buffer[i] = BX_FD_THIS s.format_fillbyte;
|
||||
+ }
|
||||
+ logical_sector = (BX_FD_THIS s.cylinder[drive] * 2 * BX_FD_THIS s.media[drive].sectors_per_track) +
|
||||
+ (BX_FD_THIS s.head[drive] * BX_FD_THIS s.media[drive].sectors_per_track) +
|
||||
+ (BX_FD_THIS s.sector[drive] - 1);
|
||||
+ floppy_xfer(drive, logical_sector*512, BX_FD_THIS s.floppy_buffer,
|
||||
+ 512, TO_FLOPPY);
|
||||
+ break;
|
||||
+ }
|
||||
+ if ((BX_FD_THIS s.format_count == 0) || (bx_pc_system.TC)) {
|
||||
+ BX_FD_THIS s.format_count = 0;
|
||||
+ BX_FD_THIS s.pending_command = 0;
|
||||
+ BX_FD_THIS s.main_status_reg = FD_MS_MRQ | FD_MS_DIO | FD_MS_BUSY | (1 << drive);
|
||||
+ BX_FD_THIS s.result_size = 7;
|
||||
+ BX_FD_THIS s.result_index = 0;
|
||||
+ BX_FD_THIS s.status_reg0 = (BX_FD_THIS s.head[drive] << 2) | drive;
|
||||
+ BX_FD_THIS s.result[0] = BX_FD_THIS s.status_reg0;
|
||||
+ BX_FD_THIS s.result[1] = BX_FD_THIS s.status_reg1;
|
||||
+ BX_FD_THIS s.result[2] = BX_FD_THIS s.status_reg2;
|
||||
+ // 4 result bytes are unused
|
||||
+ BX_FD_THIS devices->pic->trigger_irq(6);
|
||||
+ BX_FD_THIS s.pending_irq = 1;
|
||||
+ bx_pc_system.set_DRQ(FLOPPY_DMA_CHAN, 0);
|
||||
+ }
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
BX_FD_THIS s.floppy_buffer[BX_FD_THIS s.floppy_buffer_index++] = *data_byte;
|
||||
|
||||
if (BX_FD_THIS s.floppy_buffer_index >= 512) {
|
||||
- drive = BX_FD_THIS s.DOR & 0x03;
|
||||
logical_sector = (BX_FD_THIS s.cylinder[drive] * 2 * BX_FD_THIS s.media[drive].sectors_per_track) +
|
||||
(BX_FD_THIS s.head[drive] * BX_FD_THIS s.media[drive].sectors_per_track) +
|
||||
(BX_FD_THIS s.sector[drive] - 1);
|
||||
@@ -1171,17 +1292,22 @@
|
||||
// ??? calculation depends on base_count being multiple of 512
|
||||
BX_FD_THIS s.sector[drive] ++;
|
||||
if (BX_FD_THIS s.sector[drive] > BX_FD_THIS s.media[drive].sectors_per_track) {
|
||||
- BX_FD_THIS s.sector[drive] -= BX_FD_THIS s.media[drive].sectors_per_track;
|
||||
- BX_FD_THIS s.head[drive] ++;
|
||||
- if (BX_FD_THIS s.head[drive] > 1) {
|
||||
- BX_FD_THIS s.head[drive] = 0;
|
||||
- BX_FD_THIS s.cylinder[drive] ++;
|
||||
- if (BX_FD_THIS s.cylinder[drive] >= BX_FD_THIS s.media[drive].tracks) {
|
||||
- // Set to 1 past last possible cylinder value.
|
||||
- // I notice if I set it to tracks-1, prama linux won't boot.
|
||||
- BX_FD_THIS s.cylinder[drive] = BX_FD_THIS s.media[drive].tracks;
|
||||
- BX_INFO(("increment_sector: clamping cylinder to max"));
|
||||
+ BX_FD_THIS s.sector[drive] = 1;
|
||||
+ if (BX_FD_THIS s.multi_track) {
|
||||
+ BX_FD_THIS s.head[drive] ++;
|
||||
+ if (BX_FD_THIS s.head[drive] > 1) {
|
||||
+ BX_FD_THIS s.head[drive] = 0;
|
||||
+ BX_FD_THIS s.cylinder[drive] ++;
|
||||
}
|
||||
+ }
|
||||
+ else {
|
||||
+ BX_FD_THIS s.cylinder[drive] ++;
|
||||
+ }
|
||||
+ if (BX_FD_THIS s.cylinder[drive] >= BX_FD_THIS s.media[drive].tracks) {
|
||||
+ // Set to 1 past last possible cylinder value.
|
||||
+ // I notice if I set it to tracks-1, prama linux won't boot.
|
||||
+ BX_FD_THIS s.cylinder[drive] = BX_FD_THIS s.media[drive].tracks;
|
||||
+ BX_INFO(("increment_sector: clamping cylinder to max"));
|
||||
}
|
||||
}
|
||||
}
|
||||
--- ../bochs/iodev/floppy.h Thu Dec 27 10:28:53 2001
|
||||
+++ iodev/floppy.h Fri Dec 28 13:59:47 2001
|
||||
@@ -70,7 +70,10 @@
|
||||
Boolean command_complete;
|
||||
Bit8u pending_command;
|
||||
|
||||
+ Boolean multi_track;
|
||||
Boolean pending_irq;
|
||||
+ Bit8u format_count;
|
||||
+ Bit8u format_fillbyte;
|
||||
|
||||
Bit8u result[10];
|
||||
Bit8u result_index;
|
Loading…
Reference in New Issue