Bochs/bochs/patches/patch.lba
Bryce Denney 04d661f248 - I grabbed this patch from plex86. It appears to make bochs disks
support LBA.  This builds okay, but I want to find a way to actually see that
  it's making some difference before committing it.  Anyway have an OS or
  diagnostic program that tests if LBA is in use?  What would LBA allow me to
  do that I can't do without it, so that a test can be done?
2001-05-17 21:38:33 +00:00

266 lines
7.6 KiB
Plaintext

----------------------------------------------------------------------
Patch name: patch.lba
Author: Bryce grabbed this from plex86
Date: Thu May 17 17:36:31 EDT 2001
Detailed description:
Add LBA support.
This builds okay, but I want to find a way to actually see that it's
making some difference before committing it. Anyway have an OS or
diagnostic program that tests if LBA is in use? What would LBA allow
me to do that I can't do without it?
Apply patch to:
current cvs sources
Instructions:
To patch, go to main bochs directory.
Type "patch -p0 < THIS_PATCH_FILE".
----------------------------------------------------------------------
Index: bios/rombios.c
===================================================================
RCS file: /cvsroot/bochs/bochs/bios/rombios.c,v
retrieving revision 1.3
diff -u -r1.3 rombios.c
--- bios/rombios.c 2001/05/03 21:13:20 1.3
+++ bios/rombios.c 2001/05/17 18:09:55
@@ -244,7 +244,7 @@
static void debugger_off();
static void keyboard_panic();
-#define DEBUG_ROMBIOS 0
+#define DEBUG_ROMBIOS 1
#if DEBUG_ROMBIOS
# define printf(format, p...) bios_printf(0, format, ##p)
@@ -767,7 +767,7 @@
Boolean oldval;
Bit8u temp8;
- // Use keyboard conroller to set A20 enable
+ // Use keyboard controller to set A20 enable
// get current Output Port settings first
if ( (inb(0x64) & 0x02) != 0 )
@@ -1281,6 +1281,7 @@
{
Bit8u scan_code, ascii_code, shift_flags;
+
switch (GET_AH()) {
case 0x00: /* read keyboard input */
@@ -1450,6 +1451,7 @@
// DS has been set to F000 before call
//
+
scancode = GET_AL();
if (scancode == 0) {
@@ -1638,6 +1640,56 @@
+ void
+outLBA(cylinder,hd_heads,head,hd_sectors,sector,dl)
+ Bit16u cylinder;
+ Bit16u hd_heads;
+ Bit16u head;
+ Bit16u hd_sectors;
+ Bit16u sector;
+ Bit16u dl;
+{
+#asm
+ push bp
+ mov bp, sp
+ push eax
+ push ebx
+ push edx
+ xor eax,eax
+ mov ax,4[bp]
+ xor ebx,ebx
+ mov bl,6[bp]
+ imul ebx
+ add al,8[bp]
+ adc ah,#0
+ mov bl,10[bp]
+ imul ebx
+ add al,12[bp]
+ adc ah,#0
+ dec eax
+ mov dx,#0x1f3
+ out dx,al
+ mov dx,#0x1f4
+ mov al,ah
+ out dx,al
+ shr eax,#16
+ mov dx,#0x1f5
+ out dx,al
+ and ah,#0xf
+ mov bl,14[bp]
+ and bl,#1
+ shl bl,#4
+ or ah,bl
+ or ah,#0xe0
+ mov al,ah
+ mov dx,#0x01f6
+ out dx,al
+ pop edx
+ pop ebx
+ pop eax
+ pop bp
+#endasm
+}
void
@@ -1654,6 +1706,7 @@
Bit8u sector_count;
unsigned int i;
Bit16u tempbx;
+ Bit16u lba;
write_byte(0x0040, 0x008e, 0); // clear completion flag
@@ -1742,9 +1795,6 @@
panic("int13_function(): num_sectors out of range!\n");
- if (head > 15)
- panic("hard drive BIOS:(read/verify) head > 15\n");
-
if ( GET_AH() == 0x04 ) {
SET_AH(0);
set_disk_ret_status(0);
@@ -1757,10 +1807,17 @@
panic("hard drive BIOS:(read/verify) BUSY bit set\n");
}
outb(0x01f2, num_sectors);
- outb(0x01f3, sector);
- outb(0x01f4, cylinder & 0x00ff);
- outb(0x01f5, cylinder >> 8);
- outb(0x01f6, 0xa0 | ((drive&1)<<4) | (head & 0x0f));
+ /* activate LBA? (tomv) */
+ if (hd_heads > 15) {
+printf("CHS: %x %x %x\n", cylinder, head, sector);
+ outLBA(cylinder,hd_heads,head,hd_sectors,sector,drive);
+ }
+ else {
+ outb(0x01f3, sector);
+ outb(0x01f4, cylinder & 0x00ff);
+ outb(0x01f5, cylinder >> 8);
+ outb(0x01f6, 0xa0 | ((drive & 0x01)<<4) | (head & 0x0f));
+ }
outb(0x01f7, 0x20);
while (1) {
@@ -1879,19 +1936,24 @@
if ( (num_sectors > 128) || (num_sectors == 0) )
panic("int13_function(): num_sectors out of range!\n");
- if (head > 15)
- panic("hard drive BIOS:(read) head > 15\n");
-
status = inb(0x1f7);
if (status & 0x80) {
panic("hard drive BIOS:(read) BUSY bit set\n");
}
// should check for Drive Ready Bit also in status reg
outb(0x01f2, num_sectors);
- outb(0x01f3, sector);
- outb(0x01f4, cylinder & 0x00ff);
- outb(0x01f5, cylinder >> 8);
- outb(0x01f6, 0xa0 | ((drive&1)<<4) | (head & 0x0f));
+
+ /* activate LBA? (tomv) */
+ if (hd_heads > 15) {
+printf("CHS (write): %x %x %x\n", cylinder, head, sector);
+ outLBA(cylinder,hd_heads,head,hd_sectors,sector,GET_DL());
+ }
+ else {
+ outb(0x01f3, sector);
+ outb(0x01f4, cylinder & 0x00ff);
+ outb(0x01f5, cylinder >> 8);
+ outb(0x01f6, 0xa0 | ((GET_DL() & 0x01)<<4) | (head & 0x0f));
+ }
outb(0x01f7, 0x30);
// wait for busy bit to turn off after seeking
@@ -4242,7 +4304,7 @@
;-------------------------------------------------
-;- INT09h : Keyboard Harware Service Entry Point -
+;- INT09h : Keyboard Hardware Service Entry Point -
;-------------------------------------------------
.org 0xe987
int09_handler:
Index: iodev/harddrv.cc
===================================================================
RCS file: /cvsroot/bochs/bochs/iodev/harddrv.cc,v
retrieving revision 1.10
diff -u -r1.10 harddrv.cc
--- iodev/harddrv.cc 2001/05/15 14:49:56 1.10
+++ iodev/harddrv.cc 2001/05/17 18:09:58
@@ -566,13 +566,21 @@
goto return_value8;
case 0x1f6: // hard disk drive and head register
- value8 = (1 << 7) | // extended data field for ECC
- (0 << 7) | // 1=LBA mode, 0=CHSmode
+ // b7 Extended data field for ECC
+ // b6/b5: Used to be sector size. 00=256,01=512,10=1024,11=128
+ // Since 512 was always used, bit 6 was taken to mean LBA mode:
+ // b6 1=LBA mode, 0=CHS mode
+ // b5 1
+ // b4: DRV
+ // b3..0 HD3..HD0
+ value8 = (1 << 7) |
+ ((BX_SELECTED_CONTROLLER.lba_mode>0) << 6) |
(1 << 5) | // 01b = 512 sector size
(BX_HD_THIS drive_select << 4) |
(BX_SELECTED_CONTROLLER.head_no << 0);
goto return_value8;
break;
+//BX_CONTROLLER(0).lba_mode
case 0x1f7: // Hard Disk Status
case 0x3f6: // Hard Disk Alternate Status
@@ -1263,13 +1271,15 @@
break;
case 0x1f6: // hard disk drive and head register
- // b7 1
- // b6 1=LBA mode, 0=CHS mode (LBA not supported)
- // b5 1
+ // b7 Extended data field for ECC
+ // b6/b5: Used to be sector size. 00=256,01=512,10=1024,11=128
+ // Since 512 was always used, bit 6 was taken to mean LBA mode:
+ // b6 1=LBA mode, 0=CHS mode
+ // b5 1
// b4: DRV
// b3..0 HD3..HD0
- if ( (value & 0xe0) != 0xa0 ) // 101xxxxx
- BX_INFO(("disk: IO write 1f6 (%02x): not 101xxxxxb\n", (unsigned) value));
+ if ( (value & 0xa0) != 0xa0 ) // 1x1xxxxx
+ BX_INFO(("disk: IO write 1f6 (%02x): not 1x1xxxxxb\n", (unsigned) value));
BX_HD_THIS drive_select = (value >> 4) & 0x01;
WRITE_HEAD_NO(value & 0xf);
if (BX_SELECTED_CONTROLLER.lba_mode == 0 && ((value >> 6) & 1) == 1)
@@ -1720,11 +1730,13 @@
{
Bit32u logical_sector;
- if (BX_SELECTED_CONTROLLER.lba_mode)
+ if (BX_SELECTED_CONTROLLER.lba_mode) {
+ //bx_printf ("disk: calculate: %d %d %d\n", ((Bit32u)BX_SELECTED_CONTROLLER.head_no), ((Bit32u)BX_SELECTED_CONTROLLER.cylinder_no), (Bit32u)BX_SELECTED_CONTROLLER.sector_no);
logical_sector = ((Bit32u)BX_SELECTED_CONTROLLER.head_no) << 24 |
((Bit32u)BX_SELECTED_CONTROLLER.cylinder_no) << 8 |
(Bit32u)BX_SELECTED_CONTROLLER.sector_no;
- else
+ //bx_printf ("disk: result: %u\n", logical_sector);
+ } else
logical_sector = (BX_SELECTED_CONTROLLER.cylinder_no * BX_SELECTED_HD.hard_drive->heads *
BX_SELECTED_HD.hard_drive->sectors) +
(BX_SELECTED_CONTROLLER.head_no * BX_SELECTED_HD.hard_drive->sectors) +