Annotation of hatari/src/floppy.c, revision 1.1.1.6

1.1       root        1: /*
1.1.1.5   root        2:   Hatari - floppy.c
1.1       root        3: 
1.1.1.5   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.
                      6: 
                      7:   This where we read/write sectors to/from the disc image buffers. NOTE these
                      8:   buffers are in memory so we only need to write routines for the .ST format.
                      9:   When the buffer is to be saved (ie eject disc) we save it back to the original
                     10:   file in the correct format (.ST or .MSA).
                     11: 
                     12:   There are some important notes about image accessing - as we use TOS and the
                     13:   FDC to access the disc the boot-sector MUST be valid. Sometimes this is NOT
                     14:   the case! In these situations we must guess at the disc format. Eg, some disc
                     15:   images have a a boot sector which states single-sided, but the images have
                     16:   been created as double-sided. As sides are interleaved we need to read the
                     17:   image as if it was double-sided. Also note that 'NumBytesPerSector' is ALWAYS
                     18:   512 bytes, even if the boot-sector states otherwise.
1.1.1.4   root       19:   Also note that old versions of the MAKEDISK utility do not set the correct
                     20:   boot sector structure for a real ST (and also Hatari) to read it correctly.
                     21:   (PaCifiST will, however, read/write to these images as it does not perform
                     22:   FDC access as on a real ST)
1.1       root       23: */
1.1.1.6 ! root       24: static char rcsid[] = "Hatari $Id: floppy.c,v 1.12 2003/06/23 18:49:46 thothy Exp $";
1.1       root       25: 
1.1.1.4   root       26: #include <SDL_endian.h>
                     27: 
1.1       root       28: #include "main.h"
                     29: #include "debug.h"
1.1.1.6 ! root       30: #include "configuration.h"
1.1       root       31: #include "errlog.h"
                     32: #include "file.h"
                     33: #include "floppy.h"
                     34: #include "memAlloc.h"
                     35: #include "memorySnapShot.h"
                     36: #include "misc.h"
                     37: #include "msa.h"
                     38: #include "st.h"
1.1.1.6 ! root       39: #include "zip.h"
1.1       root       40: 
                     41: EMULATION_DRIVE EmulationDrives[NUM_EMULATION_DRIVES];  /* Emulation drive details, eg FileName, Inserted, Changed etc... */
                     42: int nBootDrive=0;               /* Drive A, default */
1.1.1.6 ! root       43: BOOL bFloppyChanged;            /* TRUE if a new floppy has been inserted */
1.1       root       44: 
                     45: /* Possible disc image file extensions to scan for */
1.1.1.5   root       46: char *pszDiscImageNameExts[] =
                     47: {
1.1       root       48:   ".msa",
                     49:   ".st",
                     50:   NULL
                     51: };
                     52: 
                     53: 
1.1.1.2   root       54: /*-----------------------------------------------------------------------*/
1.1       root       55: /*
                     56:   Initialize emulation floppy drives
                     57: */
                     58: void Floppy_Init(void)
                     59: {
                     60:   int i;
                     61: 
                     62:   /* Clear drive structures */
1.1.1.5   root       63:   for(i=0; i<NUM_EMULATION_DRIVES; i++)
                     64:   {
1.1       root       65:     /* Clear */
                     66:     Memory_Clear(&EmulationDrives[i],sizeof(EMULATION_DRIVE));
                     67:     /* And allocate buffer */
                     68:     EmulationDrives[i].pBuffer = (unsigned char *)Memory_Alloc(DRIVE_BUFFER_BYTES);
                     69:   }
                     70: }
                     71: 
1.1.1.2   root       72: 
                     73: /*-----------------------------------------------------------------------*/
1.1       root       74: /*
                     75:   UnInitialize drives
                     76: */
                     77: void Floppy_UnInit(void)
                     78: {
                     79:   int i;
                     80: 
1.1.1.2   root       81:   /* Free buffers used for emulation drives */
1.1.1.5   root       82:   for(i=0; i<NUM_EMULATION_DRIVES; i++)
                     83:   {
1.1       root       84:     Memory_Free(EmulationDrives[i].pBuffer);
                     85:   }
                     86: }
                     87: 
