--- uae/src/blitter.c 2018/04/24 16:42:15 1.1.1.4 +++ uae/src/blitter.c 2018/04/24 17:18:35 1.1.1.16 @@ -9,36 +9,52 @@ #include "sysconfig.h" #include "sysdeps.h" -#include "config.h" #include "options.h" #include "events.h" #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 bltcon0,bltcon1; -uae_u32 bltapt,bltbpt,bltcpt,bltdpt; +uae_u16 oldvblts; +uae_u16 bltcon0, bltcon1; +uae_u32 bltapt, bltbpt, bltcpt, bltdpt; int blinea_shift; -static uae_u16 blitlpos, blinea, blineb; -static uaecptr bltcnxlpt,bltdnxlpt; -static int blitline,blitfc,blitfill,blitife,blitdesc,blitsing; -static int blitonedot,blitsign; +static uae_u16 blinea, blineb; +static int blitline, blitfc, blitfill, blitife, blitsing, blitdesc; +static int blitonedot, blitsign; static long int bltwait; struct bltinfo blt_info; static uae_u8 blit_filltable[256][4][2]; uae_u32 blit_masktable[BLITTER_MAX_WORDS]; -static uae_u16 blit_trashtable[BLITTER_MAX_WORDS]; enum blitter_states bltstate; -void build_blitfilltable(void) +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; int i; @@ -66,74 +82,68 @@ void build_blitfilltable(void) } } -static __inline__ uae_u8 *blit_xlateptr(uaecptr bltpt, int bytecount) -{ - if (!chipmem_bank.check(bltpt,bytecount)) return NULL; - return chipmem_bank.xlateaddr(bltpt); -} - -static __inline__ uae_u8 *blit_xlateptr_desc(uaecptr bltpt, int bytecount) -{ - if (!chipmem_bank.check(bltpt-bytecount, bytecount)) return NULL; - return chipmem_bank.xlateaddr(bltpt); -} - -static void blitter_dofast(void) +static void blitter_dofast (void) { int i,j; - uae_u8 *bltadatpt = 0, *bltbdatpt = 0, *bltcdatpt = 0, *bltddatpt = 0; + uaecptr bltadatptr = 0, bltbdatptr = 0, bltcdatptr = 0, bltddatptr = 0; uae_u8 mt = bltcon0 & 0xFF; blit_masktable[0] = blt_info.bltafwm; blit_masktable[blt_info.hblitsize - 1] &= blt_info.bltalwm; if (bltcon0 & 0x800) { - bltadatpt = blit_xlateptr(bltapt, (blt_info.hblitsize*2+blt_info.bltamod)*blt_info.vblitsize); - bltapt += (blt_info.hblitsize*2+blt_info.bltamod)*blt_info.vblitsize; + bltadatptr = bltapt; + bltapt += (blt_info.hblitsize*2 + blt_info.bltamod)*blt_info.vblitsize; } if (bltcon0 & 0x400) { - bltbdatpt = blit_xlateptr(bltbpt, (blt_info.hblitsize*2+blt_info.bltbmod)*blt_info.vblitsize); - bltbpt += (blt_info.hblitsize*2+blt_info.bltbmod)*blt_info.vblitsize; + bltbdatptr = bltbpt; + bltbpt += (blt_info.hblitsize*2 + blt_info.bltbmod)*blt_info.vblitsize; } if (bltcon0 & 0x200) { - bltcdatpt = blit_xlateptr(bltcpt, (blt_info.hblitsize*2+blt_info.bltcmod)*blt_info.vblitsize); - bltcpt += (blt_info.hblitsize*2+blt_info.bltcmod)*blt_info.vblitsize; + bltcdatptr = bltcpt; + bltcpt += (blt_info.hblitsize*2 + blt_info.bltcmod)*blt_info.vblitsize; } if (bltcon0 & 0x100) { - bltddatpt = blit_xlateptr(bltdpt, (blt_info.hblitsize*2+blt_info.bltdmod)*blt_info.vblitsize); - bltdpt += (blt_info.hblitsize*2+blt_info.bltdmod)*blt_info.vblitsize; + bltddatptr = bltdpt; + bltdpt += (blt_info.hblitsize*2 + blt_info.bltdmod)*blt_info.vblitsize; } if (blitfunc_dofast[mt] && !blitfill) - (*blitfunc_dofast[mt])(bltadatpt,bltbdatpt,bltcdatpt,bltddatpt,&blt_info); + (*blitfunc_dofast[mt])(bltadatptr, bltbdatptr, bltcdatptr, bltddatptr, &blt_info); else { uae_u32 blitbhold = blt_info.bltbhold; uae_u32 preva = 0, prevb = 0; - uae_u16 foo, *dstp = &foo; + uaecptr dstp = 0; + int dodst = 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++) { uae_u32 bltadat, blitahold; - if (bltadatpt) { - bltadat = do_get_mem_word((uae_u16 *)bltadatpt); bltadatpt += 2; + if (bltadatptr) { + blt_info.bltadat = bltadat = chipmem_agnus_wget (bltadatptr); + bltadatptr += 2; } else bltadat = blt_info.bltadat; bltadat &= blit_masktable[i]; blitahold = (((uae_u32)preva << 16) | bltadat) >> blt_info.blitashift; preva = bltadat; - if (bltbdatpt) { - uae_u16 bltbdat = do_get_mem_word((uae_u16 *)bltbdatpt); bltbdatpt += 2; + if (bltbdatptr) { + uae_u16 bltbdat; + blt_info.bltbdat = bltbdat = chipmem_agnus_wget (bltbdatptr); + bltbdatptr += 2; blitbhold = (((uae_u32)prevb << 16) | bltbdat) >> blt_info.blitbshift; prevb = bltbdat; } - if (bltcdatpt) { - blt_info.bltcdat = do_get_mem_word((uae_u16 *)bltcdatpt); bltcdatpt += 2; + if (bltcdatptr) { + blt_info.bltcdat = chipmem_agnus_wget (bltcdatptr); + bltcdatptr += 2; } - do_put_mem_word(dstp, blt_info.bltddat); - blt_info.bltddat = blit_func(blitahold, blitbhold, blt_info.bltcdat, mt) & 0xFFFF; + if (dodst) + chipmem_agnus_wput (dstp, blt_info.bltddat); + blt_info.bltddat = blit_func (blitahold, blitbhold, blt_info.bltcdat, mt) & 0xFFFF; if (blitfill) { uae_u16 d = blt_info.bltddat; int ifemode = blitife ? 2 : 0; @@ -142,18 +152,21 @@ static void blitter_dofast(void) + (blit_filltable[d >> 8][ifemode + fc1][0] << 8)); blitfc = blit_filltable[d >> 8][ifemode + fc1][1]; } - if (blt_info.bltddat) blt_info.blitzero = 0; - if (bltddatpt) { - dstp = (uae_u16 *)bltddatpt; - bltddatpt += 2; + if (blt_info.bltddat) + blt_info.blitzero = 0; + if (bltddatptr) { + dodst = 1; + dstp = bltddatptr; + bltddatptr += 2; } } - if (bltadatpt) bltadatpt += blt_info.bltamod; - if (bltbdatpt) bltbdatpt += blt_info.bltbmod; - if (bltcdatpt) bltcdatpt += blt_info.bltcmod; - if (bltddatpt) bltddatpt += blt_info.bltdmod; + if (bltadatptr) bltadatptr += blt_info.bltamod; + if (bltbdatptr) bltbdatptr += blt_info.bltbmod; + if (bltcdatptr) bltcdatptr += blt_info.bltcmod; + if (bltddatptr) bltddatptr += blt_info.bltdmod; } - do_put_mem_word(dstp, blt_info.bltddat); + if (dodst) + chipmem_agnus_wput (dstp, blt_info.bltddat); blt_info.bltbhold = blitbhold; } blit_masktable[0] = 0xFFFF; @@ -162,60 +175,66 @@ static void blitter_dofast(void) bltstate = BLT_done; } -static void blitter_dofast_desc(void) +static void blitter_dofast_desc (void) { int i,j; - uae_u8 *bltadatpt = 0, *bltbdatpt = 0, *bltcdatpt = 0, *bltddatpt = 0; + uaecptr bltadatptr = 0, bltbdatptr = 0, bltcdatptr = 0, bltddatptr = 0; uae_u8 mt = bltcon0 & 0xFF; blit_masktable[0] = blt_info.bltafwm; blit_masktable[blt_info.hblitsize - 1] &= blt_info.bltalwm; if (bltcon0 & 0x800) { - bltadatpt = blit_xlateptr_desc(bltapt, (blt_info.hblitsize*2+blt_info.bltamod)*blt_info.vblitsize); - bltapt -= (blt_info.hblitsize*2+blt_info.bltamod)*blt_info.vblitsize; + bltadatptr = bltapt; + bltapt -= (blt_info.hblitsize*2 + blt_info.bltamod)*blt_info.vblitsize; } if (bltcon0 & 0x400) { - bltbdatpt = blit_xlateptr_desc(bltbpt, (blt_info.hblitsize*2+blt_info.bltbmod)*blt_info.vblitsize); - bltbpt -= (blt_info.hblitsize*2+blt_info.bltbmod)*blt_info.vblitsize; + bltbdatptr = bltbpt; + bltbpt -= (blt_info.hblitsize*2 + blt_info.bltbmod)*blt_info.vblitsize; } if (bltcon0 & 0x200) { - bltcdatpt = blit_xlateptr_desc(bltcpt, (blt_info.hblitsize*2+blt_info.bltcmod)*blt_info.vblitsize); - bltcpt -= (blt_info.hblitsize*2+blt_info.bltcmod)*blt_info.vblitsize; + bltcdatptr = bltcpt; + bltcpt -= (blt_info.hblitsize*2 + blt_info.bltcmod)*blt_info.vblitsize; } if (bltcon0 & 0x100) { - bltddatpt = blit_xlateptr_desc(bltdpt, (blt_info.hblitsize*2+blt_info.bltdmod)*blt_info.vblitsize); - bltdpt -= (blt_info.hblitsize*2+blt_info.bltdmod)*blt_info.vblitsize; + bltddatptr = bltdpt; + bltdpt -= (blt_info.hblitsize*2 + blt_info.bltdmod)*blt_info.vblitsize; } if (blitfunc_dofast_desc[mt] && !blitfill) - (*blitfunc_dofast_desc[mt])(bltadatpt,bltbdatpt,bltcdatpt,bltddatpt,&blt_info); + (*blitfunc_dofast_desc[mt])(bltadatptr, bltbdatptr, bltcdatptr, bltddatptr, &blt_info); else { uae_u32 blitbhold = blt_info.bltbhold; uae_u32 preva = 0, prevb = 0; - uae_u16 foo, *dstp = &foo; + uaecptr dstp = 0; + int dodst = 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++) { uae_u32 bltadat, blitahold; - if (bltadatpt) { - bltadat = do_get_mem_word((uae_u16 *)bltadatpt); bltadatpt -= 2; + if (bltadatptr) { + blt_info.bltadat = bltadat = chipmem_agnus_wget (bltadatptr); + bltadatptr -= 2; } else bltadat = blt_info.bltadat; bltadat &= blit_masktable[i]; blitahold = (((uae_u32)bltadat << 16) | preva) >> blt_info.blitdownashift; preva = bltadat; - if (bltbdatpt) { - uae_u16 bltbdat = do_get_mem_word((uae_u16 *)bltbdatpt); bltbdatpt -= 2; + if (bltbdatptr) { + uae_u16 bltbdat; + blt_info.bltbdat = bltbdat = chipmem_agnus_wget (bltbdatptr); + bltbdatptr -= 2; blitbhold = (((uae_u32)bltbdat << 16) | prevb) >> blt_info.blitdownbshift; prevb = bltbdat; } - if (bltcdatpt) { - blt_info.bltcdat = do_get_mem_word((uae_u16 *)bltcdatpt); bltcdatpt -= 2; + if (bltcdatptr) { + blt_info.bltcdat = chipmem_agnus_wget (bltcdatptr); + bltcdatptr -= 2; } - do_put_mem_word(dstp, blt_info.bltddat); - blt_info.bltddat = blit_func(blitahold, blitbhold, blt_info.bltcdat, mt) & 0xFFFF; + if (dodst) + chipmem_agnus_wput (dstp, blt_info.bltddat); + blt_info.bltddat = blit_func (blitahold, blitbhold, blt_info.bltcdat, mt) & 0xFFFF; if (blitfill) { uae_u16 d = blt_info.bltddat; int ifemode = blitife ? 2 : 0; @@ -224,18 +243,21 @@ static void blitter_dofast_desc(void) + (blit_filltable[d >> 8][ifemode + fc1][0] << 8)); blitfc = blit_filltable[d >> 8][ifemode + fc1][1]; } - if (blt_info.bltddat) blt_info.blitzero = 0; - if (bltddatpt) { - dstp = (uae_u16 *)bltddatpt; - bltddatpt -= 2; + if (blt_info.bltddat) + blt_info.blitzero = 0; + if (bltddatptr) { + dodst = 1; + dstp = bltddatptr; + bltddatptr -= 2; } } - if (bltadatpt) bltadatpt -= blt_info.bltamod; - if (bltbdatpt) bltbdatpt -= blt_info.bltbmod; - if (bltcdatpt) bltcdatpt -= blt_info.bltcmod; - if (bltddatpt) bltddatpt -= blt_info.bltdmod; + if (bltadatptr) bltadatptr -= blt_info.bltamod; + if (bltbdatptr) bltbdatptr -= blt_info.bltbmod; + if (bltcdatptr) bltcdatptr -= blt_info.bltcmod; + if (bltddatptr) bltddatptr -= blt_info.bltdmod; } - do_put_mem_word(dstp, blt_info.bltddat); + if (dodst) + chipmem_agnus_wput (dstp, blt_info.bltddat); blt_info.bltbhold = blitbhold; } blit_masktable[0] = 0xFFFF; @@ -244,113 +266,109 @@ static void blitter_dofast_desc(void) bltstate = BLT_done; } -static __inline__ int blitter_read(void) +STATIC_INLINE void blitter_read (void) { - if (bltcon0 & 0xe00){ - if (!dmaen(DMA_BLITTER)) return 1; /* blitter stopped */ - if (bltcon0 & 0x200) blt_info.bltcdat = chipmem_bank.wget(bltcpt); + if (bltcon0 & 0x200) { + if (!dmaen (DMA_BLITTER)) + return; + blt_info.bltcdat = chipmem_bank.wget (bltcpt); } bltstate = BLT_work; - return (bltcon0 & 0xE00) != 0; } -static __inline__ int blitter_write(void) +STATIC_INLINE void blitter_write (void) { - if (blt_info.bltddat) blt_info.blitzero = 0; - if ((bltcon0 & 0x100) || blitline){ - if (!dmaen(DMA_BLITTER)) return 1; - chipmem_bank.wput(bltdpt, blt_info.bltddat); + if (blt_info.bltddat) + blt_info.blitzero = 0; + /* D-channel state has no effect on linedraw, but C must be enabled or nothing is drawn! */ + if (bltcon0 & 0x200) { + if (!dmaen (DMA_BLITTER)) + return; + chipmem_agnus_wput (bltdpt, blt_info.bltddat); } bltstate = BLT_next; - return (bltcon0 & 0x100) != 0; } -static __inline__ void blitter_line_incx(void) +STATIC_INLINE void blitter_line_incx (void) { if (++blinea_shift == 16) { blinea_shift = 0; - bltcnxlpt += 2; - bltdnxlpt += 2; + bltcpt += 2; } } -static __inline__ void blitter_line_decx(void) +STATIC_INLINE void blitter_line_decx (void) { if (blinea_shift-- == 0) { blinea_shift = 15; - bltcnxlpt -= 2; - bltdnxlpt -= 2; + bltcpt -= 2; } } -static __inline__ void blitter_line_decy(void) +STATIC_INLINE void blitter_line_decy (void) { - bltcnxlpt -= blt_info.bltcmod; - bltdnxlpt -= blt_info.bltcmod; /* ??? am I wrong or doesn't KS1.3 set bltdmod? */ + bltcpt -= blt_info.bltcmod; blitonedot = 0; } -static __inline__ void blitter_line_incy(void) +STATIC_INLINE void blitter_line_incy (void) { - bltcnxlpt += blt_info.bltcmod; - bltdnxlpt += blt_info.bltcmod; /* ??? */ + bltcpt += blt_info.bltcmod; blitonedot = 0; } -static void blitter_line(void) +static void blitter_line (void) { - uae_u16 blitahold = blinea >> blinea_shift, blitbhold = blineb & 1 ? 0xFFFF : 0, blitchold = blt_info.bltcdat; - blt_info.bltddat = 0; + uae_u16 blitahold = (blinea & blt_info.bltafwm) >> blinea_shift; + uae_u16 blitbhold = blineb & 1 ? 0xFFFF : 0; + uae_u16 blitchold = blt_info.bltcdat; - if (blitsing && blitonedot) blitahold = 0; + if (blitsing && blitonedot) + blitahold = 0; blitonedot = 1; - blt_info.bltddat = blit_func(blitahold, blitbhold, blitchold, bltcon0 & 0xFF); - if (!blitsign){ - bltapt += (uae_s16)blt_info.bltamod; - if (bltcon1 & 0x10){ + blt_info.bltddat = blit_func (blitahold, blitbhold, blitchold, bltcon0 & 0xFF); + if (!blitsign) { + if (bltcon0 & 0x800) + bltapt += (uae_s16)blt_info.bltamod; + if (bltcon1 & 0x10) { if (bltcon1 & 0x8) - blitter_line_decy(); + blitter_line_decy (); else - blitter_line_incy(); + blitter_line_incy (); } else { if (bltcon1 & 0x8) - blitter_line_decx(); + blitter_line_decx (); else - blitter_line_incx(); + blitter_line_incx (); } } else { - bltapt += (uae_s16)blt_info.bltbmod; + if (bltcon0 & 0x800) + bltapt += (uae_s16)blt_info.bltbmod; } - if (bltcon1 & 0x10){ + if (bltcon1 & 0x10) { if (bltcon1 & 0x4) - blitter_line_decx(); + blitter_line_decx (); else - blitter_line_incx(); + blitter_line_incx (); } else { if (bltcon1 & 0x4) - blitter_line_decy(); + blitter_line_decy (); else - blitter_line_incy(); + blitter_line_incy (); } blitsign = 0 > (uae_s16)bltapt; bltstate = BLT_write; } -static __inline__ void blitter_nxline(void) +STATIC_INLINE void blitter_nxline (void) { - bltcpt = bltcnxlpt; - bltdpt = bltdnxlpt; blineb = (blineb << 1) | (blineb >> 15); - if (--blt_info.vblitsize == 0) { - bltstate = BLT_done; - } else { - bltstate = BLT_read; - } + blt_info.vblitsize--; + bltstate = BLT_read; } -static void blit_init(void) +static void blit_init (void) { - blitlpos = 0; blt_info.blitzero = 1; blitline = bltcon1 & 1; blt_info.blitashift = bltcon0 >> 12; @@ -362,14 +380,12 @@ static void blit_init(void) if (blt_info.hblitsize != 2) write_log ("weird hblitsize in linemode: %d\n", blt_info.hblitsize); - bltcnxlpt = bltcpt; - bltdnxlpt = bltdpt; blitsing = bltcon1 & 0x2; blinea = blt_info.bltadat; 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; @@ -386,72 +402,89 @@ static void blit_init(void) warn = 0; } blitdesc = bltcon1 & 0x2; - if (blitfill && !blitdesc) - write_log ("warning: blitter fill without desc\n"); + if (blitfill && !blitdesc) { + static int warn = 1; + if (warn) + write_log ("warning: blitter fill without desc (further messages suppressed)\n"); + warn = 0; + } } } -static void actually_do_blit(void) +static void actually_do_blit (void) { if (blitline) { do { - blitter_read(); - blitter_line(); - blitter_write(); - blitter_nxline(); + blitter_read (); + blitter_line (); + blitter_write (); + bltdpt = bltcpt; + blitter_nxline (); + if (blt_info.vblitsize == 0) + bltstate = BLT_done; + } 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 (); } -void blitter_handler(void) +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(); + actually_do_blit (); INTREQ(0x8040); eventtab[ev_blitter].active = 0; - regs.spcflags &= ~SPCFLAG_BLTNASTY; + unset_special (SPCFLAG_BLTNASTY); } -void do_blitter(void) -{ - long int blit_cycles; - if (!currprefs.immediate_blits) { +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(); + 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) @@ -462,8 +495,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; }