- apply patch from patches/patch.lba. This is taken from plex86 cvs

and modified for bochs.  Minimal testing so far...
This commit is contained in:
Bryce Denney 2001-09-19 15:30:44 +00:00
parent 367cf8f490
commit 3bba2f657f
3 changed files with 100 additions and 27 deletions

Binary file not shown.

View File

@ -267,7 +267,7 @@ static void keyboard_panic();
static void boot_failure_msg(); static void boot_failure_msg();
static void nmi_handler_msg(); static void nmi_handler_msg();
static void print_bios_banner(); static void print_bios_banner();
static char bios_version_string[] = "BIOS Version is $Id: rombios.c,v 1.15 2001-08-15 04:56:00 bdenney Exp $"; static char bios_version_string[] = "BIOS Version is $Id: rombios.c,v 1.16 2001-09-19 15:30:44 bdenney Exp $";
#define DEBUG_ROMBIOS 0 #define DEBUG_ROMBIOS 0
@ -1350,6 +1350,7 @@ int16_function(DI, SI, BP, SP, BX, DX, CX, AX, FLAGS)
{ {
Bit8u scan_code, ascii_code, shift_flags; Bit8u scan_code, ascii_code, shift_flags;
switch (GET_AH()) { switch (GET_AH()) {
case 0x00: /* read keyboard input */ case 0x00: /* read keyboard input */
@ -1519,6 +1520,7 @@ int09_function(DI, SI, BP, SP, BX, DX, CX, AX)
// DS has been set to F000 before call // DS has been set to F000 before call
// //
scancode = GET_AL(); scancode = GET_AL();
if (scancode == 0) { if (scancode == 0) {
@ -1707,6 +1709,56 @@ printf("int74_function: make_farcall=1\n");
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 void
@ -1723,6 +1775,7 @@ int13_function(DI, SI, BP, SP, BX, DX, CX, AX, ES, FLAGS)
Bit8u sector_count; Bit8u sector_count;
unsigned int i; unsigned int i;
Bit16u tempbx; Bit16u tempbx;
Bit16u lba;
write_byte(0x0040, 0x008e, 0); // clear completion flag write_byte(0x0040, 0x008e, 0); // clear completion flag
@ -1810,10 +1863,6 @@ printf("int13_f01\n");
if ( (num_sectors > 128) || (num_sectors == 0) ) if ( (num_sectors > 128) || (num_sectors == 0) )
panic("int13_function(): num_sectors out of range!"); panic("int13_function(): num_sectors out of range!");
if (head > 15)
panic("hard drive BIOS:(read/verify) head > 15");
if ( GET_AH() == 0x04 ) { if ( GET_AH() == 0x04 ) {
SET_AH(0); SET_AH(0);
set_disk_ret_status(0); set_disk_ret_status(0);
@ -1826,10 +1875,17 @@ printf("int13_f01\n");
panic("hard drive BIOS:(read/verify) BUSY bit set"); panic("hard drive BIOS:(read/verify) BUSY bit set");
} }
outb(0x01f2, num_sectors); outb(0x01f2, num_sectors);
outb(0x01f3, sector); /* activate LBA? (tomv) */
outb(0x01f4, cylinder & 0x00ff); if (hd_heads > 15) {
outb(0x01f5, cylinder >> 8); printf("CHS: %x %x %x\n", cylinder, head, sector);
outb(0x01f6, 0xa0 | ((drive&1)<<4) | (head & 0x0f)); 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); outb(0x01f7, 0x20);
while (1) { while (1) {
@ -1948,19 +2004,24 @@ printf("int13_f03\n");
if ( (num_sectors > 128) || (num_sectors == 0) ) if ( (num_sectors > 128) || (num_sectors == 0) )
panic("int13_function(): num_sectors out of range!"); panic("int13_function(): num_sectors out of range!");
if (head > 15)
panic("hard drive BIOS:(read) head > 15");
status = inb(0x1f7); status = inb(0x1f7);
if (status & 0x80) { if (status & 0x80) {
panic("hard drive BIOS:(read) BUSY bit set"); panic("hard drive BIOS:(read) BUSY bit set");
} }
// should check for Drive Ready Bit also in status reg // should check for Drive Ready Bit also in status reg
outb(0x01f2, num_sectors); outb(0x01f2, num_sectors);
outb(0x01f3, sector);
outb(0x01f4, cylinder & 0x00ff); /* activate LBA? (tomv) */
outb(0x01f5, cylinder >> 8); if (hd_heads > 15) {
outb(0x01f6, 0xa0 | ((drive&1)<<4) | (head & 0x0f)); 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); outb(0x01f7, 0x30);
// wait for busy bit to turn off after seeking // wait for busy bit to turn off after seeking
@ -4386,7 +4447,7 @@ int16_key_found:
;------------------------------------------------- ;-------------------------------------------------
;- INT09h : Keyboard Harware Service Entry Point - ;- INT09h : Keyboard Hardware Service Entry Point -
;------------------------------------------------- ;-------------------------------------------------
.org 0xe987 .org 0xe987
int09_handler: int09_handler:

View File

@ -95,7 +95,7 @@ bx_hard_drive_c::~bx_hard_drive_c(void)
bx_hard_drive_c::init(bx_devices_c *d, bx_cmos_c *cmos) bx_hard_drive_c::init(bx_devices_c *d, bx_cmos_c *cmos)
{ {
BX_HD_THIS devices = d; BX_HD_THIS devices = d;
BX_DEBUG(("Init $Id: harddrv.cc,v 1.31 2001-09-19 15:10:38 bdenney Exp $")); BX_DEBUG(("Init $Id: harddrv.cc,v 1.32 2001-09-19 15:30:44 bdenney Exp $"));
/* HARD DRIVE 0 */ /* HARD DRIVE 0 */
@ -568,13 +568,21 @@ bx_hard_drive_c::read(Bit32u address, unsigned io_len)
goto return_value8; goto return_value8;
case 0x1f6: // hard disk drive and head register case 0x1f6: // hard disk drive and head register
value8 = (1 << 7) | // extended data field for ECC // b7 Extended data field for ECC
(0 << 7) | // 1=LBA mode, 0=CHSmode // 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 (1 << 5) | // 01b = 512 sector size
(BX_HD_THIS drive_select << 4) | (BX_HD_THIS drive_select << 4) |
(BX_SELECTED_CONTROLLER.head_no << 0); (BX_SELECTED_CONTROLLER.head_no << 0);
goto return_value8; goto return_value8;
break; break;
//BX_CONTROLLER(0).lba_mode
case 0x1f7: // Hard Disk Status case 0x1f7: // Hard Disk Status
case 0x3f6: // Hard Disk Alternate Status case 0x3f6: // Hard Disk Alternate Status
@ -1268,13 +1276,15 @@ BX_DEBUG(("IO write to %04x = %02x", (unsigned) address, (unsigned) value));
break; break;
case 0x1f6: // hard disk drive and head register case 0x1f6: // hard disk drive and head register
// b7 1 // b7 Extended data field for ECC
// b6 1=LBA mode, 0=CHS mode (LBA not supported) // b6/b5: Used to be sector size. 00=256,01=512,10=1024,11=128
// b5 1 // Since 512 was always used, bit 6 was taken to mean LBA mode:
// b6 1=LBA mode, 0=CHS mode
// b5 1
// b4: DRV // b4: DRV
// b3..0 HD3..HD0 // b3..0 HD3..HD0
if ( (value & 0xe0) != 0xa0 ) // 101xxxxx if ( (value & 0xa0) != 0xa0 ) // 1x1xxxxx
BX_INFO(("IO write 1f6 (%02x): not 101xxxxxb", (unsigned) value)); BX_INFO(("IO write 1f6 (%02x): not 1x1xxxxxb", (unsigned) value));
BX_HD_THIS drive_select = (value >> 4) & 0x01; BX_HD_THIS drive_select = (value >> 4) & 0x01;
WRITE_HEAD_NO(value & 0xf); WRITE_HEAD_NO(value & 0xf);
if (BX_SELECTED_CONTROLLER.lba_mode == 0 && ((value >> 6) & 1) == 1) if (BX_SELECTED_CONTROLLER.lba_mode == 0 && ((value >> 6) & 1) == 1)
@ -1730,11 +1740,13 @@ bx_hard_drive_c::calculate_logical_address()
{ {
Bit32u logical_sector; 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 | logical_sector = ((Bit32u)BX_SELECTED_CONTROLLER.head_no) << 24 |
((Bit32u)BX_SELECTED_CONTROLLER.cylinder_no) << 8 | ((Bit32u)BX_SELECTED_CONTROLLER.cylinder_no) << 8 |
(Bit32u)BX_SELECTED_CONTROLLER.sector_no; (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 * logical_sector = (BX_SELECTED_CONTROLLER.cylinder_no * BX_SELECTED_HD.hard_drive->heads *
BX_SELECTED_HD.hard_drive->sectors) + BX_SELECTED_HD.hard_drive->sectors) +
(BX_SELECTED_CONTROLLER.head_no * BX_SELECTED_HD.hard_drive->sectors) + (BX_SELECTED_CONTROLLER.head_no * BX_SELECTED_HD.hard_drive->sectors) +