Unify cd emulation access and main disk access code.

Add a new backend driver for cd emulation (DTYPE_CDEMU).  This backend
    driver now does the work of scheduling mis-sized reads.
Add mechanism for obtaining emulated drive geometry.
Extend disk_1308() to support cdrom emulation.
Use regular disk_13*() calls even for cdemu.
Also, unify the X_SECTOR_SIZE definitions.
diff --git a/src/ata.c b/src/ata.c
index 884eae3..f5a1c98 100644
--- a/src/ata.c
+++ b/src/ata.c
@@ -18,9 +18,6 @@
 #include "disk.h" // struct ata_s
 #include "ata.h" // ATA_CB_STAT
 
-#define IDE_SECTOR_SIZE 512
-#define CDROM_SECTOR_SIZE 2048
-
 #define IDE_TIMEOUT 32000 //32 seconds max for IDE ops
 
 struct ata_channel_s ATA_channels[CONFIG_MAX_ATA_INTERFACES] VAR16VISIBLE;
@@ -352,7 +349,7 @@
     int ret = send_cmd(op->driveid, &cmd);
     if (ret)
         return ret;
-    return ata_transfer(op, iswrite, IDE_SECTOR_SIZE);
+    return ata_transfer(op, iswrite, DISK_SECTOR_SIZE);
 }
 
 int
