// -*- fundamental -*-
/////////////////////////////////////////////////////////////////////////
-// $Id: rombios.c,v 1.12 2008/07/11 22:59:38 pdinda Exp $
+// $Id: rombios.c,v 1.13 2008/08/14 18:22:45 cuizheng Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002 MandrakeSoft S.A.
#define DEBUG_ROMBIOS 1
+#define DEBUG_RAMDISK 0
#define DEBUG_ATA 0
#define DEBUG_INT13_HD 0
#define DEBUG_INT13_CD 0
#endif // BX_ELTORITO_BOOT
-static char bios_cvs_version_string[] = "$Revision: 1.12 $";
-static char bios_date_string[] = "$Date: 2008/07/11 22:59:38 $";
+static char bios_cvs_version_string[] = "$Revision: 1.13 $";
+static char bios_date_string[] = "$Date: 2008/08/14 18:22:45 $";
-static char CVSID[] = "$Id: rombios.c,v 1.12 2008/07/11 22:59:38 pdinda Exp $";
+static char CVSID[] = "$Id: rombios.c,v 1.13 2008/08/14 18:22:45 cuizheng Exp $";
/* Offset to skip the CVS $Id: prefix */
#define bios_version_string (CVSID + 4)
#define BX_INFO(format, p...) bios_printf(BIOS_PRINTF_INFO, format, ##p)
#define BX_PANIC(format, p...) bios_printf(BIOS_PRINTF_DEBHALT, format, ##p)
+/*Zheng 07/2008*/
+
+#if DEBUG_RAMDISK
+# define debug_outb(a...) outb(a)
+#else
+# define debug_outb(a...)
+#endif
+
+
#if DEBUG_ATA
# define BX_DEBUG_ATA(a...) BX_DEBUG(a)
#else
Bit8u hdcount, cdcount, device, type;
Bit8u buffer[0x0200];
+ debug_outb(0x3e8, 0xf0);
+
//BX_DEBUG("rombios: ata_detect\n");
#if BX_MAX_ATA_INTERFACES > 0
break;
}
+ debug_outb(0x2ed, device);
+ debug_outb(0x2ee, type);
switch (type) {
case ATA_TYPE_ATA:
printf("ata%d %s: ",channel,slave?" slave":"master");
break;
case ATA_TYPE_UNKNOWN:
printf("ata%d %s: Unknown device\n",channel,slave?" slave":"master");
+ if(device == 3) {
+ }
break;
}
}
write_byte(0x40,0x75, hdcount);
printf("\n");
+ debug_outb(0x3e8, 0xf0);
// FIXME : should use bios=cmos|auto|disable bits
// FIXME : should know about translation bits
Bit8u channel, slave, sn, sc;
Bit16u max;
+ debug_outb(0x3e9, 0xf1);
+
channel = device / 2;
slave = device % 2;
// Enable interrupts
outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
+
+ debug_outb(0x3e9, 0xf1);
}
// ---------------------------------------------------------------------------
Bit8u channel, slave;
Bit8u status, current, mode;
+ debug_outb(0x3ea, 0xf2);
+
+
channel = device / 2;
slave = device % 2;
if (status & ATA_CB_STAT_ERR) {
BX_DEBUG_ATA("ata_cmd_data_in : read error\n");
+ debug_outb(0x3ea, 0xf2);
return 2;
} else if ( !(status & ATA_CB_STAT_DRQ) ) {
BX_DEBUG_ATA("ata_cmd_data_in : DRQ not set (status %02x)\n", (unsigned) status);
+ debug_outb(0x3ea, 0xf2);
return 3;
}
if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) )
!= ATA_CB_STAT_RDY ) {
BX_DEBUG_ATA("ata_cmd_data_in : no sectors left (status %02x)\n", (unsigned) status);
+ debug_outb(0x3ea, 0xf2);
return 4;
}
break;
if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) )
!= (ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ) ) {
BX_DEBUG_ATA("ata_cmd_data_in : more sectors left (status %02x)\n", (unsigned) status);
+ debug_outb(0x3ea, 0xf2);
return 5;
}
continue;
}
// Enable interrupts
outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
+ debug_outb(0x3ea, 0xf2);
return 0;
}
Bit8u channel, slave;
Bit8u status, current, mode;
+ debug_outb(0x3eb, 0xf3);
+
channel = device / 2;
slave = device % 2;
if (status & ATA_CB_STAT_ERR) {
BX_DEBUG_ATA("ata_cmd_data_out : read error\n");
+ debug_outb(0x3eb, 0xf3);
return 2;
} else if ( !(status & ATA_CB_STAT_DRQ) ) {
BX_DEBUG_ATA("ata_cmd_data_out : DRQ not set (status %02x)\n", (unsigned) status);
+ debug_outb(0x3eb, 0xf3);
return 3;
}
if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DF | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) )
!= ATA_CB_STAT_RDY ) {
BX_DEBUG_ATA("ata_cmd_data_out : no sectors left (status %02x)\n", (unsigned) status);
+ debug_outb(0x3eb, 0xf3);
return 6;
}
break;
if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) )
!= (ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ) ) {
BX_DEBUG_ATA("ata_cmd_data_out : more sectors left (status %02x)\n", (unsigned) status);
+ debug_outb(0x3eb, 0xf3);
return 7;
}
continue;
}
// Enable interrupts
outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
+ debug_outb(0x3eb, 0xf3);
return 0;
}
Bit8u status, error, mode, lmode;
Bit32u total, transfer;
+ debug_outb(0x3ec, 0xf4);
+
channel = device / 2;
slave = device % 2;
// Data out is not supported yet
if (inout == ATA_DATA_OUT) {
BX_INFO("ata_cmd_packet: DATA_OUT not supported yet\n");
+ debug_outb(0x3ec, 0xf4);
return 1;
}
// The header length must be even
if (header & 1) {
BX_DEBUG_ATA("ata_cmd_packet : header must be even (%04x)\n",header);
+ debug_outb(0x3ec, 0xf4);
return 1;
}
// WAIT_FOR_NOT_BUSY_AND_DRIVE_READY();
WAIT_FOR_NOT_BUSY();
- //BX_DEBUG_ATA("ata_cmd_packet: not busy\n");
+ BX_DEBUG_ATA("ata_cmd_packet: not busy\n");
// set "noninterruptable"
outb(iobase2 + ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN);
outb(iobase1 + ATA_CB_SC, 0x00);
outb(iobase1 + ATA_CB_SN, 0x00);
- //BX_DEBUG_ATA("ata_cmd_packet: configuration done\n");
+ BX_DEBUG_ATA("ata_cmd_packet: configuration done\n");
// Issue command for packet
outb(iobase1 + ATA_CB_CMD, ATA_CMD_PACKET);
- //BX_DEBUG_ATA("ata_cmd_packet: A0 issued to drive\n");
+ BX_DEBUG_ATA("ata_cmd_packet: A0 issued to drive\n");
ALT_STATUS_WAIT_FOR((status&ATA_CB_STAT_BSY)==0);
- //BX_DEBUG_ATA("ata_cmd_packet: alt status shows not busy\n");
+ BX_DEBUG_ATA("ata_cmd_packet: alt status shows not busy\n");
STATUS_UPDATE();
- //BX_DEBUG_ATA("ata_cmd_packet: main status shows 0x%x\n",(unsigned)status);
+ BX_DEBUG_ATA("ata_cmd_packet: main status shows 0x%x\n",(unsigned)status);
WAIT_FOR_DATA_REQUEST();
- //BX_DEBUG_ATA("ata_cmd_packet: data request is set\n");
+ BX_DEBUG_ATA("ata_cmd_packet: data request is set\n");
// Normalize address
cmdseg += (cmdoff / 16);
#endif
if (status & ATA_CB_STAT_ERR) {
BX_DEBUG_ATA("ata_cmd_packet : error (status %02x)\n",status);
+ debug_outb(0x3ec, 0xf4);
return 3;
}
if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) )
!= (ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ) ) {
BX_DEBUG_ATA("ata_cmd_packet 1: not ready (status %02x)\n", status);
+ debug_outb(0x3ec, 0xf4);
return 4;
}
// Save transferred bytes count
transfer += count;
write_dword(ebda_seg, &EbdaData->ata.trsfbytes,transfer);
- }
- }
+ } //while(1)
+ }//else
// Final check, device must be ready
if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DF | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) )
!= ATA_CB_STAT_RDY ) {
BX_DEBUG_ATA("ata_cmd_packet 2 : not ready (status %02x)\n", (unsigned) status);
+ debug_outb(0x3ec, 0xf4);
return 4;
}
// Enable interrupts
outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
+ debug_outb(0x3ec, 0xf4);
return 0;
}
Bit8u buffer[16];
Bit8u i;
+ debug_outb(0x3ed, 0xf5);
+
memsetb(get_SS(),atacmd,0,12);
// Request SENSE
atacmd[0]=0x03;
atacmd[4]=0x20;
- if (ata_cmd_packet(device, 12, get_SS(), atacmd, 0, 16L, ATA_DATA_IN, get_SS(), buffer) != 0)
+ if (ata_cmd_packet(device, 12, get_SS(), atacmd, 0, 16L, ATA_DATA_IN, get_SS(), buffer) != 0) {
+ debug_outb(0x3ed, 0xf5);
return 0x0002;
+ }
if ((buffer[0] & 0x7e) == 0x70) {
+ debug_outb(0x3ed, 0xf5);
return (((Bit16u)buffer[2]&0x0f)*0x100)+buffer[12];
}
+ debug_outb(0x3ed, 0xf5);
return 0;
}
Bit8u atacmd[12];
Bit8u buffer[];
+ debug_outb(0x3ee, 0xf6);
+
memsetb(get_SS(),atacmd,0,12);
// Test Unit Ready
- if (ata_cmd_packet(device, 12, get_SS(), atacmd, 0, 0L, ATA_DATA_NO, get_SS(), buffer) != 0)
+ if (ata_cmd_packet(device, 12, get_SS(), atacmd, 0, 0L, ATA_DATA_NO, get_SS(), buffer) != 0) {
+ debug_outb(0x3ee, 0xf6);
return 0x000f;
+ }
if (atapi_get_sense(device) !=0 ) {
memsetb(get_SS(),atacmd,0,12);
// try to send Test Unit Ready again
- if (ata_cmd_packet(device, 12, get_SS(), atacmd, 0, 0L, ATA_DATA_NO, get_SS(), buffer) != 0)
+ if (ata_cmd_packet(device, 12, get_SS(), atacmd, 0, 0L, ATA_DATA_NO, get_SS(), buffer) != 0) {
+ debug_outb(0x3ee, 0xf6);
return 0x000f;
+ }
+ debug_outb(0x3ee, 0xf6);
return atapi_get_sense(device);
}
+ debug_outb(0x3ee, 0xf6);
return 0;
}
atapi_is_cdrom(device)
Bit8u device;
{
+
+
Bit16u ebda_seg=read_word(0x0040,0x000E);
- if (device >= BX_MAX_ATA_DEVICES)
+ debug_outb(0x3ef, 0xf7);
+
+ if (device >= BX_MAX_ATA_DEVICES) {
+ debug_outb(0x3ef, 0xf7);
return 0;
+ }
- if (read_byte(ebda_seg,&EbdaData->ata.devices[device].type) != ATA_TYPE_ATAPI)
+ if (read_byte(ebda_seg,&EbdaData->ata.devices[device].type) != ATA_TYPE_ATAPI) {
+ debug_outb(0x3ef, 0xf7);
return 0;
+ }
- if (read_byte(ebda_seg,&EbdaData->ata.devices[device].device) != ATA_DEVICE_CDROM)
+ if (read_byte(ebda_seg,&EbdaData->ata.devices[device].device) != ATA_DEVICE_CDROM) {
+ debug_outb(0x3ef, 0xf7);
return 0;
+ }
+ debug_outb(0x3ef, 0xf7);
return 1;
}
void
cdemu_init()
{
+
+
Bit16u ebda_seg=read_word(0x0040,0x000E);
+ debug_outb(0x2e8, 0xf8);
+
//BX_DEBUG("rombios: cdemu_init\n");
// the only important data is this one for now
write_byte(ebda_seg,&EbdaData->cdemu.active,0x00);
+ debug_outb(0x2e8, 0xf8);
+
+
}
Bit8u
cdemu_isactive()
{
+
Bit16u ebda_seg=read_word(0x0040,0x000E);
+ outb(0x2e9, 0xf9);
return(read_byte(ebda_seg,&EbdaData->cdemu.active));
}
Bit8u
cdemu_emulated_drive()
{
+
Bit16u ebda_seg=read_word(0x0040,0x000E);
+ debug_outb(0x2ea, 0xfa);
+ debug_outb(0x2ea, 0xfa);
return(read_byte(ebda_seg,&EbdaData->cdemu.emulated_drive));
}
Bit16u boot_segment, nbsectors, i, error;
Bit8u device;
+ debug_outb(0x2eb, 0xfb);
// Find out the first cdrom
for (device=0; device<BX_MAX_ATA_DEVICES;device++) {
}
// if not found
- if(device >= BX_MAX_ATA_DEVICES) return 2;
+ if(device >= BX_MAX_ATA_DEVICES) {
+ debug_outb(0x2eb, 0xfb);
+ return 2;
+ }
atacmd[4]=(0x11 & 0x0000ff00) >> 8;
atacmd[5]=(0x11 & 0x000000ff);
atacmd[9]=atacmd[10]=atacmd[11]=0x0; // just to be safe -PAD
- if((error = ata_cmd_packet(device, 12, get_SS(), atacmd, 0, 2048L, ATA_DATA_IN, get_SS(), buffer)) != 0)
+ if((error = ata_cmd_packet(device, 12, get_SS(), atacmd, 0, 2048L, ATA_DATA_IN, get_SS(), buffer)) != 0) {
+ debug_outb(0x2eb, 0xfb);
return 3;
+ }
// Validity checks
if(buffer[0]!=0)return 4;
for(i=0;i<5;i++){
- if(buffer[1+i]!=read_byte(0xf000,&isotag[i]))return 5;
+ if(buffer[1+i]!=read_byte(0xf000,&isotag[i])) {
+ debug_outb(0x2eb, 0xfb); return 5;
+ }
}
for(i=0;i<23;i++)
- if(buffer[7+i]!=read_byte(0xf000,&eltorito[i]))return 6;
+ if(buffer[7+i]!=read_byte(0xf000,&eltorito[i])) {
+ debug_outb(0x2eb, 0xfb); return 6;
+ }
// ok, now we calculate the Boot catalog address
lba=buffer[0x4A]*0x1000000+buffer[0x49]*0x10000+buffer[0x48]*0x100+buffer[0x47];
atacmd[3]=(lba & 0x00ff0000) >> 16;
atacmd[4]=(lba & 0x0000ff00) >> 8;
atacmd[5]=(lba & 0x000000ff);
- if((error = ata_cmd_packet(device, 12, get_SS(), atacmd, 0, 2048L, ATA_DATA_IN, get_SS(), buffer)) != 0)
+ if((error = ata_cmd_packet(device, 12, get_SS(), atacmd, 0, 2048L, ATA_DATA_IN, get_SS(), buffer)) != 0) {
+ debug_outb(0x2eb, 0xfb);
return 7;
+ }
// Validation entry
- if(buffer[0x00]!=0x01)return 8; // Header
- if(buffer[0x01]!=0x00)return 9; // Platform
- if(buffer[0x1E]!=0x55)return 10; // key 1
- if(buffer[0x1F]!=0xAA)return 10; // key 2
+ if(buffer[0x00]!=0x01) { debug_outb(0x2eb, 0xfb); return 8;} // Header
+ if(buffer[0x01]!=0x00){ debug_outb(0x2eb, 0xfb); return 9;} // Platform
+ if(buffer[0x1E]!=0x55) { debug_outb(0x2eb, 0xfb); return 10;} // key 1
+ if(buffer[0x1F]!=0xAA) { debug_outb(0x2eb, 0xfb); return 10;} // key 2
// Initial/Default Entry
- if(buffer[0x20]!=0x88)return 11; // Bootable
+ if(buffer[0x20]!=0x88) { debug_outb(0x2eb, 0xfb); return 11;} // Bootable
write_byte(ebda_seg,&EbdaData->cdemu.media,buffer[0x21]);
if(buffer[0x21]==0){
atacmd[3]=(lba & 0x00ff0000) >> 16;
atacmd[4]=(lba & 0x0000ff00) >> 8;
atacmd[5]=(lba & 0x000000ff);
- if((error = ata_cmd_packet(device, 12, get_SS(), atacmd, 0, nbsectors*512L, ATA_DATA_IN, boot_segment,0)) != 0)
+ if((error = ata_cmd_packet(device, 12, get_SS(), atacmd, 0, nbsectors*512L, ATA_DATA_IN, boot_segment,0)) != 0) {
+ debug_outb(0x2eb, 0xfb);
return 12;
+ }
// Remember the media type
write_byte(ebda_seg,&EbdaData->cdemu.active,0x01);
// return the boot drive + no error
+ debug_outb(0x2eb, 0xfb);
return (read_byte(ebda_seg,&EbdaData->cdemu.emulated_drive)*0x100)+0;
}
Bit16u size, count;
Bit8u device, status;
+ debug_outb(0x2ef, 0xff);
BX_DEBUG_INT13_HD("int13_harddisk: AX=%04x BX=%04x CX=%04x DX=%04x ES=%04x\n", AX, BX, CX, DX, ES);
write_byte(0x0040, 0x008e, 0); // clear completion flag
SET_DISK_RET_STATUS(GET_AH());
int13_fail_nostatus:
SET_CF(); // error occurred
+ debug_outb(0x2ef, 0xff);
return;
int13_success:
int13_success_noah:
SET_DISK_RET_STATUS(0x00);
CLEAR_CF(); // no error
+ debug_outb(0x2ef, 0xff);
return;
}
Bit32u lba;
Bit16u count, segment, offset, i, size;
+ debug_outb(0x2f8, 0xe0);
+
BX_DEBUG_INT13_CD("int13_cdrom: AX=%04x BX=%04x CX=%04x DX=%04x ES=%04x\n", AX, BX, CX, DX, ES);
// BX_DEBUG_INT13_CD("int13_cdrom: SS=%04x DS=%04x ES=%04x DI=%04x SI=%04x\n",get_SS(), DS, ES, DI, SI);
SET_DISK_RET_STATUS(GET_AH());
int13_fail_nostatus:
SET_CF(); // error occurred
+ debug_outb(0x2f8, 0xe0);
return;
int13_success:
int13_success_noah:
SET_DISK_RET_STATUS(0x00);
CLEAR_CF(); // no error
+ debug_outb(0x2f8, 0xe0);
return;
}
{
Bit16u ebda_seg=read_word(0x0040,0x000E);
+ debug_outb(0x2fa, 0xe2);
+
BX_DEBUG_INT13_ET("int13_eltorito: AX=%04x BX=%04x CX=%04x DX=%04x ES=%04x\n", AX, BX, CX, DX, ES);
// BX_DEBUG_INT13_ET("int13_eltorito: SS=%04x DS=%04x ES=%04x DI=%04x SI=%04x\n",get_SS(), DS, ES, DI, SI);
SET_AH(0x01); // defaults to invalid function in AH or invalid parameter
SET_DISK_RET_STATUS(GET_AH());
SET_CF(); // error occurred
+ debug_outb(0x2fa, 0xe2);
return;
int13_success:
SET_AH(0x00); // no error
SET_DISK_RET_STATUS(0x00);
CLEAR_CF(); // no error
+ debug_outb(0x2fa, 0xe2);
return;
}
Bit16u before, segment, offset;
Bit8u atacmd[12];
+ debug_outb(0x2f9, 0xe1);
+
BX_DEBUG_INT13_ET("int13_cdemu: AX=%04x BX=%04x CX=%04x DX=%04x ES=%04x\n", AX, BX, CX, DX, ES);
//BX_DEBUG_INT13_ET("int13_cdemu: SS=%04x ES=%04x DI=%04x SI=%04x\n", get_SS(), ES, DI, SI);
SET_DISK_RET_STATUS(GET_AH());
int13_fail_nostatus:
SET_CF(); // error occurred
+ debug_outb(0x2f9, 0xe1);
return;
int13_success:
int13_success_noah:
SET_DISK_RET_STATUS(0x00);
CLEAR_CF(); // no error
+ debug_outb(0x2f9, 0xe1);
return;
}
Bit32u lba;
Bit16u error;
+
+ debug_outb(0x2ef, 0xff);
BX_DEBUG_INT13_HD("int13 harddisk: AX=%04x BX=%04x CX=%04x DX=%04x ES=%04x\n", AX, BX, CX, DX, ES);
write_byte(0x0040, 0x008e, 0); // clear completion flag
SET_AH(0x01);
SET_DISK_RET_STATUS(0x01);
SET_CF(); /* error occurred */
+ debug_outb(0x2ef, 0xff);
return;
}
set_diskette_current_cyl(0, 0); /* current cylinder, diskette 1 */
set_diskette_current_cyl(1, 0); /* current cylinder, diskette 2 */
CLEAR_CF(); /* successful */
+ debug_outb(0x2ef, 0xff);
return;
break;
/* set CF if error status read */
if (status) SET_CF();
else CLEAR_CF();
+ debug_outb(0x2ef, 0xff);
return;
break;
SET_AH(1);
SET_DISK_RET_STATUS(1);
SET_CF(); /* error occurred */
+ debug_outb(0x2ef, 0xff);
return;
}
- if ( (num_sectors > 128) || (num_sectors == 0) )
+ if ( (num_sectors > 128) || (num_sectors == 0) ){
+ debug_outb(0x2ef, 0xff);
BX_PANIC("int13_harddisk(): num_sectors out of range!\n");
+ }
- if (head > 15)
+ if (head > 15) {
+ debug_outb(0x2ef, 0xff);
BX_PANIC("hard drive BIOS:(read/verify) head > 15\n");
+ }
if ( GET_AH() == 0x04 ) {
SET_AH(0);
SET_DISK_RET_STATUS(0);
CLEAR_CF();
+ debug_outb(0x2ef, 0xff);
return;
}
status = inb(0x1f7);
if (status & 0x80) {
+ debug_outb(0x2ef, 0xff);
BX_PANIC("hard drive BIOS:(read/verify) BUSY bit set\n");
}
outb(0x01f2, num_sectors);
}
if (status & 0x01) {
+ debug_outb(0x2ef, 0xff);
BX_PANIC("hard drive BIOS:(read/verify) read error\n");
} else if ( !(status & 0x08) ) {
+ debug_outb(0x2ef, 0xff);
BX_DEBUG_INT13_HD("status was %02x\n", (unsigned) status);
BX_PANIC("hard drive BIOS:(read/verify) expected DRQ=1\n");
}
if (num_sectors == 0) {
status = inb(0x1f7);
if ( (status & 0xc9) != 0x40 )
+ debug_outb(0x2ef, 0xff);
BX_PANIC("no sectors left to read/verify, status is %02x\n", (unsigned) status);
break;
}
else {
status = inb(0x1f7);
if ( (status & 0xc9) != 0x48 )
+ debug_outb(0x2ef, 0xff);
BX_PANIC("more sectors left to read/verify, status is %02x\n", (unsigned) status);
continue;
}
SET_DISK_RET_STATUS(0);
SET_AL(sector_count);
CLEAR_CF(); /* successful */
+ debug_outb(0x2ef, 0xff);
return;
break;
SET_AH( 1);
SET_DISK_RET_STATUS(1);
SET_CF(); /* error occurred */
+ debug_outb(0x2ef, 0xff);
return;
}
- if ( (num_sectors > 128) || (num_sectors == 0) )
+ if ( (num_sectors > 128) || (num_sectors == 0) ) {
+ debug_outb(0x2ef, 0xff);
BX_PANIC("int13_harddisk(): num_sectors out of range!\n");
+ }
- if (head > 15)
+ if (head > 15) {
+ debug_outb(0x2ef, 0xff);
BX_PANIC("hard drive BIOS:(read) head > 15\n");
+ }
status = inb(0x1f7);
if (status & 0x80) {
+ debug_outb(0x2ef, 0xff);
BX_PANIC("hard drive BIOS:(read) BUSY bit set\n");
}
// should check for Drive Ready Bit also in status reg
}
if ( !(status & 0x08) ) {
+ debug_outb(0x2ef, 0xff);
BX_DEBUG_INT13_HD("status was %02x\n", (unsigned) status);
BX_PANIC("hard drive BIOS:(write) data-request bit not set\n");
}
num_sectors--;
if (num_sectors == 0) {
status = inb(0x1f7);
- if ( (status & 0xe9) != 0x40 )
+ if ( (status & 0xe9) != 0x40 ) {
+ debug_outb(0x2ef, 0xff);
BX_PANIC("no sectors left to write, status is %02x\n", (unsigned) status);
+ }
break;
}
else {
status = inb(0x1f7);
- if ( (status & 0xc9) != 0x48 )
- BX_PANIC("more sectors left to write, status is %02x\n", (unsigned) status);
+ if ( (status & 0xc9) != 0x48 ) {
+ debug_outb(0x2ef, 0xff);
+ BX_PANIC("more sectors left to write, status is %02x\n", (unsigned) status);
+ }
continue;
}
}
SET_DISK_RET_STATUS(0);
SET_AL(sector_count);
CLEAR_CF(); /* successful */
+ debug_outb(0x2ef, 0xff);
return;
break;
SET_AH(0);
SET_DISK_RET_STATUS(0);
CLEAR_CF(); /* successful */
+ debug_outb(0x2ef, 0xff);
return;
break;
SET_AH(0);
SET_DISK_RET_STATUS(0);
CLEAR_CF(); /* successful */
-
+ debug_outb(0x2ef, 0xff);
return;
break;
SET_AH(0);
SET_DISK_RET_STATUS(0);
CLEAR_CF(); /* successful */
+ debug_outb(0x2ef, 0xff);
return;
break;
BX_DEBUG_INT13_HD("int13_f0a\n");
case 0x0b: /* write disk sectors with ECC */
BX_DEBUG_INT13_HD("int13_f0b\n");
+ debug_outb(0x2ef, 0xff);
BX_PANIC("int13h Functions 0Ah & 0Bh not implemented!\n");
return;
break;
SET_AH(0);
SET_DISK_RET_STATUS(0);
CLEAR_CF(); /* successful */
+ debug_outb(0x2ef, 0xff);
return;
break;
SET_AH(0);
SET_DISK_RET_STATUS(0);
CLEAR_CF(); /* successful */
+ debug_outb(0x2ef, 0xff);
return;
break;
SET_AH(0);
SET_DISK_RET_STATUS(0);
CLEAR_CF(); // drive ready
+ debug_outb(0x2ef, 0xff);
return;
}
else {
SET_AH(0xAA);
SET_DISK_RET_STATUS(0xAA);
SET_CF(); // not ready
+ debug_outb(0x2ef, 0xff);
return;
}
break;
SET_AH(0);
SET_DISK_RET_STATUS(0);
CLEAR_CF(); /* successful */
+ debug_outb(0x2ef, 0xff);
return;
break;
SET_DISK_RET_STATUS(0);
CLEAR_CF(); /* successful */
SET_AL(0);
+ debug_outb(0x2ef, 0xff);
return;
break;
SET_AH(3); // hard disk accessible
SET_DISK_RET_STATUS(0); // ??? should this be 0
CLEAR_CF(); // successful
+ debug_outb(0x2ef, 0xff);
return;
break;
SET_AH(1); // code=invalid function in AH or invalid parameter
SET_DISK_RET_STATUS(1);
SET_CF(); /* unsuccessful */
+ debug_outb(0x2ef, 0xff);
return;
break;
}
Bit8u drive_type, num_floppies, ah;
Bit16u es, last_addr;
-
+ debug_outb(0x2fb, 0xe3);
//printf("int13_diskette: AX=%04x BX=%04x CX=%04x DX=%04x ES=%04x\n", AX, BX, CX, DX, ES);
BX_DEBUG_INT13_FL("int13_diskette: SS=%04x DS=%04x ES=%04x DI=%04x SI=%04x\n",get_SS(),get_DS(), ES, DI, SI);
SET_AH(1); // invalid param
set_diskette_ret_status(1);
SET_CF();
+ debug_outb(0x2fb, 0xe3);
return;
}
drive_type = inb_cmos(0x10);
SET_AH(0x80); // drive not responding
set_diskette_ret_status(0x80);
SET_CF();
+ debug_outb(0x2fb, 0xe3);
return;
}
SET_AH(0);
set_diskette_ret_status(0);
CLEAR_CF(); // successful
set_diskette_current_cyl(drive, 0); // current cylinder
+ debug_outb(0x2fb, 0xe3);
return;
case 0x01: // Read Diskette Status
if (val8) {
SET_CF();
}
+ debug_outb(0x2fb, 0xe3);
return;
case 0x02: // Read Diskette Sectors
set_diskette_ret_status(1);
SET_AL(0); // no sectors read
SET_CF(); // error occurred
+ debug_outb(0x2fb, 0xe3);
return;
}
set_diskette_ret_status(0x80);
SET_AL(0); // no sectors read
SET_CF(); // error occurred
+ debug_outb(0x2fb, 0xe3);
return;
}
set_diskette_ret_status(0x0C);
SET_AL(0); // no sectors read
SET_CF(); // error occurred
+ debug_outb(0x2fb, 0xe3);
return;
}
}
set_diskette_ret_status(0x09);
SET_AL(0); // no sectors read
SET_CF(); // error occurred
+ debug_outb(0x2fb, 0xe3);
return;
}
// check port 3f4 for drive readiness
val8 = inb(0x3f4);
- if ( (val8 & 0xf0) != 0x80 )
+ if ( (val8 & 0xf0) != 0x80 ) {
+ debug_outb(0x2fb, 0xe3);
BX_PANIC("int13_diskette:f02: ctrl not ready\n");
+ }
// send read-normal-data command (9 bytes) to controller
outb(0x03f5, 0xe6); // e6: read normal data
// check port 3f4 for accessibility to status bytes
val8 = inb(0x3f4);
- if ( (val8 & 0xc0) != 0xc0 )
+ if ( (val8 & 0xc0) != 0xc0 ) {
+ debug_outb(0x2fb, 0xe3);
BX_PANIC("int13_diskette: ctrl not ready\n");
+ }
// read 7 return status bytes from controller
// using loop index broken, have to unroll...
set_diskette_ret_status(0x20);
SET_AL(0); // no sectors read
SET_CF(); // error occurred
+ debug_outb(0x2fb, 0xe3);
return;
}
// AL = number of sectors read (same value as passed)
SET_AH(0x00); // success
CLEAR_CF(); // success
+ debug_outb(0x2fb, 0xe3);
return;
}
else if (ah == 0x03) {
set_diskette_ret_status(0x09);
SET_AL(0); // no sectors read
SET_CF(); // error occurred
+ debug_outb(0x2fb, 0xe3);
return;
}
// check port 3f4 for drive readiness
val8 = inb(0x3f4);
- if ( (val8 & 0xf0) != 0x80 )
+ if ( (val8 & 0xf0) != 0x80 ){
+ debug_outb(0x2fb, 0xe3);
BX_PANIC("int13_diskette:f03: ctrl not ready\n");
+ }
// send read-normal-data command (9 bytes) to controller
outb(0x03f5, 0xc5); // c5: write normal data
// check port 3f4 for accessibility to status bytes
val8 = inb(0x3f4);
- if ( (val8 & 0xc0) != 0xc0 )
+ if ( (val8 & 0xc0) != 0xc0 ) {
+ debug_outb(0x2fb, 0xe3);
BX_PANIC("int13_diskette: ctrl not ready\n");
+ }
// read 7 return status bytes from controller
// using loop index broken, have to unroll...
// AL=number of sectors written=0
AX = 0x0300;
SET_CF();
+ debug_outb(0x2fb, 0xe3);
return;
} else {
+ debug_outb(0x2fb, 0xe3);
BX_PANIC("int13_diskette_function: read error\n");
}
}
// AL = number of sectors read (same value as passed)
SET_AH(0x00); // success
CLEAR_CF(); // success
+ debug_outb(0x2fb, 0xe3);
return;
}
else { // if (ah == 0x04)
// AL = number of sectors verified (same value as passed)
CLEAR_CF(); // success
SET_AH(0x00); // success
+ debug_outb(0x2fb, 0xe3);
return;
}
SET_AH(0x80); // drive not responding
set_diskette_ret_status(0x80);
SET_CF(); // error occurred
+ debug_outb(0x2fb, 0xe3);
return;
}
set_diskette_ret_status(0x0C);
SET_AL(0); // no sectors read
SET_CF(); // error occurred
+ debug_outb(0x2fb, 0xe3);
return;
}
}
set_diskette_ret_status(0x09);
SET_AL(0); // no sectors read
SET_CF(); // error occurred
+ debug_outb(0x2fb, 0xe3);
return;
}
// check port 3f4 for drive readiness
val8 = inb(0x3f4);
- if ( (val8 & 0xf0) != 0x80 )
+ if ( (val8 & 0xf0) != 0x80 ) {
+ debug_outb(0x2fb, 0xe3);
BX_PANIC("int13_diskette:f05: ctrl not ready\n");
+ }
// send read-normal-data command (6 bytes) to controller
outb(0x03f5, 0x4d); // 4d: format track
write_byte(0x0000, 0x043e, val8);
// check port 3f4 for accessibility to status bytes
val8 = inb(0x3f4);
- if ( (val8 & 0xc0) != 0xc0 )
+ if ( (val8 & 0xc0) != 0xc0 ) {
+ debug_outb(0x2fb, 0xe3);
BX_PANIC("int13_diskette: ctrl not ready\n");
+ }
// read 7 return status bytes from controller
// using loop index broken, have to unroll...
// AL=number of sectors written=0
AX = 0x0300;
SET_CF();
+ debug_outb(0x2fb, 0xe3);
return;
} else {
+ debug_outb(0x2fb, 0xe3);
BX_PANIC("int13_diskette_function: write error\n");
}
}
set_diskette_ret_status(0);
set_diskette_current_cyl(drive, 0);
CLEAR_CF(); // successful
+ debug_outb(0x2fb, 0xe3);
return;
DI = 0;
SET_DL(num_floppies);
SET_CF();
+ debug_outb(0x2fb, 0xe3);
return;
}
break;
default: // ?
+ debug_outb(0x2fb, 0xe3);
BX_PANIC("floppy: int13: bad floppy type\n");
}
ASM_END
CLEAR_CF(); // success
/* disk status not changed upon success */
+ debug_outb(0x2fb, 0xe3);
return;
SET_AH(0); // only 2 drives supported
// set_diskette_ret_status here ???
SET_CF();
+ debug_outb(0x2fb, 0xe3);
return;
}
drive_type = inb_cmos(0x10);
SET_AH(0x01); // invalid drive
set_diskette_ret_status(0x01);
SET_CF();
+ debug_outb(0x2fb, 0xe3);
return;
}
SET_AH(0x06); // change line not supported
set_diskette_ret_status(0x06);
SET_CF();
+ debug_outb(0x2fb, 0xe3);
return;
case 0x17: // set diskette type for format(old)
SET_AH(0x01); // not supported
set_diskette_ret_status(1); /* not supported */
SET_CF();
+ debug_outb(0x2fb, 0xe3);
return;
case 0x18: // set diskette type for format(new)
SET_AH(0x01); // do later
set_diskette_ret_status(1);
SET_CF();
+ debug_outb(0x2fb, 0xe3);
return;
default:
SET_AH(0x01); // ???
set_diskette_ret_status(1);
SET_CF();
+ debug_outb(0x2fb, 0xe3);
return;
// }
}
if (val8) {
SET_CF();
}
+ debug_outb(0x2fb, 0xe3);
return;
default:
write_byte(0x0000, 0x0441, 0x01);
SET_AH(0x01);
}
+ debug_outb(0x2fb, 0xe3);
}
#endif // #if BX_SUPPORT_FLOPPY
// IRQ 14 = INT 76h
// INT 76h calls INT 15h function ax=9100
+#if DEBUG_RAMDISK
+
+ mov al, #0xfc
+ mov dx, #0x02ec
+ out dx, al
+ mov ax, #0x0000
+ mov dx, #0x0000
+
+#endif
+
mov al, #0x0a ; 0000 1010 = reserved, disable IRQ 14
mov dx, #0x03f6
out dx, al