Exemplo n.º 1
0
/**
 * Restore 'snapshot' of memory/chips/emulation variables
 */
void MemorySnapShot_Restore(const char *pszFileName, bool bConfirm)
{
	/* Set to 'restore' */
	if (MemorySnapShot_OpenFile(pszFileName, false))
	{
		Configuration_MemorySnapShot_Capture(false);

		/* Reset emulator to get things running */
		IoMem_UnInit();  IoMem_Init();
		Reset_Cold();

		/* Capture each files details */
//		STMemory_MemorySnapShot_Capture(false);
		CycInt_MemorySnapShot_Capture(false);
		Cycles_MemorySnapShot_Capture(false);
		M68000_MemorySnapShot_Capture(false);
		Video_MemorySnapShot_Capture(false);
		DebugUI_MemorySnapShot_Capture(pszFileName, false);
//		IoMem_MemorySnapShot_Capture(false);

		/* And close */
		MemorySnapShot_CloseFile();

		/* changes may affect also info shown in statusbar */
		Statusbar_UpdateInfo();
	}

	/* Did error? */
	if (bCaptureError)
		Log_AlertDlg(LOG_ERROR, "Unable to restore memory state from file.");
	else if (bConfirm)
		Log_AlertDlg(LOG_INFO, "Memory state file restored.");
}
Exemplo n.º 2
0
/**
 * Save 'snapshot' of memory/chips/emulation variables
 */
void MemorySnapShot_Capture(const char *pszFileName, bool bConfirm)
{
	/* Set to 'saving' */
	if (MemorySnapShot_OpenFile(pszFileName, true))
	{
		/* Capture each files details */
		Configuration_MemorySnapShot_Capture(true);
//		STMemory_MemorySnapShot_Capture(true);
		CycInt_MemorySnapShot_Capture(true);
		Cycles_MemorySnapShot_Capture(true);
		M68000_MemorySnapShot_Capture(true);
		Video_MemorySnapShot_Capture(true);
		DebugUI_MemorySnapShot_Capture(pszFileName, true);
//		IoMem_MemorySnapShot_Capture(true);
		/* And close */
		MemorySnapShot_CloseFile();
	} else {
		/* just canceled? */
		if (!bCaptureError)
			return;
	}

	/* Did error */
	if (bCaptureError)
		Log_AlertDlg(LOG_ERROR, "Unable to save memory state to file.");
	else if (bConfirm)
		Log_AlertDlg(LOG_INFO, "Memory state file saved.");
}
Exemplo n.º 3
0
/**
 * Set given floppy drive image file name and handle
 * different image extensions.
 * Return corrected file name on success and NULL on failure.
 */
const char* Floppy_SetDiskFileName(int Drive, const char *pszFileName, const char *pszZipPath)
{
	char *filename;
	int i;

	/* setting to empty or "none" ejects */
	if (!*pszFileName || strcasecmp(pszFileName, "none") == 0)
	{
		return Floppy_SetDiskFileNameNone(Drive);
	}
	/* See if file exists, and if not, get/add correct extension */
	if (!File_Exists(pszFileName))
		filename = File_FindPossibleExtFileName(pszFileName, pszDiskImageNameExts);
	else
		filename = strdup(pszFileName);
	if (!filename)
	{
		Log_AlertDlg((const char *)LOG_INFO, "Image '%s' not found", pszFileName);
		return NULL;
	}
#if 0
	/* If we insert a disk into Drive A, should we try to put disk 2 into drive B? */
	if (Drive == 0 && ConfigureParams.DiskImage.bAutoInsertDiskB)
	{
		/* Attempt to make up second filename, eg was 'auto_100a' to 'auto_100b' */
		char *szDiskBFileName = Floppy_CreateDiskBFileName(filename);
		if (szDiskBFileName)
		{
			/* recurse with Drive B */
			Floppy_SetDiskFileName(1, szDiskBFileName, pszZipPath);
			free(szDiskBFileName);
		}
	}
#endif

	/* validity checks */
	assert(Drive >= 0 && Drive < MAX_FLOPPYDRIVES);
	for (i = 0; i < MAX_FLOPPYDRIVES; i++)
	{
		if (i == Drive)
			continue;
		/* prevent inserting same image to multiple drives */
		if (strcmp(filename, /*ConfigureParams.DiskImage.*/szDiskFileName[i]) == 0)
		{
			Log_AlertDlg((const char *)LOG_ERROR, "ERROR: Cannot insert same floppy to multiple drives!");
			return NULL;
		}
	}

	/* do the changes */
	if (pszZipPath)
		strcpy(szDiskZipPath[Drive], pszZipPath);
	else
		szDiskZipPath[Drive][0] = '\0';
	strcpy(szDiskFileName[Drive], filename);
	free(filename);
	//File_MakeAbsoluteName(ConfigureParams.DiskImage.szDiskFileName[Drive]);
	return szDiskFileName[Drive];
}
Exemplo n.º 4
0
/**
 * Open WAV output file and write header.
 */
