- 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:
parent
367cf8f490
commit
3bba2f657f
Binary file not shown.
@ -267,7 +267,7 @@ static void keyboard_panic();
|
||||
static void boot_failure_msg();
|
||||
static void nmi_handler_msg();
|
||||
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
|
||||
|
||||
@ -1350,6 +1350,7 @@ int16_function(DI, SI, BP, SP, BX, DX, CX, AX, FLAGS)
|
||||
{
|
||||
Bit8u scan_code, ascii_code, shift_flags;
|
||||
|
||||
|
||||
switch (GET_AH()) {
|
||||
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
|
||||
//
|
||||
|
||||
|
||||
scancode = GET_AL();
|
||||
|
||||
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
|
||||
@ -1723,6 +1775,7 @@ int13_function(DI, SI, BP, SP, BX, DX, CX, AX, ES, FLAGS)
|
||||
Bit8u sector_count;
|
||||
unsigned int i;
|
||||
Bit16u tempbx;
|
||||
Bit16u lba;
|
||||
|
||||
write_byte(0x0040, 0x008e, 0); // clear completion flag
|
||||
|
||||
@ -1810,10 +1863,6 @@ printf("int13_f01\n");
|
||||
if ( (num_sectors > 128) || (num_sectors == 0) )
|
||||
panic("int13_function(): num_sectors out of range!");
|
||||
|
||||
|
||||
if (head > 15)
|
||||
panic("hard drive BIOS:(read/verify) head > 15");
|
||||
|
||||
if ( GET_AH() == 0x04 ) {
|
||||
SET_AH(0);
|
||||
set_disk_ret_status(0);
|
||||
@ -1826,10 +1875,17 @@ printf("int13_f01\n");
|
||||
panic("hard drive BIOS:(read/verify) BUSY bit set");
|
||||
}
|
||||
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) {
|
||||
@ -1948,19 +2004,24 @@ printf("int13_f03\n");
|
||||
if ( (num_sectors > 128) || (num_sectors == 0) )
|
||||
panic("int13_function(): num_sectors out of range!");
|
||||
|
||||
if (head > 15)
|
||||
panic("hard drive BIOS:(read) head > 15");
|
||||
|
||||
status = inb(0x1f7);
|
||||
if (status & 0x80) {
|
||||
panic("hard drive BIOS:(read) BUSY bit set");
|
||||
}
|
||||
// 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
|
||||
@ -4386,7 +4447,7 @@ int16_key_found:
|
||||
|
||||
|
||||
;-------------------------------------------------
|
||||
;- INT09h : Keyboard Harware Service Entry Point -
|
||||
;- INT09h : Keyboard Hardware Service Entry Point -
|
||||
;-------------------------------------------------
|
||||
.org 0xe987
|
||||
int09_handler:
|
||||
|
@ -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_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 */
|
||||
|
||||
@ -568,13 +568,21 @@ bx_hard_drive_c::read(Bit32u address, unsigned io_len)
|
||||
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
|
||||
@ -1268,13 +1276,15 @@ BX_DEBUG(("IO write to %04x = %02x", (unsigned) address, (unsigned) value));
|
||||
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(("IO write 1f6 (%02x): not 101xxxxxb", (unsigned) value));
|
||||
if ( (value & 0xa0) != 0xa0 ) // 1x1xxxxx
|
||||
BX_INFO(("IO write 1f6 (%02x): not 1x1xxxxxb", (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)
|
||||
@ -1730,11 +1740,13 @@ bx_hard_drive_c::calculate_logical_address()
|
||||
{
|
||||
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) +
|
||||
|
Loading…
Reference in New Issue
Block a user