]> Shamusworld >> Repos - virtualjaguar/blobdiff - src/blitter.cpp
Z buffer fixes--still not 100%
[virtualjaguar] / src / blitter.cpp
index 57382cf9747f415a9b0b6cd191dafd9b894d3262..634b67ae4d57fc999e3896ac46d363ebcbc95594 100644 (file)
@@ -2618,58 +2618,12 @@ blitter_done:
 }
 #endif
 
-/*
-Here's a collection of various blits that aren't handled correctly yet...
-
-Spinning cube in Jaguar BIOS opening:
-
-  COMMAND  = 41802F41
-  a1_base  = 0015B000
-  a1_flags = 00033020 (0 0 0 11 . 011000 000 100 . 00)
-             pitch=0, pixSz=4, zOff=0, width=64, xCtrl=3
-  a1_clip  = 64, 64 (00400040)
-  a1_pixel = 0, 65534 (FFFE0000)
-  a1_step  = -64, -1 (FFFFFFC0)
-  a1_fstep = 0, 18161 (46F10000)
-  a1_fpixel= 32768, 42497 (A6018000)
-  a1_inc   = 1, 0 (00000001)
-  a1_finc  = 0, 1926 (07860000)
-  a2_base  = 0014B000
-  a2_flags = 00013820 (0 0 0 01 0 011100 000 100 . 00)
-             pitch=0, pixSz=4, zOff=0, width=128, xCtrl=1
-  a2_mask  = 0, 0 (00000000)
-  a2_pixel = 33, 55 (00370021)
-  a2_step  = -64, 1 (0001FFC0)
-  count    = 64 x 57
-  SRCEN    = 1
-  SRCENZ   = 0
-  SRCENX   = 0
-  DSTEN    = 0
-  DSTENZ   = 0
-  DSTWRZ   = 0
-  CLIPA1   = 1
-  UPDA1F   = 1
-  UPDA1    = 1
-  UPDA2    = 1
-  DSTA2    = 1
-  ZOP      =
---LFUFUNC  = LFU_REPLACE
-| PATDSEL  = 0 (PD=0000000000000000)
---ADDDSEL  = 0
-  CMPDST   = 0
-  BCOMPEN  = 0
-  DCOMPEN  = 0
-  TOPBEN   = 0
-  TOPNEN   = 0
-  BKGWREN  = 0
-  GOURD    = 0 (II=00FCDC80, SD=FF00FF00FF00FF00)
-  GOURZ    = 1 (ZI=00000000, ZD=0000000000000000, SZ1=0000000000000000, SZ2=0000000000000000)
-  SRCSHADE = 1
 
-*/
+//
+// Here's attempt #2--taken from the Oberon chip specs!
+//
 
 #ifdef USE_MIDSUMMER_BLITTER_MKII
-// Here's attempt #2--taken from the Oberon chip specs!
 
 void ADDRGEN(uint32 &, uint32 &, bool, bool,
        uint16, uint16, uint32, uint8, uint8, uint8, uint8,
@@ -2690,9 +2644,10 @@ void ADDRADD(int16 &addq_x, int16 &addq_y, bool a1fracldi,
        uint16 adda_x, uint16 adda_y, uint16 addb_x, uint16 addb_y, uint8 modx, bool suba_x, bool suba_y);
 void DATA(uint64 &wdata, uint8 &dcomp, uint8 &zcomp, bool &nowrite,
        bool big_pix, bool cmpdst, uint8 daddasel, uint8 daddbsel, uint8 daddmode, bool daddq_sel, uint8 data_sel,
-       uint8 dbinh, uint8 dend, uint8 dstart, uint64 dstd, uint32 iinc, uint8 lfu_func, uint64 patd, bool patdadd,
+       uint8 dbinh, uint8 dend, uint8 dstart, uint64 dstd, uint32 iinc, uint8 lfu_func, uint64 &patd, bool patdadd,
        bool phrase_mode, uint64 srcd, bool srcdread, bool srczread, bool srcz2add, uint8 zmode,
-       bool bcompen, bool bkgwren, bool dcompen, uint8 icount, uint8 pixsize);
+       bool bcompen, bool bkgwren, bool dcompen, uint8 icount, uint8 pixsize,
+       uint64 &srcz, uint64 dstz, uint32 zinc);
 void COMP_CTRL(uint8 &dbinh, bool &nowrite,
        bool bcompen, bool big_pix, bool bkgwren, uint8 dcomp, bool dcompen, uint8 icount,
        uint8 pixsize, bool phrase_mode, uint8 srcd, uint8 zcomp);
@@ -2711,7 +2666,7 @@ void BlitterMidsummer2(void)
 // $01800005 has SRCENX, may have to investigate further...
 // $00011008 has GOURD & DSTEN.
 // $41802F41 has SRCSHADE, CLIPA1
-logBlit = false;
+/*logBlit = false;
 if (
        cmd != 0x00010200 &&    // PATDSEL
        cmd != 0x01800001
@@ -2737,27 +2692,54 @@ if (
 //Start of Hover Strike (clearing screen):
        && cmd != 0x00010000    // PATDSEL
 //Hover Strike text:
-       && cmd != 0x1401060C    // SRCENX DSTEN UPDA1 UPDA2 PATDSEL BCOMPEN BKGWREN
+//     && cmd != 0x1401060C    // SRCENX DSTEN UPDA1 UPDA2 PATDSEL BCOMPEN BKGWREN
+//Hover Strike 3D stuff
+       && cmd != 0x01902839    // SRCEN DSTEN DSTENZ DSTWRZ DSTA2 GOURZ ZMODE=4 LFUFUNC=C
 //Trevor McFur stuff:
-//Various text...
-//Or is it? Look at some of these dimensions (phrase mode is OFF):
-//48 x 165, 64 x 265, 192 x 104, 48 x 392, 16 x 56, 32 x 168, 48 x 281, 80 x 448, 192 x 112,
-//96 x 72, 320 x 184, 256 x 200, 224 x 48
        && cmd != 0x05810601    // SRCEN UPDA1 UPDA2 PATDSEL BCOMPEN
        && cmd != 0x01800201    // SRCEN UPDA1 LFUFUNC=C
+//T2K:
+       && cmd != 0x00011000    // GOURD PATDSEL
+       && cmd != 0x00011040    // CLIP_A1 GOURD PATDSEL
        )
        logBlit = true;//*/
+//logBlit = true;
+if (blit_start_log == 0)       // Wait for the signal...
+       logBlit = false;//*/
 /*
-TMcF unique blits:
-logBlit = F, cmd = 00010000 *
-logBlit = F, cmd = 01800601 *
-logBlit = F, cmd = 05810601
-logBlit = F, cmd = 01800201
+Some T2K unique blits:
 logBlit = F, cmd = 00010200 *
+logBlit = F, cmd = 00011000
+logBlit = F, cmd = 00011040
+logBlit = F, cmd = 01800005 *
+logBlit = F, cmd = 09800741 *
+Hover Strike mission selection screen:
+Blit! (CMD = 01902839) // SRCEN DSTEN DSTENZ DSTWRZ DSTA2 GOURZ ZMODE=4 LFUFUNC=C
 */
 
 //printf("logBlit = %s, cmd = %08X\n", (logBlit ? "T" : "F"), cmd);
 //fflush(stdout);
+//logBlit = true;
+
+/*
+Blit! (CMD = 00011040)
+Flags: CLIP_A1 GOURD PATDSEL
+  count = 18 x 1
+  a1_base = 00100000, a2_base = 0081F6A8
+  a1_x = 00A7, a1_y = 0014, a1_frac_x = 0000, a1_frac_y = 0000, a2_x = 0001, a2_y = 0000
+  a1_step_x = FE80, a1_step_y = 0001, a1_stepf_x = 0000, a1_stepf_y = 0000, a2_step_x = FFF8, a2_step_y = 0001
+  a1_inc_x = 0001, a1_inc_y = 0000, a1_incf_x = 0000, a1_incf_y = 0000
+  a1_win_x = 0180, a1_win_y = 0118, a2_mask_x = 0000, a2_mask_y = 0000
+  a2_mask=F a1add=+phr/+0 a2add=+phr/+0
+  a1_pixsize = 4, a2_pixsize = 4
+*/
+//Testing T2K...
+/*logBlit = false;
+if (cmd == 0x00011040
+       && (GET16(blitter_ram, A1_PIXEL + 2) == 0x00A7) && (GET16(blitter_ram, A1_PIXEL + 0) == 0x0014)
+       && (GET16(blitter_ram, A2_PIXEL + 2) == 0x0001) && (GET16(blitter_ram, A2_PIXEL + 0) == 0x0000)
+       && (GET16(blitter_ram, PIXLINECOUNTER + 2) == 18))
+       logBlit = true;*/
 
        // Line states passed in via the command register
 
@@ -2877,6 +2859,11 @@ fflush(stdout);
 
        uint8 pixsize = (dsta2 ? a2_pixsize : a1_pixsize);      // From ACONTROL
 
+//Testing Trevor McFur--I *think* it's the circle on the lower RHS of the screen...
+/*logBlit = false;
+if (cmd == 0x05810601 && (GET16(blitter_ram, PIXLINECOUNTER + 2) == 96)
+       && (GET16(blitter_ram, PIXLINECOUNTER + 0) == 72))
+       logBlit = true;//*/
 //Testing...
 //if (cmd == 0x1401060C) patd = 0xFFFFFFFFFFFFFFFFLL;
 //if (cmd == 0x1401060C) patd = 0x00000000000000FFLL;
@@ -3018,6 +3005,7 @@ printf("  Phrase mode is %s\n", (phrase_mode ? "ON" : "off"));
 fflush(stdout);
 }
 #endif
+//logBlit = false;
 
        // Stopgap vars to simulate various lines
 
@@ -3753,6 +3741,8 @@ fflush(stdout);
 srcd2 = srcd1;
 srcd1 = ((uint64)JaguarReadLong(address, BLITTER) << 32) | (uint64)JaguarReadLong(address + 4, BLITTER);
 //Kludge to take pixel size into account...
+//Hmm. If we're not in phrase mode, this is most likely NOT going to be used...
+//Actually, it would be--because of BCOMPEN expansion, for example...
 if (!phrase_mode)
 {
        if (pixsize == 5)
@@ -3761,7 +3751,7 @@ if (!phrase_mode)
                srcd1 >>= 48;
        else
                srcd1 >>= 56;
-}
+}//*/
 #ifdef VERBOSE_BLITTER_LOGGING
 if (logBlit)
 {
@@ -3777,9 +3767,19 @@ fflush(stdout);
 #ifdef VERBOSE_BLITTER_LOGGING
 if (logBlit)
 {
-printf("  Entering SZREADX state...\n");
+printf("  Entering SZREADX state...");
 fflush(stdout);
 }
+#endif
+                                       srcz2 = srcz1;
+                                       srcz1 = ((uint64)JaguarReadLong(address, BLITTER) << 32) | (uint64)JaguarReadLong(address + 4, BLITTER);
+#ifdef VERBOSE_BLITTER_LOGGING
+if (logBlit)
+{
+       printf(" Src Z extra read address/pix address: %08X/%1X [%08X%08X]\n", address, pixAddr,
+               (uint32)(dstz >> 32), (uint32)(dstz & 0xFFFFFFFF));
+       fflush(stdout);
+}
 #endif
                                }
 
@@ -3802,12 +3802,17 @@ srcd1 = ((uint64)JaguarReadLong(address, BLITTER) << 32) | (uint64)JaguarReadLon
 //Kludge to take pixel size into account...
 if (!phrase_mode)
 {
-       if (pixsize == 5)
-               srcd1 >>= 32;
-       else if (pixsize == 4)
-               srcd1 >>= 48;
-       else
+       if (bcompen)
                srcd1 >>= 56;
+       else
+       {
+               if (pixsize == 5)
+                       srcd1 >>= 32;
+               else if (pixsize == 4)
+                       srcd1 >>= 48;
+               else
+                       srcd1 >>= 56;
+       }
 }
 #ifdef VERBOSE_BLITTER_LOGGING
 if (logBlit)
@@ -3824,9 +3829,23 @@ fflush(stdout);
 #ifdef VERBOSE_BLITTER_LOGGING
 if (logBlit)
 {
-printf("  Entering SZREAD state...\n");
+printf("  Entering SZREAD state...");
 fflush(stdout);
 }
+#endif
+                                       srcz2 = srcz1;
+                                       srcz1 = ((uint64)JaguarReadLong(address, BLITTER) << 32) | (uint64)JaguarReadLong(address + 4, BLITTER);
+//Kludge to take pixel size into account... I believe that it only has to take 16BPP mode into account. Not sure tho.
+if (!phrase_mode && pixsize == 4)
+       srcz1 >>= 48;
+
+#ifdef VERBOSE_BLITTER_LOGGING
+if (logBlit)
+{
+       printf("     Src Z read address/pix address: %08X/%1X [%08X%08X]\n", address, pixAddr,
+               (uint32)(dstz >> 32), (uint32)(dstz & 0xFFFFFFFF));
+       fflush(stdout);
+}
 #endif
                                }
 
@@ -3835,7 +3854,7 @@ fflush(stdout);
 #ifdef VERBOSE_BLITTER_LOGGING
 if (logBlit)
 {
-printf("  Entering DREAD state...\n");
+printf("  Entering DREAD state...");
 fflush(stdout);
 }
 #endif
@@ -3857,7 +3876,7 @@ if (!phrase_mode)
 #ifdef VERBOSE_BLITTER_LOGGING
 if (logBlit)
 {
-printf("      Dest read address/pix address: %08X/%1X [%08X%08X]\n", address, pixAddr,
+printf("       Dest read address/pix address: %08X/%1X [%08X%08X]\n", address, pixAddr,
        (uint32)(dstd >> 32), (uint32)(dstd & 0xFFFFFFFF));
 fflush(stdout);
 }
@@ -3875,6 +3894,10 @@ if (logBlit)
 }
 #endif
                                        dstz = ((uint64)JaguarReadLong(address, BLITTER) << 32) | (uint64)JaguarReadLong(address + 4, BLITTER);
+//Kludge to take pixel size into account... I believe that it only has to take 16BPP mode into account. Not sure tho.
+if (!phrase_mode && pixsize == 4)
+       dstz >>= 48;
+
 #ifdef VERBOSE_BLITTER_LOGGING
 if (logBlit)
 {
@@ -3885,13 +3908,19 @@ if (logBlit)
 #endif
                                }
 
+// These vars should probably go further up in the code... !!! FIX !!!
+// We can't preassign these unless they're static...
+//uint64 srcz = 0;                     // These are assigned to shut up stupid compiler warnings--dwrite is ALWAYS asserted
+//bool winhibit = false;
+uint64 srcz;
+bool winhibit;
 //NOTE: SRCSHADE requires GOURZ to be set to work properly--another Jaguar I bug
                                if (dwrite)
                                {
 #ifdef VERBOSE_BLITTER_LOGGING
 if (logBlit)
 {
-printf("  Entering DWRITE state...\n");
+printf("  Entering DWRITE state...");
 fflush(stdout);
 }
 #endif
@@ -4008,11 +4037,8 @@ uint8 pwidth = (((dend | dstart) & 0x07) == 0 ? 0x08 : (dend - dstart) & 0x07);
 #ifdef VERBOSE_BLITTER_LOGGING
 if (logBlit)
 {
-printf("     Dest write address/pix address: %08X/%1X", address, pixAddr);
-printf(" [dstart=%X dend=%X pwidth=%X srcshift=%X]", dstart, dend, pwidth, srcshift);
-fflush(stdout);
-printf("[daas=%X dabs=%X dam=%X ds=%X daq=%s]", daddasel, daddbsel, daddmode, data_sel, (daddq_sel ? "T" : "F"));
-fflush(stdout);
+       printf("     Dest write address/pix address: %08X/%1X", address, pixAddr);
+       fflush(stdout);
 }
 #endif
 
@@ -4034,18 +4060,55 @@ uint64 srcd = (srcd2 << (64 - srcshift)) | (srcd1 >> srcshift);
 if (srcshift == 0)
        srcd = srcd1;
 
-//Temporary kludge, to see if the fractional pattern does anything...
-//This works, BTW
-if (patfadd)
+//Z DATA() stuff done here... And it has to be done before any Z shifting...
+//Note that we need to have phrase mode start/end support here... (Not since we moved it from dzwrite...!)
+/*
+Here are a couple of Cybermorph blits with Z:
+$00113078      // DSTEN DSTENZ DSTWRZ CLIP_A1 GOURD GOURZ PATDSEL ZMODE=4
+$09900F39      // SRCEN DSTEN DSTENZ DSTWRZ UPDA1 UPDA1F UPDA2 DSTA2 ZMODE=4 LFUFUNC=C DCOMPEN
+
+We're having the same phrase mode overwrite problem we had with the pixels... !!! FIX !!!
+Odd. It's equating 0 with 0... Even though ZMODE is $04 (less than)!
+*/
+if (gourz)
 {
+/*
+void ADDARRAY(uint16 * addq, uint8 daddasel, uint8 daddbsel, uint8 daddmode,
+       uint64 dstd, uint32 iinc, uint8 initcin[], uint64 initinc, uint16 initpix,
+       uint32 istep, uint64 patd, uint64 srcd, uint64 srcz1, uint64 srcz2,
+       uint32 zinc, uint32 zstep)
+*/
        uint16 addq[4];
        uint8 initcin[4] = { 0, 0, 0, 0 };
-       ADDARRAY(addq, 4/*daddasel*/, 4/*daddbsel*/, 0/*daddmode*/, dstd, iinc, initcin, 0, 0, 0, patd, srcd, 0, 0, 0, 0);
-       srcd1 = ((uint64)addq[3] << 48) | ((uint64)addq[2] << 32) | ((uint64)addq[1] << 16) | (uint64)addq[0];
+       ADDARRAY(addq, 7/*daddasel*/, 6/*daddbsel*/, 0/*daddmode*/, 0, 0, initcin, 0, 0, 0, 0, 0, srcz1, srcz2, zinc, 0);
+       srcz2 = ((uint64)addq[3] << 48) | ((uint64)addq[2] << 32) | ((uint64)addq[1] << 16) | (uint64)addq[0];
+       ADDARRAY(addq, 6/*daddasel*/, 7/*daddbsel*/, 1/*daddmode*/, 0, 0, initcin, 0, 0, 0, 0, 0, srcz1, srcz2, zinc, 0);
+       srcz1 = ((uint64)addq[3] << 48) | ((uint64)addq[2] << 32) | ((uint64)addq[1] << 16) | (uint64)addq[0];
+
+#ifdef VERBOSE_BLITTER_LOGGING
+if (logBlit)
+{
+       printf("\n[srcz1=%08X%08X, srcz2=%08X%08X, zinc=%08X",
+               (uint32)(srcz1 >> 32), (uint32)(srcz1 & 0xFFFFFFFF),
+               (uint32)(srcz2 >> 32), (uint32)(srcz2 & 0xFFFFFFFF), zinc);
+       fflush(stdout);
+}
+#endif
 }
 
-//Note that we still don't take atick[0] & [1] into account here, so this will skip half of the data needed... !!! FIX !!!
-//Not yet enumerated: dbinh, srcdread, srczread
+uint8 zSrcShift = srcshift & 0x30;
+srcz = (srcz2 << (64 - zSrcShift)) | (srcz1 >> zSrcShift);
+//bleh, ugly ugly ugly
+if (zSrcShift == 0)
+       srcz = srcz1;
+
+#ifdef VERBOSE_BLITTER_LOGGING
+if (logBlit)
+{
+       printf(" srcz=%08X%08X]\n", (uint32)(srcz >> 32), (uint32)(srcz & 0xFFFFFFFF));
+       fflush(stdout);
+}
+#endif
 
 //When in SRCSHADE mode, it adds the IINC to the read source (from LFU???)
 //According to following line, it gets LFU mode. But does it feed the source into the LFU
@@ -4065,19 +4128,37 @@ if (srcshade)
 //Seems to work... Not 100% sure tho.
 //end try this
 
-bool winhibit;// = false;
+//Temporary kludge, to see if the fractional pattern does anything...
+//This works, BTW
+//But it seems to mess up in Cybermorph... the shading should be smooth but it isn't...
+//Seems the carry out is lost again... !!! FIX !!! [DONE--see below]
+if (patfadd)
+{
+       uint16 addq[4];
+       uint8 initcin[4] = { 0, 0, 0, 0 };
+       ADDARRAY(addq, 4/*daddasel*/, 4/*daddbsel*/, 0/*daddmode*/, dstd, iinc, initcin, 0, 0, 0, patd, srcd, 0, 0, 0, 0);
+       srcd1 = ((uint64)addq[3] << 48) | ((uint64)addq[2] << 32) | ((uint64)addq[1] << 16) | (uint64)addq[0];
+}
+
+//Note that we still don't take atick[0] & [1] into account here, so this will skip half of the data needed... !!! FIX !!!
+//Not yet enumerated: dbinh, srcdread, srczread
+//Also, should do srcshift on the z value in phrase mode... !!! FIX !!! [DONE]
+//As well as add a srcz variable we can set external to this state... !!! FIX !!! [DONE]
+
 uint64 wdata;
 uint8 dcomp, zcomp;
 DATA(wdata, dcomp, zcomp, winhibit,
        true, cmpdst, daddasel, daddbsel, daddmode, daddq_sel, data_sel, 0/*dbinh*/,
        dend, dstart, dstd, iinc, lfufunc, patd, patdadd,
        phrase_mode, srcd, false/*srcdread*/, false/*srczread*/, srcz2add, zmode,
-       bcompen, bkgwren, dcompen, icount & 0x07, pixsize);
-//     bool bcompen, bool bkgwren, bool dcompen, uint8 icount, uint8 pixsize)
+       bcompen, bkgwren, dcompen, icount & 0x07, pixsize,
+       srcz, dstz, zinc);
 /*
 Seems that the phrase mode writes with DCOMPEN and DSTEN are corrupting inside of DATA: !!! FIX !!!
 It's fairly random as well. 7CFE -> 7DFE, 7FCA -> 78CA, 7FA4 -> 78A4, 7F88 -> 8F88
 It could be related to an uninitialized variable, like the zmode bug...
+[DONE]
+It was a bug in the dech38el data--it returned $FF for ungated instead of $00...
 
 Blit! (CMD = 09800609)
 Flags: SRCEN DSTEN UPDA1 UPDA2 LFUFUNC=C DCOMPEN
@@ -4125,8 +4206,10 @@ Flags: SRCEN DSTEN UPDA1 UPDA2 LFUFUNC=C DCOMPEN
   Entering IDLE_INNER state...
 */
 
-if (patdadd)
-       patd = wdata;
+//Why isn't this taken care of in DATA? Because, DATA is modifying its local copy instead of the one used here.
+//!!! FIX !!! [DONE]
+//if (patdadd)
+//     patd = wdata;
 
 //if (patfadd)
 //     srcd1 = wdata;
@@ -4151,17 +4234,10 @@ A1_outside      := OR6 (a1_outside, a1_x{15}, a1xgr, a1xeq, a1_y{15}, a1ygr, a1yeq);
 */
 //NOTE: There seems to be an off-by-one bug here in the clip_a1 section... !!! FIX !!!
 //      Actually, seems to be related to phrase mode writes...
+//      Or is it? Could be related to non-15-bit compares as above?
 if (clip_a1 && ((a1_x & 0x8000) || (a1_y & 0x8000) || (a1_x >= a1_win_x) || (a1_y >= a1_win_y)))
        winhibit = true;
 
-/*if (dcompen)
-{
-//This is currently not correct for phrase mode. !!! FIX !!!
-       if ((pixsize == 3 && (dcomp & 0x01))
-               || (pixsize == 4 && (dcomp & 0x03)))
-               winhibit = true;
-}*/
-
 if (!winhibit)
 {
        if (phrase_mode)
@@ -4178,32 +4254,65 @@ if (!winhibit)
                else
                        JaguarWriteByte(address, wdata & 0x000000FF, BLITTER);
        }
+}
 
 #ifdef VERBOSE_BLITTER_LOGGING
 if (logBlit)
 {
        printf(" [%08X%08X]", (uint32)(wdata >> 32), (uint32)(wdata & 0xFFFFFFFF));
+       printf(" (icount=%04X, inc=%u)\n", icount, (uint16)inc);
+       printf("    [dstart=%X dend=%X pwidth=%X srcshift=%X]", dstart, dend, pwidth, srcshift);
+       printf("[daas=%X dabs=%X dam=%X ds=%X daq=%s]\n", daddasel, daddbsel, daddmode, data_sel, (daddq_sel ? "T" : "F"));
        fflush(stdout);
 }
 #endif
-}
+                               }
 
+                               if (dzwrite)
+                               {
+// OK, here's the big insight: When NOT in GOURZ mode, srcz1 & 2 function EXACTLY the same way that
+// srcd1 & 2 work--there's an implicit shift from srcz1 to srcz2 whenever srcz1 is read.
+// OTHERWISE, srcz1 is the integer for the computed Z and srcz2 is the fractional part.
+// Writes to srcz1 & 2 follow the same pattern as the other 64-bit registers--low 32 at the low address,
+// high 32 at the high address (little endian!).
+// NOTE: GOURZ is still not properly supported. Check patd/patf handling...
+//       Phrase mode start/end masks are not properly supported either...
 #ifdef VERBOSE_BLITTER_LOGGING
 if (logBlit)
 {
-printf(" (icount=%04X, inc=%u)\n", icount, (uint16)inc);
-fflush(stdout);
+       printf("  Entering DZWRITE state...");
+       printf("  Dest Z write address/pix address: %08X/%1X [%08X%08X]\n", address, pixAddr,
+               (uint32)(srcz >> 32), (uint32)(srcz & 0xFFFFFFFF));
+       fflush(stdout);
 }
 #endif
-                               }
-
-                               if (dzwrite)
-                               {
+//This is not correct... !!! FIX !!!
+//Should be OK now... We'll see...
+//Nope. Having the same starstep write problems in phrase mode as we had with pixels... !!! FIX !!!
+//This is not causing the problem in Hover Strike... :-/
+//The problem was with the SREADX not shifting. Still problems with Z comparisons & other text in pregame screen...
+if (!winhibit)
+{
+       if (phrase_mode)
+       {
+               JaguarWriteLong(address + 0, srcz >> 32, BLITTER);
+               JaguarWriteLong(address + 4, srcz & 0xFFFFFFFF, BLITTER);
+       }
+       else
+       {
+               if (pixsize == 4)
+                       JaguarWriteWord(address, srcz & 0x0000FFFF, BLITTER);
+       }
+}//*/
 #ifdef VERBOSE_BLITTER_LOGGING
 if (logBlit)
 {
-printf("  Entering DZWRITE state...\n");
-fflush(stdout);
+//     printf(" [%08X%08X]\n", (uint32)(srcz >> 32), (uint32)(srcz & 0xFFFFFFFF));
+//     fflush(stdout);
+//printf(" [dstart=%X dend=%X pwidth=%X srcshift=%X]", dstart, dend, pwidth, srcshift);
+       printf("    [dstart=? dend=? pwidth=? srcshift=%X]", srcshift);
+       printf("[daas=%X dabs=%X dam=%X ds=%X daq=%s]\n", daddasel, daddbsel, daddmode, data_sel, (daddq_sel ? "T" : "F"));
+       fflush(stdout);
 }
 #endif
                                }
@@ -4895,6 +5004,11 @@ INT16/  b
 */
 void ADD16SAT(uint16 &r, uint8 &co, uint16 a, uint16 b, uint8 cin, bool sat, bool eightbit, bool hicinh)
 {
+/*if (logBlit)
+{
+       printf("--> [sat=%s 8b=%s hicinh=%s] %04X + %04X (+ %u) = ", (sat ? "T" : "F"), (eightbit ? "T" : "F"), (hicinh ? "T" : "F"), a, b, cin);
+       fflush(stdout);
+}*/
        uint8 carry[4];
        uint32 qt = (a & 0xFF) + (b & 0xFF) + cin;
        carry[0] = (qt & 0x0100 ? 1 : 0);
@@ -4913,9 +5027,19 @@ void ADD16SAT(uint16 &r, uint8 &co, uint16 a, uint16 b, uint8 cin, bool sat, boo
 
        bool saturate = sat && (btop ^ ctop);
        bool hisaturate = saturate && !eightbit;
+/*if (logBlit)
+{
+       printf("bt=%u ct=%u s=%u hs=%u] ", btop, ctop, saturate, hisaturate);
+       fflush(stdout);
+}*/
 
        r = (saturate ? (ctop ? 0x00FF : 0x0000) : q & 0x00FF);
        r |= (hisaturate ? (ctop ? 0xFF00 : 0x0000) : q & 0xFF00);
+/*if (logBlit)
+{
+       printf("%04X (co=%u)\n", r, co);
+       fflush(stdout);
+}*/
 }
 
 /**  ADDAMUX - Address adder input A selection  *******************
@@ -5273,16 +5397,17 @@ INT32/  gpu_din                 // GPU data bus
 
 void DATA(uint64 &wdata, uint8 &dcomp, uint8 &zcomp, bool &nowrite,
        bool big_pix, bool cmpdst, uint8 daddasel, uint8 daddbsel, uint8 daddmode, bool daddq_sel, uint8 data_sel,
-       uint8 dbinh, uint8 dend, uint8 dstart, uint64 dstd, uint32 iinc, uint8 lfu_func, uint64 patd, bool patdadd,
+       uint8 dbinh, uint8 dend, uint8 dstart, uint64 dstd, uint32 iinc, uint8 lfu_func, uint64 &patd, bool patdadd,
        bool phrase_mode, uint64 srcd, bool srcdread, bool srczread, bool srcz2add, uint8 zmode,
-       bool bcompen, bool bkgwren, bool dcompen, uint8 icount, uint8 pixsize)
+       bool bcompen, bool bkgwren, bool dcompen, uint8 icount, uint8 pixsize,
+       uint64 &srcz, uint64 dstz, uint32 zinc)
 {
 /*
   Stuff we absolutely *need* to have passed in/out:
 IN:
   patdadd, dstd, srcd, patd, daddasel, daddbsel, daddmode, iinc, srcz1, srcz2, big_pix, phrase_mode, cmpdst
 OUT:
-  changed patd (wdata I guess...)
+  changed patd (wdata I guess...) (Nope. We pass it back directly now...)
 */
 
 // Source data registers
@@ -5361,23 +5486,66 @@ Zstep           := JOIN (zstep, zstep[0..31]);*/
                dcomp |= 0x40;
        if ((cmpd & 0xFF00000000000000LL) == 0)
                dcomp |= 0x80;
+//////////////////////////////////////////////////////////////////////////////////////
+
+// Zed comparator for Z-buffer operations
+
+/*Zedcomp              := ZEDCOMP (zcomp[0..3], srczp[0..1], dstz[0..1], zmode[0..2]);*/
+////////////////////////////////////// C++ CODE //////////////////////////////////////
+//srczp is srcz pipelined, also it goes through a source shift as well...
+/*The shift is basically like so (each piece is 16 bits long):
+
+       0         1         2         3         4          5         6
+       srcz1lolo srcz1lohi srcz1hilo srcz1hihi srcrz2lolo srcz2lohi srcz2hilo
+
+with srcshift bits 4 & 5 selecting the start position
+*/
+//So... basically what we have here is:
+       zcomp = 0;
+
+       if ((((srcz & 0x000000000000FFFFLL) < (dstz & 0x000000000000FFFFLL)) && (zmode & 0x01))
+               || (((srcz & 0x000000000000FFFFLL) == (dstz & 0x000000000000FFFFLL)) && (zmode & 0x02))
+               || (((srcz & 0x000000000000FFFFLL) > (dstz & 0x000000000000FFFFLL)) && (zmode & 0x04)))
+               zcomp |= 0x01;
+
+       if ((((srcz & 0x00000000FFFF0000LL) < (dstz & 0x00000000FFFF0000LL)) && (zmode & 0x01))
+               || (((srcz & 0x00000000FFFF0000LL) == (dstz & 0x00000000FFFF0000LL)) && (zmode & 0x02))
+               || (((srcz & 0x00000000FFFF0000LL) > (dstz & 0x00000000FFFF0000LL)) && (zmode & 0x04)))
+               zcomp |= 0x02;
+
+       if ((((srcz & 0x0000FFFF00000000LL) < (dstz & 0x0000FFFF00000000LL)) && (zmode & 0x01))
+               || (((srcz & 0x0000FFFF00000000LL) == (dstz & 0x0000FFFF00000000LL)) && (zmode & 0x02))
+               || (((srcz & 0x0000FFFF00000000LL) > (dstz & 0x0000FFFF00000000LL)) && (zmode & 0x04)))
+               zcomp |= 0x04;
+
+       if ((((srcz & 0xFFFF000000000000LL) < (dstz & 0xFFFF000000000000LL)) && (zmode & 0x01))
+               || (((srcz & 0xFFFF000000000000LL) == (dstz & 0xFFFF000000000000LL)) && (zmode & 0x02))
+               || (((srcz & 0xFFFF000000000000LL) > (dstz & 0xFFFF000000000000LL)) && (zmode & 0x04)))
+               zcomp |= 0x08;
+
+//TEMP, TO TEST IF ZCOMP IS THE CULPRIT...
+//Nope, this is NOT the problem...
+//zcomp=0;
 // We'll do the comparison/bit/byte inhibits here, since that's they way it happens
 // in the real thing (dcomp goes out to COMP_CTRL and back into DATA through dbinh)...
 #if 1
        uint8 dbinht;
 //     bool nowrite;
        COMP_CTRL(dbinht, nowrite,
-               bcompen, true/*big_pix*/, bkgwren, dcomp, dcompen, icount, pixsize, phrase_mode, srcd & 0xFF, 0);//zcomp);
+               bcompen, true/*big_pix*/, bkgwren, dcomp, dcompen, icount, pixsize, phrase_mode, srcd & 0xFF, zcomp);
        dbinh = dbinht;
 //     dbinh = 0x00;
 #endif
