Bochs/bochs/misc/bximage.c
Bryce Denney 5e520261db Add plugin support to Bochs by merging all the changes from the
BRANCH_PLUGINS branch!

Authors:
  Bryce Denney
  Christophe Bothamy
  Kevin Lawton (we grabbed a lot of plugin code from plex86)
Testing help from:
  Volker Ruppert
  Don Becker (Psyon)
  Jeremy Parsons (Br'fin)

The change log is too long to paste in here.  To read the change log, do
  cvs log patches/patch.final-from-BRANCH_PLUGINS.gz

All the changes and a detailed description are contained in a patch
called patch.final-from-BRANCH_PLUGINS.gz.  To look at the complete
patch, do
  cvs upd -r1.1 patches/patch.final-from-BRANCH_PLUGINS.gz

Then you will have a local copy of the patch, which you can gunzip and
play with however you want.

Modified Files:
    .bochsrc Makefile.in aclocal.m4 bochs.h config.h.in configure
    configure.in gdbstub.cc logio.cc main.cc pc_system.cc
    pc_system.h state_file.h bios/Makefile.in bios/rombios.c
    cpu/Makefile.in cpu/access.cc cpu/apic.cc cpu/arith16.cc
    cpu/arith32.cc cpu/arith8.cc cpu/cpu.cc cpu/cpu.h
    cpu/ctrl_xfer32.cc cpu/exception.cc cpu/fetchdecode.cc
    cpu/fetchdecode64.cc cpu/flag_ctrl.cc cpu/flag_ctrl_pro.cc
    cpu/init.cc cpu/io.cc cpu/logical16.cc cpu/logical32.cc
    cpu/logical8.cc cpu/paging.cc cpu/proc_ctrl.cc
    cpu/protect_ctrl.cc cpu/segment_ctrl_pro.cc cpu/shift16.cc
    cpu/shift32.cc cpu/stack64.cc cpu/string.cc cpu/tasking.cc
    debug/Makefile.in debug/dbg_main.cc disasm/Makefile.in
    doc/docbook/user/user.dbk dynamic/Makefile.in fpu/Makefile.in
    gui/Makefile.in gui/amigaos.cc gui/beos.cc gui/carbon.cc
    gui/control.cc gui/control.h gui/gui.cc gui/gui.h
    gui/keymap.cc gui/keymap.h gui/macintosh.cc gui/nogui.cc
    gui/rfb.cc gui/sdl.cc gui/sdlkeys.h gui/siminterface.cc
    gui/siminterface.h gui/term.cc gui/win32.cc gui/wx.cc
    gui/wxdialog.cc gui/wxdialog.h gui/wxmain.cc gui/wxmain.h
    gui/x.cc gui/keymaps/sdl-pc-de.map gui/keymaps/sdl-pc-us.map
    gui/keymaps/x11-pc-de.map instrument/example0/instrument.h
    instrument/example1/instrument.h
    instrument/stubs/instrument.cc instrument/stubs/instrument.h
    iodev/Makefile.in iodev/biosdev.cc iodev/biosdev.h
    iodev/cdrom.cc iodev/cmos.cc iodev/cmos.h iodev/devices.cc
    iodev/dma.cc iodev/dma.h iodev/eth_fbsd.cc iodev/eth_linux.cc
    iodev/eth_null.cc iodev/eth_tap.cc iodev/floppy.cc
    iodev/floppy.h iodev/guest2host.cc iodev/guest2host.h
    iodev/harddrv.cc iodev/harddrv.h iodev/iodebug.cc
    iodev/iodebug.h iodev/iodev.h iodev/keyboard.cc
    iodev/keyboard.h iodev/ne2k.cc iodev/ne2k.h iodev/parallel.cc
    iodev/parallel.h iodev/pci.cc iodev/pci.h iodev/pci2isa.cc
    iodev/pci2isa.h iodev/pic.cc iodev/pic.h iodev/pit.cc
    iodev/pit.h iodev/pit_wrap.cc iodev/pit_wrap.h iodev/sb16.cc
    iodev/sb16.h iodev/scancodes.cc iodev/scancodes.h
    iodev/serial.cc iodev/serial.h iodev/slowdown_timer.cc
    iodev/slowdown_timer.h iodev/unmapped.cc iodev/unmapped.h
    iodev/vga.cc iodev/vga.h memory/Makefile.in memory/memory.cc
    memory/memory.h memory/misc_mem.cc misc/bximage.c
    misc/niclist.c
Added Files:
    README-plugins extplugin.h ltdl.c ltdl.h ltdlconf.h.in
    ltmain.sh plugin.cc plugin.h
2002-10-24 21:07:56 +00:00

307 lines
8.1 KiB
C

/*
* misc/bximage.c
* $Id: bximage.c,v 1.14 2002-10-24 21:07:56 bdenney Exp $
*
* Create empty hard disk or floppy disk images for bochs.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#ifdef WIN32
# include <conio.h>
#endif
#include "config.h"
char *EOF_ERR = "ERROR: End of input";
char *rcsid = "$Id: bximage.c,v 1.14 2002-10-24 21:07:56 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; 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);
#ifdef WIN32
printf ("\nPress any key to continue\n");
getch();
#endif
exit (1);
}
/* remove leading spaces, newline junk at end. returns pointer to
cleaned string, which is between s0 and the null */
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;
}
/* 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)
{
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;
}
}
}
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; i<n_choices; i++) {
if (!strcmp (choice[i], clean)) {
// 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");
}
}
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 (Bit64u 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)
*/
long 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;
Bit64u 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=%lld\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, "ata0-master: type=disk, path=\"%s\", cylinders=%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=%lld\n", sectors);
printf (" total bytes=%lld\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 %lld bytes to %s.\n", sectors*512, filename);
printf ("\nThe following line should appear in your bochsrc:\n");
printf (" %s\n", bochsrc_line);
return 0;
}