static int line_cyclebased, diw_change;
static int bpl_shifter;
-#define SET_LINE_CYCLEBASED line_cyclebased = 1;
+static void SET_LINE_CYCLEBASED(int hpos);
/* The display and data fetch windows */
int start_pos2 = start_pos;
int end_pos = (hpos + RGA_PIPELINE_ADJUST + estimated_cycle_count) % maxhpos;
int off = (start_pos - (bpl_hstart + RGA_PIPELINE_ADJUST)) & (fetchunit - 1);
- while (start_pos != end_pos) {
+ while (start_pos != end_pos && end_pos >= 0) {
int off2 = off & fetchstart_mask;
#if 0
} else {
estimated_cycles[start_pos] = curr_diagram[off2];
start_pos++;
- if (start_pos == maxhpos) {
+ if (start_pos >= maxhpos) {
start_pos = 0;
}
if (start_pos == REFRESH_FIRST_HPOS) {
break;
}
if (GET_RES_AGNUS(con0) != GET_RES_DENISE(con0)) {
- SET_LINE_CYCLEBASED
+ SET_LINE_CYCLEBASED(hpos);
}
bplcon0_res = GET_RES_AGNUS(con0);
toscr_res_old = -1;
if (isocs7planes()) {
toscr_nr_planes_agnus = 6;
}
- SET_LINE_CYCLEBASED;
+ SET_LINE_CYCLEBASED(hpos);
}
static int REGPARAM2 custom_wput_1(int hpos, uaecptr addr, uae_u32 value, int noget);
hstrobe_conflict = true;
- SET_LINE_CYCLEBASED;
+ SET_LINE_CYCLEBASED(hpos);
}
// refresh only slot conflict
warned1--;
}
- SET_LINE_CYCLEBASED;
+ SET_LINE_CYCLEBASED(hpos);
#ifdef DEBUGGER
if (debug_dma) {
}
/* Take care of the vertical DIW. */
-static void decide_vline(void)
+static void decide_vline(int hpos)
{
bool forceoff = (vb_start_line == 1 && !harddis_v);
bool start = vpos == plffirstline && !forceoff;
event2_newevent_xx(-1, CYCLE_UNIT, 1, vdiw_change);
}
vdiwstate = diw_states::DIW_waiting_stop;
- SET_LINE_CYCLEBASED;
+ SET_LINE_CYCLEBASED(hpos);
} else if (end) {
if (vdiwstate != diw_states::DIW_waiting_start) {
event2_newevent_xx(-1, CYCLE_UNIT, 0, vdiw_change);
}
vdiwstate = diw_states::DIW_waiting_start;
- SET_LINE_CYCLEBASED;
+ SET_LINE_CYCLEBASED(hpos);
}
}
int hpos = current_hpos();
finish_partial_decision(hpos);
- SET_LINE_CYCLEBASED;
+ SET_LINE_CYCLEBASED(hpos);
uae_u16 datreg = cycle_line_pipe[hpos];
// not conflict?
if (!(datreg & CYCLE_PIPE_BITPLANE)) {
}
if (bprun != 0 || todisplay_fetched || plane0 || plane0p || toshift) {
normalstart = false;
- SET_LINE_CYCLEBASED;
+ SET_LINE_CYCLEBASED(hpos);
if (toscr_hend == 2) {
for (int i = 0; i < MAX_PLANES; i++) {
todisplay[i] = todisplay_saved[i];
hcenterblank_state = false;
hstrobe_hdiw_min = hsyncstartpos_start_cycles;
if (hstrobe_conflict) {
- SET_LINE_CYCLEBASED;
+ SET_LINE_CYCLEBASED(hpos);
}
}
diwlastword = min_diwlastword;
}
+ int hpos = current_hpos();
+
if (vstrt == vpos && vstop != vpos && vdiwstate == diw_states::DIW_waiting_start) {
// This may start BPL DMA immediately.
- SET_LINE_CYCLEBASED;
+ SET_LINE_CYCLEBASED(hpos);
}
plffirstline = vstrt;
diw_change = 2;
- decide_vline();
+ decide_vline(hpos);
}
/* display mode changed (lores, doubling etc..), recalculate everything */
return vp;
}
-static void VPOSW(uae_u16 v)
+static void VPOSW(int hpos, uae_u16 v)
{
int oldvpos = vpos;
int newvpos = vpos;
newvpos |= v << 8;
if (newvpos != oldvpos) {
+ decide_line(hpos);
+ decide_fetch_safe(hpos);
cia_adjust_eclock_phase((newvpos - oldvpos) * maxhpos);
vposw_change++;
-
- if (newvpos < oldvpos && oldvpos <= maxvpos) {
- newvpos = oldvpos;
- }
vpos = newvpos;
-
vb_check();
+ decide_vline(hpos);
+ SET_LINE_CYCLEBASED(hpos);
}
}
{
int oldvpos = vpos;
int newvpos = vpos;
- int hpos_org = -1;
+ int hpos_org = current_hpos();
+ bool enabled = false;
+
+ decide_line(hpos_org);
+ decide_fetch_safe(hpos_org);
#if 0
if (M68K_GETPC < 0xf00000 || 1)
#endif
if ((currprefs.m68k_speed >= 0 && !currprefs.cachesize) || copper_access) {
- hpos_org = current_hpos();
+ enabled = true;
int hpos = hpos_org;
int hnew = (v & 0xff);
int hnew_org = hnew;
}
}
- v >>= 8;
newvpos &= 0xff00;
- newvpos |= v;
+ newvpos |= v >> 8;
+ if (enabled && (hpos_org == 0 || hpos_org == 1)) {
+ newvpos++;
+ }
if (newvpos != oldvpos) {
vposw_change++;
#ifdef DEBUGGER
}
}
#endif
- }
- // don't allow backwards vpos (at least for now)
- // allow backwards if old vpos was out of range
- if (newvpos < oldvpos && oldvpos <= maxvpos) {
- newvpos = oldvpos;
- } else if (newvpos < minfirstline && oldvpos < minfirstline) {
- newvpos = oldvpos;
+ SET_LINE_CYCLEBASED(hpos_org);
}
vpos = newvpos;
vb_check();
-}
+ decide_vline(hpos_org);
+}
static void VHPOSW(uae_u16 v)
{
}
if (changed & (DMA_MASTER | DMA_BITPLANE)) {
- event2_newevent_xx(-1, CYCLE_UNIT, dmacon, bitplane_dma_change);
- SET_LINE_CYCLEBASED;
+ // if ECS, DDFSTRT has already passed but DMA was off and DMA gets turned on: BPRUN actvates 1 cycle earlier
+ bool bpl = (dmacon & DMA_BITPLANE) && (dmacon & DMA_MASTER);
+ if (ecs_agnus && bpl && !dmacon_bpl && ddf_enable_on > 0) {
+ dmacon_bpl = true;
+ } else {
+ event2_newevent_xx(-1, CYCLE_UNIT, dmacon, bitplane_dma_change);
+ }
+ SET_LINE_CYCLEBASED(hpos);
}
}
if (copper_access) {
int n = get_bitplane_dma_rel(hpos, 1);
if (n == num + 1) {
- SET_LINE_CYCLEBASED;
+ SET_LINE_CYCLEBASED(hpos);
return;
}
}
if (copper_access) {
int n = get_bitplane_dma_rel(hpos, 1);
if (n == num + 1) {
- SET_LINE_CYCLEBASED;
+ SET_LINE_CYCLEBASED(hpos);
return;
}
}
bplcon0_planes_changed = true;
}
- SET_LINE_CYCLEBASED;
decide_hdiw(hpos);
- decide_line(hpos);
- decide_fetch_safe(hpos);
+ SET_LINE_CYCLEBASED(hpos);
if (aga_mode) {
int e1 = isehb(dcon0, bplcon2);
return;
}
- SET_LINE_CYCLEBASED;
decide_hdiw(hpos);
- decide_line(hpos);
- decide_fetch_safe(hpos);
+ SET_LINE_CYCLEBASED(hpos);
if ((v & 1) != (bplcon0 & 1)) {
sync_color_changes(hpos);
if (bplcon1 == v) {
return;
}
- SET_LINE_CYCLEBASED;
- decide_line(hpos);
- decide_fetch_safe(hpos);
+ SET_LINE_CYCLEBASED(hpos);
bplcon1_written = true;
bplcon1 = v;
hack_shres_delay(hpos);
{
uae_u32 vv = (num << 16) | data;
if (!num) {
- SET_LINE_CYCLEBASED;
+ SET_LINE_CYCLEBASED(hpos);
}
event2_newevent_xx(-1, 1 * CYCLE_UNIT, vv, BPLxDAT_next);
}
if (!ecs_agnus) {
v &= 0xfc;
}
- decide_line(hpos);
- decide_fetch_safe(hpos);
- SET_LINE_CYCLEBASED;
+ SET_LINE_CYCLEBASED(hpos);
ddfstrt = v;
calcdiw();
// DDFSTRT modified when DDFSTRT==hpos: neither value matches
if (!ecs_agnus) {
v &= 0xfc;
}
- decide_line(hpos);
- decide_fetch_safe(hpos);
- SET_LINE_CYCLEBASED;
+ SET_LINE_CYCLEBASED(hpos);
plfstop_prev = plfstop;
ddfstop = v;
calcdiw();
if (currprefs.monitoremu) {
specialmonitor_store_fmode(vpos, hpos, v);
}
+ fmode_saved = v;
v = 0;
}
v &= 0xC00F;
if (fmode == v) {
return;
}
- decide_line(hpos);
- decide_fetch_safe(hpos);
- SET_LINE_CYCLEBASED;
- fmode_saved = v;
+ SET_LINE_CYCLEBASED(hpos);
+ if (aga_mode) {
+ fmode_saved = v;
+ }
set_chipset_mode();
bpldmainit(hpos, bplcon0);
record_register_change(hpos, 0x1fc, fmode);
}
#if ESTIMATED_FETCH_MODE
-bool bitplane_dma_access(int hpos, int offset)
+bool bitplane_dma_access(int hpos, int coffset)
{
- hpos += offset;
- if (hpos >= maxhpos) {
- hpos -= maxhpos;
- }
- if (estimated_cycles[hpos] > 0) {
- return true;
+ if (line_cyclebased) {
+ int offset = get_rga_pipeline(hpos, coffset);
+ if (cycle_line_pipe[offset] & CYCLE_PIPE_BITPLANE) {
+ return true;
+ }
+ } else {
+ hpos += coffset;
+ if (hpos >= maxhpos) {
+ hpos -= maxhpos;
+ }
+ if (estimated_cycles[hpos] > 0) {
+ return true;
+ }
}
return false;
}
bprun_start(hpos);
if (ddf_stopping) {
bprun_pipeline_flush_delay = maxhpos;
- SET_LINE_CYCLEBASED;
+ SET_LINE_CYCLEBASED(hpos);
}
#ifdef DEBUGGER
if (debug_dma) {
ddf_stopping = 2;
bprun = 3;
}
- SET_LINE_CYCLEBASED;
+ SET_LINE_CYCLEBASED(hpos);
}
} else {
bprun_start(hpos);
if (ddf_stopping) {
bprun_pipeline_flush_delay = maxhpos;
- SET_LINE_CYCLEBASED;
+ SET_LINE_CYCLEBASED(hpos);
}
#ifdef DEBUGGER
if (debug_dma) {
ddf_stopping = 2;
bprun = 3;
}
- SET_LINE_CYCLEBASED;
+ SET_LINE_CYCLEBASED(hpos);
}
}
vb_check();
}
- decide_vline();
+ decide_vline(0);
int hp = REFRESH_FIRST_HPOS;
refptr_p = refptr;
* Remembers old regs.chipset_latch_rw
*/
v = regs.chipset_latch_rw;
- SET_LINE_CYCLEBASED;
+ SET_LINE_CYCLEBASED(hpos);
if (!noput) {
int r, c, bmdma;
uae_u16 l;
case 0x024: DSKLEN(value, hpos); break;
case 0x026: /* DSKDAT(value). Writing to DMA write registers won't do anything */; break;
case 0x028: REFPTR(hpos, value); break;
- case 0x02A: VPOSW(value); break;
+ case 0x02A: VPOSW(hpos, value); break;
case 0x02C: VHPOSW(value); break;
case 0x02E: COPCON(value); break;
#ifdef SERIAL_PORT
}
return maxvpos_display >= MAXVPOS_NTSC + (MAXVPOS_PAL - MAXVPOS_NTSC) / 2;
}
+
+static void SET_LINE_CYCLEBASED(int hpos)
+{
+ line_cyclebased = 1;
+ decide_line(hpos);
+ decide_fetch_safe(hpos);
+}