#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...)
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)
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);
}
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;
}
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;
}
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;
}
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;
}
/* 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 */
}
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);
}
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)
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);
}