bool WAVFormat_OpenFile(char *pszWavFileName)
{

	Uint32 nSampleFreq, nBytesPerSec;

	bRecordingWav = false;
	nWavOutputBytes = 0;

	/* Set frequency (11Khz, 22Khz or 44Khz) */
	nSampleFreq = ConfigureParams.Sound.nPlaybackFreq;
	/* multiply by 4 for 16 bit stereo */
	nBytesPerSec = nSampleFreq * 4;

	/* Create our file */
	WavFileHndl = fopen(pszWavFileName, "wb");
	if (!WavFileHndl)
	{
		perror("WAVFormat_OpenFile");
		Log_AlertDlg(LOG_ERROR, "WAV recording: Failed to open file!");
		return false;
	}

	/* Patch sample frequency in header structure */
	WavHeader[24] = (Uint8)nSampleFreq;
	WavHeader[25] = (Uint8)(nSampleFreq >> 8);
	WavHeader[26] = (Uint8)(nSampleFreq >> 16);
	WavHeader[27] = (Uint8)(nSampleFreq >> 24);

	/* Patch bytes per second in header structure */
	WavHeader[28] = (Uint8)nBytesPerSec;
	WavHeader[29] = (Uint8)(nBytesPerSec >> 8);
	WavHeader[30] = (Uint8)(nBytesPerSec >> 16);
	WavHeader[31] = (Uint8)(nBytesPerSec >> 24);

	/* Write header to file */
	if (fwrite(&WavHeader, sizeof(WavHeader), 1, WavFileHndl) == 1)
	{
		bRecordingWav = true;
		Log_AlertDlg(LOG_INFO, "WAV sound data recording has been started.");
	}
	else
	{
		perror("WAVFormat_OpenFile");
		Log_AlertDlg(LOG_ERROR, "WAV recording: Failed to write header!");
	}

	/* Ok, or failed? */
	return bRecordingWav;
}
Exemplo n.º 5
0
/**
 * Pass byte from emulator to printer.  Opens the printer file appending
 * if it isn't already open. Returns false if connection to "printer"
 * failed
 */
bool Printer_TransferByteTo(Uint8 Byte)
{
	/* Do we want to output to a printer/file? */
	if (!ConfigureParams.Printer.bEnablePrinting)
		return false;   /* Failed if printing disabled */

	/* Have we made a connection to our printer/file? */
	if (!pPrinterHandle)
	{
		/* open printer file... */
		pPrinterHandle = File_Open(ConfigureParams.Printer.szPrintToFileName, "a+");
		if (!pPrinterHandle)
		{
			Log_AlertDlg(LOG_ERROR, "Printer output file open failed. Printing disabled.");
			ConfigureParams.Printer.bEnablePrinting = false;
			return false;
		}
	}
	if (fputc(Byte, pPrinterHandle) != Byte)
	{
		fprintf(stderr, "ERROR: Printer_TransferByteTo() writing failed!\n");
		return false;
	}
	bUnflushed = true;
	return true;
}
Exemplo n.º 6
0
/**
 * Handle creation of a the "new blank disk image".
 * return true if disk created, false otherwise.
 */
static bool DlgNewDisk_CreateDisk(const char *path)
{
	int nSectors, nSides;

	/* (potentially non-existing) filename? */
	if (File_DirExists(path))
	{
		Log_AlertDlg(LOG_ERROR, "ERROR: '%s' isn't a file!", path);
		return false;
	}

	/* Get number of sectors */
	if (newdiskdlg[DLGNEWDISK_SECTORS36].state & SG_SELECTED)
		nSectors = 36;
	else if (newdiskdlg[DLGNEWDISK_SECTORS18].state & SG_SELECTED)
		nSectors = 18;
	else if (newdiskdlg[DLGNEWDISK_SECTORS11].state & SG_SELECTED)
		nSectors = 11;
	else if (newdiskdlg[DLGNEWDISK_SECTORS10].state & SG_SELECTED)
		nSectors = 10;
	else
		nSectors = 9;

	/* Get number of sides */
	if (newdiskdlg[DLGNEWDISK_SIDES1].state & SG_SELECTED)
		nSides = 1;
	else
		nSides = 2;
	
	return CreateBlankImage_CreateFile(path, nTracks, nSectors, nSides, dlgLabel);
}
Exemplo n.º 7
0
/**
 * Save program setting to configuration file
 */
void Configuration_Save(void)
{
	if (Configuration_SaveSection(sConfigFileName, configs_Log, "[Log]") < 0)
	{
		Log_AlertDlg(LOG_ERROR, "Error saving config file.");
		return;
	}
    Configuration_SaveSection(sConfigFileName, configs_ConfigDialog, "[ConfigDialog]");
	Configuration_SaveSection(sConfigFileName, configs_Debugger, "[Debugger]");
	Configuration_SaveSection(sConfigFileName, configs_Screen, "[Screen]");
	Configuration_SaveSection(sConfigFileName, configs_Keyboard, "[Keyboard]");
	Configuration_SaveSection(sConfigFileName, configs_ShortCutWithMod, "[ShortcutsWithModifiers]");
	Configuration_SaveSection(sConfigFileName, configs_ShortCutWithoutMod, "[ShortcutsWithoutModifiers]");
    Configuration_SaveSection(sConfigFileName, configs_Mouse, "[Mouse]");
	Configuration_SaveSection(sConfigFileName, configs_Sound, "[Sound]");
	Configuration_SaveSection(sConfigFileName, configs_Memory, "[Memory]");
    Configuration_SaveSection(sConfigFileName, configs_Boot, "[Boot]");
	Configuration_SaveSection(sConfigFileName, configs_SCSI, "[HardDisk]");
    Configuration_SaveSection(sConfigFileName, configs_MO, "[MagnetoOptical]");
    Configuration_SaveSection(sConfigFileName, configs_Floppy, "[Floppy]");
    Configuration_SaveSection(sConfigFileName, configs_Ethernet, "[Ethernet]");
	Configuration_SaveSection(sConfigFileName, configs_Rom, "[ROM]");
	Configuration_SaveSection(sConfigFileName, configs_Printer, "[Printer]");
	Configuration_SaveSection(sConfigFileName, configs_System, "[System]");
    Configuration_SaveSection(sConfigFileName, configs_Dimension, "[Dimension]");
}
Exemplo n.º 8
0
/**
 * Open/Create snapshot file, and set flag so 'MemorySnapShot_Store' knows
 * how to handle data.
 */
static bool MemorySnapShot_OpenFile(const char *pszFileName, bool bSave)
{
	char VersionString[] = VERSION_STRING;

	/* Set error */
	bCaptureError = false;

	/* after opening file, set bCaptureSave to indicate whether
	 * 'MemorySnapShot_Store' should load from or save to a file
	 */
	if (bSave)
	{
		if (!File_QueryOverwrite(pszFileName))
			return false;

		/* Save */
		CaptureFile = MemorySnapShot_fopen(pszFileName, "wb");
		if (!CaptureFile)
		{
			fprintf(stderr, "Failed to open save file '%s': %s\n",
			        pszFileName, strerror(errno));
			bCaptureError = true;
			return false;
		}
		bCaptureSave = true;
		/* Store version string */
		MemorySnapShot_Store(VersionString, sizeof(VersionString));
	}
	else
	{
		/* Restore */
		CaptureFile = MemorySnapShot_fopen(pszFileName, "rb");
		if (!CaptureFile)
		{
			fprintf(stderr, "Failed to open file '%s': %s\n",
			        pszFileName, strerror(errno));
			bCaptureError = true;
			return false;
		}
		bCaptureSave = false;
		/* Restore version string */
		MemorySnapShot_Store(VersionString, sizeof(VersionString));
		/* Does match current version? */
		if (strcasecmp(VersionString, VERSION_STRING))
		{
			/* No, inform user and error */
			Log_AlertDlg(LOG_ERROR, "Unable to restore Hatari memory state. File\n"
			                       "is compatible only with Hatari version %s.",
				     VersionString);
			bCaptureError = true;
			return false;
		}
	}

	/* All OK */
	return true;
}
Exemplo n.º 9
0
/**
 * Save 'snapshot' of memory/chips/emulation variables
 */
void MemorySnapShot_Capture(const char *pszFileName, bool bConfirm)
{
	/* Set to 'saving' */
	if (MemorySnapShot_OpenFile(pszFileName, true))
	{
		/* Capture each files details */
		Configuration_MemorySnapShot_Capture(true);
		TOS_MemorySnapShot_Capture(true);
		STMemory_MemorySnapShot_Capture(true);
		FDC_MemorySnapShot_Capture(true);
		Floppy_MemorySnapShot_Capture(true);
		GemDOS_MemorySnapShot_Capture(true);
		ACIA_MemorySnapShot_Capture(true);
		IKBD_MemorySnapShot_Capture(true);
		CycInt_MemorySnapShot_Capture(true);
		Cycles_MemorySnapShot_Capture(true);
		M68000_MemorySnapShot_Capture(true);
		MFP_MemorySnapShot_Capture(true);
		PSG_MemorySnapShot_Capture(true);
		Sound_MemorySnapShot_Capture(true);
		Video_MemorySnapShot_Capture(true);
		Blitter_MemorySnapShot_Capture(true);
		DmaSnd_MemorySnapShot_Capture(true);
		Crossbar_MemorySnapShot_Capture(true);
		VIDEL_MemorySnapShot_Capture(true);
		DSP_MemorySnapShot_Capture(true);
		DebugUI_MemorySnapShot_Capture(pszFileName, true);
		IoMem_MemorySnapShot_Capture(true);
		/* And close */
		MemorySnapShot_CloseFile();
	} else {
		/* just canceled? */
		if (!bCaptureError)
			return;
	}

	/* Did error */
	if (bCaptureError)
		Log_AlertDlg(LOG_ERROR, "Unable to save memory state to file.");
	else if (bConfirm)
		Log_AlertDlg(LOG_INFO, "Memory state file saved.");
}
Exemplo n.º 10
0
/**
 * Start recording animation
 */
void ScreenSnapShot_BeginRecording(bool bCaptureChange)
{
	/* Set in globals */
	bGrabWhenChange = bCaptureChange;

	/* Start animation */
	bRecordingAnimation = TRUE;

	/* And inform user */
	Log_AlertDlg(LOG_INFO, "Screenshot recording started.");
}
Exemplo n.º 11
0
/**
 * Stop recording animation
 */
void ScreenSnapShot_EndRecording()
{
	/* Were we recording? */
	if (bRecordingAnimation)
	{
		/* Stop animation */
		bRecordingAnimation = FALSE;

		/* And inform user */
		Log_AlertDlg(LOG_INFO, "Screenshot recording stopped.");
	}
}
Exemplo n.º 12
0
/**
 * Insert previously set disk file image into floppy drive.
 * The WHOLE image is copied into Hatari drive buffers, and
 * uncompressed if necessary.
 * Return TRUE on success, false otherwise.
 */
bool Floppy_InsertDiskIntoDrive(int Drive)
{
	long nImageBytes = 0;
	char *filename;

	/* Eject disk, if one is inserted (doesn't inform user) */
	assert(Drive >= 0 && Drive < MAX_FLOPPYDRIVES);
	Floppy_EjectDiskFromDrive(Drive);

	filename = ConfigureParams.DiskImage.szDiskFileName[Drive];
	if (!filename[0])
	{
		return true; /* only do eject */
	}
	if (!File_Exists(filename))
	{
		Log_AlertDlg(LOG_INFO, "Image '%s' not found", filename);
		return false;
	}

	/* Check disk image type and read the file: */
	if (MSA_FileNameIsMSA(filename, true))
		EmulationDrives[Drive].pBuffer = MSA_ReadDisk(filename, &nImageBytes);
	else if (ST_FileNameIsST(filename, true))
		EmulationDrives[Drive].pBuffer = ST_ReadDisk(filename, &nImageBytes);
	else if (DIM_FileNameIsDIM(filename, true))
		EmulationDrives[Drive].pBuffer = DIM_ReadDisk(filename, &nImageBytes);
	else if (ZIP_FileNameIsZIP(filename))
	{
		const char *zippath = ConfigureParams.DiskImage.szDiskZipPath[Drive];
		EmulationDrives[Drive].pBuffer = ZIP_ReadDisk(filename, zippath, &nImageBytes);
	}

	if (EmulationDrives[Drive].pBuffer == NULL)
	{
		return false;
	}

	/* Store image filename (required for ejecting the disk later!) */
	strcpy(EmulationDrives[Drive].sFileName, filename);

	/* Store size and set drive states */
	EmulationDrives[Drive].nImageBytes = nImageBytes;
	EmulationDrives[Drive].bDiskInserted = true;
	EmulationDrives[Drive].bContentsChanged = false;
	EmulationDrives[Drive].bOKToSave = Floppy_IsBootSectorOK(Drive);
	Floppy_DriveTransitionSetState ( Drive , FLOPPY_DRIVE_TRANSITION_STATE_INSERT );
	Log_Printf(LOG_INFO, "Inserted disk '%s' to drive %c:.",
		   filename, 'A'+Drive);
	return true;
}
Exemplo n.º 13
0
/**
 * Load .IPF file into memory, set number of bytes loaded and return a pointer
 * to the buffer.
 */
Uint8 *IPF_ReadDisk(int Drive, const char *pszFileName, long *pImageSize, int *pImageType)
{
#ifndef HAVE_CAPSIMAGE
	Log_AlertDlg(LOG_ERROR, "This version of Hatari was not built with IPF support, this disk image can't be handled.");
	return NULL;

#else
	Uint8 *pIPFFile;

	*pImageSize = 0;

	/* Just load directly a buffer, and set ImageSize accordingly */
	pIPFFile = File_Read(pszFileName, pImageSize, NULL);
	if (!pIPFFile)
	{
		*pImageSize = 0;
		return NULL;
	}
	
	*pImageType = FLOPPY_IMAGE_TYPE_IPF;
	return pIPFFile;
#endif
}
Exemplo n.º 14
0
/**
 * Initialise Printer
 */
void Printer_Init(void)
{
	char *separator;
	Dprintf((stderr, "Printer_Init()\n"));

	/* disabled from config/command line? */
	if (!ConfigureParams.Printer.szPrintToFileName[0])
		return;

	/* printer name without path? */
	separator = strrchr(ConfigureParams.Printer.szPrintToFileName, PATHSEP);
	if (!separator)
		return;
	
	*separator = '\0';
	if (!File_DirExists(ConfigureParams.Printer.szPrintToFileName)) {
		Log_AlertDlg(LOG_ERROR, "Printer output file directory inaccessible. Printing disabled.");
		ConfigureParams.Printer.bEnablePrinting = false;
	}
	*separator = PATHSEP;

	Dprintf((stderr, "Filename for printing: %s \n", ConfigureParams.Printer.szPrintToFileName));
}
Exemplo n.º 15
0
/**
 * Write sizes to WAV header, then close the WAV file.
 */
void WAVFormat_CloseFile(void)
{
	if (bRecordingWav)
	{
		Uint32 nWavFileBytes;
		Uint32 nWavLEOutBytes;

		bRecordingWav = false;

		/* Update headers with sizes */
		nWavFileBytes = SDL_SwapLE32((12+24+8+nWavOutputBytes)-8);  /* File length, less 8 bytes for 'RIFF' and length */
		fseek(WavFileHndl, 4, SEEK_SET);                            /* 'Total Length Of Package' element */
		/* Write total length of package in 'RIFF' chunk */
		if (fwrite(&nWavFileBytes, sizeof(Uint32), 1, WavFileHndl) != 1)
		{
			perror("WAVFormat_CloseFile");
			fclose(WavFileHndl);
			WavFileHndl = NULL;
			return;
		}

		fseek(WavFileHndl, 12+24+4, SEEK_SET);                      /* 'Length' element */
		nWavLEOutBytes = SDL_SwapLE32(nWavOutputBytes);
		/* Write length of data in 'DATA' chunk */
		if (fwrite(&nWavLEOutBytes, sizeof(Uint32), 1, WavFileHndl) != 1)
		{
			perror("WAVFormat_CloseFile");
		}

		/* Close file */
		fclose(WavFileHndl);
		WavFileHndl = NULL;

		/* And inform user */
		Log_AlertDlg(LOG_INFO, "WAV Sound data recording has been stopped.");
	}
}
Exemplo n.º 16
0
/**
 * Test disk image for valid boot-sector.
 * It has been noticed that some disks, eg blank images made by the MakeDisk
 * utility or PaCifiST emulator fill in the boot-sector with incorrect information.
 * Such images cannot be read correctly using a real ST, and also Hatari.
 * To try and prevent data loss, we check for this error and flag the drive so
 * the image will not be saved back to the file.
 */
