Get CDROM emulation working.
authorKevin O'Connor <kevin@koconnor.net>
Wed, 5 Mar 2008 03:50:53 +0000 (22:50 -0500)
committerKevin O'Connor <kevin@koconnor.net>
Wed, 5 Mar 2008 03:50:53 +0000 (22:50 -0500)
Fix bug causing ata_cmd_packet to insl to wrong address.
Add new cdrom_read helper.
Join ata.hdidmap/cdidmap into one array variable.
Rename CONFIG_ELTORITO_BOOT to CONFIG_CDROM_BOOT.
Add cd emulation code.

src/ata.c
src/ata.h
src/biosvar.h
src/boot.c
src/cdrom.c
src/config.h
src/disk.c
src/disk.h
src/post.c

index a84e83ba29fa4cb3bf1c69f07a01c56804dd92ab..710bd9eeff355108afcc0554c512e23d3461d86e 100644 (file)
--- a/src/ata.c
+++ b/src/ata.c
@@ -425,7 +425,7 @@ ata_cmd_data_out(u16 device, u16 command, u16 count, u16 cylinder
       // 3 : error
       // 4 : not ready
 u16
-ata_cmd_packet(u16 device, u16 cmdbuf, u8 cmdlen, u16 header
+ata_cmd_packet(u16 device, u8 *cmdbuf, u8 cmdlen, u16 header
                , u32 length, u8 inout, u16 bufseg, u16 bufoff)
 {
     u16 iobase1, iobase2;
@@ -493,13 +493,12 @@ ata_cmd_packet(u16 device, u16 cmdbuf, u8 cmdlen, u16 header
     // Send command to device
     irq_enable();
 
-    outsw(iobase1, GET_SEG(SS), cmdbuf, cmdlen);
+    outsw(iobase1, GET_SEG(SS), (u32)cmdbuf, cmdlen);
 
     if (inout == ATA_DATA_NO) {
         await_ide(NOT_BSY, iobase1, IDE_TIMEOUT);
         status = inb(iobase1 + ATA_CB_STAT);
-    }
-    else {
+    } else {
         u16 loops = 0;
         u8 sc;
         while (1) {
@@ -507,8 +506,7 @@ ata_cmd_packet(u16 device, u16 cmdbuf, u8 cmdlen, u16 header
             if (loops == 0) {//first time through
                 status = inb(iobase2 + ATA_CB_ASTAT);
                 await_ide(NOT_BSY_DRQ, iobase1, IDE_TIMEOUT);
-            }
-            else
+            } else
                 await_ide(NOT_BSY, iobase1, IDE_TIMEOUT);
             loops++;
 
@@ -533,23 +531,21 @@ ata_cmd_packet(u16 device, u16 cmdbuf, u8 cmdlen, u16 header
             lcount =  ((u16)(inb(iobase1 + ATA_CB_CH))<<8)+inb(iobase1 + ATA_CB_CL);
 
             // adjust to read what we want
-            if(header>lcount) {
+            if (header > lcount) {
                 lbefore=lcount;
                 header-=lcount;
                 lcount=0;
-            }
-            else {
+            } else {
                 lbefore=header;
                 header=0;
                 lcount-=lbefore;
             }
 
-            if(lcount>length) {
+            if (lcount > length) {
                 lafter=lcount-length;
                 lcount=length;
                 length=0;
-            }
-            else {
+            } else {
                 lafter=0;
                 length-=lcount;
             }
@@ -589,9 +585,9 @@ ata_cmd_packet(u16 device, u16 cmdbuf, u8 cmdlen, u16 header
                     inw(iobase1);
 
             if (lmode == ATA_MODE_PIO32)
-                insl(iobase1, bufoff, bufseg, lcount);
+                insl(iobase1, bufseg, bufoff, lcount);
             else
-                insw(iobase1, bufoff, bufseg, lcount);
+                insw(iobase1, bufseg, bufoff, lcount);
 
             for (i=0; i<lafter; i++)
                 if (lmode == ATA_MODE_PIO32)
@@ -622,6 +618,26 @@ ata_cmd_packet(u16 device, u16 cmdbuf, u8 cmdlen, u16 header
     return 0;
 }
 
+u16
+cdrom_read(u16 device, u32 lba, u32 count, u16 segment, u16 offset, u16 skip)
+{
+    u16 sectors = (count + 2048 - 1) / 2048;
+
+    u8 atacmd[12];
+    memset(atacmd, 0, sizeof(atacmd));
+    atacmd[0]=0x28;                      // READ command
+    atacmd[7]=(sectors & 0xff00) >> 8;   // Sectors
+    atacmd[8]=(sectors & 0x00ff);        // Sectors
+    atacmd[2]=(lba & 0xff000000) >> 24;  // LBA
+    atacmd[3]=(lba & 0x00ff0000) >> 16;
+    atacmd[4]=(lba & 0x0000ff00) >> 8;
+    atacmd[5]=(lba & 0x000000ff);
+
+    return ata_cmd_packet(device, atacmd, sizeof(atacmd)
+                          , skip, count, ATA_DATA_IN
+                          , segment, offset);
+}
+
 // ---------------------------------------------------------------------------
 // ATA/ATAPI driver : device detection
 // ---------------------------------------------------------------------------
@@ -817,7 +833,7 @@ ata_detect()
             SET_EBDA(ata.devices[device].lchs.spt, spt);
 
             // fill hdidmap
-            SET_EBDA(ata.hdidmap[hdcount], device);
+            SET_EBDA(ata.idmap[0][hdcount], device);
             hdcount++;
         }
 
@@ -848,7 +864,7 @@ ata_detect()
             SET_EBDA(ata.devices[device].blksize, blksize);
 
             // fill cdidmap
-            SET_EBDA(ata.cdidmap[cdcount], device);
+            SET_EBDA(ata.idmap[1][cdcount], device);
             cdcount++;
         }
 
index 83c48ccc356e6f79075f9767cb503279bbfde3a9..ccd3e2ec8c5a46174427313b8b1cfe787fda752d 100644 (file)
--- a/src/ata.h
+++ b/src/ata.h
@@ -16,8 +16,10 @@ u16 ata_cmd_data_in(u16 device, u16 command, u16 count, u16 cylinder
                     , u16 head, u16 sector, u32 lba, u16 segment, u16 offset);
 u16 ata_cmd_data_out(u16 device, u16 command, u16 count, u16 cylinder
                      , u16 head, u16 sector, u32 lba, u16 segment, u16 offset);
-u16 ata_cmd_packet(u16 device, u16 cmdbuf, u8 cmdlen, u16 header
+u16 ata_cmd_packet(u16 device, u8 *cmdbuf, u8 cmdlen, u16 header
                    , u32 length, u8 inout, u16 bufseg, u16 bufoff);
+u16 cdrom_read(u16 device, u32 lba, u32 count
+               , u16 segment, u16 offset, u16 skip);
 void ata_detect();
 
 // Global defines -- ATA register and register bits.
index eea6df69e26380893220f980de4f4c4b1c848c12..55e9481b922b9209b705d10fcb091bf8622de0c1 100644 (file)
@@ -185,11 +185,9 @@ struct ata_s {
     // ATA devices info
     struct ata_device_s  devices[CONFIG_MAX_ATA_DEVICES];
     //
-    // map between (bios hd id - 0x80) and ata channels
-    u8  hdcount, hdidmap[CONFIG_MAX_ATA_DEVICES];
-
-    // map between (bios cd id - 0xE0) and ata channels
-    u8  cdcount, cdidmap[CONFIG_MAX_ATA_DEVICES];
+    // map between bios hd/cd id and ata channels
+    u8 hdcount, cdcount;
+    u8 idmap[2][CONFIG_MAX_ATA_DEVICES];
 
     // Buffer for DPTE table
     struct dpte_s dpte;
index 1ab9423bfa93c24b217562b56c400deaa653ff3d..a21136ed6b439587c84a97f19d62cf71519864b8 100644 (file)
@@ -10,6 +10,7 @@
 #include "config.h" // CONFIG_*
 #include "cmos.h" // inb_cmos
 #include "ata.h" // ata_detect
+#include "disk.h" // cdrom_boot
 
 // We need a copy of this string, but we are not actually a PnP BIOS,
 // so make sure it is *not* aligned, so OSes will not see it if they
@@ -67,7 +68,7 @@ try_boot(u16 seq_nr)
     u8 bootdrv = 0;
     u16 bootdev, bootip;
 
-    if (CONFIG_ELTORITO_BOOT) {
+    if (CONFIG_CDROM_BOOT) {
         bootdev = inb_cmos(CMOS_BIOS_BOOTFLAG2);
         bootdev |= ((inb_cmos(CMOS_BIOS_BOOTFLAG1) & 0xf0) << 4);
         bootdev >>= 4 * seq_nr;
@@ -133,10 +134,24 @@ try_boot(u16 seq_nr)
         bootip = (bootseg & 0x0fff) << 4;
         bootseg &= 0xf000;
         break;
-    case IPL_TYPE_CDROM: /* CD-ROM */
-        // XXX
-        return;
+    case IPL_TYPE_CDROM: {
+        /* CD-ROM */
+        if (! CONFIG_CDROM_BOOT)
+            break;
+        u16 status = cdrom_boot();
+        if (status) {
+            printf("CDROM boot failure code : %04x\n", status);
+            print_boot_failure(type, 1);
+            return;
+        }
+
+        bootdrv = GET_EBDA(cdemu.emulated_drive);
+        bootseg = GET_EBDA(cdemu.load_segment);
+        /* Canonicalize bootseg:bootip */
+        bootip = (bootseg & 0x0fff) << 4;
+        bootseg &= 0xf000;
         break;
+    }
     case IPL_TYPE_BEV: {
         /* Expansion ROM with a Bootstrap Entry Vector (a far
          * pointer) */
index 9782e278f62b0f60a486525d3ab3f3cafe390d89..b2caaf612a4b06d5eb3cb2a17b39f4e53b67258b 100644 (file)
@@ -9,6 +9,9 @@
 #include "util.h" // memset
 #include "ata.h" // ATA_CMD_READ_SECTORS
 
+#define DEBUGF1(fmt, args...) bprintf(0, fmt , ##args)
+#define DEBUGF(fmt, args...)
+
 
 /****************************************************************
  * CDROM functions
@@ -277,3 +280,258 @@ cdemu_134b(struct bregs *regs)
 
     disk_ret(regs, DISK_RET_SUCCESS);
 }
+
+
+/****************************************************************
+ * CD booting
+ ****************************************************************/
+
+// Request SENSE
+static u16
+atapi_get_sense(u16 device, u8 *asc, u8 *ascq)
+{
+    u8 buffer[18];
+    u8 atacmd[12];
+    memset(atacmd, 0, sizeof(atacmd));
+    atacmd[0] = ATA_CMD_REQUEST_SENSE;
+    atacmd[4] = sizeof(buffer);
+    u16 ret = ata_cmd_packet(device, atacmd, sizeof(atacmd)
+                             , 18L, 0, ATA_DATA_IN, GET_SEG(SS), (u32)buffer);
+    if (ret != 0)
+        return 0x0002;
+
+    *asc = buffer[12];
+    *ascq = buffer[13];
+
+    return 0;
+}
+
+static u16
+atapi_is_ready(u16 device)
+{
+    if (GET_EBDA(ata.devices[device].type) != ATA_TYPE_ATAPI) {
+        printf("not implemented for non-ATAPI device\n");
+        return -1;
+    }
+
+    DEBUGF("ata_detect_medium: begin\n");
+    u8 packet[12];
+    memset(packet, 0, sizeof(packet));
+    packet[0] = 0x25; /* READ CAPACITY */
+
+    /* Retry READ CAPACITY 50 times unless MEDIUM NOT PRESENT
+     * is reported by the device. If the device reports "IN PROGRESS",
+     * 30 seconds is added. */
+    u8 buf[8];
+    u32 timeout = 5000;
+    u32 time = 0;
+    u8 in_progress = 0;
+    for (;; time+=100) {
+        if (time >= timeout) {
+            DEBUGF("read capacity failed\n");
+            return -1;
+        }
+        u16 ret = ata_cmd_packet(device, packet, sizeof(packet)
+                                 , 0, 8L, ATA_DATA_IN, GET_SEG(SS), (u32)buf);
+        if (ret == 0)
+            break;
+
+        u8 asc=0, ascq=0;
+        ret = atapi_get_sense(device, &asc, &ascq);
+        if (!ret)
+            continue;
+
+        if (asc == 0x3a) { /* MEDIUM NOT PRESENT */
+            DEBUGF("Device reports MEDIUM NOT PRESENT\n");
+            return -1;
+        }
+
+        if (asc == 0x04 && ascq == 0x01 && !in_progress) {
+            /* IN PROGRESS OF BECOMING READY */
+            printf("Waiting for device to detect medium... ");
+            /* Allow 30 seconds more */
+            timeout = 30000;
+            in_progress = 1;
+        }
+    }
+
+    u32 block_len = (u32) buf[4] << 24
+        | (u32) buf[5] << 16
+        | (u32) buf[6] << 8
+        | (u32) buf[7] << 0;
+
+    if (block_len != 2048 && block_len != 512) {
+        printf("Unsupported sector size %u\n", block_len);
+        return -1;
+    }
+    SET_EBDA(ata.devices[device].blksize, block_len);
+
+    u32 sectors = (u32) buf[0] << 24
+        | (u32) buf[1] << 16
+        | (u32) buf[2] << 8
+        | (u32) buf[3] << 0;
+
+    DEBUGF("sectors=%u\n", sectors);
+    if (block_len == 2048)
+        sectors <<= 2; /* # of sectors in 512-byte "soft" sector */
+    if (sectors != GET_EBDA(ata.devices[device].sectors))
+        printf("%dMB medium detected\n", sectors>>(20-9));
+    SET_EBDA(ata.devices[device].sectors, sectors);
+    return 0;
+}
+
+static u16
+atapi_is_cdrom(u8 device)
+{
+    if (device >= CONFIG_MAX_ATA_DEVICES)
+        return 0;
+
+    if (GET_EBDA(ata.devices[device].type) != ATA_TYPE_ATAPI)
+        return 0;
+
+    if (GET_EBDA(ata.devices[device].device) != ATA_DEVICE_CDROM)
+        return 0;
+
+    return 1;
+}
+
+// Compare a string on the stack to one in the code segment.
+static int
+streq_cs(u8 *s1, char *cs_s2)
+{
+    u8 *s2 = (u8*)cs_s2;
+    for (;;) {
+        if (*s1 != GET_VAR(CS, *s2))
+            return 0;
+        if (! *s1)
+            return 1;
+        s1++;
+        s2++;
+    }
+}
+
+u16
+cdrom_boot()
+{
+    // Find out the first cdrom
+    u8 device;
+    for (device=0; device<CONFIG_MAX_ATA_DEVICES; device++)
+        if (atapi_is_cdrom(device))
+            break;
+
+    u16 ret = atapi_is_ready(device);
+    if (ret)
+        BX_INFO("ata_is_ready returned %d\n", ret);
+
+    // if not found
+    if (device >= CONFIG_MAX_ATA_DEVICES)
+        return 2;
+
+    // Read the Boot Record Volume Descriptor
+    u8 buffer[2048];
+    ret = cdrom_read(device, 0x11, 2048, GET_SEG(SS), (u32)buffer, 0);
+    if (ret)
+        return 3;
+
+    // Validity checks
+    if (buffer[0])
+        return 4;
+    if (!streq_cs(&buffer[1], "CD001\001EL TORITO SPECIFICATION"))
+        return 5;
+
+    // ok, now we calculate the Boot catalog address
+    u32 lba = *(u32*)&buffer[0x47];
+
+    // And we read the Boot Catalog
+    ret = cdrom_read(device, lba, 2048, GET_SEG(SS), (u32)buffer, 0);
+    if (ret)
+        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
+
+    // Initial/Default Entry
+    if (buffer[0x20] != 0x88)
+        return 11; // Bootable
+
+    SET_EBDA(cdemu.media,buffer[0x21]);
+    if (buffer[0x21] == 0)
+        // FIXME ElTorito Hardcoded. cdrom is hardcoded as device 0xE0.
+        // Win2000 cd boot needs to know it booted from cd
+        SET_EBDA(cdemu.emulated_drive, 0xE0);
+    else if (buffer[0x21] < 4)
+        SET_EBDA(cdemu.emulated_drive, 0x00);
+    else
+        SET_EBDA(cdemu.emulated_drive, 0x80);
+
+    SET_EBDA(cdemu.controller_index, device/2);
+    SET_EBDA(cdemu.device_spec, device%2);
+
+    u16 boot_segment = *(u16*)&buffer[0x22];
+    if (!boot_segment)
+        boot_segment = 0x07C0;
+
+    SET_EBDA(cdemu.load_segment,boot_segment);
+    SET_EBDA(cdemu.buffer_segment,0x0000);
+
+    u16 nbsectors = *(u16*)&buffer[0x26];
+    SET_EBDA(cdemu.sector_count, nbsectors);
+
+    lba = *(u32*)&buffer[0x28];
+    SET_EBDA(cdemu.ilba, lba);
+
+    // And we read the image in memory
+    ret = cdrom_read(device, lba, nbsectors*512
+                     , boot_segment, 0, 0);
+    if (ret)
+        return 12;
+
+    // Remember the media type
+    switch (GET_EBDA(cdemu.media)) {
+    case 0x01:  // 1.2M floppy
+        SET_EBDA(cdemu.vdevice.spt, 15);
+        SET_EBDA(cdemu.vdevice.cylinders, 80);
+        SET_EBDA(cdemu.vdevice.heads, 2);
+        break;
+    case 0x02:  // 1.44M floppy
+        SET_EBDA(cdemu.vdevice.spt, 18);
+        SET_EBDA(cdemu.vdevice.cylinders, 80);
+        SET_EBDA(cdemu.vdevice.heads, 2);
+        break;
+    case 0x03:  // 2.88M floppy
+        SET_EBDA(cdemu.vdevice.spt, 36);
+        SET_EBDA(cdemu.vdevice.cylinders, 80);
+        SET_EBDA(cdemu.vdevice.heads, 2);
+        break;
+    case 0x04: { // Harddrive
+        u16 spt = GET_FARVAR(boot_segment,*(u8*)(446+6));
+        u16 cyl = (spt << 2) + GET_FARVAR(boot_segment,*(u8*)(446+7)) + 1;
+        u16 heads = GET_FARVAR(boot_segment,*(u8*)(446+5)) + 1;
+        SET_EBDA(cdemu.vdevice.spt, spt & 0x3f);
+        SET_EBDA(cdemu.vdevice.cylinders, cyl);
+        SET_EBDA(cdemu.vdevice.heads, heads);
+        break;
+    }
+    }
+
+    if (GET_EBDA(cdemu.media) != 0) {
+        // Increase bios installed hardware number of devices
+        if (GET_EBDA(cdemu.emulated_drive) == 0x00)
+            SETBITS_BDA(equipment_list_flags, 0x41);
+        else
+            SET_EBDA(ata.hdcount, GET_EBDA(ata.hdcount) + 1);
+    }
+
+    // everything is ok, so from now on, the emulation is active
+    if (GET_EBDA(cdemu.media))
+        SET_EBDA(cdemu.active, 0x01);
+
+    return 0;
+}
index a118c688c6151cdef7488e9c16182964d3480fbe..199627e2151a67a577f0210c11c67f959b883cf1 100644 (file)
@@ -6,7 +6,7 @@
 #define CONFIG_PS2_MOUSE 1
 #define CONFIG_ATA 1
 #define CONFIG_KBD_CALL_INT15_4F 1
-#define CONFIG_ELTORITO_BOOT 1
+#define CONFIG_CDROM_BOOT 1
 
 #define CONFIG_MAX_ATA_INTERFACES 4
 #define CONFIG_MAX_ATA_DEVICES  (CONFIG_MAX_ATA_INTERFACES*2)
index 7c3e417af81a921f136a8531d7547d090e8d133a..5a2f069f647c34a3c12614b96a5e583264359b81 100644 (file)
@@ -104,12 +104,12 @@ basic_access(struct bregs *regs, u8 device, u16 command)
 void
 emu_access(struct bregs *regs, u8 device, u16 command)
 {
-    u16 nbsectors   = regs->al;
-    u16 cylinder    = regs->ch | ((((u16) regs->cl) << 2) & 0x300);
-    u16 sector      = regs->cl & 0x3f;
-    u16 head        = regs->dh;
+    u16 count    = regs->al;
+    u16 cylinder = regs->ch | ((((u16) regs->cl) << 2) & 0x300);
+    u16 sector   = regs->cl & 0x3f;
+    u16 head     = regs->dh;
 
-    if ((nbsectors > 128) || (nbsectors == 0) || (sector == 0)) {
+    if ((count > 128) || (count == 0) || (sector == 0)) {
         BX_INFO("int13_harddisk: function %02x, parameter out of range!\n"
                 , regs->ah);
         disk_ret(regs, DISK_RET_EPARAM);
@@ -142,34 +142,18 @@ emu_access(struct bregs *regs, u8 device, u16 command)
     // start lba on cd
     u32 slba  = (u32)vlba/4;
     u16 before= (u16)vlba%4;
-    // end lba on cd
-    u32 elba = (u32)(vlba+nbsectors-1)/4;
-    u32 count = elba-slba+1;
-    u32 lba = ilba+slba;
+    u32 lba = ilba + slba;
 
     u16 segment = regs->es;
     u16 offset  = regs->bx;
 
-    u8 atacmd[12];
-    memset(atacmd, 0, sizeof(atacmd));
-    atacmd[0]=0x28;                      // READ command
-    atacmd[7]=(count & 0xff00) >> 8;     // Sectors
-    atacmd[8]=(count & 0x00ff);          // Sectors
-    atacmd[2]=(lba & 0xff000000) >> 24;  // LBA
-    atacmd[3]=(lba & 0x00ff0000) >> 16;
-    atacmd[4]=(lba & 0x0000ff00) >> 8;
-    atacmd[5]=(lba & 0x000000ff);
-
-    u8 status = ata_cmd_packet(device, (u32)atacmd, sizeof(atacmd)
-                               , before*512, count*2048L
-                               , ATA_DATA_IN, segment, offset);
-
+    u8 status = cdrom_read(device, lba, count*512, segment, offset, before*512);
     if (status != 0) {
         BX_INFO("int13_harddisk: function %02x, error %02x !\n",regs->ah,status);
         regs->al = 0;
         disk_ret(regs, DISK_RET_EBADTRACK);
     }
-    regs->al = nbsectors;
+    regs->al = count;
     disk_ret(regs, DISK_RET_SUCCESS);
 }
 
@@ -203,25 +187,12 @@ extended_access(struct bregs *regs, u8 device, u16 command)
     u8 status;
     switch (command) {
     case ATA_CMD_READ_SECTORS:
-        if (type == ATA_TYPE_ATA) {
+        if (type == ATA_TYPE_ATA)
             status = ata_cmd_data_in(device, ATA_CMD_READ_SECTORS
                                      , count, 0, 0, 0
                                      , lba, segment, offset);
-        } else {
-            u8 atacmd[12];
-            memset(atacmd, 0, sizeof(atacmd));
-            atacmd[0]=0x28;                      // READ command
-            atacmd[7]=(count & 0xff00) >> 8;     // Sectors
-            atacmd[8]=(count & 0x00ff);          // Sectors
-            atacmd[2]=(lba & 0xff000000) >> 24;  // LBA
-            atacmd[3]=(lba & 0x00ff0000) >> 16;
-            atacmd[4]=(lba & 0x0000ff00) >> 8;
-            atacmd[5]=(lba & 0x000000ff);
-
-            status = ata_cmd_packet(device, (u32)atacmd, sizeof(atacmd)
-                                    , 0, count*2048L
-                                    , ATA_DATA_IN, segment, offset);
-        }
+        else
+            status = cdrom_read(device, lba, count*2048, segment, offset, 0);
         break;
     case ATA_CMD_WRITE_SECTORS:
         status = ata_cmd_data_out(device, ATA_CMD_WRITE_SECTORS
@@ -683,7 +654,7 @@ disk_13(struct bregs *regs, u8 device)
  ****************************************************************/
 
 static u8
-get_device(struct bregs *regs, u8 drive)
+get_device(struct bregs *regs, u8 iscd, u8 drive)
 {
     // basic check : device has to be defined
     if (drive >= CONFIG_MAX_ATA_DEVICES) {
@@ -692,7 +663,7 @@ get_device(struct bregs *regs, u8 drive)
     }
 
     // Get the ata channel
-    u8 device = GET_EBDA(ata.hdidmap[drive]);
+    u8 device = GET_EBDA(ata.idmap[iscd][drive]);
 
     // basic check : device has to be valid
     if (device >= CONFIG_MAX_ATA_DEVICES) {
@@ -718,14 +689,14 @@ handle_legacy_disk(struct bregs *regs, u8 drive)
     }
 
     if (drive >= 0xe0) {
-        u8 device = get_device(regs, drive - 0xe0);
+        u8 device = get_device(regs, 1, drive - 0xe0);
         if (device >= CONFIG_MAX_ATA_DEVICES)
             return;
         cdrom_13(regs, device);
         return;
     }
 
-    u8 device = get_device(regs, drive - 0x80);
+    u8 device = get_device(regs, 0, drive - 0x80);
     if (device >= CONFIG_MAX_ATA_DEVICES)
         return;
     disk_13(regs, device);
@@ -746,7 +717,7 @@ handle_13(struct bregs *regs)
     debug_enter(regs);
     u8 drive = regs->dl;
 
-    if (CONFIG_ELTORITO_BOOT) {
+    if (CONFIG_CDROM_BOOT) {
         if (regs->ah == 0x4b) {
             cdemu_134b(regs);
             goto done;
@@ -756,7 +727,8 @@ handle_13(struct bregs *regs)
                 cdemu_13(regs);
                 goto done;
             }
-            drive--;
+            if (drive < 0xe0)
+                drive--;
         }
     }
     handle_legacy_disk(regs, drive);
index badbb411f4a6fa184d226742424107941154799f..36e95e533bc08ab6916abe549ccb6e8058415059 100644 (file)
@@ -117,6 +117,7 @@ void disk_13XX(struct bregs *regs, u8 device);
 void cdrom_13(struct bregs *regs, u8 device);
 void cdemu_13(struct bregs *regs);
 void cdemu_134b(struct bregs *regs);
+u16 cdrom_boot();
 
 
 #endif // disk.h
index 00361d7fe7e3f9f9b7b3379dc662dba063713946..a1c71eee2d3f3452b70d91814a8ab0f63f5ad8a4 100644 (file)
@@ -352,8 +352,8 @@ ata_init()
     // hdidmap  and cdidmap init.
     u8 device;
     for (device=0; device < CONFIG_MAX_ATA_DEVICES; device++) {
-        ebda->ata.hdidmap[device] = CONFIG_MAX_ATA_DEVICES;
-        ebda->ata.cdidmap[device] = CONFIG_MAX_ATA_DEVICES;
+        ebda->ata.idmap[0][device] = CONFIG_MAX_ATA_DEVICES;
+        ebda->ata.idmap[1][device] = CONFIG_MAX_ATA_DEVICES;
     }
 }
 
@@ -437,7 +437,7 @@ init_boot_vectors()
     ip++;
 
     // CDROM
-    if (CONFIG_ELTORITO_BOOT) {
+    if (CONFIG_CDROM_BOOT) {
         ip->type = IPL_TYPE_CDROM;
         ip++;
     }