home *** CD-ROM | disk | FTP | other *** search
- /*
- * UAE - The Un*x Amiga Emulator
- *
- * Custom chip emulation
- *
- * (c) 1995 Bernd Schmidt, Alessandro Bissacco
- */
-
- #include "sysconfig.h"
- #include "sysdeps.h"
-
- #include <ctype.h>
- #include <assert.h>
-
- #include "config.h"
- #include "options.h"
- #include "events.h"
- #include "memory.h"
- #include "custom.h"
- #include "cia.h"
- #include "disk.h"
- #include "blitter.h"
- #include "xwin.h"
- #include "os.h"
- #include "keybuf.h"
-
- /*#define EMULATE_AGA*/
-
- #ifndef EMULATE_AGA
- #define AGA_CHIPSET 0
- #else
- #define AGA_CHIPSET 1
- #endif
-
- #define SMART_UPDATE 1
-
- #define MAX_PLANES 8
-
- #define PIXEL_XPOS(HPOS) (((HPOS)*2 - 0x30)*(use_lores ? 1 : 2))
-
- /* These are default values for mouse calibration.
- * The first two are default values for mstepx and mstepy.
- * The second line set the orizontal and vertical offset for amiga and X
- * pointer matching
- */
-
- #define defstepx (1<<16)
- #define defstepy (1<<16)
- #define defxoffs 0
- #define defyoffs 0
-
- /* Values below define mouse auto calibration process.
- * They are not critical, change them if you want.
- * The most important is calweight, which sets mouse adjustement rate */
-
- static const int docal = 60, xcaloff = 40, ycaloff = 20;
- static const int calweight = 3;
- static int lastsampledmx, lastsampledmy;
-
- /*
- * Events
- */
-
- unsigned long int cycles, nextevent, nextev_count, specialflags;
- int vpos;
- UWORD lof;
-
- struct ev eventtab[ev_max];
-
- int copper_active;
-
- static const int dskdelay = 2; /* FIXME: ??? */
-
- /*
- * hardware register values that are visible/can be written to by someone
- */
-
- static UWORD cregs[256];
-
- static UWORD dmacon,intena,intreq;
- UWORD adkcon; /* used by audio code */
-
- static ULONG cop1lc,cop2lc,copcon;
-
- /* Kludge. FIXME: How does sprite restart after vsync work? */
- static int spron[8];
- static CPTR sprpt[8];
-
- static ULONG bpl1dat,bpl2dat,bpl3dat,bpl4dat,bpl5dat,bpl6dat,bpl7dat,bpl8dat;
- static WORD bpl1mod,bpl2mod;
-
- xcolnr acolors[64];
-
- UWORD *r_bplpt[MAX_PLANES];
- static CPTR bplpt[MAX_PLANES];
-
- /*static int blitcount[256]; blitter debug */
-
- struct bplinfo {
- #if AGA_CHIPSET == 0
- /* X86.S will break if this isn't at the beginning of the structure. */
- UWORD color_regs[32];
- #else
- ULONG color_regs[256];
- #endif
- UWORD bplcon0,bplcon1,bplcon2,bplcon3,bplcon4;
- UWORD diwstrt,diwstop,ddfstrt,ddfstop;
-
- UWORD sprdata[8], sprdatb[8], sprctl[8], sprpos[8];
- int sprarmed[8];
- } bpl_info;
-
- struct line_description
- {
- int inborder;
- xcolnr bordercol;
- struct bplinfo bpl_info;
- struct mem_notify_node *mnn;
- CPTR bplpt[MAX_PLANES];
- int linedata_valid;
- };
-
- static int frame_redraw_necessary;
-
- /* 50 words give you 800 horizontal pixels. An A500 can't do that, so it ought
- * to be enough. */
- #define MAX_WORDS_PER_LINE 50
- static UWORD line_data[numscrlines * 2][MAX_PLANES][MAX_WORDS_PER_LINE];
- static struct line_description linedescr[numscrlines * 2];
-
- static ULONG dskpt;
- static UWORD dsklen,dsksync;
-
- static int joy0x, joy1x, joy0y, joy1y;
- int joy0button;
- UWORD joy0dir;
- static int lastspr0x,lastspr0y,lastdiffx,lastdiffy,spr0pos,spr0ctl;
- static int mstepx,mstepy,xoffs=defxoffs,yoffs=defyoffs;
- static int sprvbfl;
-
- static enum { normal_mouse, dont_care_mouse, follow_mouse } mousestate;
-
- /*
- * "hidden" hardware registers
- */
-
- int dblpf_ind1[256], dblpf_ind2[256], dblpf_2nd1[256], dblpf_2nd2[256];
- int dblpf_aga1[256], dblpf_aga2[256], linear_map_256[256], lots_of_twos[256];
-
- int dblpfofs[] = { 0, 2, 4, 8, 16, 32, 64, 128 };
-
- static ULONG coplc;
- static UWORD copi1,copi2;
-
- static enum {
- COP_stop, COP_read, COP_wait, COP_move, COP_skip
- } copstate;
-
- static int dsklength;
-
- int plffirstline,plflastline,plfstrt,plfstop,plflinelen;
- int diwfirstword,diwlastword;
- int plfpri[3];
-
- int max_diwstop, prev_max_diwstop;
-
- int dskdmaen; /* used in cia.c */
-
- int bpldelay1, bpldelay2;
- int bplehb, bplham, bpldualpf, bpldualpfpri, bplplanecnt, bplhires;
-
- static int pfield_fullline,pfield_linedone;
- static int pfield_linedmaon;
- static int pfield_lastpart_hpos,last_sprite;
- static int slowline_nextpos, slowline_linepos, slowline_lasttoscr;
-
- union {
- /* Let's try to align this thing. */
- double uupzuq;
- long int cruxmedo;
- unsigned char apixels[1000];
- } pixdata;
-
- char spixels[1000]; /* for sprites */
- char spixstate[1000]; /* more sprites */
-
- ULONG ham_linebuf[1000];
- ULONG aga_linebuf[1000], *aga_lbufptr;
-
- char *xlinebuffer;
- int next_lineno, linetoscreen, line_in_border;
-
- /*
- * Statistics
- */
-
- static unsigned long int msecs = 0, frametime = 0, timeframes = 0;
- static unsigned long int seconds_base;
- int bogusframe;
-
- /*
- * helper functions
- */
-
- static void pfield_doline_slow(int);
- static void pfield_doline(void);
- static void do_sprites(int, int);
-
- int inhibit_frame;
- static int framecnt = 0;
-
- static __inline__ void count_frame(void)
- {
- if (inhibit_frame)
- framecnt = 1;
- else {
- framecnt++;
- if (framecnt >= framerate)
- framecnt = 0;
- }
- }
-
- static __inline__ void setclr(UWORD *p, UWORD val)
- {
- if (val & 0x8000) {
- *p |= val & 0x7FFF;
- } else {
- *p &= ~val;
- }
- }
-
- int dmaen(UWORD dmamask)
- {
- return (dmamask & dmacon) && (dmacon & 0x200);
- }
-
- static __inline__ int current_hpos(void)
- {
- return cycles - eventtab[ev_hsync].oldcycles;
- }
-
- static void calcdiw(void)
- {
- if (use_lores) {
- diwfirstword = (bpl_info.diwstrt & 0xFF) - 0x30 - 1;
- diwlastword = (bpl_info.diwstop & 0xFF) + 0x100 - 0x30 - 1;
- } else {
- diwfirstword = (bpl_info.diwstrt & 0xFF) * 2 - 0x60 - 2;
- diwlastword = (bpl_info.diwstop & 0xFF) * 2 + 0x200 - 0x60 - 2;
- }
- if (diwfirstword < 0) diwfirstword = 0;
- if (diwlastword > max_diwstop) max_diwstop = diwlastword;
-
- plffirstline = bpl_info.diwstrt >> 8;
- plflastline = bpl_info.diwstop >> 8;
- #if 0
- /* This happens far too often. */
- if (plffirstline < minfirstline) {
- fprintf(stderr, "Warning: Playfield begins before line %d!\n", minfirstline);
- plffirstline = minfirstline;
- }
- #endif
- if ((plflastline & 0x80) == 0) plflastline |= 0x100;
- #if 0 /* Turrican does this */
- if (plflastline > 313) {
- fprintf(stderr, "Warning: Playfield out of range!\n");
- plflastline = 313;
- }
- #endif
- plfstrt = bpl_info.ddfstrt;
- plfstop = bpl_info.ddfstop;
- if (plfstrt < 0x18) plfstrt = 0x18;
- if (plfstop > 0xD8) plfstop = 0xD8;
- if (plfstrt > plfstop) plfstrt = plfstop;
-
- /* ! If the masking operation is changed, the pfield_doline code could break
- * on some systems (alignment) */
- /* This actually seems to be correct now... */
- plfstrt &= ~3;
- plfstop &= ~3;
- plflinelen = (plfstop-plfstrt+15) & ~7;
- }
-
- /*
- * Screen update macros/functions
- */
-
- static void decode_ham6 (int pix, int stoppos)
- {
- static UWORD lastcolor;
- ULONG *buf = ham_linebuf;
-
- if (!bplham || bplplanecnt != 6)
- return;
-
- if (pix <= diwfirstword) {
- pix = diwfirstword;
- lastcolor = bpl_info.color_regs[0];
- }
-
- while (pix < diwlastword && pix < stoppos) {
- int pv = pixdata.apixels[pix];
- switch(pv & 0x30) {
- case 0x00: lastcolor = bpl_info.color_regs[pv]; break;
- case 0x10: lastcolor &= 0xFF0; lastcolor |= (pv & 0xF); break;
- case 0x20: lastcolor &= 0x0FF; lastcolor |= (pv & 0xF) << 8; break;
- case 0x30: lastcolor &= 0xF0F; lastcolor |= (pv & 0xF) << 4; break;
- }
-
- buf[pix++] = lastcolor;
- }
- }
-
- static void decode_ham_aga (int pix, int stoppos)
- {
- static ULONG lastcolor;
- ULONG *buf = ham_linebuf;
-
- if (!bplham || (bplplanecnt != 6 && bplplanecnt != 8))
- return;
-
- if (pix <= diwfirstword) {
- pix = diwfirstword;
- lastcolor = bpl_info.color_regs[0];
- }
-
- if (bplplanecnt == 6) {
- /* HAM 6 */
- while (pix < diwlastword && pix < stoppos) {
- int pv = pixdata.apixels[pix];
- switch(pv & 0x30) {
- case 0x00: lastcolor = bpl_info.color_regs[pv]; break;
- case 0x10: lastcolor &= 0xFFFF00; lastcolor |= (pv & 0xF)*0x11; break;
- case 0x20: lastcolor &= 0x00FFFF; lastcolor |= (pv & 0xF)*0x11 << 16; break;
- case 0x30: lastcolor &= 0xFF00FF; lastcolor |= (pv & 0xF)*0x11 << 8; break;
- }
- buf[pix++] = lastcolor;
- }
- } else if (bplplanecnt == 8) {
- /* HAM 8 */
- while (pix < diwlastword && pix < stoppos) {
- int pv = pixdata.apixels[pix];
- switch(pv & 0x3) {
- case 0x0: lastcolor = bpl_info.color_regs[pv >> 2]; break;
- case 0x1: lastcolor &= 0xFFFF03; lastcolor |= (pv & 0xFC); break;
- case 0x2: lastcolor &= 0x03FFFF; lastcolor |= (pv & 0xFC) << 16; break;
- case 0x3: lastcolor &= 0xFF03FF; lastcolor |= (pv & 0xFC) << 8; break;
- }
- buf[pix++] = lastcolor;
- }
- }
- }
-
- #define LINE_TO_SCR(NAME, TYPE, DO_DOUBLE) \
- static void NAME(int pix, int stoppos, int offset) \
- { \
- TYPE *buf = (TYPE *)xlinebuffer; \
- int oldpix = pix; \
- buf -= pix; \
- if (DO_DOUBLE) offset /= sizeof(TYPE); \
- while (pix < diwfirstword && pix < stoppos) { \
- TYPE d = acolors[0]; \
- buf[pix] = d; if (DO_DOUBLE) buf[pix+offset] = d; \
- pix++; \
- } \
- if (bplham && bplplanecnt == 6) { \
- /* HAM 6 */ \
- while (pix < diwlastword && pix < stoppos) { \
- TYPE d = xcolors[ham_linebuf[pix]]; \
- buf[pix] = d; if (DO_DOUBLE) buf[pix+offset] = d; \
- pix++; \
- } \
- } else if (bpldualpf) { \
- /* Dual playfield */ \
- int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; \
- while (pix < diwlastword && pix < stoppos) { \
- int pixcol = pixdata.apixels[pix]; \
- TYPE d; \
- if (spixstate[pix]) { \
- d = acolors[pixcol]; \
- } else { \
- d = acolors[lookup[pixcol]]; \
- } \
- buf[pix] = d; if (DO_DOUBLE) buf[pix+offset] = d; \
- pix++; \
- } \
- } else { \
- while (pix < diwlastword && pix < stoppos) { \
- TYPE d = acolors[pixdata.apixels[pix]]; \
- buf[pix] = d; if (DO_DOUBLE) buf[pix+offset] = d; \
- pix++; \
- } \
- } \
- while (pix < stoppos) { \
- TYPE d = acolors[0]; \
- buf[pix] = d; if (DO_DOUBLE) buf[pix+offset] = d; \
- pix++; \
- } \
- xlinebuffer = (char *)(((TYPE *)xlinebuffer) + pix - oldpix); \
- }
-
- /* WARNING: Not too much of this will work correctly yet. */
-
- static void pfield_linetoscr_aga(int pix, int stoppos)
- {
- ULONG *buf = aga_lbufptr;
- int i;
- int xor = (UBYTE)(bpl_info.bplcon4 >> 8);
- int oldpix = pix; \
-
- buf -= pix; \
-
- for (i = 0; i < stoppos; i++)
- pixdata.apixels[i] ^= xor;
-
- while (pix < diwfirstword && pix < stoppos) {
- buf[pix++] = bpl_info.color_regs[0];
- }
- if (bplham) {
- while (pix < diwlastword && pix < stoppos) {
- ULONG d = ham_linebuf[pix];
- buf[pix] = d;
- pix++;
- }
- } else if (bpldualpf) {
- /* Dual playfield */
- int *lookup = bpldualpfpri ? dblpf_aga2 : dblpf_aga1;
- int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1;
- while (pix < diwlastword && pix < stoppos) {
- int pixcol = pixdata.apixels[pix];
- int pfno = lookup_no[pixcol];
-
- if (spixstate[pix]) {
- buf[pix] = bpl_info.color_regs[pixcol];
- } else {
- int val = lookup[pixdata.apixels[pix]];
- if (pfno == 2)
- val += dblpfofs[(bpl_info.bplcon2 >> 10) & 7];
- buf[pix] = bpl_info.color_regs[val];
- }
- pix++;
- }
- } else if (bplehb) {
- while (pix < diwlastword && pix < stoppos) {
- int pixcol = pixdata.apixels[pix];
- ULONG d = bpl_info.color_regs[pixcol];
- /* What about sprites? */
- if (pixcol & 0x20)
- d = (d & 0x777777) >> 1;
- buf[pix] = d;
- pix++;
- }
- } else {
- while (pix < diwlastword && pix < stoppos) {
- int pixcol = pixdata.apixels[pix];
- buf[pix] = bpl_info.color_regs[pixcol];
- pix++;
- }
- }
- while (pix < stoppos) {
- buf[pix++] = bpl_info.color_regs[0];
- }
- aga_lbufptr += pix - oldpix;
- }
-
- static void aga_translate32(int start, int stop)
- {
- memcpy (((ULONG *)xlinebuffer) + start, aga_linebuf + start, 4*(stop-start));
- }
-
- static void aga_translate16(int start, int stop)
- {
- int i;
- for (i = start; i < stop; i++) {
- ULONG d = aga_linebuf[i];
- UWORD v = ((d & 0xF0) >> 4) | ((d & 0xF000) >> 8) | ((d & 0xF00000) >> 12);
- ((UWORD *)xlinebuffer)[i] = xcolors[v];
- }
- }
-
- static void aga_translate8(int start, int stop)
- {
- int i;
- for (i = start; i < stop; i++) {
- ULONG d = aga_linebuf[i];
- UWORD v = ((d & 0xF0) >> 4) | ((d & 0xF000) >> 8) | ((d & 0xF00000) >> 12);
- ((UBYTE *)xlinebuffer)[i] = xcolors[v];
- }
- }
-
-
-
- #define FILL_LINE(NAME, TYPE) \
- static void NAME(char *buf) \
- { \
- TYPE *b = (TYPE *)buf; \
- int i;\
- int maxpos = gfxvidinfo.maxlinetoscr; \
- xcolnr col = acolors[0]; \
- if (!maxpos) maxpos = 796; \
- for (i = 0; i < maxpos; i++) \
- *b++ = col; \
- }
-
- LINE_TO_SCR(pfield_linetoscr_8, UBYTE, 0)
- LINE_TO_SCR(pfield_linetoscr_16, UWORD, 0)
- LINE_TO_SCR(pfield_linetoscr_32, ULONG, 0)
- LINE_TO_SCR(pfield_linetoscr_8_double_slow, UBYTE, 1)
- LINE_TO_SCR(pfield_linetoscr_16_double_slow, UWORD, 1)
- LINE_TO_SCR(pfield_linetoscr_32_double_slow, ULONG, 1)
-
- FILL_LINE(fill_line_8, UBYTE)
- FILL_LINE(fill_line_16, UWORD)
- FILL_LINE(fill_line_32, ULONG)
-
- #define pfield_linetoscr_full8 pfield_linetoscr_8
- #define pfield_linetoscr_full16 pfield_linetoscr_16
- #define pfield_linetoscr_full32 pfield_linetoscr_32
-
- #define pfield_linetoscr_full8_double pfield_linetoscr_8_double_slow
- #define pfield_linetoscr_full16_double pfield_linetoscr_16_double_slow
- #define pfield_linetoscr_full32_double pfield_linetoscr_32_double_slow
-
- #if 1 && defined(X86_ASSEMBLY)
- #undef pfield_linetoscr_full8
- #undef pfield_linetoscr_full16
- extern void pfield_linetoscr_full8(int, int, int) __asm__("pfield_linetoscr_full8");
- extern void pfield_linetoscr_full16(int, int, int) __asm__("pfield_linetoscr_full16");
- #undef pfield_linetoscr_full8_double
- #undef pfield_linetoscr_full16_double
-
- static void pfield_linetoscr_full8_double(int start, int stop, int offset)
- {
- char *oldxlb = (char *)xlinebuffer;
- pfield_linetoscr_full8(start,stop,offset);
- xlinebuffer = oldxlb + offset;
- pfield_linetoscr_full8(start,stop,offset);
- }
- static void pfield_linetoscr_full16_double(int start, int stop, int offset)
- {
- char *oldxlb = (char *)xlinebuffer;
- pfield_linetoscr_full16(start,stop,offset);
- xlinebuffer = oldxlb + offset;
- pfield_linetoscr_full16(start,stop,offset);
- }
- #endif
-
- static __inline__ void fill_line(int y)
- {
- switch (gfxvidinfo.pixbytes) {
- case 1: fill_line_8(gfxvidinfo.bufmem + gfxvidinfo.rowbytes * y); break;
- case 2: fill_line_16(gfxvidinfo.bufmem + gfxvidinfo.rowbytes * y); break;
- case 4: fill_line_32(gfxvidinfo.bufmem + gfxvidinfo.rowbytes * y); break;
- }
- }
-
- static void pfield_do_linetoscr(int start, int stop)
- {
- int factor = use_lores ? 1 : 2;
- int oldstop = stop;
- int real_start, real_stop;
-
- start = PIXEL_XPOS(start);
- if (start < 8*factor)
- start = 8*factor;
- stop = PIXEL_XPOS(stop);
- if (stop > 406*factor)
- stop = 406*factor;
-
- if (start >= stop)
- return;
- if (stop <= gfxvidinfo.x_adjust)
- return;
-
- slowline_lasttoscr = oldstop;
-
- if (start < gfxvidinfo.x_adjust)
- real_start = gfxvidinfo.x_adjust;
- else
- real_start = start;
-
- if (gfxvidinfo.maxlinetoscr) {
- real_stop = gfxvidinfo.x_adjust + gfxvidinfo.maxlinetoscr;
- if (real_stop > stop)
- real_stop = stop;
- } else
- real_stop = stop;
-
- #if AGA_CHIPSET == 0
- if (start == 8*factor && stop == 406*factor) {
- switch (gfxvidinfo.pixbytes) {
- case 1: pfield_linetoscr_full8 (real_start, real_stop, 0); break;
- case 2: pfield_linetoscr_full16 (real_start, real_stop, 0); break;
- case 4: pfield_linetoscr_full32 (real_start, real_stop, 0); break;
- }
- } else {
- if (real_start >= real_stop)
- return;
- switch (gfxvidinfo.pixbytes) {
- case 1: pfield_linetoscr_8 (real_start, real_stop, 0); break;
- case 2: pfield_linetoscr_16 (real_start, real_stop, 0); break;
- case 4: pfield_linetoscr_32 (real_start, real_stop, 0); break;
- }
- }
- #else
- pfield_linetoscr_aga(real_start, real_stop);
- #endif
- }
-
- static void pfield_do_linetoscr_full(int double_line)
- {
- int factor = use_lores ? 1 : 2;
- int stop, start;
-
- start = 8*factor;
- stop = 406*factor;
-
- if (start < gfxvidinfo.x_adjust)
- start = gfxvidinfo.x_adjust;
-
- if (gfxvidinfo.maxlinetoscr) {
- int tmp = gfxvidinfo.x_adjust + gfxvidinfo.maxlinetoscr;
- if (tmp < stop)
- stop = tmp;
- }
-
- #if AGA_CHIPSET == 0
- if (double_line) {
- switch (gfxvidinfo.pixbytes) {
- case 1: pfield_linetoscr_full8_double (start, stop, gfxvidinfo.rowbytes); break;
- case 2: pfield_linetoscr_full16_double (start, stop, gfxvidinfo.rowbytes); break;
- case 4: pfield_linetoscr_full32_double (start, stop, gfxvidinfo.rowbytes); break;
- }
- } else
- switch (gfxvidinfo.pixbytes) {
- case 1: pfield_linetoscr_full8 (start, stop, 0); break;
- case 2: pfield_linetoscr_full16 (start, stop, 0); break;
- case 4: pfield_linetoscr_full32 (start, stop, 0); break;
- }
- #else
- pfield_linetoscr_aga(start, stop);
- #endif
- }
-
- /*
- * This function is called whenever a hardware register that controls the
- * screen display is modified. Usually, this routine does nothing. But in
- * some cases, e.g., when a color changes in mid-screen, as in copper-plasma
- * effects, this function switches the update method from the fast full-line
- * update to the much slower single-color-clock update.
- */
- static void pfield_may_need_update(int colreg)
- {
- int i;
-
- /* Ignore, if this happened before or after the DDF window */
- if (framecnt != 0 || !pfield_linedmaon || current_hpos() <= plfstrt
- || vpos < plffirstline || vpos < minfirstline || vpos >= plflastline
- || next_lineno >= gfxvidinfo.maxline)
- {
- return;
- }
- /*
- * If a color reg was modified, it is only important if we are within
- * the DIW.
- */
- if (PIXEL_XPOS(current_hpos()) <= diwfirstword && colreg)
- return;
-
- /*
- * If we are past the DDF window, me might as well draw the complete
- * line now.
- */
- if (current_hpos() > plfstrt + plflinelen && pfield_fullline) {
- if (!pfield_linedone)
- pfield_doline();
- pfield_linedone = 1;
- return;
- }
-
- do_sprites(vpos, current_hpos());
- if (pfield_fullline) {
- pfield_lastpart_hpos = 0;
- memset(pixdata.apixels, 0, sizeof(pixdata.apixels));
- memset(spixstate,0,sizeof spixstate);
- pfield_fullline = 0;
- slowline_nextpos = -1;
- slowline_linepos = 0;
- slowline_lasttoscr = 0;
- } else {
- assert(pfield_lastpart_hpos <= current_hpos());
- }
- for (i = pfield_lastpart_hpos; i < current_hpos(); i++) {
- pfield_doline_slow(i);
- }
- if (colreg) {
- pfield_do_linetoscr(slowline_lasttoscr, current_hpos());
- }
- pfield_lastpart_hpos = current_hpos();
- }
-
- /* Apparently, the DMA bit is tested by the hardware at some point,
- * presumably at the ddfstart position, to determine whether it
- * ought to draw the line.
- * This is probably not completely correct, but should not matter
- * very much.
- */
- static void pfield_calclinedma(void)
- {
- if (current_hpos() >= plfstrt)
- return;
-
- pfield_linedmaon = dmaen(DMA_BITPLANE);
- }
-
- /*
- * register functions
- */
-
- static UWORD DMACONR(void)
- {
- return (dmacon | (bltstate==BLT_done ? 0 : 0x4000)
- | (blt_info.blitzero ? 0x2000 : 0));
- }
- static UWORD INTENAR(void) { return intena; }
- static UWORD INTREQR(void) { return intreq; }
- static UWORD ADKCONR(void) { return adkcon; }
- static UWORD VPOSR(void)
- {
- #if AGA_CHIPSET == 1
- return (vpos >> 8) | lof | 0x2300;
- #elif defined (ECS_AGNUS)
- return (vpos >> 8) | lof | 0x2000;
- #else
- return (vpos >> 8) | lof;
- #endif
- }
- static void VPOSW(UWORD v) { lof = v & 0x8000; }
- static UWORD VHPOSR(void) { return (vpos << 8) | current_hpos(); }
-
- static void COP1LCH(UWORD v) { cop1lc= (cop1lc & 0xffff) | ((ULONG)v << 16); }
- static void COP1LCL(UWORD v) { cop1lc= (cop1lc & ~0xffff) | v; }
- static void COP2LCH(UWORD v) { cop2lc= (cop2lc & 0xffff) | ((ULONG)v << 16); }
- static void COP2LCL(UWORD v) { cop2lc= (cop2lc & ~0xffff) | v; }
-
- static void COPJMP1(UWORD a)
- {
- coplc = cop1lc; copstate = COP_read;
- eventtab[ev_copper].active = 1; eventtab[ev_copper].oldcycles = cycles;
- eventtab[ev_copper].evtime = 4; events_schedule();
- copper_active = 1;
- }
- static void COPJMP2(UWORD a)
- {
- coplc = cop2lc; copstate = COP_read;
- eventtab[ev_copper].active = 1; eventtab[ev_copper].oldcycles = cycles;
- eventtab[ev_copper].evtime = 4; events_schedule();
- copper_active = 1;
- }
-
- static void DMACON(UWORD v)
- {
- UWORD oldcon = dmacon;
- setclr(&dmacon,v); dmacon &= 0x1FFF;
- pfield_calclinedma();
-
- /* FIXME? Maybe we need to think a bit more about the master DMA enable
- * bit in these cases. */
- if ((dmacon & DMA_COPPER) > (oldcon & DMA_COPPER)) {
- COPJMP1(0);
- }
- if ((dmacon & DMA_SPRITE) > (oldcon & DMA_SPRITE)) {
- int i;
- for (i = 0; i < 8; i++)
- spron[i] = 1;
- }
- if ((dmacon & DMA_BLITPRI) > (oldcon & DMA_BLITPRI) && bltstate != BLT_done) {
- static int count = 0;
- if (!count) {
- count = 1;
- fprintf(stderr, "warning: Program is doing blitpri hacks.\n");
- }
- specialflags |= SPCFLAG_BLTNASTY;
- }
- if (copper_active && !eventtab[ev_copper].active) {
- eventtab[ev_copper].active = 1;
- eventtab[ev_copper].oldcycles = cycles;
- eventtab[ev_copper].evtime = 1;
- events_schedule();
- }
- }
- static void INTENA(UWORD v) { setclr(&intena,v); specialflags |= SPCFLAG_INT; }
- void INTREQ(UWORD v) { setclr(&intreq,v); specialflags |= SPCFLAG_INT; }
- static void ADKCON(UWORD v) { setclr(&adkcon,v); }
-
- static void BPLPTH(UWORD v, int num) { bplpt[num] = (bplpt[num] & 0xffff) | ((ULONG)v << 16); }
- static void BPLPTL(UWORD v, int num) { bplpt[num] = (bplpt[num] & ~0xffff) | (v & 0xFFFE); }
-
- /*
- * I've seen the listing of an example program that changes
- * from lo- to hires while a line is being drawn. That's
- * awful, but we want to emulate it.
- */
- static void BPLCON0(UWORD v)
- {
- if (bpl_info.bplcon0 == v)
- return;
- pfield_may_need_update(0);
- bpl_info.bplcon0 = v;
- bplhires = (v & 0x8000) == 0x8000;
- bplplanecnt = (v & 0x7000) >> 12;
- bplham = (v & 0x800) == 0x800;
- bpldualpf = (v & 0x400) == 0x400;
- bplehb = (v & 0xFDC0) == 0x6000 && !(bpl_info.bplcon2 & 0x200); /* see below */
- calcdiw(); /* This should go away. */
- }
- static void BPLCON1(UWORD v)
- {
- if (bpl_info.bplcon1 == v)
- return;
- pfield_may_need_update(0);
- bpl_info.bplcon1 = v;
- bpldelay1 = v & 0xF;
- bpldelay2 = (v >> 4) & 0xF;
- }
- static void BPLCON2(UWORD v)
- {
- if (bpl_info.bplcon2 == v)
- return;
- pfield_may_need_update(0);
- bpl_info.bplcon2 = v;
- bpldualpfpri = (v & 0x40) == 0x40;
- plfpri[1] = 1 << 2*(v & 7);
- plfpri[2] = 1 << 2*((v>>3) & 7);
- bplehb = (bpl_info.bplcon0 & 0xFDC0) == 0x6000 && !(v & 0x200); /* see above */
- }
- static void BPLCON3(UWORD v)
- {
- if (bpl_info.bplcon3 == v)
- return;
- pfield_may_need_update(0);
- bpl_info.bplcon3 = v;
- }
- static void BPLCON4(UWORD v)
- {
- if (bpl_info.bplcon4 == v)
- return;
- pfield_may_need_update(0);
- bpl_info.bplcon4 = v;
- }
-
- static void BPL1MOD(UWORD v)
- {
- v &= ~1;
- if (bpl1mod == v)
- return;
- pfield_may_need_update(0);
- bpl1mod = v;
- }
- static void BPL2MOD(UWORD v)
- {
- v &= ~1;
- if (bpl2mod == v)
- return;
- pfield_may_need_update(0);
- bpl2mod = v;
- }
-
- static void BPL1DAT(UWORD v) { bpl1dat = v; }
- static void BPL2DAT(UWORD v) { bpl2dat = v; }
- static void BPL3DAT(UWORD v) { bpl3dat = v; }
- static void BPL4DAT(UWORD v) { bpl4dat = v; }
- static void BPL5DAT(UWORD v) { bpl5dat = v; }
- static void BPL6DAT(UWORD v) { bpl6dat = v; }
-
- /* We call pfield_may_need_update() from here. Actually,
- * I have no idea what happens if someone changes ddf or
- * diw mid-line, and I don't really want to know. I doubt
- * that this sort of thing was ever used to create a
- * useful effect.
- */
- static void DIWSTRT(UWORD v)
- {
- if (bpl_info.diwstrt == v)
- return;
- pfield_may_need_update(0);
- bpl_info.diwstrt = v;
- calcdiw();
- }
- static void DIWSTOP(UWORD v)
- {
- if (bpl_info.diwstop == v)
- return;
- pfield_may_need_update(0);
- bpl_info.diwstop = v;
- calcdiw();
- }
- static void DDFSTRT(UWORD v)
- {
- if (bpl_info.ddfstrt == v)
- return;
- pfield_may_need_update(0);
- bpl_info.ddfstrt = v;
- calcdiw();
- }
- static void DDFSTOP(UWORD v)
- {
- if (bpl_info.ddfstop == v)
- return;
- pfield_may_need_update(0);
- bpl_info.ddfstop = v;
- calcdiw();
- }
-
- static void BLTADAT(UWORD v)
- {
- maybe_blit();
- blt_info.bltadat = v;
- }
- static void BLTBDAT(UWORD v)
- {
- maybe_blit();
- blt_info.bltbdat = v;
- }
- static void BLTCDAT(UWORD v) { maybe_blit(); blt_info.bltcdat = v; }
-
- static void BLTAMOD(UWORD v) { maybe_blit(); blt_info.bltamod = v & 0xFFFE; }
- static void BLTBMOD(UWORD v) { maybe_blit(); blt_info.bltbmod = v & 0xFFFE; }
- static void BLTCMOD(UWORD v) { maybe_blit(); blt_info.bltcmod = v & 0xFFFE; }
- static void BLTDMOD(UWORD v) { maybe_blit(); blt_info.bltdmod = v & 0xFFFE; }
-
- static void BLTCON0(UWORD v) { maybe_blit(); bltcon0 = v; }
- /* The next category is "Most useless hardware register".
- * And the winner is... */
- static void BLTCON0L(UWORD v) { maybe_blit(); bltcon0 = (bltcon0 & 0xFF00) | (v & 0xFF); }
- static void BLTCON1(UWORD v) { maybe_blit(); bltcon1 = v; }
-
- static void BLTAFWM(UWORD v) { maybe_blit(); blt_info.bltafwm = v; }
- static void BLTALWM(UWORD v) { maybe_blit(); blt_info.bltalwm = v; }
-
- static void BLTAPTH(UWORD v) { maybe_blit(); bltapt= (bltapt & 0xffff) | ((ULONG)(v & 0x1F) << 16); }
- static void BLTAPTL(UWORD v) { maybe_blit(); bltapt= (bltapt & ~0xffff) | (v & 0xFFFE); }
- static void BLTBPTH(UWORD v) { maybe_blit(); bltbpt= (bltbpt & 0xffff) | ((ULONG)(v & 0x1F) << 16); }
- static void BLTBPTL(UWORD v) { maybe_blit(); bltbpt= (bltbpt & ~0xffff) | (v & 0xFFFE); }
- static void BLTCPTH(UWORD v) { maybe_blit(); bltcpt= (bltcpt & 0xffff) | ((ULONG)(v & 0x1F) << 16); }
- static void BLTCPTL(UWORD v) { maybe_blit(); bltcpt= (bltcpt & ~0xffff) | (v & 0xFFFE); }
- static void BLTDPTH(UWORD v) { maybe_blit(); bltdpt= (bltdpt & 0xffff) | ((ULONG)(v & 0x1F) << 16); }
- static void BLTDPTL(UWORD v) { maybe_blit(); bltdpt= (bltdpt & ~0xffff) | (v & 0xFFFE); }
- static void BLTSIZE(UWORD v)
- {
- bltsize = v;
-
- maybe_blit();
-
- blt_info.vblitsize = bltsize >> 6;
- blt_info.hblitsize = bltsize & 0x3F;
- if (!blt_info.vblitsize) blt_info.vblitsize = 1024;
- if (!blt_info.hblitsize) blt_info.hblitsize = 64;
-
- bltstate = BLT_init;
- specialflags |= SPCFLAG_BLIT;
- }
- static void BLTSIZV(UWORD v)
- {
- maybe_blit();
- oldvblts = v & 0x7FFF;
- }
- static void BLTSIZH(UWORD v)
- {
- maybe_blit();
- blt_info.hblitsize = v & 0x7FF;
- blt_info.vblitsize = oldvblts;
- if (!blt_info.vblitsize) blt_info.vblitsize = 32768;
- if (!blt_info.hblitsize) blt_info.hblitsize = 0x800;
- bltstate = BLT_init;
- specialflags |= SPCFLAG_BLIT;
- }
- static void SPRxCTL_1(UWORD v, int num)
- {
- bpl_info.sprctl[num] = v;
- bpl_info.sprarmed[num] = 0;
- if (bpl_info.sprpos[num] == 0 && v == 0)
- spron[num] = 0;
- else
- spron[num] |= 2;
- }
- static void SPRxPOS_1(UWORD v, int num)
- {
- bpl_info.sprpos[num] = v;
- }
- static void SPRxDATA_1(UWORD v, int num)
- {
- bpl_info.sprdata[num] = v;
- bpl_info.sprarmed[num] = 1;
- }
- static void SPRxDATB_1(UWORD v, int num)
- {
- bpl_info.sprdatb[num] = v;
- }
- static void SPRxCTL(UWORD v, int num) { pfield_may_need_update(0); SPRxCTL_1(v, num); }
- static void SPRxPOS(UWORD v, int num) { pfield_may_need_update(0); SPRxPOS_1(v, num); }
- static void SPRxDATA(UWORD v, int num){ pfield_may_need_update(0); SPRxDATA_1(v, num); }
- static void SPRxDATB(UWORD v, int num){ pfield_may_need_update(0); SPRxDATB_1(v, num); }
- static void SPRxPTH(UWORD v, int num)
- {
- sprpt[num] &= 0xffff;
- sprpt[num] |= (ULONG)v << 16;
- if (!spron[num]) spron[num] = 1;
- }
- static void SPRxPTL(UWORD v, int num)
- {
- sprpt[num] &= ~0xffff;
- sprpt[num] |= v;
- if (!spron[num]) spron[num] = 1;
- }
-
- static void COLOR(UWORD v, int num)
- {
- int r,g,b;
- int cr,cg,cb;
- int colreg;
-
- v &= 0xFFF;
- #if AGA_CHIPSET == 1
- {
- ULONG cval;
- colreg = ((bpl_info.bplcon3 >> 13) & 7) * 32 + num;
- r = (v & 0xF00) >> 8;
- g = (v & 0xF0) >> 4;
- b = (v & 0xF) >> 0;
- cr = bpl_info.color_regs[colreg] >> 16;
- cg = (bpl_info.color_regs[colreg] >> 8) & 0xFF;
- cb = bpl_info.color_regs[colreg] & 0xFF;
-
- if (bpl_info.bplcon3 & 0x200) {
- cr &= 0xF0; cr |= r;
- cg &= 0xF0; cg |= g;
- cb &= 0xF0; cb |= b;
- } else {
- cr = r + (r << 4);
- cg = g + (g << 4);
- cb = b + (b << 4);
- }
- cval = (cr << 16) | (cg << 8) | cb;
- if (cval == bpl_info.color_regs[colreg])
- return;
- bpl_info.color_regs[colreg] = cval;
- pfield_may_need_update(1);
- }
- #else
- {
- if (bpl_info.color_regs[num] == v)
- return;
- pfield_may_need_update(1);
- bpl_info.color_regs[num] = v;
- acolors[num] = xcolors[v];
- acolors[num+32] = xcolors[(v >> 1) & 0x777];
- }
- #endif
- }
-
- static void DSKSYNC(UWORD v) { dsksync = v; }
- static void DSKDAT(UWORD v) { fprintf(stderr, "DSKDAT written. Not good.\n"); }
- static void DSKPTH(UWORD v) { dskpt = (dskpt & 0xffff) | ((ULONG)v << 16); }
- static void DSKPTL(UWORD v) { dskpt = (dskpt & ~0xffff) | (v); }
-
- static void DSKLEN(UWORD v)
- {
- if (v & 0x8000) {
- dskdmaen++;
- } else {
- dskdmaen = 0;
- if (eventtab[ev_diskblk].active)
- fprintf(stderr, "warning: Disk DMA aborted!\n");
- eventtab[ev_diskblk].active = 0;
- events_schedule();
-
- }
- dsklen = dsklength = v; dsklength &= 0x3fff;
- if (dskdmaen == 2 && dsksync != 0x4489 && (adkcon & 0x400)) {
- fprintf(stderr, "Non-standard sync: %04x len: %x\n", dsksync, dsklength);
- }
- if (dskdmaen > 1) {
- if (dsklen & 0x4000) {
- eventtab[ev_diskblk].active = 1;
- eventtab[ev_diskblk].oldcycles = cycles;
- eventtab[ev_diskblk].evtime = 40; /* ??? */
- events_schedule();
- } else {
- int result = DISK_PrepareReadMFM(dsklength, dsksync, adkcon & 0x400);
- if (result) {
- eventtab[ev_diskblk].active = 1;
- eventtab[ev_diskblk].oldcycles = cycles;
- eventtab[ev_diskblk].evtime = result;
- events_schedule();
- }
- }
- }
- }
-
- static UWORD DSKBYTR(void)
- {
- UWORD v = (dsklen >> 1) & 0x6000;
- UWORD mfm, byte;
- if (DISK_GetData(&mfm, &byte))
- v |= 0x8000;
- v |= byte;
- if (dsksync == mfm) v |= 0x1000;
- return v;
- }
-
- static UWORD DSKDATR(void)
- {
- UWORD mfm, byte;
- DISK_GetData(&mfm, &byte);
- return mfm;
- }
- static UWORD POTGOR(void)
- {
- UWORD v = 0xFFFF;
- if (buttonstate[2])
- v &= 0xFBFF;
-
- if (buttonstate[1])
- v &= 0xFEFF;
-
- return v;
- }
- static UWORD POT0DAT(void)
- {
- static UWORD cnt = 0;
- if (buttonstate[2])
- cnt = ((cnt + 1) & 0xFF) | (cnt & 0xFF00);
- if (buttonstate[1])
- cnt += 0x100;
-
- return cnt;
- }
- static UWORD JOY0DAT(void) { return joy0x + (joy0y << 8); }
- static UWORD JOY1DAT(void)
- {
- return joy0dir;
- }
- static void JOYTEST(UWORD v)
- {
- joy0x = joy1x = v & 0xFC;
- joy0y = joy1y = (v >> 8) & 0xFC;
- }
- static void AUD0LCH(UWORD v) { audlc[0] = (audlc[0] & 0xffff) | ((ULONG)v << 16); }
- static void AUD0LCL(UWORD v) { audlc[0] = (audlc[0] & ~0xffff) | v; }
- static void AUD1LCH(UWORD v) { audlc[1] = (audlc[1] & 0xffff) | ((ULONG)v << 16); }
- static void AUD1LCL(UWORD v) { audlc[1] = (audlc[1] & ~0xffff) | v; }
- static void AUD2LCH(UWORD v) { audlc[2] = (audlc[2] & 0xffff) | ((ULONG)v << 16); }
- static void AUD2LCL(UWORD v) { audlc[2] = (audlc[2] & ~0xffff) | v; }
- static void AUD3LCH(UWORD v) { audlc[3] = (audlc[3] & 0xffff) | ((ULONG)v << 16); }
- static void AUD3LCL(UWORD v) { audlc[3] = (audlc[3] & ~0xffff) | v; }
- static void AUD0PER(UWORD v) { audper[0] = v; }
- static void AUD1PER(UWORD v) { audper[1] = v; }
- static void AUD2PER(UWORD v) { audper[2] = v; }
- static void AUD3PER(UWORD v) { audper[3] = v; }
- static void AUD0VOL(UWORD v) { audvol[0] = v & 64 ? 63 : v & 63; }
- static void AUD1VOL(UWORD v) { audvol[1] = v & 64 ? 63 : v & 63; }
- static void AUD2VOL(UWORD v) { audvol[2] = v & 64 ? 63 : v & 63; }
- static void AUD3VOL(UWORD v) { audvol[3] = v & 64 ? 63 : v & 63; }
- static void AUD0LEN(UWORD v) { audlen[0] = v; }
- static void AUD1LEN(UWORD v) { audlen[1] = v; }
- static void AUD2LEN(UWORD v) { audlen[2] = v; }
- static void AUD3LEN(UWORD v) { audlen[3] = v; }
-
- static UWORD SERDATR(void) { return 0; }
-
- static int copcomp(void)
- {
- UWORD vp = vpos & (((copi2 >> 8) & 0x7F) | 0x80);
- UWORD hp = current_hpos() & (copi2 & 0xFE);
- UWORD vcmp = copi1 >> 8;
- UWORD hcmp = copi1 & 0xFE;
- return (vp > vcmp || (vp == vcmp && hp >= hcmp)) && ((copi2 & 0x8000) || !(DMACONR() & 0x4000));
- }
-
- /*
- * Calculate the minimum number of cycles after which the
- * copper comparison becomes true. This is quite tricky. I hope it works.
- */
- static int calc_copcomp_true(int currvpos, int currhpos)
- {
- UWORD vp = currvpos & (((copi2 >> 8) & 0x7F) | 0x80);
- UWORD hp = currhpos & (copi2 & 0xFE);
- UWORD vcmp = copi1 >> 8;
- UWORD hcmp = copi1 & 0xFE;
- int copper_time_hpos;
- int cycleadd = maxhpos - currhpos;
- int coptime = 0;
-
- if ((vp > vcmp || (vp == vcmp && hp >= hcmp)) && ((copi2 & 0x8000) || !(DMACONR() & 0x4000)))
- return 0;
-
- try_again:
-
- while (vp < vcmp) {
- currvpos++;
- if (currvpos > maxvpos + 1)
- return -1;
- currhpos = 0;
- coptime += cycleadd;
- cycleadd = maxhpos;
- vp = currvpos & (((copi2 >> 8) & 0x7F) | 0x80);
- }
- if (coptime > 0 && bplhires && bplplanecnt == 4)
- return coptime;
- copper_time_hpos = currhpos;
- hp = copper_time_hpos & (copi2 & 0xFE);
- if (!(vp > vcmp)) {
- while (hp < hcmp-2) {
- currhpos++;
- /* Copper DMA is turned off in Hires 4 bitplane mode */
- if (!bplhires || bplplanecnt < 4 || !dmaen(DMA_BITPLANE)
- || currhpos < plfstrt-2 || currhpos > (plfstop+4))
- copper_time_hpos++;
-
- if (currhpos > maxhpos-4) {
- /* Now, what? There might be a good position on the
- * next line. But it can also be the FFFF FFFE
- * case.
- */
- currhpos = 0;
- currvpos++;
- vp = currvpos & (((copi2 >> 8) & 0x7F) | 0x80);
- goto try_again;
- }
- coptime++;
- hp = copper_time_hpos & (copi2 & 0xFE);
- }
- }
- if (coptime == 0) /* waiting for the blitter */
- return 1;
-
- return coptime;
- }
-
- static void copper_read(void)
- {
- if (dmaen(DMA_COPPER)){
- copi1 = chipmem_bank.wget(coplc);
- copi2 = chipmem_bank.wget(coplc+2);
- coplc += 4;
- eventtab[ev_copper].oldcycles = cycles;
- eventtab[ev_copper].evtime = (copi1 & 1) ? (copi2 & 1) ? 10 : 8 : 4;
- copstate = (copi1 & 1) ? (copi2 & 1) ? COP_skip : COP_wait : COP_move;
- } else {
- copstate = COP_read;
- eventtab[ev_copper].active = 0;
- }
- }
-
- static void do_copper(void)
- {
- switch(copstate){
- case COP_read:
- copper_read();
- break;
- case COP_move:
- if (copi1 >= (copcon & 2 ? 0x40 : 0x80)) {
- custom_bank.wput(copi1,copi2);
- copper_read();
- } else {
- copstate = COP_stop;
- eventtab[ev_copper].active = 0;
- copper_active = 0;
- }
- break;
- case COP_skip:
- if (calc_copcomp_true(vpos, current_hpos()) == 0)
- coplc += 4;
- copper_read();
- break;
- case COP_wait: {
- int coptime = calc_copcomp_true(vpos, current_hpos());
- if (coptime < 0) {
- copstate = COP_stop;
- eventtab[ev_copper].active = 0;
- copper_active = 0;
- } else {
- if (!coptime)
- copper_read();
- else {
- eventtab[ev_copper].evtime = coptime;
- eventtab[ev_copper].oldcycles = cycles;
- }
- }
- break;
- }
- case COP_stop:
- eventtab[ev_copper].active = 0;
- copper_active = 0;
- break;
- }
- }
-
- static void diskblk_handler(void)
- {
- specialflags |= SPCFLAG_DISK;
- eventtab[ev_diskblk].active = 0;
- }
-
- void do_disk(void)
- {
- if (dskdmaen != 2 && (specialflags & SPCFLAG_DISK)) {
- static int warned=0;
- if(!warned) {fprintf(stderr, "BUG!\n");warned=1;return;}
- }
- if (dmaen(0x10)){
- if (dsklen & 0x4000) {
- if (!chipmem_bank.check (dskpt, 2*dsklength)) {
- fprintf(stderr, "warning: Bad disk write DMA pointer\n");
- } else {
- UWORD *mfmp = get_real_address (dskpt);
- DISK_InitWrite();
- memcpy (mfmwrite, mfmp, 2*dsklength);
- DISK_WriteData(dsklength);
- }
- } else {
- int result = DISK_ReadMFM (dskpt);
- }
- specialflags &= ~SPCFLAG_DISK;
- INTREQ(0x9002);
- dskdmaen = -1;
- }
- }
-
- static __inline__ void pfield_fetchdata(void)
- {
- if (dmaen(0x100) && pfield_linedmaon) {
- switch(bplplanecnt){
- case 8:
- bpl8dat = chipmem_bank.wget(bplpt[7]); bplpt[7] += 2; bpl8dat <<= 7;
- case 7:
- bpl7dat = chipmem_bank.wget(bplpt[6]); bplpt[6] += 2; bpl7dat <<= 6;
- case 6:
- bpl6dat = chipmem_bank.wget(bplpt[5]); bplpt[5] += 2; bpl6dat <<= 5;
- case 5:
- bpl5dat = chipmem_bank.wget(bplpt[4]); bplpt[4] += 2; bpl5dat <<= 4;
- case 4:
- bpl4dat = chipmem_bank.wget(bplpt[3]); bplpt[3] += 2; bpl4dat <<= 3;
- case 3:
- bpl3dat = chipmem_bank.wget(bplpt[2]); bplpt[2] += 2; bpl3dat <<= 2;
- case 2:
- bpl2dat = chipmem_bank.wget(bplpt[1]); bplpt[1] += 2; bpl2dat <<= 1;
- case 1:
- bpl1dat = chipmem_bank.wget(bplpt[0]); bplpt[0] += 2;
- }
- }
- }
-
- static void do_sprites(int currvp, int currhp)
- {
- int i;
- int maxspr = currhp/4 -0x18/ 4;
-
- if (currvp == 0)
- return;
- if (maxspr < 0)
- return;
- if (maxspr > 7)
- maxspr = 7;
-
- for(i = last_sprite; i <= maxspr; i++) {
- int vstart = (bpl_info.sprpos[i] >> 8) | ((bpl_info.sprctl[i] << 6) & 0x100);
- int vstop = (bpl_info.sprctl[i] >> 8) | ((bpl_info.sprctl[i] << 7) & 0x100);
- if ((vstart <= currvp && vstop >= currvp) || spron[i] == 1) {
- if (dmaen(0x20)) {
- UWORD data1 = chipmem_bank.wget(sprpt[i]);
- UWORD data2 = chipmem_bank.wget(sprpt[i]+2);
- sprpt[i] += 4;
-
- if (vstop != currvp && spron[i] != 1) {
- /* Hack for X mouse auto-calibration */
- if (i == 0 && !sprvbfl && ((bpl_info.sprpos[0]&0xff)<<2)>0x60) {
- int old0ctl = spr0ctl, old0pos = spr0pos;
- spr0ctl=bpl_info.sprctl[0];
- spr0pos=bpl_info.sprpos[0];
- sprvbfl=2;
- }
- SPRxDATB_1(data2, i);
- SPRxDATA_1(data1, i);
- } else {
- SPRxPOS_1(data1, i);
- SPRxCTL_1(data2, i);
- }
- }
- }
- }
- last_sprite = maxspr + 1;
- }
-
- static __inline__ void pfield_modulos(int add)
- {
- switch(bplplanecnt){
- case 8:
- bplpt[7] += add + bpl2mod;
- case 7:
- bplpt[6] += add + bpl1mod;
- case 6:
- bplpt[5] += add + bpl2mod;
- case 5:
- bplpt[4] += add + bpl1mod;
- case 4:
- bplpt[3] += add + bpl2mod;
- case 3:
- bplpt[2] += add + bpl1mod;
- case 2:
- bplpt[1] += add + bpl2mod;
- case 1:
- bplpt[0] += add + bpl1mod;
- }
- }
-
- #if AGA_CHIPSET == 0
- static void pfield_sprite (int num, int sprxp, UWORD data, UWORD datb, int lores)
- {
- int i;
-
- int *lookup = bpldualpf ? (bpldualpfpri ? dblpf_ind2 : dblpf_ind1) : linear_map_256;
- int *lookup_no = bpldualpf ? (bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1) : lots_of_twos;
-
- for(i = 15; i >= 0; i--, data >>= 1, datb >>= 1) {
- int sprxpos = sprxp + i*(lores ? 1 : 2);
- int plno;
- int col;
-
- /* When doing the slow line update, the following condition can
- * happen. Lower-numbered sprites get the higher priority. */
- if (spixstate[sprxpos] & ((1 << num)-1))
- continue;
-
- /* Check the priority, but only if we did not already put a sprite
- * pixel at this position. If there's already a sprite pixel here,
- * the priority was previously tested. */
- if (!spixstate[sprxpos]) {
- /* ??? What about hires mode when one hires pixel is 0, enabling the
- * sprite, and the other is != 0, blocking it? */
- plno = lookup_no[pixdata.apixels[sprxpos]];
- if (plno != 0 && (1 << num) >= plfpri[plno])
- continue;
- }
-
- if ((bpl_info.sprctl[num] & 0x80) && (num & 1)) {
- /* Attached sprite */
- col = ((data << 2) & 4) + ((datb << 3) & 8);
- spixstate[sprxpos] |= 1 << (num-1);
- spixels[sprxpos] = col;
- } else {
- col = (data & 1) | ((datb << 1) & 2);
- if (spixstate[sprxpos] & (1 << num)) {
- /* Finish attached sprite */
- /* Did the upper half of the sprite have any bits set? */
- if (spixstate[sprxpos] & (1 << (num+1)))
- col += spixels[sprxpos];
- /* Is there any sprite pixel at this position at all? */
- if (!col) {
- spixstate[sprxpos] &= ~(3 << num);
- } else
- col += 16;
- } else {
- if (col) {
- col |= 16 | ((num & 6) << 1);
- }
- }
- }
- if (col) {
- pixdata.apixels[sprxpos] = col;
- spixstate[sprxpos] |= 1<<num;
- if (!lores) {
- pixdata.apixels[sprxpos+1] = col;
- spixstate[sprxpos+1] |= 1<<num;
- }
- if (bplham && bplplanecnt == 6) {
- ham_linebuf[sprxpos] = bpl_info.color_regs[col];
- if (!lores)
- ham_linebuf[sprxpos+1] = bpl_info.color_regs[col];
- }
- }
- }
- }
- #else /* AGA version */
- static void pfield_sprite (int num, int sprxp, UWORD data, UWORD datb, int lores)
- {
- int i;
-
- int *lookup = bpldualpf ? (bpldualpfpri ? dblpf_ind2 : dblpf_ind1) : linear_map_256;
- int *lookup_no = bpldualpf ? (bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1) : lots_of_twos;
-
- for(i = 15; i >= 0; i--, data >>= 1, datb >>= 1) {
- int sprxpos = sprxp + i*(lores ? 1 : 2);
- int plno;
- int col;
-
- /* When doing the slow line update, the following condition can
- * happen. Lower-numbered sprites get the higher priority. */
- if (spixstate[sprxpos] & ((1 << num)-1))
- continue;
-
- /* Check the priority, but only if we did not already put a sprite
- * pixel at this position. If there's already a sprite pixel here,
- * the priority was previously tested. */
- if (!spixstate[sprxpos]) {
- /* ??? What about hires mode when one hires pixel is 0, enabling the
- * sprite, and the other is != 0, blocking it? */
- plno = lookup_no[pixdata.apixels[sprxpos]];
- if (plno != 0 && (1 << num) >= plfpri[plno])
- continue;
- }
-
- if ((bpl_info.sprctl[num] & 0x80) && (num & 1)) {
- /* Attached sprite */
- col = ((data << 2) & 4) + ((datb << 3) & 8);
- spixstate[sprxpos] |= 1 << (num-1);
- spixels[sprxpos] = col;
- } else {
- col = (data & 1) | ((datb << 1) & 2);
- if (spixstate[sprxpos] & (1 << num)) {
- /* Finish attached sprite */
- /* Did the upper half of the sprite have any bits set? */
- if (spixstate[sprxpos] & (1 << (num+1)))
- col += spixels[sprxpos];
- /* Is there any sprite pixel at this position at all? */
- if (!col) {
- spixstate[sprxpos] &= ~(3 << num);
- } else
- col += ((bpl_info.bplcon4 << (num & 1 ? 4 : 0)) & 240);
- } else {
- if (col) {
- col |= ((bpl_info.bplcon4 << (num & 1 ? 4 : 0)) & 240) | ((num & 6) << 1);
- }
- }
- }
- if (col) {
- pixdata.apixels[sprxpos] = col;
- spixstate[sprxpos] |= 1<<num;
- if (!lores) {
- pixdata.apixels[sprxpos+1] = col;
- spixstate[sprxpos+1] |= 1<<num;
- }
- if (bplham && bplplanecnt == 6) {
- ham_linebuf[sprxpos] = bpl_info.color_regs[col];
- if (!lores)
- ham_linebuf[sprxpos+1] = bpl_info.color_regs[col];
- }
- }
- }
- }
- #endif
-
- static __inline__ UWORD *pfield_xlateptr(CPTR plpt, int bytecount)
- {
- if (!chipmem_bank.check(plpt,bytecount)) {
- static int count = 0;
- if (count < 5) {
- count++;
- fprintf(stderr, "Warning: Bad playfield pointer");
- if (count == 5) fprintf(stderr, " (no further warnings)");
- fprintf(stderr, "\n");
- }
- return NULL;
- }
- return chipmem_bank.xlateaddr(plpt);
- }
-
- static void pfield_doline_slow_h(int currhpos)
- {
- int xpos = currhpos * 4 - 0x60;
-
- if (bplhires) {
- int offs1 = xpos + 16 + bpldelay1*2;
- int offs2 = xpos + 16 + bpldelay2*2;
-
- int pix;
- for(pix = 15; pix >= 0; pix--) {
- switch(bplplanecnt) {
- case 8:
- pixdata.apixels[pix + offs2] |= bpl8dat & 0x80; bpl8dat >>= 1;
- case 7:
- pixdata.apixels[pix + offs1] |= bpl7dat & 0x40; bpl7dat >>= 1;
- case 6:
- pixdata.apixels[pix + offs2] |= bpl6dat & 0x20; bpl6dat >>= 1;
- case 5:
- pixdata.apixels[pix + offs1] |= bpl5dat & 0x10; bpl5dat >>= 1;
- case 4:
- pixdata.apixels[pix + offs2] |= bpl4dat & 0x8; bpl4dat >>= 1;
- case 3:
- pixdata.apixels[pix + offs1] |= bpl3dat & 0x4; bpl3dat >>= 1;
- case 2:
- pixdata.apixels[pix + offs2] |= bpl2dat & 0x2; bpl2dat >>= 1;
- case 1:
- pixdata.apixels[pix + offs1] |= bpl1dat & 0x1; bpl1dat >>= 1;
- }
- }
- } else {
- int offs1 = xpos + 32 + bpldelay1*2;
- int offs2 = xpos + 32 + bpldelay2*2;
-
- int pix;
- for(pix = 30; pix >= 0; pix -= 2) {
- switch(bplplanecnt) {
- case 8:
- pixdata.apixels[pix + offs2] |= bpl8dat & 0x80;
- pixdata.apixels[pix + offs2 + 1] |= bpl8dat & 0x80; bpl8dat >>= 1;
- case 7:
- pixdata.apixels[pix + offs1] |= bpl7dat & 0x40;
- pixdata.apixels[pix + offs1 + 1] |= bpl7dat & 0x40; bpl7dat >>= 1;
- case 6:
- pixdata.apixels[pix + offs2] |= bpl6dat & 0x20;
- pixdata.apixels[pix + offs2 + 1] |= bpl6dat & 0x20; bpl6dat >>= 1;
- case 5:
- pixdata.apixels[pix + offs1] |= bpl5dat & 0x10;
- pixdata.apixels[pix + offs1 + 1] |= bpl5dat & 0x10; bpl5dat >>= 1;
- case 4:
- pixdata.apixels[pix + offs2] |= bpl4dat & 0x8;
- pixdata.apixels[pix + offs2 + 1] |= bpl4dat & 0x8; bpl4dat >>= 1;
- case 3:
- pixdata.apixels[pix + offs1] |= bpl3dat & 0x4;
- pixdata.apixels[pix + offs1 + 1] |= bpl3dat & 0x4; bpl3dat >>= 1;
- case 2:
- pixdata.apixels[pix + offs2] |= bpl2dat & 0x2;
- pixdata.apixels[pix + offs2 + 1] |= bpl2dat & 0x2; bpl2dat >>= 1;
- case 1:
- pixdata.apixels[pix + offs1] |= bpl1dat & 0x1;
- pixdata.apixels[pix + offs1 + 1] |= bpl1dat & 0x1; bpl1dat >>= 1;
- }
- }
- }
- }
-
- static void pfield_doline_slow_l(int currhpos)
- {
- int xpos = currhpos * 2 - 0x30;
-
- if (bplhires) {
- int offs1 = xpos + 8 + bpldelay1;
- int offs2 = xpos + 8 + bpldelay2;
-
- int pix;
- for(pix = 7; pix >= 0; pix--) {
- switch(bplplanecnt) {
- case 8:
- pixdata.apixels[pix + offs2] |= bpl8dat & 0x80; bpl8dat >>= 2;
- case 7:
- pixdata.apixels[pix + offs1] |= bpl7dat & 0x40; bpl7dat >>= 2;
- case 6:
- pixdata.apixels[pix + offs2] |= bpl6dat & 0x20; bpl6dat >>= 2;
- case 5:
- pixdata.apixels[pix + offs1] |= bpl5dat & 0x10; bpl5dat >>= 2;
- case 4:
- pixdata.apixels[pix + offs2] |= bpl4dat & 0x8; bpl4dat >>= 2;
- case 3:
- pixdata.apixels[pix + offs1] |= bpl3dat & 0x4; bpl3dat >>= 2;
- case 2:
- pixdata.apixels[pix + offs2] |= bpl2dat & 0x2; bpl2dat >>= 2;
- case 1:
- pixdata.apixels[pix + offs1] |= bpl1dat & 0x1; bpl1dat >>= 2;
- }
- }
- } else {
- int offs1 = xpos + 16 + bpldelay1;
- int offs2 = xpos + 16 + bpldelay2;
-
- int pix;
- for(pix = 15; pix >= 0; pix --) {
- switch(bplplanecnt) {
- case 8:
- pixdata.apixels[pix + offs2] |= bpl8dat & 0x80; bpl8dat >>= 1;
- case 7:
- pixdata.apixels[pix + offs1] |= bpl7dat & 0x40; bpl7dat >>= 1;
- case 6:
- pixdata.apixels[pix + offs2] |= bpl6dat & 0x20; bpl6dat >>= 1;
- case 5:
- pixdata.apixels[pix + offs1] |= bpl5dat & 0x10; bpl5dat >>= 1;
- case 4:
- pixdata.apixels[pix + offs2] |= bpl4dat & 0x8; bpl4dat >>= 1;
- case 3:
- pixdata.apixels[pix + offs1] |= bpl3dat & 0x4; bpl3dat >>= 1;
- case 2:
- pixdata.apixels[pix + offs2] |= bpl2dat & 0x2; bpl2dat >>= 1;
- case 1:
- pixdata.apixels[pix + offs1] |= bpl1dat & 0x1; bpl1dat >>= 1;
- }
- }
- }
- }
-
- ULONG hirestab_h[256][2];
- ULONG lorestab_h[256][4];
-
- ULONG hirestab_l[256][1];
- ULONG lorestab_l[256][2];
-
- static void gen_pfield_tables(void)
- {
- int i;
- union {
- struct {
- UBYTE a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p;
- } foo;
- struct {
- ULONG a, b, c, d;
- } bar;
- } baz;
-
- for (i = 0; i < 256; i++) {
- /* We lose every second pixel in HiRes if UAE runs in a 320x200 screen. */
- baz.foo.a = i & 64 ? 1 : 0;
- baz.foo.b = i & 16 ? 1 : 0;
- baz.foo.c = i & 4 ? 1 : 0;
- baz.foo.d = i & 1 ? 1 : 0;
- hirestab_l[i][0] = baz.bar.a;
-
- baz.foo.a = i & 128 ? 1 : 0;
- baz.foo.b = i & 64 ? 1 : 0;
- baz.foo.c = i & 32 ? 1 : 0;
- baz.foo.d = i & 16 ? 1 : 0;
- baz.foo.e = i & 8 ? 1 : 0;
- baz.foo.f = i & 4 ? 1 : 0;
- baz.foo.g = i & 2 ? 1 : 0;
- baz.foo.h = i & 1 ? 1 : 0;
- lorestab_l[i][0] = baz.bar.a;
- lorestab_l[i][1] = baz.bar.b;
- }
-
- for (i = 0; i < 256; i++) {
- baz.foo.a = i & 128 ? 1 : 0;
- baz.foo.b = i & 64 ? 1 : 0;
- baz.foo.c = i & 32 ? 1 : 0;
- baz.foo.d = i & 16 ? 1 : 0;
- baz.foo.e = i & 8 ? 1 : 0;
- baz.foo.f = i & 4 ? 1 : 0;
- baz.foo.g = i & 2 ? 1 : 0;
- baz.foo.h = i & 1 ? 1 : 0;
- hirestab_h[i][0] = baz.bar.a;
- hirestab_h[i][1] = baz.bar.b;
-
- baz.foo.a = i & 128 ? 1 : 0;
- baz.foo.b = i & 128 ? 1 : 0;
- baz.foo.c = i & 64 ? 1 : 0;
- baz.foo.d = i & 64 ? 1 : 0;
- baz.foo.e = i & 32 ? 1 : 0;
- baz.foo.f = i & 32 ? 1 : 0;
- baz.foo.g = i & 16 ? 1 : 0;
- baz.foo.h = i & 16 ? 1 : 0;
- baz.foo.i = i & 8 ? 1 : 0;
- baz.foo.j = i & 8 ? 1 : 0;
- baz.foo.k = i & 4 ? 1 : 0;
- baz.foo.l = i & 4 ? 1 : 0;
- baz.foo.m = i & 2 ? 1 : 0;
- baz.foo.n = i & 2 ? 1 : 0;
- baz.foo.o = i & 1 ? 1 : 0;
- baz.foo.p = i & 1 ? 1 : 0;
- lorestab_h[i][0] = baz.bar.a;
- lorestab_h[i][1] = baz.bar.b;
- lorestab_h[i][2] = baz.bar.c;
- lorestab_h[i][3] = baz.bar.d;
- }
- }
-
- static __inline__ void pfield_orword_hires_h(int data, unsigned char *dp, int bit)
- {
- ULONG *pixptr = (ULONG *)dp;
-
- *pixptr |= hirestab_h[data >> 8][0] << bit;
- *(pixptr+1) |= hirestab_h[data >> 8][1] << bit;
- *(pixptr+2) |= hirestab_h[data & 255][0] << bit;
- *(pixptr+3) |= hirestab_h[data & 255][1] << bit;
- }
-
- static __inline__ void pfield_orword_lores_h(int data, unsigned char *dp, int bit)
- {
- ULONG *pixptr = (ULONG *)dp;
-
- *pixptr |= lorestab_h[data >> 8][0] << bit;
- *(pixptr+1) |= lorestab_h[data >> 8][1] << bit;
- *(pixptr+2) |= lorestab_h[data >> 8][2] << bit;
- *(pixptr+3) |= lorestab_h[data >> 8][3] << bit;
- *(pixptr+4) |= lorestab_h[data & 255][0] << bit;
- *(pixptr+5) |= lorestab_h[data & 255][1] << bit;
- *(pixptr+6) |= lorestab_h[data & 255][2] << bit;
- *(pixptr+7) |= lorestab_h[data & 255][3] << bit;
- }
-
- static __inline__ void pfield_setword_hires_h(int data, unsigned char *dp, int bit)
- {
- ULONG *pixptr = (ULONG *)dp;
-
- *pixptr = hirestab_h[data >> 8][0] << bit;
- *(pixptr+1) = hirestab_h[data >> 8][1] << bit;
- *(pixptr+2) = hirestab_h[data & 255][0] << bit;
- *(pixptr+3) = hirestab_h[data & 255][1] << bit;
- }
-
- static __inline__ void pfield_setword_lores_h(int data, unsigned char *dp, int bit)
- {
- ULONG *pixptr = (ULONG *)dp;
-
- *pixptr = lorestab_h[data >> 8][0] << bit;
- *(pixptr+1) = lorestab_h[data >> 8][1] << bit;
- *(pixptr+2) = lorestab_h[data >> 8][2] << bit;
- *(pixptr+3) = lorestab_h[data >> 8][3] << bit;
- *(pixptr+4) = lorestab_h[data & 255][0] << bit;
- *(pixptr+5) = lorestab_h[data & 255][1] << bit;
- *(pixptr+6) = lorestab_h[data & 255][2] << bit;
- *(pixptr+7) = lorestab_h[data & 255][3] << bit;
- }
-
- static __inline__ void pfield_orword_hires_l(int data, unsigned char *dp, int bit)
- {
- ULONG *pixptr = (ULONG *)dp;
-
- *pixptr |= hirestab_l[data >> 8][0] << bit;
- *(pixptr+1) |= hirestab_l[data & 255][0] << bit;
- }
-
- static __inline__ void pfield_orword_lores_l(int data, unsigned char *dp, int bit)
- {
- ULONG *pixptr = (ULONG *)dp;
-
- *pixptr |= lorestab_l[data >> 8][0] << bit;
- *(pixptr+1) |= lorestab_l[data >> 8][1] << bit;
- *(pixptr+2) |= lorestab_l[data & 255][0] << bit;
- *(pixptr+3) |= lorestab_l[data & 255][1] << bit;
- }
-
- static __inline__ void pfield_setword_hires_l(int data, unsigned char *dp, int bit)
- {
- ULONG *pixptr = (ULONG *)dp;
-
- *pixptr = hirestab_l[data >> 8][0] << bit;
- *(pixptr+1) = hirestab_l[data & 255][0] << bit;
- }
-
- static __inline__ void pfield_setword_lores_l(int data, unsigned char *dp, int bit)
- {
- ULONG *pixptr = (ULONG *)dp;
-
- *pixptr = lorestab_l[data >> 8][0] << bit;
- *(pixptr+1) = lorestab_l[data >> 8][1] << bit;
- *(pixptr+2) = lorestab_l[data & 255][0] << bit;
- *(pixptr+3) = lorestab_l[data & 255][1] << bit;
- }
-
- #define DO_ONE_PLANE(POINTER, MULT, FUNC, DELAY, LL_SUB, P_ADD) { \
- int i; \
- unsigned int bpldat1; \
- UWORD data; \
- unsigned int bpldat2 = 0; \
- for (i = plflinelen; i > 0; i -= LL_SUB) { \
- bpldat1 = bpldat2; \
- bpldat2 = *POINTER++; \
- data = (bpldat1 << (16 - DELAY)) | (bpldat2 >> DELAY); \
- FUNC(data, app, MULT); \
- app += P_ADD; \
- } \
- data = bpldat2 << (16 - DELAY); \
- FUNC(data, app, MULT); \
- }
-
- #define DO_ONE_PLANE_B_LORES_H(NUM, FETCH) \
- if (bplplanecnt > NUM) { \
- if (FETCH != 0) { \
- plfd[NUM] <<= 16; \
- if (FETCH == 1) \
- plfd[NUM] |= *(r_bplpt[NUM])++ << delay[NUM & 1]; \
- d = plfd[NUM] >> 24; \
- } else {\
- d = (plfd[NUM] >> 16) & 255; \
- }\
- if (NUM == 0) { \
- data1 = lorestab_h[d][0] << NUM;\
- data2 = lorestab_h[d][1] << NUM;\
- data3 = lorestab_h[d][2] << NUM;\
- data4 = lorestab_h[d][3] << NUM;\
- } else { \
- data1 |= lorestab_h[d][0] << NUM;\
- data2 |= lorestab_h[d][1] << NUM;\
- data3 |= lorestab_h[d][2] << NUM;\
- data4 |= lorestab_h[d][3] << NUM;\
- } \
- }
-
- #if 1
- static void pfield_doline_h(void)
- {
- int xpos = plfstrt * 4 - 0x60;
- int spr, sprites_seen;
-
- if (bplhires) {
- if (bplplanecnt > 0) {
- int xpos1 = xpos + 16 + (bpldelay1 >= 8 ? 16 : 0);
- int xpos2 = xpos + 16 + (bpldelay2 >= 8 ? 16 : 0);
- int delay1 = 2*(bpldelay1 & 7);
- int delay2 = 2*(bpldelay2 & 7);
- unsigned char *app = pixdata.apixels + xpos1;
-
- DO_ONE_PLANE(r_bplpt[0], 0, pfield_setword_hires_h, delay1, 4, 16);
- if (bplplanecnt > 2) {
- app = pixdata.apixels + xpos1;
- DO_ONE_PLANE(r_bplpt[2], 2, pfield_orword_hires_h, delay1, 4, 16);
- }
- #if AGA_CHIPSET == 1
- if (bplplanecnt > 4) {
- app = pixdata.apixels + xpos1;
- DO_ONE_PLANE(r_bplpt[4], 4, pfield_orword_hires_h, delay1, 4, 16);
- }
- if (bplplanecnt > 6) {
- app = pixdata.apixels + xpos1;
- DO_ONE_PLANE(r_bplpt[6], 6, pfield_orword_hires_h, delay1, 4, 16);
- }
- #endif
- if (bplplanecnt > 1) {
- app = pixdata.apixels + xpos2;
- DO_ONE_PLANE(r_bplpt[1], 1, pfield_orword_hires_h, delay2, 4, 16);
- }
- if (bplplanecnt > 3) {
- app = pixdata.apixels + xpos2;
- DO_ONE_PLANE(r_bplpt[3], 3, pfield_orword_hires_h, delay2, 4, 16);
- }
- #if AGA_CHIPSET == 1
- if (bplplanecnt > 5) {
- app = pixdata.apixels + xpos2;
- DO_ONE_PLANE(r_bplpt[5], 5, pfield_orword_hires_h, delay2, 4, 16);
- }
- if (bplplanecnt > 7) {
- app = pixdata.apixels + xpos2;
- DO_ONE_PLANE(r_bplpt[7], 7, pfield_orword_hires_h, delay2, 4, 16);
- }
- #endif
- } else {
- memset(pixdata.apixels, 0, sizeof(pixdata.apixels));
- }
- } else {
- if (bplplanecnt > 0) {
- int x = xpos + 32;
- unsigned char *app = pixdata.apixels + x;
- #if 0 /* Fun things to do in the future */
- int delay[2];
- int len;
- ULONG plfd[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
- ULONG *ptr = (ULONG *)app;
- ULONG d;
- ULONG data, data1, data2, data3, data4;
- delay[0] = 16 - bpldelay1; delay[1] = 16 - bpldelay2;
-
- for (len = plflinelen; len > 0; len -= 8, ptr+=8) {
- DO_ONE_PLANE_B_LORES_H(0,1);
- DO_ONE_PLANE_B_LORES_H(1,1);
- DO_ONE_PLANE_B_LORES_H(2,1);
- DO_ONE_PLANE_B_LORES_H(3,1);
- DO_ONE_PLANE_B_LORES_H(4,1);
- DO_ONE_PLANE_B_LORES_H(5,1);
- *ptr = data1; *(ptr+1) = data2; *(ptr+2) = data3; *(ptr+3) = data4;
-
- DO_ONE_PLANE_B_LORES_H(0,0);
- DO_ONE_PLANE_B_LORES_H(1,0);
- DO_ONE_PLANE_B_LORES_H(2,0);
- DO_ONE_PLANE_B_LORES_H(3,0);
- DO_ONE_PLANE_B_LORES_H(4,0);
- DO_ONE_PLANE_B_LORES_H(5,0);
- *(ptr+4) = data1; *(ptr+5) = data2; *(ptr+6) = data3; *(ptr+7) = data4;
- }
- DO_ONE_PLANE_B_LORES_H(0,2);
- DO_ONE_PLANE_B_LORES_H(1,2);
- DO_ONE_PLANE_B_LORES_H(2,2);
- DO_ONE_PLANE_B_LORES_H(3,2);
- DO_ONE_PLANE_B_LORES_H(4,2);
- DO_ONE_PLANE_B_LORES_H(5,2);
- *ptr = data1; *(ptr+1) = data2; *(ptr+2) = data3; *(ptr+3) = data4;
-
- DO_ONE_PLANE_B_LORES_H(0,0);
- DO_ONE_PLANE_B_LORES_H(1,0);
- DO_ONE_PLANE_B_LORES_H(2,0);
- DO_ONE_PLANE_B_LORES_H(3,0);
- DO_ONE_PLANE_B_LORES_H(4,0);
- DO_ONE_PLANE_B_LORES_H(5,0);
- *(ptr+4) = data1; *(ptr+5) = data2; *(ptr+6) = data3; *(ptr+7) = data4;
- #else
- DO_ONE_PLANE(r_bplpt[0], 0, pfield_setword_lores_h, bpldelay1, 8, 32);
- if (bplplanecnt > 2) {
- app = pixdata.apixels + x;
- DO_ONE_PLANE(r_bplpt[2], 2, pfield_orword_lores_h, bpldelay1, 8, 32);
- }
- if (bplplanecnt > 4) {
- app = pixdata.apixels + x;
- DO_ONE_PLANE(r_bplpt[4], 4, pfield_orword_lores_h, bpldelay1, 8, 32);
- }
- #if AGA_CHIPSET == 1
- if (bplplanecnt > 6) {
- app = pixdata.apixels + x;
- DO_ONE_PLANE(r_bplpt[6], 6, pfield_orword_lores_h, bpldelay1, 8, 32);
- }
- #endif
- if (bplplanecnt > 1) {
- app = pixdata.apixels + x;
- DO_ONE_PLANE(r_bplpt[1], 1, pfield_orword_lores_h, bpldelay2, 8, 32);
- }
- if (bplplanecnt > 3) {
- app = pixdata.apixels + x;
- DO_ONE_PLANE(r_bplpt[3], 3, pfield_orword_lores_h, bpldelay2, 8, 32);
- }
- if (bplplanecnt > 5) {
- app = pixdata.apixels + x;
- DO_ONE_PLANE(r_bplpt[5], 5, pfield_orword_lores_h, bpldelay2, 8, 32);
- }
- #if AGA_CHIPSET == 1
- if (bplplanecnt > 7) {
- app = pixdata.apixels + x;
- DO_ONE_PLANE(r_bplpt[7], 7, pfield_orword_lores_h, bpldelay2, 8, 32);
- }
- #endif
- #endif
- } else {
- memset(pixdata.apixels, 0, sizeof(pixdata.apixels));
- }
- }
-
- decode_ham6 (16,812);
-
- linetoscreen = 1;
- sprites_seen = 0;
-
- for(spr = 7; spr >= 0; spr--) {
- if (bpl_info.sprarmed[spr]) {
- int sprxp = ((bpl_info.sprpos[spr] & 0xFF) * 4) - 0x60 + (bpl_info.sprctl[spr] & 1)*2;
- int i;
- /* Ugh. Nasty bug. Let's rather lose some sprites than trash
- * memory. */
- if (sprxp >= 0) {
- if (!sprites_seen) {
- sprites_seen = 1;
- memset(spixstate,0,sizeof spixstate);
- }
- pfield_sprite (spr, sprxp, bpl_info.sprdata[spr], bpl_info.sprdatb[spr], 0);
- }
- }
- }
- }
- #endif
- static void pfield_doline_l(void)
- {
- int xpos = plfstrt * 2 - 0x30;
- int spr;
- int sprites_seen;
-
- if (bplhires) {
- if (bplplanecnt > 0) {
- int xpos1 = xpos + 8 + (bpldelay1 >= 8 ? 8 : 0);
- int xpos2 = xpos + 8 + (bpldelay2 >= 8 ? 8 : 0);
- int delay1 = (bpldelay1 & 7) * 2;
- int delay2 = (bpldelay2 & 7) * 2;
- unsigned char *app = pixdata.apixels + xpos1;
-
- DO_ONE_PLANE(r_bplpt[0], 0, pfield_setword_hires_l, delay1, 4, 8);
- if (bplplanecnt > 2) {
- app = pixdata.apixels + xpos1;
- DO_ONE_PLANE(r_bplpt[2], 2, pfield_orword_hires_l, delay1, 4, 8);
- }
- #if AGA_CHIPSET == 1
- if (bplplanecnt > 4) {
- app = pixdata.apixels + xpos1;
- DO_ONE_PLANE(r_bplpt[4], 4, pfield_orword_hires_l, delay1, 4, 8);
- }
- if (bplplanecnt > 6) {
- app = pixdata.apixels + xpos1;
- DO_ONE_PLANE(r_bplpt[6], 6, pfield_orword_hires_l, delay1, 4, 8);
- }
- #endif
- if (bplplanecnt > 1) {
- app = pixdata.apixels + xpos2;
- DO_ONE_PLANE(r_bplpt[1], 1, pfield_orword_hires_l, delay2, 4, 8);
- }
- if (bplplanecnt > 3) {
- app = pixdata.apixels + xpos2;
- DO_ONE_PLANE(r_bplpt[3], 3, pfield_orword_hires_l, delay2, 4, 8);
- }
- #if AGA_CHIPSET == 1
- if (bplplanecnt > 5) {
- app = pixdata.apixels + xpos2;
- DO_ONE_PLANE(r_bplpt[5], 5, pfield_orword_hires_l, delay2, 4, 8);
- }
- if (bplplanecnt > 7) {
- app = pixdata.apixels + xpos2;
- DO_ONE_PLANE(r_bplpt[7], 7, pfield_orword_hires_l, delay2, 4, 8);
- }
- #endif
- } else {
- memset(pixdata.apixels, 0, sizeof(pixdata.apixels));
- }
- } else {
- if (bplplanecnt > 0) {
- int x = xpos + 16;
- int delay1 = bpldelay1;
- int delay2 = bpldelay2;
- unsigned char *app = pixdata.apixels + x;
- DO_ONE_PLANE(r_bplpt[0], 0, pfield_setword_lores_l, delay1, 8, 16);
- if (bplplanecnt > 2) {
- app = pixdata.apixels + x;
- DO_ONE_PLANE(r_bplpt[2], 2, pfield_orword_lores_l, delay1, 8, 16);
- }
- if (bplplanecnt > 4) {
- app = pixdata.apixels + x;
- DO_ONE_PLANE(r_bplpt[4], 4, pfield_orword_lores_l, delay1, 8, 16);
- }
- #if AGA_CHIPSET == 1
- if (bplplanecnt > 6) {
- app = pixdata.apixels + x;
- DO_ONE_PLANE(r_bplpt[6], 6, pfield_orword_lores_l, delay1, 8, 16);
- }
- #endif
- if (bplplanecnt > 1) {
- app = pixdata.apixels + x;
- DO_ONE_PLANE(r_bplpt[1], 1, pfield_orword_lores_l, delay2, 8, 16);
- }
- if (bplplanecnt > 3) {
- app = pixdata.apixels + x;
- DO_ONE_PLANE(r_bplpt[3], 3, pfield_orword_lores_l, delay2, 8, 16);
- }
- if (bplplanecnt > 5) {
- app = pixdata.apixels + x;
- DO_ONE_PLANE(r_bplpt[5], 5, pfield_orword_lores_l, delay2, 8, 16);
- }
- #if AGA_CHIPSET == 1
- if (bplplanecnt > 7) {
- app = pixdata.apixels + x;
- DO_ONE_PLANE(r_bplpt[7], 7, pfield_orword_lores_l, delay2, 8, 16);
- }
- #endif
- } else {
- memset(pixdata.apixels, 0, sizeof(pixdata.apixels));
- }
- }
-
- decode_ham6 (8,406);
-
- linetoscreen = 1;
- sprites_seen = 0;
-
- for(spr = 7; spr >= 0; spr--) {
- if (bpl_info.sprarmed[spr]) {
- int sprxp = ((bpl_info.sprpos[spr] & 0xFF) * 2) - 0x30 + (bpl_info.sprctl[spr] & 1);
- int i;
- /* Ugh. Nasty bug. Let's rather lose some sprites than trash
- * memory. */
- if (sprxp >= 0) {
- if (!sprites_seen) {
- sprites_seen = 1;
- memset(spixstate,0,sizeof spixstate);
- }
- pfield_sprite (spr, sprxp, bpl_info.sprdata[spr], bpl_info.sprdatb[spr], 1);
- }
- }
- }
- }
-
- static int bpl_data_differs(UWORD *data, UWORD *r_addr, int nbytes)
- {
- return memcmpy(data, r_addr, nbytes);
- }
-
- static __inline__ int bplinfo_differs(struct bplinfo *a, struct bplinfo *b)
- {
- int ncolors;
- int i;
- if (a->bplcon0 != b->bplcon0
- || a->bplcon1 != b->bplcon1
- || a->bplcon2 != b->bplcon2
- || a->bplcon3 != b->bplcon3
- || a->bplcon4 != b->bplcon4
- || a->diwstrt != b->diwstrt
- || a->diwstop != b->diwstop
- || a->ddfstrt != b->ddfstrt
- || a->ddfstop != b->ddfstop)
- return 1;
-
- #if 1
- /* This sometimes loses for sprite colors */
- ncolors = 1 << ((a->bplcon0 & 0x7000) >> 12);
- if (ncolors == 64)
- ncolors = (a->bplcon0 & 0x800) ? 16 : 32;
- for (i = 0; i < ncolors; i++)
- if (a->color_regs[i] != b->color_regs[i])
- return 1;
- #else
- /* ... and this will lose badly on few-color screens when we implement
- * AGA.
- */
- if (memcmp(a->color_regs, b->color_regs, sizeof a->color_regs) != 0)
- return 1;
- #endif
- for (i = 0; i < 8; i++) {
- if (a->sprarmed[i] != b->sprarmed[i])
- return 1;
- if (a->sprarmed[i]
- && (a->sprctl[i] != b->sprctl[i]
- || a->sprpos[i] != b->sprpos[i]
- || a->sprdata[i] != b->sprdata[i]
- || a->sprdatb[i] != b->sprdatb[i]))
- return 1;
- }
- return 0;
- }
-
- static void pfield_doline(void)
- {
- int bytecount = plflinelen / (bplhires ? 4 : 8) * 2;
- int drawit = 0;
- int i;
-
- if (vpos < plffirstline || vpos >= plflastline)
- return;
-
- if (!dmaen(0x100) || !pfield_linedmaon) {
- line_in_border = 1;
- return;
- }
-
- for (i = 0; i < bplplanecnt; i++) {
- r_bplpt[i] = pfield_xlateptr(bplpt[i], bytecount);
- if (r_bplpt[i] == NULL)
- return;
- }
-
- #if SMART_UPDATE == 1
- drawit = bplinfo_differs(&bpl_info, &linedescr[next_lineno].bpl_info);
- if (drawit) {
- linedescr[next_lineno].bpl_info = bpl_info;
- }
- drawit |= !linedescr[next_lineno].linedata_valid | frame_redraw_necessary;
-
- if (bytecount <= MAX_WORDS_PER_LINE * 2) {
- linedescr[next_lineno].linedata_valid = 1;
- for (i = 0; i < bplplanecnt; i++)
- drawit |= bpl_data_differs(line_data[next_lineno][i],r_bplpt[i],
- bytecount);
-
- } else {
- linedescr[next_lineno].linedata_valid = 0;
- }
- #endif
-
- pfield_modulos(bytecount);
-
- #if SMART_UPDATE != 0
- if (!drawit)
- return;
- #endif
-
- if (use_lores)
- pfield_doline_l();
- else
- pfield_doline_h();
- }
-
- static void pfield_doline_slow(int currhp)
- {
- int xpos = PIXEL_XPOS(currhp);
-
- if (vpos < plffirstline || vpos >= plflastline)
- return;
-
- if (currhp == plfstrt)
- slowline_nextpos = currhp;
-
- if (currhp == slowline_nextpos) {
- if (slowline_linepos >= plflinelen) {
- /* The modulos must get added at exactly this point. */
- pfield_modulos(0);
- slowline_nextpos = -1;
- } else {
- slowline_nextpos += bplhires ? 4 : 8;
- slowline_linepos += bplhires ? 4 : 8;
-
- /* Hmmmm.....
- * In theory, we could use the fast pfield_doline functions even
- * in this case. We only need to do sprites, ham decoding and
- * the line_to_scr stuff cycle-per-cycle. However, we would no
- * longer be able to emulate tricks that switch lores/hires in
- * the middle of a line, but I'm not sure whether this sort of
- * thing actually works currently and whether it's worthwhile.
- */
-
- pfield_fetchdata();
-
- if (use_lores)
- pfield_doline_slow_l (currhp);
- else
- pfield_doline_slow_h (currhp);
- /* @@@ need to test this */
- decode_ham6 (xpos, PIXEL_XPOS(slowline_nextpos));
- }
- }
- if (currhp > 48) {
- int spr;
- for(spr = 7; spr >= 0; spr--) {
- if (bpl_info.sprarmed[spr] && currhp == (bpl_info.sprpos[spr] & 0xFF)) {
- int sprxp = xpos + (bpl_info.sprctl[spr] & 1) * (use_lores ? 1 : 2);
- pfield_sprite (spr, sprxp, bpl_info.sprdata[spr], bpl_info.sprdatb[spr], use_lores);
- }
- }
- }
- }
-
- static int first_drawn_line, last_drawn_line;
- static int first_block_line, last_block_line;
-
- static void init_frame (void)
- {
- int i;
- int maxpos = use_lores ? 400 : 800;
- int old_pmds = prev_max_diwstop;
-
- if (max_diwstop == 0)
- max_diwstop = diwlastword;
-
- if (max_diwstop < (use_lores ? 320 : 640) || max_diwstop > maxpos)
- prev_max_diwstop = maxpos;
- else
- prev_max_diwstop = max_diwstop;
-
- max_diwstop = 0;
-
- memset(spron, 0, sizeof spron);
- memset(bpl_info.sprpos, 0, sizeof bpl_info.sprpos);
- memset(bpl_info.sprctl, 0, sizeof bpl_info.sprctl);
- last_drawn_line = 0;
- first_drawn_line = 32767;
-
- first_block_line = last_block_line = -2;
- calc_adjustment();
- if (frame_redraw_necessary)
- frame_redraw_necessary--;
-
- if (old_pmds != prev_max_diwstop) {
- frame_redraw_necessary |= (bpl_info.bplcon0 & 4 ? 2 : 1);
- }
- }
-
- /*
- * A raster line has been built in the graphics buffer. Tell the graphics code
- * to do anything necessary to display it.
- */
-
- static void do_flush_line (int lineno)
- {
- if (lineno < first_drawn_line)
- first_drawn_line = lineno;
- if (lineno > last_drawn_line)
- last_drawn_line = lineno;
-
- if (gfxvidinfo.maxblocklines == 0)
- flush_line(lineno);
- else {
- if ((last_block_line+1) != lineno) {
- if (first_block_line != -2)
- flush_block (first_block_line, last_block_line);
- first_block_line = lineno;
- }
- last_block_line = lineno;
- if (last_block_line - first_block_line >= gfxvidinfo.maxblocklines) {
- flush_block (first_block_line, last_block_line);
- first_block_line = last_block_line = -2;
- }
- }
- }
-
- /*
- * One Amiga frame has been finished. Tell the graphics code about it.
- * Note that the actual flush_scren() call is a no-op for all reasonable
- * systems.
- */
-
- static void do_flush_screen (int start, int stop)
- {
- if (gfxvidinfo.maxblocklines != 0 && first_block_line != -2) {
- flush_block (first_block_line, last_block_line);
- }
- if (start <= stop)
- flush_screen (start, stop);
- }
-
- static void setdontcare(void)
- {
- fprintf(stderr, "Don't care mouse mode set\n");
- mousestate=dont_care_mouse;
- lastspr0x=lastmx; lastspr0y=lastmy;
- mstepx=defstepx; mstepy=defstepy;
- }
-
- static void setfollow(void)
- {
- fprintf(stderr, "Follow sprite mode set\n");
- mousestate=follow_mouse;
- lastdiffx=lastdiffy=0;
- sprvbfl=0;
- spr0ctl=spr0pos=0;
- mstepx=defstepx; mstepy=defstepy;
- }
-
- void togglemouse(void)
- {
- switch(mousestate) {
- case dont_care_mouse: setfollow(); break;
- case follow_mouse: setdontcare(); break;
- default: break; /* Nnnnnghh! */
- }
- }
-
- static __inline__ int adjust(int val)
- {
- if (val>127)
- return 127;
- else if (val<-127)
- return -127;
- return val;
- }
-
- static void do_mouse_hack(void)
- {
- int spr0x = ((spr0pos & 0xff) << 2) | ((spr0ctl & 1) << 1);
- int spr0y = ((spr0pos >> 8) | ((spr0ctl & 4) << 6)) << 1;
- int diffx, diffy;
-
- switch (mousestate) {
- case normal_mouse:
- diffx = lastmx - lastsampledmx;
- diffy = lastmy - lastsampledmy;
- if (!newmousecounters) {
- if (diffx > 127) diffx = 127;
- if (diffx < -127) diffx = -127;
- joy0x += diffx;
- if (diffy > 127) diffy = 127;
- if (diffy < -127) diffy = -127;
- joy0y += diffy;
- }
- lastsampledmx += diffx; lastsampledmy += diffy;
- break;
-
- case dont_care_mouse:
- diffx = adjust (((lastmx-lastspr0x) * mstepx) >> 16);
- diffy = adjust (((lastmy-lastspr0y) * mstepy) >> 16);
- lastspr0x=lastmx; lastspr0y=lastmy;
- joy0x+=diffx; joy0y+=diffy;
- break;
-
- case follow_mouse:
- if (sprvbfl && sprvbfl-- >1) {
- int mousexpos, mouseypos;
-
- if ((lastdiffx > docal || lastdiffx < -docal) && lastspr0x != spr0x
- && spr0x > plfstrt*4 + 34 + xcaloff && spr0x < plfstop*4 - xcaloff)
- {
- int val = (lastdiffx << 16) / (spr0x - lastspr0x);
- if (val>=0x8000) mstepx=(mstepx*(calweight-1)+val)/calweight;
- }
- if ((lastdiffy > docal || lastdiffy < -docal) && lastspr0y != spr0y
- && spr0y>plffirstline+ycaloff && spr0y<plflastline-ycaloff)
- {
- int val = (lastdiffy<<16) / (spr0y-lastspr0y);
- if (val>=0x8000) mstepy=(mstepy*(calweight-1)+val)/calweight;
- }
- mousexpos = lastmx;
- if (gfxvidinfo.x_adjust)
- mousexpos += gfxvidinfo.x_adjust;
- mouseypos = lastmy;
-
- if(!correct_aspect)
- mouseypos *= 2;
- if(use_lores)
- mousexpos *= 2;
- if (gfxvidinfo.x_adjust)
- mousexpos -= 16;
-
- diffx = adjust ((((mousexpos + 0x70 + xoffs - spr0x) & ~1) * mstepx) >> 16);
- diffy = adjust ((((mouseypos + yoffs - spr0y+minfirstline*2) & ~1) * mstepy) >> 16);
- lastspr0x=spr0x; lastspr0y=spr0y;
- lastdiffx=diffx; lastdiffy=diffy;
- joy0x+=diffx; joy0y+=diffy;
- }
- break;
- }
- }
-
- static void vsync_handler(void)
- {
- UWORD dir;
- int button;
-
- handle_events();
- getjoystate(&joy0dir, &joy0button);
-
- do_mouse_hack();
-
- INTREQ(0x8020);
- if (bpl_info.bplcon0 & 4) lof ^= 0x8000;
- COPJMP1(0);
-
- if (framecnt == 0)
- do_flush_screen (first_drawn_line, last_drawn_line);
-
- count_frame();
- init_frame();
- #ifdef HAVE_GETTIMEOFDAY
- {
- struct timeval tv;
- unsigned long int newtime;
-
- gettimeofday(&tv,NULL);
- newtime = (tv.tv_sec-seconds_base) * 1000 + tv.tv_usec / 1000;
-
- if (!bogusframe) {
- frametime += newtime - msecs;
- timeframes++;
- }
- msecs = newtime;
- bogusframe = 0;
- }
- #endif
- CIA_vsync_handler();
- }
-
- static void hsync_handler(void)
- {
- int lineno = vpos - minfirstline;
- int lineisdouble = 0;
- int line_was_doubled = 0;
-
- do_sprites(vpos, maxhpos);
- last_sprite = 0;
-
- if (correct_aspect) {
- lineno *= 2;
- if (bpl_info.bplcon0 & 4) {
- if(!lof) {
- lineno++;
- }
- } else {
- lineisdouble = 1;
- }
- }
-
- eventtab[ev_hsync].oldcycles = cycles;
- CIA_hsync_handler();
-
- if (produce_sound)
- do_sound ();
-
- if (framecnt == 0 && vpos >= minfirstline && lineno < gfxvidinfo.maxline) {
- if (vpos >= plffirstline && vpos < plflastline)
- {
- /* Finish the line, if we started doing it with the slow update.
- * Otherwise, draw it entirely. */
- if (pfield_fullline) {
- if (!pfield_linedone) {
- /* This can turn on line_in_border if DMA is off */
- pfield_doline();
- }
- if (linetoscreen)
- pfield_do_linetoscr_full (line_was_doubled = lineisdouble);
- } else {
- int i;
- for(i = pfield_lastpart_hpos; i < maxhpos; i++)
- pfield_doline_slow(i);
- pfield_do_linetoscr(slowline_lasttoscr, maxhpos);
- /* The COLOR routine masks off the high nibble. This means
- * that there will never be 0xFFFF in color_regs[0], and this
- * means that the line will be drawn completely the next time
- * we get into pfield_doline()
- */
- linedescr[lineno].bpl_info.color_regs[0] = 0xFFFF;
- linetoscreen = 1;
- }
- } else
- line_in_border = 1;
-
- if (line_in_border &&
- (!linedescr[lineno].inborder
- || linedescr[lineno].bordercol != acolors[0]))
- {
- linedescr[lineno].bordercol = acolors[0];
- linedescr[lineno].linedata_valid = 0;
-
- fill_line (lineno);
- linetoscreen = 1;
- }
-
- linedescr[lineno].inborder = line_in_border;
-
- if (linetoscreen) {
- #if AGA_CHIPSET == 1
- switch (gfxvidinfo.pixbytes) {
- case 1: aga_translate8 (0, aga_lbufptr-aga_linebuf); break;
- case 2: aga_translate16 (0, aga_lbufptr-aga_linebuf); break;
- case 4: aga_translate32 (0, aga_lbufptr-aga_linebuf); break;
- }
- #endif
- do_flush_line (lineno);
- }
- if (lineisdouble) {
- int drawit = 0;
-
- if (linedescr[lineno].inborder != linedescr[lineno+1].inborder
- || (linedescr[lineno].inborder == 1
- && linedescr[lineno].bordercol != linedescr[lineno+1].bordercol)) {
- drawit = 1;
-
- } else if (linedescr[lineno].inborder == 0
- && (linetoscreen
- || (bplinfo_differs(&linedescr[lineno].bpl_info,
- &linedescr[lineno+1].bpl_info)))) {
- drawit = 1;
- }
-
- if (drawit) {
- linedescr[lineno+1].inborder = linedescr[lineno].inborder;
- linedescr[lineno+1].bordercol = linedescr[lineno].bordercol;
- #if SMART_UPDATE != 0
- linedescr[lineno+1].bpl_info = linedescr[lineno].bpl_info;
- #endif
- if (!line_was_doubled) {
- if (line_in_border)
- fill_line (lineno+1);
- else
- memcpy (gfxvidinfo.bufmem + (lineno+1)*gfxvidinfo.rowbytes,
- gfxvidinfo.bufmem + lineno*gfxvidinfo.rowbytes,
- gfxvidinfo.rowbytes);
- }
- do_flush_line (lineno+1);
- }
- }
- }
-
- pfield_calclinedma();
-
- if (++vpos == (maxvpos + (lof != 0))) {
- vpos = 0;
- vsync_handler();
- }
-
- if (framecnt == 0)
- {
- lineno = vpos - minfirstline;
-
- if (correct_aspect) {
- lineno *= 2;
- if ((bpl_info.bplcon0 & 4) && !lof) {
- lineno++;
- }
- }
- xlinebuffer = gfxvidinfo.bufmem + gfxvidinfo.rowbytes * lineno;
- aga_lbufptr = aga_linebuf;
- next_lineno = lineno;
- linetoscreen = 0;
- line_in_border = 0;
- pfield_fullline = 1;
- pfield_linedone = 0;
- pfield_lastpart_hpos = 0;
- }
-
- }
-
- void customreset(void)
- {
- int i;
- #ifdef HAVE_GETTIMEOFDAY
- struct timeval tv;
- #endif
- inhibit_frame = 0;
- expamem_reset();
- CIA_reset();
- cycles = 0;
- specialflags = 0;
-
- last_sprite = 0;
- vpos = 0;
- lof = 0;
- next_lineno = 0;
- max_diwstop = 0;
-
- if (needmousehack()) {
- if (mousestate != follow_mouse) setfollow();
- } else {
- mousestate = normal_mouse;
- }
-
- memset(spixstate, 0, sizeof(spixstate));
-
- /*memset(blitcount, 0, sizeof(blitcount)); blitter debug */
-
- for (i = 0; i < numscrlines*2; i++) {
- linedescr[i].mnn = NULL;
- linedescr[i].linedata_valid = 0;
- linedescr[i].bpl_info.color_regs[0] = 0xFFFF;
- linedescr[i].bplpt[0] = (CPTR)-1;
- }
-
- xlinebuffer = gfxvidinfo.bufmem;
-
- dmacon = intena = 0;
- bltstate = BLT_done;
- copstate = COP_stop;
- copcon = 0;
- dskdmaen = 0;
- cycles = 0;
- bpl_info.bplcon4 = 0x11; /* Get AGA chipset into ECS compatibility mode */
- bpl_info.bplcon3 = 0xC00;
- for(i = 0; i < ev_max; i++) {
- eventtab[i].active = 0;
- eventtab[i].oldcycles = 0;
- }
- copper_active = 0;
- eventtab[ev_cia].handler = CIA_handler;
- eventtab[ev_copper].handler = do_copper;
- eventtab[ev_hsync].handler = hsync_handler;
- eventtab[ev_hsync].evtime = maxhpos;
- eventtab[ev_hsync].active = 1;
-
- eventtab[ev_blitter].handler = blitter_handler;
- eventtab[ev_blitter].active = 0;
- eventtab[ev_diskblk].handler = diskblk_handler;
- eventtab[ev_diskblk].active = 0;
- eventtab[ev_diskindex].handler = diskindex_handler;
- eventtab[ev_diskindex].active = 0;
-
- events_schedule();
-
- init_frame();
- #ifdef HAVE_GETTIMEOFDAY
- gettimeofday(&tv,NULL);
- seconds_base = tv.tv_sec;
- bogusframe = 1;
- #endif
- }
-
- void dumpcustom(void)
- {
- int i;
- fprintf(stderr, "DMACON: %x INTENA: %x INTREQ: %x VPOS: %x HPOS: %x\n", DMACONR(),
- intena, intreq, vpos, current_hpos());
- if (timeframes) {
- fprintf(stderr, "Average frame time: %d ms [frames: %d time: %d]\n",
- frametime/timeframes, timeframes, frametime);
- }
- /*for (i=0; i<256; i++) if (blitcount[i]) fprintf(stderr, "minterm %x = %d\n",i,blitcount[i]); blitter debug */
- }
-
- int intlev(void)
- {
- UWORD imask = intreq & intena;
- if (imask && (intena & 0x4000)){
- if (imask & 0x2000) return 6;
- if (imask & 0x1800) return 5;
- if (imask & 0x0780) return 4;
- if (imask & 0x0070) return 3;
- if (imask & 0x0008) return 2;
- if (imask & 0x0007) return 1;
- }
- return -1;
- }
-
- void custom_init(void)
- {
- int num;
- if (needmousehack())
- setfollow();
- customreset();
- for (num = 0; num < 256; num++) {
- int plane1 = (num & 1) | ((num >> 1) & 2) | ((num >> 2) & 4) | ((num >> 3) & 8);
- int plane2 = ((num >> 1) & 1) | ((num >> 2) & 2) | ((num >> 3) & 4) | ((num >> 4) & 8);
- dblpf_2nd1[num] = plane1 == 0 ? (plane2 == 0 ? 0 : 2) : 1;
- dblpf_2nd2[num] = plane2 == 0 ? (plane1 == 0 ? 0 : 1) : 2;
- dblpf_aga1[num] = plane1 == 0 ? plane2 : plane1;
- dblpf_aga2[num] = plane2 == 0 ? plane1 : plane2;
- if (plane2 > 0) plane2 += 8;
- dblpf_ind1[num] = plane1 == 0 ? plane2 : plane1;
- dblpf_ind2[num] = plane2 == 0 ? plane1 : plane2;
-
- lots_of_twos[num] = num == 0 ? 0 : 2;
- linear_map_256[num] = num;
- }
- build_blitfilltable();
- gen_pfield_tables();
- }
-
- /* Custom chip memory bank */
-
- static ULONG custom_lget(CPTR) REGPARAM;
- static UWORD custom_wget(CPTR) REGPARAM;
- static UBYTE custom_bget(CPTR) REGPARAM;
- static void custom_lput(CPTR, ULONG) REGPARAM;
- static void custom_wput(CPTR, UWORD) REGPARAM;
- static void custom_bput(CPTR, UBYTE) REGPARAM;
-
- addrbank custom_bank = {
- custom_lget, custom_wget, custom_bget,
- custom_lput, custom_wput, custom_bput,
- default_xlate, default_check
- };
-
- UWORD custom_wget(CPTR addr)
- {
- switch(addr & 0x1FE) {
- case 0x002: return DMACONR();
- case 0x004: return VPOSR();
- case 0x006: return VHPOSR();
-
- case 0x008: return DSKDATR();
- case 0x012: return POT0DAT();
- case 0x016: return POTGOR();
- case 0x018: return SERDATR();
- case 0x01A: return DSKBYTR();
- case 0x01C: return INTENAR();
- case 0x01E: return INTREQR();
- case 0x010: return ADKCONR();
- case 0x00A: return JOY0DAT();
- case 0x00C: return JOY1DAT();
- #if AGA_CHIPSET == 1
- case 0x07C: return 0xF8;
- #elif defined ECS_DENISE
- case 0x07C: return 0xFC;
- #endif
- default:
- custom_wput(addr,0);
- return 0xffff;
- }
- }
-
- UBYTE custom_bget(CPTR addr)
- {
- return custom_wget(addr & 0xfffe) >> (addr & 1 ? 0 : 8);
- }
-
- ULONG custom_lget(CPTR addr)
- {
- return ((ULONG)custom_wget(addr & 0xfffe) << 16) | custom_wget((addr+2) & 0xfffe);
- }
-
- void custom_wput(CPTR addr, UWORD value)
- {
- addr &= 0x1FE;
- cregs[addr>>1] = value;
- switch(addr) {
- case 0x020: DSKPTH(value); break;
- case 0x022: DSKPTL(value); break;
- case 0x024: DSKLEN(value); break;
- case 0x026: DSKDAT(value); break;
-
- case 0x02A: VPOSW(value); break;
-
- case 0x040: BLTCON0(value); break;
- case 0x042: BLTCON1(value); break;
-
- case 0x044: BLTAFWM(value); break;
- case 0x046: BLTALWM(value); break;
-
- case 0x050: BLTAPTH(value); break;
- case 0x052: BLTAPTL(value); break;
- case 0x04C: BLTBPTH(value); break;
- case 0x04E: BLTBPTL(value); break;
- case 0x048: BLTCPTH(value); break;
- case 0x04A: BLTCPTL(value); break;
- case 0x054: BLTDPTH(value); break;
- case 0x056: BLTDPTL(value); break;
-
- case 0x058: BLTSIZE(value); break;
-
- case 0x064: BLTAMOD(value); break;
- case 0x062: BLTBMOD(value); break;
- case 0x060: BLTCMOD(value); break;
- case 0x066: BLTDMOD(value); break;
-
- case 0x070: BLTCDAT(value); break;
- case 0x072: BLTBDAT(value); break;
- case 0x074: BLTADAT(value); break;
-
- case 0x07E: DSKSYNC(value); break;
-
- case 0x080: COP1LCH(value); break;
- case 0x082: COP1LCL(value); break;
- case 0x084: COP2LCH(value); break;
- case 0x086: COP2LCL(value); break;
-
- case 0x088: COPJMP1(value); break;
- case 0x08A: COPJMP2(value); break;
-
- case 0x08E: DIWSTRT(value); break;
- case 0x090: DIWSTOP(value); break;
- case 0x092: DDFSTRT(value); break;
- case 0x094: DDFSTOP(value); break;
-
- case 0x096: DMACON(value); break;
- case 0x09A: INTENA(value); break;
- case 0x09C: INTREQ(value); break;
- case 0x09E: ADKCON(value); break;
-
- case 0x0A0: AUD0LCH(value); break;
- case 0x0A2: AUD0LCL(value); break;
- case 0x0A4: AUD0LEN(value); break;
- case 0x0A6: AUD0PER(value); break;
- case 0x0A8: AUD0VOL(value); break;
-
- case 0x0B0: AUD1LCH(value); break;
- case 0x0B2: AUD1LCL(value); break;
- case 0x0B4: AUD1LEN(value); break;
- case 0x0B6: AUD1PER(value); break;
- case 0x0B8: AUD1VOL(value); break;
-
- case 0x0C0: AUD2LCH(value); break;
- case 0x0C2: AUD2LCL(value); break;
- case 0x0C4: AUD2LEN(value); break;
- case 0x0C6: AUD2PER(value); break;
- case 0x0C8: AUD2VOL(value); break;
-
- case 0x0D0: AUD3LCH(value); break;
- case 0x0D2: AUD3LCL(value); break;
- case 0x0D4: AUD3LEN(value); break;
- case 0x0D6: AUD3PER(value); break;
- case 0x0D8: AUD3VOL(value); break;
-
- case 0x0E0: BPLPTH(value, 0); break;
- case 0x0E2: BPLPTL(value, 0); break;
- case 0x0E4: BPLPTH(value, 1); break;
- case 0x0E6: BPLPTL(value, 1); break;
- case 0x0E8: BPLPTH(value, 2); break;
- case 0x0EA: BPLPTL(value, 2); break;
- case 0x0EC: BPLPTH(value, 3); break;
- case 0x0EE: BPLPTL(value, 3); break;
- case 0x0F0: BPLPTH(value, 4); break;
- case 0x0F2: BPLPTL(value, 4); break;
- case 0x0F4: BPLPTH(value, 5); break;
- case 0x0F6: BPLPTL(value, 5); break;
-
- case 0x100: BPLCON0(value); break;
- case 0x102: BPLCON1(value); break;
- case 0x104: BPLCON2(value); break;
- case 0x106: BPLCON3(value); break;
-
- case 0x108: BPL1MOD(value); break;
- case 0x10A: BPL2MOD(value); break;
-
- case 0x110: BPL1DAT(value); break;
- case 0x112: BPL2DAT(value); break;
- case 0x114: BPL3DAT(value); break;
- case 0x116: BPL4DAT(value); break;
- case 0x118: BPL5DAT(value); break;
- case 0x11A: BPL6DAT(value); break;
-
- case 0x180: case 0x182: case 0x184: case 0x186: case 0x188: case 0x18A:
- case 0x18C: case 0x18E: case 0x190: case 0x192: case 0x194: case 0x196:
- case 0x198: case 0x19A: case 0x19C: case 0x19E: case 0x1A0: case 0x1A2:
- case 0x1A4: case 0x1A6: case 0x1A8: case 0x1AA: case 0x1AC: case 0x1AE:
- case 0x1B0: case 0x1B2: case 0x1B4: case 0x1B6: case 0x1B8: case 0x1BA:
- case 0x1BC: case 0x1BE:
- COLOR(value & 0xFFF, (addr & 0x3E) / 2);
- break;
- case 0x120: case 0x124: case 0x128: case 0x12C:
- case 0x130: case 0x134: case 0x138: case 0x13C:
- SPRxPTH(value, (addr - 0x120) / 4);
- break;
- case 0x122: case 0x126: case 0x12A: case 0x12E:
- case 0x132: case 0x136: case 0x13A: case 0x13E:
- SPRxPTL(value, (addr - 0x122) / 4);
- break;
- case 0x140: case 0x148: case 0x150: case 0x158:
- case 0x160: case 0x168: case 0x170: case 0x178:
- SPRxPOS(value, (addr - 0x140) / 8);
- break;
- case 0x142: case 0x14A: case 0x152: case 0x15A:
- case 0x162: case 0x16A: case 0x172: case 0x17A:
- SPRxCTL(value, (addr - 0x142) / 8);
- break;
- case 0x144: case 0x14C: case 0x154: case 0x15C:
- case 0x164: case 0x16C: case 0x174: case 0x17C:
- SPRxDATA(value, (addr - 0x144) / 8);
- break;
- case 0x146: case 0x14E: case 0x156: case 0x15E:
- case 0x166: case 0x16E: case 0x176: case 0x17E:
- SPRxDATB(value, (addr - 0x146) / 8);
- break;
-
- case 0x36: JOYTEST(value); break;
- #if defined(ECS_AGNUS) || (AGA_CHIPSET == 1)
- case 0x5A: BLTCON0L(value); break;
- case 0x5C: BLTSIZV(value); break;
- case 0x5E: BLTSIZH(value); break;
- #endif
- #if AGA_CHIPSET == 1
- case 0x10C: BPLCON4(value); break;
- #endif
- }
- }
-
- void custom_bput(CPTR addr, UBYTE value)
- {
- /* Yes, there are programs that do this. The programmers should be shot.
- * This might actually work sometimes. */
- UWORD rval = value;
- CPTR raddr = addr & 0x1FE;
- if (addr & 1) {
- rval |= cregs[raddr >> 1] & 0xFF00;
- } else {
- rval <<= 8;
- rval |= cregs[raddr >> 1] & 0xFF;
- }
- custom_wput(raddr, rval);
- }
-
- void custom_lput(CPTR addr, ULONG value)
- {
- custom_wput(addr & 0xfffe, value >> 16);
- custom_wput((addr+2) & 0xfffe, (UWORD)value);
- }
-
-