]> Shamusworld >> Repos - virtualjaguar/blobdiff - src/blitter.cpp
Even more blitter fixes
[virtualjaguar] / src / blitter.cpp
index 432b53c296278b615486ed54c557578220b746c6..d3741948b5fcfcb15ff0c8678fa471b1ccf41c62 100644 (file)
@@ -1,11 +1,13 @@
 //
 // Blitter core
 //
-// by cal2
+// by Cal2
 // GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Caz (BeOS)
 // Cleanups/fixes by James L. Hammons
 //
 bool specialLog = false;
+extern int effect_start;
+extern int blit_start_log;
 
 #include "jaguar.h"
 
@@ -41,14 +43,14 @@ bool specialLog = false;
 #define INTENSITYINC   ((UINT32)0x70)
 #define ZINC                   ((UINT32)0x74)
 #define COLLISIONCTRL  ((UINT32)0x78)
-#define PHRASEINT3             ((UINT32)0x7C)
-#define PHRASEINT2             ((UINT32)0x80)
-#define PHRASEINT1             ((UINT32)0x84)
-#define PHRASEINT0             ((UINT32)0x88)
-#define PHRASEZ3               ((UINT32)0x8C)
-#define PHRASEZ2               ((UINT32)0x90)
-#define PHRASEZ1               ((UINT32)0x94)
-#define PHRASEZ0               ((UINT32)0x98)
+#define PHRASEINT0             ((UINT32)0x7C)
+#define PHRASEINT1             ((UINT32)0x80)
+#define PHRASEINT2             ((UINT32)0x84)
+#define PHRASEINT3             ((UINT32)0x88)
+#define PHRASEZ0               ((UINT32)0x8C)
+#define PHRASEZ1               ((UINT32)0x90)
+#define PHRASEZ2               ((UINT32)0x94)
+#define PHRASEZ3               ((UINT32)0x98)
 
 // Blitter command bits
 
@@ -80,7 +82,7 @@ bool specialLog = false;
 #define DCOMPEN                        (cmd & 0x08000000)
 
 #define PATDSEL                        (cmd & 0x00010000)
-#define INTADD                 (cmd & 0x00020000)
+#define ADDDSEL                        (cmd & 0x00020000)
 #define TOPBEN                 (cmd & 0x00004000)
 #define TOPNEN                 (cmd & 0x00008000)
 #define BKGWREN                        (cmd & 0x10000000)
@@ -162,22 +164,22 @@ bool specialLog = false;
 #define WRITE_ZDATA(a,f,d) WRITE_ZDATA_16(a,d); 
 
 // 1 bpp r data read
-#define READ_RDATA_1(r,a,p)  ((p) ?  ((REG(r+(((UINT32)a##_x>>19)&4)))>>(((UINT32)a##_x>>16)&0x1f))&   0x1 : (REG(r) &    0x1))
+#define READ_RDATA_1(r,a,p)  ((p) ?  ((REG(r+(((UINT32)a##_x >> 19) & 0x04))) >> (((UINT32)a##_x >> 16) & 0x1F)) & 0x0001 : (REG(r) & 0x0001))
 
 // 2 bpp r data read
-#define READ_RDATA_2(r,a,p)  ((p) ?  ((REG(r+(((UINT32)a##_x>>18)&4)))>>(((UINT32)a##_x>>15)&0x3e))&   0x3 : (REG(r) &    0x3))
+#define READ_RDATA_2(r,a,p)  ((p) ?  ((REG(r+(((UINT32)a##_x >> 18) & 0x04))) >> (((UINT32)a##_x >> 15) & 0x3E)) & 0x0003 : (REG(r) & 0x0003))
 
 // 4 bpp r data read
-#define READ_RDATA_4(r,a,p)  ((p) ?  ((REG(r+(((UINT32)a##_x>>17)&4)))>>(((UINT32)a##_x>>14)&0x28))&   0xf : (REG(r) &    0xf))
+#define READ_RDATA_4(r,a,p)  ((p) ?  ((REG(r+(((UINT32)a##_x >> 17) & 0x04))) >> (((UINT32)a##_x >> 14) & 0x28)) & 0x000F : (REG(r) & 0x000F))
 
 // 8 bpp r data read
-#define READ_RDATA_8(r,a,p)  ((p) ?  ((REG(r+(((UINT32)a##_x>>16)&4)))>>(((UINT32)a##_x>>13)&0x18))&  0xff : (REG(r) &   0xff))
+#define READ_RDATA_8(r,a,p)  ((p) ?  ((REG(r+(((UINT32)a##_x >> 16) & 0x04))) >> (((UINT32)a##_x >> 13) & 0x18)) & 0x00FF : (REG(r) & 0x00FF))
 
 // 16 bpp r data read
-#define READ_RDATA_16(r,a,p)  ((p) ? ((REG(r+(((UINT32)a##_x>>15)&4)))>>(((UINT32)a##_x>>12)&0x10))&0xffff : (REG(r) & 0xffff))
+#define READ_RDATA_16(r,a,p)  ((p) ? ((REG(r+(((UINT32)a##_x >> 15) & 0x04))) >> (((UINT32)a##_x >> 12) & 0x10)) & 0xFFFF : (REG(r) & 0xFFFF))
 
 // 32 bpp r data read
-#define READ_RDATA_32(r,a,p)  ((p) ? REG(r+(((UINT32)a##_x>>14)&4)) : REG(r))
+#define READ_RDATA_32(r,a,p)  ((p) ? REG(r+(((UINT32)a##_x >> 14) & 0x04)) : REG(r))
 
 // register data read
 #define READ_RDATA(r,a,f,p) (\
@@ -244,7 +246,7 @@ static uint8 blitter_ram[0x100];
 // as a floating point bit pattern being followed by a number of zeroes. So, e.g., 001101 translates to
 // 1.01 (the "1." being implied) x (2 ^ 3) or 1010 -> 10 in base 10 (i.e., 1.01 with the decimal place
 // being shifted to the right 3 places).
-static uint32 blitter_scanline_width[48] = 
+/*static uint32 blitter_scanline_width[48] = 
 {             
      0,    0,    0,    0,                                      // Note: This would really translate to 1, 1, 1, 1
      2,    0,    0,    0,
@@ -258,7 +260,7 @@ static uint32 blitter_scanline_width[48] =
    512,  640,  768,  896,
   1024, 1280, 1536, 1792,
   2048, 2560, 3072, 3584
-};
+};//*/
 
 //static uint8 * tom_ram_8;
 //static uint8 * paletteRam;
@@ -326,20 +328,54 @@ static int32 a1_clip_x, a1_clip_y;
 //
 void blitter_generic(uint32 cmd)
 {
+/*
+Blit! (0018FA70 <- 008DDC40) count: 2 x 13, A1/2_FLAGS: 00014218/00013C18 [cmd: 1401060C]
+ CMD -> src: SRCENX dst: DSTEN  misc:  a1ctl: UPDA1 UPDA2 mode:  ity: PATDSEL z-op:  op: LFU_CLEAR ctrl: BCOMPEN BKGWREN 
+  A1 step values: -2 (X), 1 (Y)
+  A2 step values: -1 (X), 1 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
+  A1 -> pitch: 1 phrases, depth: 8bpp, z-off: 0, width: 320 (21), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
+  A2 -> pitch: 1 phrases, depth: 8bpp, z-off: 0, width: 192 (1E), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
+        A1 x/y: 100/12, A2 x/y: 106/0 Pattern: 000000F300000000
+*/
+//if (effect_start)
+//     specialLog = true;
+/*if (cmd == 0x1401060C && blit_start_log)
+       specialLog = true;//*/
 //Testing only!
 //uint32 logGo = ((cmd == 0x01800E01 && REG(A1_BASE) == 0x898000) ? 1 : 0);
        uint32 srcdata, srczdata, dstdata, dstzdata, writedata, inhibit;
+       uint32 bppSrc = (DSTA2 ? 1 << ((REG(A1_FLAGS) >> 3) & 0x07) : 1 << ((REG(A2_FLAGS) >> 3) & 0x07));
 
 if (specialLog)
 {
-       WriteLog("About to do 8x8 blit (BM width is 448 pixels)...\n");
+       WriteLog("About to do n x m blit (BM width is ? pixels)...\n");
+       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);
 }
+/*     if (BCOMPEN)
+       {
+               if (DSTA2)
+                       a1_xadd = 0;
+               else
+                       a2_xadd = 0;
+       }//*/
+
        while (outer_loop--)
        {
 if (specialLog)
 {
        WriteLog("  A1_X/Y = %08X/%08X, A2_X/Y = %08X/%08X\n", a1_x, a1_y, a2_x, a2_y);
 }
+               uint32 a1_start = a1_x, a2_start = a2_x, bitPos = 0;
+
+               //Kludge for Hover Strike...
+               //I wonder if this kludge is in conjunction with the SRCENX down below...
+               // This isn't so much a kludge but the way things work in BCOMPEN mode...!
+               if (BCOMPEN && SRCENX)
+               {
+                       if (n_pixels < bppSrc)
+                               bitPos = bppSrc - n_pixels;
+               }
+
                inner_loop = n_pixels;
                while (inner_loop--)
                {
@@ -349,21 +385,22 @@ if (specialLog)
 }
                        srcdata = srczdata = dstdata = dstzdata = writedata = inhibit = 0;
 
-                       if (!DSTA2)
+                       if (!DSTA2)                                                     // Data movement: A1 <- A2
                        {
                                // load src data and Z
-                               if (SRCEN)
+//                             if (SRCEN)
+                               if (SRCEN || SRCENX)    // Not sure if this is correct... (seems to be...!)
                                {
                                        srcdata = READ_PIXEL(a2, REG(A2_FLAGS));
                                        if (SRCENZ)
                                                srczdata = READ_ZDATA(a2, REG(A2_FLAGS));
-                                       else if (cmd & 0x0001C020)
+                                       else if (cmd & 0x0001C020)      // PATDSEL | TOPBEN | TOPNEN | DSTWRZ
                                                srczdata = READ_RDATA(SRCZINT, a2, REG(A2_FLAGS), a2_phrase_mode);
                                }
-                               else
+                               else    // Use SRCDATA register...
                                {
                                        srcdata = READ_RDATA(SRCDATA, a2, REG(A2_FLAGS), a2_phrase_mode);
-                                       if (cmd & 0x0001C020)
+                                       if (cmd & 0x0001C020)           // PATDSEL | TOPBEN | TOPNEN | DSTWRZ
                                                srczdata = READ_RDATA(SRCZINT, a2, REG(A2_FLAGS), a2_phrase_mode);
                                }
 
@@ -402,8 +439,81 @@ if (specialLog)
                                // apply data comparator
 // Note: DCOMPEN only works in 8/16 bpp modes! !!! FIX !!!
 // Does BCOMPEN only work in 1 bpp mode???
+//   No, but it always does a 1 bit expansion no matter what the BPP of the channel is set to. !!! FIX !!!
+//   This is bit tricky... We need to fix the XADD value so that it acts like a 1BPP value while inside
+//   an 8BPP space.
                                if (DCOMPEN | BCOMPEN)
                                {
+//Temp, for testing Hover Strike
+//Doesn't seem to do it... Why?
+//What needs to happen here is twofold. First, the address generator in the outer loop has
+//to honor the BPP when calculating the start address (which it kinda does already). Second,
+//it has to step bit by bit when using BCOMPEN. How to do this???
+       if (BCOMPEN)
+//small problem with this approach: it's not accurate... We need a proper address to begin with
+//and *then* we can do the bit stepping from there the way it's *supposed* to be done... !!! FIX !!!
+//[DONE]
+       {
+               uint32 pixShift = (~bitPos) & (bppSrc - 1);
+               srcdata = (srcdata >> pixShift) & 0x01;
+
+               bitPos++;
+//             if (bitPos % bppSrc == 0)
+//                     a2_x += 0x00010000;
+       }
+/*
+Interesting (Hover Strike--large letter):
+
+Blit! (0018FA70 <- 008DDC40) count: 2 x 13, A1/2_FLAGS: 00014218/00013C18 [cmd: 1401060C]
+ CMD -> src: SRCENX dst: DSTEN  misc:  a1ctl: UPDA1 UPDA2 mode:  ity: PATDSEL z-op:  op: LFU_CLEAR ctrl: BCOMPEN BKGWREN 
+  A1 step values: -2 (X), 1 (Y)
+  A2 step values: -1 (X), 1 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
+  A1 -> pitch: 1 phrases, depth: 8bpp, z-off: 0, width: 320 (21), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
+  A2 -> pitch: 1 phrases, depth: 8bpp, z-off: 0, width: 192 (1E), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
+        A1 x/y: 100/12, A2 x/y: 106/0 Pattern: 000000F300000000
+
+Blit! (0018FA70 <- 008DDC40) count: 8 x 13, A1/2_FLAGS: 00014218/00013C18 [cmd: 1401060C]
+ CMD -> src: SRCENX dst: DSTEN  misc:  a1ctl: UPDA1 UPDA2 mode:  ity: PATDSEL z-op:  op: LFU_CLEAR ctrl: BCOMPEN BKGWREN 
+  A1 step values: -8 (X), 1 (Y)
+  A2 step values: -1 (X), 1 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
+  A1 -> pitch: 1 phrases, depth: 8bpp, z-off: 0, width: 320 (21), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
+  A2 -> pitch: 1 phrases, depth: 8bpp, z-off: 0, width: 192 (1E), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
+        A1 x/y: 102/12, A2 x/y: 107/0 Pattern: 000000F300000000
+
+Blit! (0018FA70 <- 008DDC40) count: 1 x 13, A1/2_FLAGS: 00014218/00013C18 [cmd: 1401060C]
+ CMD -> src: SRCENX dst: DSTEN  misc:  a1ctl: UPDA1 UPDA2 mode:  ity: PATDSEL z-op:  op: LFU_CLEAR ctrl: BCOMPEN BKGWREN 
+  A1 step values: -1 (X), 1 (Y)
+  A2 step values: -1 (X), 1 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
+  A1 -> pitch: 1 phrases, depth: 8bpp, z-off: 0, width: 320 (21), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
+  A2 -> pitch: 1 phrases, depth: 8bpp, z-off: 0, width: 192 (1E), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
+        A1 x/y: 118/12, A2 x/y: 70/0 Pattern: 000000F300000000
+
+Blit! (0018FA70 <- 008DDC40) count: 8 x 13, A1/2_FLAGS: 00014218/00013C18 [cmd: 1401060C]
+ CMD -> src: SRCENX dst: DSTEN  misc:  a1ctl: UPDA1 UPDA2 mode:  ity: PATDSEL z-op:  op: LFU_CLEAR ctrl: BCOMPEN BKGWREN 
+  A1 step values: -8 (X), 1 (Y)
+  A2 step values: -1 (X), 1 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
+  A1 -> pitch: 1 phrases, depth: 8bpp, z-off: 0, width: 320 (21), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
+  A2 -> pitch: 1 phrases, depth: 8bpp, z-off: 0, width: 192 (1E), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
+        A1 x/y: 119/12, A2 x/y: 71/0 Pattern: 000000F300000000
+
+Blit! (0018FA70 <- 008DDC40) count: 1 x 13, A1/2_FLAGS: 00014218/00013C18 [cmd: 1401060C]
+ CMD -> src: SRCENX dst: DSTEN  misc:  a1ctl: UPDA1 UPDA2 mode:  ity: PATDSEL z-op:  op: LFU_CLEAR ctrl: BCOMPEN BKGWREN 
+  A1 step values: -1 (X), 1 (Y)
+  A2 step values: -1 (X), 1 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
+  A1 -> pitch: 1 phrases, depth: 8bpp, z-off: 0, width: 320 (21), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
+  A2 -> pitch: 1 phrases, depth: 8bpp, z-off: 0, width: 192 (1E), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
+        A1 x/y: 127/12, A2 x/y: 66/0 Pattern: 000000F300000000
+
+Blit! (0018FA70 <- 008DDC40) count: 8 x 13, A1/2_FLAGS: 00014218/00013C18 [cmd: 1401060C]
+ CMD -> src: SRCENX dst: DSTEN  misc:  a1ctl: UPDA1 UPDA2 mode:  ity: PATDSEL z-op:  op: LFU_CLEAR ctrl: BCOMPEN BKGWREN 
+  A1 step values: -8 (X), 1 (Y)
+  A2 step values: -1 (X), 1 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
+  A1 -> pitch: 1 phrases, depth: 8bpp, z-off: 0, width: 320 (21), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
+  A2 -> pitch: 1 phrases, depth: 8bpp, z-off: 0, width: 192 (1E), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
+        A1 x/y: 128/12, A2 x/y: 67/0 Pattern: 000000F300000000
+*/
+
+
                                        if (!CMPDST)
                                        {
 //WriteLog("Blitter: BCOMPEN set on command %08X inhibit prev:%u, now:", cmd, inhibit);
@@ -432,6 +542,7 @@ Blit! (000B8250 <- 0012C3A0) count: 16 x 1, A1/2_FLAGS: 00014420/00012000 [cmd:
                                                else
                                                        WriteLog("Blitter: Bad BPP (%u) selected for BCOMPEN mode!\n", A2bpp);//*/
 // What it boils down to is this:
+
                                                if (srcdata == 0)
                                                        inhibit = 1;//*/
                                        }
@@ -442,9 +553,10 @@ Blit! (000B8250 <- 0012C3A0) count: 16 x 1, A1/2_FLAGS: 00014420/00012000 [cmd:
 //                                             if (dstdata != READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode))
                                                        inhibit = 1;
                                        }
+
 // This is DEFINITELY WRONG
-                                       if (a1_phrase_mode || a2_phrase_mode)
-                                               inhibit = !inhibit;
+//                                     if (a1_phrase_mode || a2_phrase_mode)
+//                                             inhibit = !inhibit;
                                }
 
                                if (CLIPA1)
@@ -456,20 +568,74 @@ Blit! (000B8250 <- 0012C3A0) count: 16 x 1, A1/2_FLAGS: 00014420/00012000 [cmd:
                                // compute the write data and store
                                if (!inhibit)
                                {                       
+// Houston, we have a problem...
+// Look here, at PATDSEL and GOURD. If both are active (as they are on the BIOS intro), then there's
+// a conflict! E.g.:
+//Blit! (00100000 <- 000095D0) count: 3 x 1, A1/2_FLAGS: 00014220/00004020 [cmd: 00011008]
+// CMD -> src:  dst: DSTEN  misc:  a1ctl:  mode: GOURD  ity: PATDSEL z-op:  op: LFU_CLEAR ctrl: 
+//  A1 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 320 (21), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
+//  A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 256 (20), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
+//        A1 x/y: 90/171, A2 x/y: 808/0 Pattern: 776D770077007700
+
                                        if (PATDSEL)
                                        {
                                                // use pattern data for write data
                                                writedata = READ_RDATA(PATTERNDATA, a1, REG(A1_FLAGS), a1_phrase_mode);
                                        }
-                                       else if (INTADD)
+                                       else if (ADDDSEL)
                                        {
+/*if (blit_start_log)
+       WriteLog("BLIT: ADDDSEL srcdata: %08X\, dstdata: %08X, ", srcdata, dstdata);//*/
+
                                                // intensity addition
-                                               writedata = (srcdata & 0xFF) + (dstdata & 0xFF);
+//Ok, this is wrong... Or is it? Yes, it's wrong! !!! FIX !!!
+/*                                             writedata = (srcdata & 0xFF) + (dstdata & 0xFF);
                                                if (!(TOPBEN) && writedata > 0xFF)
-                                                       writedata = 0xFF;
+//                                                     writedata = 0xFF;
+                                                       writedata &= 0xFF;
                                                writedata |= (srcdata & 0xF00) + (dstdata & 0xF00);
                                                if (!(TOPNEN) && writedata > 0xFFF)
-                                                       writedata = 0xFFF;
+//                                                     writedata = 0xFFF;
+                                                       writedata &= 0xFFF;
+                                               writedata |= (srcdata & 0xF000) + (dstdata & 0xF000);//*/
+//notneeded--writedata &= 0xFFFF;
+/*if (blit_start_log)
+       WriteLog("writedata: %08X\n", writedata);//*/
+/*
+Hover Strike ADDDSEL blit:
+
+Blit! (00098D90 <- 0081DDC0) count: 320 x 287, A1/2_FLAGS: 00004220/00004020 [cmd: 00020208]
+ CMD -> src:  dst: DSTEN  misc:  a1ctl: UPDA1  mode:  ity: ADDDSEL z-op:  op: LFU_CLEAR ctrl: 
+  A1 step values: -320 (X), 1 (Y)
+  A1 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
+  A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 256 (20), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
+        A1 x/y: 0/0, A2 x/y: 3288/0 Pattern: 0000000000000000 SRCDATA: 00FD00FD00FD00FD
+*/
+                                               writedata = (srcdata & 0xFF) + (dstdata & 0xFF);
+
+                                               if (!TOPBEN)
+                                               {
+//This is correct now, but slow...
+                                                       int16 s = (srcdata & 0xFF) | (srcdata & 0x80 ? 0xFF00 : 0x0000),
+                                                               d = dstdata & 0xFF;
+                                                       int16 sum = s + d;
+
+                                                       if (sum < 0)
+                                                               writedata = 0x00;
+                                                       else if (sum > 0xFF)
+                                                               writedata = 0xFF;
+                                                       else
+                                                               writedata = (uint32)sum;
+                                               }
+
+//This doesn't seem right... Looks like it would muck up the low byte... !!! FIX !!!
+                                               writedata |= (srcdata & 0xF00) + (dstdata & 0xF00);
+
+                                               if (!TOPNEN && writedata > 0xFFF)
+                                               {
+                                                       writedata &= 0xFFF;
+                                               }
+
                                                writedata |= (srcdata & 0xF000) + (dstdata & 0xF000);
                                        }
                                        else
@@ -480,6 +646,10 @@ Blit! (000B8250 <- 0012C3A0) count: 16 x 1, A1/2_FLAGS: 00014420/00012000 [cmd:
                                                if (LFU_A)       writedata |= srcdata  & dstdata;
                                        }
 
+//Although, this looks like it's OK... (even if it is shitty!)
+//According to JTRM, this is part of the four things the blitter does with the write data (the other
+//three being PATDSEL, ADDDSEL, and LFU (default). I'm not sure which gets precedence, this or PATDSEL
+//(see above blit example)...
                                        if (GOURD) 
                                                writedata = ((gd_c[colour_index]) << 8) | (gd_i[colour_index] >> 16);
 
@@ -503,7 +673,9 @@ Blit! (000B8250 <- 0012C3A0) count: 16 x 1, A1/2_FLAGS: 00014420/00012000 [cmd:
                                        srczdata = dstzdata;
                                }
 
+//Tried 2nd below for Hover Strike: No dice.
                                if (/*a1_phrase_mode || */BKGWREN || !inhibit)
+//                             if (/*a1_phrase_mode || BKGWREN ||*/ !inhibit)
                                {
 /*if (((REG(A1_FLAGS) >> 3) & 0x07) == 5)
 {
@@ -518,7 +690,7 @@ Blit! (000B8250 <- 0012C3A0) count: 16 x 1, A1/2_FLAGS: 00014420/00012000 [cmd:
                                                WRITE_ZDATA(a1, REG(A1_FLAGS), srczdata);
                                }
                        }
-                       else    // if (DSTA2)
+                       else    // if (DSTA2)                                                   // Data movement: A1 -> A2
                        {
                                // load src data and Z
                                if (SRCEN)
@@ -526,13 +698,13 @@ Blit! (000B8250 <- 0012C3A0) count: 16 x 1, A1/2_FLAGS: 00014420/00012000 [cmd:
                                        srcdata = READ_PIXEL(a1, REG(A1_FLAGS));
                                        if (SRCENZ)
                                                srczdata = READ_ZDATA(a1, REG(A1_FLAGS));
-                                       else if (cmd & 0x0001C020)
+                                       else if (cmd & 0x0001C020)      // PATDSEL | TOPBEN | TOPNEN | DSTWRZ
                                                srczdata = READ_RDATA(SRCZINT, a1, REG(A1_FLAGS), a1_phrase_mode);
                                }
                                else
                                {
                                        srcdata = READ_RDATA(SRCDATA, a1, REG(A1_FLAGS), a1_phrase_mode);
-                                       if (cmd & 0x001C020)
+                                       if (cmd & 0x001C020)    // PATDSEL | TOPBEN | TOPNEN | DSTWRZ
                                                srczdata = READ_RDATA(SRCZINT, a1, REG(A1_FLAGS), a1_phrase_mode);
                                }
 
@@ -593,8 +765,10 @@ Blit! (000B8250 <- 0012C3A0) count: 16 x 1, A1/2_FLAGS: 00014420/00012000 [cmd:
 //                                             if (dstdata != READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode))
                                                        inhibit = 1;
                                        }
-                                       if (a1_phrase_mode || a2_phrase_mode)
-                                               inhibit =! inhibit;
+
+// This is DEFINITELY WRONG
+//                                     if (a1_phrase_mode || a2_phrase_mode)
+//                                             inhibit = !inhibit;
                                }
                                
                                if (CLIPA1)
@@ -611,7 +785,7 @@ Blit! (000B8250 <- 0012C3A0) count: 16 x 1, A1/2_FLAGS: 00014420/00012000 [cmd:
                                                // use pattern data for write data
                                                writedata= READ_RDATA(PATTERNDATA, a2, REG(A2_FLAGS), a2_phrase_mode);
                                        }
-                                       else if (INTADD)
+                                       else if (ADDDSEL)
                                        {
                                                // intensity addition
                                                writedata = (srcdata & 0xFF) + (dstdata & 0xFF);
@@ -667,16 +841,36 @@ Blit! (000B8250 <- 0012C3A0) count: 16 x 1, A1/2_FLAGS: 00014420/00012000 [cmd:
 }//*/
                                        // write to the destination
                                        WRITE_PIXEL(a2, REG(A2_FLAGS), writedata);
+
                                        if (DSTWRZ)
                                                WRITE_ZDATA(a2, REG(A2_FLAGS), srczdata);
                                }
                        }
 
-                       // update x and y
-                       a1_x += a1_xadd;
-                       a1_y += a1_yadd;
-                       a2_x = (a2_x + a2_xadd) & a2_mask_x;
-                       a2_y = (a2_y + a2_yadd) & a2_mask_y;
+                       // Update x and y (inner loop)
+//Now it does! But crappy, crappy, crappy! !!! FIX !!! [DONE]
+//This is less than ideal, but it works...
+                       if (!BCOMPEN)
+                       {//*/
+                               a1_x += a1_xadd, a1_y += a1_yadd;
+                               a2_x = (a2_x + a2_xadd) & a2_mask_x, a2_y = (a2_y + a2_yadd) & a2_mask_y;
+                       }
+                       else
+                       {
+                               a1_y += a1_yadd, a2_y = (a2_y + a2_yadd) & a2_mask_y;
+                               if (!DSTA2)
+                               {
+                                       a1_x += a1_xadd;
+                                       if (bitPos % bppSrc == 0)
+                                               a2_x = (a2_x + a2_xadd) & a2_mask_x;
+                               }
+                               else
+                               {
+                                       a2_x = (a2_x + a2_xadd) & a2_mask_x;
+                                       if (bitPos % bppSrc == 0)
+                                               a1_x += a1_xadd;
+                               }
+                       }//*/
 
                        if (GOURZ)
                                z_i[colour_index] += zadd;
@@ -684,30 +878,144 @@ Blit! (000B8250 <- 0012C3A0) count: 16 x 1, A1/2_FLAGS: 00014420/00012000 [cmd:
                        if (GOURD || SRCSHADE)
                        {
                                gd_i[colour_index] += gd_ia;
+//Hmm, this doesn't seem to do anything...
+//But it is correct according to the JTRM...!
+if ((int32)gd_i[colour_index] < 0)
+       gd_i[colour_index] = 0;
+if (gd_i[colour_index] > 0x00FFFFFF)
+       gd_i[colour_index] = 0x00FFFFFF;//*/
+
                                gd_c[colour_index] += gd_ca;
+if ((int32)gd_c[colour_index] < 0)
+       gd_c[colour_index] = 0;
+if (gd_c[colour_index] > 0x000000FF)
+       gd_c[colour_index] = 0x000000FF;//*/
                        }
+
                        if (GOURD || SRCSHADE || GOURZ)
                        {
                                if (a1_phrase_mode)
+//This screws things up WORSE (for the BIOS opening screen)
+//                             if (a1_phrase_mode || a2_phrase_mode)
                                        colour_index = (colour_index + 1) & 0x03;
                        }
                }
 
+/*
+Here's the problem... The phrase mode code!
+Blit! (00100000 -> 00148000) count: 327 x 267, A1/2_FLAGS: 00004420/00004420 [cmd: 41802E01]
+ CMD -> src: SRCEN  dst:  misc:  a1ctl: UPDA1 UPDA2 mode: DSTA2 GOURZ ity:  z-op:  op: LFU_REPLACE ctrl: SRCSHADE
+  A1 step values: -327 (X), 1 (Y)
+  A2 step values: -327 (X), 1 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
+  A1 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 384 (22), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
+  A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 384 (22), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
+        A1 x/y: 28/58, A2 x/y: 28/58 Pattern: 00EA7BEA77EA77EA SRCDATA: 7BFF7BFF7BFF7BFF
+
+Below fixes it, but then borks:
+; O
+
+Blit! (00110000 <- 0010B2A8) count: 12 x 12, A1/2_FLAGS: 000042E2/00000020 [cmd: 09800609]
+ CMD -> src: SRCEN  dst: DSTEN  misc:  a1ctl: UPDA1 UPDA2 mode:  ity:  z-op:  op: LFU_REPLACE ctrl: DCOMPEN 
+  A1 step values: -15 (X), 1 (Y)
+  A2 step values: -4 (X), 0 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
+  A1 -> pitch: 4 phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
+  A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
+        A1 x/y: 173/144, A2 x/y: 4052/0
+
+Lesse, with pre-add we'd have:
+
+     oooooooooooo
+00001111222233334444555566667777
+  ^  ^starts here...
+  |             ^ends here.
+  |rolls back to here. Hmm.
+
+*/
                a1_x += a1_step_x;
                a1_y += a1_step_y;
                a2_x += a2_step_x;
-               a2_y += a2_step_y;
+               a2_y += a2_step_y;//*/
+
+               //New: Phrase mode taken into account! :-p
+/*             if (a1_phrase_mode)                     // v1
+               {
+                       // Bump the pointer to the next phrase boundary
+                       // Even though it works, this is crappy... Clean it up!
+                       uint32 size = 64 / a1_psize;
 
-/*             if (a2_phrase_mode)
+                       // Crappy kludge... ('aligning' source to destination)
+                       if (a2_phrase_mode && DSTA2)
+                       {
+                               uint32 extra = (a2_start >> 16) % size;
+                               a1_x += extra << 16;
+                       }
+
+                       uint32 newx = (a1_x >> 16) / size;
+                       uint32 newxrem = (a1_x >> 16) % size;
+                       a1_x &= 0x0000FFFF;
+                       a1_x |= (((newx + (newxrem == 0 ? 0 : 1)) * size) & 0xFFFF) << 16;
+               }//*/
+               if (a1_phrase_mode)                     // v2
                {
-                       a1_x+=(64/a1_psize)*a1_xadd;
-               }       
-               if (a2_phrase_mode)
+                       // Bump the pointer to the next phrase boundary
+                       // Even though it works, this is crappy... Clean it up!
+                       uint32 size = 64 / a1_psize;
+
+                       // Crappy kludge... ('aligning' source to destination)
+                       if (a2_phrase_mode && DSTA2)
+                       {
+                               uint32 extra = (a2_start >> 16) % size;
+                               a1_x += extra << 16;
+                       }
+
+                       uint32 pixelSize = (size - 1) << 16;
+                       a1_x = (a1_x + pixelSize) & ~pixelSize;
+               }
+
+/*             if (a2_phrase_mode)                     // v1
+               {
+                       // Bump the pointer to the next phrase boundary
+                       // Even though it works, this is crappy... Clean it up!
+                       uint32 size = 64 / a2_psize;
+
+                       // Crappy kludge... ('aligning' source to destination)
+                       // Prolly should do this for A1 channel as well... [DONE]
+                       if (a1_phrase_mode && !DSTA2)
+                       {
+                               uint32 extra = (a1_start >> 16) % size;
+                               a2_x += extra << 16;
+                       }
+
+                       uint32 newx = (a2_x >> 16) / size;
+                       uint32 newxrem = (a2_x >> 16) % size;
+                       a2_x &= 0x0000FFFF;
+                       a2_x |= (((newx + (newxrem == 0 ? 0 : 1)) * size) & 0xFFFF) << 16;
+               }//*/
+               if (a2_phrase_mode)                     // v1
                {
-                       for (int nb=0;nb<(64/a2_psize)+1;nb++)
-                               a2_x = (a2_x + a2_xadd) & a2_mask_x;
+                       // Bump the pointer to the next phrase boundary
+                       // Even though it works, this is crappy... Clean it up!
+                       uint32 size = 64 / a2_psize;
+
+                       // Crappy kludge... ('aligning' source to destination)
+                       // Prolly should do this for A1 channel as well... [DONE]
+                       if (a1_phrase_mode && !DSTA2)
+                       {
+                               uint32 extra = (a1_start >> 16) % size;
+                               a2_x += extra << 16;
+                       }
+
+                       uint32 pixelSize = (size - 1) << 16;
+                       a2_x = (a2_x + pixelSize) & ~pixelSize;
                }
-*/     }
+
+               //Not entirely: This still mucks things up... !!! FIX !!!
+               //Should this go before or after the phrase mode mucking around?
+/*             a1_x += a1_step_x;
+               a1_y += a1_step_y;
+               a2_x += a2_step_x;
+               a2_y += a2_step_y;//*/
+       }
        
        // write values back to registers 
        WREG(A1_PIXEL,  (a1_y & 0xFFFF0000) | ((a1_x >> 16) & 0xFFFF));
@@ -718,6 +1026,14 @@ specialLog = false;
 
 void blitter_blit(uint32 cmd)
 {
+//Apparently this is doing *something*, just not sure exactly what...
+/*if (cmd == 0x41802E01)
+{
+       WriteLog("BLIT: Found our blit. Was: %08X ", cmd);
+       cmd = 0x01800E01;
+       WriteLog("Is: %08X\n", cmd);
+}//*/
+
        uint32 pitchValue[4] = { 0, 1, 3, 2 };
        colour_index = 0;
        src = cmd & 0x07;
@@ -730,13 +1046,10 @@ void blitter_blit(uint32 cmd)
        op = (cmd >> 21) & 0x0F;
        ctrl = (cmd >> 25) & 0x3F;
 
-       a1_addr = REG(A1_BASE);
-//Just for testing Trevor McFur...
-//if (a1_addr == 0x130CB0) specialLog = true;
-//extern bool suppressOutput;
-//if (a1_addr == 0x130CB0) suppressOutput = false;
-//End testing
-       a2_addr = REG(A2_BASE);
+       // Addresses in A1/2_BASE are *phrase* aligned, i.e., bottom three bits are ignored!
+       // NOTE: This fixes Rayman's bad collision detection AND keeps T2K working!
+       a1_addr = REG(A1_BASE) & 0xFFFFFFF8;
+       a2_addr = REG(A2_BASE) & 0xFFFFFFF8;
 
        a1_zoffs = (REG(A1_FLAGS) >> 6) & 7;
        a2_zoffs = (REG(A2_FLAGS) >> 6) & 7;
@@ -755,9 +1068,14 @@ void blitter_blit(uint32 cmd)
        a1_y = (REG(A1_PIXEL) & 0xFFFF0000) | (REG(A1_FPIXEL) >> 16);
 //According to the JTRM, X is restricted to 15 bits and Y is restricted to 12.
 //But it seems to fuck up T2K! !!! FIX !!!
+//Could it be sign extended??? Doesn't seem to be so according to JTRM
 //     a1_x &= 0x7FFFFFFF, a1_y &= 0x0FFFFFFF;
+//Actually, it says that the X is 16 bits. But it still seems to mess with the Y when restricted to 12...
+//     a1_y &= 0x0FFFFFFF;
 
 //     a1_width = blitter_scanline_width[((REG(A1_FLAGS) & 0x00007E00) >> 9)];
+// According to JTRM, this must give a *whole number* of phrases in the current
+// pixel size (this means the lookup above is WRONG)... !!! FIX !!!
        UINT32 m = (REG(A1_FLAGS) >> 9) & 0x03, e = (REG(A1_FLAGS) >> 11) & 0x0F;
        a1_width = ((0x04 | m) << e) >> 2;//*/
 
@@ -766,8 +1084,12 @@ void blitter_blit(uint32 cmd)
 //According to the JTRM, X is restricted to 15 bits and Y is restricted to 12.
 //But it seems to fuck up T2K! !!! FIX !!!
 //     a2_x &= 0x7FFFFFFF, a2_y &= 0x0FFFFFFF;
+//Actually, it says that the X is 16 bits. But it still seems to mess with the Y when restricted to 12...
+//     a2_y &= 0x0FFFFFFF;
 
 //     a2_width = blitter_scanline_width[((REG(A2_FLAGS) & 0x00007E00) >> 9)];
+// According to JTRM, this must give a *whole number* of phrases in the current
+// pixel size (this means the lookup above is WRONG)... !!! FIX !!!
        m = (REG(A2_FLAGS) >> 9) & 0x03, e = (REG(A2_FLAGS) >> 11) & 0x0F;
        a2_width = ((0x04 | m) << e) >> 2;//*/
        a2_mask_x = ((REG(A2_MASK) & 0x0000FFFF) << 16) | 0xFFFF;
@@ -807,10 +1129,24 @@ void blitter_blit(uint32 cmd)
                break;
        case XADDINC:
                // add the contents of the increment register
-               a1_xadd = (REG(A1_INC) << 16)            | (REG(A1_FINC) & 0xFFFF);
+               a1_xadd = (REG(A1_INC) << 16)            | (REG(A1_FINC) & 0x0000FFFF);
                a1_yadd = (REG(A1_INC) & 0xFFFF0000) | (REG(A1_FINC) >> 16);
                break;
        }
+
+
+//Blit! (0011D000 -> 000B9600) count: 228 x 1, A1/2_FLAGS: 00073820/00064220 [cmd: 41802801]
+//  A1 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 128 (1C), addctl: XADDINC YADD1 XSIGNADD YSIGNADD
+//  A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 320 (21), addctl: XADD0 YADD1 XSIGNADD YSIGNADD
+//if (YADD1_A1 && YADD1_A2 && xadd_a2_control == XADD0 && xadd_a1_control == XADDINC)// &&
+//     UINT32 a1f = REG(A1_FLAGS), a2f = REG(A2_FLAGS);
+//Ok, so this ISN'T it... Prolly the XADDPHR code above that's doing it...
+//if (REG(A1_FLAGS) == 0x00073820 && REG(A2_FLAGS) == 0x00064220 && cmd == 0x41802801)
+//        A1 x/y: 14368/7, A2 x/y: 150/36
+//This is it... The problem...
+//if ((a1_x >> 16) == 14368) // 14368 = $3820
+//     return; //Lesse what we got...
+
        if (XSIGNSUB_A1)
                a1_xadd = -a1_xadd;
 
@@ -837,13 +1173,14 @@ void blitter_blit(uint32 cmd)
                break;
 //This really isn't a valid bit combo for A2... Shouldn't this cause the blitter to just say no?
        case XADDINC:
-WriteLog("BLIT: Asked to used invalid bit combo for A2...\n");
+WriteLog("BLIT: Asked to use invalid bit combo (XADDINC) for A2...\n");
                // add the contents of the increment register
                // since there is no register for a2 we just add 1
 //Let's do nothing, since it's not listed as a valid bit combo...
 //             a2_xadd = 1 << 16;
                break;
        }
