3 //#define USE_GENERIC_BLITTER
8 extern int jaguar_active_memory_dumps;
10 #define REG(A) blitter_reg_read(A)
11 #define WREG(A,D) blitter_reg_write(A,D)
13 int start_logging = 0;
15 static uint8 blitter_ram[0x100];
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)
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)
60 #define Z_OP_INF (cmd&0x00040000)
61 #define Z_OP_EQU (cmd&0x00080000)
62 #define Z_OP_SUP (cmd&0x00100000)
64 #define CMPDST (cmd&0x02000000)
65 #define BCOMPEN (cmd&0x04000000)
66 #define DCOMPEN (cmd&0x08000000)
68 #define LFU_NAN (cmd&0x00200000)
69 #define LFU_NA (cmd&0x00400000)
70 #define LFU_AN (cmd&0x00800000)
71 #define LFU_A (cmd&0x01000000)
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)
88 #define XSIGNSUB_A1 (REG(A1_FLAGS)&0x80000)
89 #define XSIGNSUB_A2 (REG(A2_FLAGS)&0x80000)
91 #define YSIGNSUB_A1 (REG(A1_FLAGS)&0x100000)
92 #define YSIGNSUB_A2 (REG(A2_FLAGS)&0x100000)
94 #define YADD1_A1 (REG(A1_FLAGS)&0x40000)
95 #define YADD1_A2 (REG(A2_FLAGS)&0x40000)
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)
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)
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)
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)))
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)))
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)))
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)
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)))
138 #define READ_ZDATA(a,f) (READ_ZDATA_16(a))
140 // 16 bpp z data write
141 #define WRITE_ZDATA_16(a,d) { jaguar_word_write(a##_addr+(ZDATA_OFFSET_16(a)<<1),d); }
144 #define WRITE_ZDATA(a,f,d) WRITE_ZDATA_16(a,d);
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))
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))
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))
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))
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))
161 // 32 bpp r data read
162 #define READ_RDATA_32(r,a,p) ((p) ? REG(r+(((UINT32)a##_x>>14)&4)) : REG(r))
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)
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))); }
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))); }
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))); }
184 #define WRITE_PIXEL_8(a,d) { jaguar_byte_write(a##_addr+PIXEL_OFFSET_8(a),d); }
186 // 16 bpp pixel write
187 #define WRITE_PIXEL_16(a,d) { jaguar_word_write(a##_addr+(PIXEL_OFFSET_16(a)<<1),d); }
189 // 32 bpp pixel write
190 #define WRITE_PIXEL_32(a,d) { jaguar_long_write(a##_addr+(PIXEL_OFFSET_32(a)<<2),d); }
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; \
205 // Width in Pixels of a Scanline
206 static uint32 blitter_scanline_width[48] =
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,
216 static uint8 * tom_ram_8;
217 static uint8 * paletteRam;
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;
239 static int32 a1_width;
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];
266 static int gd_ia,gd_ca;
267 static int colour_index = 0;
269 static uint32 z_i[4];
271 static uint8 blitter_code_cache[4096];
272 static uint8 * blitter_ptr;
273 uint8 blitter_working = 0;
275 typedef void (blitter_fn)(void);
277 typedef struct s_blitter_cache
283 struct s_blitter_cache *next;
284 struct s_blitter_cache *prev;
285 } s_blitter_code_cache;
287 s_blitter_cache *blitter_cache[256];
289 uint8 blitter_cache_init=0;
290 static uint8 BPP_LUT[8]={1,2,4,8,16,32,0,0};
292 FILE *blitters_code_fp;
293 FILE *blitters_code_init_fp;
295 //////////////////////////////////////////////////////////////////////////////
296 // build C code for the specified blitter
297 //////////////////////////////////////////////////////////////////////////////
301 //////////////////////////////////////////////////////////////////////////////
302 void blitter_gen_c_code(FILE *fp, uint32 cmd,uint32 hashcode)
304 static uint8 inhibit_modified=0;
306 fprintf(fp,"#ifndef blitter_code_0x%.8x\n",hashcode);
307 fprintf(fp,"#define blitter_code_0x%.8x\n",hashcode);
309 fprintf(fp,"void blitter_0x%.8x(void)\n",hashcode);
311 fprintf(fp,"\twhile (outer_loop--)\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");
343 // load src data and Z
346 fprintf(fp,"\t\t\tsrcdata = READ_PIXEL_%i(%s);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],src);
348 fprintf(fp,"\t\t\tsrczdata = READ_ZDATA_%i(%s);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],src);
351 fprintf(fp,"\t\t\tsrczdata = READ_RDATA_%i(SRCZINT, %s, %s_phrase_mode);\n",BPP_LUT[(((REG(src_flags))>>3)&0x07)],src,src);
355 fprintf(fp,"\t\t\tsrcdata = READ_RDATA_%i(SRCDATA, %s, %s_phrase_mode);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],src,src);
357 fprintf(fp,"\t\t\tsrczdata = READ_RDATA_%i(SRCZINT, %s, %s_phrase_mode);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],src,src);
360 // load dst data and Z
363 fprintf(fp,"\t\t\tdstdata = READ_PIXEL_%i(%s);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],dst);
365 fprintf(fp,"\t\t\tdstzdata = READ_ZDATA_%i(%s);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],dst);
367 fprintf(fp,"\t\t\tdstzdata = READ_RDATA_%i(DSTZ, %s, %s_phrase_mode);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],dst,dst);
371 fprintf(fp,"\t\t\tdstdata = READ_RDATA_%i(DSTDATA, %s, %s_phrase_mode);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],dst,dst);
374 fprintf(fp,"\t\t\tdstzdata = READ_RDATA_%i(DSTZ, %s, %s_phrase_mode);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],dst,dst);
378 if ((cmd & 0x00000040)&&(!DSTA2))
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");
386 fprintf(fp,"\t\t\tsrczdata=z_i[colour_index]>>16;\n");
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;}
393 // apply data comparator
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);
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);
410 // compute the write data and store
411 if (inhibit_modified) fprintf(fp,"\t\t\tif (!inhibit)\n\t\t\t{\n");
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);
420 // intensity addition
421 fprintf(fp,"\t\t\t\twritedata = (srcdata & 0xff) + (dstdata & 0xff);\n");
423 fprintf(fp,"\t\t\t\tif (writedata > 0xff) writedata = 0xff;\n");
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");
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");
438 fprintf(fp,"\t\t\t\twritedata = ((gd_c[colour_index])<<8)|(gd_i[colour_index]>>16);\n");
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");
455 if (inhibit_modified)
457 fprintf(fp,"\t\t\t} else { srczdata=dstzdata; writedata=dstdata; }\n");
460 if ((DSTA2?a2_phrase_mode:a1_phrase_mode) || BKGWREN)
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);
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");
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");
481 fprintf(fp,"\t\t\tz_i[colour_index]+=zadd;\n");
483 if ((GOURD)||(SRCSHADE))
485 fprintf(fp,"\t\t\tgd_i[colour_index] += gd_ia;\n");
486 fprintf(fp,"\t\t\tgd_c[colour_index] += gd_ca;\n");
488 if ((GOURD)||(SRCSHADE)||(GOURZ))
491 fprintf(fp,"\t\t\t colour_index=(colour_index+1)&0x3;\n");
493 fprintf(fp,"\t\t}\n");
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");
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");
506 fprintf(fp,"#endif\n");
509 //////////////////////////////////////////////////////////////////////////////
510 // Generate a start of function in x86 assembly
511 //////////////////////////////////////////////////////////////////////////////
515 //////////////////////////////////////////////////////////////////////////////
516 void blitter_gen_start_of_function(void)
518 *blitter_ptr++=0x55; // push ebp
519 *blitter_ptr++=0x8b; // mov ebp,esp
522 //////////////////////////////////////////////////////////////////////////////
523 // Generate a end of function in x86 assembly
524 //////////////////////////////////////////////////////////////////////////////
528 //////////////////////////////////////////////////////////////////////////////
529 void blitter_gen_end_of_function(void)
531 *blitter_ptr++=0x8B; // mov esp,ebp
533 *blitter_ptr++=0x5D; // pop ebp
534 *blitter_ptr++=0xC3; // ret
536 //////////////////////////////////////////////////////////////////////////////
538 //////////////////////////////////////////////////////////////////////////////
542 //////////////////////////////////////////////////////////////////////////////
543 #define HASHCODE_BIT(C,B) if (C) hashcode|=(1<<B);
544 #define HASHCODE_BIT_TEST(B) (hashcode&(1<<B))
546 uint32 blitter_calc_hashcode(uint32 cmd)
548 uint32 hashcode=0x00000000;
550 // source and destination bit depth
551 hashcode|=((REG(A1_FLAGS)>>3)&0x07)<<0;
552 hashcode|=((REG(A2_FLAGS)>>3)&0x07)<<3;
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);
582 //////////////////////////////////////////////////////////////////////////////
583 // Build the blitter code for the current blitter operation in the cache
584 //////////////////////////////////////////////////////////////////////////////
588 //////////////////////////////////////////////////////////////////////////////
589 void blitter_build_cached_code(uint32 cmd, uint32 cache_index)
592 //////////////////////////////////////////////////////////////////////////////
593 // Check if the blitter code for the current blitter operation is cached
594 //////////////////////////////////////////////////////////////////////////////
598 //////////////////////////////////////////////////////////////////////////////
599 struct s_blitter_cache * blitter_in_cache(uint32 cmd)
602 uint32 hashcode=blitter_calc_hashcode(cmd);
604 fprintf(log_get(),"blitter: hashcode= 0x%.8x\n",hashcode);
606 struct s_blitter_cache *blitter_list=blitter_cache[hashcode>>24];
609 while (blitter_list->next)
611 blitter_list=blitter_list->next;
613 if (blitter_list->hashcode==hashcode)
614 return(blitter_list);
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;
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);
628 //fprintf(log_get(),"warning: using generic blitter for blitter 0x%.8x\n",hashcode);
632 #ifndef USE_GENERIC_BLITTER
633 #include "include/blit_c.h"
635 //////////////////////////////////////////////////////////////////////////////
636 // Execute the cached blitter code for the current blitter operation
637 //////////////////////////////////////////////////////////////////////////////
641 //////////////////////////////////////////////////////////////////////////////
642 uint32 blitter_execute_cached_code(struct s_blitter_cache *blitter)
644 if ((blitter==null)||(blitter->ready==0))
647 blitter_fn *fn=(blitter_fn*)blitter->code;
653 //////////////////////////////////////////////////////////////////////////////
655 //////////////////////////////////////////////////////////////////////////////
659 //////////////////////////////////////////////////////////////////////////////
660 void blitter_add(uint32 hashcode, uint8 *code)
662 struct s_blitter_cache *blitter_list=blitter_cache[(hashcode>>24)];
664 // fprintf(log_get(),"adding blitter for hashcode 0x%.8x\n",hashcode);
666 while (blitter_list->next)
668 blitter_list=blitter_list->next;
670 if (blitter_list->hashcode==hashcode)
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;
678 blitter_list->code=code;
679 blitter_list->hashcode=hashcode;
680 blitter_list->ready=1;
681 blitter_list->used=0;
683 //////////////////////////////////////////////////////////////////////////////
685 //////////////////////////////////////////////////////////////////////////////
689 //////////////////////////////////////////////////////////////////////////////
690 void blitter_list(void)
693 fprintf(log_get(),"Used blitters list:\n");
695 for (int i=0;i<256;i++)
697 struct s_blitter_cache *blitter_list=blitter_cache[i];
699 while (blitter_list->next)
701 blitter_list=blitter_list->next;
702 if (blitter_list->used)
703 fprintf(log_get(),"\t0%.8x\n",blitter_list->hashcode);
708 //////////////////////////////////////////////////////////////////////////////
710 //////////////////////////////////////////////////////////////////////////////
714 //////////////////////////////////////////////////////////////////////////////
715 void blitter_generic(uint32 cmd)
721 uint32 writedata = 0;
737 // load src data and Z
740 srcdata = READ_PIXEL(a2, REG(A2_FLAGS));
743 srczdata = READ_ZDATA(a2, REG(A2_FLAGS));
748 srczdata = READ_RDATA(SRCZINT, a2, REG(A2_FLAGS), a2_phrase_mode);
753 srcdata = READ_RDATA(SRCDATA, a2, REG(A2_FLAGS), a2_phrase_mode);
756 srczdata = READ_RDATA(SRCZINT, a2, REG(A2_FLAGS), a2_phrase_mode);
760 // load dst data and Z
763 dstdata = READ_PIXEL(a1, REG(A1_FLAGS));
766 dstzdata = READ_ZDATA(a1, REG(A1_FLAGS));
770 dstzdata = READ_RDATA(DSTZ, a1, REG(A1_FLAGS), a1_phrase_mode);
775 dstdata = READ_RDATA(DSTDATA, a1, REG(A1_FLAGS), a1_phrase_mode);
779 dstzdata = READ_RDATA(DSTZ, a1, REG(A1_FLAGS), a1_phrase_mode);
784 if (cmd & 0x00000040)
789 (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) ||
790 (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)
796 srczdata=z_i[colour_index]>>16;
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;
803 // apply data comparator
808 // compare source pixel with pattern pixel
809 if (srcdata == READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode))
814 // compare destination pixel with pattern pixel
815 if (dstdata == READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode))
818 if (a1_phrase_mode||a2_phrase_mode)
822 // compute the write data and store
827 // use pattern data for write data
828 writedata= READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode);
833 // intensity addition
834 writedata = (srcdata & 0xff) + (dstdata & 0xff);
835 if (!(TOPBEN) && writedata > 0xff)
837 writedata |= (srcdata & 0xf00) + (dstdata & 0xf00);
838 if (!(TOPNEN) && writedata > 0xfff)
840 writedata |= (srcdata & 0xf000) + (dstdata & 0xf000);
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;
850 writedata = ((gd_c[colour_index])<<8)|(gd_i[colour_index]>>16);
854 int intensity = srcdata & 0xFF;
855 int ia = gd_ia >> 16;
857 ia = 0xFFFFFF00 | ia;
863 writedata = (srcdata & 0xFF00) | intensity;
871 if (/*a1_phrase_mode || */BKGWREN || !inhibit)
873 // write to the destination
874 WRITE_PIXEL(a1, REG(A1_FLAGS), writedata);
875 if (DSTWRZ) WRITE_ZDATA(a1, REG(A1_FLAGS), srczdata);
880 // load src data and Z
883 srcdata = READ_PIXEL(a1, REG(A1_FLAGS));
886 srczdata = READ_ZDATA(a1, REG(A1_FLAGS));
891 srczdata = READ_RDATA(SRCZINT, a1, REG(A1_FLAGS), a1_phrase_mode);
896 srcdata = READ_RDATA(SRCDATA, a1, REG(A1_FLAGS), a1_phrase_mode);
899 srczdata = READ_RDATA(SRCZINT, a1, REG(A1_FLAGS), a1_phrase_mode);
903 // load dst data and Z
906 dstdata = READ_PIXEL(a2, REG(A2_FLAGS));
909 dstzdata = READ_ZDATA(a2, REG(A2_FLAGS));
913 dstzdata = READ_RDATA(DSTZ, a2, REG(A2_FLAGS), a2_phrase_mode);
918 dstdata = READ_RDATA(DSTDATA, a2, REG(A2_FLAGS), a2_phrase_mode);
922 dstzdata = READ_RDATA(DSTZ, a2, REG(A2_FLAGS), a2_phrase_mode);
927 srczdata=z_i[colour_index]>>16;
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;
934 // apply data comparator
939 // compare source pixel with pattern pixel
940 if (srcdata == READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode))
945 // compare destination pixel with pattern pixel
946 if (dstdata == READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode))
949 if (a1_phrase_mode||a2_phrase_mode)
953 // compute the write data and store
958 // use pattern data for write data
959 writedata= READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode);
964 // intensity addition
965 writedata = (srcdata & 0xff) + (dstdata & 0xff);
966 if (!(TOPBEN) && writedata > 0xff)
968 writedata |= (srcdata & 0xf00) + (dstdata & 0xf00);
969 if (!(TOPNEN) && writedata > 0xfff)
971 writedata |= (srcdata & 0xf000) + (dstdata & 0xf000);
976 writedata |= ~srcdata & ~dstdata;
978 writedata |= ~srcdata & dstdata;
980 writedata |= srcdata & ~dstdata;
982 writedata |= srcdata & dstdata;
985 writedata = ((gd_c[colour_index])<<8)|(gd_i[colour_index]>>16);
989 int intensity = srcdata & 0xFF;
990 int ia = gd_ia >> 16;
992 ia = 0xFFFFFF00 | ia;
998 writedata = (srcdata & 0xFF00) | intensity;
1007 if (/*a2_phrase_mode || */BKGWREN || !inhibit)
1009 // write to the destination
1010 WRITE_PIXEL(a2, REG(A2_FLAGS), writedata);
1012 WRITE_ZDATA(a2, REG(A2_FLAGS), srczdata);
1018 a2_x = (a2_x + a2_xadd) & a2_mask_x;
1019 a2_y = (a2_y + a2_yadd) & a2_mask_y;
1022 z_i[colour_index]+=zadd;
1024 if ((GOURD)||(SRCSHADE))
1026 gd_i[colour_index] += gd_ia;
1027 gd_c[colour_index] += gd_ca;
1029 if ((GOURD)||(SRCSHADE)||(GOURZ))
1032 colour_index=(colour_index+1)&0x3;
1041 /* if (a2_phrase_mode)
1043 a1_x+=(64/a1_psize)*a1_xadd;
1047 for (int nb=0;nb<(64/a2_psize)+1;nb++)
1048 a2_x = (a2_x + a2_xadd) & a2_mask_x;
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));
1057 //////////////////////////////////////////////////////////////////////////////
1059 //////////////////////////////////////////////////////////////////////////////
1063 //////////////////////////////////////////////////////////////////////////////
1064 void blitter_blit(uint32 cmd)
1071 mode=(cmd>>11)&0x07;
1075 ctrl=(cmd>>25)&0x3f;
1077 a1_addr=REG(A1_BASE);
1078 a2_addr=REG(A2_BASE);
1080 a1_zoffs = (REG(A1_FLAGS) >> 6) & 7;
1081 a2_zoffs = (REG(A2_FLAGS) >> 6) & 7;
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);
1088 n_pixels=(REG(PIXLINECOUNTER)&0xffff);
1089 n_lines=((REG(PIXLINECOUNTER)>>16)&0xffff);
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)];
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);
1102 if (!((REG(A2_FLAGS))&0x8000))
1104 a2_mask_x=0xffffffff; // must be 16.16
1105 a2_mask_y=0xffffffff; // must be 16.16
1110 // determine a1_yadd
1119 // determine a1_xadd
1120 switch (xadd_a1_control)
1123 // add phrase offset to X and truncate
1129 // add pixelsize (1) to X
1133 // add zero (for those nice vertical lines)
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);
1145 // determine a2_yadd
1146 if ((YADD1_A2)||(YADD1_A1))
1156 // determine a2_xadd
1157 switch (xadd_a2_control)
1160 // add phrase offset to X and truncate
1166 // add pixelsize (1) to X
1170 // add zero (for those nice vertical lines)
1174 // add the contents of the increment register
1175 // since there is no register for a2 we just add 1
1182 // modify outer loop steps based on command
1188 if (cmd & 0x00000100)
1190 a1_step_x = (REG(A1_FSTEP)&0xffff);
1191 a1_step_y = (REG(A1_FSTEP)>>16);
1193 if (cmd & 0x00000200)
1195 a1_step_x += ((REG(A1_STEP)&0x0000ffff)<<16);
1196 a1_step_y += ((REG(A1_STEP)&0xffff0000));
1198 if (cmd & 0x00000400)
1200 a2_step_x = (REG(A2_STEP)&0x0000ffff)<<16;
1201 a2_step_y = (REG(A2_STEP)&0xffff0000);
1208 a2_psize=1 << ((REG(A2_FLAGS) >> 3) & 7);
1209 a1_psize=1 << ((REG(A1_FLAGS) >> 3) & 7);
1214 zadd=jaguar_long_read(0xF02274);
1216 for(int v=0;v<4;v++)
1217 z_i[v]=(int32)jaguar_long_read(0xF0228C+(v<<2));
1219 if ((GOURD)||(GOURZ)||(SRCSHADE))
1222 gouraud_add = jaguar_long_read(0xF02270);
1225 gd_c[0] = jaguar_byte_read(0xF02268);
1226 gd_i[0] = jaguar_byte_read(0xF02269);
1228 gd_i[0]|=jaguar_word_read(0xF02240);
1230 gd_c[1] = jaguar_byte_read(0xF0226A);
1231 gd_i[1] = jaguar_byte_read(0xF0226b);
1233 gd_i[1]|=jaguar_word_read(0xF02242);
1235 gd_c[2] = jaguar_byte_read(0xF0226C);
1236 gd_i[2] = jaguar_byte_read(0xF0226d);
1238 gd_i[2]|=jaguar_word_read(0xF02244);
1240 gd_c[3] = jaguar_byte_read(0xF0226E);
1241 gd_i[3] = jaguar_byte_read(0xF0226f);
1243 gd_i[3]|=jaguar_word_read(0xF02246);
1245 gd_ia = gouraud_add & 0xFFFFFF;
1246 if(gd_ia & 0x800000)
1247 gd_ia = 0xFF000000 | gd_ia;
1249 gd_ca = (gouraud_add>>24) & 0xFF;
1251 gd_ca = 0xFFFFFF00 | gd_ca;
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)
1262 a1_step_x=(-n_pixels)*65536;
1265 a2_step_x=(-n_pixels)*65536;;
1268 // fix for wolfenstein 3d
1269 if (jaguar_mainRom_crc32==0x3966698f)
1273 if ((a1_step_x / 65536)==-28)
1275 a1_step_x=-24*65536; // au lieu de -28
1276 a2_step_x= 0*65536; // au lieu de -8
1281 // fix for Tempest 2000
1282 if (jaguar_mainRom_crc32==0x32816d44)
1285 if ((n_lines!=1)&&((n_pixels==288)||(n_pixels==384)))
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);
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);
1315 fprintf(log_get()," count = %d x %d\n", n_pixels, n_lines);
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));
1333 // if (start_logging)
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);
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);
1363 fprintf(log_get()," count = %d x %d\n", n_pixels, n_lines);
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);
1381 #ifndef USE_GENERIC_BLITTER
1382 if (!blitter_execute_cached_code(blitter_in_cache(cmd)))
1384 blitter_generic(cmd);
1388 uint32 blitter_reg_read(uint32 offset)
1390 uint32 data = blitter_ram[offset];
1392 data |= blitter_ram[offset+1];
1394 data |= blitter_ram[offset+2];
1396 data |= blitter_ram[offset+3];
1400 void blitter_reg_write(uint32 offset, uint32 data)
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;
1408 uint32 blitter_long_read(uint32 offset)
1410 return (blitter_word_read(offset) << 16) | blitter_word_read(offset+2);
1413 void blitter_long_write(uint32 offset, uint32 data)
1415 blitter_word_write(offset, data >> 16);
1416 blitter_word_write(offset+2, data & 0xFFFF);
1419 void blitter_init(void)
1421 if (!blitter_cache_init)
1423 for (int i=0;i<256;i++)
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;
1429 blitter_cache_init=1;
1431 #ifndef USE_GENERIC_BLITTER
1432 #include "include/blit_i.h"
1437 blitters_code_fp=fopen("include/blit_c.h","awrt");
1438 blitters_code_init_fp=fopen("include/blit_i.h","awrt");
1442 void blitter_reset(void)
1444 memset(blitter_ram, 0x00, 0xA0);
1447 void blitter_done(void)
1451 fclose(blitters_code_fp);
1452 fclose(blitters_code_init_fp);
1456 void blitter_byte_write(uint32 offset, uint8 data)
1460 if ((offset >= 0x7C) && (offset <= 0x9B))
1465 case 0x7D: blitter_ram[0x69] = data; break;
1466 case 0x7E: blitter_ram[0x40] = data; break;
1467 case 0x7F: blitter_ram[0x41] = data; 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;
1475 case 0x85: blitter_ram[0x6D] = data; break;
1476 case 0x86: blitter_ram[0x44] = data; break;
1477 case 0x87: blitter_ram[0x45] = data; 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;
1487 blitter_ram[offset] = data;
1490 void blitter_word_write(uint32 offset, uint16 data)
1492 blitter_byte_write(offset+0, (data>>8) & 0xFF);
1493 blitter_byte_write(offset+1, data & 0xFF);
1495 if ((offset & 0xFF) == 0x3A)
1497 uint32 cmd = blitter_ram[0x38];
1499 cmd |= blitter_ram[0x39];
1501 cmd |= blitter_ram[0x3A];
1503 cmd |= blitter_ram[0x3B];
1509 uint8 blitter_byte_read(uint32 offset)
1514 if (offset == (0x38+3))
1515 return 0x01; // always idle
1517 return blitter_ram[offset];
1520 uint16 blitter_word_read(uint32 offset)
1522 return (blitter_byte_read(offset) << 8) | blitter_byte_read(offset+1);