|
|
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.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.