static bool Floppy_IsBootSectorOK(int Drive)
{
	Uint8 *pDiskBuffer;

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

		/* Check SPC (byte 13) for !=0 value. If is '0', invalid image and Hatari
		 * won't be-able to read (nor will a real ST)! */
		if (pDiskBuffer[13] != 0)
		{
			return true;      /* Disk sector is OK! */
		}
		else
		{
			Log_AlertDlg(LOG_WARN, "Disk in drive %c: maybe suffers from the Pacifist/Makedisk bug.\n"
			             "If it does not work, please repair the disk first!\n", 'A' + Drive);
		}
	}

	return false;         /* Bad sector */
}
Exemplo n.º 17
0
/**
 * Save/Restore snapshot of local variables('MemorySnapShot_Store' handles type)
 * We must take care of whether Hatari was compiled with IPF support of not
 * when saving/restoring snapshots to avoid incompatibilies.
 */
void IPF_MemorySnapShot_Capture(bool bSave)
{
	int	StructSize;
	int	Drive;

	if ( bSave )					/* Saving snapshot */
	{
		StructSize = sizeof ( IPF_State );	/* 0 if HAVE_CAPSIMAGE is not defined */
		MemorySnapShot_Store(&StructSize, sizeof(StructSize));
fprintf ( stderr , "ipf save %d\n" , StructSize );
		if ( StructSize > 0 )
			MemorySnapShot_Store(&IPF_State, sizeof(IPF_State));
	}

	else						/* Restoring snapshot */
	{
		MemorySnapShot_Store(&StructSize, sizeof(StructSize));
fprintf ( stderr , "ipf load %d\n" , StructSize );
		if ( ( StructSize == 0 ) && ( sizeof ( IPF_State ) > 0 ) )
		{
			Log_AlertDlg(LOG_ERROR, "This memory snapshot doesn't include IPF data but this version of Hatari was built with IPF support");
			return;				/* Continue restoring the rest of the memory snapshot */
		}
		else if ( ( StructSize > 0 ) && ( sizeof ( IPF_State ) == 0 ) )
		{
			Log_AlertDlg(LOG_ERROR, "This memory snapshot includes IPF data but this version of Hatari was not built with IPF support");
			MemorySnapShot_Skip( StructSize );	/* Ignore the IPF data */
			return;				/* Continue restoring the rest of the memory snapshot */
		}
		else if ( ( StructSize > 0 ) && ( StructSize != sizeof ( IPF_State ) ) )
		{
			Log_AlertDlg(LOG_ERROR, "This memory snapshot includes IPF data different from the ones handled in this version of Hatari");
			MemorySnapShot_Skip( StructSize );	/* Ignore the IPF data */
			return;				/* Continue restoring the rest of the memory snapshot */
		}

		if ( StructSize > 0 )
		{
			MemorySnapShot_Store(&IPF_State, sizeof(IPF_State));

#ifdef HAVE_CAPSIMAGE
			/* For IPF structures, we need to update some pointers in Fdc/Drive/CapsImage */
			/* drive : PUBYTE trackbuf, PUDWORD timebuf */
			/* fdc : PCAPSDRIVE driveprc, PCAPSDRIVE drive, CAPSFDCHOOK callback functions */
			CAPSFdcInvalidateTrack ( &IPF_State.Fdc , 0 );	/* Invalidate buffered track data for drive 0 */
			CAPSFdcInvalidateTrack ( &IPF_State.Fdc , 1 );	/* Invalidate buffered track data for drive 1 */

			IPF_State.Fdc.drive = IPF_State.Drive;		/* Connect drives array to the FDC */
			if ( IPF_State.Fdc.driveprc != NULL )		/* Recompute active drive's pointer */
				IPF_State.Fdc.driveprc = IPF_State.Fdc.drive + IPF_State.Fdc.driveact;

			/* Set callback functions */
			IPF_State.Fdc.cbirq = IPF_CallBack_Irq;
			IPF_State.Fdc.cbdrq = IPF_CallBack_Drq;
			IPF_State.Fdc.cbtrk = IPF_CallBack_Trk;
#endif

			/* Call IPF_Insert to recompute IPF_State.CapsImage[ Drive ] */
			for ( Drive=0 ; Drive < MAX_FLOPPYDRIVES ; Drive++ )
				if ( EmulationDrives[Drive].ImageType == FLOPPY_IMAGE_TYPE_IPF )
					if ( IPF_Insert ( Drive , EmulationDrives[Drive].pBuffer , EmulationDrives[Drive].nImageBytes ) == false )
					{
						Log_AlertDlg(LOG_ERROR, "Error restoring IPF image %s in drive %d" ,
							EmulationDrives[Drive].sFileName , Drive );
						return;
					}

		fprintf ( stderr , "ipf load ok\n" );
		}
	}
}
Exemplo n.º 18
0
/*
 * Init the ressources to handle the IPF image inserted into a drive (0=A: 1=B:)
 */
