Annotation of uae/src/blitter.c, revision 1.1.1.16

1.1       root        1:  /*
                      2:   * UAE - The Un*x Amiga Emulator
1.1.1.3   root        3:   *
1.1       root        4:   * Custom chip emulation
1.1.1.3   root        5:   *
1.1       root        6:   * (c) 1995 Bernd Schmidt, Alessandro Bissacco
                      7:   */
                      8: 
                      9: #include "sysconfig.h"
                     10: #include "sysdeps.h"
                     11: 
                     12: #include "options.h"
                     13: #include "events.h"
1.1.1.3   root       14: #include "uae.h"
1.1       root       15: #include "memory.h"
                     16: #include "custom.h"
                     17: #include "newcpu.h"
                     18: #include "blitter.h"
                     19: #include "blit.h"
                     20: 
1.1.1.10  root       21: uae_u16 oldvblts;
1.1.1.16! root       22: uae_u16 bltcon0, bltcon1;
        !            23: uae_u32 bltapt, bltbpt, bltcpt, bltdpt;
1.1       root       24: 
                     25: int blinea_shift;
1.1.1.16! root       26: static uae_u16 blinea, blineb;
        !            27: static int blitline, blitfc, blitfill, blitife, blitsing, blitdesc;
        !            28: static int blitonedot, blitsign;
1.1       root       29: static long int bltwait;
                     30: 
                     31: struct bltinfo blt_info;
                     32: 
1.1.1.3   root       33: static uae_u8 blit_filltable[256][4][2];
                     34: uae_u32 blit_masktable[BLITTER_MAX_WORDS];
1.1       root       35: enum blitter_states bltstate;
                     36: 
1.1.1.14  root       37: static uae_u8 blit_cycle_diagram_start[][10] =
                     38: {
                     39:     { 0, 1, 0 },               /* 0 */
                     40:     { 0, 2, 4,0 },             /* 1 */
                     41:     { 0, 2, 3,0 },             /* 2 */
                     42:     { 2, 3, 3,0, 0,3,4 },      /* 3 */
                     43:     { 0, 3, 2,0,0 },           /* 4 */
                     44:     { 2, 3, 2,0, 0,2,4 },      /* 5 */
                     45:     { 0, 3, 2,3,0 },           /* 6 */
                     46:     { 3, 4, 2,3,0, 0,2,3,4 },  /* 7 */
                     47:     { 0, 2, 1,0 },             /* 8 */
                     48:     { 2, 2, 1,0, 1,4 },                /* 9 */
                     49:     { 0, 2, 1,3 },             /* A */
                     50:     { 3, 3, 1,3,0, 1,3,4 },    /* B */
                     51:     { 2, 3, 1,2, 0,1,2 },      /* C */
                     52:     { 3, 3, 1,2,0, 1,2,4 },    /* D */
                     53:     { 0, 3, 1,2,3 },           /* E */
                     54:     { 4, 4, 1,2,3,0, 1,2,3,4 } /* F */
                     55: };
                     56: 
1.1.1.16! root       57: void build_blitfilltable (void)
1.1       root       58: {
                     59:     unsigned int d, fillmask;
                     60:     int i;
1.1.1.3   root       61: 
1.1.1.2   root       62:     for (i = 0; i < BLITTER_MAX_WORDS; i++)
                     63:        blit_masktable[i] = 0xFFFF;
1.1.1.3   root       64: 
1.1       root       65:     for (d = 0; d < 256; d++) {
                     66:        for (i = 0; i < 4; i++) {
                     67:            int fc = i & 1;
1.1.1.3   root       68:            uae_u8 data = d;
1.1       root       69:            for (fillmask = 1; fillmask != 0x100; fillmask <<= 1) {
1.1.1.3   root       70:                uae_u16 tmp = data;
1.1       root       71:                if (fc) {
                     72:                    if (i & 2)
                     73:                        data |= fillmask;
                     74:                    else
                     75:                        data ^= fillmask;
                     76:                }
                     77:                if (tmp & fillmask) fc = !fc;
                     78:            }
                     79:            blit_filltable[d][i][0] = data;
                     80:            blit_filltable[d][i][1] = fc;
                     81:        }
                     82:     }
                     83: }
                     84: 
