Move cdrom code to its own file (cdrom.c).
authorKevin O'Connor <kevin@koconnor.net>
Wed, 5 Mar 2008 00:56:41 +0000 (19:56 -0500)
committerKevin O'Connor <kevin@koconnor.net>
Wed, 5 Mar 2008 00:56:41 +0000 (19:56 -0500)
Makefile
src/cdrom.c [new file with mode: 0644]
src/disk.c
src/disk.h

index 629b92e2747465691fe701b8feeff938833cde9c..1376a2798d22c52a4b82fa52310f678a1d650af4 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -9,7 +9,7 @@ OUT=out/
 
 # Source files
 SRC16=floppy.c disk.c system.c clock.c serial.c kbd.c mouse.c output.c \
-      boot.c ata.c
+      boot.c ata.c cdrom.c
 SRC32=post.c output.c
 TABLESRC=font.c cbt.c floppy_dbt.c
 
diff --git a/src/cdrom.c b/src/cdrom.c
new file mode 100644 (file)
index 0000000..9782e27
--- /dev/null
@@ -0,0 +1,279 @@
+// 16bit code to access cdrom drives.
+//
+// Copyright (C) 2008  Kevin O'Connor <kevin@koconnor.net>
+// Copyright (C) 2002  MandrakeSoft S.A.
+//
+// This file may be distributed under the terms of the GNU GPLv3 license.
+
+#include "disk.h" // cdrom_13
+#include "util.h" // memset
+#include "ata.h" // ATA_CMD_READ_SECTORS
+
+
+/****************************************************************
+ * CDROM functions
+ ****************************************************************/
+
+// read disk drive size
+static void
+cdrom_1315(struct bregs *regs, u8 device)
+{
+    disk_ret(regs, DISK_RET_EADDRNOTFOUND);
+}
+
+// lock
+static void
+cdrom_134500(struct bregs *regs, u8 device)
+{
+    u8 locks = GET_EBDA(ata.devices[device].lock);
+    if (locks == 0xff) {
+        regs->al = 1;
+        disk_ret(regs, DISK_RET_ETOOMANYLOCKS);
+        return;
+    }
+    SET_EBDA(ata.devices[device].lock, locks + 1);
+    regs->al = 1;
+    disk_ret(regs, DISK_RET_SUCCESS);
+}
+
+// unlock
+static void
+cdrom_134501(struct bregs *regs, u8 device)
+{
+    u8 locks = GET_EBDA(ata.devices[device].lock);
+    if (locks == 0x00) {
+        regs->al = 0;
+        disk_ret(regs, DISK_RET_ENOTLOCKED);
+        return;
+    }
+    locks--;
+    SET_EBDA(ata.devices[device].lock, locks);
+    regs->al = (locks ? 1 : 0);
+    disk_ret(regs, DISK_RET_SUCCESS);
+}
+
+// status
+static void
+cdrom_134502(struct bregs *regs, u8 device)
+{
+    u8 locks = GET_EBDA(ata.devices[device].lock);
+    regs->al = (locks ? 1 : 0);
+    disk_ret(regs, DISK_RET_SUCCESS);
+}
+
+static void
+cdrom_1345XX(struct bregs *regs, u8 device)
+{
+    disk_ret(regs, DISK_RET_EPARAM);
+}
+
+// IBM/MS lock/unlock drive
+static void
+cdrom_1345(struct bregs *regs, u8 device)
+{
+    switch (regs->al) {
+    case 0x00: cdrom_134500(regs, device); break;
+    case 0x01: cdrom_134501(regs, device); break;
+    case 0x02: cdrom_134502(regs, device); break;
+    default:   cdrom_1345XX(regs, device); break;
+    }
+}
+
+// IBM/MS eject media
+static void
+cdrom_1346(struct bregs *regs, u8 device)
+{
+    u8 locks = GET_EBDA(ata.devices[device].lock);
+    if (locks != 0) {
+        disk_ret(regs, DISK_RET_ELOCKED);
+        return;
+    }
+
+    // FIXME should handle 0x31 no media in device
+    // FIXME should handle 0xb5 valid request failed
+
+    // Call removable media eject
+    struct bregs br;
+    memset(&br, 0, sizeof(br));
+    br.ah = 0x52;
+    call16_int(0x15, &br);
+
+    if (br.ah || br.flags & F_CF) {
+        disk_ret(regs, DISK_RET_ELOCKED);
+        return;
+    }
+    disk_ret(regs, DISK_RET_SUCCESS);
+}
+
+// IBM/MS extended media change
+static void
+cdrom_1349(struct bregs *regs, u8 device)
+{
+    // always send changed ??
+    regs->ah = DISK_RET_ECHANGED;
+    set_cf(regs, 1);
+}
+
+static void
+cdrom_ok(struct bregs *regs, u8 device)
+{
+    disk_ret(regs, DISK_RET_SUCCESS);
+}
+
+static void
+cdrom_wp(struct bregs *regs, u8 device)
+{
+    disk_ret(regs, DISK_RET_EWRITEPROTECT);
+}
+
+void
+cdrom_13(struct bregs *regs, u8 device)
+{
+    //debug_stub(regs);
+
+    switch (regs->ah) {
+    case 0x15: cdrom_1315(regs, device); break;
+    case 0x45: cdrom_1345(regs, device); break;
+    case 0x46: cdrom_1346(regs, device); break;
+    case 0x49: cdrom_1349(regs, device); break;
+
+    // These functions are the same as for hard disks
+    case 0x01:
+    case 0x41:
+    case 0x42:
+    case 0x44:
+    case 0x47:
+    case 0x48:
+    case 0x4e:
+        disk_13(regs, device);
+        break;
+
+    // all these functions return SUCCESS
+    case 0x00: // disk controller reset
+    case 0x09: // initialize drive parameters
+    case 0x0c: // seek to specified cylinder
+    case 0x0d: // alternate disk reset
+    case 0x10: // check drive ready
+    case 0x11: // recalibrate
+    case 0x14: // controller internal diagnostic
+    case 0x16: // detect disk change
+        cdrom_ok(regs, device);
+        break;
+
+    // all these functions return disk write-protected
+    case 0x03: // write disk sectors
+    case 0x05: // format disk track
+    case 0x43: // IBM/MS extended write
+        cdrom_wp(regs, device);
+        break;
+
+    default:   disk_13XX(regs, device); break;
+    }
+}
+
+
+/****************************************************************
+ * CD emulation
+ ****************************************************************/
+
+// read disk sectors
+static void
+cdemu_1302(struct bregs *regs, u8 device)
+{
+    emu_access(regs, device, ATA_CMD_READ_SECTORS);
+}
+
+// verify disk sectors
+static void
+cdemu_1304(struct bregs *regs, u8 device)
+{
+    emu_access(regs, device, 0);
+}
+
+// read disk drive parameters
+static void
+cdemu_1308(struct bregs *regs, u8 device)
+{
+    u16 nlc   = GET_EBDA(cdemu.vdevice.cylinders) - 1;
+    u16 nlh   = GET_EBDA(cdemu.vdevice.heads) - 1;
+    u16 nlspt = GET_EBDA(cdemu.vdevice.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_EBDA(cdemu.media);
+    if (media <= 3)
+        regs->bl = media * 2;
+
+    regs->es = SEG_BIOS;
+    regs->di = (u16)&diskette_param_table2;
+
+    disk_ret(regs, DISK_RET_SUCCESS);
+}
+
+void
+cdemu_13(struct bregs *regs)
+{
+    //debug_stub(regs);
+
+    u8 device  = GET_EBDA(cdemu.controller_index) * 2;
+    device += GET_EBDA(cdemu.device_spec);
+
+    switch (regs->ah) {
+    case 0x02: cdemu_1302(regs, device); break;
+    case 0x04: cdemu_1304(regs, device); break;
+    case 0x08: cdemu_1308(regs, device); break;
+    // XXX - All other calls get passed to standard CDROM functions.
+    default: cdrom_13(regs, device); break;
+    }
+}
+
+struct eltorito_s {
+    u8 size;
+    u8 media;
+    u8 emulated_drive;
+    u8 controller_index;
+    u32 ilba;
+    u16 device_spec;
+    u16 buffer_segment;
+    u16 load_segment;
+    u16 sector_count;
+    u8 cylinders;
+    u8 sectors;
+    u8 heads;
+};
+
+#define SET_INT13ET(regs,var,val)                                      \
+    SET_FARVAR((regs)->ds, ((struct eltorito_s*)((regs)->si+0))->var, (val))
+
+// ElTorito - Terminate disk emu
+void
+cdemu_134b(struct bregs *regs)
+{
+    // FIXME ElTorito Hardcoded
+    SET_INT13ET(regs, size, 0x13);
+    SET_INT13ET(regs, media, GET_EBDA(cdemu.media));
+    SET_INT13ET(regs, emulated_drive, GET_EBDA(cdemu.emulated_drive));
+    SET_INT13ET(regs, controller_index, GET_EBDA(cdemu.controller_index));
+    SET_INT13ET(regs, ilba, GET_EBDA(cdemu.ilba));
+    SET_INT13ET(regs, device_spec, GET_EBDA(cdemu.device_spec));
+    SET_INT13ET(regs, buffer_segment, GET_EBDA(cdemu.buffer_segment));
+    SET_INT13ET(regs, load_segment, GET_EBDA(cdemu.load_segment));
+    SET_INT13ET(regs, sector_count, GET_EBDA(cdemu.sector_count));
+    SET_INT13ET(regs, cylinders, GET_EBDA(cdemu.vdevice.cylinders));
+    SET_INT13ET(regs, sectors, GET_EBDA(cdemu.vdevice.spt));
+    SET_INT13ET(regs, heads, GET_EBDA(cdemu.vdevice.heads));
+
+    // If we have to terminate emulation
+    if (regs->al == 0x00) {
+        // FIXME ElTorito Various. Should be handled accordingly to spec
+        SET_EBDA(cdemu.active, 0x00); // bye bye
+    }
+
+    disk_ret(regs, DISK_RET_SUCCESS);
+}
index 832eee1c0043d2787a46534afc5996e923bae81e..7c3e417af81a921f136a8531d7547d090e8d133a 100644 (file)
  * Helper functions
  ****************************************************************/
 
-static inline void
-disk_ret(struct bregs *regs, u8 code)
-{
-    regs->ah = code;
-    SET_BDA(disk_last_status, code);
-    set_cf(regs, code);
-}
-
 #define DISK_STUB(regs) do {                    \
         struct bregs *__regs = (regs);          \
         debug_stub(__regs);                     \
@@ -109,7 +101,7 @@ basic_access(struct bregs *regs, u8 device, u16 command)
     disk_ret(regs, DISK_RET_SUCCESS);
 }
 
