Help on a Floppy disk controller

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
Jim
Member
Member
Posts: 27
Joined: Sun Nov 05, 2006 3:46 am

Help on a Floppy disk controller

Post by Jim »

/***************************************************************************
** HELP ** HELP ** HELP ** HELP ** HELP ** HELP ** HELP ** HELP ** HELP **

This is My Floppy driver, This driver works fine on Bochs, and On
Microsoft PC Emulator, and on Qemu, But on my real PC the Read/Write
doesn't work (It claims 'No DATA' or 'didn't find address mark' in the ST1 return value),
so it seems that the error is something with the Hardware detection of the sectors,
Does any one know how to solve the problem?????

Thanks a lot for any help, (and for your patience to read my code).

(This code was compiled by MSVC 6.0).
This is how I read a sector:

Floppy_ReadSector(nDrive,pBuffer,nSector)
Floppy_InitControllerForCommands(nDrive);
Floppy_Recalibrate(nDrive);
Floppy_Seek(nDrive,nHead,nCylinder);

DMA_SetChannel2ToReadFromFloppy();

//
//READ
//
Floppy_SendByte( (BYTE)( 0x46 ) );//0100-0110//(bit 7=MT=Multi-Track function=0),(bit 6=MFM=A one selects the double density (MFM) mode=1),(bit 5=SK=Skip flag=0),-0110
byte = (BYTE)((nHead<<2)&0x4)|(BYTE)nDrive;
Floppy_SendByte( byte );//0000-0001//0000-(bit 2=HDS=0),(bit 1=DS1),(bit 0=DS0)
Floppy_SendByte( (BYTE)nCylinder );//C = Cylinder address
Floppy_SendByte( (BYTE)nHead );//H=Head address.
Floppy_SendByte( (BYTE)nSector );//R=Sector address.
Floppy_SendByte( 02 );//N (bytes per sector).
Floppy_SendByte( 18 );//EOT = End of track.
Floppy_SendByte( 0x1B );//GPL = Gap length.
Floppy_SendByte( (BYTE)0xFF );//DTL (number of bytes to be transferred)


//
//Read returned Data
//
Floppy_GetByte(&byte);//ST0
Floppy_GetByte(&byte);//ST1
ST0_ReturnedByte = byte;//<-----
ST1_ReturnedByte = byte;//<-----
Floppy_GetByte(&byte);//ST2
ST2_ReturnedByte = byte;//<-----
Floppy_GetByte(&byte);//C
Floppy_GetByte(&byte);//H
Floppy_GetByte(&byte);//R
R_ReturnedByte=byte;//<-----
Floppy_GetByte(&byte);//N
GetKey();

Floppy_Print_ST0(ST0_ReturnedByte);
Floppy_Print_ST1(ST1_ReturnedByte);
Floppy_Print_ST2(ST2_ReturnedByte);

Code: Select all

****************************************************************************/
//Floppy.h

#ifndef __Floppy_h_
#define __Floppy_h_


#define FLOPPY_STATUS_REGISTER_A				0x3F0//Read-Only//SRA
#define FLOPPY_STATUS_REGISTER_B				0x3F1//Read-Only//SRB
#define FLOPPY_DIGITAL_OUTPUT_REGISTER			0x3F2//			//DOR
#define FLOPPY_TAPE_DRIVE_REGISTER				0x3F3//			//TDR
#define FLOPPY_MAIN_STATUS_REGISTER				0x3F4//Read-Only//MSR
#define FLOPPY_DATA_RATE_SELECT_REGISTER		0x3F4//Write-Only//DSR
#define FLOPPY_DATA_FIFO						0x3F5//			//FIFO
#define FLOPPY_DIGITAL_INPUT_REGISTER			0x3F7//Write-Only//DIR
#define FLOPPY_CONFIGURATION_CONTROL_REGISTER	0x3F7//Write-Only//CCR

//DIGITAL OUTPUT REGISTER (DOR)
#define FLOPPY_DRIVE_SEL0	0x1
#define FLOPPY_DRIVE_SEL1	0x2
#define FLOPPY_RESET		0x4
#define FLOPPY_DMA_GATE		0x8

//FLOPPY_MAIN_STATUS_REGISTER (MSR)
#define FLOPPY_MSR_READY	0x80
#define FLOPPY_MSR_READ_DRIECTION	0x40

enum FloppyCommands {

   READ_TRACK			= 2,
   SPECIFY				= 3,
   SENSE_DRIVE_STATUS	= 4,
   WRITE_DATA			= 5,
   READ_DATA			= 6,
   RECALIBRATE			= 7,
   SENSE_INTERRUPT		= 8,
   WRITE_DELETED_DATA	= 9,
   READ_ID				= 10,
   READ_DELETED_DATA	= 12,
   FORMAT_TRACK			= 13,
   SEEK					= 15,
   VERSION				= 16,
   SCAN_EQUAL			= 17,
   PERPENDICULAR_MODE	= 18,
   CONFIGURE			= 19,
   VERIFY				= 22,
   SCAN_LOW_OR_EQUAL	= 25,
   SCAN_HIGH_OR_EQUAL	= 29,

};

BOOL Floppy_Init();
void Floppy_Delay4us();
BOOL Floppy_GetByte(BYTE *pByte);
BOOL Floppy_SendByte(BYTE byte);
void Floppy_GetMainStatusInformation();
BOOL Floppy_WriteSector(DWORD nDrive,char *pBuffer,DWORD nSector);
BOOL Floppy_FormatFloppy(DWORD nDrive);
BOOL Floppy_DoneRW(DWORD nDrive);
BOOL Floppy_IsThereADrive(DWORD nDrive);
BOOL Floppy_IsThereADiskInTheDrive(DWORD nDrive);
BOOL Floppy_Seek(DWORD nDrive,DWORD nHead,DWORD nCylinder);
BOOL Floppy_Recalibrate(DWORD nDrive);
BOOL Floppy_InitControllerForCommands(DWORD nDrive);
BOOL Floppy_ReadSector(DWORD nDrive,char *pBuffer,DWORD nInputSector);
void Floppy_Print_ST0(BYTE ST0);
void Floppy_Print_ST1(BYTE ST1);
void Floppy_Print_ST2(BYTE ST2);
void Floppy_Print_ST3(BYTE ST3);
BOOL DMA_SetChannel2ToReadFromFloppy();

