home *** CD-ROM | disk | FTP | other *** search
/ ST-Computer Leser 2002 January / STC_CD_01_2002.iso / JAGUAR / JAG_SRC / SOURCE / BLITTER.C < prev    next >
C/C++ Source or Header  |  2001-08-17  |  14KB  |  375 lines

  1. ////////////////////////////////////////////////////////////////////////////////
  2. // Jagulator: Atari Jaguar Console Emulation Project (blitter.c)
  3. // -----------------------------------------------------------------------------
  4. // Jagulator is the Copyright (c) RealityMan 1998-2001 and is provided "as is" 
  5. // without any expressed or implied warranty. I have no Trademarks, Legal or 
  6. // otherwise. Atari, Jaguar and the Atari Logo are copyright Hasbro Inc. All 
  7. // other Copyrights and Trademarks are acknowledged. This project is in no way 
  8. // linked to Atari/Hasbro or other associated Atari companies.                
  9. //
  10. // 07-07-2001 GH: New Source, Rewritten for Release 1.5.0
  11. // 00-00-0000 GH: All Previous Source Considered as Development Code Only
  12.  
  13. #include "core.h"
  14.  
  15. ////////////////////////////////////////////////////////////////////////////////
  16. // Blitter Defines
  17.  
  18. #define SRCEN        0x00000001        // Blitter Command Word
  19. #define SRCENZ       0x00000002
  20. #define SRCENX       0x00000004
  21. #define DSTEN        0x00000008
  22. #define DSTENZ       0x00000010
  23. #define DSTWRZ       0x00000020
  24. #define CLIP_A1      0x00000040
  25. #define NOGO         0x00000080
  26. #define UPDA1F       0x00000100
  27. #define UPDA1        0x00000200
  28. #define UPDA2        0x00000400
  29. #define DSTA2        0x00000800
  30. #define GOURD        0x00001000
  31. #define GOURZ        0x00002000
  32. #define TOPBEN       0x00004000
  33. #define TOPNEN       0x00008000
  34. #define PATDSEL      0x00010000
  35. #define ADDDSEL      0x00020000
  36.  
  37. #define ZMODELT      0x00040000
  38. #define ZMODEEQ      0x00080000
  39. #define ZMODEGT      0x00100000
  40.  
  41. #define LFU_OP       0x01E00000
  42. #define LFU_NAN      0x00200000
  43. #define LFU_NA       0x00400000
  44. #define LFU_AN       0x00800000
  45. #define LFU_A        0x01000000
  46.  
  47. #define LFU_ZERO     0x00000000
  48. #define LFU_NSAND    0x00200000
  49. #define LFU_NSAD     0x00400000
  50. #define LFU_NOTS     0x00600000
  51. #define LFU_SAND     0x00800000
  52. #define LFU_NOTD     0x00A00000
  53. #define LFU_N_SXORD  0x00C00000
  54. #define LFU_NSORND   0x00E00000
  55. #define LFU_SAD      0x01000000
  56. #define LFU_SXORD    0x01200000
  57. #define LFU_D        0x01400000
  58. #define LFU_NSORD    0x01600000
  59. #define LFU_S        0x01800000
  60. #define LFU_SORND    0x01A00000
  61. #define LFU_SORD     0x01C00000
  62. #define LFU_ONE      0x01E00000
  63.  
  64. #define LFU_REPLACE  0x01800000
  65. #define LFU_XOR      0x01200000
  66. #define LFU_CLEAR    0x00000000
  67.  
  68. #define CMPDST       0x02000000
  69. #define BCOMPEN      0x04000000
  70. #define DCOMPEN      0x08000000
  71. #define BKGWREN      0x10000000
  72. #define BUSHI        0x20000000
  73. #define SRCSHADE     0x40000000
  74.  
  75. #define WIDTH        0x00007E00        // A1 and A2 Flags
  76. #define PITCH        0x00000003  
  77. #define PIXEL        0x00000038  
  78.  
  79. #define HI_WORD      0xFFFF0000        // Miscellaneous        
  80. #define LO_WORD      0x0000FFFF
  81.  
  82. ////////////////////////////////////////////////////////////////////////////////
  83. // Globals
  84.  
  85.    BLTSTATE blt;                       // Blitter State
  86.  
  87. ////////////////////////////////////////////////////////////////////////////////
  88. // Perform Blit as per Blitter Command Word
  89.  
  90.    BOOL blit( dword bcmd )
  91.    {
  92.       int    o, i;                     // Line and Pixel Iterators
  93.       dword  s_width, d_width;         // Source and Destination Window Widths
  94.       dword  s_pixs, d_pixs;           // Source and Destination Pixel Size
  95.       sword  s_xpos, s_ypos;           // Source X and Y Pixel Positions
  96.       sword  d_xpos, d_ypos;           // Destination X and Y Pixel Positions
  97.       word   bcount_y, bcount_x;       // Inner and Outer Loop Iterations
  98.       dword  cs_addr, cd_addr;         // Current Source and Dest Addresses
  99.       dword  srcen;                    // Source Read Enable
  100.       phrase rdp;                      // Read Data Phrase
  101.  
  102.       // Width in Pixels of a Scanline
  103.       dword widths[48] = {             
  104.              0,     0,     0,      0,      2,      0,      0,      0,      4,
  105.              0,     6,     0,      8,     10,     12,     14,     16,     20,
  106.             24,    28,    32,     40,     48,     56,     64,     80,     96,
  107.            112,   128,   160,    192,    224,    256,    320,    384,    448,
  108.            512,   640,   768,    896,   1024,   1280,   1536,   1792,   2048,
  109.           2560,  3072,  3584
  110.       };
  111.  
  112.       // Check for Unimplemented Blitter Commands (1 = Unimplemented)
  113.       // 0011 1110 0001 1110 1111 0001 0111 1111
  114.       if( bcmd & 0x3E1EF17E )
  115.       {
  116.          #ifdef DBGBLT
  117.          error( "Unimplemented Blitter Commands Detected - "
  118.                 "(0x%08X)", bcmd & 0x3E1EF17E);
  119.          #endif
  120.          return( FALSE );
  121.       }
  122.       if( bcmd & 0x00000001 ) 
  123.       {
  124.          #ifdef DBGBLT
  125.          print( YEL"SRCEN Enabled !!!!\n" );
  126.          #endif
  127.          srcen = 1;
  128.       }
  129.       else srcen = 0;
  130.  
  131.       if( bcmd & DSTA2 )               // A1 Regs are Source, A2 Regs are Dest
  132.       {
  133.          // Obtain Source and Destination Window Widths 
  134.          d_width = widths[((blt.a2flags & WIDTH) >> 9)];
  135.          s_width = widths[((blt.a1flags & WIDTH) >> 9)];
  136.          // Obtain Source and Destination X and Y Positions
  137.          d_xpos  =  blt.a2pixel & LO_WORD;
  138.          d_ypos  = (blt.a2pixel & HI_WORD) >> 16;
  139.          s_xpos  =  blt.a1pixel & LO_WORD;
  140.          s_ypos  = (blt.a1pixel & HI_WORD) >> 16;
  141.          // Obtain Source and Destination Pixel Sizes
  142.          s_pixs  = blt.a1flags & PIXEL;
  143.          d_pixs  = blt.a2flags & PIXEL;
  144.       }
  145.       else                             // A2 Regs are Source, A1 Regs are Dest
  146.       {
  147.          // Obtain Source and Destination Window Widths 
  148.          s_width = widths[((blt.a2flags & WIDTH) >> 9)];
  149.          d_width = widths[((blt.a1flags & WIDTH) >> 9)];
  150.          // Obtain Source and Destination X and Y Positions
  151.          s_xpos  =  blt.a2pixel & LO_WORD;
  152.          s_ypos  = (blt.a2pixel & HI_WORD) >> 16;
  153.          d_xpos  =  blt.a1pixel & LO_WORD;
  154.          d_ypos  = (blt.a1pixel & HI_WORD) >> 16;
  155.          // Obtain Source and Destination Pixel Sizes
  156.          s_pixs  = blt.a2flags & PIXEL;
  157.          d_pixs  = blt.a1flags & PIXEL;
  158.       }
  159.  
  160.       // Obtain Inner and Outer Loop Iterations
  161.       bcount_y = (blt.bcount & HI_WORD) >> 16;
  162.       bcount_x =  blt.bcount & LO_WORD;
  163.  
  164.       if( !bcount_y || !bcount_x )
  165.       {
  166.          #ifdef DBGBLT
  167.          error( "BCOUNT == 0 (should be 65536) !!!!!!!!!" );
  168.          #endif 
  169.          return( FALSE );
  170.       }
  171.       
  172.       // Obtain Source and Data Addresses 
  173.       if( bcmd & DSTA2 )            // A1 Regs are Source, A2 Regs are Dest
  174.       {
  175.          cd_addr = blt.a2base;
  176.          cs_addr = blt.a1base;
  177.       }
  178.       else                          // A2 Regs are Source, A1 Regs are Dest
  179.       {
  180.          cs_addr = blt.a2base;
  181.          cd_addr = blt.a1base;
  182.       }
  183.  
  184.       if( bcmd & PATDSEL )          // Select Pattern Data as the Write Data
  185.       {
  186.          // Set Read Data Phrase to the Contents of the Pattern Data Reg
  187.          rdp.hi = blt.bpatd.hi;
  188.          rdp.lo = blt.bpatd.lo;
  189.       }
  190.  
  191.       // Outer Loop Processing
  192.       for( o = 0; o < bcount_y; o++ )  // Lines
  193.       {
  194.          // Inner Loop Processing
  195.          for( i = 0; i < bcount_x; i++ ) // Pixels
  196.          {
  197.             switch( bcmd & LFU_OP )    // Writing takes Place via Logical Op
  198.             {
  199.                case LFU_ZERO:          // DST = 0 (LFU_CLEAR)
  200.                   switch( d_pixs )
  201.                   {
  202.                     case 0x28: // 32 Bit
  203.                        mem_writeword( cd_addr, 0x00000000 );
  204.                        cd_addr += 2;
  205.                        mem_writeword( cd_addr, 0x00000000 );
  206.                        cd_addr += 2;
  207.                        break;
  208.                      case 0x20: // 16 Bit
  209.                         mem_writeword( cd_addr, 0x00000000 );
  210.                         cd_addr += 2;
  211.                         break;
  212.                      case 0x18: // 8 Bit
  213.                         mem_writebyte( cd_addr, 0x00000000 );
  214.                         cd_addr += 1;
  215.                         break;
  216.                      default:
  217.                         #ifdef DBGBLT
  218.                         error( "D_PIXS Unimplementated Issue (LFU_ZERO) [0x%02X]", d_pixs );
  219.                         #endif
  220.                         break;
  221.                   }
  222.                   break;
  223.  
  224.                case LFU_NSAND:         // DST = ! SRC & ! DST
  225.                   #ifdef DBGBLT
  226.                   error( "Blitter: Logical OP (1) Implementation!!!\n" );
  227.                   #endif
  228.                   break;
  229.  
  230.                case LFU_NSAD:          // DST = ! SRC & DST         
  231.                   #ifdef DBGBLT
  232.                   error( "Blitter: Logical OP (2) Implementation!!!\n" );
  233.                   #endif
  234.                   break;
  235.                   
  236.                case LFU_NOTS:          // DST = ! SRC
  237.                   #ifdef DBGBLT
  238.                   error( "Blitter: Logical OP (3) Implementation!!!\n" );
  239.                   #endif
  240.                   break;
  241.  
  242.                case LFU_SAND:          // DST = SRC & ! DST         
  243.                   #ifdef DBGBLT
  244.                   error( "Blitter: Logical OP (4) Implementation!!!\n" );
  245.                   #endif
  246.                   break;
  247.                   
  248.                case LFU_NOTD:          // DST = ! DST
  249.                   #ifdef DBGBLT
  250.                   error( "Blitter: Logical OP (5) Implementation!!!\n" );
  251.                   #endif
  252.                   break;
  253.  
  254.                case LFU_N_SXORD:       // DST = ! (SRC ^ DST)
  255.                   #ifdef DBGBLT
  256.                   error( "Blitter: Logical OP (6) Implementation!!!\n" );
  257.                   #endif
  258.                   break;
  259.  
  260.                case LFU_NSORND:        // DST = ! SRC | ! DST
  261.                   #ifdef DBGBLT
  262.                   error( "Blitter: Logical OP (7) Implementation!!!\n" );
  263.                   #endif
  264.                   break;
  265.  
  266.                case LFU_SAD:           // DST = SRC & DST
  267.                   #ifdef DBGBLT
  268.                   error( "Blitter: Logical OP (8) Implementation!!!\n" );
  269.                   #endif
  270.                   break;
  271.  
  272.                case LFU_SXORD:         // DST = SRC ^ DST (LFU_XOR)
  273.                   #ifdef DBGBLT
  274.                   error( "Blitter: Logical OP (9) Implementation!!!\n" );
  275.                   #endif
  276.                   break;
  277.  
  278.                case LFU_D:             // DST = DST        
  279.                   #ifdef DBGBLT
  280.                   error( "Blitter: Logical OP (10) Implementation!!!\n" );
  281.                   #endif
  282.                   break;
  283.                   
  284.                case LFU_NSORD:         // DST = ! SRC | DST
  285.                   #ifdef DBGBLT
  286.                   error( "Blitter: Logical OP (11) Implementation!!!\n" );
  287.                   #endif
  288.                   break;
  289.  
  290.                case LFU_S:             // DST = SRC (LFU_REPLACE)
  291.                   if( srcen )
  292.                   {
  293.                      switch( d_pixs )
  294.                      {
  295.                         case 0x28: // 32 Bit
  296.                            mem_writeword( cd_addr, mem_readword( cs_addr ) );
  297.                            cd_addr += 2; cs_addr += 2;
  298.                            mem_writeword( cd_addr, mem_readword( cs_addr ) );
  299.                            cd_addr += 2; cs_addr += 2;
  300.                            //print( YEL"LFU_S: 32-Bit\n" );
  301.                            break;
  302.                         case 0x20: // 16 Bit
  303.                            mem_writeword( cd_addr, mem_readword( cs_addr ) );
  304.                            cd_addr += 2; cs_addr += 2;
  305.                            //print( YEL"LFU_S: 16-Bit\n" );
  306.                            break;
  307.                         case 0x18: // 8 Bit
  308.                            mem_writebyte( cd_addr, mem_readbyte( cs_addr ) );
  309.                            cd_addr++; cs_addr++;
  310.                            break;
  311.                         default:
  312.                            #ifdef DBGBLT
  313.                            error( "D_PIXS Unimplementated Issue (LFU_S) [0x%02X]", d_pixs );
  314.                            #endif
  315.                            break;
  316.                      }
  317.                   }
  318.                   else
  319.                   {
  320.                      #ifdef DBGBLT
  321.                      error( "SRCEN Issue (LFU_S)" );
  322.                      #endif
  323.                   }
  324.                   break;
  325.  
  326.                case LFU_SORND:         // DST = SRC | ! DST
  327.                   #ifdef DBGBLT
  328.                   error( "Blitter: Logical OP (13) Implementation!!!\n" );
  329.                   #endif
  330.                   break;
  331.  
  332.                case LFU_SORD:          // DST = SRC | DST        
  333.                   #ifdef DBGBLT
  334.                   error( "Blitter: Logical OP (14) Implementation!!!\n" );
  335.                   #endif
  336.                   break;
  337.  
  338.                case LFU_ONE:           // DST = 1
  339.                   #ifdef DBGBLT
  340.                   error( "Blitter: Logical OP (15) Implementation!!!\n" );
  341.                   #endif
  342.                   break;
  343.  
  344.                default:
  345.                   break;
  346.             }
  347.          }
  348.  
  349.          // Unimplemented But Recognised Flags
  350.          if( bcmd & UPDA1 )            // Add A1 Step Value to A1 Pointer
  351.             ;// printf( "[BLITTER] UPDA1 Implementation!!!\n" );
  352.          if( bcmd & UPDA2 )            // Add A2 Step Value to A2 Pointer
  353.             ;// printf( "[BLITTER] UPDA2 Implementation!!!\n" );
  354.       }
  355.  
  356.       return( TRUE );
  357.    }
  358.  
  359. ////////////////////////////////////////////////////////////////////////////////
  360. // Execute a Blitter Command
  361.  
  362.    //DWORD exec_blitter( LPVOID lpParam )
  363.    void exec_blitter( void )
  364.    {
  365.       blt.bltInactive = FALSE;         // Blitter is Active
  366.  
  367.       if( !blit( blt.bcmd ) )          // Perform BLIT
  368.       {
  369.          #ifdef DBGBLT
  370.          error( "BLITTER OPERATION FAILED" );
  371.          #endif
  372.       }
  373.  
  374.       blt.bltInactive = TRUE;          // Blitter is Inactive
  375.    }