libfusefdc: reformatted UDI i/o code
[zymosis.git] / src / libfusefdc / beta.c
blob15f6e46247a52bdb7066b727b078408210bd2741
1 /* beta.c: Routines for handling the Beta disk interface
2 Copyright (c) 2004-2016 Stuart Brady, Philip Kendall, Gergely Szasz
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 Author contact information:
20 Philip: philip-fuse@shadowmagic.org.uk
22 Stuart: stuart.brady@gmail.com
25 #ifndef LIBFUSE_DISK_IO_ONLY
27 #include <errno.h>
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <fcntl.h>
31 #include <unistd.h>
32 #include <string.h>
33 #include <strings.h>
34 #include <limits.h>
35 #include <sys/stat.h>
37 #include "../ZXEmuT/emuvars.h"
38 #include "../ZXEmuT/emuevents.h"
40 #include "beta.h"
41 #include "wd_fdc.h"
44 #define ARRAY_SIZE(a) ((sizeof(a)/sizeof(*a)))
46 static uint8_t beta_system_register = 0; /* FDC system register */
48 static wd_fdc *beta_fdc = NULL;
49 static fdd_t beta_drives[BETA_NUM_DRIVES];
52 static const periph_port_t beta_ports[] = {
53 { 0x00ff, 0x001f, beta_sr_read, beta_cr_write },
54 { 0x00ff, 0x003f, beta_tr_read, beta_tr_write },
55 { 0x00ff, 0x005f, beta_sec_read, beta_sec_write },
56 { 0x00ff, 0x007f, beta_dr_read, beta_dr_write },
57 { 0x00ff, 0x00ff, beta_sp_read, beta_sp_write },
58 { 0, 0, NULL, NULL }
63 //==========================================================================
65 // beta_select_drive
67 //==========================================================================
68 static void beta_select_drive (int i) {
69 if (beta_fdc->current_drive != &beta_drives[i&0x03]) {
70 if (beta_fdc->current_drive != NULL) {
71 fdd_select(beta_fdc->current_drive, 0);
73 beta_fdc->current_drive = &beta_drives[i&0x03];
74 fdd_select( beta_fdc->current_drive, 1);
79 //==========================================================================
81 // beta_init
83 //==========================================================================
84 void beta_init (void) {
85 beta_fdc = wd_fdc_alloc_fdc(FD1793, 0, WD_FLAG_BETA128);
86 beta_fdc->current_drive = NULL;
88 for (int i = 0; i < BETA_NUM_DRIVES; ++i) {
89 fdd_t *d = &beta_drives[i];
90 fdd_init(d, FDD_SHUGART, NULL, 0); /* drive geometry 'autodetect' */
91 d->disk.flag = DISK_FLAG_NONE;
93 beta_select_drive(0);
95 beta_fdc->dden = 1;
96 beta_fdc->set_intrq = NULL;
97 beta_fdc->reset_intrq = NULL;
98 beta_fdc->set_datarq = NULL;
99 beta_fdc->reset_datarq = NULL;
103 //==========================================================================
105 // beta_reset
107 //==========================================================================
108 void beta_reset (int hard_reset) {
109 wd_fdc_master_reset(beta_fdc);
110 beta_select_drive(0);
114 //==========================================================================
116 // beta_end
118 //==========================================================================
119 void beta_end (void) {
120 free(beta_fdc);
124 //==========================================================================
126 // beta_sr_read
128 //==========================================================================
129 uint8_t beta_sr_read (uint16_t port) {
130 return wd_fdc_sr_read(beta_fdc);
134 //==========================================================================
136 // beta_cr_write
138 //==========================================================================
139 void beta_cr_write (uint16_t port, uint8_t b) {
140 wd_fdc_cr_write(beta_fdc, b);
144 //==========================================================================
146 // beta_tr_read
148 //==========================================================================
149 uint8_t beta_tr_read (uint16_t port) {
150 return wd_fdc_tr_read(beta_fdc);
154 //==========================================================================
156 // beta_tr_write
158 //==========================================================================
159 void beta_tr_write (uint16_t port, uint8_t b) {
160 wd_fdc_tr_write(beta_fdc, b);
164 //==========================================================================
166 // beta_sec_read
168 //==========================================================================
169 uint8_t beta_sec_read (uint16_t port) {
170 return wd_fdc_sec_read(beta_fdc);
174 //==========================================================================
176 // beta_sec_write
178 //==========================================================================
179 void beta_sec_write (uint16_t port, uint8_t b) {
180 wd_fdc_sec_write(beta_fdc, b);
184 //==========================================================================
186 // beta_dr_read
188 //==========================================================================
189 uint8_t beta_dr_read (uint16_t port) {
190 return wd_fdc_dr_read( beta_fdc );
194 //==========================================================================
196 // beta_dr_write
198 //==========================================================================
199 void beta_dr_write (uint16_t port, uint8_t b) {
200 wd_fdc_dr_write(beta_fdc, b);
204 //==========================================================================
206 // beta_sp_write
208 //==========================================================================
209 void beta_sp_write (uint16_t port, uint8_t b) {
210 /* reset 0x04 and then set it to reset controller */
211 beta_select_drive(b&0x03);
212 /* 0x08 = block hlt, normally set */
213 wd_fdc_set_hlt(beta_fdc, (b&0x08 ? 1 : 0));
214 fdd_set_head(beta_fdc->current_drive, (b&0x10 ? 0 : 1));
215 /* 0x20 = density, reset = FM, set = MFM */
216 beta_fdc->dden = (b&0x20 ? 1 : 0);
217 beta_system_register = b;
221 //==========================================================================
223 // beta_sp_read
225 //==========================================================================
226 uint8_t beta_sp_read (uint16_t port) {
227 uint8_t b = 0;
228 if (beta_fdc->intrq) b |= 0x80;
229 if (beta_fdc->datarq) b |= 0x40;
230 /* we should reset beta_datarq, but we first need to raise it for each byte
231 * transferred in wd_fdc.c */
232 return b;
236 //==========================================================================
238 // beta_disk_eject
240 //==========================================================================
241 void beta_disk_eject (beta_drive_number which) {
242 fdd_t *fdd = beta_get_fdd(which);
243 if (fdd) {
244 fdd_unload(fdd);
245 disk_close(&fdd->disk);
250 //==========================================================================
252 // beta_get_fdd
254 //==========================================================================
255 fdd_t *beta_get_fdd (beta_drive_number which) {
256 return (which >= 0 && which < BETA_NUM_DRIVES ? &beta_drives[which] : NULL);
260 //==========================================================================
262 // beta_get_disk
264 //==========================================================================
265 disk_t *beta_get_disk (beta_drive_number which) {
266 return (which >= 0 && which < BETA_NUM_DRIVES ? &beta_drives[which].disk : NULL);
270 #endif /* LIBFUSE_DISK_IO_ONLY */