#define FLOPPY_DATA_RATE_1M		3
#define FLOPPY_DATA_RATE_500K	0
#define FLOPPY_DATA_RATE_300K	1
#define FLOPPY_DATA_RATE_250K	2


#define FLOPPY_RESERVED_AREA_FOR_IO 0x10000
#define FLOPPY_NUMBER_OF_SECTORS	18
#define FLOPPY_NUMBER_OF_CYLINDERS	80
#define FLOPPY_NUMBER_OF_HEADS		2

#define FLOPPY_MAX_NUMBER_OF_SECTORS \
									FLOPPY_NUMBER_OF_SECTORS*FLOPPY_NUMBER_OF_CYLINDERS*FLOPPY_NUMBER_OF_HEADS


#endif



//Floppy.C

/***************************************************************

Refrence: 82077AA data sheet

Date: 11/1/2007

Author: S.Z.Keller

****************************************************************/

#include "Define.h"
#include "IO.h"
#include "DataManipulation.h"
#include "PEKernel.h"
#include "externals.h"
#include "Keyboard.h"
#include "Floppy.h"
#include "DMA.h"
#include "CMOS.h"

////////////////////////////////////////////
//
////////////////////////////////////////////
BOOL Floppy_Init()
{
	char *pBuffer;
	DWORD loop;

	DWORD nDrive=0;


	//Check if there is floppy drives.
	if(!Floppy_IsThereADrive(nDrive))
	{
		nDrive=1;
		if(!Floppy_IsThereADrive(nDrive))
		{
			PrintColor("Didn't find any floppys!!!\n",RED_BLUE);
			GetKey();
			return FALSE;
		}
	}

	if(!Floppy_IsThereADiskInTheDrive(nDrive))
	{
		PrintColor("There is no floppy in the drive!!!\n",RED_BLUE);
		GetKey();
		return FALSE;
	}

	//Format Floppy
//	Floppy_FormatFloppy(nDrive);

again:


	pBuffer = (char*)FLOPPY_RESERVED_AREA_FOR_IO;

	if(!Floppy_WriteSector(nDrive,pBuffer,20))
	{
		PrintColor("Error Writting Sector\n",YELLOW_BLUE);
		GetKey();
		return FALSE;
	}
	memset(pBuffer,0xFF,512);
	if(!Floppy_ReadSector(nDrive,pBuffer,20))
	{
		PrintColor("Error Reading Sector\n",YELLOW_BLUE);
		GetKey();
		return FALSE;
	}

	for(loop=0;loop<512;loop++)
	{
		_sprintf(g_Buffer,"%X ",pBuffer[loop]&0xFF);
		PrintColor(g_Buffer,YELLOW_BLUE);
	}
	GetKey();

goto again;
	//
	//Shot down floppy.
	//
//	Floppy_DoneRW(nDrive);

	return TRUE;
}
////////////////////////////////////////////
//
////////////////////////////////////////////
void Floppy_Delay4us()//4 Micro Seconds.
{
	DWORD loop;

	for(loop=0;loop<10;loop++)
	{
		_inp_(FLOPPY_MAIN_STATUS_REGISTER);
	}
}
////////////////////////////////////////////
//
////////////////////////////////////////////
BOOL Floppy_ReadSector(DWORD nDrive,char *pBuffer,DWORD nInputSector)
{
	static BYTE byte;
	DWORD nSector;
	DWORD nCylinder;
	DWORD nHead;
	BYTE R_ReturnedByte;
	BYTE ST0_ReturnedByte;
	BYTE ST1_ReturnedByte;
	BYTE ST2_ReturnedByte;


	//
	//Make sure that user is not trying to read larger then the floppy
	//
	if(nInputSector>FLOPPY_MAX_NUMBER_OF_SECTORS)
	{
		PrintColor("You are trying to read a to large nSector\n",RED_BLUE);
		GetKey();
		return FALSE;
	}

	//
	//Init Controller
	//
	Floppy_InitControllerForCommands(nDrive);
	
	//
	//Recalibrate Controller (Move Floppy head to track 0).
	//
	Floppy_Recalibrate(nDrive);


	//
	//Calculate Head,Cylinder,Sector from nSector
	//
	nSector = nInputSector%FLOPPY_NUMBER_OF_SECTORS;
	nInputSector -= nSector;
	nSector++;//Remember Sectors start with 1 (not 0).
	nInputSector/=FLOPPY_NUMBER_OF_SECTORS;
	nHead = (nInputSector)%FLOPPY_NUMBER_OF_HEADS;
	nCylinder = nInputSector/FLOPPY_NUMBER_OF_HEADS;


	_sprintf(g_Buffer,"nHead = %u\n",nHead);
	PrintColor(g_Buffer,YELLOW_BLUE);
	_sprintf(g_Buffer,"nCylinder = %u\n",nCylinder);
	PrintColor(g_Buffer,YELLOW_BLUE);
	_sprintf(g_Buffer,"nSector = %u\n",nSector);
	PrintColor(g_Buffer,YELLOW_BLUE);
//	GetKey();



	Floppy_Seek(nDrive,nHead,nCylinder);

	//
	//Before Issuing a Read command, Initialize the DMA Controller.
	//Set up The 8237 DMA chip for reading from the floppy.
	//
	DMA_SetChannel2ToReadFromFloppy();

	PrintColor("Finished Init DMA\n",MAGENTA_BLUE);
//	GetKey();

	//
	//READ
	//
	Floppy_SendByte( (BYTE)( 0x46 ) );//0100-0110//(bit 7=MT=Multi-Track function=0),(bit 6=MFM=A one selects the double density (MFM) mode=1),(bit 5=SK=Skip flag=0),-0110
	byte = (BYTE)((nHead<<2)&0x4)|(BYTE)nDrive;
	Floppy_SendByte( byte );//0000-0001//0000-(bit 2=HDS=0),(bit 1=DS1),(bit 0=DS0)
	Floppy_SendByte( (BYTE)nCylinder );//C = Cylinder address
	Floppy_SendByte( (BYTE)nHead );//H=Head address.
	Floppy_SendByte( (BYTE)nSector );//R=Sector address.
	Floppy_SendByte( 02 );//N (bytes per sector).
	Floppy_SendByte( 18 );//EOT = End of track.
	Floppy_SendByte( 0x1B );//GPL = Gap length.
	Floppy_SendByte( (BYTE)0xFF );//DTL (number of bytes to be transferred)

//	Floppy_GetMainStatusInformation();

	//
	//Read returned Data
	//
	Floppy_GetByte(&byte);//ST0
	Floppy_GetByte(&byte);//ST1
	ST0_ReturnedByte = byte;//<-----
	ST1_ReturnedByte = byte;//<-----
	Floppy_GetByte(&byte);//ST2
	ST2_ReturnedByte = byte;//<-----
	Floppy_GetByte(&byte);//C
	_sprintf(g_Buffer,"C = 0x%X\n",byte&0xFF);
	PrintColor(g_Buffer,YELLOW_BLUE);
	Floppy_GetByte(&byte);//H
	_sprintf(g_Buffer,"H = 0x%X\n",byte&0xFF);
	PrintColor(g_Buffer,YELLOW_BLUE);
	Floppy_GetByte(&byte);//R
	R_ReturnedByte=byte;//<-----
	_sprintf(g_Buffer,"R = 0x%X\n",R_ReturnedByte&0xFF);
	PrintColor(g_Buffer,YELLOW_BLUE);
	Floppy_GetByte(&byte);//N
	_sprintf(g_Buffer,"N = 0x%X\n",byte&0xFF);
	PrintColor(g_Buffer,YELLOW_BLUE);
	GetKey();


	Floppy_Print_ST0(ST0_ReturnedByte);
	Floppy_Print_ST1(ST1_ReturnedByte);
	Floppy_Print_ST2(ST2_ReturnedByte);
	GetKey();

	//
	//Check if Sector count increament (if not it was in error in the last operation).
	//
	if(nSector<FLOPPY_NUMBER_OF_SECTORS)
	{
		if(R_ReturnedByte!=nSector+1)
		{
			PrintColor("Error Reading Sector\n",RED_BLUE);
			GetKey();
		}
	}
	else//nSector==FLOPPY_NUMBER_OF_SECTORS
	{
		if(R_ReturnedByte!=1)
		{
			PrintColor("Error Reading Sector\n",RED_BLUE);
			GetKey();
		}
	}

	//
	//For Floppys the output buffer is at address-->FLOPPY_RESERVED_AREA_FOR_IO
	//
	pBuffer = (char*)FLOPPY_RESERVED_AREA_FOR_IO;

	//Wait for IRQ
	if(!IRQ_WaitForIRQ(6,80))
	{
		PrintColor("ERROR: READ Timed Out\n",RED_BLUE);
		GetKey();
	}

	PrintColor("Done Reading Sector\n",CYAAN_BLUE);
	GetKey();

	return TRUE;
}
////////////////////////////////////////////
//
////////////////////////////////////////////
BOOL Floppy_WriteSector(DWORD nDrive,char *pBuffer,DWORD nInputSector)
{
	static BYTE byte;
	BYTE R_ReturnedByte;
	DWORD nSector;
	DWORD nCylinder;
	DWORD nHead;
	BYTE ST0_ReturnedByte;
	BYTE ST1_ReturnedByte;
	BYTE ST2_ReturnedByte;

	//
	//Make sure that user is not trying to Write larger then the floppy
	//
	if(nInputSector>FLOPPY_MAX_NUMBER_OF_SECTORS)
	{
		PrintColor("You are trying to Write to a to large nSector\n",RED_BLUE);
		GetKey();
		return FALSE;
	}

	//
	//Init Controller
	//
	Floppy_InitControllerForCommands(nDrive);
	
	//
	//Recalibrate Controller (Move Floppy head to track 0).
	//
	Floppy_Recalibrate(nDrive);


	//
	//Calculate Head,Cylinder,Sector from nSector
	//
	nSector = nInputSector%FLOPPY_NUMBER_OF_SECTORS;
	nInputSector -= nSector;
	nSector++;//Remember Sectors start with 1 (not 0).
	nInputSector/=FLOPPY_NUMBER_OF_SECTORS;
	nHead = (nInputSector)%FLOPPY_NUMBER_OF_HEADS;
	nCylinder = nInputSector/FLOPPY_NUMBER_OF_HEADS;



	Floppy_Seek(nDrive,nHead,nCylinder);

	//
	//Copy Input buffer to the DMA read buffer.
	//
	memcpy((char*)FLOPPY_RESERVED_AREA_FOR_IO,pBuffer,512);

	//
	//Before Issuing a Write command, Initialize the DMA Controller.
	//Set up The 8237 DMA chip for writting to the floppy.
	//
	DMA_SetChannel2ToWriteToFloppy();

	PrintColor("Finished Init DMA\n",MAGENTA_BLUE);
//	GetKey();

	//
	//WRITE
	//
	Floppy_SendByte( (BYTE)( 0x45 ) );//0100-0101//(bit 7=MT=Multi-Track function=0),(bit 6=MFM=A one selects the double density (MFM) mode=1),(bit 5=SK=Skip flag=0),-0110
	byte = (BYTE)((nHead<<2)&0x4)|(BYTE)nDrive;
	Floppy_SendByte( byte );//0000-0001//0000-(bit 2=HDS=0),(bit 1=DS1),(bit 0=DS0)
	Floppy_SendByte( (BYTE)nCylinder );//C = Cylinder address
	Floppy_SendByte( (BYTE)nHead );//H=Head address.
	Floppy_SendByte( (BYTE)nSector );//R=Sector address.
	Floppy_SendByte( 02 );//N (bytes per sector).
	Floppy_SendByte( 18 );//EOT = End of track.
	Floppy_SendByte( 0x1B );//GPL = Gap length.
	Floppy_SendByte( (BYTE)0xFF );//DTL (number of bytes to be transferred)

//	Floppy_GetMainStatusInformation();

	//
	//Read returned Data
	//
	Floppy_GetByte(&byte);//ST0
	Floppy_GetByte(&byte);//ST1
	ST0_ReturnedByte = byte;//<-----
	ST1_ReturnedByte = byte;//<-----
	Floppy_GetByte(&byte);//ST2
	ST2_ReturnedByte = byte;//<-----
	Floppy_GetByte(&byte);//C
	_sprintf(g_Buffer,"C = 0x%X\n",byte&0xFF);
	PrintColor(g_Buffer,YELLOW_BLUE);
	Floppy_GetByte(&byte);//H
	_sprintf(g_Buffer,"H = 0x%X\n",byte&0xFF);
	PrintColor(g_Buffer,YELLOW_BLUE);
	Floppy_GetByte(&byte);//R
	R_ReturnedByte=byte;//<-----
	_sprintf(g_Buffer,"R = 0x%X\n",R_ReturnedByte&0xFF);
	PrintColor(g_Buffer,YELLOW_BLUE);
	Floppy_GetByte(&byte);//N
	_sprintf(g_Buffer,"N = 0x%X\n",byte&0xFF);
	PrintColor(g_Buffer,YELLOW_BLUE);
	GetKey();


	Floppy_Print_ST0(ST0_ReturnedByte);
	Floppy_Print_ST1(ST1_ReturnedByte);
	Floppy_Print_ST2(ST2_ReturnedByte);
	GetKey();

	//
	//Check if Sector count increament (if not it was in error in the last operation).
	//
	if(nSector<FLOPPY_NUMBER_OF_SECTORS)
	{
		if(R_ReturnedByte!=nSector+1)
		{
			PrintColor("Error Writting To Sector\n",RED_BLUE);
			GetKey();
		}
	}
	else//nSector==FLOPPY_NUMBER_OF_SECTORS
	{
		if(R_ReturnedByte!=1)
		{
			PrintColor("Error Reading Sector\n",RED_BLUE);
			GetKey();
		}
	}


	//
	//Wait for IRQ
	//
	if(!IRQ_WaitForIRQ(6,80))
	{
		PrintColor("ERROR: WRITE Timed Out\n",RED_BLUE);
		GetKey();
	}

	PrintColor("Done Writting To Sector\n",CYAAN_BLUE);
	GetKey();

	return TRUE;
}
////////////////////////////////////////////
//
////////////////////////////////////////////
BOOL Floppy_FormatTrack(DWORD nDrive,DWORD nHead,DWORD nCylinder)
{
	BYTE byte;
	DWORD loop;
	DWORD nSector;
	char *pBuffer;
	BYTE ST0_ReturnedByte;
	BYTE ST1_ReturnedByte;
	BYTE ST2_ReturnedByte;

	Floppy_Seek(nDrive,nHead,nCylinder);

	//
	//Before Issuing a Write command, Initialize the DMA Controller.
	//
	//Set up The 8237 DMA chip for Writting to the floppy.
	//

	nSector=1;
	pBuffer = (char*)FLOPPY_RESERVED_AREA_FOR_IO;
	for(loop=0;loop<(FLOPPY_NUMBER_OF_SECTORS*4);loop+=4)
	{
		//C, H, R, N
		pBuffer[loop]=(BYTE)nCylinder;//C	
		pBuffer[loop+1]=(BYTE)nHead;//H
		pBuffer[loop+2]=(BYTE)nSector;//R	
		pBuffer[loop+3]=0x02;//512 bytes
		
		nSector++;
	}

	//Init DMA
	DMA_SetChannel2ToFormatFloppy();


	//
	//FORMAT
	//
	Floppy_SendByte( (BYTE)( 0x4D ) );//0100-0101//(bit 7=0),(bit 6=MFM=A one selects the double density (MFM) mode=1),(bit 5=0),-(1101==FORMAT Command)
	byte = (BYTE)((nHead<<2)&0x4)|(BYTE)nDrive;
	Floppy_SendByte( byte );//0000-0001//0000-(bit 2=HDS=0),(bit 1=DS1),(bit 0=DS0)
	Floppy_SendByte( 02 );//N (bytes per sector).
	Floppy_SendByte( 18 );//SC (sectors per cylinder).
	Floppy_SendByte( 0x54 );//GPL (Gap length for Format.).
	Floppy_SendByte( 0xF6 );//D (The pattern to be written in each sector data field during formatting.).


//	Floppy_GetMainStatusInformation();

	Floppy_GetByte(&byte);//ST0
	ST0_ReturnedByte = byte;
	Floppy_GetByte(&byte);//ST1
	ST1_ReturnedByte = byte;
	Floppy_GetByte(&byte);//ST2
	ST2_ReturnedByte = byte;
	Floppy_GetByte(&byte);//Undefined
	Floppy_GetByte(&byte);//Undefined
	Floppy_GetByte(&byte);//Undefined
	Floppy_GetByte(&byte);//Undefined

	Floppy_Print_ST0(ST0_ReturnedByte);
	Floppy_Print_ST1(ST1_ReturnedByte);
	Floppy_Print_ST2(ST2_ReturnedByte);
	

	//Wait for IRQ
	if(!IRQ_WaitForIRQ(6,80))
	{
		PrintColor("ERROR: FORMAT Timed Out\n",RED_BLUE);
		GetKey();
	}

	return TRUE;
}
////////////////////////////////////////////
//
////////////////////////////////////////////
BOOL Floppy_FormatFloppy(DWORD nDrive)
{
	DWORD loop;

	static BYTE byte;
	DWORD nSector=0;
	DWORD nCylinder=0;
	DWORD nHead=0;

	//
	//Init Controller
	//
	Floppy_InitControllerForCommands(nDrive);
	
	//
	//Recalibrate Controller (Move Floppy head to track 0).
	//
	Floppy_Recalibrate(nDrive);


	for(loop=0;loop<FLOPPY_NUMBER_OF_CYLINDERS;loop++)
	{
		Floppy_FormatTrack(nDrive,0,loop);
		Floppy_FormatTrack(nDrive,1,loop);
		_sprintf(g_Buffer,"Formatting = %u\n",loop);
		PrintColor(g_Buffer,CYAAN_BLUE);
	}


	//
	PrintColor("Press any key to continue.....\n",MAGENTA_BLUE);
	GetKey();

	return TRUE;
}
////////////////////////////////////////////
//
////////////////////////////////////////////
BOOL Floppy_InitControllerForCommands(DWORD nDrive)
{
	DWORD loop;
	static BYTE byte;

	//
	//Reset Floppy.
	//
	byte = 0x08;//0000-1000 (MOT EN3,MOT EN2,MOT EN1,MOT EN0,- 0=DMA 1=!DMA,0=Reset 1=!Reset,Drive1,Drive0)
	_outp_( (WORD)(FLOPPY_DIGITAL_OUTPUT_REGISTER) , byte);
	//Make Sure that the Drive was reseted.
	Floppy_Delay4us();
	Floppy_Delay4us();
	Floppy_Delay4us();
	Floppy_Delay4us();
	Floppy_Delay4us();

	//
	//Stop Reset and Enable Drive & Motor.
	//
	//0001-1100 (MOT EN3,MOT EN2,MOT EN1,MOT EN0,- 0=DMA 1=!DMA,0=Reset 1=!Reset,Drive1,Drive0)
	if( nDrive == 0 )
		byte|=0x1C;
	else if( nDrive == 1 )
		byte|=0x2D;
	_outp_( (WORD)(FLOPPY_DIGITAL_OUTPUT_REGISTER) , byte);

	
	//
	//Program Data rate.
	//
	byte = 0x00;//0000-00 Data Rate//(Reset),(Power-Down),(0),(0)-(0),(0),(Data rate 1),(Data rate 0)
	byte |= FLOPPY_DATA_RATE_300K;
	_outp_(FLOPPY_DATA_RATE_SELECT_REGISTER,byte);

	//Wait for IRQ
	if(!IRQ_WaitForIRQ(6,80))
	{
		PrintColor("ERROR: RESET Timed Out\n",RED_BLUE);
		GetKey();
	}

	//
	//4 times send SENSE_INTERRUPT (and read ST0, and PCN).
	//
	for(loop=0;loop<4;loop++)
	{
		Floppy_SendByte(SENSE_INTERRUPT);
		Floppy_GetByte(&byte);//Read ST0
		Floppy_GetByte(&byte);//Read PCN
	}

	//
	//CONFIGURE floppy
	//
	Floppy_SendByte( CONFIGURE );
	Floppy_SendByte( 0 );//
	Floppy_SendByte( 0x20 );//0010-0000//0,EIS,EFIFO,POLL, - (FIFOTHR 4-bits)
	Floppy_SendByte( 0 );//PRETRK



/****************************************************************
SRT 
	 This is the "Step Rate Time", which determines how long the floppy
	 drive should wait for the head to move between tracks. A reasonable
	 amount of time to allow for this is around 8 mS, but the actual
	 value used depends on the data rate. The formula for calculating 
	 the delay from SRT value and the data rate is 
	 "seconds = (16 - SRT_value)/data_rate * 500000".
	 To find the "best" SRT value this can be transformed
	 into "SRT_value = 16 - (seconds * data_rate / 500000)".
	 For a 1.44 MB floppy and 8 mS delay this gives 
	 "SRT_value = 16 - (0.008 * 500000 / 500000)" or a value of 8. 

HLT 
	This is the "Head Load Time", which determines how long 
	the floppy drive should wait for the head to become ready 
	after the head has been moved. A reasonable value for this is 
	around 10 mS, but like the SRT the delay depends on the data rate. 
	To find the delay from the HLT value and the data rate the formula 
	is "seconds = HLT_value / data_rate * 1000". To find the "best"
	HLT value this can be transformed into "HLT_value = seconds * data_rate / 1000".
	For a 1.44 MB floppy and a 10 mS delay this gives "HLT_value = 0.01 * 500000 / 1000" or 5.
	For the specify command, a HLT value of 16 is
	represented with zero (no delay isn't possible). 

HUT 
	This is the "Head Unload Time", which determines how long 
	the floppy drive should wait before setting the head to it's
	unloaded state after data is read or written (I think that if 
	the another command begins before this time expires the HLT 
	delay is avoided, but can't be sure). A reasonable value for 
	this is around 240 mS, but this delay also depends on the 
	data rate. To find the delay from the HUT value and the 
	data rate the formula is "seconds = HUT_value / data_rate * 8000".
	To find the "best" HLT value this can be transformed into 
	"HUT_value = seconds * data_rate / 8000". For a 1.44 MB floppy 
	and a 240 mS delay this gives "HLT_value = 0.24 * 500000 / 8000" 
	or 15. For the specify command, a HUT value of 128 is represented 
	with zero (no delay isn't possible). 
****************************************************************/

	//
	//SPECIFY (Init delays).
	//
	//HUT=(HeadUnload Time) = 240 mS 
	//SRT=(Step Rate Time) = 8ms = 0xD (for 250 kb rate)
	//ND=None DMA
	//HLT=(Head Load Time) = 10 mS
	//---------------------------------------
	Floppy_SendByte( SPECIFY );
	byte=(BYTE)(0x0<<4)&0xF0;//SRT
	byte|=0;//HUT
	Floppy_SendByte( byte );//(bit 4-7)SRT, (bit 0-3)HUT 
	byte=(BYTE)0x00;//HLT
	byte&=(0xFE|0);//ND
	Floppy_SendByte( byte );//0000-1110//(bit 1-7)HLT, (bit 0)ND 
	//----------------------------------------
	//Delay 500ms for Motor to speed up to the right speed.
	for(loop=0;loop<10;loop++)
	{
		Floppy_Delay4us();
	}

	PrintColor("Done Init\n",YELLOW_BLUE);


	return TRUE;
}
////////////////////////////////////////////
//When Done reading or writting or formatting, Shot down the mottor.
////////////////////////////////////////////
BOOL Floppy_DoneRW(DWORD nDrive)
{

	//0x0C = 0000-1100 (MOT EN3,MOT EN2,MOT EN1,MOT EN0,- 0=DMA 1=!DMA,0=Reset 1=!Reset,Drive1,Drive0)
	_outp_( (WORD)(FLOPPY_DIGITAL_OUTPUT_REGISTER) , 0x0C);

	return TRUE;
}
////////////////////////////////////////////
//
////////////////////////////////////////////
BOOL Floppy_VerifySector(DWORD nDrive,char *pBuffer,DWORD nSector)
{
	return TRUE;
}
////////////////////////////////////////////
//
////////////////////////////////////////////
BOOL Floppy_IsThereADrive(DWORD nDrive)
{
	static BYTE byte;
	CMOS_GetByte(0x10,&byte);
//	_sprintf(g_Buffer,"byte = 0x%X\n",byte&0xFF);
//	PrintColor(g_Buffer,YELLOW_BLUE);

	if(nDrive==0)
	{
		byte>>=4;
		byte &= 0x0F;
	}
	else if(nDrive==1)
	{
		byte &= 0x0F;
	}
	else
	{
		PrintColor("This OS dosn't support more the 2 floppys\n",RED_BLUE);
		GetKey();
		return FALSE;
	}

	switch(byte)
	{
	case 0:
		PrintColor("No Drive\n",YELLOW_BLUE);
		GetKey();
		break;
	case 1:
		PrintColor("360KB Drive (This OS dosn't support this kind of floppy)\n",YELLOW_BLUE);
		GetKey();
		break;
	case 2:
		PrintColor("1.2MB Drive (This OS dosn't support this kind of floppy)\n",YELLOW_BLUE);
		GetKey();
		break;
	case 3:
		PrintColor("720KB Drive (This OS dosn't support this kind of floppy)\n",YELLOW_BLUE);
		GetKey();
		break;
	case 4:
		PrintColor("1.44MB Drive\n",YELLOW_BLUE);
		GetKey();
		return TRUE;
		break;
	case 5:
		PrintColor("2.88MB Drive (This OS dosn't support this kind of floppy)\n",YELLOW_BLUE);
		GetKey();
		break;
	default:
		PrintColor("Unknown Value\n",RED_BLUE);
		GetKey();
	}

	return FALSE;
}
////////////////////////////////////////////
//
////////////////////////////////////////////
BOOL Floppy_IsThereADiskInTheDrive(DWORD nDrive)
{
	BYTE StatusRegister;

	//
	//Init Controller
	//
	Floppy_InitControllerForCommands(nDrive);
	
	//
	//Recalibrate Controller (Move Floppy head to track 0).
	//
	Floppy_Recalibrate(nDrive);


	StatusRegister = _inp_( FLOPPY_DIGITAL_INPUT_REGISTER );

	if(StatusRegister&0x80)//the Disk Change bit.
	{
		Floppy_Seek(nDrive,0,1);
		Floppy_Seek(nDrive,0,0);

		StatusRegister = _inp_( FLOPPY_DIGITAL_INPUT_REGISTER );
		if(StatusRegister&0x80)//the Disk Change bit.
		{
			PrintColor("Media Not Present (Please Insert Floopy)\n",RED_BLUE);
			GetKey();

			Floppy_DoneRW(0);

			return FALSE;
		}
	}

	//
	//Shot down floppy.
	//
	Floppy_DoneRW(0);

	return TRUE;
}
////////////////////////////////////////////
//
////////////////////////////////////////////
BOOL Floppy_SendByte(BYTE byte)
{
	BYTE StatusRegister;
	DWORD dwOldTime = g_dwTimerCount;

	while(1)
	{
		StatusRegister = _inp_( FLOPPY_MAIN_STATUS_REGISTER );//Read MSR
		
		if( (StatusRegister & FLOPPY_MSR_READY) &&
			!(StatusRegister & FLOPPY_MSR_READ_DRIECTION) )
			break;

		//Wait for Time out
		if(g_dwTimerCount>(dwOldTime + 25)||dwOldTime>(g_dwTimerCount+25))
		{
			PrintColor("Floppy_SendByte() TimedOut\n",RED_BLUE);
			GetKey();
			return FALSE;
		}

	}

	_outp_( (WORD)(FLOPPY_DATA_FIFO) , byte);

	return TRUE;
}
////////////////////////////////////////////
//
////////////////////////////////////////////
BOOL Floppy_GetByte(BYTE *pByte)
{
	BYTE StatusRegister;
	DWORD dwOldTime = g_dwTimerCount;

	while(1)
	{
		StatusRegister = _inp_( FLOPPY_MAIN_STATUS_REGISTER );//Read MSR
		
		if( (StatusRegister & FLOPPY_MSR_READY) &&
			(StatusRegister & FLOPPY_MSR_READ_DRIECTION) )
			break;

		//Wait for Time out
		if(g_dwTimerCount>(dwOldTime + 40)||dwOldTime>(g_dwTimerCount+40))
		{
			PrintColor("Floppy_GetByte() TimedOut\n",RED_BLUE);
			GetKey();
			return FALSE;
		}
	}

	*pByte = _inp_( (WORD)(FLOPPY_DATA_FIFO) );

	return TRUE;
}
////////////////////////////////////////////
//
////////////////////////////////////////////
void Floppy_GetMainStatusInformation()
{
	BYTE MainStatusRegister;

	MainStatusRegister = _inp_( (WORD)(FLOPPY_MAIN_STATUS_REGISTER) );

//	_sprintf(g_Buffer,"MainStatusRegister = 0x%X\n",MainStatusRegister&0xFF);
//	PrintColor(g_Buffer,YELLOW_BLUE);

	if(MainStatusRegister&0x1)
	{
		PrintColor("Drive 0 Busy\n",YELLOW_BLUE);
	}
	if((MainStatusRegister>>1)&0x1)
	{
		PrintColor("Drive 1 Busy\n",YELLOW_BLUE);
	}
	if((MainStatusRegister>>2)&0x1)
	{
		PrintColor("Drive 2 Busy\n",YELLOW_BLUE);
	}
	if((MainStatusRegister>>3)&0x1)
	{
		PrintColor("Drive 3 Busy\n",YELLOW_BLUE);
	}

	if((MainStatusRegister>>4)&0x1)
	{
		PrintColor("COMMAND BUSY (command is in progress).\n",YELLOW_BLUE);
	}
	if(MainStatusRegister>>5&0x1)
	{
		PrintColor("NON-DMA\n",YELLOW_BLUE);
	}

	if((MainStatusRegister>>6)&0x1)
	{
		PrintColor("Direction I/O Read\n",YELLOW_BLUE);
	}
	else
	{
		PrintColor("Direction I/O Write\n",YELLOW_BLUE);
	}

	if((MainStatusRegister>>7)&0x1)
	{
		PrintColor("Host can transfer data\n",YELLOW_BLUE);
	}
	else
	{
		PrintColor("Host can't transfer data\n",YELLOW_BLUE);
	}
}
////////////////////////////////////////////
//
////////////////////////////////////////////
BOOL Floppy_Recalibrate(DWORD nDrive)
{
	BYTE byte;

	//
	//RECALIBRATE (Move head to track 0).
	//
	Floppy_SendByte( RECALIBRATE );
	if( nDrive==0 )
		byte=0;
	else if( nDrive==1 )
		byte=1;
	Floppy_SendByte( byte );//Drive Select (0-3 drives).


	//Wait for IRQ
	if(!IRQ_WaitForIRQ(6,80))
	{
		PrintColor("ERROR: RECALIBRATE Timed Out\n",RED_BLUE);
		GetKey();
		return FALSE;
	}


	//
	//SENSE_INTERRUPT
	//
	Floppy_SendByte( SENSE_INTERRUPT );
	Floppy_GetByte(&byte);//Read ST0
	Floppy_GetByte(&byte);//Read PCN

	return TRUE;
}
////////////////////////////////////////////
//
////////////////////////////////////////////
BOOL Floppy_Seek(DWORD nDrive,DWORD nHead,DWORD nCylinder)
{
	BYTE byte;

	//
	//SEEK
	//
	Floppy_SendByte( SEEK );
	byte = (BYTE)( ((BYTE)(nHead&0xFF)<<2)|(BYTE)(nDrive&0xFF) );
	Floppy_SendByte( byte );//(bit 2-HDS), Drive Select (0-3 drives) (bit1 and bit0).
	Floppy_SendByte( (BYTE)nCylinder );//New Cylinder

	//Wait for IRQ
	if(!IRQ_WaitForIRQ(6,80))
	{
		PrintColor("ERROR: SEEK Timed Out\n",RED_BLUE);
		GetKey();
	}


	//
	//SENSE_INTERRUPT
	//
	Floppy_SendByte( SENSE_INTERRUPT );
	Floppy_GetByte(&byte);//Read ST0
	Floppy_GetByte(&byte);//Read PCN


	return TRUE;
}
////////////////////////////////////////////
//
////////////////////////////////////////////
void Floppy_Print_ST0(BYTE ST0)
{

	PrintColor("*************ST0*************\n",MAGENTA_BLUE);

	switch((ST0>>6)&0x3)//bit 7-6
	{
	case 0:
		PrintColor("Normal termination of command.\n",YELLOW_BLUE);
		break;
	case 1:
		PrintColor("Abnormal termination of command.\n",YELLOW_BLUE);
		break;
	case 2:
		PrintColor("Invalid command. The requested command could not be executed.\n",YELLOW_BLUE);
		break;
	case 3:
		PrintColor("Abnormal termination caused by Polling.\n",YELLOW_BLUE);
		break;
	}

	if((ST0>>5)&0x1)
	{
		PrintColor("SEEK END.\n",YELLOW_BLUE);
	}

	if((ST0>>4)&0x1)
	{
		PrintColor("The TRK0 pin failed to become a '1' (For more info see datasheet).\n",YELLOW_BLUE);
	}

	_sprintf(g_Buffer,"Head Address = %u\n",(ST0>>2&0x1)&0xFF);
	PrintColor(g_Buffer,YELLOW_BLUE);

	switch(ST0&0x3)//bit 1-0
	{
	case 0:
		PrintColor("Drive 0.\n",YELLOW_BLUE);
		break;
	case 1:
		PrintColor("Drive 1.\n",YELLOW_BLUE);
		break;
	case 2:
		PrintColor("Drive 2.\n",YELLOW_BLUE);
		break;
	case 3:
		PrintColor("Drive 3.\n",YELLOW_BLUE);
		break;
	}


	PrintColor("*****************************\n",MAGENTA_BLUE);
//	GetKey();
}
////////////////////////////////////////////
//
////////////////////////////////////////////
void Floppy_Print_ST1(BYTE ST1)
{

	PrintColor("*************ST1*************\n",MAGENTA_BLUE);


	if((ST1>>7)&0x1)
	{
		PrintColor("ERROR: End of Cylinder.\n",YELLOW_BLUE);
	}
	//--
	if((ST1>>5)&0x1)
	{
		PrintColor("CRC error.\n",YELLOW_BLUE);
	}
	if((ST1>>4)&0x1)
	{
		PrintColor("CPU or DMA is not R or W from controller.\n",YELLOW_BLUE);
	}
	//--
	if((ST1>>2)&0x1)
	{
		PrintColor("No Data.\n",YELLOW_BLUE);
	}
	if((ST1>>1)&0x1)
	{
		PrintColor("Not Writable.\n",YELLOW_BLUE);
	}
	if(ST1&0x1)
	{
		PrintColor("Missing Address Mark.\n",YELLOW_BLUE);
	}



	PrintColor("*****************************\n",MAGENTA_BLUE);
//	GetKey();
}
////////////////////////////////////////////
//
////////////////////////////////////////////
void Floppy_Print_ST2(BYTE ST2)
{

	PrintColor("*************ST2*************\n",MAGENTA_BLUE);


	//--
	if((ST2>>6)&0x1)
	{
		PrintColor("Control Mark.\n",YELLOW_BLUE);
	}
	if((ST2>>5)&0x1)
	{
		PrintColor("Data Error in Data Field..\n",YELLOW_BLUE);
	}
	if((ST2>>4)&0x1)
	{
		PrintColor("Wrong Cylinder.\n",YELLOW_BLUE);
	}
	//--
	//--
	if((ST2>>1)&0x1)
	{
		PrintColor("Bad Cylinder.\n",YELLOW_BLUE);
	}
	if((ST2>>0)&0x1)
	{
		PrintColor("Missing Data Address Mark.\n",YELLOW_BLUE);
	}



	PrintColor("*****************************\n",MAGENTA_BLUE);
//	GetKey();
}
////////////////////////////////////////////
//
////////////////////////////////////////////
void Floppy_Print_ST3(BYTE ST3)
{

	PrintColor("*************ST3*************\n",MAGENTA_BLUE);


	if((ST3>>6)&0x1)
	{
		PrintColor("Write Protected.\n",YELLOW_BLUE);
	}

	_sprintf(g_Buffer,"The status of the TRK0 pin = 0x%X\n",(ST3>>4&0x1)&0xFF);
	PrintColor(g_Buffer,YELLOW_BLUE);
	_sprintf(g_Buffer,"Head Address = %u\n",(ST3>>2&0x1)&0xFF);
	PrintColor(g_Buffer,YELLOW_BLUE);

	switch(ST3&0x3)//bit 1-0
	{
	case 0:
		PrintColor("Drive 0.\n",YELLOW_BLUE);
		break;
	case 1:
		PrintColor("Drive 1.\n",YELLOW_BLUE);
		break;
	case 2:
		PrintColor("Drive 2.\n",YELLOW_BLUE);
		break;
	case 3:
		PrintColor("Drive 3.\n",YELLOW_BLUE);
		break;
	}

	PrintColor("*****************************\n",MAGENTA_BLUE);
	GetKey();
}
////////////////////////////////////////////////////////////////
//DMA
////////////////////////////////////////////////////////////////

