X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fblitter.cpp;h=857c8d2392deef322ae98555c4a2f2b646b0fc59;hb=7ea062c269444985409c61b1ec61760a3dcf9e62;hp=52a117a912cce96e9160bc815cfb82cfa173e7f2;hpb=0031c06df2f7f099ca5ecf1632f46b92f6b0dd79;p=virtualjaguar diff --git a/src/blitter.cpp b/src/blitter.cpp index 52a117a..857c8d2 100644 --- a/src/blitter.cpp +++ b/src/blitter.cpp @@ -3,39 +3,33 @@ // // by cal2 // GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Caz (BeOS) -// Cleanups by James L. Hammons +// Cleanups/fixes by James L. Hammons // +bool specialLog = false; -#define GEN_CODE -//#define LOG_BLITS -//#define USE_GENERIC_BLITTER - #include "jaguar.h" -#define null 0 -extern int jaguar_active_memory_dumps; - -#define REG(A) blitter_reg_read(A) -#define WREG(A,D) blitter_reg_write(A,D) +#define REG(A) (((uint32)blitter_ram[(A)] << 24) | ((uint32)blitter_ram[(A)+1] << 16) \ + | ((uint32)blitter_ram[(A)+2] << 8) | (uint32)blitter_ram[(A)+3]) +#define WREG(A,D) (blitter_ram[(A)] = ((D)>>24)&0xFF, blitter_ram[(A)+1] = ((D)>>16)&0xFF, \ + blitter_ram[(A)+2] = ((D)>>8)&0xFF, blitter_ram[(A)+3] = (D)&0xFF) -int start_logging = 0; - -static uint8 blitter_ram[0x100]; +// Blitter registers (offsets from F02200) #define A1_BASE ((UINT32)0x00) #define A1_FLAGS ((UINT32)0x04) -#define A1_CLIP ((UINT32)0x08) // height and width values for clipping -#define A1_PIXEL ((UINT32)0x0c) // integer part of the pixel (Y.i and X.i) -#define A1_STEP ((UINT32)0x10) // integer part of the step -#define A1_FSTEP ((UINT32)0x14) // fractionnal part of the step -#define A1_FPIXEL ((UINT32)0x18) // fractionnal part of the pixel (Y.f and X.f) -#define A1_INC ((UINT32)0x1C) // integer part of the increment -#define A1_FINC ((UINT32)0x20) // fractionnal part of the increment +#define A1_CLIP ((UINT32)0x08) // Height and width values for clipping +#define A1_PIXEL ((UINT32)0x0C) // Integer part of the pixel (Y.i and X.i) +#define A1_STEP ((UINT32)0x10) // Integer part of the step +#define A1_FSTEP ((UINT32)0x14) // Fractionnal part of the step +#define A1_FPIXEL ((UINT32)0x18) // Fractionnal part of the pixel (Y.f and X.f) +#define A1_INC ((UINT32)0x1C) // Integer part of the increment +#define A1_FINC ((UINT32)0x20) // Fractional part of the increment #define A2_BASE ((UINT32)0x24) #define A2_FLAGS ((UINT32)0x28) -#define A2_MASK ((UINT32)0x2c) // modulo values for x and y (M.y and M.x) -#define A2_PIXEL ((UINT32)0x30) // integer part of the pixel (no fractionnal part for A2) -#define A2_STEP ((UINT32)0x34) // integer part of the step (no fractionnal part for A2) +#define A2_MASK ((UINT32)0x2C) // Modulo values for x and y (M.y and M.x) +#define A2_PIXEL ((UINT32)0x30) // Integer part of the pixel (no fractional part for A2) +#define A2_STEP ((UINT32)0x34) // Integer part of the step (no fractional part for A2) #define COMMAND ((UINT32)0x38) #define PIXLINECOUNTER ((UINT32)0x3C) #define SRCDATA ((UINT32)0x40) @@ -56,36 +50,43 @@ static uint8 blitter_ram[0x100]; #define PHRASEZ1 ((UINT32)0x94) #define PHRASEZ0 ((UINT32)0x98) -#define SRCEN (cmd&0x00000001) -#define SRCENZ (cmd&0x00000002) -#define SRCENX (cmd&0x00000004) -#define DSTEN (cmd&0x00000008) -#define DSTENZ (cmd&0x00000010) -#define DSTWRZ (cmd&0x00000020) -#define CLIPA1 (cmd&0x00000040) -#define DSTA2 (cmd&0x00000800) - -#define Z_OP_INF (cmd&0x00040000) -#define Z_OP_EQU (cmd&0x00080000) -#define Z_OP_SUP (cmd&0x00100000) - -#define CMPDST (cmd&0x02000000) -#define BCOMPEN (cmd&0x04000000) -#define DCOMPEN (cmd&0x08000000) - -#define LFU_NAN (cmd&0x00200000) -#define LFU_NA (cmd&0x00400000) -#define LFU_AN (cmd&0x00800000) -#define LFU_A (cmd&0x01000000) - -#define PATDSEL (cmd&0x00010000) -#define INTADD (cmd&0x00020000) -#define TOPBEN (cmd&0x00004000) -#define TOPNEN (cmd&0x00008000) -#define BKGWREN (cmd&0x10000000) -#define GOURD (cmd&0x00001000) -#define GOURZ (cmd&0x00002000) -#define SRCSHADE (cmd&0x40000000) +// Blitter command bits + +#define SRCEN (cmd & 0x00000001) +#define SRCENZ (cmd & 0x00000002) +#define SRCENX (cmd & 0x00000004) +#define DSTEN (cmd & 0x00000008) +#define DSTENZ (cmd & 0x00000010) +#define DSTWRZ (cmd & 0x00000020) +#define CLIPA1 (cmd & 0x00000040) + +#define UPDA1F (cmd & 0x00000100) +#define UPDA1 (cmd & 0x00000200) +#define UPDA2 (cmd & 0x00000400) + +#define DSTA2 (cmd & 0x00000800) + +#define Z_OP_INF (cmd & 0x00040000) +#define Z_OP_EQU (cmd & 0x00080000) +#define Z_OP_SUP (cmd & 0x00100000) + +#define LFU_NAN (cmd & 0x00200000) +#define LFU_NA (cmd & 0x00400000) +#define LFU_AN (cmd & 0x00800000) +#define LFU_A (cmd & 0x01000000) + +#define CMPDST (cmd & 0x02000000) +#define BCOMPEN (cmd & 0x04000000) +#define DCOMPEN (cmd & 0x08000000) + +#define PATDSEL (cmd & 0x00010000) +#define INTADD (cmd & 0x00020000) +#define TOPBEN (cmd & 0x00004000) +#define TOPNEN (cmd & 0x00008000) +#define BKGWREN (cmd & 0x10000000) +#define GOURD (cmd & 0x00001000) +#define GOURZ (cmd & 0x00002000) +#define SRCSHADE (cmd & 0x40000000) #define XADDPHR 0 @@ -93,41 +94,48 @@ static uint8 blitter_ram[0x100]; #define XADD0 2 #define XADDINC 3 -#define XSIGNSUB_A1 (REG(A1_FLAGS)&0x80000) -#define XSIGNSUB_A2 (REG(A2_FLAGS)&0x80000) +#define XSIGNSUB_A1 (REG(A1_FLAGS)&0x080000) +#define XSIGNSUB_A2 (REG(A2_FLAGS)&0x080000) #define YSIGNSUB_A1 (REG(A1_FLAGS)&0x100000) #define YSIGNSUB_A2 (REG(A2_FLAGS)&0x100000) -#define YADD1_A1 (REG(A1_FLAGS)&0x40000) -#define YADD1_A2 (REG(A2_FLAGS)&0x40000) +#define YADD1_A1 (REG(A1_FLAGS)&0x040000) +#define YADD1_A2 (REG(A2_FLAGS)&0x040000) +//Put 'em back, once we fix the problem!!! [KO] // 1 bpp pixel read #define PIXEL_SHIFT_1(a) (((~a##_x) >> 16) & 7) #define PIXEL_OFFSET_1(a) (((((UINT32)a##_y >> 16) * a##_width / 8) + (((UINT32)a##_x >> 19) & ~7)) * (1 + a##_pitch) + (((UINT32)a##_x >> 19) & 7)) -#define READ_PIXEL_1(a) ((jaguar_byte_read(a##_addr+PIXEL_OFFSET_1(a)) >> PIXEL_SHIFT_1(a)) & 0x01) +#define READ_PIXEL_1(a) ((JaguarReadByte(a##_addr+PIXEL_OFFSET_1(a), BLITTER) >> PIXEL_SHIFT_1(a)) & 0x01) +//#define READ_PIXEL_1(a) ((JaguarReadByte(a##_addr+PIXEL_OFFSET_1(a)) >> PIXEL_SHIFT_1(a)) & 0x01) // 2 bpp pixel read #define PIXEL_SHIFT_2(a) (((~a##_x) >> 15) & 6) #define PIXEL_OFFSET_2(a) (((((UINT32)a##_y >> 16) * a##_width / 4) + (((UINT32)a##_x >> 18) & ~7)) * (1 + a##_pitch) + (((UINT32)a##_x >> 18) & 7)) -#define READ_PIXEL_2(a) ((jaguar_byte_read(a##_addr+PIXEL_OFFSET_2(a)) >> PIXEL_SHIFT_2(a)) & 0x03) +#define READ_PIXEL_2(a) ((JaguarReadByte(a##_addr+PIXEL_OFFSET_2(a), BLITTER) >> PIXEL_SHIFT_2(a)) & 0x03) +//#define READ_PIXEL_2(a) ((JaguarReadByte(a##_addr+PIXEL_OFFSET_2(a)) >> PIXEL_SHIFT_2(a)) & 0x03) // 4 bpp pixel read #define PIXEL_SHIFT_4(a) (((~a##_x) >> 14) & 4) #define PIXEL_OFFSET_4(a) (((((UINT32)a##_y >> 16) * (a##_width/2)) + (((UINT32)a##_x >> 17) & ~7)) * (1 + a##_pitch) + (((UINT32)a##_x >> 17) & 7)) -#define READ_PIXEL_4(a) ((jaguar_byte_read(a##_addr+PIXEL_OFFSET_4(a)) >> PIXEL_SHIFT_4(a)) & 0x0f) +#define READ_PIXEL_4(a) ((JaguarReadByte(a##_addr+PIXEL_OFFSET_4(a), BLITTER) >> PIXEL_SHIFT_4(a)) & 0x0f) +//#define READ_PIXEL_4(a) ((JaguarReadByte(a##_addr+PIXEL_OFFSET_4(a)) >> PIXEL_SHIFT_4(a)) & 0x0f) // 8 bpp pixel read #define PIXEL_OFFSET_8(a) (((((UINT32)a##_y >> 16) * a##_width) + (((UINT32)a##_x >> 16) & ~7)) * (1 + a##_pitch) + (((UINT32)a##_x >> 16) & 7)) -#define READ_PIXEL_8(a) (jaguar_byte_read(a##_addr+PIXEL_OFFSET_8(a))) +#define READ_PIXEL_8(a) (JaguarReadByte(a##_addr+PIXEL_OFFSET_8(a), BLITTER)) +//#define READ_PIXEL_8(a) (JaguarReadByte(a##_addr+PIXEL_OFFSET_8(a))) // 16 bpp pixel read #define PIXEL_OFFSET_16(a) (((((UINT32)a##_y >> 16) * a##_width) + (((UINT32)a##_x >> 16) & ~3)) * (1 + a##_pitch) + (((UINT32)a##_x >> 16) & 3)) -#define READ_PIXEL_16(a) (jaguar_word_read(a##_addr+(PIXEL_OFFSET_16(a)<<1))) +#define READ_PIXEL_16(a) (JaguarReadWord(a##_addr+(PIXEL_OFFSET_16(a)<<1), BLITTER)) +//#define READ_PIXEL_16(a) (JaguarReadWord(a##_addr+(PIXEL_OFFSET_16(a)<<1))) // 32 bpp pixel read #define PIXEL_OFFSET_32(a) (((((UINT32)a##_y >> 16) * a##_width) + (((UINT32)a##_x >> 16) & ~1)) * (1 + a##_pitch) + (((UINT32)a##_x >> 16) & 1)) -#define READ_PIXEL_32(a) (jaguar_long_read(a##_addr+(PIXEL_OFFSET_32(a)<<2))) +#define READ_PIXEL_32(a) (JaguarReadLong(a##_addr+(PIXEL_OFFSET_32(a)<<2), BLITTER)) +//#define READ_PIXEL_32(a) (JaguarReadLong(a##_addr+(PIXEL_OFFSET_32(a)<<2))) // pixel read #define READ_PIXEL(a,f) (\ @@ -140,13 +148,15 @@ static uint8 blitter_ram[0x100]; // 16 bpp z data read #define ZDATA_OFFSET_16(a) (PIXEL_OFFSET_16(a) + a##_zoffs * 4) -#define READ_ZDATA_16(a) (jaguar_word_read(a##_addr+(ZDATA_OFFSET_16(a)<<1))) +#define READ_ZDATA_16(a) (JaguarReadWord(a##_addr+(ZDATA_OFFSET_16(a)<<1), BLITTER)) +//#define READ_ZDATA_16(a) (JaguarReadWord(a##_addr+(ZDATA_OFFSET_16(a)<<1))) // z data read #define READ_ZDATA(a,f) (READ_ZDATA_16(a)) // 16 bpp z data write -#define WRITE_ZDATA_16(a,d) { jaguar_word_write(a##_addr+(ZDATA_OFFSET_16(a)<<1),d); } +#define WRITE_ZDATA_16(a,d) { JaguarWriteWord(a##_addr+(ZDATA_OFFSET_16(a)<<1), d, BLITTER); } +//#define WRITE_ZDATA_16(a,d) { JaguarWriteWord(a##_addr+(ZDATA_OFFSET_16(a)<<1), d); } // z data write #define WRITE_ZDATA(a,f,d) WRITE_ZDATA_16(a,d); @@ -169,7 +179,6 @@ static uint8 blitter_ram[0x100]; // 32 bpp r data read #define READ_RDATA_32(r,a,p) ((p) ? REG(r+(((UINT32)a##_x>>14)&4)) : REG(r)) - // register data read #define READ_RDATA(r,a,f,p) (\ (((f>>3)&0x07) == 0) ? (READ_RDATA_1(r,a,p)) : \ @@ -180,49 +189,79 @@ static uint8 blitter_ram[0x100]; (((f>>3)&0x07) == 5) ? (READ_RDATA_32(r,a,p)) : 0) // 1 bpp pixel write -#define WRITE_PIXEL_1(a,d) { jaguar_byte_write(a##_addr+PIXEL_OFFSET_1(a),(jaguar_byte_read(a##_addr+PIXEL_OFFSET_1(a))&(~(0x01 << PIXEL_SHIFT_1(a))))|(d<>3)&0x07) { \ case 0: WRITE_PIXEL_1(a,d); break; \ case 1: WRITE_PIXEL_2(a,d); break; \ - case 2: WRITE_PIXEL_4(a,d); break; \ + case 2: WRITE_PIXEL_4(a,d); break; \ case 3: WRITE_PIXEL_8(a,d); break; \ case 4: WRITE_PIXEL_16(a,d); break; \ case 5: WRITE_PIXEL_32(a,d); break; \ - }} \ + }} + +// External global variables + +extern int jaguar_active_memory_dumps; + +// Local global variables + +int start_logging = 0; +uint8 blitter_working = 0; +// Blitter register RAM (most of it is hidden from the user) +static uint8 blitter_ram[0x100]; // Width in Pixels of a Scanline +// This is a pretranslation of the value found in the A1 & A2 flags: It's really a floating point value +// of the form EEEEMM where MM is the mantissa with an implied "1." in front of it and the EEEE value is +// the exponent. Valid values for the exponent range from 0 to 11 (decimal). It's easiest to think of it +// as a floating point bit pattern being followed by a number of zeroes. So, e.g., 001101 translates to +// 1.01 (the "1." being implied) x (2 ^ 3) or 1010 -> 10 in base 10 (i.e., 1.01 with the decimal place +// being shifted to the right 3 places). static uint32 blitter_scanline_width[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 + 0, 0, 0, 0, // Note: This would really translate to 1, 1, 1, 1 + 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 }; -static uint8 * tom_ram_8; -static uint8 * paletteRam; +//static uint8 * tom_ram_8; +//static uint8 * paletteRam; static uint8 src; static uint8 dst; static uint8 misc; @@ -256,489 +295,59 @@ static int32 a2_xadd; static int32 a2_yadd; static uint8 a1_phrase_mode; static uint8 a2_phrase_mode; -static int32 a1_step_x=0; -static int32 a1_step_y=0; -static int32 a2_step_x=0; -static int32 a2_step_y=0; +static int32 a1_step_x = 0; +static int32 a1_step_y = 0; +static int32 a2_step_x = 0; +static int32 a2_step_y = 0; static uint32 outer_loop; static uint32 inner_loop; static uint32 a2_psize; static uint32 a1_psize; static uint32 gouraud_add; -static uint32 gouraud_data; -static uint16 gint[4]; -static uint16 gfrac[4]; -static uint8 gcolour[4]; -static int gd_i[4]; -static int gd_c[4]; -static int gd_ia,gd_ca; -static int colour_index = 0; -static int32 zadd; -static uint32 z_i[4]; - -static uint8 blitter_code_cache[4096]; -static uint8 * blitter_ptr; -uint8 blitter_working = 0; - -typedef void (blitter_fn)(void); - -typedef struct s_blitter_cache -{ - uint32 hashcode; - uint8 *code; - uint32 ready; - uint8 used; - struct s_blitter_cache *next; - struct s_blitter_cache *prev; -} s_blitter_code_cache; - -s_blitter_cache *blitter_cache[256]; - -uint8 blitter_cache_init=0; -static uint8 BPP_LUT[8]={1,2,4,8,16,32,0,0}; - -FILE *blitters_code_fp; -FILE *blitters_code_init_fp; - -////////////////////////////////////////////////////////////////////////////// -// build C code for the specified blitter -////////////////////////////////////////////////////////////////////////////// -// -// -// -////////////////////////////////////////////////////////////////////////////// -void blitter_gen_c_code(FILE *fp, uint32 cmd,uint32 hashcode) -{ - static uint8 inhibit_modified=0; - - fprintf(fp,"#ifndef blitter_code_0x%.8x\n",hashcode); - fprintf(fp,"#define blitter_code_0x%.8x\n",hashcode); - - fprintf(fp,"void blitter_0x%.8x(void)\n",hashcode); - fprintf(fp,"{\n"); - fprintf(fp,"\twhile (outer_loop--)\n"); - fprintf(fp,"\t{\n"); - fprintf(fp,"\t\tinner_loop=n_pixels;\n"); - fprintf(fp,"\t\twhile (inner_loop--)\n"); - fprintf(fp,"\t\t{\n"); - fprintf(fp,"\t\t\tuint32 srcdata = 0;\n"); - fprintf(fp,"\t\t\tuint32 srczdata = 0;\n"); - fprintf(fp,"\t\t\tuint32 dstdata = 0;\n"); - fprintf(fp,"\t\t\tuint32 dstzdata = 0;\n"); - fprintf(fp,"\t\t\tuint32 writedata = 0;\n"); - fprintf(fp,"\t\t\tuint32 inhibit = 0;\n"); - - char *src; - char *dst; - uint32 src_flags; - uint32 dst_flags; - - if (!DSTA2) - { - src="a2"; - dst="a1"; - src_flags=A2_FLAGS; - dst_flags=A1_FLAGS; - } - else - { - src="a1"; - dst="a2"; - src_flags=A1_FLAGS; - dst_flags=A2_FLAGS; - } - - // load src data and Z - if (SRCEN) - { - fprintf(fp,"\t\t\tsrcdata = READ_PIXEL_%i(%s);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],src); - if (SRCENZ) - fprintf(fp,"\t\t\tsrczdata = READ_ZDATA_%i(%s);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],src); - else - if (cmd & 0x001c020) - fprintf(fp,"\t\t\tsrczdata = READ_RDATA_%i(SRCZINT, %s, %s_phrase_mode);\n",BPP_LUT[(((REG(src_flags))>>3)&0x07)],src,src); - } - else - { - fprintf(fp,"\t\t\tsrcdata = READ_RDATA_%i(SRCDATA, %s, %s_phrase_mode);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],src,src); - if (cmd & 0x001c020) - fprintf(fp,"\t\t\tsrczdata = READ_RDATA_%i(SRCZINT, %s, %s_phrase_mode);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],src,src); - } - - // load dst data and Z - if (DSTEN) - { - fprintf(fp,"\t\t\tdstdata = READ_PIXEL_%i(%s);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],dst); - if (DSTENZ) - fprintf(fp,"\t\t\tdstzdata = READ_ZDATA_%i(%s);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],dst); - else - fprintf(fp,"\t\t\tdstzdata = READ_RDATA_%i(DSTZ, %s, %s_phrase_mode);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],dst,dst); - } - else - { - fprintf(fp,"\t\t\tdstdata = READ_RDATA_%i(DSTDATA, %s, %s_phrase_mode);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],dst,dst); - - if (DSTENZ) - fprintf(fp,"\t\t\tdstzdata = READ_RDATA_%i(DSTZ, %s, %s_phrase_mode);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],dst,dst); - } - - // a1 clipping - if ((cmd & 0x00000040)&&(!DSTA2)) - - { - fprintf(fp,"\t\t\tif (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)) inhibit = 1;\n"); - inhibit_modified=1; - } - if(GOURZ) - { - fprintf(fp,"\t\t\tsrczdata=z_i[colour_index]>>16;\n"); - } - // apply z comparator - if (Z_OP_INF) { fprintf(fp,"\t\t\tif (srczdata < dstzdata) inhibit = 1;\n"); inhibit_modified=1;} - if (Z_OP_EQU) { fprintf(fp,"\t\t\tif (srczdata == dstzdata) inhibit = 1;\n"); inhibit_modified=1;} - if (Z_OP_SUP) { fprintf(fp,"\t\t\tif (srczdata > dstzdata) inhibit = 1;\n"); inhibit_modified=1;} - - // apply data comparator - if (DCOMPEN) - { - if (!CMPDST) - { - // compare source pixel with pattern pixel - fprintf(fp,"\t\t\tif (srcdata == READ_RDATA_%i(PATTERNDATA, %s,%s_phrase_mode)) inhibit=1;\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],src,src); - inhibit_modified=1; - } - else - { - // compare destination pixel with pattern pixel - fprintf(fp,"\t\t\tif (dstdata == READ_RDATA_%i(PATTERNDATA, %s,%s_phrase_mode)) inhibit=1;\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],dst,dst); - inhibit_modified=1; - } - } - - // compute the write data and store - if (inhibit_modified) fprintf(fp,"\t\t\tif (!inhibit)\n\t\t\t{\n"); - if (PATDSEL) - { - // use pattern data for write data - fprintf(fp,"\t\t\t\twritedata= READ_RDATA_%i(PATTERNDATA, %s, %s_phrase_mode);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],dst,dst); - } - else - if (INTADD) - { - // intensity addition - fprintf(fp,"\t\t\t\twritedata = (srcdata & 0xff) + (dstdata & 0xff);\n"); - if (!(TOPBEN)) - fprintf(fp,"\t\t\t\tif (writedata > 0xff) writedata = 0xff;\n"); - - fprintf(fp,"\t\t\t\twritedata |= (srcdata & 0xf00) + (dstdata & 0xf00);\n"); - if (!(TOPNEN)) fprintf(fp,"\t\t\t\tif (writedata > 0xfff) writedata = 0xfff;\n"); - fprintf(fp,"\t\t\t\twritedata |= (srcdata & 0xf000) + (dstdata & 0xf000);\n"); - } - else - { - if (LFU_NAN) fprintf(fp,"\t\t\t\twritedata |= ~srcdata & ~dstdata;\n"); - if (LFU_NA) fprintf(fp,"\t\t\t\twritedata |= ~srcdata & dstdata;\n"); - if (LFU_AN) fprintf(fp,"\t\t\t\twritedata |= srcdata & ~dstdata;\n"); - if (LFU_A) fprintf(fp,"\t\t\t\twritedata |= srcdata & dstdata;\n"); - } - if(GOURD) - { - fprintf(fp,"\t\t\t\twritedata = ((gd_c[colour_index])<<8)|(gd_i[colour_index]>>16);\n"); - } - if(SRCSHADE) - { - fprintf(fp,"\t\t\t\t{\n"); - fprintf(fp,"\t\t\t\tint intensity = srcdata & 0xFF;\n"); - fprintf(fp,"\t\t\t\tint ia = gd_ia >> 16;\n"); - fprintf(fp,"\t\t\t\tif(ia & 0x80)\n"); - fprintf(fp,"\t\t\t\t ia = 0xFFFFFF00 | ia;\n"); - fprintf(fp,"\t\t\t\tintensity += ia;\n"); - fprintf(fp,"\t\t\t\tif(intensity < 0)\n"); - fprintf(fp,"\t\t\t\t intensity = 0;\n"); - fprintf(fp,"\t\t\t\tif(intensity > 0xFF)\n"); - fprintf(fp,"\t\t\t\t intensity = 0xFF;\n"); - fprintf(fp,"\t\t\t\twritedata = (srcdata & 0xFF00) | intensity;\n"); - fprintf(fp,"\t\t\t\t}\n"); - } - if (inhibit_modified) - { - fprintf(fp,"\t\t\t} else { srczdata=dstzdata; writedata=dstdata; }\n"); - } - - if ((DSTA2?a2_phrase_mode:a1_phrase_mode) || BKGWREN) - { - // write to the destination - fprintf(fp,"\t\t\tWRITE_PIXEL_%i(%s, writedata);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],dst); - if (DSTWRZ) fprintf(fp,"\t\t\tWRITE_ZDATA_%i(%s, srczdata);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],dst); - } - else - { - if (inhibit_modified) fprintf(fp,"\t\t\tif (!inhibit)\n\t\t\t{\n"); - // write to the destination - fprintf(fp,"\t\t\t\tWRITE_PIXEL_%i(%s, writedata);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],dst); - if (DSTWRZ) fprintf(fp,"\t\t\t\tWRITE_ZDATA_%i(%s, srczdata);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],dst); - if (inhibit_modified) fprintf(fp,"\t\t\t}\n"); - } - // update x and y - fprintf(fp,"\t\t\ta1_x += a1_xadd;\n"); - fprintf(fp,"\t\t\ta1_y += a1_yadd;\n"); - fprintf(fp,"\t\t\ta2_x = (a2_x + a2_xadd) & a2_mask_x;\n"); - fprintf(fp,"\t\t\ta2_y = (a2_y + a2_yadd) & a2_mask_y;\n"); - if (GOURZ) - { - fprintf(fp,"\t\t\tz_i[colour_index]+=zadd;\n"); - } - if ((GOURD)||(SRCSHADE)) - { - fprintf(fp,"\t\t\tgd_i[colour_index] += gd_ia;\n"); - fprintf(fp,"\t\t\tgd_c[colour_index] += gd_ca;\n"); - } - if ((GOURD)||(SRCSHADE)||(GOURZ)) - { - if (a1_phrase_mode) - fprintf(fp,"\t\t\t colour_index=(colour_index+1)&0x3;\n"); - } - fprintf(fp,"\t\t}\n"); +//static uint32 gouraud_data; +//static uint16 gint[4]; +//static uint16 gfrac[4]; +//static uint8 gcolour[4]; +static int gd_i[4]; +static int gd_c[4]; +static int gd_ia, gd_ca; +static int colour_index = 0; +static int32 zadd; +static uint32 z_i[4]; + +static int32 a1_clip_x, a1_clip_y; + +// In the spirit of "get it right first, *then* optimize" I've taken the liberty +// of removing all the unnecessary code caching. If it turns out to be a good way +// to optimize the blitter, then we may revisit it in the future... - fprintf(fp,"\t\ta1_x+=a1_step_x;\n"); - fprintf(fp,"\t\ta1_y+=a1_step_y;\n"); - fprintf(fp,"\t\ta2_x+=a2_step_x;\n"); - fprintf(fp,"\t\ta2_y+=a2_step_y;\n"); - fprintf(fp,"\t}\n"); - - // write values back to registers - fprintf(fp,"\tWREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff));\n"); - fprintf(fp,"\tWREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff));\n"); - fprintf(fp,"\tWREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff));\n"); - fprintf(fp,"}\n"); - fprintf(fp,"#endif\n"); -} - -////////////////////////////////////////////////////////////////////////////// -// Generate a start of function in x86 assembly -////////////////////////////////////////////////////////////////////////////// -// -// -// -////////////////////////////////////////////////////////////////////////////// -void blitter_gen_start_of_function(void) -{ - *blitter_ptr++=0x55; // push ebp - *blitter_ptr++=0x8b; // mov ebp,esp - *blitter_ptr++=0xec; -} -////////////////////////////////////////////////////////////////////////////// -// Generate a end of function in x86 assembly -////////////////////////////////////////////////////////////////////////////// // +// Generic blit handler // -// -////////////////////////////////////////////////////////////////////////////// -void blitter_gen_end_of_function(void) +void blitter_generic(uint32 cmd) { - *blitter_ptr++=0x8B; // mov esp,ebp - *blitter_ptr++=0xE5; - *blitter_ptr++=0x5D; // pop ebp - *blitter_ptr++=0xC3; // ret -} -////////////////////////////////////////////////////////////////////////////// -// -////////////////////////////////////////////////////////////////////////////// -// -// -// -////////////////////////////////////////////////////////////////////////////// -#define HASHCODE_BIT(C,B) if (C) hashcode|=(1<>3)&0x07)<<0; - hashcode|=((REG(A2_FLAGS)>>3)&0x07)<<3; - - HASHCODE_BIT(DSTA2, 6); - HASHCODE_BIT(SRCEN, 7); - HASHCODE_BIT(SRCENZ, 8); - HASHCODE_BIT(DSTEN, 9); - HASHCODE_BIT(DSTENZ, 10); - HASHCODE_BIT(Z_OP_INF, 11); - HASHCODE_BIT(Z_OP_EQU, 12); - HASHCODE_BIT(Z_OP_SUP, 13); - HASHCODE_BIT(DCOMPEN, 14); - HASHCODE_BIT(CMPDST, 15); - HASHCODE_BIT(PATDSEL, 16); - HASHCODE_BIT(INTADD, 17); - HASHCODE_BIT(TOPBEN, 18); - HASHCODE_BIT(TOPNEN, 19); - HASHCODE_BIT(LFU_NAN, 20); - HASHCODE_BIT(LFU_NA, 21); - HASHCODE_BIT(LFU_AN, 22); - HASHCODE_BIT(LFU_A, 23); - HASHCODE_BIT(BKGWREN, 24); - HASHCODE_BIT(DSTWRZ, 25); - HASHCODE_BIT((cmd & 0x001c020), 26); // extra data read/write - HASHCODE_BIT((cmd & 0x00000040), 27); // source clipping - HASHCODE_BIT(a1_phrase_mode, 28); - HASHCODE_BIT(a2_phrase_mode, 29); - - - return(hashcode); + WriteLog("About to do 8x8 blit (BM width is 448 pixels)...\n"); } -////////////////////////////////////////////////////////////////////////////// -// Build the blitter code for the current blitter operation in the cache -////////////////////////////////////////////////////////////////////////////// -// -// -// -////////////////////////////////////////////////////////////////////////////// -void blitter_build_cached_code(uint32 cmd, uint32 cache_index) -{ -} -////////////////////////////////////////////////////////////////////////////// -// Check if the blitter code for the current blitter operation is cached -////////////////////////////////////////////////////////////////////////////// -// -// -// -////////////////////////////////////////////////////////////////////////////// -struct s_blitter_cache * blitter_in_cache(uint32 cmd) -{ - uint32 i; - uint32 hashcode=blitter_calc_hashcode(cmd); -#ifdef LOG_BLITS - fprintf(log_get(),"blitter: hashcode= 0x%.8x\n",hashcode); -#endif - struct s_blitter_cache *blitter_list=blitter_cache[hashcode>>24]; - - i=0; - while (blitter_list->next) + while (outer_loop--) { - blitter_list=blitter_list->next; - - if (blitter_list->hashcode==hashcode) - return(blitter_list); - } -#ifdef GEN_CODE - blitter_list->next=(struct s_blitter_cache *)malloc(sizeof(struct s_blitter_cache)); - blitter_list->next->prev=blitter_list; - blitter_list->next->next=null; - blitter_list=blitter_list->next; - - blitter_list->code=(uint8*)malloc(4096); - blitter_list->hashcode=hashcode; - blitter_list->ready=0; - blitter_gen_c_code(blitters_code_fp,cmd,hashcode); - fprintf(blitters_code_init_fp,"\tblitter_add(0x%.8x,(uint8*)&blitter_0x%.8x);\n",hashcode,hashcode); -#else - //fprintf(log_get(),"warning: using generic blitter for blitter 0x%.8x\n",hashcode); -#endif - return(null); -} -#ifndef USE_GENERIC_BLITTER -#include "include/blit_c.h" -#endif -////////////////////////////////////////////////////////////////////////////// -// Execute the cached blitter code for the current blitter operation -////////////////////////////////////////////////////////////////////////////// -// -// -// -////////////////////////////////////////////////////////////////////////////// -uint32 blitter_execute_cached_code(struct s_blitter_cache *blitter) +if (specialLog) { - if ((blitter==null)||(blitter->ready==0)) - return 0; - - blitter_fn *fn=(blitter_fn*)blitter->code; - blitter->used=1; - (*fn)(); - - return(1); -} -////////////////////////////////////////////////////////////////////////////// -// -////////////////////////////////////////////////////////////////////////////// -// -// -// -////////////////////////////////////////////////////////////////////////////// -void blitter_add(uint32 hashcode, uint8 *code) -{ - struct s_blitter_cache *blitter_list=blitter_cache[(hashcode>>24)]; - -// fprintf(log_get(),"adding blitter for hashcode 0x%.8x\n",hashcode); - - while (blitter_list->next) - { - blitter_list=blitter_list->next; - - if (blitter_list->hashcode==hashcode) - return; - } - blitter_list->next=(struct s_blitter_cache *)malloc(sizeof(struct s_blitter_cache)); - blitter_list->next->prev=blitter_list; - blitter_list->next->next=null; - blitter_list=blitter_list->next; - - blitter_list->code=code; - blitter_list->hashcode=hashcode; - blitter_list->ready=1; - blitter_list->used=0; + WriteLog(" A1_X/Y = %08X/%08X, A2_X/Y = %08X/%08X\n", a1_x, a1_y, a2_x, a2_y); } -////////////////////////////////////////////////////////////////////////////// -// -////////////////////////////////////////////////////////////////////////////// -// -// -// -////////////////////////////////////////////////////////////////////////////// -void blitter_list(void) -{ -/* - fprintf(log_get(),"Used blitters list:\n"); - - for (int i=0;i<256;i++) - { - struct s_blitter_cache *blitter_list=blitter_cache[i]; - - while (blitter_list->next) - { - blitter_list=blitter_list->next; - if (blitter_list->used) - fprintf(log_get(),"\t0%.8x\n",blitter_list->hashcode); - } - } -*/ -} -////////////////////////////////////////////////////////////////////////////// -// -////////////////////////////////////////////////////////////////////////////// -// -// -// -////////////////////////////////////////////////////////////////////////////// -void blitter_generic(uint32 cmd) -{ - uint32 srcdata = 0; - uint32 srczdata = 0; - uint32 dstdata = 0; - uint32 dstzdata = 0; - uint32 writedata = 0; - uint32 inhibit = 0; - while (outer_loop--) - { - inner_loop=n_pixels; + inner_loop = n_pixels; while (inner_loop--) { - srcdata = 0; - srczdata = 0; - dstdata = 0; - dstzdata = 0; - writedata = 0; - inhibit = 0; +if (specialLog) +{ + WriteLog(" A1_X/Y = %08X/%08X, A2_X/Y = %08X/%08X\n", a1_x, a1_y, a2_x, a2_y); +} + srcdata = srczdata = dstdata = dstzdata = writedata = inhibit = 0; if (!DSTA2) { @@ -747,22 +356,15 @@ void blitter_generic(uint32 cmd) { srcdata = READ_PIXEL(a2, REG(A2_FLAGS)); if (SRCENZ) - { srczdata = READ_ZDATA(a2, REG(A2_FLAGS)); - } - else - if (cmd & 0x001c020) - { + else if (cmd & 0x0001C020) srczdata = READ_RDATA(SRCZINT, a2, REG(A2_FLAGS), a2_phrase_mode); - } } else { srcdata = READ_RDATA(SRCDATA, a2, REG(A2_FLAGS), a2_phrase_mode); - if (cmd & 0x001c020) - { + if (cmd & 0x0001C020) srczdata = READ_RDATA(SRCZINT, a2, REG(A2_FLAGS), a2_phrase_mode); - } } // load dst data and Z @@ -770,38 +372,27 @@ void blitter_generic(uint32 cmd) { dstdata = READ_PIXEL(a1, REG(A1_FLAGS)); if (DSTENZ) - { dstzdata = READ_ZDATA(a1, REG(A1_FLAGS)); - } else - { dstzdata = READ_RDATA(DSTZ, a1, REG(A1_FLAGS), a1_phrase_mode); - } } else { dstdata = READ_RDATA(DSTDATA, a1, REG(A1_FLAGS), a1_phrase_mode); - if (DSTENZ) - { dstzdata = READ_RDATA(DSTZ, a1, REG(A1_FLAGS), a1_phrase_mode); - } } - // a1 clipping +/*This wasn't working... // a1 clipping if (cmd & 0x00000040) { - if ( - a1_x < 0 || - a1_y < 0 || - (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) || - (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff) - ) + if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7FFF) + || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7FFF)) inhibit = 1; - } + }//*/ - if(GOURZ) - srczdata=z_i[colour_index]>>16; + if (GOURZ) + srczdata = z_i[colour_index] >> 16; // apply z comparator if (Z_OP_INF) if (srczdata < dstzdata) inhibit = 1; @@ -809,43 +400,77 @@ void blitter_generic(uint32 cmd) if (Z_OP_SUP) if (srczdata > dstzdata) inhibit = 1; // apply data comparator - if (DCOMPEN|BCOMPEN) +// Note: DCOMPEN only works in 8/16 bpp modes! !!! FIX !!! +// Does BCOMPEN only work in 1 bpp mode??? + if (DCOMPEN | BCOMPEN) { if (!CMPDST) { +//WriteLog("Blitter: BCOMPEN set on command %08X inhibit prev:%u, now:", cmd, inhibit); // compare source pixel with pattern pixel - if (srcdata == READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode)) - inhibit=1; +/* +Blit! (000B8250 <- 0012C3A0) count: 16 x 1, A1/2_FLAGS: 00014420/00012000 [cmd: 05810001] + CMD -> src: SRCEN dst: misc: a1ctl: mode: ity: PATDSEL z-op: op: LFU_REPLACE ctrl: BCOMPEN + A1 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 384 (22), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD + A2 -> pitch: 1 phrases, depth: 1bpp, z-off: 0, width: 16 (10), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD + x/y: 0/20 +... +*/ +// AvP is still wrong, could be cuz it's doing A1 -> A2... + +// Src is the 1bpp bitmap... DST is the PATTERN!!! +// This seems to solve at least ONE of the problems with MC3D... +// Why should this be inverted??? +// Bcuz it is. This is supposed to be used only for a bit -> pixel expansion... +/* if (srcdata == READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode)) +// if (srcdata != READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode)) + inhibit = 1;//*/ +/* uint32 A2bpp = 1 << ((REG(A2_FLAGS) >> 3) & 0x07); + if (A2bpp == 1 || A2bpp == 16 || A2bpp == 8) + inhibit = (srcdata == 0 ? 1: 0); +// inhibit = !srcdata; + else + WriteLog("Blitter: Bad BPP (%u) selected for BCOMPEN mode!\n", A2bpp);//*/ +// What it boils down to is this: + if (srcdata == 0) + inhibit = 1;//*/ } else { // compare destination pixel with pattern pixel if (dstdata == READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode)) - inhibit=1; +// if (dstdata != READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode)) + inhibit = 1; } - if (a1_phrase_mode||a2_phrase_mode) - inhibit=!inhibit; +// This is DEFINITELY WRONG + if (a1_phrase_mode || a2_phrase_mode) + inhibit = !inhibit; } - + + if (CLIPA1) + { + inhibit |= (((a1_x >> 16) < a1_clip_x && (a1_x >> 16) >= 0 + && (a1_y >> 16) < a1_clip_y && (a1_y >> 16) >= 0) ? 0 : 1); + } + // compute the write data and store if (!inhibit) { if (PATDSEL) { // use pattern data for write data - writedata= READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode); + writedata = READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode); } - else - if (INTADD) + else if (INTADD) { // intensity addition - writedata = (srcdata & 0xff) + (dstdata & 0xff); - if (!(TOPBEN) && writedata > 0xff) - writedata = 0xff; - writedata |= (srcdata & 0xf00) + (dstdata & 0xf00); - if (!(TOPNEN) && writedata > 0xfff) - writedata = 0xfff; - writedata |= (srcdata & 0xf000) + (dstdata & 0xf000); + writedata = (srcdata & 0xFF) + (dstdata & 0xFF); + if (!(TOPBEN) && writedata > 0xFF) + writedata = 0xFF; + writedata |= (srcdata & 0xF00) + (dstdata & 0xF00); + if (!(TOPNEN) && writedata > 0xFFF) + writedata = 0xFFF; + writedata |= (srcdata & 0xF000) + (dstdata & 0xF000); } else { @@ -854,58 +479,61 @@ void blitter_generic(uint32 cmd) if (LFU_AN) writedata |= srcdata & ~dstdata; if (LFU_A) writedata |= srcdata & dstdata; } - if(GOURD) - writedata = ((gd_c[colour_index])<<8)|(gd_i[colour_index]>>16); - if(SRCSHADE) + if (GOURD) + writedata = ((gd_c[colour_index]) << 8) | (gd_i[colour_index] >> 16); + + if (SRCSHADE) { int intensity = srcdata & 0xFF; int ia = gd_ia >> 16; - if(ia & 0x80) + if (ia & 0x80) ia = 0xFFFFFF00 | ia; intensity += ia; - if(intensity < 0) + if (intensity < 0) intensity = 0; - if(intensity > 0xFF) + if (intensity > 0xFF) intensity = 0xFF; writedata = (srcdata & 0xFF00) | intensity; } } else { - writedata=dstdata; - srczdata=dstzdata; + writedata = dstdata; + srczdata = dstzdata; } + if (/*a1_phrase_mode || */BKGWREN || !inhibit) { +/*if (((REG(A1_FLAGS) >> 3) & 0x07) == 5) +{ + uint32 offset = a1_addr+(PIXEL_OFFSET_32(a1)<<2); +// (((((UINT32)a##_y >> 16) * a##_width) + (((UINT32)a##_x >> 16) & ~1)) * (1 + a##_pitch) + (((UINT32)a##_x >> 16) & 1)) + if ((offset >= 0x1FF020 && offset <= 0x1FF03F) || (offset >= 0x1FF820 && offset <= 0x1FF83F)) + WriteLog("32bpp pixel write: A1 Phrase mode --> "); +}//*/ // write to the destination WRITE_PIXEL(a1, REG(A1_FLAGS), writedata); - if (DSTWRZ) WRITE_ZDATA(a1, REG(A1_FLAGS), srczdata); + if (DSTWRZ) + WRITE_ZDATA(a1, REG(A1_FLAGS), srczdata); } } - else + else // if (DSTA2) { // load src data and Z if (SRCEN) { srcdata = READ_PIXEL(a1, REG(A1_FLAGS)); if (SRCENZ) - { srczdata = READ_ZDATA(a1, REG(A1_FLAGS)); - } - else - if (cmd & 0x001c020) - { + else if (cmd & 0x0001C020) srczdata = READ_RDATA(SRCZINT, a1, REG(A1_FLAGS), a1_phrase_mode); - } } else { srcdata = READ_RDATA(SRCDATA, a1, REG(A1_FLAGS), a1_phrase_mode); - if (cmd & 0x001c020) - { + if (cmd & 0x001C020) srczdata = READ_RDATA(SRCZINT, a1, REG(A1_FLAGS), a1_phrase_mode); - } } // load dst data and Z @@ -913,26 +541,19 @@ void blitter_generic(uint32 cmd) { dstdata = READ_PIXEL(a2, REG(A2_FLAGS)); if (DSTENZ) - { dstzdata = READ_ZDATA(a2, REG(A2_FLAGS)); - } else - { dstzdata = READ_RDATA(DSTZ, a2, REG(A2_FLAGS), a2_phrase_mode); - } } else { dstdata = READ_RDATA(DSTDATA, a2, REG(A2_FLAGS), a2_phrase_mode); - if (DSTENZ) - { dstzdata = READ_RDATA(DSTZ, a2, REG(A2_FLAGS), a2_phrase_mode); - } } - if(GOURZ) - srczdata=z_i[colour_index]>>16; + if (GOURZ) + srczdata = z_i[colour_index] >> 16; // apply z comparator if (Z_OP_INF) if (srczdata < dstzdata) inhibit = 1; @@ -940,24 +561,48 @@ void blitter_generic(uint32 cmd) if (Z_OP_SUP) if (srczdata > dstzdata) inhibit = 1; // apply data comparator - if (DCOMPEN|BCOMPEN) +//NOTE: The bit comparator (BCOMPEN) is NOT the same at the data comparator! + if (DCOMPEN | BCOMPEN) { if (!CMPDST) { // compare source pixel with pattern pixel - if (srcdata == READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode)) - inhibit=1; +// AvP: Numbers are correct, but sprites are not! +//This doesn't seem to be a problem... But could still be wrong... +/* if (srcdata == READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode)) +// if (srcdata != READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode)) + inhibit = 1;//*/ +// This is probably not 100% correct... It works in the 1bpp case +// (in A1 <- A2 mode, that is...) +// AvP: This is causing blocks to be written instead of bit patterns... +// Works now... +// NOTE: We really should separate out the BCOMPEN & DCOMPEN stuff! +/* uint32 A1bpp = 1 << ((REG(A1_FLAGS) >> 3) & 0x07); + if (A1bpp == 1 || A1bpp == 16 || A1bpp == 8) + inhibit = (srcdata == 0 ? 1: 0); + else + WriteLog("Blitter: Bad BPP (%u) selected for BCOMPEN mode!\n", A1bpp);//*/ +// What it boils down to is this: + if (srcdata == 0) + inhibit = 1;//*/ } else { // compare destination pixel with pattern pixel if (dstdata == READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode)) - inhibit=1; +// if (dstdata != READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode)) + inhibit = 1; } - if (a1_phrase_mode||a2_phrase_mode) - inhibit=!inhibit; + if (a1_phrase_mode || a2_phrase_mode) + inhibit =! inhibit; } + if (CLIPA1) + { + inhibit |= (((a1_x >> 16) < a1_clip_x && (a1_x >> 16) >= 0 + && (a1_y >> 16) < a1_clip_y && (a1_y >> 16) >= 0) ? 0 : 1); + } + // compute the write data and store if (!inhibit) { @@ -966,17 +611,16 @@ void blitter_generic(uint32 cmd) // use pattern data for write data writedata= READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode); } - else - if (INTADD) + else if (INTADD) { // intensity addition - writedata = (srcdata & 0xff) + (dstdata & 0xff); - if (!(TOPBEN) && writedata > 0xff) - writedata = 0xff; - writedata |= (srcdata & 0xf00) + (dstdata & 0xf00); - if (!(TOPNEN) && writedata > 0xfff) - writedata = 0xfff; - writedata |= (srcdata & 0xf000) + (dstdata & 0xf000); + writedata = (srcdata & 0xFF) + (dstdata & 0xFF); + if (!(TOPBEN) && writedata > 0xFF) + writedata = 0xFF; + writedata |= (srcdata & 0xF00) + (dstdata & 0xF00); + if (!(TOPNEN) && writedata > 0xFFF) + writedata = 0xFFF; + writedata |= (srcdata & 0xF000) + (dstdata & 0xF000); } else { @@ -989,37 +633,45 @@ void blitter_generic(uint32 cmd) if (LFU_A) writedata |= srcdata & dstdata; } - if(GOURD) - writedata = ((gd_c[colour_index])<<8)|(gd_i[colour_index]>>16); - if(SRCSHADE) + if (GOURD) + writedata = ((gd_c[colour_index]) << 8) | (gd_i[colour_index] >> 16); + + if (SRCSHADE) { int intensity = srcdata & 0xFF; int ia = gd_ia >> 16; - if(ia & 0x80) + if (ia & 0x80) ia = 0xFFFFFF00 | ia; intensity += ia; - if(intensity < 0) + if (intensity < 0) intensity = 0; - if(intensity > 0xFF) + if (intensity > 0xFF) intensity = 0xFF; writedata = (srcdata & 0xFF00) | intensity; } } else { - writedata=dstdata; - srczdata=dstzdata; + writedata = dstdata; + srczdata = dstzdata; } if (/*a2_phrase_mode || */BKGWREN || !inhibit) { +/*if (logGo) +{ + uint32 offset = a2_addr+(PIXEL_OFFSET_16(a2)<<1); +// (((((UINT32)a##_y >> 16) * a##_width) + (((UINT32)a##_x >> 16) & ~1)) * (1 + a##_pitch) + (((UINT32)a##_x >> 16) & 1)) + WriteLog("[%08X:%04X] ", offset, writedata); +}//*/ // write to the destination WRITE_PIXEL(a2, REG(A2_FLAGS), writedata); if (DSTWRZ) WRITE_ZDATA(a2, REG(A2_FLAGS), srczdata); } } + // update x and y a1_x += a1_xadd; a1_y += a1_yadd; @@ -1027,24 +679,24 @@ void blitter_generic(uint32 cmd) a2_y = (a2_y + a2_yadd) & a2_mask_y; if (GOURZ) - z_i[colour_index]+=zadd; + z_i[colour_index] += zadd; - if ((GOURD)||(SRCSHADE)) + if (GOURD || SRCSHADE) { gd_i[colour_index] += gd_ia; gd_c[colour_index] += gd_ca; } - if ((GOURD)||(SRCSHADE)||(GOURZ)) + if (GOURD || SRCSHADE || GOURZ) { - if(a1_phrase_mode) - colour_index=(colour_index+1)&0x3; + if (a1_phrase_mode) + colour_index = (colour_index + 1) & 0x03; } } - a1_x+=a1_step_x; - a1_y+=a1_step_y; - a2_x+=a2_step_x; - a2_y+=a2_step_y; + a1_x += a1_step_x; + a1_y += a1_step_y; + a2_x += a2_step_x; + a2_y += a2_step_y; /* if (a2_phrase_mode) { @@ -1058,19 +710,15 @@ void blitter_generic(uint32 cmd) */ } // write values back to registers - WREG(A1_PIXEL, (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff)); - WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff)); - WREG(A2_PIXEL, (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff)); + WREG(A1_PIXEL, (a1_y & 0xFFFF0000) | ((a1_x >> 16) & 0xFFFF)); + WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xFFFF)); + WREG(A2_PIXEL, (a2_y & 0xFFFF0000) | ((a2_x >> 16) & 0xFFFF)); +specialLog = false; } -////////////////////////////////////////////////////////////////////////////// -// -////////////////////////////////////////////////////////////////////////////// -// -// -// -////////////////////////////////////////////////////////////////////////////// + void blitter_blit(uint32 cmd) { + uint32 pitchValue[4] = { 0, 1, 3, 2 }; colour_index = 0; src = cmd & 0x07; dst = (cmd >> 3) & 0x07; @@ -1082,44 +730,62 @@ void blitter_blit(uint32 cmd) op = (cmd >> 21) & 0x0F; ctrl = (cmd >> 25) & 0x3F; - a1_addr = REG(A1_BASE); - a2_addr = REG(A2_BASE); + // Addresses in A1/2_BASE are *phrase* aligned, i.e., bottom three bits are ignored! + // NOTE: This fixes Rayman's bad collision detection AND keeps T2K working! + a1_addr = REG(A1_BASE) & 0xFFFFFFF8; + a2_addr = REG(A2_BASE) & 0xFFFFFFF8; a1_zoffs = (REG(A1_FLAGS) >> 6) & 7; a2_zoffs = (REG(A2_FLAGS) >> 6) & 7; xadd_a1_control = (REG(A1_FLAGS) >> 16) & 0x03; xadd_a2_control = (REG(A2_FLAGS) >> 16) & 0x03; - a1_pitch = (REG(A1_FLAGS) & 3) ^ ((REG(A1_FLAGS) & 2) >> 1); - a2_pitch = (REG(A2_FLAGS) & 3) ^ ((REG(A2_FLAGS) & 2) >> 1); +// a1_pitch = (REG(A1_FLAGS) & 3) ^ ((REG(A1_FLAGS) & 2) >> 1); +// a2_pitch = (REG(A2_FLAGS) & 3) ^ ((REG(A2_FLAGS) & 2) >> 1); + a1_pitch = pitchValue[(REG(A1_FLAGS) & 0x03)]; + a2_pitch = pitchValue[(REG(A2_FLAGS) & 0x03)]; n_pixels = REG(PIXLINECOUNTER) & 0xFFFF; n_lines = (REG(PIXLINECOUNTER) >> 16) & 0xFFFF; a1_x = (REG(A1_PIXEL) << 16) | (REG(A1_FPIXEL) & 0xFFFF); a1_y = (REG(A1_PIXEL) & 0xFFFF0000) | (REG(A1_FPIXEL) >> 16); - a1_width = blitter_scanline_width[((REG(A1_FLAGS) & 0x00007E00) >> 9)]; +//According to the JTRM, X is restricted to 15 bits and Y is restricted to 12. +//But it seems to fuck up T2K! !!! FIX !!! +//Could it be sign extended??? Doesn't seem to be so according to JTRM +// a1_x &= 0x7FFFFFFF, a1_y &= 0x0FFFFFFF; + +// a1_width = blitter_scanline_width[((REG(A1_FLAGS) & 0x00007E00) >> 9)]; +// According to JTRM, this must give a *whole number* of phrases in the current +// pixel size (this means the lookup above is WRONG)... !!! FIX !!! + UINT32 m = (REG(A1_FLAGS) >> 9) & 0x03, e = (REG(A1_FLAGS) >> 11) & 0x0F; + a1_width = ((0x04 | m) << e) >> 2;//*/ a2_x = (REG(A2_PIXEL) & 0x0000FFFF) << 16; a2_y = (REG(A2_PIXEL) & 0xFFFF0000); - a2_width = blitter_scanline_width[((REG(A2_FLAGS) & 0x00007E00) >> 9)]; - a2_mask_x = 0xFFFF | ((REG(A2_MASK) & 0x0000FFFF) << 16); - a2_mask_y = ((REG(A2_MASK) & 0xFFFF0000) | 0xFFFF); - - // +//According to the JTRM, X is restricted to 15 bits and Y is restricted to 12. +//But it seems to fuck up T2K! !!! FIX !!! +// a2_x &= 0x7FFFFFFF, a2_y &= 0x0FFFFFFF; + +// a2_width = blitter_scanline_width[((REG(A2_FLAGS) & 0x00007E00) >> 9)]; +// According to JTRM, this must give a *whole number* of phrases in the current +// pixel size (this means the lookup above is WRONG)... !!! FIX !!! + m = (REG(A2_FLAGS) >> 9) & 0x03, e = (REG(A2_FLAGS) >> 11) & 0x0F; + a2_width = ((0x04 | m) << e) >> 2;//*/ + a2_mask_x = ((REG(A2_MASK) & 0x0000FFFF) << 16) | 0xFFFF; + a2_mask_y = (REG(A2_MASK) & 0xFFFF0000) | 0xFFFF; + + // Check for "use mask" flag if (!(REG(A2_FLAGS) & 0x8000)) { a2_mask_x = 0xFFFFFFFF; // must be 16.16 a2_mask_y = 0xFFFFFFFF; // must be 16.16 } - + a1_phrase_mode = 0; - // determine a1_yadd - if (YADD1_A1) - a1_yadd = 1 << 16; - else - a1_yadd = 0; + // According to the official documentation, a hardware bug ties A2's yadd bit to A1's... + a2_yadd = a1_yadd = (YADD1_A1 ? 1 << 16 : 0); if (YSIGNSUB_A1) a1_yadd = -a1_yadd; @@ -1128,6 +794,7 @@ void blitter_blit(uint32 cmd) switch (xadd_a1_control) { case XADDPHR: +// This is a documented Jaguar bug relating to phrase mode and truncation... Look into it! // add phrase offset to X and truncate a1_xadd = 1 << 16; a1_phrase_mode = 1; @@ -1149,12 +816,6 @@ void blitter_blit(uint32 cmd) if (XSIGNSUB_A1) a1_xadd = -a1_xadd; - // determine a2_yadd - if (YADD1_A2 || YADD1_A1) - a2_yadd = 1 << 16; - else - a2_yadd = 0; - if (YSIGNSUB_A2) a2_yadd = -a2_yadd; @@ -1176,74 +837,82 @@ void blitter_blit(uint32 cmd) // add zero (for those nice vertical lines) a2_xadd = 0; break; +//This really isn't a valid bit combo for A2... Shouldn't this cause the blitter to just say no? case XADDINC: +WriteLog("BLIT: Asked to used invalid bit combo for A2...\n"); // add the contents of the increment register // since there is no register for a2 we just add 1 - a2_xadd = 1 << 16; +//Let's do nothing, since it's not listed as a valid bit combo... +// a2_xadd = 1 << 16; break; } if (XSIGNSUB_A2) a2_xadd = -a2_xadd; - // modify outer loop steps based on command + // Modify outer loop steps based on blitter command + a1_step_x = 0; a1_step_y = 0; a2_step_x = 0; a2_step_y = 0; - if (cmd & 0x00000100) - { - a1_step_x = (REG(A1_FSTEP)&0xffff); - a1_step_y = (REG(A1_FSTEP)>>16); - } - if (cmd & 0x00000200) - { - a1_step_x += ((REG(A1_STEP)&0x0000ffff)<<16); - a1_step_y += ((REG(A1_STEP)&0xffff0000)); - } - if (cmd & 0x00000400) - { - a2_step_x = (REG(A2_STEP)&0x0000ffff)<<16; - a2_step_y = (REG(A2_STEP)&0xffff0000); - } + if (UPDA1F) + a1_step_x = (REG(A1_FSTEP) & 0xFFFF), + a1_step_y = (REG(A1_FSTEP) >> 16); + + if (UPDA1) + a1_step_x |= ((REG(A1_STEP) & 0x0000FFFF) << 16), + a1_step_y |= ((REG(A1_STEP) & 0xFFFF0000)); + + if (UPDA2) + a2_step_x = (REG(A2_STEP) & 0x0000FFFF) << 16, + a2_step_y = (REG(A2_STEP) & 0xFFFF0000); outer_loop = n_lines; - a2_psize = 1 << ((REG(A2_FLAGS) >> 3) & 7); - a1_psize = 1 << ((REG(A1_FLAGS) >> 3) & 7); + // Clipping... + + if (CLIPA1) + a1_clip_x = REG(A1_CLIP) & 0x7FFF, + a1_clip_y = (REG(A1_CLIP) >> 16) & 0x7FFF; + +// This phrase sizing is incorrect as well... !!! FIX !!! +// Err, this is pixel size... (and it's OK) + a2_psize = 1 << ((REG(A2_FLAGS) >> 3) & 0x07); + a1_psize = 1 << ((REG(A1_FLAGS) >> 3) & 0x07); // zbuffering if (GOURZ) { - zadd = jaguar_long_read(0xF02274); + zadd = JaguarReadLong(0xF02274, BLITTER); for(int v=0; v<4; v++) - z_i[v] = (int32)jaguar_long_read(0xF0228C + (v << 2)); + z_i[v] = (int32)JaguarReadLong(0xF0228C + (v << 2), BLITTER); } if (GOURD || GOURZ || SRCSHADE) { // gouraud shading - gouraud_add = jaguar_long_read(0xF02270); + gouraud_add = JaguarReadLong(0xF02270, BLITTER); - gd_c[0] = jaguar_byte_read(0xF02268); - gd_i[0] = jaguar_byte_read(0xF02269); + gd_c[0] = JaguarReadByte(0xF02268, BLITTER); + gd_i[0] = JaguarReadByte(0xF02269, BLITTER); gd_i[0] <<= 16; - gd_i[0] |= jaguar_word_read(0xF02240); + gd_i[0] |= JaguarReadWord(0xF02240, BLITTER); - gd_c[1] = jaguar_byte_read(0xF0226A); - gd_i[1] = jaguar_byte_read(0xF0226B); + gd_c[1] = JaguarReadByte(0xF0226A, BLITTER); + gd_i[1] = JaguarReadByte(0xF0226B, BLITTER); gd_i[1] <<= 16; - gd_i[1] |= jaguar_word_read(0xF02242); + gd_i[1] |= JaguarReadWord(0xF02242, BLITTER); - gd_c[2] = jaguar_byte_read(0xF0226C); - gd_i[2] = jaguar_byte_read(0xF0226D); + gd_c[2] = JaguarReadByte(0xF0226C, BLITTER); + gd_i[2] = JaguarReadByte(0xF0226D, BLITTER); gd_i[2] <<= 16; - gd_i[2] |= jaguar_word_read(0xF02244); + gd_i[2] |= JaguarReadWord(0xF02244, BLITTER); - gd_c[3] = jaguar_byte_read(0xF0226E); - gd_i[3] = jaguar_byte_read(0xF0226F); + gd_c[3] = JaguarReadByte(0xF0226E, BLITTER); + gd_i[3] = JaguarReadByte(0xF0226F, BLITTER); gd_i[3] <<= 16; - gd_i[3] |= jaguar_word_read(0xF02246); + gd_i[3] |= JaguarReadWord(0xF02246, BLITTER); gd_ia = gouraud_add & 0xFFFFFF; if (gd_ia & 0x800000) @@ -1255,17 +924,17 @@ void blitter_blit(uint32 cmd) } // fix for zoop! and syndicate - if ((jaguar_mainRom_crc32==0x501be17c)|| +/* if ((jaguar_mainRom_crc32==0x501be17c)|| (jaguar_mainRom_crc32==0x70895c51)|| (jaguar_mainRom_crc32==0x0f1f1497)|| (jaguar_mainRom_crc32==0xfc8f0dcd) ) { - if (a1_step_x<0) - a1_step_x=(-n_pixels)*65536; + if (a1_step_x < 0) + a1_step_x = (-n_pixels) * 65536; - if (a2_step_x<0) - a2_step_x=(-n_pixels)*65536;; + if (a2_step_x < 0) + a2_step_x = (-n_pixels) * 65536;; } else // fix for wolfenstein 3d @@ -1284,183 +953,212 @@ void blitter_blit(uint32 cmd) // fix for Tempest 2000 if (jaguar_mainRom_crc32==0x32816d44) { -/* + if ((n_lines!=1)&&((n_pixels==288)||(n_pixels==384))) { - fprintf(log_get(),"Blit!\n"); - fprintf(log_get()," cmd = 0x%.8x\n",cmd); - fprintf(log_get()," a1_base = %08X\n", a1_addr); - fprintf(log_get()," a1_pitch = %d\n", a1_pitch); - fprintf(log_get()," a1_psize = %d\n", a1_psize); - fprintf(log_get()," a1_width = %d\n", a1_width); - fprintf(log_get()," a1_xadd = %f (phrase=%d)\n", (float)a1_xadd / 65536.0, a1_phrase_mode); - fprintf(log_get()," a1_yadd = %f\n", (float)a1_yadd / 65536.0); - fprintf(log_get()," a1_xstep = %f\n", (float)a1_step_x / 65536.0); - fprintf(log_get()," a1_ystep = %f\n", (float)a1_step_y / 65536.0); - fprintf(log_get()," a1_x = %f\n", (float)a1_x / 65536.0); - fprintf(log_get()," a1_y = %f\n", (float)a1_y / 65536.0); - fprintf(log_get()," a1_zoffs = %i\n",a1_zoffs); - - fprintf(log_get()," a2_base = %08X\n", a2_addr); - fprintf(log_get()," a2_pitch = %d\n", a2_pitch); - fprintf(log_get()," a2_psize = %d\n", a2_psize); - fprintf(log_get()," a2_width = %d\n", a2_width); - fprintf(log_get()," a2_xadd = %f (phrase=%d)\n", (float)a2_xadd / 65536.0, a2_phrase_mode); - fprintf(log_get()," a2_yadd = %f\n", (float)a2_yadd / 65536.0); - fprintf(log_get()," a2_xstep = %f\n", (float)a2_step_x / 65536.0); - fprintf(log_get()," a2_ystep = %f\n", (float)a2_step_y / 65536.0); - fprintf(log_get()," a2_x = %f\n", (float)a2_x / 65536.0); - fprintf(log_get()," a2_y = %f\n", (float)a2_y / 65536.0); - fprintf(log_get()," a2_mask_x= 0x%.4x\n",a2_mask_x); - fprintf(log_get()," a2_mask_y= 0x%.4x\n",a2_mask_y); - fprintf(log_get()," a2_zoffs = %i\n",a2_zoffs); - - fprintf(log_get()," count = %d x %d\n", n_pixels, n_lines); - - fprintf(log_get()," command = %08X\n", cmd); - fprintf(log_get()," dsten = %i\n",DSTEN); - fprintf(log_get()," srcen = %i\n",SRCEN); - fprintf(log_get()," patdsel = %i\n",PATDSEL); - fprintf(log_get()," color = 0x%.8x\n",REG(PATTERNDATA)); - fprintf(log_get()," dcompen = %i\n",DCOMPEN); - fprintf(log_get()," bcompen = %i\n",BCOMPEN); - fprintf(log_get()," cmpdst = %i\n",CMPDST); - fprintf(log_get()," GOURZ = %i\n",GOURZ); - fprintf(log_get()," GOURD = %i\n",GOURD); - fprintf(log_get()," SRCSHADE = %i\n",SRCSHADE); - fprintf(log_get()," DSTDATA = 0x%.8x%.8x\n",REG(DSTDATA),REG(DSTDATA+4)); + WriteLog("Blit!\n"); + WriteLog(" cmd = 0x%.8x\n",cmd); + WriteLog(" a1_base = %08X\n", a1_addr); + WriteLog(" a1_pitch = %d\n", a1_pitch); + WriteLog(" a1_psize = %d\n", a1_psize); + WriteLog(" a1_width = %d\n", a1_width); + WriteLog(" a1_xadd = %f (phrase=%d)\n", (float)a1_xadd / 65536.0, a1_phrase_mode); + WriteLog(" a1_yadd = %f\n", (float)a1_yadd / 65536.0); + WriteLog(" a1_xstep = %f\n", (float)a1_step_x / 65536.0); + WriteLog(" a1_ystep = %f\n", (float)a1_step_y / 65536.0); + WriteLog(" a1_x = %f\n", (float)a1_x / 65536.0); + WriteLog(" a1_y = %f\n", (float)a1_y / 65536.0); + WriteLog(" a1_zoffs = %i\n",a1_zoffs); + + WriteLog(" a2_base = %08X\n", a2_addr); + WriteLog(" a2_pitch = %d\n", a2_pitch); + WriteLog(" a2_psize = %d\n", a2_psize); + WriteLog(" a2_width = %d\n", a2_width); + WriteLog(" a2_xadd = %f (phrase=%d)\n", (float)a2_xadd / 65536.0, a2_phrase_mode); + WriteLog(" a2_yadd = %f\n", (float)a2_yadd / 65536.0); + WriteLog(" a2_xstep = %f\n", (float)a2_step_x / 65536.0); + WriteLog(" a2_ystep = %f\n", (float)a2_step_y / 65536.0); + WriteLog(" a2_x = %f\n", (float)a2_x / 65536.0); + WriteLog(" a2_y = %f\n", (float)a2_y / 65536.0); + WriteLog(" a2_mask_x= 0x%.4x\n",a2_mask_x); + WriteLog(" a2_mask_y= 0x%.4x\n",a2_mask_y); + WriteLog(" a2_zoffs = %i\n",a2_zoffs); + + WriteLog(" count = %d x %d\n", n_pixels, n_lines); + + WriteLog(" command = %08X\n", cmd); + WriteLog(" dsten = %i\n",DSTEN); + WriteLog(" srcen = %i\n",SRCEN); + WriteLog(" patdsel = %i\n",PATDSEL); + WriteLog(" color = 0x%.8x\n",REG(PATTERNDATA)); + WriteLog(" dcompen = %i\n",DCOMPEN); + WriteLog(" bcompen = %i\n",BCOMPEN); + WriteLog(" cmpdst = %i\n",CMPDST); + WriteLog(" GOURZ = %i\n",GOURZ); + WriteLog(" GOURD = %i\n",GOURD); + WriteLog(" SRCSHADE = %i\n",SRCSHADE); + WriteLog(" DSTDATA = 0x%.8x%.8x\n",REG(DSTDATA),REG(DSTDATA+4)); } -*/ } + }//*/ #ifdef LOG_BLITS -// if (start_logging) + if (start_logging) { - fprintf(log_get(),"Blit!\n"); - fprintf(log_get()," cmd = 0x%.8x\n",cmd); - fprintf(log_get()," a1_base = %08X\n", a1_addr); - fprintf(log_get()," a1_pitch = %d\n", a1_pitch); - fprintf(log_get()," a1_psize = %d\n", a1_psize); - fprintf(log_get()," a1_width = %d\n", a1_width); - fprintf(log_get()," a1_xadd = %f (phrase=%d)\n", (float)a1_xadd / 65536.0, a1_phrase_mode); - fprintf(log_get()," a1_yadd = %f\n", (float)a1_yadd / 65536.0); - fprintf(log_get()," a1_xstep = %f\n", (float)a1_step_x / 65536.0); - fprintf(log_get()," a1_ystep = %f\n", (float)a1_step_y / 65536.0); - fprintf(log_get()," a1_x = %f\n", (float)a1_x / 65536.0); - fprintf(log_get()," a1_y = %f\n", (float)a1_y / 65536.0); - fprintf(log_get()," a1_zoffs = %i\n",a1_zoffs); - - fprintf(log_get()," a2_base = %08X\n", a2_addr); - fprintf(log_get()," a2_pitch = %d\n", a2_pitch); - fprintf(log_get()," a2_psize = %d\n", a2_psize); - fprintf(log_get()," a2_width = %d\n", a2_width); - fprintf(log_get()," a2_xadd = %f (phrase=%d)\n", (float)a2_xadd / 65536.0, a2_phrase_mode); - fprintf(log_get()," a2_yadd = %f\n", (float)a2_yadd / 65536.0); - fprintf(log_get()," a2_xstep = %f\n", (float)a2_step_x / 65536.0); - fprintf(log_get()," a2_ystep = %f\n", (float)a2_step_y / 65536.0); - fprintf(log_get()," a2_x = %f\n", (float)a2_x / 65536.0); - fprintf(log_get()," a2_y = %f\n", (float)a2_y / 65536.0); - fprintf(log_get()," a2_mask_x= 0x%.4x\n",a2_mask_x); - fprintf(log_get()," a2_mask_y= 0x%.4x\n",a2_mask_y); - fprintf(log_get()," a2_zoffs = %i\n",a2_zoffs); - - fprintf(log_get()," count = %d x %d\n", n_pixels, n_lines); - - fprintf(log_get()," command = %08X\n", cmd); - fprintf(log_get()," dsten = %i\n",DSTEN); - fprintf(log_get()," srcen = %i\n",SRCEN); - fprintf(log_get()," patdsel = %i\n",PATDSEL); - fprintf(log_get()," color = 0x%.8x\n",REG(PATTERNDATA)); - fprintf(log_get()," dcompen = %i\n",DCOMPEN); - fprintf(log_get()," bcompen = %i\n",BCOMPEN); - fprintf(log_get()," cmpdst = %i\n",CMPDST); - fprintf(log_get()," GOURZ = %i\n",GOURZ); - fprintf(log_get()," GOURD = %i\n",GOURD); - fprintf(log_get()," SRCSHADE= %i\n",SRCSHADE); + WriteLog("Blit!\n"); + WriteLog(" cmd = 0x%.8x\n",cmd); + WriteLog(" a1_base = %08X\n", a1_addr); + WriteLog(" a1_pitch = %d\n", a1_pitch); + WriteLog(" a1_psize = %d\n", a1_psize); + WriteLog(" a1_width = %d\n", a1_width); + WriteLog(" a1_xadd = %f (phrase=%d)\n", (float)a1_xadd / 65536.0, a1_phrase_mode); + WriteLog(" a1_yadd = %f\n", (float)a1_yadd / 65536.0); + WriteLog(" a1_xstep = %f\n", (float)a1_step_x / 65536.0); + WriteLog(" a1_ystep = %f\n", (float)a1_step_y / 65536.0); + WriteLog(" a1_x = %f\n", (float)a1_x / 65536.0); + WriteLog(" a1_y = %f\n", (float)a1_y / 65536.0); + WriteLog(" a1_zoffs = %i\n",a1_zoffs); + + WriteLog(" a2_base = %08X\n", a2_addr); + WriteLog(" a2_pitch = %d\n", a2_pitch); + WriteLog(" a2_psize = %d\n", a2_psize); + WriteLog(" a2_width = %d\n", a2_width); + WriteLog(" a2_xadd = %f (phrase=%d)\n", (float)a2_xadd / 65536.0, a2_phrase_mode); + WriteLog(" a2_yadd = %f\n", (float)a2_yadd / 65536.0); + WriteLog(" a2_xstep = %f\n", (float)a2_step_x / 65536.0); + WriteLog(" a2_ystep = %f\n", (float)a2_step_y / 65536.0); + WriteLog(" a2_x = %f\n", (float)a2_x / 65536.0); + WriteLog(" a2_y = %f\n", (float)a2_y / 65536.0); + WriteLog(" a2_mask_x= 0x%.4x\n",a2_mask_x); + WriteLog(" a2_mask_y= 0x%.4x\n",a2_mask_y); + WriteLog(" a2_zoffs = %i\n",a2_zoffs); + + WriteLog(" count = %d x %d\n", n_pixels, n_lines); + + WriteLog(" command = %08X\n", cmd); + WriteLog(" dsten = %i\n",DSTEN); + WriteLog(" srcen = %i\n",SRCEN); + WriteLog(" patdsel = %i\n",PATDSEL); + WriteLog(" color = 0x%.8x\n",REG(PATTERNDATA)); + WriteLog(" dcompen = %i\n",DCOMPEN); + WriteLog(" bcompen = %i\n",BCOMPEN); + WriteLog(" cmpdst = %i\n",CMPDST); + WriteLog(" GOURZ = %i\n",GOURZ); + WriteLog(" GOURD = %i\n",GOURD); + WriteLog(" SRCSHADE= %i\n",SRCSHADE); } #endif - blitter_working = 1; -#ifndef USE_GENERIC_BLITTER - if (!blitter_execute_cached_code(blitter_in_cache(cmd))) -#endif - blitter_generic(cmd); - blitter_working = 0; +extern int blit_start_log; +extern int op_start_log; +if (blit_start_log) +{ + char * ctrlStr[4] = { "XADDPHR\0", "XADDPIX\0", "XADD0\0", "XADDINC\0" }; + char * bppStr[8] = { "1bpp\0", "2bpp\0", "4bpp\0", "8bpp\0", "16bpp\0", "32bpp\0", "???\0", "!!!\0" }; + char * opStr[16] = { "LFU_CLEAR", "LFU_NSAND", "LFU_NSAD", "LFU_NOTS", "LFU_SAND", "LFU_NOTD", "LFU_N_SXORD", "LFU_NSORND", + "LFU_SAD", "LFU_XOR", "LFU_D", "LFU_NSORD", "LFU_REPLACE", "LFU_SORND", "LFU_SORD", "LFU_ONE" }; + uint32 src = cmd & 0x07, dst = (cmd >> 3) & 0x07, misc = (cmd >> 6) & 0x03, + a1ctl = (cmd >> 8) & 0x07, mode = (cmd >> 11) & 0x07, ity = (cmd >> 14) & 0x0F, + zop = (cmd >> 18) & 0x07, op = (cmd >> 21) & 0x0F, ctrl = (cmd >> 25) & 0x3F; + UINT32 a1f = REG(A1_FLAGS), a2f = REG(A2_FLAGS); + uint32 p1 = a1f & 0x07, p2 = a2f & 0x07, + d1 = (a1f >> 3) & 0x07, d2 = (a2f >> 3) & 0x07, + zo1 = (a1f >> 6) & 0x07, zo2 = (a2f >> 6) & 0x07, + w1 = (a1f >> 9) & 0x3F, w2 = (a2f >> 9) & 0x3F, + ac1 = (a1f >> 16) & 0x1F, ac2 = (a2f >> 16) & 0x1F; + UINT32 iw1 = ((0x04 | (w1 & 0x03)) << ((w1 & 0x3C) >> 2)) >> 2; + UINT32 iw2 = ((0x04 | (w2 & 0x03)) << ((w2 & 0x3C) >> 2)) >> 2; + WriteLog("Blit! (%08X %s %08X) count: %d x %d, A1/2_FLAGS: %08X/%08X [cmd: %08X]\n", a1_addr, (mode&0x01 ? "->" : "<-"), a2_addr, n_pixels, n_lines, a1f, a2f, cmd); +// WriteLog(" CMD -> src: %d, dst: %d, misc: %d, a1ctl: %d, mode: %d, ity: %1X, z-op: %d, op: %1X, ctrl: %02X\n", src, dst, misc, a1ctl, mode, ity, zop, op, ctrl); + + WriteLog(" CMD -> src: %s%s%s ", (cmd & 0x0001 ? "SRCEN " : ""), (cmd & 0x0002 ? "SRCENZ " : ""), (cmd & 0x0004 ? "SRCENX" : "")); + WriteLog("dst: %s%s%s ", (cmd & 0x0008 ? "DSTEN " : ""), (cmd & 0x0010 ? "DSTENZ " : ""), (cmd & 0x0020 ? "DSTWRZ" : "")); + WriteLog("misc: %s%s ", (cmd & 0x0040 ? "CLIP_A1 " : ""), (cmd & 0x0080 ? "???" : "")); + WriteLog("a1ctl: %s%s%s ", (cmd & 0x0100 ? "UPDA1F " : ""), (cmd & 0x0200 ? "UPDA1 " : ""), (cmd & 0x0400 ? "UPDA2" : "")); + WriteLog("mode: %s%s%s ", (cmd & 0x0800 ? "DSTA2 " : ""), (cmd & 0x1000 ? "GOURD " : ""), (cmd & 0x2000 ? "ZBUFF" : "")); + WriteLog("ity: %s%s%s ", (cmd & 0x4000 ? "TOPBEN " : ""), (cmd & 0x8000 ? "TOPNEN " : ""), (cmd & 0x00010000 ? "PATDSEL" : "")); + WriteLog("z-op: %s%s%s ", (cmd & 0x00040000 ? "ZMODELT " : ""), (cmd & 0x00080000 ? "ZMODEEQ " : ""), (cmd & 0x00100000 ? "ZMODEGT" : "")); + WriteLog("op: %s ", opStr[(cmd >> 21) & 0x0F]); + WriteLog("ctrl: %s%s%s%s%s%s\n", (cmd & 0x02000000 ? "CMPDST " : ""), (cmd & 0x04000000 ? "BCOMPEN " : ""), (cmd & 0x08000000 ? "DCOMPEN " : ""), (cmd & 0x10000000 ? "BKGWREN " : ""), (cmd & 0x20000000 ? "BUSHI " : ""), (cmd & 0x40000000 ? "SRCSHADE" : "")); + + if (UPDA2) + { + WriteLog(" A2 step values: %d (X), %d (Y) [mask (%sused): %08X - %08X/%08X]\n", a2_step_x >> 16, a2_step_y >> 16, (a2f & 0x8000 ? "" : "un"), REG(A2_MASK), a2_mask_x, a2_mask_y); + } + + WriteLog(" A1 -> pitch: %d phrases, depth: %s, z-off: %d, width: %d (%02X), addctl: %s %s %s %s\n", 1 << p1, bppStr[d1], zo1, iw1, w1, ctrlStr[ac1&0x03], (ac1&0x04 ? "YADD1" : "YADD0"), (ac1&0x08 ? "XSIGNSUB" : "XSIGNADD"), (ac1&0x10 ? "YSIGNSUB" : "YSIGNADD")); + WriteLog(" A2 -> pitch: %d phrases, depth: %s, z-off: %d, width: %d (%02X), addctl: %s %s %s %s\n", 1 << p2, bppStr[d2], zo2, iw2, w2, ctrlStr[ac2&0x03], (ac2&0x04 ? "YADD1" : "YADD0"), (ac2&0x08 ? "XSIGNSUB" : "XSIGNADD"), (ac2&0x10 ? "YSIGNSUB" : "YSIGNADD")); + WriteLog(" A1 x/y: %d/%d, A2 x/y: %d/%d\n", a1_x >> 16, a1_y >> 16, a2_x >> 16, a2_y >> 16); +// blit_start_log = 0; +// op_start_log = 1; } -uint32 blitter_reg_read(uint32 offset) + blitter_working = 1; +//#ifndef USE_GENERIC_BLITTER +// if (!blitter_execute_cached_code(blitter_in_cache(cmd))) +//#endif + blitter_generic(cmd); + +/*if (blit_start_log) { - uint32 data = blitter_ram[offset]; - data <<= 8; - data |= blitter_ram[offset+1]; - data <<= 8; - data |= blitter_ram[offset+2]; - data <<= 8; - data |= blitter_ram[offset+3]; - return data; + if (a1_addr == 0xF03000 && a2_addr == 0x004D58) + { + WriteLog("\nBytes at 004D58:\n"); + for(int i=0x004D58; i<0x004D58+(10*127*4); i++) + WriteLog("%02X ", JaguarReadByte(i)); + WriteLog("\nBytes at F03000:\n"); + for(int i=0xF03000; i<0xF03000+(6*127*4); i++) + WriteLog("%02X ", JaguarReadByte(i)); + WriteLog("\n\n"); + } +}//*/ + + blitter_working = 0; } -void blitter_reg_write(uint32 offset, uint32 data) +void blitter_init(void) { - blitter_ram[offset+0] = (data>>24) & 0xFF; - blitter_ram[offset+1] = (data>>16) & 0xFF; - blitter_ram[offset+2] = (data>>8) & 0xFF; - blitter_ram[offset+3] = data & 0xFF; + blitter_reset(); } -uint32 blitter_long_read(uint32 offset) +void blitter_reset(void) { - return (blitter_word_read(offset) << 16) | blitter_word_read(offset+2); + memset(blitter_ram, 0x00, 0xA0); } -void blitter_long_write(uint32 offset, uint32 data) +void blitter_done(void) { - blitter_word_write(offset, data >> 16); - blitter_word_write(offset+2, data & 0xFFFF); + WriteLog("BLIT: Done.\n"); } -void blitter_init(void) +uint8 BlitterReadByte(uint32 offset, uint32 who/*=UNKNOWN*/) { - if (!blitter_cache_init) - { - for (int i=0;i<256;i++) - { - blitter_cache[i] = (struct s_blitter_cache *)malloc(sizeof(struct s_blitter_cache)); - blitter_cache[i]->next=null; - blitter_cache[i]->prev=null; - } - blitter_cache_init = 1; - } -#ifndef USE_GENERIC_BLITTER - #include "include/blit_i.h" -#endif + offset &= 0xFF; - blitter_reset(); -#ifdef GEN_CODE - blitters_code_fp = fopen("include/blit_c.h","awrt"); - blitters_code_init_fp = fopen("include/blit_i.h","awrt"); -#endif + // status register + if (offset == (0x38 + 3)) + return 0x01; // always idle + + return blitter_ram[offset]; } -void blitter_reset(void) +uint16 BlitterReadWord(uint32 offset, uint32 who/*=UNKNOWN*/) { - memset(blitter_ram, 0x00, 0xA0); + return ((uint16)BlitterReadByte(offset, who) << 8) | (uint16)BlitterReadByte(offset+1, who); } -void blitter_done(void) +uint32 BlitterReadLong(uint32 offset, uint32 who/*=UNKNOWN*/) { -// blitter_list(); -#ifdef GEN_CODE - fclose(blitters_code_fp); - fclose(blitters_code_init_fp); -#endif - fprintf(log_get(), "BLIT: Done.\n"); + return (BlitterReadWord(offset, who) << 16) | BlitterReadWord(offset+2, who); } -void blitter_byte_write(uint32 offset, uint8 data) +void BlitterWriteByte(uint32 offset, uint8 data, uint32 who/*=UNKNOWN*/) { +/*if (offset & 0xFF == 0x7B) + WriteLog("--> Wrote to B_STOP: value -> %02X\n", data);*/ offset &= 0xFF; - if ((offset >= 0x7C) && (offset <= 0x9B)) +// if ((offset >= 0x7C) && (offset <= 0x9B)) + if ((offset >= 0x7C) && (offset <= 0x8B)) { switch (offset) { @@ -1481,45 +1179,34 @@ void blitter_byte_write(uint32 offset, uint8 data) case 0x88: break; case 0x89: blitter_ram[0x6F] = data; break; - case 0x9A: blitter_ram[0x46] = data; break; - case 0x9B: blitter_ram[0x47] = data; break; +//Mistyped? +// case 0x9A: blitter_ram[0x46] = data; break; +// case 0x9B: blitter_ram[0x47] = data; break; + case 0x8A: blitter_ram[0x46] = data; break; + case 0x8B: blitter_ram[0x47] = data; break; } } blitter_ram[offset] = data; } -void blitter_word_write(uint32 offset, uint16 data) +void BlitterWriteWord(uint32 offset, uint16 data, uint32 who/*=UNKNOWN*/) { - blitter_byte_write(offset+0, (data>>8) & 0xFF); - blitter_byte_write(offset+1, data & 0xFF); + BlitterWriteByte(offset+0, (data>>8) & 0xFF, who); + BlitterWriteByte(offset+1, data & 0xFF, who); if ((offset & 0xFF) == 0x3A) - { - uint32 cmd = blitter_ram[0x38]; - cmd <<= 8; - cmd |= blitter_ram[0x39]; - cmd <<= 8; - cmd |= blitter_ram[0x3A]; - cmd <<= 8; - cmd |= blitter_ram[0x3B]; - - blitter_blit(cmd); - } -} - -uint8 blitter_byte_read(uint32 offset) -{ - offset &= 0xFF; - - // status register - if (offset == (0x38+3)) - return 0x01; // always idle - - return blitter_ram[offset]; + // I.e., the second write of 32-bit value--not convinced this is the best way to do this! + // But then again, according to the Jaguar docs, this is correct...! + blitter_blit(GET32(blitter_ram, 0x38)); +// Testing purposes only! +//This does the clipping correctly, but not the Gouraud shading... +// blitter2_exec(GET32(blitter_ram, 0x38)); } +//F02278,9,A,B -uint16 blitter_word_read(uint32 offset) +void BlitterWriteLong(uint32 offset, uint32 data, uint32 who/*=UNKNOWN*/) { - return (blitter_byte_read(offset) << 8) | blitter_byte_read(offset+1); + BlitterWriteWord(offset, data >> 16, who); + BlitterWriteWord(offset+2, data & 0xFFFF, who); }