Beispiel #1
0
/**
 * Write sectors from floppy disk image, return TRUE if all OK
 * NOTE Pass -ve as Count to write whole track
 */
bool Floppy_WriteSectors(int Drive, Uint8 *pBuffer, Uint16 Sector,
                         Uint16 Track, Uint16 Side, short Count,
                         int *pnSectorsPerTrack, int *pSectorSize)
{
	Uint8 *pDiskBuffer;
	Uint16 nSectorsPerTrack, nSides, nBytesPerTrack;
	long Offset;
	int nImageTracks;

	/* Do we have a writable disk in our drive? */
	if (EmulationDrives[Drive].bDiskInserted && !Floppy_IsWriteProtected(Drive))
	{
		/* Looks good */
		pDiskBuffer = EmulationDrives[Drive].pBuffer;

		/* Find #sides and #sectors per track */
		Floppy_FindDiskDetails(EmulationDrives[Drive].pBuffer,EmulationDrives[Drive].nImageBytes,&nSectorsPerTrack,&nSides);
		nImageTracks = ((EmulationDrives[Drive].nImageBytes / NUMBYTESPERSECTOR) / nSectorsPerTrack) / nSides;

		/* Need to write whole track? */
		if (Count<0)
			Count = nSectorsPerTrack;
		/* Write back number of sector per track */
		if (pnSectorsPerTrack)
			*pnSectorsPerTrack = nSectorsPerTrack;

		if (pSectorSize)
			*pSectorSize = NUMBYTESPERSECTOR;			/* Size is 512 bytes for ST/MSA */

		/* Debug check as if we write over the end of a track we write into side 2! */
		if (Count > nSectorsPerTrack)
		{
			Log_Printf(LOG_DEBUG, "Floppy_WriteSectors: writing over single track\n");
		}

		/* Check that the side number (0 or 1) does not exceed the amount of sides (1 or 2). */
		if (Side >= nSides)
		{
			Log_Printf(LOG_DEBUG, "Floppy_WriteSectors: Program tries to write to side %i "
			           "of a disk image with %i sides!\n", Side+1, nSides);
			return false;
		}

		/* Check if track number is in range */
		if (Track >= nImageTracks)
		{
			Log_Printf(LOG_DEBUG, "Floppy_WriteSectors: Program tries to write to track %i "
			           "of a disk image with only %i tracks!\n", Track, nImageTracks);
			return false;
		}

		/* Check if sector number is in range */
		if (Sector <= 0 || Sector > nSectorsPerTrack)
		{
			Log_Printf(LOG_DEBUG, "Floppy_WriteSectors: Program tries to write to sector %i "
			           "of a disk image with %i sectors per track!\n", Sector, nSectorsPerTrack);
			return false;
		}

		/* Seek to sector */
		nBytesPerTrack = NUMBYTESPERSECTOR*nSectorsPerTrack;
		Offset = nBytesPerTrack*Side;               /* First seek to side */
		Offset += (nBytesPerTrack*nSides)*Track;    /* Then seek to track */
		Offset += (NUMBYTESPERSECTOR*(Sector-1));   /* And finally to sector */

		/* Write sectors (usually 512 bytes per sector) */
		memcpy(pDiskBuffer+Offset, pBuffer, (int)Count*NUMBYTESPERSECTOR);
		/* And set 'changed' flag */
		EmulationDrives[Drive].bContentsChanged = true;

		return true;
	}

	return false;
}
Beispiel #2
0
/**
 * Save compressed .MSA file from memory buffer. Returns true is all OK
 */
bool MSA_WriteDisk(const char *pszFileName, Uint8 *pBuffer, int ImageSize)
{
#ifdef SAVE_TO_MSA_IMAGES

	MSAHEADERSTRUCT *pMSAHeader;
	unsigned short int *pMSADataLength;
	Uint8 *pMSAImageBuffer, *pMSABuffer, *pImageBuffer;
	Uint16 nSectorsPerTrack, nSides, nCompressedBytes, nBytesPerTrack;
	bool nRet;
	int nTracks,nBytesToGo,nBytesRun;
	int Track,Side;

	/* Allocate workspace for compressed image */
	pMSAImageBuffer = (Uint8 *)malloc(MSA_WORKSPACE_SIZE);
	if (!pMSAImageBuffer)
	{
		perror("MSA_WriteDisk");
		return false;
	}

	/* Store header */
	pMSAHeader = (MSAHEADERSTRUCT *)pMSAImageBuffer;
	pMSAHeader->ID = SDL_SwapBE16(0x0E0F);
	Floppy_FindDiskDetails(pBuffer,ImageSize, &nSectorsPerTrack, &nSides);
	pMSAHeader->SectorsPerTrack = SDL_SwapBE16(nSectorsPerTrack);
	pMSAHeader->Sides = SDL_SwapBE16(nSides-1);
	pMSAHeader->StartingTrack = SDL_SwapBE16(0);
	nTracks = ((ImageSize / NUMBYTESPERSECTOR) / nSectorsPerTrack) / nSides;
	pMSAHeader->EndingTrack = SDL_SwapBE16(nTracks-1);

	/* Compress image */
	pMSABuffer = pMSAImageBuffer + sizeof(MSAHEADERSTRUCT);
	for (Track = 0; Track < nTracks; Track++)
	{
		for (Side = 0; Side < nSides; Side++)
		{
			/* Get track data pointer */
			nBytesPerTrack = NUMBYTESPERSECTOR*nSectorsPerTrack;
			pImageBuffer = pBuffer + (nBytesPerTrack*Side) + ((nBytesPerTrack*nSides)*Track);

			/* Skip data length (fill in later) */
			pMSADataLength = (Uint16 *)pMSABuffer;
			pMSABuffer += sizeof(Uint16);

			/* Compress track */
			nBytesToGo = nBytesPerTrack;
			nCompressedBytes = 0;
			while (nBytesToGo > 0)
			{
				nBytesRun = MSA_FindRunOfBytes(pImageBuffer,nBytesToGo);
				if (nBytesRun == 0)
				{
					/* Just copy byte */
					*pMSABuffer++ = *pImageBuffer++;
					nCompressedBytes++;
					nBytesRun = 1;
				}
				else
				{
					/* Store run! */
					*pMSABuffer++ = 0xE5;               /* Marker */
					*pMSABuffer++ = *pImageBuffer;      /* Byte, and follow with 16-bit length */
					do_put_mem_word(pMSABuffer, nBytesRun);
					pMSABuffer += sizeof(Uint16);
					pImageBuffer += nBytesRun;
					nCompressedBytes += 4;
				}
				nBytesToGo -= nBytesRun;
			}

			/* Is compressed track smaller than the original? */
			if (nCompressedBytes < nBytesPerTrack)
			{
				/* Yes, store size */
				do_put_mem_word(pMSADataLength, nCompressedBytes);
			}
			else
			{
				/* No, just store uncompressed track */
				do_put_mem_word(pMSADataLength, nBytesPerTrack);
				pMSABuffer = ((Uint8 *)pMSADataLength) + 2;
				pImageBuffer = pBuffer + (nBytesPerTrack*Side) + ((nBytesPerTrack*nSides)*Track);
				memcpy(pMSABuffer,pImageBuffer, nBytesPerTrack);
				pMSABuffer += nBytesPerTrack;
			}
		}
	}

	/* And save to file! */
	nRet = File_Save(pszFileName,pMSAImageBuffer, pMSABuffer-pMSAImageBuffer, false);

	/* Free workspace */
	free(pMSAImageBuffer);

	return nRet;

#else   /*SAVE_TO_MSA_IMAGES*/

	/* Oops, cannot save */
	return false;

#endif  /*SAVE_TO_MSA_IMAGES*/
}
Beispiel #3
0
/**
 * Read sectors from floppy disk image, return TRUE if all OK
 * NOTE Pass -ve as Count to read whole track
 */