//
//DMA Address & Control registers.
//
#define DMA_8_BIT_CANNEL_0_ADDRESS_PORT 0x00
#define DMA_8_BIT_CANNEL_0_COUNT_PORT	0x01

#define DMA_8_BIT_CANNEL_1_ADDRESS_PORT 0x02
#define DMA_8_BIT_CANNEL_1_COUNT_PORT	0x03

#define DMA_8_BIT_CANNEL_2_ADDRESS_PORT 0x04
#define DMA_8_BIT_CANNEL_2_COUNT_PORT	0x05

#define DMA_8_BIT_CANNEL_3_ADDRESS_PORT 0x06
#define DMA_8_BIT_CANNEL_3_COUNT_PORT	0x07



#define DMA_16_BIT_CANNEL_4_ADDRESS_PORT	0xC0
#define DMA_16_BIT_CANNEL_4_COUNT_PORT		0xC2

#define DMA_16_BIT_CANNEL_5_ADDRESS_PORT	0xC4
#define DMA_16_BIT_CANNEL_5_COUNT_PORT		0xC6

#define DMA_16_BIT_CANNEL_6_ADDRESS_PORT	0xC8
#define DMA_16_BIT_CANNEL_6_COUNT_PORT		0xCA

#define DMA_16_BIT_CANNEL_7_ADDRESS_PORT	0xCC
#define DMA_16_BIT_CANNEL_7_COUNT_PORT		0xCE

