libfusefdc: reformatted UDI i/o code
[zymosis.git] / src / libfusefdc / upd_fdc.h
blobc00061a1f74ff092b9a99215070f511377a0c8ff
1 /* upd_fdc.h: NEC floppy disk controller emulation
2 Copyright (c) 2003-2015 Stuart Brady, Fredrick Meunier, Philip Kendall,
3 Gergely Szasz
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 Author contact information:
21 Philip: philip-fuse@shadowmagic.org.uk
23 Stuart: stuart.brady@gmail.com
26 #ifndef FUSE_UPD_FDC_H
27 #define FUSE_UPD_FDC_H
29 #include <stdint.h>
31 #include "fdd.h"
34 typedef enum upd_type_t {
35 UPD765A = 0,
36 UPD765B,
37 } upd_type_t;
40 typedef enum upd_clock_t {
41 UPD_CLOCK_4MHZ = 0,
42 UPD_CLOCK_8MHZ,
43 } upd_clock_t;
46 typedef enum upd_scan_t {
47 UPD_SCAN_EQ = 0,
48 UPD_SCAN_LO,
49 UPD_SCAN_HI,
50 } upd_scan_t;
53 typedef enum upd_cmd_id_t {
54 /* ----v computer READ at execution phase*/
55 UPD_CMD_READ_DATA = 0, /* (non)deleted */
56 UPD_CMD_READ_DIAG,
57 /* ----v computer WRITE at execution phase*/
58 UPD_CMD_WRITE_DATA, /* (non)deleted */
59 UPD_CMD_WRITE_ID, /* :) format */
60 UPD_CMD_SCAN, /* equal/low-or-equal/high-or-equal */
61 /* ----v NO data transfer at execution phase */
62 UPD_CMD_READ_ID,
63 /* ----v NO RW head contact */
64 UPD_CMD_RECALIBRATE,
65 UPD_CMD_SENSE_INT,
66 UPD_CMD_SPECIFY,
67 UPD_CMD_SENSE_DRIVE,
68 UPD_CMD_VERSION,
69 UPD_CMD_SEEK,
70 UPD_CMD_INVALID,
71 } upd_cmd_id_t;
74 typedef struct upd_cmd_t {
75 upd_cmd_id_t id; /* command ID */
76 uint8_t mask; /* && mask */
77 uint8_t value; /* == value */
78 int cmd_length; /* command length */
79 int res_length; /* result length */
80 } upd_cmd_t;
83 typedef enum upd_intrq_t {
84 UPD_INTRQ_NONE = 0,
85 UPD_INTRQ_RESULT,
86 UPD_INTRQ_EXE,
87 UPD_INTRQ_READY,
88 UPD_INTRQ_SEEK,
89 } upd_intrq_t;
92 typedef struct upd_fdc {
93 fdd_t *current_drive;
94 fdd_t *drive[4]; /* UPD765 control 4 drives */
96 upd_type_t type; /* UPD765A UPD765B */
97 upd_clock_t clock; /* clock rate ( 4/8 MHz ) */
99 int stp_rate; /* stepping rate ms */
100 int hut_time; /* head unload time ms */
101 int hld_time; /* head load time ms */
102 int non_dma; /* operating mode */
103 int first_rw; /* first sector alway read/write even EOT < R */
105 int spin_cycles;
106 fdd_dir_t direction; /* 0 = spindlewards, 1 = rimwards */
107 upd_intrq_t intrq; /* last INTRQ status */
108 int datarq; /* DRQ line status */
110 enum upd_fdc_state {
111 UPD_FDC_STATE_CMD = 0,
112 UPD_FDC_STATE_EXE,
113 UPD_FDC_STATE_RES,
114 } state;
116 int id_track;
117 int id_head;
118 int id_sector;
119 int id_length; /* sector length code 0, 1, 2, 3 */
120 int sector_length; /* sector length from length code */
121 int ddam; /* read a deleted data mark */
122 int rev; /* revolution counter */
123 int head_load; /* head state */
124 int read_id; /* searching an IDAM */
126 enum upd_fdc_am_type {
127 UPD_FDC_AM_NONE = 0,
128 UPD_FDC_AM_ID,
129 } id_mark;
131 unsigned int last_sector_read; /* for Speedlock 'random' sector hack */
132 int speedlock; /* for Speedlock 'random' sector hack, -1 -> disable */
134 /* state during transfer */
135 int data_offset;
137 int cycle; /* read/write cycle num */
138 int del_data; /* READ/WRITE deleted data */
139 int mt; /* multitrack operations */
140 int mf; /* MFM mode */
141 int sk; /* skip deleted/not deleted data */
142 int hd; /* physical head address */
143 int us; /* unit select 0-3 */
144 int pcn[4]; /* present cylinder numbers */
145 int ncn[4]; /* new cylinder numbers */
146 int rec[4]; /* recalibrate store pcns */
147 int seek[4]; /* seek status for 4 drive */
148 int seek_age[4]; /* order of overlapped seeks for 4 drive */
149 int rlen; /* expected record length */
150 upd_scan_t scan; /* SCAN type: eq/lo/hi */
152 const upd_cmd_t *cmd; /* current command */
154 uint8_t command_register; /* command register */
155 uint8_t data_register[9]; /* data registers */
156 uint8_t main_status; /* main status register */
157 uint8_t status_register[4]; /* status registers */
159 uint8_t sense_int_res[2]; /* result bytes for SENSE INTERRUPT */
161 uint16_t crc; /* to hold crc */
163 void (*set_intrq) (struct upd_fdc *f);
164 void (*reset_intrq) (struct upd_fdc *f);
165 void (*set_datarq) (struct upd_fdc *f);
166 void (*reset_datarq) (struct upd_fdc *f);
167 } upd_fdc;
170 void upd_fdc_init_events (void);
172 /* allocate an fdc */
173 upd_fdc *upd_fdc_alloc_fdc (upd_type_t type, upd_clock_t clock);
174 void upd_fdc_alloc_fdc_set_clock (upd_fdc *f, upd_clock_t clock);
175 void upd_fdc_master_reset (upd_fdc *f);
177 uint8_t upd_fdc_read_status (upd_fdc *f);
179 uint8_t upd_fdc_read_data (upd_fdc *f);
180 void upd_fdc_write_data (upd_fdc *f, uint8_t b);
182 void upd_fdc_eject (upd_fdc *f, int driveidx);
185 #endif