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