home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD1.iso / Emulatoren / UAE061.LZH / uae-0.6.1 / blitter.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-28  |  16.1 KB  |  551 lines

  1.  /*
  2.   * UAE - The Un*x Amiga Emulator
  3.   * 
  4.   * Custom chip emulation
  5.   * 
  6.   * (c) 1995 Bernd Schmidt, Alessandro Bissacco
  7.   */
  8.  
  9. #include "sysconfig.h"
  10. #include "sysdeps.h"
  11.  
  12. #include "config.h"
  13. #include "options.h"
  14. #include "events.h"
  15. #include "memory.h"
  16. #include "custom.h"
  17. #include "blitter.h"
  18. #include "blit.h"
  19. #undef FAST_BLITTER
  20. UWORD bltsize, oldvblts;
  21. UWORD bltcon0,bltcon1;
  22. ULONG bltapt,bltbpt,bltcpt,bltdpt;
  23. #define FAST_BLITTER 1
  24. static UWORD blitlpos,blinea,blineb;
  25. static CPTR bltcnxlpt,bltdnxlpt;
  26. static int blitline,blitfc,blitfill,blitife,blitdesc,blitsing;
  27. static int blitonedot,blitsign;
  28. static long int bltwait;
  29.  
  30. struct bltinfo blt_info;
  31.  
  32. static UBYTE blit_filltable[256][4][2];
  33.  
  34. enum blitter_states bltstate;
  35.  
  36. void build_blitfilltable(void)
  37. {
  38.     unsigned int d, fillmask;
  39.     int i;
  40.     for (d = 0; d < 256; d++) {
  41.     for (i = 0; i < 4; i++) {
  42.         int fc = i & 1;
  43.         UBYTE data = d;
  44.         for (fillmask = 1; fillmask != 0x100; fillmask <<= 1) {
  45.         UWORD tmp = data;
  46.         if (fc) {
  47.             if (i & 2)
  48.             data |= fillmask;
  49.             else
  50.             data ^= fillmask;
  51.         }
  52.         if (tmp & fillmask) fc = !fc;
  53.         }
  54.         blit_filltable[d][i][0] = data;
  55.         blit_filltable[d][i][1] = fc;
  56.     }
  57.     }
  58. }
  59.  
  60. static __inline__ UWORD *blit_xlateptr(CPTR bltpt, int bytecount)
  61. {
  62.     if (!chipmem_bank.check(bltpt,bytecount)) return NULL;
  63.     return chipmem_bank.xlateaddr(bltpt);
  64. }
  65.  
  66. static __inline__ UWORD *blit_xlateptr_desc(CPTR bltpt, int bytecount)
  67. {
  68.     if (!chipmem_bank.check(bltpt-bytecount, bytecount)) return NULL;
  69.     return chipmem_bank.xlateaddr(bltpt);
  70. }
  71.  
  72. static void blitter_dofast(void) 
  73. {
  74.     int i,j;
  75.     UWORD *bltadatpt = 0, *bltbdatpt = 0, *bltcdatpt = 0, *bltddatpt = 0;
  76.     UWORD blitahold, blitbhold, bltaold;
  77.     UBYTE mt = bltcon0 & 0xFF;
  78.     
  79.     if (bltcon0 & 0x800) {
  80.     bltadatpt = blit_xlateptr(bltapt, (blt_info.hblitsize*2+blt_info.bltamod)*blt_info.vblitsize);
  81.     bltapt += (blt_info.hblitsize*2+blt_info.bltamod)*blt_info.vblitsize;
  82.     }
  83.     if (bltcon0 & 0x400) {
  84.     bltbdatpt = blit_xlateptr(bltbpt, (blt_info.hblitsize*2+blt_info.bltbmod)*blt_info.vblitsize);
  85.     bltbpt += (blt_info.hblitsize*2+blt_info.bltbmod)*blt_info.vblitsize;
  86.     }
  87.     if (bltcon0 & 0x200) {
  88.     bltcdatpt = blit_xlateptr(bltcpt, (blt_info.hblitsize*2+blt_info.bltcmod)*blt_info.vblitsize);
  89.     bltcpt += (blt_info.hblitsize*2+blt_info.bltcmod)*blt_info.vblitsize;
  90.     }
  91.     if (bltcon0 & 0x100) {
  92.     bltddatpt = blit_xlateptr(bltdpt, (blt_info.hblitsize*2+blt_info.bltdmod)*blt_info.vblitsize);
  93.     bltdpt += (blt_info.hblitsize*2+blt_info.bltdmod)*blt_info.vblitsize;
  94.     }
  95.     
  96.     if (blitfunc_dofast[mt] && !blitfill) 
  97.         (*blitfunc_dofast[mt])(bltadatpt,bltbdatpt,bltcdatpt,bltddatpt,&blt_info);
  98.     else {
  99.         WORD bltamodw = blt_info.bltamod/2, bltbmodw = blt_info.bltbmod/2, bltcmodw = blt_info.bltcmod/2, bltdmodw = blt_info.bltdmod/2;
  100.     /*if (!blitfill) fprintf(stderr, "minterm %x not present\n",mt); */
  101.         for (j = 0; j < blt_info.vblitsize; j++) {
  102.         blitfc = !!(bltcon1 & 0x4);
  103.         for (i = 0; i < blt_info.hblitsize; i++) {
  104.             if (bltadatpt) blt_info.bltadat = *bltadatpt++;
  105.             if (bltbdatpt) blt_info.bltbdat = *bltbdatpt++;
  106.         if (bltcdatpt) blt_info.bltcdat = *bltcdatpt++;
  107.             bltaold = blt_info.bltadat;
  108.             if (i == 0) bltaold &= blt_info.bltafwm;
  109.             if (i== blt_info.hblitsize-1) bltaold &= blt_info.bltalwm;
  110.             blitahold = (((ULONG)blt_info.blitpreva << 16) | bltaold) >> blt_info.blitashift;
  111.             blitbhold = (((ULONG)blt_info.blitprevb << 16) | blt_info.bltbdat) >> blt_info.blitbshift;
  112.             blt_info.bltddat = blit_func(blitahold, blitbhold, blt_info.bltcdat, mt);
  113.             if (blitfill) {
  114.             UWORD d = blt_info.bltddat;
  115.             int ifemode = blitife ? 2 : 0;
  116.             int fc1 = blit_filltable[d & 255][ifemode + blitfc][1];
  117.             blt_info.bltddat = (blit_filltable[d & 255][ifemode + blitfc][0] 
  118.                     + (blit_filltable[d >> 8][ifemode + fc1][0] << 8));
  119.             blitfc = blit_filltable[d >> 8][ifemode + fc1][1];
  120.         }
  121.             blt_info.blitpreva = bltaold; blt_info.blitprevb = blt_info.bltbdat;
  122.             if (blt_info.bltddat) blt_info.blitzero = 0;
  123.             if (bltddatpt) *bltddatpt++ = blt_info.bltddat;
  124.         }
  125.         if (bltadatpt) bltadatpt += bltamodw;
  126.         if (bltbdatpt) bltbdatpt += bltbmodw;
  127.         if (bltcdatpt) bltcdatpt += bltcmodw;
  128.         if (bltddatpt) bltddatpt += bltdmodw;
  129.         }
  130.     }
  131.     bltstate = BLT_done;
  132. }
  133.  
  134. static void blitter_dofast_desc(void) 
  135. {
  136.     int i,j;
  137.     UWORD *bltadatpt = 0, *bltbdatpt = 0, *bltcdatpt = 0, *bltddatpt = 0;
  138.     UWORD blitahold, blitbhold, bltaold;
  139.     WORD bltamodw = blt_info.bltamod/2, bltbmodw = blt_info.bltbmod/2, bltcmodw = blt_info.bltcmod/2, bltdmodw = blt_info.bltdmod/2; 
  140.     UBYTE mt = bltcon0 & 0xFF;
  141.     
  142.     if (bltcon0 & 0x800) {
  143.     bltadatpt = blit_xlateptr_desc(bltapt, (blt_info.hblitsize*2+blt_info.bltamod)*blt_info.vblitsize);
  144.     bltapt -= (blt_info.hblitsize*2+blt_info.bltamod)*blt_info.vblitsize;
  145.     }
  146.     if (bltcon0 & 0x400) {
  147.     bltbdatpt = blit_xlateptr_desc(bltbpt, (blt_info.hblitsize*2+blt_info.bltbmod)*blt_info.vblitsize);
  148.     bltbpt -= (blt_info.hblitsize*2+blt_info.bltbmod)*blt_info.vblitsize;
  149.     }
  150.     if (bltcon0 & 0x200) {
  151.     bltcdatpt = blit_xlateptr_desc(bltcpt, (blt_info.hblitsize*2+blt_info.bltcmod)*blt_info.vblitsize);
  152.     bltcpt -= (blt_info.hblitsize*2+blt_info.bltcmod)*blt_info.vblitsize;
  153.     }
  154.     if (bltcon0 & 0x100) {
  155.     bltddatpt = blit_xlateptr_desc(bltdpt, (blt_info.hblitsize*2+blt_info.bltdmod)*blt_info.vblitsize);
  156.     bltdpt -= (blt_info.hblitsize*2+blt_info.bltdmod)*blt_info.vblitsize;
  157.     }
  158.     if (blitfunc_dofast_desc[mt] && !blitfill) 
  159.     (*blitfunc_dofast_desc[mt])(bltadatpt,bltbdatpt,bltcdatpt,bltddatpt,&blt_info);
  160.     else {
  161.         WORD bltamodw = blt_info.bltamod/2, bltbmodw = blt_info.bltbmod/2, bltcmodw = blt_info.bltcmod/2, bltdmodw = blt_info.bltdmod/2; 
  162. /*    if (!blitfill) fprintf(stderr, "minterm %x not present\n",mt);*/
  163.         for (j = 0; j < blt_info.vblitsize; j++) {
  164.         blitfc = !!(bltcon1 & 0x4);
  165.         for (i = 0; i < blt_info.hblitsize; i++) {
  166.             if (bltadatpt) blt_info.bltadat = *bltadatpt--;
  167.             if (bltbdatpt) blt_info.bltbdat = *bltbdatpt--;
  168.             if (bltcdatpt) blt_info.bltcdat = *bltcdatpt--;
  169.             bltaold = blt_info.bltadat;
  170.             if (i == 0) bltaold &= blt_info.bltafwm;
  171.             if (i== blt_info.hblitsize-1) bltaold &= blt_info.bltalwm;
  172.             blitahold = (((ULONG)bltaold << 16) | blt_info.blitpreva) >> (16-blt_info.blitashift);
  173.             blitbhold = (((ULONG)blt_info.bltbdat << 16) | blt_info.blitprevb) >> (16-blt_info.blitbshift);
  174.             blt_info.bltddat = blit_func(blitahold, blitbhold, blt_info.bltcdat, mt);
  175.             if (blitfill) {
  176.             UWORD d = blt_info.bltddat;
  177.             int ifemode = blitife ? 2 : 0;
  178.             int fc1 = blit_filltable[d & 255][ifemode + blitfc][1];
  179.             blt_info.bltddat = (blit_filltable[d & 255][ifemode + blitfc][0]
  180.                     + (blit_filltable[d >> 8][ifemode + fc1][0] << 8));
  181.             blitfc = blit_filltable[d >> 8][ifemode + fc1][1];
  182.         }
  183.             blt_info.blitpreva = bltaold; blt_info.blitprevb = blt_info.bltbdat;
  184.             if (blt_info.bltddat) blt_info.blitzero = 0;
  185.             if (bltddatpt) *bltddatpt-- = blt_info.bltddat;
  186.         }
  187.         if (bltadatpt) bltadatpt -= bltamodw;
  188.         if (bltbdatpt) bltbdatpt -= bltbmodw;
  189.         if (bltcdatpt) bltcdatpt -= bltcmodw;
  190.         if (bltddatpt) bltddatpt -= bltdmodw;
  191.         }
  192.     }
  193.     bltstate = BLT_done;
  194. }
  195.  
  196. static int blitter_read(void)
  197. {
  198.     if (bltcon0 & 0xe00){
  199.     if (!dmaen(DMA_BLITTER)) return 1; /* blitter stopped */
  200.     if (!blitline){
  201.         if (bltcon0 & 0x800) blt_info.bltadat = chipmem_bank.wget(bltapt);
  202.         if (bltcon0 & 0x400) blt_info.bltbdat = chipmem_bank.wget(bltbpt);
  203.     }
  204.     if (bltcon0 & 0x200) blt_info.bltcdat = chipmem_bank.wget(bltcpt);
  205.     }
  206.     bltstate = BLT_work;
  207.     return (bltcon0 & 0xE00) != 0;
  208. }
  209.  
  210. static int blitter_write(void)
  211. {
  212.     if (blt_info.bltddat) blt_info.blitzero = 0;
  213.     if ((bltcon0 & 0x100) || blitline){
  214.     if (!dmaen(DMA_BLITTER)) return 1;
  215.     chipmem_bank.wput(bltdpt, blt_info.bltddat);
  216.     }
  217.     bltstate = BLT_next;
  218.     return (bltcon0 & 0x100) != 0;
  219. }
  220.  
  221. static void blitter_blit(void)
  222. {
  223.     UWORD blitahold,blitbhold,blitchold;
  224.     UWORD bltaold;
  225.     
  226.     if (blitdesc) {
  227.     UWORD bltamask = 0xffff;
  228.     
  229.     if (!blitlpos) { bltamask &= blt_info.bltafwm; }
  230.     if (blitlpos == (blt_info.hblitsize - 1)) { bltamask &= blt_info.bltalwm; }
  231.     bltaold = blt_info.bltadat & bltamask;
  232.  
  233.     blitahold = (((ULONG)bltaold << 16) | blt_info.blitpreva) >> (16-blt_info.blitashift);
  234.     blitbhold = (((ULONG)blt_info.bltbdat << 16) | blt_info.blitprevb) >> (16-blt_info.blitbshift);
  235.     blitchold = blt_info.bltcdat;
  236.     } else {
  237.     UWORD bltamask = 0xffff;
  238.     
  239.     if (!blitlpos) { bltamask &= blt_info.bltafwm; }
  240.     if (blitlpos == (blt_info.hblitsize - 1)) { bltamask &= blt_info.bltalwm; }
  241.     bltaold = blt_info.bltadat & bltamask;
  242.  
  243.     blitahold = (((ULONG)blt_info.blitpreva << 16) | bltaold) >> blt_info.blitashift;
  244.     blitbhold = (((ULONG)blt_info.blitprevb << 16) | blt_info.bltbdat) >> blt_info.blitbshift;
  245.     blitchold = blt_info.bltcdat;
  246.     }
  247.     blt_info.bltddat = 0;
  248.     blt_info.bltddat = blit_func(blitahold, blitbhold, blitchold, bltcon0 & 0xFF);
  249.     if (blitfill){
  250.     UWORD fillmask;
  251.     for (fillmask = 1; fillmask; fillmask <<= 1){
  252.         UWORD tmp = blt_info.bltddat;
  253.         if (blitfc) {
  254.         if (blitife)
  255.             blt_info.bltddat |= fillmask;
  256.         else
  257.             blt_info.bltddat ^= fillmask;
  258.         }
  259.         if (tmp & fillmask) blitfc = !blitfc;
  260.     }
  261.     }
  262.     bltstate = BLT_write;
  263.     blt_info.blitpreva = bltaold; blt_info.blitprevb = blt_info.bltbdat;
  264. }
  265.  
  266. static void blitter_nxblit(void)
  267. {
  268.     bltstate = BLT_read;
  269.     if (blitdesc){
  270.     if (++blitlpos == blt_info.hblitsize) {
  271.         if (--blt_info.vblitsize == 0) {
  272.         bltstate = BLT_done;
  273. #if FAST_BLITTER == 0
  274.         custom_bank.wput(0xDFF09C,0x8040);
  275. #endif
  276.         }
  277.         blitfc = bltcon1 & 0x4;
  278.  
  279.         blitlpos = 0;
  280.         if (bltcon0 & 0x800) bltapt -= 2+blt_info.bltamod; 
  281.         if (bltcon0 & 0x400) bltbpt -= 2+blt_info.bltbmod; 
  282.         if (bltcon0 & 0x200) bltcpt -= 2+blt_info.bltcmod; 
  283.         if (bltcon0 & 0x100) bltdpt -= 2+blt_info.bltdmod;
  284.     } else {
  285.         if (bltcon0 & 0x800) bltapt -= 2; 
  286.         if (bltcon0 & 0x400) bltbpt -= 2; 
  287.         if (bltcon0 & 0x200) bltcpt -= 2; 
  288.         if (bltcon0 & 0x100) bltdpt -= 2;        
  289.     }
  290.     } else {
  291.     if (++blitlpos == blt_info.hblitsize) {
  292.         if (--blt_info.vblitsize == 0) { 
  293.         bltstate = BLT_done;
  294. #if FAST_BLITTER == 0
  295.         custom_bank.wput(0xDFF09C,0x8040);
  296. #endif
  297.         }
  298.         blitlpos = 0;
  299.         if (bltcon0 & 0x800) bltapt += 2+blt_info.bltamod; 
  300.         if (bltcon0 & 0x400) bltbpt += 2+blt_info.bltbmod; 
  301.         if (bltcon0 & 0x200) bltcpt += 2+blt_info.bltcmod; 
  302.         if (bltcon0 & 0x100) bltdpt += 2+blt_info.bltdmod;
  303.     } else {
  304.         if (bltcon0 & 0x800) bltapt += 2; 
  305.         if (bltcon0 & 0x400) bltbpt += 2; 
  306.         if (bltcon0 & 0x200) bltcpt += 2; 
  307.         if (bltcon0 & 0x100) bltdpt += 2;
  308.     }
  309.     }
  310. }
  311.  
  312. static __inline__ void blitter_line_incx(void)
  313. {
  314.     blinea >>= 1;
  315.     if (!blinea) {
  316.     blinea = 0x8000;
  317.     bltcnxlpt += 2;
  318.     bltdnxlpt += 2;
  319.     }
  320. }
  321.  
  322. static __inline__ void blitter_line_decx(void)
  323. {
  324.     blinea <<= 1;
  325.     if (!blinea) {
  326.     blinea = 1;
  327.     bltcnxlpt -= 2;
  328.     bltdnxlpt -= 2;
  329.     }
  330. }
  331.  
  332. static __inline__ void blitter_line_decy(void)
  333. {
  334.     bltcnxlpt -= blt_info.bltcmod;
  335.     bltdnxlpt -= blt_info.bltcmod; /* ??? am I wrong or doesn't KS1.3 set bltdmod? */
  336.     blitonedot = 0;
  337. }
  338.  
  339. static __inline__ void blitter_line_incy(void)
  340. {
  341.     bltcnxlpt += blt_info.bltcmod;
  342.     bltdnxlpt += blt_info.bltcmod; /* ??? */
  343.     blitonedot = 0;
  344. }
  345.  
  346. static void blitter_line(void)
  347. {
  348.     UWORD blitahold = blinea, blitbhold = blineb & 1 ? 0xFFFF : 0, blitchold = blt_info.bltcdat;
  349.     blt_info.bltddat = 0;
  350.     
  351.     if (blitsing && blitonedot) blitahold = 0;
  352.     blitonedot = 1;
  353.     blt_info.bltddat = blit_func(blitahold, blitbhold, blitchold, bltcon0 & 0xFF);
  354.     if (!blitsign){
  355.     bltapt += (WORD)blt_info.bltamod;
  356.     if (bltcon1 & 0x10){
  357.         if (bltcon1 & 0x8)
  358.             blitter_line_decy();
  359.         else
  360.             blitter_line_incy();
  361.     } else {
  362.         if (bltcon1 & 0x8)
  363.             blitter_line_decx();
  364.         else 
  365.             blitter_line_incx();
  366.     }
  367.     } else {
  368.     bltapt += (WORD)blt_info.bltbmod;
  369.     }
  370.     if (bltcon1 & 0x10){
  371.     if (bltcon1 & 0x4)
  372.         blitter_line_decx();
  373.     else
  374.         blitter_line_incx();
  375.     } else {
  376.     if (bltcon1 & 0x4)
  377.         blitter_line_decy();
  378.     else
  379.         blitter_line_incy();
  380.     }
  381.     blitsign = 0 > (WORD)bltapt;
  382.     bltstate = BLT_write;
  383. }
  384.  
  385. static __inline__ void blitter_nxline(void)
  386. {
  387.     bltcpt = bltcnxlpt;
  388.     bltdpt = bltdnxlpt;
  389.     blineb = (blineb << 1) | (blineb >> 15);
  390.     if (--blt_info.vblitsize == 0) {
  391.     bltstate = BLT_done;
  392. #if FAST_BLITTER == 0
  393.     custom_bank.wput(0xDFF09C,0x8040);
  394. #endif
  395.     } else {
  396.     bltstate = BLT_read;
  397.     }
  398. }
  399.  
  400. static void blit_init(void)
  401. {
  402.     blitlpos = 0;
  403.     blt_info.blitzero = 1; blt_info.blitpreva = blt_info.blitprevb = 0;
  404.     blitline = bltcon1 & 1;
  405.     blt_info.blitashift = bltcon0 >> 12; blt_info.blitbshift = bltcon1 >> 12;
  406.     
  407.     if (blitline) {
  408.     if (blt_info.hblitsize != 2)
  409.         fprintf(stderr, "weird hblitsize in linemode: %d\n", blt_info.hblitsize);
  410.     bltcnxlpt = bltcpt;
  411.     bltdnxlpt = bltdpt;
  412.     blitsing = bltcon1 & 0x2;
  413.     blinea = blt_info.bltadat >> blt_info.blitashift;
  414.     blineb = (blt_info.bltbdat >> blt_info.blitbshift) | (blt_info.bltbdat << (16-blt_info.blitbshift));
  415. #if 0
  416.     if (blineb != 0xFFFF && blineb != 0)
  417.         fprintf(stderr, "%x %x %d %x\n", blineb, blt_info.bltbdat, blt_info.blitbshift, bltcon1);
  418. #endif
  419.     blitsign = bltcon1 & 0x40; 
  420.     blitonedot = 0;
  421.     } else {
  422.     blitfc = !!(bltcon1 & 0x4);
  423.     blitife = bltcon1 & 0x8;
  424.     blitfill = bltcon1 & 0x18;
  425.     if ((bltcon1 & 0x18) == 0x18) {
  426.         /* Digital "Trash" demo does this; others too. Apparently, no
  427.          * negative effects. */
  428.         static int warn = 1;
  429.         if (warn)
  430.             fprintf(stderr, "warning: weird fill mode (further messages suppressed)\n");
  431.         warn = 0;
  432.     }
  433.     blitdesc = bltcon1 & 0x2;
  434.     if (blitfill && !blitdesc)
  435.         fprintf(stderr, "warning: blitter fill without desc\n");
  436.     }
  437. }
  438.  
  439. static void actually_do_blit(void)
  440. {
  441.     if (blitline) {
  442.     do {
  443.         blitter_read();
  444.         blitter_line();
  445.         blitter_write();
  446.         blitter_nxline();
  447.     } while (bltstate != BLT_done);
  448.     } else {
  449.     /*blitcount[bltcon0 & 0xff]++;  blitter debug */
  450.     if (blitdesc) blitter_dofast_desc();
  451.     else blitter_dofast();
  452.     }
  453. }
  454.  
  455. void blitter_handler(void)
  456. {
  457.     if (!dmaen(DMA_BLITTER)) {
  458.     eventtab[ev_blitter].active = 1;
  459.     eventtab[ev_blitter].oldcycles = cycles;
  460.     eventtab[ev_blitter].evtime = 10; /* wait a little */
  461.     return; /* gotta come back later. */
  462.     }
  463.     actually_do_blit();
  464.     
  465.     INTREQ(0x8040);
  466.     eventtab[ev_blitter].active = 0;
  467.     specialflags &= ~SPCFLAG_BLTNASTY;
  468. }
  469.  
  470. void do_blitter(void)
  471. {
  472. #if FAST_BLITTER == 0
  473.     /* I'm not sure all this bltstate stuff is really necessary.
  474.      * Most programs should be OK if the blit is done as soon as BLTSIZE is
  475.      * written to, and the BLTFINISH bit is set some time after that.
  476.      * This code here is nowhere near exact.
  477.      */
  478.     do {    
  479.     switch(bltstate) {
  480.      case BLT_init:
  481.         blit_init();
  482.         bltstate = BLT_read;
  483.         /* fall through */
  484.      case BLT_read:
  485.         if (blitter_read())
  486.             break;
  487.         /* fall through */
  488.      case BLT_work:
  489.         if (blitline)
  490.             blitter_line(); 
  491.         else 
  492.             blitter_blit();
  493.         /* fall through */
  494.      case BLT_write:
  495.         if (blitter_write())
  496.             break;
  497.         /* fall through */
  498.      case BLT_next:
  499.         if (blitline)
  500.             blitter_nxline();
  501.         else 
  502.             blitter_nxblit();
  503.         break;
  504.      case BLT_done:
  505.         specialflags &= ~SPCFLAG_BLIT;
  506.         break;
  507.     }
  508.     } while(bltstate != BLT_done && dmaen(DMA_BLITTER)
  509.         && dmaen(DMA_BLITPRI));  /* blitter nasty -> no time for CPU */
  510. #else
  511.     {
  512.     long int blit_cycles = 2;
  513.  
  514.     if (!blitline) {
  515.         if (bltcon0 & 0x400)
  516.         blit_cycles++;
  517.         if ((bltcon0 & 0x300) == 0x300)
  518.         blit_cycles++;
  519.         blit_cycles *= blt_info.vblitsize * blt_info.hblitsize;
  520.     }
  521.     blit_init();
  522.     
  523.     eventtab[ev_blitter].active = 1;
  524.     eventtab[ev_blitter].oldcycles = cycles;
  525.     eventtab[ev_blitter].evtime = blit_cycles;
  526.     events_schedule();
  527.  
  528.     specialflags &= ~SPCFLAG_BLIT;
  529.     if (dmaen(DMA_BLITPRI))
  530.         specialflags |= SPCFLAG_BLTNASTY;
  531.     }
  532. #endif
  533. }
  534.  
  535. void maybe_blit(void)
  536. {
  537.     static int warned = 0;
  538.     if (bltstate == BLT_done)
  539.     return;
  540.     
  541.     if (!warned) {
  542.     warned = 1;
  543.     fprintf(stderr, "warning: Program does not wait for blitter (no further messages)\n");
  544.     }
  545.     if (!eventtab[ev_blitter].active)
  546.     printf("FOO!!?\n");
  547.     actually_do_blit();
  548.     eventtab[ev_blitter].active = 0;
  549.     specialflags &= ~SPCFLAG_BLTNASTY;
  550. }
  551.