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