Files

141 lines
5.1 KiB
C
Raw Permalink Normal View History

2023-03-17 11:40:49 +00:00
// -----------------------------------------------------------------------------
// 3.5"/5.25" DD/HD Disk controller for Arduino
// Copyright (C) 2021 David Hansel
//
// 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 3 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
// -----------------------------------------------------------------------------
#ifndef ARDUINOFDC_H
#define ARDUINOFDC_H
#include "Arduino.h"
// return status for readSector/writeSector and formatDisk functions
#define S_OK 0 // no error
#define S_NOTINIT 1 // ArduinoFDC.begin() was not called
#define S_NOTREADY 2 // Drive is not ready (no disk or power)
#define S_NOSYNC 3 // No sync marks found
#define S_NOHEADER 4 // Sector header not found
#define S_INVALIDID 5 // Sector data record has invalid id
#define S_CRC 6 // Sector data checksum error
#define S_NOTRACK0 7 // No track0 signal
#define S_VERIFY 8 // Verify after write failed
#define S_READONLY 9 // Attempt to write to a write-protected disk
class ArduinoFDCClass
{
public:
enum DriveType {
DT_5_DD, // 5.25" double density (360 KB)
DT_5_DDonHD, // 5.25" double density disk in high density drive (360 KB)
DT_5_HD, // 5.25" high density (1.2 MB)
DT_3_DD, // 3.5" double density (720 KB)
DT_3_HD // 3.5" high density (1.44 MB)
};
enum DensityPinMode {
DP_DISCONNECT = 0, // density pin disconnected (set to INPUT mode)
DP_OUTPUT_LOW_FOR_HD, // density pin goes LOW for high density disk
DP_OUTPUT_LOW_FOR_DD // density pin goes LOW for double density disk
};
ArduinoFDCClass();
// Initialize pins used for controlling the disk drive
void begin(enum DriveType driveAType = DT_3_HD, enum DriveType driveBType = DT_3_HD);
// Release pins used for controlling the disk drive
void end();
// Select drive A(0) or B(1).
bool selectDrive(byte drive);
// Returns which drive is currently selected, A (0) or B (1)
byte selectedDrive() const;
// set the drive type for the currently selected drive
void setDriveType(enum DriveType type);
// get the type of the currently selected drive
enum DriveType getDriveType() const;
// returns true if a disk is detected in the drive
bool haveDisk() const;
// returns true if the disk is write protected
bool isWriteProtected() const;
// get number of tracks for the currently selected drive
byte numTracks() const;
// get number of sectors for the currently selected drive
byte numSectors() const;
// set the density pin mode for the currently selected drive
void setDensityPinMode(enum DensityPinMode mode);
// Read a sector from disk,
// buffer MUST have a size of at least 516 bytes.
// IMPORTANT: On successful return, the 512 bytes of sector data
// read will be in buffer[1..512] (NOT: 0..511!)
// See error codes above for possible return values
byte readSector(byte track, byte side, byte sector, byte *buffer);
// Write a sector to disk,
// buffer MUST have a size of at least 516 bytes.
// IMPORTANT: The 512 bytes of sector data to be written
// must be in buffer[1..512] (NOT: 0..511!)
// if "verify" is true then the data will be re-read after writing
// and compared to the data just written.
// See error codes above for possible return values
byte writeSector(byte track, byte side, byte sector, byte *buffer, bool verify);
// Formats a disk
// buffer is needed to store temporary data while formatting and MUST have
// a size of at least 144 bytes.
// All sector data is initialized with 0xF6.
// See error codes above for possible return values
// IMPORTANT: No DOS file system is initialized, i.e. DOS or Windows
// will NOT recognize this as a valid disk
byte formatDisk(byte *buffer, byte fromTrack=0, byte toTrack=255);
// Turn the disk drive motor on. The readSector/writeSector/formatDisk
// functions will turn on the motor automatically if it is not running
// yet. In that case (and ONLY then) they will also turn it off when finished.
void motorOn();
// Turn the disk drive motor off
void motorOff();
// Returns true if the disk drive motor is currently running
bool motorRunning() const;
private:
void driveSelect(bool state) const;
void setDensityPin();
byte getBitLength();
enum DriveType m_driveType[2];
enum DensityPinMode m_densityPinMode[2];
byte m_currentDrive, m_bitLength[2];
bool m_initialized, m_motorState[2];
};
extern ArduinoFDCClass ArduinoFDC;
#endif