// Part of SimCoupe - A SAM Coupe emulator
//
// Floppy.h: W2K/XP/W2K3 direct floppy access using fdrawcmd.sys
//
//  Copyright (c) 1999-2006  Simon Owen
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

#ifndef FLOPPY_H
#define FLOPPY_H

#include "CStream.h"

typedef struct
{
    int sectors;
    BYTE cyl, head;     // physical track location
}
TRACK, *PTRACK;

typedef struct
{
    BYTE cyl, head, sector, size;
    BYTE status;
    BYTE *pbData;
}
SECTOR, *PSECTOR;


class CFloppyStream : public CStream
{
    public:
        CFloppyStream (const char* pcszDevice_, bool fReadOnly_);
        virtual ~CFloppyStream ();

    public:
        static bool IsAvailable ();
        static bool IsRecognised (const char* pcszStream_);

    public:
        void Close ();
        unsigned long ThreadProc ();

    public:
        bool IsOpen () const { return m_hDevice != INVALID_HANDLE_VALUE; }
        bool IsBusy (BYTE* pbStatus_, bool fWait_);

        // The normal stream functions are not used
        bool Rewind () { return false; }
        size_t Read (void*, size_t) { return 0; }
        size_t Write (void*, size_t) { return 0; }

        BYTE StartCommand (BYTE bCommand_, PTRACK pTrack_=NULL, UINT uSector_=0, BYTE *pbData_=NULL);

    protected:
        HANDLE  m_hDevice, m_hThread;   // Floppy device and worker thread handles
        UINT    m_uSectors;             // Regular sector count, or zero for auto-detect (slower)

        BYTE    m_bCommand, m_bStatus;  // Current command and final status

        PTRACK  m_pTrack;               // Track for command
        UINT    m_uSector;              // Zero-based sector for write command
        BYTE   *m_pbData;               // Data to write (since track data is only updated when successful)
};

#endif  // FLOPPY_H
