⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 copy.c

📁 详细介绍了一篇关于pci开发的接口芯片
💻 C
字号:
/* copy.c

   Copy addr1 -> addr2.
   see clib1.h for "flags".
      Flags supported:
         SIZE_xxxx
         ADDRx_SAME

   Entry:
   Exit:    <> if OK, else illegal call.
            Illegal call is if neither address increments.
*/

#include <clib1.h>

extern int x4gbinitialized;


int copy( LONG length, VOID *addr1, VOID *addr2, WORD flags )
{
   register LONG counter = length;
   VBYTE *sbyteptr = addr1, *dbyteptr = addr2;
   VWORD *swordptr = addr1, *dwordptr = addr2;
   VLONG *slongptr = addr1, *dlongptr = addr2;

	if ( !( (flags & ADDR1_SAME) || (flags & ADDR2_SAME) ) )
   	/* both addresses increment */
   	{
      switch( flags & SIZE_MASK )
      {
         case SIZE_BYTE:
            for( ; counter != 0; counter-- )
               *dbyteptr++ = *sbyteptr++;
            break;

         case SIZE_WORD:
            counter /= 2;
            for( ; counter != 0; counter-- )
               *dwordptr++ = *swordptr++;
            break;

         case SIZE_LONG:
            counter /= 4;
            for( ; counter != 0; counter-- )
               *dlongptr++ = *slongptr++;
            break;
      }

      return(1);
   }


   if ( (flags & ADDR1_SAME) && !(flags & ADDR2_SAME) )
   /* source does not increment */
   {
      switch( flags & SIZE_MASK )
      {
         case SIZE_BYTE:
            for( ; counter != 0; counter-- )
               *dbyteptr++ = *sbyteptr;
            break;

         case SIZE_WORD:
            counter /= 2;
            for( ; counter != 0; counter-- )
               *dwordptr++ = *swordptr;
            break;

         case SIZE_LONG:
            counter /= 4;
            for( ; counter != 0; counter-- )
               *dlongptr++ = *slongptr;
            break;
      }

      return(1);
   }

   if ( !(flags & ADDR1_SAME) && (flags & ADDR2_SAME) )
   /* destination does not increment */
   {
      switch( flags & SIZE_MASK )
      {
         case SIZE_BYTE:
            for( ; counter != 0; counter-- )
               *dbyteptr = *sbyteptr++;
            break;

         case SIZE_WORD:
            counter /= 2;
            for( ; counter != 0; counter-- )
               *dwordptr = *swordptr++;
            break;

         case SIZE_LONG:
            counter /= 4;
            for( ; counter != 0; counter-- )
               *dlongptr = *slongptr++;
            break;
      }

      return(1);
   }


   return(0);     /* unsupported call */
}


#pragma inline
/*asm P386 */
/* **************************************** */
/* DO NOT PUT ANYTHING AFTER HERE UNLESS 	*/
/* YOU WANT THE "INLINE" PRAGMA TO BE    	*/
/* USED FOR THESE FUNCTIONS TOO.       		*/
/* **************************************** */
/*
	The "pragma inline" is only used to force the use of
	TASM (Turbo assembler), because the built-in does
	not recognize the "eax" register.
*/


int physical_copy( LONG length, VUINT32 addr1, VUINT32 addr2, WORD flags )
/*
	Same as copy, but uses full 32-bit addresses.

   Copy addr1 -> addr2.
   see clib1.h for "flags".
      Flags supported:
         SIZE_xxxx
         ADDRx_SAME

   Entry:
   Exit:    <> if OK, else illegal call.
            Illegal call is if neither address increments.
*/

