mirror of
https://github.com/Oibaf66/uae-wii.git
synced 2024-11-22 02:29:17 +01:00
make_hdf_wii
This commit is contained in:
parent
c6d863fa46
commit
742704f7d7
149
src/make_hdf_wii.c
Normal file
149
src/make_hdf_wii.c
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
/*
|
||||||
|
* E-UAE - The portable Amiga Emulator
|
||||||
|
*
|
||||||
|
* make_hdf_wii modification of make_hdf
|
||||||
|
*
|
||||||
|
* A quick hack to generate a hard file image and associated config option.
|
||||||
|
* Anybody want to show this rubbish some love, feel free.
|
||||||
|
*
|
||||||
|
* Copyright Richard Drummond 2007
|
||||||
|
* Copyright Fabio Olimpieri 2014
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sysconfig.h"
|
||||||
|
#include "sysdeps.h"
|
||||||
|
#include "writelog.h"
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static int create_hdf (const char *path, off_t size)
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
void *buf;
|
||||||
|
const size_t CHUNK_SIZE = 4096;
|
||||||
|
|
||||||
|
f = fopen (path, "wb+");
|
||||||
|
|
||||||
|
if (f) {
|
||||||
|
if (size == 0) {
|
||||||
|
fclose (f);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Try it the easy way.
|
||||||
|
*/
|
||||||
|
if (fseeko (f, size - 1, SEEK_SET) == 0) {
|
||||||
|
fputc (0, f);
|
||||||
|
if (fseeko (f, 0, SEEK_SET) == 0) {
|
||||||
|
fclose (f);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Okay. That failed. Let's assume seeking passed
|
||||||
|
* the end of a file ain't supported. Do it the
|
||||||
|
* hard way.
|
||||||
|
*/
|
||||||
|
fseeko (f, 0, SEEK_SET);
|
||||||
|
buf = calloc (1, CHUNK_SIZE);
|
||||||
|
|
||||||
|
while (size >= (off_t) CHUNK_SIZE) {
|
||||||
|
if (fwrite (buf, CHUNK_SIZE, 1, f) != 1)
|
||||||
|
break;
|
||||||
|
size -= CHUNK_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size < (off_t) CHUNK_SIZE) {
|
||||||
|
if (size == 0 || fwrite (buf, (size_t)size, 1, f) == 1) {
|
||||||
|
fclose (f);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
write_log ("Failed creating hdf\n");
|
||||||
|
|
||||||
|
if (f) {
|
||||||
|
fclose (f);
|
||||||
|
/* TODO: Should probably delete failed image here. */
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int make_hdf(int size, const char *hdf_path, int blocks_per_track, int surfaces, int block_size)
|
||||||
|
{
|
||||||
|
char *size_spec;
|
||||||
|
const char *device_name ="DH0";
|
||||||
|
|
||||||
|
uae_u64 num_blocks;
|
||||||
|
int cylinders;
|
||||||
|
|
||||||
|
|
||||||
|
if (size <= 0) {
|
||||||
|
write_log ("Invalid size\n");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((size >= (1LL << 31)) && (sizeof (off_t) < sizeof (uae_u64))) {
|
||||||
|
write_log ("Specified size too large (2GB file size is maximum).\n");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (block_size==0) block_size = 512;
|
||||||
|
num_blocks = size / block_size;
|
||||||
|
|
||||||
|
/* We don't want more than (2^32)-1 blocks */
|
||||||
|
if (num_blocks >= (1LL << 32)) {
|
||||||
|
write_log ("Specified size too large (too many blocks).\n");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Try and work out some plausible geometry
|
||||||
|
*
|
||||||
|
* We try and set surfaces and blocks_per_track to keep
|
||||||
|
* cylinders < 65536. Prior to OS 3.9, FFS had problems with
|
||||||
|
* more cylinders than that.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* The default practice in UAE hardfiles, so let's start there. */
|
||||||
|
if (blocks_per_track==0) blocks_per_track = 32;
|
||||||
|
if (surfaces==0) surfaces = 1;
|
||||||
|
|
||||||
|
cylinders = num_blocks / (blocks_per_track * surfaces);
|
||||||
|
|
||||||
|
if (cylinders == 0) {
|
||||||
|
write_log ("Specified size is too small.\n");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (cylinders > 65535 && surfaces < 255) {
|
||||||
|
surfaces++;
|
||||||
|
cylinders = num_blocks / (blocks_per_track * surfaces);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (cylinders > 65535 && blocks_per_track < 255) {
|
||||||
|
blocks_per_track++;
|
||||||
|
cylinders = num_blocks / (blocks_per_track * surfaces);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate size based on above geometry */
|
||||||
|
num_blocks = (uae_u64)cylinders * surfaces * blocks_per_track;
|
||||||
|
|
||||||
|
/* make file */
|
||||||
|
if (create_hdf (hdf_path, num_blocks * block_size) < 0)
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
|
/* output_spec */
|
||||||
|
write_log ("hardfile2=rw,%s:%s,%d,%d,%d,%d,%d,\n", device_name, hdf_path, blocks_per_track, surfaces, 2, block_size, 0);
|
||||||
|
write_log ("hardfile=rw,%d,%d,%d,%d,%s\n", blocks_per_track, surfaces, 2, block_size, hdf_path);
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user