2001-06-01 07:30:40 +04:00
|
|
|
/*
|
2001-06-01 08:20:26 +04:00
|
|
|
* misc/bximage.c
|
2001-06-01 09:45:55 +04:00
|
|
|
* $Id: bximage.c,v 1.5 2001-06-01 05:45:55 bdenney Exp $
|
2001-06-01 07:30:40 +04:00
|
|
|
*
|
|
|
|
* Create empty hard disk or floppy disk images for bochs.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
2001-06-01 09:11:45 +04:00
|
|
|
#include <string.h>
|
|
|
|
#include <ctype.h>
|
2001-06-01 07:30:40 +04:00
|
|
|
#include <assert.h>
|
|
|
|
#include "config.h"
|
|
|
|
|
2001-06-01 08:20:26 +04:00
|
|
|
char *EOF_ERR = "ERROR: End of input";
|
2001-06-01 09:45:55 +04:00
|
|
|
char *rcsid = "$Id: bximage.c,v 1.5 2001-06-01 05:45:55 bdenney Exp $";
|
2001-06-01 08:20:26 +04:00
|
|
|
char *divider = "========================================================================";
|
2001-06-01 08:07:21 +04:00
|
|
|
|
2001-06-01 08:20:26 +04:00
|
|
|
/* 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.72, 1.2, 1.44, or 2.88. [1.44] ";
|
|
|
|
char *fdsize_choices[] = { "0.72","1.2","1.44","2.88" };
|
|
|
|
int fdsize_n_choices = 4;
|
|
|
|
|
|
|
|
/* 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; i<imax; i++) fputc (' ', file);
|
|
|
|
fputs (line, file);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
print_banner ()
|
|
|
|
{
|
|
|
|
printf ("%s\n", divider);
|
|
|
|
bx_center_print (stdout, "bximage\n", 72);
|
|
|
|
bx_center_print (stdout, "Disk Image Creation Tool for Bochs\n", 72);
|
|
|
|
bx_center_print (stdout, rcsid, 72);
|
|
|
|
printf ("\n%s\n", divider);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* this is how we crash */
|
|
|
|
void fatal (char *c)
|
|
|
|
{
|
|
|
|
printf ("%s\n", c);
|
|
|
|
exit (1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* remove leading spaces, newline junk at end. returns pointer to
|
|
|
|
cleaned string, which is between s0 and the null */
|
2001-06-01 07:30:40 +04:00
|
|
|
char *
|
|
|
|
clean_string (char *s0)
|
|
|
|
{
|
|
|
|
char *s = s0;
|
|
|
|
char *ptr;
|
|
|
|
/* find first nonblank */
|
|
|
|
while (isspace (*s))
|
|
|
|
s++;
|
|
|
|
/* truncate string at first non-alphanumeric */
|
|
|
|
ptr = s;
|
|
|
|
while (isprint (*ptr))
|
|
|
|
ptr++;
|
|
|
|
*ptr = 0;
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
2001-06-01 08:20:26 +04:00
|
|
|
/* returns 0 on success, -1 on failure. The value goes into out. */
|
|
|
|
int
|
|
|
|
ask_int (char *prompt, int min, int max, int the_default, int *out)
|
2001-06-01 07:30:40 +04:00
|
|
|
{
|
|
|
|
int n = max + 1;
|
|
|
|
char buffer[1024];
|
|
|
|
char *clean;
|
|
|
|
int illegal;
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
illegal = (1 != sscanf (buffer, "%d", &n));
|
|
|
|
if (illegal || n<min || n>max) {
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-06-01 08:20:26 +04:00
|
|
|
int
|
|
|
|
ask_menu (char *prompt, int n_choices, char *choice[], int the_default, int *out)
|
2001-06-01 07:30:40 +04:00
|
|
|
{
|
|
|
|
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; i<n_choices; i++) {
|
2001-06-01 09:45:55 +04:00
|
|
|
if (!strcmp (choice[i], clean)) {
|
2001-06-01 07:30:40 +04:00
|
|
|
// matched, return the choice number
|
|
|
|
*out = i;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
printf ("Your choice (%s) did not match any of the choices:\n", clean);
|
|
|
|
for (i=0; i<n_choices; i++) {
|
|
|
|
if (i>0) printf (", ");
|
|
|
|
printf ("%s", choice[i]);
|
|
|
|
}
|
|
|
|
printf ("\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-06-01 08:20:26 +04:00
|
|
|
int
|
|
|
|
ask_yn (char *prompt, int the_default, int *out)
|
2001-06-01 08:07:21 +04:00
|
|
|
{
|
|
|
|
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");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-06-01 08:20:26 +04:00
|
|
|
int
|
|
|
|
ask_string (char *prompt, char *the_default, char *out)
|
2001-06-01 07:30:40 +04:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2001-06-01 08:20:26 +04:00
|
|
|
/* produce the image file */
|
2001-06-01 07:30:40 +04:00
|
|
|
int make_image (int sec, char *filename)
|
|
|
|
{
|
2001-06-01 08:07:21 +04:00
|
|
|
FILE *fp;
|
2001-06-01 07:30:40 +04:00
|
|
|
char buffer[1024];
|
|
|
|
int i;
|
|
|
|
unsigned int n;
|
2001-06-01 08:07:21 +04:00
|
|
|
|
|
|
|
// check if it exists before trashing someone's disk image
|
|
|
|
fp = fopen (filename, "r");
|
|
|
|
if (fp) {
|
|
|
|
int confirm;
|
2001-06-01 09:11:45 +04:00
|
|
|
sprintf (buffer, "\nThe disk image '%s' already exists. Are you sure you want to replace it?\nPlease type yes or no. [no] ", filename);
|
2001-06-01 08:07:21 +04:00
|
|
|
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");
|
2001-06-01 07:30:40 +04:00
|
|
|
if (fp == NULL) {
|
|
|
|
// attempt to print an error
|
|
|
|
#ifdef HAVE_PERROR
|
|
|
|
sprintf (buffer, "while opening '%s' for writing", filename);
|
|
|
|
perror (buffer);
|
|
|
|
#endif
|
2001-06-01 08:07:21 +04:00
|
|
|
fatal ("ERROR: Could not write disk image");
|
2001-06-01 07:30:40 +04:00
|
|
|
}
|
|
|
|
// clear the buffer
|
|
|
|
for (i=0; i<512; i++)
|
|
|
|
buffer[i] = 0;
|
|
|
|
// write it however many times
|
2001-06-01 08:20:26 +04:00
|
|
|
printf ("\nWriting: [");
|
2001-06-01 07:30:40 +04:00
|
|
|
for (i=0; i<sec; i++) {
|
|
|
|
n = (unsigned int) fwrite (buffer, 512, 1, fp);
|
|
|
|
if (n != 1) {
|
2001-06-01 08:07:21 +04:00
|
|
|
printf ("\nWrite failed with %d sectors written\n", i);
|
2001-06-01 07:30:40 +04:00
|
|
|
fclose (fp);
|
2001-06-01 08:07:21 +04:00
|
|
|
fatal ("ERROR: The disk image is not complete!");
|
|
|
|
}
|
|
|
|
if ((i%2048) == 0) {
|
|
|
|
printf (".");
|
|
|
|
fflush (stdout);
|
2001-06-01 07:30:40 +04:00
|
|
|
}
|
|
|
|
}
|
2001-06-01 08:20:26 +04:00
|
|
|
printf ("] Done.\n");
|
2001-06-01 07:30:40 +04:00
|
|
|
fclose (fp);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int main()
|
|
|
|
{
|
|
|
|
int hd;
|
|
|
|
int sectors = 0;
|
|
|
|
char filename[256];
|
|
|
|
char bochsrc_line[256];
|
2001-06-01 08:20:26 +04:00
|
|
|
print_banner ();
|
2001-06-01 07:30:40 +04:00
|
|
|
filename[0] = 0;
|
|
|
|
if (ask_menu (fdhd_menu, fdhd_n_choices, fdhd_choices, 1, &hd) < 0)
|
2001-06-01 08:07:21 +04:00
|
|
|
fatal (EOF_ERR);
|
2001-06-01 07:30:40 +04:00
|
|
|
if (hd) {
|
|
|
|
int hdsize, cyl, heads=16, spt=63;
|
2001-06-01 08:24:12 +04:00
|
|
|
if (ask_int ("\nEnter the hard disk size in megabytes, between 1 and 32255\n[10] ", 1, 32255, 10, &hdsize) < 0)
|
2001-06-01 08:07:21 +04:00
|
|
|
fatal (EOF_ERR);
|
2001-06-01 07:30:40 +04:00
|
|
|
cyl = hdsize*1024*1024/16/63/512;
|
2001-06-01 08:24:12 +04:00
|
|
|
assert (cyl < 65536);
|
2001-06-01 07:30:40 +04:00
|
|
|
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)
|
2001-06-01 08:07:21 +04:00
|
|
|
fatal (EOF_ERR);
|
2001-06-01 07:30:40 +04:00
|
|
|
sprintf (bochsrc_line, "diskc: file=\"%s\", cyl=%d, heads=%d, spt=%d", filename, cyl, heads, spt);
|
|
|
|
} else {
|
2001-06-01 09:11:45 +04:00
|
|
|
int fdsize, cyl=0, heads=0, spt=0;
|
|
|
|
char *name = NULL;
|
2001-06-01 07:30:40 +04:00
|
|
|
if (ask_menu (fdsize_menu, fdsize_n_choices, fdsize_choices, 2, &fdsize) < 0)
|
2001-06-01 08:07:21 +04:00
|
|
|
fatal (EOF_ERR);
|
2001-06-01 07:30:40 +04:00
|
|
|
switch (fdsize) {
|
|
|
|
case 0: name="720k"; cyl=80; heads=2; spt=9; break; /* 0.72 meg */
|
|
|
|
case 1: name="1_2"; cyl=80; heads=2; spt=15; break; /* 1.2 meg */
|
|
|
|
case 2: name="1_44"; cyl=80; heads=2; spt=18; break; /* 1.44 meg */
|
|
|
|
case 3: name="2_88"; cyl=80; heads=2; spt=36; break; /* 2.88 meg */
|
|
|
|
default:
|
2001-06-01 08:07:21 +04:00
|
|
|
fatal ("ERROR: fdsize out of range");
|
2001-06-01 07:30:40 +04:00
|
|
|
}
|
|
|
|
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)
|
2001-06-01 08:07:21 +04:00
|
|
|
fatal (EOF_ERR);
|
2001-06-01 07:30:40 +04:00
|
|
|
sprintf (bochsrc_line, "floppya: %s=\"%s\", status=inserted", name, filename);
|
|
|
|
}
|
|
|
|
if (sectors < 1)
|
2001-06-01 08:07:21 +04:00
|
|
|
fatal ("ERROR: Illegal disk size!");
|
2001-06-01 07:30:40 +04:00
|
|
|
if (strlen (filename) < 1)
|
2001-06-01 08:07:21 +04:00
|
|
|
fatal ("ERROR: Illegal filename");
|
2001-06-01 07:30:40 +04:00
|
|
|
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);
|
2001-06-01 09:11:45 +04:00
|
|
|
return 0;
|
2001-06-01 07:30:40 +04:00
|
|
|
}
|