📄 ataiopio.c
字号:
// Note: pio_drq_block_out() is the primary way perform PIO
// Data Out transfers. It will handle 8-bit, 16-bit and 32-bit
// I/O based data transfers and 8-bit and 16-bit PCMCIA Memory
// mode transfers.
void pio_drq_block_out( unsigned int addrDataReg,
unsigned int bufSeg, unsigned int bufOff,
long wordCnt )
{
long bCnt;
int memDtOpt;
unsigned int randVal;
unsigned int dataRegAddr;
unsigned int far * uip1;
unsigned int far * uip2;
unsigned char far * ucp1;
unsigned char far * ucp2;
unsigned long bufAddr;
// NOTE: wordCnt is the size of a DRQ data block/packet
// in words. The maximum value of wordCnt is normally:
// a) For ATA, 16384 words or 32768 bytes (64 sectors,
// only with READ/WRITE MULTIPLE commands),
// b) For ATAPI, 32768 words or 65536 bytes
// (actually 65535 bytes plus a pad byte).
// normalize bufSeg:bufOff
bufAddr = bufSeg;
bufAddr = bufAddr << 4;
bufAddr = bufAddr + bufOff;
if ( pio_memory_seg )
{
// PCMCIA Memory mode data transfer.
// set Data reg address per pio_memory_dt_opt
dataRegAddr = 0x0000;
memDtOpt = pio_memory_dt_opt;
if ( pio_memory_dt_opt == PIO_MEMORY_DT_OPTR )
{
randVal = * (unsigned int *) MK_FP( 0x40, 0x6c );
memDtOpt = randVal % 3;
}
if ( memDtOpt == PIO_MEMORY_DT_OPT8 )
dataRegAddr = 0x0008;
if ( memDtOpt == PIO_MEMORY_DT_OPTB )
{
dataRegAddr = 0x0400;
if ( pio_memory_dt_opt == PIO_MEMORY_DT_OPTR )
dataRegAddr = dataRegAddr | ( randVal & 0x03fe );
}
if ( pio_xfer_width == 8 )
{
// PCMCIA Memory mode 8-bit
bCnt = wordCnt * 2L;
ucp2 = (unsigned char far *) MK_FP( pio_memory_seg, dataRegAddr );
for ( ; bCnt > 0; bCnt -- )
{
bufSeg = (unsigned int) ( bufAddr >> 4 );
bufOff = (unsigned int) ( bufAddr & 0x0000000fL );
ucp1 = (unsigned char far *) MK_FP( bufSeg, bufOff );
* ucp2 = * ucp1;
bufAddr += 1;
if ( memDtOpt == PIO_MEMORY_DT_OPTB )
{
dataRegAddr += 1;
dataRegAddr = ( dataRegAddr & 0x03ff ) | 0x0400;
ucp2 = (unsigned char far *) MK_FP( pio_memory_seg, dataRegAddr );
}
}
trc_llt( addrDataReg, 0, TRC_LLT_OUTSB );
}
else
{
// PCMCIA Memory mode 16-bit
uip2 = (unsigned int far *) MK_FP( pio_memory_seg, dataRegAddr );
for ( ; wordCnt > 0; wordCnt -- )
{
bufSeg = (unsigned int) ( bufAddr >> 4 );
bufOff = (unsigned int) ( bufAddr & 0x0000000fL );
uip1 = (unsigned int far *) MK_FP( bufSeg, bufOff );
* uip2 = * uip1;
bufAddr += 2;
if ( memDtOpt == PIO_MEMORY_DT_OPTB )
{
dataRegAddr = dataRegAddr + 2;
dataRegAddr = ( dataRegAddr & 0x03fe ) | 0x0400;
uip2 = (unsigned int far *) MK_FP( pio_memory_seg, dataRegAddr );
}
}
trc_llt( addrDataReg, 0, TRC_LLT_OUTSW );
}
}
else
{
int pxw;
long wc;
// adjust pio_xfer_width - don't use DWORD if wordCnt is odd.
pxw = pio_xfer_width;
if ( ( pxw == 32 ) && ( wordCnt & 0x00000001L ) )
pxw = 16;
// Data transfer using OUTS instruction.
// Break the transfer into chunks of 32768 or fewer bytes.
while ( wordCnt > 0 )
{
bufOff = (unsigned int) ( bufAddr & 0x0000000fL );
bufSeg = (unsigned int) ( bufAddr >> 4 );
if ( wordCnt > 16384L )
wc = 16384;
else
wc = wordCnt;
if ( pxw == 8 )
{
// do REP OUTS
pio_rep_outbyte( addrDataReg, bufSeg, bufOff, wc * 2L );
}
else
if ( pxw == 32 )
{
// do REP OUTSD
pio_rep_outdword( addrDataReg, bufSeg, bufOff, wc / 2L );
}
else
{
// do REP OUTSW
pio_rep_outword( addrDataReg, bufSeg, bufOff, wc );
}
bufAddr = bufAddr + ( wc * 2 );
wordCnt = wordCnt - wc;
}
}
return;
}
//*************************************************************
//
// These functions do REP INS/OUTS data transfers
// (PIO data transfers in I/O mode):
//
// pio_rep_inbyte()
// pio_rep_outbyte()
// pio_rep_inword()
// pio_rep_outword()
// pio_rep_indword()
// pio_rep_outdword()
//
// These functions can be called directly but usually they
// are called by the pio_drq_block_in() and pio_drq_block_out()
// functions to perform I/O mode transfers. See the
// pio_xfer_width variable!
//
//*************************************************************
void pio_rep_inbyte( unsigned int addrDataReg,
unsigned int bufSeg, unsigned int bufOff,
long byteCnt )
{
unsigned int dataRegAddr = pio_reg_addrs[ addrDataReg ];
unsigned int bCnt = (unsigned int) byteCnt;
// Warning: Avoid calling this function with
// byteCnt > 32768 (transfers 32768 bytes).
// bufSeg and bufOff should be normalized such
// that bufOff is a value between 0 and 15 (0xf).
asm .386
asm push ax
asm push cx
asm push dx
asm push di
asm push es
asm mov ax,bufSeg
asm mov es,ax
asm mov di,bufOff
asm mov cx,bCnt
asm mov dx,dataRegAddr
asm cld
asm rep insb
asm pop es
asm pop di
asm pop dx
asm pop cx
asm pop ax
trc_llt( addrDataReg, 0, TRC_LLT_INSB );
}
//*************************************************************
void pio_rep_outbyte( unsigned int addrDataReg,
unsigned int bufSeg, unsigned int bufOff,
long byteCnt )
{
unsigned int dataRegAddr = pio_reg_addrs[ addrDataReg ];
unsigned int bCnt = (unsigned int) byteCnt;
// Warning: Avoid calling this function with
// byteCnt > 32768 (transfers 32768 bytes).
// bufSeg and bufOff should be normalized such
// that bufOff is a value between 0 and 15 (0xf).
asm .386
asm push ax
asm push cx
asm push dx
asm push si
asm push ds
asm mov ax,bufSeg
asm mov ds,ax
asm mov si,bufOff
asm mov cx,bCnt
asm mov dx,dataRegAddr
asm cld
asm rep outsb
asm pop ds
asm pop si
asm pop dx
asm pop cx
asm pop ax
trc_llt( addrDataReg, 0, TRC_LLT_OUTSB );
}
//*************************************************************
void pio_rep_inword( unsigned int addrDataReg,
unsigned int bufSeg, unsigned int bufOff,
long wordCnt )
{
unsigned int dataRegAddr = pio_reg_addrs[ addrDataReg ];
unsigned int wCnt = (unsigned int) wordCnt;
// Warning: Avoid calling this function with
// wordCnt > 16384 (transfers 32768 bytes).
// bufSeg and bufOff should be normalized such
// that bufOff is a value between 0 and 15 (0xf).
asm .386
asm push ax
asm push cx
asm push dx
asm push di
asm push es
asm mov ax,bufSeg
asm mov es,ax
asm mov di,bufOff
asm mov cx,wCnt
asm mov dx,dataRegAddr
asm cld
asm rep insw
asm pop es
asm pop di
asm pop dx
asm pop cx
asm pop ax
trc_llt( addrDataReg, 0, TRC_LLT_INSW );
}
//*************************************************************
void pio_rep_outword( unsigned int addrDataReg,
unsigned int bufSeg, unsigned int bufOff,
long wordCnt )
{
unsigned int dataRegAddr = pio_reg_addrs[ addrDataReg ];
unsigned int wCnt = (unsigned int) wordCnt;
// Warning: Avoid calling this function with
// wordCnt > 16384 (transfers 32768 bytes).
// bufSeg and bufOff should be normalized such
// that bufOff is a value between 0 and 15 (0xf).
asm .386
asm push ax
asm push cx
asm push dx
asm push si
asm push ds
asm mov ax,bufSeg
asm mov ds,ax
asm mov si,bufOff
asm mov cx,wCnt
asm mov dx,dataRegAddr
asm cld
asm rep outsw
asm pop ds
asm pop si
asm pop dx
asm pop cx
asm pop ax
trc_llt( addrDataReg, 0, TRC_LLT_OUTSW );
}
//*************************************************************
void pio_rep_indword( unsigned int addrDataReg,
unsigned int bufSeg, unsigned int bufOff,
long dwordCnt )
{
unsigned int dataRegAddr = pio_reg_addrs[ addrDataReg ];
unsigned int dwCnt = (unsigned int) dwordCnt;
// Warning: Avoid calling this function with
// dwordCnt > 8192 (transfers 32768 bytes).
// bufSeg and bufOff should be normalized such
// that bufOff is a value between 0 and 15 (0xf).
asm .386
asm push ax
asm push cx
asm push dx
asm push di
asm push es
asm mov ax,bufSeg
asm mov es,ax
asm mov di,bufOff
asm mov cx,dwCnt
asm mov dx,dataRegAddr
asm cld
asm rep insd
asm pop es
asm pop di
asm pop dx
asm pop cx
asm pop ax
trc_llt( addrDataReg, 0, TRC_LLT_INSD );
}
//*************************************************************
void pio_rep_outdword( unsigned int addrDataReg,
unsigned int bufSeg, unsigned int bufOff,
long dwordCnt )
{
unsigned int dataRegAddr = pio_reg_addrs[ addrDataReg ];
unsigned int dwCnt = (unsigned int) dwordCnt;
// Warning: Avoid calling this function with
// dwordCnt > 8192 (transfers 32768 bytes).
// bufSeg and bufOff should be normalized such
// that bufOff is a value between 0 and 15 (0xf).
asm .386
asm push ax
asm push cx
asm push dx
asm push si
asm push ds
asm mov ax,bufSeg
asm mov ds,ax
asm mov si,bufOff
asm mov cx,dwCnt
asm mov dx,dataRegAddr
asm cld
asm rep outsd
asm pop ds
asm pop si
asm pop dx
asm pop cx
asm pop ax
trc_llt( addrDataReg, 0, TRC_LLT_OUTSD );
}
// end ataiopio.c
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -