/* * misc/bximage.c * $Id: bximage.c,v 1.10 2002-09-05 16:50:03 bdenney Exp $ * * Create empty hard disk or floppy disk images for bochs. * */ #include #include #include #include #include #include "config.h" char *EOF_ERR = "ERROR: End of input"; char *rcsid = "$Id: bximage.c,v 1.10 2002-09-05 16:50:03 bdenney Exp $"; char *divider = "========================================================================"; /* menu data for choosing floppy/hard disk */ char *fdhd_menu = "\nDo you want to create a floppy disk image or a hard disk image?\nPlease type hd or fd. [hd] "; char *fdhd_choices[] = { "fd", "hd" }; int fdhd_n_choices = 2; /* menu data for choosing floppy size */ char *fdsize_menu = "\nChoose the size of floppy disk image to create, in megabytes.\nPlease type 0.36, 0.72, 1.2, 1.44, or 2.88. [1.44] "; char *fdsize_choices[] = { "0.36","0.72","1.2","1.44","2.88" }; int fdsize_n_choices = 5; /* stolen from main.cc */ void bx_center_print (FILE *file, char *line, int maxwidth) { int imax; int i; imax = (maxwidth - strlen(line)) >> 1; for (i=0; imax) { printf ("Your choice (%s) was not an integer between %d and %d.\n\n", clean, min, max); } else { // choice is okay *out = n; return 0; } } } int ask_menu (char *prompt, int n_choices, char *choice[], int the_default, int *out) { char buffer[1024]; char *clean; int i; *out = -1; while (1) { printf ("%s", prompt); if (!fgets (buffer, sizeof(buffer), stdin)) return -1; clean = clean_string (buffer); if (strlen(clean) < 1) { // empty line, use the default *out = the_default; return 0; } for (i=0; i0) printf (", "); printf ("%s", choice[i]); } printf ("\n"); } } int ask_yn (char *prompt, int the_default, int *out) { char buffer[16]; char *clean; *out = -1; while (1) { printf ("%s", prompt); if (!fgets (buffer, sizeof(buffer), stdin)) return -1; clean = clean_string (buffer); if (strlen(clean) < 1) { // empty line, use the default *out = the_default; return 0; } switch (tolower(clean[0])) { case 'y': *out=1; return 0; case 'n': *out=0; return 0; } printf ("Please type either yes or no.\n"); } } int ask_string (char *prompt, char *the_default, char *out) { char buffer[1024]; char *clean; out[0] = 0; printf ("%s", prompt); if (!fgets (buffer, sizeof(buffer), stdin)) return -1; clean = clean_string (buffer); if (strlen(clean) < 1) { // empty line, use the default strcpy (out, the_default); return 0; } strcpy (out, clean); return 0; } /* produce the image file */ int make_image (int sec, char *filename) { FILE *fp; char buffer[1024]; // check if it exists before trashing someone's disk image fp = fopen (filename, "r"); if (fp) { int confirm; sprintf (buffer, "\nThe disk image '%s' already exists. Are you sure you want to replace it?\nPlease type yes or no. [no] ", filename); if (ask_yn (buffer, 0, &confirm) < 0) fatal (EOF_ERR); if (!confirm) fatal ("ERROR: Aborted"); fclose (fp); } // okay, now open it for writing fp = fopen (filename, "w"); if (fp == NULL) { // attempt to print an error #ifdef HAVE_PERROR sprintf (buffer, "while opening '%s' for writing", filename); perror (buffer); #endif fatal ("ERROR: Could not write disk image"); } printf ("\nWriting: ["); /* * seek to sec*512-1 and write a single character. * can't just do: fseek(fp, 512*sec-1, SEEK_SET) * because 512*sec may be too large for signed int. */ while (sec > 0) { /* temp <-- min(sec, 4194303) * 4194303 is (int)(0x7FFFFFFF/512) */ int temp = ((sec < 4194303) ? sec : 4194303); fseek(fp, 512*temp, SEEK_CUR); sec -= temp; } fseek(fp, -1, SEEK_CUR); if (fputc('\0', fp) == EOF) { fclose (fp); fatal ("ERROR: The disk image is not complete!"); } printf ("] Done.\n"); fclose (fp); return 0; } int main() { int hd; int sectors = 0; char filename[256]; char bochsrc_line[256]; print_banner (); filename[0] = 0; if (ask_menu (fdhd_menu, fdhd_n_choices, fdhd_choices, 1, &hd) < 0) fatal (EOF_ERR); if (hd) { int hdsize, cyl, heads=16, spt=63; if (ask_int ("\nEnter the hard disk size in megabytes, between 1 and 32255\n[10] ", 1, 32255, 10, &hdsize) < 0) fatal (EOF_ERR); cyl = (int) (hdsize*1024.0*1024.0/16.0/63.0/512.0); assert (cyl < 65536); sectors = cyl*heads*spt; printf ("\nI will create a hard disk image with\n"); printf (" cyl=%d\n", cyl); printf (" heads=%d\n", heads); printf (" sectors per track=%d\n", spt); printf (" total sectors=%d\n", sectors); printf (" total size=%.2f megabytes\n", (float)sectors*512.0/1024.0/1024.0); if (ask_string ("\nWhat should I name the image?\n[c.img] ", "c.img", filename) < 0) fatal (EOF_ERR); sprintf (bochsrc_line, "diskc: file=\"%s\", cyl=%d, heads=%d, spt=%d", filename, cyl, heads, spt); } else { int fdsize, cyl=0, heads=0, spt=0; char *name = NULL; if (ask_menu (fdsize_menu, fdsize_n_choices, fdsize_choices, 3, &fdsize) < 0) fatal (EOF_ERR); switch (fdsize) { case 0: name="360k"; cyl=40; heads=2; spt=9; break; /* 0.36 meg */ case 1: name="720k"; cyl=80; heads=2; spt=9; break; /* 0.72 meg */ case 2: name="1_2"; cyl=80; heads=2; spt=15; break; /* 1.2 meg */ case 3: name="1_44"; cyl=80; heads=2; spt=18; break; /* 1.44 meg */ case 4: name="2_88"; cyl=80; heads=2; spt=36; break; /* 2.88 meg */ default: fatal ("ERROR: fdsize out of range"); } sectors = cyl*heads*spt; printf ("I will create a floppy image with\n"); printf (" cyl=%d\n", cyl); printf (" heads=%d\n", heads); printf (" sectors per track=%d\n", spt); printf (" total sectors=%d\n", sectors); printf (" total bytes=%d\n", sectors*512); if (ask_string ("\nWhat should I name the image?\n[a.img] ", "a.img", filename) < 0) fatal (EOF_ERR); sprintf (bochsrc_line, "floppya: %s=\"%s\", status=inserted", name, filename); } if (sectors < 1) fatal ("ERROR: Illegal disk size!"); if (strlen (filename) < 1) fatal ("ERROR: Illegal filename"); make_image (sectors, filename); printf ("\nI wrote %d bytes to %s.\n", sectors*512, filename); printf ("\nThe following line should appear in your bochsrc:\n"); printf (" %s\n", bochsrc_line); return 0; }