From: Toni Wilen Date: Sat, 10 Apr 2021 14:15:51 +0000 (+0300) Subject: Custom emulation update WIP. Sprites. X-Git-Tag: 4900~157 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=44c286c40ff22cdb4c77ab5873c72a9bb1933e4a;p=francis%2Fwinuae.git Custom emulation update WIP. Sprites. --- diff --git a/custom.cpp b/custom.cpp index 055f6d64..526ccc40 100644 --- a/custom.cpp +++ b/custom.cpp @@ -1,5 +1,4 @@ /* -/* * UAE - The Un*x Amiga Emulator * * Custom chip emulation @@ -58,6 +57,8 @@ #define AUTOSCALE_SPRITES 1 #define ALL_SUBPIXEL 1 +#define RGA_COPPER_PIPELINE_DEPTH 2 +#define RGA_SPRITE_PIPELINE_DEPTH 3 #define REFRESH_FIRST_HPOS 3 #define DMAL_FIRST_HPOS 11 #define SPR_FIRST_HPOS 25 @@ -133,6 +134,7 @@ static bool genlockvtoggle; static bool graphicsbuffer_retry; static int cia_hsync; static bool toscr_scanline_complex_bplcon1; +static bool cant_this_last_line; #define LOF_TOGGLES_NEEDED 3 //#define NLACE_CNT_NEEDED 50 @@ -510,8 +512,8 @@ static int bprun_pipeline_flush_delay; static uae_u16 rga_pipeline[256]; static int rga_pipeline_bpl_read, rga_pipeline_bpl_write; -static int rga_pipeline_copper_read; -static int rga_pipeline_sprite_read; +static int rga_pipeline_copper; +static int rga_pipeline_sprite; #define RGA_PIPELINE_MASK 255 struct custom_store custom_storage[256]; @@ -1097,6 +1099,15 @@ STATIC_INLINE int isocs7planes(void) return !aga_mode && bplcon0_res == 0 && bplcon0_planes == 7; } +int get_sprite_dma_rel(int off) +{ + uae_u16 v = rga_pipeline[(rga_pipeline_sprite + off) & RGA_PIPELINE_MASK] & 0xff; + if (v >= 0x40 && v <= 0x5f) { + return v & 7; + } + return -1; +} + int get_bitplane_dma_rel(int off) { uae_u16 v = rga_pipeline[(rga_pipeline_bpl_read + off) & RGA_PIPELINE_MASK] & 0xff; @@ -3016,7 +3027,7 @@ static void decide_bpl_fetch(int endhpos) } } -static bool cant_this_last_line(void) +static bool is_cant_this_last_line(void) { // Last line.. // ..works normally if A1000 Agnus @@ -3038,7 +3049,7 @@ static void decide_vline(int endhpos) } } // last line of field can never have bitplane dma active if not A1000 Agnus. - if (vpos == plflastline || cant_this_last_line() || (vpos == 0 && currprefs.cs_dipagnus)) { + if (vpos == plflastline || cant_this_last_line || (vpos == 0 && currprefs.cs_dipagnus)) { diwstate = DIW_waiting_start; diwstate_vpos = vpos; SET_LINE_CYCLEBASED; @@ -3564,9 +3575,10 @@ static void decide_sprites(int hpos, bool usepointx, bool quick) if (thisline_decision.plfleft < 0 && !brdspractive() && !quick) return; + point = hpos * 2 - DDF_OFFSET; + // let sprite shift register empty completely // if sprite is at the very edge of right border - point = hpos * 2 - DDF_OFFSET; if (hpos >= maxhpos) { point += (extrahpos >> 2) - 2; } @@ -5906,12 +5918,15 @@ static void spr_arm(int num, int state) static void sprstartstop(struct sprite *s) { - if (vpos < sprite_vblank_endline || cant_this_last_line () || s->ignoreverticaluntilnextline) + if (vpos < sprite_vblank_endline || cant_this_last_line || s->ignoreverticaluntilnextline) { return; - if (vpos == s->vstart) + } + if (vpos == s->vstart) { s->dmastate = 1; - if (vpos == s->vstop) + } + if (vpos == s->vstop) { s->dmastate = 0; + } } static void SPRxCTLPOS(int num) @@ -5981,6 +5996,7 @@ static void SPRxCTL_1(uae_u16 v, int num, int hpos) static void SPRxPOS_1(uae_u16 v, int num, int hpos) { struct sprite *s = &spr[num]; + if (0 && hpos >= maxhpos - 2 && s->pos != v && vpos < maxvpos - 1) { vpos++; sprstartstop(s); @@ -6119,7 +6135,7 @@ static void SPRxPOS(int hpos, uae_u16 v, int num) // Superfrog flashing intro bees fix. // if SPRxPOS is written one cycle before sprite's first DMA slot and sprite's vstart matches after // SPRxPOS write, current line's DMA slot's stay idle. DMA decision seems to be done 4 cycles earlier. - if (hpos >= SPR_FIRST_HPOS + num * 4 - 4 && hpos <= SPR_FIRST_HPOS + num * 4 - 1 && oldvpos != vpos) { + if (hpos >= SPR_FIRST_HPOS + num * 4 - 4 && hpos <= SPR_FIRST_HPOS + num * 4 - 1 && oldvpos != vpos && (copper_access || currprefs.cpu_memory_cycle_exact)) { s->ptxvpos2 = vpos; s->ptxhpos2 = hpos + 4; } @@ -6128,7 +6144,7 @@ static void SPRxPOS(int hpos, uae_u16 v, int num) static void SPRxPTH(int hpos, uae_u16 v, int num) { decide_sprites(hpos); - if (hpos - 1 != spr[num].ptxhpos) { + if (get_sprite_dma_rel(-2) != num || (!copper_access && !currprefs.cpu_memory_cycle_exact)) { spr[num].pt &= 0xffff; spr[num].pt |= (uae_u32)v << 16; } @@ -6141,7 +6157,7 @@ static void SPRxPTH(int hpos, uae_u16 v, int num) static void SPRxPTL(int hpos, uae_u16 v, int num) { decide_sprites(hpos); - if (hpos - 1 != spr[num].ptxhpos) { + if (hpos != spr[num].ptxhpos || (!copper_access && !currprefs.cpu_memory_cycle_exact)) { spr[num].pt &= ~0xffff; spr[num].pt |= v & ~1; } @@ -6338,7 +6354,7 @@ static int custom_wput_copper(int hpos, uaecptr pt, uaecptr addr, uae_u32 value, return v; } -static void do_sprites(int endhpos); +static void decide_sprite_fetch(int endhpos); static void decide_line_decision(int endhpos) @@ -6449,7 +6465,9 @@ static void decide_line_decision(int endhpos) if (!bprun && dma && diw && hwi && !hwi_old) { // Bitplane sequencer activated bprun = -1; - plfstrt_sprite = hpos + 4; + if (plfstrt_sprite > hpos) { + plfstrt_sprite = hpos; + } } hwi_old = hwi; @@ -6510,7 +6528,9 @@ static void decide_line_decision(int endhpos) if (!ddf_limit && ddfstrt_match && !bprun && dma && diw) { // Bitplane sequencer activated bprun = -1; - plfstrt_sprite = hpos + 2; + if (plfstrt_sprite > hpos) { + plfstrt_sprite = hpos; + } } // DMA or DIW off: clear BPRUN @@ -6531,9 +6551,7 @@ static void decide_line_decision(int endhpos) } } - if (hpos >= last_decide_sprite_hpos && last_decide_sprite_hpos < SPR_FIRST_HPOS + 4 * MAX_SPRITES) { - do_sprites(hpos + 1); - } + decide_sprite_fetch(hpos + 1); hpos++; } @@ -6566,7 +6584,7 @@ static int customdelay[]= { /* BPLxDAT */ 0,0,0,0,0,0,0,0, /* 8 */ /* SPRxPTH/SPRxPTL */ - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 16 */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 16 */ /* SPRxPOS/SPRxCTL/SPRxDATA/SPRxDATB */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* COLORxx */ @@ -6862,8 +6880,8 @@ static void copper_ff(int hpos) { int diff = hpos - last_copper_hpos; if (diff > 0) { - rga_pipeline_copper_read += diff; - rga_pipeline_copper_read &= RGA_PIPELINE_MASK; + rga_pipeline_copper += diff; + rga_pipeline_copper &= RGA_PIPELINE_MASK; } last_copper_hpos = hpos; } @@ -6924,7 +6942,7 @@ static void update_copper(int until_hpos) // NOTE: can use odd cycles if DMA request was done during last cycle of line and it was even cycle (always in PAL). // request cycle 226 (even), request always completes in 2 cycles = cycle 1 (odd). // pipelined copper DMA read? - int rpos = (rga_pipeline_copper_read - 2) & RGA_PIPELINE_MASK; + int rpos = (rga_pipeline_copper - RGA_COPPER_PIPELINE_DEPTH) & RGA_PIPELINE_MASK; bool copper_dma = rga_pipeline[rpos] >= 0x80 && rga_pipeline[rpos] <= 0x8f; if (copper_dma) { uae_u16 v = rga_pipeline[rpos]; @@ -6953,7 +6971,7 @@ static void update_copper(int until_hpos) } } - cp = &rga_pipeline[(rga_pipeline_copper_read + 0) & RGA_PIPELINE_MASK]; + cp = &rga_pipeline[(rga_pipeline_copper + 0) & RGA_PIPELINE_MASK]; switch (cop_state.state) { @@ -7132,8 +7150,8 @@ next: } hpos++; - rga_pipeline_copper_read++; - rga_pipeline_copper_read &= RGA_PIPELINE_MASK; + rga_pipeline_copper++; + rga_pipeline_copper &= RGA_PIPELINE_MASK; last_copper_hpos = hpos; } } @@ -7214,7 +7232,7 @@ static void cursorsprite (void) } } -static uae_u16 sprite_fetch(struct sprite *s, uaecptr pt, bool dma, int hpos, int cycle, int mode) +static uae_u16 sprite_fetch(struct sprite *s, uaecptr pt, int hpos, int slot, int mode) { uae_u16 data = last_custom_value1; @@ -7223,40 +7241,37 @@ static uae_u16 sprite_fetch(struct sprite *s, uaecptr pt, bool dma, int hpos, in write_log(_T("Sprite %d, hpos %d wrong cycle polarity!\n"), num, hpos); } - if (dma) { - if (cycle && currprefs.cpu_memory_cycle_exact) - s->ptxhpos = hpos; + s->ptxhpos = hpos; #ifdef DEBUGGER - int num = s - &spr[0]; - if (debug_dma) { - record_dma_read(num * 8 + 0x140 + mode * 4 + cycle * 2, pt, hpos, vpos, DMARECORD_SPRITE, num); - } - if (memwatch_enabled) { - debug_getpeekdma_chipram(pt, MW_MASK_SPR_0 << num, num * 8 + 0x140 + mode * 4 + cycle * 2, num * 4 + 0x120); - } + int num = s - &spr[0]; + if (debug_dma) { + record_dma_read(num * 8 + 0x140 + mode * 4 + slot * 2, pt, hpos, vpos, DMARECORD_SPRITE, num); + } + if (memwatch_enabled) { + debug_getpeekdma_chipram(pt, MW_MASK_SPR_0 << num, num * 8 + 0x140 + mode * 4 + slot * 2, num * 4 + 0x120); + } #endif - data = last_custom_value1 = chipmem_wget_indirect(pt); + data = last_custom_value1 = chipmem_wget_indirect(pt); #ifdef DEBUGGER - if (debug_dma) { - record_dma_read_value(data); - } - if (memwatch_enabled) { - debug_getpeekdma_value(data); - } -#endif - alloc_cycle(hpos, CYCLE_SPRITE); + if (debug_dma) { + record_dma_read_value(data); + } + if (memwatch_enabled) { + debug_getpeekdma_value(data); } +#endif + alloc_cycle(hpos, CYCLE_SPRITE); return data; } -static void sprite_fetch_full(struct sprite *s, int hpos, int cycle, int mode, uae_u16 *v0, uae_u32 *v1, uae_u32 *v2) +static void sprite_fetch_full(struct sprite *s, int hpos, int slot, int mode, uae_u16 *v0, uae_u32 *v1, uae_u32 *v2) { uae_u32 data321 = 0, data322 = 0; uae_u16 data16; if (sprite_width == 16) { - data16 = sprite_fetch(s, s->pt, true, hpos, cycle, mode); + data16 = sprite_fetch(s, s->pt, hpos, slot, mode); s->pt += 2; } else if (sprite_width == 64) { @@ -7270,7 +7285,7 @@ static void sprite_fetch_full(struct sprite *s, int hpos, int cycle, int mode, u pm1 = pm; pm2 = pm + 4; } - data321 = sprite_fetch(s, pm1, true, hpos, cycle, mode) << 16; + data321 = sprite_fetch(s, pm1, hpos, slot, mode) << 16; data321 |= chipmem_wget_indirect(pm1 + 2); data322 = chipmem_wget_indirect(pm2) << 16; data322 |= chipmem_wget_indirect(pm2 + 2); @@ -7286,7 +7301,7 @@ static void sprite_fetch_full(struct sprite *s, int hpos, int cycle, int mode, u } else { // 32 uaecptr pm = s->pt & ~3; - data321 = sprite_fetch(s, pm, true, hpos, cycle, mode) << 16; + data321 = sprite_fetch(s, pm, hpos, slot, mode) << 16; data321 |= chipmem_wget_indirect(pm + 2); if (s->pt & 2) { data321 &= 0x0000ffff; @@ -7305,157 +7320,26 @@ static void sprite_fetch_full(struct sprite *s, int hpos, int cycle, int mode, u *v2 = data322; } -static void do_sprite_dma(uae_u16 dat, int hpos) +static void do_sprite_fetch(int hpos, uae_u16 dat) { int num = dat & 7; struct sprite *s = &spr[num]; uae_u32 data321, data322; uae_u16 data; - bool cycle = (dat & 8) != 0; - - sprite_fetch_full(s, hpos, cycle, false, &data, &data321, &data322); - if (1) { - if (cycle) { - SPRxDATB_1(data, num, hpos); - } else { - SPRxDATA_1(data, num, hpos); - } -#ifdef AGA - switch (sprite_width) - { - case 64: - if (cycle == 0) { - s->data[1] = data321; - s->data[2] = data322 >> 16; - s->data[3] = data322; - } else { - s->datb[1] = data321; - s->datb[2] = data322 >> 16; - s->datb[3] = data322; - } - break; - case 32: - if (cycle == 0) { - s->data[1] = data321; - s->data[2] = data; - s->data[3] = data321; - } else { - s->datb[1] = data321; - s->datb[2] = data; - s->datb[3] = data321; - } - break; - } -#endif - } else { - if (cycle) { - SPRxPOS_1(data, num, hpos); - } else { - SPRxCTL_1(data, num, hpos); - } - } - -} - -static void do_sprites_1(int num, int cycle, int hpos) -{ - struct sprite *s = &spr[num]; - int posctl = 0; - uae_u16 data; - // fetch both sprite pairs even if DMA was switched off between sprites - int isdma = dmaen(DMA_SPRITE) || ((num & 1) && spr[num & ~1].dmacycle); - bool unaligned = (spr[num].pt & 2) != 0; - - if (cant_this_last_line()) - return; - -// see SPRxCTRL below -// if (isdma && vpos == sprite_vblank_endline) -// spr_arm(num, 0); - -#ifdef AGA - if (isdma && s->dblscan && (fmode & 0x8000) && (vpos & 1) != (s->vstart & 1) && s->dmastate) { - spr_arm(num, 1); - return; - } -#endif -#if SPRITE_DEBUG >= 3 * 256 - if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY && (SPRITE_DEBUG & (1 << num))) - write_log(_T("%d:%d:slot%d:%d\n"), vpos, hpos, num, cycle); -#endif - if (vpos == s->vstart) { -#if SPRITE_DEBUG > 0 - if (!s->dmastate && vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY && (SPRITE_DEBUG & (1 << num))) - write_log(_T("%d:%d:SPR%d START\n"), vpos, hpos, num); -#endif - s->dmastate = 1; - if (s->ptxvpos2 == vpos && hpos < s->ptxhpos2) - return; - if (num == 0 && cycle == 0) - cursorsprite(); - } - if (vpos == s->vstop || vpos == sprite_vblank_endline) { -#if SPRITE_DEBUG > 0 - if (s->dmastate && vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY && (SPRITE_DEBUG & (1 << num))) - write_log(_T("%d:%d:SPR%d STOP\n"), vpos, hpos, num); -#endif - s->dmastate = 0; - } - - if (!isdma) - return; + bool slot = (dat & 8) != 0; + bool dmastate = (dat & 0x10) != 0; - int dma = hpos < plfstrt_sprite || diwstate != DIW_waiting_stop; + spr[num].ptxhpos = MAXHPOS; + sprite_fetch_full(s, hpos, slot, false, &data, &data321, &data322); int sprxp = s->xpos >> (sprite_buffer_res + 1); bool start_before_dma = hpos >= sprxp && sprxp >= 16; - if (vpos == s->vstop || vpos == sprite_vblank_endline) { - s->dmastate = 0; - posctl = 1; - if (dma) { - uae_u32 data321, data322; - sprite_fetch_full(s, hpos, cycle, false, &data, &data321, &data322); - //write_log (_T("%d:%d: %04X=%04X\n"), vpos, hpos, 0x140 + cycle * 2 + num * 8, data); - if (cycle == 0) { - if (start_before_dma && s->armed) { - maybe_decide_sprites(num, hpos); - } - SPRxPOS_1(data, num, hpos); - s->dmacycle = 1; - } else { - // This is needed to disarm previous field's sprite. - // It can be seen on OCS Agnus + ECS Denise combination where - // this cycle is disabled due to weird DDFTSTR=$18 copper list - // which causes corrupted sprite to "wrap around" the display. - SPRxCTL_1(data, num, hpos); - s->dmastate = 0; - sprstartstop(s); - } - } - if (vpos == sprite_vblank_endline) { - // s->vstart == sprite_vblank_endline won't enable the sprite. - s->dmastate = 0; - } -#if SPRITE_DEBUG >= 256 - if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY && (SPRITE_DEBUG & (1 << num))) { - write_log(_T("%d:%d:dma:P=%06X "), vpos, hpos, s->pt); - } -#endif - } - if (s->dmastate && !posctl && dma) { - uae_u32 data321, data322; - sprite_fetch_full(s, hpos, cycle, true, &data, &data321, &data322); -#if SPRITE_DEBUG >= 256 - if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY && (SPRITE_DEBUG & (1 << num))) { - write_log(_T("%d:%d:dma:P=%06X "), vpos, hpos, s->pt); - } -#endif - if (cycle == 0) { + if (dmastate) { + if (!slot) { // if xpos is earlier than this cycle, decide it first. if (start_before_dma) { maybe_decide_sprites(num, hpos); } SPRxDATA_1(data, num, hpos); - s->dmacycle = 1; } else { // This is needed if xpos is between DATA and DATB fetches // Test does not need to be accurate, only purpose is to @@ -7469,7 +7353,7 @@ static void do_sprites_1(int num, int cycle, int hpos) switch (sprite_width) { case 64: - if (cycle == 0) { + if (!slot) { s->data[1] = data321; s->data[2] = data322 >> 16; s->data[3] = data322; @@ -7480,7 +7364,7 @@ static void do_sprites_1(int num, int cycle, int hpos) } break; case 32: - if (cycle == 0) { + if (!slot) { s->data[1] = data321; s->data[2] = data; s->data[3] = data321; @@ -7492,57 +7376,107 @@ static void do_sprites_1(int num, int cycle, int hpos) break; } #endif + } else { + if (!slot) { + if (start_before_dma && s->armed) { + maybe_decide_sprites(num, hpos); + } + SPRxPOS_1(data, num, hpos); + } else { + SPRxCTL_1(data, num, hpos); + // This is needed to disarm previous field's sprite. + // It can be seen on OCS Agnus + ECS Denise combination where + // this cycle is disabled due to weird DDFTSTR=$18 copper list + // which causes corrupted sprite to "wrap around" the display. + s->dmastate = 0; + sprstartstop(s); + } } + } -static void do_sprites(int endhpos) +static void decide_sprite_fetch(int endhpos) { - int maxspr, minspr; - - if (vpos < sprite_vblank_endline) { - last_decide_sprite_hpos = maxhpos; - return; - } - - if (doflickerfix() && interlace_seen && (next_lineno & 1)) - return; - - minspr = last_decide_sprite_hpos; - maxspr = endhpos; - - if (minspr >= maxspr || last_decide_sprite_hpos == endhpos) - return; - - if (maxspr > SPR_FIRST_HPOS + MAX_SPRITES * 4) - maxspr = SPR_FIRST_HPOS + MAX_SPRITES * 4; - if (minspr < SPR_FIRST_HPOS) - minspr = SPR_FIRST_HPOS; - - if (minspr >= maxspr) { + if ((vpos < sprite_vblank_endline) || (doflickerfix() && interlace_seen && (next_lineno & 1)) || (cant_this_last_line)) { + int diff = endhpos - last_decide_sprite_hpos; + if (diff > 0) { + rga_pipeline_sprite += diff; + rga_pipeline_sprite &= RGA_PIPELINE_MASK; + } last_decide_sprite_hpos = endhpos; return; } - for (int hpos = minspr; hpos < maxspr; hpos++) { - int cycle = -1; - int num = (hpos - SPR_FIRST_HPOS) / 4; - int slot = (hpos - SPR_FIRST_HPOS) & 3; - switch (slot) - { - case 0: - cycle = 0; - spr[num].dmacycle = 0; - break; - case 2: - cycle = 1; - break; - } - if (cycle >= 0) { - spr[num].ptxhpos = MAXHPOS; - do_sprites_1(num, cycle, hpos); + int hpos = last_decide_sprite_hpos; + while (hpos < endhpos) { + if (hpos >= SPR_FIRST_HPOS - RGA_SPRITE_PIPELINE_DEPTH && hpos < SPR_FIRST_HPOS + MAX_SPRITES * 4) { + int rpos = (rga_pipeline_sprite - RGA_SPRITE_PIPELINE_DEPTH) & RGA_PIPELINE_MASK; + bool sprite_dma = rga_pipeline[rpos] >= 0x40 && rga_pipeline[rpos] <= 0x5f; + if (sprite_dma) { + uae_u16 dat = rga_pipeline[rpos]; + do_sprite_fetch(hpos, dat); + rga_pipeline[rpos] = 0; + } + if (hpos < SPR_FIRST_HPOS + MAX_SPRITES * 4 - RGA_SPRITE_PIPELINE_DEPTH) { + int num = (hpos - (SPR_FIRST_HPOS - RGA_SPRITE_PIPELINE_DEPTH)) / 4; + int slot = (hpos - (SPR_FIRST_HPOS - RGA_SPRITE_PIPELINE_DEPTH)) & 3; + if (slot == 0 || slot == 2) { + struct sprite *s = &spr[num]; + if (slot == 0) { + if (!s->dmacycle && s->dmastate) { + s->dmacycle = 1; + } + if (vpos == s->vstart) { + s->dmastate = 1; + s->dmacycle = 1; + if (s->ptxvpos2 == vpos && hpos < s->ptxhpos2) + return; + if (num == 0 && slot == 0) { + cursorsprite(); + } + } + if (vpos <= sprite_vblank_endline) { + s->dmacycle = 0; + s->dmastate = 0; + } + if (vpos == s->vstop || vpos == sprite_vblank_endline) { + s->dmastate = 0; + s->dmacycle = 1; + } + } + if (dmaen(DMA_SPRITE) && hpos < plfstrt_sprite && s->dmacycle) { + bool dodma = true; +#ifdef AGA + if (s->dblscan && (fmode & 0x8000) && (vpos & 1) != (s->vstart & 1) && s->dmastate) { + spr_arm(num, 1); + dodma = false; + } +#endif + if (dodma) { + uae_u16 *sp = &rga_pipeline[(rga_pipeline_sprite + 0) & RGA_PIPELINE_MASK]; + uae_u16 dat = 0x40 | (s->dmastate ? 0x10 : 0x00) | (s->dmacycle == 1 ? 0 : 8) | num; + if (*sp) { + write_log(_T("sprite cycle already allocated! %02x\n"), *sp); + } + *sp = dat; + } + } + if (s->dmacycle) { + s->dmacycle++; + if (s->dmacycle > 2) { + s->dmacycle = 0; + if (s->dmastate) { + s->dmacycle = 1; + } + } + } + } + } } + hpos++; + rga_pipeline_sprite++; + rga_pipeline_sprite &= RGA_PIPELINE_MASK; } - last_decide_sprite_hpos = endhpos; } @@ -7550,12 +7484,11 @@ static void init_sprites(void) { for (int i = 0; i < MAX_SPRITES; i++) { struct sprite *s = &spr[i]; - s->pos = 0; - s->ctl = 0; + memset(s, 0, sizeof(struct sprite)); } } -static void init_hardware_frame (void) +static void init_hardware_frame(void) { int i; @@ -7595,7 +7528,7 @@ static void init_hardware_frame (void) ddffirstword_total = max_diwlastword; ddflastword_total = 0; plflastline_total = 0; - plffirstline_total = current_maxvpos (); + plffirstline_total = current_maxvpos(); first_bplcon0 = 0; autoscale_bordercolors = 0; @@ -7605,7 +7538,7 @@ static void init_hardware_frame (void) } } -void init_hardware_for_drawing_frame (void) +void init_hardware_for_drawing_frame(void) { /* Avoid this code in the first frame after a customreset. */ if (prev_sprite_entries) { @@ -7642,9 +7575,9 @@ void init_hardware_for_drawing_frame (void) next_sprite_forced = 1; } -static int rpt_vsync (int adjust) +static int rpt_vsync(int adjust) { - frame_time_t curr_time = read_processor_time (); + frame_time_t curr_time = read_processor_time(); int v = curr_time - vsyncwaittime + adjust; if (v > syncbase || v < -syncbase) { vsyncmintime = vsyncmaxtime = vsyncwaittime = curr_time; @@ -9378,6 +9311,7 @@ static void hsync_handler_post (bool onvsync) if (vpos + 1 == maxvpos + lof_store || vpos + 1 == maxvpos + lof_store + 1) { lof_lastline = lof_store != 0; } + cant_this_last_line = is_cant_this_last_line(); if (ecs_agnus) { if (vpos == sprhstrt) { @@ -9741,15 +9675,16 @@ void custom_cpuchange(void) intena = intena | 0x8000; } -void custom_reset (bool hardreset, bool keyboardreset) +void custom_reset(bool hardreset, bool keyboardreset) { - if (hardreset) + if (hardreset) { board_prefs_changed(-1, -1); + } - target_reset (); + target_reset(); devices_reset(hardreset); - write_log (_T("Reset at %08X. Chipset mask = %08X\n"), M68K_GETPC, currprefs.chipset_mask); - memory_map_dump (); + write_log(_T("Reset at %08X. Chipset mask = %08X\n"), M68K_GETPC, currprefs.chipset_mask); + memory_map_dump(); lightpen_active = 0; lightpen_triggered = 0; @@ -9764,8 +9699,8 @@ void custom_reset (bool hardreset, bool keyboardreset) memset(rga_pipeline, 0, sizeof(rga_pipeline)); rga_pipeline_bpl_read = 0; rga_pipeline_bpl_write = 3; - rga_pipeline_copper_read = 2; - rga_pipeline_sprite_read = 3; + rga_pipeline_copper = 2; + rga_pipeline_sprite = 3; if (!savestate_state) { cia_hsync = 0; @@ -9847,7 +9782,7 @@ void custom_reset (bool hardreset, bool keyboardreset) vpos_prev = maxvpos - 1; vpos_count = vpos_count_diff = 0; - inputdevice_reset (); + inputdevice_reset(); timehack_alive = 0; curr_sprite_entries = 0; @@ -9856,8 +9791,8 @@ void custom_reset (bool hardreset, bool keyboardreset) sprite_entries[1][0].first_pixel = MAX_SPR_PIXELS; sprite_entries[0][1].first_pixel = 0; sprite_entries[1][1].first_pixel = MAX_SPR_PIXELS; - memset (spixels, 0, 2 * MAX_SPR_PIXELS * sizeof *spixels); - memset (&spixstate, 0, sizeof spixstate); + memset(spixels, 0, 2 * MAX_SPR_PIXELS * sizeof *spixels); + memset(&spixstate, 0, sizeof spixstate); toscr_delay_sh[0] = 0; toscr_delay_sh[1] = 0; @@ -9876,16 +9811,16 @@ void custom_reset (bool hardreset, bool keyboardreset) lof_togglecnt_nlace = lof_togglecnt_lace = 0; //nlace_cnt = NLACE_CNT_NEEDED; - audio_reset (); - if (!isrestore ()) { + audio_reset(); + if (!isrestore()) { /* must be called after audio_reset */ adkcon = 0; - serial_uartbreak (0); - audio_update_adkmasks (); + serial_uartbreak(0); + audio_update_adkmasks(); } - init_hardware_frame (); - drawing_init (); + init_hardware_frame(); + drawing_init(); reset_decisions_scanline_start(); reset_decisions_hsync_start(); @@ -9899,7 +9834,7 @@ void custom_reset (bool hardreset, bool keyboardreset) uae_u16 v; uae_u32 vv; - audio_update_adkmasks (); + audio_update_adkmasks(); INTENA(0); INTREQ(0); COPJMP(1, 1); @@ -9969,8 +9904,9 @@ void custom_reset (bool hardreset, bool keyboardreset) enforcer_disable(); #endif - if (hardreset) + if (hardreset) { rtc_hardreset(); + } // must be last #ifdef AUTOCONFIG @@ -10738,7 +10674,7 @@ uae_u8 *restore_custom(uae_u8 *src) #define SW save_u16 #define SL save_u32 -uae_u8 *save_custom (int *len, uae_u8 *dstptr, int full) +uae_u8 *save_custom(int *len, uae_u8 *dstptr, int full) { uae_u8 *dstbak, *dst; int i, dummy; @@ -10746,104 +10682,104 @@ uae_u8 *save_custom (int *len, uae_u8 *dstptr, int full) uae_u16 dsklen, dsksync, dskbytr; uae_u16 v; - DISK_save_custom (&dskpt, &dsklen, &dsksync, &dskbytr); + DISK_save_custom(&dskpt, &dsklen, &dsksync, &dskbytr); if (dstptr) dstbak = dst = dstptr; else dstbak = dst = xmalloc (uae_u8, 8 + 256 * 2); - SL (currprefs.chipset_mask); - SW (0); /* 000 BLTDDAT */ - SW (dmacon); /* 002 DMACONR */ - SW (VPOSR ()); /* 004 VPOSR */ - SW (VHPOSR ()); /* 006 VHPOSR */ - SW (0); /* 008 DSKDATR */ - SW (JOYGET (0)); /* 00A JOY0DAT */ - SW (JOYGET (1)); /* 00C JOY1DAT */ - SW (clxdat | 0x8000); /* 00E CLXDAT */ - SW (ADKCONR ()); /* 010 ADKCONR */ - SW (POT0DAT ()); /* 012 POT0DAT */ - SW (POT1DAT ()); /* 014 POT1DAT */ - SW (0); /* 016 POTINP * */ - SW (0); /* 018 SERDATR * */ - SW (dskbytr); /* 01A DSKBYTR */ - SW (INTENAR ()); /* 01C INTENAR */ - SW (INTREQR ()); /* 01E INTREQR */ - SL (dskpt); /* 020-023 DSKPT */ - SW (dsklen); /* 024 DSKLEN */ - SW (0); /* 026 DSKDAT */ - SW (refptr); /* 028 REFPTR */ - SW ((lof_store ? 0x8001 : 0) | (lol ? 0x0080 : 0));/* 02A VPOSW */ - SW (0); /* 02C VHPOSW */ - SW (copcon); /* 02E COPCON */ - SW (serdat); /* 030 SERDAT * */ - SW (serper); /* 032 SERPER * */ - SW (potgo_value); /* 034 POTGO */ - SW (0); /* 036 JOYTEST * */ - SW (0); /* 038 STREQU */ - SW (0); /* 03A STRVBL */ - SW (0); /* 03C STRHOR */ - SW (0); /* 03E STRLONG */ - SW (bltcon0); /* 040 BLTCON0 */ - SW (bltcon1); /* 042 BLTCON1 */ - SW (blt_info.bltafwm); /* 044 BLTAFWM */ - SW (blt_info.bltalwm); /* 046 BLTALWM */ - SL (bltcpt); /* 048-04B BLTCPT */ - SL (bltbpt); /* 04C-04F BLTCPT */ - SL (bltapt); /* 050-053 BLTCPT */ - SL (bltdpt); /* 054-057 BLTCPT */ + SL(currprefs.chipset_mask); + SW(0); /* 000 BLTDDAT */ + SW(dmacon); /* 002 DMACONR */ + SW(VPOSR()); /* 004 VPOSR */ + SW(VHPOSR()); /* 006 VHPOSR */ + SW(0); /* 008 DSKDATR */ + SW(JOYGET(0)); /* 00A JOY0DAT */ + SW(JOYGET(1)); /* 00C JOY1DAT */ + SW(clxdat | 0x8000); /* 00E CLXDAT */ + SW(ADKCONR()); /* 010 ADKCONR */ + SW(POT0DAT()); /* 012 POT0DAT */ + SW(POT1DAT()); /* 014 POT1DAT */ + SW(0); /* 016 POTINP * */ + SW(0); /* 018 SERDATR * */ + SW(dskbytr); /* 01A DSKBYTR */ + SW(INTENAR()); /* 01C INTENAR */ + SW(INTREQR()); /* 01E INTREQR */ + SL(dskpt); /* 020-023 DSKPT */ + SW(dsklen); /* 024 DSKLEN */ + SW(0); /* 026 DSKDAT */ + SW(refptr); /* 028 REFPTR */ + SW((lof_store ? 0x8001 : 0) | (lol ? 0x0080 : 0));/* 02A VPOSW */ + SW(0); /* 02C VHPOSW */ + SW(copcon); /* 02E COPCON */ + SW(serdat); /* 030 SERDAT * */ + SW(serper); /* 032 SERPER * */ + SW(potgo_value); /* 034 POTGO */ + SW(0); /* 036 JOYTEST * */ + SW(0); /* 038 STREQU */ + SW(0); /* 03A STRVBL */ + SW(0); /* 03C STRHOR */ + SW(0); /* 03E STRLONG */ + SW(bltcon0); /* 040 BLTCON0 */ + SW(bltcon1); /* 042 BLTCON1 */ + SW(blt_info.bltafwm); /* 044 BLTAFWM */ + SW(blt_info.bltalwm); /* 046 BLTALWM */ + SL(bltcpt); /* 048-04B BLTCPT */ + SL(bltbpt); /* 04C-04F BLTCPT */ + SL(bltapt); /* 050-053 BLTCPT */ + SL(bltdpt); /* 054-057 BLTCPT */ if (blt_info.vblitsize > 1024 || blt_info.hblitsize > 64) { v = 0; } else { v = (blt_info.vblitsize << 6) | (blt_info.hblitsize & 63); } SW (v); /* 058 BLTSIZE */ - SW (bltcon0 & 0xff); /* 05A BLTCON0L (use BLTCON0 instead) */ - SW (blt_info.vblitsize);/* 05C BLTSIZV */ - SW (blt_info.hblitsize);/* 05E BLTSIZH */ - SW (blt_info.bltcmod); /* 060 BLTCMOD */ - SW (blt_info.bltbmod); /* 062 BLTBMOD */ - SW (blt_info.bltamod); /* 064 BLTAMOD */ - SW (blt_info.bltdmod); /* 066 BLTDMOD */ - SW (0); /* 068 ? */ - SW (0); /* 06A ? */ - SW (0); /* 06C ? */ - SW (0); /* 06E ? */ - SW (blt_info.bltcdat); /* 070 BLTCDAT */ - SW (blt_info.bltbdat); /* 072 BLTBDAT */ - SW (blt_info.bltadat); /* 074 BLTADAT */ - SW (0); /* 076 ? */ - SW (0); /* 078 ? */ - SW (0); /* 07A ? */ - SW (DENISEID (&dummy)); /* 07C DENISEID/LISAID */ - SW (dsksync); /* 07E DSKSYNC */ - SL (cop1lc); /* 080-083 COP1LC */ - SL (cop2lc); /* 084-087 COP2LC */ - SW (0); /* 088 ? */ - SW (0); /* 08A ? */ - SW (0); /* 08C ? */ - SW (diwstrt); /* 08E DIWSTRT */ - SW (diwstop); /* 090 DIWSTOP */ - SW (ddfstrt); /* 092 DDFSTRT */ - SW (ddfstop); /* 094 DDFSTOP */ - SW (dmacon); /* 096 DMACON */ - SW (clxcon); /* 098 CLXCON */ - SW (intena); /* 09A INTENA */ - SW (intreq); /* 09C INTREQ */ - SW (adkcon); /* 09E ADKCON */ + SW(bltcon0 & 0xff); /* 05A BLTCON0L (use BLTCON0 instead) */ + SW(blt_info.vblitsize); /* 05C BLTSIZV */ + SW(blt_info.hblitsize); /* 05E BLTSIZH */ + SW(blt_info.bltcmod); /* 060 BLTCMOD */ + SW(blt_info.bltbmod); /* 062 BLTBMOD */ + SW(blt_info.bltamod); /* 064 BLTAMOD */ + SW(blt_info.bltdmod); /* 066 BLTDMOD */ + SW(0); /* 068 ? */ + SW(0); /* 06A ? */ + SW(0); /* 06C ? */ + SW(0); /* 06E ? */ + SW(blt_info.bltcdat); /* 070 BLTCDAT */ + SW(blt_info.bltbdat); /* 072 BLTBDAT */ + SW(blt_info.bltadat); /* 074 BLTADAT */ + SW(0); /* 076 ? */ + SW(0); /* 078 ? */ + SW(0); /* 07A ? */ + SW(DENISEID(&dummy)); /* 07C DENISEID/LISAID */ + SW(dsksync); /* 07E DSKSYNC */ + SL(cop1lc); /* 080-083 COP1LC */ + SL(cop2lc); /* 084-087 COP2LC */ + SW(0); /* 088 ? */ + SW(0); /* 08A ? */ + SW(0); /* 08C ? */ + SW(diwstrt); /* 08E DIWSTRT */ + SW(diwstop); /* 090 DIWSTOP */ + SW(ddfstrt); /* 092 DDFSTRT */ + SW(ddfstop); /* 094 DDFSTOP */ + SW(dmacon); /* 096 DMACON */ + SW(clxcon); /* 098 CLXCON */ + SW(intena); /* 09A INTENA */ + SW(intreq); /* 09C INTREQ */ + SW(adkcon); /* 09E ADKCON */ for (i = 0; full && i < 32; i++) - SW (0); + SW(0); for (i = 0; i < 8; i++) - SL (bplpt[i]); /* 0E0-0FE BPLxPT */ - SW (bplcon0); /* 100 BPLCON0 */ - SW (bplcon1); /* 102 BPLCON1 */ - SW (bplcon2); /* 104 BPLCON2 */ - SW (bplcon3); /* 106 BPLCON3 */ - SW (bpl1mod); /* 108 BPL1MOD */ - SW (bpl2mod); /* 10A BPL2MOD */ - SW (bplcon4); /* 10C BPLCON4 */ - SW (clxcon2); /* 10E CLXCON2 */ + SL(bplpt[i]); /* 0E0-0FE BPLxPT */ + SW(bplcon0); /* 100 BPLCON0 */ + SW(bplcon1); /* 102 BPLCON1 */ + SW(bplcon2); /* 104 BPLCON2 */ + SW(bplcon3); /* 106 BPLCON3 */ + SW(bpl1mod); /* 108 BPL1MOD */ + SW(bpl2mod); /* 10A BPL2MOD */ + SW(bplcon4); /* 10C BPLCON4 */ + SW(clxcon2); /* 10E CLXCON2 */ for (i = 0;i < 8; i++) SW (fetched[i]); /* 110 BPLxDAT */ if (full) { @@ -10852,10 +10788,10 @@ uae_u8 *save_custom (int *len, uae_u8 *dstptr, int full) } for (i = 0; i < 8; i++) { struct sprite *s = &spr[i]; - SW (s->pos); /* 1x0 SPRxPOS */ - SW (s->ctl); /* 1x2 SPRxPOS */ - SW (s->data[0]); /* 1x4 SPRxDATA */ - SW (s->datb[0]); /* 1x6 SPRxDATB */ + SW(s->pos); /* 1x0 SPRxPOS */ + SW(s->ctl); /* 1x2 SPRxPOS */ + SW(s->data[0]); /* 1x4 SPRxDATA */ + SW(s->datb[0]); /* 1x6 SPRxDATB */ } } for (i = 0; i < 32; i++) { @@ -10866,45 +10802,45 @@ uae_u8 *save_custom (int *len, uae_u8 *dstptr, int full) v2 = (v >> 4) & 15; v2 |= ((v >> 12) & 15) << 4; v2 |= ((v >> 20) & 15) << 8; - SW (v2); + SW(v2); } else { uae_u16 v = current_colors.color_regs_ecs[i]; if (color_regs_genlock[i]) v |= 0x8000; - SW (v); /* 180-1BE COLORxx */ - } - } - SW (htotal); /* 1C0 HTOTAL */ - SW (hsstop); /* 1C2 HSTOP*/ - SW (hbstrt); /* 1C4 HBSTRT */ - SW (hbstop); /* 1C6 HBSTOP */ - SW (vtotal); /* 1C8 VTOTAL */ - SW (vsstop); /* 1CA VSSTOP */ - SW (vbstrt); /* 1CC VBSTRT */ - SW (vbstop); /* 1CE VBSTOP */ - SW (sprhstrt); /* 1D0 SPRHSTRT */ - SW (sprhstop); /* 1D2 SPRHSTOP */ - SW (bplhstrt); /* 1D4 BPLHSTRT */ - SW (bplhstop); /* 1D6 BPLHSTOP */ - SW (hhpos); /* 1D8 HHPOSW */ - SW (0); /* 1DA */ - SW (beamcon0); /* 1DC BEAMCON0 */ - SW (hsstrt); /* 1DE HSSTRT */ - SW (vsstrt); /* 1E0 VSSTRT */ - SW (hcenter); /* 1E2 HCENTER */ - SW (diwhigh | (diwhigh_written ? 0x8000 : 0) | (hdiwstate == DIW_waiting_stop ? 0x4000 : 0)); /* 1E4 DIWHIGH */ - SW (0); /* 1E6 */ - SW (0); /* 1E8 */ - SW (0); /* 1EA */ - SW (0); /* 1EC */ - SW (0); /* 1EE */ - SW (0); /* 1F0 */ - SW (0); /* 1F2 */ - SW (0); /* 1F4 */ - SW (0); /* 1F6 */ - SW (0); /* 1F8 */ - SW (0x8000 | (currprefs.ntscmode ? 1 : 0)); /* 1FA (re-used for NTSC) */ - SW (fmode); /* 1FC FMODE */ + SW(v); /* 180-1BE COLORxx */ + } + } + SW(htotal); /* 1C0 HTOTAL */ + SW(hsstop); /* 1C2 HSTOP*/ + SW(hbstrt); /* 1C4 HBSTRT */ + SW(hbstop); /* 1C6 HBSTOP */ + SW(vtotal); /* 1C8 VTOTAL */ + SW(vsstop); /* 1CA VSSTOP */ + SW(vbstrt); /* 1CC VBSTRT */ + SW(vbstop); /* 1CE VBSTOP */ + SW(sprhstrt); /* 1D0 SPRHSTRT */ + SW(sprhstop); /* 1D2 SPRHSTOP */ + SW(bplhstrt); /* 1D4 BPLHSTRT */ + SW(bplhstop); /* 1D6 BPLHSTOP */ + SW(hhpos); /* 1D8 HHPOSW */ + SW(0); /* 1DA */ + SW(beamcon0); /* 1DC BEAMCON0 */ + SW(hsstrt); /* 1DE HSSTRT */ + SW(vsstrt); /* 1E0 VSSTRT */ + SW(hcenter); /* 1E2 HCENTER */ + SW(diwhigh | (diwhigh_written ? 0x8000 : 0) | (hdiwstate == DIW_waiting_stop ? 0x4000 : 0)); /* 1E4 DIWHIGH */ + SW(0); /* 1E6 */ + SW(0); /* 1E8 */ + SW(0); /* 1EA */ + SW(0); /* 1EC */ + SW(0); /* 1EE */ + SW(0); /* 1F0 */ + SW(0); /* 1F2 */ + SW(0); /* 1F4 */ + SW(0); /* 1F6 */ + SW(0); /* 1F8 */ + SW(0x8000 | (currprefs.ntscmode ? 1 : 0)); /* 1FA (re-used for NTSC) */ + SW(fmode); /* 1FC FMODE */ SW (last_custom_value1); /* 1FE */ *len = dst - dstbak;