]> Shamusworld >> Repos - virtualjaguar/blob - src/blitter.cpp
1.0.7 update
[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 bool specialLog = false;
9
10 #include "jaguar.h"
11
12 #define REG(A)  (((uint32)blitter_ram[(A)] << 24) | ((uint32)blitter_ram[(A)+1] << 16) \
13                                 | ((uint32)blitter_ram[(A)+2] << 8) | (uint32)blitter_ram[(A)+3])
14 #define WREG(A,D)       (blitter_ram[(A)] = ((D)>>24)&0xFF, blitter_ram[(A)+1] = ((D)>>16)&0xFF, \
15                                         blitter_ram[(A)+2] = ((D)>>8)&0xFF, blitter_ram[(A)+3] = (D)&0xFF)
16
17 // Blitter registers (offsets from F02200)
18
19 #define A1_BASE                 ((UINT32)0x00)
20 #define A1_FLAGS                ((UINT32)0x04)
21 #define A1_CLIP                 ((UINT32)0x08)  // Height and width values for clipping
22 #define A1_PIXEL                ((UINT32)0x0C)  // Integer part of the pixel (Y.i and X.i)
23 #define A1_STEP                 ((UINT32)0x10)  // Integer part of the step
24 #define A1_FSTEP                ((UINT32)0x14)  // Fractionnal part of the step
25 #define A1_FPIXEL               ((UINT32)0x18)  // Fractionnal part of the pixel (Y.f and X.f)
26 #define A1_INC                  ((UINT32)0x1C)  // Integer part of the increment
27 #define A1_FINC                 ((UINT32)0x20)  // Fractional part of the increment
28 #define A2_BASE                 ((UINT32)0x24)
29 #define A2_FLAGS                ((UINT32)0x28)
30 #define A2_MASK                 ((UINT32)0x2C)  // Modulo values for x and y (M.y  and M.x)
31 #define A2_PIXEL                ((UINT32)0x30)  // Integer part of the pixel (no fractional part for A2)
32 #define A2_STEP                 ((UINT32)0x34)  // Integer part of the step (no fractional part for A2)
33 #define COMMAND                 ((UINT32)0x38)
34 #define PIXLINECOUNTER  ((UINT32)0x3C)
35 #define SRCDATA                 ((UINT32)0x40)
36 #define DSTDATA                 ((UINT32)0x48)
37 #define DSTZ                    ((UINT32)0x50)
38 #define SRCZINT                 ((UINT32)0x58)
39 #define SRCZFRAC                ((UINT32)0x60)
40 #define PATTERNDATA             ((UINT32)0x68)
41 #define INTENSITYINC    ((UINT32)0x70)
42 #define ZINC                    ((UINT32)0x74)
43 #define COLLISIONCTRL   ((UINT32)0x78)
44 #define PHRASEINT3              ((UINT32)0x7C)
45 #define PHRASEINT2              ((UINT32)0x80)
46 #define PHRASEINT1              ((UINT32)0x84)
47 #define PHRASEINT0              ((UINT32)0x88)
48 #define PHRASEZ3                ((UINT32)0x8C)
49 #define PHRASEZ2                ((UINT32)0x90)
50 #define PHRASEZ1                ((UINT32)0x94)
51 #define PHRASEZ0                ((UINT32)0x98)
52
53 // Blitter command bits
54
55 #define SRCEN                   (cmd & 0x00000001)
56 #define SRCENZ                  (cmd & 0x00000002)
57 #define SRCENX                  (cmd & 0x00000004)
58 #define DSTEN                   (cmd & 0x00000008)
59 #define DSTENZ                  (cmd & 0x00000010)
60 #define DSTWRZ                  (cmd & 0x00000020)
61 #define CLIPA1                  (cmd & 0x00000040)
62
63 #define UPDA1F                  (cmd & 0x00000100)
64 #define UPDA1                   (cmd & 0x00000200)
65 #define UPDA2                   (cmd & 0x00000400)
66
67 #define DSTA2                   (cmd & 0x00000800)
68
69 #define Z_OP_INF                (cmd & 0x00040000)
70 #define Z_OP_EQU                (cmd & 0x00080000)
71 #define Z_OP_SUP                (cmd & 0x00100000)
72
73 #define LFU_NAN                 (cmd & 0x00200000)
74 #define LFU_NA                  (cmd & 0x00400000)
75 #define LFU_AN                  (cmd & 0x00800000)
76 #define LFU_A                   (cmd & 0x01000000)
77
78 #define CMPDST                  (cmd & 0x02000000)
79 #define BCOMPEN                 (cmd & 0x04000000)
80 #define DCOMPEN                 (cmd & 0x08000000)
81
82 #define PATDSEL                 (cmd & 0x00010000)
83 #define INTADD                  (cmd & 0x00020000)
84 #define TOPBEN                  (cmd & 0x00004000)
85 #define TOPNEN                  (cmd & 0x00008000)
86 #define BKGWREN                 (cmd & 0x10000000)
87 #define GOURD                   (cmd & 0x00001000)
88 #define GOURZ                   (cmd & 0x00002000)
89 #define SRCSHADE                (cmd & 0x40000000)
90
91
92 #define XADDPHR  0
93 #define XADDPIX  1
94 #define XADD0    2
95 #define XADDINC  3
96
97 #define XSIGNSUB_A1             (REG(A1_FLAGS)&0x080000)
98 #define XSIGNSUB_A2             (REG(A2_FLAGS)&0x080000)
99
100 #define YSIGNSUB_A1             (REG(A1_FLAGS)&0x100000)
101 #define YSIGNSUB_A2             (REG(A2_FLAGS)&0x100000)
102
103 #define YADD1_A1                (REG(A1_FLAGS)&0x040000)
104 #define YADD1_A2                (REG(A2_FLAGS)&0x040000)
105
106 //Put 'em back, once we fix the problem!!! [KO]
107 // 1 bpp pixel read
108 #define PIXEL_SHIFT_1(a)      (((~a##_x) >> 16) & 7)
109 #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))
110 #define READ_PIXEL_1(a)       ((JaguarReadByte(a##_addr+PIXEL_OFFSET_1(a), BLITTER) >> PIXEL_SHIFT_1(a)) & 0x01)
111 //#define READ_PIXEL_1(a)       ((JaguarReadByte(a##_addr+PIXEL_OFFSET_1(a)) >> PIXEL_SHIFT_1(a)) & 0x01)
112
113 // 2 bpp pixel read
114 #define PIXEL_SHIFT_2(a)      (((~a##_x) >> 15) & 6)
115 #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))
116 #define READ_PIXEL_2(a)       ((JaguarReadByte(a##_addr+PIXEL_OFFSET_2(a), BLITTER) >> PIXEL_SHIFT_2(a)) & 0x03)
117 //#define READ_PIXEL_2(a)       ((JaguarReadByte(a##_addr+PIXEL_OFFSET_2(a)) >> PIXEL_SHIFT_2(a)) & 0x03)
118
119 // 4 bpp pixel read
120 #define PIXEL_SHIFT_4(a)      (((~a##_x) >> 14) & 4)
121 #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))
122 #define READ_PIXEL_4(a)       ((JaguarReadByte(a##_addr+PIXEL_OFFSET_4(a), BLITTER) >> PIXEL_SHIFT_4(a)) & 0x0f)
123 //#define READ_PIXEL_4(a)       ((JaguarReadByte(a##_addr+PIXEL_OFFSET_4(a)) >> PIXEL_SHIFT_4(a)) & 0x0f)
124
125 // 8 bpp pixel read
126 #define PIXEL_OFFSET_8(a)     (((((UINT32)a##_y >> 16) * a##_width) + (((UINT32)a##_x >> 16) & ~7)) * (1 + a##_pitch) + (((UINT32)a##_x >> 16) & 7))
127 #define READ_PIXEL_8(a)       (JaguarReadByte(a##_addr+PIXEL_OFFSET_8(a), BLITTER))
128 //#define READ_PIXEL_8(a)       (JaguarReadByte(a##_addr+PIXEL_OFFSET_8(a)))
129
130 // 16 bpp pixel read
131 #define PIXEL_OFFSET_16(a)    (((((UINT32)a##_y >> 16) * a##_width) + (((UINT32)a##_x >> 16) & ~3)) * (1 + a##_pitch) + (((UINT32)a##_x >> 16) & 3))
132 #define READ_PIXEL_16(a)       (JaguarReadWord(a##_addr+(PIXEL_OFFSET_16(a)<<1), BLITTER))
133 //#define READ_PIXEL_16(a)       (JaguarReadWord(a##_addr+(PIXEL_OFFSET_16(a)<<1)))
134
135 // 32 bpp pixel read
136 #define PIXEL_OFFSET_32(a)    (((((UINT32)a##_y >> 16) * a##_width) + (((UINT32)a##_x >> 16) & ~1)) * (1 + a##_pitch) + (((UINT32)a##_x >> 16) & 1))
137 #define READ_PIXEL_32(a)      (JaguarReadLong(a##_addr+(PIXEL_OFFSET_32(a)<<2), BLITTER))
138 //#define READ_PIXEL_32(a)      (JaguarReadLong(a##_addr+(PIXEL_OFFSET_32(a)<<2)))
139
140 // pixel read
141 #define READ_PIXEL(a,f) (\
142          (((f>>3)&0x07) == 0) ? (READ_PIXEL_1(a)) : \
143          (((f>>3)&0x07) == 1) ? (READ_PIXEL_2(a)) : \
144          (((f>>3)&0x07) == 2) ? (READ_PIXEL_4(a)) : \
145          (((f>>3)&0x07) == 3) ? (READ_PIXEL_8(a)) : \
146          (((f>>3)&0x07) == 4) ? (READ_PIXEL_16(a)) : \
147          (((f>>3)&0x07) == 5) ? (READ_PIXEL_32(a)) : 0)
148
149 // 16 bpp z data read
150 #define ZDATA_OFFSET_16(a)     (PIXEL_OFFSET_16(a) + a##_zoffs * 4)
151 #define READ_ZDATA_16(a)       (JaguarReadWord(a##_addr+(ZDATA_OFFSET_16(a)<<1), BLITTER))
152 //#define READ_ZDATA_16(a)       (JaguarReadWord(a##_addr+(ZDATA_OFFSET_16(a)<<1)))
153
154 // z data read
155 #define READ_ZDATA(a,f) (READ_ZDATA_16(a))
156
157 // 16 bpp z data write
158 #define WRITE_ZDATA_16(a,d)     {  JaguarWriteWord(a##_addr+(ZDATA_OFFSET_16(a)<<1), d, BLITTER); }
159 //#define WRITE_ZDATA_16(a,d)     {  JaguarWriteWord(a##_addr+(ZDATA_OFFSET_16(a)<<1), d); }
160
161 // z data write
162 #define WRITE_ZDATA(a,f,d) WRITE_ZDATA_16(a,d); 
163
164 // 1 bpp r data read
165 #define READ_RDATA_1(r,a,p)  ((p) ?  ((REG(r+(((UINT32)a##_x>>19)&4)))>>(((UINT32)a##_x>>16)&0x1f))&   0x1 : (REG(r) &    0x1))
166
167 // 2 bpp r data read
168 #define READ_RDATA_2(r,a,p)  ((p) ?  ((REG(r+(((UINT32)a##_x>>18)&4)))>>(((UINT32)a##_x>>15)&0x3e))&   0x3 : (REG(r) &    0x3))
169
170 // 4 bpp r data read
171 #define READ_RDATA_4(r,a,p)  ((p) ?  ((REG(r+(((UINT32)a##_x>>17)&4)))>>(((UINT32)a##_x>>14)&0x28))&   0xf : (REG(r) &    0xf))
172
173 // 8 bpp r data read
174 #define READ_RDATA_8(r,a,p)  ((p) ?  ((REG(r+(((UINT32)a##_x>>16)&4)))>>(((UINT32)a##_x>>13)&0x18))&  0xff : (REG(r) &   0xff))
175
176 // 16 bpp r data read
177 #define READ_RDATA_16(r,a,p)  ((p) ? ((REG(r+(((UINT32)a##_x>>15)&4)))>>(((UINT32)a##_x>>12)&0x10))&0xffff : (REG(r) & 0xffff))
178
179 // 32 bpp r data read
180 #define READ_RDATA_32(r,a,p)  ((p) ? REG(r+(((UINT32)a##_x>>14)&4)) : REG(r))
181
182 // register data read
183 #define READ_RDATA(r,a,f,p) (\
184          (((f>>3)&0x07) == 0) ? (READ_RDATA_1(r,a,p)) : \
185          (((f>>3)&0x07) == 1) ? (READ_RDATA_2(r,a,p)) : \
186          (((f>>3)&0x07) == 2) ? (READ_RDATA_4(r,a,p)) : \
187          (((f>>3)&0x07) == 3) ? (READ_RDATA_8(r,a,p)) : \
188          (((f>>3)&0x07) == 4) ? (READ_RDATA_16(r,a,p)) : \
189          (((f>>3)&0x07) == 5) ? (READ_RDATA_32(r,a,p)) : 0)
190
191 // 1 bpp pixel write
192 #define WRITE_PIXEL_1(a,d)       { JaguarWriteByte(a##_addr+PIXEL_OFFSET_1(a), (JaguarReadByte(a##_addr+PIXEL_OFFSET_1(a), BLITTER)&(~(0x01 << PIXEL_SHIFT_1(a))))|(d<<PIXEL_SHIFT_1(a)), BLITTER); }
193 //#define WRITE_PIXEL_1(a,d)       { JaguarWriteByte(a##_addr+PIXEL_OFFSET_1(a), (JaguarReadByte(a##_addr+PIXEL_OFFSET_1(a))&(~(0x01 << PIXEL_SHIFT_1(a))))|(d<<PIXEL_SHIFT_1(a))); }
194
195 // 2 bpp pixel write
196 #define WRITE_PIXEL_2(a,d)       { JaguarWriteByte(a##_addr+PIXEL_OFFSET_2(a), (JaguarReadByte(a##_addr+PIXEL_OFFSET_2(a), BLITTER)&(~(0x03 << PIXEL_SHIFT_2(a))))|(d<<PIXEL_SHIFT_2(a)), BLITTER); }
197 //#define WRITE_PIXEL_2(a,d)       { JaguarWriteByte(a##_addr+PIXEL_OFFSET_2(a), (JaguarReadByte(a##_addr+PIXEL_OFFSET_2(a))&(~(0x03 << PIXEL_SHIFT_2(a))))|(d<<PIXEL_SHIFT_2(a))); }
198
199 // 4 bpp pixel write
200 #define WRITE_PIXEL_4(a,d)       { JaguarWriteByte(a##_addr+PIXEL_OFFSET_4(a), (JaguarReadByte(a##_addr+PIXEL_OFFSET_4(a), BLITTER)&(~(0x0f << PIXEL_SHIFT_4(a))))|(d<<PIXEL_SHIFT_4(a)), BLITTER); }
201 //#define WRITE_PIXEL_4(a,d)       { JaguarWriteByte(a##_addr+PIXEL_OFFSET_4(a), (JaguarReadByte(a##_addr+PIXEL_OFFSET_4(a))&(~(0x0f << PIXEL_SHIFT_4(a))))|(d<<PIXEL_SHIFT_4(a))); }
202
203 // 8 bpp pixel write
204 #define WRITE_PIXEL_8(a,d)       { JaguarWriteByte(a##_addr+PIXEL_OFFSET_8(a), d, BLITTER); }
205 //#define WRITE_PIXEL_8(a,d)       { JaguarWriteByte(a##_addr+PIXEL_OFFSET_8(a), d); }
206
207 // 16 bpp pixel write
208 //#define WRITE_PIXEL_16(a,d)     {  JaguarWriteWord(a##_addr+(PIXEL_OFFSET_16(a)<<1),d); }
209 #define WRITE_PIXEL_16(a,d)     {  JaguarWriteWord(a##_addr+(PIXEL_OFFSET_16(a)<<1), d, BLITTER); if (specialLog) WriteLog("Pixel write address: %08X\n", a##_addr+(PIXEL_OFFSET_16(a)<<1)); }
210 //#define WRITE_PIXEL_16(a,d)     {  JaguarWriteWord(a##_addr+(PIXEL_OFFSET_16(a)<<1), d); if (specialLog) WriteLog("Pixel write address: %08X\n", a##_addr+(PIXEL_OFFSET_16(a)<<1)); }
211
212 // 32 bpp pixel write
213 #define WRITE_PIXEL_32(a,d)             { JaguarWriteLong(a##_addr+(PIXEL_OFFSET_32(a)<<2), d, BLITTER); } 
214 //#define WRITE_PIXEL_32(a,d)           { JaguarWriteLong(a##_addr+(PIXEL_OFFSET_32(a)<<2), d); } 
215
216 // pixel write
217 #define WRITE_PIXEL(a,f,d) {\
218         switch ((f>>3)&0x07) { \
219         case 0: WRITE_PIXEL_1(a,d);  break;  \
220         case 1: WRITE_PIXEL_2(a,d);  break;  \
221         case 2: WRITE_PIXEL_4(a,d);  break;  \
222         case 3: WRITE_PIXEL_8(a,d);  break;  \
223         case 4: WRITE_PIXEL_16(a,d); break;  \
224         case 5: WRITE_PIXEL_32(a,d); break;  \
225         }}
226
227 // External global variables
228
229 extern int jaguar_active_memory_dumps;
230
231 // Local global variables
232
233 int start_logging = 0;
234 uint8 blitter_working = 0;
235
236 // Blitter register RAM (most of it is hidden from the user)
237
238 static uint8 blitter_ram[0x100];
239
240 // Width in Pixels of a Scanline
241 // This is a pretranslation of the value found in the A1 & A2 flags: It's really a floating point value
242 // of the form EEEEMM where MM is the mantissa with an implied "1." in front of it and the EEEE value is
243 // the exponent. Valid values for the exponent range from 0 to 11 (decimal). It's easiest to think of it
244 // as a floating point bit pattern being followed by a number of zeroes. So, e.g., 001101 translates to
245 // 1.01 (the "1." being implied) x (2 ^ 3) or 1010 -> 10 in base 10 (i.e., 1.01 with the decimal place
246 // being shifted to the right 3 places).
247 static uint32 blitter_scanline_width[48] = 
248 {             
249      0,    0,    0,    0,                                       // Note: This would really translate to 1, 1, 1, 1
250      2,    0,    0,    0,
251      4,    0,    6,    0,
252      8,   10,   12,   14,
253     16,   20,   24,   28,
254     32,   40,   48,   56,
255     64,   80,   96,  112,
256    128,  160,  192,  224,
257    256,  320,  384,  448,
258    512,  640,  768,  896,
259   1024, 1280, 1536, 1792,
260   2048, 2560, 3072, 3584
261 };
262
263 //static uint8 * tom_ram_8;
264 //static uint8 * paletteRam;
265 static uint8 src;
266 static uint8 dst;
267 static uint8 misc;
268 static uint8 a1ctl;
269 static uint8 mode;
270 static uint8 ity;
271 static uint8 zop;
272 static uint8 op;
273 static uint8 ctrl;
274 static uint32 a1_addr;
275 static uint32 a2_addr;
276 static int32 a1_zoffs;
277 static int32 a2_zoffs;
278 static uint32 xadd_a1_control;
279 static uint32 xadd_a2_control;
280 static int32 a1_pitch;
281 static int32 a2_pitch;
282 static uint32 n_pixels;
283 static uint32 n_lines;
284 static int32 a1_x;
285 static int32 a1_y;
286 static int32 a1_width;
287 static int32 a2_x;
288 static int32 a2_y;
289 static int32 a2_width;
290 static int32 a2_mask_x;
291 static int32 a2_mask_y;
292 static int32 a1_xadd;
293 static int32 a1_yadd;
294 static int32 a2_xadd;
295 static int32 a2_yadd;
296 static uint8 a1_phrase_mode;
297 static uint8 a2_phrase_mode;
298 static int32 a1_step_x = 0;
299 static int32 a1_step_y = 0;
300 static int32 a2_step_x = 0;
301 static int32 a2_step_y = 0;
302 static uint32 outer_loop;
303 static uint32 inner_loop;
304 static uint32 a2_psize;
305 static uint32 a1_psize;
306 static uint32 gouraud_add;
307 //static uint32 gouraud_data;
308 //static uint16 gint[4];
309 //static uint16 gfrac[4];
310 //static uint8  gcolour[4];
311 static int gd_i[4];
312 static int gd_c[4];
313 static int gd_ia, gd_ca;
314 static int colour_index = 0;
315 static int32 zadd;
316 static uint32 z_i[4];
317
318 static int32 a1_clip_x, a1_clip_y;
319
320 // In the spirit of "get it right first, *then* optimize" I've taken the liberty
321 // of removing all the unnecessary code caching. If it turns out to be a good way
322 // to optimize the blitter, then we may revisit it in the future...
323
324 //
325 // Generic blit handler
326 //
327 void blitter_generic(uint32 cmd)
328 {
329 //Testing only!
330 //uint32 logGo = ((cmd == 0x01800E01 && REG(A1_BASE) == 0x898000) ? 1 : 0);
331         uint32 srcdata, srczdata, dstdata, dstzdata, writedata, inhibit;
332
333 if (specialLog)
334 {
335         WriteLog("About to do 8x8 blit (BM width is 448 pixels)...\n");
336 }
337         while (outer_loop--)
338         {
339 if (specialLog)
340 {
341         WriteLog("  A1_X/Y = %08X/%08X, A2_X/Y = %08X/%08X\n", a1_x, a1_y, a2_x, a2_y);
342 }
343                 uint32 a1_start = a1_x, a2_start = a2_x;
344
345                 inner_loop = n_pixels;
346                 while (inner_loop--)
347                 {
348 if (specialLog)
349 {
350         WriteLog("    A1_X/Y = %08X/%08X, A2_X/Y = %08X/%08X\n", a1_x, a1_y, a2_x, a2_y);
351 }
352                         srcdata = srczdata = dstdata = dstzdata = writedata = inhibit = 0;
353
354                         if (!DSTA2)
355                         {
356                                 // load src data and Z
357                                 if (SRCEN)
358                                 {
359                                         srcdata = READ_PIXEL(a2, REG(A2_FLAGS));
360                                         if (SRCENZ)
361                                                 srczdata = READ_ZDATA(a2, REG(A2_FLAGS));
362                                         else if (cmd & 0x0001C020)
363                                                 srczdata = READ_RDATA(SRCZINT, a2, REG(A2_FLAGS), a2_phrase_mode);
364                                 }
365                                 else
366                                 {
367                                         srcdata = READ_RDATA(SRCDATA, a2, REG(A2_FLAGS), a2_phrase_mode);
368                                         if (cmd & 0x0001C020)
369                                                 srczdata = READ_RDATA(SRCZINT, a2, REG(A2_FLAGS), a2_phrase_mode);
370                                 }
371
372                                 // load dst data and Z 
373                                 if (DSTEN)
374                                 {
375                                         dstdata = READ_PIXEL(a1, REG(A1_FLAGS));
376                                         if (DSTENZ)
377                                                 dstzdata = READ_ZDATA(a1, REG(A1_FLAGS));
378                                         else
379                                                 dstzdata = READ_RDATA(DSTZ, a1, REG(A1_FLAGS), a1_phrase_mode);
380                                 }
381                                 else
382                                 {
383                                         dstdata = READ_RDATA(DSTDATA, a1, REG(A1_FLAGS), a1_phrase_mode);
384                                         if (DSTENZ)
385                                                 dstzdata = READ_RDATA(DSTZ, a1, REG(A1_FLAGS), a1_phrase_mode);
386                                 }
387
388 /*This wasn't working...                                // a1 clipping
389                                 if (cmd & 0x00000040)
390                                 {
391                                         if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7FFF)
392                                                 || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7FFF))
393                                                 inhibit = 1;
394                                 }//*/
395
396                                 if (GOURZ) 
397                                         srczdata = z_i[colour_index] >> 16;
398
399                                 // apply z comparator
400                                 if (Z_OP_INF) if (srczdata <  dstzdata) inhibit = 1;
401                                 if (Z_OP_EQU) if (srczdata == dstzdata) inhibit = 1;
402                                 if (Z_OP_SUP) if (srczdata >  dstzdata) inhibit = 1;
403                                 
404                                 // apply data comparator
405 // Note: DCOMPEN only works in 8/16 bpp modes! !!! FIX !!!
406 // Does BCOMPEN only work in 1 bpp mode???
407                                 if (DCOMPEN | BCOMPEN)
408                                 {
409                                         if (!CMPDST)
410                                         {
411 //WriteLog("Blitter: BCOMPEN set on command %08X inhibit prev:%u, now:", cmd, inhibit);
412                                                 // compare source pixel with pattern pixel
413 /*
414 Blit! (000B8250 <- 0012C3A0) count: 16 x 1, A1/2_FLAGS: 00014420/00012000 [cmd: 05810001]
415  CMD -> src: SRCEN  dst:  misc:  a1ctl:  mode:  ity: PATDSEL z-op:  op: LFU_REPLACE ctrl: BCOMPEN 
416   A1 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 384 (22), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
417   A2 -> pitch: 1 phrases, depth: 1bpp, z-off: 0, width: 16 (10), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
418         x/y: 0/20
419 ...
420 */
421 // AvP is still wrong, could be cuz it's doing A1 -> A2...
422
423 // Src is the 1bpp bitmap... DST is the PATTERN!!!
424 // This seems to solve at least ONE of the problems with MC3D...
425 // Why should this be inverted???
426 // Bcuz it is. This is supposed to be used only for a bit -> pixel expansion...
427 /*                                              if (srcdata == READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode))
428 //                                              if (srcdata != READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode))
429                                                         inhibit = 1;//*/
430 /*                                              uint32 A2bpp = 1 << ((REG(A2_FLAGS) >> 3) & 0x07);
431                                                 if (A2bpp == 1 || A2bpp == 16 || A2bpp == 8)
432                                                         inhibit = (srcdata == 0 ? 1: 0);
433 //                                                      inhibit = !srcdata;
434                                                 else
435                                                         WriteLog("Blitter: Bad BPP (%u) selected for BCOMPEN mode!\n", A2bpp);//*/
436 // What it boils down to is this:
437                                                 if (srcdata == 0)
438                                                         inhibit = 1;//*/
439                                         }
440                                         else
441                                         {
442                                                 // compare destination pixel with pattern pixel
443                                                 if (dstdata == READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode))
444 //                                              if (dstdata != READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode))
445                                                         inhibit = 1;
446                                         }
447
448 // This is DEFINITELY WRONG
449 //                                      if (a1_phrase_mode || a2_phrase_mode)
450 //                                              inhibit = !inhibit;
451                                 }
452
453                                 if (CLIPA1)
454                                 {
455                                         inhibit |= (((a1_x >> 16) < a1_clip_x && (a1_x >> 16) >= 0
456                                                 && (a1_y >> 16) < a1_clip_y && (a1_y >> 16) >= 0) ? 0 : 1);
457                                 }
458
459                                 // compute the write data and store
460                                 if (!inhibit)
461                                 {                       
462                                         if (PATDSEL)
463                                         {
464                                                 // use pattern data for write data
465                                                 writedata = READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode);
466                                         }
467                                         else if (INTADD)
468                                         {
469                                                 // intensity addition
470                                                 writedata = (srcdata & 0xFF) + (dstdata & 0xFF);
471                                                 if (!(TOPBEN) && writedata > 0xFF)
472                                                         writedata = 0xFF;
473                                                 writedata |= (srcdata & 0xF00) + (dstdata & 0xF00);
474                                                 if (!(TOPNEN) && writedata > 0xFFF)
475                                                         writedata = 0xFFF;
476                                                 writedata |= (srcdata & 0xF000) + (dstdata & 0xF000);
477                                         }
478                                         else
479                                         {
480                                                 if (LFU_NAN) writedata |= ~srcdata & ~dstdata;
481                                                 if (LFU_NA)  writedata |= ~srcdata & dstdata;
482                                                 if (LFU_AN)  writedata |= srcdata  & ~dstdata;
483                                                 if (LFU_A)       writedata |= srcdata  & dstdata;
484                                         }
485
486                                         if (GOURD) 
487                                                 writedata = ((gd_c[colour_index]) << 8) | (gd_i[colour_index] >> 16);
488
489                                         if (SRCSHADE) 
490                                         {
491                                                 int intensity = srcdata & 0xFF;
492                                                 int ia = gd_ia >> 16;
493                                                 if (ia & 0x80)
494                                                         ia = 0xFFFFFF00 | ia;
495                                                 intensity += ia;
496                                                 if (intensity < 0)
497                                                         intensity = 0;
498                                                 if (intensity > 0xFF)
499                                                         intensity = 0xFF;
500                                                 writedata = (srcdata & 0xFF00) | intensity;
501                                         }
502                                 }
503                                 else
504                                 {
505                                         writedata = dstdata;
506                                         srczdata = dstzdata;
507                                 }
508
509                                 if (/*a1_phrase_mode || */BKGWREN || !inhibit)
510                                 {
511 /*if (((REG(A1_FLAGS) >> 3) & 0x07) == 5)
512 {
513         uint32 offset = a1_addr+(PIXEL_OFFSET_32(a1)<<2);
514 // (((((UINT32)a##_y >> 16) * a##_width) + (((UINT32)a##_x >> 16) & ~1)) * (1 + a##_pitch) + (((UINT32)a##_x >> 16) & 1))
515         if ((offset >= 0x1FF020 && offset <= 0x1FF03F) || (offset >= 0x1FF820 && offset <= 0x1FF83F))
516                 WriteLog("32bpp pixel write: A1 Phrase mode --> ");
517 }//*/
518                                         // write to the destination
519                                         WRITE_PIXEL(a1, REG(A1_FLAGS), writedata);
520                                         if (DSTWRZ)
521                                                 WRITE_ZDATA(a1, REG(A1_FLAGS), srczdata);
522                                 }
523                         }
524                         else    // if (DSTA2)
525                         {
526                                 // load src data and Z
527                                 if (SRCEN)
528                                 {
529                                         srcdata = READ_PIXEL(a1, REG(A1_FLAGS));
530                                         if (SRCENZ)
531                                                 srczdata = READ_ZDATA(a1, REG(A1_FLAGS));
532                                         else if (cmd & 0x0001C020)
533                                                 srczdata = READ_RDATA(SRCZINT, a1, REG(A1_FLAGS), a1_phrase_mode);
534                                 }
535                                 else
536                                 {
537                                         srcdata = READ_RDATA(SRCDATA, a1, REG(A1_FLAGS), a1_phrase_mode);
538                                         if (cmd & 0x001C020)
539                                                 srczdata = READ_RDATA(SRCZINT, a1, REG(A1_FLAGS), a1_phrase_mode);
540                                 }
541
542                                 // load dst data and Z 
543                                 if (DSTEN)
544                                 {
545                                         dstdata = READ_PIXEL(a2, REG(A2_FLAGS));
546                                         if (DSTENZ)
547                                                 dstzdata = READ_ZDATA(a2, REG(A2_FLAGS));
548                                         else
549                                                 dstzdata = READ_RDATA(DSTZ, a2, REG(A2_FLAGS), a2_phrase_mode);
550                                 }
551                                 else
552                                 {
553                                         dstdata = READ_RDATA(DSTDATA, a2, REG(A2_FLAGS), a2_phrase_mode);
554                                         if (DSTENZ)
555                                                 dstzdata = READ_RDATA(DSTZ, a2, REG(A2_FLAGS), a2_phrase_mode);
556                                 }
557
558                                 if (GOURZ) 
559                                         srczdata = z_i[colour_index] >> 16;
560
561                                 // apply z comparator
562                                 if (Z_OP_INF) if (srczdata < dstzdata)  inhibit = 1;
563                                 if (Z_OP_EQU) if (srczdata == dstzdata) inhibit = 1;
564                                 if (Z_OP_SUP) if (srczdata > dstzdata)  inhibit = 1;
565                                 
566                                 // apply data comparator
567 //NOTE: The bit comparator (BCOMPEN) is NOT the same at the data comparator!
568                                 if (DCOMPEN | BCOMPEN)
569                                 {
570                                         if (!CMPDST)
571                                         {
572                                                 // compare source pixel with pattern pixel
573 // AvP: Numbers are correct, but sprites are not!
574 //This doesn't seem to be a problem... But could still be wrong...
575 /*                                              if (srcdata == READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode))
576 //                                              if (srcdata != READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode))
577                                                         inhibit = 1;//*/
578 // This is probably not 100% correct... It works in the 1bpp case
579 // (in A1 <- A2 mode, that is...)
580 // AvP: This is causing blocks to be written instead of bit patterns...
581 // Works now...
582 // NOTE: We really should separate out the BCOMPEN & DCOMPEN stuff!
583 /*                                              uint32 A1bpp = 1 << ((REG(A1_FLAGS) >> 3) & 0x07);
584                                                 if (A1bpp == 1 || A1bpp == 16 || A1bpp == 8)
585                                                         inhibit = (srcdata == 0 ? 1: 0);
586                                                 else
587                                                         WriteLog("Blitter: Bad BPP (%u) selected for BCOMPEN mode!\n", A1bpp);//*/
588 // What it boils down to is this:
589                                                 if (srcdata == 0)
590                                                         inhibit = 1;//*/
591                                         }
592                                         else
593                                         {
594                                                 // compare destination pixel with pattern pixel
595                                                 if (dstdata == READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode))
596 //                                              if (dstdata != READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode))
597                                                         inhibit = 1;
598                                         }
599
600 // This is DEFINITELY WRONG
601 //                                      if (a1_phrase_mode || a2_phrase_mode)
602 //                                              inhibit = !inhibit;
603                                 }
604                                 
605                                 if (CLIPA1)
606                                 {
607                                         inhibit |= (((a1_x >> 16) < a1_clip_x && (a1_x >> 16) >= 0
608                                                 && (a1_y >> 16) < a1_clip_y && (a1_y >> 16) >= 0) ? 0 : 1);
609                                 }
610
611                                 // compute the write data and store
612                                 if (!inhibit)
613                                 {                       
614                                         if (PATDSEL)
615                                         {
616                                                 // use pattern data for write data
617                                                 writedata= READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode);
618                                         }
619                                         else if (INTADD)
620                                         {
621                                                 // intensity addition
622                                                 writedata = (srcdata & 0xFF) + (dstdata & 0xFF);
623                                                 if (!(TOPBEN) && writedata > 0xFF)
624                                                         writedata = 0xFF;
625                                                 writedata |= (srcdata & 0xF00) + (dstdata & 0xF00);
626                                                 if (!(TOPNEN) && writedata > 0xFFF)
627                                                         writedata = 0xFFF;
628                                                 writedata |= (srcdata & 0xF000) + (dstdata & 0xF000);
629                                         }
630                                         else
631                                         {
632                                                 if (LFU_NAN)
633                                                         writedata |= ~srcdata & ~dstdata;
634                                                 if (LFU_NA)
635                                                         writedata |= ~srcdata & dstdata;
636                                                 if (LFU_AN)
637                                                         writedata |= srcdata & ~dstdata;
638                                                 if (LFU_A)
639                                                         writedata |= srcdata & dstdata;
640                                         }
641
642                                         if (GOURD) 
643                                                 writedata = ((gd_c[colour_index]) << 8) | (gd_i[colour_index] >> 16);
644
645                                         if (SRCSHADE) 
646                                         {
647                                                 int intensity = srcdata & 0xFF;
648                                                 int ia = gd_ia >> 16;
649                                                 if (ia & 0x80)
650                                                         ia = 0xFFFFFF00 | ia;
651                                                 intensity += ia;
652                                                 if (intensity < 0)
653                                                         intensity = 0;
654                                                 if (intensity > 0xFF)
655                                                         intensity = 0xFF;
656                                                 writedata = (srcdata & 0xFF00) | intensity;
657                                         }
658                                 }
659                                 else
660                                 {
661                                         writedata = dstdata;
662                                         srczdata = dstzdata;
663                                 }
664
665                                 if (/*a2_phrase_mode || */BKGWREN || !inhibit)
666                                 {
667 /*if (logGo)
668 {
669         uint32 offset = a2_addr+(PIXEL_OFFSET_16(a2)<<1);
670 // (((((UINT32)a##_y >> 16) * a##_width) + (((UINT32)a##_x >> 16) & ~1)) * (1 + a##_pitch) + (((UINT32)a##_x >> 16) & 1))
671         WriteLog("[%08X:%04X] ", offset, writedata);
672 }//*/
673                                         // write to the destination
674                                         WRITE_PIXEL(a2, REG(A2_FLAGS), writedata);
675                                         if (DSTWRZ)
676                                                 WRITE_ZDATA(a2, REG(A2_FLAGS), srczdata);
677                                 }
678                         }
679
680                         // update x and y
681                         a1_x += a1_xadd;
682                         a1_y += a1_yadd;
683                         a2_x = (a2_x + a2_xadd) & a2_mask_x;
684                         a2_y = (a2_y + a2_yadd) & a2_mask_y;
685
686                         if (GOURZ)
687                                 z_i[colour_index] += zadd;
688
689                         if (GOURD || SRCSHADE)
690                         {
691                                 gd_i[colour_index] += gd_ia;
692                                 gd_c[colour_index] += gd_ca;
693                         }
694                         if (GOURD || SRCSHADE || GOURZ)
695                         {
696                                 if (a1_phrase_mode)
697                                         colour_index = (colour_index + 1) & 0x03;
698                         }
699                 }
700
701                 //New: Phrase mode taken into account! :-p
702                 if (a1_phrase_mode)
703                 {
704                         // Bump the pointer to the next phrase boundary
705                         // Even though it works, this is crappy... Clean it up!
706                         uint32 size = 64 / a1_psize;
707
708                         // Crappy kludge... ('aligning' source to destination)
709                         if (a2_phrase_mode && DSTA2)
710                         {
711                                 uint32 extra = (a2_start >> 16) % size;
712                                 a1_x += extra << 16;
713                         }
714
715                         uint32 newx = (a1_x >> 16) / size;
716                         uint32 newxrem = (a1_x >> 16) % size;
717                         a1_x &= 0x0000FFFF;
718                         a1_x |= (((newx + (newxrem == 0 ? 0 : 1)) * size) & 0xFFFF) << 16;
719                 }
720
721                 if (a2_phrase_mode)
722                 {
723                         // Bump the pointer to the next phrase boundary
724                         // Even though it works, this is crappy... Clean it up!
725                         uint32 size = 64 / a2_psize;
726
727                         // Crappy kludge... ('aligning' source to destination)
728                         // Prolly should do this for A1 channel as well...
729                         if (a1_phrase_mode && !DSTA2)
730                         {
731                                 uint32 extra = (a1_start >> 16) % size;
732                                 a2_x += extra << 16;
733                         }
734
735                         uint32 newx = (a2_x >> 16) / size;
736                         uint32 newxrem = (a2_x >> 16) % size;
737                         a2_x &= 0x0000FFFF;
738                         a2_x |= (((newx + (newxrem == 0 ? 0 : 1) /*+ extra*/) * size) & 0xFFFF) << 16;
739                 }
740
741                 //Not entirely: This still mucks things up... !!! FIX !!!
742                 a1_x += a1_step_x;
743                 a1_y += a1_step_y;
744                 a2_x += a2_step_x;
745                 a2_y += a2_step_y;//*/
746
747 /*              if (a2_phrase_mode)
748                 {
749                         a1_x+=(64/a1_psize)*a1_xadd;
750                 }       
751                 if (a2_phrase_mode)
752                 {
753                         for (int nb=0;nb<(64/a2_psize)+1;nb++)
754                                 a2_x = (a2_x + a2_xadd) & a2_mask_x;
755                 }
756 */      }
757         
758         // write values back to registers 
759         WREG(A1_PIXEL,  (a1_y & 0xFFFF0000) | ((a1_x >> 16) & 0xFFFF));
760         WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xFFFF));
761         WREG(A2_PIXEL,  (a2_y & 0xFFFF0000) | ((a2_x >> 16) & 0xFFFF));
762 specialLog = false;
763 }
764
765 void blitter_blit(uint32 cmd)
766 {
767         uint32 pitchValue[4] = { 0, 1, 3, 2 };
768         colour_index = 0;
769         src = cmd & 0x07;
770         dst = (cmd >> 3) & 0x07;
771         misc = (cmd >> 6) & 0x03;
772         a1ctl = (cmd >> 8) & 0x7;
773         mode = (cmd >> 11) & 0x07;
774         ity = (cmd >> 14) & 0x0F;
775         zop = (cmd >> 18) & 0x07;
776         op = (cmd >> 21) & 0x0F;
777         ctrl = (cmd >> 25) & 0x3F;
778
779         // Addresses in A1/2_BASE are *phrase* aligned, i.e., bottom three bits are ignored!
780         // NOTE: This fixes Rayman's bad collision detection AND keeps T2K working!
781         a1_addr = REG(A1_BASE) & 0xFFFFFFF8;
782         a2_addr = REG(A2_BASE) & 0xFFFFFFF8;
783
784         a1_zoffs = (REG(A1_FLAGS) >> 6) & 7;
785         a2_zoffs = (REG(A2_FLAGS) >> 6) & 7;
786         
787         xadd_a1_control = (REG(A1_FLAGS) >> 16) & 0x03;
788         xadd_a2_control = (REG(A2_FLAGS) >> 16) & 0x03;
789 //      a1_pitch = (REG(A1_FLAGS) & 3) ^ ((REG(A1_FLAGS) & 2) >> 1);
790 //      a2_pitch = (REG(A2_FLAGS) & 3) ^ ((REG(A2_FLAGS) & 2) >> 1);
791         a1_pitch = pitchValue[(REG(A1_FLAGS) & 0x03)];
792         a2_pitch = pitchValue[(REG(A2_FLAGS) & 0x03)];
793
794         n_pixels = REG(PIXLINECOUNTER) & 0xFFFF;
795         n_lines = (REG(PIXLINECOUNTER) >> 16) & 0xFFFF;
796
797         a1_x = (REG(A1_PIXEL) << 16) | (REG(A1_FPIXEL) & 0xFFFF);
798         a1_y = (REG(A1_PIXEL) & 0xFFFF0000) | (REG(A1_FPIXEL) >> 16);
799 //According to the JTRM, X is restricted to 15 bits and Y is restricted to 12.
800 //But it seems to fuck up T2K! !!! FIX !!!
801 //Could it be sign extended??? Doesn't seem to be so according to JTRM
802 //      a1_x &= 0x7FFFFFFF, a1_y &= 0x0FFFFFFF;
803
804 //      a1_width = blitter_scanline_width[((REG(A1_FLAGS) & 0x00007E00) >> 9)];
805 // According to JTRM, this must give a *whole number* of phrases in the current
806 // pixel size (this means the lookup above is WRONG)... !!! FIX !!!
807         UINT32 m = (REG(A1_FLAGS) >> 9) & 0x03, e = (REG(A1_FLAGS) >> 11) & 0x0F;
808         a1_width = ((0x04 | m) << e) >> 2;//*/
809
810         a2_x = (REG(A2_PIXEL) & 0x0000FFFF) << 16;
811         a2_y = (REG(A2_PIXEL) & 0xFFFF0000);
812 //According to the JTRM, X is restricted to 15 bits and Y is restricted to 12.
813 //But it seems to fuck up T2K! !!! FIX !!!
814 //      a2_x &= 0x7FFFFFFF, a2_y &= 0x0FFFFFFF;
815
816 //      a2_width = blitter_scanline_width[((REG(A2_FLAGS) & 0x00007E00) >> 9)];
817 // According to JTRM, this must give a *whole number* of phrases in the current
818 // pixel size (this means the lookup above is WRONG)... !!! FIX !!!
819         m = (REG(A2_FLAGS) >> 9) & 0x03, e = (REG(A2_FLAGS) >> 11) & 0x0F;
820         a2_width = ((0x04 | m) << e) >> 2;//*/
821         a2_mask_x = ((REG(A2_MASK) & 0x0000FFFF) << 16) | 0xFFFF;
822         a2_mask_y = (REG(A2_MASK) & 0xFFFF0000) | 0xFFFF;
823
824         // Check for "use mask" flag
825         if (!(REG(A2_FLAGS) & 0x8000))
826         {
827                 a2_mask_x = 0xFFFFFFFF; // must be 16.16
828                 a2_mask_y = 0xFFFFFFFF; // must be 16.16
829         }
830
831         a1_phrase_mode = 0;
832
833         // According to the official documentation, a hardware bug ties A2's yadd bit to A1's...
834         a2_yadd = a1_yadd = (YADD1_A1 ? 1 << 16 : 0);
835
836         if (YSIGNSUB_A1)
837                 a1_yadd = -a1_yadd;
838
839         // determine a1_xadd
840         switch (xadd_a1_control)
841         {
842         case XADDPHR:
843 // This is a documented Jaguar bug relating to phrase mode and truncation... Look into it!
844                 // add phrase offset to X and truncate
845                 a1_xadd = 1 << 16;
846                 a1_phrase_mode = 1;
847                 break;
848         case XADDPIX:
849                 // add pixelsize (1) to X
850                 a1_xadd = 1 << 16;
851                 break;
852         case XADD0:     
853                 // add zero (for those nice vertical lines)
854                 a1_xadd = 0;
855                 break;
856         case XADDINC:
857                 // add the contents of the increment register
858                 a1_xadd = (REG(A1_INC) << 16)            | (REG(A1_FINC) & 0xFFFF);
859                 a1_yadd = (REG(A1_INC) & 0xFFFF0000) | (REG(A1_FINC) >> 16);
860                 break;
861         }
862
863
864 //Blit! (0011D000 -> 000B9600) count: 228 x 1, A1/2_FLAGS: 00073820/00064220 [cmd: 41802801]
865 //  A1 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 128 (1C), addctl: XADDINC YADD1 XSIGNADD YSIGNADD
866 //  A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 320 (21), addctl: XADD0 YADD1 XSIGNADD YSIGNADD
867 //if (YADD1_A1 && YADD1_A2 && xadd_a2_control == XADD0 && xadd_a1_control == XADDINC)// &&
868 //      UINT32 a1f = REG(A1_FLAGS), a2f = REG(A2_FLAGS);
869 //Ok, so this ISN'T it... Prolly the XADDPHR code above that's doing it...
870 //if (REG(A1_FLAGS) == 0x00073820 && REG(A2_FLAGS) == 0x00064220 && cmd == 0x41802801)
871 //        A1 x/y: 14368/7, A2 x/y: 150/36
872 //This is it... The problem...
873 //if ((a1_x >> 16) == 14368) // 14368 = $3820
874 //      return; //Lesse what we got...
875
876         if (XSIGNSUB_A1)
877                 a1_xadd = -a1_xadd;
878
879         if (YSIGNSUB_A2)
880                 a2_yadd = -a2_yadd;
881
882         a2_phrase_mode = 0;
883
884         // determine a2_xadd
885         switch (xadd_a2_control)
886         {
887         case XADDPHR:
888                 // add phrase offset to X and truncate
889                 a2_xadd = 1 << 16;
890                 a2_phrase_mode = 1;
891                 break;
892         case XADDPIX:
893                 // add pixelsize (1) to X
894                 a2_xadd = 1 << 16;
895                 break;
896         case XADD0:     
897                 // add zero (for those nice vertical lines)
898                 a2_xadd = 0;
899                 break;
900 //This really isn't a valid bit combo for A2... Shouldn't this cause the blitter to just say no?
901         case XADDINC:
902 WriteLog("BLIT: Asked to use invalid bit combo (XADDINC) for A2...\n");
903                 // add the contents of the increment register
904                 // since there is no register for a2 we just add 1
905 //Let's do nothing, since it's not listed as a valid bit combo...
906 //              a2_xadd = 1 << 16;
907                 break;
908         }
909
910         if (XSIGNSUB_A2)
911                 a2_xadd = -a2_xadd;
912
913         // Modify outer loop steps based on blitter command
914
915         a1_step_x = 0;
916         a1_step_y = 0;
917         a2_step_x = 0;
918         a2_step_y = 0;
919
920         if (UPDA1F)
921                 a1_step_x = (REG(A1_FSTEP) & 0xFFFF),
922                 a1_step_y = (REG(A1_FSTEP) >> 16);
923
924         if (UPDA1)
925                 a1_step_x |= ((REG(A1_STEP) & 0x0000FFFF) << 16),
926                 a1_step_y |= ((REG(A1_STEP) & 0xFFFF0000));
927
928         if (UPDA2)
929                 a2_step_x = (REG(A2_STEP) & 0x0000FFFF) << 16,
930                 a2_step_y = (REG(A2_STEP) & 0xFFFF0000);
931
932         outer_loop = n_lines;
933
934         // Clipping...
935
936         if (CLIPA1)
937                 a1_clip_x = REG(A1_CLIP) & 0x7FFF,
938                 a1_clip_y = (REG(A1_CLIP) >> 16) & 0x7FFF;
939
940 // This phrase sizing is incorrect as well... !!! FIX !!!
941 // Err, this is pixel size... (and it's OK)
942         a2_psize = 1 << ((REG(A2_FLAGS) >> 3) & 0x07);
943         a1_psize = 1 << ((REG(A1_FLAGS) >> 3) & 0x07);
944
945         // zbuffering
946         if (GOURZ)
947         {
948                 zadd = JaguarReadLong(0xF02274, BLITTER);
949
950                 for(int v=0; v<4; v++) 
951                         z_i[v] = (int32)JaguarReadLong(0xF0228C + (v << 2), BLITTER);
952         }
953         if (GOURD || GOURZ || SRCSHADE)
954         {
955                 // gouraud shading
956                 gouraud_add = JaguarReadLong(0xF02270, BLITTER);
957                 
958                 gd_c[0] = JaguarReadByte(0xF02268, BLITTER);
959                 gd_i[0] = JaguarReadByte(0xF02269, BLITTER);
960                 gd_i[0] <<= 16;
961                 gd_i[0] |= JaguarReadWord(0xF02240, BLITTER);
962
963                 gd_c[1] = JaguarReadByte(0xF0226A, BLITTER);
964                 gd_i[1] = JaguarReadByte(0xF0226B, BLITTER);
965                 gd_i[1] <<= 16;
966                 gd_i[1] |= JaguarReadWord(0xF02242, BLITTER);
967
968                 gd_c[2] = JaguarReadByte(0xF0226C, BLITTER);
969                 gd_i[2] = JaguarReadByte(0xF0226D, BLITTER);
970                 gd_i[2] <<= 16;
971                 gd_i[2] |= JaguarReadWord(0xF02244, BLITTER);
972
973                 gd_c[3] = JaguarReadByte(0xF0226E, BLITTER);
974                 gd_i[3] = JaguarReadByte(0xF0226F, BLITTER);
975                 gd_i[3] <<= 16; 
976                 gd_i[3] |= JaguarReadWord(0xF02246, BLITTER);
977
978                 gd_ia = gouraud_add & 0xFFFFFF;
979                 if (gd_ia & 0x800000)
980                         gd_ia = 0xFF000000 | gd_ia;
981
982                 gd_ca = (gouraud_add>>24) & 0xFF;
983                 if (gd_ca & 0x80)
984                         gd_ca = 0xFFFFFF00 | gd_ca;
985         }
986
987         // fix for zoop! and syndicate
988 /*      if ((jaguar_mainRom_crc32==0x501be17c)||
989                 (jaguar_mainRom_crc32==0x70895c51)||
990                 (jaguar_mainRom_crc32==0x0f1f1497)||
991                 (jaguar_mainRom_crc32==0xfc8f0dcd)
992            )
993         {
994                 if (a1_step_x < 0)
995                         a1_step_x = (-n_pixels) * 65536;
996
997                 if (a2_step_x < 0)
998                         a2_step_x = (-n_pixels) * 65536;;
999         }
1000         else
1001         // fix for wolfenstein 3d
1002         if (jaguar_mainRom_crc32==0x3966698f)
1003         {
1004                 if (n_pixels==24)
1005                 {
1006                         if ((a1_step_x / 65536)==-28)
1007                         {
1008                                 a1_step_x=-24*65536; // au lieu de -28
1009                                 a2_step_x=  0*65536; // au lieu de -8
1010                         }
1011                 }
1012         } 
1013         else
1014         // fix for Tempest 2000
1015         if (jaguar_mainRom_crc32==0x32816d44)
1016         {
1017
1018                 if ((n_lines!=1)&&((n_pixels==288)||(n_pixels==384)))
1019                 {
1020                         WriteLog("Blit!\n");
1021                         WriteLog("  cmd      = 0x%.8x\n",cmd);
1022                         WriteLog("  a1_base  = %08X\n", a1_addr);
1023                         WriteLog("  a1_pitch = %d\n", a1_pitch);
1024                         WriteLog("  a1_psize = %d\n", a1_psize);
1025                         WriteLog("  a1_width = %d\n", a1_width);
1026                         WriteLog("  a1_xadd  = %f (phrase=%d)\n", (float)a1_xadd / 65536.0, a1_phrase_mode);
1027                         WriteLog("  a1_yadd  = %f\n", (float)a1_yadd / 65536.0);
1028                         WriteLog("  a1_xstep = %f\n", (float)a1_step_x / 65536.0);
1029                         WriteLog("  a1_ystep = %f\n", (float)a1_step_y / 65536.0);
1030                         WriteLog("  a1_x     = %f\n", (float)a1_x / 65536.0);
1031                         WriteLog("  a1_y     = %f\n", (float)a1_y / 65536.0);
1032                         WriteLog("  a1_zoffs = %i\n",a1_zoffs);
1033
1034                         WriteLog("  a2_base  = %08X\n", a2_addr);
1035                         WriteLog("  a2_pitch = %d\n", a2_pitch);
1036                         WriteLog("  a2_psize = %d\n", a2_psize);
1037                         WriteLog("  a2_width = %d\n", a2_width);
1038                         WriteLog("  a2_xadd  = %f (phrase=%d)\n", (float)a2_xadd / 65536.0, a2_phrase_mode);
1039                         WriteLog("  a2_yadd  = %f\n", (float)a2_yadd / 65536.0);
1040                         WriteLog("  a2_xstep = %f\n", (float)a2_step_x / 65536.0);
1041                         WriteLog("  a2_ystep = %f\n", (float)a2_step_y / 65536.0);
1042                         WriteLog("  a2_x     = %f\n", (float)a2_x / 65536.0);
1043                         WriteLog("  a2_y     = %f\n", (float)a2_y / 65536.0);
1044                         WriteLog("  a2_mask_x= 0x%.4x\n",a2_mask_x);
1045                         WriteLog("  a2_mask_y= 0x%.4x\n",a2_mask_y);
1046                         WriteLog("  a2_zoffs = %i\n",a2_zoffs);
1047
1048                         WriteLog("  count    = %d x %d\n", n_pixels, n_lines);
1049
1050                         WriteLog("  command  = %08X\n", cmd);
1051                         WriteLog("  dsten    = %i\n",DSTEN);
1052                         WriteLog("  srcen    = %i\n",SRCEN);
1053                         WriteLog("  patdsel  = %i\n",PATDSEL);
1054                         WriteLog("  color    = 0x%.8x\n",REG(PATTERNDATA));
1055                         WriteLog("  dcompen  = %i\n",DCOMPEN);
1056                         WriteLog("  bcompen  = %i\n",BCOMPEN);
1057                         WriteLog("  cmpdst   = %i\n",CMPDST);
1058                         WriteLog("  GOURZ    = %i\n",GOURZ);
1059                         WriteLog("  GOURD    = %i\n",GOURD);
1060                         WriteLog("  SRCSHADE = %i\n",SRCSHADE);
1061                         WriteLog("  DSTDATA  = 0x%.8x%.8x\n",REG(DSTDATA),REG(DSTDATA+4));
1062                 }       
1063         }//*/
1064
1065 #ifdef LOG_BLITS
1066         if (start_logging)
1067         {
1068                 WriteLog("Blit!\n");
1069                 WriteLog("  cmd      = 0x%.8x\n",cmd);
1070                 WriteLog("  a1_base  = %08X\n", a1_addr);
1071                 WriteLog("  a1_pitch = %d\n", a1_pitch);
1072                 WriteLog("  a1_psize = %d\n", a1_psize);
1073                 WriteLog("  a1_width = %d\n", a1_width);
1074                 WriteLog("  a1_xadd  = %f (phrase=%d)\n", (float)a1_xadd / 65536.0, a1_phrase_mode);
1075                 WriteLog("  a1_yadd  = %f\n", (float)a1_yadd / 65536.0);
1076                 WriteLog("  a1_xstep = %f\n", (float)a1_step_x / 65536.0);
1077                 WriteLog("  a1_ystep = %f\n", (float)a1_step_y / 65536.0);
1078                 WriteLog("  a1_x     = %f\n", (float)a1_x / 65536.0);
1079                 WriteLog("  a1_y     = %f\n", (float)a1_y / 65536.0);
1080                 WriteLog("  a1_zoffs = %i\n",a1_zoffs);
1081
1082                 WriteLog("  a2_base  = %08X\n", a2_addr);
1083                 WriteLog("  a2_pitch = %d\n", a2_pitch);
1084                 WriteLog("  a2_psize = %d\n", a2_psize);
1085                 WriteLog("  a2_width = %d\n", a2_width);
1086                 WriteLog("  a2_xadd  = %f (phrase=%d)\n", (float)a2_xadd / 65536.0, a2_phrase_mode);
1087                 WriteLog("  a2_yadd  = %f\n", (float)a2_yadd / 65536.0);
1088                 WriteLog("  a2_xstep = %f\n", (float)a2_step_x / 65536.0);
1089                 WriteLog("  a2_ystep = %f\n", (float)a2_step_y / 65536.0);
1090                 WriteLog("  a2_x     = %f\n", (float)a2_x / 65536.0);
1091                 WriteLog("  a2_y     = %f\n", (float)a2_y / 65536.0);
1092                 WriteLog("  a2_mask_x= 0x%.4x\n",a2_mask_x);
1093                 WriteLog("  a2_mask_y= 0x%.4x\n",a2_mask_y);
1094                 WriteLog("  a2_zoffs = %i\n",a2_zoffs);
1095
1096                 WriteLog("  count    = %d x %d\n", n_pixels, n_lines);
1097
1098                 WriteLog("  command  = %08X\n", cmd);
1099                 WriteLog("  dsten    = %i\n",DSTEN);
1100                 WriteLog("  srcen    = %i\n",SRCEN);
1101                 WriteLog("  patdsel  = %i\n",PATDSEL);
1102                 WriteLog("  color    = 0x%.8x\n",REG(PATTERNDATA));
1103                 WriteLog("  dcompen  = %i\n",DCOMPEN);
1104                 WriteLog("  bcompen  = %i\n",BCOMPEN);
1105                 WriteLog("  cmpdst   = %i\n",CMPDST);
1106                 WriteLog("  GOURZ   = %i\n",GOURZ);
1107                 WriteLog("  GOURD   = %i\n",GOURD);
1108                 WriteLog("  SRCSHADE= %i\n",SRCSHADE);
1109         }       
1110 #endif
1111
1112 //NOTE: Pitch is ignored!
1113
1114 //This *might* be the altimeter blits (they are)...
1115 //On captured screen, x-pos for black (inner) is 259, for pink is 257
1116 //Black is short by 3, pink is short by 1...
1117 /*
1118 Blit! (00110000 <- 000BF010) count: 9 x 31, A1/2_FLAGS: 000042E2/00010020 [cmd: 00010200]
1119  CMD -> src:  dst:  misc:  a1ctl: UPDA1  mode:  ity: PATDSEL z-op:  op: LFU_CLEAR ctrl: 
1120   A1 -> pitch: 4 phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
1121   A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
1122         A1 x/y: 262/124, A2 x/y: 128/0
1123 Blit! (00110000 <- 000BF010) count: 5 x 38, A1/2_FLAGS: 000042E2/00010020 [cmd: 00010200]
1124  CMD -> src:  dst:  misc:  a1ctl: UPDA1  mode:  ity: PATDSEL z-op:  op: LFU_CLEAR ctrl: 
1125   A1 -> pitch: 4 phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
1126   A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
1127         A1 x/y: 264/117, A2 x/y: 407/0
1128
1129 Blit! (00110000 <- 000BF010) count: 9 x 23, A1/2_FLAGS: 000042E2/00010020 [cmd: 00010200]
1130  CMD -> src:  dst:  misc:  a1ctl: UPDA1  mode:  ity: PATDSEL z-op:  op: LFU_CLEAR ctrl: 
1131   A1 step values: -10 (X), 1 (Y)
1132   A1 -> pitch: 4(2) phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
1133   A2 -> pitch: 1(0) phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
1134         A1 x/y: 262/132, A2 x/y: 129/0
1135 Blit! (00110000 <- 000BF010) count: 5 x 27, A1/2_FLAGS: 000042E2/00010020 [cmd: 00010200]
1136  CMD -> src:  dst:  misc:  a1ctl: UPDA1  mode:  ity: PATDSEL z-op:  op: LFU_CLEAR ctrl: 
1137   A1 step values: -8 (X), 1 (Y)
1138   A1 -> pitch: 4(2) phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
1139   A2 -> pitch: 1(0) phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
1140         A1 x/y: 264/128, A2 x/y: 336/0
1141
1142   264v       vCursor ends up here...
1143      xxxxx...`
1144      111122223333
1145
1146 262v         vCursor ends up here...
1147    xxxxxxxxx.'
1148  1111222233334444
1149
1150 Fixed! Now for more:
1151
1152 ; This looks like the ship icon in the upper left corner...
1153
1154 Blit! (00110000 <- 0010B2A8) count: 11 x 12, A1/2_FLAGS: 000042E2/00000020 [cmd: 09800609]
1155  CMD -> src: SRCEN  dst: DSTEN  misc:  a1ctl: UPDA1 UPDA2 mode:  ity:  z-op:  op: LFU_REPLACE ctrl: DCOMPEN 
1156   A1 step values: -12 (X), 1 (Y)
1157   A2 step values: 0 (X), 0 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
1158   A1 -> pitch: 4 phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
1159   A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
1160         A1 x/y: 20/24, A2 x/y: 5780/0
1161
1162 Also fixed!
1163
1164 More (not sure this is a blitter problem as much as it's a GPU problem):
1165 All but the "M" are trashed...
1166 This does *NOT* look like a blitter problem, as it's rendering properly...
1167 Actually, if you look at the A1 step values, there IS a discrepancy!
1168
1169 ; D
1170
1171 Blit! (00110000 <- 0010B2A8) count: 12 x 12, A1/2_FLAGS: 000042E2/00000020 [cmd: 09800609]
1172  CMD -> src: SRCEN  dst: DSTEN  misc:  a1ctl: UPDA1 UPDA2 mode:  ity:  z-op:  op: LFU_REPLACE ctrl: DCOMPEN 
1173   A1 step values: -14 (X), 1 (Y)
1174   A2 step values: -4 (X), 0 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
1175   A1 -> pitch: 4 phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
1176   A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
1177         A1 x/y: 134/144, A2 x/y: 2516/0
1178 ;129,146: +5,-2
1179
1180 ; E
1181
1182 Blit! (00110000 <- 0010B2A8) count: 12 x 12, A1/2_FLAGS: 000042E2/00000020 [cmd: 09800609]
1183  CMD -> src: SRCEN  dst: DSTEN  misc:  a1ctl: UPDA1 UPDA2 mode:  ity:  z-op:  op: LFU_REPLACE ctrl: DCOMPEN 
1184   A1 step values: -13 (X), 1 (Y)
1185   A2 step values: -4 (X), 0 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
1186   A1 -> pitch: 4 phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
1187   A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
1188         A1 x/y: 147/144, A2 x/y: 2660/0
1189
1190 ; M
1191
1192 Blit! (00110000 <- 0010B2A8) count: 12 x 12, A1/2_FLAGS: 000042E2/00000020 [cmd: 09800609]
1193  CMD -> src: SRCEN  dst: DSTEN  misc:  a1ctl: UPDA1 UPDA2 mode:  ity:  z-op:  op: LFU_REPLACE ctrl: DCOMPEN 
1194   A1 step values: -12 (X), 1 (Y)
1195   A2 step values: 0 (X), 0 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
1196   A1 -> pitch: 4 phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
1197   A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
1198         A1 x/y: 160/144, A2 x/y: 3764/0
1199
1200 ; O
1201
1202 Blit! (00110000 <- 0010B2A8) count: 12 x 12, A1/2_FLAGS: 000042E2/00000020 [cmd: 09800609]
1203  CMD -> src: SRCEN  dst: DSTEN  misc:  a1ctl: UPDA1 UPDA2 mode:  ity:  z-op:  op: LFU_REPLACE ctrl: DCOMPEN 
1204   A1 step values: -15 (X), 1 (Y)
1205   A2 step values: -4 (X), 0 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
1206   A1 -> pitch: 4 phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
1207   A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
1208         A1 x/y: 173/144, A2 x/y: 4052/0
1209
1210 */
1211 extern int blit_start_log;
1212 extern int op_start_log;
1213 if (blit_start_log)
1214 {
1215         char * ctrlStr[4] = { "XADDPHR\0", "XADDPIX\0", "XADD0\0", "XADDINC\0" };
1216         char * bppStr[8] = { "1bpp\0", "2bpp\0", "4bpp\0", "8bpp\0", "16bpp\0", "32bpp\0", "???\0", "!!!\0" };
1217         char * opStr[16] = { "LFU_CLEAR", "LFU_NSAND", "LFU_NSAD", "LFU_NOTS", "LFU_SAND", "LFU_NOTD", "LFU_N_SXORD", "LFU_NSORND",
1218                 "LFU_SAD", "LFU_XOR", "LFU_D", "LFU_NSORD", "LFU_REPLACE", "LFU_SORND", "LFU_SORD", "LFU_ONE" };
1219         uint32 src = cmd & 0x07, dst = (cmd >> 3) & 0x07, misc = (cmd >> 6) & 0x03,
1220                 a1ctl = (cmd >> 8) & 0x07, mode = (cmd >> 11) & 0x07, ity = (cmd >> 14) & 0x0F,
1221                 zop = (cmd >> 18) & 0x07, op = (cmd >> 21) & 0x0F, ctrl = (cmd >> 25) & 0x3F;
1222         UINT32 a1f = REG(A1_FLAGS), a2f = REG(A2_FLAGS);
1223         uint32 p1 = a1f & 0x07, p2 = a2f & 0x07,
1224                 d1 = (a1f >> 3) & 0x07, d2 = (a2f >> 3) & 0x07,
1225                 zo1 = (a1f >> 6) & 0x07, zo2 = (a2f >> 6) & 0x07,
1226                 w1 = (a1f >> 9) & 0x3F, w2 = (a2f >> 9) & 0x3F,
1227                 ac1 = (a1f >> 16) & 0x1F, ac2 = (a2f >> 16) & 0x1F;
1228         UINT32 iw1 = ((0x04 | (w1 & 0x03)) << ((w1 & 0x3C) >> 2)) >> 2;
1229         UINT32 iw2 = ((0x04 | (w2 & 0x03)) << ((w2 & 0x3C) >> 2)) >> 2;
1230         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);
1231 //      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);
1232
1233         WriteLog(" CMD -> src: %s%s%s ", (cmd & 0x0001 ? "SRCEN " : ""), (cmd & 0x0002 ? "SRCENZ " : ""), (cmd & 0x0004 ? "SRCENX" : ""));
1234         WriteLog("dst: %s%s%s ", (cmd & 0x0008 ? "DSTEN " : ""), (cmd & 0x0010 ? "DSTENZ " : ""), (cmd & 0x0020 ? "DSTWRZ" : ""));
1235         WriteLog("misc: %s%s ", (cmd & 0x0040 ? "CLIP_A1 " : ""), (cmd & 0x0080 ? "???" : ""));
1236         WriteLog("a1ctl: %s%s%s ", (cmd & 0x0100 ? "UPDA1F " : ""), (cmd & 0x0200 ? "UPDA1 " : ""), (cmd & 0x0400 ? "UPDA2" : ""));
1237         WriteLog("mode: %s%s%s ", (cmd & 0x0800 ? "DSTA2 " : ""), (cmd & 0x1000 ? "GOURD " : ""), (cmd & 0x2000 ? "ZBUFF" : ""));
1238         WriteLog("ity: %s%s%s ", (cmd & 0x4000 ? "TOPBEN " : ""), (cmd & 0x8000 ? "TOPNEN " : ""), (cmd & 0x00010000 ? "PATDSEL" : ""));
1239         WriteLog("z-op: %s%s%s ", (cmd & 0x00040000 ? "ZMODELT " : ""), (cmd & 0x00080000 ? "ZMODEEQ " : ""), (cmd & 0x00100000 ? "ZMODEGT" : ""));
1240         WriteLog("op: %s ", opStr[(cmd >> 21) & 0x0F]);
1241         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" : ""));
1242
1243         if (UPDA1)
1244                 WriteLog("  A1 step values: %d (X), %d (Y)\n", a1_step_x >> 16, a1_step_y >> 16);
1245
1246         if (UPDA2)
1247                 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);
1248
1249         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"));
1250         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"));
1251         WriteLog("        A1 x/y: %d/%d, A2 x/y: %d/%d\n", a1_x >> 16, a1_y >> 16, a2_x >> 16, a2_y >> 16);
1252 //      blit_start_log = 0;
1253 //      op_start_log = 1;
1254 }
1255
1256         blitter_working = 1;
1257 //#ifndef USE_GENERIC_BLITTER
1258 //      if (!blitter_execute_cached_code(blitter_in_cache(cmd)))
1259 //#endif
1260         blitter_generic(cmd);
1261
1262 /*if (blit_start_log)
1263 {
1264         if (a1_addr == 0xF03000 && a2_addr == 0x004D58)
1265         {
1266                 WriteLog("\nBytes at 004D58:\n");
1267                 for(int i=0x004D58; i<0x004D58+(10*127*4); i++)
1268                         WriteLog("%02X ", JaguarReadByte(i));
1269                 WriteLog("\nBytes at F03000:\n");
1270                 for(int i=0xF03000; i<0xF03000+(6*127*4); i++)
1271                         WriteLog("%02X ", JaguarReadByte(i));
1272                 WriteLog("\n\n");
1273         }
1274 }//*/
1275
1276         blitter_working = 0;
1277 }
1278
1279 void blitter_init(void)
1280 {
1281         blitter_reset();
1282 }
1283
1284 void blitter_reset(void)
1285 {
1286         memset(blitter_ram, 0x00, 0xA0);
1287 }
1288
1289 void blitter_done(void)
1290 {
1291         WriteLog("BLIT: Done.\n");
1292 }
1293
1294 uint8 BlitterReadByte(uint32 offset, uint32 who/*=UNKNOWN*/)
1295 {
1296         offset &= 0xFF;
1297
1298         // status register
1299         if (offset == (0x38 + 3))
1300                 return 0x01;    // always idle
1301
1302 //Attempted fix for AvP:
1303         if (offset >= 0x04 && offset <= 0x07)
1304                 return (offset > 0x05 ? blitter_ram[PIXLINECOUNTER + offset - 0x04] : 0x00);
1305 //              return 0x00;    // WO register! What does it expect to see here???
1306
1307         return blitter_ram[offset];
1308 }
1309
1310 //Crappy!
1311 uint16 BlitterReadWord(uint32 offset, uint32 who/*=UNKNOWN*/)
1312 {
1313         return ((uint16)BlitterReadByte(offset, who) << 8) | (uint16)BlitterReadByte(offset+1, who);
1314 }
1315
1316 //Crappy!
1317 uint32 BlitterReadLong(uint32 offset, uint32 who/*=UNKNOWN*/)
1318 {
1319         return (BlitterReadWord(offset, who) << 16) | BlitterReadWord(offset+2, who);
1320 }
1321
1322 void BlitterWriteByte(uint32 offset, uint8 data, uint32 who/*=UNKNOWN*/)
1323 {
1324 /*if (offset & 0xFF == 0x7B)
1325         WriteLog("--> Wrote to B_STOP: value -> %02X\n", data);*/
1326         offset &= 0xFF;
1327
1328 //      if ((offset >= 0x7C) && (offset <= 0x9B))
1329         if ((offset >= 0x7C) && (offset <= 0x8B))
1330         {
1331                 switch (offset)
1332                 {
1333                 case 0x7C: break;
1334                 case 0x7D: blitter_ram[0x69] = data; break;
1335                 case 0x7E: blitter_ram[0x40] = data; break;
1336                 case 0x7F: blitter_ram[0x41] = data; break;
1337
1338                 case 0x80: break;
1339                 case 0x81: blitter_ram[0x6B] = data; break;
1340                 case 0x82: blitter_ram[0x42] = data; break;
1341                 case 0x83: blitter_ram[0x43] = data; break;
1342                 
1343                 case 0x84: break;
1344                 case 0x85: blitter_ram[0x6D] = data; break;
1345                 case 0x86: blitter_ram[0x44] = data; break;
1346                 case 0x87: blitter_ram[0x45] = data; break;
1347                 
1348                 case 0x88: break;
1349                 case 0x89: blitter_ram[0x6F] = data; break;
1350 //Mistyped?
1351 //              case 0x9A: blitter_ram[0x46] = data; break;
1352 //              case 0x9B: blitter_ram[0x47] = data; break;
1353                 case 0x8A: blitter_ram[0x46] = data; break;
1354                 case 0x8B: blitter_ram[0x47] = data; break;
1355                 }
1356         }
1357
1358         blitter_ram[offset] = data;
1359 }
1360
1361 void BlitterWriteWord(uint32 offset, uint16 data, uint32 who/*=UNKNOWN*/)
1362 {
1363 //#if 1
1364 /*      if (offset & 0xFF == A1_PIXEL && data == 14368)
1365         {
1366                 WriteLog("\n1\nA1_PIXEL written by %s (%u)...\n\n\n", whoName[who], data);
1367 extern bool doGPUDis;
1368 doGPUDis = true;
1369         }
1370         if ((offset & 0xFF) == (A1_PIXEL + 2) && data == 14368)
1371         {
1372                 WriteLog("\n2\nA1_PIXEL written by %s (%u)...\n\n\n", whoName[who], data);
1373 extern bool doGPUDis;
1374 doGPUDis = true;
1375         }//*/
1376 //#endif
1377
1378         BlitterWriteByte(offset+0, (data>>8) & 0xFF, who);
1379         BlitterWriteByte(offset+1, data & 0xFF, who);
1380
1381         if ((offset & 0xFF) == 0x3A)
1382         // I.e., the second write of 32-bit value--not convinced this is the best way to do this!
1383         // But then again, according to the Jaguar docs, this is correct...!
1384                 blitter_blit(GET32(blitter_ram, 0x38));
1385 }
1386 //F02278,9,A,B
1387
1388 void BlitterWriteLong(uint32 offset, uint32 data, uint32 who/*=UNKNOWN*/)
1389 {
1390 //#if 1
1391 /*      if ((offset & 0xFF) == A1_PIXEL && (data & 0xFFFF) == 14368)
1392         {
1393                 WriteLog("\n3\nA1_PIXEL written by %s (%u)...\n\n\n", whoName[who], data);
1394 extern bool doGPUDis;
1395 doGPUDis = true;
1396         }//*/
1397 //#endif
1398
1399         BlitterWriteWord(offset, data >> 16, who);
1400         BlitterWriteWord(offset+2, data & 0xFFFF, who);
1401 }