38 #include <sys/types.h> 69 static int my_fseek(FILE *
f, off_t offset,
int whence)
72 if (whence == SEEK_SET) {
77 fseek(f, 0, SEEK_SET);
78 while (curoff < offset) {
80 cur_step = offset - curoff;
81 if (cur_step > 2000000000)
82 cur_step = 2000000000;
83 res = fseek(f, cur_step, SEEK_CUR);
90 return fseek(f, offset, whence);
92 return fseeko(f, offset, whence);
111 if (d->
type == type && d->
id ==
id)
128 size_t bitmap_name_len =
strlen(overlay_basename) + 20;
132 snprintf(bitmap_name, bitmap_name_len,
"%s.map", overlay_basename);
135 overlay.
f_data = fopen(overlay_basename, d->
writable?
"r+" :
"r");
136 if (overlay.
f_data == NULL) {
137 perror(overlay_basename);
144 fprintf(stderr,
"Please create the map file first.\n");
171 res = stat(d->
fname, &st);
173 fprintf(stderr,
"[ diskimage_recalc_size(): could not stat " 174 "'%s' ]\n", d->
fname);
208 if (d->
type == type && d->
id ==
id)
227 if (d->
type == type && d->
id ==
id)
247 if (d->
type == type && d->
id ==
id) {
255 fatal(
"diskimage_set_baseoffset(): disk id %i (type %i) not found?\n",
256 id, diskimage_types[type]);
267 int *c,
int *h,
int *s)
272 if (d->
type == type && d->
id ==
id) {
280 fatal(
"diskimage_getchs(): disk id %i (type %i) not found?\n",
281 id, diskimage_types[type]);
301 #define CDROM_SECTOR_SIZE 2048 302 static size_t diskimage_access__cdrom(
struct diskimage *d, off_t offset,
303 unsigned char *buf,
size_t len)
305 off_t aligned_offset;
306 size_t bytes_read, total_copied = 0;
308 off_t buf_ofs, i = 0;
314 my_fseek(d->
f, aligned_offset, SEEK_SET);
322 buf_ofs = offset - aligned_offset;
324 buf[i ++] = cdrom_buf[buf_ofs ++];
330 offset = aligned_offset;
338 static void overlay_set_block_in_use(
struct diskimage *d,
339 int overlay_nr, off_t ofs)
342 off_t bitmap_file_offset = bit_nr / 8;
347 bitmap_file_offset, SEEK_SET);
350 fprintf(stderr,
"Could not seek in bitmap file?" 351 " offset = %lli, read\n", (
long long)bitmap_file_offset);
360 data |= (1 << (bit_nr & 7));
364 bitmap_file_offset, SEEK_SET);
367 fprintf(stderr,
"Could not seek in bitmap file?" 368 " offset = %lli, write\n", (
long long)bitmap_file_offset);
373 fprintf(stderr,
"Could not write to bitmap file. Aborting.\n");
380 static int overlay_has_block(
struct diskimage *d,
int overlay_nr, off_t ofs)
383 off_t bitmap_file_offset = bit_nr / 8;
388 bitmap_file_offset, SEEK_SET);
397 if (data & (1 << (bit_nr & 7)))
410 static size_t fwrite_helper(off_t offset,
unsigned char *buf,
417 int res = my_fseek(d->
f, offset, SEEK_SET);
419 fatal(
"[ diskimage__internal_access(): fseek() failed" 420 " on disk id %i \n", d->
id);
424 return fwrite(buf, 1, len, d->
f);
428 fatal(
"TODO: overlay access (write), len not multiple of " 429 "overlay block size. not yet implemented.\n");
430 fatal(
"len = %lli\n", (
long long) len);
434 fatal(
"TODO: unaligned overlay access\n");
435 fatal(
"offset = %lli\n", (
long long) offset);
440 for (curofs = offset; curofs < (off_t) (offset+len);
448 fatal(
"[ diskimage__internal_access(): fseek()" 449 " failed on disk id %i \n", d->
id);
458 overlay_set_block_in_use(d, overlay_nr, curofs);
472 static size_t fread_helper(off_t offset,
unsigned char *buf,
476 size_t totallenread = 0;
480 int res = my_fseek(d->
f, offset, SEEK_SET);
482 fatal(
"[ diskimage__internal_access(): fseek() failed" 483 " on disk id %i \n", d->
id);
487 return fread(buf, 1, len, d->
f);
491 for (curofs=offset; len != 0;
494 off_t lenread, lentoread;
497 overlay_nr >= 0; overlay_nr --) {
498 if (overlay_has_block(d, overlay_nr, curofs))
504 if (overlay_nr >= 0) {
509 fatal(
"[ diskimage__internal_access(): fseek()" 510 " failed on disk id %i \n", d->
id);
513 lenread = fread(buf, 1, lentoread,
517 int res = my_fseek(d->
f, curofs, SEEK_SET);
519 fatal(
"[ diskimage__internal_access(): fseek()" 520 " failed on disk id %i \n", d->
id);
523 lenread = fread(buf, 1, lentoread, d->
f);
526 if (lenread != lentoread) {
527 fatal(
"[ INCOMPLETE READ from disk id %i, offset" 528 " %lli ]\n", d->
id, (
long long)curofs);
532 totallenread += lenread;
548 off_t offset,
unsigned char *buf,
size_t len)
553 fprintf(stderr,
"diskimage__internal_access(): buf = NULL\n");
565 lendone = fwrite_helper(offset, buf, len, d);
573 lendone = diskimage_access__cdrom(d, offset, buf, len);
575 lendone = fread_helper(offset, buf, len, d);
577 if (lendone < (ssize_t)len)
578 memset(buf + lendone, 0, len - lendone);
582 if (lendone != (ssize_t)len) {
583 #ifdef UNSTABLE_DEVEL 588 (
"[ diskimage__internal_access(): disk_id %i, offset %lli" 589 ", transfer not completed. len=%i, len_done=%i ]\n",
590 d->
id, (
long long)offset, (
int)len, (int)lendone);
606 off_t offset,
unsigned char *buf,
size_t len)
611 if (d->
type == type && d->
id ==
id)
617 fatal(
"[ diskimage_access(): ERROR: trying to access a " 618 "non-existant %s disk image (id %i)\n",
619 diskimage_types[type],
id);
625 debug(
"[ reading before start of disk image ]\n");
662 int id = 0, override_heads=0, override_spt=0;
665 int prefix_b=0, prefix_c=0, prefix_d=0, prefix_f=0, prefix_g=0;
666 int prefix_i=0, prefix_r=0, prefix_s=0, prefix_t=0, prefix_id=-1;
667 int prefix_o=0, prefix_V=0;
670 fprintf(stderr,
"diskimage_add(): NULL ptr\n");
675 cp = strchr(fname,
':');
677 while (fname <= cp) {
704 override_heads = atoi(fname);
705 while (*fname !=
'\0' && *fname !=
';')
709 override_spt = atoi(fname);
710 while (*fname !=
'\0' && *fname !=
';' &&
715 if (override_heads < 1 ||
717 fatal(
"Bad geometry: heads=%i " 718 "spt=%i\n", override_heads,
728 override_base_offset = atoi(fname);
729 while (*fname !=
'\0' && *fname !=
':' 732 if (*fname ==
':' || *fname ==
';')
734 if (override_base_offset < 0) {
735 fatal(
"Bad base offset: %" PRIi64
736 "\n", override_base_offset);
755 fprintf(stderr,
"diskimage_add(): invalid " 756 "prefix char '%c'\n", c);
776 if (prefix_i + prefix_f + prefix_s > 1) {
777 fprintf(stderr,
"Invalid disk image prefix(es). You can" 778 "only use one of i, f, and s\nfor each disk image.\n");
794 fprintf(stderr,
"The 'V' disk image prefix requires" 795 " a disk ID to also be supplied.\n");
800 if (d->
type == dx->
type && prefix_id == dx->
id)
806 fprintf(stderr,
"Bad ID supplied for overlay?\n");
824 while (d2->
next != NULL)
879 && !prefix_i && !prefix_s)
885 fatal(
"\nTODO: small (non-80-cylinder) floppies?\n\n");
898 d->
heads = override_heads;
912 d->
writable = access(fname, W_OK) == 0? 1 : 0;
918 debug(
"NOTE: '%s' is read-only in the host file system, but 'r:' was not used.\n\n", d->
fname);
922 d->
f = fopen(fname, d->
writable?
"r+" :
"r");
924 char *errmsg = (
char *) malloc(200 +
strlen(fname));
925 snprintf(errmsg, 200+
strlen(fname),
926 "could not fopen %s for reading%s", fname,
933 if (prefix_id == -1) {
934 int free = 0, collision = 1;
966 fprintf(stderr,
"disk image id %i " 967 "already in use\n",
id);
1020 char *buf,
size_t bufsize)
1028 if (d->
type == type && d->
id ==
id) {
1029 char *p = strrchr(d->
fname,
'/');
1034 snprintf(buf, bufsize,
"%s", p);
1053 if (d->
type == type && d->
id ==
id)
1074 if (d->
type == type && d->
id ==
id)
1124 debug(
" (%lli sectors)", (
long long)
1132 debug(
"overlay %i: %s\n",
void fatal(const char *fmt,...)
#define DEBUG_INDENTATION
int diskimage_getname(struct machine *machine, int id, int type, char *buf, size_t bufsize)
int diskimage_exist(struct machine *machine, int id, int type)
#define CDROM_SECTOR_SIZE
void f(int s, int func, int only_name)
void diskimage_set_baseoffset(struct machine *machine, int id, int type, int64_t offset)
#define CHECK_ALLOCATION(ptr)
struct diskimage * first_diskimage
int64_t override_base_offset
int diskimage_bootdev(struct machine *machine, int *typep)
int diskimage__internal_access(struct diskimage *d, int writeflag, off_t offset, unsigned char *buf, size_t len)
void diskimage_dump_info(struct machine *machine)
int64_t diskimage_getsize(struct machine *machine, int id, int type)
int64_t diskimage_get_baseoffset(struct machine *machine, int id, int type)
void diskimage_getchs(struct machine *machine, int id, int type, int *c, int *h, int *s)
void diskimage_recalc_size(struct diskimage *d)
#define OVERLAY_BLOCK_SIZE
void COMBINE() strlen(struct cpu *cpu, struct arm_instr_call *ic, int low_addr)
int diskimage_is_a_cdrom(struct machine *machine, int id, int type)
struct diskimage_overlay * overlays
void debug_indentation(int diff)
int diskimage_is_a_tape(struct machine *machine, int id, int type)
void diskimage_add_overlay(struct diskimage *d, char *overlay_basename)
int diskimage_add(struct machine *machine, char *fname)
int diskimage_access(struct machine *machine, int id, int type, int writeflag, off_t offset, unsigned char *buf, size_t len)