-static void
+void
 emu_access(struct bregs *regs, u8 device, u16 command)
 {
     u16 nbsectors   = regs->al;
@@ -181,7 +173,7 @@ emu_access(struct bregs *regs, u8 device, u16 command)
     disk_ret(regs, DISK_RET_SUCCESS);
 }
 
-static void
+void
 extended_access(struct bregs *regs, u8 device, u16 command)
 {
     u16 count = GET_INT13EXT(regs, count);
@@ -641,14 +633,14 @@ disk_134e(struct bregs *regs, u8 device)
     }
 }
 
-static void
+void
 disk_13XX(struct bregs *regs, u8 device)
 {
     debug_stub(regs);
     disk_ret(regs, DISK_RET_EPARAM);
 }
 
-static void
+void
 disk_13(struct bregs *regs, u8 device)
 {
     //debug_stub(regs);
@@ -686,269 +678,6 @@ disk_13(struct bregs *regs, u8 device)
 }
 
 
-/****************************************************************
- * CDROM functions
- ****************************************************************/
-
-// read disk drive size
-static void
-cdrom_1315(struct bregs *regs, u8 device)
-{
-    disk_ret(regs, DISK_RET_EADDRNOTFOUND);
-}
-
-// lock
-static void
-cdrom_134500(struct bregs *regs, u8 device)
-{
-    u8 locks = GET_EBDA(ata.devices[device].lock);
-    if (locks == 0xff) {
-        regs->al = 1;
-        disk_ret(regs, DISK_RET_ETOOMANYLOCKS);
-        return;
-    }
-    SET_EBDA(ata.devices[device].lock, locks + 1);
-    regs->al = 1;
-    disk_ret(regs, DISK_RET_SUCCESS);
-}
-
-// unlock
-static void
-cdrom_134501(struct bregs *regs, u8 device)
-{
-    u8 locks = GET_EBDA(ata.devices[device].lock);
-    if (locks == 0x00) {
-        regs->al = 0;
-        disk_ret(regs, DISK_RET_ENOTLOCKED);
-        return;
-    }
-    locks--;
-    SET_EBDA(ata.devices[device].lock, locks);
-    regs->al = (locks ? 1 : 0);
-    disk_ret(regs, DISK_RET_SUCCESS);
-}
-
-// status
-static void
-cdrom_134502(struct bregs *regs, u8 device)
-{
-    u8 locks = GET_EBDA(ata.devices[device].lock);
-    regs->al = (locks ? 1 : 0);
-    disk_ret(regs, DISK_RET_SUCCESS);
-}
-
-static void
-cdrom_1345XX(struct bregs *regs, u8 device)
-{
-    disk_ret(regs, DISK_RET_EPARAM);
-}
-
-// IBM/MS lock/unlock drive
-static void
-cdrom_1345(struct bregs *regs, u8 device)
-{
-    switch (regs->al) {
-    case 0x00: cdrom_134500(regs, device); break;
-    case 0x01: cdrom_134501(regs, device); break;
-    case 0x02: cdrom_134502(regs, device); break;
-    default:   cdrom_1345XX(regs, device); break;
-    }
-}
-
-// IBM/MS eject media
-static void
-cdrom_1346(struct bregs *regs, u8 device)
-{
-    u8 locks = GET_EBDA(ata.devices[device].lock);
-    if (locks != 0) {
-        disk_ret(regs, DISK_RET_ELOCKED);
-        return;
-    }
-
-    // FIXME should handle 0x31 no media in device
-    // FIXME should handle 0xb5 valid request failed
-
-    // Call removable media eject
-    struct bregs br;
-    memset(&br, 0, sizeof(br));
-    br.ah = 0x52;
-    call16_int(0x15, &br);
-
-    if (br.ah || br.flags & F_CF) {
-        disk_ret(regs, DISK_RET_ELOCKED);
-        return;
-    }
-    disk_ret(regs, DISK_RET_SUCCESS);
-}
-
-// IBM/MS extended media change
-static void
-cdrom_1349(struct bregs *regs, u8 device)
-{
-    // always send changed ??
-    regs->ah = DISK_RET_ECHANGED;
-    set_cf(regs, 1);
-}
-
-static void
-cdrom_ok(struct bregs *regs, u8 device)
-{
-    disk_ret(regs, DISK_RET_SUCCESS);
-}
-
-static void
-cdrom_wp(struct bregs *regs, u8 device)
-{
-    disk_ret(regs, DISK_RET_EWRITEPROTECT);
-}
-
-static void
-cdrom_13(struct bregs *regs, u8 device)
-{
-    //debug_stub(regs);
-
-    switch (regs->ah) {
-    case 0x15: cdrom_1315(regs, device); break;
-    case 0x45: cdrom_1345(regs, device); break;
-    case 0x46: cdrom_1346(regs, device); break;
-    case 0x49: cdrom_1349(regs, device); break;
-
-    // These functions are the same as for hard disks
-    case 0x01: disk_1301(regs, device); break;
-    case 0x41: disk_1341(regs, device); break;
-    case 0x42: disk_1342(regs, device); break;
-    case 0x44: disk_1344(regs, device); break;
-    case 0x47: disk_1347(regs, device); break;
-    case 0x48: disk_1348(regs, device); break;
-    case 0x4e: disk_134e(regs, device); break;
-
-    // all these functions return SUCCESS
-    case 0x00: cdrom_ok(regs, device); break; // disk controller reset
-    case 0x09: cdrom_ok(regs, device); break; // initialize drive parameters
-    case 0x0c: cdrom_ok(regs, device); break; // seek to specified cylinder
-    case 0x0d: cdrom_ok(regs, device); break; // alternate disk reset
-    case 0x10: cdrom_ok(regs, device); break; // check drive ready
-    case 0x11: cdrom_ok(regs, device); break; // recalibrate
-    case 0x14: cdrom_ok(regs, device); break; // controller internal diagnostic
-    case 0x16: cdrom_ok(regs, device); break; // detect disk change
-
-    // all these functions return disk write-protected
-    case 0x03: cdrom_wp(regs, device); break; // write disk sectors
-    case 0x05: cdrom_wp(regs, device); break; // format disk track
-    case 0x43: cdrom_wp(regs, device); break; // IBM/MS extended write
-
-    default:   disk_13XX(regs, device); break;
-    }
-}
-
-
-/****************************************************************
- * CD emulation
- ****************************************************************/
-
-// read disk sectors
-static void
-cdemu_1302(struct bregs *regs, u8 device)
-{
-    emu_access(regs, device, ATA_CMD_READ_SECTORS);
-}
-
-// verify disk sectors
-static void
-cdemu_1304(struct bregs *regs, u8 device)
-{
-    emu_access(regs, device, 0);
-}
-
-// read disk drive parameters
-static void
-cdemu_1308(struct bregs *regs, u8 device)
-{
-    u16 nlc   = GET_EBDA(cdemu.vdevice.cylinders) - 1;
-    u16 nlh   = GET_EBDA(cdemu.vdevice.heads) - 1;
-    u16 nlspt = GET_EBDA(cdemu.vdevice.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_EBDA(cdemu.media);
-    if (media <= 3)
-        regs->bl = media * 2;
-
-    regs->es = SEG_BIOS;
-    regs->di = (u16)&diskette_param_table2;
-
-    disk_ret(regs, DISK_RET_SUCCESS);
-}
-
-static void
-cdemu_13(struct bregs *regs)
-{
-    //debug_stub(regs);
-
-    u8 device  = GET_EBDA(cdemu.controller_index) * 2;
-    device += GET_EBDA(cdemu.device_spec);
-
-    switch (regs->ah) {
-    case 0x02: cdemu_1302(regs, device); break;
-    case 0x04: cdemu_1304(regs, device); break;
-    case 0x08: cdemu_1308(regs, device); break;
-    // XXX - All other calls get passed to standard CDROM functions.
-    default: cdrom_13(regs, device); break;
-    }
-}
-
-struct eltorito_s {
-    u8 size;
-    u8 media;
-    u8 emulated_drive;
-    u8 controller_index;
-    u32 ilba;
-    u16 device_spec;
-    u16 buffer_segment;
-    u16 load_segment;
-    u16 sector_count;
-    u8 cylinders;
-    u8 sectors;
-    u8 heads;
-};
-
-#define SET_INT13ET(regs,var,val)                                      \
-    SET_FARVAR((regs)->ds, ((struct eltorito_s*)((regs)->si+0))->var, (val))
-
-// ElTorito - Terminate disk emu
-static void
-cdemu_134b(struct bregs *regs)
-{
-    // FIXME ElTorito Hardcoded
-    SET_INT13ET(regs, size, 0x13);
-    SET_INT13ET(regs, media, GET_EBDA(cdemu.media));
-    SET_INT13ET(regs, emulated_drive, GET_EBDA(cdemu.emulated_drive));
-    SET_INT13ET(regs, controller_index, GET_EBDA(cdemu.controller_index));
-    SET_INT13ET(regs, ilba, GET_EBDA(cdemu.ilba));
-    SET_INT13ET(regs, device_spec, GET_EBDA(cdemu.device_spec));
-    SET_INT13ET(regs, buffer_segment, GET_EBDA(cdemu.buffer_segment));
-    SET_INT13ET(regs, load_segment, GET_EBDA(cdemu.load_segment));
-    SET_INT13ET(regs, sector_count, GET_EBDA(cdemu.sector_count));
-    SET_INT13ET(regs, cylinders, GET_EBDA(cdemu.vdevice.cylinders));
-    SET_INT13ET(regs, sectors, GET_EBDA(cdemu.vdevice.spt));
-    SET_INT13ET(regs, heads, GET_EBDA(cdemu.vdevice.heads));
-
-    // If we have to terminate emulation
-    if (regs->al == 0x00) {
-        // FIXME ElTorito Various. Should be handled accordingly to spec
-        SET_EBDA(cdemu.active, 0x00); // bye bye
-    }
-
-    disk_ret(regs, DISK_RET_SUCCESS);
-}
-
-
 /****************************************************************
  * Entry points
  ****************************************************************/
index 93e9756b7fefc96fbeaceb08bf565ea6353854c5..badbb411f4a6fa184d226742424107941154799f 100644 (file)
@@ -93,9 +93,30 @@ struct floppy_ext_dbt_s {
     u8 drive_type;
 };
 
+// Helper function for setting up a return code.
+static inline void
+disk_ret(struct bregs *regs, u8 code)
+{
+    regs->ah = code;
+    SET_BDA(disk_last_status, code);
+    set_cf(regs, code);
+}
+
 // floppy.c
 extern struct floppy_ext_dbt_s diskette_param_table2;
 void floppy_13(struct bregs *regs, u8 drive);
 void floppy_tick();
 
+// disk.c
+void emu_access(struct bregs *regs, u8 device, u16 command);
+void extended_access(struct bregs *regs, u8 device, u16 command);
+void disk_13(struct bregs *regs, u8 device);
+void disk_13XX(struct bregs *regs, u8 device);
+
+// cdrom.c
+void cdrom_13(struct bregs *regs, u8 device);
+void cdemu_13(struct bregs *regs);
+void cdemu_134b(struct bregs *regs);
+
+
 #endif // disk.h