bool	IPF_Insert ( int Drive , Uint8 *pImageBuffer , long ImageSize )
{
#ifndef HAVE_CAPSIMAGE
	return false;

#else
	CapsLong	ImageId;
	CapsLong	ImageType;

	ImageId = CAPSAddImage();
	if ( ImageId < 0 )
	{
		fprintf ( stderr , "IPF : error CAPSAddImage\n" );
		return false;
	}

#if CAPS_LIB_REL_REV >= 501
	ImageType = CAPSGetImageTypeMemory ( pImageBuffer , ImageSize );
	if ( ImageType == citError )
	{
		fprintf ( stderr , "IPF : error CAPSGetImageTypeMemory\n" );
		return false;
	}
	else if ( ImageType == citUnknown )
	{
		fprintf ( stderr , "IPF : unknown image type\n" );
		return false;
	}

	fprintf ( stderr , "IPF : IPF_Insert drive=%d buf=%p size=%ld imageid=%d type=" , Drive , pImageBuffer , ImageSize , ImageId );
	switch ( ImageType ) {
		case citIPF:		fprintf ( stderr , "IPF\n" ); break;
		case citCTRaw:		fprintf ( stderr , "CT RAW\n" ); break;
		case citKFStream:	fprintf ( stderr , "KF STREAM\n" ) ; break;
		case citDraft:		fprintf ( stderr , "DRAFT\n" ) ; break;
		default :		fprintf ( stderr , "NOT SUPPORTED\n" );
					return false;
	}
#endif

	if ( CAPSLockImageMemory ( ImageId , pImageBuffer , (CapsULong)ImageSize , DI_LOCK_MEMREF ) == imgeOk )
	{
		struct CapsImageInfo cii;
		int		i;

		/* Print some debug infos */
		if ( CAPSGetImageInfo ( &cii , ImageId ) == imgeOk )
		{
			printf("Type: %d\n", (int)cii.type);
			printf("Release: %d\n", (int)cii.release);
			printf("Revision: %d\n", (int)cii.revision);
			printf("Min Cylinder: %d\n", (int)cii.mincylinder);
			printf("Max Cylinder: %d\n", (int)cii.maxcylinder);
			printf("Min Head: %d\n", (int)cii.minhead);
			printf("Max Head: %d\n", (int)cii.maxhead);
			printf("Creation Date: %04d/%02d/%02d %02d:%02d:%02d.%03d\n", (int)cii.crdt.year, (int)cii.crdt.month, (int)cii.crdt.day, (int)cii.crdt.hour, (int)cii.crdt.min, (int)cii.crdt.sec, (int)cii.crdt.tick);
			printf("Platforms:");
			for (i = 0; i < CAPS_MAXPLATFORM; i++)
				if (cii.platform[i] != ciipNA)
					printf ( " %s" , CAPSGetPlatformName(cii.platform[i]) );
			printf("\n");

			/* Some IPF disks are not correctly supported yet : display a warning */
			if ( (int)cii.release == 3222 ) 				/* Sundog */
                		Log_AlertDlg ( LOG_INFO , "'Sundog' is not correctly supported yet, it requires write access." );
			else if ( (int)cii.release == 3058 ) 				/* Lethal Xcess */
                		Log_AlertDlg ( LOG_INFO , "'Lethal Xcess' is not correctly supported yet, protection will fail" );
		}
	}
	else
	{
		CAPSRemImage ( ImageId ) ;
		return false;
	}

	if ( CAPSLoadImage ( ImageId , DI_LOCK_DENALT | DI_LOCK_DENVAR | DI_LOCK_UPDATEFD ) != imgeOk )
	{
		fprintf ( stderr , "IPF : error CAPSLoadImage\n" );
		CAPSUnlockImage ( ImageId );
		CAPSRemImage ( ImageId ) ;
		return false;
	}

	
	IPF_State.CapsImage[ Drive ] = ImageId;

	IPF_State.Drive[ Drive ].diskattr |= CAPSDRIVE_DA_IN;				/* Disk inserted, keep the value for "write protect" */

	CAPSFdcInvalidateTrack ( &IPF_State.Fdc , Drive );				/* Invalidate previous buffered track data for drive, if any */

	IPF_State.Rev_Track[ Drive ] = -1;						/* Invalidate previous track/side to handle revolution's count */
	IPF_State.Rev_Side[ Drive ] = -1;

	return true;
#endif
}
Exemplo n.º 19
0
Arquivo: zip.c Projeto: r-type/hatari
/**
 * Load disk image from a .ZIP archive into memory, set  the number
 * of bytes loaded into pImageSize and return the data or NULL on error.
 */
