Cleanup handling of interrupt controller (PIC).
[seabios.git] / src / floppy.c
index fc5e43fc106d552e0a8915267a5e285798e41835..efe9592f5927060b1fff17ff502316372529b78f 100644 (file)
@@ -11,6 +11,7 @@
 #include "biosvar.h" // struct bregs
 #include "util.h" // irq_disable
 #include "cmos.h" // inb_cmos
+#include "pic.h" // unmask_pic1
 
 #define DEBUGF1(fmt, args...) bprintf(0, fmt , ##args)
 #define DEBUGF(fmt, args...)
@@ -43,23 +44,36 @@ struct floppy_ext_dbt_s diskette_param_table2 VISIBLE16 = {
 void
 floppy_drive_setup()
 {
+    if (! CONFIG_FLOPPY_SUPPORT)
+        return;
+    dprintf(3, "init floppy drives\n");
     u8 type = inb_cmos(CMOS_FLOPPY_DRIVE_TYPE);
     u8 out = 0;
-    if (type & 0xf0)
+    u8 num_floppies = 0;
+
+    if (type & 0xf0) {
         out |= 0x07;
-    if (type & 0x0f)
+        num_floppies++;
+    }
+    if (type & 0x0f) {
         out |= 0x70;
+        num_floppies++;
+    }
     SET_BDA(floppy_harddisk_info, out);
+
+    // Update equipment word bits for floppy
+    if (num_floppies == 1)
+        // 1 drive, ready for boot
+        SETBITS_BDA(equipment_list_flags, 0x01);
+    else if (num_floppies == 2)
+        // 2 drives, ready for boot
+        SETBITS_BDA(equipment_list_flags, 0x41);
+
     outb(0x02, PORT_DMA1_MASK_REG);
-}
 
-// Oddities:
-//   Return codes vary greatly - AL not cleared consistenlty, BDA return
-//      status not set consistently, sometimes panics.
-//   Extra outb(0x000a, 0x02) in read?
-//   Does not disable interrupts on failure paths.
-//   numfloppies used before set in int_1308
-//   int_1305 verifies track but doesn't use it?
+    // Enable IRQ6 (handle_0e)
+    unmask_pic1(PIC1_IRQ6);
+}
 
 static inline void
 set_diskette_current_cyl(u8 drive, u8 cyl)
@@ -350,12 +364,15 @@ floppy_media_sense(u8 drive)
     return rv;
 }
 
-static inline void
-floppy_ret(struct bregs *regs, u8 code)
+#define floppy_ret(regs, code) \
+    __floppy_ret(__func__, (regs), (code))
+
+void
+__floppy_ret(const char *fname, struct bregs *regs, u8 code)
 {
     SET_BDA(floppy_last_status, code);
     if (code)
-        set_code_fail(regs, code);
+        __set_code_fail(fname, regs, code);
     else
         set_code_success(regs);
 }
@@ -424,7 +441,6 @@ floppy_1302(struct bregs *regs, u8 drive)
 
     if (head > 1 || sector == 0 || num_sectors == 0
         || track > 79 || num_sectors > 72) {
-        BX_INFO("int13_diskette: read/write/verify: parameter out of range\n");
         floppy_fail(regs, DISK_RET_EPARAM);
         return;
     }
@@ -472,7 +488,6 @@ floppy_1303(struct bregs *regs, u8 drive)
 
     if (head > 1 || sector == 0 || num_sectors == 0
         || track > 79 || num_sectors > 72) {
-        BX_INFO("int13_diskette: read/write/verify: parameter out of range\n");
         floppy_fail(regs, DISK_RET_EPARAM);
         return;
     }
@@ -524,7 +539,6 @@ floppy_1304(struct bregs *regs, u8 drive)
 
     if (head > 1 || sector == 0 || num_sectors == 0
         || track > 79 || num_sectors > 72) {
-        BX_INFO("int13_diskette: read/write/verify: parameter out of range\n");
         floppy_fail(regs, DISK_RET_EPARAM);
         return;
     }
@@ -548,7 +562,6 @@ floppy_1305(struct bregs *regs, u8 drive)
     u8 head        = regs->dh;
 
     if (head > 1 || num_sectors == 0 || num_sectors > 18) {
-        BX_INFO("int13_diskette: read/write/verify: parameter out of range\n");
         floppy_fail(regs, DISK_RET_EPARAM);
         return;
     }
@@ -669,7 +682,7 @@ floppy_1308(struct bregs *regs, u8 drive)
 
     /* set es & di to point to 11 byte diskette param table in ROM */
     regs->es = SEG_BIOS;
-    regs->di = (u16)&diskette_param_table2;
+    regs->di = (u32)&diskette_param_table2;
     /* disk status not changed upon success */
 }
 
@@ -705,7 +718,6 @@ floppy_1316(struct bregs *regs, u8 drive)
 static void
 floppy_13XX(struct bregs *regs, u8 drive)
 {
-    BX_INFO("int13_diskette: unsupported AH=%02x\n", regs->ah);
     floppy_ret(regs, DISK_RET_EPARAM);
 }
 
@@ -738,7 +750,7 @@ floppy_13(struct bregs *regs, u8 drive)
 void VISIBLE16
 handle_0e()
 {
-    //debug_isr();
+    debug_isr(DEBUG_ISR_0e);
     if ((inb(PORT_FD_STATUS) & 0xc0) != 0xc0) {
         outb(0x08, PORT_FD_DATA); // sense interrupt status
         while ((inb(PORT_FD_STATUS) & 0xc0) != 0xc0)
@@ -747,7 +759,7 @@ handle_0e()
             inb(PORT_FD_DATA);
         } while ((inb(PORT_FD_STATUS) & 0xc0) == 0xc0);
     }
-    eoi_master_pic();
+    eoi_pic1();
     // diskette interrupt has occurred
     SETBITS_BDA(floppy_recalibration_status, FRS_TIMEOUT);
 }