struct denise_rga rga_denise[DENISE_RGA_SLOT_TOTAL];
static struct linestate *current_line_state;
static struct linestate lines[MAX_SCANDOUBLED_LINES][2];
-static int rga_denise_cycle, rga_denise_cycle_start, rga_denise_cycle_start_prev, rga_denise_cycle_count;
+static int rga_denise_cycle, rga_denise_cycle_start, rga_denise_cycle_count;
static int rga_denise_cycle_line = 1;
static struct pipeline_reg preg;
static struct pipeline_func pfunc[MAX_PIPELINE_REG];
if (islightpentriggered()) {
return hpos_lpen;
}
- if (!eventtab[ev_sync].active) {
+ if (!eventtab[ev_sync].active || syncs_stopped) {
return agnus_hpos;
}
evt_t c = get_cycles();
static void next_denise_rga(void)
{
- rga_denise_cycle_start_prev = rga_denise_cycle_start;
rga_denise_cycle_start = rga_denise_cycle;
rga_denise_cycle_count = 0;
rga_denise[(rga_denise_cycle - 1) & DENISE_RGA_SLOT_MASK].line++;
static int getlinetype(void)
{
int type;
+
if (agnus_vb_active) {
type = LINETYPE_BLANK;
} else if (vdiwstate == diw_states::DIW_waiting_start || GET_PLANES(bplcon0) == 0 || !dmaen(DMA_BITPLANE)) {
int cslen = 10;
draw_denise_line(dvp, nextline_how, rga_denise_cycle_line, rga_denise_cycle_start, rga_denise_cycle_count,
display_hstart_cyclewait_skip, display_hstart_cyclewait_skip2,
- wclks, cs, cslen);
+ wclks, cs, cslen, lol);
}
static void dmal_fast(void)
for (int i = 0; i < rga_denise_cycle_count; i++) {
int off = i + rga_denise_cycle_start;
struct denise_rga *rd = &rga_denise[off & DENISE_RGA_SLOT_MASK];
- if (rd->line == rga_denise_cycle_line && rd->rga != 0x1fe) {
+ if (rd->line == rga_denise_cycle_line && rd->rga != 0x1fe && (rd->rga < 0x38 || rd->rga >= 0x40)) {
denise_update_reg(rd->rga, rd->v);
}
}
+ uae_u16 strobe = get_strobe_reg(0);
+ denise_handle_quick_strobe(strobe, display_hstart_fastmode);
}
static void do_draw_line(void)
}
compute_spcflag_copper();
if (copper_enabled_thisline) {
+
#if 0
// if copper is waiting, wake up is inside blank/border and
// it is followed by only writes to color registers:
if (prev_strobe == 0x3c && str != 0x3c) {
INTREQ_INT(5, 0);
}
- denise_handle_quick_strobe(str);
+ denise_handle_quick_strobe(str, display_hstart_fastmode);
prev_strobe = str;
}
custom_trigger_start();
+ int dvp = calculate_linetype(linear_display_vpos);
+ denise_set_line(dvp);
+
if (eventtab[ev_sync].active) {
check_extra();
do_imm_dmal();
static uae_u32 debug_buf[256 * 2 * 4], debug_bufx[256 * 2 * 4];
static uae_u32 *hbstrt_ptr1, *hbstrt_ptr2;
static uae_u32 *hbstop_ptr1, *hbstop_ptr2;
+static bool no_denise_lol;
void set_inhibit_frame(int monid, int bit)
{
if (currprefs.gfx_overscanmode < OVERSCANMODE_OVERSCAN) {
denise_vblank_extra = (OVERSCANMODE_OVERSCAN - currprefs.gfx_overscanmode) * 5;
}
+ no_denise_lol = !currprefs.cpu_memory_cycle_exact && !currprefs.chipset_hr;
}
static void gen_direct_drawing_table(void)
static void set_strlong(void)
{
+ if (no_denise_lol) {
+ denise_strlong = false;
+ return;
+ }
denise_strlong = true;
if (!strlong_emulation) {
write_log("STRLONG strobe emulation activated.\n");
}
if ((rd->flags & DENISE_RGA_FLAG_LOL)) {
agnus_lol = (rd->flags & DENISE_RGA_FLAG_LOL_ON) != 0;
+ if (no_denise_lol) {
+ agnus_lol = false;
+ }
if (!agnus_lol && !denise_lol_shift_prev) {
int add = 1 << hresolution;
buf1 += add;
#endif
}
-void denise_handle_quick_strobe(uae_u16 strobe)
+// fix strobe position after fast mode
+void denise_handle_quick_strobe(uae_u16 strobe, int offset)
{
struct denise_rga rd = { 0 };
rd.rga = strobe;
handle_strobes(&rd);
+ // 3 = refresh offset, 2 = pipeline delay
+ denise_hcounter_new = (offset - 3 - 2) * 2 + 2;
+ denise_hcounter = denise_hcounter_new;
}
void denise_handle_quick_disable_hblank(void)
{
}
}
+static int prevline;
+
+// set highest line, used in fast mode emulation
+void denise_set_line(int gfx_ypos)
+{
+ if (gfx_ypos < prevline) {
+ prevline = gfx_ypos;
+ }
+}
+
static void get_line(int gfx_ypos, enum nln_how how)
{
struct vidbuf_description *vidinfo = &adisplays[0].gfxvidinfo;
struct vidbuffer *vb = &vidinfo->drawbuffer;
- static int prevline;
xlinebuffer = NULL;
xlinebuffer2 = NULL;
denise_max_odd_even = denise_odd_even;
}
-void draw_denise_line(int gfx_ypos, enum nln_how how, uae_u32 linecnt, int startpos, int total, int skip, int skip2, int dtotal, int calib_start, int calib_len)
+void draw_denise_line(int gfx_ypos, enum nln_how how, uae_u32 linecnt, int startpos, int total, int skip, int skip2, int dtotal, int calib_start, int calib_len, bool lol)
{
bool fullline = false; // currprefs.chipset_hr;
get_line(gfx_ypos, how);
hbstrt_ptr1 = NULL;
+ hbstrt_ptr2 = NULL;
+ hbstop_ptr1 = NULL;
+ hbstop_ptr2 = NULL;
if (denise_pixtotal_max == -0x7fffffff || ((linear_vpos >= denise_vblank_extra_vbstop || linear_vpos < denise_vblank_extra_vbstrt) && currprefs.gfx_overscanmode < OVERSCANMODE_ULTRA)) {
#endif
// blank last pixel row if normal overscan mode, it might have NTSC artifacts
- if (denise_pixtotal_max != -0x7fffffff && hbstrt_ptr1 && currprefs.gfx_overscanmode <= OVERSCANMODE_OVERSCAN) {
+ if (denise_pixtotal_max != -0x7fffffff && hbstrt_ptr1 && currprefs.gfx_overscanmode <= OVERSCANMODE_OVERSCAN && !ecs_denise) {
int add = 1 << hresolution;
uae_u32 *p1 = hbstrt_ptr1 - denise_lol_shift_prev;
uae_u32 *p2 = hbstrt_ptr2 - denise_lol_shift_prev;
*p2++ = 0x000000;
}
}
-
+ if (no_denise_lol && denise_pixtotal_max != -0x7fffffff && hbstrt_ptr1 && !lol) {
+ int add = 1 << hresolution;
+ uae_u32 *p1 = hbstrt_ptr1 - denise_lol_shift_prev * 2;
+ uae_u32 *p2 = hbstrt_ptr2 - denise_lol_shift_prev * 2;
+ for (int i = 0; i < add * 2; i++) {
+ *p1++ = 0x000000;
+ *p2++ = 0x000000;
+ }
+ }
if (currprefs.gfx_overscanmode < OVERSCANMODE_OVERSCAN) {
+ int add = 1 << hresolution;
int w = (OVERSCANMODE_OVERSCAN - currprefs.gfx_overscanmode) * 8;
if (currprefs.gfx_overscanmode == 0) {
w -= 4;
w <<= hresolution;
for (int i = 0; i < 4; i++) {
uae_u32 *ptr, *ptr2;
+ int lolshift = 0;
switch (i)
{
case 0:
ptr = hbstrt_ptr1;
ptr2 = buf1t;
+ lolshift = lol ? -add : 0;
break;
case 1:
ptr = hbstrt_ptr2;
ptr2 = buf2t;
+ lolshift = lol ? -add : 0;
break;
case 2:
ptr = hbstop_ptr1;
ptr2 = buf1t;
+ lolshift = lol ? add : 0;
break;
case 3:
ptr = hbstop_ptr2;
ptr2 = buf2t;
+ lolshift = lol ? add : 0;
break;
-
}
if (ptr) {
- uae_u32 *p1 = ptr - denise_lol_shift_prev;
- memset(p1, 0, w * sizeof(uae_u32));
- memset(p1 - w, 0, w * sizeof(uae_u32));
+ uae_u32 *p1 = ptr - lolshift;
+ if (i >= 2) {
+ memset(p1, 0, w * sizeof(uae_u32));
+ } else {
+ memset(p1 - w, 0, w * sizeof(uae_u32));
+ }
if (bufg) {
uae_u16 *gp1 = (p1 - ptr2) + bufg;
- memset(gp1, 0xff, w * sizeof(uae_u16));
- memset(gp1 - w, 0xff, w * sizeof(uae_u16));
+ if (i >= 2) {
+ memset(gp1, 0xff, w * sizeof(uae_u16));
+ } else {
+ memset(gp1 - w, 0xff, w * sizeof(uae_u16));
+ }
}
}
}
// bitplane and sprite merge & output
if (!dpixcnt && buf1 && denise_pixtotal >= 0 && denise_pixtotal < denise_pixtotal_max) {
- uae_u32 t = dtbuf[h ^ lol][ipix];
+ uae_u32 t = dtbuf[h ^ lol][ipix];
#ifdef DEBUGGER
if (decode_specials_debug) {
void toggle_inhibit_frame(int monid, int bit);
extern struct color_entry denise_colors;
-void draw_denise_line(int gfx_ypos, nln_how how, uae_u32 linecnt, int startpos, int total, int skip, int skip2, int dtotal, int calib_start, int calib_len);
+void draw_denise_line(int gfx_ypos, nln_how how, uae_u32 linecnt, int startpos, int total, int skip, int skip2, int dtotal, int calib_start, int calib_len, bool lol);
bool draw_denise_line_fast(uae_u8 *bplpt[8], int bplstart, int bpllen, int gfx_ypos, enum nln_how how, int total, int dstart, int dtotal, bool vblank, struct denise_fastsprite *dfs);
bool start_draw_denise(void);
void end_draw_denise(void);
bool denise_update_reg_queued(uae_u16 reg, uae_u16 v, uae_u32 cycle);
void denise_store_registers(void);
void denise_restore_registers(void);
-
+void denise_set_line(int gfx_ypos);
void denise_handle_quick_disable_hblank(void);
-void denise_handle_quick_strobe(uae_u16 strobe);
+void denise_handle_quick_strobe(uae_u16 strobe, int offset);
#endif /* UAE_DRAWING_H */