+
        if (XSIGNSUB_A2)
                a2_xadd = -a2_xadd;
 
@@ -874,129 +1211,64 @@ WriteLog("BLIT: Asked to used invalid bit combo for A2...\n");
                a1_clip_x = REG(A1_CLIP) & 0x7FFF,
                a1_clip_y = (REG(A1_CLIP) >> 16) & 0x7FFF;
 
-// This phrase sizing is incorrect as well... !!! FIX !!!
+// This phrase sizing is incorrect as well... !!! FIX !!! [NOTHING TO FIX]
 // Err, this is pixel size... (and it's OK)
        a2_psize = 1 << ((REG(A2_FLAGS) >> 3) & 0x07);
        a1_psize = 1 << ((REG(A1_FLAGS) >> 3) & 0x07);
 
-       // zbuffering
+       // Z-buffering
        if (GOURZ)
        {
-               zadd = JaguarReadLong(0xF02274, BLITTER);
+               zadd = REG(ZINC);
 
-               for(int v=0; v<4; v++) 
-                       z_i[v] = (int32)JaguarReadLong(0xF0228C + (v << 2), BLITTER);
+               for(int v=0; v<4; v++)
+                       z_i[v] = REG(PHRASEZ0 + v*4);
        }
+
+       // Gouraud shading
        if (GOURD || GOURZ || SRCSHADE)
        {
-               // gouraud shading
-               gouraud_add = JaguarReadLong(0xF02270, BLITTER);
+               gd_c[0] = blitter_ram[PATTERNDATA + 0];
+               gd_i[0] = ((uint32)blitter_ram[PATTERNDATA + 1] << 16)
+                       | ((uint32)blitter_ram[SRCDATA + 0] << 8) | blitter_ram[SRCDATA + 1];
+
+               gd_c[1] = blitter_ram[PATTERNDATA + 2];
+               gd_i[1] = ((uint32)blitter_ram[PATTERNDATA + 3] << 16)
+                       | ((uint32)blitter_ram[SRCDATA + 2] << 8) | blitter_ram[SRCDATA + 3];
+
+               gd_c[2] = blitter_ram[PATTERNDATA + 4];
+               gd_i[2] = ((uint32)blitter_ram[PATTERNDATA + 5] << 16)
+                       | ((uint32)blitter_ram[SRCDATA + 4] << 8) | blitter_ram[SRCDATA + 5];
+
+               gd_c[3] = blitter_ram[PATTERNDATA + 6];
+               gd_i[3] = ((uint32)blitter_ram[PATTERNDATA + 7] << 16)
+                       | ((uint32)blitter_ram[SRCDATA + 6] << 8) | blitter_ram[SRCDATA + 7];
+
+               gouraud_add = REG(INTENSITYINC);
                
-               gd_c[0] = JaguarReadByte(0xF02268, BLITTER);
-               gd_i[0] = JaguarReadByte(0xF02269, BLITTER);
-               gd_i[0] <<= 16;
-               gd_i[0] |= JaguarReadWord(0xF02240, BLITTER);
-
-               gd_c[1] = JaguarReadByte(0xF0226A, BLITTER);
-               gd_i[1] = JaguarReadByte(0xF0226B, BLITTER);
-               gd_i[1] <<= 16;
-               gd_i[1] |= JaguarReadWord(0xF02242, BLITTER);
-
-               gd_c[2] = JaguarReadByte(0xF0226C, BLITTER);
-               gd_i[2] = JaguarReadByte(0xF0226D, BLITTER);
-               gd_i[2] <<= 16;
-               gd_i[2] |= JaguarReadWord(0xF02244, BLITTER);
-
-               gd_c[3] = JaguarReadByte(0xF0226E, BLITTER);
-               gd_i[3] = JaguarReadByte(0xF0226F, BLITTER);
-               gd_i[3] <<= 16; 
-               gd_i[3] |= JaguarReadWord(0xF02246, BLITTER);
-
-               gd_ia = gouraud_add & 0xFFFFFF;
-               if (gd_ia & 0x800000)
+               gd_ia = gouraud_add & 0x00FFFFFF;
+               if (gd_ia & 0x00800000)
                        gd_ia = 0xFF000000 | gd_ia;
 
-               gd_ca = (gouraud_add>>24) & 0xFF;
-               if (gd_ca & 0x80)
+               gd_ca = (gouraud_add >> 24) & 0xFF;
+               if (gd_ca & 0x00000080)
                        gd_ca = 0xFFFFFF00 | gd_ca;
        }
 
-       // fix for zoop! and syndicate
-/*     if ((jaguar_mainRom_crc32==0x501be17c)||
-               (jaguar_mainRom_crc32==0x70895c51)||
-               (jaguar_mainRom_crc32==0x0f1f1497)||
-               (jaguar_mainRom_crc32==0xfc8f0dcd)
-          )
-       {
-               if (a1_step_x < 0)
-                       a1_step_x = (-n_pixels) * 65536;
-
-               if (a2_step_x < 0)
-                       a2_step_x = (-n_pixels) * 65536;;
-       }
-       else
-       // fix for wolfenstein 3d
-       if (jaguar_mainRom_crc32==0x3966698f)
+       // Bit comparitor fixing...
+/*     if (BCOMPEN)
        {
-               if (n_pixels==24)
-               {
-                       if ((a1_step_x / 65536)==-28)
-                       {
-                               a1_step_x=-24*65536; // au lieu de -28
-                               a2_step_x=  0*65536; // au lieu de -8
-                       }
-               }
-       } 
-       else
-       // fix for Tempest 2000
-       if (jaguar_mainRom_crc32==0x32816d44)
+               // Determine the data flow direction...
+               if (!DSTA2)
+                       a2_step_x /= (1 << ((REG(A2_FLAGS) >> 3) & 0x07));
+               else
+                       ;//add this later
+       }//*/
+/*     if (BCOMPEN)//Kludge for Hover Strike... !!! FIX !!!
        {
-
-               if ((n_lines!=1)&&((n_pixels==288)||(n_pixels==384)))
-               {
-                       WriteLog("Blit!\n");
-                       WriteLog("  cmd      = 0x%.8x\n",cmd);
-                       WriteLog("  a1_base  = %08X\n", a1_addr);
-                       WriteLog("  a1_pitch = %d\n", a1_pitch);
-                       WriteLog("  a1_psize = %d\n", a1_psize);
-                       WriteLog("  a1_width = %d\n", a1_width);
-                       WriteLog("  a1_xadd  = %f (phrase=%d)\n", (float)a1_xadd / 65536.0, a1_phrase_mode);
-                       WriteLog("  a1_yadd  = %f\n", (float)a1_yadd / 65536.0);
-                       WriteLog("  a1_xstep = %f\n", (float)a1_step_x / 65536.0);
-                       WriteLog("  a1_ystep = %f\n", (float)a1_step_y / 65536.0);
-                       WriteLog("  a1_x     = %f\n", (float)a1_x / 65536.0);
-                       WriteLog("  a1_y     = %f\n", (float)a1_y / 65536.0);
-                       WriteLog("  a1_zoffs = %i\n",a1_zoffs);
-
-                       WriteLog("  a2_base  = %08X\n", a2_addr);
-                       WriteLog("  a2_pitch = %d\n", a2_pitch);
-                       WriteLog("  a2_psize = %d\n", a2_psize);
-                       WriteLog("  a2_width = %d\n", a2_width);
-                       WriteLog("  a2_xadd  = %f (phrase=%d)\n", (float)a2_xadd / 65536.0, a2_phrase_mode);
-                       WriteLog("  a2_yadd  = %f\n", (float)a2_yadd / 65536.0);
-                       WriteLog("  a2_xstep = %f\n", (float)a2_step_x / 65536.0);
-                       WriteLog("  a2_ystep = %f\n", (float)a2_step_y / 65536.0);
-                       WriteLog("  a2_x     = %f\n", (float)a2_x / 65536.0);
-                       WriteLog("  a2_y     = %f\n", (float)a2_y / 65536.0);
-                       WriteLog("  a2_mask_x= 0x%.4x\n",a2_mask_x);
-                       WriteLog("  a2_mask_y= 0x%.4x\n",a2_mask_y);
-                       WriteLog("  a2_zoffs = %i\n",a2_zoffs);
-
-                       WriteLog("  count    = %d x %d\n", n_pixels, n_lines);
-
-                       WriteLog("  command  = %08X\n", cmd);
-                       WriteLog("  dsten    = %i\n",DSTEN);
-                       WriteLog("  srcen    = %i\n",SRCEN);
-                       WriteLog("  patdsel  = %i\n",PATDSEL);
-                       WriteLog("  color    = 0x%.8x\n",REG(PATTERNDATA));
-                       WriteLog("  dcompen  = %i\n",DCOMPEN);
-                       WriteLog("  bcompen  = %i\n",BCOMPEN);
-                       WriteLog("  cmpdst   = %i\n",CMPDST);
-                       WriteLog("  GOURZ    = %i\n",GOURZ);
-                       WriteLog("  GOURD    = %i\n",GOURD);
-                       WriteLog("  SRCSHADE = %i\n",SRCSHADE);
-                       WriteLog("  DSTDATA  = 0x%.8x%.8x\n",REG(DSTDATA),REG(DSTDATA+4));
-               }       
+               // Determine the data flow direction...
+               if (!DSTA2)
+                       a2_x <<= 3;
        }//*/
 
 #ifdef LOG_BLITS
