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