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 >
Wrap
C/C++ Source or Header
|
2001-08-17
|
14KB
|
375 lines
////////////////////////////////////////////////////////////////////////////////
// Jagulator: Atari Jaguar Console Emulation Project (blitter.c)
// -----------------------------------------------------------------------------
// Jagulator is the Copyright (c) RealityMan 1998-2001 and is provided "as is"
// without any expressed or implied warranty. I have no Trademarks, Legal or
// otherwise. Atari, Jaguar and the Atari Logo are copyright Hasbro Inc. All
// other Copyrights and Trademarks are acknowledged. This project is in no way
// linked to Atari/Hasbro or other associated Atari companies.
//
// 07-07-2001 GH: New Source, Rewritten for Release 1.5.0
// 00-00-0000 GH: All Previous Source Considered as Development Code Only
#include "core.h"
////////////////////////////////////////////////////////////////////////////////
// Blitter Defines
#define SRCEN 0x00000001 // Blitter Command Word
#define SRCENZ 0x00000002
#define SRCENX 0x00000004
#define DSTEN 0x00000008
#define DSTENZ 0x00000010
#define DSTWRZ 0x00000020
#define CLIP_A1 0x00000040
#define NOGO 0x00000080
#define UPDA1F 0x00000100
#define UPDA1 0x00000200
#define UPDA2 0x00000400
#define DSTA2 0x00000800
#define GOURD 0x00001000
#define GOURZ 0x00002000
#define TOPBEN 0x00004000
#define TOPNEN 0x00008000
#define PATDSEL 0x00010000
#define ADDDSEL 0x00020000
#define ZMODELT 0x00040000
#define ZMODEEQ 0x00080000
#define ZMODEGT 0x00100000
#define LFU_OP 0x01E00000
#define LFU_NAN 0x00200000
#define LFU_NA 0x00400000
#define LFU_AN 0x00800000
#define LFU_A 0x01000000
#define LFU_ZERO 0x00000000
#define LFU_NSAND 0x00200000
#define LFU_NSAD 0x00400000
#define LFU_NOTS 0x00600000
#define LFU_SAND 0x00800000
#define LFU_NOTD 0x00A00000
#define LFU_N_SXORD 0x00C00000
#define LFU_NSORND 0x00E00000
#define LFU_SAD 0x01000000
#define LFU_SXORD 0x01200000
#define LFU_D 0x01400000
#define LFU_NSORD 0x01600000
#define LFU_S 0x01800000
#define LFU_SORND 0x01A00000
#define LFU_SORD 0x01C00000
#define LFU_ONE 0x01E00000
#define LFU_REPLACE 0x01800000
#define LFU_XOR 0x01200000
#define LFU_CLEAR 0x00000000
#define CMPDST 0x02000000
#define BCOMPEN 0x04000000
#define DCOMPEN 0x08000000
#define BKGWREN 0x10000000
#define BUSHI 0x20000000
#define SRCSHADE 0x40000000
#define WIDTH 0x00007E00 // A1 and A2 Flags
#define PITCH 0x00000003
#define PIXEL 0x00000038
#define HI_WORD 0xFFFF0000 // Miscellaneous
#define LO_WORD 0x0000FFFF
////////////////////////////////////////////////////////////////////////////////
// Globals
BLTSTATE blt; // Blitter State
////////////////////////////////////////////////////////////////////////////////
// Perform Blit as per Blitter Command Word
BOOL blit( dword bcmd )
{
int o, i; // Line and Pixel Iterators
dword s_width, d_width; // Source and Destination Window Widths
dword s_pixs, d_pixs; // Source and Destination Pixel Size
sword s_xpos, s_ypos; // Source X and Y Pixel Positions
sword d_xpos, d_ypos; // Destination X and Y Pixel Positions
word bcount_y, bcount_x; // Inner and Outer Loop Iterations
dword cs_addr, cd_addr; // Current Source and Dest Addresses
dword srcen; // Source Read Enable
phrase rdp; // Read Data Phrase
// Width in Pixels of a Scanline
dword widths[48] = {
0, 0, 0, 0, 2, 0, 0, 0, 4,
0, 6, 0, 8, 10, 12, 14, 16, 20,
24, 28, 32, 40, 48, 56, 64, 80, 96,
112, 128, 160, 192, 224, 256, 320, 384, 448,
512, 640, 768, 896, 1024, 1280, 1536, 1792, 2048,
2560, 3072, 3584
};
// Check for Unimplemented Blitter Commands (1 = Unimplemented)
// 0011 1110 0001 1110 1111 0001 0111 1111
if( bcmd & 0x3E1EF17E )
{
#ifdef DBGBLT
error( "Unimplemented Blitter Commands Detected - "
"(0x%08X)", bcmd & 0x3E1EF17E);
#endif
return( FALSE );
}
if( bcmd & 0x00000001 )
{
#ifdef DBGBLT
print( YEL"SRCEN Enabled !!!!\n" );
#endif
srcen = 1;
}
else srcen = 0;
if( bcmd & DSTA2 ) // A1 Regs are Source, A2 Regs are Dest
{
// Obtain Source and Destination Window Widths
d_width = widths[((blt.a2flags & WIDTH) >> 9)];
s_width = widths[((blt.a1flags & WIDTH) >> 9)];
// Obtain Source and Destination X and Y Positions
d_xpos = blt.a2pixel & LO_WORD;
d_ypos = (blt.a2pixel & HI_WORD) >> 16;
s_xpos = blt.a1pixel & LO_WORD;
s_ypos = (blt.a1pixel & HI_WORD) >> 16;
// Obtain Source and Destination Pixel Sizes
s_pixs = blt.a1flags & PIXEL;
d_pixs = blt.a2flags & PIXEL;
}
else // A2 Regs are Source, A1 Regs are Dest
{
// Obtain Source and Destination Window Widths
s_width = widths[((blt.a2flags & WIDTH) >> 9)];
d_width = widths[((blt.a1flags & WIDTH) >> 9)];
// Obtain Source and Destination X and Y Positions
s_xpos = blt.a2pixel & LO_WORD;
s_ypos = (blt.a2pixel & HI_WORD) >> 16;
d_xpos = blt.a1pixel & LO_WORD;
d_ypos = (blt.a1pixel & HI_WORD) >> 16;
// Obtain Source and Destination Pixel Sizes
s_pixs = blt.a2flags & PIXEL;
d_pixs = blt.a1flags & PIXEL;
}
// Obtain Inner and Outer Loop Iterations
bcount_y = (blt.bcount & HI_WORD) >> 16;
bcount_x = blt.bcount & LO_WORD;
if( !bcount_y || !bcount_x )
{
#ifdef DBGBLT
error( "BCOUNT == 0 (should be 65536) !!!!!!!!!" );
#endif
return( FALSE );
}
// Obtain Source and Data Addresses
if( bcmd & DSTA2 ) // A1 Regs are Source, A2 Regs are Dest
{
cd_addr = blt.a2base;
cs_addr = blt.a1base;
}
else // A2 Regs are Source, A1 Regs are Dest
{
cs_addr = blt.a2base;
cd_addr = blt.a1base;
}
if( bcmd & PATDSEL ) // Select Pattern Data as the Write Data
{
// Set Read Data Phrase to the Contents of the Pattern Data Reg
rdp.hi = blt.bpatd.hi;
rdp.lo = blt.bpatd.lo;
}
// Outer Loop Processing
for( o = 0; o < bcount_y; o++ ) // Lines
{
// Inner Loop Processing
for( i = 0; i < bcount_x; i++ ) // Pixels
{
switch( bcmd & LFU_OP ) // Writing takes Place via Logical Op
{
case LFU_ZERO: // DST = 0 (LFU_CLEAR)
switch( d_pixs )
{
case 0x28: // 32 Bit
mem_writeword( cd_addr, 0x00000000 );
cd_addr += 2;
mem_writeword( cd_addr, 0x00000000 );
cd_addr += 2;
break;
case 0x20: // 16 Bit
mem_writeword( cd_addr, 0x00000000 );
cd_addr += 2;
break;
case 0x18: // 8 Bit
mem_writebyte( cd_addr, 0x00000000 );
cd_addr += 1;
break;
default:
#ifdef DBGBLT
error( "D_PIXS Unimplementated Issue (LFU_ZERO) [0x%02X]", d_pixs );
#endif
break;
}
break;
case LFU_NSAND: // DST = ! SRC & ! DST
#ifdef DBGBLT
error( "Blitter: Logical OP (1) Implementation!!!\n" );
#endif
break;
case LFU_NSAD: // DST = ! SRC & DST
#ifdef DBGBLT
error( "Blitter: Logical OP (2) Implementation!!!\n" );
#endif
break;
case LFU_NOTS: // DST = ! SRC
#ifdef DBGBLT
error( "Blitter: Logical OP (3) Implementation!!!\n" );
#endif
break;
case LFU_SAND: // DST = SRC & ! DST
#ifdef DBGBLT
error( "Blitter: Logical OP (4) Implementation!!!\n" );
#endif
break;
case LFU_NOTD: // DST = ! DST
#ifdef DBGBLT
error( "Blitter: Logical OP (5) Implementation!!!\n" );
#endif
break;
case LFU_N_SXORD: // DST = ! (SRC ^ DST)
#ifdef DBGBLT
error( "Blitter: Logical OP (6) Implementation!!!\n" );
#endif
break;
case LFU_NSORND: // DST = ! SRC | ! DST
#ifdef DBGBLT
error( "Blitter: Logical OP (7) Implementation!!!\n" );
#endif
break;
case LFU_SAD: // DST = SRC & DST
#ifdef DBGBLT
error( "Blitter: Logical OP (8) Implementation!!!\n" );
#endif
break;
case LFU_SXORD: // DST = SRC ^ DST (LFU_XOR)
#ifdef DBGBLT
error( "Blitter: Logical OP (9) Implementation!!!\n" );
#endif
break;
case LFU_D: // DST = DST
#ifdef DBGBLT
error( "Blitter: Logical OP (10) Implementation!!!\n" );
#endif
break;
case LFU_NSORD: // DST = ! SRC | DST
#ifdef DBGBLT
error( "Blitter: Logical OP (11) Implementation!!!\n" );
#endif
break;
case LFU_S: // DST = SRC (LFU_REPLACE)
if( srcen )
{
switch( d_pixs )
{
case 0x28: // 32 Bit
mem_writeword( cd_addr, mem_readword( cs_addr ) );
cd_addr += 2; cs_addr += 2;
mem_writeword( cd_addr, mem_readword( cs_addr ) );
cd_addr += 2; cs_addr += 2;
//print( YEL"LFU_S: 32-Bit\n" );
break;
case 0x20: // 16 Bit
mem_writeword( cd_addr, mem_readword( cs_addr ) );
cd_addr += 2; cs_addr += 2;
//print( YEL"LFU_S: 16-Bit\n" );
break;
case 0x18: // 8 Bit
mem_writebyte( cd_addr, mem_readbyte( cs_addr ) );
cd_addr++; cs_addr++;
break;
default:
#ifdef DBGBLT
error( "D_PIXS Unimplementated Issue (LFU_S) [0x%02X]", d_pixs );
#endif
break;
}
}
else
{
#ifdef DBGBLT
error( "SRCEN Issue (LFU_S)" );
#endif
}
break;
case LFU_SORND: // DST = SRC | ! DST
#ifdef DBGBLT
error( "Blitter: Logical OP (13) Implementation!!!\n" );
#endif
break;
case LFU_SORD: // DST = SRC | DST
#ifdef DBGBLT
error( "Blitter: Logical OP (14) Implementation!!!\n" );
#endif
break;
case LFU_ONE: // DST = 1
#ifdef DBGBLT
error( "Blitter: Logical OP (15) Implementation!!!\n" );
#endif
break;
default:
break;
}
}
// Unimplemented But Recognised Flags
if( bcmd & UPDA1 ) // Add A1 Step Value to A1 Pointer
;// printf( "[BLITTER] UPDA1 Implementation!!!\n" );
if( bcmd & UPDA2 ) // Add A2 Step Value to A2 Pointer
;// printf( "[BLITTER] UPDA2 Implementation!!!\n" );
}
return( TRUE );
}
////////////////////////////////////////////////////////////////////////////////
// Execute a Blitter Command
//DWORD exec_blitter( LPVOID lpParam )
void exec_blitter( void )
{
blt.bltInactive = FALSE; // Blitter is Active
if( !blit( blt.bcmd ) ) // Perform BLIT
{
#ifdef DBGBLT
error( "BLITTER OPERATION FAILED" );
#endif
}
blt.bltInactive = TRUE; // Blitter is Inactive
}