int hsynctotal;
static int maxvpos_total = 511;
int minfirstline = VBLANK_ENDLINE_PAL;
-int firstblankedline;
+static int firstblankedline;
static int equ_vblank_endline = EQU_ENDLINE_PAL;
static bool equ_vblank_toggle = true;
float vblank_hz = VBLANK_HZ_PAL, fake_vblank_hz, vblank_hz_stored, vblank_hz_nom;
static enum diw_states diwstate, hdiwstate;
static int diwstate_vpos;
static int bpl_hstart;
-static bool exthblank;
+static bool exthblank, exthblank_state;
int first_planes_vpos, last_planes_vpos;
static int first_bplcon0, first_bplcon0_old;
static int hack_delay_shift;
static bool bplcon1_written;
static bool bplcon0_planes_changed;
-static bool sprites_enabled_this_line;
+static bool sprites_enabled_this_line, sprites_enabled_prev_line;
static int shifter_mask, toscr_delay_shifter[2];
static int out_subpix[2];
static bool speedup_first;
next_color_change++;
cc[1].regno = -1;
hblank_reset(hbstrt_v2);
+ exthblank_state = true;
}
if (chpos >= hbstop_v2 && prevpos < hbstop_v2) {
cc = &curr_color_changes[next_color_change];
cc->value = 0;
next_color_change++;
cc[1].regno = -1;
+ exthblank_state = false;
}
} else {
if (chpos >= hbstop_v2 && prevpos < hbstop_v2) {
cc->value = 0;
next_color_change++;
cc[1].regno = -1;
+ exthblank_state = false;
}
if (chpos >= hbstrt_v2 && prevpos < hbstrt_v2) {
cc = &curr_color_changes[next_color_change];
next_color_change++;
cc[1].regno = -1;
hblank_reset(hbstrt_v2);
+ exthblank_state = true;
}
}
}
} else {
#if OPTIMIZED_ESTIMATE
- if (estimated_bplcon0 == bplcon0 && estimated_plfstrt == plfstrt && estimated_plfstop == plfstop && estimated_fm == fetchmode) {
+ if (estimated_bplcon0 == bplcon0 && plfstrt == hpos && estimated_plfstrt == plfstrt && estimated_plfstop == plfstop && estimated_fm == fetchmode) {
estimated_cycles = estimated_cycles_buf;
return;
}
#endif
-
+#if 0
+ // plfstrt=24 plfstop=32 bpl_hstart=56 hard_ddf_stop=216 ddf_stopping=0 fetch_cycle=136 fetchunit=8 lastfetchunit=8
+ bpl_hstart = 56;
+ plfstrt = 24;
+ plfstop = 32;
+ bplcon0_res = 0;
+ fetchmode = 0;
+ fetch_cycle = 136;
+ ddf_stopping = 0;
+ hpos = 0;
+ curr_diagram = cycle_diagram_table[fetchmode][bplcon0_res][8];
+#endif
int hard_ddf_stop = harddis_h ? 0x100 : HARD_DDF_STOP;
int start = bpl_hstart;
int adjusted_plfstop = plfstop;
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;
+ if (start > stop) {
+ // weird case handling
+ if (stop < fetch_cycle) {
+ stop = hard_ddf_stop;
+ }
+ int starting_last_block_at = (stop + fetchunit - 1) & ~(fetchunit - 1);
+ estimated_cycle_count = (starting_last_block_at - fetch_cycle) + lastfetchunit;
+ if (estimated_cycle_count < 0) {
+ estimated_cycle_count += maxhpos;
+ }
+ } else {
+ 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);
int start_pos = (hpos + RGA_PIPELINE_ADJUST) % maxhpos;
int start_pos2 = start_pos;
int end_pos = (hpos + RGA_PIPELINE_ADJUST + estimated_cycle_count) % maxhpos;
- int ce_offset = (start_pos - (bpl_hstart + RGA_PIPELINE_ADJUST)) & (fetchunit - 1);
- int off = ce_offset;
+ int off = (start_pos - (bpl_hstart + RGA_PIPELINE_ADJUST)) & (fetchunit - 1);
while (start_pos != end_pos) {
int off2 = off & fetchstart_mask;
+
+#if 0
+ if (start_pos < 0 || start_pos > maxhpos || fetchstart > 32 || end_pos < 0 || end_pos > maxhpos) {
+ gui_message(_T("ERROR: %d %d %d %d %d %d %d %d %d %d\n%d %d %d %d %d %d %d %d %04x %d\n"),
+ hpos, bpl_hstart, estimated_cycle_count, start_pos, start_pos2, end_pos, off, off2, fetchstart, maxhpos,
+ plfstrt, plfstop, hard_ddf_stop, ddf_stopping, fetch_cycle, fetchunit, lastfetchunit, vpos, bplcon0, fmode);
+ }
+#endif
+
if (!off2 && start_pos + fetchstart <= end_pos) {
- memcpy(&estimated_cycles[start_pos], curr_diagram, fetchstart);
+ memcpy(estimated_cycles + start_pos, curr_diagram, fetchstart);
start_pos += fetchstart;
} else {
estimated_cycles[start_pos] = curr_diagram[off2];
static void setextblank(void)
{
- bool extblank, extblankmode;
- if (aga_mode) {
- extblank = true;
- extblankmode = (bplcon0 & 1) && (bplcon3 & 0x01);
- } else {
- extblank = !ecs_denise || !(bplcon0 & 1) || ((bplcon0 & 1) && (bplcon3 & 0x01));
- extblankmode = false;
- }
+ bool extblank = (bplcon0 & 1) && (bplcon3 & 0x01);
current_colors.extra &= ~(1 << CE_EXTBLANKSET);
- current_colors.extra &= ~(1 << CE_EXTBLANKMODE);
if (extblank) {
current_colors.extra |= 1 << CE_EXTBLANKSET;
}
- if (extblankmode) {
- current_colors.extra |= 1 << CE_EXTBLANKMODE;
- }
}
static bool isbrdblank(int hpos, uae_u16 bplcon0, uae_u16 bplcon3)
{
- bool brdblank, brdntrans, extblank, extblankmode;
+ bool brdblank, brdntrans, extblank;
#ifdef ECS_DENISE
brdblank = ecs_denise && (bplcon0 & 1) && (bplcon3 & 0x20);
brdntrans = ecs_denise && (bplcon0 & 1) && (bplcon3 & 0x10);
// ECSENA=0: hardwired horizontal, strobe vertical
- // ECSENA=1: EXTBLKEN=0: ECS Denise: no blanking AGA: hardwired blanking, strobe vertical
- // ECSENA=1: EXTBLKEN=1: ECS Denise: hardwired horizontal, strobe vertical AGA: programmed horizontal, strobe vertical
- // extblank = blanking enabled
- // extblankmode = use hardwired or programmed blanking
- if (aga_mode) {
- extblank = true;
- extblankmode = (bplcon0 & 1) && (bplcon3 & 1);
- } else {
- extblank = !ecs_denise || !(bplcon0 & 1) || ((bplcon0 & 1) && (bplcon3 & 1));
- extblankmode = false;
- }
+ // ECSENA=1: EXTBLKEN=0: hardwired blanking, strobe vertical
+ // ECSENA=1: EXTBLKEN=1: blanking equals HSYNC, no vertical, AGA: programmed horizontal, strobe vertical
+ extblank = (bplcon0 & 1) && (bplcon3 & 1);
#else
brdblank = false;
brdntrans = false;
- extblank = true;
- extblankmode = true;
+ extblank = false;
#endif
- if (hpos >= 0 && (ce_is_borderblank(current_colors.extra) != brdblank || ce_is_borderntrans(current_colors.extra) != brdntrans
- || ce_is_extblankset(current_colors.extra) != extblank || ce_is_extblankmode(current_colors.extra) != extblankmode)) {
- record_color_change(hpos, 0, COLOR_CHANGE_BRDBLANK | (brdblank ? 1 : 0) | (ce_is_bordersprite(current_colors.extra) ? 2 : 0) | (brdntrans ? 4 : 0) | (extblank ? 8 : 0) | (extblankmode ? 16 : 0));
+ if (hpos >= 0 && (ce_is_borderblank(current_colors.extra) != brdblank || ce_is_borderntrans(current_colors.extra) != brdntrans || ce_is_extblankset(current_colors.extra) != extblank)) {
+ record_color_change(hpos, 0, COLOR_CHANGE_BRDBLANK | (brdblank ? 1 : 0) | (ce_is_bordersprite(current_colors.extra) ? 2 : 0) | (brdntrans ? 4 : 0) | (extblank ? 8 : 0));
current_colors.extra &= ~(1 << CE_BORDERBLANK);
current_colors.extra &= ~(1 << CE_BORDERNTRANS);
current_colors.extra &= ~(1 << CE_EXTBLANKSET);
- current_colors.extra &= ~(1 << CE_EXTBLANKMODE);
current_colors.extra |= brdblank ? (1 << CE_BORDERBLANK) : 0;
current_colors.extra |= brdntrans ? (1 << CE_BORDERNTRANS) : 0;
current_colors.extra |= extblank ? (1 << CE_EXTBLANKSET) : 0;
- current_colors.extra |= extblankmode ? (1 << CE_EXTBLANKMODE) : 0;
remembered_color_entry = -1;
}
return brdblank;
#endif
if (hpos >= 0 && ce_is_bordersprite(current_colors.extra) != brdsprt) {
record_color_change(hpos, 0, COLOR_CHANGE_BRDBLANK | (ce_is_borderblank(current_colors.extra) ? 1 : 0) | (brdsprt ? 2 : 0) |
- (ce_is_borderntrans(current_colors.extra) ? 4 : 0) | (ce_is_extblankset(current_colors.extra) ? 8 : 0) | (ce_is_extblankmode(current_colors.extra) ? 16 : 0));
+ (ce_is_borderntrans(current_colors.extra) ? 4 : 0) | (ce_is_extblankset(current_colors.extra) ? 8 : 0));
current_colors.extra &= ~(1 << CE_BORDERSPRITE);
current_colors.extra |= brdsprt ? (1 << CE_BORDERSPRITE) : 0;
remembered_color_entry = -1;
* there's a more-or-less full-screen DIW. */
if (hdiwstate == DIW_waiting_stop && thisline_decision.diwfirstword >= 0) {
thisline_decision.diwlastword = max_diwlastword;
+ thisline_decision.diwfull = true;
}
last_diwlastword = -1;
if (thisline_decision.diwlastword != line_decisions[next_lineno].diwlastword) {
MARK_LINE_CHANGED;
}
+ if (thisline_decision.diwfull != line_decisions[next_lineno].diwfull) {
+ MARK_LINE_CHANGED;
+ }
dip = curr_drawinfo + next_lineno;
dip_old = prev_drawinfo + next_lineno;
thisline_decision.diwfirstword = -2;
thisline_decision.diwlastword = -2;
+ thisline_decision.diwfull = false;
if (hdiwstate == DIW_waiting_stop) {
thisline_decision.diwfirstword = -1;
if (thisline_decision.diwfirstword != line_decisions[next_lineno].diwfirstword) {
}
exthblank = (bplcon0 & 1) && (bplcon3 & 1);
} else {
- if (new_beamcon0 & new_beamcon0 & 0x0010) { // VARCSYEN
+ if (new_beamcon0 & 0x0010) { // VARCSYEN
// ECS HBLANK uses CSYNC input and matches HSSYNC period.
hbstrt_v2 = (hsstrt & 0xff) << CCK_SHRES_SHIFT;
hbstop_v2 = (hsstop & 0xff) << CCK_SHRES_SHIFT;
- exthblank = (bplcon0 & 1) && !(bplcon3 & 1);
+ exthblank = (bplcon0 & 1) && (bplcon3 & 1);
} else {
exthblank = false;
}
}
}
- if (maxvpos_display_vsync < 1) {
- maxvpos_display_vsync = 1;
+ if (maxvpos_display_vsync < 0) {
+ maxvpos_display_vsync = 0;
}
if (minfirstline < 1) {
return;
}
#endif
+ thisline_changed = 1;
updateextblk();
if (!resync) {
return;
{
decide_line(hpos);
decide_fetch_safe(hpos);
- if (copper_access && get_bitplane_dma_rel(hpos, 1) == num + 1) {
- SET_LINE_CYCLEBASED;
- return;
+ if (copper_access) {
+ int n = get_bitplane_dma_rel(hpos, 1);
+ if (n == num + 1) {
+ SET_LINE_CYCLEBASED;
+ return;
+ }
}
bplpt[num] = (bplpt[num] & 0x0000ffff) | ((uae_u32)v << 16);
decide_line(hpos);
decide_fetch_safe(hpos);
/* only detect copper accesses to prevent too fast CPU mode glitches */
- if (copper_access && get_bitplane_dma_rel(hpos, 1) == num + 1) {
- SET_LINE_CYCLEBASED;
- return;
+ if (copper_access) {
+ int n = get_bitplane_dma_rel(hpos, 1);
+ if (n == num + 1) {
+ SET_LINE_CYCLEBASED;
+ return;
+ }
}
bplpt[num] = (bplpt[num] & 0xffff0000) | (v & 0x0000fffe);
bplptx[num] = (bplptx[num] & 0xffff0000) | (v & 0x0000fffe);
static void BPLCON0(int hpos, uae_u16 v);
static void bplcon0_denise_change(int hpos, uae_u16 con0)
{
- // CHECKME!
- if (bprun_cycle == 1 && !aga_mode) {
- BPLCON0(hpos, con0);
- }
int np = GET_PLANES(con0);
if (np == toscr_nr_planes_shifter_new) {
toscr_nr_planes_shifter = np;
if (bprun && !ddf_stopping) {
decide_line_decision_fetches(hpos);
ddf_stopping = 1;
+#ifdef DEBUGGER
+ if (debug_dma) {
+ record_dma_event(DMA_EVENT_DDFSTOP2, hpos, vpos);
+ }
+#endif
}
}
if (!harddis_h) {
decide_line_decision_fetches(hpos);
ddf_stopping = 1;
+#ifdef DEBUGGER
+ if (debug_dma) {
+ record_dma_event(DMA_EVENT_DDFSTOP2, hpos, vpos);
+ }
+#endif
}
}
}
if (bprun && !ddf_stopping) {
decide_line_decision_fetches(hpos);
ddf_stopping = 1;
+#ifdef DEBUGGER
+ if (debug_dma) {
+ record_dma_event(DMA_EVENT_DDFSTOP, hpos, vpos);
+ }
+#endif
}
if (plfstop != plfstrt) {
if (ddf_enable_on) {
if (ddf_stopping) {
bprun_pipeline_flush_delay = maxhpos;
}
+#ifdef DEBUGGER
+ if (debug_dma) {
+ record_dma_event(DMA_EVENT_DDFSTRT, hpos, vpos);
+ }
+#endif
}
hwi_old = hwi;
if (bprun && !ddf_stopping) {
decide_line_decision_fetches(hpos);
ddf_stopping = 1;
+#ifdef DEBUGGER
+ if (debug_dma) {
+ record_dma_event(DMA_EVENT_DDFSTOP, hpos, vpos);
+ }
+#endif
}
}
if (bprun && !ddf_stopping) {
decide_line_decision_fetches(hpos);
ddf_stopping = 1;
+#ifdef DEBUGGER
+ if (debug_dma) {
+ record_dma_event(DMA_EVENT_DDFSTOP2, hpos, vpos);
+ }
+#endif
}
}
if (ddf_stopping) {
bprun_pipeline_flush_delay = maxhpos;
}
+#ifdef DEBUGGER
+ if (debug_dma) {
+ record_dma_event(DMA_EVENT_DDFSTRT, hpos, vpos);
+ }
+#endif
}
// DMA or DIW off: clear BPRUN
cop_state.wakecond = true;
}
-
+ if ((hpos == maxhpos - 1) && !(hpos & 1)) {
+ goto next;
+ }
if (copper_cant_read(hpos, 0)) {
goto next;
}
if (!s->dmacycle && s->dmastate) {
s->dmacycle = 1;
}
- if (vpos == s->vstart && !vb_end_line) {
+ if (vpos == s->vstart && !vb_end_line && !vb_end_next_line) {
s->dmastate = 1;
s->dmacycle = 1;
if (num == 0 && slot == 0) {
cursorsprite();
}
}
- if (vpos == s->vstop || vb_end_line) {
+ if (vpos == s->vstop || vb_end_next_line) {
s->dmastate = 0;
s->dmacycle = 1;
}
toscr_nbits = 0;
update_denise_vars();
estimated_fm = 0xffff;
+ exthblank = false;
+ exthblank_state = false;
if (!savestate_state) {
cia_hsync = 0;
static int bplmode, bplehb, bplham, bpldualpf, bpldualpfpri;
static int bpldualpf2of, bplplanecnt, ecsshres;
static int bplbypass, bplcolorburst, bplcolorburst_field;
-static bool issprites;
static int bplres;
static int plf1pri, plf2pri, bplxor, bplxorsp, bpland, bpldelay_sh;
static uae_u32 plf_sprite_mask;
}
// horizontal blanking
- bool hardwired = !dp_for_drawing || !ce_is_extblankset(colors_for_drawing.extra) || !ce_is_extblankmode(colors_for_drawing.extra);
+ bool hardwired = !dp_for_drawing || !ce_is_extblankset(colors_for_drawing.extra);
bool doblank = false;
int hbstrt = (235 << CCK_SHRES_SHIFT) - 3;
int hbstop = (47 << CCK_SHRES_SHIFT) - 7;
}
}
- hardwired = (new_beamcon0 & 0x1000) == 0;
+ if (aga_mode) {
+ hardwired = (new_beamcon0 & 0x1000) == 0;
+ }
if (hardwired) {
int vbstrt = vblank_firstline_hw;
int vbstop = vblank_lastline_hw;
/* How many pixels in window coordinates which are to the left of the left border. */
static int unpainted;
-STATIC_INLINE xcolnr getbgc(int blank)
+// blank = -1: force normal border color even if borderblank is active
+static xcolnr getbgc(int blank)
{
#if BG_COLOR_DEBUG
if (exthblank)
}
bool extblken = ce_is_extblankset(colors_for_drawing.extra);
// extblken=1: hblank and vblank = black
- if (!(vb_state & 1) && extblken) {
+ if (!(vb_state & 1) && extblken && aga_mode) {
return 0;
}
bool brdblank = ce_is_borderblank(colors_for_drawing.extra);
}
#endif
// borderblank = black (overrides extblken)
- if (brdblank) {
+ if (brdblank && blank >= 0) {
return 0;
}
- if (hposblank || blank) {
+ if (hposblank || blank > 0) {
return 0;
}
return colors_for_drawing.acolors[0];
int leftborderhidden;
int native_ddf_left2;
bool expanded = false;
- bool fulldiw = false;
hsync_shift_hack = 0;
linetoscr_diw_start = dp_for_drawing->diwfirstword;
linetoscr_diw_end = dp_for_drawing->diwlastword;
if (linetoscr_diw_start < 0) {
- if (linetoscr_diw_start == -1) {
- fulldiw = true;
- }
linetoscr_diw_start = 0;
}
real_playfield_end = playfield_end;
sprite_end = linetoscr_diw_end;
- set_blanking_limits();
-
// Sprite hpos don't include DIW_DDF_OFFSET and can appear 1 lores pixel
// before first bitplane pixel appears.
// This means "bordersprite" condition is possible under OCS/ECS too. Argh!
playfield_end_pre -= bplres;
}
// if DIW was not closed horizontally, borderblank leaves color0 stripe before bitplanes
- if (ce_is_borderblank(colors_for_drawing.extra) && fulldiw) {
+ if (ce_is_borderblank(colors_for_drawing.extra) && dp_for_drawing->diwfull) {
playfield_start_pre = playfield_start - 2 * 4;
}
if (!aga_mode)
bplehb = -1;
}
- issprites = dip_for_drawing->nr_sprites > 0;
bplcolorburst = (dp_for_drawing->bplcon0 & 0x200) != 0;
if (!bplcolorburst)
bplcolorburst_field = 0;
}
// vblank + extblanken: blanked
- if (!(vb_state & 1) && ce_is_extblankset(colors_for_drawing.extra) || vp < vblank_top_start || vp >= vblank_bottom_stop) {
+ if ((!(vb_state & 1) && ce_is_extblankset(colors_for_drawing.extra) && aga_mode) || vp < vblank_top_start || vp >= vblank_bottom_stop) {
if (nextpos_in_range > lastpos && lastpos < playfield_end) {
int t = nextpos_in_range <= playfield_end ? nextpos_in_range : playfield_end;
colors_for_drawing.extra &= ~(1 << CE_BORDERNTRANS);
colors_for_drawing.extra &= ~(1 << CE_BORDERSPRITE);
colors_for_drawing.extra &= ~(1 << CE_EXTBLANKSET);
- colors_for_drawing.extra &= ~(1 << CE_EXTBLANKMODE);
colors_for_drawing.extra |= (value & 1) != 0 ? (1 << CE_BORDERBLANK) : 0;
colors_for_drawing.extra |= (value & 3) == 2 ? (1 << CE_BORDERSPRITE) : 0;
colors_for_drawing.extra |= (value & 5) == 4 ? (1 << CE_BORDERNTRANS) : 0;
colors_for_drawing.extra |= (value & 8) == 8 ? (1 << CE_EXTBLANKSET) : 0;
- colors_for_drawing.extra |= (value & 16) == 16 ? (1 << CE_EXTBLANKMODE) : 0;
} else if (value & COLOR_CHANGE_SHRES_DELAY) {
colors_for_drawing.extra &= ~(1 << CE_SHRES_DELAY_SHIFT);
colors_for_drawing.extra &= ~(1 << (CE_SHRES_DELAY_SHIFT + 1));
if (border == 0) {
pfield_expand_dp_bplcon();
+ set_blanking_limits();
pfield_init_linetoscr(false);
pfield_doline(lineno);