--- uae/src/blitter.c 2018/04/24 16:53:06 1.1.1.7 +++ uae/src/blitter.c 2018/04/24 17:09:17 1.1.1.13 @@ -15,12 +15,11 @@ #include "uae.h" #include "memory.h" #include "custom.h" -#include "readcpu.h" #include "newcpu.h" #include "blitter.h" #include "blit.h" -uae_u16 bltsize, oldvblts; +uae_u16 oldvblts; uae_u16 bltcon0,bltcon1; uae_u32 bltapt,bltbpt,bltcpt,bltdpt; @@ -111,7 +110,7 @@ static void blitter_dofast(void) uae_u32 preva = 0, prevb = 0; uaecptr dstp = 0; - /*if (!blitfill) fprintf(stderr, "minterm %x not present\n",mt); */ + /*if (!blitfill) write_log ("minterm %x not present\n",mt); */ for (j = 0; j < blt_info.vblitsize; j++) { blitfc = !!(bltcon1 & 0x4); for (i = 0; i < blt_info.hblitsize; i++) { @@ -198,7 +197,7 @@ static void blitter_dofast_desc(void) uae_u32 preva = 0, prevb = 0; uaecptr dstp = 0; -/* if (!blitfill) fprintf(stderr, "minterm %x not present\n",mt);*/ +/* if (!blitfill) write_log ("minterm %x not present\n",mt);*/ for (j = 0; j < blt_info.vblitsize; j++) { blitfc = !!(bltcon1 & 0x4); for (i = 0; i < blt_info.hblitsize; i++) { @@ -378,7 +377,7 @@ static void blit_init(void) blineb = (blt_info.bltbdat >> blt_info.blitbshift) | (blt_info.bltbdat << (16-blt_info.blitbshift)); #if 0 if (blineb != 0xFFFF && blineb != 0) - fprintf(stderr, "%x %x %d %x\n", blineb, blt_info.bltbdat, blt_info.blitbshift, bltcon1); + write_log ("%x %x %d %x\n", blineb, blt_info.bltbdat, blt_info.blitbshift, bltcon1); #endif blitsign = bltcon1 & 0x40; blitonedot = 0; @@ -398,7 +397,7 @@ static void blit_init(void) if (blitfill && !blitdesc) { static int warn = 1; if (warn) - write_log ("warning: blitter fill without desc (further messages suppressed)\n"); + write_log ("warning: blitter fill without desc (further messages suppressed)\n"); warn = 0; } } @@ -425,47 +424,74 @@ void blitter_handler(void) { if (!dmaen(DMA_BLITTER)) { eventtab[ev_blitter].active = 1; - eventtab[ev_blitter].oldcycles = cycles; - eventtab[ev_blitter].evtime = 10 + cycles; /* wait a little */ + eventtab[ev_blitter].oldcycles = get_cycles (); + eventtab[ev_blitter].evtime = 10 * CYCLE_UNIT + get_cycles (); /* wait a little */ return; /* gotta come back later. */ } actually_do_blit(); INTREQ(0x8040); eventtab[ev_blitter].active = 0; - regs.spcflags &= ~SPCFLAG_BLTNASTY; + unset_special (SPCFLAG_BLTNASTY); } -void do_blitter(void) +static uae_u8 blit_cycle_diagram_start[][10] = { - long int blit_cycles; - if (!currprefs.immediate_blits) { + { 0, 1, 0 }, /* 0 */ + { 0, 2, 4,0 }, /* 1 */ + { 0, 2, 3,0 }, /* 2 */ + { 2, 3, 3,0, 0,3,4 }, /* 3 */ + { 0, 3, 2,0,0 }, /* 4 */ + { 2, 3, 2,0, 0,2,4 }, /* 5 */ + { 0, 3, 2,3,0 }, /* 6 */ + { 3, 4, 2,3,0, 0,2,3,4 }, /* 7 */ + { 0, 2, 1,0 }, /* 8 */ + { 2, 2, 1,0, 1,4 }, /* 9 */ + { 0, 2, 1,3 }, /* A */ + { 3, 3, 1,3,0, 1,3,4 }, /* B */ + { 2, 3, 1,2, 0,1,2 }, /* C */ + { 3, 3, 1,2,0, 1,2,4 }, /* D */ + { 0, 3, 1,2,3 }, /* E */ + { 4, 4, 1,2,3,0, 1,2,3,4 } /* F */ +}; + +static long int blit_cycles; +static long blit_firstline_cycles; +static long blit_first_cycle; +static int blit_last_cycle; +static uae_u8 *blit_diag; - blit_cycles = 2; +void do_blitter(void) +{ + int ch = (bltcon0 & 0x0f00) >> 8; + blit_diag = blit_cycle_diagram_start[ch]; + blit_firstline_cycles = blit_first_cycle = get_cycles (); + blit_last_cycle = 0; + if (!currprefs.immediate_blits) { if (!blitline) { - if (bltcon0 & 0x400) - blit_cycles++; - if ((bltcon0 & 0x300) == 0x300) - blit_cycles++; + blit_cycles = blit_diag[1]; + blit_firstline_cycles += blit_cycles * blt_info.hblitsize * CYCLE_UNIT; blit_cycles *= blt_info.vblitsize * blt_info.hblitsize; - } + } else + blit_cycles = 20; /* Desert Dream demo freezes if line draw is too fast */ } else blit_cycles = 1; blit_init(); eventtab[ev_blitter].active = 1; - eventtab[ev_blitter].oldcycles = cycles; - eventtab[ev_blitter].evtime = blit_cycles + cycles; + eventtab[ev_blitter].oldcycles = get_cycles (); + eventtab[ev_blitter].evtime = blit_cycles * CYCLE_UNIT + get_cycles (); events_schedule(); - regs.spcflags &= ~SPCFLAG_BLTNASTY; + unset_special (SPCFLAG_BLTNASTY); if (dmaen(DMA_BLITPRI)) - regs.spcflags |= SPCFLAG_BLTNASTY; + set_special (SPCFLAG_BLTNASTY); + } -void maybe_blit(void) +void maybe_blit (int modulo) { static int warned = 0; if (bltstate == BLT_done) @@ -476,8 +502,34 @@ void maybe_blit(void) write_log ("warning: Program does not wait for blitter\n"); } if (!eventtab[ev_blitter].active) - printf("FOO!!?\n"); - actually_do_blit(); - eventtab[ev_blitter].active = 0; - regs.spcflags &= ~SPCFLAG_BLTNASTY; + write_log ("FOO!!?\n"); + + if (modulo && get_cycles() < blit_firstline_cycles) + return; + blitter_handler (); +} + +int blitnasty (void) +{ + int cycles, ccnt; + if (!(regs.spcflags & SPCFLAG_BLTNASTY)) + return 0; + if (bltstate == BLT_done) + return 0; + if (!dmaen(DMA_BLITTER)) + return 0; + cycles = (get_cycles () - blit_first_cycle) / CYCLE_UNIT; + ccnt = 0; + while (blit_last_cycle < cycles) { + int c; + if (blit_last_cycle < blit_diag[0]) + c = blit_diag[blit_last_cycle + 2]; + else + c = blit_diag[((blit_last_cycle - blit_diag[0]) % blit_diag[1]) + 2 + blit_diag[0]]; + blit_last_cycle ++; + if (!c) + return 0; + ccnt++; + } + return ccnt; }