]> Shamusworld >> Repos - virtualjaguar/blob - src/blitter2.cpp
Virtual Jaguar 1.0.4 update (Shamus)
[virtualjaguar] / src / blitter2.cpp
1 //#include "stdafx.h"
2 #include "jaguar.h"
3 #include "blitter.h"
4 //#include "mem.h"
5 //#include "regs.h"
6
7 //extern BYTE* MEM;
8
9 // Stuff from the header file...
10
11 typedef struct {
12         int srcen;
13         int srcenz;
14         int srcenx;
15         int dsten;
16         int dstenz;
17         int dstwrz;
18         int clip_a1;
19         int upda1f;
20         int upda1;
21         int upda2;
22         int dsta2;
23         int gourd;
24         int zbuff;
25         int topben;
26         int topnen;
27         int patdsel;
28         int adddsel;
29         int zmode;
30         int logic;
31         int cmpdst;
32         int bcompen;
33         int dcompen;
34         int bkgwren;
35         int srcshade;
36 } BLITCMD;
37
38 typedef struct {
39         DWORD base;
40         DWORD pitch;
41         DWORD width;
42         DWORD depth;
43         DWORD z_offset;
44         signed int xadd;
45         signed int yadd;
46         WORD clip_x;
47         WORD clip_y;
48         unsigned int pixel_x;
49         unsigned int pixel_y;
50         signed int step_x;
51         signed int step_y;
52         unsigned int fstep_x;
53         unsigned int fstep_y;
54         signed int inc_x;
55         signed int inc_y;
56         DWORD pixelmode;
57         DWORD xsign;
58         DWORD ysign;
59 } BLIT_A1;
60
61 typedef struct {
62         DWORD base;
63         DWORD pitch;
64         DWORD width;
65         DWORD depth;
66         DWORD z_offset;
67         DWORD mask_enable;
68         signed int xadd;
69         signed int yadd;
70         DWORD mask;
71         unsigned int pixel_x;
72         unsigned int pixel_y;
73         signed int step_x;
74         signed int step_y;
75         DWORD pixelmode;
76         DWORD xsign;
77         DWORD ysign;
78 } BLIT_A2;
79
80 const DWORD bitdepth[8] = { 1,2,4,8,16,32,0,0 };
81 const DWORD bitsize[8] = { 1,1,1,1,2,4,0,0 };
82 const DWORD pitch[4] = { 8, 16, 32, 24 };
83 const DWORD pixels_phrase[8] = {64,32,16,8,4,2,1,0};
84
85 const DWORD width_table[64] = {   1,   1,   1,   1,   2,   2,   3,   3,
86                                   4,   4,   6,   6,   8,  10,  12,  14,
87                                                              16,  20,  24,  28,  32,  40,  48,  56,
88                                                                  64,  80,  96, 112, 128, 160, 192, 224,
89                                                             256, 320, 384, 448, 512, 640, 768, 896,
90                                                            1024,1280,1536,1792,2048,2560,3072,3584,
91                                                            4096,5120,6144,7168,8192,10240,12288,14336,
92                                                            16384,20480,24576,28672,32768,40960,49152,57344 };
93
94 //
95
96 // More stuff from REG.H
97
98 // Blitter Registers
99
100 #define A1_BASE                 jaguar_long_read(0xF02200)
101 #define A1_FLAGS                jaguar_long_read(0xF02204)
102 #define A1_CLIP                 jaguar_long_read(0xF02208)
103 #define A1_CLIP_X               jaguar_word_read(0xF0220A)
104 #define A1_CLIP_Y               jaguar_word_read(0xF02208)
105 #define A1_PIXEL                jaguar_long_read(0xF0220C)
106 #define A1_PIXEL_Y              jaguar_word_read(0xF0220C)
107 #define A1_PIXEL_X              jaguar_word_read(0xF0220E)
108 #define A1_STEP                 jaguar_long_read(0xF02210)
109 #define A1_STEP_Y               jaguar_word_read(0xF02210)
110 #define A1_STEP_X               jaguar_word_read(0xF02212)
111 #define A1_FSTEP                jaguar_long_read(0xF02214)
112 #define A1_FSTEP_Y              jaguar_word_read(0xF02214)
113 #define A1_FSTEP_X              jaguar_word_read(0xF02216)
114 #define A1_FPIXEL               jaguar_long_read(0xF02218)
115 #define A1_FPIXEL_Y             jaguar_word_read(0xF02218)
116 #define A1_FPIXEL_X             jaguar_word_read(0xF0221A)
117 #define A1_INC                  jaguar_long_read(0xF0221C)
118 #define A1_INC_Y                jaguar_word_read(0xF0221C)
119 #define A1_INC_X                jaguar_word_read(0xF0221E)
120 #define A1_FINC                 jaguar_long_read(0xF02220)
121 #define A1_FINC_Y               jaguar_word_read(0xF02220)
122 #define A1_FINC_X               jaguar_word_read(0xF02222)
123 #define A2_BASE                 jaguar_long_read(0xF02224)
124 #define A2_FLAGS                jaguar_long_read(0xF02228)
125 #define A2_MASK                 jaguar_long_read(0xF0222C)
126 #define A2_MASK_Y               jaguar_word_read(0xF0222C)
127 #define A2_MASK_X               jaguar_word_read(0xF0222E)
128 #define A2_PIXEL                jaguar_long_read(0xF02230)
129 #define A2_PIXEL_Y              jaguar_word_read(0xF02230)
130 #define A2_PIXEL_X              jaguar_word_read(0xF02232)
131 #define A2_STEP                 jaguar_long_read(0xF02234)
132 #define A2_STEP_Y               jaguar_word_read(0xF02234)
133 #define A2_STEP_X               jaguar_word_read(0xF02236)
134 #define B_CMD                   jaguar_long_read(0xF02238)
135 #define B_COUNT                 jaguar_long_read(0xF0223C)
136 #define B_COUNT_OUT             jaguar_word_read(0xF0223C)
137 #define B_COUNT_IN              jaguar_word_read(0xF0223E)
138 #define B_SRCD                  *(LONGLONG*)(MEM+0xF02240)
139 #define B_SRCD0                 jaguar_long_read(0xF02240)
140 #define B_SRCD1                 jaguar_long_read(0xF02244)
141 #define B_DSTD                  *(LONGLONG*)(MEM+0xF02248)
142 #define B_DSTD0                 jaguar_long_read(0xF02248)
143 #define B_DSTD1                 jaguar_long_read(0xF0224C)
144 #define B_DSTZ                  *(LONGLONG*)(MEM+0xF02250)
145 #define B_DSTZ0                 jaguar_long_read(0xF02250)
146 #define B_DSTZ1                 jaguar_long_read(0xF02254)
147 #define B_SRCZ                  *(LONGLONG*)(MEM+0xF02258)   // Source Z Integer
148 #define B_SRCZ0                 jaguar_long_read(0xF02258)
149 #define B_SRCZ1                 jaguar_long_read(0xF0225C)
150 #define B_SRCZF                 *(LONGLONG*)(MEM+0xF02260)   // Source Z Fraction
151 #define B_SRCZF0                jaguar_long_read(0xF02260)
152 #define B_SRCZF1                jaguar_long_read(0xF02264)
153 #define B_PATD                  *(LONGLONG*)(MEM+0xF02268)
154 #define B_PATD0                 jaguar_long_read(0xF02268)
155 #define B_PATD1                 jaguar_long_read(0xF0226C)
156 #define B_IINC                  jaguar_long_read(0xF02270)
157 #define B_IINC_I                jaguar_word_read(0xF02270)
158 #define B_IINC_F                jaguar_word_read(0xF02272)
159 #define B_ZINC                  jaguar_long_read(0xF02274)
160 #define B_ZINC_I                jaguar_word_read(0xF02274)
161 #define B_ZINC_F                jaguar_word_read(0xF02276)
162 #define B_STOP                  jaguar_long_read(0xF02278)
163 #define B_I3                    jaguar_long_read(0xF0227C)
164 #define B_I3_I                  jaguar_word_read(0xF0227C)
165 #define B_I3_F                  jaguar_word_read(0xF0227E)
166 #define B_I2                    jaguar_long_read(0xF02280)
167 #define B_I2_I                  jaguar_word_read(0xF02280)
168 #define B_I2_F                  jaguar_word_read(0xF02282)
169 #define B_I1                    jaguar_long_read(0xF02284)
170 #define B_I1_I                  jaguar_word_read(0xF02284)
171 #define B_I1_F                  jaguar_word_read(0xF02286)
172 #define B_I0                    jaguar_long_read(0xF02288)
173 #define B_I0_I                  jaguar_word_read(0xF02288)
174 #define B_I0_F                  jaguar_word_read(0xF0228A)
175 #define B_Z3                    jaguar_long_read(0xF0228C)
176 #define B_Z3_I                  jaguar_word_read(0xF0228C)
177 #define B_Z3_F                  jaguar_word_read(0xF0228E)
178 #define B_Z2                    jaguar_long_read(0xF02290)
179 #define B_Z2_I                  jaguar_word_read(0xF02290)
180 #define B_Z2_F                  jaguar_word_read(0xF02292)
181 #define B_Z1                    jaguar_long_read(0xF02294)
182 #define B_Z1_I                  jaguar_word_read(0xF02294)
183 #define B_Z1_F                  jaguar_word_read(0xF02296)
184 #define B_Z0                    jaguar_long_read(0xF02298)
185 #define B_Z0_I                  jaguar_word_read(0xF02298)
186 #define B_Z0_F                  jaguar_word_read(0xF0229A)
187
188 //#define DWORDBIG(x) ((x>>16)&0xFFFF)|(x<<16)
189 #define DWORDBIG(x)             x
190
191 //
192
193 //const pixels_per_phrase[8] = { 64, 32, 16, 8, 4, 2, 1, 0 };
194
195 void blitter2_exec(DWORD cmd)
196 {
197         DWORD* src,* dst,* read;
198         DWORD a1_address, a2_address;
199         DWORD a1_bm,a2_bm;
200         DWORD* src_bm,* dst_bm;
201         BLITCMD bcmd;
202         BLIT_A1 a1;
203         BLIT_A2 a2;
204         memset(&a1,0,sizeof(BLIT_A1));
205         memset(&a2,0,sizeof(BLIT_A2));
206         memset(&bcmd,0,sizeof(BLITCMD));
207         DWORD srcd = 0xF02240;
208         DWORD dstd = 0xF02248;
209         DWORD patd = 0xF02268;
210
211         bcmd.srcen = (cmd & 0x1) ? 1 : 0;
212         bcmd.srcenz = (cmd & 0x2) ? 1 : 0;
213         bcmd.srcenx = (cmd & 0x4) ? 1 : 0;
214         bcmd.dsten = (cmd & 0x8) ? 1 : 0;
215         bcmd.dstenz = (cmd & 0x10) ? 1 : 0;
216         bcmd.dstwrz = (cmd & 0x20) ? 1 : 0;
217         bcmd.clip_a1 = (cmd & 0x40) ? 1 : 0;
218         bcmd.upda1f = (cmd & 0x100) ? 1 : 0;
219         bcmd.upda1 = (cmd & 0x200) ? 1 : 0;
220         bcmd.upda2 = (cmd & 0x400) ? 1 : 0;
221         bcmd.dsta2 = (cmd & 0x800) ? 1 : 0;
222         bcmd.gourd = (cmd & 0x1000) ? 1 : 0;
223         bcmd.patdsel = (cmd & 0x10000) ? 1 : 0;
224         bcmd.cmpdst = (cmd & 0x2000000) ? 1 : 0;
225         bcmd.bcompen = (cmd & 0x4000000) ? 1 : 0;
226         bcmd.dcompen = (cmd & 0x8000000) ? 1 : 0;
227         bcmd.bkgwren = (cmd & 0x10000000) ? 1 : 0;
228         bcmd.srcshade = (cmd & 0x40000000) ? 1 : 0;
229         bcmd.logic = (cmd >> 21) & 0xF;
230         bcmd.zmode = (cmd >> 18) & 0x7;
231
232         DWORD outer_loop = B_COUNT_OUT;
233         DWORD inner_loop = B_COUNT_IN;
234
235         a1.base = DWORDBIG(A1_BASE);
236         DWORD flags = DWORDBIG(A1_FLAGS);
237         a1.pitch = flags & 0x3;
238         a1.depth = (flags >> 3) & 0x7;
239         a1.z_offset = ((flags >> 6) & 0x7)*8;
240         a1.xadd = (short)((flags >> 16) & 0x3);
241         a1.pixel_x = A1_PIXEL_X << 16 | A1_FPIXEL_X;
242         a1.pixel_y = A1_PIXEL_Y << 16 | A1_FPIXEL_Y;
243         a1.step_x = (signed short)A1_STEP_X << 16;
244         a1.step_y = (signed short)A1_STEP_Y << 16;
245         a1.fstep_x = A1_FSTEP_X;
246         a1.fstep_y = A1_FSTEP_Y;
247         a1.inc_x = A1_INC_X << 16 | A1_FINC_X;
248         a1.inc_y = A1_INC_Y << 16 | A1_FINC_Y;
249         a1.clip_x = A1_CLIP_X & 0x7FFF;
250         a1.clip_y = A1_CLIP_Y & 0x7FFF;
251         a1.width = width_table[(flags >> 9) & 0x3F];
252
253         a1.yadd = (short)((flags >> 18) & 0x1);
254         a1.xsign = (flags >> 19) & 0x1;
255         a1.ysign = (flags >> 20) & 0x1;
256         if(a1.ysign)
257                 a1.yadd = -a1.yadd;
258         a1.pixelmode = (flags >> 16) & 0x3;
259
260         a2.base = DWORDBIG(A2_BASE);
261         flags = DWORDBIG(A2_FLAGS);
262         a2.pitch = flags & 0x3;
263         a2.z_offset = ((flags >> 6) & 0x7)*8;
264         a2.pixel_x = A2_PIXEL_X;
265         a2.pixel_y = A2_PIXEL_Y;
266         a2.step_x = (signed short)A2_STEP_X;
267         a2.step_y = (signed short)A2_STEP_Y;
268         a2.mask = DWORDBIG(A2_MASK);
269         a2.width = width_table[(flags >> 9) & 0x3F];
270 //      a2.yadd = (flags >> 18) & 0x1;
271         a2.yadd = a1.yadd; // Buggy blitter !!? YES! It is!!!
272         a2.pixelmode = (flags >> 16) & 0x3;
273         a2.xsign = (flags >> 19) & 0x1;
274         a2.ysign = (flags >> 20) & 0x1;
275         if(a2.ysign)
276                 a2.yadd = -a2.yadd;
277
278         if(bcmd.dsta2 == 0) {
279                 dst = &a1_address;
280                 src = &a2_address;
281                 read = &a1_address;
282                 dst_bm = &a1_bm;
283                 src_bm = &a2_bm;
284         } else {
285                 src = &a1_address;
286                 dst = &a2_address;
287                 read = &a2_address;
288                 dst_bm = &a2_bm;
289                 src_bm = &a1_bm;
290         }
291         if(!bcmd.srcen) {
292                 src = &srcd;
293         }
294         if(bcmd.patdsel) {
295                 src = &patd;
296         }
297         if(!bcmd.dsten) {
298                 read = &dstd;
299         }
300
301         int src_zoffset,dst_zoffset;
302         if(bcmd.dsta2) {
303                 src_zoffset = a1.z_offset;
304                 dst_zoffset = a2.z_offset;
305         } else {
306                 src_zoffset = a2.z_offset;
307                 dst_zoffset = a1.z_offset;
308         }
309
310         unsigned int a1_x = a1.pixel_x;
311         unsigned int a1_y = a1.pixel_y;
312         unsigned int a2_x = a2.pixel_x;
313         unsigned int a2_y = a2.pixel_y;
314         int a1_size = pitch[a1.pitch];
315         int a2_size = pitch[a2.pitch];
316         //inner_loop = (inner_loop * bitdepth[a1.depth]) / 8;
317
318         int a1_inc_x,a1_inc_y;
319         short a2_inc_x;
320         switch(a1.pixelmode) {
321                 case 0:a1_inc_x = 1<<16; a1_inc_y = a1.yadd<<16; break;
322                 case 1:a1_inc_x = 1<<16; a1_inc_y = a1.yadd<<16; break;
323                 case 2:a1_inc_x = 0; a1_inc_y = a1.yadd<<16; break;
324                 case 3:a1_inc_x = a1.inc_x; a1_inc_y = a1.inc_y; break;
325         }
326         if(a1.xsign)
327                 a1_inc_x = -a1_inc_x;
328         switch(a2.pixelmode) {
329                 case 0:a2_inc_x = 1;break;
330                 case 1:a2_inc_x = 1;break;
331                 case 2:a2_inc_x = 0;break;
332                 case 3:a2_inc_x = 1;break;
333         }
334         if(a2.xsign)
335                 a2_inc_x = -a2_inc_x;
336
337         int gd_i[4];
338         int gd_c[4];
339         int gd_ia,gd_ca;
340         DWORD gouraud_add,gouraud_data;
341         WORD gint[4],gfrac[4];
342         BYTE gcolour[4];
343         gouraud_add = jaguar_long_read(0xF02270);
344         gcolour[3] = jaguar_byte_read(0xF02268);
345         gcolour[2] = jaguar_byte_read(0xF0226A);
346         gcolour[1] = jaguar_byte_read(0xF0226C);
347         gcolour[0] = jaguar_byte_read(0xF0226E);
348         gint[3] = jaguar_word_read(0xF0227C);
349         gint[2] = jaguar_word_read(0xF02280);
350         gint[1] = jaguar_word_read(0xF02284);
351         gint[0] = jaguar_word_read(0xF02288);
352         gfrac[3] = jaguar_word_read(0xF0227E);
353         gfrac[2] = jaguar_word_read(0xF02282);
354         gfrac[1] = jaguar_word_read(0xF02286);
355         gfrac[0] = jaguar_word_read(0xF0228A);
356         gd_ia = gouraud_add & 0xFFFFFF;
357         if(gd_ia & 0x800000)
358                 gd_ia = 0xFF000000 | gd_ia;
359         gd_ca = (gouraud_add>>24) & 0xFF;
360         if(gd_ca & 0x80)
361                 gd_ca = 0xFFFFFF00 | gd_ca;
362         for(int v=0;v<4;v++) {
363                 gd_i[v] = gint[v] & 0xFF;
364                 //if(gd_i[v] & 0x80)
365                 //      gd_i[v] = 0xFF00 | gd_i[v];
366                 gd_i[v] = (gd_i[v] << 16) | gfrac[v];
367                 gd_c[v] = gcolour[v]<<4;
368         }
369         int colour_index = 0;
370         int pi=0;
371         switch(a1.depth) {
372                 case 0:case 1:case 2:case 3:
373                         for(DWORD j=0; j<outer_loop; j++) {
374                                 int old_a1x = a1_x;
375                                 int old_a2x = a2_x;
376                                 for(DWORD i=0; i<(inner_loop*bitdepth[a1.depth]); i+=bitdepth[a1.depth]) {
377                                         BYTE src1,src2=0;
378                                         BYTE dst1,dst2;
379                                         BYTE dst_old;
380                                         a1_address = a1.base + ((((a1_y>>16) * a1.width + (a1_x>>16))*bitdepth[a1.depth])/8);
381                                         a2_address = a2.base + (((a2_y * a2.width + a2_x)*bitdepth[a1.depth])/8);
382                                         src1 = jaguar_byte_read(*src);
383                                         dst1 = jaguar_byte_read(*dst);
384                                         dst_old = dst1;
385                                         //jaguar_long_read(*src+4,&src2);
386                                         if(!bcmd.patdsel) {
387                                                 //jaguar_long_read(*dst+4,&dst2);
388                                                 switch(bcmd.logic)
389                                                 {
390                                                 case 0:dst1 = 0;dst2 = 0;break;                         
391                                                 case 1:dst1 = !src1 & !dst1; dst2 = !src2 & !dst2;break;
392                                                 case 2:dst1 = !src1 &  dst1; dst2 = !src2 & dst2;break;                         
393                                                 case 3:dst1 = !src1; dst2 = !src2;break;
394                                                 case 4:dst1 = src1 & !dst1; dst2 = src2 & !dst2;break;
395                                                 case 5:dst1 = !dst1; dst2 = !dst2;break;
396                                                 case 6:dst1 = !(src1 ^ dst1); dst2 = !(src2 ^ dst2);break;
397                                                 case 7:dst1 = !src1 | !dst1; dst2 = !src2 | !dst2;break;
398                                                 case 8:dst1 = src1 & dst1; dst2 = src2 & dst2;break;
399                                                 case 9:dst1 = src1 ^ dst1; dst2 = src2 ^ dst2;break;
400                                                 case 10:dst1 = dst1; dst2 = dst2;break;
401                                                 case 11:dst1 = !src1 | dst1; dst2 = !src2 | dst2;break;
402                                                 case 12:dst1 = src1; dst2 = src2;break;
403                                                 case 13:dst1 = src1 | !dst1; dst2 = src2 | !dst2;break;
404                                                 case 14:dst1 = src1 | dst1; dst2 = src2 | dst2;break;
405                                                 case 15:dst1 = 0xFF; dst2 = 0xFF;break;
406                                                 }
407                                         } else {
408                                                 dst1 = src1;
409                                                 //dst2 = src2;
410                                         }
411                                         if(bcmd.dcompen) {
412                                                 BYTE pattern;
413                                                 pattern = jaguar_byte_read(0xF02268);
414                                                 if(!bcmd.cmpdst) {
415                                                         if(src1 == !dst_old)
416                                                         dst1 = dst_old;
417                                                 } else {                                        
418                                                         if(dst1 == !dst_old)
419                                                         dst1 = dst_old;
420                                                 }
421                                         }
422                                         if(bcmd.clip_a1) {
423                                                 if((a1_x>>16) < a1.clip_x && (a1_x>>16) >= 0 && (a1_y>>16) < a1.clip_y && (a1_y>>16) >= 0) {
424                                                         jaguar_byte_write(*dst,dst1);
425                                                         //jaguar_long_write(*dst+4,dst2);
426                                                 }
427                                         } else {
428                                                 jaguar_byte_write(*dst,dst1);
429                                                 //jaguar_long_write(*dst+4,dst2);
430                                         }
431                                         a1_x += a1_inc_x;
432                                         a2_x += a2_inc_x;
433                                         a1_y += a1_inc_y;
434                                         a2_y += a2.yadd;
435                                         for(int v=0;v<4;v++) {
436                                                 gd_i[v] += gd_ia;
437                                                 gd_c[v] += gd_ca;
438                                         }
439                                 }
440                                 if(bcmd.upda1) {
441                                         a1_x += a1.step_x;
442                                         a1_y += a1.step_y;
443                                 }
444                                 if(bcmd.upda1f) {
445                                         a1_x += a1.fstep_x;
446                                         a1_y += a1.fstep_y;
447                                 }
448                                 if(bcmd.upda2) {
449                                         a2_x += a2.step_x;
450                                         a2_y += a2.step_y;
451                                 }
452                                 //a1_x = old_a1x;
453                                 //a2_x = old_a2x;
454                         }
455                         break;
456                 case 4:
457                         {
458                         int zinc = jaguar_long_read(0xF02274);
459                         INT32 compz[4];
460                         compz[0] = jaguar_long_read(0xF0228C);
461                         compz[1] = jaguar_long_read(0xF02290);
462                         compz[2] = jaguar_long_read(0xF02294);
463                         compz[3] = jaguar_long_read(0xF02298);
464                         for(DWORD j=0; j<outer_loop; j++) {
465                                 for(DWORD i=0; i<inner_loop*2; i+=2) {
466                                         WORD src1,src2;
467                                         WORD dst1,dst2;
468                                         WORD dst_old;
469                                         WORD srcz,dstz;
470                                         a1_address = a1.base + (((a1_y>>16) * a1.width + ((a1_x>>16)&0xFFFFFFFC))*2*(a1_size/8)) + (((a1_x>>16)&0x3)*2);
471                                         a2_address = a2.base + ((a2_y * a2.width + (a2_x&0xFFFFFFFC))*2*(a2_size/8)) + ((a2_x&0x3)*2);
472                                         src1 = jaguar_word_read(*src);
473                                         dst1 = jaguar_word_read(*dst);
474                                         dst_old = dst1;
475                                         if(bcmd.srcenz)
476                                                 srcz = jaguar_word_read(*src+src_zoffset);
477                                         else
478                                                 srcz = compz[pi & 0x3] >> 16;
479                                         if(bcmd.dstenz)
480                                                 dstz = jaguar_word_read(*dst+dst_zoffset);
481
482                                         //jaguar_long_read(*src+4,&src2);
483                                         if(bcmd.patdsel) {
484 //                                              dst1 = *(WORD*)(&MEM[0xF02268]);
485                                                 dst1 = jaguar_word_read(0xF02268);
486                                         } else {
487                                                 //jaguar_long_read(*dst+4,&dst2);
488                                                 switch(bcmd.logic)
489                                                 {
490                                                 case 0:dst1 = 0;dst2 = 0;break;                         
491                                                 case 1:dst1 = !src1 & !dst1; dst2 = !src2 & !dst2;break;
492                                                 case 2:dst1 = !src1 &  dst1; dst2 = !src2 & dst2;break;                         
493                                                 case 3:dst1 = !src1; dst2 = !src2;break;
494                                                 case 4:dst1 = src1 & !dst1; dst2 = src2 & !dst2;break;
495                                                 case 5:dst1 = !dst1; dst2 = !dst2;break;
496                                                 case 6:dst1 = (src1 ^ dst1); dst2 = !(src2 ^ dst2);break;
497                                                 case 7:dst1 = !src1 | !dst1; dst2 = !src2 | !dst2;break;
498                                                 case 8:dst1 = src1 & dst1; dst2 = src2 & dst2;break;
499                                                 case 9:dst1 = src1 ^ dst1; dst2 = src2 ^ dst2;break;
500                                                 case 10:dst1 = dst1; dst2 = dst2;break;
501                                                 case 11:dst1 = !src1 | dst1; dst2 = !src2 | dst2;break;
502                                                 case 12:dst1 = src1; dst2 = src2;break;
503                                                 case 13:dst1 = src1 | !dst1; dst2 = src2 | !dst2;break;
504                                                 case 14:dst1 = src1 | dst1; dst2 = src2 | dst2;break;
505                                                 case 15:dst1 = 0xFFFFFFFF; dst2 = 0xFFFFFFFF;break;
506                                                 }
507                                         } 
508                                         if(bcmd.gourd) {
509                                                 DWORD gdt = (gd_i[pi & 0x3] & 0xFFFFFF) | ((gd_c[pi & 0x3]>>4) << 24);
510                                                 dst1 = gdt >> 16;
511                                         }
512                                         if(bcmd.srcshade) {
513                                                 int intensity = src1 & 0xFF;
514                                                 int ia = gd_ia >> 16;
515                                                 if(ia & 0x80)
516                                                         ia = 0xFFFFFF00 | ia;
517                                                 intensity += ia;
518                                                 if(intensity < 0)
519                                                         intensity = 0;
520                                                 if(intensity > 0xFF)
521                                                         intensity = 0xFF;
522                                                 dst1 = (src1 & 0xFF00) | intensity;
523                                         }
524                                         if(bcmd.dcompen) {
525                                                 WORD pattern;
526                                                 pattern = jaguar_word_read(0xF02268);
527                                                 if(!bcmd.cmpdst) {
528                                                         if(src1 == pattern)//dst_old)
529                                                                 dst1 = dst_old;
530                                                 } else {
531                                                         if(dst1 == pattern)
532                                                                 dst1 = dst_old;
533                                                 }
534                                         }
535                                         if(bcmd.zmode > 0) {
536                                                 bool zc = false;
537                                                 switch(bcmd.zmode) {
538                                                         case 1: zc = (srcz < dstz);break;
539                                                         case 2: zc = (srcz == dstz);break;
540                                                         case 3: zc = (srcz <= dstz);break;
541                                                         case 4: zc = (srcz > dstz);break;
542                                                         case 5: zc = (srcz != dstz);break;
543                                                         case 6: zc = (srcz >= dstz);break;
544                                                 }
545                                                 if(zc == false) {
546                                                         if(bcmd.clip_a1) {
547                                                                 if((a1_x>>16) < a1.clip_x && (a1_x>>16) >= 0 && (a1_y>>16) < a1.clip_y && (a1_y>>16) >= 0) {
548                                                                         jaguar_word_write(*dst,dst1);
549                                                                         //jaguar_long_write(*dst+4,dst2);
550                                                                 }
551                                                         } else {
552                                                                 jaguar_word_write(*dst,dst1);
553                                                                 //jaguar_long_write(*dst+4,dst2);
554                                                         }
555                                                 } else {
556                                                         srcz = dstz;
557                                                 }
558                                         } else {
559                                                 if(bcmd.clip_a1) {
560                                                         if((a1_x>>16) < a1.clip_x && (a1_x>>16) >= 0 && (a1_y>>16) < a1.clip_y && (a1_y>>16) >= 0) {
561                                                                 jaguar_word_write(*dst,dst1);
562                                                                 //jaguar_long_write(*dst+4,dst2);
563                                                         }
564                                                 } else {
565                                                         jaguar_word_write(*dst,dst1);
566                                                         //jaguar_long_write(*dst+4,dst2);
567                                                 }
568                                         }
569                                         if(bcmd.dstwrz) {
570                                                 jaguar_word_write(*dst+dst_zoffset,srcz & 0xFFFF);
571                                         }
572                                         a1_x += a1_inc_x;
573                                         a2_x += a2_inc_x;
574                                         a1_y += a1_inc_y;
575                                         a2_y += a2.yadd;
576                                         gd_i[pi & 0x3] += gd_ia;
577                                         gd_c[pi & 0x3] += gd_ca;
578                                         if(gd_i[pi & 0x3] > 0xFFFFFF)
579                                                 gd_i[pi & 0x3] = 0xFFFFFF;
580                                         if(gd_i[pi & 0x3] < 0)
581                                                 gd_i[pi & 0x3] = 0;
582                                         compz[pi & 0x3] += zinc;
583                                         if(compz[pi & 0x3] > 0xFFFFFFFF)
584                                                 compz[pi & 0x3] = 0xFFFFFFFF;
585                                         if(compz[pi & 0x3] < 0)
586                                                 compz[pi & 0x3] = 0;
587                                         if(a1.pixelmode == 0) {
588                                                 pi++;
589                                         }
590                                 }
591                                 if(bcmd.upda1) {
592                                         a1_x += a1.step_x;
593                                         a1_y += a1.step_y;
594                                 }
595                                 if(bcmd.upda1f) {
596                                         a1_x += a1.fstep_x;
597                                         a1_y += a1.fstep_y;
598                                 }
599                                 if(bcmd.upda2) {
600                                         a2_x += a2.step_x;
601                                         a2_y += a2.step_y;
602                                 }
603                         }
604                         break;
605                         }
606                 case 5:
607                         for(DWORD j=0; j<outer_loop; j++) {
608                                 for(DWORD i=0; i<(inner_loop*bitdepth[a1.depth])/8; i+=bitsize[a1.depth]) {
609                                         DWORD src1,src2=0;
610                                         DWORD dst1,dst2;
611                                         a1_address = a1.base + ((((a1_y>>16) * a1.width + (a1_x>>16))*bitdepth[a1.depth])/8);
612                                         a2_address = a2.base + (((a2_y * a2.width + a2_x)*bitdepth[a1.depth])/8);
613                                         src1 = jaguar_long_read(*src);
614                                         //jaguar_long_read(*src+4,&src2);
615                                         if(!bcmd.patdsel) {
616                                                 dst1 = jaguar_long_read(*read);
617                                                 //jaguar_long_read(*dst+4,&dst2);
618                                                 switch(bcmd.logic)
619                                                 {
620                                                 case 0:dst1 = 0;dst2 = 0;break;                         
621                                                 case 1:dst1 = !src1 & !dst1; dst2 = !src2 & !dst2;break;
622                                                 case 2:dst1 = !src1 &  dst1; dst2 = !src2 & dst2;break;                         
623                                                 case 3:dst1 = !src1; dst2 = !src2;break;
624                                                 case 4:dst1 = src1 & !dst1; dst2 = src2 & !dst2;break;
625                                                 case 5:dst1 = !dst1; dst2 = !dst2;break;
626                                                 case 6:dst1 = !(src1 ^ dst1); dst2 = !(src2 ^ dst2);break;
627                                                 case 7:dst1 = !src1 | !dst1; dst2 = !src2 | !dst2;break;
628                                                 case 8:dst1 = src1 & dst1; dst2 = src2 & dst2;break;
629                                                 case 9:dst1 = src1 ^ dst1; dst2 = src2 ^ dst2;break;
630                                                 case 10:dst1 = dst1; dst2 = dst2;break;
631                                                 case 11:dst1 = !src1 | dst1; dst2 = !src2 | dst2;break;
632                                                 case 12:dst1 = src1; dst2 = src2;break;
633                                                 case 13:dst1 = src1 | !dst1; dst2 = src2 | !dst2;break;
634                                                 case 14:dst1 = src1 | dst1; dst2 = src2 | dst2;break;
635                                                 case 15:dst1 = 0xFFFFFFFF; dst2 = 0xFFFFFFFF;break;
636                                                 }
637                                         } else {
638                                                 dst1 = src1;
639                                                 dst2 = src2;
640                                         }
641                                         if(bcmd.clip_a1) {
642                                                 if((a1_x>>16) < a1.clip_x && (a1_x>>16) >= 0 && (a1_y>>16) < a1.clip_y && (a1_y>>16) >= 0) {
643                                                         jaguar_long_write(*dst,dst1);
644                                                         //jaguar_long_write(*dst+4,dst2);
645                                                 }
646                                         } else {
647                                                 jaguar_long_write(*dst,dst1);
648                                                 //jaguar_long_write(*dst+4,dst2);
649                                         }
650                                         a1_x += a1_inc_x;
651                                         a2_x += a2_inc_x;
652                                         a1_y += a1_inc_y;
653                                         a2_y += a2.yadd;
654                                         for(int v=0;v<4;v++) {
655                                                 gd_i[v] += gd_ia;
656                                                 gd_c[v] += gd_ca;
657                                         }
658                                 }
659                                 if(bcmd.upda1) {
660                                         a1_x += a1.step_x;
661                                         a1_y += a1.step_y;
662                                 }
663                                 if(bcmd.upda1f) {
664                                         a1_x += a1.fstep_x;
665                                         a1_y += a1.fstep_y;
666                                 }
667                                 if(bcmd.upda2) {
668                                         a2_x += a2.step_x;
669                                         a2_y += a2.step_y;
670                                 }
671                         }
672                         break;
673                 default:
674                         break;
675         }
676 /*      A1_PIXEL_X = a1_x >> 16;
677         A1_PIXEL_Y = a1_y >> 16;
678         A1_FPIXEL_X = a1_x & 0xFFFF;
679         A1_FPIXEL_Y = a1_y & 0xFFFF;
680         A2_PIXEL_X = a2_x;
681         A2_PIXEL_Y = a2_y;*/
682         jaguar_word_write(0xF0220E, a1_x >> 16);        // A1_PIXEL_X = 
683         jaguar_word_write(0xF0220C, a1_y >> 16);        // A1_PIXEL_Y = 
684         jaguar_word_write(0xF0221A, a1_x & 0xFFFF);     // A1_FPIXEL_X = 
685         jaguar_word_write(0xF02218, a1_y & 0xFFFF);     // A1_FPIXEL_Y = 
686         jaguar_word_write(0xF02232, a2_x);                      // A2_PIXEL_X = 
687         jaguar_word_write(0xF02230, a2_y);                      // A2_PIXEL_Y = 
688 }
689 /*
690 #define A1_PIXEL_Y              jaguar_word_read(0xF0220C)
691 #define A1_PIXEL_X              jaguar_word_read(0xF0220E)
692 #define A1_FPIXEL_Y             jaguar_word_read(0xF02218)
693 #define A1_FPIXEL_X             jaguar_word_read(0xF0221A)
694 #define A2_PIXEL_Y              jaguar_word_read(0xF02230)
695 #define A2_PIXEL_X              jaguar_word_read(0xF02232)
696 */