uae_u8 cycle_line_slot[MAX_CHIPSETSLOTS + RGA_PIPELINE_ADJUST];
uae_u16 cycle_line_pipe[MAX_CHIPSETSLOTS + RGA_PIPELINE_ADJUST];
-static bool bpldmawasactive;
static uae_s16 bpl1mod, bpl2mod, bpl1mod_prev, bpl2mod_prev;
static int bpl1mod_hpos, bpl2mod_hpos;
static uaecptr prevbpl[2][MAXVPOS][MAX_PLANES];
static uae_u16 bplcon1, bplcon2, bplcon3, bplcon4;
static int bplcon0d, bplcon0d_old;
static uae_u32 bplcon0_res, bplcon0_planes, bplcon0_planes_limit;
-static int bplcon0_res_hr;
static int diwstrt, diwstop, diwhigh;
static int diwhigh_written;
static int ddfstrt, ddfstop, plfstop_prev;
static uae_u32 outword[MAX_PLANES];
static uae_u64 outword64[MAX_PLANES];
static uae_u16 fetched[MAX_PLANES];
-static bool todisplay_fetched[2];
+static uae_u16 todisplay_fetched;
#ifdef AGA
static uae_u64 todisplay_aga[MAX_PLANES], todisplay2_aga[MAX_PLANES];
static uae_u64 fetched_aga[MAX_PLANES];
static bool bplcon1_written;
static bool bplcon0_planes_changed;
static bool sprites_enabled_this_line;
-static int shifter_mask, shifter_size, toscr_delay_shifter[2];
+static int shifter_mask, toscr_delay_shifter[2];
static int out_subpix[2];
static bool speedup_first;
+static void events_dmal(int);
+static uae_u16 dmal, dmal_hpos;
+static bool dmal_ce;
+
/* The number of bits left from the last fetched words.
This is an optimization - conceptually, we have to make sure the result is
the same as if toscr is called in each clock cycle. However, to speed this
#define HARD_DDF_STOP 0xd8
-static uae_u8 estimated_cycles[256];
+static uae_u8 estimated_cycles_buf[256];
+static uae_u8 estimated_cycles_empty[256];
+static int estimate_cycles_empty_index = -1;
+static uae_u8* estimated_cycles = estimated_cycles_empty;
+static uae_u16 estimated_bplcon0, estimated_fm, estimated_plfstrt, estimated_plfstop;
#define ESTIMATED_FETCH_MODE 1
#if ESTIMATED_FETCH_MODE
static void end_estimate_last_fetch_cycle(int hpos)
{
+#if 1
+ if (estimate_cycles_empty_index >= 0) {
+ for (int i = 0; i < RGA_PIPELINE_ADJUST; i++) {
+ int pos = (estimate_cycles_empty_index + i) % maxhpos;
+ estimated_cycles_empty[pos] = 0;
+ }
+ estimate_cycles_empty_index = -1;
+ }
+ if (estimated_cycles_empty != estimated_cycles) {
+ estimated_cycles = estimated_cycles_empty;
+ estimate_cycles_empty_index = hpos;
+ for (int i = 0; i < RGA_PIPELINE_ADJUST; i++) {
+ int pos = (hpos + i) % maxhpos;
+ estimated_cycles_empty[pos] = estimated_cycles_buf[pos];
+ }
+ }
+#else
+ estimated_cycles = estimated_cycles_buf;
int start_pos = (hpos + RGA_PIPELINE_ADJUST) % maxhpos;
if (start_pos >= hpos) {
memset(estimated_cycles + start_pos, 0, maxhpos - start_pos);
} else {
memset(estimated_cycles + start_pos, 0, hpos - start_pos);
}
+#endif
}
static void estimate_last_fetch_cycle(int hpos)
end_estimate_last_fetch_cycle(hpos);
} else {
+
+ if (estimated_bplcon0 == bplcon0 && estimated_plfstrt == plfstrt && estimated_plfstop == plfstop && estimated_fm == fetchmode) {
+ estimated_cycles = estimated_cycles_buf;
+ return;
+ }
+
int hard_ddf_stop = harddis_h ? 0x100 : HARD_DDF_STOP;
int start = bpl_hstart;
int adjusted_plfstop = plfstop;
estimated_cycle_count = (starting_last_block_at - fc) + lastfetchunit;
}
+ estimated_cycles = estimated_cycles_buf;
// bitplane DMA end can wrap around, even in non-overrun cases
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;
off++;
}
}
+ // zero rest of buffer
+ if (end_pos != start_pos2) {
+ if (end_pos > start_pos2) {
+ memset(estimated_cycles + end_pos, 0, maxhpos - end_pos);
+ memset(estimated_cycles, 0, start_pos2);
+ } else {
+ memset(estimated_cycles + end_pos, 0, start_pos2 - end_pos);
+ }
+ }
+ estimated_bplcon0 = bplcon0;
+ estimated_plfstrt = plfstrt;
+ estimated_plfstop = plfstop;
+ estimated_fm = fetchmode;
}
}
static void compute_shifter_mask(void)
{
- shifter_size = 16 << (fetchmode + LORES_TO_SHRES_SHIFT - toscr_res);
+ int shifter_size = 16 << (fetchmode + LORES_TO_SHRES_SHIFT - toscr_res);
shifter_mask = shifter_size - 1;
}
toscr_res_mult = 0;
}
toscr_res_pixels_mask_hr = (1 << toscr_res_mult) - 1;
- toscr_res_pixels_hr = 1 << (2 - currprefs.gfx_resolution);
+ if (toscr_res > currprefs.gfx_resolution) {
+ toscr_res_pixels_shift_hr -= toscr_res - currprefs.gfx_resolution;
+ if (toscr_res_pixels_shift_hr < 0) {
+ toscr_res_pixels_shift_hr = 0;
+ }
+ }
+ toscr_res_pixels_hr = 1 << toscr_res_pixels_shift_hr;
} else {
toscr_res_mult = 0;
}
toscr_res2p = 2 << toscr_res;
}
-static void setup_fmodes_hr(void)
-{
- bplcon0_res_hr = bplcon0_res;
- if (currprefs.chipset_hr) {
- if (bplcon0_res_hr < currprefs.gfx_resolution) {
- bplcon0_res_hr = currprefs.gfx_resolution;
- }
- }
- update_toscr_vars();
-}
-
/* fetchstart_mask can be larger than fm_maxplane if FMODE > 0.
This means that the remaining cycles are idle.
*/
}
bplcon0_res = GET_RES_AGNUS(bplcon0);
toscr_res_old = -1;
- setup_fmodes_hr();
+ update_toscr_vars();
bplcon0_planes = GET_PLANES(bplcon0);
bplcon0_planes_limit = GET_PLANES_LIMIT(bplcon0);
SET_LINE_CYCLEBASED;
}
-STATIC_INLINE void clear_fetchbuffer(uae_u32 *ptr, int nwords)
-{
- if (!thisline_changed) {
- for (int i = 0; i < nwords; i++) {
- if (ptr[i]) {
- thisline_changed = 1;
- break;
- }
- }
- }
- memset(ptr, 0, nwords * 4);
-}
-
-
static int fetch_warn(int nr, int hpos)
{
static int warned1 = 30, warned2 = 30;
{
int add = fetchmode_bytes;
- // refresh conflict?
if (cycle_line_slot[hpos] == CYCLE_REFRESH) {
+ // refresh conflict
add = fetch_warn(nr, hpos);
+ } else if (cycle_line_slot[hpos] == CYCLE_MISC) {
+ // DMAL conflict
+ return false;
} else {
cycle_line_slot[hpos] = CYCLE_BITPLANE;
+#if 0
+ // audio/disk conflict? Both channel DMA transfers are skipped.
+ if (dmal_alloc_mask && hpos >= DMAL_FIRST_HPOS && hpos < DMAL_FIRST_HPOS + 8 * 2) {
+ for (int i = 0; i < 3 * 2 + 4 * 2; i += 2) {
+ if ((dmal_alloc_mask & (3 << i)) && hpos == DMAL_FIRST_HPOS + i) {
+ uae_u16 bpladdr = 0x110 + nr * 2;
+ uae_u16 dmaladdr;
+ if (i < 3 * 2) {
+ dmaladdr = (i & (1 << i)) ? 0x026 : 0x008;
+ } else {
+ dmaladdr = 0xaa + (i - 3 * 2) * 16 / 2;
+ }
+ uae_u16 newaddr = bpladdr & dmaladdr;
+ write_log("%04x-%04x=%04x ", dmaladdr, bpladdr,newaddr);
+ // clear DMAL request bits
+ dmal &= ~(3 << i);
+ // skip BPL DMA
+ return false;
+ }
+ }
+ }
+#endif
}
uaecptr p = bplpt[nr];
static void toscr_2_2_hr_oe(int oddeven, int step, int nbits) { toscr_3_aga_hr(oddeven, step, nbits, 64 - 1); }
#endif
-static void do_tosrc(int oddeven, int step, int nbits, int fm)
+STATIC_INLINE void do_tosrc(int oddeven, int step, int nbits, int fm)
{
switch (fm) {
case 0:
}
#ifdef AGA
-static void do_tosrc_hr(int oddeven, int step, int nbits, int fm)
+STATIC_INLINE void do_tosrc_hr(int oddeven, int step, int nbits, int fm)
{
switch (fm) {
case 0:
}
#endif
-#if 0
STATIC_INLINE void do_delays_3_ecs(int nbits)
{
- for (int i = 0; i < nbits; i++) {
- for (int oddeven = 0; oddeven < 2; oddeven++) {
- do_tosrc(oddeven, 2, 1, 0);
- int delaypos = (delay_cycles) & fetchmode_mask;
- if (delaypos == toscr_delay[oddeven]) {
- if (todisplay_fetched[oddeven]) {
- for (int i = oddeven; i < toscr_nr_planes_shifter; i += 2) {
- todisplay2[i] = todisplay[i];
- }
- todisplay_fetched[oddeven] = false;
- }
- }
- }
- delay_cycles++;
- delay_cycles2++;
- }
-}
-#else
-STATIC_INLINE void do_delays_3_ecs(int nbits)
-{
- int delaypos = delay_cycles & shifter_mask;
+ int delaypos = delay_cycles;
for (int oddeven = 0; oddeven < 2; oddeven++) {
- int delay = toscr_delay_shifter[oddeven];
- if (delaypos > delay) {
- delay += shifter_size;
- }
- int diff = (delay - delaypos) >> toscr_res_pixels_shift;
+ int delay = toscr_delay_shifter[0];
+ int diff = ((delay - delaypos) & shifter_mask) >> toscr_res_pixels_shift;
int nbits2 = nbits;
if (nbits2 > diff) {
do_tosrc(oddeven, 2, diff, 0);
nbits2 -= diff;
- if (todisplay_fetched[oddeven]) {
+ if (todisplay_fetched & (oddeven + 1)) {
for (int i = oddeven; i < toscr_nr_planes_shifter; i += 2) {
todisplay2[i] = todisplay[i];
}
- todisplay_fetched[oddeven] = false;
+ todisplay_fetched -= oddeven + 1;
}
}
if (nbits2) {
}
}
}
-#endif
STATIC_INLINE void do_delays_fast_3_ecs(int nbits)
{
- int delaypos = delay_cycles & shifter_mask;
+ int delaypos = delay_cycles;
int delay = toscr_delay_shifter[0];
- if (delaypos > delay) {
- delay += shifter_size;
- }
- int diff = (delay - delaypos) >> toscr_res_pixels_shift;
+ int diff = ((delay - delaypos) & shifter_mask) >> toscr_res_pixels_shift;
int nbits2 = nbits;
if (nbits2 > diff) {
do_tosrc(0, 1, diff, 0);
nbits2 -= diff;
- if (todisplay_fetched[0]) {
- for (int i = 0; i < toscr_nr_planes_shifter; i++) {
- todisplay2[i] = todisplay[i];
- }
- todisplay_fetched[0] = false;
- todisplay_fetched[1] = false;
+ if (todisplay_fetched) {
+ memcpy(todisplay2, todisplay, toscr_nr_planes_shifter * sizeof(uae_u32));
+ todisplay_fetched = 0;
}
}
if (nbits2) {
STATIC_INLINE void do_delays_3_aga(int nbits, int fm)
{
- int delaypos = delay_cycles & shifter_mask;
+ int delaypos = delay_cycles;
for (int oddeven = 0; oddeven < 2; oddeven++) {
int delay = toscr_delay_shifter[oddeven];
- if (delaypos > delay) {
- delay += shifter_size;
- }
- int diff = (delay - delaypos) >> toscr_res_pixels_shift;
+ int diff = ((delay - delaypos) & shifter_mask) >> toscr_res_pixels_shift;
int nbits2 = nbits;
if (nbits2 > diff) {
do_tosrc(oddeven, 2, diff, fm);
nbits2 -= diff;
- if (todisplay_fetched[oddeven]) {
+ if (todisplay_fetched & (oddeven + 1)) {
for (int i = oddeven; i < toscr_nr_planes_shifter; i += 2) {
todisplay2_aga[i] = todisplay_aga[i];
}
- todisplay_fetched[oddeven] = false;
+ todisplay_fetched -= oddeven + 1;
}
}
if (nbits2) {
STATIC_INLINE void do_delays_fast_3_aga(int nbits, int fm)
{
- int delaypos = delay_cycles & shifter_mask;
+ int delaypos = delay_cycles;
int delay = toscr_delay_shifter[0];
- if (delaypos > delay) {
- delay += shifter_size;
- }
- int diff = (delay - delaypos) >> toscr_res_pixels_shift;
+ int diff = ((delay - delaypos) & shifter_mask) >> toscr_res_pixels_shift;
int nbits2 = nbits;
if (nbits2 > diff) {
do_tosrc(0, 1, diff, fm);
nbits2 -= diff;
- if (todisplay_fetched[0]) {
- for (int i = 0; i < toscr_nr_planes_shifter; i++) {
- todisplay2_aga[i] = todisplay_aga[i];
- }
- todisplay_fetched[0] = false;
- todisplay_fetched[1] = false;
+ if (todisplay_fetched) {
+ memcpy(todisplay2_aga, todisplay_aga, toscr_nr_planes_shifter * sizeof(uae_u64));
+ todisplay_fetched = 0;
}
}
if (nbits2) {
}
}
-#if 0
-
STATIC_INLINE void do_delays_3_aga_hr(int nbits, int fm)
{
- int delaypos = delay_cycles & shifter_mask;
+ int delaypos = delay_cycles;
for (int oddeven = 0; oddeven < 2; oddeven++) {
int delay = toscr_delay_shifter[oddeven];
- if (delay <= delaypos)
- delay += shifter_size;
- if (delaypos + nbits >= delay && delaypos < delay) {
- int nbits2 = delay - delaypos;
- do_tosrc_hr(oddeven, 2, nbits2, fm);
- if (todisplay_fetched[oddeven]) {
- for (int i = oddeven; i < toscr_nr_planes_shifter; i += 2)
- todisplay2_aga[i] = todisplay_aga[i];
- todisplay_fetched[oddeven] = false;
- }
- out_subpix[oddeven] = 0;
- do_tosrc_hr(oddeven, 2, nbits - nbits2, fm);
- } else {
- do_tosrc_hr(oddeven, 2, nbits, fm);
- }
- }
-}
-
-STATIC_INLINE void do_delays_fast_3_aga_hr(int nbits, int fm)
-{
- int delaypos = delay_cycles & shifter_mask;
- int delay = toscr_delay_shifter[0];
- if (delay <= delaypos)
- delay += shifter_size;
- if (delaypos + nbits >= delay && delaypos < delay) {
- int nbits2 = delay - delaypos;
- do_tosrc_hr(0, 1, nbits2, fm);
- if (todisplay_fetched[0]) {
- for (int i = 0; i < toscr_nr_planes_shifter; i++)
- todisplay2_aga[i] = todisplay_aga[i];
- todisplay_fetched[0] = false;
- todisplay_fetched[1] = false;
- }
- out_subpix[0] = 0;
- do_tosrc_hr(0, 1, nbits - nbits2, fm);
- }
- else {
- do_tosrc_hr(0, 1, nbits, fm);
- }
-}
-
-#else
-
-STATIC_INLINE void do_delays_3_aga_hr(int nbits, int fm)
-{
- int delaypos = delay_cycles & shifter_mask;
- for (int oddeven = 0; oddeven < 2; oddeven++) {
- int delay = toscr_delay_shifter[oddeven];
- if (delaypos > delay) {
- delay += shifter_size;
- }
- int diff = (delay - delaypos) >> toscr_res_pixels_shift_hr;
+ int diff = ((delay - delaypos) & shifter_mask) >> toscr_res_pixels_shift_hr;
int nbits2 = nbits;
if (nbits2 > diff) {
do_tosrc_hr(oddeven, 2, diff, fm);
nbits2 -= diff;
- if (todisplay_fetched[oddeven]) {
+ if (todisplay_fetched & (oddeven + 1)) {
for (int i = oddeven; i < toscr_nr_planes_shifter; i += 2) {
todisplay2_aga[i] = todisplay_aga[i];
}
- todisplay_fetched[oddeven] = false;
+ todisplay_fetched -= oddeven + 1;
out_subpix[oddeven] = 0;
}
}
STATIC_INLINE void do_delays_fast_3_aga_hr(int nbits, int fm)
{
- int delaypos = delay_cycles & shifter_mask;
+ int delaypos = delay_cycles;
int delay = toscr_delay_shifter[0];
- if (delaypos > delay) {
- delay += shifter_size;
- }
- int diff = (delay - delaypos) >> toscr_res_pixels_shift_hr;
+ int diff = ((delay - delaypos) & shifter_mask) >> toscr_res_pixels_shift_hr;
int nbits2 = nbits;
if (nbits2 > diff) {
do_tosrc_hr(0, 1, diff, fm);
nbits2 -= diff;
- if (todisplay_fetched[0]) {
- for (int i = 0; i < toscr_nr_planes_shifter; i++) {
- todisplay2_aga[i] = todisplay_aga[i];
- }
- todisplay_fetched[0] = false;
- todisplay_fetched[1] = false;
+ if (todisplay_fetched) {
+ memcpy(todisplay2_aga, todisplay_aga, toscr_nr_planes_shifter * sizeof(uae_u64));
+ todisplay_fetched = 0;
out_subpix[0] = 0;
out_subpix[1] = 0;
}
}
}
-#endif
-
static void do_delays_2_0(int nbits) { do_delays_3_ecs(nbits); }
#ifdef AGA
static void do_delays_2_1(int nbits) { do_delays_3_aga(nbits, 1); }
}
#endif
-
-static void do_delays_null(int nbits)
+STATIC_INLINE void do_delays_null(int nbits)
{
for (int i = 0; i < MAX_PLANES; i++) {
outword[i] <<= nbits;
static uae_u32 todisplay2_saved[MAX_PLANES], todisplay_saved[MAX_PLANES];
static uae_u64 todisplay2_aga_saved[MAX_PLANES], todisplay_aga_saved[MAX_PLANES];
-static bool todisplay_fetched_saved[2];
+static uae_u16 todisplay_fetched_saved;
-static void toscr_special(int nbits, int fm)
+STATIC_INLINE void toscr_special(int nbits, int fm)
{
int total = nbits << toscr_res_pixels_shift;
bool slow = false;
todisplay2_saved[i] = todisplay2[i];
todisplay2_aga_saved[i] = todisplay2_aga[i];
}
- todisplay_fetched_saved[0] = todisplay_fetched[0];
- todisplay_fetched_saved[1] = todisplay_fetched[1];
+ todisplay_fetched_saved = todisplay_fetched;
}
if (toscr_hend <= 1) {
if (!toscr_scanline_complex_bplcon1) {
}
}
-static void toscr_special_hr(int nbits, int fm)
+STATIC_INLINE void toscr_special_hr(int nbits, int fm)
{
int total = nbits << toscr_res_pixels_shift_hr;
bool slow = false;
todisplay2_saved[i] = todisplay2[i];
todisplay2_aga_saved[i] = todisplay2_aga[i];
}
- todisplay_fetched_saved[0] = todisplay_fetched[0];
- todisplay_fetched_saved[1] = todisplay_fetched[1];
+ todisplay_fetched_saved = todisplay_fetched;
}
if (toscr_hend <= 1) {
if (!toscr_scanline_complex_bplcon1) {
}
}
-
-static void toscr_1(int nbits, int fm)
+STATIC_INLINE void toscr_1(int nbits, int fm)
{
int total = nbits << toscr_res_pixels_shift;
if (toscr_hend || delay_cycles2 + total > delay_lastcycle[lol]) {
thisline_changed = 1;
*dataptr32 = outword[i];
}
- *dataptr32 = outword[i];
dataptr += MAX_WORDS_PER_LINE * 2;
}
out_offs++;
}
}
-static void toscr_1_hr(int nbits, int fm)
+STATIC_INLINE void toscr_1_hr(int nbits, int fm)
{
toscr_special_hr(nbits, fm);
}
}
-
STATIC_INLINE void toscr_0(int nbits, int fm)
{
int t;
}
}
+STATIC_INLINE void clear_fetchbuffer(uae_u32* ptr, int nwords)
+{
+ if (!thisline_changed) {
+ for (int i = 0; i < nwords; i++) {
+ if (ptr[i]) {
+ thisline_changed = 1;
+ break;
+ }
+ }
+ }
+ memset(ptr, 0, nwords * 4);
+}
+
static void update_toscr_planes(int fm)
{
// This must be called just before new bitplane block starts,
todisplay_aga[i] = fetched_aga[i];
}
#endif
- todisplay_fetched[0] = todisplay_fetched[1] = true;
+ todisplay_fetched = 3;
sprites_enabled_this_line = true;
if (thisline_decision.plfleft < 0) {
STATIC_INLINE bool islastbplseq(void)
{
bool last = (bprun_cycle & fetchunit_mask) == fetchunit_mask;
- // AGA stops wide fetches early.
- if (aga_mode && fetchunit >= 16 && ddf_stopping == 2) {
+ // AGA stops all fetches after 8 cycles
+ if (aga_mode && ddf_stopping == 2) {
last = (bprun_cycle & 7) == 7;
}
return last;
#ifdef DEBUGGER
&& !debug_dma
#endif
- && toscr_nr_planes == toscr_nr_planes_agnus)
+ && GET_PLANES_LIMIT(bplcon0) == toscr_nr_planes_agnus)
{
int hard_ddf_stop = harddis_h ? 0x100 : HARD_DDF_STOP;
int adjusted_plfstop = plfstop;
if (ecs_denise) {
sprite_minx = min;
} else {
- if (thisline_decision.plfleft >= 0x28 || bpldmawasactive) {
+ if (thisline_decision.plfleft >= 0x28) {
sprite_minx = min;
}
}
}
}
thisline_decision.ctable = -1;
+ thisline_changed = 0;
- if (thisline_changed > 0) {
- thisline_changed = 0;
- }
curr_drawinfo[next_lineno].first_color_change = next_color_change;
last_color_change = next_color_change;
curr_drawinfo[next_lineno].first_sprite_entry = next_sprite_entry;
next_sprite_forced = 1;
last_sprite_point = 0;
- bpldmawasactive = false;
bpl1mod_hpos = -1;
bpl2mod_hpos = -1;
thisline_decision.ham_at_start = !!(bplcon0 & 0x800);
thisline_decision.bordersprite_seen = issprbrd(-1, bplcon0, bplcon3);
thisline_decision.xor_seen = (bplcon4 & 0xff00) != 0;
+ thisline_decision.nr_planes = toscr_nr_planes_agnus;
hpos_hsync_extra = 0;
int hpos = current_hpos();
if (1 && fetchmode >= 2 && !doflickerfix()) {
// handle bitplane data wrap around
- if (bprun != 0 || todisplay_fetched[0] || plane0 || plane0p || plane0_prehsync) {
+ if (bprun != 0 || todisplay_fetched || plane0 || plane0p || plane0_prehsync) {
normalstart = false;
SET_LINE_CYCLEBASED;
//thisline_decision.plfleft = hpos;
todisplay2[i] = todisplay2_saved[i];
todisplay2_aga[i] = todisplay2_aga_saved[i];
}
- todisplay_fetched[0] = todisplay_fetched_saved[0];
- todisplay_fetched[1] = todisplay_fetched_saved[1];
+ todisplay_fetched = todisplay_fetched_saved;
}
if (plane0p) {
beginning_of_plane_block_early(hpos);
plane0p_enabled = false;
memset(outword, 0, sizeof outword);
// fetched[] must not be cleared (Sony VX-90 / Royal Amiga Force)
- todisplay_fetched[0] = todisplay_fetched[1] = false;
+ todisplay_fetched = 0;
//memset(todisplay, 0, sizeof todisplay);
memset(todisplay2, 0, sizeof todisplay2);
#ifdef AGA
}
cnt--;
write_log(_T("BEAMCON0=%04X VTOTAL=%04X HTOTAL=%04X\n"), new_beamcon0, vtotal, htotal);
- write_log(_T(" HSSTOP=%04X HBSTRT=%04X HBSTOP=%04X\n"), hsstop, hbstrt, hbstop);
- write_log(_T(" VSSTOP=%04X VBSTRT=%04X VBSTOP=%04X\n"), vsstop, vbstrt, vbstop);
- write_log(_T(" HSSTRT=%04X VSSTRT=%04X HCENTER=%04X\n"), hsstrt, vsstrt, hcenter);
- write_log(_T(" HSYNCSTART=%04X.%d HSYNCEND=%04X.%d\n"),
+ write_log(_T(" HS=%04X-%04X HB=%04X-%04X HC=%04X\n"), hsstrt, hsstop, hbstrt, hbstop, hcenter);
+ write_log(_T(" VS=%04X-%04X VB=%04X-%04X\n"), vsstrt, vsstop, vbstrt, vbstop);
+ write_log(_T(" HSYNCSTART=%04X.%d HSYNCEND=%04X.%d\n"),
hsyncstartpos >> CCK_SHRES_SHIFT, hsyncstartpos & ((1 << CCK_SHRES_SHIFT) - 1),
hsyncendpos >> CCK_SHRES_SHIFT, hsyncendpos & ((1 << CCK_SHRES_SHIFT) - 1));
+ write_log(_T(" LINES=%d-%d VB=%d-%d\n"),
+ minfirstline, maxvpos_display + maxvpos_display_vsync,
+ vblank_firstline_hw, vblank_lastline_hw);
+
}
int current_maxvpos(void)
reset_drawing();
init_hz_normal();
calcdiw();
- setup_fmodes_hr();
update_toscr_vars();
compute_shifter_mask();
compute_toscr_delay(bplcon1);
#define VPOS_INC_DELAY (CPU_ACCURATE ? 1 : 0)
+static void vb_check(void)
+{
+ // A1000 Agnus VBSTRT=first line, OCS and later: VBSTRT=last line
+ if (currprefs.cs_dipagnus) {
+ if (vpos == 0) {
+ vb_start_line = 1;
+ vb_state = true;
+ }
+ } else {
+ if (vpos == maxvpos + lof_store - 1) {
+ vb_start_line = 1;
+ vb_state = true;
+ }
+ }
+ if (vpos == hardwired_vbstop - 1) {
+ vb_end_line = true;
+ vb_state = false;
+ }
+}
+
static uae_u16 VPOSR(void)
{
unsigned int csbit = 0;
if (vpos < oldvpos) {
vpos = oldvpos;
}
+ vb_check();
}
static void VHPOSW(uae_u16 v)
if (chp >= 0x21 && chp <= 0x29 && hp == 0x2d) {
hack_delay_shift = 4;
record_color_change(chp, 0, COLOR_CHANGE_HSYNC_HACK | 6);
- thisline_changed = true;
+ thisline_changed = 1;
}
}
} else if (vpos < minfirstline && oldvpos < minfirstline) {
vpos = oldvpos;
}
+ vb_check();
#if 0
if (vpos < oldvpos)
vposback (oldvpos);
if (varsync_changed > 0) {
varsync_changed--;
}
- if (thisline_changed < 0) {
- thisline_changed++;
- }
}
// emulated hardware vsync
// Bitplane only
dmacon = odmacon & (DMA_MASTER | DMA_BITPLANE);
+ // Blank last line
+ if (vpos >= maxvpos - 1) {
+ dmacon = 0;
+ }
copper_enabled_thisline = 0;
reset_decisions_scanline_start();
// copy color changes
struct draw_info *dip1 = curr_drawinfo + next_lineno - 1;
-// if (dip1->first_color_change != dip1->last_color_change)
-// write_log("1\n");
for (int idx1 = dip1->first_color_change; idx1 < dip1->last_color_change; idx1++) {
struct color_change* cs2 = &curr_color_changes[idx1];
struct color_change* cs1 = &curr_color_changes[next_color_change];
reset_scandoubler_sync(hpos);
}
-static void events_dmal(int);
-static uae_u16 dmal, dmal_hpos;
-static bool dmal_ce;
-
static void dmal_emu(uae_u32 v)
{
// Disk and Audio DMA bits are ignored by Agnus. Including DMA master bit.
int hpos = current_hpos();
+
+ if (currprefs.cpu_memory_cycle_exact) {
+ // BPL conflict
+ if (bitplane_dma_access(hpos, 0)) {
+ return;
+ }
+ }
+
if (v >= 6) {
v -= 6;
int nr = v / 2;
// disk_fifostatus() needed in >100% disk speed modes
if (w) {
// write to disk
- if (disk_fifostatus () <= 0) {
+ if (disk_fifostatus() <= 0) {
if (dmal_ce) {
#ifdef DEBUGGER
if (debug_dma) {
hhpos &= 0xff;
}
if (!(new_beamcon0 & 0x1000)) {
- // A1000 Agnus VBSTRT=first line, OCS and later: VBSTRT=last line
- if (currprefs.cs_dipagnus) {
- if (vpos == 0) {
- vb_start_line = 1;
- vb_state = true;
- }
- } else {
- if (vpos == maxvpos + lof_store - 1) {
- vb_start_line = 1;
- vb_state = true;
- }
- }
- if (vpos == hardwired_vbstop - 1) {
- vb_end_line = true;
- vb_state = false;
- }
+ vb_check();
}
decide_vline();
toscr_res_old = -1;
toscr_nbits = 0;
update_denise_vars();
+ estimated_fm = 0xffff;
if (!savestate_state) {
cia_hsync = 0;
}
}
-
bool is_cycle_ce(uaecptr addr)
{
addrbank *ab = get_mem_bank_real(addr);
struct sprite_stb spixstate;
static uae_u32 ham_linebuf[MAX_PIXELS_PER_LINE * 2];
-static uae_u8 *real_bplpt[8];
static uae_u8 all_ones[MAX_PIXELS_PER_LINE];
static uae_u8 all_zeros[MAX_PIXELS_PER_LINE];
bool hardwired = !dp_for_drawing || !ce_is_extblankset(colors_for_drawing.extra) || !ce_is_extblankmode(colors_for_drawing.extra);
bool doblank = false;
int hbstrt = (235 << CCK_SHRES_SHIFT) - 3;
- int hbstop = (46 << CCK_SHRES_SHIFT) - 7;
+ int hbstop = (47 << CCK_SHRES_SHIFT) - 7;
if (currprefs.gfx_overscanmode < OVERSCANMODE_OVERSCAN) {
int mult = (OVERSCANMODE_OVERSCAN - currprefs.gfx_overscanmode) * 4;
doblank = true;
} else if (currprefs.gfx_overscanmode == OVERSCANMODE_BROADCAST) {
hbstrt = (239 << CCK_SHRES_SHIFT) - 3;
- hbstop = (46 << CCK_SHRES_SHIFT) - 7;
doblank = true;
}
if (doblank && programmedmode != 1) {
- if (new_beamcon0 & 0x0110) {
+ // reposition to sync
+ // use hardwired hblank emulation as overscan blanking.
+ if ((new_beamcon0 & 0x0110) && !hardwired) {
extern uae_u16 hsstrt;
hbstrt += (hsstrt - 17) << CCK_SHRES_SHIFT;
hbstop += (hsstrt - 17) << CCK_SHRES_SHIFT;
}
+
if (currprefs.chipset_hr) {
hbstrt &= ~(3 >> currprefs.gfx_resolution);
hbstop &= ~(3 >> currprefs.gfx_resolution);
#define GETLONG32(P) (*(uae_u32*)P)
#define GETLONG64(P) (*(uae_u64*)P)
-STATIC_INLINE void pfield_doline32_1(uae_u32 *pixels, int wordcount, int planes)
+STATIC_INLINE void pfield_doline32_1(uae_u32 *pixels, int wordcount, int planes, uae_u8 *real_bplpt[8])
{
while (wordcount-- > 0) {
uae_u32 b0, b1, b2, b3, b4, b5, b6, b7;
}
-STATIC_INLINE void pfield_doline64_1(uae_u64 *pixels, int wordcount, int planes)
+STATIC_INLINE void pfield_doline64_1(uae_u64 *pixels, int wordcount, int planes, uae_u8 *real_bplpt[8])
{
while (wordcount-- > 0) {
uae_u64 b0, b1, b2, b3, b4, b5, b6, b7;
/* See above for comments on inlining. These functions should _not_
be inlined themselves. */
-static void NOINLINE pfield_doline32_n1(uae_u32 *data, int count) { pfield_doline32_1(data, count, 1); }
-static void NOINLINE pfield_doline32_n2(uae_u32 *data, int count) { pfield_doline32_1(data, count, 2); }
-static void NOINLINE pfield_doline32_n3(uae_u32 *data, int count) { pfield_doline32_1(data, count, 3); }
-static void NOINLINE pfield_doline32_n4(uae_u32 *data, int count) { pfield_doline32_1(data, count, 4); }
-static void NOINLINE pfield_doline32_n5(uae_u32 *data, int count) { pfield_doline32_1(data, count, 5); }
-static void NOINLINE pfield_doline32_n6(uae_u32 *data, int count) { pfield_doline32_1(data, count, 6); }
+static void NOINLINE pfield_doline32_n1(uae_u32 *data, int count, uae_u8 *real_bplpt[8]) { pfield_doline32_1(data, count, 1, real_bplpt); }
+static void NOINLINE pfield_doline32_n2(uae_u32 *data, int count, uae_u8 *real_bplpt[8]) { pfield_doline32_1(data, count, 2, real_bplpt); }
+static void NOINLINE pfield_doline32_n3(uae_u32 *data, int count, uae_u8 *real_bplpt[8]) { pfield_doline32_1(data, count, 3, real_bplpt); }
+static void NOINLINE pfield_doline32_n4(uae_u32 *data, int count, uae_u8 *real_bplpt[8]) { pfield_doline32_1(data, count, 4, real_bplpt); }
+static void NOINLINE pfield_doline32_n5(uae_u32 *data, int count, uae_u8 *real_bplpt[8]) { pfield_doline32_1(data, count, 5, real_bplpt); }
+static void NOINLINE pfield_doline32_n6(uae_u32 *data, int count, uae_u8 *real_bplpt[8]) { pfield_doline32_1(data, count, 6, real_bplpt); }
#ifdef AGA
-static void NOINLINE pfield_doline32_n7(uae_u32 *data, int count) { pfield_doline32_1(data, count, 7); }
-static void NOINLINE pfield_doline32_n8(uae_u32 *data, int count) { pfield_doline32_1(data, count, 8); }
+static void NOINLINE pfield_doline32_n7(uae_u32 *data, int count, uae_u8* real_bplpt[8]) { pfield_doline32_1(data, count, 7, real_bplpt); }
+static void NOINLINE pfield_doline32_n8(uae_u32 *data, int count, uae_u8 *real_bplpt[8]) { pfield_doline32_1(data, count, 8, real_bplpt); }
#endif
-static void NOINLINE pfield_doline64_n1(uae_u64 *data, int count) { pfield_doline64_1(data, count, 1); }
-static void NOINLINE pfield_doline64_n2(uae_u64 *data, int count) { pfield_doline64_1(data, count, 2); }
-static void NOINLINE pfield_doline64_n3(uae_u64 *data, int count) { pfield_doline64_1(data, count, 3); }
-static void NOINLINE pfield_doline64_n4(uae_u64 *data, int count) { pfield_doline64_1(data, count, 4); }
-static void NOINLINE pfield_doline64_n5(uae_u64 *data, int count) { pfield_doline64_1(data, count, 5); }
-static void NOINLINE pfield_doline64_n6(uae_u64 *data, int count) { pfield_doline64_1(data, count, 6); }
+static void NOINLINE pfield_doline64_n1(uae_u64 *data, int count, uae_u8 *real_bplpt[8]) { pfield_doline64_1(data, count, 1, real_bplpt); }
+static void NOINLINE pfield_doline64_n2(uae_u64 *data, int count, uae_u8 *real_bplpt[8]) { pfield_doline64_1(data, count, 2, real_bplpt); }
+static void NOINLINE pfield_doline64_n3(uae_u64 *data, int count, uae_u8 *real_bplpt[8]) { pfield_doline64_1(data, count, 3, real_bplpt); }
+static void NOINLINE pfield_doline64_n4(uae_u64 *data, int count, uae_u8 *real_bplpt[8]) { pfield_doline64_1(data, count, 4, real_bplpt); }
+static void NOINLINE pfield_doline64_n5(uae_u64 *data, int count, uae_u8 *real_bplpt[8]) { pfield_doline64_1(data, count, 5, real_bplpt); }
+static void NOINLINE pfield_doline64_n6(uae_u64 *data, int count, uae_u8 *real_bplpt[8]) { pfield_doline64_1(data, count, 6, real_bplpt); }
#ifdef AGA
-static void NOINLINE pfield_doline64_n7(uae_u64 *data, int count) { pfield_doline64_1(data, count, 7); }
-static void NOINLINE pfield_doline64_n8(uae_u64 *data, int count) { pfield_doline64_1(data, count, 8); }
+static void NOINLINE pfield_doline64_n7(uae_u64 *data, int count, uae_u8 *real_bplpt[8]) { pfield_doline64_1(data, count, 7, real_bplpt); }
+static void NOINLINE pfield_doline64_n8(uae_u64 *data, int count, uae_u8* real_bplpt[8]) { pfield_doline64_1(data, count, 8, real_bplpt); }
#endif
static void pfield_doline(int lineno)
{
+ uae_u8 *real_bplpt[8];
+
#if 0
int wordcount = (dp_for_drawing->plflinelen + 1) / 2;
uae_u64 *data = pixdata.apixels_q + MAX_PIXELS_PER_LINE / sizeof(uae_u64);
switch (bplplanecnt) {
default: break;
case 0: memset(data, 0, wordcount * 64); break;
- case 1: pfield_doline64_n1(data, wordcount); break;
- case 2: pfield_doline64_n2(data, wordcount); break;
- case 3: pfield_doline64_n3(data, wordcount); break;
- case 4: pfield_doline64_n4(data, wordcount); break;
- case 5: pfield_doline64_n5(data, wordcount); break;
- case 6: pfield_doline64_n6(data, wordcount); break;
+ case 1: pfield_doline64_n1(data, wordcount, real_bplpt); break;
+ case 2: pfield_doline64_n2(data, wordcount, real_bplpt); break;
+ case 3: pfield_doline64_n3(data, wordcount, real_bplpt); break;
+ case 4: pfield_doline64_n4(data, wordcount, real_bplpt); break;
+ case 5: pfield_doline64_n5(data, wordcount, real_bplpt); break;
+ case 6: pfield_doline64_n6(data, wordcount, real_bplpt); break;
#ifdef AGA
- case 7: pfield_doline64_n7(data, wordcount); break;
- case 8: pfield_doline64_n8(data, wordcount); break;
+ case 7: pfield_doline64_n7(data, wordcount, real_bplpt); break;
+ case 8: pfield_doline64_n8(data, wordcount, real_bplpt); break;
#endif
}
#else
switch (bplplanecnt) {
default: break;
case 0: memset(data, 0, wordcount * 32); break;
- case 1: pfield_doline32_n1(data, wordcount); break;
- case 2: pfield_doline32_n2(data, wordcount); break;
- case 3: pfield_doline32_n3(data, wordcount); break;
- case 4: pfield_doline32_n4(data, wordcount); break;
- case 5: pfield_doline32_n5(data, wordcount); break;
- case 6: pfield_doline32_n6(data, wordcount); break;
+ case 1: pfield_doline32_n1(data, wordcount, real_bplpt); break;
+ case 2: pfield_doline32_n2(data, wordcount, real_bplpt); break;
+ case 3: pfield_doline32_n3(data, wordcount, real_bplpt); break;
+ case 4: pfield_doline32_n4(data, wordcount, real_bplpt); break;
+ case 5: pfield_doline32_n5(data, wordcount, real_bplpt); break;
+ case 6: pfield_doline32_n6(data, wordcount, real_bplpt); break;
#ifdef AGA
- case 7: pfield_doline32_n7(data, wordcount); break;
- case 8: pfield_doline32_n8(data, wordcount); break;
+ case 7: pfield_doline32_n7(data, wordcount, real_bplpt); break;
+ case 8: pfield_doline32_n8(data, wordcount, real_bplpt); break;
#endif
}
#endif
int line = sly + i;
draw_status_line(vb->monitor_id, line, i);
}
+ } else {
+ statusbar_y1 = 0;
+ statusbar_y1 = 0;
}
if (debug_dma > 1 || debug_heatmap > 1) {
for (int i = 0; i < vb->outheight; i++) {