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