#define SPRBORDER 0
-#define EXTRAWIDTH_BROADCAST 7
#define EXTRAHEIGHT_BROADCAST_TOP 0
#define EXTRAHEIGHT_BROADCAST_BOTTOM 0
-#define EXTRAWIDTH_EXTREME 38
#define EXTRAHEIGHT_EXTREME 28
-#define EXTRAWIDTH_ULTRA 77
#define LORES_TO_SHRES_SHIFT 2
static int linear_vpos_vsync;
static int linear_display_vpos;
int current_linear_vpos, current_linear_hpos;
+static int current_linear_hblen, current_linear_hblen_temp;
int current_linear_vpos_nom, current_linear_hpos_short;
static int linear_vpos_visible, current_linear_vpos_visible;
static int current_linear_vpos_temp, current_linear_hpos_temp;
/*
* Horizontal hardwired defaults
*
+* Agnus/Alice (CCKs)
+*
* 0x00 0 HC0 (genlock handling)
* 0x01 1 HC1 (START), (VSY serration pulse start)
* 0x09 9 VR1 (LOF=0 -> VE start, LOF=1 -> VE stop)
* 0xe2 226 HC226 (LOL=0, [HTOTAL] PAL line, NTSC short line)
* 0xe3 227 HC227 (LOL=1, NTSC long line)
*
+* Denise/Lisa (in lores pixels)
+*
+* 0x0f 15 HBLANK start (OCS) = 7.5 CCK
+* 0x10 16 HBLANK start (ECS/AGA) = 8.0 CCK
+* 0x5d 93 HBLANK end (OCS/ECS/AGA) = 46.5 CCK
+*
+*
* Vertical hardwired defaults
+*
+* Agnus/Alice (lines)
*
* 0 SVB (start for Vertical Equalization zone)
* 2 VC2 (PAL/CEN/LOF=0 -> enable Vertical Sync zone)
*/
static bool agnus_phsync, agnus_phblank;
-static uae_u32 agnus_phblank_start, agnus_phblank_end, agnus_phsync_start, agnus_phsync_end, agnus_hsync_start, agnus_hsync_end;
+static uae_u32 agnus_phblank_start_tmp, agnus_phblank_start, agnus_phblank_end, agnus_hsync_start;
+static int hsync_cck;
+static int current_linear_hs_hb_dist;
+static uae_u32 agnus_hsstrt_cck, agnus_hsstop_cck;
+static uae_u32 agnus_phsstrt_cck, agnus_phsstop_cck;
+static uae_u32 agnus_pchsstrt_cck, agnus_pchsstop_cck;;
static bool agnus_pvsync, agnus_pcsync, agnus_csync;
static int agnus_vb, agnus_pvb;
static bool agnus_vb_active;
static bool agnus_hsync, agnus_vsync, agnus_ve, agnus_p_ve;
static bool agnus_bsvb, agnus_bsvb_prev;
static bool agnus_equdis;
+static int vsync_lines, vsync_linecnt;
int maxhpos = MAXHPOS_PAL;
int maxvpos = MAXVPOS_PAL;
int maxvpos_nom = MAXVPOS_PAL; // nominal value (same as maxvpos but "faked" maxvpos in fake 60hz modes)
static int maxvpos_long;
+static int hblen_display_tmp, hblen_cnt;
int maxvpos_display = MAXVPOS_PAL; // value used for display size
int maxhpos_display = AMIGA_WIDTH_MAX;
int maxvsize_display = AMIGA_HEIGHT_MAX;
int maxhposm0 = MAXHPOS_PAL;
static bool maxhposeven;
static int hsyncendpos, hsyncstartpos;
-int hsync_end_left_border, hdisplay_left_border;
-static int hsyncstartpos_start, hsyncstartpos_start_cycles;
-
-static int hsyncstartpos_start_hw;
-int hsyncstartpos_hw;
-int hsyncendpos_hw;
+int hdisplay_left_border;
int denisehtotal;
static int maxvpos_total = 511;
uae_u16 hsstop, hsstrt;
uae_u16 hbstop, hbstrt;
static int hbstop_cck, hbstrt_cck;
-static int hsstop_detect, hsstop_detect2;
static uae_u16 vsstop, vsstrt;
static uae_u16 vbstop, vbstrt;
static uae_u16 hcenter;
void getsyncregisters(uae_u16 *phsstrt, uae_u16 *phsstop, uae_u16 *pvsstrt, uae_u16 *pvsstop)
{
*phsstrt = hsstrt;
- *phsstop = hsstop_detect2 / 2;
+ *phsstop = hsstop; // hsstop_detect2 / 2;
*pvsstrt = vsstrt;
*pvsstop = vsstop;
}
return maxvpos + (lof_store ? 1 : 0);
}
+#if 0
static void updateextblk(void)
{
- hsyncstartpos_start_hw = 13;
- hsyncstartpos_hw = maxhpos_short + hsyncstartpos_start_hw;
- hsyncendpos_hw = 24;
+ int hsyncstartpos_start_hw = 13;
+ int hsyncstartpos_start;
+ int hsyncstartpos_hw = maxhpos_short + hsyncstartpos_start_hw;
+ int hsyncendpos_hw = 24;
if ((new_beamcon0 & bemcon0_hsync_mask) && (!currprefs.monitoremu || currprefs.cs_hvcsync > 0)) {
}
hsyncendpos = hsstop;
- hsstop_detect2 = (hsstrt + 21) * 2;
- if (hsstop_detect2 >= maxhpos_short * 2) {
- hsstop_detect2 -= maxhpos_short * 2;
- }
+ //hsstop_detect2 = (hsstrt + 21) * 2;
+ //if (hsstop_detect2 >= maxhpos_short * 2) {
+ // hsstop_detect2 -= maxhpos_short * 2;
+ //}
hsyncstartpos_start = hsyncstartpos;
if (hsyncstartpos < maxhpos_short / 2) {
hsyncstartpos_start = hsyncstartpos_start_hw;
hsyncstartpos = hsyncstartpos_hw;
denisehtotal = maxhpos_short + 7;
- hsstop_detect2 = (35 + 9) * 2;
+ //hsstop_detect2 = (35 + 9) * 2;
hsyncendpos = hsyncendpos_hw;
hsyncstartpos_hw <<= CCK_SHRES_SHIFT;
hsyncendpos_hw <<= CCK_SHRES_SHIFT;
- hsyncstartpos_start_cycles = hsyncstartpos_start;
+ int hsyncstartpos_start_cycles = hsyncstartpos_start;
hsyncstartpos_start <<= CCK_SHRES_SHIFT;
hsyncstartpos <<= CCK_SHRES_SHIFT;
}
}
+#endif
struct chipset_refresh *get_chipset_refresh(struct uae_prefs *p)
{
stored_chipset_refresh = cr;
vb->inxoffset = -1;
vb->inyoffset = -1;
- updateextblk();
-
- hsync_end_left_border = display_hstart_cyclewait_end + display_hstart_cyclewait;
int res = GET_RES_AGNUS(bplcon0);
int eres = 0;
eres--;
}
- hsync_end_left_border <<= eres;
-
int vres2 = currprefs.gfx_vresolution;
if (doublescan > 0 && !islace) {
vres2--;
vres2 = VRES_QUAD;
}
- if (currprefs.gfx_overscanmode >= OVERSCANMODE_ULTRA) {
- vb->inwidth = current_linear_hpos_short << (res2 + 1);
- } else {
- vb->inwidth = (current_linear_hpos_short - (display_hstart_cyclewait_skip + display_hstart_cyclewait_skip2)) << (res2 + 1);
- }
+ vb->inwidth = (current_linear_hpos_short - (display_hstart_cyclewait_skip + display_hstart_cyclewait_skip2)) << (res2 + 1);
vb->inwidth2 = vb->inwidth;
vb->extrawidth = -2;
if (currprefs.gfx_extrawidth > 0) {
vblank_hz_lof = clk / ((display_maxvpos + 1.0f) * (display_maxhpos + halfhpos));
vblank_hz_lace = clk / ((display_maxvpos + 0.5f) * (display_maxhpos + halfhpos));
+#if 0
display_hstart_cyclewait_end = 4;
if (beamcon0_has_hsync) {
+ int hblen = current_linear_hblen * 2;
display_hstart_cyclewait = 4;
if (currprefs.gfx_overscanmode >= OVERSCANMODE_ULTRA) {
display_hstart_cyclewait_end = 0;
} else {
- if (aexthblanken && !(beamcon0 & BEAMCON0_VARBEAMEN)) {
- int hp2 = maxhpos * 2;
- int hbstrtx, hbstopx;
- int hb = 1;
- hbstrtx = (hbstrt & 0xff) * 2;
- hbstopx = (hbstop & 0xff) * 2;
- if (aga_mode) {
- hbstrtx |= (hbstrt & 0x400) ? 1 : 0;
- hbstopx |= (hbstop & 0x400) ? 1 : 0;
- }
- if (hbstrtx > hp2) {
- hbstrtx = hp2;
- }
- if (hbstopx > hp2) {
- hbstopx = hp2;
+ if (aexthblanken && !(beamcon0 & BEAMCON0_VARBEAMEN) && hblen > 0) {
+ maxhpos_display = maxhpos - ((hblen + 1) / 2);
+ hsstop_detect = current_linear_hs_hb_dist * 2 + 4;
+ display_hstart_cyclewait_end += hblen / 2 - 4;
+ display_hstart_cyclewait = current_linear_hs_hb_dist;
+ if (display_hstart_cyclewait < 0) {
+ display_hstart_cyclewait = 0;
}
- if (hbstrtx > hp2 / 2 && hbstopx < hp2 / 2) {
- hb = (hp2 - hbstrtx) + hbstopx;
- } else if (hbstopx < hp2 / 2 && hbstrtx < hbstopx) {
- hb = hbstopx - hbstrtx;
- }
- if (hbstopx > hp2 / 2) {
- hbstopx = 0;
- }
- if (hb < 1) {
- hb = 1;
+ display_hstart_cyclewait_end = hblen / 2 - display_hstart_cyclewait;
+ display_hstart_cyclewait += 1;
+ } else {
+ // hardwired
+ int hbstrtx = 0x10;
+ int hbstopx = ecs_denise ? 0x5d : 0x5e;
+ int hblen = hbstopx - hbstrtx;
+ maxhpos_display = maxhpos - (hblen / 2);
+ if (beamcon0_has_hsync) {
+ hsstop_detect = hsstrt * 2;
+ } else {
+ hsstop_detect = hsstop_detect2;
}
- display_hstart_cyclewait = 4;
- if (hbstopx / 2 > hsstrt && (hbstopx / 2 - hsstrt < maxhpos / 2)) {
- display_hstart_cyclewait = hbstopx / 2 - hsstrt;
- } else if (hsstrt - hbstopx / 2 < maxhpos / 2) {
- display_hstart_cyclewait = hsstrt - hbstopx / 2;
- }
- if (hb) {
- display_hstart_cyclewait_end = hb / 2 - display_hstart_cyclewait;
- display_hstart_cyclewait += 1;
- }
+ display_hstart_cyclewait = hbstopx / 2 - hsstrt;
+ //display_hstart_cyclewait += hsstrt_delay;
}
}
} else {
display_hstart_cyclewait_end = 5;
}
}
+#endif
if (beamcon0 & BEAMCON0_VARBEAMEN) {
// programmable scanrates (ECS Agnus)
vsync_startline = 3;
if ((beamcon0 & BEAMCON0_VARVBEN) && (beamcon0 & bemcon0_vsync_mask)) {
vsync_startline += vsstrt;
- if (vsync_startline >= maxvpos / 2) {
+ if (vsync_startline >= vsync_lines / 2) {
vsync_startline = 3;
}
}
maxvpos_nom = maxvpos;
- maxvpos_display = maxvpos;
+ maxvpos_display = vsync_lines;
+
+ int hbs = 0, hbe = 0, hblen = 0;
+ denise_get_hboffsets(&hbs, &hbe, &hblen);
+ hblen /= 4;
+ hbe /= 4;
+ //hsstop_detect = hbe;
+
+ if (currprefs.gfx_overscanmode < OVERSCANMODE_BROADCAST) {
+ // one pixel row missing from right border if OCS
+ if (!ecs_denise) {
+ maxhpos_display--;
+ }
+ minfirstline++;
+ if (maxvpos_display_vsync > 0) {
+ maxvpos_display_vsync--;
+ } else {
+ maxvpos_display--;
+ }
+ } else if (currprefs.gfx_overscanmode == OVERSCANMODE_EXTREME) {
+ hblen -= 38;
+ hbe -= 30;
+ } else if (currprefs.gfx_overscanmode == OVERSCANMODE_BROADCAST) {
+ hblen -= 7;
+ }
+
+ if (hblen < 0) {
+ hblen = 0;
+ }
+
+ display_hstart_cyclewait = hbe / 2 + 4;
+ if (display_hstart_cyclewait < 0) {
+ display_hstart_cyclewait = 0;
+ }
+ display_hstart_cyclewait_end = 7;// hblen / 2 - display_hstart_cyclewait + 1;
+
+ if (currprefs.gfx_overscanmode >= OVERSCANMODE_ULTRA) {
+ display_hstart_cyclewait = 0;
+ display_hstart_cyclewait_end = 0;
+ maxhpos_display = hsync_cck * 2;
+#if 0
+ if (beamcon0_has_hsync) {
+ hsstop_detect = hsstrt * 2;
+ if (hsstop_detect > maxhpos / 2 * 2 || hsstop_detect < 4 * 2) {
+ hsstop_detect = 4 * 2;
+ }
+ } else {
+ hsstop_detect = 4 * 2;
+ }
+#endif
+ minfirstline = 0;
+ } else {
+ maxhpos_display = hsync_cck * 2 - hblen;
+ }
+
+ denisehtotal = hsync_cck;
+ denisehtotal <<= CCK_SHRES_SHIFT;
+ // ECS Denise has 1 extra lores pixel in right border
+ if (ecs_denise) {
+ denisehtotal += 1 << (CCK_SHRES_SHIFT - 1);
+ }
+
+#if 0
// calculate max possible display width in lores pixels
if ((beamcon0 & BEAMCON0_VARBEAMEN) && beamcon0_has_hsync) {
int hsstrt_delay = 2;
- int hb = 0;
display_hstart_cyclewait = 0;
display_hstart_cyclewait_end = 0;
// assume VGA-like monitor if VARBEAMEN
}
minfirstline = 0;
} else {
- int hp2 = maxhpos * 2;
- int hbstrtx, hbstopx;
+ //int hblen = current_linear_hblen * 2;
- if (aexthblanken) {
+ if (aexthblanken && hblen > 0) {
- hb = 1;
- hbstrtx = (hbstrt & 0xff) * 2;
- hbstopx = (hbstop & 0xff) * 2;
- if (aga_mode) {
- hbstrtx |= (hbstrt & 0x400) ? 1 : 0;
- hbstopx |= (hbstop & 0x400) ? 1 : 0;
- }
- if (hbstrtx > hp2) {
- hbstrtx = hp2;
- }
- if (hbstopx > hp2) {
- hbstopx = hp2;
+ maxhpos_display = maxhpos - ((hblen + 1) / 2);
+ hsstop_detect = hbe;
+ display_hstart_cyclewait_end += hblen / 2;
+ display_hstart_cyclewait = hbe / 2;
+ if (display_hstart_cyclewait < 0) {
+ display_hstart_cyclewait = 0;
}
- if (hbstrtx > hp2 / 2 && hbstopx < hp2 / 2) {
- hb = (hp2 - hbstrtx) + hbstopx;
- } else if (hbstopx < hp2 / 2 && hbstrtx < hbstopx) {
- hb = hbstopx - hbstrtx;
- }
- if (hbstopx > hp2 / 2) {
- hbstopx = 0;
- }
- if (hb < 1) {
- hb = 1;
- }
-
-#if 0
- // HSYNC adjustment
- int hsz = 0;
- if (hsstrt > maxhpos / 2 && hsstop > hsstrt) {
- hsz = hsstop - hsstrt;
- } else if (hsstrt > maxhpos / 2 && hsstop < maxhpos / 2) {
- hsz = (maxhpos - hsstrt) - hsstop;
- } else if (hsstop < maxhpos / 2 && hsstrt < hsstop) {
- hsz = hsstop - hsstrt;
- }
-#endif
- maxhpos_display = maxhpos - ((hb + 1) / 2);
- hsstop_detect = hbstopx / 2;
- display_hstart_cyclewait_end += hb / 2 - 4;
-
+ display_hstart_cyclewait_end = hblen / 2 - display_hstart_cyclewait;
+ display_hstart_cyclewait += 1;
} else {
// hardwired
- hbstrtx = 0x10;
- hbstopx = ecs_denise ? 0x5d : 0x5e;
- hb = hbstopx - hbstrtx;
- maxhpos_display = maxhpos - (hb / 2);
+ int hbstrtx = 0x10;
+ int hbstopx = ecs_denise ? 0x5d : 0x5e;
+ int hblen = hbstopx - hbstrtx;
+ maxhpos_display = maxhpos - (hblen / 2);
if (beamcon0_has_hsync) {
hsstop_detect = hsstrt * 2;
} else {
hsstop_detect = hsstop_detect2;
}
- hb = 0;
- }
- if (hbstopx / 2 > hsstrt && (hbstopx / 2 - hsstrt < maxhpos / 2)) {
display_hstart_cyclewait = hbstopx / 2 - hsstrt;
- } else if (hsstrt - hbstopx / 2 < maxhpos / 2) {
- display_hstart_cyclewait = hsstrt - hbstopx / 2;
- }
- if (hb) {
- display_hstart_cyclewait_end = hb / 2 - display_hstart_cyclewait;
- display_hstart_cyclewait += 1;
+ display_hstart_cyclewait += hsstrt_delay;
}
- display_hstart_cyclewait += hsstrt_delay;
if (currprefs.gfx_overscanmode >= OVERSCANMODE_EXTREME) {
int diff = (maxhpos - 2) - maxhpos_display;
} else if (!(beamcon0 & BEAMCON0_VARBEAMEN)) {
- maxhpos_display = AMIGA_WIDTH_MAX;
- hsstop_detect = hsstop_detect2;
+ maxhpos_display = maxhpos - (hblen / 2);
+ maxhpos_display *= 2;
+ maxhpos_display++;
+ hsstop_detect = hbe;
+ display_hstart_cyclewait = hbe / 2 + 3;
+ if (display_hstart_cyclewait < 0) {
+ display_hstart_cyclewait = 0;
+ }
+ display_hstart_cyclewait_end = hblen / 2 - display_hstart_cyclewait + 1;
+ display_hstart_cyclewait += 1;
+
+
+ //maxhpos_display = AMIGA_WIDTH_MAX;
+ //hsstop_detect = hsstop_detect2;
if (beamcon0 & bemcon0_hsync_mask) {
if (currprefs.gfx_overscanmode < OVERSCANMODE_BROADCAST) {
hsstop_detect -= 1;
}
}
+#endif
if (currprefs.gfx_extrawidth > 0) {
maxhpos_display += currprefs.gfx_extrawidth;
}
- if (hsstop_detect < 0) {
- hsstop_detect = 0;
- }
+ //if (hsstop_detect < 0) {
+ // hsstop_detect = 0;
+ //}
if (minfirstline < 0) {
minfirstline = 0;
}
if ((beamcon0 & BEAMCON0_VARVBEN) && (beamcon0 & bemcon0_vsync_mask)) {
minfirstline = vsync_startline;
- if (minfirstline > maxvpos / 2) {
+ if (minfirstline > vsync_lines / 2) {
minfirstline = vsync_startline;
}
minfirstline++;
minfirstline = vsync_startline;
}
- if (minfirstline >= maxvpos) {
- minfirstline = maxvpos - 1;
+ if (minfirstline >= vsync_lines) {
+ minfirstline = vsync_lines - 1;
}
if (minfirstline < minfirstline_hw) {
if (beamcon0 & BEAMCON0_VARBEAMEN) {
float half = (beamcon0 & BEAMCON0_PAL) ? 0: ((beamcon0 & BEAMCON0_LOLDIS) ? 0 : 0.5f);
- vblank_hz_nom = vblank_hz = clk / (maxvpos * (maxhpos + half));
+ vblank_hz_nom = vblank_hz = clk / (vsync_lines * (hsync_cck + half));
vblank_hz_shf = vblank_hz;
- vblank_hz_lof = clk / ((maxvpos + 1.0f) * (maxhpos + half));
- vblank_hz_lace = clk / ((maxvpos + 0.5f) * (maxhpos + half));
+ vblank_hz_lof = clk / ((vsync_lines + 1.0f) * (hsync_cck + half));
+ vblank_hz_lace = clk / ((vsync_lines + 0.5f) * (hsync_cck + half));
maxvpos_nom = maxvpos;
- maxvpos_display = maxvpos;
+ maxvpos_display = vsync_lines;
programmedmode = 2;
- if ((htotal < 226 || htotal > 229) || (vtotal < 256 || vtotal > 320)) {
- doublescan = htotal <= 164 && vtotal >= 350 ? 1 : 0;
+ if ((hsync_cck < 226 || hsync_cck > 229) || (vsync_lines < 256 || vsync_lines > 320)) {
+ doublescan = hsync_cck <= 164 && vsync_lines >= 350 ? 1 : 0;
// if superhires and wide enough: not doublescan
- if (doublescan && htotal >= 140 && (bplcon0 & 0x0040))
+ if (doublescan && hsync_cck >= 140 && (bplcon0 & 0x0040))
doublescan = 0;
programmedmode = 1;
}
vblank_hz = 300;
}
maxhpos_short = maxhpos;
- updateextblk();
maxvpos_total = ecs_agnus ? (MAXVPOS_LINES_ECS - 1) : (MAXVPOS_LINES_OCS - 1);
if (maxvpos_total > MAXVPOS) {
maxvpos_total = MAXVPOS;
linear_vpos = currprefs.ntscmode ? MAXVPOS_NTSC : MAXVPOS_PAL;
linear_hpos = currprefs.ntscmode ? MAXHPOS_NTSC : MAXHPOS_PAL;
linear_vpos += lof_store;
- linear_vpos -= vsync_startline;
+ //linear_vpos -= vsync_startline;
linear_vpos_prev[0] = linear_vpos;
linear_vpos_prev[1] = linear_vpos;
linear_vpos_prev[2] = linear_vpos;
linear_hpos_prev[0] = linear_hpos;
linear_hpos_prev[1] = linear_hpos;
linear_hpos_prev[2] = linear_hpos;
- current_linear_vpos = linear_vpos + vsync_startline - lof_store;
+ current_linear_vpos = linear_vpos; // +vsync_startline - lof_store;
current_linear_hpos = linear_hpos;
current_linear_vpos_nom = current_linear_vpos;
current_linear_hpos_short = linear_hpos;
current_linear_vpos_temp = current_linear_vpos;
current_linear_temp_change = 0;
current_linear_vpos_visible = 0;
+ hsync_cck = linear_hpos;
+ vsync_lines = linear_vpos;
+ vsync_linecnt = 0;
init_hz();
}
return;
}
#endif
- updateextblk();
// VB
if ((reg == 0x1cc || reg == 0x1ce) && (beamcon0 & BEAMCON0_VARVBEN)) {
current_linear_hpos_temp = hp;
current_linear_vpos_temp = vp;
current_linear_temp_change = 2;
+ if (vp == 0)
+ write_log("x");
}
}
}
}
}
+ bool framesync = false;
if (current_linear_temp_change > 0) {
current_linear_temp_change--;
if (current_linear_temp_change == 0) {
current_linear_hpos_short = current_linear_hpos - maxhpos_lol;
current_linear_vpos_nom = current_linear_vpos - lof_store;
init_beamcon0();
- compute_framesync();
- devices_syncchange();
+ framesync = true;
+ display_redraw = true;
+ }
+ if (current_linear_hblen != current_linear_hblen_temp) {
+ current_linear_hblen = current_linear_hblen_temp;
+ init_beamcon0();
+ framesync = true;
display_redraw = true;
}
}
}
+ if (framesync) {
+ compute_framesync();
+ devices_syncchange();
+ }
+
if (varsync_changed > 0) {
varsync_changed--;
if (varsync_changed == 0) {
display_hsync_counter = 0;
display_last_hsync = get_cycles();
display_last_vsync = get_cycles();
+ agnus_hsync_start = get_cck_cycles();
next_lineno = 0;
agnus_hpos = 0;
maxhpos = ntsc ? MAXHPOS_NTSC : MAXHPOS_PAL;
maxhpos_short = maxhpos;
maxhpos_lol = lol;
- updateextblk();
bplcon0_saved = bplcon0;
bplcon1_saved = bplcon1;
fmode_saved = fmode;
beamcon0_saved = new_beamcon0;
+ hsync_cck = maxhpos;
+
if (currprefs.cs_compatible == CP_DRACO || currprefs.cs_compatible == CP_CASABLANCA) {
// fake draco interrupts
INTENA(0x8000 | 0x4000 | 0x1000 | 0x2000 | 0x0080 | 0x0010 | 0x0008 | 0x0001);
vb_fast = get_strobe_reg(0) != 0x3c;
}
+STATIC_INLINE void vsync_mark(void)
+{
+ if (vsync_linecnt) {
+ vsync_lines = vsync_linecnt;
+ vsync_linecnt = 0;
+ }
+}
+
static void check_vsyncs_fast(void)
{
if (agnus_vb == 2) {
// VSYNC
if (vpos == 3 && lof_store) {
agnus_vsync = true;
+ if (!beamcon0_has_vsync) {
+ vsync_mark();
+ }
lof_detect = 1;
update_lof_detect();
}
}
if (vpos == 2 && !lof_store) {
agnus_vsync = true;
+ if (!beamcon0_has_vsync) {
+ vsync_mark();
+ }
lof_detect = 0;
update_lof_detect();
}
if (programmed_register_accessed_v) {
if (!lof_store && vpos == vsstrt) {
agnus_pvsync = true;
+ if (beamcon0_has_vsync) {
+ vsync_mark();
+ }
lof_pdetect = 0;
}
if (!lof_store && vpos == vsstop) {
}
if (lof_store && vpos == vsstrt) {
agnus_pvsync = true;
+ if (beamcon0_has_vsync) {
+ vsync_mark();
+ }
lof_pdetect = 1;
}
if (lof_store && vpos == vsstop) {
if (hcenter < maxhpos) {
if (lof_store && vpos == vsstrt) {
agnus_pvsync = true;
+ if (beamcon0_has_vsync) {
+ vsync_mark();
+ }
lof_pdetect = 1;
}
if (lof_store && vpos == vsstop) {
{
linear_hpos_prev[2] = linear_hpos_prev[1];
linear_hpos_prev[1] = linear_hpos_prev[0];
- linear_hpos_prev[0] = linear_hpos;
+ linear_hpos_prev[0] = hsync_cck;
linear_hpos = 0;
hautoscale_check();
display_hstart_cyclewait_cnt = display_hstart_cyclewait;
static void decide_hsync(void)
{
+ // hsync + display_hstart_cyclewait_cnt = end of current line
if (display_hstart_cyclewait_start) {
if (display_hstart_cyclewait_cnt > 0) {
display_hstart_cyclewait_cnt--;
linear_display_vpos = linear_vpos;
linear_vpos++;
linear_vpos_visible++;
+ hsync_cck = maxhpos;
if (linear_vpos >= maxvpos + lof_store) {
vsync_nosync();
}
draw_line_next_line = 0;
linear_vpos_vsync++;
+#if 1
if (beamcon0_has_vsync) {
if (vpos == vsstrt) {
+ //vsync_lines = vsync_linecnt;
+ //vsync_linecnt = 0;
linear_vpos_vsync = 0;
}
} else {
if (beamcon0_pal && (vpos == 3 && lof_store) || (vpos == 2 && !lof_store)) {
+ //vsync_lines = vsync_linecnt;
+ //vsync_linecnt = 0;
linear_vpos_vsync = 0;
}
if (!beamcon0_pal && vpos == 3) {
+ //vsync_lines = vsync_linecnt;
+ //vsync_linecnt = 0;
linear_vpos_vsync = 0;
}
}
+#endif
/* See if there's a chance of a copper wait ending this line. */
compute_spcflag_copper();
current_line_state = &lines[linear_vpos][lof_display];
}
- if (vpos == vsync_startline) {
-
- linear_vpos_prev[2] = linear_vpos_prev[1];
- linear_vpos_prev[1] = linear_vpos_prev[0];
- linear_vpos_prev[0] = linear_vpos;
- linear_vpos = 0;
-
- virtual_vsync_check();
-
- last_vsync_evt = get_cycles() + (maxvpos * maxhpos * 3) * CYCLE_UNIT;
- }
-
bool vposzero = false;
// LOF=1 is always matched, even when LOF=0 but only in PAL/NTSC modes
if ((vpos == maxvpos + lof_store) || (vpos == maxvpos_long)) {
write_log("Chipset emulation inactive\n");
resetfulllinestate();
}
+ vsync_linecnt++;
+ check_vsyncs_fast();
linear_hpos_prev[2] = linear_hpos_prev[1];
linear_hpos_prev[1] = linear_hpos_prev[0];
linear_hpos_prev[0] = maxhpos_short;
check_vsyncs_fast();
}
+ if (vpos == vsync_startline) {
+
+ linear_vpos_prev[2] = linear_vpos_prev[1];
+ linear_vpos_prev[1] = linear_vpos_prev[0];
+ if (vsync_lines == 0 || vsync_lines > 800)
+ write_log("x");
+ linear_vpos_prev[0] = vsync_lines;
+ linear_vpos = 0;
+
+ virtual_vsync_check();
+
+ last_vsync_evt = get_cycles() + (maxvpos * maxhpos * 3) * CYCLE_UNIT;
+ }
+
#if 0
if (1 && !can_fast_custom() && custom_fastmode) {
custom_fastmode = 0;
agnus_pcsync = !enable1 && !enable2;
if (pcsync != agnus_pcsync) {
if (agnus_pcsync) {
- agnus_phsync_start = get_cck_cycles();
+ agnus_pchsstrt_cck = get_cck_cycles();
}
#ifdef DEBUGGER
if (debug_dma) {
if (is_hsstrt) { // HSSTRT
agnus_hsync = true;
- agnus_hsync_start = get_cck_cycles();
+ agnus_hsstrt_cck = get_cck_cycles();
check_vidsyncs();
if (!beamcon0_has_hsync) {
+ hsync_cck = get_cck_cycles() - agnus_hsync_start;
+ vsync_linecnt++;
+ agnus_hsync_start = get_cck_cycles();
display_hstart_cyclewait_start = true;
write_drga_flag(DENISE_RGA_FLAG_LOL | (lol ? DENISE_RGA_FLAG_LOL_ON : 0), DENISE_RGA_FLAG_LOL | DENISE_RGA_FLAG_LOL_ON);
}
}
if (is_hsstop) { // HSSTOP
agnus_hsync = false;
- agnus_hsync_end = get_cck_cycles();
+ agnus_hsstop_cck = get_cck_cycles();
check_vidsyncs();
#ifdef DEBUGGER
if (debug_dma) {
if (is_shs) { // SHS
if (vpos == 3 && lof_store) {
agnus_vsync = true;
+ if (!beamcon0_has_vsync) {
+ vsync_mark();
+ }
lof_detect = 1;
update_lof_detect();
#ifdef DEBUGGER
if (is_cen) { // HCENTER
if (vpos == 2 && !lof_store) {
agnus_vsync = true;
+ if (!beamcon0_has_vsync) {
+ vsync_mark();
+ }
lof_detect = 0;
update_lof_detect();
#ifdef DEBUGGER
if (is_shs) { // SHS
if (vpos == 3 && lof_store) {
agnus_vsync = true;
+ if (!beamcon0_has_vsync) {
+ vsync_mark();
+ }
lof_detect = 1;
update_lof_detect();
#ifdef DEBUGGER
if (is_cen) { // HCENTER
if (vpos == 3 && !lof_store) {
agnus_vsync = true;
+ if (!beamcon0_has_vsync) {
+ vsync_mark();
+ }
lof_detect = 0;
update_lof_detect();
#ifdef DEBUGGER
if (hhp == hsstrt) {
agnus_phsync = true;
+ agnus_phsstrt_cck = get_cck_cycles();
if (!lof_store && vpos == vsstrt) {
agnus_pvsync = true;
+ if (beamcon0_has_vsync) {
+ vsync_mark();
+ }
lof_pdetect = 0;
#ifdef DEBUGGER
if (debug_dma) {
#endif
}
if (beamcon0_has_hsync) {
+ hsync_cck = get_cck_cycles() - agnus_hsync_start;
+ vsync_linecnt++;
+ agnus_hsync_start = get_cck_cycles();
display_hstart_cyclewait_start = true;
if (hsstrt > 8) {
// LOL info must be send after STRLONG cycyle
}
if (hhp == hsstop) {
agnus_phsync = false;
+ agnus_phsstop_cck = get_cck_cycles();
update_agnus_pcsync(hhp, prevsy);
- agnus_phsync_end = get_cck_cycles();
check_vidsyncs();
if (beamcon0_has_hsync && hsstrt <= 8) {
// LOL info must be send after STRLONG cycyle
}
if (hhp == hbstrt_cck) {
agnus_phblank = true;
- agnus_phblank_start = get_cck_cycles();
+ agnus_phblank_start_tmp = get_cck_cycles();
update_agnus_pcsync(hhp, prevsy);
check_vidsyncs();
#ifdef DEBUGGER
if (hhp == hbstop_cck) {
agnus_phblank = false;
agnus_phblank_end = get_cck_cycles();
+ agnus_phblank_start = agnus_phblank_start_tmp;
+ if (!agnus_vb_active) {
+ int len = agnus_phblank_end - agnus_phblank_start;
+ current_linear_hs_hb_dist = agnus_phblank_end - agnus_hsstrt_cck;
+ if (hblen_display_tmp > 0 && hblen_display_tmp == len) {
+ hblen_cnt++;
+ if (hblen_cnt > maxvpos / 8) {
+ current_linear_hblen_temp = len;
+ if (current_linear_hblen_temp != current_linear_hblen && !current_linear_temp_change) {
+ current_linear_temp_change = 2;
+ }
+ hblen_cnt = 0;
+ }
+ } else {
+ hblen_display_tmp = len;
+ hblen_cnt = 0;
+ }
+ }
update_agnus_pcsync(hhp, prevsy);
check_vidsyncs();
#ifdef DEBUGGER
if (hhp == hcenter) {
if (lof_store && vpos == vsstrt) {
agnus_pvsync = true;
+ if (beamcon0_has_vsync) {
+ vsync_mark();
+ }
lof_pdetect = 1;
#ifdef DEBUGGER
if (debug_dma) {
rga_denise_cycle_count_end += diff;
rga_denise_cycle += diff - rdc_offset;
rga_denise_cycle &= DENISE_RGA_SLOT_MASK;
+ agnus_hsync_start += diff;
if (custom_fastmode == 1) {
int rdc = rga_denise_cycle;
rga_denise_cycle_count_end += diff;
rga_denise_cycle += diff;
rga_denise_cycle &= DENISE_RGA_SLOT_MASK;
+ agnus_hsync_start += diff;
fast_lines_cnt++;
custom_trigger_start();
check_vsyncs_fast();
+ vsync_linecnt++;
if (eventtab[ev_sync].active) {
check_bpl_vdiw();
static void draw_denise_line(int gfx_ypos, nln_how how, uae_u32 linecnt, int startpos, int startcycle, int endcycle, int skip, int skip2, int dtotal, int calib_start, int calib_len, bool lol, int hdelay, bool blanked, bool finalseg, struct linestate *ls);
static void sprwrite(int reg, uae_u32 v);
+static void sprwrite_64(int reg, uae_u64 v);
static int spr_unalign_reg, spr_unalign_val;
+static uae_u64 spr_unalign_val64;
+static bool denise_sprfmode64, denise_bplfmode64;
static void quick_denise_rga(uae_u32 linecnt, int startpos, int endpos)
{
if (rd->line == linecnt && rd->rga != 0x1fe && (rd->rga < 0x38 || rd->rga >= 0x40)) {
denise_update_reg(rd->rga, rd->v, linecnt);
if (spr_unalign_reg) {
- sprwrite(spr_unalign_reg - 0x140, spr_unalign_val);
+ int sreg = spr_unalign_reg - 0x140;
+ bool datx = (sreg & 4) != 0;
+ if (datx) {
+ if (denise_sprfmode64) {
+ sprwrite_64(sreg, spr_unalign_val64);
+ } else {
+ sprwrite(sreg, spr_unalign_val);
+ }
+ } else {
+ sprwrite(sreg, spr_unalign_val);
+ }
}
}
pos++;
static int linear_denise_vbstrt, linear_denise_vbstop;
static int linear_denise_hbstrt, linear_denise_hbstop;
static int linear_denise_frame_hbstrt, linear_denise_frame_hbstop;
+static int linear_denise_frame_hbstrt_tmp, linear_denise_frame_hbstop_tmp;
+static int linear_denise_frame_hbstrt_sel, linear_denise_frame_hbstop_sel;
static int denise_visible_lines, denise_visible_lines_counted;
static uae_u16 hbstrt_denise_reg, hbstop_denise_reg;
static uae_u16 fmode_denise, denise_bplfmode, denise_sprfmode;
#if FMODE64_HACK
static int denise_bplfmode_max;
#endif
-static bool denise_sprfmode64, denise_bplfmode64;
static int bpldat_fmode;
static int fetchmode_size_denise, fetchmode_mask_denise;
static int delayed_vblank_ecs, delayed_pvblank_aga;
static uae_u8 pixx0, pixx1, pixx2, pixx3;
static uae_u32 debug_buf[256 * 2 * 4], debug_bufx[256 * 2 * 4];
static int hbstrt_offset, hbstop_offset;
+static int denise_hsync_offset;
+static int denise_hblen;
+static int denise_hbstrt_relative_cnt;
static int hstrt_offset, hstop_offset;
static int bpl1dat_trigger_offset;
static int internal_pixel_cnt, internal_pixel_start_cnt;
{
struct vidbuf_description* vidinfo = &adisplays[monid].gfxvidinfo;
- line += thisframe_y_adjust_real;
+ //line += thisframe_y_adjust_real;
if (line < 0 || line >= max_uae_height) {
xlinebuffer = get_row(monid, -1);
xlinebuffer_genlock = NULL;
{
*pvbstop = linear_denise_vbstrt;
*pvbstrt = linear_denise_vbstop;
- *phbstop = linear_denise_frame_hbstop;
- *phbstrt = linear_denise_frame_hbstrt;
+ *phbstop = linear_denise_frame_hbstop & ~15;
+ *phbstrt = linear_denise_frame_hbstrt & ~15;
}
static void setup_brdblank(void)
static void expand_drga_early2x(struct denise_rga *rd)
{
+ if (!aga_mode) {
+ return;
+ }
+
switch (rd->rga)
{
+ // BPLCON4 sprite
case 0x10c:
expand_bplcon4_spr(rd->v);
break;
+
+ // SPRxDATA/SPRxDATB
+ case 0x144: case 0x146:
+ case 0x14c: case 0x14e:
+ case 0x154: case 0x156:
+ case 0x15c: case 0x15e:
+ case 0x164: case 0x166:
+ case 0x16c: case 0x16e:
+ case 0x174: case 0x176:
+ case 0x17c: case 0x17e:
+ {
+ int sreg = rd->rga - 0x140;
+ int num = sreg / 8;
+ struct denise_spr *s = &dspr[num];
+ spr_unalign_reg = rd->rga;
+ spr_unalign_val = rd->v;
+ spr_unalign_val64 = rd->v64;
+ }
+ break;
}
}
spr_unalign_val = rd->v;
break;
- // SPRxDATA/SPRxDATB
+ // SPRxDATA/SPRxDATB
case 0x144: case 0x146:
case 0x14c: case 0x14e:
case 0x154: case 0x156:
case 0x16c: case 0x16e:
case 0x174: case 0x176:
case 0x17c: case 0x17e:
- if (denise_sprfmode64) {
- sprwrite_64(rd->rga - 0x140, rd->v64);
- } else {
- sprwrite(rd->rga - 0x140, rd->v);
+ {
+ if (!aga_mode) {
+ int sreg = rd->rga - 0x140;
+ sprwrite(sreg, rd->v);
+ }
}
break;
{
if (rd->flags) {
if (rd->flags & DENISE_RGA_FLAG_SYNC) {
+ bool hs = denise_hsync;
denise_csync = (rd->flags & DENISE_RGA_FLAG_CSYNC) != 0;
denise_vsync = (rd->flags & DENISE_RGA_FLAG_VSYNC) != 0;
denise_hsync = (rd->flags & DENISE_RGA_FLAG_HSYNC) != 0;
+ if (!hs && denise_hsync) {
+ denise_hsync_offset = internal_pixel_cnt;
+ }
}
if (rd->flags & DENISE_RGA_FLAG_LOL) {
agnus_lol = (rd->flags & DENISE_RGA_FLAG_LOL_ON) != 0;
buf_d = debug_bufx;
gbuf = xlinebuffer_genlock;
+ if ((denise_pixtotal_max << (1 + hresolution)) > vb->inwidth) {
+ denise_pixtotal_max = vb->inwidth >> (1 + hresolution);
+ }
+
if (buf1) {
for (int i = 0; i < lol_shift_prev; i++) {
if (buf1 >= (uae_u32*)xlinebuffer_start && buf1 < (uae_u32*)xlinebuffer_end) {
}
}
}
+ denise_pixtotal_max--;
}
- if ((denise_pixtotal_max << (1 + hresolution)) > vb->inwidth) {
- denise_pixtotal_max = vb->inwidth >> (1 + hresolution);
- }
if (xshift > 0) {
denise_pixtotal_max -= xshift;
}
}
if (linear_denise_hbstrt >= 0 && linear_denise_hbstop >= 0 && !denise_vblank_active) {
- linear_denise_frame_hbstrt = linear_denise_hbstrt & ~15;
- linear_denise_frame_hbstop = linear_denise_hbstop & ~15;
+ linear_denise_frame_hbstrt = linear_denise_hbstrt;
+ linear_denise_frame_hbstop = linear_denise_hbstop;
+
+ if (linear_denise_frame_hbstrt == linear_denise_frame_hbstrt_tmp && linear_denise_frame_hbstop == linear_denise_frame_hbstop_tmp) {
+ denise_hbstrt_relative_cnt++;
+ if (denise_hbstrt_relative_cnt > 30) {
+ linear_denise_frame_hbstrt_sel = linear_denise_frame_hbstrt_tmp;
+ linear_denise_frame_hbstop_sel = linear_denise_frame_hbstop_tmp;
+ if (abs(linear_denise_frame_hbstrt_sel - linear_denise_frame_hbstop_sel) < internal_pixel_cnt / 2) {
+ denise_hblen = linear_denise_frame_hbstop_sel - linear_denise_frame_hbstrt_sel;
+ } else {
+ denise_hblen = internal_pixel_cnt - linear_denise_frame_hbstrt_sel + linear_denise_frame_hbstop_sel;
+ }
+ denise_hbstrt_relative_cnt = 0;
+ }
+ } else {
+ linear_denise_frame_hbstrt_tmp = linear_denise_frame_hbstrt;
+ linear_denise_frame_hbstop_tmp = linear_denise_frame_hbstop;
+ denise_hbstrt_relative_cnt = 0;
+ }
}
if (refresh_indicator_buffer && buf1t) {
lines_count++;
}
+bool denise_get_hboffsets(int *hbs, int *hbe, int *hblen)
+{
+ if (linear_denise_frame_hbstrt_sel >= 0 && linear_denise_frame_hbstop_sel) {
+ *hbs = linear_denise_frame_hbstrt_sel;
+ *hbe = linear_denise_frame_hbstop_sel;
+ *hblen = denise_hblen;
+ return true;
+ }
+ // hardwired defaults (hardcoded to allow correct positioning immediate after reset)
+ if (!exthblanken) {
+ if (!ecs_denise) {
+ *hbs = 1728;
+ *hbe = 224;
+ *hblen = 312;
+ } else {
+ *hbs = 1732;
+ *hbe = 224;
+ *hblen = 308;
+ }
+ return true;
+ }
+ return false;
+}
+
// optimized drawing routines
#include "linetoscr_common.cpp"
#include "linetoscr_ocs_ecs.cpp"
}
#endif
- }
- if (h) {
+ } else if (h) {
bplcon4_denise_xor_val = bplcon4_denise_xor_val2;
sbasecol[0] = sbasecol2[0];
sbasecol[1] = sbasecol2[1];
}
if (spr_unalign_reg) {
- matchsprites2_aga(cnt);
- sprwrite(spr_unalign_reg - 0x140, spr_unalign_val);
+ int sreg = spr_unalign_reg - 0x140;
+ bool datx = (sreg & 4) != 0;
+ if (datx) {
+ if (denise_sprfmode64) {
+ sprwrite_64(sreg, spr_unalign_val64);
+ } else {
+ sprwrite(sreg, spr_unalign_val);
+ }
+ } else {
+ matchsprites2_aga(cnt);
+ sprwrite(sreg, spr_unalign_val);
+ }
spr_unalign_reg = 0;
}
}