]> Shamusworld >> Repos - virtualjaguar/blob - src/blitter.cpp
Blitter I/O fixes
[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 PHRASEINT0              ((UINT32)0x7C)
45 #define PHRASEINT1              ((UINT32)0x80)
46 #define PHRASEINT2              ((UINT32)0x84)
47 #define PHRASEINT3              ((UINT32)0x88)
48 #define PHRASEZ0                ((UINT32)0x8C)
49 #define PHRASEZ1                ((UINT32)0x90)
50 #define PHRASEZ2                ((UINT32)0x94)
51 #define PHRASEZ3                ((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 // Houston, we have a problem...
463 // Look here, at PATDSEL and GOURD. If both are active (as they are on the BIOS intro), then there's
464 // a conflict! E.g.:
465 //Blit! (00100000 <- 000095D0) count: 3 x 1, A1/2_FLAGS: 00014220/00004020 [cmd: 00011008]
466 // CMD -> src:  dst: DSTEN  misc:  a1ctl:  mode: GOURD  ity: PATDSEL z-op:  op: LFU_CLEAR ctrl: 
467 //  A1 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 320 (21), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
468 //  A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 256 (20), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
469 //        A1 x/y: 90/171, A2 x/y: 808/0 Pattern: 776D770077007700
470
471                                         if (PATDSEL)
472                                         {
473                                                 // use pattern data for write data
474                                                 writedata = READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode);
475                                         }
476                                         else if (INTADD)
477                                         {
478                                                 // intensity addition
479                                                 writedata = (srcdata & 0xFF) + (dstdata & 0xFF);
480                                                 if (!(TOPBEN) && writedata > 0xFF)
481                                                         writedata = 0xFF;
482                                                 writedata |= (srcdata & 0xF00) + (dstdata & 0xF00);
483                                                 if (!(TOPNEN) && writedata > 0xFFF)
484                                                         writedata = 0xFFF;
485                                                 writedata |= (srcdata & 0xF000) + (dstdata & 0xF000);
486                                         }
487                                         else
488                                         {
489                                                 if (LFU_NAN) writedata |= ~srcdata & ~dstdata;
490                                                 if (LFU_NA)  writedata |= ~srcdata & dstdata;
491                                                 if (LFU_AN)  writedata |= srcdata  & ~dstdata;
492                                                 if (LFU_A)       writedata |= srcdata  & dstdata;
493                                         }
494
495 //Although, this looks like it's OK... (even if it is shitty!)
496                                         if (GOURD) 
497                                                 writedata = ((gd_c[colour_index]) << 8) | (gd_i[colour_index] >> 16);
498
499                                         if (SRCSHADE) 
500                                         {
501                                                 int intensity = srcdata & 0xFF;
502                                                 int ia = gd_ia >> 16;
503                                                 if (ia & 0x80)
504                                                         ia = 0xFFFFFF00 | ia;
505                                                 intensity += ia;
506                                                 if (intensity < 0)
507                                                         intensity = 0;
508                                                 if (intensity > 0xFF)
509                                                         intensity = 0xFF;
510                                                 writedata = (srcdata & 0xFF00) | intensity;
511                                         }
512                                 }
513                                 else
514                                 {
515                                         writedata = dstdata;
516                                         srczdata = dstzdata;
517                                 }
518
519                                 if (/*a1_phrase_mode || */BKGWREN || !inhibit)
520                                 {
521 /*if (((REG(A1_FLAGS) >> 3) & 0x07) == 5)
522 {
523         uint32 offset = a1_addr+(PIXEL_OFFSET_32(a1)<<2);
524 // (((((UINT32)a##_y >> 16) * a##_width) + (((UINT32)a##_x >> 16) & ~1)) * (1 + a##_pitch) + (((UINT32)a##_x >> 16) & 1))
525         if ((offset >= 0x1FF020 && offset <= 0x1FF03F) || (offset >= 0x1FF820 && offset <= 0x1FF83F))
526                 WriteLog("32bpp pixel write: A1 Phrase mode --> ");
527 }//*/
528                                         // write to the destination
529                                         WRITE_PIXEL(a1, REG(A1_FLAGS), writedata);
530                                         if (DSTWRZ)
531                                                 WRITE_ZDATA(a1, REG(A1_FLAGS), srczdata);
532                                 }
533                         }
534                         else    // if (DSTA2)
535                         {
536                                 // load src data and Z
537                                 if (SRCEN)
538                                 {
539                                         srcdata = READ_PIXEL(a1, REG(A1_FLAGS));
540                                         if (SRCENZ)
541                                                 srczdata = READ_ZDATA(a1, REG(A1_FLAGS));
542                                         else if (cmd & 0x0001C020)
543                                                 srczdata = READ_RDATA(SRCZINT, a1, REG(A1_FLAGS), a1_phrase_mode);
544                                 }
545                                 else
546                                 {
547                                         srcdata = READ_RDATA(SRCDATA, a1, REG(A1_FLAGS), a1_phrase_mode);
548                                         if (cmd & 0x001C020)
549                                                 srczdata = READ_RDATA(SRCZINT, a1, REG(A1_FLAGS), a1_phrase_mode);
550                                 }
551
552                                 // load dst data and Z 
553                                 if (DSTEN)
554                                 {
555                                         dstdata = READ_PIXEL(a2, REG(A2_FLAGS));
556                                         if (DSTENZ)
557                                                 dstzdata = READ_ZDATA(a2, REG(A2_FLAGS));
558                                         else
559                                                 dstzdata = READ_RDATA(DSTZ, a2, REG(A2_FLAGS), a2_phrase_mode);
560                                 }
561                                 else
562                                 {
563                                         dstdata = READ_RDATA(DSTDATA, a2, REG(A2_FLAGS), a2_phrase_mode);
564                                         if (DSTENZ)
565                                                 dstzdata = READ_RDATA(DSTZ, a2, REG(A2_FLAGS), a2_phrase_mode);
566                                 }
567
568                                 if (GOURZ) 
569                                         srczdata = z_i[colour_index] >> 16;
570
571                                 // apply z comparator
572                                 if (Z_OP_INF) if (srczdata < dstzdata)  inhibit = 1;
573                                 if (Z_OP_EQU) if (srczdata == dstzdata) inhibit = 1;
574                                 if (Z_OP_SUP) if (srczdata > dstzdata)  inhibit = 1;
575                                 
576                                 // apply data comparator
577 //NOTE: The bit comparator (BCOMPEN) is NOT the same at the data comparator!
578                                 if (DCOMPEN | BCOMPEN)
579                                 {
580                                         if (!CMPDST)
581                                         {
582                                                 // compare source pixel with pattern pixel
583 // AvP: Numbers are correct, but sprites are not!
584 //This doesn't seem to be a problem... But could still be wrong...
585 /*                                              if (srcdata == READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode))
586 //                                              if (srcdata != READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode))
587                                                         inhibit = 1;//*/
588 // This is probably not 100% correct... It works in the 1bpp case
589 // (in A1 <- A2 mode, that is...)
590 // AvP: This is causing blocks to be written instead of bit patterns...
591 // Works now...
592 // NOTE: We really should separate out the BCOMPEN & DCOMPEN stuff!
593 /*                                              uint32 A1bpp = 1 << ((REG(A1_FLAGS) >> 3) & 0x07);
594                                                 if (A1bpp == 1 || A1bpp == 16 || A1bpp == 8)
595                                                         inhibit = (srcdata == 0 ? 1: 0);
596                                                 else
597                                                         WriteLog("Blitter: Bad BPP (%u) selected for BCOMPEN mode!\n", A1bpp);//*/
598 // What it boils down to is this:
599                                                 if (srcdata == 0)
600                                                         inhibit = 1;//*/
601                                         }
602                                         else
603                                         {
604                                                 // compare destination pixel with pattern pixel
605                                                 if (dstdata == READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode))
606 //                                              if (dstdata != READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode))
607                                                         inhibit = 1;
608                                         }
609
610 // This is DEFINITELY WRONG
611 //                                      if (a1_phrase_mode || a2_phrase_mode)
612 //                                              inhibit = !inhibit;
613                                 }
614                                 
615                                 if (CLIPA1)
616                                 {
617                                         inhibit |= (((a1_x >> 16) < a1_clip_x && (a1_x >> 16) >= 0
618                                                 && (a1_y >> 16) < a1_clip_y && (a1_y >> 16) >= 0) ? 0 : 1);
619                                 }
620
621                                 // compute the write data and store
622                                 if (!inhibit)
623                                 {                       
624                                         if (PATDSEL)
625                                         {
626                                                 // use pattern data for write data
627                                                 writedata= READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode);
628                                         }
629                                         else if (INTADD)
630                                         {
631                                                 // intensity addition
632                                                 writedata = (srcdata & 0xFF) + (dstdata & 0xFF);
633                                                 if (!(TOPBEN) && writedata > 0xFF)
634                                                         writedata = 0xFF;
635                                                 writedata |= (srcdata & 0xF00) + (dstdata & 0xF00);
636                                                 if (!(TOPNEN) && writedata > 0xFFF)
637                                                         writedata = 0xFFF;
638                                                 writedata |= (srcdata & 0xF000) + (dstdata & 0xF000);
639                                         }
640                                         else
641                                         {
642                                                 if (LFU_NAN)
643                                                         writedata |= ~srcdata & ~dstdata;
644                                                 if (LFU_NA)
645                                                         writedata |= ~srcdata & dstdata;
646                                                 if (LFU_AN)
647                                                         writedata |= srcdata & ~dstdata;
648                                                 if (LFU_A)
649                                                         writedata |= srcdata & dstdata;
650                                         }
651
652                                         if (GOURD) 
653                                                 writedata = ((gd_c[colour_index]) << 8) | (gd_i[colour_index] >> 16);
654
655                                         if (SRCSHADE) 
656                                         {
657                                                 int intensity = srcdata & 0xFF;
658                                                 int ia = gd_ia >> 16;
659                                                 if (ia & 0x80)
660                                                         ia = 0xFFFFFF00 | ia;
661                                                 intensity += ia;
662                                                 if (intensity < 0)
663                                                         intensity = 0;
664                                                 if (intensity > 0xFF)
665                                                         intensity = 0xFF;
666                                                 writedata = (srcdata & 0xFF00) | intensity;
667                                         }
668                                 }
669                                 else
670                                 {
671                                         writedata = dstdata;
672                                         srczdata = dstzdata;
673                                 }
674
675                                 if (/*a2_phrase_mode || */BKGWREN || !inhibit)
676                                 {
677 /*if (logGo)
678 {
679         uint32 offset = a2_addr+(PIXEL_OFFSET_16(a2)<<1);
680 // (((((UINT32)a##_y >> 16) * a##_width) + (((UINT32)a##_x >> 16) & ~1)) * (1 + a##_pitch) + (((UINT32)a##_x >> 16) & 1))
681         WriteLog("[%08X:%04X] ", offset, writedata);
682 }//*/
683                                         // write to the destination
684                                         WRITE_PIXEL(a2, REG(A2_FLAGS), writedata);
685
686                                         if (DSTWRZ)
687                                                 WRITE_ZDATA(a2, REG(A2_FLAGS), srczdata);
688                                 }
689                         }
690
691                         // update x and y
692                         a1_x += a1_xadd;
693                         a1_y += a1_yadd;
694                         a2_x = (a2_x + a2_xadd) & a2_mask_x;
695                         a2_y = (a2_y + a2_yadd) & a2_mask_y;
696
697                         if (GOURZ)
698                                 z_i[colour_index] += zadd;
699
700                         if (GOURD || SRCSHADE)
701                         {
702                                 gd_i[colour_index] += gd_ia;
703 //Hmm, this doesn't seem to do anything...
704 //But it is correct according to the JTRM...!
705 if ((int32)gd_i[colour_index] < 0)
706         gd_i[colour_index] = 0;
707 if (gd_i[colour_index] > 0x00FFFFFF)
708         gd_i[colour_index] = 0x00FFFFFF;//*/
709
710                                 gd_c[colour_index] += gd_ca;
711 if ((int32)gd_c[colour_index] < 0)
712         gd_c[colour_index] = 0;
713 if (gd_c[colour_index] > 0x000000FF)
714         gd_c[colour_index] = 0x000000FF;//*/
715                         }
716
717                         if (GOURD || SRCSHADE || GOURZ)
718                         {
719                                 if (a1_phrase_mode)
720 //This screws things up WORSE (for the BIOS opening screen)
721 //                              if (a1_phrase_mode || a2_phrase_mode)
722                                         colour_index = (colour_index + 1) & 0x03;
723                         }
724                 }
725
726                 //New: Phrase mode taken into account! :-p
727                 if (a1_phrase_mode)
728                 {
729                         // Bump the pointer to the next phrase boundary
730                         // Even though it works, this is crappy... Clean it up!
731                         uint32 size = 64 / a1_psize;
732
733                         // Crappy kludge... ('aligning' source to destination)
734                         if (a2_phrase_mode && DSTA2)
735                         {
736                                 uint32 extra = (a2_start >> 16) % size;
737                                 a1_x += extra << 16;
738                         }
739
740                         uint32 newx = (a1_x >> 16) / size;
741                         uint32 newxrem = (a1_x >> 16) % size;
742                         a1_x &= 0x0000FFFF;
743                         a1_x |= (((newx + (newxrem == 0 ? 0 : 1)) * size) & 0xFFFF) << 16;
744                 }
745
746                 if (a2_phrase_mode)
747                 {
748                         // Bump the pointer to the next phrase boundary
749                         // Even though it works, this is crappy... Clean it up!
750                         uint32 size = 64 / a2_psize;
751
752                         // Crappy kludge... ('aligning' source to destination)
753                         // Prolly should do this for A1 channel as well...
754                         if (a1_phrase_mode && !DSTA2)
755                         {
756                                 uint32 extra = (a1_start >> 16) % size;
757                                 a2_x += extra << 16;
758                         }
759
760                         uint32 newx = (a2_x >> 16) / size;
761                         uint32 newxrem = (a2_x >> 16) % size;
762                         a2_x &= 0x0000FFFF;
763                         a2_x |= (((newx + (newxrem == 0 ? 0 : 1) /*+ extra*/) * size) & 0xFFFF) << 16;
764                 }
765
766                 //Not entirely: This still mucks things up... !!! FIX !!!
767                 a1_x += a1_step_x;
768                 a1_y += a1_step_y;
769                 a2_x += a2_step_x;
770                 a2_y += a2_step_y;//*/
771
772 /*              if (a2_phrase_mode)
773                 {
774                         a1_x+=(64/a1_psize)*a1_xadd;
775                 }       
776                 if (a2_phrase_mode)
777                 {
778                         for (int nb=0;nb<(64/a2_psize)+1;nb++)
779                                 a2_x = (a2_x + a2_xadd) & a2_mask_x;
780                 }
781 */      }
782         
783         // write values back to registers 
784         WREG(A1_PIXEL,  (a1_y & 0xFFFF0000) | ((a1_x >> 16) & 0xFFFF));
785         WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xFFFF));
786         WREG(A2_PIXEL,  (a2_y & 0xFFFF0000) | ((a2_x >> 16) & 0xFFFF));
787 specialLog = false;
788 }
789
790 void blitter_blit(uint32 cmd)
791 {
792         uint32 pitchValue[4] = { 0, 1, 3, 2 };
793         colour_index = 0;
794         src = cmd & 0x07;
795         dst = (cmd >> 3) & 0x07;
796         misc = (cmd >> 6) & 0x03;
797         a1ctl = (cmd >> 8) & 0x7;
798         mode = (cmd >> 11) & 0x07;
799         ity = (cmd >> 14) & 0x0F;
800         zop = (cmd >> 18) & 0x07;
801         op = (cmd >> 21) & 0x0F;
802         ctrl = (cmd >> 25) & 0x3F;
803
804         // Addresses in A1/2_BASE are *phrase* aligned, i.e., bottom three bits are ignored!
805         // NOTE: This fixes Rayman's bad collision detection AND keeps T2K working!
806         a1_addr = REG(A1_BASE) & 0xFFFFFFF8;
807         a2_addr = REG(A2_BASE) & 0xFFFFFFF8;
808
809         a1_zoffs = (REG(A1_FLAGS) >> 6) & 7;
810         a2_zoffs = (REG(A2_FLAGS) >> 6) & 7;
811         
812         xadd_a1_control = (REG(A1_FLAGS) >> 16) & 0x03;
813         xadd_a2_control = (REG(A2_FLAGS) >> 16) & 0x03;
814 //      a1_pitch = (REG(A1_FLAGS) & 3) ^ ((REG(A1_FLAGS) & 2) >> 1);
815 //      a2_pitch = (REG(A2_FLAGS) & 3) ^ ((REG(A2_FLAGS) & 2) >> 1);
816         a1_pitch = pitchValue[(REG(A1_FLAGS) & 0x03)];
817         a2_pitch = pitchValue[(REG(A2_FLAGS) & 0x03)];
818
819         n_pixels = REG(PIXLINECOUNTER) & 0xFFFF;
820         n_lines = (REG(PIXLINECOUNTER) >> 16) & 0xFFFF;
821
822         a1_x = (REG(A1_PIXEL) << 16) | (REG(A1_FPIXEL) & 0xFFFF);
823         a1_y = (REG(A1_PIXEL) & 0xFFFF0000) | (REG(A1_FPIXEL) >> 16);
824 //According to the JTRM, X is restricted to 15 bits and Y is restricted to 12.
825 //But it seems to fuck up T2K! !!! FIX !!!
826 //Could it be sign extended??? Doesn't seem to be so according to JTRM
827 //      a1_x &= 0x7FFFFFFF, a1_y &= 0x0FFFFFFF;
828
829 //      a1_width = blitter_scanline_width[((REG(A1_FLAGS) & 0x00007E00) >> 9)];
830 // According to JTRM, this must give a *whole number* of phrases in the current
831 // pixel size (this means the lookup above is WRONG)... !!! FIX !!!
832         UINT32 m = (REG(A1_FLAGS) >> 9) & 0x03, e = (REG(A1_FLAGS) >> 11) & 0x0F;
833         a1_width = ((0x04 | m) << e) >> 2;//*/
834
835         a2_x = (REG(A2_PIXEL) & 0x0000FFFF) << 16;
836         a2_y = (REG(A2_PIXEL) & 0xFFFF0000);
837 //According to the JTRM, X is restricted to 15 bits and Y is restricted to 12.
838 //But it seems to fuck up T2K! !!! FIX !!!
839 //      a2_x &= 0x7FFFFFFF, a2_y &= 0x0FFFFFFF;
840
841 //      a2_width = blitter_scanline_width[((REG(A2_FLAGS) & 0x00007E00) >> 9)];
842 // According to JTRM, this must give a *whole number* of phrases in the current
843 // pixel size (this means the lookup above is WRONG)... !!! FIX !!!
844         m = (REG(A2_FLAGS) >> 9) & 0x03, e = (REG(A2_FLAGS) >> 11) & 0x0F;
845         a2_width = ((0x04 | m) << e) >> 2;//*/
846         a2_mask_x = ((REG(A2_MASK) & 0x0000FFFF) << 16) | 0xFFFF;
847         a2_mask_y = (REG(A2_MASK) & 0xFFFF0000) | 0xFFFF;
848
849         // Check for "use mask" flag
850         if (!(REG(A2_FLAGS) & 0x8000))
851         {
852                 a2_mask_x = 0xFFFFFFFF; // must be 16.16
853                 a2_mask_y = 0xFFFFFFFF; // must be 16.16
854         }
855
856         a1_phrase_mode = 0;
857
858         // According to the official documentation, a hardware bug ties A2's yadd bit to A1's...
859         a2_yadd = a1_yadd = (YADD1_A1 ? 1 << 16 : 0);
860
861         if (YSIGNSUB_A1)
862                 a1_yadd = -a1_yadd;
863
864         // determine a1_xadd
865         switch (xadd_a1_control)
866         {
867         case XADDPHR:
868 // This is a documented Jaguar bug relating to phrase mode and truncation... Look into it!
869                 // add phrase offset to X and truncate
870                 a1_xadd = 1 << 16;
871                 a1_phrase_mode = 1;
872                 break;
873         case XADDPIX:
874                 // add pixelsize (1) to X
875                 a1_xadd = 1 << 16;
876                 break;
877         case XADD0:     
878                 // add zero (for those nice vertical lines)
879                 a1_xadd = 0;
880                 break;
881         case XADDINC:
882                 // add the contents of the increment register
883                 a1_xadd = (REG(A1_INC) << 16)            | (REG(A1_FINC) & 0xFFFF);
884                 a1_yadd = (REG(A1_INC) & 0xFFFF0000) | (REG(A1_FINC) >> 16);
885                 break;
886         }
887
888
889 //Blit! (0011D000 -> 000B9600) count: 228 x 1, A1/2_FLAGS: 00073820/00064220 [cmd: 41802801]
890 //  A1 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 128 (1C), addctl: XADDINC YADD1 XSIGNADD YSIGNADD
891 //  A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 320 (21), addctl: XADD0 YADD1 XSIGNADD YSIGNADD
892 //if (YADD1_A1 && YADD1_A2 && xadd_a2_control == XADD0 && xadd_a1_control == XADDINC)// &&
893 //      UINT32 a1f = REG(A1_FLAGS), a2f = REG(A2_FLAGS);
894 //Ok, so this ISN'T it... Prolly the XADDPHR code above that's doing it...
895 //if (REG(A1_FLAGS) == 0x00073820 && REG(A2_FLAGS) == 0x00064220 && cmd == 0x41802801)
896 //        A1 x/y: 14368/7, A2 x/y: 150/36
897 //This is it... The problem...
898 //if ((a1_x >> 16) == 14368) // 14368 = $3820
899 //      return; //Lesse what we got...
900
901         if (XSIGNSUB_A1)
902                 a1_xadd = -a1_xadd;
903
904         if (YSIGNSUB_A2)
905                 a2_yadd = -a2_yadd;
906
907         a2_phrase_mode = 0;
908
909         // determine a2_xadd
910         switch (xadd_a2_control)
911         {
912         case XADDPHR:
913                 // add phrase offset to X and truncate
914                 a2_xadd = 1 << 16;
915                 a2_phrase_mode = 1;
916                 break;
917         case XADDPIX:
918                 // add pixelsize (1) to X
919                 a2_xadd = 1 << 16;
920                 break;
921         case XADD0:     
922                 // add zero (for those nice vertical lines)
923                 a2_xadd = 0;
924                 break;
925 //This really isn't a valid bit combo for A2... Shouldn't this cause the blitter to just say no?
926         case XADDINC:
927 WriteLog("BLIT: Asked to use invalid bit combo (XADDINC) for A2...\n");
928                 // add the contents of the increment register
929                 // since there is no register for a2 we just add 1
930 //Let's do nothing, since it's not listed as a valid bit combo...
931 //              a2_xadd = 1 << 16;
932                 break;
933         }
934
935         if (XSIGNSUB_A2)
936                 a2_xadd = -a2_xadd;
937
938         // Modify outer loop steps based on blitter command
939
940         a1_step_x = 0;
941         a1_step_y = 0;
942         a2_step_x = 0;
943         a2_step_y = 0;
944
945         if (UPDA1F)
946                 a1_step_x = (REG(A1_FSTEP) & 0xFFFF),
947                 a1_step_y = (REG(A1_FSTEP) >> 16);
948
949         if (UPDA1)
950                 a1_step_x |= ((REG(A1_STEP) & 0x0000FFFF) << 16),
951                 a1_step_y |= ((REG(A1_STEP) & 0xFFFF0000));
952
953         if (UPDA2)
954                 a2_step_x = (REG(A2_STEP) & 0x0000FFFF) << 16,
955                 a2_step_y = (REG(A2_STEP) & 0xFFFF0000);
956
957         outer_loop = n_lines;
958
959         // Clipping...
960
961         if (CLIPA1)
962                 a1_clip_x = REG(A1_CLIP) & 0x7FFF,
963                 a1_clip_y = (REG(A1_CLIP) >> 16) & 0x7FFF;
964
965 // This phrase sizing is incorrect as well... !!! FIX !!!
966 // Err, this is pixel size... (and it's OK)
967         a2_psize = 1 << ((REG(A2_FLAGS) >> 3) & 0x07);
968         a1_psize = 1 << ((REG(A1_FLAGS) >> 3) & 0x07);
969
970         // Z-buffering
971         if (GOURZ)
972         {
973 //              zadd = JaguarReadLong(0xF02274, BLITTER);
974                 zadd = REG(ZINC);
975
976                 for(int v=0; v<4; v++)
977 //                      z_i[v] = (int32)JaguarReadLong(0xF0228C + (v << 2), BLITTER);
978                         z_i[v] = REG(PHRASEZ0 + v*4);
979         }
980
981         // Gouraud shading
982         if (GOURD || GOURZ || SRCSHADE)
983         {
984 /*              gd_c[0] = JaguarReadByte(0xF02268, BLITTER);
985                 gd_i[0] = JaguarReadByte(0xF02269, BLITTER);
986                 gd_i[0] <<= 16;
987                 gd_i[0] |= JaguarReadWord(0xF02240, BLITTER);//*/
988                 gd_c[0] = blitter_ram[PATTERNDATA + 0];
989                 gd_i[0] = ((uint32)blitter_ram[PATTERNDATA + 1] << 16)
990                         | ((uint32)blitter_ram[SRCDATA + 0] << 8) | blitter_ram[SRCDATA + 1];
991
992 /*              gd_c[1] = JaguarReadByte(0xF0226A, BLITTER);
993                 gd_i[1] = JaguarReadByte(0xF0226B, BLITTER);
994                 gd_i[1] <<= 16;
995                 gd_i[1] |= JaguarReadWord(0xF02242, BLITTER);//*/
996                 gd_c[1] = blitter_ram[PATTERNDATA + 2];
997                 gd_i[1] = ((uint32)blitter_ram[PATTERNDATA + 3] << 16)
998                         | ((uint32)blitter_ram[SRCDATA + 2] << 8) | blitter_ram[SRCDATA + 3];
999
1000 /*              gd_c[2] = JaguarReadByte(0xF0226C, BLITTER);
1001                 gd_i[2] = JaguarReadByte(0xF0226D, BLITTER);
1002                 gd_i[2] <<= 16;
1003                 gd_i[2] |= JaguarReadWord(0xF02244, BLITTER);//*/
1004                 gd_c[2] = blitter_ram[PATTERNDATA + 4];
1005                 gd_i[2] = ((uint32)blitter_ram[PATTERNDATA + 5] << 16)
1006                         | ((uint32)blitter_ram[SRCDATA + 4] << 8) | blitter_ram[SRCDATA + 5];
1007
1008 /*              gd_c[3] = JaguarReadByte(0xF0226E, BLITTER);
1009                 gd_i[3] = JaguarReadByte(0xF0226F, BLITTER);
1010                 gd_i[3] <<= 16; 
1011                 gd_i[3] |= JaguarReadWord(0xF02246, BLITTER);//*/
1012                 gd_c[3] = blitter_ram[PATTERNDATA + 6];
1013                 gd_i[3] = ((uint32)blitter_ram[PATTERNDATA + 7] << 16)
1014                         | ((uint32)blitter_ram[SRCDATA + 6] << 8) | blitter_ram[SRCDATA + 7];
1015
1016 //              gouraud_add = JaguarReadLong(0xF02270, BLITTER);
1017                 gouraud_add = REG(INTENSITYINC);
1018                 
1019                 gd_ia = gouraud_add & 0x00FFFFFF;
1020                 if (gd_ia & 0x00800000)
1021                         gd_ia = 0xFF000000 | gd_ia;
1022
1023                 gd_ca = (gouraud_add >> 24) & 0xFF;
1024                 if (gd_ca & 0x00000080)
1025                         gd_ca = 0xFFFFFF00 | gd_ca;
1026         }
1027
1028         // fix for zoop! and syndicate
1029 /*      if ((jaguar_mainRom_crc32==0x501be17c)||
1030                 (jaguar_mainRom_crc32==0x70895c51)||
1031                 (jaguar_mainRom_crc32==0x0f1f1497)||
1032                 (jaguar_mainRom_crc32==0xfc8f0dcd)
1033            )
1034         {
1035                 if (a1_step_x < 0)
1036                         a1_step_x = (-n_pixels) * 65536;
1037
1038                 if (a2_step_x < 0)
1039                         a2_step_x = (-n_pixels) * 65536;;
1040         }//*/
1041
1042 #ifdef LOG_BLITS
1043         if (start_logging)
1044         {
1045                 WriteLog("Blit!\n");
1046                 WriteLog("  cmd      = 0x%.8x\n",cmd);
1047                 WriteLog("  a1_base  = %08X\n", a1_addr);
1048                 WriteLog("  a1_pitch = %d\n", a1_pitch);
1049                 WriteLog("  a1_psize = %d\n", a1_psize);
1050                 WriteLog("  a1_width = %d\n", a1_width);
1051                 WriteLog("  a1_xadd  = %f (phrase=%d)\n", (float)a1_xadd / 65536.0, a1_phrase_mode);
1052                 WriteLog("  a1_yadd  = %f\n", (float)a1_yadd / 65536.0);
1053                 WriteLog("  a1_xstep = %f\n", (float)a1_step_x / 65536.0);
1054                 WriteLog("  a1_ystep = %f\n", (float)a1_step_y / 65536.0);
1055                 WriteLog("  a1_x     = %f\n", (float)a1_x / 65536.0);
1056                 WriteLog("  a1_y     = %f\n", (float)a1_y / 65536.0);
1057                 WriteLog("  a1_zoffs = %i\n",a1_zoffs);
1058
1059                 WriteLog("  a2_base  = %08X\n", a2_addr);
1060                 WriteLog("  a2_pitch = %d\n", a2_pitch);
1061                 WriteLog("  a2_psize = %d\n", a2_psize);
1062                 WriteLog("  a2_width = %d\n", a2_width);
1063                 WriteLog("  a2_xadd  = %f (phrase=%d)\n", (float)a2_xadd / 65536.0, a2_phrase_mode);
1064                 WriteLog("  a2_yadd  = %f\n", (float)a2_yadd / 65536.0);
1065                 WriteLog("  a2_xstep = %f\n", (float)a2_step_x / 65536.0);
1066                 WriteLog("  a2_ystep = %f\n", (float)a2_step_y / 65536.0);
1067                 WriteLog("  a2_x     = %f\n", (float)a2_x / 65536.0);
1068                 WriteLog("  a2_y     = %f\n", (float)a2_y / 65536.0);
1069                 WriteLog("  a2_mask_x= 0x%.4x\n",a2_mask_x);
1070                 WriteLog("  a2_mask_y= 0x%.4x\n",a2_mask_y);
1071                 WriteLog("  a2_zoffs = %i\n",a2_zoffs);
1072
1073                 WriteLog("  count    = %d x %d\n", n_pixels, n_lines);
1074
1075                 WriteLog("  command  = %08X\n", cmd);
1076                 WriteLog("  dsten    = %i\n",DSTEN);
1077                 WriteLog("  srcen    = %i\n",SRCEN);
1078                 WriteLog("  patdsel  = %i\n",PATDSEL);
1079                 WriteLog("  color    = 0x%.8x\n",REG(PATTERNDATA));
1080                 WriteLog("  dcompen  = %i\n",DCOMPEN);
1081                 WriteLog("  bcompen  = %i\n",BCOMPEN);
1082                 WriteLog("  cmpdst   = %i\n",CMPDST);
1083                 WriteLog("  GOURZ   = %i\n",GOURZ);
1084                 WriteLog("  GOURD   = %i\n",GOURD);
1085                 WriteLog("  SRCSHADE= %i\n",SRCSHADE);
1086         }       
1087 #endif
1088
1089 //NOTE: Pitch is ignored!
1090
1091 //This *might* be the altimeter blits (they are)...
1092 //On captured screen, x-pos for black (inner) is 259, for pink is 257
1093 //Black is short by 3, pink is short by 1...
1094 /*
1095 Blit! (00110000 <- 000BF010) count: 9 x 31, A1/2_FLAGS: 000042E2/00010020 [cmd: 00010200]
1096  CMD -> src:  dst:  misc:  a1ctl: UPDA1  mode:  ity: PATDSEL z-op:  op: LFU_CLEAR ctrl: 
1097   A1 -> pitch: 4 phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
1098   A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
1099         A1 x/y: 262/124, A2 x/y: 128/0
1100 Blit! (00110000 <- 000BF010) count: 5 x 38, A1/2_FLAGS: 000042E2/00010020 [cmd: 00010200]
1101  CMD -> src:  dst:  misc:  a1ctl: UPDA1  mode:  ity: PATDSEL z-op:  op: LFU_CLEAR ctrl: 
1102   A1 -> pitch: 4 phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
1103   A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
1104         A1 x/y: 264/117, A2 x/y: 407/0
1105
1106 Blit! (00110000 <- 000BF010) count: 9 x 23, A1/2_FLAGS: 000042E2/00010020 [cmd: 00010200]
1107  CMD -> src:  dst:  misc:  a1ctl: UPDA1  mode:  ity: PATDSEL z-op:  op: LFU_CLEAR ctrl: 
1108   A1 step values: -10 (X), 1 (Y)
1109   A1 -> pitch: 4(2) phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
1110   A2 -> pitch: 1(0) phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
1111         A1 x/y: 262/132, A2 x/y: 129/0
1112 Blit! (00110000 <- 000BF010) count: 5 x 27, A1/2_FLAGS: 000042E2/00010020 [cmd: 00010200]
1113  CMD -> src:  dst:  misc:  a1ctl: UPDA1  mode:  ity: PATDSEL z-op:  op: LFU_CLEAR ctrl: 
1114   A1 step values: -8 (X), 1 (Y)
1115   A1 -> pitch: 4(2) phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
1116   A2 -> pitch: 1(0) phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
1117         A1 x/y: 264/128, A2 x/y: 336/0
1118
1119   264v       vCursor ends up here...
1120      xxxxx...`
1121      111122223333
1122
1123 262v         vCursor ends up here...
1124    xxxxxxxxx.'
1125  1111222233334444
1126
1127 Fixed! Now for more:
1128
1129 ; This looks like the ship icon in the upper left corner...
1130
1131 Blit! (00110000 <- 0010B2A8) count: 11 x 12, A1/2_FLAGS: 000042E2/00000020 [cmd: 09800609]
1132  CMD -> src: SRCEN  dst: DSTEN  misc:  a1ctl: UPDA1 UPDA2 mode:  ity:  z-op:  op: LFU_REPLACE ctrl: DCOMPEN 
1133   A1 step values: -12 (X), 1 (Y)
1134   A2 step values: 0 (X), 0 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
1135   A1 -> pitch: 4 phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
1136   A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
1137         A1 x/y: 20/24, A2 x/y: 5780/0
1138
1139 Also fixed!
1140
1141 More (not sure this is a blitter problem as much as it's a GPU problem):
1142 All but the "M" are trashed...
1143 This does *NOT* look like a blitter problem, as it's rendering properly...
1144 Actually, if you look at the A1 step values, there IS a discrepancy!
1145
1146 ; D
1147
1148 Blit! (00110000 <- 0010B2A8) count: 12 x 12, A1/2_FLAGS: 000042E2/00000020 [cmd: 09800609]
1149  CMD -> src: SRCEN  dst: DSTEN  misc:  a1ctl: UPDA1 UPDA2 mode:  ity:  z-op:  op: LFU_REPLACE ctrl: DCOMPEN 
1150   A1 step values: -14 (X), 1 (Y)
1151   A2 step values: -4 (X), 0 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
1152   A1 -> pitch: 4 phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
1153   A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
1154         A1 x/y: 134/144, A2 x/y: 2516/0
1155 ;129,146: +5,-2
1156
1157 ; E
1158
1159 Blit! (00110000 <- 0010B2A8) count: 12 x 12, A1/2_FLAGS: 000042E2/00000020 [cmd: 09800609]
1160  CMD -> src: SRCEN  dst: DSTEN  misc:  a1ctl: UPDA1 UPDA2 mode:  ity:  z-op:  op: LFU_REPLACE ctrl: DCOMPEN 
1161   A1 step values: -13 (X), 1 (Y)
1162   A2 step values: -4 (X), 0 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
1163   A1 -> pitch: 4 phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
1164   A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
1165         A1 x/y: 147/144, A2 x/y: 2660/0
1166
1167 ; M
1168
1169 Blit! (00110000 <- 0010B2A8) count: 12 x 12, A1/2_FLAGS: 000042E2/00000020 [cmd: 09800609]
1170  CMD -> src: SRCEN  dst: DSTEN  misc:  a1ctl: UPDA1 UPDA2 mode:  ity:  z-op:  op: LFU_REPLACE ctrl: DCOMPEN 
1171   A1 step values: -12 (X), 1 (Y)
1172   A2 step values: 0 (X), 0 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
1173   A1 -> pitch: 4 phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
1174   A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
1175         A1 x/y: 160/144, A2 x/y: 3764/0
1176
1177 ; O
1178
1179 Blit! (00110000 <- 0010B2A8) count: 12 x 12, A1/2_FLAGS: 000042E2/00000020 [cmd: 09800609]
1180  CMD -> src: SRCEN  dst: DSTEN  misc:  a1ctl: UPDA1 UPDA2 mode:  ity:  z-op:  op: LFU_REPLACE ctrl: DCOMPEN 
1181   A1 step values: -15 (X), 1 (Y)
1182   A2 step values: -4 (X), 0 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
1183   A1 -> pitch: 4 phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
1184   A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
1185         A1 x/y: 173/144, A2 x/y: 4052/0
1186
1187 */
1188 extern int blit_start_log;
1189 //extern int op_start_log;
1190 if (blit_start_log)
1191 {
1192         char * ctrlStr[4] = { "XADDPHR\0", "XADDPIX\0", "XADD0\0", "XADDINC\0" };
1193         char * bppStr[8] = { "1bpp\0", "2bpp\0", "4bpp\0", "8bpp\0", "16bpp\0", "32bpp\0", "???\0", "!!!\0" };
1194         char * opStr[16] = { "LFU_CLEAR", "LFU_NSAND", "LFU_NSAD", "LFU_NOTS", "LFU_SAND", "LFU_NOTD", "LFU_N_SXORD", "LFU_NSORND",
1195                 "LFU_SAD", "LFU_XOR", "LFU_D", "LFU_NSORD", "LFU_REPLACE", "LFU_SORND", "LFU_SORD", "LFU_ONE" };
1196         uint32 /*src = cmd & 0x07, dst = (cmd >> 3) & 0x07, misc = (cmd >> 6) & 0x03,
1197                 a1ctl = (cmd >> 8) & 0x07,*/ mode = (cmd >> 11) & 0x07/*, ity = (cmd >> 14) & 0x0F,
1198                 zop = (cmd >> 18) & 0x07, op = (cmd >> 21) & 0x0F, ctrl = (cmd >> 25) & 0x3F*/;
1199         UINT32 a1f = REG(A1_FLAGS), a2f = REG(A2_FLAGS);
1200         uint32 p1 = a1f & 0x07, p2 = a2f & 0x07,
1201                 d1 = (a1f >> 3) & 0x07, d2 = (a2f >> 3) & 0x07,
1202                 zo1 = (a1f >> 6) & 0x07, zo2 = (a2f >> 6) & 0x07,
1203                 w1 = (a1f >> 9) & 0x3F, w2 = (a2f >> 9) & 0x3F,
1204                 ac1 = (a1f >> 16) & 0x1F, ac2 = (a2f >> 16) & 0x1F;
1205         UINT32 iw1 = ((0x04 | (w1 & 0x03)) << ((w1 & 0x3C) >> 2)) >> 2;
1206         UINT32 iw2 = ((0x04 | (w2 & 0x03)) << ((w2 & 0x3C) >> 2)) >> 2;
1207         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);
1208 //      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);
1209
1210         WriteLog(" CMD -> src: %s%s%s ", (cmd & 0x0001 ? "SRCEN " : ""), (cmd & 0x0002 ? "SRCENZ " : ""), (cmd & 0x0004 ? "SRCENX" : ""));
1211         WriteLog("dst: %s%s%s ", (cmd & 0x0008 ? "DSTEN " : ""), (cmd & 0x0010 ? "DSTENZ " : ""), (cmd & 0x0020 ? "DSTWRZ" : ""));
1212         WriteLog("misc: %s%s ", (cmd & 0x0040 ? "CLIP_A1 " : ""), (cmd & 0x0080 ? "???" : ""));
1213         WriteLog("a1ctl: %s%s%s ", (cmd & 0x0100 ? "UPDA1F " : ""), (cmd & 0x0200 ? "UPDA1 " : ""), (cmd & 0x0400 ? "UPDA2" : ""));
1214         WriteLog("mode: %s%s%s ", (cmd & 0x0800 ? "DSTA2 " : ""), (cmd & 0x1000 ? "GOURD " : ""), (cmd & 0x2000 ? "ZBUFF" : ""));
1215         WriteLog("ity: %s%s%s ", (cmd & 0x4000 ? "TOPBEN " : ""), (cmd & 0x8000 ? "TOPNEN " : ""), (cmd & 0x00010000 ? "PATDSEL" : ""));
1216         WriteLog("z-op: %s%s%s ", (cmd & 0x00040000 ? "ZMODELT " : ""), (cmd & 0x00080000 ? "ZMODEEQ " : ""), (cmd & 0x00100000 ? "ZMODEGT" : ""));
1217         WriteLog("op: %s ", opStr[(cmd >> 21) & 0x0F]);
1218         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" : ""));
1219
1220         if (UPDA1)
1221                 WriteLog("  A1 step values: %d (X), %d (Y)\n", a1_step_x >> 16, a1_step_y >> 16);
1222
1223         if (UPDA2)
1224                 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);
1225
1226         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"));
1227         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"));
1228         WriteLog("        A1 x/y: %d/%d, A2 x/y: %d/%d Pattern: %08X%08X\n", a1_x >> 16, a1_y >> 16, a2_x >> 16, a2_y >> 16, REG(PATTERNDATA), REG(PATTERNDATA + 4));
1229 //      blit_start_log = 0;
1230 //      op_start_log = 1;
1231 }
1232
1233         blitter_working = 1;
1234 //#ifndef USE_GENERIC_BLITTER
1235 //      if (!blitter_execute_cached_code(blitter_in_cache(cmd)))
1236 //#endif
1237         blitter_generic(cmd);
1238
1239 /*if (blit_start_log)
1240 {
1241         if (a1_addr == 0xF03000 && a2_addr == 0x004D58)
1242         {
1243                 WriteLog("\nBytes at 004D58:\n");
1244                 for(int i=0x004D58; i<0x004D58+(10*127*4); i++)
1245                         WriteLog("%02X ", JaguarReadByte(i));
1246                 WriteLog("\nBytes at F03000:\n");
1247                 for(int i=0xF03000; i<0xF03000+(6*127*4); i++)
1248                         WriteLog("%02X ", JaguarReadByte(i));
1249                 WriteLog("\n\n");
1250         }
1251 }//*/
1252
1253         blitter_working = 0;
1254 }
1255
1256 void blitter_init(void)
1257 {
1258         blitter_reset();
1259 }
1260
1261 void blitter_reset(void)
1262 {
1263         memset(blitter_ram, 0x00, 0xA0);
1264 }
1265
1266 void blitter_done(void)
1267 {
1268         WriteLog("BLIT: Done.\n");
1269 }
1270
1271 uint8 BlitterReadByte(uint32 offset, uint32 who/*=UNKNOWN*/)
1272 {
1273         offset &= 0xFF;
1274
1275         // status register
1276         if (offset == (0x38 + 3))
1277                 return 0x01;    // always idle
1278
1279 //Attempted fix for AvP:
1280         if (offset >= 0x04 && offset <= 0x07)
1281 //              return (offset > 0x05 ? blitter_ram[PIXLINECOUNTER + offset - 0x04] : 0x00);
1282 //              return 0x00;    // WO register! What does it expect to see here???
1283 //This is it. I wonder if it just ignores the lower three bits?
1284                 return blitter_ram[A1_PIXEL + offset - 0x04];
1285
1286         return blitter_ram[offset];
1287 }
1288
1289 //Crappy!
1290 uint16 BlitterReadWord(uint32 offset, uint32 who/*=UNKNOWN*/)
1291 {
1292         return ((uint16)BlitterReadByte(offset, who) << 8) | (uint16)BlitterReadByte(offset+1, who);
1293 }
1294
1295 //Crappy!
1296 uint32 BlitterReadLong(uint32 offset, uint32 who/*=UNKNOWN*/)
1297 {
1298         return (BlitterReadWord(offset, who) << 16) | BlitterReadWord(offset+2, who);
1299 }
1300
1301 void BlitterWriteByte(uint32 offset, uint8 data, uint32 who/*=UNKNOWN*/)
1302 {
1303 /*if (offset & 0xFF == 0x7B)
1304         WriteLog("--> Wrote to B_STOP: value -> %02X\n", data);*/
1305         offset &= 0xFF;
1306
1307 //      if ((offset >= 0x7C) && (offset <= 0x9B))
1308         // This handles writes to INTENSITY0-3 by also writing them to their proper places in
1309         // PATTERNDATA & SOURCEDATA (should do the same for the Z registers! !!! FIX !!! [DONE])
1310         if ((offset >= 0x7C) && (offset <= 0x9B))//8B))
1311         {
1312                 switch (offset)
1313                 {
1314                 // INTENSITY registers 0-3
1315                 case 0x7C: break;
1316                 case 0x7D: blitter_ram[PATTERNDATA + 1] = data; break;
1317                 case 0x7E: blitter_ram[SRCDATA + 0] = data; break;
1318                 case 0x7F: blitter_ram[SRCDATA + 1] = data; break;
1319
1320                 case 0x80: break;
1321                 case 0x81: blitter_ram[PATTERNDATA + 3] = data; break;
1322                 case 0x82: blitter_ram[SRCDATA + 2] = data; break;
1323                 case 0x83: blitter_ram[SRCDATA + 3] = data; break;
1324                 
1325                 case 0x84: break;
1326                 case 0x85: blitter_ram[PATTERNDATA + 5] = data; break;
1327                 case 0x86: blitter_ram[SRCDATA + 4] = data; break;
1328                 case 0x87: blitter_ram[SRCDATA + 5] = data; break;
1329                 
1330                 case 0x88: break;
1331                 case 0x89: blitter_ram[PATTERNDATA + 7] = data; break;
1332                 case 0x8A: blitter_ram[SRCDATA + 6] = data; break;
1333                 case 0x8B: blitter_ram[SRCDATA + 7] = data; break;
1334
1335                 // Z registers 0-3
1336                 case 0x8C: blitter_ram[SRCZINT + 0] = data; break;
1337                 case 0x8D: blitter_ram[SRCZINT + 1] = data; break;
1338                 case 0x8E: blitter_ram[SRCZFRAC + 0] = data; break;
1339                 case 0x8F: blitter_ram[SRCZFRAC + 1] = data; break;
1340
1341                 case 0x90: blitter_ram[SRCZINT + 2] = data; break;
1342                 case 0x91: blitter_ram[SRCZINT + 3] = data; break;
1343                 case 0x92: blitter_ram[SRCZFRAC + 2] = data; break;
1344                 case 0x93: blitter_ram[SRCZFRAC + 3] = data; break;
1345                 
1346                 case 0x94: blitter_ram[SRCZINT + 4] = data; break;
1347                 case 0x95: blitter_ram[SRCZINT + 5] = data; break;
1348                 case 0x96: blitter_ram[SRCZFRAC + 4] = data; break;
1349                 case 0x97: blitter_ram[SRCZFRAC + 5] = data; break;
1350                 
1351                 case 0x98: blitter_ram[SRCZINT + 6] = data; break;
1352                 case 0x99: blitter_ram[SRCZINT + 7] = data; break;
1353                 case 0x9A: blitter_ram[SRCZFRAC + 6] = data; break;
1354                 case 0x9B: blitter_ram[SRCZFRAC + 7] = 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 {
1385 /*extern int blit_start_log;
1386 extern bool doGPUDis;
1387 if (blit_start_log)
1388 {
1389         WriteLog("BLIT: Blitter started by %s...\n", whoName[who]);
1390         doGPUDis = true;
1391 }//*/
1392                 blitter_blit(GET32(blitter_ram, 0x38));
1393 }
1394 }
1395 //F02278,9,A,B
1396
1397 void BlitterWriteLong(uint32 offset, uint32 data, uint32 who/*=UNKNOWN*/)
1398 {
1399 //#if 1
1400 /*      if ((offset & 0xFF) == A1_PIXEL && (data & 0xFFFF) == 14368)
1401         {
1402                 WriteLog("\n3\nA1_PIXEL written by %s (%u)...\n\n\n", whoName[who], data);
1403 extern bool doGPUDis;
1404 doGPUDis = true;
1405         }//*/
1406 //#endif
1407
1408         BlitterWriteWord(offset, data >> 16, who);
1409         BlitterWriteWord(offset+2, data & 0xFFFF, who);
1410 }