mirror of
https://git.code.sf.net/p/fuse-emulator/fuse
synced 2026-01-27 01:41:34 +03:00
158 lines
5.3 KiB
C
158 lines
5.3 KiB
C
/* 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 */
|