bool Floppy_ReadSectors(int Drive, Uint8 **pBuffer, Uint16 Sector,
                        Uint16 Track, Uint16 Side, short Count,
                        int *pnSectorsPerTrack, int *pSectorSize)
{
	Uint8 *pDiskBuffer;
	Uint16 nSectorsPerTrack, nSides, nBytesPerTrack;
	long Offset;
	int nImageTracks;

	/* Do we have a disk in our drive? */
	if (EmulationDrives[Drive].bDiskInserted)
	{
		/* Looks good */
		pDiskBuffer = EmulationDrives[Drive].pBuffer;

		/* Find #sides and #sectors per track */
		Floppy_FindDiskDetails(EmulationDrives[Drive].pBuffer,EmulationDrives[Drive].nImageBytes,&nSectorsPerTrack,&nSides);
		nImageTracks = ((EmulationDrives[Drive].nImageBytes / NUMBYTESPERSECTOR) / nSectorsPerTrack) / nSides;

		/* Need to read whole track? */
		if (Count<0)
			Count = nSectorsPerTrack;
		/* Write back number of sector per track */
		if (pnSectorsPerTrack)
			*pnSectorsPerTrack = nSectorsPerTrack;

		if (pSectorSize)
			*pSectorSize = NUMBYTESPERSECTOR;			/* Size is 512 bytes for ST/MSA */

		/* Debug check as if we read over the end of a track we read into side 2! */
		if (Count > nSectorsPerTrack)
		{
			Log_Printf(LOG_DEBUG, "Floppy_ReadSectors: reading over single track\n");
		}

		/* Check that the side number (0 or 1) does not exceed the amount of sides (1 or 2).
		 * (E.g. some games like Drakkhen or Bolo can load additional data from the
		 * second disk side, but they also work with single side floppy drives) */
		if (Side >= nSides)
		{
			Log_Printf(LOG_DEBUG, "Floppy_ReadSectors: Program tries to read from side %i "
			           "of a disk image with %i sides!\n", Side+1, nSides);
			return false;
		}

		/* Check if track number is in range */
		if (Track >= nImageTracks)
		{
			Log_Printf(LOG_DEBUG, "Floppy_ReadSectors: Program tries to read from track %i "
			           "of a disk image with only %i tracks!\n", Track, nImageTracks);
			return false;
		}

		/* Check if sector number is in range */
		if (Sector <= 0 || Sector > nSectorsPerTrack)
		{
			Log_Printf(LOG_DEBUG, "Floppy_ReadSectors: Program tries to read from sector %i "
			           "of a disk image with %i sectors per track!\n", Sector, nSectorsPerTrack);
			return false;
		}

		/* Seek to sector */
		nBytesPerTrack = NUMBYTESPERSECTOR*nSectorsPerTrack;
		Offset = nBytesPerTrack*Side;                 /* First seek to side */
		Offset += (nBytesPerTrack*nSides)*Track;      /* Then seek to track */
		Offset += (NUMBYTESPERSECTOR*(Sector-1));     /* And finally to sector */

		/* Return a pointer to the sectors data (usually 512 bytes per sector) */
		*pBuffer = pDiskBuffer+Offset;

		return true;
	}

	return false;
}
Beispiel #4
0
/**
 * Save .DIM file from memory buffer. Returns TRUE is all OK
 */
bool DIM_WriteDisk(int Drive, const char *pszFileName, Uint8 *pBuffer, int ImageSize)
{
#ifdef SAVE_TO_DIM_IMAGES

	unsigned short int nSectorsPerTrack, nSides;
	Uint8 *pDimFile;
	int nTracks;
	bool bRet;
#if HAVE_LIBZ
	gzFile hGzFile;
#else
	FILE *fhdl;
#endif

	/* Allocate memory for the whole DIM image: */
	pDimFile = malloc(ImageSize + 32);
	if (!pDimFile)
	{
		perror("DIM_WriteDisk");
		return false;
	}

	memset(pDimFile, 0, 32);
	/* Try to load the old header data to preserve the header fields that are unknown yet: */
#if HAVE_LIBZ
	hGzFile = gzopen(pszFileName, "rb");
	if (hGzFile != NULL)
	{
		gzread(hGzFile, pDimFile, 32);
		gzclose(hGzFile);
	}
#else
	fhdl = fopen(pszFileName, "rb");
	if (fhndl != NULL)
	{
		fread(pDimFile, 32, 1, fhndl);
		fclose(fhndl);
	}
#endif

	/* Now fill in the new header information: */
	Floppy_FindDiskDetails(pBuffer, ImageSize, &nSectorsPerTrack, &nSides);
	nTracks = ((ImageSize / NUMBYTESPERSECTOR) / nSectorsPerTrack) / nSides;
	pDimFile[0x00] = pDimFile[0x01] = 0x42;     /* ID */
	pDimFile[0x03] = 0;                         /* Image contains all sectors */
	pDimFile[0x06] = nSides - 1;                /* Sides */
	pDimFile[0x08] = nSectorsPerTrack;          /* Sectors per track */
	pDimFile[0x0A] = 0;                         /* Starting track */
	pDimFile[0x0C] = nTracks - 1;               /* Ending track */
	pDimFile[0x0D] = (ImageSize > 1024*1024);   /* DD / HD flag */

	/* Now copy the disk data: */
	memcpy(pDimFile + 32, pBuffer, ImageSize);
	
	/* And finally save it: */
	bRet = File_Save(pszFileName, pDimFile, ImageSize + 32, false);

	free(pDimFile);

	return bRet;

#else   /*SAVE_TO_ST_IMAGES*/

	/* Oops, cannot save */
	return false;

#endif  /*SAVE_TO_ST_IMAGES*/
}