|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.