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