- 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 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:
|
||||||
|
@ -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) +
|
||||||
|
Loading…
Reference in New Issue
Block a user