1.1.1.16! root       85: static void blitter_dofast (void)
1.1       root       86: {
                     87:     int i,j;
1.1.1.7   root       88:     uaecptr bltadatptr = 0, bltbdatptr = 0, bltcdatptr = 0, bltddatptr = 0;
1.1.1.3   root       89:     uae_u8 mt = bltcon0 & 0xFF;
                     90: 
1.1.1.2   root       91:     blit_masktable[0] = blt_info.bltafwm;
                     92:     blit_masktable[blt_info.hblitsize - 1] &= blt_info.bltalwm;
1.1.1.3   root       93: 
1.1       root       94:     if (bltcon0 & 0x800) {
1.1.1.7   root       95:        bltadatptr = bltapt;
                     96:        bltapt += (blt_info.hblitsize*2 + blt_info.bltamod)*blt_info.vblitsize;
1.1       root       97:     }
                     98:     if (bltcon0 & 0x400) {
1.1.1.7   root       99:        bltbdatptr = bltbpt;
                    100:        bltbpt += (blt_info.hblitsize*2 + blt_info.bltbmod)*blt_info.vblitsize;
1.1       root      101:     }
                    102:     if (bltcon0 & 0x200) {
1.1.1.7   root      103:        bltcdatptr = bltcpt;
                    104:        bltcpt += (blt_info.hblitsize*2 + blt_info.bltcmod)*blt_info.vblitsize;
1.1       root      105:     }
                    106:     if (bltcon0 & 0x100) {
1.1.1.7   root      107:        bltddatptr = bltdpt;
                    108:        bltdpt += (blt_info.hblitsize*2 + blt_info.bltdmod)*blt_info.vblitsize;
1.1       root      109:     }
1.1.1.3   root      110: 
                    111:     if (blitfunc_dofast[mt] && !blitfill)
1.1.1.7   root      112:        (*blitfunc_dofast[mt])(bltadatptr, bltbdatptr, bltcdatptr, bltddatptr, &blt_info);
1.1       root      113:     else {
1.1.1.3   root      114:        uae_u32 blitbhold = blt_info.bltbhold;
                    115:        uae_u32 preva = 0, prevb = 0;
1.1.1.7   root      116:        uaecptr dstp = 0;
1.1.1.16! root      117:        int dodst = 0;
1.1.1.2   root      118: 
1.1.1.11  root      119:        /*if (!blitfill) write_log ("minterm %x not present\n",mt); */
1.1.1.3   root      120:        for (j = 0; j < blt_info.vblitsize; j++) {
1.1       root      121:            blitfc = !!(bltcon1 & 0x4);
                    122:            for (i = 0; i < blt_info.hblitsize; i++) {
1.1.1.3   root      123:                uae_u32 bltadat, blitahold;
1.1.1.7   root      124:                if (bltadatptr) {
1.1.1.16! root      125:                    blt_info.bltadat = bltadat = chipmem_agnus_wget (bltadatptr);
1.1.1.7   root      126:                    bltadatptr += 2;
1.1.1.2   root      127:                } else
                    128:                    bltadat = blt_info.bltadat;
                    129:                bltadat &= blit_masktable[i];
1.1.1.3   root      130:                blitahold = (((uae_u32)preva << 16) | bltadat) >> blt_info.blitashift;
1.1.1.2   root      131:                preva = bltadat;
                    132: 
1.1.1.7   root      133:                if (bltbdatptr) {
1.1.1.16! root      134:                    uae_u16 bltbdat;
        !           135:                    blt_info.bltbdat = bltbdat = chipmem_agnus_wget (bltbdatptr);
1.1.1.7   root      136:                    bltbdatptr += 2;
1.1.1.3   root      137:                    blitbhold = (((uae_u32)prevb << 16) | bltbdat) >> blt_info.blitbshift;
1.1.1.2   root      138:                    prevb = bltbdat;
                    139:                }
1.1.1.7   root      140:                if (bltcdatptr) {
1.1.1.16! root      141:                    blt_info.bltcdat = chipmem_agnus_wget (bltcdatptr);
1.1.1.7   root      142:                    bltcdatptr += 2;
1.1.1.2   root      143:                }
1.1.1.16! root      144:                if (dodst)
        !           145:                    chipmem_agnus_wput (dstp, blt_info.bltddat);
1.1.1.7   root      146:                blt_info.bltddat = blit_func (blitahold, blitbhold, blt_info.bltcdat, mt) & 0xFFFF;
1.1.1.3   root      147:                if (blitfill) {
                    148:                    uae_u16 d = blt_info.bltddat;
1.1       root      149:                    int ifemode = blitife ? 2 : 0;
                    150:                    int fc1 = blit_filltable[d & 255][ifemode + blitfc][1];
1.1.1.3   root      151:                    blt_info.bltddat = (blit_filltable[d & 255][ifemode + blitfc][0]
1.1       root      152:                                        + (blit_filltable[d >> 8][ifemode + fc1][0] << 8));
                    153:                    blitfc = blit_filltable[d >> 8][ifemode + fc1][1];
                    154:                }
1.1.1.7   root      155:                if (blt_info.bltddat)
                    156:                    blt_info.blitzero = 0;
                    157:                if (bltddatptr) {
1.1.1.16! root      158:                    dodst = 1;
1.1.1.7   root      159:                    dstp = bltddatptr;
                    160:                    bltddatptr += 2;
1.1.1.2   root      161:                }
1.1       root      162:            }
1.1.1.7   root      163:            if (bltadatptr) bltadatptr += blt_info.bltamod;
                    164:            if (bltbdatptr) bltbdatptr += blt_info.bltbmod;
                    165:            if (bltcdatptr) bltcdatptr += blt_info.bltcmod;
                    166:            if (bltddatptr) bltddatptr += blt_info.bltdmod;
1.1.1.3   root      167:        }
1.1.1.16! root      168:        if (dodst)
        !           169:            chipmem_agnus_wput (dstp, blt_info.bltddat);
1.1.1.2   root      170:        blt_info.bltbhold = blitbhold;
1.1       root      171:     }
1.1.1.2   root      172:     blit_masktable[0] = 0xFFFF;
                    173:     blit_masktable[blt_info.hblitsize - 1] = 0xFFFF;
1.1.1.3   root      174: 
1.1       root      175:     bltstate = BLT_done;
                    176: }
                    177: 
