Annotation of hatari/src/createBlankImage.c, revision 1.1.1.16

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.