3 //#define USE_GENERIC_BLITTER
\r
8 extern int jaguar_active_memory_dumps;
\r
10 #define REG(A) blitter_reg_read(A)
\r
11 #define WREG(A,D) blitter_reg_write(A,D)
\r
13 int start_logging = 0;
\r
15 static uint8 blitter_ram[0x100];
\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
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
60 #define Z_OP_INF (cmd&0x00040000)
\r
61 #define Z_OP_EQU (cmd&0x00080000)
\r
62 #define Z_OP_SUP (cmd&0x00100000)
\r
64 #define CMPDST (cmd&0x02000000)
\r
65 #define BCOMPEN (cmd&0x04000000)
\r
66 #define DCOMPEN (cmd&0x08000000)
\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
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
88 #define XSIGNSUB_A1 (REG(A1_FLAGS)&0x80000)
\r
89 #define XSIGNSUB_A2 (REG(A2_FLAGS)&0x80000)
\r
91 #define YSIGNSUB_A1 (REG(A1_FLAGS)&0x100000)
\r
92 #define YSIGNSUB_A2 (REG(A2_FLAGS)&0x100000)
\r
94 #define YADD1_A1 (REG(A1_FLAGS)&0x40000)
\r
95 #define YADD1_A2 (REG(A2_FLAGS)&0x40000)
\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
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
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
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
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
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
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
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
138 #define READ_ZDATA(a,f) (READ_ZDATA_16(a))
\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
144 #define WRITE_ZDATA(a,f,d) WRITE_ZDATA_16(a,d);
\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
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
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
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
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
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
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
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
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
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
183 // 8 bpp pixel write
\r
184 #define WRITE_PIXEL_8(a,d) { jaguar_byte_write(a##_addr+PIXEL_OFFSET_8(a),d); }
\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
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
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
205 // Width in Pixels of a Scanline
\r
206 static uint32 blitter_scanline_width[48] =
\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
216 static uint8 * tom_ram_8;
\r
217 static uint8 * paletteRam;
\r
221 static uint8 a1ctl;
\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
239 static int32 a1_width;
\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
269 static uint32 z_i[4];
\r
271 static uint8 blitter_code_cache[4096];
\r
272 static uint8 * blitter_ptr;
\r
273 uint8 blitter_working = 0;
\r
275 typedef void (blitter_fn)(void);
\r
277 typedef struct s_blitter_cache
\r
283 struct s_blitter_cache *next;
\r
284 struct s_blitter_cache *prev;
\r
285 } s_blitter_code_cache;
\r
287 s_blitter_cache *blitter_cache[256];
\r
289 uint8 blitter_cache_init=0;
\r
290 static uint8 BPP_LUT[8]={1,2,4,8,16,32,0,0};
\r
292 FILE *blitters_code_fp;
\r
293 FILE *blitters_code_init_fp;
\r
295 //////////////////////////////////////////////////////////////////////////////
\r
296 // build C code for the specified blitter
\r
297 //////////////////////////////////////////////////////////////////////////////
\r
301 //////////////////////////////////////////////////////////////////////////////
\r
302 void blitter_gen_c_code(FILE *fp, uint32 cmd,uint32 hashcode)
\r
304 static uint8 inhibit_modified=0;
\r
306 fprintf(fp,"#ifndef blitter_code_0x%.8x\n",hashcode);
\r
307 fprintf(fp,"#define blitter_code_0x%.8x\n",hashcode);
\r
309 fprintf(fp,"void blitter_0x%.8x(void)\n",hashcode);
\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
332 src_flags=A2_FLAGS;
\r
333 dst_flags=A1_FLAGS;
\r
339 src_flags=A1_FLAGS;
\r
340 dst_flags=A2_FLAGS;
\r
343 // load src data and Z
\r
346 fprintf(fp,"\t\t\tsrcdata = READ_PIXEL_%i(%s);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],src);
\r
348 fprintf(fp,"\t\t\tsrczdata = READ_ZDATA_%i(%s);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],src);
\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
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
360 // load dst data and Z
\r
363 fprintf(fp,"\t\t\tdstdata = READ_PIXEL_%i(%s);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],dst);
\r
365 fprintf(fp,"\t\t\tdstzdata = READ_ZDATA_%i(%s);\n",BPP_LUT[(((REG(dst_flags))>>3)&0x07)],dst);
\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
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
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
378 if ((cmd & 0x00000040)&&(!DSTA2))
\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
386 fprintf(fp,"\t\t\tsrczdata=z_i[colour_index]>>16;\n");
\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
393 // apply data comparator
\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
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
410 // compute the write data and store
\r
411 if (inhibit_modified) fprintf(fp,"\t\t\tif (!inhibit)\n\t\t\t{\n");
\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
420 // intensity addition
\r
421 fprintf(fp,"\t\t\t\twritedata = (srcdata & 0xff) + (dstdata & 0xff);\n");
\r
423 fprintf(fp,"\t\t\t\tif (writedata > 0xff) writedata = 0xff;\n");
\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
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
438 fprintf(fp,"\t\t\t\twritedata = ((gd_c[colour_index])<<8)|(gd_i[colour_index]>>16);\n");
\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
455 if (inhibit_modified)
\r
457 fprintf(fp,"\t\t\t} else { srczdata=dstzdata; writedata=dstdata; }\n");
\r
460 if ((DSTA2?a2_phrase_mode:a1_phrase_mode) || BKGWREN)
\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
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
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
481 fprintf(fp,"\t\t\tz_i[colour_index]+=zadd;\n");
\r
483 if ((GOURD)||(SRCSHADE))
\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
488 if ((GOURD)||(SRCSHADE)||(GOURZ))
\r
490 if (a1_phrase_mode)
\r
491 fprintf(fp,"\t\t\t colour_index=(colour_index+1)&0x3;\n");
\r
493 fprintf(fp,"\t\t}\n");
\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
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
506 fprintf(fp,"#endif\n");
\r
509 //////////////////////////////////////////////////////////////////////////////
\r
510 // Generate a start of function in x86 assembly
\r
511 //////////////////////////////////////////////////////////////////////////////
\r
515 //////////////////////////////////////////////////////////////////////////////
\r
516 void blitter_gen_start_of_function(void)
\r
518 *blitter_ptr++=0x55; // push ebp
\r
519 *blitter_ptr++=0x8b; // mov ebp,esp
\r
520 *blitter_ptr++=0xec;
\r
522 //////////////////////////////////////////////////////////////////////////////
\r
523 // Generate a end of function in x86 assembly
\r
524 //////////////////////////////////////////////////////////////////////////////
\r
528 //////////////////////////////////////////////////////////////////////////////
\r
529 void blitter_gen_end_of_function(void)
\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
536 //////////////////////////////////////////////////////////////////////////////
\r
538 //////////////////////////////////////////////////////////////////////////////
\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
546 uint32 blitter_calc_hashcode(uint32 cmd)
\r
548 uint32 hashcode=0x00000000;
\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
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
582 //////////////////////////////////////////////////////////////////////////////
\r
583 // Build the blitter code for the current blitter operation in the cache
\r
584 //////////////////////////////////////////////////////////////////////////////
\r
588 //////////////////////////////////////////////////////////////////////////////
\r
589 void blitter_build_cached_code(uint32 cmd, uint32 cache_index)
\r
592 //////////////////////////////////////////////////////////////////////////////
\r
593 // Check if the blitter code for the current blitter operation is cached
\r
594 //////////////////////////////////////////////////////////////////////////////
\r
598 //////////////////////////////////////////////////////////////////////////////
\r
599 struct s_blitter_cache * blitter_in_cache(uint32 cmd)
\r
602 uint32 hashcode=blitter_calc_hashcode(cmd);
\r
604 fprintf(log_get(),"blitter: hashcode= 0x%.8x\n",hashcode);
\r
606 struct s_blitter_cache *blitter_list=blitter_cache[hashcode>>24];
\r
609 while (blitter_list->next)
\r
611 blitter_list=blitter_list->next;
\r
613 if (blitter_list->hashcode==hashcode)
\r
614 return(blitter_list);
\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
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
628 //fprintf(log_get(),"warning: using generic blitter for blitter 0x%.8x\n",hashcode);
\r
632 #ifndef USE_GENERIC_BLITTER
\r
633 #include "include/blit_c.h"
\r
635 //////////////////////////////////////////////////////////////////////////////
\r
636 // Execute the cached blitter code for the current blitter operation
\r
637 //////////////////////////////////////////////////////////////////////////////
\r
641 //////////////////////////////////////////////////////////////////////////////
\r
642 uint32 blitter_execute_cached_code(struct s_blitter_cache *blitter)
\r
644 if ((blitter==null)||(blitter->ready==0))
\r
647 blitter_fn *fn=(blitter_fn*)blitter->code;
\r
653 //////////////////////////////////////////////////////////////////////////////
\r
655 //////////////////////////////////////////////////////////////////////////////
\r
659 //////////////////////////////////////////////////////////////////////////////
\r
660 void blitter_add(uint32 hashcode, uint8 *code)
\r
662 struct s_blitter_cache *blitter_list=blitter_cache[(hashcode>>24)];
\r
664 // fprintf(log_get(),"adding blitter for hashcode 0x%.8x\n",hashcode);
\r
666 while (blitter_list->next)
\r
668 blitter_list=blitter_list->next;
\r
670 if (blitter_list->hashcode==hashcode)
\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
678 blitter_list->code=code;
\r
679 blitter_list->hashcode=hashcode;
\r
680 blitter_list->ready=1;
\r
681 blitter_list->used=0;
\r
683 //////////////////////////////////////////////////////////////////////////////
\r
685 //////////////////////////////////////////////////////////////////////////////
\r
689 //////////////////////////////////////////////////////////////////////////////
\r
690 void blitter_list(void)
\r
693 fprintf(log_get(),"Used blitters list:\n");
\r
695 for (int i=0;i<256;i++)
\r
697 struct s_blitter_cache *blitter_list=blitter_cache[i];
\r
699 while (blitter_list->next)
\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
708 //////////////////////////////////////////////////////////////////////////////
\r
710 //////////////////////////////////////////////////////////////////////////////
\r
714 //////////////////////////////////////////////////////////////////////////////
\r
715 void blitter_generic(uint32 cmd)
\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
725 inner_loop=n_pixels;
\r
726 while (inner_loop--)
\r
737 // load src data and Z
\r
740 srcdata = READ_PIXEL(a2, REG(A2_FLAGS));
\r
743 srczdata = READ_ZDATA(a2, REG(A2_FLAGS));
\r
746 if (cmd & 0x001c020)
\r
748 srczdata = READ_RDATA(SRCZINT, a2, REG(A2_FLAGS), a2_phrase_mode);
\r
753 srcdata = READ_RDATA(SRCDATA, a2, REG(A2_FLAGS), a2_phrase_mode);
\r
754 if (cmd & 0x001c020)
\r
756 srczdata = READ_RDATA(SRCZINT, a2, REG(A2_FLAGS), a2_phrase_mode);
\r
760 // load dst data and Z
\r
763 dstdata = READ_PIXEL(a1, REG(A1_FLAGS));
\r
766 dstzdata = READ_ZDATA(a1, REG(A1_FLAGS));
\r
770 dstzdata = READ_RDATA(DSTZ, a1, REG(A1_FLAGS), a1_phrase_mode);
\r
775 dstdata = READ_RDATA(DSTDATA, a1, REG(A1_FLAGS), a1_phrase_mode);
\r
779 dstzdata = READ_RDATA(DSTZ, a1, REG(A1_FLAGS), a1_phrase_mode);
\r
784 if (cmd & 0x00000040)
\r
789 (a1_x >> 16) >= (REG(A1_CLIP) & 0x7fff) ||
\r
790 (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7fff)
\r
796 srczdata=z_i[colour_index]>>16;
\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
803 // apply data comparator
\r
804 if (DCOMPEN|BCOMPEN)
\r
808 // compare source pixel with pattern pixel
\r
809 if (srcdata == READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode))
\r
814 // compare destination pixel with pattern pixel
\r
815 if (dstdata == READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode))
\r
818 if (a1_phrase_mode||a2_phrase_mode)
\r
822 // compute the write data and store
\r
827 // use pattern data for write data
\r
828 writedata= READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode);
\r
833 // intensity addition
\r
834 writedata = (srcdata & 0xff) + (dstdata & 0xff);
\r
835 if (!(TOPBEN) && writedata > 0xff)
\r
837 writedata |= (srcdata & 0xf00) + (dstdata & 0xf00);
\r
838 if (!(TOPNEN) && writedata > 0xfff)
\r
840 writedata |= (srcdata & 0xf000) + (dstdata & 0xf000);
\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
850 writedata = ((gd_c[colour_index])<<8)|(gd_i[colour_index]>>16);
\r
854 int intensity = srcdata & 0xFF;
\r
855 int ia = gd_ia >> 16;
\r
857 ia = 0xFFFFFF00 | ia;
\r
861 if(intensity > 0xFF)
\r
863 writedata = (srcdata & 0xFF00) | intensity;
\r
871 if (/*a1_phrase_mode || */BKGWREN || !inhibit)
\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
880 // load src data and Z
\r
883 srcdata = READ_PIXEL(a1, REG(A1_FLAGS));
\r
886 srczdata = READ_ZDATA(a1, REG(A1_FLAGS));
\r
889 if (cmd & 0x001c020)
\r
891 srczdata = READ_RDATA(SRCZINT, a1, REG(A1_FLAGS), a1_phrase_mode);
\r
896 srcdata = READ_RDATA(SRCDATA, a1, REG(A1_FLAGS), a1_phrase_mode);
\r
897 if (cmd & 0x001c020)
\r
899 srczdata = READ_RDATA(SRCZINT, a1, REG(A1_FLAGS), a1_phrase_mode);
\r
903 // load dst data and Z
\r
906 dstdata = READ_PIXEL(a2, REG(A2_FLAGS));
\r
909 dstzdata = READ_ZDATA(a2, REG(A2_FLAGS));
\r
913 dstzdata = READ_RDATA(DSTZ, a2, REG(A2_FLAGS), a2_phrase_mode);
\r
918 dstdata = READ_RDATA(DSTDATA, a2, REG(A2_FLAGS), a2_phrase_mode);
\r
922 dstzdata = READ_RDATA(DSTZ, a2, REG(A2_FLAGS), a2_phrase_mode);
\r
927 srczdata=z_i[colour_index]>>16;
\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
934 // apply data comparator
\r
935 if (DCOMPEN|BCOMPEN)
\r
939 // compare source pixel with pattern pixel
\r
940 if (srcdata == READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode))
\r
945 // compare destination pixel with pattern pixel
\r
946 if (dstdata == READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode))
\r
949 if (a1_phrase_mode||a2_phrase_mode)
\r
953 // compute the write data and store
\r
958 // use pattern data for write data
\r
959 writedata= READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode);
\r
964 // intensity addition
\r
965 writedata = (srcdata & 0xff) + (dstdata & 0xff);
\r
966 if (!(TOPBEN) && writedata > 0xff)
\r
968 writedata |= (srcdata & 0xf00) + (dstdata & 0xf00);
\r
969 if (!(TOPNEN) && writedata > 0xfff)
\r
971 writedata |= (srcdata & 0xf000) + (dstdata & 0xf000);
\r
976 writedata |= ~srcdata & ~dstdata;
\r
978 writedata |= ~srcdata & dstdata;
\r
980 writedata |= srcdata & ~dstdata;
\r
982 writedata |= srcdata & dstdata;
\r
985 writedata = ((gd_c[colour_index])<<8)|(gd_i[colour_index]>>16);
\r
989 int intensity = srcdata & 0xFF;
\r
990 int ia = gd_ia >> 16;
\r
992 ia = 0xFFFFFF00 | ia;
\r
996 if(intensity > 0xFF)
\r
998 writedata = (srcdata & 0xFF00) | intensity;
\r
1003 writedata=dstdata;
\r
1004 srczdata=dstzdata;
\r
1007 if (/*a2_phrase_mode || */BKGWREN || !inhibit)
\r
1009 // write to the destination
\r
1010 WRITE_PIXEL(a2, REG(A2_FLAGS), writedata);
\r
1012 WRITE_ZDATA(a2, REG(A2_FLAGS), srczdata);
\r
1018 a2_x = (a2_x + a2_xadd) & a2_mask_x;
\r
1019 a2_y = (a2_y + a2_yadd) & a2_mask_y;
\r
1022 z_i[colour_index]+=zadd;
\r
1024 if ((GOURD)||(SRCSHADE))
\r
1026 gd_i[colour_index] += gd_ia;
\r
1027 gd_c[colour_index] += gd_ca;
\r
1029 if ((GOURD)||(SRCSHADE)||(GOURZ))
\r
1031 if(a1_phrase_mode)
\r
1032 colour_index=(colour_index+1)&0x3;
\r
1041 /* if (a2_phrase_mode)
\r
1043 a1_x+=(64/a1_psize)*a1_xadd;
\r
1045 if (a2_phrase_mode)
\r
1047 for (int nb=0;nb<(64/a2_psize)+1;nb++)
\r
1048 a2_x = (a2_x + a2_xadd) & a2_mask_x;
\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
1057 //////////////////////////////////////////////////////////////////////////////
\r
1059 //////////////////////////////////////////////////////////////////////////////
\r
1063 //////////////////////////////////////////////////////////////////////////////
\r
1064 void blitter_blit(uint32 cmd)
\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
1077 a1_addr = REG(A1_BASE);
\r
1078 a2_addr = REG(A2_BASE);
\r
1080 a1_zoffs = (REG(A1_FLAGS) >> 6) & 7;
\r
1081 a2_zoffs = (REG(A2_FLAGS) >> 6) & 7;
\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
1088 n_pixels = REG(PIXLINECOUNTER) & 0xFFFF;
\r
1089 n_lines = (REG(PIXLINECOUNTER) >> 16) & 0xFFFF;
\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
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
1102 if (!(REG(A2_FLAGS) & 0x8000))
\r
1104 a2_mask_x = 0xFFFFFFFF; // must be 16.16
\r
1105 a2_mask_y = 0xFFFFFFFF; // must be 16.16
\r
1108 a1_phrase_mode = 0;
\r
1110 // determine a1_yadd
\r
1112 a1_yadd = 1 << 16;
\r
1117 a1_yadd = -a1_yadd;
\r
1119 // determine a1_xadd
\r
1120 switch (xadd_a1_control)
\r
1123 // add phrase offset to X and truncate
\r
1124 a1_xadd = 1 << 16;
\r
1125 a1_phrase_mode = 1;
\r
1128 // add pixelsize (1) to X
\r
1129 a1_xadd = 1 << 16;
\r
1132 // add zero (for those nice vertical lines)
\r
1136 // add the contents of the increment register
\r
1137 a1_xadd = (REG(A1_INC) << 16) | (REG(A1_FINC) & 0xFFFF);
\r
1138 a1_yadd = (REG(A1_INC) & 0xFFFF0000) | (REG(A1_FINC) >> 16);
\r
1142 a1_xadd = -a1_xadd;
\r
1144 // determine a2_yadd
\r
1145 if (YADD1_A2 || YADD1_A1)
\r
1146 a2_yadd = 1 << 16;
\r
1151 a2_yadd = -a2_yadd;
\r
1153 a2_phrase_mode = 0;
\r
1155 // determine a2_xadd
\r
1156 switch (xadd_a2_control)
\r
1159 // add phrase offset to X and truncate
\r
1160 a2_xadd = 1 << 16;
\r
1161 a2_phrase_mode = 1;
\r
1164 // add pixelsize (1) to X
\r
1165 a2_xadd = 1 << 16;
\r
1168 // add zero (for those nice vertical lines)
\r
1172 // add the contents of the increment register
\r
1173 // since there is no register for a2 we just add 1
\r
1174 a2_xadd = 1 << 16;
\r
1178 a2_xadd = -a2_xadd;
\r
1180 // modify outer loop steps based on command
\r
1186 if (cmd & 0x00000100)
\r
1188 a1_step_x = (REG(A1_FSTEP)&0xffff);
\r
1189 a1_step_y = (REG(A1_FSTEP)>>16);
\r
1191 if (cmd & 0x00000200)
\r
1193 a1_step_x += ((REG(A1_STEP)&0x0000ffff)<<16);
\r
1194 a1_step_y += ((REG(A1_STEP)&0xffff0000));
\r
1196 if (cmd & 0x00000400)
\r
1198 a2_step_x = (REG(A2_STEP)&0x0000ffff)<<16;
\r
1199 a2_step_y = (REG(A2_STEP)&0xffff0000);
\r
1202 outer_loop = n_lines;
\r
1204 a2_psize = 1 << ((REG(A2_FLAGS) >> 3) & 7);
\r
1205 a1_psize = 1 << ((REG(A1_FLAGS) >> 3) & 7);
\r
1210 zadd = jaguar_long_read(0xF02274);
\r
1212 for(int v=0; v<4; v++)
\r
1213 z_i[v] = (int32)jaguar_long_read(0xF0228C + (v << 2));
\r
1215 if (GOURD || GOURZ || SRCSHADE)
\r
1217 // gouraud shading
\r
1218 gouraud_add = jaguar_long_read(0xF02270);
\r
1220 gd_c[0] = jaguar_byte_read(0xF02268);
\r
1221 gd_i[0] = jaguar_byte_read(0xF02269);
\r
1223 gd_i[0] |= jaguar_word_read(0xF02240);
\r
1225 gd_c[1] = jaguar_byte_read(0xF0226A);
\r
1226 gd_i[1] = jaguar_byte_read(0xF0226B);
\r
1228 gd_i[1] |= jaguar_word_read(0xF02242);
\r
1230 gd_c[2] = jaguar_byte_read(0xF0226C);
\r
1231 gd_i[2] = jaguar_byte_read(0xF0226D);
\r
1233 gd_i[2] |= jaguar_word_read(0xF02244);
\r
1235 gd_c[3] = jaguar_byte_read(0xF0226E);
\r
1236 gd_i[3] = jaguar_byte_read(0xF0226F);
\r
1238 gd_i[3] |= jaguar_word_read(0xF02246);
\r
1240 gd_ia = gouraud_add & 0xFFFFFF;
\r
1241 if (gd_ia & 0x800000)
\r
1242 gd_ia = 0xFF000000 | gd_ia;
\r
1244 gd_ca = (gouraud_add>>24) & 0xFF;
\r
1246 gd_ca = 0xFFFFFF00 | gd_ca;
\r
1249 // fix for zoop! and syndicate
\r
1250 if ((jaguar_mainRom_crc32==0x501be17c)||
\r
1251 (jaguar_mainRom_crc32==0x70895c51)||
\r
1252 (jaguar_mainRom_crc32==0x0f1f1497)||
\r
1253 (jaguar_mainRom_crc32==0xfc8f0dcd)
\r
1257 a1_step_x=(-n_pixels)*65536;
\r
1260 a2_step_x=(-n_pixels)*65536;;
\r
1263 // fix for wolfenstein 3d
\r
1264 if (jaguar_mainRom_crc32==0x3966698f)
\r
1268 if ((a1_step_x / 65536)==-28)
\r
1270 a1_step_x=-24*65536; // au lieu de -28
\r
1271 a2_step_x= 0*65536; // au lieu de -8
\r
1276 // fix for Tempest 2000
\r
1277 if (jaguar_mainRom_crc32==0x32816d44)
\r
1280 if ((n_lines!=1)&&((n_pixels==288)||(n_pixels==384)))
\r
1282 fprintf(log_get(),"Blit!\n");
\r
1283 fprintf(log_get()," cmd = 0x%.8x\n",cmd);
\r
1284 fprintf(log_get()," a1_base = %08X\n", a1_addr);
\r
1285 fprintf(log_get()," a1_pitch = %d\n", a1_pitch);
\r
1286 fprintf(log_get()," a1_psize = %d\n", a1_psize);
\r
1287 fprintf(log_get()," a1_width = %d\n", a1_width);
\r
1288 fprintf(log_get()," a1_xadd = %f (phrase=%d)\n", (float)a1_xadd / 65536.0, a1_phrase_mode);
\r
1289 fprintf(log_get()," a1_yadd = %f\n", (float)a1_yadd / 65536.0);
\r
1290 fprintf(log_get()," a1_xstep = %f\n", (float)a1_step_x / 65536.0);
\r
1291 fprintf(log_get()," a1_ystep = %f\n", (float)a1_step_y / 65536.0);
\r
1292 fprintf(log_get()," a1_x = %f\n", (float)a1_x / 65536.0);
\r
1293 fprintf(log_get()," a1_y = %f\n", (float)a1_y / 65536.0);
\r
1294 fprintf(log_get()," a1_zoffs = %i\n",a1_zoffs);
\r
1296 fprintf(log_get()," a2_base = %08X\n", a2_addr);
\r
1297 fprintf(log_get()," a2_pitch = %d\n", a2_pitch);
\r
1298 fprintf(log_get()," a2_psize = %d\n", a2_psize);
\r
1299 fprintf(log_get()," a2_width = %d\n", a2_width);
\r
1300 fprintf(log_get()," a2_xadd = %f (phrase=%d)\n", (float)a2_xadd / 65536.0, a2_phrase_mode);
\r
1301 fprintf(log_get()," a2_yadd = %f\n", (float)a2_yadd / 65536.0);
\r
1302 fprintf(log_get()," a2_xstep = %f\n", (float)a2_step_x / 65536.0);
\r
1303 fprintf(log_get()," a2_ystep = %f\n", (float)a2_step_y / 65536.0);
\r
1304 fprintf(log_get()," a2_x = %f\n", (float)a2_x / 65536.0);
\r
1305 fprintf(log_get()," a2_y = %f\n", (float)a2_y / 65536.0);
\r
1306 fprintf(log_get()," a2_mask_x= 0x%.4x\n",a2_mask_x);
\r
1307 fprintf(log_get()," a2_mask_y= 0x%.4x\n",a2_mask_y);
\r
1308 fprintf(log_get()," a2_zoffs = %i\n",a2_zoffs);
\r
1310 fprintf(log_get()," count = %d x %d\n", n_pixels, n_lines);
\r
1312 fprintf(log_get()," command = %08X\n", cmd);
\r
1313 fprintf(log_get()," dsten = %i\n",DSTEN);
\r
1314 fprintf(log_get()," srcen = %i\n",SRCEN);
\r
1315 fprintf(log_get()," patdsel = %i\n",PATDSEL);
\r
1316 fprintf(log_get()," color = 0x%.8x\n",REG(PATTERNDATA));
\r
1317 fprintf(log_get()," dcompen = %i\n",DCOMPEN);
\r
1318 fprintf(log_get()," bcompen = %i\n",BCOMPEN);
\r
1319 fprintf(log_get()," cmpdst = %i\n",CMPDST);
\r
1320 fprintf(log_get()," GOURZ = %i\n",GOURZ);
\r
1321 fprintf(log_get()," GOURD = %i\n",GOURD);
\r
1322 fprintf(log_get()," SRCSHADE = %i\n",SRCSHADE);
\r
1323 fprintf(log_get()," DSTDATA = 0x%.8x%.8x\n",REG(DSTDATA),REG(DSTDATA+4));
\r
1328 // if (start_logging)
\r
1330 fprintf(log_get(),"Blit!\n");
\r
1331 fprintf(log_get()," cmd = 0x%.8x\n",cmd);
\r
1332 fprintf(log_get()," a1_base = %08X\n", a1_addr);
\r
1333 fprintf(log_get()," a1_pitch = %d\n", a1_pitch);
\r
1334 fprintf(log_get()," a1_psize = %d\n", a1_psize);
\r
1335 fprintf(log_get()," a1_width = %d\n", a1_width);
\r
1336 fprintf(log_get()," a1_xadd = %f (phrase=%d)\n", (float)a1_xadd / 65536.0, a1_phrase_mode);
\r
1337 fprintf(log_get()," a1_yadd = %f\n", (float)a1_yadd / 65536.0);
\r
1338 fprintf(log_get()," a1_xstep = %f\n", (float)a1_step_x / 65536.0);
\r
1339 fprintf(log_get()," a1_ystep = %f\n", (float)a1_step_y / 65536.0);
\r
1340 fprintf(log_get()," a1_x = %f\n", (float)a1_x / 65536.0);
\r
1341 fprintf(log_get()," a1_y = %f\n", (float)a1_y / 65536.0);
\r
1342 fprintf(log_get()," a1_zoffs = %i\n",a1_zoffs);
\r
1344 fprintf(log_get()," a2_base = %08X\n", a2_addr);
\r
1345 fprintf(log_get()," a2_pitch = %d\n", a2_pitch);
\r
1346 fprintf(log_get()," a2_psize = %d\n", a2_psize);
\r
1347 fprintf(log_get()," a2_width = %d\n", a2_width);
\r
1348 fprintf(log_get()," a2_xadd = %f (phrase=%d)\n", (float)a2_xadd / 65536.0, a2_phrase_mode);
\r
1349 fprintf(log_get()," a2_yadd = %f\n", (float)a2_yadd / 65536.0);
\r
1350 fprintf(log_get()," a2_xstep = %f\n", (float)a2_step_x / 65536.0);
\r
1351 fprintf(log_get()," a2_ystep = %f\n", (float)a2_step_y / 65536.0);
\r
1352 fprintf(log_get()," a2_x = %f\n", (float)a2_x / 65536.0);
\r
1353 fprintf(log_get()," a2_y = %f\n", (float)a2_y / 65536.0);
\r
1354 fprintf(log_get()," a2_mask_x= 0x%.4x\n",a2_mask_x);
\r
1355 fprintf(log_get()," a2_mask_y= 0x%.4x\n",a2_mask_y);
\r
1356 fprintf(log_get()," a2_zoffs = %i\n",a2_zoffs);
\r
1358 fprintf(log_get()," count = %d x %d\n", n_pixels, n_lines);
\r
1360 fprintf(log_get()," command = %08X\n", cmd);
\r
1361 fprintf(log_get()," dsten = %i\n",DSTEN);
\r
1362 fprintf(log_get()," srcen = %i\n",SRCEN);
\r
1363 fprintf(log_get()," patdsel = %i\n",PATDSEL);
\r
1364 fprintf(log_get()," color = 0x%.8x\n",REG(PATTERNDATA));
\r
1365 fprintf(log_get()," dcompen = %i\n",DCOMPEN);
\r
1366 fprintf(log_get()," bcompen = %i\n",BCOMPEN);
\r
1367 fprintf(log_get()," cmpdst = %i\n",CMPDST);
\r
1368 fprintf(log_get()," GOURZ = %i\n",GOURZ);
\r
1369 fprintf(log_get()," GOURD = %i\n",GOURD);
\r
1370 fprintf(log_get()," SRCSHADE= %i\n",SRCSHADE);
\r
1374 blitter_working = 1;
\r
1375 #ifndef USE_GENERIC_BLITTER
\r
1376 if (!blitter_execute_cached_code(blitter_in_cache(cmd)))
\r
1378 blitter_generic(cmd);
\r
1379 blitter_working = 0;
\r
1382 uint32 blitter_reg_read(uint32 offset)
\r
1384 uint32 data = blitter_ram[offset];
\r
1386 data |= blitter_ram[offset+1];
\r
1388 data |= blitter_ram[offset+2];
\r
1390 data |= blitter_ram[offset+3];
\r
1394 void blitter_reg_write(uint32 offset, uint32 data)
\r
1396 blitter_ram[offset+0] = (data>>24) & 0xFF;
\r
1397 blitter_ram[offset+1] = (data>>16) & 0xFF;
\r
1398 blitter_ram[offset+2] = (data>>8) & 0xFF;
\r
1399 blitter_ram[offset+3] = data & 0xFF;
\r
1402 uint32 blitter_long_read(uint32 offset)
\r
1404 return (blitter_word_read(offset) << 16) | blitter_word_read(offset+2);
\r
1407 void blitter_long_write(uint32 offset, uint32 data)
\r
1409 blitter_word_write(offset, data >> 16);
\r
1410 blitter_word_write(offset+2, data & 0xFFFF);
\r
1413 void blitter_init(void)
\r
1415 if (!blitter_cache_init)
\r
1417 for (int i=0;i<256;i++)
\r
1419 blitter_cache[i] = (struct s_blitter_cache *)malloc(sizeof(struct s_blitter_cache));
\r
1420 blitter_cache[i]->next=null;
\r
1421 blitter_cache[i]->prev=null;
\r
1423 blitter_cache_init = 1;
\r
1425 #ifndef USE_GENERIC_BLITTER
\r
1426 #include "include/blit_i.h"
\r
1431 blitters_code_fp = fopen("include/blit_c.h","awrt");
\r
1432 blitters_code_init_fp = fopen("include/blit_i.h","awrt");
\r
1436 void blitter_reset(void)
\r
1438 memset(blitter_ram, 0x00, 0xA0);
\r
1441 void blitter_done(void)
\r
1443 // blitter_list();
\r
1445 fclose(blitters_code_fp);
\r
1446 fclose(blitters_code_init_fp);
\r
1448 fprintf(log_get(), "BLIT: Done.\n");
\r
1451 void blitter_byte_write(uint32 offset, uint8 data)
\r
1455 if ((offset >= 0x7C) && (offset <= 0x9B))
\r
1460 case 0x7D: blitter_ram[0x69] = data; break;
\r
1461 case 0x7E: blitter_ram[0x40] = data; break;
\r
1462 case 0x7F: blitter_ram[0x41] = data; break;
\r
1465 case 0x81: blitter_ram[0x6B] = data; break;
\r
1466 case 0x82: blitter_ram[0x42] = data; break;
\r
1467 case 0x83: blitter_ram[0x43] = data; break;
\r
1470 case 0x85: blitter_ram[0x6D] = data; break;
\r
1471 case 0x86: blitter_ram[0x44] = data; break;
\r
1472 case 0x87: blitter_ram[0x45] = data; break;
\r
1475 case 0x89: blitter_ram[0x6F] = data; break;
\r
1476 case 0x9A: blitter_ram[0x46] = data; break;
\r
1477 case 0x9B: blitter_ram[0x47] = data; break;
\r
1481 blitter_ram[offset] = data;
\r
1484 void blitter_word_write(uint32 offset, uint16 data)
\r
1486 blitter_byte_write(offset+0, (data>>8) & 0xFF);
\r
1487 blitter_byte_write(offset+1, data & 0xFF);
\r
1489 if ((offset & 0xFF) == 0x3A)
\r
1491 uint32 cmd = blitter_ram[0x38];
\r
1493 cmd |= blitter_ram[0x39];
\r
1495 cmd |= blitter_ram[0x3A];
\r
1497 cmd |= blitter_ram[0x3B];
\r
1499 blitter_blit(cmd);
\r
1503 uint8 blitter_byte_read(uint32 offset)
\r
1507 // status register
\r
1508 if (offset == (0x38+3))
\r
1509 return 0x01; // always idle
\r
1511 return blitter_ram[offset];
\r
1514 uint16 blitter_word_read(uint32 offset)
\r
1516 return (blitter_byte_read(offset) << 8) | blitter_byte_read(offset+1);
\r