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