04d661f248
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?
266 lines
7.6 KiB
Plaintext
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) +
|