1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
|
/* fdd.h: Routines for emulating floppy disk drives
Copyright (c) 2007-2016 Gergely Szasz, Philip Kendall
Copyright (c) 2015 Stuart Brady
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.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Author contact information:
Philip: philip-fuse@shadowmagic.org.uk
*/
#ifndef FUSE_FDD_H
#define FUSE_FDD_H
#include "event.h"
#include "disk.h"
typedef enum fdd_error_t {
FDD_OK = 0,
FDD_GEOM,
FDD_DATA,
FDD_RDONLY,
FDD_NONE, /* FDD not exist (disabled) */
FDD_LAST_ERROR,
} fdd_error_t;
typedef enum fdd_type_t {
FDD_TYPE_NONE = 0, /* FDD not exist/disabled */
FDD_SHUGART, /* head load when selected */
/*
.. In a single drive system (program shunt position
"MX" shorted), with program shunt position "HL"
shorted, Drive Select when activated to a logical
zero level, will load the R/W head against the
diskette enabling contact of the R/W head against
the media. ...
In a multiple drive system (program shunt position
"MX" open), the three input lines (Drive Select 1,
Drive Select 2 and Drive select 3) are provided so
that the using system may select which drive on
the interface is to be used. In this mode of opera-
tion only the drive with its Drive Select line active
will respond to the input lines and gate the output
lines. In addition, the selected drive will load its
R/W head if program shunt position "HL" is
shorted. ...
*/
FDD_IBMPC,
} fdd_type_t;
typedef enum fdd_dir_t {
FDD_STEP_OUT = 0,
FDD_STEP_IN = 1,
} fdd_dir_t;
typedef struct fdd_t {
fdd_type_t type; /* fdd type: Shugart or IBMPC */
int auto_geom; /* change geometry according to loading disk */
int fdd_heads; /* 1 or 2 */
int fdd_cylinders; /* 40/40+/80/80+ */
int tr00; /* track 0 mark */
int index; /* index hole */
int wrprot; /* write protect */
int data; /* read/write to data byte 0x00nn or 0xffnn */
int marks; /* read/write other marks 0x01 -> FM 0x02 -> WEAK */
disk_t disk; /* disk */
int loaded; /* disk loaded */
int upsidedown; /* flipped disk */
int selected; /* Drive Select line active */
int ready; /* some disk drive offer a ready signal */
int dskchg; /* disk change signal */
int hdout; /* High Density signal */
fdd_error_t status;
/* WD/FD 177X may wait for an index or RDY->/RDY or /RDY->RDY
we do not need more, just a subroutine and a pointer to fdc_struct
*/
void ( *fdc_index ) ( void *fdc );
void *fdc; /* if not NULL FDC wait for an index pulse */
/*--private section, fdc may never use it */
int unreadable; /* disk unreadable in this drive */
int do_read_weak;
int c_head; /* current head (side) */
int c_cylinder; /* current cylinder number (0 -> TR00) */
int c_bpt; /* current track length in bytes */
int motoron; /* motor on */
int loadhead; /* head loaded */
int index_pulse; /* 'second' index hole, for index status */
} fdd_t;
typedef struct fdd_params_t {
int enabled;
int heads;
int cylinders;
} fdd_params_t;
extern const fdd_params_t fdd_params[];
void fdd_register_startup( void );
const char *fdd_strerror( int error );
/* initialize the fdd_t struct, and set fdd_heads and cylinders (e.g. 2/83 ) */
int fdd_init( fdd_t *d, fdd_type_t type, const fdd_params_t *dt, int reinit );
/* load the given disk into the fdd. if upsidedown = 1, floppy upsidedown in drive :) */
int fdd_load( fdd_t *d, int upsidedown );
/* unload the disk from fdd */
void fdd_unload( fdd_t *d );
/* set fdd head */
void fdd_set_head( fdd_t *d, int head );
/* step one track according to d->direction direction. set d->tr00 if reach track 0 */
void fdd_step( fdd_t *d, fdd_dir_t direction );
/* set floppy position ( upsidedown or not )*/
void fdd_motoron( fdd_t *d, int on );
/* start (1) or stop (0) spindle motor */
void fdd_head_load( fdd_t *d, int load );
/* load (1) or unload (0) head */
void fdd_select( fdd_t *d, int select );
/* select (1) or unselect (0) FDD */
void fdd_flip( fdd_t *d, int upsidedown );
/* Read the next byte from disk. The byte will go into d->data.
If d->data = 0xffnn then this byte was recorded with different clock 'mark'.
d->idx is set if we reach the 'index hole'. 0x0100 is read if the disk is
unreadable, the motor is not on, or the head is not loaded.
*/
int fdd_read_data( fdd_t *d );
/* Write the next byte to disk. The byte is taken from d->data.
If d->data = 0xffnn then this byte recorded with different clock 'mark'.
d->idx is set if we reach the 'index hole'.
*/
int fdd_write_data( fdd_t *d );
/* set write protect status on loaded disk */
void fdd_wrprot( fdd_t *d, int wrprot );
/* to reach index hole */
void fdd_wait_index_hole( fdd_t *d );
/* set floppy position ( upsidedown or not )*/
void fdd_flip( fdd_t *d, int upsidedown );
#endif /* FUSE_FDD_H */
|