Exemple #1
0
void Disk2InterfaceCard::WriteTrack(const int drive)
{
	FloppyDrive* pDrive = &m_floppyDrive[ drive ];
	FloppyDisk* pFloppy = &pDrive->m_disk;

	if (pDrive->m_track >= ImageGetNumTracks(pFloppy->m_imagehandle))
		return;

	if (pFloppy->m_bWriteProtected)
		return;

	if (pFloppy->m_trackimage && pFloppy->m_imagehandle)
	{
#if LOG_DISK_TRACKS
		LOG_DISK("track $%02X%s write\r\n", pDrive->m_track, (pDrive->m_phase & 0) ? ".5" : "  "); // TODO: hard-coded to whole tracks - see below (nickw)
#endif
		ImageWriteTrack(
			pFloppy->m_imagehandle,
			pDrive->m_track,
			pDrive->m_phase, // TODO: this should never be used; it's the current phase (half-track), not that of the track to be written (nickw)
			pFloppy->m_trackimage,
			pFloppy->m_nibbles);
	}

	pFloppy->m_trackimagedirty = false;
}
Exemple #2
0
static void ReadTrack(const int iDrive)
{
	if (! IsDriveValid( iDrive ))
		return;

	Disk_t *pFloppy = &g_aFloppyDisk[ iDrive ];

	if (pFloppy->track >= ImageGetNumTracks(pFloppy->imagehandle))
	{
		pFloppy->trackimagedata = 0;
		return;
	}

	if (! pFloppy->trackimage)
		AllocTrack( iDrive );

	if (pFloppy->trackimage && pFloppy->imagehandle)
	{
		LOG_DISK("read track %2X%s\r", pFloppy->track, (pFloppy->phase & 1) ? ".5" : "");

		ImageReadTrack(
			pFloppy->imagehandle,
			pFloppy->track,
			pFloppy->phase,
			pFloppy->trackimage,
			&pFloppy->nibbles);

		pFloppy->byte           = 0;
		pFloppy->trackimagedata = (pFloppy->nibbles != 0);
	}
}
Exemple #3
0
void Disk2InterfaceCard::ReadTrack(const int drive)
{
	if (! IsDriveValid( drive ))
		return;

	FloppyDrive* pDrive = &m_floppyDrive[ drive ];
	FloppyDisk* pFloppy = &pDrive->m_disk;

	if (pDrive->m_track >= ImageGetNumTracks(pFloppy->m_imagehandle))
	{
		pFloppy->m_trackimagedata = false;
		return;
	}

	if (!pFloppy->m_trackimage)
		AllocTrack( drive );

	if (pFloppy->m_trackimage && pFloppy->m_imagehandle)
	{
#if LOG_DISK_TRACKS
		LOG_DISK("track $%02X%s read\r\n", pDrive->m_track, (pDrive->m_phase & 1) ? ".5" : "  ");
#endif
		ImageReadTrack(
			pFloppy->m_imagehandle,
			pDrive->m_track,
			pDrive->m_phase,
			pFloppy->m_trackimage,
			&pFloppy->m_nibbles,
			m_enhanceDisk);

		pFloppy->m_byte           = 0;
		pFloppy->m_trackimagedata = (pFloppy->m_nibbles != 0);
	}
}
Exemple #4
0
void __stdcall Disk2InterfaceCard::Enable(WORD, WORD address, BYTE, BYTE, ULONG uExecutedCycles)
{
	m_currDrive = address & 1;
#if LOG_DISK_ENABLE_DRIVE
	LOG_DISK("enable drive: %d\r\n", m_currDrive);
#endif
	m_floppyDrive[!m_currDrive].m_spinning   = 0;
	m_floppyDrive[!m_currDrive].m_writelight = 0;
	CheckSpinning(uExecutedCycles);
}
Exemple #5
0
void __stdcall Disk2InterfaceCard::ControlMotor(WORD, WORD address, BYTE, BYTE, ULONG uExecutedCycles)
{
	BOOL newState = address & 1;

	if (newState != m_floppyMotorOn)	// motor changed state
		m_formatTrack.DriveNotWritingTrack();

	m_floppyMotorOn = newState;
	// NB. Motor off doesn't reset the Command Decoder like reset. (UTAIIe figures 9.7 & 9.8 chip C2)
	// - so it doesn't reset this state: m_floppyLoadMode, m_floppyWriteMode, m_phases
#if LOG_DISK_MOTOR
	LOG_DISK("motor %s\r\n", (m_floppyMotorOn) ? "on" : "off");
#endif
	CheckSpinning(uExecutedCycles);
}
Exemple #6
0
void __stdcall Disk2InterfaceCard::ReadWrite(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nExecutedCycles)
{
	/* m_floppyLoadMode = 0; */
	FloppyDrive* pDrive = &m_floppyDrive[m_currDrive];
	FloppyDisk* pFloppy = &pDrive->m_disk;

	if (!pFloppy->m_trackimagedata && pFloppy->m_imagehandle)
		ReadTrack(m_currDrive);

	if (!pFloppy->m_trackimagedata)
	{
		m_floppyLatch = 0xFF;
		return;
	}

	// Improve precision of "authentic" drive mode - GH#125
	UINT uSpinNibbleCount = 0;
	CpuCalcCycles(nExecutedCycles);	// g_nCumulativeCycles required for uSpinNibbleCount & LogWriteCheckSyncFF()

	if (!m_enhanceDisk && pDrive->m_spinning)
	{
		const ULONG nCycleDiff = (ULONG) (g_nCumulativeCycles - m_diskLastCycle);
		m_diskLastCycle = g_nCumulativeCycles;

		if (nCycleDiff > 40)
		{
			// 40 cycles for a write of a 10-bit 0xFF sync byte
			uSpinNibbleCount = nCycleDiff >> 5;	// ...but divide by 32 (not 40)

			ULONG uWrapOffset = uSpinNibbleCount % pFloppy->m_nibbles;
			pFloppy->m_byte += uWrapOffset;
			if (pFloppy->m_byte >= pFloppy->m_nibbles)
				pFloppy->m_byte -= pFloppy->m_nibbles;

#if LOG_DISK_NIBBLES_SPIN
			UINT uCompleteRevolutions = uSpinNibbleCount / pFloppy->m_nibbles;
			LOG_DISK("spin: revs=%d, nibbles=%d\r\n", uCompleteRevolutions, uWrapOffset);
#endif
		}
	}
Exemple #7
0
static BYTE __stdcall DiskControlStepper(WORD, WORD address, BYTE, BYTE, ULONG)
{
	Disk_t * fptr = &g_aFloppyDisk[currdrive];
#if 1
	int phase     = (address >> 1) & 3;
	int phase_bit = (1 << phase);

	// update the magnet states
	if (address & 1)
	{
		// phase on
		phases |= phase_bit;
		LOG_DISK("track %02X phases %X phase %d on  address $C0E%X\r", fptr->phase, phases, phase, address & 0xF);
	}
	else
	{
		// phase off
		phases &= ~phase_bit;
		LOG_DISK("track %02X phases %X phase %d off address $C0E%X\r", fptr->phase, phases, phase, address & 0xF);
	}

	// check for any stepping effect from a magnet
	// - move only when the magnet opposite the cog is off
	// - move in the direction of an adjacent magnet if one is on
	// - do not move if both adjacent magnets are on
	// momentum and timing are not accounted for ... maybe one day!
	int direction = 0;
	if (phases & (1 << ((fptr->phase + 1) & 3)))
		direction += 1;
	if (phases & (1 << ((fptr->phase + 3) & 3)))
		direction -= 1;

	// apply magnet step, if any
	if (direction)
	{
		fptr->phase = MAX(0, MIN(79, fptr->phase + direction));
		const int nNumTracksInImage = ImageGetNumTracks(fptr->imagehandle);
		const int newtrack = (nNumTracksInImage == 0)	? 0
														: MIN(nNumTracksInImage-1, fptr->phase >> 1); // (round half tracks down)
		LOG_DISK("newtrack %2X%s\r", newtrack, (fptr->phase & 1) ? ".5" : "");
		if (newtrack != fptr->track)
		{
			if (fptr->trackimage && fptr->trackimagedirty)
			{
				WriteTrack(currdrive);
			}
			fptr->track          = newtrack;
			fptr->trackimagedata = 0;
		}

		// Feature Request #201 Show track status
		// https://github.com/AppleWin/AppleWin/issues/201
		FrameDrawDiskStatus( (HDC)0 );
	}
#else	// Old 1.13.1 code for Chessmaster 2000 to work! (see bug#18109)
	const int nNumTracksInImage = ImageGetNumTracks(fptr->imagehandle);
	if (address & 1) {
		int phase = (address >> 1) & 3;
		int direction = 0;
		if (phase == ((fptr->phase+1) & 3))
			direction = 1;
		if (phase == ((fptr->phase+3) & 3))
			direction = -1;
		if (direction) {
			fptr->phase = MAX(0,MIN(79,fptr->phase+direction));
			if (!(fptr->phase & 1)) {
				int newtrack = MIN(nNumTracksInImage-1,fptr->phase >> 1);
				if (newtrack != fptr->track) {
					if (fptr->trackimage && fptr->trackimagedirty)
						WriteTrack(currdrive);
					fptr->track = newtrack;
					fptr->trackimagedata = 0;
				}
			}
		}
Exemple #8
0
void __stdcall Disk2InterfaceCard::ControlStepper(WORD, WORD address, BYTE, BYTE, ULONG uExecutedCycles)
{
	FloppyDrive* pDrive = &m_floppyDrive[m_currDrive];
	FloppyDisk* pFloppy = &pDrive->m_disk;

	if (!m_floppyMotorOn)	// GH#525
	{
		if (!pDrive->m_spinning)
		{
#if LOG_DISK_PHASES
			LOG_DISK("stepper accessed whilst motor is off and not spinning\r\n");
#endif
			return;
		}

#if LOG_DISK_PHASES
		LOG_DISK("stepper accessed whilst motor is off, but still spinning\r\n");
#endif
	}

	int phase = (address >> 1) & 3;
	int phase_bit = (1 << phase);

#if 1
	// update the magnet states
	if (address & 1)
	{
		// phase on
		m_phases |= phase_bit;
	}
	else
	{
		// phase off
		m_phases &= ~phase_bit;
	}

	// check for any stepping effect from a magnet
	// - move only when the magnet opposite the cog is off
	// - move in the direction of an adjacent magnet if one is on
	// - do not move if both adjacent magnets are on
	// momentum and timing are not accounted for ... maybe one day!
	int direction = 0;
	if (m_phases & (1 << ((pDrive->m_phase + 1) & 3)))
		direction += 1;
	if (m_phases & (1 << ((pDrive->m_phase + 3) & 3)))
		direction -= 1;

	// apply magnet step, if any
	if (direction)
	{
		pDrive->m_phase = MAX(0, MIN(79, pDrive->m_phase + direction));
		const int nNumTracksInImage = ImageGetNumTracks(pFloppy->m_imagehandle);
		const int newtrack = (nNumTracksInImage == 0)	? 0
														: MIN(nNumTracksInImage-1, pDrive->m_phase >> 1); // (round half tracks down)
		if (newtrack != pDrive->m_track)
		{
			FlushCurrentTrack(m_currDrive);
			pDrive->m_track = newtrack;
			pFloppy->m_trackimagedata = false;

			m_formatTrack.DriveNotWritingTrack();
		}

		// Feature Request #201 Show track status
		// https://github.com/AppleWin/AppleWin/issues/201
		FrameDrawDiskStatus( (HDC)0 );
	}
#else
	// substitute alternate stepping code here to test
#endif

#if LOG_DISK_PHASES
	LOG_DISK("track $%02X%s phases %d%d%d%d phase %d %s address $%4X\r\n",
		pDrive->m_phase >> 1,
		(pDrive->m_phase & 1) ? ".5" : "  ",
		(m_phases >> 3) & 1,
		(m_phases >> 2) & 1,
		(m_phases >> 1) & 1,
		(m_phases >> 0) & 1,
		phase,
		(address & 1) ? "on " : "off",
		address);
#endif
}