📄 winhpa48.cpp
字号:
reg_cmd_info.lbaSize = LBA48;
reg_cmd_info.lbaHigh = lbahi;
reg_cmd_info.lbaLow = lbalo;
// Execute the command.
return exec_non_data_cmd( dev );
}
//*************************************************************
//
// sub_setup_command() -- setup the command parameters
// in FR, SC, SN, CL, CH and DH.
//
//*************************************************************
static void sub_setup_command( void )
{
// output DevCtrl - same for all devices and commands
pio_outbyte( CB_DC, reg_cmd_info.dc );
// output command parameters
if ( reg_cmd_info.lbaSize == LBA28 )
{
// in ATA LBA28 mode
pio_outbyte( CB_FR, (unsigned char) reg_cmd_info.fr );
pio_outbyte( CB_SC, (unsigned char) reg_cmd_info.sc );
pio_outbyte( CB_SN, (unsigned char) reg_cmd_info.lbaLow );
pio_outbyte( CB_CL, (unsigned char) ( reg_cmd_info.lbaLow >> 8 ) );
pio_outbyte( CB_CH, (unsigned char) ( reg_cmd_info.lbaLow >> 16 ) );
pio_outbyte( CB_DH, (unsigned char) ( ( reg_cmd_info.dh & 0xf0 )
| ( ( reg_cmd_info.lbaLow >> 24 ) & 0x0f ) ) );
}
else
if ( reg_cmd_info.lbaSize == LBA48 )
{
// in ATA LBA48 mode
pio_outbyte( CB_FR, (unsigned char) ( reg_cmd_info.fr >> 8 ) );
pio_outbyte( CB_SC, (unsigned char) ( reg_cmd_info.sc >> 8 ) );
pio_outbyte( CB_SN, (unsigned char) ( reg_cmd_info.lbaLow >> 24 ) );
pio_outbyte( CB_CL, (unsigned char) reg_cmd_info.lbaHigh );
pio_outbyte( CB_CH, (unsigned char) ( reg_cmd_info.lbaHigh >> 8 ) );
pio_outbyte( CB_FR, (unsigned char) reg_cmd_info.fr );
pio_outbyte( CB_SC, (unsigned char) reg_cmd_info.sc );
pio_outbyte( CB_SN, (unsigned char) reg_cmd_info.lbaLow );
pio_outbyte( CB_CL, (unsigned char) ( reg_cmd_info.lbaLow >> 8 ) );
pio_outbyte( CB_CH, (unsigned char) ( reg_cmd_info.lbaLow >> 16 ) );
pio_outbyte( CB_DH, reg_cmd_info.dh );
}
else
{
// for ATAPI PACKET command
pio_outbyte( CB_FR, (unsigned char) reg_cmd_info.fr );
pio_outbyte( CB_SC, (unsigned char) reg_cmd_info.sc );
pio_outbyte( CB_SN, (unsigned char) reg_cmd_info.sn );
pio_outbyte( CB_CL, (unsigned char) reg_cmd_info.cl );
pio_outbyte( CB_CH, (unsigned char) reg_cmd_info.ch );
pio_outbyte( CB_DH, reg_cmd_info.dh );
}
}
//*************************************************************
//
// sub_trace_command() -- trace the end of a command.
//
//*************************************************************
static void sub_trace_command( void )
{
// while(0x80 & pio_inbyte( CB_STAT ));
reg_cmd_info.st = pio_inbyte( CB_STAT );
reg_cmd_info.as = pio_inbyte( CB_ASTAT );
reg_cmd_info.er = pio_inbyte( CB_ERR );
// !!! if you want to read back the other device registers
// !!! at the end of a command then this is the place to do
// !!! it. The code here is just and example of out this is
// !!! done on a little endian system like an x86.
#if 1 // read back other registers
{
unsigned long lbaHigh;
unsigned long lbaLow;
unsigned char sc48[2];
unsigned char lba48[8];
lbaHigh = 0;
lbaLow = 0;
if ( reg_cmd_info.lbaSize == LBA48 )
{
// read back ATA LBA48...
sc48[0] = pio_inbyte( CB_SC );
lba48[0] = pio_inbyte( CB_SN );
lba48[1] = pio_inbyte( CB_CL );
lba48[2] = pio_inbyte( CB_CH );
pio_outbyte( CB_DC, CB_DC_HOB );
sc48[1] = pio_inbyte( CB_SC );
lba48[3] = pio_inbyte( CB_SN );
lba48[4] = pio_inbyte( CB_CL );
lba48[5] = pio_inbyte( CB_CH );
lba48[6] = 0;
lba48[7] = 0;
reg_cmd_info.lbaHigh = * (unsigned long *) ( lba48 + 4 );
reg_cmd_info.lbaLow = * (unsigned long *) ( lba48 + 0 );
}
else
if ( reg_cmd_info.lbaSize == LBA28 )
{
// read back ATA LBA28
lbaLow = pio_inbyte( CB_DH );
lbaLow = lbaLow << 8;
lbaLow = lbaLow | pio_inbyte( CB_CH );
lbaLow = lbaLow << 8;
lbaLow = lbaLow | pio_inbyte( CB_CL );
lbaLow = lbaLow << 8;
lbaLow = lbaLow | pio_inbyte( CB_SN );
reg_cmd_info.lbaLow=lbaLow & 0x0fffffff;
}
else
{
// really no reason to read back for ATAPI
}
}
#endif // read back other registers
}
//*************************************************************
//
// sub_select() - function used to select a drive.
//
// Function to select a drive making sure that BSY=0 and DRQ=0.
//
//**************************************************************
static int sub_select( unsigned char dev )
{
unsigned char status;
// PAY ATTENTION HERE
// The caller may want to issue a command to a device that doesn't
// exist (for example, Exec Dev Diag), so if we see this,
// just select that device, skip all status checking and return.
// We assume the caller knows what they are doing!
if ( reg_config_info[dev] < REG_CONFIG_TYPE_ATA )
{
// select the device and return
pio_outbyte( CB_DH, (unsigned char) ( dev ? CB_DH_DEV1 : CB_DH_DEV0 ) );
DELAY400NS;
return 0;
}
// The rest of this is the normal ATA stuff for device selection
// and we don't expect the caller to be selecting a device that
// does not exist.
// We don't know which drive is currently selected but we should
// wait BSY=0 and DRQ=0. Normally both BSY=0 and DRQ=0
// unless something is very wrong!
while ( 1 )
{
status = pio_inbyte( CB_STAT );
if ( ( status & ( CB_STAT_BSY | CB_STAT_DRQ ) ) == 0 )
break;
if ( tmr_chk_timeout() )
{
reg_cmd_info.to = 1;
reg_cmd_info.ec = 11;
reg_cmd_info.st = status;
reg_cmd_info.as = pio_inbyte( CB_ASTAT );
reg_cmd_info.er = pio_inbyte( CB_ERR );
return 1;
}
}
// Here we select the drive we really want to work with by
// setting the DEV bit in the Drive/Head register.
pio_outbyte( CB_DH, (unsigned char) ( dev ? CB_DH_DEV1 : CB_DH_DEV0 ) );
DELAY400NS;
// Wait for the selected device to have BSY=0 and DRQ=0.
// Normally the drive should be in this state unless
// something is very wrong (or initial power up is still in
// progress).
while ( 1 )
{
status = pio_inbyte( CB_STAT );
if ( ( status & ( CB_STAT_BSY | CB_STAT_DRQ ) ) == 0 )
break;
if ( tmr_chk_timeout() )
{
reg_cmd_info.to = 1;
reg_cmd_info.ec = 12;
reg_cmd_info.st = status;
reg_cmd_info.as = pio_inbyte( CB_ASTAT );
reg_cmd_info.er = pio_inbyte( CB_ERR );
return 1;
}
}
// All done. The return values of this function are described in
// ATAIO.H.
if ( reg_cmd_info.ec )
return 1;
return 0;
}
//*************************************************************
//
// sub_wait_poll() - wait for interrupt or poll for BSY=0
//
//*************************************************************
static void sub_wait_poll( unsigned char we, unsigned char pe )
{
unsigned char status;
// Wait for interrupt -or- wait for not BUSY -or- wait for time out.
if ( we && int_use_intr_flag )
{
// if ( SYSTEM_WAIT_INTR_OR_TIMEOUT() ) // time out ?
{
reg_cmd_info.to = 1;
reg_cmd_info.ec = we;
}
}
else
{
while ( 1 )
{
status = pio_inbyte( CB_ASTAT ); // poll for not busy
if ( ( status & CB_STAT_BSY ) == 0 )
break;
if ( tmr_chk_timeout() ) // time out yet ?
{
reg_cmd_info.to = 1;
reg_cmd_info.ec = pe;
break;
}
}
}
}
//***********************************************************
//
// functions used to read/write the BMIDE registers
//
//***********************************************************
static unsigned char pio_readBusMstrCmd( void )
{
unsigned char x;
if ( ! pio_bmide_base_addr )
return 0;
x = * (pio_bmide_base_addr + BM_COMMAND_REG );
return x;
}
static unsigned char pio_readBusMstrStatus( void )
{
unsigned char x;
if ( ! pio_bmide_base_addr )
return 0;
x = * ( pio_bmide_base_addr + BM_STATUS_REG );
return x;
}
static void pio_writeBusMstrCmd( unsigned char x )
{
if ( ! pio_bmide_base_addr )
return;
* ( pio_bmide_base_addr + BM_COMMAND_REG ) = x;
}
static void pio_writeBusMstrStatus( unsigned char x )
{
if ( ! pio_bmide_base_addr )
return;
* ( pio_bmide_base_addr + BM_STATUS_REG ) = x;
}
//*************************************************************
//
// These functions do basic IN/OUT of byte and word values:
//
// pio_inbyte()
// pio_outbyte()
// pio_inword()
// pio_outword()
//
//*************************************************************
static unsigned char pio_inbyte( unsigned char addr )
{
DWORD dwPortVal;
//!!! read an 8-bit ATA register
// return * pio_reg_addrs[ addr ];
GetPortVal(pio_reg_addrs[ addr ] , &dwPortVal, 1);
return (unsigned char)dwPortVal;
}
//*************************************************************
static void pio_outbyte( int addr, unsigned char data )
{
//!!! write an 8-bit ATA register
// * pio_reg_addrs[ addr ] = data;
// outportb( pio_reg_addrs[ addr ] , data);
SetPortVal(pio_reg_addrs[ addr ], data, 1);
}
//*************************************************************
static unsigned int pio_inword( unsigned char addr )
{
DWORD dwPortVal;
//!!! read an 8-bit ATA register (usually the ATA Data register)
//return * ( (unsigned int *) pio_reg_addrs[ addr ] );
// return inport ( pio_reg_addrs[ addr ] );
GetPortVal(pio_reg_addrs[ addr ] , &dwPortVal, 2);
return dwPortVal;
}
//*************************************************************
static void pio_outword( int addr, unsigned int data )
{
//!!! Write an 8-bit ATA register (usually the ATA Data register)
//* ( (unsigned int *) pio_reg_addrs[ addr ] ) = data;
//outport ( pio_reg_addrs[ addr ] , data);
SetPortVal(pio_reg_addrs[ addr ], data, 2);
}
//*************************************************************
static unsigned long pio_indword( unsigned char addr )
{
DWORD dwPortVal;
//!!! read an 8-bit ATA register (usually the ATA Data register)
// return * ( (unsigned long *) pio_reg_addrs[ addr ] );
GetPortVal(pio_reg_addrs[ addr ] , &dwPortVal, 4);
return dwPortVal;
}
//*************************************************************
static void pio_outdword( int addr, unsigned long data )
{
//!!! Write an 8-bit ATA register (usually the ATA Data register)
//* ( (unsigned long *) pio_reg_addrs[ addr ] ) = data;
SetPortVal(pio_reg_addrs[ addr ], data, 4);
}
//*************************************************************
//
// Command timing functions
//
//**************************************************************
//static long tmr_cmd_start_time; // command start time - see the
// tmr_set_timeout() and
// tmr_chk_timeout() functions.
//*************************************************************
//
// tmr_set_timeout() - get the command start time
//
//**************************************************************
static void tmr_set_timeout( void )
{
// get the command start time
tmr_cmd_start_time = 0;//SYSTEM_READ_TIMER();
}
//*************************************************************
//
// tmr_chk_timeout() - check for command timeout.
//
// Gives non-zero return if command has timed out.
//
//**************************************************************
static int tmr_chk_timeout( void )
{
long curTime;
// get current time
curTime = 0;//SYSTEM_READ_TIMER();
// timed out yet ?
if ( curTime >= ( tmr_cmd_start_time
+ ( TMR_TIME_OUT * SYSTEM_TIMER_TICKS_PER_SECOND ) ) )
return 1; // yes
// no timeout yet
return 0;
}
// end testhpa.c
//
// test code:
void main()
{int st,st1;unsigned long lbalo=0xfff,lbahi=0;
st=reg_reset(0);
st1=reg_config();
bool bResult;
// Call InitializeWinIo to initialize the WinIo library.
bResult = InitializeWinIo();
if (bResult)
{
//int reg_non_data_lba48( unsigned char dev, unsigned char cmd,
// unsigned int fr, unsigned int sc,
// unsigned long lbahi, unsigned long lbalo )
printf("In the harddisk there are number of block: \n");
tt:
st=reg_non_data_lba48(0, READ_NATIVE_MAX_ADDRESS_EXT, 0, 0, lbahi, lbalo);
printf("%d,%d,%lx,%ld\n",st, st1,reg_cmd_info.lbaLow, reg_cmd_info.lbaLow);
printf("STAT=%x,ASTAT=%x,ERR=%x,\n\n",reg_cmd_info.st, reg_cmd_info.as, reg_cmd_info.er);
if (reg_cmd_info.st!=0x50) goto tt;
// printf("Please input HPA block number:");
// scanf("%ld",&lbalo);
lbalo=reg_cmd_info.lbaLow;//-lbalo;
st=reg_non_data_lba48(0,SET_MAX_ADDRESS_EXT,0,0, lbahi,lbalo);
printf("%d,%d,%lx,%ld\n",st, st1,reg_cmd_info.lbaLow,lbalo);
printf("STAT=%x,ASTAT=%x,ERR=%x,\n\n",reg_cmd_info.st, reg_cmd_info.as, reg_cmd_info.er);
st=reg_non_data_lba48(0,READ_NATIVE_MAX_ADDRESS_EXT,0,0,lbahi, lbalo);
printf("%d,%d,%lx,%ld\n",st, st1,reg_cmd_info.lbaLow, reg_cmd_info.lbaLow);
printf("STAT=%x,ASTAT=%x,ERR=%x,\n\n",reg_cmd_info.st, reg_cmd_info.as, reg_cmd_info.er);
// When you're done using WinIo, call ShutdownWinIo
ShutdownWinIo();
printf("Press any key to continue...");
st=getchar();
}
else
{
printf("Error during initialization of WinIo.\n");
exit(1);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -