fdc.c revision 52f16f53a955f5b24bc2132c418a5fffb700f089
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync * VBox storage devices: Floppy disk controller
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync * available from http://www.virtualbox.org. This file is free software;
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync * you can redistribute it and/or modify it under the terms of the GNU
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync * General Public License (GPL) as published by the Free Software
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync * additional information or have any questions.
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync * --------------------------------------------------------------------
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync * This code is based on:
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync * QEMU Floppy disk emulator (Intel 82078)
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync * Copyright (c) 2003 Jocelyn Mayer
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync * Permission is hereby granted, free of charge, to any person obtaining a copy
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync * of this software and associated documentation files (the "Software"), to deal
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync * in the Software without restriction, including without limitation the rights
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync * copies of the Software, and to permit persons to whom the Software is
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync * furnished to do so, subject to the following conditions:
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync * The above copyright notice and this permission notice shall be included in
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync * all copies or substantial portions of the Software.
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync * THE SOFTWARE.
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync/*******************************************************************************
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync* Header Files *
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync*******************************************************************************/
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync ((fdrive_t *)((uintptr_t)(pInterface) - RT_OFFSETOF(fdrive_t, IBase)))
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync ((fdrive_t *)((uintptr_t)(p) - RT_OFFSETOF(fdrive_t, IMountNotify)))
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync#endif /* VBOX */
c28fa006ba669ad8f26ae31d00a338379c04ea1bvboxsync#endif /* !VBOX */
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync/********************************************************/
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync/* debug Floppy devices */
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync/* #define DEBUG_FLOPPY */
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync#else /* !VBOX */
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync RTLogLogger (NULL, NULL, "floppy: %N", fmt, &args); /* %N - nested va_list * type formatting call. */
ad77e3ec3cde24263bc7537575f5cae442bee3b1vboxsync DECLINLINE(void) FLOPPY_DPRINTF(const char *pszFmt, ...) {}
ad77e3ec3cde24263bc7537575f5cae442bee3b1vboxsync#endif /* !VBOX */
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync do { printf("FLOPPY ERROR: %s: " fmt, __func__ , ##args); } while (0)
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync#else /* VBOX */
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync#endif /* VBOX */
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync#endif /* VBOX */
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync/********************************************************/
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync/* Floppy drive emulation */
ad77e3ec3cde24263bc7537575f5cae442bee3b1vboxsync/* Will always be a fixed parameter for us */
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync/* Floppy disk drive emulation */
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsynctypedef enum fdisk_type_t {
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync FDRIVE_DISK_USER = 0x04, /* User defined geometry */
typedef enum fdisk_flags_t {
#ifdef VBOX
typedef struct fdrive_t {
#ifndef VBOX
bool fMediaPresent;
} fdrive_t;
#ifndef VBOX
int enable_seek)
int ret;
ret = 0;
if (!enable_seek) {
return ret;
typedef struct fd_format_t {
const char *str;
} fd_format_t;
#ifndef VBOX
nb_heads = 0;
max_track = 0;
last_sect = 0;
#ifndef VBOX
match = i;
first_match = i;
#ifdef VBOX
#ifdef VBOX
#ifndef VBOX
void *opaque,
unsigned nchan,
FD_DIR_WRITE = 0,
#ifdef VBOX
struct fdctrl_t {
#ifndef VBOX
#ifndef VBOX
int irq_lvl;
int dma_chann;
#ifdef VBOX
return retval;
#ifndef VBOX
#ifndef VBOX
if (!fdctrl)
return NULL;
if (fds[i]) {
if (mem_mapped) {
return fdctrl;
#ifdef VBOX
#ifdef VBOX
for (i = 0; i < MAX_FD; i++)
if (do_irq)
#ifndef VBOX
return retval;
return retval;
return retval;
#ifndef VBOX
if (retval != 0)
return retval;
if (do_irq)
/* Set an error: unimplemented/unknown command */
#ifdef VBOX
int did_seek;
did_seek = 0;
if (did_seek)
int tmp;
int dma_mode;
#ifndef VBOX
#ifndef VBOX
#include <stdio.h>
#include <stdlib.h>
static FILE * f;
size_t n;
exit (0);
exit (0);
#define dump(a,b) do { } while (0)
#ifdef VBOX
void *opaque,
unsigned nchan,
#ifdef VBOX
int rc;
#ifndef VBOX
len = 0;
goto transfer_error;
#ifndef VBOX
case FD_DIR_READ:
#ifdef VBOX
case FD_DIR_WRITE:
#ifdef VBOX
#ifndef VBOX
goto transfer_error;
goto transfer_error;
int ret;
#ifdef VBOX
if (ret == 0) {
goto end_transfer;
goto end_transfer;
if (rel_pos == 0) {
return len;
#ifndef VBOX
len = 0;
goto transfer_error;
#ifndef VBOX
int rc;
case FD_DIR_READ:
#ifdef VBOX
case FD_DIR_WRITE:
#ifdef VBOX
int rc;
goto transfer_error;
goto transfer_error;
int ret;
#ifdef VBOX
if (ret == 0) {
goto end_transfer;
goto end_transfer;
if (rel_pos == 0) {
return len;
#ifdef VBOX
int rc;
if (pos == 0) {
#ifdef VBOX
return retval;
int did_seek;
#ifdef VBOX
did_seek = 0;
#ifdef VBOX
if (ok) {
#ifdef VBOX
int rc;
goto enqueue;
goto enqueue;
goto enqueue;
goto enqueue;
goto enqueue;
goto enqueue;
goto enqueue;
goto enqueue;
switch (value) {
goto enqueue;
goto enqueue;
goto enqueue;
goto enqueue;
goto enqueue;
goto enqueue;
goto enqueue;
goto enqueue;
goto enqueue;
goto enqueue;
goto enqueue;
goto enqueue;
goto enqueue;
goto enqueue;
goto enqueue;
goto enqueue;
#ifndef VBOX
#ifdef VBOX
#ifdef VBOX
void *pvUser,
unsigned cb)
return VINF_SUCCESS;
void *pvUser,
unsigned cb)
return VINF_SUCCESS;
return VERR_IOM_IOPORT_UNUSED;
return NULL;
unsigned iLUN,
return VINF_SUCCESS;
return VERR_PDM_LUN_NOT_FOUND;
return NULL;
int rc;
switch (rc) {
case VERR_ACCESS_DENIED:
return rc;
int rc;
AssertMsgFailed (("Configuration error: cannot attach or detach any but the first two LUNs - iLUN=%u\n",
iLUN));
return VERR_PDM_DEVINS_NO_ATTACH;
return rc;
switch (iLUN) {
int iInstance,
int rc;
bool mem_mapped;
return rc;
return rc;
return rc;
mem_mapped = false;
return rc;
return rc;
return rc;
if (mem_mapped) {
return VERR_NOT_SUPPORTED;
return rc;
return rc;
return rc;
rc));
return rc;
return rc;
return VINF_SUCCESS;
sizeof(fdctrl_t),
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,