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