@@ -1046,17 +1318,115 @@ WriteLog("BLIT: Asked to used invalid bit combo for A2...\n");
        }       
 #endif
 
-extern int blit_start_log;
-extern int op_start_log;
+//NOTE: Pitch is ignored!
+
+//This *might* be the altimeter blits (they are)...
+//On captured screen, x-pos for black (inner) is 259, for pink is 257
+//Black is short by 3, pink is short by 1...
+/*
+Blit! (00110000 <- 000BF010) count: 9 x 31, A1/2_FLAGS: 000042E2/00010020 [cmd: 00010200]
+ CMD -> src:  dst:  misc:  a1ctl: UPDA1  mode:  ity: PATDSEL z-op:  op: LFU_CLEAR ctrl: 
+  A1 -> pitch: 4 phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
+  A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
+        A1 x/y: 262/124, A2 x/y: 128/0
+Blit! (00110000 <- 000BF010) count: 5 x 38, A1/2_FLAGS: 000042E2/00010020 [cmd: 00010200]
+ CMD -> src:  dst:  misc:  a1ctl: UPDA1  mode:  ity: PATDSEL z-op:  op: LFU_CLEAR ctrl: 
+  A1 -> pitch: 4 phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
+  A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
+        A1 x/y: 264/117, A2 x/y: 407/0
+
+Blit! (00110000 <- 000BF010) count: 9 x 23, A1/2_FLAGS: 000042E2/00010020 [cmd: 00010200]
+ CMD -> src:  dst:  misc:  a1ctl: UPDA1  mode:  ity: PATDSEL z-op:  op: LFU_CLEAR ctrl: 
+  A1 step values: -10 (X), 1 (Y)
+  A1 -> pitch: 4(2) phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
+  A2 -> pitch: 1(0) phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
+        A1 x/y: 262/132, A2 x/y: 129/0
+Blit! (00110000 <- 000BF010) count: 5 x 27, A1/2_FLAGS: 000042E2/00010020 [cmd: 00010200]
+ CMD -> src:  dst:  misc:  a1ctl: UPDA1  mode:  ity: PATDSEL z-op:  op: LFU_CLEAR ctrl: 
+  A1 step values: -8 (X), 1 (Y)
+  A1 -> pitch: 4(2) phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
+  A2 -> pitch: 1(0) phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
+        A1 x/y: 264/128, A2 x/y: 336/0
+
+  264v       vCursor ends up here...
+     xxxxx...`
+     111122223333
+
+262v         vCursor ends up here...
+   xxxxxxxxx.'
+ 1111222233334444
+
+Fixed! Now for more:
+
+; This looks like the ship icon in the upper left corner...
+
+Blit! (00110000 <- 0010B2A8) count: 11 x 12, A1/2_FLAGS: 000042E2/00000020 [cmd: 09800609]
+ CMD -> src: SRCEN  dst: DSTEN  misc:  a1ctl: UPDA1 UPDA2 mode:  ity:  z-op:  op: LFU_REPLACE ctrl: DCOMPEN 
+  A1 step values: -12 (X), 1 (Y)
+  A2 step values: 0 (X), 0 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
+  A1 -> pitch: 4 phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
+  A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
+        A1 x/y: 20/24, A2 x/y: 5780/0
+
+Also fixed!
+
+More (not sure this is a blitter problem as much as it's a GPU problem):
+All but the "M" are trashed...
+This does *NOT* look like a blitter problem, as it's rendering properly...
+Actually, if you look at the A1 step values, there IS a discrepancy!
+
+; D
+
+Blit! (00110000 <- 0010B2A8) count: 12 x 12, A1/2_FLAGS: 000042E2/00000020 [cmd: 09800609]
+ CMD -> src: SRCEN  dst: DSTEN  misc:  a1ctl: UPDA1 UPDA2 mode:  ity:  z-op:  op: LFU_REPLACE ctrl: DCOMPEN 
+  A1 step values: -14 (X), 1 (Y)
+  A2 step values: -4 (X), 0 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
+  A1 -> pitch: 4 phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
+  A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
+        A1 x/y: 134/144, A2 x/y: 2516/0
+;129,146: +5,-2
+
+; E
+
+Blit! (00110000 <- 0010B2A8) count: 12 x 12, A1/2_FLAGS: 000042E2/00000020 [cmd: 09800609]
+ CMD -> src: SRCEN  dst: DSTEN  misc:  a1ctl: UPDA1 UPDA2 mode:  ity:  z-op:  op: LFU_REPLACE ctrl: DCOMPEN 
+  A1 step values: -13 (X), 1 (Y)
+  A2 step values: -4 (X), 0 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
+  A1 -> pitch: 4 phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
+  A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
+        A1 x/y: 147/144, A2 x/y: 2660/0
+
+; M
+
+Blit! (00110000 <- 0010B2A8) count: 12 x 12, A1/2_FLAGS: 000042E2/00000020 [cmd: 09800609]
+ CMD -> src: SRCEN  dst: DSTEN  misc:  a1ctl: UPDA1 UPDA2 mode:  ity:  z-op:  op: LFU_REPLACE ctrl: DCOMPEN 
+  A1 step values: -12 (X), 1 (Y)
+  A2 step values: 0 (X), 0 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
+  A1 -> pitch: 4 phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
+  A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
+        A1 x/y: 160/144, A2 x/y: 3764/0
+
+; O
+
+Blit! (00110000 <- 0010B2A8) count: 12 x 12, A1/2_FLAGS: 000042E2/00000020 [cmd: 09800609]
+ CMD -> src: SRCEN  dst: DSTEN  misc:  a1ctl: UPDA1 UPDA2 mode:  ity:  z-op:  op: LFU_REPLACE ctrl: DCOMPEN 
+  A1 step values: -15 (X), 1 (Y)
+  A2 step values: -4 (X), 0 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
+  A1 -> pitch: 4 phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
+  A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
+        A1 x/y: 173/144, A2 x/y: 4052/0
+
+*/
+//extern int op_start_log;
 if (blit_start_log)
 {
        char * ctrlStr[4] = { "XADDPHR\0", "XADDPIX\0", "XADD0\0", "XADDINC\0" };
        char * bppStr[8] = { "1bpp\0", "2bpp\0", "4bpp\0", "8bpp\0", "16bpp\0", "32bpp\0", "???\0", "!!!\0" };
        char * opStr[16] = { "LFU_CLEAR", "LFU_NSAND", "LFU_NSAD", "LFU_NOTS", "LFU_SAND", "LFU_NOTD", "LFU_N_SXORD", "LFU_NSORND",
                "LFU_SAD", "LFU_XOR", "LFU_D", "LFU_NSORD", "LFU_REPLACE", "LFU_SORND", "LFU_SORD", "LFU_ONE" };
-       uint32 src = cmd & 0x07, dst = (cmd >> 3) & 0x07, misc = (cmd >> 6) & 0x03,
-               a1ctl = (cmd >> 8) & 0x07, mode = (cmd >> 11) & 0x07, ity = (cmd >> 14) & 0x0F,
-               zop = (cmd >> 18) & 0x07, op = (cmd >> 21) & 0x0F, ctrl = (cmd >> 25) & 0x3F;
+       uint32 /*src = cmd & 0x07, dst = (cmd >> 3) & 0x07, misc = (cmd >> 6) & 0x03,
+               a1ctl = (cmd >> 8) & 0x07,*/ mode = (cmd >> 11) & 0x07/*, ity = (cmd >> 14) & 0x0F,
+               zop = (cmd >> 18) & 0x07, op = (cmd >> 21) & 0x0F, ctrl = (cmd >> 25) & 0x3F*/;
        UINT32 a1f = REG(A1_FLAGS), a2f = REG(A2_FLAGS);
        uint32 p1 = a1f & 0x07, p2 = a2f & 0x07,
                d1 = (a1f >> 3) & 0x07, d2 = (a2f >> 3) & 0x07,
@@ -1072,20 +1442,21 @@ if (blit_start_log)
        WriteLog("dst: %s%s%s ", (cmd & 0x0008 ? "DSTEN " : ""), (cmd & 0x0010 ? "DSTENZ " : ""), (cmd & 0x0020 ? "DSTWRZ" : ""));
        WriteLog("misc: %s%s ", (cmd & 0x0040 ? "CLIP_A1 " : ""), (cmd & 0x0080 ? "???" : ""));
        WriteLog("a1ctl: %s%s%s ", (cmd & 0x0100 ? "UPDA1F " : ""), (cmd & 0x0200 ? "UPDA1 " : ""), (cmd & 0x0400 ? "UPDA2" : ""));
-       WriteLog("mode: %s%s%s ", (cmd & 0x0800 ? "DSTA2 " : ""), (cmd & 0x1000 ? "GOURD " : ""), (cmd & 0x2000 ? "ZBUFF" : ""));
-       WriteLog("ity: %s%s%s ", (cmd & 0x4000 ? "TOPBEN " : ""), (cmd & 0x8000 ? "TOPNEN " : ""), (cmd & 0x00010000 ? "PATDSEL" : ""));
+       WriteLog("mode: %s%s%s ", (cmd & 0x0800 ? "DSTA2 " : ""), (cmd & 0x1000 ? "GOURD " : ""), (cmd & 0x2000 ? "GOURZ" : ""));
+       WriteLog("ity: %s%s%s%s ", (cmd & 0x4000 ? "TOPBEN " : ""), (cmd & 0x8000 ? "TOPNEN " : ""), (cmd & 0x00010000 ? "PATDSEL" : ""), (cmd & 0x00020000 ? "ADDDSEL" : ""));
        WriteLog("z-op: %s%s%s ", (cmd & 0x00040000 ? "ZMODELT " : ""), (cmd & 0x00080000 ? "ZMODEEQ " : ""), (cmd & 0x00100000 ? "ZMODEGT" : ""));
        WriteLog("op: %s ", opStr[(cmd >> 21) & 0x0F]);
        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" : ""));
 
+       if (UPDA1)
+               WriteLog("  A1 step values: %d (X), %d (Y)\n", a1_step_x >> 16, a1_step_y >> 16);
+
        if (UPDA2)
-       {
                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);
-       }
 
        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"));
        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"));
