From: Toni Wilen Date: Sat, 18 Dec 2021 18:58:14 +0000 (+0200) Subject: BEAMCON0 defines, blanking updates. X-Git-Tag: 4910~40 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=8aedd4d23664c32830ee26848fd24995dc6ce837;p=francis%2Fwinuae.git BEAMCON0 defines, blanking updates. --- diff --git a/custom.cpp b/custom.cpp index f1f42fcd..33db773b 100644 --- a/custom.cpp +++ b/custom.cpp @@ -83,14 +83,6 @@ extern uae_u16 serper; -STATIC_INLINE bool nocustom (void) -{ - struct amigadisplay *ad = &adisplays[0]; - if (ad->picasso_on && currprefs.picasso96_nocustom) - return true; - return false; -} - static void uae_abort (const TCHAR *format,...) { static int nomore; @@ -339,7 +331,7 @@ static uae_u16 hbstop_v, hbstrt_v, hbstop_v2, hbstrt_v2, hbstrt_v2o, hbstop_v2o; static int vsstrt_m, vsstop_m, vbstrt_m, vbstop_m; static bool vb_state, vb_end_line; static bool vs_state, vs_state_on, vs_state_hw; -static bool vb_end_next_line; +static bool vb_end_next_line, vb_end_next_line2; static int vb_start_line; static bool ocs_blanked; static uae_u16 sprhstrt, sprhstop, bplhstrt, bplhstop, hhpos, hhpos_hpos; @@ -350,6 +342,8 @@ static int diw_hstrt, diw_hstop; static int diw_hcounter; static uae_u16 refptr; static uae_u32 refptr_val; +static int line_disabled; +static bool custom_disabled; #define HSYNCTIME (maxhpos * CYCLE_UNIT) @@ -611,6 +605,18 @@ static int REGPARAM3 custom_wput_1(int, uaecptr, uae_u32, int) REGPARAM; * helper functions */ +static void check_nocustom(void) +{ + struct amigadisplay* ad = &adisplays[0]; + if (ad->picasso_on && currprefs.picasso96_nocustom) { + custom_disabled = true; + line_disabled |= 2; + } else { + custom_disabled = false; + line_disabled &= ~2; + } +} + STATIC_INLINE int ecsshres(void) { return bplcon0_res == RES_SUPERHIRES && ecs_denise && !aga_mode; @@ -896,7 +902,7 @@ static void record_color_change2(int hpos, int regno, uae_u32 value) { color_change *cc; - if (scandoubled_line || line_hidden() || nocustom()) { + if (line_disabled) { return; } @@ -930,7 +936,7 @@ static void record_color_change2(int hpos, int regno, uae_u32 value) } } - // HCENTER blanking + // HCENTER blanking (ECS Denise only) if (hcenter_v2 && vs_state_on && vpos < maxvpos_display_vsync && lof_display) { int chpos = pos; if (hcenter_v2_end == 0xffff && hcenter_v2 < chpos && hcenter_v2 >= last_recorded_diw_hpos) { @@ -942,7 +948,7 @@ static void record_color_change2(int hpos, int regno, uae_u32 value) cc[1].regno = -1; last_recorded_diw_hpos = cc->linepos; hcenter_v2_end = hcenter_v2; - hcenter_v2_end += ((beamcon0 & 0x20) ? 8 : 9) << CCK_SHRES_SHIFT; + hcenter_v2_end += ((beamcon0 & BEAMCON0_PAL) ? 8 : 9) << CCK_SHRES_SHIFT; if (hcenter_v2_end >= maxhpos << CCK_SHRES_SHIFT) { hcenter_v2_end -= maxhpos << CCK_SHRES_SHIFT; } @@ -1005,7 +1011,7 @@ static void record_color_change2(int hpos, int regno, uae_u32 value) record_dma_event(DMA_EVENT_HBE, diw_to_hpos(cc->linepos), vpos); } } - } else if (hbstrt_v2 > hbstop_v2) { + } else if (hbstrt_v2 >= hbstop_v2) { // equal: blank enable wins if (hbstop_v2 < chpos && hbstop_v2 >= last_recorded_diw_hpos) { if (next_color_change == last_color_change && exthblank_state) { cc = &curr_color_changes[next_color_change]; @@ -1068,7 +1074,7 @@ static void sync_color_changes(int hpos) // erase (color0 or bblank) area between previous end and new start static void hdiw_restart(int diw_last, int diw_current) { - if (diw_last >= diw_current || line_hidden() || nocustom()) { + if (diw_last >= diw_current || line_hidden() || custom_disabled) { return; } // update state @@ -1791,7 +1797,7 @@ int get_bitplane_dma_rel(int hpos, int off) static int islinetoggle(void) { int linetoggle = 0; - if (!(new_beamcon0 & 0x0800) && !(new_beamcon0 & 0x0020) && ecs_agnus) { + if (!(new_beamcon0 & BEAMCON0_LOLDIS) && !(new_beamcon0 & BEAMCON0_PAL) && ecs_agnus) { linetoggle = 1; // NTSC and !LOLDIS -> LOL toggles every line } else if (!ecs_agnus && currprefs.ntscmode) { linetoggle = 1; // hardwired NTSC Agnus @@ -3383,12 +3389,23 @@ static void do_long_fetch(int hpos, int nwords, int fm) #endif } + plane0 = toscr_nr_planes > 0; + + int cnt = nwords; + while (exthblank) { + cnt -= fetchstart; + hpos += fetchstart; + hbstrt_bordercheck(hpos, false); + if (cnt <= 0) { + break; + } + } + out_nbits += nwords * 16; out_offs += out_nbits >> 5; out_nbits &= 31; quick_add_delay_cycles((nwords * 16) << toscr_res_pixels_shift); - plane0 = toscr_nr_planes > 0; } #endif @@ -3853,7 +3870,7 @@ static bool isbrdblank(int hpos, uae_u16 bplcon0, uae_u16 bplcon3) brdntrans = ecs_denise && (bplcon0 & 1) && (bplcon3 & 0x10); // ECSENA=0: hardwired horizontal, strobe vertical // ECSENA=1: EXTBLKEN=0: hardwired blanking, strobe vertical - // ECSENA=1: EXTBLKEN=1: blanking equals HSYNC, no vertical, AGA: programmed horizontal, strobe vertical + // ECSENA=1: EXTBLKEN=1: blanking equals HSYNC if VARCSYEN=1, blanking equals HBSTRT-HBSTOP if VARCSYEN=0, no vertical, AGA: programmed horizontal, strobe vertical extblank = (bplcon0 & 1) && (bplcon3 & 1); #else brdblank = false; @@ -4559,7 +4576,8 @@ static void finish_decisions(int hpos) thisline_decision.bplres = output_res(RES_LORES); } - sync_color_changes(hpos + 1); + // Add DDF_OFFSET to detect blanking changes past hpos max + sync_color_changes(hpos + DDF_OFFSET / 2 + 1); /* Large DIWSTOP values can cause the stop position never to be * reached, so the state machine always stays in the same state and @@ -4735,29 +4753,40 @@ static void reset_decisions_hsync_start(void) thisline_decision.bplcon4bm = bplcon4; thisline_decision.bplcon4sp = bplcon4; thisline_decision.fmode = fmode; + // 0 = vb, 1 = vb off, 3 = vb off, previous line was bitplane + vb on //bool t = thisline_decision.plfleft >= 0 && (thisline_decision.vb & 1) == 0 && !vb_state && !vb_end_line; if (!aga_mode && ecs_denise && exthblank) { // ECS Denise + EXTHBLANK: VBLANK blanking is always disabled - thisline_decision.vb = 1; + thisline_decision.vb = VB_NOVB; } else { - thisline_decision.vb = vb_start_line > 1 + vblank_extraline ? 0 : 1; + // Visible vblank end is delayed by 1 line + thisline_decision.vb = vb_start_line > 1 + vblank_extraline || vb_end_next_line ? 0 : VB_NOVB; +#if 0 + // borderblank bug + if (vb_end_next_line2) { + if (ecs_agnus && ecs_denise && diwstate == DIW_waiting_stop && vpos != diwstate_vpos && (!exthblank || (exthblank && last_hblank_start < 0))) { + thisline_decision.vb |= VB_BRDBLANKBUG; + } + } +#endif } // if programmed vblank - if ((beamcon0 & 0x1000) && ecs_agnus) { - if (!thisline_decision.vb) { - thisline_decision.vb |= 2; + if ((beamcon0 & BEAMCON0_VARVBEN) && ecs_agnus) { + if (!(thisline_decision.vb & 15)) { + thisline_decision.vb |= VB_PRGVB; } } + // doublescan last line garbage workaround if (doflickerfix_active()) { if (vpos < maxvpos_display_vsync || (!lof_display && vpos >= maxvpos - 1) || (lof_display && vpos >= maxvpos - 1)) { - thisline_decision.vb |= 4; + thisline_decision.vb |= VB_XBLANK; } } if (!ecs_denise && vb_end_line) { - thisline_decision.vb = 1; + thisline_decision.vb = VB_NOVB; } #endif @@ -4797,7 +4826,7 @@ static void reset_decisions_hsync_start(void) if (1 && fetchmode >= 2 && !doflickerfix_active()) { // handle bitplane data wrap around bool toshift = false; - if ((exthblank || (beamcon0 & 0x0110)) && (thisline_decision.bplres == 0 || currprefs.chipset_hr)) { + if ((exthblank || (beamcon0 & (BEAMCON0_VARHSYEN | BEAMCON0_VARCSYEN))) && (thisline_decision.bplres == 0 || currprefs.chipset_hr)) { for (int i = 0; i < thisline_decision.nr_planes; i++) { if (todisplay2_aga_saved[i]) { toshift = true; @@ -4873,7 +4902,7 @@ static void reset_decisions_hsync_start(void) #endif } - if (debug_dma && (new_beamcon0 & (0x000 | 0x0010))) { + if (debug_dma && (new_beamcon0 & (BEAMCON0_VARHSYEN | BEAMCON0_VARCSYEN))) { record_dma_event(DMA_EVENT_HSS, hpos, vpos); record_dma_event(DMA_EVENT_HSE, hsstop, vpos); } @@ -5003,7 +5032,7 @@ static void checklacecount(bool lace) static void set_hcenter(void) { if (!aga_mode && ecs_denise && (bplcon0 & 1) && (bplcon3 & 1)) { - if (beamcon0 & 0x0210) { + if (beamcon0 & (BEAMCON0_VARVSYEN | BEAMCON0_VARCSYEN)) { hcenter_v2 = (hcenter & 0xff) << CCK_SHRES_SHIFT; } else { hcenter_v2 = 132 << CCK_SHRES_SHIFT; @@ -5037,6 +5066,7 @@ static void updateextblk(void) hbstop_v |= (hbstop >> 8) & 7; } if (aga_mode) { + // AGA horizontal blanking is simple // hblank has 1 lores pixel offset hbstrt_v2 = hbstrt_v - 4; if (hbstrt_v >= (1 << CCK_SHRES_SHIFT) && hbstrt_v2 < (1 << CCK_SHRES_SHIFT)) { @@ -5048,17 +5078,40 @@ static void updateextblk(void) } exthblank = (bplcon0 & 1) && (bplcon3 & 1); } else { - if (new_beamcon0 & 0x0010) { // VARCSYEN - // ECS HBLANK uses CSYNC input and matches HSSYNC period. + // ECS Denise CSYNC horizontal blanking is complex + if (new_beamcon0 & BEAMCON0_VARCSYEN) { + // ECS Denise HBLANK uses CSYNC input and matches programmed HSYNC period. hbstrt_v2 = (hsstrt & 0xff) << CCK_SHRES_SHIFT; hbstop_v2 = (hsstop & 0xff) << CCK_SHRES_SHIFT; - exthblank = (bplcon0 & 1) && (bplcon3 & 1); + } else if (new_beamcon0 & BEAMCON0_BLANKEN) { + // HBSTRT/HBSTOP blanking + hbstrt_v2 = hbstrt_v; + hbstop_v2 = hbstop_v; } else { - exthblank = false; + // ECS Denise HBLANK uses CSYNC input and matches hardwired HSYNC period. + hbstrt_v2 = 18 << CCK_SHRES_SHIFT; + hbstop_v2 = 35 << CCK_SHRES_SHIFT; + } + if (new_beamcon0 & BEAMCON0_CSYTRUE) { + uae_u16 tmp = hbstrt_v2; + hbstrt_v2 = hbstop_v2; + hbstop_v2 = tmp; + } + hbstrt_v = hbstrt_v2; + hbstop_v = hbstop_v2; + // hblank has 1 lores pixel offset + hbstrt_v2 -= 4; + hbstop_v2 -= 4; + if (hbstrt_v >= (1 << CCK_SHRES_SHIFT) && hbstrt_v2 < (1 << CCK_SHRES_SHIFT)) { + hbstrt_v2 += maxhpos << CCK_SHRES_SHIFT; } + if (hbstop_v >= (1 << CCK_SHRES_SHIFT) && hbstop_v2 < (1 << CCK_SHRES_SHIFT)) { + hbstop_v2 += maxhpos << CCK_SHRES_SHIFT; + } + exthblank = (bplcon0 & 1) && (bplcon3 & 1); } - if (new_beamcon0 & 0x0110) { // VARHSYEN | VARCSYEN + if (new_beamcon0 & (BEAMCON0_VARHSYEN | BEAMCON0_VARCSYEN)) { hsyncstartpos = hsstrt; hsstop_detect = hsstrt + 17; @@ -5121,9 +5174,15 @@ static void updateextblk(void) // hsync start offset adjustment if (hbstrt_v2 <= (hsyncstartpos_start << CCK_SHRES_SHIFT)) { hbstrt_v2 += maxhpos << CCK_SHRES_SHIFT; + if (hbstrt_v2 > (maxhpos + hsyncstartpos_start_cycles) << CCK_SHRES_SHIFT) { + hbstrt_v2 = 1 << CCK_SHRES_SHIFT; + } } if (hbstop_v2 <= (hsyncstartpos_start << CCK_SHRES_SHIFT)) { hbstop_v2 += maxhpos << CCK_SHRES_SHIFT; + if (hbstop_v2 > (maxhpos + hsyncstartpos_start_cycles) << CCK_SHRES_SHIFT) { + hbstop_v2 = 1 << CCK_SHRES_SHIFT; + } } int strt = hbstrt_v2; @@ -5171,7 +5230,7 @@ struct chipset_refresh *get_chipset_refresh(struct uae_prefs *p) { struct amigadisplay *ad = &adisplays[0]; int islace = interlace_seen ? 1 : 0; - int isntsc = (beamcon0 & 0x20) ? 0 : 1; + int isntsc = (beamcon0 & BEAMCON0_PAL) ? 0 : 1; int custom = programmedmode == 1 ? 1 : 0; if (!ecs_agnus) { @@ -5211,7 +5270,7 @@ void compute_framesync(void) struct vidbuf_description *vidinfo = &adisplays[0].gfxvidinfo; struct amigadisplay *ad = &adisplays[0]; int islace = interlace_seen ? 1 : 0; - int isntsc = (beamcon0 & 0x20) ? 0 : 1; + int isntsc = (beamcon0 & BEAMCON0_PAL) ? 0 : 1; bool found = false; if (islace) { @@ -5314,8 +5373,14 @@ void compute_framesync(void) int start = hsyncstartpos >> CCK_SHRES_SHIFT; int stop = hsyncstartpos_start_cycles; - vidinfo->drawbuffer.inwidth = ((maxhpos - (maxhpos - start + DISPLAY_LEFT_SHIFT / 2) + 1) * 2) << res2; - vidinfo->drawbuffer.inxoffset = stop * 2; + int w; + if (maxhpos > start) { + w = maxhpos - start; + } else { + w = maxhpos - (start - maxhpos); + } + vidinfo->drawbuffer.inwidth = (((w + DISPLAY_LEFT_SHIFT / 2) + 1) * 2) << res2; + vidinfo->drawbuffer.inxoffset = stop * 4; vidinfo->drawbuffer.extrawidth = 0; vidinfo->drawbuffer.inwidth2 = vidinfo->drawbuffer.inwidth; @@ -5334,7 +5399,7 @@ void compute_framesync(void) if (currprefs.gfx_extraheight > 0) { vidinfo->drawbuffer.extraheight = currprefs.gfx_extraheight; } - if (vidinfo->drawbuffer.extrawidth == -2 && ((new_beamcon0 & (0x1000 | 0x0200 | 0x0010)) || currprefs.gfx_overscanmode == OVERSCANMODE_EXTREME)) { + if (vidinfo->drawbuffer.extrawidth == -2 && ((new_beamcon0 & (BEAMCON0_VARVBEN | BEAMCON0_VARVSYEN | BEAMCON0_VARCSYEN)) || currprefs.gfx_overscanmode == OVERSCANMODE_EXTREME)) { vidinfo->drawbuffer.extrawidth = -1; } vidinfo->drawbuffer.inwidth2 = vidinfo->drawbuffer.inwidth; @@ -5377,6 +5442,8 @@ void compute_framesync(void) line_decisions[i].plfleft = -2; } + check_nocustom(); + compute_vsynctime(); hblank_hz = (currprefs.ntscmode ? CHIPSET_CLOCK_NTSC : CHIPSET_CLOCK_PAL) / (maxhpos + (islinetoggle() ? 0.5 : 0)); @@ -5419,18 +5486,18 @@ static void init_hz(bool checkvposw) doublescan = 0; programmedmode = 0; - if ((beamcon0 & (0x80 | 0x20)) != (new_beamcon0 & (0x80 | 0x20))) { + if ((beamcon0 & (BEAMCON0_VARBEAMEN | BEAMCON0_PAL)) != (new_beamcon0 & (BEAMCON0_VARBEAMEN | BEAMCON0_PAL))) { hzc = 1; } if (beamcon0 != new_beamcon0) { vpos_count_diff = vpos_count = 0; } - if ((beamcon0 & (0x1000 | 0x0200 | 0x0010)) != (new_beamcon0 & (0x1000 | 0x0200 | 0x0010))) { + if ((beamcon0 & (BEAMCON0_VARVBEN | BEAMCON0_VARVSYEN | BEAMCON0_VARCSYEN)) != (new_beamcon0 & (BEAMCON0_VARVBEN | BEAMCON0_VARVSYEN | BEAMCON0_VARCSYEN))) { hzc = 1; } beamcon0 = new_beamcon0; - isntsc = (beamcon0 & 0x20) ? 0 : 1; + isntsc = (beamcon0 & BEAMCON0_PAL) ? 0 : 1; islace = (interlace_seen) ? 1 : 0; if (!ecs_agnus) { isntsc = currprefs.ntscmode ? 1 : 0; @@ -5461,7 +5528,7 @@ static void init_hz(bool checkvposw) } dmal_htotal_mask = 0xffff; - if (beamcon0 & 0x0080) { + if (beamcon0 & BEAMCON0_VARBEAMEN) { // programmable scanrates (ECS Agnus) if (vtotal >= MAXVPOS) { vtotal = MAXVPOS - 1; @@ -5482,7 +5549,7 @@ static void init_hz(bool checkvposw) // after vsync, it seems earlier possible visible line is vsync+3. int vsync_startline = 3; - if ((beamcon0 & 0x1000) && (beamcon0 & (0x0200 | 0x0010))) { + if ((beamcon0 & BEAMCON0_VARVBEN) && (beamcon0 & (BEAMCON0_VARVSYEN | BEAMCON0_VARCSYEN))) { vsync_startline += vsstrt; if (vsync_startline >= maxvpos / 2) { vsync_startline = 3; @@ -5528,7 +5595,7 @@ static void init_hz(bool checkvposw) } else if (currprefs.gfx_overscanmode == OVERSCANMODE_BROADCAST) { minfirstline_hw -= EXTRAHEIGHT_BROADCAST_TOP; } - if (beamcon0 & 0x0080) { + if (beamcon0 & BEAMCON0_VARBEAMEN) { minfirstline_hw = 0; } @@ -5541,7 +5608,7 @@ static void init_hz(bool checkvposw) vblank_hz = (isntsc ? 15734.0 : 15625.0) / vpos_count; vblank_hz_nom = vblank_hz_shf = vblank_hz_lof = vblank_hz_lace = (float)vblank_hz; maxvpos_nom = vpos_count - (lof_store ? 1 : 0); - if ((maxvpos_nom >= 256 && maxvpos_nom <= 313) || (beamcon0 & 0x80)) { + if ((maxvpos_nom >= 256 && maxvpos_nom <= 313) || (beamcon0 & BEAMCON0_VARBEAMEN)) { maxvpos_display = maxvpos_nom; } else if (maxvpos_nom < 256) { maxvpos_display = 255; @@ -5555,7 +5622,7 @@ static void init_hz(bool checkvposw) vpos_count_diff = maxvpos; } - if ((beamcon0 & 0x1000) && (beamcon0 & (0x0200 | 0x0010))) { // VARVBEN + VARVSYEN|VARCSYEN + if ((beamcon0 & BEAMCON0_VARVBEN) && (beamcon0 & (BEAMCON0_VARVSYEN | BEAMCON0_VARCSYEN))) { minfirstline = vsync_startline; if (minfirstline > maxvpos / 2) { minfirstline = vsync_startline; @@ -5565,9 +5632,9 @@ static void init_hz(bool checkvposw) if (vsstrt > 0 && vsstrt < maxvpos / 2) { maxvpos_display_vsync += vsstrt; } - } else if (beamcon0 & (0x0200 | 0x0010)) { // VARVSYEN | VARCSYEN + } else if (beamcon0 & (BEAMCON0_VARVSYEN | BEAMCON0_VARCSYEN)) { firstblankedline = maxvpos + 1; - } else if (beamcon0 & 0x1000) { // VARVBEN + } else if (beamcon0 & BEAMCON0_VARVBEN) { firstblankedline = vbstrt; if (vsstrt > 0 && vsstrt < maxvpos / 2) { maxvpos_display_vsync += vsstrt; @@ -5575,14 +5642,13 @@ static void init_hz(bool checkvposw) } else { firstblankedline = maxvpos + 1; } - - if (beamcon0 & (0x1000 | 0x0200 | 0x0010)) { + if (beamcon0 & (BEAMCON0_VARVBEN | BEAMCON0_VARVSYEN | BEAMCON0_VARCSYEN)) { programmedmode = 2; } int eh = currprefs.gfx_extraheight; if (eh > 0) { - if (beamcon0 & (0x0200 | 0x0010)) { + if (beamcon0 & (BEAMCON0_VARVSYEN | BEAMCON0_VARCSYEN)) { maxvpos_display_vsync += eh / 2; minfirstline -= eh / 2; } else { @@ -5611,7 +5677,7 @@ static void init_hz(bool checkvposw) minfirstline = minfirstline_hw; } - if (beamcon0 & (0x0200 | 0x0010)) { + if (beamcon0 & (BEAMCON0_VARVSYEN | BEAMCON0_VARCSYEN)) { if (maxvpos_display_vsync >= vsstrt) { maxvpos_display_vsync = vsstrt; } @@ -5623,7 +5689,7 @@ static void init_hz(bool checkvposw) } } - if (beamcon0 & 0x80) { + if (beamcon0 & BEAMCON0_VARBEAMEN) { vblank_hz_nom = vblank_hz = clk / (maxvpos * maxhpos); vblank_hz_shf = vblank_hz; vblank_hz_lof = clk / ((maxvpos + 1) * maxhpos); @@ -5787,6 +5853,7 @@ static void calcdiw(void) /* display mode changed (lores, doubling etc..), recalculate everything */ void init_custom(void) { + check_nocustom(); update_mirrors(); create_cycle_diagram_table(); reset_drawing(); @@ -5902,7 +5969,7 @@ STATIC_INLINE uae_u16 ADKCONR(void) STATIC_INLINE int islightpentriggered(void) { - if (beamcon0 & 0x2000) // LPENDIS + if (beamcon0 & BEAMCON0_LPENDIS) return 0; return lightpen_triggered != 0; } @@ -5937,8 +6004,17 @@ static bool hsyncdelay(void) #define CPU_ACCURATE (currprefs.cpu_model < 68020 || (currprefs.cpu_model == 68020 && currprefs.cpu_memory_cycle_exact)) +static void check_line_enabled(void) +{ + line_disabled &= ~3; + line_disabled |= line_hidden() ? 1 : 0; + line_disabled |= custom_disabled ? 2 : 0; +} + static void vb_check(void) { + check_line_enabled(); + // A1000 Agnus VBSTRT=first line, OCS and later: VBSTRT=last line if (currprefs.cs_dipagnus) { if (vpos == 0) { @@ -6118,7 +6194,7 @@ static uae_u16 HHPOSR(void) if (islightpentriggered()) { v = hhpos_lpen; } else { - uae_u16 max = (new_beamcon0 & 0x40) ? htotal : maxhpos - 1; + uae_u16 max = (new_beamcon0 & BEAMCON0_DUAL) ? htotal : maxhpos - 1; v = hhpos + current_hpos() - hhpos_hpos; if (hhpos <= max || v >= 0x100) { if (max) { @@ -6313,7 +6389,7 @@ static void COPJMP(int num, int vblank) cop_state.strobe = num; cop_state.last_strobe = num; - if (nocustom()) { + if (custom_disabled) { immediate_copper(num); return; } @@ -6575,9 +6651,9 @@ static void ADKCON(int hpos, uae_u16 v) static void check_harddis(void) { // VARBEAMEN, HARDDIS, SHRES, UHRES - harddis_h = ecs_agnus && ((new_beamcon0 & 0x0080) || (new_beamcon0 & 0x4000) || (bplcon0 & 0x0040) || (bplcon0 & 0x0080)); + harddis_h = ecs_agnus && ((new_beamcon0 & BEAMCON0_VARBEAMEN) || (new_beamcon0 & BEAMCON0_HARDDIS) || (bplcon0 & 0x0040) || (bplcon0 & 0x0080)); // VARBEAMEN, VARVBEN, HARDDIS - harddis_v = ecs_agnus && ((new_beamcon0 & 0x0080) || (new_beamcon0 & 0x1000) || (new_beamcon0 & 0x4000)); + harddis_v = ecs_agnus && ((new_beamcon0 & BEAMCON0_VARBEAMEN) || (new_beamcon0 & BEAMCON0_VARVBEN) || (new_beamcon0 & BEAMCON0_HARDDIS)); } static void BEAMCON0(int hpos, uae_u16 v) @@ -6587,7 +6663,7 @@ static void BEAMCON0(int hpos, uae_u16 v) new_beamcon0 = v; write_log(_T("BEAMCON0 = %04X, PC=%08X\n"), v, M68K_GETPC); // not LPENDIS, LOLDIS, PAL, BLANKEN, SYNC INVERT - if (v & ~(0x2000 | 0x0800 | 0x0020 | 0x0008 | 0x0004 | 0x0002 | 0x0001)) { + if (v & ~(BEAMCON0_LPENDIS | BEAMCON0_LOLDIS | BEAMCON0_PAL | BEAMCON0_BLANKEN | BEAMCON0_CSYTRUE | BEAMCON0_VSYTRUE | BEAMCON0_HSYTRUE)) { dumpsync(); } } @@ -6616,19 +6692,19 @@ static void varsync(int reg, bool resync) return; } // TOTAL - if ((reg == 0x1c0 || reg == 0x1c8) && (beamcon0 & 0x0080)) { + if ((reg == 0x1c0 || reg == 0x1c8) && (beamcon0 & BEAMCON0_VARBEAMEN)) { varsync_changed = 1; } // VB - if ((reg == 0x1cc || reg == 0x1ce) && (beamcon0 & 0x1000)) { + if ((reg == 0x1cc || reg == 0x1ce) && (beamcon0 & BEAMCON0_VARVBEN)) { varsync_changed = 1; } // VS - if ((reg == 0x1e0 || reg == 0x1ca) && (beamcon0 & (0x0200 | 0x0010))) { + if ((reg == 0x1e0 || reg == 0x1ca) && (beamcon0 & (BEAMCON0_VARVSYEN | BEAMCON0_VARCSYEN))) { varsync_changed = 1; } // HS - if ((reg == 0x1de || reg == 0x1c2) && (beamcon0 & (0x0100 | 0x0010))) { + if ((reg == 0x1de || reg == 0x1c2) && (beamcon0 & (BEAMCON0_VARHSYEN | BEAMCON0_VARCSYEN))) { varsync_changed = 1; } } @@ -6644,7 +6720,7 @@ void set_picasso_hack_rate(int hz) if (!currprefs.cs_ciaatod) changed_prefs.cs_ciaatod = currprefs.cs_ciaatod = currprefs.ntscmode ? 2 : 1; if (p96refresh_active > 0) { - new_beamcon0 |= 0x80; + new_beamcon0 |= BEAMCON0_VARBEAMEN; } varsync_changed = 1; } @@ -8551,7 +8627,7 @@ static int coppercomp(int hpos, bool blitwait) static void update_copper(int until_hpos) { - if (1 && (nocustom() || !copper_enabled_thisline)) { + if (1 && (custom_disabled || !copper_enabled_thisline)) { last_copper_hpos = until_hpos; return; } @@ -8780,7 +8856,7 @@ next: static void compute_spcflag_copper(void) { - if (!dmaen(DMA_COPPER) || cop_state.state == COP_stop || cop_state.state == COP_waitforever || cop_state.state == COP_bltwait || cop_state.state == COP_bltwait2 || nocustom()) + if (!dmaen(DMA_COPPER) || cop_state.state == COP_stop || cop_state.state == COP_waitforever || cop_state.state == COP_bltwait || cop_state.state == COP_bltwait2 || custom_disabled) return; if (cop_state.state == COP_wait1) { int vp = vpos & (((cop_state.ir[1] >> 8) & 0x7F) | 0x80); @@ -9705,6 +9781,8 @@ static void vsync_handler_post(void) //write_log (_T("%d %d %d\n"), vsynctimebase, read_processor_time () - vsyncmintime, read_processor_time () - prevtime); prevtime = read_processor_time(); + check_nocustom(); + #if CUSTOM_DEBUG > 1 if ((intreq & 0x0020) && (intena & 0x0020)) write_log(_T("vblank interrupt not cleared\n")); @@ -9797,7 +9875,8 @@ static void vsync_handler_post(void) devices_vsync_post(); - if ((beamcon0 & (0x10 | 0x20 | 0x80 | 0x100 | 0x200 | 0x1000 | 0x4000)) != (new_beamcon0 & (0x10 | 0x20 | 0x80 | 0x100 | 0x200 | 0x1000 | 0x4000))) { + if ((beamcon0 & (BEAMCON0_VARCSYEN | BEAMCON0_PAL | BEAMCON0_VARBEAMEN | BEAMCON0_VARHSYEN | BEAMCON0_VARVSYEN | BEAMCON0_VARVBEN | BEAMCON0_HARDDIS)) != + (new_beamcon0 & (BEAMCON0_VARCSYEN | BEAMCON0_PAL | BEAMCON0_VARBEAMEN | BEAMCON0_VARHSYEN | BEAMCON0_VARVSYEN | BEAMCON0_VARVBEN | BEAMCON0_HARDDIS))) { if (!varsync_changed) { varsync_changed = 2; } @@ -9883,6 +9962,7 @@ static void hsync_scandoubler(int hpos) int lof = lof_display; next_lineno++; scandoubled_line = 1; + line_disabled |= 8; last_hdiw = 0 - 1; for (int i = 0; i < MAX_PLANES; i++) { @@ -9930,6 +10010,7 @@ static void hsync_scandoubler(int hpos) finish_decisions(hpos); hsync_record_line_state(next_lineno, nln_normal, thisline_changed); scandoubled_line = 0; + line_disabled &= ~8; dmacon = odmacon; copper_enabled_thisline = ocop; @@ -10252,7 +10333,7 @@ static void hsync_handlerh(bool onvsync) { int hpos = current_hpos(); - if (!nocustom()) { + if (!custom_disabled) { if (doflickerfix_active()) { finish_decisions(hpos); @@ -10299,7 +10380,7 @@ static void set_hpos(void) // this finishes current line static void hsync_handler_pre(bool onvsync) { - if (!nocustom()) { + if (!custom_disabled) { // make sure decisions are done to end of scanline finish_partial_decision(maxhpos); @@ -10356,6 +10437,7 @@ static void hsync_handler_pre(bool onvsync) vpos = 0; vsync_counter++; } + check_line_enabled(); hpos_hsync_extra = maxhpos; @@ -11084,7 +11166,7 @@ static void hsync_handler_post(bool onvsync) CIAB_tod_handler(18); } else if (ciahsyncs) { CIA_hsync_posthandler(true, ciahsyncs); - if (beamcon0 & 0x0100) { + if (beamcon0 & BEAMCON0_VARHSYEN) { if (hsstop < (maxhpos & ~1) && hsstrt < maxhpos) { CIAB_tod_handler(hsstrt); } @@ -11127,7 +11209,7 @@ static void hsync_handler_post(bool onvsync) #endif } else if (currprefs.cs_ciaatod == 0 && ciavsyncs) { // CIA-A TOD counter increases when vsync pulse ends - if (beamcon0 & 0x0200) { + if (beamcon0 & BEAMCON0_VARVSYEN) { if (vpos == vsstop && vs_state == true) { CIAA_tod_inc(lof_store ? hsstop : hsstop + hcenter); } @@ -11138,7 +11220,7 @@ static void hsync_handler_post(bool onvsync) } } - if (!nocustom ()) { + if (!custom_disabled) { if (!currprefs.blitter_cycle_exact && blt_info.blit_main && dmaen (DMA_BITPLANE) && diwstate == DIW_waiting_stop) { blitter_slowdown(thisline_decision.plfleft, thisline_decision.plfright - (16 << fetchmode), cycle_diagram_total_cycles[fetchmode][GET_RES_AGNUS (bplcon0)][GET_PLANES_LIMIT (bplcon0)], @@ -11162,7 +11244,13 @@ static void hsync_handler_post(bool onvsync) lof_lastline = lof_store != 0; } - vb_end_next_line = false; + if (vb_end_next_line2) { + vb_end_next_line2 = false; + } + if (vb_end_next_line) { + vb_end_next_line2 = true; + vb_end_next_line = false; + } if (vb_start_line) { vb_start_line++; } @@ -11196,7 +11284,7 @@ static void hsync_handler_post(bool onvsync) vs_state = false; } - if (new_beamcon0 & 0x1000) { + if (new_beamcon0 & BEAMCON0_VARVBEN) { if (vbstrt == vpos) { vbstrt_m = vpos; vb_start_line = 1; @@ -11226,7 +11314,7 @@ static void hsync_handler_post(bool onvsync) hhbpl = 0; } uae_u16 add = maxhpos - 1; - uae_u16 max = (new_beamcon0 & 0x040) ? htotal : add; + uae_u16 max = (new_beamcon0 & BEAMCON0_DUAL) ? htotal : add; uae_u16 hhpos_old = hhpos; hhpos += add; if (hhpos_old <= max || hhpos >= 0x100) { @@ -11242,7 +11330,7 @@ static void hsync_handler_post(bool onvsync) hhpos &= 0xff; } - if (beamcon0 & 0x20) { + if (beamcon0 & BEAMCON0_PAL) { if (vpos == 2 && !lof_store) { vs_state_hw = true; } @@ -11261,13 +11349,13 @@ static void hsync_handler_post(bool onvsync) } } - if (new_beamcon0 & (0x0200 | 0x0010)) { + if (new_beamcon0 & (BEAMCON0_VARVSYEN | BEAMCON0_VARCSYEN)) { vs_state_on = vs_state; } else { vs_state_on = vs_state_hw; } - if (!(new_beamcon0 & 0x1000)) { + if (!(new_beamcon0 & BEAMCON0_VARVBEN)) { vb_check(); } @@ -11520,6 +11608,7 @@ static void hsync_handler(void) } if (vpos == maxvpos_display_vsync) { + inputdevice_read_msg(true); vsync_display_render(); vsync_display_rendered = false; lof_display = lof_store; @@ -11713,7 +11802,7 @@ void custom_reset(bool hardreset, bool keyboardreset) CLXCON(0); CLXCON2(0); setup_fmodes(0); - beamcon0 = new_beamcon0 = beamcon0_saved = currprefs.ntscmode ? 0x00 : 0x20; + beamcon0 = new_beamcon0 = beamcon0_saved = currprefs.ntscmode ? 0x00 : BEAMCON0_PAL; blt_info.blit_main = 0; blt_info.blit_finald = 0; blt_info.blit_pending = 0; @@ -13233,13 +13322,13 @@ void check_prefs_changed_custom(void) currprefs.picasso96_nocustom = changed_prefs.picasso96_nocustom; if (currprefs.ntscmode != changed_prefs.ntscmode) { currprefs.ntscmode = changed_prefs.ntscmode; - new_beamcon0 = currprefs.ntscmode ? 0x00 : 0x20; + new_beamcon0 = currprefs.ntscmode ? 0x00 : BEAMCON0_PAL; } if ((changed_prefs.chipset_mask & CSMASK_ECS_AGNUS) && !(currprefs.chipset_mask & CSMASK_ECS_AGNUS)) { new_beamcon0 = beamcon0_saved; } else if (!(changed_prefs.chipset_mask & CSMASK_ECS_AGNUS) && (currprefs.chipset_mask & CSMASK_ECS_AGNUS)) { beamcon0_saved = beamcon0; - beamcon0 = new_beamcon0 = currprefs.ntscmode ? 0x00 : 0x20; + beamcon0 = new_beamcon0 = currprefs.ntscmode ? 0x00 : BEAMCON0_PAL; diwhigh = 0; diwhigh_written = 0; bplcon0 &= ~(0x10 | 0x01); diff --git a/drawing.cpp b/drawing.cpp index 430bae8c..102da536 100644 --- a/drawing.cpp +++ b/drawing.cpp @@ -284,6 +284,9 @@ static uae_u8 ecs_genlock_features_mask; static bool ecs_genlock_features_colorkey; static int hsync_shift_hack; static bool sprite_smaller_than_64, sprite_smaller_than_64_inuse; +static bool full_blank; +static int borderblank_blank; +static uae_u8 vb_state; uae_sem_t gui_sem; @@ -471,6 +474,26 @@ static void reset_custom_limits(void) center_reset = 1; } +static void expand_vb_state(void) +{ + full_blank = (vb_state & 15) == VB_PRGVB || (vb_state & 15) >= VB_XBLANK; + if ((vb_state & VB_BRDBLANKBUG) && ce_is_borderblank(colors_for_drawing.extra)) { + borderblank_blank = 4; + } else { + borderblank_blank = 0; + } +} + +static void extblankcheck(void) +{ + if (exthblanken && ((dp_for_drawing->bplcon3 & 1) && (dp_for_drawing->bplcon0 & 1))) { + exthblank = true; + } + if (exthblanken && (!(dp_for_drawing->bplcon3 & 1) || !(dp_for_drawing->bplcon0 & 1))) { + exthblank = false; + } +} + static void reset_hblanking_limits(void) { hblank_left_start = visible_left_start; @@ -533,7 +556,7 @@ static void set_vblanking_limits(void) bool hardwired = true; if (ecs_agnus) { - hardwired = (new_beamcon0 & 0x1000) == 0; + hardwired = (new_beamcon0 & BEAMCON0_VARVBEN) == 0; } if (hardwired) { int vbstrt, vbstop; @@ -567,7 +590,7 @@ int get_vertical_visible_height(bool useoldsize) } bool hardwired = true; if (ecs_agnus) { - hardwired = (new_beamcon0 & 0x1000) == 0; + hardwired = (new_beamcon0 & BEAMCON0_VARVBEN) == 0; } if (hardwired) { get_vblanking_limits(&vbstrt, &vbstop, true); @@ -596,6 +619,7 @@ static void set_hblanking_limits(void) hbstop -= 2 << CCK_SHRES_SHIFT; } } + if (hardwired) { doblank = true; } else if (currprefs.gfx_overscanmode <= OVERSCANMODE_OVERSCAN) { @@ -607,7 +631,7 @@ static void set_hblanking_limits(void) if (doblank && programmedmode != 1) { // reposition to sync // use hardwired hblank emulation as overscan blanking. - if ((new_beamcon0 & 0x0110) && !hardwired) { + if ((new_beamcon0 & (BEAMCON0_VARHSYEN | BEAMCON0_VARCSYEN)) && !hardwired) { extern uae_u16 hsstrt; hbstrt += (hsstrt - 17) << CCK_SHRES_SHIFT; hbstop += (hsstrt - 17) << CCK_SHRES_SHIFT; @@ -682,7 +706,7 @@ void check_custom_limits(void) visible_top_start = top; if (bottom > top && bottom < visible_bottom_stop) visible_bottom_stop = bottom; - } +} void set_custom_limits (int w, int h, int dx, int dy, bool blank) { @@ -1018,7 +1042,6 @@ static int may_require_hard_way; static int linetoscr_diw_start, linetoscr_diw_end; static int native_ddf_left, native_ddf_right; static int hamleftborderhidden; -static uae_u8 vb_state; static int pixels_offset; static int src_pixel; @@ -1051,21 +1074,23 @@ static xcolnr getbgc(int blank) } bool extblken = ce_is_extblankset(colors_for_drawing.extra); // extblken=1: hblank and vblank = black - if (!(vb_state & 1) && extblken && aga_mode) { + if (!(vb_state & VB_NOVB) && extblken && aga_mode) { + return fullblack; + } + if (hposblank) { return fullblack; } bool brdblank = ce_is_borderblank(colors_for_drawing.extra); #if 0 - // if this line next line after VB end and bitplane DMA was active in previous (hidden) line: borderblank is ignored. - if (vb_state == 3) { - brdblank = false; + if (brdblank && blank == 4) { + return colors_for_drawing.acolors[0]; } #endif // borderblank = black (overrides extblken) if (brdblank && blank >= 0) { return fullblack; } - if (hposblank || blank > 0) { + if (blank > 0) { return fullblack; } return colors_for_drawing.acolors[0]; @@ -1452,7 +1477,7 @@ static void fill_line_border(int lineno) int endpos = visible_left_border + vidinfo->drawbuffer.inwidth; int w = endpos - lastpos; - if (lineno < visible_top_start || lineno < vblank_top_start || lineno >= visible_bottom_stop || lineno >= vblank_bottom_stop || vb_state >= 4) { + if (lineno < visible_top_start || lineno < vblank_top_start || lineno >= visible_bottom_stop || lineno >= vblank_bottom_stop || full_blank) { int b = hposblank; hposblank = 3; fill_line2(lastpos, w); @@ -3135,16 +3160,6 @@ static bool isham(uae_u16 bplcon0) return 0; } -static void extblankcheck(void) -{ - if (exthblanken && ((dp_for_drawing->bplcon3 & 1) && (dp_for_drawing->bplcon0 & 1))) { - exthblank = true; - } - if (exthblanken && (!(dp_for_drawing->bplcon3 & 1) || !(dp_for_drawing->bplcon0 & 1))) { - exthblank = false; - } -} - static void pfield_expand_dp_bplconx (int regno, int v, int hp, int vp) { regno -= RECORDED_REGISTER_CHANGE_OFFSET; @@ -3231,6 +3246,7 @@ static void adjust_drawing_colors (int ctable, int need_full, bool blankcheck) if (colors_for_drawing.extra != oe) { reset_hblanking_limits(); set_hblanking_limits(); + expand_vb_state(); } } @@ -3296,96 +3312,99 @@ static void do_color_changes(line_draw_func worker_border, line_draw_func worker } if (vp >= 0) { - // left hblank (left edge to hblank end) - if (nextpos_in_range > lastpos && lastpos < hblank_left_start) { - int t = nextpos_in_range <= hblank_left_start ? nextpos_in_range : hblank_left_start; - (*worker_border)(lastpos, t, 1); - lastpos = t; - } - // vblank + programmed vblank / hardwired vblank - if (vb_state == 2 || vb_state >= 4 || vbarea) { + if (full_blank || vbarea) { + // vblank + programmed vblank / hardwired vblank - if (vbarea || vb_state >= 4) { + if (vbarea || vb_state >= VB_XBLANK) { hposblank = 3; } - if (nextpos_in_range > lastpos && lastpos < playfield_end) { - int t = nextpos_in_range <= playfield_end ? nextpos_in_range : playfield_end; + if (nextpos_in_range > lastpos) { + int t = nextpos_in_range; (*worker_border)(lastpos, t, 1); lastpos = t; } - // normal - } else if (playfield_start_pre >= playfield_start || !ce_is_borderblank(colors_for_drawing.extra)) { + } else { + // non-vblank scanline - // normal left border (hblank end to playfield start) - if (nextpos_in_range > lastpos && lastpos < playfield_start) { - int t = nextpos_in_range <= playfield_start ? nextpos_in_range : playfield_start; - (*worker_border)(lastpos, t, 0); + // left hblank (left edge to hblank end) + if (nextpos_in_range > lastpos && lastpos < hblank_left_start) { + int t = nextpos_in_range <= hblank_left_start ? nextpos_in_range : hblank_left_start; + (*worker_border)(lastpos, t, 1); lastpos = t; } - // playfield - if (nextpos_in_range > lastpos && lastpos >= playfield_start && lastpos < playfield_end) { - int t = nextpos_in_range <= playfield_end ? nextpos_in_range : playfield_end; - if ((plf2pri >= 5 || plf1pri >= 5) && !aga_mode) { - weird_bitplane_fix(lastpos, t); + if (playfield_start_pre >= playfield_start || !ce_is_borderblank(colors_for_drawing.extra)) { + + // normal left border (hblank end to playfield start) + if (nextpos_in_range > lastpos && lastpos < playfield_start) { + int t = nextpos_in_range <= playfield_start ? nextpos_in_range : playfield_start; + (*worker_border)(lastpos, t, borderblank_blank); + lastpos = t; } - if (may_require_hard_way && (may_require_hard_way < 0 || (bplxor && may_require_hard_way && worker_pfield != pfield_do_linetoscr_bordersprite_aga))) { - playfield_hard_way(worker_pfield, lastpos, t); - } else { - (*worker_pfield)(lastpos, t, 0); + + // playfield + if (nextpos_in_range > lastpos && lastpos >= playfield_start && lastpos < playfield_end) { + int t = nextpos_in_range <= playfield_end ? nextpos_in_range : playfield_end; + if ((plf2pri >= 5 || plf1pri >= 5) && !aga_mode) { + weird_bitplane_fix(lastpos, t); + } + if (may_require_hard_way && (may_require_hard_way < 0 || (bplxor && may_require_hard_way && worker_pfield != pfield_do_linetoscr_bordersprite_aga))) { + playfield_hard_way(worker_pfield, lastpos, t); + } else { + (*worker_pfield)(lastpos, t, 0); + } + lastpos = t; } - lastpos = t; - } - } else { - // special AGA borderblank 1 shres pixel delay + } else { + // special AGA borderblank 1 shres pixel delay - // borderblank left border (hblank end to playfield_start_pre) - if (nextpos_in_range > lastpos && lastpos < playfield_start_pre) { - int t = nextpos_in_range <= playfield_start_pre ? nextpos_in_range : playfield_start_pre; - (*worker_border)(lastpos, t, 0); - lastpos = t; - } - // AGA "buggy" borderblank, real background color visible, single shres pixel wide. - if (nextpos_in_range > lastpos && lastpos < playfield_start) { - int t = nextpos_in_range <= playfield_start ? nextpos_in_range : playfield_start; - (*worker_border)(lastpos, t, -1); - lastpos = t; - } + // borderblank left border (hblank end to playfield_start_pre) + if (nextpos_in_range > lastpos && lastpos < playfield_start_pre) { + int t = nextpos_in_range <= playfield_start_pre ? nextpos_in_range : playfield_start_pre; + (*worker_border)(lastpos, t, borderblank_blank); + lastpos = t; + } + // AGA "buggy" borderblank, real background color visible, single shres pixel wide. + if (nextpos_in_range > lastpos && lastpos < playfield_start) { + int t = nextpos_in_range <= playfield_start ? nextpos_in_range : playfield_start; + (*worker_border)(lastpos, t, -1); + lastpos = t; + } - // playfield with last shres pixel not drawn. - if (nextpos_in_range > lastpos && lastpos >= playfield_start && lastpos < playfield_end_pre) { - int t = nextpos_in_range <= playfield_end_pre ? nextpos_in_range : playfield_end_pre; - if (may_require_hard_way && (may_require_hard_way < 0 || (bplxor && may_require_hard_way && worker_pfield != pfield_do_linetoscr_bordersprite_aga))) { - playfield_hard_way(worker_pfield, lastpos, t); - } else { - (*worker_pfield)(lastpos, t, 0); + // playfield with last shres pixel not drawn. + if (nextpos_in_range > lastpos && lastpos >= playfield_start && lastpos < playfield_end_pre) { + int t = nextpos_in_range <= playfield_end_pre ? nextpos_in_range : playfield_end_pre; + if (may_require_hard_way && (may_require_hard_way < 0 || (bplxor && may_require_hard_way && worker_pfield != pfield_do_linetoscr_bordersprite_aga))) { + playfield_hard_way(worker_pfield, lastpos, t); + } else { + (*worker_pfield)(lastpos, t, 0); + } + lastpos = t; + } + + // last shres pixel of playfield blanked + if (nextpos_in_range > lastpos && lastpos >= playfield_end_pre && lastpos < playfield_end) { + int t = nextpos_in_range <= playfield_end ? nextpos_in_range : playfield_end; + (*worker_border)(lastpos, t, 0); + lastpos = t; } - lastpos = t; } - // last shres pixel of playfield blanked - if (nextpos_in_range > lastpos && lastpos >= playfield_end_pre && lastpos < playfield_end) { - int t = nextpos_in_range <= playfield_end ? nextpos_in_range : playfield_end; + // right border (playfield end to hblank start) + if (nextpos_in_range > lastpos && lastpos >= playfield_end_pre) { + int t = nextpos_in_range <= hblank_right_stop ? nextpos_in_range : hblank_right_stop; (*worker_border)(lastpos, t, 0); lastpos = t; } - } - - // right border (playfield end to hblank start) - if (nextpos_in_range > lastpos && lastpos >= playfield_end_pre) { - int t = nextpos_in_range <= hblank_right_stop ? nextpos_in_range : hblank_right_stop; - (*worker_border)(lastpos, t, 0); - lastpos = t; - } - - // right hblank (hblank start to right edge, hblank start may be earlier than playfield end) - if (nextpos_in_range > hblank_right_stop) { - (*worker_border) (hblank_right_stop, nextpos_in_range, 1); - lastpos = nextpos_in_range; + // right hblank (hblank start to right edge, hblank start may be earlier than playfield end) + if (nextpos_in_range > hblank_right_stop) { + (*worker_border) (hblank_right_stop, nextpos_in_range, 1); + lastpos = nextpos_in_range; + } } } @@ -3515,7 +3534,10 @@ static void pfield_draw_line(struct vidbuffer *vb, int lineno, int gfx_ypos, int } have_color_changes = is_color_changes(dip_for_drawing); - vb_state = dp_for_drawing->vb; + if (vb_state != dp_for_drawing->vb) { + vb_state = dp_for_drawing->vb; + expand_vb_state(); + } sprite_smaller_than_64_inuse = false; dh = dh_line; @@ -4259,6 +4281,8 @@ static void draw_frame2(struct vidbuffer *vbin, struct vidbuffer *vbout) set_vblanking_limits(); reset_hblanking_limits(); set_hblanking_limits(); + extblankcheck(); + expand_vb_state(); bool firstline = true; int lastline = thisframe_y_adjust_real - (1 << linedbl); @@ -4292,8 +4316,10 @@ static void draw_frame2(struct vidbuffer *vbin, struct vidbuffer *vbout) largest = whereline; #endif - reset_hblanking_limits(); - set_hblanking_limits(); + if (ecs_denise) { + reset_hblanking_limits(); + set_hblanking_limits(); + } hposblank = 0; pfield_draw_line(vbout, line, whereline, wherenext); diff --git a/include/custom.h b/include/custom.h index f6d49a24..166c5885 100644 --- a/include/custom.h +++ b/include/custom.h @@ -12,6 +12,22 @@ #include "uae/types.h" #include "machdep/rpt.h" +#define BEAMCON0_HARDDIS 0x4000 +#define BEAMCON0_LPENDIS 0x2000 +#define BEAMCON0_VARVBEN 0x1000 +#define BEAMCON0_LOLDIS 0x0800 +#define BEAMCON0_CSCBEN 0x0400 +#define BEAMCON0_VARVSYEN 0x0200 +#define BEAMCON0_VARHSYEN 0x0100 +#define BEAMCON0_VARBEAMEN 0x0080 +#define BEAMCON0_DUAL 0x0040 +#define BEAMCON0_PAL 0x0020 +#define BEAMCON0_VARCSYEN 0x0010 +#define BEAMCON0_BLANKEN 0x0008 +#define BEAMCON0_CSYTRUE 0x0004 +#define BEAMCON0_VSYTRUE 0x0002 +#define BEAMCON0_HSYTRUE 0x0001 + extern bool aga_mode, ecs_agnus, ecs_denise, direct_rgb; /* These are the masks that are ORed together in the chipset_mask option. diff --git a/include/drawing.h b/include/drawing.h index 2c0d0ef8..e137dc21 100644 --- a/include/drawing.h +++ b/include/drawing.h @@ -142,6 +142,11 @@ STATIC_INLINE bool ce_is_borderntrans(uae_u8 data) return (data & (1 << CE_BORDERNTRANS)) != 0; } +#define VB_BRDBLANKBUG 0x80 +#define VB_XBLANK 0x04 +#define VB_PRGVB 0x02 +#define VB_NOVB 0x01 + struct color_entry { uae_u16 color_regs_ecs[32]; #ifndef AGA