📄 fdbios.cpp
字号:
/*
Floppy Disk Tools v1.2 Final version write by 孙宝建
12-15-2002
*/
//#include "stdafx.h"
#include "fdbios.h"
#include <stdlib.h>
#include <dos.h>
#include <stdio.h>
#include<io.h>
#include<fcntl.h>
#include <conio.h>
BOOL CFDBios::SendCommand(USHORT ucCommand)
{
if(IsWriteReady())
{
_outp(0x3f5,ucCommand);
return TRUE;
}
else
{
return FALSE;
}
}
BOOL CFDBios::IsReadReady()
{
int i=0;
while( i<CONTROL_TIME)
{
CHAR ret=_inp(0x3f4);
if( READREADY(ret) )
{
return TRUE;
}
if( WRITEREADY(ret) )
{
uError=STATUS_READ;
return FALSE;
}
i++;
}
uError=CONTROL_OVER_TIME;
return FALSE;
}
BOOL CFDBios::IsWriteReady()
{
int i=0;
while( i<CONTROL_TIME)
{
CHAR ret=_inp(0x3f4);
if( WRITEREADY(ret) )
{
return TRUE;
}
if( READREADY(ret) )
{
uError=STATUS_WRITE;
return FALSE;
}
i++;
}
uError=CONTROL_OVER_TIME;
return FALSE;
}
void CFDBios::DetectFD(void)
{
ucDiskNumber=0;
_outp(0x3f7,0);
uError=NO_FD;
StartMotor();
if( Reset())
{
uError=OK;
}
else
{
uError=NO_FD;
}
ShutMotor();
}
void CFDBios::StartMotor(void)
{
switch(ucDiskNumber)
{
case 0:_outp(0x3f2,0x1C);break;
case 1:_outp(0x3f2,0x2d);break;
default:;
}
Delay(START_MOTOR_DELAY);
bMotorWork=TRUE;
}
void CFDBios::ShutMotor(void)
{
switch(ucDiskNumber)
{
case 0:_outp(0x3f2,0x0c);break;
case 1:_outp(0x3f2,0x0d);break;
default:;
}
bMotorWork=FALSE;
}
BOOL CFDBios::IsComplete(void)
{
int i;
for(i=0;i<WAIT_INT_TIME;i++)
{
#ifdef __BORLANDC__
Delay30us(MAX_WAIT);
char *pcIntFlag=(char far*)MK_FP(0X40,0X3E);
if( (*pcIntFlag) & 0x80)
{
*pcIntFlag=0;
return 1;
}
/*char ret=_inp(0x3f4);
if(COMPLETE(ret))
return TRUE;
*/
#endif
#ifdef __DJGPP__
#endif
// StartMotor();
_outp(0x3f2,0x1C);
}
return 0;
}
void CFDBios::Delay(int Count)
{
Delayms(Count);
}
void CFDBios::IoDelay(int delaytimes)
{
// int i=0;
// for(i=0;i<delaytimes;i++)
Delay500ns(delaytimes);
}
BOOL CFDBios::Reset(void)
{
/* if(!(_inp(0x3f7)&0x80))
{
return TRUE;
}
*/
if(ExistDisk())
return TRUE;
EnableINT();
for(int i=0;i<MAX_RETRY;i++)
{
if( SendCommand(7) )
{
if( SendCommand(ucDiskNumber) )
{
if( IsComplete() )
{
if( IsTrack(0) )
{
return TRUE;
}
}
}
}
if( !CanRetry() )
return FALSE;
}
uError=OVER_TIMES;
return FALSE;
}
void CFDBios::DisplayError(char *psErr)
{
switch (uError)
{
case NO_FD :sprintf(psErr,"No disk\n"); break;
case INVALID_BUFFER :sprintf(psErr,"Invalid buffer\n"); break;
case OVER_TIME :sprintf(psErr,"Over time\n"); break;
case STATUS_WRITE :sprintf(psErr,"Controller error:Status write \n"); break;
case STATUS_READ :sprintf(psErr,"Controller error:Status read \n"); break;
case CONTROL_OVER_TIME :sprintf(psErr,"Controller over time\n"); break;
case NO_RESPONSE :sprintf(psErr,"Controller no response \n"); break;
case OVER_TIMES :sprintf(psErr,"Retry fail\n"); break;
case NO_INT :sprintf(psErr,"No int \n"); break;
case VALID_COMMAND :sprintf(psErr,"Valid command \n"); break;
case EXCEPT_TERMINATE:sprintf(psErr,"Except terminate\n"); break;
case INCORRECT_TRACK :sprintf(psErr,"Incorrect track\n"); break;
case OVER_LAST_SECTOR:sprintf(psErr,"Over last sector\n");break;
case ID_CRC :sprintf(psErr,"Sector id CRC error \n");break;
case DMA_OVER_TIME :sprintf(psErr,"DMA over time\n");break;
case WRITE_PROTECT :sprintf(psErr,"Write protect\n");break;
case LOST_ID :sprintf(psErr,"Lost sector id\n");break;
case CONTRL_ID :sprintf(psErr,"Lost contrl id\n");break;
case DATA_CRC :sprintf(psErr,"Data CRC error\n");break;
case TRACK_ERR :sprintf(psErr,"Track error\n");break;
case BAD_TRACK :sprintf(psErr,"Bad track\n");break;
case ADDRESS_ID :sprintf(psErr,"ADDRESS_ID\n");break;
default :uError=UNKNOWN_ERROR;sprintf(psErr,"Unknown error\n");
}
}
void CFDBios::ClearCommand(void)
{
CHAR ret=_inp(0x3f4);
if( READREADY(ret) )
{
ret=_inp(0x3f5);
while(1)
{
ret=_inp(0x3f4);
if( READREADY(ret) )
{
ret=_inp(0x3f5);
}
else
{
_outp(0x3f2,0x1C);
return;
}
}
}
if( WRITEREADY(ret) )
{
_outp(0x3f5,0x36);
while(1)
{
ret=_inp(0x3f4);
if( WRITEREADY(ret) )
{
_outp(0x3f5,0x36);
}
else
{
_outp(0x3f2,0x1C);
return;
}
}
}
}
BOOL CFDBios::CanRetry()
{
switch (uError)
{
case STATUS_WRITE:
case STATUS_READ :
case CONTROL_OVER_TIME :
case NO_INT:
case NO_RESPONSE :
ClearCommand();return TRUE;
case VALID_COMMAND :
case EXCEPT_TERMINATE:
/* ResetController();*/return TRUE;
case OVER_TIMES:
return FALSE;
default:
/* ResetController();*/return TRUE;
}
}
void CFDBios::ResetController(void)
{
CHAR tmp=(_inp(0x3f2)|ucDiskNumber)&(0x0fb);
_outp(0x3f2,tmp);
_outp(0x3f5,0x36);
Delay(RESET_TIME);
}
BOOL CFDBios::IsTrack(USHORT ucTrack)
{
StartMotor();
for(int i=0;i<MAX_RETRY;i++)
{
if( SendCommand(8) )
{
Delay(COMMAND8_DELAY);
if( GetResult() )
{
//char tmp=ucResult;
if( ((~ucResult)&0x80)
&& ((~ucResult)&0x40) )
{
if( GetResult() )
{
if( ucResult==ucTrack )
return TRUE;
if( ucResult==0x80 )
{
uError=NO_INT;
return FALSE;
}
else
{
if( ucResult<80)
{
uError=INCORRECT_TRACK;
return FALSE;
}
}
}
}
else
{
TranResult(ucResult);
}
}
}
if( !CanRetry() )
return FALSE;
}
uError=OVER_TIMES;
return FALSE;
}
BOOL CFDBios::GetResult(void)
{
if( IsReadReady() )
{
ucResult=_inp(0x3f5);
return TRUE;
}
else
{
return FALSE;
}
}
void CFDBios::TranResult(CHAR Result)
{
if( (Result&0x80) && (!(Result&0x40)) )
{
uError=VALID_COMMAND;
}
if( !(Result&0x80) && (Result&0x40) )
{
uError=EXCEPT_TERMINATE;
}
if( !(Result&0x80) && !(Result&0x40) )
{
uError=OK;
}
}
BOOL CFDBios::GotoTrack(USHORT ucTrack)
{
for(int i=0;i<MAX_RETRY;i++)
{
EnableINT();
if( SendCommand(0x0f) )
{
if( SendCommand(ucDiskNumber) )
{
if( SendCommand(ucTrack) )
{
if( IsComplete() )
{
Delay(COMMANDF_DELAY);
if( IsTrack(ucTrack) )
return TRUE;
}
}
}
}
if( !CanRetry() )
return FALSE;
}
uError=OVER_TIMES;
return FALSE;
}
void CFDBios::StartDMA(CHAR ucCommand,CHAR ucnSectors,
int ucBytesOfSector,char *pBuffer)
{
#ifdef __BORLANDC__
ULONG uwSegment=(FP_SEG(pBuffer));
int uwOffset=(FP_OFF(pBuffer));//%16;
int uCount=ucnSectors*ucBytesOfSector-1;
ULONG tmp=uwSegment*16;
tmp=tmp+uwOffset;
_outp(0x0c,ucCommand);
_outp(0x0b,ucCommand);
_outp(0x4,tmp & 0x00ff);
_outp(0x4,(tmp>>8) & 0x0ff );
_outp(0x81,(tmp>>16) & 0x0f );
_outp(0x5,uCount&0x0ff);
_outp(0x5,(uCount>>8) & 0xff);
_outp(0x0a,2);
#else
int uCount=ucnSectors*ucBytesOfSector-1;
ULONG tmp=(ULONG)pBuffer;
_outp(0x0c,ucCommand);
_outp(0x0b,ucCommand);
_outp(0x4,tmp & 0x00ff);
_outp(0x4,(tmp>>8) & 0x0ff );
_outp(0x81,(tmp>>16) & 0xFf );
_outp(0x481,(tmp>>24) & 0xFf );
_outp(0x5,uCount&0x0ff);
_outp(0x5,(uCount>>8) & 0xff);
_outp(0x0a,2);
#endif
}
BOOL CFDBios::ReadSector(CHAR ucTrack,CHAR ucHead,CHAR ucStartSector,
CHAR ucnSectors,CHAR ucSectorBytesCode,CHAR ucLastSector,
CHAR ucSectorL)
{
for( int i=0;i<MAX_RETRY;i++)
{
if( Reset() )
{
if( GotoTrack(ucTrack) )
{
int tmp=GetSectorBytes(ucSectorBytesCode);
StartDMA(READ_DISK,ucnSectors,tmp,pBuffer);//MAX_ALL_BYTES,pBuffer);
EnableINT();
if( SendCommand(0x0e6) )
{
CHAR tmp2= ucHead<<2;
if( SendCommand(ucDiskNumber|tmp2) )
{
if( SendCommand(ucTrack) )
{
if( SendCommand(ucHead) )
{
if( SendCommand(ucStartSector) )
{
if( SendCommand(ucSectorBytesCode) )
{
if( SendCommand(ucLastSector) )
{
if( SendCommand(ucSectorL) )
{
if( SendCommand(0x0ff) )
{
if( IsComplete() )
{
if( GetErr(7) )
return TRUE;
}
}
}
}
}
}
}
}
}
}
}
}
if( !CanRetry() )
return FALSE;
}
if( uError==OK )
return TRUE;
else
return FALSE;
}
BOOL CFDBios::ReadSectorEx(CHAR ucTrack,CHAR ucHead,CHAR ucStartSector,
CHAR ucnSectors,CHAR ucSectorBytesCode,CHAR ucLastSector,
CHAR ucSectorL,int uReadBytes)
{
for( int i=0;i<MAX_RETRY;i++)
{
if(Reset() )
{
if( GotoTrack(ucTrack) )
{
StartDMA(READ_DISK,ucnSectors,uReadBytes,pBuffer);//MAX_ALL_BYTES,pBuffer);
EnableINT();
if( SendCommand(0x0e6) )
{
CHAR tmp2= ucHead<<2;
if( SendCommand(ucDiskNumber|tmp2) )
{
if( SendCommand(ucTrack) )
{
if( SendCommand(ucHead) )
{
if( SendCommand(ucStartSector) )
{
if( SendCommand(ucSectorBytesCode) )
{
if( SendCommand(ucLastSector) )
{
if( SendCommand(ucSectorL) )
{
if( SendCommand(0x0ff) )
{
if( IsComplete() )
{
if( GetErr(7) )
return TRUE;
}
}
}
}
}
}
}
}
}
}
}
}
if( !CanRetry() )
return FALSE;
}
if( uError==OK )
return TRUE;
else
return FALSE;
}
BOOL CFDBios::WriteSectorEx(CHAR ucTrack,CHAR ucHead,CHAR ucStartSector,
CHAR ucnSectors,CHAR ucSectorBytesCode,CHAR ucLastSector,
CHAR ucSectorL,int uReadBytes)
{
for( int i=0;i<MAX_RETRY;i++)
{
if(Reset() )
{
if( GotoTrack(ucTrack) )
{
StartDMA(READ_DISK,ucnSectors,uReadBytes,pBuffer);//MAX_ALL_BYTES,pBuffer);
EnableINT();
if( SendCommand(0x0c5) )
{
CHAR tmp2= ucHead<<2;
if( SendCommand(ucDiskNumber|tmp2) )
{
if( SendCommand(ucTrack) )
{
if( SendCommand(ucHead) )
{
if( SendCommand(ucStartSector) )
{
if( SendCommand(ucSectorBytesCode) )
{
if( SendCommand(ucLastSector) )
{
if( SendCommand(ucSectorL) )
{
if( SendCommand(0x0ff) )
{
if( IsComplete() )
{
if( GetErr(7) )
return TRUE;
}
}
}
}
}
}
}
}
}
}
}
}
if( !CanRetry() )
return FALSE;
}
if( uError==OK )
return TRUE;
else
return FALSE;
}
BOOL CFDBios::WriteSector(CHAR ucTrack,CHAR ucHead,CHAR ucStartSector,
CHAR ucnSectors,CHAR ucSectorBytesCode,CHAR ucLastSector,
CHAR ucSectorL)
{
for( int i=0;i<MAX_RETRY;i++)
{
if(Reset() )
{
if( GotoTrack(ucTrack) )
{
int tmp=GetSectorBytes(ucSectorBytesCode);
StartDMA(WRITE_DISK,ucnSectors,tmp,pBuffer);//MAX_ALL_BYTES,pBuffer);
EnableINT();
if( SendCommand(0x0C5) )
{
CHAR tmp2= ucHead<<2;
if( SendCommand(ucDiskNumber|tmp2) )
{
if( SendCommand(ucTrack) )
{
if( SendCommand(ucHead) )
{
if( SendCommand(ucStartSector) )
{
if( SendCommand(ucSectorBytesCode) )
{
if( SendCommand(ucLastSector) )
{
if( SendCommand(ucSectorL) )
{
if( SendCommand(0x0ff) )
{
if( IsComplete() )
{
if( GetErr(7) )
return TRUE;
}
}
}
}
}
}
}
}
}
}
}
}
if( !CanRetry() )
return FALSE;
}
if( uError==OK )
return TRUE;
else
return FALSE;
}
BOOL CFDBios::WriteDelSector(CHAR ucTrack,CHAR ucHead,CHAR ucStartSector,
CHAR ucnSectors,CHAR ucSectorBytesCode,CHAR ucLastSector,
CHAR ucSectorL)
{
for( int i=0;i<MAX_RETRY;i++)
{
if( Reset() )
{
if( GotoTrack(ucTrack) )
{
int tmp=GetSectorBytes(ucSectorBytesCode);
StartDMA(WRITE_DISK,ucnSectors,tmp,pBuffer);//MAX_ALL_BYTES,pBuffer);
EnableINT();
if( SendCommand(0x0C9) )
{
CHAR tmp2= ucHead<<2;
if( SendCommand(ucDiskNumber|tmp2) )
{
if( SendCommand(ucTrack) )
{
if( SendCommand(ucHead) )
{
if( SendCommand(ucStartSector) )
{
if( SendCommand(ucSectorBytesCode) )
{
if( SendCommand(ucLastSector) )
{
if( SendCommand(ucSectorL) )
{
if( SendCommand(0x0ff) )
{
if( IsComplete() )
{
if( GetErr(7) )
return TRUE;
}
}
}
}
}
}
}
}
}
}
}
}
if( !CanRetry() )
return FALSE;
}
if( uError==OK )
return TRUE;
else
return FALSE;
}
BOOL CFDBios::WriteCRCSector(CHAR ucTrack,CHAR ucHead,CHAR ucStartSector,
CHAR ucnSectors,CHAR ucSectorBytesCode,CHAR ucLastSector,
CHAR ucSectorL)
{
for( int i=0;i<MAX_RETRY;i++)
{
if( Reset() )
{
if( GotoTrack(ucTrack) )
{
int BytesOfSector=GetSectorBytes(ucSectorBytesCode);
StartDMA(WRITE_DISK,ucnSectors,BytesOfSector,pBuffer);
EnableINT();
if( SendCommand(0x0C5) )
{
CHAR tmp2= ucHead<<2;
if( SendCommand(ucDiskNumber|tmp2) )
{
if( SendCommand(ucTrack) )
{
if( SendCommand(ucHead) )
{
if( SendCommand(ucStartSector) )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -