/* * Run the FDC emulation during NbCycles cycles (relative to the 8MHz FDC's clock) */ void IPF_Emulate ( void ) { #ifndef HAVE_CAPSIMAGE return; #else int NbCycles; int Drive; NbCycles = CyclesGlobalClockCounter - IPF_State.FdcClock; /* Number of cycles since last emulation */ if ( NbCycles < 0 ) NbCycles = 0; /* We should call CAPSFdcEmulate even when NbCycles=0 */ // LOG_TRACE(TRACE_FDC, "fdc ipf emulate cycles=%d VBL=%d HBL=%d clock=%lld\n" , NbCycles , nVBLs , nHBL , CyclesGlobalClockCounter ); /* Update Write Protect status for each drive */ for ( Drive=0 ; Drive < MAX_FLOPPYDRIVES ; Drive++ ) if ( Floppy_IsWriteProtected ( Drive ) ) IPF_State.Drive[ Drive ].diskattr |= CAPSDRIVE_DA_WP; /* Disk write protected */ else IPF_State.Drive[ Drive ].diskattr &= ~CAPSDRIVE_DA_WP; /* Disk is not write protected */ CAPSFdcEmulate ( &IPF_State.Fdc , NbCycles ); /* Process at max NbCycles */ IPF_State.FdcClock += IPF_State.Fdc.clockact; /* clockact can be < NbCycle in some cases */ /* Update UI's LEDs depending on Status Register */ FDC_Drive_Set_BusyLed ( (IPF_State.Fdc.r_st0 & ~IPF_State.Fdc.r_stm) | (IPF_State.Fdc.r_st1 & IPF_State.Fdc.r_stm) ); #endif }
/** * Eject disk from floppy drive, save contents back to PCs hard-drive if * they have been changed. * Return true if there was something to eject. */ bool Floppy_EjectDiskFromDrive(int Drive) { bool bEjected = false; /* Does our drive have a disk in? */ if (EmulationDrives[Drive].bDiskInserted) { bool bSaved = false; char *psFileName = EmulationDrives[Drive].sFileName; /* OK, has contents changed? If so, need to save */ if (EmulationDrives[Drive].bContentsChanged) { /* Is OK to save image (if boot-sector is bad, don't allow a save) */ if (EmulationDrives[Drive].bOKToSave && !Floppy_IsWriteProtected(Drive)) { /* Save as .MSA or .ST image? */ if (MSA_FileNameIsMSA(psFileName, true)) bSaved = MSA_WriteDisk(psFileName, EmulationDrives[Drive].pBuffer, EmulationDrives[Drive].nImageBytes); else if (ST_FileNameIsST(psFileName, true)) bSaved = ST_WriteDisk(psFileName, EmulationDrives[Drive].pBuffer, EmulationDrives[Drive].nImageBytes); else if (DIM_FileNameIsDIM(psFileName, true)) bSaved = DIM_WriteDisk(psFileName, EmulationDrives[Drive].pBuffer, EmulationDrives[Drive].nImageBytes); else if (ZIP_FileNameIsZIP(psFileName)) bSaved = ZIP_WriteDisk(psFileName, EmulationDrives[Drive].pBuffer, EmulationDrives[Drive].nImageBytes); if (bSaved) Log_Printf(LOG_INFO, "Updated the contents of floppy image '%s'.", psFileName); else Log_Printf(LOG_INFO, "Writing of this format failed or not supported, discarded the contents\n of floppy image '%s'.", psFileName); } else Log_Printf(LOG_INFO, "Writing not possible, discarded the contents of floppy image\n '%s'.", psFileName); } /* Inform user that disk has been ejected! */ Log_Printf(LOG_INFO, "Floppy %c: has been removed from drive.", 'A'+Drive); Floppy_DriveTransitionSetState ( Drive , FLOPPY_DRIVE_TRANSITION_STATE_EJECT ); bEjected = true; } /* Drive is now empty */ if (EmulationDrives[Drive].pBuffer != NULL) { free(EmulationDrives[Drive].pBuffer); EmulationDrives[Drive].pBuffer = NULL; } EmulationDrives[Drive].sFileName[0] = '\0'; EmulationDrives[Drive].nImageBytes = 0; EmulationDrives[Drive].bDiskInserted = false; EmulationDrives[Drive].bContentsChanged = false; EmulationDrives[Drive].bOKToSave = false; return bEjected; }
/** * 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; }