//
//Page Registers
//
#define DMA_8_BIT_CANNEL_0_PAGE	0x87
#define DMA_8_BIT_CANNEL_1_PAGE	0x83
#define DMA_8_BIT_CANNEL_2_PAGE	0x81
#define DMA_8_BIT_CANNEL_3_PAGE	0x82

#define DMA_16_BIT_CANNEL_4_PAGE	0x8F
#define DMA_16_BIT_CANNEL_5_PAGE	0x8B
#define DMA_16_BIT_CANNEL_6_PAGE	0x89
#define DMA_16_BIT_CANNEL_7_PAGE	0x8A

//
//Status Registers 
//
#define DMA_8_BIT_STATUS_REGISTERS	0x08
#define DMA_16_BIT_STATUS_REGISTERS	0xD0


//
//Command Registers (Write) 
//
#define DMA_8_BIT_COMMAND_REGISTERS		0x08
#define DMA_16_BIT_COMMAND_REGISTERS	0xD0

//
//Request Registers
//
#define DMA_8_BIT_REQUST_REGISTERS	0x09
#define DMA_16_BIT_REQUST_REGISTERS	0xD2

//
//Channel Mask Registers 
//
#define DMA_8_BIT_CHANNEL_MASK_REGISTERS	0x0A
#define DMA_16_BIT_CHANNEL_MASK_REGISTERS	0xD4

