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