1.1.1.16! root      178: static void blitter_dofast_desc (void)
1.1       root      179: {
                    180:     int i,j;
1.1.1.7   root      181:     uaecptr bltadatptr = 0, bltbdatptr = 0, bltcdatptr = 0, bltddatptr = 0;
1.1.1.3   root      182:     uae_u8 mt = bltcon0 & 0xFF;
                    183: 
1.1.1.2   root      184:     blit_masktable[0] = blt_info.bltafwm;
                    185:     blit_masktable[blt_info.hblitsize - 1] &= blt_info.bltalwm;
1.1.1.3   root      186: 
1.1       root      187:     if (bltcon0 & 0x800) {
1.1.1.7   root      188:        bltadatptr = bltapt;
                    189:        bltapt -= (blt_info.hblitsize*2 + blt_info.bltamod)*blt_info.vblitsize;
1.1       root      190:     }
                    191:     if (bltcon0 & 0x400) {
1.1.1.7   root      192:        bltbdatptr = bltbpt;
                    193:        bltbpt -= (blt_info.hblitsize*2 + blt_info.bltbmod)*blt_info.vblitsize;
1.1       root      194:     }
                    195:     if (bltcon0 & 0x200) {
1.1.1.7   root      196:        bltcdatptr = bltcpt;
                    197:        bltcpt -= (blt_info.hblitsize*2 + blt_info.bltcmod)*blt_info.vblitsize;
1.1       root      198:     }
                    199:     if (bltcon0 & 0x100) {
1.1.1.7   root      200:        bltddatptr = bltdpt;
                    201:        bltdpt -= (blt_info.hblitsize*2 + blt_info.bltdmod)*blt_info.vblitsize;
1.1       root      202:     }
1.1.1.3   root      203:     if (blitfunc_dofast_desc[mt] && !blitfill)
1.1.1.7   root      204:        (*blitfunc_dofast_desc[mt])(bltadatptr, bltbdatptr, bltcdatptr, bltddatptr, &blt_info);
1.1       root      205:     else {
1.1.1.3   root      206:        uae_u32 blitbhold = blt_info.bltbhold;
                    207:        uae_u32 preva = 0, prevb = 0;
1.1.1.7   root      208:        uaecptr dstp = 0;
1.1.1.16! root      209:        int dodst = 0;
1.1.1.2   root      210: 
1.1.1.11  root      211: /*     if (!blitfill) write_log ("minterm %x not present\n",mt);*/
1.1.1.3   root      212:        for (j = 0; j < blt_info.vblitsize; j++) {
1.1       root      213:            blitfc = !!(bltcon1 & 0x4);
                    214:            for (i = 0; i < blt_info.hblitsize; i++) {
1.1.1.3   root      215:                uae_u32 bltadat, blitahold;
1.1.1.7   root      216:                if (bltadatptr) {
1.1.1.16! root      217:                    blt_info.bltadat = bltadat = chipmem_agnus_wget (bltadatptr);
1.1.1.7   root      218:                    bltadatptr -= 2;
1.1.1.2   root      219:                } else
                    220:                    bltadat = blt_info.bltadat;
                    221:                bltadat &= blit_masktable[i];
1.1.1.3   root      222:                blitahold = (((uae_u32)bltadat << 16) | preva) >> blt_info.blitdownashift;
1.1.1.2   root      223:                preva = bltadat;
1.1.1.7   root      224:                if (bltbdatptr) {
1.1.1.16! root      225:                    uae_u16 bltbdat;
        !           226:                    blt_info.bltbdat = bltbdat = chipmem_agnus_wget (bltbdatptr);
1.1.1.7   root      227:                    bltbdatptr -= 2;
1.1.1.3   root      228:                    blitbhold = (((uae_u32)bltbdat << 16) | prevb) >> blt_info.blitdownbshift;
1.1.1.2   root      229:                    prevb = bltbdat;
                    230:                }
1.1.1.7   root      231:                if (bltcdatptr) {
1.1.1.16! root      232:                    blt_info.bltcdat = chipmem_agnus_wget (bltcdatptr);
1.1.1.7   root      233:                    bltcdatptr -= 2;
1.1.1.2   root      234:                }
1.1.1.16! root      235:                if (dodst)
        !           236:                    chipmem_agnus_wput (dstp, blt_info.bltddat);
1.1.1.7   root      237:                blt_info.bltddat = blit_func (blitahold, blitbhold, blt_info.bltcdat, mt) & 0xFFFF;
1.1.1.3   root      238:                if (blitfill) {
                    239:                    uae_u16 d = blt_info.bltddat;
1.1       root      240:                    int ifemode = blitife ? 2 : 0;
                    241:                    int fc1 = blit_filltable[d & 255][ifemode + blitfc][1];
                    242:                    blt_info.bltddat = (blit_filltable[d & 255][ifemode + blitfc][0]
                    243:                                        + (blit_filltable[d >> 8][ifemode + fc1][0] << 8));
                    244:                    blitfc = blit_filltable[d >> 8][ifemode + fc1][1];
                    245:                }
1.1.1.7   root      246:                if (blt_info.bltddat)
                    247:                    blt_info.blitzero = 0;
                    248:                if (bltddatptr) {
1.1.1.16! root      249:                    dodst = 1;
1.1.1.7   root      250:                    dstp = bltddatptr;
                    251:                    bltddatptr -= 2;
1.1.1.2   root      252:                }
1.1       root      253:            }
1.1.1.7   root      254:            if (bltadatptr) bltadatptr -= blt_info.bltamod;
                    255:            if (bltbdatptr) bltbdatptr -= blt_info.bltbmod;
                    256:            if (bltcdatptr) bltcdatptr -= blt_info.bltcmod;
                    257:            if (bltddatptr) bltddatptr -= blt_info.bltdmod;
1.1.1.3   root      258:        }
1.1.1.16! root      259:        if (dodst)
        !           260:            chipmem_agnus_wput (dstp, blt_info.bltddat);
1.1.1.2   root      261:        blt_info.bltbhold = blitbhold;
1.1       root      262:     }
1.1.1.2   root      263:     blit_masktable[0] = 0xFFFF;
                    264:     blit_masktable[blt_info.hblitsize - 1] = 0xFFFF;
                    265: 
1.1       root      266:     bltstate = BLT_done;
                    267: }
                    268: 
1.1.1.16! root      269: STATIC_INLINE void blitter_read (void)
1.1       root      270: {
1.1.1.16! root      271:     if (bltcon0 & 0x200) {
        !           272:        if (!dmaen (DMA_BLITTER))
        !           273:            return;
        !           274:        blt_info.bltcdat = chipmem_bank.wget (bltcpt);
1.1       root      275:     }
                    276:     bltstate = BLT_work;
                    277: }
                    278: 
1.1.1.16! root      279: STATIC_INLINE void blitter_write (void)
1.1       root      280: {
1.1.1.16! root      281:     if (blt_info.bltddat)
        !           282:        blt_info.blitzero = 0;
        !           283:     /* D-channel state has no effect on linedraw, but C must be enabled or nothing is drawn! */
        !           284:     if (bltcon0 & 0x200) {
        !           285:        if (!dmaen (DMA_BLITTER))
        !           286:            return;
        !           287:        chipmem_agnus_wput (bltdpt, blt_info.bltddat);
1.1       root      288:     }
                    289:     bltstate = BLT_next;
                    290: }
                    291: 
1.1.1.16! root      292: STATIC_INLINE void blitter_line_incx (void)
1.1       root      293: {
                    294:     if (++blinea_shift == 16) {
                    295:        blinea_shift = 0;
1.1.1.16! root      296:        bltcpt += 2;
1.1       root      297:     }
                    298: }
                    299: 
