|
|
1.1 root 1: /*
1.1.1.4 root 2: Hatari - createBlankImage.c
1.1.1.5 root 3:
1.1.1.14 root 4: This file is distributed under the GNU General Public License, version 2
5: or at your option any later version. Read the file gpl.txt for details.
1.1.1.5 root 6:
1.1.1.7 root 7: Create blank .ST/.MSA disk images.
1.1 root 8: */
1.1.1.11 root 9: const char CreateBlankImage_fileid[] = "Hatari createBlankImage.c : " __DATE__ " " __TIME__;
1.1 root 10:
11: #include "main.h"
1.1.1.4 root 12: #include "configuration.h"
1.1.1.5 root 13: #include "dim.h"
1.1 root 14: #include "file.h"
15: #include "floppy.h"
1.1.1.6 root 16: #include "log.h"
1.1 root 17: #include "msa.h"
18: #include "st.h"
1.1.1.5 root 19: #include "createBlankImage.h"
1.1.1.16! root 20: #include "gemdos_defines.h"
1.1.1.3 root 21:
1.1 root 22: /*-----------------------------------------------------------------------*/
23: /*
24: 40 track SS 40 track DS 80 track SS 80 track DS
25: 0- 1 Branch instruction to boot program if executable
26: 2- 7 'Loader'
27: 8-10 24-bit serial number
28: 11-12 BPS 512 512 512 512
29: 13 SPC 1 2 2 2
30: 14-15 RES 1 1 1 1
31: 16 FAT 2 2 2 2
32: 17-18 DIR 64 112 112 112
33: 19-20 SEC 360 720 720 1440
1.1.1.5 root 34: 21 MEDIA $FC $FD $F8 $F9 (isn't used by ST-BIOS)
1.1 root 35: 22-23 SPF 2 2 5 5
36: 24-25 SPT 9 9 9 9
37: 26-27 SIDE 1 2 1 2
38: 28-29 HID 0 0 0 0
39: 510-511 CHECKSUM
40: */
41:
1.1.1.2 root 42:
43: /*-----------------------------------------------------------------------*/
1.1.1.9 root 44: /**
45: * Calculate the size of a disk in dialog.
46: */
1.1.1.7 root 47: static int CreateBlankImage_GetDiskImageCapacity(int nTracks, int nSectors, int nSides)
1.1 root 48: {
1.1.1.7 root 49: /* Find size of disk image */
1.1.1.5 root 50: return nTracks*nSectors*nSides*NUMBYTESPERSECTOR;
1.1 root 51: }
52:
1.1.1.2 root 53:
54: /*-----------------------------------------------------------------------*/
1.1.1.9 root 55: /**
56: * Write a short integer to addr using little endian byte order
57: * (needed for 16 bit values in the bootsector of the disk image).
58: */
1.1.1.5 root 59: static inline void WriteShortLE(void *addr, Uint16 val)
1.1 root 60: {
1.1.1.5 root 61: Uint8 *p = (Uint8 *)addr;
1.1 root 62:
1.1.1.5 root 63: p[0] = (Uint8)val;
64: p[1] = (Uint8)(val >> 8);
1.1 root 65: }
66:
1.1.1.2 root 67:
68: /*-----------------------------------------------------------------------*/
1.1.1.9 root 69: /**
1.1.1.13 root 70: * Create .ST/.MSA disk image according to 'Tracks,Sector,Sides' and save
71: * it under given filename.
1.1.1.16! root 72: * If VolumeLabel != NULL, use this 8+3 char text as the name of the disk image.
1.1.1.13 root 73: * Return true if saving succeeded, false otherwise.
1.1.1.9 root 74: */
1.1.1.16! root 75: bool CreateBlankImage_CreateFile(const char *pszFileName, int nTracks, int nSectors, int nSides, const char *VolumeLabel)
1.1 root 76: {
1.1.1.7 root 77: Uint8 *pDiskFile;
78: unsigned long nDiskSize;
1.1.1.6 root 79: unsigned short int SPC, nDir, MediaByte, SPF;
1.1.1.10 root 80: bool bRet = false;
1.1.1.15 root 81: int drive;
1.1.1.16! root 82: int LabelSize;
! 83: Uint8 *pDirStart;
1.1.1.5 root 84:
1.1.1.13 root 85: /* HD/ED disks are all double sided */
86: if (nSectors >= 18)
87: nSides = 2;
88:
1.1.1.7 root 89: /* Calculate size of disk image */
90: nDiskSize = CreateBlankImage_GetDiskImageCapacity(nTracks, nSectors, nSides);
1.1.1.5 root 91:
92: /* Allocate space for our 'file', and blank */
1.1.1.7 root 93: pDiskFile = malloc(nDiskSize);
94: if (pDiskFile == NULL)
1.1.1.5 root 95: {
1.1.1.7 root 96: perror("Error while creating blank disk image");
1.1.1.13 root 97: return false;
1.1.1.5 root 98: }
1.1.1.7 root 99: memset(pDiskFile, 0, nDiskSize); /* Clear buffer */
1.1.1.5 root 100:
101: /* Fill in boot-sector */
1.1.1.7 root 102: pDiskFile[0] = 0xE9; /* Needed for MS-DOS compatibility */
103: memset(pDiskFile+2, 0x4e, 6); /* 2-7 'Loader' */
1.1.1.5 root 104:
1.1.1.7 root 105: WriteShortLE(pDiskFile+8, rand()); /* 8-10 24-bit serial number */
106: pDiskFile[10] = rand();
1.1.1.5 root 107:
1.1.1.7 root 108: WriteShortLE(pDiskFile+11, NUMBYTESPERSECTOR); /* 11-12 BPS */
1.1.1.5 root 109:
110: if ((nTracks == 40) && (nSides == 1))
111: SPC = 1;
112: else
113: SPC = 2;
1.1.1.7 root 114: pDiskFile[13] = SPC; /* 13 SPC */
1.1.1.5 root 115:
1.1.1.7 root 116: WriteShortLE(pDiskFile+14, 1); /* 14-15 RES */
117: pDiskFile[16] = 2; /* 16 FAT */
1.1.1.5 root 118:
119: if (SPC==1)
1.1.1.6 root 120: nDir = 64;
1.1.1.13 root 121: else if (nSectors < 18)
1.1.1.6 root 122: nDir = 112;
1.1.1.13 root 123: else
124: nDir = 224;
1.1.1.7 root 125: WriteShortLE(pDiskFile+17, nDir); /* 17-18 DIR */
1.1.1.5 root 126:
1.1.1.7 root 127: WriteShortLE(pDiskFile+19, nTracks*nSectors*nSides); /* 19-20 SEC */
1.1.1.5 root 128:
1.1.1.13 root 129: if (nSectors >= 18)
130: MediaByte = 0xF0;
1.1.1.5 root 131: else
1.1.1.13 root 132: {
133: if (nTracks <= 42)
134: MediaByte = 0xFC;
135: else
136: MediaByte = 0xF8;
137: if (nSides == 2)
138: MediaByte |= 0x01;
139: }
1.1.1.7 root 140: pDiskFile[21] = MediaByte; /* 21 MEDIA */
1.1.1.5 root 141:
1.1.1.13 root 142: if (nSectors >= 18)
143: SPF = 9;
144: else if (nTracks >= 80)
1.1.1.5 root 145: SPF = 5;
146: else
147: SPF = 2;
1.1.1.7 root 148: WriteShortLE(pDiskFile+22, SPF); /* 22-23 SPF */
1.1.1.5 root 149:
1.1.1.7 root 150: WriteShortLE(pDiskFile+24, nSectors); /* 24-25 SPT */
151: WriteShortLE(pDiskFile+26, nSides); /* 26-27 SIDE */
152: WriteShortLE(pDiskFile+28, 0); /* 28-29 HID */
1.1.1.5 root 153:
154: /* Set correct media bytes in the 1st FAT: */
1.1.1.7 root 155: pDiskFile[512] = MediaByte;
156: pDiskFile[513] = pDiskFile[514] = 0xFF;
1.1.1.5 root 157: /* Set correct media bytes in the 2nd FAT: */
1.1.1.7 root 158: pDiskFile[512 + SPF * 512] = MediaByte;
159: pDiskFile[513 + SPF * 512] = pDiskFile[514 + SPF * 512] = 0xFF;
1.1.1.5 root 160:
1.1.1.16! root 161: /* Set volume label if needed (in 1st entry of the directory) */
! 162: if ( VolumeLabel != NULL )
! 163: {
! 164: /* Set 1st dir entry as 'volume label' */
! 165: pDirStart = pDiskFile + ( 1 + SPF * 2 ) * 512;
! 166: memset ( pDirStart , ' ' , 8+3 );
! 167: LabelSize = strlen ( VolumeLabel );
! 168: if ( LabelSize <= 8+3 )
! 169: memcpy ( pDirStart , VolumeLabel , LabelSize );
! 170: else
! 171: memcpy ( pDirStart , VolumeLabel , 8+3 );
! 172:
! 173: pDirStart[ 8+3 ] = GEMDOS_FILE_ATTRIB_VOLUME_LABEL;
! 174: }
! 175:
1.1.1.5 root 176: /* Ask if OK to overwrite, if exists? */
177: if (File_QueryOverwrite(pszFileName))
178: {
1.1.1.15 root 179: drive = 0; /* drive is not used for ST/MSA/DIM, set it to 0 */
1.1.1.5 root 180: /* Save image to file */
1.1.1.12 root 181: if (MSA_FileNameIsMSA(pszFileName, true))
1.1.1.15 root 182: bRet = MSA_WriteDisk(drive, pszFileName, pDiskFile, nDiskSize);
1.1.1.12 root 183: else if (ST_FileNameIsST(pszFileName, true))
1.1.1.15 root 184: bRet = ST_WriteDisk(drive, pszFileName, pDiskFile, nDiskSize);
1.1.1.12 root 185: else if (DIM_FileNameIsDIM(pszFileName, true))
1.1.1.15 root 186: bRet = DIM_WriteDisk(drive, pszFileName, pDiskFile, nDiskSize);
1.1.1.13 root 187: else
188: Log_AlertDlg(LOG_ERROR, "Unknown floppy image filename extension!");
1.1.1.5 root 189:
190: /* Did create successfully? */
191: if (bRet)
192: {
1.1.1.13 root 193: /* Say OK */
194: Log_AlertDlg(LOG_INFO, "Disk image '%s' created.", pszFileName);
1.1.1.5 root 195: }
196: else
197: {
198: /* Warn user we were unable to create image */
1.1.1.13 root 199: Log_AlertDlg(LOG_ERROR, "Unable to create disk image '%s'!", pszFileName);
1.1.1.5 root 200: }
201: }
1.1 root 202:
1.1.1.5 root 203: /* Free image */
1.1.1.7 root 204: free(pDiskFile);
1.1.1.13 root 205: return bRet;
1.1 root 206: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.