5 // GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Caz (BeOS)
6 // Cleanups/fixes by James L. Hammons
8 bool specialLog = false;
11 #include "blitter2.h" // Testing purposes only!
13 #define REG(A) (((uint32)blitter_ram[(A)] << 24) | ((uint32)blitter_ram[(A)+1] << 16) \
14 | ((uint32)blitter_ram[(A)+2] << 8) | (uint32)blitter_ram[(A)+3])
15 #define WREG(A,D) (blitter_ram[(A)] = ((D)>>24)&0xFF, blitter_ram[(A)+1] = ((D)>>16)&0xFF, \
16 blitter_ram[(A)+2] = ((D)>>8)&0xFF, blitter_ram[(A)+3] = (D)&0xFF)
18 // Blitter registers (offsets from F02200)
20 #define A1_BASE ((UINT32)0x00)
21 #define A1_FLAGS ((UINT32)0x04)
22 #define A1_CLIP ((UINT32)0x08) // Height and width values for clipping
23 #define A1_PIXEL ((UINT32)0x0C) // Integer part of the pixel (Y.i and X.i)
24 #define A1_STEP ((UINT32)0x10) // Integer part of the step
25 #define A1_FSTEP ((UINT32)0x14) // Fractionnal part of the step
26 #define A1_FPIXEL ((UINT32)0x18) // Fractionnal part of the pixel (Y.f and X.f)
27 #define A1_INC ((UINT32)0x1C) // Integer part of the increment
28 #define A1_FINC ((UINT32)0x20) // Fractional part of the increment
29 #define A2_BASE ((UINT32)0x24)
30 #define A2_FLAGS ((UINT32)0x28)
31 #define A2_MASK ((UINT32)0x2C) // Modulo values for x and y (M.y and M.x)
32 #define A2_PIXEL ((UINT32)0x30) // Integer part of the pixel (no fractional part for A2)
33 #define A2_STEP ((UINT32)0x34) // Integer part of the step (no fractional part for A2)
34 #define COMMAND ((UINT32)0x38)
35 #define PIXLINECOUNTER ((UINT32)0x3C)
36 #define SRCDATA ((UINT32)0x40)
37 #define DSTDATA ((UINT32)0x48)
38 #define DSTZ ((UINT32)0x50)
39 #define SRCZINT ((UINT32)0x58)
40 #define SRCZFRAC ((UINT32)0x60)
41 #define PATTERNDATA ((UINT32)0x68)
42 #define INTENSITYINC ((UINT32)0x70)
43 #define ZINC ((UINT32)0x74)
44 #define COLLISIONCTRL ((UINT32)0x78)
45 #define PHRASEINT3 ((UINT32)0x7C)
46 #define PHRASEINT2 ((UINT32)0x80)
47 #define PHRASEINT1 ((UINT32)0x84)
48 #define PHRASEINT0 ((UINT32)0x88)
49 #define PHRASEZ3 ((UINT32)0x8C)
50 #define PHRASEZ2 ((UINT32)0x90)
51 #define PHRASEZ1 ((UINT32)0x94)
52 #define PHRASEZ0 ((UINT32)0x98)
54 // Blitter command bits
56 #define SRCEN (cmd & 0x00000001)
57 #define SRCENZ (cmd & 0x00000002)
58 #define SRCENX (cmd & 0x00000004)
59 #define DSTEN (cmd & 0x00000008)
60 #define DSTENZ (cmd & 0x00000010)
61 #define DSTWRZ (cmd & 0x00000020)
62 #define CLIPA1 (cmd & 0x00000040)
64 #define UPDA1F (cmd & 0x00000100)
65 #define UPDA1 (cmd & 0x00000200)
66 #define UPDA2 (cmd & 0x00000400)
68 #define DSTA2 (cmd & 0x00000800)
70 #define Z_OP_INF (cmd & 0x00040000)
71 #define Z_OP_EQU (cmd & 0x00080000)
72 #define Z_OP_SUP (cmd & 0x00100000)
74 #define LFU_NAN (cmd & 0x00200000)
75 #define LFU_NA (cmd & 0x00400000)
76 #define LFU_AN (cmd & 0x00800000)
77 #define LFU_A (cmd & 0x01000000)
79 #define CMPDST (cmd & 0x02000000)
80 #define BCOMPEN (cmd & 0x04000000)
81 #define DCOMPEN (cmd & 0x08000000)
83 #define PATDSEL (cmd & 0x00010000)
84 #define INTADD (cmd & 0x00020000)
85 #define TOPBEN (cmd & 0x00004000)
86 #define TOPNEN (cmd & 0x00008000)
87 #define BKGWREN (cmd & 0x10000000)
88 #define GOURD (cmd & 0x00001000)
89 #define GOURZ (cmd & 0x00002000)
90 #define SRCSHADE (cmd & 0x40000000)
98 #define XSIGNSUB_A1 (REG(A1_FLAGS)&0x080000)
99 #define XSIGNSUB_A2 (REG(A2_FLAGS)&0x080000)
101 #define YSIGNSUB_A1 (REG(A1_FLAGS)&0x100000)
102 #define YSIGNSUB_A2 (REG(A2_FLAGS)&0x100000)
104 #define YADD1_A1 (REG(A1_FLAGS)&0x040000)
105 #define YADD1_A2 (REG(A2_FLAGS)&0x040000)
108 #define PIXEL_SHIFT_1(a) (((~a##_x) >> 16) & 7)
109 #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))
110 #define READ_PIXEL_1(a) ((jaguar_byte_read(a##_addr+PIXEL_OFFSET_1(a)) >> PIXEL_SHIFT_1(a)) & 0x01)
113 #define PIXEL_SHIFT_2(a) (((~a##_x) >> 15) & 6)
114 #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))
115 #define READ_PIXEL_2(a) ((jaguar_byte_read(a##_addr+PIXEL_OFFSET_2(a)) >> PIXEL_SHIFT_2(a)) & 0x03)
118 #define PIXEL_SHIFT_4(a) (((~a##_x) >> 14) & 4)
119 #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))
120 #define READ_PIXEL_4(a) ((jaguar_byte_read(a##_addr+PIXEL_OFFSET_4(a)) >> PIXEL_SHIFT_4(a)) & 0x0f)
123 #define PIXEL_OFFSET_8(a) (((((UINT32)a##_y >> 16) * a##_width) + (((UINT32)a##_x >> 16) & ~7)) * (1 + a##_pitch) + (((UINT32)a##_x >> 16) & 7))
124 #define READ_PIXEL_8(a) (jaguar_byte_read(a##_addr+PIXEL_OFFSET_8(a)))
127 #define PIXEL_OFFSET_16(a) (((((UINT32)a##_y >> 16) * a##_width) + (((UINT32)a##_x >> 16) & ~3)) * (1 + a##_pitch) + (((UINT32)a##_x >> 16) & 3))
128 #define READ_PIXEL_16(a) (jaguar_word_read(a##_addr+(PIXEL_OFFSET_16(a)<<1)))
131 #define PIXEL_OFFSET_32(a) (((((UINT32)a##_y >> 16) * a##_width) + (((UINT32)a##_x >> 16) & ~1)) * (1 + a##_pitch) + (((UINT32)a##_x >> 16) & 1))
132 #define READ_PIXEL_32(a) (jaguar_long_read(a##_addr+(PIXEL_OFFSET_32(a)<<2)))
135 #define READ_PIXEL(a,f) (\
136 (((f>>3)&0x07) == 0) ? (READ_PIXEL_1(a)) : \
137 (((f>>3)&0x07) == 1) ? (READ_PIXEL_2(a)) : \
138 (((f>>3)&0x07) == 2) ? (READ_PIXEL_4(a)) : \
139 (((f>>3)&0x07) == 3) ? (READ_PIXEL_8(a)) : \
140 (((f>>3)&0x07) == 4) ? (READ_PIXEL_16(a)) : \
141 (((f>>3)&0x07) == 5) ? (READ_PIXEL_32(a)) : 0)
143 // 16 bpp z data read
144 #define ZDATA_OFFSET_16(a) (PIXEL_OFFSET_16(a) + a##_zoffs * 4)
145 #define READ_ZDATA_16(a) (jaguar_word_read(a##_addr+(ZDATA_OFFSET_16(a)<<1)))
148 #define READ_ZDATA(a,f) (READ_ZDATA_16(a))
150 // 16 bpp z data write
151 #define WRITE_ZDATA_16(a,d) { jaguar_word_write(a##_addr+(ZDATA_OFFSET_16(a)<<1),d); }
152 //#define WRITE_ZDATA_16(a,d) { jaguar_word_write(a##_addr+(ZDATA_OFFSET_16(a)<<1),d); WriteLog("16bpp z write --> "); }
155 #define WRITE_ZDATA(a,f,d) WRITE_ZDATA_16(a,d);
158 #define READ_RDATA_1(r,a,p) ((p) ? ((REG(r+(((UINT32)a##_x>>19)&4)))>>(((UINT32)a##_x>>16)&0x1f))& 0x1 : (REG(r) & 0x1))
161 #define READ_RDATA_2(r,a,p) ((p) ? ((REG(r+(((UINT32)a##_x>>18)&4)))>>(((UINT32)a##_x>>15)&0x3e))& 0x3 : (REG(r) & 0x3))
164 #define READ_RDATA_4(r,a,p) ((p) ? ((REG(r+(((UINT32)a##_x>>17)&4)))>>(((UINT32)a##_x>>14)&0x28))& 0xf : (REG(r) & 0xf))
167 #define READ_RDATA_8(r,a,p) ((p) ? ((REG(r+(((UINT32)a##_x>>16)&4)))>>(((UINT32)a##_x>>13)&0x18))& 0xff : (REG(r) & 0xff))
169 // 16 bpp r data read
170 #define READ_RDATA_16(r,a,p) ((p) ? ((REG(r+(((UINT32)a##_x>>15)&4)))>>(((UINT32)a##_x>>12)&0x10))&0xffff : (REG(r) & 0xffff))
172 // 32 bpp r data read
173 #define READ_RDATA_32(r,a,p) ((p) ? REG(r+(((UINT32)a##_x>>14)&4)) : REG(r))
175 // register data read
176 #define READ_RDATA(r,a,f,p) (\
177 (((f>>3)&0x07) == 0) ? (READ_RDATA_1(r,a,p)) : \
178 (((f>>3)&0x07) == 1) ? (READ_RDATA_2(r,a,p)) : \
179 (((f>>3)&0x07) == 2) ? (READ_RDATA_4(r,a,p)) : \
180 (((f>>3)&0x07) == 3) ? (READ_RDATA_8(r,a,p)) : \
181 (((f>>3)&0x07) == 4) ? (READ_RDATA_16(r,a,p)) : \
182 (((f>>3)&0x07) == 5) ? (READ_RDATA_32(r,a,p)) : 0)
185 #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))); }
188 #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))); }
191 #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))); }
194 #define WRITE_PIXEL_8(a,d) { jaguar_byte_write(a##_addr+PIXEL_OFFSET_8(a),d); }
196 // 16 bpp pixel write
197 //#define WRITE_PIXEL_16(a,d) { jaguar_word_write(a##_addr+(PIXEL_OFFSET_16(a)<<1),d); }
198 #define WRITE_PIXEL_16(a,d) { jaguar_word_write(a##_addr+(PIXEL_OFFSET_16(a)<<1),d); if (specialLog) WriteLog("Pixel write address: %08X\n", a##_addr+(PIXEL_OFFSET_16(a)<<1)); }
200 // 32 bpp pixel write
201 #define WRITE_PIXEL_32(a,d) { jaguar_long_write(a##_addr+(PIXEL_OFFSET_32(a)<<2),d); }
202 //#define WRITE_PIXEL_32(a,d) { jaguar_long_write(a##_addr+(PIXEL_OFFSET_32(a)<<2),d); WriteLog("32bpp pixel write --> "); }
205 #define WRITE_PIXEL(a,f,d) {\
206 switch ((f>>3)&0x07) { \
207 case 0: WRITE_PIXEL_1(a,d); break; \
208 case 1: WRITE_PIXEL_2(a,d); break; \
209 case 2: WRITE_PIXEL_4(a,d); break; \
210 case 3: WRITE_PIXEL_8(a,d); break; \
211 case 4: WRITE_PIXEL_16(a,d); break; \
212 case 5: WRITE_PIXEL_32(a,d); break; \
215 // External global variables
217 extern int jaguar_active_memory_dumps;
219 // Local global variables
221 int start_logging = 0;
222 uint8 blitter_working = 0;
224 // Blitter register RAM (most of it is hidden from the user)
226 static uint8 blitter_ram[0x100];
228 // Width in Pixels of a Scanline
229 // This is a pretranslation of the value found in the A1 & A2 flags: It's really a floating point value
230 // of the form EEEEMM where MM is the mantissa with an implied "1." in front of it and the EEEE value is
231 // the exponent. Valid values for the exponent range from 0 to 11 (decimal). It's easiest to think of it
232 // as a floating point bit pattern being followed by a number of zeroes. So, e.g., 001101 translates to
233 // 1.01 (the "1." being implied) x (2 ^ 3) or 1010 -> 10 in base 10 (i.e., 1.01 with the decimal place
234 // being shifted to the right 3 places).
235 static uint32 blitter_scanline_width[48] =
237 0, 0, 0, 0, // Note: This would really translate to 1, 1, 1, 1
247 1024, 1280, 1536, 1792,
248 2048, 2560, 3072, 3584
251 //static uint8 * tom_ram_8;
252 //static uint8 * paletteRam;
262 static uint32 a1_addr;
263 static uint32 a2_addr;
264 static int32 a1_zoffs;
265 static int32 a2_zoffs;
266 static uint32 xadd_a1_control;
267 static uint32 xadd_a2_control;
268 static int32 a1_pitch;
269 static int32 a2_pitch;
270 static uint32 n_pixels;
271 static uint32 n_lines;
274 static int32 a1_width;
277 static int32 a2_width;
278 static int32 a2_mask_x;
279 static int32 a2_mask_y;
280 static int32 a1_xadd;
281 static int32 a1_yadd;
282 static int32 a2_xadd;
283 static int32 a2_yadd;
284 static uint8 a1_phrase_mode;
285 static uint8 a2_phrase_mode;
286 static int32 a1_step_x = 0;
287 static int32 a1_step_y = 0;
288 static int32 a2_step_x = 0;
289 static int32 a2_step_y = 0;
290 static uint32 outer_loop;
291 static uint32 inner_loop;
292 static uint32 a2_psize;
293 static uint32 a1_psize;
294 static uint32 gouraud_add;
295 //static uint32 gouraud_data;
296 //static uint16 gint[4];
297 //static uint16 gfrac[4];
298 //static uint8 gcolour[4];
301 static int gd_ia, gd_ca;
302 static int colour_index = 0;
304 static uint32 z_i[4];
306 static int32 a1_clip_x, a1_clip_y;
308 // In the spirit of "get it right first, *then* optimize" I've taken the liberty
309 // of removing all the unnecessary code caching. If it turns out to be a good way
310 // to optimize the blitter, then we may revisit it in the future...
313 // Generic blit handler
315 void blitter_generic(uint32 cmd)
318 //uint32 logGo = ((cmd == 0x01800E01 && REG(A1_BASE) == 0x898000) ? 1 : 0);
319 uint32 srcdata, srczdata, dstdata, dstzdata, writedata, inhibit;
323 WriteLog("About to do 8x8 blit (BM width is 448 pixels)...\n");
329 WriteLog(" A1_X/Y = %08X/%08X, A2_X/Y = %08X/%08X\n", a1_x, a1_y, a2_x, a2_y);
331 inner_loop = n_pixels;
336 WriteLog(" A1_X/Y = %08X/%08X, A2_X/Y = %08X/%08X\n", a1_x, a1_y, a2_x, a2_y);
338 srcdata = srczdata = dstdata = dstzdata = writedata = inhibit = 0;
342 // load src data and Z
345 srcdata = READ_PIXEL(a2, REG(A2_FLAGS));
347 srczdata = READ_ZDATA(a2, REG(A2_FLAGS));
348 else if (cmd & 0x0001C020)
349 srczdata = READ_RDATA(SRCZINT, a2, REG(A2_FLAGS), a2_phrase_mode);
353 srcdata = READ_RDATA(SRCDATA, a2, REG(A2_FLAGS), a2_phrase_mode);
354 if (cmd & 0x0001C020)
355 srczdata = READ_RDATA(SRCZINT, a2, REG(A2_FLAGS), a2_phrase_mode);
358 // load dst data and Z
361 dstdata = READ_PIXEL(a1, REG(A1_FLAGS));
363 dstzdata = READ_ZDATA(a1, REG(A1_FLAGS));
365 dstzdata = READ_RDATA(DSTZ, a1, REG(A1_FLAGS), a1_phrase_mode);
369 dstdata = READ_RDATA(DSTDATA, a1, REG(A1_FLAGS), a1_phrase_mode);
371 dstzdata = READ_RDATA(DSTZ, a1, REG(A1_FLAGS), a1_phrase_mode);
374 /*This wasn't working... // a1 clipping
375 if (cmd & 0x00000040)
377 if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7FFF)
378 || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7FFF))
383 srczdata = z_i[colour_index] >> 16;
385 // apply z comparator
386 if (Z_OP_INF) if (srczdata < dstzdata) inhibit = 1;
387 if (Z_OP_EQU) if (srczdata == dstzdata) inhibit = 1;
388 if (Z_OP_SUP) if (srczdata > dstzdata) inhibit = 1;
390 // apply data comparator
391 // Note: DCOMPEN only works in 8/16 bpp modes! !!! FIX !!!
392 // Does BCOMPEN only work in 1 bpp mode???
393 if (DCOMPEN | BCOMPEN)
397 //WriteLog("Blitter: BCOMPEN set on command %08X inhibit prev:%u, now:", cmd, inhibit);
398 // compare source pixel with pattern pixel
400 Blit! (000B8250 <- 0012C3A0) count: 16 x 1, A1/2_FLAGS: 00014420/00012000 [cmd: 05810001]
401 CMD -> src: SRCEN dst: misc: a1ctl: mode: ity: PATDSEL z-op: op: LFU_REPLACE ctrl: BCOMPEN
402 A1 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 384 (22), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
403 A2 -> pitch: 1 phrases, depth: 1bpp, z-off: 0, width: 16 (10), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
407 // AvP is still wrong, could be cuz it's doing A1 -> A2...
409 // Src is the 1bpp bitmap... DST is the PATTERN!!!
410 // This seems to solve at least ONE of the problems with MC3D...
411 // Why should this be inverted???
412 // Bcuz it is. This is supposed to be used only for a bit -> pixel expansion...
413 /* if (srcdata == READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode))
414 // if (srcdata != READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode))
416 /* uint32 A2bpp = 1 << ((REG(A2_FLAGS) >> 3) & 0x07);
417 if (A2bpp == 1 || A2bpp == 16 || A2bpp == 8)
418 inhibit = (srcdata == 0 ? 1: 0);
419 // inhibit = !srcdata;
421 WriteLog("Blitter: Bad BPP (%u) selected for BCOMPEN mode!\n", A2bpp);//*/
422 // What it boils down to is this:
428 // compare destination pixel with pattern pixel
429 if (dstdata == READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode))
430 // if (dstdata != READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode))
433 // This is DEFINITELY WRONG
434 if (a1_phrase_mode || a2_phrase_mode)
440 inhibit |= (((a1_x >> 16) < a1_clip_x && (a1_x >> 16) >= 0
441 && (a1_y >> 16) < a1_clip_y && (a1_y >> 16) >= 0) ? 0 : 1);
444 // compute the write data and store
449 // use pattern data for write data
450 writedata = READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode);
454 // intensity addition
455 writedata = (srcdata & 0xFF) + (dstdata & 0xFF);
456 if (!(TOPBEN) && writedata > 0xFF)
458 writedata |= (srcdata & 0xF00) + (dstdata & 0xF00);
459 if (!(TOPNEN) && writedata > 0xFFF)
461 writedata |= (srcdata & 0xF000) + (dstdata & 0xF000);
465 if (LFU_NAN) writedata |= ~srcdata & ~dstdata;
466 if (LFU_NA) writedata |= ~srcdata & dstdata;
467 if (LFU_AN) writedata |= srcdata & ~dstdata;
468 if (LFU_A) writedata |= srcdata & dstdata;
472 writedata = ((gd_c[colour_index]) << 8) | (gd_i[colour_index] >> 16);
476 int intensity = srcdata & 0xFF;
477 int ia = gd_ia >> 16;
479 ia = 0xFFFFFF00 | ia;
483 if (intensity > 0xFF)
485 writedata = (srcdata & 0xFF00) | intensity;
494 if (/*a1_phrase_mode || */BKGWREN || !inhibit)
496 /*if (((REG(A1_FLAGS) >> 3) & 0x07) == 5)
498 uint32 offset = a1_addr+(PIXEL_OFFSET_32(a1)<<2);
499 // (((((UINT32)a##_y >> 16) * a##_width) + (((UINT32)a##_x >> 16) & ~1)) * (1 + a##_pitch) + (((UINT32)a##_x >> 16) & 1))
500 if ((offset >= 0x1FF020 && offset <= 0x1FF03F) || (offset >= 0x1FF820 && offset <= 0x1FF83F))
501 WriteLog("32bpp pixel write: A1 Phrase mode --> ");
503 // write to the destination
504 WRITE_PIXEL(a1, REG(A1_FLAGS), writedata);
506 WRITE_ZDATA(a1, REG(A1_FLAGS), srczdata);
511 // load src data and Z
514 srcdata = READ_PIXEL(a1, REG(A1_FLAGS));
516 srczdata = READ_ZDATA(a1, REG(A1_FLAGS));
517 else if (cmd & 0x0001C020)
518 srczdata = READ_RDATA(SRCZINT, a1, REG(A1_FLAGS), a1_phrase_mode);
522 srcdata = READ_RDATA(SRCDATA, a1, REG(A1_FLAGS), a1_phrase_mode);
524 srczdata = READ_RDATA(SRCZINT, a1, REG(A1_FLAGS), a1_phrase_mode);
527 // load dst data and Z
530 dstdata = READ_PIXEL(a2, REG(A2_FLAGS));
532 dstzdata = READ_ZDATA(a2, REG(A2_FLAGS));
534 dstzdata = READ_RDATA(DSTZ, a2, REG(A2_FLAGS), a2_phrase_mode);
538 dstdata = READ_RDATA(DSTDATA, a2, REG(A2_FLAGS), a2_phrase_mode);
540 dstzdata = READ_RDATA(DSTZ, a2, REG(A2_FLAGS), a2_phrase_mode);
544 srczdata = z_i[colour_index] >> 16;
546 // apply z comparator
547 if (Z_OP_INF) if (srczdata < dstzdata) inhibit = 1;
548 if (Z_OP_EQU) if (srczdata == dstzdata) inhibit = 1;
549 if (Z_OP_SUP) if (srczdata > dstzdata) inhibit = 1;
551 // apply data comparator
552 //NOTE: The bit comparator (BCOMPEN) is NOT the same at the data comparator!
553 if (DCOMPEN | BCOMPEN)
557 // compare source pixel with pattern pixel
558 // AvP: Numbers are correct, but sprites are not!
559 //This doesn't seem to be a problem... But could still be wrong...
560 /* if (srcdata == READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode))
561 // if (srcdata != READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode))
563 // This is probably not 100% correct... It works in the 1bpp case
564 // (in A1 <- A2 mode, that is...)
565 // AvP: This is causing blocks to be written instead of bit patterns...
567 // NOTE: We really should separate out the BCOMPEN & DCOMPEN stuff!
568 /* uint32 A1bpp = 1 << ((REG(A1_FLAGS) >> 3) & 0x07);
569 if (A1bpp == 1 || A1bpp == 16 || A1bpp == 8)
570 inhibit = (srcdata == 0 ? 1: 0);
572 WriteLog("Blitter: Bad BPP (%u) selected for BCOMPEN mode!\n", A1bpp);//*/
573 // What it boils down to is this:
579 // compare destination pixel with pattern pixel
580 if (dstdata == READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode))
581 // if (dstdata != READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode))
584 if (a1_phrase_mode || a2_phrase_mode)
590 inhibit |= (((a1_x >> 16) < a1_clip_x && (a1_x >> 16) >= 0
591 && (a1_y >> 16) < a1_clip_y && (a1_y >> 16) >= 0) ? 0 : 1);
594 // compute the write data and store
599 // use pattern data for write data
600 writedata= READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode);
604 // intensity addition
605 writedata = (srcdata & 0xFF) + (dstdata & 0xFF);
606 if (!(TOPBEN) && writedata > 0xFF)
608 writedata |= (srcdata & 0xF00) + (dstdata & 0xF00);
609 if (!(TOPNEN) && writedata > 0xFFF)
611 writedata |= (srcdata & 0xF000) + (dstdata & 0xF000);
616 writedata |= ~srcdata & ~dstdata;
618 writedata |= ~srcdata & dstdata;
620 writedata |= srcdata & ~dstdata;
622 writedata |= srcdata & dstdata;
626 writedata = ((gd_c[colour_index]) << 8) | (gd_i[colour_index] >> 16);
630 int intensity = srcdata & 0xFF;
631 int ia = gd_ia >> 16;
633 ia = 0xFFFFFF00 | ia;
637 if (intensity > 0xFF)
639 writedata = (srcdata & 0xFF00) | intensity;
648 if (/*a2_phrase_mode || */BKGWREN || !inhibit)
652 uint32 offset = a2_addr+(PIXEL_OFFSET_16(a2)<<1);
653 // (((((UINT32)a##_y >> 16) * a##_width) + (((UINT32)a##_x >> 16) & ~1)) * (1 + a##_pitch) + (((UINT32)a##_x >> 16) & 1))
654 WriteLog("[%08X:%04X] ", offset, writedata);
656 // write to the destination
657 WRITE_PIXEL(a2, REG(A2_FLAGS), writedata);
659 WRITE_ZDATA(a2, REG(A2_FLAGS), srczdata);
666 a2_x = (a2_x + a2_xadd) & a2_mask_x;
667 a2_y = (a2_y + a2_yadd) & a2_mask_y;
670 z_i[colour_index] += zadd;
672 if (GOURD || SRCSHADE)
674 gd_i[colour_index] += gd_ia;
675 gd_c[colour_index] += gd_ca;
677 if (GOURD || SRCSHADE || GOURZ)
680 colour_index = (colour_index + 1) & 0x03;
689 /* if (a2_phrase_mode)
691 a1_x+=(64/a1_psize)*a1_xadd;
695 for (int nb=0;nb<(64/a2_psize)+1;nb++)
696 a2_x = (a2_x + a2_xadd) & a2_mask_x;
700 // write values back to registers
701 WREG(A1_PIXEL, (a1_y & 0xFFFF0000) | ((a1_x >> 16) & 0xFFFF));
702 WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xFFFF));
703 WREG(A2_PIXEL, (a2_y & 0xFFFF0000) | ((a2_x >> 16) & 0xFFFF));
707 void blitter_blit(uint32 cmd)
709 uint32 pitchValue[4] = { 0, 1, 3, 2 };
712 dst = (cmd >> 3) & 0x07;
713 misc = (cmd >> 6) & 0x03;
714 a1ctl = (cmd >> 8) & 0x7;
715 mode = (cmd >> 11) & 0x07;
716 ity = (cmd >> 14) & 0x0F;
717 zop = (cmd >> 18) & 0x07;
718 op = (cmd >> 21) & 0x0F;
719 ctrl = (cmd >> 25) & 0x3F;
721 a1_addr = REG(A1_BASE);
722 //Just for testing Trevor McFur...
723 //if (a1_addr == 0x130CB0) specialLog = true;
724 //extern bool suppressOutput;
725 //if (a1_addr == 0x130CB0) suppressOutput = false;
727 a2_addr = REG(A2_BASE);
729 a1_zoffs = (REG(A1_FLAGS) >> 6) & 7;
730 a2_zoffs = (REG(A2_FLAGS) >> 6) & 7;
732 xadd_a1_control = (REG(A1_FLAGS) >> 16) & 0x03;
733 xadd_a2_control = (REG(A2_FLAGS) >> 16) & 0x03;
734 // a1_pitch = (REG(A1_FLAGS) & 3) ^ ((REG(A1_FLAGS) & 2) >> 1);
735 // a2_pitch = (REG(A2_FLAGS) & 3) ^ ((REG(A2_FLAGS) & 2) >> 1);
736 a1_pitch = pitchValue[(REG(A1_FLAGS) & 0x03)];
737 a2_pitch = pitchValue[(REG(A2_FLAGS) & 0x03)];
739 n_pixels = REG(PIXLINECOUNTER) & 0xFFFF;
740 n_lines = (REG(PIXLINECOUNTER) >> 16) & 0xFFFF;
742 a1_x = (REG(A1_PIXEL) << 16) | (REG(A1_FPIXEL) & 0xFFFF);
743 a1_y = (REG(A1_PIXEL) & 0xFFFF0000) | (REG(A1_FPIXEL) >> 16);
744 //According to the JTRM, X is restricted to 15 bits and Y is restricted to 12.
745 //But it seems to fuck up T2K! !!! FIX !!!
746 // a1_x &= 0x7FFFFFFF, a1_y &= 0x0FFFFFFF;
748 // a1_width = blitter_scanline_width[((REG(A1_FLAGS) & 0x00007E00) >> 9)];
749 UINT32 m = (REG(A1_FLAGS) >> 9) & 0x03, e = (REG(A1_FLAGS) >> 11) & 0x0F;
750 a1_width = ((0x04 | m) << e) >> 2;//*/
752 a2_x = (REG(A2_PIXEL) & 0x0000FFFF) << 16;
753 a2_y = (REG(A2_PIXEL) & 0xFFFF0000);
754 //According to the JTRM, X is restricted to 15 bits and Y is restricted to 12.
755 //But it seems to fuck up T2K! !!! FIX !!!
756 // a2_x &= 0x7FFFFFFF, a2_y &= 0x0FFFFFFF;
758 // a2_width = blitter_scanline_width[((REG(A2_FLAGS) & 0x00007E00) >> 9)];
759 m = (REG(A2_FLAGS) >> 9) & 0x03, e = (REG(A2_FLAGS) >> 11) & 0x0F;
760 a2_width = ((0x04 | m) << e) >> 2;//*/
761 a2_mask_x = ((REG(A2_MASK) & 0x0000FFFF) << 16) | 0xFFFF;
762 a2_mask_y = (REG(A2_MASK) & 0xFFFF0000) | 0xFFFF;
764 // Check for "use mask" flag
765 if (!(REG(A2_FLAGS) & 0x8000))
767 a2_mask_x = 0xFFFFFFFF; // must be 16.16
768 a2_mask_y = 0xFFFFFFFF; // must be 16.16
773 // According to the official documentation, a hardware bug ties A2's yadd bit to A1's...
774 a2_yadd = a1_yadd = (YADD1_A1 ? 1 << 16 : 0);
780 switch (xadd_a1_control)
783 // This is a documented Jaguar bug relating to phrase mode and truncation... Look into it!
784 // add phrase offset to X and truncate
789 // add pixelsize (1) to X
793 // add zero (for those nice vertical lines)
797 // add the contents of the increment register
798 a1_xadd = (REG(A1_INC) << 16) | (REG(A1_FINC) & 0xFFFF);
799 a1_yadd = (REG(A1_INC) & 0xFFFF0000) | (REG(A1_FINC) >> 16);
811 switch (xadd_a2_control)
814 // add phrase offset to X and truncate
819 // add pixelsize (1) to X
823 // add zero (for those nice vertical lines)
826 //This really isn't a valid bit combo for A2... Shouldn't this cause the blitter to just say no?
828 WriteLog("BLIT: Asked to used invalid bit combo for A2...\n");
829 // add the contents of the increment register
830 // since there is no register for a2 we just add 1
831 //Let's do nothing, since it's not listed as a valid bit combo...
832 // a2_xadd = 1 << 16;
838 // Modify outer loop steps based on blitter command
846 a1_step_x = (REG(A1_FSTEP) & 0xFFFF),
847 a1_step_y = (REG(A1_FSTEP) >> 16);
850 a1_step_x |= ((REG(A1_STEP) & 0x0000FFFF) << 16),
851 a1_step_y |= ((REG(A1_STEP) & 0xFFFF0000));
854 a2_step_x = (REG(A2_STEP) & 0x0000FFFF) << 16,
855 a2_step_y = (REG(A2_STEP) & 0xFFFF0000);
857 outer_loop = n_lines;
862 a1_clip_x = REG(A1_CLIP) & 0x7FFF,
863 a1_clip_y = (REG(A1_CLIP) >> 16) & 0x7FFF;
865 // This phrase sizing is incorrect as well... !!! FIX !!!
866 // Err, this is pixel size... (and it's OK)
867 a2_psize = 1 << ((REG(A2_FLAGS) >> 3) & 0x07);
868 a1_psize = 1 << ((REG(A1_FLAGS) >> 3) & 0x07);
873 zadd = jaguar_long_read(0xF02274);
875 for(int v=0; v<4; v++)
876 z_i[v] = (int32)jaguar_long_read(0xF0228C + (v << 2));
878 if (GOURD || GOURZ || SRCSHADE)
881 gouraud_add = jaguar_long_read(0xF02270);
883 gd_c[0] = jaguar_byte_read(0xF02268);
884 gd_i[0] = jaguar_byte_read(0xF02269);
886 gd_i[0] |= jaguar_word_read(0xF02240);
888 gd_c[1] = jaguar_byte_read(0xF0226A);
889 gd_i[1] = jaguar_byte_read(0xF0226B);
891 gd_i[1] |= jaguar_word_read(0xF02242);
893 gd_c[2] = jaguar_byte_read(0xF0226C);
894 gd_i[2] = jaguar_byte_read(0xF0226D);
896 gd_i[2] |= jaguar_word_read(0xF02244);
898 gd_c[3] = jaguar_byte_read(0xF0226E);
899 gd_i[3] = jaguar_byte_read(0xF0226F);
901 gd_i[3] |= jaguar_word_read(0xF02246);
903 gd_ia = gouraud_add & 0xFFFFFF;
904 if (gd_ia & 0x800000)
905 gd_ia = 0xFF000000 | gd_ia;
907 gd_ca = (gouraud_add>>24) & 0xFF;
909 gd_ca = 0xFFFFFF00 | gd_ca;
912 // fix for zoop! and syndicate
913 /* if ((jaguar_mainRom_crc32==0x501be17c)||
914 (jaguar_mainRom_crc32==0x70895c51)||
915 (jaguar_mainRom_crc32==0x0f1f1497)||
916 (jaguar_mainRom_crc32==0xfc8f0dcd)
920 a1_step_x = (-n_pixels) * 65536;
923 a2_step_x = (-n_pixels) * 65536;;
926 // fix for wolfenstein 3d
927 if (jaguar_mainRom_crc32==0x3966698f)
931 if ((a1_step_x / 65536)==-28)
933 a1_step_x=-24*65536; // au lieu de -28
934 a2_step_x= 0*65536; // au lieu de -8
939 // fix for Tempest 2000
940 if (jaguar_mainRom_crc32==0x32816d44)
943 if ((n_lines!=1)&&((n_pixels==288)||(n_pixels==384)))
946 WriteLog(" cmd = 0x%.8x\n",cmd);
947 WriteLog(" a1_base = %08X\n", a1_addr);
948 WriteLog(" a1_pitch = %d\n", a1_pitch);
949 WriteLog(" a1_psize = %d\n", a1_psize);
950 WriteLog(" a1_width = %d\n", a1_width);
951 WriteLog(" a1_xadd = %f (phrase=%d)\n", (float)a1_xadd / 65536.0, a1_phrase_mode);
952 WriteLog(" a1_yadd = %f\n", (float)a1_yadd / 65536.0);
953 WriteLog(" a1_xstep = %f\n", (float)a1_step_x / 65536.0);
954 WriteLog(" a1_ystep = %f\n", (float)a1_step_y / 65536.0);
955 WriteLog(" a1_x = %f\n", (float)a1_x / 65536.0);
956 WriteLog(" a1_y = %f\n", (float)a1_y / 65536.0);
957 WriteLog(" a1_zoffs = %i\n",a1_zoffs);
959 WriteLog(" a2_base = %08X\n", a2_addr);
960 WriteLog(" a2_pitch = %d\n", a2_pitch);
961 WriteLog(" a2_psize = %d\n", a2_psize);
962 WriteLog(" a2_width = %d\n", a2_width);
963 WriteLog(" a2_xadd = %f (phrase=%d)\n", (float)a2_xadd / 65536.0, a2_phrase_mode);
964 WriteLog(" a2_yadd = %f\n", (float)a2_yadd / 65536.0);
965 WriteLog(" a2_xstep = %f\n", (float)a2_step_x / 65536.0);
966 WriteLog(" a2_ystep = %f\n", (float)a2_step_y / 65536.0);
967 WriteLog(" a2_x = %f\n", (float)a2_x / 65536.0);
968 WriteLog(" a2_y = %f\n", (float)a2_y / 65536.0);
969 WriteLog(" a2_mask_x= 0x%.4x\n",a2_mask_x);
970 WriteLog(" a2_mask_y= 0x%.4x\n",a2_mask_y);
971 WriteLog(" a2_zoffs = %i\n",a2_zoffs);
973 WriteLog(" count = %d x %d\n", n_pixels, n_lines);
975 WriteLog(" command = %08X\n", cmd);
976 WriteLog(" dsten = %i\n",DSTEN);
977 WriteLog(" srcen = %i\n",SRCEN);
978 WriteLog(" patdsel = %i\n",PATDSEL);
979 WriteLog(" color = 0x%.8x\n",REG(PATTERNDATA));
980 WriteLog(" dcompen = %i\n",DCOMPEN);
981 WriteLog(" bcompen = %i\n",BCOMPEN);
982 WriteLog(" cmpdst = %i\n",CMPDST);
983 WriteLog(" GOURZ = %i\n",GOURZ);
984 WriteLog(" GOURD = %i\n",GOURD);
985 WriteLog(" SRCSHADE = %i\n",SRCSHADE);
986 WriteLog(" DSTDATA = 0x%.8x%.8x\n",REG(DSTDATA),REG(DSTDATA+4));
994 WriteLog(" cmd = 0x%.8x\n",cmd);
995 WriteLog(" a1_base = %08X\n", a1_addr);
996 WriteLog(" a1_pitch = %d\n", a1_pitch);
997 WriteLog(" a1_psize = %d\n", a1_psize);
998 WriteLog(" a1_width = %d\n", a1_width);
999 WriteLog(" a1_xadd = %f (phrase=%d)\n", (float)a1_xadd / 65536.0, a1_phrase_mode);
1000 WriteLog(" a1_yadd = %f\n", (float)a1_yadd / 65536.0);
1001 WriteLog(" a1_xstep = %f\n", (float)a1_step_x / 65536.0);
1002 WriteLog(" a1_ystep = %f\n", (float)a1_step_y / 65536.0);
1003 WriteLog(" a1_x = %f\n", (float)a1_x / 65536.0);
1004 WriteLog(" a1_y = %f\n", (float)a1_y / 65536.0);
1005 WriteLog(" a1_zoffs = %i\n",a1_zoffs);
1007 WriteLog(" a2_base = %08X\n", a2_addr);
1008 WriteLog(" a2_pitch = %d\n", a2_pitch);
1009 WriteLog(" a2_psize = %d\n", a2_psize);
1010 WriteLog(" a2_width = %d\n", a2_width);
1011 WriteLog(" a2_xadd = %f (phrase=%d)\n", (float)a2_xadd / 65536.0, a2_phrase_mode);
1012 WriteLog(" a2_yadd = %f\n", (float)a2_yadd / 65536.0);
1013 WriteLog(" a2_xstep = %f\n", (float)a2_step_x / 65536.0);
1014 WriteLog(" a2_ystep = %f\n", (float)a2_step_y / 65536.0);
1015 WriteLog(" a2_x = %f\n", (float)a2_x / 65536.0);
1016 WriteLog(" a2_y = %f\n", (float)a2_y / 65536.0);
1017 WriteLog(" a2_mask_x= 0x%.4x\n",a2_mask_x);
1018 WriteLog(" a2_mask_y= 0x%.4x\n",a2_mask_y);
1019 WriteLog(" a2_zoffs = %i\n",a2_zoffs);
1021 WriteLog(" count = %d x %d\n", n_pixels, n_lines);
1023 WriteLog(" command = %08X\n", cmd);
1024 WriteLog(" dsten = %i\n",DSTEN);
1025 WriteLog(" srcen = %i\n",SRCEN);
1026 WriteLog(" patdsel = %i\n",PATDSEL);
1027 WriteLog(" color = 0x%.8x\n",REG(PATTERNDATA));
1028 WriteLog(" dcompen = %i\n",DCOMPEN);
1029 WriteLog(" bcompen = %i\n",BCOMPEN);
1030 WriteLog(" cmpdst = %i\n",CMPDST);
1031 WriteLog(" GOURZ = %i\n",GOURZ);
1032 WriteLog(" GOURD = %i\n",GOURD);
1033 WriteLog(" SRCSHADE= %i\n",SRCSHADE);
1037 extern int blit_start_log;
1038 extern int op_start_log;
1041 char * ctrlStr[4] = { "XADDPHR\0", "XADDPIX\0", "XADD0\0", "XADDINC\0" };
1042 char * bppStr[8] = { "1bpp\0", "2bpp\0", "4bpp\0", "8bpp\0", "16bpp\0", "32bpp\0", "???\0", "!!!\0" };
1043 char * opStr[16] = { "LFU_CLEAR", "LFU_NSAND", "LFU_NSAD", "LFU_NOTS", "LFU_SAND", "LFU_NOTD", "LFU_N_SXORD", "LFU_NSORND",
1044 "LFU_SAD", "LFU_XOR", "LFU_D", "LFU_NSORD", "LFU_REPLACE", "LFU_SORND", "LFU_SORD", "LFU_ONE" };
1045 uint32 src = cmd & 0x07, dst = (cmd >> 3) & 0x07, misc = (cmd >> 6) & 0x03,
1046 a1ctl = (cmd >> 8) & 0x07, mode = (cmd >> 11) & 0x07, ity = (cmd >> 14) & 0x0F,
1047 zop = (cmd >> 18) & 0x07, op = (cmd >> 21) & 0x0F, ctrl = (cmd >> 25) & 0x3F;
1048 UINT32 a1f = REG(A1_FLAGS), a2f = REG(A2_FLAGS);
1049 uint32 p1 = a1f & 0x07, p2 = a2f & 0x07,
1050 d1 = (a1f >> 3) & 0x07, d2 = (a2f >> 3) & 0x07,
1051 zo1 = (a1f >> 6) & 0x07, zo2 = (a2f >> 6) & 0x07,
1052 w1 = (a1f >> 9) & 0x3F, w2 = (a2f >> 9) & 0x3F,
1053 ac1 = (a1f >> 16) & 0x1F, ac2 = (a2f >> 16) & 0x1F;
1054 UINT32 iw1 = ((0x04 | (w1 & 0x03)) << ((w1 & 0x3C) >> 2)) >> 2;
1055 UINT32 iw2 = ((0x04 | (w2 & 0x03)) << ((w2 & 0x3C) >> 2)) >> 2;
1056 WriteLog("Blit! (%08X %s %08X) count: %d x %d, A1/2_FLAGS: %08X/%08X [cmd: %08X]\n", a1_addr, (mode&0x01 ? "->" : "<-"), a2_addr, n_pixels, n_lines, a1f, a2f, cmd);
1057 // WriteLog(" CMD -> src: %d, dst: %d, misc: %d, a1ctl: %d, mode: %d, ity: %1X, z-op: %d, op: %1X, ctrl: %02X\n", src, dst, misc, a1ctl, mode, ity, zop, op, ctrl);
1059 WriteLog(" CMD -> src: %s%s%s ", (cmd & 0x0001 ? "SRCEN " : ""), (cmd & 0x0002 ? "SRCENZ " : ""), (cmd & 0x0004 ? "SRCENX" : ""));
1060 WriteLog("dst: %s%s%s ", (cmd & 0x0008 ? "DSTEN " : ""), (cmd & 0x0010 ? "DSTENZ " : ""), (cmd & 0x0020 ? "DSTWRZ" : ""));
1061 WriteLog("misc: %s%s ", (cmd & 0x0040 ? "CLIP_A1 " : ""), (cmd & 0x0080 ? "???" : ""));
1062 WriteLog("a1ctl: %s%s%s ", (cmd & 0x0100 ? "UPDA1F " : ""), (cmd & 0x0200 ? "UPDA1 " : ""), (cmd & 0x0400 ? "UPDA2" : ""));
1063 WriteLog("mode: %s%s%s ", (cmd & 0x0800 ? "DSTA2 " : ""), (cmd & 0x1000 ? "GOURD " : ""), (cmd & 0x2000 ? "ZBUFF" : ""));
1064 WriteLog("ity: %s%s%s ", (cmd & 0x4000 ? "TOPBEN " : ""), (cmd & 0x8000 ? "TOPNEN " : ""), (cmd & 0x00010000 ? "PATDSEL" : ""));
1065 WriteLog("z-op: %s%s%s ", (cmd & 0x00040000 ? "ZMODELT " : ""), (cmd & 0x00080000 ? "ZMODEEQ " : ""), (cmd & 0x00100000 ? "ZMODEGT" : ""));
1066 WriteLog("op: %s ", opStr[(cmd >> 21) & 0x0F]);
1067 WriteLog("ctrl: %s%s%s%s%s%s\n", (cmd & 0x02000000 ? "CMPDST " : ""), (cmd & 0x04000000 ? "BCOMPEN " : ""), (cmd & 0x08000000 ? "DCOMPEN " : ""), (cmd & 0x10000000 ? "BKGWREN " : ""), (cmd & 0x20000000 ? "BUSHI " : ""), (cmd & 0x40000000 ? "SRCSHADE" : ""));
1071 WriteLog(" A2 step values: %d (X), %d (Y) [mask (%sused): %08X - %08X/%08X]\n", a2_step_x >> 16, a2_step_y >> 16, (a2f & 0x8000 ? "" : "un"), REG(A2_MASK), a2_mask_x, a2_mask_y);
1074 WriteLog(" A1 -> pitch: %d phrases, depth: %s, z-off: %d, width: %d (%02X), addctl: %s %s %s %s\n", 1 << p1, bppStr[d1], zo1, iw1, w1, ctrlStr[ac1&0x03], (ac1&0x04 ? "YADD1" : "YADD0"), (ac1&0x08 ? "XSIGNSUB" : "XSIGNADD"), (ac1&0x10 ? "YSIGNSUB" : "YSIGNADD"));
1075 WriteLog(" A2 -> pitch: %d phrases, depth: %s, z-off: %d, width: %d (%02X), addctl: %s %s %s %s\n", 1 << p2, bppStr[d2], zo2, iw2, w2, ctrlStr[ac2&0x03], (ac2&0x04 ? "YADD1" : "YADD0"), (ac2&0x08 ? "XSIGNSUB" : "XSIGNADD"), (ac2&0x10 ? "YSIGNSUB" : "YSIGNADD"));
1076 WriteLog(" A1 x/y: %d/%d, A2 x/y: %d/%d\n", a1_x >> 16, a1_y >> 16, a2_x >> 16, a2_y >> 16);
1077 // blit_start_log = 0;
1078 // op_start_log = 1;
1081 blitter_working = 1;
1082 //#ifndef USE_GENERIC_BLITTER
1083 // if (!blitter_execute_cached_code(blitter_in_cache(cmd)))
1085 blitter_generic(cmd);
1087 /*if (blit_start_log)
1089 if (a1_addr == 0xF03000 && a2_addr == 0x004D58)
1091 WriteLog("\nBytes at 004D58:\n");
1092 for(int i=0x004D58; i<0x004D58+(10*127*4); i++)
1093 WriteLog("%02X ", jaguar_byte_read(i));
1094 WriteLog("\nBytes at F03000:\n");
1095 for(int i=0xF03000; i<0xF03000+(6*127*4); i++)
1096 WriteLog("%02X ", jaguar_byte_read(i));
1101 blitter_working = 0;
1104 uint32 blitter_long_read(uint32 offset)
1106 return (blitter_word_read(offset) << 16) | blitter_word_read(offset+2);
1109 void blitter_long_write(uint32 offset, uint32 data)
1111 blitter_word_write(offset, data >> 16);
1112 blitter_word_write(offset+2, data & 0xFFFF);
1115 void blitter_init(void)
1120 void blitter_reset(void)
1122 memset(blitter_ram, 0x00, 0xA0);
1125 void blitter_done(void)
1127 WriteLog("BLIT: Done.\n");
1130 void blitter_byte_write(uint32 offset, uint8 data)
1132 /*if (offset & 0xFF == 0x7B)
1133 WriteLog("--> Wrote to B_STOP: value -> %02X\n", data);*/
1136 // if ((offset >= 0x7C) && (offset <= 0x9B))
1137 if ((offset >= 0x7C) && (offset <= 0x8B))
1142 case 0x7D: blitter_ram[0x69] = data; break;
1143 case 0x7E: blitter_ram[0x40] = data; break;
1144 case 0x7F: blitter_ram[0x41] = data; break;
1147 case 0x81: blitter_ram[0x6B] = data; break;
1148 case 0x82: blitter_ram[0x42] = data; break;
1149 case 0x83: blitter_ram[0x43] = data; break;
1152 case 0x85: blitter_ram[0x6D] = data; break;
1153 case 0x86: blitter_ram[0x44] = data; break;
1154 case 0x87: blitter_ram[0x45] = data; break;
1157 case 0x89: blitter_ram[0x6F] = data; break;
1159 // case 0x9A: blitter_ram[0x46] = data; break;
1160 // case 0x9B: blitter_ram[0x47] = data; break;
1161 case 0x8A: blitter_ram[0x46] = data; break;
1162 case 0x8B: blitter_ram[0x47] = data; break;
1166 blitter_ram[offset] = data;
1169 void blitter_word_write(uint32 offset, uint16 data)
1171 blitter_byte_write(offset+0, (data>>8) & 0xFF);
1172 blitter_byte_write(offset+1, data & 0xFF);
1174 if ((offset & 0xFF) == 0x3A)
1175 // I.e., the second write of 32-bit value--not convinced this is the best way to do this!
1176 // But then again, according to the Jaguar docs, this is correct...!
1177 blitter_blit(GET32(blitter_ram, 0x38));
1178 // Testing purposes only!
1179 //This does the clipping correctly, but not the Gouraud shading...
1180 // blitter2_exec(GET32(blitter_ram, 0x38));
1184 uint8 blitter_byte_read(uint32 offset)
1189 if (offset == (0x38 + 3))
1190 return 0x01; // always idle
1192 return blitter_ram[offset];
1195 uint16 blitter_word_read(uint32 offset)
1197 return ((uint16)blitter_byte_read(offset) << 8) | (uint16)blitter_byte_read(offset+1);