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