fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
at master 299 lines 5.7 kB view raw
1/***************************************************************************** 2 * pce * 3 *****************************************************************************/ 4 5/***************************************************************************** 6 * File name: src/drivers/block/blkpce.c * 7 * Created: 2004-11-28 by Hampa Hug <hampa@hampa.ch> * 8 * Copyright: (C) 2004-2012 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 "blkpce.h" 24 25#include <stdlib.h> 26#include <string.h> 27 28 29#define DSK_PCE_MAGIC 0x50494d47UL 30 31 32/* 33 * PCE image file format 34 * 35 * 0 4 Magic (PIMG) 36 * 4 4 version (0) 37 * 8 4 image offset 38 * 12 4 block count 39 * 16 4 cylinders 40 * 20 4 heads 41 * 24 4 sectors 42 * 28 4 block size 43 */ 44 45 46static 47int dsk_pce_read (disk_t *dsk, void *buf, uint32_t i, uint32_t n) 48{ 49 disk_pce_t *img; 50 uint64_t ofs, cnt; 51 52 img = dsk->ext; 53 54 if ((i + n) > img->dsk.blocks) { 55 return (1); 56 } 57 58 ofs = img->blk_ofs + 512 * (uint64_t) i; 59 cnt = 512 * (uint64_t) n; 60 61 if (dsk_read (img->fp, buf, ofs, cnt)) { 62 return (1); 63 } 64 65 return (0); 66} 67 68static 69int dsk_pce_write (disk_t *dsk, const void *buf, uint32_t i, uint32_t n) 70{ 71 disk_pce_t *img; 72 uint64_t ofs, cnt; 73 74 img = dsk->ext; 75 76 if (dsk->readonly) { 77 return (1); 78 } 79 80 if ((i + n) > dsk->blocks) { 81 return (1); 82 } 83 84 ofs = img->blk_ofs + 512 * (uint64_t) i; 85 cnt = 512 * (uint64_t) n; 86 87 if (dsk_write (img->fp, buf, ofs, cnt)) { 88 return (1); 89 } 90 91 fflush (img->fp); 92 93 return (0); 94} 95 96 97static 98int dsk_pce_get_msg (disk_t *dsk, const char *msg, char *val, unsigned max) 99{ 100 return (1); 101} 102 103static 104int dsk_pce_set_msg (disk_t *dsk, const char *msg, const char *val) 105{ 106 if (strcmp (msg, "commit") == 0) { 107 return (0); 108 } 109 110 return (1); 111} 112 113 114static 115void dsk_pce_del (disk_t *dsk) 116{ 117 disk_pce_t *img; 118 119 img = dsk->ext; 120 121 if (img->fp != NULL) { 122 fclose (img->fp); 123 } 124 125 free (img); 126} 127 128disk_t *dsk_pce_open_fp (FILE *fp, int ro) 129{ 130 disk_pce_t *img; 131 uint32_t c, h, s, n; 132 unsigned char buf[32]; 133 134 if (fread (buf, 1, 32, fp) != 32) { 135 return (NULL); 136 } 137 138 if (dsk_get_uint32_be (buf, 0) != DSK_PCE_MAGIC) { 139 return (NULL); 140 } 141 142 /* format version */ 143 if (dsk_get_uint32_be (buf, 4) != 0) { 144 return (NULL); 145 } 146 147 if (dsk_get_uint32_be (buf, 28) != 512) { 148 return (NULL); 149 } 150 151 n = dsk_get_uint32_be (buf, 12); 152 c = dsk_get_uint32_be (buf, 16); 153 h = dsk_get_uint32_be (buf, 20); 154 s = dsk_get_uint32_be (buf, 24); 155 156 img = malloc (sizeof (disk_pce_t)); 157 if (img == NULL) { 158 return (NULL); 159 } 160 161 dsk_init (&img->dsk, img, n, c, h, s); 162 163 dsk_set_type (&img->dsk, PCE_DISK_PCE); 164 165 dsk_set_readonly (&img->dsk, ro); 166 167 img->fp = fp; 168 169 img->dsk.del = dsk_pce_del; 170 img->dsk.read = dsk_pce_read; 171 img->dsk.write = dsk_pce_write; 172 img->dsk.get_msg = dsk_pce_get_msg; 173 img->dsk.set_msg = dsk_pce_set_msg; 174 175 img->blk_ofs = dsk_get_uint32_be (buf, 8); 176 img->blk_size = dsk_get_uint32_be (buf, 28); 177 178 return (&img->dsk); 179} 180 181disk_t *dsk_pce_open (const char *fname, int ro) 182{ 183 disk_t *dsk; 184 FILE *fp; 185 186 if (ro) { 187 fp = fopen (fname, "rb"); 188 } 189 else { 190 fp = fopen (fname, "r+b"); 191 192 if (fp == NULL) { 193 fp = fopen (fname, "rb"); 194 ro = 1; 195 } 196 } 197 198 if (fp == NULL) { 199 return (NULL); 200 } 201 202 dsk = dsk_pce_open_fp (fp, ro); 203 204 if (dsk == NULL) { 205 fclose (fp); 206 return (NULL); 207 } 208 209 dsk_set_fname (dsk, fname); 210 211 return (dsk); 212} 213 214int dsk_pce_create_fp (FILE *fp, uint32_t n, uint32_t c, uint32_t h, uint32_t s, 215 uint32_t ofs) 216{ 217 unsigned char buf[32]; 218 219 if (dsk_adjust_chs (&n, &c, &h, &s)) { 220 return (1); 221 } 222 223 if (ofs < 32) { 224 ofs = 512; 225 } 226 227 dsk_set_uint32_be (buf, 0, DSK_PCE_MAGIC); 228 dsk_set_uint32_be (buf, 4, 0); 229 dsk_set_uint32_be (buf, 8, ofs); 230 dsk_set_uint32_be (buf, 12, n); 231 dsk_set_uint32_be (buf, 16, c); 232 dsk_set_uint32_be (buf, 20, h); 233 dsk_set_uint32_be (buf, 24, s); 234 dsk_set_uint32_be (buf, 28, 512); 235 236 if (dsk_write (fp, buf, 0, 32)) { 237 return (1); 238 } 239 240 if (dsk_set_filesize (fp, ofs + 512 * (uint64_t) n)) { 241 buf[0] = 0; 242 if (dsk_write (fp, buf, ofs + 512 * (uint64_t) n - 1, 1)) { 243 return (1); 244 } 245 } 246 247 return (0); 248} 249 250int dsk_pce_create (const char *fname, uint32_t n, uint32_t c, uint32_t h, uint32_t s, 251 uint32_t ofs) 252{ 253 int r; 254 FILE *fp; 255 256 fp = fopen (fname, "wb"); 257 if (fp == NULL) { 258 return (1); 259 } 260 261 r = dsk_pce_create_fp (fp, n, c, h, s, ofs); 262 263 fclose (fp); 264 265 return (r); 266} 267 268int dsk_pce_probe_fp (FILE *fp) 269{ 270 unsigned char buf[4]; 271 272 if (dsk_read (fp, buf, 0, 4)) { 273 return (0); 274 } 275 276 if (dsk_get_uint32_be (buf, 0) != DSK_PCE_MAGIC) { 277 return (0); 278 } 279 280 return (1); 281} 282 283int dsk_pce_probe (const char *fname) 284{ 285 int r; 286 FILE *fp; 287 288 fp = fopen (fname, "rb"); 289 290 if (fp == NULL) { 291 return (0); 292 } 293 294 r = dsk_pce_probe_fp (fp); 295 296 fclose (fp); 297 298 return (r); 299}