|
|
1.1.1.2 ! root 1: /* 1.1 root 2: * UAE - The Un*x Amiga Emulator 3: * 4: * Custom chip emulation 5: * 6: * (c) 1995 Bernd Schmidt, Alessandro Bissacco 7: */ 8: 1.1.1.2 ! root 9: #include "sysconfig.h" ! 10: #include "sysdeps.h" ! 11: 1.1 root 12: #include <ctype.h> 13: #include <assert.h> 14: 15: #include "config.h" 16: #include "options.h" 17: #include "events.h" 18: #include "memory.h" 19: #include "custom.h" 20: #include "cia.h" 21: #include "disk.h" 22: #include "blit.h" 23: #include "xwin.h" 24: #include "os.h" 1.1.1.2 ! root 25: #include "keybuf.h" 1.1 root 26: 27: #define DMA_AUD0 0x0001 28: #define DMA_AUD1 0x0002 29: #define DMA_AUD2 0x0004 30: #define DMA_AUD3 0x0008 31: #define DMA_DISK 0x0010 32: #define DMA_SPRITE 0x0020 33: #define DMA_BLITTER 0x0040 34: #define DMA_COPPER 0x0080 35: #define DMA_BITPLANE 0x0100 36: #define DMA_BLITPRI 0x0400 37: 1.1.1.2 ! root 38: #define MAX_PLANES 8 ! 39: ! 40: #define PIXEL_XPOS(HPOS) (((HPOS)*2 - 0x30)*(use_lores ? 1 : 2)) ! 41: ! 42: /* These are default values for mouse calibration. 1.1 root 43: * The first two are default values for mstepx and mstepy. 44: * The second line set the orizontal and vertical offset for amiga and X 45: * pointer matching 46: */ 47: 48: #define defstepx (1<<16) 49: #define defstepy (1<<16) 50: #define defxoffs 0 51: #define defyoffs 0 1.1.1.2 ! root 52: 1.1 root 53: /* Values below define mouse auto calibration process. 54: * They are not critical, change them if you want. 55: * The most important is calweight, which sets mouse adjustement rate */ 56: 57: static const int docal = 60, xcaloff = 40, ycaloff = 20; 58: static const int calweight = 3; 59: 60: static int lastsampledmx, lastsampledmy; 61: 62: /* 63: * Events 64: */ 65: 66: unsigned long int cycles, nextevent, nextev_count, specialflags; 67: int vpos; 68: UWORD lof; 69: 70: struct ev eventtab[ev_max]; 71: 1.1.1.2 ! root 72: int copper_active; 1.1 root 73: 74: static const int dskdelay = 2; /* FIXME: ??? */ 75: 76: /* 77: * hardware register values that are visible/can be written to by someone 78: */ 79: 80: static UWORD cregs[256]; 81: 1.1.1.2 ! root 82: static UWORD dmacon,intena,intreq; ! 83: UWORD adkcon; /* used by audio code */ 1.1 root 84: 85: static ULONG cop1lc,cop2lc,copcon; 86: 1.1.1.2 ! root 87: /* Kludge. FIXME: How does sprite restart after vsync work? */ ! 88: static int spron[8]; ! 89: static CPTR sprpt[8]; ! 90: ! 91: static ULONG bpl1dat,bpl2dat,bpl3dat,bpl4dat,bpl5dat,bpl6dat,bpl7dat,bpl8dat; 1.1 root 92: static WORD bpl1mod,bpl2mod; 93: 1.1.1.2 ! root 94: xcolnr acolors[64]; ! 95: ! 96: UWORD *r_bplpt[MAX_PLANES]; ! 97: static CPTR bplpt[MAX_PLANES]; ! 98: ! 99: /*static int blitcount[256]; blitter debug */ ! 100: ! 101: struct bplinfo { ! 102: #if AGA_CHIPSET == 0 ! 103: /* X86.S will break if this isn't at the beginning of the structure. */ ! 104: UWORD color_regs[32]; ! 105: #else ! 106: ULONG color_regs[256]; ! 107: #endif ! 108: UWORD bplcon0,bplcon1,bplcon2,bplcon3,bplcon4; ! 109: UWORD diwstrt,diwstop,ddfstrt,ddfstop; ! 110: ! 111: UWORD sprdata[8], sprdatb[8], sprctl[8], sprpos[8]; ! 112: int sprarmed[8]; ! 113: } bpl_info; ! 114: ! 115: struct line_description ! 116: { ! 117: int inborder; ! 118: xcolnr bordercol; ! 119: struct bplinfo bpl_info; ! 120: struct mem_notify_node *mnn; ! 121: CPTR bplpt[MAX_PLANES]; ! 122: int linedata_valid; ! 123: }; 1.1 root 124: 1.1.1.2 ! root 125: /* 50 words give you 800 horizontal pixels. An A500 can't do that, so it ought ! 126: * to be enough. */ ! 127: #define MAX_WORDS_PER_LINE 50 ! 128: static UWORD line_data[numscrlines * 2][MAX_PLANES][MAX_WORDS_PER_LINE]; ! 129: static struct line_description linedescr[numscrlines * 2]; ! 130: ! 131: static UWORD bltsize; 1.1 root 132: static UWORD bltcon0,bltcon1; 133: static ULONG bltapt,bltbpt,bltcpt,bltdpt,bltcnxlpt,bltdnxlpt; 134: 135: static ULONG dskpt; 136: static UWORD dsklen,dsksync; 137: 138: static int joy0x, joy1x, joy0y, joy1y; 1.1.1.2 ! root 139: int joy0button; ! 140: UWORD joy0dir; 1.1 root 141: static int lastspr0x,lastspr0y,lastdiffx,lastdiffy,spr0pos,spr0ctl; 142: static int mstepx,mstepy,xoffs=defxoffs,yoffs=defyoffs; 143: static int sprvbfl; 144: 1.1.1.2 ! root 145: static enum { normal_mouse, dont_care_mouse, follow_mouse } mousestate; 1.1 root 146: 147: /* 148: * "hidden" hardware registers 149: */ 150: 1.1.1.2 ! root 151: int dblpf_ind1[256], dblpf_ind2[256], dblpf_2nd1[256], dblpf_2nd2[256], dblpf_aga1[256], dblpf_aga2[256]; ! 152: ! 153: int dblpfofs[] = { 0, 2, 4, 8, 16, 32, 64, 128 }; 1.1 root 154: 155: static ULONG coplc; 156: static UWORD copi1,copi2; 157: 158: static enum { 159: COP_stop, COP_read, COP_wait, COP_move, COP_skip 160: } copstate; 161: 1.1.1.2 ! root 162: static UWORD oldvblts,blitlpos,blinea,blineb; ! 163: static int blitline,blitfc,blitfill,blitife,blitdesc,blitsing; ! 164: static int blitonedot,blitsign; 1.1 root 165: static long int bltwait; 166: 1.1.1.2 ! root 167: static struct bltinfo blt_info; ! 168: 1.1 root 169: static int dsklength; 170: 171: static enum { 172: BLT_done, BLT_init, BLT_read, BLT_work, BLT_write, BLT_next 173: } bltstate; 174: 1.1.1.2 ! root 175: int plffirstline,plflastline,plfstrt,plfstop,plflinelen; ! 176: int diwfirstword,diwlastword; ! 177: int plfpri[3]; ! 178: ! 179: int max_diwstop, prev_max_diwstop; 1.1 root 180: 181: int dskdmaen; /* used in cia.c */ 182: static UWORD dskmfm,dskbyte,dsktime; 1.1.1.2 ! root 183: static int dsksynced; 1.1 root 184: 1.1.1.2 ! root 185: int bpldelay1, bpldelay2; ! 186: int bplehb, bplham, bpldualpf, bpldualpfpri, bplplanecnt, bplhires; ! 187: ! 188: static int pfield_fullline,pfield_linedone; ! 189: static int pfield_linedmaon; ! 190: static int pfield_lastpart_hpos,last_sprite; ! 191: static int slowline_nextpos, slowline_linepos, slowline_lasttoscr; ! 192: ! 193: union { ! 194: /* Let's try to align this thing. */ ! 195: double uupzuq; ! 196: long int cruxmedo; ! 197: unsigned char apixels[1000]; ! 198: } pixdata; 1.1 root 199: 200: char spixels[1000]; /* for sprites */ 201: char spixstate[1000]; /* more sprites */ 202: 1.1.1.2 ! root 203: ULONG aga_linebuf[1000], *aga_lbufptr; ! 204: ! 205: char *xlinebuffer; ! 206: int next_lineno, linetoscreen, line_in_border; ! 207: ! 208: /* ! 209: * Statistics ! 210: */ 1.1 root 211: 212: static unsigned long int msecs = 0, frametime = 0, timeframes = 0; 213: static unsigned long int seconds_base; 1.1.1.2 ! root 214: int bogusframe; 1.1 root 215: 1.1.1.2 ! root 216: /* ! 217: * helper functions ! 218: */ 1.1 root 219: 220: static void pfield_doline_slow(int); 221: static void pfield_doline(void); 1.1.1.2 ! root 222: static void do_sprites(int, int); ! 223: static void maybe_blit(void); 1.1 root 224: 1.1.1.2 ! root 225: int inhibit_frame; 1.1 root 226: static int framecnt = 0; 227: 228: static __inline__ void count_frame(void) 229: { 230: if (inhibit_frame) 231: framecnt = 1; 1.1.1.2 ! root 232: else { 1.1 root 233: framecnt++; 1.1.1.2 ! root 234: if (framecnt >= framerate) 1.1 root 235: framecnt = 0; 236: } 237: } 238: 239: static __inline__ void setclr(UWORD *p, UWORD val) 240: { 241: if (val & 0x8000) { 242: *p |= val & 0x7FFF; 243: } else { 244: *p &= ~val; 245: } 246: } 247: 1.1.1.2 ! root 248: int dmaen(UWORD dmamask) 1.1 root 249: { 250: return (dmamask & dmacon) && (dmacon & 0x200); 251: } 252: 253: static __inline__ int current_hpos(void) 254: { 255: return cycles - eventtab[ev_hsync].oldcycles; 256: } 257: 258: static void calcdiw(void) 259: { 1.1.1.2 ! root 260: if (use_lores) { ! 261: diwfirstword = (bpl_info.diwstrt & 0xFF) - 0x30 - 1; ! 262: diwlastword = (bpl_info.diwstop & 0xFF) + 0x100 - 0x30 - 1; ! 263: } else { ! 264: diwfirstword = (bpl_info.diwstrt & 0xFF) * 2 - 0x60 - 2; ! 265: diwlastword = (bpl_info.diwstop & 0xFF) * 2 + 0x200 - 0x60 - 2; ! 266: } 1.1 root 267: if (diwfirstword < 0) diwfirstword = 0; 1.1.1.2 ! root 268: if (diwlastword > max_diwstop) max_diwstop = diwlastword; ! 269: ! 270: plffirstline = bpl_info.diwstrt >> 8; ! 271: plflastline = bpl_info.diwstop >> 8; 1.1 root 272: #if 0 273: /* This happens far too often. */ 274: if (plffirstline < minfirstline) { 275: fprintf(stderr, "Warning: Playfield begins before line %d!\n", minfirstline); 276: plffirstline = minfirstline; 277: } 278: #endif 279: if ((plflastline & 0x80) == 0) plflastline |= 0x100; 280: #if 0 /* Turrican does this */ 281: if (plflastline > 313) { 282: fprintf(stderr, "Warning: Playfield out of range!\n"); 283: plflastline = 313; 284: } 285: #endif 1.1.1.2 ! root 286: plfstrt = bpl_info.ddfstrt; ! 287: plfstop = bpl_info.ddfstop; 1.1 root 288: if (plfstrt < 0x18) plfstrt = 0x18; 289: if (plfstop > 0xD8) plfstop = 0xD8; 290: if (plfstrt > plfstop) plfstrt = plfstop; 291: 292: /* 293: * Prize question: What are the next lines supposed to be? 294: * I can't seem to get it right. 295: */ 296: #if 0 297: /* Pretty good guess, but wrong. */ 298: plflinelen = (plfstop-plfstrt+15) & ~7; 299: plfstrt &= ~(bplhires ? 3 : 7); 300: plfstop &= ~(bplhires ? 3 : 7); 301: #endif 1.1.1.2 ! root 302: /* This actually seems to be correct now... */ ! 303: ! 304: /* ! If the masking operation is changed, the pfield_doline code could break ! 305: * on some systems (alignment) */ ! 306: plfstrt &= ~3; ! 307: plfstop &= ~3; 1.1 root 308: plflinelen = (plfstop-plfstrt+15) & ~7; 309: } 310: 1.1.1.2 ! root 311: /* ! 312: * Screen update macros ! 313: */ ! 314: #define LINE_TO_SCR(NAME, TYPE) \ ! 315: static void NAME(int pix, int stoppos) \ ! 316: { \ ! 317: TYPE *buf = (TYPE *)xlinebuffer; \ ! 318: \ ! 319: while (pix < diwfirstword && pix < stoppos) { \ ! 320: *buf++ = acolors[0]; pix++; \ ! 321: } \ ! 322: if (bplham && bplplanecnt == 6) { \ ! 323: /* HAM */ \ ! 324: static UWORD lastcolor; \ ! 325: if (pix <= diwfirstword) \ ! 326: lastcolor = bpl_info.color_regs[0]; \ ! 327: while (pix < diwlastword && pix < stoppos) { \ ! 328: int pv = pixdata.apixels[pix]; \ ! 329: switch(pv & 0x30) { \ ! 330: case 0x00: lastcolor = bpl_info.color_regs[pv]; break; \ ! 331: case 0x10: lastcolor &= 0xFF0; lastcolor |= (pv & 0xF); break; \ ! 332: case 0x20: lastcolor &= 0x0FF; lastcolor |= (pv & 0xF) << 8; break; \ ! 333: case 0x30: lastcolor &= 0xF0F; lastcolor |= (pv & 0xF) << 4; break; \ ! 334: } \ ! 335: \ ! 336: if (spixstate[pix]) { \ ! 337: *buf++ = acolors[spixels[pix]+16]; \ ! 338: spixels[pix] = spixstate[pix] = 0; \ ! 339: } else { \ ! 340: *buf++ = xcolors[lastcolor]; \ ! 341: } \ ! 342: pix++; \ ! 343: } \ ! 344: } else { \ ! 345: if (bpldualpf) { \ ! 346: int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; \ ! 347: int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; \ ! 348: /* Dual playfield */ \ ! 349: while (pix < diwlastword && pix < stoppos) { \ ! 350: int pixcol = pixdata.apixels[pix]; \ ! 351: int plno = lookup_no[pixcol]; \ ! 352: if (spixstate[pix]) { \ ! 353: int compare = plfpri[plno]; \ ! 354: if (plno == 0 || spixstate[pix] < compare) \ ! 355: *buf++ = acolors[spixels[pix]+16]; \ ! 356: else \ ! 357: *buf++ = acolors[lookup[pixcol]]; \ ! 358: spixels[pix] = spixstate[pix] = 0; \ ! 359: } else { \ ! 360: *buf++ = acolors[lookup[pixcol]]; \ ! 361: } \ ! 362: pix++; \ ! 363: } \ ! 364: } else { \ ! 365: while (pix < diwlastword && pix < stoppos) { \ ! 366: ULONG pixcol = pixdata.apixels[pix]; \ ! 367: if (spixstate[pix]) { \ ! 368: if (pixcol == 0 || spixstate[pix] < plfpri[2]) \ ! 369: *buf++ = acolors[spixels[pix]+16]; \ ! 370: else \ ! 371: *buf++ = acolors[pixcol]; \ ! 372: spixels[pix] = spixstate[pix] = 0; \ ! 373: } else { \ ! 374: *buf++ = acolors[pixcol]; \ ! 375: } \ ! 376: pix++; \ ! 377: } \ ! 378: } \ ! 379: } \ ! 380: while (pix < stoppos) { \ ! 381: pix++; \ ! 382: *buf++ = acolors[0]; \ ! 383: } \ ! 384: xlinebuffer = (char *)buf; \ ! 385: } ! 386: ! 387: /* WARNING: Not too much of this will work correctly yet. */ ! 388: ! 389: static void linetoscr_aga(int pix, int stoppos) ! 390: { ! 391: ULONG *buf = aga_lbufptr; ! 392: int i; ! 393: int xor = (UBYTE)(bpl_info.bplcon4 >> 8); ! 394: for (i = 0; i < stoppos; i++) ! 395: pixdata.apixels[i] ^= xor; ! 396: ! 397: while (pix < diwfirstword && pix < stoppos) { ! 398: *buf++ = bpl_info.color_regs[0]; pix++; ! 399: } ! 400: if (bplham && bplplanecnt == 6) { ! 401: /* HAM 6 */ ! 402: static UWORD lastcolor; ! 403: if (pix <= diwfirstword) ! 404: lastcolor = bpl_info.color_regs[0]; ! 405: while (pix < diwlastword && pix < stoppos) { ! 406: int pv = pixdata.apixels[pix]; ! 407: switch(pv & 0x30) { ! 408: case 0x00: lastcolor = bpl_info.color_regs[pv]; break; ! 409: case 0x10: lastcolor &= 0xF0F000; lastcolor |= (pv & 0xF0); break; ! 410: case 0x20: lastcolor &= 0x00F0F0; lastcolor |= (pv & 0xF0) << 16; break; ! 411: case 0x30: lastcolor &= 0xF000F0; lastcolor |= (pv & 0xF0) << 8; break; ! 412: } ! 413: ! 414: if (spixstate[pix]) { ! 415: *buf++ = acolors[spixels[pix]+16]; ! 416: spixels[pix] = spixstate[pix] = 0; ! 417: } else { ! 418: *buf++ = lastcolor; ! 419: } ! 420: pix++; ! 421: } ! 422: } else if (bplham && bplplanecnt == 8) { ! 423: /* HAM 8 */ ! 424: static ULONG lastcolor; ! 425: if (pix <= diwfirstword) ! 426: lastcolor = bpl_info.color_regs[0]; ! 427: while (pix < diwlastword && pix < stoppos) { ! 428: int pv = pixdata.apixels[pix]; ! 429: switch(pv & 0x3) { ! 430: case 0x0: lastcolor = bpl_info.color_regs[pv >> 2]; break; ! 431: case 0x1: lastcolor &= 0xFFFF03; lastcolor |= (pv & 0xFC); break; ! 432: case 0x2: lastcolor &= 0x03FFFF; lastcolor |= (pv & 0xFC) << 16; break; ! 433: case 0x3: lastcolor &= 0xFF03FF; lastcolor |= (pv & 0xFC) << 8; break; ! 434: } ! 435: ! 436: if (spixstate[pix]) { ! 437: *buf++ = acolors[spixels[pix]+16]; ! 438: spixels[pix] = spixstate[pix] = 0; ! 439: } else { ! 440: *buf++ = lastcolor; ! 441: } ! 442: pix++; ! 443: } ! 444: } else if (bpldualpf) { ! 445: int *lookup = bpldualpfpri ? dblpf_aga2 : dblpf_aga1; ! 446: int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; ! 447: /* Dual playfield */ ! 448: while (pix < diwlastword && pix < stoppos) { ! 449: int pixcol = pixdata.apixels[pix]; ! 450: int pfno = lookup_no[pixcol]; ! 451: ! 452: if (spixstate[pix]) { ! 453: ULONG spix = spixels[pix]; ! 454: spixels[pix] = spixstate[pix] = 0; ! 455: ! 456: *buf++ = acolors[spixels[pix]+16]; ! 457: } else { ! 458: int val = lookup[pixdata.apixels[pix]]; ! 459: if (pfno == 2) ! 460: val += dblpfofs[(bpl_info.bplcon2 >> 10) & 7]; ! 461: *buf++ = acolors[val]; ! 462: } ! 463: pix++; ! 464: } ! 465: } else if (bplehb) { ! 466: while (pix < diwlastword && pix < stoppos) { ! 467: int pixcol = pixdata.apixels[pix]; ! 468: if (spixstate[pix]) { ! 469: if (pixcol == 0 || spixstate[pix] < plfpri[2]) ! 470: *buf++ = acolors[spixels[pix]+16]; ! 471: else ! 472: *buf++ = bpl_info.color_regs[pixcol]; ! 473: spixels[pix] = spixstate[pix] = 0; ! 474: } else { ! 475: *buf++ = bpl_info.color_regs[pixcol]; ! 476: } ! 477: pix++; ! 478: } ! 479: } else { ! 480: while (pix < diwlastword && pix < stoppos) { ! 481: int pixcol = pixdata.apixels[pix]; ! 482: if (spixstate[pix]) { ! 483: if (pixcol == 0 || spixstate[pix] < plfpri[2]) ! 484: *buf++ = bpl_info.color_regs[spixels[pix]+16]; ! 485: else ! 486: *buf++ = bpl_info.color_regs[pixcol]; ! 487: spixels[pix] = spixstate[pix] = 0; ! 488: } else { ! 489: *buf++ = bpl_info.color_regs[pixcol]; ! 490: } ! 491: pix++; ! 492: } ! 493: } ! 494: while (pix < stoppos) { ! 495: pix++; ! 496: *buf++ = acolors[0]; ! 497: } ! 498: aga_lbufptr = buf; ! 499: } ! 500: ! 501: #define FILL_LINE(NAME, TYPE) \ ! 502: static void NAME(char *buf) \ ! 503: { \ ! 504: TYPE *b = (TYPE *)buf; \ ! 505: int i;\ ! 506: int maxpos = use_lores ? 400 : 796; \ ! 507: xcolnr col = acolors[0]; \ ! 508: for (i = 0; i < maxpos; i++) \ ! 509: *b++ = col; \ ! 510: } ! 511: ! 512: /* The following routines provide support for 2bit displays. ! 513: * Though coded specifically for NeXTStation Mono's they ! 514: * shoud be generically useful. ! 515: */ ! 516: #define NX_INITPIXEL char bitOffset=8;\ ! 517: *b=0; ! 518: #define NX_SETPIXEL(col)\ ! 519: {\ ! 520: if(bitOffset==0)\ ! 521: {\ ! 522: b ++;\ ! 523: bitOffset=6;\ ! 524: *b = (col<<6);\ ! 525: }\ ! 526: else\ ! 527: {\ ! 528: bitOffset-=2;\ ! 529: *b |= (col<<bitOffset);\ ! 530: }\ ! 531: } ! 532: /* Special 2bit version for NeXTStep */ ! 533: static void pfield_linetoscr_2(int pix, int stoppos) ! 534: { ! 535: char *b = (char *)xlinebuffer; ! 536: NX_INITPIXEL ! 537: while (pix < diwfirstword && pix < stoppos) { ! 538: NX_SETPIXEL(acolors[0]); pix++; ! 539: } ! 540: ! 541: if (bplham && bplplanecnt == 6) { ! 542: /* HAM */ ! 543: static UWORD lastcolor; ! 544: if (pix <= diwfirstword) ! 545: lastcolor = bpl_info.color_regs[0]; ! 546: while (pix < diwlastword && pix < stoppos) { ! 547: int pv = pixdata.apixels[pix]; ! 548: switch(pv & 0x30) { ! 549: case 0x00: lastcolor = bpl_info.color_regs[pv]; break; ! 550: case 0x10: lastcolor &= 0xFF0; lastcolor |= (pv & 0xF); break; ! 551: case 0x20: lastcolor &= 0x0FF; lastcolor |= (pv & 0xF) << 8; break; ! 552: case 0x30: lastcolor &= 0xF0F; lastcolor |= (pv & 0xF) << 4; break; ! 553: } ! 554: ! 555: if (spixstate[pix]) { ! 556: NX_SETPIXEL(acolors[spixels[pix]+16]); ! 557: spixels[pix] = spixstate[pix] = 0; ! 558: } else { ! 559: NX_SETPIXEL(xcolors[lastcolor]); ! 560: } ! 561: pix++; ! 562: } ! 563: } else { ! 564: if (bpldualpf) { ! 565: int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; ! 566: /* Dual playfield */ ! 567: while (pix < diwlastword && pix < stoppos) { ! 568: if (spixstate[pix]) { ! 569: NX_SETPIXEL( acolors[spixels[pix]+16]); ! 570: spixels[pix] = spixstate[pix] = 0; ! 571: } else { ! 572: NX_SETPIXEL( acolors[lookup[pixdata.apixels[pix]]]); ! 573: } ! 574: pix++; ! 575: } ! 576: } else { ! 577: while (pix < diwlastword && pix < stoppos) { ! 578: if (spixstate[pix]) { ! 579: if (pixdata.apixels[pix] == 0 || spixstate[pix] < plfpri[2]) ! 580: { ! 581: NX_SETPIXEL( acolors[spixels[pix]+16]); ! 582: } ! 583: else ! 584: { ! 585: NX_SETPIXEL( acolors[pixdata.apixels[pix]]); ! 586: } ! 587: spixels[pix] = spixstate[pix] = 0; ! 588: } else { ! 589: NX_SETPIXEL( acolors[pixdata.apixels[pix]]); ! 590: } ! 591: pix++; ! 592: } ! 593: } ! 594: } ! 595: while (pix < stoppos) { ! 596: pix++; ! 597: NX_SETPIXEL( acolors[0]); ! 598: } ! 599: xlinebuffer = (char *)b; ! 600: } ! 601: /* Special 2bit version for NeXTStep */ ! 602: static void fill_line_2(char *buf) ! 603: { ! 604: char *b = (char *)buf; ! 605: int i; ! 606: NX_INITPIXEL ! 607: for (i = 0; i < 796; i++) ! 608: { ! 609: NX_SETPIXEL(acolors[0]); ! 610: } ! 611: } ! 612: ! 613: /* Portability hazard ahead... */ ! 614: LINE_TO_SCR(pfield_linetoscr_8, char) ! 615: LINE_TO_SCR(pfield_linetoscr_16, short) ! 616: LINE_TO_SCR(pfield_linetoscr_32, int) ! 617: ! 618: FILL_LINE(fill_line_8, char) ! 619: FILL_LINE(fill_line_16, short) ! 620: FILL_LINE(fill_line_32, int) ! 621: ! 622: #define pfield_linetoscr_full2 pfield_linetoscr_2 ! 623: #define pfield_linetoscr_full8 pfield_linetoscr_8 ! 624: #define pfield_linetoscr_full16 pfield_linetoscr_16 ! 625: #define pfield_linetoscr_full32 pfield_linetoscr_32 ! 626: ! 627: #if defined(X86_ASSEMBLY) ! 628: #undef pfield_linetoscr_full8 ! 629: #undef pfield_linetoscr_full16 ! 630: extern void pfield_linetoscr_full8(int, int) __asm__("pfield_linetoscr_full8"); ! 631: extern void pfield_linetoscr_full16(int, int) __asm__("pfield_linetoscr_full16"); ! 632: #endif ! 633: ! 634: static __inline__ void fill_line(int y) ! 635: { ! 636: switch (gfxvidinfo.pixbytes) { ! 637: case 0: fill_line_2(gfxvidinfo.bufmem + gfxvidinfo.rowbytes * y); break; ! 638: case 1: fill_line_8(gfxvidinfo.bufmem + gfxvidinfo.rowbytes * y); break; ! 639: case 2: fill_line_16(gfxvidinfo.bufmem + gfxvidinfo.rowbytes * y); break; ! 640: case 4: fill_line_32(gfxvidinfo.bufmem + gfxvidinfo.rowbytes * y); break; ! 641: } ! 642: } ! 643: ! 644: static void pfield_slow_linetoscr(int start, int stop) ! 645: { ! 646: int factor = use_lores ? 1 : 2; ! 647: int oldstop = stop; ! 648: ! 649: start = PIXEL_XPOS(start); ! 650: if (start < 8*factor) ! 651: start = 8*factor; ! 652: stop = PIXEL_XPOS(stop); ! 653: if (stop > 406*factor) ! 654: stop = 406*factor; ! 655: ! 656: if (start >= stop) ! 657: return; ! 658: slowline_lasttoscr = oldstop; ! 659: ! 660: if (start == 8*factor && stop == 406*factor) { ! 661: switch (gfxvidinfo.pixbytes) { ! 662: case 0: pfield_linetoscr_full2 (start, stop); break; ! 663: case 1: pfield_linetoscr_full8 (start, stop); break; ! 664: case 2: pfield_linetoscr_full16 (start, stop); break; ! 665: case 4: pfield_linetoscr_full32 (start, stop); break; ! 666: } ! 667: } else { ! 668: switch (gfxvidinfo.pixbytes) { ! 669: case 0: pfield_linetoscr_2 (start, stop); break; ! 670: case 1: pfield_linetoscr_8 (start, stop); break; ! 671: case 2: pfield_linetoscr_16 (start, stop); break; ! 672: case 4: pfield_linetoscr_32 (start, stop); break; ! 673: } ! 674: } ! 675: } ! 676: ! 677: /* ! 678: * This function is called whenever a hardware register that controls the ! 679: * screen display is modified. Usually, this routine does nothing. But in ! 680: * some cases, e.g., when a color changes in mid-screen, as in copper-plasma ! 681: * effects, this function switches the update method from the fast full-line ! 682: * update to the much slower single-color-clock update. ! 683: */ ! 684: static void pfield_may_need_update(int colreg) 1.1 root 685: { 686: int i; 687: 688: /* Ignore, if this happened before or after the DDF window */ 689: if (framecnt != 0 || !pfield_linedmaon || current_hpos() <= plfstrt 1.1.1.2 ! root 690: || vpos < plffirstline || vpos < minfirstline || vpos >= plflastline) 1.1 root 691: { 692: return; 693: } 694: /* 695: * If a color reg was modified, it is only important if we are within 696: * the DIW. 697: */ 1.1.1.2 ! root 698: if (PIXEL_XPOS(current_hpos()) <= diwfirstword && colreg) 1.1 root 699: return; 700: 701: /* 702: * If we are past the DDF window, me might as well draw the complete 703: * line now. 704: */ 705: if (current_hpos() > plfstrt + plflinelen && pfield_fullline) { 706: if (!pfield_linedone) 707: pfield_doline(); 1.1.1.2 ! root 708: pfield_linedone = 1; 1.1 root 709: return; 710: } 711: 1.1.1.2 ! root 712: do_sprites(vpos, current_hpos()); 1.1 root 713: if (pfield_fullline) { 714: pfield_lastpart_hpos = 0; 1.1.1.2 ! root 715: memset(pixdata.apixels, 0, sizeof(pixdata.apixels)); ! 716: pfield_fullline = 0; ! 717: slowline_nextpos = -1; ! 718: slowline_linepos = 0; ! 719: slowline_lasttoscr = 0; 1.1 root 720: } else { 721: assert(pfield_lastpart_hpos <= current_hpos()); 722: } 723: for (i = pfield_lastpart_hpos; i < current_hpos(); i++) { 724: pfield_doline_slow(i); 725: } 1.1.1.2 ! root 726: if (colreg) { ! 727: pfield_slow_linetoscr(slowline_lasttoscr, current_hpos()); ! 728: } 1.1 root 729: pfield_lastpart_hpos = current_hpos(); 730: } 731: 732: /* Apparently, the DMA bit is tested by the hardware at some point, 733: * presumably at the ddfstart position, to determine whether it 734: * ought to draw the line. 735: * This is probably not completely correct, but should not matter 736: * very much. 737: */ 738: static void pfield_calclinedma(void) 739: { 740: if (current_hpos() >= plfstrt) 741: return; 742: 743: pfield_linedmaon = dmaen(DMA_BITPLANE); 744: } 745: 746: /* 747: * register functions 748: */ 749: 750: static UWORD DMACONR(void) 751: { 752: return (dmacon | (bltstate==BLT_done ? 0 : 0x4000) 1.1.1.2 ! root 753: | (blt_info.blitzero ? 0x2000 : 0)); 1.1 root 754: } 755: static UWORD INTENAR(void) { return intena; } 756: static UWORD INTREQR(void) { return intreq; } 757: static UWORD ADKCONR(void) { return adkcon; } 1.1.1.2 ! root 758: static UWORD VPOSR(void) ! 759: { ! 760: #if AGA_CHIPSET == 1 ! 761: return (vpos >> 8) | lof | 0x2300; ! 762: #else ! 763: #ifdef ECS_AGNUS ! 764: return (vpos >> 8) | lof | 0x2000; ! 765: #else ! 766: return (vpos >> 8) | lof; ! 767: #endif ! 768: #endif ! 769: } 1.1 root 770: static void VPOSW(UWORD v) { lof = v & 0x8000; } 771: static UWORD VHPOSR(void) { return (vpos << 8) | current_hpos(); } 772: 773: static void COP1LCH(UWORD v) { cop1lc= (cop1lc & 0xffff) | ((ULONG)v << 16); } 774: static void COP1LCL(UWORD v) { cop1lc= (cop1lc & ~0xffff) | v; } 775: static void COP2LCH(UWORD v) { cop2lc= (cop2lc & 0xffff) | ((ULONG)v << 16); } 776: static void COP2LCL(UWORD v) { cop2lc= (cop2lc & ~0xffff) | v; } 777: 778: static void COPJMP1(UWORD a) 779: { 780: coplc = cop1lc; copstate = COP_read; 781: eventtab[ev_copper].active = 1; eventtab[ev_copper].oldcycles = cycles; 782: eventtab[ev_copper].evtime = 4; events_schedule(); 1.1.1.2 ! root 783: copper_active = 1; 1.1 root 784: } 785: static void COPJMP2(UWORD a) 786: { 787: coplc = cop2lc; copstate = COP_read; 788: eventtab[ev_copper].active = 1; eventtab[ev_copper].oldcycles = cycles; 789: eventtab[ev_copper].evtime = 4; events_schedule(); 1.1.1.2 ! root 790: copper_active = 1; 1.1 root 791: } 792: 793: static void DMACON(UWORD v) 794: { 795: UWORD oldcon = dmacon; 796: setclr(&dmacon,v); dmacon &= 0x1FFF; 797: pfield_calclinedma(); 798: 1.1.1.2 ! root 799: /* FIXME? Maybe we need to think a bit more about the master DMA enable ! 800: * bit in these cases. */ 1.1 root 801: if ((dmacon & DMA_COPPER) > (oldcon & DMA_COPPER)) { 1.1.1.2 ! root 802: COPJMP1(0); ! 803: } ! 804: if ((dmacon & DMA_SPRITE) > (oldcon & DMA_SPRITE)) { ! 805: int i; ! 806: for (i = 0; i < 8; i++) ! 807: spron[i] = 1; ! 808: } ! 809: if ((dmacon & DMA_BLITPRI) > (oldcon & DMA_BLITPRI) && bltstate != BLT_done) { ! 810: static int count = 0; ! 811: if (!count) { ! 812: count = 1; ! 813: fprintf(stderr, "warning: Program is doing blitpri hacks.\n"); ! 814: } ! 815: specialflags |= SPCFLAG_BLTNASTY; 1.1 root 816: } 817: if (copper_active && !eventtab[ev_copper].active) { 1.1.1.2 ! root 818: eventtab[ev_copper].active = 1; 1.1 root 819: eventtab[ev_copper].oldcycles = cycles; 820: eventtab[ev_copper].evtime = 1; 821: events_schedule(); 822: } 823: } 824: static void INTENA(UWORD v) { setclr(&intena,v); specialflags |= SPCFLAG_INT; } 825: static void INTREQ(UWORD v) { setclr(&intreq,v); specialflags |= SPCFLAG_INT; } 826: static void ADKCON(UWORD v) { setclr(&adkcon,v); } 827: 1.1.1.2 ! root 828: static void BPLPTH(UWORD v, int num) { bplpt[num] = (bplpt[num] & 0xffff) | ((ULONG)v << 16); } ! 829: static void BPLPTL(UWORD v, int num) { bplpt[num] = (bplpt[num] & ~0xffff) | (v & 0xFFFE); } 1.1 root 830: 831: /* 832: * I've seen the listing of an example program that changes 833: * from lo- to hires while a line is being drawn. That's 834: * awful, but we want to emulate it. 835: */ 836: static void BPLCON0(UWORD v) 837: { 1.1.1.2 ! root 838: if (bpl_info.bplcon0 == v) ! 839: return; ! 840: pfield_may_need_update(0); ! 841: bpl_info.bplcon0 = v; ! 842: bplhires = (v & 0x8000) == 0x8000; ! 843: bplplanecnt = (v & 0x7000) >> 12; ! 844: bplham = (v & 0x800) == 0x800; ! 845: bpldualpf = (v & 0x400) == 0x400; ! 846: bplehb = (v & 0xFDC0) == 0x6000 && !(bpl_info.bplcon2 & 0x200); /* see below */ 1.1 root 847: calcdiw(); /* This should go away. */ 848: } 849: static void BPLCON1(UWORD v) 850: { 1.1.1.2 ! root 851: if (bpl_info.bplcon1 == v) ! 852: return; ! 853: pfield_may_need_update(0); ! 854: bpl_info.bplcon1 = v; ! 855: bpldelay1 = v & 0xF; ! 856: bpldelay2 = (v >> 4) & 0xF; 1.1 root 857: } 858: static void BPLCON2(UWORD v) 859: { 1.1.1.2 ! root 860: if (bpl_info.bplcon2 == v) ! 861: return; ! 862: pfield_may_need_update(0); ! 863: bpl_info.bplcon2 = v; ! 864: bpldualpfpri = (v & 0x40) == 0x40; ! 865: plfpri[1] = 1 << 2*(v & 7); ! 866: plfpri[2] = 1 << 2*((v>>3) & 7); ! 867: bplehb = (bpl_info.bplcon0 & 0xFDC0) == 0x6000 && !(v & 0x200); /* see above */ ! 868: } ! 869: static void BPLCON3(UWORD v) ! 870: { ! 871: if (bpl_info.bplcon3 == v) ! 872: return; ! 873: pfield_may_need_update(0); ! 874: bpl_info.bplcon3 = v; ! 875: } ! 876: static void BPLCON4(UWORD v) ! 877: { ! 878: if (bpl_info.bplcon4 == v) ! 879: return; ! 880: pfield_may_need_update(0); ! 881: bpl_info.bplcon4 = v; 1.1 root 882: } 883: 1.1.1.2 ! root 884: static void BPL1MOD(UWORD v) ! 885: { ! 886: v &= ~1; ! 887: if (bpl1mod == v) ! 888: return; ! 889: pfield_may_need_update(0); ! 890: bpl1mod = v; ! 891: } ! 892: static void BPL2MOD(UWORD v) ! 893: { ! 894: v &= ~1; ! 895: if (bpl2mod == v) ! 896: return; ! 897: pfield_may_need_update(0); ! 898: bpl2mod = v; ! 899: } 1.1 root 900: 901: static void BPL1DAT(UWORD v) { bpl1dat = v; } 902: static void BPL2DAT(UWORD v) { bpl2dat = v; } 903: static void BPL3DAT(UWORD v) { bpl3dat = v; } 904: static void BPL4DAT(UWORD v) { bpl4dat = v; } 905: static void BPL5DAT(UWORD v) { bpl5dat = v; } 906: static void BPL6DAT(UWORD v) { bpl6dat = v; } 907: 908: /* We call pfield_may_need_update() from here. Actually, 909: * I have no idea what happens if someone changes ddf or 910: * diw mid-line, and I don't really want to know. I doubt 911: * that this sort of thing was ever used to create a 912: * useful effect. 913: */ 1.1.1.2 ! root 914: static void DIWSTRT(UWORD v) ! 915: { ! 916: if (bpl_info.diwstrt == v) ! 917: return; ! 918: pfield_may_need_update(0); ! 919: bpl_info.diwstrt = v; ! 920: calcdiw(); ! 921: } ! 922: static void DIWSTOP(UWORD v) ! 923: { ! 924: if (bpl_info.diwstop == v) ! 925: return; ! 926: pfield_may_need_update(0); ! 927: bpl_info.diwstop = v; ! 928: calcdiw(); ! 929: } ! 930: static void DDFSTRT(UWORD v) ! 931: { ! 932: if (bpl_info.ddfstrt == v) ! 933: return; ! 934: pfield_may_need_update(0); ! 935: bpl_info.ddfstrt = v; ! 936: calcdiw(); ! 937: } ! 938: static void DDFSTOP(UWORD v) ! 939: { ! 940: if (bpl_info.ddfstop == v) ! 941: return; ! 942: pfield_may_need_update(0); ! 943: bpl_info.ddfstop = v; ! 944: calcdiw(); ! 945: } ! 946: ! 947: static void BLTADAT(UWORD v) ! 948: { ! 949: maybe_blit(); ! 950: blt_info.bltadat = v; ! 951: } ! 952: static void BLTBDAT(UWORD v) ! 953: { ! 954: maybe_blit(); ! 955: blt_info.bltbdat = v; ! 956: } ! 957: static void BLTCDAT(UWORD v) { maybe_blit(); blt_info.bltcdat = v; } ! 958: ! 959: static void BLTAMOD(UWORD v) { maybe_blit(); blt_info.bltamod = v & 0xFFFE; } ! 960: static void BLTBMOD(UWORD v) { maybe_blit(); blt_info.bltbmod = v & 0xFFFE; } ! 961: static void BLTCMOD(UWORD v) { maybe_blit(); blt_info.bltcmod = v & 0xFFFE; } ! 962: static void BLTDMOD(UWORD v) { maybe_blit(); blt_info.bltdmod = v & 0xFFFE; } ! 963: ! 964: static void BLTCON0(UWORD v) { maybe_blit(); bltcon0 = v; } ! 965: /* The next category is "Most useless hardware register". ! 966: * And the winner is... */ ! 967: static void BLTCON0L(UWORD v) { maybe_blit(); bltcon0 = (bltcon0 & 0xFF00) | (v & 0xFF); } ! 968: static void BLTCON1(UWORD v) { maybe_blit(); bltcon1 = v; } ! 969: ! 970: static void BLTAFWM(UWORD v) { maybe_blit(); blt_info.bltafwm = v; } ! 971: static void BLTALWM(UWORD v) { maybe_blit(); blt_info.bltalwm = v; } ! 972: ! 973: static void BLTAPTH(UWORD v) { maybe_blit(); bltapt= (bltapt & 0xffff) | ((ULONG)v << 16); } ! 974: static void BLTAPTL(UWORD v) { maybe_blit(); bltapt= (bltapt & ~0xffff) | (v & 0xFFFE); } ! 975: static void BLTBPTH(UWORD v) { maybe_blit(); bltbpt= (bltbpt & 0xffff) | ((ULONG)v << 16); } ! 976: static void BLTBPTL(UWORD v) { maybe_blit(); bltbpt= (bltbpt & ~0xffff) | (v & 0xFFFE); } ! 977: static void BLTCPTH(UWORD v) { maybe_blit(); bltcpt= (bltcpt & 0xffff) | ((ULONG)v << 16); } ! 978: static void BLTCPTL(UWORD v) { maybe_blit(); bltcpt= (bltcpt & ~0xffff) | (v & 0xFFFE); } ! 979: static void BLTDPTH(UWORD v) { maybe_blit(); bltdpt= (bltdpt & 0xffff) | ((ULONG)v << 16); } ! 980: static void BLTDPTL(UWORD v) { maybe_blit(); bltdpt= (bltdpt & ~0xffff) | (v & 0xFFFE); } ! 981: static void BLTSIZE(UWORD v) ! 982: { ! 983: bltsize = v; ! 984: ! 985: maybe_blit(); ! 986: ! 987: blt_info.vblitsize = bltsize >> 6; ! 988: blt_info.hblitsize = bltsize & 0x3F; ! 989: if (!blt_info.vblitsize) blt_info.vblitsize = 1024; ! 990: if (!blt_info.hblitsize) blt_info.hblitsize = 64; ! 991: ! 992: bltstate = BLT_init; ! 993: specialflags |= SPCFLAG_BLIT; ! 994: } ! 995: static void BLTSIZV(UWORD v) ! 996: { ! 997: maybe_blit(); ! 998: oldvblts = v & 0x7FFF; ! 999: } ! 1000: static void BLTSIZH(UWORD v) ! 1001: { ! 1002: maybe_blit(); ! 1003: blt_info.hblitsize = v & 0x7FF; ! 1004: blt_info.vblitsize = oldvblts; ! 1005: if (!blt_info.vblitsize) blt_info.vblitsize = 32768; ! 1006: if (!blt_info.hblitsize) blt_info.hblitsize = 0x800; ! 1007: bltstate = BLT_init; ! 1008: specialflags |= SPCFLAG_BLIT; ! 1009: } ! 1010: static void SPRxCTL_1(UWORD v, int num) ! 1011: { ! 1012: bpl_info.sprctl[num] = v; ! 1013: bpl_info.sprarmed[num] = 0; ! 1014: if (bpl_info.sprpos[num] == 0 && v == 0) ! 1015: spron[num] = 0; ! 1016: else ! 1017: spron[num] |= 2; ! 1018: } ! 1019: static void SPRxPOS_1(UWORD v, int num) ! 1020: { ! 1021: bpl_info.sprpos[num] = v; ! 1022: } ! 1023: static void SPRxDATA_1(UWORD v, int num) ! 1024: { ! 1025: bpl_info.sprdata[num] = v; ! 1026: bpl_info.sprarmed[num] = 1; ! 1027: } ! 1028: static void SPRxDATB_1(UWORD v, int num) ! 1029: { ! 1030: bpl_info.sprdatb[num] = v; ! 1031: } ! 1032: static void SPRxCTL(UWORD v, int num) { pfield_may_need_update(0); SPRxCTL_1(v, num); } ! 1033: static void SPRxPOS(UWORD v, int num) { pfield_may_need_update(0); SPRxPOS_1(v, num); } ! 1034: static void SPRxDATA(UWORD v, int num){ pfield_may_need_update(0); SPRxDATA_1(v, num); } ! 1035: static void SPRxDATB(UWORD v, int num){ pfield_may_need_update(0); SPRxDATB_1(v, num); } ! 1036: static void SPRxPTH(UWORD v, int num) ! 1037: { ! 1038: sprpt[num] &= 0xffff; ! 1039: sprpt[num] |= (ULONG)v << 16; ! 1040: if (!spron[num]) spron[num] = 1; ! 1041: } ! 1042: static void SPRxPTL(UWORD v, int num) ! 1043: { ! 1044: sprpt[num] &= ~0xffff; ! 1045: sprpt[num] |= v; ! 1046: if (!spron[num]) spron[num] = 1; ! 1047: } 1.1 root 1048: 1049: static void COLOR(UWORD v, int num) 1050: { 1.1.1.2 ! root 1051: int r,g,b; ! 1052: int cr,cg,cb; ! 1053: int colreg; ! 1054: ! 1055: v &= 0xFFF; ! 1056: #if AGA_CHIPSET == 1 ! 1057: { ! 1058: ULONG cval; ! 1059: colreg = ((bpl_info.bplcon3 >> 13) & 7) * 32 + num; ! 1060: r = (v & 0xF00) >> 8; ! 1061: g = (v & 0xF0) >> 4; ! 1062: b = (v & 0xF) >> 0; ! 1063: cr = bpl_info.color_regs[colreg] >> 16; ! 1064: cg = (bpl_info.color_regs[colreg] >> 8) & 0xFF; ! 1065: cb = bpl_info.color_regs[colreg] & 0xFF; ! 1066: ! 1067: if (bpl_info.bplcon3 & 0x200) { ! 1068: cr = 0xF0; cr |= r; ! 1069: cg = 0xF0; cg |= g; ! 1070: cb = 0xF0; cb |= b; ! 1071: } else { ! 1072: cr = r + (r << 4); ! 1073: cg = g + (g << 4); ! 1074: cb = b + (b << 4); ! 1075: } ! 1076: cval = (cr << 16) | (cg << 8) | cb; ! 1077: if (cval == bpl_info.color_regs[colreg]) ! 1078: return; ! 1079: bpl_info.color_regs[colreg] = cval; ! 1080: pfield_may_need_update(1); ! 1081: } ! 1082: #else ! 1083: { ! 1084: if (bpl_info.color_regs[num] == v) ! 1085: return; ! 1086: pfield_may_need_update(1); ! 1087: bpl_info.color_regs[num] = v; ! 1088: acolors[num] = xcolors[v]; ! 1089: acolors[num+32] = xcolors[(v >> 1) & 0x777]; ! 1090: } ! 1091: #endif 1.1 root 1092: } 1093: 1094: static void DSKSYNC(UWORD v) { dsksync = v; } 1095: static void DSKDAT(UWORD v) { dskmfm = v; } 1096: static void DSKPTH(UWORD v) { dskpt = (dskpt & 0xffff) | ((ULONG)v << 16); } 1097: static void DSKPTL(UWORD v) { dskpt = (dskpt & ~0xffff) | (v); } 1098: 1099: static void DSKLEN(UWORD v) 1100: { 1101: if (v & 0x8000) { dskdmaen++; } else { dskdmaen = 0; } 1.1.1.2 ! root 1102: dsktime = dskdelay; dsksynced = 0; 1.1 root 1103: dsklen = dsklength = v; dsklength &= 0x3fff; 1104: if (dskdmaen == 2 && dsksync != 0x4489 && (adkcon & 0x400)) { 1.1.1.2 ! root 1105: fprintf(stderr, "Non-standard sync: %04x len: %x\n", dsksync, dsklength); 1.1 root 1106: } 1107: if (dsklen & 0x4000) DISK_InitWrite(); 1108: if (dskdmaen) specialflags |= SPCFLAG_DISK; 1109: } 1110: 1111: static UWORD DSKBYTR(void) 1112: { 1113: UWORD v = (dsklen >> 1) & 0x6000; 1114: v |= dskbyte; 1115: dskbyte &= ~0x8000; 1116: if (dsksync == dskmfm) v |= 0x1000; 1117: return v; 1118: } 1119: 1120: static UWORD DSKDATR(void) { return dskmfm; } 1121: static UWORD POTGOR(void) 1122: { 1.1.1.2 ! root 1123: UWORD v = 0xFFFF; ! 1124: if (buttonstate[2]) ! 1125: v &= 0xFBFF; 1.1 root 1126: 1.1.1.2 ! root 1127: if (buttonstate[1]) ! 1128: v &= 0xFEFF; ! 1129: ! 1130: return v; ! 1131: } ! 1132: static UWORD POT0DAT(void) ! 1133: { ! 1134: static UWORD cnt = 0; ! 1135: if (buttonstate[2]) ! 1136: cnt = ((cnt + 1) & 0xFF) | (cnt & 0xFF00); ! 1137: if (buttonstate[1]) ! 1138: cnt += 0x100; ! 1139: ! 1140: return cnt; ! 1141: } 1.1 root 1142: static UWORD JOY0DAT(void) { return joy0x + (joy0y << 8); } 1143: static UWORD JOY1DAT(void) 1144: { 1.1.1.2 ! root 1145: return joy0dir; 1.1 root 1146: } 1147: static void JOYTEST(UWORD v) 1148: { 1149: joy0x = joy1x = v & 0xFC; 1150: joy0y = joy1y = (v >> 8) & 0xFC; 1151: } 1152: static void AUD0LCH(UWORD v) { audlc[0] = (audlc[0] & 0xffff) | ((ULONG)v << 16); } 1153: static void AUD0LCL(UWORD v) { audlc[0] = (audlc[0] & ~0xffff) | v; } 1154: static void AUD1LCH(UWORD v) { audlc[1] = (audlc[1] & 0xffff) | ((ULONG)v << 16); } 1155: static void AUD1LCL(UWORD v) { audlc[1] = (audlc[1] & ~0xffff) | v; } 1156: static void AUD2LCH(UWORD v) { audlc[2] = (audlc[2] & 0xffff) | ((ULONG)v << 16); } 1157: static void AUD2LCL(UWORD v) { audlc[2] = (audlc[2] & ~0xffff) | v; } 1158: static void AUD3LCH(UWORD v) { audlc[3] = (audlc[3] & 0xffff) | ((ULONG)v << 16); } 1159: static void AUD3LCL(UWORD v) { audlc[3] = (audlc[3] & ~0xffff) | v; } 1160: static void AUD0PER(UWORD v) { audper[0] = v; } 1161: static void AUD1PER(UWORD v) { audper[1] = v; } 1162: static void AUD2PER(UWORD v) { audper[2] = v; } 1163: static void AUD3PER(UWORD v) { audper[3] = v; } 1.1.1.2 ! root 1164: static void AUD0VOL(UWORD v) { audvol[0] = v & 64 ? 63 : v & 63; } ! 1165: static void AUD1VOL(UWORD v) { audvol[1] = v & 64 ? 63 : v & 63; } ! 1166: static void AUD2VOL(UWORD v) { audvol[2] = v & 64 ? 63 : v & 63; } ! 1167: static void AUD3VOL(UWORD v) { audvol[3] = v & 64 ? 63 : v & 63; } 1.1 root 1168: static void AUD0LEN(UWORD v) { audlen[0] = v; } 1169: static void AUD1LEN(UWORD v) { audlen[1] = v; } 1170: static void AUD2LEN(UWORD v) { audlen[2] = v; } 1171: static void AUD3LEN(UWORD v) { audlen[3] = v; } 1172: 1.1.1.2 ! root 1173: static UWORD SERDATR(void) { return 0; } 1.1 root 1174: 1.1.1.2 ! root 1175: static int copcomp(void) 1.1 root 1176: { 1.1.1.2 ! root 1177: UWORD vp = vpos & (((copi2 >> 8) & 0x7F) | 0x80); ! 1178: UWORD hp = current_hpos() & (copi2 & 0xFE); ! 1179: UWORD vcmp = copi1 >> 8; ! 1180: UWORD hcmp = copi1 & 0xFE; ! 1181: return (vp > vcmp || (vp == vcmp && hp >= hcmp)) && ((copi2 & 0x8000) || !(DMACONR() & 0x4000)); 1.1 root 1182: } 1183: 1184: /* 1185: * Calculate the minimum number of cycles after which the 1186: * copper comparison becomes true. This is quite tricky. I hope it works. 1187: */ 1188: static int calc_copcomp_true(int currvpos, int currhpos) 1189: { 1190: UWORD vp = currvpos & (((copi2 >> 8) & 0x7F) | 0x80); 1191: UWORD hp = currhpos & (copi2 & 0xFE); 1192: UWORD vcmp = copi1 >> 8; 1193: UWORD hcmp = copi1 & 0xFE; 1.1.1.2 ! root 1194: int copper_time_hpos; 1.1 root 1195: int cycleadd = maxhpos - currhpos; 1196: int coptime = 0; 1197: 1198: if ((vp > vcmp || (vp == vcmp && hp >= hcmp)) && ((copi2 & 0x8000) || !(DMACONR() & 0x4000))) 1199: return 0; 1.1.1.2 ! root 1200: 1.1 root 1201: try_again: 1.1.1.2 ! root 1202: 1.1 root 1203: while (vp < vcmp) { 1204: currvpos++; 1205: if (currvpos > maxvpos + 1) 1206: return -1; 1207: currhpos = 0; 1208: coptime += cycleadd; 1209: cycleadd = maxhpos; 1210: vp = currvpos & (((copi2 >> 8) & 0x7F) | 0x80); 1211: } 1.1.1.2 ! root 1212: if (coptime > 0 && bplhires && bplplanecnt == 4) ! 1213: return coptime; ! 1214: copper_time_hpos = currhpos; ! 1215: hp = copper_time_hpos & (copi2 & 0xFE); 1.1 root 1216: if (!(vp > vcmp)) { 1.1.1.2 ! root 1217: while (hp < hcmp-2) { 1.1 root 1218: currhpos++; 1.1.1.2 ! root 1219: /* Copper DMA is turned off in Hires 4 bitplane mode */ ! 1220: if (!bplhires || bplplanecnt < 4 || !dmaen(DMA_BITPLANE) ! 1221: || currhpos < plfstrt-2 || currhpos > (plfstop+4)) ! 1222: copper_time_hpos++; ! 1223: ! 1224: if (currhpos > maxhpos-4) { 1.1 root 1225: /* Now, what? There might be a good position on the 1226: * next line. But it can also be the FFFF FFFE 1227: * case. 1228: */ 1229: currhpos = 0; 1230: currvpos++; 1231: vp = currvpos & (((copi2 >> 8) & 0x7F) | 0x80); 1232: goto try_again; 1233: } 1234: coptime++; 1.1.1.2 ! root 1235: hp = copper_time_hpos & (copi2 & 0xFE); 1.1 root 1236: } 1237: } 1238: if (coptime == 0) /* waiting for the blitter */ 1239: return 1; 1.1.1.2 ! root 1240: 1.1 root 1241: return coptime; 1242: } 1243: 1244: static void copper_read(void) 1245: { 1246: if (dmaen(DMA_COPPER)){ 1247: copi1 = chipmem_bank.wget(coplc); 1248: copi2 = chipmem_bank.wget(coplc+2); 1249: coplc += 4; 1250: eventtab[ev_copper].oldcycles = cycles; 1.1.1.2 ! root 1251: eventtab[ev_copper].evtime = (copi1 & 1) ? (copi2 & 1) ? 10 : 8 : 4; 1.1 root 1252: copstate = (copi1 & 1) ? (copi2 & 1) ? COP_skip : COP_wait : COP_move; 1253: } else { 1254: copstate = COP_read; 1.1.1.2 ! root 1255: eventtab[ev_copper].active = 0; 1.1 root 1256: } 1257: } 1258: 1259: static void do_copper(void) 1260: { 1261: switch(copstate){ 1262: case COP_read: 1263: copper_read(); 1264: break; 1265: case COP_move: 1.1.1.2 ! root 1266: if (copi1 >= (copcon & 2 ? 0x40 : 0x80)) { 1.1 root 1267: custom_bank.wput(copi1,copi2); 1.1.1.2 ! root 1268: copper_read(); ! 1269: } else { ! 1270: copstate = COP_stop; ! 1271: eventtab[ev_copper].active = 0; ! 1272: copper_active = 0; ! 1273: } 1.1 root 1274: break; 1275: case COP_skip: 1.1.1.2 ! root 1276: if (calc_copcomp_true(vpos, current_hpos()) == 0) 1.1 root 1277: coplc += 4; 1278: copper_read(); 1279: break; 1280: case COP_wait: { 1281: int coptime = calc_copcomp_true(vpos, current_hpos()); 1282: if (coptime < 0) { 1283: copstate = COP_stop; 1.1.1.2 ! root 1284: eventtab[ev_copper].active = 0; ! 1285: copper_active = 0; 1.1 root 1286: } else { 1287: if (!coptime) 1288: copper_read(); 1289: else { 1290: eventtab[ev_copper].evtime = coptime; 1291: eventtab[ev_copper].oldcycles = cycles; 1292: } 1293: } 1294: break; 1295: } 1296: case COP_stop: 1.1.1.2 ! root 1297: eventtab[ev_copper].active = 0; ! 1298: copper_active = 0; 1.1 root 1299: break; 1300: } 1301: } 1302: 1.1.1.2 ! root 1303: static UBYTE blit_filltable[256][4][2]; ! 1304: ! 1305: static void build_filltable(void) ! 1306: { ! 1307: unsigned int d, fillmask; ! 1308: int i; ! 1309: for (d = 0; d < 256; d++) { ! 1310: for (i = 0; i < 4; i++) { ! 1311: int fc = i & 1; ! 1312: UBYTE data = d; ! 1313: for (fillmask = 1; fillmask != 0x100; fillmask <<= 1) { ! 1314: UWORD tmp = data; ! 1315: if (fc) { ! 1316: if (i & 2) ! 1317: data |= fillmask; ! 1318: else ! 1319: data ^= fillmask; ! 1320: } ! 1321: if (tmp & fillmask) fc = !fc; ! 1322: } ! 1323: blit_filltable[d][i][0] = data; ! 1324: blit_filltable[d][i][1] = fc; ! 1325: } ! 1326: } ! 1327: } ! 1328: ! 1329: static __inline__ UWORD *blit_xlateptr(CPTR bltpt, int bytecount) ! 1330: { ! 1331: if (!chipmem_bank.check(bltpt,bytecount)) return NULL; ! 1332: return chipmem_bank.xlateaddr(bltpt); ! 1333: } ! 1334: ! 1335: static __inline__ UWORD *blit_xlateptr_desc(CPTR bltpt, int bytecount) ! 1336: { ! 1337: if (!chipmem_bank.check(bltpt-bytecount, bytecount)) return NULL; ! 1338: return chipmem_bank.xlateaddr(bltpt); ! 1339: } ! 1340: ! 1341: static void blitter_dofast(void) ! 1342: { ! 1343: int i,j; ! 1344: UWORD *bltadatpt = 0, *bltbdatpt = 0, *bltcdatpt = 0, *bltddatpt = 0; ! 1345: UWORD blitahold, blitbhold, bltaold; ! 1346: UBYTE mt = bltcon0 & 0xFF; ! 1347: ! 1348: if (bltcon0 & 0x800) { ! 1349: bltadatpt = blit_xlateptr(bltapt, (blt_info.hblitsize*2+blt_info.bltamod)*blt_info.vblitsize); ! 1350: bltapt += (blt_info.hblitsize*2+blt_info.bltamod)*blt_info.vblitsize; ! 1351: } ! 1352: if (bltcon0 & 0x400) { ! 1353: bltbdatpt = blit_xlateptr(bltbpt, (blt_info.hblitsize*2+blt_info.bltbmod)*blt_info.vblitsize); ! 1354: bltbpt += (blt_info.hblitsize*2+blt_info.bltbmod)*blt_info.vblitsize; ! 1355: } ! 1356: if (bltcon0 & 0x200) { ! 1357: bltcdatpt = blit_xlateptr(bltcpt, (blt_info.hblitsize*2+blt_info.bltcmod)*blt_info.vblitsize); ! 1358: bltcpt += (blt_info.hblitsize*2+blt_info.bltcmod)*blt_info.vblitsize; ! 1359: } ! 1360: if (bltcon0 & 0x100) { ! 1361: bltddatpt = blit_xlateptr(bltdpt, (blt_info.hblitsize*2+blt_info.bltdmod)*blt_info.vblitsize); ! 1362: bltdpt += (blt_info.hblitsize*2+blt_info.bltdmod)*blt_info.vblitsize; ! 1363: } ! 1364: ! 1365: if (blitfunc_dofast[mt] && !blitfill) ! 1366: (*blitfunc_dofast[mt])(bltadatpt,bltbdatpt,bltcdatpt,bltddatpt,&blt_info); ! 1367: else { ! 1368: WORD bltamodw = blt_info.bltamod/2, bltbmodw = blt_info.bltbmod/2, bltcmodw = blt_info.bltcmod/2, bltdmodw = blt_info.bltdmod/2; ! 1369: /*if (!blitfill) fprintf(stderr, "minterm %x not present\n",mt); */ ! 1370: for (j = 0; j < blt_info.vblitsize; j++) { ! 1371: blitfc = !!(bltcon1 & 0x4); ! 1372: for (i = 0; i < blt_info.hblitsize; i++) { ! 1373: if (bltadatpt) blt_info.bltadat = *bltadatpt++; ! 1374: if (bltbdatpt) blt_info.bltbdat = *bltbdatpt++; ! 1375: if (bltcdatpt) blt_info.bltcdat = *bltcdatpt++; ! 1376: bltaold = blt_info.bltadat; ! 1377: if (i == 0) bltaold &= blt_info.bltafwm; ! 1378: if (i== blt_info.hblitsize-1) bltaold &= blt_info.bltalwm; ! 1379: blitahold = (((ULONG)blt_info.blitpreva << 16) | bltaold) >> blt_info.blitashift; ! 1380: blitbhold = (((ULONG)blt_info.blitprevb << 16) | blt_info.bltbdat) >> blt_info.blitbshift; ! 1381: blt_info.bltddat = blit_func(blitahold, blitbhold, blt_info.bltcdat, mt); ! 1382: if (blitfill) { ! 1383: UWORD d = blt_info.bltddat; ! 1384: int ifemode = blitife ? 2 : 0; ! 1385: int fc1 = blit_filltable[d & 255][ifemode + blitfc][1]; ! 1386: blt_info.bltddat = (blit_filltable[d & 255][ifemode + blitfc][0] ! 1387: + (blit_filltable[d >> 8][ifemode + fc1][0] << 8)); ! 1388: blitfc = blit_filltable[d >> 8][ifemode + fc1][1]; ! 1389: } ! 1390: blt_info.blitpreva = bltaold; blt_info.blitprevb = blt_info.bltbdat; ! 1391: if (blt_info.bltddat) blt_info.blitzero = 0; ! 1392: if (bltddatpt) *bltddatpt++ = blt_info.bltddat; ! 1393: } ! 1394: if (bltadatpt) bltadatpt += bltamodw; ! 1395: if (bltbdatpt) bltbdatpt += bltbmodw; ! 1396: if (bltcdatpt) bltcdatpt += bltcmodw; ! 1397: if (bltddatpt) bltddatpt += bltdmodw; ! 1398: } ! 1399: } ! 1400: bltstate = BLT_done; ! 1401: } ! 1402: ! 1403: static void blitter_dofast_desc(void) ! 1404: { ! 1405: int i,j; ! 1406: UWORD *bltadatpt = 0, *bltbdatpt = 0, *bltcdatpt = 0, *bltddatpt = 0; ! 1407: UWORD blitahold, blitbhold, bltaold; ! 1408: WORD bltamodw = blt_info.bltamod/2, bltbmodw = blt_info.bltbmod/2, bltcmodw = blt_info.bltcmod/2, bltdmodw = blt_info.bltdmod/2; ! 1409: UBYTE mt = bltcon0 & 0xFF; ! 1410: ! 1411: if (bltcon0 & 0x800) { ! 1412: bltadatpt = blit_xlateptr_desc(bltapt, (blt_info.hblitsize*2+blt_info.bltamod)*blt_info.vblitsize); ! 1413: bltapt -= (blt_info.hblitsize*2+blt_info.bltamod)*blt_info.vblitsize; ! 1414: } ! 1415: if (bltcon0 & 0x400) { ! 1416: bltbdatpt = blit_xlateptr_desc(bltbpt, (blt_info.hblitsize*2+blt_info.bltbmod)*blt_info.vblitsize); ! 1417: bltbpt -= (blt_info.hblitsize*2+blt_info.bltbmod)*blt_info.vblitsize; ! 1418: } ! 1419: if (bltcon0 & 0x200) { ! 1420: bltcdatpt = blit_xlateptr_desc(bltcpt, (blt_info.hblitsize*2+blt_info.bltcmod)*blt_info.vblitsize); ! 1421: bltcpt -= (blt_info.hblitsize*2+blt_info.bltcmod)*blt_info.vblitsize; ! 1422: } ! 1423: if (bltcon0 & 0x100) { ! 1424: bltddatpt = blit_xlateptr_desc(bltdpt, (blt_info.hblitsize*2+blt_info.bltdmod)*blt_info.vblitsize); ! 1425: bltdpt -= (blt_info.hblitsize*2+blt_info.bltdmod)*blt_info.vblitsize; ! 1426: } ! 1427: if (blitfunc_dofast_desc[mt] && !blitfill) ! 1428: (*blitfunc_dofast_desc[mt])(bltadatpt,bltbdatpt,bltcdatpt,bltddatpt,&blt_info); ! 1429: else { ! 1430: WORD bltamodw = blt_info.bltamod/2, bltbmodw = blt_info.bltbmod/2, bltcmodw = blt_info.bltcmod/2, bltdmodw = blt_info.bltdmod/2; ! 1431: /* if (!blitfill) fprintf(stderr, "minterm %x not present\n",mt);*/ ! 1432: for (j = 0; j < blt_info.vblitsize; j++) { ! 1433: blitfc = !!(bltcon1 & 0x4); ! 1434: for (i = 0; i < blt_info.hblitsize; i++) { ! 1435: if (bltadatpt) blt_info.bltadat = *bltadatpt--; ! 1436: if (bltbdatpt) blt_info.bltbdat = *bltbdatpt--; ! 1437: if (bltcdatpt) blt_info.bltcdat = *bltcdatpt--; ! 1438: bltaold = blt_info.bltadat; ! 1439: if (i == 0) bltaold &= blt_info.bltafwm; ! 1440: if (i== blt_info.hblitsize-1) bltaold &= blt_info.bltalwm; ! 1441: blitahold = (((ULONG)bltaold << 16) | blt_info.blitpreva) >> (16-blt_info.blitashift); ! 1442: blitbhold = (((ULONG)blt_info.bltbdat << 16) | blt_info.blitprevb) >> (16-blt_info.blitbshift); ! 1443: blt_info.bltddat = blit_func(blitahold, blitbhold, blt_info.bltcdat, mt); ! 1444: if (blitfill) { ! 1445: UWORD d = blt_info.bltddat; ! 1446: int ifemode = blitife ? 2 : 0; ! 1447: int fc1 = blit_filltable[d & 255][ifemode + blitfc][1]; ! 1448: blt_info.bltddat = (blit_filltable[d & 255][ifemode + blitfc][0] ! 1449: + (blit_filltable[d >> 8][ifemode + fc1][0] << 8)); ! 1450: blitfc = blit_filltable[d >> 8][ifemode + fc1][1]; ! 1451: } ! 1452: blt_info.blitpreva = bltaold; blt_info.blitprevb = blt_info.bltbdat; ! 1453: if (blt_info.bltddat) blt_info.blitzero = 0; ! 1454: if (bltddatpt) *bltddatpt-- = blt_info.bltddat; ! 1455: } ! 1456: if (bltadatpt) bltadatpt -= bltamodw; ! 1457: if (bltbdatpt) bltbdatpt -= bltbmodw; ! 1458: if (bltcdatpt) bltcdatpt -= bltcmodw; ! 1459: if (bltddatpt) bltddatpt -= bltdmodw; ! 1460: } ! 1461: } ! 1462: bltstate = BLT_done; ! 1463: } ! 1464: ! 1465: static int blitter_read(void) 1.1 root 1466: { 1467: if (bltcon0 & 0xe00){ 1.1.1.2 ! root 1468: if (!dmaen(DMA_BLITTER)) return 1; /* blitter stopped */ 1.1 root 1469: if (!blitline){ 1.1.1.2 ! root 1470: if (bltcon0 & 0x800) blt_info.bltadat = chipmem_bank.wget(bltapt); ! 1471: if (bltcon0 & 0x400) blt_info.bltbdat = chipmem_bank.wget(bltbpt); 1.1 root 1472: } 1.1.1.2 ! root 1473: if (bltcon0 & 0x200) blt_info.bltcdat = chipmem_bank.wget(bltcpt); 1.1 root 1474: } 1475: bltstate = BLT_work; 1476: return (bltcon0 & 0xE00) != 0; 1477: } 1478: 1.1.1.2 ! root 1479: static int blitter_write(void) 1.1 root 1480: { 1.1.1.2 ! root 1481: if (blt_info.bltddat) blt_info.blitzero = 0; 1.1 root 1482: if ((bltcon0 & 0x100) || blitline){ 1.1.1.2 ! root 1483: if (!dmaen(DMA_BLITTER)) return 1; ! 1484: chipmem_bank.wput(bltdpt, blt_info.bltddat); 1.1 root 1485: } 1486: bltstate = BLT_next; 1487: return (bltcon0 & 0x100) != 0; 1488: } 1489: 1490: static void blitter_blit(void) 1491: { 1492: UWORD blitahold,blitbhold,blitchold; 1493: UWORD bltaold; 1494: 1495: if (blitdesc) { 1496: UWORD bltamask = 0xffff; 1497: 1.1.1.2 ! root 1498: if (!blitlpos) { bltamask &= blt_info.bltafwm; } ! 1499: if (blitlpos == (blt_info.hblitsize - 1)) { bltamask &= blt_info.bltalwm; } ! 1500: bltaold = blt_info.bltadat & bltamask; ! 1501: ! 1502: blitahold = (((ULONG)bltaold << 16) | blt_info.blitpreva) >> (16-blt_info.blitashift); ! 1503: blitbhold = (((ULONG)blt_info.bltbdat << 16) | blt_info.blitprevb) >> (16-blt_info.blitbshift); ! 1504: blitchold = blt_info.bltcdat; 1.1 root 1505: } else { 1506: UWORD bltamask = 0xffff; 1507: 1.1.1.2 ! root 1508: if (!blitlpos) { bltamask &= blt_info.bltafwm; } ! 1509: if (blitlpos == (blt_info.hblitsize - 1)) { bltamask &= blt_info.bltalwm; } ! 1510: bltaold = blt_info.bltadat & bltamask; ! 1511: ! 1512: blitahold = (((ULONG)blt_info.blitpreva << 16) | bltaold) >> blt_info.blitashift; ! 1513: blitbhold = (((ULONG)blt_info.blitprevb << 16) | blt_info.bltbdat) >> blt_info.blitbshift; ! 1514: blitchold = blt_info.bltcdat; 1.1 root 1515: } 1.1.1.2 ! root 1516: blt_info.bltddat = 0; ! 1517: blt_info.bltddat = blit_func(blitahold, blitbhold, blitchold, bltcon0 & 0xFF); 1.1 root 1518: if (blitfill){ 1519: UWORD fillmask; 1520: for (fillmask = 1; fillmask; fillmask <<= 1){ 1.1.1.2 ! root 1521: UWORD tmp = blt_info.bltddat; 1.1 root 1522: if (blitfc) { 1523: if (blitife) 1.1.1.2 ! root 1524: blt_info.bltddat |= fillmask; 1.1 root 1525: else 1.1.1.2 ! root 1526: blt_info.bltddat ^= fillmask; 1.1 root 1527: } 1528: if (tmp & fillmask) blitfc = !blitfc; 1529: } 1530: } 1531: bltstate = BLT_write; 1.1.1.2 ! root 1532: blt_info.blitpreva = bltaold; blt_info.blitprevb = blt_info.bltbdat; 1.1 root 1533: } 1534: 1535: static void blitter_nxblit(void) 1536: { 1537: bltstate = BLT_read; 1538: if (blitdesc){ 1.1.1.2 ! root 1539: if (++blitlpos == blt_info.hblitsize) { ! 1540: if (--blt_info.vblitsize == 0) { 1.1 root 1541: bltstate = BLT_done; 1.1.1.2 ! root 1542: #if FAST_BLITTER == 0 1.1 root 1543: custom_bank.wput(0xDFF09C,0x8040); 1544: #endif 1545: } 1546: blitfc = bltcon1 & 0x4; 1547: 1548: blitlpos = 0; 1.1.1.2 ! root 1549: if (bltcon0 & 0x800) bltapt -= 2+blt_info.bltamod; ! 1550: if (bltcon0 & 0x400) bltbpt -= 2+blt_info.bltbmod; ! 1551: if (bltcon0 & 0x200) bltcpt -= 2+blt_info.bltcmod; ! 1552: if (bltcon0 & 0x100) bltdpt -= 2+blt_info.bltdmod; 1.1 root 1553: } else { 1554: if (bltcon0 & 0x800) bltapt -= 2; 1555: if (bltcon0 & 0x400) bltbpt -= 2; 1556: if (bltcon0 & 0x200) bltcpt -= 2; 1557: if (bltcon0 & 0x100) bltdpt -= 2; 1558: } 1559: } else { 1.1.1.2 ! root 1560: if (++blitlpos == blt_info.hblitsize) { ! 1561: if (--blt_info.vblitsize == 0) { 1.1 root 1562: bltstate = BLT_done; 1.1.1.2 ! root 1563: #if FAST_BLITTER == 0 1.1 root 1564: custom_bank.wput(0xDFF09C,0x8040); 1565: #endif 1566: } 1567: blitlpos = 0; 1.1.1.2 ! root 1568: if (bltcon0 & 0x800) bltapt += 2+blt_info.bltamod; ! 1569: if (bltcon0 & 0x400) bltbpt += 2+blt_info.bltbmod; ! 1570: if (bltcon0 & 0x200) bltcpt += 2+blt_info.bltcmod; ! 1571: if (bltcon0 & 0x100) bltdpt += 2+blt_info.bltdmod; 1.1 root 1572: } else { 1573: if (bltcon0 & 0x800) bltapt += 2; 1574: if (bltcon0 & 0x400) bltbpt += 2; 1575: if (bltcon0 & 0x200) bltcpt += 2; 1576: if (bltcon0 & 0x100) bltdpt += 2; 1577: } 1578: } 1579: } 1580: 1.1.1.2 ! root 1581: static __inline__ void blitter_line_incx(void) 1.1 root 1582: { 1583: blinea >>= 1; 1584: if (!blinea) { 1585: blinea = 0x8000; 1586: bltcnxlpt += 2; 1587: bltdnxlpt += 2; 1588: } 1589: } 1590: 1.1.1.2 ! root 1591: static __inline__ void blitter_line_decx(void) 1.1 root 1592: { 1593: blinea <<= 1; 1594: if (!blinea) { 1595: blinea = 1; 1596: bltcnxlpt -= 2; 1597: bltdnxlpt -= 2; 1598: } 1599: } 1600: 1.1.1.2 ! root 1601: static __inline__ void blitter_line_decy(void) 1.1 root 1602: { 1.1.1.2 ! root 1603: bltcnxlpt -= blt_info.bltcmod; ! 1604: bltdnxlpt -= blt_info.bltcmod; /* ??? am I wrong or doesn't KS1.3 set bltdmod? */ 1.1 root 1605: blitonedot = 0; 1606: } 1607: 1.1.1.2 ! root 1608: static __inline__ void blitter_line_incy(void) 1.1 root 1609: { 1.1.1.2 ! root 1610: bltcnxlpt += blt_info.bltcmod; ! 1611: bltdnxlpt += blt_info.bltcmod; /* ??? */ 1.1 root 1612: blitonedot = 0; 1613: } 1614: 1615: static void blitter_line(void) 1616: { 1.1.1.2 ! root 1617: UWORD blitahold = blinea, blitbhold = blineb & 1 ? 0xFFFF : 0, blitchold = blt_info.bltcdat; ! 1618: blt_info.bltddat = 0; 1.1 root 1619: 1620: if (blitsing && blitonedot) blitahold = 0; 1621: blitonedot = 1; 1.1.1.2 ! root 1622: blt_info.bltddat = blit_func(blitahold, blitbhold, blitchold, bltcon0 & 0xFF); 1.1 root 1623: if (!blitsign){ 1.1.1.2 ! root 1624: bltapt += (WORD)blt_info.bltamod; 1.1 root 1625: if (bltcon1 & 0x10){ 1626: if (bltcon1 & 0x8) 1.1.1.2 ! root 1627: blitter_line_decy(); 1.1 root 1628: else 1.1.1.2 ! root 1629: blitter_line_incy(); 1.1 root 1630: } else { 1631: if (bltcon1 & 0x8) 1.1.1.2 ! root 1632: blitter_line_decx(); 1.1 root 1633: else 1.1.1.2 ! root 1634: blitter_line_incx(); 1.1 root 1635: } 1636: } else { 1.1.1.2 ! root 1637: bltapt += (WORD)blt_info.bltbmod; 1.1 root 1638: } 1639: if (bltcon1 & 0x10){ 1640: if (bltcon1 & 0x4) 1.1.1.2 ! root 1641: blitter_line_decx(); 1.1 root 1642: else 1.1.1.2 ! root 1643: blitter_line_incx(); 1.1 root 1644: } else { 1645: if (bltcon1 & 0x4) 1.1.1.2 ! root 1646: blitter_line_decy(); 1.1 root 1647: else 1.1.1.2 ! root 1648: blitter_line_incy(); 1.1 root 1649: } 1650: blitsign = 0 > (WORD)bltapt; 1651: bltstate = BLT_write; 1652: } 1653: 1654: static __inline__ void blitter_nxline(void) 1655: { 1.1.1.2 ! root 1656: bltcpt = bltcnxlpt; ! 1657: bltdpt = bltdnxlpt; ! 1658: blineb = (blineb << 1) | (blineb >> 15); ! 1659: if (--blt_info.vblitsize == 0) { 1.1 root 1660: bltstate = BLT_done; 1.1.1.2 ! root 1661: #if FAST_BLITTER == 0 1.1 root 1662: custom_bank.wput(0xDFF09C,0x8040); 1663: #endif 1664: } else { 1665: bltstate = BLT_read; 1666: } 1667: } 1668: 1669: static void blit_init(void) 1670: { 1671: blitlpos = 0; 1.1.1.2 ! root 1672: blt_info.blitzero = 1; blt_info.blitpreva = blt_info.blitprevb = 0; 1.1 root 1673: blitline = bltcon1 & 1; 1.1.1.2 ! root 1674: blt_info.blitashift = bltcon0 >> 12; blt_info.blitbshift = bltcon1 >> 12; 1.1 root 1675: 1676: if (blitline) { 1.1.1.2 ! root 1677: if (blt_info.hblitsize != 2) ! 1678: fprintf(stderr, "weird hblitsize in linemode: %d\n", blt_info.hblitsize); 1.1 root 1679: bltcnxlpt = bltcpt; 1680: bltdnxlpt = bltdpt; 1681: blitsing = bltcon1 & 0x2; 1.1.1.2 ! root 1682: blinea = blt_info.bltadat >> blt_info.blitashift; ! 1683: blineb = (blt_info.bltbdat >> blt_info.blitbshift) | (blt_info.bltbdat << (16-blt_info.blitbshift)); ! 1684: #if 0 ! 1685: if (blineb != 0xFFFF && blineb != 0) ! 1686: fprintf(stderr, "%x %x %d %x\n", blineb, blt_info.bltbdat, blt_info.blitbshift, bltcon1); ! 1687: #endif 1.1 root 1688: blitsign = bltcon1 & 0x40; 1.1.1.2 ! root 1689: blitonedot = 0; 1.1 root 1690: } else { 1.1.1.2 ! root 1691: blitfc = !!(bltcon1 & 0x4); 1.1 root 1692: blitife = bltcon1 & 0x8; 1693: blitfill = bltcon1 & 0x18; 1694: if ((bltcon1 & 0x18) == 0x18) { 1695: /* Digital "Trash" demo does this; others too. Apparently, no 1696: * negative effects. */ 1.1.1.2 ! root 1697: static int warn = 1; 1.1 root 1698: if (warn) 1699: fprintf(stderr, "warning: weird fill mode (further messages suppressed)\n"); 1.1.1.2 ! root 1700: warn = 0; 1.1 root 1701: } 1702: blitdesc = bltcon1 & 0x2; 1703: if (blitfill && !blitdesc) 1704: fprintf(stderr, "warning: blitter fill without desc\n"); 1705: } 1706: } 1707: 1.1.1.2 ! root 1708: static void actually_do_blit(void) ! 1709: { ! 1710: if (blitline) { ! 1711: do { ! 1712: blitter_read(); ! 1713: blitter_line(); ! 1714: blitter_write(); ! 1715: blitter_nxline(); ! 1716: } while (bltstate != BLT_done); ! 1717: } else { ! 1718: /*blitcount[bltcon0 & 0xff]++; blitter debug */ ! 1719: if (blitdesc) blitter_dofast_desc(); ! 1720: else blitter_dofast(); ! 1721: } ! 1722: } 1.1 root 1723: 1.1.1.2 ! root 1724: #ifdef DEFERRED_INT 1.1 root 1725: static void defer_int_handler(void) 1726: { 1.1.1.2 ! root 1727: if (!dmaen(DMA_BLITTER)) { ! 1728: eventtab[ev_deferint].active = 1; ! 1729: eventtab[ev_deferint].oldcycles = cycles; ! 1730: eventtab[ev_deferint].evtime = 10; /* wait a little */ ! 1731: return; /* gotta come back later. */ ! 1732: } ! 1733: actually_do_blit(); ! 1734: ! 1735: INTREQ(0x8040); ! 1736: eventtab[ev_deferint].active = 0; ! 1737: specialflags &= ~SPCFLAG_BLTNASTY; 1.1 root 1738: } 1739: #endif 1740: 1741: void do_blitter(void) 1742: { 1.1.1.2 ! root 1743: #if FAST_BLITTER == 0 1.1 root 1744: /* I'm not sure all this bltstate stuff is really necessary. 1745: * Most programs should be OK if the blit is done as soon as BLTSIZE is 1746: * written to, and the BLTFINISH bit is set some time after that. 1747: * This code here is nowhere near exact. 1748: */ 1749: do { 1750: switch(bltstate) { 1751: case BLT_init: 1752: blit_init(); 1753: bltstate = BLT_read; 1754: /* fall through */ 1755: case BLT_read: 1756: if (blitter_read()) 1757: break; 1758: /* fall through */ 1759: case BLT_work: 1760: if (blitline) 1761: blitter_line(); 1762: else 1763: blitter_blit(); 1764: /* fall through */ 1765: case BLT_write: 1766: if (blitter_write()) 1767: break; 1768: /* fall through */ 1769: case BLT_next: 1770: if (blitline) 1771: blitter_nxline(); 1772: else 1773: blitter_nxblit(); 1774: break; 1775: case BLT_done: 1776: specialflags &= ~SPCFLAG_BLIT; 1777: break; 1778: } 1779: } while(bltstate != BLT_done && dmaen(DMA_BLITTER) 1780: && dmaen(DMA_BLITPRI)); /* blitter nasty -> no time for CPU */ 1781: #else 1.1.1.2 ! root 1782: { ! 1783: long int blit_cycles = 2; ! 1784: ! 1785: if (!blitline) { ! 1786: if (bltcon0 & 0x400) ! 1787: blit_cycles++; ! 1788: if ((bltcon0 & 0x300) == 0x300) ! 1789: blit_cycles++; ! 1790: blit_cycles *= blt_info.vblitsize * blt_info.hblitsize; ! 1791: } 1.1 root 1792: blit_init(); 1.1.1.2 ! root 1793: ! 1794: eventtab[ev_deferint].active = 1; ! 1795: eventtab[ev_deferint].oldcycles = cycles; ! 1796: eventtab[ev_deferint].evtime = blit_cycles; ! 1797: events_schedule(); 1.1 root 1798: 1.1.1.2 ! root 1799: specialflags &= ~SPCFLAG_BLIT; ! 1800: if (dmaen(DMA_BLITPRI)) ! 1801: specialflags |= SPCFLAG_BLTNASTY; 1.1 root 1802: } 1803: #endif 1804: } 1805: 1.1.1.2 ! root 1806: static void maybe_blit(void) ! 1807: { ! 1808: static int warned = 0; ! 1809: if (bltstate == BLT_done) ! 1810: return; ! 1811: ! 1812: if (!warned) { ! 1813: warned = 1; ! 1814: fprintf(stderr, "warning: Program does not wait for blitter (no further messages)\n"); ! 1815: } ! 1816: if (!eventtab[ev_deferint].active) ! 1817: printf("FOO!!?\n"); ! 1818: actually_do_blit(); ! 1819: eventtab[ev_deferint].active = 0; ! 1820: specialflags &= ~SPCFLAG_BLTNASTY; ! 1821: } ! 1822: ! 1823: static int disk_int_defer = 0; ! 1824: 1.1 root 1825: void do_disk(void) 1826: { 1827: if (dskdmaen > 1 && dmaen(0x10)){ 1828: if (--dsktime == 0) { 1829: dsktime = dskdelay; 1830: if (dsklen & 0x4000){ 1831: UWORD dsksync_check; 1832: DISK_GetData(&dsksync_check, &dskbyte); 1833: dskbyte |= 0x8000; 1834: if (dsksynced || !(adkcon & 0x400)) { 1835: *mfmwrite++ = chipmem_bank.wget(dskpt); dskpt += 2; 1836: if (--dsklength == 0) { 1837: DISK_WriteData(); 1838: custom_bank.wput(0xDFF09C, 0x8002); /*INTREQ->DSKBLK */ 1839: dskdmaen = 0; 1840: specialflags &= ~SPCFLAG_DISK; 1841: } 1842: } 1843: if (dsksync_check == dsksync) { 1844: custom_bank.wput(0xDFF09C, 0x9000); 1.1.1.2 ! root 1845: dsksynced = 1; 1.1 root 1846: } 1847: } else { 1.1.1.2 ! root 1848: #if defined(NO_FAST_DISK) 1.1 root 1849: DISK_GetData(&dskmfm, &dskbyte); 1850: dskbyte |= 0x8000; 1851: if (dsksynced || !(adkcon & 0x400)){ 1852: chipmem_bank.wput(dskpt, dskmfm); dskpt += 2; 1853: if (--dsklength == 0) { 1854: custom_bank.wput(0xDFF09C, 0x8002); 1855: dskdmaen = 0; 1856: specialflags &= ~SPCFLAG_DISK; 1857: } 1858: } 1859: if (dskmfm == dsksync) { 1860: custom_bank.wput(0xDFF09C,0x9000); 1.1.1.2 ! root 1861: dsksynced = 1; 1.1 root 1862: } 1.1.1.2 ! root 1863: #else ! 1864: int ntries = 100000; ! 1865: do { ! 1866: DISK_GetData(&dskmfm, &dskbyte); ! 1867: dskbyte |= 0x8000; ! 1868: if (dsksynced || !(adkcon & 0x400)){ ! 1869: chipmem_bank.wput(dskpt, dskmfm); dskpt += 2; ! 1870: if (--dsklength == 0) { ! 1871: disk_int_defer = 5; ! 1872: dskdmaen = 0; ! 1873: specialflags &= ~SPCFLAG_DISK; ! 1874: } ! 1875: } ! 1876: if (dskmfm == dsksync) { ! 1877: custom_bank.wput(0xDFF09C,0x9000); ! 1878: dsksynced = 1; ! 1879: } ! 1880: } while ((specialflags & SPCFLAG_DISK) && --ntries); ! 1881: #endif 1.1 root 1882: } 1883: } 1884: } 1885: } 1886: 1887: static __inline__ void pfield_fetchdata(void) 1888: { 1889: if (dmaen(0x100) && pfield_linedmaon) { 1890: switch(bplplanecnt){ 1.1.1.2 ! root 1891: case 8: ! 1892: bpl8dat = chipmem_bank.wget(bplpt[7]); bplpt[7] += 2; bpl8dat <<= 7; ! 1893: case 7: ! 1894: bpl7dat = chipmem_bank.wget(bplpt[6]); bplpt[6] += 2; bpl7dat <<= 6; 1.1 root 1895: case 6: 1.1.1.2 ! root 1896: bpl6dat = chipmem_bank.wget(bplpt[5]); bplpt[5] += 2; bpl6dat <<= 5; 1.1 root 1897: case 5: 1.1.1.2 ! root 1898: bpl5dat = chipmem_bank.wget(bplpt[4]); bplpt[4] += 2; bpl5dat <<= 4; 1.1 root 1899: case 4: 1.1.1.2 ! root 1900: bpl4dat = chipmem_bank.wget(bplpt[3]); bplpt[3] += 2; bpl4dat <<= 3; 1.1 root 1901: case 3: 1.1.1.2 ! root 1902: bpl3dat = chipmem_bank.wget(bplpt[2]); bplpt[2] += 2; bpl3dat <<= 2; 1.1 root 1903: case 2: 1.1.1.2 ! root 1904: bpl2dat = chipmem_bank.wget(bplpt[1]); bplpt[1] += 2; bpl2dat <<= 1; 1.1 root 1905: case 1: 1.1.1.2 ! root 1906: bpl1dat = chipmem_bank.wget(bplpt[0]); bplpt[0] += 2; 1.1 root 1907: } 1908: } 1909: } 1910: 1.1.1.2 ! root 1911: static void do_sprites(int currvp, int currhp) 1.1 root 1912: { 1.1.1.2 ! root 1913: int i; ! 1914: int maxspr = currhp/4 -0x18/ 4; ! 1915: ! 1916: if (currvp == 0) ! 1917: return; ! 1918: if (maxspr < 0) ! 1919: return; ! 1920: if (maxspr > 7) ! 1921: maxspr = 7; ! 1922: ! 1923: for(i = last_sprite; i <= maxspr; i++) { ! 1924: int vstart = (bpl_info.sprpos[i] >> 8) | ((bpl_info.sprctl[i] << 6) & 0x100); ! 1925: int vstop = (bpl_info.sprctl[i] >> 8) | ((bpl_info.sprctl[i] << 7) & 0x100); ! 1926: if ((vstart <= currvp && vstop >= currvp) || spron[i] == 1) { 1.1 root 1927: if (dmaen(0x20)) { 1.1.1.2 ! root 1928: UWORD data1 = chipmem_bank.wget(sprpt[i]); ! 1929: UWORD data2 = chipmem_bank.wget(sprpt[i]+2); ! 1930: sprpt[i] += 4; 1.1 root 1931: 1.1.1.2 ! root 1932: if (vstop != currvp && spron[i] != 1) { ! 1933: /* Hack for X mouse auto-calibration */ ! 1934: if (i == 0 && !sprvbfl && ((bpl_info.sprpos[0]&0xff)<<2)>0x60) { ! 1935: int old0ctl = spr0ctl, old0pos = spr0pos; ! 1936: spr0ctl=bpl_info.sprctl[0]; ! 1937: spr0pos=bpl_info.sprpos[0]; ! 1938: sprvbfl=2; 1.1 root 1939: } 1.1.1.2 ! root 1940: SPRxDATB_1(data2, i); ! 1941: SPRxDATA_1(data1, i); 1.1 root 1942: } else { 1.1.1.2 ! root 1943: SPRxPOS_1(data1, i); ! 1944: SPRxCTL_1(data2, i); 1.1 root 1945: } 1946: } 1947: } 1948: } 1.1.1.2 ! root 1949: last_sprite = maxspr + 1; 1.1 root 1950: } 1951: 1.1.1.2 ! root 1952: static __inline__ void pfield_modulos(int add) 1.1 root 1953: { 1954: switch(bplplanecnt){ 1.1.1.2 ! root 1955: case 8: ! 1956: bplpt[7] += add + bpl2mod; ! 1957: case 7: ! 1958: bplpt[6] += add + bpl1mod; 1.1 root 1959: case 6: 1.1.1.2 ! root 1960: bplpt[5] += add + bpl2mod; 1.1 root 1961: case 5: 1.1.1.2 ! root 1962: bplpt[4] += add + bpl1mod; 1.1 root 1963: case 4: 1.1.1.2 ! root 1964: bplpt[3] += add + bpl2mod; 1.1 root 1965: case 3: 1.1.1.2 ! root 1966: bplpt[2] += add + bpl1mod; 1.1 root 1967: case 2: 1.1.1.2 ! root 1968: bplpt[1] += add + bpl2mod; 1.1 root 1969: case 1: 1.1.1.2 ! root 1970: bplpt[0] += add + bpl1mod; ! 1971: } 1.1 root 1972: } 1973: 1.1.1.2 ! root 1974: void pfield_sprite_l (int num, int sprxp, UWORD data, UWORD datb) 1.1 root 1975: { 1.1.1.2 ! root 1976: int i; ! 1977: for(i = 15; i >= 0; i--) { ! 1978: int sprxpos = sprxp + i; ! 1979: if (spixstate[sprxpos] & ((1 << num)-1)) ! 1980: continue; ! 1981: ! 1982: if ((bpl_info.sprctl[num] & 0x80) && (num & 1)) { ! 1983: /* Attached sprite */ ! 1984: int col = ((data << 2) & 4) + ((datb << 3) & 8); ! 1985: if (col) { ! 1986: spixels[sprxpos] = col; ! 1987: spixstate[sprxpos] = 1 << num; 1.1 root 1988: } 1.1.1.2 ! root 1989: spixstate[sprxpos] |= 1 << (num-1); ! 1990: } else { ! 1991: int col = (data & 1) | ((datb << 1) & 2); ! 1992: if (spixstate[sprxpos] & (1 << num)) { ! 1993: /* finish attached sprite */ ! 1994: /* Did the upper half of the sprite have any bits set? */ ! 1995: if (spixstate[sprxpos] & (1 << (num+1))) ! 1996: col += spixels[sprxpos]; ! 1997: if (!col) { ! 1998: spixstate[sprxpos] &= ~(3 << num); 1.1 root 1999: } 1.1.1.2 ! root 2000: } else { ! 2001: if (col) { ! 2002: col |= (num & 6) << 1; 1.1 root 2003: } 2004: } 1.1.1.2 ! root 2005: if (col) { ! 2006: spixels[sprxpos] = col; ! 2007: spixstate[sprxpos] = 1<<num; 1.1 root 2008: } 2009: } 1.1.1.2 ! root 2010: data >>= 1; ! 2011: datb >>= 1; 1.1 root 2012: } 2013: } 2014: 1.1.1.2 ! root 2015: void pfield_sprite_h (int num, int sprxp, UWORD data, UWORD datb) 1.1 root 2016: { 2017: int i; 2018: for(i = 15; i >= 0; i--) { 2019: int sprxpos = sprxp + i*2; 1.1.1.2 ! root 2020: if (spixstate[sprxpos] & ((1 << num)-1)) ! 2021: continue; ! 2022: ! 2023: if ((bpl_info.sprctl[num] & 0x80) && (num & 1)) { 1.1 root 2024: /* Attached sprite */ 2025: int col = ((data << 2) & 4) + ((datb << 3) & 8); 2026: if (col) { 2027: spixels[sprxpos] = col; 2028: spixels[sprxpos+1] = col; 2029: spixstate[sprxpos] = 1 << num; 2030: spixstate[sprxpos+1] = 1 << num; 2031: } 2032: spixstate[sprxpos] |= 1 << (num-1); 2033: spixstate[sprxpos+1] |= 1 << (num-1); 2034: } else { 2035: int col = (data & 1) | ((datb << 1) & 2); 2036: if (spixstate[sprxpos] & (1 << num)) { 2037: /* finish attached sprite */ 2038: /* Did the upper half of the sprite have any bits set? */ 2039: if (spixstate[sprxpos] & (1 << (num+1))) 2040: col += spixels[sprxpos]; 2041: if (!col) { 2042: spixstate[sprxpos] = spixstate[sprxpos+1] &= ~(3 << num); 2043: } 2044: } else { 2045: if (col) { 2046: col |= (num & 6) << 1; 2047: } 2048: } 2049: if (col) { 2050: spixels[sprxpos] = col; 2051: spixels[sprxpos+1] = col; 2052: spixstate[sprxpos] = 1<<num; 2053: spixstate[sprxpos+1] = 1<<num; 2054: } 2055: } 2056: data >>= 1; 2057: datb >>= 1; 2058: } 2059: } 2060: 2061: static __inline__ UWORD *pfield_xlateptr(CPTR plpt, int bytecount) 2062: { 2063: if (!chipmem_bank.check(plpt,bytecount)) { 1.1.1.2 ! root 2064: static int count = 0; ! 2065: if (count < 5) { ! 2066: count++; ! 2067: fprintf(stderr, "Warning: Bad playfield pointer"); ! 2068: if (count == 5) fprintf(stderr, " (no further warnings)"); ! 2069: fprintf(stderr, "\n"); ! 2070: } 1.1 root 2071: return NULL; 2072: } 2073: return chipmem_bank.xlateaddr(plpt); 2074: } 2075: 1.1.1.2 ! root 2076: static void pfield_doline_slow_h(int currhpos) 1.1 root 2077: { 1.1.1.2 ! root 2078: int xpos = currhpos * 4 - 0x60; ! 2079: ! 2080: if (bplhires) { ! 2081: int offs1 = xpos + 16 + bpldelay1*2; ! 2082: int offs2 = xpos + 16 + bpldelay2*2; ! 2083: ! 2084: int pix; ! 2085: for(pix = 15; pix >= 0; pix--) { ! 2086: switch(bplplanecnt) { ! 2087: case 8: ! 2088: pixdata.apixels[pix + offs2] |= bpl8dat & 0x80; bpl8dat >>= 1; ! 2089: case 7: ! 2090: pixdata.apixels[pix + offs1] |= bpl7dat & 0x40; bpl7dat >>= 1; ! 2091: case 6: ! 2092: pixdata.apixels[pix + offs2] |= bpl6dat & 0x20; bpl6dat >>= 1; ! 2093: case 5: ! 2094: pixdata.apixels[pix + offs1] |= bpl5dat & 0x10; bpl5dat >>= 1; ! 2095: case 4: ! 2096: pixdata.apixels[pix + offs2] |= bpl4dat & 0x8; bpl4dat >>= 1; ! 2097: case 3: ! 2098: pixdata.apixels[pix + offs1] |= bpl3dat & 0x4; bpl3dat >>= 1; ! 2099: case 2: ! 2100: pixdata.apixels[pix + offs2] |= bpl2dat & 0x2; bpl2dat >>= 1; ! 2101: case 1: ! 2102: pixdata.apixels[pix + offs1] |= bpl1dat & 0x1; bpl1dat >>= 1; ! 2103: } ! 2104: } ! 2105: } else { ! 2106: int offs1 = xpos + 32 + bpldelay1*2; ! 2107: int offs2 = xpos + 32 + bpldelay2*2; ! 2108: ! 2109: int pix; ! 2110: for(pix = 30; pix >= 0; pix -= 2) { ! 2111: switch(bplplanecnt) { ! 2112: case 8: ! 2113: pixdata.apixels[pix + offs2] |= bpl8dat & 0x80; ! 2114: pixdata.apixels[pix + offs2 + 1] |= bpl8dat & 0x80; bpl8dat >>= 1; ! 2115: case 7: ! 2116: pixdata.apixels[pix + offs1] |= bpl7dat & 0x40; ! 2117: pixdata.apixels[pix + offs1 + 1] |= bpl7dat & 0x40; bpl7dat >>= 1; ! 2118: case 6: ! 2119: pixdata.apixels[pix + offs2] |= bpl6dat & 0x20; ! 2120: pixdata.apixels[pix + offs2 + 1] |= bpl6dat & 0x20; bpl6dat >>= 1; ! 2121: case 5: ! 2122: pixdata.apixels[pix + offs1] |= bpl5dat & 0x10; ! 2123: pixdata.apixels[pix + offs1 + 1] |= bpl5dat & 0x10; bpl5dat >>= 1; ! 2124: case 4: ! 2125: pixdata.apixels[pix + offs2] |= bpl4dat & 0x8; ! 2126: pixdata.apixels[pix + offs2 + 1] |= bpl4dat & 0x8; bpl4dat >>= 1; ! 2127: case 3: ! 2128: pixdata.apixels[pix + offs1] |= bpl3dat & 0x4; ! 2129: pixdata.apixels[pix + offs1 + 1] |= bpl3dat & 0x4; bpl3dat >>= 1; ! 2130: case 2: ! 2131: pixdata.apixels[pix + offs2] |= bpl2dat & 0x2; ! 2132: pixdata.apixels[pix + offs2 + 1] |= bpl2dat & 0x2; bpl2dat >>= 1; ! 2133: case 1: ! 2134: pixdata.apixels[pix + offs1] |= bpl1dat & 0x1; ! 2135: pixdata.apixels[pix + offs1 + 1] |= bpl1dat & 0x1; bpl1dat >>= 1; ! 2136: } ! 2137: } ! 2138: } ! 2139: } ! 2140: ! 2141: static void pfield_doline_slow_l(int currhpos) ! 2142: { ! 2143: int xpos = currhpos * 2 - 0x30; ! 2144: ! 2145: if (bplhires) { ! 2146: int offs1 = xpos + 8 + bpldelay1; ! 2147: int offs2 = xpos + 8 + bpldelay2; ! 2148: ! 2149: int pix; ! 2150: for(pix = 7; pix >= 0; pix--) { ! 2151: switch(bplplanecnt) { ! 2152: case 8: ! 2153: pixdata.apixels[pix + offs2] |= bpl8dat & 0x80; bpl8dat >>= 2; ! 2154: case 7: ! 2155: pixdata.apixels[pix + offs1] |= bpl7dat & 0x40; bpl7dat >>= 2; ! 2156: case 6: ! 2157: pixdata.apixels[pix + offs2] |= bpl6dat & 0x20; bpl6dat >>= 2; ! 2158: case 5: ! 2159: pixdata.apixels[pix + offs1] |= bpl5dat & 0x10; bpl5dat >>= 2; ! 2160: case 4: ! 2161: pixdata.apixels[pix + offs2] |= bpl4dat & 0x8; bpl4dat >>= 2; ! 2162: case 3: ! 2163: pixdata.apixels[pix + offs1] |= bpl3dat & 0x4; bpl3dat >>= 2; ! 2164: case 2: ! 2165: pixdata.apixels[pix + offs2] |= bpl2dat & 0x2; bpl2dat >>= 2; ! 2166: case 1: ! 2167: pixdata.apixels[pix + offs1] |= bpl1dat & 0x1; bpl1dat >>= 2; ! 2168: } ! 2169: } ! 2170: } else { ! 2171: int offs1 = xpos + 16 + bpldelay1; ! 2172: int offs2 = xpos + 16 + bpldelay2; ! 2173: ! 2174: int pix; ! 2175: for(pix = 15; pix >= 0; pix --) { ! 2176: switch(bplplanecnt) { ! 2177: case 8: ! 2178: pixdata.apixels[pix + offs2] |= bpl8dat & 0x80; bpl8dat >>= 1; ! 2179: case 7: ! 2180: pixdata.apixels[pix + offs1] |= bpl7dat & 0x40; bpl7dat >>= 1; ! 2181: case 6: ! 2182: pixdata.apixels[pix + offs2] |= bpl6dat & 0x20; bpl6dat >>= 1; ! 2183: case 5: ! 2184: pixdata.apixels[pix + offs1] |= bpl5dat & 0x10; bpl5dat >>= 1; ! 2185: case 4: ! 2186: pixdata.apixels[pix + offs2] |= bpl4dat & 0x8; bpl4dat >>= 1; ! 2187: case 3: ! 2188: pixdata.apixels[pix + offs1] |= bpl3dat & 0x4; bpl3dat >>= 1; ! 2189: case 2: ! 2190: pixdata.apixels[pix + offs2] |= bpl2dat & 0x2; bpl2dat >>= 1; ! 2191: case 1: ! 2192: pixdata.apixels[pix + offs1] |= bpl1dat & 0x1; bpl1dat >>= 1; ! 2193: } ! 2194: } ! 2195: } 1.1 root 2196: } 2197: 1.1.1.2 ! root 2198: ULONG hirestab_h[256][2]; ! 2199: ULONG lorestab_h[256][4]; ! 2200: ! 2201: ULONG hirestab_l[256][1]; ! 2202: ULONG lorestab_l[256][2]; ! 2203: ! 2204: static void gen_pfield_tables(void) ! 2205: { ! 2206: int i; ! 2207: union { ! 2208: struct { ! 2209: UBYTE a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p; ! 2210: } foo; ! 2211: struct { ! 2212: ULONG a, b, c, d; ! 2213: } bar; ! 2214: } baz; ! 2215: ! 2216: for (i = 0; i < 256; i++) { ! 2217: /* We lose every second pixel in HiRes if UAE runs in a 320x200 screen. */ ! 2218: baz.foo.a = i & 64 ? 1 : 0; ! 2219: baz.foo.b = i & 16 ? 1 : 0; ! 2220: baz.foo.c = i & 4 ? 1 : 0; ! 2221: baz.foo.d = i & 1 ? 1 : 0; ! 2222: hirestab_l[i][0] = baz.bar.a; ! 2223: ! 2224: baz.foo.a = i & 128 ? 1 : 0; ! 2225: baz.foo.b = i & 64 ? 1 : 0; ! 2226: baz.foo.c = i & 32 ? 1 : 0; ! 2227: baz.foo.d = i & 16 ? 1 : 0; ! 2228: baz.foo.e = i & 8 ? 1 : 0; ! 2229: baz.foo.f = i & 4 ? 1 : 0; ! 2230: baz.foo.g = i & 2 ? 1 : 0; ! 2231: baz.foo.h = i & 1 ? 1 : 0; ! 2232: lorestab_l[i][0] = baz.bar.a; ! 2233: lorestab_l[i][1] = baz.bar.b; ! 2234: } ! 2235: ! 2236: for (i = 0; i < 256; i++) { ! 2237: baz.foo.a = i & 128 ? 1 : 0; ! 2238: baz.foo.b = i & 64 ? 1 : 0; ! 2239: baz.foo.c = i & 32 ? 1 : 0; ! 2240: baz.foo.d = i & 16 ? 1 : 0; ! 2241: baz.foo.e = i & 8 ? 1 : 0; ! 2242: baz.foo.f = i & 4 ? 1 : 0; ! 2243: baz.foo.g = i & 2 ? 1 : 0; ! 2244: baz.foo.h = i & 1 ? 1 : 0; ! 2245: hirestab_h[i][0] = baz.bar.a; ! 2246: hirestab_h[i][1] = baz.bar.b; ! 2247: ! 2248: baz.foo.a = i & 128 ? 1 : 0; ! 2249: baz.foo.b = i & 128 ? 1 : 0; ! 2250: baz.foo.c = i & 64 ? 1 : 0; ! 2251: baz.foo.d = i & 64 ? 1 : 0; ! 2252: baz.foo.e = i & 32 ? 1 : 0; ! 2253: baz.foo.f = i & 32 ? 1 : 0; ! 2254: baz.foo.g = i & 16 ? 1 : 0; ! 2255: baz.foo.h = i & 16 ? 1 : 0; ! 2256: baz.foo.i = i & 8 ? 1 : 0; ! 2257: baz.foo.j = i & 8 ? 1 : 0; ! 2258: baz.foo.k = i & 4 ? 1 : 0; ! 2259: baz.foo.l = i & 4 ? 1 : 0; ! 2260: baz.foo.m = i & 2 ? 1 : 0; ! 2261: baz.foo.n = i & 2 ? 1 : 0; ! 2262: baz.foo.o = i & 1 ? 1 : 0; ! 2263: baz.foo.p = i & 1 ? 1 : 0; ! 2264: lorestab_h[i][0] = baz.bar.a; ! 2265: lorestab_h[i][1] = baz.bar.b; ! 2266: lorestab_h[i][2] = baz.bar.c; ! 2267: lorestab_h[i][3] = baz.bar.d; ! 2268: } ! 2269: } ! 2270: ! 2271: static __inline__ void pfield_orword_hires_h(int data, unsigned char *dp, int bit) ! 2272: { ! 2273: ULONG *pixptr = (ULONG *)dp; ! 2274: ! 2275: *pixptr |= hirestab_h[data >> 8][0] << bit; ! 2276: *(pixptr+1) |= hirestab_h[data >> 8][1] << bit; ! 2277: *(pixptr+2) |= hirestab_h[data & 255][0] << bit; ! 2278: *(pixptr+3) |= hirestab_h[data & 255][1] << bit; ! 2279: } ! 2280: ! 2281: static __inline__ void pfield_orword_lores_h(int data, unsigned char *dp, int bit) ! 2282: { ! 2283: ULONG *pixptr = (ULONG *)dp; ! 2284: ! 2285: *pixptr |= lorestab_h[data >> 8][0] << bit; ! 2286: *(pixptr+1) |= lorestab_h[data >> 8][1] << bit; ! 2287: *(pixptr+2) |= lorestab_h[data >> 8][2] << bit; ! 2288: *(pixptr+3) |= lorestab_h[data >> 8][3] << bit; ! 2289: *(pixptr+4) |= lorestab_h[data & 255][0] << bit; ! 2290: *(pixptr+5) |= lorestab_h[data & 255][1] << bit; ! 2291: *(pixptr+6) |= lorestab_h[data & 255][2] << bit; ! 2292: *(pixptr+7) |= lorestab_h[data & 255][3] << bit; ! 2293: } ! 2294: ! 2295: static __inline__ void pfield_setword_hires_h(int data, unsigned char *dp, int bit) ! 2296: { ! 2297: ULONG *pixptr = (ULONG *)dp; ! 2298: ! 2299: *pixptr = hirestab_h[data >> 8][0] << bit; ! 2300: *(pixptr+1) = hirestab_h[data >> 8][1] << bit; ! 2301: *(pixptr+2) = hirestab_h[data & 255][0] << bit; ! 2302: *(pixptr+3) = hirestab_h[data & 255][1] << bit; ! 2303: } ! 2304: ! 2305: static __inline__ void pfield_setword_lores_h(int data, unsigned char *dp, int bit) ! 2306: { ! 2307: ULONG *pixptr = (ULONG *)dp; ! 2308: ! 2309: *pixptr = lorestab_h[data >> 8][0] << bit; ! 2310: *(pixptr+1) = lorestab_h[data >> 8][1] << bit; ! 2311: *(pixptr+2) = lorestab_h[data >> 8][2] << bit; ! 2312: *(pixptr+3) = lorestab_h[data >> 8][3] << bit; ! 2313: *(pixptr+4) = lorestab_h[data & 255][0] << bit; ! 2314: *(pixptr+5) = lorestab_h[data & 255][1] << bit; ! 2315: *(pixptr+6) = lorestab_h[data & 255][2] << bit; ! 2316: *(pixptr+7) = lorestab_h[data & 255][3] << bit; ! 2317: } ! 2318: ! 2319: static __inline__ void pfield_orword_hires_l(int data, unsigned char *dp, int bit) ! 2320: { ! 2321: ULONG *pixptr = (ULONG *)dp; ! 2322: ! 2323: *pixptr |= hirestab_l[data >> 8][0] << bit; ! 2324: *(pixptr+1) |= hirestab_l[data & 255][0] << bit; ! 2325: } ! 2326: ! 2327: static __inline__ void pfield_orword_lores_l(int data, unsigned char *dp, int bit) ! 2328: { ! 2329: ULONG *pixptr = (ULONG *)dp; ! 2330: ! 2331: *pixptr |= lorestab_l[data >> 8][0] << bit; ! 2332: *(pixptr+1) |= lorestab_l[data >> 8][1] << bit; ! 2333: *(pixptr+2) |= lorestab_l[data & 255][0] << bit; ! 2334: *(pixptr+3) |= lorestab_l[data & 255][1] << bit; ! 2335: } ! 2336: ! 2337: static __inline__ void pfield_setword_hires_l(int data, unsigned char *dp, int bit) ! 2338: { ! 2339: ULONG *pixptr = (ULONG *)dp; ! 2340: ! 2341: *pixptr = hirestab_l[data >> 8][0] << bit; ! 2342: *(pixptr+1) = hirestab_l[data & 255][0] << bit; ! 2343: } ! 2344: ! 2345: static __inline__ void pfield_setword_lores_l(int data, unsigned char *dp, int bit) ! 2346: { ! 2347: ULONG *pixptr = (ULONG *)dp; ! 2348: ! 2349: *pixptr = lorestab_l[data >> 8][0] << bit; ! 2350: *(pixptr+1) = lorestab_l[data >> 8][1] << bit; ! 2351: *(pixptr+2) = lorestab_l[data & 255][0] << bit; ! 2352: *(pixptr+3) = lorestab_l[data & 255][1] << bit; ! 2353: } ! 2354: ! 2355: #define DO_ONE_PLANE(POINTER, MULT, FUNC, DELAY, LL_SUB, P_ADD) { \ ! 2356: int i; \ ! 2357: unsigned int bpldat1; \ ! 2358: UWORD data; \ ! 2359: unsigned int bpldat2 = 0; \ ! 2360: for (i = plflinelen; i > 0; i -= LL_SUB) { \ ! 2361: bpldat1 = bpldat2; \ ! 2362: bpldat2 = *POINTER++; \ ! 2363: data = (bpldat1 << (16 - DELAY)) | (bpldat2 >> DELAY); \ ! 2364: FUNC(data, app, MULT); \ ! 2365: app += P_ADD; \ ! 2366: } \ ! 2367: data = bpldat2 << (16 - DELAY); \ ! 2368: FUNC(data, app, MULT); \ ! 2369: } ! 2370: ! 2371: #define DO_ONE_PLANE_B_LORES_H(NUM, FETCH) \ ! 2372: if (bplplanecnt > NUM) { \ ! 2373: if (FETCH != 0) { \ ! 2374: plfd[NUM] <<= 16; \ ! 2375: if (FETCH == 1) \ ! 2376: plfd[NUM] |= *(r_bplpt[NUM])++ << delay[NUM & 1]; \ ! 2377: d = plfd[NUM] >> 24; \ ! 2378: } else {\ ! 2379: d = (plfd[NUM] >> 16) & 255; \ ! 2380: }\ ! 2381: if (NUM == 0) { \ ! 2382: data1 = lorestab_h[d][0] << NUM;\ ! 2383: data2 = lorestab_h[d][1] << NUM;\ ! 2384: data3 = lorestab_h[d][2] << NUM;\ ! 2385: data4 = lorestab_h[d][3] << NUM;\ ! 2386: } else { \ ! 2387: data1 |= lorestab_h[d][0] << NUM;\ ! 2388: data2 |= lorestab_h[d][1] << NUM;\ ! 2389: data3 |= lorestab_h[d][2] << NUM;\ ! 2390: data4 |= lorestab_h[d][3] << NUM;\ ! 2391: } \ ! 2392: } ! 2393: ! 2394: #if 1 ! 2395: static void pfield_doline_h(void) 1.1 root 2396: { 2397: int xpos = plfstrt * 4 - 0x60; 2398: int spr; 2399: 1.1.1.2 ! root 2400: if (bplhires) { ! 2401: if (bplplanecnt > 0) { ! 2402: int xpos1 = xpos + 16 + (bpldelay1 >= 8 ? 16 : 0); ! 2403: int xpos2 = xpos + 16 + (bpldelay2 >= 8 ? 16 : 0); ! 2404: int delay1 = 2*(bpldelay1 & 7); ! 2405: int delay2 = 2*(bpldelay2 & 7); ! 2406: unsigned char *app = pixdata.apixels + xpos1; ! 2407: ! 2408: DO_ONE_PLANE(r_bplpt[0], 0, pfield_setword_hires_h, delay1, 4, 16); ! 2409: if (bplplanecnt > 2) { ! 2410: app = pixdata.apixels + xpos1; ! 2411: DO_ONE_PLANE(r_bplpt[2], 2, pfield_orword_hires_h, delay1, 4, 16); ! 2412: } ! 2413: #if AGA_CHIPSET == 1 ! 2414: if (bplplanecnt > 4) { ! 2415: app = pixdata.apixels + xpos1; ! 2416: DO_ONE_PLANE(r_bplpt[4], 4, pfield_orword_hires_h, delay1, 4, 16); ! 2417: } ! 2418: if (bplplanecnt > 6) { ! 2419: app = pixdata.apixels + xpos1; ! 2420: DO_ONE_PLANE(r_bplpt[6], 6, pfield_orword_hires_h, delay1, 4, 16); ! 2421: } ! 2422: #endif ! 2423: if (bplplanecnt > 1) { ! 2424: app = pixdata.apixels + xpos2; ! 2425: DO_ONE_PLANE(r_bplpt[1], 1, pfield_orword_hires_h, delay2, 4, 16); ! 2426: } ! 2427: if (bplplanecnt > 3) { ! 2428: app = pixdata.apixels + xpos2; ! 2429: DO_ONE_PLANE(r_bplpt[3], 3, pfield_orword_hires_h, delay2, 4, 16); ! 2430: } ! 2431: #if AGA_CHIPSET == 1 ! 2432: if (bplplanecnt > 5) { ! 2433: app = pixdata.apixels + xpos2; ! 2434: DO_ONE_PLANE(r_bplpt[5], 5, pfield_orword_hires_h, delay2, 4, 16); ! 2435: } ! 2436: if (bplplanecnt > 7) { ! 2437: app = pixdata.apixels + xpos2; ! 2438: DO_ONE_PLANE(r_bplpt[7], 7, pfield_orword_hires_h, delay2, 4, 16); ! 2439: } ! 2440: #endif ! 2441: } else { ! 2442: memset(pixdata.apixels, 0, sizeof(pixdata.apixels)); ! 2443: } ! 2444: } else { ! 2445: if (bplplanecnt > 0) { ! 2446: int x = xpos + 32; ! 2447: unsigned char *app = pixdata.apixels + x; ! 2448: #if 0 /* Fun things to do in the future */ ! 2449: int delay[2]; ! 2450: int len; ! 2451: ULONG plfd[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; ! 2452: ULONG *ptr = (ULONG *)app; ! 2453: ULONG d; ! 2454: ULONG data, data1, data2, data3, data4; ! 2455: delay[0] = 16 - bpldelay1; delay[1] = 16 - bpldelay2; ! 2456: ! 2457: for (len = plflinelen; len > 0; len -= 8, ptr+=8) { ! 2458: DO_ONE_PLANE_B_LORES_H(0,1); ! 2459: DO_ONE_PLANE_B_LORES_H(1,1); ! 2460: DO_ONE_PLANE_B_LORES_H(2,1); ! 2461: DO_ONE_PLANE_B_LORES_H(3,1); ! 2462: DO_ONE_PLANE_B_LORES_H(4,1); ! 2463: DO_ONE_PLANE_B_LORES_H(5,1); ! 2464: *ptr = data1; *(ptr+1) = data2; *(ptr+2) = data3; *(ptr+3) = data4; ! 2465: ! 2466: DO_ONE_PLANE_B_LORES_H(0,0); ! 2467: DO_ONE_PLANE_B_LORES_H(1,0); ! 2468: DO_ONE_PLANE_B_LORES_H(2,0); ! 2469: DO_ONE_PLANE_B_LORES_H(3,0); ! 2470: DO_ONE_PLANE_B_LORES_H(4,0); ! 2471: DO_ONE_PLANE_B_LORES_H(5,0); ! 2472: *(ptr+4) = data1; *(ptr+5) = data2; *(ptr+6) = data3; *(ptr+7) = data4; ! 2473: } ! 2474: DO_ONE_PLANE_B_LORES_H(0,2); ! 2475: DO_ONE_PLANE_B_LORES_H(1,2); ! 2476: DO_ONE_PLANE_B_LORES_H(2,2); ! 2477: DO_ONE_PLANE_B_LORES_H(3,2); ! 2478: DO_ONE_PLANE_B_LORES_H(4,2); ! 2479: DO_ONE_PLANE_B_LORES_H(5,2); ! 2480: *ptr = data1; *(ptr+1) = data2; *(ptr+2) = data3; *(ptr+3) = data4; ! 2481: ! 2482: DO_ONE_PLANE_B_LORES_H(0,0); ! 2483: DO_ONE_PLANE_B_LORES_H(1,0); ! 2484: DO_ONE_PLANE_B_LORES_H(2,0); ! 2485: DO_ONE_PLANE_B_LORES_H(3,0); ! 2486: DO_ONE_PLANE_B_LORES_H(4,0); ! 2487: DO_ONE_PLANE_B_LORES_H(5,0); ! 2488: *(ptr+4) = data1; *(ptr+5) = data2; *(ptr+6) = data3; *(ptr+7) = data4; ! 2489: #else ! 2490: DO_ONE_PLANE(r_bplpt[0], 0, pfield_setword_lores_h, bpldelay1, 8, 32); ! 2491: if (bplplanecnt > 2) { ! 2492: app = pixdata.apixels + x; ! 2493: DO_ONE_PLANE(r_bplpt[2], 2, pfield_orword_lores_h, bpldelay1, 8, 32); ! 2494: } ! 2495: if (bplplanecnt > 4) { ! 2496: app = pixdata.apixels + x; ! 2497: DO_ONE_PLANE(r_bplpt[4], 4, pfield_orword_lores_h, bpldelay1, 8, 32); ! 2498: } ! 2499: #if AGA_CHIPSET == 1 ! 2500: if (bplplanecnt > 6) { ! 2501: app = pixdata.apixels + x; ! 2502: DO_ONE_PLANE(r_bplpt[6], 6, pfield_orword_lores_h, bpldelay1, 8, 32); ! 2503: } ! 2504: #endif ! 2505: if (bplplanecnt > 1) { ! 2506: app = pixdata.apixels + x; ! 2507: DO_ONE_PLANE(r_bplpt[1], 1, pfield_orword_lores_h, bpldelay2, 8, 32); ! 2508: } ! 2509: if (bplplanecnt > 3) { ! 2510: app = pixdata.apixels + x; ! 2511: DO_ONE_PLANE(r_bplpt[3], 3, pfield_orword_lores_h, bpldelay2, 8, 32); ! 2512: } ! 2513: if (bplplanecnt > 5) { ! 2514: app = pixdata.apixels + x; ! 2515: DO_ONE_PLANE(r_bplpt[5], 5, pfield_orword_lores_h, bpldelay2, 8, 32); ! 2516: } ! 2517: #if AGA_CHIPSET == 1 ! 2518: if (bplplanecnt > 7) { ! 2519: app = pixdata.apixels + x; ! 2520: DO_ONE_PLANE(r_bplpt[7], 7, pfield_orword_lores_h, bpldelay2, 8, 32); ! 2521: } ! 2522: #endif ! 2523: #endif ! 2524: } else { ! 2525: memset(pixdata.apixels, 0, sizeof(pixdata.apixels)); ! 2526: } ! 2527: } ! 2528: ! 2529: linetoscreen = 1; 1.1 root 2530: 1.1.1.2 ! root 2531: for(spr = 7; spr >= 0; spr--) { ! 2532: if (bpl_info.sprarmed[spr]) { ! 2533: int sprxp = ((bpl_info.sprpos[spr] & 0xFF) * 4) - 0x60 + (bpl_info.sprctl[spr] & 1)*2; ! 2534: int i; ! 2535: /* Ugh. Nasty bug. Let's rather lose some sprites than trash ! 2536: * memory. */ ! 2537: if (sprxp >= 0) ! 2538: pfield_sprite_h (spr, sprxp, bpl_info.sprdata[spr], bpl_info.sprdatb[spr]); 1.1 root 2539: } 1.1.1.2 ! root 2540: } ! 2541: } ! 2542: #endif ! 2543: static void pfield_doline_l(void) ! 2544: { ! 2545: int xpos = plfstrt * 2 - 0x30; ! 2546: int spr; ! 2547: ! 2548: if (bplhires) { ! 2549: if (bplplanecnt > 0) { ! 2550: int xpos1 = xpos + 8 + (bpldelay1 >= 8 ? 8 : 0); ! 2551: int xpos2 = xpos + 8 + (bpldelay2 >= 8 ? 8 : 0); ! 2552: int delay1 = (bpldelay1 & 7) * 2; ! 2553: int delay2 = (bpldelay2 & 7) * 2; ! 2554: unsigned char *app = pixdata.apixels + xpos1; ! 2555: ! 2556: DO_ONE_PLANE(r_bplpt[0], 0, pfield_setword_hires_l, delay1, 4, 8); ! 2557: if (bplplanecnt > 2) { ! 2558: app = pixdata.apixels + xpos1; ! 2559: DO_ONE_PLANE(r_bplpt[2], 2, pfield_orword_hires_l, delay1, 4, 8); ! 2560: } ! 2561: #if AGA_CHIPSET == 1 ! 2562: if (bplplanecnt > 4) { ! 2563: app = pixdata.apixels + xpos1; ! 2564: DO_ONE_PLANE(r_bplpt[4], 4, pfield_orword_hires_l, delay1, 4, 8); ! 2565: } ! 2566: if (bplplanecnt > 6) { ! 2567: app = pixdata.apixels + xpos1; ! 2568: DO_ONE_PLANE(r_bplpt[6], 6, pfield_orword_hires_l, delay1, 4, 8); ! 2569: } ! 2570: #endif ! 2571: if (bplplanecnt > 1) { ! 2572: app = pixdata.apixels + xpos2; ! 2573: DO_ONE_PLANE(r_bplpt[1], 1, pfield_orword_hires_l, delay2, 4, 8); ! 2574: } ! 2575: if (bplplanecnt > 3) { ! 2576: app = pixdata.apixels + xpos2; ! 2577: DO_ONE_PLANE(r_bplpt[3], 3, pfield_orword_hires_l, delay2, 4, 8); ! 2578: } ! 2579: #if AGA_CHIPSET == 1 ! 2580: if (bplplanecnt > 5) { ! 2581: app = pixdata.apixels + xpos2; ! 2582: DO_ONE_PLANE(r_bplpt[5], 5, pfield_orword_hires_l, delay2, 4, 8); ! 2583: } ! 2584: if (bplplanecnt > 7) { ! 2585: app = pixdata.apixels + xpos2; ! 2586: DO_ONE_PLANE(r_bplpt[7], 7, pfield_orword_hires_l, delay2, 4, 8); 1.1 root 2587: } 1.1.1.2 ! root 2588: #endif 1.1 root 2589: } else { 1.1.1.2 ! root 2590: memset(pixdata.apixels, 0, sizeof(pixdata.apixels)); ! 2591: } ! 2592: } else { ! 2593: if (bplplanecnt > 0) { ! 2594: int x = xpos + 16; ! 2595: int delay1 = bpldelay1; ! 2596: int delay2 = bpldelay2; ! 2597: unsigned char *app = pixdata.apixels + x; ! 2598: DO_ONE_PLANE(r_bplpt[0], 0, pfield_setword_lores_l, delay1, 8, 16); ! 2599: if (bplplanecnt > 2) { ! 2600: app = pixdata.apixels + x; ! 2601: DO_ONE_PLANE(r_bplpt[2], 2, pfield_orword_lores_l, delay1, 8, 16); ! 2602: } ! 2603: if (bplplanecnt > 4) { ! 2604: app = pixdata.apixels + x; ! 2605: DO_ONE_PLANE(r_bplpt[4], 4, pfield_orword_lores_l, delay1, 8, 16); ! 2606: } ! 2607: #if AGA_CHIPSET == 1 ! 2608: if (bplplanecnt > 6) { ! 2609: app = pixdata.apixels + x; ! 2610: DO_ONE_PLANE(r_bplpt[6], 6, pfield_orword_lores_l, delay1, 8, 16); ! 2611: } ! 2612: #endif ! 2613: if (bplplanecnt > 1) { ! 2614: app = pixdata.apixels + x; ! 2615: DO_ONE_PLANE(r_bplpt[1], 1, pfield_orword_lores_l, delay2, 8, 16); ! 2616: } ! 2617: if (bplplanecnt > 3) { ! 2618: app = pixdata.apixels + x; ! 2619: DO_ONE_PLANE(r_bplpt[3], 3, pfield_orword_lores_l, delay2, 8, 16); ! 2620: } ! 2621: if (bplplanecnt > 5) { ! 2622: app = pixdata.apixels + x; ! 2623: DO_ONE_PLANE(r_bplpt[5], 5, pfield_orword_lores_l, delay2, 8, 16); ! 2624: } ! 2625: #if AGA_CHIPSET == 1 ! 2626: if (bplplanecnt > 7) { ! 2627: app = pixdata.apixels + x; ! 2628: DO_ONE_PLANE(r_bplpt[7], 7, pfield_orword_lores_l, delay2, 8, 16); 1.1 root 2629: } 1.1.1.2 ! root 2630: #endif ! 2631: } else { ! 2632: memset(pixdata.apixels, 0, sizeof(pixdata.apixels)); 1.1 root 2633: } 2634: } 1.1.1.2 ! root 2635: ! 2636: linetoscreen = 1; ! 2637: 1.1 root 2638: for(spr = 7; spr >= 0; spr--) { 1.1.1.2 ! root 2639: if (bpl_info.sprarmed[spr]) { ! 2640: int sprxp = ((bpl_info.sprpos[spr] & 0xFF) * 2) - 0x30 + (bpl_info.sprctl[spr] & 1); 1.1 root 2641: int i; 2642: /* Ugh. Nasty bug. Let's rather lose some sprites than trash 2643: * memory. */ 1.1.1.2 ! root 2644: if (sprxp >= 0) ! 2645: pfield_sprite_l (spr, sprxp, bpl_info.sprdata[spr], bpl_info.sprdatb[spr]); 1.1 root 2646: } 2647: } 1.1.1.2 ! root 2648: } ! 2649: ! 2650: static int bpl_data_differs(UWORD *data, UWORD *r_addr, int nbytes) ! 2651: { ! 2652: return memcmpy(data, r_addr, nbytes); ! 2653: } ! 2654: ! 2655: static __inline__ int bplinfo_differs(struct bplinfo *a, struct bplinfo *b) ! 2656: { ! 2657: int ncolors; ! 2658: int i; ! 2659: if (a->bplcon0 != b->bplcon0 ! 2660: || a->bplcon1 != b->bplcon1 ! 2661: || a->bplcon2 != b->bplcon2 ! 2662: || a->bplcon3 != b->bplcon3 ! 2663: || a->bplcon4 != b->bplcon4 ! 2664: || a->diwstrt != b->diwstrt ! 2665: || a->diwstop != b->diwstop ! 2666: || a->ddfstrt != b->ddfstrt ! 2667: || a->ddfstop != b->ddfstop) ! 2668: return 1; ! 2669: ! 2670: #if 1 ! 2671: /* This sometimes loses for sprite colors */ ! 2672: ncolors = 1 << ((a->bplcon0 & 0x7000) >> 12); ! 2673: if (ncolors == 64) ! 2674: ncolors = (a->bplcon0 & 0x800) ? 16 : 32; ! 2675: for (i = 0; i < ncolors; i++) ! 2676: if (a->color_regs[i] != b->color_regs[i]) ! 2677: return 1; ! 2678: #else ! 2679: /* ... and this will lose badly on few-color screens when we implement ! 2680: * AGA. ! 2681: */ ! 2682: if (memcmp(a->color_regs, b->color_regs, sizeof a->color_regs) != 0) ! 2683: return 1; ! 2684: #endif ! 2685: for (i = 0; i < 8; i++) { ! 2686: if (a->sprarmed[i] != b->sprarmed[i]) ! 2687: return 1; ! 2688: if (a->sprarmed[i] ! 2689: && (a->sprctl[i] != b->sprctl[i] ! 2690: || a->sprpos[i] != b->sprpos[i] ! 2691: || a->sprdata[i] != b->sprdata[i] ! 2692: || a->sprdatb[i] != b->sprdatb[i])) ! 2693: return 1; ! 2694: } ! 2695: return 0; ! 2696: } ! 2697: ! 2698: static void pfield_doline(void) ! 2699: { ! 2700: int bytecount = plflinelen / (bplhires ? 4 : 8) * 2; ! 2701: int drawit = 0; ! 2702: int i; ! 2703: ! 2704: if (vpos < plffirstline || vpos >= plflastline) ! 2705: return; ! 2706: ! 2707: if (!dmaen(0x100) || !pfield_linedmaon) { ! 2708: line_in_border = 1; ! 2709: return; ! 2710: } 1.1 root 2711: 1.1.1.2 ! root 2712: for (i = 0; i < bplplanecnt; i++) { ! 2713: r_bplpt[i] = pfield_xlateptr(bplpt[i], bytecount); ! 2714: if (r_bplpt[i] == NULL) ! 2715: return; ! 2716: } ! 2717: ! 2718: #if SMART_UPDATE == 1 ! 2719: drawit = bplinfo_differs(&bpl_info, &linedescr[next_lineno].bpl_info); ! 2720: if (drawit) { ! 2721: linedescr[next_lineno].bpl_info = bpl_info; ! 2722: } ! 2723: drawit |= !linedescr[next_lineno].linedata_valid; ! 2724: ! 2725: if (bytecount <= MAX_WORDS_PER_LINE * 2) { ! 2726: linedescr[next_lineno].linedata_valid = 1; ! 2727: for (i = 0; i < bplplanecnt; i++) ! 2728: drawit |= bpl_data_differs(line_data[next_lineno][i],r_bplpt[i], ! 2729: bytecount); ! 2730: ! 2731: } else { ! 2732: linedescr[next_lineno].linedata_valid = 0; ! 2733: } ! 2734: #endif ! 2735: ! 2736: pfield_modulos(bytecount); ! 2737: ! 2738: #if SMART_UPDATE != 0 ! 2739: if (!drawit) ! 2740: return; ! 2741: #endif ! 2742: ! 2743: if (use_lores) ! 2744: pfield_doline_l(); ! 2745: else ! 2746: pfield_doline_h(); ! 2747: } ! 2748: ! 2749: static void pfield_doline_slow(int currhp) ! 2750: { ! 2751: if (vpos < plffirstline || vpos >= plflastline) ! 2752: return; ! 2753: ! 2754: if (currhp == plfstrt) ! 2755: slowline_nextpos = currhp; ! 2756: ! 2757: if (currhp == slowline_nextpos) { ! 2758: if (slowline_linepos >= plflinelen) { ! 2759: pfield_modulos(0); ! 2760: slowline_nextpos = -1; ! 2761: } else { ! 2762: slowline_nextpos += bplhires ? 4 : 8; ! 2763: slowline_linepos += bplhires ? 4 : 8; ! 2764: ! 2765: pfield_fetchdata(); ! 2766: ! 2767: if (use_lores) ! 2768: pfield_doline_slow_l(currhp); ! 2769: else ! 2770: pfield_doline_slow_h(currhp); ! 2771: } ! 2772: } ! 2773: if (currhp > 48) { ! 2774: int xpos = PIXEL_XPOS(currhp); ! 2775: int spr; ! 2776: for(spr = 7; spr >= 0; spr--) { ! 2777: if (bpl_info.sprarmed[spr] && currhp == (bpl_info.sprpos[spr] & 0xFF)) { ! 2778: if (use_lores) { ! 2779: int sprxp = xpos + (bpl_info.sprctl[spr] & 1); ! 2780: pfield_sprite_l (spr, sprxp, bpl_info.sprdata[spr], bpl_info.sprdatb[spr]); ! 2781: } else { ! 2782: int sprxp = xpos + (bpl_info.sprctl[spr] & 1)*2; ! 2783: pfield_sprite_h (spr, sprxp, bpl_info.sprdata[spr], bpl_info.sprdatb[spr]); ! 2784: } ! 2785: } ! 2786: } ! 2787: } 1.1 root 2788: } 2789: 2790: static void setdontcare(void) 2791: { 1.1.1.2 ! root 2792: fprintf(stderr, "Don't care mouse mode set\n"); 1.1 root 2793: mousestate=dont_care_mouse; 2794: lastspr0x=lastmx; lastspr0y=lastmy; 2795: mstepx=defstepx; mstepy=defstepy; 2796: } 2797: 2798: static void setfollow(void) 2799: { 1.1.1.2 ! root 2800: fprintf(stderr, "Follow sprite mode set\n"); 1.1 root 2801: mousestate=follow_mouse; 2802: lastdiffx=lastdiffy=0; 2803: sprvbfl=0; 2804: spr0ctl=spr0pos=0; 2805: mstepx=defstepx; mstepy=defstepy; 2806: } 2807: 2808: void togglemouse(void) 2809: { 2810: switch(mousestate) { 2811: case dont_care_mouse: setfollow(); break; 2812: case follow_mouse: setdontcare(); break; 1.1.1.2 ! root 2813: default: break; /* Nnnnnghh! */ 1.1 root 2814: } 2815: } 2816: 2817: static __inline__ int adjust(int val) 2818: { 2819: if (val>127) 2820: return 127; 2821: else if (val<-127) 2822: return -127; 2823: return val; 2824: } 2825: 1.1.1.2 ! root 2826: static int first_drawn_line, last_drawn_line; ! 2827: static int first_block_line, last_block_line; ! 2828: ! 2829: static void init_frame (void) ! 2830: { ! 2831: int i; ! 2832: int maxpos = use_lores ? 400 : 800; ! 2833: ! 2834: if (max_diwstop == 0) ! 2835: max_diwstop = diwlastword; ! 2836: ! 2837: if (max_diwstop < (use_lores ? 320 : 640) || max_diwstop > maxpos) ! 2838: prev_max_diwstop = maxpos; ! 2839: else ! 2840: prev_max_diwstop = max_diwstop; ! 2841: ! 2842: max_diwstop = 0; ! 2843: ! 2844: memset(spron, 0, sizeof spron); ! 2845: memset(bpl_info.sprpos, 0, sizeof bpl_info.sprpos); ! 2846: memset(bpl_info.sprctl, 0, sizeof bpl_info.sprctl); ! 2847: last_drawn_line = 0; ! 2848: first_drawn_line = 32767; ! 2849: ! 2850: first_block_line = last_block_line = -2; ! 2851: } ! 2852: ! 2853: static void do_flush_line (int lineno) ! 2854: { ! 2855: if (lineno < first_drawn_line) ! 2856: first_drawn_line = lineno; ! 2857: if (lineno > last_drawn_line) ! 2858: last_drawn_line = lineno; ! 2859: ! 2860: if (gfxvidinfo.maxblocklines == 0) ! 2861: flush_line(lineno); ! 2862: else { ! 2863: if ((last_block_line+1) != lineno) { ! 2864: if (first_block_line != -2) ! 2865: flush_block (first_block_line, last_block_line); ! 2866: first_block_line = lineno; ! 2867: } ! 2868: last_block_line = lineno; ! 2869: if (last_block_line - first_block_line >= gfxvidinfo.maxblocklines) { ! 2870: flush_block (first_block_line, last_block_line); ! 2871: first_block_line = last_block_line = -2; ! 2872: } ! 2873: } ! 2874: } ! 2875: ! 2876: static void do_flush_screen (int start, int stop) ! 2877: { ! 2878: if (gfxvidinfo.maxblocklines != 0 && first_block_line != -2) { ! 2879: flush_block (first_block_line, last_block_line); ! 2880: } ! 2881: if (start <= stop) ! 2882: flush_screen (start, stop); ! 2883: } ! 2884: 1.1 root 2885: static void vsync_handler(void) 2886: { 2887: int spr0x = ((spr0pos & 0xff) << 2) | ((spr0ctl & 1) << 1); 2888: int spr0y = ((spr0pos >> 8) | ((spr0ctl & 4) << 6)) << 1; 2889: int diffx, diffy; 2890: int i; 1.1.1.2 ! root 2891: UWORD dir; ! 2892: int button; ! 2893: 1.1 root 2894: handle_events(); 1.1.1.2 ! root 2895: getjoystate(&joy0dir, &joy0button); 1.1 root 2896: 2897: switch (mousestate) { 2898: case normal_mouse: 2899: diffx = lastmx - lastsampledmx; 2900: diffy = lastmy - lastsampledmy; 2901: if (!newmousecounters) { 2902: if (diffx > 127) diffx = 127; 2903: if (diffx < -127) diffx = -127; 2904: joy0x += diffx; 2905: if (diffy > 127) diffy = 127; 2906: if (diffy < -127) diffy = -127; 2907: joy0y += diffy; 2908: } 2909: lastsampledmx += diffx; lastsampledmy += diffy; 2910: break; 2911: 2912: case dont_care_mouse: 2913: diffx = adjust (((lastmx-lastspr0x) * mstepx) >> 16); 2914: diffy = adjust (((lastmy-lastspr0y) * mstepy) >> 16); 2915: lastspr0x=lastmx; lastspr0y=lastmy; 2916: joy0x+=diffx; joy0y+=diffy; 2917: break; 2918: 2919: case follow_mouse: 2920: if (sprvbfl && sprvbfl-- >1) { 1.1.1.2 ! root 2921: int mousexpos, mouseypos; 1.1 root 2922: 2923: if ((lastdiffx > docal || lastdiffx < -docal) && lastspr0x != spr0x 2924: && spr0x > plfstrt*4+34+xcaloff && spr0x < plfstop*4-xcaloff) 2925: { 2926: int val = (lastdiffx << 16) / (spr0x - lastspr0x); 2927: if (val>=0x8000) mstepx=(mstepx*(calweight-1)+val)/calweight; 2928: } 2929: if ((lastdiffy > docal || lastdiffy < -docal) && lastspr0y != spr0y 2930: && spr0y>plffirstline+ycaloff && spr0y<plflastline-ycaloff) 2931: { 2932: int val = (lastdiffy<<16) / (spr0y-lastspr0y); 2933: if (val>=0x8000) mstepy=(mstepy*(calweight-1)+val)/calweight; 2934: } 1.1.1.2 ! root 2935: mousexpos = lastmx; 1.1 root 2936: mouseypos = lastmy; 1.1.1.2 ! root 2937: 1.1 root 2938: if(dont_want_aspect) 2939: mouseypos *= 2; 1.1.1.2 ! root 2940: if(use_lores) ! 2941: mousexpos = 2 * (mousexpos + prev_max_diwstop - 328); 1.1 root 2942: 1.1.1.2 ! root 2943: diffx = adjust ((((mousexpos + 0x70 + xoffs - spr0x) & ~1) * mstepx) >> 16); 1.1 root 2944: diffy = adjust ((((mouseypos + yoffs - spr0y+minfirstline*2) & ~1) * mstepy) >> 16); 2945: lastspr0x=spr0x; lastspr0y=spr0y; 2946: lastdiffx=diffx; lastdiffy=diffy; 2947: joy0x+=diffx; joy0y+=diffy; 2948: } 2949: break; 2950: } 2951: 2952: INTREQ(0x8020); 1.1.1.2 ! root 2953: if (bpl_info.bplcon0 & 4) lof ^= 0x8000; 1.1 root 2954: COPJMP1(0); 2955: 2956: if (framecnt == 0) 1.1.1.2 ! root 2957: do_flush_screen (first_drawn_line, last_drawn_line); ! 2958: ! 2959: count_frame(); ! 2960: init_frame(); ! 2961: #ifdef HAVE_GETTIMEOFDAY 1.1 root 2962: { 2963: struct timeval tv; 2964: unsigned long int newtime; 2965: 2966: gettimeofday(&tv,NULL); 2967: newtime = (tv.tv_sec-seconds_base) * 1000 + tv.tv_usec / 1000; 2968: 2969: if (!bogusframe) { 2970: frametime += newtime - msecs; 2971: timeframes++; 2972: } 2973: msecs = newtime; 1.1.1.2 ! root 2974: bogusframe = 0; 1.1 root 2975: } 2976: #endif 2977: CIA_vsync_handler(); 2978: } 2979: 2980: static void hsync_handler(void) 2981: { 1.1.1.2 ! root 2982: int lineno = vpos - minfirstline; ! 2983: int lineisdouble = 0; ! 2984: ! 2985: do_sprites(vpos, maxhpos); ! 2986: last_sprite = 0; ! 2987: ! 2988: if (!dont_want_aspect) { ! 2989: lineno *= 2; ! 2990: if (bpl_info.bplcon0 & 4) { ! 2991: if(!lof) { ! 2992: lineno++; ! 2993: } ! 2994: } else { ! 2995: lineisdouble = 1; ! 2996: } ! 2997: } ! 2998: ! 2999: if (disk_int_defer) ! 3000: if (!--disk_int_defer) ! 3001: INTREQ(0x8002); ! 3002: 1.1 root 3003: eventtab[ev_hsync].oldcycles = cycles; 3004: CIA_hsync_handler(); 3005: 3006: if(produce_sound) 3007: do_sound (); 3008: 1.1.1.2 ! root 3009: if (framecnt == 0 && vpos >= minfirstline) { ! 3010: if (vpos >= plffirstline && vpos < plflastline) ! 3011: { ! 3012: /* Finish the line, if we started doing it with the slow update. ! 3013: * Otherwise, draw it entirely. */ ! 3014: if (pfield_fullline) { ! 3015: if (!pfield_linedone) { ! 3016: /* This can turn on line_in_border if DMA is off */ ! 3017: pfield_doline(); ! 3018: } ! 3019: if (linetoscreen) ! 3020: pfield_slow_linetoscr(0, maxhpos); ! 3021: } else { ! 3022: int i; ! 3023: for(i = pfield_lastpart_hpos; i < maxhpos; i++) ! 3024: pfield_doline_slow(i); ! 3025: pfield_slow_linetoscr(slowline_lasttoscr, maxhpos); ! 3026: /* The COLOR routine masks off the high nibble. This means ! 3027: * that there will never be 0xFFFF in color_regs[0], and this ! 3028: * means that the line will be drawn completely the next time ! 3029: * we get into pfield_doline() ! 3030: */ ! 3031: linedescr[lineno].bpl_info.color_regs[0] = 0xFFFF; ! 3032: linetoscreen = 1; ! 3033: } ! 3034: } else ! 3035: line_in_border = 1; ! 3036: ! 3037: if (line_in_border && ! 3038: (!linedescr[lineno].inborder ! 3039: || linedescr[lineno].bordercol != acolors[0])) ! 3040: { ! 3041: linedescr[lineno].bordercol = acolors[0]; ! 3042: linedescr[lineno].linedata_valid = 0; ! 3043: ! 3044: fill_line (lineno); ! 3045: linetoscreen = 1; ! 3046: } ! 3047: ! 3048: linedescr[lineno].inborder = line_in_border; ! 3049: ! 3050: if (linetoscreen) { ! 3051: do_flush_line (lineno); ! 3052: } ! 3053: if (lineisdouble) { ! 3054: int drawit = 0; ! 3055: ! 3056: if (linedescr[lineno].inborder != linedescr[lineno+1].inborder ! 3057: || (linedescr[lineno].inborder == 1 ! 3058: && linedescr[lineno].bordercol != linedescr[lineno+1].bordercol)) { ! 3059: drawit = 1; ! 3060: ! 3061: } else if (linedescr[lineno].inborder == 0 ! 3062: && (linetoscreen ! 3063: || (bplinfo_differs(&linedescr[lineno].bpl_info, ! 3064: &linedescr[lineno+1].bpl_info)))) { ! 3065: drawit = 1; ! 3066: } ! 3067: ! 3068: if (drawit) { ! 3069: linedescr[lineno+1].inborder = linedescr[lineno].inborder; ! 3070: linedescr[lineno+1].bordercol = linedescr[lineno].bordercol; ! 3071: #if SMART_UPDATE != 0 ! 3072: linedescr[lineno+1].bpl_info = linedescr[lineno].bpl_info; ! 3073: #endif ! 3074: memcpy (gfxvidinfo.bufmem + (lineno+1)*gfxvidinfo.rowbytes, ! 3075: gfxvidinfo.bufmem + lineno*gfxvidinfo.rowbytes, ! 3076: gfxvidinfo.rowbytes); ! 3077: do_flush_line (lineno+1); 1.1 root 3078: } 3079: } 3080: } 1.1.1.2 ! root 3081: 1.1 root 3082: pfield_calclinedma(); 3083: 3084: if (++vpos == (maxvpos + (lof != 0))) { 3085: vpos = 0; 3086: vsync_handler(); 3087: } 3088: 1.1.1.2 ! root 3089: if (framecnt == 0) 1.1 root 3090: { 1.1.1.2 ! root 3091: lineno = vpos - minfirstline; ! 3092: ! 3093: if (!dont_want_aspect) { ! 3094: lineno *= 2; ! 3095: if ((bpl_info.bplcon0 & 4) && !lof) { ! 3096: lineno++; 1.1 root 3097: } 3098: } 1.1.1.2 ! root 3099: xlinebuffer = gfxvidinfo.bufmem + gfxvidinfo.rowbytes * lineno; ! 3100: aga_lbufptr = aga_linebuf; ! 3101: next_lineno = lineno; ! 3102: linetoscreen = 0; ! 3103: line_in_border = 0; ! 3104: pfield_fullline = 1; ! 3105: pfield_linedone = 0; ! 3106: pfield_lastpart_hpos = 0; 1.1 root 3107: } 3108: 3109: } 3110: 3111: void customreset(void) 3112: { 3113: int i; 1.1.1.2 ! root 3114: #ifdef HAVE_GETTIMEOFDAY 1.1 root 3115: struct timeval tv; 3116: #endif 3117: inhibit_frame = 0; 1.1.1.2 ! root 3118: expamem_reset(); 1.1 root 3119: CIA_reset(); 1.1.1.2 ! root 3120: cycles = 0; ! 3121: specialflags = 0; 1.1 root 3122: 1.1.1.2 ! root 3123: last_sprite = 0; ! 3124: vpos = 0; ! 3125: lof = 0; ! 3126: next_lineno = 0; ! 3127: max_diwstop = 0; 1.1 root 3128: 3129: if (needmousehack()) { 3130: if (mousestate != follow_mouse) setfollow(); 3131: } else { 3132: mousestate = normal_mouse; 3133: } 3134: 3135: memset(spixels, 0, sizeof(spixels)); 3136: memset(spixstate, 0, sizeof(spixstate)); 3137: 1.1.1.2 ! root 3138: /*memset(blitcount, 0, sizeof(blitcount)); blitter debug */ ! 3139: ! 3140: for (i = 0; i < numscrlines*2; i++) { ! 3141: linedescr[i].mnn = NULL; ! 3142: linedescr[i].linedata_valid = 0; ! 3143: linedescr[i].bpl_info.color_regs[0] = 0xFFFF; ! 3144: linedescr[i].bplpt[0] = (CPTR)-1; ! 3145: } 1.1 root 3146: 1.1.1.2 ! root 3147: xlinebuffer = gfxvidinfo.bufmem; ! 3148: 1.1 root 3149: dmacon = intena = 0; 3150: bltstate = BLT_done; 3151: copstate = COP_stop; 3152: copcon = 0; 3153: dskdmaen = 0; 3154: cycles = 0; 1.1.1.2 ! root 3155: for(i = 0; i < ev_max; i++) { ! 3156: eventtab[i].active = 0; 1.1 root 3157: eventtab[i].oldcycles = 0; 3158: } 1.1.1.2 ! root 3159: copper_active = 0; 1.1 root 3160: eventtab[ev_cia].handler = CIA_handler; 3161: eventtab[ev_copper].handler = do_copper; 3162: eventtab[ev_hsync].handler = hsync_handler; 3163: eventtab[ev_hsync].evtime = maxhpos; 1.1.1.2 ! root 3164: eventtab[ev_hsync].active = 1; 1.1 root 3165: #ifdef DEFERRED_INT 3166: eventtab[ev_deferint].handler = defer_int_handler; 1.1.1.2 ! root 3167: eventtab[ev_deferint].active = 0; 1.1 root 3168: #endif 3169: events_schedule(); 3170: 1.1.1.2 ! root 3171: init_frame(); ! 3172: #ifdef HAVE_GETTIMEOFDAY 1.1 root 3173: gettimeofday(&tv,NULL); 3174: seconds_base = tv.tv_sec; 1.1.1.2 ! root 3175: bogusframe = 1; 1.1 root 3176: #endif 3177: } 3178: 3179: void dumpcustom(void) 3180: { 1.1.1.2 ! root 3181: int i; ! 3182: fprintf(stderr, "DMACON: %x INTENA: %x INTREQ: %x VPOS: %x HPOS: %x\n", DMACONR(), 1.1 root 3183: intena, intreq, vpos, current_hpos()); 3184: if (timeframes) { 1.1.1.2 ! root 3185: fprintf(stderr, "Average frame time: %d ms [frames: %d time: %d]\n", 1.1 root 3186: frametime/timeframes, timeframes, frametime); 3187: } 1.1.1.2 ! root 3188: /*for (i=0; i<256; i++) if (blitcount[i]) fprintf(stderr, "minterm %x = %d\n",i,blitcount[i]); blitter debug */ 1.1 root 3189: } 3190: 3191: int intlev(void) 3192: { 3193: UWORD imask = intreq & intena; 3194: if (imask && (intena & 0x4000)){ 3195: if (imask & 0x2000) return 6; 3196: if (imask & 0x1800) return 5; 3197: if (imask & 0x0780) return 4; 3198: if (imask & 0x0070) return 3; 3199: if (imask & 0x0008) return 2; 3200: if (imask & 0x0007) return 1; 3201: } 3202: return -1; 3203: } 3204: 3205: void custom_init(void) 3206: { 3207: int num; 1.1.1.2 ! root 3208: if (needmousehack()) ! 3209: setfollow(); 1.1 root 3210: customreset(); 1.1.1.2 ! root 3211: for (num = 0; num < 256; num++) { ! 3212: int plane1 = (num & 1) | ((num >> 1) & 2) | ((num >> 2) & 4) | ((num >> 3) & 8); ! 3213: int plane2 = ((num >> 1) & 1) | ((num >> 2) & 2) | ((num >> 3) & 4) | ((num >> 4) & 8); ! 3214: dblpf_2nd1[num] = plane1 == 0 ? (plane2 == 0 ? 0 : 2) : 1; ! 3215: dblpf_2nd2[num] = plane2 == 0 ? (plane1 == 0 ? 0 : 1) : 2; ! 3216: dblpf_aga1[num] = plane1 == 0 ? plane2 : plane1; ! 3217: dblpf_aga2[num] = plane2 == 0 ? plane1 : plane2; 1.1 root 3218: if (plane2 > 0) plane2 += 8; 3219: dblpf_ind1[num] = plane1 == 0 ? plane2 : plane1; 3220: dblpf_ind2[num] = plane2 == 0 ? plane1 : plane2; 3221: } 1.1.1.2 ! root 3222: build_filltable(); ! 3223: gen_pfield_tables(); ! 3224: } ! 3225: ! 3226: /* Custom chip memory bank */ ! 3227: ! 3228: static ULONG custom_lget(CPTR) REGPARAM; ! 3229: static UWORD custom_wget(CPTR) REGPARAM; ! 3230: static UBYTE custom_bget(CPTR) REGPARAM; ! 3231: static void custom_lput(CPTR, ULONG) REGPARAM; ! 3232: static void custom_wput(CPTR, UWORD) REGPARAM; ! 3233: static void custom_bput(CPTR, UBYTE) REGPARAM; ! 3234: ! 3235: addrbank custom_bank = { ! 3236: custom_lget, custom_wget, custom_bget, ! 3237: custom_lput, custom_wput, custom_bput, ! 3238: default_xlate, default_check ! 3239: }; ! 3240: ! 3241: UWORD custom_wget(CPTR addr) ! 3242: { ! 3243: switch(addr & 0x1FE) { ! 3244: case 0x002: return DMACONR(); ! 3245: case 0x004: return VPOSR(); ! 3246: case 0x006: return VHPOSR(); ! 3247: ! 3248: case 0x008: return DSKDATR(); ! 3249: case 0x012: return POT0DAT(); ! 3250: case 0x016: return POTGOR(); ! 3251: case 0x018: return SERDATR(); ! 3252: case 0x01A: return DSKBYTR(); ! 3253: case 0x01C: return INTENAR(); ! 3254: case 0x01E: return INTREQR(); ! 3255: case 0x010: return ADKCONR(); ! 3256: case 0x00A: return JOY0DAT(); ! 3257: case 0x00C: return JOY1DAT(); ! 3258: #ifdef ECS_DENISE ! 3259: case 0x07C: return 0xFC; ! 3260: #endif ! 3261: default: ! 3262: custom_wput(addr,0); ! 3263: return 0xffff; ! 3264: } ! 3265: } ! 3266: ! 3267: UBYTE custom_bget(CPTR addr) ! 3268: { ! 3269: return custom_wget(addr & 0xfffe) >> (addr & 1 ? 0 : 8); ! 3270: } ! 3271: ! 3272: ULONG custom_lget(CPTR addr) ! 3273: { ! 3274: return ((ULONG)custom_wget(addr & 0xfffe) << 16) | custom_wget((addr+2) & 0xfffe); ! 3275: } ! 3276: ! 3277: void custom_wput(CPTR addr, UWORD value) ! 3278: { ! 3279: addr &= 0x1FE; ! 3280: cregs[addr>>1] = value; ! 3281: switch(addr) { ! 3282: case 0x020: DSKPTH(value); break; ! 3283: case 0x022: DSKPTL(value); break; ! 3284: case 0x024: DSKLEN(value); break; ! 3285: case 0x026: DSKDAT(value); break; ! 3286: ! 3287: case 0x02A: VPOSW(value); break; ! 3288: ! 3289: case 0x040: BLTCON0(value); break; ! 3290: case 0x042: BLTCON1(value); break; ! 3291: ! 3292: case 0x044: BLTAFWM(value); break; ! 3293: case 0x046: BLTALWM(value); break; ! 3294: ! 3295: case 0x050: BLTAPTH(value); break; ! 3296: case 0x052: BLTAPTL(value); break; ! 3297: case 0x04C: BLTBPTH(value); break; ! 3298: case 0x04E: BLTBPTL(value); break; ! 3299: case 0x048: BLTCPTH(value); break; ! 3300: case 0x04A: BLTCPTL(value); break; ! 3301: case 0x054: BLTDPTH(value); break; ! 3302: case 0x056: BLTDPTL(value); break; ! 3303: ! 3304: case 0x058: BLTSIZE(value); break; ! 3305: ! 3306: case 0x064: BLTAMOD(value); break; ! 3307: case 0x062: BLTBMOD(value); break; ! 3308: case 0x060: BLTCMOD(value); break; ! 3309: case 0x066: BLTDMOD(value); break; ! 3310: ! 3311: case 0x070: BLTCDAT(value); break; ! 3312: case 0x072: BLTBDAT(value); break; ! 3313: case 0x074: BLTADAT(value); break; ! 3314: ! 3315: case 0x07E: DSKSYNC(value); break; ! 3316: ! 3317: case 0x080: COP1LCH(value); break; ! 3318: case 0x082: COP1LCL(value); break; ! 3319: case 0x084: COP2LCH(value); break; ! 3320: case 0x086: COP2LCL(value); break; ! 3321: ! 3322: case 0x088: COPJMP1(value); break; ! 3323: case 0x08A: COPJMP2(value); break; ! 3324: ! 3325: case 0x08E: DIWSTRT(value); break; ! 3326: case 0x090: DIWSTOP(value); break; ! 3327: case 0x092: DDFSTRT(value); break; ! 3328: case 0x094: DDFSTOP(value); break; ! 3329: ! 3330: case 0x096: DMACON(value); break; ! 3331: case 0x09A: INTENA(value); break; ! 3332: case 0x09C: INTREQ(value); break; ! 3333: case 0x09E: ADKCON(value); break; ! 3334: ! 3335: case 0x0A0: AUD0LCH(value); break; ! 3336: case 0x0A2: AUD0LCL(value); break; ! 3337: case 0x0A4: AUD0LEN(value); break; ! 3338: case 0x0A6: AUD0PER(value); break; ! 3339: case 0x0A8: AUD0VOL(value); break; ! 3340: ! 3341: case 0x0B0: AUD1LCH(value); break; ! 3342: case 0x0B2: AUD1LCL(value); break; ! 3343: case 0x0B4: AUD1LEN(value); break; ! 3344: case 0x0B6: AUD1PER(value); break; ! 3345: case 0x0B8: AUD1VOL(value); break; ! 3346: ! 3347: case 0x0C0: AUD2LCH(value); break; ! 3348: case 0x0C2: AUD2LCL(value); break; ! 3349: case 0x0C4: AUD2LEN(value); break; ! 3350: case 0x0C6: AUD2PER(value); break; ! 3351: case 0x0C8: AUD2VOL(value); break; ! 3352: ! 3353: case 0x0D0: AUD3LCH(value); break; ! 3354: case 0x0D2: AUD3LCL(value); break; ! 3355: case 0x0D4: AUD3LEN(value); break; ! 3356: case 0x0D6: AUD3PER(value); break; ! 3357: case 0x0D8: AUD3VOL(value); break; ! 3358: ! 3359: case 0x0E0: BPLPTH(value, 0); break; ! 3360: case 0x0E2: BPLPTL(value, 0); break; ! 3361: case 0x0E4: BPLPTH(value, 1); break; ! 3362: case 0x0E6: BPLPTL(value, 1); break; ! 3363: case 0x0E8: BPLPTH(value, 2); break; ! 3364: case 0x0EA: BPLPTL(value, 2); break; ! 3365: case 0x0EC: BPLPTH(value, 3); break; ! 3366: case 0x0EE: BPLPTL(value, 3); break; ! 3367: case 0x0F0: BPLPTH(value, 4); break; ! 3368: case 0x0F2: BPLPTL(value, 4); break; ! 3369: case 0x0F4: BPLPTH(value, 5); break; ! 3370: case 0x0F6: BPLPTL(value, 5); break; ! 3371: ! 3372: case 0x100: BPLCON0(value); break; ! 3373: case 0x102: BPLCON1(value); break; ! 3374: case 0x104: BPLCON2(value); break; ! 3375: case 0x106: BPLCON3(value); break; ! 3376: ! 3377: case 0x108: BPL1MOD(value); break; ! 3378: case 0x10A: BPL2MOD(value); break; ! 3379: ! 3380: case 0x110: BPL1DAT(value); break; ! 3381: case 0x112: BPL2DAT(value); break; ! 3382: case 0x114: BPL3DAT(value); break; ! 3383: case 0x116: BPL4DAT(value); break; ! 3384: case 0x118: BPL5DAT(value); break; ! 3385: case 0x11A: BPL6DAT(value); break; ! 3386: ! 3387: case 0x180: case 0x182: case 0x184: case 0x186: case 0x188: case 0x18A: ! 3388: case 0x18C: case 0x18E: case 0x190: case 0x192: case 0x194: case 0x196: ! 3389: case 0x198: case 0x19A: case 0x19C: case 0x19E: case 0x1A0: case 0x1A2: ! 3390: case 0x1A4: case 0x1A6: case 0x1A8: case 0x1AA: case 0x1AC: case 0x1AE: ! 3391: case 0x1B0: case 0x1B2: case 0x1B4: case 0x1B6: case 0x1B8: case 0x1BA: ! 3392: case 0x1BC: case 0x1BE: ! 3393: COLOR(value & 0xFFF, (addr & 0x3E) / 2); ! 3394: break; ! 3395: case 0x120: case 0x124: case 0x128: case 0x12C: ! 3396: case 0x130: case 0x134: case 0x138: case 0x13C: ! 3397: SPRxPTH(value, (addr - 0x120) / 4); ! 3398: break; ! 3399: case 0x122: case 0x126: case 0x12A: case 0x12E: ! 3400: case 0x132: case 0x136: case 0x13A: case 0x13E: ! 3401: SPRxPTL(value, (addr - 0x122) / 4); ! 3402: break; ! 3403: case 0x140: case 0x148: case 0x150: case 0x158: ! 3404: case 0x160: case 0x168: case 0x170: case 0x178: ! 3405: SPRxPOS(value, (addr - 0x140) / 8); ! 3406: break; ! 3407: case 0x142: case 0x14A: case 0x152: case 0x15A: ! 3408: case 0x162: case 0x16A: case 0x172: case 0x17A: ! 3409: SPRxCTL(value, (addr - 0x142) / 8); ! 3410: break; ! 3411: case 0x144: case 0x14C: case 0x154: case 0x15C: ! 3412: case 0x164: case 0x16C: case 0x174: case 0x17C: ! 3413: SPRxDATA(value, (addr - 0x144) / 8); ! 3414: break; ! 3415: case 0x146: case 0x14E: case 0x156: case 0x15E: ! 3416: case 0x166: case 0x16E: case 0x176: case 0x17E: ! 3417: SPRxDATB(value, (addr - 0x146) / 8); ! 3418: break; ! 3419: ! 3420: case 0x36: JOYTEST(value); break; ! 3421: #if defined(ECS_AGNUS) || (AGA_CHIPSET == 1) ! 3422: case 0x5A: BLTCON0L(value); break; ! 3423: case 0x5C: BLTSIZV(value); break; ! 3424: case 0x5E: BLTSIZH(value); break; ! 3425: #endif ! 3426: #if AGA_CHIPSET == 1 ! 3427: case 0x10C: BPLCON4(value); break; ! 3428: #endif ! 3429: } ! 3430: } ! 3431: ! 3432: void custom_bput(CPTR addr, UBYTE value) ! 3433: { ! 3434: /* Yes, there are programs that do this. The programmers should be shot. ! 3435: * This might actually work sometimes. */ ! 3436: UWORD rval = value; ! 3437: CPTR raddr = addr & 0x1FE; ! 3438: if (addr & 1) { ! 3439: rval |= cregs[raddr >> 1] & 0xFF00; ! 3440: } else { ! 3441: rval <<= 8; ! 3442: rval |= cregs[raddr >> 1] & 0xFF; ! 3443: } ! 3444: custom_wput(raddr, rval); ! 3445: } ! 3446: ! 3447: void custom_lput(CPTR addr, ULONG value) ! 3448: { ! 3449: custom_wput(addr & 0xfffe, value >> 16); ! 3450: custom_wput((addr+2) & 0xfffe, (UWORD)value); 1.1 root 3451: } 1.1.1.2 ! root 3452:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.