-       WriteLog("        A1 x/y: %d/%d, A2 x/y: %d/%d\n", a1_x >> 16, a1_y >> 16, a2_x >> 16, a2_y >> 16);
+       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));
 //     blit_start_log = 0;
 //     op_start_log = 1;
 }
@@ -1133,17 +1504,27 @@ uint8 BlitterReadByte(uint32 offset, uint32 who/*=UNKNOWN*/)
        offset &= 0xFF;
 
        // status register
+//This isn't cycle accurate--how to fix? !!! FIX !!!
        if (offset == (0x38 + 3))
                return 0x01;    // always idle
 
+//Attempted fix for AvP:
+       if (offset >= 0x04 && offset <= 0x07)
+//             return (offset > 0x05 ? blitter_ram[PIXLINECOUNTER + offset - 0x04] : 0x00);
+//             return 0x00;    // WO register! What does it expect to see here???
+//This is it. I wonder if it just ignores the lower three bits?
+               return blitter_ram[A1_PIXEL + offset - 0x04];
+
        return blitter_ram[offset];
 }
 
+//Crappy!
 uint16 BlitterReadWord(uint32 offset, uint32 who/*=UNKNOWN*/)
 {
        return ((uint16)BlitterReadByte(offset, who) << 8) | (uint16)BlitterReadByte(offset+1, who);
 }
 