{

	x4gbinitialized = FALSE;

	switch( flags & SIZE_MASK )
    {
        case SIZE_WORD:	length &= 0xFFFFFFFEL;  break;
		case SIZE_LONG: length &= 0xFFFFFFFCL;  break;
	}	


   if ( !( (flags & ADDR1_SAME) || (flags & ADDR2_SAME) ) )
   /* both addresses increment */
   {
      switch( flags & SIZE_MASK )
      {
        case SIZE_BYTE:
		if( !x4gbinitialized )
			seg4gb();
		asm
		{
	mov     ebx, [addr1]
    mov     edx, [addr2]
	mov	    esi, [length]
move1:  
	mov     cl, gs:[ebx]
    add     ebx, 1
	mov		gs:[edx], cl
    add     edx, 1
    sub     esi, 1
    jnz     move1
		}
        break;

		case SIZE_WORD:
		if( !x4gbinitialized )
			seg4gb();
		asm
		{
	mov     ebx, [addr1]
    mov     edx, [addr2]
	mov	    esi, [length]
move2:  
	mov     cx, gs:[ebx]
    add     ebx, 2
	mov		gs:[edx], cx
    add     edx, 2
    sub     esi, 2
    jnz     move2
		}
        break;


        case SIZE_LONG:
		if( !x4gbinitialized )
			seg4gb();
		asm
		{
	mov     ebx, [addr1]
    mov     edx, [addr2]
	mov	    esi, [length]
move3:  
	mov     ecx, gs:[ebx]
    add     ebx, 4
	mov		gs:[edx], ecx
    add     edx, 4
    sub     esi, 4
    jnz     move3
		}
        break;

      }

      return(1);
   }


   if ( (flags & ADDR1_SAME) && !(flags & ADDR2_SAME) )
   /* source does not increment */
   {
      switch( flags & SIZE_MASK )
      {
        case SIZE_BYTE:
		if( !x4gbinitialized )
			seg4gb();
		asm
		{
	mov     ebx, [addr1]
    mov     edx, [addr2]
	mov	    esi, [length]
move4:  
	mov     cl, gs:[ebx]
	mov		gs:[edx], cl
    add     edx, 1
    sub     esi, 1
    jnz     move4
		}
        break;

        case SIZE_WORD:
		if( !x4gbinitialized )
			seg4gb();
		asm
		{
	mov     ebx, [addr1]
    mov     edx, [addr2]
	mov	    esi, [length]
move5:  
	mov     cx, gs:[ebx]
	mov		gs:[edx], cx
    add     edx, 2
    sub     esi, 2
    jnz     move5
		}
        break;

        case SIZE_LONG:
		if( !x4gbinitialized )
			seg4gb();
		asm
		{
	mov     ebx, [addr1]
    mov     edx, [addr2]
	mov	    esi, [length]
move6:  
	mov     ecx, gs:[ebx]
	mov		gs:[edx], ecx
    add     edx, 4
    sub     esi, 4
    jnz     move6
		}
        break;

      }

      return(1);
   }

   if ( !(flags & ADDR1_SAME) && (flags & ADDR2_SAME) )
   /* destination does not increment */
   {
      switch( flags & SIZE_MASK )
      {
        case SIZE_BYTE:
		if( !x4gbinitialized )
			seg4gb();
		asm
		{
	mov     ebx, [addr1]
    mov     edx, [addr2]
	mov	    esi, [length]
move7:  
	mov     cl, gs:[ebx]
    add     ebx, 1
	mov		gs:[edx], cl
    sub     esi, 1
    jnz     move7
		}
        break;

        case SIZE_WORD:
		if( !x4gbinitialized )
			seg4gb();
		asm
		{
	mov     ebx, [addr1]
    mov     edx, [addr2]
	mov	    esi, [length]
move8:  
	mov     cx, gs:[ebx]
    add     ebx, 2
	mov		gs:[edx], cx
    sub     esi, 2
    jnz     move8
		}
        break;

        case SIZE_LONG:
		if( !x4gbinitialized )
			seg4gb();
		asm
		{
	mov     ebx, [addr1]
    mov     edx, [addr2]
	mov	    esi, [length]
move9:  
	mov     ecx, gs:[ebx]
    add     ebx, 4
	mov		gs:[edx], ecx
    sub     esi, 4
    jnz     move9		
	    }
        break;

      }

      return(1);
   }


   return(0);     /* unsupported call */
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -