X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fblitter.cpp;h=c767e5b045c4a2f9ac30d32d0a4714d1ccb11630;hb=6c19e4098a43c47f8cd1824902f7335e124b834f;hp=5baf7a551a20d97425079e233317ef40ee16c697;hpb=917eaa35751bf78a57c8592894fe982883c989cc;p=virtualjaguar diff --git a/src/blitter.cpp b/src/blitter.cpp index 5baf7a5..c767e5b 100644 --- a/src/blitter.cpp +++ b/src/blitter.cpp @@ -8,11 +8,17 @@ // to Curt. ;-) Without that excellent documentation which shows *exactly* // what's going on inside the TOM chip, we'd all still be guessing as to how // the wily blitter and other pieces of the Jaguar puzzle actually work. +// Now how about those JERRY ASIC nets gentlemen...? ;-) // -#include "jaguar.h" #include "blitter.h" +#include +#include +#include +#include "jaguar.h" +#include "log.h" + // Various conditional compilation goodies... //#define USE_ORIGINAL_BLITTER @@ -47,39 +53,39 @@ void BlitterMidsummer2(void); // Blitter registers (offsets from F02200) -#define A1_BASE ((UINT32)0x00) -#define A1_FLAGS ((UINT32)0x04) -#define A1_CLIP ((UINT32)0x08) // Height and width values for clipping -#define A1_PIXEL ((UINT32)0x0C) // Integer part of the pixel (Y.i and X.i) -#define A1_STEP ((UINT32)0x10) // Integer part of the step -#define A1_FSTEP ((UINT32)0x14) // Fractional part of the step -#define A1_FPIXEL ((UINT32)0x18) // Fractional part of the pixel (Y.f and X.f) -#define A1_INC ((UINT32)0x1C) // Integer part of the increment -#define A1_FINC ((UINT32)0x20) // Fractional part of the increment -#define A2_BASE ((UINT32)0x24) -#define A2_FLAGS ((UINT32)0x28) -#define A2_MASK ((UINT32)0x2C) // Modulo values for x and y (M.y and M.x) -#define A2_PIXEL ((UINT32)0x30) // Integer part of the pixel (no fractional part for A2) -#define A2_STEP ((UINT32)0x34) // Integer part of the step (no fractional part for A2) -#define COMMAND ((UINT32)0x38) -#define PIXLINECOUNTER ((UINT32)0x3C) // Inner & outer loop values -#define SRCDATA ((UINT32)0x40) -#define DSTDATA ((UINT32)0x48) -#define DSTZ ((UINT32)0x50) -#define SRCZINT ((UINT32)0x58) -#define SRCZFRAC ((UINT32)0x60) -#define PATTERNDATA ((UINT32)0x68) -#define INTENSITYINC ((UINT32)0x70) -#define ZINC ((UINT32)0x74) -#define COLLISIONCTRL ((UINT32)0x78) -#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) +#define A1_BASE ((uint32)0x00) +#define A1_FLAGS ((uint32)0x04) +#define A1_CLIP ((uint32)0x08) // Height and width values for clipping +#define A1_PIXEL ((uint32)0x0C) // Integer part of the pixel (Y.i and X.i) +#define A1_STEP ((uint32)0x10) // Integer part of the step +#define A1_FSTEP ((uint32)0x14) // Fractional part of the step +#define A1_FPIXEL ((uint32)0x18) // Fractional part of the pixel (Y.f and X.f) +#define A1_INC ((uint32)0x1C) // Integer part of the increment +#define A1_FINC ((uint32)0x20) // Fractional part of the increment +#define A2_BASE ((uint32)0x24) +#define A2_FLAGS ((uint32)0x28) +#define A2_MASK ((uint32)0x2C) // Modulo values for x and y (M.y and M.x) +#define A2_PIXEL ((uint32)0x30) // Integer part of the pixel (no fractional part for A2) +#define A2_STEP ((uint32)0x34) // Integer part of the step (no fractional part for A2) +#define COMMAND ((uint32)0x38) +#define PIXLINECOUNTER ((uint32)0x3C) // Inner & outer loop values +#define SRCDATA ((uint32)0x40) +#define DSTDATA ((uint32)0x48) +#define DSTZ ((uint32)0x50) +#define SRCZINT ((uint32)0x58) +#define SRCZFRAC ((uint32)0x60) +#define PATTERNDATA ((uint32)0x68) +#define INTENSITYINC ((uint32)0x70) +#define ZINC ((uint32)0x74) +#define COLLISIONCTRL ((uint32)0x78) +#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 @@ -142,34 +148,34 @@ void BlitterMidsummer2(void); //Put 'em back, once we fix the problem!!! [KO] // 1 bpp pixel read #define PIXEL_SHIFT_1(a) (((~a##_x) >> 16) & 7) -#define PIXEL_OFFSET_1(a) (((((UINT32)a##_y >> 16) * a##_width / 8) + (((UINT32)a##_x >> 19) & ~7)) * (1 + a##_pitch) + (((UINT32)a##_x >> 19) & 7)) +#define PIXEL_OFFSET_1(a) (((((uint32)a##_y >> 16) * a##_width / 8) + (((uint32)a##_x >> 19) & ~7)) * (1 + a##_pitch) + (((uint32)a##_x >> 19) & 7)) #define READ_PIXEL_1(a) ((JaguarReadByte(a##_addr+PIXEL_OFFSET_1(a), BLITTER) >> PIXEL_SHIFT_1(a)) & 0x01) //#define READ_PIXEL_1(a) ((JaguarReadByte(a##_addr+PIXEL_OFFSET_1(a)) >> PIXEL_SHIFT_1(a)) & 0x01) // 2 bpp pixel read #define PIXEL_SHIFT_2(a) (((~a##_x) >> 15) & 6) -#define PIXEL_OFFSET_2(a) (((((UINT32)a##_y >> 16) * a##_width / 4) + (((UINT32)a##_x >> 18) & ~7)) * (1 + a##_pitch) + (((UINT32)a##_x >> 18) & 7)) +#define PIXEL_OFFSET_2(a) (((((uint32)a##_y >> 16) * a##_width / 4) + (((uint32)a##_x >> 18) & ~7)) * (1 + a##_pitch) + (((uint32)a##_x >> 18) & 7)) #define READ_PIXEL_2(a) ((JaguarReadByte(a##_addr+PIXEL_OFFSET_2(a), BLITTER) >> PIXEL_SHIFT_2(a)) & 0x03) //#define READ_PIXEL_2(a) ((JaguarReadByte(a##_addr+PIXEL_OFFSET_2(a)) >> PIXEL_SHIFT_2(a)) & 0x03) // 4 bpp pixel read #define PIXEL_SHIFT_4(a) (((~a##_x) >> 14) & 4) -#define PIXEL_OFFSET_4(a) (((((UINT32)a##_y >> 16) * (a##_width/2)) + (((UINT32)a##_x >> 17) & ~7)) * (1 + a##_pitch) + (((UINT32)a##_x >> 17) & 7)) +#define PIXEL_OFFSET_4(a) (((((uint32)a##_y >> 16) * (a##_width/2)) + (((uint32)a##_x >> 17) & ~7)) * (1 + a##_pitch) + (((uint32)a##_x >> 17) & 7)) #define READ_PIXEL_4(a) ((JaguarReadByte(a##_addr+PIXEL_OFFSET_4(a), BLITTER) >> PIXEL_SHIFT_4(a)) & 0x0f) //#define READ_PIXEL_4(a) ((JaguarReadByte(a##_addr+PIXEL_OFFSET_4(a)) >> PIXEL_SHIFT_4(a)) & 0x0f) // 8 bpp pixel read -#define PIXEL_OFFSET_8(a) (((((UINT32)a##_y >> 16) * a##_width) + (((UINT32)a##_x >> 16) & ~7)) * (1 + a##_pitch) + (((UINT32)a##_x >> 16) & 7)) +#define PIXEL_OFFSET_8(a) (((((uint32)a##_y >> 16) * a##_width) + (((uint32)a##_x >> 16) & ~7)) * (1 + a##_pitch) + (((uint32)a##_x >> 16) & 7)) #define READ_PIXEL_8(a) (JaguarReadByte(a##_addr+PIXEL_OFFSET_8(a), BLITTER)) //#define READ_PIXEL_8(a) (JaguarReadByte(a##_addr+PIXEL_OFFSET_8(a))) // 16 bpp pixel read -#define PIXEL_OFFSET_16(a) (((((UINT32)a##_y >> 16) * a##_width) + (((UINT32)a##_x >> 16) & ~3)) * (1 + a##_pitch) + (((UINT32)a##_x >> 16) & 3)) +#define PIXEL_OFFSET_16(a) (((((uint32)a##_y >> 16) * a##_width) + (((uint32)a##_x >> 16) & ~3)) * (1 + a##_pitch) + (((uint32)a##_x >> 16) & 3)) #define READ_PIXEL_16(a) (JaguarReadWord(a##_addr+(PIXEL_OFFSET_16(a)<<1), BLITTER)) //#define READ_PIXEL_16(a) (JaguarReadWord(a##_addr+(PIXEL_OFFSET_16(a)<<1))) // 32 bpp pixel read -#define PIXEL_OFFSET_32(a) (((((UINT32)a##_y >> 16) * a##_width) + (((UINT32)a##_x >> 16) & ~1)) * (1 + a##_pitch) + (((UINT32)a##_x >> 16) & 1)) +#define PIXEL_OFFSET_32(a) (((((uint32)a##_y >> 16) * a##_width) + (((uint32)a##_x >> 16) & ~1)) * (1 + a##_pitch) + (((uint32)a##_x >> 16) & 1)) #define READ_PIXEL_32(a) (JaguarReadLong(a##_addr+(PIXEL_OFFSET_32(a)<<2), BLITTER)) //#define READ_PIXEL_32(a) (JaguarReadLong(a##_addr+(PIXEL_OFFSET_32(a)<<2))) @@ -198,22 +204,22 @@ void BlitterMidsummer2(void); #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) & 0x04))) >> (((UINT32)a##_x >> 16) & 0x1F)) & 0x0001 : (REG(r) & 0x0001)) +#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) & 0x04))) >> (((UINT32)a##_x >> 15) & 0x3E)) & 0x0003 : (REG(r) & 0x0003)) +#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) & 0x04))) >> (((UINT32)a##_x >> 14) & 0x28)) & 0x000F : (REG(r) & 0x000F)) +#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) & 0x04))) >> (((UINT32)a##_x >> 13) & 0x18)) & 0x00FF : (REG(r) & 0x00FF)) +#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) & 0x04))) >> (((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) & 0x04)) : 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) (\ @@ -705,7 +711,7 @@ Blit! (00098D90 <- 0081DDC0) count: 320 x 287, A1/2_FLAGS: 00004220/00004020 [cm /*if (((REG(A1_FLAGS) >> 3) & 0x07) == 5) { uint32 offset = a1_addr+(PIXEL_OFFSET_32(a1)<<2); -// (((((UINT32)a##_y >> 16) * a##_width) + (((UINT32)a##_x >> 16) & ~1)) * (1 + a##_pitch) + (((UINT32)a##_x >> 16) & 1)) +// (((((uint32)a##_y >> 16) * a##_width) + (((uint32)a##_x >> 16) & ~1)) * (1 + a##_pitch) + (((uint32)a##_x >> 16) & 1)) if ((offset >= 0x1FF020 && offset <= 0x1FF03F) || (offset >= 0x1FF820 && offset <= 0x1FF83F)) WriteLog("32bpp pixel write: A1 Phrase mode --> "); }//*/ @@ -861,7 +867,7 @@ Blit! (00098D90 <- 0081DDC0) count: 320 x 287, A1/2_FLAGS: 00004220/00004020 [cm /*if (logGo) { uint32 offset = a2_addr+(PIXEL_OFFSET_16(a2)<<1); -// (((((UINT32)a##_y >> 16) * a##_width) + (((UINT32)a##_x >> 16) & ~1)) * (1 + a##_pitch) + (((UINT32)a##_x >> 16) & 1)) +// (((((uint32)a##_y >> 16) * a##_width) + (((uint32)a##_x >> 16) & ~1)) * (1 + a##_pitch) + (((uint32)a##_x >> 16) & 1)) WriteLog("[%08X:%04X] ", offset, writedata); }//*/ // write to the destination @@ -958,7 +964,7 @@ Lesse, with pre-add we'd have: */ //NOTE: The way to fix the CD BIOS is to uncomment below and comment the stuff after // the phrase mode mucking around. But it fucks up everything else... -#define SCREWY_CD_DEPENDENT +//#define SCREWY_CD_DEPENDENT #ifdef SCREWY_CD_DEPENDENT a1_x += a1_step_x; a1_y += a1_step_y; @@ -1107,7 +1113,7 @@ void blitter_blit(uint32 cmd) // 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; + uint32 m = (REG(A1_FLAGS) >> 9) & 0x03, e = (REG(A1_FLAGS) >> 11) & 0x0F; a1_width = ((0x04 | m) << e) >> 2;//*/ a2_x = (REG(A2_PIXEL) & 0x0000FFFF) << 16; @@ -1170,7 +1176,7 @@ void blitter_blit(uint32 cmd) // 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); +// 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 @@ -1261,19 +1267,19 @@ WriteLog("BLIT: Asked to use invalid bit combo (XADDINC) for A2...\n"); { gd_c[0] = blitter_ram[PATTERNDATA + 6]; gd_i[0] = ((uint32)blitter_ram[PATTERNDATA + 7] << 16) - | ((uint32)blitter_ram[SRCDATA + 6] << 8) | blitter_ram[SRCDATA + 1]; + | ((uint32)blitter_ram[SRCDATA + 6] << 8) | blitter_ram[SRCDATA + 7]; gd_c[1] = blitter_ram[PATTERNDATA + 4]; gd_i[1] = ((uint32)blitter_ram[PATTERNDATA + 5] << 16) - | ((uint32)blitter_ram[SRCDATA + 4] << 8) | blitter_ram[SRCDATA + 3]; + | ((uint32)blitter_ram[SRCDATA + 4] << 8) | blitter_ram[SRCDATA + 5]; gd_c[2] = blitter_ram[PATTERNDATA + 2]; gd_i[2] = ((uint32)blitter_ram[PATTERNDATA + 3] << 16) - | ((uint32)blitter_ram[SRCDATA + 2] << 8) | blitter_ram[SRCDATA + 5]; + | ((uint32)blitter_ram[SRCDATA + 2] << 8) | blitter_ram[SRCDATA + 3]; gd_c[3] = blitter_ram[PATTERNDATA + 0]; gd_i[3] = ((uint32)blitter_ram[PATTERNDATA + 1] << 16) - | ((uint32)blitter_ram[SRCDATA + 0] << 8) | blitter_ram[SRCDATA + 7]; + | ((uint32)blitter_ram[SRCDATA + 0] << 8) | blitter_ram[SRCDATA + 1]; gouraud_add = REG(INTENSITYINC); @@ -1458,14 +1464,14 @@ if (blit_start_log) 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 a1f = REG(A1_FLAGS), a2f = REG(A2_FLAGS); uint32 p1 = a1f & 0x07, p2 = a2f & 0x07, d1 = (a1f >> 3) & 0x07, d2 = (a2f >> 3) & 0x07, zo1 = (a1f >> 6) & 0x07, zo2 = (a2f >> 6) & 0x07, w1 = (a1f >> 9) & 0x3F, w2 = (a2f >> 9) & 0x3F, ac1 = (a1f >> 16) & 0x1F, ac2 = (a2f >> 16) & 0x1F; - UINT32 iw1 = ((0x04 | (w1 & 0x03)) << ((w1 & 0x3C) >> 2)) >> 2; - UINT32 iw2 = ((0x04 | (w2 & 0x03)) << ((w2 & 0x3C) >> 2)) >> 2; + uint32 iw1 = ((0x04 | (w1 & 0x03)) << ((w1 & 0x3C) >> 2)) >> 2; + uint32 iw2 = ((0x04 | (w2 & 0x03)) << ((w2 & 0x3C) >> 2)) >> 2; WriteLog("Blit! (%08X %s %08X) count: %d x %d, A1/2_FLAGS: %08X/%08X [cmd: %08X]\n", a1_addr, (mode&0x01 ? "->" : "<-"), a2_addr, n_pixels, n_lines, a1f, a2f, cmd); // WriteLog(" CMD -> src: %d, dst: %d, misc: %d, a1ctl: %d, mode: %d, ity: %1X, z-op: %d, op: %1X, ctrl: %02X\n", src, dst, misc, a1ctl, mode, ity, zop, op, ctrl); @@ -1724,13 +1730,13 @@ doGPUDis = true; void LogBlit(void) { - char * opStr[16] = { "LFU_CLEAR", "LFU_NSAND", "LFU_NSAD", "LFU_NOTS", "LFU_SAND", "LFU_NOTD", "LFU_N_SXORD", "LFU_NSORND", + const 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 cmd = GET32(blitter_ram, 0x38); - UINT32 m = (REG(A1_FLAGS) >> 9) & 0x03, e = (REG(A1_FLAGS) >> 11) & 0x0F; - UINT32 a1_width = ((0x04 | m) << e) >> 2; + uint32 m = (REG(A1_FLAGS) >> 9) & 0x03, e = (REG(A1_FLAGS) >> 11) & 0x0F; + uint32 a1_width = ((0x04 | m) << e) >> 2; m = (REG(A2_FLAGS) >> 9) & 0x03, e = (REG(A2_FLAGS) >> 11) & 0x0F; - UINT32 a2_width = ((0x04 | m) << e) >> 2; + uint32 a2_width = ((0x04 | m) << e) >> 2; WriteLog("Blit!\n"); WriteLog(" COMMAND = %08X\n", cmd); @@ -1846,7 +1852,7 @@ uint8 a1_phrase_mode, a2_phrase_mode; a2_addr = REG(A2_BASE) & 0xFFFFFFF8; a1_x = (REG(A1_PIXEL) << 16) | (REG(A1_FPIXEL) & 0xFFFF); a1_y = (REG(A1_PIXEL) & 0xFFFF0000) | (REG(A1_FPIXEL) >> 16); - UINT32 m = (REG(A1_FLAGS) >> 9) & 0x03, e = (REG(A1_FLAGS) >> 11) & 0x0F; + uint32 m = (REG(A1_FLAGS) >> 9) & 0x03, e = (REG(A1_FLAGS) >> 11) & 0x0F; a1_width = ((0x04 | m) << e) >> 2;//*/ a2_x = (REG(A2_PIXEL) & 0x0000FFFF) << 16; a2_y = (REG(A2_PIXEL) & 0xFFFF0000); @@ -2475,10 +2481,10 @@ a1fupdate A1 step fraction is added to A1 pointer fraction goto a1update */ /* -#define A1_PIXEL ((UINT32)0x0C) // Integer part of the pixel (Y.i and X.i) -#define A1_STEP ((UINT32)0x10) // Integer part of the step -#define A1_FSTEP ((UINT32)0x14) // Fractional part of the step -#define A1_FPIXEL ((UINT32)0x18) // Fractional part of the pixel (Y.f and X.f) +#define A1_PIXEL ((uint32)0x0C) // Integer part of the pixel (Y.i and X.i) +#define A1_STEP ((uint32)0x10) // Integer part of the step +#define A1_FSTEP ((uint32)0x14) // Fractional part of the step +#define A1_FPIXEL ((uint32)0x18) // Fractional part of the pixel (Y.f and X.f) */ // This is all kinda murky. All we have are the Midsummer docs to give us any guidance, @@ -2618,58 +2624,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, @@ -2688,11 +2648,12 @@ void ADDBMUX(int16 &addb_x, int16 &addb_y, uint8 addbsel, int16 a1_x, int16 a1_y void DATAMUX(int16 &data_x, int16 &data_y, uint32 gpu_din, int16 addq_x, int16 addq_y, bool addqsel); 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, +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); @@ -2708,13 +2669,10 @@ void BlitterMidsummer2(void) uint32 cmd = GET32(blitter_ram, COMMAND); -// $01800005 has SRCENX, may have to investigate further... -// $00011008 has GOURD & DSTEN. -// $41802F41 has SRCSHADE, CLIPA1 logBlit = false; -/*if ( - cmd != 0x00010200 - && cmd != 0x01800001 +if ( + cmd != 0x00010200 && // PATDSEL + cmd != 0x01800001 // SRCEN LFUFUNC=C && cmd != 0x01800005 //Boot ROM ATARI letters: && cmd != 0x00011008 // DSTEN GOURD PATDSEL @@ -2725,11 +2683,11 @@ logBlit = false; //T2K TEMPEST letters: && cmd != 0x09800741 // SRCEN CLIP_A1 UPDA1 UPDA1F UPDA2 LFUFUNC=C DCOMPEN //Static letters on Cybermorph intro screen: - && cmd != 0x09800609 // DCOMPEN + && cmd != 0x09800609 // SRCEN DSTEN UPDA1 UPDA2 LFUFUNC=C DCOMPEN //Static pic on title screen: && cmd != 0x01800601 // SRCEN UPDA1 UPDA2 LFUFUNC=C //Turning letters on Cybermorph intro screen: - && cmd != 0x09800F41 // SRCEN CLIP_A1 UPDA1 UPDA1F UPDA2 DSTA2 LFUFUNC=C DCOMPEN +// && cmd != 0x09800F41 // SRCEN CLIP_A1 UPDA1 UPDA1F UPDA2 DSTA2 LFUFUNC=C DCOMPEN && cmd != 0x00113078 // DSTEN DSTENZ DSTWRZ CLIP_A1 GOURD GOURZ PATDSEL ZMODE=4 && cmd != 0x09900F39 // SRCEN DSTEN DSTENZ DSTWRZ UPDA1 UPDA1F UPDA2 DSTA2 ZMODE=4 LFUFUNC=C DCOMPEN && cmd != 0x09800209 // SRCEN DSTEN UPDA1 LFUFUNC=C DCOMPEN @@ -2738,11 +2696,70 @@ logBlit = false; && cmd != 0x00010000 // PATDSEL //Hover Strike text: && 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 +//Hover Strike darkening on intro to play (briefing) screen + && cmd != 0x00020208 // DSTEN UPDA1 ADDDSEL +//Trevor McFur stuff: + && cmd != 0x05810601 // SRCEN UPDA1 UPDA2 PATDSEL BCOMPEN + && cmd != 0x01800201 // SRCEN UPDA1 LFUFUNC=C +//T2K: + && cmd != 0x00011000 // GOURD PATDSEL + && cmd != 0x00011040 // CLIP_A1 GOURD PATDSEL +//Checkered flag: + && cmd != 0x01800000 // LFUFUNC=C + && cmd != 0x01800401 // + && cmd != 0x01800040 // + && cmd != 0x00020008 // +// && cmd != 0x09800F41 // SRCEN CLIP_A1 UPDA1 UPDA1F UPDA2 DSTA2 LFUFUNC=C DCOMPEN ) logBlit = true;//*/ +//logBlit = true; +if (blit_start_log == 0) // Wait for the signal... + logBlit = false;//*/ +/* +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 + +Checkered Flag blits in the screw up zone: +Blit! (CMD = 01800001) // SRCEN LFUFUNC=C +Blit! (CMD = 01800000) // LFUFUNC=C +Blit! (CMD = 00010000) // PATDSEL + +Wolfenstein 3D in the fuckup zone: +Blit! (CMD = 01800000) // 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 @@ -2754,7 +2771,7 @@ logBlit = false; dcompen = (DCOMPEN), bkgwren = (BKGWREN), srcshade = (SRCSHADE); uint8 zmode = (cmd & 0x01C0000) >> 18, lfufunc = (cmd & 0x1E00000) >> 21; -//Missing: ZMODE, LFUFUNC, BUSHI +//Missing: BUSHI //Where to find various lines: // clip_a1 -> inner // gourd -> dcontrol, inner, outer, state @@ -2862,6 +2879,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; @@ -2898,12 +2920,72 @@ patdld[1] -> 0 0110 1100 -> $F0226C (hi 32 bits) So... It's reversed! The data organization of the patd register is [low 32][high 32]! !!! FIX !!! [DONE] And fix all the other 64 bit registers [DONE] */ - -if (cmd == 0x1401060C) +/*if (cmd == 0x1401060C) { printf("logBlit = %s, cmd = %08X\n", (logBlit ? "T" : "F"), cmd); fflush(stdout); -} +}*/ +/*logBlit = false; +if ((cmd == 0x00010200) && (GET16(blitter_ram, PIXLINECOUNTER + 2) == 9)) + logBlit = true; + +; Pink altimeter bar + +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 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/132, A2 x/y: 129/0 +;x-coord is 257 in pic, so add 5 +;20 for ship, 33 for #... Let's see if we can find 'em! + +; Black altimeter bar + +Blit! (00110000 <- 000BF010) count: 5 x 29, 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 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/126, A2 x/y: 336/0 + +Here's the pink bar--note that it's phrase mode without dread, so how does this work??? +Not sure, but I *think* that somehow it MUXes the data at the write site in on the left or right side +of the write data when masked in phrase mode. I'll have to do some tracing to see if this is the mechanism +it uses or not... + +Blit! (CMD = 00010200) +Flags: UPDA1 PATDSEL + count = 9 x 11 + a1_base = 00110010, a2_base = 000BD7E0 + a1_x = 0106, a1_y = 0090, a1_frac_x = 0000, a1_frac_y = 8000, a2_x = 025A, a2_y = 0000 + a1_step_x = FFF6, a1_step_y = 0001, a1_stepf_x = 5E00, a1_stepf_y = D100, a2_step_x = FFF7, a2_step_y = 0001 + a1_inc_x = 0001, a1_inc_y = FFFF, a1_incf_x = 0000, a1_incf_y = E000 + a1_win_x = 0000, a1_win_y = 0000, a2_mask_x = 0000, a2_mask_y = 0000 + a2_mask=F a1add=+phr/+0 a2add=+1/+0 + a1_pixsize = 4, a2_pixsize = 4 + srcd=BAC673AC2C92E578 dstd=0000000000000000 patd=74C074C074C074C0 iinc=0002E398 + srcz1=7E127E12000088DA srcz2=DBE06DF000000000 dstz=0000000000000000 zinc=FFFE4840, coll=0 + Phrase mode is ON + [in=T a1f=F a1=F zf=F z=F a2=F iif=F iii=F izf=F izi=F] + Entering INNER state... + Entering DWRITE state... + Dest write address/pix address: 0016A830/0 [dstart=20 dend=40 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=0 daq=F] [7400000074C074C0] (icount=0007, inc=2) + Entering A1_ADD state [a1_x=0106, a1_y=0090, addasel=0, addbsel=0, modx=2, addareg=F, adda_xconst=2, adda_yconst=0]... + Entering DWRITE state... + Dest write address/pix address: 0016A850/0 [dstart=0 dend=40 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=0 daq=F] [74C074C074C074C0] (icount=0003, inc=4) + Entering A1_ADD state [a1_x=0108, a1_y=0090, addasel=0, addbsel=0, modx=2, addareg=F, adda_xconst=2, adda_yconst=0]... + Entering DWRITE state... + Dest write address/pix address: 0016A870/0 [dstart=0 dend=30 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=0 daq=F] [74C074C074C00000] (icount=FFFF, inc=4) + Entering A1_ADD state [a1_x=010C, a1_y=0090, addasel=0, addbsel=0, modx=2, addareg=F, adda_xconst=2, adda_yconst=0]... + Entering IDLE_INNER state... + Leaving INNER state... (ocount=000A) + [in=F a1f=F a1=T zf=F z=F a2=F iif=F iii=F izf=F izi=F] + Entering A1UPDATE state... (272/144 -> 262/145) + [in=T a1f=F a1=F zf=F z=F a2=F iif=F iii=F izf=F izi=F] + Entering INNER state... +*/ + // Bugs in Jaguar I a2addy = a1addy; // A2 channel Y add bit is tied to A1's @@ -2943,6 +3025,7 @@ printf(" Phrase mode is %s\n", (phrase_mode ? "ON" : "off")); fflush(stdout); } #endif +//logBlit = false; // Stopgap vars to simulate various lines @@ -2963,7 +3046,9 @@ fflush(stdout); #endif idlei = true; - return; +//Instead of a return, let's try breaking out of the loop... +break; +// return; } else idlei = false; @@ -3319,7 +3404,7 @@ sshftld = idle_inner; bool dsta_addi = (dwritei && !dstwrz) || dzwritei; bool gensrc = sreadxi || szreadxi || sreadi || szreadi; - bool gendst = dreadi || szreadi || dwritei || dzwritei; + bool gendst = dreadi || dzreadi || dwritei || dzwritei; bool gena2i = (gensrc && !dsta2) || (gendst && dsta2); bool zaddr = szreadx || szread || dzread || dzwrite; @@ -3675,18 +3760,26 @@ fflush(stdout); //ADDRGEN(srcAddr, pixAddr, gena2i, zaddr, // a1_x, a1_y, a1_base, a1_pitch, a1_pixsize, a1_width, a1_zoffset, // a2_x, a2_y, a2_base, a2_pitch, a2_pixsize, a2_width, a2_zoffset); -srcd2 = srcd1; -srcd1 = ((uint64)JaguarReadLong(address, BLITTER) << 32) | (uint64)JaguarReadLong(address + 4, BLITTER); + srcd2 = srcd1; + srcd1 = ((uint64)JaguarReadLong(address + 0, 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) - 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) { @@ -3702,9 +3795,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 } @@ -3727,17 +3830,22 @@ 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) { -printf(" Source read address/pix address: %08X/%1X [%08X%08X]\n", address, pixAddr, +printf(" Source read address/pix address: %08X/%1X [%08X%08X]\n", address, pixAddr, (uint32)(srcd1 >> 32), (uint32)(srcd1 & 0xFFFFFFFF)); fflush(stdout); } @@ -3749,9 +3857,23 @@ fflush(stdout); #ifdef VERBOSE_BLITTER_LOGGING if (logBlit) { -printf(" Entering SZREADX 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 } @@ -3760,7 +3882,7 @@ fflush(stdout); #ifdef VERBOSE_BLITTER_LOGGING if (logBlit) { -printf(" Entering DREAD state...\n"); +printf(" Entering DREAD state..."); fflush(stdout); } #endif @@ -3782,7 +3904,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); } @@ -3800,6 +3922,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) { @@ -3810,13 +3936,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 @@ -3933,17 +4065,19 @@ 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 +//More testing... This is almost certainly wrong, but how else does this work??? +//Seems to kinda work... But still, this doesn't seem to make any sense! +if (phrase_mode && !dsten) + dstd = ((uint64)JaguarReadLong(address, BLITTER) << 32) | (uint64)JaguarReadLong(address + 4, BLITTER); + //Testing only... for now... //This is wrong because the write data is a combination of srcd and dstd--either run -//thru the LFU or in PATDSEL or ADDDSEL mode. +//thru the LFU or in PATDSEL or ADDDSEL mode. [DONE now, thru DATA module] // Precedence is ADDDSEL > PATDSEL > LFU. //Also, doesn't take into account the start & end masks, or the phrase width... //Now it does! @@ -3954,18 +4088,60 @@ 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) +//NOTE: This only works with pixel sizes less than 8BPP... +//DOUBLE NOTE: Still need to do regression testing to ensure that this doesn't break other stuff... !!! CHECK !!! +if (!phrase_mode && srcshift != 0) + srcd = ((srcd2 & 0xFF) << (8 - srcshift)) | ((srcd1 & 0xFF) >> srcshift); + +//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]; + +#if 0//def 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; + +#if 0//def 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 @@ -3985,18 +4161,88 @@ 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 + count = 10 x 12 + a1_base = 00110000, a2_base = 0010B2A8 + a1_x = 004B, a1_y = 00D8, a1_frac_x = 0000, a1_frac_y = 0000, a2_x = 0704, a2_y = 0000 + a1_step_x = FFF3, a1_step_y = 0001, a1_stepf_x = 0000, a1_stepf_y = 0000, a2_step_x = FFFC, a2_step_y = 0000 + a1_inc_x = 0000, a1_inc_y = 0000, a1_incf_x = 0000, a1_incf_y = 0000 + a1_win_x = 0000, a1_win_y = 0000, a2_mask_x = 0000, a2_mask_y = 0000 + a2_mask=F a1add=+phr/+0 a2add=+phr/+0 + a1_pixsize = 4, a2_pixsize = 4 + srcd=0000000000000000 dstd=0000000000000000 patd=0000000000000000 iinc=00000000 + srcz1=0000000000000000 srcz2=0000000000000000 dstz=0000000000000000 zinc=00000000, coll=0 + Phrase mode is ON + [in=T a1f=F a1=F zf=F z=F a2=F iif=F iii=F izf=F izi=F] + Entering INNER state... + Entering SREAD state... Source read address/pix address: 0010C0B0/0 [0000000078047804] + Entering A2_ADD state [a2_x=0704, a2_y=0000, addasel=0, addbsel=1, modx=2, addareg=F, adda_xconst=2, adda_yconst=0]... + Entering DREAD state... + Dest read address/pix address: 00197240/0 [0000000000000028] + Entering DWRITE state... + Dest write address/pix address: 00197240/0 [dstart=30 dend=40 pwidth=8 srcshift=30][daas=0 dabs=0 dam=7 ds=1 daq=F] [0000000000000028] (icount=0009, inc=1) + Entering A1_ADD state [a1_x=004B, a1_y=00D8, addasel=0, addbsel=0, modx=2, addareg=F, adda_xconst=2, adda_yconst=0]... + Entering SREAD state... Source read address/pix address: 0010C0B8/0 [7804780478047804] + Entering A2_ADD state [a2_x=0708, a2_y=0000, addasel=0, addbsel=1, modx=2, addareg=F, adda_xconst=2, adda_yconst=0]... + Entering DREAD state... + Dest read address/pix address: 00197260/0 [0028000000200008] + Entering DWRITE state... + Dest write address/pix address: 00197260/0 [dstart=0 dend=40 pwidth=8 srcshift=30][daas=0 dabs=0 dam=7 ds=1 daq=F] [0028780478047804] (icount=0005, inc=4) + Entering A1_ADD state [a1_x=004C, a1_y=00D8, addasel=0, addbsel=0, modx=2, addareg=F, adda_xconst=2, adda_yconst=0]... + Entering SREAD state... Source read address/pix address: 0010C0C0/0 [0000000000000000] + Entering A2_ADD state [a2_x=070C, a2_y=0000, addasel=0, addbsel=1, modx=2, addareg=F, adda_xconst=2, adda_yconst=0]... + Entering DREAD state... + Dest read address/pix address: 00197280/0 [0008001800180018] + Entering DWRITE state... + Dest write address/pix address: 00197280/0 [dstart=0 dend=40 pwidth=8 srcshift=30][daas=0 dabs=0 dam=7 ds=1 daq=F] [7804780478040018] (icount=0001, inc=4) + Entering A1_ADD state [a1_x=0050, a1_y=00D8, addasel=0, addbsel=0, modx=2, addareg=F, adda_xconst=2, adda_yconst=0]... + Entering SREAD state... Source read address/pix address: 0010C0C8/0 [000078047BFE7BFE] + Entering A2_ADD state [a2_x=0710, a2_y=0000, addasel=0, addbsel=1, modx=2, addareg=F, adda_xconst=2, adda_yconst=0]... + Entering DREAD state... + Dest read address/pix address: 001972A0/0 [0008002000000000] + Entering DWRITE state... + Dest write address/pix address: 001972A0/0 [dstart=0 dend=10 pwidth=8 srcshift=30][daas=0 dabs=0 dam=7 ds=1 daq=F] [0008002000000000] (icount=FFFD, inc=4) + Entering A1_ADD state [a1_x=0054, a1_y=00D8, addasel=0, addbsel=0, modx=2, addareg=F, adda_xconst=2, adda_yconst=0]... + 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; @@ -4020,17 +4266,11 @@ A1_ycomp := MAG_15 (a1ygr, a1yeq, a1ylt, a1_y{0..14}, a1_win_y{0..14}); 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) @@ -4047,36 +4287,129 @@ if (!winhibit) else JaguarWriteByte(address, wdata & 0x000000FF, BLITTER); } +} #ifdef VERBOSE_BLITTER_LOGGING if (logBlit) { - printf(" [%08X%08X]", (uint32)(wdata >> 32), (uint32)(wdata & 0xFFFFFFFF)); + printf(" [%08X%08X]%s", (uint32)(wdata >> 32), (uint32)(wdata & 0xFFFFFFFF), (winhibit ? "[X]" : "")); + 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 } +/* +This is because the address generator was using only 15 bits of the X when it should have +used 16! + +There's a slight problem here: The X pointer isn't wrapping like it should when it hits +the edge of the window... Notice how the X isn't reset at the edge of the window: + +Blit! (CMD = 00010000) +Flags: PATDSEL + count = 160 x 261 + a1_base = 000E8008, a2_base = 0001FA68 + a1_x = 0000, a1_y = 0000, a1_frac_x = 0000, a1_frac_y = 0000, a2_x = 0000, a2_y = 0000 + a1_step_x = 0000, a1_step_y = 0000, a1_stepf_x = 0000, a1_stepf_y = 0000, a2_step_x = 0000, a2_step_y = 0000 + a1_inc_x = 0000, a1_inc_y = 0000, a1_incf_x = 0000, a1_incf_y = 0000 + a1_win_x = 0000, a1_win_y = 0000, a2_mask_x = 0000, a2_mask_y = 0000 + a2_mask=F a1add=+phr/+0 a2add=+phr/+0 + a1_pixsize = 5, a2_pixsize = 5 + srcd=7717771777177717 dstd=0000000000000000 patd=7730773077307730 iinc=00000000 + srcz1=0000000000000000 srcz2=0000000000000000 dstz=0000000000000000 zinc=00000000, coll=0 + Phrase mode is ON + [in=T a1f=F a1=F zf=F z=F a2=F iif=F iii=F izf=F izi=F] + Entering INNER state... + Entering DWRITE state... Dest write address/pix address: 000E8008/0 [7730773077307730] (icount=009E, inc=2) + srcz=0000000000000000][dcomp=AA zcomp=00 dbinh=00] +[srcz=0000000000000000 dstz=0000000000000000 zwdata=0000000000000000 mask=7FFF] + [dstart=0 dend=40 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=0 daq=F] + Entering A1_ADD state [a1_x=0000, a1_y=0000, addasel=0, addbsel=0, modx=1, addareg=F, adda_xconst=1, adda_yconst=0]... + Entering DWRITE state... Dest write address/pix address: 000E8018/0 [7730773077307730] (icount=009C, inc=2) + srcz=0000000000000000][dcomp=AA zcomp=00 dbinh=00] +[srcz=0000000000000000 dstz=0000000000000000 zwdata=0000000000000000 mask=7FFF] + [dstart=0 dend=40 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=0 daq=F] + Entering A1_ADD state [a1_x=0002, a1_y=0000, addasel=0, addbsel=0, modx=1, addareg=F, adda_xconst=1, adda_yconst=0]... + +... + + Entering A1_ADD state [a1_x=009C, a1_y=0000, addasel=0, addbsel=0, modx=1, addareg=F, adda_xconst=1, adda_yconst=0]... + Entering DWRITE state... Dest write address/pix address: 000E84F8/0 [7730773077307730] (icount=0000, inc=2) + srcz=0000000000000000][dcomp=AA zcomp=00 dbinh=00] +[srcz=0000000000000000 dstz=0000000000000000 zwdata=0000000000000000 mask=7FFF] + [dstart=0 dend=40 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=0 daq=F] + Entering A1_ADD state [a1_x=009E, a1_y=0000, addasel=0, addbsel=0, modx=1, addareg=F, adda_xconst=1, adda_yconst=0]... + Entering IDLE_INNER state... + + Leaving INNER state... (ocount=0104) + [in=T a1f=F a1=F zf=F z=F a2=F iif=F iii=F izf=F izi=F] + + Entering INNER state... + Entering DWRITE state... Dest write address/pix address: 000E8508/0 [7730773077307730] (icount=009E, inc=2) + srcz=0000000000000000][dcomp=AA zcomp=00 dbinh=00] +[srcz=0000000000000000 dstz=0000000000000000 zwdata=0000000000000000 mask=7FFF] + [dstart=0 dend=40 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=0 daq=F] + Entering A1_ADD state [a1_x=00A0, a1_y=0000, addasel=0, addbsel=0, modx=1, addareg=F, adda_xconst=1, adda_yconst=0]... + Entering DWRITE state... Dest write address/pix address: 000E8518/0 [7730773077307730] (icount=009C, inc=2) + srcz=0000000000000000][dcomp=AA zcomp=00 dbinh=00] +[srcz=0000000000000000 dstz=0000000000000000 zwdata=0000000000000000 mask=7FFF] + [dstart=0 dend=40 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=0 daq=F] + Entering A1_ADD state [a1_x=00A2, a1_y=0000, addasel=0, addbsel=0, modx=1, addareg=F, adda_xconst=1, adda_yconst=0]... + +*/ + if (a1_add) { #ifdef VERBOSE_BLITTER_LOGGING @@ -4306,122 +4639,86 @@ fflush(stdout); } } +// We never get here! !!! FIX !!! + +#ifdef VERBOSE_BLITTER_LOGGING +if (logBlit) +{ + printf("Done!\na1_x=%04X a1_y=%04X a1_frac_x=%04X a1_frac_y=%04X a2_x=%04X a2_y%04X\n", + GET16(blitter_ram, A1_PIXEL + 2), + GET16(blitter_ram, A1_PIXEL + 0), + GET16(blitter_ram, A1_FPIXEL + 2), + GET16(blitter_ram, A1_FPIXEL + 0), + GET16(blitter_ram, A2_PIXEL + 2), + GET16(blitter_ram, A2_PIXEL + 0)); + fflush(stdout); +} +#endif + // Write values back to registers (in real blitter, these are continuously updated) - SET16(blitter_ram, A1_PIXEL + 0, a1_y); SET16(blitter_ram, A1_PIXEL + 2, a1_x); - SET16(blitter_ram, A1_FPIXEL + 0, a1_frac_y); + SET16(blitter_ram, A1_PIXEL + 0, a1_y); SET16(blitter_ram, A1_FPIXEL + 2, a1_frac_x); - SET16(blitter_ram, A2_PIXEL + 0, a2_y); + SET16(blitter_ram, A1_FPIXEL + 0, a1_frac_y); SET16(blitter_ram, A2_PIXEL + 2, a2_x); -} + SET16(blitter_ram, A2_PIXEL + 0, a2_y); +#ifdef VERBOSE_BLITTER_LOGGING +if (logBlit) +{ + printf("Writeback!\na1_x=%04X a1_y=%04X a1_frac_x=%04X a1_frac_y=%04X a2_x=%04X a2_y%04X\n", + GET16(blitter_ram, A1_PIXEL + 2), + GET16(blitter_ram, A1_PIXEL + 0), + GET16(blitter_ram, A1_FPIXEL + 2), + GET16(blitter_ram, A1_FPIXEL + 0), + GET16(blitter_ram, A2_PIXEL + 2), + GET16(blitter_ram, A2_PIXEL + 0)); + fflush(stdout); +} +#endif +} /* -The latest that doesn't work properly: - -Blit! (CMD = 09800741) -Flags: SRCEN CLIP_A1 UPDA1 UPDA1F UPDA2 LFUFUNC=C DCOMPEN - count = 15 x 18 - a1_base = 00050000, a2_base = 0083F400 - a1_x = 003D, a1_y = 00AD, a1_frac_x = 8000, a1_frac_y = 0000, a2_x = 0027, a2_y = 00A4 - a1_step_x = FFF1, a1_step_y = 0001, a1_stepf_x = 0000, a1_stepf_y = 0000, a2_step_x = FFF1, 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=+inc/+0 a2add=+1/+0 - a1_pixsize = 4, a2_pixsize = 4 - srcd=0000000000000000 dstd=0000000000000000 patd=0000000000000000 iinc=00FFF000 - srcz1=0000000000000000 srcz2=0000000000000000 dstz=0000000000000000 zinc=00000000, col=2 - Phrase mode is off - [in=T a1f=F a1=F zf=F z=F a2=F iif=F iii=F izf=F izi=F] - Entering INNER state... - Entering SREAD state... Source read address/pix address: 00858E4E/0 [0000000000000000] - Entering A2_ADD state [a2_x=0027, a2_y=00A4, addasel=0, addbsel=1, modx=0, addareg=F, adda_xconst=0, adda_yconst=0]... - Entering DWRITE state... - Dest write address/pix address: 0007077A/0 [dstart=0 dend=10 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=1 daq=F] [0000000000000000] (icount=000E, inc=1) - Entering A1_ADD state [a1_x=003D, a1_y=00AD, addasel=3, addbsel=2, modx=0, addareg=T, adda_xconst=7, adda_yconst=0]... - Entering SREAD state... Source read address/pix address: 00858E50/0 [0000000000000000] - Entering A2_ADD state [a2_x=0028, a2_y=00A4, addasel=0, addbsel=1, modx=0, addareg=F, adda_xconst=0, adda_yconst=0]... - Entering DWRITE state... - Dest write address/pix address: 0007077C/0 [dstart=0 dend=10 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=1 daq=F] [0000000000000000] (icount=000D, inc=1) - Entering A1_ADD state [a1_x=003E, a1_y=00AD, addasel=3, addbsel=2, modx=0, addareg=T, adda_xconst=7, adda_yconst=0]... - Entering SREAD state... Source read address/pix address: 00858E52/0 [0000000000000000] - Entering A2_ADD state [a2_x=0029, a2_y=00A4, addasel=0, addbsel=1, modx=0, addareg=F, adda_xconst=0, adda_yconst=0]... - Entering DWRITE state... - Dest write address/pix address: 0007077E/0 [dstart=0 dend=10 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=1 daq=F] [0000000000000000] (icount=000C, inc=1) - Entering A1_ADD state [a1_x=003F, a1_y=00AD, addasel=3, addbsel=2, modx=0, addareg=T, adda_xconst=7, adda_yconst=0]... - Entering SREAD state... Source read address/pix address: 00858E54/0 [000000000000014A] - Entering A2_ADD state [a2_x=002A, a2_y=00A4, addasel=0, addbsel=1, modx=0, addareg=F, adda_xconst=0, adda_yconst=0]... - Entering DWRITE state... - Dest write address/pix address: 00070780/0 [dstart=0 dend=10 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=1 daq=F] [000000000000014A] (icount=000B, inc=1) - Entering A1_ADD state [a1_x=0040, a1_y=00AD, addasel=3, addbsel=2, modx=0, addareg=T, adda_xconst=7, adda_yconst=0]... - Entering SREAD state... Source read address/pix address: 00858E56/0 [000000000000014A] - Entering A2_ADD state [a2_x=002B, a2_y=00A4, addasel=0, addbsel=1, modx=0, addareg=F, adda_xconst=0, adda_yconst=0]... - Entering DWRITE state... - Dest write address/pix address: 00070782/0 [dstart=0 dend=10 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=1 daq=F] [000000000000014A] (icount=000A, inc=1) - Entering A1_ADD state [a1_x=0041, a1_y=00AD, addasel=3, addbsel=2, modx=0, addareg=T, adda_xconst=7, adda_yconst=0]... - Entering SREAD state... Source read address/pix address: 00858E58/0 [000000000000014A] - Entering A2_ADD state [a2_x=002C, a2_y=00A4, addasel=0, addbsel=1, modx=0, addareg=F, adda_xconst=0, adda_yconst=0]... - Entering DWRITE state... - Dest write address/pix address: 00070784/0 [dstart=0 dend=10 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=1 daq=F] [000000000000014A] (icount=0009, inc=1) - Entering A1_ADD state [a1_x=0042, a1_y=00AD, addasel=3, addbsel=2, modx=0, addareg=T, adda_xconst=7, adda_yconst=0]... - Entering SREAD state... Source read address/pix address: 00858E5A/0 [000000000000014A] - Entering A2_ADD state [a2_x=002D, a2_y=00A4, addasel=0, addbsel=1, modx=0, addareg=F, adda_xconst=0, adda_yconst=0]... - Entering DWRITE state... - Dest write address/pix address: 00070786/0 [dstart=0 dend=10 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=1 daq=F] [000000000000014A] (icount=0008, inc=1) - Entering A1_ADD state [a1_x=0043, a1_y=00AD, addasel=3, addbsel=2, modx=0, addareg=T, adda_xconst=7, adda_yconst=0]... - Entering SREAD state... Source read address/pix address: 00858E5C/0 [000000000000014A] - Entering A2_ADD state [a2_x=002E, a2_y=00A4, addasel=0, addbsel=1, modx=0, addareg=F, adda_xconst=0, adda_yconst=0]... - Entering DWRITE state... - Dest write address/pix address: 00070788/0 [dstart=0 dend=10 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=1 daq=F] [000000000000014A] (icount=0007, inc=1) - Entering A1_ADD state [a1_x=0044, a1_y=00AD, addasel=3, addbsel=2, modx=0, addareg=T, adda_xconst=7, adda_yconst=0]... - Entering SREAD state... Source read address/pix address: 00858E5E/0 [000000000000014A] - Entering A2_ADD state [a2_x=002F, a2_y=00A4, addasel=0, addbsel=1, modx=0, addareg=F, adda_xconst=0, adda_yconst=0]... - Entering DWRITE state... - Dest write address/pix address: 0007078A/0 [dstart=0 dend=10 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=1 daq=F] [000000000000014A] (icount=0006, inc=1) - Entering A1_ADD state [a1_x=0045, a1_y=00AD, addasel=3, addbsel=2, modx=0, addareg=T, adda_xconst=7, adda_yconst=0]... - Entering SREAD state... Source read address/pix address: 00858E60/0 [000000000000014A] - Entering A2_ADD state [a2_x=0030, a2_y=00A4, addasel=0, addbsel=1, modx=0, addareg=F, adda_xconst=0, adda_yconst=0]... - Entering DWRITE state... - Dest write address/pix address: 0007078C/0 [dstart=0 dend=10 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=1 daq=F] [000000000000014A] (icount=0005, inc=1) - Entering A1_ADD state [a1_x=0046, a1_y=00AD, addasel=3, addbsel=2, modx=0, addareg=T, adda_xconst=7, adda_yconst=0]... - Entering SREAD state... Source read address/pix address: 00858E62/0 [000000000000014A] - Entering A2_ADD state [a2_x=0031, a2_y=00A4, addasel=0, addbsel=1, modx=0, addareg=F, adda_xconst=0, adda_yconst=0]... - Entering DWRITE state... - Dest write address/pix address: 0007078E/0 [dstart=0 dend=10 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=1 daq=F] [000000000000014A] (icount=0004, inc=1) - Entering A1_ADD state [a1_x=0047, a1_y=00AD, addasel=3, addbsel=2, modx=0, addareg=T, adda_xconst=7, adda_yconst=0]... - Entering SREAD state... Source read address/pix address: 00858E64/0 [000000000000014A] - Entering A2_ADD state [a2_x=0032, a2_y=00A4, addasel=0, addbsel=1, modx=0, addareg=F, adda_xconst=0, adda_yconst=0]... - Entering DWRITE state... - Dest write address/pix address: 00070790/0 [dstart=0 dend=10 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=1 daq=F] [000000000000014A] (icount=0003, inc=1) - Entering A1_ADD state [a1_x=0048, a1_y=00AD, addasel=3, addbsel=2, modx=0, addareg=T, adda_xconst=7, adda_yconst=0]... - Entering SREAD state... Source read address/pix address: 00858E66/0 [0000000000000000] - Entering A2_ADD state [a2_x=0033, a2_y=00A4, addasel=0, addbsel=1, modx=0, addareg=F, adda_xconst=0, adda_yconst=0]... - Entering DWRITE state... - Dest write address/pix address: 00070792/0 [dstart=0 dend=10 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=1 daq=F] [0000000000000000] (icount=0002, inc=1) - Entering A1_ADD state [a1_x=0049, a1_y=00AD, addasel=3, addbsel=2, modx=0, addareg=T, adda_xconst=7, adda_yconst=0]... - Entering SREAD state... Source read address/pix address: 00858E68/0 [0000000000000000] - Entering A2_ADD state [a2_x=0034, a2_y=00A4, addasel=0, addbsel=1, modx=0, addareg=F, adda_xconst=0, adda_yconst=0]... - Entering DWRITE state... - Dest write address/pix address: 00070794/0 [dstart=0 dend=10 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=1 daq=F] [0000000000000000] (icount=0001, inc=1) - Entering A1_ADD state [a1_x=004A, a1_y=00AD, addasel=3, addbsel=2, modx=0, addareg=T, adda_xconst=7, adda_yconst=0]... - Entering SREAD state... Source read address/pix address: 00858E6A/0 [0000000000000000] - Entering A2_ADD state [a2_x=0035, a2_y=00A4, addasel=0, addbsel=1, modx=0, addareg=F, adda_xconst=0, adda_yconst=0]... - Entering DWRITE state... - Dest write address/pix address: 00070796/0 [dstart=0 dend=10 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=1 daq=F] [0000000000000000] (icount=0000, inc=1) - Entering A1_ADD state [a1_x=004B, a1_y=00AD, addasel=3, addbsel=2, modx=0, addareg=T, adda_xconst=7, adda_yconst=0]... - Entering IDLE_INNER state... - Leaving INNER state... (ocount=0011) - [in=F a1f=T a1=F zf=F z=F a2=F iif=F iii=F izf=F izi=F] - Entering A1FUPDATE state... - [in=F a1f=F a1=T zf=F z=F a2=F iif=F iii=F izf=F izi=F] - Entering A1UPDATE state... (76/173 -> 61/174) - [in=F a1f=F a1=F zf=F z=F a2=T iif=F iii=F izf=F izi=F] - Entering A2UPDATE state... (54/164 -> 39/165) - [in=T a1f=F a1=F zf=F z=F a2=F iif=F iii=F izf=F izi=F] - Entering INNER state... + int16 a1_x = (int16)GET16(blitter_ram, A1_PIXEL + 2); + int16 a1_y = (int16)GET16(blitter_ram, A1_PIXEL + 0); + uint16 a1_frac_x = GET16(blitter_ram, A1_FPIXEL + 2); + uint16 a1_frac_y = GET16(blitter_ram, A1_FPIXEL + 0); + int16 a2_x = (int16)GET16(blitter_ram, A2_PIXEL + 2); + int16 a2_y = (int16)GET16(blitter_ram, A2_PIXEL + 0); + +Seems that the ending a1_x should be written between blits, but it doesn't seem to be... + +Blit! (CMD = 01800000) +Flags: LFUFUNC=C + count = 28672 x 1 + a1_base = 00050000, a2_base = 00070000 + a1_x = 0000, a1_y = 0000, a1_frac_x = 49CD, a1_frac_y = 0000, a2_x = 0033, a2_y = 0001 + a1_step_x = 0000, a1_step_y = 0000, a1_stepf_x = 939A, a1_stepf_y = 0000, a2_step_x = 0000, a2_step_y = 0000 + a1_inc_x = 0000, a1_inc_y = 0000, a1_incf_x = 0000, a1_incf_y = 0000 + a1_win_x = 0100, a1_win_y = 0020, a2_mask_x = 0000, a2_mask_y = 0000 + a2_mask=F a1add=+phr/+0 a2add=+phr/+0 + a1_pixsize = 4, a2_pixsize = 3 + srcd=DEDEDEDEDEDEDEDE dstd=0000000000000000 patd=0000000000000000 iinc=00000000 + srcz1=0000000000000000 srcz2=0000000000000000 dstz=0000000000000000 zinc=00000000, coll=0 + Phrase mode is ON + +Blit! (CMD = 01800000) +Flags: LFUFUNC=C + count = 28672 x 1 + a1_base = 00050000, a2_base = 00070000 + a1_x = 0000, a1_y = 0000, a1_frac_x = 49CD, a1_frac_y = 0000, a2_x = 0033, a2_y = 0001 + a1_step_x = 0000, a1_step_y = 0000, a1_stepf_x = 939A, a1_stepf_y = 0000, a2_step_x = 0000, a2_step_y = 0000 + a1_inc_x = 0000, a1_inc_y = 0000, a1_incf_x = 0000, a1_incf_y = 0000 + a1_win_x = 0100, a1_win_y = 0020, a2_mask_x = 0000, a2_mask_y = 0000 + a2_mask=F a1add=+phr/+0 a2add=+phr/+0 + a1_pixsize = 4, a2_pixsize = 3 + srcd=D6D6D6D6D6D6D6D6 dstd=0000000000000000 patd=0000000000000000 iinc=00000000 + srcz1=0000000000000000 srcz2=0000000000000000 dstz=0000000000000000 zinc=00000000, coll=0 + Phrase mode is ON */ + // Various pieces of the blitter puzzle are teased out here... @@ -4456,7 +4753,8 @@ void ADDRGEN(uint32 &address, uint32 &pixa, bool gena2, bool zaddr, uint16 a1_x, uint16 a1_y, uint32 a1_base, uint8 a1_pitch, uint8 a1_pixsize, uint8 a1_width, uint8 a1_zoffset, uint16 a2_x, uint16 a2_y, uint32 a2_base, uint8 a2_pitch, uint8 a2_pixsize, uint8 a2_width, uint8 a2_zoffset) { - uint16 x = (gena2 ? a2_x : a1_x) & 0x7FFF; +// uint16 x = (gena2 ? a2_x : a1_x) & 0x7FFF; + uint16 x = (gena2 ? a2_x : a1_x) & 0xFFFF; // Actually uses all 16 bits to generate address...! uint16 y = (gena2 ? a2_y : a1_y) & 0x0FFF; uint8 width = (gena2 ? a2_width : a1_width); uint8 pixsize = (gena2 ? a2_pixsize : a1_pixsize); @@ -4764,6 +5062,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); @@ -4782,9 +5085,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 ******************* @@ -5140,18 +5453,19 @@ INT32/ gpu_din // GPU data bus :IN); */ -void DATA (uint64 &wdata, uint8 &dcomp, uint8 &zcomp, bool &nowrite, +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 @@ -5230,23 +5544,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 @@ -5270,6 +5627,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]; ////////////////////////////////////////////////////////////////////////////////////// @@ -5333,7 +5693,7 @@ Efine := DECL38E (unused[0], e_fine\[1..7], dend[0..2], e_coarse[0]);*/ { 0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F } }; uint8 dech38[8] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; uint8 dech38el[2][8] = { { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } }; + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }; int en = (dend & 0x3F ? 1 : 0); uint8 e_coarse = decl38e[en][(dend & 0x38) >> 3]; // Actually, this is e_coarse inverted... @@ -5486,6 +5846,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); @@ -5828,4 +6215,9 @@ if (logBlit) ////////////////////////////////////// C++ CODE ////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////// +// !!! TESTING !!! TESTING !!! TESTING !!! TESTING !!! TESTING !!! TESTING !!! TESTING !!! +// !!! TESTING !!! TESTING !!! TESTING !!! TESTING !!! TESTING !!! TESTING !!! TESTING !!! +// !!! TESTING !!! TESTING !!! TESTING !!! TESTING !!! TESTING !!! TESTING !!! TESTING !!! + #endif +