1.1.1.16! root      300: STATIC_INLINE void blitter_line_decx (void)
1.1       root      301: {
                    302:     if (blinea_shift-- == 0) {
                    303:        blinea_shift = 15;
1.1.1.16! root      304:        bltcpt -= 2;
1.1       root      305:     }
                    306: }
                    307: 
1.1.1.16! root      308: STATIC_INLINE void blitter_line_decy (void)
1.1       root      309: {
1.1.1.16! root      310:     bltcpt -= blt_info.bltcmod;
1.1       root      311:     blitonedot = 0;
                    312: }
                    313: 
1.1.1.16! root      314: STATIC_INLINE void blitter_line_incy (void)
1.1       root      315: {
1.1.1.16! root      316:     bltcpt += blt_info.bltcmod;
1.1       root      317:     blitonedot = 0;
                    318: }
                    319: 
1.1.1.16! root      320: static void blitter_line (void)
1.1       root      321: {
1.1.1.16! root      322:     uae_u16 blitahold = (blinea & blt_info.bltafwm) >> blinea_shift;
1.1.1.14  root      323:     uae_u16 blitbhold = blineb & 1 ? 0xFFFF : 0;
                    324:     uae_u16 blitchold = blt_info.bltcdat;
1.1.1.3   root      325: 
1.1.1.15  root      326:     if (blitsing && blitonedot)
                    327:        blitahold = 0;
1.1       root      328:     blitonedot = 1;
1.1.1.16! root      329:     blt_info.bltddat = blit_func (blitahold, blitbhold, blitchold, bltcon0 & 0xFF);
        !           330:     if (!blitsign) {
        !           331:        if (bltcon0 & 0x800)
        !           332:            bltapt += (uae_s16)blt_info.bltamod;
        !           333:        if (bltcon1 & 0x10) {
1.1       root      334:            if (bltcon1 & 0x8)
1.1.1.16! root      335:                blitter_line_decy ();
1.1       root      336:            else
1.1.1.16! root      337:                blitter_line_incy ();
1.1       root      338:        } else {
                    339:            if (bltcon1 & 0x8)
1.1.1.16! root      340:                blitter_line_decx ();
1.1.1.3   root      341:            else
1.1.1.16! root      342:                blitter_line_incx ();
1.1       root      343:        }
                    344:     } else {
1.1.1.16! root      345:        if (bltcon0 & 0x800)
        !           346:            bltapt += (uae_s16)blt_info.bltbmod;
1.1       root      347:     }
1.1.1.16! root      348:     if (bltcon1 & 0x10) {
1.1       root      349:        if (bltcon1 & 0x4)
1.1.1.16! root      350:            blitter_line_decx ();
1.1       root      351:        else
1.1.1.16! root      352:            blitter_line_incx ();
1.1       root      353:     } else {
                    354:        if (bltcon1 & 0x4)
1.1.1.16! root      355:            blitter_line_decy ();
1.1       root      356:        else
1.1.1.16! root      357:            blitter_line_incy ();
1.1       root      358:     }
1.1.1.3   root      359:     blitsign = 0 > (uae_s16)bltapt;
1.1       root      360:     bltstate = BLT_write;
                    361: }
                    362: 
