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