]> Shamusworld >> Repos - virtualjaguar/blob - src/blitter.cpp
Extensive changes to remove gcc 4.x warnings, general code cleanup
[virtualjaguar] / src / blitter.cpp
1 //
2 // Blitter core
3 //
4 // by James L. Hammons
5 //
6 // I owe a debt of gratitude to Curt Vendel and to John Mathieson--to Curt
7 // for supplying the Oberon ASIC nets and to John for making them available
8 // to Curt. ;-) Without that excellent documentation which shows *exactly*
9 // what's going on inside the TOM chip, we'd all still be guessing as to how
10 // the wily blitter and other pieces of the Jaguar puzzle actually work.
11 // Now how about those JERRY ASIC nets gentlemen...? ;-)
12 //
13
14 #include "blitter.h"
15
16 #include <stdlib.h>
17 #include <stdio.h>
18 #include <string.h>
19 #include "jaguar.h"
20 #include "log.h"
21
22 // Various conditional compilation goodies...
23
24 //#define USE_ORIGINAL_BLITTER
25 //#define USE_MIDSUMMER_BLITTER
26 #define USE_MIDSUMMER_BLITTER_MKII
27
28 // External global variables
29
30 extern int jaguar_active_memory_dumps;
31
32 // Local global variables
33
34 int start_logging = 0;
35 uint8 blitter_working = 0;
36
37 // Blitter register RAM (most of it is hidden from the user)
38
39 static uint8 blitter_ram[0x100];
40
41 // Other crapola
42
43 bool specialLog = false;
44 extern int effect_start;
45 extern int blit_start_log;
46 void BlitterMidsummer(uint32 cmd);
47 void BlitterMidsummer2(void);
48
49 #define REG(A)  (((uint32)blitter_ram[(A)] << 24) | ((uint32)blitter_ram[(A)+1] << 16) \
50                                 | ((uint32)blitter_ram[(A)+2] << 8) | (uint32)blitter_ram[(A)+3])
51 #define WREG(A,D)       (blitter_ram[(A)] = ((D)>>24)&0xFF, blitter_ram[(A)+1] = ((D)>>16)&0xFF, \
52                                         blitter_ram[(A)+2] = ((D)>>8)&0xFF, blitter_ram[(A)+3] = (D)&0xFF)
53
54 // Blitter registers (offsets from F02200)
55
56 #define A1_BASE                 ((uint32)0x00)
57 #define A1_FLAGS                ((uint32)0x04)
58 #define A1_CLIP                 ((uint32)0x08)  // Height and width values for clipping
59 #define A1_PIXEL                ((uint32)0x0C)  // Integer part of the pixel (Y.i and X.i)
60 #define A1_STEP                 ((uint32)0x10)  // Integer part of the step
61 #define A1_FSTEP                ((uint32)0x14)  // Fractional part of the step
62 #define A1_FPIXEL               ((uint32)0x18)  // Fractional part of the pixel (Y.f and X.f)
63 #define A1_INC                  ((uint32)0x1C)  // Integer part of the increment
64 #define A1_FINC                 ((uint32)0x20)  // Fractional part of the increment
65 #define A2_BASE                 ((uint32)0x24)
66 #define A2_FLAGS                ((uint32)0x28)
67 #define A2_MASK                 ((uint32)0x2C)  // Modulo values for x and y (M.y  and M.x)
68 #define A2_PIXEL                ((uint32)0x30)  // Integer part of the pixel (no fractional part for A2)
69 #define A2_STEP                 ((uint32)0x34)  // Integer part of the step (no fractional part for A2)
70 #define COMMAND                 ((uint32)0x38)
71 #define PIXLINECOUNTER  ((uint32)0x3C)  // Inner & outer loop values
72 #define SRCDATA                 ((uint32)0x40)
73 #define DSTDATA                 ((uint32)0x48)
74 #define DSTZ                    ((uint32)0x50)
75 #define SRCZINT                 ((uint32)0x58)
76 #define SRCZFRAC                ((uint32)0x60)
77 #define PATTERNDATA             ((uint32)0x68)
78 #define INTENSITYINC    ((uint32)0x70)
79 #define ZINC                    ((uint32)0x74)
80 #define COLLISIONCTRL   ((uint32)0x78)
81 #define PHRASEINT0              ((uint32)0x7C)
82 #define PHRASEINT1              ((uint32)0x80)
83 #define PHRASEINT2              ((uint32)0x84)
84 #define PHRASEINT3              ((uint32)0x88)
85 #define PHRASEZ0                ((uint32)0x8C)
86 #define PHRASEZ1                ((uint32)0x90)
87 #define PHRASEZ2                ((uint32)0x94)
88 #define PHRASEZ3                ((uint32)0x98)
89
90 // Blitter command bits
91
92 #define SRCEN                   (cmd & 0x00000001)
93 #define SRCENZ                  (cmd & 0x00000002)
94 #define SRCENX                  (cmd & 0x00000004)
95 #define DSTEN                   (cmd & 0x00000008)
96 #define DSTENZ                  (cmd & 0x00000010)
97 #define DSTWRZ                  (cmd & 0x00000020)
98 #define CLIPA1                  (cmd & 0x00000040)
99
100 #define UPDA1F                  (cmd & 0x00000100)
101 #define UPDA1                   (cmd & 0x00000200)
102 #define UPDA2                   (cmd & 0x00000400)
103
104 #define DSTA2                   (cmd & 0x00000800)
105
106 #define Z_OP_INF                (cmd & 0x00040000)
107 #define Z_OP_EQU                (cmd & 0x00080000)
108 #define Z_OP_SUP                (cmd & 0x00100000)
109
110 #define LFU_NAN                 (cmd & 0x00200000)
111 #define LFU_NA                  (cmd & 0x00400000)
112 #define LFU_AN                  (cmd & 0x00800000)
113 #define LFU_A                   (cmd & 0x01000000)
114
115 #define CMPDST                  (cmd & 0x02000000)
116 #define BCOMPEN                 (cmd & 0x04000000)
117 #define DCOMPEN                 (cmd & 0x08000000)
118
119 #define PATDSEL                 (cmd & 0x00010000)
120 #define ADDDSEL                 (cmd & 0x00020000)
121 #define TOPBEN                  (cmd & 0x00004000)
122 #define TOPNEN                  (cmd & 0x00008000)
123 #define BKGWREN                 (cmd & 0x10000000)
124 #define GOURD                   (cmd & 0x00001000)
125 #define GOURZ                   (cmd & 0x00002000)
126 #define SRCSHADE                (cmd & 0x40000000)
127
128
129 #define XADDPHR  0
130 #define XADDPIX  1
131 #define XADD0    2
132 #define XADDINC  3
133
134 #define XSIGNSUB_A1             (REG(A1_FLAGS)&0x080000)
135 #define XSIGNSUB_A2             (REG(A2_FLAGS)&0x080000)
136
137 #define YSIGNSUB_A1             (REG(A1_FLAGS)&0x100000)
138 #define YSIGNSUB_A2             (REG(A2_FLAGS)&0x100000)
139
140 #define YADD1_A1                (REG(A1_FLAGS)&0x040000)
141 #define YADD1_A2                (REG(A2_FLAGS)&0x040000)
142
143 /*******************************************************************************
144 ********************** STUFF CUT BELOW THIS LINE! ******************************
145 *******************************************************************************/
146 #ifdef USE_ORIGINAL_BLITTER                                                                             // We're ditching this crap for now...
147
148 //Put 'em back, once we fix the problem!!! [KO]
149 // 1 bpp pixel read
150 #define PIXEL_SHIFT_1(a)      (((~a##_x) >> 16) & 7)
151 #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))
152 #define READ_PIXEL_1(a)       ((JaguarReadByte(a##_addr+PIXEL_OFFSET_1(a), BLITTER) >> PIXEL_SHIFT_1(a)) & 0x01)
153 //#define READ_PIXEL_1(a)       ((JaguarReadByte(a##_addr+PIXEL_OFFSET_1(a)) >> PIXEL_SHIFT_1(a)) & 0x01)
154
155 // 2 bpp pixel read
156 #define PIXEL_SHIFT_2(a)      (((~a##_x) >> 15) & 6)
157 #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))
158 #define READ_PIXEL_2(a)       ((JaguarReadByte(a##_addr+PIXEL_OFFSET_2(a), BLITTER) >> PIXEL_SHIFT_2(a)) & 0x03)
159 //#define READ_PIXEL_2(a)       ((JaguarReadByte(a##_addr+PIXEL_OFFSET_2(a)) >> PIXEL_SHIFT_2(a)) & 0x03)
160
161 // 4 bpp pixel read
162 #define PIXEL_SHIFT_4(a)      (((~a##_x) >> 14) & 4)
163 #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))
164 #define READ_PIXEL_4(a)       ((JaguarReadByte(a##_addr+PIXEL_OFFSET_4(a), BLITTER) >> PIXEL_SHIFT_4(a)) & 0x0f)
165 //#define READ_PIXEL_4(a)       ((JaguarReadByte(a##_addr+PIXEL_OFFSET_4(a)) >> PIXEL_SHIFT_4(a)) & 0x0f)
166
167 // 8 bpp pixel read
168 #define PIXEL_OFFSET_8(a)     (((((uint32)a##_y >> 16) * a##_width) + (((uint32)a##_x >> 16) & ~7)) * (1 + a##_pitch) + (((uint32)a##_x >> 16) & 7))
169 #define READ_PIXEL_8(a)       (JaguarReadByte(a##_addr+PIXEL_OFFSET_8(a), BLITTER))
170 //#define READ_PIXEL_8(a)       (JaguarReadByte(a##_addr+PIXEL_OFFSET_8(a)))
171
172 // 16 bpp pixel read
173 #define PIXEL_OFFSET_16(a)    (((((uint32)a##_y >> 16) * a##_width) + (((uint32)a##_x >> 16) & ~3)) * (1 + a##_pitch) + (((uint32)a##_x >> 16) & 3))
174 #define READ_PIXEL_16(a)       (JaguarReadWord(a##_addr+(PIXEL_OFFSET_16(a)<<1), BLITTER))
175 //#define READ_PIXEL_16(a)       (JaguarReadWord(a##_addr+(PIXEL_OFFSET_16(a)<<1)))
176
177 // 32 bpp pixel read
178 #define PIXEL_OFFSET_32(a)    (((((uint32)a##_y >> 16) * a##_width) + (((uint32)a##_x >> 16) & ~1)) * (1 + a##_pitch) + (((uint32)a##_x >> 16) & 1))
179 #define READ_PIXEL_32(a)      (JaguarReadLong(a##_addr+(PIXEL_OFFSET_32(a)<<2), BLITTER))
180 //#define READ_PIXEL_32(a)      (JaguarReadLong(a##_addr+(PIXEL_OFFSET_32(a)<<2)))
181
182 // pixel read
183 #define READ_PIXEL(a,f) (\
184          (((f>>3)&0x07) == 0) ? (READ_PIXEL_1(a)) : \
185          (((f>>3)&0x07) == 1) ? (READ_PIXEL_2(a)) : \
186          (((f>>3)&0x07) == 2) ? (READ_PIXEL_4(a)) : \
187          (((f>>3)&0x07) == 3) ? (READ_PIXEL_8(a)) : \
188          (((f>>3)&0x07) == 4) ? (READ_PIXEL_16(a)) : \
189          (((f>>3)&0x07) == 5) ? (READ_PIXEL_32(a)) : 0)
190
191 // 16 bpp z data read
192 #define ZDATA_OFFSET_16(a)     (PIXEL_OFFSET_16(a) + a##_zoffs * 4)
193 #define READ_ZDATA_16(a)       (JaguarReadWord(a##_addr+(ZDATA_OFFSET_16(a)<<1), BLITTER))
194 //#define READ_ZDATA_16(a)       (JaguarReadWord(a##_addr+(ZDATA_OFFSET_16(a)<<1)))
195
196 // z data read
197 #define READ_ZDATA(a,f) (READ_ZDATA_16(a))
198
199 // 16 bpp z data write
200 #define WRITE_ZDATA_16(a,d)     {  JaguarWriteWord(a##_addr+(ZDATA_OFFSET_16(a)<<1), d, BLITTER); }
201 //#define WRITE_ZDATA_16(a,d)     {  JaguarWriteWord(a##_addr+(ZDATA_OFFSET_16(a)<<1), d); }
202
203 // z data write
204 #define WRITE_ZDATA(a,f,d) WRITE_ZDATA_16(a,d); 
205
206 // 1 bpp r data read
207 #define READ_RDATA_1(r,a,p)  ((p) ?  ((REG(r+(((uint32)a##_x >> 19) & 0x04))) >> (((uint32)a##_x >> 16) & 0x1F)) & 0x0001 : (REG(r) & 0x0001))
208
209 // 2 bpp r data read
210 #define READ_RDATA_2(r,a,p)  ((p) ?  ((REG(r+(((uint32)a##_x >> 18) & 0x04))) >> (((uint32)a##_x >> 15) & 0x3E)) & 0x0003 : (REG(r) & 0x0003))
211
212 // 4 bpp r data read
213 #define READ_RDATA_4(r,a,p)  ((p) ?  ((REG(r+(((uint32)a##_x >> 17) & 0x04))) >> (((uint32)a##_x >> 14) & 0x28)) & 0x000F : (REG(r) & 0x000F))
214
215 // 8 bpp r data read
216 #define READ_RDATA_8(r,a,p)  ((p) ?  ((REG(r+(((uint32)a##_x >> 16) & 0x04))) >> (((uint32)a##_x >> 13) & 0x18)) & 0x00FF : (REG(r) & 0x00FF))
217
218 // 16 bpp r data read
219 #define READ_RDATA_16(r,a,p)  ((p) ? ((REG(r+(((uint32)a##_x >> 15) & 0x04))) >> (((uint32)a##_x >> 12) & 0x10)) & 0xFFFF : (REG(r) & 0xFFFF))
220
221 // 32 bpp r data read
222 #define READ_RDATA_32(r,a,p)  ((p) ? REG(r+(((uint32)a##_x >> 14) & 0x04)) : REG(r))
223
224 // register data read
225 #define READ_RDATA(r,a,f,p) (\
226          (((f>>3)&0x07) == 0) ? (READ_RDATA_1(r,a,p)) : \
227          (((f>>3)&0x07) == 1) ? (READ_RDATA_2(r,a,p)) : \
228          (((f>>3)&0x07) == 2) ? (READ_RDATA_4(r,a,p)) : \
229          (((f>>3)&0x07) == 3) ? (READ_RDATA_8(r,a,p)) : \
230          (((f>>3)&0x07) == 4) ? (READ_RDATA_16(r,a,p)) : \
231          (((f>>3)&0x07) == 5) ? (READ_RDATA_32(r,a,p)) : 0)
232
233 // 1 bpp pixel write
234 #define WRITE_PIXEL_1(a,d)       { JaguarWriteByte(a##_addr+PIXEL_OFFSET_1(a), (JaguarReadByte(a##_addr+PIXEL_OFFSET_1(a), BLITTER)&(~(0x01 << PIXEL_SHIFT_1(a))))|(d<<PIXEL_SHIFT_1(a)), BLITTER); }
235 //#define WRITE_PIXEL_1(a,d)       { JaguarWriteByte(a##_addr+PIXEL_OFFSET_1(a), (JaguarReadByte(a##_addr+PIXEL_OFFSET_1(a))&(~(0x01 << PIXEL_SHIFT_1(a))))|(d<<PIXEL_SHIFT_1(a))); }
236
237 // 2 bpp pixel write
238 #define WRITE_PIXEL_2(a,d)       { JaguarWriteByte(a##_addr+PIXEL_OFFSET_2(a), (JaguarReadByte(a##_addr+PIXEL_OFFSET_2(a), BLITTER)&(~(0x03 << PIXEL_SHIFT_2(a))))|(d<<PIXEL_SHIFT_2(a)), BLITTER); }
239 //#define WRITE_PIXEL_2(a,d)       { JaguarWriteByte(a##_addr+PIXEL_OFFSET_2(a), (JaguarReadByte(a##_addr+PIXEL_OFFSET_2(a))&(~(0x03 << PIXEL_SHIFT_2(a))))|(d<<PIXEL_SHIFT_2(a))); }
240
241 // 4 bpp pixel write
242 #define WRITE_PIXEL_4(a,d)       { JaguarWriteByte(a##_addr+PIXEL_OFFSET_4(a), (JaguarReadByte(a##_addr+PIXEL_OFFSET_4(a), BLITTER)&(~(0x0f << PIXEL_SHIFT_4(a))))|(d<<PIXEL_SHIFT_4(a)), BLITTER); }
243 //#define WRITE_PIXEL_4(a,d)       { JaguarWriteByte(a##_addr+PIXEL_OFFSET_4(a), (JaguarReadByte(a##_addr+PIXEL_OFFSET_4(a))&(~(0x0f << PIXEL_SHIFT_4(a))))|(d<<PIXEL_SHIFT_4(a))); }
244
245 // 8 bpp pixel write
246 #define WRITE_PIXEL_8(a,d)       { JaguarWriteByte(a##_addr+PIXEL_OFFSET_8(a), d, BLITTER); }
247 //#define WRITE_PIXEL_8(a,d)       { JaguarWriteByte(a##_addr+PIXEL_OFFSET_8(a), d); }
248
249 // 16 bpp pixel write
250 //#define WRITE_PIXEL_16(a,d)     {  JaguarWriteWord(a##_addr+(PIXEL_OFFSET_16(a)<<1),d); }
251 #define WRITE_PIXEL_16(a,d)     {  JaguarWriteWord(a##_addr+(PIXEL_OFFSET_16(a)<<1), d, BLITTER); if (specialLog) WriteLog("Pixel write address: %08X\n", a##_addr+(PIXEL_OFFSET_16(a)<<1)); }
252 //#define WRITE_PIXEL_16(a,d)     {  JaguarWriteWord(a##_addr+(PIXEL_OFFSET_16(a)<<1), d); if (specialLog) WriteLog("Pixel write address: %08X\n", a##_addr+(PIXEL_OFFSET_16(a)<<1)); }
253
254 // 32 bpp pixel write
255 #define WRITE_PIXEL_32(a,d)             { JaguarWriteLong(a##_addr+(PIXEL_OFFSET_32(a)<<2), d, BLITTER); } 
256 //#define WRITE_PIXEL_32(a,d)           { JaguarWriteLong(a##_addr+(PIXEL_OFFSET_32(a)<<2), d); } 
257
258 // pixel write
259 #define WRITE_PIXEL(a,f,d) {\
260         switch ((f>>3)&0x07) { \
261         case 0: WRITE_PIXEL_1(a,d);  break;  \
262         case 1: WRITE_PIXEL_2(a,d);  break;  \
263         case 2: WRITE_PIXEL_4(a,d);  break;  \
264         case 3: WRITE_PIXEL_8(a,d);  break;  \
265         case 4: WRITE_PIXEL_16(a,d); break;  \
266         case 5: WRITE_PIXEL_32(a,d); break;  \
267         }}
268
269 // Width in Pixels of a Scanline
270 // This is a pretranslation of the value found in the A1 & A2 flags: It's really a floating point value
271 // of the form EEEEMM where MM is the mantissa with an implied "1." in front of it and the EEEE value is
272 // the exponent. Valid values for the exponent range from 0 to 11 (decimal). It's easiest to think of it
273 // as a floating point bit pattern being followed by a number of zeroes. So, e.g., 001101 translates to
274 // 1.01 (the "1." being implied) x (2 ^ 3) or 1010 -> 10 in base 10 (i.e., 1.01 with the decimal place
275 // being shifted to the right 3 places).
276 /*static uint32 blitter_scanline_width[48] = 
277 {             
278      0,    0,    0,    0,                                       // Note: This would really translate to 1, 1, 1, 1
279      2,    0,    0,    0,
280      4,    0,    6,    0,
281      8,   10,   12,   14,
282     16,   20,   24,   28,
283     32,   40,   48,   56,
284     64,   80,   96,  112,
285    128,  160,  192,  224,
286    256,  320,  384,  448,
287    512,  640,  768,  896,
288   1024, 1280, 1536, 1792,
289   2048, 2560, 3072, 3584
290 };//*/
291
292 //static uint8 * tom_ram_8;
293 //static uint8 * paletteRam;
294 static uint8 src;
295 static uint8 dst;
296 static uint8 misc;
297 static uint8 a1ctl;
298 static uint8 mode;
299 static uint8 ity;
300 static uint8 zop;
301 static uint8 op;
302 static uint8 ctrl;
303 static uint32 a1_addr;
304 static uint32 a2_addr;
305 static int32 a1_zoffs;
306 static int32 a2_zoffs;
307 static uint32 xadd_a1_control;
308 static uint32 xadd_a2_control;
309 static int32 a1_pitch;
310 static int32 a2_pitch;
311 static uint32 n_pixels;
312 static uint32 n_lines;
313 static int32 a1_x;
314 static int32 a1_y;
315 static int32 a1_width;
316 static int32 a2_x;
317 static int32 a2_y;
318 static int32 a2_width;
319 static int32 a2_mask_x;
320 static int32 a2_mask_y;
321 static int32 a1_xadd;
322 static int32 a1_yadd;
323 static int32 a2_xadd;
324 static int32 a2_yadd;
325 static uint8 a1_phrase_mode;
326 static uint8 a2_phrase_mode;
327 static int32 a1_step_x = 0;
328 static int32 a1_step_y = 0;
329 static int32 a2_step_x = 0;
330 static int32 a2_step_y = 0;
331 static uint32 outer_loop;
332 static uint32 inner_loop;
333 static uint32 a2_psize;
334 static uint32 a1_psize;
335 static uint32 gouraud_add;
336 //static uint32 gouraud_data;
337 //static uint16 gint[4];
338 //static uint16 gfrac[4];
339 //static uint8  gcolour[4];
340 static int gd_i[4];
341 static int gd_c[4];
342 static int gd_ia, gd_ca;
343 static int colour_index = 0;
344 static int32 zadd;
345 static uint32 z_i[4];
346
347 static int32 a1_clip_x, a1_clip_y;
348
349 // In the spirit of "get it right first, *then* optimize" I've taken the liberty
350 // of removing all the unnecessary code caching. If it turns out to be a good way
351 // to optimize the blitter, then we may revisit it in the future...
352
353 //
354 // Generic blit handler
355 //
356 void blitter_generic(uint32 cmd)
357 {
358 /*
359 Blit! (0018FA70 <- 008DDC40) count: 2 x 13, A1/2_FLAGS: 00014218/00013C18 [cmd: 1401060C]
360  CMD -> src: SRCENX dst: DSTEN  misc:  a1ctl: UPDA1 UPDA2 mode:  ity: PATDSEL z-op:  op: LFU_CLEAR ctrl: BCOMPEN BKGWREN 
361   A1 step values: -2 (X), 1 (Y)
362   A2 step values: -1 (X), 1 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
363   A1 -> pitch: 1 phrases, depth: 8bpp, z-off: 0, width: 320 (21), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
364   A2 -> pitch: 1 phrases, depth: 8bpp, z-off: 0, width: 192 (1E), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
365         A1 x/y: 100/12, A2 x/y: 106/0 Pattern: 000000F300000000
366 */
367 //if (effect_start)
368 //      specialLog = true;
369 /*if (cmd == 0x1401060C && blit_start_log)
370         specialLog = true;//*/
371 //Testing only!
372 //uint32 logGo = ((cmd == 0x01800E01 && REG(A1_BASE) == 0x898000) ? 1 : 0);
373         uint32 srcdata, srczdata, dstdata, dstzdata, writedata, inhibit;
374         uint32 bppSrc = (DSTA2 ? 1 << ((REG(A1_FLAGS) >> 3) & 0x07) : 1 << ((REG(A2_FLAGS) >> 3) & 0x07));
375
376 if (specialLog)
377 {
378         WriteLog("About to do n x m blit (BM width is ? pixels)...\n");
379         WriteLog("A1_STEP_X/Y = %08X/%08X, A2_STEP_X/Y = %08X/%08X\n", a1_step_x, a1_step_y, a2_step_x, a2_step_y);
380 }
381 /*      if (BCOMPEN)
382         {
383                 if (DSTA2)
384                         a1_xadd = 0;
385                 else
386                         a2_xadd = 0;
387         }//*/
388
389         while (outer_loop--)
390         {
391 if (specialLog)
392 {
393         WriteLog("  A1_X/Y = %08X/%08X, A2_X/Y = %08X/%08X\n", a1_x, a1_y, a2_x, a2_y);
394 }
395                 uint32 a1_start = a1_x, a2_start = a2_x, bitPos = 0;
396
397                 //Kludge for Hover Strike...
398                 //I wonder if this kludge is in conjunction with the SRCENX down below...
399                 // This isn't so much a kludge but the way things work in BCOMPEN mode...!
400                 if (BCOMPEN && SRCENX)
401                 {
402                         if (n_pixels < bppSrc)
403                                 bitPos = bppSrc - n_pixels;
404                 }
405
406                 inner_loop = n_pixels;
407                 while (inner_loop--)
408                 {
409 if (specialLog)
410 {
411         WriteLog("    A1_X/Y = %08X/%08X, A2_X/Y = %08X/%08X\n", a1_x, a1_y, a2_x, a2_y);
412 }
413                         srcdata = srczdata = dstdata = dstzdata = writedata = inhibit = 0;
414
415                         if (!DSTA2)                                                     // Data movement: A1 <- A2
416                         {
417                                 // load src data and Z
418 //                              if (SRCEN)
419                                 if (SRCEN || SRCENX)    // Not sure if this is correct... (seems to be...!)
420                                 {
421                                         srcdata = READ_PIXEL(a2, REG(A2_FLAGS));
422
423                                         if (SRCENZ)
424                                                 srczdata = READ_ZDATA(a2, REG(A2_FLAGS));
425                                         else if (cmd & 0x0001C020)      // PATDSEL | TOPBEN | TOPNEN | DSTWRZ
426                                                 srczdata = READ_RDATA(SRCZINT, a2, REG(A2_FLAGS), a2_phrase_mode);
427                                 }
428                                 else    // Use SRCDATA register...
429                                 {
430                                         srcdata = READ_RDATA(SRCDATA, a2, REG(A2_FLAGS), a2_phrase_mode);
431
432                                         if (cmd & 0x0001C020)           // PATDSEL | TOPBEN | TOPNEN | DSTWRZ
433                                                 srczdata = READ_RDATA(SRCZINT, a2, REG(A2_FLAGS), a2_phrase_mode);
434                                 }
435
436                                 // load dst data and Z 
437                                 if (DSTEN)
438                                 {
439                                         dstdata = READ_PIXEL(a1, REG(A1_FLAGS));
440
441                                         if (DSTENZ)
442                                                 dstzdata = READ_ZDATA(a1, REG(A1_FLAGS));
443                                         else
444                                                 dstzdata = READ_RDATA(DSTZ, a1, REG(A1_FLAGS), a1_phrase_mode);
445                                 }
446                                 else
447                                 {
448                                         dstdata = READ_RDATA(DSTDATA, a1, REG(A1_FLAGS), a1_phrase_mode);
449
450                                         if (DSTENZ)
451                                                 dstzdata = READ_RDATA(DSTZ, a1, REG(A1_FLAGS), a1_phrase_mode);
452                                 }
453
454 /*This wasn't working...                                // a1 clipping
455                                 if (cmd & 0x00000040)
456                                 {
457                                         if (a1_x < 0 || a1_y < 0 || (a1_x >> 16) >= (REG(A1_CLIP) & 0x7FFF)
458                                                 || (a1_y >> 16) >= ((REG(A1_CLIP) >> 16) & 0x7FFF))
459                                                 inhibit = 1;
460                                 }//*/
461
462                                 if (GOURZ) 
463                                         srczdata = z_i[colour_index] >> 16;
464
465                                 // apply z comparator
466                                 if (Z_OP_INF && srczdata <  dstzdata)   inhibit = 1;
467                                 if (Z_OP_EQU && srczdata == dstzdata)   inhibit = 1;
468                                 if (Z_OP_SUP && srczdata >  dstzdata)   inhibit = 1;
469                                 
470                                 // apply data comparator
471 // Note: DCOMPEN only works in 8/16 bpp modes! !!! FIX !!!
472 // Does BCOMPEN only work in 1 bpp mode???
473 //   No, but it always does a 1 bit expansion no matter what the BPP of the channel is set to. !!! FIX !!!
474 //   This is bit tricky... We need to fix the XADD value so that it acts like a 1BPP value while inside
475 //   an 8BPP space.
476                                 if (DCOMPEN | BCOMPEN)
477                                 {
478 //Temp, for testing Hover Strike
479 //Doesn't seem to do it... Why?
480 //What needs to happen here is twofold. First, the address generator in the outer loop has
481 //to honor the BPP when calculating the start address (which it kinda does already). Second,
482 //it has to step bit by bit when using BCOMPEN. How to do this???
483         if (BCOMPEN)
484 //small problem with this approach: it's not accurate... We need a proper address to begin with
485 //and *then* we can do the bit stepping from there the way it's *supposed* to be done... !!! FIX !!!
486 //[DONE]
487         {
488                 uint32 pixShift = (~bitPos) & (bppSrc - 1);
489                 srcdata = (srcdata >> pixShift) & 0x01;
490
491                 bitPos++;
492 //              if (bitPos % bppSrc == 0)
493 //                      a2_x += 0x00010000;
494         }
495 /*
496 Interesting (Hover Strike--large letter):
497
498 Blit! (0018FA70 <- 008DDC40) count: 2 x 13, A1/2_FLAGS: 00014218/00013C18 [cmd: 1401060C]
499  CMD -> src: SRCENX dst: DSTEN  misc:  a1ctl: UPDA1 UPDA2 mode:  ity: PATDSEL z-op:  op: LFU_CLEAR ctrl: BCOMPEN BKGWREN 
500   A1 step values: -2 (X), 1 (Y)
501   A2 step values: -1 (X), 1 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
502   A1 -> pitch: 1 phrases, depth: 8bpp, z-off: 0, width: 320 (21), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
503   A2 -> pitch: 1 phrases, depth: 8bpp, z-off: 0, width: 192 (1E), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
504         A1 x/y: 100/12, A2 x/y: 106/0 Pattern: 000000F300000000
505
506 Blit! (0018FA70 <- 008DDC40) count: 8 x 13, A1/2_FLAGS: 00014218/00013C18 [cmd: 1401060C]
507  CMD -> src: SRCENX dst: DSTEN  misc:  a1ctl: UPDA1 UPDA2 mode:  ity: PATDSEL z-op:  op: LFU_CLEAR ctrl: BCOMPEN BKGWREN 
508   A1 step values: -8 (X), 1 (Y)
509   A2 step values: -1 (X), 1 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
510   A1 -> pitch: 1 phrases, depth: 8bpp, z-off: 0, width: 320 (21), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
511   A2 -> pitch: 1 phrases, depth: 8bpp, z-off: 0, width: 192 (1E), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
512         A1 x/y: 102/12, A2 x/y: 107/0 Pattern: 000000F300000000
513
514 Blit! (0018FA70 <- 008DDC40) count: 1 x 13, A1/2_FLAGS: 00014218/00013C18 [cmd: 1401060C]
515  CMD -> src: SRCENX dst: DSTEN  misc:  a1ctl: UPDA1 UPDA2 mode:  ity: PATDSEL z-op:  op: LFU_CLEAR ctrl: BCOMPEN BKGWREN 
516   A1 step values: -1 (X), 1 (Y)
517   A2 step values: -1 (X), 1 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
518   A1 -> pitch: 1 phrases, depth: 8bpp, z-off: 0, width: 320 (21), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
519   A2 -> pitch: 1 phrases, depth: 8bpp, z-off: 0, width: 192 (1E), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
520         A1 x/y: 118/12, A2 x/y: 70/0 Pattern: 000000F300000000
521
522 Blit! (0018FA70 <- 008DDC40) count: 8 x 13, A1/2_FLAGS: 00014218/00013C18 [cmd: 1401060C]
523  CMD -> src: SRCENX dst: DSTEN  misc:  a1ctl: UPDA1 UPDA2 mode:  ity: PATDSEL z-op:  op: LFU_CLEAR ctrl: BCOMPEN BKGWREN 
524   A1 step values: -8 (X), 1 (Y)
525   A2 step values: -1 (X), 1 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
526   A1 -> pitch: 1 phrases, depth: 8bpp, z-off: 0, width: 320 (21), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
527   A2 -> pitch: 1 phrases, depth: 8bpp, z-off: 0, width: 192 (1E), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
528         A1 x/y: 119/12, A2 x/y: 71/0 Pattern: 000000F300000000
529
530 Blit! (0018FA70 <- 008DDC40) count: 1 x 13, A1/2_FLAGS: 00014218/00013C18 [cmd: 1401060C]
531  CMD -> src: SRCENX dst: DSTEN  misc:  a1ctl: UPDA1 UPDA2 mode:  ity: PATDSEL z-op:  op: LFU_CLEAR ctrl: BCOMPEN BKGWREN 
532   A1 step values: -1 (X), 1 (Y)
533   A2 step values: -1 (X), 1 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
534   A1 -> pitch: 1 phrases, depth: 8bpp, z-off: 0, width: 320 (21), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
535   A2 -> pitch: 1 phrases, depth: 8bpp, z-off: 0, width: 192 (1E), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
536         A1 x/y: 127/12, A2 x/y: 66/0 Pattern: 000000F300000000
537
538 Blit! (0018FA70 <- 008DDC40) count: 8 x 13, A1/2_FLAGS: 00014218/00013C18 [cmd: 1401060C]
539  CMD -> src: SRCENX dst: DSTEN  misc:  a1ctl: UPDA1 UPDA2 mode:  ity: PATDSEL z-op:  op: LFU_CLEAR ctrl: BCOMPEN BKGWREN 
540   A1 step values: -8 (X), 1 (Y)
541   A2 step values: -1 (X), 1 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
542   A1 -> pitch: 1 phrases, depth: 8bpp, z-off: 0, width: 320 (21), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
543   A2 -> pitch: 1 phrases, depth: 8bpp, z-off: 0, width: 192 (1E), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
544         A1 x/y: 128/12, A2 x/y: 67/0 Pattern: 000000F300000000
545 */
546
547
548                                         if (!CMPDST)
549                                         {
550 //WriteLog("Blitter: BCOMPEN set on command %08X inhibit prev:%u, now:", cmd, inhibit);
551                                                 // compare source pixel with pattern pixel
552 /*
553 Blit! (000B8250 <- 0012C3A0) count: 16 x 1, A1/2_FLAGS: 00014420/00012000 [cmd: 05810001]
554  CMD -> src: SRCEN  dst:  misc:  a1ctl:  mode:  ity: PATDSEL z-op:  op: LFU_REPLACE ctrl: BCOMPEN 
555   A1 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 384 (22), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
556   A2 -> pitch: 1 phrases, depth: 1bpp, z-off: 0, width: 16 (10), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
557         x/y: 0/20
558 ...
559 */
560 // AvP is still wrong, could be cuz it's doing A1 -> A2...
561
562 // Src is the 1bpp bitmap... DST is the PATTERN!!!
563 // This seems to solve at least ONE of the problems with MC3D...
564 // Why should this be inverted???
565 // Bcuz it is. This is supposed to be used only for a bit -> pixel expansion...
566 /*                                              if (srcdata == READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode))
567 //                                              if (srcdata != READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode))
568                                                         inhibit = 1;//*/
569 /*                                              uint32 A2bpp = 1 << ((REG(A2_FLAGS) >> 3) & 0x07);
570                                                 if (A2bpp == 1 || A2bpp == 16 || A2bpp == 8)
571                                                         inhibit = (srcdata == 0 ? 1: 0);
572 //                                                      inhibit = !srcdata;
573                                                 else
574                                                         WriteLog("Blitter: Bad BPP (%u) selected for BCOMPEN mode!\n", A2bpp);//*/
575 // What it boils down to is this:
576
577                                                 if (srcdata == 0)
578                                                         inhibit = 1;//*/
579                                         }
580                                         else
581                                         {
582                                                 // compare destination pixel with pattern pixel
583                                                 if (dstdata == READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode))
584 //                                              if (dstdata != READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode))
585                                                         inhibit = 1;
586                                         }
587
588 // This is DEFINITELY WRONG
589 //                                      if (a1_phrase_mode || a2_phrase_mode)
590 //                                              inhibit = !inhibit;
591                                 }
592
593                                 if (CLIPA1)
594                                 {
595                                         inhibit |= (((a1_x >> 16) < a1_clip_x && (a1_x >> 16) >= 0
596                                                 && (a1_y >> 16) < a1_clip_y && (a1_y >> 16) >= 0) ? 0 : 1);
597                                 }
598
599                                 // compute the write data and store
600                                 if (!inhibit)
601                                 {                       
602 // Houston, we have a problem...
603 // Look here, at PATDSEL and GOURD. If both are active (as they are on the BIOS intro), then there's
604 // a conflict! E.g.:
605 //Blit! (00100000 <- 000095D0) count: 3 x 1, A1/2_FLAGS: 00014220/00004020 [cmd: 00011008]
606 // CMD -> src:  dst: DSTEN  misc:  a1ctl:  mode: GOURD  ity: PATDSEL z-op:  op: LFU_CLEAR ctrl: 
607 //  A1 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 320 (21), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
608 //  A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 256 (20), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
609 //        A1 x/y: 90/171, A2 x/y: 808/0 Pattern: 776D770077007700
610
611                                         if (PATDSEL)
612                                         {
613                                                 // use pattern data for write data
614                                                 writedata = READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode);
615                                         }
616                                         else if (ADDDSEL)
617                                         {
618 /*if (blit_start_log)
619         WriteLog("BLIT: ADDDSEL srcdata: %08X\, dstdata: %08X, ", srcdata, dstdata);//*/
620
621                                                 // intensity addition
622 //Ok, this is wrong... Or is it? Yes, it's wrong! !!! FIX !!!
623 /*                                              writedata = (srcdata & 0xFF) + (dstdata & 0xFF);
624                                                 if (!(TOPBEN) && writedata > 0xFF)
625 //                                                      writedata = 0xFF;
626                                                         writedata &= 0xFF;
627                                                 writedata |= (srcdata & 0xF00) + (dstdata & 0xF00);
628                                                 if (!(TOPNEN) && writedata > 0xFFF)
629 //                                                      writedata = 0xFFF;
630                                                         writedata &= 0xFFF;
631                                                 writedata |= (srcdata & 0xF000) + (dstdata & 0xF000);//*/
632 //notneeded--writedata &= 0xFFFF;
633 /*if (blit_start_log)
634         WriteLog("writedata: %08X\n", writedata);//*/
635 /*
636 Hover Strike ADDDSEL blit:
637
638 Blit! (00098D90 <- 0081DDC0) count: 320 x 287, A1/2_FLAGS: 00004220/00004020 [cmd: 00020208]
639  CMD -> src:  dst: DSTEN  misc:  a1ctl: UPDA1  mode:  ity: ADDDSEL z-op:  op: LFU_CLEAR ctrl: 
640   A1 step values: -320 (X), 1 (Y)
641   A1 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
642   A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 256 (20), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
643         A1 x/y: 0/0, A2 x/y: 3288/0 Pattern: 0000000000000000 SRCDATA: 00FD00FD00FD00FD
644 */
645                                                 writedata = (srcdata & 0xFF) + (dstdata & 0xFF);
646
647                                                 if (!TOPBEN)
648                                                 {
649 //This is correct now, but slow...
650                                                         int16 s = (srcdata & 0xFF) | (srcdata & 0x80 ? 0xFF00 : 0x0000),
651                                                                 d = dstdata & 0xFF;
652                                                         int16 sum = s + d;
653
654                                                         if (sum < 0)
655                                                                 writedata = 0x00;
656                                                         else if (sum > 0xFF)
657                                                                 writedata = 0xFF;
658                                                         else
659                                                                 writedata = (uint32)sum;
660                                                 }
661
662 //This doesn't seem right... Looks like it would muck up the low byte... !!! FIX !!!
663                                                 writedata |= (srcdata & 0xF00) + (dstdata & 0xF00);
664
665                                                 if (!TOPNEN && writedata > 0xFFF)
666                                                 {
667                                                         writedata &= 0xFFF;
668                                                 }
669
670                                                 writedata |= (srcdata & 0xF000) + (dstdata & 0xF000);
671                                         }
672                                         else
673                                         {
674                                                 if (LFU_NAN) writedata |= ~srcdata & ~dstdata;
675                                                 if (LFU_NA)  writedata |= ~srcdata & dstdata;
676                                                 if (LFU_AN)  writedata |= srcdata  & ~dstdata;
677                                                 if (LFU_A)       writedata |= srcdata  & dstdata;
678                                         }
679
680 //Although, this looks like it's OK... (even if it is shitty!)
681 //According to JTRM, this is part of the four things the blitter does with the write data (the other
682 //three being PATDSEL, ADDDSEL, and LFU (default). I'm not sure which gets precedence, this or PATDSEL
683 //(see above blit example)...
684                                         if (GOURD) 
685                                                 writedata = ((gd_c[colour_index]) << 8) | (gd_i[colour_index] >> 16);
686
687                                         if (SRCSHADE) 
688                                         {
689                                                 int intensity = srcdata & 0xFF;
690                                                 int ia = gd_ia >> 16;
691                                                 if (ia & 0x80)
692                                                         ia = 0xFFFFFF00 | ia;
693                                                 intensity += ia;
694                                                 if (intensity < 0)
695                                                         intensity = 0;
696                                                 if (intensity > 0xFF)
697                                                         intensity = 0xFF;
698                                                 writedata = (srcdata & 0xFF00) | intensity;
699                                         }
700                                 }
701                                 else
702                                 {
703                                         writedata = dstdata;
704                                         srczdata = dstzdata;
705                                 }
706
707 //Tried 2nd below for Hover Strike: No dice.
708                                 if (/*a1_phrase_mode || */BKGWREN || !inhibit)
709 //                              if (/*a1_phrase_mode || BKGWREN ||*/ !inhibit)
710                                 {
711 /*if (((REG(A1_FLAGS) >> 3) & 0x07) == 5)
712 {
713         uint32 offset = a1_addr+(PIXEL_OFFSET_32(a1)<<2);
714 // (((((uint32)a##_y >> 16) * a##_width) + (((uint32)a##_x >> 16) & ~1)) * (1 + a##_pitch) + (((uint32)a##_x >> 16) & 1))
715         if ((offset >= 0x1FF020 && offset <= 0x1FF03F) || (offset >= 0x1FF820 && offset <= 0x1FF83F))
716                 WriteLog("32bpp pixel write: A1 Phrase mode --> ");
717 }//*/
718                                         // write to the destination
719                                         WRITE_PIXEL(a1, REG(A1_FLAGS), writedata);
720                                         if (DSTWRZ)
721                                                 WRITE_ZDATA(a1, REG(A1_FLAGS), srczdata);
722                                 }
723                         }
724                         else    // if (DSTA2)                                                   // Data movement: A1 -> A2
725                         {
726                                 // load src data and Z
727                                 if (SRCEN)
728                                 {
729                                         srcdata = READ_PIXEL(a1, REG(A1_FLAGS));
730                                         if (SRCENZ)
731                                                 srczdata = READ_ZDATA(a1, REG(A1_FLAGS));
732                                         else if (cmd & 0x0001C020)      // PATDSEL | TOPBEN | TOPNEN | DSTWRZ
733                                                 srczdata = READ_RDATA(SRCZINT, a1, REG(A1_FLAGS), a1_phrase_mode);
734                                 }
735                                 else
736                                 {
737                                         srcdata = READ_RDATA(SRCDATA, a1, REG(A1_FLAGS), a1_phrase_mode);
738                                         if (cmd & 0x001C020)    // PATDSEL | TOPBEN | TOPNEN | DSTWRZ
739                                                 srczdata = READ_RDATA(SRCZINT, a1, REG(A1_FLAGS), a1_phrase_mode);
740                                 }
741
742                                 // load dst data and Z 
743                                 if (DSTEN)
744                                 {
745                                         dstdata = READ_PIXEL(a2, REG(A2_FLAGS));
746                                         if (DSTENZ)
747                                                 dstzdata = READ_ZDATA(a2, REG(A2_FLAGS));
748                                         else
749                                                 dstzdata = READ_RDATA(DSTZ, a2, REG(A2_FLAGS), a2_phrase_mode);
750                                 }
751                                 else
752                                 {
753                                         dstdata = READ_RDATA(DSTDATA, a2, REG(A2_FLAGS), a2_phrase_mode);
754                                         if (DSTENZ)
755                                                 dstzdata = READ_RDATA(DSTZ, a2, REG(A2_FLAGS), a2_phrase_mode);
756                                 }
757
758                                 if (GOURZ) 
759                                         srczdata = z_i[colour_index] >> 16;
760
761                                 // apply z comparator
762                                 if (Z_OP_INF && srczdata < dstzdata)    inhibit = 1;
763                                 if (Z_OP_EQU && srczdata == dstzdata)   inhibit = 1;
764                                 if (Z_OP_SUP && srczdata > dstzdata)    inhibit = 1;
765                                 
766                                 // apply data comparator
767 //NOTE: The bit comparator (BCOMPEN) is NOT the same at the data comparator!
768                                 if (DCOMPEN | BCOMPEN)
769                                 {
770                                         if (!CMPDST)
771                                         {
772                                                 // compare source pixel with pattern pixel
773 // AvP: Numbers are correct, but sprites are not!
774 //This doesn't seem to be a problem... But could still be wrong...
775 /*                                              if (srcdata == READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode))
776 //                                              if (srcdata != READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode))
777                                                         inhibit = 1;//*/
778 // This is probably not 100% correct... It works in the 1bpp case
779 // (in A1 <- A2 mode, that is...)
780 // AvP: This is causing blocks to be written instead of bit patterns...
781 // Works now...
782 // NOTE: We really should separate out the BCOMPEN & DCOMPEN stuff!
783 /*                                              uint32 A1bpp = 1 << ((REG(A1_FLAGS) >> 3) & 0x07);
784                                                 if (A1bpp == 1 || A1bpp == 16 || A1bpp == 8)
785                                                         inhibit = (srcdata == 0 ? 1: 0);
786                                                 else
787                                                         WriteLog("Blitter: Bad BPP (%u) selected for BCOMPEN mode!\n", A1bpp);//*/
788 // What it boils down to is this:
789                                                 if (srcdata == 0)
790                                                         inhibit = 1;//*/
791                                         }
792                                         else
793                                         {
794                                                 // compare destination pixel with pattern pixel
795                                                 if (dstdata == READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode))
796 //                                              if (dstdata != READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode))
797                                                         inhibit = 1;
798                                         }
799
800 // This is DEFINITELY WRONG
801 //                                      if (a1_phrase_mode || a2_phrase_mode)
802 //                                              inhibit = !inhibit;
803                                 }
804                                 
805                                 if (CLIPA1)
806                                 {
807                                         inhibit |= (((a1_x >> 16) < a1_clip_x && (a1_x >> 16) >= 0
808                                                 && (a1_y >> 16) < a1_clip_y && (a1_y >> 16) >= 0) ? 0 : 1);
809                                 }
810
811                                 // compute the write data and store
812                                 if (!inhibit)
813                                 {                       
814                                         if (PATDSEL)
815                                         {
816                                                 // use pattern data for write data
817                                                 writedata = READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode);
818                                         }
819                                         else if (ADDDSEL)
820                                         {
821                                                 // intensity addition
822                                                 writedata = (srcdata & 0xFF) + (dstdata & 0xFF);
823                                                 if (!(TOPBEN) && writedata > 0xFF)
824                                                         writedata = 0xFF;
825                                                 writedata |= (srcdata & 0xF00) + (dstdata & 0xF00);
826                                                 if (!(TOPNEN) && writedata > 0xFFF)
827                                                         writedata = 0xFFF;
828                                                 writedata |= (srcdata & 0xF000) + (dstdata & 0xF000);
829                                         }
830                                         else
831                                         {
832                                                 if (LFU_NAN)
833                                                         writedata |= ~srcdata & ~dstdata;
834                                                 if (LFU_NA)
835                                                         writedata |= ~srcdata & dstdata;
836                                                 if (LFU_AN)
837                                                         writedata |= srcdata & ~dstdata;
838                                                 if (LFU_A)
839                                                         writedata |= srcdata & dstdata;
840                                         }
841
842                                         if (GOURD) 
843                                                 writedata = ((gd_c[colour_index]) << 8) | (gd_i[colour_index] >> 16);
844
845                                         if (SRCSHADE) 
846                                         {
847                                                 int intensity = srcdata & 0xFF;
848                                                 int ia = gd_ia >> 16;
849                                                 if (ia & 0x80)
850                                                         ia = 0xFFFFFF00 | ia;
851                                                 intensity += ia;
852                                                 if (intensity < 0)
853                                                         intensity = 0;
854                                                 if (intensity > 0xFF)
855                                                         intensity = 0xFF;
856                                                 writedata = (srcdata & 0xFF00) | intensity;
857                                         }
858                                 }
859                                 else
860                                 {
861                                         writedata = dstdata;
862                                         srczdata = dstzdata;
863                                 }
864
865                                 if (/*a2_phrase_mode || */BKGWREN || !inhibit)
866                                 {
867 /*if (logGo)
868 {
869         uint32 offset = a2_addr+(PIXEL_OFFSET_16(a2)<<1);
870 // (((((uint32)a##_y >> 16) * a##_width) + (((uint32)a##_x >> 16) & ~1)) * (1 + a##_pitch) + (((uint32)a##_x >> 16) & 1))
871         WriteLog("[%08X:%04X] ", offset, writedata);
872 }//*/
873                                         // write to the destination
874                                         WRITE_PIXEL(a2, REG(A2_FLAGS), writedata);
875
876                                         if (DSTWRZ)
877                                                 WRITE_ZDATA(a2, REG(A2_FLAGS), srczdata);
878                                 }
879                         }
880
881                         // Update x and y (inner loop)
882 //Now it does! But crappy, crappy, crappy! !!! FIX !!! [DONE]
883 //This is less than ideal, but it works...
884                         if (!BCOMPEN)
885                         {//*/
886                                 a1_x += a1_xadd, a1_y += a1_yadd;
887                                 a2_x = (a2_x + a2_xadd) & a2_mask_x, a2_y = (a2_y + a2_yadd) & a2_mask_y;
888                         }
889                         else
890                         {
891                                 a1_y += a1_yadd, a2_y = (a2_y + a2_yadd) & a2_mask_y;
892                                 if (!DSTA2)
893                                 {
894                                         a1_x += a1_xadd;
895                                         if (bitPos % bppSrc == 0)
896                                                 a2_x = (a2_x + a2_xadd) & a2_mask_x;
897                                 }
898                                 else
899                                 {
900                                         a2_x = (a2_x + a2_xadd) & a2_mask_x;
901                                         if (bitPos % bppSrc == 0)
902                                                 a1_x += a1_xadd;
903                                 }
904                         }//*/
905
906                         if (GOURZ)
907                                 z_i[colour_index] += zadd;
908
909                         if (GOURD || SRCSHADE)
910                         {
911                                 gd_i[colour_index] += gd_ia;
912 //Hmm, this doesn't seem to do anything...
913 //But it is correct according to the JTRM...!
914 if ((int32)gd_i[colour_index] < 0)
915         gd_i[colour_index] = 0;
916 if (gd_i[colour_index] > 0x00FFFFFF)
917         gd_i[colour_index] = 0x00FFFFFF;//*/
918
919                                 gd_c[colour_index] += gd_ca;
920 if ((int32)gd_c[colour_index] < 0)
921         gd_c[colour_index] = 0;
922 if (gd_c[colour_index] > 0x000000FF)
923         gd_c[colour_index] = 0x000000FF;//*/
924                         }
925
926                         if (GOURD || SRCSHADE || GOURZ)
927                         {
928                                 if (a1_phrase_mode)
929 //This screws things up WORSE (for the BIOS opening screen)
930 //                              if (a1_phrase_mode || a2_phrase_mode)
931                                         colour_index = (colour_index + 1) & 0x03;
932                         }
933                 }
934
935 /*
936 Here's the problem... The phrase mode code!
937 Blit! (00100000 -> 00148000) count: 327 x 267, A1/2_FLAGS: 00004420/00004420 [cmd: 41802E01]
938  CMD -> src: SRCEN  dst:  misc:  a1ctl: UPDA1 UPDA2 mode: DSTA2 GOURZ ity:  z-op:  op: LFU_REPLACE ctrl: SRCSHADE
939   A1 step values: -327 (X), 1 (Y)
940   A2 step values: -327 (X), 1 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
941   A1 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 384 (22), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
942   A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 384 (22), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
943         A1 x/y: 28/58, A2 x/y: 28/58 Pattern: 00EA7BEA77EA77EA SRCDATA: 7BFF7BFF7BFF7BFF
944
945 Below fixes it, but then borks:
946 ; O
947
948 Blit! (00110000 <- 0010B2A8) count: 12 x 12, A1/2_FLAGS: 000042E2/00000020 [cmd: 09800609]
949  CMD -> src: SRCEN  dst: DSTEN  misc:  a1ctl: UPDA1 UPDA2 mode:  ity:  z-op:  op: LFU_REPLACE ctrl: DCOMPEN 
950   A1 step values: -15 (X), 1 (Y)
951   A2 step values: -4 (X), 0 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
952   A1 -> pitch: 4 phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
953   A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
954         A1 x/y: 173/144, A2 x/y: 4052/0
955
956 Lesse, with pre-add we'd have:
957
958      oooooooooooo
959 00001111222233334444555566667777
960   ^  ^starts here...
961   |             ^ends here.
962   |rolls back to here. Hmm.
963
964 */
965 //NOTE: The way to fix the CD BIOS is to uncomment below and comment the stuff after
966 //      the phrase mode mucking around. But it fucks up everything else...
967 //#define SCREWY_CD_DEPENDENT
968 #ifdef SCREWY_CD_DEPENDENT
969                 a1_x += a1_step_x;
970                 a1_y += a1_step_y;
971                 a2_x += a2_step_x;
972                 a2_y += a2_step_y;//*/
973 #endif
974
975                 //New: Phrase mode taken into account! :-p
976 /*              if (a1_phrase_mode)                     // v1
977                 {
978                         // Bump the pointer to the next phrase boundary
979                         // Even though it works, this is crappy... Clean it up!
980                         uint32 size = 64 / a1_psize;
981
982                         // Crappy kludge... ('aligning' source to destination)
983                         if (a2_phrase_mode && DSTA2)
984                         {
985                                 uint32 extra = (a2_start >> 16) % size;
986                                 a1_x += extra << 16;
987                         }
988
989                         uint32 newx = (a1_x >> 16) / size;
990                         uint32 newxrem = (a1_x >> 16) % size;
991                         a1_x &= 0x0000FFFF;
992                         a1_x |= (((newx + (newxrem == 0 ? 0 : 1)) * size) & 0xFFFF) << 16;
993                 }//*/
994                 if (a1_phrase_mode)                     // v2
995                 {
996                         // Bump the pointer to the next phrase boundary
997                         // Even though it works, this is crappy... Clean it up!
998                         uint32 size = 64 / a1_psize;
999
1000                         // Crappy kludge... ('aligning' source to destination)
1001                         if (a2_phrase_mode && DSTA2)
1002                         {
1003                                 uint32 extra = (a2_start >> 16) % size;
1004                                 a1_x += extra << 16;
1005                         }
1006
1007                         uint32 pixelSize = (size - 1) << 16;
1008                         a1_x = (a1_x + pixelSize) & ~pixelSize;
1009                 }
1010
1011 /*              if (a2_phrase_mode)                     // v1
1012                 {
1013                         // Bump the pointer to the next phrase boundary
1014                         // Even though it works, this is crappy... Clean it up!
1015                         uint32 size = 64 / a2_psize;
1016
1017                         // Crappy kludge... ('aligning' source to destination)
1018                         // Prolly should do this for A1 channel as well... [DONE]
1019                         if (a1_phrase_mode && !DSTA2)
1020                         {
1021                                 uint32 extra = (a1_start >> 16) % size;
1022                                 a2_x += extra << 16;
1023                         }
1024
1025                         uint32 newx = (a2_x >> 16) / size;
1026                         uint32 newxrem = (a2_x >> 16) % size;
1027                         a2_x &= 0x0000FFFF;
1028                         a2_x |= (((newx + (newxrem == 0 ? 0 : 1)) * size) & 0xFFFF) << 16;
1029                 }//*/
1030                 if (a2_phrase_mode)                     // v1
1031                 {
1032                         // Bump the pointer to the next phrase boundary
1033                         // Even though it works, this is crappy... Clean it up!
1034                         uint32 size = 64 / a2_psize;
1035
1036                         // Crappy kludge... ('aligning' source to destination)
1037                         // Prolly should do this for A1 channel as well... [DONE]
1038                         if (a1_phrase_mode && !DSTA2)
1039                         {
1040                                 uint32 extra = (a1_start >> 16) % size;
1041                                 a2_x += extra << 16;
1042                         }
1043
1044                         uint32 pixelSize = (size - 1) << 16;
1045                         a2_x = (a2_x + pixelSize) & ~pixelSize;
1046                 }
1047
1048                 //Not entirely: This still mucks things up... !!! FIX !!!
1049                 //Should this go before or after the phrase mode mucking around?
1050 #ifndef SCREWY_CD_DEPENDENT
1051                 a1_x += a1_step_x;
1052                 a1_y += a1_step_y;
1053                 a2_x += a2_step_x;
1054                 a2_y += a2_step_y;//*/
1055 #endif
1056         }
1057         
1058         // write values back to registers 
1059         WREG(A1_PIXEL,  (a1_y & 0xFFFF0000) | ((a1_x >> 16) & 0xFFFF));
1060         WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xFFFF));
1061         WREG(A2_PIXEL,  (a2_y & 0xFFFF0000) | ((a2_x >> 16) & 0xFFFF));
1062 specialLog = false;
1063 }
1064
1065 void blitter_blit(uint32 cmd)
1066 {
1067 //Apparently this is doing *something*, just not sure exactly what...
1068 /*if (cmd == 0x41802E01)
1069 {
1070         WriteLog("BLIT: Found our blit. Was: %08X ", cmd);
1071         cmd = 0x01800E01;
1072         WriteLog("Is: %08X\n", cmd);
1073 }//*/
1074
1075         uint32 pitchValue[4] = { 0, 1, 3, 2 };
1076         colour_index = 0;
1077         src = cmd & 0x07;
1078         dst = (cmd >> 3) & 0x07;
1079         misc = (cmd >> 6) & 0x03;
1080         a1ctl = (cmd >> 8) & 0x7;
1081         mode = (cmd >> 11) & 0x07;
1082         ity = (cmd >> 14) & 0x0F;
1083         zop = (cmd >> 18) & 0x07;
1084         op = (cmd >> 21) & 0x0F;
1085         ctrl = (cmd >> 25) & 0x3F;
1086
1087         // Addresses in A1/2_BASE are *phrase* aligned, i.e., bottom three bits are ignored!
1088         // NOTE: This fixes Rayman's bad collision detection AND keeps T2K working!
1089         a1_addr = REG(A1_BASE) & 0xFFFFFFF8;
1090         a2_addr = REG(A2_BASE) & 0xFFFFFFF8;
1091
1092         a1_zoffs = (REG(A1_FLAGS) >> 6) & 7;
1093         a2_zoffs = (REG(A2_FLAGS) >> 6) & 7;
1094         
1095         xadd_a1_control = (REG(A1_FLAGS) >> 16) & 0x03;
1096         xadd_a2_control = (REG(A2_FLAGS) >> 16) & 0x03;
1097
1098         a1_pitch = pitchValue[(REG(A1_FLAGS) & 0x03)];
1099         a2_pitch = pitchValue[(REG(A2_FLAGS) & 0x03)];
1100
1101         n_pixels = REG(PIXLINECOUNTER) & 0xFFFF;
1102         n_lines = (REG(PIXLINECOUNTER) >> 16) & 0xFFFF;
1103
1104         a1_x = (REG(A1_PIXEL) << 16) | (REG(A1_FPIXEL) & 0xFFFF);
1105         a1_y = (REG(A1_PIXEL) & 0xFFFF0000) | (REG(A1_FPIXEL) >> 16);
1106 //According to the JTRM, X is restricted to 15 bits and Y is restricted to 12.
1107 //But it seems to fuck up T2K! !!! FIX !!!
1108 //Could it be sign extended??? Doesn't seem to be so according to JTRM
1109 //      a1_x &= 0x7FFFFFFF, a1_y &= 0x0FFFFFFF;
1110 //Actually, it says that the X is 16 bits. But it still seems to mess with the Y when restricted to 12...
1111 //      a1_y &= 0x0FFFFFFF;
1112
1113 //      a1_width = blitter_scanline_width[((REG(A1_FLAGS) & 0x00007E00) >> 9)];
1114 // According to JTRM, this must give a *whole number* of phrases in the current
1115 // pixel size (this means the lookup above is WRONG)... !!! FIX !!!
1116         uint32 m = (REG(A1_FLAGS) >> 9) & 0x03, e = (REG(A1_FLAGS) >> 11) & 0x0F;
1117         a1_width = ((0x04 | m) << e) >> 2;//*/
1118
1119         a2_x = (REG(A2_PIXEL) & 0x0000FFFF) << 16;
1120         a2_y = (REG(A2_PIXEL) & 0xFFFF0000);
1121 //According to the JTRM, X is restricted to 15 bits and Y is restricted to 12.
1122 //But it seems to fuck up T2K! !!! FIX !!!
1123 //      a2_x &= 0x7FFFFFFF, a2_y &= 0x0FFFFFFF;
1124 //Actually, it says that the X is 16 bits. But it still seems to mess with the Y when restricted to 12...
1125 //      a2_y &= 0x0FFFFFFF;
1126
1127 //      a2_width = blitter_scanline_width[((REG(A2_FLAGS) & 0x00007E00) >> 9)];
1128 // According to JTRM, this must give a *whole number* of phrases in the current
1129 // pixel size (this means the lookup above is WRONG)... !!! FIX !!!
1130         m = (REG(A2_FLAGS) >> 9) & 0x03, e = (REG(A2_FLAGS) >> 11) & 0x0F;
1131         a2_width = ((0x04 | m) << e) >> 2;//*/
1132         a2_mask_x = ((REG(A2_MASK) & 0x0000FFFF) << 16) | 0xFFFF;
1133         a2_mask_y = (REG(A2_MASK) & 0xFFFF0000) | 0xFFFF;
1134
1135         // Check for "use mask" flag
1136         if (!(REG(A2_FLAGS) & 0x8000))
1137         {
1138                 a2_mask_x = 0xFFFFFFFF; // must be 16.16
1139                 a2_mask_y = 0xFFFFFFFF; // must be 16.16
1140         }
1141
1142         a1_phrase_mode = 0;
1143
1144         // According to the official documentation, a hardware bug ties A2's yadd bit to A1's...
1145         a2_yadd = a1_yadd = (YADD1_A1 ? 1 << 16 : 0);
1146
1147         if (YSIGNSUB_A1)
1148                 a1_yadd = -a1_yadd;
1149
1150         // determine a1_xadd
1151         switch (xadd_a1_control)
1152         {
1153         case XADDPHR:
1154 // This is a documented Jaguar bug relating to phrase mode and truncation... Look into it!
1155                 // add phrase offset to X and truncate
1156                 a1_xadd = 1 << 16;
1157                 a1_phrase_mode = 1;
1158                 break;
1159         case XADDPIX:
1160                 // add pixelsize (1) to X
1161                 a1_xadd = 1 << 16;
1162                 break;
1163         case XADD0:     
1164                 // add zero (for those nice vertical lines)
1165                 a1_xadd = 0;
1166                 break;
1167         case XADDINC:
1168                 // add the contents of the increment register
1169                 a1_xadd = (REG(A1_INC) << 16)            | (REG(A1_FINC) & 0x0000FFFF);
1170                 a1_yadd = (REG(A1_INC) & 0xFFFF0000) | (REG(A1_FINC) >> 16);
1171                 break;
1172         }
1173
1174
1175 //Blit! (0011D000 -> 000B9600) count: 228 x 1, A1/2_FLAGS: 00073820/00064220 [cmd: 41802801]
1176 //  A1 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 128 (1C), addctl: XADDINC YADD1 XSIGNADD YSIGNADD
1177 //  A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 320 (21), addctl: XADD0 YADD1 XSIGNADD YSIGNADD
1178 //if (YADD1_A1 && YADD1_A2 && xadd_a2_control == XADD0 && xadd_a1_control == XADDINC)// &&
1179 //      uint32 a1f = REG(A1_FLAGS), a2f = REG(A2_FLAGS);
1180 //Ok, so this ISN'T it... Prolly the XADDPHR code above that's doing it...
1181 //if (REG(A1_FLAGS) == 0x00073820 && REG(A2_FLAGS) == 0x00064220 && cmd == 0x41802801)
1182 //        A1 x/y: 14368/7, A2 x/y: 150/36
1183 //This is it... The problem...
1184 //if ((a1_x >> 16) == 14368) // 14368 = $3820
1185 //      return; //Lesse what we got...
1186
1187         if (XSIGNSUB_A1)
1188                 a1_xadd = -a1_xadd;
1189
1190         if (YSIGNSUB_A2)
1191                 a2_yadd = -a2_yadd;
1192
1193         a2_phrase_mode = 0;
1194
1195         // determine a2_xadd
1196         switch (xadd_a2_control)
1197         {
1198         case XADDPHR:
1199                 // add phrase offset to X and truncate
1200                 a2_xadd = 1 << 16;
1201                 a2_phrase_mode = 1;
1202                 break;
1203         case XADDPIX:
1204                 // add pixelsize (1) to X
1205                 a2_xadd = 1 << 16;
1206                 break;
1207         case XADD0:     
1208                 // add zero (for those nice vertical lines)
1209                 a2_xadd = 0;
1210                 break;
1211 //This really isn't a valid bit combo for A2... Shouldn't this cause the blitter to just say no?
1212         case XADDINC:
1213 WriteLog("BLIT: Asked to use invalid bit combo (XADDINC) for A2...\n");
1214                 // add the contents of the increment register
1215                 // since there is no register for a2 we just add 1
1216 //Let's do nothing, since it's not listed as a valid bit combo...
1217 //              a2_xadd = 1 << 16;
1218                 break;
1219         }
1220
1221         if (XSIGNSUB_A2)
1222                 a2_xadd = -a2_xadd;
1223
1224         // Modify outer loop steps based on blitter command
1225
1226         a1_step_x = 0;
1227         a1_step_y = 0;
1228         a2_step_x = 0;
1229         a2_step_y = 0;
1230
1231         if (UPDA1F)
1232                 a1_step_x = (REG(A1_FSTEP) & 0xFFFF),
1233                 a1_step_y = (REG(A1_FSTEP) >> 16);
1234
1235         if (UPDA1)
1236                 a1_step_x |= ((REG(A1_STEP) & 0x0000FFFF) << 16),
1237                 a1_step_y |= ((REG(A1_STEP) & 0xFFFF0000));
1238
1239         if (UPDA2)
1240                 a2_step_x = (REG(A2_STEP) & 0x0000FFFF) << 16,
1241                 a2_step_y = (REG(A2_STEP) & 0xFFFF0000);
1242
1243         outer_loop = n_lines;
1244
1245         // Clipping...
1246
1247         if (CLIPA1)
1248                 a1_clip_x = REG(A1_CLIP) & 0x7FFF,
1249                 a1_clip_y = (REG(A1_CLIP) >> 16) & 0x7FFF;
1250
1251 // This phrase sizing is incorrect as well... !!! FIX !!! [NOTHING TO FIX]
1252 // Err, this is pixel size... (and it's OK)
1253         a2_psize = 1 << ((REG(A2_FLAGS) >> 3) & 0x07);
1254         a1_psize = 1 << ((REG(A1_FLAGS) >> 3) & 0x07);
1255
1256         // Z-buffering
1257         if (GOURZ)
1258         {
1259                 zadd = REG(ZINC);
1260
1261                 for(int v=0; v<4; v++)
1262                         z_i[v] = REG(PHRASEZ0 + v*4);
1263         }
1264
1265         // Gouraud shading
1266         if (GOURD || GOURZ || SRCSHADE)
1267         {
1268                 gd_c[0] = blitter_ram[PATTERNDATA + 6];
1269                 gd_i[0] = ((uint32)blitter_ram[PATTERNDATA + 7] << 16)
1270                         | ((uint32)blitter_ram[SRCDATA + 6] << 8) | blitter_ram[SRCDATA + 7];
1271
1272                 gd_c[1] = blitter_ram[PATTERNDATA + 4];
1273                 gd_i[1] = ((uint32)blitter_ram[PATTERNDATA + 5] << 16)
1274                         | ((uint32)blitter_ram[SRCDATA + 4] << 8) | blitter_ram[SRCDATA + 5];
1275
1276                 gd_c[2] = blitter_ram[PATTERNDATA + 2];
1277                 gd_i[2] = ((uint32)blitter_ram[PATTERNDATA + 3] << 16)
1278                         | ((uint32)blitter_ram[SRCDATA + 2] << 8) | blitter_ram[SRCDATA + 3];
1279
1280                 gd_c[3] = blitter_ram[PATTERNDATA + 0];
1281                 gd_i[3] = ((uint32)blitter_ram[PATTERNDATA + 1] << 16)
1282                         | ((uint32)blitter_ram[SRCDATA + 0] << 8) | blitter_ram[SRCDATA + 1];
1283
1284                 gouraud_add = REG(INTENSITYINC);
1285                 
1286                 gd_ia = gouraud_add & 0x00FFFFFF;
1287                 if (gd_ia & 0x00800000)
1288                         gd_ia = 0xFF000000 | gd_ia;
1289
1290                 gd_ca = (gouraud_add >> 24) & 0xFF;
1291                 if (gd_ca & 0x00000080)
1292                         gd_ca = 0xFFFFFF00 | gd_ca;
1293         }
1294
1295         // Bit comparitor fixing...
1296 /*      if (BCOMPEN)
1297         {
1298                 // Determine the data flow direction...
1299                 if (!DSTA2)
1300                         a2_step_x /= (1 << ((REG(A2_FLAGS) >> 3) & 0x07));
1301                 else
1302                         ;//add this later
1303         }//*/
1304 /*      if (BCOMPEN)//Kludge for Hover Strike... !!! FIX !!!
1305         {
1306                 // Determine the data flow direction...
1307                 if (!DSTA2)
1308                         a2_x <<= 3;
1309         }//*/
1310
1311 #ifdef LOG_BLITS
1312         if (start_logging)
1313         {
1314                 WriteLog("Blit!\n");
1315                 WriteLog("  cmd      = 0x%.8x\n",cmd);
1316                 WriteLog("  a1_base  = %08X\n", a1_addr);
1317                 WriteLog("  a1_pitch = %d\n", a1_pitch);
1318                 WriteLog("  a1_psize = %d\n", a1_psize);
1319                 WriteLog("  a1_width = %d\n", a1_width);
1320                 WriteLog("  a1_xadd  = %f (phrase=%d)\n", (float)a1_xadd / 65536.0, a1_phrase_mode);
1321                 WriteLog("  a1_yadd  = %f\n", (float)a1_yadd / 65536.0);
1322                 WriteLog("  a1_xstep = %f\n", (float)a1_step_x / 65536.0);
1323                 WriteLog("  a1_ystep = %f\n", (float)a1_step_y / 65536.0);
1324                 WriteLog("  a1_x     = %f\n", (float)a1_x / 65536.0);
1325                 WriteLog("  a1_y     = %f\n", (float)a1_y / 65536.0);
1326                 WriteLog("  a1_zoffs = %i\n",a1_zoffs);
1327
1328                 WriteLog("  a2_base  = %08X\n", a2_addr);
1329                 WriteLog("  a2_pitch = %d\n", a2_pitch);
1330                 WriteLog("  a2_psize = %d\n", a2_psize);
1331                 WriteLog("  a2_width = %d\n", a2_width);
1332                 WriteLog("  a2_xadd  = %f (phrase=%d)\n", (float)a2_xadd / 65536.0, a2_phrase_mode);
1333                 WriteLog("  a2_yadd  = %f\n", (float)a2_yadd / 65536.0);
1334                 WriteLog("  a2_xstep = %f\n", (float)a2_step_x / 65536.0);
1335                 WriteLog("  a2_ystep = %f\n", (float)a2_step_y / 65536.0);
1336                 WriteLog("  a2_x     = %f\n", (float)a2_x / 65536.0);
1337                 WriteLog("  a2_y     = %f\n", (float)a2_y / 65536.0);
1338                 WriteLog("  a2_mask_x= 0x%.4x\n",a2_mask_x);
1339                 WriteLog("  a2_mask_y= 0x%.4x\n",a2_mask_y);
1340                 WriteLog("  a2_zoffs = %i\n",a2_zoffs);
1341
1342                 WriteLog("  count    = %d x %d\n", n_pixels, n_lines);
1343
1344                 WriteLog("  command  = %08X\n", cmd);
1345                 WriteLog("  dsten    = %i\n",DSTEN);
1346                 WriteLog("  srcen    = %i\n",SRCEN);
1347                 WriteLog("  patdsel  = %i\n",PATDSEL);
1348                 WriteLog("  color    = 0x%.8x\n",REG(PATTERNDATA));
1349                 WriteLog("  dcompen  = %i\n",DCOMPEN);
1350                 WriteLog("  bcompen  = %i\n",BCOMPEN);
1351                 WriteLog("  cmpdst   = %i\n",CMPDST);
1352                 WriteLog("  GOURZ   = %i\n",GOURZ);
1353                 WriteLog("  GOURD   = %i\n",GOURD);
1354                 WriteLog("  SRCSHADE= %i\n",SRCSHADE);
1355         }       
1356 #endif
1357
1358 //NOTE: Pitch is ignored!
1359
1360 //This *might* be the altimeter blits (they are)...
1361 //On captured screen, x-pos for black (inner) is 259, for pink is 257
1362 //Black is short by 3, pink is short by 1...
1363 /*
1364 Blit! (00110000 <- 000BF010) count: 9 x 31, A1/2_FLAGS: 000042E2/00010020 [cmd: 00010200]
1365  CMD -> src:  dst:  misc:  a1ctl: UPDA1  mode:  ity: PATDSEL z-op:  op: LFU_CLEAR ctrl: 
1366   A1 -> pitch: 4 phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
1367   A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
1368         A1 x/y: 262/124, A2 x/y: 128/0
1369 Blit! (00110000 <- 000BF010) count: 5 x 38, A1/2_FLAGS: 000042E2/00010020 [cmd: 00010200]
1370  CMD -> src:  dst:  misc:  a1ctl: UPDA1  mode:  ity: PATDSEL z-op:  op: LFU_CLEAR ctrl: 
1371   A1 -> pitch: 4 phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
1372   A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
1373         A1 x/y: 264/117, A2 x/y: 407/0
1374
1375 Blit! (00110000 <- 000BF010) count: 9 x 23, A1/2_FLAGS: 000042E2/00010020 [cmd: 00010200]
1376  CMD -> src:  dst:  misc:  a1ctl: UPDA1  mode:  ity: PATDSEL z-op:  op: LFU_CLEAR ctrl: 
1377   A1 step values: -10 (X), 1 (Y)
1378   A1 -> pitch: 4(2) phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
1379   A2 -> pitch: 1(0) phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
1380         A1 x/y: 262/132, A2 x/y: 129/0
1381 Blit! (00110000 <- 000BF010) count: 5 x 27, A1/2_FLAGS: 000042E2/00010020 [cmd: 00010200]
1382  CMD -> src:  dst:  misc:  a1ctl: UPDA1  mode:  ity: PATDSEL z-op:  op: LFU_CLEAR ctrl: 
1383   A1 step values: -8 (X), 1 (Y)
1384   A1 -> pitch: 4(2) phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
1385   A2 -> pitch: 1(0) phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
1386         A1 x/y: 264/128, A2 x/y: 336/0
1387
1388   264v       vCursor ends up here...
1389      xxxxx...`
1390      111122223333
1391
1392 262v         vCursor ends up here...
1393    xxxxxxxxx.'
1394  1111222233334444
1395
1396 Fixed! Now for more:
1397
1398 ; This looks like the ship icon in the upper left corner...
1399
1400 Blit! (00110000 <- 0010B2A8) count: 11 x 12, A1/2_FLAGS: 000042E2/00000020 [cmd: 09800609]
1401  CMD -> src: SRCEN  dst: DSTEN  misc:  a1ctl: UPDA1 UPDA2 mode:  ity:  z-op:  op: LFU_REPLACE ctrl: DCOMPEN 
1402   A1 step values: -12 (X), 1 (Y)
1403   A2 step values: 0 (X), 0 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
1404   A1 -> pitch: 4 phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
1405   A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
1406         A1 x/y: 20/24, A2 x/y: 5780/0
1407
1408 Also fixed!
1409
1410 More (not sure this is a blitter problem as much as it's a GPU problem):
1411 All but the "M" are trashed...
1412 This does *NOT* look like a blitter problem, as it's rendering properly...
1413 Actually, if you look at the A1 step values, there IS a discrepancy!
1414
1415 ; D
1416
1417 Blit! (00110000 <- 0010B2A8) count: 12 x 12, A1/2_FLAGS: 000042E2/00000020 [cmd: 09800609]
1418  CMD -> src: SRCEN  dst: DSTEN  misc:  a1ctl: UPDA1 UPDA2 mode:  ity:  z-op:  op: LFU_REPLACE ctrl: DCOMPEN 
1419   A1 step values: -14 (X), 1 (Y)
1420   A2 step values: -4 (X), 0 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
1421   A1 -> pitch: 4 phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
1422   A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
1423         A1 x/y: 134/144, A2 x/y: 2516/0
1424 ;129,146: +5,-2
1425
1426 ; E
1427
1428 Blit! (00110000 <- 0010B2A8) count: 12 x 12, A1/2_FLAGS: 000042E2/00000020 [cmd: 09800609]
1429  CMD -> src: SRCEN  dst: DSTEN  misc:  a1ctl: UPDA1 UPDA2 mode:  ity:  z-op:  op: LFU_REPLACE ctrl: DCOMPEN 
1430   A1 step values: -13 (X), 1 (Y)
1431   A2 step values: -4 (X), 0 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
1432   A1 -> pitch: 4 phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
1433   A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
1434         A1 x/y: 147/144, A2 x/y: 2660/0
1435
1436 ; M
1437
1438 Blit! (00110000 <- 0010B2A8) count: 12 x 12, A1/2_FLAGS: 000042E2/00000020 [cmd: 09800609]
1439  CMD -> src: SRCEN  dst: DSTEN  misc:  a1ctl: UPDA1 UPDA2 mode:  ity:  z-op:  op: LFU_REPLACE ctrl: DCOMPEN 
1440   A1 step values: -12 (X), 1 (Y)
1441   A2 step values: 0 (X), 0 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
1442   A1 -> pitch: 4 phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
1443   A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
1444         A1 x/y: 160/144, A2 x/y: 3764/0
1445
1446 ; O
1447
1448 Blit! (00110000 <- 0010B2A8) count: 12 x 12, A1/2_FLAGS: 000042E2/00000020 [cmd: 09800609]
1449  CMD -> src: SRCEN  dst: DSTEN  misc:  a1ctl: UPDA1 UPDA2 mode:  ity:  z-op:  op: LFU_REPLACE ctrl: DCOMPEN 
1450   A1 step values: -15 (X), 1 (Y)
1451   A2 step values: -4 (X), 0 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
1452   A1 -> pitch: 4 phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
1453   A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
1454         A1 x/y: 173/144, A2 x/y: 4052/0
1455
1456 */
1457 //extern int op_start_log;
1458 if (blit_start_log)
1459 {
1460         char * ctrlStr[4] = { "XADDPHR\0", "XADDPIX\0", "XADD0\0", "XADDINC\0" };
1461         char * bppStr[8] = { "1bpp\0", "2bpp\0", "4bpp\0", "8bpp\0", "16bpp\0", "32bpp\0", "???\0", "!!!\0" };
1462         char * opStr[16] = { "LFU_CLEAR", "LFU_NSAND", "LFU_NSAD", "LFU_NOTS", "LFU_SAND", "LFU_NOTD", "LFU_N_SXORD", "LFU_NSORND",
1463                 "LFU_SAD", "LFU_XOR", "LFU_D", "LFU_NSORD", "LFU_REPLACE", "LFU_SORND", "LFU_SORD", "LFU_ONE" };
1464         uint32 /*src = cmd & 0x07, dst = (cmd >> 3) & 0x07, misc = (cmd >> 6) & 0x03,
1465                 a1ctl = (cmd >> 8) & 0x07,*/ mode = (cmd >> 11) & 0x07/*, ity = (cmd >> 14) & 0x0F,
1466                 zop = (cmd >> 18) & 0x07, op = (cmd >> 21) & 0x0F, ctrl = (cmd >> 25) & 0x3F*/;
1467         uint32 a1f = REG(A1_FLAGS), a2f = REG(A2_FLAGS);
1468         uint32 p1 = a1f & 0x07, p2 = a2f & 0x07,
1469                 d1 = (a1f >> 3) & 0x07, d2 = (a2f >> 3) & 0x07,
1470                 zo1 = (a1f >> 6) & 0x07, zo2 = (a2f >> 6) & 0x07,
1471                 w1 = (a1f >> 9) & 0x3F, w2 = (a2f >> 9) & 0x3F,
1472                 ac1 = (a1f >> 16) & 0x1F, ac2 = (a2f >> 16) & 0x1F;
1473         uint32 iw1 = ((0x04 | (w1 & 0x03)) << ((w1 & 0x3C) >> 2)) >> 2;
1474         uint32 iw2 = ((0x04 | (w2 & 0x03)) << ((w2 & 0x3C) >> 2)) >> 2;
1475         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);
1476 //      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);
1477
1478         WriteLog(" CMD -> src: %s%s%s ", (cmd & 0x0001 ? "SRCEN " : ""), (cmd & 0x0002 ? "SRCENZ " : ""), (cmd & 0x0004 ? "SRCENX" : ""));
1479         WriteLog("dst: %s%s%s ", (cmd & 0x0008 ? "DSTEN " : ""), (cmd & 0x0010 ? "DSTENZ " : ""), (cmd & 0x0020 ? "DSTWRZ" : ""));
1480         WriteLog("misc: %s%s ", (cmd & 0x0040 ? "CLIP_A1 " : ""), (cmd & 0x0080 ? "???" : ""));
1481         WriteLog("a1ctl: %s%s%s ", (cmd & 0x0100 ? "UPDA1F " : ""), (cmd & 0x0200 ? "UPDA1 " : ""), (cmd & 0x0400 ? "UPDA2" : ""));
1482         WriteLog("mode: %s%s%s ", (cmd & 0x0800 ? "DSTA2 " : ""), (cmd & 0x1000 ? "GOURD " : ""), (cmd & 0x2000 ? "GOURZ" : ""));
1483         WriteLog("ity: %s%s%s%s ", (cmd & 0x4000 ? "TOPBEN " : ""), (cmd & 0x8000 ? "TOPNEN " : ""), (cmd & 0x00010000 ? "PATDSEL" : ""), (cmd & 0x00020000 ? "ADDDSEL" : ""));
1484         WriteLog("z-op: %s%s%s ", (cmd & 0x00040000 ? "ZMODELT " : ""), (cmd & 0x00080000 ? "ZMODEEQ " : ""), (cmd & 0x00100000 ? "ZMODEGT" : ""));
1485         WriteLog("op: %s ", opStr[(cmd >> 21) & 0x0F]);
1486         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" : ""));
1487
1488         if (UPDA1)
1489                 WriteLog("  A1 step values: %d (X), %d (Y)\n", a1_step_x >> 16, a1_step_y >> 16);
1490
1491         if (UPDA2)
1492                 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);
1493
1494         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"));
1495         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"));
1496         WriteLog("        A1 x/y: %d/%d, A2 x/y: %d/%d Pattern: %08X%08X SRCDATA: %08X%08X\n", a1_x >> 16, a1_y >> 16, a2_x >> 16, a2_y >> 16, REG(PATTERNDATA), REG(PATTERNDATA + 4), REG(SRCDATA), REG(SRCDATA + 4));
1497 //      blit_start_log = 0;
1498 //      op_start_log = 1;
1499 }
1500
1501         blitter_working = 1;
1502 //#ifndef USE_GENERIC_BLITTER
1503 //      if (!blitter_execute_cached_code(blitter_in_cache(cmd)))
1504 //#endif
1505         blitter_generic(cmd);
1506
1507 /*if (blit_start_log)
1508 {
1509         if (a1_addr == 0xF03000 && a2_addr == 0x004D58)
1510         {
1511                 WriteLog("\nBytes at 004D58:\n");
1512                 for(int i=0x004D58; i<0x004D58+(10*127*4); i++)
1513                         WriteLog("%02X ", JaguarReadByte(i));
1514                 WriteLog("\nBytes at F03000:\n");
1515                 for(int i=0xF03000; i<0xF03000+(6*127*4); i++)
1516                         WriteLog("%02X ", JaguarReadByte(i));
1517                 WriteLog("\n\n");
1518         }
1519 }//*/
1520
1521         blitter_working = 0;
1522 }
1523 #endif                                                                                  // of the #if 0 near the top...
1524 /*******************************************************************************
1525 ********************** STUFF CUT ABOVE THIS LINE! ******************************
1526 *******************************************************************************/
1527
1528 void blitter_init(void)
1529 {
1530         blitter_reset();
1531 }
1532
1533 void blitter_reset(void)
1534 {
1535         memset(blitter_ram, 0x00, 0xA0);
1536 }
1537
1538 void blitter_done(void)
1539 {
1540         WriteLog("BLIT: Done.\n");
1541 }
1542
1543 uint8 BlitterReadByte(uint32 offset, uint32 who/*=UNKNOWN*/)
1544 {
1545         offset &= 0xFF;
1546
1547         // status register
1548 //This isn't cycle accurate--how to fix? !!! FIX !!!
1549 //Probably have to do some multi-threaded implementation or at least a reentrant safe implementation...
1550         if (offset == (0x38 + 3))
1551                 return 0x01;    // always idle
1552
1553 // CHECK HERE ONCE THIS FIX HAS BEEN TESTED: [ ]
1554 //Fix for AvP:
1555         if (offset >= 0x04 && offset <= 0x07)
1556 //This is it. I wonder if it just ignores the lower three bits?
1557 //No, this is a documented Jaguar I bug. It also bites the read at $F02230 as well...
1558                 return blitter_ram[offset + 0x08];              // A1_PIXEL ($F0220C) read at $F02204
1559
1560         if (offset >= 0x2C && offset <= 0x2F)
1561                 return blitter_ram[offset + 0x04];              // A2_PIXEL ($F02230) read at $F0222C
1562
1563         return blitter_ram[offset];
1564 }
1565
1566 //Crappy!
1567 uint16 BlitterReadWord(uint32 offset, uint32 who/*=UNKNOWN*/)
1568 {
1569         return ((uint16)BlitterReadByte(offset, who) << 8) | (uint16)BlitterReadByte(offset+1, who);
1570 }
1571
1572 //Crappy!
1573 uint32 BlitterReadLong(uint32 offset, uint32 who/*=UNKNOWN*/)
1574 {
1575         return (BlitterReadWord(offset, who) << 16) | BlitterReadWord(offset+2, who);
1576 }
1577
1578 void BlitterWriteByte(uint32 offset, uint8 data, uint32 who/*=UNKNOWN*/)
1579 {
1580 /*if (offset & 0xFF == 0x7B)
1581         WriteLog("--> Wrote to B_STOP: value -> %02X\n", data);*/
1582         offset &= 0xFF;
1583 /*if ((offset >= PATTERNDATA) && (offset < PATTERNDATA + 8))
1584 {
1585         printf("--> %s wrote %02X to byte %u of PATTERNDATA...\n", whoName[who], data, offset - PATTERNDATA);
1586         fflush(stdout);
1587 }//*/
1588
1589         // This handles writes to INTENSITY0-3 by also writing them to their proper places in
1590         // PATTERNDATA & SOURCEDATA (should do the same for the Z registers! !!! FIX !!! [DONE])
1591         if ((offset >= 0x7C) && (offset <= 0x9B))
1592         {
1593                 switch (offset)
1594                 {
1595                 // INTENSITY registers 0-3
1596                 case 0x7C: break;
1597                 case 0x7D: blitter_ram[PATTERNDATA + 7] = data; break;
1598                 case 0x7E: blitter_ram[SRCDATA + 6] = data; break;
1599                 case 0x7F: blitter_ram[SRCDATA + 7] = data; break;
1600
1601                 case 0x80: break;
1602                 case 0x81: blitter_ram[PATTERNDATA + 5] = data; break;
1603                 case 0x82: blitter_ram[SRCDATA + 4] = data; break;
1604                 case 0x83: blitter_ram[SRCDATA + 5] = data; break;
1605                 
1606                 case 0x84: break;
1607                 case 0x85: blitter_ram[PATTERNDATA + 3] = data; break;
1608                 case 0x86: blitter_ram[SRCDATA + 2] = data; break;
1609                 case 0x87: blitter_ram[SRCDATA + 3] = data; break;
1610                 
1611                 case 0x88: break;
1612                 case 0x89: blitter_ram[PATTERNDATA + 1] = data; break;
1613                 case 0x8A: blitter_ram[SRCDATA + 0] = data; break;
1614                 case 0x8B: blitter_ram[SRCDATA + 1] = data; break;
1615
1616
1617                 // Z registers 0-3
1618                 case 0x8C: blitter_ram[SRCZINT + 6] = data; break;
1619                 case 0x8D: blitter_ram[SRCZINT + 7] = data; break;
1620                 case 0x8E: blitter_ram[SRCZFRAC + 6] = data; break;
1621                 case 0x8F: blitter_ram[SRCZFRAC + 7] = data; break;
1622
1623                 case 0x90: blitter_ram[SRCZINT + 4] = data; break;
1624                 case 0x91: blitter_ram[SRCZINT + 5] = data; break;
1625                 case 0x92: blitter_ram[SRCZFRAC + 4] = data; break;
1626                 case 0x93: blitter_ram[SRCZFRAC + 5] = data; break;
1627                 
1628                 case 0x94: blitter_ram[SRCZINT + 2] = data; break;
1629                 case 0x95: blitter_ram[SRCZINT + 3] = data; break;
1630                 case 0x96: blitter_ram[SRCZFRAC + 2] = data; break;
1631                 case 0x97: blitter_ram[SRCZFRAC + 3] = data; break;
1632                 
1633                 case 0x98: blitter_ram[SRCZINT + 0] = data; break;
1634                 case 0x99: blitter_ram[SRCZINT + 1] = data; break;
1635                 case 0x9A: blitter_ram[SRCZFRAC + 0] = data; break;
1636                 case 0x9B: blitter_ram[SRCZFRAC + 1] = data; break;
1637                 }
1638         }
1639
1640         // It looks weird, but this is how the 64 bit registers are actually handled...!
1641
1642         else if ((offset >= SRCDATA + 0) && (offset <= SRCDATA + 3)
1643                 || (offset >= DSTDATA + 0) && (offset <= DSTDATA + 3)
1644                 || (offset >= DSTZ + 0) && (offset <= DSTZ + 3)
1645                 || (offset >= SRCZINT + 0) && (offset <= SRCZINT + 3)
1646                 || (offset >= SRCZFRAC + 0) && (offset <= SRCZFRAC + 3)
1647                 || (offset >= PATTERNDATA + 0) && (offset <= PATTERNDATA + 3))
1648         {
1649                 blitter_ram[offset + 4] = data;
1650         }
1651         else if ((offset >= SRCDATA + 4) && (offset <= SRCDATA + 7)
1652                 || (offset >= DSTDATA + 4) && (offset <= DSTDATA + 7)
1653                 || (offset >= DSTZ + 4) && (offset <= DSTZ + 7)
1654                 || (offset >= SRCZINT + 4) && (offset <= SRCZINT + 7)
1655                 || (offset >= SRCZFRAC + 4) && (offset <= SRCZFRAC + 7)
1656                 || (offset >= PATTERNDATA + 4) && (offset <= PATTERNDATA + 7))
1657         {
1658                 blitter_ram[offset - 4] = data;
1659         }
1660         else
1661                 blitter_ram[offset] = data;
1662 }
1663
1664 void BlitterWriteWord(uint32 offset, uint16 data, uint32 who/*=UNKNOWN*/)
1665 {
1666 /*if (((offset & 0xFF) >= PATTERNDATA) && ((offset & 0xFF) < PATTERNDATA + 8))
1667 {
1668         printf("----> %s wrote %04X to byte %u of PATTERNDATA...\n", whoName[who], data, offset - (0xF02200 + PATTERNDATA));
1669         fflush(stdout);
1670 }*/
1671 //#if 1
1672 /*      if (offset & 0xFF == A1_PIXEL && data == 14368)
1673         {
1674                 WriteLog("\n1\nA1_PIXEL written by %s (%u)...\n\n\n", whoName[who], data);
1675 extern bool doGPUDis;
1676 doGPUDis = true;
1677         }
1678         if ((offset & 0xFF) == (A1_PIXEL + 2) && data == 14368)
1679         {
1680                 WriteLog("\n2\nA1_PIXEL written by %s (%u)...\n\n\n", whoName[who], data);
1681 extern bool doGPUDis;
1682 doGPUDis = true;
1683         }//*/
1684 //#endif
1685
1686         BlitterWriteByte(offset + 0, data >> 8, who);
1687         BlitterWriteByte(offset + 1, data & 0xFF, who);
1688
1689         if ((offset & 0xFF) == 0x3A)
1690         // I.e., the second write of 32-bit value--not convinced this is the best way to do this!
1691         // But then again, according to the Jaguar docs, this is correct...!
1692 /*extern int blit_start_log;
1693 extern bool doGPUDis;
1694 if (blit_start_log)
1695 {
1696         WriteLog("BLIT: Blitter started by %s...\n", whoName[who]);
1697         doGPUDis = true;
1698 }//*/
1699 #ifdef USE_ORIGINAL_BLITTER
1700                 blitter_blit(GET32(blitter_ram, 0x38));
1701 #endif
1702 #ifdef USE_MIDSUMMER_BLITTER
1703                 BlitterMidsummer(GET32(blitter_ram, 0x38));
1704 #endif
1705 #ifdef USE_MIDSUMMER_BLITTER_MKII
1706                 BlitterMidsummer2();
1707 #endif
1708 }
1709 //F02278,9,A,B
1710
1711 void BlitterWriteLong(uint32 offset, uint32 data, uint32 who/*=UNKNOWN*/)
1712 {
1713 /*if (((offset & 0xFF) >= PATTERNDATA) && ((offset & 0xFF) < PATTERNDATA + 8))
1714 {
1715         printf("------> %s wrote %08X to byte %u of PATTERNDATA...\n", whoName[who], data, offset - (0xF02200 + PATTERNDATA));
1716         fflush(stdout);
1717 }//*/
1718 //#if 1
1719 /*      if ((offset & 0xFF) == A1_PIXEL && (data & 0xFFFF) == 14368)
1720         {
1721                 WriteLog("\n3\nA1_PIXEL written by %s (%u)...\n\n\n", whoName[who], data);
1722 extern bool doGPUDis;
1723 doGPUDis = true;
1724         }//*/
1725 //#endif
1726
1727         BlitterWriteWord(offset + 0, data >> 16, who);
1728         BlitterWriteWord(offset + 2, data & 0xFFFF, who);
1729 }
1730
1731 void LogBlit(void)
1732 {
1733         const char * opStr[16] = { "LFU_CLEAR", "LFU_NSAND", "LFU_NSAD", "LFU_NOTS", "LFU_SAND", "LFU_NOTD", "LFU_N_SXORD", "LFU_NSORND",
1734                 "LFU_SAD", "LFU_XOR", "LFU_D", "LFU_NSORD", "LFU_REPLACE", "LFU_SORND", "LFU_SORD", "LFU_ONE" };
1735         uint32 cmd = GET32(blitter_ram, 0x38);
1736         uint32 m = (REG(A1_FLAGS) >> 9) & 0x03, e = (REG(A1_FLAGS) >> 11) & 0x0F;
1737         uint32 a1_width = ((0x04 | m) << e) >> 2;
1738         m = (REG(A2_FLAGS) >> 9) & 0x03, e = (REG(A2_FLAGS) >> 11) & 0x0F;
1739         uint32 a2_width = ((0x04 | m) << e) >> 2;
1740
1741         WriteLog("Blit!\n");
1742         WriteLog("  COMMAND  = %08X\n", cmd);
1743         WriteLog("  a1_base  = %08X\n", REG(A1_BASE));
1744         WriteLog("  a1_flags = %08X (%c %c %c %c%c . %c%c%c%c%c%c %c%c%c %c%c%c . %c%c)\n", REG(A1_FLAGS),
1745                 (REG(A1_FLAGS) & 0x100000 ? '1' : '0'),
1746                 (REG(A1_FLAGS) & 0x080000 ? '1' : '0'),
1747                 (REG(A1_FLAGS) & 0x040000 ? '1' : '0'),
1748                 (REG(A1_FLAGS) & 0x020000 ? '1' : '0'),
1749                 (REG(A1_FLAGS) & 0x010000 ? '1' : '0'),
1750                 (REG(A1_FLAGS) & 0x004000 ? '1' : '0'),
1751                 (REG(A1_FLAGS) & 0x002000 ? '1' : '0'),
1752                 (REG(A1_FLAGS) & 0x001000 ? '1' : '0'),
1753                 (REG(A1_FLAGS) & 0x000800 ? '1' : '0'),
1754                 (REG(A1_FLAGS) & 0x000400 ? '1' : '0'),
1755                 (REG(A1_FLAGS) & 0x000200 ? '1' : '0'),
1756                 (REG(A1_FLAGS) & 0x000100 ? '1' : '0'),
1757                 (REG(A1_FLAGS) & 0x000080 ? '1' : '0'),
1758                 (REG(A1_FLAGS) & 0x000040 ? '1' : '0'),
1759                 (REG(A1_FLAGS) & 0x000020 ? '1' : '0'),
1760                 (REG(A1_FLAGS) & 0x000010 ? '1' : '0'),
1761                 (REG(A1_FLAGS) & 0x000008 ? '1' : '0'),
1762                 (REG(A1_FLAGS) & 0x000002 ? '1' : '0'),
1763                 (REG(A1_FLAGS) & 0x000001 ? '1' : '0'));
1764         WriteLog("             pitch=%u, pixSz=%u, zOff=%u, width=%u, xCtrl=%u\n",
1765                 REG(A1_FLAGS) & 0x00003, (REG(A1_FLAGS) & 0x00038) >> 3,
1766                 (REG(A1_FLAGS) & 0x001C0) >> 6,  a1_width, (REG(A1_FLAGS) & 0x30000) >> 16);
1767         WriteLog("  a1_clip  = %u, %u (%08X)\n", GET16(blitter_ram, A1_CLIP + 2), GET16(blitter_ram, A1_CLIP + 0), GET32(blitter_ram, A1_CLIP));
1768         WriteLog("  a1_pixel = %d, %d (%08X)\n", (int16)GET16(blitter_ram, A1_PIXEL + 2), (int16)GET16(blitter_ram, A1_PIXEL + 0), GET32(blitter_ram, A1_PIXEL));
1769         WriteLog("  a1_step  = %d, %d (%08X)\n", (int16)GET16(blitter_ram, A1_STEP + 2), (int16)GET16(blitter_ram, A1_STEP + 0), GET32(blitter_ram, A1_STEP));
1770         WriteLog("  a1_fstep = %u, %u (%08X)\n", GET16(blitter_ram, A1_FSTEP + 2), GET16(blitter_ram, A1_FSTEP + 0), GET32(blitter_ram, A1_FSTEP));
1771         WriteLog("  a1_fpixel= %u, %u (%08X)\n", GET16(blitter_ram, A1_FPIXEL + 2), GET16(blitter_ram, A1_FPIXEL + 0), GET32(blitter_ram, A1_FPIXEL));
1772         WriteLog("  a1_inc   = %d, %d (%08X)\n", (int16)GET16(blitter_ram, A1_INC + 2), (int16)GET16(blitter_ram, A1_INC + 0), GET32(blitter_ram, A1_INC));
1773         WriteLog("  a1_finc  = %u, %u (%08X)\n", GET16(blitter_ram, A1_FINC + 2), GET16(blitter_ram, A1_FINC + 0), GET32(blitter_ram, A1_FINC));
1774
1775         WriteLog("  a2_base  = %08X\n", REG(A2_BASE));
1776         WriteLog("  a2_flags = %08X (%c %c %c %c%c %c %c%c%c%c%c%c %c%c%c %c%c%c . %c%c)\n", REG(A2_FLAGS),
1777                 (REG(A2_FLAGS) & 0x100000 ? '1' : '0'),
1778                 (REG(A2_FLAGS) & 0x080000 ? '1' : '0'),
1779                 (REG(A2_FLAGS) & 0x040000 ? '1' : '0'),
1780                 (REG(A2_FLAGS) & 0x020000 ? '1' : '0'),
1781                 (REG(A2_FLAGS) & 0x010000 ? '1' : '0'),
1782                 (REG(A2_FLAGS) & 0x008000 ? '1' : '0'),
1783                 (REG(A2_FLAGS) & 0x004000 ? '1' : '0'),
1784                 (REG(A2_FLAGS) & 0x002000 ? '1' : '0'),
1785                 (REG(A2_FLAGS) & 0x001000 ? '1' : '0'),
1786                 (REG(A2_FLAGS) & 0x000800 ? '1' : '0'),
1787                 (REG(A2_FLAGS) & 0x000400 ? '1' : '0'),
1788                 (REG(A2_FLAGS) & 0x000200 ? '1' : '0'),
1789                 (REG(A2_FLAGS) & 0x000100 ? '1' : '0'),
1790                 (REG(A2_FLAGS) & 0x000080 ? '1' : '0'),
1791                 (REG(A2_FLAGS) & 0x000040 ? '1' : '0'),
1792                 (REG(A2_FLAGS) & 0x000020 ? '1' : '0'),
1793                 (REG(A2_FLAGS) & 0x000010 ? '1' : '0'),
1794                 (REG(A2_FLAGS) & 0x000008 ? '1' : '0'),
1795                 (REG(A2_FLAGS) & 0x000002 ? '1' : '0'),
1796                 (REG(A2_FLAGS) & 0x000001 ? '1' : '0'));
1797         WriteLog("             pitch=%u, pixSz=%u, zOff=%u, width=%u, xCtrl=%u\n",
1798                 REG(A2_FLAGS) & 0x00003, (REG(A2_FLAGS) & 0x00038) >> 3,
1799                 (REG(A2_FLAGS) & 0x001C0) >> 6,  a2_width, (REG(A2_FLAGS) & 0x30000) >> 16);
1800         WriteLog("  a2_mask  = %u, %u (%08X)\n", GET16(blitter_ram, A2_MASK + 2), GET16(blitter_ram, A2_MASK + 0), GET32(blitter_ram, A2_MASK));
1801         WriteLog("  a2_pixel = %d, %d (%08X)\n", (int16)GET16(blitter_ram, A2_PIXEL + 2), (int16)GET16(blitter_ram, A2_PIXEL + 0), GET32(blitter_ram, A2_PIXEL));
1802         WriteLog("  a2_step  = %d, %d (%08X)\n", (int16)GET16(blitter_ram, A2_STEP + 2), (int16)GET16(blitter_ram, A2_STEP + 0), GET32(blitter_ram, A2_STEP));
1803
1804         WriteLog("  count    = %d x %d\n", GET16(blitter_ram, PIXLINECOUNTER + 2), GET16(blitter_ram, PIXLINECOUNTER));
1805
1806         WriteLog("  SRCEN    = %s\n", (SRCEN ? "1" : "0"));
1807         WriteLog("  SRCENZ   = %s\n", (SRCENZ ? "1" : "0"));
1808         WriteLog("  SRCENX   = %s\n", (SRCENX ? "1" : "0"));
1809         WriteLog("  DSTEN    = %s\n", (DSTEN ? "1" : "0"));
1810         WriteLog("  DSTENZ   = %s\n", (DSTENZ ? "1" : "0"));
1811         WriteLog("  DSTWRZ   = %s\n", (DSTWRZ ? "1" : "0"));
1812         WriteLog("  CLIPA1   = %s\n", (CLIPA1 ? "1" : "0"));
1813         WriteLog("  UPDA1F   = %s\n", (UPDA1F ? "1" : "0"));
1814         WriteLog("  UPDA1    = %s\n", (UPDA1 ? "1" : "0"));
1815         WriteLog("  UPDA2    = %s\n", (UPDA2 ? "1" : "0"));
1816         WriteLog("  DSTA2    = %s\n", (DSTA2 ? "1" : "0"));
1817         WriteLog("  ZOP      = %s %s %s\n", (Z_OP_INF ? "<" : ""), (Z_OP_EQU ? "=" : ""), (Z_OP_SUP ? ">" : ""));
1818         WriteLog("--LFUFUNC  = %s\n", opStr[(cmd >> 21) & 0x0F]);
1819         WriteLog("| PATDSEL  = %s (PD=%08X%08X)\n", (PATDSEL ? "1" : "0"), REG(PATTERNDATA), REG(PATTERNDATA + 4));
1820         WriteLog("--ADDDSEL  = %s\n", (ADDDSEL ? "1" : "0"));
1821         WriteLog("  CMPDST   = %s\n", (CMPDST ? "1" : "0"));
1822         WriteLog("  BCOMPEN  = %s\n", (BCOMPEN ? "1" : "0"));
1823         WriteLog("  DCOMPEN  = %s\n", (DCOMPEN ? "1" : "0"));
1824         WriteLog("  TOPBEN   = %s\n", (TOPBEN ? "1" : "0"));
1825         WriteLog("  TOPNEN   = %s\n", (TOPNEN ? "1" : "0"));
1826         WriteLog("  BKGWREN  = %s\n", (BKGWREN ? "1" : "0"));
1827         WriteLog("  GOURD    = %s (II=%08X, SD=%08X%08X)\n", (GOURD ? "1" : "0"), REG(INTENSITYINC), REG(SRCDATA), REG(SRCDATA + 4));
1828         WriteLog("  GOURZ    = %s (ZI=%08X, ZD=%08X%08X, SZ1=%08X%08X, SZ2=%08X%08X)\n", (GOURZ ? "1" : "0"), REG(ZINC), REG(DSTZ), REG(DSTZ + 4),
1829                 REG(SRCZINT), REG(SRCZINT + 4), REG(SRCZFRAC), REG(SRCZFRAC + 4));
1830         WriteLog("  SRCSHADE = %s\n", (SRCSHADE ? "1" : "0"));
1831 }
1832
1833
1834 #ifdef USE_MIDSUMMER_BLITTER
1835 //
1836 // Here's an attempt to write a blitter that conforms to the Midsummer specs--since
1837 // it's supposedly backwards compatible, it should work well...
1838 //
1839 //#define LOG_BLITTER_MEMORY_ACCESSES
1840
1841 #define DATINIT (false)
1842 #define TXTEXT  (false)
1843 #define POLYGON (false)
1844
1845 void BlitterMidsummer(uint32 cmd)
1846 {
1847 uint32 outer_loop, inner_loop, a1_addr, a2_addr;
1848 int32 a1_x, a1_y, a2_x, a2_y, a1_width, a2_width;
1849 uint8 a1_phrase_mode, a2_phrase_mode;
1850
1851         a1_addr = REG(A1_BASE) & 0xFFFFFFF8;
1852         a2_addr = REG(A2_BASE) & 0xFFFFFFF8;
1853         a1_x = (REG(A1_PIXEL) << 16) | (REG(A1_FPIXEL) & 0xFFFF);
1854         a1_y = (REG(A1_PIXEL) & 0xFFFF0000) | (REG(A1_FPIXEL) >> 16);
1855         uint32 m = (REG(A1_FLAGS) >> 9) & 0x03, e = (REG(A1_FLAGS) >> 11) & 0x0F;
1856         a1_width = ((0x04 | m) << e) >> 2;//*/
1857         a2_x = (REG(A2_PIXEL) & 0x0000FFFF) << 16;
1858         a2_y = (REG(A2_PIXEL) & 0xFFFF0000);
1859         m = (REG(A2_FLAGS) >> 9) & 0x03, e = (REG(A2_FLAGS) >> 11) & 0x0F;
1860         a2_width = ((0x04 | m) << e) >> 2;//*/
1861
1862         a1_phrase_mode = a2_phrase_mode = 0;
1863
1864         if ((blitter_ram[A1_FLAGS + 1] & 0x03) == 0)
1865                 a1_phrase_mode = 1;
1866
1867         if ((blitter_ram[A2_FLAGS + 1] & 0x03) == 0)
1868                 a2_phrase_mode = 1;
1869
1870 #define INNER0  (inner_loop == 0)
1871 #define OUTER0  (outer_loop == 0)
1872
1873 // $01800005 has SRCENX, may have to investigate further...
1874 // $00011008 has GOURD & DSTEN.
1875 // $41802F41 has SRCSHADE, CLIPA1
1876 /*bool logBlit = false;
1877 if (cmd != 0x00010200 && cmd != 0x01800001 && cmd != 0x01800005
1878         && cmd != 0x00011008 && cmd !=0x41802F41)
1879 {
1880         logBlit = true;
1881         LogBlit();
1882 }//*/
1883
1884         uint64 srcData = GET64(blitter_ram, SRCDATA), srcXtraData,
1885                 dstData = GET64(blitter_ram, DSTDATA), writeData;
1886         uint32 srcAddr, dstAddr;
1887         uint8 bitCount, a1PixelSize, a2PixelSize;
1888
1889         // JTRM says phrase mode only works for 8BPP or higher, so let's try this...
1890         uint32 phraseOffset[8] = { 8, 8, 8, 8, 4, 2, 0, 0 };
1891         uint8 pixelShift[8] = { 3, 2, 1, 0, 1, 2, 0, 0 };
1892
1893         a1PixelSize = (blitter_ram[A1_FLAGS + 3] >> 3) & 0x07;
1894         a2PixelSize = (blitter_ram[A2_FLAGS + 3] >> 3) & 0x07;
1895
1896         outer_loop = GET16(blitter_ram, PIXLINECOUNTER + 0);
1897
1898         if (outer_loop == 0)
1899                 outer_loop = 0x10000;
1900
1901         // We just list the states here and jump from state to state in order to
1902         // keep things somewhat clear. Optimization/cleanups later.
1903
1904 //idle:                                                 // Blitter is idle, and will not perform any bus activity
1905 /*
1906 idle         Blitter is off the bus, and no activity takes place.
1907 if GO    if DATINIT goto init_if
1908          else       goto inner
1909 */
1910         if (DATINIT)
1911                 goto init_if;
1912         else
1913                 goto inner;
1914
1915 /*
1916 inner        Inner loop is active, read and write cycles are performed
1917 */
1918 inner:                                                  // Run inner loop state machine (asserts step from its idle state)
1919         inner_loop = GET16(blitter_ram, PIXLINECOUNTER + 2);
1920
1921         if (inner_loop == 0)
1922                 inner_loop = 0x10000;
1923
1924 /*
1925 ------------------------------
1926 idle:                        Inactive, blitter is idle or passing round outer loop
1927 idle       Another state in the outer loop is active. No bus transfers are performed.
1928 if STEP
1929     if SRCENX goto sreadx
1930     else if TXTEXT goto txtread
1931     else if SRCEN goto sread
1932     else if DSTEN goto dread
1933     else if DSTENZ goto dzread
1934     else goto dwrite
1935 */
1936     if (SRCENX)
1937                 goto sreadx;
1938     else if (TXTEXT)
1939                 goto txtread;
1940     else if (SRCEN)
1941                 goto sread;
1942     else if (DSTEN)
1943                 goto dread;
1944     else if (DSTENZ)
1945                 goto dzread;
1946     else
1947                 goto dwrite;
1948
1949 /*
1950 sreadx     Extra source data read at the start of an inner loop pass.
1951 if STEP
1952     if SRCENZ goto szreadx
1953     else if TXTEXT goto txtread
1954     else if SRCEN goto sread
1955     else if DSTEN goto dread
1956     else if DSTENZ goto dzread
1957     else goto dwrite
1958 */
1959 sreadx:                                                 // Extra source data read
1960         if (SRCENZ)
1961                 goto szreadx;
1962         else if (TXTEXT)
1963                 goto txtread;
1964         else if (SRCEN)
1965                 goto sread;
1966         else if (DSTEN)
1967                 goto dread;
1968         else if (DSTENZ)
1969                 goto dzread;
1970         else
1971                 goto dwrite;
1972
1973 /*
1974 szreadx    Extra source Z read as the start of an inner loop pass.
1975 if STEP
1976     if TXTEXT goto txtread
1977     else goto sread
1978 */
1979 szreadx:                                                // Extra source Z read
1980         if (TXTEXT)
1981                 goto txtread;
1982         else
1983                 goto sread;
1984
1985 /*
1986 txtread    Read texture data from external memory. This state is only used for external texture.
1987            TEXTEXT is the condition TEXTMODE=1.
1988 if STEP
1989     if SRCEN goto sread
1990     else if DSTEN goto dread
1991     else if DSTENZ goto dzread
1992     else goto dwrite
1993 */
1994 txtread:                                                // Read external texture data
1995         if (SRCEN)
1996                 goto sread;
1997         else if (DSTEN)
1998                 goto dread;
1999         else if (DSTENZ)
2000                 goto dzread;
2001         else
2002                 goto dwrite;
2003
2004 /*
2005 sread      Source data read.
2006 if STEP
2007     if SRCENZ goto szread
2008     else if DSTEN goto dread
2009     else if DSTENZ goto dzread
2010     else goto dwrite
2011 */
2012 sread:                                                  // Source data read
2013 //The JTRM doesn't really specify the internal structure of the source data read, but I would
2014 //imagine that if it's in phrase mode that it starts by reading the phrase that the window is
2015 //pointing at. Likewise, the pixel (if in BPP 1, 2 & 4, chopped) otherwise. It probably still
2016 //transfers an entire phrase even in pixel mode.
2017 //Odd thought: Does it expand, e.g., 1 BPP pixels into 32 BPP internally? Hmm...
2018 //No. 
2019 /*
2020         a1_addr = REG(A1_BASE) & 0xFFFFFFF8;
2021         a2_addr = REG(A2_BASE) & 0xFFFFFFF8;
2022         a1_zoffs = (REG(A1_FLAGS) >> 6) & 7;
2023         a2_zoffs = (REG(A2_FLAGS) >> 6) & 7;
2024         xadd_a1_control = (REG(A1_FLAGS) >> 16) & 0x03;
2025         xadd_a2_control = (REG(A2_FLAGS) >> 16) & 0x03;
2026         a1_pitch = pitchValue[(REG(A1_FLAGS) & 0x03)];
2027         a2_pitch = pitchValue[(REG(A2_FLAGS) & 0x03)];
2028         n_pixels = REG(PIXLINECOUNTER) & 0xFFFF;
2029         n_lines = (REG(PIXLINECOUNTER) >> 16) & 0xFFFF;
2030         a1_x = (REG(A1_PIXEL) << 16) | (REG(A1_FPIXEL) & 0xFFFF);
2031         a1_y = (REG(A1_PIXEL) & 0xFFFF0000) | (REG(A1_FPIXEL) >> 16);
2032         a2_psize = 1 << ((REG(A2_FLAGS) >> 3) & 0x07);
2033         a1_psize = 1 << ((REG(A1_FLAGS) >> 3) & 0x07);
2034         a1_phrase_mode = 0;
2035         a2_phrase_mode = 0;
2036         a1_width = ((0x04 | m) << e) >> 2;
2037         a2_width = ((0x04 | m) << e) >> 2;
2038
2039         // write values back to registers 
2040         WREG(A1_PIXEL,  (a1_y & 0xFFFF0000) | ((a1_x >> 16) & 0xFFFF));
2041         WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xFFFF));
2042         WREG(A2_PIXEL,  (a2_y & 0xFFFF0000) | ((a2_x >> 16) & 0xFFFF));
2043 */
2044         // Calculate the address to be read...
2045
2046 //Need to fix phrase mode calcs here, since they should *step* by eight, not mulitply.
2047 //Also, need to fix various differing BPP modes here, since offset won't be correct except
2048 //for 8BPP. !!! FIX !!!
2049         srcAddr = (DSTA2 ? a1_addr : a2_addr);
2050
2051 /*      if ((DSTA2 ? a1_phrase_mode : a2_phrase_mode) == 1)
2052         {
2053                 srcAddr += (((DSTA2 ? a1_x : a2_x) >> 16)
2054                         + (((DSTA2 ? a1_y : a2_y) >> 16) * (DSTA2 ? a1_width : a2_width)));
2055         }
2056         else*/
2057         {
2058 //              uint32 pixAddr = ((DSTA2 ? a1_x : a2_x) >> 16)
2059 //                      + (((DSTA2 ? a1_y : a2_y) >> 16) * (DSTA2 ? a1_width : a2_width));
2060                 int32 pixAddr = (int16)((DSTA2 ? a1_x : a2_x) >> 16)
2061                         + ((int16)((DSTA2 ? a1_y : a2_y) >> 16) * (DSTA2 ? a1_width : a2_width));
2062
2063                 if ((DSTA2 ? a1PixelSize : a2PixelSize) < 3)
2064                         pixAddr >>= pixelShift[(DSTA2 ? a1PixelSize : a2PixelSize)];
2065                 else if ((DSTA2 ? a1PixelSize : a2PixelSize) > 3)
2066                         pixAddr <<= pixelShift[(DSTA2 ? a1PixelSize : a2PixelSize)];
2067
2068                 srcAddr += pixAddr;
2069         }
2070
2071         // And read it!
2072
2073         if ((DSTA2 ? a1_phrase_mode : a2_phrase_mode) == 1)
2074         {
2075                 srcData = ((uint64)JaguarReadLong(srcAddr, BLITTER) << 32)
2076                         | (uint64)JaguarReadLong(srcAddr + 4, BLITTER);
2077         }
2078         else
2079         {
2080 //1,2,&4BPP are wrong here... !!! FIX !!!
2081                 if ((DSTA2 ? a1PixelSize : a2PixelSize) == 0)           // 1 BPP
2082                         srcData = JaguarReadByte(srcAddr, BLITTER);
2083                 if ((DSTA2 ? a1PixelSize : a2PixelSize) == 1)           // 2 BPP
2084                         srcData = JaguarReadByte(srcAddr, BLITTER);
2085                 if ((DSTA2 ? a1PixelSize : a2PixelSize) == 2)           // 4 BPP
2086                         srcData = JaguarReadByte(srcAddr, BLITTER);
2087                 if ((DSTA2 ? a1PixelSize : a2PixelSize) == 3)           // 8 BPP
2088                         srcData = JaguarReadByte(srcAddr, BLITTER);
2089                 if ((DSTA2 ? a1PixelSize : a2PixelSize) == 4)           // 16 BPP
2090                         srcData = JaguarReadWord(srcAddr, BLITTER);
2091                 if ((DSTA2 ? a1PixelSize : a2PixelSize) == 5)           // 32 BPP
2092                         srcData = JaguarReadLong(srcAddr, BLITTER);
2093         }
2094
2095 #ifdef LOG_BLITTER_MEMORY_ACCESSES
2096 if (logBlit)
2097         WriteLog("BLITTER: srcAddr=%08X,   srcData=%08X %08X\n", srcAddr, (uint32)(srcData >> 32), (uint32)(srcData & 0xFFFFFFFF));
2098 #endif
2099
2100         if (SRCENZ)
2101                 goto szread;
2102         else if (DSTEN)
2103                 goto dread;
2104         else if (DSTENZ)
2105                 goto dzread;
2106         else
2107                 goto dwrite;
2108
2109 szread:                                                 // Source Z read
2110 /*
2111 szread     Source Z read.
2112 if STEP
2113     if DSTEN goto dread
2114     else if DSTENZ goto dzread
2115     else goto dwrite
2116 */
2117         if (DSTEN)
2118                 goto dread;
2119         else if (DSTENZ)
2120                 goto dzread;
2121         else
2122                 goto dwrite;
2123
2124 dread:                                                  // Destination data read
2125 /*
2126 dread      Destination data read.
2127 if STEP
2128     if DSTENZ goto dzread
2129     else goto dwrite
2130 */
2131         // Calculate the destination address to be read...
2132
2133 //Need to fix phrase mode calcs here, since they should *step* by eight, not mulitply.
2134 //Also, need to fix various differing BPP modes here, since offset won't be correct except
2135 //for 8BPP. !!! FIX !!!
2136         dstAddr = (DSTA2 ? a2_addr : a1_addr);
2137
2138         {
2139 //      uint32 pixAddr = ((DSTA2 ? a2_x : a1_x) >> 16)
2140 //              + (((DSTA2 ? a2_y : a1_y) >> 16) * (DSTA2 ? a2_width : a1_width));
2141         int32 pixAddr = (int16)((DSTA2 ? a2_x : a1_x) >> 16)
2142                 + ((int16)((DSTA2 ? a2_y : a1_y) >> 16) * (DSTA2 ? a2_width : a1_width));
2143
2144         if ((DSTA2 ? a2PixelSize : a1PixelSize) < 3)
2145                 pixAddr >>= pixelShift[(DSTA2 ? a2PixelSize : a1PixelSize)];
2146         else if ((DSTA2 ? a2PixelSize : a1PixelSize) > 3)
2147                 pixAddr <<= pixelShift[(DSTA2 ? a2PixelSize : a1PixelSize)];
2148
2149         dstAddr += pixAddr;
2150         }
2151
2152         // And read it!
2153
2154         if ((DSTA2 ? a2_phrase_mode : a1_phrase_mode) == 1)
2155         {
2156                 dstData = ((uint64)JaguarReadLong(srcAddr, BLITTER) << 32)
2157                         | (uint64)JaguarReadLong(srcAddr + 4, BLITTER);
2158         }
2159         else
2160         {
2161 //1,2,&4BPP are wrong here... !!! FIX !!!
2162                 if ((DSTA2 ? a2PixelSize : a1PixelSize) == 0)           // 1 BPP
2163                         dstData = JaguarReadByte(dstAddr, BLITTER);
2164                 if ((DSTA2 ? a2PixelSize : a1PixelSize) == 1)           // 2 BPP
2165                         dstData = JaguarReadByte(dstAddr, BLITTER);
2166                 if ((DSTA2 ? a2PixelSize : a1PixelSize) == 2)           // 4 BPP
2167                         dstData = JaguarReadByte(dstAddr, BLITTER);
2168                 if ((DSTA2 ? a2PixelSize : a1PixelSize) == 3)           // 8 BPP
2169                         dstData = JaguarReadByte(dstAddr, BLITTER);
2170                 if ((DSTA2 ? a2PixelSize : a1PixelSize) == 4)           // 16 BPP
2171                         dstData = JaguarReadWord(dstAddr, BLITTER);
2172                 if ((DSTA2 ? a2PixelSize : a1PixelSize) == 5)           // 32 BPP
2173                         dstData = JaguarReadLong(dstAddr, BLITTER);
2174         }
2175
2176 #ifdef LOG_BLITTER_MEMORY_ACCESSES
2177 if (logBlit)
2178         WriteLog("BLITTER (dread): dstAddr=%08X,   dstData=%08X %08X\n", dstAddr, (uint32)(dstData >> 32), (uint32)(dstData & 0xFFFFFFFF));
2179 #endif
2180
2181         if (DSTENZ)
2182                 goto dzread;
2183         else
2184                 goto dwrite;
2185
2186 dzread:                                                 // Destination Z read
2187 /*
2188 dzread     Destination Z read.
2189 if STEP goto dwrite
2190 */
2191         goto dwrite;
2192
2193 dwrite:                                                 // Destination data write
2194 /*
2195 dwrite     Destination write. Every pass round the inner loop must go through this state..
2196 if STEP
2197     if DSTWRZ goto dzwrite
2198     else if INNER0 goto idle
2199     else if TXTEXT goto txtread
2200     else if SRCEN goto sread
2201     else if DSTEN goto dread
2202     else if DSTENZ goto dzread
2203     else goto dwrite
2204 */
2205 /*
2206 Blit!
2207   a1_base  = 00100000
2208   a1_pitch = 0
2209   a1_psize = 16
2210   a1_width = 320
2211   a1_xadd  = 1.000000 (phrase=0)
2212   a1_yadd  = 0.000000
2213   a1_x     = 159.000000
2214   a1_y     = 1.000000
2215   a1_zoffs = 0
2216   a2_base  = 000095D0
2217   a2_pitch = 0
2218   a2_psize = 16
2219   a2_width = 256
2220   a2_xadd  = 1.000000 (phrase=1)
2221   a2_yadd  = 0.000000
2222   a2_x     = 2.000000
2223   a2_y     = 0.000000
2224   a2_mask_x= 0xFFFFFFFF
2225   a2_mask_y= 0xFFFFFFFF
2226   a2_zoffs = 0
2227   count    = 2 x 1
2228   COMMAND  = 00011008
2229   SRCEN    = 0
2230   DSTEN    = 1
2231   UPDA1F   = 0
2232   UPDA1    = 0
2233   UPDA2    = 0
2234   DSTA2    = 0
2235 --LFUFUNC  = LFU_CLEAR
2236 | PATDSEL  = 1 (PD=77C7 7700 7700 7700)
2237 --ADDDSEL  = 0
2238   GOURD    = 1 (II=00FC 1A00, SD=FF00 0000 0000 0000)
2239 */
2240
2241 //Still need to do CLIPA1 and SRCSHADE and GOURD and GOURZ...
2242
2243         // Check clipping...
2244
2245         if (CLIPA1)
2246         {
2247                 uint16 x = a1_x >> 16, y = a1_y >> 16;
2248
2249                 if (x >= GET16(blitter_ram, A1_CLIP + 2) || y >= GET16(blitter_ram, A1_CLIP))
2250                         goto inhibitWrite;
2251         }
2252
2253         // Figure out what gets written...
2254         
2255         if (PATDSEL)
2256         {
2257                 writeData = GET64(blitter_ram, PATTERNDATA);
2258 //GOURD works properly only in 16BPP mode...
2259 //SRCDATA holds the intensity fractions...
2260 //Does GOURD get calc'ed here or somewhere else???
2261 //Temporary testing kludge...
2262 //if (GOURD)
2263 //   writeData >>= 48;
2264 //      writeData = 0xFF88;
2265 //OK, it's not writing an entire strip of pixels... Why?
2266 //bad incrementing, that's why!
2267         }
2268         else if (ADDDSEL)
2269         {
2270                 // Apparently this only works with 16-bit pixels. Not sure if it works in phrase mode either.
2271 //Also, take TOPBEN & TOPNEN into account here as well...
2272                 writeData = srcData + dstData;
2273         }
2274         else    // LFUFUNC is the default...
2275         {
2276                 writeData = 0;
2277                 
2278                 if (LFU_NAN)
2279                         writeData |= ~srcData & ~dstData;
2280                 if (LFU_NA)
2281                         writeData |= ~srcData & dstData;
2282                 if (LFU_AN)
2283                         writeData |= srcData & ~dstData;
2284                 if (LFU_A)
2285                         writeData |= srcData & dstData;
2286         }
2287
2288         // Calculate the address to be written...
2289
2290         dstAddr = (DSTA2 ? a2_addr : a1_addr);
2291
2292 /*      if ((DSTA2 ? a2_phrase_mode : a1_phrase_mode) == 1)
2293         {
2294 //both of these calculate the wrong address because they don't take into account
2295 //pixel sizes...
2296                 dstAddr += ((DSTA2 ? a2_x : a1_x) >> 16)
2297                         + (((DSTA2 ? a2_y : a1_y) >> 16) * (DSTA2 ? a2_width : a1_width));
2298         }
2299         else*/
2300         {
2301 /*              dstAddr += ((DSTA2 ? a2_x : a1_x) >> 16)
2302                         + (((DSTA2 ? a2_y : a1_y) >> 16) * (DSTA2 ? a2_width : a1_width));*/
2303 //              uint32 pixAddr = ((DSTA2 ? a2_x : a1_x) >> 16)
2304 //                      + (((DSTA2 ? a2_y : a1_y) >> 16) * (DSTA2 ? a2_width : a1_width));
2305                 int32 pixAddr = (int16)((DSTA2 ? a2_x : a1_x) >> 16)
2306                         + ((int16)((DSTA2 ? a2_y : a1_y) >> 16) * (DSTA2 ? a2_width : a1_width));
2307
2308                 if ((DSTA2 ? a2PixelSize : a1PixelSize) < 3)
2309                         pixAddr >>= pixelShift[(DSTA2 ? a2PixelSize : a1PixelSize)];
2310                 else if ((DSTA2 ? a2PixelSize : a1PixelSize) > 3)
2311                         pixAddr <<= pixelShift[(DSTA2 ? a2PixelSize : a1PixelSize)];
2312
2313                 dstAddr += pixAddr;
2314         }
2315
2316         // And write it!
2317
2318         if ((DSTA2 ? a2_phrase_mode : a1_phrase_mode) == 1)
2319         {
2320                 JaguarWriteLong(dstAddr, writeData >> 32, BLITTER);
2321                 JaguarWriteLong(dstAddr + 4, writeData & 0xFFFFFFFF, BLITTER);
2322         }
2323         else
2324         {
2325 //1,2,&4BPP are wrong here... !!! FIX !!!
2326                 if ((DSTA2 ? a2PixelSize : a1PixelSize) == 0)           // 1 BPP
2327                         JaguarWriteByte(dstAddr, writeData, BLITTER);
2328                 if ((DSTA2 ? a2PixelSize : a1PixelSize) == 1)           // 2 BPP
2329                         JaguarWriteByte(dstAddr, writeData, BLITTER);
2330                 if ((DSTA2 ? a2PixelSize : a1PixelSize) == 2)           // 4 BPP
2331                         JaguarWriteByte(dstAddr, writeData, BLITTER);
2332                 if ((DSTA2 ? a2PixelSize : a1PixelSize) == 3)           // 8 BPP
2333                         JaguarWriteByte(dstAddr, writeData, BLITTER);
2334                 if ((DSTA2 ? a2PixelSize : a1PixelSize) == 4)           // 16 BPP
2335                         JaguarWriteWord(dstAddr, writeData, BLITTER);
2336                 if ((DSTA2 ? a2PixelSize : a1PixelSize) == 5)           // 32 BPP
2337                         JaguarWriteLong(dstAddr, writeData, BLITTER);
2338         }
2339
2340 #ifdef LOG_BLITTER_MEMORY_ACCESSES
2341 if (logBlit)
2342         WriteLog("BLITTER: dstAddr=%08X, writeData=%08X %08X\n", dstAddr, (uint32)(writeData >> 32), (uint32)(writeData & 0xFFFFFFFF));
2343 #endif
2344
2345 inhibitWrite://Should this go here? or on the other side of the X/Y incrementing?
2346 //Seems OK here... for now.
2347
2348 // Do funky X/Y incrementation here as well... !!! FIX !!!
2349
2350         // Handle A1 channel stepping
2351
2352         if ((blitter_ram[A1_FLAGS + 1] & 0x03) == 0)
2353                 a1_x += phraseOffset[a1PixelSize] << 16;
2354         else if ((blitter_ram[A1_FLAGS + 1] & 0x03) == 1)
2355                 a1_x += (blitter_ram[A1_FLAGS + 1] & 0x08 ? -1 << 16 : 1 << 16);
2356 /*      else if ((blitter_ram[A1_FLAGS + 1] & 0x03) == 2)
2357                 a1_x += 0 << 16;                              */
2358         else if ((blitter_ram[A1_FLAGS + 1] & 0x03) == 3)
2359         {
2360 //Always add the FINC here??? That was the problem with the BIOS screen... So perhaps.
2361                 a1_x += GET16(blitter_ram, A1_FINC + 2);
2362                 a1_y += GET16(blitter_ram, A1_FINC + 0);
2363
2364                 a1_x += GET16(blitter_ram, A1_INC + 2) << 16;
2365                 a1_y += GET16(blitter_ram, A1_INC + 0) << 16;
2366         }
2367
2368         if ((blitter_ram[A1_FLAGS + 1] & 0x04) && (blitter_ram[A1_FLAGS + 1] & 0x03 != 3))
2369                 a1_y += (blitter_ram[A1_FLAGS + 1] & 0x10 ? -1 << 16 : 1 << 16);
2370
2371         // Handle A2 channel stepping
2372
2373         if ((blitter_ram[A2_FLAGS + 1] & 0x03) == 0)
2374                 a2_x += phraseOffset[a2PixelSize] << 16;
2375         else if ((blitter_ram[A2_FLAGS + 1] & 0x03) == 1)
2376                 a2_x += (blitter_ram[A2_FLAGS + 1] & 0x08 ? -1 << 16 : 1 << 16);
2377 /*      else if ((blitter_ram[A2_FLAGS + 1] & 0x03) == 2)
2378                 a2_x += 0 << 16;                              */
2379         
2380         if (blitter_ram[A2_FLAGS + 1] & 0x04)
2381                 a2_y += (blitter_ram[A2_FLAGS + 1] & 0x10 ? -1 << 16 : 1 << 16);
2382
2383 //Need to fix this so that it subtracts (saturating, of course) the correct number of pixels
2384 //in phrase mode... !!! FIX !!! [DONE]
2385 //Need to fix this so that it counts down the correct item. Does it count the
2386 //source or the destination phrase mode???
2387 //It shouldn't matter, because we *should* end up processing the same amount
2388 //the same number of pixels... Not sure though.
2389         if ((DSTA2 ? a2_phrase_mode : a1_phrase_mode) == 1)
2390         {
2391                 if (inner_loop < phraseOffset[DSTA2 ? a2PixelSize : a1PixelSize])
2392                         inner_loop = 0;
2393                 else
2394                         inner_loop -= phraseOffset[DSTA2 ? a2PixelSize : a1PixelSize];
2395         }
2396         else
2397                 inner_loop--;
2398
2399
2400         if (DSTWRZ)
2401                 goto dzwrite;
2402         else if (INNER0)
2403                 goto indone;
2404         else if (TXTEXT)
2405                 goto txtread;
2406         else if (SRCEN)
2407                 goto sread;
2408         else if (DSTEN)
2409                 goto dread;
2410         else if (DSTENZ)
2411                 goto dzread;
2412         else
2413                 goto dwrite;
2414
2415 dzwrite:                                                // Destination Z write
2416 /*
2417 dzwrite    Destination Z write.
2418 if STEP
2419     if INNER0 goto idle
2420     else if TXTEXT goto txtread
2421     else if SRCEN goto sread
2422     else if DSTEN goto dread
2423     else if DSTENZ goto dzread
2424     else goto dwrite
2425 */
2426         if (INNER0)
2427                 goto indone;
2428         else if (TXTEXT)
2429                 goto txtread;
2430         else if (SRCEN)
2431                 goto sread;
2432         else if (DSTEN)
2433                 goto dread;
2434         else if (DSTENZ)
2435                 goto dzread;
2436         else
2437                 goto dwrite;
2438
2439 /*
2440 ------------------------------
2441 if INDONE if OUTER0 goto idle
2442 else if UPDA1F        goto a1fupdate
2443 else if UPDA1         goto a1update
2444 else if GOURZ.POLYGON goto zfupdate
2445 else if UPDA2         goto a2update
2446 else if DATINIT       goto init_if
2447 else restart inner
2448 */
2449 indone:
2450         outer_loop--;
2451
2452
2453         if (OUTER0)
2454                 goto blitter_done;
2455         else if (UPDA1F)
2456                 goto a1fupdate;
2457         else if (UPDA1)
2458                 goto a1update;
2459 //kill this, for now...
2460 //      else if (GOURZ.POLYGON)
2461 //              goto zfupdate;
2462         else if (UPDA2)
2463                 goto a2update;
2464         else if (DATINIT)
2465                 goto init_if;
2466         else
2467                 goto inner;
2468
2469 a1fupdate:                                              // Update A1 pointer fractions and more (see below)
2470 /*
2471 a1fupdate    A1 step fraction is added to A1 pointer fraction
2472              POLYGON true: A1 step delta X and Y fraction parts are added to the A1
2473                          step X and Y fraction parts (the value prior to this add is used for
2474                          the step to pointer add).
2475              POLYGON true: inner count step fraction is added to the inner count
2476                          fraction part
2477              POLYGON.GOURD true: the I fraction step is added to the computed
2478                          intensity fraction parts +
2479              POLYGON.GOURD true: the I fraction step delta is added to the I
2480                          fraction step
2481 goto a1update
2482 */
2483 /*
2484 #define A1_PIXEL                ((uint32)0x0C)  // Integer part of the pixel (Y.i and X.i)
2485 #define A1_STEP                 ((uint32)0x10)  // Integer part of the step
2486 #define A1_FSTEP                ((uint32)0x14)  // Fractional part of the step
2487 #define A1_FPIXEL               ((uint32)0x18)  // Fractional part of the pixel (Y.f and X.f)
2488 */
2489
2490 // This is all kinda murky. All we have are the Midsummer docs to give us any guidance,
2491 // and it's incomplete or filled with errors (like above). Aarrrgggghhhhh!
2492
2493 //This isn't right. Is it? I don't think the fractional parts are signed...
2494 //      a1_x += (int32)((int16)GET16(blitter_ram, A1_FSTEP + 2));
2495 //      a1_y += (int32)((int16)GET16(blitter_ram, A1_FSTEP + 0));
2496         a1_x += GET16(blitter_ram, A1_FSTEP + 2);
2497         a1_y += GET16(blitter_ram, A1_FSTEP + 0);
2498
2499         goto a1update;
2500
2501 a1update:                                               // Update A1 pointer integers
2502 /*
2503 a1update     A1 step is added to A1 pointer, with carry from the fractional add
2504              POLYGON true: A1 step delta X and Y integer parts are added to the A1
2505                          step X and Y integer parts, with carry from the corresponding
2506                          fractional part add (again, the value prior to this add is used for
2507                          the step to pointer add).
2508              POLYGON true: inner count step is added to the inner count, with carry
2509              POLYGON.GOURD true: the I step is added to the computed intensities,
2510                          with carry +
2511              POLYGON.GOURD true: the I step delta is added to the I step, with
2512                          carry the texture X and Y step delta values are added to the X and Y
2513                          step values.
2514 if GOURZ.POLYGON goto zfupdate
2515 else if UPDA2 goto a2update
2516 else if DATINIT goto init_if
2517 else restart inner
2518 */
2519         a1_x += (int32)(GET16(blitter_ram, A1_STEP + 2) << 16);
2520         a1_y += (int32)(GET16(blitter_ram, A1_STEP + 0) << 16);
2521
2522
2523 //kill this, for now...
2524 //      if (GOURZ.POLYGON)
2525         if (false)
2526                 goto zfupdate;
2527         else if (UPDA2)
2528                 goto a2update;
2529         else if (DATINIT)
2530                 goto init_if;
2531         else
2532                 goto inner;
2533
2534 zfupdate:                                               // Update computed Z step fractions
2535 /*
2536 zfupdate     the Z fraction step is added to the computed Z fraction parts +
2537              the Z fraction step delta is added to the Z fraction step
2538 goto zupdate
2539 */
2540         goto zupdate;
2541
2542 zupdate:                                                // Update computed Z step integers
2543 /*
2544 zupdate      the Z step is added to the computed Zs, with carry +
2545              the Z step delta is added to the Z step, with carry
2546 if UPDA2 goto a2update
2547 else if DATINIT goto init_if
2548 else restart inner
2549 */
2550         if (UPDA2)
2551                 goto a2update;
2552         else if (DATINIT)
2553                 goto init_if;
2554         else
2555                 goto inner;
2556
2557 a2update:                                               // Update A2 pointer
2558 /*
2559 a2update     A2 step is added to the A2 pointer
2560 if DATINIT goto init_if
2561 else restart inner
2562 */
2563         a2_x += (int32)(GET16(blitter_ram, A2_STEP + 2) << 16);
2564         a2_y += (int32)(GET16(blitter_ram, A2_STEP + 0) << 16);
2565
2566
2567         if (DATINIT)
2568                 goto init_if;
2569         else
2570                 goto inner;
2571
2572 init_if:                                                // Initialise intensity fractions and texture X
2573 /*
2574 init_if      Initialise the fractional part of the computed intensity fields, from
2575              the increment and step registers. The texture X integer and fractional
2576                          parts can also be initialised.
2577 goto     init_ii
2578 */
2579         goto init_ii;
2580
2581 init_ii:                                                // Initialise intensity integers and texture Y
2582 /*
2583 init_ii      Initialise the integer part of the computed intensity, and texture Y
2584              integer and fractional parts
2585 if GOURZ goto init_zf
2586 else     goto inner
2587 */
2588         if (GOURZ)
2589                 goto init_zf;
2590         else
2591             goto inner;
2592
2593 init_zf:                                                // Initialise Z fractions
2594 /*
2595 init_zf      Initialise the fractional part of the computed Z fields.
2596 goto init_zi
2597 */
2598         goto init_zi;
2599
2600 init_zi:                                                // Initialise Z integers
2601 /*
2602 init_zi      Initialise the integer part of the computed Z fields.
2603 goto inner
2604 */
2605         goto inner;
2606
2607
2608 /*
2609 The outer loop state machine fires off the inner loop, and controls the updating
2610 process between passes through the inner loop.
2611
2612 + -- these functions are irrelevant if the DATINIT function is enabled, which it
2613      will normally be.
2614
2615 All these states will complete in one clock cycle, with the exception of the idle
2616 state, which means the blitter is quiescent; and the inner state, which takes as
2617 long as is required to complete one strip of pixels. It is therefore possible for
2618 the blitter to spend a maximum of nine clock cycles of inactivity between passes
2619 through the inner loop.
2620 */
2621
2622 blitter_done:
2623         {}
2624 }
2625 #endif
2626
2627
2628 //
2629 // Here's attempt #2--taken from the Oberon chip specs!
2630 //
2631
2632 #ifdef USE_MIDSUMMER_BLITTER_MKII
2633
2634 void ADDRGEN(uint32 &, uint32 &, bool, bool,
2635         uint16, uint16, uint32, uint8, uint8, uint8, uint8,
2636         uint16, uint16, uint32, uint8, uint8, uint8, uint8);
2637 void ADDARRAY(uint16 * addq, uint8 daddasel, uint8 daddbsel, uint8 daddmode,
2638         uint64 dstd, uint32 iinc, uint8 initcin[], uint64 initinc, uint16 initpix,
2639         uint32 istep, uint64 patd, uint64 srcd, uint64 srcz1, uint64 srcz2,
2640         uint32 zinc, uint32 zstep);
2641 void ADD16SAT(uint16 &r, uint8 &co, uint16 a, uint16 b, uint8 cin, bool sat, bool eightbit, bool hicinh);
2642 void ADDAMUX(int16 &adda_x, int16 &adda_y, uint8 addasel, int16 a1_step_x, int16 a1_step_y,
2643         int16 a1_stepf_x, int16 a1_stepf_y, int16 a2_step_x, int16 a2_step_y,
2644         int16 a1_inc_x, int16 a1_inc_y, int16 a1_incf_x, int16 a1_incf_y, uint8 adda_xconst,
2645         bool adda_yconst, bool addareg, bool suba_x, bool suba_y);
2646 void ADDBMUX(int16 &addb_x, int16 &addb_y, uint8 addbsel, int16 a1_x, int16 a1_y,
2647         int16 a2_x, int16 a2_y, int16 a1_frac_x, int16 a1_frac_y);
2648 void DATAMUX(int16 &data_x, int16 &data_y, uint32 gpu_din, int16 addq_x, int16 addq_y, bool addqsel);
2649 void ADDRADD(int16 &addq_x, int16 &addq_y, bool a1fracldi,
2650         uint16 adda_x, uint16 adda_y, uint16 addb_x, uint16 addb_y, uint8 modx, bool suba_x, bool suba_y);
2651 void DATA(uint64 &wdata, uint8 &dcomp, uint8 &zcomp, bool &nowrite,
2652         bool big_pix, bool cmpdst, uint8 daddasel, uint8 daddbsel, uint8 daddmode, bool daddq_sel, uint8 data_sel,
2653         uint8 dbinh, uint8 dend, uint8 dstart, uint64 dstd, uint32 iinc, uint8 lfu_func, uint64 &patd, bool patdadd,
2654         bool phrase_mode, uint64 srcd, bool srcdread, bool srczread, bool srcz2add, uint8 zmode,
2655         bool bcompen, bool bkgwren, bool dcompen, uint8 icount, uint8 pixsize,
2656         uint64 &srcz, uint64 dstz, uint32 zinc);
2657 void COMP_CTRL(uint8 &dbinh, bool &nowrite,
2658         bool bcompen, bool big_pix, bool bkgwren, uint8 dcomp, bool dcompen, uint8 icount,
2659         uint8 pixsize, bool phrase_mode, uint8 srcd, uint8 zcomp);
2660 #define VERBOSE_BLITTER_LOGGING
2661 bool logBlit = false;
2662
2663 void BlitterMidsummer2(void)
2664 {
2665         // Here's what the specs say the state machine does. Note that this can probably be
2666         // greatly simplified (also, it's different from what John has in his Oberon docs):
2667 //Will remove stuff that isn't in Jaguar I once fully described (stuff like texture won't
2668 //be described here at all)...
2669
2670         uint32 cmd = GET32(blitter_ram, COMMAND);
2671
2672 logBlit = false;
2673 if (
2674         cmd != 0x00010200 &&    // PATDSEL
2675         cmd != 0x01800001               // SRCEN LFUFUNC=C
2676         && cmd != 0x01800005
2677 //Boot ROM ATARI letters:
2678         && cmd != 0x00011008    // DSTEN GOURD PATDSEL
2679 //Boot ROM spinning cube:
2680         && cmd != 0x41802F41    // SRCEN CLIP_A1 UPDA1 UPDA1F UPDA2 DSTA2 GOURZ ZMODE=0 LFUFUNC=C SRCSHADE
2681 //T2K intro screen:
2682         && cmd != 0x01800E01    // SRCEN UPDA1 UPDA2 DSTA2 LFUFUNC=C
2683 //T2K TEMPEST letters:
2684         && cmd != 0x09800741    // SRCEN CLIP_A1 UPDA1 UPDA1F UPDA2 LFUFUNC=C DCOMPEN
2685 //Static letters on Cybermorph intro screen:
2686         && cmd != 0x09800609    // SRCEN DSTEN UPDA1 UPDA2 LFUFUNC=C DCOMPEN
2687 //Static pic on title screen:
2688         && cmd != 0x01800601    // SRCEN UPDA1 UPDA2 LFUFUNC=C
2689 //Turning letters on Cybermorph intro screen:
2690 //      && cmd != 0x09800F41    // SRCEN CLIP_A1 UPDA1 UPDA1F UPDA2 DSTA2 LFUFUNC=C DCOMPEN
2691         && cmd != 0x00113078    // DSTEN DSTENZ DSTWRZ CLIP_A1 GOURD GOURZ PATDSEL ZMODE=4
2692         && cmd != 0x09900F39    // SRCEN DSTEN DSTENZ DSTWRZ UPDA1 UPDA1F UPDA2 DSTA2 ZMODE=4 LFUFUNC=C DCOMPEN
2693         && cmd != 0x09800209    // SRCEN DSTEN UPDA1 LFUFUNC=C DCOMPEN
2694         && cmd != 0x00011200    // UPDA1 GOURD PATDSEL
2695 //Start of Hover Strike (clearing screen):
2696         && cmd != 0x00010000    // PATDSEL
2697 //Hover Strike text:
2698         && cmd != 0x1401060C    // SRCENX DSTEN UPDA1 UPDA2 PATDSEL BCOMPEN BKGWREN
2699 //Hover Strike 3D stuff
2700         && cmd != 0x01902839    // SRCEN DSTEN DSTENZ DSTWRZ DSTA2 GOURZ ZMODE=4 LFUFUNC=C
2701 //Hover Strike darkening on intro to play (briefing) screen
2702         && cmd != 0x00020208    // DSTEN UPDA1 ADDDSEL
2703 //Trevor McFur stuff:
2704         && cmd != 0x05810601    // SRCEN UPDA1 UPDA2 PATDSEL BCOMPEN
2705         && cmd != 0x01800201    // SRCEN UPDA1 LFUFUNC=C
2706 //T2K:
2707         && cmd != 0x00011000    // GOURD PATDSEL
2708         && cmd != 0x00011040    // CLIP_A1 GOURD PATDSEL
2709 //Checkered flag:
2710         && cmd != 0x01800000    // LFUFUNC=C
2711         && cmd != 0x01800401    // 
2712         && cmd != 0x01800040    // 
2713         && cmd != 0x00020008    // 
2714 //      && cmd != 0x09800F41    // SRCEN CLIP_A1 UPDA1 UPDA1F UPDA2 DSTA2 LFUFUNC=C DCOMPEN
2715         )
2716         logBlit = true;//*/
2717 //logBlit = true;
2718 if (blit_start_log == 0)        // Wait for the signal...
2719         logBlit = false;//*/
2720 /*
2721 Some T2K unique blits:
2722 logBlit = F, cmd = 00010200 *
2723 logBlit = F, cmd = 00011000
2724 logBlit = F, cmd = 00011040
2725 logBlit = F, cmd = 01800005 *
2726 logBlit = F, cmd = 09800741 *
2727
2728 Hover Strike mission selection screen:
2729 Blit! (CMD = 01902839)  // SRCEN DSTEN DSTENZ DSTWRZ DSTA2 GOURZ ZMODE=4 LFUFUNC=C
2730
2731 Checkered Flag blits in the screw up zone:
2732 Blit! (CMD = 01800001)  // SRCEN LFUFUNC=C
2733 Blit! (CMD = 01800000)  // LFUFUNC=C
2734 Blit! (CMD = 00010000)  // PATDSEL
2735
2736 Wolfenstein 3D in the fuckup zone:
2737 Blit! (CMD = 01800000)  // LFUFUNC=C
2738 */
2739
2740 //printf("logBlit = %s, cmd = %08X\n", (logBlit ? "T" : "F"), cmd);
2741 //fflush(stdout);
2742 //logBlit = true;
2743
2744 /*
2745 Blit! (CMD = 00011040)
2746 Flags: CLIP_A1 GOURD PATDSEL
2747   count = 18 x 1
2748   a1_base = 00100000, a2_base = 0081F6A8
2749   a1_x = 00A7, a1_y = 0014, a1_frac_x = 0000, a1_frac_y = 0000, a2_x = 0001, a2_y = 0000
2750   a1_step_x = FE80, a1_step_y = 0001, a1_stepf_x = 0000, a1_stepf_y = 0000, a2_step_x = FFF8, a2_step_y = 0001
2751   a1_inc_x = 0001, a1_inc_y = 0000, a1_incf_x = 0000, a1_incf_y = 0000
2752   a1_win_x = 0180, a1_win_y = 0118, a2_mask_x = 0000, a2_mask_y = 0000
2753   a2_mask=F a1add=+phr/+0 a2add=+phr/+0
2754   a1_pixsize = 4, a2_pixsize = 4
2755 */
2756 //Testing T2K...
2757 /*logBlit = false;
2758 if (cmd == 0x00011040
2759         && (GET16(blitter_ram, A1_PIXEL + 2) == 0x00A7) && (GET16(blitter_ram, A1_PIXEL + 0) == 0x0014)
2760         && (GET16(blitter_ram, A2_PIXEL + 2) == 0x0001) && (GET16(blitter_ram, A2_PIXEL + 0) == 0x0000)
2761         && (GET16(blitter_ram, PIXLINECOUNTER + 2) == 18))
2762         logBlit = true;*/
2763
2764         // Line states passed in via the command register
2765
2766         bool srcen = (SRCEN), srcenx = (SRCENX), srcenz = (SRCENZ),
2767                 dsten = (DSTEN), dstenz = (DSTENZ), dstwrz = (DSTWRZ), clip_a1 = (CLIPA1),
2768                 upda1 = (UPDA1), upda1f = (UPDA1F), upda2 = (UPDA2), dsta2 = (DSTA2),
2769                 gourd = (GOURD), gourz = (GOURZ), topben = (TOPBEN), topnen = (TOPNEN),
2770                 patdsel = (PATDSEL), adddsel = (ADDDSEL), cmpdst = (CMPDST), bcompen = (BCOMPEN),
2771                 dcompen = (DCOMPEN), bkgwren = (BKGWREN), srcshade = (SRCSHADE);
2772
2773         uint8 zmode = (cmd & 0x01C0000) >> 18, lfufunc = (cmd & 0x1E00000) >> 21;
2774 //Missing: BUSHI
2775 //Where to find various lines:
2776 // clip_a1  -> inner
2777 // gourd    -> dcontrol, inner, outer, state
2778 // gourz    -> dcontrol, inner, outer, state
2779 // cmpdst   -> blit, data, datacomp, state
2780 // bcompen  -> acontrol, inner, mcontrol, state
2781 // dcompen  -> inner, state
2782 // bkgwren  -> inner, state
2783 // srcshade -> dcontrol, inner, state
2784 // adddsel  -> dcontrol
2785 //NOTE: ADDDSEL takes precedence over PATDSEL, PATDSEL over LFU_FUNC
2786 #ifdef VERBOSE_BLITTER_LOGGING
2787 if (logBlit)
2788 {
2789 char zfs[512], lfus[512];
2790 zfs[0] = lfus[0] = 0;
2791 if (dstwrz || dstenz || gourz)
2792         sprintf(zfs, " ZMODE=%X", zmode);
2793 if (!(patdsel || adddsel))
2794         sprintf(lfus, " LFUFUNC=%X", lfufunc);
2795 printf("\nBlit! (CMD = %08X)\nFlags:%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", cmd,
2796         (srcen ? " SRCEN" : ""), (srcenx ? " SRCENX" : ""), (srcenz ? " SRCENZ" : ""),
2797         (dsten ? " DSTEN" : ""), (dstenz ? " DSTENZ" : ""), (dstwrz ? " DSTWRZ" : ""),
2798         (clip_a1 ? " CLIP_A1" : ""), (upda1 ? " UPDA1" : ""), (upda1f ? " UPDA1F" : ""),
2799         (upda2 ? " UPDA2" : ""), (dsta2 ? " DSTA2" : ""), (gourd ? " GOURD" : ""),
2800         (gourz ? " GOURZ" : ""), (topben ? " TOPBEN" : ""), (topnen ? " TOPNEN" : ""),
2801         (patdsel ? " PATDSEL" : ""), (adddsel ? " ADDDSEL" : ""), zfs, lfus, (cmpdst ? " CMPDST" : ""),
2802         (bcompen ? " BCOMPEN" : ""), (dcompen ? " DCOMPEN" : ""), (bkgwren ? " BKGWREN" : ""),
2803         (srcshade ? " SRCSHADE" : ""));
2804 printf("  count = %d x %d\n", GET16(blitter_ram, PIXLINECOUNTER + 2), GET16(blitter_ram, PIXLINECOUNTER));
2805 fflush(stdout);
2806 }
2807 #endif
2808
2809         // Lines that don't exist in Jaguar I (and will never be asserted)
2810         
2811         bool polygon = false, datinit = false, a1_stepld = false, a2_stepld = false, ext_int = false;
2812         bool istepadd = false, istepfadd = false, finneradd = false, inneradd = false;
2813         bool zstepfadd = false, zstepadd = false;
2814
2815         // Various state lines (initial state--basically the reset state of the FDSYNCs)
2816
2817         bool go = true, idle = true, inner = false, a1fupdate = false, a1update = false,
2818                 zfupdate = false, zupdate = false, a2update = false, init_if = false, init_ii = false,
2819                 init_zf = false, init_zi = false;
2820
2821         bool outer0 = false, indone = false;
2822
2823         bool idlei, inneri, a1fupdatei, a1updatei, zfupdatei, zupdatei, a2updatei, init_ifi, init_iii,
2824                 init_zfi, init_zii;
2825
2826         bool notgzandp = !(gourz && polygon);
2827
2828         // Various registers set up by user
2829
2830         uint16 ocount = GET16(blitter_ram, PIXLINECOUNTER);
2831         uint8 a1_pitch = blitter_ram[A1_FLAGS + 3] & 0x03;
2832         uint8 a2_pitch = blitter_ram[A2_FLAGS + 3] & 0x03;
2833         uint8 a1_pixsize = (blitter_ram[A1_FLAGS + 3] & 0x38) >> 3;
2834         uint8 a2_pixsize = (blitter_ram[A2_FLAGS + 3] & 0x38) >> 3;
2835         uint8 a1_zoffset = (GET16(blitter_ram, A1_FLAGS + 2) >> 6) & 0x07;
2836         uint8 a2_zoffset = (GET16(blitter_ram, A2_FLAGS + 2) >> 6) & 0x07;
2837         uint8 a1_width = (blitter_ram[A1_FLAGS + 2] >> 1) & 0x3F;
2838         uint8 a2_width = (blitter_ram[A2_FLAGS + 2] >> 1) & 0x3F;
2839         bool a2_mask = blitter_ram[A2_FLAGS + 2] & 0x80;
2840         uint8 a1addx = blitter_ram[A1_FLAGS + 1] & 0x03, a2addx = blitter_ram[A2_FLAGS + 1] & 0x03;
2841         bool a1addy = blitter_ram[A1_FLAGS + 1] & 0x04, a2addy = blitter_ram[A2_FLAGS + 1] & 0x04;
2842         bool a1xsign = blitter_ram[A1_FLAGS + 1] & 0x08, a2xsign = blitter_ram[A2_FLAGS + 1] & 0x08;
2843         bool a1ysign = blitter_ram[A1_FLAGS + 1] & 0x10, a2ysign = blitter_ram[A2_FLAGS + 1] & 0x10;
2844         uint32 a1_base = GET32(blitter_ram, A1_BASE) & 0xFFFFFFF8;      // Phrase aligned by ignoring bottom 3 bits
2845         uint32 a2_base = GET32(blitter_ram, A2_BASE) & 0xFFFFFFF8;
2846
2847         uint16 a1_win_x = GET16(blitter_ram, A1_CLIP + 2) & 0x7FFF;
2848         uint16 a1_win_y = GET16(blitter_ram, A1_CLIP + 0) & 0x7FFF;
2849         int16 a1_x = (int16)GET16(blitter_ram, A1_PIXEL + 2);
2850         int16 a1_y = (int16)GET16(blitter_ram, A1_PIXEL + 0);
2851         int16 a1_step_x = (int16)GET16(blitter_ram, A1_STEP + 2);
2852         int16 a1_step_y = (int16)GET16(blitter_ram, A1_STEP + 0);
2853         uint16 a1_stepf_x = GET16(blitter_ram, A1_FSTEP + 2);
2854         uint16 a1_stepf_y = GET16(blitter_ram, A1_FSTEP + 0);
2855         uint16 a1_frac_x = GET16(blitter_ram, A1_FPIXEL + 2);
2856         uint16 a1_frac_y = GET16(blitter_ram, A1_FPIXEL + 0);
2857         int16 a1_inc_x = (int16)GET16(blitter_ram, A1_INC + 2);
2858         int16 a1_inc_y = (int16)GET16(blitter_ram, A1_INC + 0);
2859         uint16 a1_incf_x = GET16(blitter_ram, A1_FINC + 2);
2860         uint16 a1_incf_y = GET16(blitter_ram, A1_FINC + 0);
2861
2862         int16 a2_x = (int16)GET16(blitter_ram, A2_PIXEL + 2);
2863         int16 a2_y = (int16)GET16(blitter_ram, A2_PIXEL + 0);
2864         uint16 a2_mask_x = GET16(blitter_ram, A2_MASK + 2);
2865         uint16 a2_mask_y = GET16(blitter_ram, A2_MASK + 0);
2866         int16 a2_step_x = (int16)GET16(blitter_ram, A2_STEP + 2);
2867         int16 a2_step_y = (int16)GET16(blitter_ram, A2_STEP + 0);
2868
2869         uint64 srcd1 = GET64(blitter_ram, SRCDATA);
2870         uint64 srcd2 = 0;
2871         uint64 dstd = GET64(blitter_ram, DSTDATA);
2872         uint64 patd = GET64(blitter_ram, PATTERNDATA);
2873         uint32 iinc = GET32(blitter_ram, INTENSITYINC);
2874         uint64 srcz1 = GET64(blitter_ram, SRCZINT);
2875         uint64 srcz2 = GET64(blitter_ram, SRCZFRAC);
2876         uint64 dstz = GET64(blitter_ram, DSTZ);
2877         uint32 zinc = GET32(blitter_ram, ZINC);
2878         uint32 collision = GET32(blitter_ram, COLLISIONCTRL);// 0=RESUME, 1=ABORT, 2=STOPEN
2879
2880         uint8 pixsize = (dsta2 ? a2_pixsize : a1_pixsize);      // From ACONTROL
2881
2882 //Testing Trevor McFur--I *think* it's the circle on the lower RHS of the screen...
2883 /*logBlit = false;
2884 if (cmd == 0x05810601 && (GET16(blitter_ram, PIXLINECOUNTER + 2) == 96)
2885         && (GET16(blitter_ram, PIXLINECOUNTER + 0) == 72))
2886         logBlit = true;//*/
2887 //Testing...
2888 //if (cmd == 0x1401060C) patd = 0xFFFFFFFFFFFFFFFFLL;
2889 //if (cmd == 0x1401060C) patd = 0x00000000000000FFLL;
2890 //If it's still not working (bcompen-patd) then see who's writing what to patd and where...
2891 //Still not OK. Check to see who's writing what to where in patd!
2892 //It looks like M68K is writing to the top half of patd... Hmm...
2893 /*
2894 ----> M68K wrote 0000 to byte 15737344 of PATTERNDATA...
2895 --> M68K wrote 00 to byte 0 of PATTERNDATA...
2896 --> M68K wrote 00 to byte 1 of PATTERNDATA...
2897 ----> M68K wrote 00FF to byte 15737346 of PATTERNDATA...
2898 --> M68K wrote 00 to byte 2 of PATTERNDATA...
2899 --> M68K wrote FF to byte 3 of PATTERNDATA...
2900 logBlit = F, cmd = 1401060C
2901
2902 Wren0 := ND6 (wren\[0], gpua\[5], gpua\[6..8], bliten, gpu_memw);
2903 Wren1 := ND6 (wren\[1], gpua[5], gpua\[6..8], bliten, gpu_memw);
2904 Wren2 := ND6 (wren\[2], gpua\[5], gpua[6], gpua\[7..8], bliten, gpu_memw);
2905 Wren3 := ND6 (wren\[3], gpua[5], gpua[6], gpua\[7..8], bliten, gpu_memw);
2906
2907 --> 0 000x xx00
2908 Dec0  := D38GH (a1baseld, a1flagld, a1winld, a1ptrld, a1stepld, a1stepfld, a1fracld, a1incld, gpua[2..4], wren\[0]);
2909 --> 0 001x xx00
2910 Dec1  := D38GH (a1incfld, a2baseld, a2flagld, a2maskld, a2ptrldg, a2stepld, cmdldt, countldt, gpua[2..4], wren\[1]);
2911 --> 0 010x xx00
2912 Dec2  := D38GH (srcd1ldg[0..1], dstdldg[0..1], dstzldg[0..1], srcz1ldg[0..1], gpua[2..4], wren\[2]);
2913 --> 0 011x xx00
2914 Dec3  := D38GH (srcz2ld[0..1], patdld[0..1], iincld, zincld, stopld, intld[0], gpua[2..4], wren\[3]);
2915
2916 wren[3] is asserted when gpu address bus = 0 011x xx00
2917 patdld[0] -> 0 0110 1000 -> $F02268 (lo 32 bits)
2918 patdld[1] -> 0 0110 1100 -> $F0226C (hi 32 bits)
2919
2920 So... It's reversed! The data organization of the patd register is [low 32][high 32]! !!! FIX !!! [DONE]
2921 And fix all the other 64 bit registers [DONE]
2922 */
2923 /*if (cmd == 0x1401060C)
2924 {
2925         printf("logBlit = %s, cmd = %08X\n", (logBlit ? "T" : "F"), cmd);
2926         fflush(stdout);
2927 }*/
2928 /*logBlit = false;
2929 if ((cmd == 0x00010200) && (GET16(blitter_ram, PIXLINECOUNTER + 2) == 9))
2930         logBlit = true;
2931
2932 ; Pink altimeter bar
2933
2934 Blit! (00110000 <- 000BF010) count: 9 x 23, A1/2_FLAGS: 000042E2/00010020 [cmd: 00010200]
2935  CMD -> src:  dst:  misc:  a1ctl: UPDA1  mode:  ity: PATDSEL z-op:  op: LFU_CLEAR ctrl: 
2936   A1 step values: -10 (X), 1 (Y)
2937   A1 -> pitch: 4 phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
2938   A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
2939         A1 x/y: 262/132, A2 x/y: 129/0
2940 ;x-coord is 257 in pic, so add 5
2941 ;20 for ship, 33 for #... Let's see if we can find 'em!
2942
2943 ; Black altimeter bar
2944
2945 Blit! (00110000 <- 000BF010) count: 5 x 29, A1/2_FLAGS: 000042E2/00010020 [cmd: 00010200]
2946  CMD -> src:  dst:  misc:  a1ctl: UPDA1  mode:  ity: PATDSEL z-op:  op: LFU_CLEAR ctrl: 
2947   A1 step values: -8 (X), 1 (Y)
2948   A1 -> pitch: 4 phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
2949   A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
2950         A1 x/y: 264/126, A2 x/y: 336/0
2951
2952 Here's the pink bar--note that it's phrase mode without dread, so how does this work???
2953 Not sure, but I *think* that somehow it MUXes the data at the write site in on the left or right side
2954 of the write data when masked in phrase mode. I'll have to do some tracing to see if this is the mechanism
2955 it uses or not...
2956
2957 Blit! (CMD = 00010200)
2958 Flags: UPDA1 PATDSEL
2959   count = 9 x 11
2960   a1_base = 00110010, a2_base = 000BD7E0
2961   a1_x = 0106, a1_y = 0090, a1_frac_x = 0000, a1_frac_y = 8000, a2_x = 025A, a2_y = 0000
2962   a1_step_x = FFF6, a1_step_y = 0001, a1_stepf_x = 5E00, a1_stepf_y = D100, a2_step_x = FFF7, a2_step_y = 0001
2963   a1_inc_x = 0001, a1_inc_y = FFFF, a1_incf_x = 0000, a1_incf_y = E000
2964   a1_win_x = 0000, a1_win_y = 0000, a2_mask_x = 0000, a2_mask_y = 0000
2965   a2_mask=F a1add=+phr/+0 a2add=+1/+0
2966   a1_pixsize = 4, a2_pixsize = 4
2967    srcd=BAC673AC2C92E578  dstd=0000000000000000 patd=74C074C074C074C0 iinc=0002E398
2968   srcz1=7E127E12000088DA srcz2=DBE06DF000000000 dstz=0000000000000000 zinc=FFFE4840, coll=0
2969   Phrase mode is ON
2970   [in=T a1f=F a1=F zf=F z=F a2=F iif=F iii=F izf=F izi=F]
2971   Entering INNER state...
2972   Entering DWRITE state...
2973      Dest write address/pix address: 0016A830/0 [dstart=20 dend=40 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=0 daq=F] [7400000074C074C0] (icount=0007, inc=2)
2974   Entering A1_ADD state [a1_x=0106, a1_y=0090, addasel=0, addbsel=0, modx=2, addareg=F, adda_xconst=2, adda_yconst=0]...
2975   Entering DWRITE state...
2976      Dest write address/pix address: 0016A850/0 [dstart=0 dend=40 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=0 daq=F] [74C074C074C074C0] (icount=0003, inc=4)
2977   Entering A1_ADD state [a1_x=0108, a1_y=0090, addasel=0, addbsel=0, modx=2, addareg=F, adda_xconst=2, adda_yconst=0]...
2978   Entering DWRITE state...
2979      Dest write address/pix address: 0016A870/0 [dstart=0 dend=30 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=0 daq=F] [74C074C074C00000] (icount=FFFF, inc=4)
2980   Entering A1_ADD state [a1_x=010C, a1_y=0090, addasel=0, addbsel=0, modx=2, addareg=F, adda_xconst=2, adda_yconst=0]...
2981   Entering IDLE_INNER state...
2982   Leaving INNER state... (ocount=000A)
2983   [in=F a1f=F a1=T zf=F z=F a2=F iif=F iii=F izf=F izi=F]
2984   Entering A1UPDATE state... (272/144 -> 262/145)
2985   [in=T a1f=F a1=F zf=F z=F a2=F iif=F iii=F izf=F izi=F]
2986   Entering INNER state...
2987 */
2988
2989         // Bugs in Jaguar I
2990         
2991         a2addy = a1addy;                                                        // A2 channel Y add bit is tied to A1's
2992
2993 //if (logBlit && (ocount > 20)) logBlit = false;
2994 #ifdef VERBOSE_BLITTER_LOGGING
2995 if (logBlit)
2996 {
2997 printf("  a1_base = %08X, a2_base = %08X\n", a1_base, a2_base);
2998 printf("  a1_x = %04X, a1_y = %04X, a1_frac_x = %04X, a1_frac_y = %04X, a2_x = %04X, a2_y = %04X\n", (uint16)a1_x, (uint16)a1_y, a1_frac_x, a1_frac_y, (uint16)a2_x, (uint16)a2_y);
2999 printf("  a1_step_x = %04X, a1_step_y = %04X, a1_stepf_x = %04X, a1_stepf_y = %04X, a2_step_x = %04X, a2_step_y = %04X\n", (uint16)a1_step_x, (uint16)a1_step_y, a1_stepf_x, a1_stepf_y, (uint16)a2_step_x, (uint16)a2_step_y);
3000 printf("  a1_inc_x = %04X, a1_inc_y = %04X, a1_incf_x = %04X, a1_incf_y = %04X\n", (uint16)a1_inc_x, (uint16)a1_inc_y, a1_incf_x, a1_incf_y);
3001 printf("  a1_win_x = %04X, a1_win_y = %04X, a2_mask_x = %04X, a2_mask_y = %04X\n", a1_win_x, a1_win_y, a2_mask_x, a2_mask_y);
3002 char x_add_str[4][4] = { "phr", "1", "0", "inc" };
3003 printf("  a2_mask=%s a1add=%s%s/%s%s a2add=%s%s/%s%s\n", (a2_mask ? "T" : "F"), (a1xsign ? "-" : "+"), x_add_str[a1addx],
3004         (a1ysign ? "-" : "+"), (a1addy ? "1" : "0"), (a2xsign ? "-" : "+"), x_add_str[a2addx],
3005         (a2ysign ? "-" : "+"), (a2addy ? "1" : "0"));
3006 printf("  a1_pixsize = %u, a2_pixsize = %u\n", a1_pixsize, a2_pixsize);
3007 printf("   srcd=%08X%08X  dstd=%08X%08X patd=%08X%08X iinc=%08X\n",
3008         (uint32)(srcd1 >> 32), (uint32)(srcd1 & 0xFFFFFFFF),
3009         (uint32)(dstd >> 32), (uint32)(dstd & 0xFFFFFFFF),
3010         (uint32)(patd >> 32), (uint32)(patd & 0xFFFFFFFF), iinc);
3011 printf("  srcz1=%08X%08X srcz2=%08X%08X dstz=%08X%08X zinc=%08X, coll=%X\n",
3012         (uint32)(srcz1 >> 32), (uint32)(srcz1 & 0xFFFFFFFF),
3013         (uint32)(srcz2 >> 32), (uint32)(srcz2 & 0xFFFFFFFF),
3014         (uint32)(dstz >> 32), (uint32)(dstz & 0xFFFFFFFF), zinc, collision);
3015 }
3016 #endif  
3017
3018         // Various state lines set up by user
3019
3020         bool phrase_mode = ((!dsta2 && a1addx == 0) || (dsta2 && a2addx == 0) ? true : false);  // From ACONTROL
3021 #ifdef VERBOSE_BLITTER_LOGGING
3022 if (logBlit)
3023 {
3024 printf("  Phrase mode is %s\n", (phrase_mode ? "ON" : "off"));
3025 fflush(stdout);
3026 }
3027 #endif
3028 //logBlit = false;
3029
3030         // Stopgap vars to simulate various lines
3031
3032         uint16 a1FracCInX = 0, a1FracCInY = 0;
3033
3034         while (true)
3035         {
3036                 // IDLE
3037         
3038                 if ((idle && !go) || (inner && outer0 && indone))
3039                 {
3040 #ifdef VERBOSE_BLITTER_LOGGING
3041 if (logBlit)
3042 {
3043 printf("  Entering IDLE state...\n");
3044 fflush(stdout);
3045 }
3046 #endif
3047                         idlei = true;
3048
3049 //Instead of a return, let's try breaking out of the loop...
3050 break;
3051 //                      return;
3052                 }
3053                 else
3054                         idlei = false;
3055         
3056                 // INNER LOOP ACTIVE
3057 /*
3058   Entering DWRITE state... (icount=0000, inc=4)
3059   Entering IDLE_INNER state...
3060   Leaving INNER state... (ocount=00EF)
3061   [in=T a1f=F a1=T zf=F z=F a2=F iif=F iii=F izf=F izi=F]
3062   Entering INNER state...
3063 Now:
3064   [in=F a1f=F a1=F zf=F z=F a2=F iif=F iii=F izf=F izi=F]
3065 */
3066         
3067                 if ((idle && go && !datinit)
3068                         || (inner && !indone)
3069                         || (inner && indone && !outer0 && !upda1f && !upda1 && notgzandp && !upda2 && !datinit)
3070                         || (a1update && !upda2 && notgzandp && !datinit)
3071                         || (zupdate && !upda2 && !datinit)
3072                         || (a2update && !datinit)
3073                         || (init_ii && !gourz)
3074                         || (init_zi))
3075                 {
3076                         inneri = true;
3077                 }
3078                 else
3079                         inneri = false;
3080         
3081                 // A1 FRACTION UPDATE
3082         
3083                 if (inner && indone && !outer0 && upda1f)
3084                 {
3085                         a1fupdatei = true;
3086                 }
3087                 else
3088                         a1fupdatei = false;
3089
3090                 // A1 POINTER UPDATE
3091
3092                 if ((a1fupdate)
3093                         || (inner && indone && !outer0 && !upda1f && upda1))
3094                 {
3095                         a1updatei = true;
3096                 }
3097                 else
3098                         a1updatei = false;
3099
3100                 // Z FRACTION UPDATE
3101
3102                 if ((a1update && gourz && polygon)
3103                         || (inner && indone && !outer0 && !upda1f && !upda1 && gourz && polygon))
3104                 {
3105                         zfupdatei = true;
3106                 }
3107                 else
3108                         zfupdatei = false;
3109
3110                 // Z INTEGER UPDATE
3111
3112                 if (zfupdate)
3113                 {
3114                         zupdatei = true;
3115                 }
3116                 else
3117                         zupdatei = false;
3118
3119                 // A2 POINTER UPDATE
3120
3121                 if ((a1update && upda2 && notgzandp)
3122                         || (zupdate && upda2)
3123                         || (inner && indone && !outer0 && !upda1f && notgzandp && !upda1 && upda2))
3124                 {
3125                         a2updatei = true;
3126                 }
3127                 else
3128                         a2updatei = false;
3129         
3130                 // INITIALIZE INTENSITY FRACTION
3131         
3132                 if ((zupdate && !upda2 && datinit)
3133                         || (a1update && !upda2 && datinit && notgzandp)
3134                         || (inner && indone && !outer0 && !upda1f && !upda1 && notgzandp && !upda2 && datinit)
3135                         || (a2update && datinit)
3136                         || (idle && go && datinit))
3137                 {
3138                         init_ifi = true;
3139                 }
3140                 else
3141                         init_ifi = false;
3142         
3143                 // INITIALIZE INTENSITY INTEGER
3144         
3145                 if (init_if)
3146                 {
3147                         init_iii = true;
3148                 }
3149                 else
3150                         init_iii = false;
3151         
3152                 // INITIALIZE Z FRACTION
3153         
3154                 if (init_ii && gourz)
3155                 {
3156                         init_zfi = true;
3157                 }
3158                 else
3159                         init_zfi = false;
3160         
3161                 // INITIALIZE Z INTEGER
3162         
3163                 if (init_zf)
3164                 {
3165                         init_zii = true;
3166                 }
3167                 else
3168                         init_zii = false;
3169         
3170 // Here we move the fooi into their foo counterparts in order to simulate the moving
3171 // of data into the various FDSYNCs... Each time we loop we simulate one clock cycle...
3172
3173                 idle = idlei;
3174                 inner = inneri;
3175                 a1fupdate = a1fupdatei;
3176                 a1update = a1updatei;
3177                 zfupdate = zfupdatei;           // *
3178                 zupdate = zupdatei;                     // *
3179                 a2update = a2updatei;
3180                 init_if = init_ifi;                     // *
3181                 init_ii = init_iii;                     // *
3182                 init_zf = init_zfi;                     // *
3183                 init_zi = init_zii;                     // *
3184 // * denotes states that will never assert for Jaguar I
3185 #ifdef VERBOSE_BLITTER_LOGGING
3186 if (logBlit)
3187 {
3188 printf("  [in=%c a1f=%c a1=%c zf=%c z=%c a2=%c iif=%c iii=%c izf=%c izi=%c]\n",
3189         (inner ? 'T' : 'F'), (a1fupdate ? 'T' : 'F'), (a1update ? 'T' : 'F'), (zfupdate ? 'T' : 'F'),
3190         (zupdate ? 'T' : 'F'), (a2update ? 'T' : 'F'), (init_if ? 'T' : 'F'), (init_ii ? 'T' : 'F'),
3191         (init_zf ? 'T' : 'F'), (init_zi ? 'T' : 'F'));
3192 fflush(stdout);
3193 }
3194 #endif
3195
3196 // Now, depending on how we want to handle things, we could either put the implementation
3197 // of the various pieces up above, or handle them down below here.
3198
3199 // Let's try postprocessing for now...
3200
3201                 if (inner)
3202                 {
3203                         indone = false;
3204 #ifdef VERBOSE_BLITTER_LOGGING
3205 if (logBlit)
3206 {
3207 printf("  Entering INNER state...\n");
3208 fflush(stdout);
3209 }
3210 #endif
3211                         uint16 icount = GET16(blitter_ram, PIXLINECOUNTER + 2);
3212                         bool idle_inner = true, step = true, sreadx = false, szreadx = false, sread = false,
3213                                 szread = false, dread = false, dzread = false, dwrite = false, dzwrite = false;
3214                         bool inner0 = false;
3215                         bool idle_inneri, sreadxi, szreadxi, sreadi, szreadi, dreadi, dzreadi, dwritei, dzwritei;
3216
3217                         // State lines that will never assert in Jaguar I
3218
3219                         bool textext = false, txtread = false;
3220
3221 //other stuff
3222 uint8 srcshift = 0;
3223 bool sshftld = true; // D flipflop (D -> Q): instart -> sshftld
3224 //NOTE: sshftld probably is only asserted at the beginning of the inner loop. !!! FIX !!!
3225 /*
3226 Blit! (CMD = 01800005)
3227 Flags: SRCEN SRCENX LFUFUNC=C
3228   count = 626 x 1
3229   a1_base = 00037290, a2_base = 000095D0
3230   a1_x = 0000, a1_y = 0000, a2_x = 0002, a2_y = 0000
3231   a1_pixsize = 4, a2_pixsize = 4
3232   srcd=0000000000000000, dstd=0000000000000000, patd=0000000000000000
3233   Phrase mode is ON
3234   [in=T a1f=F a1=F zf=F z=F a2=F iif=F iii=F izf=F izi=F]
3235   Entering INNER state...
3236   Entering SREADX state... [dstart=0 dend=20 pwidth=8 srcshift=20]
3237     Source extra read address/pix address: 000095D4/0 [0000001C00540038]
3238   Entering A2_ADD state [a2_x=0002, a2_y=0000, addasel=0, addbsel=1, modx=2, addareg=F, adda_xconst=2, adda_yconst=0]...
3239   Entering SREAD state... [dstart=0 dend=20 pwidth=8 srcshift=0]
3240     Source read address/pix address: 000095D8/0 [0054003800009814]
3241   Entering A2_ADD state [a2_x=0004, a2_y=0000, addasel=0, addbsel=1, modx=2, addareg=F, adda_xconst=2, adda_yconst=0]...
3242   Entering DWRITE state...
3243      Dest write address/pix address: 00037290/0 [dstart=0 dend=20 pwidth=8 srcshift=0] (icount=026E, inc=4)
3244   Entering A1_ADD state [a1_x=0000, a1_y=0000, addasel=0, addbsel=0, modx=2, addareg=F, adda_xconst=2, adda_yconst=0]...
3245   Entering SREAD state... [dstart=0 dend=20 pwidth=8 srcshift=0]
3246     Source read address/pix address: 000095E0/0 [00009968000377C7]
3247   Entering A2_ADD state [a2_x=0008, a2_y=0000, addasel=0, addbsel=1, modx=2, addareg=F, adda_xconst=2, adda_yconst=0]...
3248   Entering DWRITE state...
3249      Dest write address/pix address: 00037298/0 [dstart=0 dend=20 pwidth=8 srcshift=0] (icount=026A, inc=4)
3250   Entering A1_ADD state [a1_x=0004, a1_y=0000, addasel=0, addbsel=0, modx=2, addareg=F, adda_xconst=2, adda_yconst=0]...
3251 */
3252
3253 //                      while (!idle_inner)
3254                         while (true)
3255                         {
3256                                 // IDLE
3257
3258                                 if ((idle_inner && !step)
3259                                         || (dzwrite && step && inner0)
3260                                         || (dwrite && step && !dstwrz && inner0))
3261                                 {
3262 #ifdef VERBOSE_BLITTER_LOGGING
3263 if (logBlit)
3264 {
3265 printf("  Entering IDLE_INNER state...\n");
3266 fflush(stdout);
3267 }
3268 #endif
3269                                         idle_inneri = true;
3270 break;
3271                                 }
3272                                 else
3273                                         idle_inneri = false;
3274
3275                                 // EXTRA SOURCE DATA READ
3276
3277                                 if ((idle_inner && step && srcenx)
3278                                         || (sreadx && !step))
3279                                 {
3280                                         sreadxi = true;
3281                                 }
3282                                 else
3283                                         sreadxi = false;
3284
3285                                 // EXTRA SOURCE ZED READ
3286
3287                                 if ((sreadx && step && srcenz)
3288                                         || (szreadx && !step))
3289                                 {
3290                                         szreadxi = true;
3291                                 }
3292                                 else
3293                                         szreadxi = false;
3294
3295                                 // TEXTURE DATA READ (not implemented because not in Jaguar I)
3296
3297                                 // SOURCE DATA READ
3298
3299                                 if ((szreadx && step && !textext)
3300                                         || (sreadx && step && !srcenz && srcen)
3301                                         || (idle_inner && step && !srcenx && !textext && srcen)
3302                                         || (dzwrite && step && !inner0 && !textext && srcen)
3303                                         || (dwrite && step && !dstwrz && !inner0 && !textext && srcen)
3304                                         || (txtread && step && srcen)
3305                                         || (sread && !step))
3306                                 {
3307                                         sreadi = true;
3308                                 }
3309                                 else
3310                                         sreadi = false;
3311
3312                                 // SOURCE ZED READ
3313
3314                                 if ((sread && step && srcenz)
3315                                         || (szread && !step))
3316                                 {
3317                                         szreadi = true;
3318                                 }
3319                                 else
3320                                         szreadi = false;
3321
3322                                 // DESTINATION DATA READ
3323
3324                                 if ((szread && step && dsten)
3325                                         || (sread && step && !srcenz && dsten)
3326                                         || (sreadx && step && !srcenz && !textext && !srcen && dsten)
3327                                         || (idle_inner && step && !srcenx && !textext && !srcen && dsten)
3328                                         || (dzwrite && step && !inner0 && !textext && !srcen && dsten)
3329                                         || (dwrite && step && !dstwrz && !inner0 && !textext && !srcen && dsten)
3330                                         || (txtread && step && !srcen && dsten)
3331                                         || (dread && !step))
3332                                 {
3333                                         dreadi = true;
3334                                 }
3335                                 else
3336                                         dreadi = false;
3337
3338                                 // DESTINATION ZED READ
3339
3340                                 if ((dread && step && dstenz)
3341                                         || (szread && step && !dsten && dstenz)
3342                                         || (sread && step && !srcenz && !dsten && dstenz)
3343                                         || (sreadx && step && !srcenz && !textext && !srcen && !dsten && dstenz)
3344                                         || (idle_inner && step && !srcenx && !textext && !srcen && !dsten && dstenz)
3345                                         || (dzwrite && step && !inner0 && !textext && !srcen && !dsten && dstenz)
3346                                         || (dwrite && step && !dstwrz && !inner0 && !textext && !srcen && !dsten && dstenz)
3347                                         || (txtread && step && !srcen && !dsten && dstenz)
3348                                         || (dzread && !step))
3349                                 {
3350                                         dzreadi = true;
3351                                 }
3352                                 else
3353                                         dzreadi = false;
3354
3355                                 // DESTINATION DATA WRITE
3356
3357                                 if ((dzread && step)
3358                                         || (dread && step && !dstenz)
3359                                         || (szread && step && !dsten && !dstenz)
3360                                         || (sread && step && !srcenz && !dsten && !dstenz)
3361                                         || (txtread && step && !srcen && !dsten && !dstenz)
3362                                         || (sreadx && step && !srcenz && !textext && !srcen && !dsten && !dstenz)
3363                                         || (idle_inner && step && !srcenx && !textext && !srcen && !dsten && !dstenz)
3364                                         || (dzwrite && step && !inner0 && !textext && !srcen && !dsten && !dstenz)
3365                                         || (dwrite && step && !dstwrz && !inner0 && !textext && !srcen && !dsten && !dstenz)
3366                                         || (dwrite && !step))
3367                                 {
3368                                         dwritei = true;
3369                                 }
3370                                 else
3371                                         dwritei = false;
3372
3373                                 // DESTINATION ZED WRITE
3374
3375                                 if ((dzwrite && !step)
3376                                         || (dwrite && step && dstwrz))
3377                                 {
3378                                         dzwritei = true;
3379                                 }
3380                                 else
3381                                         dzwritei = false;
3382
3383 //Kludge: A QnD way to make sure that sshftld is asserted only for the first
3384 //        cycle of the inner loop...
3385 sshftld = idle_inner;
3386
3387 // Here we move the fooi into their foo counterparts in order to simulate the moving
3388 // of data into the various FDSYNCs... Each time we loop we simulate one clock cycle...
3389
3390                                 idle_inner = idle_inneri;
3391                                 sreadx = sreadxi;
3392                                 szreadx = szreadxi;
3393                                 sread = sreadi;
3394                                 szread = szreadi;
3395                                 dread = dreadi;
3396                                 dzread = dzreadi;
3397                                 dwrite = dwritei;
3398                                 dzwrite = dzwritei;
3399
3400 // Here's a few more decodes--not sure if they're supposed to go here or not...
3401
3402                                 bool srca_addi = (sreadxi && !srcenz) || (sreadi && !srcenz) || szreadxi || szreadi;
3403
3404                                 bool dsta_addi = (dwritei && !dstwrz) || dzwritei;
3405
3406                                 bool gensrc = sreadxi || szreadxi || sreadi || szreadi;
3407                                 bool gendst = dreadi || dzreadi || dwritei || dzwritei;
3408                                 bool gena2i = (gensrc && !dsta2) || (gendst && dsta2);
3409
3410                                 bool zaddr = szreadx || szread || dzread || dzwrite;
3411
3412 // Some stuff from MCONTROL.NET--not sure if this is the correct use of this decode or not...
3413 /*Fontread\     := OND1 (fontread\, sread[1], sreadx[1], bcompen);
3414 Fontread        := INV1 (fontread, fontread\);
3415 Justt           := NAN3 (justt, fontread\, phrase_mode, tactive\);
3416 Justify         := TS (justify, justt, busen);*/
3417 bool fontread = (sread || sreadx) && bcompen;
3418 bool justify = !(!fontread && phrase_mode /*&& tactive*/);
3419
3420 /* Generate inner loop update enables */
3421 /*
3422 A1_addi         := MX2 (a1_addi, dsta_addi, srca_addi, dsta2);
3423 A2_addi         := MX2 (a2_addi, srca_addi, dsta_addi, dsta2);
3424 A1_add          := FD1 (a1_add, a1_add\, a1_addi, clk);
3425 A2_add          := FD1 (a2_add, a2_add\, a2_addi, clk);
3426 A2_addb         := BUF1 (a2_addb, a2_add);
3427 */
3428                                 bool a1_add = (dsta2 ? srca_addi : dsta_addi);
3429                                 bool a2_add = (dsta2 ? dsta_addi : srca_addi);
3430
3431 /* Address adder input A register selection
3432 000     A1 step integer part
3433 001     A1 step fraction part
3434 010     A1 increment integer part
3435 011     A1 increment fraction part
3436 100     A2 step
3437
3438 bit 2 = a2update
3439 bit 1 = /a2update . (a1_add . a1addx[0..1])
3440 bit 0 = /a2update . ( a1fupdate
3441                                     + a1_add . atick[0] . a1addx[0..1])
3442 The /a2update term on bits 0 and 1 is redundant.
3443 Now look-ahead based
3444 */
3445                                 uint8 addasel = (a1fupdate || (a1_add && a1addx == 3) ? 0x01 : 0x00);
3446                                 addasel |= (a1_add && a1addx == 3 ? 0x02 : 0x00);
3447                                 addasel |= (a2update ? 0x04 : 0x00);
3448 /* Address adder input A X constant selection
3449 adda_xconst[0..2] generate a power of 2 in the range 1-64 or all
3450 zeroes when they are all 1
3451 Remember - these are pixels, so to add one phrase the pixel size
3452 has to be taken into account to get the appropriate value.
3453 for A1
3454                 if a1addx[0..1] are 00 set 6 - pixel size
3455                 if a1addx[0..1] are 01 set the value 000
3456                 if a1addx[0..1] are 10 set the value 111
3457 similarly for A2
3458 JLH: Also, 11 will likewise set the value to 111
3459 */
3460                                 uint8 a1_xconst = 6 - a1_pixsize, a2_xconst = 6 - a2_pixsize;
3461
3462                                 if (a1addx == 1)
3463                                     a1_xconst = 0;
3464                                 else if (a1addx & 0x02)
3465                                     a1_xconst = 7;
3466
3467                                 if (a2addx == 1)
3468                                     a2_xconst = 0;
3469                                 else if (a2addx & 0x02)
3470                                     a2_xconst = 7;
3471
3472                                 uint8 adda_xconst = (a2_add ? a2_xconst : a1_xconst);
3473 /* Address adder input A Y constant selection
3474 22 June 94 - This was erroneous, because only the a1addy bit was reflected here.
3475 Therefore, the selection has to be controlled by a bug fix bit.
3476 JLH: Bug fix bit in Jaguar II--not in Jaguar I!
3477 */
3478                                 bool adda_yconst = a1addy;
3479 /* Address adder input A register versus constant selection
3480 given by          a1_add . a1addx[0..1]
3481                                 + a1update
3482                                 + a1fupdate
3483                                 + a2_add . a2addx[0..1]
3484                                 + a2update
3485 */
3486                                 bool addareg = ((a1_add && a1addx == 3) || a1update || a1fupdate
3487                                         || (a2_add && a2addx == 3) || a2update ? true : false);
3488 /* The adders can be put into subtract mode in add pixel size
3489 mode when the corresponding flags are set */
3490                                 bool suba_x = ((a1_add && a1xsign && a1addx == 1) || (a2_add && a2xsign && a2addx == 1) ? true : false);
3491                                 bool suba_y = ((a1_add && a1addy && a1ysign) || (a2_add && a2addy && a2ysign) ? true : false);
3492 /* Address adder input B selection
3493 00      A1 pointer
3494 01      A2 pointer
3495 10      A1 fraction
3496 11      Zero
3497
3498 Bit 1 =   a1fupdate
3499                 + (a1_add . atick[0] . a1addx[0..1])
3500                 + a1fupdate . a1_stepld
3501                 + a1update . a1_stepld
3502                 + a2update . a2_stepld
3503 Bit 0 =   a2update + a2_add
3504                 + a1fupdate . a1_stepld
3505                 + a1update . a1_stepld
3506                 + a2update . a2_stepld
3507 */
3508                                 uint8 addbsel = (a2update || a2_add || (a1fupdate && a1_stepld)
3509                                     || (a1update && a1_stepld) || (a2update && a2_stepld) ? 0x01 : 0x00);
3510                                 addbsel |= (a1fupdate || (a1_add && a1addx == 3) || (a1fupdate && a1_stepld)
3511                                     || (a1update && a1_stepld) || (a2update && a2_stepld) ? 0x02 : 0x00);
3512
3513 /* The modulo bits are used to align X onto a phrase boundary when
3514 it is being updated by one phrase
3515 000     no mask
3516 001     mask bit 0
3517 010     mask bits 1-0
3518 ..
3519 110     mask bits 5-0
3520
3521 Masking is enabled for a1 when a1addx[0..1] is 00, and the value
3522 is 6 - the pixel size (again!)
3523 */
3524                                 uint8 maska1 = (a1_add && a1addx == 0 ? 6 - a1_pixsize : 0);
3525                                 uint8 maska2 = (a2_add && a2addx == 0 ? 6 - a2_pixsize : 0);
3526                                 uint8 modx = (a2_add ? maska2 : maska1);
3527 /* Generate load strobes for the increment updates */
3528
3529 /*A1pldt                := NAN2 (a1pldt, atick[1], a1_add);
3530 A1ptrldi        := NAN2 (a1ptrldi, a1update\, a1pldt);
3531
3532 A1fldt          := NAN4 (a1fldt, atick[0], a1_add, a1addx[0..1]);
3533 A1fracldi       := NAN2 (a1fracldi, a1fupdate\, a1fldt);
3534
3535 A2pldt          := NAN2 (a2pldt, atick[1], a2_add);
3536 A2ptrldi        := NAN2 (a2ptrldi, a2update\, a2pldt);*/
3537                                 bool a1fracldi = a1fupdate || (a1_add && a1addx == 3);
3538
3539 // Some more from DCONTROL...
3540 // atick[] just MAY be important here! We're assuming it's true and dropping the term...
3541 // That will probably screw up some of the lower terms that seem to rely on the timing of it...
3542 #warning srcdreadd is not properly initialized!
3543 bool srcdreadd = false;                                         // Set in INNER.NET
3544 //Shadeadd\     := NAN2H (shadeadd\, dwrite, srcshade);
3545 //Shadeadd      := INV2 (shadeadd, shadeadd\);
3546 bool shadeadd = dwrite && srcshade;
3547 /* Data adder control, input A selection
3548 000   Destination data
3549 001   Initialiser pixel value
3550 100   Source data      - computed intensity fraction
3551 101   Pattern data     - computed intensity
3552 110   Source zed 1     - computed zed
3553 111   Source zed 2     - computed zed fraction
3554
3555 Bit 0 =   dwrite  . gourd . atick[1]
3556         + dzwrite . gourz . atick[0]
3557         + istepadd
3558         + zstepfadd
3559         + init_if + init_ii + init_zf + init_zi
3560 Bit 1 =   dzwrite . gourz . (atick[0] + atick[1])
3561         + zstepadd
3562         + zstepfadd
3563 Bit 2 =   (gourd + gourz) . /(init_if + init_ii + init_zf + init_zi)
3564         + dwrite  . srcshade
3565 */
3566 uint8 daddasel = ((dwrite && gourd) || (dzwrite && gourz) || istepadd || zstepfadd
3567         || init_if || init_ii || init_zf || init_zi ? 0x01 : 0x00);
3568 daddasel |= ((dzwrite && gourz) || zstepadd || zstepfadd ? 0x02 : 0x00);
3569 daddasel |= (((gourd || gourz) && !(init_if || init_ii || init_zf || init_zi))
3570         || (dwrite && srcshade) ? 0x04 : 0x00);
3571 /* Data adder control, input B selection
3572 0000    Source data
3573 0001    Data initialiser increment
3574 0100    Bottom 16 bits of I increment repeated four times
3575 0101    Top 16 bits of I increment repeated four times
3576 0110    Bottom 16 bits of Z increment repeated four times
3577 0111    Top 16 bits of Z increment repeated four times
3578 1100    Bottom 16 bits of I step repeated four times
3579 1101    Top 16 bits of I step repeated four times
3580 1110    Bottom 16 bits of Z step repeated four times
3581 1111    Top 16 bits of Z step repeated four times
3582
3583 Bit 0 =   dwrite  . gourd . atick[1]
3584         + dzwrite . gourz . atick[1]
3585         + dwrite  . srcshade
3586         + istepadd
3587         + zstepadd
3588         + init_if + init_ii + init_zf + init_zi
3589 Bit 1 =   dzwrite . gourz . (atick[0] + atick[1])
3590         + zstepadd
3591         + zstepfadd
3592 Bit 2 =   dwrite  . gourd . (atick[0] + atick[1])
3593         + dzwrite . gourz . (atick[0] + atick[1])
3594         + dwrite  . srcshade
3595         + istepadd + istepfadd + zstepadd + zstepfadd
3596 Bit 3 =   istepadd + istepfadd + zstepadd + zstepfadd
3597 */
3598 uint8 daddbsel = ((dwrite && gourd) || (dzwrite && gourz) || (dwrite && srcshade)
3599         || istepadd || zstepadd || init_if || init_ii || init_zf || init_zi ? 0x01 : 0x00);
3600 daddbsel |= ((dzwrite && gourz) || zstepadd || zstepfadd ? 0x02 : 0x00);
3601 daddbsel |= ((dwrite && gourd) || (dzwrite && gourz) || (dwrite && srcshade)
3602         || istepadd || istepfadd || zstepadd || zstepfadd ? 0x04 : 0x00);
3603 daddbsel |= (istepadd && istepfadd && zstepadd && zstepfadd ? 0x08 : 0x00);
3604 /* Data adder mode control
3605 000     16-bit normal add
3606 001     16-bit saturating add with carry
3607 010     8-bit saturating add with carry, carry into top byte is 
3608         inhibited (YCrCb)
3609 011     8-bit saturating add with carry, carry into top byte and 
3610         between top nybbles is inhibited (CRY)
3611 100     16-bit normal add with carry
3612 101     16-bit saturating add
3613 110     8-bit saturating add, carry into top byte is inhibited
3614 111     8-bit saturating add, carry into top byte and between top 
3615         nybbles is inhibited
3616
3617 The first five are used for Gouraud calculations, the latter three
3618 for adding source and destination data
3619
3620 Bit 0 =   dzwrite . gourz . atick[1]
3621         + dwrite  . gourd . atick[1] . /topnen . /topben . /ext_int
3622         + dwrite  . gourd . atick[1] .  topnen .  topben . /ext_int
3623         + zstepadd
3624         + istepadd . /topnen . /topben . /ext_int
3625         + istepadd .  topnen .  topben . /ext_int
3626         + /gourd . /gourz . /topnen . /topben
3627         + /gourd . /gourz .  topnen .  topben
3628         + shadeadd . /topnen . /topben
3629         + shadeadd .  topnen .  topben
3630         + init_ii . /topnen . /topben . /ext_int
3631         + init_ii .  topnen .  topben . /ext_int
3632         + init_zi
3633                 
3634 Bit 1 =   dwrite . gourd . atick[1] . /topben . /ext_int
3635         + istepadd . /topben . /ext_int
3636         + /gourd . /gourz .  /topben
3637         + shadeadd .  /topben
3638         + init_ii .  /topben . /ext_int
3639
3640 Bit 2 =   /gourd . /gourz
3641         + shadeadd
3642         + dwrite  . gourd . atick[1] . ext_int
3643         + istepadd . ext_int
3644         + init_ii . ext_int
3645 */
3646 uint8 daddmode = ((dzwrite && gourz) || (dwrite && gourd && !topnen && !topben && !ext_int)
3647         || (dwrite && gourd && topnen && topben && !ext_int) || zstepadd
3648         || (istepadd && !topnen && !topben && !ext_int)
3649         || (istepadd && topnen && topben && !ext_int) || (!gourd && !gourz && !topnen && !topben)
3650         || (!gourd && !gourz && topnen && topben) || (shadeadd && !topnen && !topben)
3651         || (shadeadd && topnen && topben) || (init_ii && !topnen && !topben && !ext_int)
3652         || (init_ii && topnen && topben && !ext_int) || init_zi ? 0x01 : 0x00);
3653 daddmode |= ((dwrite && gourd && !topben && !ext_int) || (istepadd && !topben && !ext_int)
3654         || (!gourd && !gourz && !topben) || (shadeadd && !topben)
3655         || (init_ii && !topben && !ext_int) ? 0x02 : 0x00);
3656 daddmode |= ((!gourd && !gourz) || shadeadd || (dwrite && gourd && ext_int)
3657         || (istepadd && ext_int) || (init_ii && ext_int) ? 0x04 : 0x00);
3658 /* Data add load controls 
3659 Pattern fraction (dest data) is loaded on 
3660           dwrite . gourd . atick[0]
3661         + istepfadd . /datinit
3662         + init_if
3663 Pattern data is loaded on
3664           dwrite . gourd . atick[1]
3665         + istepadd . /datinit . /datinit
3666         + init_ii
3667 Source z1 is loaded on 
3668           dzwrite . gourz . atick[1]
3669         + zstepadd . /datinit . /datinit
3670         + init_zi
3671 Source z2 is loaded on 
3672           dzwrite . gourz . atick[0]
3673         + zstepfadd
3674         + init_zf
3675 Texture map shaded data is loaded on
3676         srcdreadd . srcshade
3677 */
3678 bool patfadd = (dwrite && gourd) || (istepfadd && !datinit) || init_if;
3679 bool patdadd = (dwrite && gourd) || (istepadd && !datinit) || init_ii;
3680 bool srcz1add = (dzwrite && gourz) || (zstepadd && !datinit) || init_zi;
3681 bool srcz2add = (dzwrite && gourz) || zstepfadd || init_zf;
3682 bool srcshadd = srcdreadd && srcshade;
3683 bool daddq_sel = patfadd || patdadd || srcz1add || srcz2add || srcshadd;
3684 /* Select write data
3685 This has to be controlled from stage 1 of the pipe-line, delayed
3686 by one tick, as the write occurs in the cycle after the ack.
3687
3688 00      pattern data
3689 01      lfu data
3690 10      adder output
3691 11      source zed
3692
3693 Bit 0 =  /patdsel . /adddsel
3694         + dzwrite1d
3695 Bit 1 =   adddsel
3696         + dzwrite1d
3697 */
3698 uint8 data_sel = ((!patdsel && !adddsel) || dzwrite ? 0x01 : 0x00)
3699         | (adddsel || dzwrite ? 0x02 : 0x00);
3700
3701 uint32 address, pixAddr;
3702 ADDRGEN(address, pixAddr, gena2i, zaddr,
3703         a1_x, a1_y, a1_base, a1_pitch, a1_pixsize, a1_width, a1_zoffset,
3704         a2_x, a2_y, a2_base, a2_pitch, a2_pixsize, a2_width, a2_zoffset);
3705
3706 //Here's my guess as to how the addresses get truncated to phrase boundaries in phrase mode...
3707 if (!justify)
3708         address &= 0xFFFFF8;
3709
3710 /* Generate source alignment shift
3711    -------------------------------
3712 The source alignment shift for data move is the difference between 
3713 the source and destination X pointers, multiplied by the pixel 
3714 size.  Only the low six bits of the pointers are of interest, as 
3715 pixel sizes are always a power of 2 and window rows are always 
3716 phrase aligned.  
3717
3718 When not in phrase mode, the top 3 bits of the shift value are
3719 set to zero (2/26).
3720
3721 Source shifting is also used to extract bits for bit-to-byte
3722 expansion in phrase mode.  This involves only the bottom three 
3723 bits of the shift value, and is based on the offset within the
3724 phrase of the destination X pointer, in pixels.
3725
3726 Source shifting is disabled when srcen is not set.
3727 */
3728 uint8 dstxp = (dsta2 ? a2_x : a1_x) & 0x3F;
3729 uint8 srcxp = (dsta2 ? a1_x : a2_x) & 0x3F;
3730 uint8 shftv = ((dstxp - srcxp) << pixsize) & 0x3F;
3731 /* The phrase mode alignment count is given by the phrase offset
3732 of the first pixel, for bit to byte expansion */
3733 uint8 pobb = 0;
3734
3735 if (pixsize == 3)
3736         pobb = dstxp & 0x07;
3737 if (pixsize == 4)
3738         pobb = dstxp & 0x03;
3739 if (pixsize == 5)
3740         pobb = dstxp & 0x01;
3741
3742 bool pobbsel = phrase_mode && bcompen;
3743 uint8 loshd = (pobbsel ? pobb : shftv) & 0x07;
3744 uint8 shfti = (srcen || pobbsel ? (sshftld ? loshd : srcshift & 0x07) : 0);
3745 /* Enable for high bits is srcen . phrase_mode */
3746 shfti |= (srcen && phrase_mode ? (sshftld ? shftv & 0x38 : srcshift & 0x38) : 0);
3747 srcshift = shfti;
3748
3749                                 if (sreadx)
3750                                 {
3751 #ifdef VERBOSE_BLITTER_LOGGING
3752 if (logBlit)
3753 {
3754 printf("  Entering SREADX state...");
3755 //printf(" [dstart=%X dend=%X pwidth=%X srcshift=%X]\n", dstart, dend, pwidth, srcshift);
3756 fflush(stdout);
3757 }
3758 #endif
3759 //uint32 srcAddr, pixAddr;
3760 //ADDRGEN(srcAddr, pixAddr, gena2i, zaddr,
3761 //      a1_x, a1_y, a1_base, a1_pitch, a1_pixsize, a1_width, a1_zoffset,
3762 //      a2_x, a2_y, a2_base, a2_pitch, a2_pixsize, a2_width, a2_zoffset);
3763                                         srcd2 = srcd1;
3764                                         srcd1 = ((uint64)JaguarReadLong(address + 0, BLITTER) << 32)
3765                                                 | (uint64)JaguarReadLong(address + 4, BLITTER);
3766 //Kludge to take pixel size into account...
3767 //Hmm. If we're not in phrase mode, this is most likely NOT going to be used...
3768 //Actually, it would be--because of BCOMPEN expansion, for example...
3769 if (!phrase_mode)
3770 {
3771         if (bcompen)
3772                 srcd1 >>= 56;
3773         else
3774         {
3775                 if (pixsize == 5)
3776                         srcd1 >>= 32;
3777                 else if (pixsize == 4)
3778                         srcd1 >>= 48;
3779                 else
3780                         srcd1 >>= 56;
3781         }
3782 }//*/
3783 #ifdef VERBOSE_BLITTER_LOGGING
3784 if (logBlit)
3785 {
3786 printf("    Source extra read address/pix address: %08X/%1X [%08X%08X]\n", address, pixAddr,
3787         (uint32)(srcd1 >> 32), (uint32)(srcd1 & 0xFFFFFFFF));
3788 fflush(stdout);
3789 }
3790 #endif
3791                                 }
3792
3793                                 if (szreadx)
3794                                 {
3795 #ifdef VERBOSE_BLITTER_LOGGING
3796 if (logBlit)
3797 {
3798 printf("  Entering SZREADX state...");
3799 fflush(stdout);
3800 }
3801 #endif
3802                                         srcz2 = srcz1;
3803                                         srcz1 = ((uint64)JaguarReadLong(address, BLITTER) << 32) | (uint64)JaguarReadLong(address + 4, BLITTER);
3804 #ifdef VERBOSE_BLITTER_LOGGING
3805 if (logBlit)
3806 {
3807         printf(" Src Z extra read address/pix address: %08X/%1X [%08X%08X]\n", address, pixAddr,
3808                 (uint32)(dstz >> 32), (uint32)(dstz & 0xFFFFFFFF));
3809         fflush(stdout);
3810 }
3811 #endif
3812                                 }
3813
3814                                 if (sread)
3815                                 {
3816 #ifdef VERBOSE_BLITTER_LOGGING
3817 if (logBlit)
3818 {
3819 printf("  Entering SREAD state...");
3820 //printf(" [dstart=%X dend=%X pwidth=%X srcshift=%X]\n", dstart, dend, pwidth, srcshift);
3821 fflush(stdout);
3822 }
3823 #endif
3824 //uint32 srcAddr, pixAddr;
3825 //ADDRGEN(srcAddr, pixAddr, gena2i, zaddr,
3826 //      a1_x, a1_y, a1_base, a1_pitch, a1_pixsize, a1_width, a1_zoffset,
3827 //      a2_x, a2_y, a2_base, a2_pitch, a2_pixsize, a2_width, a2_zoffset);
3828 srcd2 = srcd1;
3829 srcd1 = ((uint64)JaguarReadLong(address, BLITTER) << 32) | (uint64)JaguarReadLong(address + 4, BLITTER);
3830 //Kludge to take pixel size into account...
3831 if (!phrase_mode)
3832 {
3833         if (bcompen)
3834                 srcd1 >>= 56;
3835         else
3836         {
3837                 if (pixsize == 5)
3838                         srcd1 >>= 32;
3839                 else if (pixsize == 4)
3840                         srcd1 >>= 48;
3841                 else
3842                         srcd1 >>= 56;
3843         }
3844 }
3845 #ifdef VERBOSE_BLITTER_LOGGING
3846 if (logBlit)
3847 {
3848 printf("     Source read address/pix address: %08X/%1X [%08X%08X]\n", address, pixAddr,
3849         (uint32)(srcd1 >> 32), (uint32)(srcd1 & 0xFFFFFFFF));
3850 fflush(stdout);
3851 }
3852 #endif
3853                                 }
3854
3855                                 if (szread)
3856                                 {
3857 #ifdef VERBOSE_BLITTER_LOGGING
3858 if (logBlit)
3859 {
3860 printf("  Entering SZREAD state...");
3861 fflush(stdout);
3862 }
3863 #endif
3864                                         srcz2 = srcz1;
3865                                         srcz1 = ((uint64)JaguarReadLong(address, BLITTER) << 32) | (uint64)JaguarReadLong(address + 4, BLITTER);
3866 //Kludge to take pixel size into account... I believe that it only has to take 16BPP mode into account. Not sure tho.
3867 if (!phrase_mode && pixsize == 4)
3868         srcz1 >>= 48;
3869
3870 #ifdef VERBOSE_BLITTER_LOGGING
3871 if (logBlit)
3872 {
3873         printf("     Src Z read address/pix address: %08X/%1X [%08X%08X]\n", address, pixAddr,
3874                 (uint32)(dstz >> 32), (uint32)(dstz & 0xFFFFFFFF));
3875         fflush(stdout);
3876 }
3877 #endif
3878                                 }
3879
3880                                 if (dread)
3881                                 {
3882 #ifdef VERBOSE_BLITTER_LOGGING
3883 if (logBlit)
3884 {
3885 printf("  Entering DREAD state...");
3886 fflush(stdout);
3887 }
3888 #endif
3889 //uint32 dstAddr, pixAddr;
3890 //ADDRGEN(dstAddr, pixAddr, gena2i, zaddr,
3891 //      a1_x, a1_y, a1_base, a1_pitch, a1_pixsize, a1_width, a1_zoffset,
3892 //      a2_x, a2_y, a2_base, a2_pitch, a2_pixsize, a2_width, a2_zoffset);
3893 dstd = ((uint64)JaguarReadLong(address, BLITTER) << 32) | (uint64)JaguarReadLong(address + 4, BLITTER);
3894 //Kludge to take pixel size into account...
3895 if (!phrase_mode)
3896 {
3897         if (pixsize == 5)
3898                 dstd >>= 32;
3899         else if (pixsize == 4)
3900                 dstd >>= 48;
3901         else
3902                 dstd >>= 56;
3903 }
3904 #ifdef VERBOSE_BLITTER_LOGGING
3905 if (logBlit)
3906 {
3907 printf("       Dest read address/pix address: %08X/%1X [%08X%08X]\n", address, pixAddr,
3908         (uint32)(dstd >> 32), (uint32)(dstd & 0xFFFFFFFF));
3909 fflush(stdout);
3910 }
3911 #endif
3912                                 }
3913
3914                                 if (dzread)
3915                                 {
3916 // Is Z always 64 bit read? Or sometimes 16 bit (dependent on phrase_mode)?
3917 #ifdef VERBOSE_BLITTER_LOGGING
3918 if (logBlit)
3919 {
3920         printf("  Entering DZREAD state...");
3921         fflush(stdout);
3922 }
3923 #endif
3924                                         dstz = ((uint64)JaguarReadLong(address, BLITTER) << 32) | (uint64)JaguarReadLong(address + 4, BLITTER);
3925 //Kludge to take pixel size into account... I believe that it only has to take 16BPP mode into account. Not sure tho.
3926 if (!phrase_mode && pixsize == 4)
3927         dstz >>= 48;
3928
3929 #ifdef VERBOSE_BLITTER_LOGGING
3930 if (logBlit)
3931 {
3932         printf("    Dest Z read address/pix address: %08X/%1X [%08X%08X]\n", address, pixAddr,
3933                 (uint32)(dstz >> 32), (uint32)(dstz & 0xFFFFFFFF));
3934         fflush(stdout);
3935 }
3936 #endif
3937                                 }
3938
3939 // These vars should probably go further up in the code... !!! FIX !!!
3940 // We can't preassign these unless they're static...
3941 //uint64 srcz = 0;                      // These are assigned to shut up stupid compiler warnings--dwrite is ALWAYS asserted
3942 //bool winhibit = false;
3943 uint64 srcz;
3944 bool winhibit;
3945 //NOTE: SRCSHADE requires GOURZ to be set to work properly--another Jaguar I bug
3946                                 if (dwrite)
3947                                 {
3948 #ifdef VERBOSE_BLITTER_LOGGING
3949 if (logBlit)
3950 {
3951 printf("  Entering DWRITE state...");
3952 fflush(stdout);
3953 }
3954 #endif
3955 //Counter is done on the dwrite state...! (We'll do it first, since it affects dstart/dend calculations.)
3956 //Here's the voodoo for figuring the correct amount of pixels in phrase mode (or not):
3957                                         int8 inct = -((dsta2 ? a2_x : a1_x) & 0x07);    // From INNER_CNT
3958                                         uint8 inc = 0;
3959                                         inc = (!phrase_mode || (phrase_mode && (inct & 0x01)) ? 0x01 : 0x00);
3960                                         inc |= (phrase_mode && (((pixsize == 3 || pixsize == 4) && (inct & 0x02)) || pixsize == 5 && !(inct & 0x01)) ? 0x02 : 0x00);
3961                                         inc |= (phrase_mode && ((pixsize == 3 && (inct & 0x04)) || (pixsize == 4 && !(inct & 0x03))) ? 0x04 : 0x00);
3962                                         inc |= (phrase_mode && pixsize == 3 && !(inct & 0x07) ? 0x08 : 0x00);
3963
3964                                         uint16 oldicount = icount;      // Save icount to detect underflow...
3965                                         icount -= inc;
3966
3967                                         if (icount == 0 || ((icount & 0x8000) && !(oldicount & 0x8000)))
3968                                                 inner0 = true;
3969 // X/Y stepping is also done here, I think...No. It's done when a1_add or a2_add is asserted...
3970
3971 //*********************************************************************************
3972 //Start & end write mask computations...
3973 //*********************************************************************************
3974
3975 uint8 dstart = 0;
3976
3977 if (pixsize == 3)
3978         dstart = (dstxp & 0x07) << 3;
3979 if (pixsize == 4)
3980         dstart = (dstxp & 0x03) << 4;
3981 if (pixsize == 5)
3982         dstart = (dstxp & 0x01) << 5;
3983
3984 dstart = (phrase_mode ? dstart : pixAddr & 0x07);
3985
3986 //This is the other Jaguar I bug... Normally, should ALWAYS select a1_x here.
3987 uint16 dstxwr = (dsta2 ? a2_x : a1_x) & 0x7FFE;
3988 uint16 pseq = dstxwr ^ (a1_win_x & 0x7FFE);
3989 pseq = (pixsize == 5 ? pseq : pseq & 0x7FFC);
3990 pseq = ((pixsize & 0x06) == 4 ? pseq : pseq & 0x7FF8);
3991 bool penden = clip_a1 && (pseq == 0);
3992 uint8 window_mask = 0;
3993
3994 if (pixsize == 3)
3995         window_mask = (a1_win_x & 0x07) << 3;
3996 if (pixsize == 4)
3997         window_mask = (a1_win_x & 0x03) << 4;
3998 if (pixsize == 5)
3999         window_mask = (a1_win_x & 0x01) << 5;
4000
4001 window_mask = (penden ? window_mask : 0);
4002
4003 /*
4004   Entering SREADX state... [dstart=0 dend=20 pwidth=8 srcshift=20]
4005     Source extra read address/pix address: 000095D0/0 [000004E40000001C]
4006   Entering A2_ADD state [a2_x=0002, a2_y=0000, addasel=0, addbsel=1, modx=2, addareg=F, adda_xconst=2, adda_yconst=0]...
4007   Entering SREAD state... [dstart=0 dend=20 pwidth=8 srcshift=20]
4008     Source read address/pix address: 000095D8/0 [0054003800009814]
4009   Entering A2_ADD state [a2_x=0004, a2_y=0000, addasel=0, addbsel=1, modx=2, addareg=F, adda_xconst=2, adda_yconst=0]...
4010   Entering DWRITE state...
4011      Dest write address/pix address: 00037290/0 [dstart=0 dend=20 pwidth=8 srcshift=20][daas=0 dabs=0 dam=7 ds=1 daq=F] [0000001C00000000] (icount=026E, inc=4)
4012   Entering A1_ADD state [a1_x=0000, a1_y=0000, addasel=0, addbsel=0, modx=2, addareg=F, adda_xconst=2, adda_yconst=0]...
4013
4014 (icount=026E, inc=4)
4015 icount & 0x03 = 0x02
4016          << 4 = 0x20
4017
4018 window_mask = 0x1000
4019
4020 Therefore, it chooses the inner_mask over the window_mask every time! Argh!
4021 This is because we did this wrong:
4022 Innerm[3-5]     := AN2 (inner_mask[3-5], imb[3-5], inner0);
4023 NOTE! This doesn't fix the problem because inner0 is asserted too late to help here. !!! FIX !!! [Should be DONE]
4024 */
4025
4026 /* The mask to be used if within one phrase of the end of the inner
4027 loop, similarly */
4028 uint8 inner_mask = 0;
4029
4030 if (pixsize == 3)
4031         inner_mask = (icount & 0x07) << 3;
4032 if (pixsize == 4)
4033         inner_mask = (icount & 0x03) << 4;
4034 if (pixsize == 5)
4035         inner_mask = (icount & 0x01) << 5;
4036 if (!inner0)
4037         inner_mask = 0;
4038 /* The actual mask used should be the lesser of the window masks and
4039 the inner mask, where is all cases 000 means 1000. */
4040 window_mask = (window_mask == 0 ? 0x40 : window_mask);
4041 inner_mask = (inner_mask == 0 ? 0x40 : inner_mask);
4042 uint8 emask = (window_mask > inner_mask ? inner_mask : window_mask);
4043 /* The mask to be used for the pixel size, to which must be added
4044 the bit offset */
4045 uint8 pma = pixAddr + (1 << pixsize);
4046 /* Select the mask */
4047 uint8 dend = (phrase_mode ? emask : pma);
4048
4049 /* The cycle width in phrase mode is normally one phrase.  However,
4050 at the start and end it may be narrower.  The start and end masks
4051 are used to generate this.  The width is given by:
4052
4053         8 - start mask - (8 - end mask)
4054 =       end mask - start mask
4055
4056 This is only used for writes in phrase mode.
4057 Start and end from the address level of the pipeline are used.
4058 */
4059 uint8 pwidth = (((dend | dstart) & 0x07) == 0 ? 0x08 : (dend - dstart) & 0x07);
4060
4061 //uint32 dstAddr, pixAddr;
4062 //ADDRGEN(dstAddr, pixAddr, gena2i, zaddr,
4063 //      a1_x, a1_y, a1_base, a1_pitch, a1_pixsize, a1_width, a1_zoffset,
4064 //      a2_x, a2_y, a2_base, a2_pitch, a2_pixsize, a2_width, a2_zoffset);
4065 #ifdef VERBOSE_BLITTER_LOGGING
4066 if (logBlit)
4067 {
4068         printf("     Dest write address/pix address: %08X/%1X", address, pixAddr);
4069         fflush(stdout);
4070 }
4071 #endif
4072
4073 //More testing... This is almost certainly wrong, but how else does this work???
4074 //Seems to kinda work... But still, this doesn't seem to make any sense!
4075 if (phrase_mode && !dsten)
4076         dstd = ((uint64)JaguarReadLong(address, BLITTER) << 32) | (uint64)JaguarReadLong(address + 4, BLITTER);
4077
4078 //Testing only... for now...
4079 //This is wrong because the write data is a combination of srcd and dstd--either run
4080 //thru the LFU or in PATDSEL or ADDDSEL mode. [DONE now, thru DATA module]
4081 // Precedence is ADDDSEL > PATDSEL > LFU.
4082 //Also, doesn't take into account the start & end masks, or the phrase width...
4083 //Now it does!
4084
4085 // srcd2 = xxxx xxxx 0123 4567, srcd = 8901 2345 xxxx xxxx, srcshift = $20 (32)
4086 uint64 srcd = (srcd2 << (64 - srcshift)) | (srcd1 >> srcshift);
4087 //bleh, ugly ugly ugly
4088 if (srcshift == 0)
4089         srcd = srcd1;
4090
4091 //NOTE: This only works with pixel sizes less than 8BPP...
4092 //DOUBLE NOTE: Still need to do regression testing to ensure that this doesn't break other stuff... !!! CHECK !!!
4093 if (!phrase_mode && srcshift != 0)
4094         srcd = ((srcd2 & 0xFF) << (8 - srcshift)) | ((srcd1 & 0xFF) >> srcshift);
4095
4096 //Z DATA() stuff done here... And it has to be done before any Z shifting...
4097 //Note that we need to have phrase mode start/end support here... (Not since we moved it from dzwrite...!)
4098 /*
4099 Here are a couple of Cybermorph blits with Z:
4100 $00113078       // DSTEN DSTENZ DSTWRZ CLIP_A1 GOURD GOURZ PATDSEL ZMODE=4
4101 $09900F39       // SRCEN DSTEN DSTENZ DSTWRZ UPDA1 UPDA1F UPDA2 DSTA2 ZMODE=4 LFUFUNC=C DCOMPEN
4102
4103 We're having the same phrase mode overwrite problem we had with the pixels... !!! FIX !!!
4104 Odd. It's equating 0 with 0... Even though ZMODE is $04 (less than)!
4105 */
4106 if (gourz)
4107 {
4108 /*
4109 void ADDARRAY(uint16 * addq, uint8 daddasel, uint8 daddbsel, uint8 daddmode,
4110         uint64 dstd, uint32 iinc, uint8 initcin[], uint64 initinc, uint16 initpix,
4111         uint32 istep, uint64 patd, uint64 srcd, uint64 srcz1, uint64 srcz2,
4112         uint32 zinc, uint32 zstep)
4113 */
4114         uint16 addq[4];
4115         uint8 initcin[4] = { 0, 0, 0, 0 };
4116         ADDARRAY(addq, 7/*daddasel*/, 6/*daddbsel*/, 0/*daddmode*/, 0, 0, initcin, 0, 0, 0, 0, 0, srcz1, srcz2, zinc, 0);
4117         srcz2 = ((uint64)addq[3] << 48) | ((uint64)addq[2] << 32) | ((uint64)addq[1] << 16) | (uint64)addq[0];
4118         ADDARRAY(addq, 6/*daddasel*/, 7/*daddbsel*/, 1/*daddmode*/, 0, 0, initcin, 0, 0, 0, 0, 0, srcz1, srcz2, zinc, 0);
4119         srcz1 = ((uint64)addq[3] << 48) | ((uint64)addq[2] << 32) | ((uint64)addq[1] << 16) | (uint64)addq[0];
4120
4121 #if 0//def VERBOSE_BLITTER_LOGGING
4122 if (logBlit)
4123 {
4124         printf("\n[srcz1=%08X%08X, srcz2=%08X%08X, zinc=%08X",
4125                 (uint32)(srcz1 >> 32), (uint32)(srcz1 & 0xFFFFFFFF),
4126                 (uint32)(srcz2 >> 32), (uint32)(srcz2 & 0xFFFFFFFF), zinc);
4127         fflush(stdout);
4128 }
4129 #endif
4130 }
4131
4132 uint8 zSrcShift = srcshift & 0x30;
4133 srcz = (srcz2 << (64 - zSrcShift)) | (srcz1 >> zSrcShift);
4134 //bleh, ugly ugly ugly
4135 if (zSrcShift == 0)
4136         srcz = srcz1;
4137
4138 #if 0//def VERBOSE_BLITTER_LOGGING
4139 if (logBlit)
4140 {
4141         printf(" srcz=%08X%08X]\n", (uint32)(srcz >> 32), (uint32)(srcz & 0xFFFFFFFF));
4142         fflush(stdout);
4143 }
4144 #endif
4145
4146 //When in SRCSHADE mode, it adds the IINC to the read source (from LFU???)
4147 //According to following line, it gets LFU mode. But does it feed the source into the LFU
4148 //after the add?
4149 //Dest write address/pix address: 0014E83E/0 [dstart=0 dend=10 pwidth=8 srcshift=0][daas=4 dabs=5 dam=7 ds=1 daq=F] [0000000000006505] (icount=003F, inc=1)
4150 //Let's try this:
4151 if (srcshade)
4152 {
4153 //NOTE: This is basically doubling the work done by DATA--since this is what
4154 //      ADDARRAY is loaded with when srschshade is enabled... !!! FIX !!!
4155 //      Also note that it doesn't work properly unless GOURZ is set--there's the clue!
4156         uint16 addq[4];
4157         uint8 initcin[4] = { 0, 0, 0, 0 };
4158         ADDARRAY(addq, 4/*daddasel*/, 5/*daddbsel*/, 7/*daddmode*/, dstd, iinc, initcin, 0, 0, 0, patd, srcd, 0, 0, 0, 0);
4159         srcd = ((uint64)addq[3] << 48) | ((uint64)addq[2] << 32) | ((uint64)addq[1] << 16) | (uint64)addq[0];
4160 }
4161 //Seems to work... Not 100% sure tho.
4162 //end try this
4163
4164 //Temporary kludge, to see if the fractional pattern does anything...
4165 //This works, BTW
4166 //But it seems to mess up in Cybermorph... the shading should be smooth but it isn't...
4167 //Seems the carry out is lost again... !!! FIX !!! [DONE--see below]
4168 if (patfadd)
4169 {
4170         uint16 addq[4];
4171         uint8 initcin[4] = { 0, 0, 0, 0 };
4172         ADDARRAY(addq, 4/*daddasel*/, 4/*daddbsel*/, 0/*daddmode*/, dstd, iinc, initcin, 0, 0, 0, patd, srcd, 0, 0, 0, 0);
4173         srcd1 = ((uint64)addq[3] << 48) | ((uint64)addq[2] << 32) | ((uint64)addq[1] << 16) | (uint64)addq[0];
4174 }
4175
4176 //Note that we still don't take atick[0] & [1] into account here, so this will skip half of the data needed... !!! FIX !!!
4177 //Not yet enumerated: dbinh, srcdread, srczread
4178 //Also, should do srcshift on the z value in phrase mode... !!! FIX !!! [DONE]
4179 //As well as add a srcz variable we can set external to this state... !!! FIX !!! [DONE]
4180
4181 uint64 wdata;
4182 uint8 dcomp, zcomp;
4183 DATA(wdata, dcomp, zcomp, winhibit,
4184         true, cmpdst, daddasel, daddbsel, daddmode, daddq_sel, data_sel, 0/*dbinh*/,
4185         dend, dstart, dstd, iinc, lfufunc, patd, patdadd,
4186         phrase_mode, srcd, false/*srcdread*/, false/*srczread*/, srcz2add, zmode,
4187         bcompen, bkgwren, dcompen, icount & 0x07, pixsize,
4188         srcz, dstz, zinc);
4189 /*
4190 Seems that the phrase mode writes with DCOMPEN and DSTEN are corrupting inside of DATA: !!! FIX !!!
4191 It's fairly random as well. 7CFE -> 7DFE, 7FCA -> 78CA, 7FA4 -> 78A4, 7F88 -> 8F88
4192 It could be related to an uninitialized variable, like the zmode bug...
4193 [DONE]
4194 It was a bug in the dech38el data--it returned $FF for ungated instead of $00...
4195
4196 Blit! (CMD = 09800609)
4197 Flags: SRCEN DSTEN UPDA1 UPDA2 LFUFUNC=C DCOMPEN
4198   count = 10 x 12
4199   a1_base = 00110000, a2_base = 0010B2A8
4200   a1_x = 004B, a1_y = 00D8, a1_frac_x = 0000, a1_frac_y = 0000, a2_x = 0704, a2_y = 0000
4201   a1_step_x = FFF3, a1_step_y = 0001, a1_stepf_x = 0000, a1_stepf_y = 0000, a2_step_x = FFFC, a2_step_y = 0000
4202   a1_inc_x = 0000, a1_inc_y = 0000, a1_incf_x = 0000, a1_incf_y = 0000
4203   a1_win_x = 0000, a1_win_y = 0000, a2_mask_x = 0000, a2_mask_y = 0000
4204   a2_mask=F a1add=+phr/+0 a2add=+phr/+0
4205   a1_pixsize = 4, a2_pixsize = 4
4206    srcd=0000000000000000  dstd=0000000000000000 patd=0000000000000000 iinc=00000000
4207   srcz1=0000000000000000 srcz2=0000000000000000 dstz=0000000000000000 zinc=00000000, coll=0
4208   Phrase mode is ON
4209   [in=T a1f=F a1=F zf=F z=F a2=F iif=F iii=F izf=F izi=F]
4210   Entering INNER state...
4211   Entering SREAD state...    Source read address/pix address: 0010C0B0/0 [0000000078047804]
4212   Entering A2_ADD state [a2_x=0704, a2_y=0000, addasel=0, addbsel=1, modx=2, addareg=F, adda_xconst=2, adda_yconst=0]...
4213   Entering DREAD state...
4214       Dest read address/pix address: 00197240/0 [0000000000000028]
4215   Entering DWRITE state...
4216      Dest write address/pix address: 00197240/0 [dstart=30 dend=40 pwidth=8 srcshift=30][daas=0 dabs=0 dam=7 ds=1 daq=F] [0000000000000028] (icount=0009, inc=1)
4217   Entering A1_ADD state [a1_x=004B, a1_y=00D8, addasel=0, addbsel=0, modx=2, addareg=F, adda_xconst=2, adda_yconst=0]...
4218   Entering SREAD state...    Source read address/pix address: 0010C0B8/0 [7804780478047804]
4219   Entering A2_ADD state [a2_x=0708, a2_y=0000, addasel=0, addbsel=1, modx=2, addareg=F, adda_xconst=2, adda_yconst=0]...
4220   Entering DREAD state...
4221       Dest read address/pix address: 00197260/0 [0028000000200008]
4222   Entering DWRITE state...
4223      Dest write address/pix address: 00197260/0 [dstart=0 dend=40 pwidth=8 srcshift=30][daas=0 dabs=0 dam=7 ds=1 daq=F] [0028780478047804] (icount=0005, inc=4)
4224   Entering A1_ADD state [a1_x=004C, a1_y=00D8, addasel=0, addbsel=0, modx=2, addareg=F, adda_xconst=2, adda_yconst=0]...
4225   Entering SREAD state...    Source read address/pix address: 0010C0C0/0 [0000000000000000]
4226   Entering A2_ADD state [a2_x=070C, a2_y=0000, addasel=0, addbsel=1, modx=2, addareg=F, adda_xconst=2, adda_yconst=0]...
4227   Entering DREAD state...
4228       Dest read address/pix address: 00197280/0 [0008001800180018]
4229   Entering DWRITE state...
4230      Dest write address/pix address: 00197280/0 [dstart=0 dend=40 pwidth=8 srcshift=30][daas=0 dabs=0 dam=7 ds=1 daq=F] [7804780478040018] (icount=0001, inc=4)
4231   Entering A1_ADD state [a1_x=0050, a1_y=00D8, addasel=0, addbsel=0, modx=2, addareg=F, adda_xconst=2, adda_yconst=0]...
4232   Entering SREAD state...    Source read address/pix address: 0010C0C8/0 [000078047BFE7BFE]
4233   Entering A2_ADD state [a2_x=0710, a2_y=0000, addasel=0, addbsel=1, modx=2, addareg=F, adda_xconst=2, adda_yconst=0]...
4234   Entering DREAD state...
4235       Dest read address/pix address: 001972A0/0 [0008002000000000]
4236   Entering DWRITE state...
4237      Dest write address/pix address: 001972A0/0 [dstart=0 dend=10 pwidth=8 srcshift=30][daas=0 dabs=0 dam=7 ds=1 daq=F] [0008002000000000] (icount=FFFD, inc=4)
4238   Entering A1_ADD state [a1_x=0054, a1_y=00D8, addasel=0, addbsel=0, modx=2, addareg=F, adda_xconst=2, adda_yconst=0]...
4239   Entering IDLE_INNER state...
4240 */
4241
4242 //Why isn't this taken care of in DATA? Because, DATA is modifying its local copy instead of the one used here.
4243 //!!! FIX !!! [DONE]
4244 //if (patdadd)
4245 //      patd = wdata;
4246
4247 //if (patfadd)
4248 //      srcd1 = wdata;
4249
4250 /*
4251 DEF ADDRCOMP (
4252         a1_outside      // A1 pointer is outside window bounds
4253         :OUT;
4254 INT16/  a1_x
4255 INT16/  a1_y
4256 INT15/  a1_win_x
4257 INT15/  a1_win_y
4258         :IN);
4259 BEGIN
4260
4261 // The address is outside if negative, or if greater than or equal
4262 // to the window size
4263
4264 A1_xcomp        := MAG_15 (a1xgr, a1xeq, a1xlt, a1_x{0..14}, a1_win_x{0..14});
4265 A1_ycomp        := MAG_15 (a1ygr, a1yeq, a1ylt, a1_y{0..14}, a1_win_y{0..14});
4266 A1_outside      := OR6 (a1_outside, a1_x{15}, a1xgr, a1xeq, a1_y{15}, a1ygr, a1yeq);
4267 */
4268 //NOTE: There seems to be an off-by-one bug here in the clip_a1 section... !!! FIX !!!
4269 //      Actually, seems to be related to phrase mode writes...
4270 //      Or is it? Could be related to non-15-bit compares as above?
4271 if (clip_a1 && ((a1_x & 0x8000) || (a1_y & 0x8000) || (a1_x >= a1_win_x) || (a1_y >= a1_win_y)))
4272         winhibit = true;
4273
4274 if (!winhibit)
4275 {
4276         if (phrase_mode)
4277         {
4278                 JaguarWriteLong(address + 0, wdata >> 32, BLITTER);
4279                 JaguarWriteLong(address + 4, wdata & 0xFFFFFFFF, BLITTER);
4280         }
4281         else
4282         {
4283                 if (pixsize == 5)
4284                         JaguarWriteLong(address, wdata & 0xFFFFFFFF, BLITTER);
4285                 else if (pixsize == 4)
4286                         JaguarWriteWord(address, wdata & 0x0000FFFF, BLITTER);
4287                 else
4288                         JaguarWriteByte(address, wdata & 0x000000FF, BLITTER);
4289         }
4290 }
4291
4292 #ifdef VERBOSE_BLITTER_LOGGING
4293 if (logBlit)
4294 {
4295         printf(" [%08X%08X]%s", (uint32)(wdata >> 32), (uint32)(wdata & 0xFFFFFFFF), (winhibit ? "[X]" : ""));
4296         printf(" (icount=%04X, inc=%u)\n", icount, (uint16)inc);
4297         printf("    [dstart=%X dend=%X pwidth=%X srcshift=%X]", dstart, dend, pwidth, srcshift);
4298         printf("[daas=%X dabs=%X dam=%X ds=%X daq=%s]\n", daddasel, daddbsel, daddmode, data_sel, (daddq_sel ? "T" : "F"));
4299         fflush(stdout);
4300 }
4301 #endif
4302                                 }
4303
4304                                 if (dzwrite)
4305                                 {
4306 // OK, here's the big insight: When NOT in GOURZ mode, srcz1 & 2 function EXACTLY the same way that
4307 // srcd1 & 2 work--there's an implicit shift from srcz1 to srcz2 whenever srcz1 is read.
4308 // OTHERWISE, srcz1 is the integer for the computed Z and srcz2 is the fractional part.
4309 // Writes to srcz1 & 2 follow the same pattern as the other 64-bit registers--low 32 at the low address,
4310 // high 32 at the high address (little endian!).
4311 // NOTE: GOURZ is still not properly supported. Check patd/patf handling...
4312 //       Phrase mode start/end masks are not properly supported either...
4313 #ifdef VERBOSE_BLITTER_LOGGING
4314 if (logBlit)
4315 {
4316         printf("  Entering DZWRITE state...");
4317         printf("  Dest Z write address/pix address: %08X/%1X [%08X%08X]\n", address, pixAddr,
4318                 (uint32)(srcz >> 32), (uint32)(srcz & 0xFFFFFFFF));
4319         fflush(stdout);
4320 }
4321 #endif
4322 //This is not correct... !!! FIX !!!
4323 //Should be OK now... We'll see...
4324 //Nope. Having the same starstep write problems in phrase mode as we had with pixels... !!! FIX !!!
4325 //This is not causing the problem in Hover Strike... :-/
4326 //The problem was with the SREADX not shifting. Still problems with Z comparisons & other text in pregame screen...
4327 if (!winhibit)
4328 {
4329         if (phrase_mode)
4330         {
4331                 JaguarWriteLong(address + 0, srcz >> 32, BLITTER);
4332                 JaguarWriteLong(address + 4, srcz & 0xFFFFFFFF, BLITTER);
4333         }
4334         else
4335         {
4336                 if (pixsize == 4)
4337                         JaguarWriteWord(address, srcz & 0x0000FFFF, BLITTER);
4338         }
4339 }//*/
4340 #ifdef VERBOSE_BLITTER_LOGGING
4341 if (logBlit)
4342 {
4343 //      printf(" [%08X%08X]\n", (uint32)(srcz >> 32), (uint32)(srcz & 0xFFFFFFFF));
4344 //      fflush(stdout);
4345 //printf(" [dstart=%X dend=%X pwidth=%X srcshift=%X]", dstart, dend, pwidth, srcshift);
4346         printf("    [dstart=? dend=? pwidth=? srcshift=%X]", srcshift);
4347         printf("[daas=%X dabs=%X dam=%X ds=%X daq=%s]\n", daddasel, daddbsel, daddmode, data_sel, (daddq_sel ? "T" : "F"));
4348         fflush(stdout);
4349 }
4350 #endif
4351                                 }
4352
4353 /*
4354 This is because the address generator was using only 15 bits of the X when it should have
4355 used 16!
4356
4357 There's a slight problem here: The X pointer isn't wrapping like it should when it hits
4358 the edge of the window... Notice how the X isn't reset at the edge of the window:
4359
4360 Blit! (CMD = 00010000)
4361 Flags: PATDSEL
4362   count = 160 x 261
4363   a1_base = 000E8008, a2_base = 0001FA68
4364   a1_x = 0000, a1_y = 0000, a1_frac_x = 0000, a1_frac_y = 0000, a2_x = 0000, a2_y = 0000
4365   a1_step_x = 0000, a1_step_y = 0000, a1_stepf_x = 0000, a1_stepf_y = 0000, a2_step_x = 0000, a2_step_y = 0000
4366   a1_inc_x = 0000, a1_inc_y = 0000, a1_incf_x = 0000, a1_incf_y = 0000
4367   a1_win_x = 0000, a1_win_y = 0000, a2_mask_x = 0000, a2_mask_y = 0000
4368   a2_mask=F a1add=+phr/+0 a2add=+phr/+0
4369   a1_pixsize = 5, a2_pixsize = 5
4370    srcd=7717771777177717  dstd=0000000000000000 patd=7730773077307730 iinc=00000000
4371   srcz1=0000000000000000 srcz2=0000000000000000 dstz=0000000000000000 zinc=00000000, coll=0
4372   Phrase mode is ON
4373   [in=T a1f=F a1=F zf=F z=F a2=F iif=F iii=F izf=F izi=F]
4374   Entering INNER state...
4375   Entering DWRITE state...     Dest write address/pix address: 000E8008/0 [7730773077307730] (icount=009E, inc=2)
4376  srcz=0000000000000000][dcomp=AA zcomp=00 dbinh=00]
4377 [srcz=0000000000000000 dstz=0000000000000000 zwdata=0000000000000000 mask=7FFF]
4378     [dstart=0 dend=40 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=0 daq=F]
4379   Entering A1_ADD state [a1_x=0000, a1_y=0000, addasel=0, addbsel=0, modx=1, addareg=F, adda_xconst=1, adda_yconst=0]...
4380   Entering DWRITE state...     Dest write address/pix address: 000E8018/0 [7730773077307730] (icount=009C, inc=2)
4381  srcz=0000000000000000][dcomp=AA zcomp=00 dbinh=00]
4382 [srcz=0000000000000000 dstz=0000000000000000 zwdata=0000000000000000 mask=7FFF]
4383     [dstart=0 dend=40 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=0 daq=F]
4384   Entering A1_ADD state [a1_x=0002, a1_y=0000, addasel=0, addbsel=0, modx=1, addareg=F, adda_xconst=1, adda_yconst=0]...
4385
4386 ...
4387
4388   Entering A1_ADD state [a1_x=009C, a1_y=0000, addasel=0, addbsel=0, modx=1, addareg=F, adda_xconst=1, adda_yconst=0]...
4389   Entering DWRITE state...     Dest write address/pix address: 000E84F8/0 [7730773077307730] (icount=0000, inc=2)
4390  srcz=0000000000000000][dcomp=AA zcomp=00 dbinh=00]
4391 [srcz=0000000000000000 dstz=0000000000000000 zwdata=0000000000000000 mask=7FFF]
4392     [dstart=0 dend=40 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=0 daq=F]
4393   Entering A1_ADD state [a1_x=009E, a1_y=0000, addasel=0, addbsel=0, modx=1, addareg=F, adda_xconst=1, adda_yconst=0]...
4394   Entering IDLE_INNER state...
4395
4396   Leaving INNER state... (ocount=0104)
4397   [in=T a1f=F a1=F zf=F z=F a2=F iif=F iii=F izf=F izi=F]
4398
4399   Entering INNER state...
4400   Entering DWRITE state...     Dest write address/pix address: 000E8508/0 [7730773077307730] (icount=009E, inc=2)
4401  srcz=0000000000000000][dcomp=AA zcomp=00 dbinh=00]
4402 [srcz=0000000000000000 dstz=0000000000000000 zwdata=0000000000000000 mask=7FFF]
4403     [dstart=0 dend=40 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=0 daq=F]
4404   Entering A1_ADD state [a1_x=00A0, a1_y=0000, addasel=0, addbsel=0, modx=1, addareg=F, adda_xconst=1, adda_yconst=0]...
4405   Entering DWRITE state...     Dest write address/pix address: 000E8518/0 [7730773077307730] (icount=009C, inc=2)
4406  srcz=0000000000000000][dcomp=AA zcomp=00 dbinh=00]
4407 [srcz=0000000000000000 dstz=0000000000000000 zwdata=0000000000000000 mask=7FFF]
4408     [dstart=0 dend=40 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=0 daq=F]
4409   Entering A1_ADD state [a1_x=00A2, a1_y=0000, addasel=0, addbsel=0, modx=1, addareg=F, adda_xconst=1, adda_yconst=0]...
4410
4411 */
4412
4413                                 if (a1_add)
4414                                 {
4415 #ifdef VERBOSE_BLITTER_LOGGING
4416 if (logBlit)
4417 {
4418 //printf("  Entering A1_ADD state [addasel=%X, addbsel=%X, modx=%X, addareg=%s, adda_xconst=%u, adda_yconst=%s]...\n", addasel, addbsel, modx, (addareg ? "T" : "F"), adda_xconst, (adda_yconst ? "1" : "0"));
4419 printf("  Entering A1_ADD state [a1_x=%04X, a1_y=%04X, addasel=%X, addbsel=%X, modx=%X, addareg=%s, adda_xconst=%u, adda_yconst=%s]...\n", a1_x, a1_y, addasel, addbsel, modx, (addareg ? "T" : "F"), adda_xconst, (adda_yconst ? "1" : "0"));
4420 fflush(stdout);
4421 }
4422 #endif
4423 int16 adda_x, adda_y, addb_x, addb_y, data_x, data_y, addq_x, addq_y;
4424 ADDAMUX(adda_x, adda_y, addasel, a1_step_x, a1_step_y, a1_stepf_x, a1_stepf_y, a2_step_x, a2_step_y,
4425         a1_inc_x, a1_inc_y, a1_incf_x, a1_incf_y, adda_xconst, adda_yconst, addareg, suba_x, suba_y);
4426 ADDBMUX(addb_x, addb_y, addbsel, a1_x, a1_y, a2_x, a2_y, a1_frac_x, a1_frac_y);
4427 ADDRADD(addq_x, addq_y, a1fracldi, adda_x, adda_y, addb_x, addb_y, modx, suba_x, suba_y);
4428
4429 #if 0//def VERBOSE_BLITTER_LOGGING
4430 if (logBlit)
4431 {
4432 printf("  [adda_x=%d, adda_y=%d, addb_x=%d, addb_y=%d, addq_x=%d, addq_y=%d]\n", adda_x, adda_y, addb_x, addb_y, addq_x, addq_y);
4433 fflush(stdout);
4434 }
4435 #endif
4436 //Now, write to what???
4437 //a2ptrld comes from a2ptrldi...
4438 //I believe it's addbsel that determines the writeback...
4439 // This is where atick[0] & [1] come in, in determining which part (fractional, integer)
4440 // gets written to...
4441 //a1_x = addq_x;
4442 //a1_y = addq_y;
4443 //Kludge, to get A1 channel increment working...
4444 if (a1addx == 3)
4445 {
4446         a1_frac_x = addq_x, a1_frac_y = addq_y;
4447
4448 addasel = 2, addbsel = 0, a1fracldi = false;
4449 ADDAMUX(adda_x, adda_y, addasel, a1_step_x, a1_step_y, a1_stepf_x, a1_stepf_y, a2_step_x, a2_step_y,
4450         a1_inc_x, a1_inc_y, a1_incf_x, a1_incf_y, adda_xconst, adda_yconst, addareg, suba_x, suba_y);
4451 ADDBMUX(addb_x, addb_y, addbsel, a1_x, a1_y, a2_x, a2_y, a1_frac_x, a1_frac_y);
4452 ADDRADD(addq_x, addq_y, a1fracldi, adda_x, adda_y, addb_x, addb_y, modx, suba_x, suba_y);
4453
4454         a1_x = addq_x, a1_y = addq_y;
4455 }
4456 else
4457         a1_x = addq_x, a1_y = addq_y;
4458                                 }
4459
4460                                 if (a2_add)
4461                                 {
4462 #ifdef VERBOSE_BLITTER_LOGGING
4463 if (logBlit)
4464 {
4465 //printf("  Entering A2_ADD state [addasel=%X, addbsel=%X, modx=%X, addareg=%s, adda_xconst=%u, adda_yconst=%s]...\n", addasel, addbsel, modx, (addareg ? "T" : "F"), adda_xconst, (adda_yconst ? "1" : "0"));
4466 printf("  Entering A2_ADD state [a2_x=%04X, a2_y=%04X, addasel=%X, addbsel=%X, modx=%X, addareg=%s, adda_xconst=%u, adda_yconst=%s]...\n", a2_x, a2_y, addasel, addbsel, modx, (addareg ? "T" : "F"), adda_xconst, (adda_yconst ? "1" : "0"));
4467 fflush(stdout);
4468 }
4469 #endif
4470 //void ADDAMUX(int16 &adda_x, int16 &adda_y, uint8 addasel, int16 a1_step_x, int16 a1_step_y,
4471 //      int16 a1_stepf_x, int16 a1_stepf_y, int16 a2_step_x, int16 a2_step_y,
4472 //      int16 a1_inc_x, int16 a1_inc_y, int16 a1_incf_x, int16 a1_incf_y, uint8 adda_xconst,
4473 //      bool adda_yconst, bool addareg, bool suba_x, bool suba_y)
4474 //void ADDBMUX(int16 &addb_x, int16 &addb_y, uint8 addbsel, int16 a1_x, int16 a1_y,
4475 //      int16 a2_x, int16 a2_y, int16 a1_frac_x, int16 a1_frac_y)
4476 //void ADDRADD(int16 &addq_x, int16 &addq_y, bool a1fracldi,
4477 //      int16 adda_x, int16 adda_y, int16 addb_x, int16 addb_y, uint8 modx, bool suba_x, bool suba_y)
4478 //void DATAMUX(int16 &data_x, int16 &data_y, uint32 gpu_din, int16 addq_x, int16 addq_y, bool addqsel)
4479 int16 adda_x, adda_y, addb_x, addb_y, data_x, data_y, addq_x, addq_y;
4480 ADDAMUX(adda_x, adda_y, addasel, a1_step_x, a1_step_y, a1_stepf_x, a1_stepf_y, a2_step_x, a2_step_y,
4481         a1_inc_x, a1_inc_y, a1_incf_x, a1_incf_y, adda_xconst, adda_yconst, addareg, suba_x, suba_y);
4482 ADDBMUX(addb_x, addb_y, addbsel, a1_x, a1_y, a2_x, a2_y, a1_frac_x, a1_frac_y);
4483 ADDRADD(addq_x, addq_y, a1fracldi, adda_x, adda_y, addb_x, addb_y, modx, suba_x, suba_y);
4484
4485 #if 0//def VERBOSE_BLITTER_LOGGING
4486 if (logBlit)
4487 {
4488 printf("  [adda_x=%d, adda_y=%d, addb_x=%d, addb_y=%d, addq_x=%d, addq_y=%d]\n", adda_x, adda_y, addb_x, addb_y, addq_x, addq_y);
4489 fflush(stdout);
4490 }
4491 #endif
4492 //Now, write to what???
4493 //a2ptrld comes from a2ptrldi...
4494 //I believe it's addbsel that determines the writeback...
4495 a2_x = addq_x;
4496 a2_y = addq_y;
4497                                 }
4498                         }
4499 /*
4500 Flags: SRCEN CLIP_A1 UPDA1 UPDA1F UPDA2 DSTA2 GOURZ ZMODE=0 LFUFUNC=C SRCSHADE
4501   count = 64 x 55
4502   a1_base = 0015B000, a2_base = 0014B000
4503   a1_x = 0000, a1_y = 0000, a1_frac_x = 8000, a1_frac_y = 8000, a2_x = 001F, a2_y = 0038
4504   a1_step_x = FFFFFFC0, a1_step_y = 0001, a1_stepf_x = 0000, a1_stepf_y = 2AAA, a2_step_x = FFFFFFC0, a2_step_y = 0001
4505   a1_inc_x = 0001, a1_inc_y = 0000, a1_incf_x = 0000, a1_incf_y = 0000
4506   a1_win_x = 0040, a1_win_y = 0040, a2_mask_x = 0000, a2_mask_y = 0000
4507   a2_mask=F a1add=+inc/+0 a2add=+1/+0
4508   a1_pixsize = 4, a2_pixsize = 4
4509    srcd=FF00FF00FF00FF00  dstd=0000000000000000 patd=0000000000000000 iinc=00000000
4510   srcz1=0000000000000000 srcz2=0000000000000000 dstz=0000000000000000 zinc=00000000, col=0
4511   Phrase mode is off
4512   [in=T a1f=F a1=F zf=F z=F a2=F iif=F iii=F izf=F izi=F]
4513   Entering INNER state...
4514   Entering SREAD state...    Source read address/pix address: 0015B000/0 [6505650565056505]
4515   Entering A1_ADD state [a1_x=0000, a1_y=0000, addasel=3, addbsel=2, modx=0, addareg=T, adda_xconst=7, adda_yconst=0]...
4516   Entering DWRITE state...
4517      Dest write address/pix address: 0014E83E/0 [dstart=0 dend=10 pwidth=8 srcshift=0][daas=4 dabs=5 dam=7 ds=1 daq=F] [0000000000006505] (icount=003F, inc=1)
4518   Entering A2_ADD state [a2_x=001F, a2_y=0038, addasel=0, addbsel=1, modx=0, addareg=F, adda_xconst=0, adda_yconst=0]...
4519   Entering SREAD state...    Source read address/pix address: 0015B000/0 [6505650565056505]
4520   Entering A1_ADD state [a1_x=FFFF8000, a1_y=FFFF8000, addasel=3, addbsel=2, modx=0, addareg=T, adda_xconst=7, adda_yconst=0]...
4521   Entering DWRITE state...
4522      Dest write address/pix address: 0014E942/0 [dstart=0 dend=10 pwidth=8 srcshift=0][daas=4 dabs=5 dam=7 ds=1 daq=F] [0000000000006505] (icount=003E, inc=1)
4523   Entering A2_ADD state [a2_x=0021, a2_y=0039, addasel=0, addbsel=1, modx=0, addareg=F, adda_xconst=0, adda_yconst=0]...
4524   Entering SREAD state...    Source read address/pix address: 0015B000/0 [6505650565056505]
4525   Entering A1_ADD state [a1_x=FFFF8000, a1_y=FFFF8000, addasel=3, addbsel=2, modx=0, addareg=T, adda_xconst=7, adda_yconst=0]...
4526   Entering DWRITE state...
4527      Dest write address/pix address: 0014EA46/0 [dstart=0 dend=10 pwidth=8 srcshift=0][daas=4 dabs=5 dam=7 ds=1 daq=F] [0000000000006505] (icount=003D, inc=1)
4528   Entering A2_ADD state [a2_x=0023, a2_y=003A, addasel=0, addbsel=1, modx=0, addareg=F, adda_xconst=0, adda_yconst=0]...
4529   Entering SREAD state...    Source read address/pix address: 0015B000/0 [6505650565056505]
4530   Entering A1_ADD state [a1_x=FFFF8000, a1_y=FFFF8000, addasel=3, addbsel=2, modx=0, addareg=T, adda_xconst=7, adda_yconst=0]...
4531   Entering DWRITE state...
4532      Dest write address/pix address: 0014EB4A/0 [dstart=0 dend=10 pwidth=8 srcshift=0][daas=4 dabs=5 dam=7 ds=1 daq=F] [0000000000006505] (icount=003C, inc=1)
4533   Entering A2_ADD state [a2_x=0025, a2_y=003B, addasel=0, addbsel=1, modx=0, addareg=F, adda_xconst=0, adda_yconst=0]...
4534   ...
4535   Entering SREAD state...    Source read address/pix address: 0015B000/0 [6505650565056505]
4536   Entering A1_ADD state [a1_x=FFFF8000, a1_y=FFFF8000, addasel=3, addbsel=2, modx=0, addareg=T, adda_xconst=7, adda_yconst=0]...
4537   Entering DWRITE state...
4538      Dest write address/pix address: 0015283A/0 [dstart=0 dend=10 pwidth=8 srcshift=0][daas=4 dabs=5 dam=7 ds=1 daq=F] [0000000000006505] (icount=0000, inc=1)
4539   Entering A2_ADD state [a2_x=009D, a2_y=0077, addasel=0, addbsel=1, modx=0, addareg=F, adda_xconst=0, adda_yconst=0]...
4540   Entering IDLE_INNER state...
4541   Leaving INNER state... (ocount=0036)
4542   [in=F a1f=T a1=F zf=F z=F a2=F iif=F iii=F izf=F izi=F]
4543   Entering A1FUPDATE state...
4544   [in=F a1f=F a1=T zf=F z=F a2=F iif=F iii=F izf=F izi=F]
4545   Entering A1UPDATE state... (-32768/-32768 -> 32704/-32767)
4546   [in=F a1f=F a1=F zf=F z=F a2=T iif=F iii=F izf=F izi=F]
4547   Entering A2UPDATE state... (159/120 -> 95/121)
4548   [in=T a1f=F a1=F zf=F z=F a2=F iif=F iii=F izf=F izi=F]
4549   Entering INNER state...
4550 */
4551
4552 #ifdef VERBOSE_BLITTER_LOGGING
4553 if (logBlit)
4554 {
4555 printf("  Leaving INNER state...");
4556 fflush(stdout);
4557 }
4558 #endif
4559                         indone = true;
4560 // The outer counter is updated here as well on the clock cycle...
4561
4562 /* the inner loop is started whenever another state is about to
4563 cause the inner state to go active */
4564 //Instart               := ND7 (instart, innert[0], innert[2..7]);
4565
4566 //Actually, it's done only when inner gets asserted without the 2nd line of conditions
4567 //(inner AND !indone)
4568 //fixed now...
4569 //Since we don't get here until the inner loop is finished (indone = true) we can get
4570 //away with doing it here...!
4571                         ocount--;
4572                 
4573                         if (ocount == 0)
4574                                 outer0 = true;
4575 #ifdef VERBOSE_BLITTER_LOGGING
4576 if (logBlit)
4577 {
4578 printf(" (ocount=%04X)\n", ocount);
4579 fflush(stdout);
4580 }
4581 #endif
4582                 }
4583
4584                 if (a1fupdate)
4585                 {
4586 #ifdef VERBOSE_BLITTER_LOGGING
4587 if (logBlit)
4588 {
4589 printf("  Entering A1FUPDATE state...\n");
4590 fflush(stdout);
4591 }
4592 #endif
4593                         uint32 a1_frac_xt = (uint32)a1_frac_x + (uint32)a1_stepf_x;
4594                         uint32 a1_frac_yt = (uint32)a1_frac_y + (uint32)a1_stepf_y;
4595                         a1FracCInX = a1_frac_xt >> 16;
4596                         a1FracCInY = a1_frac_yt >> 16;
4597                         a1_frac_x = (uint16)(a1_frac_xt & 0xFFFF);
4598                         a1_frac_y = (uint16)(a1_frac_yt & 0xFFFF);
4599                 }
4600
4601                 if (a1update)
4602                 {
4603 #ifdef VERBOSE_BLITTER_LOGGING
4604 if (logBlit)
4605 {
4606 printf("  Entering A1UPDATE state... (%d/%d -> ", a1_x, a1_y);
4607 fflush(stdout);
4608 }
4609 #endif
4610                         a1_x += a1_step_x + a1FracCInX;
4611                         a1_y += a1_step_y + a1FracCInY;
4612 #ifdef VERBOSE_BLITTER_LOGGING
4613 if (logBlit)
4614 {
4615 printf("%d/%d)\n", a1_x, a1_y);
4616 fflush(stdout);
4617 }
4618 #endif
4619                 }
4620                 
4621                 if (a2update)
4622                 {
4623 #ifdef VERBOSE_BLITTER_LOGGING
4624 if (logBlit)
4625 {
4626 printf("  Entering A2UPDATE state... (%d/%d -> ", a2_x, a2_y);
4627 fflush(stdout);
4628 }
4629 #endif
4630                         a2_x += a2_step_x;
4631                         a2_y += a2_step_y;
4632 #ifdef VERBOSE_BLITTER_LOGGING
4633 if (logBlit)
4634 {
4635 printf("%d/%d)\n", a2_x, a2_y);
4636 fflush(stdout);
4637 }
4638 #endif
4639                 }
4640         }
4641
4642 // We never get here! !!! FIX !!!
4643
4644 #ifdef VERBOSE_BLITTER_LOGGING
4645 if (logBlit)
4646 {
4647         printf("Done!\na1_x=%04X a1_y=%04X a1_frac_x=%04X a1_frac_y=%04X a2_x=%04X a2_y%04X\n", 
4648                 GET16(blitter_ram, A1_PIXEL + 2),
4649                 GET16(blitter_ram, A1_PIXEL + 0),
4650                 GET16(blitter_ram, A1_FPIXEL + 2),
4651                 GET16(blitter_ram, A1_FPIXEL + 0),
4652                 GET16(blitter_ram, A2_PIXEL + 2),
4653                 GET16(blitter_ram, A2_PIXEL + 0));
4654         fflush(stdout);
4655 }
4656 #endif
4657
4658         // Write values back to registers (in real blitter, these are continuously updated)
4659         SET16(blitter_ram, A1_PIXEL + 2, a1_x);
4660         SET16(blitter_ram, A1_PIXEL + 0, a1_y);
4661         SET16(blitter_ram, A1_FPIXEL + 2, a1_frac_x);
4662         SET16(blitter_ram, A1_FPIXEL + 0, a1_frac_y);
4663         SET16(blitter_ram, A2_PIXEL + 2, a2_x);
4664         SET16(blitter_ram, A2_PIXEL + 0, a2_y);
4665
4666 #ifdef VERBOSE_BLITTER_LOGGING
4667 if (logBlit)
4668 {
4669         printf("Writeback!\na1_x=%04X a1_y=%04X a1_frac_x=%04X a1_frac_y=%04X a2_x=%04X a2_y%04X\n", 
4670                 GET16(blitter_ram, A1_PIXEL + 2),
4671                 GET16(blitter_ram, A1_PIXEL + 0),
4672                 GET16(blitter_ram, A1_FPIXEL + 2),
4673                 GET16(blitter_ram, A1_FPIXEL + 0),
4674                 GET16(blitter_ram, A2_PIXEL + 2),
4675                 GET16(blitter_ram, A2_PIXEL + 0));
4676         fflush(stdout);
4677 }
4678 #endif
4679 }
4680
4681 /*
4682         int16 a1_x = (int16)GET16(blitter_ram, A1_PIXEL + 2);
4683         int16 a1_y = (int16)GET16(blitter_ram, A1_PIXEL + 0);
4684         uint16 a1_frac_x = GET16(blitter_ram, A1_FPIXEL + 2);
4685         uint16 a1_frac_y = GET16(blitter_ram, A1_FPIXEL + 0);
4686         int16 a2_x = (int16)GET16(blitter_ram, A2_PIXEL + 2);
4687         int16 a2_y = (int16)GET16(blitter_ram, A2_PIXEL + 0);
4688
4689 Seems that the ending a1_x should be written between blits, but it doesn't seem to be...
4690
4691 Blit! (CMD = 01800000)
4692 Flags: LFUFUNC=C
4693   count = 28672 x 1
4694   a1_base = 00050000, a2_base = 00070000
4695   a1_x = 0000, a1_y = 0000, a1_frac_x = 49CD, a1_frac_y = 0000, a2_x = 0033, a2_y = 0001
4696   a1_step_x = 0000, a1_step_y = 0000, a1_stepf_x = 939A, a1_stepf_y = 0000, a2_step_x = 0000, a2_step_y = 0000
4697   a1_inc_x = 0000, a1_inc_y = 0000, a1_incf_x = 0000, a1_incf_y = 0000
4698   a1_win_x = 0100, a1_win_y = 0020, a2_mask_x = 0000, a2_mask_y = 0000
4699   a2_mask=F a1add=+phr/+0 a2add=+phr/+0
4700   a1_pixsize = 4, a2_pixsize = 3
4701    srcd=DEDEDEDEDEDEDEDE  dstd=0000000000000000 patd=0000000000000000 iinc=00000000
4702   srcz1=0000000000000000 srcz2=0000000000000000 dstz=0000000000000000 zinc=00000000, coll=0
4703   Phrase mode is ON
4704
4705 Blit! (CMD = 01800000)
4706 Flags: LFUFUNC=C
4707   count = 28672 x 1
4708   a1_base = 00050000, a2_base = 00070000
4709   a1_x = 0000, a1_y = 0000, a1_frac_x = 49CD, a1_frac_y = 0000, a2_x = 0033, a2_y = 0001
4710   a1_step_x = 0000, a1_step_y = 0000, a1_stepf_x = 939A, a1_stepf_y = 0000, a2_step_x = 0000, a2_step_y = 0000
4711   a1_inc_x = 0000, a1_inc_y = 0000, a1_incf_x = 0000, a1_incf_y = 0000
4712   a1_win_x = 0100, a1_win_y = 0020, a2_mask_x = 0000, a2_mask_y = 0000
4713   a2_mask=F a1add=+phr/+0 a2add=+phr/+0
4714   a1_pixsize = 4, a2_pixsize = 3
4715    srcd=D6D6D6D6D6D6D6D6  dstd=0000000000000000 patd=0000000000000000 iinc=00000000
4716   srcz1=0000000000000000 srcz2=0000000000000000 dstz=0000000000000000 zinc=00000000, coll=0
4717   Phrase mode is ON
4718 */
4719
4720
4721
4722 // Various pieces of the blitter puzzle are teased out here...
4723
4724
4725
4726 /*
4727 DEF ADDRGEN (
4728 INT24/  address         // byte address
4729                 pixa[0..2]      // bit part of address, un-pipe-lined
4730                 :OUT;
4731 INT16/  a1_x
4732 INT16/  a1_y
4733 INT21/  a1_base
4734                 a1_pitch[0..1]
4735                 a1_pixsize[0..2]
4736                 a1_width[0..5]
4737                 a1_zoffset[0..1]
4738 INT16/  a2_x
4739 INT16/  a2_y
4740 INT21/  a2_base
4741                 a2_pitch[0..1]
4742                 a2_pixsize[0..2]
4743                 a2_width[0..5]
4744                 a2_zoffset[0..1]
4745                 apipe           // load address pipe-line latch
4746                 clk                     // co-processor clock
4747                 gena2           // generate A2 as opposed to A1
4748                 zaddr           // generate Z address
4749                 :IN);
4750 */
4751
4752 void ADDRGEN(uint32 &address, uint32 &pixa, bool gena2, bool zaddr,
4753         uint16 a1_x, uint16 a1_y, uint32 a1_base, uint8 a1_pitch, uint8 a1_pixsize, uint8 a1_width, uint8 a1_zoffset,
4754         uint16 a2_x, uint16 a2_y, uint32 a2_base, uint8 a2_pitch, uint8 a2_pixsize, uint8 a2_width, uint8 a2_zoffset)
4755 {
4756 //      uint16 x = (gena2 ? a2_x : a1_x) & 0x7FFF;
4757         uint16 x = (gena2 ? a2_x : a1_x) & 0xFFFF;      // Actually uses all 16 bits to generate address...!
4758         uint16 y = (gena2 ? a2_y : a1_y) & 0x0FFF;
4759         uint8 width = (gena2 ? a2_width : a1_width);
4760         uint8 pixsize = (gena2 ? a2_pixsize : a1_pixsize);
4761         uint8 pitch = (gena2 ? a2_pitch : a1_pitch);
4762         uint32 base = (gena2 ? a2_base : a1_base) >> 3;//Only upper 21 bits are passed around the bus? Seems like it...
4763         uint8 zoffset = (gena2 ? a2_zoffset : a1_zoffset);
4764
4765         uint32 ytm = ((uint32)y << 2) + (width & 0x02 ? (uint32)y << 1 : 0) + (width & 0x01 ? (uint32)y : 0);
4766
4767         uint32 ya = (ytm << (width >> 2)) >> 2;
4768
4769         uint32 pa = ya + x;
4770
4771         /*uint32*/ pixa = pa << pixsize;
4772
4773         uint8 pt = ((pitch & 0x01) && !(pitch & 0x02) ? 0x01 : 0x00)
4774                 | (!(pitch & 0x01) && (pitch & 0x02) ? 0x02 : 0x00);
4775 //      uint32 phradr = pixa << pt;
4776         uint32 phradr = (pixa >> 6) << pt;
4777         uint32 shup = (pitch == 0x03 ? (pixa >> 6) : 0);
4778
4779         uint8 za = (zaddr ? zoffset : 0) & 0x03;
4780 //      uint32 addr = za + (phradr & 0x07) + (shup << 1) + base;
4781         uint32 addr = za + phradr + (shup << 1) + base;
4782         /*uint32*/ address = ((pixa & 0x38) >> 3) | ((addr & 0x1FFFFF) << 3);
4783 #if 0//def VERBOSE_BLITTER_LOGGING
4784 if (logBlit)
4785 {
4786 printf("    [gena2=%s, x=%04X, y=%04X, w=%1X, pxsz=%1X, ptch=%1X, b=%08X, zoff=%1X]\n", (gena2 ? "T" : "F"), x, y, width, pixsize, pitch, base, zoffset);
4787 printf("    [ytm=%X, ya=%X, pa=%X, pixa=%X, pt=%X, phradr=%X, shup=%X, za=%X, addr=%X, address=%X]\n", ytm, ya, pa, pixa, pt, phradr, shup, za, addr, address);
4788 fflush(stdout);
4789 }
4790 #endif
4791         pixa &= 0x07;
4792 /*
4793   Entering INNER state...
4794     [gena2=T, x=0002, y=0000, w=20, pxsz=4, ptch=0, b=000012BA, zoff=0]
4795     [ytm=0, ya=0, pa=2, pixa=20, pt=0, phradr=0, shup=0, za=0, addr=12BA, address=95D4]
4796   Entering SREADX state... [dstart=0 dend=20 pwidth=8 srcshift=20]
4797     Source extra read address/pix address: 000095D4/0 [0000001C00540038]
4798   Entering A2_ADD state [a2_x=0002, a2_y=0000, addasel=0, addbsel=1, modx=2, addareg=F, adda_xconst=2, adda_yconst=0]...
4799     [gena2=T, x=0004, y=0000, w=20, pxsz=4, ptch=0, b=000012BA, zoff=0]
4800     [ytm=0, ya=0, pa=4, pixa=40, pt=0, phradr=1, shup=0, za=0, addr=12BB, address=95D8]
4801   Entering SREAD state... [dstart=0 dend=20 pwidth=8 srcshift=0]
4802     Source read address/pix address: 000095D8/0 [0054003800009814]
4803   Entering A2_ADD state [a2_x=0004, a2_y=0000, addasel=0, addbsel=1, modx=2, addareg=F, adda_xconst=2, adda_yconst=0]...
4804     [gena2=F, x=0000, y=0000, w=20, pxsz=4, ptch=0, b=00006E52, zoff=0]
4805     [ytm=0, ya=0, pa=0, pixa=0, pt=0, phradr=0, shup=0, za=0, addr=6E52, address=37290]
4806   Entering DWRITE state...
4807      Dest write address/pix address: 00037290/0 [dstart=0 dend=20 pwidth=8 srcshift=0] (icount=026E, inc=4)
4808   Entering A1_ADD state [a1_x=0000, a1_y=0000, addasel=0, addbsel=0, modx=2, addareg=F, adda_xconst=2, adda_yconst=0]...
4809     [gena2=T, x=0008, y=0000, w=20, pxsz=4, ptch=0, b=000012BA, zoff=0]
4810     [ytm=0, ya=0, pa=8, pixa=80, pt=0, phradr=2, shup=0, za=0, addr=12BC, address=95E0]
4811 */
4812 /*
4813 Obviously wrong:
4814   Entering SREAD state...
4815     [gena2=T, x=0004, y=0000, w=20, pxsz=4, ptch=0, b=000010AC, zoff=0]
4816     [ytm=0, ya=0, pa=4, pixa=0, pt=0, phradr=40, shup=0, za=0, addr=10AC, address=8560]
4817     Source read address/pix address: 00008560/0 [8C27981B327E00F0]
4818
4819 2nd pass (still wrong):
4820   Entering SREAD state...
4821     [gena2=T, x=0004, y=0000, w=20, pxsz=4, ptch=0, b=000010AC, zoff=0]
4822     [ytm=0, ya=0, pa=4, pixa=0, pt=0, phradr=40, shup=0, za=0, addr=10EC, address=8760]
4823     Source read address/pix address: 00008760/0 [00E06DC04581880C]
4824
4825 Correct!:
4826   Entering SREAD state...
4827     [gena2=T, x=0004, y=0000, w=20, pxsz=4, ptch=0, b=000010AC, zoff=0]
4828     [ytm=0, ya=0, pa=4, pixa=0, pt=0, phradr=1, shup=0, za=0, addr=10AD, address=8568]
4829     Source read address/pix address: 00008568/0 [6267981A327C00F0]
4830
4831 OK, now we're back into incorrect (or is it?):
4832   Entering SREADX state... [dstart=0 dend=20 pwidth=8 srcshift=20]
4833     Source extra read address/pix address: 000095D4/0 [0000 001C 0054 0038]
4834   Entering A2_ADD state [a2_x=0002, a2_y=0000, addasel=0, addbsel=1, modx=2, addareg=F, adda_xconst=2, adda_yconst=0]...
4835   Entering SREAD state... [dstart=0 dend=20 pwidth=8 srcshift=0]
4836     Source read address/pix address: 000095D8/0 [0054 0038 0000 9814]
4837   Entering A2_ADD state [a2_x=0004, a2_y=0000, addasel=0, addbsel=1, modx=2, addareg=F, adda_xconst=2, adda_yconst=0]...
4838 I think this may be correct...!
4839 */
4840 }
4841
4842 /*
4843 // source and destination address update conditions
4844
4845 Sraat0          := AN2 (sraat[0], sreadxi, srcenz\);
4846 Sraat1          := AN2 (sraat[1], sreadi, srcenz\);
4847 Srca_addi       := OR4 (srca_addi, szreadxi, szreadi, sraat[0..1]);
4848 Srca_add        := FD1Q (srca_add, srca_addi, clk);
4849
4850 Dstaat          := AN2 (dstaat, dwritei, dstwrz\);
4851 Dsta_addi       := OR2 (dsta_addi, dzwritei, dstaat);
4852 // Dsta_add     := FD1Q (dsta_add, dsta_addi, clk);
4853
4854 // source and destination address generate conditions
4855
4856 Gensrc          := OR4 (gensrc, sreadxi, szreadxi, sreadi, szreadi);
4857 Gendst          := OR4 (gendst, dreadi, dzreadi, dwritei, dzwritei);
4858 Dsta2\          := INV1 (dsta2\, dsta2);
4859 Gena2t0         := NAN2 (gena2t[0], gensrc, dsta2\);
4860 Gena2t1         := NAN2 (gena2t[1], gendst, dsta2);
4861 Gena2i          := NAN2 (gena2i, gena2t[0..1]);
4862 Gena2           := FD1QU (gena2, gena2i, clk);
4863
4864 Zaddr           := OR4 (zaddr, szreadx, szread, dzread, dzwrite);
4865 */
4866
4867 /*void foo(void)
4868 {
4869         // Basically, the above translates to:
4870         bool srca_addi = (sreadxi && !srcenz) || (sreadi && !srcenz) || szreadxi || szreadi;
4871
4872         bool dsta_addi = (dwritei && !dstwrz) || dzwritei;
4873
4874         bool gensrc = sreadxi || szreadxi || sreadi || szreadi;
4875         bool gendst = dreadi || szreadi || dwritei || dzwritei;
4876         bool gena2i = (gensrc && !dsta2) || (gendst && dsta2);
4877
4878         bool zaddr = szreadx || szread || dzread || dzwrite;
4879 }*/
4880
4881 /*
4882 // source data reads
4883
4884 Srcdpset\       := NAN2 (srcdpset\, readreq, sread);
4885 Srcdpt1         := NAN2 (srcdpt[1], srcdpend, srcdack\);
4886 Srcdpt2         := NAN2 (srcdpt[2], srcdpset\, srcdpt[1]);
4887 Srcdpend        := FD2Q (srcdpend, srcdpt[2], clk, reset\);
4888
4889 Srcdxpset\      := NAN2 (srcdxpset\, readreq, sreadx);
4890 Srcdxpt1        := NAN2 (srcdxpt[1], srcdxpend, srcdxack\);
4891 Srcdxpt2        := NAN2 (srcdxpt[2], srcdxpset\, srcdxpt[1]);
4892 Srcdxpend       := FD2Q (srcdxpend, srcdxpt[2], clk, reset\);
4893
4894 Sdpend          := OR2 (sdpend, srcdxpend, srcdpend);
4895 Srcdreadt       := AN2 (srcdreadt, sdpend, read_ack);
4896
4897 //2/9/92 - enhancement?
4898 //Load srcdread on the next tick as well to modify it in srcshade
4899
4900 Srcdreadd       := FD1Q (srcdreadd, srcdreadt, clk);
4901 Srcdread        := AOR1 (srcdread, srcshade, srcdreadd, srcdreadt);
4902
4903 // source zed reads
4904
4905 Srczpset\       := NAN2 (srczpset\, readreq, szread);
4906 Srczpt1         := NAN2 (srczpt[1], srczpend, srczack\);
4907 Srczpt2         := NAN2 (srczpt[2], srczpset\, srczpt[1]);
4908 Srczpend        := FD2Q (srczpend, srczpt[2], clk, reset\);
4909
4910 Srczxpset\      := NAN2 (srczxpset\, readreq, szreadx);
4911 Srczxpt1        := NAN2 (srczxpt[1], srczxpend, srczxack\);
4912 Srczxpt2        := NAN2 (srczxpt[2], srczxpset\, srczxpt[1]);
4913 Srczxpend       := FD2Q (srczxpend, srczxpt[2], clk, reset\);
4914
4915 Szpend          := OR2 (szpend, srczpend, srczxpend);
4916 Srczread        := AN2 (srczread, szpend, read_ack);
4917
4918 // destination data reads
4919
4920 Dstdpset\       := NAN2 (dstdpset\, readreq, dread);
4921 Dstdpt0         := NAN2 (dstdpt[0], dstdpend, dstdack\);
4922 Dstdpt1         := NAN2 (dstdpt[1], dstdpset\, dstdpt[0]);
4923 Dstdpend        := FD2Q (dstdpend, dstdpt[1], clk, reset\);
4924 Dstdread        := AN2 (dstdread, dstdpend, read_ack);
4925
4926 // destination zed reads
4927
4928 Dstzpset\       := NAN2 (dstzpset\, readreq, dzread);
4929 Dstzpt0         := NAN2 (dstzpt[0], dstzpend, dstzack\);
4930 Dstzpt1         := NAN2 (dstzpt[1], dstzpset\, dstzpt[0]);
4931 Dstzpend        := FD2Q (dstzpend, dstzpt[1], clk, reset\);
4932 Dstzread        := AN2 (dstzread, dstzpend, read_ack);
4933 */
4934
4935 /*void foo2(void)
4936 {
4937         // Basically, the above translates to:
4938         bool srcdpend = (readreq && sread) || (srcdpend && !srcdack);
4939         bool srcdxpend = (readreq && sreadx) || (srcdxpend && !srcdxack);
4940         bool sdpend = srcxpend || srcdpend;
4941         bool srcdread = ((sdpend && read_ack) && srcshade) || (sdpend && read_ack);//the latter term is lookahead
4942
4943 }*/
4944
4945 ////////////////////////////////////////////////////////////////////////////////////////////
4946 ////////////////////////////////////////////////////////////////////////////////////////////
4947 // Here's an important bit: The source data adder logic. Need to track down the inputs!!! //
4948 ////////////////////////////////////////////////////////////////////////////////////////////
4949 ////////////////////////////////////////////////////////////////////////////////////////////
4950
4951 /*
4952 DEF ADDARRAY (
4953 INT16/  addq[0..3]
4954         :OUT;
4955         clk
4956         daddasel[0..2]  // data adder input A selection
4957         daddbsel[0..3]
4958         daddmode[0..2]
4959 INT32/  dstd[0..1]
4960 INT32/  iinc
4961         initcin[0..3]   // carry into the adders from the initializers
4962         initinc[0..63]  // the initialisation increment
4963         initpix[0..15]  // Data initialiser pixel value
4964 INT32/  istep
4965 INT32/  patd[0..1]
4966 INT32/  srcdlo
4967 INT32/  srcdhi
4968 INT32/  srcz1[0..1]
4969 INT32/  srcz2[0..1]
4970         reset\
4971 INT32/  zinc
4972 INT32/  zstep
4973         :IN);
4974 */
4975 void ADDARRAY(uint16 * addq, uint8 daddasel, uint8 daddbsel, uint8 daddmode,
4976         uint64 dstd, uint32 iinc, uint8 initcin[], uint64 initinc, uint16 initpix,
4977         uint32 istep, uint64 patd, uint64 srcd, uint64 srcz1, uint64 srcz2,
4978         uint32 zinc, uint32 zstep)
4979 {
4980         uint32 initpix2 = ((uint32)initpix << 16) | initpix;
4981         uint32 addalo[8], addahi[8];
4982         addalo[0] = dstd & 0xFFFFFFFF;
4983         addalo[1] = initpix2;
4984         addalo[2] = 0;
4985         addalo[3] = 0;
4986         addalo[4] = srcd & 0xFFFFFFFF;
4987         addalo[5] = patd & 0xFFFFFFFF;
4988         addalo[6] = srcz1 & 0xFFFFFFFF;
4989         addalo[7] = srcz2 & 0xFFFFFFFF;
4990         addahi[0] = dstd >> 32;
4991         addahi[1] = initpix2;
4992         addahi[2] = 0;
4993         addahi[3] = 0;
4994         addahi[4] = srcd >> 32;
4995         addahi[5] = patd >> 32;
4996         addahi[6] = srcz1 >> 32;
4997         addahi[7] = srcz2 >> 32;
4998         uint16 adda[4];
4999         adda[0] = addalo[daddasel] & 0xFFFF;
5000         adda[1] = addalo[daddasel] >> 16;
5001         adda[2] = addahi[daddasel] & 0xFFFF;
5002         adda[3] = addahi[daddasel] >> 16;
5003
5004         uint16 wordmux[8];
5005         wordmux[0] = iinc & 0xFFFF;
5006         wordmux[1] = iinc >> 16;
5007         wordmux[2] = zinc & 0xFFFF;
5008         wordmux[3] = zinc >> 16;;
5009         wordmux[4] = istep & 0xFFFF;
5010         wordmux[5] = istep >> 16;;
5011         wordmux[6] = zstep & 0xFFFF;
5012         wordmux[7] = zstep >> 16;;
5013         uint16 word = wordmux[((daddbsel & 0x08) >> 1) | (daddbsel & 0x03)];
5014         uint16 addb[4];
5015         bool dbsel2 = daddbsel & 0x04;
5016         bool iincsel = (daddbsel & 0x01) && !(daddbsel & 0x04);
5017
5018         if (!dbsel2 && !iincsel)
5019                 addb[0] = srcd & 0xFFFF,
5020                 addb[1] = (srcd >> 16) & 0xFFFF,
5021                 addb[2] = (srcd >> 32) & 0xFFFF,
5022                 addb[3] = (srcd >> 48) & 0xFFFF;
5023         else if (dbsel2 && !iincsel)
5024                 addb[0] = addb[1] = addb[2] = addb[3] = word;
5025         else if (!dbsel2 && iincsel)
5026                 addb[0] = initinc & 0xFFFF,
5027                 addb[1] = (initinc >> 16) & 0xFFFF,
5028                 addb[2] = (initinc >> 32) & 0xFFFF,
5029                 addb[3] = (initinc >> 48) & 0xFFFF;
5030         else
5031                 addb[0] = addb[1] = addb[2] = addb[3] = 0;
5032
5033         uint8 cinsel = (daddmode >= 1 && daddmode <= 4 ? 1 : 0);
5034
5035 static uint8 co[4];//These are preserved between calls...
5036         uint8 cin[4];
5037
5038         for(int i=0; i<4; i++)
5039                 cin[i] = initcin[i] | (co[i] & cinsel);
5040
5041         bool eightbit = daddmode & 0x02;
5042         bool sat = daddmode & 0x03;
5043         bool hicinh = ((daddmode & 0x03) == 0x03);
5044
5045 //Note that the carry out is saved between calls to this function...
5046         for(int i=0; i<4; i++)
5047                 ADD16SAT(addq[i], co[i], adda[i], addb[i], cin[i], sat, eightbit, hicinh);
5048 }
5049
5050 /*
5051 DEF ADD16SAT (
5052 INT16/  r               // result
5053         co              // carry out
5054         :IO;
5055 INT16/  a
5056 INT16/  b
5057         cin
5058         sat
5059         eightbit
5060         hicinh
5061         :IN);
5062 */
5063 void ADD16SAT(uint16 &r, uint8 &co, uint16 a, uint16 b, uint8 cin, bool sat, bool eightbit, bool hicinh)
5064 {
5065 /*if (logBlit)
5066 {
5067         printf("--> [sat=%s 8b=%s hicinh=%s] %04X + %04X (+ %u) = ", (sat ? "T" : "F"), (eightbit ? "T" : "F"), (hicinh ? "T" : "F"), a, b, cin);
5068         fflush(stdout);
5069 }*/
5070         uint8 carry[4];
5071         uint32 qt = (a & 0xFF) + (b & 0xFF) + cin;
5072         carry[0] = (qt & 0x0100 ? 1 : 0);
5073         uint16 q = qt & 0x00FF;
5074         carry[1] = (carry[0] && !eightbit ? carry[0] : 0);
5075         qt = (a & 0x0F00) + (b & 0x0F00) + (carry[1] << 8);
5076         carry[2] = (qt & 0x1000 ? 1 : 0);
5077         q |= qt & 0x0F00;
5078         carry[3] = (carry[2] && !hicinh ? carry[2] : 0);
5079         qt = (a & 0xF000) + (b & 0xF000) + (carry[3] << 12);
5080         co = (qt & 0x10000 ? 1 : 0);
5081         q |= qt & 0xF000;
5082
5083         uint8 btop = (eightbit ? (b & 0x0080) >> 7 : (b & 0x8000) >> 15);
5084         uint8 ctop = (eightbit ? carry[0] : co);
5085
5086         bool saturate = sat && (btop ^ ctop);
5087         bool hisaturate = saturate && !eightbit;
5088 /*if (logBlit)
5089 {
5090         printf("bt=%u ct=%u s=%u hs=%u] ", btop, ctop, saturate, hisaturate);
5091         fflush(stdout);
5092 }*/
5093
5094         r = (saturate ? (ctop ? 0x00FF : 0x0000) : q & 0x00FF);
5095         r |= (hisaturate ? (ctop ? 0xFF00 : 0x0000) : q & 0xFF00);
5096 /*if (logBlit)
5097 {
5098         printf("%04X (co=%u)\n", r, co);
5099         fflush(stdout);
5100 }*/
5101 }
5102
5103 /**  ADDAMUX - Address adder input A selection  *******************
5104
5105 This module generates the data loaded into the address adder input A.  This is
5106 the update value, and can be one of four registers :  A1 step, A2 step, A1
5107 increment and A1 fraction.  It can complement these values to perform
5108 subtraction, and it can generate constants to increment / decrement the window
5109 pointers.
5110
5111 addasel[0..2] select the register to add
5112
5113 000     A1 step integer part
5114 001     A1 step fraction part
5115 010     A1 increment integer part
5116 011     A1 increment fraction part
5117 100     A2 step
5118
5119 adda_xconst[0..2] generate a power of 2 in the range 1-64 or all zeroes when
5120 they are all 1.
5121
5122 addareg selects register value to be added as opposed to constant 
5123 value.
5124
5125 suba_x, suba_y complement the X and Y values
5126
5127 */
5128
5129 /*
5130 DEF ADDAMUX (
5131 INT16/  adda_x
5132 INT16/  adda_y
5133         :OUT;
5134         addasel[0..2]
5135 INT16/  a1_step_x
5136 INT16/  a1_step_y
5137 INT16/  a1_stepf_x
5138 INT16/  a1_stepf_y
5139 INT16/  a2_step_x
5140 INT16/  a2_step_y
5141 INT16/  a1_inc_x
5142 INT16/  a1_inc_y
5143 INT16/  a1_incf_x
5144 INT16/  a1_incf_y
5145         adda_xconst[0..2]
5146         adda_yconst
5147         addareg
5148         suba_x
5149         suba_y :IN);
5150 */
5151 void ADDAMUX(int16 &adda_x, int16 &adda_y, uint8 addasel, int16 a1_step_x, int16 a1_step_y,
5152         int16 a1_stepf_x, int16 a1_stepf_y, int16 a2_step_x, int16 a2_step_y,
5153         int16 a1_inc_x, int16 a1_inc_y, int16 a1_incf_x, int16 a1_incf_y, uint8 adda_xconst,
5154         bool adda_yconst, bool addareg, bool suba_x, bool suba_y)
5155 {
5156
5157 /*INT16/        addac_x, addac_y, addar_x, addar_y, addart_x, addart_y, 
5158 INT16/  addas_x, addas_y, suba_x16, suba_y16
5159 :LOCAL;
5160 BEGIN
5161
5162 Zero            := TIE0 (zero);*/
5163
5164 /* Multiplex the register terms */
5165
5166 /*Addaselb[0-2] := BUF8 (addaselb[0-2], addasel[0-2]);
5167 Addart_x        := MX4 (addart_x, a1_step_x, a1_stepf_x, a1_inc_x, a1_incf_x, addaselb[0..1]);
5168 Addar_x         := MX2 (addar_x, addart_x, a2_step_x, addaselb[2]);
5169 Addart_y        := MX4 (addart_y, a1_step_y, a1_stepf_y, a1_inc_y, a1_incf_y, addaselb[0..1]);
5170 Addar_y         := MX2 (addar_y, addart_y, a2_step_y, addaselb[2]);*/
5171
5172 ////////////////////////////////////// C++ CODE //////////////////////////////////////
5173         int16 xterm[4], yterm[4];
5174         xterm[0] = a1_step_x, xterm[1] = a1_stepf_x, xterm[2] = a1_inc_x, xterm[3] = a1_incf_x;
5175         yterm[0] = a1_step_y, yterm[1] = a1_stepf_y, yterm[2] = a1_inc_y, yterm[3] = a1_incf_y;
5176         int16 addar_x = (addasel & 0x04 ? a2_step_x : xterm[addasel & 0x03]);
5177         int16 addar_y = (addasel & 0x04 ? a2_step_y : yterm[addasel & 0x03]);
5178 //////////////////////////////////////////////////////////////////////////////////////
5179
5180 /* Generate a constant value - this is a power of 2 in the range 
5181 0-64, or zero.  The control bits are adda_xconst[0..2], when they
5182 are all 1  the result is 0.
5183 Constants for Y can only be 0 or 1 */
5184
5185 /*Addac_xlo     := D38H (addac_x[0..6], unused[0], adda_xconst[0..2]);
5186 Unused[0]       := DUMMY (unused[0]);
5187
5188 Addac_x         := JOIN (addac_x, addac_x[0..6], zero, zero, zero, zero, zero, zero, zero, zero, zero);
5189 Addac_y         := JOIN (addac_y, adda_yconst, zero, zero, zero, zero, zero, zero, zero, zero, zero, zero, 
5190                         zero, zero, zero, zero, zero);*/
5191 ////////////////////////////////////// C++ CODE //////////////////////////////////////
5192         int16 addac_x = (adda_xconst == 0x07 ? 0 : 1 << adda_xconst);
5193         int16 addac_y = (adda_yconst ? 0x01 : 0);
5194 //////////////////////////////////////////////////////////////////////////////////////
5195
5196 /* Select between constant value and register value */
5197
5198 /*Addas_x               := MX2 (addas_x, addac_x, addar_x, addareg);
5199 Addas_y         := MX2 (addas_y, addac_y, addar_y, addareg);*/
5200 ////////////////////////////////////// C++ CODE //////////////////////////////////////
5201         int16 addas_x = (addareg ? addar_x : addac_x);
5202         int16 addas_y = (addareg ? addar_y : addac_y);
5203 //////////////////////////////////////////////////////////////////////////////////////
5204
5205 /* Complement these values (complement flag gives adder carry in)*/
5206
5207 /*Suba_x16      := JOIN (suba_x16, suba_x, suba_x, suba_x, suba_x, suba_x, suba_x, suba_x, suba_x, suba_x, 
5208                         suba_x, suba_x, suba_x, suba_x, suba_x, suba_x, suba_x);
5209 Suba_y16        := JOIN (suba_y16, suba_y, suba_y, suba_y, suba_y, suba_y, suba_y, suba_y, suba_y, suba_y, 
5210                         suba_y, suba_y, suba_y, suba_y, suba_y, suba_y, suba_y);
5211 Adda_x          := EO (adda_x, suba_x16, addas_x);
5212 Adda_y          := EO (adda_y, suba_y16, addas_y);*/
5213 ////////////////////////////////////// C++ CODE //////////////////////////////////////
5214         adda_x = addas_x ^ (suba_x ? 0xFFFF : 0x0000);
5215         adda_y = addas_y ^ (suba_y ? 0xFFFF : 0x0000);
5216 //////////////////////////////////////////////////////////////////////////////////////
5217
5218 //END;
5219 }
5220
5221 /**  ADDBMUX - Address adder input B selection  *******************
5222
5223 This module selects the register to be updated by the address 
5224 adder.  This can be one of three registers, the A1 and A2 
5225 pointers, or the A1 fractional part. It can also be zero, so that the step 
5226 registers load directly into the pointers.
5227 */
5228
5229 /*DEF ADDBMUX (
5230 INT16/  addb_x
5231 INT16/  addb_y
5232         :OUT;
5233         addbsel[0..1]
5234 INT16/  a1_x
5235 INT16/  a1_y
5236 INT16/  a2_x
5237 INT16/  a2_y
5238 INT16/  a1_frac_x
5239 INT16/  a1_frac_y
5240         :IN);
5241 INT16/  zero16 :LOCAL;
5242 BEGIN*/
5243 void ADDBMUX(int16 &addb_x, int16 &addb_y, uint8 addbsel, int16 a1_x, int16 a1_y,
5244         int16 a2_x, int16 a2_y, int16 a1_frac_x, int16 a1_frac_y)
5245 {
5246
5247 /*Zero          := TIE0 (zero);
5248 Zero16          := JOIN (zero16, zero, zero, zero, zero, zero, zero, zero, 
5249                         zero, zero, zero, zero, zero, zero, zero, zero, zero);
5250 Addbselb[0-1]   := BUF8 (addbselb[0-1], addbsel[0-1]);
5251 Addb_x          := MX4 (addb_x, a1_x, a2_x, a1_frac_x, zero16, addbselb[0..1]);
5252 Addb_y          := MX4 (addb_y, a1_y, a2_y, a1_frac_y, zero16, addbselb[0..1]);*/
5253 ////////////////////////////////////// C++ CODE //////////////////////////////////////
5254         int16 xterm[4], yterm[4];
5255         xterm[0] = a1_x, xterm[1] = a2_x, xterm[2] = a1_frac_x, xterm[3] = 0;
5256         yterm[0] = a1_y, yterm[1] = a2_y, yterm[2] = a1_frac_y, yterm[3] = 0;
5257         addb_x = xterm[addbsel & 0x03];
5258         addb_y = yterm[addbsel & 0x03];
5259 //////////////////////////////////////////////////////////////////////////////////////
5260
5261 //END;
5262 }
5263
5264 /**  DATAMUX - Address local data bus selection  ******************
5265
5266 Select between the adder output and the input data bus
5267 */
5268
5269 /*DEF DATAMUX (
5270 INT16/  data_x
5271 INT16/  data_y
5272         :OUT;
5273 INT32/  gpu_din
5274 INT16/  addq_x
5275 INT16/  addq_y
5276         addqsel
5277         :IN);
5278
5279 INT16/  gpu_lo, gpu_hi
5280 :LOCAL;
5281 BEGIN*/
5282 void DATAMUX(int16 &data_x, int16 &data_y, uint32 gpu_din, int16 addq_x, int16 addq_y, bool addqsel)
5283 {
5284 /*Gpu_lo                := JOIN (gpu_lo, gpu_din{0..15});
5285 Gpu_hi          := JOIN (gpu_hi, gpu_din{16..31});
5286
5287 Addqselb        := BUF8 (addqselb, addqsel);
5288 Data_x          := MX2 (data_x, gpu_lo, addq_x, addqselb);
5289 Data_y          := MX2 (data_y, gpu_hi, addq_y, addqselb);*/
5290 ////////////////////////////////////// C++ CODE //////////////////////////////////////
5291         data_x = (addqsel ? addq_x : (int16)(gpu_din & 0xFFFF));
5292         data_y = (addqsel ? addq_y : (int16)(gpu_din >> 16));
5293 //////////////////////////////////////////////////////////////////////////////////////
5294
5295 //END;
5296 }
5297
5298 /******************************************************************
5299 addradd
5300 29/11/90
5301
5302 Blitter Address Adder
5303 ---------------------
5304 The blitter address adder is a pair of sixteen bit adders, one 
5305 each for X and Y.  The multiplexing of the input terms is 
5306 performed elsewhere, but this adder can also perform modulo 
5307 arithmetic to align X-addresses onto phrase boundaries. 
5308
5309 modx[0..2] take values
5310 000     no mask
5311 001     mask bit 0
5312 010     mask bits 1-0
5313 ..
5314 110     mask bits 5-0
5315
5316 ******************************************************************/
5317
5318 /*IMPORT duplo, tosh;
5319
5320 DEF ADDRADD (
5321 INT16/  addq_x
5322 INT16/  addq_y
5323                 :OUT;
5324                 a1fracldi               // propagate address adder carry
5325 INT16/  adda_x
5326 INT16/  adda_y
5327 INT16/  addb_x
5328 INT16/  addb_y
5329                 clk[0]                  // co-processor clock
5330                 modx[0..2]
5331                 suba_x
5332                 suba_y
5333                 :IN); 
5334
5335 BEGIN
5336
5337 Zero            := TIE0 (zero);*/
5338 void ADDRADD(int16 &addq_x, int16 &addq_y, bool a1fracldi,
5339         uint16 adda_x, uint16 adda_y, uint16 addb_x, uint16 addb_y, uint8 modx, bool suba_x, bool suba_y)
5340 {
5341
5342 /* Perform the addition */
5343
5344 /*Adder_x               := ADD16 (addqt_x[0..15], co_x, adda_x{0..15}, addb_x{0..15}, ci_x);
5345 Adder_y         := ADD16 (addq_y[0..15], co_y, adda_y{0..15}, addb_y{0..15}, ci_y);*/
5346
5347 /* latch carry and propagate if required */
5348
5349 /*Cxt0          := AN2 (cxt[0], co_x, a1fracldi);
5350 Cxt1            := FD1Q (cxt[1], cxt[0], clk[0]);
5351 Ci_x            := EO (ci_x, cxt[1], suba_x);
5352
5353 yt0                     := AN2 (cyt[0], co_y, a1fracldi);
5354 Cyt1            := FD1Q (cyt[1], cyt[0], clk[0]);
5355 Ci_y            := EO (ci_y, cyt[1], suba_y);*/
5356
5357 ////////////////////////////////////// C++ CODE //////////////////////////////////////
5358 //I'm sure the following will generate a bunch of warnings, but will have to do for now.
5359         static uint16 co_x = 0, co_y = 0;       // Carry out has to propogate between function calls...
5360         uint16 ci_x = co_x ^ (suba_x ? 1 : 0);
5361         uint16 ci_y = co_y ^ (suba_y ? 1 : 0);
5362         uint32 addqt_x = adda_x + addb_x + ci_x;
5363         uint32 addqt_y = adda_y + addb_y + ci_y;
5364         co_x = ((addqt_x & 0x10000) && a1fracldi ? 1 : 0);
5365         co_y = ((addqt_y & 0x10000) && a1fracldi ? 1 : 0);
5366 //////////////////////////////////////////////////////////////////////////////////////
5367
5368 /* Mask low bits of X to 0 if required */
5369
5370 /*Masksel               := D38H (unused[0], masksel[0..4], maskbit[5], unused[1], modx[0..2]);
5371
5372 Maskbit[0-4]    := OR2 (maskbit[0-4], masksel[0-4], maskbit[1-5]);
5373
5374 Mask[0-5]       := MX2 (addq_x[0-5], addqt_x[0-5], zero, maskbit[0-5]);
5375
5376 Addq_x          := JOIN (addq_x, addq_x[0..5], addqt_x[6..15]);
5377 Addq_y          := JOIN (addq_y, addq_y[0..15]);*/
5378
5379 ////////////////////////////////////// C++ CODE //////////////////////////////////////
5380         int16 mask[8] = { 0xFFFF, 0xFFFE, 0xFFFC, 0xFFF8, 0xFFF0, 0xFFE0, 0xFFC0, 0x0000 };
5381         addq_x = addqt_x & mask[modx];
5382         addq_y = addqt_y & 0xFFFF;
5383 //////////////////////////////////////////////////////////////////////////////////////
5384
5385 //Unused[0-1]   := DUMMY (unused[0-1]);
5386
5387 //END;
5388 }
5389
5390 /*
5391 DEF DATA (
5392                 wdata[0..63]    // co-processor write data bus
5393                 :BUS;
5394                 dcomp[0..7]             // data byte equal flags
5395                 srcd[0..7]              // bits to use for bit to byte expansion
5396                 zcomp[0..3]             // output from Z comparators
5397                 :OUT; 
5398                 a1_x[0..1]              // low two bits of A1 X pointer
5399                 big_pix                 // pixel organisation is big-endian
5400                 blitter_active  // blitter is active
5401                 clk                             // co-processor clock
5402                 cmpdst                  // compare dest rather than source
5403                 colorld                 // load the pattern color fields
5404                 daddasel[0..2]  // data adder input A selection
5405                 daddbsel[0..3]  // data adder input B selection
5406                 daddmode[0..2]  // data adder mode
5407                 daddq_sel               // select adder output vs. GPU data
5408                 data[0..63]             // co-processor read data bus
5409                 data_ena                // enable write data
5410                 data_sel[0..1]  // select data to write
5411                 dbinh\[0..7]    // byte oriented changed data inhibits
5412                 dend[0..5]              // end of changed write data zone
5413                 dpipe[0..1]             // load computed data pipe-line latch
5414                 dstart[0..5]    // start of changed write data zone
5415                 dstdld[0..1]    // dest data load (two halves)
5416                 dstzld[0..1]    // dest zed load (two halves)
5417                 ext_int                 // enable extended precision intensity calculations
5418 INT32/  gpu_din                 // GPU data bus
5419                 iincld                  // I increment load
5420                 iincldx                 // alternate I increment load
5421                 init_if                 // initialise I fraction phase
5422                 init_ii                 // initialise I integer phase
5423                 init_zf                 // initialise Z fraction phase
5424                 intld[0..3]             // computed intensities load
5425                 istepadd                // intensity step integer add
5426                 istepfadd               // intensity step fraction add
5427                 istepld                 // I step load
5428                 istepdld                // I step delta load
5429                 lfu_func[0..3]  // LFU function code
5430                 patdadd                 // pattern data gouraud add
5431                 patdld[0..1]    // pattern data load (two halves)
5432                 pdsel[0..1]             // select pattern data type
5433                 phrase_mode             // phrase write mode
5434                 reload                  // transfer contents of double buffers
5435                 reset\                  // system reset
5436                 srcd1ld[0..1]   // source register 1 load (two halves)
5437                 srcdread                // source data read load enable
5438                 srczread                // source zed read load enable
5439                 srcshift[0..5]  // source alignment shift
5440                 srcz1ld[0..1]   // source zed 1 load (two halves)
5441                 srcz2add                // zed fraction gouraud add
5442                 srcz2ld[0..1]   // source zed 2 load (two halves)
5443                 textrgb                 // texture mapping in RGB mode
5444                 txtd[0..63]             // data from the texture unit
5445                 zedld[0..3]             // computed zeds load
5446                 zincld                  // Z increment load
5447                 zmode[0..2]             // Z comparator mode
5448                 zpipe[0..1]             // load computed zed pipe-line latch
5449                 zstepadd                // zed step integer add
5450                 zstepfadd               // zed step fraction add
5451                 zstepld                 // Z step load
5452                 zstepdld                // Z step delta load
5453                 :IN);
5454 */
5455
5456 void DATA(uint64 &wdata, uint8 &dcomp, uint8 &zcomp, bool &nowrite,
5457         bool big_pix, bool cmpdst, uint8 daddasel, uint8 daddbsel, uint8 daddmode, bool daddq_sel, uint8 data_sel,
5458         uint8 dbinh, uint8 dend, uint8 dstart, uint64 dstd, uint32 iinc, uint8 lfu_func, uint64 &patd, bool patdadd,
5459         bool phrase_mode, uint64 srcd, bool srcdread, bool srczread, bool srcz2add, uint8 zmode,
5460         bool bcompen, bool bkgwren, bool dcompen, uint8 icount, uint8 pixsize,
5461         uint64 &srcz, uint64 dstz, uint32 zinc)
5462 {
5463 /*
5464   Stuff we absolutely *need* to have passed in/out:
5465 IN:
5466   patdadd, dstd, srcd, patd, daddasel, daddbsel, daddmode, iinc, srcz1, srcz2, big_pix, phrase_mode, cmpdst
5467 OUT:
5468   changed patd (wdata I guess...) (Nope. We pass it back directly now...)
5469 */
5470
5471 // Source data registers
5472
5473 /*Data_src      := DATA_SRC (srcdlo, srcdhi, srcz[0..1], srczo[0..1], srczp[0..1], srcz1[0..1], srcz2[0..1], big_pix,
5474                         clk, gpu_din, intld[0..3], local_data0, local_data1, srcd1ld[0..1], srcdread, srczread, srcshift[0..5],
5475                         srcz1ld[0..1], srcz2add, srcz2ld[0..1], zedld[0..3], zpipe[0..1]);
5476 Srcd[0-7]       := JOIN (srcd[0-7], srcdlo{0-7});
5477 Srcd[8-31]      := JOIN (srcd[8-31], srcdlo{8-31});
5478 Srcd[32-63]     := JOIN (srcd[32-63], srcdhi{0-31});*/
5479
5480 // Destination data registers 
5481
5482 /*Data_dst      := DATA_DST (dstd[0..63], dstz[0..1], clk, dstdld[0..1], dstzld[0..1], load_data[0..1]);
5483 Dstdlo          := JOIN (dstdlo, dstd[0..31]);
5484 Dstdhi          := JOIN (dstdhi, dstd[32..63]);*/
5485
5486 // Pattern and Color data registers 
5487
5488 // Looks like this is simply another register file for the pattern data registers. No adding or anything funky
5489 // going on. Note that patd & patdv will output the same info.
5490 // Patdldl/h (patdld[0..1]) can select the local_data bus to overwrite the current pattern data...
5491 // Actually, it can be either patdld OR patdadd...!
5492 /*Data_pat      := DATA_PAT (colord[0..15], int0dp[8..10], int1dp[8..10], int2dp[8..10], int3dp[8..10], mixsel[0..2],
5493                         patd[0..63], patdv[0..1], clk, colorld, dpipe[0], ext_int, gpu_din, intld[0..3], local_data0, local_data1,
5494                         patdadd, patdld[0..1], reload, reset\);
5495 Patdlo          := JOIN (patdlo, patd[0..31]);
5496 Patdhi          := JOIN (patdhi, patd[32..63]);*/
5497
5498 // Multiplying data Mixer (NOT IN JAGUAR I)
5499
5500 /*Datamix               := DATAMIX (patdo[0..1], clk, colord[0..15], dpipe[1], dstd[0..63], int0dp[8..10], int1dp[8..10], 
5501                         int2dp[8..10], int3dp[8..10], mixsel[0..2], patd[0..63], pdsel[0..1], srcd[0..63], textrgb, txtd[0..63]);*/
5502
5503 // Logic function unit
5504
5505 /*Lfu           := LFU (lfu[0..1], srcdlo, srcdhi, dstdlo, dstdhi, lfu_func[0..3]);*/
5506 ////////////////////////////////////// C++ CODE //////////////////////////////////////
5507         uint64 funcmask[2] = { 0, 0xFFFFFFFFFFFFFFFFLL };
5508         uint64 func0 = funcmask[lfu_func & 0x01];
5509         uint64 func1 = funcmask[(lfu_func >> 1) & 0x01];
5510         uint64 func2 = funcmask[(lfu_func >> 2) & 0x01];
5511         uint64 func3 = funcmask[(lfu_func >> 3) & 0x01];
5512         uint64 lfu = (~srcd & ~dstd & func0) | (~srcd & dstd & func1) | (srcd & ~dstd & func2) | (srcd & dstd & func3);
5513 //////////////////////////////////////////////////////////////////////////////////////
5514
5515 // Increment and Step Registers
5516    
5517 // Does it do anything without the step add lines? Check it!
5518 // No. This is pretty much just a register file without the Jaguar II lines...
5519 /*Inc_step      := INC_STEP (iinc, istep[0..31], zinc, zstep[0..31], clk, ext_int, gpu_din, iincld, iincldx, istepadd,
5520                         istepfadd, istepld, istepdld, reload, reset\, zincld, zstepadd, zstepfadd, zstepld, zstepdld);
5521 Istep           := JOIN (istep, istep[0..31]);
5522 Zstep           := JOIN (zstep, zstep[0..31]);*/
5523
5524 // Pixel data comparator
5525
5526 /*Datacomp      := DATACOMP (dcomp[0..7], cmpdst, dstdlo, dstdhi, patdlo, patdhi, srcdlo, srcdhi);*/
5527 ////////////////////////////////////// C++ CODE //////////////////////////////////////
5528         dcomp = 0;
5529         uint64 cmpd = patd ^ (cmpdst ? dstd : srcd);
5530
5531         if ((cmpd & 0x00000000000000FFLL) == 0)
5532                 dcomp |= 0x01;
5533         if ((cmpd & 0x000000000000FF00LL) == 0)
5534                 dcomp |= 0x02;
5535         if ((cmpd & 0x0000000000FF0000LL) == 0)
5536                 dcomp |= 0x04;
5537         if ((cmpd & 0x00000000FF000000LL) == 0)
5538                 dcomp |= 0x08;
5539         if ((cmpd & 0x000000FF00000000LL) == 0)
5540                 dcomp |= 0x10;
5541         if ((cmpd & 0x0000FF0000000000LL) == 0)
5542                 dcomp |= 0x20;
5543         if ((cmpd & 0x00FF000000000000LL) == 0)
5544                 dcomp |= 0x40;
5545         if ((cmpd & 0xFF00000000000000LL) == 0)
5546                 dcomp |= 0x80;
5547 //////////////////////////////////////////////////////////////////////////////////////
5548
5549 // Zed comparator for Z-buffer operations
5550
5551 /*Zedcomp               := ZEDCOMP (zcomp[0..3], srczp[0..1], dstz[0..1], zmode[0..2]);*/
5552 ////////////////////////////////////// C++ CODE //////////////////////////////////////
5553 //srczp is srcz pipelined, also it goes through a source shift as well...
5554 /*The shift is basically like so (each piece is 16 bits long):
5555
5556         0         1         2         3         4          5         6
5557         srcz1lolo srcz1lohi srcz1hilo srcz1hihi srcrz2lolo srcz2lohi srcz2hilo
5558
5559 with srcshift bits 4 & 5 selecting the start position
5560 */
5561 //So... basically what we have here is:
5562         zcomp = 0;
5563
5564         if ((((srcz & 0x000000000000FFFFLL) < (dstz & 0x000000000000FFFFLL)) && (zmode & 0x01))
5565                 || (((srcz & 0x000000000000FFFFLL) == (dstz & 0x000000000000FFFFLL)) && (zmode & 0x02))
5566                 || (((srcz & 0x000000000000FFFFLL) > (dstz & 0x000000000000FFFFLL)) && (zmode & 0x04)))
5567                 zcomp |= 0x01;
5568
5569         if ((((srcz & 0x00000000FFFF0000LL) < (dstz & 0x00000000FFFF0000LL)) && (zmode & 0x01))
5570                 || (((srcz & 0x00000000FFFF0000LL) == (dstz & 0x00000000FFFF0000LL)) && (zmode & 0x02))
5571                 || (((srcz & 0x00000000FFFF0000LL) > (dstz & 0x00000000FFFF0000LL)) && (zmode & 0x04)))
5572                 zcomp |= 0x02;
5573
5574         if ((((srcz & 0x0000FFFF00000000LL) < (dstz & 0x0000FFFF00000000LL)) && (zmode & 0x01))
5575                 || (((srcz & 0x0000FFFF00000000LL) == (dstz & 0x0000FFFF00000000LL)) && (zmode & 0x02))
5576                 || (((srcz & 0x0000FFFF00000000LL) > (dstz & 0x0000FFFF00000000LL)) && (zmode & 0x04)))
5577                 zcomp |= 0x04;
5578
5579         if ((((srcz & 0xFFFF000000000000LL) < (dstz & 0xFFFF000000000000LL)) && (zmode & 0x01))
5580                 || (((srcz & 0xFFFF000000000000LL) == (dstz & 0xFFFF000000000000LL)) && (zmode & 0x02))
5581                 || (((srcz & 0xFFFF000000000000LL) > (dstz & 0xFFFF000000000000LL)) && (zmode & 0x04)))
5582                 zcomp |= 0x08;
5583
5584 //TEMP, TO TEST IF ZCOMP IS THE CULPRIT...
5585 //Nope, this is NOT the problem...
5586 //zcomp=0;
5587 // We'll do the comparison/bit/byte inhibits here, since that's they way it happens
5588 // in the real thing (dcomp goes out to COMP_CTRL and back into DATA through dbinh)...
5589 #if 1
5590         uint8 dbinht;
5591 //      bool nowrite;
5592         COMP_CTRL(dbinht, nowrite,
5593                 bcompen, true/*big_pix*/, bkgwren, dcomp, dcompen, icount, pixsize, phrase_mode, srcd & 0xFF, zcomp);
5594         dbinh = dbinht;
5595 //      dbinh = 0x00;
5596 #endif
5597
5598 #if 1
5599 #ifdef VERBOSE_BLITTER_LOGGING
5600 if (logBlit)
5601 {
5602         printf("\n[dcomp=%02X zcomp=%02X dbinh=%02X]\n", dcomp, zcomp, dbinh);
5603         fflush(stdout);
5604 }//*/
5605 #endif
5606 #endif
5607 //////////////////////////////////////////////////////////////////////////////////////
5608
5609 // 22 Mar 94
5610 // The data initializer - allows all four initial values to be computed from one (NOT IN JAGUAR I)
5611
5612 /*Datinit               := DATINIT (initcin[0..3], initinc[0..63], initpix[0..15], a1_x[0..1], big_pix, clk, iinc, init_if, init_ii, 
5613                         init_zf, istep[0..31], zinc, zstep[0..31]);*/
5614
5615 // Adder array for Z and intensity increments
5616
5617 /*Addarray      := ADDARRAY (addq[0..3], clk, daddasel[0..2], daddbsel[0..3], daddmode[0..2], dstdlo, dstdhi, iinc,
5618                         initcin[0..3], initinc[0..63], initpix[0..15], istep, patdv[0..1], srcdlo, srcdhi, srcz1[0..1],
5619                         srcz2[0..1], reset\, zinc, zstep);*/
5620 /*void ADDARRAY(uint16 * addq, uint8 daddasel, uint8 daddbsel, uint8 daddmode,
5621         uint64 dstd, uint32 iinc, uint8 initcin[], uint64 initinc, uint16 initpix,
5622         uint32 istep, uint64 patd, uint64 srcd, uint64 srcz1, uint64 srcz2,
5623         uint32 zinc, uint32 zstep)*/
5624 ////////////////////////////////////// C++ CODE //////////////////////////////////////
5625         uint16 addq[4];
5626         uint8 initcin[4] = { 0, 0, 0, 0 };
5627         ADDARRAY(addq, daddasel, daddbsel, daddmode, dstd, iinc, initcin, 0, 0, 0, patd, srcd, 0, 0, 0, 0);
5628
5629         //This is normally done asynchronously above (thru local_data) when in patdadd mode...
5630 //And now it's passed back to the caller to be persistent between calls...!
5631 //But it's causing some serious fuck-ups in T2K now... !!! FIX !!! [DONE--???]
5632 //Weird! It doesn't anymore...!
5633         if (patdadd)
5634                 patd = ((uint64)addq[3] << 48) | ((uint64)addq[2] << 32) | ((uint64)addq[1] << 16) | (uint64)addq[0];
5635 //////////////////////////////////////////////////////////////////////////////////////
5636
5637 // Local data bus multiplexer
5638
5639 /*Local_mux     := LOCAL_MUX (local_data[0..1], load_data[0..1],
5640         addq[0..3], gpu_din, data[0..63], blitter_active, daddq_sel);
5641 Local_data0     := JOIN (local_data0, local_data[0]);
5642 Local_data1     := JOIN (local_data1, local_data[1]);*/
5643 ////////////////////////////////////// C++ CODE //////////////////////////////////////
5644 //////////////////////////////////////////////////////////////////////////////////////
5645
5646 // Data output multiplexer and tri-state drive
5647
5648 /*Data_mux      := DATA_MUX (wdata[0..63], addq[0..3], big_pix, dstdlo, dstdhi, dstz[0..1], data_sel[0..1], data_ena,
5649                         dstart[0..5], dend[0..5], dbinh\[0..7], lfu[0..1], patdo[0..1], phrase_mode, srczo[0..1]);*/
5650 ////////////////////////////////////// C++ CODE //////////////////////////////////////
5651 // NOTE: patdo comes from DATAMIX and can be considered the same as patd for Jaguar I
5652
5653 //////////////////////////////////////////////////////////////////////////////////////
5654 //}
5655
5656 /*DEF DATA_MUX (
5657                 wdata[0..63]    // co-processor rwrite data bus
5658                 :BUS;
5659 INT16/  addq[0..3]
5660                 big_pix                 // Pixel organisation is big-endian
5661 INT32/  dstdlo
5662 INT32/  dstdhi
5663 INT32/  dstzlo
5664 INT32/  dstzhi
5665                 data_sel[0..1]  // source of write data
5666                 data_ena                // enable write data onto read/write bus
5667                 dstart[0..5]    // start of changed write data
5668                 dend[0..5]              // end of changed write data
5669                 dbinh\[0..7]    // byte oriented changed data inhibits
5670 INT32/  lfu[0..1]
5671 INT32/  patd[0..1]
5672                 phrase_mode             // phrase write mode
5673 INT32/  srczlo
5674 INT32/  srczhi
5675                 :IN);*/
5676
5677 /*INT32/        addql[0..1], ddatlo, ddathi zero32
5678 :LOCAL;
5679 BEGIN
5680
5681 Phrase_mode\    := INV1 (phrase_mode\, phrase_mode);
5682 Zero            := TIE0 (zero);
5683 Zero32          := JOIN (zero32, zero, zero, zero, zero, zero, zero, zero, zero, zero, zero, zero, zero, zero, zero, zero, zero, zero, zero, zero, zero, zero, zero, zero, zero, zero, zero, zero, zero, zero, zero, zero, zero);*/
5684
5685 /* Generate a changed data mask */
5686
5687 /*Edis          := OR6 (edis\, dend[0..5]);
5688 Ecoarse         := DECL38E (e_coarse\[0..7], dend[3..5], edis\);
5689 E_coarse[0]     := INV1 (e_coarse[0], e_coarse\[0]);
5690 Efine           := DECL38E (unused[0], e_fine\[1..7], dend[0..2], e_coarse[0]);*/
5691 ////////////////////////////////////// C++ CODE //////////////////////////////////////
5692         uint8 decl38e[2][8] = { { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
5693                 { 0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F } };
5694         uint8 dech38[8] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
5695         uint8 dech38el[2][8] = { { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 },
5696                 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } };
5697
5698                         int en = (dend & 0x3F ? 1 : 0);
5699         uint8 e_coarse = decl38e[en][(dend & 0x38) >> 3];               // Actually, this is e_coarse inverted...
5700         uint8 e_fine = decl38e[(e_coarse & 0x01) ^ 0x01][dend & 0x07];
5701         e_fine &= 0xFE;
5702 //////////////////////////////////////////////////////////////////////////////////////
5703
5704 /*Scoarse               := DECH38 (s_coarse[0..7], dstart[3..5]);
5705 Sfen\           := INV1 (sfen\, s_coarse[0]);
5706 Sfine           := DECH38EL (s_fine[0..7], dstart[0..2], sfen\);*/
5707 ////////////////////////////////////// C++ CODE //////////////////////////////////////
5708         uint8 s_coarse = dech38[(dstart & 0x38) >> 3];
5709         uint8 s_fine = dech38el[(s_coarse & 0x01) ^ 0x01][dstart & 0x07];
5710 //////////////////////////////////////////////////////////////////////////////////////
5711
5712 /*Maskt[0]      := BUF1 (maskt[0], s_fine[0]);
5713 Maskt[1-7]      := OAN1P (maskt[1-7], maskt[0-6], s_fine[1-7], e_fine\[1-7]);*/
5714 ////////////////////////////////////// C++ CODE //////////////////////////////////////
5715         uint16 maskt = s_fine & 0x0001;
5716         maskt |= (((maskt & 0x0001) || (s_fine & 0x02)) && (e_fine & 0x02) ? 0x0002 : 0x0000);
5717         maskt |= (((maskt & 0x0002) || (s_fine & 0x04)) && (e_fine & 0x04) ? 0x0004 : 0x0000);
5718         maskt |= (((maskt & 0x0004) || (s_fine & 0x08)) && (e_fine & 0x08) ? 0x0008 : 0x0000);
5719         maskt |= (((maskt & 0x0008) || (s_fine & 0x10)) && (e_fine & 0x10) ? 0x0010 : 0x0000);
5720         maskt |= (((maskt & 0x0010) || (s_fine & 0x20)) && (e_fine & 0x20) ? 0x0020 : 0x0000);
5721         maskt |= (((maskt & 0x0020) || (s_fine & 0x40)) && (e_fine & 0x40) ? 0x0040 : 0x0000);
5722         maskt |= (((maskt & 0x0040) || (s_fine & 0x80)) && (e_fine & 0x80) ? 0x0080 : 0x0000);
5723 //////////////////////////////////////////////////////////////////////////////////////
5724
5725 /* Produce a look-ahead on the ripple carry:
5726 masktla = s_coarse[0] . /e_coarse[0] */
5727 /*Masktla               := AN2 (masktla, s_coarse[0], e_coarse\[0]);
5728 Maskt[8]        := OAN1P (maskt[8], masktla, s_coarse[1], e_coarse\[1]);
5729 Maskt[9-14]     := OAN1P (maskt[9-14], maskt[8-13], s_coarse[2-7], e_coarse\[2-7]);*/
5730 ////////////////////////////////////// C++ CODE //////////////////////////////////////
5731         maskt |= (((s_coarse & e_coarse & 0x01) || (s_coarse & 0x02)) && (e_coarse & 0x02) ? 0x0100 : 0x0000);
5732         maskt |= (((maskt & 0x0100) || (s_coarse & 0x04)) && (e_coarse & 0x04) ? 0x0200 : 0x0000);
5733         maskt |= (((maskt & 0x0200) || (s_coarse & 0x08)) && (e_coarse & 0x08) ? 0x0400 : 0x0000);
5734         maskt |= (((maskt & 0x0400) || (s_coarse & 0x10)) && (e_coarse & 0x10) ? 0x0800 : 0x0000);
5735         maskt |= (((maskt & 0x0800) || (s_coarse & 0x20)) && (e_coarse & 0x20) ? 0x1000 : 0x0000);
5736         maskt |= (((maskt & 0x1000) || (s_coarse & 0x40)) && (e_coarse & 0x40) ? 0x2000 : 0x0000);
5737         maskt |= (((maskt & 0x2000) || (s_coarse & 0x80)) && (e_coarse & 0x80) ? 0x4000 : 0x0000);
5738 //////////////////////////////////////////////////////////////////////////////////////
5739
5740 /* The bit terms are mirrored for big-endian pixels outside phrase
5741 mode.  The byte terms are mirrored for big-endian pixels in phrase 
5742 mode.  */
5743
5744 /*Mirror_bit    := AN2M (mir_bit, phrase_mode\, big_pix);
5745 Mirror_byte     := AN2H (mir_byte, phrase_mode, big_pix);
5746
5747 Masktb[14]      := BUF1 (masktb[14], maskt[14]);
5748 Masku[0]        := MX4 (masku[0],  maskt[0],  maskt[7],  maskt[14],  zero, mir_bit, mir_byte);
5749 Masku[1]        := MX4 (masku[1],  maskt[1],  maskt[6],  maskt[14],  zero, mir_bit, mir_byte);
5750 Masku[2]        := MX4 (masku[2],  maskt[2],  maskt[5],  maskt[14],  zero, mir_bit, mir_byte);
5751 Masku[3]        := MX4 (masku[3],  maskt[3],  maskt[4],  masktb[14], zero, mir_bit, mir_byte);
5752 Masku[4]        := MX4 (masku[4],  maskt[4],  maskt[3],  masktb[14], zero, mir_bit, mir_byte);
5753 Masku[5]        := MX4 (masku[5],  maskt[5],  maskt[2],  masktb[14], zero, mir_bit, mir_byte);
5754 Masku[6]        := MX4 (masku[6],  maskt[6],  maskt[1],  masktb[14], zero, mir_bit, mir_byte);
5755 Masku[7]        := MX4 (masku[7],  maskt[7],  maskt[0],  masktb[14], zero, mir_bit, mir_byte);
5756 Masku[8]        := MX2 (masku[8],  maskt[8],  maskt[13], mir_byte);
5757 Masku[9]        := MX2 (masku[9],  maskt[9],  maskt[12], mir_byte);
5758 Masku[10]       := MX2 (masku[10], maskt[10], maskt[11], mir_byte);
5759 Masku[11]       := MX2 (masku[11], maskt[11], maskt[10], mir_byte);
5760 Masku[12]       := MX2 (masku[12], maskt[12], maskt[9],  mir_byte);
5761 Masku[13]       := MX2 (masku[13], maskt[13], maskt[8],  mir_byte);
5762 Masku[14]       := MX2 (masku[14], maskt[14], maskt[0],  mir_byte);*/
5763 ////////////////////////////////////// C++ CODE //////////////////////////////////////
5764         bool mir_bit = true/*big_pix*/ && !phrase_mode;
5765         bool mir_byte = true/*big_pix*/ && phrase_mode;
5766         uint16 masku = maskt;
5767
5768         if (mir_bit)
5769         {
5770                 masku &= 0xFF00;
5771                 masku |= (maskt >> 7) & 0x0001;
5772                 masku |= (maskt >> 5) & 0x0002;
5773                 masku |= (maskt >> 3) & 0x0004;
5774                 masku |= (maskt >> 1) & 0x0008;
5775                 masku |= (maskt << 1) & 0x0010;
5776                 masku |= (maskt << 3) & 0x0020;
5777                 masku |= (maskt << 5) & 0x0040;
5778                 masku |= (maskt << 7) & 0x0080;
5779         }
5780
5781         if (mir_byte)
5782         {
5783                 masku = 0;
5784                 masku |= (maskt >> 14) & 0x0001;
5785                 masku |= (maskt >> 13) & 0x0002;
5786                 masku |= (maskt >> 12) & 0x0004;
5787                 masku |= (maskt >> 11) & 0x0008;
5788                 masku |= (maskt >> 10) & 0x0010;
5789                 masku |= (maskt >> 9)  & 0x0020;
5790                 masku |= (maskt >> 8)  & 0x0040;
5791                 masku |= (maskt >> 7)  & 0x0080;
5792
5793                 masku |= (maskt >> 5) & 0x0100;
5794                 masku |= (maskt >> 3) & 0x0200;
5795                 masku |= (maskt >> 1) & 0x0400;
5796                 masku |= (maskt << 1) & 0x0800;
5797                 masku |= (maskt << 3) & 0x1000;
5798                 masku |= (maskt << 5) & 0x2000;
5799                 masku |= (maskt << 7) & 0x4000;
5800         }
5801 //////////////////////////////////////////////////////////////////////////////////////
5802
5803 /* The maskt terms define the area for changed data, but the byte
5804 inhibit terms can override these */
5805
5806 /*Mask[0-7]     := AN2 (mask[0-7], masku[0-7], dbinh\[0]);
5807 Mask[8-14]      := AN2H (mask[8-14], masku[8-14], dbinh\[1-7]);*/
5808 ////////////////////////////////////// C++ CODE //////////////////////////////////////
5809         uint16 mask = masku & (!(dbinh & 0x01) ? 0xFFFF : 0xFF00);
5810         mask &= ~(((uint16)dbinh & 0x00FE) << 7);
5811 //////////////////////////////////////////////////////////////////////////////////////
5812
5813 /*Addql[0]      := JOIN (addql[0], addq[0..1]);
5814 Addql[1]        := JOIN (addql[1], addq[2..3]);
5815
5816 Dsel0b[0-1]     := BUF8 (dsel0b[0-1], data_sel[0]);
5817 Dsel1b[0-1]     := BUF8 (dsel1b[0-1], data_sel[1]);
5818 Ddatlo          := MX4 (ddatlo, patd[0], lfu[0], addql[0], zero32, dsel0b[0], dsel1b[0]);
5819 Ddathi          := MX4 (ddathi, patd[1], lfu[1], addql[1], zero32, dsel0b[1], dsel1b[1]);*/
5820 ////////////////////////////////////// C++ CODE //////////////////////////////////////
5821         uint64 dmux[4];
5822         dmux[0] = patd;
5823         dmux[1] = lfu;
5824         dmux[2] = ((uint64)addq[3] << 48) | ((uint64)addq[2] << 32) | ((uint64)addq[1] << 16) | (uint64)addq[0];
5825         dmux[3] = 0;
5826         uint64 ddat = dmux[data_sel];
5827 //////////////////////////////////////////////////////////////////////////////////////
5828
5829 /*Zed_sel               := AN2 (zed_sel, data_sel[0..1]);
5830 Zed_selb[0-1]   := BUF8 (zed_selb[0-1], zed_sel);
5831
5832 Dat[0-7]        := MX4 (dat[0-7],   dstdlo{0-7},   ddatlo{0-7},   dstzlo{0-7},   srczlo{0-7},   mask[0-7], zed_selb[0]);
5833 Dat[8-15]       := MX4 (dat[8-15],  dstdlo{8-15},  ddatlo{8-15},  dstzlo{8-15},  srczlo{8-15},  mask[8],   zed_selb[0]);
5834 Dat[16-23]      := MX4 (dat[16-23], dstdlo{16-23}, ddatlo{16-23}, dstzlo{16-23}, srczlo{16-23}, mask[9],   zed_selb[0]);
5835 Dat[24-31]      := MX4 (dat[24-31], dstdlo{24-31}, ddatlo{24-31}, dstzlo{24-31}, srczlo{24-31}, mask[10],  zed_selb[0]);
5836 Dat[32-39]      := MX4 (dat[32-39], dstdhi{0-7},   ddathi{0-7},   dstzhi{0-7},   srczhi{0-7},   mask[11],  zed_selb[1]);
5837 Dat[40-47]      := MX4 (dat[40-47], dstdhi{8-15},  ddathi{8-15},  dstzhi{8-15},  srczhi{8-15},  mask[12],  zed_selb[1]);
5838 Dat[48-55]      := MX4 (dat[48-55], dstdhi{16-23}, ddathi{16-23}, dstzhi{16-23}, srczhi{16-23}, mask[13],  zed_selb[1]);
5839 Dat[56-63]      := MX4 (dat[56-63], dstdhi{24-31}, ddathi{24-31}, dstzhi{24-31}, srczhi{24-31}, mask[14],  zed_selb[1]);*/
5840 ////////////////////////////////////// C++ CODE //////////////////////////////////////
5841         wdata = ((ddat & mask) | (dstd & ~mask)) & 0x00000000000000FFLL;
5842         wdata |= (mask & 0x0100 ? ddat : dstd) & 0x000000000000FF00LL;
5843         wdata |= (mask & 0x0200 ? ddat : dstd) & 0x0000000000FF0000LL;
5844         wdata |= (mask & 0x0400 ? ddat : dstd) & 0x00000000FF000000LL;
5845         wdata |= (mask & 0x0800 ? ddat : dstd) & 0x000000FF00000000LL;
5846         wdata |= (mask & 0x1000 ? ddat : dstd) & 0x0000FF0000000000LL;
5847         wdata |= (mask & 0x2000 ? ddat : dstd) & 0x00FF000000000000LL;
5848         wdata |= (mask & 0x4000 ? ddat : dstd) & 0xFF00000000000000LL;
5849 /*if (logBlit)
5850 {
5851         printf("\n[ddat=%08X%08X dstd=%08X%08X wdata=%08X%08X mask=%04X]\n",
5852                 (uint32)(ddat >> 32), (uint32)(ddat & 0xFFFFFFFF),
5853                 (uint32)(dstd >> 32), (uint32)(dstd & 0xFFFFFFFF),
5854                 (uint32)(wdata >> 32), (uint32)(wdata & 0xFFFFFFFF), mask);
5855         fflush(stdout);
5856 }//*/
5857 //This is a crappy way of handling this, but it should work for now...
5858         uint64 zwdata;
5859         zwdata = ((srcz & mask) | (dstz & ~mask)) & 0x00000000000000FFLL;
5860         zwdata |= (mask & 0x0100 ? srcz : dstz) & 0x000000000000FF00LL;
5861         zwdata |= (mask & 0x0200 ? srcz : dstz) & 0x0000000000FF0000LL;
5862         zwdata |= (mask & 0x0400 ? srcz : dstz) & 0x00000000FF000000LL;
5863         zwdata |= (mask & 0x0800 ? srcz : dstz) & 0x000000FF00000000LL;
5864         zwdata |= (mask & 0x1000 ? srcz : dstz) & 0x0000FF0000000000LL;
5865         zwdata |= (mask & 0x2000 ? srcz : dstz) & 0x00FF000000000000LL;
5866         zwdata |= (mask & 0x4000 ? srcz : dstz) & 0xFF00000000000000LL;
5867 if (logBlit)
5868 {
5869         printf("\n[srcz=%08X%08X dstz=%08X%08X zwdata=%08X%08X mask=%04X]\n",
5870                 (uint32)(srcz >> 32), (uint32)(srcz & 0xFFFFFFFF),
5871                 (uint32)(dstz >> 32), (uint32)(dstz & 0xFFFFFFFF),
5872                 (uint32)(zwdata >> 32), (uint32)(zwdata & 0xFFFFFFFF), mask);
5873         fflush(stdout);
5874 }//*/
5875         srcz = zwdata;
5876 //////////////////////////////////////////////////////////////////////////////////////
5877
5878 /*Data_enab[0-1]        := BUF8 (data_enab[0-1], data_ena);
5879 Datadrv[0-31]   := TS (wdata[0-31],  dat[0-31],  data_enab[0]);
5880 Datadrv[32-63]  := TS (wdata[32-63], dat[32-63], data_enab[1]);
5881
5882 Unused[0]       := DUMMY (unused[0]);
5883
5884 END;*/
5885 }
5886
5887 /**  COMP_CTRL - Comparator output control logic  *****************
5888
5889 This block is responsible for taking the comparator outputs and
5890 using them as appropriate to inhibit writes.  Two methods are 
5891 supported for inhibiting write data:
5892
5893 -       suppression of the inner loop controlled write operation
5894 -       a set of eight byte inhibit lines to write back dest data
5895
5896 The first technique is used in pixel oriented modes, the second in
5897 phrase mode, but the phrase mode form is only applicable to eight
5898 and sixteen bit pixel modes.
5899
5900 Writes can be suppressed by data being equal, by the Z comparator
5901 conditions being met, or by the bit to pixel expansion scheme.
5902
5903 Pipe-lining issues: the data derived comparator outputs are stable 
5904 until the next data read, well after the affected write from this
5905 operation.  However, the inner counter bits can count immediately
5906 before the ack for the last write.  Therefore, it is necessary to 
5907 delay bcompbit select terms by one inner loop pipe-line stage,
5908 when generating the select for the data control - the output is
5909 delayed one further tick to give it write data timing (2/34). 
5910
5911 There is also a problem with computed data - the new values are
5912 calculated before the write associated with the old value has been
5913 performed.  The is taken care of within the zed comparator by
5914 pipe-lining the comparator inputs where appropriate.
5915 */
5916
5917 //#define LOG_COMP_CTRL
5918 /*DEF COMP_CTRL (
5919         dbinh\[0..7]    // destination byte inhibit lines
5920         nowrite         // suppress inner loop write operation
5921         :OUT;
5922         bcompen         // bit selector inhibit enable
5923         big_pix         // pixels are big-endian
5924         bkgwren         // enable dest data write in pix inhibit
5925         clk             // co-processor clock
5926         dcomp[0..7]     // output of data byte comparators
5927         dcompen         // data comparator inhibit enable
5928         icount[0..2]    // low bits of inner count
5929         pixsize[0..2]   // destination pixel size
5930         phrase_mode     // phrase write mode
5931         srcd[0..7]      // bits to use for bit to byte expansion
5932         step_inner      // inner loop advance
5933         zcomp[0..3]     // output of word zed comparators
5934         :IN);*/
5935 void COMP_CTRL(uint8 &dbinh, bool &nowrite,
5936         bool bcompen, bool big_pix, bool bkgwren, uint8 dcomp, bool dcompen, uint8 icount,
5937         uint8 pixsize, bool phrase_mode, uint8 srcd, uint8 zcomp)
5938 {
5939 //BEGIN
5940
5941 /*Bkgwren\      := INV1 (bkgwren\, bkgwren);
5942 Phrase_mode\    := INV1 (phrase_mode\, phrase_mode);
5943 Pixsize\[0-2]   := INV2 (pixsize\[0-2], pixsize[0-2]);*/
5944
5945 /* The bit comparator bits are derived from the source data, which
5946 will have been suitably aligned for phrase mode.  The contents of
5947 the inner counter are used to select which bit to use.
5948
5949 When not in phrase mode the inner count value is used to select
5950 one bit.  It is assumed that the count has already occurred, so,
5951 7 selects bit 0, etc.  In big-endian pixel mode, this turns round,
5952 so that a count of 7 selects bit 7.
5953
5954 In phrase mode, the eight bits are used directly, and this mode is
5955 only applicable to 8-bit pixel mode (2/34) */
5956
5957 /*Bcompselt[0-2]        := EO (bcompselt[0-2], icount[0-2], big_pix);
5958 Bcompbit        := MX8 (bcompbit, srcd[7], srcd[6], srcd[5], 
5959                         srcd[4], srcd[3], srcd[2], srcd[1], srcd[0], bcompselt[0..2]);
5960 Bcompbit\       := INV1 (bcompbit\, bcompbit);*/
5961 ////////////////////////////////////// C++ CODE //////////////////////////////////////
5962 #ifdef LOG_COMP_CTRL
5963 if (logBlit)
5964 {
5965         printf("\n     [bcompen=%s dcompen=%s phrase_mode=%s bkgwren=%s dcomp=%02X zcomp=%02X]", (bcompen ? "T" : "F"), (dcompen ? "T" : "F"), (phrase_mode ? "T" : "F"), (bkgwren ? "T" : "F"), dcomp, zcomp);
5966         printf("\n     ");
5967         fflush(stdout);
5968 }
5969 #endif
5970         uint8 bcompselt = (big_pix ? ~icount : icount) & 0x07;
5971         uint8 bitmask[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
5972         bool bcompbit = srcd & bitmask[bcompselt];
5973 //////////////////////////////////////////////////////////////////////////////////////
5974
5975 /* pipe-line the count */
5976 /*Bcompsel[0-2] := FDSYNC (bcompsel[0-2], bcompselt[0-2], step_inner, clk);
5977 Bcompbt         := MX8 (bcompbitpt, srcd[7], srcd[6], srcd[5], 
5978                         srcd[4], srcd[3], srcd[2], srcd[1], srcd[0], bcompsel[0..2]);
5979 Bcompbitp       := FD1Q (bcompbitp, bcompbitpt, clk);
5980 Bcompbitp\      := INV1 (bcompbitp\, bcompbitp);*/
5981
5982 /* For pixel mode, generate the write inhibit signal for all modes
5983 on bit inhibit, for 8 and 16 bit modes on comparator inhibit, and
5984 for 16 bit mode on Z inhibit 
5985
5986 Nowrite = bcompen . /bcompbit . /phrase_mode
5987         + dcompen . dcomp[0] . /phrase_mode . pixsize = 011
5988         + dcompen . dcomp[0..1] . /phrase_mode . pixsize = 100
5989         + zcomp[0] . /phrase_mode . pixsize = 100
5990 */
5991
5992 /*Nowt0         := NAN3 (nowt[0], bcompen, bcompbit\, phrase_mode\);
5993 Nowt1           := ND6  (nowt[1], dcompen, dcomp[0], phrase_mode\, pixsize\[2], pixsize[0..1]);
5994 Nowt2           := ND7  (nowt[2], dcompen, dcomp[0..1], phrase_mode\, pixsize[2], pixsize\[0..1]);
5995 Nowt3           := NAN5 (nowt[3], zcomp[0], phrase_mode\, pixsize[2], pixsize\[0..1]);
5996 Nowt4           := NAN4 (nowt[4], nowt[0..3]);
5997 Nowrite         := AN2  (nowrite, nowt[4], bkgwren\);*/
5998 ////////////////////////////////////// C++ CODE //////////////////////////////////////
5999         nowrite = ((bcompen && !bcompbit && !phrase_mode)
6000                 || (dcompen && (dcomp & 0x01) && !phrase_mode && (pixsize == 3))
6001                 || (dcompen && ((dcomp & 0x03) == 0x03) && !phrase_mode && (pixsize == 4))
6002                 || ((zcomp & 0x01) && !phrase_mode && (pixsize == 4)))
6003                 && !bkgwren;
6004 //////////////////////////////////////////////////////////////////////////////////////
6005
6006 /*Winht         := NAN3 (winht, bcompen, bcompbitp\, phrase_mode\);
6007 Winhibit        := NAN4 (winhibit, winht, nowt[1..3]);*/
6008 ////////////////////////////////////// C++ CODE //////////////////////////////////////
6009 //This is the same as above, but with bcompbit delayed one tick and called 'winhibit'
6010 //Small difference: Besides the pipeline effect, it's also not using !bkgwren...
6011 //      bool winhibit = (bcompen && !
6012         bool winhibit = (bcompen && !bcompbit && !phrase_mode)
6013                 || (dcompen && (dcomp & 0x01) && !phrase_mode && (pixsize == 3))
6014                 || (dcompen && ((dcomp & 0x03) == 0x03) && !phrase_mode && (pixsize == 4))
6015                 || ((zcomp & 0x01) && !phrase_mode && (pixsize == 4));
6016 #ifdef LOG_COMP_CTRL
6017 if (logBlit)
6018 {
6019         printf("[nw=%s wi=%s]", (nowrite ? "T" : "F"), (winhibit ? "T" : "F"));
6020         fflush(stdout);
6021 }
6022 #endif
6023 //////////////////////////////////////////////////////////////////////////////////////
6024
6025 /* For phrase mode, generate the byte inhibit signals for eight bit
6026 mode 011, or sixteen bit mode 100 
6027 dbinh\[0] =  pixsize[2] . zcomp[0]
6028          +  pixsize[2] . dcomp[0] . dcomp[1] . dcompen
6029          + /pixsize[2] . dcomp[0] . dcompen
6030          + /srcd[0] . bcompen
6031
6032 Inhibits 0-3 are also used when not in phrase mode to write back
6033 destination data.
6034 */
6035
6036 /*Srcd\[0-7]    := INV1 (srcd\[0-7], srcd[0-7]);
6037
6038 Di0t0           := NAN2H (di0t[0], pixsize[2], zcomp[0]);
6039 Di0t1           := NAN4H (di0t[1], pixsize[2], dcomp[0..1], dcompen);
6040 Di0t2           := NAN2 (di0t[2], srcd\[0], bcompen);
6041 Di0t3           := NAN3 (di0t[3], pixsize\[2], dcomp[0], dcompen);
6042 Di0t4           := NAN4 (di0t[4], di0t[0..3]);
6043 Dbinh[0]        := ANR1P (dbinh\[0], di0t[4], phrase_mode, winhibit);*/
6044 ////////////////////////////////////// C++ CODE //////////////////////////////////////
6045         dbinh = 0;
6046         bool di0t0_1 = ((pixsize & 0x04) && (zcomp & 0x01))
6047                 || ((pixsize & 0x04) && (dcomp & 0x01) && (dcomp & 0x02) && dcompen);
6048         bool di0t4 = di0t0_1
6049                 || (!(srcd & 0x01) && bcompen)
6050                 || (!(pixsize & 0x04) && (dcomp & 0x01) && dcompen);
6051         dbinh |= (!((di0t4 && phrase_mode) || winhibit) ? 0x01 : 0x00);
6052 #ifdef LOG_COMP_CTRL
6053 if (logBlit)
6054 {
6055         printf("[di0t0_1=%s di0t4=%s]", (di0t0_1 ? "T" : "F"), (di0t4 ? "T" : "F"));
6056         fflush(stdout);
6057 }
6058 #endif
6059 //////////////////////////////////////////////////////////////////////////////////////
6060
6061 /*Di1t0         := NAN3 (di1t[0], pixsize\[2], dcomp[1], dcompen);
6062 Di1t1           := NAN2 (di1t[1], srcd\[1], bcompen);
6063 Di1t2           := NAN4 (di1t[2], di0t[0..1], di1t[0..1]);
6064 Dbinh[1]        := ANR1 (dbinh\[1], di1t[2], phrase_mode, winhibit);*/
6065 ////////////////////////////////////// C++ CODE //////////////////////////////////////
6066         bool di1t2 = di0t0_1
6067                 || (!(srcd & 0x02) && bcompen)
6068                 || (!(pixsize & 0x04) && (dcomp & 0x02) && dcompen);
6069         dbinh |= (!((di1t2 && phrase_mode) || winhibit) ? 0x02 : 0x00);
6070 #ifdef LOG_COMP_CTRL
6071 if (logBlit)
6072 {
6073         printf("[di1t2=%s]", (di1t2 ? "T" : "F"));
6074         fflush(stdout);
6075 }
6076 #endif
6077 //////////////////////////////////////////////////////////////////////////////////////
6078
6079 /*Di2t0         := NAN2H (di2t[0], pixsize[2], zcomp[1]);
6080 Di2t1           := NAN4H (di2t[1], pixsize[2], dcomp[2..3], dcompen);
6081 Di2t2           := NAN2 (di2t[2], srcd\[2], bcompen);
6082 Di2t3           := NAN3 (di2t[3], pixsize\[2], dcomp[2], dcompen);
6083 Di2t4           := NAN4 (di2t[4], di2t[0..3]);
6084 Dbinh[2]        := ANR1 (dbinh\[2], di2t[4], phrase_mode, winhibit);*/
6085 ////////////////////////////////////// C++ CODE //////////////////////////////////////
6086 //[bcompen=F dcompen=T phrase_mode=T bkgwren=F][nw=F wi=F]
6087 //[di0t0_1=F di0t4=F][di1t2=F][di2t0_1=T di2t4=T][di3t2=T][di4t0_1=F di2t4=F][di5t2=F][di6t0_1=F di6t4=F][di7t2=F]
6088 //[dcomp=$00 dbinh=$0C][7804780400007804] (icount=0005, inc=4)
6089         bool di2t0_1 = ((pixsize & 0x04) && (zcomp & 0x02))
6090                 || ((pixsize & 0x04) && (dcomp & 0x04) && (dcomp & 0x08) && dcompen);
6091         bool di2t4 = di2t0_1
6092                 || (!(srcd & 0x04) && bcompen)
6093                 || (!(pixsize & 0x04) && (dcomp & 0x04) && dcompen);
6094         dbinh |= (!((di2t4 && phrase_mode) || winhibit) ? 0x04 : 0x00);
6095 #ifdef LOG_COMP_CTRL
6096 if (logBlit)
6097 {
6098         printf("[di2t0_1=%s di2t4=%s]", (di2t0_1 ? "T" : "F"), (di2t4 ? "T" : "F"));
6099         fflush(stdout);
6100 }
6101 #endif
6102 //////////////////////////////////////////////////////////////////////////////////////
6103
6104 /*Di3t0         := NAN3 (di3t[0], pixsize\[2], dcomp[3], dcompen);
6105 Di3t1           := NAN2 (di3t[1], srcd\[3], bcompen);
6106 Di3t2           := NAN4 (di3t[2], di2t[0..1], di3t[0..1]);
6107 Dbinh[3]        := ANR1 (dbinh\[3], di3t[2], phrase_mode, winhibit);*/
6108 ////////////////////////////////////// C++ CODE //////////////////////////////////////
6109         bool di3t2 = di2t0_1
6110                 || (!(srcd & 0x08) && bcompen)
6111                 || (!(pixsize & 0x04) && (dcomp & 0x08) && dcompen);
6112         dbinh |= (!((di3t2 && phrase_mode) || winhibit) ? 0x08 : 0x00);
6113 #ifdef LOG_COMP_CTRL
6114 if (logBlit)
6115 {
6116         printf("[di3t2=%s]", (di3t2 ? "T" : "F"));
6117         fflush(stdout);
6118 }
6119 #endif
6120 //////////////////////////////////////////////////////////////////////////////////////
6121
6122 /*Di4t0         := NAN2H (di4t[0], pixsize[2], zcomp[2]);
6123 Di4t1           := NAN4H (di4t[1], pixsize[2], dcomp[4..5], dcompen);
6124 Di4t2           := NAN2 (di4t[2], srcd\[4], bcompen);
6125 Di4t3           := NAN3 (di4t[3], pixsize\[2], dcomp[4], dcompen);
6126 Di4t4           := NAN4 (di4t[4], di4t[0..3]);
6127 Dbinh[4]        := NAN2 (dbinh\[4], di4t[4], phrase_mode);*/
6128 ////////////////////////////////////// C++ CODE //////////////////////////////////////
6129         bool di4t0_1 = ((pixsize & 0x04) && (zcomp & 0x04))
6130                 || ((pixsize & 0x04) && (dcomp & 0x10) && (dcomp & 0x20) && dcompen);
6131         bool di4t4 = di4t0_1
6132                 || (!(srcd & 0x10) && bcompen)
6133                 || (!(pixsize & 0x04) && (dcomp & 0x10) && dcompen);
6134         dbinh |= (!(di4t4 && phrase_mode) ? 0x10 : 0x00);
6135 #ifdef LOG_COMP_CTRL
6136 if (logBlit)
6137 {
6138         printf("[di4t0_1=%s di2t4=%s]", (di4t0_1 ? "T" : "F"), (di4t4 ? "T" : "F"));
6139         fflush(stdout);
6140 }
6141 #endif
6142 //////////////////////////////////////////////////////////////////////////////////////
6143
6144 /*Di5t0         := NAN3 (di5t[0], pixsize\[2], dcomp[5], dcompen);
6145 Di5t1           := NAN2 (di5t[1], srcd\[5], bcompen);
6146 Di5t2           := NAN4 (di5t[2], di4t[0..1], di5t[0..1]);
6147 Dbinh[5]        := NAN2 (dbinh\[5], di5t[2], phrase_mode);*/
6148 ////////////////////////////////////// C++ CODE //////////////////////////////////////
6149         bool di5t2 = di4t0_1
6150                 || (!(srcd & 0x20) && bcompen)
6151                 || (!(pixsize & 0x04) && (dcomp & 0x20) && dcompen);
6152         dbinh |= (!(di5t2 && phrase_mode) ? 0x20 : 0x00);
6153 #ifdef LOG_COMP_CTRL
6154 if (logBlit)
6155 {
6156         printf("[di5t2=%s]", (di5t2 ? "T" : "F"));
6157         fflush(stdout);
6158 }
6159 #endif
6160 //////////////////////////////////////////////////////////////////////////////////////
6161
6162 /*Di6t0         := NAN2H (di6t[0], pixsize[2], zcomp[3]);
6163 Di6t1           := NAN4H (di6t[1], pixsize[2], dcomp[6..7], dcompen);
6164 Di6t2           := NAN2 (di6t[2], srcd\[6], bcompen);
6165 Di6t3           := NAN3 (di6t[3], pixsize\[2], dcomp[6], dcompen);
6166 Di6t4           := NAN4 (di6t[4], di6t[0..3]);
6167 Dbinh[6]        := NAN2 (dbinh\[6], di6t[4], phrase_mode);*/
6168 ////////////////////////////////////// C++ CODE //////////////////////////////////////
6169         bool di6t0_1 = ((pixsize & 0x04) && (zcomp & 0x08))
6170                 || ((pixsize & 0x04) && (dcomp & 0x40) && (dcomp & 0x80) && dcompen);
6171         bool di6t4 = di6t0_1
6172                 || (!(srcd & 0x40) && bcompen)
6173                 || (!(pixsize & 0x04) && (dcomp & 0x40) && dcompen);
6174         dbinh |= (!(di6t4 && phrase_mode) ? 0x40 : 0x00);
6175 #ifdef LOG_COMP_CTRL
6176 if (logBlit)
6177 {
6178         printf("[di6t0_1=%s di6t4=%s]", (di6t0_1 ? "T" : "F"), (di6t4 ? "T" : "F"));
6179         fflush(stdout);
6180 }
6181 #endif
6182 //////////////////////////////////////////////////////////////////////////////////////
6183
6184 /*Di7t0         := NAN3 (di7t[0], pixsize\[2], dcomp[7], dcompen);
6185 Di7t1           := NAN2 (di7t[1], srcd\[7], bcompen);
6186 Di7t2           := NAN4 (di7t[2], di6t[0..1], di7t[0..1]);
6187 Dbinh[7]        := NAN2 (dbinh\[7], di7t[2], phrase_mode);*/
6188 ////////////////////////////////////// C++ CODE //////////////////////////////////////
6189         bool di7t2 = di6t0_1
6190                 || (!(srcd & 0x80) && bcompen)
6191                 || (!(pixsize & 0x04) && (dcomp & 0x80) && dcompen);
6192         dbinh |= (!(di7t2 && phrase_mode) ? 0x80 : 0x00);
6193 #ifdef LOG_COMP_CTRL
6194 if (logBlit)
6195 {
6196         printf("[di7t2=%s]", (di7t2 ? "T" : "F"));
6197         fflush(stdout);
6198 }
6199 #endif
6200 //////////////////////////////////////////////////////////////////////////////////////
6201
6202 //END;
6203 //kludge
6204 dbinh = ~dbinh;
6205 #ifdef LOG_COMP_CTRL
6206 if (logBlit)
6207 {
6208         printf("[dcomp=$%02X dbinh=$%02X]\n    ", dcomp, dbinh);
6209         fflush(stdout);
6210 }
6211 #endif
6212 }
6213
6214
6215 ////////////////////////////////////// C++ CODE //////////////////////////////////////
6216 //////////////////////////////////////////////////////////////////////////////////////
6217
6218 // !!! TESTING !!! TESTING !!! TESTING !!! TESTING !!! TESTING !!! TESTING !!! TESTING !!!
6219 // !!! TESTING !!! TESTING !!! TESTING !!! TESTING !!! TESTING !!! TESTING !!! TESTING !!!
6220 // !!! TESTING !!! TESTING !!! TESTING !!! TESTING !!! TESTING !!! TESTING !!! TESTING !!!
6221
6222 #endif
6223