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

1.1       root        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"
1.1.1.2 ! root       17: #include "readcpu.h"
1.1       root       18: #include "newcpu.h"
                     19: #include "blitter.h"
                     20: #include "blit.h"
                     21: 
                     22: UWORD bltsize, oldvblts;
                     23: UWORD bltcon0,bltcon1;
                     24: ULONG bltapt,bltbpt,bltcpt,bltdpt;
                     25: 
                     26: int blinea_shift;
                     27: static UWORD blitlpos, blinea, blineb;
                     28: static CPTR bltcnxlpt,bltdnxlpt;
                     29: static int blitline,blitfc,blitfill,blitife,blitdesc,blitsing;
                     30: static int blitonedot,blitsign;
                     31: static long int bltwait;
                     32: 
                     33: struct bltinfo blt_info;
                     34: 
                     35: static UBYTE blit_filltable[256][4][2];
1.1.1.2 ! root       36: ULONG blit_masktable[BLITTER_MAX_WORDS];
        !            37: static UWORD blit_trashtable[BLITTER_MAX_WORDS];
1.1       root       38: enum blitter_states bltstate;
                     39: 
                     40: void build_blitfilltable(void)
                     41: {
                     42:     unsigned int d, fillmask;
                     43:     int i;
1.1.1.2 ! root       44:     
        !            45:     for (i = 0; i < BLITTER_MAX_WORDS; i++)
        !            46:        blit_masktable[i] = 0xFFFF;
        !            47:     
1.1       root       48:     for (d = 0; d < 256; d++) {
                     49:        for (i = 0; i < 4; i++) {
                     50:            int fc = i & 1;
                     51:            UBYTE data = d;
                     52:            for (fillmask = 1; fillmask != 0x100; fillmask <<= 1) {
                     53:                UWORD tmp = data;
                     54:                if (fc) {
                     55:                    if (i & 2)
                     56:                        data |= fillmask;
                     57:                    else
                     58:                        data ^= fillmask;
                     59:                }
                     60:                if (tmp & fillmask) fc = !fc;
                     61:            }
                     62:            blit_filltable[d][i][0] = data;
                     63:            blit_filltable[d][i][1] = fc;
                     64:        }
                     65:     }
                     66: }
                     67: 
                     68: static __inline__ UBYTE *blit_xlateptr(CPTR bltpt, int bytecount)
                     69: {
                     70:     if (!chipmem_bank.check(bltpt,bytecount)) return NULL;
                     71:     return chipmem_bank.xlateaddr(bltpt);
                     72: }
                     73: 
                     74: static __inline__ UBYTE *blit_xlateptr_desc(CPTR bltpt, int bytecount)
                     75: {
                     76:     if (!chipmem_bank.check(bltpt-bytecount, bytecount)) return NULL;
                     77:     return chipmem_bank.xlateaddr(bltpt);
                     78: }
                     79: 
                     80: static void blitter_dofast(void) 
                     81: {
                     82:     int i,j;
                     83:     UBYTE *bltadatpt = 0, *bltbdatpt = 0, *bltcdatpt = 0, *bltddatpt = 0;
                     84:     UBYTE mt = bltcon0 & 0xFF;
                     85:     
1.1.1.2 ! root       86:     blit_masktable[0] = blt_info.bltafwm;
        !            87:     blit_masktable[blt_info.hblitsize - 1] &= blt_info.bltalwm;
        !            88:     
1.1       root       89:     if (bltcon0 & 0x800) {
                     90:        bltadatpt = blit_xlateptr(bltapt, (blt_info.hblitsize*2+blt_info.bltamod)*blt_info.vblitsize);
                     91:        bltapt += (blt_info.hblitsize*2+blt_info.bltamod)*blt_info.vblitsize;
                     92:     }
                     93:     if (bltcon0 & 0x400) {
                     94:        bltbdatpt = blit_xlateptr(bltbpt, (blt_info.hblitsize*2+blt_info.bltbmod)*blt_info.vblitsize);
                     95:        bltbpt += (blt_info.hblitsize*2+blt_info.bltbmod)*blt_info.vblitsize;
                     96:     }
                     97:     if (bltcon0 & 0x200) {
                     98:        bltcdatpt = blit_xlateptr(bltcpt, (blt_info.hblitsize*2+blt_info.bltcmod)*blt_info.vblitsize);
                     99:        bltcpt += (blt_info.hblitsize*2+blt_info.bltcmod)*blt_info.vblitsize;
                    100:     }
                    101:     if (bltcon0 & 0x100) {
                    102:        bltddatpt = blit_xlateptr(bltdpt, (blt_info.hblitsize*2+blt_info.bltdmod)*blt_info.vblitsize);
                    103:        bltdpt += (blt_info.hblitsize*2+blt_info.bltdmod)*blt_info.vblitsize;
                    104:     }
                    105:     
                    106:     if (blitfunc_dofast[mt] && !blitfill) 
                    107:         (*blitfunc_dofast[mt])(bltadatpt,bltbdatpt,bltcdatpt,bltddatpt,&blt_info);
                    108:     else {
1.1.1.2 ! root      109:        ULONG blitbhold = blt_info.bltbhold;
        !           110:        ULONG preva = 0, prevb = 0;
        !           111: 
1.1       root      112:        /*if (!blitfill) fprintf(stderr, "minterm %x not present\n",mt); */
                    113:         for (j = 0; j < blt_info.vblitsize; j++) {
                    114:            blitfc = !!(bltcon1 & 0x4);
                    115:            for (i = 0; i < blt_info.hblitsize; i++) {
1.1.1.2 ! root      116:                ULONG bltadat, blitahold;
        !           117:                if (bltadatpt) {
        !           118:                    bltadat = do_get_mem_word((UWORD *)bltadatpt); bltadatpt += 2;
        !           119:                } else
        !           120:                    bltadat = blt_info.bltadat;
        !           121:                bltadat &= blit_masktable[i];
        !           122:                blitahold = (((ULONG)preva << 16) | bltadat) >> blt_info.blitashift;
        !           123:                preva = bltadat;
        !           124: 
        !           125:                if (bltbdatpt) {
        !           126:                    UWORD bltbdat = do_get_mem_word((UWORD *)bltbdatpt); bltbdatpt += 2;
        !           127:                    blitbhold = (((ULONG)prevb << 16) | bltbdat) >> blt_info.blitbshift;
        !           128:                    prevb = bltbdat;
        !           129:                }
        !           130:                if (bltcdatpt) {
        !           131:                    blt_info.bltcdat = do_get_mem_word((UWORD *)bltcdatpt); bltcdatpt += 2; 
        !           132:                }
        !           133:                blt_info.bltddat = blit_func(blitahold, blitbhold, blt_info.bltcdat, mt) & 0xFFFF;
1.1       root      134:                if (blitfill) {
                    135:                    UWORD d = blt_info.bltddat;
                    136:                    int ifemode = blitife ? 2 : 0;
                    137:                    int fc1 = blit_filltable[d & 255][ifemode + blitfc][1];
                    138:                    blt_info.bltddat = (blit_filltable[d & 255][ifemode + blitfc][0] 
                    139:                                        + (blit_filltable[d >> 8][ifemode + fc1][0] << 8));
                    140:                    blitfc = blit_filltable[d >> 8][ifemode + fc1][1];
                    141:                }
                    142:                if (blt_info.bltddat) blt_info.blitzero = 0;
1.1.1.2 ! root      143:                if (bltddatpt) {
        !           144:                    do_put_mem_word((UWORD *)bltddatpt, blt_info.bltddat);
        !           145:                    bltddatpt += 2;
        !           146:                }
1.1       root      147:            }
                    148:            if (bltadatpt) bltadatpt += blt_info.bltamod;
                    149:            if (bltbdatpt) bltbdatpt += blt_info.bltbmod;
                    150:            if (bltcdatpt) bltcdatpt += blt_info.bltcmod;
                    151:            if (bltddatpt) bltddatpt += blt_info.bltdmod;
                    152:         }
1.1.1.2 ! root      153:        blt_info.bltbhold = blitbhold;
1.1       root      154:     }
1.1.1.2 ! root      155:     blit_masktable[0] = 0xFFFF;
        !           156:     blit_masktable[blt_info.hblitsize - 1] = 0xFFFF;
        !           157:     
1.1       root      158:     bltstate = BLT_done;
                    159: }
                    160: 
                    161: static void blitter_dofast_desc(void) 
                    162: {
                    163:     int i,j;
                    164:     UBYTE *bltadatpt = 0, *bltbdatpt = 0, *bltcdatpt = 0, *bltddatpt = 0;
                    165:     UBYTE mt = bltcon0 & 0xFF;
                    166:     
1.1.1.2 ! root      167:     blit_masktable[0] = blt_info.bltafwm;
        !           168:     blit_masktable[blt_info.hblitsize - 1] &= blt_info.bltalwm;
        !           169:     
1.1       root      170:     if (bltcon0 & 0x800) {
                    171:        bltadatpt = blit_xlateptr_desc(bltapt, (blt_info.hblitsize*2+blt_info.bltamod)*blt_info.vblitsize);
                    172:        bltapt -= (blt_info.hblitsize*2+blt_info.bltamod)*blt_info.vblitsize;
                    173:     }
                    174:     if (bltcon0 & 0x400) {
                    175:        bltbdatpt = blit_xlateptr_desc(bltbpt, (blt_info.hblitsize*2+blt_info.bltbmod)*blt_info.vblitsize);
                    176:        bltbpt -= (blt_info.hblitsize*2+blt_info.bltbmod)*blt_info.vblitsize;
                    177:     }
                    178:     if (bltcon0 & 0x200) {
                    179:        bltcdatpt = blit_xlateptr_desc(bltcpt, (blt_info.hblitsize*2+blt_info.bltcmod)*blt_info.vblitsize);
                    180:        bltcpt -= (blt_info.hblitsize*2+blt_info.bltcmod)*blt_info.vblitsize;
                    181:     }
                    182:     if (bltcon0 & 0x100) {
                    183:        bltddatpt = blit_xlateptr_desc(bltdpt, (blt_info.hblitsize*2+blt_info.bltdmod)*blt_info.vblitsize);
                    184:        bltdpt -= (blt_info.hblitsize*2+blt_info.bltdmod)*blt_info.vblitsize;
                    185:     }
                    186:     if (blitfunc_dofast_desc[mt] && !blitfill) 
                    187:        (*blitfunc_dofast_desc[mt])(bltadatpt,bltbdatpt,bltcdatpt,bltddatpt,&blt_info);
                    188:     else {
1.1.1.2 ! root      189:        ULONG blitbhold = blt_info.bltbhold;
        !           190:        ULONG preva = 0, prevb = 0;
        !           191: 
1.1       root      192: /*     if (!blitfill) fprintf(stderr, "minterm %x not present\n",mt);*/
                    193:         for (j = 0; j < blt_info.vblitsize; j++) {
                    194:            blitfc = !!(bltcon1 & 0x4);
                    195:            for (i = 0; i < blt_info.hblitsize; i++) {
1.1.1.2 ! root      196:                ULONG bltadat, blitahold;
        !           197:                if (bltadatpt) {
        !           198:                    bltadat = do_get_mem_word((UWORD *)bltadatpt); bltadatpt -= 2;
        !           199:                } else
        !           200:                    bltadat = blt_info.bltadat;
        !           201:                bltadat &= blit_masktable[i];
        !           202:                blitahold = (((ULONG)bltadat << 16) | preva) >> blt_info.blitdownashift;
        !           203:                preva = bltadat;
        !           204:                if (bltbdatpt) {
        !           205:                    UWORD bltbdat = do_get_mem_word((UWORD *)bltbdatpt); bltbdatpt -= 2;
        !           206:                    blitbhold = (((ULONG)bltbdat << 16) | prevb) >> blt_info.blitdownbshift;
        !           207:                    prevb = bltbdat;
        !           208:                }
        !           209:                if (bltcdatpt) {
        !           210:                    blt_info.bltcdat = do_get_mem_word((UWORD *)bltcdatpt); bltcdatpt -= 2; 
        !           211:                }
        !           212:                blt_info.bltddat = blit_func(blitahold, blitbhold, blt_info.bltcdat, mt) & 0xFFFF;
1.1       root      213:                if (blitfill) {
                    214:                    UWORD d = blt_info.bltddat;
                    215:                    int ifemode = blitife ? 2 : 0;
                    216:                    int fc1 = blit_filltable[d & 255][ifemode + blitfc][1];
                    217:                    blt_info.bltddat = (blit_filltable[d & 255][ifemode + blitfc][0]
                    218:                                        + (blit_filltable[d >> 8][ifemode + fc1][0] << 8));
                    219:                    blitfc = blit_filltable[d >> 8][ifemode + fc1][1];
                    220:                }
                    221:                if (blt_info.bltddat) blt_info.blitzero = 0;
1.1.1.2 ! root      222:                if (bltddatpt) {
        !           223:                    do_put_mem_word((UWORD *)bltddatpt, blt_info.bltddat);
        !           224:                    bltddatpt -= 2;
        !           225:                }
1.1       root      226:            }
                    227:            if (bltadatpt) bltadatpt -= blt_info.bltamod;
                    228:            if (bltbdatpt) bltbdatpt -= blt_info.bltbmod;
                    229:            if (bltcdatpt) bltcdatpt -= blt_info.bltcmod;
                    230:            if (bltddatpt) bltddatpt -= blt_info.bltdmod;
                    231:         }
1.1.1.2 ! root      232:        blt_info.bltbhold = blitbhold;
1.1       root      233:     }
1.1.1.2 ! root      234:     blit_masktable[0] = 0xFFFF;
        !           235:     blit_masktable[blt_info.hblitsize - 1] = 0xFFFF;
        !           236: 
1.1       root      237:     bltstate = BLT_done;
                    238: }
                    239: 
                    240: static __inline__ int blitter_read(void)
                    241: {
                    242:     if (bltcon0 & 0xe00){
                    243:        if (!dmaen(DMA_BLITTER)) return 1; /* blitter stopped */
                    244:        if (bltcon0 & 0x200) blt_info.bltcdat = chipmem_bank.wget(bltcpt);
                    245:     }
                    246:     bltstate = BLT_work;
                    247:     return (bltcon0 & 0xE00) != 0;
                    248: }
                    249: 
                    250: static __inline__ int blitter_write(void)
                    251: {
                    252:     if (blt_info.bltddat) blt_info.blitzero = 0;
                    253:     if ((bltcon0 & 0x100) || blitline){
                    254:        if (!dmaen(DMA_BLITTER)) return 1;
                    255:        chipmem_bank.wput(bltdpt, blt_info.bltddat);
                    256:     }
                    257:     bltstate = BLT_next;
                    258:     return (bltcon0 & 0x100) != 0;
                    259: }
                    260: 
                    261: static __inline__ void blitter_line_incx(void)
                    262: {
                    263:     if (++blinea_shift == 16) {
                    264:        blinea_shift = 0;
                    265:        bltcnxlpt += 2;
                    266:        bltdnxlpt += 2;
                    267:     }
                    268: }
                    269: 
                    270: static __inline__ void blitter_line_decx(void)
                    271: {
                    272:     if (blinea_shift-- == 0) {
                    273:        blinea_shift = 15;
                    274:        bltcnxlpt -= 2;
                    275:        bltdnxlpt -= 2;
                    276:     }
                    277: }
                    278: 
                    279: static __inline__ void blitter_line_decy(void)
                    280: {
                    281:     bltcnxlpt -= blt_info.bltcmod;
                    282:     bltdnxlpt -= blt_info.bltcmod; /* ??? am I wrong or doesn't KS1.3 set bltdmod? */
                    283:     blitonedot = 0;
                    284: }
                    285: 
                    286: static __inline__ void blitter_line_incy(void)
                    287: {
                    288:     bltcnxlpt += blt_info.bltcmod;
                    289:     bltdnxlpt += blt_info.bltcmod; /* ??? */
                    290:     blitonedot = 0;
                    291: }
                    292: 
                    293: static void blitter_line(void)
                    294: {
                    295:     UWORD blitahold = blinea >> blinea_shift, blitbhold = blineb & 1 ? 0xFFFF : 0, blitchold = blt_info.bltcdat;
                    296:     blt_info.bltddat = 0;
                    297:     
                    298:     if (blitsing && blitonedot) blitahold = 0;
                    299:     blitonedot = 1;
                    300:     blt_info.bltddat = blit_func(blitahold, blitbhold, blitchold, bltcon0 & 0xFF);
                    301:     if (!blitsign){
                    302:        bltapt += (WORD)blt_info.bltamod;
                    303:        if (bltcon1 & 0x10){
                    304:            if (bltcon1 & 0x8)
                    305:                blitter_line_decy();
                    306:            else
                    307:                blitter_line_incy();
                    308:        } else {
                    309:            if (bltcon1 & 0x8)
                    310:                blitter_line_decx();
                    311:            else 
                    312:                blitter_line_incx();
                    313:        }
                    314:     } else {
                    315:        bltapt += (WORD)blt_info.bltbmod;
                    316:     }
                    317:     if (bltcon1 & 0x10){
                    318:        if (bltcon1 & 0x4)
                    319:            blitter_line_decx();
                    320:        else
                    321:            blitter_line_incx();
                    322:     } else {
                    323:        if (bltcon1 & 0x4)
                    324:            blitter_line_decy();
                    325:        else
                    326:            blitter_line_incy();
                    327:     }
                    328:     blitsign = 0 > (WORD)bltapt;
                    329:     bltstate = BLT_write;
                    330: }
                    331: 
                    332: static __inline__ void blitter_nxline(void)
                    333: {
                    334:     bltcpt = bltcnxlpt;
                    335:     bltdpt = bltdnxlpt;
                    336:     blineb = (blineb << 1) | (blineb >> 15);
                    337:     if (--blt_info.vblitsize == 0) {
                    338:        bltstate = BLT_done;
                    339:     } else {
                    340:        bltstate = BLT_read;
                    341:     }
                    342: }
                    343: 
                    344: static void blit_init(void)
                    345: {
                    346:     blitlpos = 0;
1.1.1.2 ! root      347:     blt_info.blitzero = 1; 
1.1       root      348:     blitline = bltcon1 & 1;
1.1.1.2 ! root      349:     blt_info.blitashift = bltcon0 >> 12; 
        !           350:     blt_info.blitdownashift = 16 - blt_info.blitashift;
        !           351:     blt_info.blitbshift = bltcon1 >> 12;
        !           352:     blt_info.blitdownbshift = 16 - blt_info.blitbshift;
1.1       root      353:     
                    354:     if (blitline) {
                    355:        if (blt_info.hblitsize != 2)
                    356:            fprintf(stderr, "weird hblitsize in linemode: %d\n", blt_info.hblitsize);
                    357:        bltcnxlpt = bltcpt;
                    358:        bltdnxlpt = bltdpt;
                    359:        blitsing = bltcon1 & 0x2;
                    360:        blinea = blt_info.bltadat;
                    361:        blineb = (blt_info.bltbdat >> blt_info.blitbshift) | (blt_info.bltbdat << (16-blt_info.blitbshift));
                    362: #if 0
                    363:        if (blineb != 0xFFFF && blineb != 0)
                    364:            fprintf(stderr, "%x %x %d %x\n", blineb, blt_info.bltbdat, blt_info.blitbshift, bltcon1);
                    365: #endif
                    366:        blitsign = bltcon1 & 0x40; 
                    367:        blitonedot = 0;
                    368:     } else {
                    369:        blitfc = !!(bltcon1 & 0x4);
                    370:        blitife = bltcon1 & 0x8;
                    371:        blitfill = bltcon1 & 0x18;
                    372:        if ((bltcon1 & 0x18) == 0x18) {
                    373:            /* Digital "Trash" demo does this; others too. Apparently, no
                    374:             * negative effects. */
                    375:            static int warn = 1;
                    376:            if (warn)
                    377:                fprintf(stderr, "warning: weird fill mode (further messages suppressed)\n");
                    378:            warn = 0;
                    379:        }
                    380:        blitdesc = bltcon1 & 0x2;
                    381:        if (blitfill && !blitdesc)
                    382:            fprintf(stderr, "warning: blitter fill without desc\n");
                    383:     }
                    384: }
                    385: 
                    386: static void actually_do_blit(void)
                    387: {
                    388:     if (blitline) {
                    389:        do {
                    390:            blitter_read();
                    391:            blitter_line();
                    392:            blitter_write();
                    393:            blitter_nxline();
                    394:        } while (bltstate != BLT_done);
                    395:     } else {
                    396:        /*blitcount[bltcon0 & 0xff]++;  blitter debug */
                    397:        if (blitdesc) blitter_dofast_desc();
                    398:        else blitter_dofast();
                    399:     }
1.1.1.2 ! root      400:     blitter_done_notify ();
1.1       root      401: }
                    402: 
                    403: void blitter_handler(void)
                    404: {
                    405:     if (!dmaen(DMA_BLITTER)) {
                    406:        eventtab[ev_blitter].active = 1;
                    407:        eventtab[ev_blitter].oldcycles = cycles;
                    408:        eventtab[ev_blitter].evtime = 10 + cycles; /* wait a little */
                    409:        return; /* gotta come back later. */
                    410:     }
                    411:     actually_do_blit();
                    412:     
                    413:     INTREQ(0x8040);
                    414:     eventtab[ev_blitter].active = 0;
                    415:     regs.spcflags &= ~SPCFLAG_BLTNASTY;
                    416: }
                    417: 
                    418: void do_blitter(void)
                    419: {
1.1.1.2 ! root      420:     long int blit_cycles;
        !           421:     if (!immediate_blits) {
        !           422:        
        !           423:        blit_cycles = 2;
1.1       root      424: 
                    425:        if (!blitline) {
                    426:            if (bltcon0 & 0x400)
                    427:                blit_cycles++;
                    428:            if ((bltcon0 & 0x300) == 0x300)
                    429:                blit_cycles++;
                    430:            blit_cycles *= blt_info.vblitsize * blt_info.hblitsize;
                    431:        }
1.1.1.2 ! root      432:     } else     
        !           433:        blit_cycles = 1;
        !           434: 
        !           435:     blit_init();
1.1       root      436:        
1.1.1.2 ! root      437:     eventtab[ev_blitter].active = 1;
        !           438:     eventtab[ev_blitter].oldcycles = cycles;
        !           439:     eventtab[ev_blitter].evtime = blit_cycles + cycles;
        !           440:     events_schedule();
1.1       root      441: 
1.1.1.2 ! root      442:     if (dmaen(DMA_BLITPRI))
        !           443:        regs.spcflags |= SPCFLAG_BLTNASTY;
1.1       root      444: }
                    445: 
                    446: void maybe_blit(void)
                    447: {
                    448:     static int warned = 0;
                    449:     if (bltstate == BLT_done)
                    450:        return;
                    451:     
                    452:     if (!warned) {
                    453:        warned = 1;
                    454:        fprintf(stderr, "warning: Program does not wait for blitter (no further messages)\n");
                    455:     }
                    456:     if (!eventtab[ev_blitter].active)
                    457:        printf("FOO!!?\n");
                    458:     actually_do_blit();
                    459:     eventtab[ev_blitter].active = 0;
                    460:     regs.spcflags &= ~SPCFLAG_BLTNASTY;
                    461: }

unix.superglobalmegacorp.com

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