Uint8 *ZIP_ReadDisk(int Drive, const char *pszFileName, const char *pszZipPath, long *pImageSize, int *pImageType)
{
	uLong ImageSize=0;
	unzFile uf=NULL;
	Uint8 *buf;
	char *path;
	Uint8 *pDiskBuffer = NULL;

	*pImageSize = 0;
	*pImageType = FLOPPY_IMAGE_TYPE_NONE;

	uf = unzOpen(pszFileName);
	if (uf == NULL)
	{
		Log_Printf(LOG_ERROR, "Cannot open %s\n", pszFileName);
		return NULL;
	}

	if (pszZipPath == NULL || pszZipPath[0] == 0)
	{
		path = ZIP_FirstFile(pszFileName, pszDiskNameExts);
		if (path == NULL)
		{
			Log_Printf(LOG_ERROR, "Cannot open %s\n", pszFileName);
			unzClose(uf);
			return NULL;
		}
	}
	else
	{
		path = malloc(ZIP_PATH_MAX);
		if (path == NULL)
		{
			perror("ZIP_ReadDisk");
			unzClose(uf);
			return NULL;
		}
		strncpy(path, pszZipPath, ZIP_PATH_MAX);
		path[ZIP_PATH_MAX-1] = '\0';
	}

	ImageSize = ZIP_CheckImageFile(uf, path, ZIP_PATH_MAX, pImageType);
	if (ImageSize <= 0)
	{
		unzClose(uf);
		free(path);
		return NULL;
	}

	/* extract to buf */
	buf = ZIP_ExtractFile(uf, path, ImageSize);

	unzCloseCurrentFile(uf);
	unzClose(uf);
	free(path);
	path = NULL;

	if (buf == NULL)
	{
		return NULL;  /* failed extraction, return error */
	}

	switch(*pImageType) {
	case FLOPPY_IMAGE_TYPE_IPF:
#ifndef HAVE_CAPSIMAGE
		Log_AlertDlg(LOG_ERROR, "This version of Hatari was not built with IPF support, this disk image can't be handled.");
		return NULL;
#else
		/* return buffer */
		pDiskBuffer = buf;
		break;
#endif
	case FLOPPY_IMAGE_TYPE_STX:
		/* return buffer */
		pDiskBuffer = buf;
		break;
	case FLOPPY_IMAGE_TYPE_MSA:
		/* uncompress the MSA file */
		pDiskBuffer = MSA_UnCompress(buf, (long *)&ImageSize, ImageSize);
		free(buf);
		buf = NULL;
		break;
	case FLOPPY_IMAGE_TYPE_DIM:
		/* Skip DIM header */
		ImageSize -= 32;
		memmove(buf, buf+32, ImageSize);
		/* return buffer */
		pDiskBuffer = buf;
		break;
	case FLOPPY_IMAGE_TYPE_ST:
		/* ST image => return buffer directly */
		pDiskBuffer = buf;
		break;
	}
	
	if (pDiskBuffer)
	{
		*pImageSize = ImageSize;
	}
	return pDiskBuffer;
}