--- uae/src/blitter.c 2018/04/24 17:05:48 1.1.1.11 +++ uae/src/blitter.c 2018/04/24 17:16:46 1.1.1.15 @@ -9,7 +9,6 @@ #include "sysconfig.h" #include "sysdeps.h" -#include "config.h" #include "options.h" #include "events.h" #include "uae.h" @@ -37,6 +36,26 @@ uae_u32 blit_masktable[BLITTER_MAX_WORDS static uae_u16 blit_trashtable[BLITTER_MAX_WORDS]; enum blitter_states bltstate; +static uae_u8 blit_cycle_diagram_start[][10] = +{ + { 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 */ +}; + void build_blitfilltable(void) { unsigned int d, fillmask; @@ -307,10 +326,13 @@ STATIC_INLINE void blitter_line_incy(voi static void blitter_line(void) { - uae_u16 blitahold = blinea >> blinea_shift, blitbhold = blineb & 1 ? 0xFFFF : 0, blitchold = blt_info.bltcdat; + uae_u16 blitahold = blinea >> blinea_shift; + uae_u16 blitbhold = blineb & 1 ? 0xFFFF : 0; + uae_u16 blitchold = blt_info.bltcdat; blt_info.bltddat = 0; - if (blitsing && blitonedot) blitahold = 0; + if (blitsing && blitonedot) + blitahold = 0; blitonedot = 1; blt_info.bltddat = blit_func(blitahold, blitbhold, blitchold, bltcon0 & 0xFF); if (!blitsign){ @@ -397,7 +419,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; } } @@ -413,9 +435,10 @@ static void actually_do_blit(void) blitter_nxline(); } while (bltstate != BLT_done); } else { - /*blitcount[bltcon0 & 0xff]++; blitter debug */ - if (blitdesc) blitter_dofast_desc(); - else blitter_dofast(); + if (blitdesc) + blitter_dofast_desc(); + else + blitter_dofast(); } blitter_done_notify (); } @@ -435,20 +458,26 @@ void blitter_handler(void) unset_special (SPCFLAG_BLTNASTY); } +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; + void do_blitter(void) { - long int blit_cycles; - if (!currprefs.immediate_blits) { - - blit_cycles = 2; + 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; @@ -462,9 +491,10 @@ void do_blitter(void) unset_special (SPCFLAG_BLTNASTY); if (dmaen(DMA_BLITPRI)) set_special (SPCFLAG_BLTNASTY); + } -void maybe_blit (void) +void maybe_blit (int modulo) { static int warned = 0; if (bltstate == BLT_done) @@ -475,6 +505,34 @@ void maybe_blit (void) write_log ("warning: Program does not wait for blitter\n"); } if (!eventtab[ev_blitter].active) - printf("FOO!!?\n"); + 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; +}