]> Shamusworld >> Repos - virtualjaguar/blob - src/blitter.cpp
Virtual Jaguar 1.0.4 update (Shamus)
[virtualjaguar] / src / blitter.cpp
1 //
2 // Blitter core
3 //
4 // by cal2
5 // GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Caz (BeOS)
6 // Cleanups/fixes by James L. Hammons
7 //
8
9 //#define GEN_CODE
10 //#define LOG_BLITS
11 // Generic blitter it is, until all blitter bugs are squashed!
12 #define USE_GENERIC_BLITTER
13  
14 #include "jaguar.h"
15 #include "blitter2.h"                   // Testing purposes only!
16
17 #define null 0
18 extern int jaguar_active_memory_dumps;
19
20 #define REG(A)  (((uint32)blitter_ram[(A)] << 24) | ((uint32)blitter_ram[(A)+1] << 16) \
21                                 | ((uint32)blitter_ram[(A)+2] << 8) | (uint32)blitter_ram[(A)+3])
22 #define WREG(A,D)       (blitter_ram[(A)] = ((D)>>24)&0xFF, blitter_ram[(A)+1] = ((D)>>16)&0xFF, \
23                                         blitter_ram[(A)+2] = ((D)>>8)&0xFF, blitter_ram[(A)+3] = (D)&0xFF)
24
25 int start_logging = 0;
26
27 // Blitter register RAM (most of it is hidden from the user)
28
29 static uint8 blitter_ram[0x100];
30
31 // Blitter registers (offsets from F02200)
32
33 #define A1_BASE                 ((UINT32)0x00)
34 #define A1_FLAGS                ((UINT32)0x04)
35 #define A1_CLIP                 ((UINT32)0x08)  // Height and width values for clipping
36 #define A1_PIXEL                ((UINT32)0x0C)  // Integer part of the pixel (Y.i and X.i)
37 #define A1_STEP                 ((UINT32)0x10)  // Integer part of the step
38 #define A1_FSTEP                ((UINT32)0x14)  // Fractionnal part of the step
39 #define A1_FPIXEL               ((UINT32)0x18)  // Fractionnal part of the pixel (Y.f and X.f)
40 #define A1_INC                  ((UINT32)0x1C)  // Integer part of the increment
41 #define A1_FINC                 ((UINT32)0x20)  // Fractional part of the increment
42 #define A2_BASE                 ((UINT32)0x24)
43 #define A2_FLAGS                ((UINT32)0x28)
44 #define A2_MASK                 ((UINT32)0x2C)  // Modulo values for x and y (M.y  and M.x)
45 #define A2_PIXEL                ((UINT32)0x30)  // Integer part of the pixel (no fractional part for A2)
46 #define A2_STEP                 ((UINT32)0x34)  // Integer part of the step (no fractional part for A2)
47 #define COMMAND                 ((UINT32)0x38)
48 #define PIXLINECOUNTER  ((UINT32)0x3C)
49 #define SRCDATA                 ((UINT32)0x40)
50 #define DSTDATA                 ((UINT32)0x48)
51 #define DSTZ                    ((UINT32)0x50)
52 #define SRCZINT                 ((UINT32)0x58)
53 #define SRCZFRAC                ((UINT32)0x60)
54 #define PATTERNDATA             ((UINT32)0x68)
55 #define INTENSITYINC    ((UINT32)0x70)
56 #define ZINC                    ((UINT32)0x74)
57 #define COLLISIONCTRL   ((UINT32)0x78)
58 #define PHRASEINT3              ((UINT32)0x7C)
59 #define PHRASEINT2              ((UINT32)0x80)
60 #define PHRASEINT1              ((UINT32)0x84)
61 #define PHRASEINT0              ((UINT32)0x88)
62 #define PHRASEZ3                ((UINT32)0x8C)
63 #define PHRASEZ2                ((UINT32)0x90)
64 #define PHRASEZ1                ((UINT32)0x94)
65 #define PHRASEZ0                ((UINT32)0x98)
66
67 // Blitter command bits
68
69 #define SRCEN                   (cmd & 0x00000001)
70 #define SRCENZ                  (cmd & 0x00000002)
71 #define SRCENX                  (cmd & 0x00000004)
72 #define DSTEN                   (cmd & 0x00000008)
73 #define DSTENZ                  (cmd & 0x00000010)
74 #define DSTWRZ                  (cmd & 0x00000020)
75 #define CLIPA1                  (cmd & 0x00000040)
76
77 #define UPDA1F                  (cmd & 0x00000100)
78 #define UPDA1                   (cmd & 0x00000200)
79 #define UPDA2                   (cmd & 0x00000400)
80
81 #define DSTA2                   (cmd & 0x00000800)
82
83 #define Z_OP_INF                (cmd & 0x00040000)
84 #define Z_OP_EQU                (cmd & 0x00080000)
85 #define Z_OP_SUP                (cmd & 0x00100000)
86
87 #define LFU_NAN                 (cmd & 0x00200000)
88 #define LFU_NA                  (cmd & 0x00400000)
89 #define LFU_AN                  (cmd & 0x00800000)
90 #define LFU_A                   (cmd & 0x01000000)
91
92 #define CMPDST                  (cmd & 0x02000000)
93 #define BCOMPEN                 (cmd & 0x04000000)
94 #define DCOMPEN                 (cmd & 0x08000000)
95
96 #define PATDSEL                 (cmd & 0x00010000)
97 #define INTADD                  (cmd & 0x00020000)
98 #define TOPBEN                  (cmd & 0x00004000)
99 #define TOPNEN                  (cmd & 0x00008000)
100 #define BKGWREN                 (cmd & 0x10000000)
101 #define GOURD                   (cmd & 0x00001000)
102 #define GOURZ                   (cmd & 0x00002000)
103 #define SRCSHADE                (cmd & 0x40000000)
104
105
106 #define XADDPHR  0
107 #define XADDPIX  1
108 #define XADD0    2
109 #define XADDINC  3
110
111 #define XSIGNSUB_A1             (REG(A1_FLAGS)&0x80000)
112 #define XSIGNSUB_A2             (REG(A2_FLAGS)&0x80000)
113
114 #define YSIGNSUB_A1             (REG(A1_FLAGS)&0x100000)
115 #define YSIGNSUB_A2             (REG(A2_FLAGS)&0x100000)
116
117 #define YADD1_A1                (REG(A1_FLAGS)&0x40000)
118 #define YADD1_A2                (REG(A2_FLAGS)&0x40000)
119
120 // 1 bpp pixel read
121 #define PIXEL_SHIFT_1(a)      (((~a##_x) >> 16) & 7)
122 #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))
123 #define READ_PIXEL_1(a)       ((jaguar_byte_read(a##_addr+PIXEL_OFFSET_1(a)) >> PIXEL_SHIFT_1(a)) & 0x01)
124
125 // 2 bpp pixel read
126 #define PIXEL_SHIFT_2(a)      (((~a##_x) >> 15) & 6)
127 #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))
128 #define READ_PIXEL_2(a)       ((jaguar_byte_read(a##_addr+PIXEL_OFFSET_2(a)) >> PIXEL_SHIFT_2(a)) & 0x03)
129
130 // 4 bpp pixel read
131 #define PIXEL_SHIFT_4(a)      (((~a##_x) >> 14) & 4)
132 #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))
133 #define READ_PIXEL_4(a)       ((jaguar_byte_read(a##_addr+PIXEL_OFFSET_4(a)) >> PIXEL_SHIFT_4(a)) & 0x0f)
134
135 // 8 bpp pixel read
136 #define PIXEL_OFFSET_8(a)     (((((UINT32)a##_y >> 16) * a##_width) + (((UINT32)a##_x >> 16) & ~7)) * (1 + a##_pitch) + (((UINT32)a##_x >> 16) & 7))
137 #define READ_PIXEL_8(a)       (jaguar_byte_read(a##_addr+PIXEL_OFFSET_8(a)))
138
139 // 16 bpp pixel read
140 #define PIXEL_OFFSET_16(a)    (((((UINT32)a##_y >> 16) * a##_width) + (((UINT32)a##_x >> 16) & ~3)) * (1 + a##_pitch) + (((UINT32)a##_x >> 16) & 3))
141 #define READ_PIXEL_16(a)       (jaguar_word_read(a##_addr+(PIXEL_OFFSET_16(a)<<1)))
142
143 // 32 bpp pixel read
144 #define PIXEL_OFFSET_32(a)    (((((UINT32)a##_y >> 16) * a##_width) + (((UINT32)a##_x >> 16) & ~1)) * (1 + a##_pitch) + (((UINT32)a##_x >> 16) & 1))
145 #define READ_PIXEL_32(a)      (jaguar_long_read(a##_addr+(PIXEL_OFFSET_32(a)<<2)))
146
147 // pixel read
148 #define READ_PIXEL(a,f) (\
149          (((f>>3)&0x07) == 0) ? (READ_PIXEL_1(a)) : \
150          (((f>>3)&0x07) == 1) ? (READ_PIXEL_2(a)) : \
151          (((f>>3)&0x07) == 2) ? (READ_PIXEL_4(a)) : \
152          (((f>>3)&0x07) == 3) ? (READ_PIXEL_8(a)) : \
153          (((f>>3)&0x07) == 4) ? (READ_PIXEL_16(a)) : \
154          (((f>>3)&0x07) == 5) ? (READ_PIXEL_32(a)) : 0)
155
156 // 16 bpp z data read
157 #define ZDATA_OFFSET_16(a)     (PIXEL_OFFSET_16(a) + a##_zoffs * 4)
158 #define READ_ZDATA_16(a)       (jaguar_word_read(a##_addr+(ZDATA_OFFSET_16(a)<<1)))
159
160 // z data read
161 #define READ_ZDATA(a,f) (READ_ZDATA_16(a))
162
163 // 16 bpp z data write
164 #define WRITE_ZDATA_16(a,d)     {  jaguar_word_write(a##_addr+(ZDATA_OFFSET_16(a)<<1),d); }
165 //#define WRITE_ZDATA_16(a,d)     {  jaguar_word_write(a##_addr+(ZDATA_OFFSET_16(a)<<1),d); \
166         WriteLog("16bpp z write --> ");  }
167
168 // z data write
169 #define WRITE_ZDATA(a,f,d) WRITE_ZDATA_16(a,d); 
170
171 // 1 bpp r data read
172 #define READ_RDATA_1(r,a,p)  ((p) ?  ((REG(r+(((UINT32)a##_x>>19)&4)))>>(((UINT32)a##_x>>16)&0x1f))&   0x1 : (REG(r) &    0x1))
173
174 // 2 bpp r data read
175 #define READ_RDATA_2(r,a,p)  ((p) ?  ((REG(r+(((UINT32)a##_x>>18)&4)))>>(((UINT32)a##_x>>15)&0x3e))&   0x3 : (REG(r) &    0x3))
176
177 // 4 bpp r data read
178 #define READ_RDATA_4(r,a,p)  ((p) ?  ((REG(r+(((UINT32)a##_x>>17)&4)))>>(((UINT32)a##_x>>14)&0x28))&   0xf : (REG(r) &    0xf))
179
180 // 8 bpp r data read
181 #define READ_RDATA_8(r,a,p)  ((p) ?  ((REG(r+(((UINT32)a##_x>>16)&4)))>>(((UINT32)a##_x>>13)&0x18))&  0xff : (REG(r) &   0xff))
182
183 // 16 bpp r data read
184 #define READ_RDATA_16(r,a,p)  ((p) ? ((REG(r+(((UINT32)a##_x>>15)&4)))>>(((UINT32)a##_x>>12)&0x10))&0xffff : (REG(r) & 0xffff))
185
186 // 32 bpp r data read
187 #define READ_RDATA_32(r,a,p)  ((p) ? REG(r+(((UINT32)a##_x>>14)&4)) : REG(r))
188
189 // register data read
190 #define READ_RDATA(r,a,f,p) (\
191          (((f>>3)&0x07) == 0) ? (READ_RDATA_1(r,a,p)) : \
192          (((f>>3)&0x07) == 1) ? (READ_RDATA_2(r,a,p)) : \
193          (((f>>3)&0x07) == 2) ? (READ_RDATA_4(r,a,p)) : \
194          (((f>>3)&0x07) == 3) ? (READ_RDATA_8(r,a,p)) : \
195          (((f>>3)&0x07) == 4) ? (READ_RDATA_16(r,a,p)) : \
196          (((f>>3)&0x07) == 5) ? (READ_RDATA_32(r,a,p)) : 0)
197
198 // 1 bpp pixel write
199 #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<<PIXEL_SHIFT_1(a))); }
200
201 // 2 bpp pixel write
202 #define WRITE_PIXEL_2(a,d)       { jaguar_byte_write(a##_addr+PIXEL_OFFSET_2(a),(jaguar_byte_read(a##_addr+PIXEL_OFFSET_2(a))&(~(0x03 << PIXEL_SHIFT_2(a))))|(d<<PIXEL_SHIFT_2(a))); }
203
204 // 4 bpp pixel write
205 #define WRITE_PIXEL_4(a,d)       { jaguar_byte_write(a##_addr+PIXEL_OFFSET_4(a),(jaguar_byte_read(a##_addr+PIXEL_OFFSET_4(a))&(~(0x0f << PIXEL_SHIFT_4(a))))|(d<<PIXEL_SHIFT_4(a))); }
206
207 // 8 bpp pixel write
208 #define WRITE_PIXEL_8(a,d)       { jaguar_byte_write(a##_addr+PIXEL_OFFSET_8(a),d); }
209
210 // 16 bpp pixel write
211 #define WRITE_PIXEL_16(a,d)     {  jaguar_word_write(a##_addr+(PIXEL_OFFSET_16(a)<<1),d); }
212 //#define WRITE_PIXEL_16(a,d)     {  jaguar_word_write(a##_addr+(PIXEL_OFFSET_16(a)<<1),d); \
213         WriteLog("16bpp pixel write --> ");  }
214
215 //This is where the bad YPOS values are being written... How to fix???
216 // 32 bpp pixel write
217 #define WRITE_PIXEL_32(a,d)             { jaguar_long_write(a##_addr+(PIXEL_OFFSET_32(a)<<2),d); } 
218 //#define WRITE_PIXEL_32(a,d)           { jaguar_long_write(a##_addr+(PIXEL_OFFSET_32(a)<<2),d); \
219         WriteLog("32bpp pixel write --> ");  }
220
221 // pixel write
222 #define WRITE_PIXEL(a,f,d) {\
223         switch ((f>>3)&0x07) { \
224         case 0: WRITE_PIXEL_1(a,d);  break;  \
225         case 1: WRITE_PIXEL_2(a,d);  break;  \
226         case 2: WRITE_PIXEL_4(a,d);  break;  \
227         case 3: WRITE_PIXEL_8(a,d);  break;  \
228         case 4: WRITE_PIXEL_16(a,d); break;  \
229         case 5: WRITE_PIXEL_32(a,d); break;  \
230         }}
231
232 // Width in Pixels of a Scanline
233 // This is a pretranslation of the value found in the A1 & A2 flags: It's really a floating point value
234 // of the form EEEEMM where MM is the mantissa with an implied "1." in front of it and the EEEE value is
235 // the exponent. Valid values for the exponent range from 0 to 11 (decimal). It's easiest to think of it
236 // as a floating point bit pattern being followed by a number of zeroes. So, e.g., 001101 translates to
237 // 1.01 (the "1." being implied) x (2 ^ 3) or 1010 -> 10 in base 10 (i.e., 1.01 with the decimal place
238 // being shifted to the right 3 places).
239 static uint32 blitter_scanline_width[48] = 
240 {             
241      0,    0,    0,    0,                                       // Note: This would really translate to 1, 1, 1, 1
242      2,    0,    0,    0,
243      4,    0,    6,    0,
244      8,   10,   12,   14,
245     16,   20,   24,   28,
246     32,   40,   48,   56,
247     64,   80,   96,  112,
248    128,  160,  192,  224,
249    256,  320,  384,  448,
250    512,  640,  768,  896,
251   1024, 1280, 1536, 1792,
252   2048, 2560, 3072, 3584
253 };
254
255 //static uint8 * tom_ram_8;
256 //static uint8 * paletteRam;
257 static uint8 src;
258 static uint8 dst;
259 static uint8 misc;
260 static uint8 a1ctl;
261 static uint8 mode;
262 static uint8 ity;
263 static uint8 zop;
264 static uint8 op;
265 static uint8 ctrl;
266 static uint32 a1_addr;
267 static uint32 a2_addr;
268 static int32 a1_zoffs;
269 static int32 a2_zoffs;
270 static uint32 xadd_a1_control;
271 static uint32 xadd_a2_control;
272 static int32 a1_pitch;
273 static int32 a2_pitch;
274 static uint32 n_pixels;
275 static uint32 n_lines;
276 static int32 a1_x;
277 static int32 a1_y;
278 static int32 a1_width;
279 static int32 a2_x;
280 static int32 a2_y;
281 static int32 a2_width;
282 static int32 a2_mask_x;
283 static int32 a2_mask_y;
284 static int32 a1_xadd;
285 static int32 a1_yadd;
286 static int32 a2_xadd;
287 static int32 a2_yadd;
288 static uint8 a1_phrase_mode;
289 static uint8 a2_phrase_mode;
290 static int32 a1_step_x = 0;
291 static int32 a1_step_y = 0;
292 static int32 a2_step_x = 0;
293 static int32 a2_step_y = 0;
294 static uint32 outer_loop;
295 static uint32 inner_loop;
296 static uint32 a2_psize;
297 static uint32 a1_psize;
298 static uint32 gouraud_add;
299 //static uint32 gouraud_data;
300 //static uint16 gint[4];
301 //static uint16 gfrac[4];
302 //static uint8  gcolour[4];
303 static int        gd_i[4];
304 static int    gd_c[4];
305 static int    gd_ia, gd_ca;
306 static int    colour_index = 0;
307 static int32  zadd;
308 static uint32  z_i[4];
309
310 static uint32 a1_clip_x, a1_clip_y;
311
312 static uint8 blitter_code_cache[4096];
313 static uint8 * blitter_ptr;
314 uint8 blitter_working = 0;
315
316 typedef void (blitter_fn)(void);
317
318 typedef struct s_blitter_cache
319 {
320         uint32 hashcode;
321         uint8  * code;
322         uint32 ready;
323         uint8   used;
324         struct s_blitter_cache * next;
325         struct s_blitter_cache * prev;
326 } s_blitter_code_cache;
327
328 s_blitter_cache * blitter_cache[256];
329
330 uint8 blitter_cache_init = 0;
331 static uint8 BPP_LUT[8] = { 1, 2, 4, 8, 16, 32, 0, 0 };
332
333 FILE * blitters_code_fp;
334 FILE * blitters_code_init_fp;
335
336 //////////////////////////////////////////////////////////////////////////////
337 // build C code for the specified blitter
338 //////////////////////////////////////////////////////////////////////////////
339 //
340 //
341 //
342 //////////////////////////////////////////////////////////////////////////////
343 void blitter_gen_c_code(FILE *fp, uint32 cmd,uint32 hashcode)
344 {
345         static uint8 inhibit_modified=0;
346
347         fprintf(fp,"#ifndef blitter_code_0x%.8x\n",hashcode);
348         fprintf(fp,"#define blitter_code_0x%.8x\n",hashcode);
349
350         fprintf(fp,"void blitter_0x%.8x(void)\n",hashcode);
351         fprintf(fp,"{\n");
352         fprintf(fp,"\twhile (outer_loop--)\n");
353         fprintf(fp,"\t{\n");
354         fprintf(fp,"\t\tinner_loop=n_pixels;\n");
355         fprintf(fp,"\t\twhile (inner_loop--)\n");
356         fprintf(fp,"\t\t{\n");
357         fprintf(fp,"\t\t\tuint32 srcdata   = 0;\n");
358         fprintf(fp,"\t\t\tuint32 srczdata  = 0;\n");
359         fprintf(fp,"\t\t\tuint32 dstdata   = 0;\n");
360         fprintf(fp,"\t\t\tuint32 dstzdata  = 0;\n");
361         fprintf(fp,"\t\t\tuint32 writedata = 0;\n");
362         fprintf(fp,"\t\t\tuint32 inhibit   = 0;\n");
363         
364         char *src;
365         char *dst;
366         uint32 src_flags;
367         uint32 dst_flags;
368
369         if (!DSTA2)
370         {
371                 src="a2";
372                 dst="a1";
373                 src_flags=A2_FLAGS;
374                 dst_flags=A1_FLAGS;
375         }
376         else
377         {
378                 src="a1";
379                 dst="a2";
380                 src_flags=A1_FLAGS;
381                 dst_flags=A2_FLAGS;
382         }
383
384         // load src data and Z
385         if (SRCEN)
386         {
387                 fprintf(fp, "\t\t\tsrcdata = READ_PIXEL_%i(%s);\n", BPP_LUT[(((REG(dst_flags)) >> 3) & 0x07)], src);
388                 if (SRCENZ)
389                         fprintf(fp,"\t\t\tsrczdata = READ_ZDATA_%i(%s);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],src);
390                 else 
391                 if (cmd & 0x001c020)
392                         fprintf(fp,"\t\t\tsrczdata = READ_RDATA_%i(SRCZINT, %s, %s_phrase_mode);\n",BPP_LUT[(((REG(src_flags))>>3)&0x07)],src,src);
393         }
394         else
395         {
396                 fprintf(fp,"\t\t\tsrcdata = READ_RDATA_%i(SRCDATA, %s, %s_phrase_mode);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],src,src);
397                 if (cmd & 0x001c020)
398                         fprintf(fp,"\t\t\tsrczdata = READ_RDATA_%i(SRCZINT, %s, %s_phrase_mode);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],src,src);
399         }
400
401         // load dst data and Z 
402         if (DSTEN)
403         {
404                 fprintf(fp,"\t\t\tdstdata = READ_PIXEL_%i(%s);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],dst);
405                 if (DSTENZ)
406                         fprintf(fp,"\t\t\tdstzdata = READ_ZDATA_%i(%s);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],dst);
407                 else
408                         fprintf(fp,"\t\t\tdstzdata = READ_RDATA_%i(DSTZ, %s, %s_phrase_mode);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],dst,dst);
409         }
410         else
411         {
412                 fprintf(fp,"\t\t\tdstdata = READ_RDATA_%i(DSTDATA, %s, %s_phrase_mode);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],dst,dst);
413
414                 if (DSTENZ)
415                         fprintf(fp,"\t\t\tdstzdata = READ_RDATA_%i(DSTZ, %s, %s_phrase_mode);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],dst,dst);
416         }
417
418         // a1 clipping
419         if ((cmd & 0x00000040)&&(!DSTA2))
420
421         {
422                 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");
423                  inhibit_modified=1;
424         }
425         if(GOURZ) 
426         {
427                 fprintf(fp,"\t\t\tsrczdata=z_i[colour_index]>>16;\n");
428         }
429         // apply z comparator
430         if (Z_OP_INF) { fprintf(fp,"\t\t\tif (srczdata <  dstzdata)     inhibit = 1;\n"); inhibit_modified=1;}
431         if (Z_OP_EQU) { fprintf(fp,"\t\t\tif (srczdata == dstzdata)     inhibit = 1;\n"); inhibit_modified=1;}
432         if (Z_OP_SUP) { fprintf(fp,"\t\t\tif (srczdata >  dstzdata)     inhibit = 1;\n"); inhibit_modified=1;}
433
434         // apply data comparator
435         if (DCOMPEN)
436         {
437                 if (!CMPDST)
438                 {
439                         // compare source pixel with pattern pixel
440                         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);
441                         inhibit_modified=1;
442                 }
443                 else
444                 {
445                         // compare destination pixel with pattern pixel
446                         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);
447                         inhibit_modified=1;
448                 }
449         }
450         
451         // compute the write data and store
452                 if (inhibit_modified) fprintf(fp,"\t\t\tif (!inhibit)\n\t\t\t{\n");
453                 if (PATDSEL)
454                 {
455                         // use pattern data for write data
456                         fprintf(fp,"\t\t\t\twritedata= READ_RDATA_%i(PATTERNDATA, %s, %s_phrase_mode);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],dst,dst);
457                 }
458                 else 
459                 if (INTADD)
460                 {
461                         // intensity addition
462                         fprintf(fp,"\t\t\t\twritedata = (srcdata & 0xff) + (dstdata & 0xff);\n");
463                         if (!(TOPBEN))
464                                 fprintf(fp,"\t\t\t\tif (writedata > 0xff) writedata = 0xff;\n");
465
466                         fprintf(fp,"\t\t\t\twritedata |= (srcdata & 0xf00) + (dstdata & 0xf00);\n");
467                         if (!(TOPNEN)) fprintf(fp,"\t\t\t\tif (writedata > 0xfff) writedata = 0xfff;\n");
468                         fprintf(fp,"\t\t\t\twritedata |= (srcdata & 0xf000) + (dstdata & 0xf000);\n");
469                 }
470                 else
471                 {
472                         if (LFU_NAN) fprintf(fp,"\t\t\t\twritedata |= ~srcdata & ~dstdata;\n");
473                         if (LFU_NA)  fprintf(fp,"\t\t\t\twritedata |= ~srcdata & dstdata;\n");
474                         if (LFU_AN)  fprintf(fp,"\t\t\t\twritedata |= srcdata  & ~dstdata;\n");
475                         if (LFU_A)       fprintf(fp,"\t\t\t\twritedata |= srcdata  & dstdata;\n");
476                 }
477                 if(GOURD) 
478                 {
479                         fprintf(fp,"\t\t\t\twritedata = ((gd_c[colour_index])<<8)|(gd_i[colour_index]>>16);\n");
480                 }
481                 if(SRCSHADE) 
482                 {
483                         fprintf(fp,"\t\t\t\t{\n");
484                         fprintf(fp,"\t\t\t\tint intensity = srcdata & 0xFF;\n");
485                         fprintf(fp,"\t\t\t\tint ia = gd_ia >> 16;\n");
486                         fprintf(fp,"\t\t\t\tif(ia & 0x80)\n");
487                         fprintf(fp,"\t\t\t\t    ia = 0xFFFFFF00 | ia;\n");
488                         fprintf(fp,"\t\t\t\tintensity += ia;\n");
489                         fprintf(fp,"\t\t\t\tif(intensity < 0)\n");
490                         fprintf(fp,"\t\t\t\t    intensity = 0;\n");
491                         fprintf(fp,"\t\t\t\tif(intensity > 0xFF)\n");
492                         fprintf(fp,"\t\t\t\t    intensity = 0xFF;\n");
493                         fprintf(fp,"\t\t\t\twritedata = (srcdata & 0xFF00) | intensity;\n");
494                         fprintf(fp,"\t\t\t\t}\n");
495                 }
496         if (inhibit_modified)  
497         {
498                 fprintf(fp,"\t\t\t} else { srczdata=dstzdata; writedata=dstdata; }\n");
499         }
500
501         if ((DSTA2?a2_phrase_mode:a1_phrase_mode) || BKGWREN)
502         {
503                 // write to the destination
504                 fprintf(fp,"\t\t\tWRITE_PIXEL_%i(%s, writedata);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],dst);
505                 if (DSTWRZ) fprintf(fp,"\t\t\tWRITE_ZDATA_%i(%s, srczdata);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],dst);
506         }
507         else
508         {
509                 if (inhibit_modified) fprintf(fp,"\t\t\tif (!inhibit)\n\t\t\t{\n");
510                 // write to the destination
511                 fprintf(fp,"\t\t\t\tWRITE_PIXEL_%i(%s, writedata);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],dst);
512                 if (DSTWRZ) fprintf(fp,"\t\t\t\tWRITE_ZDATA_%i(%s, srczdata);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],dst);
513                 if (inhibit_modified) fprintf(fp,"\t\t\t}\n");
514         }
515         // update x and y
516         fprintf(fp,"\t\t\ta1_x += a1_xadd;\n");
517         fprintf(fp,"\t\t\ta1_y += a1_yadd;\n");
518         fprintf(fp,"\t\t\ta2_x = (a2_x + a2_xadd) & a2_mask_x;\n");
519         fprintf(fp,"\t\t\ta2_y = (a2_y + a2_yadd) & a2_mask_y;\n");
520         if (GOURZ)
521         {
522                 fprintf(fp,"\t\t\tz_i[colour_index]+=zadd;\n");
523         }
524         if ((GOURD)||(SRCSHADE))
525         {
526                 fprintf(fp,"\t\t\tgd_i[colour_index] += gd_ia;\n");
527                 fprintf(fp,"\t\t\tgd_c[colour_index] += gd_ca;\n");
528         }
529         if ((GOURD)||(SRCSHADE)||(GOURZ))
530         {
531                 if (a1_phrase_mode)
532                 fprintf(fp,"\t\t\t colour_index=(colour_index+1)&0x3;\n");
533         }
534         fprintf(fp,"\t\t}\n");
535
536         fprintf(fp,"\t\ta1_x+=a1_step_x;\n");
537         fprintf(fp,"\t\ta1_y+=a1_step_y;\n");
538         fprintf(fp,"\t\ta2_x+=a2_step_x;\n");
539         fprintf(fp,"\t\ta2_y+=a2_step_y;\n");
540         fprintf(fp,"\t}\n");
541         
542         // write values back to registers 
543         fprintf(fp,"\tWREG(A1_PIXEL,  (a1_y & 0xffff0000) | ((a1_x >> 16) & 0xffff));\n");
544         fprintf(fp,"\tWREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xffff));\n");
545         fprintf(fp,"\tWREG(A2_PIXEL,  (a2_y & 0xffff0000) | ((a2_x >> 16) & 0xffff));\n");
546         fprintf(fp,"}\n");
547         fprintf(fp,"#endif\n");
548 }
549
550 //////////////////////////////////////////////////////////////////////////////
551 // Generate a start of function in x86 assembly
552 //////////////////////////////////////////////////////////////////////////////
553 //
554 //
555 //
556 //////////////////////////////////////////////////////////////////////////////
557 void blitter_gen_start_of_function(void)
558 {
559         *blitter_ptr++ = 0x55;  // push ebp
560         *blitter_ptr++ = 0x8B;  // mov  ebp,esp
561         *blitter_ptr++ = 0xEC;
562 }
563 //////////////////////////////////////////////////////////////////////////////
564 // Generate a end of function in x86 assembly
565 //////////////////////////////////////////////////////////////////////////////
566 //
567 //
568 //
569 //////////////////////////////////////////////////////////////////////////////
570 void blitter_gen_end_of_function(void)
571 {
572         *blitter_ptr++ = 0x8B;  // mov         esp,ebp
573         *blitter_ptr++ = 0xE5;
574         *blitter_ptr++ = 0x5D;  // pop         ebp
575         *blitter_ptr++ = 0xC3;  // ret
576 }
577
578 #define HASHCODE_BIT(C,B) if (C) hashcode|=(1<<B);
579 #define HASHCODE_BIT_TEST(B) (hashcode&(1<<B))
580
581 uint32 blitter_calc_hashcode(uint32 cmd)
582 {
583         uint32 hashcode=0x00000000;
584
585         // source and destination bit depth
586         hashcode|=((REG(A1_FLAGS)>>3)&0x07)<<0;
587         hashcode|=((REG(A2_FLAGS)>>3)&0x07)<<3;
588
589         HASHCODE_BIT(DSTA2,                                     6);
590         HASHCODE_BIT(SRCEN,                                     7);
591         HASHCODE_BIT(SRCENZ,                            8);
592         HASHCODE_BIT(DSTEN,                                     9);
593         HASHCODE_BIT(DSTENZ,                            10);
594         HASHCODE_BIT(Z_OP_INF,                          11);
595         HASHCODE_BIT(Z_OP_EQU,                          12);
596         HASHCODE_BIT(Z_OP_SUP,                          13);
597         HASHCODE_BIT(DCOMPEN,                           14);
598         HASHCODE_BIT(CMPDST,                            15);
599         HASHCODE_BIT(PATDSEL,                           16);
600         HASHCODE_BIT(INTADD,                            17);
601         HASHCODE_BIT(TOPBEN,                            18);
602         HASHCODE_BIT(TOPNEN,                            19);
603         HASHCODE_BIT(LFU_NAN,                           20);
604         HASHCODE_BIT(LFU_NA,                            21);
605         HASHCODE_BIT(LFU_AN,                            22);
606         HASHCODE_BIT(LFU_A,                                     23);
607         HASHCODE_BIT(BKGWREN,                           24);
608         HASHCODE_BIT(DSTWRZ,                            25);
609         HASHCODE_BIT((cmd & 0x001c020),         26); // extra data read/write
610         HASHCODE_BIT((cmd & 0x00000040),        27); // source clipping
611         HASHCODE_BIT(a1_phrase_mode,            28); 
612         HASHCODE_BIT(a2_phrase_mode,            29); 
613
614         return(hashcode);
615 }
616 //////////////////////////////////////////////////////////////////////////////
617 // Build the blitter code for the current blitter operation in the cache
618 //////////////////////////////////////////////////////////////////////////////
619 //
620 //
621 //
622 //////////////////////////////////////////////////////////////////////////////
623 void blitter_build_cached_code(uint32 cmd, uint32 cache_index)
624 {
625 }
626 //////////////////////////////////////////////////////////////////////////////
627 // Check if the blitter code for the current blitter operation is cached
628 //////////////////////////////////////////////////////////////////////////////
629 //
630 //
631 //
632 //////////////////////////////////////////////////////////////////////////////
633 struct s_blitter_cache * blitter_in_cache(uint32 cmd)
634 {
635         uint32 i;
636         uint32 hashcode=blitter_calc_hashcode(cmd);
637 #ifdef LOG_BLITS
638         WriteLog("blitter: hashcode= 0x%.8x\n",hashcode);
639 #endif
640         struct s_blitter_cache *blitter_list=blitter_cache[hashcode>>24];
641         
642         i=0;
643         while (blitter_list->next)
644         {
645                 blitter_list=blitter_list->next;
646
647                 if (blitter_list->hashcode==hashcode)
648                         return(blitter_list);
649         }
650 #ifdef GEN_CODE
651         blitter_list->next=(struct s_blitter_cache *)malloc(sizeof(struct s_blitter_cache));
652         blitter_list->next->prev=blitter_list;
653         blitter_list->next->next=null;
654         blitter_list=blitter_list->next;
655
656         blitter_list->code=(uint8*)malloc(4096);
657         blitter_list->hashcode=hashcode;
658         blitter_list->ready=0;
659         blitter_gen_c_code(blitters_code_fp,cmd,hashcode);
660         fprintf(blitters_code_init_fp,"\tblitter_add(0x%.8x,(uint8*)&blitter_0x%.8x);\n",hashcode,hashcode);
661 #else
662         //WriteLog("warning: using generic blitter for blitter 0x%.8x\n",hashcode);
663 #endif
664         return(null);
665 }
666 #ifndef USE_GENERIC_BLITTER
667 #include "include/blit_c.h"
668 #endif
669 //////////////////////////////////////////////////////////////////////////////
670 // Execute the cached blitter code for the current blitter operation
671 //////////////////////////////////////////////////////////////////////////////
672 //
673 //
674 //
675 //////////////////////////////////////////////////////////////////////////////
676 uint32 blitter_execute_cached_code(struct s_blitter_cache * blitter)
677 {
678         if ((blitter == null) || (blitter->ready == 0))
679                 return 0;
680
681         blitter_fn * fn = (blitter_fn *)blitter->code;
682         blitter->used = 1;
683         (*fn)();
684
685         return 1;
686 }
687
688 void blitter_add(uint32 hashcode, uint8 *code)
689 {
690         struct s_blitter_cache *blitter_list=blitter_cache[(hashcode>>24)];
691
692 //      WriteLog("adding blitter for hashcode 0x%.8x\n",hashcode);
693
694         while (blitter_list->next)
695         {
696                 blitter_list=blitter_list->next;
697
698                 if (blitter_list->hashcode==hashcode)
699                         return;
700         }
701         blitter_list->next=(struct s_blitter_cache *)malloc(sizeof(struct s_blitter_cache));
702         blitter_list->next->prev=blitter_list;
703         blitter_list->next->next=null;
704         blitter_list=blitter_list->next;
705
706         blitter_list->code=code;
707         blitter_list->hashcode=hashcode;
708         blitter_list->ready=1;
709         blitter_list->used=0;
710 }
711
712 void blitter_list(void)
713 {
714 /*
715         WriteLog("Used blitters list:\n");
716
717         for (int i=0;i<256;i++)
718         {
719                 struct s_blitter_cache *blitter_list=blitter_cache[i];
720
721                 while (blitter_list->next)
722                 {
723                         blitter_list=blitter_list->next;
724                         if (blitter_list->used)
725                                 WriteLog("\t0%.8x\n",blitter_list->hashcode);
726                 }
727         }
728 */
729 }
730
731 //
732 // Generic blit handler
733 //
734
735 void blitter_generic(uint32 cmd)
736 {
737 //Testing only!
738 //uint32 logGo = ((cmd == 0x01800E01 && REG(A1_BASE) == 0x898000) ? 1 : 0);
739
740 /*      uint32 srcdata = 0;
741         uint32 srczdata = 0;
742         uint32 dstdata = 0;
743         uint32 dstzdata = 0;
744         uint32 writedata = 0;
745         uint32 inhibit = 0;*/
746         uint32 srcdata, srczdata, dstdata, dstzdata, writedata, inhibit;
747
748         while (outer_loop--)
749         {
750                 inner_loop = n_pixels;
751                 while (inner_loop--)
752                 {
753                         srcdata = srczdata = dstdata = dstzdata = writedata = inhibit = 0;
754
755                         if (!DSTA2)
756                         {
757                                 // load src data and Z
758                                 if (SRCEN)
759                                 {
760                                         srcdata = READ_PIXEL(a2, REG(A2_FLAGS));
761                                         if (SRCENZ)
762                                                 srczdata = READ_ZDATA(a2, REG(A2_FLAGS));
763                                         else if (cmd & 0x0001C020)
764                                                 srczdata = READ_RDATA(SRCZINT, a2, REG(A2_FLAGS), a2_phrase_mode);
765                                 }
766                                 else
767                                 {
768                                         srcdata = READ_RDATA(SRCDATA, a2, REG(A2_FLAGS), a2_phrase_mode);
769                                         if (cmd & 0x0001C020)
770                                                 srczdata = READ_RDATA(SRCZINT, a2, REG(A2_FLAGS), a2_phrase_mode);
771                                 }
772
773                                 // load dst data and Z 
774                                 if (DSTEN)
775                                 {
776                                         dstdata = READ_PIXEL(a1, REG(A1_FLAGS));
777                                         if (DSTENZ)
778                                                 dstzdata = READ_ZDATA(a1, REG(A1_FLAGS));
779                                         else
780                                                 dstzdata = READ_RDATA(DSTZ, a1, REG(A1_FLAGS), a1_phrase_mode);
781                                 }
782                                 else
783                                 {
784                                         dstdata = READ_RDATA(DSTDATA, a1, REG(A1_FLAGS), a1_phrase_mode);
785                                         if (DSTENZ)
786                                                 dstzdata = READ_RDATA(DSTZ, a1, REG(A1_FLAGS), a1_phrase_mode);
787                                 }
788
789 /*This wasn't working...                                // a1 clipping
790                                 if (cmd & 0x00000040)
791                                 {
792                                         if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7FFF)
793                                                 || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7FFF))
794                                                 inhibit = 1;
795                                 }//*/
796
797                                 if (GOURZ) 
798                                         srczdata = z_i[colour_index] >> 16;
799
800                                 // apply z comparator
801                                 if (Z_OP_INF) if (srczdata <  dstzdata) inhibit = 1;
802                                 if (Z_OP_EQU) if (srczdata == dstzdata) inhibit = 1;
803                                 if (Z_OP_SUP) if (srczdata >  dstzdata) inhibit = 1;
804                                 
805                                 // apply data comparator
806 // Note: DCOMPEN only works in 8/16 bpp modes! !!! FIX !!!
807 // Does BCOMPEN only work in 1 bpp mode???
808                                 if (DCOMPEN | BCOMPEN)
809                                 {
810                                         if (!CMPDST)
811                                         {
812 //WriteLog("Blitter: BCOMPEN set on command %08X inhibit prev:%u, now:", cmd, inhibit);
813                                                 // compare source pixel with pattern pixel
814 /*
815 Blit! (000B8250 <- 0012C3A0) count: 16 x 1, A1/2_FLAGS: 00014420/00012000 [cmd: 05810001]
816  CMD -> src: SRCEN  dst:  misc:  a1ctl:  mode:  ity: PATDSEL z-op:  op: LFU_REPLACE ctrl: BCOMPEN 
817   A1 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 384 (22), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
818   A2 -> pitch: 1 phrases, depth: 1bpp, z-off: 0, width: 16 (10), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
819         x/y: 0/20
820 ...
821 */
822 // AvP is still wrong, could be cuz it's doing A1 -> A2...
823
824 // Src is the 1bpp bitmap... DST is the PATTERN!!!
825 // This seems to solve at least ONE of the problems with MC3D...
826 // Why should this be inverted???
827 // Bcuz it is. This is supposed to be used only for a bit -> pixel expansion...
828 /*                                              if (srcdata == READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode))
829 //                                              if (srcdata != READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode))
830                                                         inhibit = 1;//*/
831 /*                                              uint32 A2bpp = 1 << ((REG(A2_FLAGS) >> 3) & 0x07);
832                                                 if (A2bpp == 1 || A2bpp == 16 || A2bpp == 8)
833                                                         inhibit = (srcdata == 0 ? 1: 0);
834 //                                                      inhibit = !srcdata;
835                                                 else
836                                                         WriteLog("Blitter: Bad BPP (%u) selected for BCOMPEN mode!\n", A2bpp);//*/
837 // What it boils down to is this:
838 // ***CHECK*** Hmm. Seems to cause Rayman to freeze. Investigate.
839 // This doesn't seem to be it. Hmm.
840 // It was a bug in the TOM read word code (reading VC)
841                                                 if (srcdata == 0)
842                                                         inhibit = 1;//*/
843                                         }
844                                         else
845                                         {
846                                                 // compare destination pixel with pattern pixel
847                                                 if (dstdata == READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode))
848 //                                              if (dstdata != READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode))
849                                                         inhibit = 1;
850                                         }
851 // This is DEFINITELY WRONG
852                                         if (a1_phrase_mode || a2_phrase_mode)
853                                                 inhibit = !inhibit;
854                                 }
855
856                                 if (CLIPA1)
857                                 {
858                                         inhibit |= (((a1_x >> 16) < a1_clip_x && (a1_x >> 16) >= 0
859                                                 && (a1_y >> 16) < a1_clip_y && (a1_y >> 16) >= 0) ? 0 : 1);
860                                 }
861
862                                 // compute the write data and store
863                                 if (!inhibit)
864                                 {                       
865                                         if (PATDSEL)
866                                         {
867                                                 // use pattern data for write data
868                                                 writedata = READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode);
869                                         }
870                                         else if (INTADD)
871                                         {
872                                                 // intensity addition
873                                                 writedata = (srcdata & 0xFF) + (dstdata & 0xFF);
874                                                 if (!(TOPBEN) && writedata > 0xFF)
875                                                         writedata = 0xFF;
876                                                 writedata |= (srcdata & 0xF00) + (dstdata & 0xF00);
877                                                 if (!(TOPNEN) && writedata > 0xFFF)
878                                                         writedata = 0xFFF;
879                                                 writedata |= (srcdata & 0xF000) + (dstdata & 0xF000);
880                                         }
881                                         else
882                                         {
883                                                 if (LFU_NAN) writedata |= ~srcdata & ~dstdata;
884                                                 if (LFU_NA)  writedata |= ~srcdata & dstdata;
885                                                 if (LFU_AN)  writedata |= srcdata  & ~dstdata;
886                                                 if (LFU_A)       writedata |= srcdata  & dstdata;
887                                         }
888
889                                         if (GOURD) 
890                                                 writedata = ((gd_c[colour_index]) << 8) | (gd_i[colour_index] >> 16);
891
892                                         if (SRCSHADE) 
893                                         {
894                                                 int intensity = srcdata & 0xFF;
895                                                 int ia = gd_ia >> 16;
896                                                 if (ia & 0x80)
897                                                         ia = 0xFFFFFF00 | ia;
898                                                 intensity += ia;
899                                                 if (intensity < 0)
900                                                         intensity = 0;
901                                                 if (intensity > 0xFF)
902                                                         intensity = 0xFF;
903                                                 writedata = (srcdata & 0xFF00) | intensity;
904                                         }
905                                 }
906                                 else
907                                 {
908                                         writedata = dstdata;
909                                         srczdata = dstzdata;
910                                 }
911
912                                 if (/*a1_phrase_mode || */BKGWREN || !inhibit)
913                                 {
914 // This is the sole source of the bogus YPOS values being written to the object list... !!! FIX !!!
915 /*if (((REG(A1_FLAGS) >> 3) & 0x07) == 5)
916 {
917         uint32 offset = a1_addr+(PIXEL_OFFSET_32(a1)<<2);
918 // (((((UINT32)a##_y >> 16) * a##_width) + (((UINT32)a##_x >> 16) & ~1)) * (1 + a##_pitch) + (((UINT32)a##_x >> 16) & 1))
919         if ((offset >= 0x1FF020 && offset <= 0x1FF03F) || (offset >= 0x1FF820 && offset <= 0x1FF83F))
920                 WriteLog("32bpp pixel write: A1 Phrase mode --> ");
921 }//*/
922                                         // write to the destination
923                                         WRITE_PIXEL(a1, REG(A1_FLAGS), writedata);
924                                         if (DSTWRZ)
925                                                 WRITE_ZDATA(a1, REG(A1_FLAGS), srczdata);
926                                 }
927                         }
928                         else    // if (DSTA2)
929                         {
930                                 // load src data and Z
931                                 if (SRCEN)
932                                 {
933                                         srcdata = READ_PIXEL(a1, REG(A1_FLAGS));
934                                         if (SRCENZ)
935                                                 srczdata = READ_ZDATA(a1, REG(A1_FLAGS));
936                                         else if (cmd & 0x0001C020)
937                                                 srczdata = READ_RDATA(SRCZINT, a1, REG(A1_FLAGS), a1_phrase_mode);
938                                 }
939                                 else
940                                 {
941                                         srcdata = READ_RDATA(SRCDATA, a1, REG(A1_FLAGS), a1_phrase_mode);
942                                         if (cmd & 0x001C020)
943                                                 srczdata = READ_RDATA(SRCZINT, a1, REG(A1_FLAGS), a1_phrase_mode);
944                                 }
945
946                                 // load dst data and Z 
947                                 if (DSTEN)
948                                 {
949                                         dstdata = READ_PIXEL(a2, REG(A2_FLAGS));
950                                         if (DSTENZ)
951                                                 dstzdata = READ_ZDATA(a2, REG(A2_FLAGS));
952                                         else
953                                                 dstzdata = READ_RDATA(DSTZ, a2, REG(A2_FLAGS), a2_phrase_mode);
954                                 }
955                                 else
956                                 {
957                                         dstdata = READ_RDATA(DSTDATA, a2, REG(A2_FLAGS), a2_phrase_mode);
958                                         if (DSTENZ)
959                                                 dstzdata = READ_RDATA(DSTZ, a2, REG(A2_FLAGS), a2_phrase_mode);
960                                 }
961
962                                 if (GOURZ) 
963                                         srczdata = z_i[colour_index] >> 16;
964
965                                 // apply z comparator
966                                 if (Z_OP_INF) if (srczdata < dstzdata)  inhibit = 1;
967                                 if (Z_OP_EQU) if (srczdata == dstzdata) inhibit = 1;
968                                 if (Z_OP_SUP) if (srczdata > dstzdata)  inhibit = 1;
969                                 
970                                 // apply data comparator
971 //NOTE: The bit comparator (BCOMPEN) is NOT the same at the data comparator!
972                                 if (DCOMPEN | BCOMPEN)
973                                 {
974                                         if (!CMPDST)
975                                         {
976                                                 // compare source pixel with pattern pixel
977 // AvP: Numbers are correct, but sprites are not!
978 //This doesn't seem to be a problem... But could still be wrong...
979 /*                                              if (srcdata == READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode))
980 //                                              if (srcdata != READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode))
981                                                         inhibit = 1;//*/
982 // This is probably not 100% correct... It works in the 1bpp case
983 // (in A1 <- A2 mode, that is...)
984 // AvP: This is causing blocks to be written instead of bit patterns...
985 // Works now...
986 // NOTE: We really should separate out the BCOMPEN & DCOMPEN stuff!
987 /*                                              uint32 A1bpp = 1 << ((REG(A1_FLAGS) >> 3) & 0x07);
988                                                 if (A1bpp == 1 || A1bpp == 16 || A1bpp == 8)
989                                                         inhibit = (srcdata == 0 ? 1: 0);
990                                                 else
991                                                         WriteLog("Blitter: Bad BPP (%u) selected for BCOMPEN mode!\n", A1bpp);//*/
992 // What it boils down to is this:
993 // ***CHECK*** Hmm. Seems to cause Rayman to freeze. Investigate.
994 // This doesn't seem to be it. Hmm.
995 // It was a bug in the TOM read word code (reading VC)
996                                                 if (srcdata == 0)
997                                                         inhibit = 1;//*/
998                                         }
999                                         else
1000                                         {
1001                                                 // compare destination pixel with pattern pixel
1002                                                 if (dstdata == READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode))
1003 //                                              if (dstdata != READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode))
1004                                                         inhibit = 1;
1005                                         }
1006                                         if (a1_phrase_mode || a2_phrase_mode)
1007                                                 inhibit =! inhibit;
1008                                 }
1009                                 
1010                                 if (CLIPA1)
1011                                 {
1012                                         inhibit |= (((a1_x >> 16) < a1_clip_x && (a1_x >> 16) >= 0
1013                                                 && (a1_y >> 16) < a1_clip_y && (a1_y >> 16) >= 0) ? 0 : 1);
1014                                 }
1015
1016                                 // compute the write data and store
1017                                 if (!inhibit)
1018                                 {                       
1019                                         if (PATDSEL)
1020                                         {
1021                                                 // use pattern data for write data
1022                                                 writedata= READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode);
1023                                         }
1024                                         else if (INTADD)
1025                                         {
1026                                                 // intensity addition
1027                                                 writedata = (srcdata & 0xFF) + (dstdata & 0xFF);
1028                                                 if (!(TOPBEN) && writedata > 0xFF)
1029                                                         writedata = 0xFF;
1030                                                 writedata |= (srcdata & 0xF00) + (dstdata & 0xF00);
1031                                                 if (!(TOPNEN) && writedata > 0xFFF)
1032                                                         writedata = 0xFFF;
1033                                                 writedata |= (srcdata & 0xF000) + (dstdata & 0xF000);
1034                                         }
1035                                         else
1036                                         {
1037                                                 if (LFU_NAN)
1038                                                         writedata |= ~srcdata & ~dstdata;
1039                                                 if (LFU_NA)
1040                                                         writedata |= ~srcdata & dstdata;
1041                                                 if (LFU_AN)
1042                                                         writedata |= srcdata & ~dstdata;
1043                                                 if (LFU_A)
1044                                                         writedata |= srcdata & dstdata;
1045                                         }
1046
1047                                         if (GOURD) 
1048                                                 writedata = ((gd_c[colour_index]) << 8) | (gd_i[colour_index] >> 16);
1049
1050                                         if (SRCSHADE) 
1051                                         {
1052                                                 int intensity = srcdata & 0xFF;
1053                                                 int ia = gd_ia >> 16;
1054                                                 if (ia & 0x80)
1055                                                         ia = 0xFFFFFF00 | ia;
1056                                                 intensity += ia;
1057                                                 if (intensity < 0)
1058                                                         intensity = 0;
1059                                                 if (intensity > 0xFF)
1060                                                         intensity = 0xFF;
1061                                                 writedata = (srcdata & 0xFF00) | intensity;
1062                                         }
1063                                 }
1064                                 else
1065                                 {
1066                                         writedata = dstdata;
1067                                         srczdata = dstzdata;
1068                                 }
1069
1070                                 if (/*a2_phrase_mode || */BKGWREN || !inhibit)
1071                                 {
1072 /*if (logGo)
1073 {
1074         uint32 offset = a2_addr+(PIXEL_OFFSET_16(a2)<<1);
1075 // (((((UINT32)a##_y >> 16) * a##_width) + (((UINT32)a##_x >> 16) & ~1)) * (1 + a##_pitch) + (((UINT32)a##_x >> 16) & 1))
1076         WriteLog("[%08X:%04X] ", offset, writedata);
1077 }//*/
1078                                         // write to the destination
1079                                         WRITE_PIXEL(a2, REG(A2_FLAGS), writedata);
1080                                         if (DSTWRZ)
1081                                                 WRITE_ZDATA(a2, REG(A2_FLAGS), srczdata);
1082                                 }
1083                         }
1084
1085                         // update x and y
1086                         a1_x += a1_xadd;
1087                         a1_y += a1_yadd;
1088                         a2_x = (a2_x + a2_xadd) & a2_mask_x;
1089                         a2_y = (a2_y + a2_yadd) & a2_mask_y;
1090
1091                         if (GOURZ)
1092                                 z_i[colour_index] += zadd;
1093
1094                         if (GOURD || SRCSHADE)
1095                         {
1096                                 gd_i[colour_index] += gd_ia;
1097                                 gd_c[colour_index] += gd_ca;
1098                         }
1099                         if (GOURD || SRCSHADE || GOURZ)
1100                         {
1101                                 if (a1_phrase_mode)
1102                                         colour_index = (colour_index + 1) & 0x03;
1103                         }
1104                 }
1105
1106                 a1_x += a1_step_x;
1107                 a1_y += a1_step_y;
1108                 a2_x += a2_step_x;
1109                 a2_y += a2_step_y;
1110
1111 /*              if (a2_phrase_mode)
1112                 {
1113                         a1_x+=(64/a1_psize)*a1_xadd;
1114                 }       
1115                 if (a2_phrase_mode)
1116                 {
1117                         for (int nb=0;nb<(64/a2_psize)+1;nb++)
1118                                 a2_x = (a2_x + a2_xadd) & a2_mask_x;
1119                 }
1120 */      }
1121         
1122         // write values back to registers 
1123         WREG(A1_PIXEL,  (a1_y & 0xFFFF0000) | ((a1_x >> 16) & 0xFFFF));
1124         WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xFFFF));
1125         WREG(A2_PIXEL,  (a2_y & 0xFFFF0000) | ((a2_x >> 16) & 0xFFFF));
1126 }
1127
1128 void blitter_blit(uint32 cmd)
1129 {
1130         colour_index = 0;
1131         src = cmd & 0x07;
1132         dst = (cmd >> 3) & 0x07;
1133         misc = (cmd >> 6) & 0x03;
1134         a1ctl = (cmd >> 8) & 0x7;
1135         mode = (cmd >> 11) & 0x07;
1136         ity = (cmd >> 14) & 0x0F;
1137         zop = (cmd >> 18) & 0x07;
1138         op = (cmd >> 21) & 0x0F;
1139         ctrl = (cmd >> 25) & 0x3F;
1140
1141         a1_addr = REG(A1_BASE);
1142         a2_addr = REG(A2_BASE);
1143
1144         a1_zoffs = (REG(A1_FLAGS) >> 6) & 7;
1145         a2_zoffs = (REG(A2_FLAGS) >> 6) & 7;
1146         
1147         xadd_a1_control = (REG(A1_FLAGS) >> 16) & 0x03;
1148         xadd_a2_control = (REG(A2_FLAGS) >> 16) & 0x03;
1149         a1_pitch = (REG(A1_FLAGS) & 3) ^ ((REG(A1_FLAGS) & 2) >> 1);
1150         a2_pitch = (REG(A2_FLAGS) & 3) ^ ((REG(A2_FLAGS) & 2) >> 1);
1151
1152         n_pixels = REG(PIXLINECOUNTER) & 0xFFFF;
1153         n_lines = (REG(PIXLINECOUNTER) >> 16) & 0xFFFF;
1154
1155         a1_x = (REG(A1_PIXEL) << 16) | (REG(A1_FPIXEL) & 0xFFFF);
1156         a1_y = (REG(A1_PIXEL) & 0xFFFF0000) | (REG(A1_FPIXEL) >> 16);
1157 //      a1_width = blitter_scanline_width[((REG(A1_FLAGS) & 0x00007E00) >> 9)];
1158         UINT32 m = (REG(A1_FLAGS) >> 9) & 0x03, e = (REG(A1_FLAGS) >> 11) & 0x0F;
1159         a1_width = ((0x04 | m) << e) >> 2;//*/
1160
1161         a2_x = (REG(A2_PIXEL) & 0x0000FFFF) << 16;
1162         a2_y = (REG(A2_PIXEL) & 0xFFFF0000);
1163 //      a2_width = blitter_scanline_width[((REG(A2_FLAGS) & 0x00007E00) >> 9)];
1164         m = (REG(A2_FLAGS) >> 9) & 0x03, e = (REG(A2_FLAGS) >> 11) & 0x0F;
1165         a2_width = ((0x04 | m) << e) >> 2;//*/
1166         a2_mask_x = ((REG(A2_MASK) & 0x0000FFFF) << 16) | 0xFFFF;
1167         a2_mask_y = (REG(A2_MASK) & 0xFFFF0000) | 0xFFFF;
1168
1169         // Check for "use mask" flag
1170         if (!(REG(A2_FLAGS) & 0x8000))
1171         {
1172                 a2_mask_x = 0xFFFFFFFF; // must be 16.16
1173                 a2_mask_y = 0xFFFFFFFF; // must be 16.16
1174         }
1175
1176         a1_phrase_mode = 0;
1177
1178         // According to the official documentation, a hardware bug ties A2's yadd bit to A1's...
1179         a2_yadd = a1_yadd = (YADD1_A1 ? 1 << 16 : 0);
1180
1181         if (YSIGNSUB_A1)
1182                 a1_yadd = -a1_yadd;
1183
1184         // determine a1_xadd
1185         switch (xadd_a1_control)
1186         {
1187         case XADDPHR:
1188 // This is a documented Jaguar bug relating to phrase mode and truncation... Look into it!
1189                 // add phrase offset to X and truncate
1190                 a1_xadd = 1 << 16;
1191                 a1_phrase_mode = 1;
1192                 break;
1193         case XADDPIX:
1194                 // add pixelsize (1) to X
1195                 a1_xadd = 1 << 16;
1196                 break;
1197         case XADD0:     
1198                 // add zero (for those nice vertical lines)
1199                 a1_xadd = 0;
1200                 break;
1201         case XADDINC:
1202                 // add the contents of the increment register
1203                 a1_xadd = (REG(A1_INC) << 16)            | (REG(A1_FINC) & 0xFFFF);
1204                 a1_yadd = (REG(A1_INC) & 0xFFFF0000) | (REG(A1_FINC) >> 16);
1205                 break;
1206         }
1207         if (XSIGNSUB_A1)
1208                 a1_xadd = -a1_xadd;
1209
1210         if (YSIGNSUB_A2)
1211                 a2_yadd = -a2_yadd;
1212
1213         a2_phrase_mode = 0;
1214
1215         // determine a2_xadd
1216         switch (xadd_a2_control)
1217         {
1218         case XADDPHR:
1219                 // add phrase offset to X and truncate
1220                 a2_xadd = 1 << 16;
1221                 a2_phrase_mode = 1;
1222                 break;
1223         case XADDPIX:
1224                 // add pixelsize (1) to X
1225                 a2_xadd = 1 << 16;
1226                 break;
1227         case XADD0:     
1228                 // add zero (for those nice vertical lines)
1229                 a2_xadd = 0;
1230                 break;
1231 //This really isn't a valid bit combo for A2... Shouldn't this cause the blitter to just say no?
1232         case XADDINC:
1233                 // add the contents of the increment register
1234                 // since there is no register for a2 we just add 1
1235                 a2_xadd = 1 << 16;
1236                 break;
1237         }
1238         if (XSIGNSUB_A2)
1239                 a2_xadd = -a2_xadd;
1240
1241         // Modify outer loop steps based on blitter command
1242
1243         a1_step_x = 0;
1244         a1_step_y = 0;
1245         a2_step_x = 0;
1246         a2_step_y = 0;
1247
1248         if (UPDA1F)
1249                 a1_step_x = (REG(A1_FSTEP) & 0xFFFF),
1250                 a1_step_y = (REG(A1_FSTEP) >> 16);
1251
1252         if (UPDA1)
1253                 a1_step_x |= ((REG(A1_STEP) & 0x0000FFFF) << 16),
1254                 a1_step_y |= ((REG(A1_STEP) & 0xFFFF0000));
1255
1256         if (UPDA2)
1257                 a2_step_x = (REG(A2_STEP) & 0x0000FFFF) << 16,
1258                 a2_step_y = (REG(A2_STEP) & 0xFFFF0000);
1259
1260         outer_loop = n_lines;
1261
1262         // Clipping...
1263
1264         if (CLIPA1)
1265                 a1_clip_x = REG(A1_CLIP) & 0x7FFF,
1266                 a1_clip_y = (REG(A1_CLIP) >> 16) & 0x7FFF;
1267
1268 // This phrase sizing is incorrect as well... !!! FIX !!!
1269 // Err, this is pixel size... (and it's OK)
1270         a2_psize = 1 << ((REG(A2_FLAGS) >> 3) & 0x07);
1271         a1_psize = 1 << ((REG(A1_FLAGS) >> 3) & 0x07);
1272
1273         // zbuffering
1274         if (GOURZ)
1275         {
1276                 zadd = jaguar_long_read(0xF02274);
1277
1278                 for(int v=0; v<4; v++) 
1279                         z_i[v] = (int32)jaguar_long_read(0xF0228C + (v << 2));
1280         }
1281         if (GOURD || GOURZ || SRCSHADE)
1282         {
1283                 // gouraud shading
1284                 gouraud_add = jaguar_long_read(0xF02270);
1285                 
1286                 gd_c[0] = jaguar_byte_read(0xF02268);
1287                 gd_i[0] = jaguar_byte_read(0xF02269);
1288                 gd_i[0] <<= 16;
1289                 gd_i[0] |= jaguar_word_read(0xF02240);
1290
1291                 gd_c[1] = jaguar_byte_read(0xF0226A);
1292                 gd_i[1] = jaguar_byte_read(0xF0226B);
1293                 gd_i[1] <<= 16;
1294                 gd_i[1] |= jaguar_word_read(0xF02242);
1295
1296                 gd_c[2] = jaguar_byte_read(0xF0226C);
1297                 gd_i[2] = jaguar_byte_read(0xF0226D);
1298                 gd_i[2] <<= 16;
1299                 gd_i[2] |= jaguar_word_read(0xF02244);
1300
1301                 gd_c[3] = jaguar_byte_read(0xF0226E);
1302                 gd_i[3] = jaguar_byte_read(0xF0226F);
1303                 gd_i[3] <<= 16; 
1304                 gd_i[3] |= jaguar_word_read(0xF02246);
1305
1306                 gd_ia = gouraud_add & 0xFFFFFF;
1307                 if (gd_ia & 0x800000)
1308                         gd_ia = 0xFF000000 | gd_ia;
1309
1310                 gd_ca = (gouraud_add>>24) & 0xFF;
1311                 if (gd_ca & 0x80)
1312                         gd_ca = 0xFFFFFF00 | gd_ca;
1313         }
1314
1315         // fix for zoop! and syndicate
1316 /*      if ((jaguar_mainRom_crc32==0x501be17c)||
1317                 (jaguar_mainRom_crc32==0x70895c51)||
1318                 (jaguar_mainRom_crc32==0x0f1f1497)||
1319                 (jaguar_mainRom_crc32==0xfc8f0dcd)
1320            )
1321         {
1322                 if (a1_step_x < 0)
1323                         a1_step_x = (-n_pixels) * 65536;
1324
1325                 if (a2_step_x < 0)
1326                         a2_step_x = (-n_pixels) * 65536;;
1327         }
1328         else
1329         // fix for wolfenstein 3d
1330         if (jaguar_mainRom_crc32==0x3966698f)
1331         {
1332                 if (n_pixels==24)
1333                 {
1334                         if ((a1_step_x / 65536)==-28)
1335                         {
1336                                 a1_step_x=-24*65536; // au lieu de -28
1337                                 a2_step_x=  0*65536; // au lieu de -8
1338                         }
1339                 }
1340         } 
1341         else
1342         // fix for Tempest 2000
1343         if (jaguar_mainRom_crc32==0x32816d44)
1344         {
1345
1346                 if ((n_lines!=1)&&((n_pixels==288)||(n_pixels==384)))
1347                 {
1348                         WriteLog("Blit!\n");
1349                         WriteLog("  cmd      = 0x%.8x\n",cmd);
1350                         WriteLog("  a1_base  = %08X\n", a1_addr);
1351                         WriteLog("  a1_pitch = %d\n", a1_pitch);
1352                         WriteLog("  a1_psize = %d\n", a1_psize);
1353                         WriteLog("  a1_width = %d\n", a1_width);
1354                         WriteLog("  a1_xadd  = %f (phrase=%d)\n", (float)a1_xadd / 65536.0, a1_phrase_mode);
1355                         WriteLog("  a1_yadd  = %f\n", (float)a1_yadd / 65536.0);
1356                         WriteLog("  a1_xstep = %f\n", (float)a1_step_x / 65536.0);
1357                         WriteLog("  a1_ystep = %f\n", (float)a1_step_y / 65536.0);
1358                         WriteLog("  a1_x     = %f\n", (float)a1_x / 65536.0);
1359                         WriteLog("  a1_y     = %f\n", (float)a1_y / 65536.0);
1360                         WriteLog("  a1_zoffs = %i\n",a1_zoffs);
1361
1362                         WriteLog("  a2_base  = %08X\n", a2_addr);
1363                         WriteLog("  a2_pitch = %d\n", a2_pitch);
1364                         WriteLog("  a2_psize = %d\n", a2_psize);
1365                         WriteLog("  a2_width = %d\n", a2_width);
1366                         WriteLog("  a2_xadd  = %f (phrase=%d)\n", (float)a2_xadd / 65536.0, a2_phrase_mode);
1367                         WriteLog("  a2_yadd  = %f\n", (float)a2_yadd / 65536.0);
1368                         WriteLog("  a2_xstep = %f\n", (float)a2_step_x / 65536.0);
1369                         WriteLog("  a2_ystep = %f\n", (float)a2_step_y / 65536.0);
1370                         WriteLog("  a2_x     = %f\n", (float)a2_x / 65536.0);
1371                         WriteLog("  a2_y     = %f\n", (float)a2_y / 65536.0);
1372                         WriteLog("  a2_mask_x= 0x%.4x\n",a2_mask_x);
1373                         WriteLog("  a2_mask_y= 0x%.4x\n",a2_mask_y);
1374                         WriteLog("  a2_zoffs = %i\n",a2_zoffs);
1375
1376                         WriteLog("  count    = %d x %d\n", n_pixels, n_lines);
1377
1378                         WriteLog("  command  = %08X\n", cmd);
1379                         WriteLog("  dsten    = %i\n",DSTEN);
1380                         WriteLog("  srcen    = %i\n",SRCEN);
1381                         WriteLog("  patdsel  = %i\n",PATDSEL);
1382                         WriteLog("  color    = 0x%.8x\n",REG(PATTERNDATA));
1383                         WriteLog("  dcompen  = %i\n",DCOMPEN);
1384                         WriteLog("  bcompen  = %i\n",BCOMPEN);
1385                         WriteLog("  cmpdst   = %i\n",CMPDST);
1386                         WriteLog("  GOURZ    = %i\n",GOURZ);
1387                         WriteLog("  GOURD    = %i\n",GOURD);
1388                         WriteLog("  SRCSHADE = %i\n",SRCSHADE);
1389                         WriteLog("  DSTDATA  = 0x%.8x%.8x\n",REG(DSTDATA),REG(DSTDATA+4));
1390                 }       
1391         }//*/
1392
1393 #ifdef LOG_BLITS
1394         if (start_logging)
1395         {
1396                 WriteLog("Blit!\n");
1397                 WriteLog("  cmd      = 0x%.8x\n",cmd);
1398                 WriteLog("  a1_base  = %08X\n", a1_addr);
1399                 WriteLog("  a1_pitch = %d\n", a1_pitch);
1400                 WriteLog("  a1_psize = %d\n", a1_psize);
1401                 WriteLog("  a1_width = %d\n", a1_width);
1402                 WriteLog("  a1_xadd  = %f (phrase=%d)\n", (float)a1_xadd / 65536.0, a1_phrase_mode);
1403                 WriteLog("  a1_yadd  = %f\n", (float)a1_yadd / 65536.0);
1404                 WriteLog("  a1_xstep = %f\n", (float)a1_step_x / 65536.0);
1405                 WriteLog("  a1_ystep = %f\n", (float)a1_step_y / 65536.0);
1406                 WriteLog("  a1_x     = %f\n", (float)a1_x / 65536.0);
1407                 WriteLog("  a1_y     = %f\n", (float)a1_y / 65536.0);
1408                 WriteLog("  a1_zoffs = %i\n",a1_zoffs);
1409
1410                 WriteLog("  a2_base  = %08X\n", a2_addr);
1411                 WriteLog("  a2_pitch = %d\n", a2_pitch);
1412                 WriteLog("  a2_psize = %d\n", a2_psize);
1413                 WriteLog("  a2_width = %d\n", a2_width);
1414                 WriteLog("  a2_xadd  = %f (phrase=%d)\n", (float)a2_xadd / 65536.0, a2_phrase_mode);
1415                 WriteLog("  a2_yadd  = %f\n", (float)a2_yadd / 65536.0);
1416                 WriteLog("  a2_xstep = %f\n", (float)a2_step_x / 65536.0);
1417                 WriteLog("  a2_ystep = %f\n", (float)a2_step_y / 65536.0);
1418                 WriteLog("  a2_x     = %f\n", (float)a2_x / 65536.0);
1419                 WriteLog("  a2_y     = %f\n", (float)a2_y / 65536.0);
1420                 WriteLog("  a2_mask_x= 0x%.4x\n",a2_mask_x);
1421                 WriteLog("  a2_mask_y= 0x%.4x\n",a2_mask_y);
1422                 WriteLog("  a2_zoffs = %i\n",a2_zoffs);
1423
1424                 WriteLog("  count    = %d x %d\n", n_pixels, n_lines);
1425
1426                 WriteLog("  command  = %08X\n", cmd);
1427                 WriteLog("  dsten    = %i\n",DSTEN);
1428                 WriteLog("  srcen    = %i\n",SRCEN);
1429                 WriteLog("  patdsel  = %i\n",PATDSEL);
1430                 WriteLog("  color    = 0x%.8x\n",REG(PATTERNDATA));
1431                 WriteLog("  dcompen  = %i\n",DCOMPEN);
1432                 WriteLog("  bcompen  = %i\n",BCOMPEN);
1433                 WriteLog("  cmpdst   = %i\n",CMPDST);
1434                 WriteLog("  GOURZ   = %i\n",GOURZ);
1435                 WriteLog("  GOURD   = %i\n",GOURD);
1436                 WriteLog("  SRCSHADE= %i\n",SRCSHADE);
1437         }       
1438 #endif
1439
1440 extern int blit_start_log;
1441 extern int op_start_log;
1442 if (blit_start_log)
1443 {
1444         char * ctrlStr[4] = { "XADDPHR\0", "XADDPIX\0", "XADD0\0", "XADDINC\0" };
1445         char * bppStr[8] = { "1bpp\0", "2bpp\0", "4bpp\0", "8bpp\0", "16bpp\0", "32bpp\0", "???\0", "!!!\0" };
1446         char * opStr[16] = { "LFU_CLEAR", "LFU_NSAND", "LFU_NSAD", "LFU_NOTS", "LFU_SAND", "LFU_NOTD", "LFU_N_SXORD", "LFU_NSORND",
1447                 "LFU_SAD", "LFU_XOR", "LFU_D", "LFU_NSORD", "LFU_REPLACE", "LFU_SORND", "LFU_SORD", "LFU_ONE" };
1448         uint32 src = cmd & 0x07, dst = (cmd >> 3) & 0x07, misc = (cmd >> 6) & 0x03,
1449                 a1ctl = (cmd >> 8) & 0x07, mode = (cmd >> 11) & 0x07, ity = (cmd >> 14) & 0x0F,
1450                 zop = (cmd >> 18) & 0x07, op = (cmd >> 21) & 0x0F, ctrl = (cmd >> 25) & 0x3F;
1451         UINT32 a1f = REG(A1_FLAGS), a2f = REG(A2_FLAGS);
1452         uint32 p1 = a1f & 0x07, p2 = a2f & 0x07,
1453                 d1 = (a1f >> 3) & 0x07, d2 = (a2f >> 3) & 0x07,
1454                 zo1 = (a1f >> 6) & 0x07, zo2 = (a2f >> 6) & 0x07,
1455                 w1 = (a1f >> 9) & 0x3F, w2 = (a2f >> 9) & 0x3F,
1456                 ac1 = (a1f >> 16) & 0x1F, ac2 = (a2f >> 16) & 0x1F;
1457         UINT32 iw1 = ((0x04 | (w1 & 0x03)) << ((w1 & 0x3C) >> 2)) >> 2;
1458         UINT32 iw2 = ((0x04 | (w2 & 0x03)) << ((w2 & 0x3C) >> 2)) >> 2;
1459         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);
1460 //      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);
1461
1462         WriteLog(" CMD -> src: %s%s%s ", (cmd & 0x0001 ? "SRCEN " : ""), (cmd & 0x0002 ? "SRCENZ " : ""), (cmd & 0x0004 ? "SRCENX" : ""));
1463         WriteLog("dst: %s%s%s ", (cmd & 0x0008 ? "DSTEN " : ""), (cmd & 0x0010 ? "DSTENZ " : ""), (cmd & 0x0020 ? "DSTWRZ" : ""));
1464         WriteLog("misc: %s%s ", (cmd & 0x0040 ? "CLIP_A1 " : ""), (cmd & 0x0080 ? "???" : ""));
1465         WriteLog("a1ctl: %s%s%s ", (cmd & 0x0100 ? "UPDA1F " : ""), (cmd & 0x0200 ? "UPDA1 " : ""), (cmd & 0x0400 ? "UPDA2" : ""));
1466         WriteLog("mode: %s%s%s ", (cmd & 0x0800 ? "DSTA2 " : ""), (cmd & 0x1000 ? "GOURD " : ""), (cmd & 0x2000 ? "ZBUFF" : ""));
1467         WriteLog("ity: %s%s%s ", (cmd & 0x4000 ? "TOPBEN " : ""), (cmd & 0x8000 ? "TOPNEN " : ""), (cmd & 0x00010000 ? "PATDSEL" : ""));
1468         WriteLog("z-op: %s%s%s ", (cmd & 0x00040000 ? "ZMODELT " : ""), (cmd & 0x00080000 ? "ZMODEEQ " : ""), (cmd & 0x00100000 ? "ZMODEGT" : ""));
1469         WriteLog("op: %s ", opStr[(cmd >> 21) & 0x0F]);
1470         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" : ""));
1471
1472         if (UPDA2)
1473         {
1474                 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);
1475         }
1476
1477         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"));
1478         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"));
1479         WriteLog("        x/y: %d/%d\n", a2_x >> 16, a2_y >> 16);
1480 //      blit_start_log = 0;
1481 //      op_start_log = 1;
1482 }
1483
1484         blitter_working = 1;
1485 #ifndef USE_GENERIC_BLITTER
1486         if (!blitter_execute_cached_code(blitter_in_cache(cmd)))
1487 #endif
1488                 blitter_generic(cmd);
1489
1490 /*if (blit_start_log)
1491 {
1492         if (a1_addr == 0xF03000 && a2_addr == 0x004D58)
1493         {
1494                 WriteLog("\nBytes at 004D58:\n");
1495                 for(int i=0x004D58; i<0x004D58+(10*127*4); i++)
1496                         WriteLog("%02X ", jaguar_byte_read(i));
1497                 WriteLog("\nBytes at F03000:\n");
1498                 for(int i=0xF03000; i<0xF03000+(6*127*4); i++)
1499                         WriteLog("%02X ", jaguar_byte_read(i));
1500                 WriteLog("\n\n");
1501         }
1502 }//*/
1503
1504         blitter_working = 0;
1505 }
1506
1507 uint32 blitter_long_read(uint32 offset)
1508 {
1509         return (blitter_word_read(offset) << 16) | blitter_word_read(offset+2);
1510 }
1511
1512 void blitter_long_write(uint32 offset, uint32 data)
1513 {
1514         blitter_word_write(offset, data >> 16);
1515         blitter_word_write(offset+2, data & 0xFFFF);
1516 }
1517
1518 void blitter_init(void)
1519 {
1520         if (!blitter_cache_init)
1521         {
1522                 for (int i=0;i<256;i++)
1523                 {
1524                         blitter_cache[i] = (struct s_blitter_cache *)malloc(sizeof(struct s_blitter_cache));
1525                         blitter_cache[i]->next=null;
1526                         blitter_cache[i]->prev=null;
1527                 }
1528                 blitter_cache_init = 1;
1529         }
1530 #ifndef USE_GENERIC_BLITTER
1531         #include "include/blit_i.h"
1532 #endif
1533
1534         blitter_reset();
1535 #ifdef GEN_CODE
1536         blitters_code_fp = fopen("include/blit_c.h", "awrt");
1537         blitters_code_init_fp = fopen("include/blit_i.h", "awrt");
1538 #endif
1539 }
1540
1541 void blitter_reset(void)
1542 {
1543         memset(blitter_ram, 0x00, 0xA0);
1544 }
1545
1546 void blitter_done(void)
1547 {
1548 //      blitter_list();
1549 #ifdef GEN_CODE
1550         fclose(blitters_code_fp);
1551         fclose(blitters_code_init_fp);
1552 #endif
1553         WriteLog("BLIT: Done.\n");
1554 }
1555
1556 void blitter_byte_write(uint32 offset, uint8 data)
1557 {
1558 /*if (offset & 0xFF == 0x7B)
1559 {
1560         WriteLog("--> Wrote to B_STOP: value -> %02X\n", data);
1561 }*/
1562         offset &= 0xFF;
1563
1564 //      if ((offset >= 0x7C) && (offset <= 0x9B))
1565         if ((offset >= 0x7C) && (offset <= 0x8B))
1566         {
1567                 switch (offset)
1568                 {
1569                 case 0x7C: break;
1570                 case 0x7D: blitter_ram[0x69] = data; break;
1571                 case 0x7E: blitter_ram[0x40] = data; break;
1572                 case 0x7F: blitter_ram[0x41] = data; break;
1573
1574                 case 0x80: break;
1575                 case 0x81: blitter_ram[0x6B] = data; break;
1576                 case 0x82: blitter_ram[0x42] = data; break;
1577                 case 0x83: blitter_ram[0x43] = data; break;
1578                 
1579                 case 0x84: break;
1580                 case 0x85: blitter_ram[0x6D] = data; break;
1581                 case 0x86: blitter_ram[0x44] = data; break;
1582                 case 0x87: blitter_ram[0x45] = data; break;
1583                 
1584                 case 0x88: break;
1585                 case 0x89: blitter_ram[0x6F] = data; break;
1586 //Mistyped?
1587 //              case 0x9A: blitter_ram[0x46] = data; break;
1588 //              case 0x9B: blitter_ram[0x47] = data; break;
1589                 case 0x8A: blitter_ram[0x46] = data; break;
1590                 case 0x8B: blitter_ram[0x47] = data; break;
1591                 }
1592         }
1593
1594         blitter_ram[offset] = data;
1595 }
1596
1597 void blitter_word_write(uint32 offset, uint16 data)
1598 {
1599         blitter_byte_write(offset+0, (data>>8) & 0xFF);
1600         blitter_byte_write(offset+1, data & 0xFF);
1601
1602         if ((offset & 0xFF) == 0x3A)
1603         // I.e., the second write of 32-bit value--not convinced this is the best way to do this!
1604         // But then again, according to the Jaguar docs, this is correct...!
1605                 blitter_blit(GET32(blitter_ram, 0x38));
1606 // Testing purposes only!
1607 //This does the clipping correctly, but not the Gouraud shading...
1608 //              blitter2_exec(GET32(blitter_ram, 0x38));
1609 }
1610 //F02278,9,A,B
1611
1612 uint8 blitter_byte_read(uint32 offset)
1613 {
1614         offset &= 0xFF;
1615
1616         // status register
1617         if (offset == (0x38 + 3))
1618                 return 0x01;    // always idle
1619
1620         return blitter_ram[offset];
1621 }
1622
1623 uint16 blitter_word_read(uint32 offset)
1624 {
1625         return ((uint16)blitter_byte_read(offset) << 8) | (uint16)blitter_byte_read(offset+1);
1626 }