-//////////////////////////////////////////////////////////////////////////////////////
-
-// Zed comparator for Z-buffer operations
-
-/*Zedcomp              := ZEDCOMP (zcomp[0..3], srczp[0..1], dstz[0..1], zmode[0..2]);*/
-////////////////////////////////////// C++ CODE //////////////////////////////////////
 
+#if 1
+#ifdef VERBOSE_BLITTER_LOGGING
+if (logBlit)
+{
+       printf("\n[dcomp=%02X zcomp=%02X dbinh=%02X]\n", dcomp, zcomp, dbinh);
+       fflush(stdout);
+}//*/
+#endif
+#endif
 //////////////////////////////////////////////////////////////////////////////////////
 
 // 22 Mar 94
@@ -5401,6 +5569,9 @@ Zstep             := JOIN (zstep, zstep[0..31]);*/
        ADDARRAY(addq, daddasel, daddbsel, daddmode, dstd, iinc, initcin, 0, 0, 0, patd, srcd, 0, 0, 0, 0);
 
        //This is normally done asynchronously above (thru local_data) when in patdadd mode...
+//And now it's passed back to the caller to be persistent between calls...!
+//But it's causing some serious fuck-ups in T2K now... !!! FIX !!! [DONE--???]
+//Weird! It doesn't anymore...!
        if (patdadd)
                patd = ((uint64)addq[3] << 48) | ((uint64)addq[2] << 32) | ((uint64)addq[1] << 16) | (uint64)addq[0];
 //////////////////////////////////////////////////////////////////////////////////////
@@ -5617,6 +5788,33 @@ Dat[56-63]       := MX4 (dat[56-63], dstdhi{24-31}, ddathi{24-31}, dstzhi{24-31}, srcz
        wdata |= (mask & 0x1000 ? ddat : dstd) & 0x0000FF0000000000LL;
        wdata |= (mask & 0x2000 ? ddat : dstd) & 0x00FF000000000000LL;
        wdata |= (mask & 0x4000 ? ddat : dstd) & 0xFF00000000000000LL;
+/*if (logBlit)
+{
+       printf("\n[ddat=%08X%08X dstd=%08X%08X wdata=%08X%08X mask=%04X]\n",
+               (uint32)(ddat >> 32), (uint32)(ddat & 0xFFFFFFFF),
+               (uint32)(dstd >> 32), (uint32)(dstd & 0xFFFFFFFF),
+               (uint32)(wdata >> 32), (uint32)(wdata & 0xFFFFFFFF), mask);
+       fflush(stdout);
+}//*/
+//This is a crappy way of handling this, but it should work for now...
+       uint64 zwdata;
+       zwdata = ((srcz & mask) | (dstz & ~mask)) & 0x00000000000000FFLL;
+       zwdata |= (mask & 0x0100 ? srcz : dstz) & 0x000000000000FF00LL;
+       zwdata |= (mask & 0x0200 ? srcz : dstz) & 0x0000000000FF0000LL;
+       zwdata |= (mask & 0x0400 ? srcz : dstz) & 0x00000000FF000000LL;
+       zwdata |= (mask & 0x0800 ? srcz : dstz) & 0x000000FF00000000LL;
+       zwdata |= (mask & 0x1000 ? srcz : dstz) & 0x0000FF0000000000LL;
+       zwdata |= (mask & 0x2000 ? srcz : dstz) & 0x00FF000000000000LL;
+       zwdata |= (mask & 0x4000 ? srcz : dstz) & 0xFF00000000000000LL;
+if (logBlit)
+{
+       printf("\n[srcz=%08X%08X dstz=%08X%08X zwdata=%08X%08X mask=%04X]\n",
+               (uint32)(srcz >> 32), (uint32)(srcz & 0xFFFFFFFF),
+               (uint32)(dstz >> 32), (uint32)(dstz & 0xFFFFFFFF),
+               (uint32)(zwdata >> 32), (uint32)(zwdata & 0xFFFFFFFF), mask);
+       fflush(stdout);
+}//*/
+       srcz = zwdata;
 //////////////////////////////////////////////////////////////////////////////////////
 
 /*Data_enab[0-1]       := BUF8 (data_enab[0-1], data_ena);