1.1.1.2   root       88: 
                     89: /*-----------------------------------------------------------------------*/
1.1       root       90: /*
                     91:   Save/Restore snapshot of local variables('MemorySnapShot_Store' handles type)
                     92: */
                     93: void Floppy_MemorySnapShot_Capture(BOOL bSave)
                     94: {
                     95:   int i;
                     96: 
1.1.1.2   root       97:   /* Save/Restore details */
1.1.1.5   root       98:   for(i=0; i<NUM_EMULATION_DRIVES; i++)
                     99:   {
1.1       root      100:     MemorySnapShot_Store(EmulationDrives[i].pBuffer,DRIVE_BUFFER_BYTES);
                    101:     MemorySnapShot_Store(EmulationDrives[i].szFileName,sizeof(EmulationDrives[i].szFileName));
                    102:     MemorySnapShot_Store(&EmulationDrives[i].nImageBytes,sizeof(EmulationDrives[i].nImageBytes));
                    103:     MemorySnapShot_Store(&EmulationDrives[i].bDiscInserted,sizeof(EmulationDrives[i].bDiscInserted));
                    104:     MemorySnapShot_Store(&EmulationDrives[i].bMediaChanged,sizeof(EmulationDrives[i].bMediaChanged));
                    105:     MemorySnapShot_Store(&EmulationDrives[i].bContentsChanged,sizeof(EmulationDrives[i].bContentsChanged));
                    106:     MemorySnapShot_Store(&EmulationDrives[i].bOKToSave,sizeof(EmulationDrives[i].bOKToSave));
                    107:   }
                    108: }
                    109: 
1.1.1.2   root      110: 
                    111: /*-----------------------------------------------------------------------*/
1.1       root      112: /*
                    113:   Find which device to boot from
                    114: */
                    115: void Floppy_GetBootDrive(void)
                    116: {
1.1.1.3   root      117:   /* If we've inserted a disc or not enabled boot from hard-drive, boot from the floppy drive */
1.1       root      118:   if ( (!ConfigureParams.HardDisc.bBootFromHardDisc) || (EmulationDrives[0].bDiscInserted) )
1.1.1.3   root      119:     nBootDrive = 0;  /* Drive A */
1.1       root      120:   else
1.1.1.3   root      121:     nBootDrive = 2;  /* Drive C */
1.1       root      122: }
                    123: 
1.1.1.2   root      124: 
                    125: /*-----------------------------------------------------------------------*/
1.1       root      126: /*
                    127:   Test disc image for valid boot-sector
                    128: 
1.1.1.5   root      129:   It has been noticed that some discs, eg blank images made by the (current)
                    130:   MakeDisk utility fill in the boot-sector with incorrect information. Such
                    131:   images cannot be read correctly using a real ST, and also Hatari.
                    132:   To try and prevent data loss, we check for this error and flag the drive so
                    133:   the image will not be saved back to the file.
1.1       root      134: */
                    135: BOOL Floppy_IsBootSectorOK(int Drive)
                    136: {
1.1.1.5   root      137:   char szString[256];
1.1       root      138:   unsigned char *pDiscBuffer;
                    139: 
                    140:   /* Does our drive have a disc in? */
1.1.1.5   root      141:   if (EmulationDrives[Drive].bDiscInserted)
                    142:   {
1.1       root      143:     pDiscBuffer = EmulationDrives[Drive].pBuffer;
1.1.1.5   root      144: 
                    145:     /* Check SPC (byte 13) for !=0 value. If is '0', invalid image and Hatari
                    146:      * won't be-able to read (nor will a real ST)! */
1.1       root      147:     if (pDiscBuffer[13]!=0)
1.1.1.5   root      148:     {
1.1       root      149:       return(TRUE);     /* Disc sector is OK! */
1.1.1.5   root      150:     }
                    151:     else
                    152:     {
                    153:       sprintf(szString, "Disc in drive %c seems to suffer from the Pacifist/Makedisk bug.\n"
                    154:                         "If it does not work, please repair the disk first!\n", 'A' + Drive);
                    155:       Main_Message(szString, "Warning");
                    156:     }
1.1       root      157:   }
                    158: 
                    159:   return(FALSE);        /* Bad sector */
                    160: }
                    161: 
