fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

fdc: Add an FDC device

Hampa Hug 5523dd28 c7f8c3af

+411 -1
+10
Makefile.dep
··· 1914 1914 src/devices/device.o: src/devices/device.c \ 1915 1915 src/devices/device.h 1916 1916 1917 + src/devices/fdc.o: src/devices/fdc.c \ 1918 + src/chipset/82xx/e8272.h \ 1919 + src/config.h \ 1920 + src/devices/block/blkfdc.h \ 1921 + src/devices/block/block.h \ 1922 + src/devices/block/pfdc.h \ 1923 + src/devices/device.h \ 1924 + src/devices/fdc.h \ 1925 + src/devices/memory.h 1926 + 1917 1927 src/devices/memory.o: src/devices/memory.c \ 1918 1928 src/devices/memory.h 1919 1929
+2 -1
src/devices/Makefile.inc
··· 5 5 DIRS += $(rel) 6 6 DIST += $(rel)/Makefile.inc 7 7 8 - DEV_BAS := ata device memory nvram parport pci pci-ata serport slip 8 + DEV_BAS := ata device fdc memory nvram parport pci pci-ata serport slip 9 9 DEV_SRC := $(foreach f,$(DEV_BAS),$(rel)/$(f).c) 10 10 DEV_OBJ := $(foreach f,$(DEV_BAS),$(rel)/$(f).o) 11 11 DEV_HDR := $(foreach f,$(DEV_BAS),$(rel)/$(f).h) ··· 15 15 16 16 $(rel)/ata.o: $(rel)/ata.c 17 17 $(rel)/device.o: $(rel)/device.c 18 + $(rel)/fdc.o: $(rel)/fdc.c 18 19 $(rel)/memory.o: $(rel)/memory.c 19 20 $(rel)/nvram.o: $(rel)/nvram.c 20 21 $(rel)/parport.o: $(rel)/parport.c
+4
src/devices/device.c
··· 63 63 64 64 void dev_del (device_t *dev) 65 65 { 66 + if (dev == NULL) { 67 + return; 68 + } 69 + 66 70 if (dev->del != NULL) { 67 71 dev->del (dev); 68 72 }
+335
src/devices/fdc.c
··· 1 + /***************************************************************************** 2 + * pce * 3 + *****************************************************************************/ 4 + 5 + /***************************************************************************** 6 + * File name: src/devices/fdc.c * 7 + * Created: 2007-09-06 by Hampa Hug <hampa@hampa.ch> * 8 + * Copyright: (C) 2007-2010 Hampa Hug <hampa@hampa.ch> * 9 + *****************************************************************************/ 10 + 11 + /***************************************************************************** 12 + * This program is free software. You can redistribute it and / or modify it * 13 + * under the terms of the GNU General Public License version 2 as published * 14 + * by the Free Software Foundation. * 15 + * * 16 + * This program is distributed in the hope that it will be useful, but * 17 + * WITHOUT ANY WARRANTY, without even the implied warranty of * 18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * 19 + * Public License for more details. * 20 + *****************************************************************************/ 21 + 22 + 23 + #include <stdlib.h> 24 + #include <string.h> 25 + 26 + #include <devices/fdc.h> 27 + #include <devices/block/blkfdc.h> 28 + 29 + 30 + /* 31 + * This is the glue code between the 8272 FDC, block devices and 32 + * the rest of the emulator. 33 + */ 34 + 35 + 36 + static 37 + struct { 38 + unsigned v1; 39 + unsigned v2; 40 + } errmap[] = { 41 + { PCE_BLK_FDC_NO_ID, E8272_ERR_NO_ID }, 42 + { PCE_BLK_FDC_NO_DATA, E8272_ERR_NO_DATA }, 43 + { PCE_BLK_FDC_CRC_ID, E8272_ERR_CRC_ID }, 44 + { PCE_BLK_FDC_CRC_DATA, E8272_ERR_CRC_DATA }, 45 + { PCE_BLK_FDC_DATALEN, E8272_ERR_DATALEN }, 46 + { PCE_BLK_FDC_WPROT, E8272_ERR_WPROT }, 47 + { 0, 0 } 48 + }; 49 + 50 + 51 + static void dev_fdc_del_dev (device_t *dev); 52 + 53 + 54 + /* 55 + * Map an error code from PCE_BLK_FDC_* to E8272_ERR_*. 56 + */ 57 + static 58 + unsigned dev_fdc_map_error (unsigned err) 59 + { 60 + unsigned i; 61 + unsigned ret; 62 + 63 + ret = 0; 64 + 65 + i = 0; 66 + 67 + while (errmap[i].v1 != 0) { 68 + if (err & errmap[i].v1) { 69 + err &= ~errmap[i].v1; 70 + ret |= errmap[i].v2; 71 + } 72 + 73 + i += 1; 74 + } 75 + 76 + if (err) { 77 + ret |= E8272_ERR_OTHER; 78 + } 79 + 80 + return (ret); 81 + } 82 + 83 + static 84 + unsigned dev_fdc_block_read (dev_fdc_t *fdc, void *buf, unsigned *cnt, 85 + unsigned d, unsigned pc, unsigned ph, unsigned ps, unsigned s) 86 + { 87 + unsigned ret, err; 88 + disk_t *dsk; 89 + 90 + dsk = dsks_get_disk (fdc->dsks, fdc->drive[d & 3]); 91 + 92 + if (dsk == NULL) { 93 + *cnt = 0; 94 + return (E8272_ERR_NO_DATA); 95 + } 96 + 97 + if (dsk_get_type (dsk) != PCE_DISK_FDC) { 98 + if (*cnt < 512) { 99 + *cnt = 0; 100 + return (E8272_ERR_OTHER); 101 + } 102 + 103 + if (dsk_read_chs (dsk, buf, pc, ph, s, 1)) { 104 + *cnt = 0; 105 + return (E8272_ERR_NO_DATA); 106 + } 107 + 108 + *cnt = 512; 109 + 110 + return (0); 111 + } 112 + 113 + err = dsk_fdc_read_chs (dsk->ext, buf, cnt, pc, ph, ps, 1); 114 + 115 + ret = dev_fdc_map_error (err); 116 + 117 + return (ret); 118 + } 119 + 120 + static 121 + unsigned dev_fdc_block_write (dev_fdc_t *fdc, void *buf, unsigned *cnt, 122 + unsigned d, unsigned pc, unsigned ph, unsigned ps, unsigned s) 123 + { 124 + unsigned err, ret; 125 + disk_t *dsk; 126 + 127 + dsk = dsks_get_disk (fdc->dsks, fdc->drive[d & 3]); 128 + 129 + if (dsk == NULL) { 130 + *cnt = 0; 131 + return (E8272_ERR_NO_DATA); 132 + } 133 + 134 + if (dsk_get_type (dsk) != PCE_DISK_FDC) { 135 + if (*cnt != 512) { 136 + return (E8272_ERR_OTHER); 137 + } 138 + 139 + if (dsk_write_chs (dsk, buf, pc, ph, s, 1)) { 140 + *cnt = 0; 141 + return (E8272_ERR_OTHER); 142 + } 143 + 144 + return (0); 145 + } 146 + 147 + err = dsk_fdc_write_chs (dsk->ext, buf, cnt, pc, ph, ps, 1); 148 + 149 + ret = dev_fdc_map_error (err); 150 + 151 + return (ret); 152 + } 153 + 154 + static 155 + int dev_fdc_block_fmt (dev_fdc_t *fdc, 156 + unsigned d, 157 + unsigned pc, unsigned ph, unsigned ps, 158 + unsigned lc, unsigned lh, unsigned ls, unsigned ln, 159 + unsigned fill) 160 + { 161 + unsigned cnt; 162 + disk_t *dsk; 163 + unsigned char buf[512]; 164 + 165 + dsk = dsks_get_disk (fdc->dsks, fdc->drive[d & 3]); 166 + 167 + if (dsk == NULL) { 168 + return (E8272_ERR_NO_DATA); 169 + } 170 + 171 + cnt = 128 << ln; 172 + 173 + if (dsk_get_type (dsk) != PCE_DISK_FDC) { 174 + if (cnt != 512) { 175 + return (E8272_ERR_OTHER); 176 + } 177 + 178 + memset (buf, fill, 512); 179 + 180 + if (dsk_write_chs (dsk, buf, pc, ph, ps + 1, 1)) { 181 + return (E8272_ERR_OTHER); 182 + } 183 + 184 + return (0); 185 + } 186 + 187 + if (ps == 0) { 188 + dsk_fdc_erase_track (dsk->ext, pc, ph); 189 + } 190 + 191 + if (dsk_fdc_format_sector (dsk->ext, pc, ph, lc, lh, ls, cnt, fill)) { 192 + return (E8272_ERR_OTHER); 193 + } 194 + 195 + return (0); 196 + } 197 + 198 + static 199 + int dev_fdc_block_rdid (dev_fdc_t *fdc, 200 + unsigned d, unsigned pc, unsigned ph, unsigned ps, 201 + unsigned *lc, unsigned *lh, unsigned *ls, unsigned *ln) 202 + { 203 + unsigned cnt; 204 + disk_t *dsk; 205 + unsigned char buf[512]; 206 + 207 + dsk = dsks_get_disk (fdc->dsks, fdc->drive[d & 3]); 208 + 209 + if (dsk == NULL) { 210 + return (1); 211 + } 212 + 213 + if (dsk_get_type (dsk) != PCE_DISK_FDC) { 214 + if (dsk_read_chs (dsk, buf, pc, ph, ps + 1, 1)) { 215 + return (1); 216 + } 217 + 218 + *lc = pc; 219 + *lh = ph; 220 + *ls = ps + 1; 221 + *ln = 2; 222 + 223 + return (0); 224 + } 225 + 226 + if (dsk_fdc_read_id (dsk->ext, pc, ph, ps, lc, lh, ls, &cnt)) { 227 + return (1); 228 + } 229 + 230 + *ln = 0; 231 + 232 + while (cnt > 128) { 233 + cnt >>= 1; 234 + *ln += 1; 235 + } 236 + 237 + return (0); 238 + } 239 + 240 + 241 + static 242 + void dev_fdc_clock (dev_fdc_t *fdc, unsigned n) 243 + { 244 + e8272_clock (&fdc->e8272, n); 245 + } 246 + 247 + dev_fdc_t *dev_fdc_new (unsigned long addr) 248 + { 249 + unsigned i; 250 + dev_fdc_t *fdc; 251 + 252 + fdc = malloc (sizeof (dev_fdc_t)); 253 + 254 + if (fdc == NULL) { 255 + return (NULL); 256 + } 257 + 258 + dev_init (&fdc->dev, fdc, "fdc"); 259 + 260 + fdc->dev.del = dev_fdc_del_dev; 261 + fdc->dev.clock = (void *) dev_fdc_clock; 262 + 263 + e8272_init (&fdc->e8272); 264 + 265 + e8272_set_block_read_fct (&fdc->e8272, fdc, dev_fdc_block_read); 266 + e8272_set_block_write_fct (&fdc->e8272, fdc, dev_fdc_block_write); 267 + e8272_set_block_fmt_fct (&fdc->e8272, fdc, dev_fdc_block_fmt); 268 + e8272_set_block_rdid_fct (&fdc->e8272, fdc, dev_fdc_block_rdid); 269 + 270 + mem_blk_init (&fdc->blk, addr, 8, 0); 271 + 272 + mem_blk_set_fct (&fdc->blk, &fdc->e8272, 273 + e8272_get_uint8, NULL, NULL, 274 + e8272_set_uint8, NULL, NULL 275 + ); 276 + 277 + for (i = 0; i < 4; i++) { 278 + fdc->drive[i] = 0xffff; 279 + } 280 + 281 + return (fdc); 282 + } 283 + 284 + void dev_fdc_del (dev_fdc_t *fdc) 285 + { 286 + if (fdc != NULL) { 287 + mem_blk_free (&fdc->blk); 288 + e8272_free (&fdc->e8272); 289 + 290 + free (fdc); 291 + } 292 + } 293 + 294 + static 295 + void dev_fdc_del_dev (device_t *dev) 296 + { 297 + dev_fdc_del (dev->ext); 298 + } 299 + 300 + void dev_fdc_mem_add_io (dev_fdc_t *fdc, memory_t *io) 301 + { 302 + mem_add_blk (io, &fdc->blk, 0); 303 + } 304 + 305 + void dev_fdc_mem_rmv_io (dev_fdc_t *fdc, memory_t *io) 306 + { 307 + mem_rmv_blk (io, &fdc->blk); 308 + } 309 + 310 + 311 + void dev_fdc_reset (dev_fdc_t *fdc) 312 + { 313 + e8272_reset (&fdc->e8272); 314 + } 315 + 316 + void dev_fdc_set_disks (dev_fdc_t *fdc, disks_t *dsks) 317 + { 318 + fdc->dsks = dsks; 319 + } 320 + 321 + void dev_fdc_set_drive (dev_fdc_t *fdc, unsigned fdcdrv, unsigned drive) 322 + { 323 + if (fdcdrv < 4) { 324 + fdc->drive[fdcdrv] = drive; 325 + } 326 + } 327 + 328 + unsigned dev_fdc_get_drive (dev_fdc_t *fdc, unsigned fdcdrv) 329 + { 330 + if (fdcdrv < 4) { 331 + return (fdc->drive[fdcdrv]); 332 + } 333 + 334 + return (0xffff); 335 + }
+60
src/devices/fdc.h
··· 1 + /***************************************************************************** 2 + * pce * 3 + *****************************************************************************/ 4 + 5 + /***************************************************************************** 6 + * File name: src/devices/fdc.h * 7 + * Created: 2007-09-06 by Hampa Hug <hampa@hampa.ch> * 8 + * Copyright: (C) 2007-2010 Hampa Hug <hampa@hampa.ch> * 9 + *****************************************************************************/ 10 + 11 + /***************************************************************************** 12 + * This program is free software. You can redistribute it and / or modify it * 13 + * under the terms of the GNU General Public License version 2 as published * 14 + * by the Free Software Foundation. * 15 + * * 16 + * This program is distributed in the hope that it will be useful, but * 17 + * WITHOUT ANY WARRANTY, without even the implied warranty of * 18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * 19 + * Public License for more details. * 20 + *****************************************************************************/ 21 + 22 + 23 + #ifndef PCE_DEVICES_FDC_H 24 + #define PCE_DEVICES_FDC_H 1 25 + 26 + 27 + #include <devices/device.h> 28 + #include <devices/memory.h> 29 + #include <devices/block/block.h> 30 + 31 + #include <chipset/82xx/e8272.h> 32 + 33 + 34 + typedef struct { 35 + device_t dev; 36 + e8272_t e8272; 37 + 38 + mem_blk_t blk; 39 + 40 + disks_t *dsks; 41 + unsigned drive[4]; 42 + } dev_fdc_t; 43 + 44 + 45 + dev_fdc_t *dev_fdc_new (unsigned long addr); 46 + void dev_fdc_del (dev_fdc_t *fdc); 47 + 48 + void dev_fdc_mem_add_io (dev_fdc_t *fdc, memory_t *io); 49 + void dev_fdc_mem_rmv_io (dev_fdc_t *fdc, memory_t *io); 50 + 51 + void dev_fdc_reset (dev_fdc_t *fdc); 52 + 53 + void dev_fdc_set_disks (dev_fdc_t *fdc, disks_t *dsks); 54 + 55 + void dev_fdc_set_drive (dev_fdc_t *fdc, unsigned fdcdrv, unsigned drive); 56 + 57 + unsigned dev_fdc_get_drive (dev_fdc_t *fdc, unsigned fdcdrv); 58 + 59 + 60 + #endif