void reset_frame_rate_hack (void)
{
- if (currprefs.m68k_speed >= 0)
+ if (currprefs.m68k_speed >= 0) {
return;
+ }
rpt_did_reset = 1;
events_reset_syncline();
- vsyncmintime = read_processor_time () + vsynctimebase;
- write_log (_T("Resetting frame rate hack\n"));
+ vsyncmintime = read_processor_time() + vsynctimebase;
+ write_log(_T("Resetting frame rate hack\n"));
}
static void setclr(uae_u16 *p, uae_u16 val)
*/
int hdiw = hpos >= maxhpos ? maxhpos * 2 + 1 : hpos * 2 + 2;
- if (!ecs_denise && vpos <= get_equ_vblank_endline())
+ if (!ecs_denise && vpos <= get_equ_vblank_endline()) {
hdiw = diw_hcounter;
+ }
/* always mask, bad programs may have set maxhpos = 256 */
hdiw &= 511;
for (;;) {
int lhdiw = hdiw;
- if (last_hdiw > lhdiw)
+ if (last_hdiw > lhdiw) {
lhdiw = 512;
+ }
if (lhdiw >= diw_hstrt && last_hdiw < diw_hstrt && hdiwstate == DIW_waiting_start) {
- if (thisline_decision.diwfirstword < 0)
+ if (thisline_decision.diwfirstword < 0) {
thisline_decision.diwfirstword = diwfirstword < 0 ? min_diwlastword : diwfirstword;
+ }
hdiwstate = DIW_waiting_stop;
}
if ((lhdiw >= diw_hstop && last_hdiw < diw_hstop) && hdiwstate == DIW_waiting_stop) {
- if (thisline_decision.diwlastword < 0)
+ if (thisline_decision.diwlastword < 0) {
thisline_decision.diwlastword = diwlastword < 0 ? 0 : diwlastword;
+ }
hdiwstate = DIW_waiting_start;
}
- if (lhdiw != 512)
+ if (lhdiw != 512) {
break;
+ }
last_hdiw = 0 - 1;
}
last_hdiw = hdiw;
#endif
}
+static void clear_bitplane_pipeline(int type)
+{
+ // clear bitplane allocations
+ int safepos = (hsyncstartpos_start >> CCK_SHRES_SHIFT) - 1;
+ int count = RGA_PIPELINE_ADJUST + 1;
+ if (type) {
+ for (int i = 0; i < maxhpos + RGA_PIPELINE_ADJUST; i++) {
+ if (i < safepos || i >= safepos + count) {
+ struct chipsetslot *cs = &cycle_line[i];
+ int v = cs->pipeline;
+ if (v > 0 && v < 0x20) {
+ cs->pipeline = 0;
+ }
+ }
+ }
+ } else {
+ for (int i = safepos; i < safepos + count; i++) {
+ struct chipsetslot *cs = &cycle_line[i];
+ int v = cs->pipeline;
+ if (v > 0 && v < 0x20) {
+ cs->pipeline = 0;
+ }
+ }
+ }
+}
+
+#define HARD_DDF_STOP 0xd8
+
+static uae_u8 estimated_cycles[256];
+#define ESTIMATED_FETCH_MODE 1
+
+#if ESTIMATED_FETCH_MODE
+
+static void end_estimate_last_fetch_cycle(int hpos)
+{
+ int start_pos = (hpos + RGA_PIPELINE_ADJUST) % maxhpos;
+ int end_pos = hpos;
+ while (start_pos != end_pos) {
+ estimated_cycles[start_pos] = 0;
+ start_pos++;
+ if (start_pos == maxhpos) {
+ start_pos = 0;
+ }
+ }
+}
+
+static void estimate_last_fetch_cycle(int hpos)
+{
+ int hard_ddf_stop = harddis ? 0x100 : HARD_DDF_STOP;
+ int start = bpl_hstart;
+ int adjusted_plfstop = plfstop;
+ int estimated_cycle_count;
+ int fetchunit = fetchunits[fetchmode * 4 + bplcon0_res];
+ // Last fetch is always max 8 even if fetchunit is larger.
+ int lastfetchunit = fetchunit >= 8 ? 8 : fetchunit;
+
+ if (!bprun) {
+
+ end_estimate_last_fetch_cycle(hpos);
+
+ } else {
+
+ if (!ddf_stopping) {
+ int stop;
+ if (ecs_agnus) {
+ // ECS: stop wins if start == stop
+ stop = adjusted_plfstop < hpos || adjusted_plfstop > hard_ddf_stop ? hard_ddf_stop : adjusted_plfstop;
+ } else {
+ // OCS: start wins if start == stop
+ stop = adjusted_plfstop <= hpos || adjusted_plfstop > hard_ddf_stop ? hard_ddf_stop : adjusted_plfstop;
+ }
+ /* We know that fetching is up-to-date up until hpos, so we can use fetch_cycle. */
+ int fetch_cycle_at_stop = fetch_cycle + (stop - start);
+ int starting_last_block_at = (fetch_cycle_at_stop + fetchunit - 1) & ~(fetchunit - 1);
+ estimated_cycle_count = (starting_last_block_at - fetch_cycle) + lastfetchunit;
+ } else {
+ int fc = fetch_cycle;
+ int starting_last_block_at = (fc + fetchunit - 1) & ~(fetchunit - 1);
+ if (ddf_stopping == 2) {
+ starting_last_block_at -= fetchunit;
+ }
+ estimated_cycle_count = (starting_last_block_at - fc) + lastfetchunit;
+ }
+
+ // bitplane DMA end can wrap around, even in non-overrun cases
+ int start_pos = (hpos + RGA_PIPELINE_ADJUST) % maxhpos;
+ int end_pos = (hpos + RGA_PIPELINE_ADJUST + estimated_cycle_count) % maxhpos;
+ int ce_offset = ((bpl_hstart + RGA_PIPELINE_ADJUST) - start_pos) & (fetchunit - 1);
+ int off = ce_offset;
+ while (start_pos != end_pos) {
+ int off2 = off & fetchstart_mask;
+ estimated_cycles[start_pos] = curr_diagram[off2];
+ start_pos++;
+ if (start_pos == maxhpos) {
+ start_pos = 0;
+ }
+ off++;
+ }
+ }
+}
+
+#else
+
struct bpl_estimate {
uae_u16 startend;
uae_u16 start_pos;
static struct bpl_estimate bpl_estimates[MAX_BPL_ESTIMATES];
static int bpl_estimate_index;
-#define HARD_DDF_STOP 0xd8
-
static void end_estimate_last_fetch_cycle(int hpos)
{
for (int i = 0; i < MAX_BPL_ESTIMATES; i++) {
}
}
-static void clear_bitplane_pipeline(int type)
-{
- // clear bitplane allocations
- int safepos = (hsyncstartpos_start >> CCK_SHRES_SHIFT) - 1;
- int count = RGA_PIPELINE_ADJUST + 1;
- if (type) {
- for (int i = 0; i < maxhpos + RGA_PIPELINE_ADJUST; i++) {
- if (i < safepos || i >= safepos + count) {
- struct chipsetslot *cs = &cycle_line[i];
- int v = cs->pipeline;
- if (v > 0 && v < 0x20) {
- cs->pipeline = 0;
- }
- }
- }
- } else {
- for (int i = safepos; i < safepos + count; i++) {
- struct chipsetslot *cs = &cycle_line[i];
- int v = cs->pipeline;
- if (v > 0 && v < 0x20) {
- cs->pipeline = 0;
- }
- }
- }
-}
-
static void estimate_last_fetch_cycle(int hpos)
{
int hard_ddf_stop = harddis ? 0x100 : HARD_DDF_STOP;
be->cycle_diagram = curr_diagram;
be->ce_offset = ((bpl_hstart + RGA_PIPELINE_ADJUST) - be->start_pos) & (fetchunit - 1);
}
+#endif
#define TOSCR_NBITS 16
STATIC_INLINE void clear_fetchbuffer(uae_u32 *ptr, int nwords)
{
- int i;
-
- if (! thisline_changed) {
- for (i = 0; i < nwords; i++) {
+ if (!thisline_changed) {
+ for (int i = 0; i < nwords; i++) {
if (ptr[i]) {
thisline_changed = 1;
break;
}
}
}
- memset (ptr, 0, nwords * 4);
+ memset(ptr, 0, nwords * 4);
}
static void update_toscr_planes(int fm)
if (toscr_nr_planes_agnus > thisline_decision.nr_planes) {
if (out_offs) {
for (int j = thisline_decision.nr_planes; j < toscr_nr_planes_agnus; j++) {
- clear_fetchbuffer ((uae_u32 *)(line_data[next_lineno] + 2 * MAX_WORDS_PER_LINE * j), out_offs);
+ clear_fetchbuffer((uae_u32 *)(line_data[next_lineno] + 2 * MAX_WORDS_PER_LINE * j), out_offs);
if (thisline_decision.plfleft >= 0) {
todisplay[j] = 0;
#ifdef AGA
- if (fm)
+ if (fm) {
todisplay_aga[j] = 0;
+ }
#endif
}
}
int add = fetchmode_bytes;
if (cycle_line[hpos].cycle == CYCLE_REFRESH) {
if (warned1 >= 0) {
- write_log (_T("WARNING: BPL fetch conflicts with strobe refresh slot, hpos %02X!\n"), hpos);
+ write_log(_T("WARNING: BPL fetch conflicts with strobe refresh slot, hpos %02X!\n"), hpos);
warned1--;
}
add = refptr_val;
} else {
if (warned2 >= 0) {
warned2--;
- write_log (_T("WARNING: BPL fetch at hpos %02X!\n"), hpos);
+ write_log(_T("WARNING: BPL fetch at hpos %02X!\n"), hpos);
}
add = refptr_val;
}
static bool fetch(int nr, int fm, int hpos, bool addmodulo)
{
- if (1) {
- int add = fetchmode_bytes;
+ int add = fetchmode_bytes;
- // refresh conflict?
- if (cycle_line[hpos].cycle == CYCLE_REFRESH) {
- add = fetch_warn(nr, hpos);
- } else {
- cycle_line[hpos].cycle = CYCLE_BITPLANE;
- }
+ // refresh conflict?
+ if (cycle_line[hpos].cycle == CYCLE_REFRESH) {
+ add = fetch_warn(nr, hpos);
+ } else {
+ cycle_line[hpos].cycle = CYCLE_BITPLANE;
+ }
- uaecptr p = bplpt[nr];
+ uaecptr p = bplpt[nr];
- bplpt[nr] += add;
- bplptx[nr] += add;
- if (addmodulo) {
- add_modulo(hpos, nr);
- }
+ bplpt[nr] += add;
+ bplptx[nr] += add;
+ if (addmodulo) {
+ add_modulo(hpos, nr);
+ }
#ifdef DEBUGGER
- if (debug_dma) {
- record_dma_read(0x110 + nr * 2, p, hpos, vpos, DMARECORD_BITPLANE, nr);
- }
- if (memwatch_enabled) {
- debug_getpeekdma_chipram(p, MW_MASK_BPL_0 << nr, 0x110 + nr * 2, 0xe0 + nr * 4);
- }
- uae_u32 v = aga_mode ? chipmem_lget_indirect(p & ~3) : chipmem_wget_indirect(p);
- if (debug_dma) {
- record_dma_read_value(v);
- }
- if (memwatch_enabled) {
- debug_getpeekdma_value(v);
- }
+ if (debug_dma) {
+ record_dma_read(0x110 + nr * 2, p, hpos, vpos, DMARECORD_BITPLANE, nr);
+ }
+ if (memwatch_enabled) {
+ debug_getpeekdma_chipram(p, MW_MASK_BPL_0 << nr, 0x110 + nr * 2, 0xe0 + nr * 4);
+ }
+ uae_u32 v = aga_mode ? chipmem_lget_indirect(p & ~3) : chipmem_wget_indirect(p);
+ if (debug_dma) {
+ record_dma_read_value(v);
+ }
+ if (memwatch_enabled) {
+ debug_getpeekdma_value(v);
+ }
#endif
- switch (fm)
- {
- case 0:
- {
- uae_u16 v;
- if (aga_mode) {
- // AGA always does 32-bit fetches, this is needed
- // to emulate 64 pixel wide sprite side-effects.
- uae_u32 vv = chipmem_lget_indirect(p & ~3);
- if (p & 2) {
- v = (uae_u16)vv;
- fetched_aga_spr[nr] = (v << 16) | v;
- } else {
- v = vv >> 16;
- fetched_aga_spr[nr] = vv;
- }
+ switch (fm)
+ {
+ case 0:
+ {
+ uae_u16 v;
+ if (aga_mode) {
+ // AGA always does 32-bit fetches, this is needed
+ // to emulate 64 pixel wide sprite side-effects.
+ uae_u32 vv = chipmem_lget_indirect(p & ~3);
+ if (p & 2) {
+ v = (uae_u16)vv;
+ fetched_aga_spr[nr] = (v << 16) | v;
} else {
- v = chipmem_wget_indirect(p);
+ v = vv >> 16;
+ fetched_aga_spr[nr] = vv;
}
- fetched_aga[nr] = fetched[nr] = v;
- last_custom_value1 = v;
- last_custom_value2 = (uae_u16)last_custom_value1;
- break;
+ } else {
+ v = chipmem_wget_indirect(p);
}
+ fetched_aga[nr] = fetched[nr] = v;
+ last_custom_value1 = v;
+ last_custom_value2 = (uae_u16)last_custom_value1;
+ break;
+ }
#ifdef AGA
- case 1:
- {
- uaecptr pm = p & ~3;
- if (p & 2) {
- fetched_aga[nr] = chipmem_lget_indirect(pm) & 0x0000ffff;
- fetched_aga[nr] |= fetched_aga[nr] << 16;
- } else if (fetchmode_fmode_bpl & 2) { // optimized (fetchmode_fmode & 3) == 2
- fetched_aga[nr] = chipmem_lget_indirect(pm) & 0xffff0000;
- fetched_aga[nr] |= fetched_aga[nr] >> 16;
- } else {
- fetched_aga[nr] = chipmem_lget_indirect(pm);
- }
- last_custom_value1 = (uae_u32)fetched_aga[nr];
- last_custom_value2 = (uae_u16)last_custom_value1;
- fetched[nr] = (uae_u16)fetched_aga[nr];
- break;
+ case 1:
+ {
+ uaecptr pm = p & ~3;
+ if (p & 2) {
+ fetched_aga[nr] = chipmem_lget_indirect(pm) & 0x0000ffff;
+ fetched_aga[nr] |= fetched_aga[nr] << 16;
+ } else if (fetchmode_fmode_bpl & 2) { // optimized (fetchmode_fmode & 3) == 2
+ fetched_aga[nr] = chipmem_lget_indirect(pm) & 0xffff0000;
+ fetched_aga[nr] |= fetched_aga[nr] >> 16;
+ } else {
+ fetched_aga[nr] = chipmem_lget_indirect(pm);
}
- case 2:
- {
- uaecptr pm = p & ~7;
- uaecptr pm1, pm2;
- if (p & 4) {
- pm1 = pm + 4;
- pm2 = pm + 4;
- } else {
- pm1 = pm;
- pm2 = pm + 4;
- }
- if (p & 2) {
- uae_u32 v1 = chipmem_lget_indirect(pm1) & 0x0000ffff;
- uae_u32 v2 = chipmem_lget_indirect(pm2) & 0x0000ffff;
- v1 |= v1 << 16;
- v2 |= v2 << 16;
- fetched_aga[nr] = (((uae_u64)v1) << 32) | v2;
- } else {
- fetched_aga[nr] = ((uae_u64)chipmem_lget_indirect(pm1)) << 32;
- fetched_aga[nr] |= chipmem_lget_indirect(pm2);
- }
- last_custom_value1 = (uae_u32)fetched_aga[nr];
- last_custom_value2 = (uae_u16)last_custom_value1;
- fetched[nr] = (uae_u16)fetched_aga[nr];
- break;
+ last_custom_value1 = (uae_u32)fetched_aga[nr];
+ last_custom_value2 = (uae_u16)last_custom_value1;
+ fetched[nr] = (uae_u16)fetched_aga[nr];
+ break;
+ }
+ case 2:
+ {
+ uaecptr pm = p & ~7;
+ uaecptr pm1, pm2;
+ if (p & 4) {
+ pm1 = pm + 4;
+ pm2 = pm + 4;
+ } else {
+ pm1 = pm;
+ pm2 = pm + 4;
}
-#endif
+ if (p & 2) {
+ uae_u32 v1 = chipmem_lget_indirect(pm1) & 0x0000ffff;
+ uae_u32 v2 = chipmem_lget_indirect(pm2) & 0x0000ffff;
+ v1 |= v1 << 16;
+ v2 |= v2 << 16;
+ fetched_aga[nr] = (((uae_u64)v1) << 32) | v2;
+ } else {
+ fetched_aga[nr] = ((uae_u64)chipmem_lget_indirect(pm1)) << 32;
+ fetched_aga[nr] |= chipmem_lget_indirect(pm2);
}
- return nr == 0;
+ last_custom_value1 = (uae_u32)fetched_aga[nr];
+ last_custom_value2 = (uae_u16)last_custom_value1;
+ fetched[nr] = (uae_u16)fetched_aga[nr];
+ break;
}
- return false;
+#endif
+ }
+ return nr == 0;
}
STATIC_INLINE void toscr_3_ecs(int oddeven, int step, int nbits)
thisline_changed = 1;
*dataptr32 = outword[i];
}
+ *dataptr32 = outword[i];
dataptr += MAX_WORDS_PER_LINE * 2;
}
out_offs++;
return;
}
- thisline_decision.plfright = hpos + hpos_hsync_extra;
-
flush_display(fetchmode);
// This is really the end of scanline, we can finally flush all remaining data.
thisline_decision.plfright += flush_plane_data(fetchmode);
+
// This can overflow if display setup is really bad.
if (out_offs > MAX_PIXELS_PER_LINE / 32) {
out_offs = MAX_PIXELS_PER_LINE / 32;
hpos++;
}
last_fetch_hpos = hpos;
- flush_display(fm);
}
static void update_fetch_0(int hpos) { update_fetch(hpos, 0); }
return;
}
// collision bit already set?
- if (clxdat & 1)
+ if (clxdat & 1) {
return;
+ }
collided = 0;
minpos = thisline_decision.plfleft * 2 - DDF_OFFSET;
- if (minpos < hw_diwfirst)
+ if (minpos < hw_diwfirst) {
minpos = hw_diwfirst;
+ }
maxpos = thisline_decision.plfright * 2- DDF_OFFSET;
- if (maxpos > hw_diwlast)
+ if (maxpos > hw_diwlast) {
maxpos = hw_diwlast;
+ }
for (i = minpos; i < maxpos && !collided; i+= 32) {
int offs = ((i << bplres) - ddf_left) >> 3;
int j;
}
}
- if (collided)
+ if (collided) {
clxdat |= 1;
+ }
}
/* Sprite-to-sprite collisions are taken care of in record_sprite. This one does
hwres_t hw_diwlast = coord_window_to_diw_x(thisline_decision.diwlastword);
hwres_t hw_diwfirst = coord_window_to_diw_x(thisline_decision.diwfirstword);
- if (clxcon_bpl_enable == 0 && !nr_sprites)
+ if (clxcon_bpl_enable == 0 && !nr_sprites) {
return;
+ }
// all sprite to bitplane collision bits already set?
- if ((clxdat & 0x1fe) == 0x1fe)
+ if ((clxdat & 0x1fe) == 0x1fe) {
return;
+ }
for (int i = 0; i < nr_sprites; i++) {
struct sprite_entry *e = curr_sprite_entries + first + i;
hwres_t minp1 = minpos >> sprite_buffer_res;
hwres_t maxp1 = maxpos >> sprite_buffer_res;
- if (maxp1 > hw_diwlast)
+ if (maxp1 > hw_diwlast) {
maxpos = hw_diwlast << sprite_buffer_res;
- if (maxp1 > thisline_decision.plfright * 2 - DDF_OFFSET)
+ }
+ if (maxp1 > thisline_decision.plfright * 2 - DDF_OFFSET) {
maxpos = (thisline_decision.plfright * 2 - DDF_OFFSET) << sprite_buffer_res;
- if (minp1 < hw_diwfirst)
+ }
+ if (minp1 < hw_diwfirst) {
minpos = hw_diwfirst << sprite_buffer_res;
- if (minp1 < thisline_decision.plfleft * 2 - DDF_OFFSET)
+ }
+ if (minp1 < thisline_decision.plfleft * 2 - DDF_OFFSET) {
minpos = (thisline_decision.plfleft * 2 - DDF_OFFSET) << sprite_buffer_res;
+ }
for (sprbuf_res_t j = minpos; j < maxpos; j++) {
int sprpix = spixels[e->first_pixel + j - e->pos] & collision_mask;
int offs, match = 1;
- if (sprpix == 0)
+ if (sprpix == 0) {
continue;
+ }
offs = ((j << bplres) >> sprite_buffer_res) - ddf_left;
sprpix = sprite_ab_merge[sprpix & 255] | (sprite_ab_merge[sprpix >> 8] << 2);
sprpix <<= 1;
// both odd and even collision bits already set?
- if (((clxdat & (sprpix << 0)) == (sprpix << 0)) && ((clxdat & (sprpix << 4)) == (sprpix << 4)))
+ if (((clxdat & (sprpix << 0)) == (sprpix << 0)) && ((clxdat & (sprpix << 4)) == (sprpix << 4))) {
continue;
+ }
/* Loop over number of playfields. */
for (int k = 1; k >= 0; k--) {
#else
int planes = 6;
#endif
- if (bplcon0 & 0x400)
+ if (bplcon0 & 0x400) {
match = 1;
+ }
for (int l = k; match && l < planes; l += 2) {
int t = 0;
if (l < thisline_decision.nr_planes) {
#endif
}
if (clxcon_bpl_enable & (1 << l)) {
- if (t != ((clxcon_bpl_match >> l) & 1))
+ if (t != ((clxcon_bpl_match >> l) & 1)) {
match = 0;
+ }
}
}
if (match) {
return 0;
}
-static int color_changes_differ(struct draw_info *dip, struct draw_info *dip_old)
+static bool color_changes_differ(struct draw_info *dip, struct draw_info *dip_old)
{
if (dip->nr_color_changes != dip_old->nr_color_changes) {
- return 1;
+ return true;
}
if (dip->nr_color_changes == 0) {
- return 0;
+ return false;
}
if (memcmp(curr_color_changes + dip->first_color_change,
prev_color_changes + dip_old->first_color_change,
dip->nr_color_changes * sizeof * curr_color_changes) != 0) {
- return 1;
+ return true;
}
- return 0;
+ return false;
}
/* End of a horizontal scan line. Finish off all decisions that were not
static void finish_partial_decision(int hpos)
{
+ sync_copper(hpos);
decide_diw(hpos);
decide_line(hpos);
- sync_copper(hpos);
decide_fetch_safe(hpos);
decide_sprites(hpos);
+ if (thisline_decision.plfleft >= 0) {
+ thisline_decision.plfright = hpos + hpos_hsync_extra;
+ }
}
static void finish_decisions(int hpos)
dip_old = prev_drawinfo + next_lineno;
dp = line_decisions + next_lineno;
changed = thisline_changed | ad->custom_frame_redraw_necessary;
- if (thisline_decision.plfleft >= 0 && thisline_decision.nr_planes > 0)
+ if (thisline_decision.plfleft >= 0 && thisline_decision.nr_planes > 0) {
record_diw_line(thisline_decision.plfleft, diwfirstword, diwlastword);
+ }
dip->last_sprite_entry = next_sprite_entry;
dip->last_color_change = next_color_change;
if (thisline_decision.ctable < 0) {
- if (thisline_decision.plfleft < 0)
+ if (thisline_decision.plfleft < 0) {
remember_ctable_for_border();
- else
+ } else {
remember_ctable();
+ }
}
dip->nr_color_changes = next_color_change - dip->first_color_change;
static void reset_decisions_hsync_start(void)
{
- if (nodraw())
+ if (nodraw()) {
return;
+ }
toscr_nr_planes = toscr_nr_planes2 = 0;
thisline_decision.bplres = output_res(bplcon0_res);
bpl2mod_hpos = -1;
plane0 = false;
- delay_cycles = 0;
delay_cycles_right_offset = 0;
compute_toscr_delay(bplcon1);
}
if (currprefs.produce_sound > 1) {
double clk = svpos * shpos * fake_vblank_hz;
- write_log (_T("SNDRATE %.1f*%.1f*%.6f=%.6f\n"), svpos, shpos, fake_vblank_hz, clk);
+ write_log(_T("SNDRATE %.1f*%.1f*%.6f=%.6f\n"), svpos, shpos, fake_vblank_hz, clk);
devices_update_sound(clk, syncadjust);
}
devices_update_sync(svpos, syncadjust);
#endif
}
+#if ESTIMATED_FETCH_MODE
+STATIC_INLINE bool bitplane_dma_access(int hpos, int offset)
+{
+ hpos += offset;
+ if (hpos >= maxhpos) {
+ hpos -= maxhpos;
+ }
+ if (estimated_cycles[hpos]) {
+ return true;
+ }
+ return false;
+}
+#else
STATIC_INLINE bool bitplane_dma_access(int hpos, int offset)
{
hpos += offset;
}
return false;
}
+#endif
bool blitter_cant_access(int hpos)
{
if (bprun && !ddf_stopping) {
decide_line_decision_fetches(hpos);
ddf_stopping = 1;
- estimate_last_fetch_cycle(hpos);
}
if (plfstop != plfstrt) {
if (ddf_enable_on) {
}
bpl_hstart = hpos;
fetch_cycle = 0;
- //clear_bitplane_pipeline();
estimate_last_fetch_cycle(hpos);
if (ddf_stopping) {
bprun_pipeline_flush_delay = -2;
}
bpl_hstart = hpos;
fetch_cycle = 0;
- //clear_bitplane_pipeline();
estimate_last_fetch_cycle(hpos);
if (ddf_stopping) {
bprun_pipeline_flush_delay = -2;
{
if (1 && (nocustom() || !copper_enabled_thisline)) {
last_copper_hpos = until_hpos;
- //decide_line_decision(until_hpos);
return;
}
goto next;
}
cop_state.state = COP_wait1;
+ if (cop_state.ir[0] == 0x1ddf)
+ write_log("1");
}
break;
{
if (cop_state.state != COP_bltwait)
return;
-
+#if 0
+ blitter_done_notify_wakeup(0);
+#else
// Blitline check is a hack!
// Copper emulation is not correct and new blitter emulation needs this workaround.
event2_newevent_xx(-1, (blitline ? 4 : 2) * CYCLE_UNIT, 0, blitter_done_notify_wakeup);
+#endif
}
void do_copper(void)
}
}
-static void cursorsprite (void)
+static void cursorsprite(void)
{
- if (!dmaen (DMA_SPRITE) || first_planes_vpos == 0)
+ if (!dmaen(DMA_SPRITE) || first_planes_vpos == 0) {
return;
+ }
sprite_0 = spr[0].pt;
sprite_0_height = spr[0].vstop - spr[0].vstart;
sprite_0_colors[0] = 0;
sprite_0_doubled = 0;
- if (sprres == 0)
+ if (sprres == 0) {
sprite_0_doubled = 1;
+ }
if (aga_mode) {
int sbasecol = ((bplcon4 >> 4) & 15) << 4;
sprite_0_colors[1] = current_colors.color_regs_aga[sbasecol + 1];
}
sprite_0_width = sprite_width;
if (currprefs.input_tablet && (currprefs.input_mouse_untrap & MOUSEUNTRAP_MAGIC)) {
- if (currprefs.input_magic_mouse_cursor == MAGICMOUSE_HOST_ONLY && mousehack_alive ())
+ if (currprefs.input_magic_mouse_cursor == MAGICMOUSE_HOST_ONLY && mousehack_alive()) {
magic_sprite_mask &= ~1;
- else
+ } else {
magic_sprite_mask |= 1;
+ }
}
}
md->mavg = 0;
}
-static int mavg (struct mavg_data *md, int newval, int size)
+static int mavg(struct mavg_data *md, int newval, int size)
{
if (md->size < size) {
md->values[md->size++] = newval;
md->values[md->offset] = newval;
md->mavg += newval;
md->offset++;
- if (md->offset >= size)
+ if (md->offset >= size) {
md->offset -= size;
+ }
}
return md->mavg / md->size;
}
#define MAVG_VSYNC_SIZE 128
extern int log_vsync, debug_vsync_min_delay, debug_vsync_forced_delay;
-static bool framewait (void)
+static bool framewait(void)
{
struct amigadisplay *ad = &adisplays[0];
frame_time_t curr_time;
curr_time = read_processor_time();
vsyncwaittime = vsyncmaxtime = curr_time + vsynctimebase;
- if (!frame_rendered && !ad->picasso_on)
+ if (!frame_rendered && !ad->picasso_on) {
frame_rendered = render_screen(0, 1, false);
+ }
start = read_processor_time();
t = 0;
- if ((int)start - (int)vsync_time >= 0 && (int)start - (int)vsync_time < vsynctimebase)
+ if ((int)start - (int)vsync_time >= 0 && (int)start - (int)vsync_time < vsynctimebase) {
t += (int)start - (int)vsync_time;
+ }
if (!frame_shown) {
show_screen(0, 1);
- if (currprefs.gfx_apmode[0].gfx_strobo)
+ if (currprefs.gfx_apmode[0].gfx_strobo) {
show_screen(0, 4);
+ }
}
maybe_process_pull_audio();
int legacy_avg = mavg(&ma_legacy, t, MAVG_VSYNC_SIZE);
- if (t > legacy_avg)
+ if (t > legacy_avg) {
legacy_avg = t;
+ }
t = legacy_avg;
- if (debug_vsync_min_delay && t < debug_vsync_min_delay * vsynctimebase / 100)
+ if (debug_vsync_min_delay && t < debug_vsync_min_delay * vsynctimebase / 100) {
t = debug_vsync_min_delay * vsynctimebase / 100;
- if (debug_vsync_forced_delay > 0)
+ }
+ if (debug_vsync_forced_delay > 0) {
t = debug_vsync_forced_delay * vsynctimebase / 100;
+ }
vsync_time = read_processor_time();
- if (t > vsynctimebase * 2 / 3)
+ if (t > vsynctimebase * 2 / 3) {
t = vsynctimebase * 2 / 3;
+ }
if (currprefs.m68k_speed < 0) {
vsynctimeperline = (vsynctimebase - t) / (maxvpos_display + 1);
vsynctimeperline = (vsynctimebase - t) / 3;
}
- if (vsynctimeperline < 1)
+ if (vsynctimeperline < 1) {
vsynctimeperline = 1;
+ }
if (0 || (log_vsync & 2)) {
write_log (_T("%06d %06d/%06d %03d%%\n"), t, vsynctimeperline, vsynctimebase, t * 100 / vsynctimebase);
} else if (vs < 0) {
- if (!vblank_hz_state)
+ if (!vblank_hz_state) {
return status != 0;
+ }
frame_shown = true;
status = 1;
// this delay can safely overshoot frame time by 1-2 ms, following code will compensate for it.
for (;;) {
curr_time = read_processor_time();
- if ((int)vsyncwaittime - (int)curr_time <= 0 || (int)vsyncwaittime - (int)curr_time > 2 * vsynctimebase)
+ if ((int)vsyncwaittime - (int)curr_time <= 0 || (int)vsyncwaittime - (int)curr_time > 2 * vsynctimebase) {
break;
+ }
rtg_vsynccheck ();
if (cpu_sleep_millis(1) < 0) {
curr_time = read_processor_time();
int max;
int adjust = 0;
- if ((int)curr_time - (int)vsyncwaittime > 0 && (int)curr_time - (int)vsyncwaittime < vstb / 2)
+ if ((int)curr_time - (int)vsyncwaittime > 0 && (int)curr_time - (int)vsyncwaittime < vstb / 2) {
adjust += curr_time - vsyncwaittime;
+ }
adjust += clockadjust;
max = (int)(vstb * (1000.0 + currprefs.m68k_speed_throttle) / 1000.0 - adjust);
vsyncwaittime = curr_time + vstb - adjust;
t += frameskipt_avg;
vsynctimeperline = (vstb - t) / 4;
- if (vsynctimeperline < 1)
+ if (vsynctimeperline < 1) {
vsynctimeperline = 1;
- else if (vsynctimeperline > vstb / 4)
+ } else if (vsynctimeperline > vstb / 4) {
vsynctimeperline = vstb / 4;
+ }
frame_shown = true;
last = now - lastframetime;
lastframetime = now;
- if (bogusframe || (int)last < 0)
+ if (bogusframe || (int)last < 0) {
return;
+ }
mavg(&fps_mavg, last / 10, FPSCOUNTER_MAVG_SIZE);
mavg(&idle_mavg, idletime / 10, FPSCOUNTER_MAVG_SIZE);
}
// vsync functions that are not hardware timing related
-static void vsync_handler_pre (void)
+static void vsync_handler_pre(void)
{
struct amigadisplay *ad = &adisplays[0];
reset_cpu_idle();
}
}
- if (regs.halted < 0)
+ if (regs.halted < 0) {
reset_cpu_idle();
+ }
cpu_last_stop_vpos = 0;
cpu_stopped_lines = 0;
#endif
- if (bogusframe > 0)
+ if (bogusframe > 0) {
bogusframe--;
+ }
config_check_vsync();
- if (timehack_alive > 0)
+ if (timehack_alive > 0) {
timehack_alive--;
+ }
#ifdef PICASSO96
- if (isvsync_rtg() >= 0)
+ if (isvsync_rtg() >= 0) {
rtg_vsync();
+ }
#endif
if (!vsync_rendered) {
frameskiptime += end - start;
}
- bool frameok = framewait ();
+ bool frameok = framewait();
if (!ad->picasso_on) {
if (!frame_rendered && vblank_hz_state) {
frame_shown = false;
frame_rendered = false;
- if (vblank_hz_mult > 0)
+ if (vblank_hz_mult > 0) {
vblank_hz_state ^= 1;
- else
+ } else {
vblank_hz_state = 1;
+ }
vsync_handle_check();
//checklacecount (bplcon0_interlace_seen || lof_lace);
}
// emulated hardware vsync
-static void vsync_handler_post (void)
+static void vsync_handler_post(void)
{
int monid = 0;
static frame_time_t prevtime;
}
if (lof_prev_lastline != lof_lastline) {
- if (lof_togglecnt_lace < LOF_TOGGLES_NEEDED)
+ if (lof_togglecnt_lace < LOF_TOGGLES_NEEDED) {
lof_togglecnt_lace++;
- if (lof_togglecnt_lace >= LOF_TOGGLES_NEEDED)
+ }
+ if (lof_togglecnt_lace >= LOF_TOGGLES_NEEDED) {
lof_togglecnt_nlace = 0;
+ }
} else {
// only 1-2 vblanks with bplcon0 lace bit set?
// lets check if lof has changed
// lof toggling? decide as interlace.
if (lof_changed_previous_field >= LOF_TOGGLES_NEEDED) {
lof_changed_previous_field = LOF_TOGGLES_NEEDED;
- if (lof_lace == false)
+ if (lof_lace == false) {
lof_lace = true;
- else
+ } else {
lof_changed = 0;
+ }
}
- if (bplcon0 & 4)
+ if (bplcon0 & 4) {
lof_changed = 0;
+ }
}
lof_changing = 0;
} else {
init_hz_normal();
} else if (vpos_count > 0 && abs (vpos_count - vpos_count_diff) > 1 && vposw_change < 4) {
init_hz_vposw();
- } else if (interlace_changed || changed_chipset_refresh () || lof_changed) {
- compute_framesync ();
+ } else if (interlace_changed || changed_chipset_refresh() || lof_changed) {
+ compute_framesync();
}
lof_changed = 0;
vsync_cycles = get_cycles();
}
-static void copper_check (int n)
+static void copper_check(int n)
{
if (cop_state.state == COP_wait) {
int vp = vpos & (((cop_state.ir[1] >> 8) & 0x7F) | 0x80);
if (vp < cop_state.vcmp) {
- if (copper_enabled_thisline)
- write_log (_T("COPPER BUG %d: vp=%d vpos=%d vcmp=%d thisline=%d\n"), n, vp, vpos, cop_state.vcmp, copper_enabled_thisline);
+ if (copper_enabled_thisline) {
+ write_log(_T("COPPER BUG %d: vp=%d vpos=%d vcmp=%d thisline=%d\n"), n, vp, vpos, cop_state.vcmp, copper_enabled_thisline);
+ }
}
}
}
uae_u16 odmacon = dmacon;
uaecptr bpltmp[8], bpltmpx[8];
- if (lof_store && vpos >= maxvpos_nom - 1)
+ if (lof_store && vpos >= maxvpos_nom - 1) {
return;
+ }
next_lineno++;
scandoubled_line = 1;
if (pb1 && pb2) {
diff = pb1 - pb2;
if (lof_store) {
- if (bplcon0 & 4)
+ if (bplcon0 & 4) {
bplpt[i] = pb1 - diff;
+ }
} else {
- if (bplcon0 & 4)
+ if (bplcon0 & 4) {
bplpt[i] = pb1;
- else
+ } else {
bplpt[i] = bplpt[i] - diff;
+ }
}
}
int regno = cs2->regno;
int hpos = cs2->linepos / 4;
struct color_change *cs1 = &curr_color_changes[next_color_change];
- memcpy (cs1, cs2, sizeof (struct color_change));
+ memcpy(cs1, cs2, sizeof (struct color_change));
next_color_change++;
}
curr_color_changes[next_color_change].regno = -1;
finish_decisions(maxhpos + current_hpos());
- hsync_record_line_state (next_lineno, nln_normal, thisline_changed);
+ hsync_record_line_state(next_lineno, nln_normal, thisline_changed);
scandoubled_line = 0;
dmacon = odmacon;
}
#endif
}
- uae_u16 dat = chipmem_wget_indirect (pt);
+ uae_u16 dat = chipmem_wget_indirect(pt);
if (dmal_ce) {
#ifdef DEBUGGER
if (debug_dma) {
#endif
}
last_custom_value1 = last_custom_value2 = dat;
- AUDxDAT (nr, dat, pt);
+ AUDxDAT(nr, dat, pt);
} else {
uae_u16 dat = 0;
int w = v & 1;
- uaecptr pt = disk_getpt ();
+ uaecptr pt = disk_getpt();
// disk_fifostatus() needed in >100% disk speed modes
if (w) {
// write to disk
}
#endif
}
- dat = chipmem_wget_indirect (pt);
+ dat = chipmem_wget_indirect(pt);
if (dmal_ce) {
#ifdef DEBUGGER
if (debug_dma) {
#endif
}
last_custom_value1 = last_custom_value2 = dat;
- DSKDAT (dat);
+ DSKDAT(dat);
}
} else {
// read from disk
- if (disk_fifostatus () >= 0) {
- dat = DSKDATR ();
+ if (disk_fifostatus() >= 0) {
+ dat = DSKDATR();
if (dmal_ce) {
#ifdef DEBUGGER
if (debug_dma) {
}
#endif
}
- chipmem_wput_indirect (pt, dat);
+ chipmem_wput_indirect(pt, dat);
}
}
}
int hpos = current_hpos();
if (!nocustom()) {
- check_sprite_collisions();
+
finish_decisions(hpos);
+
hsync_record_line_state(next_lineno, nextline_how, thisline_changed);
- if (doflickerfix() && interlace_seen > 0)
+ if (doflickerfix() && interlace_seen > 0) {
hsync_scandoubler();
+ }
+
notice_resolution_seen(GET_RES_AGNUS(bplcon0), interlace_seen != 0);
int lineno = vposh;
- if (lineno >= MAXVPOS)
+ if (lineno >= MAXVPOS) {
lineno %= MAXVPOS;
+ }
nextline_how = nln_normal;
if (doflickerfix() && interlace_seen > 0) {
lineno *= 2;
vposh++;
hpos_hsync_extra = 0;
+ estimate_last_fetch_cycle(hpos);
eventtab[ev_hsynch].evtime = get_cycles() + HSYNCTIME;
eventtab[ev_hsynch].oldcycles = get_cycles();
// make sure decisions are done to end of scanline
finish_partial_decision(maxhpos);
clear_bitplane_pipeline(0);
+ check_sprite_collisions();
/* reset light pen latch */
if (vpos == sprite_vblank_endline) {
hhpos &= 0xff;
}
-#ifdef CPUEMU_13
- if (currprefs.cpu_memory_cycle_exact || currprefs.blitter_cycle_exact) {
- int hp = REFRESH_FIRST_HPOS;
- for (int i = 0; i < 4; i++) {
- alloc_cycle(hp, i == 0 ? CYCLE_STROBE : CYCLE_REFRESH); /* strobe */
+ int hp = REFRESH_FIRST_HPOS;
+ for (int i = 0; i < 4; i++) {
+ alloc_cycle(hp, i == 0 ? CYCLE_STROBE : CYCLE_REFRESH); /* strobe */
#ifdef DEBUGGER
- if (debug_dma) {
- uae_u16 strobe = 0x3c;
- if (vpos < equ_vblank_endline)
- strobe = 0x38;
- else if (vpos < minfirstline)
- strobe = 0x3a;
- else if (vpos + 1 == maxvpos + lof_store)
- strobe = 0x38;
- else if (ecs_agnus && lol)
- strobe = 0x3e;
- record_dma_read(i == 0 ? strobe : 0x1fe, 0xffffffff, hp, vpos, DMARECORD_REFRESH, i);
- record_dma_read_value(0xffff);
+ if (debug_dma) {
+ uae_u16 strobe = 0x3c;
+ if (vpos < equ_vblank_endline) {
+ strobe = 0x38;
+ } else if (vpos < minfirstline) {
+ strobe = 0x3a;
+ } else if (vpos + 1 == maxvpos + lof_store) {
+ strobe = 0x38;
+ } else if (ecs_agnus && lol) {
+ strobe = 0x3e;
}
+ record_dma_read(i == 0 ? strobe : 0x1fe, 0xffffffff, hp, vpos, DMARECORD_REFRESH, i);
+ record_dma_read_value(0xffff);
+ }
#endif
- hp += 2;
- if (hp >= maxhpos)
- hp -= maxhpos;
+ hp += 2;
+ if (hp >= maxhpos) {
+ hp -= maxhpos;
}
}
-#endif
events_dmal_hsync ();
#if 0