HatariWii/src/createBlankImage.c

188 lines
5.6 KiB
C

/*
Hatari - createBlankImage.c
This file is distributed under the GNU General Public License, version 2
or at your option any later version. Read the file gpl.txt for details.
Create blank .ST/.MSA disk images.
*/
const char CreateBlankImage_fileid[] = "Hatari createBlankImage.c : " __DATE__ " " __TIME__;
#include "main.h"
#include "configuration.h"
#include "dim.h"
#include "file.h"
#include "floppy.h"
#include "log.h"
#include "msa.h"
#include "st.h"
#include "createBlankImage.h"
/*-----------------------------------------------------------------------*/
/*
40 track SS 40 track DS 80 track SS 80 track DS
0- 1 Branch instruction to boot program if executable
2- 7 'Loader'
8-10 24-bit serial number
11-12 BPS 512 512 512 512
13 SPC 1 2 2 2
14-15 RES 1 1 1 1
16 FAT 2 2 2 2
17-18 DIR 64 112 112 112
19-20 SEC 360 720 720 1440
21 MEDIA $FC $FD $F8 $F9 (isn't used by ST-BIOS)
22-23 SPF 2 2 5 5
24-25 SPT 9 9 9 9
26-27 SIDE 1 2 1 2
28-29 HID 0 0 0 0
510-511 CHECKSUM
*/
/*-----------------------------------------------------------------------*/
/**
* Calculate the size of a disk in dialog.
*/
static int CreateBlankImage_GetDiskImageCapacity(int nTracks, int nSectors, int nSides)
{
/* Find size of disk image */
return nTracks*nSectors*nSides*NUMBYTESPERSECTOR;
}
/*-----------------------------------------------------------------------*/
/**
* Write a short integer to addr using little endian byte order
* (needed for 16 bit values in the bootsector of the disk image).
*/
static inline void WriteShortLE(void *addr, Uint16 val)
{
Uint8 *p = (Uint8 *)addr;
p[0] = (Uint8)val;
p[1] = (Uint8)(val >> 8);
}
/*-----------------------------------------------------------------------*/
/**
* Create .ST/.MSA disk image according to 'Tracks,Sector,Sides' and save
* it under given filename.
* Return true if saving succeeded, false otherwise.
*/
bool CreateBlankImage_CreateFile(const char *pszFileName, int nTracks, int nSectors, int nSides)
{
Uint8 *pDiskFile;
unsigned long nDiskSize;
unsigned short int SPC, nDir, MediaByte, SPF;
bool bRet = false;
int drive;
/* HD/ED disks are all double sided */
if (nSectors >= 18)
nSides = 2;
/* Calculate size of disk image */
nDiskSize = CreateBlankImage_GetDiskImageCapacity(nTracks, nSectors, nSides);
/* Allocate space for our 'file', and blank */
pDiskFile = malloc(nDiskSize);
if (pDiskFile == NULL)
{
perror("Error while creating blank disk image");
return false;
}
memset(pDiskFile, 0, nDiskSize); /* Clear buffer */
/* Fill in boot-sector */
pDiskFile[0] = 0xE9; /* Needed for MS-DOS compatibility */
memset(pDiskFile+2, 0x4e, 6); /* 2-7 'Loader' */
WriteShortLE(pDiskFile+8, rand()); /* 8-10 24-bit serial number */
pDiskFile[10] = rand();
WriteShortLE(pDiskFile+11, NUMBYTESPERSECTOR); /* 11-12 BPS */
if ((nTracks == 40) && (nSides == 1))
SPC = 1;
else
SPC = 2;
pDiskFile[13] = SPC; /* 13 SPC */
WriteShortLE(pDiskFile+14, 1); /* 14-15 RES */
pDiskFile[16] = 2; /* 16 FAT */
if (SPC==1)
nDir = 64;
else if (nSectors < 18)
nDir = 112;
else
nDir = 224;
WriteShortLE(pDiskFile+17, nDir); /* 17-18 DIR */
WriteShortLE(pDiskFile+19, nTracks*nSectors*nSides); /* 19-20 SEC */
if (nSectors >= 18)
MediaByte = 0xF0;
else
{
if (nTracks <= 42)
MediaByte = 0xFC;
else
MediaByte = 0xF8;
if (nSides == 2)
MediaByte |= 0x01;
}
pDiskFile[21] = MediaByte; /* 21 MEDIA */
if (nSectors >= 18)
SPF = 9;
else if (nTracks >= 80)
SPF = 5;
else
SPF = 2;
WriteShortLE(pDiskFile+22, SPF); /* 22-23 SPF */
WriteShortLE(pDiskFile+24, nSectors); /* 24-25 SPT */
WriteShortLE(pDiskFile+26, nSides); /* 26-27 SIDE */
WriteShortLE(pDiskFile+28, 0); /* 28-29 HID */
/* Set correct media bytes in the 1st FAT: */
pDiskFile[512] = MediaByte;
pDiskFile[513] = pDiskFile[514] = 0xFF;
/* Set correct media bytes in the 2nd FAT: */
pDiskFile[512 + SPF * 512] = MediaByte;
pDiskFile[513 + SPF * 512] = pDiskFile[514 + SPF * 512] = 0xFF;
/* Ask if OK to overwrite, if exists? */
if (File_QueryOverwrite(pszFileName))
{
drive = 0; /* drive is not used for ST/MSA/DIM, set it to 0 */
/* Save image to file */
if (MSA_FileNameIsMSA(pszFileName, true))
bRet = MSA_WriteDisk(drive, pszFileName, pDiskFile, nDiskSize);
else if (ST_FileNameIsST(pszFileName, true))
bRet = ST_WriteDisk(drive, pszFileName, pDiskFile, nDiskSize);
else if (DIM_FileNameIsDIM(pszFileName, true))
bRet = DIM_WriteDisk(drive, pszFileName, pDiskFile, nDiskSize);
else
Log_AlertDlg(LOG_ERROR, "Unknown floppy image filename extension!");
/* Did create successfully? */
if (bRet)
{
/* Say OK */
Log_AlertDlg(LOG_INFO, "Disk image '%s' created.", pszFileName);
}
else
{
/* Warn user we were unable to create image */
Log_AlertDlg(LOG_ERROR, "Unable to create disk image '%s'!", pszFileName);
}
}
/* Free image */
free(pDiskFile);
return bRet;
}