+//Crappy!
 uint32 BlitterReadLong(uint32 offset, uint32 who/*=UNKNOWN*/)
 {
        return (BlitterReadWord(offset, who) << 16) | BlitterReadWord(offset+2, who);
@@ -1156,32 +1537,53 @@ void BlitterWriteByte(uint32 offset, uint8 data, uint32 who/*=UNKNOWN*/)
        offset &= 0xFF;
 
 //     if ((offset >= 0x7C) && (offset <= 0x9B))
-       if ((offset >= 0x7C) && (offset <= 0x8B))
+       // This handles writes to INTENSITY0-3 by also writing them to their proper places in
+       // PATTERNDATA & SOURCEDATA (should do the same for the Z registers! !!! FIX !!! [DONE])
+       if ((offset >= 0x7C) && (offset <= 0x9B))//8B))
        {
                switch (offset)
                {
+               // INTENSITY registers 0-3
                case 0x7C: break;
-               case 0x7D: blitter_ram[0x69] = data; break;
-               case 0x7E: blitter_ram[0x40] = data; break;
-               case 0x7F: blitter_ram[0x41] = data; break;
+               case 0x7D: blitter_ram[PATTERNDATA + 1] = data; break;
+               case 0x7E: blitter_ram[SRCDATA + 0] = data; break;
+               case 0x7F: blitter_ram[SRCDATA + 1] = data; break;
 
                case 0x80: break;
-               case 0x81: blitter_ram[0x6B] = data; break;
-               case 0x82: blitter_ram[0x42] = data; break;
-               case 0x83: blitter_ram[0x43] = data; break;
+               case 0x81: blitter_ram[PATTERNDATA + 3] = data; break;
+               case 0x82: blitter_ram[SRCDATA + 2] = data; break;
+               case 0x83: blitter_ram[SRCDATA + 3] = data; break;
                
                case 0x84: break;
-               case 0x85: blitter_ram[0x6D] = data; break;
-               case 0x86: blitter_ram[0x44] = data; break;
-               case 0x87: blitter_ram[0x45] = data; break;
+               case 0x85: blitter_ram[PATTERNDATA + 5] = data; break;
+               case 0x86: blitter_ram[SRCDATA + 4] = data; break;
+               case 0x87: blitter_ram[SRCDATA + 5] = data; break;
                
                case 0x88: break;
-               case 0x89: blitter_ram[0x6F] = data; break;
-//Mistyped?
-//             case 0x9A: blitter_ram[0x46] = data; break;
-//             case 0x9B: blitter_ram[0x47] = data; break;
-               case 0x8A: blitter_ram[0x46] = data; break;
-               case 0x8B: blitter_ram[0x47] = data; break;
+               case 0x89: blitter_ram[PATTERNDATA + 7] = data; break;
+               case 0x8A: blitter_ram[SRCDATA + 6] = data; break;
+               case 0x8B: blitter_ram[SRCDATA + 7] = data; break;
+
+               // Z registers 0-3
+               case 0x8C: blitter_ram[SRCZINT + 0] = data; break;
+               case 0x8D: blitter_ram[SRCZINT + 1] = data; break;
+               case 0x8E: blitter_ram[SRCZFRAC + 0] = data; break;
+               case 0x8F: blitter_ram[SRCZFRAC + 1] = data; break;
+
+               case 0x90: blitter_ram[SRCZINT + 2] = data; break;
+               case 0x91: blitter_ram[SRCZINT + 3] = data; break;
+               case 0x92: blitter_ram[SRCZFRAC + 2] = data; break;
+               case 0x93: blitter_ram[SRCZFRAC + 3] = data; break;
+               
+               case 0x94: blitter_ram[SRCZINT + 4] = data; break;
+               case 0x95: blitter_ram[SRCZINT + 5] = data; break;
+               case 0x96: blitter_ram[SRCZFRAC + 4] = data; break;
+               case 0x97: blitter_ram[SRCZFRAC + 5] = data; break;
+               
+               case 0x98: blitter_ram[SRCZINT + 6] = data; break;
+               case 0x99: blitter_ram[SRCZINT + 7] = data; break;
+               case 0x9A: blitter_ram[SRCZFRAC + 6] = data; break;
+               case 0x9B: blitter_ram[SRCZFRAC + 7] = data; break;
                }
        }
 
@@ -1190,21 +1592,98 @@ void BlitterWriteByte(uint32 offset, uint8 data, uint32 who/*=UNKNOWN*/)
 
 void BlitterWriteWord(uint32 offset, uint16 data, uint32 who/*=UNKNOWN*/)
 {
+//#if 1
+/*     if (offset & 0xFF == A1_PIXEL && data == 14368)
+       {
+               WriteLog("\n1\nA1_PIXEL written by %s (%u)...\n\n\n", whoName[who], data);
+extern bool doGPUDis;
+doGPUDis = true;
+       }
+       if ((offset & 0xFF) == (A1_PIXEL + 2) && data == 14368)
+       {
+               WriteLog("\n2\nA1_PIXEL written by %s (%u)...\n\n\n", whoName[who], data);
+extern bool doGPUDis;
+doGPUDis = true;
+       }//*/
+//#endif
+
        BlitterWriteByte(offset+0, (data>>8) & 0xFF, who);
        BlitterWriteByte(offset+1, data & 0xFF, who);
 
        if ((offset & 0xFF) == 0x3A)
        // I.e., the second write of 32-bit value--not convinced this is the best way to do this!
        // But then again, according to the Jaguar docs, this is correct...!
+{
+/*extern int blit_start_log;
+extern bool doGPUDis;
+if (blit_start_log)
+{
+       WriteLog("BLIT: Blitter started by %s...\n", whoName[who]);
+       doGPUDis = true;
+}//*/
                blitter_blit(GET32(blitter_ram, 0x38));
-// Testing purposes only!
-//This does the clipping correctly, but not the Gouraud shading...
-//             blitter2_exec(GET32(blitter_ram, 0x38));
+}
 }
 //F02278,9,A,B
 
 void BlitterWriteLong(uint32 offset, uint32 data, uint32 who/*=UNKNOWN*/)
 {
+//#if 1
+/*     if ((offset & 0xFF) == A1_PIXEL && (data & 0xFFFF) == 14368)
+       {
+               WriteLog("\n3\nA1_PIXEL written by %s (%u)...\n\n\n", whoName[who], data);
+extern bool doGPUDis;
+doGPUDis = true;
+       }//*/
+//#endif
+
        BlitterWriteWord(offset, data >> 16, who);
        BlitterWriteWord(offset+2, data & 0xFFFF, who);
 }
+
+void LogBlit(void)
+{
+       uint32 cmd = GET32(blitter_ram, 0x38);
+
+       WriteLog("Blit!\n");
+       WriteLog("  cmd      = %08X\n", cmd);
+       WriteLog("  a1_base  = %08X\n", a1_addr);
+       WriteLog("  a1_pitch = %d\n", a1_pitch);
+       WriteLog("  a1_psize = %d\n", a1_psize);
+       WriteLog("  a1_width = %d\n", a1_width);
+       WriteLog("  a1_xadd  = %f (phrase=%d)\n", (float)a1_xadd / 65536.0, a1_phrase_mode);
+       WriteLog("  a1_yadd  = %f\n", (float)a1_yadd / 65536.0);
+       WriteLog("  a1_xstep = %f\n", (float)a1_step_x / 65536.0);
+       WriteLog("  a1_ystep = %f\n", (float)a1_step_y / 65536.0);
+       WriteLog("  a1_x     = %f\n", (float)a1_x / 65536.0);
+       WriteLog("  a1_y     = %f\n", (float)a1_y / 65536.0);
+       WriteLog("  a1_zoffs = %i\n",a1_zoffs);
+
+       WriteLog("  a2_base  = %08X\n", a2_addr);
+       WriteLog("  a2_pitch = %d\n", a2_pitch);
+       WriteLog("  a2_psize = %d\n", a2_psize);
+       WriteLog("  a2_width = %d\n", a2_width);
+       WriteLog("  a2_xadd  = %f (phrase=%d)\n", (float)a2_xadd / 65536.0, a2_phrase_mode);
+       WriteLog("  a2_yadd  = %f\n", (float)a2_yadd / 65536.0);
+       WriteLog("  a2_xstep = %f\n", (float)a2_step_x / 65536.0);
+       WriteLog("  a2_ystep = %f\n", (float)a2_step_y / 65536.0);
+       WriteLog("  a2_x     = %f\n", (float)a2_x / 65536.0);
+       WriteLog("  a2_y     = %f\n", (float)a2_y / 65536.0);
+       WriteLog("  a2_mask_x= 0x%.4x\n",a2_mask_x);
+       WriteLog("  a2_mask_y= 0x%.4x\n",a2_mask_y);
+       WriteLog("  a2_zoffs = %i\n",a2_zoffs);
+
+       WriteLog("  count    = %d x %d\n", n_pixels, n_lines);
+
+       WriteLog("  COMMAND  = %08X\n", cmd);
+       WriteLog("  DSTEN    = %s\n", (DSTEN ? "1" : "0"));
+       WriteLog("  SRCEN    = %s\n", (SRCEN ? "1" : "0"));
+       WriteLog("  PATDSEL  = %s\n", (PATDSEL ? "1" : "0"));
+       WriteLog("  COLOR    = %08X\n", REG(PATTERNDATA));
+       WriteLog("  DCOMPEN  = %s\n", (DCOMPEN ? "1" : "0"));
+       WriteLog("  BCOMPEN  = %s\n", (BCOMPEN ? "1" : "0"));
+       WriteLog("  CMPDST   = %s\n", (CMPDST ? "1" : "0"));
+       WriteLog("  GOURZ    = %s\n", (GOURZ ? "1" : "0"));
+       WriteLog("  GOURD    = %s\n", (GOURD ? "1" : "0"));
+       WriteLog("  SRCSHADE = %s\n", (SRCSHADE ? "1" : "0"));
+}