@@ -547,7 +544,7 @@
 init_drive_atapi(int driveid, u16 *buffer)
 {
     // Send an IDENTIFY_DEVICE_PACKET command to device
-    memset(buffer, 0, IDE_SECTOR_SIZE);
+    memset(buffer, 0, DISK_SECTOR_SIZE);
     struct disk_op_s dop;
     memset(&dop, 0, sizeof(dop));
     dop.driveid = driveid;
@@ -594,7 +591,7 @@
 init_drive_ata(int driveid, u16 *buffer)
 {
     // Send an IDENTIFY_DEVICE command to device
-    memset(buffer, 0, IDE_SECTOR_SIZE);
+    memset(buffer, 0, DISK_SECTOR_SIZE);
     struct disk_op_s dop;
     memset(&dop, 0, sizeof(dop));
     dop.driveid = driveid;
@@ -608,7 +605,7 @@
     // Success - setup as ATA.
     extract_identify(driveid, buffer);
     SET_GLOBAL(Drives.drives[driveid].type, DTYPE_ATA);
-    SET_GLOBAL(Drives.drives[driveid].blksize, IDE_SECTOR_SIZE);
+    SET_GLOBAL(Drives.drives[driveid].blksize, DISK_SECTOR_SIZE);
 
     SET_GLOBAL(Drives.drives[driveid].pchs.cylinders, buffer[1]);
     SET_GLOBAL(Drives.drives[driveid].pchs.heads, buffer[3]);
diff --git a/src/block.c b/src/block.c
index c24e118..10ddcfc 100644
--- a/src/block.c
+++ b/src/block.c
@@ -255,7 +255,7 @@
  ****************************************************************/
 
 // Execute a disk_op request.
-static int
+int
 process_op(struct disk_op_s *op)
 {
     u8 type = GET_GLOBAL(Drives.drives[op->driveid].type);
@@ -268,6 +268,8 @@
         return process_atapi_op(op);
     case DTYPE_RAMDISK:
         return process_ramdisk_op(op);
+    case DTYPE_CDEMU:
+        return process_cdemu_op(op);
     default:
         op->count = 0;
         return DISK_RET_EPARAM;
diff --git a/src/cdrom.c b/src/cdrom.c
index 1801d22..67d7016 100644
--- a/src/cdrom.c
+++ b/src/cdrom.c
@@ -1,4 +1,4 @@
-// 16bit code to access cdrom drives.
+// Support for booting from cdroms (the "El Torito" spec).
 //
 // Copyright (C) 2008,2009  Kevin O'Connor <kevin@koconnor.net>
 // Copyright (C) 2002  MandrakeSoft S.A.
@@ -16,85 +16,113 @@
  * CD emulation
  ****************************************************************/
 
-static void
-cdemu_wp(struct bregs *regs, u8 driveid)
+static int
+cdemu_read(struct disk_op_s *op)
 {
-    disk_ret(regs, DISK_RET_EWRITEPROTECT);
-}
-
-static void
-cdemu_1302(struct bregs *regs, u8 driveid)
-{
-    cdemu_access(regs, driveid, CMD_READ);
-}
-
-static void
-cdemu_1304(struct bregs *regs, u8 driveid)
-{
-    cdemu_access(regs, driveid, CMD_VERIFY);
-}
-
-// read disk drive parameters
-static void
-cdemu_1308(struct bregs *regs, u8 driveid)
-{
-    u16 ebda_seg = get_ebda_seg();
-    u16 nlc   = GET_EBDA2(ebda_seg, cdemu.lchs.cylinders) - 1;
-    u16 nlh   = GET_EBDA2(ebda_seg, cdemu.lchs.heads) - 1;
-    u16 nlspt = GET_EBDA2(ebda_seg, cdemu.lchs.spt);
-
-    regs->al = 0x00;
-    regs->bl = 0x00;
-    regs->ch = nlc & 0xff;
-    regs->cl = ((nlc >> 2) & 0xc0) | (nlspt & 0x3f);
-    regs->dh = nlh;
-    // FIXME ElTorito Various. should send the real count of drives 1 or 2
-    // FIXME ElTorito Harddisk. should send the HD count
-    regs->dl = 0x02;
-    u8 media = GET_EBDA2(ebda_seg, cdemu.media);
-    if (media <= 3)
-        regs->bl = media * 2;
-
-    regs->es = SEG_BIOS;
-    regs->di = (u32)&diskette_param_table2;
-
-    disk_ret(regs, DISK_RET_SUCCESS);
-}
-
-void
-cdemu_13(struct bregs *regs)
-{
-    //debug_stub(regs);
-
     u16 ebda_seg = get_ebda_seg();
     u8 driveid = GET_EBDA2(ebda_seg, cdemu.emulated_driveid);
+    struct disk_op_s dop;
+    dop.driveid = driveid;
+    dop.command = op->command;
+    dop.lba = GET_EBDA2(ebda_seg, cdemu.ilba) + op->lba / 4;
 
-    switch (regs->ah) {
-    case 0x02: cdemu_1302(regs, driveid); break;
-    case 0x04: cdemu_1304(regs, driveid); break;
-    case 0x08: cdemu_1308(regs, driveid); break;
+    int count = op->count;
+    op->count = 0;
+    u8 *cdbuf_far = (void*)offsetof(struct extended_bios_data_area_s, cdemu_buf);
 
-    case 0x03:
-    case 0x05:
-        cdemu_wp(regs, driveid);
-        break;
-
-    // These functions are the same as standard CDROM.
-    case 0x00:
-    case 0x01:
-    case 0x09:
-    case 0x0c:
-    case 0x0d:
-    case 0x10:
-    case 0x11:
-    case 0x14:
-    case 0x15:
-    case 0x16:
-        disk_13(regs, driveid);
-        break;
-
-    default:   disk_13XX(regs, driveid); break;
+    if (op->lba & 3) {
+        // Partial read of first block.
+        dop.count = 1;
+        dop.buf_fl = MAKE_FLATPTR(ebda_seg, cdbuf_far);
+        int ret = process_op(&dop);
+        if (ret)
+            return ret;
+        u8 thiscount = 4 - (op->lba & 3);
+        if (thiscount > count)
+            thiscount = count;
+        count -= thiscount;
+        memcpy_far(FLATPTR_TO_SEG(op->buf_fl)
+                   , (void*)FLATPTR_TO_OFFSET(op->buf_fl)
+                   , ebda_seg, cdbuf_far + (op->lba & 3) * 512
+                   , thiscount * 512);
+        op->buf_fl += thiscount * 512;
+        op->count += thiscount;
+        dop.lba++;
     }
+
+    if (count > 3) {
+        // Read n number of regular blocks.
+        dop.count = count / 4;
+        dop.buf_fl = op->buf_fl;
+        int ret = process_op(&dop);
+        op->count += dop.count * 4;
+        if (ret)
+            return ret;
+        u8 thiscount = count & ~3;
+        count &= 3;
+        op->buf_fl += thiscount * 512;
+        dop.lba += thiscount / 4;
+    }
+
+    if (count) {
+        // Partial read on last block.
+        dop.count = 1;
+        dop.buf_fl = MAKE_FLATPTR(ebda_seg, cdbuf_far);
+        int ret = process_op(&dop);
+        if (ret)
+            return ret;
+        u8 thiscount = count;
+        memcpy_far(FLATPTR_TO_SEG(op->buf_fl)
+                   , (void*)FLATPTR_TO_OFFSET(op->buf_fl)
+                   , ebda_seg, cdbuf_far, thiscount * 512);
+        op->count += thiscount;
+    }
+
+    return DISK_RET_SUCCESS;
+}
+
+int
+process_cdemu_op(struct disk_op_s *op)
+{
+    if (!CONFIG_CDROM_EMU)
+        return 0;
+
+    switch (op->command) {
+    case CMD_READ:
+        return cdemu_read(op);
+    case CMD_WRITE:
+    case CMD_FORMAT:
+        return DISK_RET_EWRITEPROTECT;
+    case CMD_VERIFY:
+    case CMD_RESET:
+    case CMD_SEEK:
+    case CMD_ISREADY:
+        return DISK_RET_SUCCESS;
+    default:
+        op->count = 0;
+        return DISK_RET_EPARAM;
+    }
+}
+
+int cdemu_driveid VAR16VISIBLE;
+
+void
+cdemu_setup()
+{
+    if (!CONFIG_CDROM_EMU)
+        return;
+
+    int driveid = Drives.drivecount;
+    if (driveid >= ARRAY_SIZE(Drives.drives)) {
+        cdemu_driveid = -1;
+        return;
+    }
+    Drives.drivecount++;
+    cdemu_driveid = driveid;
+    memset(&Drives.drives[driveid], 0, sizeof(Drives.drives[0]));
+    Drives.drives[driveid].type = DTYPE_CDEMU;
+    Drives.drives[driveid].blksize = DISK_SECTOR_SIZE;
+    Drives.drives[driveid].sectors = (u64)-1;
 }
 
 struct eltorito_s {
@@ -329,7 +357,7 @@
     }
 
     // Emulation of a floppy/harddisk requested
-    if (! CONFIG_CDROM_EMU)
+    if (! CONFIG_CDROM_EMU || cdemu_driveid < 0)
         return 13;
 
     // Set emulated drive id and increase bios installed hardware
diff --git a/src/disk.c b/src/disk.c
index b021c40..4ebccee 100644
--- a/src/disk.c
+++ b/src/disk.c
@@ -43,38 +43,23 @@
 #define DISK_STUB(regs)                         \
     __disk_stub((regs), __LINE__, __func__)
 
-// Obtain the requested disk lba from an old-style chs request.
-static int
-legacy_lba(struct bregs *regs, u16 lchs_seg, struct chs_s *lchs_far)
+static void
+fillLCHS(u8 driveid, u16 *nlc, u16 *nlh, u16 *nlspt)
 {
-    u8 count = regs->al;
-    u16 cylinder = regs->ch | ((((u16)regs->cl) << 2) & 0x300);
-    u16 sector = regs->cl & 0x3f;
-    u16 head = regs->dh;
-
-    if (count > 128 || count == 0 || sector == 0) {
-        dprintf(1, "int13_harddisk: function %02x, parameter out of range!\n"
-                , regs->ah);
-        disk_ret(regs, DISK_RET_EPARAM);
-        return -1;
+    if (CONFIG_CDROM_EMU && driveid == GET_GLOBAL(cdemu_driveid)) {
+        // Emulated drive - get info from ebda.  (It's not possible to
+        // populate the geometry directly in the driveid because the
+        // geometry is only known after the bios segment is made
+        // read-only).
+        u16 ebda_seg = get_ebda_seg();
+        *nlc = GET_EBDA2(ebda_seg, cdemu.lchs.cylinders);
+        *nlh = GET_EBDA2(ebda_seg, cdemu.lchs.heads);
+        *nlspt = GET_EBDA2(ebda_seg, cdemu.lchs.spt);
+        return;
     }
-
-    u16 nlc = GET_FARVAR(lchs_seg, lchs_far->cylinders);
-    u16 nlh = GET_FARVAR(lchs_seg, lchs_far->heads);
-    u16 nlspt = GET_FARVAR(lchs_seg, lchs_far->spt);
-
-    // sanity check on cyl heads, sec
-    if (cylinder >= nlc || head >= nlh || sector > nlspt) {
-        dprintf(1, "int13_harddisk: function %02x, parameters out of"
-                " range %04x/%04x/%04x!\n"
-                , regs->ah, cylinder, head, sector);
-        disk_ret(regs, DISK_RET_EPARAM);
-        return -1;
-    }
-
-    // translate lchs to lba
-    return (((((u32)cylinder * (u32)nlh) + (u32)head) * (u32)nlspt)
-            + (u32)sector - 1);
+    *nlc = GET_GLOBAL(Drives.drives[driveid].lchs.cylinders);
+    *nlh = GET_GLOBAL(Drives.drives[driveid].lchs.heads);
+    *nlspt = GET_GLOBAL(Drives.drives[driveid].lchs.spt);
 }
 
 // Perform read/write/verify using old-style chs accesses
@@ -84,11 +69,36 @@
     struct disk_op_s dop;
     dop.driveid = driveid;
     dop.command = command;
-    int lba = legacy_lba(regs, get_global_seg(), &Drives.drives[driveid].lchs);
-    if (lba < 0)
+
+    u8 count = regs->al;
+    u16 cylinder = regs->ch | ((((u16)regs->cl) << 2) & 0x300);
+    u16 sector = regs->cl & 0x3f;
+    u16 head = regs->dh;
+
+    if (count > 128 || count == 0 || sector == 0) {
+        dprintf(1, "int13_harddisk: function %02x, parameter out of range!\n"
+                , regs->ah);
+        disk_ret(regs, DISK_RET_EPARAM);
         return;
-    dop.lba = lba;
-    dop.count = regs->al;
+    }
+    dop.count = count;
+
+    u16 nlc, nlh, nlspt;
+    fillLCHS(driveid, &nlc, &nlh, &nlspt);
+
+    // sanity check on cyl heads, sec
+    if (cylinder >= nlc || head >= nlh || sector > nlspt) {
+        dprintf(1, "int13_harddisk: function %02x, parameters out of"
+                " range %04x/%04x/%04x!\n"
+                , regs->ah, cylinder, head, sector);
+        disk_ret(regs, DISK_RET_EPARAM);
+        return;
+    }
+
+    // translate lchs to lba
+    dop.lba = (((((u32)cylinder * (u32)nlh) + (u32)head) * (u32)nlspt)
+               + (u32)sector - 1);
+
     dop.buf_fl = MAKE_FLATPTR(regs->es, regs->bx);
 
     int status = send_disk_op(&dop);
@@ -98,72 +108,6 @@
     disk_ret(regs, status);
 }
 
-// Perform cdemu read/verify
-void
-cdemu_access(struct bregs *regs, u8 driveid, u16 command)
-{
-    struct disk_op_s dop;
-    dop.driveid = driveid;
-    dop.command = command;
-    u16 ebda_seg = get_ebda_seg();
-    int vlba = legacy_lba(
-        regs, ebda_seg
-        , (void*)offsetof(struct extended_bios_data_area_s, cdemu.lchs));
-    if (vlba < 0)
-        return;
-    dop.lba = GET_EBDA2(ebda_seg, cdemu.ilba) + vlba / 4;
-    u8 count = regs->al;
-    u8 *cdbuf_far = (void*)offsetof(struct extended_bios_data_area_s, cdemu_buf);
-    u8 *dest_far = (void*)(regs->bx+0);
-    regs->al = 0;
-    int status = DISK_RET_SUCCESS;
-
-    if (vlba & 3) {
-        dop.count = 1;
-        dop.buf_fl = MAKE_FLATPTR(ebda_seg, cdbuf_far);
-        status = send_disk_op(&dop);
-        if (status)
-            goto fail;
-        u8 thiscount = 4 - (vlba & 3);
-        if (thiscount > count)
-            thiscount = count;
-        count -= thiscount;
-        memcpy_far(regs->es, dest_far
-                   , ebda_seg, cdbuf_far + (vlba & 3) * 512
-                   , thiscount * 512);
-        dest_far += thiscount * 512;
-        regs->al += thiscount;
-        dop.lba++;
-    }
-
-    if (count > 3) {
-        dop.count = count / 4;
-        dop.buf_fl = MAKE_FLATPTR(regs->es, dest_far);
-        status = send_disk_op(&dop);
-        regs->al += dop.count * 4;
-        if (status)
-            goto fail;
-        u8 thiscount = count & ~3;
-        count &= 3;
-        dest_far += thiscount * 512;
-        dop.lba += thiscount / 4;
-    }
-
-    if (count) {
-        dop.count = 1;
-        dop.buf_fl = MAKE_FLATPTR(ebda_seg, cdbuf_far);
-        status = send_disk_op(&dop);
-        if (status)
-            goto fail;
-        u8 thiscount = count;
-        memcpy_far(regs->es, dest_far, ebda_seg, cdbuf_far, thiscount * 512);
-        regs->al += thiscount;
-    }
-
-fail:
-    disk_ret(regs, status);
-}
-
 // Perform read/write/verify using new-style "int13ext" accesses.
 static void
 extended_access(struct bregs *regs, u8 driveid, u16 command)
@@ -249,8 +193,8 @@
 {
     DISK_STUB(regs);
 
-    u16 nlh = GET_GLOBAL(Drives.drives[driveid].lchs.heads);
-    u16 nlspt = GET_GLOBAL(Drives.drives[driveid].lchs.spt);
+    u16 nlc, nlh, nlspt;
+    fillLCHS(driveid, &nlc, &nlh, &nlspt);
 
     u8 num_sectors = regs->al;
     u8 head        = regs->dh;
@@ -274,16 +218,21 @@
 static void
 disk_1308(struct bregs *regs, u8 driveid)
 {
+    u16 ebda_seg = get_ebda_seg();
     // Get logical geometry from table
-    u16 nlc = GET_GLOBAL(Drives.drives[driveid].lchs.cylinders) - 1;
-    u16 nlh = GET_GLOBAL(Drives.drives[driveid].lchs.heads) - 1;
-    u16 nlspt = GET_GLOBAL(Drives.drives[driveid].lchs.spt);
+    u16 nlc, nlh, nlspt;
+    fillLCHS(driveid, &nlc, &nlh, &nlspt);
+    nlc--;
+    nlh--;
     u8 count;
     if (regs->dl < EXTSTART_HD) {
         // Floppy
         count = GET_GLOBAL(Drives.floppycount);
 
-        regs->bx = GET_GLOBAL(Drives.drives[driveid].floppy_type);
+        if (CONFIG_CDROM_EMU && driveid == GET_GLOBAL(cdemu_driveid))
+            regs->bx = GET_EBDA2(ebda_seg, cdemu.media) * 2;
+        else
+            regs->bx = GET_GLOBAL(Drives.drives[driveid].floppy_type);
 
         // set es & di to point to 11 byte diskette param table in ROM
         regs->es = SEG_BIOS;
@@ -298,6 +247,16 @@
         return;
     }
 
+    if (CONFIG_CDROM_EMU && GET_EBDA2(ebda_seg, cdemu.active)) {
+        u8 emudrive = GET_EBDA2(ebda_seg, cdemu.emulated_extdrive);
+        if (((emudrive ^ regs->dl) & 0x80) == 0)
+            // Note extra drive due to emulation.
+            count++;
+        if (regs->dl < EXTSTART_HD && count > 2)
+            // Max of two floppy drives.
+            count = 2;
+    }
+
     regs->al = 0;
     regs->ch = nlc & 0xff;
     regs->cl = ((nlc >> 2) & 0xc0) | (nlspt & 0x3f);
@@ -368,9 +327,8 @@
     // Hard drive
 
     // Get logical geometry from table
-    u16 nlc   = GET_GLOBAL(Drives.drives[driveid].lchs.cylinders);
-    u16 nlh   = GET_GLOBAL(Drives.drives[driveid].lchs.heads);
-    u16 nlspt = GET_GLOBAL(Drives.drives[driveid].lchs.spt);
+    u16 nlc, nlh, nlspt;
+    fillLCHS(driveid, &nlc, &nlh, &nlspt);
 
     // Compute sector count seen by int13
     u32 lba = (u32)(nlc - 1) * (u32)nlh * (u32)nlspt;
@@ -725,13 +683,13 @@
     }
 }
 
-void
+static void
 disk_13XX(struct bregs *regs, u8 driveid)
 {
     disk_ret(regs, DISK_RET_EPARAM);
 }
 
-void
+static void
 disk_13(struct bregs *regs, u8 driveid)
 {
     //debug_stub(regs);
@@ -866,7 +824,13 @@
         if (GET_EBDA2(ebda_seg, cdemu.active)) {
             u8 emudrive = GET_EBDA2(ebda_seg, cdemu.emulated_extdrive);
             if (extdrive == emudrive) {
-                cdemu_13(regs);
+                int cdemuid = GET_GLOBAL(cdemu_driveid);
+                if (regs->ah > 0x16) {
+                    // Only old-style commands supported.
+                    disk_13XX(regs, cdemuid);
+                    return;
+                }
+                disk_13(regs, cdemuid);
                 return;
             }
             if (extdrive < EXTSTART_CD && ((emudrive ^ extdrive) & 0x80) == 0)
diff --git a/src/disk.h b/src/disk.h
index 4c3f8cd..28aeda3 100644
--- a/src/disk.h
+++ b/src/disk.h
@@ -185,11 +185,15 @@
     u64 sectors;      // Total sectors count
 };
 
+#define DISK_SECTOR_SIZE  512
+#define CDROM_SECTOR_SIZE 2048
+
 #define DTYPE_NONE     0x00
 #define DTYPE_FLOPPY   0x01
 #define DTYPE_ATA      0x02
 #define DTYPE_ATAPI    0x03
 #define DTYPE_RAMDISK  0x04
+#define DTYPE_CDEMU    0x05
 
 #define TRANSLATION_NONE  0
 #define TRANSLATION_LBA   1
@@ -226,6 +230,7 @@
 void map_hd_drive(int driveid);
 void map_cd_drive(int driveid);
 void describe_drive(int driveid);
+int process_op(struct disk_op_s *op);
 int send_disk_op(struct disk_op_s *op);
 void drive_setup();
 
@@ -238,14 +243,10 @@
 int process_floppy_op(struct disk_op_s *op);
 void floppy_tick();
 
-// disk.c
-void disk_13(struct bregs *regs, u8 driveid);
-void disk_13XX(struct bregs *regs, u8 driveid);
-void cdemu_access(struct bregs *regs, u8 driveid, u16 command);
-
 // cdrom.c
-void cdrom_13(struct bregs *regs, u8 driveid);
-void cdemu_13(struct bregs *regs);
+extern int cdemu_driveid;
+int process_cdemu_op(struct disk_op_s *op);
+void cdemu_setup();
 void cdemu_134b(struct bregs *regs);
 int cdrom_boot(int cdid);
 
diff --git a/src/floppy.c b/src/floppy.c
index 2489507..922a2f5 100644
--- a/src/floppy.c
+++ b/src/floppy.c
@@ -14,7 +14,6 @@
 #include "pic.h" // eoi_pic1
 #include "bregs.h" // struct bregs
 
-#define FLOPPY_SECTOR_SIZE 512
 #define FLOPPY_SIZE_CODE 0x02 // 512 byte sectors
 #define FLOPPY_DATALEN 0xff   // Not used - because size code is 0x02
 #define FLOPPY_MOTOR_TICKS 37 // ~2 seconds
@@ -104,9 +103,9 @@
     memset(&Drives.drives[driveid], 0, sizeof(Drives.drives[0]));
     Drives.drives[driveid].cntl_id = floppyid;
     Drives.drives[driveid].type = driver;
-    Drives.drives[driveid].blksize = FLOPPY_SECTOR_SIZE;
+    Drives.drives[driveid].blksize = DISK_SECTOR_SIZE;
     Drives.drives[driveid].floppy_type = ftype;
-    Drives.drives[driveid].sectors = (u16)-1;
+    Drives.drives[driveid].sectors = (u64)-1;
 
     memcpy(&Drives.drives[driveid].lchs, &FloppyInfo[ftype].chs
            , sizeof(FloppyInfo[ftype].chs));
@@ -150,7 +149,7 @@
     int i;
     for (i=1; i<ARRAY_SIZE(FloppyInfo); i++) {
         struct chs_s *c = &FloppyInfo[i].chs;
-        if (c->cylinders * c->heads * c->spt * FLOPPY_SECTOR_SIZE == size)
+        if (c->cylinders * c->heads * c->spt * DISK_SECTOR_SIZE == size)
             return i;
     }
     return -1;
@@ -432,7 +431,7 @@
     data[7] = FLOPPY_GAPLEN;
     data[8] = FLOPPY_DATALEN;
 
-    res = floppy_cmd(op, op->count * FLOPPY_SECTOR_SIZE, data, 9);
+    res = floppy_cmd(op, op->count * DISK_SECTOR_SIZE, data, 9);
     if (res)
         goto fail;
 
@@ -473,7 +472,7 @@
     data[7] = FLOPPY_GAPLEN;
     data[8] = FLOPPY_DATALEN;
 
-    res = floppy_cmd(op, op->count * FLOPPY_SECTOR_SIZE, data, 9);
+    res = floppy_cmd(op, op->count * DISK_SECTOR_SIZE, data, 9);
     if (res)
         goto fail;
 
diff --git a/src/post.c b/src/post.c
index 7edd1f6..0cedb08 100644
--- a/src/post.c
+++ b/src/post.c
@@ -187,6 +187,7 @@
     boot_setup();
 
     drive_setup();
+    cdemu_setup();
     floppy_setup();
     ata_setup();
     ramdisk_setup();
diff --git a/src/ramdisk.c b/src/ramdisk.c
index c6672a7..83aa7c4 100644
--- a/src/ramdisk.c
+++ b/src/ramdisk.c
@@ -10,8 +10,6 @@
 #include "biosvar.h" // GET_GLOBAL
 #include "bregs.h" // struct bregs
 
-#define RAMDISK_SECTOR_SIZE 512
-
 void
 describe_ramdisk(int driveid)
 {
@@ -59,7 +57,7 @@
 ramdisk_copy(struct disk_op_s *op, int iswrite)
 {
     u32 offset = GET_GLOBAL(Drives.drives[op->driveid].cntl_id);
-    offset += (u32)op->lba * RAMDISK_SECTOR_SIZE;
+    offset += (u32)op->lba * DISK_SECTOR_SIZE;
     u64 opd = GDT_DATA | GDT_LIMIT(0xfffff) | GDT_BASE((u32)op->buf_fl);
     u64 ramd = GDT_DATA | GDT_LIMIT(0xfffff) | GDT_BASE(offset);
 
@@ -79,7 +77,7 @@
     br.ah = 0x87;
     br.es = GET_SEG(SS);
     br.si = (u32)gdt;
-    br.cx = op->count * RAMDISK_SECTOR_SIZE / 2;
+    br.cx = op->count * DISK_SECTOR_SIZE / 2;
     call16_int(0x15, &br);
 
     if (br.flags & F_CF)