home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Contributed / SpriteWorld / SpriteWorld Files / BlitPixie / Sources / BlitPixieUtils.c < prev   
Encoding:
Text File  |  2000-10-06  |  9.6 KB  |  504 lines  |  [TEXT/CWIE]

  1. ///--------------------------------------------------------------------------------------
  2. //    BlitPixieUtils - miscellaneous utilities for BlitPixie
  3. //
  4. //    written by Anders F Björklund <afb@algonet.se>
  5. //    © 1999 afb.
  6. ///--------------------------------------------------------------------------------------
  7.  
  8. #ifndef __BLITPIXIE__
  9. #include "BlitPixieHeader.h"
  10. #endif
  11.  
  12. #include "BlitPixieAsm.h"
  13.  
  14. #ifndef GENERATINGASM // do not include for asm file generation
  15.  
  16. short         gBlitPixieProcessorType = kUnknownProcessor;
  17.  
  18. ///--------------------------------------------------------------------------------------
  19. //    BlitPixieVersion - get numeric version
  20. ///--------------------------------------------------------------------------------------
  21.  
  22. unsigned long BlitPixieVersion( void )
  23. {
  24.     return BLITPIXIE_VERSION_NUM;
  25. }
  26.  
  27. ///--------------------------------------------------------------------------------------
  28. //    BlitPixieVersionString - get string version
  29. ///--------------------------------------------------------------------------------------
  30.  
  31. void BlitPixieVersionString( char string[BLITPIXIE_VERSION_STRINGLEN] )
  32. {
  33.     char    *p,*version = BLITPIXIE_VERSION_STRING;
  34.     
  35.     for ( p = version; *p; *string++ = *p++ )
  36.         {}
  37. }
  38.  
  39. #pragma mark -
  40.  
  41. #pragma mark *** Macintosh : 
  42. #ifdef macintosh
  43.  
  44. #include <Gestalt.h>
  45.  
  46. ///--------------------------------------------------------------------------------------
  47. //    BlitPixieGetProcessorType
  48. ///--------------------------------------------------------------------------------------
  49.  
  50. void BlitPixieGetProcessorType()
  51. {
  52.     OSErr        err;        
  53.     long        response;
  54.     short        processor;
  55.  
  56.     err = Gestalt(gestaltSysArchitecture,&response);
  57.     if ( err != noErr )
  58.         return;
  59.  
  60.     if ( response == gestalt68k )
  61.     {
  62.         err = Gestalt(gestaltProcessorType,&response);
  63.         if ( err != noErr )
  64.             return;
  65.  
  66.         switch (response)
  67.         {
  68.             case gestalt68000:        processor = k68000;        break;
  69.             case gestalt68010:        processor = k68010;        break;
  70.             case gestalt68020:        processor = k68020;        break;
  71.             case gestalt68030:        processor = k68030;        break;
  72.             case gestalt68040:        processor = k68040;        break;
  73.             default:                return;
  74.         }    
  75.     }
  76.     else if ( response == gestaltPowerPC )
  77.     {
  78.         err = Gestalt(gestaltNativeCPUtype,&response);
  79.         if ( err != noErr )
  80.             return;
  81.     
  82.         switch (response)
  83.         {
  84.             case gestaltCPU601:        processor = k601;        break;
  85.             case gestaltCPU603:        processor = k603;        break;
  86.         
  87.         #if UNIVERSAL_INTERFACES_VERSION >= 0x0300
  88.             case gestaltCPU603e:
  89.             case gestaltCPU603ev:
  90.                                     processor = k603;        break;
  91.     
  92.             case gestaltCPU604:
  93.             case gestaltCPU604e:
  94.             case gestaltCPU604ev:
  95.                                     processor = k604;        break;
  96.             case gestaltCPU750:    
  97.                                     processor = kG3;        break;
  98.         #endif
  99.     
  100.         #if 0    /* TODO: add this when the selector is known */
  101.             case gestaltCPU???:    
  102.                                     processor = kG4;        break;
  103.         #endif
  104.  
  105.             default:                return;
  106.         }
  107.     }
  108.  
  109.     gBlitPixieProcessorType = processor;
  110. }
  111.  
  112. #pragma mark *** Other : 
  113. #else
  114.  
  115. ///--------------------------------------------------------------------------------------
  116. // GetProcessorType
  117. ///--------------------------------------------------------------------------------------
  118.  
  119. void BlitPixieGetProcessorType()
  120. {
  121.     gBlitPixieProcessorType = kUnknownProcessor;
  122. }
  123.  
  124. #endif //macintosh
  125.  
  126. #endif //GENERATINGASM
  127.  
  128. #pragma mark -
  129.  
  130. #pragma mark *** PowerPC asm : 
  131. #if USE_PPC_ASSEMBLY
  132.  
  133. ASM_FUNC void BlitPixieMemCopy(
  134.     register unsigned char *dst,        // r3
  135.     register unsigned char *src,        // r4
  136.     register int bytes)                    // r5
  137. {
  138.     #define r_dst        r3
  139.     #define r_src        r4
  140.     #define r_bytes        r5
  141.  
  142.     #define r_index        r6
  143.     #define r_chunks    r7
  144.  
  145.     ASM_BEGIN
  146.  
  147.     rlwinm    r_chunks,r_bytes,27,5,31    
  148.     rlwinm    r10,r_bytes,0,31,31    
  149.     rlwinm    r11,r_bytes,31,31,31
  150.     rlwinm    r_bytes,r_bytes,30,29,31
  151.  
  152.     cmplwi    r_chunks,0
  153.     cmplwi    cr7,r10,0
  154.     cmplwi    cr6,r11,0
  155.     cmplwi    cr5,r_bytes,0
  156.  
  157.     subi    r_src,r_src,32
  158.     subi    r_dst,r_dst,32
  159.     li        r_index,32
  160.  
  161.     beq        @skipchunks
  162.         mtctr    r_chunks
  163.     @chunkloop:
  164.         lwzu    r0,32(r_src)
  165.         lwz        r9,4(r_src)
  166.         lwz        r10,8(r_src)
  167.         lwz        r11,12(r_src)
  168.         stwu    r0,32(r_dst)
  169.         stw        r9,4(r_dst)
  170.         stw        r10,8(r_dst)
  171.         stw        r11,12(r_dst)
  172.         lwz        r0,16(r_src)
  173.         lwz        r9,20(r_src)
  174.         lwz        r10,24(r_src)
  175.         lwz        r11,28(r_src)
  176.         stw        r0,16(r_dst)
  177.         stw        r9,20(r_dst)
  178.         stw        r10,24(r_dst)
  179.         stw        r11,28(r_dst)
  180.         bdnz    @chunkloop
  181.     @skipchunks:
  182.     
  183.     beq        cr5,@skipwords
  184.         mtctr    r_bytes 
  185.     @wordloop:
  186.         lwzx    r0,r_src,r_index
  187.         stwx    r0,r_dst,r_index
  188.         addi    r_index,r_index,4
  189.         bdnz    @wordloop
  190.     @skipwords:
  191.  
  192.     beq        cr6,@skipshort
  193.         lhzx    r0,r_src,r_index
  194.         sthx    r0,r_dst,r_index
  195.         addi    r_index,r_index,2
  196.     @skipshort:    
  197.  
  198.     beq        cr7,@skipbyte
  199.         lbzx    r0,r_src,r_index
  200.         stbx    r0,r_dst,r_index
  201.         addi    r_index,r_index,1
  202.     @skipbyte:    
  203.  
  204.     #undef r_dst
  205.     ASM_END
  206. }
  207.  
  208. ASM_FUNC void BlitPixieMemSet(
  209.     register unsigned char *dst,        // r3
  210.     register unsigned long value,        // r4
  211.     register int bytes)                    // r5
  212. {
  213.     #define r_dst        r3
  214.     #define r_value        r4
  215.     #define r_bytes        r5
  216.  
  217.     ASM_BEGIN
  218.  
  219.     rlwinm    r9,r_bytes,27,5,31    
  220.     rlwinm    r10,r_bytes,0,31,31    
  221.     rlwinm    r11,r_bytes,31,31,31
  222.     rlwinm    r_bytes,r_bytes,30,29,31
  223.  
  224.     cmplwi    r9,0
  225.     cmplwi    cr7,r10,0
  226.     cmplwi    cr6,r11,0
  227.     cmplwi    cr5,r_bytes,0
  228.  
  229.     subi    r_dst,r_dst,4
  230.     
  231.     beq        @skipchunks
  232.         mtctr    r9
  233.     @chunkloop:
  234.         stw        r_value,4(r_dst)
  235.         stw        r_value,8(r_dst)
  236.         stw        r_value,12(r_dst)
  237.         stw        r_value,16(r_dst)
  238.         stw        r_value,20(r_dst)
  239.         stw        r_value,24(r_dst)
  240.         stw        r_value,28(r_dst)
  241.         stwu    r_value,32(r_dst)
  242.         bdnz    @chunkloop
  243.     @skipchunks:
  244.     
  245.     beq        cr5,@skipwords
  246.         mtctr    r_bytes
  247.     @wordloop:
  248.         stwu    r_value,4(r_dst)
  249.         bdnz    @wordloop
  250.     @skipwords:
  251.  
  252.     beq        cr6,@skipshort
  253.         sth        r_value,4(r_dst)
  254.         addi    r_dst,r_dst,2
  255.     @skipshort:    
  256.  
  257.     beq        cr7,@skipbyte
  258.         stb        r_value,4(r_dst)
  259.         addi    r_dst,dst,1
  260.     @skipbyte:    
  261.  
  262.     ASM_END
  263. }
  264.  
  265. #pragma mark *** 680x0 asm : 
  266. #elif USE_68K_ASSEMBLY
  267.  
  268. ASM_FUNC void BlitPixieMemCopy(
  269.     unsigned char *dst,    
  270.     unsigned char *src,    
  271.     int bytes)                
  272. {
  273.     ASM_BEGIN
  274.     MOVE.L      A2,-(SP)
  275.     
  276.     MOVEA.L    src,A0
  277.     MOVEA.L    dst,A1
  278. #if LONGINTS
  279.     MOVE.L    bytes,D2
  280. #else
  281.     MOVE.W    bytes,D2
  282. #endif
  283.  
  284.     MOVEQ     #15,D0
  285.      CLR.L     D1
  286.     MOVE.W    D2,D1
  287.     LSR.W     #2,D1
  288.     AND.W      D0,D1
  289.     ADD.W      D1,D1            //    * sizeof("MOVE.L (A0)+,(A1)+")
  290.     LEA          @loopend,A2
  291.     SUBA.L      D1,A2    
  292.     MOVE.W    D2,D1
  293.     LSR.W       #6,D1
  294.         
  295. @rowloop:
  296.  
  297.             // main block copy loop
  298.         MOVE.W    D1,D0
  299.            JMP        (A2)
  300.    @loopstart:
  301.         MOVE.L    (A0)+,(A1)+
  302.         MOVE.L     (A0)+,(A1)+
  303.         MOVE.L    (A0)+,(A1)+
  304.         MOVE.L     (A0)+,(A1)+
  305.         MOVE.L    (A0)+,(A1)+
  306.         MOVE.L    (A0)+,(A1)+
  307.         MOVE.L    (A0)+,(A1)+
  308.         MOVE.L     (A0)+,(A1)+
  309.         MOVE.L    (A0)+,(A1)+
  310.         MOVE.L    (A0)+,(A1)+
  311.         MOVE.L     (A0)+,(A1)+
  312.         MOVE.L    (A0)+,(A1)+
  313.         MOVE.L    (A0)+,(A1)+
  314.         MOVE.L    (A0)+,(A1)+
  315.         MOVE.L     (A0)+,(A1)+
  316.         MOVE.L    (A0)+,(A1)+
  317.     @loopend:
  318.            DBRA    D0,@loopstart
  319.  
  320.               // do left-over bytes
  321.         MOVE.W    D2,D0
  322.            ANDI.W  #2,D0
  323.         BEQ.S    @skipword
  324.         MOVE.W    (A0)+,(A1)+
  325.       @skipword:
  326.         MOVE.W    D2,D0
  327.            ANDI.W  #1,D0
  328.         BEQ.S    @skipbyte
  329.           MOVE.B    (A0)+,(A1)+
  330.       @skipbyte:
  331.  
  332.     MOVE.L      (SP)+,A2
  333.     ASM_END
  334. }
  335.  
  336. ASM_FUNC void BlitPixieMemSet(
  337.     unsigned char *dst,        
  338.     unsigned long value,        
  339.     int bytes)                    
  340. {
  341.     ASM_BEGIN
  342.     
  343. #if LONGINTS
  344.     MOVE.L    bytes,D2
  345. #else
  346.     MOVE.W    bytes,D2
  347. #endif
  348.  
  349.     MOVEQ     #15,D0
  350.      CLR.L     D1
  351.     MOVE.W    D2,D1
  352.     LSR.W     #2,D1
  353.     AND.W      D0,D1
  354.     ADD.W      D1,D1            //    * sizeof("MOVE.L (A0)+,(A1)+")
  355.     LEA          @loopend,A1
  356.     SUBA.L      D1,A1    
  357.     MOVE.W    D2,D1
  358.     LSR.W       #6,D1
  359.         
  360.     MOVE.L      value,D0
  361.     MOVEA.L      dst,A0
  362.  
  363.             // main block copy loop
  364.         JMP        (A1)
  365.    @loopstart:
  366.         MOVE.L    D0,(A0)+
  367.         MOVE.L     D0,(A0)+
  368.         MOVE.L    D0,(A0)+
  369.         MOVE.L     D0,(A0)+
  370.         MOVE.L    D0,(A0)+
  371.         MOVE.L    D0,(A0)+
  372.         MOVE.L    D0,(A0)+
  373.         MOVE.L     D0,(A0)+
  374.         MOVE.L    D0,(A0)+
  375.         MOVE.L    D0,(A0)+
  376.         MOVE.L     D0,(A0)+
  377.         MOVE.L    D0,(A0)+
  378.         MOVE.L    D0,(A0)+
  379.         MOVE.L    D0,(A0)+
  380.         MOVE.L     D0,(A0)+
  381.         MOVE.L    D0,(A0)+
  382.     @loopend:
  383.            DBRA    D1,@loopstart
  384.  
  385.               // do left-over bytes
  386.         MOVE.W    D2,D1
  387.            ANDI.W  #2,D1
  388.         BEQ.S    @skipword
  389.         MOVE.W    D0,(A0)+
  390.       @skipword:
  391.         ANDI.W  #1,D2
  392.         BEQ.S    @skipbyte
  393.           MOVE.B    D0,(A0)+
  394.       @skipbyte:
  395.  
  396.     ASM_END
  397. }
  398.  
  399. #pragma mark *** Generic C : 
  400. #elif USE_GENERIC_C
  401.  
  402. #ifndef THINK_C
  403. #define CAN_DO_PTR_CAST        1    // can we cast pointers during assignment ? (is not ANSI, but useful)
  404. #else
  405. #define CAN_DO_PTR_CAST        0
  406. #endif
  407.  
  408. void BlitPixieMemCopy( unsigned char *dst, unsigned char *src, int bytes)
  409. {
  410.     int    i;
  411.  
  412. #if CAN_DO_PTR_CAST
  413.  
  414.     for ( i = 0; i < (bytes >> 2); i++ )
  415.         *((unsigned long *) dst)++ = *((unsigned long *) src)++;
  416.     if ( bytes & 2 )
  417.         *((unsigned short *) dst)++ = *((unsigned short *) src)++;
  418.     if ( bytes & 1 )
  419.         *((unsigned char *) dst)++ = *((unsigned char *) src)++;
  420.  
  421. #else
  422.  
  423.     {
  424.         unsigned long    *srcTemp = (unsigned long *) src,
  425.                         *dstTemp = (unsigned long *) dst;    
  426.         
  427.         for ( i = 0; i < (bytes >> 2); i++ )
  428.             *dstTemp++ = *srcTemp++;
  429.         
  430.         src = (unsigned char *) srcTemp;
  431.         dst = (unsigned char *) dstTemp;
  432.     }
  433.     if ( bytes & 2 )
  434.     {
  435.         unsigned short    *srcTemp = (unsigned short *) src,
  436.                         *dstTemp = (unsigned short *) dst;    
  437.         
  438.         *dstTemp++ = *srcTemp++;
  439.         
  440.         src = (unsigned char *) srcTemp;
  441.         dst = (unsigned char *) dstTemp;
  442.     }
  443.     if ( bytes & 1 )
  444.     {
  445.         unsigned char    *srcTemp = (unsigned char *) src,
  446.                         *dstTemp = (unsigned char *) dst;    
  447.         
  448.         *dstTemp++ = *srcTemp++;
  449.         
  450.         src = (unsigned char *) srcTemp;
  451.         dst = (unsigned char *) dstTemp;
  452.     }
  453.  
  454. #endif
  455.  
  456. }
  457.  
  458. void BlitPixieMemSet( unsigned char *dst, unsigned long value, int bytes )
  459. {
  460.     int    i;
  461.  
  462. #if CAN_DO_PTR_CAST
  463.     
  464.     for ( i = 0; i < (bytes >> 2); i++ )
  465.         *((unsigned long *) dst)++ = value;
  466.     if ( bytes & 2 )
  467.         *((unsigned short *) dst)++ = value;
  468.     if ( bytes & 1 )
  469.         *((unsigned char *) dst)++ = value;
  470.  
  471. #else
  472.         
  473.     {
  474.         unsigned long    *dstTemp = (unsigned long *) dst;
  475.         
  476.         for ( i = 0; i < (bytes >> 2); i++ )
  477.             *dstTemp++ = value;
  478.         
  479.         dst = (unsigned char *) dstTemp;
  480.     }
  481.     if ( bytes & 2 )
  482.     {
  483.         unsigned short    *dstTemp = (unsigned short *) dst;
  484.     
  485.         *dstTemp++ = value;
  486.     
  487.         dst = (unsigned char *) dstTemp;
  488.     }
  489.     if ( bytes & 1 )
  490.     {
  491.         unsigned char    *dstTemp = (unsigned char *) dst;
  492.     
  493.         *dstTemp++ = value;
  494.     
  495.         dst = (unsigned char *) dstTemp;
  496.     }
  497.  
  498. #endif
  499.  
  500. }
  501.  
  502.  
  503. #endif
  504.