1.1.1.2   root      162: 
                    163: /*-----------------------------------------------------------------------*/
1.1       root      164: /*
                    165:   Try to create disc B filename, eg 'auto_100a' becomes 'auto_100b'
                    166:   Return TRUE if think we should try!
                    167: */
                    168: BOOL Floppy_CreateDiscBFileName(char *pSrcFileName, char *pDestFileName)
                    169: {
1.1.1.3   root      170:   char szDir[256], szName[128], szExt[32];
1.1       root      171: 
1.1.1.3   root      172:   /* So, first split name into parts */
                    173:   File_splitpath(pSrcFileName, szDir, szName, szExt);
                    174:   /* All OK? */
1.1.1.5   root      175:   if (strlen(szName)>0)
                    176:   {
1.1.1.3   root      177:     /* Now, did filename end with an 'A' or 'a'? */
1.1.1.5   root      178:     if ( (szName[strlen(szName)-1]=='A') || (szName[strlen(szName)-1]=='a') )
                    179:     {
1.1.1.3   root      180:       /* Change 'A' to a 'B' */
                    181:       szName[strlen(szName)-1] += 1;
                    182:       /* And re-build name into destination */
                    183:       File_makepath(pDestFileName,szDir,szName,szExt);
                    184:       /* Does file exist? */
1.1       root      185:       if (File_Exists(pDestFileName))
1.1.1.3   root      186:         return(TRUE);  /* Try this */
1.1       root      187:     }
                    188:   }
1.1.1.3   root      189: 
1.1.1.2   root      190:   return(FALSE);  /* No, doesn't have disc B */
1.1       root      191: }
                    192: 
1.1.1.2   root      193: 
                    194: /*-----------------------------------------------------------------------*/
1.1       root      195: /*
                    196:   Insert disc into floppy drive
                    197:   The WHOLE image is copied into our drive buffers, and uncompressed if necessary
                    198: */
                    199: BOOL Floppy_InsertDiscIntoDrive(int Drive, char *pszFileName)
                    200: {
1.1.1.6 ! root      201:   return(Floppy_ZipInsertDiscIntoDrive(Drive, pszFileName, NULL));
        !           202: }
        !           203: 
        !           204: BOOL Floppy_ZipInsertDiscIntoDrive(int Drive, char *pszFileName, char *pszZipPath)
        !           205: {
1.1       root      206:   char szDiscBFileName[MAX_FILENAME_LENGTH];
                    207:   int nImageBytes=0;
                    208: 
                    209:   /* Eject disc, if one is inserted(don't inform user) */
                    210:   Floppy_EjectDiscFromDrive(Drive,FALSE);
                    211: 
                    212:   /* See if file exists, and if not get correct extension */
1.1.1.3   root      213:   if( !File_Exists(pszFileName) )
                    214:     File_FindPossibleExtFileName(pszFileName,pszDiscImageNameExts);
1.1       root      215: 
                    216:   /* Is .MSA or .ST image? */
                    217:   if (File_FileNameIsMSA(pszFileName))
                    218:     nImageBytes = MSA_ReadDisc(pszFileName,EmulationDrives[Drive].pBuffer);
                    219:   else if (File_FileNameIsST(pszFileName))
                    220:     nImageBytes = ST_ReadDisc(pszFileName,EmulationDrives[Drive].pBuffer);
1.1.1.6 ! root      221:   else if (File_FileNameIsZIP(pszFileName))
        !           222:     nImageBytes = ZIP_ReadDisc(pszFileName,pszZipPath,EmulationDrives[Drive].pBuffer);
        !           223:   else if (File_FileNameIsMSAGZ(pszFileName) || File_FileNameIsSTGZ(pszFileName))
        !           224:     nImageBytes = GZIP_ReadDisc(pszFileName,EmulationDrives[Drive].pBuffer);
        !           225: 
1.1       root      226:   /* Did load OK? */
1.1.1.5   root      227:   if (nImageBytes!=0)
                    228:   {
1.1       root      229:     /* Store filename and size */
                    230:     strcpy(EmulationDrives[Drive].szFileName,pszFileName);
                    231:     EmulationDrives[Drive].nImageBytes = nImageBytes;
                    232:     /* And set drive states */
                    233:     EmulationDrives[Drive].bDiscInserted = TRUE;
                    234:     EmulationDrives[Drive].bContentsChanged = FALSE;
                    235:     EmulationDrives[Drive].bMediaChanged = TRUE;
                    236:     EmulationDrives[Drive].bOKToSave = Floppy_IsBootSectorOK(Drive);
                    237:   }
                    238: 
                    239:   /* If we insert a disc into Drive A, should be try to put disc 2 into drive B? */
1.1.1.5   root      240:   if ( (Drive==0) && (ConfigureParams.DiscImage.bAutoInsertDiscB) )
                    241:   {
1.1       root      242:     strcpy(EmulationDrives[1].szFileName,"");
1.1.1.3   root      243:     /* Attempt to make up second filename, eg was 'auto_100a' to 'auto_100b' */
1.1.1.5   root      244:     if (Floppy_CreateDiscBFileName(pszFileName,szDiscBFileName))
                    245:     {
1.1.1.3   root      246:       /* Put image into Drive B, clear out if fails */
1.1       root      247:       if (!Floppy_InsertDiscIntoDrive(1,szDiscBFileName))
                    248:         strcpy(EmulationDrives[1].szFileName,"");
                    249:     }
                    250:   }
1.1.1.3   root      251: 
1.1.1.6 ! root      252:   bFloppyChanged = TRUE;
        !           253: 
1.1       root      254:   /* Return TRUE if loaded OK */
                    255:   if (nImageBytes)
                    256:     return(TRUE);
                    257:   else
                    258:     return(FALSE);
                    259: }
                    260: 
1.1.1.2   root      261: 
                    262: /*-----------------------------------------------------------------------*/
1.1       root      263: /*
1.1.1.5   root      264:   Eject disc from floppy drive, save contents back to PCs hard-drive if has changed
1.1       root      265: */
1.1.1.5   root      266: void Floppy_EjectDiscFromDrive(int Drive, BOOL bInformUser)
1.1       root      267: {
                    268:   char szString[256];
                    269: 
                    270:   /* Does our drive have a disc in? */
1.1.1.5   root      271:   if (EmulationDrives[Drive].bDiscInserted)
                    272:   {
1.1       root      273:     /* OK, has contents changed? If so, need to save */
1.1.1.5   root      274:     if (EmulationDrives[Drive].bContentsChanged)
                    275:     {
1.1       root      276:       /* Is OK to save image(if boot-sector is bad, don't allow a save) */
1.1.1.5   root      277:       if (EmulationDrives[Drive].bOKToSave)
                    278:       {
1.1       root      279:         /* Save as .MSA or .ST image? */
                    280:         if (File_FileNameIsMSA(EmulationDrives[Drive].szFileName))
                    281:           MSA_WriteDisc(EmulationDrives[Drive].szFileName,EmulationDrives[Drive].pBuffer,EmulationDrives[Drive].nImageBytes);
                    282:         else if (File_FileNameIsST(EmulationDrives[Drive].szFileName))
                    283:           ST_WriteDisc(EmulationDrives[Drive].szFileName,EmulationDrives[Drive].pBuffer,EmulationDrives[Drive].nImageBytes);
1.1.1.6 ! root      284:         else if (File_FileNameIsZIP(EmulationDrives[Drive].szFileName))
        !           285:           ZIP_WriteDisc(EmulationDrives[Drive].szFileName,EmulationDrives[Drive].pBuffer,EmulationDrives[Drive].nImageBytes);
        !           286:         else if (File_FileNameIsMSAGZ(EmulationDrives[Drive].szFileName) || 
        !           287:                 File_FileNameIsSTGZ(EmulationDrives[Drive].szFileName))
        !           288:           GZIP_WriteDisc(EmulationDrives[Drive].szFileName,EmulationDrives[Drive].pBuffer,EmulationDrives[Drive].nImageBytes);
        !           289: 
1.1       root      290:       }
                    291:     }
                    292: 
                    293:     /* Inform user that disc has been ejected! */
1.1.1.5   root      294:     if (bInformUser)
                    295:     {
1.1       root      296:       sprintf(szString,"Disc has been removed from Drive '%c'.",'A'+Drive);
1.1.1.5   root      297:       Main_Message(szString, PROG_NAME /*,MB_OK | MB_ICONINFORMATION*/);
1.1       root      298:     }
                    299:   }
                    300: 
                    301:   /* Drive is now empty */
                    302:   strcpy(EmulationDrives[Drive].szFileName,"");
                    303:   EmulationDrives[Drive].nImageBytes = 0;
                    304:   EmulationDrives[Drive].bDiscInserted = FALSE;
                    305:   EmulationDrives[Drive].bContentsChanged = FALSE;
                    306:   EmulationDrives[Drive].bOKToSave = FALSE;
                    307: }
                    308: 
1.1.1.2   root      309: 
                    310: /*-----------------------------------------------------------------------*/
1.1       root      311: /*
                    312:   Eject all disc image from floppy drives - call when quit
                    313: */
                    314: void Floppy_EjectBothDrives(void)
                    315: {
                    316:   /* Eject disc images from drives 'A' and 'B' */
                    317:   Floppy_EjectDiscFromDrive(0,FALSE);
                    318:   Floppy_EjectDiscFromDrive(1,FALSE);
                    319: }
                    320: 
1.1.1.2   root      321: 
                    322: /*-----------------------------------------------------------------------*/
1.1       root      323: /*
1.1.1.4   root      324:   Double-check information read from boot-sector as this is sometimes found to
                    325:   be incorrect. The .ST image file should be divisible by the sector size and
                    326:   sectors per track.
                    327:   NOTE - Pass information from boot-sector to this function (if we can't
                    328:   decide we leave it alone).
1.1       root      329: */
1.1.1.4   root      330: static void Floppy_DoubleCheckFormat(long DiscSize, Uint16 *pnSides, Uint16 *pnSectorsPerTrack)
1.1       root      331: {
                    332:   int nSectorsPerTrack;
                    333:   long TotalSectors;
                    334: 
                    335:   /* Now guess at number of sides */
                    336:   if (DiscSize<(500*1024))                      /* Is size is >500k assume 2 sides to disc! */
                    337:     *pnSides = 1;
                    338:   else
                    339:     *pnSides = 2;
                    340: 
                    341:   /* And Sectors Per Track(always 512 bytes per sector) */
                    342:   TotalSectors = DiscSize/512;                  /* # Sectors on disc image */
1.1.1.2   root      343:   /* Does this match up with what we've read from boot-sector? */
1.1       root      344:   nSectorsPerTrack = *pnSectorsPerTrack;
                    345:   if (nSectorsPerTrack==0)                      /* Check valid, default to 9 */
                    346:     nSectorsPerTrack = 9;
1.1.1.4   root      347:   if ((TotalSectors%nSectorsPerTrack)!=0)
                    348:   {
1.1       root      349:     /* No, we have an invalid boot-sector - re-calculate from disc size */
                    350:     if ((TotalSectors%9)==0)                    /* Work in this order.... */
                    351:       *pnSectorsPerTrack = 9;
                    352:     else if ((TotalSectors%10)==0)
                    353:       *pnSectorsPerTrack = 10;
                    354:     else if ((TotalSectors%11)==0)
                    355:       *pnSectorsPerTrack = 11;
                    356:     else if ((TotalSectors%12)==0)
                    357:       *pnSectorsPerTrack = 12;
                    358:   }
                    359:   /* else unknown, assume boot-sector is correct!!! */
                    360: }
                    361: 
1.1.1.2   root      362: 
                    363: /*-----------------------------------------------------------------------*/
1.1       root      364: /*
                    365:   Find details of disc image. We need to do this via a function as sometimes the boot-block
                    366:   is not actually correct with the image - some demos/game discs have incorrect bytes in the
                    367:   boot sector and this attempts to find the correct values.
                    368: */
1.1.1.4   root      369: void Floppy_FindDiscDetails(unsigned char *pBuffer, int nImageBytes,
                    370:                             unsigned short int *pnSectorsPerTrack, unsigned short int *pnSides)
1.1       root      371: {
                    372:   unsigned char *pDiscBuffer;
1.1.1.6 ! root      373:   Uint16 nSectorsPerTrack, nSides,nsectors;
1.1       root      374: 
                    375:   pDiscBuffer = pBuffer;
                    376:   /* First do check to find number of sectors and bytes per sector */
1.1.1.4   root      377:   nSectorsPerTrack = SDL_SwapLE16(*(Uint16 *)(pDiscBuffer+24));     /* SPT */
                    378:   nSides = SDL_SwapLE16(*(Uint16 *)(pDiscBuffer+26));               /* SIDE */
1.1.1.6 ! root      379:   nsectors = SDL_SwapLE16(*(Uint16 *)(pDiscBuffer+19));             /* total sectors */
1.1.1.4   root      380: 
                    381:   /* Now double-check info as boot-sector may contain incorrect information,
                    382:      eg 'Eat.st' demo, or single/double sides */
1.1.1.6 ! root      383:   if (nsectors != nImageBytes/512)
        !           384:     /* Don't be paranoid : if the number of sectors announced is correct, then chances
        !           385:        are high that the bootsector is correct */
        !           386:     Floppy_DoubleCheckFormat(nImageBytes, &nSides, &nSectorsPerTrack);
1.1       root      387: 
                    388:   /* And set values */
                    389:   if (pnSectorsPerTrack)
                    390:     *pnSectorsPerTrack = nSectorsPerTrack;
                    391:   if (pnSides)
                    392:     *pnSides = nSides;
                    393: }
                    394: 
1.1.1.2   root      395: 
                    396: /*-----------------------------------------------------------------------*/
1.1       root      397: /*
                    398:   Read sectors from floppy disc image, return TRUE if all OK
                    399:   NOTE Pass -ve as Count to read whole track
                    400: */
                    401: BOOL Floppy_ReadSectors(int Drive,char *pBuffer,unsigned short int Sector,unsigned short int Track,unsigned short int Side, short int Count, int *pnSectorsPerTrack)
                    402: {
                    403:   unsigned char *pDiscBuffer;
                    404:   unsigned short int nSectorsPerTrack,nSides,nBytesPerTrack;
                    405:   long Offset;
                    406: 
1.1.1.5   root      407:   if(Track > 85)
                    408:   {
1.1.1.6 ! root      409:     fprintf(stderr,"Floppy_ReadSectors: Strange floppy track (%i)!\n", Track);
        !           410:     return FALSE;
1.1.1.3   root      411:   }
                    412: 
1.1.1.2   root      413:   /* Do we have a disc in our drive? */
1.1.1.5   root      414:   if (EmulationDrives[Drive].bDiscInserted)
                    415:   {
1.1.1.2   root      416:     /* Looks good */
1.1.1.3   root      417:     /*StatusBar_SetIcon(STATUS_ICON_FLOPPY,ICONSTATE_UPDATE);*/ /* Sorry - no statusbar in Hatari */
1.1       root      418:     pDiscBuffer = EmulationDrives[Drive].pBuffer;
                    419: 
1.1.1.2   root      420:     /* Find #sides and #sectors per track */
1.1       root      421:     Floppy_FindDiscDetails(EmulationDrives[Drive].pBuffer,EmulationDrives[Drive].nImageBytes,&nSectorsPerTrack,&nSides);
                    422: 
1.1.1.2   root      423:     /* Need to read whole track? */
1.1       root      424:     if (Count<0)
                    425:       Count = nSectorsPerTrack;
1.1.1.2   root      426:     /* Write back number of sector per track */
1.1       root      427:     if (pnSectorsPerTrack)
                    428:       *pnSectorsPerTrack = nSectorsPerTrack;
                    429: 
1.1.1.2   root      430:     /* Debug check as if we read over the end of a track we read into side 2! */
1.1.1.5   root      431:     if (Count>nSectorsPerTrack)
                    432:     {
1.1       root      433:       ErrLog_File("ERROR Floppy_ReadSectors reading over single track\n");
                    434:     }
                    435: 
1.1.1.2   root      436:     /* Seek to sector */
1.1       root      437:     nBytesPerTrack = NUMBYTESPERSECTOR*nSectorsPerTrack;
1.1.1.2   root      438:     Offset = nBytesPerTrack*Side;                 /* First seek to side */
                    439:     Offset += (nBytesPerTrack*nSides)*Track;      /* Then seek to track */
                    440:     Offset += (NUMBYTESPERSECTOR*(Sector-1));     /* And finally to sector */
1.1.1.6 ! root      441:     if (Offset < 0)
        !           442:     {
        !           443:       fprintf(stderr,"Floppy_ReadSectors: Offset is negative (%li)!\n", Offset);
        !           444:       return FALSE;
        !           445:     }
        !           446: 
1.1.1.2   root      447:     /* Read sectors (usually 512 bytes per sector) */
1.1       root      448:     memcpy(pBuffer,pDiscBuffer+Offset,(int)Count*NUMBYTESPERSECTOR);
                    449: 
                    450:     return(TRUE);
                    451:   }
                    452: 
                    453:   return(FALSE);
                    454: }
                    455: 
1.1.1.2   root      456: 
                    457: /*-----------------------------------------------------------------------*/
1.1       root      458: /*
                    459:   Write sectors from floppy disc image, return TRUE if all OK
                    460:   NOTE Pass -ve as Count to write whole track
                    461: */
                    462: BOOL Floppy_WriteSectors(int Drive,char *pBuffer,unsigned short int Sector,unsigned short int Track,unsigned short int Side, short int Count, int *pnSectorsPerTrack)
                    463: {
                    464:   unsigned char *pDiscBuffer;
                    465:   unsigned short int nSectorsPerTrack,nSides,nBytesPerTrack;
                    466:   long Offset;
                    467: 
1.1.1.2   root      468:   /* Do we have a disc in our drive? */
1.1.1.5   root      469:   if (EmulationDrives[Drive].bDiscInserted)
                    470:   {
1.1.1.2   root      471:     /* Looks good */
1.1.1.3   root      472:     /*StatusBar_SetIcon(STATUS_ICON_FLOPPY,ICONSTATE_UPDATE);*/ /* Sorry - no statusbar in Hatari yet */
1.1       root      473:     pDiscBuffer = EmulationDrives[Drive].pBuffer;
                    474: 
1.1.1.2   root      475:     /* Find #sides and #sectors per track */
1.1       root      476:     Floppy_FindDiscDetails(EmulationDrives[Drive].pBuffer,EmulationDrives[Drive].nImageBytes,&nSectorsPerTrack,&nSides);
                    477: 
1.1.1.2   root      478:     /* Need to write whole track? */
1.1       root      479:     if (Count<0)
                    480:       Count = nSectorsPerTrack;
1.1.1.2   root      481:     /* Write back number of sector per track */
1.1       root      482:     if (pnSectorsPerTrack)
                    483:       *pnSectorsPerTrack = nSectorsPerTrack;
                    484: 
1.1.1.2   root      485:     /* Debug check as if we write over the end of a track we write into side 2! */
1.1.1.5   root      486:     if (Count>nSectorsPerTrack)
                    487:     {
1.1       root      488:       ErrLog_File("ERROR Floppy_WriteSectors reading over single track\n");
                    489:     }
                    490: 
1.1.1.2   root      491:     /* Seek to sector */
1.1       root      492:     nBytesPerTrack = NUMBYTESPERSECTOR*nSectorsPerTrack;
1.1.1.2   root      493:     Offset = nBytesPerTrack*Side;               /* First seek to side */
                    494:     Offset += (nBytesPerTrack*nSides)*Track;    /* Then seek to track */
                    495:     Offset += (NUMBYTESPERSECTOR*(Sector-1));   /* And finally to sector */
                    496:     /* Write sectors (usually 512 bytes per sector) */
1.1       root      497:     memcpy(pDiscBuffer+Offset,pBuffer,(int)Count*NUMBYTESPERSECTOR);
1.1.1.2   root      498:     /* And set 'changed' flag */
1.1       root      499:     EmulationDrives[Drive].bContentsChanged = TRUE;
                    500: 
                    501:     return(TRUE);
                    502:   }
                    503: 
                    504:   return(FALSE);
                    505: }

unix.superglobalmegacorp.com

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