//
//Mask Registers 
//
#define DMA_8_BIT_MASK_REGISTERS	0x0F
#define DMA_16_BIT_MASK_REGISTERS	0xDE

//
//Mode Registers
//
#define DMA_8_BIT_MODE_REGISTERS	0x0B
#define DMA_16_BIT_MODE_REGISTERS	0xD6

//
//Byte / Word Register
//
#define DMA_8_BIT_BYTE_REGISTERS	0x0C
#define DMA_16_BIT_WORD_REGISTERS	0xD8


//
//Intermediate Register
//
#define DMA_8_BIT_INTERMEDIATE_REGISTERS	0x0D
#define DMA_16_BIT_INTERMEDIATE_REGISTERS	0xDA

////////////////////////////////////////////
//
//Routine Name: DMA_SetChannel2ToReadFromFloppy()
//
//
//Routine Description:
// 
//		Set up the 8237 DMA chip for reading 512 bytes
//		from the floppy controller, to address FLOPPY_RESERVED_AREA_FOR_IO
//
//Return Value: None
//
//Error Handeling: None
//
//Auther: S.Z.Keller
//
////////////////////////////////////////////
BOOL DMA_SetChannel2ToReadFromFloppy()
{

	//Mask Channel 2
	_outp_(DMA_8_BIT_CHANNEL_MASK_REGISTERS, 0x6);//0000-0110//0000-0,(1 - Set mask bit),(1- Select channel 2 mask bit),(0)

	//Reset the master flip-flop
	_outp_(DMA_16_BIT_WORD_REGISTERS, (BYTE)0xFF);

	//Destination address
	_outp_(DMA_8_BIT_CANNEL_2_ADDRESS_PORT, (BYTE)(FLOPPY_RESERVED_AREA_FOR_IO)&0xFF);//(low byte)
	_outp_(DMA_8_BIT_CANNEL_2_ADDRESS_PORT, (BYTE)(FLOPPY_RESERVED_AREA_FOR_IO>>8)&0xFF);//(high byte)

	//Reset the master flip-flop
	_outp_(DMA_16_BIT_WORD_REGISTERS, (BYTE)0xFF);

	//Number of bytes to transfore (0x1FF = 512-1) because it starts with Index 0
	_outp_(DMA_8_BIT_CANNEL_2_COUNT_PORT, (BYTE)0xFF);//(low byte)
	_outp_(DMA_8_BIT_CANNEL_2_COUNT_PORT, (BYTE)0x01);//(high byte)

	//(The 16-20 bits of the Base address)
	_outp_(DMA_8_BIT_CANNEL_2_PAGE, (BYTE)(FLOPPY_RESERVED_AREA_FOR_IO>>16)&0xFF);


	//Transforem Mode 
	//( [0100-0110]			-0100-0110
	//--------------------------------------
	// Single transfer,		-01
	// address increment,	-0
	// Autoinitialized,		-0
	// Read transfer,		-01
	// Channel 2 select)	-10
	_outp_(DMA_8_BIT_MODE_REGISTERS, (BYTE)0x46);

	//unmask DMA channel 2
	_outp_(DMA_8_BIT_CHANNEL_MASK_REGISTERS, (BYTE)2);



	return TRUE;
}
Last edited by Jim on Sun Jan 21, 2007 1:21 pm, edited 1 time in total.
User avatar
bubach
Member
Member
Posts: 1223
Joined: Sat Oct 23, 2004 11:00 pm
Location: Sweden
Contact:

Post by bubach »

Please edit you post and use

Code: Select all

 [ /code] tags around your code.
"Simplicity is the ultimate sophistication."
http://bos.asmhackers.net/ - GitHub
frank
Member
Member
Posts: 729
Joined: Sat Dec 30, 2006 2:31 pm
Location: East Coast, USA

Post by frank »

Have you tried using longer delays? Sometimes if the delays are too short, it will work in an emulator just fine, but not on real hardware.

Frank
Jim
Member
Member
Posts: 27
Joined: Sun Nov 05, 2006 3:46 am

I got it working

Post by Jim »

:D :D :D
It seems that the problom was that after a SEEK you must delay to let
the Head of the Floppy drive settele, so after I added a delay of 15 ms
it works
:D :D :D
Post Reply