1.1.1.16! root      363: STATIC_INLINE void blitter_nxline (void)
1.1       root      364: {
                    365:     blineb = (blineb << 1) | (blineb >> 15);
1.1.1.16! root      366:     blt_info.vblitsize--;
        !           367:     bltstate = BLT_read;
1.1       root      368: }
                    369: 
1.1.1.16! root      370: static void blit_init (void)
1.1       root      371: {
1.1.1.3   root      372:     blt_info.blitzero = 1;
1.1       root      373:     blitline = bltcon1 & 1;
1.1.1.3   root      374:     blt_info.blitashift = bltcon0 >> 12;
1.1.1.2   root      375:     blt_info.blitdownashift = 16 - blt_info.blitashift;
                    376:     blt_info.blitbshift = bltcon1 >> 12;
                    377:     blt_info.blitdownbshift = 16 - blt_info.blitbshift;
1.1.1.3   root      378: 
1.1       root      379:     if (blitline) {
1.1.1.4   root      380:        if (blt_info.hblitsize != 2)
                    381:            write_log ("weird hblitsize in linemode: %d\n", blt_info.hblitsize);
                    382: 
1.1       root      383:        blitsing = bltcon1 & 0x2;
                    384:        blinea = blt_info.bltadat;
                    385:        blineb = (blt_info.bltbdat >> blt_info.blitbshift) | (blt_info.bltbdat << (16-blt_info.blitbshift));
                    386: #if 0
                    387:        if (blineb != 0xFFFF && blineb != 0)
1.1.1.11  root      388:            write_log ("%x %x %d %x\n", blineb, blt_info.bltbdat, blt_info.blitbshift, bltcon1);
1.1       root      389: #endif
1.1.1.3   root      390:        blitsign = bltcon1 & 0x40;
1.1       root      391:        blitonedot = 0;
                    392:     } else {
                    393:        blitfc = !!(bltcon1 & 0x4);
                    394:        blitife = bltcon1 & 0x8;
                    395:        blitfill = bltcon1 & 0x18;
                    396:        if ((bltcon1 & 0x18) == 0x18) {
                    397:            /* Digital "Trash" demo does this; others too. Apparently, no
                    398:             * negative effects. */
                    399:            static int warn = 1;
                    400:            if (warn)
1.1.1.3   root      401:                write_log ("warning: weird fill mode (further messages suppressed)\n");
1.1       root      402:            warn = 0;
                    403:        }
                    404:        blitdesc = bltcon1 & 0x2;
1.1.1.7   root      405:        if (blitfill && !blitdesc) {
                    406:            static int warn = 1;
                    407:            if (warn)
1.1.1.13  root      408:                write_log ("warning: blitter fill without desc (further messages suppressed)\n");
1.1.1.7   root      409:            warn = 0;
                    410:        }
1.1       root      411:     }
                    412: }
                    413: 
1.1.1.16! root      414: static void actually_do_blit (void)
1.1       root      415: {
                    416:     if (blitline) {
                    417:        do {
1.1.1.16! root      418:            blitter_read ();
        !           419:            blitter_line ();
        !           420:            blitter_write ();
        !           421:            bltdpt = bltcpt;
        !           422:            blitter_nxline ();
        !           423:            if (blt_info.vblitsize == 0)
        !           424:                bltstate = BLT_done;
        !           425:            
1.1       root      426:        } while (bltstate != BLT_done);
                    427:     } else {
1.1.1.15  root      428:        if (blitdesc)
1.1.1.16! root      429:            blitter_dofast_desc ();
1.1.1.15  root      430:        else
1.1.1.16! root      431:            blitter_dofast ();
1.1       root      432:     }
1.1.1.2   root      433:     blitter_done_notify ();
1.1       root      434: }
                    435: 
1.1.1.16! root      436: void blitter_handler (void)
1.1       root      437: {
                    438:     if (!dmaen(DMA_BLITTER)) {
                    439:        eventtab[ev_blitter].active = 1;
1.1.1.9   root      440:        eventtab[ev_blitter].oldcycles = get_cycles ();
                    441:        eventtab[ev_blitter].evtime = 10 * CYCLE_UNIT + get_cycles (); /* wait a little */
1.1       root      442:        return; /* gotta come back later. */
                    443:     }
1.1.1.16! root      444:     actually_do_blit ();
1.1.1.3   root      445: 
1.1       root      446:     INTREQ(0x8040);
                    447:     eventtab[ev_blitter].active = 0;
1.1.1.8   root      448:     unset_special (SPCFLAG_BLTNASTY);
1.1       root      449: }
                    450: 
