From c634b7bb720c4ce8a685fbcd8eacfaa7b4f807da Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sun, 7 May 2017 15:00:11 +0300 Subject: [PATCH] Blitter B old fix when manually loading B-DAT and B-shift is non-zero. --- blitter.cpp | 69 ++++++++++++++++++---------- genblitter.cpp | 114 ++++++---------------------------------------- include/blitter.h | 2 +- 3 files changed, 61 insertions(+), 124 deletions(-) diff --git a/blitter.cpp b/blitter.cpp index 3b0e5a5a..b4278361 100644 --- a/blitter.cpp +++ b/blitter.cpp @@ -186,6 +186,28 @@ There is at least one demo that does this.. */ +/* Copper pointer to Blitter register copy bug + + 1: -d = D (-D) + 2: -c = C (-C) + 3: - (-CD) + 4: - (-B-) + 5: - (-BD) + 6: - (-BC) + 7: -BcD = C, -BCd = D + 8: - (A-) + 9: - (AD) + A: - (AC) + B: A (ACD) + C: - (AB-) + D: - (ABD-) + E: - (ABC) + F: AxBxCxD = -, aBxCxD = A, + + 1FE,8C,RGA,8C + + */ + // 5 = internal "processing cycle" static const int blit_cycle_diagram_line[] = { @@ -473,7 +495,6 @@ static void blitter_dofast (void) #endif { uae_u32 blitbhold = blt_info.bltbhold; - uae_u32 preva = 0, prevb = 0; uaecptr dstp = 0; int dodst = 0; @@ -481,21 +502,21 @@ static void blitter_dofast (void) blitfc = !!(bltcon1 & 0x4); for (i = 0; i < blt_info.hblitsize; i++) { uae_u32 bltadat, blitahold; - uae_u16 bltbdat; if (bltadatptr) { blt_info.bltadat = bltadat = chipmem_wget_indirect (bltadatptr); bltadatptr += 2; } else bltadat = blt_info.bltadat; bltadat &= blit_masktable[i]; - blitahold = (((uae_u32)preva << 16) | bltadat) >> blt_info.blitashift; - preva = bltadat; + blitahold = (((uae_u32)blt_info.bltaold << 16) | bltadat) >> blt_info.blitashift; + blt_info.bltaold = bltadat; if (bltbdatptr) { - blt_info.bltbdat = bltbdat = chipmem_wget_indirect (bltbdatptr); + uae_u16 bltbdat = chipmem_wget_indirect (bltbdatptr); bltbdatptr += 2; - blitbhold = (((uae_u32)prevb << 16) | bltbdat) >> blt_info.blitbshift; - prevb = bltbdat; + blitbhold = (((uae_u32)blt_info.bltbold << 16) | bltbdat) >> blt_info.blitbshift; + blt_info.bltbold = bltbdat; + blt_info.bltbdat = bltbdat; } if (bltcdatptr) { @@ -572,7 +593,6 @@ static void blitter_dofast_desc (void) #endif { uae_u32 blitbhold = blt_info.bltbhold; - uae_u32 preva = 0, prevb = 0; uaecptr dstp = 0; int dodst = 0; @@ -580,21 +600,21 @@ static void blitter_dofast_desc (void) blitfc = !!(bltcon1 & 0x4); for (i = 0; i < blt_info.hblitsize; i++) { uae_u32 bltadat, blitahold; - uae_u16 bltbdat; if (bltadatptr) { bltadat = blt_info.bltadat = chipmem_wget_indirect (bltadatptr); bltadatptr -= 2; } else bltadat = blt_info.bltadat; bltadat &= blit_masktable[i]; - blitahold = (((uae_u32)bltadat << 16) | preva) >> blt_info.blitdownashift; - preva = bltadat; + blitahold = (((uae_u32)bltadat << 16) | blt_info.bltaold) >> blt_info.blitdownashift; + blt_info.bltaold = bltadat; if (bltbdatptr) { - blt_info.bltbdat = bltbdat = chipmem_wget_indirect (bltbdatptr); + uae_u16 bltbdat = chipmem_wget_indirect (bltbdatptr); bltbdatptr -= 2; - blitbhold = (((uae_u32)bltbdat << 16) | prevb) >> blt_info.blitdownbshift; - prevb = bltbdat; + blitbhold = (((uae_u32)bltbdat << 16) | blt_info.bltbold) >> blt_info.blitdownbshift; + blt_info.bltbold = bltbdat; + blt_info.bltbdat = bltbdat; } if (bltcdatptr) { @@ -914,7 +934,6 @@ void blitter_handler (uae_u32 data) #ifdef CPUEMU_13 -static uae_u32 preva, prevb; STATIC_INLINE uae_u16 blitter_doblit (void) { uae_u32 blitahold; @@ -927,10 +946,10 @@ STATIC_INLINE uae_u16 blitter_doblit (void) if (blitter_hcounter1 == blt_info.hblitsize - 1) bltadat &= blt_info.bltalwm; if (blitdesc) - blitahold = (((uae_u32)bltadat << 16) | preva) >> blt_info.blitdownashift; + blitahold = (((uae_u32)bltadat << 16) | blt_info.bltaold) >> blt_info.blitdownashift; else - blitahold = (((uae_u32)preva << 16) | bltadat) >> blt_info.blitashift; - preva = bltadat; + blitahold = (((uae_u32)blt_info.bltaold << 16) | bltadat) >> blt_info.blitashift; + blt_info.bltaold = bltadat; ddat = blit_func (blitahold, blt_info.bltbhold, blt_info.bltcdat, mt) & 0xFFFF; @@ -1010,10 +1029,10 @@ STATIC_INLINE void blitter_dodma (int ch, int hpos) addr = bltbpt; bltbpt += blit_add; if (blitdesc) - blt_info.bltbhold = (((uae_u32)blt_info.bltbdat << 16) | prevb) >> blt_info.blitdownbshift; + blt_info.bltbhold = (((uae_u32)blt_info.bltbdat << 16) | blt_info.bltbold) >> blt_info.blitdownbshift; else - blt_info.bltbhold = (((uae_u32)prevb << 16) | blt_info.bltbdat) >> blt_info.blitbshift; - prevb = blt_info.bltbdat; + blt_info.bltbhold = (((uae_u32)blt_info.bltbold << 16) | blt_info.bltbdat) >> blt_info.blitbshift; + blt_info.bltbold = blt_info.bltbdat; reg = 0x72; alloc_cycle_blitter (hpos, &bltbpt, 2); break; @@ -1457,8 +1476,6 @@ static bool waitingblits (void) static void blitter_start_init (void) { blt_info.blitzero = 1; - preva = 0; - prevb = 0; blit_frozen = 0; blitline_started = bltcon1 & 1; @@ -1467,6 +1484,12 @@ static void blitter_start_init (void) ddat1use = ddat2use = 0; blit_interrupt = 0; + // A old is always cleared + blt_info.bltaold = 0; + // B old is cleared only if channel is enabled + if (blit_ch & 4) + blt_info.bltbold = 0; + if (blitline) { blinea = blt_info.bltadat; blineb = (blt_info.bltbdat >> blt_info.blitbshift) | (blt_info.bltbdat << (16 - blt_info.blitbshift)); diff --git a/genblitter.cpp b/genblitter.cpp index 5ba6dc63..dcb40d5d 100644 --- a/genblitter.cpp +++ b/genblitter.cpp @@ -51,60 +51,20 @@ static void generate_func(void) printf("{\n"); printf("int i,j;\n"); printf("uae_u32 totald = 0;\n"); -#if 0 - printf("if (currprefs.blits_32bit_enabled && b->hblitsize > 1"); - if (a_is_on) printf(" && !b->blitashift && b->bltafwm==0xffff && b->bltalwm==0xffff"); - if (b_is_on) printf(" && !b->blitbshift"); - printf(") {\n"); - if (a_is_on) printf("uae_u32 srca=((uae_u32)b->bltadat << 16) | b->bltadat;\n"); - if (b_is_on) printf("uae_u32 srcb=((uae_u32)b->bltbdat << 16) | b->bltbdat;\n"); - if (c_is_on) printf("uae_u32 srcc=((uae_u32)b->bltcdat << 16) | b->bltcdat;\n"); - printf("uae_u32 dest;\n"); - printf("int count=b->hblitsize/2, oddword=b->hblitsize&1;\n"); - printf("for (j=0;jvblitsize;j++) {\n"); - printf("\tfor(i=0;ibltamod;\n"); - if (b_is_on) printf("\tif (ptb) ptb += b->bltbmod;\n"); - if (c_is_on) printf("\tif (ptc) ptc += b->bltcmod;\n"); - printf("\tif (ptd) ptd += b->bltdmod;\n"); - printf("}\n"); - if (a_is_on) printf("if (pta) b->bltadat = (*(pta-b->bltamod-2) << 8) | *(pta - b->bltamod - 1);\n"); /* Maybe not necessary, but I don't want problems */ - if (b_is_on) printf("if (ptb) b->bltbdat = (*(ptb-b->bltbmod-2) << 8) | *(ptb - b->bltbmod - 1);\n"); - if (c_is_on) printf("if (ptc) b->bltcdat = (*(ptc-b->bltcmod-2) << 8) | *(ptc - b->bltcmod - 1);\n"); - printf("if (ptd) b->bltddat = (*(ptd-b->bltdmod-2) << 8) | *(ptd - b->bltdmod - 1);\n"); - - printf("} else {\n"); -#endif - if (a_is_on) printf("uae_u32 preva = 0;\n"); - if (b_is_on) printf("uae_u32 prevb = 0, srcb = b->bltbhold;\n"); + if (b_is_on) printf("uae_u32 srcb = b->bltbhold;\n"); if (c_is_on) printf("uae_u32 srcc = b->bltcdat;\n"); printf("uae_u32 dstd=0;\n"); printf("uaecptr dstp = 0;\n"); printf("for (j = 0; j < b->vblitsize; j++) {\n"); printf("\tfor (i = 0; i < b->hblitsize; i++) {\n\t\tuae_u32 bltadat, srca;\n\n"); if (c_is_on) printf("\t\tif (ptc) { srcc = chipmem_wget_indirect (ptc); ptc += 2; }\n"); - if (b_is_on) printf("\t\tif (ptb) {\n\t\t\tuae_u32 bltbdat = blt_info.bltbdat = chipmem_wget_indirect (ptb); ptb += 2;\n"); - if (b_is_on) printf("\t\t\tsrcb = (((uae_u32)prevb << 16) | bltbdat) >> b->blitbshift;\n"); - if (b_is_on) printf("\t\t\tprevb = bltbdat;\n\t\t}\n"); - if (a_is_on) printf("\t\tif (pta) { bltadat = blt_info.bltadat = chipmem_wget_indirect (pta); pta += 2; } else { bltadat = blt_info.bltadat; }\n"); + if (b_is_on) printf("\t\tif (ptb) {\n\t\t\tuae_u32 bltbdat = b->bltbdat = chipmem_wget_indirect (ptb); ptb += 2;\n"); + if (b_is_on) printf("\t\t\tsrcb = (((uae_u32)b->bltbold << 16) | bltbdat) >> b->blitbshift;\n"); + if (b_is_on) printf("\t\t\tb->bltbold = bltbdat;\n\t\t}\n"); + if (a_is_on) printf("\t\tif (pta) { bltadat = b->bltadat = chipmem_wget_indirect (pta); pta += 2; } else { bltadat = b->bltadat; }\n"); if (a_is_on) printf("\t\tbltadat &= blit_masktable[i];\n"); - if (a_is_on) printf("\t\tsrca = (((uae_u32)preva << 16) | bltadat) >> b->blitashift;\n"); - if (a_is_on) printf("\t\tpreva = bltadat;\n"); + if (a_is_on) printf("\t\tsrca = (((uae_u32)b->bltaold << 16) | bltadat) >> b->blitashift;\n"); + if (a_is_on) printf("\t\tb->bltaold = bltadat;\n"); printf("\t\tif (dstp) chipmem_wput_indirect (dstp, dstd);\n"); printf("\t\tdstd = (%s) & 0xFFFF;\n", blitops[blttbl[i]].s); printf("\t\ttotald |= dstd;\n"); @@ -118,9 +78,6 @@ static void generate_func(void) if (b_is_on) printf("b->bltbhold = srcb;\n"); if (c_is_on) printf("b->bltcdat = srcc;\n"); printf("\t\tif (dstp) chipmem_wput_indirect (dstp, dstd);\n"); -#if 0 - printf("}\n"); -#endif printf("if (totald != 0) b->blitzero = 0;\n"); printf("}\n"); @@ -128,60 +85,20 @@ static void generate_func(void) printf("{\n"); printf("uae_u32 totald = 0;\n"); printf("int i,j;\n"); -#if 0 - printf("if (currprefs.blits_32bit_enabled && b->hblitsize > 1"); - if (a_is_on) printf(" && !b->blitashift && b->bltafwm==0xffff && b->bltalwm==0xffff"); - if (b_is_on) printf(" && !b->blitbshift"); - printf(") {\n"); - if (a_is_on) printf("uae_u32 srca = ((uae_u32)b->bltadat << 16) | b->bltadat;\n"); - if (b_is_on) printf("uae_u32 srcb = ((uae_u32)b->bltbdat << 16) | b->bltbdat;\n"); - if (c_is_on) printf("uae_u32 srcc = ((uae_u32)b->bltcdat << 16) | b->bltcdat;\n"); - printf("uae_u32 dest;\n"); - printf("int count=b->hblitsize/2, oddword=b->hblitsize&1;\n"); - printf("for (j=0;jvblitsize;j++) {\n"); - printf("\tfor(i=0;ibltamod;\n"); - if (b_is_on) printf("\tif (ptb) ptb -= b->bltbmod;\n"); - if (c_is_on) printf("\tif (ptc) ptc -= b->bltcmod;\n"); - printf("\tif (ptd) ptd-=b->bltdmod;\n"); - printf("}\n"); - if (a_is_on) printf("if (pta) b->bltadat = (*(pta + b->bltamod + 2) << 8) | *(pta + b->bltamod + 1);\n"); /* Maybe not necessary, but I don't want problems */ - if (b_is_on) printf("if (ptb) b->bltbdat = (*(ptb + b->bltbmod + 2) << 8) | *(ptb + b->bltbmod + 1);\n"); - if (c_is_on) printf("if (ptc) b->bltcdat = (*(ptc + b->bltcmod + 2) << 8) | *(ptc + b->bltcmod + 1);\n"); - printf("if (ptd) b->bltddat = (*(ptd + b->bltdmod + 2) << 8) | *(ptd + b->bltdmod + 1);\n"); - - printf("} else {\n"); -#endif - if (a_is_on) printf("uae_u32 preva = 0;\n"); - if (b_is_on) printf("uae_u32 prevb = 0, srcb = b->bltbhold;\n"); + if (b_is_on) printf("uae_u32 srcb = b->bltbhold;\n"); if (c_is_on) printf("uae_u32 srcc = b->bltcdat;\n"); printf("uae_u32 dstd = 0;\n"); printf("uaecptr dstp = 0;\n"); printf("for (j = 0; j < b->vblitsize; j++) {\n"); printf("\tfor (i = 0; i < b->hblitsize; i++) {\n\t\tuae_u32 bltadat, srca;\n"); if (c_is_on) printf("\t\tif (ptc) { srcc = chipmem_wget_indirect (ptc); ptc -= 2; }\n"); - if (b_is_on) printf("\t\tif (ptb) {\n\t\t\tuae_u32 bltbdat = blt_info.bltbdat = chipmem_wget_indirect (ptb); ptb -= 2;\n"); - if (b_is_on) printf("\t\t\tsrcb = ((bltbdat << 16) | prevb) >> b->blitdownbshift;\n"); - if (b_is_on) printf("\t\t\tprevb = bltbdat;\n\t\t}\n"); - if (a_is_on) printf("\t\tif (pta) { bltadat = blt_info.bltadat = chipmem_wget_indirect (pta); pta -= 2; } else { bltadat = blt_info.bltadat; }\n"); + if (b_is_on) printf("\t\tif (ptb) {\n\t\t\tuae_u32 bltbdat = b->bltbdat = chipmem_wget_indirect (ptb); ptb -= 2;\n"); + if (b_is_on) printf("\t\t\tsrcb = ((bltbdat << 16) | b->bltbold) >> b->blitdownbshift;\n"); + if (b_is_on) printf("\t\t\tb->bltbold = bltbdat;\n\t\t}\n"); + if (a_is_on) printf("\t\tif (pta) { bltadat = b->bltadat = chipmem_wget_indirect (pta); pta -= 2; } else { bltadat = b->bltadat; }\n"); if (a_is_on) printf("\t\tbltadat &= blit_masktable[i];\n"); - if (a_is_on) printf("\t\tsrca = (((uae_u32)bltadat << 16) | preva) >> b->blitdownashift;\n"); - if (a_is_on) printf("\t\tpreva = bltadat;\n"); + if (a_is_on) printf("\t\tsrca = (((uae_u32)bltadat << 16) | b->bltaold) >> b->blitdownashift;\n"); + if (a_is_on) printf("\t\tb->bltaold = bltadat;\n"); printf("\t\tif (dstp) chipmem_wput_indirect (dstp, dstd);\n"); printf("\t\tdstd = (%s) & 0xFFFF;\n", blitops[blttbl[i]].s); printf("\t\ttotald |= dstd;\n"); @@ -195,9 +112,6 @@ static void generate_func(void) if (b_is_on) printf("b->bltbhold = srcb;\n"); if (c_is_on) printf("b->bltcdat = srcc;\n"); printf("\t\tif (dstp) chipmem_wput_indirect (dstp, dstd);\n"); -#if 0 - printf("}\n"); -#endif printf("if (totald != 0) b->blitzero = 0;\n"); printf("}\n"); } diff --git a/include/blitter.h b/include/blitter.h index 7bb74927..4e71b672 100644 --- a/include/blitter.h +++ b/include/blitter.h @@ -15,7 +15,7 @@ struct bltinfo { int blitzero; int blitashift, blitbshift, blitdownashift, blitdownbshift; uae_u16 bltadat, bltbdat, bltcdat, bltddat; - uae_u16 bltahold, bltbhold, bltafwm, bltalwm; + uae_u16 bltaold, bltahold, bltbold, bltbhold, bltafwm, bltalwm; int vblitsize, hblitsize; int bltamod, bltbmod, bltcmod, bltdmod; int got_cycle; -- 2.47.3