408 lines
13 KiB
Plaintext
408 lines
13 KiB
Plaintext
|
----------------------------------------------------------------------
|
||
|
Patch name: patch.tekram-dc280e-vlb-ide
|
||
|
Author: Christophe Bothamy
|
||
|
Date: October, 8st 2002
|
||
|
|
||
|
Detailed description:
|
||
|
This patch adds Tekram DC280E VLB-IDE support to Bochs.
|
||
|
This card has 2 ata channels, so this would be better
|
||
|
than the promise DC2300.
|
||
|
|
||
|
Driver name is DC280EU.ZIP. It should find it somewhere
|
||
|
on the net. Look on tekram site at:
|
||
|
http://www.tekram.com.tw/Storageftp/IDE/DC-2X0/DC-280X/DC-280E/Driver%26AP/
|
||
|
|
||
|
Datasheet can be found at :
|
||
|
http://www.ryston.cz/petr/vlb/vlbidechips.html
|
||
|
|
||
|
With this patch win95 uses native acesses on the first four
|
||
|
ATA/ATAPI devices.
|
||
|
|
||
|
Quite a few "IO read(1f0h) with drq == 0" errors appears in the log,
|
||
|
and seem to be related with the timing of the ATA devices.
|
||
|
|
||
|
Many thanks to Volker for fixing the interrupt bug! It was not
|
||
|
working before.
|
||
|
|
||
|
Patch was created with:
|
||
|
cvs diff -u
|
||
|
Apply patch to what version:
|
||
|
cvs checked out on October, 8st 2002
|
||
|
Instructions:
|
||
|
To patch, go to main bochs directory.
|
||
|
Type "patch -p0 < THIS_PATCH_FILE".
|
||
|
----------------------------------------------------------------------
|
||
|
===================================================================
|
||
|
RCS file: /cvsroot/bochs/bochs/config.h.in,v
|
||
|
retrieving revision 1.85
|
||
|
diff -u -r1.85 config.h.in
|
||
|
--- config.h.in 6 Oct 2002 14:16:13 -0000 1.85
|
||
|
+++ config.h.in 8 Oct 2002 14:53:44 -0000
|
||
|
@@ -611,6 +611,13 @@
|
||
|
// Promise VLBIDE DC2300 Support
|
||
|
#define BX_PDC20230C_VLBIDE_SUPPORT 0
|
||
|
|
||
|
+// Tekram VLBIDE DC280E Support
|
||
|
+#define BX_W83759A_VLBIDE_SUPPORT 0
|
||
|
+
|
||
|
+#if (BX_PDC20230C_VLBIDE_SUPPORT == 1 && BX_W83759A_VLBIDE_SUPPORT == 1)
|
||
|
+#error Promise DC2300 can not be used with Tekram DC280E
|
||
|
+#endif
|
||
|
+
|
||
|
// dynamic translation (future: not supported yet)
|
||
|
#define BX_DYNAMIC_TRANSLATION 0
|
||
|
#define BX_DYNAMIC_CPU_I386 0
|
||
|
Index: configure
|
||
|
===================================================================
|
||
|
RCS file: /cvsroot/bochs/bochs/configure,v
|
||
|
retrieving revision 1.148
|
||
|
diff -u -r1.148 configure
|
||
|
--- configure 6 Oct 2002 14:16:13 -0000 1.148
|
||
|
+++ configure 8 Oct 2002 14:53:46 -0000
|
||
|
@@ -855,6 +855,7 @@
|
||
|
--enable-ne2000 enable limited ne2000 support
|
||
|
--enable-pci enable limited i440FX PCI support
|
||
|
--enable-dc2300-vlb-ide enable Promise DC2300 VLB-IDE support
|
||
|
+ --enable-dc280e-vlb-ide enable Tekram DC280E VLB-IDE support
|
||
|
--enable-4meg-pages support 4Megabyte pages extensions
|
||
|
--enable-pae support Physical Address Extensions
|
||
|
--enable-guest2host-tlb support guest to host addr TLB for speed
|
||
|
@@ -9267,6 +9268,38 @@
|
||
|
echo "${ECHO_T}no" >&6
|
||
|
cat >>confdefs.h <<\_ACEOF
|
||
|
#define BX_PDC20230C_VLBIDE_SUPPORT 0
|
||
|
+_ACEOF
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+fi;
|
||
|
+
|
||
|
+echo "$as_me:$LINENO: checking for Tekram DC280E VLB-IDE support" >&5
|
||
|
+echo $ECHO_N "checking for Tekram DC280E VLB-IDE support... $ECHO_C" >&6
|
||
|
+# Check whether --enable-dc280e-vlb-ide or --disable-dc280e-vlb-ide was given.
|
||
|
+if test "${enable_dc280e_vlb_ide+set}" = set; then
|
||
|
+ enableval="$enable_dc280e_vlb_ide"
|
||
|
+ if test "$enableval" = yes; then
|
||
|
+ echo "$as_me:$LINENO: result: yes" >&5
|
||
|
+echo "${ECHO_T}yes" >&6
|
||
|
+ cat >>confdefs.h <<\_ACEOF
|
||
|
+#define BX_W83759A_VLBIDE_SUPPORT 1
|
||
|
+_ACEOF
|
||
|
+
|
||
|
+ else
|
||
|
+ echo "$as_me:$LINENO: result: no" >&5
|
||
|
+echo "${ECHO_T}no" >&6
|
||
|
+ cat >>confdefs.h <<\_ACEOF
|
||
|
+#define BX_W83759A_VLBIDE_SUPPORT 0
|
||
|
+_ACEOF
|
||
|
+
|
||
|
+ fi
|
||
|
+else
|
||
|
+
|
||
|
+ echo "$as_me:$LINENO: result: no" >&5
|
||
|
+echo "${ECHO_T}no" >&6
|
||
|
+ cat >>confdefs.h <<\_ACEOF
|
||
|
+#define BX_W83759A_VLBIDE_SUPPORT 0
|
||
|
_ACEOF
|
||
|
|
||
|
|
||
|
Index: configure.in
|
||
|
===================================================================
|
||
|
RCS file: /cvsroot/bochs/bochs/configure.in,v
|
||
|
retrieving revision 1.148
|
||
|
diff -u -r1.148 configure.in
|
||
|
--- configure.in 5 Oct 2002 12:07:51 -0000 1.148
|
||
|
+++ configure.in 8 Oct 2002 14:53:47 -0000
|
||
|
@@ -563,6 +563,22 @@
|
||
|
]
|
||
|
)
|
||
|
|
||
|
+AC_MSG_CHECKING(for Tekram DC280E VLB-IDE support)
|
||
|
+AC_ARG_ENABLE(dc280e-vlb-ide,
|
||
|
+ [ --enable-dc280e-vlb-ide enable Tekram DC280E VLB-IDE support],
|
||
|
+ [if test "$enableval" = yes; then
|
||
|
+ AC_MSG_RESULT(yes)
|
||
|
+ AC_DEFINE(BX_W83759A_VLBIDE_SUPPORT, 1)
|
||
|
+ else
|
||
|
+ AC_MSG_RESULT(no)
|
||
|
+ AC_DEFINE(BX_W83759A_VLBIDE_SUPPORT, 0)
|
||
|
+ fi],
|
||
|
+ [
|
||
|
+ AC_MSG_RESULT(no)
|
||
|
+ AC_DEFINE(BX_W83759A_VLBIDE_SUPPORT, 0)
|
||
|
+ ]
|
||
|
+ )
|
||
|
+
|
||
|
|
||
|
AC_MSG_CHECKING(for 4Meg pages support)
|
||
|
AC_ARG_ENABLE(4meg-pages,
|
||
|
Index: iodev/harddrv.cc
|
||
|
===================================================================
|
||
|
RCS file: /cvsroot/bochs/bochs/iodev/harddrv.cc,v
|
||
|
retrieving revision 1.80
|
||
|
diff -u -r1.80 harddrv.cc
|
||
|
--- iodev/harddrv.cc 6 Oct 2002 20:19:03 -0000 1.80
|
||
|
+++ iodev/harddrv.cc 8 Oct 2002 14:53:48 -0000
|
||
|
@@ -337,6 +337,38 @@
|
||
|
BX_HD_THIS pdc20230c.p1f4_value = 0;
|
||
|
#endif
|
||
|
|
||
|
+#if BX_W83759A_VLBIDE_SUPPORT
|
||
|
+
|
||
|
+ BX_HD_THIS devices->register_io_read_handler(this, w83759a_read_handler, BX_W83759A_IDIN, "W83759A");
|
||
|
+ BX_HD_THIS devices->register_io_write_handler(this, w83759a_write_handler, BX_W83759A_IDIN, "W83759A");
|
||
|
+ BX_HD_THIS devices->register_io_read_handler(this, w83759a_read_handler, BX_W83759A_INDEX, "W83759A");
|
||
|
+ BX_HD_THIS devices->register_io_write_handler(this, w83759a_write_handler, BX_W83759A_INDEX, "W83759A");
|
||
|
+ BX_HD_THIS devices->register_io_read_handler(this, w83759a_read_handler, BX_W83759A_DATA, "W83759A");
|
||
|
+ BX_HD_THIS devices->register_io_write_handler(this, w83759a_write_handler, BX_W83759A_DATA, "W83759A");
|
||
|
+ BX_HD_THIS devices->register_io_read_handler(this, w83759a_read_handler, BX_W83759A_IDOUT, "W83759A");
|
||
|
+ BX_HD_THIS devices->register_io_write_handler(this, w83759a_write_handler, BX_W83759A_IDOUT, "W83759A");
|
||
|
+
|
||
|
+ BX_HD_THIS w83759a.detected = false;
|
||
|
+ BX_HD_THIS w83759a.prog_mode = 0;
|
||
|
+ BX_HD_THIS w83759a.index = 0x80;
|
||
|
+ BX_HD_THIS w83759a.registers[0x0] = 0x8f;
|
||
|
+ BX_HD_THIS w83759a.registers[0x1] = 0x8f;
|
||
|
+ BX_HD_THIS w83759a.registers[0x2] = 0xff;
|
||
|
+ BX_HD_THIS w83759a.registers[0x3] = 0xff;
|
||
|
+ BX_HD_THIS w83759a.registers[0x4] = 0xff;
|
||
|
+ BX_HD_THIS w83759a.registers[0x5] = 0xff;
|
||
|
+ BX_HD_THIS w83759a.registers[0x6] = 0x80;
|
||
|
+ BX_HD_THIS w83759a.registers[0x7] = 0x8a;
|
||
|
+ BX_HD_THIS w83759a.registers[0x8] = 0x00;
|
||
|
+ BX_HD_THIS w83759a.registers[0x9] = 0x00;
|
||
|
+ BX_HD_THIS w83759a.registers[0xa] = 0x00;
|
||
|
+ BX_HD_THIS w83759a.registers[0xb] = 0x00;
|
||
|
+ BX_HD_THIS w83759a.registers[0xc] = 0x00;
|
||
|
+ BX_HD_THIS w83759a.registers[0xd] = 0x00;
|
||
|
+ BX_HD_THIS w83759a.registers[0xe] = 0x00;
|
||
|
+ BX_HD_THIS w83759a.registers[0xf] = 0x00;
|
||
|
+
|
||
|
+#endif
|
||
|
|
||
|
// generate CMOS values for hard drive if not using a CMOS image
|
||
|
if (!bx_options.cmos.OcmosImage->get ()) {
|
||
|
@@ -434,6 +466,31 @@
|
||
|
if (BX_HD_THIS channels[channel].irq)
|
||
|
BX_HD_THIS devices->pic->lower_irq(BX_HD_THIS channels[channel].irq);
|
||
|
}
|
||
|
+
|
||
|
+#if BX_W83759A_VLBIDE_SUPPORT
|
||
|
+
|
||
|
+ BX_HD_THIS w83759a.detected = false;
|
||
|
+ BX_HD_THIS w83759a.prog_mode = 0;
|
||
|
+ BX_HD_THIS w83759a.index = 0x80;
|
||
|
+ BX_HD_THIS w83759a.registers[0x0] = 0x8f;
|
||
|
+ BX_HD_THIS w83759a.registers[0x1] = 0x8f;
|
||
|
+ BX_HD_THIS w83759a.registers[0x2] = 0xff;
|
||
|
+ BX_HD_THIS w83759a.registers[0x3] = 0xff;
|
||
|
+ BX_HD_THIS w83759a.registers[0x4] = 0xff;
|
||
|
+ BX_HD_THIS w83759a.registers[0x5] = 0xff;
|
||
|
+ BX_HD_THIS w83759a.registers[0x6] = 0x80;
|
||
|
+ BX_HD_THIS w83759a.registers[0x7] = 0x8a;
|
||
|
+ BX_HD_THIS w83759a.registers[0x8] = 0x00;
|
||
|
+ BX_HD_THIS w83759a.registers[0x9] = 0x00;
|
||
|
+ BX_HD_THIS w83759a.registers[0xa] = 0x00;
|
||
|
+ BX_HD_THIS w83759a.registers[0xb] = 0x00;
|
||
|
+ BX_HD_THIS w83759a.registers[0xc] = 0x00;
|
||
|
+ BX_HD_THIS w83759a.registers[0xd] = 0x00;
|
||
|
+ BX_HD_THIS w83759a.registers[0xe] = 0x00;
|
||
|
+ BX_HD_THIS w83759a.registers[0xf] = 0x00;
|
||
|
+
|
||
|
+#endif
|
||
|
+
|
||
|
}
|
||
|
|
||
|
|
||
|
@@ -1956,6 +2013,7 @@
|
||
|
|
||
|
case 0xef: // SET FEATURES
|
||
|
switch(BX_SELECTED_CONTROLLER(channel).features) {
|
||
|
+ case 0x03: // Set transfer mode based on SC register. FIXME we should handle this
|
||
|
case 0x02: // Enable and
|
||
|
case 0x82: // Disable write cache.
|
||
|
case 0xAA: // Enable and
|
||
|
@@ -2282,6 +2340,118 @@
|
||
|
(unsigned) address, (unsigned) value));
|
||
|
}
|
||
|
}
|
||
|
+
|
||
|
+#if BX_W83759A_VLBIDE_SUPPORT
|
||
|
+
|
||
|
+ // static IO port read callback handler
|
||
|
+ // redirects to non-static class handler to avoid virtual functions
|
||
|
+
|
||
|
+ Bit32u
|
||
|
+bx_hard_drive_c::w83759a_read_handler(void *this_ptr, Bit32u address, unsigned io_len)
|
||
|
+{
|
||
|
+#if !BX_USE_HD_SMF
|
||
|
+ bx_hard_drive_c *class_ptr = (bx_hard_drive_c *) this_ptr;
|
||
|
+
|
||
|
+ return( class_ptr->w83759a_read(address, io_len) );
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+ Bit32u
|
||
|
+bx_hard_drive_c::w83759a_read(Bit32u address, unsigned io_len)
|
||
|
+{
|
||
|
+#else
|
||
|
+ UNUSED(this_ptr);
|
||
|
+#endif // !BX_USE_HD_SMF
|
||
|
+
|
||
|
+ Bit8u value8 = 0xff;
|
||
|
+
|
||
|
+ if (!BX_HD_THIS w83759a.detected) {
|
||
|
+ BX_HD_THIS w83759a.detected = true;
|
||
|
+ BX_INFO(("Tekram VLB-IDE DC280E accessed"));
|
||
|
+ }
|
||
|
+
|
||
|
+ BX_DEBUG(("W83759A VLBIDE: read access port %04x, iolen=%x", address, io_len));
|
||
|
+
|
||
|
+ switch(address) {
|
||
|
+ case BX_W83759A_IDIN:
|
||
|
+ BX_INFO(("W83759A VLBIDE: read from IDIN !"));
|
||
|
+ break;
|
||
|
+ case BX_W83759A_INDEX:
|
||
|
+ value8 = BX_HD_THIS w83759a.index;
|
||
|
+ BX_DEBUG(("W83759A VLBIDE: read from INDEX returning %02x",value8));
|
||
|
+ break;
|
||
|
+ case BX_W83759A_DATA:
|
||
|
+ if ((BX_HD_THIS w83759a.index < 0x80) || (BX_HD_THIS w83759a.index > 0x8f)) value8 = 0xff;
|
||
|
+ else value8 = BX_HD_THIS w83759a.registers[BX_HD_THIS w83759a.index&0xf];
|
||
|
+ BX_DEBUG(("W83759A VLBIDE: read from DATA returning reg %02x %02x",BX_HD_THIS w83759a.index,value8));
|
||
|
+ break;
|
||
|
+ case BX_W83759A_IDOUT:
|
||
|
+ value8 = BX_W83759A_ID;
|
||
|
+ BX_DEBUG(("W83759A VLBIDE: read from IDOUT returning %02x",value8));
|
||
|
+ break;
|
||
|
+ }
|
||
|
+
|
||
|
+ return value8;
|
||
|
+}
|
||
|
+
|
||
|
+ // static IO port write callback handler
|
||
|
+ // redirects to non-static class handler to avoid virtual functions
|
||
|
+
|
||
|
+ void
|
||
|
+bx_hard_drive_c::w83759a_write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len)
|
||
|
+{
|
||
|
+#if !BX_USE_HD_SMF
|
||
|
+ bx_hard_drive_c *class_ptr = (bx_hard_drive_c *) this_ptr;
|
||
|
+
|
||
|
+ class_ptr->w83759a_write(address, value, io_len);
|
||
|
+}
|
||
|
+
|
||
|
+ void
|
||
|
+bx_hard_drive_c::w83759a_write(Bit32u address, Bit32u value, unsigned io_len)
|
||
|
+{
|
||
|
+#else
|
||
|
+ UNUSED(this_ptr);
|
||
|
+#endif // !BX_USE_HD_SMF
|
||
|
+
|
||
|
+ BX_DEBUG(("W83759A VLBIDE: write access port %04x, iolen=%x", address, io_len));
|
||
|
+
|
||
|
+ switch(address) {
|
||
|
+ case BX_W83759A_IDIN:
|
||
|
+ BX_DEBUG(("W83759A VLBIDE: write to IDIN value %x",value));
|
||
|
+ if (value == BX_W83759A_ID) {
|
||
|
+ BX_DEBUG(("W83759A VLBIDE: Entering programming sequence"));
|
||
|
+ BX_HD_THIS w83759a.prog_mode = 1;
|
||
|
+ }
|
||
|
+ else {
|
||
|
+ BX_DEBUG(("W83759A VLBIDE: Leaving programming sequence"));
|
||
|
+ BX_HD_THIS w83759a.prog_mode = 0;
|
||
|
+ }
|
||
|
+ break;
|
||
|
+ case BX_W83759A_INDEX:
|
||
|
+ BX_DEBUG(("W83759A VLBIDE: write to INDEX value %x",value));
|
||
|
+ BX_HD_THIS w83759a.index = value;
|
||
|
+ break;
|
||
|
+ case BX_W83759A_DATA:
|
||
|
+ BX_DEBUG(("W83759A VLBIDE: write to DATA reg %02x value %x",BX_HD_THIS w83759a.index,value));
|
||
|
+ switch (BX_HD_THIS w83759a.index&0x0f) {
|
||
|
+ case 0:
|
||
|
+ case 2:
|
||
|
+ case 4:
|
||
|
+ case 7:
|
||
|
+ BX_DEBUG(("W83759A VLBIDE: reg %02x is read only",BX_HD_THIS w83759a.index));
|
||
|
+ break;
|
||
|
+ default:
|
||
|
+ BX_HD_THIS w83759a.registers[BX_HD_THIS w83759a.index&0x0f] = value;
|
||
|
+ BX_DEBUG(("W83759A VLBIDE: reg %02x written",BX_HD_THIS w83759a.index));
|
||
|
+ }
|
||
|
+ break;
|
||
|
+ case BX_W83759A_IDOUT:
|
||
|
+ BX_DEBUG(("W83759A VLBIDE: write to IDOUT discarded"));
|
||
|
+ break;
|
||
|
+ }
|
||
|
+
|
||
|
+}
|
||
|
+#endif
|
||
|
|
||
|
void
|
||
|
bx_hard_drive_c::close_harddrive(void)
|
||
|
Index: iodev/harddrv.h
|
||
|
===================================================================
|
||
|
RCS file: /cvsroot/bochs/bochs/iodev/harddrv.h,v
|
||
|
retrieving revision 1.16
|
||
|
diff -u -r1.16 harddrv.h
|
||
|
--- iodev/harddrv.h 30 Sep 2002 14:19:46 -0000 1.16
|
||
|
+++ iodev/harddrv.h 8 Oct 2002 14:53:48 -0000
|
||
|
@@ -305,6 +305,19 @@
|
||
|
static Bit32u read_handler(void *this_ptr, Bit32u address, unsigned io_len);
|
||
|
static void write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len);
|
||
|
|
||
|
+
|
||
|
+#if BX_W83759A_VLBIDE_SUPPORT
|
||
|
+
|
||
|
+#if !BX_USE_HD_SMF
|
||
|
+ Bit32u w83759a_read(Bit32u address, unsigned io_len);
|
||
|
+ void w83759a_write(Bit32u address, Bit32u value, unsigned io_len);
|
||
|
+#endif
|
||
|
+
|
||
|
+ static Bit32u w83759a_read_handler(void *this_ptr, Bit32u address, unsigned io_len);
|
||
|
+ static void w83759a_write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len);
|
||
|
+
|
||
|
+#endif
|
||
|
+
|
||
|
private:
|
||
|
|
||
|
BX_HD_SMF Boolean calculate_logical_address(Bit8u channel, off_t *sector);
|
||
|
@@ -356,6 +369,36 @@
|
||
|
Bit32u p1f3_value;
|
||
|
Bit32u p1f4_value;
|
||
|
} pdc20230c;
|
||
|
+#endif
|
||
|
+
|
||
|
+#if BX_W83759A_VLBIDE_SUPPORT
|
||
|
+
|
||
|
+// From specs, configuration registers can be at 0x1bX or 0x13X
|
||
|
+// Specs p11 are totally wrong. I guess registers can be :
|
||
|
+// Y0BX with Y in 1 5 9 D and X in 0 4 8 C
|
||
|
+// or Y03X with Y in 1 5 9 D and X in 0 4 8 C
|
||
|
+#define BX_W83759A_IDIN 0x10b0
|
||
|
+#define BX_W83759A_INDEX 0x10b4
|
||
|
+#define BX_W83759A_DATA 0x10b8
|
||
|
+#define BX_W83759A_IDOUT 0x10bc
|
||
|
+
|
||
|
+#if 0
|
||
|
+#define BX_W83759A_IDIN 0x1030
|
||
|
+#define BX_W83759A_INDEX 0x1034
|
||
|
+#define BX_W83759A_DATA 0x1038
|
||
|
+#define BX_W83759A_IDOUT 0x103c
|
||
|
+#endif
|
||
|
+
|
||
|
+#define BX_W83759A_ID 0x00
|
||
|
+
|
||
|
+// Only one w83759A chip can be present.
|
||
|
+// Well there is a multichip mode, but all on same io port
|
||
|
+ struct w83759a_t {
|
||
|
+ Boolean prog_mode;
|
||
|
+ Bit8u index;
|
||
|
+ Bit8u registers[0x10];
|
||
|
+ Boolean detected;
|
||
|
+ } w83759a;
|
||
|
#endif
|
||
|
|
||
|
bx_devices_c *devices;
|