1.1.1.12  root      451: static long int blit_cycles;
                    452: static long blit_firstline_cycles;
                    453: static long blit_first_cycle;
                    454: static int blit_last_cycle;
                    455: static uae_u8 *blit_diag;
1.1.1.3   root      456: 
1.1.1.16! root      457: void do_blitter (void)
1.1.1.12  root      458: {
                    459:     int ch = (bltcon0 & 0x0f00) >> 8;
                    460:     blit_diag = blit_cycle_diagram_start[ch];
1.1       root      461: 
1.1.1.12  root      462:     blit_firstline_cycles = blit_first_cycle = get_cycles ();
                    463:     blit_last_cycle = 0;
                    464:     if (!currprefs.immediate_blits) {
1.1       root      465:        if (!blitline) {
1.1.1.12  root      466:            blit_cycles = blit_diag[1];
                    467:            blit_firstline_cycles += blit_cycles * blt_info.hblitsize * CYCLE_UNIT;
1.1       root      468:            blit_cycles *= blt_info.vblitsize * blt_info.hblitsize;
1.1.1.12  root      469:        } else
1.1.1.13  root      470:             blit_cycles = 20; /* Desert Dream demo freezes if line draw is too fast */
1.1.1.3   root      471:     } else
1.1.1.2   root      472:        blit_cycles = 1;
                    473: 
                    474:     blit_init();
1.1.1.3   root      475: 
1.1.1.2   root      476:     eventtab[ev_blitter].active = 1;
1.1.1.9   root      477:     eventtab[ev_blitter].oldcycles = get_cycles ();
                    478:     eventtab[ev_blitter].evtime = blit_cycles * CYCLE_UNIT + get_cycles ();
1.1.1.2   root      479:     events_schedule();
1.1       root      480: 
1.1.1.8   root      481:     unset_special (SPCFLAG_BLTNASTY);
1.1.1.2   root      482:     if (dmaen(DMA_BLITPRI))
1.1.1.8   root      483:        set_special (SPCFLAG_BLTNASTY);
1.1.1.12  root      484: 
1.1       root      485: }
                    486: 
1.1.1.12  root      487: void maybe_blit (int modulo)
1.1       root      488: {
                    489:     static int warned = 0;
                    490:     if (bltstate == BLT_done)
                    491:        return;
1.1.1.3   root      492: 
1.1       root      493:     if (!warned) {
                    494:        warned = 1;
1.1.1.3   root      495:        write_log ("warning: Program does not wait for blitter\n");
1.1       root      496:     }
                    497:     if (!eventtab[ev_blitter].active)
1.1.1.12  root      498:        write_log ("FOO!!?\n");
                    499: 
                    500:     if (modulo && get_cycles() < blit_firstline_cycles)
                    501:        return;
1.1.1.8   root      502:     blitter_handler ();
1.1       root      503: }
1.1.1.12  root      504: 
                    505: int blitnasty (void)
                    506: {
                    507:     int cycles, ccnt;
                    508:     if (!(regs.spcflags & SPCFLAG_BLTNASTY))
                    509:        return 0;
                    510:     if (bltstate == BLT_done)
                    511:        return 0;
                    512:     if (!dmaen(DMA_BLITTER))
                    513:        return 0;
                    514:     cycles = (get_cycles () - blit_first_cycle) / CYCLE_UNIT;
                    515:     ccnt = 0;
                    516:     while (blit_last_cycle < cycles) {
                    517:        int c;
                    518:        if (blit_last_cycle < blit_diag[0])
                    519:            c = blit_diag[blit_last_cycle + 2];
                    520:        else
1.1.1.13  root      521:            c = blit_diag[((blit_last_cycle - blit_diag[0]) % blit_diag[1]) + 2 + blit_diag[0]];
1.1.1.12  root      522:        blit_last_cycle ++;
                    523:        if (!c)
                    524:            return 0;
                    525:        ccnt++;
                    526:     }
                    527:     return ccnt;
                    528: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.